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:
notaz 2007-10-22 20:38:41 +00:00
parent 9112b6ce9f
commit 3aa1e148a2
18 changed files with 398 additions and 8706 deletions

View file

@ -46,29 +46,17 @@ PICO_INTERNAL int PicoAreaPackCpu(unsigned char *cpu, int is_sub)
{
unsigned int pc=0;
#ifdef EMU_A68K
memcpy(cpu,M68000_regs.d,0x40);
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;
#if defined(EMU_C68K)
struct Cyclone *context = is_sub ? &PicoCpuCS68k : &PicoCpuCM68k;
memcpy(cpu,context->d,0x40);
pc=context->pc-context->membase;
*(unsigned int *)(cpu+0x44)=CycloneGetSr(context);
*(unsigned int *)(cpu+0x48)=context->osp;
cpu[0x4c] = context->irq;
cpu[0x4d] = context->state_flags & 1;
#endif
#ifdef EMU_M68K
#elif defined(EMU_M68K)
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);
pc=m68ki_cpu_p->pc;
*(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[0x4d] = CPU_STOPPED;
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
*(unsigned int *)(cpu+0x40)=pc;
@ -84,18 +80,8 @@ PICO_INTERNAL int PicoAreaPackCpu(unsigned char *cpu, int is_sub)
PICO_INTERNAL int PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
{
#ifdef EMU_A68K
memcpy(M68000_regs.d,cpu,0x40);
M68000_regs.pc=pc;
M68000_regs.ccr=*(unsigned char *)(cpu+0x44);
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;
#if defined(EMU_C68K)
struct Cyclone *context = is_sub ? &PicoCpuCS68k : &PicoCpuCM68k;
CycloneSetSr(context, *(unsigned int *)(cpu+0x44));
context->osp=*(unsigned int *)(cpu+0x48);
memcpy(context->d,cpu,0x40);
@ -105,11 +91,9 @@ PICO_INTERNAL int PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
context->state_flags = 0;
if (cpu[0x4d])
context->state_flags |= 1;
#endif
#ifdef EMU_M68K
#elif defined(EMU_M68K)
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);
m68ki_cpu_p->pc=*(unsigned int *)(cpu+0x40);
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_STOPPED = cpu[0x4d];
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
return 0;
}

View file

@ -73,7 +73,7 @@ static u32 CPU_CALL PicoCheckPc(u32 pc)
{
u32 ret=0;
#if defined(EMU_C68K)
pc-=PicoCpu.membase; // Get real pc
pc-=PicoCpuCM68k.membase; // Get real pc
// pc&=0xfffffe;
pc&=~1;
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
}
PicoCpu.membase=PicoMemBase(pc&0x00ffffff);
PicoCpu.membase-=pc&0xff000000;
PicoCpuCM68k.membase=PicoMemBase(pc&0x00ffffff);
PicoCpuCM68k.membase-=pc&0xff000000;
ret = PicoCpu.membase+pc;
ret = PicoCpuCM68k.membase+pc;
#endif
return ret;
}
@ -491,21 +491,35 @@ PICO_INTERNAL void PicoMemSetup(void)
{
// Setup memory callbacks:
#ifdef EMU_C68K
PicoCpu.checkpc=PicoCheckPc;
PicoCpu.fetch8 =PicoCpu.read8 =PicoRead8;
PicoCpu.fetch16=PicoCpu.read16=PicoRead16;
PicoCpu.fetch32=PicoCpu.read32=PicoRead32;
PicoCpu.write8 =PicoWrite8;
PicoCpu.write16=PicoWrite16;
PicoCpu.write32=PicoWrite32;
PicoCpuCM68k.checkpc=PicoCheckPc;
PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoRead8;
PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoRead16;
PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoRead32;
PicoCpuCM68k.write8 =PicoWrite8;
PicoCpuCM68k.write16=PicoWrite16;
PicoCpuCM68k.write32=PicoWrite32;
#endif
#ifdef EMU_F68K
PicoCpuM68k.read_byte =PicoRead8;
PicoCpuM68k.read_word =PicoRead16;
PicoCpuM68k.read_long =PicoRead32;
PicoCpuM68k.write_byte=PicoWrite8;
PicoCpuM68k.write_word=PicoWrite16;
PicoCpuM68k.write_long=PicoWrite32;
PicoCpuFM68k.read_byte =PicoRead8;
PicoCpuFM68k.read_word =PicoRead16;
PicoCpuFM68k.read_long =PicoRead32;
PicoCpuFM68k.write_byte=PicoWrite8;
PicoCpuFM68k.write_word=PicoWrite16;
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
}

View file

