SPU transfer control

From Final Fantasy Hacktics Wiki
Revision as of 08:01, 21 January 2025 by Talcall (talk | contribs)
Jump to navigation Jump to search

p1 = mode?
     0: tell SPU to start DMA read transfer
     1: tell SPU to stop data transfer
     2: give p2 instruction to SPU control
     3: execute sound data transfer
p2 = spu control instruction << 3 // if p1 = 3, memory address to read sound data from
p3 = size (bytes) of area to transfer
p4 = not used
00018e44: afa40000 sw r4,0x0000(r29)                     # goes to stack.18
00018e48: afa50004 sw r5,0x0004(r29)                     # stack.1c
00018e4c: afa60008 sw r6,0x0008(r29)                     # stack.20
00018e50: afa7000c sw r7,0x000c(r29)                     # stack.24 ? weird ass stack management.
00018e54: 27bdffe8 addiu r29,r29,0xffe8                  # - 0x18
00018e58: afb00010 sw r16,0x0010(r29)
00018e5c: 27b0001c addiu r16,r29,0x001c
00018e60: 34060001 ori r6,r0,0x0001
00018e64: afbf0014 sw r31,0x0014(r29)
00018e68: 1086001a beq r4,r6,0x00018ed4                  # branch if p1 = 1
00018e6c: afa40018 sw r4,0x0018(r29)                     # save p1 over itself
00018e70: 28820002 slti r2,r4,0x0002
00018e74: 10400005 beq r2,r0,0x00018e8c                  # branch if p1 > 1
00018e78: 00000000 nop
00018e7c: 10800031 beq r4,r0,0x00018f44                  # branch if p1 = 0
00018e80: 00001021 addu r2,r0,r0
00018e84: 08006430 j 0x000190c0
00018e88: 00000000 nop
00018e8c: 34020002 ori r2,r0,0x0002
00018e90: 10820005 beq r4,r2,0x00018ea8                  # branch if p1 = 2
00018e94: 34020003 ori r2,r0,0x0003
00018e98: 10820045 beq r4,r2,0x00018fb0                  # branch if p1 = 3
00018e9c: 00001021 addu r2,r0,r0
00018ea0: 08006430 j 0x000190c0                          # else end return 0
00018ea4: 00000000 nop

p1 = 2 (give p2 instruction >> 3 to sound data transfer?)

00018ea8: 8fa4001c lw r4,0x001c(r29)                     # p2
00018eac: 3c028003 lui r2,0x8003
00018eb0: 8c42ad6c lw r2,-0x5294(r2)                     # 3
00018eb4: 3c038003 lui r3,0x8003
00018eb8: 8c63ad44 lw r3,-0x52bc(r3)                     # SPU IO left port address
00018ebc: 00441006 srlv r2,r4,r2                         # p2 >> 3 (?)
00018ec0: 3c018003 lui r1,0x8003
00018ec4: a422ad5c sh r2,-0x52a4(r1)                     # store current instruction to RAM
00018ec8: a46201a6 sh r2,0x01a6(r3)                      # store instruction in sound data transfer address
00018ecc: 08006430 j 0x000190c0                          # return 0
00018ed0: 00001021 addu r2,r0,r0

p1 = 1 (tell SPU to stop data transfer)

00018ed4: 3c058003 lui r5,0x8003
00018ed8: 8ca5ad44 lw r5,-0x52bc(r5)                     # SPU IO port left
00018edc: 3c048003 lui r4,0x8003
00018ee0: 9484ad5c lhu r4,-0x52a4(r4)                    # current spu data transfer instruction
00018ee4: 94a201a6 lhu r2,0x01a6(r5)                     # read from sound data transfer address
00018ee8: 3c018003 lui r1,0x8003
00018eec: ac20ad94 sw r0,-0x526c(r1)                     # set dma not reading?
00018ef0: 3042ffff andi r2,r2,0xffff                     # sound buffer address/8
00018ef4: 10440009 beq r2,r4,0x00018f1c                  # branch if instruction = instruction in port
00018ef8: 00001821 addu r3,r0,r0
sound data transfer instruction != instruction in port
00018efc: 24630001 addiu r3,r3,0x0001
00018f00: 2c620f01 sltiu r2,r3,0x0f01
00018f04: 1040006e beq r2,r0,0x000190c0                  # branch if timed out?
00018f08: 2402fffe addiu r2,r0,0xfffe                    # return -2
00018f0c: 94a201a6 lhu r2,0x01a6(r5)                     # read from sound data transfer address
00018f10: 00000000 nop
00018f14: 1444fffa bne r2,r4,0x00018f00                  # loop if not 0
00018f18: 24630001 addiu r3,r3,0x0001                    # i ++
sound data transfer instruction == instruction in port
00018f1c: 3c038003 lui r3,0x8003
00018f20: 8c63ad44 lw r3,-0x52bc(r3)                     # SPU IO port left
00018f24: 00000000 nop
00018f28: 946401aa lhu r4,0x01aa(r3)                     # read SPU control register
00018f2c: 00000000 nop
00018f30: 3082ffcf andi r2,r4,0xffcf                     # stop sound transfer
00018f34: 34440020 ori r4,r2,0x0020
00018f38: a46401aa sh r4,0x01aa(r3)                      # tell SPU to stop sound transfer
00018f3c: 08006430 j 0x000190c0                          # end return 0
00018f40: 00001021 addu r2,r0,r0

