region detection, cd states wip, fixes, stuff
[picodrive.git] / Pico / cd / Sek.c
CommitLineData
cc68a136 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
b837b69b 16#ifdef EMU_C68K
17// ---------------------- Cyclone 68000 ----------------------
18struct Cyclone PicoCpuS68k;
19#endif
20
cc68a136 21#ifdef EMU_M68K
22// ---------------------- MUSASHI 68000 ----------------------
23m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU
24#endif
25
51a902ae 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++;
b837b69b 33
51a902ae 34 return level_new;
35}
cc68a136 36
37#ifdef EMU_M68K
b837b69b 38static int SekIntAckS68k(int level)
cc68a136 39{
51a902ae 40 int level_new = new_irq_level(level);
b837b69b 41 dprintf("s68kACK %i -> %i", level, level_new);
42 CPU_INT_LEVEL = level_new << 8;
cc68a136 43 return M68K_INT_ACK_AUTOVECTOR;
44}
45#endif
46
b837b69b 47#ifdef EMU_C68K
48// interrupt acknowledgment
51a902ae 49static void SekIntAckS68k(int level)
b837b69b 50{
51a902ae 51 int level_new = new_irq_level(level);
b837b69b 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
cc68a136 74
75int SekInitS68k()
76{
b837b69b 77#ifdef EMU_C68K
78// CycloneInit();
79 memset(&PicoCpuS68k,0,sizeof(PicoCpuS68k));
51a902ae 80 PicoCpuS68k.IrqCallback=SekIntAckS68k;
b837b69b 81 PicoCpuS68k.ResetCallback=SekResetAck;
82 PicoCpuS68k.UnrecognizedCallback=SekUnrecognizedOpcode;
83#endif
cc68a136 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
b837b69b 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
cc68a136 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{
51a902ae 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
b837b69b 135#ifdef EMU_C68K
51a902ae 136 PicoCpuS68k.irq=real_irq;
b837b69b 137#endif
cc68a136 138#ifdef EMU_M68K
139 void *oldcontext = m68ki_cpu_p;
140 m68k_set_context(&PicoS68kCPU);
51a902ae 141 m68k_set_irq(real_irq); // raise irq (gets lowered after taken or must be done in ack)
cc68a136 142 m68k_set_context(oldcontext);
143#endif
144 return 0;
145}
146