System Calls

The Dreamcast ROM does not offer much in terms of system calls for applications to use. If fact, the few that are available are not even executed from the ROM, but reside in the RAM area 8C000000-8C007FFF together with the default exception and interrupt handlers. Any functionality not provided by these syscalls (graphics/sound/whatnot) must be performed by the application itself banging the hardware. The official devkit provides link libraries to perform these duties.

Calling conventions

Each system call is performed via an indirect vector. This means that rather than calling a fixed address, a function pointer is fetched from the fixed address and the call goes through this pointer. For each vector there is a number of different functions available, selected by register r7. Sometimes there is also a superfunction to be selected by register r6. Any arguments to the syscall is passed in registers r4 and r5 (and r6, if it is not used to select superfunction) as in a normal function call. The ROMFONT syscalls are a bit peculiar by using r1 instead of r7 to select function.

Function call list

This is a list of all known system calls. They are sorted first by vector, and then by (superfunction and) function code. Detailed descriptions follow below. (The names selected for the syscalls below are totally arbitrary, and is only intended as a mnemonic for the function of the call.)

Vector 8C0000B0 - System information functions
Vector 8C0000B4 - Boot-ROM font functions
Vector 8C0000B8 - Flash ROM functions
Vector 8C0000BC - MISC/GDROM functions

Vector 8C0000B0 - SYSINFO


Prepares the other two SYSINFO calls for use by copying the relevant data from the system flashrom into 8C000068-8C00007F. Always call this function before using the other two calls.

Args: none

Returns: zero


Read an icon from the flashrom. The format those icons are in is not known. SYSINFO_INIT must have been called first.


  • r4 = icon number (0-9, but only 5-9 seems to really be icons)
  • r5 = destination buffer (704 bytes in size)

Returns: number of read bytes if successful, negative if read failed


Query the unique 64 bit ID number of this Dreamcast. SYSINFO_INIT must have been called first.

Args: none

Returns: A pointer to where the ID is stored as 8 contiguous bytes

Vector 8C0000B4 - ROMFONT


Returns the address of the ROM font. The font is organized as 288 narrow characters (12 24 pixels), followed by 7078 wide characters (24 24 pixels), finally followed by 129 VMS icons (32 32 pixels). The total size of the font is thus (288 * 12 * 24 / 8) + (7078 * 24 * 24 / 8) + (129 * 32 *32 / 8) = (288 * 36) + (7078 * 72) + (129 * 128) = 10368 + 509616 + 16512 = 536496 bytes. Note that the narrow characters are stored as three nybbles per line, so each pair of two lines occupy three bytes together.

The organization of the narrow characters are as follows:
0 Overbar ()
1-94 ASCII characters 33-126
95 Yen ()
96-191 ISO-8859-1 characters 160-255
192-287 JISX-0201 characters 160-255
(As there is no glyph for ASCII space, use glyph 96 = ISO-8859-1 unbreakable space instead.)

The organization of the wide characters are as follows (a row is 94 characters):
0-657 JISX-0208 row 33-39
658-7049 JISX-0208 row 48-115
7050-7055 JISX-0208 row 116 (first 6 characters)
7056-7077 Dreamcast specific glyphs (A,B,X,Y, direction arrows, etc.)

The organization of the VMS icons are as follows:
0 Invalid VMS icon (circle + cross)
1-4 Hourglass animation
5-128 User selectable icons

Args: none

Returns: A pointer to the first narrow character


Tries to lock a mutex for exclusive access to the ROM font. Quite why anyone would want to arbitrate for access to a resource that resides in ROM is beyond me, but there you have it... The mutex is not checked by ROMFONT_ADDRESS, only by this function.

Args: none

