Memory.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070
  1. // This is part of Pico Library
  2. // (c) Copyright 2004 Dave, All rights reserved.
  3. // (c) Copyright 2006,2007 notaz, All rights reserved.
  4. // Free for non-commercial use.
  5. // For commercial use, separate licencing terms must be obtained.
  6. #include "PicoInt.h"
  7. #include "sound/ym2612.h"
  8. #include "sound/sn76496.h"
  9. #ifndef UTYPES_DEFINED
  10. typedef unsigned char u8;
  11. typedef unsigned short u16;
  12. typedef unsigned int u32;
  13. #define UTYPES_DEFINED
  14. #endif
  15. extern unsigned int lastSSRamWrite; // used by serial SRAM code
  16. #ifdef _ASM_MEMORY_C
  17. u32 PicoRead8(u32 a);
  18. u32 PicoRead16(u32 a);
  19. void PicoWrite8(u32 a,u8 d);
  20. void PicoWriteRomHW_SSF2(u32 a,u32 d);
  21. #endif
  22. #ifdef EMU_CORE_DEBUG
  23. u32 lastread_a, lastread_d[16]={0,}, lastwrite_cyc_d[16]={0,}, lastwrite_mus_d[16]={0,};
  24. int lrp_cyc=0, lrp_mus=0, lwp_cyc=0, lwp_mus=0;
  25. extern unsigned int ppop;
  26. #endif
  27. #ifdef IO_STATS
  28. void log_io(unsigned int addr, int bits, int rw);
  29. #elif defined(_MSC_VER)
  30. #define log_io
  31. #else
  32. #define log_io(...)
  33. #endif
  34. #if defined(EMU_C68K)
  35. static __inline int PicoMemBase(u32 pc)
  36. {
  37. int membase=0;
  38. if (pc<Pico.romsize+4)
  39. {
  40. membase=(int)Pico.rom; // Program Counter in Rom
  41. }
  42. else if ((pc&0xe00000)==0xe00000)
  43. {
  44. membase=(int)Pico.ram-(pc&0xff0000); // Program Counter in Ram
  45. }
  46. else
  47. {
  48. // Error - Program Counter is invalid
  49. membase=(int)Pico.rom;
  50. }
  51. return membase;
  52. }
  53. #endif
  54. PICO_INTERNAL u32 PicoCheckPc(u32 pc)
  55. {
  56. u32 ret=0;
  57. #if defined(EMU_C68K)
  58. pc-=PicoCpuCM68k.membase; // Get real pc
  59. // pc&=0xfffffe;
  60. pc&=~1;
  61. if ((pc<<8) == 0)
  62. {
  63. printf("%i:%03i: game crash detected @ %06x\n", Pico.m.frame_count, Pico.m.scanline, SekPc);
  64. return (int)Pico.rom + Pico.romsize; // common crash condition, can happen if acc timing is off
  65. }
  66. PicoCpuCM68k.membase=PicoMemBase(pc&0x00ffffff);
  67. PicoCpuCM68k.membase-=pc&0xff000000;
  68. ret = PicoCpuCM68k.membase+pc;
  69. #endif
  70. return ret;
  71. }
  72. PICO_INTERNAL void PicoInitPc(u32 pc)
  73. {
  74. PicoCheckPc(pc);
  75. }
  76. #ifndef _ASM_MEMORY_C
  77. PICO_INTERNAL_ASM void PicoMemReset(void)
  78. {
  79. }
  80. #endif
  81. // -----------------------------------------------------------------
  82. int PadRead(int i)
  83. {
  84. int pad,value,data_reg;
  85. pad=~PicoPadInt[i]; // Get inverse of pad MXYZ SACB RLDU
  86. data_reg=Pico.ioports[i+1];
  87. // orr the bits, which are set as output
  88. value = data_reg&(Pico.ioports[i+4]|0x80);
  89. if (PicoOpt & POPT_6BTN_PAD)
  90. {
  91. int phase = Pico.m.padTHPhase[i];
  92. if(phase == 2 && !(data_reg&0x40)) { // TH
  93. value|=(pad&0xc0)>>2; // ?0SA 0000
  94. return value;
  95. } else if(phase == 3) {
  96. if(data_reg&0x40)
  97. value|=(pad&0x30)|((pad>>8)&0xf); // ?1CB MXYZ
  98. else
  99. value|=((pad&0xc0)>>2)|0x0f; // ?0SA 1111
  100. return value;
  101. }
  102. }
  103. if(data_reg&0x40) // TH
  104. value|=(pad&0x3f); // ?1CB RLDU
  105. else value|=((pad&0xc0)>>2)|(pad&3); // ?0SA 00DU
  106. return value; // will mirror later
  107. }
  108. #ifndef _ASM_MEMORY_C
  109. static
  110. #endif
  111. u32 SRAMRead(u32 a)
  112. {
  113. unsigned int sreg = Pico.m.sram_reg;
  114. if (!(sreg & 0x10) && (sreg & 1) && a > 0x200001) { // not yet detected SRAM
  115. elprintf(EL_SRAMIO, "normal sram detected.");
  116. Pico.m.sram_reg|=0x10; // should be normal SRAM
  117. }
  118. if (sreg & 4) // EEPROM read
  119. return SRAMReadEEPROM();
  120. else // if(sreg & 1) // (sreg&5) is one of prerequisites
  121. return *(u8 *)(SRam.data-SRam.start+a);
  122. }
  123. #ifndef _ASM_MEMORY_C
  124. static
  125. #endif
  126. u32 SRAMRead16(u32 a)
  127. {
  128. u32 d;
  129. if (Pico.m.sram_reg & 4) {
  130. d = SRAMReadEEPROM();
  131. d |= d << 8;
  132. } else {
  133. u8 *pm=(u8 *)(SRam.data-SRam.start+a);
  134. d =*pm++ << 8;
  135. d|=*pm++;
  136. }
  137. return d;
  138. }
  139. static void SRAMWrite(u32 a, u32 d)
  140. {
  141. unsigned int sreg = Pico.m.sram_reg;
  142. if(!(sreg & 0x10)) {
  143. // not detected SRAM
  144. if((a&~1)==0x200000) {
  145. elprintf(EL_SRAMIO, "eeprom detected.");
  146. sreg|=4; // this should be a game with EEPROM (like NBA Jam)
  147. SRam.start=0x200000; SRam.end=SRam.start+1;
  148. } else
  149. elprintf(EL_SRAMIO, "normal sram detected.");
  150. sreg|=0x10;
  151. Pico.m.sram_reg=sreg;
  152. }
  153. if(sreg & 4) { // EEPROM write
  154. // this diff must be at most 16 for NBA Jam to work
  155. if(SekCyclesDoneT()-lastSSRamWrite < 16) {
  156. // just update pending state
  157. elprintf(EL_EEPROM, "eeprom: skip because cycles=%i", SekCyclesDoneT()-lastSSRamWrite);
  158. SRAMUpdPending(a, d);
  159. } else {
  160. int old=sreg;
  161. SRAMWriteEEPROM(sreg>>6); // execute pending
  162. SRAMUpdPending(a, d);
  163. if ((old^Pico.m.sram_reg)&0xc0) // update time only if SDA/SCL changed
  164. lastSSRamWrite = SekCyclesDoneT();
  165. }
  166. } else if(!(sreg & 2)) {
  167. u8 *pm=(u8 *)(SRam.data-SRam.start+a);
  168. if(*pm != (u8)d) {
  169. SRam.changed = 1;
  170. *pm=(u8)d;
  171. }
  172. }
  173. }
  174. // for nonstandard reads
  175. static u32 OtherRead16End(u32 a, int realsize)
  176. {
  177. u32 d=0;
  178. // 32x test
  179. /*
  180. if (a == 0xa130ec) { d = 0x4d41; goto end; } // MA
  181. else if (a == 0xa130ee) { d = 0x5253; goto end; } // RS
  182. else if (a == 0xa15100) { d = 0x0080; goto end; }
  183. else
  184. */
  185. // for games with simple protection devices, discovered by Haze
  186. // some dumb detection is used, but that should be enough to make things work
  187. if ((a>>22) == 1 && Pico.romsize >= 512*1024) {
  188. if (*(int *)(Pico.rom+0x123e4) == 0x00550c39 && *(int *)(Pico.rom+0x123e8) == 0x00000040) { // Super Bubble Bobble (Unl) [!]
  189. if (a == 0x400000) { d=0x55<<8; goto end; }
  190. else if (a == 0x400002) { d=0x0f<<8; goto end; }
  191. }
  192. else if (*(int *)(Pico.rom+0x008c4) == 0x66240055 && *(int *)(Pico.rom+0x008c8) == 0x00404df9) { // Smart Mouse (Unl)
  193. if (a == 0x400000) { d=0x55<<8; goto end; }
  194. else if (a == 0x400002) { d=0x0f<<8; goto end; }
  195. else if (a == 0x400004) { d=0xaa<<8; goto end; }
  196. else if (a == 0x400006) { d=0xf0<<8; goto end; }
  197. }
  198. else if (*(int *)(Pico.rom+0x00404) == 0x00a90600 && *(int *)(Pico.rom+0x00408) == 0x6708b013) { // King of Fighters '98, The (Unl) [!]
  199. if (a == 0x480000 || a == 0x4800e0 || a == 0x4824a0 || a == 0x488880) { d=0xaa<<8; goto end; }
  200. else if (a == 0x4a8820) { d=0x0a<<8; goto end; }
  201. // there is also a read @ 0x4F8820 which needs 0, but that is returned in default case
  202. }
  203. else if (*(int *)(Pico.rom+0x01b24) == 0x004013f9 && *(int *)(Pico.rom+0x01b28) == 0x00ff0000) { // Mahjong Lover (Unl) [!]
  204. if (a == 0x400000) { d=0x90<<8; goto end; }
  205. else if (a == 0x401000) { d=0xd3<<8; goto end; } // this one doesn't seem to be needed, the code does 2 comparisons and only then
  206. // checks the result, which is of the above one. Left it just in case.
  207. }
  208. else if (*(int *)(Pico.rom+0x05254) == 0x0c3962d0 && *(int *)(Pico.rom+0x05258) == 0x00400055) { // Elf Wor (Unl)
  209. if (a == 0x400000) { d=0x55<<8; goto end; }
  210. else if (a == 0x400004) { d=0xc9<<8; goto end; } // this check is done if the above one fails
  211. else if (a == 0x400002) { d=0x0f<<8; goto end; }
  212. else if (a == 0x400006) { d=0x18<<8; goto end; } // similar to above
  213. }
  214. // our default behaviour is to return whatever was last written a 0x400000-0x7fffff range (used by Squirrel King (R) [!])
  215. // Lion King II, The (Unl) [!] writes @ 400000 and wants to get that val @ 400002 and wites another val
  216. // @ 400004 which is expected @ 400006, so we really remember 2 values here
  217. d = Pico.m.prot_bytes[(a>>2)&1]<<8;
  218. }
  219. else if (a == 0xa13000 && Pico.romsize >= 1024*1024) {
  220. if (*(int *)(Pico.rom+0xc8af0) == 0x30133013 && *(int *)(Pico.rom+0xc8af4) == 0x000f0240) { // Rockman X3 (Unl) [!]
  221. d=0x0c; goto end;
  222. }
  223. else if (*(int *)(Pico.rom+0x28888) == 0x07fc0000 && *(int *)(Pico.rom+0x2888c) == 0x4eb94e75) { // Bug's Life, A (Unl) [!]
  224. d=0x28; goto end; // does the check from RAM
  225. }
  226. else if (*(int *)(Pico.rom+0xc8778) == 0x30133013 && *(int *)(Pico.rom+0xc877c) == 0x000f0240) { // Super Mario Bros. (Unl) [!]
  227. d=0x0c; goto end; // seems to be the same code as in Rockman X3 (Unl) [!]
  228. }
  229. else if (*(int *)(Pico.rom+0xf20ec) == 0x30143013 && *(int *)(Pico.rom+0xf20f0) == 0x000f0200) { // Super Mario 2 1998 (Unl) [!]
  230. d=0x0a; goto end;
  231. }
  232. }
  233. else if (a == 0xa13002) { // Pocket Monsters (Unl)
  234. d=0x01; goto end;
  235. }
  236. else if (a == 0xa1303E) { // Pocket Monsters (Unl)
  237. d=0x1f; goto end;
  238. }
  239. else if (a == 0x30fe02) {
  240. // Virtua Racing - just for fun
  241. // this seems to be some flag that SVP is ready or something similar
  242. d=1; goto end;
  243. }
  244. end:
  245. elprintf(EL_UIO, "strange r%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc);
  246. return d;
  247. }
  248. //extern UINT32 mz80GetRegisterValue(void *, UINT32);
  249. static void OtherWrite8End(u32 a,u32 d,int realsize)
  250. {
  251. // sram
  252. if(a >= SRam.start && a <= SRam.end) {
  253. elprintf(EL_SRAMIO, "sram w8 [%06x] %02x @ %06x", a, d, SekPc);
  254. SRAMWrite(a, d);
  255. return;
  256. }
  257. #ifdef _ASM_MEMORY_C
  258. // special ROM hardware (currently only banking and sram reg supported)
  259. if((a&0xfffff1) == 0xA130F1) {
  260. PicoWriteRomHW_SSF2(a, d); // SSF2 or SRAM
  261. return;
  262. }
  263. #else
  264. // sram access register
  265. if(a == 0xA130F1) {
  266. elprintf(EL_SRAMIO, "sram reg=%02x", d);
  267. Pico.m.sram_reg &= ~3;
  268. Pico.m.sram_reg |= (u8)(d&3);
  269. return;
  270. }
  271. #endif
  272. elprintf(EL_UIO, "strange w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc);
  273. // for games with simple protection devices, discovered by Haze
  274. if ((a>>22) == 1)
  275. Pico.m.prot_bytes[(a>>2)&1] = (u8)d;
  276. }
  277. #include "MemoryCmn.c"
  278. // -----------------------------------------------------------------
  279. // Read Rom and read Ram
  280. #ifndef _ASM_MEMORY_C
  281. PICO_INTERNAL_ASM u32 PicoRead8(u32 a)
  282. {
  283. u32 d=0;
  284. if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram
  285. a&=0xffffff;
  286. #ifndef EMU_CORE_DEBUG
  287. // sram
  288. if (a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
  289. d = SRAMRead(a);
  290. elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc);
  291. goto end;
  292. }
  293. #endif
  294. if (a<Pico.romsize) { d = *(u8 *)(Pico.rom+(a^1)); goto end; } // Rom
  295. log_io(a, 8, 0);
  296. if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram
  297. if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead8(a); goto end; } // VDP
  298. d=OtherRead16(a&~1, 8);
  299. if ((a&1)==0) d>>=8;
  300. end:
  301. elprintf(EL_IO, "r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
  302. #ifdef EMU_CORE_DEBUG
  303. if (a>=Pico.romsize) {
  304. lastread_a = a;
  305. lastread_d[lrp_cyc++&15] = (u8)d;
  306. }
  307. #endif
  308. return d;
  309. }
  310. PICO_INTERNAL_ASM u32 PicoRead16(u32 a)
  311. {
  312. u32 d=0;
  313. if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram
  314. a&=0xfffffe;
  315. #ifndef EMU_CORE_DEBUG
  316. // sram
  317. if (a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
  318. d = SRAMRead16(a);
  319. elprintf(EL_SRAMIO, "sram r16 [%06x] %04x @ %06x", a, d, SekPc);
  320. goto end;
  321. }
  322. #endif
  323. if (a<Pico.romsize) { d = *(u16 *)(Pico.rom+a); goto end; } // Rom
  324. log_io(a, 16, 0);
  325. if ((a&0xe700e0)==0xc00000)
  326. d = PicoVideoRead(a);
  327. else d = OtherRead16(a, 16);
  328. end:
  329. elprintf(EL_IO, "r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);
  330. #ifdef EMU_CORE_DEBUG
  331. if (a>=Pico.romsize) {
  332. lastread_a = a;
  333. lastread_d[lrp_cyc++&15] = d;
  334. }
  335. #endif
  336. return d;
  337. }
  338. PICO_INTERNAL_ASM u32 PicoRead32(u32 a)
  339. {
  340. u32 d=0;
  341. if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram
  342. a&=0xfffffe;
  343. // sram
  344. if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
  345. d = (SRAMRead16(a)<<16)|SRAMRead16(a+2);
  346. elprintf(EL_SRAMIO, "sram r32 [%06x] %08x @ %06x", a, d, SekPc);
  347. goto end;
  348. }
  349. if (a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); d = (pm[0]<<16)|pm[1]; goto end; } // Rom
  350. log_io(a, 32, 0);
  351. if ((a&0xe700e0)==0xc00000)
  352. d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);
  353. else d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);
  354. end:
  355. elprintf(EL_IO, "r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);
  356. #ifdef EMU_CORE_DEBUG
  357. if (a>=Pico.romsize) {
  358. lastread_a = a;
  359. lastread_d[lrp_cyc++&15] = d;
  360. }
  361. #endif
  362. return d;
  363. }
  364. #endif
  365. // -----------------------------------------------------------------
  366. // Write Ram
  367. #if !defined(_ASM_MEMORY_C) || defined(_ASM_MEMORY_C_AMIPS)
  368. PICO_INTERNAL_ASM void PicoWrite8(u32 a,u8 d)
  369. {
  370. elprintf(EL_IO, "w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);
  371. #ifdef EMU_CORE_DEBUG
  372. lastwrite_cyc_d[lwp_cyc++&15] = d;
  373. #endif
  374. if ((a&0xe00000)==0xe00000) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram
  375. log_io(a, 8, 1);
  376. a&=0xffffff;
  377. OtherWrite8(a,d);
  378. }
  379. #endif
  380. void PicoWrite16(u32 a,u16 d)
  381. {
  382. elprintf(EL_IO, "w16: %06x, %04x", a&0xffffff, d);
  383. #ifdef EMU_CORE_DEBUG
  384. lastwrite_cyc_d[lwp_cyc++&15] = d;
  385. #endif
  386. if ((a&0xe00000)==0xe00000) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram
  387. log_io(a, 16, 1);
  388. a&=0xfffffe;
  389. if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP
  390. OtherWrite16(a,d);
  391. }
  392. static void PicoWrite32(u32 a,u32 d)
  393. {
  394. elprintf(EL_IO, "w32: %06x, %08x @%06x", a&0xffffff, d, SekPc);
  395. #ifdef EMU_CORE_DEBUG
  396. lastwrite_cyc_d[lwp_cyc++&15] = d;
  397. #endif
  398. if ((a&0xe00000)==0xe00000)
  399. {
  400. // Ram:
  401. u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));
  402. pm[0]=(u16)(d>>16); pm[1]=(u16)d;
  403. return;
  404. }
  405. log_io(a, 32, 1);
  406. a&=0xfffffe;
  407. if ((a&0xe700e0)==0xc00000)
  408. {
  409. // VDP:
  410. PicoVideoWrite(a, (u16)(d>>16));
  411. PicoVideoWrite(a+2,(u16)d);
  412. return;
  413. }
  414. OtherWrite16(a, (u16)(d>>16));
  415. OtherWrite16(a+2,(u16)d);
  416. }
  417. // -----------------------------------------------------------------
  418. static void OtherWrite16End(u32 a,u32 d,int realsize)
  419. {
  420. PicoWrite8Hook(a, d>>8, realsize);
  421. PicoWrite8Hook(a+1,d&0xff, realsize);
  422. }
  423. u32 (*PicoRead16Hook) (u32 a, int realsize) = OtherRead16End;
  424. void (*PicoWrite8Hook) (u32 a, u32 d, int realsize) = OtherWrite8End;
  425. void (*PicoWrite16Hook)(u32 a, u32 d, int realsize) = OtherWrite16End;
  426. PICO_INTERNAL void PicoMemResetHooks(void)
  427. {
  428. // default unmapped/cart specific handlers
  429. PicoRead16Hook = OtherRead16End;
  430. PicoWrite8Hook = OtherWrite8End;
  431. PicoWrite16Hook = OtherWrite16End;
  432. }
  433. #ifdef EMU_M68K
  434. static void m68k_mem_setup(void);
  435. #endif
  436. PICO_INTERNAL void PicoMemSetup(void)
  437. {
  438. // Setup memory callbacks:
  439. #ifdef EMU_C68K
  440. PicoCpuCM68k.checkpc=PicoCheckPc;
  441. PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoRead8;
  442. PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoRead16;
  443. PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoRead32;
  444. PicoCpuCM68k.write8 =PicoWrite8;
  445. PicoCpuCM68k.write16=PicoWrite16;
  446. PicoCpuCM68k.write32=PicoWrite32;
  447. #endif
  448. #ifdef EMU_F68K
  449. PicoCpuFM68k.read_byte =PicoRead8;
  450. PicoCpuFM68k.read_word =PicoRead16;
  451. PicoCpuFM68k.read_long =PicoRead32;
  452. PicoCpuFM68k.write_byte=PicoWrite8;
  453. PicoCpuFM68k.write_word=PicoWrite16;
  454. PicoCpuFM68k.write_long=PicoWrite32;
  455. // setup FAME fetchmap
  456. {
  457. int i;
  458. // by default, point everything to first 64k of ROM
  459. for (i = 0; i < M68K_FETCHBANK1; i++)
  460. PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom - (i<<(24-FAMEC_FETCHBITS));
  461. // now real ROM
  462. for (i = 0; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < Pico.romsize; i++)
  463. PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom;
  464. // .. and RAM
  465. for (i = M68K_FETCHBANK1*14/16; i < M68K_FETCHBANK1; i++)
  466. PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.ram - (i<<(24-FAMEC_FETCHBITS));
  467. }
  468. #endif
  469. #ifdef EMU_M68K
  470. m68k_mem_setup();
  471. #endif
  472. }
  473. /* some nasty things below :( */
  474. #ifdef EMU_M68K
  475. unsigned int (*pm68k_read_memory_8) (unsigned int address) = NULL;
  476. unsigned int (*pm68k_read_memory_16)(unsigned int address) = NULL;
  477. unsigned int (*pm68k_read_memory_32)(unsigned int address) = NULL;
  478. void (*pm68k_write_memory_8) (unsigned int address, unsigned char value) = NULL;
  479. void (*pm68k_write_memory_16)(unsigned int address, unsigned short value) = NULL;
  480. void (*pm68k_write_memory_32)(unsigned int address, unsigned int value) = NULL;
  481. unsigned int (*pm68k_read_memory_pcr_8) (unsigned int address) = NULL;
  482. unsigned int (*pm68k_read_memory_pcr_16)(unsigned int address) = NULL;
  483. unsigned int (*pm68k_read_memory_pcr_32)(unsigned int address) = NULL;
  484. // these are here for core debugging mode
  485. static unsigned int m68k_read_8 (unsigned int a, int do_fake)
  486. {
  487. a&=0xffffff;
  488. if(a<Pico.romsize && m68ki_cpu_p==&PicoCpuMM68k) return *(u8 *)(Pico.rom+(a^1)); // Rom
  489. #ifdef EMU_CORE_DEBUG
  490. if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
  491. #endif
  492. return pm68k_read_memory_pcr_8(a);
  493. }
  494. static unsigned int m68k_read_16(unsigned int a, int do_fake)
  495. {
  496. a&=0xffffff;
  497. if(a<Pico.romsize && m68ki_cpu_p==&PicoCpuMM68k) return *(u16 *)(Pico.rom+(a&~1)); // Rom
  498. #ifdef EMU_CORE_DEBUG
  499. if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
  500. #endif
  501. return pm68k_read_memory_pcr_16(a);
  502. }
  503. static unsigned int m68k_read_32(unsigned int a, int do_fake)
  504. {
  505. a&=0xffffff;
  506. if(a<Pico.romsize && m68ki_cpu_p==&PicoCpuMM68k) { u16 *pm=(u16 *)(Pico.rom+(a&~1)); return (pm[0]<<16)|pm[1]; }
  507. #ifdef EMU_CORE_DEBUG
  508. if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
  509. #endif
  510. return pm68k_read_memory_pcr_32(a);
  511. }
  512. unsigned int m68k_read_pcrelative_8 (unsigned int a) { return m68k_read_8 (a, 1); }
  513. unsigned int m68k_read_pcrelative_16(unsigned int a) { return m68k_read_16(a, 1); }
  514. unsigned int m68k_read_pcrelative_32(unsigned int a) { return m68k_read_32(a, 1); }
  515. unsigned int m68k_read_immediate_16(unsigned int a) { return m68k_read_16(a, 0); }
  516. unsigned int m68k_read_immediate_32(unsigned int a) { return m68k_read_32(a, 0); }
  517. unsigned int m68k_read_disassembler_8 (unsigned int a) { return m68k_read_8 (a, 0); }
  518. unsigned int m68k_read_disassembler_16(unsigned int a) { return m68k_read_16(a, 0); }
  519. unsigned int m68k_read_disassembler_32(unsigned int a) { return m68k_read_32(a, 0); }
  520. static unsigned int m68k_read_memory_pcr_8(unsigned int a)
  521. {
  522. if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram
  523. return 0;
  524. }
  525. static unsigned int m68k_read_memory_pcr_16(unsigned int a)
  526. {
  527. if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram
  528. return 0;
  529. }
  530. static unsigned int m68k_read_memory_pcr_32(unsigned int a)
  531. {
  532. if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram
  533. return 0;
  534. }
  535. #ifdef EMU_CORE_DEBUG
  536. // ROM only
  537. unsigned int m68k_read_memory_8(unsigned int a)
  538. {
  539. u8 d;
  540. if (a<Pico.romsize && m68ki_cpu_p==&PicoCpuMM68k)
  541. d = *(u8 *) (Pico.rom+(a^1));
  542. else d = (u8) lastread_d[lrp_mus++&15];
  543. elprintf(EL_IO, "r8_mu : %06x, %02x @%06x", a&0xffffff, d, SekPc);
  544. return d;
  545. }
  546. unsigned int m68k_read_memory_16(unsigned int a)
  547. {
  548. u16 d;
  549. if (a<Pico.romsize && m68ki_cpu_p==&PicoCpuMM68k)
  550. d = *(u16 *)(Pico.rom+(a&~1));
  551. else d = (u16) lastread_d[lrp_mus++&15];
  552. elprintf(EL_IO, "r16_mu: %06x, %04x @%06x", a&0xffffff, d, SekPc);
  553. return d;
  554. }
  555. unsigned int m68k_read_memory_32(unsigned int a)
  556. {
  557. u32 d;
  558. if (a<Pico.romsize && m68ki_cpu_p==&PicoCpuMM68k)
  559. { u16 *pm=(u16 *)(Pico.rom+(a&~1));d=(pm[0]<<16)|pm[1]; }
  560. else if (a <= 0x78) d = m68k_read_32(a, 0);
  561. else d = lastread_d[lrp_mus++&15];
  562. elprintf(EL_IO, "r32_mu: %06x, %08x @%06x", a&0xffffff, d, SekPc);
  563. return d;
  564. }
  565. // ignore writes, Cyclone already done that
  566. void m68k_write_memory_8(unsigned int address, unsigned int value) { lastwrite_mus_d[lwp_mus++&15] = value; }
  567. void m68k_write_memory_16(unsigned int address, unsigned int value) { lastwrite_mus_d[lwp_mus++&15] = value; }
  568. void m68k_write_memory_32(unsigned int address, unsigned int value) { lastwrite_mus_d[lwp_mus++&15] = value; }
  569. #else // if !EMU_CORE_DEBUG
  570. /* it appears that Musashi doesn't always mask the unused bits */
  571. unsigned int m68k_read_memory_8 (unsigned int address) { return pm68k_read_memory_8 (address) & 0xff; }
  572. unsigned int m68k_read_memory_16(unsigned int address) { return pm68k_read_memory_16(address) & 0xffff; }
  573. unsigned int m68k_read_memory_32(unsigned int address) { return pm68k_read_memory_32(address); }
  574. void m68k_write_memory_8 (unsigned int address, unsigned int value) { pm68k_write_memory_8 (address, (u8)value); }
  575. void m68k_write_memory_16(unsigned int address, unsigned int value) { pm68k_write_memory_16(address,(u16)value); }
  576. void m68k_write_memory_32(unsigned int address, unsigned int value) { pm68k_write_memory_32(address, value); }
  577. #endif // !EMU_CORE_DEBUG
  578. static void m68k_mem_setup(void)
  579. {
  580. pm68k_read_memory_8 = PicoRead8;
  581. pm68k_read_memory_16 = PicoRead16;
  582. pm68k_read_memory_32 = PicoRead32;
  583. pm68k_write_memory_8 = PicoWrite8;
  584. pm68k_write_memory_16 = PicoWrite16;
  585. pm68k_write_memory_32 = PicoWrite32;
  586. pm68k_read_memory_pcr_8 = m68k_read_memory_pcr_8;
  587. pm68k_read_memory_pcr_16 = m68k_read_memory_pcr_16;
  588. pm68k_read_memory_pcr_32 = m68k_read_memory_pcr_32;
  589. }
  590. #endif // EMU_M68K
  591. // -----------------------------------------------------------------
  592. static int get_scanline(int is_from_z80)
  593. {
  594. if (is_from_z80) {
  595. int cycles = z80_cyclesDone();
  596. while (cycles - z80_scanline_cycles >= 228)
  597. z80_scanline++, z80_scanline_cycles += 228;
  598. return z80_scanline;
  599. }
  600. return Pico.m.scanline;
  601. }
  602. /* probably should not be in this file, but it's near related code here */
  603. void ym2612_sync_timers(int z80_cycles, int mode_old, int mode_new)
  604. {
  605. int xcycles = z80_cycles << 8;
  606. /* check for overflows */
  607. if ((mode_old & 4) && xcycles > timer_a_next_oflow)
  608. ym2612.OPN.ST.status |= 1;
  609. if ((mode_old & 8) && xcycles > timer_b_next_oflow)
  610. ym2612.OPN.ST.status |= 2;
  611. /* update timer a */
  612. if (mode_old & 1)
  613. while (xcycles > timer_a_next_oflow)
  614. timer_a_next_oflow += timer_a_step;
  615. if ((mode_old ^ mode_new) & 1) // turning on/off
  616. {
  617. if (mode_old & 1)
  618. timer_a_next_oflow = TIMER_NO_OFLOW;
  619. else
  620. timer_a_next_oflow = xcycles + timer_a_step;
  621. }
  622. if (mode_new & 1)
  623. elprintf(EL_YMTIMER, "timer a upd to %i @ %i", timer_a_next_oflow>>8, z80_cycles);
  624. /* update timer b */
  625. if (mode_old & 2)
  626. while (xcycles > timer_b_next_oflow)
  627. timer_b_next_oflow += timer_b_step;
  628. if ((mode_old ^ mode_new) & 2)
  629. {
  630. if (mode_old & 2)
  631. timer_b_next_oflow = TIMER_NO_OFLOW;
  632. else
  633. timer_b_next_oflow = xcycles + timer_b_step;
  634. }
  635. if (mode_new & 2)
  636. elprintf(EL_YMTIMER, "timer b upd to %i @ %i", timer_b_next_oflow>>8, z80_cycles);
  637. }
  638. // ym2612 DAC and timer I/O handlers for z80
  639. int ym2612_write_local(u32 a, u32 d, int is_from_z80)
  640. {
  641. int addr;
  642. a &= 3;
  643. if (a == 1 && ym2612.OPN.ST.address == 0x2a) /* DAC data */
  644. {
  645. int scanline = get_scanline(is_from_z80);
  646. //elprintf(EL_STATUS, "%03i -> %03i dac w %08x z80 %i", PsndDacLine, scanline, d, is_from_z80);
  647. ym2612.dacout = ((int)d - 0x80) << 6;
  648. if (PsndOut && ym2612.dacen && scanline >= PsndDacLine)
  649. PsndDoDAC(scanline);
  650. return 0;
  651. }
  652. switch (a)
  653. {
  654. case 0: /* address port 0 */
  655. ym2612.OPN.ST.address = d;
  656. ym2612.addr_A1 = 0;
  657. #ifdef __GP2X__
  658. if (PicoOpt & POPT_EXT_FM) YM2612Write_940(a, d, -1);
  659. #endif
  660. return 0;
  661. case 1: /* data port 0 */
  662. if (ym2612.addr_A1 != 0)
  663. return 0;
  664. addr = ym2612.OPN.ST.address;
  665. ym2612.REGS[addr] = d;
  666. switch (addr)
  667. {
  668. case 0x24: // timer A High 8
  669. case 0x25: { // timer A Low 2
  670. int TAnew = (addr == 0x24) ? ((ym2612.OPN.ST.TA & 0x03)|(((int)d)<<2))
  671. : ((ym2612.OPN.ST.TA & 0x3fc)|(d&3));
  672. if (ym2612.OPN.ST.TA != TAnew)
  673. {
  674. //elprintf(EL_STATUS, "timer a set %i", TAnew);
  675. ym2612.OPN.ST.TA = TAnew;
  676. //ym2612.OPN.ST.TAC = (1024-TAnew)*18;
  677. //ym2612.OPN.ST.TAT = 0;
  678. timer_a_step = TIMER_A_TICK_ZCYCLES * (1024 - TAnew);
  679. if (ym2612.OPN.ST.mode & 1) {
  680. // this is not right, should really be done on overflow only
  681. int cycles = is_from_z80 ? z80_cyclesDone() : cycles_68k_to_z80(SekCyclesDone());
  682. timer_a_next_oflow = (cycles << 8) + timer_a_step;
  683. }
  684. elprintf(EL_YMTIMER, "timer a set to %i, %i", 1024 - TAnew, timer_a_next_oflow>>8);
  685. }
  686. return 0;
  687. }
  688. case 0x26: // timer B
  689. if (ym2612.OPN.ST.TB != d) {
  690. //elprintf(EL_STATUS, "timer b set %i", d);
  691. ym2612.OPN.ST.TB = d;
  692. //ym2612.OPN.ST.TBC = (256-d) * 288;
  693. //ym2612.OPN.ST.TBT = 0;
  694. timer_b_step = TIMER_B_TICK_ZCYCLES * (256 - d); // 262800
  695. if (ym2612.OPN.ST.mode & 2) {
  696. int cycles = is_from_z80 ? z80_cyclesDone() : cycles_68k_to_z80(SekCyclesDone());
  697. timer_b_next_oflow = (cycles << 8) + timer_b_step;
  698. }
  699. elprintf(EL_YMTIMER, "timer b set to %i, %i", 256 - d, timer_b_next_oflow>>8);
  700. }
  701. return 0;
  702. case 0x27: { /* mode, timer control */
  703. int old_mode = ym2612.OPN.ST.mode;
  704. int cycles = is_from_z80 ? z80_cyclesDone() : cycles_68k_to_z80(SekCyclesDone());
  705. ym2612.OPN.ST.mode = d;
  706. elprintf(EL_YMTIMER, "st mode %02x", d);
  707. ym2612_sync_timers(cycles, old_mode, d);
  708. /* reset Timer a flag */
  709. if (d & 0x10)
  710. ym2612.OPN.ST.status &= ~1;
  711. /* reset Timer b flag */
  712. if (d & 0x20)
  713. ym2612.OPN.ST.status &= ~2;
  714. if ((d ^ old_mode) & 0xc0) {
  715. #ifdef __GP2X__
  716. if (PicoOpt & POPT_EXT_FM) return YM2612Write_940(a, d, get_scanline(is_from_z80));
  717. #endif
  718. return 1;
  719. }
  720. return 0;
  721. }
  722. case 0x2b: { /* DAC Sel (YM2612) */
  723. int scanline = get_scanline(is_from_z80);
  724. ym2612.dacen = d & 0x80;
  725. if (d & 0x80) PsndDacLine = scanline;
  726. #ifdef __GP2X__
  727. if (PicoOpt & POPT_EXT_FM) YM2612Write_940(a, d, scanline);
  728. #endif
  729. return 0;
  730. }
  731. }
  732. break;
  733. case 2: /* address port 1 */
  734. ym2612.OPN.ST.address = d;
  735. ym2612.addr_A1 = 1;
  736. #ifdef __GP2X__
  737. if (PicoOpt & POPT_EXT_FM) YM2612Write_940(a, d, -1);
  738. #endif
  739. return 0;
  740. case 3: /* data port 1 */
  741. if (ym2612.addr_A1 != 1)
  742. return 0;
  743. addr = ym2612.OPN.ST.address | 0x100;
  744. ym2612.REGS[addr] = d;
  745. break;
  746. }
  747. #ifdef __GP2X__
  748. if (PicoOpt & POPT_EXT_FM)
  749. return YM2612Write_940(a, d, get_scanline(is_from_z80));
  750. #endif
  751. return YM2612Write_(a, d);
  752. }
  753. #define ym2612_read_local() \
  754. if (xcycles >= timer_a_next_oflow) \
  755. ym2612.OPN.ST.status |= (ym2612.OPN.ST.mode >> 2) & 1; \
  756. if (xcycles >= timer_b_next_oflow) \
  757. ym2612.OPN.ST.status |= (ym2612.OPN.ST.mode >> 2) & 2
  758. u32 ym2612_read_local_z80(void)
  759. {
  760. int xcycles = z80_cyclesDone() << 8;
  761. ym2612_read_local();
  762. elprintf(EL_YMTIMER, "timer z80 read %i, sched %i, %i @ %i|%i", ym2612.OPN.ST.status,
  763. timer_a_next_oflow>>8, timer_b_next_oflow>>8, xcycles >> 8, (xcycles >> 8) / 228);
  764. return ym2612.OPN.ST.status;
  765. }
  766. u32 ym2612_read_local_68k(void)
  767. {
  768. int xcycles = cycles_68k_to_z80(SekCyclesDone()) << 8;
  769. ym2612_read_local();
  770. elprintf(EL_YMTIMER, "timer 68k read %i, sched %i, %i @ %i|%i", ym2612.OPN.ST.status,
  771. timer_a_next_oflow>>8, timer_b_next_oflow>>8, xcycles >> 8, (xcycles >> 8) / 228);
  772. return ym2612.OPN.ST.status;
  773. }
  774. void ym2612_pack_state(void)
  775. {
  776. // timers are saved as tick counts, in 16.16 int format
  777. int tac, tat = 0, tbc, tbt = 0;
  778. tac = 1024 - ym2612.OPN.ST.TA;
  779. tbc = 256 - ym2612.OPN.ST.TB;
  780. if (timer_a_next_oflow != TIMER_NO_OFLOW)
  781. tat = (int)((double)(timer_a_step - timer_a_next_oflow) / (double)timer_a_step * tac * 65536);
  782. if (timer_b_next_oflow != TIMER_NO_OFLOW)
  783. tbt = (int)((double)(timer_b_step - timer_b_next_oflow) / (double)timer_b_step * tbc * 65536);
  784. elprintf(EL_YMTIMER, "save: timer a %i/%i", tat >> 16, tac);
  785. elprintf(EL_YMTIMER, "save: timer b %i/%i", tbt >> 16, tbc);
  786. #ifdef __GP2X__
  787. if (PicoOpt & POPT_EXT_FM)
  788. YM2612PicoStateSave2_940(tat, tbt);
  789. else
  790. #endif
  791. YM2612PicoStateSave2(tat, tbt);
  792. }
  793. void ym2612_unpack_state(void)
  794. {
  795. int i, ret, tac, tat, tbc, tbt;
  796. YM2612PicoStateLoad();
  797. // feed all the registers and update internal state
  798. for (i = 0x20; i < 0xA0; i++) {
  799. ym2612_write_local(0, i, 0);
  800. ym2612_write_local(1, ym2612.REGS[i], 0);
  801. }
  802. for (i = 0x30; i < 0xA0; i++) {
  803. ym2612_write_local(2, i, 0);
  804. ym2612_write_local(3, ym2612.REGS[i|0x100], 0);
  805. }
  806. for (i = 0xAF; i >= 0xA0; i--) { // must apply backwards
  807. ym2612_write_local(2, i, 0);
  808. ym2612_write_local(3, ym2612.REGS[i|0x100], 0);
  809. ym2612_write_local(0, i, 0);
  810. ym2612_write_local(1, ym2612.REGS[i], 0);
  811. }
  812. for (i = 0xB0; i < 0xB8; i++) {
  813. ym2612_write_local(0, i, 0);
  814. ym2612_write_local(1, ym2612.REGS[i], 0);
  815. ym2612_write_local(2, i, 0);
  816. ym2612_write_local(3, ym2612.REGS[i|0x100], 0);
  817. }
  818. #ifdef __GP2X__
  819. if (PicoOpt & POPT_EXT_FM)
  820. ret = YM2612PicoStateLoad2_940(&tat, &tbt);
  821. else
  822. #endif
  823. ret = YM2612PicoStateLoad2(&tat, &tbt);
  824. if (ret != 0) {
  825. elprintf(EL_STATUS, "old ym2612 state");
  826. return; // no saved timers
  827. }
  828. tac = (1024 - ym2612.OPN.ST.TA) << 16;
  829. tbc = (256 - ym2612.OPN.ST.TB) << 16;
  830. if (ym2612.OPN.ST.mode & 1)
  831. timer_a_next_oflow = (int)((double)(tac - tat) / (double)tac * timer_a_step);
  832. else
  833. timer_a_next_oflow = TIMER_NO_OFLOW;
  834. if (ym2612.OPN.ST.mode & 2)
  835. timer_b_next_oflow = (int)((double)(tbc - tbt) / (double)tbc * timer_b_step);
  836. else
  837. timer_b_next_oflow = TIMER_NO_OFLOW;
  838. elprintf(EL_YMTIMER, "load: %i/%i, timer_a_next_oflow %i", tat>>16, tac>>16, timer_a_next_oflow >> 8);
  839. elprintf(EL_YMTIMER, "load: %i/%i, timer_b_next_oflow %i", tbt>>16, tbc>>16, timer_b_next_oflow >> 8);
  840. }
  841. // -----------------------------------------------------------------
  842. // z80 memhandlers
  843. PICO_INTERNAL unsigned char z80_read(unsigned short a)
  844. {
  845. u8 ret = 0;
  846. if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)
  847. {
  848. return ym2612_read_local_z80();
  849. }
  850. if (a>=0x8000)
  851. {
  852. extern u32 PicoReadM68k8(u32 a);
  853. u32 addr68k;
  854. addr68k=Pico.m.z80_bank68k<<15;
  855. addr68k+=a&0x7fff;
  856. if (addr68k < Pico.romsize) { ret = Pico.rom[addr68k^1]; goto bnkend; }
  857. elprintf(EL_ANOMALY, "z80->68k upper read [%06x] %02x", addr68k, ret);
  858. if (PicoAHW & PAHW_MCD)
  859. ret = PicoReadM68k8(addr68k);
  860. else ret = PicoRead8(addr68k);
  861. bnkend:
  862. elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret);
  863. return ret;
  864. }
  865. // should not be needed, cores should be able to access RAM themselves
  866. if (a<0x4000) return Pico.zram[a&0x1fff];
  867. elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, ret);
  868. return ret;
  869. }
  870. #ifndef _USE_CZ80
  871. PICO_INTERNAL_ASM void z80_write(unsigned char data, unsigned short a)
  872. #else
  873. PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data)
  874. #endif
  875. {
  876. if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)
  877. {
  878. if(PicoOpt&POPT_EN_FM) emustatus|=ym2612_write_local(a, data, 1) & 1;
  879. return;
  880. }
  881. if ((a&0xfff9)==0x7f11) // 7f11 7f13 7f15 7f17
  882. {
  883. if(PicoOpt&POPT_EN_PSG) SN76496Write(data);
  884. return;
  885. }
  886. if ((a>>8)==0x60)
  887. {
  888. Pico.m.z80_bank68k>>=1;
  889. Pico.m.z80_bank68k|=(data&1)<<8;
  890. Pico.m.z80_bank68k&=0x1ff; // 9 bits and filled in the new top one
  891. return;
  892. }
  893. if (a>=0x8000)
  894. {
  895. extern void PicoWriteM68k8(u32 a,u8 d);
  896. u32 addr68k;
  897. addr68k=Pico.m.z80_bank68k<<15;
  898. addr68k+=a&0x7fff;
  899. elprintf(EL_Z80BNK, "z80->68k w8 [%06x] %02x", addr68k, data);
  900. if (PicoAHW & PAHW_MCD)
  901. PicoWriteM68k8(addr68k, data);
  902. else PicoWrite8(addr68k, data);
  903. return;
  904. }
  905. // should not be needed
  906. if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }
  907. elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data);
  908. }
  909. #ifndef _USE_CZ80
  910. PICO_INTERNAL unsigned short z80_read16(unsigned short a)
  911. {
  912. return (u16) ( (u16)z80_read(a) | ((u16)z80_read((u16)(a+1))<<8) );
  913. }
  914. PICO_INTERNAL void z80_write16(unsigned short data, unsigned short a)
  915. {
  916. z80_write((unsigned char) data,a);
  917. z80_write((unsigned char)(data>>8),(u16)(a+1));
  918. }
  919. #endif