]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Remaining bus error prefetch updates and other fixes.
authorToni Wilen <twilen@winuae.net>
Thu, 26 Dec 2019 18:16:44 +0000 (20:16 +0200)
committerToni Wilen <twilen@winuae.net>
Thu, 26 Dec 2019 18:16:44 +0000 (20:16 +0200)
cputest.cpp
cputest/adis/decode_ea.c
cputest/adis/defs.h
cputest/adis/util.c
cputest/asm.S
cputest/cputest_defines.h
cputest/main.c
gencpu.cpp
include/newcpu.h
newcpu_common.cpp

index 0bfd73e4390a486ff56dca2499a07c96e1b8a21e..05a214ab5c906a80d2233255d3d76d2186620c20 100644 (file)
@@ -159,7 +159,7 @@ struct accesshistory
 static int ahcnt_current, ahcnt_written;
 static int noaccesshistory = 0;
 
-#define MAX_ACCESSHIST 80
+#define MAX_ACCESSHIST 128
 static struct accesshistory ahist[MAX_ACCESSHIST];
 
 static int is_superstack_use_required(void)
@@ -2953,6 +2953,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
        int quick = 0;
        int rounds = feature_test_rounds;
        int subtest_count = 0;
+       int data_saved = 0;
 
        int count = 0;
 
@@ -3074,6 +3075,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                uae_u32 dstaddr = 0xffffffff;
                uae_u32 branchtarget_old = 0xffffffff;
                uae_u32 instructionendpc_old = opcode_memory_start;
+               uae_u32 startpc_old = opcode_memory_start;
                int branch_target_swap_mode_old = 0;
 
                if (verbose) {
@@ -3189,11 +3191,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                printf("");
 
 
-                                       uaecptr pc = opcode_memory_start + 2;
-
-                                       if (is_nowrite_address(pc, 1)) {
-                                               goto nextopcode;
-                                       }
+                                       uaecptr startpc = opcode_memory_start;
+                                       uaecptr pc = startpc + 2;
 
                                        if (target_opcode_address != 0xffffffff) {
                                                pc -= 2;
@@ -3207,6 +3206,13 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                                abort();
                                                        }
                                                }