@ -209,9 +209,9 @@ static __inline void SekRunM68k(int cyc)
// this means we do run-compare Cyclone vs Musashi
SekCycleCnt+=CM_compareRun(cyc_do);
#elif defined(EMU_C68K)
PicoCpu.cycles=cyc_do;
CycloneRun(&PicoCpu);
SekCycleCnt+=cyc_do-PicoCpu.cycles;
PicoCpuCM68k.cycles=cyc_do;
CycloneRun(&PicoCpuCM68k);
SekCycleCnt+=cyc_do-PicoCpuCM68k.cycles;
#elif defined(EMU_M68K)
SekCycleCnt+=m68k_execute(cyc_do);
#elif defined(EMU_F68K)
@ -227,9 +227,9 @@ static __inline void SekStep(void)
// this means we do run-compare Cyclone vs Musashi
SekCycleCnt+=CM_compareRun(1);
#elif defined(EMU_C68K)
PicoCpu.cycles=1;
CycloneRun(&PicoCpu);
SekCycleCnt+=1-PicoCpu.cycles;
PicoCpuCM68k.cycles=1;
CycloneRun(&PicoCpuCM68k);
SekCycleCnt+=1-PicoCpuCM68k.cycles;
#elif defined(EMU_M68K)
SekCycleCnt+=m68k_execute(1);
#elif defined(EMU_F68K)
@ -240,27 +240,16 @@ static __inline void SekStep(void)
static int CheckIdle(void)
{
#if 1
unsigned char state[0x88];
memset(state,0,sizeof(state));
int i, state[0x22];
// See if the state is the same after 2 steps:
SekState(state); SekStep(); SekStep(); SekState(state+0x44);
if (memcmp(state,state+0x44,0x44)==0) return 1;
#else
unsigned char state[0x44];
static unsigned char oldstate[0x44];
SekState(state); SekStep(); SekStep(); SekState(state+0x11);
for (i = 0x10; i >= 0; i--)
if (state[i] != state[i+0x11]) return 0;
SekState(state);
if(memcmp(state,oldstate,0x40)==0) return 1;
memcpy(oldstate, state, 0x40);
#endif
return 0;
return 1;
}
void lprintf_al(const char *fmt, ...);
// to be called on 224 or line_sample scanlines only
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"
#endif
// helper z80 runner. Runs only if z80 is enabled at this point
// (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);
dstrp+=strlen(dstrp);
#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);
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, "d1=%08x, a1=%08x, sr=%04x\n", PicoCpu.d[1], PicoCpu.a[1], CycloneGetSr(&PicoCpu)); 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", PicoCpuCM68k.d[1], PicoCpuCM68k.a[1], CycloneGetSr(&PicoCpuCM68k)); dstrp+=strlen(dstrp);
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)
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)
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
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);

View file

@ -34,69 +34,68 @@ extern "C" {
// ----------------------- 68000 CPU -----------------------
#ifdef EMU_C68K
#include "../cpu/Cyclone/Cyclone.h"
extern struct Cyclone PicoCpu, PicoCpuS68k;
#define SekCyclesLeftNoMCD PicoCpu.cycles // cycles left for this run
extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
#define SekCyclesLeftNoMCD PicoCpuCM68k.cycles // cycles left for this run
#define SekCyclesLeft \
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)
#define SekCyclesLeftS68k \
((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoCpuS68k.cycles)
#define SekSetCyclesLeftNoMCD(c) PicoCpu.cycles=c
((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoCpuCS68k.cycles)
#define SekSetCyclesLeftNoMCD(c) PicoCpuCM68k.cycles=c
#define SekSetCyclesLeft(c) { \
if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SekSetCyclesLeftNoMCD(c); \
}
#define SekPc (PicoCpu.pc-PicoCpu.membase)
#define SekPcS68k (PicoCpuS68k.pc-PicoCpuS68k.membase)
#define SekSetStop(x) { PicoCpu.state_flags&=~1; if (x) { PicoCpu.state_flags|=1; PicoCpu.cycles=0; } }
#define SekSetStopS68k(x) { PicoCpuS68k.state_flags&=~1; if (x) { PicoCpuS68k.state_flags|=1; PicoCpuS68k.cycles=0; } }
#define SekPc (PicoCpuCM68k.pc-PicoCpuCM68k.membase)
#define SekPcS68k (PicoCpuCS68k.pc-PicoCpuCS68k.membase)
#define SekSetStop(x) { PicoCpuCM68k.state_flags&=~1; if (x) { PicoCpuCM68k.state_flags|=1; PicoCpuCM68k.cycles=0; } }
#define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }
#endif
#ifdef EMU_F68K
#include "../cpu/fame/fame.h"
M68K_CONTEXT PicoCpuM68k, PicoCpuS68k;
#define SekCyclesLeftNoMCD PicoCpuM68k.io_cycle_counter
M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
#define SekCyclesLeftNoMCD PicoCpuFM68k.io_cycle_counter
#define SekCyclesLeft \
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)
#define SekCyclesLeftS68k \
((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoCpuS68k.io_cycle_counter)
#define SekSetCyclesLeftNoMCD(c) PicoCpuM68k.io_cycle_counter=c
((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoCpuFS68k.io_cycle_counter)
#define SekSetCyclesLeftNoMCD(c) PicoCpuFM68k.io_cycle_counter=c
#define SekSetCyclesLeft(c) { \
if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SekSetCyclesLeftNoMCD(c); \
}
#define SekPc m68k_get_pc(&PicoCpuM68k)
#define SekPcS68k m68k_get_pc(&PicoCpuS68k)
#define SekPc m68k_get_pc(&PicoCpuFM68k)
#define SekPcS68k m68k_get_pc(&PicoCpuFS68k)
#define SekSetStop(x) { \
PicoCpuM68k.execinfo &= ~M68K_HALTED; \
if (x) { PicoCpuM68k.execinfo |= M68K_HALTED; PicoCpuM68k.io_cycle_counter = 0; } \
PicoCpuFM68k.execinfo &= ~M68K_HALTED; \
if (x) { PicoCpuFM68k.execinfo |= M68K_HALTED; PicoCpuFM68k.io_cycle_counter = 0; } \
}
#define SekSetStopS68k(x) { \
PicoCpuS68k.execinfo &= ~M68K_HALTED; \
if (x) { PicoCpuS68k.execinfo |= M68K_HALTED; PicoCpuS68k.io_cycle_counter = 0; } \
PicoCpuFS68k.execinfo &= ~M68K_HALTED; \
if (x) { PicoCpuFS68k.execinfo |= M68K_HALTED; PicoCpuFS68k.io_cycle_counter = 0; } \
}
#endif
#ifdef EMU_M68K
#include "../cpu/musashi/m68kcpu.h"
extern m68ki_cpu_core PicoM68kCPU; // MD's CPU
extern m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU
extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k;
#ifndef SekCyclesLeft
#define SekCyclesLeftNoMCD PicoM68kCPU.cyc_remaining_cycles
#define SekCyclesLeftNoMCD PicoCpuMM68k.cyc_remaining_cycles
#define SekCyclesLeft \
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)
#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 SekSetCyclesLeft(c) { \
if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SET_CYCLES(c); \
}
#define SekPc m68k_get_reg(&PicoM68kCPU, M68K_REG_PC)
#define SekPcS68k m68k_get_reg(&PicoS68kCPU, M68K_REG_PC)
#define SekPc m68k_get_reg(&PicoCpuMM68k, M68K_REG_PC)
#define SekPcS68k m68k_get_reg(&PicoCpuMS68k, M68K_REG_PC)
#define SekSetStop(x) { \
if(x) { SET_CYCLES(0); PicoM68kCPU.stopped=STOP_LEVEL_STOP; } \
else PicoM68kCPU.stopped=0; \
if(x) { SET_CYCLES(0); PicoCpuMM68k.stopped=STOP_LEVEL_STOP; } \
else PicoCpuMM68k.stopped=0; \
}
#define SekSetStopS68k(x) { \
if(x) { SET_CYCLES(0); PicoS68kCPU.stopped=STOP_LEVEL_STOP; } \
else PicoS68kCPU.stopped=0; \
if(x) { SET_CYCLES(0); PicoCpuMS68k.stopped=STOP_LEVEL_STOP; } \
else PicoCpuMS68k.stopped=0; \
}
#endif
#endif
@ -345,7 +344,7 @@ PICO_INTERNAL int PicoFrameMCD(void);
PICO_INTERNAL int SekInit(void);
PICO_INTERNAL int SekReset(void);
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);
// cd/Sek.c

