123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- {
- 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 works also with TP
- 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.
- **********************************************************************}
- { a simple 64 bit simulator memory manager, also running with TP }
- {$N+}
- unit mm64;
- interface
- uses
- simbase;
- const
- memoryblocksize = 32768;
- type
- taddr = qword;
- tmemoryblock = array[0..memoryblocksize-1] of byte;
- pmemoryblock = ^tmemoryblock;
- pmemoryarea = ^tmemoryarea;
- tmemoryarea = record
- addr : qword;
- memory : pmemoryblock;
- size : dword;
- next : pmemoryarea;
- end;
- tmemorymanager = object
- mem : pmemoryarea;
- 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));
- stopsim;
- end;
- constructor tmemorymanager.init;
- begin
- mem:=nil;
- end;
- procedure tmemorymanager.allocate(addr : taddr;size : qword);
- var
- ma : pmemoryarea;
- asize : qword;
- begin
- while size>0 do
- begin
- if size>32768 then
- asize:=32768
- else
- asize:=size;
- size:=size-asize;
- new(ma);
- getmem(ma^.memory,trunc(asize));
- fillchar(ma^.memory^,trunc(asize),0);
- ma^.size:=trunc(asize);
- ma^.addr:=addr;
- addr:=addr+asize;
- ma^.next:=mem;
- mem:=ma;
- end;
- end;
- function tmemorymanager.readq(addr : taddr) : qword;
- var
- h : qword;
- ma : pmemoryarea;
- qw : tqwordrec;
- begin
- ma:=mem;
- while assigned(ma) do
- begin
- if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
- begin
- if addr<ma^.addr+ma^.size-7 then
- begin
- move(ma^.memory^[trunc(addr-ma^.addr)],h,8);
- readq:=h;
- exit;
- end
- else
- begin
- qw.low32:=readd(addr);
- qw.high32:=readd(addr+4);
- readq:=comp(qw);
- exit;
- end;
- end;
- ma:=ma^.next;
- end;
- exception('Access violation to $'+qword2str(addr),instructionpc);
- end;
- function tmemorymanager.readalignedq(addr : taddr) : qword;
- var
- h : qword;
- ma : pmemoryarea;
- qw : tqwordrec;
- begin
- if (tqwordrec(addr).low32 and $7)<>0 then
- exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
- ma:=mem;
- while assigned(ma) do
- begin
- if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
- begin
- move(ma^.memory^[trunc(addr-ma^.addr)],h,8);
- readalignedq:=h;
- exit;
- end;
- ma:=ma^.next;
- end;
- exception('Access violation to $'+qword2str(addr),instructionpc);
- end;
- function tmemorymanager.readd(addr : taddr) : dword;
- var
- h : dword;
- ma : pmemoryarea;
- begin
- ma:=mem;
- while assigned(ma) do
- begin
- if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
- begin
- if addr<ma^.addr+ma^.size-3 then
- begin
- move(ma^.memory^[trunc(addr-ma^.addr)],h,4);
- readd:=h;
- exit;
- end
- else
- begin
- readd:=readb(addr)+readb(addr+1) shl 8+readb(addr+2) shl 16+
- readb(addr+3) shl 24;
- exit;
- end;
- end;
- ma:=ma^.next;
- end;
- exception('Access violation to $'+qword2str(addr),instructionpc);
- end;
- function tmemorymanager.readalignedd(addr : taddr) : dword;
- var
- h : dword;
- ma : pmemoryarea;
- begin
- if (tqwordrec(addr).low32 and $3)<>0 then
- exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
- ma:=mem;
- while assigned(ma) do
- begin
- if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
- begin
- move(ma^.memory^[trunc(addr-ma^.addr)],h,4);
- readalignedd:=h;
- exit;
- end;
- ma:=ma^.next;
- end;
- exception('Access violation to $'+qword2str(addr),instructionpc);
- end;
- function tmemorymanager.readb(addr : taddr) : dword;
- var
- ma : pmemoryarea;
- begin
- ma:=mem;
- while assigned(ma) do
- begin
- if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
- begin
- readb:=ma^.memory^[trunc(addr-ma^.addr)];
- exit;
- end;
- ma:=ma^.next;
- end;
- exception('Access violation to $'+qword2str(addr),instructionpc);
- end;
- procedure tmemorymanager.writeb(addr : taddr;b : byte);
- var
- ma : pmemoryarea;
- begin
- ma:=mem;
- while assigned(ma) do
- begin
- if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
- begin
- ma^.memory^[trunc(addr-ma^.addr)]:=b;
- exit;
- end;
- ma:=ma^.next;
- end;
- exception('Access violation to $'+qword2str(addr),instructionpc);
- 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.writealignedd(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);
- var
- ma : pmemoryarea;
- begin
- ma:=mem;
- while assigned(ma) do
- begin
- if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size-7) then
- begin
- move(q,ma^.memory^[trunc(addr-ma^.addr)],8);
- exit;
- end
- else
- { misaligned write! }
- if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
- begin
- writeln('Not implemented 1!');
- halt(1);
- end;
- ma:=ma^.next;
- end;
- exception('Access violation to $'+qword2str(addr),instructionpc);
- end;
- end.
|