]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
CPU tester WIP 68000 bus error support. Misc updates and fixes.
authorToni Wilen <twilen@winuae.net>
Sat, 5 Oct 2019 11:32:59 +0000 (14:32 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 5 Oct 2019 11:32:59 +0000 (14:32 +0300)
12 files changed:
cputest.cpp
cputest/adis/decode_ea.c
cputest/adis/globals.c
cputest/adis/opcode_handler_cpu.c
cputest/cputestgen.ini
cputest/main.c
gencpu.cpp
include/newcpu.h
ini.cpp
jit/exception_handler.cpp
newcpu.cpp
newcpu_common.cpp

index 21cfeefb8dff5b37889a73bfb7bebc39a25f16af..34bbecd2195845b86d61b39528220ac36f0bd5b9 100644 (file)
@@ -5,7 +5,6 @@
 #include "disasm.h"
 #include "ini.h"
 #include "fpp.h"
-#include "mmu_common.h"
 
 #include "options.h"
 
@@ -42,6 +41,7 @@ int movem_index1[256];
 int movem_index2[256];
 int movem_next[256];
 int bus_error_offset;
+int cpu_bus_error;
 
 struct mmufixup mmufixup[2];
 cpuop_func *cpufunctbl[65536];
@@ -66,6 +66,7 @@ static int feature_loop_mode_register = -1;
 static int feature_full_extension_format = 0;
 static int feature_test_rounds = 2;
 static int feature_flag_mode = 0;
+static TCHAR *feature_instruction_size = NULL;
 static uae_u32 feature_addressing_modes[2];
 static int ad8r[2], pc8r[2];
 static int multi_mode;
@@ -215,6 +216,11 @@ oob:
        return 0;
 }
 
+static bool is_nowrite_address(uaecptr addr, int size)
+{
+       return addr + size >= safe_memory_start && addr < safe_memory_end;
+}
+
 static void validate_addr(uaecptr addr, int size)
 {
        if (valid_address(addr, size, 0))
@@ -265,11 +271,7 @@ static void check_bus_error(uaecptr addr, int write, int fc)
        if (safe_memory_start == 0xffffffff && safe_memory_end == 0xffffffff)
                return;
        if (addr >= safe_memory_start && addr < safe_memory_end) {
-               test_exception = 2;
-               test_exception_3_w = write;
-               test_exception_addr = addr;
-               test_exception_3_fc = fc;
-               THROW(2);
+               cpu_bus_error = 1;
        }
 }
 
@@ -851,6 +853,27 @@ uae_u32 REGPARAM2 op_illg(uae_u32 opcode)
        return op_illg_1(opcode);
 }
 
