SameBoy/BootROMs/dmg_boot.asm

197 lines
3.5 KiB
NASM

; SameBoy DMG bootstrap ROM
include "sameboot.inc"
SECTION "BootCode", ROM0[$0000]
Start:
; Init stack pointer
ld sp, $FFFE
; Clear memory VRAM
ld hl, _VRAM
xor a
.clearVRAMLoop
ldi [hl], a
bit 5, h
jr z, .clearVRAMLoop
; Init Audio
ld a, AUDENA_ON
ldh [rNR52], a
assert AUDENA_ON == AUDLEN_DUTY_50
ldh [rNR11], a
ld a, $F3
ldh [rNR12], a ; Envelope $F, decreasing, sweep $3
ldh [rNR51], a ; Channels 1+2+3+4 left, channels 1+2 right
ld a, $77
ldh [rNR50], a ; Volume $7, left and right
; Init BG palette
ld a, %01_01_01_00
ldh [rBGP], a
; Load logo from ROM.
; A nibble represents a 4-pixels line, 2 bytes represent a 4x4 tile, scaled to 8x8.
; Tiles are ordered left to right, top to bottom.
ld de, NintendoLogo
ld hl, _VRAM + $10 ; This is where we load the tiles in VRAM
.loadLogoLoop
ld a, [de] ; Read 2 rows
ld b, a
call DoubleBitsAndWriteRow
call DoubleBitsAndWriteRow
inc de
ld a, e
xor LOW(NintendoLogoEnd)
jr nz, .loadLogoLoop
; Load trademark symbol
ld de, TrademarkSymbol
ld c, TrademarkSymbolEnd - TrademarkSymbol
.loadTrademarkSymbolLoop:
ld a, [de]
inc de
ldi [hl], a
inc hl
dec c
jr nz, .loadTrademarkSymbolLoop
; Set up tilemap
ld a, $19 ; Trademark symbol tile ID
ld [_SCRN0 + 8 * SCRN_VX_B + 16], a ; ... put in the superscript position
ld hl, _SCRN0 + 9 * SCRN_VX_B + 15 ; Bottom right corner of the logo
ld c, 12 ; Tiles in a logo row
.tilemapLoop
dec a
jr z, .tilemapDone
ldd [hl], a
dec c
jr nz, .tilemapLoop
ld l, $0F ; Jump to top row
jr .tilemapLoop
.tilemapDone
ld a, 30
ldh [rSCY], a
; Turn on LCD
ld a, LCDCF_ON | LCDCF_BLK01 | LCDCF_BGON
ldh [rLCDC], a
ld d, LOW(-119)
ld c, 15
.animate
call WaitFrame
ld a, d
sra a
sra a
ldh [rSCY], a
ld a, d
add c
ld d, a
ld a, c
cp 8
jr nz, .noPaletteChange
ld a, %10_10_10_00
ldh [rBGP], a
.noPaletteChange
dec c
jr nz, .animate
ld a, %11_11_11_00
ldh [rBGP], a
; Play first sound
ld a, $83
call PlaySound
ld b, 5
call WaitBFrames
; Play second sound
ld a, $C1
call PlaySound
; Wait ~1 second
ld b, 60
call WaitBFrames
; Set registers to match the original DMG boot
IF DEF(MGB)
lb hl, BOOTUP_A_MGB, %10110000
ELSE
lb hl, BOOTUP_A_DMG, %10110000
ENDC
push hl
pop af
ld hl, HeaderChecksum
lb bc, 0, LOW(rNR13) ; $0013
lb de, 0, $D8 ; $00D8
; Boot the game
jp BootGame
DoubleBitsAndWriteRow:
; Double the most significant 4 bits, b is shifted by 4
ld a, 4
ld c, 0
.doubleCurrentBit
sla b
push af
rl c
pop af
rl c
dec a
jr nz, .doubleCurrentBit
ld a, c
; Write as two rows
ldi [hl], a
inc hl
ldi [hl], a
inc hl
ret
WaitFrame:
push hl
ld hl, rIF
res 0, [hl]
.wait
bit 0, [hl]
jr z, .wait
pop hl
ret
WaitBFrames:
call WaitFrame
dec b
jr nz, WaitBFrames
ret
PlaySound:
ldh [rNR13], a
ld a, AUDHIGH_RESTART | $7
ldh [rNR14], a
ret
TrademarkSymbol:
pusho
opt b.X
db %..XXXX..
db %.X....X.
db %X.XXX..X
db %X.X..X.X
db %X.XXX..X
db %X.X..X.X
db %.X....X.
db %..XXXX..
popo
TrademarkSymbolEnd:
SECTION "BootGame", ROM0[$00FE]
BootGame:
ldh [rBANK], a ; unmap boot ROM