memory.c 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471
  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 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 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 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. // write16
  1490. static void REGPARM(3) sh2_write16_unmapped(u32 a, u32 d, SH2 *sh2)
  1491. {
  1492. elprintf_sh2(sh2, EL_32X, "unmapped w16 [%08x] %04x @%06x",
  1493. a, d & 0xffff, sh2_pc(sh2));
  1494. }
  1495. static void REGPARM(3) sh2_write16_cs0(u32 a, u32 d, SH2 *sh2)
  1496. {
  1497. DRC_SAVE_SR(sh2);
  1498. if (((EL_LOGMASK & EL_PWM) || (a & 0x30) != 0x30)) // hide PWM
  1499. elprintf_sh2(sh2, EL_32X, "w16 [%08x] %04x @%06x",
  1500. a, d & 0xffff, sh2_pc(sh2));
  1501. if ((a & 0x3ffc0) == 0x4000) {
  1502. p32x_sh2reg_write16(a, d, sh2);
  1503. goto out;
  1504. }
  1505. if (Pico32x.regs[0] & P32XS_FM) {
  1506. if ((a & 0x3fff0) == 0x4100) {
  1507. sh2->poll_cnt = 0;
  1508. p32x_vdp_write16(a, d, sh2);
  1509. goto out;
  1510. }
  1511. if ((a & 0x3fe00) == 0x4200) {
  1512. sh2->poll_cnt = 0;
  1513. Pico32xMem->pal[(a & 0x1ff) / 2] = d;
  1514. Pico32x.dirty_pal = 1;
  1515. goto out;
  1516. }
  1517. }
  1518. sh2_write16_unmapped(a, d, sh2);
  1519. out:
  1520. DRC_RESTORE_SR(sh2);
  1521. }
  1522. #ifdef _ASM_32X_MEMORY_C
  1523. extern void REGPARM(3) sh2_write16_dram(u32 a, u32 d, SH2 *sh2);
  1524. extern void REGPARM(3) sh2_write16_sdram(u32 a, u32 d, SH2 *sh2);
  1525. extern void REGPARM(3) sh2_write16_da(u32 a, u32 d, SH2 *sh2);
  1526. #else
  1527. static void REGPARM(3) sh2_write16_dram(u32 a, u32 d, SH2 *sh2)
  1528. {
  1529. sh2_write16_dramN(sh2->p_dram, a, d);
  1530. }
  1531. static void REGPARM(3) sh2_write16_sdram(u32 a, u32 d, SH2 *sh2)
  1532. {
  1533. u32 a1 = a & 0x3fffe;
  1534. ((u16 *)sh2->p_sdram)[a1 / 2] = d;
  1535. #ifdef DRC_SH2
  1536. u8 *p = sh2->p_drcblk_ram;
  1537. u32 t = p[a1 >> SH2_DRCBLK_RAM_SHIFT];
  1538. if (t)
  1539. sh2_sdram_checks(a, d, sh2, t);
  1540. #endif
  1541. }
  1542. static void REGPARM(3) sh2_write16_da(u32 a, u32 d, SH2 *sh2)
  1543. {
  1544. u32 a1 = a & 0xffe;
  1545. ((u16 *)sh2->data_array)[a1 / 2] = d;
  1546. #ifdef DRC_SH2
  1547. u8 *p = sh2->p_drcblk_da;
  1548. u32 t = p[a1 >> SH2_DRCBLK_DA_SHIFT];
  1549. if (t)
  1550. sh2_da_checks(a, t, sh2);
  1551. #endif
  1552. }
  1553. #endif
  1554. static void REGPARM(3) sh2_write16_rom(u32 a, u32 d, SH2 *sh2)
  1555. {
  1556. u32 a1 = a & 0x3ffffe;
  1557. // tweak for WWF Raw: does writes to ROM area, and it doesn't work without
  1558. // allowing this.
  1559. // Presumably the write goes to the CPU cache and is read back from there,
  1560. // but it would be extremely costly to emulate cache behaviour. Just allow
  1561. // writes to that region, hoping that the original ROM values are never used.
  1562. if ((a1 & 0x3e0000) == 0x3e0000)
  1563. ((u16 *)sh2->p_rom)[a1 / 2] = d;
  1564. else
  1565. sh2_write16_unmapped(a, d, sh2);
  1566. }
  1567. static void REGPARM(3) sh2_write32_unmapped(u32 a, u32 d, SH2 *sh2)
  1568. {
  1569. elprintf_sh2(sh2, EL_32X, "unmapped w32 [%08x] %08x @%06x",
  1570. a, d, sh2_pc(sh2));
  1571. }
  1572. static void REGPARM(3) sh2_write32_cs0(u32 a, u32 d, SH2 *sh2)
  1573. {
  1574. sh2_write16_cs0(a, d >> 16, sh2);
  1575. sh2_write16_cs0(a + 2, d, sh2);
  1576. }
  1577. #define sh2_write32_dramN(p, a, d) \
  1578. u32 *pd = &((u32 *)p)[(a & 0x1ffff) / 4]; \
  1579. if (!(a & 0x20000)) { \
  1580. *pd = (d << 16) | (d >> 16); \
  1581. } else { \
  1582. /* overwrite */ \
  1583. u32 v = *pd, m = 0; d = (d << 16) | (d >> 16) ; \
  1584. if (!(d & 0x000000ff)) m |= 0x000000ff; \
  1585. if (!(d & 0x0000ff00)) m |= 0x0000ff00; \
  1586. if (!(d & 0x00ff0000)) m |= 0x00ff0000; \
  1587. if (!(d & 0xff000000)) m |= 0xff000000; \
  1588. *pd = d | (v&m); \
  1589. }
  1590. #ifdef _ASM_32X_MEMORY_C
  1591. extern void REGPARM(3) sh2_write32_dram(u32 a, u32 d, SH2 *sh2);
  1592. extern void REGPARM(3) sh2_write32_sdram(u32 a, u32 d, SH2 *sh2);
  1593. extern void REGPARM(3) sh2_write32_da(u32 a, u32 d, SH2 *sh2);
  1594. #else
  1595. static void REGPARM(3) sh2_write32_dram(u32 a, u32 d, SH2 *sh2)
  1596. {
  1597. sh2_write32_dramN(sh2->p_dram, a, d);
  1598. }
  1599. static void REGPARM(3) sh2_write32_sdram(u32 a, u32 d, SH2 *sh2)
  1600. {
  1601. u32 a1 = a & 0x3fffc;
  1602. *(u32 *)((char*)sh2->p_sdram + a1) = (d << 16) | (d >> 16);
  1603. #ifdef DRC_SH2
  1604. u8 *p = sh2->p_drcblk_ram;
  1605. u32 t = p[a1 >> SH2_DRCBLK_RAM_SHIFT];
  1606. u32 u = p[(a1+2) >> SH2_DRCBLK_RAM_SHIFT];
  1607. if (t|(u<<16))
  1608. sh2_sdram_checks_l(a, d, sh2, t|(u<<16));
  1609. #endif
  1610. }
  1611. static void REGPARM(3) sh2_write32_da(u32 a, u32 d, SH2 *sh2)
  1612. {
  1613. u32 a1 = a & 0xffc;
  1614. *((u32 *)sh2->data_array + a1/4) = (d << 16) | (d >> 16);
  1615. #ifdef DRC_SH2
  1616. u8 *p = sh2->p_drcblk_da;
  1617. u32 t = p[a1 >> SH2_DRCBLK_DA_SHIFT];
  1618. u32 u = p[(a1+2) >> SH2_DRCBLK_DA_SHIFT];
  1619. if (t|(u<<16))
  1620. sh2_da_checks_l(a, t|(u<<16), sh2);
  1621. #endif
  1622. }
  1623. #endif
  1624. static void REGPARM(3) sh2_write32_rom(u32 a, u32 d, SH2 *sh2)
  1625. {
  1626. sh2_write16_rom(a, d >> 16, sh2);
  1627. sh2_write16_rom(a + 2, d, sh2);
  1628. }
  1629. typedef u32 (sh2_read_handler)(u32 a, SH2 *sh2);
  1630. typedef void REGPARM(3) (sh2_write_handler)(u32 a, u32 d, SH2 *sh2);
  1631. #define SH2MAP_ADDR2OFFS_R(a) \
  1632. ((u32)(a) >> SH2_READ_SHIFT)
  1633. #define SH2MAP_ADDR2OFFS_W(a) \
  1634. ((u32)(a) >> SH2_WRITE_SHIFT)
  1635. u32 REGPARM(2) p32x_sh2_read8(u32 a, SH2 *sh2)
  1636. {
  1637. const sh2_memmap *sh2_map = sh2->read8_map;
  1638. uptr p;
  1639. sh2_map += SH2MAP_ADDR2OFFS_R(a);
  1640. p = sh2_map->addr;
  1641. if (!map_flag_set(p))
  1642. return *(s8 *)((p << 1) + ((a & sh2_map->mask) ^ 1));
  1643. else
  1644. return ((sh2_read_handler *)(p << 1))(a, sh2);
  1645. }
  1646. u32 REGPARM(2) p32x_sh2_read16(u32 a, SH2 *sh2)
  1647. {
  1648. const sh2_memmap *sh2_map = sh2->read16_map;
  1649. uptr p;
  1650. sh2_map += SH2MAP_ADDR2OFFS_R(a);
  1651. p = sh2_map->addr;
  1652. if (!map_flag_set(p))
  1653. return *(s16 *)((p << 1) + (a & sh2_map->mask));
  1654. else
  1655. return ((sh2_read_handler *)(p << 1))(a, sh2);
  1656. }
  1657. u32 REGPARM(2) p32x_sh2_read32(u32 a, SH2 *sh2)
  1658. {
  1659. const sh2_memmap *sh2_map = sh2->read32_map;
  1660. uptr p;
  1661. sh2_map += SH2MAP_ADDR2OFFS_R(a);
  1662. p = sh2_map->addr;
  1663. if (!map_flag_set(p)) {
  1664. u32 *pd = (u32 *)((p << 1) + (a & sh2_map->mask));
  1665. return (*pd << 16) | (*pd >> 16);
  1666. } else
  1667. return ((sh2_read_handler *)(p << 1))(a, sh2);
  1668. }
  1669. void REGPARM(3) p32x_sh2_write8(u32 a, u32 d, SH2 *sh2)
  1670. {
  1671. const void **sh2_wmap = sh2->write8_tab;
  1672. sh2_write_handler *wh;
  1673. wh = sh2_wmap[SH2MAP_ADDR2OFFS_W(a)];
  1674. wh(a, d, sh2);
  1675. }
  1676. void REGPARM(3) p32x_sh2_write16(u32 a, u32 d, SH2 *sh2)
  1677. {
  1678. const void **sh2_wmap = sh2->write16_tab;
  1679. sh2_write_handler *wh;
  1680. wh = sh2_wmap[SH2MAP_ADDR2OFFS_W(a)];
  1681. wh(a, d, sh2);
  1682. }
  1683. void REGPARM(3) p32x_sh2_write32(u32 a, u32 d, SH2 *sh2)
  1684. {
  1685. const void **sh2_wmap = sh2->write32_tab;
  1686. sh2_write_handler *wh;
  1687. wh = sh2_wmap[SH2MAP_ADDR2OFFS_W(a)];
  1688. wh(a, d, sh2);
  1689. }
  1690. void *p32x_sh2_get_mem_ptr(u32 a, u32 *mask, SH2 *sh2)
  1691. {
  1692. const sh2_memmap *mm = sh2->read8_map;
  1693. void *ret = (void *)-1;
  1694. mm += SH2MAP_ADDR2OFFS_R(a);
  1695. if (!map_flag_set(mm->addr)) {
  1696. // directly mapped memory (SDRAM, ROM, data array)
  1697. ret = (void *)(mm->addr << 1);
  1698. *mask = mm->mask;
  1699. } else if ((a & ~0x7ff) == 0) {
  1700. // BIOS, has handler function since it shares its segment with I/O
  1701. ret = sh2->p_bios;
  1702. *mask = 0x7ff;
  1703. } else if ((a & 0xc6000000) == 0x02000000) {
  1704. // banked ROM. Return bank address
  1705. u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
  1706. ret = (char*)sh2->p_rom + bank;
  1707. *mask = 0x07ffff;
  1708. }
  1709. return ret;
  1710. }
  1711. int p32x_sh2_memcpy(u32 dst, u32 src, int count, int size, SH2 *sh2)
  1712. {
  1713. u32 mask;
  1714. u8 *ps, *pd;
  1715. int len, i;
  1716. // check if src and dst points to memory (rom/sdram/dram/da)
  1717. if ((pd = p32x_sh2_get_mem_ptr(dst, &mask, sh2)) == (void *)-1)
  1718. return 0;
  1719. if ((ps = p32x_sh2_get_mem_ptr(src, &mask, sh2)) == (void *)-1)
  1720. return 0;
  1721. ps += src & mask;
  1722. len = count * size;
  1723. // DRAM in byte access is always in overwrite mode
  1724. if (pd == sh2->p_dram && size == 1)
  1725. dst |= 0x20000;
  1726. // align dst to halfword
  1727. if (dst & 1) {
  1728. p32x_sh2_write8(dst, *(u8 *)((uptr)ps ^ 1), sh2);
  1729. ps++, dst++, len --;
  1730. }
  1731. // copy data
  1732. if ((uptr)ps & 1) {
  1733. // unaligned, use halfword copy mode to reduce memory bandwidth
  1734. u16 *sp = (u16 *)(ps - 1);
  1735. u16 dl, dh = *sp++;
  1736. for (i = 0; i < (len & ~1); i += 2, dst += 2, sp++) {
  1737. dl = dh, dh = *sp;
  1738. p32x_sh2_write16(dst, (dh >> 8) | (dl << 8), sh2);
  1739. }
  1740. if (len & 1)
  1741. p32x_sh2_write8(dst, dh, sh2);
  1742. } else {
  1743. // dst and src at least halfword aligned
  1744. u16 *sp = (u16 *)ps;
  1745. // align dst to word
  1746. if ((dst & 2) && len >= 2) {
  1747. p32x_sh2_write16(dst, *sp++, sh2);
  1748. dst += 2, len -= 2;
  1749. }
  1750. if ((uptr)sp & 2) {
  1751. // halfword copy, using word writes to reduce memory bandwidth
  1752. u16 dl, dh;
  1753. for (i = 0; i < (len & ~3); i += 4, dst += 4, sp += 2) {
  1754. dl = sp[0], dh = sp[1];
  1755. p32x_sh2_write32(dst, (dl << 16) | dh, sh2);
  1756. }
  1757. } else {
  1758. // word copy
  1759. u32 d;
  1760. for (i = 0; i < (len & ~3); i += 4, dst += 4, sp += 2) {
  1761. d = *(u32 *)sp;
  1762. p32x_sh2_write32(dst, (d << 16) | (d >> 16), sh2);
  1763. }
  1764. }
  1765. if (len & 2) {
  1766. p32x_sh2_write16(dst, *sp++, sh2);
  1767. dst += 2;
  1768. }
  1769. if (len & 1)
  1770. p32x_sh2_write8(dst, *sp >> 8, sh2);
  1771. }
  1772. return count;
  1773. }
  1774. // -----------------------------------------------------------------
  1775. static void z80_md_bank_write_32x(u32 a, unsigned char d)
  1776. {
  1777. u32 addr68k;
  1778. addr68k = Pico.m.z80_bank68k << 15;
  1779. addr68k += a & 0x7fff;
  1780. if ((addr68k & 0xfff000) == 0xa15000)
  1781. Pico32x.emu_flags |= P32XF_Z80_32X_IO;
  1782. elprintf(EL_Z80BNK, "z80->68k w8 [%06x] %02x", addr68k, d);
  1783. m68k_write8(addr68k, d);
  1784. }
  1785. // -----------------------------------------------------------------
  1786. static const u16 msh2_code[] = {
  1787. // trap instructions
  1788. 0xaffe, // 200 bra <self>
  1789. 0x0009, // 202 nop
  1790. // have to wait a bit until m68k initial program finishes clearing stuff
  1791. // to avoid races with game SH2 code, like in Tempo
  1792. 0xd406, // 204 mov.l @(_m_ok,pc), r4
  1793. 0xc400, // 206 mov.b @(h'0,gbr),r0
  1794. 0xc801, // 208 tst #1, r0
  1795. 0x8b0f, // 20a bf cd_start
  1796. 0xd105, // 20c mov.l @(_cnt,pc), r1
  1797. 0xd206, // 20e mov.l @(_start,pc), r2
  1798. 0x71ff, // 210 add #-1, r1
  1799. 0x4115, // 212 cmp/pl r1
  1800. 0x89fc, // 214 bt -2
  1801. 0x6043, // 216 mov r4, r0
  1802. 0xc208, // 218 mov.l r0, @(h'20,gbr)
  1803. 0x6822, // 21a mov.l @r2, r8
  1804. 0x482b, // 21c jmp @r8
  1805. 0x0009, // 21e nop
  1806. ('M'<<8)|'_', ('O'<<8)|'K', // 220 _m_ok
  1807. 0x0001, 0x0000, // 224 _cnt
  1808. 0x2200, 0x03e0, // master start pointer in ROM
  1809. // cd_start:
  1810. 0xd20d, // 22c mov.l @(__cd_,pc), r2
  1811. 0xc608, // 22e mov.l @(h'20,gbr), r0
  1812. 0x3200, // 230 cmp/eq r0, r2
  1813. 0x8bfc, // 232 bf #-2
  1814. 0xe000, // 234 mov #0, r0
  1815. 0xcf80, // 236 or.b #0x80,@(r0,gbr)
  1816. 0xd80b, // 238 mov.l @(_start_cd,pc), r8 // 24000018
  1817. 0xd30c, // 23a mov.l @(_max_len,pc), r3
  1818. 0x5b84, // 23c mov.l @(h'10,r8), r11 // master vbr
  1819. 0x5a82, // 23e mov.l @(8,r8), r10 // entry
  1820. 0x5081, // 240 mov.l @(4,r8), r0 // len
  1821. 0x5980, // 242 mov.l @(0,r8), r9 // dst
  1822. 0x3036, // 244 cmp/hi r3,r0
  1823. 0x8b00, // 246 bf #1
  1824. 0x6033, // 248 mov r3,r0
  1825. 0x7820, // 24a add #0x20, r8
  1826. // ipl_copy:
  1827. 0x6286, // 24c mov.l @r8+, r2
  1828. 0x2922, // 24e mov.l r2, @r9
  1829. 0x7904, // 250 add #4, r9
  1830. 0x70fc, // 252 add #-4, r0
  1831. 0x8800, // 254 cmp/eq #0, r0
  1832. 0x8bf9, // 256 bf #-5
  1833. //
  1834. 0x4b2e, // 258 ldc r11, vbr
  1835. 0x6043, // 25a mov r4, r0 // M_OK
  1836. 0xc208, // 25c mov.l r0, @(h'20,gbr)
  1837. 0x4a2b, // 25e jmp @r10
  1838. 0x0009, // 260 nop
  1839. 0x0009, // 262 nop // pad
  1840. ('_'<<8)|'C', ('D'<<8)|'_', // 264 __cd_
  1841. 0x2400, 0x0018, // 268 _start_cd
  1842. 0x0001, 0xffe0, // 26c _max_len
  1843. };
  1844. static const u16 ssh2_code[] = {
  1845. 0xaffe, // 200 bra <self>
  1846. 0x0009, // 202 nop
  1847. // code to wait for master, in case authentic master BIOS is used
  1848. 0xd106, // 204 mov.l @(_m_ok,pc), r1
  1849. 0xd208, // 206 mov.l @(_start,pc), r2
  1850. 0xc608, // 208 mov.l @(h'20,gbr), r0
  1851. 0x3100, // 20a cmp/eq r0, r1
  1852. 0x8bfc, // 20c bf #-2
  1853. 0xc400, // 20e mov.b @(h'0,gbr),r0
  1854. 0xc801, // 210 tst #1, r0
  1855. 0xd004, // 212 mov.l @(_s_ok,pc), r0
  1856. 0x8b0a, // 214 bf cd_start
  1857. 0xc209, // 216 mov.l r0, @(h'24,gbr)
  1858. 0x6822, // 218 mov.l @r2, r8
  1859. 0x482b, // 21a jmp @r8
  1860. 0x0009, // 21c nop
  1861. 0x0009, // 21e nop
  1862. ('M'<<8)|'_', ('O'<<8)|'K', // 220
  1863. ('S'<<8)|'_', ('O'<<8)|'K', // 224
  1864. 0x2200, 0x03e4, // slave start pointer in ROM
  1865. // cd_start:
  1866. 0xd803, // 22c mov.l @(_start_cd,pc), r8 // 24000018
  1867. 0x5b85, // 22e mov.l @(h'14,r8), r11 // slave vbr
  1868. 0x5a83, // 230 mov.l @(h'0c,r8), r10 // entry
  1869. 0x4b2e, // 232 ldc r11, vbr
  1870. 0xc209, // 234 mov.l r0, @(h'24,gbr) // write S_OK
  1871. 0x4a2b, // 236 jmp @r10
  1872. 0x0009, // 238 nop
  1873. 0x0009, // 23a nop
  1874. 0x2400, 0x0018, // 23c _start_cd
  1875. };
  1876. #define HWSWAP(x) (((u16)(x) << 16) | ((x) >> 16))
  1877. static void get_bios(void)
  1878. {
  1879. u16 *ps;
  1880. u32 *pl;
  1881. int i;
  1882. // M68K ROM
  1883. if (p32x_bios_g != NULL) {
  1884. elprintf(EL_STATUS|EL_32X, "32x: using supplied 68k BIOS");
  1885. Byteswap(Pico32xMem->m68k_rom, p32x_bios_g, sizeof(Pico32xMem->m68k_rom));
  1886. }
  1887. else {
  1888. static const u16 andb[] = { 0x0239, 0x00fe, 0x00a1, 0x5107 };
  1889. static const u16 p_d4[] = {
  1890. 0x48e7, 0x8040, // movem.l d0/a1, -(sp)
  1891. 0x227c, 0x00a1, 0x30f1, // movea.l #0xa130f1, a1
  1892. 0x7007, // moveq.l #7, d0
  1893. 0x12d8, //0: move.b (a0)+, (a1)+
  1894. 0x5289, // addq.l #1, a1
  1895. 0x51c8, 0xfffa, // dbra d0, 0b
  1896. 0x0239, 0x00fe, 0x00a1, // and.b #0xfe, (0xa15107).l
  1897. 0x5107,
  1898. 0x4cdf, 0x0201 // movem.l (sp)+, d0/a1
  1899. };
  1900. // generate 68k ROM
  1901. ps = (u16 *)Pico32xMem->m68k_rom;
  1902. pl = (u32 *)ps;
  1903. for (i = 1; i < 0xc0/4; i++)
  1904. pl[i] = HWSWAP(0x880200 + (i - 1) * 6);
  1905. pl[0x70/4] = 0;
  1906. // fill with nops
  1907. for (i = 0xc0/2; i < 0x100/2; i++)
  1908. ps[i] = 0x4e71;
  1909. // c0: don't need to care about RV - not emulated
  1910. ps[0xc8/2] = 0x1280; // move.b d0, (a1)
  1911. memcpy(ps + 0xca/2, andb, sizeof(andb)); // and.b #0xfe, (a15107)
  1912. ps[0xd2/2] = 0x4e75; // rts
  1913. // d4:
  1914. memcpy(ps + 0xd4/2, p_d4, sizeof(p_d4));
  1915. ps[0xfe/2] = 0x4e75; // rts
  1916. }
  1917. // fill remaining m68k_rom page with game ROM
  1918. memcpy(Pico32xMem->m68k_rom_bank + sizeof(Pico32xMem->m68k_rom),
  1919. Pico.rom + sizeof(Pico32xMem->m68k_rom),
  1920. sizeof(Pico32xMem->m68k_rom_bank) - sizeof(Pico32xMem->m68k_rom));
  1921. // MSH2
  1922. if (p32x_bios_m != NULL) {
  1923. elprintf(EL_STATUS|EL_32X, "32x: using supplied master SH2 BIOS");
  1924. Byteswap(&Pico32xMem->sh2_rom_m, p32x_bios_m, sizeof(Pico32xMem->sh2_rom_m));
  1925. }
  1926. else {
  1927. pl = (u32 *)&Pico32xMem->sh2_rom_m;
  1928. // fill exception vector table to our trap address
  1929. for (i = 0; i < 128; i++)
  1930. pl[i] = HWSWAP(0x200);
  1931. // start
  1932. pl[0] = pl[2] = HWSWAP(0x204);
  1933. // reset SP
  1934. pl[1] = pl[3] = HWSWAP(0x6040000);
  1935. // startup code
  1936. memcpy(&Pico32xMem->sh2_rom_m.b[0x200], msh2_code, sizeof(msh2_code));
  1937. }
  1938. // SSH2
  1939. if (p32x_bios_s != NULL) {
  1940. elprintf(EL_STATUS|EL_32X, "32x: using supplied slave SH2 BIOS");
  1941. Byteswap(&Pico32xMem->sh2_rom_s, p32x_bios_s, sizeof(Pico32xMem->sh2_rom_s));
  1942. }
  1943. else {
  1944. pl = (u32 *)&Pico32xMem->sh2_rom_s;
  1945. // fill exception vector table to our trap address
  1946. for (i = 0; i < 128; i++)
  1947. pl[i] = HWSWAP(0x200);
  1948. // start
  1949. pl[0] = pl[2] = HWSWAP(0x204);
  1950. // reset SP
  1951. pl[1] = pl[3] = HWSWAP(0x603f800);
  1952. // startup code
  1953. memcpy(&Pico32xMem->sh2_rom_s.b[0x200], ssh2_code, sizeof(ssh2_code));
  1954. }
  1955. }
  1956. #define MAP_MEMORY(m) ((uptr)(m) >> 1)
  1957. #define MAP_HANDLER(h) ( ((uptr)(h) >> 1) | ((uptr)1 << (sizeof(uptr) * 8 - 1)) )
  1958. static sh2_memmap msh2_read8_map[0x80], msh2_read16_map[0x80], msh2_read32_map[0x80];
  1959. static sh2_memmap ssh2_read8_map[0x80], ssh2_read16_map[0x80], ssh2_read32_map[0x80];
  1960. // for writes we are using handlers only
  1961. static sh2_write_handler *msh2_write8_map[0x80], *msh2_write16_map[0x80], *msh2_write32_map[0x80];
  1962. static sh2_write_handler *ssh2_write8_map[0x80], *ssh2_write16_map[0x80], *ssh2_write32_map[0x80];
  1963. void Pico32xSwapDRAM(int b)
  1964. {
  1965. cpu68k_map_set(m68k_read8_map, 0x840000, 0x85ffff, Pico32xMem->dram[b], 0);
  1966. cpu68k_map_set(m68k_read16_map, 0x840000, 0x85ffff, Pico32xMem->dram[b], 0);
  1967. cpu68k_map_set(m68k_read8_map, 0x860000, 0x87ffff, Pico32xMem->dram[b], 0);
  1968. cpu68k_map_set(m68k_read16_map, 0x860000, 0x87ffff, Pico32xMem->dram[b], 0);
  1969. cpu68k_map_set(m68k_write8_map, 0x840000, 0x87ffff,
  1970. b ? m68k_write8_dram1_ow : m68k_write8_dram0_ow, 1);
  1971. cpu68k_map_set(m68k_write16_map, 0x840000, 0x87ffff,
  1972. b ? m68k_write16_dram1_ow : m68k_write16_dram0_ow, 1);
  1973. // SH2
  1974. msh2_read8_map[0x04/2].addr = msh2_read8_map[0x24/2].addr =
  1975. msh2_read16_map[0x04/2].addr = msh2_read16_map[0x24/2].addr =
  1976. msh2_read32_map[0x04/2].addr = msh2_read32_map[0x24/2].addr = MAP_MEMORY(Pico32xMem->dram[b]);
  1977. ssh2_read8_map[0x04/2].addr = ssh2_read8_map[0x24/2].addr =
  1978. ssh2_read16_map[0x04/2].addr = ssh2_read16_map[0x24/2].addr =
  1979. ssh2_read32_map[0x04/2].addr = ssh2_read32_map[0x24/2].addr = MAP_MEMORY(Pico32xMem->dram[b]);
  1980. // convenience ptrs
  1981. msh2.p_dram = ssh2.p_dram = Pico32xMem->dram[b];
  1982. }
  1983. static void bank_switch_rom_sh2(void)
  1984. {
  1985. if (!carthw_ssf2_active) {
  1986. // easy
  1987. msh2_read8_map[0x02/2].addr = msh2_read8_map[0x22/2].addr =
  1988. msh2_read16_map[0x02/2].addr = msh2_read16_map[0x22/2].addr =
  1989. msh2_read32_map[0x02/2].addr = msh2_read32_map[0x22/2].addr = MAP_MEMORY(Pico.rom);
  1990. ssh2_read8_map[0x02/2].addr = ssh2_read8_map[0x22/2].addr =
  1991. ssh2_read16_map[0x02/2].addr = ssh2_read16_map[0x22/2].addr =
  1992. ssh2_read32_map[0x02/2].addr = ssh2_read32_map[0x22/2].addr = MAP_MEMORY(Pico.rom);
  1993. }
  1994. else {
  1995. msh2_read8_map[0x02/2].addr = msh2_read8_map[0x22/2].addr = MAP_HANDLER(sh2_read8_rom);
  1996. msh2_read16_map[0x02/2].addr = msh2_read16_map[0x22/2].addr = MAP_HANDLER(sh2_read16_rom);
  1997. msh2_read32_map[0x02/2].addr = msh2_read32_map[0x22/2].addr = MAP_HANDLER(sh2_read32_rom);
  1998. ssh2_read8_map[0x02/2].addr = ssh2_read8_map[0x22/2].addr = MAP_HANDLER(sh2_read8_rom);
  1999. ssh2_read16_map[0x02/2].addr = ssh2_read16_map[0x22/2].addr = MAP_HANDLER(sh2_read16_rom);
  2000. ssh2_read32_map[0x02/2].addr = ssh2_read32_map[0x22/2].addr = MAP_HANDLER(sh2_read32_rom);
  2001. }
  2002. }
  2003. void PicoMemSetup32x(void)
  2004. {
  2005. unsigned int rs;
  2006. int i;
  2007. Pico32xMem = plat_mmap(0x06000000, sizeof(*Pico32xMem), 0, 0);
  2008. if (Pico32xMem == NULL) {
  2009. elprintf(EL_STATUS, "OOM");
  2010. return;
  2011. }
  2012. get_bios();
  2013. // cartridge area becomes unmapped
  2014. // XXX: we take the easy way and don't unmap ROM,
  2015. // so that we can avoid handling the RV bit.
  2016. // m68k_map_unmap(0x000000, 0x3fffff);
  2017. if (!Pico.m.ncart_in) {
  2018. // MD ROM area
  2019. rs = sizeof(Pico32xMem->m68k_rom_bank);
  2020. cpu68k_map_set(m68k_read8_map, 0x000000, rs - 1, Pico32xMem->m68k_rom_bank, 0);
  2021. cpu68k_map_set(m68k_read16_map, 0x000000, rs - 1, Pico32xMem->m68k_rom_bank, 0);
  2022. cpu68k_map_set(m68k_write8_map, 0x000000, rs - 1, PicoWrite8_hint, 1); // TODO verify
  2023. cpu68k_map_set(m68k_write16_map, 0x000000, rs - 1, PicoWrite16_hint, 1);
  2024. // 32X ROM (unbanked, XXX: consider mirroring?)
  2025. rs = (Pico.romsize + M68K_BANK_MASK) & ~M68K_BANK_MASK;
  2026. if (rs > 0x80000)
  2027. rs = 0x80000;
  2028. cpu68k_map_set(m68k_read8_map, 0x880000, 0x880000 + rs - 1, Pico.rom, 0);
  2029. cpu68k_map_set(m68k_read16_map, 0x880000, 0x880000 + rs - 1, Pico.rom, 0);
  2030. cpu68k_map_set(m68k_write8_map, 0x880000, 0x880000 + rs - 1, PicoWrite8_cart, 1);
  2031. cpu68k_map_set(m68k_write16_map, 0x880000, 0x880000 + rs - 1, PicoWrite16_cart, 1);
  2032. // 32X ROM (banked)
  2033. bank_switch_rom_68k(0);
  2034. cpu68k_map_set(m68k_write8_map, 0x900000, 0x9fffff, PicoWrite8_bank, 1);
  2035. cpu68k_map_set(m68k_write16_map, 0x900000, 0x9fffff, PicoWrite16_bank, 1);
  2036. }
  2037. // SYS regs
  2038. cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoRead8_32x_on, 1);
  2039. cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoRead16_32x_on, 1);
  2040. cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWrite8_32x_on, 1);
  2041. cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_32x_on, 1);
  2042. // TODO: cd + carthw
  2043. if (PicoIn.AHW & PAHW_MCD) {
  2044. m68k_write8_io = PicoWrite8_32x_on_io_cd;
  2045. m68k_write16_io = PicoWrite16_32x_on_io_cd;
  2046. }
  2047. else if (carthw_ssf2_active) {
  2048. m68k_write8_io = PicoWrite8_32x_on_io_ssf2;
  2049. m68k_write16_io = PicoWrite16_32x_on_io_ssf2;
  2050. }
  2051. else {
  2052. m68k_write8_io = PicoWrite8_32x_on_io;
  2053. m68k_write16_io = PicoWrite16_32x_on_io;
  2054. }
  2055. // SH2 maps: A31,A30,A29,CS1,CS0
  2056. // all unmapped by default
  2057. for (i = 0; i < ARRAY_SIZE(msh2_read8_map); i++) {
  2058. msh2_read8_map[i].addr = MAP_HANDLER(sh2_read8_unmapped);
  2059. msh2_read16_map[i].addr = MAP_HANDLER(sh2_read16_unmapped);
  2060. msh2_read32_map[i].addr = MAP_HANDLER(sh2_read32_unmapped);
  2061. }
  2062. for (i = 0; i < ARRAY_SIZE(msh2_write8_map); i++) {
  2063. msh2_write8_map[i] = sh2_write8_unmapped;
  2064. msh2_write16_map[i] = sh2_write16_unmapped;
  2065. msh2_write32_map[i] = sh2_write32_unmapped;
  2066. }
  2067. // "purge area"
  2068. for (i = 0x40; i <= 0x5f; i++) {
  2069. msh2_write8_map[i >> 1] =
  2070. msh2_write16_map[i >> 1] =
  2071. msh2_write32_map[i >> 1] = sh2_write_ignore;
  2072. }
  2073. // CS0
  2074. msh2_read8_map[0x00/2].addr = msh2_read8_map[0x20/2].addr = MAP_HANDLER(sh2_read8_cs0);
  2075. msh2_read16_map[0x00/2].addr = msh2_read16_map[0x20/2].addr = MAP_HANDLER(sh2_read16_cs0);
  2076. msh2_read32_map[0x00/2].addr = msh2_read32_map[0x20/2].addr = MAP_HANDLER(sh2_read32_cs0);
  2077. msh2_write8_map[0x00/2] = msh2_write8_map[0x20/2] = sh2_write8_cs0;
  2078. msh2_write16_map[0x00/2] = msh2_write16_map[0x20/2] = sh2_write16_cs0;
  2079. msh2_write32_map[0x00/2] = msh2_write32_map[0x20/2] = sh2_write32_cs0;
  2080. // CS1 - ROM
  2081. bank_switch_rom_sh2();
  2082. msh2_read8_map[0x02/2].mask = msh2_read8_map[0x22/2].mask = 0x3fffff; // FIXME
  2083. msh2_read16_map[0x02/2].mask = msh2_read16_map[0x22/2].mask = 0x3ffffe; // FIXME
  2084. msh2_read32_map[0x02/2].mask = msh2_read32_map[0x22/2].mask = 0x3ffffc; // FIXME
  2085. msh2_write16_map[0x02/2] = msh2_write16_map[0x22/2] = sh2_write16_rom;
  2086. msh2_write32_map[0x02/2] = msh2_write32_map[0x22/2] = sh2_write32_rom;
  2087. // CS2 - DRAM
  2088. msh2_read8_map[0x04/2].mask = msh2_read8_map[0x24/2].mask = 0x01ffff;
  2089. msh2_read16_map[0x04/2].mask = msh2_read16_map[0x24/2].mask = 0x01fffe;
  2090. msh2_read32_map[0x04/2].mask = msh2_read32_map[0x24/2].mask = 0x01fffc;
  2091. msh2_write8_map[0x04/2] = msh2_write8_map[0x24/2] = sh2_write8_dram;
  2092. msh2_write16_map[0x04/2] = msh2_write16_map[0x24/2] = sh2_write16_dram;
  2093. msh2_write32_map[0x04/2] = msh2_write32_map[0x24/2] = sh2_write32_dram;
  2094. // CS3 - SDRAM
  2095. msh2_read8_map[0x06/2].addr = msh2_read8_map[0x26/2].addr =
  2096. msh2_read16_map[0x06/2].addr = msh2_read16_map[0x26/2].addr =
  2097. msh2_read32_map[0x06/2].addr = msh2_read32_map[0x26/2].addr = MAP_MEMORY(Pico32xMem->sdram);
  2098. msh2_write8_map[0x06/2] = msh2_write8_map[0x26/2] = sh2_write8_sdram;
  2099. msh2_write16_map[0x06/2] = msh2_write16_map[0x26/2] = sh2_write16_sdram;
  2100. msh2_write32_map[0x06/2] = msh2_write32_map[0x26/2] = sh2_write32_sdram;
  2101. msh2_read8_map[0x06/2].mask = msh2_read8_map[0x26/2].mask = 0x03ffff;
  2102. msh2_read16_map[0x06/2].mask = msh2_read16_map[0x26/2].mask = 0x03fffe;
  2103. msh2_read32_map[0x06/2].mask = msh2_read32_map[0x26/2].mask = 0x03fffc;
  2104. // SH2 data array
  2105. msh2_read8_map[0xc0/2].mask = 0x0fff;
  2106. msh2_read16_map[0xc0/2].mask = 0x0ffe;
  2107. msh2_read32_map[0xc0/2].mask = 0x0ffc;
  2108. msh2_write8_map[0xc0/2] = sh2_write8_da;
  2109. msh2_write16_map[0xc0/2] = sh2_write16_da;
  2110. msh2_write32_map[0xc0/2] = sh2_write32_da;
  2111. // SH2 IO
  2112. msh2_read8_map[0xff/2].addr = MAP_HANDLER(sh2_peripheral_read8);
  2113. msh2_read16_map[0xff/2].addr = MAP_HANDLER(sh2_peripheral_read16);
  2114. msh2_read32_map[0xff/2].addr = MAP_HANDLER(sh2_peripheral_read32);
  2115. msh2_write8_map[0xff/2] = sh2_peripheral_write8;
  2116. msh2_write16_map[0xff/2] = sh2_peripheral_write16;
  2117. msh2_write32_map[0xff/2] = sh2_peripheral_write32;
  2118. memcpy(ssh2_read8_map, msh2_read8_map, sizeof(msh2_read8_map));
  2119. memcpy(ssh2_read16_map, msh2_read16_map, sizeof(msh2_read16_map));
  2120. memcpy(ssh2_read32_map, msh2_read32_map, sizeof(msh2_read32_map));
  2121. memcpy(ssh2_write8_map, msh2_write8_map, sizeof(msh2_write8_map));
  2122. memcpy(ssh2_write16_map, msh2_write16_map, sizeof(msh2_write16_map));
  2123. memcpy(ssh2_write32_map, msh2_write32_map, sizeof(msh2_write32_map));
  2124. msh2_read8_map[0xc0/2].addr =
  2125. msh2_read16_map[0xc0/2].addr =
  2126. msh2_read32_map[0xc0/2].addr = MAP_MEMORY(msh2.data_array);
  2127. ssh2_read8_map[0xc0/2].addr =
  2128. ssh2_read16_map[0xc0/2].addr =
  2129. ssh2_read32_map[0xc0/2].addr = MAP_MEMORY(ssh2.data_array);
  2130. // map DRAM area, both 68k and SH2
  2131. Pico32xSwapDRAM(1);
  2132. msh2.read8_map = msh2_read8_map; ssh2.read8_map = ssh2_read8_map;
  2133. msh2.read16_map = msh2_read16_map; ssh2.read16_map = ssh2_read16_map;
  2134. msh2.read32_map = msh2_read32_map; ssh2.read32_map = ssh2_read32_map;
  2135. msh2.write8_tab = (const void **)(void *)msh2_write8_map;
  2136. msh2.write16_tab = (const void **)(void *)msh2_write16_map;
  2137. msh2.write32_tab = (const void **)(void *)msh2_write32_map;
  2138. ssh2.write8_tab = (const void **)(void *)ssh2_write8_map;
  2139. ssh2.write16_tab = (const void **)(void *)ssh2_write16_map;
  2140. ssh2.write32_tab = (const void **)(void *)ssh2_write32_map;
  2141. // convenience ptrs
  2142. msh2.p_sdram = ssh2.p_sdram = Pico32xMem->sdram;
  2143. msh2.p_rom = ssh2.p_rom = Pico.rom;
  2144. msh2.p_bios = Pico32xMem->sh2_rom_m.w; msh2.p_da = msh2.data_array;
  2145. ssh2.p_bios = Pico32xMem->sh2_rom_s.w; ssh2.p_da = ssh2.data_array;
  2146. sh2_drc_mem_setup(&msh2);
  2147. sh2_drc_mem_setup(&ssh2);
  2148. memset(sh2_poll_rd, 0, sizeof(sh2_poll_rd));
  2149. memset(sh2_poll_wr, 0, sizeof(sh2_poll_wr));
  2150. memset(sh2_poll_fifo, -1, sizeof(sh2_poll_fifo));
  2151. // z80 hack
  2152. z80_map_set(z80_write_map, 0x8000, 0xffff, z80_md_bank_write_32x, 1);
  2153. }
  2154. void p32x_update_banks(void)
  2155. {
  2156. bank_switch_rom_68k(Pico32x.regs[4 / 2]);
  2157. bank_switch_rom_sh2();
  2158. if (Pico32x.emu_flags & P32XF_DRC_ROM_C)
  2159. sh2_drc_flush_all();
  2160. }
  2161. void Pico32xMemStateLoaded(void)
  2162. {
  2163. bank_switch_rom_68k(Pico32x.regs[4 / 2]);
  2164. Pico32xSwapDRAM((Pico32x.vdp_regs[0x0a / 2] & P32XV_FS) ^ P32XV_FS);
  2165. memset(Pico32xMem->pwm, 0, sizeof(Pico32xMem->pwm));
  2166. Pico32x.dirty_pal = 1;
  2167. Pico32x.emu_flags &= ~(P32XF_68KCPOLL | P32XF_68KVPOLL);
  2168. memset(&m68k_poll, 0, sizeof(m68k_poll));
  2169. msh2.state = 0;
  2170. msh2.poll_addr = msh2.poll_cycles = msh2.poll_cnt = 0;
  2171. ssh2.state = 0;
  2172. ssh2.poll_addr = ssh2.poll_cycles = ssh2.poll_cnt = 0;
  2173. sh2_drc_flush_all();
  2174. }
  2175. // vim:shiftwidth=2:ts=2:expandtab