z80if.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include "pico_int.h"
  2. #include "sound/sn76496.h"
  3. #define Z80_MEM_SHIFT 13
  4. unsigned long z80_read_map [0x10000 >> Z80_MEM_SHIFT];
  5. unsigned long z80_write_map[0x10000 >> Z80_MEM_SHIFT];
  6. #ifdef _USE_MZ80
  7. // memhandlers for mz80 core
  8. unsigned char mz80_read(UINT32 a, struct MemoryReadByte *w) { return z80_read(a); }
  9. void mz80_write(UINT32 a, UINT8 d, struct MemoryWriteByte *w) { z80_write(d, a); }
  10. // structures for mz80 core
  11. static struct MemoryReadByte mz80_mem_read[]=
  12. {
  13. {0x0000,0xffff,mz80_read},
  14. {(UINT32) -1,(UINT32) -1,NULL}
  15. };
  16. static struct MemoryWriteByte mz80_mem_write[]=
  17. {
  18. {0x0000,0xffff,mz80_write},
  19. {(UINT32) -1,(UINT32) -1,NULL}
  20. };
  21. static struct z80PortRead mz80_io_read[] ={
  22. {(UINT16) -1,(UINT16) -1,NULL}
  23. };
  24. static struct z80PortWrite mz80_io_write[]={
  25. {(UINT16) -1,(UINT16) -1,NULL}
  26. };
  27. int mz80_run(int cycles)
  28. {
  29. int ticks_pre = mz80GetElapsedTicks(0);
  30. mz80exec(cycles);
  31. return mz80GetElapsedTicks(0) - ticks_pre;
  32. }
  33. #endif
  34. #ifdef _USE_DRZ80
  35. struct DrZ80 drZ80;
  36. #endif
  37. PICO_INTERNAL void z80_init(void)
  38. {
  39. #ifdef _USE_MZ80
  40. struct mz80context z80;
  41. // z80
  42. mz80init();
  43. // Modify the default context
  44. mz80GetContext(&z80);
  45. // point mz80 stuff
  46. z80.z80Base=Pico.zram;
  47. z80.z80MemRead=mz80_mem_read;
  48. z80.z80MemWrite=mz80_mem_write;
  49. z80.z80IoRead=mz80_io_read;
  50. z80.z80IoWrite=mz80_io_write;
  51. mz80SetContext(&z80);
  52. #endif
  53. #ifdef _USE_DRZ80
  54. memset(&drZ80, 0, sizeof(drZ80));
  55. drZ80.z80_rebasePC=NULL; // unused, handled by xmap
  56. drZ80.z80_rebaseSP=NULL;
  57. drZ80.z80_read8 =(void *)z80_read_map;
  58. drZ80.z80_read16 =NULL;
  59. drZ80.z80_write8 =(void *)z80_write_map;
  60. drZ80.z80_write16 =NULL;
  61. drZ80.z80_irq_callback=NULL;
  62. #endif
  63. #ifdef _USE_CZ80
  64. memset(&CZ80, 0, sizeof(CZ80));
  65. Cz80_Init(&CZ80);
  66. Cz80_Set_ReadB(&CZ80, NULL); // unused (hacked in)
  67. Cz80_Set_WriteB(&CZ80, NULL);
  68. #endif
  69. }
  70. PICO_INTERNAL void z80_reset(void)
  71. {
  72. #ifdef _USE_MZ80
  73. mz80reset();
  74. #endif
  75. #ifdef _USE_DRZ80
  76. memset(&drZ80, 0, 0x54);
  77. drZ80.Z80F = (1<<2); // set ZFlag
  78. drZ80.Z80F2 = (1<<2); // set ZFlag
  79. drZ80.Z80IX = 0xFFFF << 16;
  80. drZ80.Z80IY = 0xFFFF << 16;
  81. drZ80.Z80IM = 0; // 1?
  82. drZ80.z80irqvector = 0xff0000; // RST 38h
  83. drZ80.Z80PC_BASE = drZ80.Z80PC = z80_read_map[0] << 1;
  84. // drZ80 is locked in single bank
  85. drZ80.Z80SP_BASE = ((PicoAHW & PAHW_SMS) ?
  86. z80_read_map[0xc000 >> Z80_MEM_SHIFT] : z80_read_map[0]) << 1;
  87. // drZ80.Z80SP = drZ80.z80_rebaseSP(0x2000); // 0xf000 ?
  88. #endif
  89. #ifdef _USE_CZ80
  90. Cz80_Reset(&CZ80);
  91. Cz80_Set_Reg(&CZ80, CZ80_IX, 0xffff);
  92. Cz80_Set_Reg(&CZ80, CZ80_IY, 0xffff);
  93. Cz80_Set_Reg(&CZ80, CZ80_SP, 0x2000);
  94. #endif
  95. }
  96. // XXX TODO: should better use universal z80 save format
  97. PICO_INTERNAL void z80_pack(unsigned char *data)
  98. {
  99. #if defined(_USE_MZ80)
  100. struct mz80context mz80;
  101. *(int *)data = 0x00005A6D; // "mZ"
  102. mz80GetContext(&mz80);
  103. memcpy(data+4, &mz80.z80clockticks, sizeof(mz80)-5*4); // don't save base&memhandlers
  104. #elif defined(_USE_DRZ80)
  105. *(int *)data = 0x015A7244; // "DrZ" v1
  106. // drZ80.Z80PC = drZ80.z80_rebasePC(drZ80.Z80PC-drZ80.Z80PC_BASE);
  107. // drZ80.Z80SP = drZ80.z80_rebaseSP(drZ80.Z80SP-drZ80.Z80SP_BASE);
  108. memcpy(data+4, &drZ80, 0x54);
  109. #elif defined(_USE_CZ80)
  110. *(int *)data = 0x00007a43; // "Cz"
  111. *(int *)(data+4) = Cz80_Get_Reg(&CZ80, CZ80_PC);
  112. memcpy(data+8, &CZ80, (INT32)&CZ80.BasePC - (INT32)&CZ80);
  113. #endif
  114. }
  115. PICO_INTERNAL void z80_unpack(unsigned char *data)
  116. {
  117. #if defined(_USE_MZ80)
  118. if (*(int *)data == 0x00005A6D) { // "mZ" save?
  119. struct mz80context mz80;
  120. mz80GetContext(&mz80);
  121. memcpy(&mz80.z80clockticks, data+4, sizeof(mz80)-5*4);
  122. mz80SetContext(&mz80);
  123. } else {
  124. z80_reset();
  125. z80_int();
  126. }
  127. #elif defined(_USE_DRZ80)
  128. if (*(int *)data == 0x015A7244) { // "DrZ" v1 save?
  129. int pc, sp;
  130. memcpy(&drZ80, data+4, 0x54);
  131. pc = (drZ80.Z80PC - drZ80.Z80PC_BASE) & 0xffff;
  132. sp = (drZ80.Z80SP - drZ80.Z80SP_BASE) & 0xffff;
  133. // update bases
  134. drZ80.Z80PC_BASE = z80_read_map[pc >> Z80_MEM_SHIFT];
  135. if (drZ80.Z80PC & (1<<31)) {
  136. elprintf(EL_STATUS|EL_ANOMALY, "bad PC in z80 save: %04x", pc);
  137. drZ80.Z80PC_BASE = drZ80.Z80PC = z80_read_map[0];
  138. } else {
  139. drZ80.Z80PC_BASE <<= 1;
  140. drZ80.Z80PC = drZ80.Z80PC_BASE + pc;
  141. }
  142. drZ80.Z80SP_BASE = z80_read_map[sp >> Z80_MEM_SHIFT];
  143. if (drZ80.Z80SP & (1<<31)) {
  144. elprintf(EL_STATUS|EL_ANOMALY, "bad SP in z80 save: %04x", sp);
  145. drZ80.Z80SP_BASE = z80_read_map[0];
  146. drZ80.Z80SP = drZ80.Z80SP_BASE + (1 << Z80_MEM_SHIFT);
  147. } else {
  148. drZ80.Z80SP_BASE <<= 1;
  149. drZ80.Z80SP = drZ80.Z80SP_BASE + sp;
  150. }
  151. } else {
  152. z80_reset();
  153. drZ80.Z80IM = 1;
  154. z80_int(); // try to goto int handler, maybe we won't execute trash there?
  155. }
  156. #elif defined(_USE_CZ80)
  157. if (*(int *)data == 0x00007a43) { // "Cz" save?
  158. memcpy(&CZ80, data+8, (INT32)&CZ80.BasePC - (INT32)&CZ80);
  159. Cz80_Set_Reg(&CZ80, CZ80_PC, *(int *)(data+4));
  160. } else {
  161. z80_reset();
  162. z80_int();
  163. }
  164. #endif
  165. }
  166. PICO_INTERNAL void z80_exit(void)
  167. {
  168. #if defined(_USE_MZ80)
  169. mz80shutdown();
  170. #endif
  171. }
  172. PICO_INTERNAL void z80_debug(char *dstr)
  173. {
  174. #if defined(_USE_DRZ80)
  175. sprintf(dstr, "Z80 state: PC: %04x SP: %04x\n", drZ80.Z80PC-drZ80.Z80PC_BASE, drZ80.Z80SP-drZ80.Z80SP_BASE);
  176. #elif defined(_USE_CZ80)
  177. sprintf(dstr, "Z80 state: PC: %04x SP: %04x\n", CZ80.PC - CZ80.BasePC, CZ80.SP.W);
  178. #endif
  179. }