fastmm64.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. {
  2. $Id$
  3. This file is part of the Free Pascal simulator environment
  4. 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
  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. runerror(255);
  45. stopsim;
  46. end;
  47. constructor tmemorymanager.init;
  48. begin
  49. fillchar(mem,sizeof(mem),0);
  50. end;
  51. procedure tmemorymanager.allocate(addr : taddr;size : qword);
  52. procedure allocateblock(addr : taddr);
  53. var
  54. upperbits : longint;
  55. begin
  56. if (tqwordrec(addr).high32 and $fffffff0)<>0 then
  57. begin
  58. writeln('This memory manager supports only 36 bit');
  59. writeln('Base address was ',qword2str(addr));
  60. halt(1);
  61. end;
  62. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  63. if not(assigned(mem[upperbits])) then
  64. begin
  65. getmem(mem[upperbits],1024*1024);
  66. fillchar(mem[upperbits]^,1024*1024,0);
  67. end;
  68. end;
  69. var
  70. asize : qword;
  71. begin
  72. while size>0 do
  73. begin
  74. if size>1024*1024 then
  75. asize:=1024*1024;
  76. allocateblock(addr);
  77. if asize>size then
  78. break;
  79. size:=size-asize;
  80. addr:=addr+asize;
  81. end;
  82. end;
  83. function tmemorymanager.readq(addr : taddr) : qword;
  84. var
  85. h : qword;
  86. begin
  87. tqwordrec(h).low32:=readd(addr);
  88. tqwordrec(h).high32:=readd(addr+4);
  89. readq:=h;
  90. end;
  91. function tmemorymanager.readd(addr : taddr) : dword;
  92. begin
  93. readd:=readb(addr)+readb(addr+1) shl 8+readb(addr+2) shl 16+
  94. readb(addr+3) shl 24;
  95. end;
  96. function tmemorymanager.readalignedd(addr : taddr) : dword;
  97. var
  98. upperbits : longint;
  99. begin
  100. if (tqwordrec(addr).low32 and $3)<>0 then
  101. exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
  102. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  103. if not(assigned(mem[upperbits])) then
  104. exception('Access violation to $'+qword2str(addr),instructionpc);
  105. readalignedd:=pdword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 2];
  106. end;
  107. function tmemorymanager.readalignedq(addr : taddr) : qword;
  108. var
  109. upperbits : longint;
  110. begin
  111. if (tqwordrec(addr).low32 and $7)<>0 then
  112. exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
  113. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  114. if not(assigned(mem[upperbits])) then
  115. exception('Access violation to $'+qword2str(addr),instructionpc);
  116. readalignedq:=pqword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 3];
  117. end;
  118. function tmemorymanager.readb(addr : taddr) : dword;
  119. var
  120. upperbits : longint;
  121. begin
  122. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  123. if not(assigned(mem[upperbits])) then
  124. exception('Access violation to $'+qword2str(addr),instructionpc);
  125. readb:=mem[upperbits,tqwordrec(addr).low32 and $fffff];
  126. end;
  127. procedure tmemorymanager.writeb(addr : taddr;b : byte);
  128. var
  129. upperbits : longint;
  130. begin
  131. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  132. if not(assigned(mem[upperbits])) then
  133. exception('Access violation to $'+qword2str(addr),instructionpc);
  134. mem[upperbits,tqwordrec(addr).low32 and $fffff]:=b;
  135. end;
  136. procedure tmemorymanager.writealignedd(addr : taddr;d : dword);
  137. var
  138. upperbits : longint;
  139. begin
  140. if (tqwordrec(addr).low32 and $3)<>0 then
  141. exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
  142. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  143. if not(assigned(mem[upperbits])) then
  144. exception('Access violation to $'+qword2str(addr),instructionpc);
  145. pdword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 2]:=d;
  146. end;
  147. procedure tmemorymanager.writed(addr : taddr;d : dword);
  148. begin
  149. writeb(addr,tdword(d)[0]);
  150. writeb(addr+1,tdword(d)[1]);
  151. writeb(addr+2,tdword(d)[2]);
  152. writeb(addr+3,tdword(d)[3]);
  153. end;
  154. procedure tmemorymanager.writeq(addr : taddr;q : qword);
  155. begin
  156. writed(addr,tqwordrec(q).low32);
  157. writed(addr+4,tqwordrec(q).high32);
  158. end;
  159. end.
  160. {
  161. $Log$
  162. Revision 1.2 2002-09-07 15:40:37 peter
  163. * old logs removed and tabs fixed
  164. }