memory.c 67 KB

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