bugfixes, adjusted famec timing

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@283 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-10-28 20:23:15 +00:00
parent 80db44425a
commit 03e4f2a349
15 changed files with 324 additions and 344 deletions

View file

@ -71,7 +71,7 @@ PICO_INTERNAL int PicoAreaPackCpu(unsigned char *cpu, int is_sub)
*(unsigned int *)(cpu+0x44)=context->sr; *(unsigned int *)(cpu+0x44)=context->sr;
*(unsigned int *)(cpu+0x48)=context->asp; *(unsigned int *)(cpu+0x48)=context->asp;
cpu[0x4c] = context->interrupts[0]; cpu[0x4c] = context->interrupts[0];
cpu[0x4d] = (context->execinfo & M68K_HALTED) ? 1 : 0; cpu[0x4d] = (context->execinfo & FM68K_HALTED) ? 1 : 0;
#endif #endif
*(unsigned int *)(cpu+0x40)=pc; *(unsigned int *)(cpu+0x40)=pc;
@ -108,8 +108,8 @@ PICO_INTERNAL int PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
context->sr =*(unsigned int *)(cpu+0x44); context->sr =*(unsigned int *)(cpu+0x44);
context->asp=*(unsigned int *)(cpu+0x48); context->asp=*(unsigned int *)(cpu+0x48);
context->interrupts[0] = cpu[0x4c]; context->interrupts[0] = cpu[0x4c];
context->execinfo &= ~M68K_HALTED; context->execinfo &= ~FM68K_HALTED;
if (cpu[0x4d]&1) context->execinfo |= M68K_HALTED; if (cpu[0x4d]&1) context->execinfo |= FM68K_HALTED;
#endif #endif
return 0; return 0;
} }

View file

