Reality Signal Processor/Interface: Difference between revisions

Jump to navigation Jump to search
Content added Content deleted
No edit summary
Line 25: Line 25:


All DMA registers are double-buffered: this means that it is possible to program a DMA transfer while another one is in progress. As soon as the first transfer finishes, the second one will start. The RSP status register reports in separate bits whether there is a transfer ongoing, and whether there is a transfer pending.
All DMA registers are double-buffered: this means that it is possible to program a DMA transfer while another one is in progress. As soon as the first transfer finishes, the second one will start. The RSP status register reports in separate bits whether there is a transfer ongoing, and whether there is a transfer pending.

DMA transfers only happen between 8-byte aligned addresses (in both RDRAM and IMEM/DMEM). DMA registers do not allow misaligned addresses to be written, as the lowest 3 bits are ignored and fixed to 0. The same applies to the length registers, so that the transfer size is always a multiple of 8.


== RSP Internal Registers ==
== RSP Internal Registers ==
Line 39: Line 41:
|0x0404 0000
|0x0404 0000
|c0
|c0
|SP_DMA_SPADDR
|SP_MEM_ADDR
|Address in IMEM/DMEM for a DMA transfer
|Address in IMEM/DMEM for a DMA transfer
|-
|-
|0x0404 0004
|0x0404 0004
|c1
|c1
|SP_DMA_RAMADDR
|SP_DRAM_ADDR
|Address in RDRAM for a DMA transfer
|Address in RDRAM for a DMA transfer
|-
|-
|0x0404 0008
|0x0404 0008
|c2
|c2
|SP_DMA_RDLEN
|SP_RD_LEN
|Length of a DMA transfer. Writing this register triggers a DMA transfer from RDRAM to IMEM/DMEM
|Length of a DMA transfer. Writing this register triggers a DMA transfer from RDRAM to IMEM/DMEM
|-
|-
|0x0404 000C
|0x0404 000C
|c3
|c3
|SP_DMA_WRLEN
|SP_WR_LEN
|Length of a DMA transfer. Writing this register triggers a DMA transfer from IMEM/DMEM to RDRAM.
|Length of a DMA transfer. Writing this register triggers a DMA transfer from IMEM/DMEM to RDRAM.
|-
|-
Line 78: Line 80:
|}
|}


