Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
GameBoy Color Boot ROM Disassembly
; GameBoy Color Boot ROM Disassembly
; Dumped by Costis
; Commenting by Randy Mongenel (Duo)
; WORK-IN-PROGRESS VERSION 09-27-2009
; ===========================================================================
; Segment type: Pure code
SECTION "ROM", CODE
; =============== S U B R O U T I N E =======================================
; Set Top-Down Stack starting position in cpu-internal HiRAM area.
sub_0000:
ld sp, $FFFE
ld a, 2 ; Set Work RAM Bank 2
jp System_Setup ; Set Work RAM Bank from A
; ---------------------------------------------------------------------------
HDMA_1: db $D3, 0,$98,$A0,$12
HDMA_2: db $D3, 0,$80, 0,$40
db $1E
db $53 ; S
db $D0 ; Ð
db 0
db $1F
db $42 ; B
db $1C
db 0
db $14
db $2A ; *
db $4D ; M
db $19
db $8C ; Œ
db $7E ; ~
db 0
db $7C ; |
db $31 ; 1
db $6E ; n
db $4A ; J
db $45 ; E
db $52 ; R
db $4A ; J
db 0
db 0
db $FF
db $53 ; S
db $1F
db $7C ; |
db $FF
db 3
db $1F
db 0
db $FF
db $1F
db $A7 ; §
db 0
db $EF ; ï
db $1B
db $1F
db 0
db $EF ; ï
db $1B
db 0
db $7C ; |
db 0
db 0
db $FF
db 3
Nintendo_Logo: db $CE,$ED,$66,$66,$CC, $D, 0, $B, 3,$73, 0,$83, 0
db $C, 0, $D, 0, 8,$11,$1F,$88,$89, 0, $E,$DC,$CC
db $6E,$E6,$DD,$DD,$D9,$99,$BB,$BB,$67,$63,$6E, $E,$EC
db $CC,$DD,$DC,$99,$9F,$BB,$B9,$33,$3E
R_Tile: db $3C,$42,$B9,$A5,$B9,$A5,$42,$3C ; (R) tile, compressed to 8 bytes
db $58 ; X
db $43 ; C
; ---------------------------------------------------------------------------
System_Setup: ; CODE XREF: sub_0000+5j
ld [Reg_SVBK], a ; Set Work RAM Bank from A
ld a, $FC ; 'ü' ; Set DMG Mode BG Palette to BLACK BLACK BLACK WHITE
ld [Reg_BGP], a ; |
call Setup_Sound
call Clear_8KB_at_8000_Aligned ; Falls through to Clear function below
ld h, $D0 ; 'Ð'
call Clear_8KB_at_HL_Aligned ; Fill 8KB at HL with zeroes (7-byte TINY version)
;
; Input:
; HL = Pointer to start of area to clear
;
; Note: HL must be aligned to xx000000, due to 8KB Counter check method (bit 5,h = done?)
ld hl, $FE00 ; Clear A0 bytes of OAM at FE00 (all of it)
ld c, $A0 ; ' ' ; |
xor a
loc_0093: ; CODE XREF: sub_0000+95j
ldi [hl], a ; |
dec c ; |
jr nz, loc_0093 ; |
Load_Logo_into_RAM_VRAM: ; Cartridge ROM Location of Nintendo Logo bytes
ld de, $104
ld hl, $8010
ld c, h
loc_009E: ; CODE XREF: sub_0000+ABj
ld a, [de] ; get header logo byte
ld [c], a ; copy it to FF80+
inc c
call Scale_Graphic_Byte_2X_Nibble1 ; 2x scales nintendo logo graphic data for display on LCD
call Scale_Graphic_Byte_2X_Nibble2 ; must be called after 1 to work right
inc de
ld a, e
cp $34 ; '4'
jr nz, loc_009E ; get header logo byte
Copy_R_Tile_To_VRAM: ; address of R tile ($0072)
ld de, $72 ; 'r'
ld b, 8 ; size of R tile (8 bytes 2x vertical compressed tile)
_copy_r_tile_loop: ; CODE XREF: sub_0000+B7j
ld a, [de] ; get tile byte
inc de ; increment pointer
ldi [hl], a ; store tile byte at (HL)
inc hl ; skip compressed byte by incrementing destination pointer again (after the previous LDI)
dec b ; decrement length counter
jr nz, _copy_r_tile_loop ; get tile byte
call Load_GameBoy_Check_Header
ld a, 1
ld [Reg_VBK], a ; VRAM Bank 1
ld a, $91 ; '‘'
ld [Reg_LCDC], a ; $91 = LCD ON | Window OFF | Char 8000 | BG 9800 | BG ON | OBJ OFF
ld hl, $98B2
ld b, $4E ; 'N'
ld c, $44 ; 'D'
call sub_0291 ; Input:
; HL = VRAM Map Address
; B = ?
; C = ?
xor a
ld [Reg_VBK], a
ld c, $80 ; '€'
ld hl, $42 ; 'B'
ld b, $18
loc_00D8: ; CODE XREF: sub_0000+DFj
ld a, [c]
inc c
cp [hl]
loc_00DB: ; CODE XREF: sub_0000:loc_00DBj
jr nz, @
inc hl
dec b
jr nz, loc_00D8
ld hl, $134 ; Cartridge ROM Header Game Title
ld b, $19 ; Add up Game Title data for checksum check
ld a, b ; from 0134 to 014C (title, manufacturer, cart type, version codes)
loc_00E7: ; CODE XREF: sub_0000+EAj
add a, [hl]
inc l
dec b
jr nz, loc_00E7
add a, [hl] ; Add Complement Checksum at 014D to summed header data. If result = 0, then header is valid
FAIL_LOOP: ; CODE XREF: sub_0000:FAIL_LOOPj
jr nz, @ ; if Complement Checksum != 0, then check failed. Stop execution by jumping to self.
call Load_VRAM_and_Palettes ; If checksum = 0 then success, setup graphics and Palettes and Commit System type and boot cartridge
jr Commit_System_and_Boot_Cart
; ---------------------------------------------------------------------------
db 0
db 0
; ---------------------------------------------------------------------------
Commit_System_and_Boot_Cart: ; CODE XREF: sub_0000+F2j
call Set_System_Mode
xor a ; Set work ram bank to 0 (0/1 are both bank 1)
ld [Reg_SVBK], a ; |
ld a, $11
ld [Reg_BLCK], a ; Disable boot ROM
; End of function sub_0000
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
loc_0137: ; DATA XREF: Load_GameBoy_Check_Header:loc_04BBr
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
loc_0143: ; DATA XREF: Set_System_Mode+3r
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
; =============== S U B R O U T I N E =======================================
; Falls through to Clear function below
Clear_8KB_at_8000_Aligned: ; CODE XREF: sub_0000+85p
; Load_GameBoy_Check_Header+4p
ld hl, $8000
; End of function Clear_8KB_at_8000_Aligned
; =============== S U B R O U T I N E =======================================
; Fill 8KB at HL with zeroes (7-byte TINY version)
;
; Input:
; HL = Pointer to start of area to clear
;
; Note: HL must be aligned to xx000000, due to 8KB Counter check method (bit 5,h = done?)
Clear_8KB_at_HL_Aligned: ; CODE XREF: sub_0000+8Ap
xor a
_clear_8kb_loop: ; CODE XREF: Clear_8KB_at_HL_Aligned+4j
ldi [hl], a ; if HL < $2000, loop back
bit 5, h
jr z, _clear_8kb_loop ; if HL < $2000, loop back
ret
; End of function Clear_8KB_at_HL_Aligned
; =============== S U B R O U T I N E =======================================
; Copy bytes from Pointer in HL to Pointer in DE
;
; Input:
; HL = Source Address
; DE = Destination Address
; C = copy length
;
; Output:
; HL = HL + C
; DE = DE + C
; C = 0
Copy_C_bytes_from_HL_to_DE: ; CODE XREF: Copy_C_bytes_from_HL_to_DE+4j
; Load_HDMA_HL+5p ...
ldi a, [hl]
ld [de], a
inc de
dec c
jr nz, Copy_C_bytes_from_HL_to_DE ; |
ret
; End of function Copy_C_bytes_from_HL_to_DE
; =============== S U B R O U T I N E =======================================
; Wait until LCD VBlank Interrupt is flagged.
;
; Input: None.
; Output: None.
Wait_for_next_VBLANK: ; CODE XREF: sub_0291p sub_0291+2Bp ...
push hl
ld hl, $FF0F
res 0, [hl]
_wait_vblank_loop: ; CODE XREF: Wait_for_next_VBLANK+8j
bit 0, [hl] ; wait until hardware goes into vblank mode and sets the vblank flag (bit 0 of FF0F)
jr z, _wait_vblank_loop ; wait until hardware goes into vblank mode and sets the vblank flag (bit 0 of FF0F)
pop hl
ret
; End of function Wait_for_next_VBLANK
; =============== S U B R O U T I N E =======================================
; Input:
; D003 = Last Keypad state
;
; Output:
; Bit Format: D, U, L, R, ST, SEL, B, A
; D003 = New Keypad state
; D004 = Keys changed since last read?
Read_Keypad: ; CODE XREF: DMG_Manual_Color_Selectp
ld de, $FF00 ; Pad register
ld hl, $D003 ; D003 = Copy of keys last/currently pressed
ld c, $F ; button mask
ld a, $30 ; '0' ; Reset Keypad
ld [de], a ; |
ld a, $20 ; ' ' ; Enable D-PAD bits
ld [de], a ; |
ld a, [de] ; Get pad bits
cpl ; Invert Pad bits
and c ; mask off upper control bits, leaving only lower pad bits
swap a ; swap d-pad bits to upper 4 bits
ld b, a ; store d-pad bits in B
ld a, $10 ; Enable Button (A,B,Select,Start) bits
ld [de], a ; |
ld a, [de] ; Get button bits
cpl ; invert button bits
and c ; mask off control bits, leaving only button bits
or b ; merge button bits with d-pad bits
ld c, a ; store complete button reading in C
ld a, [hl] ; get data from D003
xor c ; XOR with last keypad reading. Changed bits since last reading will be 1 in A.
and $F0 ; 'ð' ; Isolate D-Pad bits, clear button bits
ld b, a ; save dpad bits in B
ldi a, [hl] ; get last keypad reading again and increment pointer to D004
xor c ; XOR current keypad reading with last keypad reading. Changed bits are 1 in A
and c ; AND changed bits with current keypad data to get bits which have turned ON since last reading
or b ; combine with saved Dpad reading.
; At this point, we have the ability to HOLD the d-pad while changing A or B buttons to change the palette
ldd [hl], a
ld b, a
ld a, c
ld [hl], a
ld a, $30 ; '0'
ld [de], a
ret
; End of function Read_Keypad
; =============== S U B R O U T I N E =======================================
; Input:
; HL = Pointer to OBJ Palette Data
; B = Size in bytes of OBJ Palette Data to load
; D = 256-byte offset from end of OBJ palette to start of BG Palette
; E = Size in bytes of BG Palette Data to load
Load_BG_OBJ_Palettes: ; CODE XREF: Setup_Color_Palettes_1+Cp
; Set_System_Mode+22p
ld a, $80 ; '€'
ld [Reg_BCPS], a ; BG Palette Selection
ld [Reg_OCPS], a ; setup BG and OBJ color palette registers to accept entries in sequence
ld c, $6B ; 'k' ; $6B is register for OBJ Palette Data
loc_0252: ; CODE XREF: Load_BG_OBJ_Palettes+Bj
ldi a, [hl] ; Load next palette data byte from HL into C, increment HL pointer
ld [c], a
dec b ; B palette bytes to load into OBJ palette registers
jr nz, loc_0252 ; Load next palette data byte from HL into C, increment HL pointer
ld c, d
add hl, bc ; Next Palette is D+1 bytes from previous
ld b, e
ld c, $69 ; 'i'
loc_025C: ; CODE XREF: Load_BG_OBJ_Palettes+15j
ldi a, [hl]
ld [c], a
dec b ; B palette bytes to load into BG Palette registers
jr nz, loc_025C
ret
; End of function Load_BG_OBJ_Palettes
; =============== S U B R O U T I N E =======================================
Setup_Color_Palettes_1: ; CODE XREF: sub_0291+3p
; Load_VRAM_and_Palettes+8p ...
push bc
push de
push hl ; save registers
ld hl, $D800 ; RAM location of palettes to use
ld b, 1 ; Length of OBJ palette to load
ld d, $3F ; '?' ; Offset to BG palette start
ld e, $40 ; '@' ; Length of BG Palette
call Load_BG_OBJ_Palettes ; Input:
; HL = Pointer to OBJ Palette Data
; B = Size in bytes of OBJ Palette Data to load
; D = 256-byte offset from end of OBJ palette to start of BG Palette
; E = Size in bytes of BG Palette Data to load
pop hl ; restore saved registers
pop de
pop bc
ret
; End of function Setup_Color_Palettes_1
; =============== S U B R O U T I N E =======================================
Setup_Sound: ; CODE XREF: sub_0000+82p
ld a, $80 ; '€'
ld [unk_FF26], a ; Enable sound system, all channels OFF
ld [unk_FF11], a ; Sound wave duty 50%
ld a, $F3 ; 'ó'
ld [unk_FF12], a ; Init Envelope
ld [unk_FF25], a ; Set enabled soudn channels
ld a, $77 ; 'w'
ld [unk_FF24], a ; Set full volume
ld hl, $FF30 ; Setup 00 FF repeating waveform in wave RAM
xor a
ld c, $10
_loop_clear_wave_data: ; CODE XREF: Setup_Sound+19j
ldi [hl], a
cpl
dec c
jr nz, _loop_clear_wave_data
ret
; End of function Setup_Sound
; =============== S U B R O U T I N E =======================================
; Input:
; HL = VRAM Map Address
; B = ?
; C = ?
sub_0291: ; CODE XREF: sub_0000+CBp sub_0291+83j ...
call Wait_for_next_VBLANK ; |
call Setup_Color_Palettes_1
ld a, c
cp $38 ; '8'
jr nz, loc_02B0
push hl
xor a
ld [Reg_VBK], a
ld hl, $99A7
ld a, $38 ; '8'
loc_02A5: ; CODE XREF: sub_0291+18j
ldi [hl], a
inc a
cp $3F ; '?'
jr nz, loc_02A5
ld a, 1
ld [Reg_VBK], a
pop hl
loc_02B0: ; CODE XREF: sub_0291+9j
push bc
push hl
ld hl, $143 ; GBC flag bit check
bit 7, [hl]
call z, DMG_Manual_Color_Select ; if Cartridge Header CGB flag is NOT present, call 0589
pop hl
pop bc
call Wait_for_next_VBLANK ; |
ld a, c
sub $30 ; '0'
jp nc, loc_0306
ld a, c
cp 1
jp z, loc_0306
ld a, l
cp $D1 ; 'Ñ'
jr z, loc_02F1
push bc
ld b, 3
loc_02D3: ; CODE XREF: sub_0291+59j
ld c, 1
loc_02D5: ; CODE XREF: sub_0291+52j
ld d, 3
loc_02D7: ; CODE XREF: sub_0291+4Cj
ld a, [hl]
and $F8 ; 'ø'
or c
ldi [hl], a ; write palette data to screen for color sweep
dec d
jr nz, loc_02D7
inc c
ld a, c
cp 6
jr nz, loc_02D5
ld de, $11
add hl, de
dec b
jr nz, loc_02D3
ld de, $FFA1
add hl, de
pop bc
loc_02F1: ; CODE XREF: sub_0291+3Dj
inc b
ld a, b
ld e, $83 ; 'ƒ'
cp $62 ; 'b'
jr z, loc_02FF
ld e, $C1 ; 'Á'
cp $64 ; 'd'
jr nz, loc_0306
loc_02FF: ; CODE XREF: sub_0291+66j
ld a, e
ld [unk_FF13], a
ld a, $87 ; '‡'
ld [unk_FF14], a
loc_0306: ; CODE XREF: sub_0291+31j sub_0291+37j ...
ld a, [byte_C000+$1002]
cp 0
jr z, loc_0317
dec a
ld [byte_C000+$1002], a
ld a, c
cp 1
jp z, sub_0291 ; Input:
; HL = VRAM Map Address
; B = ?
; C = ?
loc_0317: ; CODE XREF: sub_0291+7Aj
dec c
jp nz, sub_0291 ; Input:
; HL = VRAM Map Address
; B = ?
; C = ?
ret
; End of function sub_0291
; =============== S U B R O U T I N E =======================================
Load_VRAM_and_Palettes: ; CODE XREF: sub_0000+EFp
ld c, $26 ; '&'
loc_031E: ; CODE XREF: Load_VRAM_and_Palettes+Cj
call Strange_D840_Counter
call Wait_for_next_VBLANK ; Wait until LCD VBlank Interrupt is flagged.
;
; Input: None.
; Output: None.
call Setup_Color_Palettes_1
dec c
jr nz, loc_031E
call Wait_for_next_VBLANK ; Wait until LCD VBlank Interrupt is flagged.
;
; Input: None.
; Output: None.
ld a, 1
ld [Reg_VBK], a ; VRAM Bank 1
call Load_HDMA_0008 ; Copy 288 Map bytes from D300 to 98A0 (char map)
call Load_HDMA_HL ; Copy 64 CHARs from D300 to 8000
xor a
ld [Reg_VBK], a ; VRAM Bank 0
call Load_HDMA_0008
ret
; End of function Load_VRAM_and_Palettes
; =============== S U B R O U T I N E =======================================
Load_HDMA_0008: ; CODE XREF: Load_VRAM_and_Palettes+15p
; Load_VRAM_and_Palettes+1Ep
ld hl, 8
; End of function Load_HDMA_0008
; =============== S U B R O U T I N E =======================================
Load_HDMA_HL: ; CODE XREF: Load_VRAM_and_Palettes+18p
ld de, $FF51
ld c, 5 ; Copies 5 bytes of HDMA control data from HL into HDMA registers
call Copy_C_bytes_from_HL_to_DE ; Copy bytes from Pointer in HL to Pointer in DE
;
; Input:
; HL = Source Address
; DE = Destination Address
; C = copy length
;
; Output:
; HL = HL + C
; DE = DE + C
; C = 0
ret
; End of function Load_HDMA_HL
; =============== S U B R O U T I N E =======================================
Strange_D840_Counter: ; CODE XREF: Load_VRAM_and_Palettes:loc_031Ep
push bc
push de ; save BC, DE, HL registers
push hl
ld hl, $D840 ; RAM structure ??
ld c, $20 ; ' '
loc_0352: ; CODE XREF: Strange_D840_Counter+3Fj
ld a, [hl] ; get data from RAM
and $1F ; clear upper 3 bits
cp $1F ; if lower 5 bits are all 1, then skip
jr z, loc_035A ; |
inc a ; else inc A
loc_035A: ; CODE XREF: Strange_D840_Counter+Dj
ld d, a
ldi a, [hl] ; get next RAM byte
rlca
rlca
rlca ; rotate left 3 bits
and 7
ld b, a
ldd a, [hl]
rlca
rlca
rlca
and $18
or b
cp $1F
jr z, loc_036E
inc a
loc_036E: ; CODE XREF: Strange_D840_Counter+21j
rrca
rrca
rrca
ld b, a
and $E0 ; 'à'
or d
ldi [hl], a
ld a, b
and 3
ld e, a
ld a, [hl]
rrca
rrca
and $1F
cp $1F
jr z, loc_0384
inc a
loc_0384: ; CODE XREF: Strange_D840_Counter+37j
rlca
rlca
or e
ldi [hl], a
dec c ; loop $20 times
jr nz, loc_0352 ; get data from RAM
pop hl
pop de
pop bc
ret
; End of function Strange_D840_Counter
; =============== S U B R O U T I N E =======================================
Copy_Cart_Logo_Data_Add_Checksum: ; CODE XREF: Load_GameBoy_Check_Header+1Bp
; Load_GameBoy_Check_Header+22p
ld c, 0
loc_0391: ; CODE XREF: Copy_Cart_Logo_Data_Add_Checksum+34j
ld a, [de]
and $F0 ; 'ð'
bit 1, c
jr z, loc_039A
swap a
loc_039A: ; CODE XREF: Copy_Cart_Logo_Data_Add_Checksum+7j
ld b, a
inc hl
ld a, [hl]
or b
ldi [hl], a
ld a, [de]
and $F
bit 1, c
jr nz, loc_03A8
swap a
loc_03A8: ; CODE XREF: Copy_Cart_Logo_Data_Add_Checksum+15j
ld b, a
inc hl
ld a, [hl]
or b
ldi [hl], a
inc de
bit 0, c
jr z, loc_03BF
push de
ld de, $FFF8
bit 1, c
jr z, loc_03BD
ld de, 8
loc_03BD: ; CODE XREF: Copy_Cart_Logo_Data_Add_Checksum+29j
add hl, de
pop de
loc_03BF: ; CODE XREF: Copy_Cart_Logo_Data_Add_Checksum+21j
inc c
ld a, c
cp $18
jr nz, loc_0391
ret
; End of function Copy_Cart_Logo_Data_Add_Checksum
; =============== S U B R O U T I N E =======================================
Scale_Graphic_Byte_2X_Nibble1: ; CODE XREF: sub_0000+A1p
ld b, a ; save logo byte to B
; End of function Scale_Graphic_Byte_2X_Nibble1
; =============== S U B R O U T I N E =======================================
Scale_Graphic_Byte_2X_Nibble2: ; CODE XREF: sub_0000+A4p
push de ; save header logo pointer
ld d, 4 ; D = bit counter to scale
loc_03CA: ; CODE XREF: Scale_Graphic_Byte_2X_Nibble2+Bj
ld e, b ; DE = 40,logo_byte
rl b ; scale Nintendo logo horizontally 2x
rla ; |
rl e ; |
rla ; |
dec d ; |
jr nz, loc_03CA ; |
pop de ; restore logo pointer
ldi [hl], a ; scale nintendo logo vertically 2x by storing the byte 2x at HL (tile memory)
inc hl ; |
ldi [hl], a ; |
inc hl ; |
ret
; End of function Scale_Graphic_Byte_2X_Nibble2
; =============== S U B R O U T I N E =======================================
; Draws the basic map for the Nintendo(r) logo in DMG style centered.
Copy_Nintendo_Logo_Map: ; CODE XREF: Set_System_Mode+30p
ld a, $19
ld [byte_9800+$110], a ; BG MAP ? Bottom of Y graphic gets (R) character from cart logo
ld hl, $992F
loc_03E2: ; CODE XREF: Copy_Nintendo_Logo_Map+13j
ld c, $C
loc_03E4: ; CODE XREF: Copy_Nintendo_Logo_Map+Fj
dec a
jr z, locret_03EF
ldd [hl], a
dec c
jr nz, loc_03E4
ld l, $F
jr loc_03E2
; ---------------------------------------------------------------------------
locret_03EF: ; CODE XREF: Copy_Nintendo_Logo_Map+Bj
ret
; End of function Copy_Nintendo_Logo_Map
; =============== S U B R O U T I N E =======================================
Load_GameBoy_Check_Header: ; CODE XREF: sub_0000+B9p
ld a, 1
ld [Reg_VBK], a ; Set Video Bank 1
call Clear_8KB_at_8000_Aligned ; Falls through to Clear function below
ld de, $607
ld hl, $8080
ld c, $C0 ; 'À'
loc_03FF: ; CODE XREF: Load_GameBoy_Check_Header+16j
ld a, [de] ; decompress vertically squashed GameBoy logo data
ldi [hl], a
inc hl
ldi [hl], a
inc hl
inc de
dec c
jr nz, loc_03FF ; decompress vertically squashed GameBoy logo data
ld de, $104 ; address of Cartridge Logo data
call Copy_Cart_Logo_Data_Add_Checksum
ld bc, $FFA8 ; subtract 88 from HL
add hl, bc
call Copy_Cart_Logo_Data_Add_Checksum
ld bc, $FFF8
add hl, bc ; Subtract 8 from HL
ld de, $72 ; 'r' ; data at $0072 8-byte vertically compressed (R) tile
ld c, 8
_copy_r_tile_loop2: ; CODE XREF: Load_GameBoy_Check_Header+33j
inc hl
ld a, [de] ; copy (R) tile from 0072 to vram
ldi [hl], a
inc de
dec c
jr nz, _copy_r_tile_loop2
@@loc_setup_attributes: ; Map 0 location of top left corner of "GAMEBOY" Graphic
ld hl, $98C2
ld b, 8
ld a, 8
loc_042C: ; CODE XREF: Load_GameBoy_Check_Header+47j
ld c, $10 ; map data line length
loc_042E: ; CODE XREF: Load_GameBoy_Check_Header+40j
ldi [hl], a ; fill map attribute bytes with $8
dec c
jr nz, loc_042E ; fill map attribute bytes with $8
ld de, $10 ; next map row
add hl, de ; |
dec b
jr nz, loc_042C ; fill 8 lines worth
Draw_GAMEBOY_Logo_Map:
xor a
ld [Reg_VBK], a ; VRAM Bank 0
ld hl, $98C2 ; Map 0 location of top left corner of "GAMEBOY" Graphic
ld a, 8
loc_0441: ; CODE XREF: Load_GameBoy_Check_Header+62j
ldi [hl], a ; Fill Map rectangle from 2,6 to 11,8 with 08-37 (map data for GAMEBOY logo)
inc a ; |
cp $18
jr nz, loc_0449
ld l, $E2 ; 'â'
loc_0449: ; CODE XREF: Load_GameBoy_Check_Header+55j
cp $28 ; '('
jr nz, loc_0450
ld hl, $9902
loc_0450: ; CODE XREF: Load_GameBoy_Check_Header+5Bj
cp $38 ; '8'
jr nz, loc_0441 ; Done with logo fill
Addr_0454: ; Create structures with data at 08D8
ld hl, $8D8 ; FF, FF, xx, xx, 00, 00, XX, XX
; FF, FF, xx, xx, 00, 00, XX, XX
; FF, FF, xx, xx, 00, 00, XX, XX
; FF, FF, xx, xx, 00, 00, XX, XX
; FF, FF, xx, xx, 00, 00, XX, XX
; FF, FF, xx, xx, 00, 00, XX, XX
; FF, FF, xx, xx, 00, 00, XX, XX
; FF, FF, xx, xx, 00, 00, XX, XX
;
ld de, $D840
ld b, 8
loc_045C: ; CODE XREF: Load_GameBoy_Check_Header+80j
ld a, $FF
ld [de], a
inc de
ld [de], a
inc de
ld c, 2
call Copy_C_bytes_from_HL_to_DE ; |
ld a, 0
ld [de], a
inc de
ld [de], a
inc de
inc de
inc de
dec b
jr nz, loc_045C
call Setup_Color_Palettes_1
ld hl, $14B ; Cartridge Header Data Magic Number static $33
ld a, [hl]
cp $33 ; '3'
jr nz, loc_0488
ld l, $44 ; 'D'
ld e, $30 ; '0'
ldi a, [hl]
cp e
jr nz, loc_04CE
inc e
jr loc_048C
; ---------------------------------------------------------------------------
loc_0488: ; CODE XREF: Load_GameBoy_Check_Header+8Bj
ld l, $4B ; 'K'
ld e, 1
loc_048C: ; CODE XREF: Load_GameBoy_Check_Header+96j
ldi a, [hl]
cp e
jr nz, loc_04CE
ld l, $34 ; '4'
ld bc, $10
loc_0495: ; CODE XREF: Load_GameBoy_Check_Header+A9j
ldi a, [hl]
add a, b
ld b, a
dec c
jr nz, loc_0495
ld [byte_C000+$1000], a
ld hl, $6C7
ld c, 0
loc_04A3: ; CODE XREF: Load_GameBoy_Check_Header+BBj
ldi a, [hl]
cp b
jr z, loc_04AF
inc c
ld a, c
cp $4F ; 'O'
jr nz, loc_04A3
jr loc_04CE
; ---------------------------------------------------------------------------
loc_04AF: ; CODE XREF: Load_GameBoy_Check_Header+B5j
ld a, c
sub $41 ; 'A'
jr c, loc_04D0
ld hl, $716
ld d, 0
ld e, a
add hl, de
loc_04BB: ; CODE XREF: Load_GameBoy_Check_Header+DCj
ld a, [loc_0137]
ld d, a
ld a, [hl]
cp d
jr z, loc_04D0
ld de, $E
add hl, de
ld a, c
add a, e
ld c, a
sub $5E ; '^'
jr c, loc_04BB
loc_04CE: ; CODE XREF: Load_GameBoy_Check_Header+93j
; Load_GameBoy_Check_Header+9Ej ...
ld c, 0
loc_04D0: ; CODE XREF: Load_GameBoy_Check_Header+C2j
; Load_GameBoy_Check_Header+D1j
ld hl, $733
ld b, 0
add hl, bc
ld a, [hl]
and $1F
ld [byte_C000+$1008], a
ld a, [hl]
and $E0 ; 'à'
rlca
rlca
rlca
ld [byte_C000+$100B], a
call sub_04E9
ret
; End of function Load_GameBoy_Check_Header
; =============== S U B R O U T I N E =======================================
sub_04E9: ; CODE XREF: Load_GameBoy_Check_Header+F5p
; DMG_Manual_Color_Select+40p
ld de, $791
ld hl, $D900
ld a, [byte_C000+$100B]
ld b, a
ld c, $1E
loc_04F5: ; CODE XREF: sub_04E9+33j
bit 0, b
jr nz, loc_04FB
inc de
inc de
loc_04FB: ; CODE XREF: sub_04E9+Ej
ld a, [de]
ldi [hl], a
jr nz, loc_0501
dec de
dec de
loc_0501: ; CODE XREF: sub_04E9+14j
bit 1, b
jr nz, loc_0507
inc de
inc de
loc_0507: ; CODE XREF: sub_04E9+1Aj
ld a, [de]
ldi [hl], a
inc de
inc de
jr nz, loc_050F
dec de
dec de
loc_050F: ; CODE XREF: sub_04E9+22j
bit 2, b
jr z, loc_0518
dec de
dec hl
ld a, [de]
ldi [hl], a
inc de
loc_0518: ; CODE XREF: sub_04E9+28j
ld a, [de]
ldi [hl], a
inc de
dec c
jr nz, loc_04F5
ld hl, $D900
ld de, $DA00
call Dictionary_Decompress_HL_to_DE ; This routine uses an index list ($60 long) at HL with a dictionary of 8-byte-long words at $07E8,
; and copies the words in index sequence to DE.
; Index is a byte offset, not a word offset, eg: index $80 is at $07E8+$80, not $80 * 8 byte word size.
ret
; End of function sub_04E9
; =============== S U B R O U T I N E =======================================
sub_0528: ; CODE XREF: DMG_Manual_Color_Select+43p
ld hl, $12
ld a, [byte_C000+$1005]
rlca
rlca
ld b, 0
ld c, a
add hl, bc
ld de, $D840
ld b, 8
loc_0539: ; CODE XREF: sub_0528+1Fj
push hl
ld c, 2
call Copy_C_bytes_from_HL_to_DE ; Copy bytes from Pointer in HL to Pointer in DE
;
; Input:
; HL = Source Address
; DE = Destination Address
; C = copy length
;
; Output:
; HL = HL + C
; DE = DE + C
; C = 0
inc de
inc de
inc de
inc de
inc de
inc de
pop hl
dec b
jr nz, loc_0539
ld de, $D842
ld c, 2
call Copy_C_bytes_from_HL_to_DE ; Copy bytes from Pointer in HL to Pointer in DE
;
; Input:
; HL = Source Address
; DE = Destination Address
; C = copy length
;
; Output:
; HL = HL + C
; DE = DE + C
; C = 0
ld de, $D84A
ld c, 2
call Copy_C_bytes_from_HL_to_DE ; Copy bytes from Pointer in HL to Pointer in DE
;
; Input:
; HL = Source Address
; DE = Destination Address
; C = copy length
;
; Output:
; HL = HL + C
; DE = DE + C
; C = 0
dec hl
dec hl
ld de, $D844
ld c, 2
call Copy_C_bytes_from_HL_to_DE ; Copy bytes from Pointer in HL to Pointer in DE
;
; Input:
; HL = Source Address
; DE = Destination Address
; C = copy length
;
; Output:
; HL = HL + C
; DE = DE + C
; C = 0
ret
; End of function sub_0528
; =============== S U B R O U T I N E =======================================
; This routine uses an index list ($60 long) at HL with a dictionary of 8-byte-long words at $07E8,
; and copies the words in index sequence to DE.
; Index is a byte offset, not a word offset, eg: index $80 is at $07E8+$80, not $80 * 8 byte word size.
Dictionary_Decompress_HL_to_DE: ; CODE XREF: sub_04E9+3Bp
ld c, $60 ; '`'
loc_0566: ; CODE XREF: Dictionary_Decompress_HL_to_DE+14j
ldi a, [hl]
push hl
push bc
ld hl, $7E8 ; Large table
ld b, 0
ld c, a
add hl, bc
ld c, 8
call Copy_C_bytes_from_HL_to_DE ; Copy bytes from Pointer in HL to Pointer in DE
;
; Input:
; HL = Source Address
; DE = Destination Address
; C = copy length
;
; Output:
; HL = HL + C
; DE = DE + C
; C = 0
pop bc
pop hl
dec c
jr nz, loc_0566
ret
; End of function Dictionary_Decompress_HL_to_DE
; =============== S U B R O U T I N E =======================================
HL_plus_D008_times_24: ; CODE XREF: Set_System_Mode+19p
ld a, [byte_C000+$1008]
ld de, $18 ; HL = HL + 24*[D008]
inc a
loc_0582: ; CODE XREF: HL_plus_D008_times_24+Bj
dec a
jr z, locret_0588
add hl, de
jr nz, loc_0582
locret_0588: ; CODE XREF: HL_plus_D008_times_24+8j
ret
; End of function HL_plus_D008_times_24
; =============== S U B R O U T I N E =======================================
DMG_Manual_Color_Select: ; CODE XREF: sub_0291+26p
call Read_Keypad ; |
ld a, b ; Keypad data is left in B
and $FF
jr z, loc_05A0 ; If no buttons pressed, then skip to return
ld hl, $8E4 ; Address of Color_Palette_KeyPad
ld b, 0
loc_0596: ; CODE XREF: DMG_Manual_Color_Select+15j
ldi a, [hl]
cp c
jr z, loc_05A2
inc b
ld a, b
cp $C
jr nz, loc_0596
loc_05A0: ; CODE XREF: DMG_Manual_Color_Select+6j
jr locret_05CF
; ---------------------------------------------------------------------------
loc_05A2: ; CODE XREF: DMG_Manual_Color_Select+Fj
ld a, b
ld [byte_C000+$1005], a
ld a, $1E
ld [byte_C000+$1002], a
ld de, $B
add hl, de
ld d, [hl]
ld a, d
and $1F
ld e, a
ld hl, $D008
ldd a, [hl]
ldi [hl], a
ld a, e
ld [hl], a
ld a, d
and $E0 ; 'à'
rlca
rlca
rlca
ld e, a
ld hl, $D00B
ldd a, [hl]
ldi [hl], a
ld a, e
ld [hl], a
call sub_04E9
call sub_0528
locret_05CF: ; CODE XREF: DMG_Manual_Color_Select:loc_05A0j
ret
; End of function DMG_Manual_Color_Select
; =============== S U B R O U T I N E =======================================
Set_System_Mode: ; CODE XREF: sub_0000:Commit_System_and_Boot_Cartp
call Wait_for_next_VBLANK ; Wait until LCD VBlank Interrupt is flagged.
;
; Input: None.
; Output: None.
ld a, [loc_0143] ; Cartridge ROM Compatability Flag (CGB = $80)
bit 7, a
jr z, Set_System_Mode_DMG ; If DMG, skip over FF4C part
ld [Reg_LCDMODE], a ; This unknown register is at the tail end of the LCD register space. It may possibly lockdown advanced color hardware features from being accessed by a game in DMG mode. This could be tested.
; The CGB boot ROM sets this to $80 if a CGB game is inserted, or $04 if a DMG game is inserted.
jr locret_0606
; ---------------------------------------------------------------------------
Set_System_Mode_DMG: ; CODE XREF: Set_System_Mode+8j
ld a, 4
ld [Reg_LCDMODE], a ; This unknown register is at the tail end of the LCD register space. It may possibly lockdown advanced color hardware features from being accessed by a game in DMG mode. This could be tested.
; The CGB boot ROM sets this to $80 if a CGB game is inserted, or $04 if a DMG game is inserted.
ld a, 1
ld [Reg_PAL_LOCK], a ; Unknown lockout register? Color palette lockout?
ld hl, $DA00
call HL_plus_D008_times_24
ld b, $10
ld d, 0
ld e, 8
call Load_BG_OBJ_Palettes ; Input:
; HL = Pointer to OBJ Palette Data
; B = Size in bytes of OBJ Palette Data to load
; D = 256-byte offset from end of OBJ palette to start of BG Palette
; E = Size in bytes of BG Palette Data to load
ld hl, $7A ; 'z'
ld a, [byte_C000+$1000]
ld b, a
ld c, 2
loc_05FE: ; CODE XREF: Set_System_Mode+34j
ldi a, [hl]
cp b
call z, Copy_Nintendo_Logo_Map ; Draws the basic map for the Nintendo(r) logo in DMG style centered.
dec c
jr nz, loc_05FE
locret_0606: ; CODE XREF: Set_System_Mode+Cj
ret
; End of function Set_System_Mode
; ---------------------------------------------------------------------------
GameBoy_Logo: db 1, $F,$3F,$7E,$FF,$FF,$C0, 0,$C0,$F0,$F1, 3,$7C
db $FC,$FE,$FE, 3, 7, 7, $F,$E0,$E0,$F0,$F0,$1E,$3E
db $7E,$FE, $F, $F,$1F,$1F,$FF,$FF, 0, 0, 1, 1, 1
db 3,$FF,$FF,$E1,$E0,$C0,$F0,$F9,$FB,$1F,$7F,$F8,$E0
db $F3,$FD,$3E,$1E,$E0,$F0,$F9,$7F,$3E,$7C,$F8,$E0,$F8
db $F0,$F0,$F8, 0, 0,$7F,$7F, 7, $F,$9F,$BF,$9E,$1F
db $FF,$FF, $F,$1E,$3E,$3C,$F1,$FB,$7F,$7F,$FE,$DE,$DF
db $9F,$1F,$3F,$3E,$3C,$F8,$F8, 0, 0, 3, 3, 7, 7
db $FF,$FF,$C1,$C0,$F3,$E7,$F7,$F3,$C0,$C0,$C0,$C0,$1F
db $1F,$1E,$3E,$3F,$1F,$3E,$3E,$80, 0, 0, 0,$7C,$1F
db 7, 0, $F,$FF,$FE, 0,$7C,$F8,$F0, 0,$1F, $F, $F
db 0,$7C,$F8,$F8, 0,$3F,$3E,$1C, 0, $F, $F, $F, 0
db $7C,$FF,$FF, 0, 0,$F8,$F8, 0, 7, $F, $F, 0,$81
db $FF,$FF, 0,$F3,$E1,$80, 0,$E0,$FF,$7F, 0,$FC,$F0
db $C0, 0,$3E,$7C,$7C, 0, 0, 0, 0, 0
Addr_06C7: db 0,$88,$16,$36,$D1,$DB,$F2,$3C,$8C,$92,$3D,$5C,$58
db $C9,$3E,$70,$1D,$59,$69,$19,$35,$A8,$14,$AA,$75,$95
db $99,$34,$6F,$15,$FF,$97,$4B,$90,$17,$10,$39,$F7,$F6
db $A2,$49,$4E,$43,$68,$E0,$8B,$F0,$CE, $C,$29,$E8,$B7
db $86,$9A,$52, 1,$9D,$71,$9C,$BD,$5D,$6D,$67,$3F,$6B
db $B3,$46,$28,$A5,$C6,$D3,$27,$61,$18,$66,$6A,$BF, $D
db $F4
Addr_0716: db $42,$45,$46,$41,$41,$52,$42,$45,$4B,$45,$4B,$20,$52
db $2D,$55,$52,$41,$52,$20,$49,$4E,$41,$49,$4C,$49,$43
db $45,$20,$52
Addr_0733: db $7C, 8,$12,$A3,$A2, 7,$87,$4B,$20,$12,$65,$A8,$16
db $A9,$86,$B1,$68,$A0,$87,$66,$12,$A1,$30,$3C,$12,$85
db $12,$64,$1B, 7, 6,$6F,$6E,$6E,$AE,$AF,$6F,$B2,$AF
db $B2,$A8,$AB,$6F,$AF,$86,$AE,$A2,$A2,$12,$AF,$13,$12
db $A1,$6E,$AF,$AF,$AD, 6,$4C,$6E,$AF,$AF,$12,$7C,$AC
db $A8,$6A,$6E,$13,$A0,$2D,$A8,$2B,$AC,$64,$AC,$6D,$87
db $BC,$60,$B4,$13,$72,$7C,$B5,$AE,$AE,$7C,$7C,$65,$A2
db $6C,$64,$85
Palette_Index: db $80,$B0,$40,$88,$20,$68,$DE, 0,$70,$DE,$20,$78,$20
db $20,$38,$20,$B0,$90,$20,$B0,$A0,$E0,$B0,$C0,$98,$B6
db $48,$80,$E0,$50,$1E,$1E,$58,$20,$B8,$E0,$88,$B0,$10
db $20, 0,$10,$20,$E0,$18,$E0,$18, 0,$18,$E0,$20,$A8
db $E0,$20,$18,$E0, 0,$20,$18,$D8,$C8,$18,$E0, 0,$E0
db $40,$28,$28,$28,$18,$E0,$60,$20,$18,$E0, 0, 0, 8
db $E0,$18,$30,$D0,$D0,$D0,$20,$E0,$E8
Palette_Dictionary:db $FF,$7F,$BF,$32,$D0, 0, 0, 0
db $9F,$63,$79,$42,$B0,$15,$CB, 4
db $FF,$7F,$31,$6E,$4A,$45, 0, 0
db $FF,$7F,$EF,$1B, 0, 2, 0, 0
db $FF,$7F,$1F,$42,$F2,$1C, 0, 0
db $FF,$7F,$94,$52,$4A,$29, 0, 0
db $FF,$7F,$FF, 3,$2F, 1, 0, 0
db $FF,$7F,$EF, 3,$D6, 1, 0, 0
db $FF,$7F,$B5,$42,$C8,$3D, 0, 0
db $74,$7E,$FF, 3,$80, 1, 0, 0
db $FF,$67,$AC,$77,$13,$1A,$6B,$2D
db $D6,$7E,$FF,$4B,$75,$21, 0, 0
db $FF,$53,$5F,$4A,$52,$7E, 0, 0
db $FF,$4F,$D2,$7E,$4C,$3A,$E0,$1C
db $ED, 3,$FF,$7F,$5F,$25, 0, 0
db $6A, 3,$1F, 2,$FF, 3,$FF,$7F
db $FF,$7F,$DF, 1,$12, 1, 0, 0
db $1F,$23,$5F, 3,$F2, 0, 9, 0
db $FF,$7F,$EA, 3,$1F, 1, 0, 0
db $9F,$29,$1A, 0, $C, 0, 0, 0
db $FF,$7F,$7F, 2,$1F, 0, 0, 0
db $FF,$7F,$E0, 3, 6, 2,$20, 1
db $FF,$7F,$EB,$7E,$1F, 0, 0,$7C
db $FF,$7F,$FF,$3F, 0,$7E,$1F, 0
db $FF,$7F,$FF, 3,$1F, 0, 0, 0
db $FF, 3,$1F, 0, $C, 0, 0, 0
db $FF,$7F,$3F, 3,$93, 1, 0, 0
db 0, 0, 0,$42,$7F, 3,$FF,$7F
db $FF,$7F,$8C,$7E, 0,$7C, 0, 0
db $FF,$7F,$EF,$1B,$80,$61, 0, 0
Addr_08D8: db $FF,$7F
db 0,$7C
db $E0, 3
db $1F,$7C
db $1F, 0
db $FF, 3
Color_Palette_KeyPad:db $40,$41 ; Values used when keypad is pressed to change color palettes
db $42,$20
db $21,$22
db $80,$81
db $82,$10
db $11,$12
db $12,$B0
db $79,$B8
db $AD,$16
db $17, 7
db $BA, 5
db $7C,$13
db 0
db 0
db 0
db 0
; end of 'ROM'
; ===========================================================================
; Segment type: Regular
SECTION "VRAM_CHAR", DATA
org $8000
ds $1800
; end of 'VRAM_CHAR'
; ===========================================================================
; Segment type: Regular
SECTION "VRAM_MAP", DATA
org $9800
byte_9800: ds $800
; end of 'VRAM_MAP'
; ===========================================================================
; Segment type: Regular
SECTION "EXT_RAM", DATA
org $A000
ds $2000
; end of 'EXT_RAM'
; ===========================================================================
; Segment type: Regular
SECTION "INT_RAM", DATA
org $C000
byte_C000: ds $2000
; end of 'INT_RAM'
; ===========================================================================
; Segment type: Regular
SECTION "IO_REG", DATA
org $FF00
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
unk_FF11: ds 1
unk_FF12: ds 1
unk_FF13: ds 1
unk_FF14: ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
unk_FF24: ds 1
unk_FF25: ds 1
unk_FF26: ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
Reg_LCDC: ds 1 ; DATA XREF: sub_0000+C2w
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
Reg_BGP: ds 1 ; DATA XREF: sub_0000+80w
ds 1
ds 1
ds 1
ds 1
Reg_LCDMODE: ds 1 ; This unknown register is at the tail end of the LCD register space. It may possibly lockdown advanced color hardware features from being accessed by a game in DMG mode. This could be tested.
; The CGB boot ROM sets this to $80 if a CGB game is inserted, or $04 if a DMG game is inserted.
ds 1
ds 1
Reg_VBK: ds 1 ; DATA XREF: sub_0000+BEw sub_0000+CFw ...
Reg_BLCK: ds 1 ; DATA XREF: sub_0000+FEw
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
Reg_BCPS: ds 1 ; BG Palette Selection
Reg_BCPD: ds 1 ; BG Palette Data
Reg_OCPS: ds 1 ; OBJ Palette Selection
Reg_OCPD: ds 1 ; OBJ Palette Data
Reg_PAL_LOCK: ds 1 ; Unknown lockout register? Color palette lockout?
ds 1
ds 1
ds 1
Reg_SVBK: ds 1 ; DATA XREF: sub_0000:System_Setupw
; sub_0000+FAw
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
ds 1
; end of 'IO_REG'
; ===========================================================================
; Segment type: Regular
SECTION "HiRAM", DATA
org $FF80
ds $7F
; end of 'HiRAM'
; end of file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.