IOP/Deckard
IOP
I/O processor - MIPS R3000A (PS1 main processor) used in PS2 since SCPH-10000 to SCPH-700XX. Runs at a 36.864 mHz clock speed. It is connected to an external 2 MB EDO-RAM chip. Later got replaced by a new IOP based around a PowerPC 405 core, but with an additional MIPS core.
Revisions
- 1.5 : CXD9553GB (GH-001, GH-003)
- 1.15: CXD9619GB (GH-004 - GH-014, GH-016)
- 2.0 : CXD9660GB (earlier GH-015)
- 2.1 : CXD9697GP (later GH-015, erroneously listed as "CXD9697GB" in service manuals?)
- 2.1 : CXD9732GP (GH-017 - GH-022)
- 2.2 : CXD9783GP (GH-023)
- 2.4 : CXD9798GP (some GH-026 boards, maybe J-chassis GH-029?)
- 2.4 : CXD9799GP (PSX XPD-001/XPD-005, Namco System 256, some K-chassis slim boards, some GH-026 boards, maybe J-chassis GH-029?)
- 2.4 : CXD9799AGP (some K-chassis slim boards, Namco System 147, Namco System 148)
DECKARD
PowerPC 405 chip that replaced IOP and SPEED. It is connected to an external 4 MB DDR-SDRAM chip. In IOP emulator mode 2MB are used as a IOP memory. In PS2 used since SCPH-750XX model. New chip require some compatibility tweaks that are done per title by xparam file found in PS2 BOOTROM.
Note: There is some evidence that the new IOP might still additionaly contain some kind of MIPS core.
Revisions
- 3.0 : CXD9796GP (SCPH-750XX series/L-chassis)
- As the only IOP revision to do so, this revision needs heatsinking!
- 3.0 : CXD9209GP (SCPH-770XX series/M-chassis)
Starting with N-chassis/SCPH-790XX, the IOP was integrated into the new main SoC together with its RAM. It still reports as version 3.0 in software.
TLB Entries
Virtual | Physical | Size | Endian (Big/little) | RWX | Write-Through | Cache Inhibit | Memory Coherence | Guarded | User-defined storage attribute Un n=[0-3] | Notes | |
---|---|---|---|---|---|---|---|---|---|---|---|
0xFFE00000 | 0xFFE00000 | 0x00100000 | B | RX | 1 | 0 | 0 | 0 | - | DECKARD's BOOT ROM PPC440 BOOT ROM: 0xFFE00000 - 0xFFFFFFFF (2MB) | |
0xFFF00000 | 0xFFF00000 | 0x00100000 | B | RX | 1 | 0 | 0 | 0 | - | DECKARD's BOOT ROM | |
0x00000000 | 0x00200000 | 0x00100000 | L | RW | 1 | 0 | 0 | 0 | 2 | IOP RAM low 1MB mirror virtual R3000 IOP instructions use | |
0x00100000 | 0x00300000 | 0x00100000 | L | RW | 1 | 0 | 0 | 0 | 2 | IOP RAM high 1MB mirror | |
0x00200000 | 0x00200000 | 0x00100000 | IOP RAM low 1MB mirror | ||||||||
0x00300000 | 0x00300000 | 0x00100000 | IOP RAM high 1MB mirror | ||||||||
0x00400000 | 0x00200000 | 0x00100000 | IOP RAM low 1MB mirror | ||||||||
0x00500000 | 0x00300000 | 0x00100000 | IOP RAM high 1MB mirror | ||||||||
0x00600000 | 0x00200000 | 0x00100000 | IOP RAM low 1MB mirror | ||||||||
0x00700000 | 0x00300000 | 0x00100000 | IOP RAM high 1MB mirror | ||||||||
0xDFE00000 | 0x00200000 | 0x00100000 | L | R | 1 | 0 | 0 | 0 | 2 | IOP RAM low 1MB mirror NOT:EE SIF (SBUS) IOP mem. window ? most likely:DECKARD 'supervisor' ?? | |
0xDFF00000 | 0x00300000 | 0x00100000 | L | R | 1 | 0 | 0 | 0 | 2 | IOP RAM high 1MB mirror | |
0x00000000 | 0x00000000 | 0x00100000 | L | RW | 0 | 1 | 0 | 0 | - | 1MB Invalid these two segments are the same! one maps to 0x00200000 and the other to 0 Switcing the valid entries is done in code. | |
0x00100000 | 0x00100000 | 0x00100000 | L | RW | 0 | 1 | 0 | 0 | - | 1MB Invalid | |
0x00200000 | 0x00000000 | 0x00100000 | L | ||||||||
0x00300000 | 0x00100000 | 0x00100000 | L | ||||||||
0x00400000 | 0x00000000 | 0x00100000 | L | ||||||||
0x00500000 | 0x00100000 | 0x00100000 | L | ||||||||
0x00600000 | 0x00000000 | 0x00100000 | L | ||||||||
0x00700000 | 0x00100000 | 0x00100000 | L | ||||||||
0xDFE00000 | 0x00000000 | 0x00100000 | L | R | 0 | 1 | 0 | 0 | - | 1MB Invalid | |
0xDFF00000 | 0x00100000 | 0x00100000 | L | R | 0 | 1 | 0 | 0 | - | 1MB Invalid | |
0x00A00000 | 0x00A00000 | 0x00100000 | B | RWX | 1 | 0 | 0 | 0 | - | 1MB DECKARD file RAM loading segment (code & data) | |
0x00BE0000 | 0x00B60000 | 0x00001000 | B | RW | 0 | 0 | 0 | 0 | - | 4kB Some variables and flags...? | |
0x00BFF000 | 0x00B7F000 | 0x00001000 | B | RW | 0 | 0 | 0 | 0 | - | 4kB PPC stack? | |
0x00BDF000 | 0x00B7F000 | 0x00001000 | B | R | 0 | 0 | 0 | 0 | - | 4kB | |
0x00B40000 | 0x00B40000 | 0x00000400 | L | RW | 0 | 1 | 0 | 0 | - | 1kB PS1DRV fetch GP1 commands from that region. in a loop that read 0xB40004,
then in every iteration 0x10 is added to address, after reaching 0xB003F4 loops start from 0xB40004 again. | |
0x00B40400 | 0x00B40400 | 0x00000400 | L | RW | 0 | 1 | 0 | 0 | - | 1kB PS1DRV send per title compatibility flags to that region. | |
0x00B40C00 | 0x00FFFC00 | 0x00000400 | L | RW | 0 | 1 | 0 | 0 | - | 1kB The physical addr. of this is in the last 1kB of the 16MB of IOP RAM. | |
0x01000000 | 0x40000000 | 0x00000400 | B | RW | 0 | 1 | 0 | 1 | - | 1kB PPC devices: PPC UART is here | |
0x40000000 | 0x00200000 | 0x00100000 | L | RW | 1 | 0 | 0 | 0 | 2 | 1MB IOP RAM low 1MB mirror | |
0x40100000 | 0x00300000 | 0x00100000 | L | RW | 1 | 0 | 0 | 0 | 2 | 1MB IOP RAM high 1MB mirror | |
0x40200000 | 0x00200000 | 0x00100000 | L | RW | 1 | 0 | 0 | 0 | 2 | 1MB IOP RAM low 1MB mirror | |
0x40300000 | 0x00300000 | 0x00100000 | L | RW | 1 | 0 | 0 | 0 | 2 | 1MB IOP RAM high 1MB mirror | |
0x40400000 | 0x00200000 | 0x00100000 | L | RW | 1 | 0 | 0 | 0 | 2 | 1MB IOP RAM low 1MB mirror | |
0x40500000 | 0x00300000 | 0x00100000 | L | RW | 1 | 0 | 0 | 0 | 2 | 1MB IOP RAM high 1MB mirror | |
0x40600000 | 0x00200000 | 0x00100000 | L | RW | 1 | 0 | 0 | 0 | 2 | 1MB IOP RAM low 1MB mirror | |
0x40700000 | 0x00300000 | 0x00100000 | L | RW | 1 | 0 | 0 | 0 | 2 | 1MB IOP RAM high 1MB mirror | |
0x12000000 | 0x10000000 | 0x01000000 | L | RW | 0 | 1 | 0 | 1 | 2 | 16MB IOP devices - Dev#10 Dev9_2, Dev#12 Dev9_3 ?? | |
0x13000000 | 0x11000000 | 0x01000000 | L | RW | 0 | 1 | 0 | 1 | 2 | 16MB Dev9/SPEED - placed here sor some reason rather than at 0x10000000. | |
0x1D000000 | 0x1D000000 | 0x00000400 | L | RW | 0 | 1 | 0 | 1 | 2 | 1kB SIF SBUS BDn regs on EE, accessed through SBUS | |
0x1E000000 | 0x1E000000 | 0x01000000 | L | RW | 0 | 1 | 0 | 1 | 2 | 16MB Dev#1 ROM-DVD /CS1 | |
0x1F402000 | 0x1F402000 | 0x00000400 | L | RW | 0 | 1 | 0 | 1 | 2 | 1kB Dev#5 CDVD /CS5 | |
0x1F7FFC00 | 0x00B00400 | 0x00000400 | L | RW | 0 | 1 | 0 | 1 | 2 | 1kB Cache ? | |
0x00BDE800 | 0x00B00000 | 0x00000400 | L | R | 0 | 0 | 0 | 0 | - | 1kB Cache. Status reg? | |
0x00BDEC00 | 0x00B00400 | 0x00000400 | L | R | 0 | 0 | 0 | 0 | - | 1kB Cache. Status reg? | |
0x1F801000 | 0x1F801000 | 0x00001000 | L | RW | 0 | 1 | 0 | 1 | 2 | 4kB IOP devices (DMAC, SSBUSC,...) and Dev#4 SPU /CS4 | |
0x1F802000 | 0x1F802000 | 0x00001000 | L | RW | 0 | 1 | 0 | 1 | 2 | 4kB Dev#8 Exp2 /EXTR (PIO) | |
0x1F803000 | 0x1F803000 | 0x00001000 | L | RW | 0 | 1 | 0 | 1 | 2 | 4kB Dev#8 Exp2 /EXTR (PIO) | |
0x1F808000 | 0x1F808000 | 0x00000400 | L | RW | 0 | 1 | 0 | 1 | 2 | 1kB SIO2, iLink | |
0x1F900000 | 0x1F900000 | 0x00001000 | L | RW | 0 | 1 | 0 | 1 | 2 | 4kB Dev#4 Hard-wired (not through SSBUSC address reg.) SPU2 regs. | |
0x1FC00000 | 0x1FC00000 | 0x00100000 | L | RW | 0 | 1 | 0 | 1 | 2 | 1MB Dev#2 ROM-BOOT /CS2 0x1FC00000-0x1FFFFFFF 4MB | |
0x1FD00000 | 0x1FD00000 | 0x00100000 | L | RW | 0 | 1 | 0 | 1 | 2 | 1MB Dev#2 ROM-BOOT /CS2 | |
0x1FE00000 | 0x1FE00000 | 0x00100000 | L | RW | 0 | 1 | 0 | 1 | 2 | 1MB Dev#2 ROM-BOOT /CS2 | |
0x1FF00000 | 0x1FF00000 | 0x00100000 | L | RW | 0 | 1 | 0 | 1 | 2 | 1MB Dev#2 ROM-BOOT /CS2 |
TLB entries = 54 (55?) up to here, of 64 maximum. At this point the code gets the number of remaining TLB entries = 10 and disables them. Then it sets-up 4 more entries, starting from 60:
Virtual | Physical | Size | Endian (Big/little) | RWX | Write-Through | Cache Inhibit | Memory Coherence | Guarded | User-defined storage attribute Un n=[0-3] | Notes |
---|---|---|---|---|---|---|---|---|---|---|
0x5F800400 | 0x00B00400 | 0x00000400 | L | RW | 0 | 1 | 0 | 1 | 2 | 1kB IOP Cache / Scratchpad |
0x5F800000 | 0x00B00000 | 0x00000400 | L | RW | 0 | 1 | 0 | 1 | 2 | 1kB |
0x1F800400 | 0x00B00400 | 0x00000400 | L | RW | 0 | 1 | 0 | 1 | 2 | 1kB |
0x1F800000 | 0x00B00000 | 0x00000400 | L | RW | 0 | 1 | 0 | 1 | 2 | 1kB |
Per game configuration
Deckard to keep better compatibility use some flags/settings selected per Title ID. List of configurations is stored in rom:XPARAM, and in internal list in PS1DRV. Default values are listed in table below.
Currently used settings can be read thru "hidden" HW registers. To read value of selected command from PS1 user program, write command number to 0xFFFE01A0, and then read value from 0xFFFE01A4. Keep in mind those ports are unavailable in PS2 mode. Same way we can set values for commands. First write command number to 0xFFFE01A0, and then write value to 0xFFFE01A4.
Command | Value | Name |
---|---|---|
0x00 | 0x1F4 | PARAM_MDEC_DELAY_CYCLE |
0x01 | 0x7D0 | PARAM_SPU_INT_DELAY_LIMIT |
0x02 | 0x23 | PARAM_SPU_INT_DELAY_PPC_COEFF |
0x03 | 0x7D0 | PARAM_SPU2_INT_DELAY_LIMIT |
0x04 | 0x14 | PARAM_SPU2_INT_DELAY_PPC_COEFF |
0x05 | 0 | PARAM_DMAC_CH10_INT_DELAY |
0x06 | 1 | PARAM_CPU_DELAY |
0x07 | 0x20 | PARAM_SPU_DMA_WAIT_LIMIT |
0x08 | 0 | PARAM_GPU_DMA_WAIT_LIMIT |
0x09 | 0 | PARAM_DMAC_CH10_INT_DELAY_DPC |
0x0A | 0 | PARAM_CPU_DELAY_DPC |
0x0B | 0 | PARAM_USB_DELAYED_INT_ENABLE |
0x0C | 0 | PARAM_TIMER_LOAD_DELAY |
0x0D | 0x229C | PARAM_SIO0_DTR_SCK_DELAY |
0x0E | 0x6EC | PARAM_SIO0_DSR_SCK_DELAY_C |
0x0F | 0x6EC | PARAM_SIO0_DSR_SCK_DELAY_M |
0x10 | 1 | PARAM_MIPS_DCACHE_ON |
0x11 | 0x90 | PARAM_CACHE_FLASH_CHANNELS |
Example settings from XPARAM file.
Name | Command | Value | Title ID |
---|---|---|---|
PARAM_CPU_DELAY | 6 | 0xB60 | SLPS_250.72 |
PARAM_MIPS_DCACHE_ON | 0x10 | 0 | SLPS_250.72 |
PARAM_CACHE_FLASH_CHANNELS | 0x11 | 0x10 | SLPS_250.79 |
PARAM_CPU_DELAY | 6 | 0xC80 | SLPS_250.79 |
PARAM_DMAC_CH10_INT_DELAY | 5 | 0x3E8 | SLPS_250.79 |