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