psx-spx.github.io/docs/serialportsio.md

183 lines
9.5 KiB
Markdown
Raw Normal View History

2020-07-23 20:49:17 +02:00
# Serial Port (SIO)
2020-07-23 22:41:06 +02:00
#### 1F801050h SIO\_TX\_DATA (W)
2020-07-23 20:49:17 +02:00
```
0-7 Data to be sent
8-31 Not used
```
Writing to this register starts transmit (if, or as soon as, TXEN=1 and CTS=on
2020-07-23 22:41:06 +02:00
and SIO\_STAT.2=Ready). Writing to this register while SIO\_STAT.0=Busy causes
2020-07-23 20:49:17 +02:00
the old value to be overwritten.<br/>
2020-07-23 22:41:06 +02:00
The "TXEN=1" condition is a bit more complex: Writing to SIO\_TX\_DATA latches
2020-07-23 20:49:17 +02:00
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
2020-07-23 22:41:06 +02:00
SIO\_TX\_DATA, then the transfer may STILL start if the old latched TXEN value
2020-07-23 20:49:17 +02:00
was set; this appears for SIO transfers in Wipeout 2097).<br/>
2020-07-23 22:41:06 +02:00
#### 1F801050h SIO\_RX\_DATA (R)
2020-07-23 20:49:17 +02:00
```
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)
```
2020-07-23 22:41:06 +02:00
A data byte can be read when SIO\_STAT.1=1. Data should be read only via 8bit
2020-07-23 20:49:17 +02:00
memory access (the 16bit/32bit "preview" feature is rather unusable).<br/>
2020-07-23 22:41:06 +02:00
#### 1F801054h SIO\_STAT (R)
2020-07-23 20:49:17 +02:00
```
0 TX Ready Flag 1 (1=Ready/Started) (depends on CTS) (TX requires CTS)
1 RX FIFO Not Empty (0=Empty, 1=Not Empty)
2 TX Ready Flag 2 (1=Ready/Finished) (depends on TXEN and on CTS)
3 RX Parity Error (0=No, 1=Error; Wrong Parity, when enabled) (sticky)
4 RX FIFO Overrun (0=No, 1=Error; Received more than 8 bytes) (sticky)
5 RX Bad Stop Bit (0=No, 1=Error; Bad Stop Bit) (when RXEN) (sticky)
6 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 CTS Input Level (0=Off, 1=On) (remote RTS) ;CTS required for TX
9 Interrupt Request (0=None, 1=IRQ) (sticky)
10 Unknown (always zero)
11-25 Baudrate Timer (15bit timer, decrementing at 33MHz)
26-31 Unknown (usually zero, sometimes all bits set)
```
Note: Bit0 gets cleared after sending the Startbit, Bit2 gets cleared after
sending all bits up to including the Stopbit.<br/>
2020-07-23 22:41:06 +02:00
#### 1F801058h SIO\_MODE (R/W) (eg. 004Eh --\> 8N1 with Factor=MUL16)
2020-07-23 20:49:17 +02:00
```
0-1 Baudrate Reload Factor (1=MUL1, 2=MUL16, 3=MUL64) (or 0=STOP)
2-3 Character Length (0=5bits, 1=6bits, 2=7bits, 3=8bits)
4 Parity Enable (0=No, 1=Enable)
5 Parity Type (0=Even, 1=Odd) (seems to be vice-versa...?)
6-7 Stop bit length (0=Reserved/1bit, 1=1bit, 2=1.5bits, 3=2bits)
8-15 Not used (always zero)
```
2020-07-23 22:41:06 +02:00
#### 1F80105Ah SIO\_CTRL (R/W)
2020-07-23 20:49:17 +02:00
```
0 TX Enable (TXEN) (0=Disable, 1=Enable, when CTS=On)
1 DTR Output Level (0=Off, 1=On)
2 RX Enable (RXEN) (0=Disable, 1=Enable) ;Disable also clears RXFIFO
3 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 RTS Output Level (0=Off, 1=On)
6 Reset (0=No change, 1=Reset most SIO_registers to zero) (W)
7 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=On
13-15 Not used (always zero)
```
2020-07-23 22:41:06 +02:00
#### 1F80105Ch SIO\_MISC (R/W)
2020-07-23 20:49:17 +02:00
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
2020-07-23 22:41:06 +02:00
C0C0h or 8080h" (depending on the character length in SIO\_MODE).<br/>
2020-07-23 20:49:17 +02:00
2020-07-23 22:41:06 +02:00
#### 1F80105Eh SIO\_BAUD (R/W) (eg. 00DCh --\> 9600 bauds; when Factor=MUL16)
2020-07-23 20:49:17 +02:00
```
0-15 Baudrate Reload value for decrementing Baudrate Timer
```
2020-07-23 22:41:06 +02:00
The Baudrate is calculated (based on SIO\_BAUD, and on Factor in SIO\_MODE):<br/>
2020-07-23 20:49:17 +02:00
```
BitsPerSecond = (44100Hz*300h) / MIN(((Reload*Factor) AND NOT 1),Factor)
```
2020-07-23 22:41:06 +02:00
#### SIO\_TX\_DATA Notes
2020-07-23 20:49:17 +02:00
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
2020-07-23 22:41:06 +02:00
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
2020-07-23 20:49:17 +02:00
still busy). As soon as the transfer of the most recently written byte ends,
2020-07-23 22:41:06 +02:00
SIO\_STAT.2 becomes set.<br/>
2020-07-23 20:49:17 +02:00
2020-07-23 22:41:06 +02:00
#### SIO\_RX\_DATA Notes
2020-07-23 20:49:17 +02:00
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
2020-07-23 22:41:06 +02:00
by the new byte, and SIO\_STAT.4 gets set; the hardware does NOT automatically
2020-07-23 20:49:17 +02:00
disable RTS when the FIFO becomes full).<br/>
2020-07-23 22:41:06 +02:00
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
2020-07-23 20:49:17 +02:00
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).<br/>
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).<br/>
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).<br/>
#### Interrupt Acknowledge Notes
2020-07-23 22:41:06 +02:00
First reset I\_STAT.8, then set SIO.CTRL.4 (when doing it vice-versa, the
2020-07-23 20:49:17 +02:00
hardware may miss a new IRQ which may occur immediately after setting
2020-07-23 22:41:06 +02:00
SIO.CTRL.4) (and I\_STAT.8 is edge triggered, so that bit can be reset even
while SIO\_STAT.9 is still set).<br/>
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
2020-07-23 20:49:17 +02:00
does trigger again (almost) immediately (it goes off only for a very short
2020-07-23 22:41:06 +02:00
moment; barely enough to allow I\_STAT.8 to sense a edge).<br/>
2020-07-23 20:49:17 +02:00
2020-07-23 22:41:06 +02:00
#### SIO\_BAUD Notes
Timer reload occurs when writing to SIO\_BAUD, and, automatically when the
2020-07-23 20:49:17 +02:00
Baudrate Timer reaches zero. There should be two 16bit SIO timers (for TX and
2020-07-23 22:41:06 +02:00
RX), the upper 15bit of one of that timers can be read from SIO\_STAT (not sure
2020-07-23 20:49:17 +02:00
which one, and no idea if there's a way to read the other timer, too).<br/>
Or... maybe there is only ONE timer, and RX/TX are separated only by separate
"timer ellapsed" counters, in that case the MUL1 factor won't work properly,
but, with the MUL16 or MUL64 factors, RX could start anytime (eg. when TX has
already ellapsed a bunch of times)...?<br/>
The maximum baud rate may vary depending on the length and quality of the
cable, whether and how many inverters and anti-inverters are used (on the
mainboard and in external adaptor, and on whether signals are externally
converted to +/-12V levels)... anyways, rates up to 9600 baud should be working
in all cases.<br/>
However, running in no$psx, Wipeout 2097 seems to use about 2 million bauds...
although, in older no$psx versions, I believe I did see it using some kind of
baudrate detection, where it did try different rates in steps of 200 bauds or
so...?<br/>
#### SIO Ports vs JOY Ports
SIO uses I/O Addresses 1F801050h..1F80105Fh, which seem to be organized similar
to the Controller/Memory Card registers at 1F801040h..1F80104Fh, though not
identical, and with an additional register at 1F80105Ch, which has no
corresponding port at 1F80104Ch.<br/>
2020-07-23 22:41:06 +02:00
SIO\_BAUD is \<effectively\> same as for JOY\_BAUD, but, \<internally\>
2020-07-23 20:49:17 +02:00
they are a bit different:<br/>
```
JOY_BAUD is multiplied by Factor, and does then ellapse "2" times per bit.
SIO_BAUD is NOT multiplied, and, instead, ellapses "2*Factor" times per bit.
```
Unlike for the Controller/Memory Card ports, the data is transferred without
CLK signal, instead, it's using RS232 format, ie. the transfer starts with a
start bit, and is then transferred at a specific baudrate (which must be
configured identically at the receiver side). For RS232, data is usually 8bit,
and may optionally end with a parity bit, and one or two stop bits.<br/>
#### Note
For SIO Pinouts, PSone SIO upgrading, and for building RS232 adaptors, see:<br/>
[Pinouts - SIO Pinouts](pinouts.md#pinouts---sio-pinouts)<br/>
Aside from the internal SIO port, the PSX BIOS supports two additional external
serial ports, connected to the expansion port,<br/>
[EXP2 Dual Serial Port (for TTY Debug Terminal)](expansionportpio.md#exp2-dual-serial-port-for-tty-debug-terminal)<br/>
#### SIO Games
The serial port is used (for 2-player link) by Wipeout 2097 (that game
2020-07-23 22:41:06 +02:00
accidently assumes BAUDs based on 64\*1024\*1025 Hz rather than on 600h\*44100
2020-07-23 20:49:17 +02:00
Hz).<br/>
Ridge Racer Revolution is also said to support 2P link.<br/>
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).<br/>
#### 8251A Note
The Playstation Serial Port is apparently based/inspired on the Intel 8251A
USART chip; which has very similar 8bit Mode/Command/Status registers.<br/>