]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68000 (CHK and div by zero) and 68010 cycle timing fixes.
authorToni Wilen <twilen@winuae.net>
Sun, 12 Jan 2020 17:59:25 +0000 (19:59 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 12 Jan 2020 17:59:25 +0000 (19:59 +0200)
gencpu.cpp
newcpu.cpp
newcpu_common.cpp

index 8d8cc5b515535feff0e22c4ec4538db196e6aa16..acfe3100b1e2989b49b4aa641731cc313d6b7f15 100644 (file)
@@ -4679,10 +4679,11 @@ static void gen_opcode (unsigned int opcode)
        case i_ORSR:
        case i_ANDSR:
        case i_EORSR:
+               next_level_000();
                printf("\tMakeSR();\n");
                if (cpu_level == 0)
                        printf("\tint t1 = regs.t1;\n");
-               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, cpu_level == 1 ? GF_NOREFILL : 0);
                if (curi->size == sz_byte) {
                        printf("\tsrc &= 0xFF;\n");
                        if (curi->mnemo == i_ANDSR)
@@ -4776,6 +4777,7 @@ static void gen_opcode (unsigned int opcode)
                break;
        }
        case i_SUBX:
+               next_level_000();
                if (!isreg(curi->smode))
                        addcycles000 (2);
                genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_REVERSE);
@@ -4820,7 +4822,10 @@ static void gen_opcode (unsigned int opcode)
                                fill_prefetch_next_after(1, NULL);
                        }
                        if (curi->size == sz_long && isreg(curi->smode)) {
-                               addcycles000(4);
+                               if (cpu_level == 0)
+                                       addcycles000(4);
+                               else
+                                       addcycles000(2);
                        }
                        if (curi->size == sz_long || !isreg(curi->smode)) {
                                genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst");
@@ -4943,6 +4948,7 @@ static void gen_opcode (unsigned int opcode)
                break;
        }
        case i_ADDX:
+               next_level_000();
                if (!isreg(curi->smode)) {
                        addcycles000(2);
                }