View file

@ -18,15 +18,15 @@ unsigned int SekCycleCntT=0;
/* context */
// Cyclone 68000
#ifdef EMU_C68K
struct Cyclone PicoCpu;
struct Cyclone PicoCpuCM68k;
#endif
// MUSASHI 68000
#ifdef EMU_M68K
m68ki_cpu_core PicoM68kCPU;
m68ki_cpu_core PicoCpuMM68k;
#endif
// FAME 68000
#ifdef EMU_F68K
M68K_CONTEXT PicoCpuM68k;
M68K_CONTEXT PicoCpuFM68k;
#endif
@ -38,7 +38,7 @@ static int SekIntAck(int level)
// 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); }
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;
}
@ -51,12 +51,12 @@ static int SekUnrecognizedOpcode()
{
unsigned int pc, op;
pc = SekPc;
op = PicoCpu.read16(pc);
op = PicoCpuCM68k.read16(pc);
elprintf(EL_ANOMALY, "Unrecognized Opcode %04x @ %06x", op, pc);
// see if we are not executing trash
if (pc < 0x200 || (pc > Pico.romsize+4 && (pc&0xe00000)!=0xe00000)) {
PicoCpu.cycles = 0;
PicoCpu.state_flags |= 1;
PicoCpuCM68k.cycles = 0;
PicoCpuCM68k.state_flags |= 1;
return 1;
}
#ifdef EMU_M68K // debugging cyclone
@ -87,31 +87,11 @@ static int SekTasCallback(void)
#ifdef EMU_F68K
static void setup_fame_fetchmap(void)
{
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)
static void SekIntAckF68K(unsigned level)
{
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); }
PicoCpuM68k.interrupts[0] = 0;
PicoCpuFM68k.interrupts[0] = 0;
}
#endif
@ -120,15 +100,15 @@ PICO_INTERNAL int SekInit()
{
#ifdef EMU_C68K
CycloneInit();
memset(&PicoCpu,0,sizeof(PicoCpu));
PicoCpu.IrqCallback=SekIntAck;
PicoCpu.ResetCallback=SekResetAck;
PicoCpu.UnrecognizedCallback=SekUnrecognizedOpcode;
memset(&PicoCpuCM68k,0,sizeof(PicoCpuCM68k));
PicoCpuCM68k.IrqCallback=SekIntAck;
PicoCpuCM68k.ResetCallback=SekResetAck;
PicoCpuCM68k.UnrecognizedCallback=SekUnrecognizedOpcode;
#endif
#ifdef EMU_M68K
{
void *oldcontext = m68ki_cpu_p;
m68k_set_context(&PicoM68kCPU);
m68k_set_context(&PicoCpuMM68k);
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
m68k_init();
m68k_set_int_ack_callback(SekIntAckM68K);
@ -140,10 +120,10 @@ PICO_INTERNAL int SekInit()
#ifdef EMU_F68K
{
void *oldcontext = g_m68kcontext;
g_m68kcontext = &PicoCpuM68k;
memset(&PicoCpuM68k, 0, sizeof(PicoCpuM68k));
g_m68kcontext = &PicoCpuFM68k;
memset(&PicoCpuFM68k, 0, sizeof(PicoCpuFM68k));
m68k_init();
PicoCpuM68k.iack_handler = SekIntAckF68K;
PicoCpuFM68k.iack_handler = SekIntAckF68K;
g_m68kcontext = oldcontext;
}
#endif
@ -158,28 +138,25 @@ PICO_INTERNAL int SekReset()
if (Pico.rom==NULL) return 1;
#ifdef EMU_C68K
PicoCpu.state_flags=0;
PicoCpu.osp=0;
PicoCpu.srh =0x27; // Supervisor mode
PicoCpu.flags=4; // Z set
PicoCpu.irq=0;
PicoCpu.a[7]=PicoCpu.read32(0); // Stack Pointer
PicoCpu.membase=0;
PicoCpu.pc=PicoCpu.checkpc(PicoCpu.read32(4)); // Program Counter
PicoCpuCM68k.state_flags=0;
PicoCpuCM68k.osp=0;
PicoCpuCM68k.srh =0x27; // Supervisor mode
PicoCpuCM68k.flags=4; // Z set
PicoCpuCM68k.irq=0;
PicoCpuCM68k.a[7]=PicoCpuCM68k.read32(0); // Stack Pointer
PicoCpuCM68k.membase=0;
PicoCpuCM68k.pc=PicoCpuCM68k.checkpc(PicoCpuCM68k.read32(4)); // Program Counter
#endif
#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;
m68k_set_irq(0);
m68k_pulse_reset();
#endif
#ifdef EMU_F68K
{
unsigned ret;
g_m68kcontext = &PicoCpuM68k;
setup_fame_fetchmap();
ret = m68k_reset();
/*if (ret)*/ elprintf(EL_ANOMALY, "m68k_reset returned %u", ret);
g_m68kcontext = &PicoCpuFM68k;
m68k_reset();
}
#endif
@ -197,33 +174,34 @@ PICO_INTERNAL int SekInterrupt(int irq)
}
#endif
#ifdef EMU_C68K
PicoCpu.irq=irq;
PicoCpuCM68k.irq=irq;
#endif
#ifdef EMU_M68K
{
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_context(oldcontext);
}
#endif
#ifdef EMU_F68K
PicoCpuM68k.interrupts[0]=irq;
PicoCpuFM68k.interrupts[0]=irq;
#endif
return 0;
}
PICO_INTERNAL void SekState(unsigned char *data)
// data must be word aligned
PICO_INTERNAL void SekState(int *data)
{
#ifdef EMU_C68K
memcpy(data,PicoCpu.d,0x44);
memcpy32(data,PicoCpuCM68k.d,0x44/4);
#elif defined(EMU_M68K)
memcpy(data, PicoM68kCPU.dar, 0x40);
*(int *)(data+0x40) = PicoM68kCPU.pc;
memcpy32(data, PicoCpuMM68k.dar, 0x40/4);
data[0x10] = PicoCpuMM68k.pc;
#elif defined(EMU_F68K)
memcpy(data, PicoCpuM68k.dreg, 0x40);
*(int *)(data+0x40) = PicoCpuM68k.pc;
memcpy32(data, (int *)PicoCpuFM68k.dreg, 0x40/4);
data[0x10] = PicoCpuFM68k.pc;
#endif
}

