PSX cdrom sector buffer capacity
Posted: April 8th, 2013, 6:36 am
I have been doing some hardware tests on a PSone to find out how many sectors the console can hold in its sector buffer. The result is a bit puzzling: It seems to be able to hold up to EIGHT sectors, BUT: it allows to access only TWO of those sectors. The other sectors are lost - they appear to be in the buffer, but I haven't found a way to read them. Either I am doing something wrong (?) ... or Sony has made a fundamental mistake in their hardware design.
Some more details: The CDROM sector buffer is 32Kx8 SRAM (IC303 on PU-8/PU-18 boards; intergrated in the SPU on later boards). The buffer is apparently divided into 8 slots, theoretically allowing to buffer up to 8 sectors. But, the drive controller seems to allow only 2 of those 8 sectors (the oldest sector, and the current/newest sector), ie. after processing the INT1 for the oldest sector, one would expect the controller to generate another INT1 for next newer sector - but instead it appears to jump directly to INT1 for the newest sector (skipping all other unprocessed sectors).
So far, the big 32Kbyte buffer is entirely useless (the two accessible sectors could have been as well stored in a 8Kbyte chip) (unless, maybe the 32Kbytes have been intended for some error-correction "read-ahead" purposes, rather than as "look-back" buffer for old sectors; one of the unused slots might be also used for XA-ADPCM sectors).
The bottom line is that one should process INT1's as soon as possible (ie. before the cdrom controller receives and skips further sectors). Otherwise sectors would be lost without notice. As far as I know there appear to be absolutely no overrun status flags, nor overrun error interrupts - or are there such overrun notifications?
Did anybody else see the same lost-sector-problem? And is there a way around it?
Of course the two latters tests (with longer delays, and with overwritten slots) can't work, but the test with short delay should work.
Some more details: The CDROM sector buffer is 32Kx8 SRAM (IC303 on PU-8/PU-18 boards; intergrated in the SPU on later boards). The buffer is apparently divided into 8 slots, theoretically allowing to buffer up to 8 sectors. But, the drive controller seems to allow only 2 of those 8 sectors (the oldest sector, and the current/newest sector), ie. after processing the INT1 for the oldest sector, one would expect the controller to generate another INT1 for next newer sector - but instead it appears to jump directly to INT1 for the newest sector (skipping all other unprocessed sectors).
So far, the big 32Kbyte buffer is entirely useless (the two accessible sectors could have been as well stored in a 8Kbyte chip) (unless, maybe the 32Kbytes have been intended for some error-correction "read-ahead" purposes, rather than as "look-back" buffer for old sectors; one of the unused slots might be also used for XA-ADPCM sectors).
The bottom line is that one should process INT1's as soon as possible (ie. before the cdrom controller receives and skips further sectors). Otherwise sectors would be lost without notice. As far as I know there appear to be absolutely no overrun status flags, nor overrun error interrupts - or are there such overrun notifications?
Code: Select all
Some sector buffer test cases...
Setloc(0:2:0)+Read
Process INT1 --> receives sector header for 0:2:0
Process INT1 --> receives sector header for 0:2:1
Process INT1 --> receives sector header for 0:2:2
Process INT1 --> receives sector header for 0:2:3
Above shows the normal flow when processing INT1's as they arise. Now,
inserting delays (and not processing INT1's during that delays):
Setloc(0:2:0)+Read
Process INT1 --> receives sector header for 0:2:0
delay(1)
Process INT1 --> receives sector header for 0:2:1 (oldest sector)
Process INT1 --> receives sector header for 0:2:6 (newest sector)
Process INT1 --> receives sector header for 0:2:7 (next sector)
Above suggests that the CDROM buffer can hold max 2 sectors (the oldest
and current one). However, using a longer delay:
Setloc(0:2:0)+Read
Process INT1 --> receives sector header for 0:2:0
delay(2)
Process INT1 --> receives sector header for 0:2:9 (oldest/overwritten)
Process INT1 --> receives sector header for 0:2:11 (newest sector)
Process INT1 --> receives sector header for 0:2:12 (next sector)
Above indicates that sector buffer can hold 8 sectors (as the sector 1 slot
is overwritten by sector 9). And, another test with even longer delay:
Setloc(0:2:0)+Read
Process INT1 --> receives sector header for 0:2:0
delay(3)
Process INT1 --> receives sector header for 0:2:17 (currently received)
Process INT1 --> receives sector header for 0:2:16 (newest full sector)
Process INT1 --> receives sector header for 0:2:17 (next sector)
Process INT1 --> receives sector header for 0:2:18 (next sector)
Above is a special case where sector 17 appears twice; the first one is the
sector 1 slot (which was overwritten by sector 9, and apparently then half
overwritten by sector 17).
Of course the two latters tests (with longer delays, and with overwritten slots) can't work, but the test with short delay should work.