summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authornakeee <nakeee@gmail.com>2009-04-23 08:55:12 +0000
committernakeee <nakeee@gmail.com>2009-04-23 08:55:12 +0000
commitac55a807ef15c3f95d255bf36d4e3939414dca56 (patch)
tree796fef2e5874b4d59176dba95b852cfca741a89c /Source
parent992dcea5ce153fd95c1897b2dcf4f02a8792e8b4 (diff)
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
Diffstat (limited to 'Source')
-rw-r--r--Source/DSPSpy/tests/dsp_code.ds (renamed from Source/DSPSpy/dsp_code.ds)0
-rw-r--r--Source/DSPSpy/tests/if_test.ds698
-rw-r--r--Source/DSPSpy/tests/if_test2.ds698
-rw-r--r--Source/DSPSpy/tests/if_test3.ds698
4 files changed, 2094 insertions, 0 deletions
diff --git a/Source/DSPSpy/dsp_code.ds b/Source/DSPSpy/tests/dsp_code.ds
index c9b4adf9bc..c9b4adf9bc 100644
--- a/Source/DSPSpy/dsp_code.ds
+++ b/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