View file

@ -382,7 +382,7 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
if(num < 2) {
#ifdef EMU_C68K
// 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
int lines, pints;
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);
#ifdef EMU_C68K
// adjust cycles for Cyclone so it would take the int "in time"
if(PicoCpu.irq) {
if(PicoCpuCM68k.irq) {
SekEndRun(24);
}
}

View file

@ -22,8 +22,8 @@ void dumpPCandExit()
dprintf("PC: %06x: %04x: %s", pppc, ppop, buff);
dprintf(" this | prev");
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("SR: %04x | %04x (??s? 0iii 000x nzvc)", CycloneGetSr(&PicoCpu), old_sr);
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(&PicoCpuCM68k), old_sr);
dprintf("last_read: %08x @ %06x", lastread_d[--lrp_cyc&15], lastread_a);
dprintf("ops done: %i", ops);
exit(1);
@ -43,7 +43,7 @@ int CM_compareRun(int cyc)
{
have_illegal = 0;
m68ki_cpu.pc += 2;
PicoCpu.pc=PicoCpu.checkpc(PicoCpu.pc + 2);
PicoCpuCM68k.pc=PicoCpuCM68k.checkpc(PicoCpuCM68k.pc + 2);
}
// hacks for test_misc2
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
have_illegal = 1;
//m68ki_cpu.s_flag = SFLAG_SET;
//PicoCpu.srh|=0x20;
//PicoCpuCM68k.srh|=0x20;
}
pppc = SekPc;
ppop = m68k_read_disassembler_16(pppc);
memcpy(old_regs, PicoCpu.d, 4*16);
old_sr = CycloneGetSr(&PicoCpu);
memcpy(old_regs, PicoCpuCM68k.d, 4*16);
old_sr = CycloneGetSr(&PicoCpuCM68k);
#if 0
{
@ -65,20 +65,20 @@ int CM_compareRun(int cyc)
dprintf("---");
m68k_disassemble(buff, pppc, M68K_CPU_TYPE_68000);
dprintf("PC: %06x: %04x: %s", pppc, ppop, buff);
//dprintf("A7: %08x", PicoCpu.a[7]);
//dprintf("A7: %08x", PicoCpuCM68k.a[7]);
}
#endif
if (dbg_irq_level)
{
PicoCpu.irq=dbg_irq_level;
PicoCpuCM68k.irq=dbg_irq_level;
m68k_set_irq(dbg_irq_level);
dbg_irq_level=0;
}
PicoCpu.cycles=1;
CycloneRun(&PicoCpu);
cyc_cyclone=1-PicoCpu.cycles;
PicoCpuCM68k.cycles=1;
CycloneRun(&PicoCpuCM68k);
cyc_cyclone=1-PicoCpuCM68k.cycles;
cyc_musashi=m68k_execute(1);
if(cyc_cyclone != cyc_musashi) {
@ -120,57 +120,57 @@ int CM_compareRun(int cyc)
// compare regs
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";
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;
}
}
// SR
if((CycloneGetSr(&PicoCpu)) != (mu_sr = m68k_get_reg(NULL, M68K_REG_SR))) {
dprintf("SR: %04x vs %04x (??s? 0iii 000x nzvc)", CycloneGetSr(&PicoCpu), mu_sr);
if((CycloneGetSr(&PicoCpuCM68k)) != (mu_sr = m68k_get_reg(NULL, M68K_REG_SR))) {
dprintf("SR: %04x vs %04x (??s? 0iii 000x nzvc)", CycloneGetSr(&PicoCpuCM68k), mu_sr);
err=1;
}
// IRQl
if(PicoCpu.irq != (m68ki_cpu.int_level>>8)) {
dprintf("IRQ: %i vs %i", PicoCpu.irq, (m68ki_cpu.int_level>>8));
if(PicoCpuCM68k.irq != (m68ki_cpu.int_level>>8)) {
dprintf("IRQ: %i vs %i", PicoCpuCM68k.irq, (m68ki_cpu.int_level>>8));
err=1;
}
// OSP/USP
if(PicoCpu.osp != m68ki_cpu.sp[((mu_sr>>11)&4)^4]) {
dprintf("OSP: %06x vs %06x", 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", PicoCpuCM68k.osp, m68ki_cpu.sp[((mu_sr>>11)&4)^4]);
err=1;
}
// stopped
if(((PicoCpu.state_flags&1) && !m68ki_cpu.stopped) || (!(PicoCpu.state_flags&1) && m68ki_cpu.stopped)) {
dprintf("stopped: %i vs %i", 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", PicoCpuCM68k.state_flags&1, m68ki_cpu.stopped);
err=1;
}
// tracing
if(((PicoCpu.state_flags&2) && !m68ki_tracing) || (!(PicoCpu.state_flags&2) && m68ki_tracing)) {
dprintf("tracing: %i vs %i", PicoCpu.state_flags&2, m68ki_tracing);
if(((PicoCpuCM68k.state_flags&2) && !m68ki_tracing) || (!(PicoCpuCM68k.state_flags&2) && m68ki_tracing)) {
dprintf("tracing: %i vs %i", PicoCpuCM68k.state_flags&2, m68ki_tracing);
err=1;
}
if(err) dumpPCandExit();
#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
#if 0
m68k_set_reg(M68K_REG_SR, ((mu_sr-1)&~0x2000)|(mu_sr&0x2000)); // broken
CycloneSetSr(&PicoCpu, ((mu_sr-1)&~0x2000)|(mu_sr&0x2000));
PicoCpu.stopped = m68ki_cpu.stopped = 0;
if(SekPc > 0x400 && (PicoCpu.a[7] < 0xff0000 || PicoCpu.a[7] > 0xffffff))
PicoCpu.a[7] = m68ki_cpu.dar[15] = 0xff8000;
CycloneSetSr(&PicoCpuCM68k, ((mu_sr-1)&~0x2000)|(mu_sr&0x2000));
PicoCpuCM68k.stopped = m68ki_cpu.stopped = 0;
if(SekPc > 0x400 && (PicoCpuCM68k.a[7] < 0xff0000 || PicoCpuCM68k.a[7] > 0xffffff))
PicoCpuCM68k.a[7] = m68ki_cpu.dar[15] = 0xff8000;
#endif
cyc_done += cyc_cyclone;

View file

@ -240,8 +240,8 @@ PICO_INTERNAL int PicoCdLoadState(void *file)
/* after load events */
if (Pico_mcd->s68k_regs[3]&4) // 1M mode?
wram_2M_to_1M(Pico_mcd->word_ram2M);
#ifdef _ASM_CD_MEMORY_C
PicoMemResetCD(Pico_mcd->s68k_regs[3]);
#ifdef _ASM_CD_MEMORY_C
if (Pico_mcd->s68k_regs[3]&4)
PicoMemResetCDdecode(Pico_mcd->s68k_regs[3]);
#endif

View file

@ -293,9 +293,7 @@ void s68k_reg_write8(u32 a, u32 d)
if (d&4) {
if ((d ^ dold) & 5) {
d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit
#ifdef _ASM_CD_MEMORY_C
PicoMemResetCD(d);
#endif
}
#ifdef _ASM_CD_MEMORY_C
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
}
wram_1M_to_2M(Pico_mcd->word_ram2M);
#ifdef _ASM_CD_MEMORY_C
PicoMemResetCD(d);
#endif
}
else
d |= dold&1;
@ -817,7 +813,7 @@ static u32 PicoReadS68k8(u32 a)
// test: batman returns
wrdprintf("s68k_wram2M r8: [%06x] @%06x", a, SekPcS68k);
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];
if (a&1) d &= 0x0f;
else d >>= 4;
@ -836,7 +832,7 @@ static u32 PicoReadS68k8(u32 a)
wrdprintf("s68k_wram1M r8: [%06x] @%06x", a, SekPcS68k);
// if (!(Pico_mcd->s68k_regs[3]&4))
// 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];
wrdprintf("ret = %02x", (u8)d);
goto end;
@ -907,7 +903,7 @@ static u32 PicoReadS68k16(u32 a)
if ((a&0xfc0000)==0x080000) { // 080000-0bffff
wrdprintf("s68k_wram2M r16: [%06x] @%06x", a, SekPcS68k);
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 |= d << 4; d &= ~0xf0;
dprintf("FIXME: decode");
@ -925,7 +921,7 @@ static u32 PicoReadS68k16(u32 a)
wrdprintf("s68k_wram1M r16: [%06x] @%06x", a, SekPcS68k);
// if (!(Pico_mcd->s68k_regs[3]&4))
// 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));
wrdprintf("ret = %04x", d);
goto end;
@ -999,7 +995,7 @@ static u32 PicoReadS68k32(u32 a)
if ((a&0xfc0000)==0x080000) { // 080000-0bffff
wrdprintf("s68k_wram2M r32: [%06x] @%06x", a, SekPcS68k);
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;
d = Pico_mcd->word_ram1M[bank][((a+0)^1)&0x1ffff] << 16;
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);
// if (!(Pico_mcd->s68k_regs[3]&4))
// 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];
wrdprintf("ret = %08x", d);
goto end;
@ -1075,7 +1071,7 @@ static u32 PicoReadS68k32(u32 a)
/* check: jaguar xj 220 (draws entire world using decode) */
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;
r3 &= 0x18;
@ -1098,7 +1094,7 @@ do_it:
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;
@ -1173,7 +1169,7 @@ static void PicoWriteS68k8(u32 a,u8 d)
wrdprintf("s68k_wram1M w8: [%06x] %02x @%06x", a, d, SekPcS68k);
// if (!(Pico_mcd->s68k_regs[3]&4))
// 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;
return;
}
@ -1256,7 +1252,7 @@ static void PicoWriteS68k16(u32 a,u16 d)
wrdprintf("s68k_wram1M w16: [%06x] %04x @%06x", a, d, SekPcS68k);
// if (!(Pico_mcd->s68k_regs[3]&4))
// 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;
return;
}
@ -1346,7 +1342,7 @@ static void PicoWriteS68k32(u32 a,u32 d)
wrdprintf("s68k_wram1M w32: [%06x] %08x @%06x", a, d, SekPcS68k);
// if (!(Pico_mcd->s68k_regs[3]&4))
// 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[0]=(u16)(d>>16); pm[1]=(u16)d;
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)
{
if ((pc&0xe00000)==0xe00000)
@ -1401,7 +1397,7 @@ static __inline int PicoMemBaseM68k(u32 pc)
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);
int bank = Pico_mcd->s68k_regs[3]&1;
return (int)Pico_mcd->word_ram1M[bank] - 0x200000;
}
}
@ -1415,12 +1411,12 @@ static __inline int PicoMemBaseM68k(u32 pc)
static u32 PicoCheckPcM68k(u32 pc)
{
pc-=PicoCpu.membase; // Get real pc
pc-=PicoCpuCM68k.membase; // Get real pc
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;
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;
}
@ -1446,37 +1442,101 @@ static __inline int PicoMemBaseS68k(u32 pc)
static u32 PicoCheckPcS68k(u32 pc)
{
pc-=PicoCpuS68k.membase; // Get real pc
pc-=PicoCpuCS68k.membase; // Get real pc
pc&=0xfffffe;
PicoCpuS68k.membase=PicoMemBaseS68k(pc);
PicoCpuCS68k.membase=PicoMemBaseS68k(pc);
return PicoCpuS68k.membase+pc;
return PicoCpuCS68k.membase+pc;
}
#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)
{
dprintf("PicoMemSetupCD()");
#ifdef EMU_C68K
// Setup m68k memory callbacks:
PicoCpu.checkpc=PicoCheckPcM68k;
PicoCpu.fetch8 =PicoCpu.read8 =PicoReadM68k8;
PicoCpu.fetch16=PicoCpu.read16=PicoReadM68k16;
PicoCpu.fetch32=PicoCpu.read32=PicoReadM68k32;
PicoCpu.write8 =PicoWriteM68k8;
PicoCpu.write16=PicoWriteM68k16;
PicoCpu.write32=PicoWriteM68k32;
PicoCpuCM68k.checkpc=PicoCheckPcM68k;
PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoReadM68k8;
PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoReadM68k16;
PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoReadM68k32;
PicoCpuCM68k.write8 =PicoWriteM68k8;
PicoCpuCM68k.write16=PicoWriteM68k16;
PicoCpuCM68k.write32=PicoWriteM68k32;
// s68k
PicoCpuS68k.checkpc=PicoCheckPcS68k;
PicoCpuS68k.fetch8 =PicoCpuS68k.read8 =PicoReadS68k8;
PicoCpuS68k.fetch16=PicoCpuS68k.read16=PicoReadS68k16;
PicoCpuS68k.fetch32=PicoCpuS68k.read32=PicoReadS68k32;
PicoCpuS68k.write8 =PicoWriteS68k8;
PicoCpuS68k.write16=PicoWriteS68k16;
PicoCpuS68k.write32=PicoWriteS68k32;
PicoCpuCS68k.checkpc=PicoCheckPcS68k;
PicoCpuCS68k.fetch8 =PicoCpuCS68k.read8 =PicoReadS68k8;
PicoCpuCS68k.fetch16=PicoCpuCS68k.read16=PicoReadS68k16;
PicoCpuCS68k.fetch32=PicoCpuCS68k.read32=PicoReadS68k32;
PicoCpuCS68k.write8 =PicoWriteS68k8;
PicoCpuCS68k.write16=PicoWriteS68k16;
PicoCpuCS68k.write32=PicoWriteS68k32;
#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;
s68k_poll_adclk = s68k_poll_cnt = 0;
}
@ -1484,33 +1544,33 @@ PICO_INTERNAL void PicoMemSetupCD(void)
#ifdef EMU_M68K
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) {
return m68ki_cpu_p == &PicoS68kCPU ? PicoReadS68k16(a) : PicoReadM68k16(a);
return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k16(a) : PicoReadM68k16(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) {
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) {
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) {
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
unsigned int m68k_read_pcrelative_CD8 (unsigned int a) {
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&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)
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)
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));
}
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) {
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&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)
return *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));
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));
}
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) {
u16 *pm;
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&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]; }
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));
return (pm[0]<<16)|pm[1];
}

