better mmuhack usage
[picodrive.git] / Pico / cd / Sek.c
1 // (c) Copyright 2006 notaz, All rights reserved.
2
3
4 #include "../PicoInt.h"
5
6
7 int SekCycleCntS68k=0; // cycles done in this frame
8 int SekCycleAimS68k=0; // cycle aim
9
10 #ifdef EMU_C68K
11 // ---------------------- Cyclone 68000 ----------------------
12 struct Cyclone PicoCpuS68k;
13 #endif
14
15 #ifdef EMU_M68K
16 // ---------------------- MUSASHI 68000 ----------------------
17 m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU
18 #endif
19
20 static int new_irq_level(int level)
21 {
22   int level_new = 0, irqs;
23   Pico_mcd->m.s68k_pend_ints &= ~(1 << level);
24   irqs = Pico_mcd->m.s68k_pend_ints;
25   irqs &= Pico_mcd->s68k_regs[0x33];
26   while ((irqs >>= 1)) level_new++;
27
28   return level_new;
29 }
30
31 #ifdef EMU_M68K
32 static int SekIntAckS68k(int level)
33 {
34   int level_new = new_irq_level(level);
35   dprintf("s68kACK %i -> %i", level, level_new);
36   CPU_INT_LEVEL = level_new << 8;
37   return M68K_INT_ACK_AUTOVECTOR;
38 }
39 #endif
40
41 #ifdef EMU_C68K
42 // interrupt acknowledgment
43 static void SekIntAckS68k(int level)
44 {
45   int level_new = new_irq_level(level);
46
47   dprintf("s68kACK %i -> %i", level, level_new);
48   PicoCpuS68k.irq = level_new;
49 }
50
51 static void SekResetAck()
52 {
53   dprintf("s68k: Reset encountered @ %06x", SekPcS68k);
54 }
55
56 static int SekUnrecognizedOpcode()
57 {
58   unsigned int pc, op;
59   pc = SekPcS68k;
60   op = PicoCpuS68k.read16(pc);
61   dprintf("Unrecognized Opcode %04x @ %06x", op, pc);
62   //exit(1);
63   return 0;
64 }
65 #endif
66
67
68
69 int SekInitS68k()
70 {
71 #ifdef EMU_C68K
72 //  CycloneInit();
73   memset(&PicoCpuS68k,0,sizeof(PicoCpuS68k));
74   PicoCpuS68k.IrqCallback=SekIntAckS68k;
75   PicoCpuS68k.ResetCallback=SekResetAck;
76   PicoCpuS68k.UnrecognizedCallback=SekUnrecognizedOpcode;
77 #endif
78 #ifdef EMU_M68K
79   {
80     // Musashi is not very context friendly..
81     void *oldcontext = m68ki_cpu_p;
82     m68k_set_context(&PicoS68kCPU);
83     m68k_set_cpu_type(M68K_CPU_TYPE_68000);
84     m68k_init();
85     m68k_set_int_ack_callback(SekIntAckS68k);
86 //  m68k_pulse_reset(); // not yet, memmap is not set up
87     m68k_set_context(oldcontext);
88   }
89 #endif
90
91   return 0;
92 }
93
94 // Reset the 68000:
95 int SekResetS68k()
96 {
97   if (Pico.rom==NULL) return 1;
98
99 #ifdef EMU_C68K
100   PicoCpuS68k.stopped=0;
101   PicoCpuS68k.osp=0;
102   PicoCpuS68k.srh =0x27; // Supervisor mode
103   PicoCpuS68k.flags=4;   // Z set
104   PicoCpuS68k.irq=0;
105   PicoCpuS68k.a[7]=PicoCpuS68k.read32(0); // Stack Pointer
106   PicoCpuS68k.membase=0;
107   PicoCpuS68k.pc=PicoCpuS68k.checkpc(PicoCpuS68k.read32(4)); // Program Counter
108 #endif
109 #ifdef EMU_M68K
110   {
111     void *oldcontext = m68ki_cpu_p;
112
113     m68k_set_context(&PicoS68kCPU);
114     m68k_pulse_reset();
115     m68k_set_context(oldcontext);
116   }
117 #endif
118
119   return 0;
120 }
121
122 int SekInterruptS68k(int irq)
123 {
124   int irqs, real_irq = 1;
125   Pico_mcd->m.s68k_pend_ints |= 1 << irq;
126   irqs = Pico_mcd->m.s68k_pend_ints >> 1;
127   while ((irqs >>= 1)) real_irq++; // this is probably only needed for Cyclone
128
129 #ifdef EMU_C68K
130   PicoCpuS68k.irq=real_irq;
131 #endif
132 #ifdef EMU_M68K
133   void *oldcontext = m68ki_cpu_p;
134   m68k_set_context(&PicoS68kCPU);
135   m68k_set_irq(real_irq); // raise irq (gets lowered after taken or must be done in ack)
136   m68k_set_context(oldcontext);
137 #endif
138   return 0;
139 }
140