From ac55a807ef15c3f95d255bf36d4e3939414dca56 Mon Sep 17 00:00:00 2001 From: nakeee Date: Thu, 23 Apr 2009 08:55:12 +0000 Subject: [PATCH] DSP: Created test directory and added some dspspy tests This way we can commonly share the tests we ran git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3052 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/DSPSpy/{ => tests}/dsp_code.ds | 0 Source/DSPSpy/tests/if_test.ds | 698 ++++++++++++++++++++++++++ Source/DSPSpy/tests/if_test2.ds | 698 ++++++++++++++++++++++++++ Source/DSPSpy/tests/if_test3.ds | 698 ++++++++++++++++++++++++++ 4 files changed, 2094 insertions(+) rename Source/DSPSpy/{ => tests}/dsp_code.ds (100%) create mode 100644 Source/DSPSpy/tests/if_test.ds create mode 100644 Source/DSPSpy/tests/if_test2.ds create mode 100644 Source/DSPSpy/tests/if_test3.ds diff --git a/Source/DSPSpy/dsp_code.ds b/Source/DSPSpy/tests/dsp_code.ds similarity index 100% rename from Source/DSPSpy/dsp_code.ds rename to Source/DSPSpy/tests/dsp_code.ds diff --git a/Source/DSPSpy/tests/if_test.ds b/Source/DSPSpy/tests/if_test.ds new file mode 100644 index 0000000000..48e1d2490b --- /dev/null +++ b/Source/DSPSpy/tests/if_test.ds @@ -0,0 +1,698 @@ +; This is the trojan program we send to the DSP from DSPSpy to figure it out. + +; A lot of constant definitions. +DSCR: equ 0xffc9 ; DSP DMA Control Reg +DSBL: equ 0xffcb ; DSP DMA Block Length +DSPA: equ 0xffcd ; DSP DMA DMEM Address +DSMAH: equ 0xffce ; DSP DMA Mem Address H +DSMAL: equ 0xffcf ; DSP DMA Mem Address L + +ACSAH: equ 0xffd4 +ACSAL: equ 0xffd5 +ACEAH: equ 0xffd6 +ACEAL: equ 0xffd7 +ACCAH: equ 0xffd8 +ACCAL: equ 0xffd9 +AMDM: equ 0xffef ; ARAM DMA Request Mask + +DIRQ: equ 0xfffb ; DSP Irq Request +DMBH: equ 0xfffc ; DSP Mailbox H +DMBL: equ 0xfffd ; DSP Mailbox L +CMBH: equ 0xfffe ; CPU Mailbox H +CMBL: equ 0xffff ; CPU Mailbox L + +R00: equ 0x00 +R01: equ 0x01 +R02: equ 0x02 +R03: equ 0x03 +R04: equ 0x04 +R05: equ 0x05 +R06: equ 0x06 +R07: equ 0x07 +R08: equ 0x08 +R09: equ 0x09 +R0A: equ 0x0a +R0B: equ 0x0b +R0C: equ 0x0c +R0D: equ 0x0d +R0E: equ 0x0e +R0F: equ 0x0f +R10: equ 0x10 +R11: equ 0x11 +R12: equ 0x12 +R13: equ 0x13 +R14: equ 0x14 +R15: equ 0x15 +R16: equ 0x16 +R17: equ 0x17 +R18: equ 0x18 +R19: equ 0x19 +R1A: equ 0x1a +R1B: equ 0x1b +R1C: equ 0x1c +R1D: equ 0x1d +R1E: equ 0x1e +R1F: equ 0x1f + +ACH0: equ 0x10 +ACH1: equ 0x11 +ACL0: equ 0x1e +ACL1: equ 0x1f + +DSP_CR_IMEM: equ 2 +DSP_CR_TO_CPU: equ 1 + + +REGS_BASE: equ 0x0f80 +MEM_HI: equ 0x0f7E +MEM_LO: equ 0x0f7F + +; CODE STARTS HERE. + +; Interrupt vectors 8 vectors, 2 opcodes each + + jmp irq0 + jmp irq1 + jmp irq2 + jmp irq3 + jmp irq4 + jmp irq5 + jmp irq6 + jmp irq7 + +; Main code at 0x10 + sbset #0x02 + sbset #0x03 + sbclr #0x04 + sbset #0x05 + sbset #0x06 + + set16 + lri $CR, #0x00ff + +; Why do we have a main label here? +main: + + clr $ACC1 + clr $ACC0 + +; get address of memory dump and copy it to DRAM + + call wait_for_dsp_mbox + si @DMBH, #0x8888 + si @DMBL, #0xdead + si @DIRQ, #0x0001 + + call wait_for_cpu_mbox + lrs $ACL0, @CMBL + andi $acl1, #0x7fff + + sr @MEM_HI, $ACL1 + sr @MEM_LO, $ACL0 + + lri $r18, #0 + lri $r19, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $r1a, #0x2000 + lr $r1c, @MEM_HI + lr $r1e, @MEM_LO + call do_dma + + +; get address of registers and DMA them to ram + + call wait_for_dsp_mbox + si @DMBH, #0x8888 + si @DMBL, #0xbeef + si @DIRQ, #0x0001 + + call wait_for_cpu_mbox + lrs $ACL0, @CMBL + andi $acl1, #0x7fff + + sr @MEM_HI, $ACL1 + sr @MEM_LO, $ACL0 + + lri $r18, #REGS_BASE + lri $r19, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $r1a, #0x80 + lr $r1c, @MEM_HI + lr $r1e, @MEM_LO + call do_dma + +; Read in all the registers from RAM + + lri $r00, #REGS_BASE+1 + lrri $r01, @$r00 + lrri $r02, @$r00 + lrri $r03, @$r00 + lrri $r04, @$r00 + lrri $r05, @$r00 + lrri $r06, @$r00 + lrri $r07, @$r00 + lrri $r08, @$r00 + lrri $r09, @$r00 + lrri $r0a, @$r00 + lrri $r0b, @$r00 + lrri $r0c, @$r00 + lrri $r0d, @$r00 + lrri $r0e, @$r00 + lrri $r0f, @$r00 + lrri $r10, @$r00 + lrri $r11, @$r00 + lrri $r12, @$r00 + lrri $r13, @$r00 + lrri $r14, @$r00 + lrri $r15, @$r00 + lrri $r16, @$r00 + lrri $r17, @$r00 + lrri $r18, @$r00 + lrri $r19, @$r00 + lrri $r1a, @$r00 + lrri $r1b, @$r00 + lrri $r1c, @$r00 + lrri $r1d, @$r00 + lrri $r1e, @$r00 + lrri $r1f, @$r00 + lr $r00, @REGS_BASE + +; Right here we are at a specific predetermined state. +; Ideal environment to try instructions. + +; We can call send_back at any time to send data back to the PowerPC. + +; Calling set40 here seemed to crash the dsp tester in strange ways +; until I added set16 in send_back. Seems clear that it affects something important. + + lri $R04, #0x0000 + lri $R13, #0x0001 + + ifs + lri $R04, #0x1337 + call send_back + + ifns + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x0002 + + ifs + lri $R04, #0x1337 + call send_back + + ifns + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x0004 + + ifs + lri $R04, #0x1337 + call send_back + + ifns + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x0008 + + ifs + lri $R04, #0x1337 + call send_back + + ifns + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x000a + + ifs + lri $R04, #0x1337 + call send_back + + ifns + lri $R04, #0x1338 + call send_back +; We're done - currently we only test one opcode, in this case 0x8600. +; It's possible to test many more in one go - just call send_back after each one. + + jmp ende + +; Below here is tons of random leftover test code from whoever last experimented with this. + +; call dump_memory +; call send_back + + cw 0x00de + cw 0x03f1 + call send_back + + cw 0x0200 + cw 0x0a60 + call send_back + + cw 0x1c7e + call send_back + + cw 0x8100 + call send_back + + cw 0x8900 + call send_back + + cw 0x009f + cw 0x00a0 + call send_back + + cw 0x00de + cw 0x03f1 + call send_back + + cw 0x5d00 + call send_back + + cw 0x0e50 + call send_back + + cw 0x0750 + call send_back + + cw 0x0270 + call send_back + + cw 0x5d00 + call send_back + + cw 0x00da + cw 0x03f2 + call send_back + + cw 0x8600 + call send_back + + JNS g_0c4d +; cw 0x0290 +; cw 0x0c4d +; call send_back JX0 + + cw 0x00de + cw 0x03f3 + call send_back + + cw 0x5c00 + call send_back + + JLE g_0c38 +; cw 0x0293 +; cw 0x0c38 JX3 +; call send_back + + JMP g_0c52 + +; cw 0x029f +; cw 0x0c52 +; call send_back + +g_0c38: + cw 0x00db + cw 0x03f7 + call send_back + + cw 0x009e + cw 0x8000 + call send_back + + cw 0x4600 + call send_back + + JMP g_0c44 +; cw 0x029f +; cw 0x0c44 +; call send_back + +g_0c3f: + cw 0x00db + cw 0x03f7 + call send_back + + cw 0x009e + cw 0x8000 + call send_back + + cw 0x5600 + call send_back + +g_0c44: + cw 0x00fe + cw 0x03f5 + call send_back + + cw 0x1fda + call send_back + + cw 0x7c00 + call send_back + + cw 0x1f5e + call send_back + + cw 0x00fe + cw 0x03f2 + call send_back + + JMP g_0c52 +; cw 0x029f +; cw 0x0c52 +; call send_back + +g_0c4d: + + cw 0x00de + cw 0x03f4 + call send_back + + cw 0x5d00 + call send_back + + JLE g_0c3f +; cw 0x0293 +; cw 0x0c3f +; call send_back + +g_0c52: + cw 0x8900 + call send_back + + cw 0x00dd + cw 0x03f5 + call send_back + + cw 0x1501 + call send_back + + cw 0x8100 + call send_back + + cw 0x00dc + cw 0x03f6 + call send_back + + cw 0x008b + cw 0x009f + call send_back + + cw 0x0080 + cw 0x0a00 + call send_back + + cw 0x0900 + call send_back + + BLOOPI #0x50, g_0c65 +; cw 0x1150 +; cw 0x0c65 +; call send_back + + + cw 0x1878 + call send_back + + cw 0x4c00 + call send_back + + cw 0x1cfe + call send_back + + cw 0x001f + call send_back + + cw 0x1fd9 + call send_back +g_0c65: + cw 0x1b18 + call send_back + + cw 0x009f + cw 0x0a60 + call send_back + + cw 0x1fc3 + call send_back + + cw 0x5c00 + call send_back + + cw 0x00fe + cw 0x03f1 + call send_back + + cw 0x00fc + cw 0x03f6 + call send_back + + cw 0x008b + cw 0xffff + call send_back + + +; This is where we jump when we're done testing, see above. +ende: + + nop + nop + nop + nop + nop + nop + nop + +; We just fall into a loop, playing dead until someone resets the DSP. +dead_loop: + jmp dead_loop + +; Utility function to do DMA. +; r1c:r1e - external address. +; r18 - address in DSP +do_dma: + sr @DSMAH, $r1c + sr @DSMAL, $r1e + sr @DSPA, $r18 + sr @DSCR, $r19 + sr @DSBL, $r1a ; This kicks off the DMA. + +; Waits for said DMA to complete by watching a bit in DSCR. +wait_dma: + LRS $ACL1, @DSCR + andcf $acl1, #0x0004 + JLZ wait_dma + RET + +; This waits for a mail to arrive in the DSP in-mailbox. +wait_for_dsp_mbox: + lrs $ACL1, @DMBH + andcf $acl1, #0x8000 + jlz wait_for_dsp_mbox + ret + +; This waits for the CPU to grab a mail that we just sent from the DSP. +wait_for_cpu_mbox: + lrs $ACL1, @cmbh + andcf $acl1, #0x8000 + jlnz wait_for_cpu_mbox + ret + +; IRQ handlers. Not entirely sure what good they do currently. +irq0: + lri $acl0, #0x0000 + jmp irq +irq1: + lri $acl0, #0x0001 + jmp irq +irq2: + lri $acl0, #0x0002 + jmp irq +irq3: + lri $acl0, #0x0003 + jmp irq +irq4: + lri $acl0, #0x0004 + jmp irq +irq5: +; No idea what this code is doing. + set16 + mrr $r0d, $r1c + mrr $r0d, $r1e + clr $acc0 + mrr $r1e, $r0d + mrr $r1c, $r0d + nop ; Or why there's a nop sled here. + nop + nop + nop + nop + nop + rti + + lri $acl0, #0x0005 + jmp irq +irq6: + lri $acl0, #0x0006 + jmp irq +irq7: + lri $acl0, #0x0007 + jmp irq + +irq: + lrs $ACL1, @DMBH + andcf $acl1, #0x8000 + jlz irq + si @DMBH, #0x8BAD + sr @DMBL, $r0b +;sr @DMBL, $acl0 + si @DIRQ, #0x0001 + halt + +; DMA:s the current state of the registers back to the PowerPC. To do this, +; it must write the contents of all regs to DRAM. +send_back: + ; make state safe. + set16 + ; store registers to reg table + sr @REGS_BASE, $r00 + lri $r00, #(REGS_BASE + 1) + srri @$r00, $r01 + srri @$r00, $r02 + srri @$r00, $r03 + srri @$r00, $r04 + srri @$r00, $r05 + srri @$r00, $r06 + srri @$r00, $r07 + srri @$r00, $r08 + srri @$r00, $r09 + srri @$r00, $r0a + srri @$r00, $r0b + srri @$r00, $r0c + srri @$r00, $r0d + srri @$r00, $r0e + srri @$r00, $r0f + srri @$r00, $r10 + srri @$r00, $r11 + srri @$r00, $r12 + srri @$r00, $r13 + srri @$r00, $r14 + srri @$r00, $r15 + srri @$r00, $r16 + srri @$r00, $r17 + srri @$r00, $r18 + srri @$r00, $r19 + srri @$r00, $r1a + srri @$r00, $r1b + srri @$r00, $r1c + srri @$r00, $r1d + srri @$r00, $r1e + srri @$r00, $r1f + +; Regs are stored. Prepare DMA. + lri $r18, #0x0000 + lri $r19, #1 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $r1a, #0x200 + lr $r1c, @MEM_HI + lr $r1e, @MEM_LO + + lri $r01, #8+8 + +; Now, why are we looping here? + bloop $r01, dma_copy + call do_dma + addi $r1e, #0x200 + mrr $r1f, $r18 + addi $r1f, #0x100 + mrr $r18, $r1f + nop + +dma_copy: + nop + +; Wait for the CPU to send us a mail. + call wait_for_dsp_mbox + si @DMBH, #0x8888 + si @DMBL, #0xfeeb + si @DIRQ, #0x0001 + +; wait for the CPU to recieve our response before we execute the next op + call wait_for_cpu_mbox + lrs $ACL0, @CMBL + andi $acl1, #0x7fff + +; Restore all regs again so we're ready to execute another op. + lri $r00, #REGS_BASE+1 + lrri $r01, @$r00 + lrri $r02, @$r00 + lrri $r03, @$r00 + lrri $r04, @$r00 + lrri $r05, @$r00 + lrri $r06, @$r00 + lrri $r07, @$r00 + lrri $r08, @$r00 + lrri $r09, @$r00 + lrri $r0a, @$r00 + lrri $r0b, @$r00 + lrri $r0c, @$r00 + lrri $r0d, @$r00 + lrri $r0e, @$r00 + lrri $r0f, @$r00 + lrri $r10, @$r00 + lrri $r11, @$r00 + lrri $r12, @$r00 + lrri $r13, @$r00 + lrri $r14, @$r00 + lrri $r15, @$r00 + lrri $r16, @$r00 + lrri $r17, @$r00 + lrri $r18, @$r00 + lrri $r19, @$r00 + lrri $r1a, @$r00 + lrri $r1b, @$r00 + lrri $r1c, @$r00 + lrri $r1d, @$r00 + lrri $r1e, @$r00 + lrri $r1f, @$r00 + lr $r00, @REGS_BASE + + ret ; from send_back + +; If you are in set40 mode, use this instead of send_back if you want to stay +; in set40 mode. +send_back_40: + set16 + call send_back + set40 + ret + +; This one's odd. Doesn't look like it should work since it uses acl0 but +; increments acm0... (acc0) +dump_memory: + lri $r02, #0x0000 + lri $acl0, #0x1000 + + lri $r01, #0x1000 + bloop $r01, _fill_loop2 + + mrr $r03, $acl0 + nx'ld : $AX0.H, $AX1.H, @$AR0 + + mrr $r1f, $r00 + mrr $r00, $r02 + srri @$r00, $r1b + mrr $r02, $r00 + mrr $r00, $r1f + + addis $acc0, #0x1 + +_fill_loop2: + nop + ret ; from dump_memory diff --git a/Source/DSPSpy/tests/if_test2.ds b/Source/DSPSpy/tests/if_test2.ds new file mode 100644 index 0000000000..3750d7a917 --- /dev/null +++ b/Source/DSPSpy/tests/if_test2.ds @@ -0,0 +1,698 @@ +; This is the trojan program we send to the DSP from DSPSpy to figure it out. + +; A lot of constant definitions. +DSCR: equ 0xffc9 ; DSP DMA Control Reg +DSBL: equ 0xffcb ; DSP DMA Block Length +DSPA: equ 0xffcd ; DSP DMA DMEM Address +DSMAH: equ 0xffce ; DSP DMA Mem Address H +DSMAL: equ 0xffcf ; DSP DMA Mem Address L + +ACSAH: equ 0xffd4 +ACSAL: equ 0xffd5 +ACEAH: equ 0xffd6 +ACEAL: equ 0xffd7 +ACCAH: equ 0xffd8 +ACCAL: equ 0xffd9 +AMDM: equ 0xffef ; ARAM DMA Request Mask + +DIRQ: equ 0xfffb ; DSP Irq Request +DMBH: equ 0xfffc ; DSP Mailbox H +DMBL: equ 0xfffd ; DSP Mailbox L +CMBH: equ 0xfffe ; CPU Mailbox H +CMBL: equ 0xffff ; CPU Mailbox L + +R00: equ 0x00 +R01: equ 0x01 +R02: equ 0x02 +R03: equ 0x03 +R04: equ 0x04 +R05: equ 0x05 +R06: equ 0x06 +R07: equ 0x07 +R08: equ 0x08 +R09: equ 0x09 +R0A: equ 0x0a +R0B: equ 0x0b +R0C: equ 0x0c +R0D: equ 0x0d +R0E: equ 0x0e +R0F: equ 0x0f +R10: equ 0x10 +R11: equ 0x11 +R12: equ 0x12 +R13: equ 0x13 +R14: equ 0x14 +R15: equ 0x15 +R16: equ 0x16 +R17: equ 0x17 +R18: equ 0x18 +R19: equ 0x19 +R1A: equ 0x1a +R1B: equ 0x1b +R1C: equ 0x1c +R1D: equ 0x1d +R1E: equ 0x1e +R1F: equ 0x1f + +ACH0: equ 0x10 +ACH1: equ 0x11 +ACL0: equ 0x1e +ACL1: equ 0x1f + +DSP_CR_IMEM: equ 2 +DSP_CR_TO_CPU: equ 1 + + +REGS_BASE: equ 0x0f80 +MEM_HI: equ 0x0f7E +MEM_LO: equ 0x0f7F + +; CODE STARTS HERE. + +; Interrupt vectors 8 vectors, 2 opcodes each + + jmp irq0 + jmp irq1 + jmp irq2 + jmp irq3 + jmp irq4 + jmp irq5 + jmp irq6 + jmp irq7 + +; Main code at 0x10 + sbset #0x02 + sbset #0x03 + sbclr #0x04 + sbset #0x05 + sbset #0x06 + + set16 + lri $CR, #0x00ff + +; Why do we have a main label here? +main: + + clr $ACC1 + clr $ACC0 + +; get address of memory dump and copy it to DRAM + + call wait_for_dsp_mbox + si @DMBH, #0x8888 + si @DMBL, #0xdead + si @DIRQ, #0x0001 + + call wait_for_cpu_mbox + lrs $ACL0, @CMBL + andi $acl1, #0x7fff + + sr @MEM_HI, $ACL1 + sr @MEM_LO, $ACL0 + + lri $r18, #0 + lri $r19, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $r1a, #0x2000 + lr $r1c, @MEM_HI + lr $r1e, @MEM_LO + call do_dma + + +; get address of registers and DMA them to ram + + call wait_for_dsp_mbox + si @DMBH, #0x8888 + si @DMBL, #0xbeef + si @DIRQ, #0x0001 + + call wait_for_cpu_mbox + lrs $ACL0, @CMBL + andi $acl1, #0x7fff + + sr @MEM_HI, $ACL1 + sr @MEM_LO, $ACL0 + + lri $r18, #REGS_BASE + lri $r19, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $r1a, #0x80 + lr $r1c, @MEM_HI + lr $r1e, @MEM_LO + call do_dma + +; Read in all the registers from RAM + + lri $r00, #REGS_BASE+1 + lrri $r01, @$r00 + lrri $r02, @$r00 + lrri $r03, @$r00 + lrri $r04, @$r00 + lrri $r05, @$r00 + lrri $r06, @$r00 + lrri $r07, @$r00 + lrri $r08, @$r00 + lrri $r09, @$r00 + lrri $r0a, @$r00 + lrri $r0b, @$r00 + lrri $r0c, @$r00 + lrri $r0d, @$r00 + lrri $r0e, @$r00 + lrri $r0f, @$r00 + lrri $r10, @$r00 + lrri $r11, @$r00 + lrri $r12, @$r00 + lrri $r13, @$r00 + lrri $r14, @$r00 + lrri $r15, @$r00 + lrri $r16, @$r00 + lrri $r17, @$r00 + lrri $r18, @$r00 + lrri $r19, @$r00 + lrri $r1a, @$r00 + lrri $r1b, @$r00 + lrri $r1c, @$r00 + lrri $r1d, @$r00 + lrri $r1e, @$r00 + lrri $r1f, @$r00 + lr $r00, @REGS_BASE + +; Right here we are at a specific predetermined state. +; Ideal environment to try instructions. + +; We can call send_back at any time to send data back to the PowerPC. + +; Calling set40 here seemed to crash the dsp tester in strange ways +; until I added set16 in send_back. Seems clear that it affects something important. + + lri $R04, #0x0000 + lri $R13, #0x0001 + + ifg + lri $R04, #0x1337 + call send_back + + ifle + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x0002 + + ifg + lri $R04, #0x1337 + call send_back + + ifle + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x0004 + + ifg + lri $R04, #0x1337 + call send_back + + ifle + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x0008 + + ifg + lri $R04, #0x1337 + call send_back + + ifle + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x000a + + ifg + lri $R04, #0x1337 + call send_back + + ifle + lri $R04, #0x1338 + call send_back +; We're done - currently we only test one opcode, in this case 0x8600. +; It's possible to test many more in one go - just call send_back after each one. + + jmp ende + +; Below here is tons of random leftover test code from whoever last experimented with this. + +; call dump_memory +; call send_back + + cw 0x00de + cw 0x03f1 + call send_back + + cw 0x0200 + cw 0x0a60 + call send_back + + cw 0x1c7e + call send_back + + cw 0x8100 + call send_back + + cw 0x8900 + call send_back + + cw 0x009f + cw 0x00a0 + call send_back + + cw 0x00de + cw 0x03f1 + call send_back + + cw 0x5d00 + call send_back + + cw 0x0e50 + call send_back + + cw 0x0750 + call send_back + + cw 0x0270 + call send_back + + cw 0x5d00 + call send_back + + cw 0x00da + cw 0x03f2 + call send_back + + cw 0x8600 + call send_back + + JNS g_0c4d +; cw 0x0290 +; cw 0x0c4d +; call send_back JX0 + + cw 0x00de + cw 0x03f3 + call send_back + + cw 0x5c00 + call send_back + + JLE g_0c38 +; cw 0x0293 +; cw 0x0c38 JX3 +; call send_back + + JMP g_0c52 + +; cw 0x029f +; cw 0x0c52 +; call send_back + +g_0c38: + cw 0x00db + cw 0x03f7 + call send_back + + cw 0x009e + cw 0x8000 + call send_back + + cw 0x4600 + call send_back + + JMP g_0c44 +; cw 0x029f +; cw 0x0c44 +; call send_back + +g_0c3f: + cw 0x00db + cw 0x03f7 + call send_back + + cw 0x009e + cw 0x8000 + call send_back + + cw 0x5600 + call send_back + +g_0c44: + cw 0x00fe + cw 0x03f5 + call send_back + + cw 0x1fda + call send_back + + cw 0x7c00 + call send_back + + cw 0x1f5e + call send_back + + cw 0x00fe + cw 0x03f2 + call send_back + + JMP g_0c52 +; cw 0x029f +; cw 0x0c52 +; call send_back + +g_0c4d: + + cw 0x00de + cw 0x03f4 + call send_back + + cw 0x5d00 + call send_back + + JLE g_0c3f +; cw 0x0293 +; cw 0x0c3f +; call send_back + +g_0c52: + cw 0x8900 + call send_back + + cw 0x00dd + cw 0x03f5 + call send_back + + cw 0x1501 + call send_back + + cw 0x8100 + call send_back + + cw 0x00dc + cw 0x03f6 + call send_back + + cw 0x008b + cw 0x009f + call send_back + + cw 0x0080 + cw 0x0a00 + call send_back + + cw 0x0900 + call send_back + + BLOOPI #0x50, g_0c65 +; cw 0x1150 +; cw 0x0c65 +; call send_back + + + cw 0x1878 + call send_back + + cw 0x4c00 + call send_back + + cw 0x1cfe + call send_back + + cw 0x001f + call send_back + + cw 0x1fd9 + call send_back +g_0c65: + cw 0x1b18 + call send_back + + cw 0x009f + cw 0x0a60 + call send_back + + cw 0x1fc3 + call send_back + + cw 0x5c00 + call send_back + + cw 0x00fe + cw 0x03f1 + call send_back + + cw 0x00fc + cw 0x03f6 + call send_back + + cw 0x008b + cw 0xffff + call send_back + + +; This is where we jump when we're done testing, see above. +ende: + + nop + nop + nop + nop + nop + nop + nop + +; We just fall into a loop, playing dead until someone resets the DSP. +dead_loop: + jmp dead_loop + +; Utility function to do DMA. +; r1c:r1e - external address. +; r18 - address in DSP +do_dma: + sr @DSMAH, $r1c + sr @DSMAL, $r1e + sr @DSPA, $r18 + sr @DSCR, $r19 + sr @DSBL, $r1a ; This kicks off the DMA. + +; Waits for said DMA to complete by watching a bit in DSCR. +wait_dma: + LRS $ACL1, @DSCR + andcf $acl1, #0x0004 + JLZ wait_dma + RET + +; This waits for a mail to arrive in the DSP in-mailbox. +wait_for_dsp_mbox: + lrs $ACL1, @DMBH + andcf $acl1, #0x8000 + jlz wait_for_dsp_mbox + ret + +; This waits for the CPU to grab a mail that we just sent from the DSP. +wait_for_cpu_mbox: + lrs $ACL1, @cmbh + andcf $acl1, #0x8000 + jlnz wait_for_cpu_mbox + ret + +; IRQ handlers. Not entirely sure what good they do currently. +irq0: + lri $acl0, #0x0000 + jmp irq +irq1: + lri $acl0, #0x0001 + jmp irq +irq2: + lri $acl0, #0x0002 + jmp irq +irq3: + lri $acl0, #0x0003 + jmp irq +irq4: + lri $acl0, #0x0004 + jmp irq +irq5: +; No idea what this code is doing. + set16 + mrr $r0d, $r1c + mrr $r0d, $r1e + clr $acc0 + mrr $r1e, $r0d + mrr $r1c, $r0d + nop ; Or why there's a nop sled here. + nop + nop + nop + nop + nop + rti + + lri $acl0, #0x0005 + jmp irq +irq6: + lri $acl0, #0x0006 + jmp irq +irq7: + lri $acl0, #0x0007 + jmp irq + +irq: + lrs $ACL1, @DMBH + andcf $acl1, #0x8000 + jlz irq + si @DMBH, #0x8BAD + sr @DMBL, $r0b +;sr @DMBL, $acl0 + si @DIRQ, #0x0001 + halt + +; DMA:s the current state of the registers back to the PowerPC. To do this, +; it must write the contents of all regs to DRAM. +send_back: + ; make state safe. + set16 + ; store registers to reg table + sr @REGS_BASE, $r00 + lri $r00, #(REGS_BASE + 1) + srri @$r00, $r01 + srri @$r00, $r02 + srri @$r00, $r03 + srri @$r00, $r04 + srri @$r00, $r05 + srri @$r00, $r06 + srri @$r00, $r07 + srri @$r00, $r08 + srri @$r00, $r09 + srri @$r00, $r0a + srri @$r00, $r0b + srri @$r00, $r0c + srri @$r00, $r0d + srri @$r00, $r0e + srri @$r00, $r0f + srri @$r00, $r10 + srri @$r00, $r11 + srri @$r00, $r12 + srri @$r00, $r13 + srri @$r00, $r14 + srri @$r00, $r15 + srri @$r00, $r16 + srri @$r00, $r17 + srri @$r00, $r18 + srri @$r00, $r19 + srri @$r00, $r1a + srri @$r00, $r1b + srri @$r00, $r1c + srri @$r00, $r1d + srri @$r00, $r1e + srri @$r00, $r1f + +; Regs are stored. Prepare DMA. + lri $r18, #0x0000 + lri $r19, #1 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $r1a, #0x200 + lr $r1c, @MEM_HI + lr $r1e, @MEM_LO + + lri $r01, #8+8 + +; Now, why are we looping here? + bloop $r01, dma_copy + call do_dma + addi $r1e, #0x200 + mrr $r1f, $r18 + addi $r1f, #0x100 + mrr $r18, $r1f + nop + +dma_copy: + nop + +; Wait for the CPU to send us a mail. + call wait_for_dsp_mbox + si @DMBH, #0x8888 + si @DMBL, #0xfeeb + si @DIRQ, #0x0001 + +; wait for the CPU to recieve our response before we execute the next op + call wait_for_cpu_mbox + lrs $ACL0, @CMBL + andi $acl1, #0x7fff + +; Restore all regs again so we're ready to execute another op. + lri $r00, #REGS_BASE+1 + lrri $r01, @$r00 + lrri $r02, @$r00 + lrri $r03, @$r00 + lrri $r04, @$r00 + lrri $r05, @$r00 + lrri $r06, @$r00 + lrri $r07, @$r00 + lrri $r08, @$r00 + lrri $r09, @$r00 + lrri $r0a, @$r00 + lrri $r0b, @$r00 + lrri $r0c, @$r00 + lrri $r0d, @$r00 + lrri $r0e, @$r00 + lrri $r0f, @$r00 + lrri $r10, @$r00 + lrri $r11, @$r00 + lrri $r12, @$r00 + lrri $r13, @$r00 + lrri $r14, @$r00 + lrri $r15, @$r00 + lrri $r16, @$r00 + lrri $r17, @$r00 + lrri $r18, @$r00 + lrri $r19, @$r00 + lrri $r1a, @$r00 + lrri $r1b, @$r00 + lrri $r1c, @$r00 + lrri $r1d, @$r00 + lrri $r1e, @$r00 + lrri $r1f, @$r00 + lr $r00, @REGS_BASE + + ret ; from send_back + +; If you are in set40 mode, use this instead of send_back if you want to stay +; in set40 mode. +send_back_40: + set16 + call send_back + set40 + ret + +; This one's odd. Doesn't look like it should work since it uses acl0 but +; increments acm0... (acc0) +dump_memory: + lri $r02, #0x0000 + lri $acl0, #0x1000 + + lri $r01, #0x1000 + bloop $r01, _fill_loop2 + + mrr $r03, $acl0 + nx'ld : $AX0.H, $AX1.H, @$AR0 + + mrr $r1f, $r00 + mrr $r00, $r02 + srri @$r00, $r1b + mrr $r02, $r00 + mrr $r00, $r1f + + addis $acc0, #0x1 + +_fill_loop2: + nop + ret ; from dump_memory diff --git a/Source/DSPSpy/tests/if_test3.ds b/Source/DSPSpy/tests/if_test3.ds new file mode 100644 index 0000000000..e8f60e95dd --- /dev/null +++ b/Source/DSPSpy/tests/if_test3.ds @@ -0,0 +1,698 @@ +; This is the trojan program we send to the DSP from DSPSpy to figure it out. + +; A lot of constant definitions. +DSCR: equ 0xffc9 ; DSP DMA Control Reg +DSBL: equ 0xffcb ; DSP DMA Block Length +DSPA: equ 0xffcd ; DSP DMA DMEM Address +DSMAH: equ 0xffce ; DSP DMA Mem Address H +DSMAL: equ 0xffcf ; DSP DMA Mem Address L + +ACSAH: equ 0xffd4 +ACSAL: equ 0xffd5 +ACEAH: equ 0xffd6 +ACEAL: equ 0xffd7 +ACCAH: equ 0xffd8 +ACCAL: equ 0xffd9 +AMDM: equ 0xffef ; ARAM DMA Request Mask + +DIRQ: equ 0xfffb ; DSP Irq Request +DMBH: equ 0xfffc ; DSP Mailbox H +DMBL: equ 0xfffd ; DSP Mailbox L +CMBH: equ 0xfffe ; CPU Mailbox H +CMBL: equ 0xffff ; CPU Mailbox L + +R00: equ 0x00 +R01: equ 0x01 +R02: equ 0x02 +R03: equ 0x03 +R04: equ 0x04 +R05: equ 0x05 +R06: equ 0x06 +R07: equ 0x07 +R08: equ 0x08 +R09: equ 0x09 +R0A: equ 0x0a +R0B: equ 0x0b +R0C: equ 0x0c +R0D: equ 0x0d +R0E: equ 0x0e +R0F: equ 0x0f +R10: equ 0x10 +R11: equ 0x11 +R12: equ 0x12 +R13: equ 0x13 +R14: equ 0x14 +R15: equ 0x15 +R16: equ 0x16 +R17: equ 0x17 +R18: equ 0x18 +R19: equ 0x19 +R1A: equ 0x1a +R1B: equ 0x1b +R1C: equ 0x1c +R1D: equ 0x1d +R1E: equ 0x1e +R1F: equ 0x1f + +ACH0: equ 0x10 +ACH1: equ 0x11 +ACL0: equ 0x1e +ACL1: equ 0x1f + +DSP_CR_IMEM: equ 2 +DSP_CR_TO_CPU: equ 1 + + +REGS_BASE: equ 0x0f80 +MEM_HI: equ 0x0f7E +MEM_LO: equ 0x0f7F + +; CODE STARTS HERE. + +; Interrupt vectors 8 vectors, 2 opcodes each + + jmp irq0 + jmp irq1 + jmp irq2 + jmp irq3 + jmp irq4 + jmp irq5 + jmp irq6 + jmp irq7 + +; Main code at 0x10 + sbset #0x02 + sbset #0x03 + sbclr #0x04 + sbset #0x05 + sbset #0x06 + + set16 + lri $CR, #0x00ff + +; Why do we have a main label here? +main: + + clr $ACC1 + clr $ACC0 + +; get address of memory dump and copy it to DRAM + + call wait_for_dsp_mbox + si @DMBH, #0x8888 + si @DMBL, #0xdead + si @DIRQ, #0x0001 + + call wait_for_cpu_mbox + lrs $ACL0, @CMBL + andi $acl1, #0x7fff + + sr @MEM_HI, $ACL1 + sr @MEM_LO, $ACL0 + + lri $r18, #0 + lri $r19, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $r1a, #0x2000 + lr $r1c, @MEM_HI + lr $r1e, @MEM_LO + call do_dma + + +; get address of registers and DMA them to ram + + call wait_for_dsp_mbox + si @DMBH, #0x8888 + si @DMBL, #0xbeef + si @DIRQ, #0x0001 + + call wait_for_cpu_mbox + lrs $ACL0, @CMBL + andi $acl1, #0x7fff + + sr @MEM_HI, $ACL1 + sr @MEM_LO, $ACL0 + + lri $r18, #REGS_BASE + lri $r19, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $r1a, #0x80 + lr $r1c, @MEM_HI + lr $r1e, @MEM_LO + call do_dma + +; Read in all the registers from RAM + + lri $r00, #REGS_BASE+1 + lrri $r01, @$r00 + lrri $r02, @$r00 + lrri $r03, @$r00 + lrri $r04, @$r00 + lrri $r05, @$r00 + lrri $r06, @$r00 + lrri $r07, @$r00 + lrri $r08, @$r00 + lrri $r09, @$r00 + lrri $r0a, @$r00 + lrri $r0b, @$r00 + lrri $r0c, @$r00 + lrri $r0d, @$r00 + lrri $r0e, @$r00 + lrri $r0f, @$r00 + lrri $r10, @$r00 + lrri $r11, @$r00 + lrri $r12, @$r00 + lrri $r13, @$r00 + lrri $r14, @$r00 + lrri $r15, @$r00 + lrri $r16, @$r00 + lrri $r17, @$r00 + lrri $r18, @$r00 + lrri $r19, @$r00 + lrri $r1a, @$r00 + lrri $r1b, @$r00 + lrri $r1c, @$r00 + lrri $r1d, @$r00 + lrri $r1e, @$r00 + lrri $r1f, @$r00 + lr $r00, @REGS_BASE + +; Right here we are at a specific predetermined state. +; Ideal environment to try instructions. + +; We can call send_back at any time to send data back to the PowerPC. + +; Calling set40 here seemed to crash the dsp tester in strange ways +; until I added set16 in send_back. Seems clear that it affects something important. + + lri $R04, #0x0000 + lri $R13, #0x0001 + + ifl + lri $R04, #0x1337 + call send_back + + ifge + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x0002 + + ifl + lri $R04, #0x1337 + call send_back + + ifge + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x0004 + + ifl + lri $R04, #0x1337 + call send_back + + ifge + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x0008 + + ifl + lri $R04, #0x1337 + call send_back + + ifge + lri $R04, #0x1338 + call send_back + + lri $R04, #0x0000 + lri $R13, #0x000a + + ifl + lri $R04, #0x1337 + call send_back + + ifge + lri $R04, #0x1338 + call send_back +; We're done - currently we only test one opcode, in this case 0x8600. +; It's possible to test many more in one go - just call send_back after each one. + + jmp ende + +; Below here is tons of random leftover test code from whoever last experimented with this. + +; call dump_memory +; call send_back + + cw 0x00de + cw 0x03f1 + call send_back + + cw 0x0200 + cw 0x0a60 + call send_back + + cw 0x1c7e + call send_back + + cw 0x8100 + call send_back + + cw 0x8900 + call send_back + + cw 0x009f + cw 0x00a0 + call send_back + + cw 0x00de + cw 0x03f1 + call send_back + + cw 0x5d00 + call send_back + + cw 0x0e50 + call send_back + + cw 0x0750 + call send_back + + cw 0x0270 + call send_back + + cw 0x5d00 + call send_back + + cw 0x00da + cw 0x03f2 + call send_back + + cw 0x8600 + call send_back + + JNS g_0c4d +; cw 0x0290 +; cw 0x0c4d +; call send_back JX0 + + cw 0x00de + cw 0x03f3 + call send_back + + cw 0x5c00 + call send_back + + JLE g_0c38 +; cw 0x0293 +; cw 0x0c38 JX3 +; call send_back + + JMP g_0c52 + +; cw 0x029f +; cw 0x0c52 +; call send_back + +g_0c38: + cw 0x00db + cw 0x03f7 + call send_back + + cw 0x009e + cw 0x8000 + call send_back + + cw 0x4600 + call send_back + + JMP g_0c44 +; cw 0x029f +; cw 0x0c44 +; call send_back + +g_0c3f: + cw 0x00db + cw 0x03f7 + call send_back + + cw 0x009e + cw 0x8000 + call send_back + + cw 0x5600 + call send_back + +g_0c44: + cw 0x00fe + cw 0x03f5 + call send_back + + cw 0x1fda + call send_back + + cw 0x7c00 + call send_back + + cw 0x1f5e + call send_back + + cw 0x00fe + cw 0x03f2 + call send_back + + JMP g_0c52 +; cw 0x029f +; cw 0x0c52 +; call send_back + +g_0c4d: + + cw 0x00de + cw 0x03f4 + call send_back + + cw 0x5d00 + call send_back + + JLE g_0c3f +; cw 0x0293 +; cw 0x0c3f +; call send_back + +g_0c52: + cw 0x8900 + call send_back + + cw 0x00dd + cw 0x03f5 + call send_back + + cw 0x1501 + call send_back + + cw 0x8100 + call send_back + + cw 0x00dc + cw 0x03f6 + call send_back + + cw 0x008b + cw 0x009f + call send_back + + cw 0x0080 + cw 0x0a00 + call send_back + + cw 0x0900 + call send_back + + BLOOPI #0x50, g_0c65 +; cw 0x1150 +; cw 0x0c65 +; call send_back + + + cw 0x1878 + call send_back + + cw 0x4c00 + call send_back + + cw 0x1cfe + call send_back + + cw 0x001f + call send_back + + cw 0x1fd9 + call send_back +g_0c65: + cw 0x1b18 + call send_back + + cw 0x009f + cw 0x0a60 + call send_back + + cw 0x1fc3 + call send_back + + cw 0x5c00 + call send_back + + cw 0x00fe + cw 0x03f1 + call send_back + + cw 0x00fc + cw 0x03f6 + call send_back + + cw 0x008b + cw 0xffff + call send_back + + +; This is where we jump when we're done testing, see above. +ende: + + nop + nop + nop + nop + nop + nop + nop + +; We just fall into a loop, playing dead until someone resets the DSP. +dead_loop: + jmp dead_loop + +; Utility function to do DMA. +; r1c:r1e - external address. +; r18 - address in DSP +do_dma: + sr @DSMAH, $r1c + sr @DSMAL, $r1e + sr @DSPA, $r18 + sr @DSCR, $r19 + sr @DSBL, $r1a ; This kicks off the DMA. + +; Waits for said DMA to complete by watching a bit in DSCR. +wait_dma: + LRS $ACL1, @DSCR + andcf $acl1, #0x0004 + JLZ wait_dma + RET + +; This waits for a mail to arrive in the DSP in-mailbox. +wait_for_dsp_mbox: + lrs $ACL1, @DMBH + andcf $acl1, #0x8000 + jlz wait_for_dsp_mbox + ret + +; This waits for the CPU to grab a mail that we just sent from the DSP. +wait_for_cpu_mbox: + lrs $ACL1, @cmbh + andcf $acl1, #0x8000 + jlnz wait_for_cpu_mbox + ret + +; IRQ handlers. Not entirely sure what good they do currently. +irq0: + lri $acl0, #0x0000 + jmp irq +irq1: + lri $acl0, #0x0001 + jmp irq +irq2: + lri $acl0, #0x0002 + jmp irq +irq3: + lri $acl0, #0x0003 + jmp irq +irq4: + lri $acl0, #0x0004 + jmp irq +irq5: +; No idea what this code is doing. + set16 + mrr $r0d, $r1c + mrr $r0d, $r1e + clr $acc0 + mrr $r1e, $r0d + mrr $r1c, $r0d + nop ; Or why there's a nop sled here. + nop + nop + nop + nop + nop + rti + + lri $acl0, #0x0005 + jmp irq +irq6: + lri $acl0, #0x0006 + jmp irq +irq7: + lri $acl0, #0x0007 + jmp irq + +irq: + lrs $ACL1, @DMBH + andcf $acl1, #0x8000 + jlz irq + si @DMBH, #0x8BAD + sr @DMBL, $r0b +;sr @DMBL, $acl0 + si @DIRQ, #0x0001 + halt + +; DMA:s the current state of the registers back to the PowerPC. To do this, +; it must write the contents of all regs to DRAM. +send_back: + ; make state safe. + set16 + ; store registers to reg table + sr @REGS_BASE, $r00 + lri $r00, #(REGS_BASE + 1) + srri @$r00, $r01 + srri @$r00, $r02 + srri @$r00, $r03 + srri @$r00, $r04 + srri @$r00, $r05 + srri @$r00, $r06 + srri @$r00, $r07 + srri @$r00, $r08 + srri @$r00, $r09 + srri @$r00, $r0a + srri @$r00, $r0b + srri @$r00, $r0c + srri @$r00, $r0d + srri @$r00, $r0e + srri @$r00, $r0f + srri @$r00, $r10 + srri @$r00, $r11 + srri @$r00, $r12 + srri @$r00, $r13 + srri @$r00, $r14 + srri @$r00, $r15 + srri @$r00, $r16 + srri @$r00, $r17 + srri @$r00, $r18 + srri @$r00, $r19 + srri @$r00, $r1a + srri @$r00, $r1b + srri @$r00, $r1c + srri @$r00, $r1d + srri @$r00, $r1e + srri @$r00, $r1f + +; Regs are stored. Prepare DMA. + lri $r18, #0x0000 + lri $r19, #1 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $r1a, #0x200 + lr $r1c, @MEM_HI + lr $r1e, @MEM_LO + + lri $r01, #8+8 + +; Now, why are we looping here? + bloop $r01, dma_copy + call do_dma + addi $r1e, #0x200 + mrr $r1f, $r18 + addi $r1f, #0x100 + mrr $r18, $r1f + nop + +dma_copy: + nop + +; Wait for the CPU to send us a mail. + call wait_for_dsp_mbox + si @DMBH, #0x8888 + si @DMBL, #0xfeeb + si @DIRQ, #0x0001 + +; wait for the CPU to recieve our response before we execute the next op + call wait_for_cpu_mbox + lrs $ACL0, @CMBL + andi $acl1, #0x7fff + +; Restore all regs again so we're ready to execute another op. + lri $r00, #REGS_BASE+1 + lrri $r01, @$r00 + lrri $r02, @$r00 + lrri $r03, @$r00 + lrri $r04, @$r00 + lrri $r05, @$r00 + lrri $r06, @$r00 + lrri $r07, @$r00 + lrri $r08, @$r00 + lrri $r09, @$r00 + lrri $r0a, @$r00 + lrri $r0b, @$r00 + lrri $r0c, @$r00 + lrri $r0d, @$r00 + lrri $r0e, @$r00 + lrri $r0f, @$r00 + lrri $r10, @$r00 + lrri $r11, @$r00 + lrri $r12, @$r00 + lrri $r13, @$r00 + lrri $r14, @$r00 + lrri $r15, @$r00 + lrri $r16, @$r00 + lrri $r17, @$r00 + lrri $r18, @$r00 + lrri $r19, @$r00 + lrri $r1a, @$r00 + lrri $r1b, @$r00 + lrri $r1c, @$r00 + lrri $r1d, @$r00 + lrri $r1e, @$r00 + lrri $r1f, @$r00 + lr $r00, @REGS_BASE + + ret ; from send_back + +; If you are in set40 mode, use this instead of send_back if you want to stay +; in set40 mode. +send_back_40: + set16 + call send_back + set40 + ret + +; This one's odd. Doesn't look like it should work since it uses acl0 but +; increments acm0... (acc0) +dump_memory: + lri $r02, #0x0000 + lri $acl0, #0x1000 + + lri $r01, #0x1000 + bloop $r01, _fill_loop2 + + mrr $r03, $acl0 + nx'ld : $AX0.H, $AX1.H, @$AR0 + + mrr $r1f, $r00 + mrr $r00, $r02 + srri @$r00, $r1b + mrr $r02, $r00 + mrr $r00, $r1f + + addis $acc0, #0x1 + +_fill_loop2: + nop + ret ; from dump_memory