mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
CPUTester update (68000 IPL timing, wait states, etc)
This commit is contained in:
parent
645df54f71
commit
819595132d
622
cputest.cpp
622
cputest.cpp
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,8 @@
|
||||
|
||||
.globl _allocate_absolute
|
||||
.globl _free_absolute
|
||||
.globl _allocate_blttemp
|
||||
.globl _free_blttemp
|
||||
.globl _touser
|
||||
.globl _tosuper
|
||||
.globl _testexit
|
||||
@ -44,12 +46,29 @@ uaefuncname:
|
||||
.asciz "uaelib_demux"
|
||||
|
||||
sync:
|
||||
move.l a1,d0
|
||||
lea 0xdff040,a1
|
||||
move.w #0x0400+0x200+0x0100,(a1)+ | BCD
|
||||
move.w #0x0000,(a1)+
|
||||
addq.l #4,a1
|
||||
move.l d0,(a1)+ | A
|
||||
move.l d0,(a1)+ | B
|
||||
move.l d0,(a1)+ | C
|
||||
move.l d0,(a1)+ | D
|
||||
move.b 0xdff006,d0
|
||||
beq.s sync
|
||||
cmp.b #0xff,d0
|
||||
beq.s sync
|
||||
cmp.b #0x38,d0
|
||||
beq.s sync
|
||||
cmp.b #0xfc,d0
|
||||
bcc.s sync
|
||||
cmp.b #0x34,d0
|
||||
bcs.s sync2
|
||||
cmp.b #0x39,d0
|
||||
bcs.s sync
|
||||
sync2:
|
||||
move.b 0xdff007,d0
|
||||
cmp.b #110,d0
|
||||
bcs.s sync2
|
||||
cmp.b #130,d0
|
||||
bcc.s sync2
|
||||
| above prevent wraparound between
|
||||
| dff004.w and dff006.w reads
|
||||
move.l 0xdff004,d0
|
||||
@ -70,9 +89,11 @@ _tosuper:
|
||||
move.l 4.w,a6
|
||||
jsr -0x78(a6) | Disable
|
||||
jsr -0x96(a6) | SuperState
|
||||
move.w 0xdff002,dmacon
|
||||
tst.l 8+1*4(sp)
|
||||
beq.s .keepdisplay
|
||||
move.w #0x0200,0xdff096
|
||||
move.w #0x7fff,0xdff096
|
||||
move.w #0x8000+0x0400+0x0200+0x0040,0xdff096
|
||||
.keepdisplay:
|
||||
move.w #0x2700,sr
|
||||
move.l (sp)+,a6
|
||||
@ -84,7 +105,10 @@ _touser:
|
||||
move.l 4.w,a6
|
||||
move.l 8(sp),d0
|
||||
jsr -0x9c(a6) | UserState
|
||||
move.w #0x8200,0xdff096
|
||||
move.w #0x7fff,0xdff096
|
||||
move.w dmacon,d0
|
||||
or.w #0x8000,d0
|
||||
move.w d0,0xdff096
|
||||
jsr -0x7e(a6) | Enable
|
||||
move.l (sp)+,a6
|
||||
rts
|
||||
@ -109,6 +133,24 @@ _allocate_absolute:
|
||||
move.l (sp)+,a6
|
||||
rts
|
||||
|
||||
_allocate_blttemp:
|
||||
move.l a6,-(sp)
|
||||
move.l 8(sp),d0
|
||||
move.l #65536+2,d1
|
||||
move.l 4.w,a6
|
||||
jsr -0xc6(a6) | AllocMem
|
||||
move.l (sp)+,a6
|
||||
rts
|
||||
_free_blttemp:
|
||||
move.l a6,-(sp)
|
||||
move.l 8(sp),a1
|
||||
move.l 12(sp),d0
|
||||
move.l 4.w,a6
|
||||
jsr -0xd2(a6) | FreeMem
|
||||
move.l (sp)+,a6
|
||||
rts
|
||||
|
||||
|
||||
| return CPU model (68000=0, 68010=1, 68020=2, 68030=3, 68040=4, 68060=5)
|
||||
_get_cpu_model:
|
||||
move.l 4.w,a0
|
||||
@ -151,4 +193,7 @@ illg:
|
||||
move.l a1,sp
|
||||
rte
|
||||
|
||||
dmacon:
|
||||
dc.l 0
|
||||
|
||||
.include "asm.S"
|
||||
|
||||
@ -43,7 +43,8 @@ S_TRACESTACK = S_TRACECNT+4
|
||||
S_CYCLES = S_TRACESTACK+12
|
||||
S_CYCLES2 = S_CYCLES+4
|
||||
S_CYCLEST = S_CYCLES2+4
|
||||
S_FPU = S_CYCLEST+4
|
||||
S_BLTTEMP = S_CYCLEST+4
|
||||
S_FPU = S_BLTTEMP+4
|
||||
S_FPIAR = S_FPU+8*12
|
||||
S_FPCR = S_FPIAR+4
|
||||
S_FPSR = S_FPCR+4
|
||||
@ -202,6 +203,7 @@ _execute_test000:
|
||||
move.w S_SR+2(a0),-(sp)
|
||||
move.l S_AREG+7*4(a0),a1
|
||||
move.l a1,USP
|
||||
move.l S_BLTTEMP(a0),a1
|
||||
bsr sync
|
||||
move.l d0,S_CYCLES2(a0)
|
||||
movem.l (a0),d0-d7/a0-a6
|
||||
@ -292,6 +294,7 @@ exception_trace000:
|
||||
move.w sr,-(sp)
|
||||
_cyclereg_address3:
|
||||
move.w CYCLEREG,cycles+4
|
||||
| pop SR and bsr.s exception_trace000
|
||||
addq.l #2+4,sp
|
||||
move.l a0,-(sp)
|
||||
move.l datapointer(pc),a0
|
||||
@ -364,16 +367,23 @@ _cyclereg_address4:
|
||||
bcs.s .okpc
|
||||
cmp.l #asm_end,2+4+2(sp)
|
||||
bhi.s .okpc
|
||||
| interrupt?
|
||||
cmp.l #_exceptiontable000+24*2,2(sp)
|
||||
bcs.s .okpc
|
||||
cmp.l #_exceptiontable000+(24+8)*2,2(sp)
|
||||
bcc.s .okpc
|
||||
| possibly IPL tester spurious interrupt
|
||||
| ignore it. Mark cycle count as invalid.
|
||||
#ifdef AMIGA
|
||||
move.w #0x0800,0xdff09c
|
||||
#endif
|
||||
move.w #0x7fff,0xdff09c
|
||||
| Interrupt exception interrupted trace?
|
||||
cmp.l #_exceptiontable000+(9-2)*2,2+4+2(sp)
|
||||
bne.s .notokpc
|
||||
| Store trace, copy trace PC/SR to interrupt PC/SR
|
||||
move.l a0,-(sp)
|
||||
move.l datapointer(pc),a0
|
||||
move.l 4+2+6+4+0(sp),S_TRACESTACK(a0)
|
||||
move.l 4+2+6+4+4(sp),S_TRACESTACK+4(a0)
|
||||
| set exception PC and SR same as Trace
|
||||
move.w 4+2+6+4+0(sp),4+2+4+0(sp)
|
||||
move.l 4+2+6+4+2(sp),4+2+4+2(sp)
|
||||
addq.l #1,S_TRACECNT(a0)
|
||||
move.l (sp)+,a0
|
||||
bra.s .okpc
|
||||
.notokpc:
|
||||
| Mark cycle count as invalid.
|
||||
move.l #0xffffffff,cycles
|
||||
addq.l #2+4,sp
|
||||
rte
|
||||
@ -404,7 +414,7 @@ _cyclereg_address4:
|
||||
cmp.w #24+8,d0
|
||||
bcc.s .nointerrupt
|
||||
#ifdef AMIGA
|
||||
move.w #0x0800,0xdff09c
|
||||
move.w #0x7fff,0xdff09c
|
||||
#endif
|
||||
.nointerrupt:
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
#define DATA_VERSION 23
|
||||
#define DATA_VERSION 24
|
||||
|
||||
#define CT_FPREG 0
|
||||
#define CT_DREG 0
|
||||
@ -55,13 +55,18 @@
|
||||
// MOVEA.L A0,A0
|
||||
// not NOP because on 68040 NOP generates T0 trace.
|
||||
#define NOP_OPCODE 0x2048
|
||||
#define REAL_NOP_OPCODE 0x4e71
|
||||
#define ILLG_OPCODE 0x4afc
|
||||
#define LM_OPCODE 0x42db
|
||||
|
||||
#define IPL_TEST_NOP1 0x4e71
|
||||
#define IPL_TEST_NOP2 0x4e71
|
||||
|
||||
#define IPL_TRIGGER_ADDR 0xdff030
|
||||
#define IPL_TRIGGER_ADDR_SIZE 2
|
||||
#define IPL_TRIGGER_DATA 0x100
|
||||
#define IPL_TRIGGER_DATA (0x100 | 0xCA)
|
||||
#define IPL_TRIGGER_SERPER 10
|
||||
#define INTERRUPT_CYCLES ((((IPL_TRIGGER_SERPER + 1) * 9) + (((IPL_TRIGGER_SERPER + 1) - 1) / 2) + 1 + 3 + 9) * 2)
|
||||
#define INTERRUPT_CYCLES ((((IPL_TRIGGER_SERPER + 1) * 9) + (((IPL_TRIGGER_SERPER + 1) - 1) / 2) + 1 + 3 + 9 + 0) * 2)
|
||||
#define IPL_TRIGGER_INTMASK 0x0800
|
||||
#define IPL_TEST_IPL_LEVEL 5
|
||||
#define IPL_BLTSIZE 0xdff058
|
||||
|
||||
@ -139,12 +139,18 @@ exceptions=
|
||||
; 2 = always all zeros and all ones only
|
||||
feature_flags_mode=1
|
||||
|
||||
; SR initial interrupt mask
|
||||
feature_initial_interrupt_mask=0
|
||||
|
||||
; SR min interrupt mask
|
||||
; Amiga: can be zero.
|
||||
; Atari ST: should be 4 or larger.
|
||||
; Skips all tests that would set lower interrupt mask.
|
||||
feature_min_interrupt_mask=0
|
||||
|
||||
; Initial active interrupt level, 0 to 6. (Amiga only)
|
||||
feature_initial_interrupt=0
|
||||
|
||||
; Interrupt test
|
||||
; 1 = interrupt request is set before test.
|
||||
; Tests all INTREQ bits one by one. Compatible with cycle count mode.
|
||||
@ -202,6 +208,11 @@ feature_full_extension_format=0
|
||||
feature_addressing_modes_src=
|
||||
feature_addressing_modes_dst=
|
||||
|
||||
; empty = all condition codes
|
||||
; T, F, HI, LS, CC etc.. select condition codes to generate. All others will be skipped.
|
||||
; Xcc instructions only.
|
||||
feature_condition_codes=
|
||||
|
||||
; Limit test instruction size
|
||||
; B = byte, W = word, L = long, empty = no size limit
|
||||
; FPU only: S = single, D = double, X = extended, P = packed
|
||||
@ -234,10 +245,27 @@ feature_sr_mask=0x8000
|
||||
[test=BASIC]
|
||||
cpu=68000-68010
|
||||
enabled=0
|
||||
verbose=0
|
||||
feature_sr_mask=0x8000
|
||||
feature_undefined_ccr=1
|
||||
mode=all
|
||||
|
||||
; interrupt timing test with waitstates
|
||||
[test=WIPL]
|
||||
cpu=68000-68010
|
||||
enabled=1
|
||||
verbose=0
|
||||
feature_undefined_ccr=1
|
||||
feature_interrupts=2
|
||||
feature_waitstates=2
|
||||
#feature_addressing_modes_src=dreg
|
||||
feature_condition_codes=
|
||||
# wait state mode requires use of chip ram
|
||||
test_memory_start=0xd0000
|
||||
test_memory_size=0x20000
|
||||
rnd_seed=10
|
||||
mode=btst.b
|
||||
|
||||
; interrupt timing test
|
||||
[test=IPL]
|
||||
cpu=68000-68010
|
||||
@ -245,17 +273,33 @@ enabled=1
|
||||
verbose=0
|
||||
feature_undefined_ccr=1
|
||||
feature_interrupts=2
|
||||
;feature_sr_mask=0x2100
|
||||
mode=all
|
||||
feature_sr_mask=0x2000
|
||||
#feature_addressing_modes_dst=apdi
|
||||
feature_condition_codes=pl
|
||||
rnd_seed=10
|
||||
mode=btst.b
|
||||
|
||||
; STOP/SR modification timing special test
|
||||
[test=SR]
|
||||
cpu=68000-68010
|
||||
enabled=0
|
||||
verbose=0
|
||||
feature_undefined_ccr=1
|
||||
feature_interrupts=1
|
||||
feature_initial_interrupt_mask=4
|
||||
feature_sr_mask=0x8000
|
||||
#mode=stop,eorsr.w,andsr.w,mvsr2.w,mv2sr.w
|
||||
mode=stop
|
||||
|
||||
; interrupt exception
|
||||
[test=IRQ]
|
||||
enabled=0
|
||||
verbose=0
|
||||
cpu=68000-68010
|
||||
feature_sr_mask=0x8000
|
||||
feature_interrupts=1
|
||||
feature_undefined_ccr=1
|
||||
mode=jsr,jmp,bsr,bcc,dbcc,nop,exg,swap,stop,mvsr2,mv2sr,andsr,eorsr,orsr
|
||||
mode=jsr,jmp,bsr,bcc,dbcc,nop,exg,swap,stop,mvsr2.w,mv2sr.w,andsr.w,eorsr.w,orsr.w
|
||||
min_opcode_test_rounds=100
|
||||
|
||||
; source EA address error
|
||||
|
||||
222
cputest/main.c
222
cputest/main.c
@ -49,6 +49,7 @@ struct registers
|
||||
uae_u32 tracecnt;
|
||||
uae_u16 tracedata[6];
|
||||
uae_u32 cycles, cycles2, cyclest;
|
||||
uae_u32 blttemp;
|
||||
|
||||
struct fpureg fpuregs[8];
|
||||
uae_u32 fpiar, fpcr, fpsr;
|
||||
@ -77,6 +78,8 @@ static uae_u8 *test_memory;
|
||||
static uae_u32 test_memory_addr, test_memory_end;
|
||||
static uae_u32 test_memory_size;
|
||||
static uae_u8 *test_data;
|
||||
#define BLT_TEMP_SIZE 8000
|
||||
static uae_u32 blt_data;
|
||||
static uae_u8 *safe_memory_start, *safe_memory_end;
|
||||
static short safe_memory_mode;
|
||||
static uae_u32 user_stack_memory, super_stack_memory;
|
||||
@ -136,6 +139,8 @@ static uae_u8 ccr_mask;
|
||||
static uae_u32 fpsr_ignore_mask;
|
||||
static uae_u32 addressing_mask = 0x00ffffff;
|
||||
static uae_u32 interrupt_mask;
|
||||
static short initial_interrupt_mask;
|
||||
static short initial_interrupt;
|
||||
static short loop_mode_jit, loop_mode_68010, loop_mode_cnt;
|
||||
static short instructionsize;
|
||||
static short disasm;
|
||||
@ -163,6 +168,8 @@ static uae_u16 main_intena;
|
||||
static int prealloc_test_data_size = 1001000;
|
||||
static int prealloc_gzip_size = 500000;
|
||||
static int prealloc;
|
||||
static uae_u8 *debug_item_data;
|
||||
static short debug_item_count;
|
||||
|
||||
#define SIZE_STORED_ADDRESS_OFFSET 6
|
||||
#define SIZE_STORED_ADDRESS 20
|
||||
@ -190,6 +197,13 @@ static uae_u8 *allocate_absolute(uae_u32 addr, uae_u32 size)
|
||||
static void free_absolute(uae_u32 addr, uae_u32 size)
|
||||
{
|
||||
}
|
||||
static uae_u8 *allocate_blttemp(uae_u32 size)
|
||||
{
|
||||
return calloc(1, size);
|
||||
}
|
||||
static void free_blttemp(uae_u32 addr, uae_u32 size)
|
||||
{
|
||||
}
|
||||
static void execute_test000(struct registers *regs)
|
||||
{
|
||||
}
|
||||
@ -245,6 +259,8 @@ static void xmemcpy(void *d, void *s, int size)
|
||||
|
||||
extern uae_u8 *allocate_absolute(uae_u32, uae_u32);
|
||||
extern void free_absolute(uae_u32, uae_u32);
|
||||
extern uae_u32 allocate_blttemp(uae_u32);
|
||||
extern void free_blttemp(uae_u32, uae_u32);
|
||||
extern void execute_test000(struct registers*);
|
||||
extern void execute_test010(struct registers *);
|
||||
extern void execute_test020(struct registers *);
|
||||
@ -454,7 +470,7 @@ static void start_test(void)
|
||||
error_vectors[i - 2] = p[i];
|
||||
}
|
||||
}
|
||||
if (interrupttest) {
|
||||
if (interrupttest || initial_interrupt_mask || initial_interrupt) {
|
||||
for (int i = 24; i < 24 + 8; i++) {
|
||||
p[i] = (uae_u32)(((uae_u32)&exceptiontable000) + (i - 2) * 2);
|
||||
if (exception_vectors) {
|
||||
@ -618,7 +634,7 @@ static int load_file_offset(FILE *f, int *foffsetp)
|
||||
unsigned char buf[4] = { 0 };
|
||||
fseek(f, *foffsetp, SEEK_SET);
|
||||
fread(buf, 1, sizeof(buf), f);
|
||||
if (buf[0] == 0xff && buf[1] == 0xff && buf[2] == 0xff && buf[3] == 0xff) {
|
||||
if (buf[0] == 0xaf && buf[1] == 'M' && buf[2] == 'R' && buf[3] == 'G') {
|
||||
fread(buf, 1, sizeof(buf), f);
|
||||
size = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3] << 0);
|
||||
if (size == 0) {
|
||||
@ -653,7 +669,7 @@ static uae_u8 *load_file(const char *path, const char *file, uae_u8 *p, int *siz
|
||||
}
|
||||
FILE *f = fopen(fname, "rb");
|
||||
if (f) {
|
||||
int gsize;
|
||||
int gsize = 0;
|
||||
if (foffsetp) {
|
||||
gsize = load_file_offset(f, foffsetp);
|
||||
if (gsize == 0) {
|
||||
@ -663,7 +679,7 @@ static uae_u8 *load_file(const char *path, const char *file, uae_u8 *p, int *siz
|
||||
*sizep = gsize;
|
||||
}
|
||||
}
|
||||
if (*sizep <= 0) {
|
||||
if (*sizep <= 0 || foffsetp == NULL) {
|
||||
fseek(f, 0, SEEK_END);
|
||||
gsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
@ -719,11 +735,17 @@ static uae_u8 *load_file(const char *path, const char *file, uae_u8 *p, int *siz
|
||||
printf("Decompressing '%s' (%d -> %d)\n", fname, gsize, size);
|
||||
callinflate(p, gzdata, inflatestack);
|
||||
*sizep = size;
|
||||
if (!prealloc_gzip) {
|
||||
free(gzbuf);
|
||||
}
|
||||
return p;
|
||||
} else if (candirect) {
|
||||
printf("Decompressing '%s' (%d -> %d)\n", fname, gsize, size);
|
||||
callinflate(p, gzdata, inflatestack);
|
||||
*sizep = size;
|
||||
if (!prealloc_gzip) {
|
||||
free(gzbuf);
|
||||
}
|
||||
return p;
|
||||
} else {
|
||||
unpack = calloc(1, size);
|
||||
@ -870,6 +892,11 @@ end:
|
||||
return p;
|
||||
}
|
||||
|
||||
static void endinfo_debug(uae_u8 *p)
|
||||
{
|
||||
printf("PTR %08x, %08x, count %d\n", debug_item_data, p, debug_item_count);
|
||||
}
|
||||
|
||||
static void pl(uae_u8 *p, uae_u32 v)
|
||||
{
|
||||
p[0] = v >> 24;
|
||||
@ -899,6 +926,7 @@ static uae_u8 *restore_fpvalue(uae_u8 *p, struct fpureg *fp)
|
||||
if ((v & CT_SIZE_MASK) != CT_SIZE_FPU) {
|
||||
end_test();
|
||||
printf("Expected CT_SIZE_FPU, got %02x\n", v);
|
||||
endinfo_debug(p);
|
||||
endinfo();
|
||||
exit(0);
|
||||
}
|
||||
@ -967,7 +995,8 @@ static uae_u8 *restore_value(uae_u8 *p, uae_u32 *vp, int *sizep)
|
||||
break;
|
||||
case CT_SIZE_FPU:
|
||||
end_test();
|
||||
printf("Unexpected CT_SIZE_FPU\n");
|
||||
printf("Unexpected CT_SIZE_FPU (%02x)\n", v);
|
||||
endinfo_debug(p);
|
||||
endinfo();
|
||||
exit(0);
|
||||
break;
|
||||
@ -1020,6 +1049,7 @@ static uae_u8 *restore_rel(uae_u8 *p, uae_u32 *vp, int nocheck)
|
||||
} else if ((val & addressing_mask) < test_memory_addr || (val & addressing_mask) >= test_memory_addr + test_memory_size) {
|
||||
end_test();
|
||||
printf("restore_rel CT_ABSOLUTE_LONG outside of test memory! %08x\n", v);
|
||||
endinfo_debug(p);
|
||||
endinfo();
|
||||
exit(0);
|
||||
}
|
||||
@ -1039,11 +1069,13 @@ static uae_u8 *restore_rel_ordered(uae_u8 *p, uae_u32 *vp)
|
||||
}
|
||||
|
||||
|
||||
static void validate_mode(uae_u8 mode, uae_u8 v)
|
||||
static void validate_mode(uae_u8 *p, uae_u8 v)
|
||||
{
|
||||
uae_u8 mode = p[0];
|
||||
if ((mode & CT_DATA_MASK) != v) {
|
||||
end_test();
|
||||
printf("CT_MEMWRITE expected but got %02X\n", mode);
|
||||
endinfo_debug(p);
|
||||
endinfo();
|
||||
exit(0);
|
||||
}
|
||||
@ -1066,7 +1098,7 @@ static uae_u8 *get_memory_addr(uae_u8 *p, uae_u8 **addrp)
|
||||
} else {
|
||||
addr = low_memory + offset;
|
||||
}
|
||||
validate_mode(p[0], CT_MEMWRITE);
|
||||
validate_mode(p, CT_MEMWRITE);
|
||||
*addrp = addr;
|
||||
return p;
|
||||
}
|
||||
@ -1083,7 +1115,7 @@ static uae_u8 *get_memory_addr(uae_u8 *p, uae_u8 **addrp)
|
||||
#else
|
||||
uae_u8 *addr = (uae_u8*)val;
|
||||
#endif
|
||||
validate_mode(p[0], CT_MEMWRITE);
|
||||
validate_mode(p, CT_MEMWRITE);
|
||||
*addrp = addr;
|
||||
return p;
|
||||
} else if (val >= test_memory_addr && val < test_memory_addr + test_memory_size) {
|
||||
@ -1092,12 +1124,13 @@ static uae_u8 *get_memory_addr(uae_u8 *p, uae_u8 **addrp)
|
||||
#else
|
||||
uae_u8 *addr = (uae_u8*)val;
|
||||
#endif
|
||||
validate_mode(p[0], CT_MEMWRITE);
|
||||
validate_mode(p, CT_MEMWRITE);
|
||||
*addrp = addr;
|
||||
return p;
|
||||
} else {
|
||||
end_test();
|
||||
printf("get_memory_addr CT_ABSOLUTE_LONG outside of test memory! %08x\n", val);
|
||||
endinfo_debug(p);
|
||||
endinfo();
|
||||
exit(0);
|
||||
}
|
||||
@ -1109,7 +1142,7 @@ static uae_u8 *get_memory_addr(uae_u8 *p, uae_u8 **addrp)
|
||||
val |= *p++;
|
||||
uae_s16 offset = (uae_s16)val;
|
||||
uae_u8 *addr = opcode_memory + offset;
|
||||
validate_mode(p[0], CT_MEMWRITE);
|
||||
validate_mode(p, CT_MEMWRITE);
|
||||
*addrp = addr;
|
||||
return p;
|
||||
}
|
||||
@ -1118,6 +1151,7 @@ static uae_u8 *get_memory_addr(uae_u8 *p, uae_u8 **addrp)
|
||||
default:
|
||||
end_test();
|
||||
printf("get_memory_addr unknown size %02x\n", v);
|
||||
endinfo_debug(p);
|
||||
endinfo();
|
||||
exit(0);
|
||||
}
|
||||
@ -1171,21 +1205,27 @@ static void restoreahist(void)
|
||||
static uae_u8 *restore_bytes(uae_u8 *mem, uae_u8 *p)
|
||||
{
|
||||
uae_u8 *addr = mem;
|
||||
uae_u16 v = *p++;
|
||||
addr += v >> 5;
|
||||
v &= 31;
|
||||
if (v == 31) {
|
||||
v = *p++;
|
||||
if (v == 0) {
|
||||
v = 256;
|
||||
uae_u16 len, offset;
|
||||
if (*p == 0xff) {
|
||||
p++;
|
||||
offset = *p++;
|
||||
len = *p++;
|
||||
if (len == 0) {
|
||||
len = 256;
|
||||
}
|
||||
} else {
|
||||
uae_u8 v = *p++;
|
||||
offset = v >> 5;
|
||||
len = v & 31;
|
||||
if (len == 0) {
|
||||
len = 32;
|
||||
}
|
||||
} else if (v == 0) {
|
||||
v = 32;
|
||||
}
|
||||
addr += offset;
|
||||
#ifndef _MSC_VER
|
||||
xmemcpy(addr, p, v);
|
||||
xmemcpy(addr, p, len);
|
||||
#endif
|
||||
p += v;
|
||||
p += len;
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -1230,6 +1270,7 @@ static uae_u8 *restore_memory(uae_u8 *p, int storedata)
|
||||
default:
|
||||
end_test();
|
||||
printf("Unknown restore_memory type!?\n");
|
||||
endinfo_debug(p);
|
||||
endinfo();
|
||||
exit(0);
|
||||
break;
|
||||
@ -1251,6 +1292,7 @@ static uae_u8 *restore_memory(uae_u8 *p, int storedata)
|
||||
default:
|
||||
end_test();
|
||||
printf("Unknown restore_memory type!?\n");
|
||||
endinfo_debug(p);
|
||||
endinfo();
|
||||
exit(0);
|
||||
break;
|
||||
@ -1271,6 +1313,7 @@ static uae_u8 *restore_edata(uae_u8 *p)
|
||||
default:
|
||||
end_test();
|
||||
printf("Unexpected CT_EDATA 0x%02x\n", *p);
|
||||
endinfo_debug(p);
|
||||
endinfo();
|
||||
exit(0);
|
||||
}
|
||||
@ -1283,6 +1326,7 @@ static uae_u8 *restore_data(uae_u8 *p, struct registers *r)
|
||||
if (v & CT_END) {
|
||||
end_test();
|
||||
printf("Unexpected end bit!? 0x%02x offset %d\n", v, p - test_data);
|
||||
endinfo_debug(p);
|
||||
endinfo();
|
||||
exit(0);
|
||||
}
|
||||
@ -1510,18 +1554,20 @@ struct srbit
|
||||
{
|
||||
char *name;
|
||||
int bit;
|
||||
int size;
|
||||
};
|
||||
static const struct srbit srbits[] = {
|
||||
{ "T1", 15 },
|
||||
{ "T0", 14 },
|
||||
{ "S", 13 },
|
||||
{ "M", 12 },
|
||||
{ "X", 4 },
|
||||
{ "N", 3 },
|
||||
{ "Z", 2 },
|
||||
{ "V", 1 },
|
||||
{ "C", 0 },
|
||||
{ NULL, 0 }
|
||||
{ "T1", 15, 1 },
|
||||
{ "T0", 14, 1 },
|
||||
{ "S", 13, 1 },
|
||||
{ "M", 12, 1 },
|
||||
{ "IM", 8, 3 },
|
||||
{ "X", 4, 1 },
|
||||
{ "N", 3, 1 },
|
||||
{ "Z", 2, 1 },
|
||||
{ "V", 1, 1 },
|
||||
{ "C", 0, 1 },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
// r = registers to output
|
||||
@ -1593,9 +1639,13 @@ static void out_regs(struct registers *r, struct registers *r1, struct registers
|
||||
for (int i = 0; srbits[i].name; i++) {
|
||||
if (i > 0)
|
||||
*outbp++ = ' ';
|
||||
uae_u16 mask = 1 << srbits[i].bit;
|
||||
uae_u16 mask = 0;
|
||||
for (int j = 0; j < srbits[i].size; j++) {
|
||||
mask <<= 1;
|
||||
mask |= 1 << srbits[i].bit;
|
||||
}
|
||||
sprintf(outbp, "%s%c%d", srbits[i].name,
|
||||
(s2 & mask) != (s3 & mask) ? '!' : ((s1 & mask) != (s2 & mask) ? '*' : '='), (s & mask) != 0);
|
||||
(s2 & mask) != (s3 & mask) ? '!' : ((s1 & mask) != (s2 & mask) ? '*' : '='), (s & mask) >> srbits[i].bit);
|
||||
outbp += strlen(outbp);
|
||||
}
|
||||
*outbp++ = '\n';
|
||||
@ -1782,19 +1832,19 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, short excnu
|
||||
}
|
||||
sprintf(outbp, "Expected trace exception (PC=%08x) but got none.\n", pc);
|
||||
outbp += strlen(outbp);
|
||||
*experr = 1;
|
||||
*experr |= 2;
|
||||
} else if (!(last_exception_extra & 0x80)) {
|
||||
// Trace stacked with group 2 exception
|
||||
if (!(sr & 0x2000) || (sr | 0x2000 | 0xc000) != (regs->sr | 0x2000 | 0xc000)) {
|
||||
sprintf(outbp, "Trace (%d stacked) SR mismatch: %04x != %04x\n", excnum, sr, regs->sr);
|
||||
outbp += strlen(outbp);
|
||||
*experr = 1;
|
||||
*experr |= 2;
|
||||
}
|
||||
uae_u32 retv = exceptiontableinuse + (excnum - 2) * 2;
|
||||
if (ret != retv) {
|
||||
sprintf(outbp, "Trace (%d stacked) PC mismatch: %08x != %08x\n", excnum, ret, retv);
|
||||
outbp += strlen(outbp);
|
||||
*experr = 1;
|
||||
*experr |= 2;
|
||||
}
|
||||
*extratrace = 1;
|
||||
} else {
|
||||
@ -1806,13 +1856,14 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, short excnu
|
||||
if ((vsr & test_ccrignoremask) != (sr & test_ccrignoremask)) {
|
||||
sprintf(outbp, "Trace (non-stacked) SR mismatch: %04x != %04x (PC=%08x)\n", sr, vsr, v);
|
||||
outbp += strlen(outbp);
|
||||
*experr = 1;
|
||||
*experr |= 2;
|
||||
}
|
||||
if (v != ret) {
|
||||
sprintf(outbp, "Trace (non-stacked) PC mismatch: %08x != %08x (SR=%04x)\n", ret, v, vsr);
|
||||
outbp += strlen(outbp);
|
||||
*experr = 1;
|
||||
*experr |= 2;
|
||||
}
|
||||
*extratrace = -1;
|
||||
}
|
||||
} else if (!last_exception_extra && excnum != 9) {
|
||||
if (regs->tracecnt > 0) {
|
||||
@ -1824,7 +1875,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, short excnu
|
||||
sprintf(outbp, "Exception %d also pending.\n", excnum);
|
||||
outbp += strlen(outbp);
|
||||
}
|
||||
*experr = 1;
|
||||
*experr |= 2;
|
||||
}
|
||||
} else if (last_exception_extra) {
|
||||
end_test();
|
||||
@ -2081,7 +2132,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, short excnu
|
||||
strcpy(outbp, "Got : ");
|
||||
outbp += strlen(outbp);
|
||||
hexdump(sp, exclen, 1);
|
||||
*experr = 1;
|
||||
*experr |= 1;
|
||||
}
|
||||
exception_stored = exclen;
|
||||
return p;
|
||||
@ -2200,6 +2251,18 @@ static int get_cycles_amiga(void)
|
||||
|
||||
static uae_u16 test_intena, test_intreq;
|
||||
|
||||
static const uae_u16 itable[] =
|
||||
{
|
||||
0,
|
||||
1 << 2,
|
||||
1 << 3,
|
||||
1 << 4,
|
||||
1 << 7,
|
||||
1 << 11,
|
||||
1 << 13,
|
||||
0
|
||||
};
|
||||
|
||||
static void set_interrupt(void)
|
||||
{
|
||||
if (interrupttest == 1) {
|
||||
@ -2221,6 +2284,13 @@ static void set_interrupt(void)
|
||||
*intena = 0x8000 | 0x4000 | IPL_TRIGGER_INTMASK;
|
||||
*intreq = IPL_TRIGGER_INTMASK;
|
||||
}
|
||||
if (initial_interrupt) {
|
||||
uae_u16 mask = itable[initial_interrupt];
|
||||
volatile uae_u16 *intena = (uae_u16*)0xdff09a;
|
||||
volatile uae_u16 *intreq = (uae_u16*)0xdff09c;
|
||||
*intena = 0x8000 | 0x4000 | mask;
|
||||
*intreq = 0x8000 | mask;
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_interrupt(void)
|
||||
@ -2305,7 +2375,7 @@ static int check_cycles(int exc, short extratrace, short extrag2w1, struct regis
|
||||
}
|
||||
gotcycles += cycles_adjust;
|
||||
|
||||
if (extratrace) {
|
||||
if (extratrace > 0) {
|
||||
expectedcycles += getexceptioncycles(9);
|
||||
}
|
||||
// address error during group 2 exception stacking (=odd exception vector)
|
||||
@ -2328,10 +2398,9 @@ static int check_cycles(int exc, short extratrace, short extrag2w1, struct regis
|
||||
}
|
||||
|
||||
if (0 || abs(gotcycles - expectedcycles) > cycles_range) {
|
||||
addinfo();
|
||||
sprintf(outbp, "Got %d cycles (%d + %d) but expected %d (%d + %d)\n",
|
||||
sprintf(outbp, "Got %d cycles (%d + %d) but expected %d (%d + %d) %08x\n",
|
||||
gotcycles, gotcycles - exceptioncycles, exceptioncycles,
|
||||
expectedcycles, expectedcycles - exceptioncycles, exceptioncycles);
|
||||
expectedcycles, expectedcycles - exceptioncycles, exceptioncycles, test_regs.cycles);
|
||||
outbp += strlen(outbp);
|
||||
return 0;
|
||||
}
|
||||
@ -2521,7 +2590,7 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr, st
|
||||
if (cpu_lvl > 0 && exc >= 2 && cpuexc010 != cpuexc) {
|
||||
if (dooutput) {
|
||||
sprintf(outbp, "Exception: vector number does not match vector offset! (%d <> %d) %d\n", exc, cpuexc010, cpuexc);
|
||||
experr = 1;
|
||||
experr |= 1;
|
||||
outbp += strlen(outbp);
|
||||
errflag |= 1 << 16;
|
||||
}
|
||||
@ -2589,7 +2658,11 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr, st
|
||||
hexdump(excp, excsize, 1);
|
||||
}
|
||||
}
|
||||
experr = 1;
|
||||
if ((experr & 2) && !(experr & 1) && extratrace) {
|
||||
sprintf(outbp, "Valid trace exception found\n");
|
||||
outbp += strlen(outbp);
|
||||
}
|
||||
experr |= 2;
|
||||
}
|
||||
errflag |= 1 << 16;
|
||||
}
|
||||
@ -2967,7 +3040,7 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr, st
|
||||
}
|
||||
#endif
|
||||
if (exc > 1) {
|
||||
if (!experr) {
|
||||
if (!(experr & 1)) {
|
||||
sprintf(outbp, "OK: exception %d ", exc);
|
||||
outbp += strlen(outbp);
|
||||
if (exception_stored) {
|
||||
@ -3002,7 +3075,7 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr, st
|
||||
|
||||
static void out_endinfo(void)
|
||||
{
|
||||
sprintf(outbp, "%u (%u/%u) ", testcnt, testcntsub, testcntsubmax);
|
||||
sprintf(outbp, "%u (%u/%u/%u) ", testcnt, testcntsub, testcntsubmax, interrupt_delay_cnt);
|
||||
outbp += strlen(outbp);
|
||||
sprintf(outbp, "S=%d", supercnt);
|
||||
outbp += strlen(outbp);
|
||||
@ -3104,7 +3177,7 @@ static void process_test(uae_u8 *p)
|
||||
|
||||
short doopcodeswap = 1;
|
||||
|
||||
if (interrupttest >= 1) {
|
||||
if (interrupttest >= 2) {
|
||||
doopcodeswap = 0;
|
||||
}
|
||||
|
||||
@ -3113,12 +3186,16 @@ static void process_test(uae_u8 *p)
|
||||
cur_regs.endpc = endpc;
|
||||
cur_regs.pc = startpc;
|
||||
|
||||
debug_item_data = p;
|
||||
debug_item_count = 0;
|
||||
for (;;) {
|
||||
uae_u8 v = *p;
|
||||
if (v == CT_END_INIT || v == CT_END_FINISH)
|
||||
break;
|
||||
p = restore_data(p, &cur_regs);
|
||||
debug_item_count++;
|
||||
}
|
||||
debug_item_count = -1;
|
||||
if (*p == CT_END_FINISH)
|
||||
break;
|
||||
p++;
|
||||
@ -3213,6 +3290,7 @@ static void process_test(uae_u8 *p)
|
||||
test_regs.pc = startpc;
|
||||
test_regs.cyclest = 0xffffffff;
|
||||
test_regs.fpeaset = 0;
|
||||
test_regs.blttemp = blt_data;
|
||||
|
||||
#ifdef M68K
|
||||
if (stackcopysize > 0)
|
||||
@ -3223,7 +3301,7 @@ static void process_test(uae_u8 *p)
|
||||
} else {
|
||||
test_regs.sr = (ccr & 1) ? 31 : 0;
|
||||
}
|
||||
test_regs.sr |= sr_mask | (interrupt_mask << 8);
|
||||
test_regs.sr |= sr_mask | (initial_interrupt_mask << 8);
|
||||
if (fpumode) {
|
||||
test_regs.fpcr = 0;
|
||||
test_regs.fpsr = 0;
|
||||
@ -3347,7 +3425,7 @@ static void process_test(uae_u8 *p)
|
||||
|
||||
|
||||
#ifdef AMIGA
|
||||
if (interrupttest) {
|
||||
if (interrupttest || initial_interrupt_mask || initial_interrupt) {
|
||||
set_interrupt();
|
||||
}
|
||||
#endif
|
||||
@ -3365,7 +3443,7 @@ static void process_test(uae_u8 *p)
|
||||
}
|
||||
|
||||
#ifdef AMIGA
|
||||
if (interrupttest) {
|
||||
if (interrupttest || initial_interrupt_mask || initial_interrupt) {
|
||||
clear_interrupt();
|
||||
}
|
||||
#endif
|
||||
@ -3494,8 +3572,12 @@ end:
|
||||
|
||||
static void freestuff(void)
|
||||
{
|
||||
if (test_memory && test_memory_addr)
|
||||
if (test_memory && test_memory_addr) {
|
||||
free_absolute(test_memory_addr, test_memory_size);
|
||||
}
|
||||
if (blt_data) {
|
||||
free_blttemp(blt_data, BLT_TEMP_SIZE);
|
||||
}
|
||||
#ifdef WAITEXIT
|
||||
getchar();
|
||||
#endif
|
||||
@ -3546,15 +3628,20 @@ static int test_mnemo(const char *opcode)
|
||||
test_memory_end = test_memory_addr + test_memory_size;
|
||||
opcode_memory_addr = read_u32(headerfile, &headoffset);
|
||||
opcode_memory = (uae_u8*)opcode_memory_addr;
|
||||
uae_u32 lvl_mask = read_u32(headerfile, &headoffset);
|
||||
lvl = (lvl_mask >> 16) & 15;
|
||||
interrupt_mask = (lvl_mask >> 20) & 7;
|
||||
addressing_mask = (lvl_mask & 0x80000000) ? 0xffffffff : 0x00ffffff;
|
||||
interrupttest = (lvl_mask >> 26) & 3;
|
||||
sr_undefined_mask = lvl_mask & 0xffff;
|
||||
safe_memory_mode = (lvl_mask >> 23) & 7;
|
||||
loop_mode_jit = (lvl_mask >> 28) & 1;
|
||||
loop_mode_68010 = (lvl_mask >> 29) & 1;
|
||||
v = read_u32(headerfile, &headoffset);
|
||||
lvl = (v >> 16) & 15;
|
||||
interrupt_mask = (v >> 20) & 7;
|
||||
addressing_mask = (v & 0x80000000) ? 0xffffffff : 0x00ffffff;
|
||||
interrupttest = (v >> 26) & 3;
|
||||
sr_undefined_mask = v & 0xffff;
|
||||
safe_memory_mode = (v >> 23) & 7;
|
||||
loop_mode_jit = (v >> 28) & 1;
|
||||
loop_mode_68010 = (v >> 29) & 1;
|
||||
v = read_u32(headerfile, &headoffset);
|
||||
initial_interrupt_mask = v & 7;
|
||||
initial_interrupt = (v >> 3) & 7;
|
||||
v = read_u32(headerfile, &headoffset);
|
||||
v = read_u32(headerfile, &headoffset);
|
||||
fpu_model = read_u32(headerfile, &headoffset);
|
||||
test_low_memory_start = read_u32(headerfile, &headoffset);
|
||||
test_low_memory_end = read_u32(headerfile, &headoffset);
|
||||
@ -3666,6 +3753,12 @@ static int test_mnemo(const char *opcode)
|
||||
}
|
||||
}
|
||||
|
||||
blt_data = allocate_blttemp(BLT_TEMP_SIZE);
|
||||
if (!blt_data) {
|
||||
printf("blt_temp failed to allocated.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int otestcnt = -1;
|
||||
for (;;) {
|
||||
if (otestcnt != testcnt) {
|
||||
@ -3739,6 +3832,11 @@ static int test_mnemo(const char *opcode)
|
||||
}
|
||||
}
|
||||
|
||||
if (blt_data) {
|
||||
free_blttemp(blt_data, BLT_TEMP_SIZE);
|
||||
blt_data = 0;
|
||||
}
|
||||
|
||||
if (errorcnt == 0) {
|
||||
outbp = outbuffer;
|
||||
out_endinfo();
|
||||
|
||||
@ -10,13 +10,14 @@
|
||||
#include "cpummu030.h"
|
||||
|
||||
cpuop_func *loop_mode_table[65536];
|
||||
int cpuipldelay2, cpuipldelay4;
|
||||
|
||||
void my_trim(TCHAR *s)
|
||||
{
|
||||
int len;
|
||||
while (s[0] != '\0' && _tcscspn(s, _T("\t \r\n")) == 0)
|
||||
memmove(s, s + 1, (_tcslen(s + 1) + 1) * sizeof(TCHAR));
|
||||
len = _tcslen(s);
|
||||
memmove(s, s + 1, (uaetcslen(s + 1) + 1) * sizeof(TCHAR));
|
||||
len = uaetcslen(s);
|
||||
while (len > 0 && _tcscspn(s + len - 1, _T("\t \r\n")) == 0)
|
||||
s[--len] = '\0';
|
||||
}
|
||||
@ -40,8 +41,8 @@ TCHAR *buf_out(TCHAR *buffer, int *bufsize, const TCHAR *format, ...)
|
||||
return 0;
|
||||
count = _vsntprintf(buffer, (*bufsize) - 1, format, parms);
|
||||
va_end(parms);
|
||||
*bufsize -= _tcslen(buffer);
|
||||
return buffer + _tcslen(buffer);
|
||||
*bufsize -= uaetcslen(buffer);
|
||||
return buffer + uaetcslen(buffer);
|
||||
}
|
||||
|
||||
void fpux_restore(int *v)
|
||||
@ -52,10 +53,11 @@ void fp_init_native(void)
|
||||
wprintf(_T("fp_init_native called!"));
|
||||
exit(0);
|
||||
}
|
||||
void fp_init_native_80(void)
|
||||
bool fp_init_native_80(void)
|
||||
{
|
||||
wprintf(_T("fp_init_native_80 called!"));
|
||||
exit(0);
|
||||
return false;
|
||||
}
|
||||
void init_fpucw_x87(void)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user