source: trunk/MemoryTypes.pas

Last change on this file was 13, checked in by chronos, 2 weeks ago
  • Added: Call stack window.
  • Modified: Use reload pending boolean variable and reload from timer instead of Thread.Synchronize to not delay CPU execution.
File size: 4.8 KB
Line 
1unit MemoryTypes;
2
3interface
4
5uses
6 Classes, SysUtils, Generics.Collections, Base;
7
8type
9
10 { TMemory }
11
12 TMemory = class
13 private
14 function GetSize: Integer; virtual;
15 procedure SetSize(AValue: Integer); virtual; abstract;
16 public
17 Title: string;
18 Position: Integer;
19 function Read(Address: Word): Byte; virtual; abstract;
20 procedure Write(Address: Word; Data: Byte); virtual; abstract;
21 function ReadByte: Byte;
22 function ReadWord: Word;
23 procedure LoadFromFile(FileName: string); virtual; abstract;
24 destructor Destroy; override;
25 property Size: Integer read GetSize write SetSize;
26 end;
27
28 { TMemoryData }
29
30 TMemoryData = class(TMemory)
31 DataPtr: PByte;
32 function GetSize: Integer; override;
33 procedure SetSize(AValue: Integer); override;
34 function Read(Address: Word): Byte; override;
35 procedure Write(Address: Word; Data: Byte); override;
36 procedure LoadFromFile(FileName: string); override;
37 end;
38
39 { TMemoryIO }
40
41 TMemoryIO = class(TMemory)
42 private
43 FOnInput: TReadEvent;
44 FOnOutput: TWriteEvent;
45 FSize: Integer;
46 public
47 BasePort: Byte;
48 function GetSize: Integer; override;
49 procedure SetSize(AValue: Integer); override;
50 function Read(Address: Word): Byte; override;
51 procedure Write(Address: Word; Data: Byte); override;
52 property OnInput: TReadEvent read FOnInput write FOnInput;
53 property OnOutput: TWriteEvent read FOnOutput write FOnOutput;
54 end;
55
56 { TMemoryMappedArea }
57
58 TMemoryMappedArea = class
59 Base: Word;
60 Memory: TMemory;
61 function InRange(Address: Word): Boolean;
62 end;
63
64 { TMemoryMappedAreas }
65
66 TMemoryMappedAreas = class(TObjectList<TMemoryMappedArea>)
67 function AddNew(Base: Word; Memory: TMemory): TMemoryMappedArea;
68 end;
69
70 { TMemoryMapped }
71
72 TMemoryMapped = class(TMemory)
73 private
74 FSize: Integer;
75 public
76 Areas: TMemoryMappedAreas;
77 function GetSize: Integer; override;
78 procedure SetSize(AValue: Integer); override;
79 function Read(Address: Word): Byte; override;
80 procedure Write(Address: Word; Data: Byte); override;
81 constructor Create;
82 destructor Destroy; override;
83 end;
84
85
86implementation
87
88{ TMemoryMappedAreas }
89
90function TMemoryMappedAreas.AddNew(Base: Word; Memory: TMemory): TMemoryMappedArea;
91begin
92 Result := TMemoryMappedArea.Create;
93 Result.Base := Base;
94 Result.Memory := Memory;
95 Add(Result);
96end;
97
98{ TMemoryMappedArea }
99
100function TMemoryMappedArea.InRange(Address: Word): Boolean;
101begin
102 Result := (Address >= Base) and (Address < (Base + Memory.Size));
103end;
104
105{ TMemoryMapped }
106
107function TMemoryMapped.GetSize: Integer;
108begin
109 Result := FSize;
110end;
111
112procedure TMemoryMapped.SetSize(AValue: Integer);
113begin
114 FSize := AValue;
115end;
116
117function TMemoryMapped.Read(Address: Word): Byte;
118var
119 I: Integer;
120begin
121 for I := 0 to Areas.Count - 1 do
122 if Areas[I].InRange(Address) then begin
123 Result := Areas[I].Memory.Read(Address - Areas[I].Base);
124 Break;
125 end;
126end;
127
128procedure TMemoryMapped.Write(Address: Word; Data: Byte);
129var
130 I: Integer;
131begin
132 for I := 0 to Areas.Count - 1 do
133 if Areas[I].InRange(Address) then begin
134 Areas[I].Memory.Write(Address - Areas[I].Base, Data);
135 Break;
136 end;
137end;
138
139constructor TMemoryMapped.Create;
140begin
141 inherited;
142 Areas := TMemoryMappedAreas.Create;
143end;
144
145destructor TMemoryMapped.Destroy;
146begin
147 FreeAndNil(Areas);
148 inherited;
149end;
150
151{ TMemoryData }
152
153function TMemoryData.GetSize: Integer;
154begin
155 Result := MemSize(DataPtr);
156end;
157
158procedure TMemoryData.SetSize(AValue: Integer);
159begin
160 ReAllocMem(DataPtr, AValue);
161end;
162
163function TMemoryData.Read(Address: Word): Byte;
164begin
165 Result := PByte(DataPtr + Address)^;
166end;
167
168procedure TMemoryData.Write(Address: Word; Data: Byte);
169begin
170 PByte(DataPtr + Address)^ := Data;
171end;
172
173procedure TMemoryData.LoadFromFile(FileName: string);
174var
175 FileStream: TFileStream;
176begin
177 FileStream := TFileStream.Create(FileName, fmOpenRead);
178 try
179 Size := FileStream.Size;
180 FileStream.Read(DataPtr^, FileStream.Size);
181 finally
182 FreeAndNil(FileStream);
183 end;
184end;
185
186{ TMemoryIO }
187
188function TMemoryIO.GetSize: Integer;
189begin
190 Result := FSize;
191end;
192
193procedure TMemoryIO.SetSize(AValue: Integer);
194begin
195 FSize := AVAlue;
196end;
197
198function TMemoryIO.Read(Address: Word): Byte;
199begin
200 if Assigned(FOnInput) then FOnInput(BasePort + Address);
201end;
202
203procedure TMemoryIO.Write(Address: Word; Data: Byte);
204begin
205 if Assigned(FOnOutput) then FOnOutput(BasePort + Address, Data);
206end;
207
208{ TMemory }
209
210function TMemory.GetSize: Integer;
211begin
212 Result := 0;
213end;
214
215function TMemory.ReadByte: Byte;
216begin
217 if Position < Size then Result := Read(Position)
218 else Result := 0;
219 Position := Position + SizeOf(Byte);
220end;
221
222function TMemory.ReadWord: Word;
223begin
224 Result := Read(Position) or (Read(Position + 1) shl 8);
225 Position := Position + SizeOf(Word);
226end;
227
228destructor TMemory.Destroy;
229begin
230 Size := 0;
231 inherited;
232end;
233
234end.
235
Note: See TracBrowser for help on using the repository browser.