region detection, cd states wip, fixes, stuff
[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 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_M68K
38 static int SekIntAckS68k(int level)
39 {
40   int level_new = new_irq_level(level);
41   dprintf("s68kACK %i -> %i", level, level_new);
42   CPU_INT_LEVEL = level_new << 8;
43   return M68K_INT_ACK_AUTOVECTOR;
44 }
45 #endif
46
47 #ifdef EMU_C68K
48 // interrupt acknowledgment
49 static void SekIntAckS68k(int level)
50 {
51   int level_new = new_irq_level(level);
52
53   dprintf("s68kACK %i -> %i", level, level_new);
54   PicoCpuS68k.irq = level_new;
55 }
56
57 static void SekResetAck()
58 {
59   dprintf("s68k: Reset encountered @ %06x", SekPcS68k);
60 }
61
62 static int SekUnrecognizedOpcode()
63 {
64   unsigned int pc, op;
65   pc = SekPcS68k;
66   op = PicoCpuS68k.read16(pc);
67   dprintf("Unrecognized Opcode %04x @ %06x", op, pc);
68   //exit(1);
69   return 0;
70 }
71 #endif
72
73
74
75 int SekInitS68k()
76 {
77 #ifdef EMU_C68K
78 //  CycloneInit();
79   memset(&PicoCpuS68k,0,sizeof(PicoCpuS68k));
80   PicoCpuS68k.IrqCallback=SekIntAckS68k;
81   PicoCpuS68k.ResetCallback=SekResetAck;
82   PicoCpuS68k.UnrecognizedCallback=SekUnrecognizedOpcode;
83 #endif
84 #ifdef EMU_M68K
85   {
86     // Musashi is not very context friendly..
87     void *oldcontext = m68ki_cpu_p;
88     m68k_set_context(&PicoS68kCPU);
89     m68k_set_cpu_type(M68K_CPU_TYPE_68000);
90     m68k_init();
91     m68k_set_int_ack_callback(SekIntAckS68k);
92 //  m68k_pulse_reset(); // not yet, memmap is not set up
93     m68k_set_context(oldcontext);
94   }
95 #endif
96
97   return 0;
98 }
99
100 // Reset the 68000:
101 int SekResetS68k()
102 {
103   if (Pico.rom==NULL) return 1;
104
105 #ifdef EMU_C68K
106   PicoCpuS68k.stopped=0;
107   PicoCpuS68k.osp=0;
108   PicoCpuS68k.srh =0x27; // Supervisor mode
109   PicoCpuS68k.flags=4;   // Z set
110   PicoCpuS68k.irq=0;
111   PicoCpuS68k.a[7]=PicoCpuS68k.read32(0); // Stack Pointer
112   PicoCpuS68k.membase=0;
113   PicoCpuS68k.pc=PicoCpuS68k.checkpc(PicoCpuS68k.read32(4)); // Program Counter
114 #endif
115 #ifdef EMU_M68K
116   {
117     void *oldcontext = m68ki_cpu_p;
118
119     m68k_set_context(&PicoS68kCPU);
120     m68k_pulse_reset();
121     m68k_set_context(oldcontext);
122   }
123 #endif
124
125   return 0;
126 }
127
128 int SekInterruptS68k(int irq)
129 {
130   int irqs, real_irq = 1;
131   Pico_mcd->m.s68k_pend_ints |= 1 << irq;
132   irqs = Pico_mcd->m.s68k_pend_ints >> 1;
133   while ((irqs >>= 1)) real_irq++; // this is probably only needed for Cyclone
134
135 #ifdef EMU_C68K
136   PicoCpuS68k.irq=real_irq;
137 #endif
138 #ifdef EMU_M68K
139   void *oldcontext = m68ki_cpu_p;
140   m68k_set_context(&PicoS68kCPU);
141   m68k_set_irq(real_irq); // raise irq (gets lowered after taken or must be done in ack)
142   m68k_set_context(oldcontext);
143 #endif
144   return 0;
145 }
146