mm64.pas 8.2 KB

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