memory.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169
  1. /*
  2. * memory handling
  3. * (c) Copyright Dave, 2004
  4. * (C) notaz, 2006-2010
  5. *
  6. * This work is licensed under the terms of MAME license.
  7. * See COPYING file in the top-level directory.
  8. */
  9. #include "pico_int.h"
  10. #include "memory.h"
  11. #include "sound/ym2612.h"
  12. #include "sound/sn76496.h"
  13. extern unsigned int lastSSRamWrite; // used by serial eeprom code
  14. uptr m68k_read8_map [0x1000000 >> M68K_MEM_SHIFT];
  15. uptr m68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];
  16. uptr m68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
  17. uptr m68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
  18. static void xmap_set(uptr *map, int shift, int start_addr, int end_addr,
  19. const void *func_or_mh, int is_func)
  20. {
  21. uptr addr = (uptr)func_or_mh;
  22. int mask = (1 << shift) - 1;
  23. int i;
  24. if ((start_addr & mask) != 0 || (end_addr & mask) != mask) {
  25. elprintf(EL_STATUS|EL_ANOMALY, "xmap_set: tried to map bad range: %06x-%06x",
  26. start_addr, end_addr);
  27. return;
  28. }
  29. if (addr & 1) {
  30. elprintf(EL_STATUS|EL_ANOMALY, "xmap_set: ptr is not aligned: %08lx", addr);
  31. return;
  32. }
  33. if (!is_func)
  34. addr -= start_addr;
  35. for (i = start_addr >> shift; i <= end_addr >> shift; i++) {
  36. map[i] = addr >> 1;
  37. if (is_func)
  38. map[i] |= (uptr)1 << (sizeof(addr) * 8 - 1);
  39. }
  40. }
  41. void z80_map_set(uptr *map, int start_addr, int end_addr,
  42. const void *func_or_mh, int is_func)
  43. {
  44. xmap_set(map, Z80_MEM_SHIFT, start_addr, end_addr, func_or_mh, is_func);
  45. }
  46. void cpu68k_map_set(uptr *map, int start_addr, int end_addr,
  47. const void *func_or_mh, int is_func)
  48. {
  49. xmap_set(map, M68K_MEM_SHIFT, start_addr, end_addr, func_or_mh, is_func);
  50. }
  51. // more specialized/optimized function (does same as above)
  52. void cpu68k_map_all_ram(int start_addr, int end_addr, void *ptr, int is_sub)
  53. {
  54. uptr *r8map, *r16map, *w8map, *w16map;
  55. uptr addr = (uptr)ptr;
  56. int shift = M68K_MEM_SHIFT;
  57. int i;
  58. if (!is_sub) {
  59. r8map = m68k_read8_map;
  60. r16map = m68k_read16_map;
  61. w8map = m68k_write8_map;
  62. w16map = m68k_write16_map;
  63. } else {
  64. r8map = s68k_read8_map;
  65. r16map = s68k_read16_map;
  66. w8map = s68k_write8_map;
  67. w16map = s68k_write16_map;
  68. }
  69. addr -= start_addr;
  70. addr >>= 1;
  71. for (i = start_addr >> shift; i <= end_addr >> shift; i++)
  72. r8map[i] = r16map[i] = w8map[i] = w16map[i] = addr;
  73. }
  74. static u32 m68k_unmapped_read8(u32 a)
  75. {
  76. elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc);
  77. return 0; // assume pulldown, as if MegaCD2 was attached
  78. }
  79. static u32 m68k_unmapped_read16(u32 a)
  80. {
  81. elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc);
  82. return 0;
  83. }
  84. static void m68k_unmapped_write8(u32 a, u32 d)
  85. {
  86. elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
  87. }
  88. static void m68k_unmapped_write16(u32 a, u32 d)
  89. {
  90. elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
  91. }
  92. void m68k_map_unmap(int start_addr, int end_addr)
  93. {
  94. uptr addr;
  95. int shift = M68K_MEM_SHIFT;
  96. int i;
  97. addr = (uptr)m68k_unmapped_read8;
  98. for (i = start_addr >> shift; i <= end_addr >> shift; i++)
  99. m68k_read8_map[i] = (addr >> 1) | (1 << 31);
  100. addr = (uptr)m68k_unmapped_read16;
  101. for (i = start_addr >> shift; i <= end_addr >> shift; i++)
  102. m68k_read16_map[i] = (addr >> 1) | (1 << 31);
  103. addr = (uptr)m68k_unmapped_write8;
  104. for (i = start_addr >> shift; i <= end_addr >> shift; i++)
  105. m68k_write8_map[i] = (addr >> 1) | (1 << 31);
  106. addr = (uptr)m68k_unmapped_write16;
  107. for (i = start_addr >> shift; i <= end_addr >> shift; i++)
  108. m68k_write16_map[i] = (addr >> 1) | (1 << 31);
  109. }
  110. MAKE_68K_READ8(m68k_read8, m68k_read8_map)
  111. MAKE_68K_READ16(m68k_read16, m68k_read16_map)
  112. MAKE_68K_READ32(m68k_read32, m68k_read16_map)
  113. MAKE_68K_WRITE8(m68k_write8, m68k_write8_map)
  114. MAKE_68K_WRITE16(m68k_write16, m68k_write16_map)
  115. MAKE_68K_WRITE32(m68k_write32, m68k_write16_map)
  116. // -----------------------------------------------------------------
  117. static u32 ym2612_read_local_68k(void);
  118. static int ym2612_write_local(u32 a, u32 d, int is_from_z80);
  119. static void z80_mem_setup(void);
  120. #ifdef _ASM_MEMORY_C
  121. u32 PicoRead8_sram(u32 a);
  122. u32 PicoRead16_sram(u32 a);
  123. #endif
  124. #ifdef EMU_CORE_DEBUG
  125. u32 lastread_a, lastread_d[16]={0,}, lastwrite_cyc_d[16]={0,}, lastwrite_mus_d[16]={0,};
  126. int lrp_cyc=0, lrp_mus=0, lwp_cyc=0, lwp_mus=0;
  127. extern unsigned int ppop;
  128. #endif
  129. #ifdef IO_STATS
  130. void log_io(unsigned int addr, int bits, int rw);
  131. #elif defined(_MSC_VER)
  132. #define log_io
  133. #else
  134. #define log_io(...)
  135. #endif
  136. #if defined(EMU_C68K)
  137. void cyclone_crashed(u32 pc, struct Cyclone *context)
  138. {
  139. elprintf(EL_STATUS|EL_ANOMALY, "%c68k crash detected @ %06x",
  140. context == &PicoCpuCM68k ? 'm' : 's', pc);
  141. context->membase = (u32)Pico.rom;
  142. context->pc = (u32)Pico.rom + Pico.romsize;
  143. }
  144. #endif
  145. // -----------------------------------------------------------------
  146. // memmap helpers
  147. #ifndef _ASM_MEMORY_C
  148. static
  149. #endif
  150. int PadRead(int i)
  151. {
  152. int pad,value,data_reg;
  153. pad=~PicoPadInt[i]; // Get inverse of pad MXYZ SACB RLDU
  154. data_reg=Pico.ioports[i+1];
  155. // orr the bits, which are set as output
  156. value = data_reg&(Pico.ioports[i+4]|0x80);
  157. if (PicoOpt & POPT_6BTN_PAD)
  158. {
  159. int phase = Pico.m.padTHPhase[i];
  160. if(phase == 2 && !(data_reg&0x40)) { // TH
  161. value|=(pad&0xc0)>>2; // ?0SA 0000
  162. return value;
  163. } else if(phase == 3) {
  164. if(data_reg&0x40)
  165. value|=(pad&0x30)|((pad>>8)&0xf); // ?1CB MXYZ
  166. else
  167. value|=((pad&0xc0)>>2)|0x0f; // ?0SA 1111
  168. return value;
  169. }
  170. }
  171. if(data_reg&0x40) // TH
  172. value|=(pad&0x3f); // ?1CB RLDU
  173. else value|=((pad&0xc0)>>2)|(pad&3); // ?0SA 00DU
  174. return value; // will mirror later
  175. }
  176. #ifndef _ASM_MEMORY_C
  177. static u32 io_ports_read(u32 a)
  178. {
  179. u32 d;
  180. a = (a>>1) & 0xf;
  181. switch (a) {
  182. case 0: d = Pico.m.hardware; break; // Hardware value (Version register)
  183. case 1: d = PadRead(0); break;
  184. case 2: d = PadRead(1); break;
  185. default: d = Pico.ioports[a]; break; // IO ports can be used as RAM
  186. }
  187. return d;
  188. }
  189. static void NOINLINE io_ports_write(u32 a, u32 d)
  190. {
  191. a = (a>>1) & 0xf;
  192. // 6 button gamepad: if TH went from 0 to 1, gamepad changes state
  193. if (1 <= a && a <= 2 && (PicoOpt & POPT_6BTN_PAD))
  194. {
  195. Pico.m.padDelay[a - 1] = 0;
  196. if (!(Pico.ioports[a] & 0x40) && (d & 0x40))
  197. Pico.m.padTHPhase[a - 1]++;
  198. }
  199. // certain IO ports can be used as RAM
  200. Pico.ioports[a] = d;
  201. }
  202. #endif // _ASM_MEMORY_C
  203. void NOINLINE ctl_write_z80busreq(u32 d)
  204. {
  205. d&=1; d^=1;
  206. elprintf(EL_BUSREQ, "set_zrun: %i->%i [%i] @%06x", Pico.m.z80Run, d, SekCyclesDone(), SekPc);
  207. if (d ^ Pico.m.z80Run)
  208. {
  209. if (d)
  210. {
  211. z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone());
  212. }
  213. else
  214. {
  215. z80stopCycle = SekCyclesDone();
  216. if ((PicoOpt&POPT_EN_Z80) && !Pico.m.z80_reset) {
  217. pprof_start(m68k);
  218. PicoSyncZ80(z80stopCycle);
  219. pprof_end_sub(m68k);
  220. }
  221. }
  222. Pico.m.z80Run = d;
  223. }
  224. }
  225. void NOINLINE ctl_write_z80reset(u32 d)
  226. {
  227. d&=1; d^=1;
  228. elprintf(EL_BUSREQ, "set_zreset: %i->%i [%i] @%06x", Pico.m.z80_reset, d, SekCyclesDone(), SekPc);
  229. if (d ^ Pico.m.z80_reset)
  230. {
  231. if (d)
  232. {
  233. if ((PicoOpt&POPT_EN_Z80) && Pico.m.z80Run) {
  234. pprof_start(m68k);
  235. PicoSyncZ80(SekCyclesDone());
  236. pprof_end_sub(m68k);
  237. }
  238. YM2612ResetChip();
  239. timers_reset();
  240. }
  241. else
  242. {
  243. z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone());
  244. z80_reset();
  245. }
  246. Pico.m.z80_reset = d;
  247. }
  248. }
  249. // -----------------------------------------------------------------
  250. #ifndef _ASM_MEMORY_C
  251. // cart (save) RAM area (usually 0x200000 - ...)
  252. static u32 PicoRead8_sram(u32 a)
  253. {
  254. u32 d;
  255. if (SRam.start <= a && a <= SRam.end && (Pico.m.sram_reg & SRR_MAPPED))
  256. {
  257. if (SRam.flags & SRF_EEPROM) {
  258. d = EEPROM_read();
  259. if (!(a & 1))
  260. d >>= 8;
  261. } else
  262. d = *(u8 *)(SRam.data - SRam.start + a);
  263. elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc);
  264. return d;
  265. }
  266. // XXX: this is banking unfriendly
  267. if (a < Pico.romsize)
  268. return Pico.rom[a ^ 1];
  269. return m68k_unmapped_read8(a);
  270. }
  271. static u32 PicoRead16_sram(u32 a)
  272. {
  273. u32 d;
  274. if (SRam.start <= a && a <= SRam.end && (Pico.m.sram_reg & SRR_MAPPED))
  275. {
  276. if (SRam.flags & SRF_EEPROM)
  277. d = EEPROM_read();
  278. else {
  279. u8 *pm = (u8 *)(SRam.data - SRam.start + a);
  280. d = pm[0] << 8;
  281. d |= pm[1];
  282. }
  283. elprintf(EL_SRAMIO, "sram r16 [%06x] %04x @ %06x", a, d, SekPc);
  284. return d;
  285. }
  286. if (a < Pico.romsize)
  287. return *(u16 *)(Pico.rom + a);
  288. return m68k_unmapped_read16(a);
  289. }
  290. #endif // _ASM_MEMORY_C
  291. static void PicoWrite8_sram(u32 a, u32 d)
  292. {
  293. if (a > SRam.end || a < SRam.start || !(Pico.m.sram_reg & SRR_MAPPED)) {
  294. m68k_unmapped_write8(a, d);
  295. return;
  296. }
  297. elprintf(EL_SRAMIO, "sram w8 [%06x] %02x @ %06x", a, d & 0xff, SekPc);
  298. if (SRam.flags & SRF_EEPROM)
  299. {
  300. EEPROM_write8(a, d);
  301. }
  302. else {
  303. u8 *pm = (u8 *)(SRam.data - SRam.start + a);
  304. if (*pm != (u8)d) {
  305. SRam.changed = 1;
  306. *pm = (u8)d;
  307. }
  308. }
  309. }
  310. static void PicoWrite16_sram(u32 a, u32 d)
  311. {
  312. if (a > SRam.end || a < SRam.start || !(Pico.m.sram_reg & SRR_MAPPED)) {
  313. m68k_unmapped_write16(a, d);
  314. return;
  315. }
  316. elprintf(EL_SRAMIO, "sram w16 [%06x] %04x @ %06x", a, d & 0xffff, SekPc);
  317. if (SRam.flags & SRF_EEPROM)
  318. {
  319. EEPROM_write16(d);
  320. }
  321. else {
  322. // XXX: hardware could easily use MSB too..
  323. u8 *pm = (u8 *)(SRam.data - SRam.start + a);
  324. if (*pm != (u8)d) {
  325. SRam.changed = 1;
  326. *pm = (u8)d;
  327. }
  328. }
  329. }
  330. // z80 area (0xa00000 - 0xa0ffff)
  331. // TODO: verify mirrors VDP and bank reg (bank area mirroring verified)
  332. static u32 PicoRead8_z80(u32 a)
  333. {
  334. u32 d = 0xff;
  335. if ((Pico.m.z80Run & 1) || Pico.m.z80_reset) {
  336. elprintf(EL_ANOMALY, "68k z80 read with no bus! [%06x] @ %06x", a, SekPc);
  337. // open bus. Pulled down if MegaCD2 is attached.
  338. return 0;
  339. }
  340. if ((a & 0x4000) == 0x0000)
  341. d = Pico.zram[a & 0x1fff];
  342. else if ((a & 0x6000) == 0x4000) // 0x4000-0x5fff
  343. d = ym2612_read_local_68k();
  344. else
  345. elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc);
  346. return d;
  347. }
  348. static u32 PicoRead16_z80(u32 a)
  349. {
  350. u32 d = PicoRead8_z80(a);
  351. return d | (d << 8);
  352. }
  353. static void PicoWrite8_z80(u32 a, u32 d)
  354. {
  355. if ((Pico.m.z80Run & 1) || Pico.m.z80_reset) {
  356. // verified on real hw
  357. elprintf(EL_ANOMALY, "68k z80 write with no bus or reset! [%06x] %02x @ %06x", a, d&0xff, SekPc);
  358. return;
  359. }
  360. if ((a & 0x4000) == 0x0000) { // z80 RAM
  361. SekCyclesBurn(2); // hack
  362. Pico.zram[a & 0x1fff] = (u8)d;
  363. return;
  364. }
  365. if ((a & 0x6000) == 0x4000) { // FM Sound
  366. if (PicoOpt & POPT_EN_FM)
  367. emustatus |= ym2612_write_local(a&3, d&0xff, 0)&1;
  368. return;
  369. }
  370. // TODO: probably other VDP access too? Maybe more mirrors?
  371. if ((a & 0x7ff9) == 0x7f11) { // PSG Sound
  372. if (PicoOpt & POPT_EN_PSG)
  373. SN76496Write(d);
  374. return;
  375. }
  376. if ((a & 0x7f00) == 0x6000) // Z80 BANK register
  377. {
  378. Pico.m.z80_bank68k >>= 1;
  379. Pico.m.z80_bank68k |= d << 8;
  380. Pico.m.z80_bank68k &= 0x1ff; // 9 bits and filled in the new top one
  381. elprintf(EL_Z80BNK, "z80 bank=%06x", Pico.m.z80_bank68k << 15);
  382. return;
  383. }
  384. elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %02x @ %06x", a, d&0xff, SekPc);
  385. }
  386. static void PicoWrite16_z80(u32 a, u32 d)
  387. {
  388. // for RAM, only most significant byte is sent
  389. // TODO: verify remaining accesses
  390. PicoWrite8_z80(a, d >> 8);
  391. }
  392. #ifndef _ASM_MEMORY_C
  393. // IO/control area (0xa10000 - 0xa1ffff)
  394. u32 PicoRead8_io(u32 a)
  395. {
  396. u32 d;
  397. if ((a & 0xffe0) == 0x0000) { // I/O ports
  398. d = io_ports_read(a);
  399. goto end;
  400. }
  401. // faking open bus (MegaCD pulldowns don't work here curiously)
  402. d = Pico.m.rotate++;
  403. d ^= d << 6;
  404. if ((a & 0xfc00) == 0x1000) {
  405. // bit8 seems to be readable in this range
  406. if (!(a & 1))
  407. d &= ~0x01;
  408. if ((a & 0xff01) == 0x1100) { // z80 busreq (verified)
  409. d |= (Pico.m.z80Run | Pico.m.z80_reset) & 1;
  410. elprintf(EL_BUSREQ, "get_zrun: %02x [%i] @%06x", d, SekCyclesDone(), SekPc);
  411. }
  412. goto end;
  413. }
  414. if (PicoOpt & POPT_EN_32X) {
  415. d = PicoRead8_32x(a);
  416. goto end;
  417. }
  418. d = m68k_unmapped_read8(a);
  419. end:
  420. return d;
  421. }
  422. u32 PicoRead16_io(u32 a)
  423. {
  424. u32 d;
  425. if ((a & 0xffe0) == 0x0000) { // I/O ports
  426. d = io_ports_read(a);
  427. d |= d << 8;
  428. goto end;
  429. }
  430. // faking open bus
  431. d = (Pico.m.rotate += 0x41);
  432. d ^= (d << 5) ^ (d << 8);
  433. // bit8 seems to be readable in this range
  434. if ((a & 0xfc00) == 0x1000) {
  435. d &= ~0x0100;
  436. if ((a & 0xff00) == 0x1100) { // z80 busreq
  437. d |= ((Pico.m.z80Run | Pico.m.z80_reset) & 1) << 8;
  438. elprintf(EL_BUSREQ, "get_zrun: %04x [%i] @%06x", d, SekCyclesDone(), SekPc);
  439. }
  440. goto end;
  441. }
  442. if (PicoOpt & POPT_EN_32X) {
  443. d = PicoRead16_32x(a);
  444. goto end;
  445. }
  446. d = m68k_unmapped_read16(a);
  447. end:
  448. return d;
  449. }
  450. void PicoWrite8_io(u32 a, u32 d)
  451. {
  452. if ((a & 0xffe1) == 0x0001) { // I/O ports (verified: only LSB!)
  453. io_ports_write(a, d);
  454. return;
  455. }
  456. if ((a & 0xff01) == 0x1100) { // z80 busreq
  457. ctl_write_z80busreq(d);
  458. return;
  459. }
  460. if ((a & 0xff01) == 0x1200) { // z80 reset
  461. ctl_write_z80reset(d);
  462. return;
  463. }
  464. if (a == 0xa130f1) { // sram access register
  465. elprintf(EL_SRAMIO, "sram reg=%02x", d);
  466. Pico.m.sram_reg &= ~(SRR_MAPPED|SRR_READONLY);
  467. Pico.m.sram_reg |= (u8)(d & 3);
  468. return;
  469. }
  470. if (PicoOpt & POPT_EN_32X) {
  471. PicoWrite8_32x(a, d);
  472. return;
  473. }
  474. m68k_unmapped_write8(a, d);
  475. }
  476. void PicoWrite16_io(u32 a, u32 d)
  477. {
  478. if ((a & 0xffe0) == 0x0000) { // I/O ports (verified: only LSB!)
  479. io_ports_write(a, d);
  480. return;
  481. }
  482. if ((a & 0xff00) == 0x1100) { // z80 busreq
  483. ctl_write_z80busreq(d >> 8);
  484. return;
  485. }
  486. if ((a & 0xff00) == 0x1200) { // z80 reset
  487. ctl_write_z80reset(d >> 8);
  488. return;
  489. }
  490. if (a == 0xa130f0) { // sram access register
  491. elprintf(EL_SRAMIO, "sram reg=%02x", d);
  492. Pico.m.sram_reg &= ~(SRR_MAPPED|SRR_READONLY);
  493. Pico.m.sram_reg |= (u8)(d & 3);
  494. return;
  495. }
  496. if (PicoOpt & POPT_EN_32X) {
  497. PicoWrite16_32x(a, d);
  498. return;
  499. }
  500. m68k_unmapped_write16(a, d);
  501. }
  502. #endif // _ASM_MEMORY_C
  503. // VDP area (0xc00000 - 0xdfffff)
  504. // TODO: verify if lower byte goes to PSG on word writes
  505. static u32 PicoRead8_vdp(u32 a)
  506. {
  507. if ((a & 0x00e0) == 0x0000)
  508. return PicoVideoRead8(a);
  509. elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc);
  510. return 0;
  511. }
  512. static u32 PicoRead16_vdp(u32 a)
  513. {
  514. if ((a & 0x00e0) == 0x0000)
  515. return PicoVideoRead(a);
  516. elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc);
  517. return 0;
  518. }
  519. static void PicoWrite8_vdp(u32 a, u32 d)
  520. {
  521. if ((a & 0x00f9) == 0x0011) { // PSG Sound
  522. if (PicoOpt & POPT_EN_PSG)
  523. SN76496Write(d);
  524. return;
  525. }
  526. if ((a & 0x00e0) == 0x0000) {
  527. d &= 0xff;
  528. PicoVideoWrite(a, d | (d << 8));
  529. return;
  530. }
  531. elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %02x @%06x", a, d & 0xff, SekPc);
  532. }
  533. static void PicoWrite16_vdp(u32 a, u32 d)
  534. {
  535. if ((a & 0x00f9) == 0x0010) { // PSG Sound
  536. if (PicoOpt & POPT_EN_PSG)
  537. SN76496Write(d);
  538. return;
  539. }
  540. if ((a & 0x00e0) == 0x0000) {
  541. PicoVideoWrite(a, d);
  542. return;
  543. }
  544. elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %04x @%06x", a, d & 0xffff, SekPc);
  545. }
  546. // -----------------------------------------------------------------
  547. #ifdef EMU_M68K
  548. static void m68k_mem_setup(void);
  549. #endif
  550. PICO_INTERNAL void PicoMemSetup(void)
  551. {
  552. int mask, rs, a;
  553. // setup the memory map
  554. cpu68k_map_set(m68k_read8_map, 0x000000, 0xffffff, m68k_unmapped_read8, 1);
  555. cpu68k_map_set(m68k_read16_map, 0x000000, 0xffffff, m68k_unmapped_read16, 1);
  556. cpu68k_map_set(m68k_write8_map, 0x000000, 0xffffff, m68k_unmapped_write8, 1);
  557. cpu68k_map_set(m68k_write16_map, 0x000000, 0xffffff, m68k_unmapped_write16, 1);
  558. // ROM
  559. // align to bank size. We know ROM loader allocated enough for this
  560. mask = (1 << M68K_MEM_SHIFT) - 1;
  561. rs = (Pico.romsize + mask) & ~mask;
  562. cpu68k_map_set(m68k_read8_map, 0x000000, rs - 1, Pico.rom, 0);
  563. cpu68k_map_set(m68k_read16_map, 0x000000, rs - 1, Pico.rom, 0);
  564. // Common case of on-cart (save) RAM, usually at 0x200000-...
  565. if ((SRam.flags & SRF_ENABLED) && SRam.data != NULL) {
  566. rs = SRam.end - SRam.start;
  567. rs = (rs + mask) & ~mask;
  568. if (SRam.start + rs >= 0x1000000)
  569. rs = 0x1000000 - SRam.start;
  570. cpu68k_map_set(m68k_read8_map, SRam.start, SRam.start + rs - 1, PicoRead8_sram, 1);
  571. cpu68k_map_set(m68k_read16_map, SRam.start, SRam.start + rs - 1, PicoRead16_sram, 1);
  572. cpu68k_map_set(m68k_write8_map, SRam.start, SRam.start + rs - 1, PicoWrite8_sram, 1);
  573. cpu68k_map_set(m68k_write16_map, SRam.start, SRam.start + rs - 1, PicoWrite16_sram, 1);
  574. }
  575. // Z80 region
  576. cpu68k_map_set(m68k_read8_map, 0xa00000, 0xa0ffff, PicoRead8_z80, 1);
  577. cpu68k_map_set(m68k_read16_map, 0xa00000, 0xa0ffff, PicoRead16_z80, 1);
  578. cpu68k_map_set(m68k_write8_map, 0xa00000, 0xa0ffff, PicoWrite8_z80, 1);
  579. cpu68k_map_set(m68k_write16_map, 0xa00000, 0xa0ffff, PicoWrite16_z80, 1);
  580. // IO/control region
  581. cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoRead8_io, 1);
  582. cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoRead16_io, 1);
  583. cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWrite8_io, 1);
  584. cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_io, 1);
  585. // VDP region
  586. for (a = 0xc00000; a < 0xe00000; a += 0x010000) {
  587. if ((a & 0xe700e0) != 0xc00000)
  588. continue;
  589. cpu68k_map_set(m68k_read8_map, a, a + 0xffff, PicoRead8_vdp, 1);
  590. cpu68k_map_set(m68k_read16_map, a, a + 0xffff, PicoRead16_vdp, 1);
  591. cpu68k_map_set(m68k_write8_map, a, a + 0xffff, PicoWrite8_vdp, 1);
  592. cpu68k_map_set(m68k_write16_map, a, a + 0xffff, PicoWrite16_vdp, 1);
  593. }
  594. // RAM and it's mirrors
  595. for (a = 0xe00000; a < 0x1000000; a += 0x010000) {
  596. cpu68k_map_set(m68k_read8_map, a, a + 0xffff, Pico.ram, 0);
  597. cpu68k_map_set(m68k_read16_map, a, a + 0xffff, Pico.ram, 0);
  598. cpu68k_map_set(m68k_write8_map, a, a + 0xffff, Pico.ram, 0);
  599. cpu68k_map_set(m68k_write16_map, a, a + 0xffff, Pico.ram, 0);
  600. }
  601. // Setup memory callbacks:
  602. #ifdef EMU_C68K
  603. PicoCpuCM68k.read8 = (void *)m68k_read8_map;
  604. PicoCpuCM68k.read16 = (void *)m68k_read16_map;
  605. PicoCpuCM68k.read32 = (void *)m68k_read16_map;
  606. PicoCpuCM68k.write8 = (void *)m68k_write8_map;
  607. PicoCpuCM68k.write16 = (void *)m68k_write16_map;
  608. PicoCpuCM68k.write32 = (void *)m68k_write16_map;
  609. PicoCpuCM68k.checkpc = NULL; /* unused */
  610. PicoCpuCM68k.fetch8 = NULL;
  611. PicoCpuCM68k.fetch16 = NULL;
  612. PicoCpuCM68k.fetch32 = NULL;
  613. #endif
  614. #ifdef EMU_F68K
  615. PicoCpuFM68k.read_byte = m68k_read8;
  616. PicoCpuFM68k.read_word = m68k_read16;
  617. PicoCpuFM68k.read_long = m68k_read32;
  618. PicoCpuFM68k.write_byte = m68k_write8;
  619. PicoCpuFM68k.write_word = m68k_write16;
  620. PicoCpuFM68k.write_long = m68k_write32;
  621. // setup FAME fetchmap
  622. {
  623. int i;
  624. // by default, point everything to first 64k of ROM
  625. for (i = 0; i < M68K_FETCHBANK1; i++)
  626. PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom - (i<<(24-FAMEC_FETCHBITS));
  627. // now real ROM
  628. for (i = 0; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < Pico.romsize; i++)
  629. PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom;
  630. // .. and RAM
  631. for (i = M68K_FETCHBANK1*14/16; i < M68K_FETCHBANK1; i++)
  632. PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.ram - (i<<(24-FAMEC_FETCHBITS));
  633. }
  634. #endif
  635. #ifdef EMU_M68K
  636. m68k_mem_setup();
  637. #endif
  638. z80_mem_setup();
  639. }
  640. #ifdef EMU_M68K
  641. unsigned int (*pm68k_read_memory_8) (unsigned int address) = NULL;
  642. unsigned int (*pm68k_read_memory_16)(unsigned int address) = NULL;
  643. unsigned int (*pm68k_read_memory_32)(unsigned int address) = NULL;
  644. void (*pm68k_write_memory_8) (unsigned int address, unsigned char value) = NULL;
  645. void (*pm68k_write_memory_16)(unsigned int address, unsigned short value) = NULL;
  646. void (*pm68k_write_memory_32)(unsigned int address, unsigned int value) = NULL;
  647. /* it appears that Musashi doesn't always mask the unused bits */
  648. unsigned int m68k_read_memory_8 (unsigned int address) { return pm68k_read_memory_8 (address) & 0xff; }
  649. unsigned int m68k_read_memory_16(unsigned int address) { return pm68k_read_memory_16(address) & 0xffff; }
  650. unsigned int m68k_read_memory_32(unsigned int address) { return pm68k_read_memory_32(address); }
  651. void m68k_write_memory_8 (unsigned int address, unsigned int value) { pm68k_write_memory_8 (address, (u8)value); }
  652. void m68k_write_memory_16(unsigned int address, unsigned int value) { pm68k_write_memory_16(address,(u16)value); }
  653. void m68k_write_memory_32(unsigned int address, unsigned int value) { pm68k_write_memory_32(address, value); }
  654. static void m68k_mem_setup(void)
  655. {
  656. pm68k_read_memory_8 = m68k_read8;
  657. pm68k_read_memory_16 = m68k_read16;
  658. pm68k_read_memory_32 = m68k_read32;
  659. pm68k_write_memory_8 = m68k_write8;
  660. pm68k_write_memory_16 = m68k_write16;
  661. pm68k_write_memory_32 = m68k_write32;
  662. }
  663. #endif // EMU_M68K
  664. // -----------------------------------------------------------------
  665. static int get_scanline(int is_from_z80)
  666. {
  667. if (is_from_z80) {
  668. int cycles = z80_cyclesDone();
  669. while (cycles - z80_scanline_cycles >= 228)
  670. z80_scanline++, z80_scanline_cycles += 228;
  671. return z80_scanline;
  672. }
  673. return Pico.m.scanline;
  674. }
  675. /* probably should not be in this file, but it's near related code here */
  676. void ym2612_sync_timers(int z80_cycles, int mode_old, int mode_new)
  677. {
  678. int xcycles = z80_cycles << 8;
  679. /* check for overflows */
  680. if ((mode_old & 4) && xcycles > timer_a_next_oflow)
  681. ym2612.OPN.ST.status |= 1;
  682. if ((mode_old & 8) && xcycles > timer_b_next_oflow)
  683. ym2612.OPN.ST.status |= 2;
  684. /* update timer a */
  685. if (mode_old & 1)
  686. while (xcycles > timer_a_next_oflow)
  687. timer_a_next_oflow += timer_a_step;
  688. if ((mode_old ^ mode_new) & 1) // turning on/off
  689. {
  690. if (mode_old & 1)
  691. timer_a_next_oflow = TIMER_NO_OFLOW;
  692. else
  693. timer_a_next_oflow = xcycles + timer_a_step;
  694. }
  695. if (mode_new & 1)
  696. elprintf(EL_YMTIMER, "timer a upd to %i @ %i", timer_a_next_oflow>>8, z80_cycles);
  697. /* update timer b */
  698. if (mode_old & 2)
  699. while (xcycles > timer_b_next_oflow)
  700. timer_b_next_oflow += timer_b_step;
  701. if ((mode_old ^ mode_new) & 2)
  702. {
  703. if (mode_old & 2)
  704. timer_b_next_oflow = TIMER_NO_OFLOW;
  705. else
  706. timer_b_next_oflow = xcycles + timer_b_step;
  707. }
  708. if (mode_new & 2)
  709. elprintf(EL_YMTIMER, "timer b upd to %i @ %i", timer_b_next_oflow>>8, z80_cycles);
  710. }
  711. // ym2612 DAC and timer I/O handlers for z80
  712. static int ym2612_write_local(u32 a, u32 d, int is_from_z80)
  713. {
  714. int addr;
  715. a &= 3;
  716. if (a == 1 && ym2612.OPN.ST.address == 0x2a) /* DAC data */
  717. {
  718. int scanline = get_scanline(is_from_z80);
  719. //elprintf(EL_STATUS, "%03i -> %03i dac w %08x z80 %i", PsndDacLine, scanline, d, is_from_z80);
  720. ym2612.dacout = ((int)d - 0x80) << 6;
  721. if (PsndOut && ym2612.dacen && scanline >= PsndDacLine)
  722. PsndDoDAC(scanline);
  723. return 0;
  724. }
  725. switch (a)
  726. {
  727. case 0: /* address port 0 */
  728. ym2612.OPN.ST.address = d;
  729. ym2612.addr_A1 = 0;
  730. #ifdef __GP2X__
  731. if (PicoOpt & POPT_EXT_FM) YM2612Write_940(a, d, -1);
  732. #endif
  733. return 0;
  734. case 1: /* data port 0 */
  735. if (ym2612.addr_A1 != 0)
  736. return 0;
  737. addr = ym2612.OPN.ST.address;
  738. ym2612.REGS[addr] = d;
  739. switch (addr)
  740. {
  741. case 0x24: // timer A High 8
  742. case 0x25: { // timer A Low 2
  743. int TAnew = (addr == 0x24) ? ((ym2612.OPN.ST.TA & 0x03)|(((int)d)<<2))
  744. : ((ym2612.OPN.ST.TA & 0x3fc)|(d&3));
  745. if (ym2612.OPN.ST.TA != TAnew)
  746. {
  747. //elprintf(EL_STATUS, "timer a set %i", TAnew);
  748. ym2612.OPN.ST.TA = TAnew;
  749. //ym2612.OPN.ST.TAC = (1024-TAnew)*18;
  750. //ym2612.OPN.ST.TAT = 0;
  751. timer_a_step = TIMER_A_TICK_ZCYCLES * (1024 - TAnew);
  752. if (ym2612.OPN.ST.mode & 1) {
  753. // this is not right, should really be done on overflow only
  754. int cycles = is_from_z80 ? z80_cyclesDone() : cycles_68k_to_z80(SekCyclesDone());
  755. timer_a_next_oflow = (cycles << 8) + timer_a_step;
  756. }
  757. elprintf(EL_YMTIMER, "timer a set to %i, %i", 1024 - TAnew, timer_a_next_oflow>>8);
  758. }
  759. return 0;
  760. }
  761. case 0x26: // timer B
  762. if (ym2612.OPN.ST.TB != d) {
  763. //elprintf(EL_STATUS, "timer b set %i", d);
  764. ym2612.OPN.ST.TB = d;
  765. //ym2612.OPN.ST.TBC = (256-d) * 288;
  766. //ym2612.OPN.ST.TBT = 0;
  767. timer_b_step = TIMER_B_TICK_ZCYCLES * (256 - d); // 262800
  768. if (ym2612.OPN.ST.mode & 2) {
  769. int cycles = is_from_z80 ? z80_cyclesDone() : cycles_68k_to_z80(SekCyclesDone());
  770. timer_b_next_oflow = (cycles << 8) + timer_b_step;
  771. }
  772. elprintf(EL_YMTIMER, "timer b set to %i, %i", 256 - d, timer_b_next_oflow>>8);
  773. }
  774. return 0;
  775. case 0x27: { /* mode, timer control */
  776. int old_mode = ym2612.OPN.ST.mode;
  777. int cycles = is_from_z80 ? z80_cyclesDone() : cycles_68k_to_z80(SekCyclesDone());
  778. ym2612.OPN.ST.mode = d;
  779. elprintf(EL_YMTIMER, "st mode %02x", d);
  780. ym2612_sync_timers(cycles, old_mode, d);
  781. /* reset Timer a flag */
  782. if (d & 0x10)
  783. ym2612.OPN.ST.status &= ~1;
  784. /* reset Timer b flag */
  785. if (d & 0x20)
  786. ym2612.OPN.ST.status &= ~2;
  787. if ((d ^ old_mode) & 0xc0) {
  788. #ifdef __GP2X__
  789. if (PicoOpt & POPT_EXT_FM) return YM2612Write_940(a, d, get_scanline(is_from_z80));
  790. #endif
  791. return 1;
  792. }
  793. return 0;
  794. }
  795. case 0x2b: { /* DAC Sel (YM2612) */
  796. int scanline = get_scanline(is_from_z80);
  797. ym2612.dacen = d & 0x80;
  798. if (d & 0x80) PsndDacLine = scanline;
  799. #ifdef __GP2X__
  800. if (PicoOpt & POPT_EXT_FM) YM2612Write_940(a, d, scanline);
  801. #endif
  802. return 0;
  803. }
  804. }
  805. break;
  806. case 2: /* address port 1 */
  807. ym2612.OPN.ST.address = d;
  808. ym2612.addr_A1 = 1;
  809. #ifdef __GP2X__
  810. if (PicoOpt & POPT_EXT_FM) YM2612Write_940(a, d, -1);
  811. #endif
  812. return 0;
  813. case 3: /* data port 1 */
  814. if (ym2612.addr_A1 != 1)
  815. return 0;
  816. addr = ym2612.OPN.ST.address | 0x100;
  817. ym2612.REGS[addr] = d;
  818. break;
  819. }
  820. #ifdef __GP2X__
  821. if (PicoOpt & POPT_EXT_FM)
  822. return YM2612Write_940(a, d, get_scanline(is_from_z80));
  823. #endif
  824. return YM2612Write_(a, d);
  825. }
  826. #define ym2612_read_local() \
  827. if (xcycles >= timer_a_next_oflow) \
  828. ym2612.OPN.ST.status |= (ym2612.OPN.ST.mode >> 2) & 1; \
  829. if (xcycles >= timer_b_next_oflow) \
  830. ym2612.OPN.ST.status |= (ym2612.OPN.ST.mode >> 2) & 2
  831. static u32 ym2612_read_local_z80(void)
  832. {
  833. int xcycles = z80_cyclesDone() << 8;
  834. ym2612_read_local();
  835. elprintf(EL_YMTIMER, "timer z80 read %i, sched %i, %i @ %i|%i", ym2612.OPN.ST.status,
  836. timer_a_next_oflow>>8, timer_b_next_oflow>>8, xcycles >> 8, (xcycles >> 8) / 228);
  837. return ym2612.OPN.ST.status;
  838. }
  839. static u32 ym2612_read_local_68k(void)
  840. {
  841. int xcycles = cycles_68k_to_z80(SekCyclesDone()) << 8;
  842. ym2612_read_local();
  843. elprintf(EL_YMTIMER, "timer 68k read %i, sched %i, %i @ %i|%i", ym2612.OPN.ST.status,
  844. timer_a_next_oflow>>8, timer_b_next_oflow>>8, xcycles >> 8, (xcycles >> 8) / 228);
  845. return ym2612.OPN.ST.status;
  846. }
  847. void ym2612_pack_state(void)
  848. {
  849. // timers are saved as tick counts, in 16.16 int format
  850. int tac, tat = 0, tbc, tbt = 0;
  851. tac = 1024 - ym2612.OPN.ST.TA;
  852. tbc = 256 - ym2612.OPN.ST.TB;
  853. if (timer_a_next_oflow != TIMER_NO_OFLOW)
  854. tat = (int)((double)(timer_a_step - timer_a_next_oflow) / (double)timer_a_step * tac * 65536);
  855. if (timer_b_next_oflow != TIMER_NO_OFLOW)
  856. tbt = (int)((double)(timer_b_step - timer_b_next_oflow) / (double)timer_b_step * tbc * 65536);
  857. elprintf(EL_YMTIMER, "save: timer a %i/%i", tat >> 16, tac);
  858. elprintf(EL_YMTIMER, "save: timer b %i/%i", tbt >> 16, tbc);
  859. #ifdef __GP2X__
  860. if (PicoOpt & POPT_EXT_FM)
  861. YM2612PicoStateSave2_940(tat, tbt);
  862. else
  863. #endif
  864. YM2612PicoStateSave2(tat, tbt);
  865. }
  866. void ym2612_unpack_state(void)
  867. {
  868. int i, ret, tac, tat, tbc, tbt;
  869. YM2612PicoStateLoad();
  870. // feed all the registers and update internal state
  871. for (i = 0x20; i < 0xA0; i++) {
  872. ym2612_write_local(0, i, 0);
  873. ym2612_write_local(1, ym2612.REGS[i], 0);
  874. }
  875. for (i = 0x30; i < 0xA0; i++) {
  876. ym2612_write_local(2, i, 0);
  877. ym2612_write_local(3, ym2612.REGS[i|0x100], 0);
  878. }
  879. for (i = 0xAF; i >= 0xA0; i--) { // must apply backwards
  880. ym2612_write_local(2, i, 0);
  881. ym2612_write_local(3, ym2612.REGS[i|0x100], 0);
  882. ym2612_write_local(0, i, 0);
  883. ym2612_write_local(1, ym2612.REGS[i], 0);
  884. }
  885. for (i = 0xB0; i < 0xB8; i++) {
  886. ym2612_write_local(0, i, 0);
  887. ym2612_write_local(1, ym2612.REGS[i], 0);
  888. ym2612_write_local(2, i, 0);
  889. ym2612_write_local(3, ym2612.REGS[i|0x100], 0);
  890. }
  891. #ifdef __GP2X__
  892. if (PicoOpt & POPT_EXT_FM)
  893. ret = YM2612PicoStateLoad2_940(&tat, &tbt);
  894. else
  895. #endif
  896. ret = YM2612PicoStateLoad2(&tat, &tbt);
  897. if (ret != 0) {
  898. elprintf(EL_STATUS, "old ym2612 state");
  899. return; // no saved timers
  900. }
  901. tac = (1024 - ym2612.OPN.ST.TA) << 16;
  902. tbc = (256 - ym2612.OPN.ST.TB) << 16;
  903. if (ym2612.OPN.ST.mode & 1)
  904. timer_a_next_oflow = (int)((double)(tac - tat) / (double)tac * timer_a_step);
  905. else
  906. timer_a_next_oflow = TIMER_NO_OFLOW;
  907. if (ym2612.OPN.ST.mode & 2)
  908. timer_b_next_oflow = (int)((double)(tbc - tbt) / (double)tbc * timer_b_step);
  909. else
  910. timer_b_next_oflow = TIMER_NO_OFLOW;
  911. elprintf(EL_YMTIMER, "load: %i/%i, timer_a_next_oflow %i", tat>>16, tac>>16, timer_a_next_oflow >> 8);
  912. elprintf(EL_YMTIMER, "load: %i/%i, timer_b_next_oflow %i", tbt>>16, tbc>>16, timer_b_next_oflow >> 8);
  913. }
  914. #if defined(NO_32X) && defined(_ASM_MEMORY_C)
  915. // referenced by asm code
  916. u32 PicoRead8_32x(u32 a) { return 0; }
  917. u32 PicoRead16_32x(u32 a) { return 0; }
  918. void PicoWrite8_32x(u32 a, u32 d) {}
  919. void PicoWrite16_32x(u32 a, u32 d) {}
  920. #endif
  921. // -----------------------------------------------------------------
  922. // z80 memhandlers
  923. static unsigned char z80_md_vdp_read(unsigned short a)
  924. {
  925. // TODO?
  926. elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, 0xff);
  927. return 0xff;
  928. }
  929. static unsigned char z80_md_bank_read(unsigned short a)
  930. {
  931. unsigned int addr68k;
  932. unsigned char ret;
  933. addr68k = Pico.m.z80_bank68k<<15;
  934. addr68k += a & 0x7fff;
  935. ret = m68k_read8(addr68k);
  936. elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret);
  937. return ret;
  938. }
  939. static void z80_md_ym2612_write(unsigned int a, unsigned char data)
  940. {
  941. if (PicoOpt & POPT_EN_FM)
  942. emustatus |= ym2612_write_local(a, data, 1) & 1;
  943. }
  944. static void z80_md_vdp_br_write(unsigned int a, unsigned char data)
  945. {
  946. // TODO: allow full VDP access
  947. if ((a&0xfff9) == 0x7f11) // 7f11 7f13 7f15 7f17
  948. {
  949. if (PicoOpt & POPT_EN_PSG)
  950. SN76496Write(data);
  951. return;
  952. }
  953. if ((a>>8) == 0x60)
  954. {
  955. Pico.m.z80_bank68k >>= 1;
  956. Pico.m.z80_bank68k |= data << 8;
  957. Pico.m.z80_bank68k &= 0x1ff; // 9 bits and filled in the new top one
  958. return;
  959. }
  960. elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data);
  961. }
  962. static void z80_md_bank_write(unsigned int a, unsigned char data)
  963. {
  964. unsigned int addr68k;
  965. addr68k = Pico.m.z80_bank68k << 15;
  966. addr68k += a & 0x7fff;
  967. elprintf(EL_Z80BNK, "z80->68k w8 [%06x] %02x", addr68k, data);
  968. m68k_write8(addr68k, data);
  969. }
  970. // -----------------------------------------------------------------
  971. static unsigned char z80_md_in(unsigned short p)
  972. {
  973. elprintf(EL_ANOMALY, "Z80 port %04x read", p);
  974. return 0xff;
  975. }
  976. static void z80_md_out(unsigned short p, unsigned char d)
  977. {
  978. elprintf(EL_ANOMALY, "Z80 port %04x write %02x", p, d);
  979. }
  980. static void z80_mem_setup(void)
  981. {
  982. z80_map_set(z80_read_map, 0x0000, 0x1fff, Pico.zram, 0);
  983. z80_map_set(z80_read_map, 0x2000, 0x3fff, Pico.zram, 0);
  984. z80_map_set(z80_read_map, 0x4000, 0x5fff, ym2612_read_local_z80, 1);
  985. z80_map_set(z80_read_map, 0x6000, 0x7fff, z80_md_vdp_read, 1);
  986. z80_map_set(z80_read_map, 0x8000, 0xffff, z80_md_bank_read, 1);
  987. z80_map_set(z80_write_map, 0x0000, 0x1fff, Pico.zram, 0);
  988. z80_map_set(z80_write_map, 0x2000, 0x3fff, Pico.zram, 0);
  989. z80_map_set(z80_write_map, 0x4000, 0x5fff, z80_md_ym2612_write, 1);
  990. z80_map_set(z80_write_map, 0x6000, 0x7fff, z80_md_vdp_br_write, 1);
  991. z80_map_set(z80_write_map, 0x8000, 0xffff, z80_md_bank_write, 1);
  992. #ifdef _USE_DRZ80
  993. drZ80.z80_in = z80_md_in;
  994. drZ80.z80_out = z80_md_out;
  995. #endif
  996. #ifdef _USE_CZ80
  997. Cz80_Set_Fetch(&CZ80, 0x0000, 0x1fff, (FPTR)Pico.zram); // main RAM
  998. Cz80_Set_Fetch(&CZ80, 0x2000, 0x3fff, (FPTR)Pico.zram); // mirror
  999. Cz80_Set_INPort(&CZ80, z80_md_in);
  1000. Cz80_Set_OUTPort(&CZ80, z80_md_out);
  1001. #endif
  1002. }