bugfixes related to mmap usage for ROM
[picodrive.git] / pico / cd / sek.c
1 // (c) Copyright 2007 notaz, All rights reserved.
2
3
4 #include "../pico_int.h"
5
6
7 int SekCycleCntS68k=0; // cycles done in this frame
8 int SekCycleAimS68k=0; // cycle aim
9
10
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
25
26 static int new_irq_level(int level)
27 {
28   int level_new = 0, irqs;
29   Pico_mcd->m.s68k_pend_ints &= ~(1 << level);
30   irqs = Pico_mcd->m.s68k_pend_ints;
31   irqs &= Pico_mcd->s68k_regs[0x33];
32   while ((irqs >>= 1)) level_new++;
33
34   return level_new;
35 }
36
37 #ifdef EMU_C68K
38 // interrupt acknowledgement
39 static int SekIntAckS68k(int level)
40 {
41   int level_new = new_irq_level(level);
42
43   elprintf(EL_INTS, "s68kACK %i -> %i", level, level_new);
44   PicoCpuCS68k.irq = level_new;
45   return CYCLONE_INT_ACK_AUTOVECTOR;
46 }
47
48 static void SekResetAckS68k(void)
49 {
50   elprintf(EL_ANOMALY, "s68k: Reset encountered @ %06x", SekPcS68k);
51 }
52
53 static int SekUnrecognizedOpcodeS68k(void)
54 {
55   elprintf(EL_ANOMALY, "Unrecognized Opcode @ %06x", SekPcS68k);
56   //exit(1);
57   return 0;
58 }
59 #endif
60
61 #ifdef EMU_M68K
62 static int SekIntAckMS68k(int level)
63 {
64 #ifndef EMU_CORE_DEBUG
65   int level_new = new_irq_level(level);
66   elprintf(EL_INTS, "s68kACK %i -> %i", level, level_new);
67   CPU_INT_LEVEL = level_new << 8;
68 #else
69   CPU_INT_LEVEL = 0;
70 #endif
71   return M68K_INT_ACK_AUTOVECTOR;
72 }
73 #endif
74
75 #ifdef EMU_F68K
76 static void SekIntAckFS68k(unsigned level)
77 {
78   int level_new = new_irq_level(level);
79   elprintf(EL_INTS, "s68kACK %i -> %i", level, level_new);
80 #ifndef EMU_CORE_DEBUG
81   PicoCpuFS68k.interrupts[0] = level_new;
82 #else
83   {
84     extern int dbg_irq_level_sub;
85     dbg_irq_level_sub = level_new;
86     PicoCpuFS68k.interrupts[0] = 0;
87   }
88 #endif
89 }
90 #endif
91
92
93 PICO_INTERNAL void SekInitS68k(void)
94 {
95 #ifdef EMU_C68K
96 //  CycloneInit();
97   memset(&PicoCpuCS68k,0,sizeof(PicoCpuCS68k));
98   PicoCpuCS68k.IrqCallback=SekIntAckS68k;
99   PicoCpuCS68k.ResetCallback=SekResetAckS68k;
100   PicoCpuCS68k.UnrecognizedCallback=SekUnrecognizedOpcodeS68k;
101 #endif
102 #ifdef EMU_M68K
103   {
104     // Musashi is not very context friendly..
105     void *oldcontext = m68ki_cpu_p;
106     m68k_set_context(&PicoCpuMS68k);
107     m68k_set_cpu_type(M68K_CPU_TYPE_68000);
108     m68k_init();
109     m68k_set_int_ack_callback(SekIntAckMS68k);
110 //  m68k_pulse_reset(); // not yet, memmap is not set up
111     m68k_set_context(oldcontext);
112   }
113 #endif
114 #ifdef EMU_F68K
115   {
116     void *oldcontext = g_m68kcontext;
117     g_m68kcontext = &PicoCpuFS68k;
118     memset(&PicoCpuFS68k, 0, sizeof(PicoCpuFS68k));
119     fm68k_init();
120     PicoCpuFS68k.iack_handler = SekIntAckFS68k;
121     PicoCpuFS68k.sr = 0x2704; // Z flag
122     g_m68kcontext = oldcontext;
123   }
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   {
148     void *oldcontext = g_m68kcontext;
149     g_m68kcontext = &PicoCpuFS68k;
150     fm68k_reset();
151     g_m68kcontext = oldcontext;
152   }
153 #endif
154
155   return 0;
156 }
157
158 PICO_INTERNAL int SekInterruptS68k(int irq)
159 {
160   int irqs, real_irq = 1;
161   Pico_mcd->m.s68k_pend_ints |= 1 << irq;
162   irqs = Pico_mcd->m.s68k_pend_ints >> 1;
163   while ((irqs >>= 1)) real_irq++;
164
165 #ifdef EMU_CORE_DEBUG
166   {
167     extern int dbg_irq_level_sub;
168     dbg_irq_level_sub=real_irq;
169     return 0;
170   }
171 #endif
172 #ifdef EMU_C68K
173   PicoCpuCS68k.irq=real_irq;
174 #endif
175 #ifdef EMU_M68K
176   void *oldcontext = m68ki_cpu_p;
177   m68k_set_context(&PicoCpuMS68k);
178   m68k_set_irq(real_irq);
179   m68k_set_context(oldcontext);
180 #endif
181 #ifdef EMU_F68K
182   PicoCpuFS68k.interrupts[0]=real_irq;
183 #endif
184   return 0;
185 }
186