@ -12,6 +12,37 @@ unsigned int old_regs[16], old_sr, ppop, have_illegal = 0, dbg_irq_level = 0;
#undef dprintf #undef dprintf
#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__) #define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)
#if defined(EMU_C68K)
#define other_get_sr() CycloneGetSr(&PicoCpuCM68k)
#define other_dar(i) PicoCpuCM68k.d[i]
#define other_osp PicoCpuCM68k.osp
#define other_get_irq() PicoCpuCM68k.irq
#define other_set_irq(irq) PicoCpuCM68k.irq=irq
#define other_is_stopped() (PicoCpuCM68k.state_flags&1)
#define other_is_tracing() ((PicoCpuCM68k.state_flags&2)?1:0)
#elif defined(EMU_F68K)
#define other_get_sr() PicoCpuFM68k.sr
#define other_dar(i) ((unsigned int*)PicoCpuFM68k.dreg)[i]
#define other_osp PicoCpuFM68k.asp
#define other_get_irq() PicoCpuFM68k.interrupts[0]
#define other_set_irq(irq) PicoCpuFM68k.interrupts[0]=irq
#define other_is_stopped() ((PicoCpuFM68k.execinfo&FM68K_HALTED)?1:0)
#define other_is_tracing() ((PicoCpuFM68k.execinfo&FM68K_EMULATE_TRACE)?1:0)
#else
#error other core missing, don't compile this file
#endif
static int otherRun(void)
{
#if defined(EMU_C68K)
PicoCpuCM68k.cycles=1;
CycloneRun(&PicoCpuCM68k);
return 1-PicoCpuCM68k.cycles;
#elif defined(EMU_F68K)
return fm68k_emulate(1);
#endif
}
//static //static
void dumpPCandExit() void dumpPCandExit()
{ {
@ -22,8 +53,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, PicoCpuCM68k.d[i], i, PicoCpuCM68k.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, other_dar(i), i, other_dar(i+8), i, old_regs[i], i, old_regs[i+8]);
dprintf("SR: %04x | %04x (??s? 0iii 000x nzvc)", CycloneGetSr(&PicoCpuCM68k), old_sr); dprintf("SR: %04x | %04x (??s? 0iii 000x nzvc)", other_get_sr(), 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);
@ -32,7 +63,7 @@ void dumpPCandExit()
int CM_compareRun(int cyc) int CM_compareRun(int cyc)
{ {
char *str; char *str;
int cyc_done=0, cyc_cyclone, cyc_musashi, err=0; int cyc_done=0, cyc_other, cyc_musashi, err=0;
unsigned int i, mu_sr; unsigned int i, mu_sr;
lrp_cyc = lrp_mus = 0; lrp_cyc = lrp_mus = 0;
@ -43,7 +74,9 @@ int CM_compareRun(int cyc)
{ {
have_illegal = 0; have_illegal = 0;
m68ki_cpu.pc += 2; m68ki_cpu.pc += 2;
#ifdef EMU_C68K
PicoCpuCM68k.pc=PicoCpuCM68k.checkpc(PicoCpuCM68k.pc + 2); PicoCpuCM68k.pc=PicoCpuCM68k.checkpc(PicoCpuCM68k.pc + 2);
#endif
} }
// 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)
@ -56,8 +89,8 @@ int CM_compareRun(int cyc)
pppc = SekPc; pppc = SekPc;
ppop = m68k_read_disassembler_16(pppc); ppop = m68k_read_disassembler_16(pppc);
memcpy(old_regs, PicoCpuCM68k.d, 4*16); memcpy(old_regs, &other_dar(0), 4*16);
old_sr = CycloneGetSr(&PicoCpuCM68k); old_sr = other_get_sr();
#if 0 #if 0
{ {
@ -71,43 +104,41 @@ int CM_compareRun(int cyc)
if (dbg_irq_level) if (dbg_irq_level)
{ {
PicoCpuCM68k.irq=dbg_irq_level; other_set_irq(dbg_irq_level);
m68k_set_irq(dbg_irq_level); m68k_set_irq(dbg_irq_level);
dbg_irq_level=0; dbg_irq_level=0;
} }
PicoCpuCM68k.cycles=1; cyc_other=otherRun();
CycloneRun(&PicoCpuCM68k);
cyc_cyclone=1-PicoCpuCM68k.cycles;
cyc_musashi=m68k_execute(1); cyc_musashi=m68k_execute(1);
if(cyc_cyclone != cyc_musashi) { if (cyc_other != cyc_musashi) {
dprintf("cycles: %i vs %i", cyc_cyclone, cyc_musashi); dprintf("cycles: %i vs %i", cyc_other, cyc_musashi);
err=1; err=1;
} }
if(lrp_cyc != lrp_mus) { if (lrp_cyc != lrp_mus) {
dprintf("lrp: %i vs %i", lrp_cyc&15, lrp_mus&15); dprintf("lrp: %i vs %i", lrp_cyc&15, lrp_mus&15);
err=1; err=1;
} }
if(lwp_cyc != lwp_mus) { if (lwp_cyc != lwp_mus) {
dprintf("lwp: %i vs %i", lwp_cyc&15, lwp_mus&15); dprintf("lwp: %i vs %i", lwp_cyc&15, lwp_mus&15);
err=1; err=1;
} }
for(i=0; i < 16; i++) { for (i=0; i < 16; i++) {
if(lastwrite_cyc_d[i] != lastwrite_mus_d[i]) { if (lastwrite_cyc_d[i] != lastwrite_mus_d[i]) {
dprintf("lastwrite: [%i]= %08x vs %08x", i, lastwrite_cyc_d[i], lastwrite_mus_d[i]); dprintf("lastwrite: [%i]= %08x vs %08x", i, lastwrite_cyc_d[i], lastwrite_mus_d[i]);
err=1; err=1;
break; break;
} }
} }
// compare PC // compare PC
m68ki_cpu.pc&=~1; m68ki_cpu.pc&=~1;
if( SekPc != (m68ki_cpu.pc/*&0xffffff*/) ) { if ( SekPc != (m68ki_cpu.pc&0xffffff) ) {
dprintf("PC: %06x vs %06x", SekPc, m68ki_cpu.pc/*&0xffffff*/); dprintf("PC: %06x vs %06x", SekPc, m68ki_cpu.pc&0xffffff);
err=1; err=1;
} }
@ -119,41 +150,41 @@ int CM_compareRun(int cyc)
#endif #endif
// compare regs // compare regs
for(i=0; i < 16; i++) { for (i=0; i < 16; i++) {
if(PicoCpuCM68k.d[i] != m68ki_cpu.dar[i]) { if (other_dar(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, PicoCpuCM68k.d[i], m68ki_cpu.dar[i]); dprintf("reg: %s%i: %08x vs %08x", str, i&7, other_dar(i), m68ki_cpu.dar[i]);
err=1; err=1;
} }
} }
// SR // SR
if((CycloneGetSr(&PicoCpuCM68k)) != (mu_sr = m68k_get_reg(NULL, M68K_REG_SR))) { if (other_get_sr() != (mu_sr = m68k_get_reg(NULL, M68K_REG_SR))) {
dprintf("SR: %04x vs %04x (??s? 0iii 000x nzvc)", CycloneGetSr(&PicoCpuCM68k), mu_sr); dprintf("SR: %04x vs %04x (??s? 0iii 000x nzvc)", other_get_sr(), mu_sr);
err=1; err=1;
} }
// IRQl // IRQl
if(PicoCpuCM68k.irq != (m68ki_cpu.int_level>>8)) { if (other_get_irq() != (m68ki_cpu.int_level>>8)) {
dprintf("IRQ: %i vs %i", PicoCpuCM68k.irq, (m68ki_cpu.int_level>>8)); dprintf("IRQ: %i vs %i", other_get_irq(), (m68ki_cpu.int_level>>8));
err=1; err=1;
} }
// OSP/USP // OSP/USP
if(PicoCpuCM68k.osp != m68ki_cpu.sp[((mu_sr>>11)&4)^4]) { if (other_osp != m68ki_cpu.sp[((mu_sr>>11)&4)^4]) {
dprintf("OSP: %06x vs %06x", PicoCpuCM68k.osp, m68ki_cpu.sp[((mu_sr>>11)&4)^4]); dprintf("OSP: %06x vs %06x", other_osp, m68ki_cpu.sp[((mu_sr>>11)&4)^4]);
err=1; err=1;
} }
// stopped // stopped
if(((PicoCpuCM68k.state_flags&1) && !m68ki_cpu.stopped) || (!(PicoCpuCM68k.state_flags&1) && m68ki_cpu.stopped)) { if ((other_is_stopped() && !m68ki_cpu.stopped) || (!other_is_stopped() && m68ki_cpu.stopped)) {
dprintf("stopped: %i vs %i", PicoCpuCM68k.state_flags&1, m68ki_cpu.stopped); dprintf("stopped: %i vs %i", other_is_stopped(), m68ki_cpu.stopped);
err=1; err=1;
} }
// tracing // tracing
if(((PicoCpuCM68k.state_flags&2) && !m68ki_tracing) || (!(PicoCpuCM68k.state_flags&2) && m68ki_tracing)) { if((other_is_tracing() && !m68ki_tracing) || (!other_is_tracing() && m68ki_tracing)) {
dprintf("tracing: %i vs %i", PicoCpuCM68k.state_flags&2, m68ki_tracing); dprintf("tracing: %i vs %i", other_is_tracing(), m68ki_tracing);
err=1; err=1;
} }
@ -173,7 +204,7 @@ int CM_compareRun(int cyc)
PicoCpuCM68k.a[7] = m68ki_cpu.dar[15] = 0xff8000; PicoCpuCM68k.a[7] = m68ki_cpu.dar[15] = 0xff8000;
#endif #endif
cyc_done += cyc_cyclone; cyc_done += cyc_other;
ops++; ops++;
} }

View file

@ -32,8 +32,7 @@ void PicoWriteRomHW_in1 (u32 a,u32 d);
#endif #endif
#if defined(EMU_C68K) && defined(EMU_M68K) #ifdef EMU_CORE_DEBUG
// cyclone debug mode
u32 lastread_a, lastread_d[16]={0,}, lastwrite_cyc_d[16]={0,}, lastwrite_mus_d[16]={0,}; u32 lastread_a, lastread_d[16]={0,}, lastwrite_cyc_d[16]={0,}, lastwrite_mus_d[16]={0,};
int lrp_cyc=0, lrp_mus=0, lwp_cyc=0, lwp_mus=0; int lrp_cyc=0, lrp_mus=0, lwp_cyc=0, lwp_mus=0;
extern unsigned int ppop; extern unsigned int ppop;
@ -323,7 +322,7 @@ PICO_INTERNAL_ASM u32 PicoRead8(u32 a)
a&=0xffffff; a&=0xffffff;
#if !(defined(EMU_C68K) && defined(EMU_M68K)) #ifndef EMU_CORE_DEBUG
// sram // sram
if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) { if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
d = SRAMRead(a); d = SRAMRead(a);
@ -342,7 +341,7 @@ end:
#ifdef __debug_io #ifdef __debug_io
dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc); dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
#endif #endif
#if defined(EMU_C68K) && defined(EMU_M68K) #ifdef EMU_CORE_DEBUG
if(a>=Pico.romsize/*&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b*/) { if(a>=Pico.romsize/*&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b*/) {
lastread_a = a; lastread_a = a;
lastread_d[lrp_cyc++&15] = (u8)d; lastread_d[lrp_cyc++&15] = (u8)d;
@ -359,7 +358,7 @@ PICO_INTERNAL_ASM u32 PicoRead16(u32 a)
a&=0xfffffe; a&=0xfffffe;
#if !(defined(EMU_C68K) && defined(EMU_M68K)) #ifndef EMU_CORE_DEBUG
// sram // sram
if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) { if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
d = SRAMRead(a); d = SRAMRead(a);
@ -378,7 +377,7 @@ end:
#ifdef __debug_io #ifdef __debug_io
dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc); dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);
#endif #endif
#if defined(EMU_C68K) && defined(EMU_M68K) #ifdef EMU_CORE_DEBUG
if(a>=Pico.romsize/*&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b*/) { if(a>=Pico.romsize/*&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b*/) {
lastread_a = a; lastread_a = a;
lastread_d[lrp_cyc++&15] = d; lastread_d[lrp_cyc++&15] = d;
@ -412,7 +411,7 @@ end:
#ifdef __debug_io #ifdef __debug_io
dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc); dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);
#endif #endif
#if defined(EMU_C68K) && defined(EMU_M68K) #ifdef EMU_CORE_DEBUG
if(a>=Pico.romsize/*&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b*/) { if(a>=Pico.romsize/*&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b*/) {
lastread_a = a; lastread_a = a;
lastread_d[lrp_cyc++&15] = d; lastread_d[lrp_cyc++&15] = d;
@ -431,12 +430,9 @@ PICO_INTERNAL_ASM void PicoWrite8(u32 a,u8 d)
#ifdef __debug_io #ifdef __debug_io
dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc); dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);
#endif #endif
#if defined(EMU_C68K) && defined(EMU_M68K) #ifdef EMU_CORE_DEBUG
lastwrite_cyc_d[lwp_cyc++&15] = d; lastwrite_cyc_d[lwp_cyc++&15] = d;
#endif #endif
//if ((a&0xe0ffff)==0xe0a9ba+0x69c)
//if(a==0x200000||a==0x200001) printf("w8 : %02x [%06x] @ %06x [%i]\n", d, a, SekPc, SekCyclesDoneT());
// dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);
if ((a&0xe00000)==0xe00000) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram if ((a&0xe00000)==0xe00000) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram
log_io(a, 8, 1); log_io(a, 8, 1);
@ -451,7 +447,7 @@ void PicoWrite16(u32 a,u16 d)
#ifdef __debug_io #ifdef __debug_io
dprintf("w16: %06x, %04x", a&0xffffff, d); dprintf("w16: %06x, %04x", a&0xffffff, d);
#endif #endif
#if defined(EMU_C68K) && defined(EMU_M68K) #ifdef EMU_CORE_DEBUG
lastwrite_cyc_d[lwp_cyc++&15] = d; lastwrite_cyc_d[lwp_cyc++&15] = d;
#endif #endif
@ -467,7 +463,7 @@ static void PicoWrite32(u32 a,u32 d)
#ifdef __debug_io #ifdef __debug_io
dprintf("w32: %06x, %08x", a&0xffffff, d); dprintf("w32: %06x, %08x", a&0xffffff, d);
#endif #endif
#if defined(EMU_C68K) && defined(EMU_M68K) #ifdef EMU_CORE_DEBUG
lastwrite_cyc_d[lwp_cyc++&15] = d; lastwrite_cyc_d[lwp_cyc++&15] = d;
#endif #endif
@ -534,7 +530,7 @@ static unsigned int m68k_read_8 (unsigned int a, int do_fake) {
a&=0xffffff; a&=0xffffff;
if(PicoMCD&1) return m68k_read_pcrelative_CD8(a); if(PicoMCD&1) return m68k_read_pcrelative_CD8(a);
if(a<Pico.romsize) return *(u8 *)(Pico.rom+(a^1)); // Rom if(a<Pico.romsize) return *(u8 *)(Pico.rom+(a^1)); // Rom
#ifdef EMU_C68K #ifdef EMU_CORE_DEBUG
if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15]; if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
#endif #endif
if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram
@ -544,7 +540,7 @@ static unsigned int m68k_read_16(unsigned int a, int do_fake) {
a&=0xffffff; a&=0xffffff;
if(PicoMCD&1) return m68k_read_pcrelative_CD16(a); if(PicoMCD&1) return m68k_read_pcrelative_CD16(a);
if(a<Pico.romsize) return *(u16 *)(Pico.rom+(a&~1)); // Rom if(a<Pico.romsize) return *(u16 *)(Pico.rom+(a&~1)); // Rom
#ifdef EMU_C68K #ifdef EMU_CORE_DEBUG
if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15]; if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
#endif #endif
if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram
@ -554,7 +550,7 @@ static unsigned int m68k_read_32(unsigned int a, int do_fake) {
a&=0xffffff; a&=0xffffff;
if(PicoMCD&1) return m68k_read_pcrelative_CD32(a); if(PicoMCD&1) return m68k_read_pcrelative_CD32(a);
if(a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+(a&~1)); return (pm[0]<<16)|pm[1]; } if(a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+(a&~1)); return (pm[0]<<16)|pm[1]; }
#ifdef EMU_C68K #ifdef EMU_CORE_DEBUG
if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15]; if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
#endif #endif
if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram
@ -570,7 +566,7 @@ unsigned int m68k_read_disassembler_8 (unsigned int a) { return m68k_read_8 (a,
unsigned int m68k_read_disassembler_16(unsigned int a) { return m68k_read_16(a, 0); } unsigned int m68k_read_disassembler_16(unsigned int a) { return m68k_read_16(a, 0); }
unsigned int m68k_read_disassembler_32(unsigned int a) { return m68k_read_32(a, 0); } unsigned int m68k_read_disassembler_32(unsigned int a) { return m68k_read_32(a, 0); }
#ifdef EMU_C68K #ifdef EMU_CORE_DEBUG
// ROM only // ROM only
unsigned int m68k_read_memory_8(unsigned int a) unsigned int m68k_read_memory_8(unsigned int a)
{ {
@ -658,10 +654,14 @@ PICO_INTERNAL unsigned char z80_read(unsigned short a)
{ {
u8 ret = 0; u8 ret = 0;
#ifndef _USE_DRZ80
if (a<0x4000) return Pico.zram[a&0x1fff];
#endif
if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald) if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)
{ {
if(PicoOpt&1) ret = (u8) YM2612Read(); if (PicoOpt&1) ret = (u8) YM2612Read();
goto end; return ret;
} }
if (a>=0x8000) if (a>=0x8000)
@ -672,15 +672,15 @@ PICO_INTERNAL unsigned char z80_read(unsigned short a)
ret = (u8) PicoRead8(addr68k); ret = (u8) PicoRead8(addr68k);
elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret); elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret);
goto end; return ret;
} }
#ifdef _USE_DRZ80
// should not be needed || dprintf("z80_read RAM"); // should not be needed || dprintf("z80_read RAM");
if (a<0x4000) { ret = (u8) Pico.zram[a&0x1fff]; goto end; } if (a<0x4000) return Pico.zram[a&0x1fff];
#endif
elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, ret); elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, ret);
end:
return ret; return ret;
} }
@ -690,8 +690,9 @@ PICO_INTERNAL_ASM void z80_write(unsigned char data, unsigned short a)
PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data) PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data)
#endif #endif
{ {
//if (a<0x4000) #ifndef _USE_DRZ80
// dprintf("z80 w8 : %06x, %02x @%04x", a, data, mz80GetRegisterValue(NULL, 0)); if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }
#endif
if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald) if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)
{ {
@ -723,8 +724,10 @@ PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data)
return; return;
} }
#ifdef _USE_DRZ80
// should not be needed, drZ80 knows how to access RAM itself || dprintf("z80_write RAM @ %08x", lr); // should not be needed, drZ80 knows how to access RAM itself || dprintf("z80_write RAM @ %08x", lr);
if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; } if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }
#endif
elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data); elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data);
} }
@ -732,15 +735,11 @@ PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data)
#ifndef _USE_CZ80 #ifndef _USE_CZ80
PICO_INTERNAL unsigned short z80_read16(unsigned short a) PICO_INTERNAL unsigned short z80_read16(unsigned short a)
{ {
//dprintf("z80_read16");
return (u16) ( (u16)z80_read(a) | ((u16)z80_read((u16)(a+1))<<8) ); return (u16) ( (u16)z80_read(a) | ((u16)z80_read((u16)(a+1))<<8) );
} }
PICO_INTERNAL void z80_write16(unsigned short data, unsigned short a) PICO_INTERNAL void z80_write16(unsigned short data, unsigned short a)
{ {
//dprintf("z80_write16");
z80_write((unsigned char) data,a); z80_write((unsigned char) data,a);
z80_write((unsigned char)(data>>8),(u16)(a+1)); z80_write((unsigned char)(data>>8),(u16)(a+1));
} }

