sek.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. unsigned int SekCycleCntS68k;
  10. unsigned int SekCycleAimS68k;
  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. memset(&PicoCpuFS68k, 0, sizeof(PicoCpuFS68k));
  105. fm68k_init();
  106. PicoCpuFS68k.iack_handler = SekIntAckFS68k;
  107. PicoCpuFS68k.sr = 0x2704; // Z flag
  108. #endif
  109. }
  110. // Reset the 68000:
  111. PICO_INTERNAL int SekResetS68k(void)
  112. {
  113. if (Pico.rom==NULL) return 1;
  114. #ifdef EMU_C68K
  115. CycloneReset(&PicoCpuCS68k);
  116. #endif
  117. #ifdef EMU_M68K
  118. {
  119. void *oldcontext = m68ki_cpu_p;
  120. m68k_set_context(&PicoCpuMS68k);
  121. m68ki_cpu.sp[0]=0;
  122. m68k_set_irq(0);
  123. m68k_pulse_reset();
  124. m68k_set_context(oldcontext);
  125. }
  126. #endif
  127. #ifdef EMU_F68K
  128. fm68k_reset(&PicoCpuFS68k);
  129. #endif
  130. return 0;
  131. }
  132. PICO_INTERNAL int SekInterruptS68k(int irq)
  133. {
  134. int irqs, real_irq = 1;
  135. Pico_mcd->m.s68k_pend_ints |= 1 << irq;
  136. irqs = Pico_mcd->m.s68k_pend_ints >> 1;
  137. while ((irqs >>= 1)) real_irq++;
  138. #ifdef EMU_CORE_DEBUG
  139. {
  140. extern int dbg_irq_level_sub;
  141. dbg_irq_level_sub=real_irq;
  142. return 0;
  143. }
  144. #endif
  145. #ifdef EMU_C68K
  146. PicoCpuCS68k.irq=real_irq;
  147. #endif
  148. #ifdef EMU_M68K
  149. // avoid m68k_set_irq() for delaying to work
  150. PicoCpuMS68k.int_level = real_irq << 8;
  151. #endif
  152. #ifdef EMU_F68K
  153. PicoCpuFS68k.interrupts[0]=real_irq;
  154. #endif
  155. return 0;
  156. }
  157. void SekInterruptClearS68k(int irq)
  158. {
  159. int level_new = new_irq_level(irq);
  160. #ifdef EMU_C68K
  161. PicoCpuCS68k.irq = level_new;
  162. #endif
  163. #ifdef EMU_M68K
  164. CPU_INT_LEVEL = level_new << 8;
  165. #endif
  166. #ifdef EMU_F68K
  167. PicoCpuFS68k.interrupts[0] = level_new;
  168. #endif
  169. }