sek.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * PicoDrive
  3. * (C) notaz, 2007
  4. *
  5. * This work is licensed under the terms of MAME license.
  6. * See COPYING file in the top-level directory.
  7. */
  8. #include "../pico_int.h"
  9. int SekCycleCntS68k=0; // cycles done in this frame
  10. int SekCycleAimS68k=0; // cycle aim
  11. /* context */
  12. // Cyclone 68000
  13. #ifdef EMU_C68K
  14. struct Cyclone PicoCpuCS68k;
  15. #endif
  16. // MUSASHI 68000
  17. #ifdef EMU_M68K
  18. m68ki_cpu_core PicoCpuMS68k;
  19. #endif
  20. // FAME 68000
  21. #ifdef EMU_F68K
  22. M68K_CONTEXT PicoCpuFS68k;
  23. #endif
  24. static int new_irq_level(int level)
  25. {
  26. int level_new = 0, irqs;
  27. Pico_mcd->m.s68k_pend_ints &= ~(1 << level);
  28. irqs = Pico_mcd->m.s68k_pend_ints;
  29. irqs &= Pico_mcd->s68k_regs[0x33];
  30. while ((irqs >>= 1)) level_new++;
  31. return level_new;
  32. }
  33. #ifdef EMU_C68K
  34. // interrupt acknowledgement
  35. static int SekIntAckS68k(int level)
  36. {
  37. int level_new = new_irq_level(level);
  38. elprintf(EL_INTS, "s68kACK %i -> %i", level, level_new);
  39. PicoCpuCS68k.irq = level_new;
  40. return CYCLONE_INT_ACK_AUTOVECTOR;
  41. }
  42. static void SekResetAckS68k(void)
  43. {
  44. elprintf(EL_ANOMALY, "s68k: Reset encountered @ %06x", SekPcS68k);
  45. }
  46. static int SekUnrecognizedOpcodeS68k(void)
  47. {
  48. elprintf(EL_ANOMALY, "Unrecognized Opcode @ %06x", SekPcS68k);
  49. //exit(1);
  50. return 0;
  51. }
  52. #endif
  53. #ifdef EMU_M68K
  54. static int SekIntAckMS68k(int level)
  55. {
  56. #ifndef EMU_CORE_DEBUG
  57. int level_new = new_irq_level(level);
  58. elprintf(EL_INTS, "s68kACK %i -> %i", level, level_new);
  59. CPU_INT_LEVEL = level_new << 8;
  60. #else
  61. CPU_INT_LEVEL = 0;
  62. #endif
  63. return M68K_INT_ACK_AUTOVECTOR;
  64. }
  65. #endif
  66. #ifdef EMU_F68K
  67. static void SekIntAckFS68k(unsigned level)
  68. {
  69. int level_new = new_irq_level(level);
  70. elprintf(EL_INTS, "s68kACK %i -> %i", level, level_new);
  71. #ifndef EMU_CORE_DEBUG
  72. PicoCpuFS68k.interrupts[0] = level_new;
  73. #else
  74. {
  75. extern int dbg_irq_level_sub;
  76. dbg_irq_level_sub = level_new;
  77. PicoCpuFS68k.interrupts[0] = 0;
  78. }
  79. #endif
  80. }
  81. #endif
  82. PICO_INTERNAL void SekInitS68k(void)
  83. {
  84. #ifdef EMU_C68K
  85. // CycloneInit();
  86. memset(&PicoCpuCS68k,0,sizeof(PicoCpuCS68k));
  87. PicoCpuCS68k.IrqCallback=SekIntAckS68k;
  88. PicoCpuCS68k.ResetCallback=SekResetAckS68k;
  89. PicoCpuCS68k.UnrecognizedCallback=SekUnrecognizedOpcodeS68k;
  90. #endif
  91. #ifdef EMU_M68K
  92. {
  93. // Musashi is not very context friendly..
  94. void *oldcontext = m68ki_cpu_p;
  95. m68k_set_context(&PicoCpuMS68k);
  96. m68k_set_cpu_type(M68K_CPU_TYPE_68000);
  97. m68k_init();
  98. m68k_set_int_ack_callback(SekIntAckMS68k);
  99. // m68k_pulse_reset(); // not yet, memmap is not set up
  100. m68k_set_context(oldcontext);
  101. }
  102. #endif
  103. #ifdef EMU_F68K
  104. {
  105. void *oldcontext = g_m68kcontext;
  106. g_m68kcontext = &PicoCpuFS68k;
  107. memset(&PicoCpuFS68k, 0, sizeof(PicoCpuFS68k));
  108. fm68k_init();
  109. PicoCpuFS68k.iack_handler = SekIntAckFS68k;
  110. PicoCpuFS68k.sr = 0x2704; // Z flag
  111. g_m68kcontext = oldcontext;
  112. }
  113. #endif
  114. }
  115. // Reset the 68000:
  116. PICO_INTERNAL int SekResetS68k(void)
  117. {
  118. if (Pico.rom==NULL) return 1;
  119. #ifdef EMU_C68K
  120. CycloneReset(&PicoCpuCS68k);
  121. #endif
  122. #ifdef EMU_M68K
  123. {
  124. void *oldcontext = m68ki_cpu_p;
  125. m68k_set_context(&PicoCpuMS68k);
  126. m68ki_cpu.sp[0]=0;
  127. m68k_set_irq(0);
  128. m68k_pulse_reset();
  129. m68k_set_context(oldcontext);
  130. }
  131. #endif
  132. #ifdef EMU_F68K
  133. {
  134. void *oldcontext = g_m68kcontext;
  135. g_m68kcontext = &PicoCpuFS68k;
  136. fm68k_reset();
  137. g_m68kcontext = oldcontext;
  138. }
  139. #endif
  140. return 0;
  141. }
  142. PICO_INTERNAL int SekInterruptS68k(int irq)
  143. {
  144. int irqs, real_irq = 1;
  145. Pico_mcd->m.s68k_pend_ints |= 1 << irq;
  146. irqs = Pico_mcd->m.s68k_pend_ints >> 1;
  147. while ((irqs >>= 1)) real_irq++;
  148. #ifdef EMU_CORE_DEBUG
  149. {
  150. extern int dbg_irq_level_sub;
  151. dbg_irq_level_sub=real_irq;
  152. return 0;
  153. }
  154. #endif
  155. #ifdef EMU_C68K
  156. PicoCpuCS68k.irq=real_irq;
  157. #endif
  158. #ifdef EMU_M68K
  159. void *oldcontext = m68ki_cpu_p;
  160. m68k_set_context(&PicoCpuMS68k);
  161. m68k_set_irq(real_irq);
  162. m68k_set_context(oldcontext);
  163. #endif
  164. #ifdef EMU_F68K
  165. PicoCpuFS68k.interrupts[0]=real_irq;
  166. #endif
  167. return 0;
  168. }