View file

@ -202,11 +202,9 @@ static __inline void SekRunM68k(int cyc)
{ {
int cyc_do; int cyc_do;
SekCycleAim+=cyc; SekCycleAim+=cyc;
//printf("aim: %i, cnt: %i\n", SekCycleAim, SekCycleCnt);
if((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return; if((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return;
//printf("cyc_do: %i\n", cyc_do); #if defined(EMU_CORE_DEBUG)
#if defined(EMU_C68K) && defined(EMU_M68K) // this means we do run-compare
// 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)
PicoCpuCM68k.cycles=cyc_do; PicoCpuCM68k.cycles=cyc_do;
@ -215,7 +213,7 @@ static __inline void SekRunM68k(int cyc)
#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)
SekCycleCnt+=m68k_emulate(cyc_do); SekCycleCnt+=fm68k_emulate(cyc_do+1);
#endif #endif
} }
@ -223,8 +221,7 @@ static __inline void SekStep(void)
{ {
// this is required for timing sensitive stuff to work // this is required for timing sensitive stuff to work
int realaim=SekCycleAim; SekCycleAim=SekCycleCnt+1; int realaim=SekCycleAim; SekCycleAim=SekCycleCnt+1;
#if defined(EMU_C68K) && defined(EMU_M68K) #if defined(EMU_CORE_DEBUG)
// 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)
PicoCpuCM68k.cycles=1; PicoCpuCM68k.cycles=1;
@ -233,7 +230,7 @@ static __inline void SekStep(void)
#elif defined(EMU_M68K) #elif defined(EMU_M68K)
SekCycleCnt+=m68k_execute(1); SekCycleCnt+=m68k_execute(1);
#elif defined(EMU_F68K) #elif defined(EMU_F68K)
SekCycleCnt+=m68k_emulate(1); SekCycleCnt+=fm68k_emulate(1);
#endif #endif
SekCycleAim=realaim; SekCycleAim=realaim;
} }

View file

@ -54,10 +54,20 @@
static int PicoFrameHints(void) static int PicoFrameHints(void)
{ {
struct PicoVideo *pv=&Pico.video; struct PicoVideo *pv=&Pico.video;
int lines,y,lines_vis = 224,total_z80 = 0,z80CycleAim = 0,line_sample; int lines, y, lines_vis = 224, total_z80 = 0, z80CycleAim = 0, line_sample, skip;
int skip=PicoSkipFrame || (PicoOpt&0x10);
int hint; // Hint counter int hint; // Hint counter
if ((PicoOpt&0x10) && !PicoSkipFrame) {
// draw a frame just after vblank in alternative render mode
// yes, this will cause 1 frame lag, but this is inaccurate mode anyway.
PicoFrameFull();
#ifdef DRAW_FINISH_FUNC
DRAW_FINISH_FUNC();
#endif
skip = 1;
}
else skip=PicoSkipFrame;
if (Pico.m.pal) { if (Pico.m.pal) {
//cycles_68k = (int) ((double) OSC_PAL / 7 / 50 / 312 + 0.4); // should compile to a constant (488) //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 //cycles_z80 = (int) ((double) OSC_PAL / 15 / 50 / 312 + 0.4); // 228
@ -140,7 +150,8 @@ static int PicoFrameHints(void)
} }
#ifdef DRAW_FINISH_FUNC #ifdef DRAW_FINISH_FUNC
DRAW_FINISH_FUNC(); if (!skip)
DRAW_FINISH_FUNC();
#endif #endif
// V-int line (224 or 240) // V-int line (224 or 240)
@ -223,10 +234,6 @@ static int PicoFrameHints(void)
#endif #endif
} }
// draw a frame just after vblank in alternative render mode
if (!PicoSkipFrame && (PicoOpt&0x10))
PicoFrameFull();
return 0; return 0;
} }

View file

@ -48,6 +48,10 @@ extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
#define SekPcS68k (PicoCpuCS68k.pc-PicoCpuCS68k.membase) #define SekPcS68k (PicoCpuCS68k.pc-PicoCpuCS68k.membase)
#define SekSetStop(x) { PicoCpuCM68k.state_flags&=~1; if (x) { PicoCpuCM68k.state_flags|=1; PicoCpuCM68k.cycles=0; } } #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; } } #define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }
#define SekShouldInterrupt (PicoCpuCM68k.irq > (PicoCpuCM68k.srh&7))
#ifdef EMU_M68K
#define EMU_CORE_DEBUG
#endif
#endif #endif
#ifdef EMU_F68K #ifdef EMU_F68K
@ -62,16 +66,20 @@ M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
#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(&PicoCpuFM68k) #define SekPc fm68k_get_pc(&PicoCpuFM68k)
#define SekPcS68k m68k_get_pc(&PicoCpuFS68k) #define SekPcS68k fm68k_get_pc(&PicoCpuFS68k)
#define SekSetStop(x) { \ #define SekSetStop(x) { \
PicoCpuFM68k.execinfo &= ~M68K_HALTED; \ PicoCpuFM68k.execinfo &= ~FM68K_HALTED; \
if (x) { PicoCpuFM68k.execinfo |= M68K_HALTED; PicoCpuFM68k.io_cycle_counter = 0; } \ if (x) { PicoCpuFM68k.execinfo |= FM68K_HALTED; PicoCpuFM68k.io_cycle_counter = 0; } \
} }
#define SekSetStopS68k(x) { \ #define SekSetStopS68k(x) { \
PicoCpuFS68k.execinfo &= ~M68K_HALTED; \ PicoCpuFS68k.execinfo &= ~FM68K_HALTED; \
if (x) { PicoCpuFS68k.execinfo |= M68K_HALTED; PicoCpuFS68k.io_cycle_counter = 0; } \ if (x) { PicoCpuFS68k.execinfo |= FM68K_HALTED; PicoCpuFS68k.io_cycle_counter = 0; } \
} }
#define SekShouldInterrupt fm68k_would_interrupt()
#ifdef EMU_M68K
#define EMU_CORE_DEBUG
#endif
#endif #endif
#ifdef EMU_M68K #ifdef EMU_M68K
@ -97,6 +105,7 @@ extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k;
if(x) { SET_CYCLES(0); PicoCpuMS68k.stopped=STOP_LEVEL_STOP; } \ if(x) { SET_CYCLES(0); PicoCpuMS68k.stopped=STOP_LEVEL_STOP; } \
else PicoCpuMS68k.stopped=0; \ else PicoCpuMS68k.stopped=0; \
} }
#define SekShouldInterrupt (CPU_INT_LEVEL > FLAG_INT_MASK)
#endif #endif
#endif #endif
@ -128,8 +137,7 @@ extern int SekCycleAimS68k;
} }
#define SekCyclesDoneS68k() (SekCycleAimS68k-SekCyclesLeftS68k) #define SekCyclesDoneS68k() (SekCycleAimS68k-SekCyclesLeftS68k)
// debug cyclone #ifdef EMU_CORE_DEBUG
#if defined(EMU_C68K) && defined(EMU_M68K)
#undef SekSetCyclesLeftNoMCD #undef SekSetCyclesLeftNoMCD
#undef SekSetCyclesLeft #undef SekSetCyclesLeft
#undef SekCyclesBurn #undef SekCyclesBurn
@ -304,6 +312,9 @@ PICO_INTERNAL int PicoCdLoadState(void *file);
// Cart.c // Cart.c
PICO_INTERNAL void PicoCartDetect(void); PICO_INTERNAL void PicoCartDetect(void);
// Debug.c
int CM_compareRun(int cyc);
// Draw.c // Draw.c
PICO_INTERNAL int PicoLine(int scan); PICO_INTERNAL int PicoLine(int scan);
PICO_INTERNAL void PicoFrameStart(void); PICO_INTERNAL void PicoFrameStart(void);

