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;
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);
}
{
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)
test_exception = n;
test_exception_3_inst = 0;
test_exception_addr = m68k_getpci();
+ test_exception_opcode = -1;
doexcstack();
}
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
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)
test_exception_3_inst = i;
test_exception_3_w = w;
test_exception_addr = addr;
+ test_exception_opcode = opcode;
doexcstack();
}
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.
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);
{
case i_STOP:
case i_MV2SR:
- case i_MVSR2:
return 1;
}
return 0;
// 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);
}
if (opc == 0xf228)
printf("");
- if (subtest_count == 3136)
+ if (subtest_count == 1537)
printf("");
if (regs.sr & 0x2000)
prev_s_cnt++;
- if (subtest_count == 928)
+ if (subtest_count == 1536)
printf("");
execute_ins(opc, pc - 2, branch_target);
// 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]++;
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;
}
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);
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) {
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;
*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);
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) {
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;
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;
} 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");
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) {
break;
}
if (exc) {
- p = validate_exception(&test_regs, p, exc);
+ p = validate_exception(&test_regs, p, exc, exc == cpuexc);
}
if (exc != cpuexc) {
addinfo();
// 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++;
if (testexit()) {
end_test();
- printf("\nAborted\n");
+ printf("\nAborted (%ld)\n", testcnt);
exit(0);
}
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) {
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);
}
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);
break;
free(test_data);
+next:
filecnt++;
}
} 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);