@ Thumbwrestler @ mic, 2005-2006 | micol972@gmail.com @ @ Runs THUMB instructions and checks for valid results. Useful for people developing THUMB emulators @ Compile with devkitarm .text .global _tmbmain .thumb .equ VARBASE, 0x2200000 .equ TESTNUM, (VARBASE+8) .equ CURSEL, (VARBASE+16) .equ C_MASK, 0x01 .equ C_SHIFT, 0 .equ V_MASK, 0x02 .equ V_SHIFT, 1 .equ Rd_MASK, 0x100 .equ Rd_SHIFT, 8 .macro TEST_Rd reg val cmp \reg,\val beq 1f lsl r4,r5,#Rd_SHIFT orr r6,r4 1: .endm _tmbmain: mov r0,#0 _forever: bl _vsync mov r1,r10 cmp r1,#0 beq _no_cls bl _clearscreen mov r1,#0 _no_cls: mov r10,r1 mov r7,#16 mov r5,#1 ldr r0,=TESTNUM ldr r1,[r0] bl _runtest ldr r0,=szStart mov r1,#20 mov r2,#151 mov r3,#5 bl _drawtext ldr r0,=szNext mov r1,#76 mov r2,#151 mov r3,#4 bl _drawtext ldr r0,=szSelect2 mov r1,#132 mov r2,#151 mov r3,#5 bl _drawtext ldr r0,=szMenu mov r1,#192 mov r2,#151 mov r3,#4 bl _drawtext bl _checkkeys mov r3,#0x4 tst r2,r3 beq not_select_tmb bl _menu not_select_tmb: mov r3,#0x8 tst r2,r3 beq not_start_tmb ldr r0,=TESTNUM ldr r1,[r0] add r1,#1 str r1,[r0] mov r10,r1 not_start_tmb: b _forever .align .pool _runtest: push {lr} lsl r1,r1,#2 @ r1 *= sizeof(word) ldr r0,=_jumptable mov r2,#1 add r0,r1 ldr r1,[r0] @ r1 = jumptable[test_number] orr r1,r2 @ We want to stay in Thumb mode bx r1 _clearscreen: ldr r0,=0x6800000 mov r4,#0 ldr r5,=24576 _cs_repeat: str r4,[r0] add r0,#4 sub r5,#1 bne _cs_repeat bx lr .align 1 _test0: ldr r0,=_szALU mov r1,#88 mov r2,#1 mov r3,#4 bl _drawtext @ ADD mov r6,#0 mov r0,#0 mov r1,#1 mov r2,#4 mov r3,#5 add r0,r1,#2 TEST_Rd r0,#3 add r0,r1,r2 TEST_Rd r0,#5 mov r0,#2 mov r1,#0 mov r2,#0 add r1,r1,#0 @ clear carry add r0,r11 bcc _add_ok_1 orr r6,r5 _add_ok_1: TEST_Rd r0,#1 mov r0,#0 add r0,pc,#4 beq _add_ok_2 lsl r4,r5,#3 _add_labelpc: orr r6,r4 _add_ok_2: ldr r1,=_add_labelpc TEST_Rd r0,r1 ldr r0,=0xFFFFFF01 mov r1,r0 add r0,#0xFF beq _add_ok_3 lsl r4,r5,#3 orr r6,r4 _add_ok_3: TEST_Rd r0,#0 add r1,#0xFF bcs _add_ok_4 orr r6,r5 _add_ok_4: ldr r0,=_szADD bl _drawresult add r7,#8 @ ASR mov r6,#0 @ Test ASR by imm==32 ldr r0,=0x80000000 ldr r1,=0xFFFFFFFF mov r2,#0 add r2,r2,#0 @ clear carry asr r0,r0,#32 bcs _asr_ok_1 orr r6,r5 _asr_ok_1: TEST_Rd r1,r0 ldr r0,=0x80000000 asr r0,r0,#32 bmi _asr_ok_3 lsl r4,r5,#1 orr r6,r4 _asr_ok_3: ldr r0,=0x80000000 asr r0,r0,#32 bne _asr_ok_4 lsl r4,r5,#3 orr r6,r4 _asr_ok_4: ldr r0,=_szASR bl _drawresult add r7,#8 @ BIC mov r1,#0 add r2,r2,#0 @ clear carry ldr r2,=0xFFFFFFFF ldr r3,=0xC000000D bic r2,r3 bcc _bic_cc bmi _bic_mi beq _bic_eq _bic_cc: mov r3,#1 orr r1,r3 b _bic_fin _bic_mi: mov r3,#2 orr r1,r3 b _bic_fin _bic_eq: mov r3,#8 orr r1,r3 b _bic_fin _bic_fin: ldr r3,=0x1FFFFFF9 cmp r2,r3 bne _bic_ne b _bic_fin2 _bic_ne: mov r3,#16 orr r1,r3 b _bic_fin2 _bic_fin2: ldr r0,=_szBIC bl _drawresult add r7,#8 @ CMP mov r6,#0 mov r0, #1 neg r1,r0 cmp r1,#0 blt cmp_end mov r6,#V_MASK cmp_end: ldr r0,=_szCMP bl _drawresult add r7,#8 @ LSL mov r6,#0 @ Test LSL by reg==32 mov r0,#3 mov r1,#32 lsl r0,r1 bcs _lsl_ok_1 orr r6,r5 _lsl_ok_1: cmp r0,#0 beq _lsl_ok_2 lsl r4,r5,#Rd_SHIFT orr r6,r4 _lsl_ok_2: mov r0,#3 lsl r0,r1 bpl _lsl_ok_3 lsl r4,r5,#1 orr r6,r4 _lsl_ok_3: mov r0,#3 lsl r0,r1 beq _lsl_ok_4 lsl r4,r5,#3 orr r6,r4 _lsl_ok_4: ldr r0,=_szLSL bl _drawresult add r7,#8 @ LSR mov r6,#0 @ Test LSR by imm==32 ldr r0,=0x80000000 mov r1,#2 mov r2,#0 add r2,r2,#0 @ clear carry lsr r1,r0,#32 bcs _lsr_ok_1 orr r6,r5 _lsr_ok_1: cmp r1,#0 beq _lsr_ok_2 lsl r4,r5,#Rd_SHIFT orr r6,r4 _lsr_ok_2: ldr r0,=_szLSR bl _drawresult add r7,#8 @ MUL mov r6,#0 mov r0,#1 mov r1,#20 ldr r2,=0xFFFFFFF6 ldr r3,=0xFFFFFF38 lsr r0,r0,#1 @ set carry mul r1,r2 @bcs _mul_ok_1 @orr r6,r5 @_mul_ok_1: TEST_Rd r1,r3 mov r1,#20 mul r1,r2 bmi _mul_ok_2 lsl r4,r5,#1 orr r6,r4 _mul_ok_2: mov r1,#20 mul r1,r2 bne _mul_ok_3 lsl r4,r5,#3 orr r6,r4 _mul_ok_3: ldr r0,=_szMUL bl _drawresult add r7,#8 @ MVN mov r6,#0 ldr r0,=0xFFFFFF00 mvn r0,r0 bpl _mvn_ok_1 lsl r4,r5,#1 orr r6,r4 _mvn_ok_1: TEST_Rd r0,#0xFF ldr r0,=_szMVN bl _drawresult add r7,#8 @ NEG mov r6,#0 mov r0,#1 neg r1,r0 bne _neg_ok_1 lsl r4,r5,#3 orr r6,r4 _neg_ok_1: neg r1,r0 bmi _neg_ok_2 lsl r4,r5,#1 orr r6,r4 _neg_ok_2: neg r1,r1 bpl _neg_ok_3 lsl r4,r5,#1 orr r6,r4 _neg_ok_3: neg r0,r0 ldr r2,=0xFFFFFFFF TEST_Rd r0,r2 ldr r0,=_szNEG bl _drawresult add r7,#8 @ SUB mov r6,#0 mov r0, #1 neg r1,r0 sub r2,r1,#1 blt sub_end mov r6,#V_MASK sub_end: ldr r0,=_szSUB bl _drawresult add r7,#8 @ ROR mov r6,#0 @ Test ROR by reg==0 ldr r0,=0x80000000 mov r1,r0 mov r2,#1 mov r3,#0 lsr r2,r2,#1 @ set carry ror r0,r3 bcs _ror_ok_1 orr r6,r5 _ror_ok_1: cmp r0,r1 beq _ror_ok_2 lsl r4,r5,#Rd_SHIFT orr r6,r4 _ror_ok_2: @ Test ROR by reg==16 ldr r0,=0x80000000 ldr r1,=0x8000 mov r2,#1 mov r3,#16 lsr r2,r2,#1 @ set carry ror r0,r3 cmp r0,r1 bcs _ror_ok_3 orr r6,r5 _ror_ok_3: cmp r0,r1 beq _ror_ok_4 lsl r4,r5,#Rd_SHIFT orr r6,r4 _ror_ok_4: @ Test ROR by reg>32 ldr r0,=0x80000000 mov r1,#66 ror r0,r1 bcc _ror_ok_5 orr r6,r5 _ror_ok_5: ldr r2,=0x20000000 cmp r0,r2 beq _ror_ok_6 lsl r4,r5,#Rd_SHIFT orr r6,r4 _ror_ok_6: @ Test ROR by reg==32 ldr r0,=0x80000000 mov r2,r0 mov r1,#32 ror r0,r1 bcs _ror_ok_7 orr r6,r5 _ror_ok_7: ldr r0,=0x80000000 ror r0,r1 bmi _ror_ok_8 lsl r4,r5,#1 orr r6,r4 _ror_ok_8: ldr r0,=0x80000000 ror r0,r1 bne _ror_ok_9 lsl r4,r5,#3 orr r6,r4 _ror_ok_9: cmp r0,r2 beq _ror_ok_10 lsl r4,r5,#Rd_SHIFT orr r6,r4 _ror_ok_10: ldr r0,=_szROR bl _drawresult add r7,#8 pop {pc} .pool .align _test1: ldr r0,=_szLDR1 mov r1,#64 mov r2,#1 mov r3,#4 bl _drawtext @ LDR Rd,[Rb,#imm] mov r6,#0 ldr r0,=romvar2-2 ldr r1,[r0,#4] ldr r2,=0x8f00ff00 TEST_Rd r1,r2 ldr r0,=_szLDR bl _drawresult add r7,#8 @ LDR Rd,[Rb,Ro] mov r6,#0 ldr r0,=romvar2 ldr r2,=0x8f00ff00 mov r3,#2 ldr r1,[r0,r3] TEST_Rd r1,r2 ldr r0,=_szLDR bl _drawresult add r7,#8 @ LDRB Rd,[Rb,Ro] mov r6,#0 ldr r0,=romvar2 ldr r2,=0x8f mov r3,#1 ldrb r1,[r0,r3] TEST_Rd r1,r2 ldr r0,=_szLDRB bl _drawresult add r7,#8 @ LDRH Rd,[Rb,Ro] mov r6,#0 ldr r0,=romvar2 ldr r2,=0x8f00 mov r3,#0 ldrh r1,[r0,r3] TEST_Rd r1,r2 ldr r0,=_szLDRH1 bl _drawresult add r7,#8 @ LDRH Rd,[Rb,#nn] mov r6,#0 ldr r0,=romvar2 ldr r2,=0x8f00 ldrh r1,[r0,#0] TEST_Rd r1,r2 ldr r0,=_szLDRH2 bl _drawresult add r7,#8 @ LDRSH Rd,[Rb,Ro] mov r6,#0 ldr r0,=romvar2 ldr r2,=0xFFFF8F00 mov r3,#0 ldsh r1,[r0,r3] TEST_Rd r1,r2 ldr r0,=_szLDRSH bl _drawresult add r7,#8 @ LDRSB Rd,[Rb,Ro] mov r6,#0 ldr r0,=romvar2 ldr r2,=0xFFFFFF8F mov r3,#1 ldsb r1,[r0,r3] TEST_Rd r1,r2 ldr r0,=_szLDRSB bl _drawresult add r7,#8 pop {pc} .pool .align 1 _test2: ldr r0,=_szLDM1 mov r1,#72 mov r2,#1 mov r3,#4 bl _drawtext @ LDMIA Rb!,{Rlist} mov r6,#0 @clear flags mov r1,#0 ldr r3,=_var64 sub r3,r3,#4 ldmia r3!,{r1,r2} ldr r0,=_var64+4 cmp r3,r0 beq _ldm_r2_r0 b _ldm_done _ldm_r2_r0: ldr r0,=_var64 ldr r0,[r0] cmp r1,r0 beq _ldm_r1_r0 b _ldm_done _ldm_r1_r0: ldr r0,=_var64+4 ldr r0,[r0] cmp r2,r0 _ldm_done: ldr r0,=_szLDMIA bl _drawresult add r7,#8 @ STMIA Rb!,{Rlist} mov r6,#0 @clear flags ldr r1,=0x44332211 ldr r2,=0x88776655 ldr r3,=_tvar64 sub r3,r3,#4 stmia r3!,{r1,r2} ldr r0,=_tvar64+4 cmp r3,r0 beq _stm_r2_r0 b _stm_done _stm_r2_r0: ldr r0,=_tvar64 ldr r0,[r0] cmp r1,r0 beq _stm_r1_r0 b _stm_done _stm_r1_r0: ldr r0,=_tvar64+4 ldr r0,[r0] cmp r2,r0 _stm_done: ldr r0,=_szSTMIA bl _drawresult add r7,#8 pop {pc} _menu: pop {r1} @ Remove the return address from the stack ldr r4,=TESTNUM mov r0,#1 mov r10,r0 @ Clear screen needed mov r3,#10 @ 10 = Menu strb r3,[r4] ldr r0,=forever bx r0 @ Branch back to ARM code _vsync: push {r0-r1,lr} ldr r0,=0x4000004 _vs_loop_1: ldrh r1,[r0] lsr r1,r1,#1 bcs _vs_loop_1 _vs_loop_2: ldrh r1,[r0] lsr r1,r1,#1 bcc _vs_loop_2 pop {r0-r1,pc} .align .pool _checkkeys: push {lr} ldr r0,=0x4000130 ldrh r2,[r0] ldr r0,=(VARBASE+12) ldrh r3,[r0] mov r5,#0xff and r2,r5 eor r2,r5 strh r2,[r0] cmp r2,#0 beq _ck_no_mask eor r2,r3 _ck_no_mask: pop {pc} .align .pool _drawresult: @ r0: lpszText @ r6: bitmask push {r4-r5,lr} mov r1,#16 mov r2,r7 mov r3,#3 bl _drawtext cmp r6,#0 beq _dr_ok ldr r0,=_szBad mov r1,#72 mov r2,r7 mov r3,#2 bl _drawtext mov r5,#C_MASK ldr r0,=_szC mov r1,#104 mov r2,r7 mov r3,#2 _dr_test_flags: tst r6,r5 beq _dr_flag_ok bl _drawtext _dr_flag_ok: add r0,#2 add r1,#8 lsl r5,r5,#1 cmp r5,#16 bne _dr_test_flags mov r5,#V_MASK ldr r0,=_szV mov r1,#112 mov r2,r7 mov r3,#2 _dv_test_flags: tst r6,r5 beq _dv_flag_ok bl _drawtext _dv_flag_ok: add r0,#2 add r1,#8 lsl r5,r5,#1 cmp r5,#16 bne _dv_test_flags ldr r5,=Rd_MASK tst r6,r5 beq _dr_rd_ok ldr r0,=_szRd mov r1,#144 mov r2,r7 mov r3,#2 bl _drawtext _dr_rd_ok: b _dr_done _dr_ok: ldr r0,=_szOK mov r1,#72 mov r2,r7 mov r3,#1 bl _drawtext _dr_done: pop {r4-r5,pc} .align .pool _drawtext: @ r0: lpszText @ r1: x @ r2: y @ r3: color push {r0-r7,lr} ldr r6,=palette lsl r3,r3,#1 ldrh r3,[r6,r3] @ r7 = 0x6800000 + y*512 + x*2 mov r6,#0x68 lsl r7,r2,#9 lsl r6,r6,#20 lsl r1,r1,#1 add r7,r1 add r7,r6 _dt_chrloop: ldrb r1,[r0] ldr r6,=font add r0,#1 cmp r1,#0 beq _dt_null cmp r1,#32 beq _dt_space sub r1,#37 lsl r1,r1,#6 add r6,r1 _dt_space: push {r7} mov r4,#8 _dt_yloop: push {r4} mov r4,#8 mov r5,#0xFF _dt_xloop: ldrb r1,[r6] @lsr r2,r1,#8 add r6,#1 and r1,r5 beq _dt_pixel_1_0 mov r1,r3 _dt_pixel_1_0: @and r2,r5 @beq _dt_pixel_2_0 @mov r2,r3 @_dt_pixel_2_0: @lsl r2,r2,#8 @orr r1,r2 strh r1,[r7] add r7,#2 sub r4,#1 bne _dt_xloop pop {r4} add r7,#248 add r7,#248 sub r4,#1 bne _dt_yloop pop {r7} add r7,#16 b _dt_chrloop _dt_null: pop {r0-r7,pc} .align 2 .pool .align 3 _var64: .word 0x11223344,0x55667788 _tvar64: .word 0x11223344,0x55667788 .align 2 _jumptable: .word _test0,_test1,_test2,_menu .align 2 _szALU: .asciz "ALU TEST" _szLDR1: .asciz "LDR/STR TEST 1" _szLDM1: .asciz "LDM/STM TEST" _szADC: .asciz "ADC" _szADD: .asciz "ADD" _szAND: .asciz "AND" _szASR: .asciz "ASR" _szBIC: .asciz "BIC" _szCMP: .asciz "CMP" _szLSL: .asciz "LSL" _szLSR: .asciz "LSR" _szMUL: .asciz "MUL" _szMVN: .asciz "MVN" _szNEG: .asciz "NEG" _szORR: .asciz "ORR" _szROR: .asciz "ROR" _szSUB: .asciz "SUB" _szLDR: .asciz "LDR" _szLDRH: .asciz "LDRH" _szLDRH1: .asciz "LDRH R" _szLDRH2: .asciz "LDRH \\" _szLDRB: .asciz "LDRB" _szLDRSH: .asciz "LDRSH" _szLDRSB: .asciz "LDRSB" _szLDM: .asciz "LDM" _szLDMIA: .asciz "LDMIA" _szSTR: .asciz "STR" _szSTRH: .asciz "STRH" _szSTRB: .asciz "STRB" _szSTMIA: .asciz "STMIA" _szOK: .asciz "OK" _szBad: .asciz "BAD" _szRd: .asciz "R^" _szRn: .asciz "R_" _szC: .asciz "C" _szN: .asciz "N" _szV: .asciz "V" _szZ: .asciz "Z" _szGT: .asciz "+" _szGE: .asciz "," _szLT: .asciz "-" _szLE: .asciz "." .align 2 .end