Cyclone interface for new mem system, minor tweaks

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@779 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2009-09-14 20:35:30 +00:00
parent fc1874de8a
commit 5e89f0f5ae
8 changed files with 194 additions and 164 deletions

View file

@ -89,8 +89,9 @@ PICO_INTERNAL void PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
CycloneSetSr(context, *(unsigned int *)(cpu+0x44));
context->osp=*(unsigned int *)(cpu+0x48);
memcpy(context->d,cpu,0x40);
context->membase=0;
context->pc = context->checkpc(*(unsigned int *)(cpu+0x40)); // Base pc
context->membase = 0;
context->pc = *(unsigned int *)(cpu+0x40);
CycloneUnpack(context, NULL); // rebase PC
context->irq = cpu[0x4c];
context->state_flags = 0;
if (cpu[0x4d])

View file

@ -787,74 +787,6 @@ static void PicoWriteS68k16_pr(u32 a, u32 d)
// -----------------------------------------------------------------
#ifdef EMU_C68K
static __inline int PicoMemBaseM68k(u32 pc)
{
if ((pc&0xe00000)==0xe00000)
return (int)Pico.ram-(pc&0xff0000); // Program Counter in Ram
if (pc < 0x20000)
return (int)Pico_mcd->bios; // Program Counter in BIOS
if ((pc&0xfc0000)==0x200000)
{
if (!(Pico_mcd->s68k_regs[3]&4))
return (int)Pico_mcd->word_ram2M - 0x200000; // Program Counter in Word Ram
if (pc < 0x220000) {
int bank = Pico_mcd->s68k_regs[3]&1;
return (int)Pico_mcd->word_ram1M[bank] - 0x200000;
}
}
// Error - Program Counter is invalid
elprintf(EL_ANOMALY, "m68k FIXME: unhandled jump to %06x", pc);
return (int)Pico_mcd->bios;
}
static u32 PicoCheckPcM68k(u32 pc)
{
pc-=PicoCpuCM68k.membase; // Get real pc
pc&=0xfffffe;
PicoCpuCM68k.membase=PicoMemBaseM68k(pc);
return PicoCpuCM68k.membase+pc;
}
static __inline int PicoMemBaseS68k(u32 pc)
{
if (pc < 0x80000) // PRG RAM
return (int)Pico_mcd->prg_ram;
if ((pc&0xfc0000)==0x080000) // WORD RAM 2M area (assume we are in the right mode..)
return (int)Pico_mcd->word_ram2M - 0x080000;
if ((pc&0xfe0000)==0x0c0000) { // word RAM 1M area
int bank = (Pico_mcd->s68k_regs[3]&1)^1;
return (int)Pico_mcd->word_ram1M[bank] - 0x0c0000;
}
// Error - Program Counter is invalid
elprintf(EL_ANOMALY, "s68k FIXME: unhandled jump to %06x", pc);
return (int)Pico_mcd->prg_ram;
}
static u32 PicoCheckPcS68k(u32 pc)
{
pc-=PicoCpuCS68k.membase; // Get real pc
pc&=0xfffffe;
PicoCpuCS68k.membase=PicoMemBaseS68k(pc);
return PicoCpuCS68k.membase+pc;
}
#endif
// TODO: probably split
void PicoMemRemapCD(int r3)
{
@ -963,15 +895,17 @@ PICO_INTERNAL void PicoMemSetupCD(void)
cpu68k_map_set(s68k_write16_map, 0xff0000, 0xffffff, PicoWriteS68k16_pr, 1);
#ifdef EMU_C68K
PicoCpuCM68k.checkpc = PicoCheckPcM68k;
// s68k
PicoCpuCS68k.checkpc = PicoCheckPcS68k;
PicoCpuCS68k.fetch8 = PicoCpuCS68k.read8 = s68k_read8;
PicoCpuCS68k.fetch16 = PicoCpuCS68k.read16 = s68k_read16;
PicoCpuCS68k.fetch32 = PicoCpuCS68k.read32 = s68k_read32;
PicoCpuCS68k.write8 = s68k_write8;
PicoCpuCS68k.write16 = s68k_write16;
PicoCpuCS68k.write32 = s68k_write32;
PicoCpuCS68k.read8 = (void *)s68k_read8_map;
PicoCpuCS68k.read16 = (void *)s68k_read16_map;
PicoCpuCS68k.read32 = (void *)s68k_read16_map;
PicoCpuCS68k.write8 = (void *)s68k_write8_map;
PicoCpuCS68k.write16 = (void *)s68k_write16_map;
PicoCpuCS68k.write32 = (void *)s68k_write16_map;
PicoCpuCS68k.checkpc = NULL; /* unused */
PicoCpuCS68k.fetch8 = NULL;
PicoCpuCS68k.fetch16 = NULL;
PicoCpuCS68k.fetch32 = NULL;
#endif
#ifdef EMU_F68K
// s68k

View file

@ -133,14 +133,7 @@ PICO_INTERNAL int SekResetS68k(void)
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
{

140
pico/m68kif_cyclone.s Normal file
View file

@ -0,0 +1,140 @@
@ 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

View file

@ -160,57 +160,15 @@ void log_io(unsigned int addr, int bits, int rw);
#endif
#if defined(EMU_C68K)
static __inline int PicoMemBase(u32 pc)
void cyclone_crashed(u32 pc, struct Cyclone *context)
{
int membase=0;
if (pc<Pico.romsize+4)
{
membase=(int)Pico.rom; // Program Counter in Rom
}
else if ((pc&0xe00000)==0xe00000)
{
membase=(int)Pico.ram-(pc&0xff0000); // Program Counter in Ram
}
else
{
// Error - Program Counter is invalid
membase=(int)Pico.rom;
}
return membase;
elprintf(EL_STATUS|EL_ANOMALY, "%c68k crash detected @ %06x\n",
context == &PicoCpuCM68k ? 'm' : 's', pc);
context->membase = (u32)Pico.rom;
context->pc = (u32)Pico.rom + Pico.romsize;
}
#endif
PICO_INTERNAL u32 PicoCheckPc(u32 pc)
{
u32 ret=0;
#if defined(EMU_C68K)
pc-=PicoCpuCM68k.membase; // Get real pc
// pc&=0xfffffe;
pc&=~1;
if ((pc<<8) == 0)
{
elprintf(EL_STATUS|EL_ANOMALY, "%i:%03i: game crash detected @ %06x\n",
Pico.m.frame_count, Pico.m.scanline, SekPc);
return (int)Pico.rom + Pico.romsize; // common crash condition, may happen with bad ROMs
}
PicoCpuCM68k.membase=PicoMemBase(pc&0x00ffffff);
PicoCpuCM68k.membase-=pc&0xff000000;
ret = PicoCpuCM68k.membase+pc;
#endif
return ret;
}
PICO_INTERNAL void PicoInitPc(u32 pc)
{
PicoCheckPc(pc);
}
// -----------------------------------------------------------------
// memmap helpers
@ -259,7 +217,7 @@ static u32 io_ports_read(u32 a)
return d;
}
static void io_ports_write(u32 a, u32 d)
static void NOINLINE io_ports_write(u32 a, u32 d)
{
a = (a>>1) & 0xf;
@ -271,11 +229,11 @@ static void io_ports_write(u32 a, u32 d)
Pico.m.padTHPhase[a - 1]++;
}
// cartain IO ports can be used as RAM
// certain IO ports can be used as RAM
Pico.ioports[a] = d;
}
static void ctl_write_z80busreq(u32 d)
static void NOINLINE ctl_write_z80busreq(u32 d)
{
d&=1; d^=1;
elprintf(EL_BUSREQ, "set_zrun: %i->%i [%i] @%06x", Pico.m.z80Run, d, SekCyclesDone(), SekPc);
@ -295,7 +253,7 @@ static void ctl_write_z80busreq(u32 d)
}
}
static void ctl_write_z80reset(u32 d)
static void NOINLINE ctl_write_z80reset(u32 d)
{
d&=1; d^=1;
elprintf(EL_BUSREQ, "set_zreset: %i->%i [%i] @%06x", Pico.m.z80_reset, d, SekCyclesDone(), SekPc);
@ -491,13 +449,15 @@ u32 PicoRead8_io(u32 a)
d = Pico.m.rotate++;
d ^= d << 6;
// bit8 seems to be readable in this range
if ((a & 0xfc01) == 0x1000)
d &= ~0x01;
if ((a & 0xfc00) == 0x1000) {
// bit8 seems to be readable in this range
if (!(a & 1))
d &= ~0x01;
if ((a & 0xff01) == 0x1100) { // z80 busreq (verified)
d |= (Pico.m.z80Run | Pico.m.z80_reset) & 1;
elprintf(EL_BUSREQ, "get_zrun: %02x [%i] @%06x", d, SekCyclesDone(), SekPc);
if ((a & 0xff01) == 0x1100) { // z80 busreq (verified)
d |= (Pico.m.z80Run | Pico.m.z80_reset) & 1;
elprintf(EL_BUSREQ, "get_zrun: %02x [%i] @%06x", d, SekCyclesDone(), SekPc);
}
goto end;
}
@ -526,12 +486,13 @@ u32 PicoRead16_io(u32 a)
d ^= (d << 5) ^ (d << 8);
// bit8 seems to be readable in this range
if ((a & 0xfc00) == 0x1000)
if ((a & 0xfc00) == 0x1000) {
d &= ~0x0100;
if ((a & 0xff00) == 0x1100) { // z80 busreq
d |= ((Pico.m.z80Run | Pico.m.z80_reset) & 1) << 8;
elprintf(EL_BUSREQ, "get_zrun: %04x [%i] @%06x", d, SekCyclesDone(), SekPc);
if ((a & 0xff00) == 0x1100) { // z80 busreq
d |= ((Pico.m.z80Run | Pico.m.z80_reset) & 1) << 8;
elprintf(EL_BUSREQ, "get_zrun: %04x [%i] @%06x", d, SekCyclesDone(), SekPc);
}
goto end;
}
@ -718,13 +679,16 @@ PICO_INTERNAL void PicoMemSetup(void)
// Setup memory callbacks:
#ifdef EMU_C68K
PicoCpuCM68k.checkpc = PicoCheckPc;
PicoCpuCM68k.fetch8 = PicoCpuCM68k.read8 = m68k_read8;
PicoCpuCM68k.fetch16 = PicoCpuCM68k.read16 = m68k_read16;
PicoCpuCM68k.fetch32 = PicoCpuCM68k.read32 = m68k_read32;
PicoCpuCM68k.write8 = m68k_write8;
PicoCpuCM68k.write16 = m68k_write16;
PicoCpuCM68k.write32 = m68k_write32;
PicoCpuCM68k.read8 = (void *)m68k_read8_map;
PicoCpuCM68k.read16 = (void *)m68k_read16_map;
PicoCpuCM68k.read32 = (void *)m68k_read16_map;
PicoCpuCM68k.write8 = (void *)m68k_write8_map;
PicoCpuCM68k.write16 = (void *)m68k_write16_map;
PicoCpuCM68k.write32 = (void *)m68k_write16_map;
PicoCpuCM68k.checkpc = NULL; /* unused */
PicoCpuCM68k.fetch8 = NULL;
PicoCpuCM68k.fetch16 = NULL;
PicoCpuCM68k.fetch32 = NULL;
#endif
#ifdef EMU_F68K
PicoCpuFM68k.read_byte = m68k_read8;

View file

@ -471,8 +471,6 @@ void PicoDoHighPal555M4(void);
void PicoDrawSetColorFormatMode4(int which);
// memory.c
PICO_INTERNAL void PicoInitPc(unsigned int pc);
PICO_INTERNAL unsigned int PicoCheckPc(unsigned int pc);
PICO_INTERNAL void PicoMemSetup(void);
unsigned int PicoRead8_io(unsigned int a);
unsigned int PicoRead16_io(unsigned int a);
@ -686,6 +684,12 @@ extern void lprintf(const char *fmt, ...);
#define MEMH_FUNC
#endif
#ifdef __GNUC__
#define NOINLINE __attribute__((noinline))
#else
#define NOINLINE
#endif
#ifdef __cplusplus
} // End of extern "C"
#endif

View file

@ -138,13 +138,7 @@ PICO_INTERNAL int SekReset(void)
if (Pico.rom==NULL) return 1;
#ifdef EMU_C68K
PicoCpuCM68k.state_flags=0;
PicoCpuCM68k.osp=0;
PicoCpuCM68k.srh =0x27; // Supervisor mode
PicoCpuCM68k.irq=0;
PicoCpuCM68k.a[7]=PicoCpuCM68k.read32(0); // Stack Pointer
PicoCpuCM68k.membase=0;
PicoCpuCM68k.pc=PicoCpuCM68k.checkpc(PicoCpuCM68k.read32(4)); // Program Counter
CycloneReset(&PicoCpuCM68k);
#endif
#ifdef EMU_M68K
m68k_set_context(&PicoCpuMM68k); // if we ever reset m68k, we always need it's context to be set