+                                               startpc = opcode_memory_address;
+                                       }
+
+                                       // Start address to start address + 3 must be accessible or
+                                       // jump prefetch would cause early bus error which we don't want
+                                       if (is_nowrite_address(startpc, 4)) {
+                                               goto nextopcode;
                                        }
 
                                        if (dp->mnemo != i_ILLG) {
@@ -3494,13 +3500,17 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                        dst = store_mem_writes(dst, 1);
 
                                        uae_u32 instructionendpc_old_prev = instructionendpc_old;
+                                       uae_u32 startpc_old_prev = startpc_old;
                                        uae_u32 branchtarget_old_prev = branchtarget_old;
                                        uae_u32 srcaddr_old_prev = srcaddr_old;
                                        uae_u32 dstaddr_old_prev = dstaddr_old;
 
-                                       // PC before test: end address of test intruction
+                                       if (startpc != startpc_old) {
+                                               dst = store_reg(dst, CT_PC, startpc_old, startpc, -1);
+                                               startpc_old = startpc;
+                                       }
                                        if (instructionendpc != instructionendpc_old) {
-                                               dst = store_reg(dst, CT_PC, instructionendpc_old, instructionendpc, -1);
+                                               dst = store_reg(dst, CT_ENDPC, instructionendpc_old, instructionendpc, -1);
                                                instructionendpc_old = instructionendpc;
                                        }
                                        if (srcaddr != srcaddr_old && (dflags & 1)) {
@@ -3623,7 +3633,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
 
                                                        // initialize CPU state
 
-                                                       regs.pc = opcode_memory_start;
+                                                       regs.pc = startpc;
                                                        regs.ir = get_word_test(regs.pc + 0);
                                                        regs.irc = get_word_test(regs.pc + 2);
 
@@ -3906,8 +3916,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                dstaddr_old = dstaddr_old_prev;
                                                branchtarget_old = branchtarget_old_prev;
                                                instructionendpc_old = instructionendpc_old_prev;
+                                               startpc_old = startpc_old_prev;
                                        } else {
                                                full_format_cnt++;
+                                               data_saved = 1;
                                        }
                                        if (verbose) {
                                                wprintf(_T(" OK=%d OB=%d S=%d/%d T=%d STP=%d"), ok, exception_array[0], prev_s_cnt, s_cnt, t_cnt, cnt_stopped);
@@ -3927,6 +3939,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        srcaddr_old = 0xffffffff;
                                                        dstaddr_old = 0xffffffff;
                                                        instructionendpc_old = opcode_memory_start;
+                                                       startpc_old = opcode_memory_start;
                                                }
                                                dst = storage_buffer;
                                                for (int i = 0; i < MAX_REGISTERS; i++) {
@@ -3957,8 +3970,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                nextopcode:;
                }
 
-               if (subtest_count > 0) {
+               if (data_saved) {
                        save_data(dst, dir);
+                       data_saved = 0;
                }
                dst = storage_buffer;
 
@@ -4006,6 +4020,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                target_ea_opcode_cnt = 0;
                                if (target_ea_opcode_max > 0)
                                        nextround = true;
+                       } else {
+                               quick = 0;
                        }
                        target_opcode_address = feature_target_ea[target_ea_opcode_cnt][2];
                        target_ea[2] = opcode_memory_address + target_opcode_address;
index 24874dda599766a17e61019443cb0827387f4061..3f4b39edaa658fcbbd99001bd1f307338814f4e7 100644 (file)
@@ -139,19 +139,25 @@ switch (mode)
   /****************** address register indirect indexed ***************/
 
   case 6:
+    if ((first_ext_w & 0x100) && !cpu68020)
+      first_ext_w &= ~0x100;
     if (first_ext_w & 0x100)
       {
       if (cpu68020)
         return (full_extension (to, code + first_ext, mode, reg));
+#if 0
       else
         {
         instr_bad = TRUE;
         return (0);
         }
-      }
+#endif
+    }
     else
       {
       UWORD size = (first_ext_w >> 9) & 0x3;
+      if (size != 0 && !cpu68020)
+          size = 0;
 #if 0
       if (!cpu68020 && size != 0)  /* Only size of 1 allowed for 68000 */
         {
@@ -263,7 +269,9 @@ switch (mode)
       /***************** PC memory indirect with index ************/
 
       case 3:
-        if (first_ext_w & 0x0100)
+          if ((first_ext_w & 0x100) && !cpu68020)
+              first_ext_w &= ~0x100;
+          if (first_ext_w & 0x0100)
           {
           /* long extension word */
           if (cpu68020)
@@ -279,6 +287,8 @@ switch (mode)
         else
           {
           UWORD size = (first_ext_w >> 9) & 0x3;
+          if (size != 0 && !cpu68020)
+              size = 0;
 #if 0
           if (!cpu68020 && size != 0)  /* Only size of 1 allowed for 68000 */
             {
index 63c2454401d5c5d5b305a5aefd689d54ee842569..1a1c53d0a54b4a5dd3c2d5f78efd47cb122fe359 100644 (file)
@@ -319,7 +319,7 @@ void analyze_code (UBYTE *seg);
 uint decode_ea (char *to, ushort mode, ushort reg, UWORD access, ushort first_ext);
 
 /* disasm_code.c */
-uint disasm_instr (UWORD *instr, char*);
+uint disasm_instr (UWORD *instr, char*, int);
 void disasm_code (UBYTE *seg, ULONG seg_size);
 
 /* disasm_data.c */
index 6280b541a384e2771cf9b6d6a8216cfece3d6382..8df07bded15ad986eab4ce78949cc361112036ff 100644 (file)
@@ -960,7 +960,7 @@ ULONG next_ref(ULONG from, ULONG to, UWORD *access_type)
        return 0;
 }
 
-uint disasm_instr(UWORD *instr, char *out)
+uint disasm_instr(UWORD *instr, char *out, int cpu_lvl)
 
 /**********************************************************************/
 /*    Returns number of 16 bit words disassembled                     */
@@ -973,6 +973,19 @@ uint disasm_instr(UWORD *instr, char *out)
     first_ref = 0;
     last_ref = 0xffffffff;
     current_ref = (ULONG)instr;
+    if (cpu_lvl < 5) {
+        cpu68060 = 0;
+    }
+    if (cpu_lvl < 4) {
+        cpu68040 = 0;
+    }
+    if (cpu_lvl < 3) {
+        cpu68030 = 0;
+    }
+    if (cpu_lvl < 2) {
+        cpu68020 = 0;
+        fpu68881 = 0;
+    }
 
        set_pass3;
 
index beee98ff79458d9f148f6b109ed396e399d246b4..c37f5f8257488fafe83fc6c93b3b103dc48697b1 100644 (file)
@@ -122,10 +122,7 @@ _execute_test000:
        move.l S_SSP(a0),sp
        move.l S_PC(a0),a1
        move.l a1,-(sp)
-       move.w (a1)+,d0
-       move.w (a1),d1
-       eor.w d1,d0
-       move.w d0,ACTIVITYREG | opcode^first param = background color
+       move.w (a1),ACTIVITYREG | opcode = background color
        move.w S_SR+2(a0),-(sp)
        move.l S_AREG+7*4(a0),a1
        move.l a1,USP
@@ -144,10 +141,7 @@ _execute_test010:
        move.l S_PC(a0),a1
        clr.w -(sp)
        move.l a1,-(sp)
-       move.w (a1)+,d0
-       move.w (a1),d1
-       eor.w d1,d0
-       move.w d0,ACTIVITYREG | opcode^first param = background color
+       move.w (a1),ACTIVITYREG | opcode = background color
        move.w S_SR+2(a0),-(sp)
        move.l S_AREG+7*4(a0),a1
        move.l a1,USP
@@ -169,10 +163,7 @@ _execute_test020:
        move.l S_PC(a0),a1
        clr.w -(sp)
        move.l a1,-(sp)
-       move.w (a1)+,d0
-       move.w (a1),d1
-       eor.w d1,d0
-       move.w d0,ACTIVITYREG | opcode^first param = background color
+       move.w (a1),ACTIVITYREG | opcode = background color
        move.w S_SR+2(a0),-(sp)
        move.l S_AREG+7*4(a0),a1
        move.l a1,USP
@@ -196,10 +187,7 @@ _execute_testfpu:
        move.l S_PC(a0),a1
        clr.w -(sp)
        move.l a1,-(sp)
-       move.w (a1)+,d0
-       move.w (a1),d1
-       eor.w d1,d0
-       move.w d0,ACTIVITYREG | opcode^first param = background color
+       move.w (a1),ACTIVITYREG | opcode = background color
        move.w S_SR+2(a0),-(sp)
        move.l S_AREG+7*4(a0),a1
        move.l a1,USP
index e50b27acfa3bc5efcc949805e06c20a2ce0d28c7..33d15780411d9257f83e2b5736bc7a33b87f38e1 100644 (file)
@@ -1,5 +1,5 @@
 
-#define DATA_VERSION 10
+#define DATA_VERSION 11
 
 #define CT_FPREG 0
 #define CT_DREG 0
@@ -11,6 +11,7 @@
 #define CT_FPIAR 20
 #define CT_FPSR 21
 #define CT_FPCR 22
+#define CT_ENDPC 26
 #define CT_BRANCHTARGET 27
 #define CT_SRCADDR 28
 #define CT_DSTADDR 29
index 0eb1e8aa7b4e2b3a81cbd963dd661980a4b36ed7..a54b4fd6e6744fd30643dd6fddc96f7e902d648d 100644 (file)
@@ -50,6 +50,7 @@ struct registers
        uae_u16 tracedata[6];
        uae_u32 srcaddr, dstaddr, branchtarget;
        uae_u8 branchtarget_mode;
+       uae_u32 endpc;
 };
 
 static struct registers test_regs;
@@ -97,7 +98,7 @@ static int high_memory_offset;
 static uae_u32 vbr[256];
 static int exceptioncount[3][128];
 static int supercnt;
-static uae_u32 endpc;
+static uae_u32 startpc, endpc;
 
 static char inst_name[16+1];
 #ifndef M68K
@@ -115,6 +116,7 @@ static int quit;
 static uae_u8 ccr_mask;
 static uae_u32 addressing_mask = 0x00ffffff;
 static uae_u32 interrupt_mask;
+static int disasm;
 
 #define SIZE_STORED_ADDRESS_OFFSET 8
 #define SIZE_STORED_ADDRESS 16
@@ -878,6 +880,9 @@ static uae_u8 *restore_data(uae_u8 *p)
        } else if (mode == CT_DSTADDR) {
                int size;
                p = restore_value(p, &regs.dstaddr, &size);
+       } else if (mode == CT_ENDPC) {
+               int size;
+               p = restore_value(p, &regs.endpc, &size);
        } else if (mode == CT_PC) {
                int size;
                p = restore_value(p, &regs.pc, &size);
@@ -959,7 +964,7 @@ static void addinfo_bytes(char *name, uae_u8 *src, uae_u32 address, int offset,
        *outbp++ = '\n';
 }
 
-extern uae_u16 disasm_instr(uae_u16 *, char *);
+extern uae_u16 disasm_instr(uae_u16 *, char *, int);
 
 static void out_disasm(uae_u8 *mem)
 {
@@ -985,7 +990,7 @@ static void out_disasm(uae_u8 *mem)
                }
                tmpbuffer[0] = 0;
                if (!(((uae_u32)code) & 1)) {
-                       v = disasm_instr(code + offset, tmpbuffer);
+                       v = disasm_instr(code + offset, tmpbuffer, cpu_lvl);
                        sprintf(outbp, "%08lx ", p);
                        outbp += strlen(outbp);
                        for (int i = 0; i < v; i++) {
@@ -1024,7 +1029,9 @@ static void addinfo(void)
        if (!dooutput)
                return;
 
-       out_disasm(opcode_memory);
+       if (disasm) {
+               out_disasm(opcode_memory);
+       }
 
        if (regs.branchtarget != 0xffffffff) {
                out_disasm((uae_u8*)regs.branchtarget);
@@ -1055,8 +1062,8 @@ static void addinfo(void)
                uae_u8 *b = (uae_u8 *)regs.branchtarget - SIZE_STORED_ADDRESS_OFFSET;
                addinfo_bytes("B", b, regs.branchtarget, -SIZE_STORED_ADDRESS_OFFSET, SIZE_STORED_ADDRESS);
        }
-       //sprintf(outbp, "ENDPC=%08lx\n", endpc);
-       //outbp += strlen(outbp);
+       sprintf(outbp, "STARTPC=%08lx ENDPC=%08lx\n", startpc, endpc);
+       outbp += strlen(outbp);
 }
 
 struct srbit
@@ -1541,8 +1548,13 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr)
                        if ((val & (sr_undefined_mask & test_ccrignoremask)) != (test_regs.sr & (sr_undefined_mask & test_ccrignoremask)) && !ignore_errors && !ignore_sr) {
                                addinfo();
                                if (dooutput) {
-                                       sprintf(outbp, "SR: expected %04x -> %04x but got %04x (%04x)\n", test_sr & 0xffff, val & 0xffff, test_regs.sr & 0xffff, test_ccrignoremask);
+                                       sprintf(outbp, "SR: expected %04x -> %04x but got %04x", test_sr & 0xffff, val & 0xffff, test_regs.sr & 0xffff);
                                        outbp += strlen(outbp);
+                                       if (test_ccrignoremask != 0xffff) {
+                                               sprintf(outbp, " (%04x)", test_ccrignoremask);
+                                               outbp += strlen(outbp);
+                                       }
+                                       *outbp++ = '\n';
                                }
                                errors++;
                        }
@@ -1779,6 +1791,7 @@ static void process_test(uae_u8 *p)
        regs.branchtarget = 0xffffffff;
 
        endpc = opcode_memory_addr;
+       startpc = opcode_memory_addr;
 
        start_test();
 
@@ -1791,7 +1804,9 @@ static void process_test(uae_u8 *p)
                outbp = outbuffer;
 #endif
 
-               regs.pc = endpc;
+               regs.endpc = endpc;
+               regs.pc = startpc;
+
                for (;;) {
                        uae_u8 v = *p;
                        if (v == CT_END_INIT || v == CT_END_FINISH)
@@ -1805,14 +1820,14 @@ static void process_test(uae_u8 *p)
                store_addr(regs.srcaddr, srcaddr);
                store_addr(regs.dstaddr, dstaddr);
                store_addr(regs.branchtarget, branchtarget);
-               endpc = regs.pc;
+               startpc = regs.pc;
+               endpc = regs.endpc;
                uae_u8 *opcode_memory_end = (uae_u8*)endpc;
 
                xmemcpy(&last_registers, &regs, sizeof(struct registers));
 
                int fpumode = fpu_model && (opcode_memory[0] & 0xf0) == 0xf0;
 
-               uae_u32 pc = opcode_memory_addr;
                uae_u32 originalopcodeend = 0x4afc4e71;
                uae_u32 opcodeend = originalopcodeend;
                int extraccr = 0;
@@ -1823,8 +1838,8 @@ static void process_test(uae_u8 *p)
                        validendsize = 1;
                }
 
-               uae_u32 last_pc = opcode_memory_addr;
-               uae_u32 last_fpiar = opcode_memory_addr;
+               uae_u32 last_pc = startpc;
+               uae_u32 last_fpiar = startpc;
                int old_super = -1;
 
                for (;;) {
@@ -1866,8 +1881,8 @@ static void process_test(uae_u8 *p)
 
                                regs.ssp = super_stack_memory - 0x80;
                                regs.msp = super_stack_memory;
-                               regs.pc = opcode_memory_addr;
-                               regs.fpiar = opcode_memory_addr;
+                               regs.pc = startpc;
+                               regs.fpiar = startpc;
 
 #ifdef M68K
                                xmemcpy((void*)regs.ssp, (void*)regs.regs[15], 0x20);
@@ -2291,6 +2306,7 @@ int main(int argc, char *argv[])
 
        check_undefined_sr = 1;
        ccr_mask = 0xff;
+       disasm = 1;
        for (int i = 1; i < argc; i++) {
                char *s = argv[i];
                char *next = i + 1 < argc ? argv[i + 1] : NULL;
@@ -2318,6 +2334,8 @@ int main(int argc, char *argv[])
                        cpu_lvl = 4;
                } else if (!_stricmp(s, "68060")) {
                        cpu_lvl = 5;
+               } else if (!_stricmp(s, "nodisasm")) {
+                       disasm = 0;
                }
        }
 
index a6f6172b70885c788c7f5678d8c7ea4668cbc6d0..9e746b81940257fd9d61fd1ee3e6c70d0698676d 100644 (file)
@@ -4134,6 +4134,7 @@ static void gen_opcode (unsigned int opcode)
        g_instr = curi;
        g_srcname[0] = 0;
        bus_error_code[0] = 0;
+       bus_error_code2[0] = 0;
 
        // do not unnecessarily create useless mmuop030
        // functions when CPU is not 68030
@@ -4183,9 +4184,9 @@ static void gen_opcode (unsigned int opcode)
                                c += 2;
                                if (curi->smode == imm || curi->smode == Dreg) {
                                        c += 2;
-                                       fill_prefetch_next_after("\t\tccr_68000_long_move_ae_LZN(src);\n\t\treg_68000_long_replace_low(dstreg, src);\n");
+                                       fill_prefetch_next_after("\t\tccr_68000_long_move_ae_LZN(src);\n\t\tdreg_68000_long_replace_low(dstreg, src);\n");
                                } else {
-                                       fill_prefetch_next_after("\t\treg_68000_long_replace_low(dstreg, src);\n");
+                                       fill_prefetch_next_after("\t\tdreg_68000_long_replace_low(dstreg, src);\n");
                                }
                        } else {
                                fill_prefetch_next_after("\t\tccr_68000_long_move_ae_LZN(src);\n");
@@ -4210,35 +4211,22 @@ static void gen_opcode (unsigned int opcode)
                }
                break;
        }
-       // all SR/CCR modifications does full prefetch
+       // all SR/CCR modifications do full prefetch
        case i_ORSR:
+       case i_ANDSR:
        case i_EORSR:
-               printf("\tMakeSR ();\n");
+               printf("\tMakeSR();\n");
                genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                if (curi->size == sz_byte) {
                        printf("\tsrc &= 0xFF;\n");
                } else {
                        check_trace();
                }
-               addcycles000 (8);
-               printf("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
+               addcycles000(8);
+               printf("\tregs.sr %c= src;\n", curi->mnemo == i_ORSR ? '|' : curi->mnemo == i_ANDSR ? '&' : '^');
                makefromsr_t0();
-               sync_m68k_pc ();
-               fill_prefetch_full_ntx(0);
-               break;
-       case i_ANDSR:
-               printf("\tMakeSR ();\n");
-               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               if (curi->size == sz_byte) {
-                       printf("\tsrc |= 0xFF00;\n");
-               } else {
-                       check_trace();
-               }
-               addcycles000 (8);
-               printf("\tregs.sr &= src;\n");
-               makefromsr_t0();
-               sync_m68k_pc ();
-               fill_prefetch_full_ntx(0);
+               sync_m68k_pc();
+               fill_prefetch_full_ntx(1);
                break;
        case i_SUB:
        {
@@ -4246,21 +4234,54 @@ static void gen_opcode (unsigned int opcode)
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "src", 1, 0,
                        curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW);
-               if (curi->dmode == Dreg) {
-                       if (curi->size == sz_long) {
+               genflags(flag_sub, curi->size, "newv", "src", "dst");
+               if (curi->size == sz_long) {
+                       if (curi->dmode == Dreg) {
                                c += 2;
-                               if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg || curi->smode == Areg)
+                               if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg || curi->smode == Areg) {
                                        c += 2;
+                                       fill_prefetch_next_after(
+                                               "\t\tuae_s16 bnewv = (uae_s16)dst - (uae_s16)src;\n"
+                                               "\t\tint bflgs = ((uae_s16)(src)) < 0;\n"
+                                               "\t\tint bflgo = ((uae_s16)(dst)) < 0;\n"
+                                               "\t\tint bflgn = bnewv < 0;\n"
+                                               "\t\tccr_68000_long_move_ae_LZN(bnewv);\n"
+                                               "\t\tSET_CFLG(((uae_u16)(src)) > ((uae_u16)(dst)));\n"
+                                               "\t\tSET_XFLG(GET_CFLG());\n"
+                                               "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgn ^ bflgo));\n"
+                                               "\t\tdreg_68000_long_replace_low(dstreg, bnewv);\n");
+                               } else {
+                                       fill_prefetch_next_after("\t\tdreg_68000_long_replace_low(dstreg, newv);\n");
+                               }
+                       } else {
+                               fill_prefetch_next_after(
+                                       "\t\tuae_s16 bnewv = (uae_s16)dst - (uae_s16)src;\n"
+                                       "\t\tint bflgs = ((uae_s16)(src)) < 0;\n"
+                                       "\t\tint bflgo = ((uae_s16)(dst)) < 0;\n"
+                                       "\t\tint bflgn = bnewv < 0;\n"
+                                       "\t\tccr_68000_long_move_ae_LZN(bnewv);\n"
+                                       "\t\tSET_CFLG(((uae_u16)(src)) > ((uae_u16)(dst)));\n"
+                                       "\t\tSET_XFLG(GET_CFLG());\n"
+                                       "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgn ^ bflgo));\n");
+                       }
+                       if (c > 0)
+                               addcycles000(c);
+                       genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst");
+               } else {
+                       if (curi->dmode == Dreg) {
+                               genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst");
+                       }
+                       if ((curi->smode >= imm || curi->smode == Dreg) && curi->dmode != Dreg) {
+                               fill_prefetch_next_after(NULL);
+                       } else {
+                               fill_prefetch_next();
+                       }
+                       if (c > 0)
+                               addcycles000(c);
+                       if (curi->dmode != Dreg) {
+                               genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst");
                        }
                }
-               fill_prefetch_next ();
-               if (c > 0)
-                       addcycles000 (c);
-               start_brace ();
-               genflags (flag_sub, curi->size, "newv", "src", "dst");
-               genastore_rev ("newv", curi->dmode, "dstreg", curi->size, "dst");
                break;
        }
        case i_SUBA:
@@ -4269,8 +4290,7 @@ static void gen_opcode (unsigned int opcode)
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "src", 1, 0,
                        curi->dmode, "dstreg", sz_long, "dst", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW);
