Created
March 2, 2025 10:56
-
-
Save ketsuban/cd14f405cbf32120327571e48cf3f0c7 to your computer and use it in GitHub Desktop.
Sega Megadrive initialisation code formatted for GNU as
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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