The Curious Case of the Initial Program Loader
So, if you've ever looked at the leaked official Sega CD documentation, you may have come across this
and probably thought that it didn't make much sense at all. Turns out, this page is mainly just speculation on how the BIOS loads the initial program (IP). While the step to change the IP load address is actually correct, the reasoning for it isn't.
Let's take a look at the BIOS (the behavior I am about to explain applies to all BIOS revisions). First, let's take a look at how it reads the IP load parameters and uses them to load the IP on the Sub CPU side.
Code:
loadInitialProgram:
movea.l ipDstAddress(a5), a0
bsr.w copySector0
move.l a0, dataBufferAddress(a5)
movea.l bootHeaderAddress(a5), a0
movea.l SYSTEMHEADER.ipAddress(a0), a1
cmpa.l #$200, a1
bne.s loc_3C80
cmpi.l #$600, SYSTEMHEADER.ipSize(a0)
bne.s loc_3C80
bra.w loc_3C88
; ---------------------------------------------------------------------------
loc_3C80:
; Read IP from disc
; d1 is most likely $FFFF if we get here, so we read 32 sectors (64 KiB)
bsr.w readSectorsFromDisc
; Jump back if error
bcs.w loc_3A84
Code:
; Copy bytes $200-$7FF (relative to bootHeaderAddress)
copySector0:
movea.l bootHeaderAddress(a5), a1
adda.w #$200, a1
move.w #95, d1
@loc_3DC8:
move.l (a1)+, (a0)+
move.l (a1)+, (a0)+
move.l (a1)+, (a0)+
move.l (a1)+, (a0)+
dbf d1, @loc_3DC8
rts
; End of function copySector0
The last loading bit happens on the Main CPU side, where it transfers the data stored in Word RAM into Genesis RAM to be executed.
Code:
@loc_687A:
move.w #$1FFF, d0
lea ($FFFF0000).l, a1
lea (WordRAM_Bank0).l, a0
; Copy from WordRAM to $FF0000-$FF8000 (32 KiB)
@loc_688A:
move.l (a0)+, (a1)+
dbf d0, @loc_688A
So, in conclusion, for loading the IP, if it's less than or equal to $600 bytes, then just store it at $200 in the CD image, and set the IP load address to $200, and the IP load size to $600. If it's any larger, set the IP load address to $800, so that it will load the data after the first sector. The maximum size of the IP is 32 KiB. IP load size can be left alone.
It is also possible to split up the IP by storing the first $600 bytes in the first sector at $200, and placing the rest of the IP at the start of another sector, but quite frankly, there is absolutely no reason to do that.
Last edited: