From: notaz Date: Sun, 16 Jun 2013 16:48:40 +0000 (+0300) Subject: tests and tools from PicoDrive X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=cyclone68000.git;a=commitdiff_plain;h=a6905b4de17f4d772c7742065f2863b77ddf0b31;hp=e10b1284d3c6dcbd9790c1a9cd7560907b9692ff tests and tools from PicoDrive --- diff --git a/tests/crash_cyclone.bin b/tests/crash_cyclone.bin new file mode 100644 index 0000000..dfa0276 Binary files /dev/null and b/tests/crash_cyclone.bin differ diff --git a/tests/test_abcd.bin b/tests/test_abcd.bin new file mode 100644 index 0000000..fe25040 Binary files /dev/null and b/tests/test_abcd.bin differ diff --git a/tests/test_cmpm.bin b/tests/test_cmpm.bin new file mode 100644 index 0000000..e761857 Binary files /dev/null and b/tests/test_cmpm.bin differ diff --git a/tests/test_div.bin b/tests/test_div.bin new file mode 100644 index 0000000..6e9cb77 Binary files /dev/null and b/tests/test_div.bin differ diff --git a/tests/test_misc2_gen.c b/tests/test_misc2_gen.c new file mode 100644 index 0000000..108156b --- /dev/null +++ b/tests/test_misc2_gen.c @@ -0,0 +1,119 @@ +#include +#include +#include + + +static FILE *f; + +#define bswap16(x) (x=(unsigned short)((x<<8)|(x>>8))) +#define bswap32(x) (x=((x<<24)|((x<<8)&0xff0000)|((x>>8)&0x00ff00)|((unsigned)x>>24))) + +static void write_op(unsigned short op, unsigned short word0, unsigned short word1, unsigned short word2) +{ + bswap16(op); + bswap16(word0); + bswap16(word1); + bswap16(word2); + + fwrite(&op, 1, sizeof(op), f); + fwrite(&word0, 1, sizeof(word0), f); + fwrite(&word1, 1, sizeof(word1), f); + fwrite(&word2, 1, sizeof(word2), f); +} + +static void write32(unsigned int a) +{ + bswap32(a); + fwrite(&a, 1, sizeof(a), f); +} + +static int op_check(unsigned short op) +{ + if ((op&0xf000) == 0x6000) return 0; // Bxx + if ((op&0xf0f8) == 0x50c8) return 0; // DBxx + if ((op&0xff80) == 0x4e80) return 0; // Jsr + if ((op&0xf000) == 0xa000) return 0; // a-line + if ((op&0xf000) == 0xf000) return 0; // f-line + if ((op&0xfff8)==0x4e70&&op!=0x4e71&&op!=0x4e76) return 0; // reset, rte, rts + + if ((op&0x3f) >= 0x28) op = (op&~0x3f) | (rand() % 0x28); + return 1; +} + +static unsigned short safe_rand(void) +{ + unsigned short op; + + /* avoid branch opcodes */ + do + { + op = rand(); + } + while (!op_check(op)); + + return op; +} + +int main() +{ + int i, op; + + srand(time(0)); + + f = fopen("test_misc2.bin", "wb"); + if (!f) return 1; + + write32(0x00ff8000); // stack + write32(0x300); // IP + + for (i=0x100/4-2; i; i--) + { + write32(0x200+i*4); // exception vectors + } + + for (i=0x100/4; i; i--) + { + write32(0); // pad + } + + for (i=0x100/4; i; i--) + { + write32(0x4e734e73); // fill with rte instructions + } + + for (op = 0; op < 0x10000; op++) + { + if ((op&0xf000) == 0x6000) // Bxx + { + if ((op&0x00ff) == 0) + write_op(op, 6, 0, 0); + } + else if ((op&0xf0f8)==0x50c8) // DBxx + { + write_op(op, 6, 0, 0); + } + else if ((op&0xff80)==0x4e80) // Jsr + { + int addr = 0x300 + op*8 + 8; + if ((op&0x3f) == 0x39) + write_op(op, addr >> 16, addr & 0xffff, 0); + } + else if ((op&0xf000)==0xa000 || (op&0xf000)==0xf000) // a-line, f-line + { + if (op != 0xa000 && op != 0xf000) continue; + } + else if ((op&0xfff8)==0x4e70&&op!=0x4e71&&op!=0x4e76); // rte, rts, stop, reset + else + { + write_op(op, safe_rand(), safe_rand(), safe_rand()); + } + } + + // jump to the beginning + write_op(0x4ef8, 0x300, 0x4ef8, 0x300); + write_op(0x4ef8, 0x300, 0x4ef8, 0x300); + + fclose(f); + return 0; +} + diff --git a/tests/test_negx.bin b/tests/test_negx.bin new file mode 100644 index 0000000..1f6e6cf Binary files /dev/null and b/tests/test_negx.bin differ diff --git a/tests/test_rol.bin b/tests/test_rol.bin new file mode 100644 index 0000000..0cb0a41 Binary files /dev/null and b/tests/test_rol.bin differ diff --git a/tests/test_shift.bin b/tests/test_shift.bin new file mode 100644 index 0000000..c364f21 Binary files /dev/null and b/tests/test_shift.bin differ diff --git a/tests/test_trace.bin b/tests/test_trace.bin new file mode 100644 index 0000000..e9ca5fa Binary files /dev/null and b/tests/test_trace.bin differ diff --git a/tests/test_trace.s b/tests/test_trace.s new file mode 100644 index 0000000..b6d8421 --- /dev/null +++ b/tests/test_trace.s @@ -0,0 +1,140 @@ +| Processor: 68K +| Target Assembler: 680x0 Assembler by GNU project + +| ___________________________________________________________________________ + +| Segment type: Pure code +| segment "ROM" +dword_0: .long 0 | DATA XREF: ROM:00007244r + | sub_764E+3Eo ... + | initial interrupt stack pointer +dword_4: .long _start | DATA XREF: ROM:00007248r + | ROM:000142C2w + | reset initial PC +dword_8: .long 0x4DE | DATA XREF: sub_20050+B54w + .long 0x490 + .long 0x4AA | illegal instruction + .long 0x4C4 + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long _trace | trace + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x548 | Level 1 Interrupt Autovector + .long 0x548 | 2 = ext interrupt + .long 0x548 + .long 0x592 | 4 = horizontal interrupt? + .long 0x548 + .long 0x594 | 6 = verticai interrupt? + .long 0x552 +dword_80: .long 0x45C | DATA XREF: ROM:00152F29o + | trap vector table? trap 0? + .long 0x1738 + .long 0x171C + .long 0x1754 + .long 0x1700 + .long 0x556 + .long 0x57A + .long 0x548 + .long 0x548 + .long 0x7CE | 9 + .long 0x548 + .long 0x548 + .long 0x548 + .long 0x548 + .long 0x548 + .long 0x548 + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE + .long 0x4DE +aSegaGenesis: .ascii "SEGA GENESIS " | DATA XREF: ROM:00045C6Ao +aCSega1994_jul: .ascii "(C)SEGA 1994.JUL" +aDumpedByTsd: .ascii "Dumped By TSD " +aShiningForce2: .ascii "SHINING FORCE 2 " +aGmMk131500: .ascii "GM MK-1315 -00" + .word 0x8921 | checksum +aJ: .ascii "J " | IO_Support + .long 0 | Rom_Start_Adress +dword_1A4: .long 0x1FFFFF | DATA XREF: sub_28008+F66o + | Rom_End_Adress + .long 0xFF0000 | Ram_Start_Adress + .long 0xFFFFFF | Ram_End_Adress +aRaa: .ascii "RA° "<0>" "<0><1><0>" ?"<0xFF> | Modem_Infos + .ascii " " + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | +aU: .ascii "U " | Countries + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | + .byte 0x20 | +_trace: + nop + nop + rte + +.globl _start +_start: + move.l #0xFFFFFFFF, %d0 + move.l #0xFFFFFFFF, %d1 + move.w #0xa711, %sr + move.l #0x1, %d2 + move.l #0x8000, %d3 + negx.l %d0 + negx.l %d1 + move.w #0x270f, %sr + negx.b %d2 + negx.w %d3 +_loop: + bra _loop + + nop + nop + nop + nop diff --git a/tools/idle.h b/tools/idle.h new file mode 100644 index 0000000..254cc57 --- /dev/null +++ b/tools/idle.h @@ -0,0 +1,3 @@ + +void CycloneInitIdle(void); +void CycloneFinishIdle(void); diff --git a/tools/idle.s b/tools/idle.s new file mode 100644 index 0000000..a8b7cca --- /dev/null +++ b/tools/idle.s @@ -0,0 +1,176 @@ +@ vim:filetype=armasm + +@ ranges/opcodes (idle, normal): +@ 71xx, 73xx - bne.s (8bit offset) +@ 75xx, 77xx - beq.s (8bit offset) +@ 7dxx, 7fxx - bra.s (8bit offset) + +.data +.align 2 + +have_patches: + .word 0 + +.equ patch_desc_table_size, 10 + +patch_desc_table: + .word (0x71fa<<16) | 0x66fa, idle_detector_bcc8, idle_bne, Op6601 @ bne.s + .word (0x71f8<<16) | 0x66f8, idle_detector_bcc8, idle_bne, Op6601 @ bne.s + .word (0x71f6<<16) | 0x66f6, idle_detector_bcc8, idle_bne, Op6601 @ bne.s + .word (0x71f2<<16) | 0x66f2, idle_detector_bcc8, idle_bne, Op6601 @ bne.s + .word (0x75fa<<16) | 0x67fa, idle_detector_bcc8, idle_beq, Op6701 @ beq.s + .word (0x75f8<<16) | 0x67f8, idle_detector_bcc8, idle_beq, Op6701 @ beq.s + .word (0x75f6<<16) | 0x67f6, idle_detector_bcc8, idle_beq, Op6701 @ beq.s + .word (0x75f2<<16) | 0x67f2, idle_detector_bcc8, idle_beq, Op6701 @ beq.s + .word (0x7dfe<<16) | 0x60fe, idle_detector_bcc8, idle_bra, Op6001 @ bra.s + .word (0x7dfc<<16) | 0x60fc, idle_detector_bcc8, idle_bra, Op6001 @ bra.s + + +.text +.align 2 + + +.global CycloneInitIdle + +CycloneInitIdle: + ldr r3, =CycloneJumpTab + ldr r2, =patch_desc_table + mov r12,#patch_desc_table_size + +cii_loop: + ldrh r0, [r2] + ldr r1, [r2, #4] @ detector + str r1, [r3, r0, lsl #2] + ldrh r0, [r2, #2] + ldr r1, [r2, #8] @ idle + add r0, r3, r0, lsl #2 + str r1, [r0] + ldr r1, [r2, #12] @ normal + str r1, [r0, #0x800] + add r2, r2, #16 + subs r12,r12,#1 + bgt cii_loop + + ldr r0, =have_patches + mov r1, #1 + str r1, [r0] + bx lr + + +.global CycloneFinishIdle + +CycloneFinishIdle: + ldr r0, =have_patches + ldr r0, [r0] + tst r0, r0 + bxeq lr + + ldr r3, =CycloneJumpTab + ldr r2, =patch_desc_table + mov r12,#patch_desc_table_size + +cfi_loop: + ldrh r0, [r2] + ldr r1, [r2, #12] @ normal + str r1, [r3, r0, lsl #2] + ldrh r0, [r2, #2] + ldr r1, =Op____ + add r0, r3, r0, lsl #2 + str r1, [r0] + str r1, [r0, #0x800] + add r2, r2, #16 + subs r12,r12,#1 + bgt cfi_loop + + ldr r0, =have_patches + mov r1, #0 + str r1, [r0] + bx lr + + + +.macro inc_counter cond +@ ldr\cond r0, [r7, #0x60] +@ mov r11,lr +@ sub r0, r4, r0 +@ sub r0, r0, #2 +@ bl\cond SekRegisterIdleHit +@ mov lr, r11 +.endm + +idle_bra: + mov r5, #2 + inc_counter + b Op6001 + +idle_bne: + msr cpsr_flg, r10 + movne r5, #2 @ 2 is intentional due to strange timing issues + inc_counter ne + b Op6601 + +idle_beq: + msr cpsr_flg, r10 ;@ ARM flags = 68000 flags + moveq r5, #2 + inc_counter eq + b Op6701 + + +@ @@@ @ + +idle_detector_bcc8: + ldr r0, =(Pico+0x22208) @ Pico.m + ldr r1, =idledet_start_frame + ldr r0, [r0, #0x1c] @ ..frame_count + ldr r1, [r1] + cmp r0, r1 + blt exit_detector @ not yet + + mov r0, r8, asl #24 @ Shift 8-bit signed offset up... + add r0, r4, r0, asr #24 @ jump dest + bic r0, r0, #1 + + mov r1, #0 + sub r1, r1, r8, lsl #24 + mov r1, r1, lsr #24 + sub r1, r1, #2 + bic r1, r1, #1 + + bl SekIsIdleCode + tst r0, r0 + and r2, r8, #0x00ff + orr r2, r2, #0x7100 + orreq r2, r2, #0x0200 + mov r0, r8, lsr #8 + cmp r0, #0x66 + orrgt r2, r2, #0x0400 @ 67xx (beq) + orrlt r2, r2, #0x0c00 @ 60xx (bra) + + @ r2 = patch_opcode + sub r0, r4, #2 + ldrh r1, [r0] + mov r11,r2 + mov r3, r7 + bl SekRegisterIdlePatch + cmp r0, #1 @ 0 - ok to patch, 1 - no patch, 2 - remove detector + strlth r11,[r4, #-2] + ble exit_detector + + @ remove detector from Cyclone + mov r0, r8, lsr #8 + cmp r0, #0x66 + ldrlt r1, =Op6001 + ldreq r1, =Op6601 + ldrgt r1, =Op6701 + + ldr r3, =CycloneJumpTab + str r1, [r3, r8, lsl #2] + bx r1 + +exit_detector: + mov r0, r8, lsr #8 + cmp r0, #0x66 + blt Op6001 + beq Op6601 + b Op6701 +