fastmm64.pas 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. {
  2. This file is part of the Free Pascal simulator environment
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. This unit implemements a memory manager for 64 bit processor
  5. simulations, it needs a 32 bit compiler to be compiled
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$N+}
  13. unit fastmm64;
  14. interface
  15. uses
  16. simbase;
  17. type
  18. taddr = qword;
  19. tmemorymanager = object
  20. mem : array[0..65535] of pbyte;
  21. constructor init;
  22. { "memory" access routines }
  23. function readalignedq(addr : taddr) : qword;
  24. function readq(addr : taddr) : qword;
  25. function readalignedd(addr : taddr) : dword;
  26. function readd(addr : taddr) : dword;
  27. function readb(addr : taddr) : dword;
  28. procedure writeb(addr : taddr;b : byte);
  29. procedure writealignedd(addr : taddr;d : dword);
  30. procedure writed(addr : taddr;d : dword);
  31. procedure writeq(addr : taddr;q : qword);
  32. procedure allocate(addr : taddr;size : qword);
  33. end;
  34. var
  35. { address of the currently executed instruction, }
  36. { necessary for correct output of exception }
  37. instructionpc : taddr;
  38. implementation
  39. procedure exception(const s : string;addr : taddr);
  40. begin
  41. writeln;
  42. writeln('Exception: ',s,' at $',qword2str(addr));
  43. runerror(255);
  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. writeln('Base address was ',qword2str(addr));
  59. halt(1);
  60. end;
  61. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  62. if not(assigned(mem[upperbits])) then
  63. begin
  64. getmem(mem[upperbits],1024*1024);
  65. fillchar(mem[upperbits]^,1024*1024,0);
  66. end;
  67. end;
  68. var
  69. asize : qword;
  70. begin
  71. while size>0 do
  72. begin
  73. if size>1024*1024 then
  74. asize:=1024*1024;
  75. allocateblock(addr);
  76. if asize>size then
  77. break;
  78. size:=size-asize;
  79. addr:=addr+asize;
  80. end;
  81. end;
  82. function tmemorymanager.readq(addr : taddr) : qword;
  83. var
  84. h : qword;
  85. begin
  86. tqwordrec(h).low32:=readd(addr);
  87. tqwordrec(h).high32:=readd(addr+4);
  88. readq:=h;
  89. end;
  90. function tmemorymanager.readd(addr : taddr) : dword;
  91. begin
  92. readd:=readb(addr)+readb(addr+1) shl 8+readb(addr+2) shl 16+
  93. readb(addr+3) shl 24;
  94. end;
  95. function tmemorymanager.readalignedd(addr : taddr) : dword;
  96. var
  97. upperbits : longint;
  98. begin
  99. if (tqwordrec(addr).low32 and $3)<>0 then
  100. exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
  101. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  102. if not(assigned(mem[upperbits])) then
  103. exception('Access violation to $'+qword2str(addr),instructionpc);
  104. readalignedd:=pdword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 2];
  105. end;
  106. function tmemorymanager.readalignedq(addr : taddr) : qword;
  107. var
  108. upperbits : longint;
  109. begin
  110. if (tqwordrec(addr).low32 and $7)<>0 then
  111. exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
  112. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  113. if not(assigned(mem[upperbits])) then
  114. exception('Access violation to $'+qword2str(addr),instructionpc);
  115. readalignedq:=pqword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 3];
  116. end;
  117. function tmemorymanager.readb(addr : taddr) : dword;
  118. var
  119. upperbits : longint;
  120. begin
  121. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  122. if not(assigned(mem[upperbits])) then
  123. exception('Access violation to $'+qword2str(addr),instructionpc);
  124. readb:=mem[upperbits,tqwordrec(addr).low32 and $fffff];
  125. end;
  126. procedure tmemorymanager.writeb(addr : taddr;b : byte);
  127. var
  128. upperbits : longint;
  129. begin
  130. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  131. if not(assigned(mem[upperbits])) then
  132. exception('Access violation to $'+qword2str(addr),instructionpc);
  133. mem[upperbits,tqwordrec(addr).low32 and $fffff]:=b;
  134. end;
  135. procedure tmemorymanager.writealignedd(addr : taddr;d : dword);
  136. var
  137. upperbits : longint;
  138. begin
  139. if (tqwordrec(addr).low32 and $3)<>0 then
  140. exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
  141. upperbits:=((tqwordrec(addr).high32 and $f) shl 12) or ((tqwordrec(addr).low32 and $fff) shr 20);
  142. if not(assigned(mem[upperbits])) then
  143. exception('Access violation to $'+qword2str(addr),instructionpc);
  144. pdword(mem[upperbits])[(tqwordrec(addr).low32 and $fffff) shr 2]:=d;
  145. end;
  146. procedure tmemorymanager.writed(addr : taddr;d : dword);
  147. begin
  148. writeb(addr,tdword(d)[0]);
  149. writeb(addr+1,tdword(d)[1]);
  150. writeb(addr+2,tdword(d)[2]);
  151. writeb(addr+3,tdword(d)[3]);
  152. end;
  153. procedure tmemorymanager.writeq(addr : taddr;q : qword);
  154. begin
  155. writed(addr,tqwordrec(q).low32);
  156. writed(addr+4,tqwordrec(q).high32);
  157. end;
  158. end.