+               printf("\tuae_u32 newv = dst - src;\n");
                if (curi->smode == immi) {
                        // SUBAQ.x is always 8 cycles
                        c += 4;
@@ -4279,11 +4299,9 @@ static void gen_opcode (unsigned int opcode)
                        if (islongimm (curi))
                                c += 2;
                }
-               fill_prefetch_next ();
+               fill_prefetch_next_after("\t\tareg_68000_long_replace_low(dstreg, newv);\n");
                if (c > 0)
                        addcycles000 (c);
-               start_brace ();
-               printf("\tuae_u32 newv = dst - src;\n");
                genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
                break;
        }
@@ -4316,7 +4334,7 @@ static void gen_opcode (unsigned int opcode)
                                        "\t\tSET_XFLG(GET_CFLG());\n"
                                        "\t\tif (newv & 0xffff) SET_ZFLG(0);\n"
                                        "\t\tSET_NFLG(newv & 0x8000); \n"
-                                       "\t\treg_68000_long_replace_low(dstreg, newv);\n");
+                                       "\t\tdreg_68000_long_replace_low(dstreg, newv);\n");
                        } else {
                                fill_prefetch_next();
                        }
@@ -4372,21 +4390,54 @@ static void gen_opcode (unsigned int opcode)
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "src", 1, 0,
                        curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW);
-               if (curi->dmode == Dreg) {
-                       if (curi->size == sz_long) {
+               genflags(flag_add, curi->size, "newv", "src", "dst");
+               if (curi->size == sz_long) {
+                       if (curi->dmode == Dreg) {
                                c += 2;
-                               if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg || curi->smode == Areg)
+                               if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg || curi->smode == Areg) {
                                        c += 2;
+                                       fill_prefetch_next_after(
+                                               "\t\tuae_s16 bnewv = (uae_s16)dst + (uae_s16)src;\n"
+                                               "\t\tint bflgs = ((uae_s16)(src)) < 0;\n"
+                                               "\t\tint bflgo = ((uae_s16)(dst)) < 0;\n"
+                                               "\t\tint bflgn = bnewv < 0;\n"
+                                               "\t\tccr_68000_long_move_ae_LZN(bnewv);\n"
+                                               "\t\tSET_CFLG(((uae_u16)(~dst)) < ((uae_u16)(src)));\n"
+                                               "\t\tSET_XFLG(GET_CFLG());\n"
+                                               "\t\tSET_VFLG((bflgs ^ bflgn) & (bflgo ^ bflgn));\n"
+                                               "\t\tdreg_68000_long_replace_low(dstreg, bnewv);\n");
+                               } else {
+                                       fill_prefetch_next_after("\t\tdreg_68000_long_replace_low(dstreg, newv);\n");
+                               }
+                       } else {
+                               fill_prefetch_next_after(
+                                       "\t\tuae_s16 bnewv = (uae_s16)dst + (uae_s16)src;\n"
+                                       "\t\tint bflgs = ((uae_s16)(src)) < 0;\n"
+                                       "\t\tint bflgo = ((uae_s16)(dst)) < 0;\n"
+                                       "\t\tint bflgn = bnewv < 0;\n"
+                                       "\t\tccr_68000_long_move_ae_LZN(bnewv);\n"
+                                       "\t\tSET_CFLG(((uae_u16)(~dst)) < ((uae_u16)(src)));\n"
+                                       "\t\tSET_XFLG(GET_CFLG());\n"
+                                       "\t\tSET_VFLG((bflgs ^ bflgn) & (bflgo ^ bflgn));\n");
+                       }
+                       if (c > 0)
+                               addcycles000(c);
+                       genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst");
+               } else {
+                       if (curi->dmode == Dreg) {
+                               genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst");
+                       }
+                       if ((curi->smode >= imm || curi->smode == Dreg) && curi->dmode != Dreg) {
+                               fill_prefetch_next_after(NULL);
+                       } else {
+                               fill_prefetch_next();
+                       }
+                       if (c > 0)
+                               addcycles000(c);
+                       if (curi->dmode != Dreg) {
+                               genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst");
                        }
                }
