From df469b57a6df9e7127ce9a21652669a526199854 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Tue, 13 May 2025 14:53:13 -0400 Subject: [PATCH 01/27] Update actions/checkout to v4 --- .github/workflows/testing.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 29f90d4..7453da2 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -7,7 +7,7 @@ jobs: macos-testing: runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install RGBDS run: | brew install rgbds @@ -18,7 +18,7 @@ jobs: windows-testing: runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install RGBDS run: | # Find the URL of the latest Win64 release with the GitHub API @@ -30,4 +30,4 @@ jobs: Expand-Archive rgbds.zip - name: Run rgbasm on hardware.inc run: | - rgbds/rgbasm.exe hardware.inc \ No newline at end of file + rgbds/rgbasm.exe hardware.inc From 384fd9d68e38f97f1408989f279ce7c382236662 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Tue, 13 May 2025 14:53:34 -0400 Subject: [PATCH 02/27] Update hardware.inc to version 4.10.0 - Add more constants - Deprecate some alias constants - Move change log to HISTORY.md file - Regroup and reformat constants - Define `F`lags in terms of shifted `B`its --- HISTORY.md | 81 ++ README.md | 21 +- hardware.inc | 2221 +++++++++++++++++++++++++------------------------- 3 files changed, 1197 insertions(+), 1126 deletions(-) create mode 100644 HISTORY.md diff --git a/HISTORY.md b/HISTORY.md new file mode 100644 index 0000000..ad11dff --- /dev/null +++ b/HISTORY.md @@ -0,0 +1,81 @@ +# History + +- **Rev 1.1** - 1997-07-15 + - Added define check +- **Rev 1.2** - 1997-07-18 + - Added revision check macro +- **Rev 1.3** - 1997-07-19 + - Updated syntax for RGBASM 1.05 +- **Rev 1.4** - 1997-07-27 + - Updated subroutine prefixes +- **Rev 1.5** - 1997-08-15 + - Added `_HRAM` constant + - Added `PAD*` constants for `rP1` register + - Added `CART*` MBC constants + - Added `NINTENDO_LOGO` macro +- **Rev 1.6** - 1997-11-30 + - Added `rDIV`, `rTIMA`, `rTMA`, and `rTAC` registers +- **Rev 1.7** - 1998-01-31 + - Added `_SCRN0` and `_SCRN1` constants +- **Rev 1.8** - 1998-02-15 + - Added `rSB` and `rSC` registers +- **Rev 1.9** - 1998-02-16 + - Converted I/O registers to `$FFxx` format +- **Rev 2.0** + - Added GBC registers +- **Rev 2.1** + - Added MBC5 and cart RAM enable/disable constants +- **Rev 2.2** + - Fixed `NR42`, `NR43`, and `NR44` constants +- **Rev 2.3** + - Fixed incorrect `_HRAM` constant +- **Rev 2.4** - 2013-04-27 *(AntonioND)* + - Added some `CART_*` MBC constants +- **Rev 2.5** - 2015-05-03 *(AntonioND)* + - Fixed formatting +- **Rev 2.6** - 2016-04-09 *(AntonioND)* + - Added GBC `OAMF_*` and `CART_*` constants +- **Rev 2.7** - 2019-01-19 *(ISSOtm)* + - Added `rPCM12` and `rPCM34` registers +- **Rev 2.8** - 2019-02-03 *(Álvaro Cuesta)* + - Added flag values for audio registers +- **Rev 2.9** - 2020-02-28 + - Added `P1F_*` flag values for `rP1F` register +- **Rev 3.0** - 2020-08-27 *(Blitter Object)* + - Register ordering + - Byte-based sizes + - OAM additions + - General cleanup +- **Rev 4.0** - 2021-05-03 *(Eievui)* + - Updated to use RGBASM 0.5.0 syntax + - Changed `IEF_LCDC` to `IEF_STAT` +- **Rev 4.1** - 2021-08-16 *(rondnelson99)* + - Added more flags, bit number constants, and offset constants for OAM and window positions +- **Rev 4.2** - 2021-09-04 *(ISSOtm)* + - Added CH3- and CH4-specific audio registers flags +- **Rev 4.3** - 2021-11-07 *(Eievui)* + - Deprecate VRAM address constants +- **Rev 4.4** - 2022-01-11 *(avivace)* + - Deprecate VRAM `CART_SRAM_2KB` constant +- **Rev 4.5** - 2022-03-03 *(sukus)* + - Added bit number definitions for `OCPS`, `BCPS` and `LCDC` +- **Rev 4.6** - 2022-06-15 + - Added MBC3 registers and special values +- **Rev 4.7.0** - 2022-06-27 + - Added alternate names for some constants +- **Rev 4.7.1** - 2022-07-05 + - Added `RPB_LED_ON` constant +- **Rev 4.8.0** - 2022-10-25 *(zlago)* + - Changed background addressing constants +- **Rev 4.8.1** - 2023-04-29 *(rbong)* + - Added `rOPRI` +- **Rev 4.9.0** - 2023-06-24 *(sukus)* + - Added definitions for interrupt vectors +- **Rev 4.9.1** - 2023-09-11 + - Added repository link and CC0 waiver notice +- **Rev 4.9.2** - 2024-08-18 *(DevEd)* + - Corrected `CART_ROM_MBC5_BAT` to `CART_ROM_MBC5_RAM` +- **Rev 4.10.0** - 2025-05-13 *(Rangi42)* + - Moved revision history to separate HISTORY.md file + - Changed formatting + - Added `_ROM` and `_ROMBANK` constants diff --git a/README.md b/README.md index 063467f..cd05fa2 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,21 @@ # `hardware.inc` -### Game Boy Hardware definitions +## Game Boy hardware definitions `hardware.inc` has been the standard include file containing Game Boy hardware definitions for use in [RGBDS](https://rgbds.gbdev.io) projects for over 20 years. -The file was originally created by Jeff Frohwein in 1997, who still hosts [his latest version (2.3)](http://www.devrs.com/gb/files/hardware.zip) on his great [Dev'rs](http://devrs.com) website. +The file was originally created by Jeff Frohwein in 1997. Although Jeff tried to track version updates with a rudimentary change log at the top of the file, people have made small changes throughout the years, often without bumping the version number. -Although Jeff tried to version control the file with a rudimentary change log at the top of the file, people have added small changes throughout the years, often without bumping the version number. - -This repo has become the new official reference for `hardware.inc`, using [@AntonioND](http://github.com/AntonioND)'s fork as the baseline. +This repository has become the official reference for `hardware.inc`, using [@AntonioND](https://github.com/AntonioND)'s fork as the baseline. ## Contributing -This repository's `master` branch should be considered production; -Each commit represents a new release, requiring the embedded version number to be bumped (and an entry to be added to the changelog at the beginning of the file). - -We follow [semantic versioning](https://semver.org); -Breaking changes (such as those in [72ec03f](https://github.com/gbdev/hardware.inc/commit/72ec03f835e72be83a1ef189a4a9eac0fbdf39e2)) increase the major version, backwards-compatible changes (typically additions) only increase the minor version, and bugfixes only increase the patch level. +This repository's `master` branch should be considered the production version. +Each commit represents a new release, so each one should update the embedded version number in `hardware.inc` and the change log in `HISTORY.md`. -Changes to the comments should be considered a bugfix. +We follow [semantic versioning](https://semver.org). +Breaking changes increase the major version, backwards-compatible changes (typically new additions) only increase the minor version, and bug fixes (including changes to the comments) only increase the patch level. +(An example of a breaking change is when `hardware.inc` 4.0 updated its syntax for compatibility with RGBDS 0.5.0, breaking compatibility with older RGBDS versions.) ## Contributors @@ -26,5 +23,5 @@ Changes to the comments should be considered a bugfix. * Carsten Sørensen (whose ideas Jeff based his file on) * Jeff Frohwein * AntonioND -* BlitterObjectBob, tobiasvl, ISSOtm, avivace, Eievui, QuinnPainter, rondnelson99, daid, Hacktix, sukus21, alvaro-cuesta, basxto +* BlitterObjectBob, tobiasvl, ISSOtm, Rangi42, avivace, Eievui, QuinnPainter, rondnelson99, daid, Hacktix, sukus21, alvaro-cuesta, basxto * Probably lots of other people who have added to the file throughout the years diff --git a/hardware.inc b/hardware.inc index f2e6260..efab3e1 100644 --- a/hardware.inc +++ b/hardware.inc @@ -1,1114 +1,1107 @@ -;* -;* Game Boy 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 -;* Rev 1.4 - 27-Jul-97 : Modified for new subroutine prefixes -;* Rev 1.5 - 15-Aug-97 : Added _HRAM, PAD, CART defines -;* : and Nintendo Logo -;* Rev 1.6 - 30-Nov-97 : Added rDIV, rTIMA, rTMA, & rTAC -;* Rev 1.7 - 31-Jan-98 : Added _SCRN0, _SCRN1 -;* Rev 1.8 - 15-Feb-98 : Added rSB, rSC -;* Rev 1.9 - 16-Feb-98 : Converted I/O registers to $FFXX format -;* Rev 2.0 - : Added GBC registers -;* Rev 2.1 - : Added MBC5 & cart RAM enable/disable defines -;* Rev 2.2 - : Fixed NR42,NR43, & NR44 equates -;* Rev 2.3 - : Fixed incorrect _HRAM equate -;* Rev 2.4 - 27-Apr-13 : Added some cart defines (AntonioND) -;* Rev 2.5 - 03-May-15 : Fixed format (AntonioND) -;* Rev 2.6 - 09-Apr-16 : Added GBC OAM and cart defines (AntonioND) -;* Rev 2.7 - 19-Jan-19 : Added rPCMXX (ISSOtm) -;* Rev 2.8 - 03-Feb-19 : Added audio registers flags (Álvaro Cuesta) -;* Rev 2.9 - 28-Feb-20 : Added utility rP1 constants -;* 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 -;* Rev 4.9.2 - 18-Aug-24 : Corrected CART_ROM_MBC5_BAT to CART_ROM_MBC5_RAM (DevEd) - - -; 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." -ENDC - -; If all of these are already defined, don't do it again. - - 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 - DEF CUR_VER equs "4,9,2" ; ** 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 -DEF _SRAM EQU $A000 ; $A000->$BFFF -DEF _RAM EQU $C000 ; $C000->$CFFF / $C000->$DFFF -DEF _RAMBANK EQU $D000 ; $D000->$DFFF -DEF _OAMRAM EQU $FE00 ; $FE00->$FE9F -DEF _IO EQU $FF00 ; $FF00->$FF7F,$FFFF -DEF _AUD3WAVERAM EQU $FF30 ; $FF30->$FF3F -DEF _HRAM EQU $FF80 ; $FF80->$FFFE - - -;*************************************************************************** -;* -;* 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 - - -;*************************************************************************** -;* -;* Memory-mapped registers -;* -;*************************************************************************** - -; -- -; -- P1 ($FF00) -; -- Register for reading joy pad info. (R/W) -; -- -DEF rP1 EQU $FF00 - -DEF P1F_5 EQU %00100000 ; P15 out port, set to 0 to get buttons -DEF P1F_4 EQU %00010000 ; P14 out port, set to 0 to get dpad -DEF P1F_3 EQU %00001000 ; P13 in port -DEF P1F_2 EQU %00000100 ; P12 in port -DEF P1F_1 EQU %00000010 ; P11 in port -DEF P1F_0 EQU %00000001 ; P10 in port - -DEF P1F_GET_DPAD EQU P1F_5 -DEF P1F_GET_BTN EQU P1F_4 -DEF P1F_GET_NONE EQU P1F_4 | P1F_5 - - -; -- -; -- SB ($FF01) -; -- Serial Transfer Data (R/W) -; -- -DEF rSB EQU $FF01 - - -; -- -; -- SC ($FF02) -; -- Serial I/O Control (R/W) -; -- -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 SCB_START EQU 7 -DEF SCB_SPEED EQU 1 -DEF SCB_SOURCE EQU 0 - -; -- -; -- DIV ($FF04) -; -- Divider register (R/W) -; -- -DEF rDIV EQU $FF04 - - -; -- -; -- TIMA ($FF05) -; -- Timer counter (R/W) -; -- -DEF rTIMA EQU $FF05 - - -; -- -; -- TMA ($FF06) -; -- Timer modulo (R/W) -; -- -DEF rTMA EQU $FF06 - - -; -- -; -- TAC ($FF07) -; -- Timer control (R/W) -; -- -DEF rTAC EQU $FF07 - -DEF TACF_START EQU %00000100 -DEF TACF_STOP EQU %00000000 -DEF TACF_4KHZ EQU %00000000 -DEF TACF_16KHZ EQU %00000011 -DEF TACF_65KHZ EQU %00000010 -DEF TACF_262KHZ EQU %00000001 - -DEF TACB_START EQU 2 - - -; -- -; -- IF ($FF0F) -; -- Interrupt Flag (R/W) -; -- -DEF rIF EQU $FF0F - - -; -- -; -- AUD1SWEEP/NR10 ($FF10) -; -- Sweep register (R/W) -; -- -; -- Bit 6-4 - Sweep Time -; -- Bit 3 - Sweep Increase/Decrease -; -- 0: Addition (frequency increases???) -; -- 1: Subtraction (frequency increases???) -; -- Bit 2-0 - Number of sweep shift (# 0-7) -; -- Sweep Time: (n*7.8ms) -; -- -DEF rNR10 EQU $FF10 -DEF rAUD1SWEEP EQU rNR10 - -DEF AUD1SWEEP_UP EQU %00000000 -DEF AUD1SWEEP_DOWN EQU %00001000 - - -; -- -; -- AUD1LEN/NR11 ($FF11) -; -- Sound length/Wave pattern duty (R/W) -; -- -; -- Bit 7-6 - Wave Pattern Duty (00:12.5% 01:25% 10:50% 11:75%) -; -- Bit 5-0 - Sound length data (# 0-63) -; -- -DEF rNR11 EQU $FF11 -DEF rAUD1LEN EQU rNR11 - - -; -- -; -- AUD1ENV/NR12 ($FF12) -; -- Envelope (R/W) -; -- -; -- Bit 7-4 - Initial value of envelope -; -- Bit 3 - Envelope UP/DOWN -; -- 0: Decrease -; -- 1: Range of increase -; -- Bit 2-0 - Number of envelope sweep (# 0-7) -; -- -DEF rNR12 EQU $FF12 -DEF rAUD1ENV EQU rNR12 - - -; -- -; -- AUD1LOW/NR13 ($FF13) -; -- Frequency low byte (W) -; -- -DEF rNR13 EQU $FF13 -DEF rAUD1LOW EQU rNR13 - - -; -- -; -- AUD1HIGH/NR14 ($FF14) -; -- Frequency high byte (W) -; -- -; -- Bit 7 - Initial (when set, sound restarts) -; -- Bit 6 - Counter/consecutive selection -; -- Bit 2-0 - Frequency's higher 3 bits -; -- -DEF rNR14 EQU $FF14 -DEF rAUD1HIGH EQU rNR14 - - -; -- -; -- AUD2LEN/NR21 ($FF16) -; -- Sound Length; Wave Pattern Duty (R/W) -; -- -; -- see AUD1LEN for info -; -- -DEF rNR21 EQU $FF16 -DEF rAUD2LEN EQU rNR21 - - -; -- -; -- AUD2ENV/NR22 ($FF17) -; -- Envelope (R/W) -; -- -; -- see AUD1ENV for info -; -- -DEF rNR22 EQU $FF17 -DEF rAUD2ENV EQU rNR22 - - -; -- -; -- AUD2LOW/NR23 ($FF18) -; -- Frequency low byte (W) -; -- -DEF rNR23 EQU $FF18 -DEF rAUD2LOW EQU rNR23 - - -; -- -; -- AUD2HIGH/NR24 ($FF19) -; -- Frequency high byte (W) -; -- -; -- see AUD1HIGH for info -; -- -DEF rNR24 EQU $FF19 -DEF rAUD2HIGH EQU rNR24 - - -; -- -; -- AUD3ENA/NR30 ($FF1A) -; -- Sound on/off (R/W) -; -- -; -- Bit 7 - Sound ON/OFF (1=ON,0=OFF) -; -- -DEF rNR30 EQU $FF1A -DEF rAUD3ENA EQU rNR30 - -DEF AUD3ENA_OFF EQU %00000000 -DEF AUD3ENA_ON EQU %10000000 - - -; -- -; -- AUD3LEN/NR31 ($FF1B) -; -- Sound length (R/W) -; -- -; -- Bit 7-0 - Sound length -; -- -DEF rNR31 EQU $FF1B -DEF rAUD3LEN EQU rNR31 - - -; -- -; -- AUD3LEVEL/NR32 ($FF1C) -; -- Select output level -; -- -; -- Bit 6-5 - Select output level -; -- 00: 0/1 (mute) -; -- 01: 1/1 -; -- 10: 1/2 -; -- 11: 1/4 -; -- -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) -; -- Frequency low byte (W) -; -- -; -- see AUD1LOW for info -; -- -DEF rNR33 EQU $FF1D -DEF rAUD3LOW EQU rNR33 - - -; -- -; -- AUD3HIGH/NR34 ($FF1E) -; -- Frequency high byte (W) -; -- -; -- see AUD1HIGH for info -; -- -DEF rNR34 EQU $FF1E -DEF rAUD3HIGH EQU rNR34 - - -; -- -; -- AUD4LEN/NR41 ($FF20) -; -- Sound length (R/W) -; -- -; -- Bit 5-0 - Sound length data (# 0-63) -; -- -DEF rNR41 EQU $FF20 -DEF rAUD4LEN EQU rNR41 - - -; -- -; -- AUD4ENV/NR42 ($FF21) -; -- Envelope (R/W) -; -- -; -- see AUD1ENV for info -; -- -DEF rNR42 EQU $FF21 -DEF rAUD4ENV EQU rNR42 - - -; -- -; -- AUD4POLY/NR43 ($FF22) -; -- Polynomial counter (R/W) -; -- -; -- Bit 7-4 - Selection of the shift clock frequency of the (scf) -; -- polynomial counter (0000-1101) -; -- freq=drf*1/2^scf (not sure) -; -- Bit 3 - Selection of the polynomial counter's step -; -- 0: 15 steps -; -- 1: 7 steps -; -- Bit 2-0 - Selection of the dividing ratio of frequencies (drf) -; -- 000: f/4 001: f/8 010: f/16 011: f/24 -; -- 100: f/32 101: f/40 110: f/48 111: f/56 (f=4.194304 Mhz) -; -- -DEF rNR43 EQU $FF22 -DEF rAUD4POLY EQU rNR43 - -DEF AUD4POLY_15STEP EQU %00000000 -DEF AUD4POLY_7STEP EQU %00001000 - - -; -- -; -- AUD4GO/NR44 ($FF23) -; -- -; -- Bit 7 - Initial (when set, sound restarts) -; -- Bit 6 - Counter/consecutive selection -; -- -DEF rNR44 EQU $FF23 -DEF rAUD4GO EQU rNR44 - - -; -- -; -- AUDVOL/NR50 ($FF24) -; -- Channel control / ON-OFF / Volume (R/W) -; -- -; -- Bit 7 - Vin->SO2 ON/OFF (left) -; -- Bit 6-4 - SO2 output level (left speaker) (# 0-7) -; -- Bit 3 - Vin->SO1 ON/OFF (right) -; -- Bit 2-0 - SO1 output level (right speaker) (# 0-7) -; -- -DEF rNR50 EQU $FF24 -DEF rAUDVOL EQU rNR50 - -DEF AUDVOL_VIN_LEFT EQU %10000000 ; SO2 -DEF AUDVOL_VIN_RIGHT EQU %00001000 ; SO1 - - -; -- -; -- AUDTERM/NR51 ($FF25) -; -- Selection of Sound output terminal (R/W) -; -- -; -- Bit 7 - Output channel 4 to SO2 terminal (left) -; -- Bit 6 - Output channel 3 to SO2 terminal (left) -; -- Bit 5 - Output channel 2 to SO2 terminal (left) -; -- Bit 4 - Output channel 1 to SO2 terminal (left) -; -- Bit 3 - Output channel 4 to SO1 terminal (right) -; -- Bit 2 - Output channel 3 to SO1 terminal (right) -; -- Bit 1 - Output channel 2 to SO1 terminal (right) -; -- Bit 0 - Output channel 1 to SO1 terminal (right) -; -- -DEF rNR51 EQU $FF25 -DEF rAUDTERM EQU rNR51 - -; SO2 -DEF AUDTERM_4_LEFT EQU %10000000 -DEF AUDTERM_3_LEFT EQU %01000000 -DEF AUDTERM_2_LEFT EQU %00100000 -DEF AUDTERM_1_LEFT EQU %00010000 -; SO1 -DEF AUDTERM_4_RIGHT EQU %00001000 -DEF AUDTERM_3_RIGHT EQU %00000100 -DEF AUDTERM_2_RIGHT EQU %00000010 -DEF AUDTERM_1_RIGHT EQU %00000001 - - -; -- -; -- AUDENA/NR52 ($FF26) -; -- Sound on/off (R/W) -; -- -; -- Bit 7 - All sound on/off (sets all audio regs to 0!) -; -- Bit 3 - Sound 4 ON flag (read only) -; -- Bit 2 - Sound 3 ON flag (read only) -; -- Bit 1 - Sound 2 ON flag (read only) -; -- Bit 0 - Sound 1 ON flag (read only) -; -- -DEF rNR52 EQU $FF26 -DEF rAUDENA EQU rNR52 - -DEF AUDENA_ON EQU %10000000 -DEF AUDENA_OFF EQU %00000000 ; sets all audio regs to 0! - - -; -- -; -- LCDC ($FF40) -; -- LCD Control (R/W) -; -- -DEF rLCDC EQU $FF40 - -DEF LCDCF_OFF EQU %00000000 ; LCD Control Operation -DEF LCDCF_ON EQU %10000000 ; LCD Control Operation -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_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 -DEF LCDCF_OBJ16 EQU %00000100 ; OBJ Construction -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 - - -; -- -; -- STAT ($FF41) -; -- LCDC Status (R/W) -; -- -DEF rSTAT EQU $FF41 - -DEF STATF_LYC EQU %01000000 ; LYC=LY Coincidence (Selectable) -DEF STATF_MODE10 EQU %00100000 ; Mode 10 -DEF STATF_MODE01 EQU %00010000 ; Mode 01 (V-Blank) -DEF STATF_MODE00 EQU %00001000 ; Mode 00 (H-Blank) -DEF STATF_LYCF EQU %00000100 ; Coincidence Flag -DEF STATF_HBL EQU %00000000 ; H-Blank -DEF STATF_VBL EQU %00000001 ; V-Blank -DEF STATF_OAM EQU %00000010 ; OAM-RAM is used by system -DEF STATF_LCD EQU %00000011 ; Both OAM and VRAM used by system -DEF STATF_BUSY EQU %00000010 ; When set, VRAM access is unsafe - -DEF STATB_LYC EQU 6 -DEF STATB_MODE10 EQU 5 -DEF STATB_MODE01 EQU 4 -DEF STATB_MODE00 EQU 3 -DEF STATB_LYCF EQU 2 -DEF STATB_BUSY EQU 1 - -; -- -; -- SCY ($FF42) -; -- Scroll Y (R/W) -; -- -DEF rSCY EQU $FF42 - - -; -- -; -- SCX ($FF43) -; -- Scroll X (R/W) -; -- -DEF rSCX EQU $FF43 - - -; -- -; -- LY ($FF44) -; -- LCDC Y-Coordinate (R) -; -- -; -- Values range from 0->153. 144->153 is the VBlank period. -; -- -DEF rLY EQU $FF44 - - -; -- -; -- LYC ($FF45) -; -- LY Compare (R/W) -; -- -; -- When LY==LYC, STATF_LYCF will be set in STAT -; -- -DEF rLYC EQU $FF45 - - -; -- -; -- DMA ($FF46) -; -- DMA Transfer and Start Address (W) -; -- -DEF rDMA EQU $FF46 - - -; -- -; -- BGP ($FF47) -; -- BG Palette Data (W) -; -- -; -- Bit 7-6 - Intensity for %11 -; -- Bit 5-4 - Intensity for %10 -; -- Bit 3-2 - Intensity for %01 -; -- Bit 1-0 - Intensity for %00 -; -- -DEF rBGP EQU $FF47 - - -; -- -; -- OBP0 ($FF48) -; -- Object Palette 0 Data (W) -; -- -; -- See BGP for info -; -- -DEF rOBP0 EQU $FF48 - - -; -- -; -- OBP1 ($FF49) -; -- Object Palette 1 Data (W) -; -- -; -- See BGP for info -; -- -DEF rOBP1 EQU $FF49 - - -; -- -; -- WY ($FF4A) -; -- Window Y Position (R/W) -; -- -; -- 0 <= WY <= 143 -; -- When WY = 0, the window is displayed from the top edge of the LCD screen. -; -- -DEF rWY EQU $FF4A - - -; -- -; -- WX ($FF4B) -; -- Window X Position (R/W) -; -- -; -- 7 <= WX <= 166 -; -- When WX = 7, the window is displayed from the left edge of the LCD screen. -; -- Values of 0-6 and 166 are unreliable due to hardware bugs. -; -- -DEF rWX EQU $FF4B - -DEF WX_OFS EQU 7 ; add this to a screen position to get a WX position - - -; -- -; -- SPEED ($FF4D) -; -- Select CPU Speed (R/W) -; -- -DEF rKEY1 EQU $FF4D -DEF rSPD EQU rKEY1 - -DEF KEY1F_DBLSPEED EQU %10000000 ; 0=Normal Speed, 1=Double Speed (R) -DEF KEY1F_PREPARE EQU %00000001 ; 0=No, 1=Prepare (R/W) - - -; -- -; -- VBK ($FF4F) -; -- Select Video RAM Bank (R/W) -; -- -; -- Bit 0 - Bank Specification (0: Specify Bank 0; 1: Specify Bank 1) -; -- -DEF rVBK EQU $FF4F - - -; -- -; -- HDMA1 ($FF51) -; -- High byte for Horizontal Blanking/General Purpose DMA source address (W) -; -- CGB Mode Only -; -- -DEF rHDMA1 EQU $FF51 - - -; -- -; -- HDMA2 ($FF52) -; -- Low byte for Horizontal Blanking/General Purpose DMA source address (W) -; -- CGB Mode Only -; -- -DEF rHDMA2 EQU $FF52 - - -; -- -; -- HDMA3 ($FF53) -; -- High byte for Horizontal Blanking/General Purpose DMA destination address (W) -; -- CGB Mode Only -; -- -DEF rHDMA3 EQU $FF53 - - -; -- -; -- HDMA4 ($FF54) -; -- Low byte for Horizontal Blanking/General Purpose DMA destination address (W) -; -- CGB Mode Only -; -- -DEF rHDMA4 EQU $FF54 - - -; -- -; -- HDMA5 ($FF55) -; -- Transfer length (in tiles minus 1)/mode/start for Horizontal Blanking, General Purpose DMA (R/W) -; -- CGB Mode Only -; -- -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) - - -; -- -; -- RP ($FF56) -; -- Infrared Communications Port (R/W) -; -- CGB Mode Only -; -- -DEF rRP EQU $FF56 - -DEF RPF_ENREAD EQU %11000000 -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/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/BGPD ($FF69) -; -- Background Color Palette Data (aka Background Palette Data) (R/W) -; -- -DEF rBCPD EQU $FF69 -DEF rBGPD EQU rBCPD - - -; -- -; -- 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/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) - - - -; -- -; -- SMBK/SVBK ($FF70) -; -- Select Main RAM Bank (R/W) -; -- -; -- Bit 2-0 - Bank Specification (0,1: Specify Bank 1; 2-7: Specify Banks 2-7) -; -- -DEF rSVBK EQU $FF70 -DEF rSMBK EQU rSVBK - - -; -- -; -- PCM12 ($FF76) -; -- Sound channel 1&2 PCM amplitude (R) -; -- -; -- Bit 7-4 - Copy of sound channel 2's PCM amplitude -; -- Bit 3-0 - Copy of sound channel 1's PCM amplitude -; -- -DEF rPCM12 EQU $FF76 - - -; -- -; -- PCM34 ($FF77) -; -- Sound channel 3&4 PCM amplitude (R) -; -- -; -- Bit 7-4 - Copy of sound channel 4's PCM amplitude -; -- Bit 3-0 - Copy of sound channel 3's PCM amplitude -; -- -DEF rPCM34 EQU $FF77 - - -; -- -; -- IE ($FFFF) -; -- Interrupt Enable (R/W) -; -- -DEF rIE EQU $FFFF - -DEF IEF_HILO EQU %00010000 ; Transition from High to Low of Pin number P10-P13 -DEF IEF_SERIAL EQU %00001000 ; Serial I/O transfer end -DEF IEF_TIMER EQU %00000100 ; Timer Overflow -DEF IEF_STAT EQU %00000010 ; STAT -DEF IEF_VBLANK EQU %00000001 ; V-Blank - -DEF IEB_HILO EQU 4 -DEF IEB_SERIAL EQU 3 -DEF IEB_TIMER EQU 2 -DEF IEB_STAT EQU 1 -DEF IEB_VBLANK EQU 0 - - -;*************************************************************************** -;* -;* Flags common to multiple sound channels -;* -;*************************************************************************** - -; -- -; -- Square wave duty cycle -; -- -; -- Can be used with AUD1LEN and AUD2LEN -; -- See AUD1LEN for more info -; -- -DEF AUDLEN_DUTY_12_5 EQU %00000000 ; 12.5% -DEF AUDLEN_DUTY_25 EQU %01000000 ; 25% -DEF AUDLEN_DUTY_50 EQU %10000000 ; 50% -DEF AUDLEN_DUTY_75 EQU %11000000 ; 75% - - -; -- -; -- Audio envelope flags -; -- -; -- Can be used with AUD1ENV, AUD2ENV, AUD4ENV -; -- See AUD1ENV for more info -; -- -DEF AUDENV_UP EQU %00001000 -DEF AUDENV_DOWN EQU %00000000 - - -; -- -; -- Audio trigger flags -; -- -; -- 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 - - -;*************************************************************************** -;* -;* CPU values on bootup (a=type, b=qualifier) -;* -;*************************************************************************** - -DEF BOOTUP_A_DMG EQU $01 ; Dot Matrix Game -DEF BOOTUP_A_CGB EQU $11 ; Color Game Boy -DEF BOOTUP_A_MGB EQU $FF ; Mini Game Boy (Pocket Game Boy) - -; if a=BOOTUP_A_CGB, bit 0 in b can be checked to determine if real CGB or -; other system running in GBC mode -DEF BOOTUP_B_CGB EQU %00000000 -DEF BOOTUP_B_AGB EQU %00000001 ; GBA, GBA SP, Game Boy Player, or New GBA SP - - -;*************************************************************************** -;* -;* 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 Game Boy) -;* (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 Game Boy compatibility code -DEF CART_COMPATIBLE_DMG EQU $00 -DEF CART_COMPATIBLE_DMG_GBC EQU $80 -DEF CART_COMPATIBLE_GBC EQU $C0 - -; $0146 Game Boy/Super Game Boy indicator -DEF CART_INDICATOR_GB EQU $00 -DEF CART_INDICATOR_SGB EQU $03 - -; $0147 Cartridge type -DEF CART_ROM EQU $00 -DEF CART_ROM_MBC1 EQU $01 -DEF CART_ROM_MBC1_RAM EQU $02 -DEF CART_ROM_MBC1_RAM_BAT EQU $03 -DEF CART_ROM_MBC2 EQU $05 -DEF CART_ROM_MBC2_BAT EQU $06 -DEF CART_ROM_RAM EQU $08 -DEF CART_ROM_RAM_BAT EQU $09 -DEF CART_ROM_MMM01 EQU $0B -DEF CART_ROM_MMM01_RAM EQU $0C -DEF CART_ROM_MMM01_RAM_BAT EQU $0D -DEF CART_ROM_MBC3_BAT_RTC EQU $0F -DEF CART_ROM_MBC3_RAM_BAT_RTC EQU $10 -DEF CART_ROM_MBC3 EQU $11 -DEF CART_ROM_MBC3_RAM EQU $12 -DEF CART_ROM_MBC3_RAM_BAT EQU $13 -DEF CART_ROM_MBC5 EQU $19 -DEF CART_ROM_MBC5_RAM EQU $1A -DEF CART_ROM_MBC5_RAM_BAT EQU $1B -DEF CART_ROM_MBC5_RUMBLE EQU $1C -DEF CART_ROM_MBC5_RAM_RUMBLE EQU $1D -DEF CART_ROM_MBC5_RAM_BAT_RUMBLE EQU $1E -DEF CART_ROM_MBC7_RAM_BAT_GYRO EQU $22 -DEF CART_ROM_POCKET_CAMERA EQU $FC -DEF CART_ROM_BANDAI_TAMA5 EQU $FD -DEF CART_ROM_HUDSON_HUC3 EQU $FE -DEF CART_ROM_HUDSON_HUC1 EQU $FF - -; $0148 ROM size -; these are kilobytes -DEF CART_ROM_32KB EQU $00 ; 2 banks -DEF CART_ROM_64KB EQU $01 ; 4 banks -DEF CART_ROM_128KB EQU $02 ; 8 banks -DEF CART_ROM_256KB EQU $03 ; 16 banks -DEF CART_ROM_512KB EQU $04 ; 32 banks -DEF CART_ROM_1024KB EQU $05 ; 64 banks -DEF CART_ROM_2048KB EQU $06 ; 128 banks -DEF CART_ROM_4096KB EQU $07 ; 256 banks -DEF CART_ROM_8192KB EQU $08 ; 512 banks -DEF CART_ROM_1152KB EQU $52 ; 72 banks -DEF CART_ROM_1280KB EQU $53 ; 80 banks -DEF CART_ROM_1536KB EQU $54 ; 96 banks - -; $0149 SRAM size -; these are kilobytes -DEF CART_SRAM_NONE EQU 0 -DEF CART_SRAM_8KB EQU 2 ; 1 bank -DEF CART_SRAM_32KB EQU 3 ; 4 banks -DEF CART_SRAM_128KB EQU 4 ; 16 banks - -; $014A Destination code -DEF CART_DEST_JAPANESE EQU $00 -DEF CART_DEST_NON_JAPANESE EQU $01 - - -;*************************************************************************** -;* -;* Keypad related -;* -;*************************************************************************** - -DEF PADF_DOWN EQU $80 -DEF PADF_UP EQU $40 -DEF PADF_LEFT EQU $20 -DEF PADF_RIGHT EQU $10 -DEF PADF_START EQU $08 -DEF PADF_SELECT EQU $04 -DEF PADF_B EQU $02 -DEF PADF_A EQU $01 - -DEF PADB_DOWN EQU $7 -DEF PADB_UP EQU $6 -DEF PADB_LEFT EQU $5 -DEF PADB_RIGHT EQU $4 -DEF PADB_START EQU $3 -DEF PADB_SELECT EQU $2 -DEF PADB_B EQU $1 -DEF PADB_A EQU $0 - - -;*************************************************************************** -;* -;* Screen related -;* -;*************************************************************************** - -DEF SCRN_X EQU 160 ; Width 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 - -DEF SCRN_VX EQU 256 ; Virtual width of screen in pixels -DEF SCRN_VY EQU 256 ; Virtual height of screen in pixels -DEF SCRN_VX_B EQU 32 ; Virtual width of screen in bytes -DEF SCRN_VY_B EQU 32 ; Virtual height of screen in bytes - - -;*************************************************************************** -;* -;* OAM related -;* -;*************************************************************************** - -; OAM attributes -; each entry in OAM RAM is 4 bytes (sizeof_OAM_ATTRS) -RSRESET -DEF OAMA_Y RB 1 ; y pos plus 16 -DEF OAMA_X RB 1 ; x pos plus 8 -DEF OAMA_TILEID RB 1 ; tile id -DEF OAMA_FLAGS RB 1 ; flags (see below) -DEF sizeof_OAM_ATTRS RB 0 - -DEF OAM_Y_OFS EQU 16 ; add this to a screen-relative Y position to get an OAM Y position -DEF OAM_X_OFS EQU 8 ; add this to a screen-relative X position to get an OAM X position - -DEF OAM_COUNT EQU 40 ; number of OAM entries in OAM RAM - -; flags -DEF OAMF_PRI EQU %10000000 ; Priority -DEF OAMF_YFLIP EQU %01000000 ; Y flip -DEF OAMF_XFLIP EQU %00100000 ; X flip -DEF OAMF_PAL0 EQU %00000000 ; Palette number; 0,1 (DMG) -DEF OAMF_PAL1 EQU %00010000 ; Palette number; 0,1 (DMG) -DEF OAMF_BANK0 EQU %00000000 ; Bank number; 0,1 (GBC) -DEF OAMF_BANK1 EQU %00001000 ; Bank number; 0,1 (GBC) - -DEF OAMF_PALMASK EQU %00000111 ; Palette (GBC) - -DEF OAMB_PRI EQU 7 ; Priority -DEF OAMB_YFLIP EQU 6 ; Y flip -DEF OAMB_XFLIP EQU 5 ; X flip -DEF OAMB_PAL1 EQU 4 ; Palette number; 0,1 (DMG) -DEF OAMB_BANK1 EQU 3 ; Bank number; 0,1 (GBC) - - -; 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 +;****************************************************************************** +; Game Boy hardware definitions +; https://github.com/gbdev/hardware.inc +;****************************************************************************** + +; 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 + +; If this file was already included, don't do it again +if !def(HARDWARE_INC) + +; Check for the minimum supported RGBDS version +if !def(__RGBDS_MAJOR__) || !def(__RGBDS_MINOR__) || !def(__RGBDS_PATCH__) + fail "This version of 'hardware.inc' requires RGBDS version 0.5.0 or later" +endc +if __RGBDS_MAJOR__ == 0 && __RGBDS_MINOR__ < 5 + fail "This version of 'hardware.inc' requires RGBDS version 0.5.0 or later." +endc + +; Define the include guard and the current hardware.inc version +; (do this after the RGBDS version check since the `def` syntax depends on it) +def HARDWARE_INC equ 1 +def HARDWARE_INC_VERSION equs "4.10.0" + +; Usage: rev_Check_hardware_inc +; Examples: +; rev_Check_hardware_inc 1.2.3 +; rev_Check_hardware_inc 1.2 (equivalent to 1.2.0) +; rev_Check_hardware_inc 1 (equivalent to 1.0.0) +MACRO rev_Check_hardware_inc + def hw_inc_cur_ver\@ equs strrpl("{HARDWARE_INC_VERSION}", ".", ",") + def hw_inc_min_ver\@ equs strrpl("\1", ".", ",") + def hw_inc_min_ver\@ equs """MACRO hw_inc_check\@ + 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""" + hw_inc_def_check\@ + hw_inc_check\@ {hw_inc_cur_ver\@}, {hw_inc_min_ver\@}, 0, 0 + purge hw_inc_cur_ver\@, hw_inc_min_ver\@, hw_inc_def_check\@, hw_inc_check\@ +ENDM + +;****************************************************************************** +; General memory region constants +;****************************************************************************** + +; Prefer `STARTOF(
)` when the value can be determined at link time, +; for example `STARTOF(WRAMX)` instead of `_RAMBANK` +def _ROM equ $0000 ; $0000-$3FFF / $0000-$7FFF +def _ROMBANK equ $4000 ; $4000-$7FFF +def _VRAM equ $8000 ; $8000-$9FFF +def _SCRN0 equ $9800 ; $9800-$9BFF +def _SCRN1 equ $9C00 ; $9C00-$9FFF +def _SRAM equ $A000 ; $A000-$BFFF +def _RAM equ $C000 ; $C000-$CFFF / $C000-$DFFF +def _RAMBANK equ $D000 ; $D000-$DFFF +def _OAMRAM equ $FE00 ; $FE00-$FE9F +def _IO equ $FF00 ; $FF00-$FF7F, $FFFF +def _HRAM equ $FF80 ; $FF80-$FFFE + +;****************************************************************************** +; MBC registers +;****************************************************************************** + +;------------------------------------------------------------------------------ +; RAMG ($0000-$1FFF) +; RAM enable [w] +;------------------------------------------------------------------------------ +def rRAMG equ $0000 + +; Common values +def CART_SRAM_ENABLE equ $0A +def CART_SRAM_DISABLE equ $00 + +; MBC3-specific values +def RTC_S equ $08 ; seconds counter (0-59) +def RTC_M equ $09 ; minutes counter (0-59) +def RTC_H equ $0A ; hours counter (0-23) +def RTC_DL equ $0B ; days counter, low byte (0-255) +def RTC_DH equ $0C ; days counter, high bit and other flags + def RTC_DHB_OVERFLOW equ 7 ; 1 = days counter overflowed [w] + def RTC_DHB_HALT equ 6 ; 0 = run timer, 1 = stop timer [w] + def RTC_DHB_HIGH equ 0 ; days counter, high bit (bit 8) [w] + def RTC_DHF_OVERFLOW equ 1 << RTC_DHB_OVERFLOW + def RTC_DHF_HALT equ 1 << RTC_DHB_HALT + def RTC_DHF_HIGH equ 1 << RTC_DHB_HIGH + +;------------------------------------------------------------------------------ +; ROMB0 ($2000-$3FFF) +; ROM bank number [w] +;------------------------------------------------------------------------------ +def rROMB0 equ $2000 + +;------------------------------------------------------------------------------ +; ROMB1 ($3000-$3FFF) +; (MBC5 only) ROM bank number bit 8 [w] +;------------------------------------------------------------------------------ +def rROMB1 equ $3000 + +;------------------------------------------------------------------------------ +; RAMB ($4000-$5FFF) +; RAM bank number [w] +;------------------------------------------------------------------------------ +def rRAMB equ $4000 + +def CARTB_RUMBLE_ON equ 3 ; (MBC5 and MBC7 only) enable the rumble motor (if any) + def CART_RUMBLE_ON equ 1 << CARTB_RUMBLE_ON + +;------------------------------------------------------------------------------ +; RTCLATCH ($6000-$7FFF) +; (MBC3 only) RTC latch clock data [w] +;------------------------------------------------------------------------------ +def rRTCLATCH equ $6000 + +; Write $00 then $01 to latch the current time into the RTC registers +def RTCLATCH_START equ $00 +def RTCLATCH_FINISH equ $01 + +;****************************************************************************** +; Memory-mapped registers +;****************************************************************************** + +;------------------------------------------------------------------------------ +; JOYP / P1 ($FF00) +; Joypad buttons +;------------------------------------------------------------------------------ +def rJOYP equ $FF00 + +def JOYPB_GET_BTN equ 5 ; 0 = reading buttons [r/w] +def JOYPB_GET_DPAD equ 4 ; 0 = reading D-pad [r/w] + def JOYPF_GET equ %00_11_0000 ; select which inputs to read from the lower nybble + def JOYP_GET_BTN equ %00_01_0000 ; reading A/B/Select/Start buttons + def JOYP_GET_DPAD equ %00_10_0000 ; reading D-pad directions + def JOYP_GET_NONE equ %00_11_0000 ; reading nothing + +def JOYPB_START equ 3 ; 0 = Start is pressed (if reading buttons) [ro] +def JOYPB_SELECT equ 2 ; 0 = Select is pressed (if reading buttons) [ro] +def JOYPB_B equ 1 ; 0 = B is pressed (if reading buttons) [ro] +def JOYPB_A equ 0 ; 0 = A is pressed (if reading buttons) [ro] +def JOYPB_DOWN equ 3 ; 0 = Down is pressed (if reading D-pad) [ro] +def JOYPB_UP equ 2 ; 0 = Up is pressed (if reading D-pad) [ro] +def JOYPB_LEFT equ 1 ; 0 = Left is pressed (if reading D-pad) [ro] +def JOYPB_RIGHT equ 0 ; 0 = Right is pressed (if reading D-pad) [ro] + def JOYPF_INPUTS equ %0000_1111 + def JOYPF_START equ 1 << JOYPB_START + def JOYPF_SELECT equ 1 << JOYPB_SELECT + def JOYPF_B equ 1 << JOYPB_B + def JOYPF_A equ 1 << JOYPB_A + def JOYPF_DOWN equ 1 << JOYPB_DOWN + def JOYPF_UP equ 1 << JOYPB_UP + def JOYPF_LEFT equ 1 << JOYPB_LEFT + def JOYPF_RIGHT equ 1 << JOYPB_RIGHT + +; Combined input byte, with D-pad in high nybble (conventional order) +def PADB_DOWN equ 7 +def PADB_UP equ 6 +def PADB_LEFT equ 5 +def PADB_RIGHT equ 4 +def PADB_START equ 3 +def PADB_SELECT equ 2 +def PADB_B equ 1 +def PADB_A equ 0 + def PADF_DOWN equ 1 << PADB_DOWN + def PADF_UP equ 1 << PADB_UP + def PADF_LEFT equ 1 << PADB_LEFT + def PADF_RIGHT equ 1 << PADB_RIGHT + def PADF_START equ 1 << PADB_START + def PADF_SELECT equ 1 << PADB_SELECT + def PADF_B equ 1 << PADB_B + def PADF_A equ 1 << PADB_A + +; Combined input byte, with D-pad in low nybble (swapped order) +def PADB_SWAP_START equ 7 +def PADB_SWAP_SELECT equ 6 +def PADB_SWAP_B equ 5 +def PADB_SWAP_A equ 4 +def PADB_SWAP_DOWN equ 3 +def PADB_SWAP_UP equ 2 +def PADB_SWAP_LEFT equ 1 +def PADB_SWAP_RIGHT equ 0 + def PADF_SWAP_START equ 1 << PADB_SWAP_START + def PADF_SWAP_SELECT equ 1 << PADB_SWAP_SELECT + def PADF_SWAP_B equ 1 << PADB_SWAP_B + def PADF_SWAP_A equ 1 << PADB_SWAP_A + def PADF_SWAP_DOWN equ 1 << PADB_SWAP_DOWN + def PADF_SWAP_UP equ 1 << PADB_SWAP_UP + def PADF_SWAP_LEFT equ 1 << PADB_SWAP_LEFT + def PADF_SWAP_RIGHT equ 1 << PADB_SWAP_RIGHT + +;------------------------------------------------------------------------------ +; SB ($FF01) +; Serial transfer data [r/w] +;------------------------------------------------------------------------------ +def rSB equ $FF01 + +;------------------------------------------------------------------------------ +; SC ($FF02) +; Serial transfer control +;------------------------------------------------------------------------------ +def rSC equ $FF02 + +def SCB_START equ 7 ; reading 1 = transfer in progress, writing 1 = start transfer [r/w] +def SCB_SPEED equ 1 ; (CGB only) 1 = use faster internal clock [r/w] +def SCB_SOURCE equ 0 ; 0 = use external clock ("slave"), 1 = use internal clock ("master") [r/w] + def SCF_START equ 1 << SCB_START + def SCF_SPEED equ 1 << SCB_SPEED + def SC_SLOW equ 0 << SCB_SPEED + def SC_FAST equ 1 << SCB_SPEED + def SCF_SOURCE equ 1 << SCB_SOURCE + def SC_EXTERNAL equ 0 << SCB_SOURCE + def SC_INTERNAL equ 1 << SCB_SOURCE + +;------------------------------------------------------------------------------ +; $FF03 is unused +;------------------------------------------------------------------------------ + +;------------------------------------------------------------------------------ +; DIV ($FF04) +; Divider register [r/w] +;------------------------------------------------------------------------------ +def rDIV equ $FF04 + +;------------------------------------------------------------------------------ +; TIMA ($FF05) +; Timer counter [r/w] +;------------------------------------------------------------------------------ +def rTIMA equ $FF05 + +;------------------------------------------------------------------------------ +; TMA ($FF06) +; Timer modulo [r/w] +;------------------------------------------------------------------------------ +def rTMA equ $FF06 + +;------------------------------------------------------------------------------ +; TAC ($FF07) +; Timer control +;------------------------------------------------------------------------------ +def rTAC equ $FF07 + +def TACB_START equ 2 ; enable incrementing TIMA [r/w] + def TACF_STOP equ 0 << TACB_START + def TACF_START equ 1 << TACB_START + +def TACF_CLOCK equ %000000_11 ; the frequency at which TIMER_CNT increments [r/w] + def TACF_4KHZ equ %000000_00 ; every 256 M-cycles = ~4 KHz on DMG + def TACF_262KHZ equ %000000_01 ; every 4 M-cycles = ~262 KHz on DMG + def TACF_65KHZ equ %000000_10 ; every 16 M-cycles = ~65 KHz on DMG + def TACF_16KHZ equ %000000_11 ; every 64 M-cycles = ~16 KHz on DMG + +;------------------------------------------------------------------------------ +; $FF08-$FF0E are unused +;------------------------------------------------------------------------------ + +;------------------------------------------------------------------------------ +; IF ($FF0F) +; Pending interrupts +;------------------------------------------------------------------------------ +def rIF equ $FF0F + +def IFB_JOYPAD equ 4 ; 1 = joypad interrupt is pending [r/w] +def IFB_SERIAL equ 3 ; 1 = serial interrupt is pending [r/w] +def IFB_TIMER equ 2 ; 1 = timer interrupt is pending [r/w] +def IFB_STAT equ 1 ; 1 = STAT interrupt is pending [r/w] +def IFB_VBLANK equ 0 ; 1 = VBlank interrupt is pending [r/w] + def IFF_JOYPAD equ 1 << IFB_JOYPAD + def IFF_SERIAL equ 1 << IFB_SERIAL + def IFF_TIMER equ 1 << IFB_TIMER + def IFF_STAT equ 1 << IFB_STAT + def IFF_VBLANK equ 1 << IFB_VBLANK + +;------------------------------------------------------------------------------ +; AUD1SWEEP / NR10 ($FF10) +; Audio channel 1 sweep +;------------------------------------------------------------------------------ +def rAUD1SWEEP equ $FF10 + +def AUD1SWEEPF_TIME equ %0_111_0000 ; how long between sweep iterations (in 128 Hz ticks, ~7.8 ms apart) [r/w] + +def AUD1SWEEPB_DIR equ 3 ; sweep direction [r/w] + def AUD1SWEEPF_DIR equ 1 << AUD1SWEEPB_DIR + def AUD1SWEEP_UP equ 0 << AUD1SWEEPB_DIR + def AUD1SWEEP_DOWN equ 1 << AUD1SWEEPB_DIR + +def AUD1SWEEP_SHIFT equ %00000_111 ; how much the period increases/decreases per iteration [r/w] + +;------------------------------------------------------------------------------ +; AUD1LEN / NR11 ($FF11) +; Audio channel 1 length timer and duty cycle +;------------------------------------------------------------------------------ +def rAUD1LEN equ $FF11 + +; These values are also applicable to AUD2LEN +def AUDLENF_DUTY equ %11_000000 ; ratio of time spent high vs. time spent low [r/w] + def AUDLEN_DUTY_12_5 equ %00_000000 ; 12.5% + def AUDLEN_DUTY_25 equ %01_000000 ; 25% + def AUDLEN_DUTY_50 equ %10_000000 ; 50% + def AUDLEN_DUTY_75 equ %11_000000 ; 75% + +; This value is also applicable to AUD2LEN and AUD4LEN +def AUDLENF_TIMER equ %00_111111 ; initial length timer (0-63) [wo] + +;------------------------------------------------------------------------------ +; AUD1ENV / NR12 ($FF12) +; Audio channel 1 volume and envelope +;------------------------------------------------------------------------------ +def rAUD1ENV equ $FF12 + +; Values are also applicable to AUD2ENV and AUD4ENV + +def AUDENVF_INIT_VOL equ %1111_0000 ; initial volume [r/w] + +def AUDENVB_DIR equ 3 ; direction of volume envelope [r/w] + def AUDENVF_DIR equ 1 << AUDENVB_DIR + def AUDENV_DOWN equ 0 << AUDENVB_DIR + def AUDENV_UP equ 1 << AUDENVB_DIR + +def AUDENVF_PACE equ %00000_111 ; how long between envelope iterations (in 64 Hz ticks, ~15.6 ms apart) [r/w] + +;------------------------------------------------------------------------------ +; AUD1LOW / NR13 ($FF13) +; Audio channel 1 period (low 8 bits) [rw] +;------------------------------------------------------------------------------ +def rAUD1LOW equ $FF13 + +;------------------------------------------------------------------------------ +; AUD1HIGH / NR14 ($FF14) +; Audio channel 1 period (high 3 bits) and control +;------------------------------------------------------------------------------ +def rAUD1HIGH equ $FF14 + +; Values are also applicable to AUD2HIGH and AUD3HIGH + +def AUDHIGHB_RESTART equ 7 ; 1 = restart the channel [wo] +def AUDHIGHB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [rw] + def AUDHIGH_RESTART equ 1 << AUDHIGHB_RESTART + def AUDHIGH_LENGTH_OFF equ 0 << AUDHIGHB_LEN_ENABLE + def AUDHIGH_LENGTH_ON equ 1 << AUDHIGHB_LEN_ENABLE + +def AUDHIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [rw] + +;------------------------------------------------------------------------------ +; $FF15 is unused +;------------------------------------------------------------------------------ + +;------------------------------------------------------------------------------ +; AUD2LEN / NR21 ($FF16) +; Audio channel 2 length timer and duty cycle +;------------------------------------------------------------------------------ +def rAUD2LEN equ $FF16 + +; Values are reused from AUD1LEN + +;------------------------------------------------------------------------------ +; AUD2ENV / NR22 ($FF17) +; Audio channel 2 volume and envelope +;------------------------------------------------------------------------------ +def rAUD2ENV equ $FF17 + +; Values are reused from AUD1ENV + +;------------------------------------------------------------------------------ +; AUD2LOW / NR23 ($FF18) +; Audio channel 2 period (low 8 bits) [rw] +;------------------------------------------------------------------------------ +def rAUD2LOW equ $FF18 + +;------------------------------------------------------------------------------ +; AUD2HIGH / NR24 ($FF19) +; Audio channel 2 period (high 3 bits) and control +;------------------------------------------------------------------------------ +def rAUD2HIGH equ $FF19 + +; Values are reused from AUD1HIGH + +;------------------------------------------------------------------------------ +; AUD3ENA / NR30 ($FF1A) +; Audio channel 3 enable +;------------------------------------------------------------------------------ +def rAUD3ENA equ $FF1A + +def AUD3ENAB_ENABLE equ 7 ; 1 = channel is active [rw] + def AUD3ENA_OFF equ 0 << AUD3ENAB_ENABLE + def AUD3ENA_ON equ 1 << AUD3ENAB_ENABLE + +;------------------------------------------------------------------------------ +; AUD3LEN / NR31 ($FF1B) +; Audio channel 3 length timer [wo] +;------------------------------------------------------------------------------ +def rAUD3LEN equ $FF1B + +;------------------------------------------------------------------------------ +; AUD3LEVEL / NR32 ($FF1C) +; Audio channel 3 volume +;------------------------------------------------------------------------------ +def rAUD3LEVEL equ $FF1C + +def AUD3LEVELF_VOLUME equ %0_11_00000 ; volume level [rw] + def AUD3LEVEL_MUTE equ %0_00_00000 ; 0% (muted) + def AUD3LEVEL_100 equ %0_01_00000 ; 100% + def AUD3LEVEL_50 equ %0_10_00000 ; 50% + def AUD3LEVEL_25 equ %0_11_00000 ; 25% + +;------------------------------------------------------------------------------ +; AUD3LOW / NR33 ($FF1D) +; Audio channel 3 period (low 8 bits) [rw] +;------------------------------------------------------------------------------ +def rAUD3LOW equ $FF1D + +;------------------------------------------------------------------------------ +; AUD3HIGH / NR34 ($FF1E) +; Audio channel 3 period (high 3 bits) and control +;------------------------------------------------------------------------------ +def rAUD3HIGH equ $FF1E + +; Values are reused from AUD1HIGH + +;------------------------------------------------------------------------------ +; $FF1F is unused +;------------------------------------------------------------------------------ + +;------------------------------------------------------------------------------ +; AUD4LEN / NR41 ($FF20) +; Audio channel 4 length timer [wo] +;------------------------------------------------------------------------------ +def rAUD4LEN equ $FF20 + +; AUDLENF_TIMER value is reused from AUD1LEN + +;------------------------------------------------------------------------------ +; AUD4ENV / NR42 ($FF21) +; Audio channel 4 volume and envelope +;------------------------------------------------------------------------------ +def rAUD4ENV equ $FF21 + +; Values are reused from AUD1ENV + +;------------------------------------------------------------------------------ +; AUD4POLY / NR43 ($FF22) +; Audio channel 4 period and randomness +;------------------------------------------------------------------------------ +def rAUD4POLY equ $FF22 + +def AUD4POLYF_SHIFT equ %1111_0000 ; coarse control of the channel's period [rw] + +def AUD4POLYB_WIDTH equ 3 ; controls the noise generator (LFSR)'s step width [rw] + def AUD4POLY_15STEP equ 0 << AUD4POLYB_WIDTH + def AUD4POLY_7STEP equ 1 << AUD4POLYB_WIDTH + +def AUD4POLYF_DIV equ %00000_111 ; fine control of the channel's period [rw] + +;------------------------------------------------------------------------------ +; AUD4GO / NR44 ($FF23) +; Audio channel 4 control +;------------------------------------------------------------------------------ +def rAUD4GO equ $FF23 + +def AUD4GOB_RESTART equ 7 ; 1 = restart the channel [wo] +def AUD4GOB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [rw] + def AUD4GO_RESTART equ 1 << AUD4GOB_RESTART + def AUD4GO_LENGTH_OFF equ 0 << AUD4GOB_LEN_ENABLE + def AUD4GO_LENGTH_ON equ 1 << AUD4GOB_LEN_ENABLE + +;------------------------------------------------------------------------------ +; AUDVOL / NR50 ($FF24) +; Audio master volume and VIN mixer +;------------------------------------------------------------------------------ +def rAUDVOL equ $FF24 + +def AUDVOLB_VIN_LEFT equ 7 ; 1 = output VIN to left ear (SO2, speaker 2) [rw] + def AUDVOL_VIN_LEFT equ 1 << AUDVOLB_VIN_LEFT + +def AUDVOLF_LEFT equ %0_111_0000 ; 0 = barely audible, 7 = full volume [rw] + +def AUDVOLB_VIN_RIGHT equ 3 ; 1 = output VIN to right ear (SO1, speaker 1) [rw] + def AUDVOL_VIN_RIGHT equ 1 << AUDVOLB_VIN_RIGHT + +def AUDVOLF_RIGHT equ %00000_111 ; 0 = barely audible, 7 = full volume [rw] + +;------------------------------------------------------------------------------ +; AUDTERM / NR51 ($FF25) +; Audio channel mixer +;------------------------------------------------------------------------------ +def rAUDTERM equ $FF25 + +def AUDTERMB_4_LEFT equ 7 ; 1 = output channel 4 to left ear [rw] +def AUDTERMB_3_LEFT equ 6 ; 1 = output channel 3 to left ear [rw] +def AUDTERMB_2_LEFT equ 5 ; 1 = output channel 2 to left ear [rw] +def AUDTERMB_1_LEFT equ 4 ; 1 = output channel 1 to left ear [rw] +def AUDTERMB_4_RIGHT equ 3 ; 1 = output channel 4 to right ear [rw] +def AUDTERMB_3_RIGHT equ 2 ; 1 = output channel 3 to right ear [rw] +def AUDTERMB_2_RIGHT equ 1 ; 1 = output channel 2 to right ear [rw] +def AUDTERMB_1_RIGHT equ 0 ; 1 = output channel 1 to right ear [rw] + def AUDTERM_4_LEFT equ 1 << AUDTERMB_4_LEFT + def AUDTERM_3_LEFT equ 1 << AUDTERMB_3_LEFT + def AUDTERM_2_LEFT equ 1 << AUDTERMB_2_LEFT + def AUDTERM_1_LEFT equ 1 << AUDTERMB_1_LEFT + def AUDTERM_4_RIGHT equ 1 << AUDTERMB_4_RIGHT + def AUDTERM_3_RIGHT equ 1 << AUDTERMB_3_RIGHT + def AUDTERM_2_RIGHT equ 1 << AUDTERMB_2_RIGHT + def AUDTERM_1_RIGHT equ 1 << AUDTERMB_1_RIGHT + +;------------------------------------------------------------------------------ +; AUDENA / NR52 ($FF26) +; Audio master enable +;------------------------------------------------------------------------------ +def rAUDENA equ $FF26 + +def AUDENAB_ENABLE equ 7 ; 0 = disable the APU, saving power (resets all audio registers to 0!) [r/w] +def AUDENAB_ENABLE_CH4 equ 3 ; 1 = channel 4 is running [ro] +def AUDENAB_ENABLE_CH3 equ 2 ; 1 = channel 3 is running [ro] +def AUDENAB_ENABLE_CH2 equ 1 ; 1 = channel 2 is running [ro] +def AUDENAB_ENABLE_CH1 equ 0 ; 1 = channel 1 is running [ro] + def AUDENA_OFF equ 0 << AUDENAB_ENABLE + def AUDENA_ON equ 1 << AUDENAB_ENABLE + def AUDENAF_CH4_OFF equ 0 << AUDENAB_ENABLE_CH4 + def AUDENAF_CH4_ON equ 1 << AUDENAB_ENABLE_CH4 + def AUDENAF_CH3_OFF equ 0 << AUDENAB_ENABLE_CH3 + def AUDENAF_CH3_ON equ 1 << AUDENAB_ENABLE_CH3 + def AUDENAF_CH2_OFF equ 0 << AUDENAB_ENABLE_CH2 + def AUDENAF_CH2_ON equ 1 << AUDENAB_ENABLE_CH2 + def AUDENAF_CH1_OFF equ 0 << AUDENAB_ENABLE_CH1 + def AUDENAF_CH1_ON equ 1 << AUDENAB_ENABLE_CH1 + +;------------------------------------------------------------------------------ +; $FF27-$FF2F are unused +;------------------------------------------------------------------------------ + +;------------------------------------------------------------------------------ +; AUD3WAVE ($FF30-$FF3F) +; Audio channel 3 wave pattern RAM +;------------------------------------------------------------------------------ +def _AUD3WAVERAM equ $FF30 ; $FF30-$FF3F + +def rAUD3WAVE_0 equ $FF30 +def rAUD3WAVE_1 equ $FF31 +def rAUD3WAVE_2 equ $FF32 +def rAUD3WAVE_3 equ $FF33 +def rAUD3WAVE_4 equ $FF34 +def rAUD3WAVE_5 equ $FF35 +def rAUD3WAVE_6 equ $FF36 +def rAUD3WAVE_7 equ $FF37 +def rAUD3WAVE_8 equ $FF38 +def rAUD3WAVE_9 equ $FF39 +def rAUD3WAVE_A equ $FF3A +def rAUD3WAVE_B equ $FF3B +def rAUD3WAVE_C equ $FF3C +def rAUD3WAVE_D equ $FF3D +def rAUD3WAVE_E equ $FF3E +def rAUD3WAVE_F equ $FF3F + +;------------------------------------------------------------------------------ +; LCDC ($FF40) +; LCD graphics control +;------------------------------------------------------------------------------ +def rLCDC equ $FF40 + +def LCDCF_OFF equ %00000000 ; LCD Control Operation +def LCDCF_ON equ %10000000 ; LCD Control Operation +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_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 +def LCDCF_OBJ16 equ %00000100 ; OBJ Construction +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 + + +; -- +; -- STAT ($FF41) +; -- LCDC Status (R/W) +; -- +def rSTAT equ $FF41 + +def STATF_LYC equ %01000000 ; LYC=LY Coincidence (Selectable) +def STATF_MODE10 equ %00100000 ; Mode 10 +def STATF_MODE01 equ %00010000 ; Mode 01 (V-Blank) +def STATF_MODE00 equ %00001000 ; Mode 00 (H-Blank) +def STATF_LYCF equ %00000100 ; Coincidence Flag +def STATF_HBL equ %00000000 ; H-Blank +def STATF_VBL equ %00000001 ; V-Blank +def STATF_OAM equ %00000010 ; OAM-RAM is used by system +def STATF_LCD equ %00000011 ; Both OAM and VRAM used by system +def STATF_BUSY equ %00000010 ; When set, VRAM access is unsafe + +def STATB_LYC equ 6 +def STATB_MODE10 equ 5 +def STATB_MODE01 equ 4 +def STATB_MODE00 equ 3 +def STATB_LYCF equ 2 +def STATB_BUSY equ 1 + +; -- +; -- SCY ($FF42) +; -- Scroll Y (R/W) +; -- +def rSCY equ $FF42 + + +; -- +; -- SCX ($FF43) +; -- Scroll X (R/W) +; -- +def rSCX equ $FF43 + + +; -- +; -- LY ($FF44) +; -- LCDC Y-Coordinate (R) +; -- +; -- Values range from 0-153. 144-153 is the VBlank period. +; -- +def rLY equ $FF44 + + +; -- +; -- LYC ($FF45) +; -- LY Compare (R/W) +; -- +; -- When LY==LYC, STATF_LYCF will be set in STAT +; -- +def rLYC equ $FF45 + + +; -- +; -- DMA ($FF46) +; -- DMA Transfer and Start Address (W) +; -- +def rDMA equ $FF46 + + +; -- +; -- BGP ($FF47) +; -- BG Palette Data (W) +; -- +; -- Bit 7-6 - Intensity for %11 +; -- Bit 5-4 - Intensity for %10 +; -- Bit 3-2 - Intensity for %01 +; -- Bit 1-0 - Intensity for %00 +; -- +def rBGP equ $FF47 + + +; -- +; -- OBP0 ($FF48) +; -- Object Palette 0 Data (W) +; -- +; -- See BGP for info +; -- +def rOBP0 equ $FF48 + + +; -- +; -- OBP1 ($FF49) +; -- Object Palette 1 Data (W) +; -- +; -- See BGP for info +; -- +def rOBP1 equ $FF49 + + +; -- +; -- WY ($FF4A) +; -- Window Y Position (R/W) +; -- +; -- 0 <= WY <= 143 +; -- When WY = 0, the window is displayed from the top edge of the LCD screen. +; -- +def rWY equ $FF4A + + +; -- +; -- WX ($FF4B) +; -- Window X Position (R/W) +; -- +; -- 7 <= WX <= 166 +; -- When WX = 7, the window is displayed from the left edge of the LCD screen. +; -- Values of 0-6 and 166 are unreliable due to hardware bugs. +; -- +def rWX equ $FF4B + +def WX_OFS equ 7 ; add this to a screen position to get a WX position + + +; -- +; -- SPEED ($FF4D) +; -- Select CPU Speed (R/W) +; -- +def rKEY1 equ $FF4D +def rSPD equ rKEY1 + +def KEY1F_DBLSPEED equ %10000000 ; 0=Normal Speed, 1=Double Speed (R) +def KEY1F_PREPARE equ %00000001 ; 0=No, 1=Prepare (R/W) + + +; -- +; -- VBK ($FF4F) +; -- Select Video RAM Bank (R/W) +; -- +; -- Bit 0 - Bank Specification (0: Specify Bank 0; 1: Specify Bank 1) +; -- +def rVBK equ $FF4F + + +; -- +; -- HDMA1 ($FF51) +; -- High byte for Horizontal Blanking/General Purpose DMA source address (W) +; -- CGB Mode Only +; -- +def rHDMA1 equ $FF51 + + +; -- +; -- HDMA2 ($FF52) +; -- Low byte for Horizontal Blanking/General Purpose DMA source address (W) +; -- CGB Mode Only +; -- +def rHDMA2 equ $FF52 + + +; -- +; -- HDMA3 ($FF53) +; -- High byte for Horizontal Blanking/General Purpose DMA destination address (W) +; -- CGB Mode Only +; -- +def rHDMA3 equ $FF53 + + +; -- +; -- HDMA4 ($FF54) +; -- Low byte for Horizontal Blanking/General Purpose DMA destination address (W) +; -- CGB Mode Only +; -- +def rHDMA4 equ $FF54 + + +; -- +; -- HDMA5 ($FF55) +; -- Transfer length (in tiles minus 1)/mode/start for Horizontal Blanking, General Purpose DMA (R/W) +; -- CGB Mode Only +; -- +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) + + +; -- +; -- RP ($FF56) +; -- Infrared Communications Port (R/W) +; -- CGB Mode Only +; -- +def rRP equ $FF56 + +def RPF_ENREAD equ %11000000 +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/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/BGPD ($FF69) +; -- Background Color Palette Data (aka Background Palette Data) (R/W) +; -- +def rBCPD equ $FF69 +def rBGPD equ rBCPD + + +; -- +; -- 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/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) + + + +; -- +; -- SMBK/SVBK ($FF70) +; -- Select Main RAM Bank (R/W) +; -- +; -- Bit 2-0 - Bank Specification (0,1: Specify Bank 1; 2-7: Specify Banks 2-7) +; -- +def rSVBK equ $FF70 +def rSMBK equ rSVBK + + +; -- +; -- PCM12 ($FF76) +; -- Sound channel 1&2 PCM amplitude (R) +; -- +; -- Bit 7-4 - Copy of sound channel 2's PCM amplitude +; -- Bit 3-0 - Copy of sound channel 1's PCM amplitude +; -- +def rPCM12 equ $FF76 + + +; -- +; -- PCM34 ($FF77) +; -- Sound channel 3&4 PCM amplitude (R) +; -- +; -- Bit 7-4 - Copy of sound channel 4's PCM amplitude +; -- Bit 3-0 - Copy of sound channel 3's PCM amplitude +; -- +def rPCM34 equ $FF77 + + +; -- +; -- IE ($FFFF) +; -- Interrupt Enable (R/W) +; -- +def rIE equ $FFFF + +def IEF_JOYPAD equ %00010000 ; Transition from High to Low of Pin number P10-P13 +def IEF_SERIAL equ %00001000 ; Serial I/O transfer end +def IEF_TIMER equ %00000100 ; Timer Overflow +def IEF_STAT equ %00000010 ; STAT +def IEF_VBLANK equ %00000001 ; V-Blank + +def IEB_JOYPAD equ 4 +def IEB_SERIAL equ 3 +def IEB_TIMER equ 2 +def IEB_STAT equ 1 +def IEB_VBLANK equ 0 + +;*************************************************************************** +;* +;* CPU values on bootup (a=type, b=qualifier) +;* +;*************************************************************************** + +def BOOTUP_A_DMG equ $01 ; Dot Matrix Game +def BOOTUP_A_CGB equ $11 ; Color Game Boy +def BOOTUP_A_MGB equ $FF ; Mini Game Boy (Pocket Game Boy) + +; if a=BOOTUP_A_CGB, bit 0 in b can be checked to determine if real CGB or +; other system running in GBC mode +def BOOTUP_B_CGB equ %00000000 +def BOOTUP_B_AGB equ %00000001 ; GBA, GBA SP, Game Boy Player, or New GBA SP + + +;*************************************************************************** +;* +;* 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 Game Boy) +;* (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 Game Boy compatibility code +def CART_COMPATIBLE_DMG equ $00 +def CART_COMPATIBLE_DMG_GBC equ $80 +def CART_COMPATIBLE_GBC equ $C0 + +; $0146 Game Boy/Super Game Boy indicator +def CART_INDICATOR_GB equ $00 +def CART_INDICATOR_SGB equ $03 + +; $0147 Cartridge type +def CART_ROM equ $00 +def CART_ROM_MBC1 equ $01 +def CART_ROM_MBC1_RAM equ $02 +def CART_ROM_MBC1_RAM_BAT equ $03 +def CART_ROM_MBC2 equ $05 +def CART_ROM_MBC2_BAT equ $06 +def CART_ROM_RAM equ $08 +def CART_ROM_RAM_BAT equ $09 +def CART_ROM_MMM01 equ $0B +def CART_ROM_MMM01_RAM equ $0C +def CART_ROM_MMM01_RAM_BAT equ $0D +def CART_ROM_MBC3_BAT_RTC equ $0F +def CART_ROM_MBC3_RAM_BAT_RTC equ $10 +def CART_ROM_MBC3 equ $11 +def CART_ROM_MBC3_RAM equ $12 +def CART_ROM_MBC3_RAM_BAT equ $13 +def CART_ROM_MBC5 equ $19 +def CART_ROM_MBC5_RAM equ $1A +def CART_ROM_MBC5_RAM_BAT equ $1B +def CART_ROM_MBC5_RUMBLE equ $1C +def CART_ROM_MBC5_RAM_RUMBLE equ $1D +def CART_ROM_MBC5_RAM_BAT_RUMBLE equ $1E +def CART_ROM_MBC7_RAM_BAT_GYRO equ $22 +def CART_ROM_POCKET_CAMERA equ $FC +def CART_ROM_BANDAI_TAMA5 equ $FD +def CART_ROM_HUDSON_HUC3 equ $FE +def CART_ROM_HUDSON_HUC1 equ $FF + +; $0148 ROM size +; these are kilobytes +def CART_ROM_32KB equ $00 ; 2 banks +def CART_ROM_64KB equ $01 ; 4 banks +def CART_ROM_128KB equ $02 ; 8 banks +def CART_ROM_256KB equ $03 ; 16 banks +def CART_ROM_512KB equ $04 ; 32 banks +def CART_ROM_1024KB equ $05 ; 64 banks +def CART_ROM_2048KB equ $06 ; 128 banks +def CART_ROM_4096KB equ $07 ; 256 banks +def CART_ROM_8192KB equ $08 ; 512 banks +def CART_ROM_1152KB equ $52 ; 72 banks +def CART_ROM_1280KB equ $53 ; 80 banks +def CART_ROM_1536KB equ $54 ; 96 banks + +; $0149 SRAM size +; these are kilobytes +def CART_SRAM_NONE equ 0 +def CART_SRAM_8KB equ 2 ; 1 bank +def CART_SRAM_32KB equ 3 ; 4 banks +def CART_SRAM_128KB equ 4 ; 16 banks + +; $014A Destination code +def CART_DEST_JAPANESE equ $00 +def CART_DEST_NON_JAPANESE equ $01 + + +;*************************************************************************** +;* +;* Screen related +;* +;*************************************************************************** + +def SCRN_X equ 160 ; Width 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 + +def SCRN_VX equ 256 ; Virtual width of screen in pixels +def SCRN_VY equ 256 ; Virtual height of screen in pixels +def SCRN_VX_B equ 32 ; Virtual width of screen in bytes +def SCRN_VY_B equ 32 ; Virtual height of screen in bytes + + +;*************************************************************************** +;* +;* OAM related +;* +;*************************************************************************** + +; OAM attributes +; each entry in OAM RAM is 4 bytes (sizeof_OAM_ATTRS) +RSRESET +def OAMA_Y RB 1 ; y pos plus 16 +def OAMA_X RB 1 ; x pos plus 8 +def OAMA_TILEID RB 1 ; tile id +def OAMA_FLAGS RB 1 ; flags (see below) +def sizeof_OAM_ATTRS RB 0 + +def OAM_Y_OFS equ 16 ; add this to a screen-relative Y position to get an OAM Y position +def OAM_X_OFS equ 8 ; add this to a screen-relative X position to get an OAM X position + +def OAM_COUNT equ 40 ; number of OAM entries in OAM RAM + +; flags +def OAMF_PRI equ %10000000 ; Priority +def OAMF_YFLIP equ %01000000 ; Y flip +def OAMF_XFLIP equ %00100000 ; X flip +def OAMF_PAL0 equ %00000000 ; Palette number; 0,1 (DMG) +def OAMF_PAL1 equ %00010000 ; Palette number; 0,1 (DMG) +def OAMF_BANK0 equ %00000000 ; Bank number; 0,1 (GBC) +def OAMF_BANK1 equ %00001000 ; Bank number; 0,1 (GBC) + +def OAMF_PALMASK equ %00000111 ; Palette (GBC) + +def OAMB_PRI equ 7 ; Priority +def OAMB_YFLIP equ 6 ; Y flip +def OAMB_XFLIP equ 5 ; X flip +def OAMB_PAL1 equ 4 ; Palette number; 0,1 (DMG) +def OAMB_BANK1 equ 3 ; Bank number; 0,1 (GBC) + + +; Aliases + +def rP1 equ rJOYP +def rNR10 equ rAUD1SWEEP +def rNR11 equ rAUD1LEN +def rNR12 equ rAUD1ENV +def rNR13 equ rAUD1LOW +def rNR14 equ rAUD1HIGH +def rNR21 equ rAUD2LEN +def rNR22 equ rAUD2ENV +def rNR23 equ rAUD2LOW +def rNR24 equ rAUD2HIGH +def rNR30 equ rAUD3ENA +def rNR31 equ rAUD3LEN +def rNR32 equ rAUD3LEVEL +def rNR33 equ rAUD3LOW +def rNR34 equ rAUD3HIGH +def rNR41 equ rAUD4LEN +def rNR42 equ rAUD4ENV +def rNR43 equ rAUD4POLY +def rNR44 equ rAUD4GO +def rNR50 equ rAUDVOL +def rNR51 equ rAUDTERM +def rNR52 equ rAUDENA + +; Deprecated constants. Please avoid using. + +def IEB_HILO equ IEB_JOYPAD +def IEF_HILO equ 1 << IEB_JOYPAD + +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 + +def P1F_5 equ JOYP_GET_DPAD +def P1F_4 equ JOYP_GET_BTN +def P1F_3 equ JOYPF_DOWN +def P1F_2 equ JOYPF_UP +def P1F_1 equ JOYPF_LEFT +def P1F_0 equ JOYPF_RIGHT + +def P1F_GET_DPAD equ JOYP_GET_DPAD +def P1F_GET_BTN equ JOYP_GET_BTN +def P1F_GET_NONE equ JOYP_GET_NONE + +endc ; HARDWARE_INC From f4b0d534ff5d3aff05a2d2a16797f9f464650d0a Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Wed, 14 May 2025 15:12:34 -0400 Subject: [PATCH 03/27] Use shorter register heading dash comments --- hardware.inc | 328 ++++++++++++++++++++------------------------------- 1 file changed, 126 insertions(+), 202 deletions(-) diff --git a/hardware.inc b/hardware.inc index efab3e1..61fe6ba 100644 --- a/hardware.inc +++ b/hardware.inc @@ -1,5 +1,5 @@ ;****************************************************************************** -; Game Boy hardware definitions +; Game Boy hardware constant definitions ; https://github.com/gbdev/hardware.inc ;****************************************************************************** @@ -32,7 +32,7 @@ def HARDWARE_INC_VERSION equs "4.10.0" MACRO rev_Check_hardware_inc def hw_inc_cur_ver\@ equs strrpl("{HARDWARE_INC_VERSION}", ".", ",") def hw_inc_min_ver\@ equs strrpl("\1", ".", ",") - def hw_inc_min_ver\@ equs """MACRO hw_inc_check\@ + def hw_inc_def_check\@ equs """MACRO hw_inc_check\@ 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 @@ -42,107 +42,30 @@ MACRO rev_Check_hardware_inc purge hw_inc_cur_ver\@, hw_inc_min_ver\@, hw_inc_def_check\@, hw_inc_check\@ ENDM -;****************************************************************************** -; General memory region constants -;****************************************************************************** - -; Prefer `STARTOF(
)` when the value can be determined at link time, -; for example `STARTOF(WRAMX)` instead of `_RAMBANK` -def _ROM equ $0000 ; $0000-$3FFF / $0000-$7FFF -def _ROMBANK equ $4000 ; $4000-$7FFF -def _VRAM equ $8000 ; $8000-$9FFF -def _SCRN0 equ $9800 ; $9800-$9BFF -def _SCRN1 equ $9C00 ; $9C00-$9FFF -def _SRAM equ $A000 ; $A000-$BFFF -def _RAM equ $C000 ; $C000-$CFFF / $C000-$DFFF -def _RAMBANK equ $D000 ; $D000-$DFFF -def _OAMRAM equ $FE00 ; $FE00-$FE9F -def _IO equ $FF00 ; $FF00-$FF7F, $FFFF -def _HRAM equ $FF80 ; $FF80-$FFFE ;****************************************************************************** -; MBC registers +; Memory-mapped registers ($FFxx range) ;****************************************************************************** -;------------------------------------------------------------------------------ -; RAMG ($0000-$1FFF) -; RAM enable [w] -;------------------------------------------------------------------------------ -def rRAMG equ $0000 - -; Common values -def CART_SRAM_ENABLE equ $0A -def CART_SRAM_DISABLE equ $00 - -; MBC3-specific values -def RTC_S equ $08 ; seconds counter (0-59) -def RTC_M equ $09 ; minutes counter (0-59) -def RTC_H equ $0A ; hours counter (0-23) -def RTC_DL equ $0B ; days counter, low byte (0-255) -def RTC_DH equ $0C ; days counter, high bit and other flags - def RTC_DHB_OVERFLOW equ 7 ; 1 = days counter overflowed [w] - def RTC_DHB_HALT equ 6 ; 0 = run timer, 1 = stop timer [w] - def RTC_DHB_HIGH equ 0 ; days counter, high bit (bit 8) [w] - def RTC_DHF_OVERFLOW equ 1 << RTC_DHB_OVERFLOW - def RTC_DHF_HALT equ 1 << RTC_DHB_HALT - def RTC_DHF_HIGH equ 1 << RTC_DHB_HIGH - -;------------------------------------------------------------------------------ -; ROMB0 ($2000-$3FFF) -; ROM bank number [w] -;------------------------------------------------------------------------------ -def rROMB0 equ $2000 - -;------------------------------------------------------------------------------ -; ROMB1 ($3000-$3FFF) -; (MBC5 only) ROM bank number bit 8 [w] -;------------------------------------------------------------------------------ -def rROMB1 equ $3000 - -;------------------------------------------------------------------------------ -; RAMB ($4000-$5FFF) -; RAM bank number [w] -;------------------------------------------------------------------------------ -def rRAMB equ $4000 - -def CARTB_RUMBLE_ON equ 3 ; (MBC5 and MBC7 only) enable the rumble motor (if any) - def CART_RUMBLE_ON equ 1 << CARTB_RUMBLE_ON - -;------------------------------------------------------------------------------ -; RTCLATCH ($6000-$7FFF) -; (MBC3 only) RTC latch clock data [w] -;------------------------------------------------------------------------------ -def rRTCLATCH equ $6000 - -; Write $00 then $01 to latch the current time into the RTC registers -def RTCLATCH_START equ $00 -def RTCLATCH_FINISH equ $01 - -;****************************************************************************** -; Memory-mapped registers -;****************************************************************************** - -;------------------------------------------------------------------------------ -; JOYP / P1 ($FF00) -; Joypad buttons -;------------------------------------------------------------------------------ +; -- JOYP / P1 ($FF00) -------------------------------------------------------- +; Joypad face buttons def rJOYP equ $FF00 -def JOYPB_GET_BTN equ 5 ; 0 = reading buttons [r/w] -def JOYPB_GET_DPAD equ 4 ; 0 = reading D-pad [r/w] +def JOYPB_GET_BTN equ 5 ; 0 = reading buttons [r/w] +def JOYPB_GET_DPAD equ 4 ; 0 = reading Control Pad [r/w] def JOYPF_GET equ %00_11_0000 ; select which inputs to read from the lower nybble def JOYP_GET_BTN equ %00_01_0000 ; reading A/B/Select/Start buttons - def JOYP_GET_DPAD equ %00_10_0000 ; reading D-pad directions + def JOYP_GET_DPAD equ %00_10_0000 ; reading Control Pad directions def JOYP_GET_NONE equ %00_11_0000 ; reading nothing -def JOYPB_START equ 3 ; 0 = Start is pressed (if reading buttons) [ro] -def JOYPB_SELECT equ 2 ; 0 = Select is pressed (if reading buttons) [ro] -def JOYPB_B equ 1 ; 0 = B is pressed (if reading buttons) [ro] -def JOYPB_A equ 0 ; 0 = A is pressed (if reading buttons) [ro] -def JOYPB_DOWN equ 3 ; 0 = Down is pressed (if reading D-pad) [ro] -def JOYPB_UP equ 2 ; 0 = Up is pressed (if reading D-pad) [ro] -def JOYPB_LEFT equ 1 ; 0 = Left is pressed (if reading D-pad) [ro] -def JOYPB_RIGHT equ 0 ; 0 = Right is pressed (if reading D-pad) [ro] +def JOYPB_START equ 3 ; 0 = Start is pressed (if reading buttons) [ro] +def JOYPB_SELECT equ 2 ; 0 = Select is pressed (if reading buttons) [ro] +def JOYPB_B equ 1 ; 0 = B is pressed (if reading buttons) [ro] +def JOYPB_A equ 0 ; 0 = A is pressed (if reading buttons) [ro] +def JOYPB_DOWN equ 3 ; 0 = Down is pressed (if reading Control Pad) [ro] +def JOYPB_UP equ 2 ; 0 = Up is pressed (if reading Control Pad) [ro] +def JOYPB_LEFT equ 1 ; 0 = Left is pressed (if reading Control Pad) [ro] +def JOYPB_RIGHT equ 0 ; 0 = Right is pressed (if reading Control Pad) [ro] def JOYPF_INPUTS equ %0000_1111 def JOYPF_START equ 1 << JOYPB_START def JOYPF_SELECT equ 1 << JOYPB_SELECT @@ -153,7 +76,7 @@ def JOYPB_RIGHT equ 0 ; 0 = Right is pressed (if reading D-pad) [ro] def JOYPF_LEFT equ 1 << JOYPB_LEFT def JOYPF_RIGHT equ 1 << JOYPB_RIGHT -; Combined input byte, with D-pad in high nybble (conventional order) +; Combined input byte, with Control Pad in high nybble (conventional order) def PADB_DOWN equ 7 def PADB_UP equ 6 def PADB_LEFT equ 5 @@ -171,7 +94,7 @@ def PADB_A equ 0 def PADF_B equ 1 << PADB_B def PADF_A equ 1 << PADB_A -; Combined input byte, with D-pad in low nybble (swapped order) +; Combined input byte, with Control Pad in low nybble (swapped order) def PADB_SWAP_START equ 7 def PADB_SWAP_SELECT equ 6 def PADB_SWAP_B equ 5 @@ -189,16 +112,12 @@ def PADB_SWAP_RIGHT equ 0 def PADF_SWAP_LEFT equ 1 << PADB_SWAP_LEFT def PADF_SWAP_RIGHT equ 1 << PADB_SWAP_RIGHT -;------------------------------------------------------------------------------ -; SB ($FF01) +; -- SB ($FF01) --------------------------------------------------------------- ; Serial transfer data [r/w] -;------------------------------------------------------------------------------ def rSB equ $FF01 -;------------------------------------------------------------------------------ -; SC ($FF02) +; -- SC ($FF02) --------------------------------------------------------------- ; Serial transfer control -;------------------------------------------------------------------------------ def rSC equ $FF02 def SCB_START equ 7 ; reading 1 = transfer in progress, writing 1 = start transfer [r/w] @@ -212,32 +131,22 @@ def SCB_SOURCE equ 0 ; 0 = use external clock ("slave"), 1 = use internal clock def SC_EXTERNAL equ 0 << SCB_SOURCE def SC_INTERNAL equ 1 << SCB_SOURCE -;------------------------------------------------------------------------------ -; $FF03 is unused -;------------------------------------------------------------------------------ +; -- $FF03 is unused ---------------------------------------------------------- -;------------------------------------------------------------------------------ -; DIV ($FF04) +; -- DIV ($FF04) -------------------------------------------------------------- ; Divider register [r/w] -;------------------------------------------------------------------------------ def rDIV equ $FF04 -;------------------------------------------------------------------------------ -; TIMA ($FF05) +; -- TIMA ($FF05) ------------------------------------------------------------- ; Timer counter [r/w] -;------------------------------------------------------------------------------ def rTIMA equ $FF05 -;------------------------------------------------------------------------------ -; TMA ($FF06) +; -- TMA ($FF06) -------------------------------------------------------------- ; Timer modulo [r/w] -;------------------------------------------------------------------------------ def rTMA equ $FF06 -;------------------------------------------------------------------------------ -; TAC ($FF07) +; -- TAC ($FF07) -------------------------------------------------------------- ; Timer control -;------------------------------------------------------------------------------ def rTAC equ $FF07 def TACB_START equ 2 ; enable incrementing TIMA [r/w] @@ -250,14 +159,10 @@ def TACF_CLOCK equ %000000_11 ; the frequency at which TIMER_CNT increments [r/w def TACF_65KHZ equ %000000_10 ; every 16 M-cycles = ~65 KHz on DMG def TACF_16KHZ equ %000000_11 ; every 64 M-cycles = ~16 KHz on DMG -;------------------------------------------------------------------------------ -; $FF08-$FF0E are unused -;------------------------------------------------------------------------------ +; -- $FF08-$FF0E are unused --------------------------------------------------- -;------------------------------------------------------------------------------ -; IF ($FF0F) +; -- IF ($FF0F) --------------------------------------------------------------- ; Pending interrupts -;------------------------------------------------------------------------------ def rIF equ $FF0F def IFB_JOYPAD equ 4 ; 1 = joypad interrupt is pending [r/w] @@ -271,13 +176,12 @@ def IFB_VBLANK equ 0 ; 1 = VBlank interrupt is pending [r/w] def IFF_STAT equ 1 << IFB_STAT def IFF_VBLANK equ 1 << IFB_VBLANK -;------------------------------------------------------------------------------ -; AUD1SWEEP / NR10 ($FF10) +; -- AUD1SWEEP / NR10 ($FF10) ------------------------------------------------- ; Audio channel 1 sweep -;------------------------------------------------------------------------------ def rAUD1SWEEP equ $FF10 -def AUD1SWEEPF_TIME equ %0_111_0000 ; how long between sweep iterations (in 128 Hz ticks, ~7.8 ms apart) [r/w] +def AUD1SWEEPF_TIME equ %0_111_0000 ; how long between sweep iterations + ; (in 128 Hz ticks, ~7.8 ms apart) [r/w] def AUD1SWEEPB_DIR equ 3 ; sweep direction [r/w] def AUD1SWEEPF_DIR equ 1 << AUD1SWEEPB_DIR @@ -286,10 +190,8 @@ def AUD1SWEEPB_DIR equ 3 ; sweep direction [r/w] def AUD1SWEEP_SHIFT equ %00000_111 ; how much the period increases/decreases per iteration [r/w] -;------------------------------------------------------------------------------ -; AUD1LEN / NR11 ($FF11) +; -- AUD1LEN / NR11 ($FF11) --------------------------------------------------- ; Audio channel 1 length timer and duty cycle -;------------------------------------------------------------------------------ def rAUD1LEN equ $FF11 ; These values are also applicable to AUD2LEN @@ -302,10 +204,8 @@ def AUDLENF_DUTY equ %11_000000 ; ratio of time spent high vs. time spent low [r ; This value is also applicable to AUD2LEN and AUD4LEN def AUDLENF_TIMER equ %00_111111 ; initial length timer (0-63) [wo] -;------------------------------------------------------------------------------ -; AUD1ENV / NR12 ($FF12) +; -- AUD1ENV / NR12 ($FF12) --------------------------------------------------- ; Audio channel 1 volume and envelope -;------------------------------------------------------------------------------ def rAUD1ENV equ $FF12 ; Values are also applicable to AUD2ENV and AUD4ENV @@ -317,18 +217,15 @@ def AUDENVB_DIR equ 3 ; direction of volume envelope [r/w] def AUDENV_DOWN equ 0 << AUDENVB_DIR def AUDENV_UP equ 1 << AUDENVB_DIR -def AUDENVF_PACE equ %00000_111 ; how long between envelope iterations (in 64 Hz ticks, ~15.6 ms apart) [r/w] +def AUDENVF_PACE equ %00000_111 ; how long between envelope iterations + ; (in 64 Hz ticks, ~15.6 ms apart) [r/w] -;------------------------------------------------------------------------------ -; AUD1LOW / NR13 ($FF13) +; -- AUD1LOW / NR13 ($FF13) --------------------------------------------------- ; Audio channel 1 period (low 8 bits) [rw] -;------------------------------------------------------------------------------ def rAUD1LOW equ $FF13 -;------------------------------------------------------------------------------ -; AUD1HIGH / NR14 ($FF14) +; -- AUD1HIGH / NR14 ($FF14) -------------------------------------------------- ; Audio channel 1 period (high 3 bits) and control -;------------------------------------------------------------------------------ def rAUD1HIGH equ $FF14 ; Values are also applicable to AUD2HIGH and AUD3HIGH @@ -341,60 +238,44 @@ def AUDHIGHB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer exp def AUDHIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [rw] -;------------------------------------------------------------------------------ -; $FF15 is unused -;------------------------------------------------------------------------------ +; -- $FF15 is unused ---------------------------------------------------------- -;------------------------------------------------------------------------------ -; AUD2LEN / NR21 ($FF16) +; -- AUD2LEN / NR21 ($FF16) --------------------------------------------------- ; Audio channel 2 length timer and duty cycle -;------------------------------------------------------------------------------ def rAUD2LEN equ $FF16 ; Values are reused from AUD1LEN -;------------------------------------------------------------------------------ -; AUD2ENV / NR22 ($FF17) +; -- AUD2ENV / NR22 ($FF17) --------------------------------------------------- ; Audio channel 2 volume and envelope -;------------------------------------------------------------------------------ def rAUD2ENV equ $FF17 ; Values are reused from AUD1ENV -;------------------------------------------------------------------------------ -; AUD2LOW / NR23 ($FF18) +; -- AUD2LOW / NR23 ($FF18) --------------------------------------------------- ; Audio channel 2 period (low 8 bits) [rw] -;------------------------------------------------------------------------------ def rAUD2LOW equ $FF18 -;------------------------------------------------------------------------------ -; AUD2HIGH / NR24 ($FF19) +; -- AUD2HIGH / NR24 ($FF19) -------------------------------------------------- ; Audio channel 2 period (high 3 bits) and control -;------------------------------------------------------------------------------ def rAUD2HIGH equ $FF19 ; Values are reused from AUD1HIGH -;------------------------------------------------------------------------------ -; AUD3ENA / NR30 ($FF1A) +; -- AUD3ENA / NR30 ($FF1A) --------------------------------------------------- ; Audio channel 3 enable -;------------------------------------------------------------------------------ def rAUD3ENA equ $FF1A def AUD3ENAB_ENABLE equ 7 ; 1 = channel is active [rw] def AUD3ENA_OFF equ 0 << AUD3ENAB_ENABLE def AUD3ENA_ON equ 1 << AUD3ENAB_ENABLE -;------------------------------------------------------------------------------ -; AUD3LEN / NR31 ($FF1B) +; -- AUD3LEN / NR31 ($FF1B) --------------------------------------------------- ; Audio channel 3 length timer [wo] -;------------------------------------------------------------------------------ def rAUD3LEN equ $FF1B -;------------------------------------------------------------------------------ -; AUD3LEVEL / NR32 ($FF1C) +; -- AUD3LEVEL / NR32 ($FF1C) ------------------------------------------------- ; Audio channel 3 volume -;------------------------------------------------------------------------------ def rAUD3LEVEL equ $FF1C def AUD3LEVELF_VOLUME equ %0_11_00000 ; volume level [rw] @@ -403,44 +284,32 @@ def AUD3LEVELF_VOLUME equ %0_11_00000 ; volume level [rw] def AUD3LEVEL_50 equ %0_10_00000 ; 50% def AUD3LEVEL_25 equ %0_11_00000 ; 25% -;------------------------------------------------------------------------------ -; AUD3LOW / NR33 ($FF1D) +; -- AUD3LOW / NR33 ($FF1D) --------------------------------------------------- ; Audio channel 3 period (low 8 bits) [rw] -;------------------------------------------------------------------------------ def rAUD3LOW equ $FF1D -;------------------------------------------------------------------------------ -; AUD3HIGH / NR34 ($FF1E) +; -- AUD3HIGH / NR34 ($FF1E) -------------------------------------------------- ; Audio channel 3 period (high 3 bits) and control -;------------------------------------------------------------------------------ def rAUD3HIGH equ $FF1E ; Values are reused from AUD1HIGH -;------------------------------------------------------------------------------ -; $FF1F is unused -;------------------------------------------------------------------------------ +; -- $FF1F is unused ---------------------------------------------------------- -;------------------------------------------------------------------------------ -; AUD4LEN / NR41 ($FF20) +; -- AUD4LEN / NR41 ($FF20) --------------------------------------------------- ; Audio channel 4 length timer [wo] -;------------------------------------------------------------------------------ def rAUD4LEN equ $FF20 ; AUDLENF_TIMER value is reused from AUD1LEN -;------------------------------------------------------------------------------ -; AUD4ENV / NR42 ($FF21) +; -- AUD4ENV / NR42 ($FF21) --------------------------------------------------- ; Audio channel 4 volume and envelope -;------------------------------------------------------------------------------ def rAUD4ENV equ $FF21 ; Values are reused from AUD1ENV -;------------------------------------------------------------------------------ -; AUD4POLY / NR43 ($FF22) +; -- AUD4POLY / NR43 ($FF22) -------------------------------------------------- ; Audio channel 4 period and randomness -;------------------------------------------------------------------------------ def rAUD4POLY equ $FF22 def AUD4POLYF_SHIFT equ %1111_0000 ; coarse control of the channel's period [rw] @@ -451,10 +320,8 @@ def AUD4POLYB_WIDTH equ 3 ; controls the noise generator (LFSR)'s step width [rw def AUD4POLYF_DIV equ %00000_111 ; fine control of the channel's period [rw] -;------------------------------------------------------------------------------ -; AUD4GO / NR44 ($FF23) +; -- AUD4GO / NR44 ($FF23) ---------------------------------------------------- ; Audio channel 4 control -;------------------------------------------------------------------------------ def rAUD4GO equ $FF23 def AUD4GOB_RESTART equ 7 ; 1 = restart the channel [wo] @@ -463,10 +330,8 @@ def AUD4GOB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expi def AUD4GO_LENGTH_OFF equ 0 << AUD4GOB_LEN_ENABLE def AUD4GO_LENGTH_ON equ 1 << AUD4GOB_LEN_ENABLE -;------------------------------------------------------------------------------ -; AUDVOL / NR50 ($FF24) +; -- AUDVOL / NR50 ($FF24) ---------------------------------------------------- ; Audio master volume and VIN mixer -;------------------------------------------------------------------------------ def rAUDVOL equ $FF24 def AUDVOLB_VIN_LEFT equ 7 ; 1 = output VIN to left ear (SO2, speaker 2) [rw] @@ -479,10 +344,8 @@ def AUDVOLB_VIN_RIGHT equ 3 ; 1 = output VIN to right ear (SO1, speaker 1) [rw] def AUDVOLF_RIGHT equ %00000_111 ; 0 = barely audible, 7 = full volume [rw] -;------------------------------------------------------------------------------ -; AUDTERM / NR51 ($FF25) +; -- AUDTERM / NR51 ($FF25) --------------------------------------------------- ; Audio channel mixer -;------------------------------------------------------------------------------ def rAUDTERM equ $FF25 def AUDTERMB_4_LEFT equ 7 ; 1 = output channel 4 to left ear [rw] @@ -502,10 +365,8 @@ def AUDTERMB_1_RIGHT equ 0 ; 1 = output channel 1 to right ear [rw] def AUDTERM_2_RIGHT equ 1 << AUDTERMB_2_RIGHT def AUDTERM_1_RIGHT equ 1 << AUDTERMB_1_RIGHT -;------------------------------------------------------------------------------ -; AUDENA / NR52 ($FF26) +; -- AUDENA / NR52 ($FF26) ---------------------------------------------------- ; Audio master enable -;------------------------------------------------------------------------------ def rAUDENA equ $FF26 def AUDENAB_ENABLE equ 7 ; 0 = disable the APU, saving power (resets all audio registers to 0!) [r/w] @@ -524,14 +385,10 @@ def AUDENAB_ENABLE_CH1 equ 0 ; 1 = channel 1 is running [ro] def AUDENAF_CH1_OFF equ 0 << AUDENAB_ENABLE_CH1 def AUDENAF_CH1_ON equ 1 << AUDENAB_ENABLE_CH1 -;------------------------------------------------------------------------------ -; $FF27-$FF2F are unused -;------------------------------------------------------------------------------ +; -- $FF27-$FF2F are unused --------------------------------------------------- -;------------------------------------------------------------------------------ -; AUD3WAVE ($FF30-$FF3F) +; -- AUD3WAVE ($FF30-$FF3F) --------------------------------------------------- ; Audio channel 3 wave pattern RAM -;------------------------------------------------------------------------------ def _AUD3WAVERAM equ $FF30 ; $FF30-$FF3F def rAUD3WAVE_0 equ $FF30 @@ -551,10 +408,8 @@ def rAUD3WAVE_D equ $FF3D def rAUD3WAVE_E equ $FF3E def rAUD3WAVE_F equ $FF3F -;------------------------------------------------------------------------------ -; LCDC ($FF40) +; -- LCDC ($FF40) ------------------------------------------------------------- ; LCD graphics control -;------------------------------------------------------------------------------ def rLCDC equ $FF40 def LCDCF_OFF equ %00000000 ; LCD Control Operation @@ -889,6 +744,72 @@ def IEB_TIMER equ 2 def IEB_STAT equ 1 def IEB_VBLANK equ 0 + +;****************************************************************************** +; Memory regions +;****************************************************************************** + +; Prefer `STARTOF(
)` when the value can be determined at link time +def _ROM equ $0000 ; $0000-$3FFF / $0000-$7FFF (prefer `STARTOF(ROM0)`) +def _ROMBANK equ $4000 ; $4000-$7FFF (prefer `STARTOF(ROMX)`) +def _VRAM equ $8000 ; $8000-$9FFF (prefer `STARTOF(VRAM)`) +def _SRAM equ $A000 ; $A000-$BFFF (prefer `STARTOF(SRAM)`) +def _RAM equ $C000 ; $C000-$CFFF / $C000-$DFFF (prefer `STARTOF(WRAM0)`) +def _RAMBANK equ $D000 ; $D000-$DFFF (prefer `STARTOF(WRAMX)`) +def _OAMRAM equ $FE00 ; $FE00-$FE9F (prefer `STARTOF(OAM)`) +def _IO equ $FF00 ; $FF00-$FF7F, $FFFF +def _HRAM equ $FF80 ; $FF80-$FFFE (prefer `STARTOF(HRAM)`) + + +;****************************************************************************** +; Cartridge registers (MBC) +;****************************************************************************** + +; -- RAMG ($0000-$1FFF) ------------------------------------------------------- +; RAM enable [w] +def rRAMG equ $0000 + +; Common values +def CART_SRAM_ENABLE equ $0A +def CART_SRAM_DISABLE equ $00 + +; MBC3-specific values +def RTC_S equ $08 ; seconds counter (0-59) +def RTC_M equ $09 ; minutes counter (0-59) +def RTC_H equ $0A ; hours counter (0-23) +def RTC_DL equ $0B ; days counter, low byte (0-255) +def RTC_DH equ $0C ; days counter, high bit and other flags + def RTC_DHB_OVERFLOW equ 7 ; 1 = days counter overflowed [w] + def RTC_DHB_HALT equ 6 ; 0 = run timer, 1 = stop timer [w] + def RTC_DHB_HIGH equ 0 ; days counter, high bit (bit 8) [w] + def RTC_DHF_OVERFLOW equ 1 << RTC_DHB_OVERFLOW + def RTC_DHF_HALT equ 1 << RTC_DHB_HALT + def RTC_DHF_HIGH equ 1 << RTC_DHB_HIGH + +; -- ROMB0 ($2000-$3FFF) ------------------------------------------------------ +; ROM bank number [w] +def rROMB0 equ $2000 + +; -- ROMB1 ($3000-$3FFF) ------------------------------------------------------ +; (MBC5 only) ROM bank number bit 8 [w] +def rROMB1 equ $3000 + +; -- RAMB ($4000-$5FFF) ------------------------------------------------------- +; RAM bank number [w] +def rRAMB equ $4000 + +def CARTB_RUMBLE_ON equ 3 ; (MBC5 and MBC7 only) enable the rumble motor (if any) + def CART_RUMBLE_ON equ 1 << CARTB_RUMBLE_ON + +; -- RTCLATCH ($6000-$7FFF) --------------------------------------------------- +; (MBC3 only) RTC latch clock data [w] +def rRTCLATCH equ $6000 + +; Write $00 then $01 to latch the current time into the RTC registers +def RTCLATCH_START equ $00 +def RTCLATCH_FINISH equ $01 + + ;*************************************************************************** ;* ;* CPU values on bootup (a=type, b=qualifier) @@ -1005,6 +926,9 @@ def CART_DEST_NON_JAPANESE equ $01 ;* ;*************************************************************************** +def _SCRN0 equ $9800 ; $9800-$9BFF +def _SCRN1 equ $9C00 ; $9C00-$9FFF + def SCRN_X equ 160 ; Width 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 From 2ed849698b7174e518a5c143b6de9800e83ac6d3 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Wed, 14 May 2025 15:58:09 -0400 Subject: [PATCH 04/27] Update more registers --- HISTORY.md | 4 +- hardware.inc | 228 ++++++++++++++++++++++----------------------------- 2 files changed, 99 insertions(+), 133 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ad11dff..22c58ca 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -76,6 +76,6 @@ - **Rev 4.9.2** - 2024-08-18 *(DevEd)* - Corrected `CART_ROM_MBC5_BAT` to `CART_ROM_MBC5_RAM` - **Rev 4.10.0** - 2025-05-13 *(Rangi42)* - - Moved revision history to separate HISTORY.md file + - Added more constants - Changed formatting - - Added `_ROM` and `_ROMBANK` constants + - Moved revision history to separate HISTORY.md file diff --git a/hardware.inc b/hardware.inc index 61fe6ba..1e369ec 100644 --- a/hardware.inc +++ b/hardware.inc @@ -369,7 +369,7 @@ def AUDTERMB_1_RIGHT equ 0 ; 1 = output channel 1 to right ear [rw] ; Audio master enable def rAUDENA equ $FF26 -def AUDENAB_ENABLE equ 7 ; 0 = disable the APU, saving power (resets all audio registers to 0!) [r/w] +def AUDENAB_ENABLE equ 7 ; 0 = disable the APU (resets all audio registers to 0!) [r/w] def AUDENAB_ENABLE_CH4 equ 3 ; 1 = channel 4 is running [ro] def AUDENAB_ENABLE_CH3 equ 2 ; 1 = channel 3 is running [ro] def AUDENAB_ENABLE_CH2 equ 1 ; 1 = channel 2 is running [ro] @@ -388,7 +388,7 @@ def AUDENAB_ENABLE_CH1 equ 0 ; 1 = channel 1 is running [ro] ; -- $FF27-$FF2F are unused --------------------------------------------------- ; -- AUD3WAVE ($FF30-$FF3F) --------------------------------------------------- -; Audio channel 3 wave pattern RAM +; Audio channel 3 wave pattern RAM [r/w] def _AUD3WAVERAM equ $FF30 ; $FF30-$FF3F def rAUD3WAVE_0 equ $FF30 @@ -409,162 +409,124 @@ def rAUD3WAVE_E equ $FF3E def rAUD3WAVE_F equ $FF3F ; -- LCDC ($FF40) ------------------------------------------------------------- -; LCD graphics control +; PPU graphics control def rLCDC equ $FF40 -def LCDCF_OFF equ %00000000 ; LCD Control Operation -def LCDCF_ON equ %10000000 ; LCD Control Operation -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_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 -def LCDCF_OBJ16 equ %00000100 ; OBJ Construction -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 - - -; -- -; -- STAT ($FF41) -; -- LCDC Status (R/W) -; -- +def LCDCB_ON equ 7 ; whether the PPU (and LCD) are turned on [r/w] +def LCDCB_WIN9C00 equ 6 ; which tilemap the Window reads from [r/w] +def LCDCB_WINON equ 5 ; whether the Window is enabled [r/w] +def LCDCB_BLKS equ 4 ; which "tile blocks" the BG and Window use [r/w] +def LCDCB_BG9C00 equ 3 ; which tilemap the BG reads from [r/w] +def LCDCB_OBJ16 equ 2 ; how many pixels tall each OBJ is [r/w] +def LCDCB_OBJON equ 1 ; whether OBJs are enabled [r/w] +def LCDCB_BGON equ 0 ; (DMG only) whether the BG is enabled [r/w] +def LCDCB_PRION equ 0 ; (CGB only) whether OBJ priority bits are enabled [r/w] + def LCDCF_OFF equ 0 << LCDCB_ON + def LCDCF_ON equ 1 << LCDCB_ON + def LCDCF_WIN9800 equ 0 << LCDCB_WIN9C00 + def LCDCF_WIN9C00 equ 1 << LCDCB_WIN9C00 + def LCDCF_WINOFF equ 0 << LCDCB_WINON + def LCDCF_WINON equ 1 << LCDCB_WINON + def LCDCF_BLKS equ 1 << LCDCB_BLKS + def LCDCF_BLK21 equ 0 << LCDCB_BLKS + def LCDCF_BLK01 equ 1 << LCDCB_BLKS + def LCDCF_BG9800 equ 0 << LCDCB_BG9C00 + def LCDCF_BG9C00 equ 1 << LCDCB_BG9C00 + def LCDCF_OBJ8 equ 0 << LCDCB_OBJ16 + def LCDCF_OBJ16 equ 1 << LCDCB_OBJ16 + def LCDCF_OBJOFF equ 0 << LCDCB_OBJON + def LCDCF_OBJON equ 1 << LCDCB_OBJON + def LCDCF_BGOFF equ 0 << LCDCB_BGON + def LCDCF_BGON equ 1 << LCDCB_BGON + def LCDCF_PRIOFF equ 0 << LCDCB_PRION + def LCDCF_PRION equ 1 << LCDCB_PRION + +; -- STAT ($FF41) ------------------------------------------------------------- +; Graphics status and interrupt control def rSTAT equ $FF41 -def STATF_LYC equ %01000000 ; LYC=LY Coincidence (Selectable) -def STATF_MODE10 equ %00100000 ; Mode 10 -def STATF_MODE01 equ %00010000 ; Mode 01 (V-Blank) -def STATF_MODE00 equ %00001000 ; Mode 00 (H-Blank) -def STATF_LYCF equ %00000100 ; Coincidence Flag -def STATF_HBL equ %00000000 ; H-Blank -def STATF_VBL equ %00000001 ; V-Blank -def STATF_OAM equ %00000010 ; OAM-RAM is used by system -def STATF_LCD equ %00000011 ; Both OAM and VRAM used by system -def STATF_BUSY equ %00000010 ; When set, VRAM access is unsafe - -def STATB_LYC equ 6 -def STATB_MODE10 equ 5 -def STATB_MODE01 equ 4 -def STATB_MODE00 equ 3 -def STATB_LYCF equ 2 -def STATB_BUSY equ 1 - -; -- -; -- SCY ($FF42) -; -- Scroll Y (R/W) -; -- +def STATB_LYC equ 6 ; 1 = LY match triggers the STAT interrupt [r/w] +def STATB_MODE10 equ 5 ; 1 = OAM Scan triggers the PPU interrupt [r/w] +def STATB_MODE01 equ 4 ; 1 = VBlank triggers the PPU interrupt [r/w] +def STATB_MODE00 equ 3 ; 1 = HBlank triggers the PPU interrupt [r/w] +def STATB_LYCF equ 2 ; 1 = LY is currently equal to LYC [ro] +def STATB_BUSY equ 1 ; 1 = the PPU is currently accessing VRAM [ro] + def STATF_LYC equ 1 << STATB_LYC + def STATF_MODE10 equ 1 << STATB_MODE10 + def STATF_MODE01 equ 1 << STATB_MODE01 + def STATF_MODE00 equ 1 << STATB_MODE00 + def STATF_LYCF equ 1 << STATB_LYCF + def STATF_BUSY equ 1 << STATB_BUSY + +def STATF_MODE equ %000000_11 ; PPU's current status [ro] + def STATF_HBL equ %000000_00 ; Waiting after a line's rendering (HBlank) + def STATF_VBL equ %000000_01 ; Waiting between frames (VBlank) + def STATF_OAM equ %000000_10 ; Checking which OBJs will be rendered on this line (OAM scan) + def STATF_LCD equ %000000_11 ; Pushing pixels to the LCD + +; -- SCY ($FF42) -------------------------------------------------------------- +; Background Y scroll offset (in pixels) [r/w] def rSCY equ $FF42 - -; -- -; -- SCX ($FF43) -; -- Scroll X (R/W) -; -- +; -- SCX ($FF43) -------------------------------------------------------------- +; Background X scroll offset (in pixels) [r/w] def rSCX equ $FF43 - -; -- -; -- LY ($FF44) -; -- LCDC Y-Coordinate (R) -; -- -; -- Values range from 0-153. 144-153 is the VBlank period. -; -- +; -- LY ($FF44) --------------------------------------------------------------- +; Y coordinate of the line currently processed by the PPU (0-153) [ro] def rLY equ $FF44 +def LY_VBLANK equ 144 ; 144-153 is the VBlank period -; -- -; -- LYC ($FF45) -; -- LY Compare (R/W) -; -- -; -- When LY==LYC, STATF_LYCF will be set in STAT -; -- +; -- LYC ($FF45) -------------------------------------------------------------- +; Value that LY is constantly compared to [r/w] def rLYC equ $FF45 - -; -- -; -- DMA ($FF46) -; -- DMA Transfer and Start Address (W) -; -- +; -- DMA ($FF46) -------------------------------------------------------------- +; OAM DMA start address (high 8 bits) and start [wo] def rDMA equ $FF46 - -; -- -; -- BGP ($FF47) -; -- BG Palette Data (W) -; -- -; -- Bit 7-6 - Intensity for %11 -; -- Bit 5-4 - Intensity for %10 -; -- Bit 3-2 - Intensity for %01 -; -- Bit 1-0 - Intensity for %00 -; -- +; -- BGP ($FF47) -------------------------------------------------------------- +; (DMG only) Background color mapping [r/w] def rBGP equ $FF47 - -; -- -; -- OBP0 ($FF48) -; -- Object Palette 0 Data (W) -; -- -; -- See BGP for info -; -- +; -- OBP0 ($FF48) ------------------------------------------------------------- +; (DMG only) OBJ color mapping #0 [r/w] def rOBP0 equ $FF48 - -; -- -; -- OBP1 ($FF49) -; -- Object Palette 1 Data (W) -; -- -; -- See BGP for info -; -- +; -- OBP1 ($FF49) ------------------------------------------------------------- +; (DMG only) OBJ color mapping #1 [r/w] def rOBP1 equ $FF49 - -; -- -; -- WY ($FF4A) -; -- Window Y Position (R/W) -; -- -; -- 0 <= WY <= 143 -; -- When WY = 0, the window is displayed from the top edge of the LCD screen. -; -- +; -- WY ($FF4A) --------------------------------------------------------------- +; Y coordinate of the Window's top-left pixel (0-143) [r/w] def rWY equ $FF4A - -; -- -; -- WX ($FF4B) -; -- Window X Position (R/W) -; -- -; -- 7 <= WX <= 166 -; -- When WX = 7, the window is displayed from the left edge of the LCD screen. -; -- Values of 0-6 and 166 are unreliable due to hardware bugs. -; -- +; -- WX ($FF4B) --------------------------------------------------------------- +; X coordinate of the Window's top-left pixel, plus 7 (7-166) [r/w] def rWX equ $FF4B -def WX_OFS equ 7 ; add this to a screen position to get a WX position +def WX_OFS equ 7 ; subtract this to get the actual Window Y coordinate +; -- KEY0 ($FF4C) ------------------------------------------------------------- +; (CGB boot ROM only) CPU mode select +def rKEY0 equ $FF4C -; -- -; -- SPEED ($FF4D) -; -- Select CPU Speed (R/W) -; -- -def rKEY1 equ $FF4D -def rSPD equ rKEY1 +def KEY1F_MODE equ %0000_11_00 ; current system mode [r/w] + def KEY1F_CGB equ %0000_00_00 ; CGB mode + def KEY1F_DMG equ %0000_01_00 ; DMG compatibility mode + def KEY1F_PGB1 equ %0000_10_00 ; LCD is driven externally, CPU is stopped + def KEY1F_PGB2 equ %0000_11_00 ; LCD is driven externally, CPU is running + +; -- SPD / KEY1 ($FF4D) ------------------------------------------------------- +; (CGB only) Double-speed mode control +def rSPD equ $FF4D + +def SPDB_DBLSPEED equ 7 ; current clock speed [ro] +def SPDB_PREPARE equ 0 ; 1 = next `stop` instruction will switch clock speeds [r/w] + def SPDF_DBLSPEED equ 1 << SPDB_DBLSPEED + def SPDF_PREPARE equ 1 << SPDB_PREPARE -def KEY1F_DBLSPEED equ %10000000 ; 0=Normal Speed, 1=Double Speed (R) -def KEY1F_PREPARE equ %00000001 ; 0=No, 1=Prepare (R/W) ; -- @@ -1002,13 +964,14 @@ def rNR44 equ rAUD4GO def rNR50 equ rAUDVOL def rNR51 equ rAUDTERM def rNR52 equ rAUDENA +def rKEY1 equ rSPD ; Deprecated constants. Please avoid using. def IEB_HILO equ IEB_JOYPAD def IEF_HILO equ 1 << IEB_JOYPAD -def IEF_LCDC equ %00000010 ; LCDC (see STAT) +def IEF_LCDC equ IEF_STAT ; LCDC (see STAT) def _VRAM8000 equ _VRAM def _VRAM8800 equ _VRAM+$800 def _VRAM9000 equ _VRAM+$1000 @@ -1028,4 +991,7 @@ def P1F_GET_DPAD equ JOYP_GET_DPAD def P1F_GET_BTN equ JOYP_GET_BTN def P1F_GET_NONE equ JOYP_GET_NONE +def KEY1F_DBLSPEED equ 1 << SPDB_DBLSPEED +def KEY1F_PREPARE equ 1 << SPDB_PREPARE + endc ; HARDWARE_INC From d7a3af8f5d6152e29e08bbf61835390a793e44bf Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Wed, 14 May 2025 16:09:25 -0400 Subject: [PATCH 05/27] More registers --- hardware.inc | 68 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/hardware.inc b/hardware.inc index 1e369ec..e58a978 100644 --- a/hardware.inc +++ b/hardware.inc @@ -445,24 +445,24 @@ def LCDCB_PRION equ 0 ; (CGB only) whether OBJ priority bits are enabled [r/w] ; Graphics status and interrupt control def rSTAT equ $FF41 -def STATB_LYC equ 6 ; 1 = LY match triggers the STAT interrupt [r/w] -def STATB_MODE10 equ 5 ; 1 = OAM Scan triggers the PPU interrupt [r/w] -def STATB_MODE01 equ 4 ; 1 = VBlank triggers the PPU interrupt [r/w] -def STATB_MODE00 equ 3 ; 1 = HBlank triggers the PPU interrupt [r/w] -def STATB_LYCF equ 2 ; 1 = LY is currently equal to LYC [ro] -def STATB_BUSY equ 1 ; 1 = the PPU is currently accessing VRAM [ro] - def STATF_LYC equ 1 << STATB_LYC - def STATF_MODE10 equ 1 << STATB_MODE10 - def STATF_MODE01 equ 1 << STATB_MODE01 - def STATF_MODE00 equ 1 << STATB_MODE00 - def STATF_LYCF equ 1 << STATB_LYCF - def STATF_BUSY equ 1 << STATB_BUSY +def STATB_LYC equ 6 ; 1 = LY match triggers the STAT interrupt [r/w] +def STATB_MODE10 equ 5 ; 1 = OAM Scan triggers the PPU interrupt [r/w] +def STATB_MODE01 equ 4 ; 1 = VBlank triggers the PPU interrupt [r/w] +def STATB_MODE00 equ 3 ; 1 = HBlank triggers the PPU interrupt [r/w] +def STATB_LYCF equ 2 ; 1 = LY is currently equal to LYC [ro] +def STATB_BUSY equ 1 ; 1 = the PPU is currently accessing VRAM [ro] + def STATF_LYC equ 1 << STATB_LYC + def STATF_MODE10 equ 1 << STATB_MODE10 + def STATF_MODE01 equ 1 << STATB_MODE01 + def STATF_MODE00 equ 1 << STATB_MODE00 + def STATF_LYCF equ 1 << STATB_LYCF + def STATF_BUSY equ 1 << STATB_BUSY def STATF_MODE equ %000000_11 ; PPU's current status [ro] - def STATF_HBL equ %000000_00 ; Waiting after a line's rendering (HBlank) - def STATF_VBL equ %000000_01 ; Waiting between frames (VBlank) - def STATF_OAM equ %000000_10 ; Checking which OBJs will be rendered on this line (OAM scan) - def STATF_LCD equ %000000_11 ; Pushing pixels to the LCD + def STATF_HBL equ %000000_00 ; Waiting after a line's rendering (HBlank) + def STATF_VBL equ %000000_01 ; Waiting between frames (VBlank) + def STATF_OAM equ %000000_10 ; Checking which OBJs will be rendered on this line (OAM scan) + def STATF_LCD equ %000000_11 ; Pushing pixels to the LCD ; -- SCY ($FF42) -------------------------------------------------------------- ; Background Y scroll offset (in pixels) [r/w] @@ -512,11 +512,16 @@ def WX_OFS equ 7 ; subtract this to get the actual Window Y coordinate ; (CGB boot ROM only) CPU mode select def rKEY0 equ $FF4C -def KEY1F_MODE equ %0000_11_00 ; current system mode [r/w] - def KEY1F_CGB equ %0000_00_00 ; CGB mode - def KEY1F_DMG equ %0000_01_00 ; DMG compatibility mode - def KEY1F_PGB1 equ %0000_10_00 ; LCD is driven externally, CPU is stopped - def KEY1F_PGB2 equ %0000_11_00 ; LCD is driven externally, CPU is running +; KEY0 is known as the "CPU mode register" in Fig. 11 of this patent: +; https://patents.google.com/patent/US6322447B1/en?oq=US6322447bi +; "OBJ priority mode designating register" in the same patent +; Credit to @mattcurrie for this finding! + +def KEY0F_MODE equ %0000_11_00 ; current system mode [r/w] + def KEY0F_CGB equ %0000_00_00 ; CGB mode + def KEY0F_DMG equ %0000_01_00 ; DMG compatibility mode + def KEY0F_PGB1 equ %0000_10_00 ; LCD is driven externally, CPU is stopped + def KEY0F_PGB2 equ %0000_11_00 ; LCD is driven externally, CPU is running ; -- SPD / KEY1 ($FF4D) ------------------------------------------------------- ; (CGB only) Double-speed mode control @@ -527,16 +532,23 @@ def SPDB_PREPARE equ 0 ; 1 = next `stop` instruction will switch clock speeds [ def SPDF_DBLSPEED equ 1 << SPDB_DBLSPEED def SPDF_PREPARE equ 1 << SPDB_PREPARE +; -- $FF4E is unused ---------------------------------------------------------- - -; -- -; -- VBK ($FF4F) -; -- Select Video RAM Bank (R/W) -; -- -; -- Bit 0 - Bank Specification (0: Specify Bank 0; 1: Specify Bank 1) -; -- +; -- VBK ($FF4F) -------------------------------------------------------------- +; (CGB only) VRAM bank number (0 or 1) def rVBK equ $FF4F +def VBK_BANK equ %0000000_1 ; mapped VRAM bank [r/w] + +; -- BANK ($FF50) ------------------------------------------------------------- +; (boot ROM only) Boot ROM mapping control +def rBANK equ $FF50 + +def BANKB_ON equ 0 ; whether the boot ROM is mapped [wo] + def BANKF_ON equ 0 << BANKB_ON + def BANKF_OFF equ 1 << BANKB_ON + + ; -- ; -- HDMA1 ($FF51) From f662df25a1af81223156bf4921e858e0eab02fbe Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Wed, 14 May 2025 16:49:15 -0400 Subject: [PATCH 06/27] Add HDMA registers --- hardware.inc | 105 ++++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 55 deletions(-) diff --git a/hardware.inc b/hardware.inc index e58a978..469fa9d 100644 --- a/hardware.inc +++ b/hardware.inc @@ -459,10 +459,10 @@ def STATB_BUSY equ 1 ; 1 = the PPU is currently accessing VRAM [ro] def STATF_BUSY equ 1 << STATB_BUSY def STATF_MODE equ %000000_11 ; PPU's current status [ro] - def STATF_HBL equ %000000_00 ; Waiting after a line's rendering (HBlank) - def STATF_VBL equ %000000_01 ; Waiting between frames (VBlank) - def STATF_OAM equ %000000_10 ; Checking which OBJs will be rendered on this line (OAM scan) - def STATF_LCD equ %000000_11 ; Pushing pixels to the LCD + def STATF_HBL equ %000000_00 ; waiting after a line's rendering (HBlank) + def STATF_VBL equ %000000_01 ; waiting between frames (VBlank) + def STATF_OAM equ %000000_10 ; checking which OBJs will be rendered on this line (OAM scan) + def STATF_LCD equ %000000_11 ; pushing pixels to the LCD ; -- SCY ($FF42) -------------------------------------------------------------- ; Background Y scroll offset (in pixels) [r/w] @@ -548,69 +548,54 @@ def BANKB_ON equ 0 ; whether the boot ROM is mapped [wo] def BANKF_ON equ 0 << BANKB_ON def BANKF_OFF equ 1 << BANKB_ON +; -- VDMA_SRC_HIGH / HDMA1 ($FF51) -------------------------------------------- +; (CGB only) VRAM DMA source address (high 8 bits) [wo] +def rVDMA_SRC_HIGH equ $FF51 +; -- VDMA_SRC_LO / HDMA2 ($FF52) ---------------------------------------------- +; (CGB only) VRAM DMA source address (low 8 bits) [wo] +def rVDMA_SRC_LOW equ $FF52 -; -- -; -- HDMA1 ($FF51) -; -- High byte for Horizontal Blanking/General Purpose DMA source address (W) -; -- CGB Mode Only -; -- -def rHDMA1 equ $FF51 - - -; -- -; -- HDMA2 ($FF52) -; -- Low byte for Horizontal Blanking/General Purpose DMA source address (W) -; -- CGB Mode Only -; -- -def rHDMA2 equ $FF52 +; -- VDMA_DEST_HIGH / HDMA3 ($FF53) ------------------------------------------- +; (CGB only) VRAM DMA destination address (high 8 bits) [wo] +def rVDMA_DEST_HIGH equ $FF53 +; -- VDMA_DEST_LOW / HDMA3 ($FF54) -------------------------------------------- +; (CGB only) VRAM DMA destination address (low 8 bits) [wo] +def rVDMA_DEST_LOW equ $FF54 -; -- -; -- HDMA3 ($FF53) -; -- High byte for Horizontal Blanking/General Purpose DMA destination address (W) -; -- CGB Mode Only -; -- -def rHDMA3 equ $FF53 +; -- VDMA_LEN / HDMA5 ($FF55) ------------------------------------------------- +; (CGB only) VRAM DMA length, mode, and start +def rVDMA_LEN equ $FF55 +def VDMA_LENB_MODE equ 7 ; on write: VRAM DMA mode [wo] + def VDMA_LENF_MODE equ 1 << HDMA_LENB_MODE + def VDMA_LENF_MODE_GP equ 0 << HDMA_LENB_MODE ; GDMA (general-purpose) + def VDMA_LENF_MODE_HBL equ 1 << HDMA_LENB_MODE ; HDMA (HBlank) -; -- -; -- HDMA4 ($FF54) -; -- Low byte for Horizontal Blanking/General Purpose DMA destination address (W) -; -- CGB Mode Only -; -- -def rHDMA4 equ $FF54 +def VDMA_LENB_BUSY equ 7 ; on read: is a VRAM DMA active? + def VDMA_LENF_BUSY equ 1 << VDMA_LENB_ACTIVE + def VDMA_LENF_NO equ 0 << VDMA_LENB_ACTIVE + def VDMA_LENF_YES equ 1 << VDMA_LENB_ACTIVE +def VDMA_LENB_SIZE equ %0_1111111 ; how many 16-byte blocks (minus 1) to transfer [r/w] -; -- -; -- HDMA5 ($FF55) -; -- Transfer length (in tiles minus 1)/mode/start for Horizontal Blanking, General Purpose DMA (R/W) -; -- CGB Mode Only -; -- -def rHDMA5 equ $FF55 +; -- RP ($FF56) --------------------------------------------------------------- +; (CGB only) Infrared communications port +def rRP equ $FF56 -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) +def RPF_READ equ %11_000000 ; whether the IR read is enabled [r/w] + def RPF_DISREAD equ %00_000000 + def RPF_ENREAD equ %11_000000 -; -- 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) +def RPB_DATAIN equ 1 ; 0 = IR light is being received [ro] +def RPB_LED_ON equ 0 ; 1 = IR light is being sent [r/w] + def RPF_DATAIN equ 1 << RPB_DATAIN + def RPF_LED_ON equ 1 << RPB_LED_ON + def RPF_WRITE_LO equ 0 << RPB_LED_ON + def RPF_WRITE_HI equ 1 << RPB_LED_ON -; -- -; -- RP ($FF56) -; -- Infrared Communications Port (R/W) -; -- CGB Mode Only -; -- -def rRP equ $FF56 - -def RPF_ENREAD equ %11000000 -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 ; -- @@ -977,6 +962,11 @@ def rNR50 equ rAUDVOL def rNR51 equ rAUDTERM def rNR52 equ rAUDENA def rKEY1 equ rSPD +def rHDMA1 equ rHDMA_SRC_HIGH +def rHDMA2 equ rHDMA_SRC_LOW +def rHDMA3 equ rHDMA_DEST_HIGH +def rHDMA4 equ rHDMA_DEST_LOW +def rHDMA5 equ rHDMA_LEN ; Deprecated constants. Please avoid using. @@ -1006,4 +996,9 @@ def P1F_GET_NONE equ JOYP_GET_NONE def KEY1F_DBLSPEED equ 1 << SPDB_DBLSPEED def KEY1F_PREPARE equ 1 << SPDB_PREPARE +def HDMA5B_MODE equ VDMA_LENB_MODE +def HDMA5F_MODE_GP equ VDMA_LENF_MODE_GP +def HDMA5F_MODE_HBL equ VDMA_LENF_MODE_HBL +def HDMA5F_BUSY equ VDMA_LENF_BUSY + endc ; HARDWARE_INC From ded2c6299e032925234ef931b32b4bfee03024da Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 11:27:15 -0400 Subject: [PATCH 07/27] Fix VDMA (aka HDMA or GDMA) constants --- hardware.inc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/hardware.inc b/hardware.inc index 469fa9d..dacb19c 100644 --- a/hardware.inc +++ b/hardware.inc @@ -569,14 +569,14 @@ def rVDMA_DEST_LOW equ $FF54 def rVDMA_LEN equ $FF55 def VDMA_LENB_MODE equ 7 ; on write: VRAM DMA mode [wo] - def VDMA_LENF_MODE equ 1 << HDMA_LENB_MODE - def VDMA_LENF_MODE_GP equ 0 << HDMA_LENB_MODE ; GDMA (general-purpose) - def VDMA_LENF_MODE_HBL equ 1 << HDMA_LENB_MODE ; HDMA (HBlank) + def VDMA_LENF_MODE equ 1 << VDMA_LENB_MODE + def VDMA_LENF_MODE_GP equ 0 << VDMA_LENB_MODE ; GDMA (general-purpose) + def VDMA_LENF_MODE_HBL equ 1 << VDMA_LENB_MODE ; HDMA (HBlank) def VDMA_LENB_BUSY equ 7 ; on read: is a VRAM DMA active? - def VDMA_LENF_BUSY equ 1 << VDMA_LENB_ACTIVE - def VDMA_LENF_NO equ 0 << VDMA_LENB_ACTIVE - def VDMA_LENF_YES equ 1 << VDMA_LENB_ACTIVE + def VDMA_LENF_BUSY equ 1 << VDMA_LENB_BUSY + def VDMA_LENF_NO equ 0 << VDMA_LENB_BUSY + def VDMA_LENF_YES equ 1 << VDMA_LENB_BUSY def VDMA_LENB_SIZE equ %0_1111111 ; how many 16-byte blocks (minus 1) to transfer [r/w] @@ -962,11 +962,11 @@ def rNR50 equ rAUDVOL def rNR51 equ rAUDTERM def rNR52 equ rAUDENA def rKEY1 equ rSPD -def rHDMA1 equ rHDMA_SRC_HIGH -def rHDMA2 equ rHDMA_SRC_LOW -def rHDMA3 equ rHDMA_DEST_HIGH -def rHDMA4 equ rHDMA_DEST_LOW -def rHDMA5 equ rHDMA_LEN +def rHDMA1 equ rVDMA_SRC_HIGH +def rHDMA2 equ rVDMA_SRC_LOW +def rHDMA3 equ rVDMA_DEST_HIGH +def rHDMA4 equ rVDMA_DEST_LOW +def rHDMA5 equ rVDMA_LEN ; Deprecated constants. Please avoid using. From 8bbf15b12d38ca0e345093539c658634e23199e1 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 12:04:07 -0400 Subject: [PATCH 08/27] Finish $FFxx registers --- hardware.inc | 185 +++++++++++++++++++++++---------------------------- 1 file changed, 83 insertions(+), 102 deletions(-) diff --git a/hardware.inc b/hardware.inc index dacb19c..8d0e2dc 100644 --- a/hardware.inc +++ b/hardware.inc @@ -595,113 +595,83 @@ def RPB_LED_ON equ 0 ; 1 = IR light is being sent [r/w] def RPF_WRITE_LO equ 0 << RPB_LED_ON def RPF_WRITE_HI equ 1 << RPB_LED_ON +; -- $FF57-$FF67 are unused --------------------------------------------------- +; -- BGPI / BCPS ($FF68) ------------------------------------------------------ +; (CGB only) Background palette I/O index +def rBGPI equ $FF68 +def BGPIB_AUTOINC equ 7 ; whether the index field is incremented after each write to BCPD [r/w] + def BGPIF_AUTOINC equ 1 << BGPIB_AUTOINC -; -- -; -- BCPS/BGPI ($FF68) -; -- Background Color Palette Specification (aka Background Palette Index) (R/W) -; -- -def rBCPS equ $FF68 -def rBGPI equ rBCPS +def BGPIF_INDEX equ %00_111111 ; the index within Palette RAM accessed via BCPD [r/w] -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 +; -- BGPD / BCPD ($FF69) ------------------------------------------------------ +; (CGB only) Background palette I/O access [r/w] +def rBGPD equ $FF69 +; -- OBPI / OCPS ($FF6A) ------------------------------------------------------ +; (CGB only) OBJ palette I/O index +def rOBPI equ $FF6A -; -- -; -- BCPD/BGPD ($FF69) -; -- Background Color Palette Data (aka Background Palette Data) (R/W) -; -- -def rBCPD equ $FF69 -def rBGPD equ rBCPD +def OBPIB_AUTOINC equ 7 ; whether the index field is incremented after each write to OBPD [r/w] + def OBPIF_AUTOINC equ 1 << OBPIB_AUTOINC +def OBPIF_INDEX equ %00_111111 ; the index within Palette RAM accessed via OBPD [r/w] -; -- -; -- OCPS/OBPI ($FF6A) -; -- Object Color Palette Specification (aka Object Background Palette Index) (R/W) -; -- -def rOCPS equ $FF6A -def rOBPI equ rOCPS +; -- OBPD / OCPD ($FF6B) ------------------------------------------------------ +; (CGB only) OBJ palette I/O access [r/w] +def rOBPD equ $FF6B -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/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 -; -- +; -- OPRI ($FF6C) ------------------------------------------------------------- +; (CGB boot ROM only) OBJ draw priority mode 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) +def OPRIB_PRI equ 0 ; which drawing priority is used for OBJs [r/w] + def OPRIF_PRI equ 1 << OPRIB_PRI + def OPRI_OAM equ 0 << OPRIB_PRI ; CGB mode default: earliest OBJ in OAM wins + def OPRI_COORD equ 1 << OPRIB_PRI ; DMG mode default: leftmost OBJ wins +; -- $FF6D-$FF6F are unused --------------------------------------------------- +; -- SMBK / SVBK ($FF70) ------------------------------------------------------ +; (CGB only) WRAM bank number +def rSMBK equ $FF70 -; -- -; -- SMBK/SVBK ($FF70) -; -- Select Main RAM Bank (R/W) -; -- -; -- Bit 2-0 - Bank Specification (0,1: Specify Bank 1; 2-7: Specify Banks 2-7) -; -- -def rSVBK equ $FF70 -def rSMBK equ rSVBK +def SVMKF_BANK equ %00000_111 ; mapped WRAM bank (0-7) [r/w] +; -- $FF71-$FF75 are unused --------------------------------------------------- -; -- -; -- PCM12 ($FF76) -; -- Sound channel 1&2 PCM amplitude (R) -; -- -; -- Bit 7-4 - Copy of sound channel 2's PCM amplitude -; -- Bit 3-0 - Copy of sound channel 1's PCM amplitude -; -- +; -- PCM12 ($FF76) ------------------------------------------------------------ +; Audio channels 1 and 2 output def rPCM12 equ $FF76 +def PCM12F_CH2 equ %1111_0000 ; audio channel 2 output [ro] +def PCM12F_CH1 equ %0000_1111 ; audio channel 1 output [ro] -; -- -; -- PCM34 ($FF77) -; -- Sound channel 3&4 PCM amplitude (R) -; -- -; -- Bit 7-4 - Copy of sound channel 4's PCM amplitude -; -- Bit 3-0 - Copy of sound channel 3's PCM amplitude -; -- +; -- PCM34 ($FF77) ------------------------------------------------------------ +; Audio channels 3 and 4 output def rPCM34 equ $FF77 +def PCM34F_CH4 equ %1111_0000 ; audio channel 4 output [ro] +def PCM34F_CH3 equ %0000_1111 ; audio channel 3 output [ro] -; -- -; -- IE ($FFFF) -; -- Interrupt Enable (R/W) -; -- -def rIE equ $FFFF +; -- $FF78-$FF7F are unused --------------------------------------------------- -def IEF_JOYPAD equ %00010000 ; Transition from High to Low of Pin number P10-P13 -def IEF_SERIAL equ %00001000 ; Serial I/O transfer end -def IEF_TIMER equ %00000100 ; Timer Overflow -def IEF_STAT equ %00000010 ; STAT -def IEF_VBLANK equ %00000001 ; V-Blank +; -- IE ($FFFF) --------------------------------------------------------------- +; Interrupt enable +def rIE equ $FFFF -def IEB_JOYPAD equ 4 -def IEB_SERIAL equ 3 -def IEB_TIMER equ 2 -def IEB_STAT equ 1 -def IEB_VBLANK equ 0 +def IEB_JOYPAD equ 4 ; 1 = joypad interrupt is enabled [r/w] +def IEB_SERIAL equ 3 ; 1 = serial interrupt is enabled [r/w] +def IEB_TIMER equ 2 ; 1 = timer interrupt is enabled [r/w] +def IEB_STAT equ 1 ; 1 = STAT interrupt is enabled [r/w] +def IEB_VBLANK equ 0 ; 1 = VBlank interrupt is enabled [r/w] + def IEF_JOYPAD equ 1 << IFB_JOYPAD + def IEF_SERIAL equ 1 << IFB_SERIAL + def IEF_TIMER equ 1 << IFB_TIMER + def IEF_STAT equ 1 << IFB_STAT + def IEF_VBLANK equ 1 << IFB_VBLANK ;****************************************************************************** @@ -940,6 +910,16 @@ def OAMB_BANK1 equ 3 ; Bank number; 0,1 (GBC) ; Aliases def rP1 equ rJOYP + def P1F_5 equ JOYP_GET_DPAD + def P1F_4 equ JOYP_GET_BTN + def P1F_3 equ JOYPF_DOWN + def P1F_2 equ JOYPF_UP + def P1F_1 equ JOYPF_LEFT + def P1F_0 equ JOYPF_RIGHT + def P1F_GET_DPAD equ JOYP_GET_DPAD + def P1F_GET_BTN equ JOYP_GET_BTN + def P1F_GET_NONE equ JOYP_GET_NONE + def rNR10 equ rAUD1SWEEP def rNR11 equ rAUD1LEN def rNR12 equ rAUD1ENV @@ -961,12 +941,32 @@ def rNR44 equ rAUD4GO def rNR50 equ rAUDVOL def rNR51 equ rAUDTERM def rNR52 equ rAUDENA + def rKEY1 equ rSPD + def KEY1F_DBLSPEED equ SPDF_DBLSPEED + def KEY1F_PREPARE equ SPDF_PREPARE + def rHDMA1 equ rVDMA_SRC_HIGH def rHDMA2 equ rVDMA_SRC_LOW def rHDMA3 equ rVDMA_DEST_HIGH def rHDMA4 equ rVDMA_DEST_LOW def rHDMA5 equ rVDMA_LEN + def HDMA5B_MODE equ VDMA_LENB_MODE + def HDMA5F_MODE_GP equ VDMA_LENF_MODE_GP + def HDMA5F_MODE_HBL equ VDMA_LENF_MODE_HBL + def HDMA5F_BUSY equ VDMA_LENF_BUSY + +def rBCPS equ rBGPI + def BCPSB_AUTOINC equ BGPIB_AUTOINC + def BCPSF_AUTOINC equ BGPIF_AUTOINC +def rBCPD equ rBGPD + +def rOCPS equ rOBPI + def OCPSB_AUTOINC equ OBPIB_AUTOINC + def OCPSF_AUTOINC equ OBPIF_AUTOINC +def rOCPD equ rOBPD + +def rSVBK equ rSMBK ; Deprecated constants. Please avoid using. @@ -982,23 +982,4 @@ 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 -def P1F_5 equ JOYP_GET_DPAD -def P1F_4 equ JOYP_GET_BTN -def P1F_3 equ JOYPF_DOWN -def P1F_2 equ JOYPF_UP -def P1F_1 equ JOYPF_LEFT -def P1F_0 equ JOYPF_RIGHT - -def P1F_GET_DPAD equ JOYP_GET_DPAD -def P1F_GET_BTN equ JOYP_GET_BTN -def P1F_GET_NONE equ JOYP_GET_NONE - -def KEY1F_DBLSPEED equ 1 << SPDB_DBLSPEED -def KEY1F_PREPARE equ 1 << SPDB_PREPARE - -def HDMA5B_MODE equ VDMA_LENB_MODE -def HDMA5F_MODE_GP equ VDMA_LENF_MODE_GP -def HDMA5F_MODE_HBL equ VDMA_LENF_MODE_HBL -def HDMA5F_BUSY equ VDMA_LENF_BUSY - endc ; HARDWARE_INC From 4bc1f39321e293cadacc7cdb0e1181f42fe2d4cc Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 12:22:31 -0400 Subject: [PATCH 09/27] Finish cartridge MBC registers --- hardware.inc | 78 ++++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/hardware.inc b/hardware.inc index 8d0e2dc..03f1b2e 100644 --- a/hardware.inc +++ b/hardware.inc @@ -674,64 +674,54 @@ def IEB_VBLANK equ 0 ; 1 = VBlank interrupt is enabled [r/w] def IEF_VBLANK equ 1 << IFB_VBLANK -;****************************************************************************** -; Memory regions -;****************************************************************************** - -; Prefer `STARTOF(
)` when the value can be determined at link time -def _ROM equ $0000 ; $0000-$3FFF / $0000-$7FFF (prefer `STARTOF(ROM0)`) -def _ROMBANK equ $4000 ; $4000-$7FFF (prefer `STARTOF(ROMX)`) -def _VRAM equ $8000 ; $8000-$9FFF (prefer `STARTOF(VRAM)`) -def _SRAM equ $A000 ; $A000-$BFFF (prefer `STARTOF(SRAM)`) -def _RAM equ $C000 ; $C000-$CFFF / $C000-$DFFF (prefer `STARTOF(WRAM0)`) -def _RAMBANK equ $D000 ; $D000-$DFFF (prefer `STARTOF(WRAMX)`) -def _OAMRAM equ $FE00 ; $FE00-$FE9F (prefer `STARTOF(OAM)`) -def _IO equ $FF00 ; $FF00-$FF7F, $FFFF -def _HRAM equ $FF80 ; $FF80-$FFFE (prefer `STARTOF(HRAM)`) - - ;****************************************************************************** ; Cartridge registers (MBC) ;****************************************************************************** +; Note that these "registers" are each actually accessible at an entire address range; +; however, one address for each of these ranges is considered the "canonical" one, and +; these addresses are what's provided here. + ; -- RAMG ($0000-$1FFF) ------------------------------------------------------- -; RAM enable [w] +; Whether SRAM can be accessed [wo] def rRAMG equ $0000 ; Common values -def CART_SRAM_ENABLE equ $0A def CART_SRAM_DISABLE equ $00 - -; MBC3-specific values -def RTC_S equ $08 ; seconds counter (0-59) -def RTC_M equ $09 ; minutes counter (0-59) -def RTC_H equ $0A ; hours counter (0-23) -def RTC_DL equ $0B ; days counter, low byte (0-255) -def RTC_DH equ $0C ; days counter, high bit and other flags - def RTC_DHB_OVERFLOW equ 7 ; 1 = days counter overflowed [w] - def RTC_DHB_HALT equ 6 ; 0 = run timer, 1 = stop timer [w] - def RTC_DHB_HIGH equ 0 ; days counter, high bit (bit 8) [w] - def RTC_DHF_OVERFLOW equ 1 << RTC_DHB_OVERFLOW - def RTC_DHF_HALT equ 1 << RTC_DHB_HALT - def RTC_DHF_HIGH equ 1 << RTC_DHB_HIGH +def CART_SRAM_ENABLE equ $0A ; some MBCs accept any value whose low nybble is $A ; -- ROMB0 ($2000-$3FFF) ------------------------------------------------------ -; ROM bank number [w] +; ROM bank number (low 8 bits when applicable) [wo] def rROMB0 equ $2000 ; -- ROMB1 ($3000-$3FFF) ------------------------------------------------------ -; (MBC5 only) ROM bank number bit 8 [w] +; (MBC5 only) ROM bank number high bit (bit 8) [wo] def rROMB1 equ $3000 ; -- RAMB ($4000-$5FFF) ------------------------------------------------------- -; RAM bank number [w] + ; SRAM bank number [wo] def rRAMB equ $4000 +; (MBC3-only) Special RAM bank numbers that actually map the RTC registers +def RTC_S equ $08 ; seconds counter (0-59) +def RTC_M equ $09 ; minutes counter (0-59) +def RTC_H equ $0A ; hours counter (0-23) +def RTC_DL equ $0B ; days counter, low byte (0-255) +def RTC_DH equ $0C ; days counter, high bit and other flags + def RTC_DHB_CARRY equ 7 ; 1 = days counter overflowed [wo] + def RTC_DHB_HALT equ 6 ; 0 = run timer, 1 = stop timer [wo] + def RTC_DHB_HIGH equ 0 ; days counter, high bit (bit 8) [wo] + def RTC_DHF_CARRY equ 1 << RTC_DHB_CARRY + def RTC_DHF_HALT equ 1 << RTC_DHB_HALT + def RTC_DHF_HIGH equ 1 << RTC_DHB_HIGH + def CARTB_RUMBLE_ON equ 3 ; (MBC5 and MBC7 only) enable the rumble motor (if any) - def CART_RUMBLE_ON equ 1 << CARTB_RUMBLE_ON + def CARTF_RUMBLE_ON equ 1 << CARTB_RUMBLE_ON + def CART_RUMBLE_OFF equ 0 << CARTB_RUMBLE_ON + def CART_RUMBLE_ON equ 1 << CARTB_RUMBLE_ON ; -- RTCLATCH ($6000-$7FFF) --------------------------------------------------- -; (MBC3 only) RTC latch clock data [w] +; (MBC3 only) RTC latch clock data [wo] def rRTCLATCH equ $6000 ; Write $00 then $01 to latch the current time into the RTC registers @@ -739,6 +729,22 @@ def RTCLATCH_START equ $00 def RTCLATCH_FINISH equ $01 +;****************************************************************************** +; Memory regions +;****************************************************************************** + +; Prefer `STARTOF(
)` when the value can be determined at link time +def _ROM equ $0000 ; $0000-$3FFF / $0000-$7FFF (prefer `STARTOF(ROM0)`) +def _ROMBANK equ $4000 ; $4000-$7FFF (prefer `STARTOF(ROMX)`) +def _VRAM equ $8000 ; $8000-$9FFF (prefer `STARTOF(VRAM)`) +def _SRAM equ $A000 ; $A000-$BFFF (prefer `STARTOF(SRAM)`) +def _RAM equ $C000 ; $C000-$CFFF / $C000-$DFFF (prefer `STARTOF(WRAM0)`) +def _RAMBANK equ $D000 ; $D000-$DFFF (prefer `STARTOF(WRAMX)`) +def _OAMRAM equ $FE00 ; $FE00-$FE9F (prefer `STARTOF(OAM)`) +def _IO equ $FF00 ; $FF00-$FF7F, $FFFF +def _HRAM equ $FF80 ; $FF80-$FFFE (prefer `STARTOF(HRAM)`) + + ;*************************************************************************** ;* ;* CPU values on bootup (a=type, b=qualifier) From dbe2383097a060e293e8ac712576967dfde5e5bc Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 12:55:47 -0400 Subject: [PATCH 10/27] Finish deprecated constants --- hardware.inc | 243 ++++++++++++++++++++++++++------------------------- 1 file changed, 125 insertions(+), 118 deletions(-) diff --git a/hardware.inc b/hardware.inc index 03f1b2e..ed9180e 100644 --- a/hardware.inc +++ b/hardware.inc @@ -667,11 +667,11 @@ def IEB_SERIAL equ 3 ; 1 = serial interrupt is enabled [r/w] def IEB_TIMER equ 2 ; 1 = timer interrupt is enabled [r/w] def IEB_STAT equ 1 ; 1 = STAT interrupt is enabled [r/w] def IEB_VBLANK equ 0 ; 1 = VBlank interrupt is enabled [r/w] - def IEF_JOYPAD equ 1 << IFB_JOYPAD - def IEF_SERIAL equ 1 << IFB_SERIAL - def IEF_TIMER equ 1 << IFB_TIMER - def IEF_STAT equ 1 << IFB_STAT - def IEF_VBLANK equ 1 << IFB_VBLANK + def IEF_JOYPAD equ 1 << IEB_JOYPAD + def IEF_SERIAL equ 1 << IEB_SERIAL + def IEF_TIMER equ 1 << IEB_TIMER + def IEF_STAT equ 1 << IEB_STAT + def IEF_VBLANK equ 1 << IEB_VBLANK ;****************************************************************************** @@ -729,22 +729,6 @@ def RTCLATCH_START equ $00 def RTCLATCH_FINISH equ $01 -;****************************************************************************** -; Memory regions -;****************************************************************************** - -; Prefer `STARTOF(
)` when the value can be determined at link time -def _ROM equ $0000 ; $0000-$3FFF / $0000-$7FFF (prefer `STARTOF(ROM0)`) -def _ROMBANK equ $4000 ; $4000-$7FFF (prefer `STARTOF(ROMX)`) -def _VRAM equ $8000 ; $8000-$9FFF (prefer `STARTOF(VRAM)`) -def _SRAM equ $A000 ; $A000-$BFFF (prefer `STARTOF(SRAM)`) -def _RAM equ $C000 ; $C000-$CFFF / $C000-$DFFF (prefer `STARTOF(WRAM0)`) -def _RAMBANK equ $D000 ; $D000-$DFFF (prefer `STARTOF(WRAMX)`) -def _OAMRAM equ $FE00 ; $FE00-$FE9F (prefer `STARTOF(OAM)`) -def _IO equ $FF00 ; $FF00-$FF7F, $FFFF -def _HRAM equ $FF80 ; $FF80-$FFFE (prefer `STARTOF(HRAM)`) - - ;*************************************************************************** ;* ;* CPU values on bootup (a=type, b=qualifier) @@ -774,87 +758,6 @@ def INT_HANDLER_SERIAL equ $0058 def INT_HANDLER_JOYPAD equ $0060 -;*************************************************************************** -;* -;* Header -;* -;*************************************************************************** - -;* -;* Nintendo scrolling logo -;* (Code won't work on a real Game Boy) -;* (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 Game Boy compatibility code -def CART_COMPATIBLE_DMG equ $00 -def CART_COMPATIBLE_DMG_GBC equ $80 -def CART_COMPATIBLE_GBC equ $C0 - -; $0146 Game Boy/Super Game Boy indicator -def CART_INDICATOR_GB equ $00 -def CART_INDICATOR_SGB equ $03 - -; $0147 Cartridge type -def CART_ROM equ $00 -def CART_ROM_MBC1 equ $01 -def CART_ROM_MBC1_RAM equ $02 -def CART_ROM_MBC1_RAM_BAT equ $03 -def CART_ROM_MBC2 equ $05 -def CART_ROM_MBC2_BAT equ $06 -def CART_ROM_RAM equ $08 -def CART_ROM_RAM_BAT equ $09 -def CART_ROM_MMM01 equ $0B -def CART_ROM_MMM01_RAM equ $0C -def CART_ROM_MMM01_RAM_BAT equ $0D -def CART_ROM_MBC3_BAT_RTC equ $0F -def CART_ROM_MBC3_RAM_BAT_RTC equ $10 -def CART_ROM_MBC3 equ $11 -def CART_ROM_MBC3_RAM equ $12 -def CART_ROM_MBC3_RAM_BAT equ $13 -def CART_ROM_MBC5 equ $19 -def CART_ROM_MBC5_RAM equ $1A -def CART_ROM_MBC5_RAM_BAT equ $1B -def CART_ROM_MBC5_RUMBLE equ $1C -def CART_ROM_MBC5_RAM_RUMBLE equ $1D -def CART_ROM_MBC5_RAM_BAT_RUMBLE equ $1E -def CART_ROM_MBC7_RAM_BAT_GYRO equ $22 -def CART_ROM_POCKET_CAMERA equ $FC -def CART_ROM_BANDAI_TAMA5 equ $FD -def CART_ROM_HUDSON_HUC3 equ $FE -def CART_ROM_HUDSON_HUC1 equ $FF - -; $0148 ROM size -; these are kilobytes -def CART_ROM_32KB equ $00 ; 2 banks -def CART_ROM_64KB equ $01 ; 4 banks -def CART_ROM_128KB equ $02 ; 8 banks -def CART_ROM_256KB equ $03 ; 16 banks -def CART_ROM_512KB equ $04 ; 32 banks -def CART_ROM_1024KB equ $05 ; 64 banks -def CART_ROM_2048KB equ $06 ; 128 banks -def CART_ROM_4096KB equ $07 ; 256 banks -def CART_ROM_8192KB equ $08 ; 512 banks -def CART_ROM_1152KB equ $52 ; 72 banks -def CART_ROM_1280KB equ $53 ; 80 banks -def CART_ROM_1536KB equ $54 ; 96 banks - -; $0149 SRAM size -; these are kilobytes -def CART_SRAM_NONE equ 0 -def CART_SRAM_8KB equ 2 ; 1 bank -def CART_SRAM_32KB equ 3 ; 4 banks -def CART_SRAM_128KB equ 4 ; 16 banks - -; $014A Destination code -def CART_DEST_JAPANESE equ $00 -def CART_DEST_NON_JAPANESE equ $01 - - ;*************************************************************************** ;* ;* Screen related @@ -913,18 +816,23 @@ def OAMB_PAL1 equ 4 ; Palette number; 0,1 (DMG) def OAMB_BANK1 equ 3 ; Bank number; 0,1 (GBC) +;****************************************************************************** ; Aliases +;****************************************************************************** + +; Prefer the standard names to these aliases, which may be official but are +; less directly meaningful or human-readable. -def rP1 equ rJOYP +def rP1 equ rJOYP + def P1F_GET_BTN equ JOYP_GET_BTN + def P1F_GET_DPAD equ JOYP_GET_DPAD + def P1F_GET_NONE equ JOYP_GET_NONE def P1F_5 equ JOYP_GET_DPAD def P1F_4 equ JOYP_GET_BTN def P1F_3 equ JOYPF_DOWN def P1F_2 equ JOYPF_UP def P1F_1 equ JOYPF_LEFT def P1F_0 equ JOYPF_RIGHT - def P1F_GET_DPAD equ JOYP_GET_DPAD - def P1F_GET_BTN equ JOYP_GET_BTN - def P1F_GET_NONE equ JOYP_GET_NONE def rNR10 equ rAUD1SWEEP def rNR11 equ rAUD1LEN @@ -958,9 +866,9 @@ def rHDMA3 equ rVDMA_DEST_HIGH def rHDMA4 equ rVDMA_DEST_LOW def rHDMA5 equ rVDMA_LEN def HDMA5B_MODE equ VDMA_LENB_MODE - def HDMA5F_MODE_GP equ VDMA_LENF_MODE_GP - def HDMA5F_MODE_HBL equ VDMA_LENF_MODE_HBL - def HDMA5F_BUSY equ VDMA_LENF_BUSY + def HDMA5F_MODE_GP equ VDMA_LENF_MODE_GP + def HDMA5F_MODE_HBL equ VDMA_LENF_MODE_HBL + def HDMA5F_BUSY equ VDMA_LENF_BUSY def rBCPS equ rBGPI def BCPSB_AUTOINC equ BGPIB_AUTOINC @@ -974,18 +882,117 @@ def rOCPD equ rOBPD def rSVBK equ rSMBK -; Deprecated constants. Please avoid using. +; These values are deprecated; please avoid using them. + +def LCDCB_BG8000 equ LCDCB_BLKS + def LCDCF_BG8800 equ LCDCF_BLK21 + def LCDCF_BG8000 equ LCDCF_BLK01 def IEB_HILO equ IEB_JOYPAD -def IEF_HILO equ 1 << IEB_JOYPAD + def IEF_HILO equ IEF_JOYPAD +def IEF_LCDC equ IEF_STAT + + +;****************************************************************************** +; (deprecated) Memory regions +;****************************************************************************** + +; These values are deprecated; please use RGBASM and RGBLINK features instead. +; Note that the value of `STARTOF()` is determined at link time. + +def _ROM equ $0000 ; $0000-$3FFF / $0000-$7FFF (prefer `STARTOF(ROM0)`) +def _ROMBANK equ $4000 ; $4000-$7FFF (prefer `STARTOF(ROMX)`) +def _VRAM equ $8000 ; $8000-$9FFF (prefer `STARTOF(VRAM)`) +def _SRAM equ $A000 ; $A000-$BFFF (prefer `STARTOF(SRAM)`) +def _RAM equ $C000 ; $C000-$CFFF / $C000-$DFFF (prefer `STARTOF(WRAM0)`) +def _RAMBANK equ $D000 ; $D000-$DFFF (prefer `STARTOF(WRAMX)`) +def _OAMRAM equ $FE00 ; $FE00-$FE9F (prefer `STARTOF(OAM)`) +def _IO equ $FF00 ; $FF00-$FF7F, $FFFF (prefer `ldh [c]` to `ld [_IO+c]`) +def _HRAM equ $FF80 ; $FF80-$FFFE (prefer `STARTOF(HRAM)`) -def IEF_LCDC equ IEF_STAT ; 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 +def _VRAM8800 equ _VRAM + $800 +def _VRAM9000 equ _VRAM + $1000 + + +;****************************************************************************** +; (deprecated) Cartridge header +;****************************************************************************** + +; These values are deprecated; please use RGBFIX instead. + +; -- Nintendo logo ($0104-$0133) ---------------------------------------------- +; Prefer `rgbfix -f/--fix-spec l` for the official logo, or `rgbfix -L ` for a custom one +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 + +; -- CGB compatibility code ($0143) ------------------------------------------- +def CART_COMPATIBLE_DMG equ $00 +def CART_COMPATIBLE_DMG_GBC equ $80 ; prefer `rgbfix -c/--color-compatible` +def CART_COMPATIBLE_GBC equ $C0 ; prefer `rgbfix -C/--color-only` + +; -- SGB flag ($0146) --------------------------------------------------------- +def CART_INDICATOR_GB equ $00 +def CART_INDICATOR_SGB equ $03 ; prefer `rgblink -s/--sgb-compatible` + +; -- Cartridge type ($0147) --------------------------------------------------- +; Prefer `rgblink -m/--mbc_type ` +def CART_ROM equ $00 +def CART_ROM_MBC1 equ $01 +def CART_ROM_MBC1_RAM equ $02 +def CART_ROM_MBC1_RAM_BAT equ $03 +def CART_ROM_MBC2 equ $05 +def CART_ROM_MBC2_BAT equ $06 +def CART_ROM_RAM equ $08 +def CART_ROM_RAM_BAT equ $09 +def CART_ROM_MMM01 equ $0B +def CART_ROM_MMM01_RAM equ $0C +def CART_ROM_MMM01_RAM_BAT equ $0D +def CART_ROM_MBC3_BAT_RTC equ $0F +def CART_ROM_MBC3_RAM_BAT_RTC equ $10 +def CART_ROM_MBC3 equ $11 +def CART_ROM_MBC3_RAM equ $12 +def CART_ROM_MBC3_RAM_BAT equ $13 +def CART_ROM_MBC5 equ $19 +def CART_ROM_MBC5_RAM equ $1A +def CART_ROM_MBC5_RAM_BAT equ $1B +def CART_ROM_MBC5_RUMBLE equ $1C +def CART_ROM_MBC5_RAM_RUMBLE equ $1D +def CART_ROM_MBC5_RAM_BAT_RUMBLE equ $1E +def CART_ROM_MBC7_RAM_BAT_GYRO equ $22 +def CART_ROM_POCKET_CAMERA equ $FC +def CART_ROM_BANDAI_TAMA5 equ $FD +def CART_ROM_HUDSON_HUC3 equ $FE +def CART_ROM_HUDSON_HUC1 equ $FF + +; -- ROM size ($0148) --------------------------------------------------------- +; Prefer `rgbfix -p/--pad_value `, which pads to the smallest valid size +def CART_ROM_32KB equ $00 ; 2 banks +def CART_ROM_64KB equ $01 ; 4 banks +def CART_ROM_128KB equ $02 ; 8 banks +def CART_ROM_256KB equ $03 ; 16 banks +def CART_ROM_512KB equ $04 ; 32 banks +def CART_ROM_1024KB equ $05 ; 64 banks +def CART_ROM_2048KB equ $06 ; 128 banks +def CART_ROM_4096KB equ $07 ; 256 banks +def CART_ROM_8192KB equ $08 ; 512 banks +def CART_ROM_1152KB equ $52 ; 72 banks +def CART_ROM_1280KB equ $53 ; 80 banks +def CART_ROM_1536KB equ $54 ; 96 banks + +; -- SRAM size ($0149) -------------------------------------------------------- +; Prefer `rgbfix -r/--ram_size ` +def CART_SRAM_NONE equ 0 ; none +def CART_SRAM_2KB equ 1 ; 1 incomplete bank (homebrew only) +def CART_SRAM_8KB equ 2 ; 1 bank +def CART_SRAM_32KB equ 3 ; 4 banks +def CART_SRAM_128KB equ 4 ; 16 banks + +; -- Destination code ($014A) ------------------------------------------------- +def CART_DEST_JAPANESE equ $00 +def CART_DEST_NON_JAPANESE equ $01 ; prefer `rgbfix -j/--non-japanese` endc ; HARDWARE_INC From fc840973a8c5a2d3c8973773e1e6d265ef3d858a Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 13:04:31 -0400 Subject: [PATCH 11/27] Start porting some constants from gb-bootroms --- hardware.inc | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/hardware.inc b/hardware.inc index ed9180e..b4777d6 100644 --- a/hardware.inc +++ b/hardware.inc @@ -408,6 +408,8 @@ def rAUD3WAVE_D equ $FF3D def rAUD3WAVE_E equ $FF3E def rAUD3WAVE_F equ $FF3F +def AUD3WAVE_SIZE equ 16 + ; -- LCDC ($FF40) ------------------------------------------------------------- ; PPU graphics control def rLCDC equ $FF40 @@ -634,11 +636,11 @@ def OPRIB_PRI equ 0 ; which drawing priority is used for OBJs [r/w] ; -- $FF6D-$FF6F are unused --------------------------------------------------- -; -- SMBK / SVBK ($FF70) ------------------------------------------------------ +; -- WBK / SVBK / SMBK ($FF70) ------------------------------------------------ ; (CGB only) WRAM bank number -def rSMBK equ $FF70 +def rWBK equ $FF70 -def SVMKF_BANK equ %00000_111 ; mapped WRAM bank (0-7) [r/w] +def WBKF_BANK equ %00000_111 ; mapped WRAM bank (0-7) [r/w] ; -- $FF71-$FF75 are unused --------------------------------------------------- @@ -777,6 +779,14 @@ def SCRN_VY equ 256 ; Virtual height of screen in pixels def SCRN_VX_B equ 32 ; Virtual width of screen in bytes def SCRN_VY_B equ 32 ; Virtual height of screen in bytes +; from gb-bootroms +DEF COLOR_MASK equ $1F ; Each color spans 5 bits +DEF COLOR_MAX equ $1F +DEF COLOR_SIZE equ 2 ; Colors are encoded as 2-byte little-endian BGR555 +DEF COLORS_PER_PALETTE equ 4 +DEF PALETTE_SIZE equ COLOR_SIZE * COLORS_PER_PALETTE +DEF TILE_SIZE equ 16 ; Each tile is 16 bytes = 8x8 pixels * 2 bits/pixel + ;*************************************************************************** ;* @@ -815,6 +825,10 @@ def OAMB_XFLIP equ 5 ; X flip def OAMB_PAL1 equ 4 ; Palette number; 0,1 (DMG) def OAMB_BANK1 equ 3 ; Bank number; 0,1 (GBC) +; from gb-bootroms +DEF OBJ_SIZE equ 4 ; Each OAM OBJ is 4 bytes +DEF OAM_SIZE equ OAM_COUNT * OBJ_SIZE + ;****************************************************************************** ; Aliases @@ -880,7 +894,8 @@ def rOCPS equ rOBPI def OCPSF_AUTOINC equ OBPIF_AUTOINC def rOCPD equ rOBPD -def rSVBK equ rSMBK +def rSVBK equ rWBK +def rSMBK equ rWBK ; These values are deprecated; please avoid using them. From 3233aaacee13ae00e62b5a4554fa2690903b8d54 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 13:19:33 -0400 Subject: [PATCH 12/27] Finish CPU values on bootup and interrupt vector addresses --- hardware.inc | 62 +++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/hardware.inc b/hardware.inc index b4777d6..65d0c9d 100644 --- a/hardware.inc +++ b/hardware.inc @@ -731,35 +731,6 @@ def RTCLATCH_START equ $00 def RTCLATCH_FINISH equ $01 -;*************************************************************************** -;* -;* CPU values on bootup (a=type, b=qualifier) -;* -;*************************************************************************** - -def BOOTUP_A_DMG equ $01 ; Dot Matrix Game -def BOOTUP_A_CGB equ $11 ; Color Game Boy -def BOOTUP_A_MGB equ $FF ; Mini Game Boy (Pocket Game Boy) - -; if a=BOOTUP_A_CGB, bit 0 in b can be checked to determine if real CGB or -; other system running in GBC mode -def BOOTUP_B_CGB equ %00000000 -def BOOTUP_B_AGB equ %00000001 ; GBA, GBA SP, Game Boy Player, or New GBA SP - - -;*************************************************************************** -;* -;* 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 - - ;*************************************************************************** ;* ;* Screen related @@ -830,6 +801,33 @@ DEF OBJ_SIZE equ 4 ; Each OAM OBJ is 4 bytes DEF OAM_SIZE equ OAM_COUNT * OBJ_SIZE +;****************************************************************************** +; CPU values on bootup +;****************************************************************************** + +; Register A = CPU type +def BOOTUP_A_DMG equ $01 ; DMG (Dot Matrix Game, aka Game Boy) +def BOOTUP_A_CGB equ $11 ; CGB (Color Game Boy, aka Game Boy Color) + ; or AGB (Advance Game Boy, aka GBA, GBA SP, GB Player, or New GBA SP) +def BOOTUP_A_MGB equ $FF ; MGB (Mini Game Boy, aka Game Boy Pocket) + +; Register B = CPU qualifier (if A is BOOTUP_A_CGB) +def BOOTUP_B_AGBB equ 0 + def BOOTUP_B_CGB equ 0 << BOOTUP_B_AGBB ; CPU is really CGB + def BOOTUP_B_AGB equ 1 << BOOTUP_B_AGBB ; CPU is actually AGB + + +;****************************************************************************** +; Interrupt vector addresses +;****************************************************************************** + +def INT_HANDLER_VBLANK equ $0040 ; VBlank interrupt handler address +def INT_HANDLER_STAT equ $0048 ; STAT interrupt handler address +def INT_HANDLER_TIMER equ $0050 ; timer interrupt handler address +def INT_HANDLER_SERIAL equ $0058 ; serial interrupt handler address +def INT_HANDLER_JOYPAD equ $0060 ; joypad interrupt handler address + + ;****************************************************************************** ; Aliases ;****************************************************************************** @@ -925,9 +923,9 @@ def _OAMRAM equ $FE00 ; $FE00-$FE9F (prefer `STARTOF(OAM)`) def _IO equ $FF00 ; $FF00-$FF7F, $FFFF (prefer `ldh [c]` to `ld [_IO+c]`) def _HRAM equ $FF80 ; $FF80-$FFFE (prefer `STARTOF(HRAM)`) -def _VRAM8000 equ _VRAM -def _VRAM8800 equ _VRAM + $800 -def _VRAM9000 equ _VRAM + $1000 +def _VRAM8000 equ _VRAM +def _VRAM8800 equ _VRAM + $800 +def _VRAM9000 equ _VRAM + $1000 ;****************************************************************************** From 77c4186fd17d8efb97b3d82ae4946b9e236ede99 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 14:12:50 -0400 Subject: [PATCH 13/27] Finish screen-related constants --- hardware.inc | 80 +++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/hardware.inc b/hardware.inc index 65d0c9d..74e851c 100644 --- a/hardware.inc +++ b/hardware.inc @@ -731,32 +731,35 @@ def RTCLATCH_START equ $00 def RTCLATCH_FINISH equ $01 -;*************************************************************************** -;* -;* Screen related -;* -;*************************************************************************** +;****************************************************************************** +; Screen-related constants +;****************************************************************************** -def _SCRN0 equ $9800 ; $9800-$9BFF -def _SCRN1 equ $9C00 ; $9C00-$9FFF +def SCRN_X equ 160 ; width of screen in pixels +def SCRN_Y equ 144 ; height of screen in pixels +def SCRN_X_B equ 20 ; width of screen in bytes +def SCRN_Y_B equ 18 ; height of screen in bytes -def SCRN_X equ 160 ; Width 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 +def SCRN_VX equ 256 ; width of tilemap in pixels +def SCRN_VY equ 256 ; height of tilemap in pixels +def SCRN_VX_B equ 32 ; width of tilemap in bytes +def SCRN_VY_B equ 32 ; height of tilemap in bytes -def SCRN_VX equ 256 ; Virtual width of screen in pixels -def SCRN_VY equ 256 ; Virtual height of screen in pixels -def SCRN_VX_B equ 32 ; Virtual width of screen in bytes -def SCRN_VY_B equ 32 ; Virtual height of screen in bytes +def TILE_X equ 8 ; width of tile in pixels +def TILE_Y equ 8 ; height of tile in pixels +def TILE_B equ 16 ; size of tile in bytes (2 bits/pixel) -; from gb-bootroms -DEF COLOR_MASK equ $1F ; Each color spans 5 bits -DEF COLOR_MAX equ $1F -DEF COLOR_SIZE equ 2 ; Colors are encoded as 2-byte little-endian BGR555 -DEF COLORS_PER_PALETTE equ 4 -DEF PALETTE_SIZE equ COLOR_SIZE * COLORS_PER_PALETTE -DEF TILE_SIZE equ 16 ; Each tile is 16 bytes = 8x8 pixels * 2 bits/pixel +def COLOR_B equ 2 ; size of color in bytes (little-endian BGR555) + def COLORF_BLUE equ %0_11111_00 + def COLORF_GREEN_HIGH equ %000000_11 + def COLORF_GREEN_LOW equ %111_00000 + def COLORF_RED equ %000_11111 +def PAL_COLORS equ 4 ; colors per palette +def PAL_B equ COLOR_B * PAL_COLORS ; size of palette in bytes + +; Tilemaps the BG or Window can read from (controlled by LCDC) +def _SCRN0 equ $9800 ; $9800-$9BFF +def _SCRN1 equ $9C00 ; $9C00-$9FFF ;*************************************************************************** @@ -801,22 +804,6 @@ DEF OBJ_SIZE equ 4 ; Each OAM OBJ is 4 bytes DEF OAM_SIZE equ OAM_COUNT * OBJ_SIZE -;****************************************************************************** -; CPU values on bootup -;****************************************************************************** - -; Register A = CPU type -def BOOTUP_A_DMG equ $01 ; DMG (Dot Matrix Game, aka Game Boy) -def BOOTUP_A_CGB equ $11 ; CGB (Color Game Boy, aka Game Boy Color) - ; or AGB (Advance Game Boy, aka GBA, GBA SP, GB Player, or New GBA SP) -def BOOTUP_A_MGB equ $FF ; MGB (Mini Game Boy, aka Game Boy Pocket) - -; Register B = CPU qualifier (if A is BOOTUP_A_CGB) -def BOOTUP_B_AGBB equ 0 - def BOOTUP_B_CGB equ 0 << BOOTUP_B_AGBB ; CPU is really CGB - def BOOTUP_B_AGB equ 1 << BOOTUP_B_AGBB ; CPU is actually AGB - - ;****************************************************************************** ; Interrupt vector addresses ;****************************************************************************** @@ -828,6 +815,23 @@ def INT_HANDLER_SERIAL equ $0058 ; serial interrupt handler address def INT_HANDLER_JOYPAD equ $0060 ; joypad interrupt handler address +;****************************************************************************** +; Boot-up register values +;****************************************************************************** + +; Register A = CPU type +def BOOTUP_A_DMG equ $01 +def BOOTUP_A_CGB equ $11 ; CGB or AGB +def BOOTUP_A_MGB equ $FF + def BOOTUP_A_SGB equ BOOTUP_A_DMG + def BOOTUP_A_SGB2 equ BOOTUP_A_MGB + +; Register B = CPU qualifier (if A is BOOTUP_A_CGB) +def BOOTUP_B_AGBB equ 0 + def BOOTUP_B_CGB equ 0 << BOOTUP_B_AGBB + def BOOTUP_B_AGB equ 1 << BOOTUP_B_AGBB + + ;****************************************************************************** ; Aliases ;****************************************************************************** From baf5e1823bac32dff0c552c2e857c41c313683fb Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 14:24:12 -0400 Subject: [PATCH 14/27] Finish OAM constants --- hardware.inc | 95 +++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 50 deletions(-) diff --git a/hardware.inc b/hardware.inc index 74e851c..c1e4f09 100644 --- a/hardware.inc +++ b/hardware.inc @@ -762,46 +762,34 @@ def _SCRN0 equ $9800 ; $9800-$9BFF def _SCRN1 equ $9C00 ; $9C00-$9FFF -;*************************************************************************** -;* -;* OAM related -;* -;*************************************************************************** - -; OAM attributes -; each entry in OAM RAM is 4 bytes (sizeof_OAM_ATTRS) -RSRESET -def OAMA_Y RB 1 ; y pos plus 16 -def OAMA_X RB 1 ; x pos plus 8 -def OAMA_TILEID RB 1 ; tile id -def OAMA_FLAGS RB 1 ; flags (see below) -def sizeof_OAM_ATTRS RB 0 - -def OAM_Y_OFS equ 16 ; add this to a screen-relative Y position to get an OAM Y position -def OAM_X_OFS equ 8 ; add this to a screen-relative X position to get an OAM X position - -def OAM_COUNT equ 40 ; number of OAM entries in OAM RAM - -; flags -def OAMF_PRI equ %10000000 ; Priority -def OAMF_YFLIP equ %01000000 ; Y flip -def OAMF_XFLIP equ %00100000 ; X flip -def OAMF_PAL0 equ %00000000 ; Palette number; 0,1 (DMG) -def OAMF_PAL1 equ %00010000 ; Palette number; 0,1 (DMG) -def OAMF_BANK0 equ %00000000 ; Bank number; 0,1 (GBC) -def OAMF_BANK1 equ %00001000 ; Bank number; 0,1 (GBC) - -def OAMF_PALMASK equ %00000111 ; Palette (GBC) - -def OAMB_PRI equ 7 ; Priority -def OAMB_YFLIP equ 6 ; Y flip -def OAMB_XFLIP equ 5 ; X flip -def OAMB_PAL1 equ 4 ; Palette number; 0,1 (DMG) -def OAMB_BANK1 equ 3 ; Bank number; 0,1 (GBC) - -; from gb-bootroms -DEF OBJ_SIZE equ 4 ; Each OAM OBJ is 4 bytes -DEF OAM_SIZE equ OAM_COUNT * OBJ_SIZE +;****************************************************************************** +; OBJ-related constants +;****************************************************************************** + +; OAM attribute field offsets +def OAMA_Y equ 0 + def OAM_Y_OFS equ 16 ; subtract 16 from what's written to OAM to get the real Y position +def OAMA_X equ 1 + def OAM_X_OFS equ 8 ; subtract 8 from what's written to OAM to get the real X position +def OAMA_TILEID equ 2 +def OAMA_FLAGS equ 3 + def OAMB_PRI equ 7 ; whether the OBJ is drawn above BG colors 1-3 + def OAMB_YFLIP equ 6 ; whether the whole OBJ is flipped vertically + def OAMB_XFLIP equ 5 ; whether the whole OBJ is flipped horizontally + def OAMB_PAL1 equ 4 ; (DMG only) which of the two palettes the OBJ uses + def OAMB_BANK1 equ 3 ; (CGB only) which VRAM bank the OBJ takes its tile(s) from + def OAMF_PALMASK equ %00000_111 ; (CGB only) which palette the OBJ uses + def OAMF_PRI equ 1 << OAMB_PRI + def OAMF_YFLIP equ 1 << OAMB_YFLIP + def OAMF_XFLIP equ 1 << OAMB_XFLIP + def OAMF_PAL0 equ 0 << OAMB_PAL1 + def OAMF_PAL1 equ 1 << OAMB_PAL1 + def OAMF_BANK0 equ 0 << OAMB_BANK1 + def OAMF_BANK1 equ 1 << OAMB_BANK1 + +def OBJ_B equ 4 ; size of OBJ in bytes +def OAM_COUNT equ 40 ; how many OBJs there are room for in OAM +def OAM_B equ OBJ_B * OAM_COUNT ;****************************************************************************** @@ -899,16 +887,6 @@ def rOCPD equ rOBPD def rSVBK equ rWBK def rSMBK equ rWBK -; These values are deprecated; please avoid using them. - -def LCDCB_BG8000 equ LCDCB_BLKS - def LCDCF_BG8800 equ LCDCF_BLK21 - def LCDCF_BG8000 equ LCDCF_BLK01 - -def IEB_HILO equ IEB_JOYPAD - def IEF_HILO equ IEF_JOYPAD -def IEF_LCDC equ IEF_STAT - ;****************************************************************************** ; (deprecated) Memory regions @@ -1012,4 +990,21 @@ def CART_SRAM_128KB equ 4 ; 16 banks def CART_DEST_JAPANESE equ $00 def CART_DEST_NON_JAPANESE equ $01 ; prefer `rgbfix -j/--non-japanese` + +;****************************************************************************** +; Deprecated constants +;****************************************************************************** + +; These values are deprecated; please avoid using them. + +def LCDCB_BG8000 equ LCDCB_BLKS + def LCDCF_BG8800 equ LCDCF_BLK21 + def LCDCF_BG8000 equ LCDCF_BLK01 + +def IEB_HILO equ IEB_JOYPAD + def IEF_HILO equ IEF_JOYPAD +def IEF_LCDC equ IEF_STAT + +def sizeof_OAM_ATTRS equ OBJ_B + endc ; HARDWARE_INC From 33ce4b9a88d9c06c34d3f256d056271331624cb2 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 14:34:32 -0400 Subject: [PATCH 15/27] Fix spacing --- hardware.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware.inc b/hardware.inc index c1e4f09..e668bc4 100644 --- a/hardware.inc +++ b/hardware.inc @@ -869,7 +869,7 @@ def rHDMA2 equ rVDMA_SRC_LOW def rHDMA3 equ rVDMA_DEST_HIGH def rHDMA4 equ rVDMA_DEST_LOW def rHDMA5 equ rVDMA_LEN - def HDMA5B_MODE equ VDMA_LENB_MODE + def HDMA5B_MODE equ VDMA_LENB_MODE def HDMA5F_MODE_GP equ VDMA_LENF_MODE_GP def HDMA5F_MODE_HBL equ VDMA_LENF_MODE_HBL def HDMA5F_BUSY equ VDMA_LENF_BUSY From cbbabcdce991a97b91cf1fd6f656b26aa0f7537c Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 14:36:57 -0400 Subject: [PATCH 16/27] Update change log --- HISTORY.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 22c58ca..0dd5630 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -75,7 +75,7 @@ - Added repository link and CC0 waiver notice - **Rev 4.9.2** - 2024-08-18 *(DevEd)* - Corrected `CART_ROM_MBC5_BAT` to `CART_ROM_MBC5_RAM` -- **Rev 4.10.0** - 2025-05-13 *(Rangi42)* - - Added more constants - - Changed formatting +- **Rev 4.10.0** - 2025-05-16 *(Rangi42)* + - Added many more constants + - Changed formatting and reorganized sections - Moved revision history to separate HISTORY.md file From 1f750f1f0b4308790e4e1a403e3a49cd3cbc2829 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 15:24:01 -0400 Subject: [PATCH 17/27] Add `BGP_SGB_TRANSFER` --- hardware.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hardware.inc b/hardware.inc index e668bc4..8abcc7e 100644 --- a/hardware.inc +++ b/hardware.inc @@ -492,6 +492,8 @@ def rDMA equ $FF46 ; (DMG only) Background color mapping [r/w] def rBGP equ $FF47 +def BGP_SGB_TRANSFER equ %11_10_01_00 ; set BGP to this value before SGB VRAM transfer + ; -- OBP0 ($FF48) ------------------------------------------------------------- ; (DMG only) OBJ color mapping #0 [r/w] def rOBP0 equ $FF48 From 8751947156b881c732088f7ca0e285d3bf20b320 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 15 May 2025 16:00:23 -0400 Subject: [PATCH 18/27] Consistently use `[r/w]` not `[rw]` --- hardware.inc | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/hardware.inc b/hardware.inc index 8abcc7e..af3d626 100644 --- a/hardware.inc +++ b/hardware.inc @@ -221,7 +221,7 @@ def AUDENVF_PACE equ %00000_111 ; how long between envelope iterations ; (in 64 Hz ticks, ~15.6 ms apart) [r/w] ; -- AUD1LOW / NR13 ($FF13) --------------------------------------------------- -; Audio channel 1 period (low 8 bits) [rw] +; Audio channel 1 period (low 8 bits) [r/w] def rAUD1LOW equ $FF13 ; -- AUD1HIGH / NR14 ($FF14) -------------------------------------------------- @@ -231,12 +231,12 @@ def rAUD1HIGH equ $FF14 ; Values are also applicable to AUD2HIGH and AUD3HIGH def AUDHIGHB_RESTART equ 7 ; 1 = restart the channel [wo] -def AUDHIGHB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [rw] +def AUDHIGHB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w] def AUDHIGH_RESTART equ 1 << AUDHIGHB_RESTART def AUDHIGH_LENGTH_OFF equ 0 << AUDHIGHB_LEN_ENABLE def AUDHIGH_LENGTH_ON equ 1 << AUDHIGHB_LEN_ENABLE -def AUDHIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [rw] +def AUDHIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [r/w] ; -- $FF15 is unused ---------------------------------------------------------- @@ -253,7 +253,7 @@ def rAUD2ENV equ $FF17 ; Values are reused from AUD1ENV ; -- AUD2LOW / NR23 ($FF18) --------------------------------------------------- -; Audio channel 2 period (low 8 bits) [rw] +; Audio channel 2 period (low 8 bits) [r/w] def rAUD2LOW equ $FF18 ; -- AUD2HIGH / NR24 ($FF19) -------------------------------------------------- @@ -266,7 +266,7 @@ def rAUD2HIGH equ $FF19 ; Audio channel 3 enable def rAUD3ENA equ $FF1A -def AUD3ENAB_ENABLE equ 7 ; 1 = channel is active [rw] +def AUD3ENAB_ENABLE equ 7 ; 1 = channel is active [r/w] def AUD3ENA_OFF equ 0 << AUD3ENAB_ENABLE def AUD3ENA_ON equ 1 << AUD3ENAB_ENABLE @@ -278,14 +278,14 @@ def rAUD3LEN equ $FF1B ; Audio channel 3 volume def rAUD3LEVEL equ $FF1C -def AUD3LEVELF_VOLUME equ %0_11_00000 ; volume level [rw] +def AUD3LEVELF_VOLUME equ %0_11_00000 ; volume level [r/w] def AUD3LEVEL_MUTE equ %0_00_00000 ; 0% (muted) def AUD3LEVEL_100 equ %0_01_00000 ; 100% def AUD3LEVEL_50 equ %0_10_00000 ; 50% def AUD3LEVEL_25 equ %0_11_00000 ; 25% ; -- AUD3LOW / NR33 ($FF1D) --------------------------------------------------- -; Audio channel 3 period (low 8 bits) [rw] +; Audio channel 3 period (low 8 bits) [r/w] def rAUD3LOW equ $FF1D ; -- AUD3HIGH / NR34 ($FF1E) -------------------------------------------------- @@ -312,20 +312,20 @@ def rAUD4ENV equ $FF21 ; Audio channel 4 period and randomness def rAUD4POLY equ $FF22 -def AUD4POLYF_SHIFT equ %1111_0000 ; coarse control of the channel's period [rw] +def AUD4POLYF_SHIFT equ %1111_0000 ; coarse control of the channel's period [r/w] -def AUD4POLYB_WIDTH equ 3 ; controls the noise generator (LFSR)'s step width [rw] +def AUD4POLYB_WIDTH equ 3 ; controls the noise generator (LFSR)'s step width [r/w] def AUD4POLY_15STEP equ 0 << AUD4POLYB_WIDTH def AUD4POLY_7STEP equ 1 << AUD4POLYB_WIDTH -def AUD4POLYF_DIV equ %00000_111 ; fine control of the channel's period [rw] +def AUD4POLYF_DIV equ %00000_111 ; fine control of the channel's period [r/w] ; -- AUD4GO / NR44 ($FF23) ---------------------------------------------------- ; Audio channel 4 control def rAUD4GO equ $FF23 def AUD4GOB_RESTART equ 7 ; 1 = restart the channel [wo] -def AUD4GOB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [rw] +def AUD4GOB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w] def AUD4GO_RESTART equ 1 << AUD4GOB_RESTART def AUD4GO_LENGTH_OFF equ 0 << AUD4GOB_LEN_ENABLE def AUD4GO_LENGTH_ON equ 1 << AUD4GOB_LEN_ENABLE @@ -334,28 +334,28 @@ def AUD4GOB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expi ; Audio master volume and VIN mixer def rAUDVOL equ $FF24 -def AUDVOLB_VIN_LEFT equ 7 ; 1 = output VIN to left ear (SO2, speaker 2) [rw] +def AUDVOLB_VIN_LEFT equ 7 ; 1 = output VIN to left ear (SO2, speaker 2) [r/w] def AUDVOL_VIN_LEFT equ 1 << AUDVOLB_VIN_LEFT -def AUDVOLF_LEFT equ %0_111_0000 ; 0 = barely audible, 7 = full volume [rw] +def AUDVOLF_LEFT equ %0_111_0000 ; 0 = barely audible, 7 = full volume [r/w] -def AUDVOLB_VIN_RIGHT equ 3 ; 1 = output VIN to right ear (SO1, speaker 1) [rw] +def AUDVOLB_VIN_RIGHT equ 3 ; 1 = output VIN to right ear (SO1, speaker 1) [r/w] def AUDVOL_VIN_RIGHT equ 1 << AUDVOLB_VIN_RIGHT -def AUDVOLF_RIGHT equ %00000_111 ; 0 = barely audible, 7 = full volume [rw] +def AUDVOLF_RIGHT equ %00000_111 ; 0 = barely audible, 7 = full volume [r/w] ; -- AUDTERM / NR51 ($FF25) --------------------------------------------------- ; Audio channel mixer def rAUDTERM equ $FF25 -def AUDTERMB_4_LEFT equ 7 ; 1 = output channel 4 to left ear [rw] -def AUDTERMB_3_LEFT equ 6 ; 1 = output channel 3 to left ear [rw] -def AUDTERMB_2_LEFT equ 5 ; 1 = output channel 2 to left ear [rw] -def AUDTERMB_1_LEFT equ 4 ; 1 = output channel 1 to left ear [rw] -def AUDTERMB_4_RIGHT equ 3 ; 1 = output channel 4 to right ear [rw] -def AUDTERMB_3_RIGHT equ 2 ; 1 = output channel 3 to right ear [rw] -def AUDTERMB_2_RIGHT equ 1 ; 1 = output channel 2 to right ear [rw] -def AUDTERMB_1_RIGHT equ 0 ; 1 = output channel 1 to right ear [rw] +def AUDTERMB_4_LEFT equ 7 ; 1 = output channel 4 to left ear [r/w] +def AUDTERMB_3_LEFT equ 6 ; 1 = output channel 3 to left ear [r/w] +def AUDTERMB_2_LEFT equ 5 ; 1 = output channel 2 to left ear [r/w] +def AUDTERMB_1_LEFT equ 4 ; 1 = output channel 1 to left ear [r/w] +def AUDTERMB_4_RIGHT equ 3 ; 1 = output channel 4 to right ear [r/w] +def AUDTERMB_3_RIGHT equ 2 ; 1 = output channel 3 to right ear [r/w] +def AUDTERMB_2_RIGHT equ 1 ; 1 = output channel 2 to right ear [r/w] +def AUDTERMB_1_RIGHT equ 0 ; 1 = output channel 1 to right ear [r/w] def AUDTERM_4_LEFT equ 1 << AUDTERMB_4_LEFT def AUDTERM_3_LEFT equ 1 << AUDTERMB_3_LEFT def AUDTERM_2_LEFT equ 1 << AUDTERMB_2_LEFT From f424cadb3d3df245c59c7295557f69620e954d41 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Fri, 16 May 2025 11:29:56 -0400 Subject: [PATCH 19/27] Comment on how to fill header with zeros --- hardware.inc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hardware.inc b/hardware.inc index af3d626..f6aa05b 100644 --- a/hardware.inc +++ b/hardware.inc @@ -917,6 +917,11 @@ def _VRAM9000 equ _VRAM + $1000 ;****************************************************************************** ; These values are deprecated; please use RGBFIX instead. +; Zero-filled space can be reserved for fixable header values like this: +; +; SECTION "Cartridge header", ROM0[$0100] +; nop :: jp $0150 ; Entry point ($0100-$0104) +; ds $150 - @, $00 ; Header ($0104-$014FF) filled with $00s for RGBFIX to populate ; -- Nintendo logo ($0104-$0133) ---------------------------------------------- ; Prefer `rgbfix -f/--fix-spec l` for the official logo, or `rgbfix -L ` for a custom one From 849fe1722b37e1349013d22b1d90760168a70bbe Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Fri, 16 May 2025 11:32:03 -0400 Subject: [PATCH 20/27] Note which values RGBFIX "sets" by not overwriting zeros --- hardware.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hardware.inc b/hardware.inc index f6aa05b..a55cb59 100644 --- a/hardware.inc +++ b/hardware.inc @@ -932,12 +932,12 @@ MACRO NINTENDO_LOGO ENDM ; -- CGB compatibility code ($0143) ------------------------------------------- -def CART_COMPATIBLE_DMG equ $00 +def CART_COMPATIBLE_DMG equ $00 ; default value if header is zero-filled def CART_COMPATIBLE_DMG_GBC equ $80 ; prefer `rgbfix -c/--color-compatible` def CART_COMPATIBLE_GBC equ $C0 ; prefer `rgbfix -C/--color-only` ; -- SGB flag ($0146) --------------------------------------------------------- -def CART_INDICATOR_GB equ $00 +def CART_INDICATOR_GB equ $00 ; default value if header is zero-filled def CART_INDICATOR_SGB equ $03 ; prefer `rgblink -s/--sgb-compatible` ; -- Cartridge type ($0147) --------------------------------------------------- @@ -994,7 +994,7 @@ def CART_SRAM_32KB equ 3 ; 4 banks def CART_SRAM_128KB equ 4 ; 16 banks ; -- Destination code ($014A) ------------------------------------------------- -def CART_DEST_JAPANESE equ $00 +def CART_DEST_JAPANESE equ $00 ; default value if header is zero-filled def CART_DEST_NON_JAPANESE equ $01 ; prefer `rgbfix -j/--non-japanese` From 6c6ed14969209b9f34460c7fdc0f135be900a10d Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Fri, 16 May 2025 11:52:21 -0400 Subject: [PATCH 21/27] Remove extra space --- hardware.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware.inc b/hardware.inc index a55cb59..acfcaa7 100644 --- a/hardware.inc +++ b/hardware.inc @@ -184,7 +184,7 @@ def AUD1SWEEPF_TIME equ %0_111_0000 ; how long between sweep iterations ; (in 128 Hz ticks, ~7.8 ms apart) [r/w] def AUD1SWEEPB_DIR equ 3 ; sweep direction [r/w] - def AUD1SWEEPF_DIR equ 1 << AUD1SWEEPB_DIR + def AUD1SWEEPF_DIR equ 1 << AUD1SWEEPB_DIR def AUD1SWEEP_UP equ 0 << AUD1SWEEPB_DIR def AUD1SWEEP_DOWN equ 1 << AUD1SWEEPB_DIR From e29541b0a92300d8b6a08aa8728fbd6038d26c15 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Fri, 16 May 2025 12:13:18 -0400 Subject: [PATCH 22/27] Define `rRTCREG` --- hardware.inc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hardware.inc b/hardware.inc index acfcaa7..5f632ae 100644 --- a/hardware.inc +++ b/hardware.inc @@ -706,7 +706,7 @@ def rROMB1 equ $3000 ; SRAM bank number [wo] def rRAMB equ $4000 -; (MBC3-only) Special RAM bank numbers that actually map the RTC registers +; (MBC3-only) Special RAM bank numbers that actually map values into RTCREG def RTC_S equ $08 ; seconds counter (0-59) def RTC_M equ $09 ; minutes counter (0-59) def RTC_H equ $0A ; hours counter (0-23) @@ -728,10 +728,14 @@ def CARTB_RUMBLE_ON equ 3 ; (MBC5 and MBC7 only) enable the rumble motor (if any ; (MBC3 only) RTC latch clock data [wo] def rRTCLATCH equ $6000 -; Write $00 then $01 to latch the current time into the RTC registers +; Write $00 then $01 to latch the current time into RTCREG def RTCLATCH_START equ $00 def RTCLATCH_FINISH equ $01 +; -- RTCREG ($A000-$BFFF) --------------------------------------------------- +; (MBC3 only) RTC register [wo] +def rRTCREG equ $A000 + ;****************************************************************************** ; Screen-related constants From 9a4fcfd8d1a1e5f1da80590660fac310ae633a91 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Fri, 16 May 2025 12:17:56 -0400 Subject: [PATCH 23/27] Fix comment --- hardware.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware.inc b/hardware.inc index 5f632ae..1f246b0 100644 --- a/hardware.inc +++ b/hardware.inc @@ -733,7 +733,7 @@ def RTCLATCH_START equ $00 def RTCLATCH_FINISH equ $01 ; -- RTCREG ($A000-$BFFF) --------------------------------------------------- -; (MBC3 only) RTC register [wo] +; (MBC3 only) RTC register [r/w] def rRTCREG equ $A000 From 0d8f86f70fa17427a331fd618ba3de067d1a13b1 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Fri, 16 May 2025 12:42:27 -0400 Subject: [PATCH 24/27] Updated history change log --- HISTORY.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 0dd5630..75506b2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -76,6 +76,11 @@ - **Rev 4.9.2** - 2024-08-18 *(DevEd)* - Corrected `CART_ROM_MBC5_BAT` to `CART_ROM_MBC5_RAM` - **Rev 4.10.0** - 2025-05-16 *(Rangi42)* - - Added many more constants + - Added `rKEY0`, `rBANK`, and `rRTCREG` registers + - Added `rJOYP`, `rVDMA_*`, and `rWBK` register aliases + - Added `HARDWARE_INC_VERSION` string constant + - Added many more bit number, flag, and value constants + - Deprecate `IEB_HILO` and `IEF_HILO` in favor of `IEB_JOYPAD` and `IEF_JOYPAD` + - Deprecate memory region and cartridge header constants - Changed formatting and reorganized sections - Moved revision history to separate HISTORY.md file From aa8b70d521ebf2f963a7b567ebc78da4bab80c33 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Sun, 18 May 2025 08:43:53 -0400 Subject: [PATCH 25/27] Suggestions from code review --- README.md | 3 ++- hardware.inc | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index cd05fa2..63d44bc 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ `hardware.inc` has been the standard include file containing Game Boy hardware definitions for use in [RGBDS](https://rgbds.gbdev.io) projects for over 20 years. -The file was originally created by Jeff Frohwein in 1997. Although Jeff tried to track version updates with a rudimentary change log at the top of the file, people have made small changes throughout the years, often without bumping the version number. +The file was originally created by Jeff Frohwein in 1997. +Although Jeff tried to track version updates with a rudimentary change log at the top of the file, people have made small changes throughout the years, often without bumping the version number. This repository has become the official reference for `hardware.inc`, using [@AntonioND](https://github.com/AntonioND)'s fork as the baseline. diff --git a/hardware.inc b/hardware.inc index 1f246b0..54d26c8 100644 --- a/hardware.inc +++ b/hardware.inc @@ -756,10 +756,10 @@ def TILE_Y equ 8 ; height of tile in pixels def TILE_B equ 16 ; size of tile in bytes (2 bits/pixel) def COLOR_B equ 2 ; size of color in bytes (little-endian BGR555) - def COLORF_BLUE equ %0_11111_00 - def COLORF_GREEN_HIGH equ %000000_11 - def COLORF_GREEN_LOW equ %111_00000 - def COLORF_RED equ %000_11111 + def COLORF_GREEN_LOW equ %111_00000 ; for the low byte + def COLORF_RED equ %000_11111 ; for the low byte + def COLORF_BLUE equ %0_11111_00 ; for the high byte + def COLORF_GREEN_HIGH equ %000000_11 ; for the high byte def PAL_COLORS equ 4 ; colors per palette def PAL_B equ COLOR_B * PAL_COLORS ; size of palette in bytes @@ -821,9 +821,9 @@ def BOOTUP_A_MGB equ $FF def BOOTUP_A_SGB2 equ BOOTUP_A_MGB ; Register B = CPU qualifier (if A is BOOTUP_A_CGB) -def BOOTUP_B_AGBB equ 0 - def BOOTUP_B_CGB equ 0 << BOOTUP_B_AGBB - def BOOTUP_B_AGB equ 1 << BOOTUP_B_AGBB +def BOOTUPB_B_AGB equ 0 + def BOOTUP_B_CGB equ 0 << BOOTUPB_B_AGB + def BOOTUP_B_AGB equ 1 << BOOTUPB_B_AGB ;****************************************************************************** From 076e28735526da658a1d5cec08f0ecaf6986b531 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Sun, 18 May 2025 11:12:43 -0400 Subject: [PATCH 26/27] Use `rb` for OAM field offsets --- hardware.inc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hardware.inc b/hardware.inc index 54d26c8..1ba2c22 100644 --- a/hardware.inc +++ b/hardware.inc @@ -773,12 +773,13 @@ def _SCRN1 equ $9C00 ; $9C00-$9FFF ;****************************************************************************** ; OAM attribute field offsets -def OAMA_Y equ 0 +rsreset +def OAMA_Y rb ; 0 def OAM_Y_OFS equ 16 ; subtract 16 from what's written to OAM to get the real Y position -def OAMA_X equ 1 +def OAMA_X rb ; 1 def OAM_X_OFS equ 8 ; subtract 8 from what's written to OAM to get the real X position -def OAMA_TILEID equ 2 -def OAMA_FLAGS equ 3 +def OAMA_TILEID rb ; 2 +def OAMA_FLAGS rb ; 3 def OAMB_PRI equ 7 ; whether the OBJ is drawn above BG colors 1-3 def OAMB_YFLIP equ 6 ; whether the whole OBJ is flipped vertically def OAMB_XFLIP equ 5 ; whether the whole OBJ is flipped horizontally @@ -792,8 +793,8 @@ def OAMA_FLAGS equ 3 def OAMF_PAL1 equ 1 << OAMB_PAL1 def OAMF_BANK0 equ 0 << OAMB_BANK1 def OAMF_BANK1 equ 1 << OAMB_BANK1 +def OBJ_B rb 0 ; size of OBJ in bytes = 4 -def OBJ_B equ 4 ; size of OBJ in bytes def OAM_COUNT equ 40 ; how many OBJs there are room for in OAM def OAM_B equ OBJ_B * OAM_COUNT From 78635fe6f209d3b2e428a4211753be6782f92d83 Mon Sep 17 00:00:00 2001 From: Antonio Vivace Date: Mon, 19 May 2025 09:27:47 +0200 Subject: [PATCH 27/27] Update date of last revision --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 75506b2..e74d105 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -75,7 +75,7 @@ - Added repository link and CC0 waiver notice - **Rev 4.9.2** - 2024-08-18 *(DevEd)* - Corrected `CART_ROM_MBC5_BAT` to `CART_ROM_MBC5_RAM` -- **Rev 4.10.0** - 2025-05-16 *(Rangi42)* +- **Rev 4.10.0** - 2025-05-19 *(Rangi42)* - Added `rKEY0`, `rBANK`, and `rRTCREG` registers - Added `rJOYP`, `rVDMA_*`, and `rWBK` register aliases - Added `HARDWARE_INC_VERSION` string constant