memory.c 65 KB

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