View file

@ -104,6 +104,7 @@ PICO_INTERNAL int SekInit()
PicoCpuCM68k.IrqCallback=SekIntAck; PicoCpuCM68k.IrqCallback=SekIntAck;
PicoCpuCM68k.ResetCallback=SekResetAck; PicoCpuCM68k.ResetCallback=SekResetAck;
PicoCpuCM68k.UnrecognizedCallback=SekUnrecognizedOpcode; PicoCpuCM68k.UnrecognizedCallback=SekUnrecognizedOpcode;
PicoCpuCM68k.flags=4; // Z set
#endif #endif
#ifdef EMU_M68K #ifdef EMU_M68K
{ {
@ -122,7 +123,7 @@ PICO_INTERNAL int SekInit()
void *oldcontext = g_m68kcontext; void *oldcontext = g_m68kcontext;
g_m68kcontext = &PicoCpuFM68k; g_m68kcontext = &PicoCpuFM68k;
memset(&PicoCpuFM68k, 0, sizeof(PicoCpuFM68k)); memset(&PicoCpuFM68k, 0, sizeof(PicoCpuFM68k));
m68k_init(); fm68k_init();
PicoCpuFM68k.iack_handler = SekIntAckF68K; PicoCpuFM68k.iack_handler = SekIntAckF68K;
g_m68kcontext = oldcontext; g_m68kcontext = oldcontext;
} }
@ -141,7 +142,6 @@ PICO_INTERNAL int SekReset()
PicoCpuCM68k.state_flags=0; PicoCpuCM68k.state_flags=0;
PicoCpuCM68k.osp=0; PicoCpuCM68k.osp=0;
PicoCpuCM68k.srh =0x27; // Supervisor mode PicoCpuCM68k.srh =0x27; // Supervisor mode
PicoCpuCM68k.flags=4; // Z set
PicoCpuCM68k.irq=0; PicoCpuCM68k.irq=0;
PicoCpuCM68k.a[7]=PicoCpuCM68k.read32(0); // Stack Pointer PicoCpuCM68k.a[7]=PicoCpuCM68k.read32(0); // Stack Pointer
PicoCpuCM68k.membase=0; PicoCpuCM68k.membase=0;
@ -156,7 +156,7 @@ PICO_INTERNAL int SekReset()
#ifdef EMU_F68K #ifdef EMU_F68K
{ {
g_m68kcontext = &PicoCpuFM68k; g_m68kcontext = &PicoCpuFM68k;
m68k_reset(); fm68k_reset();
} }
#endif #endif
@ -166,7 +166,7 @@ PICO_INTERNAL int SekReset()
PICO_INTERNAL int SekInterrupt(int irq) PICO_INTERNAL int SekInterrupt(int irq)
{ {
#if defined(EMU_C68K) && defined(EMU_M68K) #ifdef EMU_CORE_DEBUG
{ {
extern unsigned int dbg_irq_level; extern unsigned int dbg_irq_level;
dbg_irq_level=irq; dbg_irq_level=irq;
@ -195,9 +195,9 @@ PICO_INTERNAL int SekInterrupt(int irq)
PICO_INTERNAL void SekState(int *data) PICO_INTERNAL void SekState(int *data)
{ {
#ifdef EMU_C68K #ifdef EMU_C68K
memcpy32(data,PicoCpuCM68k.d,0x44/4); memcpy32(data,(int *)PicoCpuCM68k.d,0x44/4);
#elif defined(EMU_M68K) #elif defined(EMU_M68K)
memcpy32(data, PicoCpuMM68k.dar, 0x40/4); memcpy32(data, (int *)PicoCpuMM68k.dar, 0x40/4);
data[0x10] = PicoCpuMM68k.pc; data[0x10] = PicoCpuMM68k.pc;
#elif defined(EMU_F68K) #elif defined(EMU_F68K)
memcpy32(data, (int *)PicoCpuFM68k.dreg, 0x40/4); memcpy32(data, (int *)PicoCpuFM68k.dreg, 0x40/4);

View file

@ -129,7 +129,7 @@ static void DmaSlow(int len)
pd=(u16 *)(prg_ram+(source&0x1fffe)); pd=(u16 *)(prg_ram+(source&0x1fffe));
pdend=(u16 *)(prg_ram+0x20000); pdend=(u16 *)(prg_ram+0x20000);
} else { } else {
elprintf(EL_VDPDMA|EL_ANOMALY, "DmaSlow FIXME: unsupported src"); elprintf(EL_VDPDMA|EL_ANOMALY, "DmaSlow[%i] %06x->%04x: FIXME: unsupported src", Pico.video.type, source, a);
return; return;
} }
} else { } else {
@ -137,7 +137,7 @@ static void DmaSlow(int len)
pd=(u16 *)(Pico.rom+(source&~1)); pd=(u16 *)(Pico.rom+(source&~1));
pdend=(u16 *)(Pico.rom+Pico.romsize); pdend=(u16 *)(Pico.rom+Pico.romsize);
} else { } else {
elprintf(EL_VDPDMA|EL_ANOMALY, "DmaSlow: invalid dma src"); elprintf(EL_VDPDMA|EL_ANOMALY, "DmaSlow[%i] %06x->%04x: invalid src", Pico.video.type, source, a);
return; return;
} }
} }
@ -374,29 +374,24 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
//if(num==01) dprintf("set_blank: %i @ %06x [%i|%i]", !((d&0x40)>>6), SekPc, Pico.m.scanline, SekCyclesDone()); //if(num==01) dprintf("set_blank: %i @ %06x [%i|%i]", !((d&0x40)>>6), SekPc, Pico.m.scanline, SekCyclesDone());
//if(num==10) dprintf("hint_set: %i @ %06x [%i|%i]", (unsigned char)d, SekPc, Pico.m.scanline, SekCyclesDone()); //if(num==10) dprintf("hint_set: %i @ %06x [%i|%i]", (unsigned char)d, SekPc, Pico.m.scanline, SekCyclesDone());
pvid->reg[num]=(unsigned char)d; pvid->reg[num]=(unsigned char)d;
#if !(defined(EMU_C68K) && defined(EMU_M68K)) // not debugging Cyclone #ifndef EMU_CORE_DEBUG
// update IRQ level (Lemmings, Wiz 'n' Liz intro, ... ) // update IRQ level (Lemmings, Wiz 'n' Liz intro, ... )
// may break if done improperly: // may break if done improperly:
// International Superstar Soccer Deluxe (crash), Street Racer (logos), Burning Force (gfx), // International Superstar Soccer Deluxe (crash), Street Racer (logos), Burning Force (gfx),
// Fatal Rewind (hang), Sesame Street Counting Cafe // Fatal Rewind (crash), Sesame Street Counting Cafe
if(num < 2) { 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 (!SekShouldInterrupt) // hack
if (PicoCpuCM68k.irq <= (PicoCpuCM68k.srh&7)) { {
#endif int lines, pints, irq=0;
int lines, pints;
lines = (pvid->reg[1] & 0x20) | (pvid->reg[0] & 0x10); lines = (pvid->reg[1] & 0x20) | (pvid->reg[0] & 0x10);
pints = (pvid->pending_ints&lines); pints = (pvid->pending_ints&lines);
if(pints & 0x20) SekInterrupt(6); if(pints & 0x20) irq = 6;
else if(pints & 0x10) SekInterrupt(4); else if(pints & 0x10) irq = 4;
else SekInterrupt(0); SekInterrupt(irq); // update line
#ifdef EMU_C68K
// adjust cycles for Cyclone so it would take the int "in time" if (irq) SekEndRun(24); // make it delayed
if(PicoCpuCM68k.irq) {
SekEndRun(24);
}
} }
#endif
} }
else else
#endif #endif

View file

@ -97,7 +97,7 @@ static __inline void SekRunM68k(int cyc)
SekCycleCnt+=m68k_execute(cyc_do); SekCycleCnt+=m68k_execute(cyc_do);
#elif defined(EMU_F68K) #elif defined(EMU_F68K)
g_m68kcontext=&PicoCpuFM68k; g_m68kcontext=&PicoCpuFM68k;
SekCycleCnt+=m68k_emulate(cyc_do); SekCycleCnt+=fm68k_emulate(cyc_do);
#endif #endif
} }
@ -115,7 +115,7 @@ static __inline void SekRunS68k(int cyc)
SekCycleCntS68k+=m68k_execute(cyc_do); SekCycleCntS68k+=m68k_execute(cyc_do);
#elif defined(EMU_F68K) #elif defined(EMU_F68K)
g_m68kcontext=&PicoCpuFS68k; g_m68kcontext=&PicoCpuFS68k;
SekCycleCntS68k+=m68k_emulate(cyc_do); SekCycleCntS68k+=fm68k_emulate(cyc_do);
#endif #endif
} }
@ -148,7 +148,7 @@ static __inline void SekRunPS(int cyc_m68k, int cyc_s68k)
SekCycleCnt += m68k_execute(cyc_do); SekCycleCnt += m68k_execute(cyc_do);
#elif defined(EMU_F68K) #elif defined(EMU_F68K)
g_m68kcontext = &PicoCpuFM68k; g_m68kcontext = &PicoCpuFM68k;
SekCycleCnt += m68k_emulate(cyc_do); SekCycleCnt += fm68k_emulate(cyc_do);
#endif #endif
} }
if ((cyc_do = SekCycleAimS68k-SekCycleCntS68k-cycn_s68k) > 0) { if ((cyc_do = SekCycleAimS68k-SekCycleCntS68k-cycn_s68k) > 0) {
@ -161,7 +161,7 @@ static __inline void SekRunPS(int cyc_m68k, int cyc_s68k)
SekCycleCntS68k += m68k_execute(cyc_do); SekCycleCntS68k += m68k_execute(cyc_do);
#elif defined(EMU_F68K) #elif defined(EMU_F68K)
g_m68kcontext = &PicoCpuFS68k; g_m68kcontext = &PicoCpuFS68k;
SekCycleCntS68k += m68k_emulate(cyc_do); SekCycleCntS68k += fm68k_emulate(cyc_do);
#endif #endif
} }
} }

