From 3aa1e148a28da9b4e10e824984f7b3a4908b1ace Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 22 Oct 2007 20:38:41 +0000 Subject: [PATCH] FAME integration finished, some adjustments of CPU core stuff git-svn-id: file:///home/notaz/opt/svn/PicoDrive@278 be3aeb3a-fb24-0410-a615-afba39da0efa --- Pico/Area.c | 61 +- Pico/Memory.c | 48 +- Pico/Pico.c | 178 +- Pico/PicoInt.h | 57 +- Pico/Sek.c | 98 +- Pico/VideoPort.c | 4 +- Pico/_cyclone_debug.c | 58 +- Pico/cd/Area.c | 2 +- Pico/cd/Memory.c | 160 +- Pico/cd/Memory.s | 6 +- Pico/cd/Pico.c | 52 +- Pico/cd/Pico.s | 18 +- Pico/cd/Sek.c | 107 +- cpu/a68k/Makefile.win | 16 - cpu/a68k/cpuintrf.h | 1 - cpu/a68k/make68kd.c | 8192 ----------------------------------------- cpu/fame/fame.h | 15 - cpu/fame/famec.c | 29 - 18 files changed, 397 insertions(+), 8705 deletions(-) delete mode 100644 cpu/a68k/Makefile.win delete mode 100644 cpu/a68k/cpuintrf.h delete mode 100644 cpu/a68k/make68kd.c diff --git a/Pico/Area.c b/Pico/Area.c index e62274a..41ee68b 100644 --- a/Pico/Area.c +++ b/Pico/Area.c @@ -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,20 +80,10 @@ 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; - CycloneSetSr(context, *(unsigned int *)(cpu+0x44)); - context->osp=*(unsigned int *)(cpu+0x48); +#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); context->membase=0; context->pc = context->checkpc(*(unsigned int *)(cpu+0x40)); // Base pc @@ -105,11 +91,9 @@ PICO_INTERNAL int PicoAreaUnpackCpu(unsigned char *cpu, int is_sub) context->state_flags = 0; 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; } diff --git a/Pico/Memory.c b/Pico/Memory.c index b0aa7af..963d30b 100644 --- a/Pico/Memory.c +++ b/Pico/Memory.c @@ -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 } diff --git a/Pico/Pico.c b/Pico/Pico.c index b9fbfe6..ce3e340 100644 --- a/Pico/Pico.c +++ b/Pico/Pico.c @@ -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;ylwrite_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); diff --git a/Pico/PicoInt.h b/Pico/PicoInt.h index a6fceff..a9720c8 100644 --- a/Pico/PicoInt.h +++ b/Pico/PicoInt.h @@ -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 diff --git a/Pico/Sek.c b/Pico/Sek.c index f3af531..449a4d7 100644 --- a/Pico/Sek.c +++ b/Pico/Sek.c @@ -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 } diff --git a/Pico/VideoPort.c b/Pico/VideoPort.c index 6f41dfa..ffbda06 100644 --- a/Pico/VideoPort.c +++ b/Pico/VideoPort.c @@ -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); } } diff --git a/Pico/_cyclone_debug.c b/Pico/_cyclone_debug.c index a15f85b..854bb74 100644 --- a/Pico/_cyclone_debug.c +++ b/Pico/_cyclone_debug.c @@ -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; diff --git a/Pico/cd/Area.c b/Pico/cd/Area.c index dbd66cb..1dd6fc4 100644 --- a/Pico/cd/Area.c +++ b/Pico/cd/Area.c @@ -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 diff --git a/Pico/cd/Memory.c b/Pico/cd/Memory.c index 92c6060..1be1823 100644 --- a/Pico/cd/Memory.c +++ b/Pico/cd/Memory.c @@ -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]; } diff --git a/Pico/cd/Memory.s b/Pico/cd/Memory.s index 7b19e61..3b49cac 100644 --- a/Pico/cd/Memory.s +++ b/Pico/cd/Memory.s @@ -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] diff --git a/Pico/cd/Pico.c b/Pico/cd/Pico.c index 16a25da..2550c3d 100644 --- a/Pico/cd/Pico.c +++ b/Pico/cd/Pico.c @@ -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 } } diff --git a/Pico/cd/Pico.s b/Pico/cd/Pico.s index b1f554c..87e8554 100644 --- a/Pico/cd/Pico.s +++ b/Pico/cd/Pico.s @@ -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] diff --git a/Pico/cd/Sek.c b/Pico/cd/Sek.c index 6295af5..6005f59 100644 --- a/Pico/cd/Sek.c +++ b/Pico/cd/Sek.c @@ -7,16 +7,22 @@ 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 -// ---------------------- MUSASHI 68000 ---------------------- -m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU +m68ki_cpu_core PicoCpuMS68k; +#endif +// FAME 68000 +#ifdef EMU_F68K +M68K_CONTEXT PicoCpuFS68k; #endif + static int new_irq_level(int level) { int level_new = 0, irqs; @@ -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; } diff --git a/cpu/a68k/Makefile.win b/cpu/a68k/Makefile.win deleted file mode 100644 index 5777884..0000000 --- a/cpu/a68k/Makefile.win +++ /dev/null @@ -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 diff --git a/cpu/a68k/cpuintrf.h b/cpu/a68k/cpuintrf.h deleted file mode 100644 index c38055f..0000000 --- a/cpu/a68k/cpuintrf.h +++ /dev/null @@ -1 +0,0 @@ -// dave filler file \ No newline at end of file diff --git a/cpu/a68k/make68kd.c b/cpu/a68k/make68kd.c deleted file mode 100644 index 9f64748..0000000 --- a/cpu/a68k/make68kd.c +++ /dev/null @@ -1,8192 +0,0 @@ -/*--------------------------------------------------------------- - * Motorola 68000 32 Bit emulator - * - * Copyright 1998-2001 Mike Coates, All rights reserved - * Darren Olafson - *--------------------------------------------------------------- - * - * Thanks to ... - * - * Neil Bradley (lots of optimisation help & ideas) - * - *--------------------------------------------------------------- - * History (so we know what bugs have been fixed) - * - * 02.11.98 MJC - CMPM bug, overwriting first value - * 04.11.98 MJC - Debug timing - same as C core - * save PC on calls to C memory routines - * 05.11.98 NS - Re-insert changes to make work on OS/2 - * 06.11.98 MJC - Flags saved on ADDA commands - * X set on ADD commands - * 23.11.98 MJC - Alternate Memory Read/Write for non DOS ports - * 24.11.98 CK - Add WIN32 specific stuff - * 25.11.98 DEO - ABCD Size not initialised - * 21.12.98 MJC - Change register saving on Memory Banking - * 13.01.99 M/D - Change to new C core disassembler - * 19.01.99 MJC - Proper? support for new Interrupt System - * 17.02.99 MJC - TRACE68K define added - * ABCD,SBCD not keeping Z flag - * JMP, JSR for some EA combo's damaging flags - * DIVU - Overflow not being set correctly - * ASL/ASR - Flag Handling now correct - * some minor optimisations - * 13.03.99 DEO - Added new cycle timing - * 24.03.99 MJC - TRACE68K define removed - * NEW INTERRUPT SYSTEM only - * interrupt check sped up (when not taken) - * STOP checks for interrupt - * 01.04.99 MJC - OS2 specifics added - * MOVEM reference point moved - * Data and Address register mode combined for :- - * movecodes - * dumpx - * 04.05.99 MJC - Add Previous PC support to MOVE.B #X,XXXXXX.L (F1 Dream) - * ABCD/SBCD could corrupt zero flag - * DIVS/DIVU overflow should not update register - * 22.05.99 MJC - Complete support of Previous PC on C calls - * Some optional bits now selected by DEFINES - * 27.05.99 MJC - Interrupt system changed - * 28.05.99 MJC - Use DEFINES in more places - * Interrupt check running one opcode when taken - * 16.07.99 MJC - Reset - Preload next opcode / external call - * 68010 commands almost complete - * more compression on jump table (16k smaller) - * Some optimising - * shl reg,1 -> add reg,reg - * or ecx,ecx:jz -> jecxz - * 22.08.99 DEO - SBCD/ABCD sets N flag same as carry - * 19.10.99 MJC - Change DOS memory routines - * Change DOS Clobber flags (ESI no longer safe) - * Save EAX around memory write where needed - * bit commands optimised - * 25.10.99 MJC - Was keeping masked register on read/write - * if register was preserved over call - * ESI assumed 'safe' again - * 25.10.99 MJC - Bank ID moved to CPU context - * 03.11.99 KENJO - VC++6.0 seems not to preserve EDI. Fixed "ABCD -(A0), -(A0)" crash / "roxr (A0)"-type shift crash - * 13.11.99 KENJO - Fixed "NABC" - * Now Win32 uses FASTCALL type call for interrupt callback - * 09.02.00 MJC - Check CPU type before allowing 68010/68020 instructions - * remove routines for 5 non existant opcodes - * 05.03.00 MJC - not command decrement A7 by 1 for bytes - * 10.03.00 MJC - as did btst,cmpm and nbcd - * 22.03.00 MJC - Divide by zero should not decrement PC by 2 before push - * Move memory banking into exception routine - * 14.04.00 Dave - BTST missing Opcode - * ASL.L > 31 shift - * 20.04.00 MJC - TST.B Also missing A7 specific routine - * - Extra Define A7ROUTINE to switch between having seperate - * routines for +-(A7) address modes. - * 24.06.00 MJC - ADDX/SUBX +-(A7) routines added. - * TAS should not touch X flag - * LSL/LSR EA not clearing V flag - * CHK not all opcodes in jump table - * Add define to mask status register - * 04.07.00 MJC - Keep high byte of Program Counter on Bxx and Jxx - * Fix flag handling on NEGX - * Really fix ADDX/SUBX +-(A7) - * PC could be set wrong after CHK.W instruction - * DIVS/DIVU always clear C flag - * ABCD/SBCD missing +-(A7) Routine - * TAS missing +-(A7) Routine - * Bitwise Static missing +-(A7) Routine - * CMPM missing +-(A7) Routine - * 30.09.00 DEO - added mull, divl, bfextu - * added '020 addressing modes - * fixed $6xff branching - * 23.01.01 MJC - Spits out seperate code for 68000 & 68020 - * allows seperate optimising! - * 17.02.01 MJC - Support for encrypted PC relative fetch calls - * 11.03.01 GUTI - change some cmp reg,0 and or reg,reg with test - * 13.03.01 MJC - Single Icount for Asm & C cores - * 16.05.01 ASG - use push/pop around mem calls instead of store to safe_REG - * optimized a bit the 020 extension word decoder - * removed lots of unnecessary code in branches - *--------------------------------------------------------------- - * Known Problems / Bugs - * - * 68000 - * None - Let us know if you find any! - * - * 68010 - * Instructions that are supervisor only as per 68000 spec. - * move address space not implemented. - * - * 68020 - * only long Bcc instruction implemented. - *--------------------------------------------------------------- - * Notes - * - * STALLCHECK should be defined for Pentium Class - * undefined for P2/Celerons - * - * ALIGNMENT is normally 4, but seems faster on my P2 as 0 ! - * - *--------------------------------------------------------------- - * - * Future Changes - * - * 68020 instructions to be completed - * assembler memory routines + - * - * and anything else that takes our fancy! - *---------------------------------------------------------------*/ - -/* Specials - Switch what program allows/disallows */ - -#undef STALLCHECK /* Affects fetching of Opcode */ -#undef SAVEPPC /* Save Previous PC */ // dave -#define ENCRYPTED /* PC relative = decrypted */ -#define ASMBANK /* Memory banking algorithm to use */ // dave -#define A7ROUTINE /* Define to use separate routines for -(a7)/(a7)+ */ -#define ALIGNMENT 4 /* Alignment to use for branches */ -#undef MASKCCR /* Mask the status register to filter out unused bits */ -#define KEEPHIGHPC /* Keep or Ignore bits 24-31 */ -#define QUICKZERO /* selects XOR r,r or MOV r,0 */ - -#include -#include -#include -#include - -/* New Disassembler */ - -char * codebuf; -int DisOp; - -#define cpu_readmem24bew(addr) (0) -#define cpu_readmem24bew_word(addr) (DisOp) - -#define MEMORY_H /* so memory.h will not be included... */ -/* -#include "d68k.c" -*/ -#undef MEMORY_H - -#undef cpu_readmem24bew -#undef cpu_readmem24bew_word - -#include "cpuintrf.h" - -/* - * Defines used by Program - * - */ - -#define VERSION "0.30" - -#define TRUE -1 -#define FALSE 0 - -#define EAX 0 -#define EBX 1 -#define ECX 2 -#define EDX 3 -#define ESI 4 -#define PC ESI -#define EDI 5 -#define EBP 6 - - -#define NORMAL 0 -#define PCREL 1 - -/* Register Location Offsets */ - -#define ICOUNT "_m68k_ICount" - -#define REG_DAT "R_D0" -#define REG_DAT_EBX "[R_D0+ebx*4]" -#define REG_ADD "R_A0" -#define REG_A7 "R_A7" -#define REG_USP "R_USP" -#define REG_ISP "R_ISP" -#define REG_SRH "R_SR_H" -#define REG_CCR "R_CCR" -#define REG_X "R_XC" -#define REG_PC "R_PC" -#define REG_IRQ "R_IRQ" -#define REG_S "R_SR" -#define REG_IRQ_CALLBACK "R_IRQ_CALLBACK" -#define REG_RESET_CALLBACK "R_RESET_CALLBACK" - - -/* 68010 Regs */ - -#define REG_VBR "R_VBR" -#define REG_SFC "R_SFC" -#define REG_DFC "R_DFC" - -#define FASTCALL_FIRST_REG "ecx" -#define FASTCALL_SECOND_REG "edx" - - - -/* - * Global Variables - * - */ - -FILE *fp = NULL; - -char *comptab = NULL; -char *CPUtype = NULL; - -int CPU = 0; -int FlagProcess = 0; -int CheckInterrupt = 0; -int ExternalIO = 0; -int Opcount = 0; -int TimingCycles = 0; -int AddEACycles = 0; -int AccessType = NORMAL; -int ppro = 0; - - - -/* External register preservation */ - -#ifdef DOS - -/* Registers normally saved around C routines anyway */ -/* GCC 2.9.1 (dos) seems to preserve EBX,EDI and EBP */ -static char SavedRegs[] = "-B--SDB"; - -#elif defined(WIN32) - -/* visual C++, win32, says it preserves ebx, edi, esi, and ebp */ -/* ---------- VC++ deosn't preserve EDI? (Kenjo, 110399) ---------- */ -static char SavedRegs[] = "-B--S-B"; - -#else - -/* Assume nothing preserved */ -static char SavedRegs[] = "-------"; - -#endif - - - -/* Jump Table */ - -int OpcodeArray[65536]; - -/* Lookup Arrays */ - -static char* regnameslong[] = -{ "EAX","EBX","ECX","EDX","ESI","EDI","EBP"}; - -static char* regnamesword[] = -{ "AX","BX","CX","DX", "SI", "DI", "BP"}; - -static char* regnamesshort[] = -{ "AL","BL","CL","DL"}; - - - -/*********************************/ -/* Conversion / Utility Routines */ -/*********************************/ - -/* Convert EA to Address Mode Number - * - * 0 Dn - * 1 An - * 2 (An) - * 3 (An)+ - * 4 -(An) - * 5 x(An) - * 6 x(An,xr.s) - * 7 x.w - * 8 x.l - * 9 x(PC) - * 10 x(PC,xr.s) - * 11 #x,SR,CCR Read = Immediate, Write = SR or CCR - * in order to read SR to AX, use READCCR - * 12-15 INVALID - * - * 19 (A7)+ - * 20 -(A7) - * - */ - -int EAtoAMN(int EA, int Way) -{ - int Work; - - if (Way) - { - Work = (EA & 0x7); - - if (Work == 7) Work += ((EA & 0x38) >> 3); - - if (((Work == 3) || (Work == 4)) && (((EA & 0x38) >> 3) == 7)) - { - Work += 16; - } - } - else - { - Work = (EA & 0x38) >> 3; - - if (Work == 7) Work += (EA & 7); - - if (((Work == 3) || (Work == 4)) && ((EA & 7) == 7)) - { - Work += 16; - } - } - - return Work; -} - -/* - * Generate Main or Sub label - */ - -char *GenerateLabel(int ID,int Type) -{ - static int LabID,LabNum; -/* - static char disasm[80]; - char *dis = disasm; -*/ - if (Type == 0) - { - CheckInterrupt=0; /* No need to check for Interrupts */ - ExternalIO=0; /* Not left Assembler Yet */ - TimingCycles=0; /* No timing info for this command */ - AddEACycles=1; /* default to add in EA timing */ - Opcount++; /* for screen display */ - - DisOp = ID; -/* - m68k_disassemble(dis,0); - sprintf(codebuf, "OP%d_%4.4x:\t\t\t\t; %s", CPU,ID, dis); -*/ - sprintf(codebuf, "OP%d_%4.4x:\t\t\t\t;", CPU,ID); - - LabID = ID; - LabNum = 0; - } - else - { - LabNum++; - sprintf(codebuf, "OP%d_%4.4x_%1x", CPU,LabID, LabNum); - } - - return codebuf; -} - -/* - * Generate Alignment Line - */ - -void Align(void) -{ - fprintf(fp, "\t\t ALIGN %d\n\n",ALIGNMENT); -} - -/* - * Copy X into Carry - * - * There are several ways this could be done, this allows - * us to easily change the way we are doing it! - */ - -void CopyX(void) -{ - /* Copy bit 0 from X flag store into Carry */ - - fprintf(fp, "\t\t bt dword [%s],0\n",REG_X); -} - -/* - * Immediate 3 bit data - * - * 0=8, anything else is itself - * - * Again, several ways to achieve this - * - * ECX contains data as 3 lowest bits - * - */ - -void ClearRegister(int regno) -{ -#ifdef QUICKZERO - fprintf(fp, "\t\t mov %s,0\n",regnameslong[regno]); -#else - fprintf(fp, "\t\t xor %s,%s\n",regnameslong[regno],regnameslong[regno]); -#endif -} - -void Immediate8(void) -{ - /* This takes 3 cycles, 5 bytes, no memory reads */ - - fprintf(fp, "\t\t dec ecx ; Move range down\n"); - fprintf(fp, "\t\t and ecx,byte 7 ; Mask out lower bits\n"); - fprintf(fp, "\t\t inc ecx ; correct range\n"); - - - /* This takes 2 cycles, 10 bytes but has a memory read */ - /* I don't know timing for the mov command - assumed 1 */ - -#if 0 - fprintf(fp, "\t\t and ecx,byte 7\n"); - fprintf(fp, "\t\t mov ecx,[ImmTable+ECX*4]\n"); -#endif -} - -/* - * This will check for bank changes before - * resorting to calling the C bank select code - * - * Most of the time it does not change! - * - */ - -/* forward used by MemoryBanking */ -void Exception(int Number, int BaseCode) ; - -void MemoryBanking(int BaseCode) -{ - /* check for odd address */ - fprintf(fp, "\t\t test esi, dword 1\n"); - fprintf(fp, "\t\t jz near OP%d_%5.5x\n",CPU,BaseCode); - - /* trying to run at an odd address */ - Exception(3,BaseCode); - - /* Keep Whole PC */ - - fprintf(fp, "OP%d_%5.5x:\n",CPU,BaseCode); - -/* ASG - always call to the changepc subroutine now, since the number of */ -/* bits varies based on the memory model */ -#ifdef KEEPHIGHPC - fprintf(fp, "\t\t mov [FullPC],ESI\n"); -#endif - - /* Mask to n bits */ - fprintf(fp, "\t\t and esi,[_mem_amask]\n"); - -#if 0 -#ifdef KEEPHIGHPC - fprintf(fp, "\t\t mov [FullPC],ESI\n"); -#endif - - /* Mask to 24 bits */ -// fprintf(fp, "\t\t and esi,0ffffffh\n"); - -#ifdef ASMBANK - /* Assembler bank switch - 64k granularity */ - - fprintf(fp, "\t\t mov eax,esi\n"); - fprintf(fp, "\t\t shr eax,16\n"); - fprintf(fp, "\t\t cmp [asmbank],eax\n"); - fprintf(fp, "\t\t je OP%d_%5.5x_Bank\n",CPU,BaseCode); - - fprintf(fp, "\t\t mov [asmbank],eax\n"); -#else - /* This code is same as macro used by C core */ - - fprintf(fp, "\t\t mov ecx,esi\n"); - fprintf(fp, "\t\t mov ebx,[_cur_mrhard]\n"); - fprintf(fp, "\t\t shr ecx,9\n"); - fprintf(fp, "\t\t mov al,byte [_opcode_entry]\n"); - fprintf(fp, "\t\t cmp al,[ecx+ebx]\n"); - fprintf(fp, "\t\t je OP%d_%5.5x_Bank\n",CPU,BaseCode); -#endif -#endif - - /* Call Banking Routine */ - - if (SavedRegs[ESI] == '-') - { - fprintf(fp, "\t\t mov [%s],ESI\n",REG_PC); - } - - if (SavedRegs[EDX] == '-') - { - fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR); - } - -#ifdef FASTCALL - fprintf(fp, "\t\t mov %s,esi\n",FASTCALL_FIRST_REG); -#else - fprintf(fp, "\t\t push esi\n"); -#endif - - fprintf(fp, "\t\t call [_a68k_memory_intf+28]\n"); - -#ifndef FASTCALL - fprintf(fp, "\t\t lea esp,[esp+4]\n"); -#endif - - if (SavedRegs[EDX] == '-') - { - fprintf(fp, "\t\t mov edx,[%s]\n",REG_CCR); - } - - if (SavedRegs[ESI] == '-') - { - fprintf(fp, "\t\t mov esi,[%s]\n",REG_PC); - } - - /* Update our copy */ - - fprintf(fp, "\t\t mov ebp,dword [_OP_ROM]\n"); - - fprintf(fp, "OP%d_%5.5x_Bank:\n",CPU,BaseCode); -} - -/* - * Update Previous PC value - * - */ - -void SavePreviousPC(void) -{ -#ifdef SAVEPPC - fprintf(fp, "\t\t mov [R_PPC],esi\t\t\t ; Keep Previous PC\n"); -#endif -} - -/* - * Complete Opcode handling - * - * Any tidying up, end code - * - */ - -void Completed(void) -{ - - /* Flag Processing to be finished off ? */ - - AccessType = NORMAL; - - /* Use assembler timing routines */ - - if (TimingCycles != 0) - { - if (TimingCycles > 127) - fprintf(fp, "\t\t sub dword [%s],%d\n",ICOUNT,TimingCycles); - else - { - if (TimingCycles != -1) - fprintf(fp, "\t\t sub dword [%s],byte %d\n",ICOUNT,TimingCycles); - } - - if (FlagProcess > 0) - fprintf(fp, "\t\t pop EDX\n"); - if (FlagProcess == 2) - fprintf(fp, "\t\t mov [%s],edx\n",REG_X); - - fprintf(fp, "\t\t js near MainExit\n\n"); - } - else - { - fprintf(fp, "\t\t test dword [%s],0xffffffff\n",ICOUNT); - - if (FlagProcess > 0) - fprintf(fp, "\t\t pop EDX\n"); - if (FlagProcess == 2) - fprintf(fp, "\t\t mov [%s],edx\n",REG_X); - - fprintf(fp, "\t\t jle near MainExit\n\n"); - } - FlagProcess = 0; - -#ifdef MAME_DEBUG - - /* Check for Debug Active */ - - fprintf(fp, "\n\t\t test byte [_mame_debug],byte 0xff\n"); - fprintf(fp, "\t\t jnz near MainExit\n\n"); - -#endif - - if (CheckInterrupt) - { - fprintf(fp,"; Check for Interrupt waiting\n\n"); - fprintf(fp,"\t\t test byte [%s],07H\n",REG_IRQ); - fprintf(fp,"\t\t jne near interrupt\n\n"); - } - - if(CPU==2) - { - /* 32 bit memory version */ - fprintf(fp, "\t\t mov eax,2\n"); /* ASG */ - fprintf(fp, "\t\t xor eax,esi\n"); /* ASG */ - -#ifdef STALLCHECK - ClearRegister(ECX); - fprintf(fp, "\t\t mov cx,[eax+ebp]\n"); -#else - fprintf(fp, "\t\t movzx ecx,word [eax+ebp]\n"); -#endif - } - else - { - /* 16 bit memory */ -#ifdef STALLCHECK - ClearRegister(ECX); - fprintf(fp, "\t\t mov cx,[esi+ebp]\n"); -#else - fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n"); -#endif - } - - fprintf(fp, "\t\t jmp [%s_OPCODETABLE+ecx*4]\n\n", CPUtype); -} - -/* - * Flag Routines - * - * Size = B,W or L - * Sreg = Register to Test - * TestReg = Need to test register (false if flags already set up) - * SetX = if C needs to be copied across to X register - * Delayed = Delays final processing to end of routine (Completed()) - * - */ - -void TestFlags(char Size,int Sreg) -{ - char* Regname=""; - - switch (Size) - { - case 66: - Regname = regnamesshort[Sreg]; - break; - - case 87: - Regname = regnamesword[Sreg]; - break; - - case 76: - Regname = regnameslong[Sreg]; - break; - } - - /* Test does not update register */ - /* so cannot generate partial stall */ - - fprintf(fp, "\t\t test %s,%s\n",Regname,Regname); -} - -void SetFlags(char Size,int Sreg,int Testreg,int SetX,int Delayed) -{ - if (Testreg) TestFlags(Size,Sreg); - - fprintf(fp, "\t\t pushfd\n"); - - if (Delayed) - { - /* Rest of code done by Completed routine */ - - if (SetX) FlagProcess = 2; - else FlagProcess = 1; - } - else - { - fprintf(fp, "\t\t pop EDX\n"); - - if (SetX) fprintf(fp, "\t\t mov [%s],edx\n",REG_X); - } -} - -/******************/ -/* Check CPU Type */ -/******************/ - -void CheckCPUtype(int Minimum) -{ - if(CPU==2) - { - /* Only check for > 020 */ - - if(Minimum>2) - { - fprintf(fp, "\t\t mov eax,[CPUversion]\n"); - - fprintf(fp, "\t\t cmp al,%d\n",Minimum); - fprintf(fp, "\t\t jb near ILLEGAL\n\n"); - } - } - else - { - fprintf(fp, "\t\t mov eax,[CPUversion]\n"); - - if (Minimum == 1) - { - fprintf(fp, "\t\t test eax,eax\n"); - fprintf(fp, "\t\t jz near ILLEGAL\n\n"); - } - else - { - fprintf(fp, "\t\t cmp al,%d\n",Minimum); - fprintf(fp, "\t\t jb near ILLEGAL\n\n"); - } - } -} - -/************************************/ -/* Pre-increment and Post-Decrement */ -/************************************/ - -void IncrementEDI(int Size,int Rreg) -{ - switch (Size) - { - case 66: - -#ifdef A7ROUTINE - - /* Always does Byte Increment - A7 uses special routine */ - - fprintf(fp, "\t\t inc dword [%s+%s*4]\n",REG_ADD,regnameslong[Rreg]); - -#else - - /* A7 uses same routines, so inc by 2 if A7 */ - - fprintf(fp, "\t\t cmp %s,7\n",regnamesshort[Rreg]); - fprintf(fp, "\t\t cmc\n"); - fprintf(fp, "\t\t adc dword [%s+%s*4],byte 1\n",REG_ADD,regnameslong[Rreg]); - -#endif - break; - - case 87: - - fprintf(fp, "\t\t add dword [%s+%s*4],byte 2\n",REG_ADD,regnameslong[Rreg]); - break; - - case 76: - - fprintf(fp, "\t\t add dword [%s+%s*4],byte 4\n",REG_ADD,regnameslong[Rreg]); - break; - } -} - -void DecrementEDI(int Size,int Rreg) -{ - switch (Size) - { - case 66: - -#ifdef A7ROUTINE - - /* Always does Byte Increment - A7 uses special routine */ - - fprintf(fp, "\t\t dec EDI\n"); - -#else - - /* A7 uses same routines, so dec by 2 if A7 */ - - fprintf(fp, "\t\t cmp %s,7\n",regnamesshort[Rreg]); - fprintf(fp, "\t\t cmc\n"); - fprintf(fp, "\t\t sbb dword edi,byte 1\n"); - -#endif - break; - - case 87: - - fprintf(fp, "\t\t sub EDI,byte 2\n"); - break; - - case 76: - fprintf(fp, "\t\t sub EDI,byte 4\n"); - break; - } -} - -/* - * Generate an exception - * - * if Number = -1 then assume value in AL already - * code must continue running afterwards - * - */ - -void Exception(int Number, int BaseCode) -{ - if (Number > -1) - { - fprintf(fp, "\t\t sub esi,byte 2\n"); - fprintf(fp, "\t\t mov al,%d\n",Number); - } - - fprintf(fp, "\t\t call Exception\n\n"); - - if (Number > -1) - Completed(); -} - - -/********************/ -/* Address Routines */ -/********************/ - -/* - * Decode Intel flags into AX as SR register - * - * Wreg = spare register to use (must not be EAX or EDX) - */ - -void ReadCCR(char Size, int Wreg) -{ - fprintf(fp, "\t\t mov eax,edx\n"); - fprintf(fp, "\t\t mov ah,byte [%s]\n",REG_X); - - /* Partial stall so .. switch to new bit of processing */ - - fprintf(fp, "\t\t mov %s,edx\n",regnameslong[Wreg]); - fprintf(fp, "\t\t and %s,byte 1\n",regnameslong[Wreg]); - - /* Finish what we started */ - - fprintf(fp, "\t\t shr eax,4\n"); - fprintf(fp, "\t\t and eax,byte 01Ch \t\t; X, N & Z\n\n"); - - /* and complete second task */ - - fprintf(fp, "\t\t or eax,%s \t\t\t\t; C\n\n",regnameslong[Wreg]); - - /* and Finally */ - - fprintf(fp, "\t\t mov %s,edx\n",regnameslong[Wreg]); - fprintf(fp, "\t\t shr %s,10\n",regnameslong[Wreg]); - fprintf(fp, "\t\t and %s,byte 2\n",regnameslong[Wreg]); - fprintf(fp, "\t\t or eax,%s\t\t\t\t; O\n\n",regnameslong[Wreg]); - - if (Size == 'W') - { - fprintf(fp, "\t\t mov ah,byte [%s] \t; T, S & I\n\n",REG_SRH); - -#ifdef MASKCCR - fprintf(fp, "\t\t and ax,0A71Fh\t; Mask unused bits\n"); -#endif - } -} - -/* - * Convert SR into Intel flags - * - * Also handles change of mode from Supervisor to User - * - * n.b. This is also called by EffectiveAddressWrite - */ - -void WriteCCR(char Size) -{ - if (Size == 'W') - { - /* Did we change from Supervisor to User mode ? */ - - char *Label = GenerateLabel(0,1); - - fprintf(fp, "\t\t test ah,20h \t\t\t; User Mode ?\n"); - fprintf(fp, "\t\t jne short %s\n\n",Label); - - /* Mode Switch - Update A7 */ - - fprintf(fp, "\t\t mov edx,[%s]\n",REG_A7); - fprintf(fp, "\t\t mov [%s],edx\n",REG_ISP); - fprintf(fp, "\t\t mov edx,[%s]\n",REG_USP); - fprintf(fp, "\t\t mov [%s],edx\n",REG_A7); - - fprintf(fp, "%s:\n",Label); - fprintf(fp, "\t\t mov byte [%s],ah \t;T, S & I\n",REG_SRH); - - /* Mask may now allow Interrupt */ - - CheckInterrupt += 1; - } - - /* Flags */ - - fprintf(fp, "\t\t and eax,byte 1Fh\n"); - fprintf(fp, "\t\t mov edx,[IntelFlag+eax*4]\n"); - fprintf(fp, "\t\t mov [%s],dh\n",REG_X); - fprintf(fp, "\t\t and edx,0EFFh\n"); -} - - -/* - * Interface to Mame memory commands - * - * Flags = "ABCDSDB" - set to '-' if not required to preserve - * (order EAX,EBX,ECX,EDX,ESI,EDI,EBP) - * - * AReg = Register containing Address - * - * Mask 0 : No Masking - * 1 : Mask top byte, but preserve register - * 2 : Mask top byte, preserve masked register - */ - -void Memory_Read(char Size,int AReg,char *Flags,int Mask) -{ - ExternalIO = 1; - - /* Save PC */ - - fprintf(fp, "\t\t mov [%s],ESI\n",REG_PC); - - /* Check for special mask condition */ - - /* ASG - no longer need to mask addresses here */ -/* if (Mask == 2) - fprintf(fp, "\t\t and %s,0FFFFFFh\n",regnameslong[AReg]);*/ - - /* Check to see if registers need saving */ - - if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-')) - { - fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR); - } - - if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-')) - { - fprintf(fp, "\t\t push EBX\n"); - } - - if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-')) - { - fprintf(fp, "\t\t push ECX\n"); - } - - if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-')) - { - fprintf(fp, "\t\t push EDI\n"); - } - - /* Sort Address out */ - -#ifdef FASTCALL - - fprintf(fp, "\t\t mov %s,%s\n",FASTCALL_FIRST_REG,regnameslong[AReg]); - - /* ASG - no longer need to mask addresses here */ -/* if (Mask == 1) - fprintf(fp, "\t\t and %s,0FFFFFFh\n",FASTCALL_FIRST_REG);*/ - -#else - - if (Mask == 1) - { - if ((Flags[AReg] != '-') && (SavedRegs[AReg] != '-')) - { - /* Don't trash a wanted safe register */ - - fprintf(fp, "\t\t mov EAX,%s\n",regnameslong[AReg]); - /* ASG - no longer need to mask addresses here */ -/* fprintf(fp, "\t\t and EAX,0FFFFFFh\n");*/ - fprintf(fp, "\t\t push EAX\n"); - } - else - { - /* ASG - no longer need to mask addresses here */ -/* fprintf(fp, "\t\t and %s,0FFFFFFh\n",regnameslong[AReg]);*/ - fprintf(fp, "\t\t push %s\n",regnameslong[AReg]); - } - } - else - fprintf(fp, "\t\t push %s\n",regnameslong[AReg]); - -#endif - - - - /* Call Mame memory routine */ - - /* ASG - changed these to call through the function pointers */ - -#ifdef ENCRYPTED - switch (AccessType) - { - case NORMAL : - switch (Size) - { - case 66 : - fprintf(fp, "\t\t call [_a68k_memory_intf+4]\n"); - break; - - case 87 : - fprintf(fp, "\t\t call [_a68k_memory_intf+8]\n"); - break; - - case 76 : - fprintf(fp, "\t\t call [_a68k_memory_intf+12]\n"); - break; - } - break; - - case PCREL : - - switch (Size) - { - case 66 : - fprintf(fp, "\t\t call [_a68k_memory_intf+32]\n"); - break; - - case 87 : - fprintf(fp, "\t\t call [_a68k_memory_intf+36]\n"); - break; - - case 76 : - fprintf(fp, "\t\t call [_a68k_memory_intf+40]\n"); - break; - } - break; - } - -// AccessType = NORMAL; - -#else - - switch (Size) - { - case 66 : - fprintf(fp, "\t\t call [_a68k_memory_intf+4]\n"); - break; - - case 87 : - fprintf(fp, "\t\t call [_a68k_memory_intf+8]\n"); - break; - - case 76 : - fprintf(fp, "\t\t call [_a68k_memory_intf+12]\n"); - break; - } -#endif - - /* Correct Stack */ - -#ifndef FASTCALL - fprintf(fp, "\t\t lea esp,[esp+4]\n"); -#endif - - - - /* Restore registers */ - - /* Check to see if registers need restoring */ - - if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-')) - { - fprintf(fp, "\t\t pop EDI\n"); - } - - if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-')) - { - fprintf(fp, "\t\t pop ECX\n"); - } - - if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-')) - { - fprintf(fp, "\t\t pop EBX\n"); - } - - if ((Flags[ESI] != '-') && (SavedRegs[ESI] == '-')) - { - fprintf(fp, "\t\t mov ESI,[%s]\n",REG_PC); - } - - if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-')) - { - fprintf(fp, "\t\t mov EDX,[%s]\n",REG_CCR); - } - - if ((Flags[EBP] != '-') && (SavedRegs[EBP] == '-')) - { - fprintf(fp, "\t\t mov ebp,dword [_OP_ROM]\n"); - } -} - -void Memory_Write(char Size,int AReg,int DReg,char *Flags,int Mask) -{ - ExternalIO = 1; - - /* Save PC */ - - fprintf(fp, "\t\t mov [%s],ESI\n",REG_PC); - - /* Check for special mask condition */ - - /* ASG - no longer need to mask addresses here */ -/* if (Mask == 2) - fprintf(fp, "\t\t and %s,0FFFFFFh\n",regnameslong[AReg]);*/ - - /* Check to see if registers need saving */ - - if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-')) - { - fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR); - } - - if ((Flags[EAX] != '-') && (SavedRegs[EAX] == '-')) - { - fprintf(fp, "\t\t push EAX\n"); - } - - if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-')) - { - fprintf(fp, "\t\t push EBX\n"); - } - - if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-')) - { - fprintf(fp, "\t\t push ECX\n"); - } - - if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-')) - { - fprintf(fp, "\t\t push EDI\n"); - } - -#ifdef FASTCALL - - fprintf(fp, "\t\t mov %s,%s\n",FASTCALL_SECOND_REG,regnameslong[DReg]); - fprintf(fp, "\t\t mov %s,%s\n",FASTCALL_FIRST_REG,regnameslong[AReg]); - - /* ASG - no longer need to mask addresses here */ -/* if (Mask == 1) - fprintf(fp, "\t\t and %s,0FFFFFFh\n",FASTCALL_FIRST_REG);*/ - -#else - - fprintf(fp, "\t\t push %s\n",regnameslong[DReg]); - - if (Mask == 1) - { - if ((Flags[AReg] != '-') && (SavedRegs[AReg] != '-')) - { - /* Don't trash a wanted safe register */ - - fprintf(fp, "\t\t mov EAX,%s\n",regnameslong[AReg]); - /* ASG - no longer need to mask addresses here */ -/* fprintf(fp, "\t\t and EAX,0FFFFFFh\n");*/ - fprintf(fp, "\t\t push EAX\n"); - } - else - { - /* ASG - no longer need to mask addresses here */ -/* fprintf(fp, "\t\t and %s,0FFFFFFh\n",regnameslong[AReg]);*/ - fprintf(fp, "\t\t push %s\n",regnameslong[AReg]); - } - } - else - fprintf(fp, "\t\t push %s\n",regnameslong[AReg]); - -#endif - - - - /* Call Mame Routine */ - - /* ASG - changed these to call through the function pointers */ - switch (Size) - { - case 66 : - fprintf(fp, "\t\t call [_a68k_memory_intf+16]\n"); - break; - - case 87 : - fprintf(fp, "\t\t call [_a68k_memory_intf+20]\n"); - break; - - case 76 : - fprintf(fp, "\t\t call [_a68k_memory_intf+24]\n"); - break; - } - - /* Correct Stack */ - -#ifndef FASTCALL - fprintf(fp, "\t\t lea esp,[esp+8]\n"); -#endif - - - - /* Restore registers */ - - /* Check to see if registers need restoring */ - - if ((Flags[EDI] != '-') && (SavedRegs[EDI] == '-')) - { - fprintf(fp, "\t\t pop EDI\n"); - } - - if ((Flags[ECX] != '-') && (SavedRegs[ECX] == '-')) - { - fprintf(fp, "\t\t pop ECX\n"); - } - - if ((Flags[EBX] != '-') && (SavedRegs[EBX] == '-')) - { - fprintf(fp, "\t\t pop EBX\n"); - } - - if ((Flags[EAX] != '-') && (SavedRegs[EAX] == '-')) - { - fprintf(fp, "\t\t pop EAX\n"); - } - - if ((Flags[EDX] != '-') && (SavedRegs[EDX] == '-')) - { - fprintf(fp, "\t\t mov EDX,[%s]\n",REG_CCR); - } - - if ((Flags[ESI] != '-') && (SavedRegs[ESI] == '-')) - { - fprintf(fp, "\t\t mov ESI,[%s]\n",REG_PC); - } - - if ((Flags[EBP] != '-') && (SavedRegs[EBP] == '-')) - { - fprintf(fp, "\t\t mov ebp,dword [_OP_ROM]\n"); - } -} - - -/* - * Fetch data from Code area - * - * Dreg = Destination Register - * Extend = Sign Extend Word to Long - * - */ - -void Memory_Fetch(char Size,int Dreg,int Extend) -{ - static int loopcount=0; - - /* Always goes via OP_ROM */ - - if(CPU!=2) - { - /* 16 Bit version */ - - if ((Extend == TRUE) & (Size == 'W')) - fprintf(fp, "\t\t movsx %s,word [esi+ebp]\n",regnameslong[Dreg]); - else if (Size == 'W') - fprintf(fp, "\t\t movzx %s,word [esi+ebp]\n",regnameslong[Dreg]); - else - fprintf(fp, "\t\t mov %s,dword [esi+ebp]\n",regnameslong[Dreg]); - - if (Size == 'L') - fprintf(fp, "\t\t rol %s,16\n",regnameslong[Dreg]); - } - else - { - /* 32 Bit version */ - - if (Size == 'W') - { - fprintf(fp, "\t\t mov %s,esi\n",regnameslong[Dreg]); - fprintf(fp, "\t\t xor %s,byte 2\n",regnameslong[Dreg]); - - if (Extend == TRUE) - fprintf(fp, "\t\t movsx %s,word [%s+ebp]\n",regnameslong[Dreg],regnameslong[Dreg]); - else - fprintf(fp, "\t\t movzx %s,word [%s+ebp]\n",regnameslong[Dreg],regnameslong[Dreg]); - } - else - { - // if address is exact multiple of 4, long read will work - // otherwise we need to get words address-2 and address+4 - - // Always read long - fprintf(fp, "\t\t test esi,2\n"); -#if (!ppro) - fprintf(fp, "\t\t mov %s,dword [esi+ebp]\n",regnameslong[Dreg]); - - // OK ? - fprintf(fp, "\t\t jz short FL%3.3d\n",loopcount+1); - - // no, so get high word - fprintf(fp, "\t\t mov %s,dword [esi+ebp-4]\n",regnameslong[Dreg]); - // and get low word - fprintf(fp, "\t\t mov %s,word [esi+ebp+4]\n",regnamesword[Dreg]); - - fprintf(fp, "FL%3.3d:\n",++loopcount); -#else - fprintf(fp, "\t\t cmovnz %s,dword [esi+ebp-4]\n",regnameslong[Dreg]); - fprintf(fp, "\t\t cmovz %s,dword [esi+ebp]\n",regnameslong[Dreg]); - fprintf(fp, "\t\t cmovnz %s,word [esi+ebp+4]\n",regnamesword[Dreg]); -#endif - } - } -} - -/**********************/ -/* Push PC onto Stack */ -/**********************/ - -void PushPC(int Wreg,int Wreg2,char *Flags, int Mask) -{ - - /* Wreg2 is only used when high byte is kept */ - /* If it is EBP then the register is restored */ - - fprintf(fp, "\t\t mov %s,[%s]\t ; Push onto Stack\n",regnameslong[Wreg],REG_A7); - fprintf(fp, "\t\t sub %s,byte 4\n",regnameslong[Wreg]); - fprintf(fp, "\t\t mov [%s],%s\n",REG_A7,regnameslong[Wreg]); - -#ifndef KEEPHIGHPC - - Memory_Write('L',Wreg,ESI,Flags,Mask); - -#else - - fprintf(fp, "\t\t mov %s,[FullPC]\n",regnameslong[Wreg2]); - fprintf(fp, "\t\t and %s,0xff000000\n",regnameslong[Wreg2]); - fprintf(fp, "\t\t or %s,ESI\n",regnameslong[Wreg2]); - - Memory_Write('L',Wreg,Wreg2,Flags,Mask); - - if (Wreg2 == EBP) - { - fprintf(fp, "\t\t mov ebp,dword [_OP_ROM]\n"); - } - -#endif -} - -void ExtensionDecode(int SaveEDX) -{ - char *Label = GenerateLabel(0,1); - - if (SaveEDX) - fprintf(fp, "\t\t push edx\n"); - - Memory_Fetch('W',EAX,FALSE); - fprintf(fp, "\t\t add esi,byte 2\n"); - - if(CPU!=2) - { - /* 68000 Extension */ - - fprintf(fp, "\t\t mov edx,eax\n"); - fprintf(fp, "\t\t shr eax,12\n"); - fprintf(fp, "\t\t test edx,0x0800\n"); - fprintf(fp, "\t\t mov eax,[%s+eax*4]\n",REG_DAT); - fprintf(fp, "\t\t jnz short %s\n",Label); - fprintf(fp, "\t\t cwde\n"); - fprintf(fp, "%s:\n",Label); - fprintf(fp, "\t\t lea edi,[edi+eax]\n"); - fprintf(fp, "\t\t movsx edx,dl\n"); - fprintf(fp, "\t\t lea edi,[edi+edx]\n"); - } - else - { - /* 68020 Extension */ - - // eax holds scaled index - - // might be faster just to push all regs - fprintf(fp, "\t\t push ebx\n"); - fprintf(fp, "\t\t push ecx\n"); - - // copies for later use - fprintf(fp, "\t\t mov ecx,eax\n"); - fprintf(fp, "\t\t mov edx,eax\n"); - - // check E bit to see if displacement or full format - fprintf(fp, "\t\t test edx,0x0100\n"); - fprintf(fp, "\t\t jz short %s_a\n",Label); - // full mode so check IS (index supress) - fprintf(fp, "\t\t test edx,0x0040\n"); - fprintf(fp, "\t\t jz short %s_b\n",Label); - // set index to 0, it's not added - ClearRegister(EAX); - fprintf(fp, "\t\t jmp short %s_d\n",Label); // near - - // add displacement - fprintf(fp, "%s_a:\n",Label); - fprintf(fp, "\t\t movsx eax,al\n"); - fprintf(fp, "\t\t lea edi,[edi+eax]\n"); - - fprintf(fp, "%s_b:\n",Label); - // calc index always scale (68k will scale by 1) - fprintf(fp, "\t\t mov eax,edx\n"); - fprintf(fp, "\t\t shr eax,12\n"); - fprintf(fp, "\t\t test edx,0x0800\n"); - fprintf(fp, "\t\t mov eax,[%s+eax*4]\n",REG_DAT); - fprintf(fp, "\t\t jnz short %s_c\n",Label); - fprintf(fp, "\t\t cwde\n"); - - fprintf(fp, "%s_c:\n",Label); - fprintf(fp, "\t\t shr ecx,byte 9\n"); - fprintf(fp, "\t\t and ecx,byte 3\n"); - fprintf(fp, "\t\t shl eax,cl\n"); - - // if brief mode we can add index and exit - fprintf(fp, "\t\t test edx,0x0100\n"); - fprintf(fp, "\t\t jz near %s_i2\n",Label); - - fprintf(fp, "%s_d:\n",Label); - // check BS (base supress) - // if BS is 1 then set edi to 0 - fprintf(fp, "\t\t test edx,0x0080\n"); - fprintf(fp, "\t\t jz short %s_4a\n",Label); - ClearRegister(EDI); - // if null displacement skip over - fprintf(fp, "%s_4a:\n",Label); - fprintf(fp, "\t\t test edx,0x0020\n"); - fprintf(fp, "\t\t jz short %s_f\n",Label); - - // **** calc base displacement **** - // is it long - fprintf(fp, "\t\t test edx,0x0010\n"); - fprintf(fp, "\t\t jz short %s_e\n",Label); - // fetch long base - Memory_Fetch('L',EBX,FALSE); - fprintf(fp, "\t\t lea edi,[edi+ebx]\n"); - fprintf(fp, "\t\t add esi,byte 4\n"); - fprintf(fp, "\t\t jmp short %s_f\n",Label); - - // fetch word base - fprintf(fp, "%s_e:\n",Label); - Memory_Fetch('W',EBX,TRUE); - fprintf(fp, "\t\t lea edi,[edi+ebx]\n"); - fprintf(fp, "\t\t add esi,byte 2\n"); - - // **** indirect? **** - fprintf(fp, "%s_f:\n",Label); - fprintf(fp, "\t\t test edx,0x0003\n"); - fprintf(fp, "\t\t jz near %s_7a\n",Label); - // pre or post indirect - fprintf(fp, "\t\t test edx,0x0004\n"); - fprintf(fp, "\t\t jnz short %s_g\n",Label); - // do pre - fprintf(fp, "\t\t lea edi,[edi+eax]\n"); - Memory_Read('L',EDI,"ABCDSDB",2); - fprintf(fp, "\t\t mov edi,eax\n"); - fprintf(fp, "\t\t jmp short %s_h\n",Label); - - // do post - fprintf(fp, "%s_g:\n",Label); - fprintf(fp, "\t\t push eax\n"); - Memory_Read('L',EDI,"-B-DS-B",2); - fprintf(fp, "\t\t pop edi\n"); - - fprintf(fp, "%s_7a:\n",Label); - fprintf(fp, "\t\t lea edi,[edi+eax]\n"); - - // **** outer displacement **** - // if null displacement skip over - fprintf(fp, "%s_h:\n",Label); - fprintf(fp, "\t\t test edx,0x0002\n"); - fprintf(fp, "\t\t jz short %s_j\n",Label); - // word or long? - fprintf(fp, "\t\t test edx,0x0001\n"); - fprintf(fp, "\t\t jz short %s_i\n",Label); - // fetch long - Memory_Fetch('L',EAX,FALSE); - fprintf(fp, "\t\t add esi,byte 4\n"); - fprintf(fp, "\t\t jmp short %s_i2\n",Label); - // fetch word - fprintf(fp, "%s_i:\n",Label); - Memory_Fetch('W',EAX,TRUE); - fprintf(fp, "\t\t add esi,byte 2\n"); - fprintf(fp, "%s_i2:\n",Label); - fprintf(fp, "\t\t lea edi,[edi+eax]\n"); - - // **** exit **** - fprintf(fp, "%s_j:\n",Label); - fprintf(fp, "\t\t pop ecx\n"); - fprintf(fp, "\t\t pop ebx\n"); - } - - if (SaveEDX) - fprintf(fp, "\t\t pop edx\n"); -} - -/* Calculate Effective Address - Return address in EDI - * - * mode = Effective Address from Instruction - * Size = Byte,Word or Long - * Rreg = Register with Register Number in - * - * Only for modes 2 - 10 (5-10 clobber EAX) - */ - -void EffectiveAddressCalculate(int mode,char Size,int Rreg,int SaveEDX) -{ - /* timing */ - - if ((TimingCycles > 0) && (AddEACycles!=0)) - { - switch (mode) - { - case 2: /* (An) */ - case 3: /* (An)+ */ - case 11: /* #x,SR,CCR */ - case 19: /* (A7)+ */ - TimingCycles += 4 ; - break ; - - case 4: /* -(An) */ - case 20: /* -(A7) */ - TimingCycles += (CPU==2) ? 5 : 6 ; - break ; - - case 5: /* x(An) */ - case 9: /* x(PC) */ - TimingCycles += (CPU==2) ? 5 : 8 ; - break ; - - case 7: /* x.w */ - TimingCycles += (CPU==2) ? 4 : 8 ; - break ; - - case 6: /* x(An,xr.s) */ - case 10: /* x(PC,xr.s) */ - TimingCycles += (CPU==2) ? 7 : 10 ; - break ; - - case 8: /* x.l */ - TimingCycles += (CPU==2) ? 4 : 12 ; - break ; - } - - /* long w/r adds 4 cycles */ - - if ((mode>1) && (Size == 'L') && (CPU != 2)) - TimingCycles += 4 ; - } - - AccessType = NORMAL; - - switch (mode) - { - - case 2: - fprintf(fp, "\t\t mov EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]); - break; - - case 3: - fprintf(fp, "\t\t mov EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]); - IncrementEDI(Size,Rreg); - break; - - case 4: - fprintf(fp, "\t\t mov EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]); - DecrementEDI(Size,Rreg); - fprintf(fp, "\t\t mov [%s+%s*4],EDI\n",REG_ADD,regnameslong[Rreg]); - break; - - case 5: - Memory_Fetch('W',EAX,TRUE); - fprintf(fp, "\t\t mov EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]); - fprintf(fp, "\t\t add esi,byte 2\n"); - fprintf(fp, "\t\t add edi,eax\n"); - break; - - case 6: - - /* Get Address register Value */ - - fprintf(fp, "\t\t mov EDI,[%s+%s*4]\n",REG_ADD,regnameslong[Rreg]); - - /* Add Extension Details */ - - ExtensionDecode(SaveEDX); - break; - - case 7: - - /* Get Word */ - - Memory_Fetch('W',EDI,TRUE); -// fprintf(fp, "\t\t movsx edi,di\n"); - fprintf(fp, "\t\t add esi,byte 2\n"); - break; - - case 8: - - /* Get Long */ - - Memory_Fetch('L',EDI,FALSE); - fprintf(fp, "\t\t add esi,byte 4\n"); - break; - - case 9: - - AccessType = PCREL; - - Memory_Fetch('W',EAX,TRUE); -// fprintf(fp, "\t\t movsx eax,ax\n"); - fprintf(fp, "\t\t mov EDI,ESI ; Get PC\n"); - fprintf(fp, "\t\t add esi,byte 2\n"); - fprintf(fp, "\t\t add edi,eax ; Add Offset to PC\n"); - break; - - case 10: - - AccessType = PCREL; - - /* Get PC */ - - fprintf(fp, "\t\t mov edi,esi ; Get PC\n"); - - /* Add Extension Details */ - - ExtensionDecode(SaveEDX); - - break; - - case 19: - - /* (A7)+ */ - - fprintf(fp, "\t\t mov edi,[%s] ; Get A7\n",REG_A7); - fprintf(fp, "\t\t add dword [%s],byte 2\n",REG_A7); - break; - - case 20: - - /* -(A7) */ - - fprintf(fp, "\t\t mov edi,[%s] ; Get A7\n",REG_A7); - fprintf(fp, "\t\t sub edi,byte 2\n"); - fprintf(fp, "\t\t mov [%s],edi\n",REG_A7); - break; - - } -} - -/* Read from Effective Address - * - * mode = Effective Address from Instruction - * Size = Byte,Word or Long - * Rreg = Register with Register Number in - * Flag = Registers to preserve (EDX is handled by SaveEDX) - * - * Return - * Dreg = Register to return result in (EAX is usually most efficient) - * (modes 5 to 10) EDI = Address of data read (masked with FFFFFF) - */ - -void EffectiveAddressRead(int mode,char Size,int Rreg,int Dreg,const char *flags,int SaveEDX) -{ - char* Regname=""; - int MaskMode; - char Flags[8]; - - AccessType = NORMAL; - - strcpy(Flags,flags); - - /* Which Masking to Use */ - - if (Flags[5] != '-') - MaskMode = 2; - else - MaskMode = 1; - - if (SaveEDX) - Flags[3] = 'D'; - else - Flags[3] = '-'; - - switch (Size) - { - case 66: - Regname = regnamesshort[Dreg]; - break; - - case 87: - Regname = regnamesword[Dreg]; - break; - - case 76: - Regname = regnameslong[Dreg]; - break; - } - - switch (mode & 15) - { - - case 0: - - /* Read 32 bits - No prefix */ - - fprintf(fp, "\t\t mov %s,[%s+%s*4]\n",regnameslong[Dreg],REG_DAT,regnameslong[Rreg]); - break; - - case 1: - - /* Read 32 bits - No prefix */ - - fprintf(fp, "\t\t mov %s,[%s+%s*4]\n",regnameslong[Dreg],REG_ADD,regnameslong[Rreg]); - break; - - case 2: - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - - Memory_Read(Size,EDI,Flags,MaskMode); - - if (Dreg != EAX) - { - fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]); - } - break; - - case 3: - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - - Memory_Read(Size,EDI,Flags,MaskMode); - - if (Dreg != EAX) - { - fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]); - } - break; - - case 4: - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - - Memory_Read(Size,EDI,Flags,MaskMode); - - if (Dreg != EAX) - { - fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]); - } - break; - - - case 5: - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - - Memory_Read(Size,EDI,Flags,MaskMode); - - if (Dreg != EAX) - { - fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]); - } - break; - - case 6: - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - - Memory_Read(Size,EDI,Flags,MaskMode); - - if (Dreg != EAX) - { - fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]); - } - break; - - case 7: - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - - Memory_Read(Size,EDI,Flags,MaskMode); - - if (Dreg != EAX) - { - fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]); - } - break; - - case 8: - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - - Memory_Read(Size,EDI,Flags,MaskMode); - - if (Dreg != EAX) - { - fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]); - } - break; - - case 9: - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - - Memory_Read(Size,EDI,Flags,MaskMode); - - if (Dreg != EAX) - { - fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]); - } - break; - - case 10: - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - - Memory_Read(Size,EDI,Flags,MaskMode); - - if (Dreg != EAX) - { - fprintf(fp, "\t\t mov %s,EAX\n",regnameslong[Dreg]); - } - break; - - case 11: - - /* Immediate - for SR or CCR see ReadCCR() */ - - if (Size == 'L') - { - Memory_Fetch('L',Dreg,FALSE); - fprintf(fp, "\t\t add esi,byte 4\n"); - } - else - { - Memory_Fetch('W',Dreg,FALSE); - fprintf(fp, "\t\t add esi,byte 2\n"); - }; - break; - } -} - -/* - * EA = Effective Address from Instruction - * Size = Byte,Word or Long - * Rreg = Register with Register Number in - * - * Writes from EAX - */ - -void EffectiveAddressWrite(int mode,char Size,int Rreg,int CalcAddress,const char *flags,int SaveEDX) -{ - int MaskMode; - char* Regname=""; - char Flags[8]; - - - strcpy(Flags,flags); - - /* Which Masking to Use ? */ - - if (CalcAddress) - { - if (Flags[5] != '-') - MaskMode = 2; - else - MaskMode = 1; - } - else - MaskMode = 0; - - if (SaveEDX) - Flags[3] = 'D'; - else - Flags[3] = '-'; - - switch (Size) - { - case 66: - Regname = regnamesshort[0]; - break; - - case 87: - Regname = regnamesword[0]; - break; - - case 76: - Regname = regnameslong[0]; - break; - } - - switch (mode & 15) - { - - case 0: - fprintf(fp, "\t\t mov [%s+%s*4],%s\n",REG_DAT,regnameslong[Rreg],Regname); - break; - - case 1: - if (Size == 66) - { - /* Not Allowed */ - - fprintf(fp, "DUFF CODE!\n"); - } - else - { - if (Size == 87) - { - fprintf(fp, "\t\t cwde\n"); - } - - fprintf(fp, "\t\t mov [%s+%s*4],%s\n",REG_ADD,regnameslong[Rreg],regnameslong[0]); - } - break; - - case 2: - if (CalcAddress) EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - Memory_Write(Size,EDI,EAX,Flags,MaskMode); - break; - - case 3: - if (CalcAddress) EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - Memory_Write(Size,EDI,EAX,Flags,MaskMode); - break; - - case 4: - if (CalcAddress) EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - Memory_Write(Size,EDI,EAX,Flags,MaskMode); - break; - - case 5: - if (CalcAddress) - { - fprintf(fp, "\t\t push EAX\n"); - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - fprintf(fp, "\t\t pop EAX\n"); - } - Memory_Write(Size,EDI,EAX,Flags,MaskMode); - break; - - case 6: - if (CalcAddress) - { - fprintf(fp, "\t\t push EAX\n"); - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - fprintf(fp, "\t\t pop EAX\n"); - } - Memory_Write(Size,EDI,EAX,Flags,MaskMode); - break; - - case 7: - if (CalcAddress) - { - fprintf(fp, "\t\t push EAX\n"); - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - fprintf(fp, "\t\t pop EAX\n"); - } - Memory_Write(Size,EDI,EAX,Flags,MaskMode); - break; - - case 8: - if (CalcAddress) - { - fprintf(fp, "\t\t push EAX\n"); - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - fprintf(fp, "\t\t pop EAX\n"); - } - Memory_Write(Size,EDI,EAX,Flags,MaskMode); - break; - - case 9: - if (CalcAddress) - { - fprintf(fp, "\t\t push EAX\n"); - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - fprintf(fp, "\t\t pop EAX\n"); - } - Memory_Write(Size,EDI,EAX,Flags,MaskMode); - break; - - case 10: - if (CalcAddress) - { - fprintf(fp, "\t\t push EAX\n"); - EffectiveAddressCalculate(mode,Size,Rreg,SaveEDX); - fprintf(fp, "\t\t pop EAX\n"); - } - Memory_Write(Size,EDI,EAX,Flags,MaskMode); - break; - - case 11: - - /* SR, CCR - Chain to correct routine */ - - WriteCCR(Size); - } -} - -/* Condition Decode Routines */ - -/* - * mode = condition to check for - * - * Returns LABEL that is jumped to if condition is Condition - * - * Some conditions clobber AH - */ - -char *ConditionDecode(int mode, int Condition) -{ - char *Label = GenerateLabel(0,1); - - switch (mode) - { - - case 0: /* A - Always */ - if (Condition) - { - fprintf(fp, "\t\t jmp %s ;dave removed near\n",Label); - } - break; - - case 1: /* F - Never */ - if (!Condition) - { - fprintf(fp, "\t\t jmp near %s\n",Label); - } - break; - - case 2: /* Hi */ - fprintf(fp, "\t\t mov ah,dl\n"); - fprintf(fp, "\t\t sahf\n"); - - if (Condition) - { - fprintf(fp, "\t\t ja near %s\n",Label); - } - else - { - fprintf(fp, "\t\t jbe near %s\n",Label); - } - break; - - case 3: /* Ls */ - fprintf(fp, "\t\t mov ah,dl\n"); - fprintf(fp, "\t\t sahf\n"); - - if (Condition) - { - fprintf(fp, "\t\t jbe near %s\n",Label); - } - else - { - fprintf(fp, "\t\t ja near %s\n",Label); - } - break; - - case 4: /* CC */ - fprintf(fp, "\t\t test dl,1H\t\t;check carry\n"); - - if (Condition) - { - fprintf(fp, "\t\t jz near %s\n",Label); - } - else - { - fprintf(fp, "\t\t jnz near %s\n",Label); - } - break; - - case 5: /* CS */ - fprintf(fp, "\t\t test dl,1H\t\t;check carry\n"); - if (Condition) - { - fprintf(fp, "\t\t jnz near %s\n",Label); - } - else - { - fprintf(fp, "\t\t jz near %s\n",Label); - } - break; - - case 6: /* NE */ - fprintf(fp, "\t\t test dl,40H\t\t;Check zero\n"); - if (Condition) - { - fprintf(fp, "\t\t jz near %s\n",Label); - } - else - { - fprintf(fp, "\t\t jnz near %s\n",Label); - } - break; - - case 7: /* EQ */ - fprintf(fp, "\t\t test dl,40H\t\t;Check zero\n"); - if (Condition) - { - fprintf(fp, "\t\t jnz near %s\n",Label); - } - else - { - fprintf(fp, "\t\t jz near %s\n",Label); - } - break; - - case 8: /* VC */ - fprintf(fp, "\t\t test dh,8H\t\t;Check Overflow\n"); - if (Condition) - { - fprintf(fp, "\t\t jz near %s\n", Label); - } - else - { - fprintf(fp, "\t\t jnz near %s\n", Label); - } - break; - - case 9: /* VS */ - fprintf(fp, "\t\t test dh,8H\t\t;Check Overflow\n"); - if (Condition) - { - fprintf(fp, "\t\t jnz near %s\n", Label); - } - else - { - fprintf(fp, "\t\t jz near %s\n", Label); - } - break; - - case 10: /* PL */ - fprintf(fp,"\t\t test dl,80H\t\t;Check Sign\n"); - if (Condition) - { - fprintf(fp, "\t\t jz near %s\n", Label); - } - else - { - fprintf(fp, "\t\t jnz near %s\n", Label); - } - break; - - case 11: /* MI */ - fprintf(fp,"\t\t test dl,80H\t\t;Check Sign\n"); - if (Condition) - { - fprintf(fp, "\t\t jnz near %s\n", Label); - } - else - { - fprintf(fp, "\t\t jz near %s\n", Label); - } - break; - - case 12: /* GE */ - fprintf(fp, "\t\t or edx,200h\n"); - fprintf(fp, "\t\t push edx\n"); - fprintf(fp, "\t\t popf\n"); - if (Condition) - { - fprintf(fp, "\t\t jge near %s\n",Label); - } - else - { - fprintf(fp, "\t\t jl near %s\n",Label); - } - break; - - case 13: /* LT */ - fprintf(fp, "\t\t or edx,200h\n"); - fprintf(fp, "\t\t push edx\n"); - fprintf(fp, "\t\t popf\n"); - if (Condition) - { - fprintf(fp, "\t\t jl near %s\n",Label); - } - else - { - fprintf(fp, "\t\t jge near %s\n",Label); - } - break; - - case 14: /* GT */ - fprintf(fp, "\t\t or edx,200h\n"); - fprintf(fp, "\t\t push edx\n"); - fprintf(fp, "\t\t popf\n"); - if (Condition) - { - fprintf(fp, "\t\t jg near %s\n",Label); - } - else - { - fprintf(fp, "\t\t jle near %s\n",Label); - } - break; - - case 15: /* LE */ - fprintf(fp, "\t\t or edx,200h\n"); - fprintf(fp, "\t\t push edx\n"); - fprintf(fp, "\t\t popf\n"); - if (Condition) - { - fprintf(fp, "\t\t jle near %s\n",Label); - } - else - { - fprintf(fp, "\t\t jg near %s\n",Label); - } - break; - } - - return Label; -} - -/* - * mode = condition to check for - * SetWhat = text for assembler command (usually AL or address descriptor) - * - * Some conditions clobber AH - */ - -void ConditionCheck(int mode, char *SetWhat) -{ - switch (mode) - { - - case 0: /* A - Always */ - fprintf(fp, "\t\t mov %s,byte 0ffh\n",SetWhat); - break; - - case 1: /* F - Never */ - if (SetWhat[1] == 'L') - { - ClearRegister(EAX); - } - else - { - fprintf(fp, "\t\t mov %s,byte 0h\n",SetWhat); - } - break; - - case 2: /* Hi */ - fprintf(fp, "\t\t mov ah,dl\n"); - fprintf(fp, "\t\t sahf\n"); - fprintf(fp, "\t\t seta %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 3: /* Ls */ - fprintf(fp, "\t\t mov ah,dl\n"); - fprintf(fp, "\t\t sahf\n"); - fprintf(fp, "\t\t setbe %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 4: /* CC */ - fprintf(fp, "\t\t test dl,1\t\t;Check Carry\n"); - fprintf(fp, "\t\t setz %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 5: /* CS */ - fprintf(fp, "\t\t test dl,1\t\t;Check Carry\n"); - fprintf(fp, "\t\t setnz %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 6: /* NE */ - fprintf(fp, "\t\t test dl,40H\t\t;Check Zero\n"); - fprintf(fp, "\t\t setz %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 7: /* EQ */ - fprintf(fp, "\t\t test dl,40H\t\t;Check Zero\n"); - fprintf(fp, "\t\t setnz %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 8: /* VC */ - fprintf(fp, "\t\t test dh,8H\t\t;Check Overflow\n"); - fprintf(fp, "\t\t setz %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 9: /* VS */ - fprintf(fp, "\t\t test dh,8H\t\t;Check Overflow\n"); - fprintf(fp, "\t\t setnz %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 10: /* PL */ - fprintf(fp, "\t\t test dl,80H\t\t;Check Sign\n"); - fprintf(fp, "\t\t setz %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 11: /* MI */ - fprintf(fp, "\t\t test dl,80H\t\t;Check Sign\n"); - fprintf(fp, "\t\t setnz %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 12: /* GE */ - fprintf(fp, "\t\t or edx,200h\n"); - fprintf(fp, "\t\t push edx\n"); - fprintf(fp, "\t\t popf\n"); - fprintf(fp, "\t\t setge %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 13: /* LT */ - fprintf(fp, "\t\t or edx,200h\n"); - fprintf(fp, "\t\t push edx\n"); - fprintf(fp, "\t\t popf\n"); - fprintf(fp, "\t\t setl %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 14: /* GT */ - fprintf(fp, "\t\t or edx,200h\n"); - fprintf(fp, "\t\t push edx\n"); - fprintf(fp, "\t\t popf\n"); - fprintf(fp, "\t\t setg %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - - case 15: /* LE */ - fprintf(fp, "\t\t or edx,200h\n"); - fprintf(fp, "\t\t push edx\n"); - fprintf(fp, "\t\t popf\n"); - fprintf(fp, "\t\t setle %s\n",SetWhat); - fprintf(fp, "\t\t neg byte %s\n",SetWhat); - break; - } -} - - -/**********************************************************************/ -/* Instructions - Each routine generates a range of instruction codes */ -/**********************************************************************/ - -/* - * Immediate Commands - * - * ORI 00xx - * ANDI 02xx - * SUBI 04xx - * ADDI 06xx - * EORI 0axx - * CMPI 0cxx - * - */ - -void dump_imm( int type, int leng, int mode, int sreg ) -{ - int Opcode,BaseCode ; - char Size=' ' ; - char * RegnameEBX="" ; - char * Regname="" ; - char * OpcodeName[16] = {"or ", "and", "sub", "add",0,"xor","cmp",0} ; - int allow[] = {1,0,1,1, 1,1,1,1, 1,0,0,0, 0,0,0,0, 0,0,0,1, 1} ; - - Opcode = (type << 9) | ( leng << 6 ) | ( mode << 3 ) | sreg; - - BaseCode = Opcode & 0xfff8; - - if (mode == 7) BaseCode |= sreg ; - -#ifdef A7ROUTINE - if ((leng == 0) && (sreg == 7) && (mode > 2) && (mode < 5)) - { - BaseCode |= sreg ; - } -#endif - - if (type != 4) /* Not Valid (for this routine) */ - { - int Dest = EAtoAMN(Opcode, FALSE); - int SetX; - - /* ADDI & SUBI also set X flag */ - - SetX = ((type == 2) || (type == 3)); - - switch (leng) - { - case 0: - Size = 'B'; - Regname = regnamesshort[0]; - RegnameEBX = regnamesshort[EBX]; - break; - case 1: - Size = 'W'; - Regname = regnamesword[0]; - RegnameEBX = regnamesword[EBX]; - break; - case 2: - Size = 'L'; - Regname = regnameslong[0]; - RegnameEBX = regnameslong[EBX]; - break; - } - - if (allow[Dest]) - { - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - /* Save Previous PC if Memory Access */ - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (mode < 2) - { - if (Size != 'L') - TimingCycles += (CPU==2) ? 4 : 8; - else - { - TimingCycles += (CPU==2) ? 8 : 14; - if ((type != 1) && (type!=6)) - TimingCycles += 2 ; - } - } - else - { - if (type != 6) - { - if (Size != 'L') - TimingCycles += (CPU==2) ? 4 : 12 ; - else - TimingCycles += (CPU==2) ? 4 : 20 ; - } - else - { - if (Size != 'L') - TimingCycles += (CPU==2) ? 4 : 8 ; - else - TimingCycles += (CPU==2) ? 4 : 12 ; - } - } - - fprintf(fp, "\t\t and ecx,byte 7\n"); - - /* Immediate Mode Data */ - EffectiveAddressRead(11,Size,EBX,EBX,"--C-S-B",FALSE); - - /* Source Data */ - EffectiveAddressRead(Dest,Size,ECX,EAX,"-BC-SDB",FALSE); - - /* The actual work */ - fprintf(fp, "\t\t %s %s,%s\n", OpcodeName[type], Regname, RegnameEBX ); - - SetFlags(Size,EAX,FALSE,SetX,TRUE); - - if (type != 6) /* CMP no update */ - EffectiveAddressWrite(Dest,Size,ECX,EAX,"---DS-B",FALSE); - - Completed(); - } - } - else - { - /* Logicals are allowed to alter SR/CCR */ - - if ((!SetX) && (Dest == 11) && (Size != 'L') && (type != 6)) - { - Align(); - - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - TimingCycles += 20 ; - - if (Size=='W') - { - /* If SR then must be in Supervisor Mode */ - - char *Label = GenerateLabel(0,1); - - fprintf(fp, "\t\t test byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH); - fprintf(fp, "\t\t jne near %s\n\n",Label); - - /* User Mode - Exception */ - - Exception(8,BaseCode); - - fprintf(fp, "%s:\n",Label); - } - - /* Immediate Mode Data */ - EffectiveAddressRead(11,Size,EBX,EBX,"---DS-B",TRUE); - - ReadCCR(Size,ECX); - - fprintf(fp, "\t\t %s %s,%s\n", OpcodeName[type], Regname, RegnameEBX ); - - WriteCCR(Size); - - Completed(); - } - else - { - - /* Illegal Opcode */ - - OpcodeArray[BaseCode] = -1; - BaseCode = -1; - } - } - } - else - { - BaseCode = -2; - } - - OpcodeArray[Opcode] = BaseCode; -} - -void immediate(void) -{ - int type, size, mode, sreg ; - - for (type = 0 ; type < 0x7; type++) - for (size = 0 ; size < 3 ; size++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - dump_imm( type, size, mode, sreg ) ; -} - - -/* - * Bitwise Codes - * - */ - -void dump_bit_dynamic( int sreg, int type, int mode, int dreg ) -{ - int Opcode, BaseCode ; - char Size ; - char *EAXReg,*ECXReg, *Label ; - char allow[] = "0-2345678-------" ; - int Dest ; - - /* BTST allows x(PC) and x(PC,xr.s) - others do not */ - - if (type == 0) - { - allow[9] = '9'; - allow[10] = 'a'; - allow[11] = 'b'; // dave fix to nhl - } - - Opcode = 0x0100 | (sreg << 9) | (type<<6) | (mode<<3) | dreg ; - - BaseCode = Opcode & 0x01f8 ; - if (mode == 7) BaseCode |= dreg ; - - - // A7+, A7- - -#ifdef A7ROUTINE - if ((mode > 2) && (mode < 5)) - { - if (dreg == 7) BaseCode |= dreg; - } -#endif - - Dest = EAtoAMN(Opcode, FALSE); - - if (allow[Dest&0xf] != '-') - { - if (mode == 0) /* long*/ - { - /* Modify register memory directly */ - - Size = 'L' ; - EAXReg = REG_DAT_EBX; - ECXReg = regnameslong[ECX]; - } - else - { - Size = 'B' ; - EAXReg = regnamesshort[EAX]; - ECXReg = regnamesshort[ECX]; - } - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - /* Save Previous PC if Memory Access */ - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (mode<2) - { - switch (type) - { - case 0: - TimingCycles += 6 ; - break; - case 1: - case 3: - TimingCycles += 8 ; - break; - case 2: - TimingCycles += 10; - break; - } - } - else - { - if (type==0) - TimingCycles += 4; - else - TimingCycles += 8; - } - - /* Only need this sorted out if a register is involved */ - - if (Dest < 7) - { - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - } - - /* Get bit number and create mask in ECX */ - - fprintf(fp, "\t\t shr ecx, byte 9\n"); - fprintf(fp, "\t\t and ecx, byte 7\n"); - fprintf(fp, "\t\t mov ecx, [%s+ECX*4]\n",REG_DAT); - - if (Size == 'L') - fprintf(fp, "\t\t and ecx, byte 31\n"); - else - fprintf(fp, "\t\t and ecx, byte 7\n"); - - #ifdef QUICKZERO - fprintf(fp,"\t\t mov eax,1\n"); - #else - fprintf(fp,"\t\t xor eax,eax\n"); - fprintf(fp,"\t\t inc eax\n"); - #endif - - fprintf(fp,"\t\t shl eax,cl\n"); - fprintf(fp,"\t\t mov ecx,eax\n"); - - if (mode != 0) - EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",TRUE); - - - /* All commands copy existing bit to Zero Flag */ - - Label = GenerateLabel(0,1); - - fprintf(fp,"\t\t or edx,byte 40h\t; Set Zero Flag\n"); - fprintf(fp,"\t\t test %s,%s\n",EAXReg,ECXReg); - fprintf(fp,"\t\t jz short %s\n",Label); - fprintf(fp,"\t\t xor edx,byte 40h\t; Clear Zero Flag\n"); - fprintf(fp,"%s:\n",Label); - - /* Some then modify the data */ - - switch (type) - { - case 0: /* btst*/ - break; - - case 1: /* bchg*/ - fprintf(fp,"\t\t xor %s,%s\n",EAXReg,ECXReg); - break; - - case 2: /* bclr*/ - fprintf(fp,"\t\t not ecx\n"); - fprintf(fp,"\t\t and %s,%s\n",EAXReg,ECXReg); - break; - - case 3: /* bset*/ - fprintf(fp,"\t\t or %s,%s\n",EAXReg,ECXReg); - break; - } - - if ((mode !=0) && (type != 0)) - EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",TRUE); - - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -void bitdynamic(void) /* dynamic non-immediate bit operations*/ -{ - int type, sreg, mode, dreg ; - - for (sreg = 0 ; sreg < 8 ; sreg++) - for (type = 0 ; type < 4 ; type++) - for (mode = 0 ; mode < 8 ;mode++) - for (dreg = 0 ; dreg < 8 ;dreg++) - dump_bit_dynamic( sreg, type, mode, dreg ) ; -} - -void dump_bit_static(int type, int mode, int dreg ) -{ - int Opcode, BaseCode ; - char Size ; - char *EAXReg,*ECXReg, *Label ; - char allow[] = "0-2345678-------" ; - int Dest ; - - /* BTST allows x(PC) and x(PC,xr.s) - others do not */ - - if (type == 0) - { - allow[9] = '9'; - allow[10] = 'a'; - } - - Opcode = 0x0800 | (type<<6) | (mode<<3) | dreg ; - BaseCode = Opcode & 0x08f8 ; - if (mode == 7) BaseCode |= dreg ; - - // A7+, A7- - -#ifdef A7ROUTINE - if ((mode > 2) && (mode < 5)) - { - if (dreg == 7) BaseCode |= dreg; - } -#endif - - Dest = EAtoAMN(Opcode, FALSE); - - if (allow[Dest&0xf] != '-') - { - if (mode == 0) /* long*/ - { - /* Modify register memory directly */ - - Size = 'L' ; - EAXReg = REG_DAT_EBX; - ECXReg = regnameslong[ECX]; - } - else - { - Size = 'B' ; - EAXReg = regnamesshort[EAX]; - ECXReg = regnamesshort[ECX]; - } - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - /* Save Previous PC if Memory Access */ - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (mode<2) - { - switch (type) - { - case 0: - TimingCycles += 10 ; - break ; - case 1: - case 3: - TimingCycles += 12 ; - break ; - case 2: - TimingCycles += 14 ; - break ; - } - } - else - { - if (type != 0) - TimingCycles += 12 ; - else - TimingCycles += 8 ; - } - - /* Only need this sorted out if a register is involved */ - - if (Dest < 7) - { - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx, byte 7\n"); - } - - /* Get bit number and create mask in ECX */ - - Memory_Fetch('W',ECX,FALSE); - fprintf(fp, "\t\t add esi,byte 2\n"); - - if (Size == 'L') - fprintf(fp, "\t\t and ecx, byte 31\n"); - else - fprintf(fp, "\t\t and ecx, byte 7\n"); - - #ifdef QUICKZERO - fprintf(fp,"\t\t mov eax,1\n"); - #else - fprintf(fp,"\t\t xor eax,eax\n"); - fprintf(fp,"\t\t inc eax\n"); - #endif - - fprintf(fp,"\t\t shl eax,cl\n"); - fprintf(fp,"\t\t mov ecx,eax\n"); - - if (mode != 0) - EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",TRUE); - - /* All commands copy existing bit to Zero Flag */ - - Label = GenerateLabel(0,1); - - fprintf(fp,"\t\t or edx,byte 40h\t; Set Zero Flag\n"); - fprintf(fp,"\t\t test %s,%s\n",EAXReg,ECXReg); - fprintf(fp,"\t\t jz short %s\n",Label); - fprintf(fp,"\t\t xor edx,byte 40h\t; Clear Zero Flag\n"); - fprintf(fp,"%s:\n",Label); - - /* Some then modify the data */ - - switch (type) - { - case 0: /* btst*/ - break; - - case 1: /* bchg*/ - fprintf(fp,"\t\t xor %s,%s\n",EAXReg,ECXReg); - break; - - case 2: /* bclr*/ - fprintf(fp,"\t\t not ecx\n"); - fprintf(fp,"\t\t and %s,%s\n",EAXReg,ECXReg); - break; - - case 3: /* bset*/ - fprintf(fp,"\t\t or %s,%s\n",EAXReg,ECXReg); - break; - } - - if ((mode !=0) && (type != 0)) - EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",TRUE); - - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - - -void bitstatic(void) /* static non-immediate bit operations*/ -{ - int type, mode, dreg ; - - for (type = 0 ; type < 4 ; type++) - for (mode = 0 ; mode < 8 ;mode++) - for (dreg = 0 ; dreg < 8 ;dreg++) - dump_bit_static( type, mode, dreg ) ; -} - -/* - * Move Peripheral - * - */ - -void movep(void) -{ - int sreg,dir,leng,dreg ; - int Opcode, BaseCode ; - - for (sreg = 0 ; sreg < 8 ; sreg++) - { - for (dir = 0 ; dir < 2 ; dir++) - { - for (leng = 0 ; leng < 2 ; leng++) - { - for (dreg = 0 ; dreg < 8 ; dreg++) - { - Opcode = 0x0108 | (sreg<<9) | (dir<<7) | (leng<<6) | dreg; - BaseCode = Opcode & 0x01c8 ; - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - SavePreviousPC(); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (leng == 0) /* word */ - TimingCycles += 16 ; - else - TimingCycles += 24 ; - - /* Save Flags Register (so we only do it once) */ - - fprintf(fp, "\t\t push edx\n"); - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - - /* Get Address to Read/Write in EDI */ - - EffectiveAddressCalculate(5,'L',EBX,FALSE); - - fprintf(fp, "\t\t shr ecx,byte 9\n"); - fprintf(fp, "\t\t and ecx,byte 7\n"); - - - if (dir == 0) /* from memory to register*/ - { - Memory_Read('B',EDI,"-BC-SDB",2); /* mask first call */ - fprintf(fp,"\t\t mov bh,al\n"); - fprintf(fp,"\t\t add edi,byte 2\n"); - Memory_Read('B',EDI,"-BC-SDB",0); /* not needed then */ - fprintf(fp,"\t\t mov bl,al\n"); - - if (leng == 0) /* word d(Ax) into Dx.W*/ - { - fprintf(fp,"\t\t mov [%s+ecx*4],bx\n",REG_DAT); - } - else /* long d(Ax) into Dx.L*/ - { - fprintf(fp,"\t\t add edi,byte 2\n"); - fprintf(fp,"\t\t shl ebx,16\n"); - Memory_Read('B',EDI,"-BC-SDB",0); - fprintf(fp,"\t\t mov bh,al\n"); - fprintf(fp,"\t\t add edi,byte 2\n"); - Memory_Read('B',EDI,"-BC-S-B",0); - fprintf(fp,"\t\t mov bl,al\n"); - fprintf(fp,"\t\t mov [%s+ecx*4],ebx\n",REG_DAT); - } - } - else /* Register to Memory*/ - { - fprintf(fp,"\t\t mov eax,[%s+ecx*4]\n",REG_DAT); - - /* Move bytes into Line */ - - if (leng == 1) - fprintf(fp,"\t\t rol eax,byte 8\n"); - else - fprintf(fp,"\t\t rol eax,byte 24\n"); - - Memory_Write('B',EDI,EAX,"A---SDB",2); /* Mask First */ - fprintf(fp,"\t\t add edi,byte 2\n"); - fprintf(fp,"\t\t rol eax,byte 8\n"); - - if (leng == 1) /* long*/ - { - Memory_Write('B',EDI,EAX,"A---SDB",0); - fprintf(fp,"\t\t add edi,byte 2\n"); - fprintf(fp,"\t\t rol eax,byte 8\n"); - Memory_Write('B',EDI,EAX,"A---SDB",0); - fprintf(fp,"\t\t add edi,byte 2\n"); - fprintf(fp,"\t\t rol eax,byte 8\n"); - } - Memory_Write('B',EDI,EAX,"A---S-B",0); - } - - fprintf(fp, "\t\t pop edx\n"); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } - } - } -} - -void movecodes(int allowfrom[],int allowto[],int Start,char Size) /* MJC */ -{ - int Opcode; - int Src,Dest; - int SaveEDX; - int BaseCode; - - for (Opcode=Start;Opcode> 6, TRUE); - - if ((allowfrom[(Src & 15)]) && (allowto[(Dest & 15)])) - { - /* If we are not going to calculate the flags */ - /* we need to preserve the existing ones */ - - SaveEDX = (Dest == 1); - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if (((Src >= 2) && (Src <= 10)) || ((Dest >= 2) && (Dest <=10))) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - - TimingCycles += 4 ; - - if (Src < 7) - { - if (Dest < 7) - { - fprintf(fp, "\t\t mov ebx,ecx\n"); - - if ((Src == 0) && allowfrom[1]) - fprintf(fp, "\t\t and ebx,byte 15\n"); - else - fprintf(fp, "\t\t and ebx,byte 7\n"); - - EffectiveAddressRead(Src,Size,EBX,EAX,"--CDS-B",SaveEDX); - } - else - { - if ((Src == 0) && allowfrom[1]) - fprintf(fp, "\t\t and ecx,byte 15\n"); - else - fprintf(fp, "\t\t and ecx,byte 7\n"); - - EffectiveAddressRead(Src,Size,ECX,EAX,"---DS-B",SaveEDX); - } - } - else - { - if (Dest < 7) - EffectiveAddressRead(Src,Size,EBX,EAX,"--CDS-B",SaveEDX); - else - EffectiveAddressRead(Src,Size,EBX,EAX,"---DS-B",SaveEDX); - } - - /* No flags if Destination Ax */ - - if (!SaveEDX) - { - SetFlags(Size,EAX,TRUE,FALSE,TRUE); - } - - if (Dest < 7) - { - fprintf(fp, "\t\t shr ecx,9\n"); - fprintf(fp, "\t\t and ecx,byte 7\n"); - } - - EffectiveAddressWrite(Dest,Size,ECX,TRUE,"---DS-B",SaveEDX); - - Completed(); - } - else - { - BaseCode = -1; /* Invalid Code */ - } - } - else - { - BaseCode = OpcodeArray[BaseCode]; - } - - if (OpcodeArray[Opcode] < 0) - OpcodeArray[Opcode] = BaseCode; - } -} - -void moveinstructions(void) -{ - int allowfrom[] = {1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}; - int allowto[] = {1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0}; - - /* For Byte */ - - movecodes(allowfrom,allowto,0x1000,'B'); - - /* For Word & Long */ - - allowto[1] = 1; - movecodes(allowfrom,allowto,0x2000,'L'); - movecodes(allowfrom,allowto,0x3000,'W'); -} - -/* - * - * Opcodes 5### - * - * ADDQ,SUBQ,Scc and DBcc - * - */ - -void opcode5(void) -{ - /* ADDQ,SUBQ,Scc and DBcc */ - - int allowtoScc[] = {1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0}; - int allowtoADDQ[] = {1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0}; - int Opcode,BaseCode; - char Label[32]; - char Label2[32]; - char Size=' '; - char* Regname=""; - char* RegnameECX=""; - - for (Opcode = 0x5000;Opcode < 0x6000;Opcode++) - { - if ((Opcode & 0xc0) == 0xc0) - { - /* Scc or DBcc */ - - BaseCode = Opcode & 0x5FF8; - if ((BaseCode & 0x38) == 0x38) BaseCode |= (Opcode & 7); - - /* If mode = 3 or 4 and register = A7 */ - /* then make it a separate code */ - -#ifdef A7ROUTINE - if (((Opcode & 0x3F) == 0x1F) || ((Opcode & 0x3F) == 0x27)) - { - BaseCode |= 0x07; - } -#endif - - if (OpcodeArray[BaseCode] == -2) - { - OpcodeArray[BaseCode] = BaseCode; - - if ((BaseCode & 0x38) == 0x8) - { - /* DBcc */ - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - TimingCycles += 10 ; - - - strcpy(Label,GenerateLabel(BaseCode,1)) ; - strcpy(Label2,ConditionDecode((Opcode >> 8) & 0x0F,TRUE)); - - /* False - Decrement Counter - Loop if not -1 */ - - fprintf(fp, "\t\t and ecx,byte 7\n"); - fprintf(fp, "\t\t mov ax,[%s+ecx*4]\n",REG_DAT); - fprintf(fp, "\t\t dec ax\n"); - fprintf(fp, "\t\t mov [%s+ecx*4],ax\n",REG_DAT); - fprintf(fp, "\t\t inc ax\t\t; Is it -1\n"); - fprintf(fp, "\t\t jz short %s\n",Label); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - Memory_Fetch('W',EAX,TRUE); - fprintf(fp, "\t\t add esi,eax\n"); - Completed(); - - /* True - Exit Loop */ - fprintf(fp, "%s:\n",Label); - - fprintf(fp, "%s:\n",Label2); - fprintf(fp, "\t\t add esi,byte 4\n"); - TimingCycles += 2 ; - - Completed(); - } - else - { - /* Scc */ - - int Dest = EAtoAMN(Opcode, FALSE); - - if (allowtoScc[(Dest & 15)]) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (Dest > 1) - TimingCycles += 8 ; - else - TimingCycles += 4 ; - - if (Dest < 7) - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - } - - if (Dest > 1) - { - EffectiveAddressCalculate(Dest,'B',ECX,TRUE); - /* ASG - no longer need to mask addresses here */ -/* fprintf(fp,"\t\t and edi,0FFFFFFh\n");*/ - } - - ConditionCheck((Opcode >> 8) & 0x0F,"AL"); - - EffectiveAddressWrite(Dest,'B',ECX,FALSE,"---DS-B",TRUE); - - /* take advantage of AL being 0 for false, 0xff for true */ - /* need to add 2 cycles if register and condition is true */ - - if (Dest == 0) - { - fprintf(fp, "\t\t and eax,byte 2\n"); - fprintf(fp, "\t\t add eax,byte %d\n",TimingCycles); - fprintf(fp, "\t\t sub dword [%s],eax\n",ICOUNT); - - TimingCycles = -1; - } - Completed(); - } - else - { - OpcodeArray[BaseCode] = -1; - BaseCode = -1; - } - } - } - else - { - BaseCode = OpcodeArray[BaseCode]; - } - - OpcodeArray[Opcode] = BaseCode; - } - else - { - /* ADDQ or SUBQ */ - - BaseCode = Opcode & 0x51F8; - if ((BaseCode & 0x38) == 0x38) BaseCode |= (Opcode & 7); - - /* Special for Address Register Direct - Force LONG */ - - if ((Opcode & 0x38) == 0x8) BaseCode = ((BaseCode & 0xFF3F) | 0x80); - - - /* If mode = 3 or 4 and Size = byte and register = A7 */ - /* then make it a separate code */ - -#ifdef A7ROUTINE - if ((Opcode & 0xC0) == 0) - { - if (((Opcode & 0x3F) == 0x1F) || ((Opcode & 0x3F) == 0x27)) - { - BaseCode |= 0x07; - } - } -#endif - - if (OpcodeArray[BaseCode] == -2) - { - char *Operation; - int Dest = EAtoAMN(Opcode, FALSE); - int SaveEDX = (Dest == 1); - - if (allowtoADDQ[(Dest & 15)]) - { - switch (BaseCode & 0xC0) - { - case 0: - Size = 'B'; - Regname = regnamesshort[0]; - RegnameECX = regnamesshort[ECX]; - break; - - case 0x40: - Size = 'W'; - Regname = regnamesword[0]; - RegnameECX = regnamesword[ECX]; - break; - - case 0x80: - Size = 'L'; - Regname = regnameslong[0]; - RegnameECX = regnameslong[ECX]; - break; - } - - OpcodeArray[BaseCode] = BaseCode; - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (Dest == 0) /* write to Dx */ - { - if (Size != 'L') - TimingCycles += 4 ; - else - TimingCycles += 8 ; - } - - if (Dest == 1) - { - if ((Size == 'L') || (Opcode & 0x100)) /* if long or SUBQ */ - TimingCycles += 8 ; - else - TimingCycles += 4 ; - } - - if (Dest > 1) /* write to mem */ - { - if (Size != 'L') - TimingCycles += 8 ; - else - TimingCycles += 12 ; - } - - if (Dest < 7) - { - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - } - - if (Dest > 1) - { - EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",SaveEDX); - } - - /* Sub Immediate from Opcode */ - - fprintf(fp, "\t\t shr ecx,9\n"); - - Immediate8(); - - if (Opcode & 0x100) - { - /* SUBQ */ - Operation = "sub"; - } - else - { - /* ADDQ */ - Operation = "add"; - } - - /* For Data or Address register, operate directly */ - /* on the memory location. Don't load into EAX */ - - if (Dest < 2) - { - if (Dest == 0) - { - fprintf(fp, "\t\t %s [%s+ebx*4],%s\n",Operation,REG_DAT,RegnameECX); - } - else - { - fprintf(fp, "\t\t %s [%s+ebx*4],%s\n",Operation,REG_ADD,RegnameECX); - } - } - else - { - fprintf(fp, "\t\t %s %s,%s\n",Operation,Regname,RegnameECX); - } - - /* No Flags for Address Direct */ - - if (!SaveEDX) - { - /* Directly after ADD or SUB, so test not needed */ - - SetFlags(Size,EAX,FALSE,TRUE,TRUE); - } - - if (Dest > 1) - { - EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",FALSE); - } - - Completed(); - } - else - { - OpcodeArray[BaseCode] = -1; - BaseCode = -1; - } - } - else - { - BaseCode = OpcodeArray[BaseCode]; - } - - OpcodeArray[Opcode] = BaseCode; - } - } -} - -/* - * Branch Instructions - * - * BSR, Bcc - * - */ - -void branchinstructions(void) -{ - int Opcode,BaseCode; - int Counter; - char *Label; - char jmpLabel[40] ; - - for (Opcode = 0x60;Opcode < 0x70;Opcode++) - { - /* Displacement = 0 -> 16 Bit displacement */ - - BaseCode = Opcode * 0x100; - OpcodeArray[BaseCode] = BaseCode; - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 10 ; - - if (Opcode == 0x60) - { - Memory_Fetch('W',EAX,TRUE); - fprintf(fp, "\t\t add esi,eax\n"); - MemoryBanking(BaseCode); - Completed(); - } - else - { - if (Opcode != 0x61) - { - Label = ConditionDecode(Opcode & 0x0F,TRUE); - - /* Code for Failed branch */ - - fprintf(fp, "\t\t add esi,byte 2\n"); - - /* 2 less cycles for Failure */ - - TimingCycles -= 2; - Completed(); - TimingCycles += 2; - - /* Successful Branch */ - - Align(); - fprintf(fp, "%s:\n",Label); - - Memory_Fetch('W',EAX,TRUE); - fprintf(fp, "\t\t add esi,eax\n"); - MemoryBanking(BaseCode+2); - Completed(); - - } - else - { - /* BSR - Special Case */ - - TimingCycles += 8 ; - - Memory_Fetch('W',EBX,TRUE); - fprintf(fp, "\t\t add ebx,esi\n"); - - fprintf(fp, "\t\t add esi,byte 2\n"); - PushPC(ECX,EAX,"-B-DS-B",1); - - fprintf(fp, "\t\t mov esi,ebx\n"); - MemoryBanking(BaseCode+3); - Completed(); - } - } - - /* 8 Bit Displacement */ - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode+1,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 10 ; - - if (Opcode > 0x60) - { - if (Opcode != 0x61) - { - Label = ConditionDecode(Opcode & 0x0F,TRUE); - - /* Code for Failed branch */ - - TimingCycles -= 2; - Completed(); - TimingCycles += 2; - - /* Successful Branch */ - - Align(); - fprintf(fp, "%s:\n",Label); - } - else - { - /* BSR - Special Case */ - - TimingCycles += 8 ; - - PushPC(EDI,EBX,"--CDS-B",1); - } - } - - /* Common Ending */ - - fprintf(fp, "\t\t movsx eax,cl ; Sign Extend displacement\n"); - fprintf(fp, "\t\t add esi,eax\n"); - MemoryBanking(BaseCode+5); - Completed(); - - /* Fill up Opcode Array */ - - for (Counter=1;Counter<0x100;Counter++) - OpcodeArray[BaseCode+Counter] = BaseCode+1; - - if(CPU==2) - { - - /* 8 bit 0xff & 68020 instruction - 32 bit displacement */ - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode+0xff,0)); - sprintf( jmpLabel, GenerateLabel(BaseCode+0xff,1) ) ; - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 10 ; - - if (Opcode == 0x60) - { - /* bra - always branch */ - Memory_Fetch('L',EAX,FALSE); - fprintf(fp, "\t\t add esi,eax\n"); - MemoryBanking(BaseCode+6); - Completed(); - } - else - { - if (Opcode != 0x61) - { - Label = ConditionDecode(Opcode & 0x0F,TRUE); - - /* Code for Failed branch */ - fprintf(fp, "\t\t add esi,byte 4\n"); - - TimingCycles -= 2; - Completed(); - TimingCycles += 2; - - /* Successful Branch */ - Align(); - fprintf(fp, "%s:\n",Label); - - Memory_Fetch('L',EAX,FALSE); - fprintf(fp, "\t\t add esi,eax\n"); - MemoryBanking(BaseCode+8); - Completed(); - } - else - { - /* BSR - Special Case */ - - TimingCycles += 8 ; - - Memory_Fetch('L',EBX,TRUE); - fprintf(fp, "\t\t add ebx,esi\n"); - - fprintf(fp, "\t\t add esi,byte 4\n"); - PushPC(ECX,EAX,"-B-DS-B",1); - - fprintf(fp, "\t\t mov esi,ebx\n"); - MemoryBanking(BaseCode+9); - Completed(); - } - } - - OpcodeArray[BaseCode+0xff] = BaseCode+0xff; - } - } -} - -/* - * Move Quick Commands - * - * Fairly simple, as only allowed to Data Registers - * - */ - -void moveq(void) -{ - int Count; - - /* The Code */ - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(0x7000,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 4 ; - - fprintf(fp, "\t\t movsx eax,cl\n"); - fprintf(fp, "\t\t shr ecx,9\n"); - fprintf(fp, "\t\t and ecx,byte 7\n"); - SetFlags('L',EAX,TRUE,FALSE,FALSE); - EffectiveAddressWrite(0,'L',ECX,TRUE,"---DS-B",FALSE); - Completed(); - - /* Set OpcodeArray (Not strictly correct, since some are illegal!) */ - - for (Count=0x7000;Count<0x8000;Count++) - { - OpcodeArray[Count] = 0x7000; - } -} - -/* - * Extended version of Add & Sub commands - * - */ - -void addx_subx(void) -{ - int Opcode, BaseCode ; - int regx,type,leng,rm,regy,mode ; - int ModeModX; - int ModeModY; - char Size=' ' ; - char * Regname="" ; - char * RegnameEBX="" ; - char * Operand=""; - char * Label; - - for (type = 0 ; type < 2 ; type ++) /* 0=subx, 1=addx */ - for (regx = 0 ; regx < 8 ; regx++) - for (leng = 0 ; leng < 3 ; leng++) - for (rm = 0 ; rm < 2 ; rm++) - for (regy = 0 ; regy < 8 ; regy++) - { - Opcode = 0x9100 | (type<<14) | (regx<<9) | (leng<<6) | (rm<<3) | regy ; - - BaseCode = Opcode & 0xd1c8 ; - - ModeModX = 0; - ModeModY = 0; - -#ifdef A7ROUTINE - if ((rm == 1) && (leng == 0)) - { - if (regx == 7) - { - BaseCode |= (regx << 9); - ModeModY = 16; - } - if (regy == 7) - { - BaseCode |= regy; - ModeModX = 16; - } - } -#endif - - if (rm == 0) - mode = 0 ; - else - mode = 4 ; - - switch (leng) - { - case 0: - Size = 'B'; - Regname = regnamesshort[0]; - RegnameEBX = regnamesshort[EBX]; - break; - case 1: - Size = 'W'; - Regname = regnamesword[0]; - RegnameEBX = regnamesword[EBX]; - break; - case 2: - Size = 'L'; - Regname = regnameslong[0]; - RegnameEBX = regnameslong[EBX]; - break; - } - - if (OpcodeArray[BaseCode] == -2) - { - if (type == 0) - Operand = "sbb"; - else - Operand = "adc"; - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if (mode == 4) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - /* don't add in EA timing for ADDX,SUBX */ - - AddEACycles = 0 ; - - if (rm == 0) /* reg to reg */ - { - if (Size != 'L') - TimingCycles += 4 ; - else - TimingCycles += 8 ; - } - else - { - if (Size != 'L') - TimingCycles += 18 ; - else - TimingCycles += 30 ; - } - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx, byte 7\n"); - fprintf(fp, "\t\t shr ecx, byte 9\n"); - fprintf(fp, "\t\t and ecx, byte 7\n"); - - /* Get Source */ - - EffectiveAddressRead(mode+ModeModX,Size,EBX,EBX,"--CDS-B",FALSE); - - /* Get Destination (if needed) */ - - if (mode == 4) - EffectiveAddressRead(mode+ModeModY,Size,ECX,EAX,"-BCDSDB",FALSE); - - /* Copy the X flag into the Carry Flag */ - - CopyX(); - - /* Do the sums */ - - if (mode == 0) - fprintf(fp, "\t\t %s [%s+ecx*4],%s\n",Operand,REG_DAT,RegnameEBX); - else - fprintf(fp, "\t\t %s %s,%s\n",Operand,Regname,RegnameEBX); - - /* Preserve old Z flag */ - - fprintf(fp, "\t\t mov ebx,edx\n"); - - /* Set the Flags */ - - SetFlags(Size,EAX,FALSE,TRUE,FALSE); - - /* Handle the Z flag */ - - Label = GenerateLabel(0,1); - - fprintf(fp, "\t\t jnz short %s\n\n",Label); - - fprintf(fp, "\t\t and dl,0BFh ; Remove Z\n"); - fprintf(fp, "\t\t and bl,40h ; Mask out Old Z\n"); - fprintf(fp, "\t\t or dl,bl ; Copy across\n\n"); - fprintf(fp, "%s:\n",Label); - - /* Update the Data (if needed) */ - - if (mode == 4) - EffectiveAddressWrite(mode,Size,ECX,FALSE,"---DS-B",TRUE); - - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -/* - * Logicals / Simple Maths (+ and -) - * - * OR,AND,CMP,EOR,ADD and SUB - * - */ - -void dumpx( int start, int reg, int type, char * Op, int dir, int leng, int mode, int sreg ) -{ - int Opcode,BaseCode ; - char Size=' ' ; - char * RegnameECX="" ; - char * Regname="" ; - int Dest ; - int SaveEDX ; - int SaveDir; - char * allow="" ; - char * allowtypes[] = { "0-23456789ab----", "--2345678-------", - "0123456789ab----", "0-2345678-------"}; - - SaveDir = dir; - - switch (type) - { - case 0: /* or and*/ - if (dir == 0) - allow = allowtypes[0]; - else - allow = allowtypes[1]; - break ; - - case 1: /* cmp*/ - allow = allowtypes[2] ; - break ; - - case 2: /* eor*/ - allow = allowtypes[3] ; - break ; - - case 3: /* adda suba cmpa*/ - allow = allowtypes[2] ; - break ; - - case 4: /* sub add*/ - if (dir == 0) - allow = allowtypes[0] ; - else - allow = allowtypes[1] ; - break ; - } - - if ((type == 4) && (dir == 0) && (leng > 0)) - { - allow = allowtypes[2] ; /* word and long ok*/ - } - - Opcode = start | (reg << 9 ) | (dir<<8) | (leng<<6) | (mode<<3) | sreg; - - BaseCode = Opcode & 0xf1f8; - - if (mode == 7) BaseCode |= sreg ; - -#ifdef A7ROUTINE - if ((mode == 3 || mode == 4) && ( leng == 0 ) && (sreg == 7 )) - BaseCode |= sreg ; -#endif - - - - /* If Source = Data or Address register - combine into same routine */ - - if (((Opcode & 0x38) == 0x08) && (allow[1] != '-')) - { - BaseCode &= 0xfff7; - } - - Dest = EAtoAMN(Opcode, FALSE); - SaveEDX = (Dest == 1) || (type == 3); - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[BaseCode] == -2) - { - switch (leng) - { - case 0: - Size = 'B'; - Regname = regnamesshort[0]; - RegnameECX = regnamesshort[ECX]; - break; - case 1: - Size = 'W'; - Regname = regnamesword[0]; - RegnameECX = regnamesword[ECX]; - break; - case 2: - Size = 'L'; - Regname = regnameslong[0]; - RegnameECX = regnameslong[ECX]; - break; - - case 3: /* cmpa adda suba */ - if (dir == 0) - { - Size = 'W'; - Regname = regnamesword[0]; - RegnameECX = regnamesword[ECX]; - } - else - { - Size = 'L'; - Regname = regnameslong[0]; - RegnameECX = regnameslong[ECX]; - } - dir = 0 ; - break ; - } - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (dir==0) - { - if (Size != 'L') - TimingCycles += 4; - else - TimingCycles += 6; - } - else - { - if (Size != 'L') - TimingCycles += 8; - else - TimingCycles += 12; - } - - if ((mode == 0) && (dir==0) && (Size == 'L')) - TimingCycles += 2 ; - - if ((mode == 1) && (dir==0) && (Size != 'L')) - TimingCycles += 4 ; - - if (Dest < 7) /* Others do not need reg.no. */ - { - fprintf(fp, "\t\t mov ebx,ecx\n"); - - if ((Dest == 0) & (allow[1] != '-')) - fprintf(fp, "\t\t and ebx,byte 15\n"); - else - fprintf(fp, "\t\t and ebx,byte 7\n"); - } - - fprintf(fp, "\t\t shr ecx,byte 9\n"); - fprintf(fp, "\t\t and ecx,byte 7\n"); - - EffectiveAddressRead(Dest,Size,EBX,EAX,"-BCDSDB",SaveEDX); - - if (dir == 0) - { - if (type != 3) - { - fprintf(fp, "\t\t %s [%s+ECX*4],%s\n",Op ,REG_DAT ,Regname ) ; - - if (type == 4) - SetFlags(Size,EAX,FALSE,TRUE,FALSE); - else - SetFlags(Size,EAX,FALSE,FALSE,FALSE); - } - else - { - if (Size == 'W') - fprintf(fp, "\t\t cwde\n"); - - fprintf(fp, "\t\t %s [%s+ECX*4],EAX\n",Op ,REG_ADD); - - if (Op[0] == 'c') - { - SetFlags('L',EAX,FALSE,FALSE,FALSE); - } - } - } - else - { - fprintf(fp, "\t\t %s %s,[%s+ECX*4]\n", Op, Regname ,REG_DAT ) ; - - if (type == 4) - SetFlags(Size,EAX,FALSE,TRUE,TRUE); - else - SetFlags(Size,EAX,FALSE,FALSE,TRUE); - - EffectiveAddressWrite(Dest,Size,EBX,FALSE,"---DS-B",FALSE); - } - Completed(); - } - - OpcodeArray[Opcode] = BaseCode; - } - - dir = SaveDir; -} - -void typelogicalmath(void) -{ - int dir, leng, mode, sreg ,reg ; - - for (reg = 0 ; reg < 8 ; reg++) - { - /* or */ - for (dir = 0 ; dir < 2 ; dir++) - for (leng = 0 ; leng < 3; leng++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - dumpx( 0x8000, reg, 0, "or ", dir, leng, mode, sreg ) ; - - /* sub */ - for (dir = 0 ; dir < 2 ; dir++) - for (leng = 0 ; leng < 3; leng++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - dumpx( 0x9000, reg, 4, "sub", dir, leng, mode, sreg ) ; - - /* suba */ - - for (dir = 0 ; dir < 2 ; dir++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - dumpx( 0x9000, reg, 3, "sub", dir, 3, mode, sreg ) ; - - - /* cmp */ - for (leng = 0 ; leng < 3; leng++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - dumpx( 0xb000, reg, 1, "cmp", 0, leng, mode, sreg ) ; - - /* cmpa */ - - for (dir = 0 ; dir < 2 ; dir++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - dumpx( 0xb000, reg, 3, "cmp", dir, 3, mode, sreg ) ; - - /* adda */ - - for (dir = 0 ; dir < 2 ; dir++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - dumpx( 0xd000, reg, 3, "add", dir, 3, mode, sreg ) ; - - - /* eor */ - for (leng = 0 ; leng < 3; leng++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - dumpx( 0xb100, reg, 2, "xor", 1, leng, mode, sreg ) ; - - /* and */ - for (dir = 0 ; dir < 2 ; dir++) - for (leng = 0 ; leng < 3; leng++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - dumpx( 0xc000, reg, 0, "and", dir, leng, mode, sreg ) ; - - /* add */ - for (dir = 0 ; dir < 2 ; dir++) - for (leng = 0 ; leng < 3; leng++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - dumpx( 0xd000, reg, 4, "add", dir, leng, mode, sreg ) ; - } -} - -/* - * Single commands missed out by routines above - * - */ - -void mul(void) -{ - int dreg, type, mode, sreg ; - int Opcode, BaseCode ; - int Dest ; - char allow[] = "0-23456789ab-----" ; - - for (dreg = 0 ; dreg < 8 ; dreg++) - for (type = 0 ; type < 2 ; type++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0xc0c0 | (dreg<<9) | (type<<8) | (mode<<3) | sreg ; - BaseCode = Opcode & 0xc1f8 ; - if (mode == 7) - { - BaseCode |= sreg ; - } - - Dest = EAtoAMN(Opcode, FALSE); - if (allow[Dest&0x0f] != '-') - { - if (OpcodeArray[ BaseCode ] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 70 ; - - if (mode < 7) - { - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - } - - fprintf(fp, "\t\t shr ecx, byte 9\n"); - fprintf(fp, "\t\t and ecx, byte 7\n"); - - EffectiveAddressRead(Dest,'W',EBX,EAX,"ABCDSDB",FALSE); - - if (type == 0) - fprintf(fp, "\t\t mul word [%s+ECX*4]\n",REG_DAT); - else - fprintf(fp, "\t\t imul word [%s+ECX*4]\n",REG_DAT); - - fprintf(fp, "\t\t shl edx, byte 16\n"); - fprintf(fp, "\t\t mov dx,ax\n"); - fprintf(fp, "\t\t mov [%s+ECX*4],edx\n",REG_DAT); - SetFlags('L',EDX,TRUE,FALSE,FALSE); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -void mull(void) -{ - int mode, sreg ; - int Opcode, BaseCode ; - int Dest ; - char allow[] = "0-23456789ab-----" ; - char *Label = NULL ; - - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0x4c00 | (mode<<3) | sreg ; - BaseCode = Opcode & 0x4c38 ; - if (mode == 7) - { - BaseCode |= sreg ; - } - - Dest = EAtoAMN(Opcode, FALSE); - if (allow[Dest&0x0f] != '-') - { - if (OpcodeArray[ BaseCode ] == -2) - { - TimingCycles += 70 ; - Align(); - Label = GenerateLabel(BaseCode,0); - fprintf(fp, "%s:\n",Label); - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (mode < 7) - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - } - - Memory_Fetch('W', EBX, FALSE ); // fetch the next word - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - EffectiveAddressRead(Dest,'L',ECX,EAX,"ABCDSDB",FALSE); // read from the EA - - fprintf(fp, "\t\t mov ecx,ebx\n"); // save 2nd word in ecx - fprintf(fp, "\t\t shr ebx,12\n"); // ebx = Dl register - fprintf(fp, "\t\t and ebx,7\n"); // 0-7 - - Label = GenerateLabel(BaseCode,1); - - fprintf(fp, "\t\t test ecx,0x0800\n"); // signed/unsigned? - fprintf(fp, "\t\t jz short %s\n",Label); // skip if unsigned - - fprintf(fp, "\t\t imul dword [%s+EBX*4]\n",REG_DAT); // signed 32x32->64 - fprintf(fp, "\t\t jmp short %s_1\n",Label); // skip - - fprintf(fp, "%s:\n",Label); - fprintf(fp, "\t\t mul dword [%s+EBX*4]\n",REG_DAT); // unsigned 32x32->64 - - fprintf(fp, "%s_1:\n",Label); - fprintf(fp, "\t\t mov [%s+EBX*4],eax\n",REG_DAT); // store Dl back - - fprintf(fp, "\t\t test ecx,0x0400\n"); // do we care? - fprintf(fp, "\t\t jz short %s_2\n",Label); // if not, skip - fprintf(fp, "\t\t and ecx,7\n"); // get Dh register - fprintf(fp, "\t\t mov [%s+ECX*4],edx\n",REG_DAT); // store upper 32 bits - SetFlags('L',EDX,TRUE,FALSE,FALSE); // set the flags - fprintf(fp, "\t\t and edx,~0x0800\n"); // clear the overflow - fprintf(fp, "\t\t jmp short %s_3\n",Label); // skip - - fprintf(fp, "%s_2:\n",Label); - fprintf(fp, "\t\t mov ebx,edx\n"); // save upper 32 in ebx - SetFlags('L',EAX,TRUE,FALSE,FALSE); // set the flags - fprintf(fp, "\t\t sar eax,31\n"); // eax = sign-extended - fprintf(fp, "\t\t test ecx,0x0800\n"); // signed/unsigned? - fprintf(fp, "\t\t jnz short %s_4\n",Label); // skip if signed - fprintf(fp, "\t\t xor eax,eax\n"); // always use 0 for unsigned - fprintf(fp, "%s_4:\n",Label); - fprintf(fp, "\t\t cmp eax,ebx\n"); // compare upper 32 against eax - fprintf(fp, "\t\t je short %s_3\n",Label); // if equal to sign extension, skip - fprintf(fp, "\t\t or edx,0x0800\n"); // set the overflow - - fprintf(fp, "%s_3:\n",Label); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -void divl(void) -{ - int mode, sreg ; - int Opcode, BaseCode ; - int Dest ; - char allow[] = "0-23456789ab-----" ; - char *Label = NULL ; - - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0x4c40 | (mode<<3) | sreg ; - BaseCode = Opcode & 0x4c78 ; - if (mode == 7) - { - BaseCode |= sreg ; - } - - Dest = EAtoAMN(Opcode, FALSE); - if (allow[Dest&0x0f] != '-') - { - if (OpcodeArray[ BaseCode ] == -2) - { - TimingCycles += 70 ; - Align(); - Label = GenerateLabel(BaseCode,0); - fprintf(fp, "%s:\n",Label); - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t push edx\n"); // save edx - fprintf(fp, "\t\t add esi,byte 2\n\n"); - fprintf(fp, "\t\t and ecx,byte 7\n"); // read from ea - - Memory_Fetch('W', EDX, FALSE ); // fetch 2nd word in ecx - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - EffectiveAddressRead(Dest,'L',ECX,EBX,"---DSDB",FALSE); - - fprintf(fp, "\t\t push esi\n"); // save and 0 esi - ClearRegister(ESI); - - Label = GenerateLabel(BaseCode,1); - - fprintf(fp, "\t\t test ebx,ebx\n"); // check divisor against 0 - fprintf(fp, "\t\t jz near %s_ZERO\n",Label); // handle divide-by-zero -// low part always used - fprintf(fp, "\t\t mov ecx,edx\n"); // ecx = extension word - fprintf(fp, "\t\t shr edx,12\n"); // edx = Dq register - fprintf(fp, "\t\t and edx,7\n"); // 0-7 - fprintf(fp, "\t\t mov eax,[%s+edx*4]\n",REG_DAT); // eax = Dq register value - - ClearRegister(EDX); // edx = 0 - fprintf(fp, "\t\t test ecx,0x0400\n"); // check size - fprintf(fp, "\t\t jz short %s_1\n",Label); // skip if 32-bit dividend -// high longword (64bit) - fprintf(fp, "\t\t mov edx,ecx\n"); // edx = extension word - fprintf(fp, "\t\t and edx,7\n"); // 0-7 - fprintf(fp, "\t\t mov edx,[%s+edx*4]\n",REG_DAT); // fetch upper 32-bits - - fprintf(fp, "\t\t test ecx,0x0800\n"); // signed? - fprintf(fp, "\t\t jz near %s_3\n",Label); // if not, skip to unsigned 64-bit - fprintf(fp, "\t\t jmp near %s_2\n",Label); // skip to signed 64-bit case - - fprintf(fp, "%s_1:\n",Label); // short case - ClearRegister(EDX); // clear edx - fprintf(fp, "\t\t test ecx,0x0800\n"); // signed? - fprintf(fp, "\t\t jz short %s_3\n",Label); // if not, don't convert - fprintf(fp, "\t\t cdq\n"); // sign extend into edx -// signed - fprintf(fp, "%s_2:\n",Label); // signed 32/64-bit case - fprintf(fp, "\t\t or esi,1\n"); // esi |= 1 to indicate signed - fprintf(fp, "\t\t test ebx,ebx\n"); // check divisor sign - fprintf(fp, "\t\t jge short %s_2b\n",Label); // if >= 0, don't set - fprintf(fp, "\t\t or esi,2\n"); // esi |= 2 to indicate negative divisor - fprintf(fp, "\t\t neg ebx\n"); // make positive - fprintf(fp, "%s_2b:\n",Label); - fprintf(fp, "\t\t test edx,edx\n"); // check dividend sign - fprintf(fp, "\t\t jge short %s_3\n",Label); // if >= 0, don't set - fprintf(fp, "\t\t push ebx\n"); // save ebx - fprintf(fp, "\t\t push ecx\n"); // save ecx - ClearRegister(EBX); // clear ebx - ClearRegister(ECX); // clear ecx - fprintf(fp, "\t\t sub ebx,eax\n"); // ebx = 0 - eax - fprintf(fp, "\t\t sbb ecx,edx\n"); // ecx = 0 - edx - fprintf(fp, "\t\t mov eax,ebx\n"); // eax = ebx - fprintf(fp, "\t\t mov edx,ecx\n"); // edx = ecx - fprintf(fp, "\t\t pop ecx\n"); // restore ecx - fprintf(fp, "\t\t pop ebx\n"); // restore ebx - fprintf(fp, "\t\t or esi,4\n"); // esi |= 4 to indicate negative dividend -// unsigned - fprintf(fp, "%s_3:\n",Label); // unsigned 32/64-bit case - fprintf(fp, "\t\t cmp ebx,edx\n"); // check ebx against upper 32 bits - fprintf(fp, "\t\t jbe near %s_OVERFLOW\n",Label); // generate overflow - fprintf(fp, "\t\t div ebx\n"); // do the divide - fprintf(fp, "\t\t test esi,esi\n"); // see if we need to post process - fprintf(fp, "\t\t jz short %s_4\n",Label); // if not, skip - fprintf(fp, "\t\t jpo short %s_4\n",Label); // if PO (pos*pos or neg*neg), leave the result - fprintf(fp, "\t\t neg eax\n"); // negate the result - -// store results - fprintf(fp, "%s_4:\n",Label); - fprintf(fp, "\t\t mov ebx,ecx\n"); // ebx = extension word - fprintf(fp, "\t\t and ebx,7\n"); // get Dr in ebx - fprintf(fp, "\t\t shr ecx,12\n"); // ecx = Dq - fprintf(fp, "\t\t and ecx,7\n"); // 0-7 - fprintf(fp, "\t\t mov [%s+ebx*4],edx\n",REG_DAT); // store remainder first - fprintf(fp, "\t\t mov [%s+ecx*4],eax\n",REG_DAT); // store quotient second - fprintf(fp, "\t\t pop esi\n"); // restore esi - fprintf(fp, "\t\t pop edx\n"); // restore edx - SetFlags('L',EAX,TRUE,FALSE,FALSE); // set the flags - fprintf(fp, "%s_5:\n",Label); - fprintf(fp, "\t\t and edx,~1\n"); // clear the carry - Completed(); - - fprintf(fp, "%s_ZERO:\t\t ;Do divide by zero trap\n", Label); - /* Correct cycle counter for error */ - fprintf(fp, "\t\t pop esi\n"); // restore esi - fprintf(fp, "\t\t pop edx\n"); // restore edx - fprintf(fp, "\t\t add dword [%s],byte %d\n",ICOUNT,95); - fprintf(fp,"\t\t jmp short %s_5\n",Label); - Exception(5,BaseCode); - - fprintf(fp, "%s_OVERFLOW:\n",Label); -//set overflow - fprintf(fp, "\t\t pop esi\n"); // restore esi - fprintf(fp, "\t\t pop edx\n"); // restore edx - fprintf(fp, "\t\t or edx,0x0800\n"); // set the overflow bit - fprintf(fp, "\t\t jmp near %s_5\n",Label); // done - - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -void bfext(void) -{ -// just bfextu/bfexts for now - char allow[] = "0-2--56789a-----" ; - char *Label = NULL ; - int mode,dreg,sign,Opcode,BaseCode,Dest ; - for (mode=0; mode<8; mode++) - for (dreg=0; dreg<8; dreg++) - for (sign=0; sign<2; sign++) - { - Opcode = 0xe9c0 | (sign<<9) | (mode<<3) | dreg ; - BaseCode = Opcode & 0xebf8 ; - if (mode == 7) - BaseCode |= dreg ; - Dest = EAtoAMN(Opcode, FALSE); - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[BaseCode] == -2) - { - Align(); - Label = GenerateLabel(BaseCode,0); - fprintf(fp, "%s:\n",Label); - Label = GenerateLabel(BaseCode,1); - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (mode < 7) - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - } - - Memory_Fetch('W', EAX, FALSE ) ; - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - EffectiveAddressRead(Dest,'L',ECX,EDX,"ABCDSDB",FALSE); // edx = dword - - fprintf(fp, "\t\t mov ecx,eax\n"); - fprintf(fp, "\t\t shr ecx,byte 6\n"); - fprintf(fp, "\t\t test eax,0x0800\n"); - fprintf(fp, "\t\t je short %s_1\n",Label); - //get offset from Dx - fprintf(fp, "\t\t and ecx,byte 7\n"); - fprintf(fp, "\t\t mov ecx,[%s+ECX*4]\n",REG_DAT); - //get offset from extension - fprintf(fp, "%s_1:\n",Label); - fprintf(fp, "\t\t and ecx,31\n"); // ecx = offset - fprintf(fp, "\t\t mov ebx,eax\n"); - fprintf(fp, "\t\t test eax,0x0020\n"); - fprintf(fp, "\t\t je short %s_2\n",Label); - //get width from Dy - fprintf(fp, "\t\t and ebx,byte 7\n"); - fprintf(fp, "\t\t mov ebx,[%s+EBX*4]\n",REG_DAT); - //get width from extension - fprintf(fp, "%s_2:\n",Label); - //fix 0=32 - fprintf(fp, "\t\t sub ebx,byte 1\n"); - fprintf(fp, "\t\t and ebx,byte 31\n"); - fprintf(fp, "\t\t add ebx,byte 1\n"); // ebx = width - fprintf(fp, "\t\t rol edx,cl\n"); - // check for N - fprintf(fp, "\t\t mov ecx,32\n"); - fprintf(fp, "\t\t sub ecx,ebx\n"); - fprintf(fp, "\t\t mov ebx,edx\n"); - SetFlags('L',EBX,TRUE,FALSE,FALSE); - if (sign) - fprintf(fp, "\t\t sar ebx,cl\n"); - else - fprintf(fp, "\t\t shr ebx,cl\n"); - fprintf(fp, "\t\t shr eax,12\n"); - fprintf(fp, "\t\t and eax,7\n"); - fprintf(fp, "\t\t mov [%s+EAX*4],ebx\n",REG_DAT); - fprintf(fp, "\t\t test ebx,ebx\n"); - fprintf(fp, "\t\t jnz short %s_3\n",Label); - //zero flag - fprintf(fp, "\t\t or edx,40h\n"); - fprintf(fp, "%s_3:\n",Label); - Completed(); - } - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * not - * clr - * neg - * negx - * - */ - -void not(void) -{ - int type,leng, mode, sreg ; - int Opcode, BaseCode ; - int Dest ; - int SaveEDX=0; - char Size=' ' ; - char * Regname="" ; - char * RegnameECX ; - char * Label; - - char allow[] = "0-2345678-------" ; - - for (type = 0 ; type < 4 ; type++) - for (leng = 0 ; leng < 3 ; leng++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0x4000 | (type<<9) | (leng<<6) | (mode<<3) | sreg ; - BaseCode = Opcode & 0x46f8 ; - if (mode == 7) - { - BaseCode |= sreg ; - } - - // A7+, A7- - -#ifdef A7ROUTINE - if ((leng == 0) && (sreg == 7) && (mode > 2) && (mode < 5)) - { - BaseCode |= sreg ; - } -#endif - - Dest = EAtoAMN(Opcode, FALSE); - - if (allow[Dest&0x0f] != '-') - { - switch (leng) - { - case 0: - Size = 'B'; - Regname = regnamesshort[0]; - RegnameECX = regnamesshort[ECX]; - break; - case 1: - Size = 'W'; - Regname = regnamesword[0]; - RegnameECX = regnamesword[ECX]; - break; - case 2: - Size = 'L'; - Regname = regnameslong[0]; - RegnameECX = regnameslong[ECX]; - break; - } - - if (OpcodeArray[ BaseCode ] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (Size != 'L') - TimingCycles += 4; - else - TimingCycles += 6; - - if (Dest < 7) - fprintf(fp, "\t\t and ecx,byte 7\n"); - - if (type == 0) SaveEDX = TRUE; - else SaveEDX = FALSE; - - /* CLR does not need to read source (although it does on a real 68000) */ - - if (type != 1) - { - EffectiveAddressRead(Dest,Size,ECX,EAX,"A-CDS-B",SaveEDX); - } - - switch (type) - { - case 0: /* negx */ - - /* Preserve old Z flag */ - - fprintf(fp, "\t\t mov ebx,edx\n"); - - CopyX(); - fprintf(fp, "\t\t adc %s,byte 0\n", Regname ) ; - fprintf(fp, "\t\t neg %s\n", Regname ) ; - - /* Set the Flags */ - - SetFlags(Size,EAX,FALSE,TRUE,FALSE); - - /* Handle the Z flag */ - - Label = GenerateLabel(0,1); - - fprintf(fp, "\t\t jnz short %s\n\n",Label); - - fprintf(fp, "\t\t and edx,byte -65 ; Remove Z\n"); - fprintf(fp, "\t\t and ebx,byte 40h ; Mask out Old Z\n"); - fprintf(fp, "\t\t or edx,ebx ; Copy across\n\n"); - fprintf(fp, "%s:\n",Label); - - break; - - case 1: /* clr */ - ClearRegister(EAX); - EffectiveAddressWrite(Dest,Size,ECX,TRUE,"----S-B",FALSE); - fprintf(fp, "\t\t mov edx,40H\n"); - break; - - case 2: /* neg */ - fprintf(fp, "\t\t neg %s\n",Regname ) ; - SetFlags(Size,EAX,FALSE,TRUE,TRUE); - break; - - case 3: /* not */ - fprintf(fp, "\t\t xor %s,-1\n",Regname ) ; - SetFlags(Size,EAX,FALSE,FALSE,TRUE); - break; - } - - /* Update (unless CLR command) */ - - if (type != 1) - EffectiveAddressWrite(Dest,Size,ECX,FALSE,"---DS-B",TRUE); - - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * Move to/from USP - * - */ - -void moveusp(void) -{ - int Opcode, BaseCode ; - int dir, sreg ; - char * Label; - - for (dir = 0 ; dir < 2 ; dir++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0x4e60 | ( dir << 3 ) | sreg ; - BaseCode = Opcode & 0x4e68 ; - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - Label = GenerateLabel(BaseCode,0); - fprintf(fp, "%s\n", Label ); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 4; - - fprintf(fp, "\t\t test byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH); - fprintf(fp, "\t\t jz short OP%d_%4.4x_Trap\n",CPU,BaseCode); - - fprintf(fp, "\t\t and ecx,7\n"); - - if (dir == 0) /* reg 2 USP */ - { - fprintf(fp, "\t\t mov eax,[%s+ECX*4]\n",REG_ADD); - fprintf(fp, "\t\t mov [%s],eax\n",REG_USP); - } - else - { - fprintf(fp, "\t\t mov eax,[%s]\n",REG_USP); - fprintf(fp, "\t\t mov [%s+ECX*4],eax\n",REG_ADD); - } - Completed(); - - fprintf(fp, "OP%d_%4.4x_Trap:\n",CPU,BaseCode); - Exception(8,BaseCode); - } - OpcodeArray[Opcode] = BaseCode ; - } -} - - -/* - * Check - * - */ - -void chk(void) -{ - int dreg,mode,sreg,size ; - int Opcode, BaseCode ; - int Dest ; - char * Label ; - - char *allow = "0-23456789ab----" ; - - for (size = 0 ; size < (CPU==2 ? 2 : 1); size++) - for (dreg = 0 ; dreg < 8; dreg++) - for (mode = 0 ; mode < 8; mode++) - for (sreg = 0 ; sreg < 8; sreg++) - { - if (size == 0) /* word */ - Opcode = 0x4180 | (dreg<<9) | (mode<<3) | sreg ; - else /* long */ - Opcode = 0x4100 | (dreg<<9) | (mode<<3) | sreg ; - BaseCode = Opcode & 0x41f8 ; - - if (mode == 7) - { - BaseCode |= sreg ; - } - - Dest = EAtoAMN(Opcode, FALSE); - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[BaseCode] == -2) - { - Align(); - Label = GenerateLabel(BaseCode,0); - fprintf(fp, "%s:\n", Label ); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 10; - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t shr ebx,byte 9\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - - if (Dest < 7) - fprintf(fp, "\t\t and ecx,byte 7\n"); - - EffectiveAddressRead(Dest,(size == 0) ? 'W' : 'L',ECX,EAX,"----S-B",FALSE); - - if (size == 0) /* word */ - { - fprintf(fp, "\t\t movsx ebx,word [%s+EBX*4]\n",REG_DAT); - fprintf(fp, "\t\t movsx eax,ax\n"); - } - else /* long */ - fprintf(fp, "\t\t mov ebx,[%s+EBX*4]\n",REG_DAT); - - fprintf(fp, "\t\t test ebx,ebx\n"); /* is word bx < 0 */ - fprintf(fp, "\t\t jl near OP%d_%4.4x_Trap_minus\n",CPU,BaseCode); - - fprintf(fp, "\t\t cmp ebx,eax\n"); - fprintf(fp, "\t\t jg near OP%d_%4.4x_Trap_over\n",CPU,BaseCode); - Completed(); - - /* N is set if data less than zero */ - - Align(); - fprintf(fp, "OP%d_%4.4x_Trap_minus:\n",CPU,BaseCode); - fprintf(fp, "\t\t or edx,0x0080\n"); /* N flag = 80H */ - fprintf(fp, "\t\t jmp short OP%d_%4.4x_Trap_Exception\n",CPU,BaseCode); - - /* N is cleared if greated than compared number */ - - Align(); - fprintf(fp, "OP%d_%4.4x_Trap_over:\n",CPU,BaseCode); - fprintf(fp, "\t\t and edx,0x007f\n"); /* N flag = 80H */ - - fprintf(fp, "OP%d_%4.4x_Trap_Exception:\n",CPU,BaseCode); - fprintf(fp, "\t\t mov al,6\n"); - Exception(-1,0x10000+BaseCode); - Completed(); - - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -void chk2(void) -{ -#if 0 - int mode,sreg,size ; - int Opcode, BaseCode ; - int Dest ; - char * Label ; - - char *allow = "--2--56789a-----" ; - - for (size = 0 ; size < 2; size++) - for (mode = 0 ; mode < 8; mode++) - for (sreg = 0 ; sreg < 8; sreg++) - { - Opcode = 0x00c0 | (size<<9) | (mode<<3) | sreg; - BaseCode = Opcode & 0xfff8 ; - - if (mode == 7) - { - BaseCode |= sreg ; - } - - Dest = EAtoAMN(Opcode, FALSE); - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[BaseCode] == -2) - { - Align(); - Label = GenerateLabel(BaseCode,0); - fprintf(fp, "%s:\n", Label ); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 10; - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t shr ebx,byte 9\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - - if (Dest < 7) - fprintf(fp, "\t\t and ecx,byte 7\n"); - - EffectiveAddressRead(Dest,'W',ECX,EAX,"----S-B",FALSE); - - if (size == 0) /* word */ - { - fprintf(fp, "\t\t movsx ebx,word [%s+EBX*4]\n",REG_DAT); - fprintf(fp, "\t\t movsx eax,ax\n"); - } - else /* long */ - fprintf(fp, "\t\t mov ebx,[%s+EBX*4]\n",REG_DAT); - - fprintf(fp, "\t\t test ebx,ebx\n"); /* is word bx < 0 */ - fprintf(fp, "\t\t jl near OP%d_%4.4x_Trap_minus\n",CPU,BaseCode); - - fprintf(fp, "\t\t cmp ebx,eax\n"); - fprintf(fp, "\t\t jg near OP%d_%4.4x_Trap_over\n",CPU,BaseCode); - Completed(); - - /* N is set if data less than zero */ - - Align(); - fprintf(fp, "OP%d_%4.4x_Trap_minus:\n",CPU,BaseCode); - fprintf(fp, "\t\t or edx,0x0080\n"); /* N flag = 80H */ - fprintf(fp, "\t\t jmp short OP%d_%4.4x_Trap_Exception\n",CPU,BaseCode); - - /* N is cleared if greated than compared number */ - - Align(); - fprintf(fp, "OP%d_%4.4x_Trap_over:\n",CPU,BaseCode); - fprintf(fp, "\t\t and edx,0x007f\n"); /* N flag = 80H */ - - fprintf(fp, "OP%d_%4.4x_Trap_Exception:\n",CPU,BaseCode); - fprintf(fp, "\t\t mov al,6\n"); - Exception(-1,0x10000+BaseCode); - Completed(); - - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -#endif -} - -/* - * Load Effective Address - */ - -void LoadEffectiveAddress(void) -{ - int Opcode, BaseCode ; - int sreg,mode,dreg ; - int Dest ; - char allow[] = "--2--56789a-----" ; - - for (sreg = 0 ; sreg < 8 ; sreg++) - for (mode = 0 ; mode < 8 ; mode++) - for (dreg = 0 ; dreg < 8 ; dreg++) - { - Opcode = 0x41c0 | (sreg<<9) | (mode<<3) | dreg ; - - BaseCode = Opcode & 0x41f8 ; - - if (mode == 7) - BaseCode = BaseCode | dreg ; - - Dest = EAtoAMN(BaseCode, FALSE); - - if (allow[Dest&0x0f] != '-') - { - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - switch (mode) - { - case 2: - TimingCycles += 4; - break; - case 5: - case 7: - case 9: - TimingCycles += 8; - break; - case 6: - case 8: - case 10: - TimingCycles += 12; - break; - } - - if (mode < 7) - { - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - } - - fprintf(fp, "\t\t shr ecx,byte 9\n"); - fprintf(fp, "\t\t and ecx,byte 7\n"); - - EffectiveAddressCalculate(Dest,'L',EBX,TRUE); - fprintf(fp, "\t\t mov [%s+ECX*4],edi\n",REG_ADD); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * Negate BCD - * - */ - -void nbcd(void) -{ - int Opcode, BaseCode ; - int sreg,mode,Dest ; - char allow[] = "0-2345678-------" ; - - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0x4800 | (mode<<3) | sreg ; - BaseCode = Opcode & 0x4838 ; - - if (mode == 7) - BaseCode |= sreg ; - - // A7+, A7- - -#ifdef A7ROUTINE - if ((sreg == 7) && (mode > 2) && (mode < 5)) - { - BaseCode |= sreg; - } -#endif - - Dest = EAtoAMN(BaseCode, FALSE); - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (mode < 2) - TimingCycles += 6; - else - TimingCycles += 8; - - fprintf(fp, "\t\t and ecx, byte 7\n"); - - EffectiveAddressRead(Dest,'B',ECX,EBX,"--C-SDB",FALSE); - - ClearRegister(EAX); - CopyX(); - - fprintf(fp, "\t\t sbb al,bl\n"); - fprintf(fp, "\t\t das\n"); - - SetFlags('B',EAX,FALSE,TRUE,TRUE); - - EffectiveAddressWrite(Dest,'B',ECX,EAX,"----S-B",FALSE); - Completed(); - } - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -void tas(void) -{ - int Opcode, BaseCode ; - int sreg,mode,Dest ; - char allow[] = "0-2345678-------" ; - - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0x4ac0 | (mode<<3) | sreg ; - BaseCode = Opcode & 0x4af8 ; - - if (mode == 7) - BaseCode |= sreg ; - -#ifdef A7ROUTINE - if ((sreg == 7) && (mode > 2) && (mode < 5)) - { - BaseCode |= sreg ; - } -#endif - - Dest = EAtoAMN(BaseCode, FALSE); - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (mode < 2) - TimingCycles += 4; - else - TimingCycles += 14; - - fprintf(fp, "\t\t and ecx, byte 7\n"); - - EffectiveAddressRead(Dest,'B',ECX,EAX,"--C-SDB",FALSE); - - SetFlags('B',EAX,TRUE,FALSE,TRUE); - fprintf(fp, "\t\t or al,128\n"); - - EffectiveAddressWrite(Dest,'B',ECX,EAX,"----S-B",FALSE); - Completed(); - } - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * push Effective Address - */ - -void PushEffectiveAddress(void) -{ - int Opcode, BaseCode ; - int mode,dreg ; - int Dest ; - char allow[] = "--2--56789a-----" ; - - for (mode = 0 ; mode < 8 ; mode++) - for (dreg = 0 ; dreg < 8 ; dreg++) - { - Opcode = 0x4840 | (mode<<3) | dreg ; - - BaseCode = Opcode & 0x4878 ; - - if (mode == 7) - BaseCode = BaseCode | dreg ; - - Dest = EAtoAMN(BaseCode, FALSE); - - if (allow[Dest&0x0f] != '-') - { - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - SavePreviousPC(); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - switch (mode) - { - case 2: - TimingCycles += 12; - break; - case 5: - case 7: - case 9: - TimingCycles += 16; - break; - case 6: - case 8: - case 10: - TimingCycles += 20; - break; - } - - if (mode < 7) - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - } - - EffectiveAddressCalculate(Dest,'L',ECX,TRUE); - - fprintf(fp, "\t\t mov ecx,[%s]\t ; Push onto Stack\n",REG_A7); - fprintf(fp, "\t\t sub ecx,byte 4\n"); - fprintf(fp, "\t\t mov [%s],ecx\n",REG_A7); - Memory_Write('L',ECX,EDI,"---DS-B",2); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * Test - * - */ - -void tst(void) -{ - int leng, mode, sreg ; - int Opcode, BaseCode ; - int Dest ; - char Size=' ' ; - char * Regname ; - char * RegnameECX ; - - char allow[] = "0-2345678-------" ; - if (CPU==2) - allow[1] = '1'; - - for (leng = 0 ; leng < 3 ; leng++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0x4a00 | (leng<<6) | (mode<<3) | sreg ; - BaseCode = Opcode & 0x4af8 ; - if (mode == 7) - { - BaseCode |= sreg ; - } - - // A7+, A7- - -#ifdef A7ROUTINE - if ((leng == 0) && (sreg == 7) && (mode > 2) && (mode < 5)) - { - BaseCode |= sreg ; - } -#endif - - Dest = EAtoAMN(Opcode, FALSE); - - if ((allow[Dest&0x0f] != '-') || (( mode == 1 ) && (leng != 0))) - { - switch (leng) - { - case 0: - Size = 'B'; - Regname = regnamesshort[0]; - RegnameECX = regnamesshort[ECX]; - break; - case 1: - Size = 'W'; - Regname = regnamesword[0]; - RegnameECX = regnamesword[ECX]; - break; - case 2: - Size = 'L'; - Regname = regnameslong[0]; - RegnameECX = regnameslong[ECX]; - break; - } - - if (OpcodeArray[ BaseCode ] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 4; - - if (Dest < 7) - fprintf(fp, "\t\t and ecx,byte 7\n"); - - EffectiveAddressRead(Dest,Size,ECX,EAX,"----S-B",FALSE); - - SetFlags(Size,EAX,TRUE,FALSE,FALSE); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * Move registers too / from memory - * - */ - -void movem_reg_ea(void) -{ - int leng,mode,sreg ; - int Opcode, BaseCode ; - int Dest ; - char Size ; - char * Label ; - - char *allow = "--2-45678-------" ; - - for (leng = 0 ; leng < 2; leng++) - for (mode = 0 ; mode < 8; mode++) - for (sreg = 0 ; sreg < 8; sreg++) - { - Opcode = 0x4880 | ( leng<<6) | (mode<<3) | sreg ; - BaseCode = Opcode & 0x4cf8 ; - - if (mode == 7) - { - BaseCode |= sreg ; - } - - Dest = EAtoAMN(Opcode, FALSE); - - Size = "WL"[leng] ; - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[BaseCode] == - 2) - { - Align(); - Label = GenerateLabel(BaseCode,0); - fprintf(fp, "%s:\n",Label ) ; - SavePreviousPC(); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - switch (mode) - { - case 2: - case 4: - TimingCycles += 8 ; - break; - case 5: - case 7: - TimingCycles += 12 ; - break; - case 6: - case 8: - TimingCycles += 14 ; - break; - } - - fprintf(fp, "\t\t push edx\n"); - - Memory_Fetch('W',EDX,FALSE); - fprintf(fp, "\t\t add esi,byte 2\n"); - - if (mode < 7) - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - } - - if (mode == 4) - { - fprintf(fp, "\t\t push ecx\n"); - fprintf(fp, "\t\t mov edi,[%s+ECX*4]\n",REG_ADD); - } - else - EffectiveAddressCalculate(Dest,'L',ECX,TRUE); - - fprintf(fp, "\t\t mov ebx,1\n"); - - /* predecrement uses d0-d7..a0-a7 a7 first*/ - /* other modes use a7-a0..d7-d0 d0 first*/ - - if (Dest != 4) - ClearRegister(ECX); - else - fprintf(fp, "\t\t mov ecx,3Ch\n"); - - fprintf(fp, "OP%d_%4.4x_Again:\n",CPU,BaseCode); - fprintf(fp, "\t\t test edx,ebx\n"); - fprintf(fp, "\t\t je OP%d_%4.4x_Skip\n",CPU,BaseCode); - - fprintf(fp, "\t\t mov eax,[%s+ecx]\n",REG_DAT); /* load eax with current reg data */ - - if (Dest == 4) - { - if (Size == 'W') /* adjust pointer before write */ - fprintf(fp, "\t\t sub edi,byte 2\n"); - else - fprintf(fp, "\t\t sub edi,byte 4\n"); - } - - Memory_Write(Size,EDI,EAX,"-BCDSDB",1); - - if (Dest != 4) - { - if (Size == 'W') /* adjust pointer after write */ - fprintf(fp, "\t\t add edi,byte 2\n"); - else - fprintf(fp, "\t\t add edi,byte 4\n"); - } - - /* Update Cycle Count */ - - if (Size == 'W') - fprintf(fp, "\t\t sub dword [%s],byte 4\n",ICOUNT); - else - fprintf(fp, "\t\t sub dword [%s],byte 8\n",ICOUNT); - - fprintf(fp, "OP%d_%4.4x_Skip:\n",CPU,BaseCode); - - if (Dest != 4) - fprintf(fp, "\t\t add ecx,byte 4h\n"); - else - fprintf(fp, "\t\t sub ecx,byte 4h\n"); - - fprintf(fp, "\t\t add ebx,ebx\n"); /* faster than shl ebx,1 */ - fprintf(fp, "\t\t test bx,bx\n"); /* check low 16 bits */ - fprintf(fp, "\t\t jnz OP%d_%4.4x_Again\n",CPU,BaseCode); - - if (Dest == 4) - { - fprintf(fp, "\t\t pop ecx\n"); - fprintf(fp, "\t\t mov [%s+ECX*4],edi\n",REG_ADD); - } - - fprintf(fp, "\t\t pop edx\n"); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -void movem_ea_reg(void) -{ - int leng,mode,sreg ; - int Opcode, BaseCode ; - int Dest ; - char Size ; - char * Label ; - - char *allow = "--23-56789a-----" ; - - for (leng = 0 ; leng < 2; leng++) - for (mode = 0 ; mode < 8; mode++) - for (sreg = 0 ; sreg < 8; sreg++) - { - Opcode = 0x4c80 | ( leng<<6) | (mode<<3) | sreg ; - BaseCode = Opcode & 0x4cf8 ; - - if (mode == 7) - { - BaseCode |= sreg ; - } - - Dest = EAtoAMN(Opcode, FALSE); - - Size = "WL"[leng] ; - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[BaseCode] == - 2) - { - Align(); - Label = GenerateLabel(BaseCode,0); - - fprintf(fp, "%s:\n",Label ) ; - SavePreviousPC(); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - switch (mode) - { - case 2: - case 4: - TimingCycles += 8 ; - break; - case 5: - case 7: - TimingCycles += 12 ; - break; - case 6: - case 8: - TimingCycles += 14 ; - break; - } - - fprintf(fp, "\t\t push edx\n"); /* save edx because sr is unaffected */ - - Memory_Fetch('W',EDX,FALSE); - fprintf(fp, "\t\t add esi,byte 2\n"); - - if (mode < 7) - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - } - - if (mode == 3) - fprintf(fp, "\t\t push ecx\n"); /* if (An)+ then it needed later */ - - EffectiveAddressCalculate(Dest,'L',ECX,TRUE); - - fprintf(fp, "\t\t mov ebx,1\n"); /* setup register list mask */ - - /* predecrement uses d0-d7..a0-a7 a7 first*/ - /* other modes use a7-a0..d7-d0 d0 first*/ - - ClearRegister(ECX); /* always start with D0 */ - - fprintf(fp, "OP%d_%4.4x_Again:\n",CPU,BaseCode); - fprintf(fp, "\t\t test edx,ebx\n"); /* is bit set for this register? */ - fprintf(fp, "\t\t je OP%d_%4.4x_Skip\n",CPU,BaseCode); - - Memory_Read(Size,EDI,"-BCDSDB",1); - - if (Size == 'W') - fprintf(fp, "\t\t cwde\n"); /* word size must be sign extended */ - - fprintf(fp, "\t\t mov [%s+ecx],eax\n",REG_DAT); /* load current reg with eax */ - - if (Size == 'W') /* adjust pointer after write */ - fprintf(fp, "\t\t add edi,byte 2\n"); - else - fprintf(fp, "\t\t add edi,byte 4\n"); - - /* Update Cycle Count */ - - if (Size == 'W') - fprintf(fp, "\t\t sub dword [%s],byte 4\n",ICOUNT); - else - fprintf(fp, "\t\t sub dword [%s],byte 8\n",ICOUNT); - - fprintf(fp, "OP%d_%4.4x_Skip:\n",CPU,BaseCode); - fprintf(fp, "\t\t add ecx,byte 4\n"); /* adjust pointer to next reg */ - fprintf(fp, "\t\t add ebx,ebx\n"); /* Faster than shl ebx,1 */ - fprintf(fp, "\t\t test bx,bx\n"); /* check low 16 bits */ - fprintf(fp, "\t\t jnz OP%d_%4.4x_Again\n",CPU,BaseCode); - - if (mode == 3) - { - fprintf(fp, "\t\t pop ecx\n"); - fprintf(fp, "\t\t mov [%s+ECX*4],edi\n",REG_ADD); /* reset Ax if mode = (Ax)+ */ - } - - fprintf(fp, "\t\t pop edx\n"); /* restore flags */ - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * Link / Unlink - * - * Local stack space - * - */ - -void link(void) -{ - int sreg ; - int Opcode, BaseCode ; - - for (sreg = 0 ; sreg < 8; sreg++) - { - Opcode = 0x4e50 | sreg ; - BaseCode = 0x4e50 ; - - if (OpcodeArray[BaseCode] == - 2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - SavePreviousPC(); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 16; - - fprintf(fp, "\t\t sub dword [%s],byte 4\n",REG_A7); - - fprintf(fp, "\t\t and ecx, byte 7\n"); - fprintf(fp, "\t\t mov eax,[%s+ECX*4]\n",REG_ADD); - fprintf(fp, "\t\t mov edi,[%s]\n",REG_A7); - fprintf(fp, "\t\t mov [%s+ECX*4],edi\n",REG_ADD); - - Memory_Write('L',EDI,EAX,"---DS-B",1); - - Memory_Fetch('W',EAX,TRUE); - fprintf(fp, "\t\t add esi,byte 2\n"); - fprintf(fp, "\t\t add [%s],eax\n",REG_A7); - - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -void unlinkasm(void) -{ - int sreg ; - int Opcode, BaseCode ; - - for (sreg = 0 ; sreg < 8; sreg++) - { - Opcode = 0x4e58 | sreg ; - BaseCode = 0x4e58 ; - - if (OpcodeArray[BaseCode] == - 2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - SavePreviousPC(); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 12; - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx, byte 7\n"); - fprintf(fp, "\t\t mov edi,[%s+EBX*4]\n",REG_ADD); - - Memory_Read('L',EDI,"-B-DSDB",1); - - fprintf(fp, "\t\t mov [%s+EBX*4],eax\n",REG_ADD); - fprintf(fp, "\t\t add edi,byte 4\n"); - fprintf(fp, "\t\t mov dword [%s],EDI\n",REG_A7); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -void trap(void) -{ - int Count; - int BaseCode = 0x4E40; - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - fprintf(fp, "\t\t mov eax,ecx\n"); - fprintf(fp, "\t\t and eax,byte 15\n"); - fprintf(fp, "\t\t or eax,byte 32\n"); - Exception(-1,BaseCode); - Completed(); - } - - for (Count=0;Count<=15;Count++) - OpcodeArray[BaseCode+Count] = BaseCode; -} - -void reset(void) -{ - int BaseCode = 0x4E70; - char * Label; - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - Label = GenerateLabel(BaseCode,0); - - TimingCycles += 132; - - fprintf(fp, "%s:\n", Label ); - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - fprintf(fp, "\t\t test byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH); - fprintf(fp, "\t\t jnz near OP%d_%4.4x_RESET\n",CPU,BaseCode); - Exception(8,BaseCode); - - fprintf(fp, "\nOP%d_%4.4x_RESET:\n",CPU,BaseCode); - - /* Prefetch next instruction */ - - if(CPU==2) - { - /* 32 bit memory version */ - - fprintf(fp, "\t\t xor esi,2\n"); /* ASG */ -#ifdef STALLCHECK - ClearRegister(ECX); - fprintf(fp, "\t\t mov cx,[esi+ebp]\n"); -#else - fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n"); -#endif - fprintf(fp, "\t\t xor esi,2\n"); /* ASG */ - } - else - { - /* 16 bit memory */ -#ifdef STALLCHECK - ClearRegister(ECX); - fprintf(fp, "\t\t mov cx,[esi+ebp]\n"); -#else - fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n"); -#endif - } - - fprintf(fp, "\t\t mov eax,dword [%s]\n", REG_RESET_CALLBACK); - fprintf(fp, "\t\t test eax,eax\n"); - fprintf(fp, "\t\t jz near OP%d_%4.4x_END\n",CPU,BaseCode); - - /* Callback for Reset */ - - fprintf(fp, "\t\t mov [%s],ESI,\n",REG_PC); - fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR); - fprintf(fp, "\t\t push ECX\n"); - - fprintf(fp, "\t\t call [eax]\n"); - - fprintf(fp, "\t\t mov ESI,[%s]\n",REG_PC); - fprintf(fp, "\t\t mov edx,[%s]\n",REG_CCR); - fprintf(fp, "\t\t pop ECX\n"); - fprintf(fp, "\t\t mov ebp,dword [_OP_ROM]\n"); - - fprintf(fp, "OP%d_%4.4x_END:\n",CPU,BaseCode); - fprintf(fp, "\t\t sub dword [%s],%d\n",ICOUNT,TimingCycles); - fprintf(fp, "\t\t jmp [%s_OPCODETABLE+ecx*4]\n\n", CPUtype); - } - OpcodeArray[BaseCode] = BaseCode ; -} - -void nop(void) -{ - int BaseCode = 0x4e71 ; - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 4; - - Completed(); - OpcodeArray[BaseCode] = BaseCode ; - } -} - -void stop(void) -{ - char TrueLabel[16]; - int BaseCode = 0x4e72 ; - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 4; - - /* Must be in Supervisor Mode */ - - sprintf(TrueLabel,GenerateLabel(0,1)); - - fprintf(fp, "\t\t test byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH); - fprintf(fp, "\t\t je near %s\n\n",TrueLabel); - - /* Next WORD is new SR */ - - Memory_Fetch('W',EAX,FALSE); - fprintf(fp, "\t\t add esi,byte 2\n"); - - WriteCCR('W'); - - /* See if Valid interrupt waiting */ - - CheckInterrupt = 0; - - fprintf(fp, "\t\t mov eax,[%s]\n",REG_IRQ); - fprintf(fp, "\t\t and eax,byte 07H\n"); - - fprintf(fp, "\t\t cmp al,7\t\t ; Always take 7\n"); - fprintf(fp, "\t\t je near procint\n\n"); - - fprintf(fp, "\t\t mov ebx,[%s]\t\t; int mask\n",REG_SRH); - fprintf(fp, "\t\t and ebx,byte 07H\n"); - fprintf(fp, "\t\t cmp eax,ebx\n"); - fprintf(fp, "\t\t jg near procint\n\n"); - - /* No int waiting - clear count, set stop */ - - ClearRegister(ECX); - fprintf(fp, "\t\t mov [%s],ecx\n",ICOUNT); - fprintf(fp, "\t\t or byte [%s],80h\n",REG_IRQ); - Completed(); - - /* User Mode - Exception */ - - Align(); - fprintf(fp, "%s:\n",TrueLabel); - Exception(8,BaseCode); - - OpcodeArray[BaseCode] = BaseCode ; - } -} - -void ReturnFromException(void) -{ - char TrueLabel[16]; - - int BaseCode = 0x4e73; - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - SavePreviousPC(); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 20; - - /* Check in Supervisor Mode */ - - sprintf(TrueLabel,GenerateLabel(0,1)); - fprintf(fp, "\t\t test byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH); - fprintf(fp, "\t\t je near %s\n\n",TrueLabel); - - /* Get SR - Save in EBX */ - - fprintf(fp, "\t\t mov edi,[%s]\n",REG_A7); - fprintf(fp, "\t\t add dword [%s],byte 6\n",REG_A7); - Memory_Read('W',EDI,"-----DB",2); - fprintf(fp, "\t\t add edi,byte 2\n"); - fprintf(fp, "\t\t mov esi,eax\n"); - - /* Get PC */ - - Memory_Read('L',EDI,"----S-B",0); - fprintf(fp, "\t\t xchg esi,eax\n"); - - /* Update CCR (and A7) */ - - WriteCCR('W'); - - MemoryBanking(BaseCode); - Completed(); - - fprintf(fp, "%s:\n",TrueLabel); - Exception(8,0x10000+BaseCode); - - OpcodeArray[BaseCode] = BaseCode; -} - -void trapv(void) -{ - int BaseCode = 0x4E76; - char * Label; - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - Label = GenerateLabel(BaseCode,0); - fprintf(fp, "%s\n", Label ); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 4; - - fprintf(fp, "\t\t test dh,08h\n"); - fprintf(fp, "\t\t jz near OP%d_%4.4x_Clear\n",CPU,BaseCode); - Exception(7,BaseCode); - - fprintf(fp, "OP%d_%4.4x_Clear:\n",CPU,BaseCode); - Completed(); - } - OpcodeArray[BaseCode] = BaseCode ; -} - -void illegal_opcode(void) -{ - Align(); - fprintf(fp, "ILLEGAL:\n"); - fprintf(fp, "\t\t mov [_illegal_op],ecx\n"); - fprintf(fp, "\t\t mov [_illegal_pc],esi\n"); - -#ifdef MAME_DEBUG - fprintf(fp, "\t\t jmp ecx\n"); - fprintf(fp, "\t\t pushad\n"); - fprintf(fp, "\t\t call _m68k_illegal_opcode\n"); - fprintf(fp, "\t\t popad\n"); -#endif - - Exception(4,0xFFFE); -} - -/* - * Return from subroutine - * restoring flags as well - * - */ - -void ReturnandRestore(void) -{ - int BaseCode = 0x4e77; - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - SavePreviousPC(); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 20; - - /* Get SR into ESI */ - - fprintf(fp, "\t\t mov edi,[%s]\n",REG_A7); - fprintf(fp, "\t\t add dword [%s],byte 6\n",REG_A7); - - Memory_Read('W',EDI,"-----DB",2); - fprintf(fp, "\t\t add edi,byte 2\n"); - fprintf(fp, "\t\t mov esi,eax\n"); - - /* Get PC */ - - Memory_Read('L',EDI,"----SDB",0); - fprintf(fp, "\t\t xchg esi,eax\n"); - - /* Update flags */ - - WriteCCR('B'); - - MemoryBanking(BaseCode); - Completed(); - - OpcodeArray[BaseCode] = BaseCode; -} - -/* - * Return from Subroutine - * - */ - -void rts(void) -{ - int BaseCode = 0x4e75 ; - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - SavePreviousPC(); - - TimingCycles += 16; - - OpcodeArray[BaseCode] = BaseCode ; - - fprintf(fp, "\t\t mov eax,[%s]\n",REG_A7); - fprintf(fp, "\t\t add dword [%s],byte 4\n",REG_A7); - Memory_Read('L',EAX,"---D--B",1); - fprintf(fp, "\t\t mov esi,eax\n"); - MemoryBanking(BaseCode); - Completed(); - } -} - -void jmp_jsr(void) -{ - int Opcode, BaseCode ; - int dreg,mode,type ; - int Dest ; - char allow[] = "--2--56789a-----" ; - - for (type = 0 ; type < 2 ; type++) - for (mode = 0 ; mode < 8 ; mode++) - for (dreg = 0 ; dreg < 8 ; dreg++) - { - Opcode = 0x4e80 | (type<<6) | (mode<<3) | dreg ; - BaseCode = Opcode & 0x4ef8 ; - if (mode == 7) - BaseCode = BaseCode | dreg ; - - Dest = EAtoAMN(BaseCode, FALSE); - if (allow[Dest&0x0f] != '-') - { - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - SavePreviousPC(); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - switch (mode) - { - case 2: - TimingCycles += 8; - break; - case 5: - case 7: - case 9: - TimingCycles += 10; - break; - case 8: - TimingCycles += 12; - break; - case 6: - case 10: - TimingCycles += 14; - break; - } - - if (type == 0) /* jsr takes 8 more than jmp */ - TimingCycles += 8; - - if (mode < 7) - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - } - EffectiveAddressCalculate(Dest,'L',ECX,TRUE); - - /* jsr needs to push PC onto stack */ - - if (type == 0) - { - PushPC(EBX,EAX,"---D-DB",1); - } - - fprintf(fp, "\t\t mov esi,edi\n"); - MemoryBanking(BaseCode); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -void cmpm(void) -{ - int Opcode, BaseCode ; - int regx,leng,regy ; - int ModeModX, ModeModY; - char Size=' ' ; - char * Regname="" ; - char * RegnameEBX="" ; - - for (regx = 0 ; regx < 8 ; regx++) - for (leng = 0 ; leng < 3 ; leng++) - for (regy = 0 ; regy < 8 ; regy++) - { - Opcode = 0xb108 | (regx<<9) | (leng<<6) | regy ; - BaseCode = Opcode & 0xb1c8 ; - - ModeModX = 0; - ModeModY = 0; - -#ifdef A7ROUTINE - if (leng==0) - { - if (regx==7) - { - BaseCode |= (regx<<9); - ModeModX = 16; - } - - if (regy==7) - { - BaseCode |= regy; - ModeModY = 16; - } - } -#endif - - switch (leng) - { - case 0: - Size = 'B'; - Regname = regnamesshort[EAX]; - RegnameEBX = regnamesshort[EBX]; - break; - case 1: - Size = 'W'; - Regname = regnamesword[EAX]; - RegnameEBX = regnamesword[EBX]; - break; - case 2: - Size = 'L'; - Regname = regnameslong[EAX]; - RegnameEBX = regnameslong[EBX]; - break; - } - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - SavePreviousPC(); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - AddEACycles = 0 ; - - if (Size != 'L') - TimingCycles += 12 ; - else - TimingCycles += 20 ; - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx, byte 7\n"); - fprintf(fp, "\t\t shr ecx, byte 9\n"); - fprintf(fp, "\t\t and ecx, byte 7\n"); - - EffectiveAddressRead(3+ModeModY,Size,EBX,EBX,"--C-S-B",FALSE); - EffectiveAddressRead(3+ModeModX,Size,ECX,EAX,"-B--S-B",FALSE); - - fprintf(fp, "\t\t cmp %s,%s\n",Regname,RegnameEBX); - SetFlags(Size,EAX,FALSE,FALSE,FALSE); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -void exg(void) -{ - int Opcode, BaseCode ; - int regx,type,regy ; - int opmask[3] = { 0x08, 0x09, 0x11} ; - - for (regx = 0 ; regx < 8 ; regx++) - for (type = 0 ; type < 3 ; type++) - for (regy = 0 ; regy < 8 ; regy++) - { - Opcode = 0xc100 | (regx<<9) | (opmask[type]<<3) | regy ; - BaseCode = Opcode & 0xc1c8 ; - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 6 ; - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - fprintf(fp, "\t\t shr ecx,byte 9\n"); - fprintf(fp, "\t\t and ecx,byte 7\n"); - - if (type == 0) - { - fprintf(fp, "\t\t mov eax,[%s+ECX*4]\n",REG_DAT); - fprintf(fp, "\t\t mov edi,[%s+EBX*4]\n",REG_DAT); - fprintf(fp, "\t\t mov [%s+ECX*4],edi\n",REG_DAT); - fprintf(fp, "\t\t mov [%s+EBX*4],eax\n",REG_DAT); - } - if (type == 1) - { - fprintf(fp, "\t\t mov eax,[%s+ECX*4]\n",REG_ADD); - fprintf(fp, "\t\t mov edi,[%s+EBX*4]\n",REG_ADD); - fprintf(fp, "\t\t mov [%s+ECX*4],edi\n",REG_ADD); - fprintf(fp, "\t\t mov [%s+EBX*4],eax\n",REG_ADD); - } - if (type == 2) - { - fprintf(fp, "\t\t mov eax,[%s+ECX*4]\n",REG_DAT); - fprintf(fp, "\t\t mov edi,[%s+EBX*4]\n",REG_ADD); - fprintf(fp, "\t\t mov [%s+ECX*4],edi\n",REG_DAT); - fprintf(fp, "\t\t mov [%s+EBX*4],eax\n",REG_ADD); - } - - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -void ext(void) -{ - int Opcode, BaseCode ; - int type,regy ; - - for (type = 2 ; type < 8 ; type++) - for (regy = 0 ; regy < 8 ; regy++) - { - if (type > 3 && type < 7) - continue ; - Opcode = 0x4800 | (type<<6) | regy ; - BaseCode = Opcode & 0x48c0 ; - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 4 ; - - fprintf(fp, "\t\t and ecx, byte 7\n"); - - if (type == 2) /* byte to word */ - { - fprintf(fp, "\t\t movsx eax,byte [%s+ECX*4]\n",REG_DAT); - fprintf(fp, "\t\t mov [%s+ECX*4],ax\n",REG_DAT); - SetFlags('W',EAX,TRUE,FALSE,FALSE); - } - if (type == 3) /* word to long */ - { - fprintf(fp, "\t\t movsx eax,word [%s+ECX*4]\n",REG_DAT); - fprintf(fp, "\t\t mov [%s+ECX*4],eax\n",REG_DAT); - SetFlags('L',EAX,TRUE,FALSE,FALSE); - } - if (type == 7) /* byte to long */ - { - fprintf(fp, "\t\t movsx eax,byte [%s+ECX*4]\n",REG_DAT); - fprintf(fp, "\t\t mov [%s+ECX*4],eax\n",REG_DAT); - SetFlags('L',EAX,TRUE,FALSE,FALSE); - } - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -void swap(void) -{ - int Opcode, BaseCode ; - int sreg ; - - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0x4840 | sreg ; - BaseCode = Opcode & 0x4840; - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 4 ; - - fprintf(fp, "\t\t and ecx, byte 7\n"); - fprintf(fp, "\t\t mov eax, dword [%s+ECX*4]\n",REG_DAT); - fprintf(fp, "\t\t ror eax, 16\n"); - fprintf(fp, "\t\t test eax,eax\n"); - fprintf(fp, "\t\t mov dword [%s+ECX*4],eax\n",REG_DAT); - SetFlags('L',EAX,FALSE,FALSE,FALSE); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -/* - * Line A and Line F commands - * - */ - -void LineA(void) -{ - int Count; - - /* Line A */ - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(0xA000,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - Exception(0x0A,0xA000); - - for (Count=0xA000;Count<0xB000;Count++) - { - OpcodeArray[Count] = 0xA000; - } -} - -void LineF(void) -{ - int Count; - - /* Line F */ - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(0xF000,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - Exception(0x0B,0xF000); - - for (Count=0xF000;Count<0x10000;Count++) - { - OpcodeArray[Count] = 0xF000; - } -} - -/* - * Moves To/From CCR and SR - * - * (Move from CCR is 68010 command) - * - */ - -void movesr(void) -{ - int Opcode, BaseCode ; - int type, mode, sreg ; - int Dest ; - char allow[] = "0-2345678-------" ; - char Size; - - for (type = 0 ; type < 4 ; type++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0x40c0 | (type << 9) | ( mode << 3 ) | sreg ; - - /* To has extra modes */ - - if (type > 1) - { - allow[0x9] = '9'; - allow[0xa] = 'a'; - allow[0xb] = 'b' ; - } - - if ((type == 0) | (type == 3)) - Size = 'W'; /* SR */ - else - Size = 'B'; /* CCR */ - - BaseCode = Opcode & 0x46f8 ; - - if (mode == 7) - BaseCode |= sreg ; - - Dest = EAtoAMN(BaseCode, FALSE); - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[BaseCode] == -2) - { - char TrueLabel[16]; - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (type > 1) /* move to */ - TimingCycles += 12 ; - else - { - if (mode < 2) - TimingCycles += 6 ; - else - TimingCycles += 8 ; - } - - /* If Move to SR then must be in Supervisor Mode */ - - if (type == 3) - { - sprintf(TrueLabel,GenerateLabel(0,1)); - - fprintf(fp, "\t\t test byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH); - fprintf(fp, "\t\t je near %s\n\n",TrueLabel); - } - - /* 68010 Command ? */ - if (type==1) CheckCPUtype(1); - - - if (mode < 7) - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - } - - /* Always read/write word 2 bytes */ - if (type < 2) - { - ReadCCR(Size,EBX); - EffectiveAddressWrite(Dest & 15,'W',ECX,TRUE,"---DS-B",TRUE); - } - else - { - EffectiveAddressRead(Dest & 15,'W',ECX,EAX,"----S-B",FALSE); - WriteCCR(Size); - } - Completed(); - - /* Exception if not Supervisor Mode */ - - if (type == 3) - { - /* Was in User Mode - Exception */ - - fprintf(fp, "%s:\n",TrueLabel); - Exception(8,BaseCode); - } - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * Decimal mode Add / Subtracts - * - */ - -void abcd_sbcd(void) -{ - int Opcode, BaseCode ; - int regx,type,rm,regy,mode ; - int ModeModX; - int ModeModY; - char *Label; - - for (type = 0 ; type < 2 ; type ++) /* 0=sbcd, 1=abcd */ - for (regx = 0 ; regx < 8 ; regx++) - for (rm = 0 ; rm < 2 ; rm++) - for (regy = 0 ; regy < 8 ; regy++) - { - Opcode = 0x8100 | (type<<14) | (regx<<9) | (rm<<3) | regy ; - BaseCode = Opcode & 0xc108 ; - - ModeModX = 0; - ModeModY = 0; - - if (rm == 0) - mode = 0 ; - else - { - mode = 4 ; - -#ifdef A7ROUTINE - - if (regx == 7) - { - BaseCode |= (regx << 9); - ModeModY = 16; - } - if (regy == 7) - { - BaseCode |= regy; - ModeModX = 16; - } - -#endif - } - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if (mode == 4) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - AddEACycles = 0 ; - - if (rm == 0) - TimingCycles += 6 ; - else - TimingCycles += 18 ; - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx, byte 7\n"); - fprintf(fp, "\t\t shr ecx, byte 9\n"); - fprintf(fp, "\t\t and ecx, byte 7\n"); - - EffectiveAddressRead(mode+ModeModX,'B',EBX,EBX,"--C-S-B",TRUE); - EffectiveAddressRead(mode+ModeModY,'B',ECX,EAX,"-BC-SDB",TRUE); - - CopyX(); - - if (type == 0) - { - fprintf(fp, "\t\t sbb al,bl\n"); - fprintf(fp, "\t\t das\n"); - } - else - { - fprintf(fp, "\t\t adc al,bl\n"); - fprintf(fp, "\t\t daa\n"); - } - - /* Should only clear Zero flag if not zero */ - - Label = GenerateLabel(0,1); - - fprintf(fp, "\t\t mov ebx,edx\n"); - fprintf(fp, "\t\t setc dl\n"); - - fprintf(fp, "\t\t jnz short %s\n\n",Label); - - /* Keep original Zero flag */ - fprintf(fp, "\t\t and bl,40h ; Mask out Old Z\n"); - fprintf(fp, "\t\t or dl,bl ; Copy across\n\n"); - - fprintf(fp, "%s:\n",Label); - - fprintf(fp, "\t\t mov bl,dl\n"); /* copy carry into sign */ - fprintf(fp, "\t\t and bl,1\n"); - fprintf(fp, "\t\t shl bl,7\n"); - fprintf(fp, "\t\t and dl,7Fh\n"); - fprintf(fp, "\t\t or dl,bl\n"); - - fprintf(fp, "\t\t mov [%s],edx\n",REG_X); - - EffectiveAddressWrite(mode,'B',ECX,EAX,"---DS-B",TRUE); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -/* - * Rotate Left / Right - * - */ - -void rol_ror(void) -{ - int Opcode, BaseCode ; - int dreg, dr, leng, ir, sreg ; - char Size=' '; - char * Label ; - char * Regname="" ; - char * RegnameECX ; - - for (dreg = 0 ; dreg < 8 ; dreg++) - for (dr = 0 ; dr < 2 ; dr++) - for (leng = 0 ; leng < 3 ; leng++) - for (ir = 0 ; ir < 2 ; ir++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0xe018 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ; - BaseCode = Opcode & 0xe1f8 ; - - switch (leng) - { - case 0: - Size = 'B'; - Regname = regnamesshort[0]; - RegnameECX = regnamesshort[ECX]; - break; - case 1: - Size = 'W'; - Regname = regnamesword[0]; - RegnameECX = regnamesword[ECX]; - break; - case 2: - Size = 'L'; - Regname = regnameslong[0]; - RegnameECX = regnameslong[ECX]; - break; - } - - if (OpcodeArray[ BaseCode ] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (Size != 'L') - TimingCycles += 6 ; - else - TimingCycles += 8 ; - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - fprintf(fp, "\t\t shr ecx,byte 9\n"); - - if (ir == 0) - { - Immediate8(); - } - else - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - EffectiveAddressRead(0,'L',ECX,ECX,"-B--S-B",FALSE); - fprintf(fp, "\t\t and ecx,byte 63\n"); - } - - EffectiveAddressRead(0,Size,EBX,EAX,"-BC-S-B",FALSE); - - /* shift 0 - no time, no shift and clear carry */ - - Label = GenerateLabel(0,1); - fprintf(fp, "\t\t jecxz %s\n",Label); - - /* allow 2 cycles per shift */ - - fprintf(fp, "\t\t mov edx,ecx\n"); - fprintf(fp, "\t\t add edx,edx\n"); - fprintf(fp, "\t\t sub dword [%s],edx\n",ICOUNT); - - if (dr == 0) - fprintf(fp, "\t\t ror %s,cl\n",Regname); - else - fprintf(fp, "\t\t rol %s,cl\n",Regname); - - fprintf(fp, "\t\t setc ch\n"); - - fprintf(fp, "%s:\n",Label); - - SetFlags(Size,EAX,TRUE,FALSE,FALSE); -/* fprintf(fp, "\t\t and dl,254\n"); Test clears Carry */ - fprintf(fp, "\t\t or dl,ch\n"); - - EffectiveAddressWrite(0,Size,EBX,EAX,"--C-S-B",TRUE); - - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -void rol_ror_ea(void) -{ - int Opcode, BaseCode ; - int dr, mode, sreg ; - int Dest ; - char allow[] = "--2345678-------" ; - - for (dr = 0 ; dr < 2 ; dr++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0xe6c0 | (dr<<8) | (mode<<3) | sreg ; - BaseCode = Opcode & 0xfff8 ; - - if (mode == 7) - BaseCode |= sreg ; - - Dest = EAtoAMN(BaseCode, FALSE); - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[ BaseCode ] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 8 ; - - fprintf(fp, "\t\t and ecx,byte 7\n"); - EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE); - - if (dr == 0) - fprintf(fp, "\t\t ror ax,1\n"); - else - fprintf(fp, "\t\t rol ax,1\n"); - - fprintf(fp, "\t\t setc bl\n"); - SetFlags('W',EAX,TRUE,FALSE,FALSE); -/* fprintf(fp, "\t\t and dl,254\n"); Test clears Carry */ - fprintf(fp, "\t\t or dl,bl\n"); - - EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"---DS-B",TRUE); - - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * Logical Shift Left / Right - * - */ - -void lsl_lsr(void) -{ - int Opcode, BaseCode ; - int dreg, dr, leng, ir, sreg ; - char Size=' '; - char * Regname="" ; - char * RegnameECX="" ; - char * RegnameEDX="" ; - char * Label ; - - for (dreg = 0 ; dreg < 8 ; dreg++) - for (dr = 0 ; dr < 2 ; dr++) - for (leng = 0 ; leng < 3 ; leng++) - for (ir = 0 ; ir < 2 ; ir++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0xe008 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ; - BaseCode = Opcode & 0xe1f8 ; - - switch (leng) - { - case 0: - Size = 'B'; - Regname = regnamesshort[0]; - RegnameECX = regnamesshort[ECX]; - RegnameEDX = regnamesshort[EDX]; - break; - case 1: - Size = 'W'; - Regname = regnamesword[0]; - RegnameECX = regnamesword[ECX]; - RegnameEDX = regnamesword[EDX]; - break; - case 2: - Size = 'L'; - Regname = regnameslong[0]; - RegnameECX = regnameslong[ECX]; - RegnameEDX = regnameslong[EDX]; - break; - } - - if (OpcodeArray[ BaseCode ] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (Size != 'L') - TimingCycles += 6 ; - else - TimingCycles += 8 ; - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - fprintf(fp, "\t\t shr ecx,byte 9\n"); - - if (ir == 0) - { - Immediate8(); - } - else - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - EffectiveAddressRead(0,'L',ECX,ECX,"-B--S-B",FALSE); - fprintf(fp, "\t\t and ecx,byte 63\n"); - } - - /* and 2 cycles per shift */ - - fprintf(fp, "\t\t mov edx,ecx\n"); - fprintf(fp, "\t\t add edx,edx\n"); - fprintf(fp, "\t\t sub dword [%s],edx\n",ICOUNT); - - EffectiveAddressRead(0,Size,EBX,EAX,"-BC-S-B",FALSE); - - /* ASG: on the 68k, the shift count is mod 64; on the x86, the */ - /* shift count is mod 32; we need to check for shifts of 32-63 */ - /* and produce zero */ - Label = GenerateLabel(0,1); - fprintf(fp, "\t\t test cl,0x20\n"); - fprintf(fp, "\t\t jnz %s_BigShift\n",Label); - - fprintf(fp, "%s_Continue:\n",Label); - if (dr == 0) - fprintf(fp, "\t\t shr %s,cl\n",Regname); - else - fprintf(fp, "\t\t shl %s,cl\n",Regname); - - SetFlags(Size,EAX,FALSE,FALSE,FALSE); - - /* Clear Overflow flag */ - fprintf(fp, "\t\t xor dh,dh\n"); - - EffectiveAddressWrite(0,Size,EBX,EAX,"--CDS-B",TRUE); - - /* if shift count is zero clear carry */ - - fprintf(fp, "\t\t jecxz %s\n",Label); - - fprintf(fp, "\t\t mov [%s],edx\n",REG_X); - Completed(); - - Align(); - fprintf(fp, "%s:\n",Label); - fprintf(fp, "\t\t and dl,254\t\t;clear C flag\n"); - Completed(); - - fprintf(fp, "%s_BigShift:\n",Label); - if (dr == 0) - { - fprintf(fp, "\t\t shr %s,16\n",Regname); - fprintf(fp, "\t\t shr %s,16\n",Regname); - } - else - { - fprintf(fp, "\t\t shl %s,16\n",Regname); - fprintf(fp, "\t\t shl %s,16\n",Regname); - } - fprintf(fp, "\t\t jmp %s_Continue\n",Label); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -void lsl_lsr_ea(void) -{ - int Opcode, BaseCode ; - int dr, mode, sreg ; - int Dest ; - char allow[] = "--2345678-------" ; - - for (dr = 0 ; dr < 2 ; dr++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0xe2c0 | (dr<<8) | (mode<<3) | sreg ; - BaseCode = Opcode & 0xfff8 ; - - if (mode == 7) - BaseCode |= sreg ; - - Dest = EAtoAMN(BaseCode, FALSE); - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[ BaseCode ] == -2) - { - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 8 ; - - fprintf(fp, "\t\t and ecx,byte 7\n"); - EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE); - - if (dr == 0) - fprintf(fp, "\t\t shr ax,1\n"); - else - fprintf(fp, "\t\t shl ax,1\n"); - - SetFlags('W',EAX,FALSE,TRUE,FALSE); - - /* Clear Overflow flag */ - - fprintf(fp, "\t\t xor dh,dh\n"); - - EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"---DS-B",TRUE); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * Rotate Left / Right though Extend - * - */ - -void roxl_roxr(void) -{ - int Opcode, BaseCode ; - int dreg, dr, leng, ir, sreg ; - char Size=' ' ; - char * Regname="" ; - char * RegnameECX="" ; - char * Label ; - - for (dreg = 0 ; dreg < 8 ; dreg++) - for (dr = 0 ; dr < 2 ; dr++) - for (leng = 0 ; leng < 3 ; leng++) - for (ir = 0 ; ir < 2 ; ir++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0xe010 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ; - BaseCode = Opcode & 0xe1f8 ; - - switch (leng) - { - case 0: - Size = 'B'; - Regname = regnamesshort[0]; - RegnameECX = regnamesshort[ECX]; - break; - case 1: - Size = 'W'; - Regname = regnamesword[0]; - RegnameECX = regnamesword[ECX]; - break; - case 2: - Size = 'L'; - Regname = regnameslong[0]; - RegnameECX = regnameslong[ECX]; - break; - } - - if (OpcodeArray[ BaseCode ] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - if (Size != 'L') - TimingCycles += 6 ; - else - TimingCycles += 8 ; - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - fprintf(fp, "\t\t shr ecx,byte 9\n"); - - if (ir == 0) - { - Immediate8(); - } - else - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - EffectiveAddressRead(0,'L',ECX,ECX,"-B--S-B",FALSE); - fprintf(fp, "\t\t and ecx,byte 63\n"); - } - - /* allow 2 cycles per shift */ - - fprintf(fp, "\t\t mov edx,ecx\n"); - fprintf(fp, "\t\t add edx,edx\n"); - fprintf(fp, "\t\t sub dword [%s],edx\n",ICOUNT); - - EffectiveAddressRead(0,Size,EBX,EAX,"-BC-SDB",FALSE); - - /* move X into C so RCR & RCL can be used */ - /* RCR & RCL only set the carry flag */ - - CopyX(); - - if (dr == 0) - fprintf(fp, "\t\t rcr %s,cl\n",Regname); - else - fprintf(fp, "\t\t rcl %s,cl\n",Regname); - - fprintf(fp, "\t\t setc ch\n"); - SetFlags(Size,EAX,TRUE,FALSE,FALSE); -/* fprintf(fp, "\t\t and dl,254\n"); Test Clears Carry */ - - EffectiveAddressWrite(0,Size,EBX,EAX,"--CDS-B",TRUE); - - /* if shift count is zero clear carry */ - - Label = GenerateLabel(0,1); - fprintf(fp, "\t\t test cl,cl\n"); - fprintf(fp, "\t\t jz %s\n",Label); - - /* Add in Carry Flag */ - - fprintf(fp, "\t\t or dl,ch\n"); - fprintf(fp, "\t\t mov [%s],dl\n",REG_X); - Completed(); - - - /* copy X onto C when shift is zero */ - - Align(); - fprintf(fp, "%s:\n",Label); - fprintf(fp, "\t\t mov ecx,[%s]\n",REG_X); - fprintf(fp, "\t\t and ecx,byte 1\n"); - fprintf(fp, "\t\t or edx,ecx\n"); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -void roxl_roxr_ea(void) -{ - int Opcode, BaseCode ; - int dr, mode, sreg ; - int Dest ; - char allow[] = "--2345678-------" ; - - for (dr = 0 ; dr < 2 ; dr++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0xe4c0 | (dr<<8) | (mode<<3) | sreg ; - BaseCode = Opcode & 0xfff8 ; - - if (mode == 7) - BaseCode |= sreg ; - - Dest = EAtoAMN(BaseCode, FALSE); - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[ BaseCode ] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 8 ; - - fprintf(fp, "\t\t and ecx,byte 7\n"); - EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE); - - /* move X into C so RCR & RCL can be used */ - /* RCR & RCL only set the carry flag */ - - CopyX(); - - if (dr == 0) - fprintf(fp, "\t\t rcr ax,1\n"); - else - fprintf(fp, "\t\t rcl ax,1\n"); - - fprintf(fp, "\t\t setc bl\n"); - SetFlags('W',EAX,TRUE,FALSE,FALSE); -/* fprintf(fp, "\t\t and dl,254\n"); - Intel Clears on Test */ - fprintf(fp, "\t\t or dl,bl\n"); - - EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"---DS-B",TRUE); - - fprintf(fp, "\t\t mov [%s],edx\n",REG_X); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * Arithmetic Shift Left / Right - * - */ - -void asl_asr(void) -{ - int Opcode, BaseCode ; - int dreg, dr, leng, ir, sreg ; - char Size=' '; - char * Sizename="" ; - char * Regname="" ; - char * RegnameEDX="" ; - char * RegnameECX="" ; - char * Label; - - /* Normal routines for codes */ - - for (dreg = 0 ; dreg < 8 ; dreg++) - for (dr = 0 ; dr < 2 ; dr++) - for (leng = 0 ; leng < 3 ; leng++) - for (ir = 0 ; ir < 2 ; ir++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0xe000 | (dreg<<9) | (dr<<8) | (leng<<6) | (ir<<5) | sreg ; - BaseCode = Opcode & 0xe1f8 ; - - switch (leng) - { - case 0: - Size = 'B'; - Regname = regnamesshort[0]; - RegnameECX = regnamesshort[ECX]; - RegnameEDX = regnamesshort[EDX]; - break; - case 1: - Size = 'W'; - Regname = regnamesword[0]; - RegnameECX = regnamesword[ECX]; - RegnameEDX = regnamesword[EDX]; - break; - case 2: - Size = 'L'; - Regname = regnameslong[0]; - RegnameECX = regnameslong[ECX]; - RegnameEDX = regnameslong[EDX]; - break; - } - - if (OpcodeArray[ BaseCode ] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - Label = GenerateLabel(0,1); - - if (Size != 'L') - TimingCycles += 6 ; - else - TimingCycles += 8 ; - - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - fprintf(fp, "\t\t shr ecx,byte 9\n"); - - EffectiveAddressRead(0,Size,EBX,EAX,"-BC-S-B",FALSE); - - if (ir == 0) - { - Immediate8(); - } - else - { - fprintf(fp, "\t\t and ecx,byte 7\n"); - EffectiveAddressRead(0,'L',ECX,ECX,"-B--S-B",FALSE); - fprintf(fp, "\t\t and ecx,byte 63\n"); - fprintf(fp, "\t\t jz short %s\n",Label); - } - - /* allow 2 cycles per shift */ - - fprintf(fp, "\t\t mov edx,ecx\n"); - fprintf(fp, "\t\t add edx,edx\n"); - fprintf(fp, "\t\t sub dword [%s],edx\n",ICOUNT); - - if (dr == 0) - { - /* ASR */ - - /* ASG: on the 68k, the shift count is mod 64; on the x86, the */ - /* shift count is mod 32; we need to check for shifts of 32-63 */ - /* and effectively shift 31 */ - fprintf(fp, "\t\t shrd edx,ecx,6\n"); - fprintf(fp, "\t\t sar edx,31\n"); - fprintf(fp, "\t\t and edx,31\n"); - fprintf(fp, "\t\t or ecx,edx\n"); - - fprintf(fp, "\t\t sar %s,cl\n",Regname); - - /* Mode 0 write does not affect Flags */ - EffectiveAddressWrite(0,Size,EBX,EAX,"---DS-B",TRUE); - - /* Update Flags */ - fprintf(fp, "\t\t lahf\n"); - -#ifdef STALLCHECK - ClearRegister(EDX); - fprintf(fp, "\t\t mov dl,ah\n"); -#else - fprintf(fp, "\t\t movzx edx,ah\n"); -#endif - - fprintf(fp, "\t\t mov [%s],edx\n",REG_X); - } - else - { - /* ASL */ - - /* Check to see if Overflow should be set */ - - fprintf(fp,"\t\t mov edi,eax\t\t; Save It\n"); - - ClearRegister(EDX); - fprintf(fp,"\t\t stc\n"); - fprintf(fp,"\t\t rcr %s,1\t\t; d=1xxxx\n",RegnameEDX); - fprintf(fp,"\t\t sar %s,cl\t\t; d=1CCxx\n",RegnameEDX); - fprintf(fp,"\t\t and eax,edx\n"); - fprintf(fp,"\t\t jz short %s_V\t\t; No Overflow\n",Label); - fprintf(fp,"\t\t cmp eax,edx\n"); - fprintf(fp,"\t\t je short %s_V\t\t; No Overflow\n",Label); - - /* Set Overflow */ - fprintf(fp,"\t\t mov edx,0x800\n"); - fprintf(fp,"\t\t jmp short %s_OV\n",Label); - - fprintf(fp,"%s_V:\n",Label); - ClearRegister(EDX); - - fprintf(fp,"%s_OV:\n",Label); - - /* more than 31 shifts and long */ - - if ((ir==1) && (leng==2)) - { - fprintf(fp,"\t\t test cl,0x20\n"); - fprintf(fp,"\t\t jnz short %s_32\n\n",Label); - } - - fprintf(fp,"\t\t mov eax,edi\t\t; Restore It\n"); - - fprintf(fp, "\t\t sal %s,cl\n",Regname); - - EffectiveAddressWrite(0,Size,EBX,EAX,"---DS-B",TRUE); - fprintf(fp, "\t\t lahf\n"); - fprintf(fp, "\t\t mov dl,ah\n"); - fprintf(fp, "\t\t mov [%s],edx\n",REG_X); - } - Completed(); - - if (ir != 0) - { - Align(); - fprintf(fp, "%s:\n",Label); - - - if (dr == 0) - { - /* ASR - Test clears V and C */ - SetFlags(Size,EAX,TRUE,FALSE,FALSE); - } - else - { - /* ASL - Keep existing Carry flag, Clear V */ - fprintf(fp, "\t\t mov ebx,edx\n"); - fprintf(fp, "\t\t and ebx,byte 1\n"); - SetFlags(Size,EAX,TRUE,FALSE,FALSE); - fprintf(fp, "\t\t or edx,ebx\n"); - - if (leng==2) - { - Completed(); - - /* > 31 Shifts */ - - fprintf(fp, "%s_32:\n",Label); - fprintf(fp, "\t\t mov dl,40h\n"); // Zero flag - ClearRegister(EAX); - EffectiveAddressWrite(0,Size,EBX,EAX,"----S-B",TRUE); - } - } - - Completed(); - } - } - - OpcodeArray[Opcode] = BaseCode ; - } - - /* End with special routines for ASL.x #1,Dx */ - /* To do correct V setting, ASL needs quite a */ - /* bit of additional code. A Shift of one has */ - /* correct flags on Intel, and is very common */ - /* in 68000 programs. */ - - for (leng = 0 ; leng < 3 ; leng++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0xe300 | (leng<<6) | sreg ; - BaseCode = Opcode & 0xe3c8 ; - - switch (leng) - { - case 0: - Sizename = "byte"; - break; - case 1: - Sizename = "word"; - break; - case 2: - Sizename = "long"; - break; - } - - if (sreg == 0) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - Label = GenerateLabel(0,1); - - if (Size != 'L') - TimingCycles += 6 ; - else - TimingCycles += 8 ; - - fprintf(fp, "\t\t and ecx,byte 7\n"); - fprintf(fp, "\t\t sal %s [%s+ecx*4],1\n",Sizename,REG_DAT); - SetFlags('L',EAX,FALSE,TRUE,FALSE); - Completed(); - - } - - OpcodeArray[Opcode] = BaseCode ; - } -} - -void asl_asr_ea(void) -{ - int Opcode, BaseCode ; - int dr, mode, sreg ; - int Dest ; - char allow[] = "--2345678-------" ; - - for (dr = 0 ; dr < 2 ; dr++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0xe0c0 | (dr<<8) | (mode<<3) | sreg ; - BaseCode = Opcode & 0xfff8 ; - - if (mode == 7) - BaseCode |= sreg ; - - Dest = EAtoAMN(BaseCode, FALSE); - - if (allow[Dest&0xf] != '-') - { - if (OpcodeArray[ BaseCode ] == -2) - { - - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - TimingCycles += 8 ; - - fprintf(fp, "\t\t and ecx,byte 7\n"); - EffectiveAddressRead(Dest&0xf,'W',ECX,EAX,"--C-SDB",FALSE); - - if (dr == 0) - fprintf(fp, "\t\t sar ax,1\n"); - else - fprintf(fp, "\t\t sal ax,1\n"); - - SetFlags('W',EAX,FALSE,TRUE,TRUE); - - EffectiveAddressWrite(Dest&0xf,'W',ECX,EAX,"----S-B",FALSE); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - -/* - * Divide Commands - */ - -void divides(void) -{ - int dreg, type, mode, sreg ; - int Opcode, BaseCode ; - int Dest ; - char allow[] = "0-23456789ab-----" ; - char TrapLabel[16]; - int Cycles; - - int divide_cycles[12] = - { - 38,0,42,42,44,46,50,46,50,46,48,42 - }; - - for (dreg = 0 ; dreg < 8 ; dreg++) - for (type = 0 ; type < 2 ; type++) - for (mode = 0 ; mode < 8 ; mode++) - for (sreg = 0 ; sreg < 8 ; sreg++) - { - Opcode = 0x80c0 | (dreg<<9) | (type<<8) | (mode<<3) | sreg ; - BaseCode = Opcode & 0x81f8 ; - if (mode == 7) - { - BaseCode |= sreg ; - } - - Dest = EAtoAMN(Opcode, FALSE); - if (allow[Dest&0x0f] != '-') - { - if (OpcodeArray[ BaseCode ] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - if ((Dest >= 2) && (Dest <=10)) - SavePreviousPC(); - - fprintf(fp, "\t\t add esi,byte 2\n\n"); - - - /* Save EDX (in case of overflow) */ - - fprintf(fp, "\t\t and edx,byte -2\n"); - fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR); - - - /* Cycle Timing (if succeeds OK) */ - - Cycles = divide_cycles[Dest & 0x0f] + 95 + (type * 17); - - if (Cycles > 127) - fprintf(fp, "\t\t sub dword [%s],%d\n",ICOUNT,Cycles); - else - fprintf(fp, "\t\t sub dword [%s],byte %d\n",ICOUNT,Cycles); - - if (mode < 7) - { - fprintf(fp, "\t\t mov ebx,ecx\n"); - fprintf(fp, "\t\t and ebx,byte 7\n"); - } - - fprintf(fp, "\t\t shr ecx, byte 9\n"); - fprintf(fp, "\t\t and ecx, byte 7\n"); - - sprintf(TrapLabel, "%s", GenerateLabel(0,1) ) ; - - EffectiveAddressRead(Dest,'W',EBX,EAX,"A-C-SDB",FALSE); /* source */ - - fprintf(fp, "\t\t test ax,ax\n"); - fprintf(fp, "\t\t je near %s_ZERO\t\t;do div by zero trap\n", TrapLabel); - - if (type == 1) /* signed */ - { - fprintf(fp, "\t\t movsx ebx,ax\n"); - } - else - { - fprintf(fp, "\t\t movzx ebx,ax\n"); - } - - EffectiveAddressRead(0,'L',ECX,EAX,"ABC-SDB",FALSE); /* dest */ - - if (type == 1) /* signed */ - { - fprintf(fp, "\t\t cdq\n"); /* EDX:EAX = 64 bit signed */ - fprintf(fp, "\t\t idiv ebx\n"); /* EBX = 32 bit */ - - /* Check for Overflow */ - - fprintf(fp, "\t\t movsx ebx,ax\n"); - fprintf(fp, "\t\t cmp eax,ebx\n"); - fprintf(fp, "\t\t jne short %s_OVER\n",TrapLabel); - } - else - { - ClearRegister(EDX); - fprintf(fp, "\t\t div ebx\n"); - - /* Check for Overflow */ - - fprintf(fp, "\t\t test eax, 0FFFF0000H\n"); - fprintf(fp, "\t\t jnz short %s_OVER\n",TrapLabel); - } - - /* Sort out Result */ - - fprintf(fp, "\t\t shl edx, byte 16\n"); - fprintf(fp, "\t\t mov dx,ax\n"); - fprintf(fp, "\t\t mov [%s+ECX*4],edx\n",REG_DAT); - SetFlags('W',EDX,TRUE,FALSE,FALSE); - - Completed(); - - - /* Overflow */ - - Align(); - fprintf(fp, "%s_OVER:\n",TrapLabel); - fprintf(fp, "\t\t mov edx,[%s]\n",REG_CCR); - fprintf(fp, "\t\t or edx,0x0800\t\t;V flag\n"); - Completed(); - - - /* Division by Zero */ - - Align(); - fprintf(fp, "%s_ZERO:\t\t ;Do divide by zero trap\n", TrapLabel); - - /* Correct cycle counter for error */ - - fprintf(fp, "\t\t add dword [%s],byte %d\n",ICOUNT,95 + (type * 17)); - fprintf(fp, "\t\t mov al,5\n"); - Exception(-1,BaseCode); - Completed(); - } - - OpcodeArray[Opcode] = BaseCode ; - } - } -} - - -/* - * 68010 Extra Opcodes - * - * move from CCR is done above - * - */ - -void ReturnandDeallocate(void) -{ - int BaseCode = 0x4e74 ; - - if (OpcodeArray[BaseCode] == -2) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode,0)); - - CheckCPUtype(1); - - SavePreviousPC(); - - TimingCycles += 16; - - OpcodeArray[BaseCode] = BaseCode ; - - /* Get Return Address */ - - fprintf(fp, "\t\t mov eax,[%s]\n",REG_A7); - Memory_Read('L',EAX,"---D--B",1); - - - /* Get Displacement */ - - Memory_Fetch('W',EBX,TRUE); - - - /* Set PC = New Address */ - - fprintf(fp, "\t\t mov esi,eax\n"); - - - /* Correct Stack for Return Address and Displacement */ - - fprintf(fp, "\t\t add ebx,byte 4\n"); - fprintf(fp, "\t\t add dword [%s],ebx\n",REG_A7); - - MemoryBanking(BaseCode); - Completed(); - } -} - -void MoveControlRegister(void) -{ - int Direction; - int BaseCode = 0x4e7a ; - - for (Direction=0;Direction<2;Direction++) - { - Align(); - fprintf(fp, "%s:\n",GenerateLabel(BaseCode+Direction,0)); - - TimingCycles += 4; /* Assume same as move usp */ - - CheckCPUtype(1); - - fprintf(fp, "\t\t test byte [%s],20h \t\t\t; Supervisor Mode ?\n",REG_SRH); - fprintf(fp, "\t\t jz short OP%d_%4.4x_Trap\n",CPU,BaseCode+Direction); - - fprintf(fp, "\t\t add esi,byte 2\n"); - if (CPU==2) - fprintf(fp, "\t\t xor esi,2\n"); /* ASG */ -#ifdef STALLCHECK - ClearRegister(EBX); - fprintf(fp, "\t\t mov bx,[esi+ebp]\n"); -#else - fprintf(fp, "\t\t movzx ebx,word [esi+ebp]\n"); -#endif - if (CPU==2) - fprintf(fp, "\t\t xor esi,2\n"); /* ASG */ - - fprintf(fp, "\t\t add esi,byte 2\n"); - fprintf(fp, "\t\t mov eax,ebx\n"); - fprintf(fp, "\t\t mov ecx,ebx\n"); - - /* Sort out Register */ - - fprintf(fp, "\t\t shr ebx,12\n"); - - /* Sort out Control Register ID */ - - fprintf(fp, "\t\t and eax,byte 1\n"); - fprintf(fp, "\t\t shr ecx,10\n"); - fprintf(fp, "\t\t and ecx,2\n"); - fprintf(fp, "\t\t or ecx,eax\n"); - - if (Direction==0) - { - /* from Control */ - - fprintf(fp, "\t\t mov eax,[%s+ecx*4]\n",REG_SFC); - fprintf(fp, "\t\t mov %s,eax\n",REG_DAT_EBX); - } - else - { - /* To Control */ - - fprintf(fp, "\t\t mov eax,%s\n",REG_DAT_EBX); - - /* Mask out for SFC & DFC */ - - fprintf(fp, "\t\t test cl,2\n"); - fprintf(fp, "\t\t jne short OP%d_%4.4x_Mask\n",CPU,BaseCode+Direction); - fprintf(fp, "\t\t and eax,byte 7\n"); - fprintf(fp, "OP%d_%4.4x_Mask:\n",CPU,BaseCode+Direction); - - /* Write to control */ - - fprintf(fp, "\t\t mov [%s+ecx*4],eax\n",REG_SFC); - } - - Completed(); - - /* Not Supervisor Mode */ - - Align(); - fprintf(fp, "OP%d_%4.4x_Trap:\n",CPU,BaseCode+Direction); - Exception(8,BaseCode+Direction); - - OpcodeArray[BaseCode+Direction] = BaseCode+Direction; - } -} - -void MoveAddressSpace(void) -{ -} - -/* - * Generate Jump Table - * - */ - -void JumpTable(void) -{ - int Opcode,l,op; - - fprintf(fp, "DD OP%d_1000\n",CPU); - - l = 0 ; - for (Opcode=0x0;Opcode<0x10000;) - { - - op = OpcodeArray[Opcode]; - - fprintf(fp, "DD "); - - l = 1 ; - while (op == OpcodeArray[Opcode+l] && ((Opcode+l) & 0xfff) != 0) - { - l++ ; - } - - Opcode += l ; - - if (l > 255) - { - if (op > -1) - fprintf(fp, "OP%d_%4.4x - OP%d_1000\n",CPU,op,CPU); - else - fprintf(fp, "ILLEGAL - OP%d_1000\n",CPU); - - fprintf(fp, "DW %d\n", l); - } - else - { - if (op > -1) - fprintf(fp, "(OP%d_%4.4x - OP%d_1000) + (%d * 1000000h)\n",CPU,op,CPU,l); - else - fprintf(fp, "(ILLEGAL - OP%d_1000) + (%d * 1000000h)\n",CPU,l); - } - } -} - -void CodeSegmentBegin(void) -{ - -/* Messages */ - - fprintf(fp, "; Make68K - V%s - Copyright 1998, Mike Coates (mame@btinternet.com)\n", VERSION); - fprintf(fp, "; & Darren Olafson (deo@mail.island.net)\n\n"); - -/* Needed code to make it work! */ - - fprintf(fp, "\t\t BITS 32\n\n"); - - fprintf(fp, "\t\t GLOBAL %s_RUN\n",CPUtype); - fprintf(fp, "\t\t GLOBAL %s_RESET\n",CPUtype); - fprintf(fp, "\t\t GLOBAL %s_regs\n",CPUtype); - fprintf(fp, "\t\t GLOBAL %s_COMPTABLE\n",CPUtype); - fprintf(fp, "\t\t GLOBAL %s_OPCODETABLE\n",CPUtype); - - /* ASG - only one interface to memory now */ - fprintf(fp, "\t\t EXTERN _m68k_ICount\n"); - fprintf(fp, "\t\t EXTERN _a68k_memory_intf\n"); - fprintf(fp, "\t\t EXTERN _mem_amask\n"); - - fprintf(fp, "; Vars Mame declares / needs access to\n\n"); - - fprintf(fp, "\t\t EXTERN _mame_debug\n"); - fprintf(fp, "\t\t EXTERN _illegal_op\n"); - fprintf(fp, "\t\t EXTERN _illegal_pc\n"); - - fprintf(fp, "\t\t EXTERN _OP_ROM\n"); - fprintf(fp, "\t\t EXTERN _OP_RAM\n"); - - fprintf(fp, "\t\t EXTERN _opcode_entry\n"); - fprintf(fp, "\t\t EXTERN _cur_mrhard\n"); - -//#ifdef MAME_DEBUG - fprintf(fp, "\t\t EXTERN _m68k_illegal_opcode\n"); -//#endif - -#ifdef OS2 - fprintf(fp, "\t\t SECTION maincode USE32 FLAT CLASS=CODE\n\n"); -#else - fprintf(fp, "\t\t SECTION .text\n\n"); -#endif - - - -/* Reset routine */ - - fprintf(fp, "%s_RESET:\n",CPUtype); - - fprintf(fp, "\t\t pushad\n\n"); - - fprintf(fp, "; Build Jump Table (not optimised!)\n\n"); - - fprintf(fp, "\t\t lea edi,[%s_OPCODETABLE]\t\t; Jump Table\n", CPUtype); - fprintf(fp, "\t\t lea esi,[%s_COMPTABLE]\t\t; RLE Compressed Table\n", CPUtype); - - /* Reference Point in EBP */ - - fprintf(fp, "\t\t mov ebp,[esi]\n"); - fprintf(fp, "\t\t add esi,byte 4\n"); - - fprintf(fp, "RESET0:\n"); - fprintf(fp, "\t\t mov eax,[esi]\n"); - fprintf(fp, "\t\t mov ecx,eax\n"); - fprintf(fp, "\t\t and eax,0xffffff\n"); - fprintf(fp, "\t\t add eax,ebp\n"); - fprintf(fp, "\t\t add esi,byte 4\n"); - - /* if count is zero, then it's a word RLE length */ - - fprintf(fp, "\t\t shr ecx,24\n"); - fprintf(fp, "\t\t jne short RESET1\n"); - -#ifdef STALLCHECK - ClearRegister(ECX); - fprintf(fp, "\t\t mov cx,[esi]\t\t; Repeats\n"); -#else - fprintf(fp, "\t\t movzx ecx,word [esi]\t\t; Repeats\n"); -#endif - - fprintf(fp, "\t\t add esi,byte 2\n"); - fprintf(fp, "\t\t jecxz RESET2\t\t; Finished!\n"); - - fprintf(fp, "RESET1:\n"); - fprintf(fp, "\t\t mov [edi],eax\n"); - fprintf(fp, "\t\t add edi,byte 4\n"); - fprintf(fp, "\t\t dec ecx\n"); - fprintf(fp, "\t\t jnz short RESET1\n"); - fprintf(fp, "\t\t jmp short RESET0\n"); - - fprintf(fp, "RESET2:\n"); - fprintf(fp, "\t\t popad\n"); - fprintf(fp, "\t\t ret\n\n"); - -/* Emulation Entry Point */ - - Align(); - - fprintf(fp, "%s_RUN:\n",CPUtype); - - fprintf(fp, "\t\t pushad\n"); - fprintf(fp, "\t\t mov esi,[%s]\n",REG_PC); - fprintf(fp, "\t\t mov edx,[%s]\n",REG_CCR); - fprintf(fp, "\t\t mov ebp,dword [_OP_ROM]\n"); - - fprintf(fp,"; Check for Interrupt waiting\n\n"); - fprintf(fp,"\t\t test [%s],byte 07H\n",REG_IRQ); - fprintf(fp,"\t\t jne near interrupt\n\n"); - - fprintf(fp, "IntCont:\n"); - - /* See if was only called to check for Interrupt */ - - fprintf(fp, "\t\t test dword [%s],-1\n",ICOUNT); - fprintf(fp, "\t\t js short MainExit\n\n"); - - if(CPU==2) - { - /* 32 Bit */ - fprintf(fp, "\t\t mov eax,2\n"); /* ASG */ - fprintf(fp, "\t\t xor eax,esi\n"); /* ASG */ -#ifdef STALLCHECK - ClearRegister(ECX); - fprintf(fp, "\t\t mov cx,[eax+ebp]\n"); -#else - fprintf(fp, "\t\t movzx ecx,word [eax+ebp]\n"); -#endif - } - else - { - /* 16 Bit Fetch */ -#ifdef STALLCHECK - ClearRegister(ECX); - fprintf(fp, "\t\t mov cx,[esi+ebp]\n"); -#else - fprintf(fp, "\t\t movzx ecx,word [esi+ebp]\n"); -#endif - } - fprintf(fp, "\t\t jmp [%s_OPCODETABLE+ecx*4]\n", CPUtype); - - Align(); - - fprintf(fp, "MainExit:\n"); - fprintf(fp, "\t\t mov [%s],esi\t\t; Save PC\n",REG_PC); - fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR); - fprintf(fp, "\t\t test byte [%s],20H\n",REG_SRH); - fprintf(fp, "\t\t mov eax,[%s]\t\t; Get A7\n",REG_A7); - fprintf(fp, "\t\t jne short ME1\t\t; Mode ?\n"); - fprintf(fp, "\t\t mov [%s],eax\t\t;Save in USP\n",REG_USP); - fprintf(fp, "\t\t jmp short MC68Kexit\n"); - fprintf(fp, "ME1:\n"); - fprintf(fp, "\t\t mov [%s],eax\n",REG_ISP); - fprintf(fp, "MC68Kexit:\n"); - - /* If in Debug mode make normal SR register */ - -#ifdef MAME_DEBUG - - ReadCCR('W', ECX); - fprintf(fp, "\t\t mov [%s],eax\n\n",REG_S); - -#endif - - fprintf(fp, "\t\t popad\n"); - fprintf(fp, "\t\t ret\n"); - -/* Check for Pending Interrupts */ - - Align(); - fprintf(fp, "; Interrupt check\n\n"); - - fprintf(fp, "interrupt:\n"); - - /* check to exclude interrupts */ - - fprintf(fp, "\t\t mov eax,[%s]\n",REG_IRQ); - fprintf(fp, "\t\t and eax,byte 07H\n"); - - fprintf(fp, "\t\t cmp al,7\t\t ; Always take 7\n"); - fprintf(fp, "\t\t je short procint\n\n"); - - fprintf(fp, "\t\t mov ebx,[%s]\t\t; int mask\n",REG_SRH); - fprintf(fp, "\t\t and ebx,byte 07H\n"); - fprintf(fp, "\t\t cmp eax,ebx\n"); - fprintf(fp, "\t\t jle near IntCont\n\n"); - - /* Take pending Interrupt */ - - Align(); - fprintf(fp, "procint:\n"); - fprintf(fp, "\t\t and byte [%s],78h\t\t; remove interrupt & stop\n\n",REG_IRQ); - - /* Get Interrupt Vector from callback */ - - fprintf(fp, "\t\t push eax\t\t; save level\n\n"); - - if (SavedRegs[EBX] == '-') - { - fprintf(fp, "\t\t push EBX\n"); - } - else - { - fprintf(fp, "\t\t mov ebx,eax\n"); - } - - if (SavedRegs[ESI] == '-') - { - fprintf(fp, "\t\t mov [%s],ESI\n",REG_PC); - } - - if (SavedRegs[EDX] == '-') - { - fprintf(fp, "\t\t mov [%s],edx\n",REG_CCR); - } - -/* ----- Win32 uses FASTCALL (By Kenjo)----- */ - -#ifdef FASTCALL - fprintf(fp, "\t\t mov %s, eax\t\t; irq line #\n",FASTCALL_FIRST_REG); - fprintf(fp, "\t\t call dword [%s]\t; get the IRQ level\n", REG_IRQ_CALLBACK); -#else - fprintf(fp, "\t\t push eax\t\t; irq line #\n"); - fprintf(fp, "\t\t call dword [%s]\t; get the IRQ level\n", REG_IRQ_CALLBACK); - fprintf(fp, "\t\t lea esp,[esp+4]\n"); -#endif - - if (SavedRegs[EDX] == '-') - { - fprintf(fp, "\t\t mov edx,[%s]\n",REG_CCR); - } - - if (SavedRegs[ESI] == '-') - { - fprintf(fp, "\t\t mov esi,[%s]\n",REG_PC); - } - - /* Do we want to use normal vector number ? */ - - - fprintf(fp, "\t\t test eax,eax\n"); - fprintf(fp, "\t\t jns short AUTOVECTOR\n"); - - /* Only need EBX restored if default vector to be used */ - - if (SavedRegs[EBX] == '-') - { - fprintf(fp, "\t\t pop EBX\n"); - } - - /* Just get default vector */ - - fprintf(fp, "\t\t mov eax,ebx\n"); - - fprintf(fp, "\t\t add eax,byte 24\t\t; Vector\n\n"); - - fprintf(fp, "AUTOVECTOR:\n\n"); - - Exception(-1,0xFFFF); - - fprintf(fp, "\t\t pop eax\t\t; set Int mask\n"); - fprintf(fp, "\t\t mov bl,byte [%s]\n",REG_SRH); - fprintf(fp, "\t\t and bl,0F8h\n"); - fprintf(fp, "\t\t or bl,al\n"); - fprintf(fp, "\t\t mov byte [%s],bl\n\n",REG_SRH); - fprintf(fp, "\t\t jmp IntCont\n\n"); - -/* Exception Routine */ - - Align(); - fprintf(fp, "Exception:\n"); - fprintf(fp, "\t\t push edx\t\t; Save flags\n"); - fprintf(fp, "\t\t and eax,0FFH\t\t; Zero Extend IRQ Vector\n"); - - fprintf(fp, "\t\t push eax\t\t; Save for Later\n"); - - /* Update Cycle Count */ - - fprintf(fp, "\t\t mov al,[exception_cycles+eax]\t\t; Get Cycles\n"); - fprintf(fp, "\t\t sub [%s],eax\t\t; Decrement ICount\n",ICOUNT); - - ReadCCR('W',ECX); - - fprintf(fp, "\t\t mov edi,[%s]\t\t; Get A7\n",REG_A7); - - fprintf(fp, "\t\t test ah,20H\t; Which Mode ?\n"); - fprintf(fp, "\t\t jne short ExSuperMode\t\t; Supervisor\n"); - - fprintf(fp, "\t\t or byte [%s],20H\t; Set Supervisor Mode\n",REG_SRH); - fprintf(fp, "\t\t mov [%s],edi\t\t; Save in USP\n",REG_USP); - fprintf(fp, "\t\t mov edi,[%s]\t\t; Get ISP\n",REG_ISP); - - /* Write SR first (since it's in a register) */ - - fprintf(fp, "ExSuperMode:\n"); - fprintf(fp, "\t\t sub edi,byte 6\n"); - fprintf(fp, "\t\t mov [%s],edi\t\t; Put in A7\n",REG_A7); - Memory_Write('W',EDI,EAX,"----S-B",2); - - /* Then write PC */ - - fprintf(fp, "\t\t add edi,byte 2\n"); - Memory_Write('L',EDI,ESI,"------B",0); - - /* Get new PC */ - - fprintf(fp, "\t\t pop eax\t\t;Level\n"); - fprintf(fp, "\t\t shl eax,2\n"); - fprintf(fp, "\t\t add eax,[%s]\n",REG_VBR); /* 68010+ Vector Base */ - - /* Direct Read */ - - Memory_Read('L',EAX,"------B",0); - - fprintf(fp, "\t\t mov esi,eax\t\t;Set PC\n"); - fprintf(fp, "\t\t pop edx\t\t; Restore flags\n"); - - /* Sort out any bank changes */ - MemoryBanking(1); - - fprintf(fp, "\t\t ret\n"); -} - -void CodeSegmentEnd(void) -{ -#ifdef OS2 - fprintf(fp, "\t\t SECTION maindata USE32 FLAT CLASS=DATA\n\n"); -#else - fprintf(fp, "\t\t SECTION .data\n"); -#endif - - fprintf(fp, "\n\t\t align 16\n"); - fprintf(fp, "%s_ICount\n",CPUtype); - fprintf(fp, "asm_count\t DD 0\n\n"); - - /* Memory structure for 68000 registers */ - /* Same layout as structure in CPUDEFS.H */ - - fprintf(fp, "\n\n; Register Structure\n\n"); - fprintf(fp, "%s_regs\n",CPUtype); - - fprintf(fp, "R_D0\t DD 0\t\t\t ; Data Registers\n"); - fprintf(fp, "R_D1\t DD 0\n"); - fprintf(fp, "R_D2\t DD 0\n"); - fprintf(fp, "R_D3\t DD 0\n"); - fprintf(fp, "R_D4\t DD 0\n"); - fprintf(fp, "R_D5\t DD 0\n"); - fprintf(fp, "R_D6\t DD 0\n"); - fprintf(fp, "R_D7\t DD 0\n\n"); - - fprintf(fp, "R_A0\t DD 0\t\t\t ; Address Registers\n"); - fprintf(fp, "R_A1\t DD 0\n"); - fprintf(fp, "R_A2\t DD 0\n"); - fprintf(fp, "R_A3\t DD 0\n"); - fprintf(fp, "R_A4\t DD 0\n"); - fprintf(fp, "R_A5\t DD 0\n"); - fprintf(fp, "R_A6\t DD 0\n"); - fprintf(fp, "R_A7\t DD 0\n\n"); - - fprintf(fp, "R_ISP\t DD 0\t\t\t ; Supervisor Stack\n"); - fprintf(fp, "R_SR_H\t DD 0\t\t\t ; Status Register High TuSuuIII\n"); - fprintf(fp, "R_CCR\t DD 0\t\t\t ; CCR Register in Intel Format\n"); - fprintf(fp, "R_XC\t DD 0\t\t\t ; Extended Carry uuuuuuuX\n"); - - fprintf(fp, "R_PC\t DD 0\t\t\t ; Program Counter\n"); - fprintf(fp, "R_IRQ\t DD 0\t\t\t ; IRQ Request Level\n\n"); - fprintf(fp, "R_SR\t DD 0\t\t\t ; Motorola Format SR\n\n"); - - fprintf(fp, "R_IRQ_CALLBACK\t DD 0\t\t\t ; irq callback (get vector)\n\n"); - - fprintf(fp, "R_PPC\t DD 0\t\t\t ; Previous Program Counter\n"); - - fprintf(fp, "R_RESET_CALLBACK\t DD 0\t\t\t ; Reset Callback\n"); - - fprintf(fp, "R_SFC\t DD 0\t\t\t ; Source Function Call\n"); - fprintf(fp, "R_DFC\t DD 0\t\t\t ; Destination Function Call\n"); - fprintf(fp, "R_USP\t DD 0\t\t\t ; User Stack\n"); - fprintf(fp, "R_VBR\t DD 0\t\t\t ; Vector Base\n"); - - fprintf(fp, "asmbank\t DD 0\n\n"); - fprintf(fp, "CPUversion\t DD 0\n\n"); - fprintf(fp, "FullPC\t DD 0\n\n"); - - /* Extra space for variables mame uses for debugger */ - - fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n"); - fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n"); - fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n"); - fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n"); - fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n"); - fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n"); - fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n"); - fprintf(fp, "\t\t DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n\n"); - - /* Safe Memory Locations */ - - fprintf(fp, "\t\t ALIGN 16\n"); - - fprintf(fp, "\n\nIntelFlag\t\t\t\t; Intel Flag Lookup Table\n"); - fprintf(fp, "\t\t DD 0000h,0001h,0800h,0801h,0040h,0041h,0840h,0841h\n"); - fprintf(fp, "\t\t DD 0080h,0081h,0880h,0881h,00C0h,00C1h,08C0h,08C1h\n"); - fprintf(fp, "\t\t DD 0100h,0101h,0900h,0901h,0140h,0141h,0940h,0941h\n"); - fprintf(fp, "\t\t DD 0180h,0181h,0980h,0981h,01C0h,01C1h,09C0h,09C1h\n"); - -#if 0 - fprintf(fp, "\n\nImmTable\n"); - fprintf(fp, "\t\t DD 8,1,2,3,4,5,6,7\n\n"); -#endif - - - - /* Exception Timing Table */ - - fprintf(fp, "exception_cycles\n"); - fprintf(fp, "\t\t DB 0, 0, 0, 0, 38, 42, 44, 38, 38, 0, 38, 38, 0, 0, 0, 0\n"); - fprintf(fp, "\t\t DB 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46\n"); - fprintf(fp, "\t\t DB 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38\n\n"); - - fprintf(fp, "; RLE Compressed Jump Table\n\n"); - - fprintf(fp, "%s_COMPTABLE\n\n", CPUtype); - - fprintf(fp, "%cinclude '%s'\n\n",'%', comptab); - - fprintf(fp, "\t\tDW 0,0,0\n\n"); - - -/* If Win32, put the table area in .data section (Kenjo) */ - -#ifdef WIN32 - - fprintf(fp, "%s_OPCODETABLE\tTIMES 65536 DD 0\n\n", CPUtype); - -#else - -#ifdef OS2 - fprintf(fp, "\t\t SECTION tempdata USE32 FLAT CLASS=BSS\n\n"); -#else - fprintf(fp, "\t\t SECTION .bss\n"); -#endif - - fprintf(fp, "%s_OPCODETABLE\tRESD 65536\n\n", CPUtype); - -#endif - -} - -void EmitCode(void) -{ - CodeSegmentBegin(); - - /* Instructions */ - - moveinstructions(); /* 1000 to 3FFF MOVE.X */ - immediate(); /* 0### XXX.I */ - bitdynamic(); /* 0### dynamic bit operations */ - movep(); /* 0### Move Peripheral */ - bitstatic(); /* 08## static bit operations */ - LoadEffectiveAddress(); /* 4### */ - PushEffectiveAddress(); /* ???? */ - movesr(); /* 4#C# */ - opcode5(); /* 5000 to 5FFF ADDQ,SUBQ,Scc and DBcc */ - branchinstructions(); /* 6000 to 6FFF Bcc,BSR */ - moveq(); /* 7000 to 7FFF MOVEQ */ - abcd_sbcd(); /* 8### Decimal Add/Sub */ - typelogicalmath(); /* Various ranges */ - addx_subx(); - divides(); - swap(); - not(); /* also neg negx clr */ - moveusp(); - chk(); - exg(); - cmpm(); - mul(); - ReturnandRestore(); - rts(); - jmp_jsr(); - nbcd(); - tas(); - trap(); - trapv(); - reset(); - nop(); - stop(); - ext(); - ReturnFromException(); - tst(); - movem_reg_ea(); - movem_ea_reg(); - link(); - unlinkasm(); - asl_asr(); /* E### Shift Commands */ - asl_asr_ea(); - roxl_roxr(); - roxl_roxr_ea(); - lsl_lsr(); - lsl_lsr_ea(); - rol_ror(); - rol_ror_ea(); - LineA(); /* A000 to AFFF Line A */ - LineF(); /* F000 to FFFF Line F */ - illegal_opcode(); - - ReturnandDeallocate(); /* 68010 Commands */ - MoveControlRegister(); - MoveAddressSpace(); - - if(CPU==2) /* 68020 Commands */ - { - divl(); - mull(); - bfext(); - } - - CodeSegmentEnd(); -} - -int main(int argc, char **argv) -{ - int dwLoop; - - printf("\nMake68K - V%s - Copyright 1998, Mike Coates (mame@btinternet.com)\n", VERSION); - printf(" 1999, & Darren Olafson (deo@mail.island.net)\n"); - printf(" 2000\n"); - - if (argc != 4 && argc != 5) - { - printf("Usage: %s outfile jumptable-outfile type [ppro]\n", argv[0]); - exit(1); - } - - printf("Building 680%s 2001\n\n",argv[3]); - - for (dwLoop=0;dwLoop<65536;) OpcodeArray[dwLoop++] = -2; - - codebuf=malloc(64); - if (!codebuf) - { - printf ("Memory allocation error\n"); - exit(3); - } - - /* Emit the code */ - fp = fopen(argv[1], "w"); - if (!fp) - { - fprintf(stderr, "Can't open %s for writing\n", argv[1]); - exit(1); - } - - comptab = argv[2]; - - - CPUtype = malloc(64); -#ifdef OS2 - sprintf(CPUtype,"M680%s",argv[3]); -#else - sprintf(CPUtype,"_M680%s",argv[3]); -#endif - - if(argv[3][0]=='2') CPU = 2; - if(argc > 4 && !stricmp(argv[4], "ppro")) - { - ppro = 1; - printf("Generating ppro opcodes\n"); - } - - EmitCode(); - - fclose(fp); - - printf("\n%d Unique Opcodes\n",Opcount); - - /* output Jump table to separate file */ - fp = fopen(argv[2], "w"); - if (!fp) - { - fprintf(stderr, "Can't open %s for writing\n", argv[2]); - exit(1); - } - - JumpTable(); - - fclose(fp); - - exit(0); -} diff --git a/cpu/fame/fame.h b/cpu/fame/fame.h index 1195593..7b12343 100644 --- a/cpu/fame/fame.h +++ b/cpu/fame/fame.h @@ -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 { diff --git a/cpu/fame/famec.c b/cpu/fame/famec.c index d3cd539..8c71c07 100644 --- a/cpu/fame/famec.c +++ b/cpu/fame/famec.c @@ -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 */ /***********************/ -- 2.39.2