region detection, cd states wip, fixes, stuff
[picodrive.git] / Pico / cd / Sek.c
... / ...
CommitLineData
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
13int SekCycleCntS68k=0; // cycles done in this frame
14int SekCycleAimS68k=0; // cycle aim
15
16#ifdef EMU_C68K
17// ---------------------- Cyclone 68000 ----------------------
18struct Cyclone PicoCpuS68k;
19#endif
20
21#ifdef EMU_M68K
22// ---------------------- MUSASHI 68000 ----------------------
23m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU
24#endif
25
26static 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
38static 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
49static 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
57static void SekResetAck()
58{
59 dprintf("s68k: Reset encountered @ %06x", SekPcS68k);
60}
61
62static 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
75int 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:
101int 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
128int 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