View file

@ -1,4 +1,4 @@
// (c) Copyright 2006 notaz, All rights reserved. // (c) Copyright 2007 notaz, All rights reserved.
#include "../PicoInt.h" #include "../PicoInt.h"
@ -107,7 +107,7 @@ PICO_INTERNAL int SekInitS68k()
void *oldcontext = g_m68kcontext; void *oldcontext = g_m68kcontext;
g_m68kcontext = &PicoCpuFS68k; g_m68kcontext = &PicoCpuFS68k;
memset(&PicoCpuFS68k, 0, sizeof(PicoCpuFS68k)); memset(&PicoCpuFS68k, 0, sizeof(PicoCpuFS68k));
m68k_init(); fm68k_init();
PicoCpuFS68k.iack_handler = SekIntAckFS68k; PicoCpuFS68k.iack_handler = SekIntAckFS68k;
g_m68kcontext = oldcontext; g_m68kcontext = oldcontext;
} }
@ -146,7 +146,7 @@ PICO_INTERNAL int SekResetS68k()
{ {
void *oldcontext = g_m68kcontext; void *oldcontext = g_m68kcontext;
g_m68kcontext = &PicoCpuFS68k; g_m68kcontext = &PicoCpuFS68k;
m68k_reset(); fm68k_reset();
g_m68kcontext = oldcontext; g_m68kcontext = oldcontext;
} }
#endif #endif

View file

@ -444,7 +444,6 @@ PICO_INTERNAL void z80_pack(unsigned char *data)
#elif defined(_USE_CZ80) #elif defined(_USE_CZ80)
*(int *)data = 0x00007a43; // "Cz" *(int *)data = 0x00007a43; // "Cz"
memcpy(data+4, &CZ80, (INT32)&CZ80.BasePC - (INT32)&CZ80); memcpy(data+4, &CZ80, (INT32)&CZ80.BasePC - (INT32)&CZ80);
printf("size: %i (%x)\n", (INT32)&CZ80.BasePC - (INT32)&CZ80, (INT32)&CZ80.BasePC - (INT32)&CZ80); // FIXME rm
#endif #endif
} }

View file