View file

@ -136,7 +136,7 @@ m_s68k_decode_write_table:
.extern gfx_cd_write16
.extern s68k_reg_write8
.extern s68k_poll_adclk
.extern PicoCpuS68k
.extern PicoCpuMS68k
.extern s68k_poll_detect
.extern SN76496Write
.extern m_m68k_read8_misc
@ -1259,7 +1259,7 @@ m_m68k_write16_regs_spec: @ special case
and r2, r2, #0xfe
cmp r2, #0x0e
bxne lr
ldr r0, =PicoCpuS68k
ldr r0, =PicoCpuCS68k
str r1, [r0, #0x58] @ push s68k out of stopped state
str r1, [r3]
bx lr
@ -1450,7 +1450,7 @@ m_m68k_write32_regs_comm: @ Handle the 0x10-0x1f range
strneh r1, [r2, #2]
cmp r0, #0x10
bxlt lr
ldr r0, =PicoCpuS68k @ remove poll detected state for s68k
ldr r0, =PicoCpuCS68k @ remove poll detected state for s68k
mov r1, #0
str r1, [r0, #0x58]
str r1, [r3]

View file

@ -69,8 +69,8 @@ PICO_INTERNAL int PicoResetMCD(int hard)
Reset_CD();
LC89510_Reset();
gfx_cd_reset();
#ifdef _ASM_CD_MEMORY_C
PicoMemResetCD(1);
#ifdef _ASM_CD_MEMORY_C
//PicoMemResetCDdecode(1); // don't have to call this in 2M mode
#endif
@ -89,12 +89,15 @@ static __inline void SekRunM68k(int cyc)
SekCycleAim+=cyc;
if((cyc_do=SekCycleAim-SekCycleCnt) < 0) return;
#if defined(EMU_C68K)
PicoCpu.cycles=cyc_do;
CycloneRun(&PicoCpu);
SekCycleCnt+=cyc_do-PicoCpu.cycles;
PicoCpuCM68k.cycles=cyc_do;
CycloneRun(&PicoCpuCM68k);
SekCycleCnt+=cyc_do-PicoCpuCM68k.cycles;
#elif defined(EMU_M68K)
m68k_set_context(&PicoM68kCPU);
m68k_set_context(&PicoCpuMM68k);
SekCycleCnt+=m68k_execute(cyc_do);
#elif defined(EMU_F68K)
g_m68kcontext=&PicoCpuFM68k;
SekCycleCnt+=m68k_emulate(cyc_do);
#endif
}
@ -104,12 +107,15 @@ static __inline void SekRunS68k(int cyc)
SekCycleAimS68k+=cyc;
if((cyc_do=SekCycleAimS68k-SekCycleCntS68k) < 0) return;
#if defined(EMU_C68K)
PicoCpuS68k.cycles=cyc_do;
CycloneRun(&PicoCpuS68k);
SekCycleCntS68k+=cyc_do-PicoCpuS68k.cycles;
PicoCpuCS68k.cycles=cyc_do;
CycloneRun(&PicoCpuCS68k);
SekCycleCntS68k+=cyc_do-PicoCpuCS68k.cycles;
#elif defined(EMU_M68K)
m68k_set_context(&PicoS68kCPU);
m68k_set_context(&PicoCpuMS68k);
SekCycleCntS68k+=m68k_execute(cyc_do);
#elif defined(EMU_F68K)
g_m68kcontext=&PicoCpuFS68k;
SekCycleCntS68k+=m68k_emulate(cyc_do);
#endif
}
@ -122,7 +128,6 @@ 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 ex;
SekCycleAim+=cyc_m68k;
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 */
for (cycn = (488<<16)-PS_STEP_M68K; cycn >= 0; cycn -= PS_STEP_M68K)
{
ex = 0;
cycn_s68k = (cycn + cycn/2 + cycn/8) >> 16;
if ((cyc_do = SekCycleAim-SekCycleCnt-(cycn>>16)) > 0) {
#if defined(EMU_C68K)
PicoCpu.cycles = cyc_do;
CycloneRun(&PicoCpu);
SekCycleCnt += cyc_do - PicoCpu.cycles;
PicoCpuCM68k.cycles = cyc_do;
CycloneRun(&PicoCpuCM68k);
SekCycleCnt += cyc_do - PicoCpuCM68k.cycles;
#elif defined(EMU_M68K)
m68k_set_context(&PicoM68kCPU);
SekCycleCnt += (ex = m68k_execute(cyc_do));
m68k_set_context(&PicoCpuMM68k);
SekCycleCnt += m68k_execute(cyc_do);
#elif defined(EMU_F68K)
g_m68kcontext = &PicoCpuFM68k;
SekCycleCnt += m68k_emulate(cyc_do);
#endif
}
if ((cyc_do = SekCycleAimS68k-SekCycleCntS68k-cycn_s68k) > 0) {
#if defined(EMU_C68K)
PicoCpuS68k.cycles = cyc_do;
CycloneRun(&PicoCpuS68k);
SekCycleCntS68k += cyc_do - PicoCpuS68k.cycles;
PicoCpuCS68k.cycles = cyc_do;
CycloneRun(&PicoCpuCS68k);
SekCycleCntS68k += cyc_do - PicoCpuCS68k.cycles;
#elif defined(EMU_M68K)
m68k_set_context(&PicoS68kCPU);
SekCycleCntS68k += (ex = m68k_execute(cyc_do));
m68k_set_context(&PicoCpuMS68k);
SekCycleCntS68k += m68k_execute(cyc_do);
#elif defined(EMU_F68K)
g_m68kcontext = &PicoCpuFS68k;
SekCycleCntS68k += m68k_emulate(cyc_do);
#endif
}
}

View file

@ -1,6 +1,6 @@
@ 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
@ 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 CycloneJumpTab
.extern CycloneDoInterrupt
.extern PicoCpu
.extern PicoCpuS68k
.extern PicoCpuCM68k
.extern PicoCpuCS68k
.extern SekCycleAim
.extern SekCycleCnt
.extern SekCycleAimS68k
@ -32,8 +32,8 @@ SekRunPS:
sub sp, sp, #2*4 @ sp[0] = main_cycle_cnt, sp[4] = run_cycle_cnt
@ override CycloneEnd for both contexts
ldr r7, =PicoCpu
ldr lr, =PicoCpuS68k
ldr r7, =PicoCpuCM68k
ldr lr, =PicoCpuCS68k
ldr r2, =CycloneEnd_M68k
ldr r3, =CycloneEnd_S68k
str r2, [r7,#0x98]
@ -90,7 +90,7 @@ schedule_s68k:
subs r5, r0, r3, asr #16
ble schedule_m68k @ s68k has not enough cycles
ldr r7, =PicoCpuS68k
ldr r7, =PicoCpuCS68k
str r5, [sp,#4] @ run_cycle_cnt
b CycloneRunLocal
@ -122,15 +122,15 @@ schedule_m68k:
subs r5, r0, r3, asr #16
ble schedule_s68k @ m68k has not enough cycles
ldr r7, =PicoCpu
ldr r7, =PicoCpuCM68k
str r5, [sp,#4] @ run_cycle_cnt
b CycloneRunLocal
SekRunPS_end:
ldr r7, =PicoCpu
ldr lr, =PicoCpuS68k
ldr r7, =PicoCpuCM68k
ldr lr, =PicoCpuCS68k
mov r0, #0
str r0, [r7,#0x98] @ remove CycloneEnd handler
str r0, [lr,#0x98]

View file

@ -7,15 +7,21 @@
int SekCycleCntS68k=0; // cycles done in this frame
int SekCycleAimS68k=0; // cycle aim
/* context */
// Cyclone 68000
#ifdef EMU_C68K
// ---------------------- Cyclone 68000 ----------------------
struct Cyclone PicoCpuS68k;
struct Cyclone PicoCpuCS68k;
#endif
// MUSASHI 68000
#ifdef EMU_M68K
m68ki_cpu_core PicoCpuMS68k;
#endif
// FAME 68000
#ifdef EMU_F68K
M68K_CONTEXT PicoCpuFS68k;
#endif
#ifdef EMU_M68K
// ---------------------- MUSASHI 68000 ----------------------
m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU
#endif
static int new_irq_level(int level)
{
@ -28,16 +34,6 @@ static int new_irq_level(int level)
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
// interrupt acknowledgement
static int SekIntAckS68k(int level)
@ -45,7 +41,7 @@ static int SekIntAckS68k(int level)
int level_new = new_irq_level(level);
dprintf("s68kACK %i -> %i", level, level_new);
PicoCpuS68k.irq = level_new;
PicoCpuCS68k.irq = level_new;
return CYCLONE_INT_ACK_AUTOVECTOR;
}
@ -58,36 +54,64 @@ static int SekUnrecognizedOpcodeS68k(void)
{
unsigned int pc, op;
pc = SekPcS68k;
op = PicoCpuS68k.read16(pc);
op = PicoCpuCS68k.read16(pc);
dprintf("Unrecognized Opcode %04x @ %06x", op, pc);
//exit(1);
return 0;
}
#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()
{
#ifdef EMU_C68K
// CycloneInit();
memset(&PicoCpuS68k,0,sizeof(PicoCpuS68k));
PicoCpuS68k.IrqCallback=SekIntAckS68k;
PicoCpuS68k.ResetCallback=SekResetAckS68k;
PicoCpuS68k.UnrecognizedCallback=SekUnrecognizedOpcodeS68k;
memset(&PicoCpuCS68k,0,sizeof(PicoCpuCS68k));
PicoCpuCS68k.IrqCallback=SekIntAckS68k;
PicoCpuCS68k.ResetCallback=SekResetAckS68k;
PicoCpuCS68k.UnrecognizedCallback=SekUnrecognizedOpcodeS68k;
#endif
#ifdef EMU_M68K
{
// Musashi is not very context friendly..
void *oldcontext = m68ki_cpu_p;
m68k_set_context(&PicoS68kCPU);
m68k_set_context(&PicoCpuMS68k);
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
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_set_context(oldcontext);
}
#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;
}
@ -98,26 +122,34 @@ PICO_INTERNAL int SekResetS68k()
if (Pico.rom==NULL) return 1;
#ifdef EMU_C68K
PicoCpuS68k.state_flags=0;
PicoCpuS68k.osp=0;
PicoCpuS68k.srh =0x27; // Supervisor mode
PicoCpuS68k.flags=4; // Z set
PicoCpuS68k.irq=0;
PicoCpuS68k.a[7]=PicoCpuS68k.read32(0); // Stack Pointer
PicoCpuS68k.membase=0;
PicoCpuS68k.pc=PicoCpuS68k.checkpc(PicoCpuS68k.read32(4)); // Program Counter
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
#endif
#ifdef EMU_M68K
{
void *oldcontext = m68ki_cpu_p;
m68k_set_context(&PicoS68kCPU);
m68k_set_context(&PicoCpuMS68k);
m68ki_cpu.sp[0]=0;
m68k_set_irq(0);
m68k_pulse_reset();
m68k_set_context(oldcontext);
}
#endif
#ifdef EMU_F68K
{
void *oldcontext = g_m68kcontext;
g_m68kcontext = &PicoCpuFS68k;
m68k_reset();
g_m68kcontext = oldcontext;
}
#endif
return 0;
}
@ -127,16 +159,19 @@ PICO_INTERNAL int SekInterruptS68k(int irq)
int irqs, real_irq = 1;
Pico_mcd->m.s68k_pend_ints |= 1 << irq;
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
PicoCpuS68k.irq=real_irq;
PicoCpuCS68k.irq=real_irq;
#endif
#ifdef EMU_M68K
void *oldcontext = m68ki_cpu_p;
m68k_set_context(&PicoS68kCPU);
m68k_set_irq(real_irq); // raise irq (gets lowered after taken or must be done in ack)
m68k_set_context(&PicoCpuMS68k);
m68k_set_irq(real_irq);
m68k_set_context(oldcontext);
#endif
#ifdef EMU_F68K
PicoCpuFS68k.interrupts[0]=real_irq;
#endif
return 0;
}

View file

@ -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

View file

@ -1 +0,0 @@
// dave filler file

File diff suppressed because it is too large Load diff

View file

@ -125,21 +125,6 @@ typedef union
signed int SD;
} 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 */
typedef struct
{

View file

@ -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 */
/***********************/