diff --git a/Source/DSPSpy/tests/dsp_base.inc b/Source/DSPSpy/tests/dsp_base.inc index 95816250a8..685c634d95 100644 --- a/Source/DSPSpy/tests/dsp_base.inc +++ b/Source/DSPSpy/tests/dsp_base.inc @@ -1,9 +1,3 @@ -; This is the trojan program we send to the DSP from DSPSpy to figure it out. -REGS_BASE: equ 0x0f80 -MEM_HI: equ 0x0f7E -MEM_LO: equ 0x0f7F - - ; Interrupt vectors 8 vectors, 2 opcodes each jmp irq0 jmp irq1 @@ -14,279 +8,5 @@ MEM_LO: equ 0x0f7F jmp irq6 jmp irq7 -; Main code (and normal entrypoint) at 0x10 - sbset #0x02 - sbset #0x03 - sbclr #0x04 - sbset #0x05 - sbset #0x06 - - s16 - lri $CR, #0x00ff - - clr $acc1 - clr $acc0 - -; get address of memory dump and copy it to DRAM - call 0x807e - si @DMBH, #0x8888 - si @DMBL, #0xdead - si @DIRQ, #0x0001 - - call 0x8078 - andi $ac0.m, #0x7fff - lrs $ac1.m, @CMBL - - sr @MEM_HI, $ac0.m - sr @MEM_LO, $ac1.m - - lri $ax0.l, #0 - lri $ax1.l, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) - lri $ax0.h, #0x2000 - lr $ac0.l, @MEM_HI - lr $ac0.m, @MEM_LO - call do_dma - - -; get address of registers and DMA them to ram - call 0x807e - si @DMBH, #0x8888 - si @DMBL, #0xbeef - si @DIRQ, #0x0001 - - call 0x8078 - andi $ac0.m, #0x7fff - lrs $ac1.m, @CMBL - - sr @MEM_HI, $ac0.m - sr @MEM_LO, $ac1.m - - lri $ax0.l, #REGS_BASE - lri $ax1.l, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) - lri $ax0.h, #0x80 - lr $ac0.l, @MEM_HI - lr $ac0.m, @MEM_LO - call do_dma - -; Read in all the registers from RAM - lri $ar0, #REGS_BASE+1 - lrri $ar1, @$ar0 - lrri $ar2, @$ar0 - lrri $ar3, @$ar0 - lrri $ix0, @$ar0 - lrri $ix1, @$ar0 - lrri $ix2, @$ar0 - lrri $ix3, @$ar0 - lrri $wr0, @$ar0 - lrri $wr1, @$ar0 - lrri $wr2, @$ar0 - lrri $wr3, @$ar0 - lrri $st0, @$ar0 - lrri $st1, @$ar0 - lrri $st2, @$ar0 - lrri $st3, @$ar0 - lrri $ac0.h, @$ar0 - lrri $ac1.h, @$ar0 - lrri $cr, @$ar0 - lrri $sr, @$ar0 - lrri $prod.l, @$ar0 - lrri $prod.m1, @$ar0 - lrri $prod.h, @$ar0 - lrri $prod.m2, @$ar0 - lrri $ax0.l, @$ar0 - lrri $ax1.l, @$ar0 - lrri $ax0.h, @$ar0 - lrri $ax1.h, @$ar0 - lrri $ac0.l, @$ar0 - lrri $ac1.l, @$ar0 - lrri $ac0.m, @$ar0 - lrri $ac1.m, @$ar0 - lr $ar0, @REGS_BASE - - jmp start_of_test - -; This is where we jump when we're done testing, see above. -; We just fall into a loop, playing dead until someone resets the DSP. -end_of_test: - nop - jmp end_of_test - -; Utility function to do DMA. -do_dma: - sr @DSMAH, $ac0.l - sr @DSMAL, $ac0.m - sr @DSPA, $ax0.l - sr @DSCR, $ax1.l - sr @DSBL, $ax0.h ; This kicks off the DMA. -wait_dma_finish: - lr $ac1.m, @DSCR - andcf $ac1.m, #0x4 - jlz wait_dma_finish - ret - -; IRQ handlers. Just send back exception# and die -irq0: - lri $ac0.m, #0x0000 - jmp irq -irq1: - lri $ac0.m, #0x0001 - jmp irq -irq2: - lri $ac0.m, #0x0002 - jmp irq -irq3: - lri $ac0.m, #0x0003 - jmp irq -irq4: - lri $ac0.m, #0x0004 - jmp irq -irq5: - lrs $ac0.m, @DMBH - andcf $ac0.m, #0x8000 - jlz irq5 - si @DMBH, #0x8005 - si @DMBL, #0x0000 - si @DIRQ, #0x0001 - lri $ac0.m, #0xbbbb - sr @0xffda, $ac0.m ; pred scale - sr @0xffdb, $ac0.m ; yn1 - lr $ix2, @ARAM - sr @0xffdc, $ac0.m ; yn2 - rti -irq6: - lri $ac0.m, #0x0006 - jmp irq -irq7: - lri $ac0.m, #0x0007 - -irq: - lrs $ac1.m, @DMBH - andcf $ac1.m, #0x8000 - jlz irq - si @DMBH, #0x8bad - ;sr @DMBL, $wr3 ; ??? - sr @DMBL, $ac0.m ; Exception number - si @DIRQ, #0x0001 - halt ; Through some magic this allows us to properly ack the exception in dspspy - ;rti ; allow dumping of ucodes which cause exceptions...probably not safe at all - -; 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: - ; first, store $sr so we can modify it - sr @(REGS_BASE + 19), $sr - set16 - ; Now store $wr0, as it must be 0xffff for srri to work as we expect - sr @(REGS_BASE + 8), $wr0 - lri $wr0, #0xffff - ; store registers to reg table - sr @REGS_BASE, $ar0 - lri $ar0, #(REGS_BASE + 1) - srri @$ar0, $ar1 - srri @$ar0, $ar2 - srri @$ar0, $ar3 - srri @$ar0, $ix0 - srri @$ar0, $ix1 - srri @$ar0, $ix2 - srri @$ar0, $ix3 - ; skip $wr0 since we already stored and modified it - iar $ar0 - srri @$ar0, $wr1 - srri @$ar0, $wr2 - srri @$ar0, $wr3 - srri @$ar0, $st0 - srri @$ar0, $st1 - srri @$ar0, $st2 - srri @$ar0, $st3 - srri @$ar0, $ac0.h - srri @$ar0, $ac1.h - srri @$ar0, $cr - ; skip $sr since we already stored and modified it - iar $ar0 - srri @$ar0, $prod.l - srri @$ar0, $prod.m1 - srri @$ar0, $prod.h - srri @$ar0, $prod.m2 - srri @$ar0, $ax0.l - srri @$ar0, $ax1.l - srri @$ar0, $ax0.h - srri @$ar0, $ax1.h - srri @$ar0, $ac0.l - srri @$ar0, $ac1.l - srri @$ar0, $ac0.m - srri @$ar0, $ac1.m - -; Regs are stored. Prepare DMA. -; $cr must be 0x00ff because the ROM uses lrs and srs with the assumption that -; they will modify hardware registers. - lri $cr, #0x00ff - lri $ax0.l, #0x0000 - lri $ax1.l, #1 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) - lri $ax0.h, #0x200 - lr $ac0.l, @MEM_HI - lr $ac0.m, @MEM_LO - -; Now, why are we looping here? - lri $ar1, #8+8 - bloop $ar1, dma_copy - call do_dma - addi $ac0.m, #0x200 - mrr $ac1.m, $ax0.l - addi $ac1.m, #0x100 -dma_copy: - mrr $ax0.l, $ac1.m - -; Wait for the CPU to send us a mail. - call 0x807e - si @DMBH, #0x8888 - si @DMBL, #0xfeeb - si @DIRQ, #0x0001 - -; wait for the CPU to recieve our response before we execute the next op - call 0x8078 - andi $ac0.m, #0x7fff - lrs $ac1.m, @CMBL - -; Restore all regs again so we're ready to execute another op. - lri $ar0, #REGS_BASE+1 - lrri $ar1, @$ar0 - lrri $ar2, @$ar0 - lrri $ar3, @$ar0 - lrri $ix0, @$ar0 - lrri $ix1, @$ar0 - lrri $ix2, @$ar0 - lrri $ix3, @$ar0 - ; leave $wr for later - iar $ar0 - lrri $wr1, @$ar0 - lrri $wr2, @$ar0 - lrri $wr3, @$ar0 - lrri $st0, @$ar0 - lrri $st1, @$ar0 - lrri $st2, @$ar0 - lrri $st3, @$ar0 - lrri $ac0.h, @$ar0 - lrri $ac1.h, @$ar0 - lrri $cr, @$ar0 - ; leave $sr for later - iar $ar0 - lrri $prod.l, @$ar0 - lrri $prod.m1, @$ar0 - lrri $prod.h, @$ar0 - lrri $prod.m2, @$ar0 - lrri $ax0.l, @$ar0 - lrri $ax1.l, @$ar0 - lrri $ax0.h, @$ar0 - lrri $ax1.h, @$ar0 - lrri $ac0.l, @$ar0 - lrri $ac1.l, @$ar0 - lrri $ac0.m, @$ar0 - lrri $ac1.m, @$ar0 - lr $ar0, @REGS_BASE - lr $wr0, @(REGS_BASE+8) - lr $sr, @(REGS_BASE+19) - - ret ; from send_back - -; Obviously this must be included directly before your test code -start_of_test: +; The rest is in dsp_base_noirq.inc +include "dsp_base_noirq.inc" diff --git a/Source/DSPSpy/tests/dsp_base_noirq.inc b/Source/DSPSpy/tests/dsp_base_noirq.inc new file mode 100644 index 0000000000..1d2f815e41 --- /dev/null +++ b/Source/DSPSpy/tests/dsp_base_noirq.inc @@ -0,0 +1,286 @@ +; This is the trojan program we send to the DSP from DSPSpy to figure it out. +REGS_BASE: equ 0x0f80 +MEM_HI: equ 0x0f7E +MEM_LO: equ 0x0f7F + +WARNPC 0x10 +ORG 0x10 + +; Main code (and normal entrypoint) at 0x10 +; It is expected that IRQs were listed beforehand +; (e.g. by including dsp_base.inc instead of dsp_base_noirq.inc) + sbset #0x02 + sbset #0x03 + sbclr #0x04 + sbset #0x05 + sbset #0x06 + + s16 + lri $CR, #0x00ff + + clr $acc1 + clr $acc0 + +; get address of memory dump and copy it to DRAM + call 0x807e + si @DMBH, #0x8888 + si @DMBL, #0xdead + si @DIRQ, #0x0001 + + call 0x8078 + andi $ac0.m, #0x7fff + lrs $ac1.m, @CMBL + + sr @MEM_HI, $ac0.m + sr @MEM_LO, $ac1.m + + lri $ax0.l, #0 + lri $ax1.l, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $ax0.h, #0x2000 + lr $ac0.l, @MEM_HI + lr $ac0.m, @MEM_LO + call do_dma + + +; get address of registers and DMA them to ram + call 0x807e + si @DMBH, #0x8888 + si @DMBL, #0xbeef + si @DIRQ, #0x0001 + + call 0x8078 + andi $ac0.m, #0x7fff + lrs $ac1.m, @CMBL + + sr @MEM_HI, $ac0.m + sr @MEM_LO, $ac1.m + + lri $ax0.l, #REGS_BASE + lri $ax1.l, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $ax0.h, #0x80 + lr $ac0.l, @MEM_HI + lr $ac0.m, @MEM_LO + call do_dma + +; Read in all the registers from RAM + lri $ar0, #REGS_BASE+1 + lrri $ar1, @$ar0 + lrri $ar2, @$ar0 + lrri $ar3, @$ar0 + lrri $ix0, @$ar0 + lrri $ix1, @$ar0 + lrri $ix2, @$ar0 + lrri $ix3, @$ar0 + lrri $wr0, @$ar0 + lrri $wr1, @$ar0 + lrri $wr2, @$ar0 + lrri $wr3, @$ar0 + lrri $st0, @$ar0 + lrri $st1, @$ar0 + lrri $st2, @$ar0 + lrri $st3, @$ar0 + lrri $ac0.h, @$ar0 + lrri $ac1.h, @$ar0 + lrri $cr, @$ar0 + lrri $sr, @$ar0 + lrri $prod.l, @$ar0 + lrri $prod.m1, @$ar0 + lrri $prod.h, @$ar0 + lrri $prod.m2, @$ar0 + lrri $ax0.l, @$ar0 + lrri $ax1.l, @$ar0 + lrri $ax0.h, @$ar0 + lrri $ax1.h, @$ar0 + lrri $ac0.l, @$ar0 + lrri $ac1.l, @$ar0 + lrri $ac0.m, @$ar0 + lrri $ac1.m, @$ar0 + lr $ar0, @REGS_BASE + + jmp start_of_test + +; This is where we jump when we're done testing, see above. +; We just fall into a loop, playing dead until someone resets the DSP. +end_of_test: + nop + jmp end_of_test + +; Utility function to do DMA. +do_dma: + sr @DSMAH, $ac0.l + sr @DSMAL, $ac0.m + sr @DSPA, $ax0.l + sr @DSCR, $ax1.l + sr @DSBL, $ax0.h ; This kicks off the DMA. +wait_dma_finish: + lr $ac1.m, @DSCR + andcf $ac1.m, #0x4 + jlz wait_dma_finish + ret + +; IRQ handlers. Just send back exception# and die +irq0: + lri $ac0.m, #0x0000 + jmp irq +irq1: + lri $ac0.m, #0x0001 + jmp irq +irq2: + lri $ac0.m, #0x0002 + jmp irq +irq3: + lri $ac0.m, #0x0003 + jmp irq +irq4: + lri $ac0.m, #0x0004 + jmp irq +irq5: + lrs $ac0.m, @DMBH + andcf $ac0.m, #0x8000 + jlz irq5 + si @DMBH, #0x8005 + si @DMBL, #0x0000 + si @DIRQ, #0x0001 + lri $ac0.m, #0xbbbb + sr @0xffda, $ac0.m ; pred scale + sr @0xffdb, $ac0.m ; yn1 + lr $ix2, @ARAM + sr @0xffdc, $ac0.m ; yn2 + rti +irq6: + lri $ac0.m, #0x0006 + jmp irq +irq7: + lri $ac0.m, #0x0007 + +irq: + lrs $ac1.m, @DMBH + andcf $ac1.m, #0x8000 + jlz irq + si @DMBH, #0x8bad + ;sr @DMBL, $wr3 ; ??? + sr @DMBL, $ac0.m ; Exception number + si @DIRQ, #0x0001 + halt ; Through some magic this allows us to properly ack the exception in dspspy + ;rti ; allow dumping of ucodes which cause exceptions...probably not safe at all + +; 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: + ; first, store $sr so we can modify it + sr @(REGS_BASE + 19), $sr + set16 + ; Now store $wr0, as it must be 0xffff for srri to work as we expect + sr @(REGS_BASE + 8), $wr0 + lri $wr0, #0xffff + ; store registers to reg table + sr @REGS_BASE, $ar0 + lri $ar0, #(REGS_BASE + 1) + srri @$ar0, $ar1 + srri @$ar0, $ar2 + srri @$ar0, $ar3 + srri @$ar0, $ix0 + srri @$ar0, $ix1 + srri @$ar0, $ix2 + srri @$ar0, $ix3 + ; skip $wr0 since we already stored and modified it + iar $ar0 + srri @$ar0, $wr1 + srri @$ar0, $wr2 + srri @$ar0, $wr3 + srri @$ar0, $st0 + srri @$ar0, $st1 + srri @$ar0, $st2 + srri @$ar0, $st3 + srri @$ar0, $ac0.h + srri @$ar0, $ac1.h + srri @$ar0, $cr + ; skip $sr since we already stored and modified it + iar $ar0 + srri @$ar0, $prod.l + srri @$ar0, $prod.m1 + srri @$ar0, $prod.h + srri @$ar0, $prod.m2 + srri @$ar0, $ax0.l + srri @$ar0, $ax1.l + srri @$ar0, $ax0.h + srri @$ar0, $ax1.h + srri @$ar0, $ac0.l + srri @$ar0, $ac1.l + srri @$ar0, $ac0.m + srri @$ar0, $ac1.m + +; Regs are stored. Prepare DMA. +; $cr must be 0x00ff because the ROM uses lrs and srs with the assumption that +; they will modify hardware registers. + lri $cr, #0x00ff + lri $ax0.l, #0x0000 + lri $ax1.l, #1 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) + lri $ax0.h, #0x200 + lr $ac0.l, @MEM_HI + lr $ac0.m, @MEM_LO + +; Now, why are we looping here? + lri $ar1, #8+8 + bloop $ar1, dma_copy + call do_dma + addi $ac0.m, #0x200 + mrr $ac1.m, $ax0.l + addi $ac1.m, #0x100 +dma_copy: + mrr $ax0.l, $ac1.m + +; Wait for the CPU to send us a mail. + call 0x807e + si @DMBH, #0x8888 + si @DMBL, #0xfeeb + si @DIRQ, #0x0001 + +; wait for the CPU to recieve our response before we execute the next op + call 0x8078 + andi $ac0.m, #0x7fff + lrs $ac1.m, @CMBL + +; Restore all regs again so we're ready to execute another op. + lri $ar0, #REGS_BASE+1 + lrri $ar1, @$ar0 + lrri $ar2, @$ar0 + lrri $ar3, @$ar0 + lrri $ix0, @$ar0 + lrri $ix1, @$ar0 + lrri $ix2, @$ar0 + lrri $ix3, @$ar0 + ; leave $wr for later + iar $ar0 + lrri $wr1, @$ar0 + lrri $wr2, @$ar0 + lrri $wr3, @$ar0 + lrri $st0, @$ar0 + lrri $st1, @$ar0 + lrri $st2, @$ar0 + lrri $st3, @$ar0 + lrri $ac0.h, @$ar0 + lrri $ac1.h, @$ar0 + lrri $cr, @$ar0 + ; leave $sr for later + iar $ar0 + lrri $prod.l, @$ar0 + lrri $prod.m1, @$ar0 + lrri $prod.h, @$ar0 + lrri $prod.m2, @$ar0 + lrri $ax0.l, @$ar0 + lrri $ax1.l, @$ar0 + lrri $ax0.h, @$ar0 + lrri $ax1.h, @$ar0 + lrri $ac0.l, @$ar0 + lrri $ac1.l, @$ar0 + lrri $ac0.m, @$ar0 + lrri $ac1.m, @$ar0 + lr $ar0, @REGS_BASE + lr $wr0, @(REGS_BASE+8) + lr $sr, @(REGS_BASE+19) + + ret ; from send_back + +; Obviously this must be included directly before your test code +start_of_test: