diff --git a/CHANGES.txt b/CHANGES.txt index a95e4bd..499ac9f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,7 +4,7 @@ * Make shadow during jump more visible * Revamp instructions with visual aids * Add tutorial floor "Closet" -* SGB, GBC: Lighten green to reduce Helmholtz-Kohlrausch +* SGB, GBC: Lighten green to reduce Helmholtz-Kohlrausch illusion * SGB: make border tile 0 transparent to reduce flash during fade * Upgrade to new hardware.inc * Prepare for RGBDS 0.6: HALT NOP, LD to LDH, SET to =, MACRO name @@ -15,7 +15,9 @@ * extractcels.py: add 8x16-pixel object tile support * extractcels.py: add streaming object tile format * Make header with rgbfix +* Allow building with out-of-tree RGBDS for regression testing * Document sound effects driver, including its stream format +* Document some inspirations for the character design * how_to_encode.md: recommend CamStudio codec (CSCD) (thanks beware) * how_to_encode.md: vertical video diff --git a/README.md b/README.md index 0f1282c..8c2571a 100644 --- a/README.md +++ b/README.md @@ -48,27 +48,15 @@ harder to earn than others. Building -------- -Building the game requires [RGBDS] 0.6.2 or later, [Python] 3, -[Pillow], and [GNU Make]. Once you have these installed, -run this command: +Building the game requires [RGBDS] 0.7 or later, [Python] 3, +[Pillow], [GNU Make], and GNU Coreutils. Once you have these +installed, run this command: make -Until RGBDS 0.6.2 is released, use the development version (`master`) -instead. To install the development version on Windows without WSL: - -1. Open "Installing [RGBDS]". -2. Follow "using a development version". -3. Scroll down to "Using our CI" and follow "made available on - GitHub". -4. Under "workflow run results", follow the name of the most recent - pull request with a green checkmark next to `master`. -5. Scroll down to "Artifacts" and follow `rgbds-canary-win64`, which - is a link to a zip archive. -6. Install the programs in the archive per the instructions in - "Installing RGBDS". - -To add GNU Make to an installation of [Git for Windows], follow +If you're using Windows and not using WSL, it may be convenient to +obtain Coreutils through [Git for Windows], which contains a +distribution of MSYS2. To add GNU Make to Git for Windows, follow [evanwill's instructions] to download the latest Make without Guile from [ezwinports]. @@ -83,7 +71,7 @@ from [ezwinports]. Legal ----- Copyright 2002, 2012 Martin Korth -Copyright 2018, 2021 Damian Yerrick +Copyright 2018, 2024 Damian Yerrick This program is free software. Permission is granted to use it subject to the terms of the zlib License. See the file `LICENSE`. diff --git a/src/hardware.inc b/src/hardware.inc index c3fec32..c1a8c41 100644 --- a/src/hardware.inc +++ b/src/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 @@ -27,6 +34,21 @@ ;* Rev 3.0 - 27-Aug-20 : Register ordering, byte-based sizes, OAM additions, general cleanup (Blitter Object) ;* Rev 4.0 - 03-May-21 : Updated to use RGBDS 0.5.0 syntax, changed IEF_LCDC to IEF_STAT (Eievui) ;* Rev 4.1 - 16-Aug-21 : Added more flags, bit number defines, and offset constants for OAM and window positions (rondnelson99) +;* Rev 4.2 - 04-Sep-21 : Added CH3- and CH4-specific audio registers flags (ISSOtm) +;* 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." @@ -37,18 +59,32 @@ 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.1 ;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 _VRAM8000 EQU _VRAM -DEF _VRAM8800 EQU _VRAM+$800 -DEF _VRAM9000 EQU _VRAM+$1000 DEF _SCRN0 EQU $9800 ; $9800->$9BFF DEF _SCRN1 EQU $9C00 ; $9C00->$9FFF DEF _SRAM EQU $A000 ; $A000->$BFFF @@ -59,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 ;* ;*************************************************************************** @@ -104,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 @@ -146,6 +245,8 @@ DEF TACF_16KHZ EQU %00000011 DEF TACF_65KHZ EQU %00000010 DEF TACF_262KHZ EQU %00000001 +DEF TACB_START EQU 2 + ; -- ; -- IF ($FF0F) @@ -264,6 +365,9 @@ DEF rAUD2HIGH EQU rNR24 DEF rNR30 EQU $FF1A DEF rAUD3ENA EQU rNR30 +DEF AUD3ENA_OFF EQU %00000000 +DEF AUD3ENA_ON EQU %10000000 + ; -- ; -- AUD3LEN/NR31 ($FF1B) @@ -288,6 +392,11 @@ DEF rAUD3LEN EQU rNR31 DEF rNR32 EQU $FF1C DEF rAUD3LEVEL EQU rNR32 +DEF AUD3LEVEL_MUTE EQU %00000000 +DEF AUD3LEVEL_100 EQU %00100000 +DEF AUD3LEVEL_50 EQU %01000000 +DEF AUD3LEVEL_25 EQU %01100000 + ; -- ; -- AUD3LOW/NR33 ($FF1D) @@ -346,6 +455,9 @@ DEF rAUD4ENV EQU rNR42 DEF rNR43 EQU $FF22 DEF rAUD4POLY EQU rNR43 +DEF AUD4POLY_15STEP EQU %00000000 +DEF AUD4POLY_7STEP EQU %00001000 + ; -- ; -- AUD4GO/NR44 ($FF23) @@ -430,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 @@ -440,6 +552,15 @@ DEF LCDCF_OBJOFF EQU %00000000 ; OBJ Display DEF LCDCF_OBJON EQU %00000010 ; OBJ Display DEF LCDCF_BGOFF EQU %00000000 ; BG Display 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_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 +DEF LCDCB_BGON EQU 0 ; BG Display ; "Window Character Data Select" follows BG @@ -620,6 +741,7 @@ DEF rHDMA5 EQU $FF55 DEF HDMA5F_MODE_GP EQU %00000000 ; General Purpose DMA (W) DEF HDMA5F_MODE_HBL EQU %10000000 ; HBlank DMA (W) +DEF HDMA5B_MODE EQU 7 ; DMA mode select (W) ; -- Once DMA has started, use HDMA5F_BUSY to check when the transfer is complete DEF HDMA5F_BUSY EQU %10000000 ; 0=Busy (DMA still in progress), 1=Transfer complete (R) @@ -637,37 +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) + ; -- @@ -753,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 @@ -777,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 @@ -837,14 +1009,10 @@ DEF CART_ROM_1536KB EQU $54 ; 96 banks ; $0149 SRAM size ; these are kilobytes DEF CART_SRAM_NONE EQU 0 -DEF CART_SRAM_2KB EQU 1 ; 1 incomplete bank 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 @@ -882,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 @@ -930,18 +1098,16 @@ 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) +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/src/instructions.z80 b/src/instructions.z80 index c77b6e4..8e33021 100644 --- a/src/instructions.z80 +++ b/src/instructions.z80 @@ -180,9 +180,9 @@ pages_end: page1txt: db LF db "Libbet and the Magic Floor",LF - db "v0.08wip (2021-03-xx)",LF + db "v0.08 (2024-01-xx)",LF ; Row skipped because B=3 - ; Can't cut 1 line here because "rearranging" and "passage" are so long + ; Can't cut 1 line here because "rearranging" and "passage" are long db "One day, Libbet was",LF db "rearranging her basement",LF db "when she discovered a",LF diff --git a/src/intro.z80 b/src/intro.z80 index ec5c355..865bc88 100644 --- a/src/intro.z80 +++ b/src/intro.z80 @@ -375,7 +375,7 @@ def COPR equ $1A coprNotice: db "",LF db COPR," 2002, 2012 Martin Korth",LF - db COPR," 2018, 2023 Damian Yerrick",LF + db COPR," 2018, 2024 Damian Yerrick",LF db "",0 intro_obj_palette: