Sega CD Development

Home Sega CD SLO 32X Transfer ConvSCD

The goal of this page is to provide the Sega development community with documentation on the Sega CD. Although there is fairly adequate documentation for the Genesis/MegaDrive there is very little available for the Sega CD/Mega CD and certainly not enough to write any software for it.

If you have any questions feel free to e-mail me at


68K Assembly
Part I: Data, Instructions, and Memory
Part II: Registers and Addressing Modes
Part III: Addition, Subtraction and Two's Complement
Part IV: Branches, Conditions and Lables
Part V: Subroutines, Exceptions and the Stack

Tools and Source

This is a little tool that will insert boot code into an ISO and build the data structure described below. It's text based and has a couple of limitations (biggest of which being that you can't use spaces. Yes I am too lazy to use cin.getline()). If someone wants to give it a pretty GUI I'd be more than happy to send them the source.

Here's the source to SLO.

The first file contains the source for the main CPU and the second is an ISO-9660 library which runs on the sub CPU. If you have trouble compiling it, feel free to e-mail me. For an explanation as to what SLO is supposed to do, go to the SLO page.

PCM Chip

Charles MacDonald managed to find the datasheet for a functionally equivalent PCM chip to the one used in the Sega CD. You can get the datasheet in PDF format here

The PCM chip is clocked at ~12.5MHz despite the fact that the datasheet lists 10MHz as the max.
The scale on the waveform graph doesn't correspond to the binary data that produces the waveform in a logical way.
Since the chip is an 8-bit device, it's mapped only to odd addresses starting at $FF0001. So you need to multiply the addresses listed in the datasheet by 2 and add $FF0001 to get the coresponding Sega CD address.

Graphics Coprocessor

I put together a little document on this chip, get it here


The BIOS expects to find one of the following 16byte identifiers at the very beginning of the CD: 'SEGADISC        ', 'SEGABOOTDISC    ', 'SEGADATADISC    ', or 'SEGADISCSYSTEM  '. The boot process is effected by which one is used, but I'm not exactly sure what the difference is at the moment. I do know that it only performs the security check if SEGABOOTDISC or SEGADISCSYSTEM are used, and it would appear that SEGADISC and SEGADATADISC are not bootable identifiers.

On the Genesis Side

By default, the data from 200h to 800h(the security code and a little more) is loaded into the beginning of Word RAM. If the longwords at offsets 30h and 34h are not 200h and 600h respectively, more sectors are copied. The longword at 30h is the start address and the longword at 34h is the length. These numbers don't have to be sector aligned but they do get truncated when they are converted to blocks. This only occurs if the data from 200h - 783h matches the copy that is in the BIOS. It should be noted that at least in the Model 1 BIOS there is a bug that causes it to always use FFFF(I think) as the length resulting in 20h sectors being copied. This is not a problem as long as your CD has at least 20h(64KB) sectors on it.

After this is done 2000h longwords(32KB) are copied from the beginning of Word RAM to the beginning of Genesis RAM. Once start is pressed, the MAIN CPU does a jump to FF0000h. The security code executes and displays the Sega logo, when it's done execution continues at FF0584h. The security code does not clear VRAM when it's done and conveniently leaves an ASCII font loaded.

On the Sega CD Side

The longword at offset 40h is the start address of the data to be copied to 6000h (just after the BIOS in Program RAM), the longword at offset 44h is the length. These numbers don't have to be sector aligned, but the least significant bits are truncated when they get converted to block numbers. After it copies the data it expects to find a header that defines entry points to the code at 6000h.

At offset 0h from the beginning of the header there is an 11 character(12 if you count the NULL character), null-terminated string. The first four characters must be 'MAIN' or the last three must be 'SYS', 'SUB', or 'DAT'. If none of these are present, the header will not be recognized. The longword at offset 10h, is the offset from the beginning of the current header to the next one. If there are no more headers, this number is 0. The longword at offset 14h is the length of the packet including the header. The longword at offset 18h contains the offset from the beginning of the header to the start of the entry point data.

The entry point is a series of word long offsets from the beginning of the offset data to the desired location in the data proper. The list is terminated with a 0. The first two entry points are called by the boot section of the BIOS. The third is called from the level 2 interrupt handler. If there isn't at least 1 entry point defined, the BIOS has a fit and starts accessing the CD like crazy. If the first entry point returns (i.e. has an rts), then there must also be a second entry point or the aforementioned behavior will occur.

For more information on the Sega CD check out Eidolon's Inn

This is a little Genesis demo I ported to Sega CD. The original was written by Charles Doty.

NOTE: This was put together before I figured out the boot structure described above.
scdtest4.iso: This is the completed CD image. It should work in emulators and in American models.
segacdb.asm: This is the modified assembly source
base.img: Binary image of the first 784h bytes of an American Sega CD game (needed to pass security test).
char.dat: Sprite data, unchanged from the original version.
misc.dat: Slightly modified data file.

Notes for those attempting to assemble this:
After running the source code through an appropriate assembler you need to append it to the file base.img. base.img contains the header and security code and the system will not boot without it.
I ran into a little assembler bug while working on this project. The assembler that the original version of this demo shipped with changed one of my eor.b #8 to an eor.b #1. I eventually just fixed this in a hex editor.

Many thanks to Eidolon, Charles Doty and all of the emu authors (especially Stef because that debugging feature in Gens was rather useful) for making this project possible.

This page Copyright 2002-2004 by Michael Pavone, most of the source for the demo is the property of Charles Doty with the modifications being my handywork. Sega, Sega Genesis, Sega CD and other trademarks are the property of their respective owners.