=== SP_MEM_ADDR ===
=== SP_DMA_SPADDR ===
{{#invoke:Register table|head|850px|SP_MEM_ADDR <code>0x0404 0000</code> (RSP COP0: <code>c0</code>)}}
{{#invoke:Register table|head|850px|SP_DMA_SPADDR <code>0x0404 0000</code> (RSP COP0: <code>c0</code>)}}
{{#invoke:Register table|row|31:24}}
{{#invoke:Register table|row|31:24}}
| U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0
| U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0
Line 93: Line 95:
| colspan="3" | — || MEM_BANK || colspan="4" | MEM_ADDR[11:8]
| colspan="3" | — || MEM_BANK || colspan="4" | MEM_ADDR[11:8]
{{#invoke:Register table|row|7:0}}
{{#invoke:Register table|row|7:0}}
| RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0
| RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || U-0 || U-0 || U-0
|-
|-
| colspan="8" | MEM_ADDR[7:0]
| colspan="5" | MEM_ADDR[7:3] || 0 || 0 || 0
{{#invoke:Register table|foot}}{{#invoke:Register table|definitions
{{#invoke:Register table|foot}}{{#invoke:Register table|definitions
| 31-13 | Undefined | Initialized to <code>0</code>
| 31-13 | Undefined | Initialized to <code>0</code>
| 12 | MEM_BANK | Bank accessed by the transfer <br>0 {{=}} DMEM <br>1 {{=}} IMEM
| 12 | MEM_BANK | Bank accessed by the transfer <br>0 {{=}} DMEM <br>1 {{=}} IMEM
| 11-0 | MEM_ADDR[11:0] | DMEM or IMEM address used in SP DMAs
| 11-0 | MEM_ADDR[11:0] | DMEM or IMEM address used in SP DMAs. Notice that the lowest 3 bits are always 0.
}}
}}
'''Extra Details:'''
'''Extra Details:'''
: '''MEM_BANK'''
: '''MEM_BANK'''
:: This bit select the memory bank that will be accessed by the DMA transfer. Notice that, even though the memory banks appear to be contiguous in VR4300 address space, it is not possible to perform a single DMA transfers that spans across two banks. Each transfer will only access a single bank. For instance, to load a microcode, it is normally necessary to do two separate transfers: one for IMEM and one for DMEM.
:: This bit selects the memory bank that will be accessed by the DMA transfer. Notice that, even though the memory banks appear to be contiguous in VR4300 address space, it is not possible to perform a single DMA transfers that spans across two banks. Each transfer will only access a single bank. For instance, to load a microcode, it is normally necessary to do two separate transfers: one for IMEM and one for DMEM.
: '''MEM_ADDR'''
:: This field contains the address in SP memory where the DMA transfer begins. The address is always aligned to 8 bytes, as the lowest 3 bits cannot be written. Notice that after writing to this register, the value is latched by SP but it is kept "pending" until the transfer is initiated via writes to <code>SP_DMA_WRLEN</code> or <code>SP_DMA_RDLEN</code>. Reads will continue returning the current (non-pending) value that refers to either an ongoing DMA transfer, or the last finished one. After a DMA transfer is finished, reading this register contains the address after the last one that was written.


=== SP_DRAM_ADDR ===
=== SP_DMA_RAMADDR ===
{{#invoke:Register table|head|550px|SP_DRAM_ADDR <code>0x0404 0004</code> (RSP COP0: <code>c1</code>)}}
{{#invoke:Register table|head|550px|SP_DMA_RAMADDR <code>0x0404 0004</code> (RSP COP0: <code>c1</code>)}}
{{#invoke:Register table|row|31:24}}
{{#invoke:Register table|row|31:24}}
| U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0
| U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0 || U-0
Line 120: Line 124:
| colspan="8" | DRAM_ADDR[15:8]
| colspan="8" | DRAM_ADDR[15:8]
{{#invoke:Register table|row|7:0}}
{{#invoke:Register table|row|7:0}}
| RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0
| RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || U-0 || U-0 || U-0
|-
|-
| colspan="8" | DRAM_ADDR[7:0]
| colspan="5" | DRAM_ADDR[7:3] || 0 || 0 || 0
{{#invoke:Register table|foot}}{{#invoke:Register table|definitions
{{#invoke:Register table|foot}}{{#invoke:Register table|definitions
| 31-24 | Undefined | Initialized to <code>0</code>
| 31-24 | Undefined | Initialized to <code>0</code>
| 23-0 | DRAM_ADDR[23:0] | RDRAM address used in SP DMAs
| 23-0 | DRAM_ADDR[23:0] | RDRAM address used in SP DMAs. Notice that the lowest 3 bits are always 0.
}}
}}
'''Extra Details:'''
: '''MEM_ADDR'''
:: This field contains the address in RDRAM memory where the DMA transfer begins. The address is always aligned to 8 bytes, as the lowest 3 bits cannot be written. Notice that after writing to this register, the value is latched by SP but it is kept "pending" until the transfer is initiated via writes to <code>SP_DMA_WRLEN</code> or <code>SP_DMA_RDLEN</code>. Reads will continue returning the current (non-pending) value that refers to either an ongoing DMA transfer, or the last finished one. After a DMA transfer is finished, reading this register contains the address after the last one that was written.


=== SP_DMA_RDLEN ===

This register is used to initiate a DMA transfer from RDRAM to DMEM/IMEM. It must be written as third register, after programming <code>SP_DMA_SPADDR</code> and <code>SP_DMA_RAMADDR</code>. As soon as it is written, if the DMA engine was idle, a DMA transfer is started. Otherwise, the DMA transfer is enqueued (double-buffered), waiting for the previous one to be finished.

{{#invoke:Register table|head|550px|SP_DMA_RDLEN <code>0x0404 0008</code> (RSP COP0: <code>c2</code>)}}
{{#invoke:Register table|row|31:24}}
| RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0
|-
| colspan="8" | SKIP[11:4]
{{#invoke:Register table|row|23:16}}
| RW-0 || U-0 || U-0 || U-0 || RW-0 || RW-0 || RW-0 || RW-0
|-
| SKIP[3] || 0 || 0 || 0 || colspan="4" | COUNT[7:4]
{{#invoke:Register table|row|15:8}}
| RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0
|-
| colspan="4" | COUNT[3:0] || colspan="4" | LEN[11:8]
{{#invoke:Register table|row|7:0}}
| RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || U-0 || U-0 || U-0
|-
| colspan="5" | LEN[7:3] || 0 || 0 || 0
{{#invoke:Register table|foot}}{{#invoke:Register table|definitions
| 31-20 | SKIP | Number of bytes to skip in RDRAM after each row. Notice that the lowest 3 bits are always 0.
| 19-12 | COUNT | Number of rows to transfer minus 1.
| 21-0 | RDLEN | Number of bytes to transfer for each row minus 1. Notice that the lowest 3 bits are always 0.
}}
'''Extra Details:'''
: '''RDLEN'''
:: Like other DMA transfers in N64, this field holds the number of bytes to transfer minus 1. Since the DMA engine works in 64-bit words, writing 0 (or any value up to and including 6) starts a transfer of exactly 8 bytes. After the transfer is finished, this field contains <code>0xFF8</code> (which would be -8, as expected for a transfer in units of 8 bytes).
: '''COUNT and SKIP'''
:: Setting <code>COUNT</code> to 0 initiates a linear transfer of <code>RDLEN</code> plus 1 bytes (rounded up to 8 bytes); in this case, the value of <code>SKIP</code> is effectively ignored as only one row is transferred. With any other value, <code>COUNT</code> indicates the number of rows, to transfer a portion of a rectangular image, and <code>SKIP</code> indicates the so-called row stride, that is number of bytes to add to jump from the end of a row to the beginning of next one. After a DMA transfer is finished, <code>COUNT</code> is reset to 0, and <code>SKIP</code> is unchanged.

=== SP_DMA_WRLEN ===

This register is used to initiate a DMA transfer from DMEM/IMEM to RDRAM. It must be written as third register, after programming <code>SP_DMA_SPADDR</code> and <code>SP_DMA_RAMADDR</code>. As soon as it is written, if the DMA engine was idle, a DMA transfer is started. Otherwise, the DMA transfer is enqueued (double-buffered), waiting for the previous one to be finished.

{{#invoke:Register table|head|550px|SP_DMA_WRLEN <code>0x0404 000C</code> (RSP COP0: <code>c3</code>)}}
{{#invoke:Register table|row|31:24}}
| RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0
|-
| colspan="8" | SKIP[11:4]
{{#invoke:Register table|row|23:16}}
| RW-0 || U-0 || U-0 || U-0 || RW-0 || RW-0 || RW-0 || RW-0
|-
| SKIP[3] || 0 || 0 || 0 || colspan="4" | COUNT[7:4]
{{#invoke:Register table|row|15:8}}
| RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || RW-0
|-
| colspan="4" | COUNT[3:0] || colspan="4" | LEN[11:8]
{{#invoke:Register table|row|7:0}}
| RW-0 || RW-0 || RW-0 || RW-0 || RW-0 || U-0 || U-0 || U-0
|-
| colspan="5" | LEN[7:3] || 0 || 0 || 0
{{#invoke:Register table|foot}}{{#invoke:Register table|definitions
| 31-20 | SKIP | Number of bytes to skip in RDRAM after each row. Notice that the lowest 3 bits are always 0.
| 19-12 | COUNT | Number of rows to transfer minus 1.
| 21-0 | RDLEN | Number of bytes to transfer for each row minus 1. Notice that the lowest 3 bits are always 0.
}}
'''Extra Details:'''
Please refer to <code>SP_DMA_RDLEN</code> for details.


=== SP_STATUS ===
=== SP_STATUS ===