]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
MOVE complete bus error emulation.
authorToni Wilen <twilen@winuae.net>
Sun, 13 Oct 2019 12:55:54 +0000 (15:55 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 13 Oct 2019 12:55:54 +0000 (15:55 +0300)
cputest.cpp
cputest/asm.S
cputest/main.c
debug.cpp
disasm.cpp
gencpu.cpp
newcpu_common.cpp

index 3add91841a2a240b634abff08f41be61e8eb1eb8..7800d42a4925ff6b6708db9a98dfe0f0573ff064 100644 (file)
@@ -315,7 +315,7 @@ void put_byte_test(uaecptr addr, uae_u32 v)
 {
        check_bus_error(addr, 1, regs.s ? 5 : 1);
        uae_u8 *p = get_addr(addr, 1, 1);
-       if (!out_of_test_space && !noaccesshistory) {
+       if (!out_of_test_space && !noaccesshistory && !cpu_bus_error) {
                previoussame(addr, sz_byte);
                if (ahcnt >= MAX_ACCESSHIST) {
                        wprintf(_T("ahist overflow!"));
@@ -337,7 +337,7 @@ void put_word_test(uaecptr addr, uae_u32 v)
                put_byte_test(addr + 1, v >> 0);
        } else {
                uae_u8 *p = get_addr(addr, 2, 1);
-               if (!out_of_test_space && !noaccesshistory) {
+               if (!out_of_test_space && !noaccesshistory && !cpu_bus_error) {
                        previoussame(addr, sz_word);
                        if (ahcnt >= MAX_ACCESSHIST) {
                                wprintf(_T("ahist overflow!"));
@@ -365,7 +365,7 @@ void put_long_test(uaecptr addr, uae_u32 v)
                put_word_test(addr + 2, v >> 0);
        } else {
                uae_u8 *p = get_addr(addr, 4, 1);
-               if (!out_of_test_space && !noaccesshistory) {
+               if (!out_of_test_space && !noaccesshistory && !cpu_bus_error) {
                        previoussame(addr, sz_long);
                        if (ahcnt >= MAX_ACCESSHIST) {
                                wprintf(_T("ahist overflow!"));
@@ -2832,6 +2832,15 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                abort();
                                        }
 
+                                       if ((dflags & 1) && target_ea[0] == 0xffffffff && (srcaddr & addressing_mask) >= safe_memory_start - 4 && (srcaddr & addressing_mask) < safe_memory_end + 4) {
+                                               // random generated EA must never be inside safe memory
+                                               continue;
+                                       }
+                                       if ((dflags & 2) && target_ea[1] == 0xffffffff && (dstaddr & addressing_mask) >= safe_memory_start - 4 && (dstaddr & addressing_mask) < safe_memory_end + 4) {
+                                               // random generated EA must never be inside safe memory
+                                               continue;
+                                       }
+
 #if 0
                                        // can't test because dp may be empty if instruction is invalid
                                        if (nextpc != pc - 2) {
index 9f6430870a183ac829099f662a07fadf1ed17add..85ee63e57f5fa6abb98e4d3e5b9a412da3567bdd 100644 (file)
@@ -16,6 +16,7 @@
        .globl _msp_address2
        .globl _msp_address3
        .globl _msp_address4
+       .globl _error_vector
 
 | must match main.c
 S_DREG = 0
@@ -257,6 +258,7 @@ _exceptiontable000:
        bsr.s exception | 47
        nop
 exception:
+       move.w #0,ACTIVITYREG
        move.l a0,-(sp)
        move.l datapointer(pc),a0
        movem.l d0-d7/a0-a6,(a0)
@@ -283,12 +285,14 @@ exception:
        move.l USP,a1
        move.l a1,S_AREG+7*4(a0)
 
+       move.w #0x222,ACTIVITYREG
        move.l superstack(pc),sp
        move.w (sp)+,sr
        movem.l (sp)+,d1-d7/a0-a6
        rts
 
 _exception010:
+       move.w #0,ACTIVITYREG
        move.l a0,-(sp)
        move.l datapointer(pc),a0
        movem.l d0-d7/a0-a6,(a0)
@@ -305,12 +309,14 @@ _exception010:
        move.l USP,a1
        move.l a1,S_AREG+7*4(a0)
                
+       move.w #0x222,ACTIVITYREG
        move.l superstack(pc),sp
        move.w (sp)+,sr
        movem.l (sp)+,d1-d7/a0-a6
        rts
        
 _exception020:
+       move.w #0,ACTIVITYREG
        move.l a0,-(sp)
        move.l datapointer(pc),a0
        movem.l d0-d7/a0-a6,(a0)
@@ -331,6 +337,7 @@ _msp_address3:
        move.l USP,a1
        move.l a1,S_AREG+7*4(a0)
                
+       move.w #0x222,ACTIVITYREG
        | restore SR first, then stack
        | M-bit may have been set.
        move.l superstack(pc),a0
@@ -340,6 +347,7 @@ _msp_address3:
        rts
 
 _exceptionfpu:
+       move.w #0,ACTIVITYREG
        move.l a0,-(sp)
        move.l datapointer(pc),a0
        movem.l d0-d7/a0-a6,(a0)
@@ -366,12 +374,20 @@ _msp_address4:
        fmove.l fpcr,(a1)+
        fmove.l fpsr,(a1)+
                
+       move.w #0x222,ACTIVITYREG
        move.l superstack(pc),a0
        move.w (a0)+,sr
        move.l a0,sp
        movem.l (sp)+,d1-d7/a0-a6
        rts
 
+_error_vector:
+       or.w #0x700,sr
+waiterr:
+       move.w #0x400,ACTIVITYREG
+       move.w #0x004,ACTIVITYREG
+       bra.s waiterr
+
 datapointer:
        dc.l 0
 superstack:
index 9e394688e3d8f65818241848a00fbf781f47a4c4..1f92d8a7a9a4f6ddc79679ae4e4e3fcd9891836c 100644 (file)
@@ -164,6 +164,7 @@ static void setcpu(uae_u32 v, uae_u32 *s, uae_u32 *d)
 static void flushcache(uae_u32 v)
 {
 }
+static void *error_vector;
 #else
 
 static void xmemcpy(void *d, void *s, int size)
@@ -185,6 +186,7 @@ extern uae_u32 setvbr(uae_u32);
 extern uae_u32 get_cpu_model(void);
 extern void setcpu(uae_u32, uae_u32*, uae_u32*);
 extern void flushcache(uae_u32);
+extern void *error_vector;
 
 #endif
 
@@ -249,6 +251,35 @@ static void safe_memcpy(uae_u8 *d, uae_u8 *s, int size)
 
 static int test_active;
 static uae_u32 enable_data;
+static uae_u32 error_vectors[12];
+
+// if exception happens outside of test code, jump to
+// infinite loop and flash colors.
+static void reset_error_vectors(void)
+{
+       uae_u32 *p;
+       if (cpu_lvl == 0) {
+               p = (uae_u32*)vbr_zero;
+       } else {
+               p = vbr;
+       }
+       for (int i = 2; i < 4; i++) {
+               p[i] = error_vectors[i - 2];
+       }
+}
+
+static void set_error_vectors(void)
+{
+       uae_u32 *p;
+       if (cpu_lvl == 0) {
+               p = (uae_u32 *)vbr_zero;
+       } else {
+               p = vbr;
+       }
+       for (int i = 2; i < 4; i++) {
+               p[i] = (uae_u32)&error_vector;
+       }
+}
 
 static void start_test(void)
 {
@@ -293,6 +324,9 @@ static void start_test(void)
                uae_u32 *p = (uae_u32 *)vbr_zero;
                for (int i = 2; i < 12; i++) {
                        p[i] = (uae_u32)(((uae_u32)&exceptiontable000) + (i - 2) * 2);
+                       if (i < 12 + 2) {
+                               error_vectors[i - 2] = p[i];
+                       }
                }
                for (int i = 32; i < 48; i++) {
                        p[i] = (uae_u32)(((uae_u32)&exceptiontable000) + (i - 2) * 2);
@@ -301,6 +335,9 @@ static void start_test(void)
                oldvbr = setvbr((uae_u32)vbr);
                for (int i = 0; i < 256; i++) {
                        vbr[i] = fpu_model ? (uae_u32)(&exceptionfpu) : (cpu_lvl == 1 ? (uae_u32)(&exception010) : (uae_u32)(&exception020));
+                       if (i >= 2 && i < 12) {
+                               error_vectors[i - 2] = vbr[i];
+                       }
                }
        }
        setcpu(cpu_lvl, cpustatearraynew, cpustatearraystore);
@@ -929,7 +966,7 @@ static void out_regs(struct registers *r, int before)
                                strcat(outbp, " ");
                        }
                        outbp += strlen(outbp);
-                       sprintf(outbp, "%c%d:%c%08lx", i < 8 ? 'D' : 'A', i & 7, test_regs.regs[i] != regs.regs[i] ? '*' : ' ', r->regs[i]);
+                       sprintf(outbp, "%c%d:%c%08lx", i < 8 ? 'D' : 'A', i & 7, test_regs.regs[i] != last_registers.regs[i] ? '*' : ' ', r->regs[i]);
                        outbp += strlen(outbp);
                }
                *outbp++ = '\n';
@@ -950,7 +987,7 @@ static void out_regs(struct registers *r, int before)
                                        int idx = i * 4 + j;
                                        if (j > 0)
                                                *outbp++ = ' ';
-                                       sprintf(outbp, "%c%d:%c%08lx", idx < 8 ? 'D' : 'A', idx & 7, test_regs.regs[idx] != regs.regs[idx] ? '*' : ' ', r->regs[idx]);
+                                       sprintf(outbp, "%c%d:%c%08lx", idx < 8 ? 'D' : 'A', idx & 7, test_regs.regs[idx] != last_registers.regs[idx] ? '*' : ' ', regs.regs[idx]);
                                        outbp += strlen(outbp);
                                }
                        }
@@ -1126,7 +1163,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
        if (exclen == 0 || !sameexc)
                return p;
        if (memcmp(exc, sp, exclen)) {
-               strcpy(outbp, "Exception stack frame mismatch:\n");
+               sprintf(outbp, "Exception %ld stack frame mismatch:\n", excnum);
                outbp += strlen(outbp);
                strcpy(outbp, "Expected: ");
                outbp += strlen(outbp);
@@ -1607,6 +1644,8 @@ static void process_test(uae_u8 *p)
 
                                        if ((ccr_mask & ccr) || (ccr == 0)) {
 
+                                               reset_error_vectors();
+
                                                if (cpu_lvl == 1) {
                                                        execute_test010(&test_regs);
                                                } else if (cpu_lvl >= 2) {
@@ -1621,6 +1660,8 @@ static void process_test(uae_u8 *p)
                                                if (ccr_mask == 0 && ccr == 0)
                                                        ignore_sr = 1;
 
+                                               set_error_vectors();
+
                                        } else {
 
                                                test_regs.sr = test_sr;
@@ -1970,6 +2011,8 @@ int main(int argc, char *argv[])
                                ccr_mask = ~getparamval(next);
                                i++;
                        }
+               } else if (!_stricmp(s, "silent")) {
+                       dooutput = 0;
                } else if (!_stricmp(s, "68000")) {
                        cpu_lvl = 0;
                } else if (!_stricmp(s, "68010")) {
index 373fe2a2ed213067157a38072439e3fc7a70832c..8a50b7daad9adb642d50e69480e9ed9609c0f520 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -3003,7 +3003,11 @@ static int memwatch_func (uaecptr addr, int rwi, int size, uae_u32 *valp, uae_u3
                        continue;
 
                if (m->bus_error) {
+#if BUS_ERROR_EMULATION
+                       cpu_bus_error = 1;
+#else
                        exception2(addr, (rwi & 2) == 0, size, ((rwi & 4) ? 2 : 1) | (regs.s ? 4 : 0));
+#endif
                        continue;
                }
 
index b891d97fa3ef45d5c7d7dc81c3a94a0992600d52..bd72d41cc291a1ab514fe221b8132d9e30379972 100644 (file)
@@ -176,10 +176,6 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name
                dispreg = (uae_s32)(uae_s16)(dispreg);
        }
 
-       if (currprefs.cpu_model >= 68020) {
-               dispreg <<= (dp >> 9) & 3; // SCALE
-       }
-
        int m = 1 << ((dp >> 9) & 3);
        mult[0] = 0;
        if (m > 1 && buffer) {
@@ -190,8 +186,11 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name
                buffer[0] = 0;
        if ((dp & 0x100) && currprefs.cpu_model >= 68020) {
                TCHAR dr[20];
-               // Full format extension (68020+)
                uae_s32 outer = 0, disp = 0;
+
+               // Full format extension (68020+)
+
+               dispreg <<= (dp >> 9) & 3; // SCALE
                if (dp & 0x80) { // BS (base register suppress)
                        base = 0;
                        if (buffer)
index 88054bee9ead66f137a0ada83edf5e7465ca856f..975a96a45348c21ff0f43ca65490ecf501206cf6 100644 (file)
@@ -75,6 +75,14 @@ static int optimized_flags;
 #define GF_OPCE020 2048
 #define GF_REVERSE 4096
 #define GF_REVERSE2 8192
+#define GF_SECONDWORDSETFLAGS 16384
+
+typedef enum
+{
+       flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_z, flag_zn,
+       flag_av, flag_sv
+}
+flagtypes;
 
 /* For the current opcode, the next lower level that will have different code.
 * Initialized to -1 for each opcode. If it remains unchanged, indicates we
@@ -997,6 +1005,385 @@ static void clearmmufixup (int cnt)
        }
 }
 
+
+static void duplicate_carry(int n)
+{
+       int i;
+       for (i = 0; i <= n; i++)
+               printf("\t");
+       printf("COPY_CARRY ();\n");
+}
+
+static void genflags_normal(flagtypes type, wordsizes size, const char *value, const char *src, const char *dst)
+{
+       char vstr[100], sstr[100], dstr[100];
+       char usstr[100], udstr[100];
+       char unsstr[100], undstr[100];
+
+       switch (size) {
+       case sz_byte:
+               strcpy(vstr, "((uae_s8)(");
+               strcpy(usstr, "((uae_u8)(");
+               break;
+       case sz_word:
+               strcpy(vstr, "((uae_s16)(");
+               strcpy(usstr, "((uae_u16)(");
+               break;
+       case sz_long:
+               strcpy(vstr, "((uae_s32)(");
+               strcpy(usstr, "((uae_u32)(");
+               break;
+       default:
+               term();
+       }
+       strcpy(unsstr, usstr);
+
+       strcpy(sstr, vstr);
+       strcpy(dstr, vstr);
+       strcat(vstr, value);
+       strcat(vstr, "))");
+       strcat(dstr, dst);
+       strcat(dstr, "))");
+       strcat(sstr, src);
+       strcat(sstr, "))");
+
+       strcpy(udstr, usstr);
+       strcat(udstr, dst);
+       strcat(udstr, "))");
+       strcat(usstr, src);
+       strcat(usstr, "))");
+
+       strcpy(undstr, unsstr);
+       strcat(unsstr, "-");
+       strcat(undstr, "~");
+       strcat(undstr, dst);
+       strcat(undstr, "))");
+       strcat(unsstr, src);
+       strcat(unsstr, "))");
+
+       switch (type) {
+       case flag_logical_noclobber:
+       case flag_logical:
+       case flag_z:
+       case flag_zn:
+       case flag_av:
+       case flag_sv:
+       case flag_addx:
+       case flag_subx:
+               break;
+
+       case flag_add:
+               start_brace();
+               printf("uae_u32 %s = %s + %s;\n", value, udstr, usstr);
+               break;
+       case flag_sub:
+       case flag_cmp:
+               start_brace();
+               printf("uae_u32 %s = %s - %s;\n", value, udstr, usstr);
+               break;
+       }
+
+       switch (type) {
+       case flag_logical_noclobber:
+       case flag_logical:
+       case flag_zn:
+               break;
+
+       case flag_add:
+       case flag_sub:
+       case flag_addx:
+       case flag_subx:
+       case flag_cmp:
+       case flag_av:
+       case flag_sv:
+               start_brace();
+               printf("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr);
+               printf("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr);
+               printf("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr);
+               break;
+       }
+
+       switch (type) {
+       case flag_logical:
+               printf("\tCLEAR_CZNV ();\n");
+               printf("\tSET_ZFLG (%s == 0);\n", vstr);
+               printf("\tSET_NFLG (%s < 0);\n", vstr);
+               break;
+       case flag_logical_noclobber:
+               printf("\tSET_ZFLG (%s == 0);\n", vstr);
+               printf("\tSET_NFLG (%s < 0);\n", vstr);
+               break;
+       case flag_av:
+               printf("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
+               break;
+       case flag_sv:
+               printf("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
+               break;
+       case flag_z:
+               printf("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr);
+               break;
+       case flag_zn:
+               printf("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr);
+               printf("\tSET_NFLG (%s < 0);\n", vstr);
+               break;
+       case flag_add:
+               printf("\tSET_ZFLG (%s == 0);\n", vstr);
+               printf("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
+               printf("\tSET_CFLG (%s < %s);\n", undstr, usstr);
+               duplicate_carry(0);
+               printf("\tSET_NFLG (flgn != 0);\n");
+               break;
+       case flag_sub:
+               printf("\tSET_ZFLG (%s == 0);\n", vstr);
+               printf("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
+               printf("\tSET_CFLG (%s > %s);\n", usstr, udstr);
+               duplicate_carry(0);
+               printf("\tSET_NFLG (flgn != 0);\n");
+               break;
+       case flag_addx:
+               printf("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0x42 */
+               printf("\tSET_CFLG (flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));\n"); /* minterm SON: 0xD4 */
+               duplicate_carry(0);
+               break;
+       case flag_subx:
+               printf("\tSET_VFLG ((flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0x24 */
+               printf("\tSET_CFLG (flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));\n"); /* minterm SON: 0xB2 */
+               duplicate_carry(0);
+               break;
+       case flag_cmp:
+               printf("\tSET_ZFLG (%s == 0);\n", vstr);
+               printf("\tSET_VFLG ((flgs != flgo) && (flgn != flgo));\n");
+               printf("\tSET_CFLG (%s > %s);\n", usstr, udstr);
+               printf("\tSET_NFLG (flgn != 0);\n");
+               break;
+       }
+}
+
+static void genflags(flagtypes type, wordsizes size, const char *value, const char *src, const char *dst)
+{
+       /* Temporarily deleted 68k/ARM flag optimizations.  I'd prefer to have
+       them in the appropriate m68k.h files and use just one copy of this
+       code here.  The API can be changed if necessary.  */
+       if (optimized_flags) {
+               switch (type) {
+               case flag_add:
+               case flag_sub:
+                       start_brace();
+                       printf("\tuae_u32 %s;\n", value);
+                       break;
+
+               default:
+                       break;
+               }
+
+               /* At least some of those casts are fairly important! */
+               switch (type) {
+               case flag_logical_noclobber:
+                       printf("\t{uae_u32 oldcznv = GET_CZNV & ~(FLAGVAL_Z | FLAGVAL_N);\n");
+                       if (strcmp(value, "0") == 0) {
+                               printf("\tSET_CZNV (olcznv | FLAGVAL_Z);\n");
+                       } else {
+                               switch (size) {
+                               case sz_byte: printf("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break;
+                               case sz_word: printf("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break;
+                               case sz_long: printf("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break;
+                               }
+                               printf("\tIOR_CZNV (oldcznv);\n");
+                       }
+                       printf("\t}\n");
+                       return;
+               case flag_logical:
+                       if (strcmp(value, "0") == 0) {
+                               printf("\tSET_CZNV (FLAGVAL_Z);\n");
+                       } else {
+                               switch (size) {
+                               case sz_byte: printf("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break;
+                               case sz_word: printf("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break;
+                               case sz_long: printf("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break;
+                               }
+                       }
+                       return;
+
+               case flag_add:
+                       switch (size) {
+                       case sz_byte: printf("\toptflag_addb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
+                       case sz_word: printf("\toptflag_addw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
+                       case sz_long: printf("\toptflag_addl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
+                       }
+                       return;
+
+               case flag_sub:
+                       switch (size) {
+                       case sz_byte: printf("\toptflag_subb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
+                       case sz_word: printf("\toptflag_subw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
+                       case sz_long: printf("\toptflag_subl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
+                       }
+                       return;
+
+               case flag_cmp:
+                       switch (size) {
+                       case sz_byte: printf("\toptflag_cmpb (regs, (uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break;
+                       case sz_word: printf("\toptflag_cmpw (regs, (uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break;
+                       case sz_long: printf("\toptflag_cmpl (regs, (uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break;
+                       }
+                       return;
+
+               default:
+                       break;
+               }
+       }
+
+       genflags_normal(type, size, value, src, dst);
+}
+
+// Handle special MOVE.W/.L condition codes when destination write causes bus error.
+static void move_68000_bus_error(int offset, int size, int *setapdi, int *fcmodeflags)
+{
+
+       int smode = g_instr->smode;
+       int dmode = g_instr->dmode;
+
+       if (size == sz_byte) {
+
+               if (dmode == Apdi) {
+
+                       // this is buggy, bus error stack frame opcode field contains next
+                       // instruction opcode and Instruction/Not field is one!
+                       printf("\t\topcode = regs.ir;\n");
+                       *fcmodeflags |= 0x08; // "Not instruction" = 1
+
+               } else if (dmode == Aipi) {
+
+                       // move.b x,(an)+: an is not increased
+                       printf("\t\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n");
+               }
+
+       } else if (size == sz_word) {
+
+               if (dmode == Apdi) {
+                       // this is buggy, bus error stack frame opcode field contains next
+                       // instruction opcode and Instruction/Not field is one!
+                       printf("\t\topcode = regs.ir;\n");
+                       *fcmodeflags |= 0x08; // "Not instruction" = 1
+               }
+
+       } else if (size == sz_long && ((offset == 0 && dmode != Apdi) || (offset == 2 && dmode == Apdi))) {
+
+               // Long MOVE is more complex but not as complex as address error..
+               // First word.
+
+               int set_ccr = 0;
+               int set_high_word = 0;
+               int set_low_word = 0;
+               switch (smode)
+               {
+               case Dreg:
+               case Areg:
+                       if (dmode == Ad16 || dmode == Ad8r) {
+                               set_high_word = 3;
+                       } else if (dmode == Apdi || dmode == absw || dmode == absl) {
+                               set_ccr = 1;
+                       }
+                       break;
+               case Aind:
+               case Aipi:
+               case Apdi:
+               case Ad16:
+               case Ad8r:
+               case PC16:
+               case PC8r:
+               case absl:
+               case absw:
+                       if (dmode == Aind || dmode == Aipi || dmode == absw || dmode == absl) {
+                               set_low_word = 1;
+                       } else if (dmode == Apdi || dmode == Ad16 || dmode == Ad8r) {
+                               set_ccr = 1;
+                       }
+                       break;
+               case imm:
+                       if (dmode == Ad16 || dmode == Ad8r) {
+                               set_high_word = 1;
+                       } else if (dmode == Apdi || dmode == absw || dmode == absl) {
+                               set_ccr = 1;
+                       }
+                       break;
+               }
+
+               if (set_low_word == 1) {
+                       // Low word: Z and N
+                       printf("\t\tccr_68000_long_move_ae_LZN(src);\n");
+               } else if (set_high_word == 3) {
+                       // High word: N only, clear Z if non-zero
+                       printf("\t\tSET_NFLG(src < 0);\n");
+                       printf("\t\tif((src & 0xffff0000)) SET_ZFLG(0);\n");
+               } else if (set_high_word) {
+                       // High word: N set/reset and Z clear.
+                       printf("\t\tccr_68000_long_move_ae_HNZ(src);\n");
+               } else if (set_ccr) {
+                       // Set normally.
+                       printf("\t\tccr_68000_long_move_ae_normal(src);\n");
+               }
+
+               if (dmode == Aipi) {
+                       printf("\t\tm68k_areg(regs, dstreg) -= 4;\n");
+               } else if (dmode == Apdi) {
+                       printf("\t\tm68k_areg(regs, dstreg) += 4;\n");
+               }
+
+       } else if (size == sz_long) {
+
+               // Second word (much simpler)
+
+               int set_ccr = 0;
+               int set_low_word = 0;
+               switch (smode)
+               {
+               case Dreg:
+               case Areg:
+                       if (dmode == Apdi || dmode == absw || dmode == absl) {
+                               set_ccr = 1;
+                       } else {
+                               set_low_word = 1;
+                       }
+                       break;
+               case Aind:
+               case Aipi:
+               case Apdi:
+               case Ad16:
+               case Ad8r:
+               case PC16:
+               case PC8r:
+               case absl:
+               case absw:
+                       set_ccr = 1;
+                       break;
+               case imm:
+                       if (dmode == Apdi || dmode == absw || dmode == absl) {
+                               set_ccr = 1;
+                       } else {
+                               set_low_word = 1;
+                       }
+                       break;
+               }
+
+               if (set_low_word == 1) {
+                       // Low word: Z and N
+                       printf("\t\tccr_68000_long_move_ae_LZN(src);\n");
+               } else if (set_ccr) {
+                       // Set normally.
+                       printf("\t\tccr_68000_long_move_ae_normal(src);\n");
+               }
+
+               if (dmode == Aipi) {
+                       printf("\t\tm68k_areg(regs, dstreg) -= 4;\n");
+               } else if (dmode == Apdi) {
+                       printf("\t\tm68k_areg(regs, dstreg) += 4;\n");
+               }
+
+       }
+
+}
+
 static char const *bus_error_reg;
 static int bus_error_reg_add;
 
@@ -1009,19 +1396,30 @@ static void check_bus_error(const char *name, int offset, int write, int fc)
                return;
        printf("\tif(cpu_bus_error) {\n");
 
+       int setapdiback = 0;
+
        if (fc == 2) {
 
                printf("\t\texception2_read(opcode, m68k_getpci() + %d, 2);\n", offset);
 
        } else {
 
-               if (exception_pc_offset)
+               if (exception_pc_offset) {
                        incpc("%d", exception_pc_offset);
+               }
+
+               if (g_instr->mnemo == i_MOVE && write) {
+                       move_68000_bus_error(offset, g_instr->size, &setapdiback, &fc);
+               }
 
                switch (bus_error_reg_add)
                {
                case 1:
-                       printf("\t\tm68k_areg(regs, %s) += areg_byteinc[%s] + %d;\n", bus_error_reg, bus_error_reg, offset);
+                       if (g_instr->mnemo == i_CMPM && write) {
+                               ;
+                       } else {
+                               printf("\t\tm68k_areg(regs, %s) += areg_byteinc[%s] + %d;\n", bus_error_reg, bus_error_reg, offset);
+                       }
                        break;
                case 2:
                        printf("\t\tm68k_areg(regs, %s) += 2 + %d;\n", bus_error_reg, offset);
@@ -1030,9 +1428,6 @@ static void check_bus_error(const char *name, int offset, int write, int fc)
                        if (g_instr->mnemo == i_CMPM) {
                                // CMPM.L (an)+,(an)+: increased by 2
                                printf("\t\tm68k_areg(regs, %s) += 2 + %d;\n", bus_error_reg, offset);
-                       } else {
-                               // not increased if long first word causes bus error
-                               ;
                        }
                        break;
                case 4:
@@ -1045,14 +1440,17 @@ static void check_bus_error(const char *name, int offset, int write, int fc)
                        break;
                }
 
+               if (g_instr->mnemo == i_BTST && (g_instr->dmode == PC16 || g_instr->dmode == PC8r)) {
+                       // BTST special case where destination is read access
+                       fc = 2;
+               }
+
                printf("\t\texception2_%s(opcode, %sa + %d, %d);\n",
                        write ? "write" : "read", name, offset,
-                       (!write && (g_instr->smode == PC16 || g_instr->smode == PC8r) ? 2 : fc));
+                       (!write && (g_instr->smode == PC16 || g_instr->smode == PC8r)) ||
+                       (write && (g_instr->dmode == PC16 || g_instr->dmode == PC8r)) ? 2 : fc);
        }
 
-       //              if (exception_pc_offset)
-       //                      printf("\tbus_error_offset = %d;\n", exception_pc_offset);
-
        printf("\t\tgoto %s;\n", endlabelstr);
        printf("\t}\n");
        need_endlabel = 1;
@@ -1525,7 +1923,7 @@ static void maybeaddop_ce020 (int flags)
 
 
 // Handle special MOVE.W/.L condition codes when destination write causes address error.
-static void move_68000_address_error(amodes mode, int size, int *setapdi, int *fcmodeflags)
+static void move_68000_address_error(int size, int *setapdi, int *fcmodeflags)
 {
        int smode = g_instr->smode;
        int dmode = g_instr->dmode;
@@ -1549,7 +1947,7 @@ static void move_68000_address_error(amodes mode, int size, int *setapdi, int *f
                        case absw:
                        case absl:
                        case imm:
-                               if (dmode == Aind || dmode == Aipi || dmode == Apdi || dmode == Ad16 || mode == Ad8r || mode == absw || mode == absl)
+                               if (dmode == Aind || dmode == Aipi || dmode == Apdi || dmode == Ad16 || dmode == Ad8r || dmode == absw || dmode == absl)
                                        set_ccr = 1;
                        break;
                }
@@ -1561,9 +1959,6 @@ static void move_68000_address_error(amodes mode, int size, int *setapdi, int *f
                }
                if (set_ccr) {
                        printf("\t\tccr_68000_word_move_ae_normal((uae_s16)(src));\n");
-                       //printf("\t\tCLEAR_CZNV();\n");
-                       //printf("\t\tSET_ZFLG(((uae_s16)(src)) == 0);\n");
-                       //printf("\t\tSET_NFLG(((uae_s16)(src)) < 0);\n");
                }
        } else {
                // Long MOVE is much more complex..
@@ -1589,9 +1984,9 @@ static void move_68000_address_error(amodes mode, int size, int *setapdi, int *f
                case PC8r:
                case absw:
                case absl:
-                       if (mode == Apdi || mode == Ad16 || mode == Ad8r || mode == absw) {
+                       if (dmode == Apdi || dmode == Ad16 || dmode == Ad8r || dmode == absw) {
                                set_ccr = 1;
-                       } else if (mode == Aind || mode == Aipi || mode == absl) {
+                       } else if (dmode == Aind || dmode == Aipi || dmode == absl) {
                                set_low_word = 1;
                        } else {
                                set_low_word = 2;
@@ -1615,35 +2010,15 @@ static void move_68000_address_error(amodes mode, int size, int *setapdi, int *f
                if (set_low_word == 1) {
                        // Low word: Z and N
                        printf("\t\tccr_68000_long_move_ae_LZN(src);\n");
-                       //printf("\t\tCLEAR_CZNV();\n");
-                       //printf("\t\tuae_s16 vsrc = (uae_s16)(src & 0xffff);\n");
-                       //printf("\t\tSET_ZFLG(vsrc == 0);\n");
-                       //printf("\t\tSET_NFLG(vsrc < 0);\n");
                } else if (set_low_word == 2) {
                        // Low word: N only
                        printf("\t\tccr_68000_long_move_ae_LN(src);\n");
-                       //printf("\t\tCLEAR_CZNV();\n");
-                       //printf("\t\tuae_s16 vsrc = (uae_s16)(src & 0xffff);\n");
-                       //printf("\t\tSET_NFLG(vsrc < 0);\n");
                } else if (set_high_word) {
                        // High word: N and Z clear.
                        printf("\t\tccr_68000_long_move_ae_HNZ(src);\n");
-                       //printf("\t\tuae_s16 vsrc = (uae_s16)(src >> 16);\n");
-                       //printf("\t\tif(vsrc < 0) {\n");
-                       //printf("\t\t\tSET_NFLG(1);\n");
-                       //printf("\t\t\tSET_ZFLG(0);\n");
-                       //printf("\t\t} else if (vsrc) {\n");
-                       //printf("\t\t\tSET_NFLG(0);\n");
-                       //printf("\t\t\tSET_ZFLG(0);\n");
-                       //printf("\t\t} else {\n");
-                       //printf("\t\t\tSET_NFLG(0);\n");
-                       //printf("\t\t}\n");
                } else if (set_ccr) {
                        // Set normally.
                        printf("\t\tccr_68000_long_move_ae_normal(src);\n");
-                       //printf("\t\tCLEAR_CZNV();\n");
-                       //printf("\t\tSET_ZFLG((src) == 0);\n");
-                       //printf("\t\tSET_NFLG((src) < 0);\n");
                }
        }
 }
@@ -1994,7 +2369,7 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
 
                if (g_instr->mnemo == i_MOVE) {
                        if (getv == 2) {
-                               move_68000_address_error(mode, size, &setapdiback, &fcmodeflags);
+                               move_68000_address_error(size, &setapdiback, &fcmodeflags);
                        }
                } else if (g_instr->mnemo == i_MVSR2) {
                        // If MOVE from SR generates address error exception,
@@ -2367,12 +2742,18 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                                        printf ("\t%s (%sa + 2, %s);\n", dstwx, to, from);
                                        check_bus_error(to, 2, 1, 1);
                                        check_ipl_again();
+                                       if (flags & GF_SECONDWORDSETFLAGS) {
+                                               genflags(flag_logical, g_instr->size, "src", "", "");
+                                       }
                                        printf ("%s (%sa, %s >> 16);\n", dstwx, to, from);
                                        check_bus_error(to, 0, 1, 1);
                                } else {
                                        printf ("\t%s (%sa, %s >> 16);\n", dstwx, to, from);
                                        check_bus_error(to, 0, 1, 1);
                                        check_ipl_again();
+                                       if (flags & GF_SECONDWORDSETFLAGS) {
+                                               genflags(flag_logical, g_instr->size, "src", "", "");
+                                       }
                                        printf ("\t%s (%sa + 2, %s);\n", dstwx, to, from);
                                        check_bus_error(to, 2, 1, 1);
                                }
@@ -2404,11 +2785,17 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                                if (store_dir) {
                                        printf("\t%s(%sa + 2, %s);\n", dstwx, to, from);
                                        check_bus_error(to, 2, 1, 1);
+                                       if (flags & GF_SECONDWORDSETFLAGS) {
+                                               genflags(flag_logical, g_instr->size, "src", "", "");
+                                       }
                                        printf("\t%s(%sa, %s >> 16); \n", dstwx, to, from);
                                        check_bus_error(to, 0, 1, 1);
                                } else {
                                        printf("\t%s (%sa, %s >> 16);\n", dstwx, to, from);
                                        check_bus_error(to, 0, 1, 1);
+                                       if (flags & GF_SECONDWORDSETFLAGS) {
+                                               genflags(flag_logical, g_instr->size, "src", "", "");
+                                       }
                                        printf("\t%s(%sa + 2, %s); \n", dstwx, to, from);
                                        check_bus_error(to, 2, 1, 1);
                                }
@@ -2947,243 +3334,6 @@ static void genmovemle_ce (uae_u16 opcode)
        fill_prefetch_next ();
 }
 
-static void duplicate_carry (int n)
-{
-       int i;
-       for (i = 0; i <= n; i++)
-               printf ("\t");
-       printf ("COPY_CARRY ();\n");
-}
-
-typedef enum
-{
-       flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_z, flag_zn,
-       flag_av, flag_sv
-}
-flagtypes;
-
-static void genflags_normal (flagtypes type, wordsizes size, const char *value, const char *src, const char *dst)
-{
-       char vstr[100], sstr[100], dstr[100];
-       char usstr[100], udstr[100];
-       char unsstr[100], undstr[100];
-
-       switch (size) {
-       case sz_byte:
-               strcpy (vstr, "((uae_s8)(");
-               strcpy (usstr, "((uae_u8)(");
-               break;
-       case sz_word:
-               strcpy (vstr, "((uae_s16)(");
-               strcpy (usstr, "((uae_u16)(");
-               break;
-       case sz_long:
-               strcpy (vstr, "((uae_s32)(");
-               strcpy (usstr, "((uae_u32)(");
-               break;
-       default:
-               term ();
-       }
-       strcpy (unsstr, usstr);
-
-       strcpy (sstr, vstr);
-       strcpy (dstr, vstr);
-       strcat (vstr, value);
-       strcat (vstr, "))");
-       strcat (dstr, dst);
-       strcat (dstr, "))");
-       strcat (sstr, src);
-       strcat (sstr, "))");
-
-       strcpy (udstr, usstr);
-       strcat (udstr, dst);
-       strcat (udstr, "))");
-       strcat (usstr, src);
-       strcat (usstr, "))");
-
-       strcpy (undstr, unsstr);
-       strcat (unsstr, "-");
-       strcat (undstr, "~");
-       strcat (undstr, dst);
-       strcat (undstr, "))");
-       strcat (unsstr, src);
-       strcat (unsstr, "))");
-
-       switch (type) {
-       case flag_logical_noclobber:
-       case flag_logical:
-       case flag_z:
-       case flag_zn:
-       case flag_av:
-       case flag_sv:
-       case flag_addx:
-       case flag_subx:
-               break;
-
-       case flag_add:
-               start_brace ();
-               printf ("uae_u32 %s = %s + %s;\n", value, udstr, usstr);
-               break;
-       case flag_sub:
-       case flag_cmp:
-               start_brace ();
-               printf ("uae_u32 %s = %s - %s;\n", value, udstr, usstr);
-               break;
-       }
-
-       switch (type) {
-       case flag_logical_noclobber:
-       case flag_logical:
-       case flag_zn:
-               break;
-
-       case flag_add:
-       case flag_sub:
-       case flag_addx:
-       case flag_subx:
-       case flag_cmp:
-       case flag_av:
-       case flag_sv:
-               start_brace ();
-               printf ("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr);
-               printf ("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr);
-               printf ("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr);
-               break;
-       }
-
-       switch (type) {
-       case flag_logical:
-               printf ("\tCLEAR_CZNV ();\n");
-               printf ("\tSET_ZFLG (%s == 0);\n", vstr);
-               printf ("\tSET_NFLG (%s < 0);\n", vstr);
-               break;
-       case flag_logical_noclobber:
-               printf ("\tSET_ZFLG (%s == 0);\n", vstr);
-               printf ("\tSET_NFLG (%s < 0);\n", vstr);
-               break;
-       case flag_av:
-               printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
-               break;
-       case flag_sv:
-               printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
-               break;
-       case flag_z:
-               printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr);
-               break;
-       case flag_zn:
-               printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr);
-               printf ("\tSET_NFLG (%s < 0);\n", vstr);
-               break;
-       case flag_add:
-               printf ("\tSET_ZFLG (%s == 0);\n", vstr);
-               printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
-               printf ("\tSET_CFLG (%s < %s);\n", undstr, usstr);
-               duplicate_carry (0);
-               printf ("\tSET_NFLG (flgn != 0);\n");
-               break;
-       case flag_sub:
-               printf ("\tSET_ZFLG (%s == 0);\n", vstr);
-               printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
-               printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr);
-               duplicate_carry (0);
-               printf ("\tSET_NFLG (flgn != 0);\n");
-               break;
-       case flag_addx:
-               printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0x42 */
-               printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));\n"); /* minterm SON: 0xD4 */
-               duplicate_carry (0);
-               break;
-       case flag_subx:
-               printf ("\tSET_VFLG ((flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0x24 */
-               printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));\n"); /* minterm SON: 0xB2 */
-               duplicate_carry (0);
-               break;
-       case flag_cmp:
-               printf ("\tSET_ZFLG (%s == 0);\n", vstr);
-               printf ("\tSET_VFLG ((flgs != flgo) && (flgn != flgo));\n");
-               printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr);
-               printf ("\tSET_NFLG (flgn != 0);\n");
-               break;
-       }
-}
-
-static void genflags (flagtypes type, wordsizes size, const char *value, const char *src, const char *dst)
-{
-       /* Temporarily deleted 68k/ARM flag optimizations.  I'd prefer to have
-       them in the appropriate m68k.h files and use just one copy of this
-       code here.  The API can be changed if necessary.  */
-       if (optimized_flags) {
-               switch (type) {
-               case flag_add:
-               case flag_sub:
-                       start_brace ();
-                       printf ("\tuae_u32 %s;\n", value);
-                       break;
-
-               default:
-                       break;
-               }
-
-               /* At least some of those casts are fairly important! */
-               switch (type) {
-               case flag_logical_noclobber:
-                       printf ("\t{uae_u32 oldcznv = GET_CZNV & ~(FLAGVAL_Z | FLAGVAL_N);\n");
-                       if (strcmp (value, "0") == 0) {
-                               printf ("\tSET_CZNV (olcznv | FLAGVAL_Z);\n");
-                       } else {
-                               switch (size) {
-                               case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break;
-                               case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break;
-                               case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break;
-                               }
-                               printf ("\tIOR_CZNV (oldcznv);\n");
-                       }
-                       printf ("\t}\n");
-                       return;
-               case flag_logical:
-                       if (strcmp (value, "0") == 0) {
-                               printf ("\tSET_CZNV (FLAGVAL_Z);\n");
-                       } else {
-                               switch (size) {
-                               case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break;
-                               case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break;
-                               case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break;
-                               }
-                       }
-                       return;
-
-               case flag_add:
-                       switch (size) {
-                       case sz_byte: printf ("\toptflag_addb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
-                       case sz_word: printf ("\toptflag_addw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
-                       case sz_long: printf ("\toptflag_addl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
-                       }
-                       return;
-
-               case flag_sub:
-                       switch (size) {
-                       case sz_byte: printf ("\toptflag_subb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
-                       case sz_word: printf ("\toptflag_subw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
-                       case sz_long: printf ("\toptflag_subl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
-                       }
-                       return;
-
-               case flag_cmp:
-                       switch (size) {
-                       case sz_byte: printf ("\toptflag_cmpb (regs, (uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break;
-                       case sz_word: printf ("\toptflag_cmpw (regs, (uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break;
-                       case sz_long: printf ("\toptflag_cmpl (regs, (uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break;
-                       }
-                       return;
-
-               default:
-                       break;
-               }
-       }
-
-       genflags_normal (type, size, value, src, dst);
-}
-
 static void force_range_for_rox (const char *var, wordsizes size)
 {
        /* Could do a modulo operation here... which one is faster? */
@@ -4255,8 +4405,17 @@ static void gen_opcode (unsigned int opcode)
                                        prefetch_done = 1;
                                }
 
-                               if (curi->mnemo == i_MOVE)
-                                       genflags(flag_logical, curi->size, "src", "", "");
+                               int storeflags = 0;
+
+                               if (curi->mnemo == i_MOVE) {
+                                       if (curi->size == sz_long && cpu_level <= 1 && (using_prefetch || using_ce) && curi->dmode >= Aind) {
+                                               // to support bus error exception correct flags, flags needs to be set
+                                               // after first word has been written.
+                                               storeflags = GF_SECONDWORDSETFLAGS;
+                                       } else {
+                                               genflags(flag_logical, curi->size, "src", "", "");
+                                       }
+                               }
 
                                if (curi->size == sz_long) {
                                        if ((curi->dmode == Ad16 || curi->dmode == PC16) && curi->smode == imm) {
@@ -4268,9 +4427,9 @@ static void gen_opcode (unsigned int opcode)
                                }
                                // MOVE EA,-(An) long writes are always reversed. Reads are normal.
                                if (curi->dmode == Apdi && curi->size == sz_long) {
-                                       genastore_rev("src", curi->dmode, "dstreg", curi->size, "dst");
+                                       genastore_2("src", curi->dmode, "dstreg", curi->size, "dst", 1, storeflags);
                                } else {
-                                       genastore("src", curi->dmode, "dstreg", curi->size, "dst");
+                                       genastore_2("src", curi->dmode, "dstreg", curi->size, "dst", 0, storeflags);
                                }
                                sync_m68k_pc ();
                                if (dualprefetch) {
@@ -6995,6 +7154,8 @@ int main(int argc, char *argv[])
 
        headerfile = fopen("cputbl.h", "wb");
 
+       fprintf(headerfile, "#define BUS_ERROR_EMULATION %d\n", using_bus_error);
+
        stblfile = fopen("cpustbl.cpp", "wb");
        generate_includes(stblfile, 0);
 
index 7dbb49088b9bbabab1d4ef7764cb849c96d4c0bf..ecb4f97f5d6900ac82f03779d6115845dde1b1a3 100644 (file)
@@ -1567,7 +1567,7 @@ void cpu_restore_fixup(void)
        }
 }
 
-// Low word: Z and N
+// Low word: Clear + Z and N
 void ccr_68000_long_move_ae_LZN(uae_s32 src)
 {
        CLEAR_CZNV();
@@ -1576,7 +1576,7 @@ void ccr_68000_long_move_ae_LZN(uae_s32 src)
        SET_NFLG(vsrc < 0);
 }
 
-// Low word: N only
+// Low word: Clear + N only
 void ccr_68000_long_move_ae_LN(uae_s32 src)
 {
        CLEAR_CZNV();