--- uae/src/newcpu.c 2018/04/24 16:42:08 1.1.1.4 +++ uae/src/newcpu.c 2018/04/24 16:47:25 1.1.1.7 @@ -13,7 +13,6 @@ #include "options.h" #include "events.h" #include "uae.h" -#include "machdep/m68k.h" #include "memory.h" #include "custom.h" #include "readcpu.h" @@ -220,7 +219,27 @@ void init_m68k (void) } } #endif - write_log ("Building CPU table... "); + write_log ("Building CPU table for configuration: 68"); + if (currprefs.address_space_24 && currprefs.cpu_level > 1) + write_log ("EC"); + switch (currprefs.cpu_level) { + case 1: + write_log ("010"); + break; + case 2: + write_log ("020"); + break; + case 3: + write_log ("020/881"); + break; + default: + write_log ("000"); + break; + } + if (currprefs.cpu_compatible) + write_log (" (compatible mode)"); + write_log ("\n"); + read_table68k (); do_merges (); @@ -537,6 +556,58 @@ static int verify_ea (int reg, amodes mo return 0; } +uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp) +{ + int reg = (dp >> 12) & 15; + uae_s32 regd = regs.regs[reg]; + if ((dp & 0x800) == 0) + regd = (uae_s32)(uae_s16)regd; + regd <<= (dp >> 9) & 3; + if (dp & 0x100) { + uae_s32 outer = 0; + if (dp & 0x80) base = 0; + if (dp & 0x40) regd = 0; + + if ((dp & 0x30) == 0x20) base += (uae_s32)(uae_s16)next_iword(); + if ((dp & 0x30) == 0x30) base += next_ilong(); + + if ((dp & 0x3) == 0x2) outer = (uae_s32)(uae_s16)next_iword(); + if ((dp & 0x3) == 0x3) outer = next_ilong(); + + if ((dp & 0x4) == 0) base += regd; + if (dp & 0x3) base = get_long (base); + if (dp & 0x4) base += regd; + + return base + outer; + } else { + return base + (uae_s32)((uae_s8)dp) + regd; + } +} + +uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp) +{ + int reg = (dp >> 12) & 15; + uae_s32 regd = regs.regs[reg]; +#if 1 + if ((dp & 0x800) == 0) + regd = (uae_s32)(uae_s16)regd; + return base + (uae_s8)dp + regd; +#else + /* Branch-free code... benchmark this again now that + * things are no longer inline. */ + uae_s32 regd16; + uae_u32 mask; + mask = ((dp & 0x800) >> 11) - 1; + regd16 = (uae_s32)(uae_s16)regd; + regd16 &= mask; + mask = ~mask; + base += (uae_s8)dp; + regd &= mask; + regd |= regd16; + return base + regd; +#endif +} + void MakeSR (void) { #if 0 @@ -552,8 +623,8 @@ void MakeSR (void) #endif regs.sr = ((regs.t1 << 15) | (regs.t0 << 14) | (regs.s << 13) | (regs.m << 12) | (regs.intmask << 8) - | (XFLG << 4) | (NFLG << 3) | (ZFLG << 2) | (VFLG << 1) - | CFLG); + | (GET_XFLG << 4) | (GET_NFLG << 3) | (GET_ZFLG << 2) | (GET_VFLG << 1) + | GET_CFLG); } void MakeFromSR (void) @@ -566,11 +637,11 @@ void MakeFromSR (void) regs.s = (regs.sr >> 13) & 1; regs.m = (regs.sr >> 12) & 1; regs.intmask = (regs.sr >> 8) & 7; - XFLG = (regs.sr >> 4) & 1; - NFLG = (regs.sr >> 3) & 1; - ZFLG = (regs.sr >> 2) & 1; - VFLG = (regs.sr >> 1) & 1; - CFLG = regs.sr & 1; + SET_XFLG ((regs.sr >> 4) & 1); + SET_NFLG ((regs.sr >> 3) & 1); + SET_ZFLG ((regs.sr >> 2) & 1); + SET_VFLG ((regs.sr >> 1) & 1); + SET_CFLG (regs.sr & 1); if (currprefs.cpu_level >= 2) { if (olds != regs.s) { if (olds) { @@ -777,13 +848,15 @@ void m68k_divl (uae_u32 opcode, uae_u32 if ((quot & UVAL64(0xffffffff80000000)) != 0 && (quot & UVAL64(0xffffffff80000000)) != UVAL64(0xffffffff80000000)) { - VFLG = NFLG = 1; - CFLG = 0; + SET_VFLG (1); + SET_NFLG (1); + SET_CFLG (0); } else { if (((uae_s32)rem < 0) != ((uae_s64)a < 0)) rem = -rem; - VFLG = CFLG = 0; - ZFLG = ((uae_s32)quot) == 0; - NFLG = ((uae_s32)quot) < 0; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (((uae_s32)quot) == 0); + SET_NFLG (((uae_s32)quot) < 0); m68k_dreg(regs, extra & 7) = rem; m68k_dreg(regs, (extra >> 12) & 7) = quot; } @@ -799,12 +872,14 @@ void m68k_divl (uae_u32 opcode, uae_u32 rem = a % (uae_u64)src; quot = a / (uae_u64)src; if (quot > 0xffffffffu) { - VFLG = NFLG = 1; - CFLG = 0; + SET_VFLG (1); + SET_NFLG (1); + SET_CFLG (0); } else { - VFLG = CFLG = 0; - ZFLG = ((uae_s32)quot) == 0; - NFLG = ((uae_s32)quot) < 0; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (((uae_s32)quot) == 0); + SET_NFLG (((uae_s32)quot) < 0); m68k_dreg(regs, extra & 7) = rem; m68k_dreg(regs, (extra >> 12) & 7) = quot; } @@ -835,14 +910,16 @@ void m68k_divl (uae_u32 opcode, uae_u32 if ((uae_s32)src < 0) src = -src; if (div_unsigned(hi, lo, src, ", &rem) || (sign & 0x80000000) ? quot > 0x80000000 : quot > 0x7fffffff) { - VFLG = NFLG = 1; - CFLG = 0; + SET_VFLG (1); + SET_NFLG (1); + SET_CFLG (0); } else { if (sign & 0x80000000) quot = -quot; if (((uae_s32)rem < 0) != (save_high < 0)) rem = -rem; - VFLG = CFLG = 0; - ZFLG = ((uae_s32)quot) == 0; - NFLG = ((uae_s32)quot) < 0; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (((uae_s32)quot) == 0); + SET_NFLG (((uae_s32)quot) < 0); m68k_dreg(regs, extra & 7) = rem; m68k_dreg(regs, (extra >> 12) & 7) = quot; } @@ -856,12 +933,14 @@ void m68k_divl (uae_u32 opcode, uae_u32 hi = (uae_u32)m68k_dreg(regs, extra & 7); } if (div_unsigned(hi, lo, src, ", &rem)) { - VFLG = NFLG = 1; - CFLG = 0; + SET_VFLG (1); + SET_NFLG (1); + SET_CFLG (0); } else { - VFLG = CFLG = 0; - ZFLG = ((uae_s32)quot) == 0; - NFLG = ((uae_s32)quot) < 0; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (((uae_s32)quot) == 0); + SET_NFLG (((uae_s32)quot) < 0); m68k_dreg(regs, extra & 7) = rem; m68k_dreg(regs, (extra >> 12) & 7) = quot; } @@ -896,15 +975,16 @@ void m68k_mull (uae_u32 opcode, uae_u32 uae_s64 a = (uae_s64)(uae_s32)m68k_dreg(regs, (extra >> 12) & 7); a *= (uae_s64)(uae_s32)src; - VFLG = CFLG = 0; - ZFLG = a == 0; - NFLG = a < 0; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (a == 0); + SET_NFLG (a < 0); if (extra & 0x400) m68k_dreg(regs, extra & 7) = a >> 32; else if ((a & UVAL64(0xffffffff80000000)) != 0 && (a & UVAL64(0xffffffff80000000)) != UVAL64(0xffffffff80000000)) { - VFLG = 1; + SET_VFLG (1); } m68k_dreg(regs, (extra >> 12) & 7) = (uae_u32)a; } else { @@ -912,13 +992,14 @@ void m68k_mull (uae_u32 opcode, uae_u32 uae_u64 a = (uae_u64)(uae_u32)m68k_dreg(regs, (extra >> 12) & 7); a *= (uae_u64)src; - VFLG = CFLG = 0; - ZFLG = a == 0; - NFLG = ((uae_s64)a) < 0; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (a == 0); + SET_NFLG (((uae_s64)a) < 0); if (extra & 0x400) m68k_dreg(regs, extra & 7) = a >> 32; else if ((a & UVAL64(0xffffffff00000000)) != 0) { - VFLG = 1; + SET_VFLG (1); } m68k_dreg(regs, (extra >> 12) & 7) = (uae_u32)a; } @@ -940,16 +1021,17 @@ void m68k_mull (uae_u32 opcode, uae_u32 dst_lo = -dst_lo; if (dst_lo == 0) dst_hi++; } - VFLG = CFLG = 0; - ZFLG = dst_hi == 0 && dst_lo == 0; - NFLG = ((uae_s32)dst_hi) < 0; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (dst_hi == 0 && dst_lo == 0); + SET_NFLG (((uae_s32)dst_hi) < 0); if (extra & 0x400) m68k_dreg(regs, extra & 7) = dst_hi; else if ((dst_hi != 0 || (dst_lo & 0x80000000) != 0) && ((dst_hi & 0xffffffff) != 0xffffffff || (dst_lo & 0x80000000) != 0x80000000)) { - VFLG = 1; + SET_VFLG (1); } m68k_dreg(regs, (extra >> 12) & 7) = dst_lo; } else { @@ -958,13 +1040,14 @@ void m68k_mull (uae_u32 opcode, uae_u32 mul_unsigned(src,(uae_u32)m68k_dreg(regs, (extra >> 12) & 7),&dst_hi,&dst_lo); - VFLG = CFLG = 0; - ZFLG = dst_hi == 0 && dst_lo == 0; - NFLG = ((uae_s32)dst_hi) < 0; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (dst_hi == 0 && dst_lo == 0); + SET_NFLG (((uae_s32)dst_hi) < 0); if (extra & 0x400) m68k_dreg(regs, extra & 7) = dst_hi; else if (dst_hi != 0) { - VFLG = 1; + SET_VFLG (1); } m68k_dreg(regs, (extra >> 12) & 7) = dst_lo; } @@ -985,7 +1068,11 @@ void m68k_reset (void) regs.stopped = 0; regs.t1 = 0; regs.t0 = 0; - ZFLG = CFLG = NFLG = VFLG = 0; + SET_ZFLG (0); + SET_XFLG (0); + SET_CFLG (0); + SET_VFLG (0); + SET_NFLG (0); regs.spcflags = 0; regs.intmask = 7; regs.vbr = regs.sfc = regs.dfc = 0; @@ -1064,43 +1151,42 @@ static int n_insns = 0, n_spcinsns = 0; static uaecptr last_trace_ad = 0; -static __inline__ void do_trace (void) +static void do_trace (void) { - if (regs.spcflags & SPCFLAG_TRACE) { /* 6 */ - if (regs.t0) { - uae_u16 opcode; - /* should also include TRAP, CHK, SR modification FPcc */ - /* probably never used so why bother */ - /* We can afford this to be inefficient... */ - m68k_setpc (m68k_getpc ()); - fill_prefetch_0 (); - opcode = get_word (regs.pc); - if (opcode == 0x4e72 /* RTE */ - || opcode == 0x4e74 /* RTD */ - || opcode == 0x4e75 /* RTS */ - || opcode == 0x4e77 /* RTR */ - || opcode == 0x4e76 /* TRAPV */ - || (opcode & 0xffc0) == 0x4e80 /* JSR */ - || (opcode & 0xffc0) == 0x4ec0 /* JMP */ - || (opcode & 0xff00) == 0x6100 /* BSR */ - || ((opcode & 0xf000) == 0x6000 /* Bcc */ - && cctrue((opcode >> 8) & 0xf)) - || ((opcode & 0xf0f0) == 0x5050 /* DBcc */ - && !cctrue((opcode >> 8) & 0xf) - && (uae_s16)m68k_dreg(regs, opcode & 7) != 0)) - { - last_trace_ad = m68k_getpc (); - regs.spcflags &= ~SPCFLAG_TRACE; - regs.spcflags |= SPCFLAG_DOTRACE; - } - } else if (regs.t1) { + if (regs.t0) { + uae_u16 opcode; + /* should also include TRAP, CHK, SR modification FPcc */ + /* probably never used so why bother */ + /* We can afford this to be inefficient... */ + m68k_setpc (m68k_getpc ()); + fill_prefetch_0 (); + opcode = get_word (regs.pc); + if (opcode == 0x4e72 /* RTE */ + || opcode == 0x4e74 /* RTD */ + || opcode == 0x4e75 /* RTS */ + || opcode == 0x4e77 /* RTR */ + || opcode == 0x4e76 /* TRAPV */ + || (opcode & 0xffc0) == 0x4e80 /* JSR */ + || (opcode & 0xffc0) == 0x4ec0 /* JMP */ + || (opcode & 0xff00) == 0x6100 /* BSR */ + || ((opcode & 0xf000) == 0x6000 /* Bcc */ + && cctrue((opcode >> 8) & 0xf)) + || ((opcode & 0xf0f0) == 0x5050 /* DBcc */ + && !cctrue((opcode >> 8) & 0xf) + && (uae_s16)m68k_dreg(regs, opcode & 7) != 0)) + { last_trace_ad = m68k_getpc (); regs.spcflags &= ~SPCFLAG_TRACE; regs.spcflags |= SPCFLAG_DOTRACE; } + } else if (regs.t1) { + last_trace_ad = m68k_getpc (); + regs.spcflags &= ~SPCFLAG_TRACE; + regs.spcflags |= SPCFLAG_DOTRACE; } } + static int do_specialties (void) { /*n_spcinsns++;*/ @@ -1127,7 +1213,8 @@ static int do_specialties (void) } } } - do_trace (); + if (regs.spcflags & SPCFLAG_TRACE) + do_trace (); if (regs.spcflags & SPCFLAG_DISK) do_disk (); @@ -1333,7 +1420,7 @@ void m68k_dumpstate (uaecptr *nextpc) regs.usp,regs.isp,regs.msp,regs.vbr); printf ("T=%d%d S=%d M=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d\n", regs.t1, regs.t0, regs.s, regs.m, - XFLG, NFLG, ZFLG, VFLG, CFLG, regs.intmask); + GET_XFLG, GET_NFLG, GET_ZFLG, GET_VFLG, GET_CFLG, regs.intmask); for (i = 0; i < 8; i++){ printf ("FP%d: %g ", i, regs.fp[i]); if ((i & 3) == 3) printf ("\n");