@@ -4988,7 +4994,10 @@ static void gen_opcode (unsigned int opcode)
                                fill_prefetch_next_after(1, NULL);
                        }
                        if (curi->size == sz_long && isreg(curi->smode)) {
-                               addcycles000(4);
+                               if (cpu_level == 0)
+                                       addcycles000(4);
+                               else
+                                       addcycles000(2);
                        }
                        if (curi->size == sz_long || !isreg(curi->smode)) {
                                genastore_rev("newv", curi->dmode, "dstreg", curi->size, "dst");
@@ -5276,6 +5285,7 @@ static void gen_opcode (unsigned int opcode)
                        bsetcycles(curi);
                        if (curi->dmode == imm) {
                                // btst dn,#x
+                               addcycles000(2);
                                fill_prefetch_next_after(1, NULL);
                                printf("\tSET_ZFLG(1 ^ ((dst >> src) & 1));\n");
                        } else {
@@ -6504,7 +6514,10 @@ static void gen_opcode (unsigned int opcode)
                pop_ins_cnt();
                printf("\t}\n");
                sync_m68k_pc ();
-               if (cpu_level != 1 && curi->size != sz_byte) {
+               if (cpu_level == 1) {
+                       if (curi->size != sz_byte)
+                               addcycles000(2);
+               } else if (cpu_level == 0) {
                        addcycles000(2);
                }
                get_prefetch_020_continue ();
@@ -6644,6 +6657,12 @@ bccl_not68020:
                fill_prefetch_full_020 ();
                returncycles ("\t\t\t", 10);
                printf("\t\t}\n");
+               if (cpu_level == 1) {
+                       printf("\t\tif (!src) {\n");
+                       addcycles000_onlyce(2);
+                       addcycles000_nonce("\t\t\t", 2);
+                       printf("\t\t}\n");
+               }
                add_head_cycs (10);
                addcycles000_nonce("\t\t", 2 + 2);
                if (cpu_level == 0) {
@@ -6696,6 +6715,7 @@ bccl_not68020:
                printf("\tif (src == 0) {\n");
                printf("\t\tdivbyzero_special(0, dst);\n");
                incpc("%d", m68k_pc_offset);
+               addcycles000(4);
                printf("\t\tException_cpu(5);\n");
                write_return_cycles("\t\t", 0);
                printf("\t}\n");
@@ -6730,6 +6750,7 @@ bccl_not68020:
                printf("\tif (src == 0) {\n");
                printf("\t\tdivbyzero_special (1, dst);\n");
                incpc("%d", m68k_pc_offset);
+               addcycles000(4);
                printf("\t\tException_cpu(5);\n");
                write_return_cycles("\t\t", 0);
                printf("\t}\n");
@@ -6802,15 +6823,15 @@ bccl_not68020:
        case i_CHK:
                genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
-               sync_m68k_pc ();
-               addcycles000 (4);
-               printf("\tif ((uae_s32)dst < 0) {\n");
+               sync_m68k_pc();
+               addcycles000(4);
+               printf("\tif (dst > src) {\n");
                printf("\t\tsetchkundefinedflags(src, dst, %d);\n", curi->size);
                printf("\t\tException_cpu(6);\n");
                write_return_cycles("\t\t", 0);
                printf("\t}\n");
-               addcycles000 (2);
-               printf("\tif (dst > src) {\n");
+               addcycles000(2);
+               printf("\tif ((uae_s32)dst < 0) {\n");
                printf("\t\tsetchkundefinedflags(src, dst, %d);\n", curi->size);
                printf("\t\tException_cpu(6);\n");
                write_return_cycles("\t\t", 0);
@@ -7295,6 +7316,7 @@ bccl_not68020:
                printf("\tif (!m68k_movec2(src & 0xFFF, regp)) {\n");
                write_return_cycles("\t\t", 0);
                printf("\t}\n");
+               addcycles000(2);
                trace_t0_68040_only();
                break;
        case i_MOVE2C:
@@ -7306,6 +7328,7 @@ bccl_not68020:
                printf("\tif (!m68k_move2c(src & 0xFFF, regp)) {\n");
                write_return_cycles("\t\t", 0);
                printf("\t}\n");
+               addcycles000(4);
                trace_t0_68040_only();
                break;
        case i_CAS:
index ac5b6ec8efe17c3c8c8f3098bf51e20963262771..894db7a7384a12027ffc81ac3413a9c76558260f 100644 (file)
@@ -2375,7 +2375,7 @@ Address/Bus Error:
 
 Division by Zero:
 
-- 8 idle cycles
+- 4 idle cycles (EA + 4 cycles in cpuemu)
 - write PC low word
 - write SR
 - write PC high word
@@ -2411,7 +2411,7 @@ TrapV:
 
 CHK:
 
-- 8 idle cycles
+- 4 idle cycles (EA + 4 cycles in cpuemu)
 - write PC low word
 - write SR
 - write PC high word
@@ -2487,7 +2487,7 @@ static void Exception_ce000 (int nr)
                        start = 0;
                else if (nr >= 32 && nr < 32 + 16) // TRAP #x
                        start = 4;
-               else if (nr == 4 || nr == 8 || nr == 9 || nr == 10 || nr == 11) // ILLG, PRIV, TRACE, LINEA, LINEF
+               else if (nr == 4 || nr == 5 || nr == 6 || nr == 8 || nr == 9 || nr == 10 || nr == 11) // ILLG, DIVBYZERO, PRIV, TRACE, LINEA, LINEF
                        start = 4;
        }
 
@@ -2801,15 +2801,15 @@ static void add_approximate_exception_cycles(int nr)
                cycles = 44 + 4; 
        } else if (nr >= 32 && nr <= 47) {
                /* Trap (total is 34, but cpuemux.c already adds 4) */ 
-               cycles = 34 -4;
+               cycles = 34 - 4;
        } else {
                switch (nr)
                {
                        case 2: cycles = 50; break;             /* Bus error */
                        case 3: cycles = 50; break;             /* Address error */
                        case 4: cycles = 34; break;             /* Illegal instruction */
-                       case 5: cycles = 38; break;             /* Division by zero */
-                       case 6: cycles = 40; break;             /* CHK */
+                       case 5: cycles = 34; break;             /* Division by zero */
+                       case 6: cycles = 34; break;             /* CHK */
                        case 7: cycles = 34; break;             /* TRAPV */
                        case 8: cycles = 34; break;             /* Privilege violation */
                        case 9: cycles = 34; break;             /* Trace */
index b9ec8d52da2ab51c308d8688db79e6f33008cf65..d0b35e5b77d14641b6709e8cbf50cd1a9636370f 100644 (file)
@@ -770,6 +770,7 @@ int getDivu68kCycles (uae_u32 dividend, uae_u16 divisor)
                        }
                }
        }
+       // -4 = remove prefetch cycle
        return mcycles * 2 - 4;
 }