+void exception2_read(uae_u32 opcode, uaecptr addr, int fc)
+{
+       test_exception = 2;
+       test_exception_3_w = 0;
+       test_exception_addr = addr;
+       test_exception_opcode = opcode;
+       test_exception_3_fc = fc;
+       doexcstack();
+}
+
+void exception2_write(uae_u32 opcode, uaecptr addr, int fc)
+{
+       test_exception = 2;
+       test_exception_3_w = 1;
+       test_exception_addr = addr;
+       test_exception_opcode = opcode;
+       test_exception_3_fc = fc;
+       doexcstack();
+}
+
+
 void exception3_read(uae_u32 opcode, uae_u32 addr, int fc)
 {
        test_exception = 3;
@@ -1691,7 +1714,7 @@ static int create_ea_exact(uae_u16 *opcodep, uaecptr pc, int mode, int reg, stru
        }
        case PC16:
        {
-               uae_u32 pct = opcode_memory_start + 2;
+               uae_u32 pct = pc + 2 - 2;
                if (target <= pct + 0x7ffe && target >= pct - 0x8000) {
                        put_word_test(pc, target - pct);
                        *eap = target;
@@ -1729,7 +1752,7 @@ static int create_ea_exact(uae_u16 *opcodep, uaecptr pc, int mode, int reg, stru
        case PC8r:
        {
                for (int r = 0; r < 16; r++) {
-                       uae_u32 aval = opcode_memory_start + 2;
+                       uae_u32 aval = pc + 2 - 2;
                        int rn = ((ea_exact_cnt >> 1) + r) & 15;
                        for (int i = 0; i < 2; i++) {
                                if ((ea_exact_cnt & 1) == 0 || i == 1) {
@@ -2126,6 +2149,7 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc, struct ins
        test_memory_accessed = 0;
        testing_active = 1;
        testing_active_opcode = opc;
+       cpu_bus_error = 0;
 
        int cnt = feature_loop_mode * 2;
        if (multi_mode)
@@ -2140,12 +2164,7 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc, struct ins
                uaecptr a7 = regs.regs[15];
                int s = regs.s;
 
-               TRY (ex) {
-                       (*cpufunctbl[opc])(opc);
-               } CATCH(ex) {
-                       // got bus error
-                       Exception(2);
-               } ENDTRY
+               (*cpufunctbl[opc])(opc);
 
                // Supervisor mode and A7 was modified: skip this test round.
                if (s && regs.regs[15] != a7) {
@@ -2296,7 +2315,7 @@ static uae_u8 *save_exception(uae_u8 *p, struct instr *dp)
        // parse exception and store fields that are unique
        // SR and PC was already saved with non-exception data
        if (cpu_lvl == 0) {
-               if (test_exception == 3) {
+               if (test_exception == 2 || test_exception == 3) {
                        // status
                        *p++ = sf[1];
                        // opcode (which is not necessarily current opcode!)
@@ -2844,7 +2863,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        continue;
                                                } else {
                                                        // branch target = generate exception
-                                                       put_word_test(srcaddr, 0x4afc);
+                                                       if (!is_nowrite_address(srcaddr, 2)) {
+                                                               put_word_test(srcaddr, 0x4afc);
+                                                       }
                                                        branch_target = srcaddr;
                                                        dst = store_mem(dst, 1);
                                                        memcpy(&ahist2, &ahist, sizeof(struct accesshistory) *MAX_ACCESSHIST);
@@ -3215,24 +3236,30 @@ static void test_mnemo_text(const TCHAR *path, const TCHAR *mode)
        _tcscpy(modetxt, mode);
        my_trim(modetxt);
        TCHAR *s = _tcschr(modetxt, '.');
-       if (s) {
-               *s = 0;
-               TCHAR c = _totlower(s[1]);
-               if (c == 'b')
+       if (s || feature_instruction_size != NULL) {
+               TCHAR c = 0;
+               if (s) {
+                       *s = 0;
+                       TCHAR c = _totlower(s[1]);
+               }
+               if (!c && feature_instruction_size) {
+                       c = feature_instruction_size[0];
+               }
+               if (c == 'b' || c == 'B')
                        sizes = 6;
-               if (c == 'w')
+               if (c == 'w' || c == 'W')
                        sizes = 4;
-               if (c == 'l')
+               if (c == 'l' || c == 'L')
                        sizes = 0;
-               if (c == 'u')
+               if (c == 'u' || c == 'U')
                        sizes = 8;
-               if (c == 's')
+               if (c == 's' || c == 'S')
                        sizes = 1;
-               if (c == 'x')
+               if (c == 'x' || c == 'X')
                        sizes = 2;
-               if (c == 'p')
+               if (c == 'p' || c == 'P')
                        sizes = 3;
-               if (c == 'd')
+               if (c == 'd' || c == 'D')
                        sizes = 5;
        }
 
@@ -3349,7 +3376,7 @@ static const TCHAR *addrmodes[] =
 int __cdecl main(int argc, char *argv[])
 {
        const struct cputbl *tbl = NULL;
-       TCHAR path[1000];
+       TCHAR path[1000], *vs;
        int v;
 
        struct ini_data *ini = ini_load(_T("cputestgen.ini"), false);
@@ -3400,12 +3427,13 @@ int __cdecl main(int argc, char *argv[])
        feature_exception3_instruction = 0;
        ini_getval(ini, INISECTION, _T("feature_exception3_instruction"), &feature_exception3_instruction);
 
-       v = -1;
-       ini_getval(ini, INISECTION, _T("feature_target_src_ea"), &v);
-       feature_target_ea[0] = v;
-       v = -1;
-       ini_getval(ini, INISECTION, _T("feature_target_dst_ea"), &v);
-       feature_target_ea[1] = v;
+       feature_target_ea[0] = 0xffffffff;
+       if (ini_getval(ini, INISECTION, _T("feature_target_src_ea"), &v))
+               feature_target_ea[0] = v;
+       feature_target_ea[1] = 0xffffffff;
+       if (ini_getval(ini, INISECTION, _T("feature_target_dst_ea"), &v))
+               feature_target_ea[1] = v;
+
        if (feature_target_ea[0] != 0xffffffff || feature_target_ea[1] != 0xffffffff) {
                if (feature_target_ea[0] & 1) {
                        feature_exception3_data = 3;
@@ -3510,6 +3538,11 @@ int __cdecl main(int argc, char *argv[])
        feature_test_rounds = 2;
        ini_getval(ini, INISECTION, _T("test_rounds"), &feature_test_rounds);
 
+       feature_instruction_size = NULL;
+       ini_getstring(ini, INISECTION, _T("feature_instruction_size"), &feature_instruction_size);
+
+       ini_getval(ini, INISECTION, _T("feature_instruction_size"), &feature_test_rounds);
+
        v = 0;
        ini_getval(ini, INISECTION, _T("test_memory_start"), &v);
        if (!v) {
index b44eb731817d0170678b92bd10ef082e82bbc24e..24874dda599766a17e61019443cb0827387f4061 100644 (file)
@@ -152,13 +152,14 @@ switch (mode)
     else
       {
       UWORD size = (first_ext_w >> 9) & 0x3;
-
+#if 0
       if (!cpu68020 && size != 0)  /* Only size of 1 allowed for 68000 */
         {
         instr_bad = TRUE;
         return (0);
         }
-      if (pass3)
+#endif
+         if (pass3)
         {
         /* To get the sign right */
         disp_an_indexed (to, (ushort)(reg + 8),
@@ -267,22 +268,25 @@ switch (mode)
           /* long extension word */
           if (cpu68020)
             return (full_extension (to, code + first_ext, mode, reg));
-          else
+#if 0
+                 else
             {
             instr_bad = TRUE;
             return (0);
             }
-          }
+#endif
+               }
         else
           {
           UWORD size = (first_ext_w >> 9) & 0x3;
-
+#if 0
           if (!cpu68020 && size != 0)  /* Only size of 1 allowed for 68000 */
             {
             instr_bad = TRUE;
             return (0);
             }
-          /* A neg displacement can make ref neg if out of bounds. */
+#endif
+                 /* A neg displacement can make ref neg if out of bounds. */
           ref = current_ref + ((ULONG)first_ext << 1) + (BYTE)first_ext_w;
           if (pass3)
             disp_pc_indexed (to, ref, (BYTE)first_ext_w,
index 79d472f9bbbd071954dad11e40a59833d9914ddd..e8d53ca927a899481bc8370c1f4ac2094a77d0b1 100644 (file)
@@ -87,12 +87,12 @@ BOOL try_small = FALSE;             /* -b */
 BOOL single_file = TRUE;                                   
 BOOL print_illegal_instr_offset = FALSE;         /* -i */
 BOOL old_style = FALSE;
-BOOL cpu68020 = FALSE,              /* -m2 */
-     cpu68030 = FALSE,              /* -m3 */
-     cpu68040 = FALSE,              /* -m4 */
-     cpu68060 = FALSE,              /* -m6 */
+BOOL cpu68020 = TRUE,              /* -m2 */
+     cpu68030 = TRUE,              /* -m3 */
+     cpu68040 = TRUE,              /* -m4 */
+     cpu68060 = TRUE,              /* -m6 */
      cpuCF = FALSE,
-     fpu68881 = FALSE;              /* -m8 */
+     fpu68881 = TRUE;              /* -m8 */
 BOOL disasm_as_lib = FALSE;         /* -l */
 BOOL ascending_label_numbers = FALSE;   /* -dn */
 BOOL verbose = FALSE;
index 4afbc9f2092b0f9ed59fc9202129e8c7b1bef13c..700b467b9e27b8f845c9e529a6381515a031ecae 100644 (file)
@@ -172,6 +172,7 @@ uint imm_b (struct opcode_entry *op)
 {
 ULONG instr = *(ULONG*)code;
 
+#if 0
 if ((instr & 0xfc0000ff) == 0)  /* if ori.b #0,ea or andi.b #0,ea */
   {
   /* ori.b #0,ea and andi.b #0,ea are probably not code */
@@ -185,7 +186,7 @@ if (!((instr == 0) || (instr == 0x0000ff00)))  /* GCC immediate may be $ffxx */
   instr_bad = TRUE;
   return (1);
   }
-
+#endif
 if (pass3)
   {
   char *to;
@@ -202,13 +203,14 @@ uint imm_w (struct opcode_entry *op)
 
 /* handler for ori.w andi.w eori.w subi.w addi.w cmpi.w */
 {
+#if 0
 if ((*((ULONG*)code) & 0xfc00ffff) == 0)
   {
   /* ori.w #0,ea and andi.w #0,ea are probably not code */
   instr_bad = TRUE;
   return (1);
   }
-
+#endif
 if (pass3)
   {
   char *to;
@@ -227,13 +229,14 @@ uint imm_l (struct opcode_entry *op)
 {
 register ULONG instr_ext = *(ULONG*)(code + 1);
 
+#if 0
 if ((instr_ext == 0) && (*(code) & 0xfc00) == 0)
   {
   /* ori.l #0,ea and andi.l #0,ea are probably not code */
   instr_bad = TRUE;
   return (1);
   }
-
+#endif
 if (pass2 && FLAGS_RELOC (current_ref + 2))
   {
   enter_ref (instr_ext, NULL, ACC_UNKNOWN);
@@ -291,13 +294,14 @@ uint bit_imm (struct opcode_entry *op)
 UWORD code_w = *code;
 UWORD data_w = *(code + 1);
 
+#if 0
 if ((data_w & 0xff00) != 0)
   {
   /* only bit #0-255 are valid */
   instr_bad = TRUE;
   return (1);
   }
-
+#endif
 if (pass3)
   {
   char *to;
index d048564d580a4389fdadf196c3c877968deb7317..903d48cc38dd68826acbacde5dd65fa7520e0af6 100644 (file)
@@ -104,6 +104,10 @@ feature_full_extension_format=0
 feature_addressing_modes_src=
 feature_addressing_modes_dst=
 
+; Limit test instruction size
+; B = byte, W = word, L = long, empty = no size limit
+feature_instruction_size=
+
 ; mnemonics separated by comma or all/fall.
 ; all = generate all CPU tests. tst = generate tst.b, tst.w and tst.l. tst.l = generate only tst.l
 ; fall = generate all FPU tests.
index 8a4e5443c7d042411f4c1ce36b46ce103333071f..0ba549e80dea86e7b7cd63c4f018c179227afeb6 100644 (file)
@@ -108,7 +108,8 @@ static uae_u8 ccr_mask;
 static uae_u32 addressing_mask = 0x00ffffff;
 static uae_u32 interrupt_mask;
 
-#define SIZE_STORED_ADDRESS 20
+#define SIZE_STORED_ADDRESS_OFFSET 8
+#define SIZE_STORED_ADDRESS 16
 static uae_u8 srcaddr[SIZE_STORED_ADDRESS];
 static uae_u8 dstaddr[SIZE_STORED_ADDRESS];
 static uae_u8 stackaddr[SIZE_STORED_ADDRESS];
@@ -351,40 +352,34 @@ static uae_u8 *load_file(const char *path, const char *file, uae_u8 *p, int *siz
                        exit(0);
                }
        }
-       if (safe_memory_start == (uae_u8*)0xffffffff && safe_memory_end == (uae_u8*)0xffffffff) {
-               *sizep = fread(p, 1, size, f);
-       } else if (safe_memory_end < p || safe_memory_start >= p + size) {
+       if (safe_memory_end < p || safe_memory_start >= p + size) {
                *sizep = fread(p, 1, size, f);
        } else {
-               *sizep = size;
-               uae_u8 *pp = p;
-               while (size > 0) {
-                       int size2 = size > sizeof(tmpbuffer) ? sizeof(tmpbuffer) : size;
-                       if (p + size2 > safe_memory_start && p < safe_memory_end) {
-                               if (fread(tmpbuffer, 1, size2, f) != size2) {
-                                       printf("Couldn't read file '%s' %ld\n", fname, size2);
-                                       exit(0);
-                               }
-                               uae_u8 *sp = tmpbuffer;
-                               for (int i = 0; i < size2; i++) {
-                                       if (pp < safe_memory_start || pp >= safe_memory_end) {
-                                               *pp = *sp;
-                                       }
-                                       pp++;
-                                       sp++;
-                               }
-                       } else {
-                               if (fread(p, 1, size2, f) != size2) {
-                                       printf("Couldn't read file '%s'\n", fname);
-                                       exit(0);
-                               }
-                               p += size2;
-                       }
+               if (size > 0 && p < safe_memory_start) {
+                       int size2 = safe_memory_start - p;
+                       if (size2 > size)
+                               size2 = size;
+                       if (fread(p, 1, size2, f) != size2)
+                               goto end;
+                       p += size2;
+                       size -= size2;
+               }
+               if (size > 0 && p >= safe_memory_start && p < safe_memory_end) {
+                       int size2 = safe_memory_end - p;
+                       if (size2 > size)
+                               size2 = size;
+                       fseek(f, size2, SEEK_CUR);
+                       p += size2;
                        size -= size2;
                }
+               if (size > 0) {
+                       if (fread(p, 1, size, f) != size)
+                               goto end;
+               }
                size = *sizep;
        }
        if (*sizep != size) {
+end:
                printf("Couldn't read file '%s'\n", fname);
                exit(0);
        }
@@ -811,7 +806,7 @@ static int addr_diff(uae_u8 *ap, uae_u8 *bp, int size)
 
 static void addinfo_bytes(char *name, uae_u8 *src, uae_u32 address, int offset, int len)
 {
-       sprintf(outbp, "%s: %08lx ", name, address);
+       sprintf(outbp, "%s %08lx ", name, address);
        address += offset;
        outbp += strlen(outbp);
        int cnt = 0;
@@ -885,35 +880,25 @@ static void addinfo(void)
        }
        *outbp = 0;
        if (code[0] == 0x4e73 || code[0] == 0x4e74 || code[0] == 0x4e75) {
-               addinfo_bytes("SA", stackaddr, stackaddr_ptr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
-               addinfo_bytes("  ", (uae_u8 *)stackaddr_ptr - SIZE_STORED_ADDRESS / 2, stackaddr_ptr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
+               addinfo_bytes("P", stackaddr, stackaddr_ptr, -SIZE_STORED_ADDRESS_OFFSET, SIZE_STORED_ADDRESS);
+               addinfo_bytes(" ", (uae_u8 *)stackaddr_ptr - SIZE_STORED_ADDRESS_OFFSET, stackaddr_ptr, -SIZE_STORED_ADDRESS_OFFSET, SIZE_STORED_ADDRESS);
        }
        if (regs.srcaddr != 0xffffffff) {
                uae_u8 *a = srcaddr;
-               uae_u8 *b = (uae_u8 *)regs.srcaddr - SIZE_STORED_ADDRESS / 2;
-               addinfo_bytes("SA", a, regs.srcaddr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
+               uae_u8 *b = (uae_u8 *)regs.srcaddr - SIZE_STORED_ADDRESS_OFFSET;
+               addinfo_bytes("S", a, regs.srcaddr, -SIZE_STORED_ADDRESS_OFFSET, SIZE_STORED_ADDRESS);
                if (addr_diff(a, b, SIZE_STORED_ADDRESS)) {
-                       addinfo_bytes("  ", b, regs.srcaddr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
+                       addinfo_bytes(" ", b, regs.srcaddr, -SIZE_STORED_ADDRESS_OFFSET, SIZE_STORED_ADDRESS);
                }
        }
        if (regs.dstaddr != 0xffffffff) {
                uae_u8 *a = dstaddr;
-               uae_u8 *b = (uae_u8*)regs.dstaddr - SIZE_STORED_ADDRESS / 2;
-               addinfo_bytes("DA", a, regs.dstaddr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
+               uae_u8 *b = (uae_u8*)regs.dstaddr - SIZE_STORED_ADDRESS_OFFSET;
+               addinfo_bytes("D", a, regs.dstaddr, -SIZE_STORED_ADDRESS_OFFSET, SIZE_STORED_ADDRESS);
                if (addr_diff(a, b, SIZE_STORED_ADDRESS)) {
-                       addinfo_bytes("  ", b, regs.dstaddr, -SIZE_STORED_ADDRESS / 2, SIZE_STORED_ADDRESS);
+                       addinfo_bytes(" ", b, regs.dstaddr, -SIZE_STORED_ADDRESS_OFFSET, SIZE_STORED_ADDRESS);
                }
        }
-
-#if 0
-int    Disass68k(long addr, char *labelBuffer, char *opcodeBuffer, char *operandBuffer, char *commentBuffer);
-void Disasm_SetCPUType(int CPU, int FPU);
-       Disasm_SetCPUType(0, 0);
-       char buf1[80], buf2[80], buf3[80], buf4[80];
-       Disass68k((long)opcode_memory, buf1, buf2, buf3, buf4);
-       sprintf(outbp, "%s %s\n", buf2, buf3);
-       outbp += strlen(outbp);
-#endif
 }
 
 struct srbit
@@ -1061,7 +1046,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum,
        exc = last_exception;
        if (excdatalen != 0xff) {
                if (cpu_lvl == 0) {
-                       if (excnum == 3) {
+                       if (excnum == 2 || excnum == 3) {
                                // status (with undocumented opcode part)
                                uae_u8 opcode0 = p[1];
                                uae_u8 opcode1 = p[2];
@@ -1496,8 +1481,8 @@ static void store_addr(uae_u32 s, uae_u8 *d)
 {
        if (s == 0xffffffff)
                return;
-       for (int i = -SIZE_STORED_ADDRESS / 2; i < SIZE_STORED_ADDRESS / 2; i++) {
-               uae_u32 ss = s + i;
+       for (int i = 0; i < SIZE_STORED_ADDRESS; i++) {
+               uae_u32 ss = s + (i - SIZE_STORED_ADDRESS_OFFSET);
                if (is_valid_test_addr(ss)) {
                        *d++ = *((uae_u8 *)ss);
                } else {
@@ -1940,10 +1925,7 @@ int main(int argc, char *argv[])
 
        cpu_lvl = get_cpu_model();
 
-#endif
-
        if (cpu_lvl == 5) {
-#ifdef M68K
                // Overwrite MOVEC to/from MSP
                // with NOPs if 68060
                extern void *msp_address1;
@@ -1954,9 +1936,10 @@ int main(int argc, char *argv[])
                *((uae_u32*)&msp_address2) = 0x4e714e71;
                *((uae_u32*)&msp_address3) = 0x4e714e71;
                *((uae_u32*)&msp_address4) = 0x4e714e71;
-#endif
        }
 
+#endif
+
        if (argc < 2) {
                printf("cputest <all/mnemonic> (<start mnemonic>) (continue)\n");
                printf("mnemonic = test single mnemonic\n");
index ddeb28a3e315d2bf82b4001988bb78cc5fada5cf..4ae77af4c921459ceec2bc22abb6e205b1e412de 100644 (file)
@@ -177,6 +177,7 @@ static int genamode_cnt, genamode8r_offset[2];
 static int n_braces, limit_braces;
 static int m68k_pc_offset, m68k_pc_offset_old;
 static int m68k_pc_total;
+static int exception_pc_offset;
 static int branch_inst;
 static int insn_n_cycles, insn_n_cycles020;
 static int ir2irc;
@@ -480,6 +481,31 @@ static void add_mmu040_movem (int movem)
        start_brace ();
 }
 
+static char bus_error_text[200];
+
+static void do_instruction_buserror(void)
+{
+       if (bus_error_text[0]) {
+               printf("\tif(cpu_bus_error) {\n");
+               printf("%s", bus_error_text);
+               printf("\t\tgoto %s;\n", endlabelstr);
+               need_endlabel = 1;
+               printf("\t}\n");
+               bus_error_text[0] = 0;
+       }
+}
+
+static void check_bus_error_ins(int offset)
+{
+       sprintf(bus_error_text, "\t\texception2_read(opcode, m68k_getpci() + %d, 2);\n", offset);
+}
+
+static void check_prefetch_bus_error(int offset)
+{
+       check_bus_error_ins(offset);
+       do_instruction_buserror();
+}
+
 static void gen_nextilong2 (const char *type, const char *name, int flags, int movem)
 {
        int r = m68k_pc_offset;
@@ -526,6 +552,7 @@ static void gen_nextilong2 (const char *type, const char *name, int flags, int m
 }
 static void gen_nextilong (const char *type, const char *name, int flags)
 {
+       bus_error_text[0] = 0;
        gen_nextilong2 (type, name, flags, 0);
 }
 
@@ -535,6 +562,7 @@ static const char *gen_nextiword (int flags)
        int r = m68k_pc_offset;
        m68k_pc_offset += 2;
 
+       bus_error_text[0] = 0;
        if (using_ce020) {
                if (flags & GF_NOREFILL)
                        sprintf(buffer, "%s (%d)", prefetch_word, r);
@@ -547,6 +575,7 @@ static const char *gen_nextiword (int flags)
                } else {
                        sprintf (buffer, "%s (%d)", prefetch_word, r + 2);
                        count_read++;
+                       check_bus_error_ins(r + 2);
                }
        } else {
                if (using_prefetch) {
@@ -555,10 +584,12 @@ static const char *gen_nextiword (int flags)
                        } else {
                                sprintf (buffer, "%s (%d)", prefetch_word, r + 2);
                                count_read++;
+                               check_bus_error_ins(r + 2);
                                insn_n_cycles += 4;
                        }
                } else {
                        sprintf (buffer, "%s (%d)", prefetch_word, r);
+                       check_bus_error_ins(r);
                        insn_n_cycles += 4;
                }
        }
@@ -571,6 +602,7 @@ static const char *gen_nextibyte (int flags)
        int r = m68k_pc_offset;
        m68k_pc_offset += 2;
 
+       bus_error_text[0] = 0;
        if (using_ce020 || using_prefetch_020) {
                if (flags & GF_NOREFILL)
                        sprintf(buffer, "(uae_u8)%s (%d)", prefetch_word, r);
@@ -583,6 +615,7 @@ static const char *gen_nextibyte (int flags)
                } else {
                        sprintf (buffer, "(uae_u8)%s (%d)", prefetch_word, r + 2);
                        count_read++;
+                       check_bus_error_ins(r + 2);
                }
        } else {
                insn_n_cycles += 4;
@@ -591,11 +624,13 @@ static const char *gen_nextibyte (int flags)
                                strcpy (buffer, "(uae_u8)regs.irc");
                        } else {
                                sprintf (buffer, "(uae_u8)%s (%d)", prefetch_word, r + 2);
-                               insn_n_cycles += 4;
                                count_read++;
+                               check_bus_error_ins(r + 2);
+                               insn_n_cycles += 4;
                        }
                } else {
                        sprintf (buffer, "%s (%d)", srcbi, r);
+                       check_bus_error_ins(r);
                        insn_n_cycles += 4;
                }
        }
@@ -669,6 +704,7 @@ static void fill_prefetch_2 (void)
        if (!using_prefetch)
                return;
        printf ("\t%s (%d);\n", prefetch_word, m68k_pc_offset + 2);
+       check_prefetch_bus_error(m68k_pc_offset + 2);
        did_prefetch = 1;
        ir2irc = 0;
        count_read++;
@@ -679,6 +715,7 @@ static void fill_prefetch_1 (int o)
 {
        if (using_prefetch) {
                printf ("\t%s (%d);\n", prefetch_word, o);
+               check_prefetch_bus_error(o);
                did_prefetch = 1;
                ir2irc = 0;
                count_read++;
@@ -781,6 +818,7 @@ static void fill_prefetch_0 (void)
        if (!using_prefetch)
                return;
        printf ("\t%s (0);\n", prefetch_word);
+       check_prefetch_bus_error(0);
        did_prefetch = 1;
        ir2irc = 0;
        count_read++;
@@ -793,6 +831,7 @@ static void dummy_prefetch (void)
        if (!using_prefetch)
                return;
        printf ("\t%s (%d);\n", srcwi, o);
+       check_prefetch_bus_error(o);
        count_read++;
        insn_n_cycles += 4;
 }
@@ -917,6 +956,67 @@ static void clearmmufixup (int cnt)
        }
 }
 
+static char const *bus_error_reg;
+static int bus_error_reg_add;
+
+static void check_bus_error(const char *name, int offset, int write, int fc)
+{
+       // check possible bus error (if 68000/010 and enabled)
+       if (!using_bus_error)
+               return;
+       if (!using_prefetch && !using_ce)
+               return;
+       printf("\tif(cpu_bus_error) {\n");
+
+       if (fc == 2) {
+
+               printf("\t\texception2_read(opcode, m68k_getpci() + %d, 2);\n", offset);
+
+       } else {
+
+               if (exception_pc_offset)
+                       incpc("%d", exception_pc_offset);
+
+               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);
+                       break;
+               case 2:
+                       printf("\t\tm68k_areg(regs, %s) += 2 + %d;\n", bus_error_reg, offset);
+                       break;
+               case 3:
+                       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:
+                       if ((g_instr->mnemo == i_ADDX || g_instr->mnemo == i_SUBX) && g_instr->size == sz_long) {
+                               // ADDX.L/SUBX.L -(an),-(an): not decreased
+                               ;
+                       } else {
+                               printf("\t\tm68k_areg (regs, %s) = %sa;\n", bus_error_reg, name);
+                       }
+                       break;
+               }
+
+               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));
+       }
+
+       //              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;
+}
+
 static void gen_set_fault_pc (bool multi, bool not68030)
 {
        int m68k_pc_total_old = m68k_pc_total;
@@ -1768,6 +1868,7 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
                default:
                        term ();
                }
+               do_instruction_buserror();
                maybeaddop_ce020 (flags);
                syncmovepc (getv, flags);
                return;
@@ -1810,13 +1911,15 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
                term ();
        }
 
+       do_instruction_buserror();
+
        syncmovepc (getv, flags);
        maybeaddop_ce020 (flags);
 
        /* We get here for all non-reg non-immediate addressing modes to
        * actually fetch the value. */
 
-       int exception_pc_offset = 0;
+       exception_pc_offset = 0;
        if (getv == 2) {
                // store
                if (pc_68000_offset) {
@@ -1877,16 +1980,32 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
                start_brace ();
        }
 
-       if ((using_prefetch || using_ce) && using_bus_error && getv != 0) {
-               if (exception_pc_offset)
-                       printf("\tbus_error_offset = %d;\n", exception_pc_offset);
-       }
-
        if (flags & GF_PREFETCH)
                fill_prefetch_next ();
        else if (flags & GF_IR2IRC)
                irc2ir (true);
 
+       bus_error_reg_add = 0;
+       bus_error_reg = reg;
+       if (!movem) {
+               if (mode == Aipi) {
+                       switch (size)
+                       {
+                       case sz_byte:
+                               bus_error_reg_add = 1;
+                               break;
+                       case sz_word:
+                               bus_error_reg_add = 2;
+                               break;
+                       case sz_long:
+                               bus_error_reg_add = 3;
+                               break;
+                       }
+               } else if (mode == Apdi) {
+                       bus_error_reg_add = 4;
+               }
+       }
+
        if (getv == 1) {
                const char *srcbx = !(flags & GF_FC) ? srcb : "sfc_nommu_get_byte";
                const char *srcwx = !(flags & GF_FC) ? srcw : "sfc_nommu_get_word";
@@ -1917,14 +2036,34 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
                        }
                } else if (using_ce || using_prefetch) {
                        switch (size) {
-                       case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcbx, name); count_read++; break;
-                       case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcwx, name); count_read++; break;
-                       case sz_long: {
+                       case sz_byte:
+                       {
+                               insn_n_cycles += 4; printf("\tuae_s8 %s = %s (%sa);\n", name, srcbx, name);
+                               count_read++;
+                               check_bus_error(name, 0, 0, 1);
+                               break;
+                       }
+                       case sz_word:
+                       {
+                               insn_n_cycles += 4; printf("\tuae_s16 %s = %s (%sa);\n", name, srcwx, name);
+                               count_read++;
+                               check_bus_error(name, 0, 0, 1);
+                               break;
+                       }
+                       case sz_long:
+                       {
                                insn_n_cycles += 8;
-                               if ((flags & GF_REVERSE) && mode == Apdi)
-                                       printf("\tuae_s32 %s = %s (%sa + 2); %s |= %s (%sa) << 16;\n", name, srcwx, name, name, srcw, name);
-                               else
-                                       printf("\tuae_s32 %s = %s (%sa) << 16; %s |= %s (%sa + 2);\n", name, srcwx, name, name, srcw, name);
+                               if ((flags & GF_REVERSE) && mode == Apdi) {
+                                       printf("\tuae_s32 %s = %s (%sa + 2);\n", name, srcwx, name);
+                                       check_bus_error(name, 0, 0, 1);
+                                       printf("\t%s |= % s(% sa) << 16; \n", name, srcw, name);
+                                       check_bus_error(name, 0, 0, 1);
+                               } else {
+                                       printf("\tuae_s32 %s = %s (%sa) << 16;\n", name, srcwx, name);
+                                       check_bus_error(name, 0, 0, 1);
+                                       printf("\t%s |= % s(% sa + 2); \n", name, srcw, name);
+                                       check_bus_error(name, 2, 0, 1);
+                               }
                                count_read += 2;
                                break;
                        }
@@ -1940,6 +2079,8 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char
                }
        }
 
+       bus_error_reg_add = 0;
+
        /* We now might have to fix up the register for pre-dec or post-inc
        * addressing modes. */
        if (!movem)
@@ -2168,6 +2309,7 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                                check_ipl_again();
                                printf ("\tx_put_byte (%sa, %s);\n", to, from);
                                count_write++;
+                               check_bus_error(to, 0, 1, 1);
                                break;
                        case sz_word:
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
@@ -2175,18 +2317,23 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                                check_ipl_again();
                                printf ("\tx_put_word (%sa, %s);\n", to, from);
                                count_write++;
+                               check_bus_error(to, 0, 1, 1);
                                break;
                        case sz_long:
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                                        term ();
                                if (store_dir) {
                                        printf ("\t%s (%sa + 2, %s);\n", dstwx, to, from);
+                                       check_bus_error(to, 2, 1, 1);
                                        check_ipl_again();
                                        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();
                                        printf ("\t%s (%sa + 2, %s);\n", dstwx, to, from);
+                                       check_bus_error(to, 2, 1, 1);
                                }
                                count_write += 2;
                                break;
@@ -2199,22 +2346,31 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                                insn_n_cycles += 4;
                                printf ("\t%s (%sa, %s);\n", dstbx, to, from);
                                count_write++;
+                               check_bus_error(to, 0, 1, 1);
                                break;
                        case sz_word:
                                insn_n_cycles += 4;
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                                        term ();
                                printf ("\t%s (%sa, %s);\n", dstwx, to, from);
+                               check_bus_error(to, 0, 1, 1);
                                count_write++;
                                break;
                        case sz_long:
                                insn_n_cycles += 8;
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                                        term ();
-                               if (store_dir)
-                                       printf ("\t%s (%sa + 2, %s); %s (%sa, %s >> 16);\n", dstwx, to, from, dstwx, to, from);
-                               else
-                                       printf ("\t%s (%sa, %s >> 16); %s (%sa + 2, %s);\n", dstwx, to, from, dstwx, to, from);
+                               if (store_dir) {
+                                       printf("\t%s(%sa + 2, %s);\n", dstwx, to, from);
+                                       check_bus_error(to, 2, 1, 1);
+                                       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);
+                                       printf("\t%s(%sa + 2, %s); \n", dstwx, to, from);
+                                       check_bus_error(to, 2, 1, 1);
+                               }
                                count_write += 2;
                                break;
                        default:
@@ -3902,29 +4058,45 @@ static void gen_opcode (unsigned int opcode)
                * weird things... */
        case i_MVPRM: // MOVEP R->M
                genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               printf ("\tuaecptr memp = m68k_areg (regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
+               printf ("\tuaecptr mempa = m68k_areg (regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
                if (curi->size == sz_word) {
-                       printf ("\t%s (memp, src >> 8);\n\t%s (memp + 2, src);\n", dstb, dstb);
+                       printf("\t%s(mempa, src >> 8);\n", dstb);
+                       check_bus_error("memp", 0, 1, 1);
+                       printf("\t%s(mempa + 2, src); \n", dstb);
+                       check_bus_error("memp", 2, 1, 1);
                        count_write += 2;
                } else {
-                       printf ("\t%s (memp, src >> 24);\n\t%s (memp + 2, src >> 16);\n", dstb, dstb);
-                       printf ("\t%s (memp + 4, src >> 8);\n\t%s (memp + 6, src);\n", dstb, dstb);
+                       printf("\t%s(mempa, src >> 24);\n", dstb);
+                       check_bus_error("memp", 0, 1, 1);
+                       printf("\t%s(mempa + 2, src >> 16);\n", dstb);
+                       check_bus_error("memp", 2, 1, 1);
+                       printf("\t%s(mempa + 4, src >> 8);\n", dstb);
+                       check_bus_error("memp", 4, 1, 1);
+                       printf("\t%s(mempa + 6, src); \n", dstb);
+                       check_bus_error("memp", 6, 1, 1);
                        count_write += 4;
                }
                fill_prefetch_next ();
                break;
        case i_MVPMR: // MOVEP M->R
-               printf ("\tuaecptr memp = m68k_areg (regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
+               printf ("\tuaecptr mempa = m68k_areg (regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
                genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
                if (curi->size == sz_word) {
-                       printf ("\tuae_u16 val  = (%s (memp) & 0xff) << 8;\n", srcb);
-                       printf ("\t        val |= (%s (memp + 2) & 0xff);\n", srcb);
+                       printf ("\tuae_u16 val  = (%s (mempa) & 0xff) << 8;\n", srcb);
+                       check_bus_error("memp", 0, 0, 1);
+                       printf ("\t        val |= (%s (mempa + 2) & 0xff);\n", srcb);
+                       check_bus_error("memp", 2, 0, 1);
                        count_read += 2;
                } else {
-                       printf ("\tuae_u32 val  = (%s (memp) & 0xff) << 24;\n", srcb);
-                       printf ("\t        val |= (%s (memp + 2) & 0xff) << 16;\n", srcb);
-                       printf ("\t        val |= (%s (memp + 4) & 0xff) << 8;\n", srcb);
-                       printf ("\t        val |= (%s (memp + 6) & 0xff);\n", srcb);
+                       printf ("\tuae_u32 val  = (%s (mempa) & 0xff) << 24;\n", srcb);
+                       check_bus_error("memp", 0, 0, 1);
+                       printf ("\t        val |= (%s (mempa + 2) & 0xff) << 16;\n", srcb);
+                       check_bus_error("memp", 2, 0, 1);
+                       printf ("\t        val |= (%s (mempa + 4) & 0xff) << 8;\n", srcb);
+                       check_bus_error("memp", 4, 0, 1);
+                       printf ("\t        val |= (%s (mempa + 6) & 0xff);\n", srcb);
+                       printf ("\t        val |= (%s (mempa + 6) & 0xff);\n", srcb);
+                       check_bus_error("memp", 6, 0, 1);
                        count_read += 4;
                }
                fill_prefetch_next ();
@@ -4493,9 +4665,15 @@ static void gen_opcode (unsigned int opcode)
                } else if (using_ce020 == 2) {
                        add_head_cycs (1);
                        printf ("\tm68k_do_rts_ce030 ();\n");
-               } else if (using_ce) {
-                       printf ("\tm68k_do_rts_ce ();\n");
-               } else if (using_prefetch || using_prefetch_020) {
+               } else if (using_ce || using_prefetch || (using_test && cpu_level <= 1)) {
+                       printf("\tuaecptr newpc, dsta = m68k_areg(regs, 7);\n");
+                       printf("\tnewpc = %s(dsta) << 16;\n", srcw);
+                       check_bus_error("dst", 0, 0, 1);
+                       printf("\tnewpc |= %s(dsta + 2);\n", srcw);
+                       check_bus_error("dst", 2, 0, 1);
+                       printf("\tm68k_areg(regs, 7) += 4;\n");
+                       setpc("newpc");
+               } else if (using_prefetch_020 || (using_test && cpu_level >= 2)) {
                        printf ("\tm68k_do_rtsi ();\n");
                } else {
                        printf ("\tm68k_do_rts ();\n");
@@ -4609,10 +4787,13 @@ static void gen_opcode (unsigned int opcode)
                        clear_m68k_offset();
                        fill_prefetch_1 (0);
                        if (using_ce || using_prefetch) {
-                               printf ("\t%s (m68k_areg (regs, 7), nextpc >> 16);\n", dstw);
-                               printf ("\t%s (m68k_areg (regs, 7) + 2, nextpc);\n", dstw);
+                               printf("\tuaecptr dsta = m68k_areg(regs, 7);\n");
+                               printf("\t%s(dsta, nextpc >> 16);\n", dstw);
+                               check_bus_error("dst", 0, 1, 1);
+                               printf("\t%s(dsta + 2, nextpc);\n", dstw);
+                               check_bus_error("dst", 2, 1, 1);
                        } else {
-                               printf ("\t%s (m68k_areg (regs, 7), nextpc);\n", dstl);
+                               printf ("\t%s(m68k_areg(regs, 7), nextpc);\n", dstl);
                        }
                        if (using_debugmem) {
                                printf("\tif (debugmem_trace)\n");
@@ -4696,7 +4877,15 @@ static void gen_opcode (unsigned int opcode)
                        printf ("\tm68k_do_bsr_ce030 (nextpc, s);\n");
                } else if (using_ce) {
                        printf ("\tm68k_do_bsr_ce (nextpc, s);\n");
-               } else if (using_prefetch || using_prefetch_020 || using_test) {
+               } else if (using_prefetch || (using_test && cpu_level <= 1)) {
+                       printf("\tm68k_areg(regs, 7) -= 4;\n");
+                       printf("\tuaecptr dsta = m68k_areg(regs, 7);\n");
+                       printf("\t%s(dsta, nextpc >> 16);\n", dstw);
+                       check_bus_error("dst", 0, 1, 1);
+                       printf("\t%s(dsta + 2, nextpc);\n", dstw);
+                       check_bus_error("dst", 2, 1, 1);
+                       incpc("s");
+               } else if (using_prefetch_020 || (using_test && cpu_level >= 2)) {
                        printf ("\tm68k_do_bsri (nextpc, s);\n");
                } else {
                        printf ("\tm68k_do_bsr (nextpc, s);\n");
@@ -6480,6 +6669,7 @@ static void generate_cpu_test(int mode)
        }
 
        using_exception_3 = 1;
+       using_bus_error = 1;
        using_prefetch = 0;
        using_prefetch_020 = 0;
        using_ce = 0;
index 5c5a6b1d1bef9f08cd4d54f708ebc0678a480cac..1f69cf5443f964a04fa3e1f34528c64f6d768a38 100644 (file)
@@ -53,6 +53,7 @@ extern int fpp_movem_next[256];
 #endif
 
 extern int bus_error_offset;
+extern int cpu_bus_error;
 
 typedef uae_u32 REGPARAM3 cpuop_func (uae_u32) REGPARAM;
 typedef void REGPARAM3 cpuop_func_ce (uae_u32) REGPARAM;
@@ -722,7 +723,9 @@ extern void exception3_notinstruction(uae_u32 opcode, uaecptr addr);
 extern void exception3i (uae_u32 opcode, uaecptr addr);
 extern void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc);
 extern void exception2 (uaecptr addr, bool read, int size, uae_u32 fc);
-extern void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc);
+extern void exception2_setup(uaecptr addr, bool read, uae_u32 fc);
+extern void exception2_read(uae_u32 opcode, uaecptr addr, int fc);
+extern void exception2_write(uae_u32 opcode, uaecptr addr, int fc);
 extern void m68k_reset (void);
 extern void cpureset (void);
 extern void cpu_halt (int id);
diff --git a/ini.cpp b/ini.cpp
index bd68b8fdf51bf865104eab1d34db3d84d16995b9..4e555ff04aa682566e682c256cff1414352b3e29 100644 (file)
--- a/ini.cpp
+++ b/ini.cpp
@@ -347,6 +347,8 @@ bool ini_getval_multi(struct ini_data *ini, const TCHAR *section, const TCHAR *k
        TCHAR *out2 = NULL;
        if (!ini_getstring_multi(ini, section, key, &out2, ctx))
                return false;
+       if (out2[0] == 0)
+               return false;
        if (_tcslen(out2) > 2 && out2[0] == '0' && _totupper(out2[1]) == 'X') {
                TCHAR *endptr;
                *v = _tcstol(out2 + 2, &endptr, 16);
index 9f4698b0f6d29ffa922c523d67551227891416d3..efc4e04a1e0efe0eb43b02d83bf9527b96fe6c8f 100644 (file)
@@ -507,7 +507,7 @@ LONG WINAPI EvalException(LPEXCEPTION_POINTERS info)
        }
        if (currprefs.comp_catchfault) {
                // setup fake exception
-               exception2_setup(uae_p32(address) - uae_p32(NATMEM_OFFSET), info->ExceptionRecord->ExceptionInformation[0] == 0, 1, regs.s ? 4 : 0);
+               exception2_setup(uae_p32(address) - uae_p32(NATMEM_OFFSET), info->ExceptionRecord->ExceptionInformation[0] == 0, regs.s ? 4 : 0);
                return EXCEPTION_EXECUTE_HANDLER;
        }
        return EXCEPTION_CONTINUE_SEARCH;
index 81b0350a82e80de4ab55cf91532bb0f2e2e192dc..e89fe279c3d9a227aaf6475550f849ff628f4945 100644 (file)
@@ -79,6 +79,7 @@ static int exception_in_exception;
 int mmu_enabled, mmu_triggered;
 int cpu_cycles;
 int bus_error_offset;
+int cpu_bus_error;
 static int baseclock;
 int m68k_pc_indirect;
 bool m68k_interrupt_delay;
@@ -6852,7 +6853,7 @@ void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc)
        exception3f (opcode, addr, w, i, false, pc, true, -1);
 }
 
-void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc)
+void exception2_setup(uaecptr addr, bool read, uae_u32 fc)
 {
        last_addr_for_exception_3 = m68k_getpc() + bus_error_offset;
        last_fault_for_exception_3 = addr;
@@ -6860,9 +6861,10 @@ void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc)
        last_fc_for_exception_3 = fc;
        last_op_for_exception_3 = regs.opcode;
        last_notinstruction_for_exception_3 = exception_in_exception != 0;
+       cpu_bus_error = 0;
 }
 
-void exception2 (uaecptr addr, bool read, int size, uae_u32 fc)
+void exception2(uaecptr addr, bool read, int size, uae_u32 fc)
 {
        if (currprefs.mmu_model) {
                if (currprefs.mmu_model == 68030) {
@@ -6872,11 +6874,24 @@ void exception2 (uaecptr addr, bool read, int size, uae_u32 fc)
                        mmu_bus_error (addr, 0, fc, read == false, size, 0, true);
                }
        } else {
-               exception2_setup(addr, read, size, fc);
+               exception2_setup(addr, read, fc);
                THROW(2);
+               activate_debugger();
        }
 }
 
+void exception2_read(uae_u32 opcode, uaecptr addr, int fc)
+{
+       exception2_setup(addr, true, fc);
+       Exception(2);
+}
+
+void exception2_write(uae_u32 opcode, uaecptr addr, int fc)
+{
+       exception2_setup(addr, false, fc);
+       Exception(2);
+}
+
 void cpureset (void)
 {
     /* RESET hasn't increased PC yet, 1 word offset */
index 7314172bbbbeb3639d336c6a81002515120c5e3c..7dbb49088b9bbabab1d4ef7764cb849c96d4c0bf 100644 (file)
@@ -817,7 +817,8 @@ void divbyzero_special (bool issigned, uae_s32 dst)
 
 /* DIVU overflow
  *
- * 68000: V=1, C=0, Z=0, N=1
+ * 68000: V=1, N=1, C=0, Z=0
+ * 68010: V=1, N=1, C=0, Z=0
  * 68020: V=1, C=0, Z=0, N=X
  * 68040: V=1, C=0, NZ not modified.
  * 68060: V=1, C=0, NZ not modified.
@@ -838,9 +839,17 @@ void setdivuflags(uae_u32 dividend, uae_u16 divisor)
                SET_VFLG(1);
                if ((uae_s32)dividend < 0)
                        SET_NFLG(1);
+       } else if (currprefs.cpu_model == 68010) {
+               SET_VFLG(1);
+               SET_NFLG(1);
+               SET_ZFLG(0);
+               SET_CFLG(0);
        } else {
+               // 68000
                SET_VFLG(1);
                SET_NFLG(1);
+               SET_ZFLG(0);
+               SET_CFLG(0);
        }
 }
 
@@ -876,7 +885,12 @@ void setdivsflags(uae_s32 dividend, uae_s16 divisor)
                        SET_ZFLG(1);
                if ((uae_s8)aquot < 0)
                        SET_NFLG(1);
+       } else if (currprefs.cpu_model == 68010) {
+               CLEAR_CZNV();
+               SET_VFLG(1);
+               SET_NFLG(1);
        } else {
+               // 68000
                CLEAR_CZNV();
                SET_VFLG(1);
                SET_NFLG(1);