-               fill_prefetch_next ();
-               if (c > 0)
-                       addcycles000 (c);
-               start_brace ();
-               genflags (flag_add, curi->size, "newv", "src", "dst");
-               genastore_rev ("newv", curi->dmode, "dstreg", curi->size, "dst");
                break;
        }
        case i_ADDA:
@@ -4395,8 +4446,7 @@ static void gen_opcode (unsigned int opcode)
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "src", 1, 0,
                        curi->dmode, "dstreg", sz_long, "dst", 1, GF_RMW);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               //genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW);
+               printf("\tuae_u32 newv = dst + src;\n");
                if (curi->smode == immi) {
                        // ADDAQ.x is always 8 cycles
                        c += 4;
@@ -4405,12 +4455,10 @@ static void gen_opcode (unsigned int opcode)
                        if (islongimm (curi))
                                c += 2;
                }
-               fill_prefetch_next ();
+               fill_prefetch_next_after("\t\tareg_68000_long_replace_low(dstreg, newv);\n");
                if (c > 0)
                        addcycles000 (c);
-               start_brace ();
-               printf("\tuae_u32 newv = dst + src;\n");
-               genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
+               genastore("newv", curi->dmode, "dstreg", sz_long, "dst");
                break;
        }
        case i_ADDX:
@@ -4443,7 +4491,7 @@ static void gen_opcode (unsigned int opcode)
                                        "\t\tSET_XFLG(GET_CFLG());\n"
                                        "\t\tif (newv & 0xffff) SET_ZFLG(0);\n"
                                        "\t\tSET_NFLG(newv & 0x8000); \n"
-                                       "\t\treg_68000_long_replace_low(dstreg, newv);\n");
+                                       "\t\tdreg_68000_long_replace_low(dstreg, newv);\n");
                        } else {
                                fill_prefetch_next();
                        }
@@ -4498,17 +4546,35 @@ static void gen_opcode (unsigned int opcode)
                genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
                genflags(flag_sub, curi->size, "dst", "src", "0");
                if (curi->smode == Dreg) {
-                       genastore_rev("dst", curi->smode, "srcreg", curi->size, "src");
                        if (curi->size == sz_long) {
                                // prefetch bus error and long register: only low word is updated
                                // N flag from high word. Z both.
-                               fill_prefetch_next_after("\t\treg_68000_long_replace_low(srcreg, dst);\n\t\tSET_VFLG(0);SET_ZFLG(!dst);SET_NFLG(dst & 0x80000000);SET_CFLG(!GET_ZFLG());SET_XFLG(GET_CFLG());\n");
+                               fill_prefetch_next_after(
+                                       "\t\tdreg_68000_long_replace_low(srcreg, dst);\n"
+                                       "\t\tint bflgs = ((uae_s16)(src)) < 0;\n"
+                                       "\t\tint bflgo = ((uae_s16)(0)) < 0;\n"
+                                       "\t\tint bflgn = ((uae_s16)(dst)) < 0;\n"
+                                       "\t\tSET_ZFLG(((uae_s16)(dst)) == 0);\n"
+                                       "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgn ^ bflgo));\n"
+                                       "\t\tSET_CFLG(((uae_u16)(src)) > ((uae_u16)(0)));\n"
+                                       "\t\tSET_NFLG(dst & 0x80000000);\n"
+                                       "\t\tSET_XFLG(GET_CFLG());\n");
+                               genastore_rev("dst", curi->smode, "srcreg", curi->size, "src");
                        } else {
+                               genastore_rev("dst", curi->smode, "srcreg", curi->size, "src");
                                fill_prefetch_next();
                        }
                } else if (curi->size == sz_long) {
                        // prefetch bus error and long memory: only low word CCR decoded
-                       fill_prefetch_next_after("\t\tSET_VFLG(0);SET_ZFLG(!(dst & 0xffff));SET_NFLG(dst & 0x8000);SET_CFLG(!GET_ZFLG());SET_XFLG(GET_CFLG());\n");
+                       fill_prefetch_next_after(
+                               "\t\tint bflgs = ((uae_s16)(src)) < 0;\n"
+                               "\t\tint bflgo = ((uae_s16)(0)) < 0;\n"
+                               "\t\tint bflgn = ((uae_s16)(dst)) < 0;\n"
+                               "\t\tSET_ZFLG(((uae_s16)(dst)) == 0);\n"
+                               "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgn ^ bflgo));\n"
+                               "\t\tSET_CFLG(((uae_u16)(src)) > ((uae_u16)(0)));\n"
+                               "\t\tSET_NFLG(bflgn != 0);\n"
+                               "\t\tSET_XFLG(GET_CFLG());\n");
                } else {
                        fill_prefetch_next_after(NULL);
                }
