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