CD-ROM Registers: Difference between revisions
| Revision as of 02:46, 23 October 2026 RemmyLee (GTE, MDEC, controllers, Memory Card, SIO and expansion port at register depth) | Revision as of 02:46, 23 October 2026 RemmyLee (SPU and CD-ROM at register depth; CPU overview rewritten) | ||
| Line 1: | Line 1: | ||
| + | --- | ||
| + | title: CD-ROM Registers | ||
| + | type: register | ||
| + | summary: Host interface registers of the CD-ROM decoder at 1F801800h to 1F801803h. | ||
| + | category: Hardware | ||
| + | --- | ||
| + | |||
| + | ## Summary | ||
| + | |||
| + | The CPU reaches the [CD-ROM](/hardware/cd-rom/) drive only through the host interface of the decoder chip. The interface provides mailboxes for commands to the drive's microcontroller and a data port for sector data. It also holds the audio volume registers.[^spxio] It occupies the four 8-bit addresses 1F801800h to 1F801803h. Two bits in the ADDRESS register select one of four banks, so each address reaches up to four different registers.[^spxio][^dsadr] | ||
| + | |||
| + | The register set is that of Sony's CXD1199AQ CD-ROM decoder, and the later decoders of the PlayStation appear to be variants of it.[^spxio] Old PU-7 boards use the CXD1199BQ and later boards the CXD1815Q, while still later boards build the decoder into the SPU.[^spxint] The register names on this page are the names in the CXD1199AQ data sheet.[^dsw] | ||
| + | |||
| + | ## Register Map | ||
| + | |||
| + | The registers available for reading are as follows:[^spxio][^dsr] | ||
| + | |||
| + | Table: Read registers | ||
| + | |||
| + | | Bank | 1F801800h | 1F801801h | 1F801802h | 1F801803h | | ||
| + | | --- | --- | --- | --- | --- | | ||
| + | | 0, 2 | HSTS | RESULT | RDDATA | HINTMSK | | ||
| + | | 1, 3 | HSTS | RESULT | RDDATA | HINTSTS | | ||
| + | |||
| + | The registers available for writing are as follows:[^spxio][^dsr] | ||
| + | |||
| + | Table: Write registers | ||
| + | |||
| + | | Bank | 1F801800h | 1F801801h | 1F801802h | 1F801803h | | ||
| + | | --- | --- | --- | --- | --- | | ||
| + | | 0 | ADDRESS | COMMAND | PARAMETER | HCHPCTL | | ||
| + | | 1 | ADDRESS | WRDATA | HINTMSK | HCLRCTL | | ||
| + | | 2 | ADDRESS | CI | ATV0 | ATV1 | | ||
| + | | 3 | ADDRESS | ATV2 | ATV3 | ADPCTL | | ||
| + | |||
| + | A 32-bit read from 1F801800h returns HSTS four times. The auto increment flag in the CD-ROM bus configuration at 1F801018h is off by default, and turning it on breaks CD-ROM DMA, which depends on each 32-bit word being split into four reads of RDDATA.[^spxmisc] | ||
| + | |||
| + | ## HSTS and ADDRESS | ||
| + | |||
| + | HSTS is the status register at 1F801800h in every bank. A write to the same address goes to the ADDRESS register, and bits 0 and 1 (RA) of ADDRESS select the bank.[^dshsts][^dsw] | ||
| + | |||
| + | Table: HSTS register | ||
| + | |||
| + | | Bit | Name | Contents | | ||
| + | | --- | --- | --- | | ||
| + | | 7 | BUSYSTS | Busy status. Set when the host writes a command and cleared when the sub CPU takes it. | | ||
| + | | 6 | DRQSTS | Data request status. Must be set before RDDATA or WRDATA is accessed in I/O mode. | | ||
| + | | 5 | RSLRRDY | Result read ready. The RESULT register is not empty. | | ||
| + | | 4 | PRMWRDY | Parameter write ready. The PARAMETER register is not full. | | ||
| + | | 3 | PRMEMPT | Parameter empty | | ||
| + | | 2 | ADPBUSY | ADPCM busy. Set during ADPCM decoding. | | ||
| + | | 0 to 1 | RA1, RA0 | Current bank from ADDRESS | | ||
| + | |||
| + | While BUSYSTS is set, a new command must not be sent. A command sent during that time is lost, and the controller may hang after the next one.[^spxbusy] When BUSYSTS clears, a new command can be written. However, the result is unpredictable while the interrupt of the previous command is still pending, so the interrupt is acknowledged first.[^spxbusy][^spxcmd] | ||
| + | |||
| + | ## COMMAND and PARAMETER | ||
| + | |||
| + | A write to COMMAND (bank 0, 1F801801h) passes the command byte to the drive's HC05 microcontroller. The HC05 takes the parameters from the FIFO, executes the command, puts the response in the result FIFO and raises INT3, or INT5 on an error.[^spxcmd] The parameter bytes are written to PARAMETER (bank 0, 1F801802h) before the command. The data sheet gives the FIFO as 8 bytes deep, while psx-spx finds 16 bytes on the PlayStation, where the longest command has 13 parameter bytes.[^dsw][^spxprm] | ||
| + | |||
| + | A command that the drive does not support returns INT5 and leaves its parameters in the FIFO. They then pass to the next command, so software sets CLRPRM in HCLRCTL after such an error.[^spxunsup] | ||
| + | |||
| + | ## RESULT | ||
| + | |||
| + | RESULT (1F801801h in every bank) returns the response bytes of a command. The data sheet gives an 8-byte FIFO; psx-spx finds 16 bytes.[^dsresult][^spxresult] RSLRRDY clears after the last byte of the response is read. Further reads return zeros to the end of the 16 bytes and then the same response again, until a new response arrives.[^spxresult] | ||
| + | |||
| + | ## RDDATA | ||
| + | |||
| + | RDDATA (1F801802h in every bank) returns sector data. After a read command raises INT1, software sets BFRD in HCHPCTL and waits for DRQSTS, and the sector can then be read.[^spxrddata] RDDATA can be read with 8-bit or 16-bit loads, and a 2048-byte sector therefore takes 2048 byte loads, 1024 halfword loads or a 512-word DMA transfer. The CD-ROM data bus itself is 8 bits wide, so the CPU bus interface splits every wider read.[^spxrddata] | ||
| + | |||
| + | The sector size in the mode makes a sector 800h or 924h bytes long. Reads past the end repeat the byte at index 800h - 8 or 924h - 4.[^spxrddata] | ||
| + | |||
| + | ## HCHPCTL | ||
| + | |||
| + | Table: HCHPCTL register | ||
| + | |||
| + | | Bit | Name | Contents | | ||
| + | | --- | --- | --- | | ||
| + | | 7 | BFRD | Buffer read. Starts the transfer of drive data from the buffer to the host and clears itself when done. | | ||
| + | | 6 | BFWR | Buffer write. Starts a transfer from the host to the buffer and clears itself when done. | | ||
| + | | 5 | SMEN | Sound map enable, for ADPCM playback from the host | | ||
| + | | 0 to 4 | Reserved | Write 0 | | ||
| + | |||
| + | The bit descriptions are from the data sheet.[^dshchp] The older nocash documents describe SMEN as a request for an interrupt on the next command. psx-spx explains this as a side effect of the BFWRDY interrupt.[^spxhchp] | ||
| + | |||
| + | ## Interrupts | ||
| + | |||
| + | HINTSTS (banks 1 and 3, read at 1F801803h) holds the interrupt status, and HINTMSK enables each bit. The drive raises its interrupt whenever HINTMSK AND HINTSTS is not zero, and HINTMSK is normally set to 1Fh.[^spxhint][^spxhmsk] | ||
| + | |||
| + | Table: HINTSTS register | ||
| + | |||
| + | | Bits | Name | Contents | | ||
| + | | --- | --- | --- | | ||
| + | | 5 to 7 | | Reserved, read as 1 | | ||
| + | | 4 | BFWRDY | Sound map buffer write ready | | ||
| + | | 3 | BFEMPT | Sound map buffer empty | | ||
| + | | 0 to 2 | INTSTS | Interrupt from the HC05 | | ||
| + | |||
| + | Table: HINTMSK register | ||
| + | |||
| + | | Bits | Name | Contents | | ||
| + | | --- | --- | --- | | ||
| + | | 5 to 7 | | Reserved. Write 0, read as 1. | | ||
| + | | 4 | ENBFWRDY | Enable the BFWRDY interrupt | | ||
| + | | 3 | ENBFEMPT | Enable the BFEMPT interrupt | | ||
| + | | 0 to 2 | ENINT | Enable the INTSTS interrupts | | ||
| + | |||
| + | The data sheet makes bits 0 to 2 three separate interrupt flags that the sub CPU sets.[^dshint] The HC05 instead uses them as a single 3-bit interrupt type, which always takes one of the following values:[^spxhint] | ||
| + | |||
| + | Table: CD-ROM interrupt types | ||
| + | |||
| + | | Value | Name | Contents | | ||
| + | | --- | --- | --- | | ||
| + | | INT0 | NoIntr | No interrupt pending | | ||
| + | | INT1 | DataReady | A new sector (ReadN, ReadS) or a report packet (Play) is available | | ||
| + | | INT2 | Complete | A command finished, for commands with a second response | | ||
| + | | INT3 | Acknowledge | A command was received (all commands) | | ||
| + | | INT4 | DataEnd | End of disc, or end of track with auto pause | | ||
| + | | INT5 | DiskError | Command error, read error, license error or lid opened | | ||
| + | |||
| + | The responses are queued one after another. If the first response is INT3 and the second INT5, INT5 is not delivered until INT3 is acknowledged. However, BFEMPT and BFWRDY can appear together with an INT value (13h for BFWRDY with INT3).[^spxhint] Every interrupt answers a command, except INT5, which opening the lid also raises at any time.[^spxhint] | ||
| + | |||
| + | Sony's libcd gives the same values as the normal subsystem status: CdlDataReady 0x01, CdlComplete 0x02, CdlAcknowledge 0x03, CdlDataEnd 0x04 and CdlDiskError 0x05.[^ovr1127] libcd also uses CdlNoIntr for a command or read that has not finished.[^ovr1112][^ovr1114] | ||
| + | |||
| + | ## HCLRCTL | ||
| + | |||
| + | HCLRCTL (bank 1, write at 1F801803h) acknowledges interrupts and resets parts of the decoder.[^dshclr] | ||
| + | |||
| + | Table: HCLRCTL register | ||
| + | |||
| + | | Bit | Name | Contents | | ||
| + | | --- | --- | --- | | ||
| + | | 7 | CHPRST | Chip reset. Initializes the decoder and clears itself. The XHRS pin goes low. | | ||
| + | | 6 | CLRPRM | Clear the parameter FIFO | | ||
| + | | 5 | SMADPCLR | Stop sound map ADPCM decoding and empty the buffer | | ||
| + | | 4 | CLRBFWRDY | Clear the BFWRDY interrupt | | ||
| + | | 3 | CLRBFEMPT | Clear the BFEMPT interrupt | | ||
| + | | 0 to 2 | CLRINT | Clear the INTSTS bits | | ||
| + | |||
| + | Software normally writes 07h to acknowledge the HC05 interrupt or 1Fh to acknowledge all of them. After the acknowledge the result FIFO is drained, and a pending command then goes to the controller.[^spxhclr] | ||
| + | |||
| + | When the flags are polled, a read can catch the bits while they change. About once in a thousand INT3s the CPU sees 1 before 3, and about once in a hundred INT5s it sees 4 before 5. A second read after the first nonzero value gives the stable value.[^spxpoll] The problem occurs on older consoles such as LATE-PU-8 and does not occur on the PSone.[^spxpoll] | ||
| + | |||
| + | ## Audio Registers | ||
| + | |||
| + | The four attenuators of the decoder set how the left and right CD audio reach the SPU. Sony's libcd sets them with CdMix() and the CdlATV structure.[^ovr115] | ||
| + | |||
| + | Table: CD audio attenuators | ||
| + | |||
| + | | Register | Bank, address | Path | | ||
| + | | --- | --- | --- | | ||
| + | | ATV0 | 2, 1F801802h | CD left to SPU left | | ||
| + | | ATV1 | 2, 1F801803h | CD left to SPU right | | ||
| + | | ATV2 | 3, 1F801801h | CD right to SPU right | | ||
| + | | ATV3 | 3, 1F801802h | CD right to SPU left | | ||
| + | |||
| + | 80h is 0 dB, and a lower value v attenuates by 20 log (v / 80h) dB. 40h is therefore 6.02 dB down, and 00h cuts the path off.[^dsatv] The data sheet prohibits 81h and higher.[^dsatv] psx-spx reports that the PlayStation accepts values up to FFh for double volume and saturates only partly above that. With this, "80h, 0, 80h, 0" gives normal stereo and "40h, 40h, 40h, 40h" gives mono at the same level.[^spxatv] | ||
| + | |||
| + | ATV0 and ATV2 are 80h after reset, and the other write registers are 00h.[^dsadp] A change to the attenuators takes effect only when CHNGATV is set in ADPCTL.[^dsadp] | ||
| + | |||
| + | Table: ADPCTL register | ||
| + | |||
| + | | Bit | Name | Contents | | ||
| + | | --- | --- | --- | | ||
| + | | 5 | CHNGATV | Apply the ATV0 to ATV3 values | | ||
| + | | 0 | ADPMUTE | Mute ADPCM output | | ||
| + | | 1 to 4, 6, 7 | Reserved | Write 0 | | ||
| + | |||
| + | ## Sound Map Registers | ||
| + | |||
| + | WRDATA (bank 1, 1F801801h) and CI (bank 2, 1F801801h) serve sound map playback, in which the host sends ADPCM sectors to the decoder in place of the disc.[^spxsmap] CI has the layout of the coding information byte of an XA subheader:[^dsci] | ||
| + | |||
| + | Table: CI register | ||
| + | |||
| + | | Bit | Name | Contents | | ||
| + | | --- | --- | --- | | ||
| + | | 6 | EMPHASIS | Emphasis on | | ||
| + | | 4 | BITLNGTH | 8 bits per sample (0 = 4 bits) | | ||
| + | | 2 | FS | 18.9 kHz (0 = 37.8 kHz) | | ||
| + | | 0 | S/M | Stereo (0 = mono) | | ||
| + | | 1, 3, 5, 7 | Reserved | Write 0 | | ||
| + | |||
| + | The sound map procedure and its limits are on the [XA audio](/hardware/cd-rom/xa-audio/) page. | ||
| + | |||
| + | ## Initialization | ||
| + | |||
| + | psx-spx gives the following start-up sequence. The kernel writes 1325h to Com_Delay at 1F801020h as a 32-bit write.[^spxinit] | ||
| + | |||
| + | Table: CD-ROM initialization | ||
| + | |||
| + | | Step | Action | | ||
| + | | --- | --- | | ||
| + | | 1 | Acknowledge all interrupts | | ||
| + | | 2 | Write 0 to HCHPCTL | | ||
| + | | 3 | Write 1325h to Com_Delay (1F801020h) | | ||
| + | | 4 | Send two Nop commands | | ||
| + | | 5 | Send Init (0Ah) | | ||
| + | | 6 | Send Demute | | ||
| + | |||
| + | ## Reading a Sector | ||
| + | |||
| + | For each sector the steps are: wait for INT1, set BFRD, acknowledge INT1 and copy the data to main memory by I/O or DMA.[^spxover] The data request belongs to the interrupt that is pending, so it is normally set between the arrival and the acknowledge of INT1. If the buffer overruns before the request, wrong sectors are delivered without any error flag. After the request the requested data is held intact.[^spxover] | ||
| + | |||
| + | ## References | ||
| + | |||
| + | [^ovr115]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 11-5. | ||
| + | [^ovr1112]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 11-12, Table 11-12. | ||
| + | [^ovr1127]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 11-27. | ||
| + | [^ovr1114]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 11-14, Table 11-15. | ||
| + | [^dsw]: Sony Corporation. CXD1199AQ CD-ROM Decoder. Page 35, sections 3-1-1 to 3-1-6. | ||
| + | [^dshclr]: Sony Corporation. CXD1199AQ CD-ROM Decoder. Page 36, section 3-1-7. | ||
| + | [^dsci]: Sony Corporation. CXD1199AQ CD-ROM Decoder. Page 36, section 3-1-8. | ||
| + | [^dsatv]: Sony Corporation. CXD1199AQ CD-ROM Decoder. Pages 37 and 38, sections 3-1-9 to 3-1-12. | ||
| + | [^dsadp]: Sony Corporation. CXD1199AQ CD-ROM Decoder. Page 39, section 3-1-13. | ||
| + | [^dshsts]: Sony Corporation. CXD1199AQ CD-ROM Decoder. Page 40, section 3-2-1. | ||
| + | [^dsresult]: Sony Corporation. CXD1199AQ CD-ROM Decoder. Page 40, section 3-2-2. | ||
| + | [^dshint]: Sony Corporation. CXD1199AQ CD-ROM Decoder. Page 41, section 3-2-5. | ||
| + | [^dsr]: Sony Corporation. CXD1199AQ CD-ROM Decoder. Page 41, host write and read register tables. | ||
| + | [^dsadr]: Sony Corporation. CXD1199AQ CD-ROM Decoder. Page 35, section 3-1-1. | ||
| + | [^dshchp]: Sony Corporation. CXD1199AQ CD-ROM Decoder. Page 35, section 3-1-4. | ||
| + | [^spxio]: psx-spx. CDROM Drive, CDROM Controller I/O Ports. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxint]: psx-spx. CDROM Internal Info on PSX CDROM Controller, Decoder/FIFO (CXD1199BQ or CXD1815Q). https://psx-spx.consoledev.net/cdrominternalinfoonpsxcdromcontroller/ | ||
| + | [^spxmisc]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, Misc. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxbusy]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, BUSYSTS flag. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxcmd]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, COMMAND. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxprm]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, PARAMETER. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxunsup]: psx-spx. CDROM Drive, CDROM Controller Command Summary, Unsupported GetQ,VCD,SecretUnlock. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxresult]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, RESULT. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxrddata]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, RDDATA. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxhchp]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, HCHPCTL. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxhint]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, HINTSTS. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxhmsk]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, HINTMSK. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxhclr]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, HCLRCTL. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxpoll]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, Caution - Unstable IRQ Flag polling. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxatv]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, ATV0 to ATV3. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxsmap]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, WRDATA and CI. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxinit]: psx-spx. CDROM Drive, CDROM Controller I/O Ports, To init the CD. https://psx-spx.consoledev.net/cdromdrive/ | ||
| + | [^spxover]: psx-spx. CDROM Drive, CDROM - Read Commands, CDROM Incoming Data / Buffer Overrun Timings. https://psx-spx.consoledev.net/cdromdrive/ | ||