@@ -4524,17 +4590,35 @@ static void gen_opcode (unsigned int opcode)
                genflags(flag_subx, curi->size, "newv", "src", "0");
                genflags(flag_zn, curi->size, "newv", "", "");
                if (curi->smode == Dreg) {
-                       genastore_rev("newv", curi->smode, "srcreg", curi->size, "src");
                        if (curi->size == sz_long) {
                                // prefetch bus error and long register: only low word is updated
                                // N flag from high word. Z both.
-                               fill_prefetch_next_after("\t\treg_68000_long_replace_low(srcreg, newv);\n\t\tSET_VFLG(0);SET_ZFLG(!newv);SET_NFLG(newv & 0x80000000);SET_CFLG(!GET_ZFLG());SET_XFLG(GET_CFLG());\n");
+                               fill_prefetch_next_after(
+                                       "\t\tdreg_68000_long_replace_low(srcreg, newv);\n"
+                                       "\t\tint bflgs = ((uae_s16)(src)) < 0;\n"
+                                       "\t\tint bflgo = ((uae_s16)(0)) < 0;\n"
+                                       "\t\tint bflgn = ((uae_s16)(newv)) < 0;\n"
+                                       "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgo ^ bflgn));\n"
+                                       "\t\tSET_CFLG(bflgs ^ ((bflgs ^ bflgn) & (bflgo ^ bflgn)));\n"
+                                       "\t\tSET_ZFLG(GET_ZFLG() & (((uae_s16)(newv)) == 0));\n"
+                                       "\t\tSET_NFLG(((uae_s32)(newv)) < 0);\n"
+                                       "\t\tSET_XFLG(GET_CFLG());\n");
+                               genastore_rev("newv", curi->smode, "srcreg", curi->size, "src");
                        } else {
+                               genastore_rev("newv", curi->smode, "srcreg", curi->size, "src");
                                fill_prefetch_next();
                        }
                } else if (curi->size == sz_long) {
                        // prefetch bus error and long memory: only low word CCR decoded
-                       fill_prefetch_next_after("\t\tSET_VFLG(0);SET_ZFLG(!(newv & 0xffff));SET_NFLG(newv & 0x8000);SET_CFLG(!GET_ZFLG());SET_XFLG(GET_CFLG());\n");
+                       fill_prefetch_next_after(
+                               "\t\tint bflgs = ((uae_s16)(src)) < 0;\n"
+                               "\t\tint bflgo = ((uae_s16)(0)) < 0;\n"
+                               "\t\tint bflgn = ((uae_s16)(newv)) < 0;\n"
+                               "\t\tSET_VFLG((bflgs ^ bflgo) & (bflgo ^ bflgn));\n"
+                               "\t\tSET_CFLG(bflgs ^ ((bflgs ^ bflgn) & (bflgo ^ bflgn)));\n"
+                               "\t\tSET_ZFLG(GET_ZFLG() & (((uae_s16)(newv)) == 0));\n"
+                               "\t\tSET_NFLG(((uae_s16)(newv)) < 0);\n"
+                               "\t\tSET_XFLG(GET_CFLG());\n");
                } else {
                        fill_prefetch_next_after(NULL);
                }
@@ -4585,12 +4669,15 @@ static void gen_opcode (unsigned int opcode)
                        genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                        genflags(flag_logical, curi->size, "0", "", "");
                        if (curi->smode == Dreg) {
-                               genastore_rev("0", curi->smode, "srcreg", curi->size, "src");
                                if (curi->size == sz_long) {
                                        // prefetch bus error and long register: only low word is updated
                                        // N flag from high word. Z both.
-                                       fill_prefetch_next_after("\t\tm68k_dreg(regs, srcreg) = (src & 0xffff0000);\n\t\tSET_VFLG(0);SET_ZFLG(1);SET_NFLG(0);SET_CFLG(0);\n");
+                                       fill_prefetch_next_after(
+                                               "\t\tm68k_dreg(regs, srcreg) = (src & 0xffff0000);\n"
+                                               "\t\tSET_VFLG(0);SET_ZFLG(1);SET_NFLG(0);SET_CFLG(0);\n");
+                                       genastore_rev("0", curi->smode, "srcreg", curi->size, "src");
                                } else {
+                                       genastore_rev("0", curi->smode, "srcreg", curi->size, "src");
                                        fill_prefetch_next();
                                }
                        } else if (curi->size == sz_long) {
@@ -4632,17 +4719,26 @@ static void gen_opcode (unsigned int opcode)
                printf("\tuae_u32 dst = ~src;\n");
                genflags(flag_logical, curi->size, "dst", "", "");
                if (curi->smode == Dreg) {
-                       genastore_rev("dst", curi->smode, "srcreg", curi->size, "src");
                        if (curi->size == sz_long) {
                                // prefetch bus error and long register: only low word is updated
                                // N flag from high word. Z both.
-                               fill_prefetch_next_after("\t\treg_68000_long_replace_low(srcreg, dst);\n\t\tSET_VFLG(0);SET_ZFLG(!dst);SET_NFLG(dst & 0x80000000);SET_CFLG(0);\n");
+                               fill_prefetch_next_after(
+                                       "\t\tdreg_68000_long_replace_low(srcreg, dst);\n"
+                                       "\t\tSET_VFLG(0);SET_ZFLG(!dst);\n"
+                                       "\t\tSET_NFLG(dst & 0x80000000);\n"
+                                       "\t\tSET_CFLG(0);\n");
+                               genastore_rev("dst", curi->smode, "srcreg", curi->size, "src");
                        } else {
+                               genastore_rev("dst", curi->smode, "srcreg", curi->size, "src");
                                fill_prefetch_next();
                        }
                } else if (curi->size == sz_long) {
                        // prefetch bus error and long memory: only low word CCR decoded
-                       fill_prefetch_next_after("\t\tSET_VFLG(0);SET_ZFLG(!(dst & 0xffff));SET_NFLG(dst & 0x8000);SET_CFLG(0);\n");
+                       fill_prefetch_next_after(
+                               "\t\tSET_VFLG(0);\n"
+                               "\t\tSET_ZFLG(!(dst & 0xffff));\n"
+                               "\t\tSET_NFLG(dst & 0x8000);\n"
+                               "\t\tSET_CFLG(0);\n");
                } else {
                        fill_prefetch_next_after(NULL);
                }
@@ -4691,6 +4787,10 @@ static void gen_opcode (unsigned int opcode)
                        curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW);
                if (curi->size == sz_long) {
                        fill_prefetch_next_after(NULL);
+               } else {
+                       if (curi->smode == Dreg || curi->smode >= imm) {
+                               fill_prefetch_next_after(NULL);
+                       }
                }
                bsetcycles(curi);
                // bclr needs 1 extra cycle
