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:
2 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/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;
Note: See TracChangeset for help on using the changeset viewer.