memory.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  1. /*
  2. * Memory I/O handlers for Sega/Mega CD.
  3. * (C) notaz, 2007-2009
  4. *
  5. * This work is licensed under the terms of MAME license.
  6. * See COPYING file in the top-level directory.
  7. */
  8. #include "../pico_int.h"
  9. #include "../memory.h"
  10. uptr s68k_read8_map [0x1000000 >> M68K_MEM_SHIFT];
  11. uptr s68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];
  12. uptr s68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
  13. uptr s68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
  14. #ifndef _ASM_CD_MEMORY_C
  15. MAKE_68K_READ8(s68k_read8, s68k_read8_map)
  16. MAKE_68K_READ16(s68k_read16, s68k_read16_map)
  17. MAKE_68K_READ32(s68k_read32, s68k_read16_map)
  18. MAKE_68K_WRITE8(s68k_write8, s68k_write8_map)
  19. MAKE_68K_WRITE16(s68k_write16, s68k_write16_map)
  20. MAKE_68K_WRITE32(s68k_write32, s68k_write16_map)
  21. #endif
  22. // -----------------------------------------------------------------
  23. // provided by ASM code:
  24. #ifdef _ASM_CD_MEMORY_C
  25. u32 PicoReadS68k8_pr(u32 a);
  26. u32 PicoReadS68k16_pr(u32 a);
  27. void PicoWriteS68k8_pr(u32 a, u32 d);
  28. void PicoWriteS68k16_pr(u32 a, u32 d);
  29. u32 PicoReadM68k8_cell0(u32 a);
  30. u32 PicoReadM68k8_cell1(u32 a);
  31. u32 PicoReadM68k16_cell0(u32 a);
  32. u32 PicoReadM68k16_cell1(u32 a);
  33. void PicoWriteM68k8_cell0(u32 a, u32 d);
  34. void PicoWriteM68k8_cell1(u32 a, u32 d);
  35. void PicoWriteM68k16_cell0(u32 a, u32 d);
  36. void PicoWriteM68k16_cell1(u32 a, u32 d);
  37. u32 PicoReadS68k8_dec0(u32 a);
  38. u32 PicoReadS68k8_dec1(u32 a);
  39. u32 PicoReadS68k16_dec0(u32 a);
  40. u32 PicoReadS68k16_dec1(u32 a);
  41. void PicoWriteS68k8_dec_m0b0(u32 a, u32 d);
  42. void PicoWriteS68k8_dec_m1b0(u32 a, u32 d);
  43. void PicoWriteS68k8_dec_m2b0(u32 a, u32 d);
  44. void PicoWriteS68k8_dec_m0b1(u32 a, u32 d);
  45. void PicoWriteS68k8_dec_m1b1(u32 a, u32 d);
  46. void PicoWriteS68k8_dec_m2b1(u32 a, u32 d);
  47. void PicoWriteS68k16_dec_m0b0(u32 a, u32 d);
  48. void PicoWriteS68k16_dec_m1b0(u32 a, u32 d);
  49. void PicoWriteS68k16_dec_m2b0(u32 a, u32 d);
  50. void PicoWriteS68k16_dec_m0b1(u32 a, u32 d);
  51. void PicoWriteS68k16_dec_m1b1(u32 a, u32 d);
  52. void PicoWriteS68k16_dec_m2b1(u32 a, u32 d);
  53. #endif
  54. static void remap_prg_window(u32 r1, u32 r3);
  55. static void remap_word_ram(u32 r3);
  56. // poller detection
  57. #define POLL_LIMIT 16
  58. #define POLL_CYCLES 64
  59. void m68k_comm_check(u32 a)
  60. {
  61. pcd_sync_s68k(SekCyclesDone(), 0);
  62. if (a >= 0x0e && !Pico_mcd->m.need_sync) {
  63. // there are cases when slave updates comm and only switches RAM
  64. // over after that (mcd1b), so there must be a resync..
  65. SekEndRun(64);
  66. Pico_mcd->m.need_sync = 1;
  67. }
  68. if (SekNotPolling || a != Pico_mcd->m.m68k_poll_a) {
  69. Pico_mcd->m.m68k_poll_a = a;
  70. Pico_mcd->m.m68k_poll_cnt = 0;
  71. SekNotPolling = 0;
  72. return;
  73. }
  74. Pico_mcd->m.m68k_poll_cnt++;
  75. }
  76. #ifndef _ASM_CD_MEMORY_C
  77. static u32 m68k_reg_read16(u32 a)
  78. {
  79. u32 d = 0;
  80. a &= 0x3e;
  81. switch (a) {
  82. case 0:
  83. // here IFL2 is always 0, just like in Gens
  84. d = ((Pico_mcd->s68k_regs[0x33] << 13) & 0x8000)
  85. | Pico_mcd->m.busreq;
  86. goto end;
  87. case 2:
  88. m68k_comm_check(a);
  89. d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7);
  90. elprintf(EL_CDREG3, "m68k_regs r3: %02x @%06x", (u8)d, SekPc);
  91. goto end;
  92. case 4:
  93. d = Pico_mcd->s68k_regs[4]<<8;
  94. goto end;
  95. case 6:
  96. d = *(u16 *)(Pico_mcd->bios + 0x72);
  97. goto end;
  98. case 8:
  99. d = cdc_host_r();
  100. goto end;
  101. case 0xA:
  102. elprintf(EL_UIO, "m68k FIXME: reserved read");
  103. goto end;
  104. case 0xC: // 384 cycle stopwatch timer
  105. // ugh..
  106. d = pcd_cycles_m68k_to_s68k(SekCyclesDone());
  107. d = (d - Pico_mcd->m.stopwatch_base_c) / 384;
  108. d &= 0x0fff;
  109. elprintf(EL_CDREGS, "m68k stopwatch timer read (%04x)", d);
  110. goto end;
  111. }
  112. if (a < 0x30) {
  113. // comm flag/cmd/status (0xE-0x2F)
  114. m68k_comm_check(a);
  115. d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];
  116. goto end;
  117. }
  118. elprintf(EL_UIO, "m68k_regs FIXME invalid read @ %02x", a);
  119. end:
  120. return d;
  121. }
  122. #endif
  123. #ifndef _ASM_CD_MEMORY_C
  124. static
  125. #endif
  126. void m68k_reg_write8(u32 a, u32 d)
  127. {
  128. u32 dold;
  129. a &= 0x3f;
  130. switch (a) {
  131. case 0:
  132. d &= 1;
  133. if (d && (Pico_mcd->s68k_regs[0x33] & PCDS_IEN2)) {
  134. elprintf(EL_INTS, "m68k: s68k irq 2");
  135. pcd_sync_s68k(SekCyclesDone(), 0);
  136. SekInterruptS68k(2);
  137. }
  138. return;
  139. case 1:
  140. d &= 3;
  141. dold = Pico_mcd->m.busreq;
  142. if (!(d & 1))
  143. d |= 2; // verified: can't release bus on reset
  144. if (dold == d)
  145. return;
  146. pcd_sync_s68k(SekCyclesDone(), 0);
  147. if ((dold ^ d) & 1)
  148. elprintf(EL_INTSW, "m68k: s68k reset %i", !(d&1));
  149. if (!(d & 1))
  150. Pico_mcd->m.state_flags |= PCD_ST_S68K_RST;
  151. else if (d == 1 && (Pico_mcd->m.state_flags & PCD_ST_S68K_RST)) {
  152. Pico_mcd->m.state_flags &= ~PCD_ST_S68K_RST;
  153. elprintf(EL_CDREGS, "m68k: resetting s68k");
  154. SekResetS68k();
  155. }
  156. if ((dold ^ d) & 2) {
  157. elprintf(EL_INTSW, "m68k: s68k brq %i", d >> 1);
  158. remap_prg_window(d, Pico_mcd->s68k_regs[3]);
  159. }
  160. Pico_mcd->m.busreq = d;
  161. return;
  162. case 2:
  163. elprintf(EL_CDREGS, "m68k: prg wp=%02x", d);
  164. Pico_mcd->s68k_regs[2] = d; // really use s68k side register
  165. return;
  166. case 3:
  167. dold = Pico_mcd->s68k_regs[3];
  168. elprintf(EL_CDREG3, "m68k_regs w3: %02x @%06x", (u8)d, SekPc);
  169. if ((d ^ dold) & 0xc0) {
  170. elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i",
  171. (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));
  172. remap_prg_window(Pico_mcd->m.busreq, d);
  173. }
  174. // 2M mode state is tracked regardless of current mode
  175. if (d & 2) {
  176. Pico_mcd->m.dmna_ret_2m |= 2;
  177. Pico_mcd->m.dmna_ret_2m &= ~1;
  178. }
  179. if (dold & 4) { // 1M mode
  180. d ^= 2; // 0 sets DMNA, 1 does nothing
  181. d = (d & 0xc2) | (dold & 0x1f);
  182. }
  183. else
  184. d = (d & 0xc0) | (dold & 0x1c) | Pico_mcd->m.dmna_ret_2m;
  185. goto write_comm;
  186. case 6:
  187. Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer
  188. return;
  189. case 7:
  190. Pico_mcd->bios[0x72] = d;
  191. elprintf(EL_CDREGS, "hint vector set to %04x%04x",
  192. ((u16 *)Pico_mcd->bios)[0x70/2], ((u16 *)Pico_mcd->bios)[0x72/2]);
  193. return;
  194. case 0x0f:
  195. a = 0x0e;
  196. case 0x0e:
  197. goto write_comm;
  198. }
  199. if ((a&0xf0) == 0x10)
  200. goto write_comm;
  201. elprintf(EL_UIO, "m68k FIXME: invalid write? [%02x] %02x", a, d);
  202. return;
  203. write_comm:
  204. if (d == Pico_mcd->s68k_regs[a])
  205. return;
  206. pcd_sync_s68k(SekCyclesDone(), 0);
  207. Pico_mcd->s68k_regs[a] = d;
  208. if (a == 0x03) {
  209. // There are cases when master checks for successful switching of RAM to
  210. // slave. This can produce race conditions where slave switches RAM back to
  211. // master while master is delayed by interrupt before the check executes.
  212. // Delay slave a bit to make sure master can check before slave changes.
  213. SekCycleCntS68k += 24;
  214. }
  215. if (Pico_mcd->m.s68k_poll_a == (a & ~1))
  216. {
  217. if (Pico_mcd->m.s68k_poll_cnt > POLL_LIMIT) {
  218. elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);
  219. SekSetStopS68k(0);
  220. }
  221. Pico_mcd->m.s68k_poll_a = 0;
  222. }
  223. }
  224. u32 s68k_poll_detect(u32 a, u32 d)
  225. {
  226. #ifdef USE_POLL_DETECT
  227. u32 cycles, cnt = 0;
  228. if (SekIsStoppedS68k())
  229. return d;
  230. cycles = SekCyclesDoneS68k();
  231. if (!SekNotPollingS68k && a == Pico_mcd->m.s68k_poll_a) {
  232. u32 clkdiff = cycles - Pico_mcd->m.s68k_poll_clk;
  233. if (clkdiff <= POLL_CYCLES) {
  234. cnt = Pico_mcd->m.s68k_poll_cnt + 1;
  235. //printf("-- diff: %u, cnt = %i\n", clkdiff, cnt);
  236. if (Pico_mcd->m.s68k_poll_cnt > POLL_LIMIT) {
  237. SekSetStopS68k(1);
  238. elprintf(EL_CDPOLL, "s68k poll detected @%06x, a=%02x",
  239. SekPcS68k, a);
  240. }
  241. }
  242. }
  243. Pico_mcd->m.s68k_poll_a = a;
  244. Pico_mcd->m.s68k_poll_clk = cycles;
  245. Pico_mcd->m.s68k_poll_cnt = cnt;
  246. SekNotPollingS68k = 0;
  247. #endif
  248. return d;
  249. }
  250. #define READ_FONT_DATA(basemask) \
  251. { \
  252. unsigned int fnt = *(unsigned int *)(Pico_mcd->s68k_regs + 0x4c); \
  253. unsigned int col0 = (fnt >> 8) & 0x0f, col1 = (fnt >> 12) & 0x0f; \
  254. if (fnt & (basemask << 0)) d = col1 ; else d = col0; \
  255. if (fnt & (basemask << 1)) d |= col1 << 4; else d |= col0 << 4; \
  256. if (fnt & (basemask << 2)) d |= col1 << 8; else d |= col0 << 8; \
  257. if (fnt & (basemask << 3)) d |= col1 << 12; else d |= col0 << 12; \
  258. }
  259. #ifndef _ASM_CD_MEMORY_C
  260. static
  261. #endif
  262. u32 s68k_reg_read16(u32 a)
  263. {
  264. u32 d=0;
  265. switch (a) {
  266. case 0:
  267. return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state
  268. case 2:
  269. d = (Pico_mcd->s68k_regs[2]<<8) | (Pico_mcd->s68k_regs[3]&0x1f);
  270. elprintf(EL_CDREG3, "s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k);
  271. return s68k_poll_detect(a, d);
  272. case 6:
  273. return cdc_reg_r();
  274. case 8:
  275. return cdc_host_r();
  276. case 0xC:
  277. d = SekCyclesDoneS68k() - Pico_mcd->m.stopwatch_base_c;
  278. d /= 384;
  279. d &= 0x0fff;
  280. elprintf(EL_CDREGS, "s68k stopwatch timer read (%04x)", d);
  281. return d;
  282. case 0x30:
  283. elprintf(EL_CDREGS, "s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[31]);
  284. return Pico_mcd->s68k_regs[31];
  285. case 0x34: // fader
  286. return 0; // no busy bit
  287. case 0x50: // font data (check: Lunar 2, Silpheed)
  288. READ_FONT_DATA(0x00100000);
  289. return d;
  290. case 0x52:
  291. READ_FONT_DATA(0x00010000);
  292. return d;
  293. case 0x54:
  294. READ_FONT_DATA(0x10000000);
  295. return d;
  296. case 0x56:
  297. READ_FONT_DATA(0x01000000);
  298. return d;
  299. }
  300. d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];
  301. if (a >= 0x0e && a < 0x30)
  302. return s68k_poll_detect(a, d);
  303. return d;
  304. }
  305. #ifndef _ASM_CD_MEMORY_C
  306. static
  307. #endif
  308. void s68k_reg_write8(u32 a, u32 d)
  309. {
  310. // Warning: d might have upper bits set
  311. switch (a) {
  312. case 1:
  313. if (!(d & 1))
  314. pcd_soft_reset();
  315. return;
  316. case 2:
  317. return; // only m68k can change WP
  318. case 3: {
  319. int dold = Pico_mcd->s68k_regs[3];
  320. elprintf(EL_CDREG3, "s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k);
  321. d &= 0x1d;
  322. d |= dold & 0xc2;
  323. // 2M mode state
  324. if (d & 1) {
  325. Pico_mcd->m.dmna_ret_2m |= 1;
  326. Pico_mcd->m.dmna_ret_2m &= ~2; // DMNA clears
  327. }
  328. if (d & 4)
  329. {
  330. if (!(dold & 4)) {
  331. elprintf(EL_CDREG3, "wram mode 2M->1M");
  332. wram_2M_to_1M(Pico_mcd->word_ram2M);
  333. }
  334. if ((d ^ dold) & 0x1d)
  335. remap_word_ram(d);
  336. if ((d ^ dold) & 0x05)
  337. d &= ~2; // clear DMNA - swap complete
  338. }
  339. else
  340. {
  341. if (dold & 4) {
  342. elprintf(EL_CDREG3, "wram mode 1M->2M");
  343. wram_1M_to_2M(Pico_mcd->word_ram2M);
  344. remap_word_ram(d);
  345. }
  346. d = (d & ~3) | Pico_mcd->m.dmna_ret_2m;
  347. }
  348. goto write_comm;
  349. }
  350. case 4:
  351. elprintf(EL_CDREGS, "s68k CDC dest: %x", d&7);
  352. Pico_mcd->s68k_regs[4] = (Pico_mcd->s68k_regs[4]&0xC0) | (d&7); // CDC mode
  353. return;
  354. case 5:
  355. //dprintf("s68k CDC reg addr: %x", d&0xf);
  356. break;
  357. case 7:
  358. cdc_reg_w(d & 0xff);
  359. return;
  360. case 0xa:
  361. elprintf(EL_CDREGS, "s68k set CDC dma addr");
  362. break;
  363. case 0xc:
  364. case 0xd: // 384 cycle stopwatch timer
  365. elprintf(EL_CDREGS|EL_CD, "s68k clear stopwatch (%x)", d);
  366. // does this also reset internal 384 cycle counter?
  367. Pico_mcd->m.stopwatch_base_c = SekCyclesDoneS68k();
  368. return;
  369. case 0x0e:
  370. a = 0x0f;
  371. case 0x0f:
  372. goto write_comm;
  373. case 0x31: // 384 cycle int3 timer
  374. d &= 0xff;
  375. elprintf(EL_CDREGS|EL_CD, "s68k set int3 timer: %02x", d);
  376. Pico_mcd->s68k_regs[a] = (u8) d;
  377. if (d) // d or d+1??
  378. pcd_event_schedule_s68k(PCD_EVENT_TIMER3, d * 384);
  379. else
  380. pcd_event_schedule(0, PCD_EVENT_TIMER3, 0);
  381. break;
  382. case 0x33: // IRQ mask
  383. elprintf(EL_CDREGS|EL_CD, "s68k irq mask: %02x", d);
  384. d &= 0x7e;
  385. if ((d ^ Pico_mcd->s68k_regs[0x33]) & d & PCDS_IEN4) {
  386. // XXX: emulate pending irq instead?
  387. if (Pico_mcd->s68k_regs[0x37] & 4) {
  388. elprintf(EL_INTS, "cdd export irq 4 (unmask)");
  389. SekInterruptS68k(4);
  390. }
  391. }
  392. break;
  393. case 0x34: // fader
  394. Pico_mcd->s68k_regs[a] = (u8) d & 0x7f;
  395. return;
  396. case 0x36:
  397. return; // d/m bit is unsetable
  398. case 0x37: {
  399. u32 d_old = Pico_mcd->s68k_regs[0x37];
  400. Pico_mcd->s68k_regs[0x37] = d & 7;
  401. if ((d&4) && !(d_old&4)) {
  402. // ??
  403. pcd_event_schedule_s68k(PCD_EVENT_CDC, 12500000/75);
  404. if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) {
  405. elprintf(EL_INTS, "cdd export irq 4");
  406. SekInterruptS68k(4);
  407. }
  408. }
  409. return;
  410. }
  411. case 0x4b:
  412. Pico_mcd->s68k_regs[a] = 0; // (u8) d; ?
  413. cdd_process();
  414. {
  415. static const char *nm[] =
  416. { "stat", "stop", "read_toc", "play",
  417. "seek", "???", "pause", "resume",
  418. "ff", "fr", "tjump", "???",
  419. "close","open", "???", "???" };
  420. u8 *c = &Pico_mcd->s68k_regs[0x42];
  421. u8 *s = &Pico_mcd->s68k_regs[0x38];
  422. elprintf(EL_CD,
  423. "CDD command: %02x %02x %02x %02x %02x %02x %02x %02x %12s",
  424. c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], nm[c[0] & 0x0f]);
  425. elprintf(EL_CD,
  426. "CDD status: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
  427. s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]);
  428. }
  429. return;
  430. case 0x58:
  431. return;
  432. }
  433. if ((a&0x1f0) == 0x20)
  434. goto write_comm;
  435. if ((a&0x1f0) == 0x10 || (a >= 0x38 && a < 0x42))
  436. {
  437. elprintf(EL_UIO, "s68k FIXME: invalid write @ %02x?", a);
  438. return;
  439. }
  440. Pico_mcd->s68k_regs[a] = (u8) d;
  441. return;
  442. write_comm:
  443. Pico_mcd->s68k_regs[a] = (u8) d;
  444. if (Pico_mcd->m.m68k_poll_cnt)
  445. SekEndRunS68k(0);
  446. Pico_mcd->m.m68k_poll_cnt = 0;
  447. }
  448. void s68k_reg_write16(u32 a, u32 d)
  449. {
  450. u8 *r = Pico_mcd->s68k_regs;
  451. if ((a & 0x1f0) == 0x20)
  452. goto write_comm;
  453. switch (a) {
  454. case 0x0e:
  455. // special case, 2 byte writes would be handled differently
  456. // TODO: verify
  457. r[0xf] = d;
  458. return;
  459. case 0x58: // stamp data size
  460. r[0x59] = d & 7;
  461. return;
  462. case 0x5a: // stamp map base address
  463. r[0x5a] = d >> 8;
  464. r[0x5b] = d & 0xe0;
  465. return;
  466. case 0x5c: // V cell size
  467. r[0x5d] = d & 0x1f;
  468. return;
  469. case 0x5e: // image buffer start address
  470. r[0x5e] = d >> 8;
  471. r[0x5f] = d & 0xf8;
  472. return;
  473. case 0x60: // image buffer offset
  474. r[0x61] = d & 0x3f;
  475. return;
  476. case 0x62: // h dot size
  477. r[0x62] = (d >> 8) & 1;
  478. r[0x63] = d;
  479. return;
  480. case 0x64: // v dot size
  481. r[0x65] = d;
  482. return;
  483. case 0x66: // trace vector base address
  484. d &= 0xfffe;
  485. r[0x66] = d >> 8;
  486. r[0x67] = d;
  487. gfx_start(d);
  488. return;
  489. default:
  490. break;
  491. }
  492. s68k_reg_write8(a, d >> 8);
  493. s68k_reg_write8(a + 1, d & 0xff);
  494. return;
  495. write_comm:
  496. r[a] = d >> 8;
  497. r[a + 1] = d;
  498. if (Pico_mcd->m.m68k_poll_cnt)
  499. SekEndRunS68k(0);
  500. Pico_mcd->m.m68k_poll_cnt = 0;
  501. }
  502. // -----------------------------------------------------------------
  503. // Main 68k
  504. // -----------------------------------------------------------------
  505. #ifndef _ASM_CD_MEMORY_C
  506. #include "cell_map.c"
  507. // WORD RAM, cell aranged area (220000 - 23ffff)
  508. static u32 PicoReadM68k8_cell0(u32 a)
  509. {
  510. a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged
  511. return Pico_mcd->word_ram1M[0][a ^ 1];
  512. }
  513. static u32 PicoReadM68k8_cell1(u32 a)
  514. {
  515. a = (a&3) | (cell_map(a >> 2) << 2);
  516. return Pico_mcd->word_ram1M[1][a ^ 1];
  517. }
  518. static u32 PicoReadM68k16_cell0(u32 a)
  519. {
  520. a = (a&2) | (cell_map(a >> 2) << 2);
  521. return *(u16 *)(Pico_mcd->word_ram1M[0] + a);
  522. }
  523. static u32 PicoReadM68k16_cell1(u32 a)
  524. {
  525. a = (a&2) | (cell_map(a >> 2) << 2);
  526. return *(u16 *)(Pico_mcd->word_ram1M[1] + a);
  527. }
  528. static void PicoWriteM68k8_cell0(u32 a, u32 d)
  529. {
  530. a = (a&3) | (cell_map(a >> 2) << 2);
  531. Pico_mcd->word_ram1M[0][a ^ 1] = d;
  532. }
  533. static void PicoWriteM68k8_cell1(u32 a, u32 d)
  534. {
  535. a = (a&3) | (cell_map(a >> 2) << 2);
  536. Pico_mcd->word_ram1M[1][a ^ 1] = d;
  537. }
  538. static void PicoWriteM68k16_cell0(u32 a, u32 d)
  539. {
  540. a = (a&3) | (cell_map(a >> 2) << 2);
  541. *(u16 *)(Pico_mcd->word_ram1M[0] + a) = d;
  542. }
  543. static void PicoWriteM68k16_cell1(u32 a, u32 d)
  544. {
  545. a = (a&3) | (cell_map(a >> 2) << 2);
  546. *(u16 *)(Pico_mcd->word_ram1M[1] + a) = d;
  547. }
  548. #endif
  549. // RAM cart (40000 - 7fffff, optional)
  550. static u32 PicoReadM68k8_ramc(u32 a)
  551. {
  552. u32 d = 0;
  553. if (a == 0x400001) {
  554. if (Pico.sv.data != NULL)
  555. d = 3; // 64k cart
  556. return d;
  557. }
  558. if ((a & 0xfe0000) == 0x600000) {
  559. if (Pico.sv.data != NULL)
  560. d = Pico.sv.data[((a >> 1) & 0xffff) + 0x2000];
  561. return d;
  562. }
  563. if (a == 0x7fffff)
  564. return Pico_mcd->m.bcram_reg;
  565. elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc);
  566. return d;
  567. }
  568. static u32 PicoReadM68k16_ramc(u32 a)
  569. {
  570. elprintf(EL_ANOMALY, "ramcart r16: [%06x] @%06x", a, SekPcS68k);
  571. return PicoReadM68k8_ramc(a + 1);
  572. }
  573. static void PicoWriteM68k8_ramc(u32 a, u32 d)
  574. {
  575. if ((a & 0xfe0000) == 0x600000) {
  576. if (Pico.sv.data != NULL && (Pico_mcd->m.bcram_reg & 1)) {
  577. Pico.sv.data[((a>>1) & 0xffff) + 0x2000] = d;
  578. Pico.sv.changed = 1;
  579. }
  580. return;
  581. }
  582. if (a == 0x7fffff) {
  583. Pico_mcd->m.bcram_reg = d;
  584. return;
  585. }
  586. elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x",
  587. a, d & 0xff, SekPc);
  588. }
  589. static void PicoWriteM68k16_ramc(u32 a, u32 d)
  590. {
  591. elprintf(EL_ANOMALY, "ramcart w16: [%06x] %04x @%06x",
  592. a, d, SekPcS68k);
  593. PicoWriteM68k8_ramc(a + 1, d);
  594. }
  595. // IO/control/cd registers (a10000 - ...)
  596. #ifndef _ASM_CD_MEMORY_C
  597. u32 PicoRead8_mcd_io(u32 a)
  598. {
  599. u32 d;
  600. if ((a & 0xff00) == 0x2000) { // a12000 - a120ff
  601. d = m68k_reg_read16(a); // TODO: m68k_reg_read8
  602. if (!(a & 1))
  603. d >>= 8;
  604. d &= 0xff;
  605. elprintf(EL_CDREGS, "m68k_regs r8: [%02x] %02x @%06x",
  606. a & 0x3f, d, SekPc);
  607. return d;
  608. }
  609. // fallback to default MD handler
  610. return PicoRead8_io(a);
  611. }
  612. u32 PicoRead16_mcd_io(u32 a)
  613. {
  614. u32 d;
  615. if ((a & 0xff00) == 0x2000) {
  616. d = m68k_reg_read16(a);
  617. elprintf(EL_CDREGS, "m68k_regs r16: [%02x] %04x @%06x",
  618. a & 0x3f, d, SekPc);
  619. return d;
  620. }
  621. return PicoRead16_io(a);
  622. }
  623. void PicoWrite8_mcd_io(u32 a, u32 d)
  624. {
  625. if ((a & 0xff00) == 0x2000) { // a12000 - a120ff
  626. elprintf(EL_CDREGS, "m68k_regs w8: [%02x] %02x @%06x",
  627. a & 0x3f, d, SekPc);
  628. m68k_reg_write8(a, d);
  629. return;
  630. }
  631. PicoWrite8_io(a, d);
  632. }
  633. void PicoWrite16_mcd_io(u32 a, u32 d)
  634. {
  635. if ((a & 0xff00) == 0x2000) { // a12000 - a120ff
  636. elprintf(EL_CDREGS, "m68k_regs w16: [%02x] %04x @%06x",
  637. a & 0x3f, d, SekPc);
  638. m68k_reg_write8(a, d >> 8);
  639. if ((a & 0x3e) != 0x0e) // special case
  640. m68k_reg_write8(a + 1, d & 0xff);
  641. return;
  642. }
  643. PicoWrite16_io(a, d);
  644. }
  645. #endif
  646. // -----------------------------------------------------------------
  647. // Sub 68k
  648. // -----------------------------------------------------------------
  649. static u32 s68k_unmapped_read8(u32 a)
  650. {
  651. elprintf(EL_UIO, "s68k unmapped r8 [%06x] @%06x", a, SekPc);
  652. return 0;
  653. }
  654. static u32 s68k_unmapped_read16(u32 a)
  655. {
  656. elprintf(EL_UIO, "s68k unmapped r16 [%06x] @%06x", a, SekPc);
  657. return 0;
  658. }
  659. static void s68k_unmapped_write8(u32 a, u32 d)
  660. {
  661. elprintf(EL_UIO, "s68k unmapped w8 [%06x] %02x @%06x",
  662. a, d & 0xff, SekPc);
  663. }
  664. static void s68k_unmapped_write16(u32 a, u32 d)
  665. {
  666. elprintf(EL_UIO, "s68k unmapped w16 [%06x] %04x @%06x",
  667. a, d & 0xffff, SekPc);
  668. }
  669. // PRG RAM protected range (000000 - 01fdff)?
  670. // XXX verify: ff00 or 1fe00 max?
  671. static void PicoWriteS68k8_prgwp(u32 a, u32 d)
  672. {
  673. if (a >= (Pico_mcd->s68k_regs[2] << 9))
  674. Pico_mcd->prg_ram[a ^ 1] = d;
  675. }
  676. static void PicoWriteS68k16_prgwp(u32 a, u32 d)
  677. {
  678. if (a >= (Pico_mcd->s68k_regs[2] << 9))
  679. *(u16 *)(Pico_mcd->prg_ram + a) = d;
  680. }
  681. #ifndef _ASM_CD_MEMORY_C
  682. // decode (080000 - 0bffff, in 1M mode)
  683. static u32 PicoReadS68k8_dec0(u32 a)
  684. {
  685. u32 d = Pico_mcd->word_ram1M[0][((a >> 1) ^ 1) & 0x1ffff];
  686. if (a & 1)
  687. d &= 0x0f;
  688. else
  689. d >>= 4;
  690. return d;
  691. }
  692. static u32 PicoReadS68k8_dec1(u32 a)
  693. {
  694. u32 d = Pico_mcd->word_ram1M[1][((a >> 1) ^ 1) & 0x1ffff];
  695. if (a & 1)
  696. d &= 0x0f;
  697. else
  698. d >>= 4;
  699. return d;
  700. }
  701. static u32 PicoReadS68k16_dec0(u32 a)
  702. {
  703. u32 d = Pico_mcd->word_ram1M[0][((a >> 1) ^ 1) & 0x1ffff];
  704. d |= d << 4;
  705. d &= ~0xf0;
  706. return d;
  707. }
  708. static u32 PicoReadS68k16_dec1(u32 a)
  709. {
  710. u32 d = Pico_mcd->word_ram1M[1][((a >> 1) ^ 1) & 0x1ffff];
  711. d |= d << 4;
  712. d &= ~0xf0;
  713. return d;
  714. }
  715. /* check: jaguar xj 220 (draws entire world using decode) */
  716. #define mk_decode_w8(bank) \
  717. static void PicoWriteS68k8_dec_m0b##bank(u32 a, u32 d) \
  718. { \
  719. u8 *pd = &Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; \
  720. \
  721. if (!(a & 1)) \
  722. *pd = (*pd & 0x0f) | (d << 4); \
  723. else \
  724. *pd = (*pd & 0xf0) | (d & 0x0f); \
  725. } \
  726. \
  727. static void PicoWriteS68k8_dec_m1b##bank(u32 a, u32 d) \
  728. { \
  729. u8 *pd = &Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; \
  730. u8 mask = (a & 1) ? 0x0f : 0xf0; \
  731. \
  732. if (!(*pd & mask) && (d & 0x0f)) /* underwrite */ \
  733. PicoWriteS68k8_dec_m0b##bank(a, d); \
  734. } \
  735. \
  736. static void PicoWriteS68k8_dec_m2b##bank(u32 a, u32 d) /* ...and m3? */ \
  737. { \
  738. if (d & 0x0f) /* overwrite */ \
  739. PicoWriteS68k8_dec_m0b##bank(a, d); \
  740. }
  741. mk_decode_w8(0)
  742. mk_decode_w8(1)
  743. #define mk_decode_w16(bank) \
  744. static void PicoWriteS68k16_dec_m0b##bank(u32 a, u32 d) \
  745. { \
  746. u8 *pd = &Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; \
  747. \
  748. d &= 0x0f0f; \
  749. *pd = d | (d >> 4); \
  750. } \
  751. \
  752. static void PicoWriteS68k16_dec_m1b##bank(u32 a, u32 d) \
  753. { \
  754. u8 *pd = &Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; \
  755. \
  756. d &= 0x0f0f; /* underwrite */ \
  757. if (!(*pd & 0xf0)) *pd |= d >> 4; \
  758. if (!(*pd & 0x0f)) *pd |= d; \
  759. } \
  760. \
  761. static void PicoWriteS68k16_dec_m2b##bank(u32 a, u32 d) \
  762. { \
  763. u8 *pd = &Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; \
  764. \
  765. d &= 0x0f0f; /* overwrite */ \
  766. d |= d >> 4; \
  767. \
  768. if (!(d & 0xf0)) d |= *pd & 0xf0; \
  769. if (!(d & 0x0f)) d |= *pd & 0x0f; \
  770. *pd = d; \
  771. }
  772. mk_decode_w16(0)
  773. mk_decode_w16(1)
  774. #endif
  775. // backup RAM (fe0000 - feffff)
  776. static u32 PicoReadS68k8_bram(u32 a)
  777. {
  778. return Pico_mcd->bram[(a>>1)&0x1fff];
  779. }
  780. static u32 PicoReadS68k16_bram(u32 a)
  781. {
  782. u32 d;
  783. elprintf(EL_ANOMALY, "FIXME: s68k_bram r16: [%06x] @%06x", a, SekPcS68k);
  784. a = (a >> 1) & 0x1fff;
  785. d = Pico_mcd->bram[a++];
  786. d|= Pico_mcd->bram[a++] << 8; // probably wrong, TODO: verify
  787. return d;
  788. }
  789. static void PicoWriteS68k8_bram(u32 a, u32 d)
  790. {
  791. Pico_mcd->bram[(a >> 1) & 0x1fff] = d;
  792. Pico.sv.changed = 1;
  793. }
  794. static void PicoWriteS68k16_bram(u32 a, u32 d)
  795. {
  796. elprintf(EL_ANOMALY, "s68k_bram w16: [%06x] %04x @%06x", a, d, SekPcS68k);
  797. a = (a >> 1) & 0x1fff;
  798. Pico_mcd->bram[a++] = d;
  799. Pico_mcd->bram[a++] = d >> 8; // TODO: verify..
  800. Pico.sv.changed = 1;
  801. }
  802. #ifndef _ASM_CD_MEMORY_C
  803. // PCM and registers (ff0000 - ffffff)
  804. static u32 PicoReadS68k8_pr(u32 a)
  805. {
  806. u32 d = 0;
  807. // regs
  808. if ((a & 0xfe00) == 0x8000) {
  809. a &= 0x1ff;
  810. if (a >= 0x0e && a < 0x30) {
  811. d = Pico_mcd->s68k_regs[a];
  812. s68k_poll_detect(a & ~1, d);
  813. goto regs_done;
  814. }
  815. d = s68k_reg_read16(a & ~1);
  816. if (!(a & 1))
  817. d >>= 8;
  818. regs_done:
  819. d &= 0xff;
  820. elprintf(EL_CDREGS, "s68k_regs r8: [%02x] %02x @%06x",
  821. a, d, SekPcS68k);
  822. return d;
  823. }
  824. // PCM
  825. // XXX: verify: probably odd addrs only?
  826. if ((a & 0x8000) == 0x0000) {
  827. a &= 0x7fff;
  828. if (a >= 0x2000)
  829. d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a >> 1) & 0xfff];
  830. else if (a >= 0x20)
  831. d = pcd_pcm_read(a >> 1);
  832. return d;
  833. }
  834. return s68k_unmapped_read8(a);
  835. }
  836. static u32 PicoReadS68k16_pr(u32 a)
  837. {
  838. u32 d = 0;
  839. // regs
  840. if ((a & 0xfe00) == 0x8000) {
  841. a &= 0x1fe;
  842. d = s68k_reg_read16(a);
  843. elprintf(EL_CDREGS, "s68k_regs r16: [%02x] %04x @%06x",
  844. a, d, SekPcS68k);
  845. return d;
  846. }
  847. // PCM
  848. if ((a & 0x8000) == 0x0000) {
  849. a &= 0x7fff;
  850. if (a >= 0x2000)
  851. d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a >> 1) & 0xfff];
  852. else if (a >= 0x20)
  853. d = pcd_pcm_read(a >> 1);
  854. return d;
  855. }
  856. return s68k_unmapped_read16(a);
  857. }
  858. static void PicoWriteS68k8_pr(u32 a, u32 d)
  859. {
  860. // regs
  861. if ((a & 0xfe00) == 0x8000) {
  862. a &= 0x1ff;
  863. elprintf(EL_CDREGS, "s68k_regs w8: [%02x] %02x @%06x", a, d, SekPcS68k);
  864. if (0x59 <= a && a < 0x68) // word regs
  865. s68k_reg_write16(a & ~1, (d << 8) | d);
  866. else
  867. s68k_reg_write8(a, d);
  868. return;
  869. }
  870. // PCM
  871. if ((a & 0x8000) == 0x0000) {
  872. a &= 0x7fff;
  873. if (a >= 0x2000)
  874. Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d;
  875. else if (a < 0x12)
  876. pcd_pcm_write(a>>1, d);
  877. return;
  878. }
  879. s68k_unmapped_write8(a, d);
  880. }
  881. static void PicoWriteS68k16_pr(u32 a, u32 d)
  882. {
  883. // regs
  884. if ((a & 0xfe00) == 0x8000) {
  885. a &= 0x1fe;
  886. elprintf(EL_CDREGS, "s68k_regs w16: [%02x] %04x @%06x", a, d, SekPcS68k);
  887. s68k_reg_write16(a, d);
  888. return;
  889. }
  890. // PCM
  891. if ((a & 0x8000) == 0x0000) {
  892. a &= 0x7fff;
  893. if (a >= 0x2000)
  894. Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d;
  895. else if (a < 0x12)
  896. pcd_pcm_write(a>>1, d & 0xff);
  897. return;
  898. }
  899. s68k_unmapped_write16(a, d);
  900. }
  901. #endif
  902. static const void *m68k_cell_read8[] = { PicoReadM68k8_cell0, PicoReadM68k8_cell1 };
  903. static const void *m68k_cell_read16[] = { PicoReadM68k16_cell0, PicoReadM68k16_cell1 };
  904. static const void *m68k_cell_write8[] = { PicoWriteM68k8_cell0, PicoWriteM68k8_cell1 };
  905. static const void *m68k_cell_write16[] = { PicoWriteM68k16_cell0, PicoWriteM68k16_cell1 };
  906. static const void *s68k_dec_read8[] = { PicoReadS68k8_dec0, PicoReadS68k8_dec1 };
  907. static const void *s68k_dec_read16[] = { PicoReadS68k16_dec0, PicoReadS68k16_dec1 };
  908. static const void *s68k_dec_write8[2][4] = {
  909. { PicoWriteS68k8_dec_m0b0, PicoWriteS68k8_dec_m1b0, PicoWriteS68k8_dec_m2b0, PicoWriteS68k8_dec_m2b0 },
  910. { PicoWriteS68k8_dec_m0b1, PicoWriteS68k8_dec_m1b1, PicoWriteS68k8_dec_m2b1, PicoWriteS68k8_dec_m2b1 },
  911. };
  912. static const void *s68k_dec_write16[2][4] = {
  913. { PicoWriteS68k16_dec_m0b0, PicoWriteS68k16_dec_m1b0, PicoWriteS68k16_dec_m2b0, PicoWriteS68k16_dec_m2b0 },
  914. { PicoWriteS68k16_dec_m0b1, PicoWriteS68k16_dec_m1b1, PicoWriteS68k16_dec_m2b1, PicoWriteS68k16_dec_m2b1 },
  915. };
  916. // -----------------------------------------------------------------
  917. static void remap_prg_window(u32 r1, u32 r3)
  918. {
  919. // PRG RAM
  920. if (r1 & 2) {
  921. void *bank = Pico_mcd->prg_ram_b[(r3 >> 6) & 3];
  922. cpu68k_map_all_ram(0x020000, 0x03ffff, bank, 0);
  923. }
  924. else {
  925. m68k_map_unmap(0x020000, 0x03ffff);
  926. }
  927. }
  928. static void remap_word_ram(u32 r3)
  929. {
  930. void *bank;
  931. // WORD RAM
  932. if (!(r3 & 4)) {
  933. // 2M mode. XXX: allowing access in all cases for simplicity
  934. bank = Pico_mcd->word_ram2M;
  935. cpu68k_map_all_ram(0x200000, 0x23ffff, bank, 0);
  936. cpu68k_map_all_ram(0x080000, 0x0bffff, bank, 1);
  937. // TODO: handle 0x0c0000
  938. }
  939. else {
  940. int b0 = r3 & 1;
  941. int m = (r3 & 0x18) >> 3;
  942. bank = Pico_mcd->word_ram1M[b0];
  943. cpu68k_map_all_ram(0x200000, 0x21ffff, bank, 0);
  944. bank = Pico_mcd->word_ram1M[b0 ^ 1];
  945. cpu68k_map_all_ram(0x0c0000, 0x0effff, bank, 1);
  946. // "cell arrange" on m68k
  947. cpu68k_map_set(m68k_read8_map, 0x220000, 0x23ffff, m68k_cell_read8[b0], 1);
  948. cpu68k_map_set(m68k_read16_map, 0x220000, 0x23ffff, m68k_cell_read16[b0], 1);
  949. cpu68k_map_set(m68k_write8_map, 0x220000, 0x23ffff, m68k_cell_write8[b0], 1);
  950. cpu68k_map_set(m68k_write16_map, 0x220000, 0x23ffff, m68k_cell_write16[b0], 1);
  951. // "decode format" on s68k
  952. cpu68k_map_set(s68k_read8_map, 0x080000, 0x0bffff, s68k_dec_read8[b0 ^ 1], 1);
  953. cpu68k_map_set(s68k_read16_map, 0x080000, 0x0bffff, s68k_dec_read16[b0 ^ 1], 1);
  954. cpu68k_map_set(s68k_write8_map, 0x080000, 0x0bffff, s68k_dec_write8[b0 ^ 1][m], 1);
  955. cpu68k_map_set(s68k_write16_map, 0x080000, 0x0bffff, s68k_dec_write16[b0 ^ 1][m], 1);
  956. }
  957. }
  958. void pcd_state_loaded_mem(void)
  959. {
  960. u32 r3 = Pico_mcd->s68k_regs[3];
  961. /* after load events */
  962. if (r3 & 4) // 1M mode?
  963. wram_2M_to_1M(Pico_mcd->word_ram2M);
  964. remap_word_ram(r3);
  965. remap_prg_window(Pico_mcd->m.busreq, r3);
  966. Pico_mcd->m.dmna_ret_2m &= 3;
  967. // restore hint vector
  968. *(unsigned short *)(Pico_mcd->bios + 0x72) = Pico_mcd->m.hint_vector;
  969. }
  970. #ifdef EMU_M68K
  971. static void m68k_mem_setup_cd(void);
  972. #endif
  973. PICO_INTERNAL void PicoMemSetupCD(void)
  974. {
  975. // setup default main68k map
  976. PicoMemSetup();
  977. // main68k map (BIOS mapped by PicoMemSetup()):
  978. // RAM cart
  979. if (PicoIn.opt & POPT_EN_MCD_RAMCART) {
  980. cpu68k_map_set(m68k_read8_map, 0x400000, 0x7fffff, PicoReadM68k8_ramc, 1);
  981. cpu68k_map_set(m68k_read16_map, 0x400000, 0x7fffff, PicoReadM68k16_ramc, 1);
  982. cpu68k_map_set(m68k_write8_map, 0x400000, 0x7fffff, PicoWriteM68k8_ramc, 1);
  983. cpu68k_map_set(m68k_write16_map, 0x400000, 0x7fffff, PicoWriteM68k16_ramc, 1);
  984. }
  985. // registers/IO:
  986. cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoRead8_mcd_io, 1);
  987. cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoRead16_mcd_io, 1);
  988. cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWrite8_mcd_io, 1);
  989. cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_mcd_io, 1);
  990. // sub68k map
  991. cpu68k_map_set(s68k_read8_map, 0x000000, 0xffffff, s68k_unmapped_read8, 1);
  992. cpu68k_map_set(s68k_read16_map, 0x000000, 0xffffff, s68k_unmapped_read16, 1);
  993. cpu68k_map_set(s68k_write8_map, 0x000000, 0xffffff, s68k_unmapped_write8, 1);
  994. cpu68k_map_set(s68k_write16_map, 0x000000, 0xffffff, s68k_unmapped_write16, 1);
  995. // PRG RAM
  996. cpu68k_map_set(s68k_read8_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0);
  997. cpu68k_map_set(s68k_read16_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0);
  998. cpu68k_map_set(s68k_write8_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0);
  999. cpu68k_map_set(s68k_write16_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0);
  1000. cpu68k_map_set(s68k_write8_map, 0x000000, 0x01ffff, PicoWriteS68k8_prgwp, 1);
  1001. cpu68k_map_set(s68k_write16_map, 0x000000, 0x01ffff, PicoWriteS68k16_prgwp, 1);
  1002. // BRAM
  1003. cpu68k_map_set(s68k_read8_map, 0xfe0000, 0xfeffff, PicoReadS68k8_bram, 1);
  1004. cpu68k_map_set(s68k_read16_map, 0xfe0000, 0xfeffff, PicoReadS68k16_bram, 1);
  1005. cpu68k_map_set(s68k_write8_map, 0xfe0000, 0xfeffff, PicoWriteS68k8_bram, 1);
  1006. cpu68k_map_set(s68k_write16_map, 0xfe0000, 0xfeffff, PicoWriteS68k16_bram, 1);
  1007. // PCM, regs
  1008. cpu68k_map_set(s68k_read8_map, 0xff0000, 0xffffff, PicoReadS68k8_pr, 1);
  1009. cpu68k_map_set(s68k_read16_map, 0xff0000, 0xffffff, PicoReadS68k16_pr, 1);
  1010. cpu68k_map_set(s68k_write8_map, 0xff0000, 0xffffff, PicoWriteS68k8_pr, 1);
  1011. cpu68k_map_set(s68k_write16_map, 0xff0000, 0xffffff, PicoWriteS68k16_pr, 1);
  1012. // RAMs
  1013. remap_word_ram(1);
  1014. #ifdef EMU_C68K
  1015. // s68k
  1016. PicoCpuCS68k.read8 = (void *)s68k_read8_map;
  1017. PicoCpuCS68k.read16 = (void *)s68k_read16_map;
  1018. PicoCpuCS68k.read32 = (void *)s68k_read16_map;
  1019. PicoCpuCS68k.write8 = (void *)s68k_write8_map;
  1020. PicoCpuCS68k.write16 = (void *)s68k_write16_map;
  1021. PicoCpuCS68k.write32 = (void *)s68k_write16_map;
  1022. PicoCpuCS68k.checkpc = NULL; /* unused */
  1023. PicoCpuCS68k.fetch8 = NULL;
  1024. PicoCpuCS68k.fetch16 = NULL;
  1025. PicoCpuCS68k.fetch32 = NULL;
  1026. #endif
  1027. #ifdef EMU_F68K
  1028. // s68k
  1029. PicoCpuFS68k.read_byte = (void *)s68k_read8;
  1030. PicoCpuFS68k.read_word = (void *)s68k_read16;
  1031. PicoCpuFS68k.read_long = (void *)s68k_read32;
  1032. PicoCpuFS68k.write_byte = (void *)s68k_write8;
  1033. PicoCpuFS68k.write_word = (void *)s68k_write16;
  1034. PicoCpuFS68k.write_long = (void *)s68k_write32;
  1035. // setup FAME fetchmap
  1036. {
  1037. #ifdef __clang__
  1038. volatile // prevent strange relocs from clang
  1039. #endif
  1040. unsigned long ptr_ram = (uptr)PicoMem.ram;
  1041. int i;
  1042. // M68k
  1043. // by default, point everything to fitst 64k of ROM (BIOS)
  1044. for (i = 0; i < M68K_FETCHBANK1; i++)
  1045. PicoCpuFM68k.Fetch[i] = (uptr)Pico.rom - (i<<(24-FAMEC_FETCHBITS));
  1046. // now real ROM (BIOS)
  1047. for (i = 0; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < Pico.romsize; i++)
  1048. PicoCpuFM68k.Fetch[i] = (uptr)Pico.rom;
  1049. // .. and RAM
  1050. for (i = M68K_FETCHBANK1*14/16; i < M68K_FETCHBANK1; i++)
  1051. PicoCpuFM68k.Fetch[i] = ptr_ram - (i<<(24-FAMEC_FETCHBITS));
  1052. // S68k
  1053. // PRG RAM is default
  1054. for (i = 0; i < M68K_FETCHBANK1; i++)
  1055. PicoCpuFS68k.Fetch[i] = (uptr)Pico_mcd->prg_ram - (i<<(24-FAMEC_FETCHBITS));
  1056. // real PRG RAM
  1057. for (i = 0; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < 0x80000; i++)
  1058. PicoCpuFS68k.Fetch[i] = (uptr)Pico_mcd->prg_ram;
  1059. // WORD RAM 2M area
  1060. for (i = M68K_FETCHBANK1*0x08/0x100; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < 0xc0000; i++)
  1061. PicoCpuFS68k.Fetch[i] = (uptr)Pico_mcd->word_ram2M - 0x80000;
  1062. // remap_word_ram() will setup word ram for both
  1063. }
  1064. #endif
  1065. #ifdef EMU_M68K
  1066. m68k_mem_setup_cd();
  1067. #endif
  1068. }
  1069. #ifdef EMU_M68K
  1070. u32 m68k_read8(u32 a);
  1071. u32 m68k_read16(u32 a);
  1072. u32 m68k_read32(u32 a);
  1073. void m68k_write8(u32 a, u8 d);
  1074. void m68k_write16(u32 a, u16 d);
  1075. void m68k_write32(u32 a, u32 d);
  1076. static unsigned int PicoReadCD8w (unsigned int a) {
  1077. return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read8(a) : m68k_read8(a);
  1078. }
  1079. static unsigned int PicoReadCD16w(unsigned int a) {
  1080. return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read16(a) : m68k_read16(a);
  1081. }
  1082. static unsigned int PicoReadCD32w(unsigned int a) {
  1083. return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read32(a) : m68k_read32(a);
  1084. }
  1085. static void PicoWriteCD8w (unsigned int a, unsigned char d) {
  1086. if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write8(a, d); else m68k_write8(a, d);
  1087. }
  1088. static void PicoWriteCD16w(unsigned int a, unsigned short d) {
  1089. if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write16(a, d); else m68k_write16(a, d);
  1090. }
  1091. static void PicoWriteCD32w(unsigned int a, unsigned int d) {
  1092. if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write32(a, d); else m68k_write32(a, d);
  1093. }
  1094. extern unsigned int (*pm68k_read_memory_8) (unsigned int address);
  1095. extern unsigned int (*pm68k_read_memory_16)(unsigned int address);
  1096. extern unsigned int (*pm68k_read_memory_32)(unsigned int address);
  1097. extern void (*pm68k_write_memory_8) (unsigned int address, unsigned char value);
  1098. extern void (*pm68k_write_memory_16)(unsigned int address, unsigned short value);
  1099. extern void (*pm68k_write_memory_32)(unsigned int address, unsigned int value);
  1100. static void m68k_mem_setup_cd(void)
  1101. {
  1102. pm68k_read_memory_8 = PicoReadCD8w;
  1103. pm68k_read_memory_16 = PicoReadCD16w;
  1104. pm68k_read_memory_32 = PicoReadCD32w;
  1105. pm68k_write_memory_8 = PicoWriteCD8w;
  1106. pm68k_write_memory_16 = PicoWriteCD16w;
  1107. pm68k_write_memory_32 = PicoWriteCD32w;
  1108. }
  1109. #endif // EMU_M68K
  1110. // vim:shiftwidth=2:ts=2:expandtab