fastmm64.pas 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. {
  2. $Id$
  3. This file is part of the Free Pascal simulator environment
  4. Copyright (c) 1999 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
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. {$N+}
  14. unit fastmm64;
  15. interface
  16. uses
  17. simbase;
  18. type
  19. taddr = qword;
  20. tmemorymanager = object
  21. mem : array[0..65535] of pbyte;
  22. constructor init;
  23. { "memory" access routines }
  24. function readalignedq(addr : taddr) : qword;
  25. function readq(addr : taddr) : qword;
  26. function readalignedd(addr : taddr) : dword;
  27. function readd(addr : taddr) : dword;
  28. function readb(addr : taddr) : dword;
  29. procedure writeb(addr : taddr;b : byte);
  30. procedure writealignedd(addr : taddr;d : dword);
  31. procedure writed(addr : taddr;d : dword);
  32. procedure writeq(addr : taddr;q : qword);
  33. procedure allocate(addr : taddr;size : qword);
  34. end;
  35. var
  36. { address of the currently executed instruction, }
  37. { necessary for correct output of exception }
  38. instructionpc : taddr;
  39. implementation
  40. procedure exception(const s : string;addr : taddr);
  41. begin
  42. writeln;
  43. writeln('Exception: ',s,' at $',qword2str(addr));
  44. stopsim;
  45. end;
  46. constructor tmemorymanager.init;
  47. begin
  48. fillchar(mem,sizeof(mem),0);
  49. end;
  50. procedure tmemorymanager.allocate(addr : taddr;size : qword);
  51. procedure allocateblock(addr : taddr);
  52. var
  53. upperbits : longint;
  54. begin
  55. if (tqwordrec(addr).high32 and $fffffff0)<>0 then
  56. begin
  57. writeln('This memory manager supports only 36 bit');
  58. halt(1);
  59. end;
  60. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  61. if not(assigned(mem[upperbits])) then
  62. begin
  63. getmem(mem[upperbits],1024*1024);
  64. fillchar(mem[upperbits]^,1024*1024,0);
  65. end;
  66. end;
  67. var
  68. asize : qword;
  69. begin
  70. while size>0 do
  71. begin
  72. if size>1024*1024 then
  73. asize:=1024*1024;
  74. size:=size-asize;
  75. allocateblock(addr);
  76. addr:=addr+asize;
  77. end;
  78. end;
  79. function tmemorymanager.readq(addr : taddr) : qword;
  80. var
  81. h : qword;
  82. begin
  83. tqwordrec(h).low32:=readd(addr);
  84. tqwordrec(h).high32:=readd(addr+4);
  85. readq:=h;
  86. end;
  87. function tmemorymanager.readd(addr : taddr) : dword;
  88. begin
  89. readd:=readb(addr)+readb(addr+1) shl 8+readb(addr+2) shl 16+
  90. readb(addr+3) shl 24;
  91. end;
  92. function tmemorymanager.readalignedd(addr : taddr) : dword;
  93. var
  94. upperbits : longint;
  95. begin
  96. if (tqwordrec(addr).low32 and $3)<>0 then
  97. exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
  98. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  99. if not(assigned(mem[upperbits])) then
  100. exception('Access violation to $'+qword2str(addr),instructionpc);
  101. readalignedd:=pdword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 2];
  102. end;
  103. function tmemorymanager.readalignedq(addr : taddr) : qword;
  104. var
  105. upperbits : longint;
  106. begin
  107. if (tqwordrec(addr).low32 and $7)<>0 then
  108. exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
  109. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  110. if not(assigned(mem[upperbits])) then
  111. exception('Access violation to $'+qword2str(addr),instructionpc);
  112. readalignedq:=pqword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 3];
  113. end;
  114. function tmemorymanager.readb(addr : taddr) : dword;
  115. var
  116. upperbits : longint;
  117. begin
  118. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  119. if not(assigned(mem[upperbits])) then
  120. exception('Access violation to $'+qword2str(addr),instructionpc);
  121. readb:=mem[upperbits,tqwordrec(addr).low32 and $fffff];
  122. end;
  123. procedure tmemorymanager.writeb(addr : taddr;b : byte);
  124. var
  125. upperbits : longint;
  126. begin
  127. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  128. if not(assigned(mem[upperbits])) then
  129. exception('Access violation to $'+qword2str(addr),instructionpc);
  130. mem[upperbits,tqwordrec(addr).low32 and $fffff]:=b;
  131. end;
  132. procedure tmemorymanager.writealignedd(addr : taddr;d : dword);
  133. var
  134. upperbits : longint;
  135. begin
  136. if (tqwordrec(addr).low32 and $3)<>0 then
  137. exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
  138. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  139. if not(assigned(mem[upperbits])) then
  140. exception('Access violation to $'+qword2str(addr),instructionpc);
  141. pdword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 2]:=d;
  142. end;
  143. procedure tmemorymanager.writed(addr : taddr;d : dword);
  144. begin
  145. writeb(addr,tdword(d)[0]);
  146. writeb(addr+1,tdword(d)[1]);
  147. writeb(addr+2,tdword(d)[2]);
  148. writeb(addr+3,tdword(d)[3]);
  149. end;
  150. procedure tmemorymanager.writeq(addr : taddr;q : qword);
  151. begin
  152. writed(addr,tqwordrec(q).low32);
  153. writed(addr+4,tqwordrec(q).high32);
  154. end;
  155. end.
  156. {
  157. $Log$
  158. Revision 1.1 1999-06-14 11:49:48 florian
  159. + initial revision, it runs simple Alpha Linux ELF executables
  160. - integer operations are nearly completed (non with overflow checking)
  161. - floating point operations aren't implemented (except loading and
  162. storing)
  163. - only the really necessary system calls are implemented by dummys
  164. write syscalls are redirected to the console
  165. }