source: branches/simple/DeviceManager.pas

Last change on this file was 42, checked in by chronos, 9 months ago
  • Modified: Improved simple virtual machine.
File size: 4.6 KB
Line 
1unit DeviceManager;
2
3interface
4
5uses
6 Classes, SysUtils, Channel, Device, Generics.Collections;
7
8type
9 TReadEvent8 = function: Byte of object;
10 TReadEvent16 = function: Word of object;
11 TWriteEvent8 = procedure (Data: Byte) of object;
12 TWriteEvent16 = procedure (Data: Word) of object;
13
14 { TDeviceManager8 }
15
16 TDeviceManager8 = class(TDevice8)
17 private
18 FreeBaseAddress: Byte;
19 Handlers: TObjectList<TChannel8>;
20 Devices: TObjectList<TDevice8>;
21 procedure RebuildHandlers;
22 public
23 procedure Write8(Address: Byte; Data: Byte);
24 function Read8(Address: Byte): Byte;
25 procedure SetDataBus(Channel: TAddressableChannel8); override;
26 procedure RegisterDevice(Device: TDevice8);
27 procedure UnregisterDevice(Device: TDevice8);
28 constructor Create;
29 destructor Destroy; override;
30 end;
31
32 { TDeviceManager16 }
33
34 TDeviceManager16 = class(TDevice16)
35 private
36 FreeBaseAddress: Byte;
37 Handlers: TObjectList<TChannel16>;
38 Devices: TObjectList<TDevice16>;
39 procedure RebuildHandlers;
40 public
41 function GetFreeHandler: TChannel16;
42 function Read8(Address: Word): Byte;
43 function Read16(Address: Word): Word;
44 procedure Write8(Address: Word; Data: Byte);
45 procedure Write16(Address: Word; Data: Word);
46 procedure SetDataBus(Channel: TAddressableChannel16); override;
47 procedure RegisterDevice(Device: TDevice16);
48 procedure UnregisterDevice(Device: TDevice16);
49 constructor Create;
50 destructor Destroy; override;
51 end;
52
53 TDeviceManager = class(TDevice)
54 BitWidth: TBitWidth;
55 DeviceManager8: TDeviceManager8;
56 DeviceManager16: TDeviceManager16;
57 end;
58
59
60implementation
61
62{ TDeviceManager16 }
63
64procedure TDeviceManager16.RebuildHandlers;
65var
66 I, J: Integer;
67begin
68 for I := 0 to Devices.Count - 1 do begin
69 if Handlers.Count < Devices[I].BaseAddress + Devices[I].GetHandlerCount then
70 Handlers.Count := Devices[I].BaseAddress + Devices[I].GetHandlerCount;
71 for J := 0 to Devices[I].GetHandlerCount - 1 do
72 Handlers[Devices[I].BaseAddress + J] := Devices[I].GetHandler(J);
73 end;
74end;
75
76function TDeviceManager16.GetFreeHandler: TChannel16;
77begin
78 Result := TChannel16.Create;
79 Handlers.Add(Result);
80end;
81
82function TDeviceManager16.Read8(Address: Word): Byte;
83begin
84 Result := Handlers[Address].Read8;
85end;
86
87function TDeviceManager16.Read16(Address: Word): Word;
88begin
89 Result := Handlers[Address].Read16;
90end;
91
92procedure TDeviceManager16.Write8(Address: Word; Data: Byte);
93begin
94 Handlers[Address].Write8(Data);
95end;
96
97procedure TDeviceManager16.Write16(Address: Word; Data: Word);
98begin
99 Handlers[Address].Write16(Data);
100end;
101
102procedure TDeviceManager16.SetDataBus(Channel: TAddressableChannel16);
103begin
104 Channel.Read8 := Read8;
105 Channel.Read16 := Read16;
106 Channel.Write8 := Write8;
107 Channel.Write16 := Write16;
108end;
109
110procedure TDeviceManager16.RegisterDevice(Device: TDevice16);
111begin
112 Devices.Add(Device);
113 Device.BaseAddress := FreeBaseAddress;
114 Inc(FreeBaseAddress, Device.GetHandlerCount);
115 RebuildHandlers;
116end;
117
118procedure TDeviceManager16.UnregisterDevice(Device: TDevice16);
119begin
120 Devices.Remove(Device);
121 RebuildHandlers;
122end;
123
124constructor TDeviceManager16.Create;
125begin
126 Handlers := TObjectList<TChannel16>.Create;
127 Devices := TObjectList<TDevice16>.Create;
128end;
129
130destructor TDeviceManager16.Destroy;
131begin
132 FreeAndNil(Devices);
133 FreeAndNil(Handlers);
134 inherited;
135end;
136
137{ TDeviceManager8 }
138
139procedure TDeviceManager8.RebuildHandlers;
140var
141 I, J: Integer;
142begin
143 for I := 0 to Devices.Count - 1 do begin
144 if Handlers.Count < Devices[I].BaseAddress + Devices[I].GetHandlerCount then
145 Handlers.Count := Devices[I].BaseAddress + Devices[I].GetHandlerCount;
146 for J := 0 to Devices[I].GetHandlerCount - 1 do
147 Handlers[Devices[I].BaseAddress + J] := Devices[I].GetHandler(J);
148 end;
149end;
150
151procedure TDeviceManager8.Write8(Address: Byte; Data: Byte);
152begin
153 Handlers[Address].Write8(Data);
154end;
155
156function TDeviceManager8.Read8(Address: Byte): Byte;
157begin
158 Result := Handlers[Address].Read8;
159end;
160
161procedure TDeviceManager8.SetDataBus(Channel: TAddressableChannel8);
162begin
163 Channel.Read8 := Read8;
164 Channel.Write8 := Write8;
165end;
166
167procedure TDeviceManager8.RegisterDevice(Device: TDevice8);
168begin
169 Devices.Add(Device);
170 Device.BaseAddress := FreeBaseAddress;
171 Inc(FreeBaseAddress, Device.GetHandlerCount);
172 RebuildHandlers;
173end;
174
175procedure TDeviceManager8.UnregisterDevice(Device: TDevice8);
176begin
177 Devices.Remove(Device);
178 RebuildHandlers;
179end;
180
181constructor TDeviceManager8.Create;
182begin
183 Handlers := TObjectList<TChannel8>.Create;
184 Devices := TObjectList<TDevice8>.Create;
185end;
186
187destructor TDeviceManager8.Destroy;
188begin
189 FreeAndNil(Devices);
190 FreeAndNil(Handlers);
191 inherited;
192end;
193
194end.
195
Note: See TracBrowser for help on using the repository browser.