--- uae/include/newcpu.h 2018/04/24 16:37:54 1.1 +++ uae/include/newcpu.h 2018/04/24 16:38:27 1.1.1.2 @@ -3,274 +3,155 @@ * * MC68000 emulation * - * (c) 1995 Bernd Schmidt - * + * Copyright 1995 Bernd Schmidt */ -/* Kludge! */ -#define INLINE static __inline__ +extern int areg_byteinc[]; +extern int imm8_table[]; + +extern int broken_in; + +typedef void cpuop_func(ULONG) REGPARAM; -extern bool broken_in; +struct cputbl { + cpuop_func *handler; + int specific; + UWORD opcode; +}; -typedef void cpuop_func(UWORD) REGPARAM; +extern struct cputbl smallcputbl[]; extern cpuop_func *cpufunctbl[65536]; -extern void op_illg(UWORD) REGPARAM; +extern void op_illg(ULONG) REGPARAM; typedef char flagtype; +union flagu { + struct { + /* v must be at the start so that the x86 seto instruction + * changes the V flag. C must follow after V. */ + char v; + char c; + char n; + char z; + } flags; + ULONG longflags; +}; + extern struct regstruct { ULONG d[8]; CPTR a[8],usp; UWORD sr; - flagtype t,s,x,n,z,v,c,stopped; + flagtype t; + flagtype s; + flagtype x; + flagtype stopped; int intmask; ULONG pc; UWORD *pc_p; UWORD *pc_oldp; + + ULONG vbr,sfc,dfc; } regs; +#ifdef INTEL_FLAG_OPT +extern union flagu intel_flag_lookup[256] __asm__ ("intel_flag_lookup"); +extern union flagu regflags __asm__ ("regflags"); +#else +extern union flagu regflags; +#endif + +#define ZFLG (regflags.flags.z) +#define NFLG (regflags.flags.n) +#define CFLG (regflags.flags.c) +#define VFLG (regflags.flags.v) + + extern void MC68000_oldstep(UWORD opcode); -INLINE UWORD nextiword(void) +static __inline__ UWORD nextiword(void) { UWORD r = *regs.pc_p++; return r; } -INLINE ULONG nextilong(void) +static __inline__ ULONG nextilong(void) { ULONG r = *regs.pc_p++; r = (r << 16) + *regs.pc_p++; return r; } -INLINE void m68k_setpc(CPTR newpc) +static __inline__ void m68k_setpc(CPTR newpc) { regs.pc = newpc; regs.pc_p = regs.pc_oldp = get_real_address(newpc); } -INLINE CPTR m68k_getpc(void) +static __inline__ CPTR m68k_getpc(void) { return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp); } -INLINE void m68k_setstopped(int stop) +static __inline__ void m68k_setstopped(int stop) { regs.stopped = stop; if (stop) - specialflags |= SPCFLAG_STOP; -} - -INLINE void setflags_add(const ULONG src, const ULONG oldv, - const ULONG newv, const ULONG mask) -{ - int n=0, o=0, s=0; - switch(mask) { - case 0xff: - s = (BYTE)src < 0; - o = (BYTE)oldv < 0; - n = (BYTE)newv < 0; - regs.z = (BYTE)newv == 0; - break; - case 0xffff: - s = (WORD)src < 0; - o = (WORD)oldv < 0; - n = (WORD)newv < 0; - regs.z = (WORD)newv == 0; - break; - case 0xffffffff: - s = (LONG)src < 0; - o = (LONG)oldv < 0; - n = (LONG)newv < 0; - regs.z = (LONG)newv == 0; - break; - } - regs.c = regs.x = (s && o) || (!n && (o || s)); - regs.n = n; - regs.v = ((s && o && !n) || (!s && !o && n)); -} - -INLINE void setflags_sub(const ULONG src, const ULONG oldv, - const ULONG newv, const ULONG mask) -{ - int n=0, o=0, s=0; - switch(mask) { - case 0xff: - s = (BYTE)src < 0; - o = (BYTE)oldv < 0; - n = (BYTE)newv < 0; - regs.z = (BYTE)newv == 0; - break; - case 0xffff: - s = (WORD)src < 0; - o = (WORD)oldv < 0; - n = (WORD)newv < 0; - regs.z = (WORD)newv == 0; - break; - case 0xffffffff: - s = (LONG)src < 0; - o = (LONG)oldv < 0; - n = (LONG)newv < 0; - regs.z = (LONG)newv == 0; - break; - } - - regs.z = newv == 0; - regs.c = regs.x = (s && !o) || (n && (!o || s)); - regs.n = n; - regs.v = ((!s && o && !n) || (s && !o && n)); -} - -INLINE void setflags_addx(const ULONG src, const ULONG oldv, - const ULONG newv, const ULONG mask) -{ - int n=0, o=0, s=0; - switch(mask) { - case 0xff: - s = (BYTE)src < 0; - o = (BYTE)oldv < 0; - n = (BYTE)newv < 0; - if ((BYTE)newv != 0) regs.z = 0; - break; - case 0xffff: - s = (WORD)src < 0; - o = (WORD)oldv < 0; - n = (WORD)newv < 0; - if ((WORD)newv != 0) regs.z = 0; - break; - case 0xffffffff: - s = (LONG)src < 0; - o = (LONG)oldv < 0; - n = (LONG)newv < 0; - if ((LONG)newv != 0) regs.z = 0; - break; - } - - regs.c = regs.x = (s && o) || (!n && (o || s)); - regs.n = n; - regs.v = ((s && o && !n) || (!s && !o && n)); + specialflags |= SPCFLAG_STOP; } -INLINE void setflags_subx(const ULONG src, const ULONG oldv, - const ULONG newv, const ULONG mask) +static __inline__ int cctrue(const int cc) { - int n=0, o=0, s=0; - switch(mask) { - case 0xff: - s = (BYTE)src < 0; - o = (BYTE)oldv < 0; - n = (BYTE)newv < 0; - if ((BYTE)newv != 0) regs.z = 0; - break; - case 0xffff: - s = (WORD)src < 0; - o = (WORD)oldv < 0; - n = (WORD)newv < 0; - if ((WORD)newv != 0) regs.z = 0; - break; - case 0xffffffff: - s = (LONG)src < 0; - o = (LONG)oldv < 0; - n = (LONG)newv < 0; - if ((LONG)newv != 0) regs.z = 0; - break; - } - - if (newv != 0) regs.z = 0; - regs.c = regs.x = (s && !o) || (n && (!o || s)); - regs.n = n; - regs.v = ((!s && o && !n) || (s && !o && n)); -} - -INLINE void setflags_cmp(const ULONG src, const ULONG oldv, - const ULONG newv, const ULONG mask) -{ - int n=0, o=0, s=0; - switch(mask) { - case 0xff: - s = (BYTE)src < 0; - o = (BYTE)oldv < 0; - n = (BYTE)newv < 0; - regs.z = (BYTE)newv == 0; - break; - case 0xffff: - s = (WORD)src < 0; - o = (WORD)oldv < 0; - n = (WORD)newv < 0; - regs.z = (WORD)newv == 0; - break; - case 0xffffffff: - s = (LONG)src < 0; - o = (LONG)oldv < 0; - n = (LONG)newv < 0; - regs.z = (LONG)newv == 0; - break; - } - - regs.z = newv == 0; - regs.c = (s && !o) || (n && (!o || s)); - regs.n = n; - regs.v = ((!s && o && !n) || (s && !o && n)); -} - -INLINE void setflags_logical(ULONG newv, const ULONG mask) -{ - switch(mask) { - case 0xff: - regs.z = (BYTE)(newv) == 0; - regs.n = (BYTE)(newv) < 0; - break; - case 0xffff: - regs.z = (WORD)(newv) == 0; - regs.n = (WORD)(newv) < 0; - break; - case 0xffffffff: - regs.z = (LONG)(newv) == 0; - regs.n = (LONG)(newv) < 0; - break; + switch(cc){ + case 0: return 1; /* T */ + case 1: return 0; /* F */ + case 2: return !CFLG && !ZFLG; /* HI */ + case 3: return CFLG || ZFLG; /* LS */ + case 4: return !CFLG; /* CC */ + case 5: return CFLG; /* CS */ + case 6: return !ZFLG; /* NE */ + case 7: return ZFLG; /* EQ */ + case 8: return !VFLG; /* VC */ + case 9: return VFLG; /* VS */ + case 10:return !NFLG; /* PL */ + case 11:return NFLG; /* MI */ + case 12:return NFLG == VFLG; /* GE */ + case 13:return NFLG != VFLG; /* LT */ + case 14:return !ZFLG && (NFLG == VFLG); /* GT */ + case 15:return ZFLG || (NFLG != VFLG); /* LE */ } - regs.v = regs.c = 0; + abort(); + return 0; } +#if CPU_LEVEL > 1 +extern ULONG get_disp_ea (ULONG, UWORD); -static __inline__ bool cctrue(const int cc) +#else +static __inline__ ULONG get_disp_ea (ULONG base, UWORD dp) { - switch(cc){ - case 0: return true; /* T */ - case 1: return false; /* F */ - case 2: return !regs.c && !regs.z; /* HI */ - case 3: return regs.c || regs.z; /* LS */ - case 4: return !regs.c; /* CC */ - case 5: return regs.c; /* CS */ - case 6: return !regs.z; /* NE */ - case 7: return regs.z; /* EQ */ - case 8: return !regs.v; /* VC */ - case 9: return regs.v; /* VS */ - case 10:return !regs.n; /* PL */ - case 11:return regs.n; /* MI */ -#if 0 - case 12:return (regs.n && regs.v) || (!regs.n && !regs.v); /* GE */ - case 13:return (regs.n && !regs.v) || (!regs.n && regs.v); /* LT */ - case 14:return !regs.z && ((regs.n && regs.v) || (!regs.n && !regs.v)); /* GT */ - case 15:return regs.z || ((regs.n && !regs.v) || (!regs.n && regs.v)); /* LE */ -#endif - case 12:return regs.n == regs.v; /* GE */ - case 13:return regs.n != regs.v; /* LT */ - case 14:return !regs.z && (regs.n == regs.v);/* GT */ - case 15:return regs.z || (regs.n != regs.v); /* LE */ - } - abort(); - return 0; + int reg = (dp >> 12) & 7; + LONG regd; + + if (dp & 0x8000) + regd = regs.a[reg]; + else + regd = regs.d[reg]; + if (!(dp & 0x800)) + regd = (LONG)(WORD)regd; + return base + (BYTE)(dp) + regd; } +#endif extern void MakeSR(void); extern void MakeFromSR(void); extern void Exception(int); - -extern void MC68000_init(void); +extern void m68k_move2c(int, ULONG *); +extern void m68k_movec2(int, ULONG *); +extern void m68k_divl (UWORD, ULONG, UWORD); +extern void m68k_mull (UWORD, ULONG, UWORD); +extern void init_m68k (void); extern void MC68000_step(void); extern void MC68000_run(void); extern void MC68000_skip(CPTR);