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 needs a 32 bit compiler to be compiled
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
**********************************************************************}
27
tmemorymanager = object
28
mem : array[0..65535] of pbyte;
30
{ "memory" access routines }
31
function readalignedq(addr : taddr) : qword;
32
function readq(addr : taddr) : qword;
33
function readalignedd(addr : taddr) : dword;
34
function readd(addr : taddr) : dword;
35
function readb(addr : taddr) : dword;
36
procedure writeb(addr : taddr;b : byte);
37
procedure writealignedd(addr : taddr;d : dword);
38
procedure writed(addr : taddr;d : dword);
39
procedure writeq(addr : taddr;q : qword);
40
procedure allocate(addr : taddr;size : qword);
44
{ address of the currently executed instruction, }
45
{ necessary for correct output of exception }
46
instructionpc : taddr;
50
procedure exception(const s : string;addr : taddr);
54
writeln('Exception: ',s,' at $',qword2str(addr));
59
constructor tmemorymanager.init;
62
fillchar(mem,sizeof(mem),0);
65
procedure tmemorymanager.allocate(addr : taddr;size : qword);
67
procedure allocateblock(addr : taddr);
73
if (tqwordrec(addr).high32 and $fffffff0)<>0 then
75
writeln('This memory manager supports only 36 bit');
76
writeln('Base address was ',qword2str(addr));
79
upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
80
if not(assigned(mem[upperbits])) then
82
getmem(mem[upperbits],1024*1024);
83
fillchar(mem[upperbits]^,1024*1024,0);
93
if size>1024*1024 then
103
function tmemorymanager.readq(addr : taddr) : qword;
109
tqwordrec(h).low32:=readd(addr);
110
tqwordrec(h).high32:=readd(addr+4);
114
function tmemorymanager.readd(addr : taddr) : dword;
117
readd:=readb(addr)+readb(addr+1) shl 8+readb(addr+2) shl 16+
118
readb(addr+3) shl 24;
121
function tmemorymanager.readalignedd(addr : taddr) : dword;
127
if (tqwordrec(addr).low32 and $3)<>0 then
128
exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
129
upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
130
if not(assigned(mem[upperbits])) then
131
exception('Access violation to $'+qword2str(addr),instructionpc);
132
readalignedd:=pdword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 2];
135
function tmemorymanager.readalignedq(addr : taddr) : qword;
141
if (tqwordrec(addr).low32 and $7)<>0 then
142
exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
143
upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
144
if not(assigned(mem[upperbits])) then
145
exception('Access violation to $'+qword2str(addr),instructionpc);
146
readalignedq:=pqword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 3];
149
function tmemorymanager.readb(addr : taddr) : dword;
155
upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
156
if not(assigned(mem[upperbits])) then
157
exception('Access violation to $'+qword2str(addr),instructionpc);
158
readb:=mem[upperbits,tqwordrec(addr).low32 and $fffff];
161
procedure tmemorymanager.writeb(addr : taddr;b : byte);
167
upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
168
if not(assigned(mem[upperbits])) then
169
exception('Access violation to $'+qword2str(addr),instructionpc);
170
mem[upperbits,tqwordrec(addr).low32 and $fffff]:=b;
173
procedure tmemorymanager.writealignedd(addr : taddr;d : dword);
179
if (tqwordrec(addr).low32 and $3)<>0 then
180
exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
181
upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
182
if not(assigned(mem[upperbits])) then
183
exception('Access violation to $'+qword2str(addr),instructionpc);
184
pdword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 2]:=d;
187
procedure tmemorymanager.writed(addr : taddr;d : dword);
190
writeb(addr,tdword(d)[0]);
191
writeb(addr+1,tdword(d)[1]);
192
writeb(addr+2,tdword(d)[2]);
193
writeb(addr+3,tdword(d)[3]);
196
procedure tmemorymanager.writeq(addr : taddr;q : qword);
199
writed(addr,tqwordrec(q).low32);
200
writed(addr+4,tqwordrec(q).high32);