2
This file is part of the Free Pascal simulator environment
3
Copyright (c) 1999-2000 by Florian Klaempfl
5
This unit implemements a memory manager for 64 bit processor
6
simulations, it works also with TP
8
See the file COPYING.FPC, included in this distribution,
9
for details about the copyright.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
**********************************************************************}
16
{ a simple 64 bit simulator memory manager, also running with TP }
26
memoryblocksize = 32768;
30
tmemoryblock = array[0..memoryblocksize-1] of byte;
31
pmemoryblock = ^tmemoryblock;
33
pmemoryarea = ^tmemoryarea;
36
memory : pmemoryblock;
41
tmemorymanager = object
44
{ "memory" access routines }
45
function readalignedq(addr : taddr) : qword;
46
function readq(addr : taddr) : qword;
47
function readalignedd(addr : taddr) : dword;
48
function readd(addr : taddr) : dword;
49
function readb(addr : taddr) : dword;
50
procedure writeb(addr : taddr;b : byte);
51
procedure writealignedd(addr : taddr;d : dword);
52
procedure writed(addr : taddr;d : dword);
53
procedure writeq(addr : taddr;q : qword);
54
procedure allocate(addr : taddr;size : qword);
58
{ address of the currently executed instruction, }
59
{ necessary for correct output of exception }
60
instructionpc : taddr;
64
procedure exception(const s : string;addr : taddr);
68
writeln('Exception: ',s,' at $',qword2str(addr));
72
constructor tmemorymanager.init;
78
procedure tmemorymanager.allocate(addr : taddr;size : qword);
93
getmem(ma^.memory,trunc(asize));
94
fillchar(ma^.memory^,trunc(asize),0);
95
ma^.size:=trunc(asize);
104
function tmemorymanager.readq(addr : taddr) : qword;
113
while assigned(ma) do
115
if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
117
if addr<ma^.addr+ma^.size-7 then
119
move(ma^.memory^[trunc(addr-ma^.addr)],h,8);
125
qw.low32:=readd(addr);
126
qw.high32:=readd(addr+4);
133
exception('Access violation to $'+qword2str(addr),instructionpc);
136
function tmemorymanager.readalignedq(addr : taddr) : qword;
144
if (tqwordrec(addr).low32 and $7)<>0 then
145
exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
147
while assigned(ma) do
149
if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
151
move(ma^.memory^[trunc(addr-ma^.addr)],h,8);
157
exception('Access violation to $'+qword2str(addr),instructionpc);
160
function tmemorymanager.readd(addr : taddr) : dword;
168
while assigned(ma) do
170
if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
172
if addr<ma^.addr+ma^.size-3 then
174
move(ma^.memory^[trunc(addr-ma^.addr)],h,4);
180
readd:=readb(addr)+readb(addr+1) shl 8+readb(addr+2) shl 16+
181
readb(addr+3) shl 24;
187
exception('Access violation to $'+qword2str(addr),instructionpc);
190
function tmemorymanager.readalignedd(addr : taddr) : dword;
197
if (tqwordrec(addr).low32 and $3)<>0 then
198
exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
200
while assigned(ma) do
202
if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
204
move(ma^.memory^[trunc(addr-ma^.addr)],h,4);
210
exception('Access violation to $'+qword2str(addr),instructionpc);
213
function tmemorymanager.readb(addr : taddr) : dword;
220
while assigned(ma) do
222
if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
224
readb:=ma^.memory^[trunc(addr-ma^.addr)];
229
exception('Access violation to $'+qword2str(addr),instructionpc);
232
procedure tmemorymanager.writeb(addr : taddr;b : byte);
239
while assigned(ma) do
241
if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
243
ma^.memory^[trunc(addr-ma^.addr)]:=b;
248
exception('Access violation to $'+qword2str(addr),instructionpc);
251
procedure tmemorymanager.writed(addr : taddr;d : dword);
254
writeb(addr,tdword(d)[0]);
255
writeb(addr+1,tdword(d)[1]);
256
writeb(addr+2,tdword(d)[2]);
257
writeb(addr+3,tdword(d)[3]);
260
procedure tmemorymanager.writealignedd(addr : taddr;d : dword);
263
writeb(addr,tdword(d)[0]);
264
writeb(addr+1,tdword(d)[1]);
265
writeb(addr+2,tdword(d)[2]);
266
writeb(addr+3,tdword(d)[3]);
269
procedure tmemorymanager.writeq(addr : taddr;q : qword);
276
while assigned(ma) do
278
if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size-7) then
280
move(q,ma^.memory^[trunc(addr-ma^.addr)],8);
284
{ misaligned write! }
285
if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
287
writeln('Not implemented 1!');
292
exception('Access violation to $'+qword2str(addr),instructionpc);