mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
FAME integration finished, some adjustments of CPU core stuff
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@278 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
9112b6ce9f
commit
3aa1e148a2
18 changed files with 398 additions and 8706 deletions
61
Pico/Area.c
61
Pico/Area.c
|
@ -46,29 +46,17 @@ PICO_INTERNAL int PicoAreaPackCpu(unsigned char *cpu, int is_sub)
|
||||||
{
|
{
|
||||||
unsigned int pc=0;
|
unsigned int pc=0;
|
||||||
|
|
||||||
#ifdef EMU_A68K
|
#if defined(EMU_C68K)
|
||||||
memcpy(cpu,M68000_regs.d,0x40);
|
struct Cyclone *context = is_sub ? &PicoCpuCS68k : &PicoCpuCM68k;
|
||||||
pc=M68000_regs.pc;
|
|
||||||
*(unsigned char *)(cpu+0x44)=(unsigned char)M68000_regs.ccr;
|
|
||||||
*(unsigned char *)(cpu+0x45)=(unsigned char)M68000_regs.srh;
|
|
||||||
*(unsigned int *)(cpu+0x48)=M68000_regs.isp;
|
|
||||||
cpu[0x4c] = M68000_regs.irq;
|
|
||||||
// stop flag?
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EMU_C68K
|
|
||||||
struct Cyclone *context = is_sub ? &PicoCpuS68k : &PicoCpu;
|
|
||||||
memcpy(cpu,context->d,0x40);
|
memcpy(cpu,context->d,0x40);
|
||||||
pc=context->pc-context->membase;
|
pc=context->pc-context->membase;
|
||||||
*(unsigned int *)(cpu+0x44)=CycloneGetSr(context);
|
*(unsigned int *)(cpu+0x44)=CycloneGetSr(context);
|
||||||
*(unsigned int *)(cpu+0x48)=context->osp;
|
*(unsigned int *)(cpu+0x48)=context->osp;
|
||||||
cpu[0x4c] = context->irq;
|
cpu[0x4c] = context->irq;
|
||||||
cpu[0x4d] = context->state_flags & 1;
|
cpu[0x4d] = context->state_flags & 1;
|
||||||
#endif
|
#elif defined(EMU_M68K)
|
||||||
|
|
||||||
#ifdef EMU_M68K
|
|
||||||
void *oldcontext = m68ki_cpu_p;
|
void *oldcontext = m68ki_cpu_p;
|
||||||
m68k_set_context(is_sub ? &PicoS68kCPU : &PicoM68kCPU);
|
m68k_set_context(is_sub ? &PicoCpuMS68k : &PicoCpuMM68k);
|
||||||
memcpy(cpu,m68ki_cpu_p->dar,0x40);
|
memcpy(cpu,m68ki_cpu_p->dar,0x40);
|
||||||
pc=m68ki_cpu_p->pc;
|
pc=m68ki_cpu_p->pc;
|
||||||
*(unsigned int *)(cpu+0x44)=m68k_get_reg(NULL, M68K_REG_SR);
|
*(unsigned int *)(cpu+0x44)=m68k_get_reg(NULL, M68K_REG_SR);
|
||||||
|
@ -76,6 +64,14 @@ PICO_INTERNAL int PicoAreaPackCpu(unsigned char *cpu, int is_sub)
|
||||||
cpu[0x4c] = CPU_INT_LEVEL>>8;
|
cpu[0x4c] = CPU_INT_LEVEL>>8;
|
||||||
cpu[0x4d] = CPU_STOPPED;
|
cpu[0x4d] = CPU_STOPPED;
|
||||||
m68k_set_context(oldcontext);
|
m68k_set_context(oldcontext);
|
||||||
|
#elif defined(EMU_F68K)
|
||||||
|
M68K_CONTEXT *context = is_sub ? &PicoCpuFS68k : &PicoCpuFM68k;
|
||||||
|
memcpy(cpu,context->dreg,0x40);
|
||||||
|
pc=context->pc;
|
||||||
|
*(unsigned int *)(cpu+0x44)=context->sr;
|
||||||
|
*(unsigned int *)(cpu+0x48)=context->asp;
|
||||||
|
cpu[0x4c] = context->interrupts[0];
|
||||||
|
cpu[0x4d] = (context->execinfo & M68K_HALTED) ? 1 : 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*(unsigned int *)(cpu+0x40)=pc;
|
*(unsigned int *)(cpu+0x40)=pc;
|
||||||
|
@ -84,20 +80,10 @@ PICO_INTERNAL int PicoAreaPackCpu(unsigned char *cpu, int is_sub)
|
||||||
|
|
||||||
PICO_INTERNAL int PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
|
PICO_INTERNAL int PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
|
||||||
{
|
{
|
||||||
#ifdef EMU_A68K
|
#if defined(EMU_C68K)
|
||||||
memcpy(M68000_regs.d,cpu,0x40);
|
struct Cyclone *context = is_sub ? &PicoCpuCS68k : &PicoCpuCM68k;
|
||||||
M68000_regs.pc=pc;
|
CycloneSetSr(context, *(unsigned int *)(cpu+0x44));
|
||||||
M68000_regs.ccr=*(unsigned char *)(cpu+0x44);
|
context->osp=*(unsigned int *)(cpu+0x48);
|
||||||
M68000_regs.srh=*(unsigned char *)(cpu+0x45);
|
|
||||||
M68000_regs.isp=*(unsigned int *)(cpu+0x48);
|
|
||||||
M68000_regs.irq = cpu[0x4c];
|
|
||||||
// stop flag?
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EMU_C68K
|
|
||||||
struct Cyclone *context = is_sub ? &PicoCpuS68k : &PicoCpu;
|
|
||||||
CycloneSetSr(context, *(unsigned int *)(cpu+0x44));
|
|
||||||
context->osp=*(unsigned int *)(cpu+0x48);
|
|
||||||
memcpy(context->d,cpu,0x40);
|
memcpy(context->d,cpu,0x40);
|
||||||
context->membase=0;
|
context->membase=0;
|
||||||
context->pc = context->checkpc(*(unsigned int *)(cpu+0x40)); // Base pc
|
context->pc = context->checkpc(*(unsigned int *)(cpu+0x40)); // Base pc
|
||||||
|
@ -105,11 +91,9 @@ PICO_INTERNAL int PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
|
||||||
context->state_flags = 0;
|
context->state_flags = 0;
|
||||||
if (cpu[0x4d])
|
if (cpu[0x4d])
|
||||||
context->state_flags |= 1;
|
context->state_flags |= 1;
|
||||||
#endif
|
#elif defined(EMU_M68K)
|
||||||
|
|
||||||
#ifdef EMU_M68K
|
|
||||||
void *oldcontext = m68ki_cpu_p;
|
void *oldcontext = m68ki_cpu_p;
|
||||||
m68k_set_context(is_sub ? &PicoS68kCPU : &PicoM68kCPU);
|
m68k_set_context(is_sub ? &PicoCpuMS68k : &PicoCpuMM68k);
|
||||||
memcpy(m68ki_cpu_p->dar,cpu,0x40);
|
memcpy(m68ki_cpu_p->dar,cpu,0x40);
|
||||||
m68ki_cpu_p->pc=*(unsigned int *)(cpu+0x40);
|
m68ki_cpu_p->pc=*(unsigned int *)(cpu+0x40);
|
||||||
m68k_set_reg(M68K_REG_SR, *(unsigned int *)(cpu+0x44));
|
m68k_set_reg(M68K_REG_SR, *(unsigned int *)(cpu+0x44));
|
||||||
|
@ -117,6 +101,15 @@ PICO_INTERNAL int PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
|
||||||
CPU_INT_LEVEL = cpu[0x4c] << 8;
|
CPU_INT_LEVEL = cpu[0x4c] << 8;
|
||||||
CPU_STOPPED = cpu[0x4d];
|
CPU_STOPPED = cpu[0x4d];
|
||||||
m68k_set_context(oldcontext);
|
m68k_set_context(oldcontext);
|
||||||
|
#elif defined(EMU_F68K)
|
||||||
|
M68K_CONTEXT *context = is_sub ? &PicoCpuFS68k : &PicoCpuFM68k;
|
||||||
|
memcpy(context->dreg,cpu,0x40);
|
||||||
|
context->pc =*(unsigned int *)(cpu+0x40);
|
||||||
|
context->sr =*(unsigned int *)(cpu+0x44);
|
||||||
|
context->asp=*(unsigned int *)(cpu+0x48);
|
||||||
|
context->interrupts[0] = cpu[0x4c];
|
||||||
|
context->execinfo &= ~M68K_HALTED;
|
||||||
|
if (cpu[0x4d]&1) context->execinfo |= M68K_HALTED;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ static u32 CPU_CALL PicoCheckPc(u32 pc)
|
||||||
{
|
{
|
||||||
u32 ret=0;
|
u32 ret=0;
|
||||||
#if defined(EMU_C68K)
|
#if defined(EMU_C68K)
|
||||||
pc-=PicoCpu.membase; // Get real pc
|
pc-=PicoCpuCM68k.membase; // Get real pc
|
||||||
// pc&=0xfffffe;
|
// pc&=0xfffffe;
|
||||||
pc&=~1;
|
pc&=~1;
|
||||||
if ((pc<<8) == 0)
|
if ((pc<<8) == 0)
|
||||||
|
@ -82,10 +82,10 @@ static u32 CPU_CALL PicoCheckPc(u32 pc)
|
||||||
return (int)Pico.rom + Pico.romsize; // common crash condition, can happen if acc timing is off
|
return (int)Pico.rom + Pico.romsize; // common crash condition, can happen if acc timing is off
|
||||||
}
|
}
|
||||||
|
|
||||||
PicoCpu.membase=PicoMemBase(pc&0x00ffffff);
|
PicoCpuCM68k.membase=PicoMemBase(pc&0x00ffffff);
|
||||||
PicoCpu.membase-=pc&0xff000000;
|
PicoCpuCM68k.membase-=pc&0xff000000;
|
||||||
|
|
||||||
ret = PicoCpu.membase+pc;
|
ret = PicoCpuCM68k.membase+pc;
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -491,21 +491,35 @@ PICO_INTERNAL void PicoMemSetup(void)
|
||||||
{
|
{
|
||||||
// Setup memory callbacks:
|
// Setup memory callbacks:
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
PicoCpu.checkpc=PicoCheckPc;
|
PicoCpuCM68k.checkpc=PicoCheckPc;
|
||||||
PicoCpu.fetch8 =PicoCpu.read8 =PicoRead8;
|
PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoRead8;
|
||||||
PicoCpu.fetch16=PicoCpu.read16=PicoRead16;
|
PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoRead16;
|
||||||
PicoCpu.fetch32=PicoCpu.read32=PicoRead32;
|
PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoRead32;
|
||||||
PicoCpu.write8 =PicoWrite8;
|
PicoCpuCM68k.write8 =PicoWrite8;
|
||||||
PicoCpu.write16=PicoWrite16;
|
PicoCpuCM68k.write16=PicoWrite16;
|
||||||
PicoCpu.write32=PicoWrite32;
|
PicoCpuCM68k.write32=PicoWrite32;
|
||||||
#endif
|
#endif
|
||||||
#ifdef EMU_F68K
|
#ifdef EMU_F68K
|
||||||
PicoCpuM68k.read_byte =PicoRead8;
|
PicoCpuFM68k.read_byte =PicoRead8;
|
||||||
PicoCpuM68k.read_word =PicoRead16;
|
PicoCpuFM68k.read_word =PicoRead16;
|
||||||
PicoCpuM68k.read_long =PicoRead32;
|
PicoCpuFM68k.read_long =PicoRead32;
|
||||||
PicoCpuM68k.write_byte=PicoWrite8;
|
PicoCpuFM68k.write_byte=PicoWrite8;
|
||||||
PicoCpuM68k.write_word=PicoWrite16;
|
PicoCpuFM68k.write_word=PicoWrite16;
|
||||||
PicoCpuM68k.write_long=PicoWrite32;
|
PicoCpuFM68k.write_long=PicoWrite32;
|
||||||
|
|
||||||
|
// setup FAME fetchmap
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
// by default, point everything to fitst 64k of ROM
|
||||||
|
for (i = 0; i < M68K_FETCHBANK1; i++)
|
||||||
|
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom - (i<<(24-FAMEC_FETCHBITS));
|
||||||
|
// now real ROM
|
||||||
|
for (i = 0; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < Pico.romsize; i++)
|
||||||
|
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom;
|
||||||
|
// .. and RAM
|
||||||
|
for (i = M68K_FETCHBANK1*14/16; i < M68K_FETCHBANK1; i++)
|
||||||
|
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.ram - (i<<(24-FAMEC_FETCHBITS));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
178
Pico/Pico.c
178
Pico/Pico.c
|
@ -209,9 +209,9 @@ static __inline void SekRunM68k(int cyc)
|
||||||
// this means we do run-compare Cyclone vs Musashi
|
// this means we do run-compare Cyclone vs Musashi
|
||||||
SekCycleCnt+=CM_compareRun(cyc_do);
|
SekCycleCnt+=CM_compareRun(cyc_do);
|
||||||
#elif defined(EMU_C68K)
|
#elif defined(EMU_C68K)
|
||||||
PicoCpu.cycles=cyc_do;
|
PicoCpuCM68k.cycles=cyc_do;
|
||||||
CycloneRun(&PicoCpu);
|
CycloneRun(&PicoCpuCM68k);
|
||||||
SekCycleCnt+=cyc_do-PicoCpu.cycles;
|
SekCycleCnt+=cyc_do-PicoCpuCM68k.cycles;
|
||||||
#elif defined(EMU_M68K)
|
#elif defined(EMU_M68K)
|
||||||
SekCycleCnt+=m68k_execute(cyc_do);
|
SekCycleCnt+=m68k_execute(cyc_do);
|
||||||
#elif defined(EMU_F68K)
|
#elif defined(EMU_F68K)
|
||||||
|
@ -227,9 +227,9 @@ static __inline void SekStep(void)
|
||||||
// this means we do run-compare Cyclone vs Musashi
|
// this means we do run-compare Cyclone vs Musashi
|
||||||
SekCycleCnt+=CM_compareRun(1);
|
SekCycleCnt+=CM_compareRun(1);
|
||||||
#elif defined(EMU_C68K)
|
#elif defined(EMU_C68K)
|
||||||
PicoCpu.cycles=1;
|
PicoCpuCM68k.cycles=1;
|
||||||
CycloneRun(&PicoCpu);
|
CycloneRun(&PicoCpuCM68k);
|
||||||
SekCycleCnt+=1-PicoCpu.cycles;
|
SekCycleCnt+=1-PicoCpuCM68k.cycles;
|
||||||
#elif defined(EMU_M68K)
|
#elif defined(EMU_M68K)
|
||||||
SekCycleCnt+=m68k_execute(1);
|
SekCycleCnt+=m68k_execute(1);
|
||||||
#elif defined(EMU_F68K)
|
#elif defined(EMU_F68K)
|
||||||
|
@ -240,27 +240,16 @@ static __inline void SekStep(void)
|
||||||
|
|
||||||
static int CheckIdle(void)
|
static int CheckIdle(void)
|
||||||
{
|
{
|
||||||
#if 1
|
int i, state[0x22];
|
||||||
unsigned char state[0x88];
|
|
||||||
|
|
||||||
memset(state,0,sizeof(state));
|
|
||||||
|
|
||||||
// See if the state is the same after 2 steps:
|
// See if the state is the same after 2 steps:
|
||||||
SekState(state); SekStep(); SekStep(); SekState(state+0x44);
|
SekState(state); SekStep(); SekStep(); SekState(state+0x11);
|
||||||
if (memcmp(state,state+0x44,0x44)==0) return 1;
|
for (i = 0x10; i >= 0; i--)
|
||||||
#else
|
if (state[i] != state[i+0x11]) return 0;
|
||||||
unsigned char state[0x44];
|
|
||||||
static unsigned char oldstate[0x44];
|
|
||||||
|
|
||||||
SekState(state);
|
return 1;
|
||||||
if(memcmp(state,oldstate,0x40)==0) return 1;
|
|
||||||
memcpy(oldstate, state, 0x40);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lprintf_al(const char *fmt, ...);
|
|
||||||
|
|
||||||
// to be called on 224 or line_sample scanlines only
|
// to be called on 224 or line_sample scanlines only
|
||||||
static __inline void getSamples(int y)
|
static __inline void getSamples(int y)
|
||||||
|
@ -284,140 +273,7 @@ static __inline void getSamples(int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 1*0
|
|
||||||
int vint_delay = 205/*68*/, as_delay = 18/*148*/;
|
|
||||||
|
|
||||||
// Accurate but slower frame which does hints
|
|
||||||
static int PicoFrameHints(void)
|
|
||||||
{
|
|
||||||
struct PicoVideo *pv=&Pico.video;
|
|
||||||
int total_z80=0,lines,y,lines_vis = 224,z80CycleAim = 0,line_sample;
|
|
||||||
const int cycles_68k=488,cycles_z80=228; // both PAL and NTSC compile to same values
|
|
||||||
int skip=PicoSkipFrame || (PicoOpt&0x10);
|
|
||||||
int hint; // Hint counter
|
|
||||||
|
|
||||||
if(Pico.m.pal) { //
|
|
||||||
//cycles_68k = (int) ((double) OSC_PAL / 7 / 50 / 312 + 0.4); // should compile to a constant (488)
|
|
||||||
//cycles_z80 = (int) ((double) OSC_PAL / 15 / 50 / 312 + 0.4); // 228
|
|
||||||
lines = 312; // Steve Snake says there are 313 lines, but this seems to also work well
|
|
||||||
line_sample = 68;
|
|
||||||
if(pv->reg[1]&8) lines_vis = 240;
|
|
||||||
} else {
|
|
||||||
//cycles_68k = (int) ((double) OSC_NTSC / 7 / 60 / 262 + 0.4); // 488
|
|
||||||
//cycles_z80 = (int) ((double) OSC_NTSC / 15 / 60 / 262 + 0.4); // 228
|
|
||||||
lines = 262;
|
|
||||||
line_sample = 93;
|
|
||||||
}
|
|
||||||
|
|
||||||
SekCyclesReset();
|
|
||||||
//z80ExtraCycles = 0;
|
|
||||||
|
|
||||||
if(PicoOpt&4)
|
|
||||||
z80CycleAim = 0;
|
|
||||||
// z80_resetCycles();
|
|
||||||
|
|
||||||
pv->status&=~0x88; // clear V-Int, come out of vblank
|
|
||||||
|
|
||||||
hint=pv->reg[10]; // Load H-Int counter
|
|
||||||
//dprintf("-hint: %i", hint);
|
|
||||||
|
|
||||||
//SekRun(as_delay);
|
|
||||||
SekRun(148);
|
|
||||||
|
|
||||||
for (y=0;y<lines;y++)
|
|
||||||
{
|
|
||||||
Pico.m.scanline=(short)y;
|
|
||||||
|
|
||||||
// VDP FIFO
|
|
||||||
pv->lwrite_cnt -= 12;
|
|
||||||
if (pv->lwrite_cnt < 0) pv->lwrite_cnt=0;
|
|
||||||
if (pv->lwrite_cnt == 0)
|
|
||||||
Pico.video.status|=0x200;
|
|
||||||
|
|
||||||
// pad delay (for 6 button pads)
|
|
||||||
if(PicoOpt&0x20) {
|
|
||||||
if(Pico.m.padDelay[0]++ > 25) Pico.m.padTHPhase[0]=0;
|
|
||||||
if(Pico.m.padDelay[1]++ > 25) Pico.m.padTHPhase[1]=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// H-Interrupts:
|
|
||||||
if(y <= lines_vis && --hint < 0) // y <= lines_vis: Comix Zone, Golden Axe
|
|
||||||
{
|
|
||||||
//dprintf("rhint:old @ %06x", SekPc);
|
|
||||||
hint=pv->reg[10]; // Reload H-Int counter
|
|
||||||
pv->pending_ints|=0x10;
|
|
||||||
if (pv->reg[0]&0x10) {
|
|
||||||
elprintf(EL_INTS, "hint: @ %06x [%i]", SekPc, SekCycleCnt);
|
|
||||||
SekInterrupt(4);
|
|
||||||
}
|
|
||||||
//dprintf("hint_routine: %x", (*(unsigned short*)(Pico.ram+0x0B84)<<16)|*(unsigned short*)(Pico.ram+0x0B86));
|
|
||||||
}
|
|
||||||
|
|
||||||
// V-Interrupt:
|
|
||||||
if (y == lines_vis)
|
|
||||||
{
|
|
||||||
pv->status|=0x08; // go into vblank
|
|
||||||
//pv->status|=0x80; // V-Int happened
|
|
||||||
//if(!Pico.m.dma_bytes||(Pico.video.reg[0x17]&0x80)) {
|
|
||||||
// there must be a gap between H and V ints, also after vblank bit set (Mazin Saga, Bram Stoker's Dracula)
|
|
||||||
SekRun(68); SekCycleAim-=68; // 128; ?
|
|
||||||
SekCycleAim-=148;
|
|
||||||
// SekRun(vint_delay); SekCycleAim-=vint_delay; // 128; ?
|
|
||||||
// SekCycleAim-=as_delay;
|
|
||||||
//}
|
|
||||||
pv->pending_ints|=0x20;
|
|
||||||
if(pv->reg[1]&0x20) {
|
|
||||||
elprintf(EL_INTS, "vint: @ %06x [%i]", SekPc, SekCycleCnt);
|
|
||||||
SekInterrupt(6);
|
|
||||||
}
|
|
||||||
if(Pico.m.z80Run && (PicoOpt&4)) // ?
|
|
||||||
z80_int();
|
|
||||||
//dprintf("zint: [%i|%i] zPC=%04x", Pico.m.scanline, SekCyclesDone(), mz80GetRegisterValue(NULL, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// decide if we draw this line
|
|
||||||
#if CAN_HANDLE_240_LINES
|
|
||||||
if(!skip && ((!(pv->reg[1]&8) && y<224) || ((pv->reg[1]&8) && y<240)) )
|
|
||||||
#else
|
|
||||||
if(!skip && y<224)
|
|
||||||
#endif
|
|
||||||
PicoLine(y);
|
|
||||||
|
|
||||||
if(PicoOpt&1)
|
|
||||||
sound_timers_and_dac(y);
|
|
||||||
|
|
||||||
// get samples from sound chips
|
|
||||||
if(y == 32 && PsndOut)
|
|
||||||
emustatus &= ~1;
|
|
||||||
else if((y == 224 || y == line_sample) && PsndOut)
|
|
||||||
getSamples(y);
|
|
||||||
|
|
||||||
// Run scanline:
|
|
||||||
if (Pico.m.dma_xfers) SekCyclesBurn(CheckDMA());
|
|
||||||
SekRun(cycles_68k);
|
|
||||||
if ((PicoOpt&4) && Pico.m.z80Run) {
|
|
||||||
if (Pico.m.z80Run & 2) z80CycleAim+=cycles_z80;
|
|
||||||
else {
|
|
||||||
int cnt = SekCyclesDone() - z80startCycle;
|
|
||||||
cnt = (cnt>>1)-(cnt>>5);
|
|
||||||
//if (cnt > cycles_z80) printf("FIXME: z80 cycles: %i\n", cnt);
|
|
||||||
if (cnt > cycles_z80) cnt = cycles_z80;
|
|
||||||
Pico.m.z80Run |= 2;
|
|
||||||
z80CycleAim+=cnt;
|
|
||||||
}
|
|
||||||
total_z80+=z80_run(z80CycleAim-total_z80);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw a frame just after vblank in alternative render mode
|
|
||||||
if(!PicoSkipFrame && (PicoOpt&0x10))
|
|
||||||
PicoFrameFull();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#include "PicoFrameHints.c"
|
#include "PicoFrameHints.c"
|
||||||
#endif
|
|
||||||
|
|
||||||
// helper z80 runner. Runs only if z80 is enabled at this point
|
// helper z80 runner. Runs only if z80 is enabled at this point
|
||||||
// (z80WriteBusReq will handle the rest)
|
// (z80WriteBusReq will handle the rest)
|
||||||
|
@ -664,17 +520,17 @@ char *debugString(void)
|
||||||
sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status);
|
sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status);
|
||||||
dstrp+=strlen(dstrp);
|
dstrp+=strlen(dstrp);
|
||||||
#if defined(EMU_C68K)
|
#if defined(EMU_C68K)
|
||||||
sprintf(dstrp, "M68k: PC: %06x, st_flg: %x, cycles: %u\n", SekPc, PicoCpu.state_flags, SekCyclesDoneT());
|
sprintf(dstrp, "M68k: PC: %06x, st_flg: %x, cycles: %u\n", SekPc, PicoCpuCM68k.state_flags, SekCyclesDoneT());
|
||||||
dstrp+=strlen(dstrp);
|
dstrp+=strlen(dstrp);
|
||||||
sprintf(dstrp, "d0=%08x, a0=%08x, osp=%08x, irql=%i\n", PicoCpu.d[0], PicoCpu.a[0], PicoCpu.osp, PicoCpu.irq); dstrp+=strlen(dstrp);
|
sprintf(dstrp, "d0=%08x, a0=%08x, osp=%08x, irql=%i\n", PicoCpuCM68k.d[0], PicoCpuCM68k.a[0], PicoCpuCM68k.osp, PicoCpuCM68k.irq); dstrp+=strlen(dstrp);
|
||||||
sprintf(dstrp, "d1=%08x, a1=%08x, sr=%04x\n", PicoCpu.d[1], PicoCpu.a[1], CycloneGetSr(&PicoCpu)); dstrp+=strlen(dstrp);
|
sprintf(dstrp, "d1=%08x, a1=%08x, sr=%04x\n", PicoCpuCM68k.d[1], PicoCpuCM68k.a[1], CycloneGetSr(&PicoCpuCM68k)); dstrp+=strlen(dstrp);
|
||||||
for(r=2; r < 8; r++) {
|
for(r=2; r < 8; r++) {
|
||||||
sprintf(dstrp, "d%i=%08x, a%i=%08x\n", r, PicoCpu.d[r], r, PicoCpu.a[r]); dstrp+=strlen(dstrp);
|
sprintf(dstrp, "d%i=%08x, a%i=%08x\n", r, PicoCpuCM68k.d[r], r, PicoCpuCM68k.a[r]); dstrp+=strlen(dstrp);
|
||||||
}
|
}
|
||||||
#elif defined(EMU_M68K)
|
#elif defined(EMU_M68K)
|
||||||
sprintf(dstrp, "M68k: PC: %06x, cycles: %u, irql: %i\n", SekPc, SekCyclesDoneT(), PicoM68kCPU.int_level>>8); dstrp+=strlen(dstrp);
|
sprintf(dstrp, "M68k: PC: %06x, cycles: %u, irql: %i\n", SekPc, SekCyclesDoneT(), PicoCpuMM68k.int_level>>8); dstrp+=strlen(dstrp);
|
||||||
#elif defined(EMU_F68K)
|
#elif defined(EMU_F68K)
|
||||||
sprintf(dstrp, "M68k: PC: %06x, cycles: %u, irql: %i\n", SekPc, SekCyclesDoneT(), PicoCpuM68k.interrupts[0]); dstrp+=strlen(dstrp);
|
sprintf(dstrp, "M68k: PC: %06x, cycles: %u, irql: %i\n", SekPc, SekCyclesDoneT(), PicoCpuFM68k.interrupts[0]); dstrp+=strlen(dstrp);
|
||||||
#endif
|
#endif
|
||||||
sprintf(dstrp, "z80Run: %i, pal: %i, frame#: %i\n", Pico.m.z80Run, Pico.m.pal, Pico.m.frame_count); dstrp+=strlen(dstrp);
|
sprintf(dstrp, "z80Run: %i, pal: %i, frame#: %i\n", Pico.m.z80Run, Pico.m.pal, Pico.m.frame_count); dstrp+=strlen(dstrp);
|
||||||
z80_debug(dstrp); dstrp+=strlen(dstrp);
|
z80_debug(dstrp); dstrp+=strlen(dstrp);
|
||||||
|
|
|
@ -34,69 +34,68 @@ extern "C" {
|
||||||
// ----------------------- 68000 CPU -----------------------
|
// ----------------------- 68000 CPU -----------------------
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
#include "../cpu/Cyclone/Cyclone.h"
|
#include "../cpu/Cyclone/Cyclone.h"
|
||||||
extern struct Cyclone PicoCpu, PicoCpuS68k;
|
extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
|
||||||
#define SekCyclesLeftNoMCD PicoCpu.cycles // cycles left for this run
|
#define SekCyclesLeftNoMCD PicoCpuCM68k.cycles // cycles left for this run
|
||||||
#define SekCyclesLeft \
|
#define SekCyclesLeft \
|
||||||
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)
|
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)
|
||||||
#define SekCyclesLeftS68k \
|
#define SekCyclesLeftS68k \
|
||||||
((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoCpuS68k.cycles)
|
((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoCpuCS68k.cycles)
|
||||||
#define SekSetCyclesLeftNoMCD(c) PicoCpu.cycles=c
|
#define SekSetCyclesLeftNoMCD(c) PicoCpuCM68k.cycles=c
|
||||||
#define SekSetCyclesLeft(c) { \
|
#define SekSetCyclesLeft(c) { \
|
||||||
if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SekSetCyclesLeftNoMCD(c); \
|
if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SekSetCyclesLeftNoMCD(c); \
|
||||||
}
|
}
|
||||||
#define SekPc (PicoCpu.pc-PicoCpu.membase)
|
#define SekPc (PicoCpuCM68k.pc-PicoCpuCM68k.membase)
|
||||||
#define SekPcS68k (PicoCpuS68k.pc-PicoCpuS68k.membase)
|
#define SekPcS68k (PicoCpuCS68k.pc-PicoCpuCS68k.membase)
|
||||||
#define SekSetStop(x) { PicoCpu.state_flags&=~1; if (x) { PicoCpu.state_flags|=1; PicoCpu.cycles=0; } }
|
#define SekSetStop(x) { PicoCpuCM68k.state_flags&=~1; if (x) { PicoCpuCM68k.state_flags|=1; PicoCpuCM68k.cycles=0; } }
|
||||||
#define SekSetStopS68k(x) { PicoCpuS68k.state_flags&=~1; if (x) { PicoCpuS68k.state_flags|=1; PicoCpuS68k.cycles=0; } }
|
#define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EMU_F68K
|
#ifdef EMU_F68K
|
||||||
#include "../cpu/fame/fame.h"
|
#include "../cpu/fame/fame.h"
|
||||||
M68K_CONTEXT PicoCpuM68k, PicoCpuS68k;
|
M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
|
||||||
#define SekCyclesLeftNoMCD PicoCpuM68k.io_cycle_counter
|
#define SekCyclesLeftNoMCD PicoCpuFM68k.io_cycle_counter
|
||||||
#define SekCyclesLeft \
|
#define SekCyclesLeft \
|
||||||
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)
|
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)
|
||||||
#define SekCyclesLeftS68k \
|
#define SekCyclesLeftS68k \
|
||||||
((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoCpuS68k.io_cycle_counter)
|
((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoCpuFS68k.io_cycle_counter)
|
||||||
#define SekSetCyclesLeftNoMCD(c) PicoCpuM68k.io_cycle_counter=c
|
#define SekSetCyclesLeftNoMCD(c) PicoCpuFM68k.io_cycle_counter=c
|
||||||
#define SekSetCyclesLeft(c) { \
|
#define SekSetCyclesLeft(c) { \
|
||||||
if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SekSetCyclesLeftNoMCD(c); \
|
if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SekSetCyclesLeftNoMCD(c); \
|
||||||
}
|
}
|
||||||
#define SekPc m68k_get_pc(&PicoCpuM68k)
|
#define SekPc m68k_get_pc(&PicoCpuFM68k)
|
||||||
#define SekPcS68k m68k_get_pc(&PicoCpuS68k)
|
#define SekPcS68k m68k_get_pc(&PicoCpuFS68k)
|
||||||
#define SekSetStop(x) { \
|
#define SekSetStop(x) { \
|
||||||
PicoCpuM68k.execinfo &= ~M68K_HALTED; \
|
PicoCpuFM68k.execinfo &= ~M68K_HALTED; \
|
||||||
if (x) { PicoCpuM68k.execinfo |= M68K_HALTED; PicoCpuM68k.io_cycle_counter = 0; } \
|
if (x) { PicoCpuFM68k.execinfo |= M68K_HALTED; PicoCpuFM68k.io_cycle_counter = 0; } \
|
||||||
}
|
}
|
||||||
#define SekSetStopS68k(x) { \
|
#define SekSetStopS68k(x) { \
|
||||||
PicoCpuS68k.execinfo &= ~M68K_HALTED; \
|
PicoCpuFS68k.execinfo &= ~M68K_HALTED; \
|
||||||
if (x) { PicoCpuS68k.execinfo |= M68K_HALTED; PicoCpuS68k.io_cycle_counter = 0; } \
|
if (x) { PicoCpuFS68k.execinfo |= M68K_HALTED; PicoCpuFS68k.io_cycle_counter = 0; } \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EMU_M68K
|
#ifdef EMU_M68K
|
||||||
#include "../cpu/musashi/m68kcpu.h"
|
#include "../cpu/musashi/m68kcpu.h"
|
||||||
extern m68ki_cpu_core PicoM68kCPU; // MD's CPU
|
extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k;
|
||||||
extern m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU
|
|
||||||
#ifndef SekCyclesLeft
|
#ifndef SekCyclesLeft
|
||||||
#define SekCyclesLeftNoMCD PicoM68kCPU.cyc_remaining_cycles
|
#define SekCyclesLeftNoMCD PicoCpuMM68k.cyc_remaining_cycles
|
||||||
#define SekCyclesLeft \
|
#define SekCyclesLeft \
|
||||||
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)
|
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)
|
||||||
#define SekCyclesLeftS68k \
|
#define SekCyclesLeftS68k \
|
||||||
((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoS68kCPU.cyc_remaining_cycles)
|
((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoCpuMS68k.cyc_remaining_cycles)
|
||||||
#define SekSetCyclesLeftNoMCD(c) SET_CYCLES(c)
|
#define SekSetCyclesLeftNoMCD(c) SET_CYCLES(c)
|
||||||
#define SekSetCyclesLeft(c) { \
|
#define SekSetCyclesLeft(c) { \
|
||||||
if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SET_CYCLES(c); \
|
if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SET_CYCLES(c); \
|
||||||
}
|
}
|
||||||
#define SekPc m68k_get_reg(&PicoM68kCPU, M68K_REG_PC)
|
#define SekPc m68k_get_reg(&PicoCpuMM68k, M68K_REG_PC)
|
||||||
#define SekPcS68k m68k_get_reg(&PicoS68kCPU, M68K_REG_PC)
|
#define SekPcS68k m68k_get_reg(&PicoCpuMS68k, M68K_REG_PC)
|
||||||
#define SekSetStop(x) { \
|
#define SekSetStop(x) { \
|
||||||
if(x) { SET_CYCLES(0); PicoM68kCPU.stopped=STOP_LEVEL_STOP; } \
|
if(x) { SET_CYCLES(0); PicoCpuMM68k.stopped=STOP_LEVEL_STOP; } \
|
||||||
else PicoM68kCPU.stopped=0; \
|
else PicoCpuMM68k.stopped=0; \
|
||||||
}
|
}
|
||||||
#define SekSetStopS68k(x) { \
|
#define SekSetStopS68k(x) { \
|
||||||
if(x) { SET_CYCLES(0); PicoS68kCPU.stopped=STOP_LEVEL_STOP; } \
|
if(x) { SET_CYCLES(0); PicoCpuMS68k.stopped=STOP_LEVEL_STOP; } \
|
||||||
else PicoS68kCPU.stopped=0; \
|
else PicoCpuMS68k.stopped=0; \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -345,7 +344,7 @@ PICO_INTERNAL int PicoFrameMCD(void);
|
||||||
PICO_INTERNAL int SekInit(void);
|
PICO_INTERNAL int SekInit(void);
|
||||||
PICO_INTERNAL int SekReset(void);
|
PICO_INTERNAL int SekReset(void);
|
||||||
PICO_INTERNAL int SekInterrupt(int irq);
|
PICO_INTERNAL int SekInterrupt(int irq);
|
||||||
PICO_INTERNAL void SekState(unsigned char *data);
|
PICO_INTERNAL void SekState(int *data);
|
||||||
PICO_INTERNAL void SekSetRealTAS(int use_real);
|
PICO_INTERNAL void SekSetRealTAS(int use_real);
|
||||||
|
|
||||||
// cd/Sek.c
|
// cd/Sek.c
|
||||||
|
|
98
Pico/Sek.c
98
Pico/Sek.c
|
@ -18,15 +18,15 @@ unsigned int SekCycleCntT=0;
|
||||||
/* context */
|
/* context */
|
||||||
// Cyclone 68000
|
// Cyclone 68000
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
struct Cyclone PicoCpu;
|
struct Cyclone PicoCpuCM68k;
|
||||||
#endif
|
#endif
|
||||||
// MUSASHI 68000
|
// MUSASHI 68000
|
||||||
#ifdef EMU_M68K
|
#ifdef EMU_M68K
|
||||||
m68ki_cpu_core PicoM68kCPU;
|
m68ki_cpu_core PicoCpuMM68k;
|
||||||
#endif
|
#endif
|
||||||
// FAME 68000
|
// FAME 68000
|
||||||
#ifdef EMU_F68K
|
#ifdef EMU_F68K
|
||||||
M68K_CONTEXT PicoCpuM68k;
|
M68K_CONTEXT PicoCpuFM68k;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ static int SekIntAck(int level)
|
||||||
// try to emulate VDP's reaction to 68000 int ack
|
// try to emulate VDP's reaction to 68000 int ack
|
||||||
if (level == 4) { Pico.video.pending_ints = 0; elprintf(EL_INTS, "hack: @ %06x [%i]", SekPc, SekCycleCnt); }
|
if (level == 4) { Pico.video.pending_ints = 0; elprintf(EL_INTS, "hack: @ %06x [%i]", SekPc, SekCycleCnt); }
|
||||||
else if(level == 6) { Pico.video.pending_ints &= ~0x20; elprintf(EL_INTS, "vack: @ %06x [%i]", SekPc, SekCycleCnt); }
|
else if(level == 6) { Pico.video.pending_ints &= ~0x20; elprintf(EL_INTS, "vack: @ %06x [%i]", SekPc, SekCycleCnt); }
|
||||||
PicoCpu.irq = 0;
|
PicoCpuCM68k.irq = 0;
|
||||||
return CYCLONE_INT_ACK_AUTOVECTOR;
|
return CYCLONE_INT_ACK_AUTOVECTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,12 +51,12 @@ static int SekUnrecognizedOpcode()
|
||||||
{
|
{
|
||||||
unsigned int pc, op;
|
unsigned int pc, op;
|
||||||
pc = SekPc;
|
pc = SekPc;
|
||||||
op = PicoCpu.read16(pc);
|
op = PicoCpuCM68k.read16(pc);
|
||||||
elprintf(EL_ANOMALY, "Unrecognized Opcode %04x @ %06x", op, pc);
|
elprintf(EL_ANOMALY, "Unrecognized Opcode %04x @ %06x", op, pc);
|
||||||
// see if we are not executing trash
|
// see if we are not executing trash
|
||||||
if (pc < 0x200 || (pc > Pico.romsize+4 && (pc&0xe00000)!=0xe00000)) {
|
if (pc < 0x200 || (pc > Pico.romsize+4 && (pc&0xe00000)!=0xe00000)) {
|
||||||
PicoCpu.cycles = 0;
|
PicoCpuCM68k.cycles = 0;
|
||||||
PicoCpu.state_flags |= 1;
|
PicoCpuCM68k.state_flags |= 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#ifdef EMU_M68K // debugging cyclone
|
#ifdef EMU_M68K // debugging cyclone
|
||||||
|
@ -87,31 +87,11 @@ static int SekTasCallback(void)
|
||||||
|
|
||||||
|
|
||||||
#ifdef EMU_F68K
|
#ifdef EMU_F68K
|
||||||
static void setup_fame_fetchmap(void)
|
static void SekIntAckF68K(unsigned level)
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// be default, point everything to fitst 64k of ROM
|
|
||||||
for (i = 0; i < M68K_FETCHBANK1; i++)
|
|
||||||
PicoCpuM68k.Fetch[i] = (unsigned int)Pico.rom - (i<<(24-FAMEC_FETCHBITS));
|
|
||||||
// now real ROM
|
|
||||||
for (i = 0; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < Pico.romsize; i++)
|
|
||||||
PicoCpuM68k.Fetch[i] = (unsigned int)Pico.rom;
|
|
||||||
elprintf(EL_ANOMALY, "ROM end @ #%i %06x", i, (i<<(24-FAMEC_FETCHBITS)));
|
|
||||||
// .. and RAM (TODO)
|
|
||||||
for (i = M68K_FETCHBANK1*14/16; i < M68K_FETCHBANK1; i++)
|
|
||||||
PicoCpuM68k.Fetch[i] = (unsigned int)Pico.ram - (i<<(24-FAMEC_FETCHBITS));
|
|
||||||
|
|
||||||
elprintf(EL_ANOMALY, "rom = %p, ram = %p", Pico.rom, Pico.ram);
|
|
||||||
for (i = 0; i < M68K_FETCHBANK1; i++)
|
|
||||||
elprintf(EL_ANOMALY, "Fetch[%i] = %p", i, PicoCpuM68k.Fetch[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SekIntAckF68K(unsigned level)
|
|
||||||
{
|
{
|
||||||
if (level == 4) { Pico.video.pending_ints = 0; elprintf(EL_INTS, "hack: @ %06x [%i]", SekPc, SekCycleCnt); }
|
if (level == 4) { Pico.video.pending_ints = 0; elprintf(EL_INTS, "hack: @ %06x [%i]", SekPc, SekCycleCnt); }
|
||||||
else if(level == 6) { Pico.video.pending_ints &= ~0x20; elprintf(EL_INTS, "vack: @ %06x [%i]", SekPc, SekCycleCnt); }
|
else if(level == 6) { Pico.video.pending_ints &= ~0x20; elprintf(EL_INTS, "vack: @ %06x [%i]", SekPc, SekCycleCnt); }
|
||||||
PicoCpuM68k.interrupts[0] = 0;
|
PicoCpuFM68k.interrupts[0] = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -120,15 +100,15 @@ PICO_INTERNAL int SekInit()
|
||||||
{
|
{
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
CycloneInit();
|
CycloneInit();
|
||||||
memset(&PicoCpu,0,sizeof(PicoCpu));
|
memset(&PicoCpuCM68k,0,sizeof(PicoCpuCM68k));
|
||||||
PicoCpu.IrqCallback=SekIntAck;
|
PicoCpuCM68k.IrqCallback=SekIntAck;
|
||||||
PicoCpu.ResetCallback=SekResetAck;
|
PicoCpuCM68k.ResetCallback=SekResetAck;
|
||||||
PicoCpu.UnrecognizedCallback=SekUnrecognizedOpcode;
|
PicoCpuCM68k.UnrecognizedCallback=SekUnrecognizedOpcode;
|
||||||
#endif
|
#endif
|
||||||
#ifdef EMU_M68K
|
#ifdef EMU_M68K
|
||||||
{
|
{
|
||||||
void *oldcontext = m68ki_cpu_p;
|
void *oldcontext = m68ki_cpu_p;
|
||||||
m68k_set_context(&PicoM68kCPU);
|
m68k_set_context(&PicoCpuMM68k);
|
||||||
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
|
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
|
||||||
m68k_init();
|
m68k_init();
|
||||||
m68k_set_int_ack_callback(SekIntAckM68K);
|
m68k_set_int_ack_callback(SekIntAckM68K);
|
||||||
|
@ -140,10 +120,10 @@ PICO_INTERNAL int SekInit()
|
||||||
#ifdef EMU_F68K
|
#ifdef EMU_F68K
|
||||||
{
|
{
|
||||||
void *oldcontext = g_m68kcontext;
|
void *oldcontext = g_m68kcontext;
|
||||||
g_m68kcontext = &PicoCpuM68k;
|
g_m68kcontext = &PicoCpuFM68k;
|
||||||
memset(&PicoCpuM68k, 0, sizeof(PicoCpuM68k));
|
memset(&PicoCpuFM68k, 0, sizeof(PicoCpuFM68k));
|
||||||
m68k_init();
|
m68k_init();
|
||||||
PicoCpuM68k.iack_handler = SekIntAckF68K;
|
PicoCpuFM68k.iack_handler = SekIntAckF68K;
|
||||||
g_m68kcontext = oldcontext;
|
g_m68kcontext = oldcontext;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -158,28 +138,25 @@ PICO_INTERNAL int SekReset()
|
||||||
if (Pico.rom==NULL) return 1;
|
if (Pico.rom==NULL) return 1;
|
||||||
|
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
PicoCpu.state_flags=0;
|
PicoCpuCM68k.state_flags=0;
|
||||||
PicoCpu.osp=0;
|
PicoCpuCM68k.osp=0;
|
||||||
PicoCpu.srh =0x27; // Supervisor mode
|
PicoCpuCM68k.srh =0x27; // Supervisor mode
|
||||||
PicoCpu.flags=4; // Z set
|
PicoCpuCM68k.flags=4; // Z set
|
||||||
PicoCpu.irq=0;
|
PicoCpuCM68k.irq=0;
|
||||||
PicoCpu.a[7]=PicoCpu.read32(0); // Stack Pointer
|
PicoCpuCM68k.a[7]=PicoCpuCM68k.read32(0); // Stack Pointer
|
||||||
PicoCpu.membase=0;
|
PicoCpuCM68k.membase=0;
|
||||||
PicoCpu.pc=PicoCpu.checkpc(PicoCpu.read32(4)); // Program Counter
|
PicoCpuCM68k.pc=PicoCpuCM68k.checkpc(PicoCpuCM68k.read32(4)); // Program Counter
|
||||||
#endif
|
#endif
|
||||||
#ifdef EMU_M68K
|
#ifdef EMU_M68K
|
||||||
m68k_set_context(&PicoM68kCPU); // if we ever reset m68k, we always need it's context to be set
|
m68k_set_context(&PicoCpuMM68k); // if we ever reset m68k, we always need it's context to be set
|
||||||
m68ki_cpu.sp[0]=0;
|
m68ki_cpu.sp[0]=0;
|
||||||
m68k_set_irq(0);
|
m68k_set_irq(0);
|
||||||
m68k_pulse_reset();
|
m68k_pulse_reset();
|
||||||
#endif
|
#endif
|
||||||
#ifdef EMU_F68K
|
#ifdef EMU_F68K
|
||||||
{
|
{
|
||||||
unsigned ret;
|
g_m68kcontext = &PicoCpuFM68k;
|
||||||
g_m68kcontext = &PicoCpuM68k;
|
m68k_reset();
|
||||||
setup_fame_fetchmap();
|
|
||||||
ret = m68k_reset();
|
|
||||||
/*if (ret)*/ elprintf(EL_ANOMALY, "m68k_reset returned %u", ret);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -197,33 +174,34 @@ PICO_INTERNAL int SekInterrupt(int irq)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
PicoCpu.irq=irq;
|
PicoCpuCM68k.irq=irq;
|
||||||
#endif
|
#endif
|
||||||
#ifdef EMU_M68K
|
#ifdef EMU_M68K
|
||||||
{
|
{
|
||||||
void *oldcontext = m68ki_cpu_p;
|
void *oldcontext = m68ki_cpu_p;
|
||||||
m68k_set_context(&PicoM68kCPU);
|
m68k_set_context(&PicoCpuMM68k);
|
||||||
m68k_set_irq(irq); // raise irq (gets lowered after taken or must be done in ack)
|
m68k_set_irq(irq); // raise irq (gets lowered after taken or must be done in ack)
|
||||||
m68k_set_context(oldcontext);
|
m68k_set_context(oldcontext);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef EMU_F68K
|
#ifdef EMU_F68K
|
||||||
PicoCpuM68k.interrupts[0]=irq;
|
PicoCpuFM68k.interrupts[0]=irq;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PICO_INTERNAL void SekState(unsigned char *data)
|
// data must be word aligned
|
||||||
|
PICO_INTERNAL void SekState(int *data)
|
||||||
{
|
{
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
memcpy(data,PicoCpu.d,0x44);
|
memcpy32(data,PicoCpuCM68k.d,0x44/4);
|
||||||
#elif defined(EMU_M68K)
|
#elif defined(EMU_M68K)
|
||||||
memcpy(data, PicoM68kCPU.dar, 0x40);
|
memcpy32(data, PicoCpuMM68k.dar, 0x40/4);
|
||||||
*(int *)(data+0x40) = PicoM68kCPU.pc;
|
data[0x10] = PicoCpuMM68k.pc;
|
||||||
#elif defined(EMU_F68K)
|
#elif defined(EMU_F68K)
|
||||||
memcpy(data, PicoCpuM68k.dreg, 0x40);
|
memcpy32(data, (int *)PicoCpuFM68k.dreg, 0x40/4);
|
||||||
*(int *)(data+0x40) = PicoCpuM68k.pc;
|
data[0x10] = PicoCpuFM68k.pc;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -382,7 +382,7 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
|
||||||
if(num < 2) {
|
if(num < 2) {
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
// hack: make sure we do not touch the irq line if Cyclone is just about to take the IRQ
|
// hack: make sure we do not touch the irq line if Cyclone is just about to take the IRQ
|
||||||
if (PicoCpu.irq <= (PicoCpu.srh&7)) {
|
if (PicoCpuCM68k.irq <= (PicoCpuCM68k.srh&7)) {
|
||||||
#endif
|
#endif
|
||||||
int lines, pints;
|
int lines, pints;
|
||||||
lines = (pvid->reg[1] & 0x20) | (pvid->reg[0] & 0x10);
|
lines = (pvid->reg[1] & 0x20) | (pvid->reg[0] & 0x10);
|
||||||
|
@ -392,7 +392,7 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
|
||||||
else SekInterrupt(0);
|
else SekInterrupt(0);
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
// adjust cycles for Cyclone so it would take the int "in time"
|
// adjust cycles for Cyclone so it would take the int "in time"
|
||||||
if(PicoCpu.irq) {
|
if(PicoCpuCM68k.irq) {
|
||||||
SekEndRun(24);
|
SekEndRun(24);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ void dumpPCandExit()
|
||||||
dprintf("PC: %06x: %04x: %s", pppc, ppop, buff);
|
dprintf("PC: %06x: %04x: %s", pppc, ppop, buff);
|
||||||
dprintf(" this | prev");
|
dprintf(" this | prev");
|
||||||
for(i=0; i < 8; i++)
|
for(i=0; i < 8; i++)
|
||||||
dprintf("d%i=%08x, a%i=%08x | d%i=%08x, a%i=%08x", i, PicoCpu.d[i], i, PicoCpu.a[i], i, old_regs[i], i, old_regs[i+8]);
|
dprintf("d%i=%08x, a%i=%08x | d%i=%08x, a%i=%08x", i, PicoCpuCM68k.d[i], i, PicoCpuCM68k.a[i], i, old_regs[i], i, old_regs[i+8]);
|
||||||
dprintf("SR: %04x | %04x (??s? 0iii 000x nzvc)", CycloneGetSr(&PicoCpu), old_sr);
|
dprintf("SR: %04x | %04x (??s? 0iii 000x nzvc)", CycloneGetSr(&PicoCpuCM68k), old_sr);
|
||||||
dprintf("last_read: %08x @ %06x", lastread_d[--lrp_cyc&15], lastread_a);
|
dprintf("last_read: %08x @ %06x", lastread_d[--lrp_cyc&15], lastread_a);
|
||||||
dprintf("ops done: %i", ops);
|
dprintf("ops done: %i", ops);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -43,7 +43,7 @@ int CM_compareRun(int cyc)
|
||||||
{
|
{
|
||||||
have_illegal = 0;
|
have_illegal = 0;
|
||||||
m68ki_cpu.pc += 2;
|
m68ki_cpu.pc += 2;
|
||||||
PicoCpu.pc=PicoCpu.checkpc(PicoCpu.pc + 2);
|
PicoCpuCM68k.pc=PicoCpuCM68k.checkpc(PicoCpuCM68k.pc + 2);
|
||||||
}
|
}
|
||||||
// hacks for test_misc2
|
// hacks for test_misc2
|
||||||
if (m68ki_cpu.pc == 0x0002e0 && m68k_read_disassembler_16(m68ki_cpu.pc) == 0x4e73)
|
if (m68ki_cpu.pc == 0x0002e0 && m68k_read_disassembler_16(m68ki_cpu.pc) == 0x4e73)
|
||||||
|
@ -51,13 +51,13 @@ int CM_compareRun(int cyc)
|
||||||
// get out of "priviledge violation" loop
|
// get out of "priviledge violation" loop
|
||||||
have_illegal = 1;
|
have_illegal = 1;
|
||||||
//m68ki_cpu.s_flag = SFLAG_SET;
|
//m68ki_cpu.s_flag = SFLAG_SET;
|
||||||
//PicoCpu.srh|=0x20;
|
//PicoCpuCM68k.srh|=0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
pppc = SekPc;
|
pppc = SekPc;
|
||||||
ppop = m68k_read_disassembler_16(pppc);
|
ppop = m68k_read_disassembler_16(pppc);
|
||||||
memcpy(old_regs, PicoCpu.d, 4*16);
|
memcpy(old_regs, PicoCpuCM68k.d, 4*16);
|
||||||
old_sr = CycloneGetSr(&PicoCpu);
|
old_sr = CycloneGetSr(&PicoCpuCM68k);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
|
@ -65,20 +65,20 @@ int CM_compareRun(int cyc)
|
||||||
dprintf("---");
|
dprintf("---");
|
||||||
m68k_disassemble(buff, pppc, M68K_CPU_TYPE_68000);
|
m68k_disassemble(buff, pppc, M68K_CPU_TYPE_68000);
|
||||||
dprintf("PC: %06x: %04x: %s", pppc, ppop, buff);
|
dprintf("PC: %06x: %04x: %s", pppc, ppop, buff);
|
||||||
//dprintf("A7: %08x", PicoCpu.a[7]);
|
//dprintf("A7: %08x", PicoCpuCM68k.a[7]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dbg_irq_level)
|
if (dbg_irq_level)
|
||||||
{
|
{
|
||||||
PicoCpu.irq=dbg_irq_level;
|
PicoCpuCM68k.irq=dbg_irq_level;
|
||||||
m68k_set_irq(dbg_irq_level);
|
m68k_set_irq(dbg_irq_level);
|
||||||
dbg_irq_level=0;
|
dbg_irq_level=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PicoCpu.cycles=1;
|
PicoCpuCM68k.cycles=1;
|
||||||
CycloneRun(&PicoCpu);
|
CycloneRun(&PicoCpuCM68k);
|
||||||
cyc_cyclone=1-PicoCpu.cycles;
|
cyc_cyclone=1-PicoCpuCM68k.cycles;
|
||||||
cyc_musashi=m68k_execute(1);
|
cyc_musashi=m68k_execute(1);
|
||||||
|
|
||||||
if(cyc_cyclone != cyc_musashi) {
|
if(cyc_cyclone != cyc_musashi) {
|
||||||
|
@ -120,57 +120,57 @@ int CM_compareRun(int cyc)
|
||||||
|
|
||||||
// compare regs
|
// compare regs
|
||||||
for(i=0; i < 16; i++) {
|
for(i=0; i < 16; i++) {
|
||||||
if(PicoCpu.d[i] != m68ki_cpu.dar[i]) {
|
if(PicoCpuCM68k.d[i] != m68ki_cpu.dar[i]) {
|
||||||
str = (i < 8) ? "d" : "a";
|
str = (i < 8) ? "d" : "a";
|
||||||
dprintf("reg: %s%i: %08x vs %08x", str, i&7, PicoCpu.d[i], m68ki_cpu.dar[i]);
|
dprintf("reg: %s%i: %08x vs %08x", str, i&7, PicoCpuCM68k.d[i], m68ki_cpu.dar[i]);
|
||||||
err=1;
|
err=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SR
|
// SR
|
||||||
if((CycloneGetSr(&PicoCpu)) != (mu_sr = m68k_get_reg(NULL, M68K_REG_SR))) {
|
if((CycloneGetSr(&PicoCpuCM68k)) != (mu_sr = m68k_get_reg(NULL, M68K_REG_SR))) {
|
||||||
dprintf("SR: %04x vs %04x (??s? 0iii 000x nzvc)", CycloneGetSr(&PicoCpu), mu_sr);
|
dprintf("SR: %04x vs %04x (??s? 0iii 000x nzvc)", CycloneGetSr(&PicoCpuCM68k), mu_sr);
|
||||||
err=1;
|
err=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IRQl
|
// IRQl
|
||||||
if(PicoCpu.irq != (m68ki_cpu.int_level>>8)) {
|
if(PicoCpuCM68k.irq != (m68ki_cpu.int_level>>8)) {
|
||||||
dprintf("IRQ: %i vs %i", PicoCpu.irq, (m68ki_cpu.int_level>>8));
|
dprintf("IRQ: %i vs %i", PicoCpuCM68k.irq, (m68ki_cpu.int_level>>8));
|
||||||
err=1;
|
err=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OSP/USP
|
// OSP/USP
|
||||||
if(PicoCpu.osp != m68ki_cpu.sp[((mu_sr>>11)&4)^4]) {
|
if(PicoCpuCM68k.osp != m68ki_cpu.sp[((mu_sr>>11)&4)^4]) {
|
||||||
dprintf("OSP: %06x vs %06x", PicoCpu.osp, m68ki_cpu.sp[((mu_sr>>11)&4)^4]);
|
dprintf("OSP: %06x vs %06x", PicoCpuCM68k.osp, m68ki_cpu.sp[((mu_sr>>11)&4)^4]);
|
||||||
err=1;
|
err=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// stopped
|
// stopped
|
||||||
if(((PicoCpu.state_flags&1) && !m68ki_cpu.stopped) || (!(PicoCpu.state_flags&1) && m68ki_cpu.stopped)) {
|
if(((PicoCpuCM68k.state_flags&1) && !m68ki_cpu.stopped) || (!(PicoCpuCM68k.state_flags&1) && m68ki_cpu.stopped)) {
|
||||||
dprintf("stopped: %i vs %i", PicoCpu.state_flags&1, m68ki_cpu.stopped);
|
dprintf("stopped: %i vs %i", PicoCpuCM68k.state_flags&1, m68ki_cpu.stopped);
|
||||||
err=1;
|
err=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tracing
|
// tracing
|
||||||
if(((PicoCpu.state_flags&2) && !m68ki_tracing) || (!(PicoCpu.state_flags&2) && m68ki_tracing)) {
|
if(((PicoCpuCM68k.state_flags&2) && !m68ki_tracing) || (!(PicoCpuCM68k.state_flags&2) && m68ki_tracing)) {
|
||||||
dprintf("tracing: %i vs %i", PicoCpu.state_flags&2, m68ki_tracing);
|
dprintf("tracing: %i vs %i", PicoCpuCM68k.state_flags&2, m68ki_tracing);
|
||||||
err=1;
|
err=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(err) dumpPCandExit();
|
if(err) dumpPCandExit();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (PicoCpu.a[7] < 0x00ff0000 || PicoCpu.a[7] >= 0x01000000)
|
if (PicoCpuCM68k.a[7] < 0x00ff0000 || PicoCpuCM68k.a[7] >= 0x01000000)
|
||||||
{
|
{
|
||||||
PicoCpu.a[7] = m68ki_cpu.dar[15] = 0xff8000;
|
PicoCpuCM68k.a[7] = m68ki_cpu.dar[15] = 0xff8000;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
m68k_set_reg(M68K_REG_SR, ((mu_sr-1)&~0x2000)|(mu_sr&0x2000)); // broken
|
m68k_set_reg(M68K_REG_SR, ((mu_sr-1)&~0x2000)|(mu_sr&0x2000)); // broken
|
||||||
CycloneSetSr(&PicoCpu, ((mu_sr-1)&~0x2000)|(mu_sr&0x2000));
|
CycloneSetSr(&PicoCpuCM68k, ((mu_sr-1)&~0x2000)|(mu_sr&0x2000));
|
||||||
PicoCpu.stopped = m68ki_cpu.stopped = 0;
|
PicoCpuCM68k.stopped = m68ki_cpu.stopped = 0;
|
||||||
if(SekPc > 0x400 && (PicoCpu.a[7] < 0xff0000 || PicoCpu.a[7] > 0xffffff))
|
if(SekPc > 0x400 && (PicoCpuCM68k.a[7] < 0xff0000 || PicoCpuCM68k.a[7] > 0xffffff))
|
||||||
PicoCpu.a[7] = m68ki_cpu.dar[15] = 0xff8000;
|
PicoCpuCM68k.a[7] = m68ki_cpu.dar[15] = 0xff8000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cyc_done += cyc_cyclone;
|
cyc_done += cyc_cyclone;
|
||||||
|
|
|
@ -240,8 +240,8 @@ PICO_INTERNAL int PicoCdLoadState(void *file)
|
||||||
/* after load events */
|
/* after load events */
|
||||||
if (Pico_mcd->s68k_regs[3]&4) // 1M mode?
|
if (Pico_mcd->s68k_regs[3]&4) // 1M mode?
|
||||||
wram_2M_to_1M(Pico_mcd->word_ram2M);
|
wram_2M_to_1M(Pico_mcd->word_ram2M);
|
||||||
#ifdef _ASM_CD_MEMORY_C
|
|
||||||
PicoMemResetCD(Pico_mcd->s68k_regs[3]);
|
PicoMemResetCD(Pico_mcd->s68k_regs[3]);
|
||||||
|
#ifdef _ASM_CD_MEMORY_C
|
||||||
if (Pico_mcd->s68k_regs[3]&4)
|
if (Pico_mcd->s68k_regs[3]&4)
|
||||||
PicoMemResetCDdecode(Pico_mcd->s68k_regs[3]);
|
PicoMemResetCDdecode(Pico_mcd->s68k_regs[3]);
|
||||||
#endif
|
#endif
|
||||||
|
|
160
Pico/cd/Memory.c
160
Pico/cd/Memory.c
|
@ -293,9 +293,7 @@ void s68k_reg_write8(u32 a, u32 d)
|
||||||
if (d&4) {
|
if (d&4) {
|
||||||
if ((d ^ dold) & 5) {
|
if ((d ^ dold) & 5) {
|
||||||
d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit
|
d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit
|
||||||
#ifdef _ASM_CD_MEMORY_C
|
|
||||||
PicoMemResetCD(d);
|
PicoMemResetCD(d);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#ifdef _ASM_CD_MEMORY_C
|
#ifdef _ASM_CD_MEMORY_C
|
||||||
if ((d ^ dold) & 0x1d)
|
if ((d ^ dold) & 0x1d)
|
||||||
|
@ -313,9 +311,7 @@ void s68k_reg_write8(u32 a, u32 d)
|
||||||
d |= (dold&1) ? 2 : 1; // then give it to the one which had bank0 in 1M mode
|
d |= (dold&1) ? 2 : 1; // then give it to the one which had bank0 in 1M mode
|
||||||
}
|
}
|
||||||
wram_1M_to_2M(Pico_mcd->word_ram2M);
|
wram_1M_to_2M(Pico_mcd->word_ram2M);
|
||||||
#ifdef _ASM_CD_MEMORY_C
|
|
||||||
PicoMemResetCD(d);
|
PicoMemResetCD(d);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
d |= dold&1;
|
d |= dold&1;
|
||||||
|
@ -817,7 +813,7 @@ static u32 PicoReadS68k8(u32 a)
|
||||||
// test: batman returns
|
// test: batman returns
|
||||||
wrdprintf("s68k_wram2M r8: [%06x] @%06x", a, SekPcS68k);
|
wrdprintf("s68k_wram2M r8: [%06x] @%06x", a, SekPcS68k);
|
||||||
if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?
|
if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?
|
||||||
int bank = !(Pico_mcd->s68k_regs[3]&1);
|
int bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];
|
d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];
|
||||||
if (a&1) d &= 0x0f;
|
if (a&1) d &= 0x0f;
|
||||||
else d >>= 4;
|
else d >>= 4;
|
||||||
|
@ -836,7 +832,7 @@ static u32 PicoReadS68k8(u32 a)
|
||||||
wrdprintf("s68k_wram1M r8: [%06x] @%06x", a, SekPcS68k);
|
wrdprintf("s68k_wram1M r8: [%06x] @%06x", a, SekPcS68k);
|
||||||
// if (!(Pico_mcd->s68k_regs[3]&4))
|
// if (!(Pico_mcd->s68k_regs[3]&4))
|
||||||
// dprintf("s68k_wram1M FIXME: wrong mode");
|
// dprintf("s68k_wram1M FIXME: wrong mode");
|
||||||
bank = !(Pico_mcd->s68k_regs[3]&1);
|
bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
d = Pico_mcd->word_ram1M[bank][(a^1)&0x1ffff];
|
d = Pico_mcd->word_ram1M[bank][(a^1)&0x1ffff];
|
||||||
wrdprintf("ret = %02x", (u8)d);
|
wrdprintf("ret = %02x", (u8)d);
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -907,7 +903,7 @@ static u32 PicoReadS68k16(u32 a)
|
||||||
if ((a&0xfc0000)==0x080000) { // 080000-0bffff
|
if ((a&0xfc0000)==0x080000) { // 080000-0bffff
|
||||||
wrdprintf("s68k_wram2M r16: [%06x] @%06x", a, SekPcS68k);
|
wrdprintf("s68k_wram2M r16: [%06x] @%06x", a, SekPcS68k);
|
||||||
if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?
|
if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?
|
||||||
int bank = !(Pico_mcd->s68k_regs[3]&1);
|
int bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];
|
d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];
|
||||||
d |= d << 4; d &= ~0xf0;
|
d |= d << 4; d &= ~0xf0;
|
||||||
dprintf("FIXME: decode");
|
dprintf("FIXME: decode");
|
||||||
|
@ -925,7 +921,7 @@ static u32 PicoReadS68k16(u32 a)
|
||||||
wrdprintf("s68k_wram1M r16: [%06x] @%06x", a, SekPcS68k);
|
wrdprintf("s68k_wram1M r16: [%06x] @%06x", a, SekPcS68k);
|
||||||
// if (!(Pico_mcd->s68k_regs[3]&4))
|
// if (!(Pico_mcd->s68k_regs[3]&4))
|
||||||
// dprintf("s68k_wram1M FIXME: wrong mode");
|
// dprintf("s68k_wram1M FIXME: wrong mode");
|
||||||
bank = !(Pico_mcd->s68k_regs[3]&1);
|
bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
d = *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));
|
d = *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));
|
||||||
wrdprintf("ret = %04x", d);
|
wrdprintf("ret = %04x", d);
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -999,7 +995,7 @@ static u32 PicoReadS68k32(u32 a)
|
||||||
if ((a&0xfc0000)==0x080000) { // 080000-0bffff
|
if ((a&0xfc0000)==0x080000) { // 080000-0bffff
|
||||||
wrdprintf("s68k_wram2M r32: [%06x] @%06x", a, SekPcS68k);
|
wrdprintf("s68k_wram2M r32: [%06x] @%06x", a, SekPcS68k);
|
||||||
if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?
|
if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?
|
||||||
int bank = !(Pico_mcd->s68k_regs[3]&1);
|
int bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
a >>= 1;
|
a >>= 1;
|
||||||
d = Pico_mcd->word_ram1M[bank][((a+0)^1)&0x1ffff] << 16;
|
d = Pico_mcd->word_ram1M[bank][((a+0)^1)&0x1ffff] << 16;
|
||||||
d |= Pico_mcd->word_ram1M[bank][((a+1)^1)&0x1ffff];
|
d |= Pico_mcd->word_ram1M[bank][((a+1)^1)&0x1ffff];
|
||||||
|
@ -1018,7 +1014,7 @@ static u32 PicoReadS68k32(u32 a)
|
||||||
wrdprintf("s68k_wram1M r32: [%06x] @%06x", a, SekPcS68k);
|
wrdprintf("s68k_wram1M r32: [%06x] @%06x", a, SekPcS68k);
|
||||||
// if (!(Pico_mcd->s68k_regs[3]&4))
|
// if (!(Pico_mcd->s68k_regs[3]&4))
|
||||||
// dprintf("s68k_wram1M FIXME: wrong mode");
|
// dprintf("s68k_wram1M FIXME: wrong mode");
|
||||||
bank = !(Pico_mcd->s68k_regs[3]&1);
|
bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];
|
u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];
|
||||||
wrdprintf("ret = %08x", d);
|
wrdprintf("ret = %08x", d);
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -1075,7 +1071,7 @@ static u32 PicoReadS68k32(u32 a)
|
||||||
/* check: jaguar xj 220 (draws entire world using decode) */
|
/* check: jaguar xj 220 (draws entire world using decode) */
|
||||||
static void decode_write8(u32 a, u8 d, int r3)
|
static void decode_write8(u32 a, u8 d, int r3)
|
||||||
{
|
{
|
||||||
u8 *pd = Pico_mcd->word_ram1M[!(r3 & 1)] + (((a>>1)^1)&0x1ffff);
|
u8 *pd = Pico_mcd->word_ram1M[(r3 & 1)^1] + (((a>>1)^1)&0x1ffff);
|
||||||
u8 oldmask = (a&1) ? 0xf0 : 0x0f;
|
u8 oldmask = (a&1) ? 0xf0 : 0x0f;
|
||||||
|
|
||||||
r3 &= 0x18;
|
r3 &= 0x18;
|
||||||
|
@ -1098,7 +1094,7 @@ do_it:
|
||||||
|
|
||||||
static void decode_write16(u32 a, u16 d, int r3)
|
static void decode_write16(u32 a, u16 d, int r3)
|
||||||
{
|
{
|
||||||
u8 *pd = Pico_mcd->word_ram1M[!(r3 & 1)] + (((a>>1)^1)&0x1ffff);
|
u8 *pd = Pico_mcd->word_ram1M[(r3 & 1)^1] + (((a>>1)^1)&0x1ffff);
|
||||||
|
|
||||||
//if ((a & 0x3ffff) < 0x28000) return;
|
//if ((a & 0x3ffff) < 0x28000) return;
|
||||||
|
|
||||||
|
@ -1173,7 +1169,7 @@ static void PicoWriteS68k8(u32 a,u8 d)
|
||||||
wrdprintf("s68k_wram1M w8: [%06x] %02x @%06x", a, d, SekPcS68k);
|
wrdprintf("s68k_wram1M w8: [%06x] %02x @%06x", a, d, SekPcS68k);
|
||||||
// if (!(Pico_mcd->s68k_regs[3]&4))
|
// if (!(Pico_mcd->s68k_regs[3]&4))
|
||||||
// dprintf("s68k_wram1M FIXME: wrong mode");
|
// dprintf("s68k_wram1M FIXME: wrong mode");
|
||||||
bank = !(Pico_mcd->s68k_regs[3]&1);
|
bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
*(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff))=d;
|
*(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff))=d;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1256,7 +1252,7 @@ static void PicoWriteS68k16(u32 a,u16 d)
|
||||||
wrdprintf("s68k_wram1M w16: [%06x] %04x @%06x", a, d, SekPcS68k);
|
wrdprintf("s68k_wram1M w16: [%06x] %04x @%06x", a, d, SekPcS68k);
|
||||||
// if (!(Pico_mcd->s68k_regs[3]&4))
|
// if (!(Pico_mcd->s68k_regs[3]&4))
|
||||||
// dprintf("s68k_wram1M FIXME: wrong mode");
|
// dprintf("s68k_wram1M FIXME: wrong mode");
|
||||||
bank = !(Pico_mcd->s68k_regs[3]&1);
|
bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
*(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe))=d;
|
*(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe))=d;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1346,7 +1342,7 @@ static void PicoWriteS68k32(u32 a,u32 d)
|
||||||
wrdprintf("s68k_wram1M w32: [%06x] %08x @%06x", a, d, SekPcS68k);
|
wrdprintf("s68k_wram1M w32: [%06x] %08x @%06x", a, d, SekPcS68k);
|
||||||
// if (!(Pico_mcd->s68k_regs[3]&4))
|
// if (!(Pico_mcd->s68k_regs[3]&4))
|
||||||
// dprintf("s68k_wram1M FIXME: wrong mode");
|
// dprintf("s68k_wram1M FIXME: wrong mode");
|
||||||
bank = !(Pico_mcd->s68k_regs[3]&1);
|
bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));
|
pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));
|
||||||
pm[0]=(u16)(d>>16); pm[1]=(u16)d;
|
pm[0]=(u16)(d>>16); pm[1]=(u16)d;
|
||||||
return;
|
return;
|
||||||
|
@ -1387,7 +1383,7 @@ static void PicoWriteS68k32(u32 a,u32 d)
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
#if defined(EMU_C68K)
|
#ifdef EMU_C68K
|
||||||
static __inline int PicoMemBaseM68k(u32 pc)
|
static __inline int PicoMemBaseM68k(u32 pc)
|
||||||
{
|
{
|
||||||
if ((pc&0xe00000)==0xe00000)
|
if ((pc&0xe00000)==0xe00000)
|
||||||
|
@ -1401,7 +1397,7 @@ static __inline int PicoMemBaseM68k(u32 pc)
|
||||||
if (!(Pico_mcd->s68k_regs[3]&4))
|
if (!(Pico_mcd->s68k_regs[3]&4))
|
||||||
return (int)Pico_mcd->word_ram2M - 0x200000; // Program Counter in Word Ram
|
return (int)Pico_mcd->word_ram2M - 0x200000; // Program Counter in Word Ram
|
||||||
if (pc < 0x220000) {
|
if (pc < 0x220000) {
|
||||||
int bank = (Pico_mcd->s68k_regs[3]&1);
|
int bank = Pico_mcd->s68k_regs[3]&1;
|
||||||
return (int)Pico_mcd->word_ram1M[bank] - 0x200000;
|
return (int)Pico_mcd->word_ram1M[bank] - 0x200000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1415,12 +1411,12 @@ static __inline int PicoMemBaseM68k(u32 pc)
|
||||||
|
|
||||||
static u32 PicoCheckPcM68k(u32 pc)
|
static u32 PicoCheckPcM68k(u32 pc)
|
||||||
{
|
{
|
||||||
pc-=PicoCpu.membase; // Get real pc
|
pc-=PicoCpuCM68k.membase; // Get real pc
|
||||||
pc&=0xfffffe;
|
pc&=0xfffffe;
|
||||||
|
|
||||||
PicoCpu.membase=PicoMemBaseM68k(pc);
|
PicoCpuCM68k.membase=PicoMemBaseM68k(pc);
|
||||||
|
|
||||||
return PicoCpu.membase+pc;
|
return PicoCpuCM68k.membase+pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1433,7 +1429,7 @@ static __inline int PicoMemBaseS68k(u32 pc)
|
||||||
return (int)Pico_mcd->word_ram2M - 0x080000;
|
return (int)Pico_mcd->word_ram2M - 0x080000;
|
||||||
|
|
||||||
if ((pc&0xfe0000)==0x0c0000) { // word RAM 1M area
|
if ((pc&0xfe0000)==0x0c0000) { // word RAM 1M area
|
||||||
int bank = !(Pico_mcd->s68k_regs[3]&1);
|
int bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
return (int)Pico_mcd->word_ram1M[bank] - 0x0c0000;
|
return (int)Pico_mcd->word_ram1M[bank] - 0x0c0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1446,37 +1442,101 @@ static __inline int PicoMemBaseS68k(u32 pc)
|
||||||
|
|
||||||
static u32 PicoCheckPcS68k(u32 pc)
|
static u32 PicoCheckPcS68k(u32 pc)
|
||||||
{
|
{
|
||||||
pc-=PicoCpuS68k.membase; // Get real pc
|
pc-=PicoCpuCS68k.membase; // Get real pc
|
||||||
pc&=0xfffffe;
|
pc&=0xfffffe;
|
||||||
|
|
||||||
PicoCpuS68k.membase=PicoMemBaseS68k(pc);
|
PicoCpuCS68k.membase=PicoMemBaseS68k(pc);
|
||||||
|
|
||||||
return PicoCpuS68k.membase+pc;
|
return PicoCpuCS68k.membase+pc;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _ASM_CD_MEMORY_C
|
||||||
|
void PicoMemResetCD(int r3)
|
||||||
|
{
|
||||||
|
#ifdef EMU_F68K
|
||||||
|
// update fetchmap..
|
||||||
|
int i;
|
||||||
|
if (!(r3 & 4))
|
||||||
|
{
|
||||||
|
for (i = M68K_FETCHBANK1*2/16; (i<<(24-FAMEC_FETCHBITS)) < 0x240000; i++)
|
||||||
|
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico_mcd->word_ram2M - 0x200000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = M68K_FETCHBANK1*2/16; (i<<(24-FAMEC_FETCHBITS)) < 0x220000; i++)
|
||||||
|
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico_mcd->word_ram1M[r3 & 1] - 0x200000;
|
||||||
|
for (i = M68K_FETCHBANK1*0x0c/0x100; (i<<(24-FAMEC_FETCHBITS)) < 0x0e0000; i++)
|
||||||
|
PicoCpuFS68k.Fetch[i] = (unsigned int)Pico_mcd->word_ram1M[(r3&1)^1] - 0x0c0000;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
PICO_INTERNAL void PicoMemSetupCD(void)
|
PICO_INTERNAL void PicoMemSetupCD(void)
|
||||||
{
|
{
|
||||||
dprintf("PicoMemSetupCD()");
|
dprintf("PicoMemSetupCD()");
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
// Setup m68k memory callbacks:
|
// Setup m68k memory callbacks:
|
||||||
PicoCpu.checkpc=PicoCheckPcM68k;
|
PicoCpuCM68k.checkpc=PicoCheckPcM68k;
|
||||||
PicoCpu.fetch8 =PicoCpu.read8 =PicoReadM68k8;
|
PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoReadM68k8;
|
||||||
PicoCpu.fetch16=PicoCpu.read16=PicoReadM68k16;
|
PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoReadM68k16;
|
||||||
PicoCpu.fetch32=PicoCpu.read32=PicoReadM68k32;
|
PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoReadM68k32;
|
||||||
PicoCpu.write8 =PicoWriteM68k8;
|
PicoCpuCM68k.write8 =PicoWriteM68k8;
|
||||||
PicoCpu.write16=PicoWriteM68k16;
|
PicoCpuCM68k.write16=PicoWriteM68k16;
|
||||||
PicoCpu.write32=PicoWriteM68k32;
|
PicoCpuCM68k.write32=PicoWriteM68k32;
|
||||||
// s68k
|
// s68k
|
||||||
PicoCpuS68k.checkpc=PicoCheckPcS68k;
|
PicoCpuCS68k.checkpc=PicoCheckPcS68k;
|
||||||
PicoCpuS68k.fetch8 =PicoCpuS68k.read8 =PicoReadS68k8;
|
PicoCpuCS68k.fetch8 =PicoCpuCS68k.read8 =PicoReadS68k8;
|
||||||
PicoCpuS68k.fetch16=PicoCpuS68k.read16=PicoReadS68k16;
|
PicoCpuCS68k.fetch16=PicoCpuCS68k.read16=PicoReadS68k16;
|
||||||
PicoCpuS68k.fetch32=PicoCpuS68k.read32=PicoReadS68k32;
|
PicoCpuCS68k.fetch32=PicoCpuCS68k.read32=PicoReadS68k32;
|
||||||
PicoCpuS68k.write8 =PicoWriteS68k8;
|
PicoCpuCS68k.write8 =PicoWriteS68k8;
|
||||||
PicoCpuS68k.write16=PicoWriteS68k16;
|
PicoCpuCS68k.write16=PicoWriteS68k16;
|
||||||
PicoCpuS68k.write32=PicoWriteS68k32;
|
PicoCpuCS68k.write32=PicoWriteS68k32;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef EMU_F68K
|
||||||
|
// m68k
|
||||||
|
PicoCpuFM68k.read_byte =PicoReadM68k8;
|
||||||
|
PicoCpuFM68k.read_word =PicoReadM68k16;
|
||||||
|
PicoCpuFM68k.read_long =PicoReadM68k32;
|
||||||
|
PicoCpuFM68k.write_byte=PicoWriteM68k8;
|
||||||
|
PicoCpuFM68k.write_word=PicoWriteM68k16;
|
||||||
|
PicoCpuFM68k.write_long=PicoWriteM68k32;
|
||||||
|
// s68k
|
||||||
|
PicoCpuFS68k.read_byte =PicoReadS68k8;
|
||||||
|
PicoCpuFS68k.read_word =PicoReadS68k16;
|
||||||
|
PicoCpuFS68k.read_long =PicoReadS68k32;
|
||||||
|
PicoCpuFS68k.write_byte=PicoWriteS68k8;
|
||||||
|
PicoCpuFS68k.write_word=PicoWriteS68k16;
|
||||||
|
PicoCpuFS68k.write_long=PicoWriteS68k32;
|
||||||
|
|
||||||
|
// setup FAME fetchmap
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
// M68k
|
||||||
|
// by default, point everything to fitst 64k of ROM (BIOS)
|
||||||
|
for (i = 0; i < M68K_FETCHBANK1; i++)
|
||||||
|
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom - (i<<(24-FAMEC_FETCHBITS));
|
||||||
|
// now real ROM (BIOS)
|
||||||
|
for (i = 0; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < Pico.romsize; i++)
|
||||||
|
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom;
|
||||||
|
// .. and RAM
|
||||||
|
for (i = M68K_FETCHBANK1*14/16; i < M68K_FETCHBANK1; i++)
|
||||||
|
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.ram - (i<<(24-FAMEC_FETCHBITS));
|
||||||
|
// S68k
|
||||||
|
// PRG RAM is default
|
||||||
|
for (i = 0; i < M68K_FETCHBANK1; i++)
|
||||||
|
PicoCpuFS68k.Fetch[i] = (unsigned int)Pico_mcd->prg_ram - (i<<(24-FAMEC_FETCHBITS));
|
||||||
|
// real PRG RAM
|
||||||
|
for (i = 0; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < 0x80000; i++)
|
||||||
|
PicoCpuFS68k.Fetch[i] = (unsigned int)Pico_mcd->prg_ram;
|
||||||
|
// WORD RAM 2M area
|
||||||
|
for (i = M68K_FETCHBANK1*0x08/0x100; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < 0xc0000; i++)
|
||||||
|
PicoCpuFS68k.Fetch[i] = (unsigned int)Pico_mcd->word_ram2M - 0x80000;
|
||||||
|
// PicoMemResetCD() will setup word ram for both
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// m68k_poll_addr = m68k_poll_cnt = 0;
|
// m68k_poll_addr = m68k_poll_cnt = 0;
|
||||||
s68k_poll_adclk = s68k_poll_cnt = 0;
|
s68k_poll_adclk = s68k_poll_cnt = 0;
|
||||||
}
|
}
|
||||||
|
@ -1484,33 +1544,33 @@ PICO_INTERNAL void PicoMemSetupCD(void)
|
||||||
|
|
||||||
#ifdef EMU_M68K
|
#ifdef EMU_M68K
|
||||||
unsigned char PicoReadCD8w (unsigned int a) {
|
unsigned char PicoReadCD8w (unsigned int a) {
|
||||||
return m68ki_cpu_p == &PicoS68kCPU ? PicoReadS68k8(a) : PicoReadM68k8(a);
|
return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k8(a) : PicoReadM68k8(a);
|
||||||
}
|
}
|
||||||
unsigned short PicoReadCD16w(unsigned int a) {
|
unsigned short PicoReadCD16w(unsigned int a) {
|
||||||
return m68ki_cpu_p == &PicoS68kCPU ? PicoReadS68k16(a) : PicoReadM68k16(a);
|
return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k16(a) : PicoReadM68k16(a);
|
||||||
}
|
}
|
||||||
unsigned int PicoReadCD32w(unsigned int a) {
|
unsigned int PicoReadCD32w(unsigned int a) {
|
||||||
return m68ki_cpu_p == &PicoS68kCPU ? PicoReadS68k32(a) : PicoReadM68k32(a);
|
return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k32(a) : PicoReadM68k32(a);
|
||||||
}
|
}
|
||||||
void PicoWriteCD8w (unsigned int a, unsigned char d) {
|
void PicoWriteCD8w (unsigned int a, unsigned char d) {
|
||||||
if (m68ki_cpu_p == &PicoS68kCPU) PicoWriteS68k8(a, d); else PicoWriteM68k8(a, d);
|
if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k8(a, d); else PicoWriteM68k8(a, d);
|
||||||
}
|
}
|
||||||
void PicoWriteCD16w(unsigned int a, unsigned short d) {
|
void PicoWriteCD16w(unsigned int a, unsigned short d) {
|
||||||
if (m68ki_cpu_p == &PicoS68kCPU) PicoWriteS68k16(a, d); else PicoWriteM68k16(a, d);
|
if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k16(a, d); else PicoWriteM68k16(a, d);
|
||||||
}
|
}
|
||||||
void PicoWriteCD32w(unsigned int a, unsigned int d) {
|
void PicoWriteCD32w(unsigned int a, unsigned int d) {
|
||||||
if (m68ki_cpu_p == &PicoS68kCPU) PicoWriteS68k32(a, d); else PicoWriteM68k32(a, d);
|
if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k32(a, d); else PicoWriteM68k32(a, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are allowed to access RAM
|
// these are allowed to access RAM
|
||||||
unsigned int m68k_read_pcrelative_CD8 (unsigned int a) {
|
unsigned int m68k_read_pcrelative_CD8 (unsigned int a) {
|
||||||
a&=0xffffff;
|
a&=0xffffff;
|
||||||
if(m68ki_cpu_p == &PicoS68kCPU) {
|
if(m68ki_cpu_p == &PicoCpuMS68k) {
|
||||||
if (a < 0x80000) return *(u8 *)(Pico_mcd->prg_ram+(a^1)); // PRG Ram
|
if (a < 0x80000) return *(u8 *)(Pico_mcd->prg_ram+(a^1)); // PRG Ram
|
||||||
if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)
|
if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)
|
||||||
return *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff));
|
return *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff));
|
||||||
if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)
|
if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)
|
||||||
int bank = !(Pico_mcd->s68k_regs[3]&1);
|
int bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
return *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff));
|
return *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff));
|
||||||
}
|
}
|
||||||
dprintf("s68k_read_pcrelative_CD8 FIXME: can't handle %06x", a);
|
dprintf("s68k_read_pcrelative_CD8 FIXME: can't handle %06x", a);
|
||||||
|
@ -1531,12 +1591,12 @@ unsigned int m68k_read_pcrelative_CD8 (unsigned int a) {
|
||||||
}
|
}
|
||||||
unsigned int m68k_read_pcrelative_CD16(unsigned int a) {
|
unsigned int m68k_read_pcrelative_CD16(unsigned int a) {
|
||||||
a&=0xffffff;
|
a&=0xffffff;
|
||||||
if(m68ki_cpu_p == &PicoS68kCPU) {
|
if(m68ki_cpu_p == &PicoCpuMS68k) {
|
||||||
if (a < 0x80000) return *(u16 *)(Pico_mcd->prg_ram+(a&~1)); // PRG Ram
|
if (a < 0x80000) return *(u16 *)(Pico_mcd->prg_ram+(a&~1)); // PRG Ram
|
||||||
if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)
|
if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)
|
||||||
return *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));
|
return *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));
|
||||||
if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)
|
if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)
|
||||||
int bank = !(Pico_mcd->s68k_regs[3]&1);
|
int bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
return *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));
|
return *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));
|
||||||
}
|
}
|
||||||
dprintf("s68k_read_pcrelative_CD16 FIXME: can't handle %06x", a);
|
dprintf("s68k_read_pcrelative_CD16 FIXME: can't handle %06x", a);
|
||||||
|
@ -1558,12 +1618,12 @@ unsigned int m68k_read_pcrelative_CD16(unsigned int a) {
|
||||||
unsigned int m68k_read_pcrelative_CD32(unsigned int a) {
|
unsigned int m68k_read_pcrelative_CD32(unsigned int a) {
|
||||||
u16 *pm;
|
u16 *pm;
|
||||||
a&=0xffffff;
|
a&=0xffffff;
|
||||||
if(m68ki_cpu_p == &PicoS68kCPU) {
|
if(m68ki_cpu_p == &PicoCpuMS68k) {
|
||||||
if (a < 0x80000) { u16 *pm=(u16 *)(Pico_mcd->prg_ram+(a&~1)); return (pm[0]<<16)|pm[1]; } // PRG Ram
|
if (a < 0x80000) { u16 *pm=(u16 *)(Pico_mcd->prg_ram+(a&~1)); return (pm[0]<<16)|pm[1]; } // PRG Ram
|
||||||
if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)
|
if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)
|
||||||
{ pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); return (pm[0]<<16)|pm[1]; }
|
{ pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); return (pm[0]<<16)|pm[1]; }
|
||||||
if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)
|
if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)
|
||||||
int bank = !(Pico_mcd->s68k_regs[3]&1);
|
int bank = (Pico_mcd->s68k_regs[3]&1)^1;
|
||||||
pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));
|
pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));
|
||||||
return (pm[0]<<16)|pm[1];
|
return (pm[0]<<16)|pm[1];
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ m_s68k_decode_write_table:
|
||||||
.extern gfx_cd_write16
|
.extern gfx_cd_write16
|
||||||
.extern s68k_reg_write8
|
.extern s68k_reg_write8
|
||||||
.extern s68k_poll_adclk
|
.extern s68k_poll_adclk
|
||||||
.extern PicoCpuS68k
|
.extern PicoCpuMS68k
|
||||||
.extern s68k_poll_detect
|
.extern s68k_poll_detect
|
||||||
.extern SN76496Write
|
.extern SN76496Write
|
||||||
.extern m_m68k_read8_misc
|
.extern m_m68k_read8_misc
|
||||||
|
@ -1259,7 +1259,7 @@ m_m68k_write16_regs_spec: @ special case
|
||||||
and r2, r2, #0xfe
|
and r2, r2, #0xfe
|
||||||
cmp r2, #0x0e
|
cmp r2, #0x0e
|
||||||
bxne lr
|
bxne lr
|
||||||
ldr r0, =PicoCpuS68k
|
ldr r0, =PicoCpuCS68k
|
||||||
str r1, [r0, #0x58] @ push s68k out of stopped state
|
str r1, [r0, #0x58] @ push s68k out of stopped state
|
||||||
str r1, [r3]
|
str r1, [r3]
|
||||||
bx lr
|
bx lr
|
||||||
|
@ -1450,7 +1450,7 @@ m_m68k_write32_regs_comm: @ Handle the 0x10-0x1f range
|
||||||
strneh r1, [r2, #2]
|
strneh r1, [r2, #2]
|
||||||
cmp r0, #0x10
|
cmp r0, #0x10
|
||||||
bxlt lr
|
bxlt lr
|
||||||
ldr r0, =PicoCpuS68k @ remove poll detected state for s68k
|
ldr r0, =PicoCpuCS68k @ remove poll detected state for s68k
|
||||||
mov r1, #0
|
mov r1, #0
|
||||||
str r1, [r0, #0x58]
|
str r1, [r0, #0x58]
|
||||||
str r1, [r3]
|
str r1, [r3]
|
||||||
|
|
|
@ -69,8 +69,8 @@ PICO_INTERNAL int PicoResetMCD(int hard)
|
||||||
Reset_CD();
|
Reset_CD();
|
||||||
LC89510_Reset();
|
LC89510_Reset();
|
||||||
gfx_cd_reset();
|
gfx_cd_reset();
|
||||||
#ifdef _ASM_CD_MEMORY_C
|
|
||||||
PicoMemResetCD(1);
|
PicoMemResetCD(1);
|
||||||
|
#ifdef _ASM_CD_MEMORY_C
|
||||||
//PicoMemResetCDdecode(1); // don't have to call this in 2M mode
|
//PicoMemResetCDdecode(1); // don't have to call this in 2M mode
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -89,12 +89,15 @@ static __inline void SekRunM68k(int cyc)
|
||||||
SekCycleAim+=cyc;
|
SekCycleAim+=cyc;
|
||||||
if((cyc_do=SekCycleAim-SekCycleCnt) < 0) return;
|
if((cyc_do=SekCycleAim-SekCycleCnt) < 0) return;
|
||||||
#if defined(EMU_C68K)
|
#if defined(EMU_C68K)
|
||||||
PicoCpu.cycles=cyc_do;
|
PicoCpuCM68k.cycles=cyc_do;
|
||||||
CycloneRun(&PicoCpu);
|
CycloneRun(&PicoCpuCM68k);
|
||||||
SekCycleCnt+=cyc_do-PicoCpu.cycles;
|
SekCycleCnt+=cyc_do-PicoCpuCM68k.cycles;
|
||||||
#elif defined(EMU_M68K)
|
#elif defined(EMU_M68K)
|
||||||
m68k_set_context(&PicoM68kCPU);
|
m68k_set_context(&PicoCpuMM68k);
|
||||||
SekCycleCnt+=m68k_execute(cyc_do);
|
SekCycleCnt+=m68k_execute(cyc_do);
|
||||||
|
#elif defined(EMU_F68K)
|
||||||
|
g_m68kcontext=&PicoCpuFM68k;
|
||||||
|
SekCycleCnt+=m68k_emulate(cyc_do);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,12 +107,15 @@ static __inline void SekRunS68k(int cyc)
|
||||||
SekCycleAimS68k+=cyc;
|
SekCycleAimS68k+=cyc;
|
||||||
if((cyc_do=SekCycleAimS68k-SekCycleCntS68k) < 0) return;
|
if((cyc_do=SekCycleAimS68k-SekCycleCntS68k) < 0) return;
|
||||||
#if defined(EMU_C68K)
|
#if defined(EMU_C68K)
|
||||||
PicoCpuS68k.cycles=cyc_do;
|
PicoCpuCS68k.cycles=cyc_do;
|
||||||
CycloneRun(&PicoCpuS68k);
|
CycloneRun(&PicoCpuCS68k);
|
||||||
SekCycleCntS68k+=cyc_do-PicoCpuS68k.cycles;
|
SekCycleCntS68k+=cyc_do-PicoCpuCS68k.cycles;
|
||||||
#elif defined(EMU_M68K)
|
#elif defined(EMU_M68K)
|
||||||
m68k_set_context(&PicoS68kCPU);
|
m68k_set_context(&PicoCpuMS68k);
|
||||||
SekCycleCntS68k+=m68k_execute(cyc_do);
|
SekCycleCntS68k+=m68k_execute(cyc_do);
|
||||||
|
#elif defined(EMU_F68K)
|
||||||
|
g_m68kcontext=&PicoCpuFS68k;
|
||||||
|
SekCycleCntS68k+=m68k_emulate(cyc_do);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +128,6 @@ void SekRunPS(int cyc_m68k, int cyc_s68k);
|
||||||
static __inline void SekRunPS(int cyc_m68k, int cyc_s68k)
|
static __inline void SekRunPS(int cyc_m68k, int cyc_s68k)
|
||||||
{
|
{
|
||||||
int cycn, cycn_s68k, cyc_do;
|
int cycn, cycn_s68k, cyc_do;
|
||||||
int ex;
|
|
||||||
SekCycleAim+=cyc_m68k;
|
SekCycleAim+=cyc_m68k;
|
||||||
SekCycleAimS68k+=cyc_s68k;
|
SekCycleAimS68k+=cyc_s68k;
|
||||||
|
|
||||||
|
@ -132,26 +137,31 @@ static __inline void SekRunPS(int cyc_m68k, int cyc_s68k)
|
||||||
/* loop 488 downto 0 in steps of PS_STEP */
|
/* loop 488 downto 0 in steps of PS_STEP */
|
||||||
for (cycn = (488<<16)-PS_STEP_M68K; cycn >= 0; cycn -= PS_STEP_M68K)
|
for (cycn = (488<<16)-PS_STEP_M68K; cycn >= 0; cycn -= PS_STEP_M68K)
|
||||||
{
|
{
|
||||||
ex = 0;
|
|
||||||
cycn_s68k = (cycn + cycn/2 + cycn/8) >> 16;
|
cycn_s68k = (cycn + cycn/2 + cycn/8) >> 16;
|
||||||
if ((cyc_do = SekCycleAim-SekCycleCnt-(cycn>>16)) > 0) {
|
if ((cyc_do = SekCycleAim-SekCycleCnt-(cycn>>16)) > 0) {
|
||||||
#if defined(EMU_C68K)
|
#if defined(EMU_C68K)
|
||||||
PicoCpu.cycles = cyc_do;
|
PicoCpuCM68k.cycles = cyc_do;
|
||||||
CycloneRun(&PicoCpu);
|
CycloneRun(&PicoCpuCM68k);
|
||||||
SekCycleCnt += cyc_do - PicoCpu.cycles;
|
SekCycleCnt += cyc_do - PicoCpuCM68k.cycles;
|
||||||
#elif defined(EMU_M68K)
|
#elif defined(EMU_M68K)
|
||||||
m68k_set_context(&PicoM68kCPU);
|
m68k_set_context(&PicoCpuMM68k);
|
||||||
SekCycleCnt += (ex = m68k_execute(cyc_do));
|
SekCycleCnt += m68k_execute(cyc_do);
|
||||||
|
#elif defined(EMU_F68K)
|
||||||
|
g_m68kcontext = &PicoCpuFM68k;
|
||||||
|
SekCycleCnt += m68k_emulate(cyc_do);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if ((cyc_do = SekCycleAimS68k-SekCycleCntS68k-cycn_s68k) > 0) {
|
if ((cyc_do = SekCycleAimS68k-SekCycleCntS68k-cycn_s68k) > 0) {
|
||||||
#if defined(EMU_C68K)
|
#if defined(EMU_C68K)
|
||||||
PicoCpuS68k.cycles = cyc_do;
|
PicoCpuCS68k.cycles = cyc_do;
|
||||||
CycloneRun(&PicoCpuS68k);
|
CycloneRun(&PicoCpuCS68k);
|
||||||
SekCycleCntS68k += cyc_do - PicoCpuS68k.cycles;
|
SekCycleCntS68k += cyc_do - PicoCpuCS68k.cycles;
|
||||||
#elif defined(EMU_M68K)
|
#elif defined(EMU_M68K)
|
||||||
m68k_set_context(&PicoS68kCPU);
|
m68k_set_context(&PicoCpuMS68k);
|
||||||
SekCycleCntS68k += (ex = m68k_execute(cyc_do));
|
SekCycleCntS68k += m68k_execute(cyc_do);
|
||||||
|
#elif defined(EMU_F68K)
|
||||||
|
g_m68kcontext = &PicoCpuFS68k;
|
||||||
|
SekCycleCntS68k += m68k_emulate(cyc_do);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@ vim:filetype=armasm
|
@ vim:filetype=armasm
|
||||||
|
|
||||||
@ SekRunPS runs PicoCpu and PicoCpuS68k interleaved in steps of PS_STEP_M68K
|
@ SekRunPS runs PicoCpuCM68k and PicoCpuCS68k interleaved in steps of PS_STEP_M68K
|
||||||
@ cycles. This is done without calling CycloneRun and jumping directly to
|
@ cycles. This is done without calling CycloneRun and jumping directly to
|
||||||
@ Cyclone code to avoid pushing/popping all the registers every time.
|
@ Cyclone code to avoid pushing/popping all the registers every time.
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@
|
||||||
@ .extern is ignored by gas, we add these here just to see what we depend on.
|
@ .extern is ignored by gas, we add these here just to see what we depend on.
|
||||||
.extern CycloneJumpTab
|
.extern CycloneJumpTab
|
||||||
.extern CycloneDoInterrupt
|
.extern CycloneDoInterrupt
|
||||||
.extern PicoCpu
|
.extern PicoCpuCM68k
|
||||||
.extern PicoCpuS68k
|
.extern PicoCpuCS68k
|
||||||
.extern SekCycleAim
|
.extern SekCycleAim
|
||||||
.extern SekCycleCnt
|
.extern SekCycleCnt
|
||||||
.extern SekCycleAimS68k
|
.extern SekCycleAimS68k
|
||||||
|
@ -32,8 +32,8 @@ SekRunPS:
|
||||||
sub sp, sp, #2*4 @ sp[0] = main_cycle_cnt, sp[4] = run_cycle_cnt
|
sub sp, sp, #2*4 @ sp[0] = main_cycle_cnt, sp[4] = run_cycle_cnt
|
||||||
|
|
||||||
@ override CycloneEnd for both contexts
|
@ override CycloneEnd for both contexts
|
||||||
ldr r7, =PicoCpu
|
ldr r7, =PicoCpuCM68k
|
||||||
ldr lr, =PicoCpuS68k
|
ldr lr, =PicoCpuCS68k
|
||||||
ldr r2, =CycloneEnd_M68k
|
ldr r2, =CycloneEnd_M68k
|
||||||
ldr r3, =CycloneEnd_S68k
|
ldr r3, =CycloneEnd_S68k
|
||||||
str r2, [r7,#0x98]
|
str r2, [r7,#0x98]
|
||||||
|
@ -90,7 +90,7 @@ schedule_s68k:
|
||||||
subs r5, r0, r3, asr #16
|
subs r5, r0, r3, asr #16
|
||||||
ble schedule_m68k @ s68k has not enough cycles
|
ble schedule_m68k @ s68k has not enough cycles
|
||||||
|
|
||||||
ldr r7, =PicoCpuS68k
|
ldr r7, =PicoCpuCS68k
|
||||||
str r5, [sp,#4] @ run_cycle_cnt
|
str r5, [sp,#4] @ run_cycle_cnt
|
||||||
b CycloneRunLocal
|
b CycloneRunLocal
|
||||||
|
|
||||||
|
@ -122,15 +122,15 @@ schedule_m68k:
|
||||||
subs r5, r0, r3, asr #16
|
subs r5, r0, r3, asr #16
|
||||||
ble schedule_s68k @ m68k has not enough cycles
|
ble schedule_s68k @ m68k has not enough cycles
|
||||||
|
|
||||||
ldr r7, =PicoCpu
|
ldr r7, =PicoCpuCM68k
|
||||||
str r5, [sp,#4] @ run_cycle_cnt
|
str r5, [sp,#4] @ run_cycle_cnt
|
||||||
b CycloneRunLocal
|
b CycloneRunLocal
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SekRunPS_end:
|
SekRunPS_end:
|
||||||
ldr r7, =PicoCpu
|
ldr r7, =PicoCpuCM68k
|
||||||
ldr lr, =PicoCpuS68k
|
ldr lr, =PicoCpuCS68k
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
str r0, [r7,#0x98] @ remove CycloneEnd handler
|
str r0, [r7,#0x98] @ remove CycloneEnd handler
|
||||||
str r0, [lr,#0x98]
|
str r0, [lr,#0x98]
|
||||||
|
|
109
Pico/cd/Sek.c
109
Pico/cd/Sek.c
|
@ -7,15 +7,21 @@
|
||||||
int SekCycleCntS68k=0; // cycles done in this frame
|
int SekCycleCntS68k=0; // cycles done in this frame
|
||||||
int SekCycleAimS68k=0; // cycle aim
|
int SekCycleAimS68k=0; // cycle aim
|
||||||
|
|
||||||
|
|
||||||
|
/* context */
|
||||||
|
// Cyclone 68000
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
// ---------------------- Cyclone 68000 ----------------------
|
struct Cyclone PicoCpuCS68k;
|
||||||
struct Cyclone PicoCpuS68k;
|
#endif
|
||||||
|
// MUSASHI 68000
|
||||||
|
#ifdef EMU_M68K
|
||||||
|
m68ki_cpu_core PicoCpuMS68k;
|
||||||
|
#endif
|
||||||
|
// FAME 68000
|
||||||
|
#ifdef EMU_F68K
|
||||||
|
M68K_CONTEXT PicoCpuFS68k;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EMU_M68K
|
|
||||||
// ---------------------- MUSASHI 68000 ----------------------
|
|
||||||
m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int new_irq_level(int level)
|
static int new_irq_level(int level)
|
||||||
{
|
{
|
||||||
|
@ -28,16 +34,6 @@ static int new_irq_level(int level)
|
||||||
return level_new;
|
return level_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EMU_M68K
|
|
||||||
static int SekIntAckS68kM(int level)
|
|
||||||
{
|
|
||||||
int level_new = new_irq_level(level);
|
|
||||||
dprintf("s68kACK %i -> %i", level, level_new);
|
|
||||||
CPU_INT_LEVEL = level_new << 8;
|
|
||||||
return M68K_INT_ACK_AUTOVECTOR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
// interrupt acknowledgement
|
// interrupt acknowledgement
|
||||||
static int SekIntAckS68k(int level)
|
static int SekIntAckS68k(int level)
|
||||||
|
@ -45,7 +41,7 @@ static int SekIntAckS68k(int level)
|
||||||
int level_new = new_irq_level(level);
|
int level_new = new_irq_level(level);
|
||||||
|
|
||||||
dprintf("s68kACK %i -> %i", level, level_new);
|
dprintf("s68kACK %i -> %i", level, level_new);
|
||||||
PicoCpuS68k.irq = level_new;
|
PicoCpuCS68k.irq = level_new;
|
||||||
return CYCLONE_INT_ACK_AUTOVECTOR;
|
return CYCLONE_INT_ACK_AUTOVECTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,36 +54,64 @@ static int SekUnrecognizedOpcodeS68k(void)
|
||||||
{
|
{
|
||||||
unsigned int pc, op;
|
unsigned int pc, op;
|
||||||
pc = SekPcS68k;
|
pc = SekPcS68k;
|
||||||
op = PicoCpuS68k.read16(pc);
|
op = PicoCpuCS68k.read16(pc);
|
||||||
dprintf("Unrecognized Opcode %04x @ %06x", op, pc);
|
dprintf("Unrecognized Opcode %04x @ %06x", op, pc);
|
||||||
//exit(1);
|
//exit(1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef EMU_M68K
|
||||||
|
static int SekIntAckMS68k(int level)
|
||||||
|
{
|
||||||
|
int level_new = new_irq_level(level);
|
||||||
|
dprintf("s68kACK %i -> %i", level, level_new);
|
||||||
|
CPU_INT_LEVEL = level_new << 8;
|
||||||
|
return M68K_INT_ACK_AUTOVECTOR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EMU_F68K
|
||||||
|
static void SekIntAckFS68k(unsigned level)
|
||||||
|
{
|
||||||
|
int level_new = new_irq_level(level);
|
||||||
|
dprintf("s68kACK %i -> %i", level, level_new);
|
||||||
|
PicoCpuFS68k.interrupts[0] = level_new;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
PICO_INTERNAL int SekInitS68k()
|
PICO_INTERNAL int SekInitS68k()
|
||||||
{
|
{
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
// CycloneInit();
|
// CycloneInit();
|
||||||
memset(&PicoCpuS68k,0,sizeof(PicoCpuS68k));
|
memset(&PicoCpuCS68k,0,sizeof(PicoCpuCS68k));
|
||||||
PicoCpuS68k.IrqCallback=SekIntAckS68k;
|
PicoCpuCS68k.IrqCallback=SekIntAckS68k;
|
||||||
PicoCpuS68k.ResetCallback=SekResetAckS68k;
|
PicoCpuCS68k.ResetCallback=SekResetAckS68k;
|
||||||
PicoCpuS68k.UnrecognizedCallback=SekUnrecognizedOpcodeS68k;
|
PicoCpuCS68k.UnrecognizedCallback=SekUnrecognizedOpcodeS68k;
|
||||||
#endif
|
#endif
|
||||||
#ifdef EMU_M68K
|
#ifdef EMU_M68K
|
||||||
{
|
{
|
||||||
// Musashi is not very context friendly..
|
// Musashi is not very context friendly..
|
||||||
void *oldcontext = m68ki_cpu_p;
|
void *oldcontext = m68ki_cpu_p;
|
||||||
m68k_set_context(&PicoS68kCPU);
|
m68k_set_context(&PicoCpuMS68k);
|
||||||
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
|
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
|
||||||
m68k_init();
|
m68k_init();
|
||||||
m68k_set_int_ack_callback(SekIntAckS68kM);
|
m68k_set_int_ack_callback(SekIntAckMS68k);
|
||||||
// m68k_pulse_reset(); // not yet, memmap is not set up
|
// m68k_pulse_reset(); // not yet, memmap is not set up
|
||||||
m68k_set_context(oldcontext);
|
m68k_set_context(oldcontext);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef EMU_F68K
|
||||||
|
{
|
||||||
|
void *oldcontext = g_m68kcontext;
|
||||||
|
g_m68kcontext = &PicoCpuFS68k;
|
||||||
|
memset(&PicoCpuFS68k, 0, sizeof(PicoCpuFS68k));
|
||||||
|
m68k_init();
|
||||||
|
PicoCpuFS68k.iack_handler = SekIntAckFS68k;
|
||||||
|
g_m68kcontext = oldcontext;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -98,26 +122,34 @@ PICO_INTERNAL int SekResetS68k()
|
||||||
if (Pico.rom==NULL) return 1;
|
if (Pico.rom==NULL) return 1;
|
||||||
|
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
PicoCpuS68k.state_flags=0;
|
PicoCpuCS68k.state_flags=0;
|
||||||
PicoCpuS68k.osp=0;
|
PicoCpuCS68k.osp=0;
|
||||||
PicoCpuS68k.srh =0x27; // Supervisor mode
|
PicoCpuCS68k.srh =0x27; // Supervisor mode
|
||||||
PicoCpuS68k.flags=4; // Z set
|
PicoCpuCS68k.flags=4; // Z set
|
||||||
PicoCpuS68k.irq=0;
|
PicoCpuCS68k.irq=0;
|
||||||
PicoCpuS68k.a[7]=PicoCpuS68k.read32(0); // Stack Pointer
|
PicoCpuCS68k.a[7]=PicoCpuCS68k.read32(0); // Stack Pointer
|
||||||
PicoCpuS68k.membase=0;
|
PicoCpuCS68k.membase=0;
|
||||||
PicoCpuS68k.pc=PicoCpuS68k.checkpc(PicoCpuS68k.read32(4)); // Program Counter
|
PicoCpuCS68k.pc=PicoCpuCS68k.checkpc(PicoCpuCS68k.read32(4)); // Program Counter
|
||||||
#endif
|
#endif
|
||||||
#ifdef EMU_M68K
|
#ifdef EMU_M68K
|
||||||
{
|
{
|
||||||
void *oldcontext = m68ki_cpu_p;
|
void *oldcontext = m68ki_cpu_p;
|
||||||
|
|
||||||
m68k_set_context(&PicoS68kCPU);
|
m68k_set_context(&PicoCpuMS68k);
|
||||||
m68ki_cpu.sp[0]=0;
|
m68ki_cpu.sp[0]=0;
|
||||||
m68k_set_irq(0);
|
m68k_set_irq(0);
|
||||||
m68k_pulse_reset();
|
m68k_pulse_reset();
|
||||||
m68k_set_context(oldcontext);
|
m68k_set_context(oldcontext);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef EMU_F68K
|
||||||
|
{
|
||||||
|
void *oldcontext = g_m68kcontext;
|
||||||
|
g_m68kcontext = &PicoCpuFS68k;
|
||||||
|
m68k_reset();
|
||||||
|
g_m68kcontext = oldcontext;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -127,16 +159,19 @@ PICO_INTERNAL int SekInterruptS68k(int irq)
|
||||||
int irqs, real_irq = 1;
|
int irqs, real_irq = 1;
|
||||||
Pico_mcd->m.s68k_pend_ints |= 1 << irq;
|
Pico_mcd->m.s68k_pend_ints |= 1 << irq;
|
||||||
irqs = Pico_mcd->m.s68k_pend_ints >> 1;
|
irqs = Pico_mcd->m.s68k_pend_ints >> 1;
|
||||||
while ((irqs >>= 1)) real_irq++; // this is probably only needed for Cyclone
|
while ((irqs >>= 1)) real_irq++;
|
||||||
|
|
||||||
#ifdef EMU_C68K
|
#ifdef EMU_C68K
|
||||||
PicoCpuS68k.irq=real_irq;
|
PicoCpuCS68k.irq=real_irq;
|
||||||
#endif
|
#endif
|
||||||
#ifdef EMU_M68K
|
#ifdef EMU_M68K
|
||||||
void *oldcontext = m68ki_cpu_p;
|
void *oldcontext = m68ki_cpu_p;
|
||||||
m68k_set_context(&PicoS68kCPU);
|
m68k_set_context(&PicoCpuMS68k);
|
||||||
m68k_set_irq(real_irq); // raise irq (gets lowered after taken or must be done in ack)
|
m68k_set_irq(real_irq);
|
||||||
m68k_set_context(oldcontext);
|
m68k_set_context(oldcontext);
|
||||||
|
#endif
|
||||||
|
#ifdef EMU_F68K
|
||||||
|
PicoCpuFS68k.interrupts[0]=real_irq;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
all : a68k.obj
|
|
||||||
|
|
||||||
a68k.obj :
|
|
||||||
cl /DWIN32 /DFASTCALL make68kd.c
|
|
||||||
make68kd a68k.asm a68k_jmp.asm 00
|
|
||||||
nasm -f win32 a68k.asm
|
|
||||||
|
|
||||||
|
|
||||||
clean : tidy
|
|
||||||
del a68k.obj
|
|
||||||
|
|
||||||
tidy :
|
|
||||||
del a68k.asm
|
|
||||||
del a68k_jmp.asm
|
|
||||||
del make68kd.exe
|
|
||||||
del make68kd.obj
|
|
|
@ -1 +0,0 @@
|
||||||
// dave filler file
|
|
8192
cpu/a68k/make68kd.c
8192
cpu/a68k/make68kd.c
File diff suppressed because it is too large
Load diff
|
@ -125,21 +125,6 @@ typedef union
|
||||||
signed int SD;
|
signed int SD;
|
||||||
} famec_union32;
|
} famec_union32;
|
||||||
|
|
||||||
/* The memory blocks must be in native (Motorola) format */
|
|
||||||
struct M68K_PROGRAM {
|
|
||||||
unsigned low_addr;
|
|
||||||
unsigned high_addr;
|
|
||||||
unsigned offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The memory blocks must be in native (Motorola) format */
|
|
||||||
struct M68K_DATA {
|
|
||||||
unsigned low_addr;
|
|
||||||
unsigned high_addr;
|
|
||||||
void *mem_handler;
|
|
||||||
void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* M68K CPU CONTEXT */
|
/* M68K CPU CONTEXT */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -626,35 +626,6 @@ static const s32 exception_cycle_table[256] =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/********************/
|
|
||||||
/* helper functions */
|
|
||||||
/********************/
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void famec_SetFetch(u32 low_adr, u32 high_adr, u32 fetch_adr)
|
|
||||||
{
|
|
||||||
u32 i, j;
|
|
||||||
|
|
||||||
i = (low_adr >> M68K_FETCHSFT) & M68K_FETCHMASK;
|
|
||||||
j = (high_adr >> M68K_FETCHSFT) & M68K_FETCHMASK;
|
|
||||||
|
|
||||||
while (i <= j)
|
|
||||||
g_m68kcontext->Fetch[i++] = fetch_adr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void famec_SetBanks(void)
|
|
||||||
{
|
|
||||||
u32 i=0;
|
|
||||||
while(m68kcontext.fetch[i].low_addr != (u32)-1)
|
|
||||||
{
|
|
||||||
famec_SetFetch(m68kcontext.fetch[i].low_addr,m68kcontext.fetch[i].high_addr,m68kcontext.fetch[i].offset);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/***********************/
|
/***********************/
|
||||||
/* core main functions */
|
/* core main functions */
|
||||||
/***********************/
|
/***********************/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue