diff --git a/BootROMs/agb_boot.asm b/BootROMs/agb_boot.asm index 02399f2a5..a4e3ee889 100644 --- a/BootROMs/agb_boot.asm +++ b/BootROMs/agb_boot.asm @@ -1,2 +1,2 @@ -DEF AGB = 1 -include "cgb_boot.asm" \ No newline at end of file +DEF AGB = 1 +include "cgb_boot.asm" diff --git a/BootROMs/cgb0_boot.asm b/BootROMs/cgb0_boot.asm index 5ed4c2e29..af9c8d5e5 100644 --- a/BootROMs/cgb0_boot.asm +++ b/BootROMs/cgb0_boot.asm @@ -1,2 +1,2 @@ -DEF CGB0 = 1 -include "cgb_boot.asm" \ No newline at end of file +DEF CGB0 = 1 +include "cgb_boot.asm" diff --git a/BootROMs/cgb_boot.asm b/BootROMs/cgb_boot.asm index 116c227a4..8fc2ca459 100644 --- a/BootROMs/cgb_boot.asm +++ b/BootROMs/cgb_boot.asm @@ -1,18 +1,18 @@ ; SameBoy CGB bootstrap ROM -INCLUDE "hardware.inc" +include "sameboot.inc" -SECTION "BootCode", ROM0[$0] +SECTION "BootCode", ROM0[$0000] Start: ; Init stack pointer - ld sp, $fffe + ld sp, $FFFE ; Clear memory VRAM - call ClearMemoryPage8000 + call ClearMemoryVRAM ; Clear OAM - ld h, $fe - ld c, $a0 + ld h, HIGH(_OAMRAM) + ld c, sizeof_OAM_ATTRS * OAM_COUNT .clearOAMLoop ldi [hl], a dec c @@ -20,8 +20,8 @@ Start: IF !DEF(CGB0) ; Init waveform - ld c, $10 - ld hl, $FF30 + ld c, 16 + ld hl, _AUD3WAVERAM .waveformLoop ldi [hl], a cpl @@ -30,22 +30,23 @@ IF !DEF(CGB0) ENDC ; Clear chosen input palette - ldh [InputPalette], a + ldh [hInputPalette], a ; Clear title checksum - ldh [TitleChecksum], a + ldh [hTitleChecksum], a ; Init Audio - ld a, $80 + ld a, AUDENA_ON ldh [rNR52], a + assert AUDENA_ON == AUDLEN_DUTY_50 ldh [rNR11], a - ld a, $f3 - ldh [rNR12], a - ldh [rNR51], 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 + ldh [rNR50], a ; Volume $7, left and right ; Init BG palette - ld a, $fc + ld a, %11_11_11_00 ldh [rBGP], a ; Load logo from ROM. @@ -53,8 +54,8 @@ ENDC ; Tiles are ordered left to right, top to bottom. ; These tiles are not used, but are required for DMG compatibility. This is done ; by the original CGB Boot ROM as well. - ld de, $104 ; Logo start - ld hl, $8010 ; This is where we load the tiles in VRAM + ld de, NintendoLogo + ld hl, _VRAM + $10 ; This is where we load the tiles in VRAM .loadLogoLoop ld a, [de] ; Read 2 rows @@ -62,14 +63,14 @@ ENDC call DoubleBitsAndWriteRowTwice inc de ld a, e - cp $34 ; End of logo + cp LOW(NintendoLogoEnd) jr nz, .loadLogoLoop call ReadTrademarkSymbol ; Clear the second VRAM bank ld a, 1 ldh [rVBK], a - call ClearMemoryPage8000 + call ClearMemoryVRAM call LoadTileset ld b, 3 @@ -78,12 +79,12 @@ IF DEF(FAST) ldh [rVBK], a ELSE ; Load Tilemap - ld hl, $98C2 + ld hl, _SCRN0 + 6 * SCRN_VX_B + 2 ld d, 3 ld a, 8 .tilemapLoop - ld c, $10 + ld c, 16 .tilemapRowLoop @@ -117,8 +118,8 @@ ELSE dec d ld a, $38 - ld l, $a7 - ld bc, $0107 + ld l, $A7 + lb bc, 1, 7 ; $0107 jr .tilemapRowLoop .write_with_palette @@ -139,7 +140,7 @@ ENDC ; Expand Palettes ld de, AnimationColors ld c, 8 - ld hl, BgPalettes + ld hl, hBgPalettes xor a .expandPalettesLoop: cpl @@ -182,14 +183,14 @@ ENDC call LoadPalettesFromHRAM ; Turn on LCD - ld a, $91 + ld a, LCDCF_ON | LCDCF_BLK01 | LCDCF_BGON ldh [rLCDC], a IF !DEF(FAST) call DoIntroAnimation ld a, 48 ; frames to wait after playing the chime - ldh [WaitLoopCounter], a + ldh [hWaitLoopCounter], a ld b, 4 ; frames to wait before playing the chime call WaitBFrames @@ -199,17 +200,17 @@ IF !DEF(FAST) ld b, 5 call WaitBFrames ; Play second sound - ld a, $c1 + ld a, $C1 call PlaySound .waitLoop call GetInputPaletteIndex call WaitFrame - ld hl, WaitLoopCounter + ld hl, hWaitLoopCounter dec [hl] jr nz, .waitLoop ELSE - ld a, $c1 + ld a, $C1 call PlaySound ENDC call Preboot @@ -219,14 +220,19 @@ ENDC jr BootGame HDMAData: - db $D0, $00, $98, $A0, $12 - db $D0, $00, $80, $00, $40 +MACRO hdma_data ; source, destination, length + db HIGH(\1), LOW(\1) + db HIGH(\2), LOW(\2) + db (\3) +ENDM + hdma_data _RAMBANK, _SCRN0 + 5 * SCRN_VX_B + 0, 18 + hdma_data _RAMBANK, _VRAM, 64 -SECTION "BootGame", ROM0[$fe] +SECTION "BootGame", ROM0[$00FE] BootGame: ldh [rBANK], a ; unmap boot ROM -SECTION "MoreStuff", ROM0[$200] +SECTION "BootData", ROM0[$0200] ; Game Palettes Data TitleChecksums: db $00 ; Default @@ -329,103 +335,107 @@ FirstChecksumWithDuplicate: ChecksumsEnd: PalettePerChecksum: -MACRO palette_index ; palette, flags - db ((\1)) | (\2) ; | $80 means game requires DMG boot tilemap +MACRO palette_index ; palette[, flags] + IF _NARG == 1 + db (\1) + ELSE + db (\1) | (\2) ; flag $80 means game requires DMG boot tilemap + ENDC ENDM - palette_index 0, 0 ; Default Palette - palette_index 4, 0 ; ALLEY WAY - palette_index 5, 0 ; YAKUMAN - palette_index 35, 0 ; BASEBALL, (Game and Watch 2) - palette_index 34, 0 ; TENNIS - palette_index 3, 0 ; TETRIS - palette_index 31, 0 ; QIX - palette_index 15, 0 ; DR.MARIO - palette_index 10, 0 ; RADARMISSION - palette_index 5, 0 ; F1RACE - palette_index 19, 0 ; YOSSY NO TAMAGO - palette_index 36, 0 ; - palette_index 7, $80 ; X - palette_index 37, 0 ; MARIOLAND2 - palette_index 30, 0 ; YOSSY NO COOKIE - palette_index 44, 0 ; ZELDA - palette_index 21, 0 ; - palette_index 32, 0 ; - palette_index 31, 0 ; TETRIS FLASH - palette_index 20, 0 ; DONKEY KONG - palette_index 5, 0 ; MARIO'S PICROSS - palette_index 33, 0 ; - palette_index 13, 0 ; POKEMON RED, (GAMEBOYCAMERA G) - palette_index 14, 0 ; POKEMON GREEN - palette_index 5, 0 ; PICROSS 2 - palette_index 29, 0 ; YOSSY NO PANEPON - palette_index 5, 0 ; KIRAKIRA KIDS - palette_index 18, 0 ; GAMEBOY GALLERY - palette_index 9, 0 ; POCKETCAMERA - palette_index 3, 0 ; - palette_index 2, 0 ; BALLOON KID - palette_index 26, 0 ; KINGOFTHEZOO - palette_index 25, 0 ; DMG FOOTBALL - palette_index 25, 0 ; WORLD CUP - palette_index 41, 0 ; OTHELLO - palette_index 42, 0 ; SUPER RC PRO-AM - palette_index 26, 0 ; DYNABLASTER - palette_index 45, 0 ; BOY AND BLOB GB2 - palette_index 42, 0 ; MEGAMAN - palette_index 45, 0 ; STAR WARS-NOA - palette_index 36, 0 ; - palette_index 38, 0 ; WAVERACE + palette_index 0 ; Default Palette + palette_index 4 ; ALLEY WAY + palette_index 5 ; YAKUMAN + palette_index 35 ; BASEBALL, (Game and Watch 2) + palette_index 34 ; TENNIS + palette_index 3 ; TETRIS + palette_index 31 ; QIX + palette_index 15 ; DR.MARIO + palette_index 10 ; RADARMISSION + palette_index 5 ; F1RACE + palette_index 19 ; YOSSY NO TAMAGO + palette_index 36 ; + palette_index 7, $80 ; X + palette_index 37 ; MARIOLAND2 + palette_index 30 ; YOSSY NO COOKIE + palette_index 44 ; ZELDA + palette_index 21 ; + palette_index 32 ; + palette_index 31 ; TETRIS FLASH + palette_index 20 ; DONKEY KONG + palette_index 5 ; MARIO'S PICROSS + palette_index 33 ; + palette_index 13 ; POKEMON RED, (GAMEBOYCAMERA G) + palette_index 14 ; POKEMON GREEN + palette_index 5 ; PICROSS 2 + palette_index 29 ; YOSSY NO PANEPON + palette_index 5 ; KIRAKIRA KIDS + palette_index 18 ; GAMEBOY GALLERY + palette_index 9 ; POCKETCAMERA + palette_index 3 ; + palette_index 2 ; BALLOON KID + palette_index 26 ; KINGOFTHEZOO + palette_index 25 ; DMG FOOTBALL + palette_index 25 ; WORLD CUP + palette_index 41 ; OTHELLO + palette_index 42 ; SUPER RC PRO-AM + palette_index 26 ; DYNABLASTER + palette_index 45 ; BOY AND BLOB GB2 + palette_index 42 ; MEGAMAN + palette_index 45 ; STAR WARS-NOA + palette_index 36 ; + palette_index 38 ; WAVERACE palette_index 26, $80 ; - palette_index 42, 0 ; LOLO2 - palette_index 30, 0 ; YOSHI'S COOKIE - palette_index 41, 0 ; MYSTIC QUEST - palette_index 34, 0 ; - palette_index 34, 0 ; TOPRANKINGTENNIS - palette_index 5, 0 ; MANSELL - palette_index 42, 0 ; MEGAMAN3 - palette_index 6, 0 ; SPACE INVADERS - palette_index 5, 0 ; GAME&WATCH - palette_index 33, 0 ; DONKEYKONGLAND95 - palette_index 25, 0 ; ASTEROIDS/MISCMD - palette_index 42, 0 ; STREET FIGHTER 2 - palette_index 42, 0 ; DEFENDER/JOUST - palette_index 40, 0 ; KILLERINSTINCT95 - palette_index 2, 0 ; TETRIS BLAST - palette_index 16, 0 ; PINOCCHIO - palette_index 25, 0 ; - palette_index 42, 0 ; BA.TOSHINDEN - palette_index 42, 0 ; NETTOU KOF 95 - palette_index 5, 0 ; - palette_index 0, 0 ; TETRIS PLUS - palette_index 39, 0 ; DONKEYKONGLAND 3 - palette_index 36, 0 ; - palette_index 22, 0 ; SUPER MARIOLAND - palette_index 25, 0 ; GOLF - palette_index 6, 0 ; SOLARSTRIKER - palette_index 32, 0 ; GBWARS - palette_index 12, 0 ; KAERUNOTAMENI - palette_index 36, 0 ; - palette_index 11, 0 ; POKEMON BLUE - palette_index 39, 0 ; DONKEYKONGLAND - palette_index 18, 0 ; GAMEBOY GALLERY2 - palette_index 39, 0 ; DONKEYKONGLAND 2 - palette_index 24, 0 ; KID ICARUS - palette_index 31, 0 ; TETRIS2 - palette_index 50, 0 ; - palette_index 17, 0 ; MOGURANYA - palette_index 46, 0 ; - palette_index 6, 0 ; GALAGA&GALAXIAN - palette_index 27, 0 ; BT2RAGNAROKWORLD - palette_index 0, 0 ; KEN GRIFFEY JR - palette_index 47, 0 ; - palette_index 41, 0 ; MAGNETIC SOCCER - palette_index 41, 0 ; VEGAS STAKES - palette_index 0, 0 ; - palette_index 0, 0 ; MILLI/CENTI/PEDE - palette_index 19, 0 ; MARIO & YOSHI - palette_index 34, 0 ; SOCCER - palette_index 23, 0 ; POKEBOM - palette_index 18, 0 ; G&W GALLERY - palette_index 29, 0 ; TETRIS ATTACK + palette_index 42 ; LOLO2 + palette_index 30 ; YOSHI'S COOKIE + palette_index 41 ; MYSTIC QUEST + palette_index 34 ; + palette_index 34 ; TOPRANKINGTENNIS + palette_index 5 ; MANSELL + palette_index 42 ; MEGAMAN3 + palette_index 6 ; SPACE INVADERS + palette_index 5 ; GAME&WATCH + palette_index 33 ; DONKEYKONGLAND95 + palette_index 25 ; ASTEROIDS/MISCMD + palette_index 42 ; STREET FIGHTER 2 + palette_index 42 ; DEFENDER/JOUST + palette_index 40 ; KILLERINSTINCT95 + palette_index 2 ; TETRIS BLAST + palette_index 16 ; PINOCCHIO + palette_index 25 ; + palette_index 42 ; BA.TOSHINDEN + palette_index 42 ; NETTOU KOF 95 + palette_index 5 ; + palette_index 0 ; TETRIS PLUS + palette_index 39 ; DONKEYKONGLAND 3 + palette_index 36 ; + palette_index 22 ; SUPER MARIOLAND + palette_index 25 ; GOLF + palette_index 6 ; SOLARSTRIKER + palette_index 32 ; GBWARS + palette_index 12 ; KAERUNOTAMENI + palette_index 36 ; + palette_index 11 ; POKEMON BLUE + palette_index 39 ; DONKEYKONGLAND + palette_index 18 ; GAMEBOY GALLERY2 + palette_index 39 ; DONKEYKONGLAND 2 + palette_index 24 ; KID ICARUS + palette_index 31 ; TETRIS2 + palette_index 50 ; + palette_index 17 ; MOGURANYA + palette_index 46 ; + palette_index 6 ; GALAGA&GALAXIAN + palette_index 27 ; BT2RAGNAROKWORLD + palette_index 0 ; KEN GRIFFEY JR + palette_index 47 ; + palette_index 41 ; MAGNETIC SOCCER + palette_index 41 ; VEGAS STAKES + palette_index 0 ; + palette_index 0 ; MILLI/CENTI/PEDE + palette_index 19 ; MARIO & YOSHI + palette_index 34 ; SOCCER + palette_index 23 ; POKEBOM + palette_index 18 ; G&W GALLERY + palette_index 29 ; TETRIS ATTACK Dups4thLetterArray: db "BEFAARBEKEK R-URAR INAILICE R" @@ -439,119 +449,133 @@ ENDM MACRO raw_palette_comb ; Obj0, Obj1, Bg db (\1) * 2, (\2) * 2, (\3) * 2 ENDM - palette_comb 4, 4, 29 - palette_comb 18, 18, 18 - palette_comb 20, 20, 20 - palette_comb 24, 24, 24 - palette_comb 9, 9, 9 - palette_comb 0, 0, 0 - palette_comb 27, 27, 27 - palette_comb 5, 5, 5 - palette_comb 12, 12, 12 - palette_comb 26, 26, 26 - palette_comb 16, 8, 8 - palette_comb 4, 28, 28 - palette_comb 4, 2, 2 - palette_comb 3, 4, 4 - palette_comb 4, 29, 29 - palette_comb 28, 4, 28 - palette_comb 2, 17, 2 - palette_comb 16, 16, 8 - palette_comb 4, 4, 7 - palette_comb 4, 4, 18 - palette_comb 4, 4, 20 - palette_comb 19, 19, 9 - raw_palette_comb 4 * 4 - 1, 4 * 4 - 1, 11 * 4 - palette_comb 17, 17, 2 - palette_comb 4, 4, 2 - palette_comb 4, 4, 3 - palette_comb 28, 28, 0 - palette_comb 3, 3, 0 - palette_comb 0, 0, 1 - palette_comb 18, 22, 18 - palette_comb 20, 22, 20 - palette_comb 24, 22, 24 - palette_comb 16, 22, 8 - palette_comb 17, 4, 13 - raw_palette_comb 28 * 4 - 1, 0 * 4, 14 * 4 - raw_palette_comb 28 * 4 - 1, 4 * 4, 15 * 4 - raw_palette_comb 19 * 4, 23 * 4 - 1, 9 * 4 - palette_comb 16, 28, 10 - palette_comb 4, 23, 28 - palette_comb 17, 22, 2 - palette_comb 4, 0, 2 - palette_comb 4, 28, 3 - palette_comb 28, 3, 0 - palette_comb 3, 28, 4 - palette_comb 21, 28, 4 - palette_comb 3, 28, 0 - palette_comb 25, 3, 28 - palette_comb 0, 28, 8 - palette_comb 4, 3, 28 - palette_comb 28, 3, 6 - palette_comb 4, 28, 29 + palette_comb 4, 4, 29 ; 0, Right + A + palette_comb 18, 18, 18 ; 1, Right + palette_comb 20, 20, 20 ; 2 + palette_comb 24, 24, 24 ; 3, Down + A + palette_comb 9, 9, 9 ; 4 + palette_comb 0, 0, 0 ; 5, Up + palette_comb 27, 27, 27 ; 6, Right + B + palette_comb 5, 5, 5 ; 7, Left + B + palette_comb 12, 12, 12 ; 8, Down + palette_comb 26, 26, 26 ; 9 + palette_comb 16, 8, 8 ; 10 + palette_comb 4, 28, 28 ; 11 + palette_comb 4, 2, 2 ; 12 + palette_comb 3, 4, 4 ; 13 + palette_comb 4, 29, 29 ; 14 + palette_comb 28, 4, 28 ; 15 + palette_comb 2, 17, 2 ; 16 + palette_comb 16, 16, 8 ; 17 + palette_comb 4, 4, 7 ; 18 + palette_comb 4, 4, 18 ; 19 + palette_comb 4, 4, 20 ; 20 + palette_comb 19, 19, 9 ; 21 + raw_palette_comb 4 * 4 - 1, 4 * 4 - 1, 11 * 4 ; 22 + palette_comb 17, 17, 2 ; 23 + palette_comb 4, 4, 2 ; 24 + palette_comb 4, 4, 3 ; 25 + palette_comb 28, 28, 0 ; 26 + palette_comb 3, 3, 0 ; 27 + palette_comb 0, 0, 1 ; 28, Up + B + palette_comb 18, 22, 18 ; 29 + palette_comb 20, 22, 20 ; 30 + palette_comb 24, 22, 24 ; 31 + palette_comb 16, 22, 8 ; 32 + palette_comb 17, 4, 13 ; 33 + raw_palette_comb 28 * 4 - 1, 0 * 4, 14 * 4 ; 34 + raw_palette_comb 28 * 4 - 1, 4 * 4, 15 * 4 ; 35 + raw_palette_comb 19 * 4, 23 * 4 - 1, 9 * 4 ; 36 + palette_comb 16, 28, 10 ; 37 + palette_comb 4, 23, 28 ; 38 + palette_comb 17, 22, 2 ; 39 + palette_comb 4, 0, 2 ; 40, Left + A + palette_comb 4, 28, 3 ; 41 + palette_comb 28, 3, 0 ; 42 + palette_comb 3, 28, 4 ; 43, Up + A + palette_comb 21, 28, 4 ; 44 + palette_comb 3, 28, 0 ; 45 + palette_comb 25, 3, 28 ; 46 + palette_comb 0, 28, 8 ; 47 + palette_comb 4, 3, 28 ; 48, Left + palette_comb 28, 3, 6 ; 49, Down + B + palette_comb 4, 28, 29 ; 50 ; SameBoy "Exclusives" - palette_comb 30, 30, 30 ; CGA - palette_comb 31, 31, 31 ; DMG LCD - palette_comb 28, 4, 1 - palette_comb 0, 0, 2 + palette_comb 30, 30, 30 ; 51, Right + A + B, CGA + palette_comb 31, 31, 31 ; 52, Left + A + B, DMG LCD + palette_comb 28, 4, 1 ; 53, Up + A + B + palette_comb 0, 0, 2 ; 54, Down + A + B Palettes: - dw $7FFF, $32BF, $00D0, $0000 - dw $639F, $4279, $15B0, $04CB - dw $7FFF, $6E31, $454A, $0000 - dw $7FFF, $1BEF, $0200, $0000 - dw $7FFF, $421F, $1CF2, $0000 - dw $7FFF, $5294, $294A, $0000 - dw $7FFF, $03FF, $012F, $0000 - dw $7FFF, $03EF, $01D6, $0000 - dw $7FFF, $42B5, $3DC8, $0000 - dw $7E74, $03FF, $0180, $0000 - dw $67FF, $77AC, $1A13, $2D6B - dw $7ED6, $4BFF, $2175, $0000 - dw $53FF, $4A5F, $7E52, $0000 - dw $4FFF, $7ED2, $3A4C, $1CE0 - dw $03ED, $7FFF, $255F, $0000 - dw $036A, $021F, $03FF, $7FFF - dw $7FFF, $01DF, $0112, $0000 - dw $231F, $035F, $00F2, $0009 - dw $7FFF, $03EA, $011F, $0000 - dw $299F, $001A, $000C, $0000 - dw $7FFF, $027F, $001F, $0000 - dw $7FFF, $03E0, $0206, $0120 - dw $7FFF, $7EEB, $001F, $7C00 - dw $7FFF, $3FFF, $7E00, $001F - dw $7FFF, $03FF, $001F, $0000 - dw $03FF, $001F, $000C, $0000 - dw $7FFF, $033F, $0193, $0000 - dw $0000, $4200, $037F, $7FFF - dw $7FFF, $7E8C, $7C00, $0000 - dw $7FFF, $1BEF, $6180, $0000 + dw $7FFF, $32BF, $00D0, $0000 ; 0 + dw $639F, $4279, $15B0, $04CB ; 1 + dw $7FFF, $6E31, $454A, $0000 ; 2 + dw $7FFF, $1BEF, $0200, $0000 ; 3 + dw $7FFF, $421F, $1CF2, $0000 ; 4 + dw $7FFF, $5294, $294A, $0000 ; 5 + dw $7FFF, $03FF, $012F, $0000 ; 6 + dw $7FFF, $03EF, $01D6, $0000 ; 7 + dw $7FFF, $42B5, $3DC8, $0000 ; 8 + dw $7E74, $03FF, $0180, $0000 ; 9 + dw $67FF, $77AC, $1A13, $2D6B ; 10 + dw $7ED6, $4BFF, $2175, $0000 ; 11 + dw $53FF, $4A5F, $7E52, $0000 ; 12 + dw $4FFF, $7ED2, $3A4C, $1CE0 ; 13 + dw $03ED, $7FFF, $255F, $0000 ; 14 + dw $036A, $021F, $03FF, $7FFF ; 15 + dw $7FFF, $01DF, $0112, $0000 ; 16 + dw $231F, $035F, $00F2, $0009 ; 17 + dw $7FFF, $03EA, $011F, $0000 ; 18 + dw $299F, $001A, $000C, $0000 ; 19 + dw $7FFF, $027F, $001F, $0000 ; 20 + dw $7FFF, $03E0, $0206, $0120 ; 21 + dw $7FFF, $7EEB, $001F, $7C00 ; 22 + dw $7FFF, $3FFF, $7E00, $001F ; 23 + dw $7FFF, $03FF, $001F, $0000 ; 24 + dw $03FF, $001F, $000C, $0000 ; 25 + dw $7FFF, $033F, $0193, $0000 ; 26 + dw $0000, $4200, $037F, $7FFF ; 27 + dw $7FFF, $7E8C, $7C00, $0000 ; 28 + dw $7FFF, $1BEF, $6180, $0000 ; 29 ; SameBoy "Exclusives" - dw $7FFF, $7FEA, $7D5F, $0000 ; CGA 1 - dw $4778, $3290, $1D87, $0861 ; DMG LCD + dw $7FFF, $7FEA, $7D5F, $0000 ; 30, CGA 1 + dw $4778, $3290, $1D87, $0861 ; 31, DMG LCD KeyCombinationPalettes: - db 1 * 3 ; Right - db 48 * 3 ; Left - db 5 * 3 ; Up - db 8 * 3 ; Down - db 0 * 3 ; Right + A - db 40 * 3 ; Left + A - db 43 * 3 ; Up + A - db 3 * 3 ; Down + A - db 6 * 3 ; Right + B - db 7 * 3 ; Left + B - db 28 * 3 ; Up + B - db 49 * 3 ; Down + B +MACRO palette_comb_id ; PaletteCombinations ID + db (\1) * 3 +ENDM + palette_comb_id 1 ; 1, Right + palette_comb_id 48 ; 2, Left + palette_comb_id 5 ; 3, Up + palette_comb_id 8 ; 4, Down + palette_comb_id 0 ; 5, Right + A + palette_comb_id 40 ; 6, Left + A + palette_comb_id 43 ; 7, Up + A + palette_comb_id 3 ; 8, Down + A + palette_comb_id 6 ; 9, Right + B + palette_comb_id 7 ; 10, Left + B + palette_comb_id 28 ; 11, Up + B + palette_comb_id 49 ; 12, Down + B ; SameBoy "Exclusives" - db 51 * 3 ; Right + A + B - db 52 * 3 ; Left + A + B - db 53 * 3 ; Up + A + B - db 54 * 3 ; Down + A + B + palette_comb_id 51 ; 13, Right + A + B + palette_comb_id 52 ; 14, Left + A + B + palette_comb_id 53 ; 15, Up + A + B + palette_comb_id 54 ; 16, Down + A + B TrademarkSymbol: - db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c + 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: SameBoyLogo: incbin "SameBoyLogo.pb12" @@ -570,7 +594,7 @@ IF DEF(AGB) ELSE dw $5500 ; Blue ENDC - + AnimationColorsEnd: ; Helper Functions @@ -598,7 +622,7 @@ DoubleBitsAndWriteRowTwice: WaitFrame: push hl - ld hl, $FF0F + ld hl, rIF res 0, [hl] .wait bit 0, [hl] @@ -619,8 +643,8 @@ PlaySound: ldh [rNR14], a ret -ClearMemoryPage8000: - ld hl, $8000 +ClearMemoryVRAM: + ld hl, _VRAM ; Clear from HL to HL | 0x2000 ClearMemoryPage: xor a @@ -631,7 +655,7 @@ ClearMemoryPage: ReadTwoTileLines: call ReadTileLine -; c = $f0 for even lines, $f for odd lines. +; c = $F0 for even lines, $0F for odd lines. ReadTileLine: ld a, [de] and c @@ -665,13 +689,10 @@ ReadCGBLogoHalfTile: ; LoadTileset using PB12 codec, 2020 Jakub Kądziołka ; (based on PB8 codec, 2019 Damian Yerrick) -DEF SameBoyLogo_dst = $8080 -DEF SameBoyLogo_length = (128 * 24) / 64 - LoadTileset: - ld hl, SameBoyLogo - ld de, SameBoyLogo_dst - 1 - ld c, SameBoyLogo_length + ld hl, SameBoyLogo ; source + ld de, _VRAM + $80 - 1 ; destination + ld c, (128 * 24) / (8 * 8) ; length .refill ; Register map for PB12 decompression ; HL: source address in boot ROM @@ -709,13 +730,13 @@ LoadTileset: ld c, a jr nc, .shift_left srl a - db $fe ; eat the add a with cp d8 + db $FE ; eat the `add a` with `cp d8` .shift_left add a sla b jr c, .go_and or c - db $fe ; eat the and c with cp d8 + db $FE ; eat the `and c` with `cp d8` .go_and and c jr .got_byte @@ -739,26 +760,26 @@ LoadTileset: ld l, $80 ; Copy (unresized) ROM logo - ld de, $104 + ld de, NintendoLogo .CGBROMLogoLoop - ld c, $f0 + ld c, $F0 call ReadCGBLogoHalfTile add a, 22 ld e, a call ReadCGBLogoHalfTile sub a, 22 ld e, a - cp $1c + cp $1C jr nz, .CGBROMLogoLoop inc hl ; fallthrough ReadTrademarkSymbol: ld de, TrademarkSymbol - ld c,$08 + ld c, TrademarkSymbolEnd - TrademarkSymbol .loadTrademarkSymbolLoop: - ld a,[de] + ld a, [de] inc de - ldi [hl],a + ldi [hl], a inc hl dec c jr nz, .loadTrademarkSymbolLoop @@ -772,7 +793,7 @@ DoIntroAnimation: .animationLoop ld b, 2 call WaitBFrames - ld hl, $98C0 + ld hl, _SCRN0 + 6 * SCRN_VX_B + 0 ld c, 3 ; Row count .loop ld a, [hl] @@ -799,8 +820,8 @@ Preboot: IF !DEF(FAST) ld b, 32 ; 32 times to fade .fadeLoop - ld c, 32 ; 32 colors to fade - ld hl, BgPalettes + ld c, (hBgPalettesEnd - hBgPalettes) / 2 ; 32 colors to fade + ld hl, hBgPalettes .frameLoop push bc @@ -810,7 +831,7 @@ IF !DEF(FAST) ld a, [hld] ld d, a ; RGB(1,1,1) - ld bc, $421 + ld bc, $0421 ; Is blue maxed? ld a, e @@ -859,7 +880,7 @@ ENDC ld a, 2 ldh [rSVBK], a ; Clear RAM Bank 2 (Like the original boot ROM) - ld hl, $D000 + ld hl, _RAMBANK call ClearMemoryPage inc a call ClearVRAMViaHDMA @@ -873,19 +894,19 @@ ENDC ; Final values for CGB mode ld d, a ld e, c - ld l, $0d + ld l, $0D - ld a, [$143] + ld a, [CGBFlag] bit 7, a call z, EmulateDMG bit 7, a ldh [rKEY0], a ; write CGB compatibility byte, CGB mode - ldh a, [TitleChecksum] + ldh a, [hTitleChecksum] ld b, a jr z, .skipDMGForCGBCheck - ldh a, [InputPalette] + ldh a, [hInputPalette] and a jr nz, .emulateDMGForCGBGame .skipDMGForCGBCheck @@ -894,17 +915,17 @@ IF DEF(AGB) ; AF = $1100, C = 0 xor a ld c, a - add a, $11 + add a, BOOTUP_A_CGB ld h, c - ; B is set to 1 after ret + ; B is set to BOOTUP_B_AGB (1) after ret ELSE ; Set registers to match the original CGB boot ; AF = $1180, C = 0 xor a ld c, a - ld a, $11 + ld a, BOOTUP_A_CGB ld h, c - ; B is set to the title checksum + ; B is set to the title checksum (BOOTUP_B_CGB, 0) ENDC ret @@ -933,7 +954,7 @@ EmulateDMG: add b add b ld b, a - ldh a, [InputPalette] + ldh a, [hInputPalette] and a jr z, .nothingDown call GetKeyComboPalette @@ -946,19 +967,19 @@ EmulateDMG: ld a, 4 ; Set the final values for DMG mode ld de, 8 - ld l, $7c + ld l, $7C ret GetPaletteIndex: - ld hl, $14B - ld a, [hl] ; Old Licensee + ld hl, OldLicenseeCode + ld a, [hl] cp $33 jr z, .newLicensee dec a ; 1 = Nintendo jr nz, .notNintendo jr .doChecksum .newLicensee - ld l, $44 + ld l, LOW(NewLicenseeCode) ld a, [hli] cp "0" jr nz, .notNintendo @@ -967,16 +988,15 @@ GetPaletteIndex: jr nz, .notNintendo .doChecksum - ld l, $34 - ld c, $10 + ld l, LOW(Title) + ld c, 16 xor a - .checksumLoop add [hl] inc l dec c jr nz, .checksumLoop - ldh [TitleChecksum], a + ldh [hTitleChecksum], a ld b, a ; c = 0 @@ -1002,7 +1022,7 @@ GetPaletteIndex: ld a, [hl] pop hl ld c, a - ld a, [$134 + 3] ; Get 4th letter + ld a, [Title + 3] ; Get 4th letter cp c jr nz, .searchLoop ; Not a match, continue @@ -1011,7 +1031,7 @@ GetPaletteIndex: add PalettePerChecksum - TitleChecksums - 1; -1 since hl was incremented ld l, a ld a, b - ldh [TitleChecksum], a + ldh [hTitleChecksum], a ld a, [hl] ret @@ -1039,13 +1059,13 @@ LoadPalettesFromIndex: ; a = index of combination ; b is already 0 ld c, a add hl, bc - ld d, 8 - ld c, $6A + ld d, 4 * 2 + ld c, LOW(rOBPI) call LoadPalettes pop hl - bit 3, e + bit OAMB_BANK1, e jr nz, .loadBGPalette - ld e, 8 + ld e, OAMF_BANK1 jr .loadObjPalette .loadBGPalette ;BG Palette @@ -1057,13 +1077,11 @@ LoadPalettesFromIndex: ; a = index of combination jr LoadBGPalettes LoadPalettesFromHRAM: - ld hl, BgPalettes - ld d, 64 - + ld hl, hBgPalettes + ld d, hBgPalettesEnd - hBgPalettes LoadBGPalettes: ld e, 0 ld c, LOW(rBGPI) - LoadPalettes: ld a, $80 or e @@ -1081,7 +1099,7 @@ ClearVRAMViaHDMA: ld hl, HDMAData _ClearVRAMViaHDMA: call WaitFrame ; Wait for vblank - ld c, $51 + ld c, LOW(rHDMA1) ld b, 5 .loop ld a, [hli] @@ -1093,7 +1111,7 @@ _ClearVRAMViaHDMA: ; clobbers AF and HL GetInputPaletteIndex: - ld a, $20 ; Select directions + ld a, P1F_GET_DPAD ldh [rJOYP], a ldh a, [rJOYP] cpl @@ -1108,7 +1126,7 @@ GetInputPaletteIndex: ; c = 1: Right, 2: Left, 3: Up, 4: Down - ld a, $10 ; Select buttons + ld a, P1F_GET_BTN ldh [rJOYP], a ldh a, [rJOYP] cpl @@ -1117,11 +1135,11 @@ GetInputPaletteIndex: and $C add l ld l, a - ldh a, [InputPalette] + ldh a, [hInputPalette] cp l ret z ; No change, don't load ld a, l - ldh [InputPalette], a + ldh [hInputPalette], a ; Slide into change Animation Palette ChangeAnimationPalette: @@ -1144,21 +1162,21 @@ ChangeAnimationPalette: ld a, [hli] push hl - ld hl, BgPalettes ; First color, all palettes + ld hl, hBgPalettes ; First color, all palettes call ReplaceColorInAllPalettes - ld l, LOW(BgPalettes + 2) ; Second color, all palettes + ld l, LOW(hBgPalettes + 2) ; Second color, all palettes call ReplaceColorInAllPalettes pop hl - ldh [BgPalettes + 6], a ; Fourth color, first palette + ldh [hBgPalettes + 6], a ; Fourth color, first palette ld a, [hli] push hl - ld hl, BgPalettes + 1 ; First color, all palettes + ld hl, hBgPalettes + 1 ; First color, all palettes call ReplaceColorInAllPalettes - ld l, LOW(BgPalettes + 3) ; Second color, all palettes + ld l, LOW(hBgPalettes + 3) ; Second color, all palettes call ReplaceColorInAllPalettes pop hl - ldh [BgPalettes + 7], a ; Fourth color, first palette + ldh [hBgPalettes + 7], a ; Fourth color, first palette pop af jr z, .isNotWhite @@ -1166,41 +1184,41 @@ ChangeAnimationPalette: inc hl .isNotWhite ; Mixing code by ISSOtm - ldh a, [BgPalettes + 7 * 8 + 2] + ldh a, [hBgPalettes + 7 * 8 + 2] and ~$21 ld b, a ld a, [hli] and ~$21 add a, b ld b, a - ld a, [BgPalettes + 7 * 8 + 3] + ld a, [hBgPalettes + 7 * 8 + 3] res 2, a ; and ~$04, but not touching carry ld c, [hl] res 2, c ; and ~$04, but not touching carry adc a, c rra ; Carry sort of "extends" the accumulator, we're bringing that bit back home - ld [BgPalettes + 7 * 8 + 3], a + ld [hBgPalettes + 7 * 8 + 3], a ld a, b rra - ld [BgPalettes + 7 * 8 + 2], a + ld [hBgPalettes + 7 * 8 + 2], a dec l ld a, [hli] - ldh [BgPalettes + 7 * 8 + 6], a ; Fourth color, 7th palette + ldh [hBgPalettes + 7 * 8 + 6], a ; Fourth color, 7th palette ld a, [hli] - ldh [BgPalettes + 7 * 8 + 7], a ; Fourth color, 7th palette + ldh [hBgPalettes + 7 * 8 + 7], a ; Fourth color, 7th palette ld a, [hli] - ldh [BgPalettes + 4], a ; Third color, first palette + ldh [hBgPalettes + 4], a ; Third color, first palette ld a, [hli] - ldh [BgPalettes + 5], a ; Third color, first palette + ldh [hBgPalettes + 5], a ; Third color, first palette call WaitFrame call LoadPalettesFromHRAM ; Delay the wait loop while the user is selecting a palette ld a, 48 - ldh [WaitLoopCounter], a + ldh [hWaitLoopCounter], a pop de pop bc ret @@ -1218,34 +1236,35 @@ ReplaceColorInAllPalettes: LoadDMGTilemap: push af call WaitFrame - ld a, $19 ; Trademark symbol - ld [$9910], a ; ... put in the superscript position - ld hl,$992f ; Bottom right corner of the logo - ld c,$c ; Tiles in a logo row + 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 + ld l, $0F ; Jump to top row jr .tilemapLoop .tilemapDone pop af ret BootEnd: -IF BootEnd > $900 +IF BootEnd > $0900 FAIL "BootROM overflowed: {BootEnd}" ENDC ds $100 + $800 - @ ; Ensure that the ROM is padded up to standard size. -SECTION "HRAM", HRAM[$FF80] -TitleChecksum: +SECTION "HRAM", HRAM[_HRAM] +hTitleChecksum: ds 1 -BgPalettes: +hBgPalettes: ds 8 * 4 * 2 -InputPalette: +hBgPalettesEnd: +hInputPalette: ds 1 -WaitLoopCounter: +hWaitLoopCounter: ds 1 diff --git a/BootROMs/cgb_boot_fast.asm b/BootROMs/cgb_boot_fast.asm index 8707a587b..c0d6eab67 100644 --- a/BootROMs/cgb_boot_fast.asm +++ b/BootROMs/cgb_boot_fast.asm @@ -1,2 +1,2 @@ -DEF FAST = 1 -include "cgb_boot.asm" \ No newline at end of file +DEF FAST = 1 +include "cgb_boot.asm" diff --git a/BootROMs/dmg_boot.asm b/BootROMs/dmg_boot.asm index 17a15ffc3..7013033a5 100644 --- a/BootROMs/dmg_boot.asm +++ b/BootROMs/dmg_boot.asm @@ -1,14 +1,14 @@ ; SameBoy DMG bootstrap ROM -INCLUDE "hardware.inc" +include "sameboot.inc" -SECTION "BootCode", ROM0[$0] +SECTION "BootCode", ROM0[$0000] Start: ; Init stack pointer - ld sp, $fffe + ld sp, $FFFE ; Clear memory VRAM - ld hl, $8000 + ld hl, _VRAM xor a .clearVRAMLoop @@ -17,24 +17,25 @@ Start: jr z, .clearVRAMLoop ; Init Audio - ld a, $80 + ld a, AUDENA_ON ldh [rNR52], a + assert AUDENA_ON == AUDLEN_DUTY_50 ldh [rNR11], a - ld a, $f3 - ldh [rNR12], a - ldh [rNR51], 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 + ldh [rNR50], a ; Volume $7, left and right ; Init BG palette - ld a, $54 + 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, $104 ; Logo start - ld hl, $8010 ; This is where we load the tiles in VRAM + ld de, NintendoLogo + ld hl, _VRAM + $10 ; This is where we load the tiles in VRAM .loadLogoLoop ld a, [de] ; Read 2 rows @@ -43,45 +44,45 @@ Start: call DoubleBitsAndWriteRow inc de ld a, e - xor $34 ; End of logo + xor LOW(NintendoLogoEnd) jr nz, .loadLogoLoop ; Load trademark symbol ld de, TrademarkSymbol - ld c,$08 + ld c, TrademarkSymbolEnd - TrademarkSymbol .loadTrademarkSymbolLoop: - ld a,[de] + ld a, [de] inc de - ldi [hl],a + ldi [hl], a inc hl dec c jr nz, .loadTrademarkSymbolLoop ; Set up tilemap - ld a,$19 ; Trademark symbol - ld [$9910], a ; ... put in the superscript position - ld hl,$992f ; Bottom right corner of the logo - ld c,$c ; Tiles in a logo row + 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 + ld l, $0F ; Jump to top row jr .tilemapLoop .tilemapDone ld a, 30 ldh [rSCY], a - + ; Turn on LCD - ld a, $91 + ld a, LCDCF_ON | LCDCF_BLK01 | LCDCF_BGON ldh [rLCDC], a - ld d, (-119) & $FF + ld d, LOW(-119) ld c, 15 - + .animate call WaitFrame ld a, d @@ -94,41 +95,41 @@ Start: ld a, c cp 8 jr nz, .noPaletteChange - ld a, $A8 + ld a, %10_10_10_00 ldh [rBGP], a .noPaletteChange dec c jr nz, .animate - ld a, $fc + 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 + ld a, $C1 call PlaySound - + ; Wait ~1 second ld b, 60 call WaitBFrames - + ; Set registers to match the original DMG boot IF DEF(MGB) - ld hl, $FFB0 + lb hl, BOOTUP_A_MGB, %10110000 ELSE - ld hl, $01B0 + lb hl, BOOTUP_A_DMG, %10110000 ENDC push hl pop af - ld hl, $014D - ld bc, $0013 - ld de, $00D8 - + ld hl, HeaderChecksum + lb bc, 0, LOW(rNR13) ; $0013 + lb de, 0, $D8 ; $00D8 + ; Boot the game jp BootGame @@ -155,7 +156,7 @@ DoubleBitsAndWriteRow: WaitFrame: push hl - ld hl, $FF0F + ld hl, rIF res 0, [hl] .wait bit 0, [hl] @@ -171,14 +172,25 @@ WaitBFrames: PlaySound: ldh [rNR13], a - ld a, $87 + ld a, AUDHIGH_RESTART | $7 ldh [rNR14], a ret TrademarkSymbol: -db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c - -SECTION "BootGame", ROM0[$fe] + 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 \ No newline at end of file + ldh [rBANK], a ; unmap boot ROM diff --git a/BootROMs/hardware.inc b/BootROMs/hardware.inc index b341f1cfe..c1a8c41a3 100755 --- a/BootROMs/hardware.inc +++ b/BootROMs/hardware.inc @@ -1,9 +1,16 @@ ;* ;* Gameboy Hardware definitions +;* https://github.com/gbdev/hardware.inc ;* ;* Based on Jones' hardware.inc ;* And based on Carsten Sorensen's ideas. ;* +;* To the extent possible under law, the authors of this work have +;* waived all copyright and related or neighboring rights to the work. +;* See https://creativecommons.org/publicdomain/zero/1.0/ for details. +;* +;* SPDX-License-Identifier: CC0-1.0 +;* ;* Rev 1.1 - 15-Jul-97 : Added define check ;* Rev 1.2 - 18-Jul-97 : Added revision check macro ;* Rev 1.3 - 19-Jul-97 : Modified for RGBASM V1.05 @@ -31,6 +38,17 @@ ;* Rev 4.3 - 07-Nov-21 : Deprecate VRAM address constants (Eievui) ;* Rev 4.4 - 11-Jan-22 : Deprecate VRAM CART_SRAM_2KB constant (avivace) ;* Rev 4.5 - 03-Mar-22 : Added bit number definitions for OCPS, BCPS and LCDC (sukus) +;* Rev 4.6 - 15-Jun-22 : Added MBC3 registers and special values +;* Rev 4.7.0 - 27-Jun-22 : Added alternate names for some constants +;* Rev 4.7.1 - 05-Jul-22 : Added RPB_LED_ON constant +;* Rev 4.8.0 - 25-Oct-22 : Changed background addressing constants (zlago) +;* Rev 4.8.1 - 29-Apr-23 : Added rOPRI (rbong) +;* Rev 4.9.0 - 24-Jun-23 : Added definitions for interrupt vectors (sukus) +;* Rev 4.9.1 - 11-Sep-23 : Added repository link and CC0 waiver notice + + +; NOTE: REVISION NUMBER CHANGES MUST BE REFLECTED +; IN `rev_Check_hardware_inc` BELOW! IF __RGBDS_MAJOR__ == 0 && __RGBDS_MINOR__ < 5 FAIL "This version of 'hardware.inc' requires RGBDS version 0.5.0 or later." @@ -41,14 +59,31 @@ ENDC IF !DEF(HARDWARE_INC) DEF HARDWARE_INC EQU 1 +; Usage: rev_Check_hardware_inc +; Examples: rev_Check_hardware_inc 4.1.2 +; rev_Check_hardware_inc 4.1 (equivalent to 4.1.0) +; rev_Check_hardware_inc 4 (equivalent to 4.0.0) MACRO rev_Check_hardware_inc -;NOTE: REVISION NUMBER CHANGES MUST BE ADDED -;TO SECOND PARAMETER IN FOLLOWING LINE. - IF \1 > 4.5 ;PUT REVISION NUMBER HERE - WARN "Version \1 or later of 'hardware.inc' is required." + DEF CUR_VER equs "4,9,1" ; ** UPDATE THIS LINE WHEN CHANGING THE REVISION NUMBER ** + + DEF MIN_VER equs STRRPL("\1", ".", ",") + DEF INTERNAL_CHK equs """MACRO ___internal + IF \\1 != \\4 || \\2 < \\5 || (\\2 == \\5 && \\3 < \\6) + FAIL "Version \\1.\\2.\\3 of 'hardware.inc' is incompatible with requested version \\4.\\5.\\6" ENDC +\nENDM""" + INTERNAL_CHK + ___internal {CUR_VER}, {MIN_VER},0,0 + PURGE CUR_VER, MIN_VER, INTERNAL_CHK, ___internal ENDM + +;*************************************************************************** +;* +;* General memory region constants +;* +;*************************************************************************** + DEF _VRAM EQU $8000 ; $8000->$9FFF DEF _SCRN0 EQU $9800 ; $9800->$9BFF DEF _SCRN1 EQU $9C00 ; $9C00->$9FFF @@ -60,17 +95,80 @@ DEF _IO EQU $FF00 ; $FF00->$FF7F,$FFFF DEF _AUD3WAVERAM EQU $FF30 ; $FF30->$FF3F DEF _HRAM EQU $FF80 ; $FF80->$FFFE -; *** MBC5 Equates *** -DEF rRAMG EQU $0000 ; $0000->$1fff -DEF rROMB0 EQU $2000 ; $2000->$2fff -DEF rROMB1 EQU $3000 ; $3000->$3fff - If more than 256 ROM banks are present. -DEF rRAMB EQU $4000 ; $4000->$5fff - Bit 3 enables rumble (if present) +;*************************************************************************** +;* +;* MBC registers +;* +;*************************************************************************** + +; *** Common *** + +; -- +; -- RAMG ($0000-$1FFF) +; -- Controls whether access to SRAM (and the MBC3 RTC registers) is allowed (W) +; -- +DEF rRAMG EQU $0000 + +DEF CART_SRAM_ENABLE EQU $0A +DEF CART_SRAM_DISABLE EQU $00 + + +; -- +; -- ROMB0 ($2000-$3FFF) +; -- Selects which ROM bank is mapped to the ROMX space ($4000-$7FFF) (W) +; -- +; -- The range of accepted values, as well as the behavior of writing $00, +; -- varies depending on the MBC. +; -- +DEF rROMB0 EQU $2000 + +; -- +; -- RAMB ($4000-$5FFF) +; -- Selects which SRAM bank is mapped to the SRAM space ($A000-$BFFF) (W) +; -- +; -- The range of accepted values varies depending on the cartridge configuration. +; -- +DEF rRAMB EQU $4000 + + +; *** MBC3-specific registers *** + +; Write one of these to rRAMG to map the corresponding RTC register to all SRAM space +DEF RTC_S EQU $08 ; Seconds (0-59) +DEF RTC_M EQU $09 ; Minutes (0-59) +DEF RTC_H EQU $0A ; Hours (0-23) +DEF RTC_DL EQU $0B ; Lower 8 bits of Day Counter ($00-$FF) +DEF RTC_DH EQU $0C ; Bit 7 - Day Counter Carry Bit (1=Counter Overflow) + ; Bit 6 - Halt (0=Active, 1=Stop Timer) + ; Bit 0 - Most significant bit of Day Counter (Bit 8) + + +; -- +; -- RTCLATCH ($6000-$7FFF) +; -- Write $00 then $01 to latch the current time into the RTC registers (W) +; -- +DEF rRTCLATCH EQU $6000 + + +; *** MBC5-specific register *** + +; -- +; -- ROMB1 ($3000-$3FFF) +; -- A 9th bit that "extends" ROMB0 if more than 256 banks are present (W) +; -- +; -- Also note that rROMB0 thus only spans $2000-$2FFF. +; -- +DEF rROMB1 EQU $3000 + + +; Bit 3 of RAMB enables the rumble motor (if any) +DEF CART_RUMBLE_ON EQU 1 << 3 ;*************************************************************************** ;* -;* Custom registers +;* Memory-mapped registers ;* ;*************************************************************************** @@ -105,9 +203,9 @@ DEF rSB EQU $FF01 ; -- DEF rSC EQU $FF02 -DEF SCF_START EQU %10000000 ;Transfer Start Flag (1=Transfer in progress, or requested) -DEF SCF_SPEED EQU %00000010 ;Clock Speed (0=Normal, 1=Fast) ** CGB Mode Only ** -DEF SCF_SOURCE EQU %00000001 ;Shift Clock (0=External Clock, 1=Internal Clock) +DEF SCF_START EQU %10000000 ; Transfer Start Flag (1=Transfer in progress, or requested) +DEF SCF_SPEED EQU %00000010 ; Clock Speed (0=Normal, 1=Fast) ** CGB Mode Only ** +DEF SCF_SOURCE EQU %00000001 ; Shift Clock (0=External Clock, 1=Internal Clock) DEF SCB_START EQU 7 DEF SCB_SPEED EQU 1 @@ -444,8 +542,8 @@ DEF LCDCF_WIN9800 EQU %00000000 ; Window Tile Map Display Select DEF LCDCF_WIN9C00 EQU %01000000 ; Window Tile Map Display Select DEF LCDCF_WINOFF EQU %00000000 ; Window Display DEF LCDCF_WINON EQU %00100000 ; Window Display -DEF LCDCF_BG8800 EQU %00000000 ; BG & Window Tile Data Select -DEF LCDCF_BG8000 EQU %00010000 ; BG & Window Tile Data Select +DEF LCDCF_BLK21 EQU %00000000 ; BG & Window Tile Data Select +DEF LCDCF_BLK01 EQU %00010000 ; BG & Window Tile Data Select DEF LCDCF_BG9800 EQU %00000000 ; BG Tile Map Display Select DEF LCDCF_BG9C00 EQU %00001000 ; BG Tile Map Display Select DEF LCDCF_OBJ8 EQU %00000000 ; OBJ Construction @@ -458,7 +556,7 @@ DEF LCDCF_BGON EQU %00000001 ; BG Display DEF LCDCB_ON EQU 7 ; LCD Control Operation DEF LCDCB_WIN9C00 EQU 6 ; Window Tile Map Display Select DEF LCDCB_WINON EQU 5 ; Window Display -DEF LCDCB_BG8000 EQU 4 ; BG & Window Tile Data Select +DEF LCDCB_BLKS EQU 4 ; BG & Window Tile Data Select DEF LCDCB_BG9C00 EQU 3 ; BG Tile Map Display Select DEF LCDCB_OBJ16 EQU 2 ; OBJ Construction DEF LCDCB_OBJON EQU 1 ; OBJ Display @@ -661,39 +759,65 @@ DEF RPF_DATAIN EQU %00000010 ; 0=Receiving IR Signal, 1=Normal DEF RPF_WRITE_HI EQU %00000001 DEF RPF_WRITE_LO EQU %00000000 +DEF RPB_LED_ON EQU 0 +DEF RPB_DATAIN EQU 1 + ; -- -; -- BCPS ($FF68) -; -- Background Color Palette Specification (R/W) +; -- BCPS/BGPI ($FF68) +; -- Background Color Palette Specification (aka Background Palette Index) (R/W) ; -- DEF rBCPS EQU $FF68 +DEF rBGPI EQU rBCPS DEF BCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing) DEF BCPSB_AUTOINC EQU 7 +DEF BGPIF_AUTOINC EQU BCPSF_AUTOINC +DEF BGPIB_AUTOINC EQU BCPSB_AUTOINC ; -- -; -- BCPD ($FF69) -; -- Background Color Palette Data (R/W) +; -- BCPD/BGPD ($FF69) +; -- Background Color Palette Data (aka Background Palette Data) (R/W) ; -- DEF rBCPD EQU $FF69 +DEF rBGPD EQU rBCPD ; -- -; -- OCPS ($FF6A) -; -- Object Color Palette Specification (R/W) +; -- OCPS/OBPI ($FF6A) +; -- Object Color Palette Specification (aka Object Background Palette Index) (R/W) ; -- DEF rOCPS EQU $FF6A +DEF rOBPI EQU rOCPS DEF OCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing) DEF OCPSB_AUTOINC EQU 7 +DEF OBPIF_AUTOINC EQU OCPSF_AUTOINC +DEF OBPIB_AUTOINC EQU OCPSB_AUTOINC ; -- -; -- OCPD ($FF6B) -; -- Object Color Palette Data (R/W) +; -- OCPD/OBPD ($FF6B) +; -- Object Color Palette Data (aka Object Background Palette Data) (R/W) ; -- DEF rOCPD EQU $FF6B +DEF rOBPD EQU rOCPD + + +; -- +; -- OPRI ($FF6C) +; -- Object Priority Mode (R/W) +; -- CGB Only + +; -- +; -- Priority can be changed only from the boot ROM +; -- +DEF rOPRI EQU $FF6C + +DEF OPRI_OAM EQU 0 ; Prioritize objects by location in OAM (CGB Mode default) +DEF OPRI_COORD EQU 1 ; Prioritize objects by x-coordinate (Non-CGB Mode default) + ; -- @@ -726,17 +850,6 @@ DEF rPCM12 EQU $FF76 DEF rPCM34 EQU $FF77 -; SameBoy additions -DEF rKEY0 EQU $FF4C -DEF rBANK EQU $FF50 -DEF rOPRI EQU $FF6C - -DEF rJOYP EQU rP1 -DEF rBGPI EQU rBCPS -DEF rBGPD EQU rBCPD -DEF rOBPI EQU rOCPS -DEF rOBPD EQU rOCPD - ; -- ; -- IE ($FFFF) ; -- Interrupt Enable (R/W) @@ -790,7 +903,6 @@ DEF AUDENV_DOWN EQU %00000000 ; -- Can be used with AUD1HIGH, AUD2HIGH, AUD3HIGH ; -- See AUD1HIGH for more info ; -- - DEF AUDHIGH_RESTART EQU %10000000 DEF AUDHIGH_LENGTH_ON EQU %01000000 DEF AUDHIGH_LENGTH_OFF EQU %00000000 @@ -814,10 +926,33 @@ DEF BOOTUP_B_AGB EQU %00000001 ; GBA, GBA SP, Game Boy Player, or New GBA S ;*************************************************************************** ;* -;* Cart related +;* Interrupt vector addresses +;* +;*************************************************************************** + +DEF INT_HANDLER_VBLANK EQU $0040 +DEF INT_HANDLER_STAT EQU $0048 +DEF INT_HANDLER_TIMER EQU $0050 +DEF INT_HANDLER_SERIAL EQU $0058 +DEF INT_HANDLER_JOYPAD EQU $0060 + + +;*************************************************************************** +;* +;* Header ;* ;*************************************************************************** +;* +;* Nintendo scrolling logo +;* (Code won't work on a real GameBoy) +;* (if next lines are altered.) +MACRO NINTENDO_LOGO + DB $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C,$00,$0D + DB $00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 + DB $BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC,$99,$9F,$BB,$B9,$33,$3E +ENDM + ; $0143 Color GameBoy compatibility code DEF CART_COMPATIBLE_DMG EQU $00 DEF CART_COMPATIBLE_DMG_GBC EQU $80 @@ -878,9 +1013,6 @@ DEF CART_SRAM_8KB EQU 2 ; 1 bank DEF CART_SRAM_32KB EQU 3 ; 4 banks DEF CART_SRAM_128KB EQU 4 ; 16 banks -DEF CART_SRAM_ENABLE EQU $0A -DEF CART_SRAM_DISABLE EQU $00 - ; $014A Destination code DEF CART_DEST_JAPANESE EQU $00 DEF CART_DEST_NON_JAPANESE EQU $01 @@ -918,7 +1050,7 @@ DEF PADB_A EQU $0 ;*************************************************************************** DEF SCRN_X EQU 160 ; Width of screen in pixels -DEF SCRN_Y EQU 144 ; Height of screen in pixels +DEF SCRN_Y EQU 144 ; Height of screen in pixels. Also corresponds to the value in LY at the beginning of VBlank. DEF SCRN_X_B EQU 20 ; Width of screen in bytes DEF SCRN_Y_B EQU 18 ; Height of screen in bytes @@ -966,16 +1098,6 @@ DEF OAMB_PAL1 EQU 4 ; Palette number; 0,1 (DMG) DEF OAMB_BANK1 EQU 3 ; Bank number; 0,1 (GBC) -;* -;* Nintendo scrolling logo -;* (Code won't work on a real GameBoy) -;* (if next lines are altered.) -MACRO NINTENDO_LOGO - DB $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C,$00,$0D - DB $00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 - DB $BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC,$99,$9F,$BB,$B9,$33,$3E -ENDM - ; Deprecated constants. Please avoid using. DEF IEF_LCDC EQU %00000010 ; LCDC (see STAT) @@ -983,6 +1105,9 @@ DEF _VRAM8000 EQU _VRAM DEF _VRAM8800 EQU _VRAM+$800 DEF _VRAM9000 EQU _VRAM+$1000 DEF CART_SRAM_2KB EQU 1 ; 1 incomplete bank +DEF LCDCF_BG8800 EQU %00000000 ; BG & Window Tile Data Select +DEF LCDCF_BG8000 EQU %00010000 ; BG & Window Tile Data Select +DEF LCDCB_BG8000 EQU 4 ; BG & Window Tile Data Select ENDC ;HARDWARE_INC diff --git a/BootROMs/mgb_boot.asm b/BootROMs/mgb_boot.asm index b0bc0bc9d..c20230386 100644 --- a/BootROMs/mgb_boot.asm +++ b/BootROMs/mgb_boot.asm @@ -1,2 +1,2 @@ -DEF MGB = 1 -include "dmg_boot.asm" \ No newline at end of file +DEF MGB = 1 +include "dmg_boot.asm" diff --git a/BootROMs/sameboot.inc b/BootROMs/sameboot.inc new file mode 100644 index 000000000..b7eecc734 --- /dev/null +++ b/BootROMs/sameboot.inc @@ -0,0 +1,40 @@ +IF !DEF(SAMEBOY_INC) +DEF SAMEBOY_INC EQU 1 + +include "hardware.inc" + +DEF rKEY0 EQU $FF4C +DEF rBANK EQU $FF50 + +DEF rJOYP EQU rP1 + + +MACRO lb ; r16, high, low + ld \1, LOW(\2) << 8 | LOW(\3) +ENDM + + +MACRO header_section ; name, address + PUSHS + SECTION "\1", ROM0[\2] + \1: + POPS +ENDM + header_section EntryPoint, $0100 + header_section NintendoLogo, $0104 + header_section NintendoLogoEnd, $0134 + header_section Title, $0134 + header_section ManufacturerCode, $013F + header_section CGBFlag, $0143 + header_section NewLicenseeCode, $0144 + header_section SGBFlag, $0146 + header_section CartridgeType, $0147 + header_section ROMSize, $0148 + header_section RAMSize, $0149 + header_section DestinationCode, $014A + header_section OldLicenseeCode, $014B + header_section MaskRomVersion, $014C + header_section HeaderChecksum, $014D + header_section GlobalChecksum, $014E + +ENDC diff --git a/BootROMs/sgb2_boot.asm b/BootROMs/sgb2_boot.asm index ee14ab19f..d81de18f6 100644 --- a/BootROMs/sgb2_boot.asm +++ b/BootROMs/sgb2_boot.asm @@ -1,2 +1,2 @@ -DEF SGB2 = 1 -include "sgb_boot.asm" \ No newline at end of file +DEF SGB2 = 1 +include "sgb_boot.asm" diff --git a/BootROMs/sgb_boot.asm b/BootROMs/sgb_boot.asm index 8cd2943aa..ba42b826a 100644 --- a/BootROMs/sgb_boot.asm +++ b/BootROMs/sgb_boot.asm @@ -1,14 +1,14 @@ ; SameBoy SGB bootstrap ROM -INCLUDE "hardware.inc" +include "sameboot.inc" -SECTION "BootCode", ROM0[$0] +SECTION "BootCode", ROM0[$0000] Start: ; Init stack pointer - ld sp, $fffe + ld sp, $FFFE ; Clear memory VRAM - ld hl, $8000 + ld hl, _VRAM xor a .clearVRAMLoop @@ -17,24 +17,25 @@ Start: jr z, .clearVRAMLoop ; Init Audio - ld a, $80 + ld a, AUDENA_ON ldh [rNR52], a + assert AUDENA_ON == AUDLEN_DUTY_50 ldh [rNR11], a - ld a, $f3 - ldh [rNR12], a - ldh [rNR51], 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 + ldh [rNR50], a ; Volume $7, left and right ; Init BG palette to white - ld a, $0 + ld a, %00_00_00_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, $104 ; Logo start - ld hl, $8010 ; This is where we load the tiles in VRAM + ld de, NintendoLogo + ld hl, _VRAM + $10 ; This is where we load the tiles in VRAM .loadLogoLoop ld a, [de] ; Read 2 rows @@ -43,43 +44,43 @@ Start: call DoubleBitsAndWriteRow inc de ld a, e - xor $34 ; End of logo + xor LOW(NintendoLogoEnd) jr nz, .loadLogoLoop ; Load trademark symbol ld de, TrademarkSymbol - ld c,$08 + ld c, TrademarkSymbolEnd - TrademarkSymbol .loadTrademarkSymbolLoop: - ld a,[de] + ld a, [de] inc de - ldi [hl],a + ldi [hl], a inc hl dec c jr nz, .loadTrademarkSymbolLoop ; Set up tilemap - ld a,$19 ; Trademark symbol - ld [$9910], a ; ... put in the superscript position - ld hl,$992f ; Bottom right corner of the logo - ld c,$c ; Tiles in a logo row + 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 + ld l, $0F ; Jump to top row jr .tilemapLoop .tilemapDone ; Turn on LCD - ld a, $91 + ld a, LCDCF_ON | LCDCF_BLK01 | LCDCF_BGON ldh [rLCDC], a - ld a, $f1 ; Packet magic, increases by 2 for every packet - ldh [_HRAM], a - ld hl, $104 ; Header start - + ld a, $F1 ; Packet magic, increases by 2 for every packet + ldh [hCommand], a + ld hl, NintendoLogo ; Header start + xor a ld c, a ; JOYP @@ -88,37 +89,37 @@ Start: ld [c], a ld a, $30 ld [c], a - - ldh a, [_HRAM] + + ldh a, [hCommand] call SendByte push hl - ld b, $e + + ld b, 14 ld d, 0 - .checksumLoop call ReadHeaderByte add d ld d, a dec b jr nz, .checksumLoop - + ; Send checksum call SendByte pop hl - - ld b, $e + + ld b, 14 .sendLoop call ReadHeaderByte call SendByte dec b jr nz, .sendLoop - + ; Done bit ld a, $20 ld [c], a ld a, $30 ld [c], a - + ; Wait 4 frames ld e, 4 ld a, 1 @@ -126,41 +127,41 @@ Start: xor a .waitLoop ldh [rIF], a - db $76 ; halt, compatible with rgbds 0.5-0.8 + halt nop dec e jr nz, .waitLoop ldh [rIE], a - + ; Update command - ldh a, [_HRAM] + ldh a, [hCommand] add 2 - ldh [_HRAM], a - + ldh [hCommand], a + ld a, $58 cp l jr nz, .sendCommand - + ; Write to sound registers for DMG compatibility - ld c, $13 - ld a, $c1 + ld c, LOW(rNR13) + ld a, $C1 ld [c], a inc c - ld a, 7 + ld a, $7 ld [c], a - + ; Init BG palette - ld a, $fc + ld a, %11_11_11_00 ldh [rBGP], a - + ; Set registers to match the original SGB boot IF DEF(SGB2) - ld a, $FF + ld a, BOOTUP_A_MGB ELSE - ld a, 1 + ld a, BOOTUP_A_DMG ENDC - ld hl, $c060 - + ld hl, $C060 + ; Boot the game jp BootGame @@ -212,8 +213,23 @@ DoubleBitsAndWriteRow: ret TrademarkSymbol: -db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c - -SECTION "BootGame", ROM0[$fe] + 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 \ No newline at end of file + ldh [rBANK], a + +SECTION "HRAM", HRAM[_HRAM] +hCommand: + ds 1 diff --git a/Makefile b/Makefile index 844057177..719ebb9e2 100644 --- a/Makefile +++ b/Makefile @@ -151,6 +151,10 @@ RGBASM := $(RGBDS)rgbasm RGBLINK := $(RGBDS)rgblink RGBGFX := $(RGBDS)rgbgfx +# RGBASM 0.7+ deprecate and remove `-h` +RGBASM_FLAGS := $(if $(filter $(shell echo 'println __RGBDS_MAJOR__ || (!__RGBDS_MAJOR__ && __RGBDS_MINOR__ > 6)' | $(RGBASM) -), $$0), -h,) --include $(OBJ)/BootROMs/ --include BootROMs/ +# RGBGFX 0.6+ replace `-h` with `-Z`, and need `-c embedded` +RGBGFX_FLAGS := $(if $(filter $(shell echo 'println __RGBDS_MAJOR__ || (!__RGBDS_MAJOR__ && __RGBDS_MINOR__ > 5)' | $(RGBASM) -), $$0), -h -u, -Z -u -c embedded) # Set compilation and linkage flags based on target, platform and configuration @@ -620,7 +624,7 @@ $(BIN)/SDL/Palettes: Misc/Palettes $(OBJ)/%.2bpp: %.png -@$(MKDIR) -p $(dir $@) - $(RGBGFX) $(if $(filter $(shell echo 'print __RGBDS_MAJOR__ || (!__RGBDS_MAJOR__ && __RGBDS_MINOR__ > 5)' | $(RGBASM) -), $$0), -h -u, -Z -u -c embedded) -o $@ $< + $(RGBGFX) $(RGBGFX_FLAGS) -o $@ $< $(OBJ)/BootROMs/SameBoyLogo.pb12: $(OBJ)/BootROMs/SameBoyLogo.2bpp $(PB12_COMPRESS) -@$(MKDIR) -p $(dir $@) @@ -633,11 +637,11 @@ $(PB12_COMPRESS): BootROMs/pb12.c $(BIN)/BootROMs/cgb0_boot.bin: BootROMs/cgb_boot.asm $(BIN)/BootROMs/agb_boot.bin: BootROMs/cgb_boot.asm $(BIN)/BootROMs/cgb_boot_fast.bin: BootROMs/cgb_boot.asm -$(BIN)/BootROMs/sgb2_boot: BootROMs/sgb_boot.asm +$(BIN)/BootROMs/sgb2_boot.bin: BootROMs/sgb_boot.asm $(BIN)/BootROMs/%.bin: BootROMs/%.asm $(OBJ)/BootROMs/SameBoyLogo.pb12 -@$(MKDIR) -p $(dir $@) - $(RGBASM) -i $(OBJ)/BootROMs/ -i BootROMs/ -o $@.tmp $< + $(RGBASM) $(RGBASM_FLAGS) -o $@.tmp $< $(RGBLINK) -x -o $@ $@.tmp @rm $@.tmp