p1 = 0 (tell SPU to start DMA read transfer)

00018f44: 3c058003 lui r5,0x8003
00018f48: 8ca5ad44 lw r5,-0x52bc(r5)                     # SPU IO port left
00018f4c: 3c048003 lui r4,0x8003
00018f50: 9484ad5c lhu r4,-0x52a4(r4)                    # SPU data transfer instruction
00018f54: 94a201a6 lhu r2,0x01a6(r5)                     # read from SPU data transfer address
00018f58: 3c018003 lui r1,0x8003
00018f5c: ac26ad94 sw r6,-0x526c(r1)                     # store dma reading?
00018f60: 3042ffff andi r2,r2,0xffff
00018f64: 10440009 beq r2,r4,0x00018f8c                  # branch if instruction in RAM == instruction in port
00018f68: 00001821 addu r3,r0,r0
instruction in port != instruction in RAM
00018f6c: 24630001 addiu r3,r3,0x0001
00018f70: 2c620f01 sltiu r2,r3,0x0f01
00018f74: 10400052 beq r2,r0,0x000190c0                  # end return -2 if timeout
00018f78: 2402fffe addiu r2,r0,0xfffe
00018f7c: 94a201a6 lhu r2,0x01a6(r5)
00018f80: 00000000 nop
00018f84: 1444fffa bne r2,r4,0x00018f70                  # loop if instructions still not equal
00018f88: 24630001 addiu r3,r3,0x0001
instruction in port == instruction in RAM
00018f8c: 3c028003 lui r2,0x8003
00018f90: 8c42ad44 lw r2,-0x52bc(r2)                     # spu IO port left
00018f94: 00000000 nop
00018f98: 944401aa lhu r4,0x01aa(r2)                     # read from spu control register
00018f9c: 00000000 nop
00018fa0: 34840030 ori r4,r4,0x0030                      # enable DMA read transfer mode
00018fa4: a44401aa sh r4,0x01aa(r2)                      # tell SPU control register
00018fa8: 08006430 j 0x000190c0                          # return 0
00018fac: 00001021 addu r2,r0,r0

p1 = 3 (execute transfer)

