From 28b2a7bb82e065807d06325e81f196ba4ec2f9fc Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 12 Jan 2020 19:59:25 +0200 Subject: [PATCH] 68000 (CHK and div by zero) and 68010 cycle timing fixes. --- gencpu.cpp | 41 ++++++++++++++++++++++++++++++++--------- newcpu.cpp | 12 ++++++------ newcpu_common.cpp | 1 + 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/gencpu.cpp b/gencpu.cpp index 8d8cc5b5..acfe3100 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -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: diff --git a/newcpu.cpp b/newcpu.cpp index ac5b6ec8..894db7a7 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -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 */ diff --git a/newcpu_common.cpp b/newcpu_common.cpp index b9ec8d52..d0b35e5b 100644 --- a/newcpu_common.cpp +++ b/newcpu_common.cpp @@ -770,6 +770,7 @@ int getDivu68kCycles (uae_u32 dividend, uae_u16 divisor) } } } + // -4 = remove prefetch cycle return mcycles * 2 - 4; } -- 2.47.3