Serial Interfaces (SIO)
The console has two serial interfaces, SIO0 (connected to the controller and
memory card ports) and SIO1 (connected to the serial port). SIO0 is hardwired to
run in synchronous mode, while SIO1 can only operate in asynchronous mode. Both
units are fairly similar, although not identical, and seem to be vaguely based
on the Intel 8251A USART chip.
1F801040h+N*10h - SIO#_TX_DATA (W)
0-7 Data to be sent
8-31 Not used
The "TXEN=1" condition is a bit more complex: Writing to SIO_TX_DATA latches the current TXEN value, and the transfer DOES start if the current TXEN value OR the latched TXEN value is set (ie. if TXEN gets cleared after writing to SIO_TX_DATA, then the transfer may STILL start if the old latched TXEN value was set; this appears for SIO transfers in Wipeout 2097).
1F801040h+N*10h - SIO#_RX_DATA (R)
0-7 Received Data (1st RX FIFO entry) (oldest entry)
8-15 Preview (2nd RX FIFO entry)
16-23 Preview (3rd RX FIFO entry)
24-31 Preview (4th RX FIFO entry) (5th..8th cannot be previewed)
1F801044h+N*10h - SIO#_STAT (R)
0 TX FIFO Not Full (1=Ready for new byte) (depends on CTS) (TX requires CTS)
1 RX FIFO Not Empty (0=Empty, 1=Data available)
2 TX Idle (1=Idle/Finished) (depends on TXEN and on CTS)
3 RX Parity Error (0=No, 1=Error; Wrong Parity, when enabled) (sticky)
4 SIO1 RX FIFO Overrun (0=No, 1=Error; received more than 8 bytes) (sticky)
5 SIO1 RX Bad Stop Bit (0=No, 1=Error; Bad Stop Bit) (when RXEN) (sticky)
6 SIO1 RX Input Level (0=Normal, 1=Inverted) ;only AFTER receiving Stop Bit
7 DSR Input Level (0=Off, 1=On) (remote DTR) ;DSR not required to be on
8 SIO1 CTS Input Level (0=Off, 1=On) (remote RTS) ;CTS required for TX
9 Interrupt Request (0=None, 1=IRQ) (See SIO_CTRL.Bit4,10-12) (sticky)
10 Unknown (always zero)
11-31 Baudrate Timer (15-21 bit timer, decrementing at 33MHz)
On SIO0, DSR is wired to the /ACK pin on the controller and memory card ports; bit 7 is thus set when /ACK is low (asserted) and cleared when it is high. Bits 4-6 and 8 are always zero.
The number of bits actually used by the baud rate timer is probably affected by the reload factor set in SIO_MODE.
1F801048h+N*10h - SIO#_MODE (R/W) (eg. 004Eh --> 8N1 with Factor=MUL16)
0-1 Baudrate Reload Factor (1=MUL1, 2=MUL16, 3=MUL64) (or 0=MUL1 on SIO0, STOP on SIO1)
2-3 Character Length (0=5 bits, 1=6 bits, 2=7 bits, 3=8 bits)
4 Parity Enable (0=No, 1=Enable)
5 Parity Type (0=Even, 1=Odd) (seems to be vice-versa...?)
6-7 SIO1 stop bit length (0=Reserved/1bit, 1=1bit, 2=1.5bits, 3=2bits)
8 SIO0 clock polarity (CPOL) (0=High when idle, 1=Low when idle)
9-15 Not used (always zero)
1F80104Ah+N*10h - SIO#_CTRL (R/W)
0 TX Enable (TXEN) (0=Disable, 1=Enable)
1 DTR Output Level (0=Off, 1=On)
2 RX Enable (RXEN) (SIO1: 0=Disable, 1=Enable) ;Disable also clears RXFIFO
(SIO0: 0=only receive when /CS low, 1=force receiving single byte)
3 SIO1 TX Output Level (0=Normal, 1=Inverted, during Inactivity & Stop bits)
4 Acknowledge (0=No change, 1=Reset SIO_STAT.Bits 3,4,5,9) (W)
5 SIO1 RTS Output Level (0=Off, 1=On)
6 Reset (0=No change, 1=Reset most registers to zero) (W)
7 SIO1 unknown? (read/write-able when FACTOR non-zero) (otherwise always zero)
8-9 RX Interrupt Mode (0..3 = IRQ when RX FIFO contains 1,2,4,8 bytes)
10 TX Interrupt Enable (0=Disable, 1=Enable) ;when SIO_STAT.0-or-2 ;Ready
11 RX Interrupt Enable (0=Disable, 1=Enable) ;when N bytes in RX FIFO
12 DSR Interrupt Enable (0=Disable, 1=Enable) ;when SIO_STAT.7 ;DSR high or /ACK low
13 SIO0 port select (0=port 1, 1=port 2) (/CS pulled low when bit 1 set)
14-15 Not used (always zero)
Bit 2 behaves differently on SIO0: when not set, incoming data will be ignored unless bit 1 is also set. When set, data will be received regardless of whether /CS is asserted, however bit 2 will be automatically cleared after a byte is received.
Note that some emulators do not implement all SIO0 interrupts, as the kernel's controller driver only ever uses the DSR (/ACK) interrupt.
1F80105Ch - SIO1_MISC (R/W)
This is an internal register, which usually shouldn't be accessed by software.
Messing with it has rather strange effects: After writing a value "X" to this
register, reading returns "X ROR 8" eventually "ANDed with 1F1Fh and ORed with
C0C0h or 8080h" (depending on the character length in SIO_MODE). SIO0 does not
have this register.
1F80104Eh+N*10h - SIO#_BAUD (R/W) (eg. 00DCh --> 9600 bps; when Factor=MUL16)
0-15 Baudrate Reload value for decrementing Baudrate Timer
SIO0: BitsPerSecond = 33868800 / MIN(((Reload*Factor) AND NOT 1),1)
SIO1: BitsPerSecond = 33868800 / MIN(((Reload*Factor) AND NOT 1),Factor)
SIO0_BAUD is multiplied by Factor, and does then elapse "2" times per bit.
SIO1_BAUD is NOT multiplied, and, instead, elapses "2*Factor" times per bit.
SIO_TX_DATA Notes
The hardware can hold (almost) 2 bytes in the TX direction (one being currently
transferred, and, once when the start bit was sent, another byte can be stored
in SIO_TX_DATA). When writing to SIO_TX_DATA, both SIO_STAT.0 and SIO_STAT.2
become zero. As soon as the transfer starts, SIO_STAT.0 becomes set (indicating
that one can write a new byte to SIO_TX_DATA; although the transmission is
still busy). As soon as the transfer of the most recently written byte ends,
SIO_STAT.2 becomes set.
SIO_RX_DATA Notes
The hardware can hold 8 bytes in the RX direction (when receiving further
byte(s) while the RX FIFO is full, then the last FIFO entry will by overwritten
by the new byte, and SIO_STAT.4 gets set; the hardware does NOT automatically
disable RTS when the FIFO becomes full). The RX FIFO overrun flag is not
accessible on SIO0.
Data can be read from SIO_RX_DATA when SIO_STAT.1 is set, that flag gets
automatically cleared after reading from SIO_RX_DATA (unless there are still
further bytes in the RX FIFO). Note: The hardware does always store incoming
data in RX FIFO (even when Parity or Stop bits are invalid).
Note: A 16bit read allows to read two FIFO entries at once; nethertheless, it
removes only ONE entry from the FIFO. On the contrary, a 32bit read DOES remove
FOUR entries (although, there's nothing that'd indicate if the FIFO did
actually contain four entries).
Reading from Empty RX FIFO returns either the most recently received byte or
zero (the hardware stores incoming data in ALL unused FIFO entries; eg. if five
entries are used, then the data gets stored thrice, after reading 6 bytes, the
FIFO empty flag gets set, but nethertheless, the last byte can be read two more
times, but doing further reads returns 00h).
Interrupt Acknowledge Notes
First reset I_STAT.8, then set SIO.CTRL.4 (when doing it vice-versa, the
hardware may miss a new IRQ which may occur immediately after setting
SIO.CTRL.4) (and I_STAT.8 is edge triggered, so that bit can be reset even
while SIO_STAT.9 is still set).
When acknowledging via SIO_CTRL.4 with the enabled condition(s) in
SIO_CTRL.10-12 still being true (eg. the RX FIFO is still not empty): the IRQ
does trigger again (almost) immediately (it goes off only for a very short
moment; barely enough to allow I_STAT.8 to sense a edge).
Note
For more details on how SIO0 is used to communicate with controllers and memory
cards, see:
Controller and Memory Card Overview
For serial port pinouts, PSone SIO1 upgrading, and for building RS232 adaptors,
see:
Pinouts - SIO Pinouts
Aside from the internal SIO port, the PSX BIOS supports two additional external
serial ports, connected to the expansion port.
EXP2 Dual Serial Port (for TTY Debug Terminal)
SIO1 link cable games
The serial ports on two consoles can be connected with an SCPH-1040 Link Cable (known as Taisen Cable, or "Fight Cable" in Japan) for multiplayer functionality on games that support this method. This was used by a small number of games in the console's lifecycle, but inconveniently required a second console and copy of the game.
Two-Console Link Cable Games (Incomplete List):
Andretti Racing
Armored Core (and Armored Core "Link Versus Demo" disc)
Armored Core Project Phantasma
Armored Core Master of Arena
Assault Rigs
Ayrton Senna Kart Duel
Blast Radius
Bogey Dead 6
Burning Road
Bushido Blade
Bushido Blade 2
C1 -Circuit-
CART World Series
Command & Conquer Red Alert
Command & Conquer Red Alert Retaliation
Cool Boarders 2
Dead in the Water
Descent
Descent Maximum
Destruction Derby
Duke Nukem Total Meltdown
Dodgem Arena
Doom
Dune 2000
Explosive Racing (X Racing in NTSC-J)
Final Doom
Formula 1
Formula 1 98
Grand Tour Racing '98 (Gekisou!! Grand Racing -Total Driving'- in NTSC-J, Total Drivin in PAL)
Independence Day
Krazy Ivan
Leading Jockey Highbred
Metal Jacket
Mobile Suit Z-Gundam
Monaco Grand Prix Racing Simulation 2 (Monaco Grand Prix in NTSC-U/C)
Motor Toon Grand Prix (reportedly NTSC-U/C version only)
Motor Toon Grand Prix 2
Motor Toon Grand Prix USA Edition
The Need for Speed (Over Drivin' DX in NTSC-J)
PrePre Vol. 2
Pro Pinball Big Race USA
RacinGroovy
Real Robots Final Attack
Red Asphalt (Rock & Roll Racing 2 Red Asphalt in PAL)
Ridge Racer Revolution
R4 Ridge Racer Type 4
Robo Pit
Rogue Trip Vacation 2012
San Francisco Rush Extreme Racing (reportedly PAL version only)
Shutokou Battle R
Sidewinder
Sidewinder USA
Soukou Kihei Votoms Gaiden: Ao no Kishi Berserga Monogatari
Streak Hoverboard Racing
Test Drive 4
Test Drive Off-Road (reportedly NTSC-U/C only)
TOCA 2 Touring Car Challenge (TOCA 2 Touring Cars in PAL)
Trick'N Snowboarder (Tricky Sliders Freestyle Snowboard in NTSC-J)
Twisted Metal III
Wing Over
Wipeout
Wipeout 3 Special Edition
Wipeout XL (Wipeout 2097 in PAL)
Zero Pilot Ginyoku no Senshi
The serial port is used (for 2-player link) by Wipeout 2097 (that game
accidently assumes BAUDs based on 64*1024*1025 Hz rather than on 600h*44100
Hz).
Ridge Racer Revolution is also said to support 2P link.
Keitai Eddy seems to allow to connect a mobile phone to the SIO port (the games
CD cover suggests so; this seems to be something different than the "normal"
I-Mode adaptor, which would connect to controller port, not to SIO port).