mm64.pas 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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 works also with TP
  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. { a simple 64 bit simulator memory manager, also running with TP }
  13. {$N+}
  14. unit mm64;
  15. interface
  16. uses
  17. simbase;
  18. const
  19. memoryblocksize = 32768;
  20. type
  21. taddr = qword;
  22. tmemoryblock = array[0..memoryblocksize-1] of byte;
  23. pmemoryblock = ^tmemoryblock;
  24. pmemoryarea = ^tmemoryarea;
  25. tmemoryarea = record
  26. addr : qword;
  27. memory : pmemoryblock;
  28. size : dword;
  29. next : pmemoryarea;
  30. end;
  31. tmemorymanager = object
  32. mem : pmemoryarea;
  33. constructor init;
  34. { "memory" access routines }
  35. function readalignedq(addr : taddr) : qword;
  36. function readq(addr : taddr) : qword;
  37. function readalignedd(addr : taddr) : dword;
  38. function readd(addr : taddr) : dword;
  39. function readb(addr : taddr) : dword;
  40. procedure writeb(addr : taddr;b : byte);
  41. procedure writealignedd(addr : taddr;d : dword);
  42. procedure writed(addr : taddr;d : dword);
  43. procedure writeq(addr : taddr;q : qword);
  44. procedure allocate(addr : taddr;size : qword);
  45. end;
  46. var
  47. { address of the currently executed instruction, }
  48. { necessary for correct output of exception }
  49. instructionpc : taddr;
  50. implementation
  51. procedure exception(const s : string;addr : taddr);
  52. begin
  53. writeln;
  54. writeln('Exception: ',s,' at $',qword2str(addr));
  55. stopsim;
  56. end;
  57. constructor tmemorymanager.init;
  58. begin
  59. mem:=nil;
  60. end;
  61. procedure tmemorymanager.allocate(addr : taddr;size : qword);
  62. var
  63. ma : pmemoryarea;
  64. asize : qword;
  65. begin
  66. while size>0 do
  67. begin
  68. if size>32768 then
  69. asize:=32768
  70. else
  71. asize:=size;
  72. size:=size-asize;
  73. new(ma);
  74. getmem(ma^.memory,trunc(asize));
  75. fillchar(ma^.memory^,trunc(asize),0);
  76. ma^.size:=trunc(asize);
  77. ma^.addr:=addr;
  78. addr:=addr+asize;
  79. ma^.next:=mem;
  80. mem:=ma;
  81. end;
  82. end;
  83. function tmemorymanager.readq(addr : taddr) : qword;
  84. var
  85. h : qword;
  86. ma : pmemoryarea;
  87. qw : tqwordrec;
  88. begin
  89. ma:=mem;
  90. while assigned(ma) do
  91. begin
  92. if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
  93. begin
  94. if addr<ma^.addr+ma^.size-7 then
  95. begin
  96. move(ma^.memory^[trunc(addr-ma^.addr)],h,8);
  97. readq:=h;
  98. exit;
  99. end
  100. else
  101. begin
  102. qw.low32:=readd(addr);
  103. qw.high32:=readd(addr+4);
  104. readq:=comp(qw);
  105. exit;
  106. end;
  107. end;
  108. ma:=ma^.next;
  109. end;
  110. exception('Access violation to $'+qword2str(addr),instructionpc);
  111. end;
  112. function tmemorymanager.readalignedq(addr : taddr) : qword;
  113. var
  114. h : qword;
  115. ma : pmemoryarea;
  116. qw : tqwordrec;
  117. begin
  118. if (tqwordrec(addr).low32 and $7)<>0 then
  119. exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
  120. ma:=mem;
  121. while assigned(ma) do
  122. begin
  123. if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
  124. begin
  125. move(ma^.memory^[trunc(addr-ma^.addr)],h,8);
  126. readalignedq:=h;
  127. exit;
  128. end;
  129. ma:=ma^.next;
  130. end;
  131. exception('Access violation to $'+qword2str(addr),instructionpc);
  132. end;
  133. function tmemorymanager.readd(addr : taddr) : dword;
  134. var
  135. h : dword;
  136. ma : pmemoryarea;
  137. begin
  138. ma:=mem;
  139. while assigned(ma) do
  140. begin
  141. if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
  142. begin
  143. if addr<ma^.addr+ma^.size-3 then
  144. begin
  145. move(ma^.memory^[trunc(addr-ma^.addr)],h,4);
  146. readd:=h;
  147. exit;
  148. end
  149. else
  150. begin
  151. readd:=readb(addr)+readb(addr+1) shl 8+readb(addr+2) shl 16+
  152. readb(addr+3) shl 24;
  153. exit;
  154. end;
  155. end;
  156. ma:=ma^.next;
  157. end;
  158. exception('Access violation to $'+qword2str(addr),instructionpc);
  159. end;
  160. function tmemorymanager.readalignedd(addr : taddr) : dword;
  161. var
  162. h : dword;
  163. ma : pmemoryarea;
  164. begin
  165. if (tqwordrec(addr).low32 and $3)<>0 then
  166. exception('Alignment violation (dword) to $'+qword2str(addr),instructionpc);
  167. ma:=mem;
  168. while assigned(ma) do
  169. begin
  170. if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
  171. begin
  172. move(ma^.memory^[trunc(addr-ma^.addr)],h,4);
  173. readalignedd:=h;
  174. exit;
  175. end;
  176. ma:=ma^.next;
  177. end;
  178. exception('Access violation to $'+qword2str(addr),instructionpc);
  179. end;
  180. function tmemorymanager.readb(addr : taddr) : dword;
  181. var
  182. ma : pmemoryarea;
  183. begin
  184. ma:=mem;
  185. while assigned(ma) do
  186. begin
  187. if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
  188. begin
  189. readb:=ma^.memory^[trunc(addr-ma^.addr)];
  190. exit;
  191. end;
  192. ma:=ma^.next;
  193. end;
  194. exception('Access violation to $'+qword2str(addr),instructionpc);
  195. end;
  196. procedure tmemorymanager.writeb(addr : taddr;b : byte);
  197. var
  198. ma : pmemoryarea;
  199. begin
  200. ma:=mem;
  201. while assigned(ma) do
  202. begin
  203. if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
  204. begin
  205. ma^.memory^[trunc(addr-ma^.addr)]:=b;
  206. exit;
  207. end;
  208. ma:=ma^.next;
  209. end;
  210. exception('Access violation to $'+qword2str(addr),instructionpc);
  211. end;
  212. procedure tmemorymanager.writed(addr : taddr;d : dword);
  213. begin
  214. writeb(addr,tdword(d)[0]);
  215. writeb(addr+1,tdword(d)[1]);
  216. writeb(addr+2,tdword(d)[2]);
  217. writeb(addr+3,tdword(d)[3]);
  218. end;
  219. procedure tmemorymanager.writealignedd(addr : taddr;d : dword);
  220. begin
  221. writeb(addr,tdword(d)[0]);
  222. writeb(addr+1,tdword(d)[1]);
  223. writeb(addr+2,tdword(d)[2]);
  224. writeb(addr+3,tdword(d)[3]);
  225. end;
  226. procedure tmemorymanager.writeq(addr : taddr;q : qword);
  227. var
  228. ma : pmemoryarea;
  229. begin
  230. ma:=mem;
  231. while assigned(ma) do
  232. begin
  233. if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size-7) then
  234. begin
  235. move(q,ma^.memory^[trunc(addr-ma^.addr)],8);
  236. exit;
  237. end
  238. else
  239. { misaligned write! }
  240. if (addr>=ma^.addr) and (addr<ma^.addr+ma^.size) then
  241. begin
  242. writeln('Not implemented 1!');
  243. halt(1);
  244. end;
  245. ma:=ma^.next;
  246. end;
  247. exception('Access violation to $'+qword2str(addr),instructionpc);
  248. end;
  249. end.