Peripheral Interface: Difference between revisions

From N64brew Wiki
Jump to navigation Jump to search
Content added Content deleted
m (→‎0x0460 00n0 - PI_BSD_DOMn_RLS: Fixed bit range typo)
(→‎0x0460 00nC - PI_BSD_DOMn_PGS: explicitly spell out minimum and maximum values)
Line 282: Line 282:
'''Extra Details:'''
'''Extra Details:'''
: During [[Initial_Program_Load#IPL2|IPL2]], the N64 will initialize Domain 1's PGS using data read from the cartridge [[ROM_Header|ROM header]]. All official ROMs set PGS = 7 (meaning 2^(7+2) = 512 bytes).
: During [[Initial_Program_Load#IPL2|IPL2]], the N64 will initialize Domain 1's PGS using data read from the cartridge [[ROM_Header|ROM header]]. All official ROMs set PGS = 7 (meaning 2^(7+2) = 512 bytes).
: The smallest possible value, 0, means 2^(0+2) = 4 bytes; the largest means 2^(15+2) = 128KiB.


Page Size only matters for DMA transfers; all direct accesses via the PI are only ever 32 bits wide.
Page Size only matters for DMA transfers; all direct accesses via the PI are only ever 32 bits wide.

Revision as of 02:54, 28 November 2023

The Peripheral Interface (or PI, or Parallel Interface) is one of multiple I/O interfaces in the RCP, which is used to communicate with game cartridges or other devices connected to either the cartridge port or expansion port on the bottom of the console. (e.g. 64DD)

Memory mapped registers are used to configure the Peripheral Interface and initiate DMA reads and writes. The base address for these registers is 0x0460 0000, also known as PI_BASE. However, because all memory accesses in the CPU are made using virtual addresses, the following addresses must be offset appropriately. For non-cached reads/writes, add 0xA000 0000 to the address. As an example, to directly write to the PI_DRAM_ADDR register, use address 0xA460 0000.


The PI Bus

The PI bus is the bus where external devices can be connected, via either the cartridge port on the top of the console, or the expansion port at the bottom of the console. Notice both ports are electrically connected to the same bus, even if the connector is different.

The bus address is 32-bit and the values being transferred are 16-bits. So each access (read or write) is made to a 32-bit address with a 16-bit data. The PI (as master device) issues reads and writes to the bus with a wire protocol detailed below. Each device is expected to use an address range (a subset of the whole 32-bit address space); the device will receive all reads and writes requests from PI, and is expected to reply / execute those falling within the address range of interest. The PI has no way of knowing if one or more devices are attached to the bus, it does not know which address ranges are used by what device (there is no "address registration / reservation system"), and there is no handling of conflicts.

The PI will issue reads or writes as drive by the CPU via two different systems:

  • DMA: this allows to transfer multiple words. In general, the PI bus protocol allows the PI to write the address once, and then either reads or writes multiple consecutive words, and the DMA will use this mechanism to do quicker transfers. In fact, addresses in the PI bus are virtually split in "pages" of configurable size. The PI is allowed to read/write multiple words within the same page, so during the DMA will issue the address only once for page, and then read/write multiple words as requested. This is done to speed up transfers (as issuing a new address after every word would waste time).
  • Direct I/O: part of the 32-bit PI address space is memory mapped to the CPU address space. This means that when the CPU accesses one of these memory mapped addresses, the PI will perform a read or write on the bus. The mapped addresses are only those in the range 0x0500_0000 - 0x1FBF_FFFF and 0x1FD0_0000 - 0x7FFF_FFFF. Addresses outside of these ranges can only be accessed via DMA. Notice also that direct I/O accesses can only be done as 32-bit words (concatenating two consecutive 16-bit reads), see Memory map#Ranges 0x0500'0000 - 0x1FBF'FFFF and 0x1FD0'0000 - 0x7FFF'FFFF (PI external bus) for more information.

NOTE: it is easy to get confused with the different kind of addresses. Addresses mentioned here are PI bus addresses, which is a 32-bit namespace by itself. Addresses in the CPU physical memory map are a different namespace. They can be confused because of the memory mapped addresses: accessing physical address 0x0700_0000 in the CPU does map exactly to PI address 0x0700_0000, but in general the two namespaces are technically separated. For instance, PI address 0x0000_1234 is a valid PI address on the bus where a device could be attached, but reading from physical address 0x0000_1234 on the CPU accesses RDRAM instead; in fact PI address 0x0000_1234 is not memory mapped, so the only way to access it is via DMA.

Domains

To cope with different peripherals, the PI allows to configure some parameters that affect the bus protocol:

  • PGS (page size). This is the size of a virtual page, and defines how often the PI must issue a new address during a DMA transfer. For instance, if the configure page size is 32 16-bit words, assuming an aligned transfer, the PI will issue an address at the start, and then read (or write) 32 consecutive words.
  • LAT (latency). Number of RCP clock cycles to wait between the address and the transfer of the first word
  • PWD
  • RLS

The PI stores two set of configurations for these 4 registers, and uses them for different ranges of the address space. These two sets are called "domain 1" and "domain 2". Most of the address space is accessed using the "domain 1" configuration, but a few ranges are accessed as "domain 2". See this table for the mapping:

PI address range Domain Device
0x0000_0000 - 0x04FF_FFFF Domain 1 No known device exists that operates in this range
0x0500_0000 - 0x05FF_FFFF Domain 2 64DD registers
0x0600_0000 - 0x07FF_FFFF Domain 1 64DD ROM
0x0800_0000 - 0x0FFF_FFFF Domain 2 SRAM
0x1000_0000 - 0xFFFF_FFFF Domain 1 ROM (though this address range is huge, and ROM only typically occupied a small portion of it)

There is no way to have more than two domains, nor to decide which domain is used for some specific address. The above table is hardcoded in the PI itself, and cannot the changed. In general, software that needs to change domain parameters before accessing a device is advised to do that in a transactional way, so that the default values are restored after the access for other peripherals.

Open bus behavior

Writes made to addresses with no "receiver" devices cause no harm; the writes are just ignored. As explained above, the PI has absolutely no notion if devices are attached or not (and whether they care about some addresses) so all writes will always be performed as if somebody cared about them. In particular, notice also that PI will also execute writes to the ROM address space (as it has no notion that the ROM is read-only, nor that a ROM is mapped to those addresses!): the cartridge will then ignore those writes.

Reads made to addresses with no "receiver" devices cause an open-bus behavior: the 32-bit word returned by PI is the 16-bit lowest part of the address put on the bus, repeated in both halves. For instance, a direct I/O 32-bit read from PI address 0x6666_DCBA will return the value 0xDCBA_DCBA. When reading unmapped areas via DMA, the rule is the same but the address returned is the address of the page being accessed (the only one physically put on the bus), and it is repeated for all words read until page change.

Registers

Table Notation:

R = Readable bit
W = Writable bit
U = Undefined/Unused bit
-n = Default value n at power on
[x:y] = Specifies bits x to y, inclusively

0x0460 0000 - PI_DRAM_ADDR


PI_DRAM_ADDR 0x0460 0000
31:24 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
23:16 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
DRAM_ADDR[23:16]
15:8 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
DRAM_ADDR[15:8]
7:0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 R-0
DRAM_ADDR[7:0]
bit 31-24 Undefined: Initialized to 0
bit 23-0 DRAM_ADDR[23:0]: Base address of RDRAM for PI DMAs; bit-0 is always 0

Extra Details:

Note that DMA transfers are buggy if DRAM_ADDR[2:0] are not all zero, see below.

0x0460 0004 - PI_CART_ADDR


PI_CART_ADDR 0x0460 0004
31:24 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
CART_ADDR[31:24]
23:16 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
CART_ADDR[23:16]
15:8 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
CART_ADDR[15:8]
7:0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 R-0
CART_ADDR[7:0]
bit 31-0 CART_ADDR[31:0]: Base address of the PI bus (e.g. cartridge) for PI DMAs; bit-0 is always 0

0x0460 0008 - PI_RD_LEN


PI_RD_LEN 0x0460 0008
31:24 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
23:16 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
RD_LEN[23:16]
15:8 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
RD_LEN[15:8]
7:0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
RD_LEN[7:0]
bit 31-24 Undefined: Initialized to 0
bit 23-0 RD_LEN[23:0]: Number of bytes, minus one, to be transferred from RDRAM, to the PI bus

Extra Details:

Writing to this register will start the DMA transfer. Reading appears to always return `0x7F` (more research required).

0x0460 000C - PI_WR_LEN


PI_WR_LEN 0x0460 000C
31:24 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
23:16 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
WR_LEN[23:16]
15:8 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
WR_LEN[15:8]
7:0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
WR_LEN[7:0]
bit 31-24 Undefined: Initialized to 0
bit 23-0 WR_LEN[23:0]: Number of bytes, minus one, to be transferred from the PI bus, into RDRAM

Extra Details:

Writing to this register will start the DMA transfer. Reading appears to always return `0x7F` (more research required).

0x0460 0010 - PI_STATUS


PI_STATUS 0x0460 0010
31:24 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
23:16 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
15:8 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
7:0 U-0 U-0 U-0 U-0 R-0 R-0 RW-0 RW-0
Details below
READ:                                 WRITE:
    [3]    Interrupt (DMA completed)      [3]    -
    [2]    DMA error                      [2]    -
    [1]    I/O busy                       [1]    Clear Interrupt
    [0]    DMA is busy                    [0]    Reset DMA controller and stop any transfer being done

0x0460 00n4 - PI_BSD_DOMn_LAT


PI_BSD_DOM1_LAT 0x0460 0014

PI_BSD_DOM2_LAT 0x0460 0024

31:24 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
23:16 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
15:8 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
7:0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
LAT[7:0]
bit 31-8 Undefined: Initialized to 0
bit 7-0 LAT[7:0]: The "LATch" value is the number of RCP cycles, minus one, after the address has been sent (falling edge of ALE_L) and before the first read or write may start (falling edge of /RD or /WR)

Extra Details:

During IPL2, the N64 will initialize Domain 1's LAT using data read from the cartridge ROM header. All official ROMs set LAT = 64 (meaning (64+1)*16 = 1040ns).

0x0460 00n8 - PI_BSD_DOMn_PWD


PI_BSD_DOM1_PWD 0x0460 0018

PI_BSD_DOM2_PWD 0x0460 0028

31:24 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
23:16 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
15:8 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
7:0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0 RW-0
PWD[7:0]
bit 31-8 Undefined: Initialized to 0
bit 7-0 PWD[7:0]: The "Pulse WiDth" value is the number of RCP cycles, minus one, the /RD or /WR signals are held low

Extra Details:

During IPL2, the N64 will initialize Domain 1's PWD using data read from the cartridge ROM header. All official ROMs set PWD = 18 (meaning (18+1)*16 = 304ns).

0x0460 00nC - PI_BSD_DOMn_PGS


PI_BSD_DOM1_PGS 0x0460 001C

PI_BSD_DOM2_PGS 0x0460 002C

31:24 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
23:16 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
15:8 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
7:0 U-0 U-0 U-0 U-0 U-0 RW-0 RW-0 RW-0
PGS[3:0]
bit 31-4 Undefined: Initialized to 0
bit 3-0 PGS[3:0]: The "PaGe Size" value configures how many bytes can be sequentially read/written on the bus before sending the next base address (Size = 2^(PGS+2) bytes)

Extra Details:

During IPL2, the N64 will initialize Domain 1's PGS using data read from the cartridge ROM header. All official ROMs set PGS = 7 (meaning 2^(7+2) = 512 bytes).
The smallest possible value, 0, means 2^(0+2) = 4 bytes; the largest means 2^(15+2) = 128KiB.

Page Size only matters for DMA transfers; all direct accesses via the PI are only ever 32 bits wide.

The maximum number of transfers will only happen when the address's least significant bits are all 0.

0x0460 00n0 - PI_BSD_DOMn_RLS


PI_BSD_DOM1_RLS 0x0460 0020

PI_BSD_DOM2_RLS 0x0460 0030

31:24 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
23:16 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
15:8 U-0 U-0 U-0 U-0 U-0 U-0 U-0 U-0
7:0 U-0 U-0 U-0 U-0 U-0 U-0 RW-0 RW-0
RLS[1:0]
bit 31-2 Undefined: Initialized to 0
bit 1-0 RLS[1:0]: The "ReLeaSe" value is the number of RCP cycles, minus one, that the /RD or /WR signals are held high between each 16-bits of data

Extra Details:

During IPL2, the N64 will initialize Domain 1's RLS using data read from the cartridge ROM header. All official ROMs set RLS = 3 (meaning (3+1)*16 = 64ns).

Physical Bus Pinout

The PI Bus is a Bi-directional and multiplexed interface with a 16bit data path to the ROM, 64DD, Flash Ram and cart RAM chips. It is used to send both the wanted address and data to and from the RCP. This is not to be confused with the serial EEPROM, CIC and RTC (real time clock) chips that go through the SI interface and PIF chip via the cartridge port as well.

Pin Name Cart pins Description
AD0 28 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[16] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[0] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [0]

AD1 29 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[17] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[1] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [1]

AD2 30 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[18] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[2] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [2]

AD3 32 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[19] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[3] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [3]

AD4 36 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[20] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[4] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [4]

AD5 37 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[21] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[5] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [5]

AD6 40 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[22] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[6] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [6]

AD7 41 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[23] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[7] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [7]

AD8 16 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[24] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[8] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [8]

AD9 15 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[25] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[9] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [9]

AD10 12 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[26] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[10] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [10]

AD11 11 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[27] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[11] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [11]

AD12 7 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[28] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[12] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [12]

AD13 5 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[29] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[13] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [13]

AD14 4 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[30] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[14] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [14]

AD15 3 This data bit is used with the following signals to represent the following

/ALEH - Signal changes from HIGH to LOW: Address Bit[31] is latched internally in the ROM

/ALEL - Signal changes from HIGH to LOW: Address Bit[15] is latched internally in the ROM

/WR or /RD - Signal changes from LOW to HIGH: This will read/write to that ROM location latched in the Cart. Bit [15]

/ALEH 35 Parts on the PI bus are expected to latch the high address (Bits[31:16]) when this goes from HIGH to LOW.

When this signal goes from LOW to HIGH it resets the internal address system so it can await for a new address request.

This stays HIGH when in idle and LOW when processing data. Commercial ROMs also use this as /CE, entering a low-power state while this signal is high.

This signal will be high for at least 7 FSB cycles, each time a new address is loaded.

/ALEL 33 Parts on the PI bus are expected to latch the low address (Bits[15:0]) when this goes from HIGH to LOW.

No action has been seen when this goes from LOW to HIGH.

This stays HIGH when in idle and LOW when processing data.

This signal will be high for at least 14 FSB cycles, each time a new address is loaded, ending 7 FSB cycles after ALEH falls.

/WR 8 This is the signal that sends a write command to the FLASH ram, SRAM or 64DD

While this signal is low, the RCP drives the PI bus with the current word of data.

When this signal goes from LOW to HIGH external parts are expected to record the value at that moment, if they need it. The RCP and external parts are also expected to increase the internal address counter in preparation for the next word transferred.

The RCP will not change this signal from HIGH to LOW until either the Latency (PI_BSD_DOMn_LAT) or Release (PI_BSD_DOMn_RLS) registers have counted the required number of FSB clocks.

This stays HIGH when idle.

/RD 10 This is the signal that sends a read command to the ROM, FLASH ram, SRAM or 64DD.

While this signal is low, the RCP expects that some device will drive the PI Bus.

When this signal goes from LOW to HIGH the RCP will record the value at that moment. The RCP and external parts are also expected to increase the internal address counter in preparation for the next word transferred.

The /RD signal has the same timing constraints as the /WR signal above.

This stays HIGH when idle.

PI Interface Process

Address output:
Rom Address Output
Rom Address Output



Data Read:
Rom Read Data
Rom Read Data



Constant Read:
Constant ROM Access
Constant ROM Access




Aligned DMA Transfer

An aligned DMA transfer is when the PI_DRAM_ADDR_REG is set to a 64bit (8byte) aligned address. The PI_CART_ADDR_REG can be any 16bit (2Byte) value as will transfer from that offset to RDRAM.

The PI_RD_LEN_REG and PI_WR_LEN_REG can be any length, as long as it is a 2 byte aligned amount (more testing is to be done on this to confirm this)

Unaligned DMA transfer

An un-aligned ROM dma transfer is when you use the PI_DRAM_ADDR_REG and not set it as a 8 Byte aligned address and use variable PI_RD_LEN_REG and PI_WR_LEN_REG lengths.

The following rules are based on assumptions via the created test ROMs by Krom, Mazamars312 and Lemmy (https://github.com/PeterLemon/N64/tree/master/CPUTest/DMAAlignment-PI-cart)

This are example DMA transfers
RDRAM Address ROM Address Read or Write Length What happens
0000_0100 1000_1000 Read 0x7F (128 Bytes) This is a normal aligned transfer
0000_0102 1000_1000 Read 0x7F (128 Bytes) The start of the ROM data is transferred to RDRAM offset as expected (So the first two bytes of RDRAM are not affected by this write).

However, this is where we see that the last 2 bytes are dropped from the transfer. Thus only making it a 0x7D length transfer (126 bytes - 1)

0000_0106 1000_1000 Read 0x7F (128 Bytes) The start of the ROM data is transferred to RDRAM offset as expected (So the first 6 bytes of RDRAM are not affected by this write).

However, this is where we see that the last 6 bytes are dropped from the transfer. Thus only making it a 0x79 length transfer (122 bytes - 1)

0000_0106 1000_1000 Read 0x17 (24 Bytes) The start of the ROM data is transferred to RDRAM offset as expected (So the first 6 bytes of RDRAM are not affected by this write).

However, this is where we see that the last 6 bytes are dropped from the transfer. Thus only making it a 0x11 length transfer (18 bytes - 1)

0000_0106 1000_1000 Read 0xFF (256 Bytes) This is where we have found that internally the N64 can only DMA blocks of 128 at a time to and from RDRAM as a burst to the PI controller.

The First 128 Bytes:

The start of the ROM data is transferred to RDRAM offset as expected (So the first two bytes of RDRAM are not affected by this write).

However, this is where we see that the last 6 bytes are dropped from the transfer. Thus only making it a 0x79 length transfer (122 bytes - 1)

The Second 128 Bytes:

This will do a normal Aligned DMA transfer from the RDRAM offset 128 to 255. From this we believe the first DMA transfer is corrupted due to some internal issue with the PI controller and the RDRAM controller.

The image blow shows this example (look at address 112 -> 127) this shows the last 6 Bytes are not transferred. (Confirmed by Krom)
0000_0106 1000_1000 Write 0x7F (128 Bytes) *** Writes to Flash and SRAM to be tested ***