psx.wiki

BIOS File I/O

I/O management service for the CD-ROM, Memory Card and console devices.

BIOS File I/O
Open files16, of which 2 are standard I/O
Devicescdrom, bu, tty

Overview

The PlayStation supports low-level access to files and logical devices through the I/O management service, and all file control on the PlayStation is performed with it.12 Each file system is reached through a device driver, which allows several file systems to coexist.3 The structures used for input and output are defined in sys/file.h.1

A file name starts with the device name. Examples are cdrom:PSX.EXE;1 and bu00:ABCD12345.1 Each device has a data access unit called its block size, and all data access is done in multiples of the block size. If a size given to read() or write() has a fraction, the fraction is discarded.1

Devices

The kernel supports the following devices.14

Table 1: IO devices
Device name Contents Block size Example of file designation
cdrom CD-ROM file system 2048 bytes cdrom:PSX.EXE;1
bu Memory Card file system 128 bytes bu00:ABCD12345
tty Console (DUART or dummy) 1 byte tty00:

Device names are lowercase and case-sensitive. A hexadecimal port number may follow the name, so "bu00:" selects the first Memory Card slot and "cdrom:" is short for "cdrom0:".56 Because a trailing hex digit is read as the port number, a device name must not end in a hex digit.5

CD-ROM File System

The CD-ROM file system conforms to the level 1 format of ISO 9660.1 Its rules are shown below.

Table 2: CD-ROM file system (ISO 9660 level 1)
Item Rule
Device name cdrom
File format basename.extension;version, with an 8-letter base name and an extension of up to 3 letters
Characters English capital letters, numbers and underscore
Directory name format Base name of 8 letters
Directory hierarchy At most 8 levels, no root name
File arrangement All sectors of a file are physically contiguous
Block size 2048 bytes

The file and directory lists are supported only as far as they fit in one 2048-byte sector. With standard 8.3 names this allows up to 45 directories and 30 files per directory, and shorter names allow more.1 A program can avoid the limits by keeping track of its own files and not using CdSearchFile().1

The PlayStation Operating System manual states a different rule: subdirectories cannot be created, all files are in the root directory, and the number of files there has no limit.7

cd() changes the default directory of a device. Only the directory is remembered, so every file name must still include the device name. The function does not check that the directory exists, and for the CD-ROM it reads the path table from the disc on every call.89 The kernel has no function for playing CD audio tracks or for setting the XA-ADPCM filter, so these require direct access to the CD-ROM ports.6

Memory Card File System

The Memory Card file system manages the files on the removable Memory Card used for saving game data. Mounting and initialization are performed by libcard BIOS calls.10

Table 3: Memory Card file system
Item Rule
Device name buXY, with X the port (0 for A, 1 for B) and Y the extension connector number (1 and up) or 0
File format ASCII base name of up to 20 bytes, with no extension
Directory structure None
Block size 128 bytes

Before the file functions are used on a Memory Card, a program calls InitCARD2(), StartCARD2() and then _bu_init().11 The file size is fixed when the file is created: it must be a multiple of 0x2000 bytes (one block), up to 0x1E000 bytes for all 15 blocks, and is given in bits 16 to 31 of the access mode. The BIOS does not allow the size to change afterward.11 Reads and writes must be multiples of 0x80 bytes at positions aligned to 0x80 bytes, but they may cross block boundaries.11 The first 0x100 to 0x200 bytes of a file must hold its title and icon.11

The BIOS accesses only one sector per frame, and each slot only on every second frame. Consequently Memory Card access through the BIOS runs at about 0.5 sectors per frame.11 The device names bu01 to bu03 and bu11 to bu13 select extra cards on a Multi Tap. However, the BIOS keeps directory and broken sector buffers for only two cards, and using more cards may corrupt data.11 The Memory Card file system format page describes the data on the card.

Standard I/O Stream

The standard I/O stream reserves file descriptors 0 and 1.10 The PlayStation Operating System manual assigns standard output to descriptor 0 and standard input to descriptor 1, on RS232C channel 0 (tty00) with 8-bit characters, one stop bit and no parity under hardware flow control.12 On the game unit the stream is assigned to a NULL device, and in the development environment standard output goes to Debug Message Window #0.10

Several BIOS functions print status and error messages with printf(). Closing descriptors 0 and 1 therefore makes those functions unstable.13

Open Modes

open() opens a device for low-level input and output and returns a descriptor. The values of the open mode depend on the device.14

Table 4: Open modes
Macro Open mode
O_RDONLY Read only
O_WRONLY Write only
O_RDWR Both read and write
O_CREAT Create new file
O_NOBUF Non-buffer mode
O_NOWAIT Asynchronous mode

The bits of the access mode word as the BIOS reads them are shown below.9

Table 5: BIOS access mode bits
Bit Meaning
0 Read
1 Write
2 Return without waiting when the TTY buffer is empty
9 Create a new file (Memory Card only)
15 Asynchronous mode (Memory Card only)
16 to 31 Number of blocks for a new Memory Card file

The BIOS ignores bits 0 and 1. However, at least one bit of the word must be set, or the open fails.9 Up to 16 files may be open at once. Two descriptors are reserved for standard I/O, and cd(), testdevice(), erase(), undelete(), format(), firstfile2() and rename() each borrow one internally. Consequently erase() fails when a game has more than 13 files open.9

File Functions

Table 6: File functions
Function BIOS Explanation
open(devname, flag) A(00h), B(32h) Opens a file and returns its descriptor, or -114
lseek(fd, offset, flag) A(01h), B(33h) Moves the file pointer from SEEK_SET or SEEK_CUR15
read(fd, buf, n) A(02h), B(34h) Reads n bytes and returns the number read, or -116
write(fd, buf, n) A(03h), B(35h) Writes n bytes and returns the number written, or -117
close(fd) A(04h), B(36h) Closes the file and returns fd, or -118
ioctl(fd, com, arg) A(05h), B(37h) Executes a device control command19
cd(path) B(40h) Changes the default directory8
format(fs) B(41h) Initializes a writeable file system20
firstfile(name, dir) B(42h) Finds the first file matching a name pattern21
nextfile(dir) B(43h) Finds the next file matching the same pattern22
rename(src, dest) B(44h) Changes a file name; both names include the device23
erase(name) B(45h) Deletes a file (formerly called delete)24
undelete(name) B(46h) Resurrects a deleted file25
_get_errno() B(54h) Returns the latest I/O error code26
_get_error(fd) B(55h) Returns the error code of one descriptor27

The BIOS function at B(42h) is named firstfile2 by psx-spx.28 lseek() from the end of a file (seek type 2) does not work in the BIOS, and movement past the end of a file is not checked.9 Sony notes that lseek() does not apply to a PC communication link.15 A read on the bu device proceeds in 0x80-byte units and on the cdrom device in 0x800-byte units, and a write to the cdrom device returns 0.9

Directory Entries

firstfile() and nextfile() store information about a file in a DIRENTRY structure. The wildcards "?" (any one character) and "" (any string) may be used in the name, and characters after "" are ignored.2129

struct DIRENTRY {
    char name[20];            /* filename */
    long attr;                /* attributes (dependent on file system) */
    long size;                /* file size (in bytes) */
    struct DIRENTRY *next;    /* pointer to next file entry (for user) */
    char system[8];           /* reserved by system */
};
Table 7: DIRENTRY layout
Offset Size Contents
0x00 0x14 File name, ended by 0x00
0x14 4 Attribute (0 for CD-ROM; 0x50 normal or 0xA0 deleted for a Memory Card)
0x18 4 File size
0x1C 4 Pointer to the next entry (not used by the BIOS)
0x20 4 First sector number
0x24 4 Reserved

The offsets and attribute values are from psx-spx.9 nextfile() fails and reports that no file is found if the CD-ROM shell cover has been opened since the previous firstfile().22 set_card_find_mode(1) makes firstfile2() and nextfile() find deleted Memory Card files.11

Error Codes

_get_errno() returns the latest error code from all file descriptors, and the codes are defined in sys/errno.h.26 The code is not cleared by functions that succeed, so it is meaningful only after an error.9

Table 8: File error numbers
Code Meaning
0x00 No error
0x02 File not found
0x06 Bad device port number (tty2 and up)
0x09 Invalid or unused file handle
0x10 General error (I/O error, unformatted card, disc changed)
0x11 File already exists (create, undelete, rename)
0x12 Rename across devices
0x13 Unknown device name
0x16 Sector alignment error, position past the end, unknown seek type or ioctl command
0x18 Not enough free file handles
0x1C Not enough free Memory Card blocks

The codes are from psx-spx.9

CD-ROM Functions

The normal file functions read the CD-ROM synchronously and wait until all data is transferred. A file can be read asynchronously instead by finding its first sector with CdGetLbn() and reading with CdAsyncSeekL() and CdAsyncReadSector(). This works because CD-ROM files are never fragmented.6 Before the boot executable starts, the BIOS calls _96_init(), so a game can use the CD-ROM file functions without initialization.6

Table 9: BIOS CD-ROM functions
Function BIOS Explanation
_96_init() A(54h), A(71h) Installs the ISO 9660 file system driver30
_96_remove() A(56h), A(72h) Removes the ISO 9660 file system driver31
CdGetLbn(filename) A(A4h) Returns the first sector of a file
CdReadSector(count, sector, buffer) A(A5h) Reads count 2048-byte sectors at double speed and waits
CdGetStatus() A(A6h) Returns the drive status byte
CdAsyncSeekL(src) A(78h) Issues Setloc and SeekL to a BCD MM:SS:FF position
CdAsyncGetStatus(dst) A(7Ch) Issues GetStat and stores the status byte
CdAsyncReadSector(count, dst, mode) A(7Eh) Issues SetMode and ReadN, or ReadS when mode bit 8 is set
CdAsyncSetMode(mode) A(81h) Issues SetMode only

The asynchronous functions return 1 when the command is accepted and 0 on failure. Completion is reported by an event with class 0xF0000003 and type 0x20, 0x80, or 0x8000.6 The sector size of CdAsyncReadSector() follows the mode: 0x918 bytes when bit 4 is set, 0x924 bytes when only bit 5 is set, and 0x800 bytes otherwise.6

CdGetLbn() returns -1 for the first entry of a directory, and garbage when the file is not found.6 CdAsyncGetStatus() clears the door open flag but does not reload the path table. After a disc change a program should therefore call cd() or another function that reloads the path table.6 _96_remove() does not work in the retail BIOS, because SysDeqIntRP() cannot remove the CD-ROM interrupt handlers.6

Memory Card Functions

The Memory Card functions below the file system work on single 128-byte sectors.11

Table 10: BIOS Memory Card functions
Function BIOS Explanation
InitCARD2(pad_enable) B(4Ah) Initializes the card driver and selects whether pads are read with it
StartCARD2() B(4Bh) Starts the card driver
StopCARD2() B(4Ch) Stops the card driver
_bu_init() A(55h), A(70h) Initializes the Memory Card file system
_card_read(port, sector, dst) B(4Fh) Starts reading one sector
_card_write(port, sector, src) B(4Eh) Starts writing one sector
_card_status(slot) B(5Ch) Returns the status of the last command
_card_wait(slot) B(5Dh) Waits until the last command is not busy
_card_info(port) A(ABh) Checks a card with a dummy read
_card_load(port) A(ACh) Reads the directory asynchronously
_card_auto(flag) A(ADh) Turns automatic formatting on or off
card_write_test(port) A(AFh) Clears the card change flag with a dummy write
_new_card() B(50h) Ignores the card change flag on the next access

_card_read() and _card_write() take sector numbers 0 to 0x3FF and access the sector directly. They do not use the broken sector replacement list. They return 1 when the command starts and 0 for an invalid sector.11 A write error is reported only when the next sector command completes, so _card_info() is used to verify the last sector written.11

Table 11: Memory Card command status
Value Status
0x01 Ready
0x02 Busy, reading
0x04 Busy, writing
0x08 Busy, info
0x11 Failed, timeout (no card)
0x21 Failed, general error

The file read() and write() functions run asynchronously when the file is opened with access mode bit 15. Completion is then reported by one of several events, which the game must open and test.11 The events page lists these events. Automatic formatting formats a card whenever the "MC" identifier in sector 0 cannot be read. psx-spx warns that a dirty or loose card can cause such a read error, and _bu_init() leaves automatic formatting off.11

Control Blocks

The kernel keeps 16 file control blocks of 0x2C bytes and 10 device control blocks of 0x50 bytes at fixed addresses in its variables.4 A file descriptor converts to its FCB as [0x140] + fd * 0x2C.32

Table 12: File control block
Offset Contents
0x00 Status (0 free, otherwise the access mode)
0x04 Disc ID (CD-ROM) or port number (Memory Card)
0x08 Transfer address
0x0C Transfer length
0x10 Current file position
0x14 Device flags (copy of DCB 0x04)
0x18 Error code (returned by _get_error)
0x1C Pointer to the DCB
0x20 File size
0x24 First logical block number
0x28 FCB number (0 to 15)
Table 13: Device control block
Offset Contents
0x00 Pointer to the lowercase name (cdrom, bu, tty), or 0 when free
0x04 Device flags (cdrom 0x14, bu 0x14, dummy tty 1, DUART tty 3)
0x08 Sector size (cdrom 0x800, bu 0x80, tty 1)
0x0C Pointer to the long name (CD-ROM, MEMORY CARD, CONSOLE)
0x10 to 0x4C Pointers to the init, open, in_out, close, ioctl, read, write, erase, undelete, firstfile, nextfile, format, cd, rename, remove and testdevice functions

The control block layouts are from psx-spx.4

References


  1. ^ a b c d e f g h Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-15, Table 2-17, Table 2-18.

  2. ^ Sony Computer Entertainment Inc. PlayStation Operating System. August 1998. Page 3-3.

  3. ^ Sony Computer Entertainment Inc. PlayStation Operating System. August 1998. Page 1-4.

  4. ^ a b c psx-spx. Kernel (BIOS), BIOS Control Blocks. https://psx-spx.consoledev.net/kernelbios/

  5. ^ a b psx-spx. Kernel (BIOS), BIOS More Internal Functions, Device Names. https://psx-spx.consoledev.net/kernelbios/

  6. ^ a b c d e f g h i psx-spx. Kernel (BIOS), BIOS CDROM Functions. https://psx-spx.consoledev.net/kernelbios/

  7. ^ Sony Computer Entertainment Inc. PlayStation Operating System. August 1998. Page 2-4.

  8. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-11, cd.

  9. ^ a b c d e f g h i psx-spx. Kernel (BIOS), BIOS File Functions. https://psx-spx.consoledev.net/kernelbios/

  10. ^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-16, Table 2-19.

  11. ^ a b c d e f g h i j k l psx-spx. Kernel (BIOS), BIOS Memory Card Functions. https://psx-spx.consoledev.net/kernelbios/

  12. ^ Sony Computer Entertainment Inc. PlayStation Operating System. August 1998. Page 4-5.

  13. ^ psx-spx. Kernel (BIOS), BIOS TTY Console (std_io). https://psx-spx.consoledev.net/kernelbios/

  14. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-53, open, Table 1-3.

  15. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-49, lseek.

  16. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-56, read.

  17. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-77, write.

  18. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-14, close.

  19. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-43, ioctl.

  20. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-29, format.

  21. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-27, firstfile.

  22. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-52, nextfile.

  23. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-59, rename.

  24. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-23, erase.

  25. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-74, undelete.

  26. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-81, _get_errno.

  27. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-82, _get_error.

  28. ^ psx-spx. Kernel (BIOS), BIOS Function Summary. https://psx-spx.consoledev.net/kernelbios/

  29. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-3, DIRENTRY.

  30. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-78, _96_init.

  31. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-79, _96_remove.

  32. ^ psx-spx. Kernel (BIOS), Table of Tables. https://psx-spx.consoledev.net/kernelbios/

Categories: System software