Returns: 0 if you got the mutex (unlock it with ROMFONT_UNLOCK when you're done), -1 if it was already taken by someone else


Releases the mutex locked with ROMFONT_LOCK. Only call this function if you actually got the mutex.

Args: none

Returns: no return value

Vector 8C0000B8 - FLASHROM


Queries the extent of a single partition in the system flashrom.


  • r4 = partition number (0-4)
  • r5 = pointer to two 32 bit integers to receive the result. The first will be the offset of the partition start, in bytes from the start of the flashrom. The second will be the size of the partition, in bytes.

Returns: zero if successful, -1 if no such partition exists


Read data from the system flashrom.


  • r4 = read start position, in bytes from the start of the flashrom
  • r5 = pointer to destination buffer
  • r6 = number of bytes to read

Returns: number of read bytes if successful, -1 if read failed


Write data to the system flashrom. Important: It is only possible to overwrite 1:s with 0:s, 0:s can not be written back to 1:s. General overwriting is therefore not possible. Only bytes containing all ones ($FF) can be written with arbitrary values.


  • r4 = write start position, in bytes from the start of the flashrom
  • r5 = pointer to source buffer
  • r6 = number of bytes to write

Returns: number of written bytes if successful, -1 if write failed


Return a flashrom partition to all ones, so that it may be rewritten. Danger Will Robinson: ALL data in the entire partition will be lost.


  • r4 = offset of the start of the partition you want to delete, in bytes from the start of the flashrom

Returns: zero if successful, -1 if delete failed

Vector 8C0000BC - MISC/GDROM

MISC_INIT (r6=-1, r7=0)

Initializes all the syscall vectors to their default values.

Args: none

Returns: zero

MISC_SETVECTOR (r6=-1, r7=1)

Sets/clears the handler for one of the eight superfunctions for this vector. Setting a handler is only allowed if it not currently set.


  • r4 = superfunction number (0-7)
  • r5 = pointer to handler function, or NULL to clear

Returns: zero if successful, -1 if setting/clearing the handler fails


Enqueue a command for the GDROM subsystem to execute.


  • r4 = command code
  • r5 = pointer to parameter block for the command, can be NULL if the command does not take parameters

Returns: a request id (>=0) if successful, negative error code if failed


Check if an enqueued command has completed.


  • r4 = request id
  • r5 = pointer to four 32 bit integers to receive extended status information. The first is a generic error code.


  • 0 - no such request active
  • 1 - request is still being processed
  • 2 - request has completed (if queried again, you will get a 0)
  • 3 - request was aborted(?)
  • -1 - request has failed (examine extended status information for cause of failure)

GDROM_MAINLOOP (r6=0, r7=2)

In order for enqueued commands to get processed, this function must be called a few times. It can be called from a periodic interrupt, or just keep calling it manually until GDROM_CHECK_COMMAND says that your command has stopped processing.

Args: none

Returns: no return value

GDROM_INIT (r6=0, r7=3)

Initialize the GDROM subsystem. Should be called before any requests are enqueued.

Args: none

Returns: no return value

GDROM_CHECK_DRIVE (r6=0, r7=4)

Checks the general condition of the drive.


  • r4 = pointer to two 32 bit integers, to receive the drive status. The first is the current drive status, the second is the type of disc inserted (if any).
  • Drive status
    0 Drive is busy
    1 Drive is paused
    2 Drive is in standby
    3 Drive is playing
    4 Drive is seeking
    5 Drive is scanning
    6 Drive lid is open
    7 Lid is closed, but there is no disc
    Disk type
    $00 CDDA
    $10 CDROM
    $20 CDROM/XA
    $30 CDI
    $80 GDROM

Returns: zero if successful, nonzero if failure


Tries to abort a previously enqueued command.


  • r4 = request id

Returns: zero if successful, nonzero if failure

GDROM_RESET (r6=0, r7=9)

Resets the drive.

Args: none

Returns: no return value

GDROM_SECTOR_MODE (r6=0, r7=10)

Sets/gets the sector format for read commands.


  • r4 = pointer to a struct of four 32 bit integers containing new values, or to receive the old values
  • FieldFunction
    0 Get/Set, if 0 the mode will be set, if 1 it will be queried.
    1 ? (always 8192)
    2 1024 = mode 1, 2048 = mode 2, 0 = auto detect
    3 Sector size in bytes (normally 2048)

Returns: zero if successful, -1 if failure

Powered by RoxenDreamcast Programming by Marcus Comstedt
Last modified: Mon Mar 12 00:10:21 MET 2001