Skip to content

Instantly share code, notes, and snippets.

@ketsuban
Created March 2, 2025 10:56
Show Gist options
  • Save ketsuban/cd14f405cbf32120327571e48cf3f0c7 to your computer and use it in GitHub Desktop.
Save ketsuban/cd14f405cbf32120327571e48cf3f0c7 to your computer and use it in GitHub Desktop.
Sega Megadrive initialisation code formatted for GNU as
| skip reinitialising hardware after a soft reset
tst.l (0xA10008).l
bne.s 1f
tst.w (0xA1000C).l
1: bne.s 2f
| load register values for initialisation
lea .Ltable(%pc), %a5
movem.w (%a5)+, %d5-%d7
movem.l (%a5)+, %a0-%a4
| deal with TMSS on afflicted machines
move.b -0x10FF(%a1), %d0
andi.b #0xF, %d0
beq.s 1f
move.l #0x53454741, 0x2F00(%a1)
1:
| reset VDP working state
move.w (%a4), %d0
| clear some registers
moveq #0, %d0
movea.l %d0, %a6
move %a6, %usp
| reset VDP registers
moveq #23, %d1
1: move.b (%a5)+, %d5
move.w %d5, (%a4)
add.w %d7, %d5
dbra %d1, 1b
| the previous loop set up a DMA fill operation which this now starts
move.l (%a5)+, (%a4)
move.w %d0, (%a3)
| acquire Z80 bus
move.w %d7, (%a1)
move.w %d7, (%a2)
1: btst %d0, (%a1)
bne.s 1b
| load program into Z80 memory
moveq #37, %d2
1: move.b (%a5)+, (%a0)+
dbra %d2, 1b
| release Z80 bus
move.w %d0, (%a2)
move.w %d0, (%a1)
| reset Z80
move.w %d7, (%a2)
| clear RAM
1: move.l %d0, -(%a6)
dbra %d6, 1b
| disable DMA and reset autoincrement
move.l (%a5)+, (%a4)
| clear CRAM
move.l (%a5)+, (%a4)
moveq #31, %d3
1: move.l %d0, (%a3)
dbra %d3, 1b
| clear VSRAM
move.l (%a5)+, (%a4)
moveq #19, %d4
1: move.l %d0, (%a3)
dbra %d4, 1b
| mute PSG channels
moveq #3, %d5
1: move.b (%a5)+, 0x11(%a3)
dbra %d5, 1b
| release Z80 reset line
move.w %d0, (%a2)
| clear registers
movem.l (%a6), %d0-%d7/%a0-%a6
| disable interrupts
move #0x2700, %sr
2: bra.s .Lskip
.Ltable:
.word 0x8000 | d5
.word 0x3FFF | d6
.word 0x0100 | d7
.long 0xA00000 | a0: start of Z80 memory
.long 0xA11100 | a1: Z80 bus request line
.long 0xA11200 | a2: Z80 reset line
.long 0xC00000 | a3: VDP data port
.long 0xC00004 | a4: VDP address port
| VDP register values
.byte 0x04, 0x14, 0x30, 0x3C
.byte 0x07, 0x6C, 0x00, 0x00
.byte 0x00, 0x00, 0xFF, 0x00
.byte 0x81, 0x37, 0x00, 0x01
.byte 0x01, 0x00, 0x00, 0xFF
.byte 0xFF, 0x00, 0x00, 0x80
| VDP command: DMA fill to VRAM
.long 0x40000080
| Z80 program
.byte 0xAF | xor a
.byte 0x01, 0xD9, 0x1F | ld bc, 1FD9h
.byte 0x11, 0x27, 0x00 | ld de, 0027h
.byte 0x21, 0x26, 0x00 | ld hl, 0026h
.byte 0xF9 | ld sp, hl
.byte 0x77 | ld (hl), a
.byte 0xED, 0xB0 | ldir
.byte 0xDD, 0xE1 | pop ix
.byte 0xFD, 0xE1 | pop iy
.byte 0xED, 0x47 | ld i, a
.byte 0xED, 0x4F | ld r, a
.byte 0xD1 | pop de
.byte 0xE1 | pop hl
.byte 0xF1 | pop af
.byte 0x08 | ex af, af'
.byte 0xD9 | exx
.byte 0xC1 | pop bc
.byte 0xD1 | pop de
.byte 0xE1 | pop hl
.byte 0xF1 | pop af
.byte 0xF9 | ld sp, hl
.byte 0xF3 | di
.byte 0xED, 0x56 | im1
.byte 0x36, 0xE9 | ld (hl), E9h
.byte 0xE9 | jp (hl)
| set VDP display mode and increment
.word 0x8104
.word 0x8F02
| VDP commands: CRAM write, VSRAM write
.long 0xC0000000
.long 0x40000010
| PSG volume data
.byte 0x9F, 0xBF, 0xDF, 0xFF
.Lskip:
tst.w (0xC00004).l
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment