psx.wiki

Extended CD-ROM Library (libds): Difference between revisions

Revision as of 02:47, 23 October 2026
RemmyLee
(Formats: Sony paragraph voice; HMD, RSD extended files, full BS code book; sprite editor formats)
Revision as of 02:58, 23 October 2026
RemmyLee
(Run-time library pages: 20 libraries from the Library Overview and Reference 4.4)
Line 1:Line 1:
+---
+title: Extended CD-ROM Library (libds)
+type: component
+summary: Provides a command queue interface to the CD-ROM drive.
+category: Libraries
+info: Library = libds.lib
+info: Header File = libds.h
+---
+
+## Overview
+
+The Extended CD-ROM Library (libds) provides a new interface that uses the kernel of the CD-ROM library ([libcd](/libraries/libcd/)). It has a command queue that absorbs the difference in speed between the CPU and the CD subsystem, and it performs processing specific to the PlayStation, such as the operations needed when the CD cover opens or closes.[^o12-3]
+
+A program that uses libds links with libds.lib and includes libds.h. Because libds controls the CD subsystem through libcd, the program also links libcd.lib and libetc.lib of version 4.0 or later.[^o12-3]
+
+## Relationship with libcd
+
+libds installs its own kernel system over the control routines of libcd, and it offers functions equivalent to those of libcd, so programs are easy to convert. The kernel system and command queue of libds work apart from the libcd functions. Consequently, a libcd function called while libds is in use destroys them, and no function whose name begins with "Cd" is called, CdInit() included.[^o12-3]
+
+The streaming functions (St) are part of libcd.lib, but they do not control the CD subsystem and work normally with libds. Streaming is started with libds functions and commands such as DsRead2() and DslReadS. The CD functions of libapi, such as _96_init(), LoadExec() and Load(), are not used while libds runs.[^o12-3][^o12-4]
+
+## Differences from libcd
+
+The primitive commands of libds perform the same operations as those of libcd, with "Dsl" in place of "Cdl" in their symbols, and libds adds two commands:[^o12-4]
+
+Table: Commands added in libds
+
+| Symbol | Code | Type | Details |
+| --- | --- | --- | --- |
+| DslGetTN | 0x13 | B | Get number of TOC entries |
+| DslGetTD | 0x14 | B | Get TOC |
+
+The structures of libds are DslATV, DslFILE, DslFILTER and DslLOC, which match CdlATV, CdlFILE, CdlFILTER and CdlLOC. The functions are those of libcd with "Ds" in place of "Cd", although some take different arguments or have different timing.[^o12-4][^o12-5]
+
+In libcd a command issued while another runs blocks the function until the previous command ends. In libds the new command enters the queue and the function returns, and at the end of each command and at every VSync the queue is checked for a command that can run. The CPU is therefore never blocked by the CD subsystem, and several commands can be issued at once. All primitive commands of libds are non-blocking, but libds also provides a function that corresponds to CdControlB().[^o12-5]
+
+## Initialization and Exit
+
+DsInit() is executed at the start of the program once ResetGraph() and PadInit() have run. It initializes libcd itself, so CdInit() is not called even when the streaming functions are used. After DsInit() the CD subsystem can no longer be controlled through libcd or libapi, and DsInit() is not called again.[^o12-5]
+
+DsFlush() resets libds during operation by flushing the CD subsystem and clearing the command queue. DsReset() restores the original state but also clears the callbacks, which the program then sets again. DsClose() ends libds before a child process starts, and DsInit() starts it again afterward. None of these functions stops a read or playback. The program therefore issues DslPause with them, since a LoadExec() during a read may fail.[^o12-5][^o12-6]
+
+## Command Queue
+
+The command queue monitors the state of the CD subsystem and controls the issue and completion of the primitive commands. A command is added to the queue and sent when the subsystem can receive it. The queue also performs the operations the subsystem needs, such as those after the cover is opened, and commands wait in the queue meanwhile.[^o12-6]
+
+DsCommand() adds a command to the queue. Its third argument is a callback called when that command completes, and it returns a command ID, or 0 when the queue is full. DsSync() returns the state of a command by its ID:[^o12-6][^o12-7]
+
+Table: Command completion states
+
+| Symbol | Meaning |
+| --- | --- |
+| DslComplete | Command exited normally |
+| DslDiskError | Command returned an error |
+| DslNoIntr | Command has not yet been executed |
+| DslNoResult | Command has exited but no results are available |
+
+libds keeps the results of the last commands, up to the number DslMaxRESULTS, so DsSync() returns DslNoResult for a command that is too old. DsQueueLen() returns the number of commands in the queue, including the one being executed, and the maximum is DslMaxCOMMANDS. DsSystemStatus() returns DslReady when the subsystem is idle, DslBusy when a command runs or commands cannot run, and DslNoCD when no disc is found after the cover closes.[^o12-7]
+
+A command that can run is sent at once, and otherwise it is issued from the sync callback of the previous command. When operations are blocked, for example by the cover, the queue is polled at the VSync interrupt.[^o12-8]
+
+The fourth argument of DsCommand() is the retry count. A command that fails is issued again that many times and then returns an error and leaves the queue, a count of 0 gives no retry and -1 retries until it succeeds. When the cover opens, all commands in the queue are cancelled and their callbacks are called in queue order.[^o12-8]
+
+A callback may be set for each command, and it is removed after it has been called once. A common callback is called when all commands have completed or when an error such as an open cover occurs. Each callback takes the arguments intr and result like a data ready callback.[^o12-8]
+
+## Multiple Operations
+
+Several commands can wait in the queue, but only one data read or playback runs at a time. DslReadN, DslReadS and DslPlay are complete as soon as the subsystem accepts them and then leave the queue. The next command in the queue may therefore stop the read before its data arrives. A program issues one read, takes its data and only then queues the next read.[^o12-8]
+
+## Command Packets
+
+A command packet is a series of commands issued together. DsPacket() enters four commands into the queue. DslPause ends the previous operation, DslSetmode sets the mode and DslSetloc sets the position, and the command given in com follows them. The command may be DslPlay, DslReadN or DslReadS, or DslSeekL or DslSeekP for a pre-seek.[^o12-9]
+
+Each packet sets its own mode and start position, so it does not depend on the previous state of the subsystem. On an error the whole packet is retried from its first command, which makes the retry more likely to succeed. The manual therefore recommends packets for reads and playback. A packet is complete when all its commands are, and DsSync() returns the result of its last command.[^o12-9][^o12-10]
+
+## Simple Callback
+
+A read issues a data read command and transfers each sector from the sector buffer to main memory after each data ready interrupt. The simple callback started by DsStartReadySystem() handles these interrupts. It is called only when a sector is read normally, and libds recovers from read errors itself.[^o12-10]
+
+On an error libds reissues the command from its saved state: the last command, mode, seek position and current position. The read restarts at the sector before the error, but the callback is called next for the sector after the last good one. For example, after an error at the fourth sector, the callback follows with the fourth sector.[^o12-10]
+
+The callback receives DslDataReady, or DslDataEnd for DA playback. It receives DslDiskError when the retry count is exceeded or the cover opens, and the application recovers in these cases. When the callback runs the subheader has already been read, so the 2048 bytes of the data body can be transferred at once. The read mode must use a 2340-byte sector (DslModeSize1 on, DslModeSize0 off).[^o12-11]
+
+DsEndReadySystem() ends the simple callback right after the last sector, since further reads would call it again and overwrite memory. DsReadySystemMode(1) makes the simple callback wait through an open cover and recover as from an error. The library cannot tell whether the disc was changed, however, so automatic recovery is not used while discs are swapped. DsGetDiskType(), DsPlay() and DsRead() also use the simple callback.[^o12-11][^o12-12]
+
+## Cover and Disc Swaps
+
+When the cover opens libds becomes busy (DslBusy) and blocks the commands of the user. When it closes, libds checks the disc again and returns to DslReady. The operation in progress returns an error and the queue is emptied. The mode and head position are also initialized, so the program repeats the operation once libds is ready.[^o12-12]
+
+libds does not identify the disc after a swap. The program confirms that the cover has opened with DsStatus() and waits for DslReady from DsSystemStatus(). It then checks with DsGetDiskType() that the disc is a PlayStation disc and with its own data that it is the right disc. DslNoCD means that the spindle did not turn and no disc was found.[^o12-12][^o12-13]
+
+## Transfer Speed Change
+
+After a change of transfer speed the drive cannot execute head commands for a time. libds therefore sets the status to DslBusy for 3 VSyncs after the speed change and holds the commands in the queue, which run automatically afterward. The program need not wait itself.[^o12-13]
+
+## Seeks and Load Time
+
+A seek to the start of the next file before it is needed shortens a read by about 0.4 seconds, and a command packet automates its retries. Reducing seeks is the most effective way to shorten loading. A layout in which several files are read by one continuous read saves about 0.4 seconds per seek, so five fewer seeks load two seconds faster. The simple callback changes the transfer address between files during the read.[^o12-13]
+
+A seek into the outer three minutes of the disc can go wrong depending on its start point. The outer three minutes are therefore filled with unused data, given to a CD-DA final track of three minutes or more that is played from its start, or used for one continuous file such as a movie.[^o12-13]
+
+## Structures
+
+In the tables below, Introduced is the run-time library version that added the item.[^refs113]
+
+libds has the following structures:[^refs113]
+
+Table: libds structures
+
+| Structure | Introduced | Purpose |
+| --- | --- | --- |
+| `DslATV` | 4.0 | Audio attenuator. |
+| `DslFILE` | 4.0 | 9660 file descriptor. |
+| `DslFILTER` | 4.0 | ADPCM channel. |
+| `DslLOC` | 4.0 | CD-ROM location. |
+
+## Functions
+
+libds has the following functions:[^reff117]
+
+Table: libds functions
+
+| Function | Introduced | Purpose |
+| --- | --- | --- |
+| `DsClose` | 4.0 | Close the libds system. |
+| `DsCommand` | 4.0 | Add primitive command to the command queue. |
+| `DsComstr` | 4.3 | Get the character string corresponding to each command code (for debugging). |
+| `DsControl` | 4.0 | CdControl() compatibility function. |
+| `DsControlB` | 4.0 | CdControlB() compatibility function. |
+| `DsControlF` | 4.0 | CdControlF() compatibility function. |
+| `DsDataCallback` | 4.0 | Set exit callback for DsGetSector() and DsGetSector2(). |
+| `DsDataSync` | 4.0 | Wait for completion of DsGetSector2. |
+| `DsEndReadySystem` | 4.0 | End simple callback system. |
+| `DsFlush` | 4.0 | Flush the command queue. |
+| `DsGetDiskType` | 4.0 | Get CD type. |
+| `DsGetSector` | 4.0 | Transfer data from the sector buffer to main memory. |
+| `DsGetSector2` | 4.0 | Transfer data from the sector buffer to main memory (non-blocking). |
+| `DsGetToc` | 4.1 | TOC read. |
+| `DsInit` | 4.0 | Perform system initialization. |
+| `DsInstr` | 4.3 | Get the corresponding character string for the command process status (for debugging). |
+| `DsIntToPos` | 4.0 | Get minutes, seconds, sectors from absolute sector number. |
+| `DsLastCom` | 4.3 | Get the command issued last. |
+| `DsLastPos` | 4.0 | Get the last setloc position. |
+| `DsMix` | 4.0 | Set attenuator. |
+| `DsPacket` | 4.0 | Add a sequence of commands to the queue. |
+| `DsPlay` | 4.0 | Play back CD-DA tracks. |
+| `DsPosToInt` | 4.0 | Get absolute sector number from minutes, seconds, sectors. |
+| `DsQueueLen` | 4.0 | Get the number of commands stored in the command queue. |
+| `DsRead` | 4.0 | Read data. |
+| `DsRead2` | 4.0 | Begin playback of movie. |
+| `DsReadBreak` | 4.0 | Interrupt DsRead() operation. |
+| `DsReadCallback` | 4.0 | Set a callback function to be called when DsRead() is finished. |
+| `DsReadExec` | 4.0 | Read an executable file. |
+| `DsReadFile` | 4.0 | Read a file from CD-ROM. |
+| `DsReadSync` | 4.0 | Wait for completion of DsRead(). |
+| `DsReady` | 4.0 | Check for arrival of data. |
+| `DsReadyCallback` | 4.0 | Set up Ready callback function. |
+| `DsReadySystemMode` | 4.1 | Set action of cover open/close for the simple callback. |
+| `DsReset` | 4.0 | Reset system. |
+| `DsSearchFile` | 4.0 | Get position and size of CD-ROM file. |
+| `DsSetDebug` | 4.0 | Set the debug level. |
+| `DsShellOpen` | 4.0 | Get the number of times the cover was opened. |
+| `DsStartReadySystem` | 4.0 | Start the simple callback. |
+| `DsStatus` | 4.0 | Get the status of the CD subsystem. |
+| `DsSync` | 4.0 | Check for completion of primitive command. |
+| `DsSyncCallback` | 4.0 | Set Sync Callback function. |
+| `DsSystemStatus` | 4.0 | Get status of command queue. |
+
+## References
+
+[^o12-3]: Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 12-3.
+[^o12-4]: Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 12-4.
+[^o12-5]: Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 12-5.
+[^o12-6]: Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 12-6.
+[^o12-7]: Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 12-7.
+[^o12-8]: Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 12-8.
+[^o12-9]: Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 12-9.
+[^o12-10]: Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 12-10.
+[^o12-11]: Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 12-11.
+[^o12-12]: Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 12-12.
+[^o12-13]: Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 12-13.
+[^refs113]: Sony Computer Entertainment Inc. Run-Time Library Reference. Run-Time Library 4.4. January 1999. Pages 11-3 to 11-6.
+[^reff117]: Sony Computer Entertainment Inc. Run-Time Library Reference. Run-Time Library 4.4. January 1999. Pages 11-7 to 11-49.