static int feature_loop_mode_register = -1;
static int feature_full_extension_format = 0;
static int feature_test_rounds = 2;
+static int feature_flag_mode = 0;
static uae_u32 feature_addressing_modes[2];
static int ad8r[2], pc8r[2];
fwrite(data, 1, 4, f);
pl(data, opcode_memory_start - test_memory_start);
fwrite(data, 1, 4, f);
- pl(data, (cpu_lvl << 16) | sr_undefined_mask | (addressing_mask == 0xffffffff ? 0x80000000 : 0));
+ pl(data, (cpu_lvl << 16) | sr_undefined_mask | (addressing_mask == 0xffffffff ? 0x80000000 : 0) | ((feature_flag_mode & 1) << 30));
fwrite(data, 1, 4, f);
pl(data, currprefs.fpu_model);
fwrite(data, 1, 4, f);
*isconstant = imm_special >= (1 << (4 + 5)) * 4 ? 0 : -1;
} else if (dp->mnemo == i_RTS) {
// RTS
+ imm_special++;
*isconstant = imm_special >= 256 ? 0 : -1;
}
v = generate_stack_return(imm_special);
for (;;) {
uae_u16 sr_mask = 0;
+ int maxflag = fpumode ? 256 : 32;
+ if (feature_flag_mode == 1) {
+ maxflag = fpumode ? 256 / 8 : 2;
+ }
+
if (extraccr & 1)
sr_mask |= 0x2000; // S
if (extraccr & 2)
}
// Test every CPU CCR or FPU SR/rounding/precision combination
- for (int ccr = 0; ccr < (fpumode ? 256 : 32); ccr++) {
+ for (int ccr = 0; ccr < maxflag; ccr++) {
bool skipped = false;
}
regs.fpiar = regs.pc;
// condition codes
- fpp_set_fpsr((ccr & 15) << 24);
- // precision and rounding
- fpp_set_fpcr((ccr >> 4) << 4);
+ if (feature_flag_mode == 0) {
+ fpp_set_fpsr((ccr & 15) << 24);
+ // precision and rounding
+ fpp_set_fpcr((ccr >> 4) << 4);
+ } else {
+ fpp_set_fpsr(((ccr & 1) ? 15 : 0) << 24);
+ // precision and rounding
+ fpp_set_fpcr((ccr >> 1) << 4);
+ }
+ }
+ if (feature_flag_mode == 0) {
+ regs.sr = ccr | sr_mask;
+ } else {
+ regs.sr = ((ccr & 1) ? 31 : 0) | sr_mask;
}
- regs.sr = ccr | sr_mask;
regs.usp = regs.regs[8 + 7];
regs.isp = test_memory_end - 0x80;
// copy user stack to super stack, for RTE etc support
if (feature_loop_mode) {
feature_loop_mode_register = 7;
}
+ feature_flag_mode = 0;
+ ini_getval(ini, INISECTION, _T("feature_flags_mode"), &feature_flag_mode);
feature_full_extension_format = 0;
if (currprefs.cpu_model >= 68020) {
; same options as above
feature_exception3_instruction=0
+; CCR/FPU status flags mode
+; 0 = all combinations (32 CCR loops, 256 FPU loops)
+; 1 = all zeros and all ones only (2 CCR loops, 32 FPU loops)
+feature_flags_mode=1
+
; SR extra mask.
; 0x8000 = T1
; 0x4000 = T0 (68020-68040)
static uae_u8 *absallocated;
static int cpu_lvl, fpu_model;
static uae_u16 sr_undefined_mask;
+static int flag_mode;
static int check_undefined_sr;
static uae_u32 cpustatearraystore[16];
static uae_u32 cpustatearraynew[] = {
if (extraccr & 8)
sr_mask |= 0x1000; // M
- int ccrmax = fpumode ? 256 : 32;
- for (int ccr = 0; ccr < ccrmax; ccr++) {
+ int maxccr = fpumode ? 256 : 32;
+ if (flag_mode) {
+ maxccr = fpumode ? 256 / 8 : 2;
+ }
+ for (int ccr = 0; ccr < maxccr; ccr++) {
regs.ssp = test_memory_addr + test_memory_size - 0x80;
regs.msp = test_memory_addr + test_memory_size;
memcpy((void*)regs.ssp, (void*)regs.regs[15], 0x20);
xmemcpy(&test_regs, ®s, sizeof(struct registers));
- test_regs.sr = ccr | sr_mask;
+ if (flag_mode == 0) {
+ test_regs.sr = ccr;
+ } else {
+ test_regs.sr = (ccr ? 31 : 0);
+ }
+ test_regs.sr |= sr_mask;
uae_u32 test_sr = test_regs.sr;
if (fpumode) {
- test_regs.fpsr = (ccr & 15) << 24;
- test_regs.fpcr = (ccr >> 4) << 4;
+ if (flag_mode == 0) {
+ test_regs.fpsr = (ccr & 15) << 24;
+ test_regs.fpcr = (ccr >> 4) << 4;
+ } else {
+ test_regs.fpsr = (ccr ? 15 : 0) << 24;
+ test_regs.fpcr = (ccr >> 1) << 4;
+ }
test_fpsr = test_regs.fpsr;
test_fpcr = test_regs.fpcr;
}
fread(data, 1, 4, f);
lvl = (gl(data) >> 16) & 15;
addressing_mask = (gl(data) & 0x80000000) ? 0xffffffff : 0x00ffffff;
- sr_undefined_mask = gl(data);
+ flag_mode = (gl(data) >> 30) & 1;
+ sr_undefined_mask = gl(data) & 0xffff;
fread(data, 1, 4, f);
fpu_model = gl(data);
fread(inst_name, 1, sizeof(inst_name) - 1, f);
UAE CPU Tester
-I finally wrote utility (this was my "Summer 2019" project) that can be used to verify operation of for example software emulated or FPGA 680x0 CPUs.
+I finally wrote utility (This was my "Summer 2019" project) that can be used to verify operation of for example software emulated or FPGA 680x0 CPUs.
It is based on UAE CPU core (gencpu generated special test core). All the CPU logic comes from UAE CPU core.
Verifies:
Tester compatibility (integer instructions only):
-68000: Complete.
+68000: Complete. (Bus errors are not yet verified)
68010: Not supported yet (Don't have real 68010, at least not yet).
68020: Almost complete (DIVS.W/DIVS.L V-flag weirdness).
68030: Same as 68020.
Use "test_low_memory_start"/"test_high_memory_start" and "test_low_memory_end"/"test_high_memory_end" to restrict range of memory region used for tests, for example if part of region is normally inaccessible.
-"test_memory_start"/"test_memory_size" is the main test memory, tested instruction and stack is located here. Must be at least 128k but larger the size, the easier it is for the generator to find effective addresses that hit test memory. This memory space must be free on target m68k hardware.
+"test_memory_start"/"test_memory_size" is the main test memory, tested instruction and stack is located here. Must be at least 128k but larger the size, the easier it is for the generator to find effective addresses that hit test memory. This memory space must be free on test target m68k hardware.
All 3 memory regions (if RAM) are filled with pseudo-random pattern and saved as "lmem.dat", "hmem.dat" and "tmem.dat"
Usage of Amiga m68k native test program:
-Copy all three dat files, test executable compiled for target platform (currently only Amiga is supported) and data file directories to target system.
+Copy all memory dat files, test executable compiled for target platform (currently only Amiga is supported) and data/<cpu model> contents to target system, keeping original directory structure.
cputest all = run all tests, in alphabetical order. Stops when mismatch is detected.
cputest tst.b = run tst.b tests only