memory.c 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493
  1. /*
  2. * PicoDrive
  3. * (C) notaz, 2009,2010,2013
  4. * (C) kub, 2019
  5. *
  6. * This work is licensed under the terms of MAME license.
  7. * See COPYING file in the top-level directory.
  8. *
  9. * Register map:
  10. * a15100 F....... R.....EA F.....AC N...VHMP 4000 // Fm Ren nrEs Aden Cart heN V H cMd Pwm
  11. * a15102 ........ ......SM ? 4002 // intS intM
  12. * a15104 ........ ......10 ........ hhhhhhhh 4004 // bk1 bk0 Hint
  13. * a15106 ........ F....SDR UE...... .....SDR 4006 // Full 68S Dma Rv fUll[fb] Empt[fb]
  14. * a15108 (32bit DREQ src) 4008
  15. * a1510c (32bit DREQ dst) 400c
  16. * a15110 llllllll llllll00 4010 // DREQ Len
  17. * a15112 (16bit FIFO reg) 4012
  18. * a15114 0 (16bit VRES clr) 4014
  19. * a15116 0 (16bit Vint clr) 4016
  20. * a15118 0 (16bit Hint clr) 4018
  21. * a1511a .......? .......C (16bit CMD clr) 401a // TV Cm
  22. * a1511c 0 (16bit PWM clr) 401c
  23. * a1511e 0 ? 401e
  24. * a15120 (16 bytes comm) 2020
  25. * a15130 (PWM) 2030
  26. *
  27. * SH2 addr lines:
  28. * iii. .cc. ..xx * // Internal, Cs, x
  29. *
  30. * sh2 map, wait/bus cycles (from docs):
  31. * r w
  32. * rom 0000000-0003fff 1 -
  33. * sys reg 0004000-00040ff 1 1
  34. * vdp reg 0004100-00041ff 5 5
  35. * vdp pal 0004200-00043ff 5 5
  36. * cart 2000000-23fffff 6-15
  37. * dram/fb 4000000-401ffff 5-12 1-3
  38. * fb ovr 4020000-403ffff
  39. * sdram 6000000-603ffff 12 2 (cycles)
  40. * d.a. c0000000-?
  41. */
  42. #include "../pico_int.h"
  43. #include "../memory.h"
  44. #include <cpu/sh2/compiler.h>
  45. DRC_DECLARE_SR;
  46. static const char str_mars[] = "MARS";
  47. void *p32x_bios_g, *p32x_bios_m, *p32x_bios_s;
  48. struct Pico32xMem *Pico32xMem;
  49. static void bank_switch_rom_68k(int b);
  50. static void (*m68k_write8_io)(u32 a, u32 d);
  51. static void (*m68k_write16_io)(u32 a, u32 d);
  52. // addressing byte in 16bit reg
  53. #define REG8IN16(ptr, offs) ((u8 *)ptr)[MEM_BE2(offs)]
  54. // poll detection
  55. #define POLL_THRESHOLD 5
  56. static struct {
  57. u32 addr1, addr2, cycles;
  58. int cnt;
  59. } m68k_poll;
  60. static int m68k_poll_detect(u32 a, u32 cycles, u32 flags)
  61. {
  62. int ret = 0;
  63. // support polling on 2 addresses - seen in Wolfenstein
  64. int match = (a - m68k_poll.addr1 <= 2 || a - m68k_poll.addr2 <= 2);
  65. if (match && cycles - m68k_poll.cycles <= 64 && !SekNotPolling)
  66. {
  67. // detect split 32bit access by same cycle count, and ignore those
  68. if (cycles != m68k_poll.cycles && ++m68k_poll.cnt >= POLL_THRESHOLD) {
  69. if (!(Pico32x.emu_flags & flags)) {
  70. elprintf(EL_32X, "m68k poll addr %08x, cyc %u",
  71. a, cycles - m68k_poll.cycles);
  72. }
  73. Pico32x.emu_flags |= flags;
  74. ret = 1;
  75. }
  76. }
  77. else {
  78. // reset poll state in case of restart by interrupt
  79. Pico32x.emu_flags &= ~(P32XF_68KCPOLL|P32XF_68KVPOLL);
  80. SekSetStop(0);
  81. m68k_poll.cnt = 0;
  82. if (!match) {
  83. m68k_poll.addr2 = m68k_poll.addr1;
  84. m68k_poll.addr1 = a;
  85. }
  86. SekNotPolling = 0;
  87. }
  88. m68k_poll.cycles = cycles;
  89. return ret;
  90. }
  91. void p32x_m68k_poll_event(u32 flags)
  92. {
  93. if (Pico32x.emu_flags & flags) {
  94. elprintf(EL_32X, "m68k poll %02x -> %02x", Pico32x.emu_flags,
  95. Pico32x.emu_flags & ~flags);
  96. Pico32x.emu_flags &= ~flags;
  97. SekSetStop(0);
  98. }
  99. m68k_poll.addr1 = m68k_poll.addr2 = m68k_poll.cnt = 0;
  100. }
  101. void NOINLINE p32x_sh2_poll_detect(u32 a, SH2 *sh2, u32 flags, int maxcnt)
  102. {
  103. u32 cycles_done = sh2_cycles_done_t(sh2);
  104. u32 cycles_diff = cycles_done - sh2->poll_cycles;
  105. // reading 2 consecutive 16bit values is probably a 32bit access. detect this
  106. // by checking address (max 2 bytes away) and cycles (max 2 cycles later).
  107. // no polling if more than 20 cycles have passed since last detect call.
  108. if (a - sh2->poll_addr <= 2 && CYCLES_GE(20, cycles_diff)) {
  109. if (!sh2_not_polling(sh2) && CYCLES_GT(cycles_diff, 2) &&
  110. ++sh2->poll_cnt >= maxcnt) {
  111. if (!(sh2->state & flags))
  112. elprintf_sh2(sh2, EL_32X, "state: %02x->%02x",
  113. sh2->state, sh2->state | flags);
  114. sh2->state |= flags;
  115. sh2_end_run(sh2, 0);
  116. pevt_log_sh2(sh2, EVT_POLL_START);
  117. #ifdef DRC_SH2
  118. // mark this as an address used for polling if SDRAM
  119. if ((a & 0xc6000000) == 0x06000000) {
  120. unsigned char *p = sh2->p_drcblk_ram;
  121. p[(a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT] |= 0x80;
  122. // mark next word too to enable poll fifo for 32bit access
  123. p[((a+2) & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT] |= 0x80;
  124. }
  125. #endif
  126. }
  127. }
  128. else if (!(sh2->state & (SH2_STATE_CPOLL|SH2_STATE_VPOLL|SH2_STATE_RPOLL))) {
  129. sh2->poll_cnt = 0;
  130. sh2->poll_addr = a;
  131. }
  132. sh2->poll_cycles = cycles_done;
  133. sh2_set_polling(sh2);
  134. }
  135. void NOINLINE p32x_sh2_poll_event(SH2 *sh2, u32 flags, u32 m68k_cycles)
  136. {
  137. if (sh2->state & flags) {
  138. elprintf_sh2(sh2, EL_32X, "state: %02x->%02x", sh2->state,
  139. sh2->state & ~flags);
  140. if (sh2->m68krcycles_done < m68k_cycles && !(sh2->state & SH2_STATE_RUN))
  141. sh2->m68krcycles_done = m68k_cycles;
  142. pevt_log_sh2_o(sh2, EVT_POLL_END);
  143. sh2->state &= ~flags;
  144. }
  145. if (!(sh2->state & (SH2_STATE_CPOLL|SH2_STATE_VPOLL|SH2_STATE_RPOLL)))
  146. sh2->poll_addr = sh2->poll_cycles = sh2->poll_cnt = 0;
  147. }
  148. static NOINLINE void sh2s_sync_on_read(SH2 *sh2, unsigned cycles)
  149. {
  150. if (sh2->poll_cnt != 0)
  151. return;
  152. if (p32x_sh2_ready(sh2->other_sh2, cycles-250))
  153. p32x_sync_other_sh2(sh2, cycles);
  154. }
  155. // poll fifo, stores writes to potential addresses used for polling.
  156. // This is used to correctly deliver syncronisation data to the 3 cpus. The
  157. // fifo stores 16 bit values, 8/32 bit accesses must be adapted accordingly.
  158. #define PFIFO_SZ 4
  159. #define PFIFO_CNT 8
  160. struct sh2_poll_fifo {
  161. u32 cycles;
  162. u32 a;
  163. u16 d;
  164. int cpu;
  165. } sh2_poll_fifo[PFIFO_CNT][PFIFO_SZ];
  166. unsigned sh2_poll_rd[PFIFO_CNT], sh2_poll_wr[PFIFO_CNT]; // ringbuffer pointers
  167. static NOINLINE u32 sh2_poll_read(u32 a, u32 d, unsigned int cycles, SH2* sh2)
  168. {
  169. int hix = (a >> 1) % PFIFO_CNT;
  170. struct sh2_poll_fifo *fifo = sh2_poll_fifo[hix];
  171. struct sh2_poll_fifo *p;
  172. int cpu = sh2 ? sh2->is_slave : -1;
  173. unsigned idx;
  174. a &= ~0x20000000; // ignore writethrough bit
  175. // fetch oldest write to address from fifo, but stop when reaching the present
  176. idx = sh2_poll_rd[hix];
  177. while (idx != sh2_poll_wr[hix] && CYCLES_GE(cycles, fifo[idx].cycles)) {
  178. p = &fifo[idx];
  179. idx = (idx+1) % PFIFO_SZ;
  180. if (cpu != p->cpu) {
  181. if (CYCLES_GT(cycles, p->cycles+80)) {
  182. // drop older fifo stores that may cause synchronisation problems.
  183. p->a = -1;
  184. } else if (p->a == a) {
  185. // replace current data with fifo value and discard fifo entry
  186. d = p->d;
  187. p->a = -1;
  188. break;
  189. }
  190. }
  191. }
  192. return d;
  193. }
  194. static NOINLINE void sh2_poll_write(u32 a, u32 d, unsigned int cycles, SH2 *sh2)
  195. {
  196. int hix = (a >> 1) % PFIFO_CNT;
  197. struct sh2_poll_fifo *fifo = sh2_poll_fifo[hix];
  198. struct sh2_poll_fifo *q;
  199. int cpu = sh2 ? sh2->is_slave : -1;
  200. unsigned rd = sh2_poll_rd[hix], wr = sh2_poll_wr[hix];
  201. unsigned idx, nrd;
  202. a &= ~0x20000000; // ignore writethrough bit
  203. // throw out any values written by other cpus, plus heading cancelled stuff
  204. for (idx = nrd = wr; idx != rd; ) {
  205. idx = (idx-1) % PFIFO_SZ;
  206. q = &fifo[idx];
  207. if (q->a == a && q->cpu != cpu) { q->a = -1; }
  208. if (q->a != -1) { nrd = idx; }
  209. }
  210. rd = nrd;
  211. // fold 2 consecutive writes to the same address to avoid reading of
  212. // intermediate values that may cause synchronisation problems.
  213. // NB this can take an eternity on m68k: mov.b <addr1.l>,<addr2.l> needs
  214. // 28 m68k-cycles (~80 sh2-cycles) to complete (observed in Metal Head)
  215. q = &fifo[(sh2_poll_wr[hix]-1) % PFIFO_SZ];
  216. if (rd != wr && q->a == a && !CYCLES_GT(cycles,q->cycles + (cpu<0 ? 30:4))) {
  217. q->d = d;
  218. } else {
  219. // store write to poll address in fifo
  220. fifo[wr] =
  221. (struct sh2_poll_fifo){ .cycles = cycles, .a = a, .d = d, .cpu = cpu };
  222. wr = (wr+1) % PFIFO_SZ;
  223. if (wr == rd)
  224. // fifo overflow, discard oldest value
  225. rd = (rd+1) % PFIFO_SZ;
  226. }
  227. sh2_poll_rd[hix] = rd; sh2_poll_wr[hix] = wr;
  228. }
  229. u32 REGPARM(3) p32x_sh2_poll_memory8(u32 a, u32 d, SH2 *sh2)
  230. {
  231. int shift = (a & 1 ? 0 : 8);
  232. d = (s8)(p32x_sh2_poll_memory16(a & ~1, d << shift, sh2) >> shift);
  233. return d;
  234. }
  235. u32 REGPARM(3) p32x_sh2_poll_memory16(u32 a, u32 d, SH2 *sh2)
  236. {
  237. unsigned char *p = sh2->p_drcblk_ram;
  238. unsigned int cycles;
  239. DRC_SAVE_SR(sh2);
  240. // is this a synchronisation address?
  241. if(p[(a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT] & 0x80) {
  242. cycles = sh2_cycles_done_m68k(sh2);
  243. sh2s_sync_on_read(sh2, cycles);
  244. // check poll fifo and sign-extend the result correctly
  245. d = (s16)sh2_poll_read(a, d, cycles, sh2);
  246. }
  247. p32x_sh2_poll_detect(a, sh2, SH2_STATE_RPOLL, 5);
  248. DRC_RESTORE_SR(sh2);
  249. return d;
  250. }
  251. u32 REGPARM(3) p32x_sh2_poll_memory32(u32 a, u32 d, SH2 *sh2)
  252. {
  253. unsigned char *p = sh2->p_drcblk_ram;
  254. unsigned int cycles;
  255. DRC_SAVE_SR(sh2);
  256. // is this a synchronisation address?
  257. if(p[(a & 0x3ffff) >> SH2_DRCBLK_RAM_SHIFT] & 0x80) {
  258. cycles = sh2_cycles_done_m68k(sh2);
  259. sh2s_sync_on_read(sh2, cycles);
  260. // check poll fifo and sign-extend the result correctly
  261. d = (sh2_poll_read(a, d >> 16, cycles, sh2) << 16) |
  262. ((u16)sh2_poll_read(a+2, d, cycles, sh2));
  263. }
  264. p32x_sh2_poll_detect(a, sh2, SH2_STATE_RPOLL, 5);
  265. DRC_RESTORE_SR(sh2);
  266. return d;
  267. }
  268. // SH2 faking
  269. //#define FAKE_SH2
  270. #ifdef FAKE_SH2
  271. static int p32x_csum_faked;
  272. static const u16 comm_fakevals[] = {
  273. 0x4d5f, 0x4f4b, // M_OK
  274. 0x535f, 0x4f4b, // S_OK
  275. 0x4D41, 0x5346, // MASF - Brutal Unleashed
  276. 0x5331, 0x4d31, // Darxide
  277. 0x5332, 0x4d32,
  278. 0x5333, 0x4d33,
  279. 0x0000, 0x0000, // eq for doom
  280. 0x0002, // Mortal Kombat
  281. // 0, // pad
  282. };
  283. static u32 sh2_comm_faker(u32 a)
  284. {
  285. static int f = 0;
  286. if (a == 0x28 && !p32x_csum_faked) {
  287. p32x_csum_faked = 1;
  288. return *(u16 *)(Pico.rom + 0x18e);
  289. }
  290. if (f >= sizeof(comm_fakevals) / sizeof(comm_fakevals[0]))
  291. f = 0;
  292. return comm_fakevals[f++];
  293. }
  294. #endif
  295. // ------------------------------------------------------------------
  296. // 68k regs
  297. static u32 p32x_reg_read16(u32 a)
  298. {
  299. a &= 0x3e;
  300. #if 0
  301. if ((a & 0x30) == 0x20)
  302. return sh2_comm_faker(a);
  303. #else
  304. if ((a & 0x30) == 0x20) {
  305. unsigned int cycles = SekCyclesDone();
  306. if (CYCLES_GT(cycles - msh2.m68krcycles_done, 244))
  307. p32x_sync_sh2s(cycles);
  308. if (m68k_poll_detect(a, cycles, P32XF_68KCPOLL)) {
  309. SekSetStop(1);
  310. SekEndRun(16);
  311. }
  312. return sh2_poll_read(a, Pico32x.regs[a / 2], cycles, NULL);
  313. }
  314. #endif
  315. if (a == 2) { // INTM, INTS
  316. unsigned int cycles = SekCyclesDone();
  317. if (CYCLES_GT(cycles - msh2.m68krcycles_done, 64))
  318. p32x_sync_sh2s(cycles);
  319. goto out;
  320. }
  321. if ((a & 0x30) == 0x30)
  322. return p32x_pwm_read16(a, NULL, SekCyclesDone());
  323. out:
  324. return Pico32x.regs[a / 2];
  325. }
  326. static void dreq0_write(u16 *r, u32 d)
  327. {
  328. if (!(r[6 / 2] & P32XS_68S)) {
  329. elprintf(EL_32X|EL_ANOMALY, "DREQ FIFO w16 without 68S?");
  330. return; // ignored - tested
  331. }
  332. if (Pico32x.dmac0_fifo_ptr < DMAC_FIFO_LEN) {
  333. Pico32x.dmac_fifo[Pico32x.dmac0_fifo_ptr++] = d;
  334. if (Pico32x.dmac0_fifo_ptr == DMAC_FIFO_LEN)
  335. r[6 / 2] |= P32XS_FULL;
  336. // tested: len register decrements and 68S clears
  337. // even if SH2s/DMAC aren't active..
  338. r[0x10 / 2]--;
  339. if (r[0x10 / 2] == 0)
  340. r[6 / 2] &= ~P32XS_68S;
  341. if ((Pico32x.dmac0_fifo_ptr & 3) == 0) {
  342. p32x_sync_sh2s(SekCyclesDone());
  343. p32x_dreq0_trigger();
  344. }
  345. }
  346. else
  347. elprintf(EL_32X|EL_ANOMALY, "DREQ FIFO overflow!");
  348. }
  349. // writable bits tested
  350. static void p32x_reg_write8(u32 a, u32 d)
  351. {
  352. u16 *r = Pico32x.regs;
  353. a &= 0x3f;
  354. // for things like bset on comm port
  355. m68k_poll.cnt = 0;
  356. switch (a) {
  357. case 0x00: // adapter ctl: FM writable
  358. REG8IN16(r, 0x00) = d & 0x80;
  359. return;
  360. case 0x01: // adapter ctl: RES and ADEN writable
  361. if ((d ^ r[0]) & d & P32XS_nRES)
  362. p32x_reset_sh2s();
  363. REG8IN16(r, 0x01) &= ~(P32XS_nRES|P32XS_ADEN);
  364. REG8IN16(r, 0x01) |= d & (P32XS_nRES|P32XS_ADEN);
  365. return;
  366. case 0x02: // ignored, always 0
  367. return;
  368. case 0x03: // irq ctl
  369. if ((d ^ r[0x02 / 2]) & 3) {
  370. unsigned int cycles = SekCyclesDone();
  371. p32x_sync_sh2s(cycles);
  372. r[0x02 / 2] = d & 3;
  373. p32x_update_cmd_irq(NULL, cycles);
  374. }
  375. return;
  376. case 0x04: // ignored, always 0
  377. return;
  378. case 0x05: // bank
  379. d &= 3;
  380. if (r[0x04 / 2] != d) {
  381. r[0x04 / 2] = d;
  382. bank_switch_rom_68k(d);
  383. }
  384. return;
  385. case 0x06: // ignored, always 0
  386. return;
  387. case 0x07: // DREQ ctl
  388. REG8IN16(r, 0x07) &= ~(P32XS_68S|P32XS_DMA|P32XS_RV);
  389. if (!(d & P32XS_68S)) {
  390. Pico32x.dmac0_fifo_ptr = 0;
  391. REG8IN16(r, 0x07) &= ~P32XS_FULL;
  392. }
  393. REG8IN16(r, 0x07) |= d & (P32XS_68S|P32XS_DMA|P32XS_RV);
  394. return;
  395. case 0x08: // ignored, always 0
  396. return;
  397. case 0x09: // DREQ src
  398. REG8IN16(r, 0x09) = d;
  399. return;
  400. case 0x0a:
  401. REG8IN16(r, 0x0a) = d;
  402. return;
  403. case 0x0b:
  404. REG8IN16(r, 0x0b) = d & 0xfe;
  405. return;
  406. case 0x0c: // ignored, always 0
  407. return;
  408. case 0x0d: // DREQ dest
  409. case 0x0e:
  410. case 0x0f:
  411. case 0x10: // DREQ len
  412. REG8IN16(r, a) = d;
  413. return;
  414. case 0x11:
  415. REG8IN16(r, a) = d & 0xfc;
  416. return;
  417. // DREQ FIFO - writes to odd addr go to fifo
  418. // do writes to even work? Reads return 0
  419. case 0x12:
  420. REG8IN16(r, a) = d;
  421. return;
  422. case 0x13:
  423. d = (REG8IN16(r, 0x12) << 8) | (d & 0xff);
  424. REG8IN16(r, 0x12) = 0;
  425. dreq0_write(r, d);
  426. return;
  427. case 0x14: // ignored, always 0
  428. case 0x15:
  429. case 0x16:
  430. case 0x17:
  431. case 0x18:
  432. case 0x19:
  433. return;
  434. case 0x1a: // what's this?
  435. elprintf(EL_32X|EL_ANOMALY, "mystery w8 %02x %02x", a, d);
  436. REG8IN16(r, a) = d & 0x01;
  437. return;
  438. case 0x1b: // TV
  439. REG8IN16(r, a) = d & 0x01;
  440. return;
  441. case 0x1c: // ignored, always 0
  442. case 0x1d:
  443. case 0x1e:
  444. case 0x1f:
  445. return;
  446. case 0x20: // comm port
  447. case 0x21:
  448. case 0x22:
  449. case 0x23:
  450. case 0x24:
  451. case 0x25:
  452. case 0x26:
  453. case 0x27:
  454. case 0x28:
  455. case 0x29:
  456. case 0x2a:
  457. case 0x2b:
  458. case 0x2c:
  459. case 0x2d:
  460. case 0x2e:
  461. case 0x2f:
  462. { unsigned int cycles = SekCyclesDone();
  463. if (CYCLES_GT(cycles - msh2.m68krcycles_done, 64))
  464. p32x_sync_sh2s(cycles);
  465. if (REG8IN16(r, a) != (u8)d) {
  466. REG8IN16(r, a) = d;
  467. p32x_sh2_poll_event(&sh2s[0], SH2_STATE_CPOLL, cycles);
  468. p32x_sh2_poll_event(&sh2s[1], SH2_STATE_CPOLL, cycles);
  469. sh2_poll_write(a & ~1, r[a / 2], cycles, NULL);
  470. }
  471. }
  472. return;
  473. case 0x30:
  474. return;
  475. case 0x31: // PWM control
  476. REG8IN16(r, a) &= ~0x0f;
  477. REG8IN16(r, a) |= d & 0x0f;
  478. d = r[0x30 / 2];
  479. goto pwm_write;
  480. case 0x32: // PWM cycle
  481. REG8IN16(r, a) = d & 0x0f;
  482. d = r[0x32 / 2];
  483. goto pwm_write;
  484. case 0x33:
  485. REG8IN16(r, a) = d;
  486. d = r[0x32 / 2];
  487. goto pwm_write;
  488. // PWM pulse regs.. Only writes to odd address send a value
  489. // to FIFO; reads are 0 (except status bits)
  490. case 0x34:
  491. case 0x36:
  492. case 0x38:
  493. REG8IN16(r, a) = d;
  494. return;
  495. case 0x35:
  496. case 0x37:
  497. case 0x39:
  498. d = (REG8IN16(r, a ^ 1) << 8) | (d & 0xff);
  499. REG8IN16(r, a ^ 1) = 0;
  500. goto pwm_write;
  501. case 0x3a: // ignored, always 0
  502. case 0x3b:
  503. case 0x3c:
  504. case 0x3d:
  505. case 0x3e:
  506. case 0x3f:
  507. return;
  508. pwm_write:
  509. p32x_pwm_write16(a & ~1, d, NULL, SekCyclesDone());
  510. return;
  511. }
  512. }
  513. static void p32x_reg_write16(u32 a, u32 d)
  514. {
  515. u16 *r = Pico32x.regs;
  516. a &= 0x3e;
  517. // for things like bset on comm port
  518. m68k_poll.cnt = 0;
  519. switch (a/2) {
  520. case 0x00/2: // adapter ctl
  521. if ((d ^ r[0]) & d & P32XS_nRES)
  522. p32x_reset_sh2s();
  523. r[0] &= ~(P32XS_FM|P32XS_nRES|P32XS_ADEN);
  524. r[0] |= d & (P32XS_FM|P32XS_nRES|P32XS_ADEN);
  525. return;
  526. case 0x08/2: // DREQ src
  527. r[a / 2] = d & 0xff;
  528. return;
  529. case 0x0a/2:
  530. r[a / 2] = d & ~1;
  531. return;
  532. case 0x0c/2: // DREQ dest
  533. r[a / 2] = d & 0xff;
  534. return;
  535. case 0x0e/2:
  536. r[a / 2] = d;
  537. return;
  538. case 0x10/2: // DREQ len
  539. r[a / 2] = d & ~3;
  540. return;
  541. case 0x12/2: // FIFO reg
  542. dreq0_write(r, d);
  543. return;
  544. case 0x1a/2: // TV + mystery bit
  545. r[a / 2] = d & 0x0101;
  546. return;
  547. case 0x20/2: // comm port
  548. case 0x22/2:
  549. case 0x24/2:
  550. case 0x26/2:
  551. case 0x28/2:
  552. case 0x2a/2:
  553. case 0x2c/2:
  554. case 0x2e/2:
  555. { unsigned int cycles = SekCyclesDone();
  556. if (CYCLES_GT(cycles - msh2.m68krcycles_done, 64))
  557. p32x_sync_sh2s(cycles);
  558. if (r[a / 2] != (u16)d) {
  559. r[a / 2] = d;
  560. p32x_sh2_poll_event(&sh2s[0], SH2_STATE_CPOLL, cycles);
  561. p32x_sh2_poll_event(&sh2s[1], SH2_STATE_CPOLL, cycles);
  562. sh2_poll_write(a, (u16)d, cycles, NULL);
  563. }
  564. }
  565. return;
  566. case 0x30/2: // PWM control
  567. d = (r[a / 2] & ~0x0f) | (d & 0x0f);
  568. r[a / 2] = d;
  569. p32x_pwm_write16(a, d, NULL, SekCyclesDone());
  570. return;
  571. case 0x32/2:
  572. case 0x34/2:
  573. case 0x36/2:
  574. case 0x38/2:
  575. case 0x3a/2:
  576. case 0x3c/2:
  577. case 0x3e/2:
  578. p32x_pwm_write16(a, d, NULL, SekCyclesDone());
  579. return;
  580. }
  581. p32x_reg_write8(a + 1, d);
  582. }
  583. // ------------------------------------------------------------------
  584. // VDP regs
  585. static u32 p32x_vdp_read16(u32 a)
  586. {
  587. u32 d;
  588. a &= 0x0e;
  589. d = Pico32x.vdp_regs[a / 2];
  590. if (a == 0x0a) {
  591. // tested: FEN seems to be randomly pulsing on hcnt 0x80-0xf0,
  592. // most often at 0xb1-0xb5, even during vblank,
  593. // what's the deal with that?
  594. // we'll just fake it along with hblank for now
  595. Pico32x.vdp_fbcr_fake++;
  596. if (Pico32x.vdp_fbcr_fake & 4)
  597. d |= P32XV_HBLK;
  598. if ((Pico32x.vdp_fbcr_fake & 7) == 0)
  599. d |= P32XV_nFEN;
  600. }
  601. return d;
  602. }
  603. static void p32x_vdp_write8(u32 a, u32 d)
  604. {
  605. u16 *r = Pico32x.vdp_regs;
  606. a &= 0x0f;
  607. // TODO: verify what's writeable
  608. switch (a) {
  609. case 0x01:
  610. // priority inversion is handled in palette
  611. if ((r[0] ^ d) & P32XV_PRI)
  612. Pico32x.dirty_pal = 1;
  613. r[0] = (r[0] & P32XV_nPAL) | (d & 0xff);
  614. break;
  615. case 0x03: // shift (for pp mode)
  616. r[2 / 2] = d & 1;
  617. break;
  618. case 0x05: // fill len
  619. r[4 / 2] = d & 0xff;
  620. break;
  621. case 0x0b:
  622. d &= 1;
  623. Pico32x.pending_fb = d;
  624. // if we are blanking and FS bit is changing
  625. if (((r[0x0a/2] & P32XV_VBLK) || (r[0] & P32XV_Mx) == 0) && ((r[0x0a/2] ^ d) & P32XV_FS)) {
  626. r[0x0a/2] ^= P32XV_FS;
  627. Pico32xSwapDRAM(d ^ 1);
  628. elprintf(EL_32X, "VDP FS: %d", r[0x0a/2] & P32XV_FS);
  629. }
  630. break;
  631. }
  632. }
  633. static void p32x_vdp_write16(u32 a, u32 d, SH2 *sh2)
  634. {
  635. a &= 0x0e;
  636. if (a == 6) { // fill start
  637. Pico32x.vdp_regs[6 / 2] = d;
  638. return;
  639. }
  640. if (a == 8) { // fill data
  641. u16 *dram = Pico32xMem->dram[(Pico32x.vdp_regs[0x0a/2] & P32XV_FS) ^ 1];
  642. int len = Pico32x.vdp_regs[4 / 2] + 1;
  643. int len1 = len;
  644. a = Pico32x.vdp_regs[6 / 2];
  645. while (len1--) {
  646. dram[a] = d;
  647. a = (a & 0xff00) | ((a + 1) & 0xff);
  648. }
  649. Pico32x.vdp_regs[0x06 / 2] = a;
  650. Pico32x.vdp_regs[0x08 / 2] = d;
  651. if (sh2 != NULL && len > 8) {
  652. Pico32x.vdp_regs[0x0a / 2] |= P32XV_nFEN;
  653. // supposedly takes 3 bus/6 sh2 cycles? or 3 sh2 cycles?
  654. p32x_event_schedule_sh2(sh2, P32X_EVENT_FILLEND, 3 + len);
  655. }
  656. return;
  657. }
  658. p32x_vdp_write8(a | 1, d);
  659. }
  660. // ------------------------------------------------------------------
  661. // SH2 regs
  662. static u32 p32x_sh2reg_read16(u32 a, SH2 *sh2)
  663. {
  664. u16 *r = Pico32x.regs;
  665. unsigned cycles;
  666. a &= 0x3e;
  667. switch (a/2) {
  668. case 0x00/2: // adapter/irq ctl
  669. return (r[0] & P32XS_FM) | Pico32x.sh2_regs[0]
  670. | Pico32x.sh2irq_mask[sh2->is_slave];
  671. case 0x04/2: // H count (often as comm too)
  672. p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 5);
  673. cycles = sh2_cycles_done_m68k(sh2);
  674. sh2s_sync_on_read(sh2, cycles);
  675. return sh2_poll_read(a, Pico32x.sh2_regs[4 / 2], cycles, sh2);
  676. case 0x06/2:
  677. return (r[a / 2] & ~P32XS_FULL) | 0x4000;
  678. case 0x08/2: // DREQ src
  679. case 0x0a/2:
  680. case 0x0c/2: // DREQ dst
  681. case 0x0e/2:
  682. case 0x10/2: // DREQ len
  683. return r[a / 2];
  684. case 0x12/2: // DREQ FIFO - does this work on hw?
  685. if (Pico32x.dmac0_fifo_ptr > 0) {
  686. Pico32x.dmac0_fifo_ptr--;
  687. r[a / 2] = Pico32x.dmac_fifo[0];
  688. memmove(&Pico32x.dmac_fifo[0], &Pico32x.dmac_fifo[1],
  689. Pico32x.dmac0_fifo_ptr * 2);
  690. }
  691. return r[a / 2];
  692. case 0x14/2:
  693. case 0x16/2:
  694. case 0x18/2:
  695. case 0x1a/2:
  696. case 0x1c/2:
  697. return 0; // ?
  698. case 0x20/2: // comm port
  699. case 0x22/2:
  700. case 0x24/2:
  701. case 0x26/2:
  702. case 0x28/2:
  703. case 0x2a/2:
  704. case 0x2c/2:
  705. case 0x2e/2:
  706. p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 5);
  707. cycles = sh2_cycles_done_m68k(sh2);
  708. sh2s_sync_on_read(sh2, cycles);
  709. return sh2_poll_read(a, r[a / 2], cycles, sh2);
  710. case 0x30/2: // PWM
  711. case 0x32/2:
  712. case 0x34/2:
  713. case 0x36/2:
  714. case 0x38/2:
  715. case 0x3a/2:
  716. case 0x3c/2:
  717. case 0x3e/2:
  718. return p32x_pwm_read16(a, sh2, sh2_cycles_done_m68k(sh2));
  719. }
  720. elprintf_sh2(sh2, EL_32X|EL_ANOMALY,
  721. "unhandled sysreg r16 [%02x] @%08x", a, sh2_pc(sh2));
  722. return 0;
  723. }
  724. static void p32x_sh2reg_write8(u32 a, u32 d, SH2 *sh2)
  725. {
  726. u16 *r = Pico32x.regs;
  727. u32 old;
  728. a &= 0x3f;
  729. sh2->poll_cnt = 0;
  730. switch (a) {
  731. case 0x00: // FM
  732. r[0] &= ~P32XS_FM;
  733. r[0] |= (d << 8) & P32XS_FM;
  734. return;
  735. case 0x01: // HEN/irq masks
  736. old = Pico32x.sh2irq_mask[sh2->is_slave];
  737. if ((d ^ old) & 1)
  738. p32x_pwm_sync_to_sh2(sh2);
  739. Pico32x.sh2irq_mask[sh2->is_slave] = d & 0x0f;
  740. Pico32x.sh2_regs[0] &= ~0x80;
  741. Pico32x.sh2_regs[0] |= d & 0x80;
  742. if ((d ^ old) & 1)
  743. p32x_pwm_schedule_sh2(sh2);
  744. if ((old ^ d) & 2)
  745. p32x_update_cmd_irq(sh2, 0);
  746. if ((old ^ d) & 4)
  747. p32x_schedule_hint(sh2, 0);
  748. return;
  749. case 0x04: // ignored?
  750. return;
  751. case 0x05: // H count
  752. d &= 0xff;
  753. if (Pico32x.sh2_regs[4 / 2] != (u8)d) {
  754. unsigned int cycles = sh2_cycles_done_m68k(sh2);
  755. Pico32x.sh2_regs[4 / 2] = d;
  756. p32x_sh2_poll_event(sh2->other_sh2, SH2_STATE_CPOLL, cycles);
  757. if (p32x_sh2_ready(sh2->other_sh2, cycles+8))
  758. sh2_end_run(sh2, 4);
  759. sh2_poll_write(a & ~1, d, cycles, sh2);
  760. }
  761. return;
  762. case 0x20: // comm port
  763. case 0x21:
  764. case 0x22:
  765. case 0x23:
  766. case 0x24:
  767. case 0x25:
  768. case 0x26:
  769. case 0x27:
  770. case 0x28:
  771. case 0x29:
  772. case 0x2a:
  773. case 0x2b:
  774. case 0x2c:
  775. case 0x2d:
  776. case 0x2e:
  777. case 0x2f:
  778. if (REG8IN16(r, a) != (u8)d) {
  779. unsigned int cycles = sh2_cycles_done_m68k(sh2);
  780. REG8IN16(r, a) = d;
  781. p32x_m68k_poll_event(P32XF_68KCPOLL);
  782. p32x_sh2_poll_event(sh2->other_sh2, SH2_STATE_CPOLL, cycles);
  783. if (p32x_sh2_ready(sh2->other_sh2, cycles+8))
  784. sh2_end_run(sh2, 0);
  785. sh2_poll_write(a & ~1, r[a / 2], cycles, sh2);
  786. }
  787. return;
  788. case 0x30:
  789. REG8IN16(r, a) = d & 0x0f;
  790. d = r[0x30 / 2];
  791. goto pwm_write;
  792. case 0x31: // PWM control
  793. REG8IN16(r, a) = d & 0x8f;
  794. d = r[0x30 / 2];
  795. goto pwm_write;
  796. case 0x32: // PWM cycle
  797. REG8IN16(r, a) = d & 0x0f;
  798. d = r[0x32 / 2];
  799. goto pwm_write;
  800. case 0x33:
  801. REG8IN16(r, a) = d;
  802. d = r[0x32 / 2];
  803. goto pwm_write;
  804. // PWM pulse regs.. Only writes to odd address send a value
  805. // to FIFO; reads are 0 (except status bits)
  806. case 0x34:
  807. case 0x36:
  808. case 0x38:
  809. REG8IN16(r, a) = d;
  810. return;
  811. case 0x35:
  812. case 0x37:
  813. case 0x39:
  814. d = (REG8IN16(r, a ^ 1) << 8) | (d & 0xff);
  815. REG8IN16(r, a ^ 1) = 0;
  816. goto pwm_write;
  817. case 0x3a: // ignored, always 0?
  818. case 0x3b:
  819. case 0x3c:
  820. case 0x3d:
  821. case 0x3e:
  822. case 0x3f:
  823. return;
  824. pwm_write:
  825. p32x_pwm_write16(a & ~1, d, sh2, sh2_cycles_done_m68k(sh2));
  826. return;
  827. }
  828. elprintf(EL_32X|EL_ANOMALY,
  829. "unhandled sysreg w8 [%02x] %02x @%08x", a, d, sh2_pc(sh2));
  830. }
  831. static void p32x_sh2reg_write16(u32 a, u32 d, SH2 *sh2)
  832. {
  833. a &= 0x3e;
  834. sh2->poll_cnt = 0;
  835. switch (a/2) {
  836. case 0x00/2: // FM
  837. Pico32x.regs[0] &= ~P32XS_FM;
  838. Pico32x.regs[0] |= d & P32XS_FM;
  839. break;
  840. case 0x14/2:
  841. Pico32x.sh2irqs &= ~P32XI_VRES;
  842. goto irls;
  843. case 0x16/2:
  844. Pico32x.sh2irqi[sh2->is_slave] &= ~P32XI_VINT;
  845. goto irls;
  846. case 0x18/2:
  847. Pico32x.sh2irqi[sh2->is_slave] &= ~P32XI_HINT;
  848. goto irls;
  849. case 0x1a/2:
  850. Pico32x.regs[2 / 2] &= ~(1 << sh2->is_slave);
  851. p32x_update_cmd_irq(sh2, 0);
  852. return;
  853. case 0x1c/2:
  854. p32x_pwm_sync_to_sh2(sh2);
  855. Pico32x.sh2irqi[sh2->is_slave] &= ~P32XI_PWM;
  856. p32x_pwm_schedule_sh2(sh2);
  857. goto irls;
  858. case 0x20/2: // comm port
  859. case 0x22/2:
  860. case 0x24/2:
  861. case 0x26/2:
  862. case 0x28/2:
  863. case 0x2a/2:
  864. case 0x2c/2:
  865. case 0x2e/2:
  866. if (Pico32x.regs[a / 2] != (u16)d) {
  867. unsigned int cycles = sh2_cycles_done_m68k(sh2);
  868. Pico32x.regs[a / 2] = d;
  869. p32x_m68k_poll_event(P32XF_68KCPOLL);
  870. p32x_sh2_poll_event(sh2->other_sh2, SH2_STATE_CPOLL, cycles);
  871. if (p32x_sh2_ready(sh2->other_sh2, cycles+8))
  872. sh2_end_run(sh2, 0);
  873. sh2_poll_write(a, d, cycles, sh2);
  874. }
  875. return;
  876. case 0x30/2: // PWM
  877. case 0x32/2:
  878. case 0x34/2:
  879. case 0x36/2:
  880. case 0x38/2:
  881. case 0x3a/2:
  882. case 0x3c/2:
  883. case 0x3e/2:
  884. p32x_pwm_write16(a, d, sh2, sh2_cycles_done_m68k(sh2));
  885. return;
  886. }
  887. p32x_sh2reg_write8(a | 1, d, sh2);
  888. return;
  889. irls:
  890. p32x_update_irls(sh2, 0);
  891. }
  892. // ------------------------------------------------------------------
  893. // 32x 68k handlers
  894. // after ADEN
  895. static u32 PicoRead8_32x_on(u32 a)
  896. {
  897. u32 d = 0;
  898. if ((a & 0xffc0) == 0x5100) { // a15100
  899. d = p32x_reg_read16(a);
  900. goto out_16to8;
  901. }
  902. if ((a & 0xfc00) != 0x5000) {
  903. if (PicoIn.AHW & PAHW_MCD)
  904. return PicoRead8_mcd_io(a);
  905. else
  906. return PicoRead8_io(a);
  907. }
  908. if ((a & 0xfff0) == 0x5180) { // a15180
  909. d = p32x_vdp_read16(a);
  910. goto out_16to8;
  911. }
  912. if ((a & 0xfe00) == 0x5200) { // a15200
  913. d = Pico32xMem->pal[(a & 0x1ff) / 2];
  914. goto out_16to8;
  915. }
  916. if ((a & 0xfffc) == 0x30ec) { // a130ec
  917. d = str_mars[a & 3];
  918. goto out;
  919. }
  920. elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc);
  921. return d;
  922. out_16to8:
  923. if (a & 1)
  924. d &= 0xff;
  925. else
  926. d >>= 8;
  927. out:
  928. elprintf(EL_32X, "m68k 32x r8 [%06x] %02x @%06x", a, d, SekPc);
  929. return d;
  930. }
  931. static u32 PicoRead16_32x_on(u32 a)
  932. {
  933. u32 d = 0;
  934. if ((a & 0xffc0) == 0x5100) { // a15100
  935. d = p32x_reg_read16(a);
  936. goto out;
  937. }
  938. if ((a & 0xfc00) != 0x5000) {
  939. if (PicoIn.AHW & PAHW_MCD)
  940. return PicoRead16_mcd_io(a);
  941. else
  942. return PicoRead16_io(a);
  943. }
  944. if ((a & 0xfff0) == 0x5180) { // a15180
  945. d = p32x_vdp_read16(a);
  946. goto out;
  947. }
  948. if ((a & 0xfe00) == 0x5200) { // a15200
  949. d = Pico32xMem->pal[(a & 0x1ff) / 2];
  950. goto out;
  951. }
  952. if ((a & 0xfffc) == 0x30ec) { // a130ec
  953. d = !(a & 2) ? ('M'<<8)|'A' : ('R'<<8)|'S';
  954. goto out;
  955. }
  956. elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc);
  957. return d;
  958. out:
  959. elprintf(EL_32X, "m68k 32x r16 [%06x] %04x @%06x", a, d, SekPc);
  960. return d;
  961. }
  962. static void PicoWrite8_32x_on(u32 a, u32 d)
  963. {
  964. if ((a & 0xfc00) == 0x5000)
  965. elprintf(EL_32X, "m68k 32x w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
  966. if ((a & 0xffc0) == 0x5100) { // a15100
  967. p32x_reg_write8(a, d);
  968. return;
  969. }
  970. if ((a & 0xfc00) != 0x5000) {
  971. m68k_write8_io(a, d);
  972. return;
  973. }
  974. if (!(Pico32x.regs[0] & P32XS_FM)) {
  975. if ((a & 0xfff0) == 0x5180) { // a15180
  976. p32x_vdp_write8(a, d);
  977. return;
  978. }
  979. // TODO: verify
  980. if ((a & 0xfe00) == 0x5200) { // a15200
  981. elprintf(EL_32X|EL_ANOMALY, "m68k 32x PAL w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
  982. ((u8 *)Pico32xMem->pal)[MEM_BE2(a & 0x1ff)] = d;
  983. Pico32x.dirty_pal = 1;
  984. return;
  985. }
  986. }
  987. elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
  988. }
  989. static void PicoWrite8_32x_on_io(u32 a, u32 d)
  990. {
  991. PicoWrite8_io(a, d);
  992. if (a == 0xa130f1)
  993. bank_switch_rom_68k(Pico32x.regs[4 / 2]);
  994. }
  995. static void PicoWrite8_32x_on_io_cd(u32 a, u32 d)
  996. {
  997. PicoWrite8_mcd_io(a, d);
  998. if (a == 0xa130f1)
  999. bank_switch_rom_68k(Pico32x.regs[4 / 2]);
  1000. }
  1001. static void PicoWrite8_32x_on_io_ssf2(u32 a, u32 d)
  1002. {
  1003. carthw_ssf2_write8(a, d);
  1004. if ((a & ~0x0e) == 0xa130f1)
  1005. bank_switch_rom_68k(Pico32x.regs[4 / 2]);
  1006. }
  1007. static void PicoWrite16_32x_on(u32 a, u32 d)
  1008. {
  1009. if ((a & 0xfc00) == 0x5000)
  1010. elprintf(EL_32X, "m68k 32x w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
  1011. if ((a & 0xffc0) == 0x5100) { // a15100
  1012. p32x_reg_write16(a, d);
  1013. return;
  1014. }
  1015. if ((a & 0xfc00) != 0x5000) {
  1016. m68k_write16_io(a, d);
  1017. return;
  1018. }
  1019. if (!(Pico32x.regs[0] & P32XS_FM)) {
  1020. if ((a & 0xfff0) == 0x5180) { // a15180
  1021. p32x_vdp_write16(a, d, NULL); // FIXME?
  1022. return;
  1023. }
  1024. if ((a & 0xfe00) == 0x5200) { // a15200
  1025. Pico32xMem->pal[(a & 0x1ff) / 2] = d;
  1026. Pico32x.dirty_pal = 1;
  1027. return;
  1028. }
  1029. }
  1030. elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
  1031. }
  1032. static void PicoWrite16_32x_on_io(u32 a, u32 d)
  1033. {
  1034. PicoWrite16_io(a, d);
  1035. if (a == 0xa130f0)
  1036. bank_switch_rom_68k(Pico32x.regs[4 / 2]);
  1037. }
  1038. static void PicoWrite16_32x_on_io_cd(u32 a, u32 d)
  1039. {
  1040. PicoWrite16_mcd_io(a, d);
  1041. if (a == 0xa130f0)
  1042. bank_switch_rom_68k(Pico32x.regs[4 / 2]);
  1043. }
  1044. static void PicoWrite16_32x_on_io_ssf2(u32 a, u32 d)
  1045. {
  1046. PicoWrite16_io(a, d);
  1047. if ((a & ~0x0f) == 0xa130f0) {
  1048. carthw_ssf2_write8(a + 1, d);
  1049. bank_switch_rom_68k(Pico32x.regs[4 / 2]);
  1050. }
  1051. }
  1052. // before ADEN
  1053. u32 PicoRead8_32x(u32 a)
  1054. {
  1055. u32 d = 0;
  1056. if (PicoIn.opt & POPT_EN_32X) {
  1057. if ((a & 0xffc0) == 0x5100) { // a15100
  1058. // regs are always readable
  1059. d = ((u8 *)Pico32x.regs)[MEM_BE2(a & 0x3f)];
  1060. goto out;
  1061. }
  1062. if ((a & 0xfffc) == 0x30ec) { // a130ec
  1063. d = str_mars[a & 3];
  1064. goto out;
  1065. }
  1066. }
  1067. elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc);
  1068. return d;
  1069. out:
  1070. elprintf(EL_32X, "m68k 32x r8 [%06x] %02x @%06x", a, d, SekPc);
  1071. return d;
  1072. }
  1073. u32 PicoRead16_32x(u32 a)
  1074. {
  1075. u32 d = 0;
  1076. if (PicoIn.opt & POPT_EN_32X) {
  1077. if ((a & 0xffc0) == 0x5100) { // a15100
  1078. d = Pico32x.regs[(a & 0x3f) / 2];
  1079. goto out;
  1080. }
  1081. if ((a & 0xfffc) == 0x30ec) { // a130ec
  1082. d = !(a & 2) ? ('M'<<8)|'A' : ('R'<<8)|'S';
  1083. goto out;
  1084. }
  1085. }
  1086. elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc);
  1087. return d;
  1088. out:
  1089. elprintf(EL_32X, "m68k 32x r16 [%06x] %04x @%06x", a, d, SekPc);
  1090. return d;
  1091. }
  1092. void PicoWrite8_32x(u32 a, u32 d)
  1093. {
  1094. if ((PicoIn.opt & POPT_EN_32X) && (a & 0xffc0) == 0x5100) // a15100
  1095. {
  1096. u16 *r = Pico32x.regs;
  1097. elprintf(EL_32X, "m68k 32x w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
  1098. a &= 0x3f;
  1099. if (a == 1) {
  1100. if ((d ^ r[0]) & d & P32XS_ADEN) {
  1101. Pico32xStartup();
  1102. r[0] &= ~P32XS_nRES; // causes reset if specified by this write
  1103. r[0] |= P32XS_ADEN;
  1104. p32x_reg_write8(a, d); // forward for reset processing
  1105. }
  1106. return;
  1107. }
  1108. // allow only COMM for now
  1109. if ((a & 0x30) == 0x20) {
  1110. u8 *r8 = (u8 *)r;
  1111. r8[MEM_BE2(a)] = d;
  1112. }
  1113. return;
  1114. }
  1115. elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
  1116. }
  1117. void PicoWrite16_32x(u32 a, u32 d)
  1118. {
  1119. if ((PicoIn.opt & POPT_EN_32X) && (a & 0xffc0) == 0x5100) // a15100
  1120. {
  1121. u16 *r = Pico32x.regs;
  1122. elprintf(EL_UIO, "m68k 32x w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
  1123. a &= 0x3e;
  1124. if (a == 0) {
  1125. if ((d ^ r[0]) & d & P32XS_ADEN) {
  1126. Pico32xStartup();
  1127. r[0] &= ~P32XS_nRES; // causes reset if specified by this write
  1128. r[0] |= P32XS_ADEN;
  1129. p32x_reg_write16(a, d); // forward for reset processing
  1130. }
  1131. return;
  1132. }
  1133. // allow only COMM for now
  1134. if ((a & 0x30) == 0x20)
  1135. r[a / 2] = d;
  1136. return;
  1137. }
  1138. elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
  1139. }
  1140. /* quirk: in both normal and overwrite areas only nonzero values go through */
  1141. #define sh2_write8_dramN(p, a, d) \
  1142. if ((d & 0xff) != 0) { \
  1143. u8 *dram = (u8 *)p; \
  1144. dram[MEM_BE2(a & 0x1ffff)] = d; \
  1145. }
  1146. static void m68k_write8_dram0_ow(u32 a, u32 d)
  1147. {
  1148. sh2_write8_dramN(Pico32xMem->dram[0], a, d);
  1149. }
  1150. static void m68k_write8_dram1_ow(u32 a, u32 d)
  1151. {
  1152. sh2_write8_dramN(Pico32xMem->dram[1], a, d);
  1153. }
  1154. #define sh2_write16_dramN(p, a, d) \
  1155. u16 *pd = &((u16 *)p)[(a & 0x1ffff) / 2]; \
  1156. if (!(a & 0x20000)) { \
  1157. *pd = d; \
  1158. } else { \
  1159. u16 v = *pd; /* overwrite */ \
  1160. if (!(d & 0x00ff)) d |= v & 0x00ff; \
  1161. if (!(d & 0xff00)) d |= v & 0xff00; \
  1162. *pd = d; \
  1163. }
  1164. static void m68k_write16_dram0_ow(u32 a, u32 d)
  1165. {
  1166. sh2_write16_dramN(Pico32xMem->dram[0], a, d);
  1167. }
  1168. static void m68k_write16_dram1_ow(u32 a, u32 d)
  1169. {
  1170. sh2_write16_dramN(Pico32xMem->dram[1], a, d);
  1171. }
  1172. // -----------------------------------------------------------------
  1173. // hint vector is writeable
  1174. static void PicoWrite8_hint(u32 a, u32 d)
  1175. {
  1176. if ((a & 0xfffc) == 0x0070) {
  1177. Pico32xMem->m68k_rom[MEM_BE2(a)] = d;
  1178. return;
  1179. }
  1180. elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x",
  1181. a, d & 0xff, SekPc);
  1182. }
  1183. static void PicoWrite16_hint(u32 a, u32 d)
  1184. {
  1185. if ((a & 0xfffc) == 0x0070) {
  1186. ((u16 *)Pico32xMem->m68k_rom)[a/2] = d;
  1187. return;
  1188. }
  1189. elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x",
  1190. a, d & 0xffff, SekPc);
  1191. }
  1192. // normally not writable, but somebody could make a RAM cart
  1193. static void PicoWrite8_cart(u32 a, u32 d)
  1194. {
  1195. elprintf(EL_UIO, "m68k w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
  1196. a &= 0xfffff;
  1197. m68k_write8(a, d);
  1198. }
  1199. static void PicoWrite16_cart(u32 a, u32 d)
  1200. {
  1201. elprintf(EL_UIO, "m68k w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
  1202. a &= 0xfffff;
  1203. m68k_write16(a, d);
  1204. }
  1205. // same with bank, but save ram is sometimes here
  1206. static u32 PicoRead8_bank(u32 a)
  1207. {
  1208. a = (Pico32x.regs[4 / 2] << 20) | (a & 0xfffff);
  1209. return m68k_read8(a);
  1210. }
  1211. static u32 PicoRead16_bank(u32 a)
  1212. {
  1213. a = (Pico32x.regs[4 / 2] << 20) | (a & 0xfffff);
  1214. return m68k_read16(a);
  1215. }
  1216. static void PicoWrite8_bank(u32 a, u32 d)
  1217. {
  1218. if (!(Pico.m.sram_reg & SRR_MAPPED))
  1219. elprintf(EL_UIO, "m68k w8 [%06x] %02x @%06x",
  1220. a, d & 0xff, SekPc);
  1221. a = (Pico32x.regs[4 / 2] << 20) | (a & 0xfffff);
  1222. m68k_write8(a, d);
  1223. }
  1224. static void PicoWrite16_bank(u32 a, u32 d)
  1225. {
  1226. if (!(Pico.m.sram_reg & SRR_MAPPED))
  1227. elprintf(EL_UIO, "m68k w16 [%06x] %04x @%06x",
  1228. a, d & 0xffff, SekPc);
  1229. a = (Pico32x.regs[4 / 2] << 20) | (a & 0xfffff);
  1230. m68k_write16(a, d);
  1231. }
  1232. static void bank_map_handler(void)
  1233. {
  1234. cpu68k_map_set(m68k_read8_map, 0x900000, 0x9fffff, PicoRead8_bank, 1);
  1235. cpu68k_map_set(m68k_read16_map, 0x900000, 0x9fffff, PicoRead16_bank, 1);
  1236. }
  1237. static void bank_switch_rom_68k(int b)
  1238. {
  1239. unsigned int rs, bank, bank2;
  1240. if (Pico.m.ncart_in)
  1241. return;
  1242. bank = b << 20;
  1243. if ((Pico.m.sram_reg & SRR_MAPPED) && bank == Pico.sv.start) {
  1244. bank_map_handler();
  1245. return;
  1246. }
  1247. if (bank >= Pico.romsize) {
  1248. elprintf(EL_32X|EL_ANOMALY, "missing bank @ %06x", bank);
  1249. bank_map_handler();
  1250. return;
  1251. }
  1252. // 32X ROM (XXX: consider mirroring?)
  1253. rs = (Pico.romsize + M68K_BANK_MASK) & ~M68K_BANK_MASK;
  1254. if (!carthw_ssf2_active) {
  1255. rs -= bank;
  1256. if (rs > 0x100000)
  1257. rs = 0x100000;
  1258. cpu68k_map_set(m68k_read8_map, 0x900000, 0x900000 + rs - 1, Pico.rom + bank, 0);
  1259. cpu68k_map_set(m68k_read16_map, 0x900000, 0x900000 + rs - 1, Pico.rom + bank, 0);
  1260. elprintf(EL_32X, "bank %06x-%06x -> %06x", 0x900000, 0x900000 + rs - 1, bank);
  1261. }
  1262. else {
  1263. bank = bank >> 19;
  1264. bank2 = carthw_ssf2_banks[bank + 0] << 19;
  1265. cpu68k_map_set(m68k_read8_map, 0x900000, 0x97ffff, Pico.rom + bank2, 0);
  1266. cpu68k_map_set(m68k_read16_map, 0x900000, 0x97ffff, Pico.rom + bank2, 0);
  1267. bank2 = carthw_ssf2_banks[bank + 1] << 19;
  1268. cpu68k_map_set(m68k_read8_map, 0x980000, 0x9fffff, Pico.rom + bank2, 0);
  1269. cpu68k_map_set(m68k_read16_map, 0x980000, 0x9fffff, Pico.rom + bank2, 0);
  1270. }
  1271. }
  1272. // -----------------------------------------------------------------
  1273. // SH2
  1274. // -----------------------------------------------------------------
  1275. // read8
  1276. static REGPARM(2) u32 sh2_read8_unmapped(u32 a, SH2 *sh2)
  1277. {
  1278. elprintf_sh2(sh2, EL_32X, "unmapped r8 [%08x] %02x @%06x",
  1279. a, 0, sh2_pc(sh2));
  1280. return 0;
  1281. }
  1282. static u32 REGPARM(2) sh2_read8_cs0(u32 a, SH2 *sh2)
  1283. {
  1284. u32 d = 0;
  1285. DRC_SAVE_SR(sh2);
  1286. sh2_burn_cycles(sh2, 1*2);
  1287. // 0x3ffc0 is verified
  1288. if ((a & 0x3ffc0) == 0x4000) {
  1289. d = p32x_sh2reg_read16(a, sh2);
  1290. goto out_16to8;
  1291. }
  1292. if ((a & 0x3fff0) == 0x4100) {
  1293. d = p32x_vdp_read16(a);
  1294. p32x_sh2_poll_detect(a, sh2, SH2_STATE_VPOLL, 7);
  1295. goto out_16to8;
  1296. }
  1297. if ((a & 0x3fe00) == 0x4200) {
  1298. d = Pico32xMem->pal[(a & 0x1ff) / 2];
  1299. goto out_16to8;
  1300. }
  1301. // TODO: mirroring?
  1302. if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
  1303. d = Pico32xMem->sh2_rom_m.b[MEM_BE2(a)];
  1304. else if (sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_s))
  1305. d = Pico32xMem->sh2_rom_s.b[MEM_BE2(a)];
  1306. else
  1307. d = sh2_read8_unmapped(a, sh2);
  1308. goto out;
  1309. out_16to8:
  1310. if (a & 1)
  1311. d &= 0xff;
  1312. else
  1313. d >>= 8;
  1314. out:
  1315. elprintf_sh2(sh2, EL_32X, "r8 [%08x] %02x @%06x",
  1316. a, d, sh2_pc(sh2));
  1317. DRC_RESTORE_SR(sh2);
  1318. return (s8)d;
  1319. }
  1320. // for ssf2
  1321. static u32 REGPARM(2) sh2_read8_rom(u32 a, SH2 *sh2)
  1322. {
  1323. u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
  1324. s8 *p = sh2->p_rom;
  1325. return p[MEM_BE2(bank + (a & 0x7ffff))];
  1326. }
  1327. // read16
  1328. static u32 REGPARM(2) sh2_read16_unmapped(u32 a, SH2 *sh2)
  1329. {
  1330. elprintf_sh2(sh2, EL_32X, "unmapped r16 [%08x] %04x @%06x",
  1331. a, 0, sh2_pc(sh2));
  1332. return 0;
  1333. }
  1334. static u32 REGPARM(2) sh2_read16_cs0(u32 a, SH2 *sh2)
  1335. {
  1336. u32 d = 0;
  1337. DRC_SAVE_SR(sh2);
  1338. sh2_burn_cycles(sh2, 1*2);
  1339. if ((a & 0x3ffc0) == 0x4000) {
  1340. d = p32x_sh2reg_read16(a, sh2);
  1341. if (!(EL_LOGMASK & EL_PWM) && (a & 0x30) == 0x30) // hide PWM
  1342. goto out_noprint;
  1343. goto out;
  1344. }
  1345. if ((a & 0x3fff0) == 0x4100) {
  1346. d = p32x_vdp_read16(a);
  1347. p32x_sh2_poll_detect(a, sh2, SH2_STATE_VPOLL, 7);
  1348. goto out;
  1349. }
  1350. if ((a & 0x3fe00) == 0x4200) {
  1351. d = Pico32xMem->pal[(a & 0x1ff) / 2];
  1352. goto out;
  1353. }
  1354. if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
  1355. d = Pico32xMem->sh2_rom_m.w[a / 2];
  1356. else if (sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_s))
  1357. d = Pico32xMem->sh2_rom_s.w[a / 2];
  1358. else
  1359. d = sh2_read16_unmapped(a, sh2);
  1360. out:
  1361. elprintf_sh2(sh2, EL_32X, "r16 [%08x] %04x @%06x",
  1362. a, d, sh2_pc(sh2));
  1363. out_noprint:
  1364. DRC_RESTORE_SR(sh2);
  1365. return (s16)d;
  1366. }
  1367. static u32 REGPARM(2) sh2_read16_rom(u32 a, SH2 *sh2)
  1368. {
  1369. u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
  1370. s16 *p = sh2->p_rom;
  1371. return p[(bank + (a & 0x7fffe)) / 2];
  1372. }
  1373. static u32 REGPARM(2) sh2_read32_unmapped(u32 a, SH2 *sh2)
  1374. {
  1375. elprintf_sh2(sh2, EL_32X, "unmapped r32 [%08x] %08x @%06x",
  1376. a, 0, sh2_pc(sh2));
  1377. return 0;
  1378. }
  1379. static u32 REGPARM(2) sh2_read32_cs0(u32 a, SH2 *sh2)
  1380. {
  1381. u32 d1 = sh2_read16_cs0(a, sh2) << 16, d2 = sh2_read16_cs0(a + 2, sh2) << 16;
  1382. return d1 | (d2 >> 16);
  1383. }
  1384. static u32 REGPARM(2) sh2_read32_rom(u32 a, SH2 *sh2)
  1385. {
  1386. u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
  1387. u32 *p = sh2->p_rom;
  1388. u32 d = p[(bank + (a & 0x7fffc)) / 4];
  1389. return CPU_BE2(d);
  1390. }
  1391. // writes
  1392. #ifdef DRC_SH2
  1393. static void sh2_sdram_poll(u32 a, u32 d, SH2 *sh2)
  1394. {
  1395. unsigned cycles;
  1396. DRC_SAVE_SR(sh2);
  1397. cycles = sh2_cycles_done_m68k(sh2);
  1398. sh2_poll_write(a, d, cycles, sh2);
  1399. p32x_sh2_poll_event(sh2->other_sh2, SH2_STATE_RPOLL, cycles);
  1400. if (p32x_sh2_ready(sh2->other_sh2, cycles+8))
  1401. sh2_end_run(sh2, 0);
  1402. DRC_RESTORE_SR(sh2);
  1403. }
  1404. void NOINLINE sh2_sdram_checks(u32 a, u32 d, SH2 *sh2, u32 t)
  1405. {
  1406. if (t & 0x80) sh2_sdram_poll(a, d, sh2);
  1407. if (t & 0x7f) sh2_drc_wcheck_ram(a, 2, sh2);
  1408. }
  1409. void NOINLINE sh2_sdram_checks_l(u32 a, u32 d, SH2 *sh2, u32 t)
  1410. {
  1411. if (t & 0x000080) sh2_sdram_poll(a, d>>16, sh2);
  1412. if (t & 0x800000) sh2_sdram_poll(a+2, d, sh2);
  1413. if (t & ~0x800080) sh2_drc_wcheck_ram(a, 4, sh2);
  1414. }
  1415. #ifndef _ASM_32X_MEMORY_C
  1416. static void sh2_da_checks(u32 a, u32 t, SH2 *sh2)
  1417. {
  1418. sh2_drc_wcheck_da(a, 2, sh2);
  1419. }
  1420. static void sh2_da_checks_l(u32 a, u32 t, SH2 *sh2)
  1421. {
  1422. sh2_drc_wcheck_da(a, 4, sh2);
  1423. }
  1424. #endif
  1425. #endif
  1426. static void REGPARM(3) sh2_write_ignore(u32 a, u32 d, SH2 *sh2)
  1427. {
  1428. }
  1429. // write8
  1430. static void REGPARM(3) sh2_write8_unmapped(u32 a, u32 d, SH2 *sh2)
  1431. {
  1432. elprintf_sh2(sh2, EL_32X, "unmapped w8 [%08x] %02x @%06x",
  1433. a, d & 0xff, sh2_pc(sh2));
  1434. }
  1435. static void REGPARM(3) sh2_write8_cs0(u32 a, u32 d, SH2 *sh2)
  1436. {
  1437. DRC_SAVE_SR(sh2);
  1438. elprintf_sh2(sh2, EL_32X, "w8 [%08x] %02x @%06x",
  1439. a, d & 0xff, sh2_pc(sh2));
  1440. if ((a & 0x3ffc0) == 0x4000) {
  1441. p32x_sh2reg_write8(a, d, sh2);
  1442. goto out;
  1443. }
  1444. if (Pico32x.regs[0] & P32XS_FM) {
  1445. if ((a & 0x3fff0) == 0x4100) {
  1446. sh2->poll_cnt = 0;
  1447. p32x_vdp_write8(a, d);
  1448. goto out;
  1449. }
  1450. if ((a & 0x3fe00) == 0x4200) {
  1451. sh2->poll_cnt = 0;
  1452. ((u8 *)Pico32xMem->pal)[MEM_BE2(a & 0x1ff)] = d;
  1453. Pico32x.dirty_pal = 1;
  1454. goto out;
  1455. }
  1456. }
  1457. sh2_write8_unmapped(a, d, sh2);
  1458. out:
  1459. DRC_RESTORE_SR(sh2);
  1460. }
  1461. #ifdef _ASM_32X_MEMORY_C
  1462. extern void REGPARM(3) sh2_write8_dram(u32 a, u32 d, SH2 *sh2);
  1463. extern void REGPARM(3) sh2_write8_sdram(u32 a, u32 d, SH2 *sh2);
  1464. extern void REGPARM(3) sh2_write8_da(u32 a, u32 d, SH2 *sh2);
  1465. #else
  1466. static void REGPARM(3) sh2_write8_dram(u32 a, u32 d, SH2 *sh2)
  1467. {
  1468. sh2_write8_dramN(sh2->p_dram, a, d);
  1469. }
  1470. static void REGPARM(3) sh2_write8_sdram(u32 a, u32 d, SH2 *sh2)
  1471. {
  1472. u32 a1 = MEM_BE2(a & 0x3ffff);
  1473. ((u8 *)sh2->p_sdram)[a1] = d;
  1474. #ifdef DRC_SH2
  1475. u8 *p = sh2->p_drcblk_ram;
  1476. u32 t = p[a1 >> SH2_DRCBLK_RAM_SHIFT];
  1477. if (t)
  1478. sh2_sdram_checks(a & ~1, ((u16 *)sh2->p_sdram)[a1 / 2], sh2, t);
  1479. #endif
  1480. }
  1481. static void REGPARM(3) sh2_write8_da(u32 a, u32 d, SH2 *sh2)
  1482. {
  1483. u32 a1 = MEM_BE2(a & 0xfff);
  1484. sh2->data_array[a1] = d;
  1485. #ifdef DRC_SH2
  1486. u8 *p = sh2->p_drcblk_da;
  1487. u32 t = p[a1 >> SH2_DRCBLK_DA_SHIFT];
  1488. if (t)
  1489. sh2_da_checks(a, t, sh2);
  1490. #endif
  1491. }
  1492. #endif
  1493. static NOINLINE void REGPARM(3) sh2_write8_sdram_sync(u32 a, u32 d, SH2 *sh2)
  1494. {
  1495. DRC_SAVE_SR(sh2);
  1496. sh2_end_run(sh2, 32);
  1497. DRC_RESTORE_SR(sh2);
  1498. sh2_write8_sdram(a, d, sh2);
  1499. }
  1500. static void REGPARM(3) sh2_write8_sdram_wt(u32 a, u32 d, SH2 *sh2)
  1501. {
  1502. // xmen sync hack..
  1503. if ((a << 8) >> 17) // ((a & 0x00ffffff) < 0x200)
  1504. sh2_write8_sdram(a, d, sh2);
  1505. else
  1506. sh2_write8_sdram_sync(a, d, sh2);
  1507. }
  1508. // write16
  1509. static void REGPARM(3) sh2_write16_unmapped(u32 a, u32 d, SH2 *sh2)
  1510. {
  1511. elprintf_sh2(sh2, EL_32X, "unmapped w16 [%08x] %04x @%06x",
  1512. a, d & 0xffff, sh2_pc(sh2));
  1513. }
  1514. static void REGPARM(3) sh2_write16_cs0(u32 a, u32 d, SH2 *sh2)
  1515. {
  1516. DRC_SAVE_SR(sh2);
  1517. if (((EL_LOGMASK & EL_PWM) || (a & 0x30) != 0x30)) // hide PWM
  1518. elprintf_sh2(sh2, EL_32X, "w16 [%08x] %04x @%06x",
  1519. a, d & 0xffff, sh2_pc(sh2));
  1520. if ((a & 0x3ffc0) == 0x4000) {
  1521. p32x_sh2reg_write16(a, d, sh2);
  1522. goto out;
  1523. }
  1524. if (Pico32x.regs[0] & P32XS_FM) {
  1525. if ((a & 0x3fff0) == 0x4100) {
  1526. sh2->poll_cnt = 0;
  1527. p32x_vdp_write16(a, d, sh2);
  1528. goto out;
  1529. }
  1530. if ((a & 0x3fe00) == 0x4200) {
  1531. sh2->poll_cnt = 0;
  1532. Pico32xMem->pal[(a & 0x1ff) / 2] = d;
  1533. Pico32x.dirty_pal = 1;
  1534. goto out;
  1535. }
  1536. }
  1537. sh2_write16_unmapped(a, d, sh2);
  1538. out:
  1539. DRC_RESTORE_SR(sh2);
  1540. }
  1541. #ifdef _ASM_32X_MEMORY_C
  1542. extern void REGPARM(3) sh2_write16_dram(u32 a, u32 d, SH2 *sh2);
  1543. extern void REGPARM(3) sh2_write16_sdram(u32 a, u32 d, SH2 *sh2);
  1544. extern void REGPARM(3) sh2_write16_da(u32 a, u32 d, SH2 *sh2);
  1545. #else
  1546. static void REGPARM(3) sh2_write16_dram(u32 a, u32 d, SH2 *sh2)
  1547. {
  1548. sh2_write16_dramN(sh2->p_dram, a, d);
  1549. }
  1550. static void REGPARM(3) sh2_write16_sdram(u32 a, u32 d, SH2 *sh2)
  1551. {
  1552. u32 a1 = a & 0x3fffe;
  1553. ((u16 *)sh2->p_sdram)[a1 / 2] = d;
  1554. #ifdef DRC_SH2
  1555. u8 *p = sh2->p_drcblk_ram;
  1556. u32 t = p[a1 >> SH2_DRCBLK_RAM_SHIFT];
  1557. if (t)
  1558. sh2_sdram_checks(a, d, sh2, t);
  1559. #endif
  1560. }
  1561. static void REGPARM(3) sh2_write16_da(u32 a, u32 d, SH2 *sh2)
  1562. {
  1563. u32 a1 = a & 0xffe;
  1564. ((u16 *)sh2->data_array)[a1 / 2] = d;
  1565. #ifdef DRC_SH2
  1566. u8 *p = sh2->p_drcblk_da;
  1567. u32 t = p[a1 >> SH2_DRCBLK_DA_SHIFT];
  1568. if (t)
  1569. sh2_da_checks(a, t, sh2);
  1570. #endif
  1571. }
  1572. #endif
  1573. static void REGPARM(3) sh2_write16_rom(u32 a, u32 d, SH2 *sh2)
  1574. {
  1575. u32 a1 = a & 0x3ffffe;
  1576. // tweak for WWF Raw: does writes to ROM area, and it doesn't work without
  1577. // allowing this.
  1578. // Presumably the write goes to the CPU cache and is read back from there,
  1579. // but it would be extremely costly to emulate cache behaviour. Just allow
  1580. // writes to that region, hoping that the original ROM values are never used.
  1581. if ((a1 & 0x3e0000) == 0x3e0000)
  1582. ((u16 *)sh2->p_rom)[a1 / 2] = d;
  1583. else
  1584. sh2_write16_unmapped(a, d, sh2);
  1585. }
  1586. static void REGPARM(3) sh2_write32_unmapped(u32 a, u32 d, SH2 *sh2)
  1587. {
  1588. elprintf_sh2(sh2, EL_32X, "unmapped w32 [%08x] %08x @%06x",
  1589. a, d, sh2_pc(sh2));
  1590. }
  1591. static void REGPARM(3) sh2_write32_cs0(u32 a, u32 d, SH2 *sh2)
  1592. {
  1593. sh2_write16_cs0(a, d >> 16, sh2);
  1594. sh2_write16_cs0(a + 2, d, sh2);
  1595. }
  1596. #define sh2_write32_dramN(p, a, d) \
  1597. u32 *pd = &((u32 *)p)[(a & 0x1ffff) / 4]; \
  1598. if (!(a & 0x20000)) { \
  1599. *pd = CPU_BE2(d); \
  1600. } else { \
  1601. /* overwrite */ \
  1602. u32 v = *pd, m = 0; d = CPU_BE2(d); \
  1603. if (!(d & 0x000000ff)) m |= 0x000000ff; \
  1604. if (!(d & 0x0000ff00)) m |= 0x0000ff00; \
  1605. if (!(d & 0x00ff0000)) m |= 0x00ff0000; \
  1606. if (!(d & 0xff000000)) m |= 0xff000000; \
  1607. *pd = d | (v&m); \
  1608. }
  1609. #ifdef _ASM_32X_MEMORY_C
  1610. extern void REGPARM(3) sh2_write32_dram(u32 a, u32 d, SH2 *sh2);
  1611. extern void REGPARM(3) sh2_write32_sdram(u32 a, u32 d, SH2 *sh2);
  1612. extern void REGPARM(3) sh2_write32_da(u32 a, u32 d, SH2 *sh2);
  1613. #else
  1614. static void REGPARM(3) sh2_write32_dram(u32 a, u32 d, SH2 *sh2)
  1615. {
  1616. sh2_write32_dramN(sh2->p_dram, a, d);
  1617. }
  1618. static void REGPARM(3) sh2_write32_sdram(u32 a, u32 d, SH2 *sh2)
  1619. {
  1620. u32 a1 = a & 0x3fffc;
  1621. *(u32 *)((char*)sh2->p_sdram + a1) = CPU_BE2(d);
  1622. #ifdef DRC_SH2
  1623. u8 *p = sh2->p_drcblk_ram;
  1624. u32 t = p[a1 >> SH2_DRCBLK_RAM_SHIFT];
  1625. u32 u = p[(a1+2) >> SH2_DRCBLK_RAM_SHIFT];
  1626. if (t|(u<<16))
  1627. sh2_sdram_checks_l(a, d, sh2, t|(u<<16));
  1628. #endif
  1629. }
  1630. static void REGPARM(3) sh2_write32_da(u32 a, u32 d, SH2 *sh2)
  1631. {
  1632. u32 a1 = a & 0xffc;
  1633. *((u32 *)sh2->data_array + a1/4) = CPU_BE2(d);
  1634. #ifdef DRC_SH2
  1635. u8 *p = sh2->p_drcblk_da;
  1636. u32 t = p[a1 >> SH2_DRCBLK_DA_SHIFT];
  1637. u32 u = p[(a1+2) >> SH2_DRCBLK_DA_SHIFT];
  1638. if (t|(u<<16))
  1639. sh2_da_checks_l(a, t|(u<<16), sh2);
  1640. #endif
  1641. }
  1642. #endif
  1643. static void REGPARM(3) sh2_write32_rom(u32 a, u32 d, SH2 *sh2)
  1644. {
  1645. sh2_write16_rom(a, d >> 16, sh2);
  1646. sh2_write16_rom(a + 2, d, sh2);
  1647. }
  1648. typedef u32 REGPARM(2) (sh2_read_handler)(u32 a, SH2 *sh2);
  1649. typedef void REGPARM(3) (sh2_write_handler)(u32 a, u32 d, SH2 *sh2);
  1650. #define SH2MAP_ADDR2OFFS_R(a) \
  1651. ((u32)(a) >> SH2_READ_SHIFT)
  1652. #define SH2MAP_ADDR2OFFS_W(a) \
  1653. ((u32)(a) >> SH2_WRITE_SHIFT)
  1654. u32 REGPARM(2) p32x_sh2_read8(u32 a, SH2 *sh2)
  1655. {
  1656. const sh2_memmap *sh2_map = sh2->read8_map;
  1657. uptr p;
  1658. sh2_map += SH2MAP_ADDR2OFFS_R(a);
  1659. p = sh2_map->addr;
  1660. if (!map_flag_set(p))
  1661. return *(s8 *)((p << 1) + MEM_BE2(a & sh2_map->mask));
  1662. else
  1663. return ((sh2_read_handler *)(p << 1))(a, sh2);
  1664. }
  1665. u32 REGPARM(2) p32x_sh2_read16(u32 a, SH2 *sh2)
  1666. {
  1667. const sh2_memmap *sh2_map = sh2->read16_map;
  1668. uptr p;
  1669. sh2_map += SH2MAP_ADDR2OFFS_R(a);
  1670. p = sh2_map->addr;
  1671. if (!map_flag_set(p))
  1672. return *(s16 *)((p << 1) + (a & sh2_map->mask));
  1673. else
  1674. return ((sh2_read_handler *)(p << 1))(a, sh2);
  1675. }
  1676. u32 REGPARM(2) p32x_sh2_read32(u32 a, SH2 *sh2)
  1677. {
  1678. const sh2_memmap *sh2_map = sh2->read32_map;
  1679. uptr p;
  1680. sh2_map += SH2MAP_ADDR2OFFS_R(a);
  1681. p = sh2_map->addr;
  1682. if (!map_flag_set(p)) {
  1683. u32 *pd = (u32 *)((p << 1) + (a & sh2_map->mask));
  1684. return CPU_BE2(*pd);
  1685. } else
  1686. return ((sh2_read_handler *)(p << 1))(a, sh2);
  1687. }
  1688. void REGPARM(3) p32x_sh2_write8(u32 a, u32 d, SH2 *sh2)
  1689. {
  1690. const void **sh2_wmap = sh2->write8_tab;
  1691. sh2_write_handler *wh;
  1692. wh = sh2_wmap[SH2MAP_ADDR2OFFS_W(a)];
  1693. wh(a, d, sh2);
  1694. }
  1695. void REGPARM(3) p32x_sh2_write16(u32 a, u32 d, SH2 *sh2)
  1696. {
  1697. const void **sh2_wmap = sh2->write16_tab;
  1698. sh2_write_handler *wh;
  1699. wh = sh2_wmap[SH2MAP_ADDR2OFFS_W(a)];
  1700. wh(a, d, sh2);
  1701. }
  1702. void REGPARM(3) p32x_sh2_write32(u32 a, u32 d, SH2 *sh2)
  1703. {
  1704. const void **sh2_wmap = sh2->write32_tab;
  1705. sh2_write_handler *wh;
  1706. wh = sh2_wmap[SH2MAP_ADDR2OFFS_W(a)];
  1707. wh(a, d, sh2);
  1708. }
  1709. void *p32x_sh2_get_mem_ptr(u32 a, u32 *mask, SH2 *sh2)
  1710. {
  1711. const sh2_memmap *mm = sh2->read8_map;
  1712. void *ret = (void *)-1;
  1713. mm += SH2MAP_ADDR2OFFS_R(a);
  1714. if (!map_flag_set(mm->addr)) {
  1715. // directly mapped memory (SDRAM, ROM, data array)
  1716. ret = (void *)(mm->addr << 1);
  1717. *mask = mm->mask;
  1718. } else if ((a & ~0x7ff) == 0) {
  1719. // BIOS, has handler function since it shares its segment with I/O
  1720. ret = sh2->p_bios;
  1721. *mask = 0x7ff;
  1722. } else if ((a & 0xc6000000) == 0x02000000) {
  1723. // banked ROM. Return bank address
  1724. u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
  1725. ret = (char*)sh2->p_rom + bank;
  1726. *mask = 0x07ffff;
  1727. }
  1728. return ret;
  1729. }
  1730. int p32x_sh2_memcpy(u32 dst, u32 src, int count, int size, SH2 *sh2)
  1731. {
  1732. u32 mask;
  1733. u8 *ps, *pd;
  1734. int len, i;
  1735. // check if src and dst points to memory (rom/sdram/dram/da)
  1736. if ((pd = p32x_sh2_get_mem_ptr(dst, &mask, sh2)) == (void *)-1)
  1737. return 0;
  1738. if ((ps = p32x_sh2_get_mem_ptr(src, &mask, sh2)) == (void *)-1)
  1739. return 0;
  1740. ps += src & mask;
  1741. len = count * size;
  1742. // DRAM in byte access is always in overwrite mode
  1743. if (pd == sh2->p_dram && size == 1)
  1744. dst |= 0x20000;
  1745. // align dst to halfword
  1746. if (dst & 1) {
  1747. p32x_sh2_write8(dst, *(u8 *)MEM_BE2((uptr)ps), sh2);
  1748. ps++, dst++, len --;
  1749. }
  1750. // copy data
  1751. if ((uptr)ps & 1) {
  1752. // unaligned, use halfword copy mode to reduce memory bandwidth
  1753. u16 *sp = (u16 *)(ps - 1);
  1754. u16 dl, dh = *sp++;
  1755. for (i = 0; i < (len & ~1); i += 2, dst += 2, sp++) {
  1756. dl = dh, dh = *sp;
  1757. p32x_sh2_write16(dst, (dh >> 8) | (dl << 8), sh2);
  1758. }
  1759. if (len & 1)
  1760. p32x_sh2_write8(dst, dh, sh2);
  1761. } else {
  1762. // dst and src at least halfword aligned
  1763. u16 *sp = (u16 *)ps;
  1764. // align dst to word
  1765. if ((dst & 2) && len >= 2) {
  1766. p32x_sh2_write16(dst, *sp++, sh2);
  1767. dst += 2, len -= 2;
  1768. }
  1769. if ((uptr)sp & 2) {
  1770. // halfword copy, using word writes to reduce memory bandwidth
  1771. u16 dl, dh;
  1772. for (i = 0; i < (len & ~3); i += 4, dst += 4, sp += 2) {
  1773. dl = sp[0], dh = sp[1];
  1774. p32x_sh2_write32(dst, (dl << 16) | dh, sh2);
  1775. }
  1776. } else {
  1777. // word copy
  1778. u32 d;
  1779. for (i = 0; i < (len & ~3); i += 4, dst += 4, sp += 2) {
  1780. d = *(u32 *)sp;
  1781. p32x_sh2_write32(dst, CPU_BE2(d), sh2);
  1782. }
  1783. }
  1784. if (len & 2) {
  1785. p32x_sh2_write16(dst, *sp++, sh2);
  1786. dst += 2;
  1787. }
  1788. if (len & 1)
  1789. p32x_sh2_write8(dst, *sp >> 8, sh2);
  1790. }
  1791. return count;
  1792. }
  1793. // -----------------------------------------------------------------
  1794. static void z80_md_bank_write_32x(u32 a, unsigned char d)
  1795. {
  1796. u32 addr68k;
  1797. addr68k = Pico.m.z80_bank68k << 15;
  1798. addr68k += a & 0x7fff;
  1799. if ((addr68k & 0xfff000) == 0xa15000)
  1800. Pico32x.emu_flags |= P32XF_Z80_32X_IO;
  1801. elprintf(EL_Z80BNK, "z80->68k w8 [%06x] %02x", addr68k, d);
  1802. m68k_write8(addr68k, d);
  1803. }
  1804. // -----------------------------------------------------------------
  1805. static const u16 msh2_code[] = {
  1806. // trap instructions
  1807. 0xaffe, // 200 bra <self>
  1808. 0x0009, // 202 nop
  1809. // have to wait a bit until m68k initial program finishes clearing stuff
  1810. // to avoid races with game SH2 code, like in Tempo
  1811. 0xd406, // 204 mov.l @(_m_ok,pc), r4
  1812. 0xc400, // 206 mov.b @(h'0,gbr),r0
  1813. 0xc801, // 208 tst #1, r0
  1814. 0x8b0f, // 20a bf cd_start
  1815. 0xd105, // 20c mov.l @(_cnt,pc), r1
  1816. 0xd206, // 20e mov.l @(_start,pc), r2
  1817. 0x71ff, // 210 add #-1, r1
  1818. 0x4115, // 212 cmp/pl r1
  1819. 0x89fc, // 214 bt -2
  1820. 0x6043, // 216 mov r4, r0
  1821. 0xc208, // 218 mov.l r0, @(h'20,gbr)
  1822. 0x6822, // 21a mov.l @r2, r8
  1823. 0x482b, // 21c jmp @r8
  1824. 0x0009, // 21e nop
  1825. ('M'<<8)|'_', ('O'<<8)|'K', // 220 _m_ok
  1826. 0x0001, 0x0000, // 224 _cnt
  1827. 0x2200, 0x03e0, // master start pointer in ROM
  1828. // cd_start:
  1829. 0xd20d, // 22c mov.l @(__cd_,pc), r2
  1830. 0xc608, // 22e mov.l @(h'20,gbr), r0
  1831. 0x3200, // 230 cmp/eq r0, r2
  1832. 0x8bfc, // 232 bf #-2
  1833. 0xe000, // 234 mov #0, r0
  1834. 0xcf80, // 236 or.b #0x80,@(r0,gbr)
  1835. 0xd80b, // 238 mov.l @(_start_cd,pc), r8 // 24000018
  1836. 0xd30c, // 23a mov.l @(_max_len,pc), r3
  1837. 0x5b84, // 23c mov.l @(h'10,r8), r11 // master vbr
  1838. 0x5a82, // 23e mov.l @(8,r8), r10 // entry
  1839. 0x5081, // 240 mov.l @(4,r8), r0 // len
  1840. 0x5980, // 242 mov.l @(0,r8), r9 // dst
  1841. 0x3036, // 244 cmp/hi r3,r0
  1842. 0x8b00, // 246 bf #1
  1843. 0x6033, // 248 mov r3,r0
  1844. 0x7820, // 24a add #0x20, r8
  1845. // ipl_copy:
  1846. 0x6286, // 24c mov.l @r8+, r2
  1847. 0x2922, // 24e mov.l r2, @r9
  1848. 0x7904, // 250 add #4, r9
  1849. 0x70fc, // 252 add #-4, r0
  1850. 0x8800, // 254 cmp/eq #0, r0
  1851. 0x8bf9, // 256 bf #-5
  1852. //
  1853. 0x4b2e, // 258 ldc r11, vbr
  1854. 0x6043, // 25a mov r4, r0 // M_OK
  1855. 0xc208, // 25c mov.l r0, @(h'20,gbr)
  1856. 0x4a2b, // 25e jmp @r10
  1857. 0x0009, // 260 nop
  1858. 0x0009, // 262 nop // pad
  1859. ('_'<<8)|'C', ('D'<<8)|'_', // 264 __cd_
  1860. 0x2400, 0x0018, // 268 _start_cd
  1861. 0x0001, 0xffe0, // 26c _max_len
  1862. };
  1863. static const u16 ssh2_code[] = {
  1864. 0xaffe, // 200 bra <self>
  1865. 0x0009, // 202 nop
  1866. // code to wait for master, in case authentic master BIOS is used
  1867. 0xd106, // 204 mov.l @(_m_ok,pc), r1
  1868. 0xd208, // 206 mov.l @(_start,pc), r2
  1869. 0xc608, // 208 mov.l @(h'20,gbr), r0
  1870. 0x3100, // 20a cmp/eq r0, r1
  1871. 0x8bfc, // 20c bf #-2
  1872. 0xc400, // 20e mov.b @(h'0,gbr),r0
  1873. 0xc801, // 210 tst #1, r0
  1874. 0xd004, // 212 mov.l @(_s_ok,pc), r0
  1875. 0x8b0a, // 214 bf cd_start
  1876. 0xc209, // 216 mov.l r0, @(h'24,gbr)
  1877. 0x6822, // 218 mov.l @r2, r8
  1878. 0x482b, // 21a jmp @r8
  1879. 0x0009, // 21c nop
  1880. 0x0009, // 21e nop
  1881. ('M'<<8)|'_', ('O'<<8)|'K', // 220
  1882. ('S'<<8)|'_', ('O'<<8)|'K', // 224
  1883. 0x2200, 0x03e4, // slave start pointer in ROM
  1884. // cd_start:
  1885. 0xd803, // 22c mov.l @(_start_cd,pc), r8 // 24000018
  1886. 0x5b85, // 22e mov.l @(h'14,r8), r11 // slave vbr
  1887. 0x5a83, // 230 mov.l @(h'0c,r8), r10 // entry
  1888. 0x4b2e, // 232 ldc r11, vbr
  1889. 0xc209, // 234 mov.l r0, @(h'24,gbr) // write S_OK
  1890. 0x4a2b, // 236 jmp @r10
  1891. 0x0009, // 238 nop
  1892. 0x0009, // 23a nop
  1893. 0x2400, 0x0018, // 23c _start_cd
  1894. };
  1895. static void get_bios(void)
  1896. {
  1897. u16 *ps;
  1898. u32 *pl;
  1899. int i;
  1900. // M68K ROM
  1901. if (p32x_bios_g != NULL) {
  1902. elprintf(EL_STATUS|EL_32X, "32x: using supplied 68k BIOS");
  1903. Byteswap(Pico32xMem->m68k_rom, p32x_bios_g, sizeof(Pico32xMem->m68k_rom));
  1904. }
  1905. else {
  1906. static const u16 andb[] = { 0x0239, 0x00fe, 0x00a1, 0x5107 };
  1907. static const u16 p_d4[] = {
  1908. 0x48e7, 0x8040, // movem.l d0/a1, -(sp)
  1909. 0x227c, 0x00a1, 0x30f1, // movea.l #0xa130f1, a1
  1910. 0x7007, // moveq.l #7, d0
  1911. 0x12d8, //0: move.b (a0)+, (a1)+
  1912. 0x5289, // addq.l #1, a1
  1913. 0x51c8, 0xfffa, // dbra d0, 0b
  1914. 0x0239, 0x00fe, 0x00a1, // and.b #0xfe, (0xa15107).l
  1915. 0x5107,
  1916. 0x4cdf, 0x0201 // movem.l (sp)+, d0/a1
  1917. };
  1918. // generate 68k ROM
  1919. ps = (u16 *)Pico32xMem->m68k_rom;
  1920. pl = (u32 *)ps;
  1921. for (i = 1; i < 0xc0/4; i++)
  1922. pl[i] = CPU_BE2(0x880200 + (i - 1) * 6);
  1923. pl[0x70/4] = 0;
  1924. // fill with nops
  1925. for (i = 0xc0/2; i < 0x100/2; i++)
  1926. ps[i] = 0x4e71;
  1927. // c0: don't need to care about RV - not emulated
  1928. ps[0xc8/2] = 0x1280; // move.b d0, (a1)
  1929. memcpy(ps + 0xca/2, andb, sizeof(andb)); // and.b #0xfe, (a15107)
  1930. ps[0xd2/2] = 0x4e75; // rts
  1931. // d4:
  1932. memcpy(ps + 0xd4/2, p_d4, sizeof(p_d4));
  1933. ps[0xfe/2] = 0x4e75; // rts
  1934. }
  1935. // fill remaining m68k_rom page with game ROM
  1936. memcpy(Pico32xMem->m68k_rom_bank + sizeof(Pico32xMem->m68k_rom),
  1937. Pico.rom + sizeof(Pico32xMem->m68k_rom),
  1938. sizeof(Pico32xMem->m68k_rom_bank) - sizeof(Pico32xMem->m68k_rom));
  1939. // MSH2
  1940. if (p32x_bios_m != NULL) {
  1941. elprintf(EL_STATUS|EL_32X, "32x: using supplied master SH2 BIOS");
  1942. Byteswap(&Pico32xMem->sh2_rom_m, p32x_bios_m, sizeof(Pico32xMem->sh2_rom_m));
  1943. }
  1944. else {
  1945. pl = (u32 *)&Pico32xMem->sh2_rom_m;
  1946. // fill exception vector table to our trap address
  1947. for (i = 0; i < 128; i++)
  1948. pl[i] = CPU_BE2(0x200);
  1949. // start
  1950. pl[0] = pl[2] = CPU_BE2(0x204);
  1951. // reset SP
  1952. pl[1] = pl[3] = CPU_BE2(0x6040000);
  1953. // startup code
  1954. memcpy(&Pico32xMem->sh2_rom_m.b[0x200], msh2_code, sizeof(msh2_code));
  1955. }
  1956. // SSH2
  1957. if (p32x_bios_s != NULL) {
  1958. elprintf(EL_STATUS|EL_32X, "32x: using supplied slave SH2 BIOS");
  1959. Byteswap(&Pico32xMem->sh2_rom_s, p32x_bios_s, sizeof(Pico32xMem->sh2_rom_s));
  1960. }
  1961. else {
  1962. pl = (u32 *)&Pico32xMem->sh2_rom_s;
  1963. // fill exception vector table to our trap address
  1964. for (i = 0; i < 128; i++)
  1965. pl[i] = CPU_BE2(0x200);
  1966. // start
  1967. pl[0] = pl[2] = CPU_BE2(0x204);
  1968. // reset SP
  1969. pl[1] = pl[3] = CPU_BE2(0x603f800);
  1970. // startup code
  1971. memcpy(&Pico32xMem->sh2_rom_s.b[0x200], ssh2_code, sizeof(ssh2_code));
  1972. }
  1973. }
  1974. #define MAP_MEMORY(m) ((uptr)(m) >> 1)
  1975. #define MAP_HANDLER(h) ( ((uptr)(h) >> 1) | ((uptr)1 << (sizeof(uptr) * 8 - 1)) )
  1976. static sh2_memmap msh2_read8_map[0x80], msh2_read16_map[0x80], msh2_read32_map[0x80];
  1977. static sh2_memmap ssh2_read8_map[0x80], ssh2_read16_map[0x80], ssh2_read32_map[0x80];
  1978. // for writes we are using handlers only
  1979. static sh2_write_handler *msh2_write8_map[0x80], *msh2_write16_map[0x80], *msh2_write32_map[0x80];
  1980. static sh2_write_handler *ssh2_write8_map[0x80], *ssh2_write16_map[0x80], *ssh2_write32_map[0x80];
  1981. void Pico32xSwapDRAM(int b)
  1982. {
  1983. cpu68k_map_set(m68k_read8_map, 0x840000, 0x85ffff, Pico32xMem->dram[b], 0);
  1984. cpu68k_map_set(m68k_read16_map, 0x840000, 0x85ffff, Pico32xMem->dram[b], 0);
  1985. cpu68k_map_set(m68k_read8_map, 0x860000, 0x87ffff, Pico32xMem->dram[b], 0);
  1986. cpu68k_map_set(m68k_read16_map, 0x860000, 0x87ffff, Pico32xMem->dram[b], 0);
  1987. cpu68k_map_set(m68k_write8_map, 0x840000, 0x87ffff,
  1988. b ? m68k_write8_dram1_ow : m68k_write8_dram0_ow, 1);
  1989. cpu68k_map_set(m68k_write16_map, 0x840000, 0x87ffff,
  1990. b ? m68k_write16_dram1_ow : m68k_write16_dram0_ow, 1);
  1991. // SH2
  1992. msh2_read8_map[0x04/2].addr = msh2_read8_map[0x24/2].addr =
  1993. msh2_read16_map[0x04/2].addr = msh2_read16_map[0x24/2].addr =
  1994. msh2_read32_map[0x04/2].addr = msh2_read32_map[0x24/2].addr = MAP_MEMORY(Pico32xMem->dram[b]);
  1995. ssh2_read8_map[0x04/2].addr = ssh2_read8_map[0x24/2].addr =
  1996. ssh2_read16_map[0x04/2].addr = ssh2_read16_map[0x24/2].addr =
  1997. ssh2_read32_map[0x04/2].addr = ssh2_read32_map[0x24/2].addr = MAP_MEMORY(Pico32xMem->dram[b]);
  1998. // convenience ptrs
  1999. msh2.p_dram = ssh2.p_dram = Pico32xMem->dram[b];
  2000. }
  2001. static void bank_switch_rom_sh2(void)
  2002. {
  2003. if (!carthw_ssf2_active) {
  2004. // easy
  2005. msh2_read8_map[0x02/2].addr = msh2_read8_map[0x22/2].addr =
  2006. msh2_read16_map[0x02/2].addr = msh2_read16_map[0x22/2].addr =
  2007. msh2_read32_map[0x02/2].addr = msh2_read32_map[0x22/2].addr = MAP_MEMORY(Pico.rom);
  2008. ssh2_read8_map[0x02/2].addr = ssh2_read8_map[0x22/2].addr =
  2009. ssh2_read16_map[0x02/2].addr = ssh2_read16_map[0x22/2].addr =
  2010. ssh2_read32_map[0x02/2].addr = ssh2_read32_map[0x22/2].addr = MAP_MEMORY(Pico.rom);
  2011. }
  2012. else {
  2013. msh2_read8_map[0x02/2].addr = msh2_read8_map[0x22/2].addr = MAP_HANDLER(sh2_read8_rom);
  2014. msh2_read16_map[0x02/2].addr = msh2_read16_map[0x22/2].addr = MAP_HANDLER(sh2_read16_rom);
  2015. msh2_read32_map[0x02/2].addr = msh2_read32_map[0x22/2].addr = MAP_HANDLER(sh2_read32_rom);
  2016. ssh2_read8_map[0x02/2].addr = ssh2_read8_map[0x22/2].addr = MAP_HANDLER(sh2_read8_rom);
  2017. ssh2_read16_map[0x02/2].addr = ssh2_read16_map[0x22/2].addr = MAP_HANDLER(sh2_read16_rom);
  2018. ssh2_read32_map[0x02/2].addr = ssh2_read32_map[0x22/2].addr = MAP_HANDLER(sh2_read32_rom);
  2019. }
  2020. }
  2021. void PicoMemSetup32x(void)
  2022. {
  2023. unsigned int rs;
  2024. int i;
  2025. Pico32xMem = plat_mmap(0x06000000, sizeof(*Pico32xMem), 0, 0);
  2026. if (Pico32xMem == NULL) {
  2027. elprintf(EL_STATUS, "OOM");
  2028. return;
  2029. }
  2030. get_bios();
  2031. // cartridge area becomes unmapped
  2032. // XXX: we take the easy way and don't unmap ROM,
  2033. // so that we can avoid handling the RV bit.
  2034. // m68k_map_unmap(0x000000, 0x3fffff);
  2035. if (!Pico.m.ncart_in) {
  2036. // MD ROM area
  2037. rs = sizeof(Pico32xMem->m68k_rom_bank);
  2038. cpu68k_map_set(m68k_read8_map, 0x000000, rs - 1, Pico32xMem->m68k_rom_bank, 0);
  2039. cpu68k_map_set(m68k_read16_map, 0x000000, rs - 1, Pico32xMem->m68k_rom_bank, 0);
  2040. cpu68k_map_set(m68k_write8_map, 0x000000, rs - 1, PicoWrite8_hint, 1); // TODO verify
  2041. cpu68k_map_set(m68k_write16_map, 0x000000, rs - 1, PicoWrite16_hint, 1);
  2042. // 32X ROM (unbanked, XXX: consider mirroring?)
  2043. rs = (Pico.romsize + M68K_BANK_MASK) & ~M68K_BANK_MASK;
  2044. if (rs > 0x80000)
  2045. rs = 0x80000;
  2046. cpu68k_map_set(m68k_read8_map, 0x880000, 0x880000 + rs - 1, Pico.rom, 0);
  2047. cpu68k_map_set(m68k_read16_map, 0x880000, 0x880000 + rs - 1, Pico.rom, 0);
  2048. cpu68k_map_set(m68k_write8_map, 0x880000, 0x880000 + rs - 1, PicoWrite8_cart, 1);
  2049. cpu68k_map_set(m68k_write16_map, 0x880000, 0x880000 + rs - 1, PicoWrite16_cart, 1);
  2050. // 32X ROM (banked)
  2051. bank_switch_rom_68k(0);
  2052. cpu68k_map_set(m68k_write8_map, 0x900000, 0x9fffff, PicoWrite8_bank, 1);
  2053. cpu68k_map_set(m68k_write16_map, 0x900000, 0x9fffff, PicoWrite16_bank, 1);
  2054. }
  2055. // SYS regs
  2056. cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoRead8_32x_on, 1);
  2057. cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoRead16_32x_on, 1);
  2058. cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWrite8_32x_on, 1);
  2059. cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_32x_on, 1);
  2060. // TODO: cd + carthw
  2061. if (PicoIn.AHW & PAHW_MCD) {
  2062. m68k_write8_io = PicoWrite8_32x_on_io_cd;
  2063. m68k_write16_io = PicoWrite16_32x_on_io_cd;
  2064. }
  2065. else if (carthw_ssf2_active) {
  2066. m68k_write8_io = PicoWrite8_32x_on_io_ssf2;
  2067. m68k_write16_io = PicoWrite16_32x_on_io_ssf2;
  2068. }
  2069. else {
  2070. m68k_write8_io = PicoWrite8_32x_on_io;
  2071. m68k_write16_io = PicoWrite16_32x_on_io;
  2072. }
  2073. // SH2 maps: A31,A30,A29,CS1,CS0
  2074. // all unmapped by default
  2075. for (i = 0; i < ARRAY_SIZE(msh2_read8_map); i++) {
  2076. msh2_read8_map[i].addr = MAP_HANDLER(sh2_read8_unmapped);
  2077. msh2_read16_map[i].addr = MAP_HANDLER(sh2_read16_unmapped);
  2078. msh2_read32_map[i].addr = MAP_HANDLER(sh2_read32_unmapped);
  2079. }
  2080. for (i = 0; i < ARRAY_SIZE(msh2_write8_map); i++) {
  2081. msh2_write8_map[i] = sh2_write8_unmapped;
  2082. msh2_write16_map[i] = sh2_write16_unmapped;
  2083. msh2_write32_map[i] = sh2_write32_unmapped;
  2084. }
  2085. // "purge area"
  2086. for (i = 0x40; i <= 0x5f; i++) {
  2087. msh2_write8_map[i >> 1] =
  2088. msh2_write16_map[i >> 1] =
  2089. msh2_write32_map[i >> 1] = sh2_write_ignore;
  2090. }
  2091. // CS0
  2092. msh2_read8_map[0x00/2].addr = msh2_read8_map[0x20/2].addr = MAP_HANDLER(sh2_read8_cs0);
  2093. msh2_read16_map[0x00/2].addr = msh2_read16_map[0x20/2].addr = MAP_HANDLER(sh2_read16_cs0);
  2094. msh2_read32_map[0x00/2].addr = msh2_read32_map[0x20/2].addr = MAP_HANDLER(sh2_read32_cs0);
  2095. msh2_write8_map[0x00/2] = msh2_write8_map[0x20/2] = sh2_write8_cs0;
  2096. msh2_write16_map[0x00/2] = msh2_write16_map[0x20/2] = sh2_write16_cs0;
  2097. msh2_write32_map[0x00/2] = msh2_write32_map[0x20/2] = sh2_write32_cs0;
  2098. // CS1 - ROM
  2099. bank_switch_rom_sh2();
  2100. msh2_read8_map[0x02/2].mask = msh2_read8_map[0x22/2].mask = 0x3fffff; // FIXME
  2101. msh2_read16_map[0x02/2].mask = msh2_read16_map[0x22/2].mask = 0x3ffffe; // FIXME
  2102. msh2_read32_map[0x02/2].mask = msh2_read32_map[0x22/2].mask = 0x3ffffc; // FIXME
  2103. msh2_write16_map[0x02/2] = msh2_write16_map[0x22/2] = sh2_write16_rom;
  2104. msh2_write32_map[0x02/2] = msh2_write32_map[0x22/2] = sh2_write32_rom;
  2105. // CS2 - DRAM
  2106. msh2_read8_map[0x04/2].mask = msh2_read8_map[0x24/2].mask = 0x01ffff;
  2107. msh2_read16_map[0x04/2].mask = msh2_read16_map[0x24/2].mask = 0x01fffe;
  2108. msh2_read32_map[0x04/2].mask = msh2_read32_map[0x24/2].mask = 0x01fffc;
  2109. msh2_write8_map[0x04/2] = msh2_write8_map[0x24/2] = sh2_write8_dram;
  2110. msh2_write16_map[0x04/2] = msh2_write16_map[0x24/2] = sh2_write16_dram;
  2111. msh2_write32_map[0x04/2] = msh2_write32_map[0x24/2] = sh2_write32_dram;
  2112. // CS3 - SDRAM
  2113. msh2_read8_map[0x06/2].addr = msh2_read8_map[0x26/2].addr =
  2114. msh2_read16_map[0x06/2].addr = msh2_read16_map[0x26/2].addr =
  2115. msh2_read32_map[0x06/2].addr = msh2_read32_map[0x26/2].addr = MAP_MEMORY(Pico32xMem->sdram);
  2116. msh2_write8_map[0x06/2] = msh2_write8_map[0x26/2] = sh2_write8_sdram;
  2117. msh2_write8_map[0x26/2] = sh2_write8_sdram_wt;
  2118. msh2_write16_map[0x06/2] = msh2_write16_map[0x26/2] = sh2_write16_sdram;
  2119. msh2_write32_map[0x06/2] = msh2_write32_map[0x26/2] = sh2_write32_sdram;
  2120. msh2_read8_map[0x06/2].mask = msh2_read8_map[0x26/2].mask = 0x03ffff;
  2121. msh2_read16_map[0x06/2].mask = msh2_read16_map[0x26/2].mask = 0x03fffe;
  2122. msh2_read32_map[0x06/2].mask = msh2_read32_map[0x26/2].mask = 0x03fffc;
  2123. // SH2 data array
  2124. msh2_read8_map[0xc0/2].mask = 0x0fff;
  2125. msh2_read16_map[0xc0/2].mask = 0x0ffe;
  2126. msh2_read32_map[0xc0/2].mask = 0x0ffc;
  2127. msh2_write8_map[0xc0/2] = sh2_write8_da;
  2128. msh2_write16_map[0xc0/2] = sh2_write16_da;
  2129. msh2_write32_map[0xc0/2] = sh2_write32_da;
  2130. // SH2 IO
  2131. msh2_read8_map[0xff/2].addr = MAP_HANDLER(sh2_peripheral_read8);
  2132. msh2_read16_map[0xff/2].addr = MAP_HANDLER(sh2_peripheral_read16);
  2133. msh2_read32_map[0xff/2].addr = MAP_HANDLER(sh2_peripheral_read32);
  2134. msh2_write8_map[0xff/2] = sh2_peripheral_write8;
  2135. msh2_write16_map[0xff/2] = sh2_peripheral_write16;
  2136. msh2_write32_map[0xff/2] = sh2_peripheral_write32;
  2137. memcpy(ssh2_read8_map, msh2_read8_map, sizeof(msh2_read8_map));
  2138. memcpy(ssh2_read16_map, msh2_read16_map, sizeof(msh2_read16_map));
  2139. memcpy(ssh2_read32_map, msh2_read32_map, sizeof(msh2_read32_map));
  2140. memcpy(ssh2_write8_map, msh2_write8_map, sizeof(msh2_write8_map));
  2141. memcpy(ssh2_write16_map, msh2_write16_map, sizeof(msh2_write16_map));
  2142. memcpy(ssh2_write32_map, msh2_write32_map, sizeof(msh2_write32_map));
  2143. msh2_read8_map[0xc0/2].addr =
  2144. msh2_read16_map[0xc0/2].addr =
  2145. msh2_read32_map[0xc0/2].addr = MAP_MEMORY(msh2.data_array);
  2146. ssh2_read8_map[0xc0/2].addr =
  2147. ssh2_read16_map[0xc0/2].addr =
  2148. ssh2_read32_map[0xc0/2].addr = MAP_MEMORY(ssh2.data_array);
  2149. // map DRAM area, both 68k and SH2
  2150. Pico32xSwapDRAM(1);
  2151. msh2.read8_map = msh2_read8_map; ssh2.read8_map = ssh2_read8_map;
  2152. msh2.read16_map = msh2_read16_map; ssh2.read16_map = ssh2_read16_map;
  2153. msh2.read32_map = msh2_read32_map; ssh2.read32_map = ssh2_read32_map;
  2154. msh2.write8_tab = (const void **)(void *)msh2_write8_map;
  2155. msh2.write16_tab = (const void **)(void *)msh2_write16_map;
  2156. msh2.write32_tab = (const void **)(void *)msh2_write32_map;
  2157. ssh2.write8_tab = (const void **)(void *)ssh2_write8_map;
  2158. ssh2.write16_tab = (const void **)(void *)ssh2_write16_map;
  2159. ssh2.write32_tab = (const void **)(void *)ssh2_write32_map;
  2160. // convenience ptrs
  2161. msh2.p_sdram = ssh2.p_sdram = Pico32xMem->sdram;
  2162. msh2.p_rom = ssh2.p_rom = Pico.rom;
  2163. msh2.p_bios = Pico32xMem->sh2_rom_m.w; msh2.p_da = msh2.data_array;
  2164. ssh2.p_bios = Pico32xMem->sh2_rom_s.w; ssh2.p_da = ssh2.data_array;
  2165. sh2_drc_mem_setup(&msh2);
  2166. sh2_drc_mem_setup(&ssh2);
  2167. memset(sh2_poll_rd, 0, sizeof(sh2_poll_rd));
  2168. memset(sh2_poll_wr, 0, sizeof(sh2_poll_wr));
  2169. memset(sh2_poll_fifo, -1, sizeof(sh2_poll_fifo));
  2170. // z80 hack
  2171. z80_map_set(z80_write_map, 0x8000, 0xffff, z80_md_bank_write_32x, 1);
  2172. }
  2173. void p32x_update_banks(void)
  2174. {
  2175. bank_switch_rom_68k(Pico32x.regs[4 / 2]);
  2176. bank_switch_rom_sh2();
  2177. if (Pico32x.emu_flags & P32XF_DRC_ROM_C)
  2178. sh2_drc_flush_all();
  2179. }
  2180. void Pico32xMemStateLoaded(void)
  2181. {
  2182. bank_switch_rom_68k(Pico32x.regs[4 / 2]);
  2183. Pico32xSwapDRAM((Pico32x.vdp_regs[0x0a / 2] & P32XV_FS) ^ P32XV_FS);
  2184. memset(Pico32xMem->pwm, 0, sizeof(Pico32xMem->pwm));
  2185. Pico32x.dirty_pal = 1;
  2186. Pico32x.emu_flags &= ~(P32XF_68KCPOLL | P32XF_68KVPOLL);
  2187. memset(&m68k_poll, 0, sizeof(m68k_poll));
  2188. msh2.state = 0;
  2189. msh2.poll_addr = msh2.poll_cycles = msh2.poll_cnt = 0;
  2190. ssh2.state = 0;
  2191. ssh2.poll_addr = ssh2.poll_cycles = ssh2.poll_cnt = 0;
  2192. sh2_drc_flush_all();
  2193. }
  2194. // vim:shiftwidth=2:ts=2:expandtab