memory.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * 6502 Memory manager - The peTI-NESulator Project
  3. * memory.c - Taken from the Quick6502 project
  4. *
  5. * Created by Manoel Trapier on 18/09/06.
  6. * Copyright (c) 2003-2018 986-Studio. All rights reserved.
  7. *
  8. * $LastChangedDate$
  9. * $Author$
  10. * $HeadURL$
  11. * $Revision$
  12. *
  13. */
  14. #include <stdio.h>
  15. #include <types.h>
  16. #include <os_dependent.h>
  17. #include <memory/manager.h>
  18. /* Private structures */
  19. #define KBYTE * (1024)
  20. /*
  21. * What inside memory manager:
  22. *
  23. * Table of attributes
  24. * Table of original page ptr
  25. * Table of moded page ptr
  26. *
  27. */
  28. /* Private data */
  29. byte *memory_pages[0x100];
  30. byte memory_pages_attr[0x100];
  31. func_rdhook rdh_table[0x100];
  32. func_wrhook wrh_table[0x100];
  33. //#define DEBUG
  34. #undef DEBUG
  35. #ifdef DEBUG
  36. #define LOG(s) s
  37. #else
  38. #define LOG(s) {}
  39. #endif
  40. /* Public functions */
  41. void set_page_ptr(byte page, byte *ptr)
  42. {
  43. LOG(console_printf(Console_Default, "Set page 0x%X to ptr %p\n", page, ptr));
  44. memory_pages[page] = ptr;
  45. }
  46. void set_page_ptr_1k(byte page, byte *ptr)
  47. { /* 1k = 4 * 256 */
  48. LOG(console_printf(Console_Default, "Set page(1k) 0x%X to ptr %p\n", page, ptr));
  49. memory_pages[page + 0] = ptr;
  50. memory_pages[page + 1] = ptr + 0x100;
  51. memory_pages[page + 2] = ptr + (0x100 * 2);
  52. memory_pages[page + 3] = ptr + (0x100 * 3);
  53. }
  54. void set_page_ptr_2k(byte page, byte *ptr)
  55. {
  56. LOG(console_printf(Console_Default, "Set page(2k) 0x%X to ptr %p\n", page, ptr));
  57. memory_pages[page + 0] = ptr;
  58. memory_pages[page + 1] = ptr + 0x100;
  59. memory_pages[page + 2] = ptr + (0x100 * 2);
  60. memory_pages[page + 3] = ptr + (0x100 * 3);
  61. memory_pages[page + 4] = ptr + (0x100 * 4);
  62. memory_pages[page + 5] = ptr + (0x100 * 5);
  63. memory_pages[page + 6] = ptr + (0x100 * 6);
  64. memory_pages[page + 7] = ptr + (0x100 * 7);
  65. }
  66. void set_page_ptr_4k(byte page, byte *ptr)
  67. {
  68. LOG(console_printf(Console_Default, "Set page(4k) 0x%X to ptr %p\n", page, ptr));
  69. set_page_ptr_2k(page, ptr);
  70. set_page_ptr_2k(page+((4 KBYTE / 256) / 2), ptr + 2 KBYTE);
  71. }
  72. void set_page_ptr_8k(byte page, byte *ptr)
  73. {
  74. LOG(console_printf(Console_Default, "Set page(8k) 0x%X to ptr %p\n", page, ptr));
  75. set_page_ptr_4k(page, ptr);
  76. set_page_ptr_4k(page+((8 KBYTE / 256) / 2), ptr + 4 KBYTE);
  77. }
  78. void set_page_ptr_16k(byte page, byte *ptr)
  79. {
  80. set_page_ptr_8k(page, ptr);
  81. set_page_ptr_8k(page+((16 KBYTE / 256) / 2), ptr + 8 KBYTE);
  82. }
  83. void set_page_ptr_32k(byte page, byte *ptr)
  84. {
  85. set_page_ptr_16k(page, ptr);
  86. set_page_ptr_16k(page+((32 KBYTE / 256) / 2), ptr + 16 KBYTE);
  87. }
  88. byte *get_page_ptr(byte page)
  89. {
  90. return memory_pages[page];
  91. }
  92. /* Functions to set pages attributes */
  93. void set_page_rd_hook(byte page, func_rdhook func)
  94. {
  95. if (func == NULL)
  96. {
  97. memory_pages_attr[page] &= (~ATTR_PAGE_HAVE_RDHOOK);
  98. if (memory_pages[page] == (byte *)0x01)
  99. memory_pages[page] = NULL;
  100. }
  101. else
  102. {
  103. memory_pages_attr[page] |= ATTR_PAGE_HAVE_RDHOOK;
  104. if (memory_pages[page] == NULL)
  105. memory_pages[page] = (byte *)0x01;
  106. }
  107. rdh_table[page] = func;
  108. }
  109. void set_page_wr_hook(byte page, func_wrhook func)
  110. {
  111. if (func == NULL)
  112. {
  113. memory_pages_attr[page] &= (~ATTR_PAGE_HAVE_WRHOOK);
  114. if (memory_pages[page] == (byte*)0x01)
  115. memory_pages[page] = NULL;
  116. }
  117. else
  118. {
  119. memory_pages_attr[page] |= ATTR_PAGE_HAVE_WRHOOK;
  120. if (memory_pages[page] == NULL)
  121. memory_pages[page] = (byte *)0x01;
  122. }
  123. wrh_table[page] = func;
  124. }
  125. void set_page_readable(byte page, bool value)
  126. {
  127. if (value == true)
  128. memory_pages_attr[page] |= ATTR_PAGE_READABLE;
  129. else
  130. memory_pages_attr[page] &= (~ATTR_PAGE_READABLE);
  131. }
  132. void set_page_writeable(byte page, bool value)
  133. {
  134. if (value == true)
  135. memory_pages_attr[page] |= ATTR_PAGE_WRITEABLE;
  136. else
  137. memory_pages_attr[page] &= (~ATTR_PAGE_WRITEABLE);
  138. }
  139. void set_page_ghost(byte page, bool value, byte ghost)
  140. {
  141. if (value == true)
  142. {
  143. memory_pages_attr[page] = memory_pages_attr[ghost];
  144. rdh_table[page] = rdh_table[ghost];
  145. wrh_table[page] = wrh_table[ghost];
  146. memory_pages[page] = memory_pages[ghost];
  147. }
  148. }
  149. byte get_page_attributes(byte page)
  150. {
  151. return memory_pages_attr[page];
  152. }
  153. func_rdhook get_page_rdhook(byte page)
  154. {
  155. if (memory_pages_attr[page] & ATTR_PAGE_HAVE_RDHOOK)
  156. return rdh_table[page];
  157. return NULL;
  158. }
  159. func_wrhook get_page_wrhook(byte page)
  160. {
  161. if (memory_pages_attr[page] & ATTR_PAGE_HAVE_WRHOOK)
  162. return wrh_table[page];
  163. return NULL;
  164. }
  165. byte ReadMemory(byte page, byte addr)
  166. {
  167. static byte LastRetByte = 0xA5;
  168. byte *page_ptr;
  169. byte attributes;
  170. LOG(console_printf(Console_Default, "Read @ 0x%X-%X\n", page, addr));
  171. /* Est-ce que la page est mappé ? && Est-ce que la page est "readable" ? */
  172. if ((page_ptr = memory_pages[page]) &&
  173. ( (attributes = memory_pages_attr[page]) & ATTR_PAGE_READABLE) )
  174. {
  175. LOG(console_printf(Console_Default, "Page is non null & readable\n"));
  176. if ( attributes & ATTR_PAGE_HAVE_RDHOOK )
  177. return ( LastRetByte = rdh_table[page](addr) );
  178. else
  179. return ( LastRetByte = page_ptr[addr] );
  180. }
  181. //console_printf(Console_Default, "Trying to read @ 0x%X-%X\n", page, addr);
  182. return LastRetByte;
  183. }
  184. void WriteMemory(byte page, byte addr, byte value)
  185. {
  186. byte *page_ptr;
  187. byte attributes;
  188. LOG(console_printf(Console_Default, "Write 0x%x @ 0x%X-%X\n", value, page, addr));
  189. /* Est-ce que la page est mappé ? && Est-ce que la page est "writable" ? */
  190. if ( (page_ptr = memory_pages[page]) &&
  191. ( (attributes = memory_pages_attr[page]) & ATTR_PAGE_WRITEABLE) )
  192. {
  193. if ( attributes & ATTR_PAGE_HAVE_WRHOOK )
  194. {
  195. #ifdef DETECT_BUS_CONFLICT
  196. if ((page >= 0x80) && (memory_pages[page][addr] != value))
  197. console_printf(Console_Default, "WriteHook: bus conflict at %02X%02X rom:%02X write:%02X\n", page, addr, memory_pages[page][addr], value);
  198. #endif
  199. wrh_table[page](addr, value);
  200. }
  201. else
  202. page_ptr[addr] = value;
  203. }
  204. else { console_printf(Console_Default, "Trying to write 0x%X @ 0x%X-%X\n", value, page, addr); }
  205. }
  206. void DumpMemoryState(FILE *fp)
  207. {
  208. int i;
  209. for (i = 0x00; i < 0x100; i++)
  210. {
  211. fprintf(fp,
  212. "Page 0x%02X : [%c%c%c%c%c%c] RdH:%p WrH:%p ptr:%p\n",
  213. i,
  214. (memory_pages_attr[i]&ATTR_PAGE_HAVE_RDHOOK)?'r':'.',
  215. (memory_pages_attr[i]&ATTR_PAGE_HAVE_WRHOOK)?'w':'.',
  216. (memory_pages_attr[i]&ATTR_PAGE_READABLE)?'R':'.',
  217. (memory_pages_attr[i]&ATTR_PAGE_WRITEABLE)?'W':'.',
  218. (memory_pages_attr[i]&ATTR_PAGE_GHOST)?'G':'.',
  219. (memory_pages_attr[i]&ATTR_PAGE_MAPPED)?'M':'.',
  220. rdh_table[i],
  221. wrh_table[i],
  222. memory_pages[i]
  223. );
  224. }
  225. }
  226. void InitMemory()
  227. {
  228. int page;
  229. for(page = 0 ; page < 0x100 ; page++)
  230. {
  231. set_page_ptr(page,NULL);
  232. memory_pages_attr[page] = 0x00;
  233. }
  234. }