123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- {
- This file is part of the Free Pascal simulator environment
- Copyright (c) 1999-2000 by Florian Klaempfl
- This unit implemements a memory manager for 64 bit processor
- simulations, it needs a 32 bit compiler to be compiled
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {$N+}
- unit fastmm64;
- interface
- uses
- simbase;
- type
- taddr = qword;
- tmemorymanager = object
- mem : array[0..65535] of pbyte;
- constructor init;
- { "memory" access routines }
- function readalignedq(addr : taddr) : qword;
- function readq(addr : taddr) : qword;
- function readalignedd(addr : taddr) : dword;
- function readd(addr : taddr) : dword;
- function readb(addr : taddr) : dword;
- procedure writeb(addr : taddr;b : byte);
- procedure writealignedd(addr : taddr;d : dword);
- procedure writed(addr : taddr;d : dword);
- procedure writeq(addr : taddr;q : qword);
- procedure allocate(addr : taddr;size : qword);
- end;
- var
- { address of the currently executed instruction, }
- { necessary for correct output of exception }
- instructionpc : taddr;
- implementation
- procedure exception(const s : string;addr : taddr);
- begin
- writeln;
- writeln('Exception: ',s,' at $',qword2str(addr));
- runerror(255);
- stopsim;
- end;
- constructor tmemorymanager.init;
- begin
- fillchar(mem,sizeof(mem),0);
- end;
- procedure tmemorymanager.allocate(addr : taddr;size : qword);
- procedure allocateblock(addr : taddr);
- var
- upperbits : longint;
- begin
- if (tqwordrec(addr).high32 and $fffffff0)<>0 then
- begin
- writeln('This memory manager supports only 36 bit');
- writeln('Base address was ',qword2str(addr));
- halt(1);
- end;
- upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
- if not(assigned(mem[upperbits])) then
- begin
- getmem(mem[upperbits],1024*1024);
- fillchar(mem[upperbits]^,1024*1024,0);
- end;
- end;
- var
- asize : qword;
- begin
- while size>0 do
- begin
- if size>1024*1024 then
- asize:=1024*1024;
- allocateblock(addr);
- if asize>size then
- break;
- size:=size-asize;
- addr:=addr+asize;
- end;
- end;
- function tmemorymanager.readq(addr : taddr) : qword;
- var
- h : qword;
- begin
- tqwordrec(h).low32:=readd(addr);
- tqwordrec(h).high32:=readd(addr+4);
- readq:=h;
- end;
- function tmemorymanager.readd(addr : taddr) : dword;
- begin
- readd:=readb(addr)+readb(addr+1) shl 8+readb(addr+2) shl 16+
- readb(addr+3) shl 24;
- end;
- function tmemorymanager.readalignedd(addr : taddr) : dword;
- var
- upperbits : longint;
- begin
- if (tqwordrec(addr).low32 and $3)<>0 then
- exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
- upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
- if not(assigned(mem[upperbits])) then
- exception('Access violation to $'+qword2str(addr),instructionpc);
- readalignedd:=pdword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 2];
- end;
- function tmemorymanager.readalignedq(addr : taddr) : qword;
- var
- upperbits : longint;
- begin
- if (tqwordrec(addr).low32 and $7)<>0 then
- exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
- upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
- if not(assigned(mem[upperbits])) then
- exception('Access violation to $'+qword2str(addr),instructionpc);
- readalignedq:=pqword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 3];
- end;
- function tmemorymanager.readb(addr : taddr) : dword;
- var
- upperbits : longint;
- begin
- upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
- if not(assigned(mem[upperbits])) then
- exception('Access violation to $'+qword2str(addr),instructionpc);
- readb:=mem[upperbits,tqwordrec(addr).low32 and $fffff];
- end;
- procedure tmemorymanager.writeb(addr : taddr;b : byte);
- var
- upperbits : longint;
- begin
- upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
- if not(assigned(mem[upperbits])) then
- exception('Access violation to $'+qword2str(addr),instructionpc);
- mem[upperbits,tqwordrec(addr).low32 and $fffff]:=b;
- end;
- procedure tmemorymanager.writealignedd(addr : taddr;d : dword);
- var
- upperbits : longint;
- begin
- if (tqwordrec(addr).low32 and $3)<>0 then
- exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
- upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
- if not(assigned(mem[upperbits])) then
- exception('Access violation to $'+qword2str(addr),instructionpc);
- pdword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 2]:=d;
- end;
- procedure tmemorymanager.writed(addr : taddr;d : dword);
- begin
- writeb(addr,tdword(d)[0]);
- writeb(addr+1,tdword(d)[1]);
- writeb(addr+2,tdword(d)[2]);
- writeb(addr+3,tdword(d)[3]);
- end;
- procedure tmemorymanager.writeq(addr : taddr;q : qword);
- begin
- writed(addr,tqwordrec(q).low32);
- writed(addr+4,tqwordrec(q).high32);
- end;
- end.
|