@ -18,13 +18,13 @@ extern "C" {
#define M68K_FETCHBANK1 (1 << FAMEC_FETCHBITS) #define M68K_FETCHBANK1 (1 << FAMEC_FETCHBITS)
//#define M68K_RUNNING 0x01 //#define M68K_RUNNING 0x01
#define M68K_HALTED 0x80 #define FM68K_HALTED 0x80
#define M68K_WAITING 0x04 //#define M68K_WAITING 0x04
#define M68K_DISABLE 0x20 //#define M68K_DISABLE 0x20
#define M68K_FAULTED 0x40 //#define M68K_FAULTED 0x40
#define M68K_EMULATE_GROUP_0 0x02 #define FM68K_EMULATE_GROUP_0 0x02
#define M68K_EMULATE_TRACE 0x08 #define FM68K_EMULATE_TRACE 0x08
#define M68K_DO_TRACE 0x10 #define FM68K_DO_TRACE 0x10
/************************************/ /************************************/
@ -92,29 +92,6 @@ extern "C" {
/* Data definition */ /* Data definition */
/*******************/ /*******************/
/* M68K registers */
typedef enum {
M68K_REG_D0=0,
M68K_REG_D1,
M68K_REG_D2,
M68K_REG_D3,
M68K_REG_D4,
M68K_REG_D5,
M68K_REG_D6,
M68K_REG_D7,
M68K_REG_A0,
M68K_REG_A1,
M68K_REG_A2,
M68K_REG_A3,
M68K_REG_A4,
M68K_REG_A5,
M68K_REG_A6,
M68K_REG_A7,
M68K_REG_ASP,
M68K_REG_PC,
M68K_REG_SR
} m68k_register;
typedef union typedef union
{ {
unsigned char B; unsigned char B;
@ -155,13 +132,12 @@ extern M68K_CONTEXT *g_m68kcontext;
/************************/ /************************/
/* General purpose functions */ /* General purpose functions */
void m68k_init(void); void fm68k_init(void);
int m68k_reset(void); int fm68k_reset(void);
int m68k_emulate(int n); int fm68k_emulate(int n);
int fm68k_would_interrupt(void); // to be called from fm68k_emulate()
unsigned m68k_get_pc(M68K_CONTEXT *context); unsigned fm68k_get_pc(M68K_CONTEXT *context);
unsigned m68k_get_register(M68K_CONTEXT *context, m68k_register reg);
unsigned m68k_set_register(M68K_CONTEXT *context, m68k_register reg, unsigned value);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -481,7 +481,7 @@ static u32 flag_I;
if ((_PC_)&1) \ if ((_PC_)&1) \
{ \ { \
u32 pr_PC=GET_PC; \ u32 pr_PC=GET_PC; \
m68kcontext.execinfo |= M68K_EMULATE_GROUP_0; \ m68kcontext.execinfo |= FM68K_EMULATE_GROUP_0; \
execute_exception_group_0(M68K_ADDRESS_ERROR_EX, 0, pr_PC, 0x12 ); \ execute_exception_group_0(M68K_ADDRESS_ERROR_EX, 0, pr_PC, 0x12 ); \
CHECK_BRANCH_EXCEPTION_GOTO_END \ CHECK_BRANCH_EXCEPTION_GOTO_END \
} }
@ -602,14 +602,14 @@ static const s32 exception_cycle_table[256] =
/* Debe ser llamado para inicializar la tabla de saltos de instruccion */ /* Debe ser llamado para inicializar la tabla de saltos de instruccion */
/* No recibe parametros y no devuelve nada */ /* No recibe parametros y no devuelve nada */
/***************************************************************************/ /***************************************************************************/
void m68k_init(void) void fm68k_init(void)
{ {
#ifdef FAMEC_DEBUG #ifdef FAMEC_DEBUG
puts("Initializing FAME..."); puts("Initializing FAME...");
#endif #endif
if (!initialised) if (!initialised)
m68k_emulate(0); fm68k_emulate(0);
#ifdef FAMEC_DEBUG #ifdef FAMEC_DEBUG
puts("FAME initialized."); puts("FAME initialized.");
@ -625,17 +625,17 @@ void m68k_init(void)
/* M68K_NO_SUP_ADDR_SPACE (2): No se puede resetear porque no hay mapa */ /* M68K_NO_SUP_ADDR_SPACE (2): No se puede resetear porque no hay mapa */
/* de memoria supervisor de extraccion de opcodes */ /* de memoria supervisor de extraccion de opcodes */
/******************************************************************************/ /******************************************************************************/
int m68k_reset(void) int fm68k_reset(void)
{ {
if (!initialised) if (!initialised)
m68k_emulate(0); fm68k_emulate(0);
// Si la CPU esta en ejecucion, salir con M68K_RUNNING // Si la CPU esta en ejecucion, salir con M68K_RUNNING
if (m68kcontext.execinfo & M68K_RUNNING) if (m68kcontext.execinfo & M68K_RUNNING)
return M68K_RUNNING; return M68K_RUNNING;
// Resetear registros // Resetear registros
memset(&m68kcontext.dreg[0], 0, 16*4); //memset(&m68kcontext.dreg[0], 0, 16*4);
// Resetear interrupts, execinfo y ASP // Resetear interrupts, execinfo y ASP
m68kcontext.interrupts[0] = 0; m68kcontext.interrupts[0] = 0;
@ -643,7 +643,7 @@ int m68k_reset(void)
ASP = 0; ASP = 0;
// Fijar registro de estado // Fijar registro de estado
m68kcontext.sr = 0x2700; m68kcontext.sr = (m68kcontext.sr & 0xff) | 0x2700;
// Obtener puntero de pila inicial y PC // Obtener puntero de pila inicial y PC
AREG(7) = m68kcontext.read_long(0); AREG(7) = m68kcontext.read_long(0);
@ -663,138 +663,12 @@ int m68k_reset(void)
/* No recibe parametros */ /* No recibe parametros */
/* Retorna 68k PC */ /* Retorna 68k PC */
/****************************************************************************/ /****************************************************************************/
u32 m68k_get_pc(M68K_CONTEXT *context) u32 fm68k_get_pc(M68K_CONTEXT *context)
{ {
return (context->execinfo & M68K_RUNNING)?(u32)PC-BasePC:context->pc; return (context->execinfo & M68K_RUNNING)?(u32)PC-BasePC:context->pc;
} }
/***************************************************************************/
/* m68k_get_register(register) */
/* Parametro: Registro a obtener valor (indice) */
/* Retorno: Valor del registro requerido */
/* Observacion: En caso de que el indice no sea correcto */
/* la funcion devolvera -1 */
/***************************************************************************/
u32 m68k_get_register(M68K_CONTEXT *context, m68k_register reg)
{
M68K_CONTEXT *oldcontext = g_m68kcontext;
s32 ret;
g_m68kcontext = context;
switch (reg)
{
case M68K_REG_D0:
case M68K_REG_D1:
case M68K_REG_D2:
case M68K_REG_D3:
case M68K_REG_D4:
case M68K_REG_D5:
case M68K_REG_D6:
case M68K_REG_D7:
ret = DREG(reg - M68K_REG_D0);
break;
case M68K_REG_A0:
case M68K_REG_A1:
case M68K_REG_A2:
case M68K_REG_A3:
case M68K_REG_A4:
case M68K_REG_A5:
case M68K_REG_A6:
case M68K_REG_A7:
ret = AREG(reg - M68K_REG_A0);
break;
case M68K_REG_ASP:
ret = ASP;
break;
case M68K_REG_PC:
ret = m68k_get_pc(context);
break;
case M68K_REG_SR:
ret = m68kcontext.sr;
break;
default:
ret = M68K_INV_REG;
break;
}
g_m68kcontext = oldcontext;
return ret;
}
/***********************************************************************/
/* m68k_set_register(register,value) */
/* Parametros: Registro (indice) y valor a asignar */
/* Retorno: Exito de la operacion */
/* 0 La operacion se ha realizado satisfactoriamente */
/* 1 El indice del registro no es valido (fuera de limites) */
/***********************************************************************/
u32 m68k_set_register(M68K_CONTEXT *context, m68k_register reg, u32 value)
{
M68K_CONTEXT *oldcontext = g_m68kcontext;
s32 ret = M68K_OK;
g_m68kcontext = context;
switch (reg)
{
case M68K_REG_D0:
case M68K_REG_D1:
case M68K_REG_D2:
case M68K_REG_D3:
case M68K_REG_D4:
case M68K_REG_D5:
case M68K_REG_D6:
case M68K_REG_D7:
DREG(reg - M68K_REG_D0) = value;
break;
case M68K_REG_A0:
case M68K_REG_A1:
case M68K_REG_A2:
case M68K_REG_A3:
case M68K_REG_A4:
case M68K_REG_A5:
case M68K_REG_A6:
case M68K_REG_A7:
AREG(reg - M68K_REG_A0) = value;
break;
case M68K_REG_ASP:
ASP = value;
break;
case M68K_REG_PC:
if (m68kcontext.execinfo & M68K_RUNNING)
{
SET_PC(value & M68K_ADR_MASK);
}
else
{
m68kcontext.pc = value;
}
break;
case M68K_REG_SR:
m68kcontext.sr = value & 0xFFFF;
break;
default:
ret = M68K_INV_REG;
break;
}
g_m68kcontext = oldcontext;
return ret;
}
////////////////////////// //////////////////////////
// Chequea las interrupciones y las inicia // Chequea las interrupciones y las inicia
static FAMEC_EXTRA_INLINE s32 interrupt_chk__(void) static FAMEC_EXTRA_INLINE s32 interrupt_chk__(void)
@ -805,6 +679,10 @@ static FAMEC_EXTRA_INLINE s32 interrupt_chk__(void)
return 0; return 0;
} }
int fm68k_would_interrupt(void)
{
return interrupt_chk__();
}
static FAMEC_EXTRA_INLINE void execute_exception(s32 vect) static FAMEC_EXTRA_INLINE void execute_exception(s32 vect)
{ {
@ -839,7 +717,7 @@ static FAMEC_EXTRA_INLINE void execute_exception(s32 vect)
/* adjust SR */ /* adjust SR */
flag_S = M68K_SR_S; flag_S = M68K_SR_S;
newPC&=M68K_ADR_MASK; newPC&=M68K_ADR_MASK&~1; // don't crash on games with bad vector tables
SET_PC(newPC) SET_PC(newPC)
@ -873,7 +751,7 @@ static u32 Opcode;
// main exec function // main exec function
////////////////////// //////////////////////
int m68k_emulate(s32 cycles) int fm68k_emulate(s32 cycles)
{ {
if (!initialised) if (!initialised)
{ {
@ -885,16 +763,16 @@ int m68k_emulate(s32 cycles)
#endif #endif
} }
/* Comprobar si la CPU esta detenida debido a un doble error de bus */ // won't emulate double fault
if (m68kcontext.execinfo & M68K_FAULTED) return -1; // if (m68kcontext.execinfo & M68K_FAULTED) return -1;
if (m68kcontext.execinfo & M68K_HALTED) if (m68kcontext.execinfo & FM68K_HALTED)
{ {
if (interrupt_chk__() <= 0) if (interrupt_chk__() <= 0)
{ {
return cycles; return cycles;
} }
m68kcontext.execinfo &= ~M68K_HALTED; m68kcontext.execinfo &= ~FM68K_HALTED;
} }
#ifdef FAMEC_DEBUG #ifdef FAMEC_DEBUG
@ -923,7 +801,7 @@ int m68k_emulate(s32 cycles)
cycles_needed = 0; cycles_needed = 0;
#ifdef FAMEC_EMULATE_TRACE #ifdef FAMEC_EMULATE_TRACE
if (!(m68kcontext.execinfo & M68K_EMULATE_TRACE)) if (!(m68kcontext.execinfo & FM68K_EMULATE_TRACE))
#endif #endif
{ {
s32 line=interrupt_chk__(); s32 line=interrupt_chk__();
@ -937,12 +815,13 @@ int m68k_emulate(s32 cycles)
execute_exception(line + 0x18); execute_exception(line + 0x18);
flag_I = (u32)line; flag_I = (u32)line;
if (m68kcontext.io_cycle_counter <= 0) goto famec_End;
} }
#ifdef FAMEC_EMULATE_TRACE #ifdef FAMEC_EMULATE_TRACE
else else
if (flag_T) if (flag_T)
{ {
m68kcontext.execinfo |= M68K_EMULATE_TRACE; m68kcontext.execinfo |= FM68K_EMULATE_TRACE;
cycles_needed= m68kcontext.io_cycle_counter; cycles_needed= m68kcontext.io_cycle_counter;
m68kcontext.io_cycle_counter=0; m68kcontext.io_cycle_counter=0;
} }
@ -950,9 +829,9 @@ int m68k_emulate(s32 cycles)
} }
#ifndef FAMEC_NO_GOTOS //#ifndef FAMEC_NO_GOTOS
famec_Exec: famec_Exec:
#endif //#endif
#ifdef FAMEC_DEBUG #ifdef FAMEC_DEBUG
printf("Antes de NEXT... PC = %p\n", PC); printf("Antes de NEXT... PC = %p\n", PC);
@ -970,11 +849,11 @@ famec_Exec:
#endif #endif
#ifdef FAMEC_EMULATE_TRACE #ifdef FAMEC_EMULATE_TRACE
if (m68kcontext.execinfo & M68K_EMULATE_TRACE) if (m68kcontext.execinfo & FM68K_EMULATE_TRACE)
{ {
m68kcontext.io_cycle_counter= cycles_needed; m68kcontext.io_cycle_counter= cycles_needed;
m68kcontext.execinfo &= ~M68K_EMULATE_TRACE; m68kcontext.execinfo &= ~FM68K_EMULATE_TRACE;
m68kcontext.execinfo |= M68K_DO_TRACE; m68kcontext.execinfo |= FM68K_DO_TRACE;
execute_exception(M68K_TRACE_EX); execute_exception(M68K_TRACE_EX);
flag_T=0; flag_T=0;
if (m68kcontext.io_cycle_counter > 0) if (m68kcontext.io_cycle_counter > 0)
@ -984,7 +863,7 @@ famec_Exec:
} }
else else
#endif #endif
if (cycles_needed>0) if (cycles_needed != 0)
{ {
s32 line=interrupt_chk__(); s32 line=interrupt_chk__();
m68kcontext.io_cycle_counter= cycles_needed; m68kcontext.io_cycle_counter= cycles_needed;
@ -1003,10 +882,12 @@ famec_Exec:
#endif #endif
if (m68kcontext.io_cycle_counter > 0) if (m68kcontext.io_cycle_counter > 0)
{ {
NEXT //NEXT
goto famec_Exec;
} }
} }
famec_End:
m68kcontext.sr = GET_SR; m68kcontext.sr = GET_SR;
m68kcontext.pc = GET_PC; m68kcontext.pc = GET_PC;
@ -1032,6 +913,8 @@ init_jump_table:
#endif #endif
u32 i, j; u32 i, j;
m68kcontext.sr = 0x2704; // Z flag
for(i = 0x0000; i <= 0xFFFF; i += 0x0001) for(i = 0x0000; i <= 0xFFFF; i += 0x0001)
JumpTable[0x0000 + i] = CAST_OP(0x4AFC); JumpTable[0x0000 + i] = CAST_OP(0x4AFC);
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
@ -1542,6 +1425,7 @@ init_jump_table:
JumpTable[0x1EC0 + i] = CAST_OP(0x1EC0); JumpTable[0x1EC0 + i] = CAST_OP(0x1EC0);
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
JumpTable[0x1F00 + i] = CAST_OP(0x1F00); JumpTable[0x1F00 + i] = CAST_OP(0x1F00);
#if 0
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
for(j = 0x0000; j <= 0x0E00; j += 0x0200) for(j = 0x0000; j <= 0x0E00; j += 0x0200)
JumpTable[0x1008 + i + j] = CAST_OP(0x1008); JumpTable[0x1008 + i + j] = CAST_OP(0x1008);
@ -1568,6 +1452,7 @@ init_jump_table:
JumpTable[0x1EC8 + i] = CAST_OP(0x1EC8); JumpTable[0x1EC8 + i] = CAST_OP(0x1EC8);
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
JumpTable[0x1F08 + i] = CAST_OP(0x1F08); JumpTable[0x1F08 + i] = CAST_OP(0x1F08);
#endif
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
for(j = 0x0000; j <= 0x0E00; j += 0x0200) for(j = 0x0000; j <= 0x0E00; j += 0x0200)
JumpTable[0x1010 + i + j] = CAST_OP(0x1010); JumpTable[0x1010 + i + j] = CAST_OP(0x1010);
@ -3697,9 +3582,11 @@ init_jump_table:
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
for(j = 0x0000; j <= 0x0E00; j += 0x0200) for(j = 0x0000; j <= 0x0E00; j += 0x0200)
JumpTable[0x9000 + i + j] = CAST_OP(0x9000); JumpTable[0x9000 + i + j] = CAST_OP(0x9000);
#if 0
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
for(j = 0x0000; j <= 0x0E00; j += 0x0200) for(j = 0x0000; j <= 0x0E00; j += 0x0200)
JumpTable[0x9008 + i + j] = CAST_OP(0x9008); JumpTable[0x9008 + i + j] = CAST_OP(0x9008);
#endif
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
for(j = 0x0000; j <= 0x0E00; j += 0x0200) for(j = 0x0000; j <= 0x0E00; j += 0x0200)
JumpTable[0x9010 + i + j] = CAST_OP(0x9010); JumpTable[0x9010 + i + j] = CAST_OP(0x9010);
@ -3976,9 +3863,11 @@ init_jump_table:
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
for(j = 0x0000; j <= 0x0E00; j += 0x0200) for(j = 0x0000; j <= 0x0E00; j += 0x0200)
JumpTable[0xB000 + i + j] = CAST_OP(0xB000); JumpTable[0xB000 + i + j] = CAST_OP(0xB000);
#if 0
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
for(j = 0x0000; j <= 0x0E00; j += 0x0200) for(j = 0x0000; j <= 0x0E00; j += 0x0200)
JumpTable[0xB008 + i + j] = CAST_OP(0xB008); JumpTable[0xB008 + i + j] = CAST_OP(0xB008);
#endif
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
for(j = 0x0000; j <= 0x0E00; j += 0x0200) for(j = 0x0000; j <= 0x0E00; j += 0x0200)
JumpTable[0xB010 + i + j] = CAST_OP(0xB010); JumpTable[0xB010 + i + j] = CAST_OP(0xB010);
@ -4502,9 +4391,11 @@ init_jump_table:
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
for(j = 0x0000; j <= 0x0E00; j += 0x0200) for(j = 0x0000; j <= 0x0E00; j += 0x0200)
JumpTable[0xD000 + i + j] = CAST_OP(0xD000); JumpTable[0xD000 + i + j] = CAST_OP(0xD000);
#if 0
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
for(j = 0x0000; j <= 0x0E00; j += 0x0200) for(j = 0x0000; j <= 0x0E00; j += 0x0200)
JumpTable[0xD008 + i + j] = CAST_OP(0xD008); JumpTable[0xD008 + i + j] = CAST_OP(0xD008);
#endif
for(i = 0x0000; i <= 0x0007; i += 0x0001) for(i = 0x0000; i <= 0x0007; i += 0x0001)
for(j = 0x0000; j <= 0x0E00; j += 0x0200) for(j = 0x0000; j <= 0x0E00; j += 0x0200)
JumpTable[0xD010 + i + j] = CAST_OP(0xD010); JumpTable[0xD010 + i + j] = CAST_OP(0xD010);

View file

@ -1953,7 +1953,7 @@ OPCODE(0x0A7C)
u32 newPC = (u32)(PC) - BasePC; u32 newPC = (u32)(PC) - BasePC;
SET_PC(newPC-2); SET_PC(newPC-2);
execute_exception(M68K_PRIVILEGE_VIOLATION_EX); execute_exception(M68K_PRIVILEGE_VIOLATION_EX);
RET(4) RET(0)
} }
RET(20) RET(20)
} }
@ -5213,7 +5213,11 @@ OPCODE(0x0108)
READ_BYTE_F(adr + 2, src) READ_BYTE_F(adr + 2, src)
DREGu16((Opcode >> 9) & 7) = (res << 8) | src; DREGu16((Opcode >> 9) & 7) = (res << 8) | src;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(16)
#else
RET(24) RET(24)
#endif
} }
// MOVEPLaD // MOVEPLaD
@ -5237,7 +5241,11 @@ OPCODE(0x0148)
READ_BYTE_F(adr, src) READ_BYTE_F(adr, src)
DREG((Opcode >> 9) & 7) = res | src; DREG((Opcode >> 9) & 7) = res | src;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(24)
#else
RET(32) RET(32)
#endif
} }
// MOVEPWDa // MOVEPWDa
@ -5253,7 +5261,11 @@ OPCODE(0x0188)
WRITE_BYTE_F(adr + 0, res >> 8) WRITE_BYTE_F(adr + 0, res >> 8)
WRITE_BYTE_F(adr + 2, res >> 0) WRITE_BYTE_F(adr + 2, res >> 0)
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(16)
#else
RET(24) RET(24)
#endif
} }
// MOVEPLDa // MOVEPLDa
@ -5274,7 +5286,11 @@ OPCODE(0x01C8)
adr += 2; adr += 2;
WRITE_BYTE_F(adr, res >> 0) WRITE_BYTE_F(adr, res >> 0)
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(24)
#else
RET(32) RET(32)
#endif
} }
// MOVEB // MOVEB
@ -5460,6 +5476,7 @@ OPCODE(0x1F00)
RET(8) RET(8)
} }
#if 0
// MOVEB // MOVEB
OPCODE(0x1008) OPCODE(0x1008)
{ {
@ -5692,6 +5709,7 @@ OPCODE(0x1F08)
*/ */
RET(8) RET(8)
} }
#endif
// MOVEB // MOVEB
OPCODE(0x1010) OPCODE(0x1010)
@ -8279,7 +8297,7 @@ OPCODE(0x2F00)
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
PRE_IO PRE_IO
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(12) RET(12)
} }
@ -8462,7 +8480,7 @@ OPCODE(0x2F08)
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
PRE_IO PRE_IO
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(12) RET(12)
} }
@ -8657,7 +8675,7 @@ OPCODE(0x2F10)
flag_N = res >> 24; flag_N = res >> 24;
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(20) RET(20)
} }
@ -8862,7 +8880,7 @@ OPCODE(0x2F18)
flag_N = res >> 24; flag_N = res >> 24;
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(20) RET(20)
} }
@ -9067,7 +9085,7 @@ OPCODE(0x2F20)
flag_N = res >> 24; flag_N = res >> 24;
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(22) RET(22)
} }
@ -9272,7 +9290,7 @@ OPCODE(0x2F28)
flag_N = res >> 24; flag_N = res >> 24;
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(24) RET(24)
} }
@ -9477,7 +9495,7 @@ OPCODE(0x2F30)
flag_N = res >> 24; flag_N = res >> 24;
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(26) RET(26)
} }
@ -9672,7 +9690,7 @@ OPCODE(0x2F38)
flag_N = res >> 24; flag_N = res >> 24;
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(24) RET(24)
} }
@ -9867,7 +9885,7 @@ OPCODE(0x2F39)
flag_N = res >> 24; flag_N = res >> 24;
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(28) RET(28)
} }
@ -10072,7 +10090,7 @@ OPCODE(0x2F3A)
flag_N = res >> 24; flag_N = res >> 24;
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(24) RET(24)
} }
@ -10277,7 +10295,7 @@ OPCODE(0x2F3B)
flag_N = res >> 24; flag_N = res >> 24;
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(26) RET(26)
} }
@ -10460,7 +10478,7 @@ OPCODE(0x2F3C)
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
PRE_IO PRE_IO
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(20) RET(20)
} }
@ -10665,7 +10683,7 @@ OPCODE(0x2F1F)
flag_N = res >> 24; flag_N = res >> 24;
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(20) RET(20)
} }
@ -10870,7 +10888,7 @@ OPCODE(0x2F27)
flag_N = res >> 24; flag_N = res >> 24;
adr = AREG(7) - 4; adr = AREG(7) - 4;
AREG(7) = adr; AREG(7) = adr;
WRITE_LONG_F(adr, res) WRITE_LONG_DEC_F(adr, res)
POST_IO POST_IO
RET(22) RET(22)
} }
@ -18458,7 +18476,7 @@ OPCODE(0x4AFC)
u32 oldPC=GET_PC; u32 oldPC=GET_PC;
SET_PC(oldPC-2) SET_PC(oldPC-2)
execute_exception(M68K_ILLEGAL_INSTRUCTION_EX); execute_exception(M68K_ILLEGAL_INSTRUCTION_EX);
RET(4) RET(0)
} }
// ILLEGAL A000-AFFF // ILLEGAL A000-AFFF
@ -18467,7 +18485,7 @@ OPCODE(0xA000)
u32 oldPC=GET_PC; u32 oldPC=GET_PC;
SET_PC(oldPC-2) SET_PC(oldPC-2)
execute_exception(M68K_1010_EX); execute_exception(M68K_1010_EX);
RET(4) RET(0)
} }
// ILLEGAL F000-FFFF // ILLEGAL F000-FFFF
@ -18476,7 +18494,7 @@ OPCODE(0xF000)
u32 oldPC=GET_PC; u32 oldPC=GET_PC;
SET_PC(oldPC-2) SET_PC(oldPC-2)
execute_exception(M68K_1111_EX); execute_exception(M68K_1111_EX);
RET(4) RET(0) // 4 already taken by exc. handler
} }
// MOVEMaR // MOVEMaR
@ -19183,7 +19201,7 @@ OPCODE(0x4E72)
AREG(7) = ASP; AREG(7) = ASP;
ASP = res; ASP = res;
} }
m68kcontext.execinfo |= M68K_HALTED; m68kcontext.execinfo |= FM68K_HALTED;
m68kcontext.io_cycle_counter = 0; m68kcontext.io_cycle_counter = 0;
RET(4) RET(4)
} }
@ -19213,7 +19231,7 @@ OPCODE(0x4E73)
ASP = res; ASP = res;
} }
POST_IO POST_IO
m68kcontext.execinfo &= ~(M68K_EMULATE_GROUP_0|M68K_EMULATE_TRACE|M68K_DO_TRACE); m68kcontext.execinfo &= ~(FM68K_EMULATE_GROUP_0|FM68K_EMULATE_TRACE|FM68K_DO_TRACE);
CHECK_INT_TO_JUMP(20) CHECK_INT_TO_JUMP(20)
RET(20) RET(20)
} }
@ -23892,7 +23910,7 @@ OPCODE(0x5048)
dst = AREGu32((Opcode >> 0) & 7); dst = AREGu32((Opcode >> 0) & 7);
res = dst + src; res = dst + src;
AREG((Opcode >> 0) & 7) = res; AREG((Opcode >> 0) & 7) = res;
#ifdef USE_CYCLONE_TIMING_ // breaks Project-X #ifdef USE_CYCLONE_TIMING
RET(4) RET(4)
#else #else
RET(8) RET(8)
@ -28333,6 +28351,7 @@ RET(4)
} }
// SUBaD // SUBaD
#if 0
OPCODE(0x9008) OPCODE(0x9008)
{ {
u32 adr, res; u32 adr, res;
@ -28352,6 +28371,7 @@ OPCODE(0x9008)
*/ */
RET(4) RET(4)
} }
#endif
// SUBaD // SUBaD
OPCODE(0x9010) OPCODE(0x9010)
@ -30461,6 +30481,7 @@ RET(4)
} }
// CMP // CMP
#if 0
OPCODE(0xB008) OPCODE(0xB008)
{ {
u32 adr, res; u32 adr, res;
@ -30479,6 +30500,7 @@ OPCODE(0xB008)
*/ */
RET(4) RET(4)
} }
#endif
// CMP // CMP
OPCODE(0xB010) OPCODE(0xB010)
@ -34756,6 +34778,7 @@ RET(4)
} }
// ADDaD // ADDaD
#if 0
OPCODE(0xD008) OPCODE(0xD008)
{ {
u32 adr, res; u32 adr, res;
@ -34775,6 +34798,7 @@ OPCODE(0xD008)
*/ */
RET(4) RET(4)
} }
#endif
// ADDaD // ADDaD
OPCODE(0xD010) OPCODE(0xD010)
@ -36449,7 +36473,11 @@ OPCODE(0xD0D0)
res = dst + src; res = dst + src;
AREG((Opcode >> 9) & 7) = res; AREG((Opcode >> 9) & 7) = res;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(12)
#else
RET(10) RET(10)
#endif
} }
// ADDA // ADDA
@ -36466,7 +36494,11 @@ OPCODE(0xD0D8)
res = dst + src; res = dst + src;
AREG((Opcode >> 9) & 7) = res; AREG((Opcode >> 9) & 7) = res;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(12)
#else
RET(10) RET(10)
#endif
} }
// ADDA // ADDA
@ -36483,7 +36515,11 @@ OPCODE(0xD0E0)
res = dst + src; res = dst + src;
AREG((Opcode >> 9) & 7) = res; AREG((Opcode >> 9) & 7) = res;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(14)
#else
RET(12) RET(12)
#endif
} }
// ADDA // ADDA
@ -36500,7 +36536,11 @@ OPCODE(0xD0E8)
res = dst + src; res = dst + src;
AREG((Opcode >> 9) & 7) = res; AREG((Opcode >> 9) & 7) = res;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(16)
#else
RET(14) RET(14)
#endif
} }
// ADDA // ADDA
@ -36517,7 +36557,11 @@ OPCODE(0xD0F0)
res = dst + src; res = dst + src;
AREG((Opcode >> 9) & 7) = res; AREG((Opcode >> 9) & 7) = res;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(18)
#else
RET(16) RET(16)
#endif
} }
// ADDA // ADDA
@ -36533,7 +36577,11 @@ OPCODE(0xD0F8)
res = dst + src; res = dst + src;
AREG((Opcode >> 9) & 7) = res; AREG((Opcode >> 9) & 7) = res;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(16)
#else
RET(14) RET(14)
#endif
} }
// ADDA // ADDA
@ -36549,7 +36597,11 @@ OPCODE(0xD0F9)
res = dst + src; res = dst + src;
AREG((Opcode >> 9) & 7) = res; AREG((Opcode >> 9) & 7) = res;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(20)
#else
RET(18) RET(18)
#endif
} }
// ADDA // ADDA
@ -36566,7 +36618,11 @@ OPCODE(0xD0FA)
res = dst + src; res = dst + src;
AREG((Opcode >> 9) & 7) = res; AREG((Opcode >> 9) & 7) = res;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(16)
#else
RET(14) RET(14)
#endif
} }
// ADDA // ADDA
@ -36583,7 +36639,11 @@ OPCODE(0xD0FB)
res = dst + src; res = dst + src;
AREG((Opcode >> 9) & 7) = res; AREG((Opcode >> 9) & 7) = res;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(18)
#else
RET(16) RET(16)
#endif
} }
// ADDA // ADDA
@ -36613,7 +36673,11 @@ OPCODE(0xD0DF)
res = dst + src; res = dst + src;
AREG((Opcode >> 9) & 7) = res; AREG((Opcode >> 9) & 7) = res;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(12)
#else
RET(10) RET(10)
#endif
} }
// ADDA // ADDA
@ -36630,7 +36694,11 @@ OPCODE(0xD0E7)
res = dst + src; res = dst + src;
AREG((Opcode >> 9) & 7) = res; AREG((Opcode >> 9) & 7) = res;
POST_IO POST_IO
#ifdef USE_CYCLONE_TIMING
RET(14)
#else
RET(12) RET(12)
#endif
} }
// ADDA // ADDA

