From 408623b6e92c0e3e00fb4ddb3bd18b3fe00b2e2d Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 14 Aug 2021 17:36:55 -0700 Subject: [PATCH] docs/DSP: Document behavior of LRS/SRS/SI with CR --- Source/DSPSpy/tests/cr_test.ds | 81 +++++++++++++++++++ .../GameCube_DSP_Users_Manual.tex | 18 +++-- 2 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 Source/DSPSpy/tests/cr_test.ds diff --git a/Source/DSPSpy/tests/cr_test.ds b/Source/DSPSpy/tests/cr_test.ds new file mode 100644 index 0000000000..272e4b8c2a --- /dev/null +++ b/Source/DSPSpy/tests/cr_test.ds @@ -0,0 +1,81 @@ +incdir "tests" +include "dsp_base.inc" + +; Tests the behavior of SI, SRS, and LRS when CR is changed + +; Register that is writable but with contents that doesn't matter (COEF_A1_0) +TEST_REG: equ 0xFFA0 ; 0xFF00 (not writable) +; This is separate because SRS and SI currently require value 0..7f or ff80..ffff, +; though the actual behavior doesn't match that +TEST_ADDR: equ 0xFFA0 ; 0x0000 +; Memory addresses +TEST_MEM: equ 0x00A0 ; 0x0000 +TEST_MEM_2: equ 0x01A0 ; 0x0100 + + LRI $AC0.L, #0xf00f + SR @TEST_REG, $AC0.L + SR @TEST_MEM, $AC0.L + SR @TEST_MEM_2, $AC0.L + CALL send_regs + + ; Observed: writes to TEST_REG + SI @TEST_ADDR, #0xf11f + CALL send_regs + + LRI $AC0.L, #0xf22f + ; Observed: writes to TEST_REG + SRS @TEST_ADDR, $AC0.L + CALL send_regs + + LRI $CR, #0x0000 + ; Observed: still writes to TEST_REG + SI @TEST_ADDR, #0xf33f + CALL send_regs + + LRI $AC0.L, #0xf44f + ; Observed: writes to TEST_MEM + SRS @TEST_ADDR, $AC0.L + CALL send_regs + + LRI $CR, #0x0001 + ; Observed: still writes to TEST_REG + SI @TEST_ADDR, #0xf55f + CALL send_regs + + LRI $AC0.L, #0xf66f + ; Observed: writes to TEST_MEM_2 + SRS @TEST_ADDR, $AC0.L + CALL send_regs + + ; At this point, TEST_REG should be f55f, TEST_MEM should be f44f, + ; and TEST_MEM_2 should be f66f. Test the behavior of LRS. + ; Changes to prod.l are for display only. + LRI $CR, #0x00ff + LRI $prod.l, #0xf55f + LRS $AC0.L, @TEST_ADDR + CALL send_regs + + LRI $CR, #0x0000 + LRI $prod.l, #0xf44f + LRS $AC0.L, @TEST_ADDR + CALL send_regs + + LRI $CR, #0x0001 + LRI $prod.l, #0xf66f + LRS $AC0.L, @TEST_ADDR + CALL send_regs + +; We're done, DO NOT DELETE THIS LINE + JMP end_of_test + +send_regs: + ; For display purposes only + LRI $prod.m1, #TEST_REG + LRI $prod.h, #TEST_MEM + LRI $prod.m2, #TEST_MEM_2 + ; Actual registers + LR $AC1.L, @TEST_REG + LR $AC0.M, @TEST_MEM + LR $AC1.M, @TEST_MEM_2 + CALL send_back + RET diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 6980489b8c..615a834bc0 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -534,7 +534,7 @@ If the value is not zero, then the PC is modified by the value from call stack \ \section{Config register} -Its purpose is unknown at this time. It is written with \Value{0x00FF} and \Value{0x0004} values. +Serves as a base offset for \Opcode{SRS} and \Opcode{LRS}. Zelda uCode writes it with \Value{0x0004}, but otherwise it is usually \Value{0x00FF}. This is an 8-bit register. Writes to the upper 8 bits are ignored and those bits always read back as 0. @@ -2558,12 +2558,12 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Move value from data memory pointed by address \Address{M} (8-bit sign-extended) to register \Register{\$(0x18+D)}. + \item Move value from data memory pointed by address \Address{(\$cr << 8) | M} to register \Register{\$(0x18+D)}. Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $(0x18+D) = MEM[M] + $(0x18+D) = MEM[($cr << 8) | M] $pc++ \end{DSPOpcodeOperation} @@ -3843,14 +3843,18 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Store 16-bit immediate value \Value{I} to a memory location pointed by address \Address{M} (\Address{M} is an 8-bit sign-extended value). + \item Store 16-bit immediate value \Value{I} to a memory location pointed by address \Address{0xFF00 | M}. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - MEM[M] = I + MEM[0xFF00 | M] = I $pc += 2 \end{DSPOpcodeOperation} + \begin{DSPOpcodeNote} + \item Unlike \Opcode{LRS} and \Opcode{SRS}, \Opcode{SI} does not use \Register{\$cr} to decide the base address and instead always uses \Address{0xFF00}. + \end{DSPOpcodeNote} + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} @@ -3979,12 +3983,12 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Store value from register \Register{\$(0x18+S)} to a memory pointed by address \Address{M} (8-bit sign-extended). + \item Store value from register \Register{\$(0x18+S)} to a memory pointed by address \Address{(\$cr << 8) | M}. Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - MEM[M] = $(0x18+S) + MEM[($cr << 8) | M] = $(0x18+S) $pc++ \end{DSPOpcodeOperation}