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