static int feature_min_interrupt_mask = 0;
static int feature_loop_mode = 0;
static int feature_loop_mode_register = -1;
+static int feature_loop_mode_68010 = 0;
static int feature_full_extension_format = 0;
static int feature_test_rounds = 2;
static int feature_flag_mode = 0;
static uae_u8 *opcode_memory;
static uae_u8 *storage_buffer;
static char inst_name[16+1];
+static int storage_buffer_watermark_size;
static int storage_buffer_watermark;
-static int max_storage_buffer = 1000000;
+static int max_storage_buffer;
static bool out_of_test_space;
static uaecptr out_of_test_space_addr;
static int ahcnt_current, ahcnt_written;
static int noaccesshistory = 0;
-#define MAX_ACCESSHIST 128
+#define MAX_ACCESSHIST 16000
static struct accesshistory ahist[MAX_ACCESSHIST];
static int is_superstack_use_required(void)
uae_u16 opc = regs.ir;
uae_u16 opw1 = (opcode_memory[2] << 8) | (opcode_memory[3] << 0);
uae_u16 opw2 = (opcode_memory[4] << 8) | (opcode_memory[5] << 0);
- if (opc == 0xe3d5
- //&& opw1 == 0x0000
+ if (opc == 0x40ef
+ && opw1 == 0x64fc
//&& opw2 == 0x4afc
)
printf("");
regs.write_buffer = 0xf00d;
exception_extra_frame_size = 0;
cpu_cycles = 0;
+ regs.loop_mode = 0;
int cnt = (feature_loop_mode + 1) * 2;
if (multi_mode)
abort();
}
+ if (!regs.loop_mode)
+ regs.ird = opc;
+
+ if (currprefs.cpu_model >= 68020) {
+ regs.ir = get_word_test(regs.pc + 0);
+ regs.irc = get_word_test(regs.pc + 2);
+ }
+ opc = regs.ir;
}
testing_active = 0;
if (dp->clev > cpu_lvl && lookup->mnemo != i_ILLG)
continue;
+ if (feature_loop_mode_68010) {
+ if (!opcode_loop_mode(opcode))
+ continue;
+ }
+
target_ea[0] = target_ea_bak[0];
target_ea[1] = target_ea_bak[1];
target_ea[2] = target_ea_bak[2];
if (feature_loop_mode) {
feature_loop_mode_register = 7;
}
+ feature_loop_mode_68010 = 0;
+ ini_getvalx(ini, sections, _T("feature_loop_mode_68010"), &feature_loop_mode_68010);
+
feature_flag_mode = 0;
ini_getvalx(ini, sections, _T("feature_flags_mode"), &feature_flag_mode);
feature_usp = 0;
if (ini_getvalx(ini, sections, _T("test_high_memory_end"), &v))
test_high_memory_end = v;
- if (addressing_mask == 0xffffffff && test_high_memory_end <= 0x01000000) {
+ if ((addressing_mask == 0xffffffff && test_high_memory_end <= 0x01000000) || test_high_memory_start == 0xffffffff) {
test_high_memory_start = 0xffffffff;
test_high_memory_end = 0xffffffff;
+ high_memory_size = 0xffffffff;
}
test_memory = (uae_u8 *)calloc(1, test_memory_size + EXTRA_RESERVED_SPACE);
user_stack_memory_use |= 1;
}
+ storage_buffer_watermark_size = 200000;
+ max_storage_buffer = 1000000;
+ ini_getvalx(ini, sections, _T("buffer_size"), &max_storage_buffer);
+ ini_getvalx(ini, sections, _T("watermark"), &storage_buffer_watermark_size);
+ max_storage_buffer += storage_buffer_watermark_size;
+
low_memory_size = test_low_memory_end;
if (low_memory_size < 0x8000)
low_memory_size = 0x8000;
save_memory(path, _T("tmem.dat"), test_memory_temp, test_memory_size);
- storage_buffer = (uae_u8 *)calloc(max_storage_buffer, 1);
+ storage_buffer = (uae_u8 *)calloc(max_storage_buffer + storage_buffer_watermark_size, 1);
// FMOVEM stores can use lots of memory
- storage_buffer_watermark = max_storage_buffer - 70000;
+ storage_buffer_watermark = max_storage_buffer - storage_buffer_watermark_size;
for (int i = 0; i < 256; i++) {
int j;
cpufunctbl[opcode] = f;
memcpy(&cpudatatbl[opcode], &cpudatatbl[idx], sizeof(struct cputbl_data));
}
+
+ if (opcode_loop_mode(opcode)) {
+ loop_mode_table[opcode] = cpufunctbl[opcode];
+ }
+
}
x_get_long = get_long_test;
int __cdecl main(int argc, char *argv[])
{
- const struct cputbl *tbl = NULL;
- TCHAR path[1000], *vs;
- int v;
-
struct ini_data *ini = ini_load(_T("cputestgen.ini"), false);
if (!ini) {
wprintf(_T("Couldn't open cputestgen.ini"));
static char inst_name[16+1];
#ifndef M68K
static char outbuffer[40000];
+static char outbuffer2[40000];
#else
static char outbuffer[4000];
+static char outbuffer2[4000];
#endif
static char tmpbuffer[1024];
static char path[256];
static uae_u32 interrupt_mask;
static short disasm;
static short basicexcept;
+static short excskipccr;
static short askifmissing;
static short nextall;
static int exitcnt;
}
}
-static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum, int *gotexcnum, int *experr, int *extratrace)
+static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, short excnum, short *gotexcnum, short *experr, short *extratrace)
{
int exclen = 0;
uae_u8 *exc;
case 11:
return 38;
case 5:
- return 42;
+ return 38;
case 6:
return 44;
case 7:
// test_reg: registers used during execution of test code, also modified by test code.
// last_registers: registers after modifications from data files. Test ok if test_reg == last_registers.
-static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr)
+static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr)
{
uae_u8 regs_changed[16] = { 0 };
uae_u8 regs_fpuchanged[8] = { 0 };
uae_u8 sr_changed = 0, pc_changed = 0;
uae_u8 fpiar_changed = 0, fpsr_changed = 0, fpcr_changed = 0;
- int exc = -1;
+ short exc = -1;
for (int i = 0; i < 16; i++) {
if (last_registers.regs[i] != test_regs.regs[i]) {
if (*p == CT_END_SKIP)
return p + 1;
- int experr = 0;
+ short experr = 0;
int errflag = 0;
int errflag_orig = 0;
- int extratrace = 0;
+ short extratrace = 0;
+ short exceptionnum = 0;
uae_u8 *outbp_old = outbp;
exception_stored = 0;
uae_u8 v = *p;
if (v & CT_END) {
exc = v & CT_EXCEPTION_MASK;
- int cpuexc = test_regs.exc & 65535;
- int cpuexc010 = test_regs.exc010 & 65535;
+ short cpuexc = test_regs.exc & 65535;
+ short cpuexc010 = test_regs.exc010 & 65535;
p++;
if ((v & CT_END_INIT) == CT_END_INIT) {
end_test();
exit(0);
}
if (cpu_lvl > 0 && exc >= 2 && cpuexc010 != cpuexc) {
- addinfo();
if (dooutput) {
sprintf(outbp, "Exception: vector number does not match vector offset! (%d <> %d)\n", exc, cpuexc010);
experr = 1;
if (exc) {
p = validate_exception(&test_regs, p, exc, &cpuexc, &experr, &extratrace);
}
- errflag_orig = errflag;
+ errflag_orig |= errflag;
errflag = 0;
break;
}
p = validate_exception(&test_regs, p, exc, &cpuexc, &experr, &extratrace);
if (experr) {
errflag |= 1 << 16;
+ errflag_orig |= errflag;
}
if (basicexcept && (cpuexc == 2 || cpuexc == 3)) {
- errflag_orig = errflag;
errflag &= ~(1 << 0);
errflag &= ~(1 << 7);
}
+ exceptionnum = cpuexc;
}
if (exc != cpuexc && exc >= 2) {
- addinfo();
if (dooutput) {
if (cpuexc == 4 && last_registers.pc == test_regs.pc) {
sprintf(outbp, "Exception: expected %d but got no exception.\n", exc);
}
break;
}
- int mode = v & CT_DATA_MASK;
+ short mode = v & CT_DATA_MASK;
if (mode < CT_AREG + 8 && (v & CT_SIZE_MASK) != CT_SIZE_FPU) {
uae_u32 val = last_registers.regs[mode];
int size;
p = restore_value(p, &val, &size);
if (val != test_regs.regs[mode] && !ignore_errors) {
- addinfo();
if (dooutput) {
sprintf(outbp, "%c%d: expected %08x but got %08x\n", mode < CT_AREG ? 'D' : 'A', mode & 7, val, test_regs.regs[mode]);
outbp += strlen(outbp);
struct fpureg val;
p = restore_fpvalue(p, &val);
if (memcmp(&val, &test_regs.fpuregs[mode], sizeof(struct fpureg)) && !ignore_errors) {
- addinfo();
if (dooutput) {
sprintf(outbp, "FP%d: expected %04x-%08x%08x but got %04x-%08x%08x\n", mode,
val.exp, val.m[0], val.m[1],
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) {
- addinfo();
if (dooutput) {
sprintf(outbp, "SR: expected %04x -> %04x but got %04x", test_sr & 0xffff, val & 0xffff, test_regs.sr & 0xffff);
outbp += strlen(outbp);
errflag |= 1 << 2;
errflag |= 1 << 7;
}
+ // SR check
uae_u16 mask = test_ccrignoremask & 0xff00;
if ((val & (sr_undefined_mask & mask)) == (test_regs.sr & (sr_undefined_mask & mask))) {
errflag &= ~(1 << 2);
}
+ // CCR check
mask = test_ccrignoremask & 0x00ff;
if ((val & (sr_undefined_mask & mask)) == (test_regs.sr & (sr_undefined_mask & mask))) {
errflag &= ~(1 << 7);
int size;
p = restore_value(p, &val, &size);
if (val != test_regs.fpcr && !ignore_errors) {
- addinfo();
if (dooutput) {
sprintf(outbp, "FPCR: expected %08x -> %08x but got %08x\n", test_fpcr, val, test_regs.fpcr);
outbp += strlen(outbp);
int size;
p = restore_value(p, &val, &size);
if (val != test_regs.fpsr && !ignore_errors) {
- addinfo();
if (dooutput) {
sprintf(outbp, "FPSR: expected %08x -> %08x but got %08x\n", test_fpsr, val, test_regs.fpsr);
outbp += strlen(outbp);
uae_u32 val = last_registers.fpiar;
p = restore_rel(p, &val, 0);
if (val != test_regs.fpiar && !ignore_errors) {
- addinfo();
if (dooutput) {
sprintf(outbp, "FPIAR: expected %08x but got %08x\n", val, test_regs.fpiar);
outbp += strlen(outbp);
case 0:
mval = addr[0];
if (mval != val && !ignore_errors) {
- addinfo();
if (dooutput) {
sprintf(outbp, "Memory byte write: address %08x, expected %02x but got %02x\n", (uae_u32)addr, val, mval);
outbp += strlen(outbp);
case 1:
mval = (addr[0] << 8) | (addr[1]);
if (mval != val && !ignore_errors) {
- addinfo();
if (dooutput) {
sprintf(outbp, "Memory word write: address %08x, expected %04x but got %04x\n", (uae_u32)addr, val, mval);
outbp += strlen(outbp);
case 2:
mval = gl(addr);
if (mval != val && !ignore_errors) {
- addinfo();
if (dooutput) {
sprintf(outbp, "Memory long write: address %08x, expected %08x but got %08x\n", (uae_u32)addr, val, mval);
outbp += strlen(outbp);
if (!ignore_sr) {
for (int i = 0; i < 16; i++) {
if (regs_changed[i]) {
- addinfo();
if (dooutput) {
sprintf(outbp, "%c%d: modified %08x -> %08x but expected no modifications\n", i < 8 ? 'D' : 'A', i & 7, last_registers.regs[i], test_regs.regs[i]);
outbp += strlen(outbp);
}
}
if (sr_changed) {
- addinfo();
if (dooutput) {
sprintf(outbp, "SR: modified %04x -> %04x but expected no modifications\n", last_registers.sr & 0xffff, test_regs.sr & 0xffff);
outbp += strlen(outbp);
}
for (int i = 0; i < 8; i++) {
if (regs_fpuchanged[i]) {
- addinfo();
if (dooutput) {
sprintf(outbp, "FP%d: modified %04x-%08x%08x -> %04x-%08x%08x but expected no modifications\n", i,
last_registers.fpuregs[i].exp, last_registers.fpuregs[i].m[0], last_registers.fpuregs[i].m[1],
}
}
if (fpsr_changed) {
- addinfo();
if (dooutput) {
sprintf(outbp, "FPSR: modified %08x -> %08x but expected no modifications\n", last_registers.fpsr, test_regs.fpsr);
outbp += strlen(outbp);
errflag |= 1 << 3;
}
if (fpcr_changed) {
- addinfo();
if (dooutput) {
sprintf(outbp, "FPCR: modified %08x -> %08x but expected no modifications\n", last_registers.fpcr, test_regs.fpcr);
outbp += strlen(outbp);
errflag |= 1 << 4;
}
if (fpiar_changed) {
- addinfo();
if (dooutput) {
sprintf(outbp, "FPIAR: modified %08x -> %08x but expected no modifications\n", last_registers.fpiar, test_regs.fpiar);
outbp += strlen(outbp);
}
}
}
+ errflag_orig |= errflag;
+ }
+
+ // if excskipccr + bus, address, divide by zero or chk + only CCR mismatch detected: clear error
+ if (excskipccr && errflag == (1 << 7) && (exceptionnum == 2 || exceptionnum == 3 || exceptionnum == 5 || exceptionnum == 6)) {
+ errflag = 0;
}
+
if (errflag && dooutput) {
+ outbp = outbuffer;
addinfo();
+ strcpy(outbp, outbuffer2);
if (!fpu_model) {
strcat(outbp, "Registers before:\n");
outbp += strlen(outbp);
static void process_test(uae_u8 *p)
{
- outbp = outbuffer;
+ outbp = outbuffer2;
outbp[0] = 0;
infoadded = 0;
errors = 0;
for (;;) {
#ifndef M68K
- outbp = outbuffer;
+ outbp = outbuffer2;
#endif
regs.endpc = endpc;
} else {
- int ignore_errors = 0;
- int ignore_sr = 0;
+ short ignore_errors = 0;
+ short ignore_sr = 0;
if ((ccr_mask & ccr) || (ccr == 0)) {
printf("-ccrmask = ignore CCR bits that are not set.\n");
printf("-nodisasm = do not disassemble failed test.\n");
printf("-basicexc = do only basic checks when exception is 2 or 3.\n");
+ printf("-excskipccr = ignore CCR if DivByZero, CHK, Address/Bus error exception.\n");
printf("-askifmissing = ask for new path if dat file is missing.\n");
printf("-exit n = exit after n tests.\n");
printf("-cycles [range adjust] = check cycle counts.\n");
disasm = 0;
} else if (!_stricmp(s, "-basicexc")) {
basicexcept = 1;
+ } else if (!_stricmp(s, "-excskipccr")) {
+ excskipccr = 1;
} else if (!_stricmp(s, "-askifmissing")) {
askifmissing = 1;
} else if (!_stricmp(s, "-next")) {