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