From 65334472a0f05cc207cc5c07a64921e5a9209b3c Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Wed, 14 Aug 2019 21:15:02 +0300 Subject: [PATCH] CPU tester updates. --- cputest.cpp | 90 +++++++++++++++++++++++++--------------- cputest/main.c | 109 ++++++++++++++++++++++++++++--------------------- 2 files changed, 120 insertions(+), 79 deletions(-) diff --git a/cputest.cpp b/cputest.cpp index a90002f5..2f8eb85c 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -97,6 +97,7 @@ static int exception_stack_frame_size; static uaecptr test_exception_addr; static int test_exception_3_inst; static int test_exception_3_w; +static int test_exception_opcode; static uae_u8 imm8_cnt; static uae_u16 imm16_cnt; static uae_u32 imm32_cnt; @@ -667,13 +668,21 @@ static void doexcstack(void) noaccesshistory = 1; testing_active = -1; + int opcode = (opcode_memory[0] << 8) | (opcode_memory[1]); + int statusormask = 0, statusandmask = 0; + if (test_exception_opcode >= 0) { + opcode = test_exception_opcode; + statusormask = (test_exception_opcode >> 16) & 0xff; + statusandmask = (test_exception_opcode >> 24) & 0xff; + } + int sv = regs.s; uaecptr tmp = m68k_areg(regs, 7); m68k_areg(regs, 7) = test_memory_end + EXTRA_RESERVED_SPACE; if (cpu_lvl == 0) { if (test_exception == 3) { - uae_u16 opcode = (opcode_memory[0] << 8) | (opcode_memory[1]); - uae_u16 mode = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1); + uae_u16 mode = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1) | statusormask; + mode &= ~statusandmask; mode |= test_exception_3_w ? 0 : 16; Exception_build_68000_address_error_stack_frame(mode, opcode, test_exception_addr, regs.pc); } @@ -738,14 +747,18 @@ void exception3_read(uae_u32 opcode, uae_u32 addr) { test_exception = 3; test_exception_3_inst = 0; + test_exception_3_w = 0; test_exception_addr = addr; + test_exception_opcode = opcode; doexcstack(); } void exception3_write(uae_u32 opcode, uae_u32 addr) { test_exception = 3; test_exception_3_inst = 0; + test_exception_3_w = 1; test_exception_addr = addr; + test_exception_opcode = opcode; doexcstack(); } void REGPARAM2 Exception(int n) @@ -753,6 +766,7 @@ void REGPARAM2 Exception(int n) test_exception = n; test_exception_3_inst = 0; test_exception_addr = m68k_getpci(); + test_exception_opcode = -1; doexcstack(); } void REGPARAM2 Exception_cpu(int n) @@ -760,6 +774,7 @@ void REGPARAM2 Exception_cpu(int n) test_exception = n; test_exception_3_inst = 0; test_exception_addr = m68k_getpci(); + test_exception_opcode = -1; bool t0 = currprefs.cpu_model >= 68020 && regs.t0; // check T0 trace @@ -774,6 +789,7 @@ void exception3i(uae_u32 opcode, uaecptr addr) test_exception_3_inst = 1; test_exception_3_w = 0; test_exception_addr = addr; + test_exception_opcode = opcode; doexcstack(); } void exception3b(uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc) @@ -782,6 +798,7 @@ void exception3b(uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc) test_exception_3_inst = i; test_exception_3_w = w; test_exception_addr = addr; + test_exception_opcode = opcode; doexcstack(); } @@ -1484,17 +1501,6 @@ static int handle_specials_pack(uae_u16 opcode, uaecptr pc, struct instr *dp, in static void handle_specials_extra(uae_u16 opcode, uaecptr pc, struct instr *dp) { - // if MOVES to A7: change it to MOVES from A7. SSP modification would cause crash. - if (dp->mnemo == i_MOVES) { - uae_u16 extra = get_word_test(opcode_memory_start + 2); - if (!(extra & 0x800)) { - int reg = extra >> 12; - if (reg == 7 + 8) { - extra |= 0x800; - put_word_test(opcode_memory_start + 2, extra); - } - } - } // cas undocumented (marked as zero in document) fields do something weird, for example // setting bit 9 will make "Du" address register but results are not correct. // so lets make sure unused zero bits are zeroed. @@ -1624,8 +1630,16 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc) do_trace(); regs.instruction_pc = regs.pc; + uaecptr a7 = regs.regs[15]; + int s = regs.s; + (*cpufunctbl[opc])(opc); + // supervisor mode and A7 was modified: skip this test round. + if (s && regs.regs[15] != a7) { + test_exception = -1; + } + if (!test_exception) { if (SPCFLAG_DOTRACE) Exception(9); @@ -1709,7 +1723,6 @@ static int is_test_trace(struct instr *dp) { case i_STOP: case i_MV2SR: - case i_MVSR2: return 1; } return 0; @@ -1745,7 +1758,11 @@ static uae_u8 *save_exception(uae_u8 *p, struct instr *dp) // SR and PC was already saved with non-exception data if (cpu_lvl == 0) { if (test_exception == 3) { + // status *p++ = sf[1]; + // opcode (which is not necessarily current opcode!) + *p++ = sf[6]; + *p++ = sf[7]; // access address p = store_rel(p, 0, opcode_memory_start, gl(sf + 2), 1); } @@ -2039,7 +2056,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in if (opc == 0xf228) printf(""); - if (subtest_count == 3136) + if (subtest_count == 1537) printf(""); @@ -2305,7 +2322,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in if (regs.sr & 0x2000) prev_s_cnt++; - if (subtest_count == 928) + if (subtest_count == 1536) printf(""); execute_ins(opc, pc - 2, branch_target); @@ -2326,6 +2343,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in // instruction accessed memory out of test address space bounds skipped = 1; did_out_of_bounds = true; + } else if (test_exception < 0) { + // something happened that requires test skip + skipped = 1; } else if (test_exception) { // generated exception exception_array[test_exception]++; @@ -2615,7 +2635,7 @@ int __cdecl main(int argc, char *argv[]) struct ini_data *ini = ini_load(_T("cputestgen.ini"), false); if (!ini) { - wprintf(_T("couldn't open cputestgen.ini")); + wprintf(_T("Couldn't open cputestgen.ini")); return 0; } @@ -2793,28 +2813,32 @@ int __cdecl main(int argc, char *argv[]) fill_memory(); - TCHAR *lmem_rom_name = NULL; - ini_getstring(ini, INISECTION, _T("low_rom"), &lmem_rom_name); - if (lmem_rom_name && test_low_memory_start != 0xffffffff) { - if (load_file(NULL, lmem_rom_name, low_memory_temp, low_memory_size, 0)) { - wprintf(_T("Low test memory ROM loaded\n")); - lmem_rom = 1; + if (test_low_memory_start != 0xffffffff) { + TCHAR *lmem_rom_name = NULL; + ini_getstring(ini, INISECTION, _T("low_rom"), &lmem_rom_name); + if (lmem_rom_name) { + if (load_file(NULL, lmem_rom_name, low_memory_temp, low_memory_size, 0)) { + wprintf(_T("Low test memory ROM loaded\n")); + lmem_rom = 1; + } } + free(lmem_rom_name); + save_memory(path, _T("lmem.dat"), low_memory_temp, low_memory_size); } - free(lmem_rom_name); - TCHAR *hmem_rom_name = NULL; - ini_getstring(ini, INISECTION, _T("high_rom"), &hmem_rom_name); - if (hmem_rom_name && test_high_memory_start != 0xffffffff) { - if (load_file(NULL, hmem_rom_name, high_memory_temp, high_memory_size, -1)) { - wprintf(_T("High test memory ROM loaded\n")); - hmem_rom = 1; + if (test_high_memory_start != 0xffffffff) { + TCHAR *hmem_rom_name = NULL; + ini_getstring(ini, INISECTION, _T("high_rom"), &hmem_rom_name); + if (hmem_rom_name) { + if (load_file(NULL, hmem_rom_name, high_memory_temp, high_memory_size, -1)) { + wprintf(_T("High test memory ROM loaded\n")); + hmem_rom = 1; + } } + free(hmem_rom_name); + save_memory(path, _T("hmem.dat"), high_memory_temp, high_memory_size); } - free(hmem_rom_name); - save_memory(path, _T("lmem.dat"), low_memory_temp, low_memory_size); - save_memory(path, _T("hmem.dat"), high_memory_temp, high_memory_size); save_memory(path, _T("tmem.dat"), test_memory_temp, test_memory_size); storage_buffer = (uae_u8 *)calloc(max_storage_buffer, 1); diff --git a/cputest/main.c b/cputest/main.c index f338f7f5..4a256cf4 100644 --- a/cputest/main.c +++ b/cputest/main.c @@ -267,14 +267,17 @@ static void end_test(void) touser(enable_data); } -static uae_u8 *load_file(const char *path, const char *file, uae_u8 *p, int *sizep) +static uae_u8 *load_file(const char *path, const char *file, uae_u8 *p, int *sizep, int exiterror) { char fname[256]; sprintf(fname, "%s%s", path, file); FILE *f = fopen(fname, "rb"); if (!f) { - printf("Couldn't open '%s'\n", fname); - exit(0); + if (exiterror) { + printf("Couldn't open '%s'\n", fname); + exit(0); + } + return NULL; } int size = *sizep; if (size < 0) { @@ -681,9 +684,6 @@ static uae_u8 *restore_data(uae_u8 *p) return p; } -int Disass68k(long addr, char *labelBuffer, char *opcodeBuffer, char *operandBuffer, char *commentBuffer); -void Disasm_SetCPUType(int CPU, int FPU); - static uae_u16 test_sr, test_ccrignoremask; static uae_u32 test_fpsr, test_fpcr; @@ -722,6 +722,8 @@ static void addinfo(void) *outbp = 0; #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); @@ -764,16 +766,18 @@ static void out_regs(struct registers *r, int before) outbp += strlen(outbp); sprintf(outbp, "SR:%c%04x PC: %08lx ISP: %08lx MSP: %08lx\n", test_regs.sr != test_sr ? '*' : ' ', before ? test_sr : r->sr, r->pc, r->ssp, r->msp); outbp += strlen(outbp); - uae_u16 s = before ? test_sr : r->sr; - uae_u16 s1 = test_regs.sr; - uae_u16 s2 = test_sr; - uae_u16 s3 = before ? s1 : last_registers.sr; - for (int i = 0; srbits[i].name; i++) { - if (i > 0) - *outbp++ = ' '; - uae_u16 mask = 1 << srbits[i].bit; - sprintf(outbp, "%s%c%d", srbits[i].name, (s3 & mask) != (s1 & mask) ? '!' : ((s1 & mask) != (s2 & mask) ? '*' : '='), (s & mask) != 0); - outbp += strlen(outbp); + if (before >= 0) { + uae_u16 s = before ? test_sr : r->sr; + uae_u16 s1 = test_regs.sr; + uae_u16 s2 = test_sr; + uae_u16 s3 = before ? s1 : last_registers.sr; + for (int i = 0; srbits[i].name; i++) { + if (i > 0) + *outbp++ = ' '; + uae_u16 mask = 1 << srbits[i].bit; + sprintf(outbp, "%s%c%d", srbits[i].name, (s3 & mask) != (s1 & mask) ? '!' : ((s1 & mask) != (s2 & mask) ? '*' : '='), (s & mask) != 0); + outbp += strlen(outbp); + } } if (!fpu_model) { @@ -823,7 +827,7 @@ static void hexdump(uae_u8 *p, int len) static uae_u8 last_exception[256]; static int last_exception_len; -static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum) +static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum, int sameexc) { int exclen = 0; uae_u8 *exc; @@ -840,15 +844,18 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum) if (cpu_lvl == 0) { if (excnum == 3) { // status (with undocumented opcode part) - exc[0] = opcode_memory[0]; - exc[1] = (opcode_memory[1] & 0xf0) | (*p++); + uae_u8 opcode0 = p[1]; + uae_u8 opcode1 = p[2]; + exc[0] = opcode0; + exc[1] = (opcode1 & ~0x1f) | p[0]; + p += 3; // access address v = opcode_memory_addr; p = restore_rel_ordered(p, &v); pl(exc + 2, v); // opcode - exc[6] = opcode_memory[0]; - exc[7] = opcode_memory[1]; + exc[6] = opcode0; + exc[7] = opcode1; // sr exc[8] = regs->sr >> 8; exc[9] = regs->sr; @@ -914,7 +921,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum) } else { exclen = last_exception_len; } - if (exclen == 0) + if (exclen == 0 || !sameexc) return p; if (memcmp(exc, sp, exclen)) { strcpy(outbp, "Exception stack frame mismatch:\n"); @@ -987,8 +994,12 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr) endinfo(); exit(0); } - if (ignore_errors) + if (ignore_errors) { + if (exc) { + p = validate_exception(&test_regs, p, exc, exc == cpuexc); + } break; + } if (exc == 0 && cpuexc == 4) { // successful complete generates exception 4 with matching PC if (last_registers.pc != test_regs.pc && dooutput) { @@ -999,7 +1010,7 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr) break; } if (exc) { - p = validate_exception(&test_regs, p, exc); + p = validate_exception(&test_regs, p, exc, exc == cpuexc); } if (exc != cpuexc) { addinfo(); @@ -1052,10 +1063,11 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr) // High 16 bit: ignore mask, low 16 bit: SR/CCR p = restore_value(p, &val, &size); test_ccrignoremask = ~(val >> 16); - if ((val & (sr_undefined_mask | test_ccrignoremask)) != (test_regs.sr & (sr_undefined_mask | test_ccrignoremask)) && !ignore_errors && !ignore_sr) { + + if ((val & (sr_undefined_mask & test_ccrignoremask)) != (test_regs.sr & (sr_undefined_mask & test_ccrignoremask)) && !ignore_errors && !ignore_sr) { addinfo(); if (dooutput) { - sprintf(outbp, "SR: expected %04x -> %04x but got %04x\n", test_sr, val & 0xffff, test_regs.sr & 0xffff); + sprintf(outbp, "SR: expected %04x -> %04x but got %04x (%04x)\n", test_sr, val & 0xffff, test_regs.sr & 0xffff, test_ccrignoremask); outbp += strlen(outbp); } errors++; @@ -1375,7 +1387,7 @@ static void process_test(uae_u8 *p) if (testexit()) { end_test(); - printf("\nAborted\n"); + printf("\nAborted (%ld)\n", testcnt); exit(0); } @@ -1465,6 +1477,15 @@ static int test_mnemo(const char *path, const char *opcode) sr_undefined_mask = 0xffff; } + if (lmem_rom >= 0 && (low_memory_size <= 0 || !low_memory_temp)) { + printf("lmem.dat required but it was not loaded or was missing.\n"); + return 0; + } + if (hmem_rom >= 0 && (high_memory_size <= 0 || !high_memory_temp)) { + printf("hmem.dat required but it was not loaded or was missing.\n"); + return 0; + } + if (!absallocated) { test_memory = allocate_absolute(test_memory_addr, test_memory_size); if (!test_memory) { @@ -1481,7 +1502,7 @@ static int test_mnemo(const char *path, const char *opcode) opcode_memory = test_memory + (opcode_memory_addr - test_memory_addr); size = test_memory_size; - load_file(path, "tmem.dat", test_memory, &size); + load_file(path, "tmem.dat", test_memory, &size, 1); if (size != test_memory_size) { printf("tmem.dat size mismatch\n"); exit(0); @@ -1505,8 +1526,8 @@ static int test_mnemo(const char *path, const char *opcode) } fread(data, 1, 4, f); if (gl(data) != starttimeid) { - printf("Test data file header mismatch\n"); - exit(0); + printf("Test data file header mismatch (old test data file?)\n"); + goto next; } fseek(f, 0, SEEK_END); test_data_size = ftell(f); @@ -1535,6 +1556,7 @@ static int test_mnemo(const char *path, const char *opcode) break; free(test_data); +next: filecnt++; } @@ -1618,33 +1640,28 @@ int main(int argc, char *argv[]) } else if (!_stricmp(s, "ccrmask")) { ccr_mask = 0; if (next) { - ccr_mask = getparamval(next); + ccr_mask = ~getparamval(next); i++; } } } low_memory_size = -1; - low_memory_temp = load_file(path, "lmem.dat", NULL, &low_memory_size); + low_memory_temp = load_file(path, "lmem.dat", NULL, &low_memory_size, 0); high_memory_size = -1; - high_memory_temp = load_file(path, "hmem.dat", NULL, &high_memory_size); - - if (low_memory_size < 0 || !low_memory_temp) { - printf("Couldn't allocate low memory\n"); - return 0; - } - if (high_memory_size < 0 || !high_memory_temp) { - printf("Couldn't allocate low memory\n"); - return 0; - } + high_memory_temp = load_file(path, "hmem.dat", NULL, &high_memory_size, 0); #ifndef M68K - low_memory = calloc(1, low_memory_size); - high_memory = calloc(1, high_memory_size); + if (low_memory_size > 0) + low_memory = calloc(1, low_memory_size); + if (high_memory_size > 0) + high_memory = calloc(1, high_memory_size); #endif - low_memory_back = calloc(1, low_memory_size); - high_memory_back = calloc(1, high_memory_size); + if (low_memory_size > 0) + low_memory_back = calloc(1, low_memory_size); + if (high_memory_size > 0) + high_memory_back = calloc(1, high_memory_size); if (!_stricmp(opcode, "all")) { DIR *d = opendir(path); -- 2.47.3