View file

@ -1,6 +1,7 @@
# settings # settings
#use_musashi = 1 #use_musashi = 1
use_fame = 1
#use_mz80 = 1 #use_mz80 = 1
# profile = 1 # profile = 1
@ -51,22 +52,26 @@ OBJS += ../../unzip/unzip.o ../../unzip/unzip_stream.o
ifeq "$(use_musashi)" "1" ifeq "$(use_musashi)" "1"
DEFINC += -DEMU_M68K DEFINC += -DEMU_M68K
OBJS += ../../cpu/musashi/m68kops.o ../../cpu/musashi/m68kcpu.o OBJS += ../../cpu/musashi/m68kops.o ../../cpu/musashi/m68kcpu.o
else endif
ifeq "$(use_fame)" "1"
DEFINC += -DEMU_F68K DEFINC += -DEMU_F68K
OBJS += ../../cpu/fame/famec.o OBJS += ../../cpu/fame/famec.o
endif endif
# z80 # z80
ifeq "$(use_mz80)" "1" ifeq "$(use_mz80)" "1"
CFLAGS += -D_USE_MZ80 DEFINC += -D_USE_MZ80
OBJS += ../../cpu/mz80/mz80.o OBJS += ../../cpu/mz80/mz80.o
else else
CFLAGS += -D_USE_CZ80 DEFINC += -D_USE_CZ80
OBJS += ../../cpu/cz80/cz80.o OBJS += ../../cpu/cz80/cz80.o
endif endif
# misc
# faked asm ifeq "$(use_fame)" "1"
#DEFINC += -D_ASM_DRAW_C ifeq "$(use_musashi)" "1"
#OBJS += fakedasm.o OBJS += ../../Pico/Debug.o
OBJS += ../../cpu/musashi/m68kdasm.o
endif
endif
all: PicoDrive all: PicoDrive
@ -78,8 +83,8 @@ tidy:
@make -C ../common/helix/ X86=1 clean @make -C ../common/helix/ X86=1 clean
PicoDrive : $(OBJS) ../common/helix/helix_mp3_x86.a PicoDrive : $(OBJS) ../common/helix/helix_mp3_x86.a
@echo $@ @echo ">>>" $@
@$(GCC) $(COPT) $^ $(LDFLAGS) -lm -lpng -Wl,-Map=PicoDrive.map -o $@ $(GCC) $(COPT) $^ $(LDFLAGS) -lm -lpng -Wl,-Map=PicoDrive.map -o $@
../../cpu/musashi/m68kops.c : ../../cpu/musashi/m68kops.c :
@ -96,18 +101,19 @@ PicoDrive : $(OBJS) ../common/helix/helix_mp3_x86.a
@make -C ../common/helix/ X86=1 clean all @make -C ../common/helix/ X86=1 clean all
.c.o: .c.o:
@echo $< @echo ">>>" $<
@$(GCC) $(COPT) $(DEFINC) -c $< -o $@ $(GCC) $(COPT) $(DEFINC) -c $< -o $@
.s.o: .s.o:
@echo $< @echo ">>>" $<
@$(GCC) $(COPT) $(DEFINC) -c $< -o $@ $(GCC) $(COPT) $(DEFINC) -c $< -o $@
../../Pico/sound/ym2612.o : ../../Pico/sound/ym2612.c ../../Pico/sound/ym2612.o : ../../Pico/sound/ym2612.c
@echo $@ @echo ">>>" $@
@$(GCC) $(COPT_COMMON) $(DEFINC) -c $< -o $@ # -mtune=arm940t -DEXTERNAL_YM2612 $(GCC) $(COPT_COMMON) $(DEFINC) -c $< -o $@
../../cpu/fame/famec.o : ../../cpu/fame/famec.c ../../cpu/fame/famec_opcodes.h
@echo ">>>" $<
$(GCC) $(COPT) $(DEFINC) -Wno-unused -c $< -o $@
../../cpu/fame/famec.o : ../../cpu/fame/famec.c
@echo $<
@$(GCC) $(COPT) $(DEFINC) -Wno-unused -c $< -o $@