From 9b426adc6236e2134de3ccbf45db848b03371b8a Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 8 Dec 2019 17:29:13 +0200 Subject: [PATCH] CPU tester updates, check stacked SR against SR at the beginning of exception handler. RTE fix. --- cputest.cpp | 15 ++++++++++----- cputest/asm.S | 11 ++++++++++- cputest/main.c | 16 +++++++++++++++- gencpu.cpp | 13 ++++++------- newcpu.cpp | 4 ++-- 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/cputest.cpp b/cputest.cpp index 8da7f0a5..42201213 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -999,7 +999,7 @@ void exception3_read(uae_u32 opcode, uae_u32 addr, int size, int fc) regs.read_buffer = 0; if (currprefs.cpu_model == 68000) { - if (generates_group1_exception(regs.ir)) { + if (generates_group1_exception(regs.ir) && !(opcode & 0x20000)) { test_exception_3_fc |= 8; // set N/I } if (opcode & 0x10000) @@ -1021,7 +1021,7 @@ void exception3_write(uae_u32 opcode, uae_u32 addr, int size, uae_u32 val, int f test_exception_3_di = 1; if (currprefs.cpu_model == 68000) { - if (generates_group1_exception(regs.ir)) { + if (generates_group1_exception(regs.ir) && !(opcode & 0x20000)) { test_exception_3_fc |= 8; // set N/I } if (opcode & 0x10000) @@ -2455,15 +2455,20 @@ static int handle_specials_stack(uae_u16 opcode, uaecptr pc, struct instr *dp, i imm_special++; v = imm_special >> 2; uae_u16 sr = v & 31; - sr |= (v >> 5) << 12; + if (v & 32) + sr |= 0x2000; + if (v & 64) + sr |= 0x8000; put_word_test(addr, sr); + printf("%04x (%04x) ", sr, regs.sr); addr += 2; offset += 2; + *isconstant = imm_special >= (1 << (2 + 5)) * 4 ? 0 : -1; } else { offset += handle_rte(opcode, pc, dp, isconstant, addr); addr += 2; + *isconstant = imm_special >= (1 << (4 + 5)) * 4 ? 0 : -1; } - *isconstant = imm_special >= (1 << (4 + 5)) * 4 ? 0 : -1; } else if (dp->mnemo == i_RTS) { // RTS imm_special++; @@ -3250,7 +3255,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi } // requested target address but no EA? skip - if (target_address != 0xffffffff) { + if (target_address != 0xffffffff && isbranchinst(dp) != 2) { if (srcea != target_address && dstea != target_address) { memcpy(opcode_memory, oldbytes, sizeof(oldbytes)); continue; diff --git a/cputest/asm.S b/cputest/asm.S index e697c921..beee98ff 100644 --- a/cputest/asm.S +++ b/cputest/asm.S @@ -25,7 +25,8 @@ S_SSP = S_AREG+8*4 S_MSP = S_SSP+4 S_PC = S_MSP+4 S_SR = S_PC+4 -S_EXC = S_SR+4 +S_EXPSR = S_SR+4 +S_EXC = S_EXPSR+4 S_EXC010 = S_EXC+4 S_EXCFRAME = S_EXC010+4 S_FPU = S_EXCFRAME+4 @@ -276,11 +277,13 @@ _exceptiontable000: bsr.s exception | 47 nop exception: + move.w sr,-(sp) move.w #0,ACTIVITYREG move.l a0,-(sp) move.l datapointer(pc),a0 movem.l d0-d7/a0-a6,(a0) move.l (sp)+,8*4(a0) + move.w (sp)+,S_EXPSR+2(a0) move.l (sp)+,d0 lea _exceptiontable000(pc),a1 sub.l a1,d0 @@ -371,11 +374,13 @@ _exceptiontable010: bsr.s exception010 | 47 nop exception010: + move.w sr,-(sp) move.w #0,ACTIVITYREG move.l a0,-(sp) move.l datapointer(pc),a0 movem.l d0-d7/a0-a6,(a0) move.l (sp)+,8*4(a0) + move.w (sp)+,S_EXPSR+2(a0) move.l (sp)+,d0 lea _exceptiontable010(pc),a1 @@ -453,11 +458,13 @@ _exceptiontable020: bsr.s exception020 | 47 nop exception020: + move.w sr,-(sp) move.w #0,ACTIVITYREG move.l a0,-(sp) move.l datapointer(pc),a0 movem.l d0-d7/a0-a6,(a0) move.l (sp)+,8*4(a0) + move.w (sp)+,S_EXPSR+2(a0) move.l (sp)+,d0 lea _exceptiontable020(pc),a1 @@ -542,11 +549,13 @@ _exceptiontablefpu: bsr.s exceptionfpu | 47 nop exceptionfpu: + move.w sr,-(sp) move.w #0,ACTIVITYREG move.l a0,-(sp) move.l datapointer(pc),a0 movem.l d0-d7/a0-a6,(a0) move.l (sp)+,8*4(a0) + move.w (sp)+,S_EXPSR+2(a0) move.l (sp)+,d0 lea _exceptiontable020(pc),a1 diff --git a/cputest/main.c b/cputest/main.c index 204794ff..e1a523fe 100644 --- a/cputest/main.c +++ b/cputest/main.c @@ -41,6 +41,7 @@ struct registers uae_u32 msp; uae_u32 pc; uae_u32 sr; + uae_u32 expsr; uae_u32 exc, exc010; uae_u32 excframe; struct fpureg fpuregs[8]; @@ -1072,6 +1073,7 @@ static void out_regs(struct registers *r, int before) outbp += strlen(outbp); } *outbp++ = '\n'; + sprintf(outbp, "SR:%c%04x PC: %08lx ISP: %08lx", test_sr != last_registers.sr ? '*' : ' ', test_sr, r->pc, r->ssp); } else { // output only lines that have at least one modified register to save screen space for (int i = 0; i < 4; i++) { @@ -1093,8 +1095,8 @@ static void out_regs(struct registers *r, int before) *outbp++ = '\n'; } } + sprintf(outbp, "SR:%c%04x/%04x PC: %08lx ISP: %08lx", test_sr != last_registers.sr ? '*' : ' ', test_regs.sr, test_regs.expsr, r->pc, r->ssp); } - sprintf(outbp, "SR:%c%04x PC: %08lx ISP: %08lx", test_sr != last_registers.sr ? '*' : ' ', before ? test_sr : test_regs.sr, r->pc, r->ssp); outbp += strlen(outbp); if (cpu_lvl >= 2 && cpu_lvl <= 4) { sprintf(outbp, " MSP: %08lx", r->msp); @@ -1527,6 +1529,17 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr) } sr_changed = 0; last_registers.sr = val; + if (!(test_regs.expsr & 0x2000)) { + sprintf(outbp, "SR S-bit is not set at start of exception handler!\n"); + outbp += strlen(outbp); + errors++; + } + if ((test_regs.expsr & 0xff) != (test_regs.sr & 0xff)) { + sprintf(outbp, "Exception stacked CCR != CCR at start of exception handler!\n"); + outbp += strlen(outbp); + errors++; + } + } else if (mode == CT_PC) { uae_u32 val = last_registers.pc; p = restore_rel(p, &val, 0); @@ -1855,6 +1868,7 @@ static void process_test(uae_u8 *p) test_regs.sr = (ccr ? 31 : 0); } test_regs.sr |= sr_mask | (interrupt_mask << 8); + test_regs.expsr = test_regs.sr | 0x2000; test_sr = test_regs.sr; if (fpumode) { if (maxccr >= 32) { diff --git a/gencpu.cpp b/gencpu.cpp index b2c0db15..f0f27b19 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -4878,17 +4878,16 @@ static void gen_opcode (unsigned int opcode) genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL); genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL); printf("\tuaecptr oldpc = %s;\n", getpc); - printf ("\tregs.sr = sr;\n"); - makefromsr_t0(); - printf ("\tif (pc & 1) {\n"); - printf ("\t\texception3i (0x%04X, pc);\n", opcode); - printf ("\t\tgoto %s;\n", endlabelstr); - printf ("\t}\n"); + printf("\tregs.sr = sr;\n"); + makefromsr(); + printf("\tif (pc & 1) {\n"); + printf("\t\texception3_read(0x%04X | 0x20000, pc, 1, 2);\n", opcode); + printf("\t\tgoto %s;\n", endlabelstr); + printf("\t}\n"); setpc ("pc"); if (using_debugmem) { printf("\tbranch_stack_pop_rte(oldpc);\n"); } - makefromsr(); } else if (cpu_level == 1 && using_prefetch) { // 68010 int old_brace_level = n_braces; diff --git a/newcpu.cpp b/newcpu.cpp index 6bb92166..3c7af561 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -6870,7 +6870,7 @@ void exception3_read(uae_u32 opcode, uaecptr addr, int size, int fc) { bool ni = false; if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) { - if (generates_group1_exception(regs.ir)) { + if (generates_group1_exception(regs.ir) && !(opcode & 0x20000)) { ni = true; fc = -1; } @@ -6884,7 +6884,7 @@ void exception3_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int f { bool ni = false; if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) { - if (generates_group1_exception(regs.ir)) { + if (generates_group1_exception(regs.ir) && !(opcode & 0x20000)) { ni = true; fc = -1; } -- 2.47.3