CycloneSetSr(context, *(unsigned int *)(cpu+0x44));\r
context->osp=*(unsigned int *)(cpu+0x48);\r
memcpy(context->d,cpu,0x40);\r
- context->membase=0;\r
- context->pc = context->checkpc(*(unsigned int *)(cpu+0x40)); // Base pc\r
+ context->membase = 0;\r
+ context->pc = *(unsigned int *)(cpu+0x40);\r
+ CycloneUnpack(context, NULL); // rebase PC\r
context->irq = cpu[0x4c];\r
context->state_flags = 0;\r
if (cpu[0x4d])\r
\r
// -----------------------------------------------------------------\r
\r
-#ifdef EMU_C68K\r
-static __inline int PicoMemBaseM68k(u32 pc)\r
-{\r
- if ((pc&0xe00000)==0xe00000)\r
- return (int)Pico.ram-(pc&0xff0000); // Program Counter in Ram\r
-\r
- if (pc < 0x20000)\r
- return (int)Pico_mcd->bios; // Program Counter in BIOS\r
-\r
- if ((pc&0xfc0000)==0x200000)\r
- {\r
- if (!(Pico_mcd->s68k_regs[3]&4))\r
- return (int)Pico_mcd->word_ram2M - 0x200000; // Program Counter in Word Ram\r
- if (pc < 0x220000) {\r
- int bank = Pico_mcd->s68k_regs[3]&1;\r
- return (int)Pico_mcd->word_ram1M[bank] - 0x200000;\r
- }\r
- }\r
-\r
- // Error - Program Counter is invalid\r
- elprintf(EL_ANOMALY, "m68k FIXME: unhandled jump to %06x", pc);\r
-\r
- return (int)Pico_mcd->bios;\r
-}\r
-\r
-\r
-static u32 PicoCheckPcM68k(u32 pc)\r
-{\r
- pc-=PicoCpuCM68k.membase; // Get real pc\r
- pc&=0xfffffe;\r
-\r
- PicoCpuCM68k.membase=PicoMemBaseM68k(pc);\r
-\r
- return PicoCpuCM68k.membase+pc;\r
-}\r
-\r
-\r
-static __inline int PicoMemBaseS68k(u32 pc)\r
-{\r
- if (pc < 0x80000) // PRG RAM\r
- return (int)Pico_mcd->prg_ram;\r
-\r
- if ((pc&0xfc0000)==0x080000) // WORD RAM 2M area (assume we are in the right mode..)\r
- return (int)Pico_mcd->word_ram2M - 0x080000;\r
-\r
- if ((pc&0xfe0000)==0x0c0000) { // word RAM 1M area\r
- int bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
- return (int)Pico_mcd->word_ram1M[bank] - 0x0c0000;\r
- }\r
-\r
- // Error - Program Counter is invalid\r
- elprintf(EL_ANOMALY, "s68k FIXME: unhandled jump to %06x", pc);\r
-\r
- return (int)Pico_mcd->prg_ram;\r
-}\r
-\r
-\r
-static u32 PicoCheckPcS68k(u32 pc)\r
-{\r
- pc-=PicoCpuCS68k.membase; // Get real pc\r
- pc&=0xfffffe;\r
-\r
- PicoCpuCS68k.membase=PicoMemBaseS68k(pc);\r
-\r
- return PicoCpuCS68k.membase+pc;\r
-}\r
-#endif\r
-\r
// TODO: probably split\r
void PicoMemRemapCD(int r3)\r
{\r
cpu68k_map_set(s68k_write16_map, 0xff0000, 0xffffff, PicoWriteS68k16_pr, 1);\r
\r
#ifdef EMU_C68K\r
- PicoCpuCM68k.checkpc = PicoCheckPcM68k;\r
// s68k\r
- PicoCpuCS68k.checkpc = PicoCheckPcS68k;\r
- PicoCpuCS68k.fetch8 = PicoCpuCS68k.read8 = s68k_read8;\r
- PicoCpuCS68k.fetch16 = PicoCpuCS68k.read16 = s68k_read16;\r
- PicoCpuCS68k.fetch32 = PicoCpuCS68k.read32 = s68k_read32;\r
- PicoCpuCS68k.write8 = s68k_write8;\r
- PicoCpuCS68k.write16 = s68k_write16;\r
- PicoCpuCS68k.write32 = s68k_write32;\r
+ PicoCpuCS68k.read8 = (void *)s68k_read8_map;\r
+ PicoCpuCS68k.read16 = (void *)s68k_read16_map;\r
+ PicoCpuCS68k.read32 = (void *)s68k_read16_map;\r
+ PicoCpuCS68k.write8 = (void *)s68k_write8_map;\r
+ PicoCpuCS68k.write16 = (void *)s68k_write16_map;\r
+ PicoCpuCS68k.write32 = (void *)s68k_write16_map;\r
+ PicoCpuCS68k.checkpc = NULL; /* unused */\r
+ PicoCpuCS68k.fetch8 = NULL;\r
+ PicoCpuCS68k.fetch16 = NULL;\r
+ PicoCpuCS68k.fetch32 = NULL;\r
#endif\r
#ifdef EMU_F68K\r
// s68k\r
if (Pico.rom==NULL) return 1;
#ifdef EMU_C68K
- PicoCpuCS68k.state_flags=0;
- PicoCpuCS68k.osp=0;
- PicoCpuCS68k.srh =0x27; // Supervisor mode
- PicoCpuCS68k.flags=4; // Z set
- PicoCpuCS68k.irq=0;
- PicoCpuCS68k.a[7]=PicoCpuCS68k.read32(0); // Stack Pointer
- PicoCpuCS68k.membase=0;
- PicoCpuCS68k.pc=PicoCpuCS68k.checkpc(PicoCpuCS68k.read32(4)); // Program Counter
+ CycloneReset(&PicoCpuCS68k);
#endif
#ifdef EMU_M68K
{
--- /dev/null
+@ vim:filetype=armasm
+
+.equ M68K_MEM_SHIFT, 16
+
+.global cyclone_checkpc
+.global cyclone_fetch8
+.global cyclone_fetch16
+.global cyclone_fetch32
+.global cyclone_read8
+.global cyclone_read16
+.global cyclone_read32
+.global cyclone_write8
+.global cyclone_write16
+.global cyclone_write32
+
+@ Warning: here we abuse the fact that we are only called
+@ from Cyclone, and assume that r7 contains context pointer.
+cyclone_checkpc:
+ ldr r1, [r7, #0x60] @ membase
+ sub r0, r0, r1
+ bic r0, r0, #0xff000000
+ bics r0, r0, #1
+ beq crashed
+
+ ldr r1, [r7, #0x6c] @ read16 map
+ mov r2, r0, lsr #M68K_MEM_SHIFT
+ ldr r1, [r1, r2, lsl #2]
+ movs r1, r1, lsl #1
+ bcs crashed
+
+ str r1, [r7, #0x60] @ membase
+ add r0, r0, r1
+ bx lr
+
+crashed:
+ stmfd sp!,{lr}
+ mov r1, r7
+ bl cyclone_crashed
+ ldr r0, [r7, #0x40] @ reload PC + membase
+ ldmfd sp!,{pc}
+
+
+cyclone_read8: @ u32 a
+cyclone_fetch8:
+ bic r0, r0, #0xff000000
+ ldr r1, [r7, #0x68] @ read8 map
+ mov r2, r0, lsr #M68K_MEM_SHIFT
+ ldr r1, [r1, r2, lsl #2]
+ eor r2, r0, #1
+ movs r1, r1, lsl #1
+ ldrccb r0, [r1, r2]
+ bxcc lr
+ bx r1
+
+
+cyclone_read16: @ u32 a
+cyclone_fetch16:
+ bic r0, r0, #0xff000000
+ ldr r1, [r7, #0x6c] @ read16 map
+ mov r2, r0, lsr #M68K_MEM_SHIFT
+ ldr r1, [r1, r2, lsl #2]
+ bic r0, r0, #1
+ movs r1, r1, lsl #1
+ ldrcch r0, [r1, r0]
+ bxcc lr
+ bx r1
+
+
+cyclone_read32: @ u32 a
+cyclone_fetch32:
+ bic r0, r0, #0xff000000
+ ldr r1, [r7, #0x6c] @ read16 map
+ mov r2, r0, lsr #M68K_MEM_SHIFT
+ ldr r1, [r1, r2, lsl #2]
+ bic r0, r0, #1
+ movs r1, r1, lsl #1
+ ldrcch r0, [r1, r0]!
+ ldrcch r1, [r1, #2]
+ orrcc r0, r1, r0, lsl #16
+ bxcc lr
+
+ stmfd sp!,{r0,r1,lr}
+ mov lr, pc
+ bx r1
+ mov r2, r0, lsl #16
+ ldmia sp, {r0,r1}
+ str r2, [sp]
+ add r0, r0, #2
+ mov lr, pc
+ bx r1
+ ldr r1, [sp]
+ mov r0, r0, lsl #16
+ orr r0, r1, r0, lsr #16
+ ldmfd sp!,{r1,r2,pc}
+
+
+cyclone_write8: @ u32 a, u8 d
+ bic r0, r0, #0xff000000
+ ldr r2, [r7, #0x74] @ write8 map
+ mov r3, r0, lsr #M68K_MEM_SHIFT
+ ldr r2, [r2, r3, lsl #2]
+ eor r3, r0, #1
+ movs r2, r2, lsl #1
+ strccb r1, [r2, r3]
+ bxcc lr
+ bx r2
+
+
+cyclone_write16: @ u32 a, u16 d
+ bic r0, r0, #0xff000000
+ ldr r2, [r7, #0x78] @ write16 map
+ mov r3, r0, lsr #M68K_MEM_SHIFT
+ ldr r2, [r2, r3, lsl #2]
+ bic r0, r0, #1
+ movs r2, r2, lsl #1
+ strcch r1, [r2, r0]
+ bxcc lr
+ bx r2
+
+
+cyclone_write32: @ u32 a, u32 d
+ bic r0, r0, #0xff000000
+ ldr r2, [r7, #0x78] @ write16 map
+ mov r3, r0, lsr #M68K_MEM_SHIFT
+ ldr r2, [r2, r3, lsl #2]
+ bic r0, r0, #1
+ movs r2, r2, lsl #1
+ movcc r3, r1, lsr #16
+ strcch r3, [r2, r0]!
+ strcch r1, [r2, #2]
+ bxcc lr
+
+ stmfd sp!,{r0-r2,lr}
+ mov r1, r1, lsr #16
+ mov lr, pc
+ bx r2
+ ldmfd sp!,{r0-r2,lr}
+ add r0, r0, #2
+ bx r2
+
#endif\r
\r
#if defined(EMU_C68K)\r
-static __inline int PicoMemBase(u32 pc)\r
+void cyclone_crashed(u32 pc, struct Cyclone *context)\r
{\r
- int membase=0;\r
-\r
- if (pc<Pico.romsize+4)\r
- {\r
- membase=(int)Pico.rom; // Program Counter in Rom\r
- }\r
- else if ((pc&0xe00000)==0xe00000)\r
- {\r
- membase=(int)Pico.ram-(pc&0xff0000); // Program Counter in Ram\r
- }\r
- else\r
- {\r
- // Error - Program Counter is invalid\r
- membase=(int)Pico.rom;\r
- }\r
-\r
- return membase;\r
+ elprintf(EL_STATUS|EL_ANOMALY, "%c68k crash detected @ %06x\n",\r
+ context == &PicoCpuCM68k ? 'm' : 's', pc);\r
+ context->membase = (u32)Pico.rom;\r
+ context->pc = (u32)Pico.rom + Pico.romsize;\r
}\r
#endif\r
\r
-\r
-PICO_INTERNAL u32 PicoCheckPc(u32 pc)\r
-{\r
- u32 ret=0;\r
-#if defined(EMU_C68K)\r
- pc-=PicoCpuCM68k.membase; // Get real pc\r
-// pc&=0xfffffe;\r
- pc&=~1;\r
- if ((pc<<8) == 0)\r
- {\r
- elprintf(EL_STATUS|EL_ANOMALY, "%i:%03i: game crash detected @ %06x\n",\r
- Pico.m.frame_count, Pico.m.scanline, SekPc);\r
- return (int)Pico.rom + Pico.romsize; // common crash condition, may happen with bad ROMs\r
- }\r
-\r
- PicoCpuCM68k.membase=PicoMemBase(pc&0x00ffffff);\r
- PicoCpuCM68k.membase-=pc&0xff000000;\r
-\r
- ret = PicoCpuCM68k.membase+pc;\r
-#endif\r
- return ret;\r
-}\r
-\r
-\r
-PICO_INTERNAL void PicoInitPc(u32 pc)\r
-{\r
- PicoCheckPc(pc);\r
-}\r
-\r
// -----------------------------------------------------------------\r
// memmap helpers\r
\r
return d;\r
}\r
\r
-static void io_ports_write(u32 a, u32 d)\r
+static void NOINLINE io_ports_write(u32 a, u32 d)\r
{\r
a = (a>>1) & 0xf;\r
\r
Pico.m.padTHPhase[a - 1]++;\r
}\r
\r
- // cartain IO ports can be used as RAM\r
+ // certain IO ports can be used as RAM\r
Pico.ioports[a] = d;\r
}\r
\r
-static void ctl_write_z80busreq(u32 d)\r
+static void NOINLINE ctl_write_z80busreq(u32 d)\r
{\r
d&=1; d^=1;\r
elprintf(EL_BUSREQ, "set_zrun: %i->%i [%i] @%06x", Pico.m.z80Run, d, SekCyclesDone(), SekPc);\r
}\r
}\r
\r
-static void ctl_write_z80reset(u32 d)\r
+static void NOINLINE ctl_write_z80reset(u32 d)\r
{\r
d&=1; d^=1;\r
elprintf(EL_BUSREQ, "set_zreset: %i->%i [%i] @%06x", Pico.m.z80_reset, d, SekCyclesDone(), SekPc);\r
d = Pico.m.rotate++;\r
d ^= d << 6;\r
\r
- // bit8 seems to be readable in this range\r
- if ((a & 0xfc01) == 0x1000)\r
- d &= ~0x01;\r
+ if ((a & 0xfc00) == 0x1000) {\r
+ // bit8 seems to be readable in this range\r
+ if (!(a & 1))\r
+ d &= ~0x01;\r
\r
- if ((a & 0xff01) == 0x1100) { // z80 busreq (verified)\r
- d |= (Pico.m.z80Run | Pico.m.z80_reset) & 1;\r
- elprintf(EL_BUSREQ, "get_zrun: %02x [%i] @%06x", d, SekCyclesDone(), SekPc);\r
+ if ((a & 0xff01) == 0x1100) { // z80 busreq (verified)\r
+ d |= (Pico.m.z80Run | Pico.m.z80_reset) & 1;\r
+ elprintf(EL_BUSREQ, "get_zrun: %02x [%i] @%06x", d, SekCyclesDone(), SekPc);\r
+ }\r
goto end;\r
}\r
\r
d ^= (d << 5) ^ (d << 8);\r
\r
// bit8 seems to be readable in this range\r
- if ((a & 0xfc00) == 0x1000)\r
+ if ((a & 0xfc00) == 0x1000) {\r
d &= ~0x0100;\r
\r
- if ((a & 0xff00) == 0x1100) { // z80 busreq\r
- d |= ((Pico.m.z80Run | Pico.m.z80_reset) & 1) << 8;\r
- elprintf(EL_BUSREQ, "get_zrun: %04x [%i] @%06x", d, SekCyclesDone(), SekPc);\r
+ if ((a & 0xff00) == 0x1100) { // z80 busreq\r
+ d |= ((Pico.m.z80Run | Pico.m.z80_reset) & 1) << 8;\r
+ elprintf(EL_BUSREQ, "get_zrun: %04x [%i] @%06x", d, SekCyclesDone(), SekPc);\r
+ }\r
goto end;\r
}\r
\r
\r
// Setup memory callbacks:\r
#ifdef EMU_C68K\r
- PicoCpuCM68k.checkpc = PicoCheckPc;\r
- PicoCpuCM68k.fetch8 = PicoCpuCM68k.read8 = m68k_read8;\r
- PicoCpuCM68k.fetch16 = PicoCpuCM68k.read16 = m68k_read16;\r
- PicoCpuCM68k.fetch32 = PicoCpuCM68k.read32 = m68k_read32;\r
- PicoCpuCM68k.write8 = m68k_write8;\r
- PicoCpuCM68k.write16 = m68k_write16;\r
- PicoCpuCM68k.write32 = m68k_write32;\r
+ PicoCpuCM68k.read8 = (void *)m68k_read8_map;\r
+ PicoCpuCM68k.read16 = (void *)m68k_read16_map;\r
+ PicoCpuCM68k.read32 = (void *)m68k_read16_map;\r
+ PicoCpuCM68k.write8 = (void *)m68k_write8_map;\r
+ PicoCpuCM68k.write16 = (void *)m68k_write16_map;\r
+ PicoCpuCM68k.write32 = (void *)m68k_write16_map;\r
+ PicoCpuCM68k.checkpc = NULL; /* unused */\r
+ PicoCpuCM68k.fetch8 = NULL;\r
+ PicoCpuCM68k.fetch16 = NULL;\r
+ PicoCpuCM68k.fetch32 = NULL;\r
#endif\r
#ifdef EMU_F68K\r
PicoCpuFM68k.read_byte = m68k_read8;\r
void PicoDrawSetColorFormatMode4(int which);\r
\r
// memory.c\r
-PICO_INTERNAL void PicoInitPc(unsigned int pc);\r
-PICO_INTERNAL unsigned int PicoCheckPc(unsigned int pc);\r
PICO_INTERNAL void PicoMemSetup(void);\r
unsigned int PicoRead8_io(unsigned int a);\r
unsigned int PicoRead16_io(unsigned int a);\r
#define MEMH_FUNC\r
#endif\r
\r
+#ifdef __GNUC__\r
+#define NOINLINE __attribute__((noinline))\r
+#else\r
+#define NOINLINE\r
+#endif\r
+\r
#ifdef __cplusplus\r
} // End of extern "C"\r
#endif\r
if (Pico.rom==NULL) return 1;\r
\r
#ifdef EMU_C68K\r
- PicoCpuCM68k.state_flags=0;\r
- PicoCpuCM68k.osp=0;\r
- PicoCpuCM68k.srh =0x27; // Supervisor mode\r
- PicoCpuCM68k.irq=0;\r
- PicoCpuCM68k.a[7]=PicoCpuCM68k.read32(0); // Stack Pointer\r
- PicoCpuCM68k.membase=0;\r
- PicoCpuCM68k.pc=PicoCpuCM68k.checkpc(PicoCpuCM68k.read32(4)); // Program Counter\r
+ CycloneReset(&PicoCpuCM68k);\r
#endif\r
#ifdef EMU_M68K\r
m68k_set_context(&PicoCpuMM68k); // if we ever reset m68k, we always need it's context to be set\r
endif\r
ifeq "$(use_cyclone)" "1"\r
DEFINC += -DEMU_C68K\r
-OBJS += cpu/Cyclone/proj/Cyclone.o cpu/Cyclone/tools/idle.o\r
+OBJS += pico/m68kif_cyclone.o cpu/Cyclone/proj/Cyclone.o cpu/Cyclone/tools/idle.o\r
endif\r
ifeq "$(mz80)" "1"\r
DEFINC += -D_USE_MZ80\r