@@ -4707,7 +4807,9 @@ static void gen_opcode (unsigned int opcode)
                        printf("\tdst |= (1 << src);\n");
                }
                if (curi->size != sz_long) {
-                       fill_prefetch_next();
+                       if (curi->smode < imm && curi->smode != Dreg) {
+                               fill_prefetch_next();
+                       }
                }
                genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
                break;
@@ -4735,7 +4837,11 @@ static void gen_opcode (unsigned int opcode)
                        curi->smode, "srcreg", curi->size, "src", 1, 0,
                        curi->dmode, "dstreg", sz_long, "dst", 1, 0);
                genflags(flag_cmp, sz_long, "newv", "src", "dst");
-               fill_prefetch_next();
+               if (curi->dmode == Areg) {
+                       fill_prefetch_next_after(NULL);
+               } else {
+                       fill_prefetch_next();
+               }
                addcycles000(2);
                break;
                /* The next two are coded a little unconventional, but they are doing
@@ -4780,7 +4886,7 @@ static void gen_opcode (unsigned int opcode)
                        check_bus_error("memp", 2, 0, 0, NULL, 1);
 
                        // upper word gets updated after two bytes (makes only difference if bus error is possible)
-                       printf("\treg_68000_long_replace_low(dstreg, val);\n");
+                       printf("\tdreg_68000_long_replace_low(dstreg, val);\n");
 
                        printf("\tval |= (%s(mempa + 4) & 0xff) << 8;\n", srcb);
                        check_bus_error("memp", 4, 0, 0, NULL, 1 | 0x10000);
@@ -4897,9 +5003,24 @@ static void gen_opcode (unsigned int opcode)
                                if (curi->mnemo == i_MOVE) {
                                        if (curi->size == sz_long) {
                                                if (curi->smode == imm) {
+                                                       if (curi->dmode == absw) {
+                                                               strcpy(bus_error_code, "\t\tccr_68000_long_move_ae_LZN(src);\n");
+                                                       } else if (curi->dmode == absl) {
+                                                               strcpy(bus_error_code2, "\t\tccr_68000_long_move_ae_LZN(src);\n");
+                                                       }
+                                               } else if (curi->smode == Dreg || curi->smode == Areg) {
                                                        if (curi->dmode == absl) {
+                                                               strcpy(bus_error_code, "\t\t// nothing;\n");
+                                                               strcpy(bus_error_code2, "\t\tccr_68000_long_move_ae_LZN(src);\n");
+                                                       } else if (curi->dmode == absw) {
                                                                strcpy(bus_error_code, "\t\tccr_68000_long_move_ae_LZN(src);\n");
+                                                       }
+                                               } else {
+                                                       if (curi->dmode == absl) {
+                                                               strcpy(bus_error_code, "\t\t// nothing;\n");
                                                                strcpy(bus_error_code2, "\t\tccr_68000_long_move_ae_LZN(src);\n");
+                                                       } else {
+                                                               strcpy(bus_error_code, "\t\tccr_68000_long_move_ae_LZN(src);\n");
                                                        }
                                                }
                                        } else {
@@ -4926,13 +5047,19 @@ static void gen_opcode (unsigned int opcode)
                                if (curi->dmode == Apdi) {
                                        // -(an) decrease is not done if bus error
                                        if (curi->size == sz_long) {
-                                               fill_prefetch_next_after("\t\tm68k_areg(regs, dstreg) += 4;\n");
+                                               fill_prefetch_next_after(
+                                                       "\t\tm68k_areg(regs, dstreg) += 4;\n"
+                                                       "\t\tccr_68000_long_move_ae_LZN(src);\n"
+                                               );
                                        } else {
                                                // x,-(an): flags are set before prefetch detects possible bus error
                                                if (curi->mnemo == i_MOVE) {
-                                                       fill_prefetch_next_after("\t\tm68k_areg(regs, dstreg) += 2;\n\t\tccr_68000_word_move_ae_normal((uae_s16)src);");
+                                                       fill_prefetch_next_after(
+                                                               "\t\tm68k_areg(regs, dstreg) += 2;\n"
+                                                               "\t\tccr_68000_word_move_ae_normal((uae_s16)src);");
                                                } else {
-                                                       fill_prefetch_next_after("\t\tm68k_areg(regs, dstreg) += 2;\n");
+                                                       fill_prefetch_next_after(
+                                                               "\t\tm68k_areg(regs, dstreg) += 2;\n");
                                                }
                                        }
                                        prefetch_done = 1;
@@ -4950,6 +5077,9 @@ static void gen_opcode (unsigned int opcode)
                                        }
                                }
 
+                               bus_error_code[0] = 0;
+                               bus_error_code2[0] = 0;
+
                                if (curi->size == sz_long) {
                                        if ((curi->dmode == Ad16 || curi->dmode == PC16) && curi->smode == imm) {
                                                // lots more needed..
@@ -5011,7 +5141,7 @@ static void gen_opcode (unsigned int opcode)
                if (curi->size == sz_byte) {
                        // MOVE TO CCR
                        addcycles000 (4);
-                       printf("\tMakeSR ();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
+                       printf("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
                } else {
                        // MOVE TO SR
                        check_trace();
@@ -5094,14 +5224,9 @@ static void gen_opcode (unsigned int opcode)
                fill_prefetch_next();
                break;
        case i_RESET:
-               fill_prefetch_next ();
-               printf("\tcpureset ();\n");
-               sync_m68k_pc ();
-               addcycles000 (128);
-               if (using_prefetch) {
-                       printf("\t%s(2);\n", prefetch_word);
-                       clear_m68k_offset();
-               }
+               printf("\tcpureset();\n");
+               addcycles000(128);
+               fill_prefetch_next();
                break;
        case i_NOP:
                fill_prefetch_next();
@@ -5208,7 +5333,7 @@ static void gen_opcode (unsigned int opcode)
                        printf("\t\t\tException_cpu(14);\n");
                        printf("\t\t\tgoto %s; \n", endlabelstr);
                        printf("\t\t}\n");
-                       printf("\t\tregs.sr = newsr; MakeFromSR ();\n}\n");
+                       printf("\t\tregs.sr = newsr; MakeFromSR();\n}\n");
                    pop_braces (old_brace_level);
                    printf("\tregs.sr = newsr;\n");
                        makefromsr();
@@ -5463,7 +5588,14 @@ static void gen_opcode (unsigned int opcode)
                break;
        case i_TRAPV:
                sync_m68k_pc();
-               fill_prefetch_next_noopcodecopy("\t\tif (GET_VFLG()) { ; } else opcode = regs.ir;\n");
+               // If V is set but prefetch causes bus error: S is set.
+               fill_prefetch_next_after(
+                       "\t\tif (GET_VFLG()) {\n"
+                       "\t\t\tregs.sr |= 0x2000;\n"
+                       "\t\t\tMakeFromSR();\n"
+                       "\t\t} else {\n"
+                       "\t\t\topcode = regs.ir;\n"
+                       "\t\t}\n");
                printf("\tif (GET_VFLG()) {\n");
                printf("\t\tException_cpu(7);\n");
                printf("\t\tgoto %s;\n", endlabelstr);
@@ -5472,7 +5604,7 @@ static void gen_opcode (unsigned int opcode)
                break;
        case i_RTR:
                printf("\tuaecptr oldpc = %s;\n", getpc);
-               printf("\tMakeSR ();\n");
+               printf("\tMakeSR();\n");
                genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, 0);
                genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, 0);
                if (cpu_level >= 4) {
@@ -5790,15 +5922,19 @@ bccl_not68020:
        case i_LEA:
                if (curi->smode == Ad8r || curi->smode == PC8r)
                        addcycles000 (2);
+               if (curi->smode == absl) {
+                       strcpy(bus_error_code, "\t\tm68k_areg(regs, dstreg) = (m68k_areg(regs, dstreg) & 0x0000ffff) | (srca & 0xffff0000);\n");
+                       strcpy(bus_error_code2, "\t\tm68k_areg(regs, dstreg) = (srca);\n");
+               }  else if (curi->smode != Ad8r && curi->smode != PC8r) {
+                       strcpy(bus_error_code, "\t\tm68k_areg(regs, dstreg) = (srca);\n");
+               }
                genamodedual (curi,
                        curi->smode, "srcreg", curi->size, "src", 0, GF_AA,
                        curi->dmode, "dstreg", curi->size, "dst", 2, GF_AA);
-               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
-               //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA);
                if (curi->smode == Ad8r || curi->smode == PC8r)
                        addcycles000 (2);
+               genastore("srca", curi->dmode, "dstreg", curi->size, "dst");
                fill_prefetch_next ();
-               genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
                break;
        case i_PEA:
                if (curi->smode == Ad8r || curi->smode == PC8r)
@@ -5927,7 +6063,6 @@ bccl_not68020:
                        addcycles000_3("\t\t");
                }
                addcycles000_nonces("\t\t", "(getDivu68kCycles((uae_u32)dst, (uae_u16)src)) - 4");
-               fill_prefetch_next();
                printf("\t\tif (newv > 0xffff) {\n");
                printf("\t\t\tsetdivuflags((uae_u32)dst, (uae_u16)src);\n");
                printf("\t\t} else {\n");
@@ -5937,6 +6072,7 @@ bccl_not68020:
                printf("\t\t");
                genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
                printf("\t\t}\n");
+               fill_prefetch_next();
                sync_m68k_pc();
                count_ncycles++;
                insn_n_cycles += 136 - (136 - 76) / 2; /* average */