00018fb0: 3c028003 lui r2,0x8003
00018fb4: 8c42ad94 lw r2,-0x526c(r2)                     # whether or not dma is reading?
00018fb8: 00000000 nop
00018fbc: 14460002 bne r2,r6,0x00018fc8                  # branch if not reading
00018fc0: 34040020 ori r4,r0,0x0020                      # else check if control is set to dma write mode
00018fc4: 34040030 ori r4,r0,0x0030                      # if reading, check if control is set to dma read mode
00018fc8: 3c058003 lui r5,0x8003
00018fcc: 8ca5ad44 lw r5,-0x52bc(r5)                     # spu IO port left
00018fd0: 00001821 addu r3,r0,r0
00018fd4: 94a201aa lhu r2,0x01aa(r5)                     # read spu control
00018fd8: 3084ffff andi r4,r4,0xffff
00018fdc: 30420030 andi r2,r2,0x0030                     # get spu sound transfer mode
00018fe0: 10440009 beq r2,r4,0x00019008                  # branch if same as current state
spu state does not equal what ram says it is
00018fe4: 24630001 addiu r3,r3,0x0001
00018fe8: 2c620f01 sltiu r2,r3,0x0f01 
00018fec: 10400034 beq r2,r0,0x000190c0                  # end return -2 if timeout
00018ff0: 2402fffe addiu r2,r0,0xfffe
00018ff4: 94a201aa lhu r2,0x01aa(r5)
00018ff8: 00000000 nop
00018ffc: 30420030 andi r2,r2,0x0030
00019000: 1444fff9 bne r2,r4,0x00018fe8                  # loop for as long as they are not equal (or timeout)
00019004: 24630001 addiu r3,r3,0x0001                    # i ++
spu state equals what ram says it is
00019008: 3c038003 lui r3,0x8003
0001900c: 8c63ad94 lw r3,-0x526c(r3)                     # whether or not dma is reading
00019010: 34020001 ori r2,r0,0x0001
spu transfer state is set to dmaread
00019014: 14620005 bne r3,r2,0x0001902c                  # branch if not reading
00019018: 00000000 nop
0001901c: 0c0064de jal 0x00019378                        # 00019378 - 000193a0
00019020: 26100004 addiu r16,r16,0x0004                  # stack 0x20
00019024: 0800640e j 0x00019038
00019028: 3c060100 lui r6,0x0100
spu transfer state is set to dmawrite
0001902c: 0c0064d3 jal 0x0001934c                        # 0001934c - 00019374
00019030: 26100004 addiu r16,r16,0x0004                  # stack 0x20
00019034: 3c060100 lui r6,0x0100                         # 0x0100 0000
00019038: 8e04fffc lw r4,-0x0004(r16)                    # p2
0001903c: 3c018003 lui r1,0x8003
00019040: ac24ad98 sw r4,-0x5268(r1)                     # store in ram mem address to read from
00019044: 8e040000 lw r4,0x0000(r16)                     # size (bytes)
00019048: 3c058003 lui r5,0x8003
0001904c: 8ca5ad48 lw r5,-0x52b8(r5)                     # DMA SPU channel
00019050: 00041982 srl r3,r4,0x06                        # p3 >> 6
00019054: 3082003f andi r2,r4,0x003f                     #
00019058: 0002102b sltu r2,r0,r2                         # rounding
0001905c: 3c048003 lui r4,0x8003
00019060: 8c84ad98 lw r4,-0x5268(r4)                     # mem address
00019064: 00621821 addu r3,r3,r2                         # size (blocks, rounded up)
00019068: 3c018003 lui r1,0x8003
0001906c: ac23ad9c sw r3,-0x5264(r1)
00019070: aca40000 sw r4,0x0000(r5)                      # set channel's mem address
00019074: 3c028003 lui r2,0x8003
00019078: 8c42ad9c lw r2,-0x5264(r2)
0001907c: 3c038003 lui r3,0x8003
00019080: 8c63ad4c lw r3,-0x52b4(r3)                     # DMA SPU block control
00019084: 00021400 sll r2,r2,0x10
00019088: 34420010 ori r2,r2,0x0010
0001908c: ac620000 sw r2,0x0000(r3)                      # number of words
00019090: 3c038003 lui r3,0x8003
00019094: 8c63ad94 lw r3,-0x526c(r3)                     # whether or not DMA is reading
00019098: 34020001 ori r2,r0,0x0001
0001909c: 14620003 bne r3,r2,0x000190ac                  # branch if not reading
000190a0: 34c60201 ori r6,r6,0x0201                      # if not reading, r6 = 0x0100 0201 (RAM to device; madr per step +4; transfer mode slice; start transfer)
000190a4: 3c060100 lui r6,0x0100
000190a8: 34c60200 ori r6,r6,0x0200                      # if reading, r6 = 0x0100 0200 (device to RAM, madr per step +4; transfer mode slice; start transfer)
000190ac: 3c028003 lui r2,0x8003
000190b0: 8c42ad50 lw r2,-0x52b0(r2)                     # DMA SPU channel control
000190b4: 00000000 nop
000190b8: ac460000 sw r6,0x0000(r2)                      # store command
000190bc: 00001021 addu r2,r0,r0                         # return 0
end
000190c0: 8fbf0014 lw r31,0x0014(r29)
000190c4: 8fb00010 lw r16,0x0010(r29)
000190c8: 27bd0018 addiu r29,r29,0x0018
000190cc: 03e00008 jr r31
000190d0: 00000000 nop