memory.c 7.0 KB

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