Ignore:
Timestamp:
Aug 6, 2024, 10:31:16 PM (2 months ago)
Author:
chronos
Message:
  • Modified: Optimized DeviceMapper read/write handlers calls without case statement.
  • Modified: Use TInt as base data type which can be redefined to different higher integer type. For start it is Int64.
Location:
branches/ByteArray
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/ByteArray

    • Property svn:ignore set to
      lib
      heaptrclog.trc
      ByteArray
      ByteArray.dbg
      ByteArray.lps
      ByteArray.res
  • branches/ByteArray/Devices/Device.pas

    r5 r9  
    44
    55uses
    6   Classes, SysUtils, Channel, Forms, BigInt, Common.FormEx;
     6  Classes, SysUtils, Channel, Forms, Int, Common.FormEx, Generics.Collections;
    77
    88type
     
    1212  TFormDevice = class;
    1313
     14  TReadEvent = function (DataSize: TIntSize): TInt of object;
     15  TWriteEvent = procedure (DataSize: TIntSize; Value: TInt) of object;
     16  TReadEvents = TList<TReadEvent>;
     17  TWriteEvents = TList<TWriteEvent>;
     18
     19  { THandlers }
     20
     21  THandlers = class
     22    ReadHandlers: TReadEvents;
     23    WriteHandlers: TWriteEvents;
     24    constructor Create;
     25    destructor Destroy; override;
     26  end;
     27
    1428  { TDevice }
    1529
     
    1832    DeviceClass: TDeviceClass;
    1933    Form: TFormDevice;
    20     BaseAddress: Integer;
    21     function GetAddressCount: Integer; virtual;
    22     procedure SetChannel(Channel: TChannel); virtual;
     34    function GetHandlers: THandlers; virtual;
    2335  end;
    2436
     
    6072end;
    6173
     74{ THandlers }
     75
     76constructor THandlers.Create;
     77begin
     78  ReadHandlers := TReadEvents.Create;
     79  WriteHandlers := TWriteEvents.Create;
     80end;
     81
     82destructor THandlers.Destroy;
     83begin
     84  FreeAndNil(ReadHandlers);
     85  FreeAndNil(WriteHandlers);
     86  inherited;
     87end;
     88
    6289{ TDevice }
    6390
    64 function TDevice.GetAddressCount: Integer;
     91function TDevice.GetHandlers: THandlers;
    6592begin
    66   Result := 0;
    67 end;
    68 
    69 procedure TDevice.SetChannel(Channel: TChannel);
    70 begin
     93  Result := nil;
    7194end;
    7295
  • branches/ByteArray/Devices/DeviceMapper.pas

    r5 r9  
    44
    55uses
    6   Classes, SysUtils, Device, Channel, Generics.Collections, BigInt;
     6  Classes, SysUtils, Device, Channel, Generics.Collections, Int, Math;
    77
    88type
     
    1212  TMappedDevice = class
    1313    Device: TDevice;
    14     Count: Integer;
    15     Channel: TChannel;
     14    ReadCount: Integer;
     15    WriteCount: Integer;
     16    ReadBase: Integer;
     17    WriteBase: Integer;
    1618    constructor Create;
    1719    destructor Destroy; override;
     
    2022  { TDeviceMapper }
    2123
    22   TDeviceMapper = class
    23     FreeBaseAddress: Integer;
     24  TDeviceMapper = class(TChannelDevice)
     25  private
     26    function ChannelRead(Address: TInt; Size: TIntSize): TInt;
     27    procedure ChannelWrite(Address: TInt; Size: TIntSize; Value: TInt);
     28    function ChannelGetSize: TInt;
     29  public
     30    ReadHandlers: TList<TReadEvent>;
     31    WriteHandlers: TList<TWriteEvent>;
    2432    MappedDevices: TObjectList<TMappedDevice>;
    2533    procedure RegisterDevice(Device: TDevice);
    2634    procedure UnregisterDevice(Device: TDevice);
    27     function Read(Address: TBigInt; Size: TBigIntSize): TBigInt;
    28     procedure Write(Address: TBigInt; Size: TBigIntSize; Value: TBigInt);
    29     procedure SetChannel(Channel: TChannel);
     35    procedure SetChannel(Channel: TChannel); override;
    3036    constructor Create;
    3137    destructor Destroy; override;
     
    3945constructor TMappedDevice.Create;
    4046begin
    41   Channel := TChannel.Create;
    4247end;
    4348
    4449destructor TMappedDevice.Destroy;
    4550begin
    46   FreeAndNil(Channel);
    4751  inherited;
    4852end;
     
    5357var
    5458  NewMappedDevice: TMappedDevice;
     59  Handlers: THandlers;
    5560begin
     61  Handlers := Device.GetHandlers;
     62
    5663  NewMappedDevice := TMappedDevice.Create;
    5764  NewMappedDevice.Device := Device;
    58   NewMappedDevice.Device.BaseAddress := FreeBaseAddress;
    59   NewMappedDevice.Count := Device.GetAddressCount;
    60   Device.SetChannel(NewMappedDevice.Channel);
     65  NewMappedDevice.ReadBase := ReadHandlers.Count;
     66  NewMappedDevice.WriteBase := WriteHandlers.Count;
     67  NewMappedDevice.ReadCount := Handlers.ReadHandlers.Count;
     68  NewMappedDevice.WriteCount := Handlers.WriteHandlers.Count;
    6169  MappedDevices.Add(NewMappedDevice);
    62   Inc(FreeBaseAddress, NewMappedDevice.Count);
     70
     71  ReadHandlers.AddRange(Handlers.ReadHandlers);
     72  WriteHandlers.AddRange(Handlers.WriteHandlers);
     73  Handlers.Free;
    6374end;
    6475
     
    7485end;
    7586
    76 function TDeviceMapper.Read(Address: TBigInt; Size: TBigIntSize): TBigInt;
     87function TDeviceMapper.ChannelRead(Address: TInt; Size: TIntSize): TInt;
     88begin
     89  if Address < ReadHandlers.Count then
     90    Result := ReadHandlers[Address](Size)
     91    else Result := 0;
     92end;
     93
     94procedure TDeviceMapper.ChannelWrite(Address: TInt; Size: TIntSize; Value: TInt);
    7795var
    7896  I: Integer;
    7997begin
    80   for I := 0 to MappedDevices.Count - 1 do
    81     if (Integer(Address) >= MappedDevices[I].Device.BaseAddress) and (Integer(Address) >= MappedDevices[I].Device.BaseAddress + MappedDevices[I].Count) then begin
    82       Result := MappedDevices[I].Channel.Read(Integer(Address) - MappedDevices[I].Device.BaseAddress, Size);
    83       Break;
    84     end;
     98  if Address < WriteHandlers.Count then
     99    WriteHandlers[Address](Size, Value);
    85100end;
    86101
    87 procedure TDeviceMapper.Write(Address: TBigInt; Size: TBigIntSize; Value: TBigInt);
    88 var
    89   I: Integer;
     102function TDeviceMapper.ChannelGetSize: TInt;
    90103begin
    91   for I := 0 to MappedDevices.Count - 1 do
    92     if (Integer(Address) >= MappedDevices[I].Device.BaseAddress) and
    93     (Integer(Address) < MappedDevices[I].Device.BaseAddress + MappedDevices[I].Count) then begin
    94       MappedDevices[I].Channel.Write(Integer(Address) - MappedDevices[I].Device.BaseAddress, Size, Value);
    95       Break;
    96     end;
     104  Result := Max(ReadHandlers.Count, WriteHandlers.Count);
    97105end;
    98106
    99107procedure TDeviceMapper.SetChannel(Channel: TChannel);
    100108begin
    101   Channel.Read := Read;
    102   Channel.Write := Write;
     109  Channel.Read := ChannelRead;
     110  Channel.Write := ChannelWrite;
     111  Channel.GetSize := ChannelGetSize;
    103112end;
    104113
     
    106115begin
    107116  MappedDevices := TObjectList<TMappedDevice>.Create;
     117  ReadHandlers := TList<TReadEvent>.Create;
     118  WriteHandlers := TList<TWriteEvent>.Create;
    108119end;
    109120
    110121destructor TDeviceMapper.Destroy;
    111122begin
     123  FreeAndNil(ReadHandlers);
     124  FreeAndNil(WriteHandlers);
    112125  FreeAndNil(MappedDevices);
    113126  inherited;
  • branches/ByteArray/Devices/FrameBuffer.pas

    r5 r9  
    44
    55uses
    6   Classes, SysUtils, Device, Channel, Memory, BigInt;
     6  Classes, SysUtils, Device, Channel, Memory, Int;
    77
    88type
     
    1515    FOnChange: TNotifyEvent;
    1616    procedure DoChange;
     17    function ReadData(Size: TIntSize): TInt;
     18    function ReadPosition(Size: TIntSize): TInt;
     19    function ReadWidth(Size: TIntSize): TInt;
     20    function ReadHeight(Size: TIntSize): TInt;
     21    function ReadMode(Size: TIntSize): TInt;
     22    procedure WriteData(Size: TIntSize; Value: TInt);
     23    procedure WritePosition(Size: TIntSize; Value: TInt);
     24    procedure WriteWidth(Size: TIntSize; Value: TInt);
     25    procedure WriteHeight(Size: TIntSize; Value: TInt);
     26    procedure WriteMode(Size: TIntSize; Value: TInt);
    1727  public
    1828    Memory: TMemory;
     
    2232    Mode: TScreenMode;
    2333    procedure UpdateMode;
    24     function Read(Address: TBigInt; Size: TBigIntSize): TBigInt;
    25     procedure Write(Address: TBigInt; Size: TBigIntSize; Value: TBigInt);
    26     function GetAddressCount: Integer; override;
    27     procedure SetChannel(Channel: TChannel); override;
     34    function GetHandlers: THandlers; override;
    2835    constructor Create;
    2936    destructor Destroy; override;
     
    4148end;
    4249
     50function TFrameBuffer.ReadData(Size: TIntSize): TInt;
     51begin
     52  Result := Memory.Read(Position, Size);
     53  Inc(Position, Size);
     54end;
     55
     56function TFrameBuffer.ReadPosition(Size: TIntSize): TInt;
     57begin
     58  Result := Position;
     59end;
     60
     61function TFrameBuffer.ReadWidth(Size: TIntSize): TInt;
     62begin
     63  Result := Width;
     64end;
     65
     66function TFrameBuffer.ReadHeight(Size: TIntSize): TInt;
     67begin
     68  Result := Height;
     69end;
     70
     71function TFrameBuffer.ReadMode(Size: TIntSize): TInt;
     72begin
     73  Result := Byte(Mode);
     74end;
     75
     76procedure TFrameBuffer.WriteData(Size: TIntSize; Value: TInt);
     77begin
     78  Memory.Write(Position, Size, Value);
     79  Inc(Position, Size);
     80end;
     81
     82procedure TFrameBuffer.WritePosition(Size: TIntSize; Value: TInt);
     83begin
     84  Position := Value;
     85end;
     86
     87procedure TFrameBuffer.WriteWidth(Size: TIntSize; Value: TInt);
     88begin
     89  Width := Value;
     90  UpdateMode;
     91end;
     92
     93procedure TFrameBuffer.WriteHeight(Size: TIntSize; Value: TInt);
     94begin
     95  Height := Value;
     96  UpdateMode;
     97end;
     98
     99procedure TFrameBuffer.WriteMode(Size: TIntSize; Value: TInt);
     100begin
     101  Mode := TScreenMode(Integer(Value));
     102  UpdateMode;
     103end;
     104
    43105procedure TFrameBuffer.UpdateMode;
    44106begin
     
    47109end;
    48110
    49 function TFrameBuffer.Read(Address: TBigInt; Size: TBigIntSize): TBigInt;
     111function TFrameBuffer.GetHandlers: THandlers;
    50112begin
    51   case Integer(Address) of
    52     0: begin
    53       Result := Memory.Read(Position, Size);
    54       Inc(Position, Size);
    55     end;
    56     1: Result := Position;
    57     2: Result := Width;
    58     3: Result := Height;
    59     4: Result := Byte(Mode);
    60   end;
    61 end;
    62 
    63 procedure TFrameBuffer.Write(Address: TBigInt; Size: TBigIntSize; Value: TBigInt);
    64 begin
    65   case Integer(Address) of
    66     0: begin
    67       Memory.Write(Position, Size, Value);
    68       Inc(Position, Size);
    69     end;
    70     1: Position := Value;
    71     2: begin
    72       Width := Value;
    73       UpdateMode;
    74     end;
    75     3: begin
    76       Height := Value;
    77       UpdateMode;
    78     end;
    79     4: begin
    80       Mode := TScreenMode(Integer(Value));
    81       UpdateMode;
    82     end;
    83   end;
    84   DoChange;
    85 end;
    86 
    87 function TFrameBuffer.GetAddressCount: Integer;
    88 begin
    89   Result := 5;
    90 end;
    91 
    92 procedure TFrameBuffer.SetChannel(Channel: TChannel);
    93 begin
    94   Channel.Read := Read;
    95   Channel.Write := Write;
     113  Result := THandlers.Create;
     114  Result.ReadHandlers.Add(ReadData);
     115  Result.ReadHandlers.Add(ReadPosition);
     116  Result.ReadHandlers.Add(ReadWidth);
     117  Result.ReadHandlers.Add(ReadHeight);
     118  Result.ReadHandlers.Add(ReadMode);
     119  Result.WriteHandlers.Add(WriteData);
     120  Result.WriteHandlers.Add(WritePosition);
     121  Result.WriteHandlers.Add(WriteWidth);
     122  Result.WriteHandlers.Add(WriteHeight);
     123  Result.WriteHandlers.Add(WriteMode);
    96124end;
    97125
  • branches/ByteArray/Devices/Memory.pas

    r5 r9  
    44
    55uses
    6   Classes, SysUtils, BigInt, Channel, Device;
     6  Classes, SysUtils, Int, Channel, Device;
    77
    88type
     
    1010  { TMemory }
    1111
    12   TMemory = class(TDevice)
     12  TMemory = class(TChannelDevice)
    1313  private
    14     FSize: Integer;
     14    FSize: TInt;
    1515    FData: PByte;
    16     function GetSize: Integer;
    17     procedure SetSize(AValue: Integer);
     16    function GetSize: TInt;
     17    procedure SetSize(AValue: TInt);
    1818    procedure CheckGrow(Address: Integer);
    1919  public
    20     Position: Integer;
     20    Position: TInt;
    2121    Grow: Boolean;
    2222    procedure Assign(Source: TMemory);
    23     function Read(Address: TBigInt; ASize: TBigIntSize): TBigInt;
    24     function ReadPos(ASize: Byte): TBigInt;
    25     procedure Write(Address: TBigInt; ASize: TBigIntSize; Value: TBigInt);
    26     procedure WritePos(ASize: Byte; Value: TBigInt);
     23    function Read(Address: TInt; ASize: TIntSize): TInt;
     24    function ReadPos(ASize: Byte): TInt;
     25    procedure Write(Address: TInt; ASize: TIntSize; Value: TInt);
     26    procedure WritePos(ASize: Byte; Value: TInt);
    2727    procedure WriteStringPos(Value: string);
    2828    procedure WriteMemoryPos(Memory: TMemory);
    29     function GetAddressCount: Integer; override;
    3029    procedure SetChannel(Channel: TChannel); override;
    3130    procedure SaveToFile(FileName: string);
     31    procedure LoadFromFile(FileName: string);
    3232    procedure FillZero;
    3333    procedure Clear;
    34     property Size: Integer read FSize write SetSize;
     34    property Size: TInt read FSize write SetSize;
    3535    destructor Destroy; override;
    3636  end;
     
    4444{ TMemory }
    4545
    46 function TMemory.GetSize: Integer;
     46function TMemory.GetSize: TInt;
    4747begin
    4848  Result := MemSize(FData);
    4949end;
    5050
    51 procedure TMemory.SetSize(AValue: Integer);
     51procedure TMemory.SetSize(AValue: TInt);
    5252begin
    5353  FSize := AValue;
     
    6868end;
    6969
    70 function TMemory.Read(Address: TBigInt; ASize: TBigIntSize): TBigInt;
     70function TMemory.Read(Address: TInt; ASize: TIntSize): TInt;
    7171begin
    7272  if Address + ASize > FSize then raise Exception.Create(SOutOfRange);
     
    7979end;
    8080
    81 function TMemory.ReadPos(ASize: Byte): TBigInt;
     81function TMemory.ReadPos(ASize: Byte): TInt;
    8282begin
    8383  Result := Read(Position, ASize);
     
    8585end;
    8686
    87 procedure TMemory.Write(Address: TBigInt; ASize: TBigIntSize; Value: TBigInt);
     87procedure TMemory.Write(Address: TInt; ASize: TIntSize; Value: TInt);
    8888begin
    8989  if Address + ASize > FSize then raise Exception.Create(SOutOfRange);
     
    9696end;
    9797
    98 procedure TMemory.WritePos(ASize: Byte; Value: TBigInt);
     98procedure TMemory.WritePos(ASize: Byte; Value: TInt);
    9999begin
    100100  CheckGrow(Position + ASize);
     
    126126end;
    127127
    128 function TMemory.GetAddressCount: Integer;
    129 begin
    130   Result := FSize;
    131 end;
    132 
    133128procedure TMemory.SetChannel(Channel: TChannel);
    134129begin
    135130  Channel.Read := Read;
    136131  Channel.Write := Write;
     132  Channel.GetSize := GetSize;
    137133end;
    138134
     
    168164end;
    169165
     166procedure TMemory.LoadFromFile(FileName: string);
     167var
     168  F: TFileStream;
     169begin
     170  F := TFileStream.Create(FileName, fmOpenRead);
     171  try
     172    if FSize < F.Size then Size := F.Size;
     173    F.Read(FData[0], FSize);
     174  finally
     175    F.Free;
     176  end;
     177end;
     178
    170179end.
    171180
  • branches/ByteArray/Devices/Mouse.pas

    r5 r9  
    11unit Mouse;
    2 
    3 {$mode Delphi}
    42
    53interface
  • branches/ByteArray/Devices/Serial.pas

    r5 r9  
    44
    55uses
    6   Classes, SysUtils, Device, BigInt, Channel;
     6  Classes, SysUtils, Device, Int, Channel;
    77
    88type
     
    1717    FOnWrite: TWriteEvent;
    1818  public
    19     function Read(Address: TBigInt; Size: TBigIntSize): TBigInt;
    20     procedure Write(Address: TBigInt; Size: TBigIntSize; Value: TBigInt);
    21     function GetAddressCount: Integer; override;
    22     procedure SetChannel(Channel: TChannel); override;
     19    function ReadData(Size: TIntSize): TInt;
     20    procedure WriteData(Size: TIntSize; Value: TInt);
     21    function GetHandlers: THandlers; override;
    2322    property OnWrite: TWriteEvent read FOnWrite write FOnWrite;
    2423    property OnRead: TReadEvent read FOnRead write FOnRead;
     
    3029{ TSerial }
    3130
    32 function TSerial.Read(Address: TBigInt; Size: TBigIntSize): TBigInt;
     31function TSerial.ReadData(Size: TIntSize): TInt;
    3332begin
    34   case Integer(Address) of
    35     0: if Assigned(FOnRead) then Result := FOnRead;
    36   end;
     33  if Assigned(FOnRead) then Result := FOnRead;
    3734end;
    3835
    39 procedure TSerial.Write(Address: TBigInt; Size: TBigIntSize; Value: TBigInt);
     36procedure TSerial.WriteData(Size: TIntSize; Value: TInt);
    4037begin
    41   case Integer(Address) of
    42     0: if Assigned(FOnWrite) then FOnWrite(Value);
    43   end;
     38  if Assigned(FOnWrite) then FOnWrite(Value);
    4439end;
    4540
    46 function TSerial.GetAddressCount: Integer;
     41function TSerial.GetHandlers: THandlers;
    4742begin
    48   Result := 1;
    49 end;
    50 
    51 procedure TSerial.SetChannel(Channel: TChannel);
    52 begin
    53   Channel.Read := Read;
    54   Channel.Write := Write;
     43  Result := THandlers.Create;
     44  Result.ReadHandlers.Add(ReadData);
     45  Result.WriteHandlers.Add(WriteData);
    5546end;
    5647
  • branches/ByteArray/Devices/Storage.pas

    r5 r9  
    44
    55uses
    6   Classes, SysUtils, Device, Channel, BigInt;
     6  Classes, SysUtils, Device, Channel, Int;
    77
    88type
     
    1919    FFile: TFileStream;
    2020    Position: Integer;
    21     function ReadByte(Address: TBigInt): Byte;
    22     function Read(Address: TBigInt; Size: TBigIntSize): TBigInt;
    23     procedure Write(Address: TBigInt; Size: TBigIntSize; Value: TBigInt);
    24     function GetAddressCount: Integer; override;
    25     procedure SetChannel(Channel: TChannel); override;
     21    function ReadByte(Address: TInt): Byte;
     22    function ReadData(Size: TIntSize): TInt;
     23    function ReadPosition(Size: TIntSize): TInt;
     24    function ReadSize(Size: TIntSize): TInt;
     25    procedure WriteData(Size: TIntSize; Value: TInt);
     26    procedure WritePosition(Size: TIntSize; Value: TInt);
     27    procedure WriteSize(Size: TIntSize; Value: TInt);
     28    function GetHandlers: THandlers; override;
    2629    constructor Create;
    2730    destructor Destroy; override;
     
    5659end;
    5760
    58 function TStorage.ReadByte(Address: TBigInt): Byte;
     61function TStorage.ReadByte(Address: TInt): Byte;
    5962begin
    6063  Result := 0;
     
    6366end;
    6467
    65 function TStorage.Read(Address: TBigInt; Size: TBigIntSize): TBigInt;
    66 var
    67   Buffer: array of Byte;
     68function TStorage.ReadData(Size: TIntSize): TInt;
    6869begin
    69   case Integer(Address) of
    70     0: begin
    71       SetLength(Buffer, Size);
    72       FFile.Position := Position;
    73       FFile.Read(Buffer[0], Size);
    74       Result.SetByteArray(Buffer, Size);
    75       Inc(Position, Size);
    76     end;
    77     1: Result := Position;
    78     2: Result := FFile.Size;
    79   end;
     70  FFile.Position := Position;
     71  FFile.Read(Result, Size);
     72  Inc(Position, Size);
    8073end;
    8174
    82 procedure TStorage.Write(Address: TBigInt; Size: TBigIntSize; Value: TBigInt);
    83 var
    84   Buffer: array of Byte;
     75function TStorage.ReadPosition(Size: TIntSize): TInt;
    8576begin
    86   case Integer(Address) of
    87     0: begin
    88       SetLength(Buffer, Size);
    89       Value.GetByteArray(Buffer, Size);
    90       FFile.Position := Position;
    91       FFile.Write(Buffer[1], Size);
    92       Inc(Position, Size);
    93     end;
    94     1: Position := Value;
    95     2: FFile.Size := Value;
    96   end;
     77  Result := Position;
    9778end;
    9879
    99 function TStorage.GetAddressCount: Integer;
     80function TStorage.ReadSize(Size: TIntSize): TInt;
    10081begin
    101   Result := 3;
     82  Result := FFile.Size;
    10283end;
    10384
    104 procedure TStorage.SetChannel(Channel: TChannel);
     85procedure TStorage.WriteData(Size: TIntSize; Value: TInt);
    10586begin
    106   Channel.Read := Read;
    107   Channel.Write := Write;
     87  FFile.Position := Position;
     88  FFile.Write(Value, Size);
     89  Inc(Position, Size);
     90end;
     91
     92procedure TStorage.WritePosition(Size: TIntSize; Value: TInt);
     93begin
     94  Position := Value;
     95end;
     96
     97procedure TStorage.WriteSize(Size: TIntSize; Value: TInt);
     98begin
     99  FFile.Size := Value;
     100end;
     101function TStorage.GetHandlers: THandlers;
     102begin
     103  Result := THandlers.Create;
     104  Result.ReadHandlers.Add(ReadData);
     105  Result.ReadHandlers.Add(ReadPosition);
     106  Result.ReadHandlers.Add(ReadSize);
     107  Result.WriteHandlers.Add(WriteData);
     108  Result.WriteHandlers.Add(WritePosition);
     109  Result.WriteHandlers.Add(WriteSize);
    108110end;
    109111
Note: See TracChangeset for help on using the changeset viewer.