source: branches/ByteArray/Devices/IntMemory.pas

Last change on this file was 11, checked in by chronos, 2 months ago
  • Modified: Updated Common package.
  • Fixed: Wrong return address from CALL instruction.
File size: 4.3 KB
Line 
1unit IntMemory;
2
3interface
4
5uses
6 Classes, SysUtils, Int, Channel, Device;
7
8type
9
10 { TMemory }
11
12 TMemory = class(TChannelDevice)
13 private
14 FSize: TInt;
15 FData: PByte;
16 function GetSize: TInt;
17 procedure SetSize(AValue: TInt);
18 procedure CheckGrow(Address: Integer);
19 public
20 Position: TInt;
21 Grow: Boolean;
22 procedure Assign(Source: TMemory);
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);
27 procedure WriteStringPos(Value: string);
28 procedure WriteMemoryPos(Memory: TMemory);
29 procedure SetChannel(Channel: TChannel); override;
30 procedure SaveToFile(FileName: string);
31 procedure LoadFromFile(FileName: string);
32 procedure FillZero;
33 procedure Clear;
34 function ToString: string; override;
35 property Size: TInt read FSize write SetSize;
36 constructor Create;
37 destructor Destroy; override;
38 end;
39
40
41implementation
42
43resourcestring
44 SOutOfRange = 'Address out of range.';
45
46{ TMemory }
47
48function TMemory.GetSize: TInt;
49begin
50 Result := MemSize(FData);
51end;
52
53procedure TMemory.SetSize(AValue: TInt);
54begin
55 FSize := AValue;
56 FData := ReAllocMem(FData, AValue);
57end;
58
59procedure TMemory.CheckGrow(Address: Integer);
60begin
61 if Grow and (Size < Address) then Size := Address;
62end;
63
64procedure TMemory.Assign(Source: TMemory);
65begin
66 Size := Source.Size;
67 if FSize > 0 then
68 Move(Source.FData[0], FData[0], FSize);
69 Position := Source.Position;
70end;
71
72function TMemory.Read(Address: TInt; ASize: TIntSize): TInt;
73begin
74 if Address + ASize > FSize then raise Exception.Create(SOutOfRange);
75 case ASize of
76 1: Result := PByte(FData + Integer(Address))^;
77 2: Result := PWord(FData + Integer(Address))^;
78 4: Result := PDWord(FData + Integer(Address))^;
79 8: Result := PQWord(FData + Integer(Address))^;
80 end;
81end;
82
83function TMemory.ReadPos(ASize: Byte): TInt;
84begin
85 Result := Read(Position, ASize);
86 Inc(Position, ASize);
87end;
88
89procedure TMemory.Write(Address: TInt; ASize: TIntSize; Value: TInt);
90begin
91 if Address + ASize > FSize then raise Exception.Create(SOutOfRange);
92 case ASize of
93 1: PByte(FData + Integer(Address))^ := Value;
94 2: PWord(FData + Integer(Address))^ := Value;
95 4: PDWord(FData + Integer(Address))^ := Value;
96 8: PQWord(FData + Integer(Address))^ := Value;
97 end;
98end;
99
100procedure TMemory.WritePos(ASize: Byte; Value: TInt);
101begin
102 CheckGrow(Position + ASize);
103 Write(Position, ASize, Value);
104 Inc(Position, ASize);
105end;
106
107procedure TMemory.WriteStringPos(Value: string);
108var
109 I: Integer;
110begin
111 CheckGrow(Position + Length(Value));
112 if Length(Value) > 0 then begin
113 if Position + Length(Value) > FSize then Size := Position + Length(Value);
114 for I := 0 to Length(Value) - 1 do
115 Write(Position + I, 1, Ord(Value[I + 1]));
116 Inc(Position, Length(Value));
117 end;
118end;
119
120procedure TMemory.WriteMemoryPos(Memory: TMemory);
121begin
122 CheckGrow(Position + Memory.Size);
123 if Memory.Size > 0 then begin
124 if Position + Memory.Size > FSize then Size := Position + Memory.Size;
125 Move(Memory.FData[0], FData[Position], Memory.Size);
126 Inc(Position, Memory.Size);
127 end;
128end;
129
130procedure TMemory.SetChannel(Channel: TChannel);
131begin
132 Channel.Read := Read;
133 Channel.Write := Write;
134 Channel.GetSize := GetSize;
135end;
136
137procedure TMemory.FillZero;
138begin
139 FillChar(FData^, FSize, 0);
140end;
141
142procedure TMemory.Clear;
143begin
144 Size := 0;
145 Position := 0;
146end;
147
148function TMemory.ToString: string;
149var
150 I: Integer;
151begin
152 Result := '';
153 for I := 0 to FSize - 1 do
154 Result := Result + ', ' + IntToStr(FData[I]);
155 Delete(Result, 1, 2);
156end;
157
158constructor TMemory.Create;
159begin
160 FSize := 0;
161end;
162
163destructor TMemory.Destroy;
164begin
165 Size := 0;
166 inherited;
167end;
168
169procedure TMemory.SaveToFile(FileName: string);
170var
171 F: TFileStream;
172begin
173 if FileExists(FileName) then
174 F := TFileStream.Create(FileName, fmOpenWrite)
175 else F := TFileStream.Create(FileName, fmCreate);
176 try
177 if FSize > 0 then F.Write(FData[0], FSize);
178 finally
179 F.Free;
180 end;
181end;
182
183procedure TMemory.LoadFromFile(FileName: string);
184var
185 F: TFileStream;
186begin
187 F := TFileStream.Create(FileName, fmOpenRead);
188 try
189 if FSize < F.Size then Size := F.Size;
190 F.Read(FData[0], FSize);
191 finally
192 F.Free;
193 end;
194end;
195
196end.
197
Note: See TracBrowser for help on using the repository browser.