@@ -5961,7 +6097,6 @@ bccl_not68020:
                        addcycles000_3("\t\t");
                }
                addcycles000_nonces("\t\t", "(getDivs68kCycles((uae_s32)dst, (uae_s16)src)) - 4");
-               fill_prefetch_next ();
                printf("\tif (dst == 0x80000000 && src == -1) {\n");
                printf("\t\tsetdivsflags((uae_s32)dst, (uae_s16)src);\n");
                printf("\t} else {\n");
@@ -5977,6 +6112,7 @@ bccl_not68020:
                genastore("newv", curi->dmode, "dstreg", sz_long, "dst");
                printf("\t\t}\n");
                printf("\t}\n");
+               fill_prefetch_next();
                sync_m68k_pc();
                count_ncycles++;
                insn_n_cycles += 156 - (156 - 120) / 2; /* average */
@@ -5988,8 +6124,10 @@ bccl_not68020:
                genamodedual (curi,
                        curi->smode, "srcreg", sz_word, "src", 1, 0,
                        curi->dmode, "dstreg", sz_word, "dst", 1, 0);
-               fill_prefetch_next();
-               start_brace ();
+               fill_prefetch_next_after(
+                       "\t\tCLEAR_CZNV();\n"
+                       "\t\tSET_ZFLG(1);\n"
+                       "\t\tm68k_dreg(regs, dstreg) &= 0xffff0000;\n");
                printf("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n");
                if (using_ce)
                        printf("\tint cycles = 38 - 4, bits;\n");
@@ -6012,8 +6150,10 @@ bccl_not68020:
                genamodedual (curi,
                        curi->smode, "srcreg", sz_word, "src", 1, 0,
                        curi->dmode, "dstreg", sz_word, "dst", 1, 0);
-               fill_prefetch_next();
-               start_brace ();
+               fill_prefetch_next_after(
+                       "\t\tCLEAR_CZNV();\n"
+                       "\t\tSET_ZFLG(1);\n"
+                       "\t\tm68k_dreg(regs, dstreg) &= 0xffff0000;\n");
                printf("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n");
                if (using_ce) {
                        printf("\tint cycles = 38 - 4, bits;\n");
index 47cd11b1f7009598ea2e61a80d2f116aaeb14ace..318b4fa3ab2fdc90a5e837d0225c6823b247f98a 100644 (file)
@@ -702,7 +702,8 @@ void ccr_68000_long_move_ae_LN(uae_s32 src);
 void ccr_68000_long_move_ae_HNZ(uae_s32 src);
 void ccr_68000_long_move_ae_normal(uae_s32 src);
 void ccr_68000_word_move_ae_normal(uae_s16 src);
-void reg_68000_long_replace_low(int reg, uae_u16 v);
+void dreg_68000_long_replace_low(int reg, uae_u16 v);
+void areg_68000_long_replace_low(int reg, uae_u16 v);
 
 extern void mmu_op (uae_u32, uae_u32);
 extern bool mmu_op30 (uaecptr, uae_u32, uae_u16, uaecptr);
index 0a10a80dea07043b128bba7352f46830ebea13b8..83a3d9dcf9a9b5d6e50aae7838c5d453a643304f 100644 (file)
@@ -1618,11 +1618,16 @@ void ccr_68000_word_move_ae_normal(uae_s16 src)
        SET_NFLG(src < 0);
 }
 
-void reg_68000_long_replace_low(int reg, uae_u16 v)
+void dreg_68000_long_replace_low(int reg, uae_u16 v)
 {
        m68k_dreg(regs, reg) = (m68k_dreg(regs, reg) & 0xffff0000) | v;
 }
 
+void areg_68000_long_replace_low(int reg, uae_u16 v)
+{
+       m68k_areg(regs, reg) = (m68k_areg(regs, reg) & 0xffff0000) | v;
+}
+
 // Change F-line to privilege violation if missing co-pro
 bool privileged_copro_instruction(uae_u16 opcode)
 {