diff --git a/HISTORY.md b/HISTORY.md index 48c6c77..16a7632 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -90,3 +90,12 @@ - Refactored the `rev_Check_hardware_inc` macro - **Rev 4.12.0** - 2025-06-06 *(Rangi42)* - Added `SCRN_B` and `SCRN_V_B` constants +- **Rev 5.0.0** - 2025-06-22 *(Rangi42)* + - Changed bit number naming convention `B_` to `B__` + - Changed bit flag naming convention `F_` to `_` + - Unabbreviated some names, e.g. `SCRN` to `SCREEN` and `HBL` to `HBLANK` + - Added `LCDC_*` flag constants separate from flag values + - Added `SPD_SINGLE` flag constant + - Added `BG_*` constants for CGB-only BG tile attributes + - Added hardware_compat.inc for backwards-compatibility aliases + - Deprecated `rSMBK` alias for `rWBK`/`rSVBK` diff --git a/hardware.inc b/hardware.inc index e0ed42c..6012326 100644 --- a/hardware.inc +++ b/hardware.inc @@ -22,7 +22,7 @@ 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.12.0" +def HARDWARE_INC_VERSION equs "5.0.0" ; Usage: rev_Check_hardware_inc ; Examples: @@ -51,66 +51,66 @@ ENDM ; 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 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 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 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 - 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 +def B_JOYP_GET_BUTTONS equ 5 ; 0 = reading buttons [r/w] +def B_JOYP_GET_CTRL_PAD equ 4 ; 0 = reading Control Pad [r/w] + def JOYP_GET equ %00_11_0000 ; select which inputs to read from the lower nybble + def JOYP_GET_BUTTONS equ %00_01_0000 ; reading A/B/Select/Start buttons + def JOYP_GET_CTRL_PAD equ %00_10_0000 ; reading Control Pad directions + def JOYP_GET_NONE equ %00_11_0000 ; reading nothing + +def B_JOYP_START equ 3 ; 0 = Start is pressed (if reading buttons) [ro] +def B_JOYP_SELECT equ 2 ; 0 = Select is pressed (if reading buttons) [ro] +def B_JOYP_B equ 1 ; 0 = B is pressed (if reading buttons) [ro] +def B_JOYP_A equ 0 ; 0 = A is pressed (if reading buttons) [ro] +def B_JOYP_DOWN equ 3 ; 0 = Down is pressed (if reading Control Pad) [ro] +def B_JOYP_UP equ 2 ; 0 = Up is pressed (if reading Control Pad) [ro] +def B_JOYP_LEFT equ 1 ; 0 = Left is pressed (if reading Control Pad) [ro] +def B_JOYP_RIGHT equ 0 ; 0 = Right is pressed (if reading Control Pad) [ro] + def JOYP_INPUTS equ %0000_1111 + def JOYP_START equ 1 << B_JOYP_START + def JOYP_SELECT equ 1 << B_JOYP_SELECT + def JOYP_B equ 1 << B_JOYP_B + def JOYP_A equ 1 << B_JOYP_A + def JOYP_DOWN equ 1 << B_JOYP_DOWN + def JOYP_UP equ 1 << B_JOYP_UP + def JOYP_LEFT equ 1 << B_JOYP_LEFT + def JOYP_RIGHT equ 1 << B_JOYP_RIGHT ; 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 -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 +def B_PAD_DOWN equ 7 +def B_PAD_UP equ 6 +def B_PAD_LEFT equ 5 +def B_PAD_RIGHT equ 4 +def B_PAD_START equ 3 +def B_PAD_SELECT equ 2 +def B_PAD_B equ 1 +def B_PAD_A equ 0 + def PAD_DOWN equ 1 << B_PAD_DOWN + def PAD_UP equ 1 << B_PAD_UP + def PAD_LEFT equ 1 << B_PAD_LEFT + def PAD_RIGHT equ 1 << B_PAD_RIGHT + def PAD_START equ 1 << B_PAD_START + def PAD_SELECT equ 1 << B_PAD_SELECT + def PAD_B equ 1 << B_PAD_B + def PAD_A equ 1 << B_PAD_A ; 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 -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 +def B_PAD_SWAP_START equ 7 +def B_PAD_SWAP_SELECT equ 6 +def B_PAD_SWAP_B equ 5 +def B_PAD_SWAP_A equ 4 +def B_PAD_SWAP_DOWN equ 3 +def B_PAD_SWAP_UP equ 2 +def B_PAD_SWAP_LEFT equ 1 +def B_PAD_SWAP_RIGHT equ 0 + def PAD_SWAP_START equ 1 << B_PAD_SWAP_START + def PAD_SWAP_SELECT equ 1 << B_PAD_SWAP_SELECT + def PAD_SWAP_B equ 1 << B_PAD_SWAP_B + def PAD_SWAP_A equ 1 << B_PAD_SWAP_A + def PAD_SWAP_DOWN equ 1 << B_PAD_SWAP_DOWN + def PAD_SWAP_UP equ 1 << B_PAD_SWAP_UP + def PAD_SWAP_LEFT equ 1 << B_PAD_SWAP_LEFT + def PAD_SWAP_RIGHT equ 1 << B_PAD_SWAP_RIGHT ; -- SB ($FF01) --------------------------------------------------------------- ; Serial transfer data [r/w] @@ -120,16 +120,16 @@ def rSB equ $FF01 ; 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 +def B_SC_START equ 7 ; reading 1 = transfer in progress, writing 1 = start transfer [r/w] +def B_SC_SPEED equ 1 ; (CGB only) 1 = use faster internal clock [r/w] +def B_SC_SOURCE equ 0 ; 0 = use external clock ("slave"), 1 = use internal clock ("master") [r/w] + def SC_START equ 1 << B_SC_START + def SC_SPEED equ 1 << B_SC_SPEED + def SC_SLOW equ 0 << B_SC_SPEED + def SC_FAST equ 1 << B_SC_SPEED + def SC_SOURCE equ 1 << B_SC_SOURCE + def SC_EXTERNAL equ 0 << B_SC_SOURCE + def SC_INTERNAL equ 1 << B_SC_SOURCE ; -- $FF03 is unused ---------------------------------------------------------- @@ -149,15 +149,15 @@ def rTMA equ $FF06 ; 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 B_TAC_START equ 2 ; enable incrementing TIMA [r/w] + def TAC_STOP equ 0 << B_TAC_START + def TAC_START equ 1 << B_TAC_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 +def TAC_CLOCK equ %000000_11 ; the frequency at which TIMA increments [r/w] + def TAC_4KHZ equ %000000_00 ; every 256 M-cycles = ~4 KHz on DMG + def TAC_262KHZ equ %000000_01 ; every 4 M-cycles = ~262 KHz on DMG + def TAC_65KHZ equ %000000_10 ; every 16 M-cycles = ~65 KHz on DMG + def TAC_16KHZ equ %000000_11 ; every 64 M-cycles = ~16 KHz on DMG ; -- $FF08-$FF0E are unused --------------------------------------------------- @@ -165,28 +165,28 @@ def TACF_CLOCK equ %000000_11 ; the frequency at which TIMER_CNT increments [r/w ; 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 +def B_IF_JOYPAD equ 4 ; 1 = joypad interrupt is pending [r/w] +def B_IF_SERIAL equ 3 ; 1 = serial interrupt is pending [r/w] +def B_IF_TIMER equ 2 ; 1 = timer interrupt is pending [r/w] +def B_IF_STAT equ 1 ; 1 = STAT interrupt is pending [r/w] +def B_IF_VBLANK equ 0 ; 1 = VBlank interrupt is pending [r/w] + def IF_JOYPAD equ 1 << B_IF_JOYPAD + def IF_SERIAL equ 1 << B_IF_SERIAL + def IF_TIMER equ 1 << B_IF_TIMER + def IF_STAT equ 1 << B_IF_STAT + def IF_VBLANK equ 1 << B_IF_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 AUD1SWEEP_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 B_AUD1SWEEP_DIR equ 3 ; sweep direction [r/w] + def AUD1SWEEP_DIR equ 1 << B_AUD1SWEEP_DIR + def AUD1SWEEP_UP equ 0 << B_AUD1SWEEP_DIR + def AUD1SWEEP_DOWN equ 1 << B_AUD1SWEEP_DIR def AUD1SWEEP_SHIFT equ %00000_111 ; how much the period increases/decreases per iteration [r/w] @@ -194,27 +194,27 @@ def AUD1SWEEP_SHIFT equ %00000_111 ; how much the period increases/decreases per ; Audio channel 1 length timer and duty cycle def rAUD1LEN equ $FF11 -def AUD1LENF_DUTY equ %11_000000 ; ratio of time spent high vs. time spent low [r/w] +def AUD1LEN_DUTY equ %11_000000 ; ratio of time spent high vs. time spent low [r/w] def AUD1LEN_DUTY_12_5 equ %00_000000 ; 12.5% def AUD1LEN_DUTY_25 equ %01_000000 ; 25% def AUD1LEN_DUTY_50 equ %10_000000 ; 50% def AUD1LEN_DUTY_75 equ %11_000000 ; 75% -def AUD1LENF_TIMER equ %00_111111 ; initial length timer (0-63) [wo] +def AUD1LEN_TIMER equ %00_111111 ; initial length timer (0-63) [wo] ; -- AUD1ENV / NR12 ($FF12) --------------------------------------------------- ; Audio channel 1 volume and envelope def rAUD1ENV equ $FF12 -def AUD1ENVF_INIT_VOL equ %1111_0000 ; initial volume [r/w] +def AUD1ENV_INIT_VOLUME equ %1111_0000 ; initial volume [r/w] -def AUD1ENVB_DIR equ 3 ; direction of volume envelope [r/w] - def AUD1ENVF_DIR equ 1 << AUD1ENVB_DIR - def AUD1ENV_DOWN equ 0 << AUD1ENVB_DIR - def AUD1ENV_UP equ 1 << AUD1ENVB_DIR +def B_AUD1ENV_DIR equ 3 ; direction of volume envelope [r/w] + def AUD1ENV_DIR equ 1 << B_AUD1ENV_DIR + def AUD1ENV_DOWN equ 0 << B_AUD1ENV_DIR + def AUD1ENV_UP equ 1 << B_AUD1ENV_DIR -def AUD1ENVF_PACE equ %00000_111 ; how long between envelope iterations - ; (in 64 Hz ticks, ~15.6 ms apart) [r/w] +def AUD1ENV_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) [r/w] @@ -224,13 +224,13 @@ def rAUD1LOW equ $FF13 ; Audio channel 1 period (high 3 bits) and control def rAUD1HIGH equ $FF14 -def AUD1HIGHB_RESTART equ 7 ; 1 = restart the channel [wo] -def AUD1HIGHB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w] - def AUD1HIGH_RESTART equ 1 << AUD1HIGHB_RESTART - def AUD1HIGH_LENGTH_OFF equ 0 << AUD1HIGHB_LEN_ENABLE - def AUD1HIGH_LENGTH_ON equ 1 << AUD1HIGHB_LEN_ENABLE +def B_AUD1HIGH_RESTART equ 7 ; 1 = restart the channel [wo] +def B_AUD1HIGH_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w] + def AUD1HIGH_RESTART equ 1 << B_AUD1HIGH_RESTART + def AUD1HIGH_LENGTH_OFF equ 0 << B_AUD1HIGH_LEN_ENABLE + def AUD1HIGH_LENGTH_ON equ 1 << B_AUD1HIGH_LEN_ENABLE -def AUD1HIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [r/w] +def AUD1HIGH_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [r/w] ; -- $FF15 is unused ---------------------------------------------------------- @@ -238,27 +238,27 @@ def AUD1HIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period ; Audio channel 2 length timer and duty cycle def rAUD2LEN equ $FF16 -def AUD2LENF_DUTY equ %11_000000 ; ratio of time spent high vs. time spent low [r/w] +def AUD2LEN_DUTY equ %11_000000 ; ratio of time spent high vs. time spent low [r/w] def AUD2LEN_DUTY_12_5 equ %00_000000 ; 12.5% def AUD2LEN_DUTY_25 equ %01_000000 ; 25% def AUD2LEN_DUTY_50 equ %10_000000 ; 50% def AUD2LEN_DUTY_75 equ %11_000000 ; 75% -def AUD2LENF_TIMER equ %00_111111 ; initial length timer (0-63) [wo] +def AUD2LEN_TIMER equ %00_111111 ; initial length timer (0-63) [wo] ; -- AUD2ENV / NR22 ($FF17) --------------------------------------------------- ; Audio channel 2 volume and envelope def rAUD2ENV equ $FF17 -def AUD2ENVF_INIT_VOL equ %1111_0000 ; initial volume [r/w] +def AUD2ENV_INIT_VOLUME equ %1111_0000 ; initial volume [r/w] -def AUD2ENVB_DIR equ 3 ; direction of volume envelope [r/w] - def AUD2ENVF_DIR equ 1 << AUD2ENVB_DIR - def AUD2ENV_DOWN equ 0 << AUD2ENVB_DIR - def AUD2ENV_UP equ 1 << AUD2ENVB_DIR +def B_AUD2ENV_DIR equ 3 ; direction of volume envelope [r/w] + def AUD2ENV_DIR equ 1 << B_AUD2ENV_DIR + def AUD2ENV_DOWN equ 0 << B_AUD2ENV_DIR + def AUD2ENV_UP equ 1 << B_AUD2ENV_DIR -def AUD2ENVF_PACE equ %00000_111 ; how long between envelope iterations - ; (in 64 Hz ticks, ~15.6 ms apart) [r/w] +def AUD2ENV_PACE equ %00000_111 ; how long between envelope iterations + ; (in 64 Hz ticks, ~15.6 ms apart) [r/w] ; -- AUD2LOW / NR23 ($FF18) --------------------------------------------------- ; Audio channel 2 period (low 8 bits) [r/w] @@ -268,21 +268,21 @@ def rAUD2LOW equ $FF18 ; Audio channel 2 period (high 3 bits) and control def rAUD2HIGH equ $FF19 -def AUD2HIGHB_RESTART equ 7 ; 1 = restart the channel [wo] -def AUD2HIGHB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w] - def AUD2HIGH_RESTART equ 1 << AUD2HIGHB_RESTART - def AUD2HIGH_LENGTH_OFF equ 0 << AUD2HIGHB_LEN_ENABLE - def AUD2HIGH_LENGTH_ON equ 1 << AUD2HIGHB_LEN_ENABLE +def B_AUD2HIGH_RESTART equ 7 ; 1 = restart the channel [wo] +def B_AUD2HIGH_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w] + def AUD2HIGH_RESTART equ 1 << B_AUD2HIGH_RESTART + def AUD2HIGH_LENGTH_OFF equ 0 << B_AUD2HIGH_LEN_ENABLE + def AUD2HIGH_LENGTH_ON equ 1 << B_AUD2HIGH_LEN_ENABLE -def AUD2HIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [r/w] +def AUD2HIGH_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [r/w] ; -- AUD3ENA / NR30 ($FF1A) --------------------------------------------------- ; Audio channel 3 enable def rAUD3ENA equ $FF1A -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 +def B_AUD3ENA_ENABLE equ 7 ; 1 = channel is active [r/w] + def AUD3ENA_OFF equ 0 << B_AUD3ENA_ENABLE + def AUD3ENA_ON equ 1 << B_AUD3ENA_ENABLE ; -- AUD3LEN / NR31 ($FF1B) --------------------------------------------------- ; Audio channel 3 length timer [wo] @@ -292,7 +292,7 @@ def rAUD3LEN equ $FF1B ; Audio channel 3 volume def rAUD3LEVEL equ $FF1C -def AUD3LEVELF_VOLUME equ %0_11_00000 ; volume level [r/w] +def AUD3LEVEL_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% @@ -306,13 +306,13 @@ def rAUD3LOW equ $FF1D ; Audio channel 3 period (high 3 bits) and control def rAUD3HIGH equ $FF1E -def AUD3HIGHB_RESTART equ 7 ; 1 = restart the channel [wo] -def AUD3HIGHB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w] - def AUD3HIGH_RESTART equ 1 << AUD3HIGHB_RESTART - def AUD3HIGH_LENGTH_OFF equ 0 << AUD3HIGHB_LEN_ENABLE - def AUD3HIGH_LENGTH_ON equ 1 << AUD3HIGHB_LEN_ENABLE +def B_AUD3HIGH_RESTART equ 7 ; 1 = restart the channel [wo] +def B_AUD3HIGH_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w] + def AUD3HIGH_RESTART equ 1 << B_AUD3HIGH_RESTART + def AUD3HIGH_LENGTH_OFF equ 0 << B_AUD3HIGH_LEN_ENABLE + def AUD3HIGH_LENGTH_ON equ 1 << B_AUD3HIGH_LEN_ENABLE -def AUD3HIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [r/w] +def AUD3HIGH_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [r/w] ; -- $FF1F is unused ---------------------------------------------------------- @@ -320,98 +320,98 @@ def AUD3HIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period ; Audio channel 4 length timer def rAUD4LEN equ $FF20 -def AUD4LENF_TIMER equ %00_111111 ; initial length timer (0-63) [wo] +def AUD4LEN_TIMER equ %00_111111 ; initial length timer (0-63) [wo] ; -- AUD4ENV / NR42 ($FF21) --------------------------------------------------- ; Audio channel 4 volume and envelope def rAUD4ENV equ $FF21 -def AUD4ENVF_INIT_VOL equ %1111_0000 ; initial volume [r/w] +def AUD4ENV_INIT_VOLUME equ %1111_0000 ; initial volume [r/w] -def AUD4ENVB_DIR equ 3 ; direction of volume envelope [r/w] - def AUD4ENVF_DIR equ 1 << AUD4ENVB_DIR - def AUD4ENV_DOWN equ 0 << AUD4ENVB_DIR - def AUD4ENV_UP equ 1 << AUD4ENVB_DIR +def B_AUD4ENV_DIR equ 3 ; direction of volume envelope [r/w] + def AUD4ENV_DIR equ 1 << B_AUD4ENV_DIR + def AUD4ENV_DOWN equ 0 << B_AUD4ENV_DIR + def AUD4ENV_UP equ 1 << B_AUD4ENV_DIR -def AUD4ENVF_PACE equ %00000_111 ; how long between envelope iterations - ; (in 64 Hz ticks, ~15.6 ms apart) [r/w] +def AUD4ENV_PACE equ %00000_111 ; how long between envelope iterations + ; (in 64 Hz ticks, ~15.6 ms apart) [r/w] ; -- 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 [r/w] +def AUD4POLY_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 [r/w] - def AUD4POLY_15STEP equ 0 << AUD4POLYB_WIDTH - def AUD4POLY_7STEP equ 1 << AUD4POLYB_WIDTH +def B_AUD4POLY_WIDTH equ 3 ; controls the noise generator (LFSR)'s step width [r/w] + def AUD4POLY_15STEP equ 0 << B_AUD4POLY_WIDTH + def AUD4POLY_7STEP equ 1 << B_AUD4POLY_WIDTH -def AUD4POLYF_DIV equ %00000_111 ; fine control of the channel's period [r/w] +def AUD4POLY_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 [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 +def B_AUD4GO_RESTART equ 7 ; 1 = restart the channel [wo] +def B_AUD4GO_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w] + def AUD4GO_RESTART equ 1 << B_AUD4GO_RESTART + def AUD4GO_LENGTH_OFF equ 0 << B_AUD4GO_LEN_ENABLE + def AUD4GO_LENGTH_ON equ 1 << B_AUD4GO_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) [r/w] - def AUDVOL_VIN_LEFT equ 1 << AUDVOLB_VIN_LEFT +def B_AUDVOL_VIN_LEFT equ 7 ; 1 = output VIN to left ear (SO2, speaker 2) [r/w] + def AUDVOL_VIN_LEFT equ 1 << B_AUDVOL_VIN_LEFT -def AUDVOLF_LEFT equ %0_111_0000 ; 0 = barely audible, 7 = full volume [r/w] +def AUDVOL_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) [r/w] - def AUDVOL_VIN_RIGHT equ 1 << AUDVOLB_VIN_RIGHT +def B_AUDVOL_VIN_RIGHT equ 3 ; 1 = output VIN to right ear (SO1, speaker 1) [r/w] + def AUDVOL_VIN_RIGHT equ 1 << B_AUDVOL_VIN_RIGHT -def AUDVOLF_RIGHT equ %00000_111 ; 0 = barely audible, 7 = full volume [r/w] +def AUDVOL_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 [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 - 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 +def B_AUDTERM_4_LEFT equ 7 ; 1 = output channel 4 to left ear [r/w] +def B_AUDTERM_3_LEFT equ 6 ; 1 = output channel 3 to left ear [r/w] +def B_AUDTERM_2_LEFT equ 5 ; 1 = output channel 2 to left ear [r/w] +def B_AUDTERM_1_LEFT equ 4 ; 1 = output channel 1 to left ear [r/w] +def B_AUDTERM_4_RIGHT equ 3 ; 1 = output channel 4 to right ear [r/w] +def B_AUDTERM_3_RIGHT equ 2 ; 1 = output channel 3 to right ear [r/w] +def B_AUDTERM_2_RIGHT equ 1 ; 1 = output channel 2 to right ear [r/w] +def B_AUDTERM_1_RIGHT equ 0 ; 1 = output channel 1 to right ear [r/w] + def AUDTERM_4_LEFT equ 1 << B_AUDTERM_4_LEFT + def AUDTERM_3_LEFT equ 1 << B_AUDTERM_3_LEFT + def AUDTERM_2_LEFT equ 1 << B_AUDTERM_2_LEFT + def AUDTERM_1_LEFT equ 1 << B_AUDTERM_1_LEFT + def AUDTERM_4_RIGHT equ 1 << B_AUDTERM_4_RIGHT + def AUDTERM_3_RIGHT equ 1 << B_AUDTERM_3_RIGHT + def AUDTERM_2_RIGHT equ 1 << B_AUDTERM_2_RIGHT + def AUDTERM_1_RIGHT equ 1 << B_AUDTERM_1_RIGHT ; -- AUDENA / NR52 ($FF26) ---------------------------------------------------- ; Audio master enable def rAUDENA equ $FF26 -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] -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 +def B_AUDENA_ENABLE equ 7 ; 0 = disable the APU (resets all audio registers to 0!) [r/w] +def B_AUDENA_ENABLE_CH4 equ 3 ; 1 = channel 4 is running [ro] +def B_AUDENA_ENABLE_CH3 equ 2 ; 1 = channel 3 is running [ro] +def B_AUDENA_ENABLE_CH2 equ 1 ; 1 = channel 2 is running [ro] +def B_AUDENA_ENABLE_CH1 equ 0 ; 1 = channel 1 is running [ro] + def AUDENA_OFF equ 0 << B_AUDENA_ENABLE + def AUDENA_ON equ 1 << B_AUDENA_ENABLE + def AUDENA_CH4_OFF equ 0 << B_AUDENA_ENABLE_CH4 + def AUDENA_CH4_ON equ 1 << B_AUDENA_ENABLE_CH4 + def AUDENA_CH3_OFF equ 0 << B_AUDENA_ENABLE_CH3 + def AUDENA_CH3_ON equ 1 << B_AUDENA_ENABLE_CH3 + def AUDENA_CH2_OFF equ 0 << B_AUDENA_ENABLE_CH2 + def AUDENA_CH2_ON equ 1 << B_AUDENA_ENABLE_CH2 + def AUDENA_CH1_OFF equ 0 << B_AUDENA_ENABLE_CH1 + def AUDENA_CH1_ON equ 1 << B_AUDENA_ENABLE_CH1 ; -- $FF27-$FF2F are unused --------------------------------------------------- @@ -442,57 +442,65 @@ def AUD3WAVE_SIZE equ 16 ; PPU graphics control def rLCDC equ $FF40 -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 +def B_LCDC_ENABLE equ 7 ; whether the PPU (and LCD) are turned on [r/w] +def B_LCDC_WIN_MAP equ 6 ; which tilemap the Window reads from [r/w] +def B_LCDC_WINDOW equ 5 ; whether the Window is enabled [r/w] +def B_LCDC_BLOCKS equ 4 ; which "tile blocks" the BG and Window use [r/w] +def B_LCDC_BG_MAP equ 3 ; which tilemap the BG reads from [r/w] +def B_LCDC_OBJ_SIZE equ 2 ; how many pixels tall each OBJ is [r/w] +def B_LCDC_OBJS equ 1 ; whether OBJs are enabled [r/w] +def B_LCDC_BG equ 0 ; (DMG only) whether the BG is enabled [r/w] +def B_LCDC_PRIO equ 0 ; (CGB only) whether OBJ priority bits are enabled [r/w] + def LCDC_ENABLE equ 1 << B_LCDC_ENABLE + def LCDC_OFF equ 0 << B_LCDC_ENABLE + def LCDC_ON equ 1 << B_LCDC_ENABLE + def LCDC_WIN_MAP equ 1 << B_LCDC_WIN_MAP + def LCDC_WIN_9800 equ 0 << B_LCDC_WIN_MAP + def LCDC_WIN_9C00 equ 1 << B_LCDC_WIN_MAP + def LCDC_WINDOW equ 1 << B_LCDC_WINDOW + def LCDC_WIN_OFF equ 0 << B_LCDC_WINDOW + def LCDC_WIN_ON equ 1 << B_LCDC_WINDOW + def LCDC_BLOCKS equ 1 << B_LCDC_BLOCKS + def LCDC_BLOCK21 equ 0 << B_LCDC_BLOCKS + def LCDC_BLOCK01 equ 1 << B_LCDC_BLOCKS + def LCDC_BG_MAP equ 1 << B_LCDC_BG_MAP + def LCDC_BG_9800 equ 0 << B_LCDC_BG_MAP + def LCDC_BG_9C00 equ 1 << B_LCDC_BG_MAP + def LCDC_OBJ_SIZE equ 1 << B_LCDC_OBJ_SIZE + def LCDC_OBJ_8 equ 0 << B_LCDC_OBJ_SIZE + def LCDC_OBJ_16 equ 1 << B_LCDC_OBJ_SIZE + def LCDC_OBJS equ 1 << B_LCDC_OBJS + def LCDC_OBJ_OFF equ 0 << B_LCDC_OBJS + def LCDC_OBJ_ON equ 1 << B_LCDC_OBJS + def LCDC_BG equ 1 << B_LCDC_BG + def LCDC_BG_OFF equ 0 << B_LCDC_BG + def LCDC_BG_ON equ 1 << B_LCDC_BG + def LCDC_PRIO equ 1 << B_LCDC_PRIO + def LCDC_PRIO_OFF equ 0 << B_LCDC_PRIO + def LCDC_PRIO_ON equ 1 << B_LCDC_PRIO ; -- STAT ($FF41) ------------------------------------------------------------- ; 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 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 B_STAT_LYC equ 6 ; 1 = LY match triggers the STAT interrupt [r/w] +def B_STAT_MODE_2 equ 5 ; 1 = OAM Scan triggers the PPU interrupt [r/w] +def B_STAT_MODE_1 equ 4 ; 1 = VBlank triggers the PPU interrupt [r/w] +def B_STAT_MODE_0 equ 3 ; 1 = HBlank triggers the PPU interrupt [r/w] +def B_STAT_LYCF equ 2 ; 1 = LY is currently equal to LYC [ro] +def B_STAT_BUSY equ 1 ; 1 = the PPU is currently accessing VRAM [ro] + def STAT_LYC equ 1 << B_STAT_LYC + def STAT_MODE_2 equ 1 << B_STAT_MODE_2 + def STAT_MODE_1 equ 1 << B_STAT_MODE_1 + def STAT_MODE_0 equ 1 << B_STAT_MODE_0 + def STAT_LYCF equ 1 << B_STAT_LYCF + def STAT_BUSY equ 1 << B_STAT_BUSY + +def STAT_MODE equ %000000_11 ; PPU's current status [ro] + def STAT_HBLANK equ %000000_00 ; waiting after a line's rendering (HBlank) + def STAT_VBLANK equ %000000_01 ; waiting between frames (VBlank) + def STAT_OAM equ %000000_10 ; checking which OBJs will be rendered on this line (OAM scan) + def STAT_LCD equ %000000_11 ; pushing pixels to the LCD ; -- SCY ($FF42) -------------------------------------------------------------- ; Background Y scroll offset (in pixels) [r/w] @@ -540,7 +548,7 @@ def rWX equ $FF4B def WX_OFS equ 7 ; subtract this to get the actual Window Y coordinate -; -- SYS / KEY0 ($FF4C) ------------------------------------------------------------- +; -- SYS / KEY0 ($FF4C) ------------------------------------------------------- ; (CGB boot ROM only) CPU mode select def rSYS equ $FF4C @@ -549,20 +557,21 @@ def rSYS equ $FF4C ; "OBJ priority mode designating register" in the same patent ; Credit to @mattcurrie for this finding! -def SYSF_MODE equ %0000_11_00 ; current system mode [r/w] - def SYSF_CGB equ %0000_00_00 ; CGB mode - def SYSF_DMG equ %0000_01_00 ; DMG compatibility mode - def SYSF_PGB1 equ %0000_10_00 ; LCD is driven externally, CPU is stopped - def SYSF_PGB2 equ %0000_11_00 ; LCD is driven externally, CPU is running +def SYS_MODE equ %0000_11_00 ; current system mode [r/w] + def SYS_CGB equ %0000_00_00 ; CGB mode + def SYS_DMG equ %0000_01_00 ; DMG compatibility mode + def SYS_PGB1 equ %0000_10_00 ; LCD is driven externally, CPU is stopped + def SYS_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 B_SPD_DOUBLE equ 7 ; current clock speed [ro] +def B_SPD_PREPARE equ 0 ; 1 = next `stop` instruction will switch clock speeds [r/w] + def SPD_SINGLE equ 0 << B_SPD_DOUBLE + def SPD_DOUBLE equ 1 << B_SPD_DOUBLE + def SPD_PREPARE equ 1 << B_SPD_PREPARE ; -- $FF4E is unused ---------------------------------------------------------- @@ -576,15 +585,15 @@ def VBK_BANK equ %0000000_1 ; mapped VRAM bank [r/w] ; (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 +def B_BANK_ON equ 0 ; whether the boot ROM is mapped [wo] + def BANK_ON equ 0 << B_BANK_ON + def BANK_OFF equ 1 << B_BANK_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) ---------------------------------------------- +; -- VDMA_SRC_LOW / HDMA2 ($FF52) --------------------------------------------- ; (CGB only) VRAM DMA source address (low 8 bits) [wo] def rVDMA_SRC_LOW equ $FF52 @@ -600,32 +609,32 @@ def rVDMA_DEST_LOW equ $FF54 ; (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 << 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 B_VDMA_LEN_MODE equ 7 ; on write: VRAM DMA mode [wo] + def VDMA_LEN_MODE equ 1 << B_VDMA_LEN_MODE + def VDMA_LEN_MODE_GENERAL equ 0 << B_VDMA_LEN_MODE ; GDMA (general-purpose) + def VDMA_LEN_MODE_HBLANK equ 1 << B_VDMA_LEN_MODE ; HDMA (HBlank) -def VDMA_LENB_BUSY equ 7 ; on read: is a VRAM DMA 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 B_VDMA_LEN_BUSY equ 7 ; on read: is a VRAM DMA active? + def VDMA_LEN_BUSY equ 1 << B_VDMA_LEN_BUSY + def VDMA_LEN_NO equ 0 << B_VDMA_LEN_BUSY + def VDMA_LEN_YES equ 1 << B_VDMA_LEN_BUSY -def VDMA_LENB_SIZE equ %0_1111111 ; how many 16-byte blocks (minus 1) to transfer [r/w] +def VDMA_LEN_SIZE equ %0_1111111 ; how many 16-byte blocks (minus 1) to transfer [r/w] ; -- RP ($FF56) --------------------------------------------------------------- ; (CGB only) Infrared communications port def rRP equ $FF56 -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 +def RP_READ equ %11_000000 ; whether the IR read is enabled [r/w] + def RP_DISABLE equ %00_000000 + def RP_ENABLE equ %11_000000 -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 +def B_RP_DATA_IN equ 1 ; 0 = IR light is being received [ro] +def B_RP_LED_ON equ 0 ; 1 = IR light is being sent [r/w] + def RP_DATA_IN equ 1 << B_RP_DATA_IN + def RP_LED_ON equ 1 << B_RP_LED_ON + def RP_WRITE_LOW equ 0 << B_RP_LED_ON + def RP_WRITE_HIGH equ 1 << B_RP_LED_ON ; -- $FF57-$FF67 are unused --------------------------------------------------- @@ -633,10 +642,10 @@ def RPB_LED_ON equ 0 ; 1 = IR light is being sent [r/w] ; (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 +def B_BGPI_AUTOINC equ 7 ; whether the index field is incremented after each write to BCPD [r/w] + def BGPI_AUTOINC equ 1 << B_BGPI_AUTOINC -def BGPIF_INDEX equ %00_111111 ; the index within Palette RAM accessed via BCPD [r/w] +def BGPI_INDEX equ %00_111111 ; the index within Palette RAM accessed via BCPD [r/w] ; -- BGPD / BCPD ($FF69) ------------------------------------------------------ ; (CGB only) Background palette I/O access [r/w] @@ -646,10 +655,10 @@ def rBGPD equ $FF69 ; (CGB only) OBJ palette I/O index def rOBPI equ $FF6A -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 B_OBPI_AUTOINC equ 7 ; whether the index field is incremented after each write to OBPD [r/w] + def OBPI_AUTOINC equ 1 << B_OBPI_AUTOINC -def OBPIF_INDEX equ %00_111111 ; the index within Palette RAM accessed via OBPD [r/w] +def OBPI_INDEX equ %00_111111 ; the index within Palette RAM accessed via OBPD [r/w] ; -- OBPD / OCPD ($FF6B) ------------------------------------------------------ ; (CGB only) OBJ palette I/O access [r/w] @@ -659,18 +668,18 @@ def rOBPD equ $FF6B ; (CGB boot ROM only) OBJ draw priority mode def rOPRI equ $FF6C -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 +def B_OPRI_PRIORITY equ 0 ; which drawing priority is used for OBJs [r/w] + def OPRI_PRIORITY equ 1 << B_OPRI_PRIORITY + def OPRI_OAM equ 0 << B_OPRI_PRIORITY ; CGB mode default: earliest OBJ in OAM wins + def OPRI_COORD equ 1 << B_OPRI_PRIORITY ; DMG mode default: leftmost OBJ wins ; -- $FF6D-$FF6F are unused --------------------------------------------------- -; -- WBK / SVBK / SMBK ($FF70) ------------------------------------------------ +; -- WBK / SVBK ($FF70) ------------------------------------------------------- ; (CGB only) WRAM bank number def rWBK equ $FF70 -def WBKF_BANK equ %00000_111 ; mapped WRAM bank (0-7) [r/w] +def WBK_BANK equ %00000_111 ; mapped WRAM bank (0-7) [r/w] ; -- $FF71-$FF75 are unused --------------------------------------------------- @@ -678,15 +687,15 @@ def WBKF_BANK equ %00000_111 ; mapped WRAM bank (0-7) [r/w] ; 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] +def PCM12_CH2 equ %1111_0000 ; audio channel 2 output [ro] +def PCM12_CH1 equ %0000_1111 ; audio channel 1 output [ro] ; -- 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] +def PCM34_CH4 equ %1111_0000 ; audio channel 4 output [ro] +def PCM34_CH3 equ %0000_1111 ; audio channel 3 output [ro] ; -- $FF78-$FF7F are unused --------------------------------------------------- @@ -694,16 +703,16 @@ def PCM34F_CH3 equ %0000_1111 ; audio channel 3 output [ro] ; Interrupt enable def rIE equ $FFFF -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 << 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 +def B_IE_JOYPAD equ 4 ; 1 = joypad interrupt is enabled [r/w] +def B_IE_SERIAL equ 3 ; 1 = serial interrupt is enabled [r/w] +def B_IE_TIMER equ 2 ; 1 = timer interrupt is enabled [r/w] +def B_IE_STAT equ 1 ; 1 = STAT interrupt is enabled [r/w] +def B_IE_VBLANK equ 0 ; 1 = VBlank interrupt is enabled [r/w] + def IE_JOYPAD equ 1 << B_IE_JOYPAD + def IE_SERIAL equ 1 << B_IE_SERIAL + def IE_TIMER equ 1 << B_IE_TIMER + def IE_STAT equ 1 << B_IE_STAT + def IE_VBLANK equ 1 << B_IE_VBLANK ;****************************************************************************** @@ -719,8 +728,8 @@ def IEB_VBLANK equ 0 ; 1 = VBlank interrupt is enabled [r/w] def rRAMG equ $0000 ; Common values -def CART_SRAM_DISABLE equ $00 -def CART_SRAM_ENABLE equ $0A ; some MBCs accept any value whose low nybble is $A +def RAMG_SRAM_DISABLE equ $00 +def RAMG_SRAM_ENABLE equ $0A ; some MBCs accept any value whose low nybble is $A ; -- ROMB0 ($2000-$3FFF) ------------------------------------------------------ ; ROM bank number (low 8 bits when applicable) [wo] @@ -735,22 +744,22 @@ def rROMB1 equ $3000 def rRAMB equ $4000 ; (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) -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 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 +def RAMB_RTC_S equ $08 ; seconds counter (0-59) +def RAMB_RTC_M equ $09 ; minutes counter (0-59) +def RAMB_RTC_H equ $0A ; hours counter (0-23) +def RAMB_RTC_DL equ $0B ; days counter, low byte (0-255) +def RAMB_RTC_DH equ $0C ; days counter, high bit and other flags + def B_RAMB_RTC_DH_CARRY equ 7 ; 1 = days counter overflowed [wo] + def B_RAMB_RTC_DH_HALT equ 6 ; 0 = run timer, 1 = stop timer [wo] + def B_RAMB_RTC_DH_HIGH equ 0 ; days counter, high bit (bit 8) [wo] + def RAMB_RTC_DH_CARRY equ 1 << B_RAMB_RTC_DH_CARRY + def RAMB_RTC_DH_HALT equ 1 << B_RAMB_RTC_DH_HALT + def RAMB_RTC_DH_HIGH equ 1 << B_RAMB_RTC_DH_HIGH + +def B_RAMB_RUMBLE equ 3 ; (MBC5 and MBC7 only) enable the rumble motor (if any) + def RAMB_RUMBLE equ 1 << B_RAMB_RUMBLE + def RAMB_RUMBLE_OFF equ 0 << B_RAMB_RUMBLE + def RAMB_RUMBLE_ON equ 1 << B_RAMB_RUMBLE ; -- RTCLATCH ($6000-$7FFF) --------------------------------------------------- ; (MBC3 only) RTC latch clock data [wo] @@ -760,7 +769,7 @@ def rRTCLATCH equ $6000 def RTCLATCH_START equ $00 def RTCLATCH_FINISH equ $01 -; -- RTCREG ($A000-$BFFF) --------------------------------------------------- +; -- RTCREG ($A000-$BFFF) ----------------------------------------------------- ; (MBC3 only) RTC register [r/w] def rRTCREG equ $A000 @@ -769,33 +778,45 @@ def rRTCREG equ $A000 ; Screen-related constants ;****************************************************************************** -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_B equ SCRN_X_B * SCRN_Y_B ; size 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_V_B equ SCRN_VX_B * SCRN_VY_B ; size of tilemap 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) - -def COLOR_B equ 2 ; size of color in bytes (little-endian BGR555) - 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 SCREEN_WIDTH_PX equ 160 ; width of screen in pixels +def SCREEN_HEIGHT_PX equ 144 ; height of screen in pixels +def SCREEN_WIDTH equ 20 ; width of screen in bytes +def SCREEN_HEIGHT equ 18 ; height of screen in bytes +def SCREEN_AREA equ SCREEN_WIDTH * SCREEN_HEIGHT ; size of screen in bytes + +def TILEMAP_WIDTH_PX equ 256 ; width of tilemap in pixels +def TILEMAP_HEIGHT_PX equ 256 ; height of tilemap in pixels +def TILEMAP_WIDTH equ 32 ; width of tilemap in bytes +def TILEMAP_HEIGHT equ 32 ; height of tilemap in bytes +def TILEMAP_AREA equ TILEMAP_WIDTH * TILEMAP_HEIGHT ; size of tilemap in bytes + +def TILE_WIDTH equ 8 ; width of tile in pixels +def TILE_HEIGHT equ 8 ; height of tile in pixels +def TILE_SIZE equ 16 ; size of tile in bytes (2 bits/pixel) + +def COLOR_SIZE equ 2 ; size of color in bytes (little-endian BGR555) + def COLOR_GREEN_LOW equ %111_00000 ; for the low byte + def COLOR_RED equ %000_11111 ; for the low byte + def COLOR_BLUE equ %0_11111_00 ; for the high byte + def COLOR_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 +def PAL_SIZE equ COLOR_SIZE * 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 +def TILEMAP0 equ $9800 ; $9800-$9BFF +def TILEMAP1 equ $9C00 ; $9C00-$9FFF + +; (CGB only) BG tile attribute fields +def B_BG_PRIO equ 7 ; whether the BG tile colors 1-3 are drawn below OBJs +def B_BG_YFLIP equ 6 ; whether the whole BG tile is flipped vertically +def B_BG_XFLIP equ 5 ; whether the whole BG tile is flipped horizontally +def B_BG_BANK1 equ 3 ; which VRAM bank the BG tile is taken from +def BG_PALETTE equ %00000_111 ; which palette the BG tile uses + def BG_PRIO equ 1 << B_BG_PRIO + def BG_YFLIP equ 1 << B_BG_YFLIP + def BG_XFLIP equ 1 << B_BG_XFLIP + def BG_BANK0 equ 0 << B_BG_BANK1 + def BG_BANK1 equ 1 << B_BG_BANK1 ;****************************************************************************** @@ -810,23 +831,23 @@ 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 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 - 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 rb 0 ; size of OBJ in bytes = 4 + def B_OAM_PRIO equ 7 ; whether the OBJ is drawn above BG colors 1-3 + def B_OAM_YFLIP equ 6 ; whether the whole OBJ is flipped vertically + def B_OAM_XFLIP equ 5 ; whether the whole OBJ is flipped horizontally + def B_OAM_PAL1 equ 4 ; (DMG only) which of the two palettes the OBJ uses + def B_OAM_BANK1 equ 3 ; (CGB only) which VRAM bank the OBJ takes its tile(s) from + def OAM_PALETTE equ %00000_111 ; (CGB only) which palette the OBJ uses + def OAM_PRIO equ 1 << B_OAM_PRIO + def OAM_YFLIP equ 1 << B_OAM_YFLIP + def OAM_XFLIP equ 1 << B_OAM_XFLIP + def OAM_PAL0 equ 0 << B_OAM_PAL1 + def OAM_PAL1 equ 1 << B_OAM_PAL1 + def OAM_BANK0 equ 0 << B_OAM_BANK1 + def OAM_BANK1 equ 1 << B_OAM_BANK1 +def OBJ_SIZE rb 0 ; size of OBJ in bytes = 4 def OAM_COUNT equ 40 ; how many OBJs there are room for in OAM -def OAM_B equ OBJ_B * OAM_COUNT +def OAM_SIZE equ OBJ_SIZE * OAM_COUNT ;****************************************************************************** @@ -852,9 +873,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 BOOTUPB_B_AGB equ 0 - def BOOTUP_B_CGB equ 0 << BOOTUPB_B_AGB - def BOOTUP_B_AGB equ 1 << BOOTUPB_B_AGB +def B_BOOTUP_B_AGB equ 0 + def BOOTUP_B_CGB equ 0 << B_BOOTUP_B_AGB + def BOOTUP_B_AGB equ 1 << B_BOOTUP_B_AGB ;****************************************************************************** @@ -865,15 +886,6 @@ def BOOTUPB_B_AGB equ 0 ; less directly meaningful or human-readable. 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 rNR10 equ rAUD1SWEEP def rNR11 equ rAUD1LEN @@ -898,187 +910,20 @@ def rNR51 equ rAUDTERM def rNR52 equ rAUDENA def rKEY0 equ rSYS -def KEY0F_MODE equ SYSF_MODE - def KEY0F_CGB equ SYSF_CGB - def KEY0F_DMG equ SYSF_DMG - def KEY0F_PGB1 equ SYSF_PGB1 - def KEY0F_PGB2 equ SYSF_PGB2 - 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 rWBK -def rSMBK equ rWBK - - -;****************************************************************************** -; (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)`) - - -;****************************************************************************** -; (deprecated) Cartridge header -;****************************************************************************** - -; 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 -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 ; 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 ; default value if header is zero-filled -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 ; default value if header is zero-filled -def CART_DEST_NON_JAPANESE equ $01 ; prefer `rgbfix -j/--non-japanese` - - -;****************************************************************************** -; Deprecated constants -;****************************************************************************** - -; These values are deprecated; please avoid using them. - -def AUDLENF_DUTY equ AUD1LENF_DUTY - def AUDLEN_DUTY_12_5 equ AUD1LEN_DUTY_12_5 - def AUDLEN_DUTY_25 equ AUD1LEN_DUTY_25 - def AUDLEN_DUTY_50 equ AUD1LEN_DUTY_50 - def AUDLEN_DUTY_75 equ AUD1LEN_DUTY_75 - -def AUDLENF_TIMER equ AUD1LENF_TIMER - -def AUDENVF_INIT_VOL equ AUD1ENVF_INIT_VOL - -def AUDENVB_DIR equ AUD1ENVB_DIR - def AUDENVF_DIR equ AUD1ENVF_DIR - def AUDENV_DOWN equ AUD1ENV_DOWN - def AUDENV_UP equ AUD1ENV_UP - -def AUDENVF_PACE equ AUD1ENVF_PACE - -def AUDHIGHB_RESTART equ AUD1HIGHB_RESTART -def AUDHIGHB_LEN_ENABLE equ AUD1HIGHB_LEN_ENABLE - def AUDHIGH_RESTART equ AUD1HIGH_RESTART - def AUDHIGH_LENGTH_OFF equ AUD1HIGH_LENGTH_OFF - def AUDHIGH_LENGTH_ON equ AUD1HIGH_LENGTH_ON - -def AUDHIGHF_PERIOD_HIGH equ AUD1HIGHF_PERIOD_HIGH - -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 - -def _VRAM8000 equ _VRAM -def _VRAM8800 equ _VRAM + $800 -def _VRAM9000 equ _VRAM + $1000 endc ; HARDWARE_INC diff --git a/hardware_compat.inc b/hardware_compat.inc new file mode 100644 index 0000000..704777d --- /dev/null +++ b/hardware_compat.inc @@ -0,0 +1,573 @@ +;****************************************************************************** +; Deprecated Game Boy hardware constant definitions for backwards compatibility +; https://github.com/gbdev/hardware_compat.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_COMPAT_INC) + +; Check for hardware.inc to have been previously included +if !def(HARDWARE_INC) + fail "'hardware_compat.inc' requires 'hardware.inc'" +endc + +; Define the include guard +; (do this after the hardware.inc check since the `def` syntax depends on it) +def HARDWARE_COMPAT_INC equ 1 + + +;****************************************************************************** +; Memory-mapped registers ($FFxx range) +;****************************************************************************** + +def JOYPB_GET_BTN equ B_JOYP_GET_BUTTONS +def JOYPB_GET_DPAD equ B_JOYP_GET_CTRL_PAD + def JOYPF_GET equ JOYP_GET + def JOYP_GET_BTN equ JOYP_GET_BUTTONS + def JOYP_GET_DPAD equ JOYP_GET_CTRL_PAD +def JOYPB_START equ B_JOYP_START +def JOYPB_SELECT equ B_JOYP_SELECT +def JOYPB_B equ B_JOYP_B +def JOYPB_A equ B_JOYP_A +def JOYPB_DOWN equ B_JOYP_DOWN +def JOYPB_UP equ B_JOYP_UP +def JOYPB_LEFT equ B_JOYP_LEFT +def JOYPB_RIGHT equ B_JOYP_RIGHT + def JOYPF_INPUTS equ JOYP_INPUTS + def JOYPF_START equ JOYP_START + def JOYPF_SELECT equ JOYP_SELECT + def JOYPF_B equ JOYP_B + def JOYPF_A equ JOYP_A + def JOYPF_DOWN equ JOYP_DOWN + def JOYPF_UP equ JOYP_UP + def JOYPF_LEFT equ JOYP_LEFT + def JOYPF_RIGHT equ JOYP_RIGHT + +def PADB_DOWN equ B_PAD_DOWN +def PADB_UP equ B_PAD_UP +def PADB_LEFT equ B_PAD_LEFT +def PADB_RIGHT equ B_PAD_RIGHT +def PADB_START equ B_PAD_START +def PADB_SELECT equ B_PAD_SELECT +def PADB_B equ B_PAD_B +def PADB_A equ B_PAD_A + def PADF_DOWN equ PAD_DOWN + def PADF_UP equ PAD_UP + def PADF_LEFT equ PAD_LEFT + def PADF_RIGHT equ PAD_RIGHT + def PADF_START equ PAD_START + def PADF_SELECT equ PAD_SELECT + def PADF_B equ PAD_B + def PADF_A equ PAD_A + +def PADB_SWAP_START equ B_PAD_SWAP_START +def PADB_SWAP_SELECT equ B_PAD_SWAP_SELECT +def PADB_SWAP_B equ B_PAD_SWAP_B +def PADB_SWAP_A equ B_PAD_SWAP_A +def PADB_SWAP_DOWN equ B_PAD_SWAP_DOWN +def PADB_SWAP_UP equ B_PAD_SWAP_UP +def PADB_SWAP_LEFT equ B_PAD_SWAP_LEFT +def PADB_SWAP_RIGHT equ B_PAD_SWAP_RIGHT + def PADF_SWAP_START equ PAD_SWAP_START + def PADF_SWAP_SELECT equ PAD_SWAP_SELECT + def PADF_SWAP_B equ PAD_SWAP_B + def PADF_SWAP_A equ PAD_SWAP_A + def PADF_SWAP_DOWN equ PAD_SWAP_DOWN + def PADF_SWAP_UP equ PAD_SWAP_UP + def PADF_SWAP_LEFT equ PAD_SWAP_LEFT + def PADF_SWAP_RIGHT equ PAD_SWAP_RIGHT + +def SCB_START equ B_SC_START +def SCB_SPEED equ B_SC_SPEED +def SCB_SOURCE equ B_SC_SOURCE + def SCF_START equ SC_START + def SCF_SPEED equ SC_SPEED + def SCF_SOURCE equ SC_SOURCE + +def TACB_START equ B_TAC_START + def TACF_STOP equ TAC_STOP + def TACF_START equ TAC_START +def TACF_CLOCK equ TAC_CLOCK + def TACF_4KHZ equ TAC_4KHZ + def TACF_262KHZ equ TAC_262KHZ + def TACF_65KHZ equ TAC_65KHZ + def TACF_16KHZ equ TAC_16KHZ + +def IFB_JOYPAD equ B_IF_JOYPAD +def IFB_SERIAL equ B_IF_SERIAL +def IFB_TIMER equ B_IF_TIMER +def IFB_STAT equ B_IF_STAT +def IFB_VBLANK equ B_IF_VBLANK + def IFF_JOYPAD equ IF_JOYPAD + def IFF_SERIAL equ IF_SERIAL + def IFF_TIMER equ IF_TIMER + def IFF_STAT equ IF_STAT + def IFF_VBLANK equ IF_VBLANK + +def AUD1SWEEPF_TIME equ AUD1SWEEP_TIME +def AUD1SWEEPB_DIR equ B_AUD1SWEEP_DIR + def AUD1SWEEPF_DIR equ AUD1SWEEP_DIR + +def AUD1LENF_DUTY equ AUD1LEN_DUTY +def AUD1LENF_TIMER equ AUD1LEN_TIMER + +def AUD1ENVF_INIT_VOL equ AUD1ENV_INIT_VOLUME +def AUD1ENVB_DIR equ B_AUD1ENV_DIR + def AUD1ENVF_DIR equ AUD1ENV_DIR +def AUD1ENVF_PACE equ AUD1ENV_PACE + +def AUD1HIGHB_RESTART equ B_AUD1HIGH_RESTART +def AUD1HIGHB_LEN_ENABLE equ B_AUD1HIGH_LEN_ENABLE +def AUD1HIGHF_PERIOD_HIGH equ AUD1HIGH_PERIOD_HIGH + +def AUD2LENF_DUTY equ AUD2LEN_DUTY +def AUD2LENF_TIMER equ AUD2LEN_TIMER + +def AUD2ENVF_INIT_VOL equ AUD2ENV_INIT_VOLUME +def AUD2ENVB_DIR equ B_AUD2ENV_DIR + def AUD2ENVF_DIR equ AUD2ENV_DIR +def AUD2ENVF_PACE equ AUD2ENV_PACE + +def AUD2HIGHB_RESTART equ B_AUD2HIGH_RESTART +def AUD2HIGHB_LEN_ENABLE equ B_AUD2HIGH_LEN_ENABLE +def AUD2HIGHF_PERIOD_HIGH equ AUD2HIGH_PERIOD_HIGH + +def AUD3ENAB_ENABLE equ B_AUD3ENA_ENABLE + +def AUD3LEVELF_VOLUME equ AUD3LEVEL_VOLUME + +def AUD3HIGHB_RESTART equ B_AUD3HIGH_RESTART +def AUD3HIGHB_LEN_ENABLE equ B_AUD3HIGH_LEN_ENABLE +def AUD3HIGHF_PERIOD_HIGH equ AUD3HIGH_PERIOD_HIGH + +def AUD4LENF_TIMER equ AUD4LEN_TIMER + +def AUD4ENVF_INIT_VOL equ AUD4ENV_INIT_VOLUME +def AUD4ENVB_DIR equ B_AUD4ENV_DIR + def AUD4ENVF_DIR equ AUD4ENV_DIR +def AUD4ENVF_PACE equ AUD4ENV_PACE + +def AUD4POLYF_SHIFT equ AUD4POLY_SHIFT +def AUD4POLYB_WIDTH equ B_AUD4POLY_WIDTH +def AUD4POLYF_DIV equ AUD4POLY_DIV + +def AUD4GOB_RESTART equ B_AUD4GO_RESTART +def AUD4GOB_LEN_ENABLE equ B_AUD4GO_LEN_ENABLE + +def AUDVOLB_VIN_LEFT equ B_AUDVOL_VIN_LEFT + def AUDVOLF_LEFT equ AUDVOL_LEFT +def AUDVOLB_VIN_RIGHT equ B_AUDVOL_VIN_RIGHT + def AUDVOLF_RIGHT equ AUDVOL_RIGHT + +def AUDTERMB_4_LEFT equ B_AUDTERM_4_LEFT +def AUDTERMB_3_LEFT equ B_AUDTERM_3_LEFT +def AUDTERMB_2_LEFT equ B_AUDTERM_2_LEFT +def AUDTERMB_1_LEFT equ B_AUDTERM_1_LEFT +def AUDTERMB_4_RIGHT equ B_AUDTERM_4_RIGHT +def AUDTERMB_3_RIGHT equ B_AUDTERM_3_RIGHT +def AUDTERMB_2_RIGHT equ B_AUDTERM_2_RIGHT +def AUDTERMB_1_RIGHT equ B_AUDTERM_1_RIGHT + +def AUDENAB_ENABLE equ B_AUDENA_ENABLE +def AUDENAB_ENABLE_CH4 equ B_AUDENA_ENABLE_CH4 +def AUDENAB_ENABLE_CH3 equ B_AUDENA_ENABLE_CH3 +def AUDENAB_ENABLE_CH2 equ B_AUDENA_ENABLE_CH2 +def AUDENAB_ENABLE_CH1 equ B_AUDENA_ENABLE_CH1 + def AUDENAF_CH4_OFF equ AUDENA_CH4_OFF + def AUDENAF_CH4_ON equ AUDENA_CH4_ON + def AUDENAF_CH3_OFF equ AUDENA_CH3_OFF + def AUDENAF_CH3_ON equ AUDENA_CH3_ON + def AUDENAF_CH2_OFF equ AUDENA_CH2_OFF + def AUDENAF_CH2_ON equ AUDENA_CH2_ON + def AUDENAF_CH1_OFF equ AUDENA_CH1_OFF + def AUDENAF_CH1_ON equ AUDENA_CH1_ON + +def LCDCB_ON equ B_LCDC_ENABLE +def LCDCB_WIN9C00 equ B_LCDC_WIN_MAP +def LCDCB_WINON equ B_LCDC_WINDOW +def LCDCB_BLKS equ B_LCDC_BLOCKS +def LCDCB_BG9C00 equ B_LCDC_BG_MAP +def LCDCB_OBJ16 equ B_LCDC_OBJ_SIZE +def LCDCB_OBJON equ B_LCDC_OBJS +def LCDCB_BGON equ B_LCDC_BG +def LCDCB_PRION equ B_LCDC_PRIO + def LCDCF_OFF equ LCDC_OFF + def LCDCF_ON equ LCDC_ON + def LCDCF_WIN9800 equ LCDC_WIN_9800 + def LCDCF_WIN9C00 equ LCDC_WIN_9C00 + def LCDCF_WINOFF equ LCDC_WIN_OFF + def LCDCF_WINON equ LCDC_WIN_ON + def LCDCF_BLKS equ LCDC_BLOCKS + def LCDCF_BLK21 equ LCDC_BLOCK21 + def LCDCF_BLK01 equ LCDC_BLOCK01 + def LCDCF_BG9800 equ LCDC_BG_9800 + def LCDCF_BG9C00 equ LCDC_BG_9C00 + def LCDCF_OBJ8 equ LCDC_OBJ_8 + def LCDCF_OBJ16 equ LCDC_OBJ_16 + def LCDCF_OBJOFF equ LCDC_OBJ_OFF + def LCDCF_OBJON equ LCDC_OBJ_ON + def LCDCF_BGOFF equ LCDC_BG_OFF + def LCDCF_BGON equ LCDC_BG_ON + def LCDCF_PRIOFF equ LCDC_PRIO_OFF + def LCDCF_PRION equ LCDC_PRIO_ON + +def STATB_LYC equ B_STAT_LYC +def STATB_MODE10 equ B_STAT_MODE_2 +def STATB_MODE01 equ B_STAT_MODE_1 +def STATB_MODE00 equ B_STAT_MODE_0 +def STATB_LYCF equ B_STAT_LYCF +def STATB_BUSY equ B_STAT_BUSY + def STATF_LYC equ STAT_LYC + def STATF_MODE10 equ STAT_MODE_2 + def STATF_MODE01 equ STAT_MODE_1 + def STATF_MODE00 equ STAT_MODE_0 + def STATF_LYCF equ STAT_LYCF + def STATF_BUSY equ STAT_BUSY +def STATF_MODE equ STAT_MODE + def STATF_HBL equ STAT_HBLANK + def STATF_VBL equ STAT_VBLANK + def STATF_OAM equ STAT_OAM + def STATF_LCD equ STAT_LCD + +def SYSF_MODE equ SYS_MODE + def SYSF_CGB equ SYS_CGB + def SYSF_DMG equ SYS_DMG + def SYSF_PGB1 equ SYS_PGB1 + def SYSF_PGB2 equ SYS_PGB2 + +def SPDB_DBLSPEED equ B_SPD_DOUBLE +def SPDB_PREPARE equ B_SPD_PREPARE + def SPDF_DBLSPEED equ SPD_DOUBLE + def SPDF_PREPARE equ SPD_PREPARE + +def BANKB_ON equ B_BANK_ON + def BANKF_ON equ BANK_ON + def BANKF_OFF equ BANK_OFF + +def VDMA_LENB_MODE equ B_VDMA_LEN_MODE + def VDMA_LENF_MODE equ VDMA_LEN_MODE + def VDMA_LENF_MODE_GP equ VDMA_LEN_MODE_GENERAL + def VDMA_LENF_MODE_HBL equ VDMA_LEN_MODE_HBLANK +def VDMA_LENB_BUSY equ B_VDMA_LEN_BUSY + def VDMA_LENF_BUSY equ VDMA_LEN_BUSY + def VDMA_LENF_NO equ VDMA_LEN_NO + def VDMA_LENF_YES equ VDMA_LEN_YES +def VDMA_LENB_SIZE equ VDMA_LEN_SIZE + +def RPF_READ equ RP_READ + def RPF_DISREAD equ RP_DISABLE + def RPF_ENREAD equ RP_ENABLE +def RPB_DATAIN equ B_RP_DATA_IN +def RPB_LED_ON equ B_RP_LED_ON + def RPF_DATAIN equ RP_DATA_IN + def RPF_LED_ON equ RP_LED_ON + def RPF_WRITE_LO equ RP_WRITE_LOW + def RPF_WRITE_HI equ RP_WRITE_HIGH + +def BGPIB_AUTOINC equ B_BGPI_AUTOINC + def BGPIF_AUTOINC equ BGPI_AUTOINC +def BGPIF_INDEX equ BGPI_INDEX + +def OBPIB_AUTOINC equ B_OBPI_AUTOINC + def OBPIF_AUTOINC equ OBPI_AUTOINC +def OBPIF_INDEX equ OBPI_INDEX + +def OPRIB_PRI equ B_OPRI_PRIORITY + def OPRIF_PRI equ OPRI_PRIORITY + +def WBKF_BANK equ WBK_BANK + +def PCM12F_CH2 equ PCM12_CH2 +def PCM12F_CH1 equ PCM12_CH1 + +def PCM34F_CH4 equ PCM34_CH4 +def PCM34F_CH3 equ PCM34_CH3 + +def IEB_JOYPAD equ B_IE_JOYPAD +def IEB_SERIAL equ B_IE_SERIAL +def IEB_TIMER equ B_IE_TIMER +def IEB_STAT equ B_IE_STAT +def IEB_VBLANK equ B_IE_VBLANK + def IEF_JOYPAD equ IE_JOYPAD + def IEF_SERIAL equ IE_SERIAL + def IEF_TIMER equ IE_TIMER + def IEF_STAT equ IE_STAT + def IEF_VBLANK equ IE_VBLANK + + +;****************************************************************************** +; Cartridge registers (MBC) +;****************************************************************************** + +def CART_SRAM_DISABLE equ RAMG_SRAM_DISABLE +def CART_SRAM_ENABLE equ RAMG_SRAM_ENABLE + +def RTC_S equ RAMB_RTC_S +def RTC_M equ RAMB_RTC_M +def RTC_H equ RAMB_RTC_H +def RTC_DL equ RAMB_RTC_DL +def RTC_DH equ RAMB_RTC_DH + def RTC_DHB_CARRY equ B_RAMB_RTC_DH_CARRY + def RTC_DHB_HALT equ B_RAMB_RTC_DH_HALT + def RTC_DHB_HIGH equ B_RAMB_RTC_DH_HIGH + def RTC_DHF_CARRY equ RAMB_RTC_DH_CARRY + def RTC_DHF_HALT equ RAMB_RTC_DH_HALT + def RTC_DHF_HIGH equ RAMB_RTC_DH_HIGH + +def CARTB_RUMBLE_ON equ B_RAMB_RUMBLE +def CARTF_RUMBLE_ON equ RAMB_RUMBLE +def CART_RUMBLE_OFF equ RAMB_RUMBLE_OFF +def CART_RUMBLE_ON equ RAMB_RUMBLE_ON + + +;****************************************************************************** +; Screen-related constants +;****************************************************************************** + +def SCRN_X equ SCREEN_WIDTH_PX +def SCRN_Y equ SCREEN_HEIGHT_PX +def SCRN_X_B equ SCREEN_WIDTH +def SCRN_Y_B equ SCREEN_HEIGHT +def SCRN_B equ SCREEN_AREA + +def SCRN_VX equ TILEMAP_WIDTH_PX +def SCRN_VY equ TILEMAP_HEIGHT_PX +def SCRN_VX_B equ TILEMAP_WIDTH +def SCRN_VY_B equ TILEMAP_HEIGHT +def SCRN_V_B equ TILEMAP_AREA + +def TILE_X equ TILE_WIDTH +def TILE_Y equ TILE_HEIGHT +def TILE_B equ TILE_SIZE + +def COLOR_B equ COLOR_SIZE + def COLORF_GREEN_LOW equ COLOR_GREEN_LOW + def COLORF_RED equ COLOR_RED + def COLORF_BLUE equ COLOR_BLUE + def COLORF_GREEN_HIGH equ COLOR_GREEN_HIGH + +def PAL_B equ PAL_SIZE + +def _SCRN0 equ TILEMAP0 +def _SCRN1 equ TILEMAP1 + + +;****************************************************************************** +; OBJ-related constants +;****************************************************************************** + +def OAMB_PRI equ B_OAM_PRIO +def OAMB_YFLIP equ B_OAM_YFLIP +def OAMB_XFLIP equ B_OAM_XFLIP +def OAMB_PAL1 equ B_OAM_PAL1 +def OAMB_BANK1 equ B_OAM_BANK1 +def OAMF_PALMASK equ OAM_PALETTE + def OAMF_PRI equ OAM_PRIO + def OAMF_YFLIP equ OAM_YFLIP + def OAMF_XFLIP equ OAM_XFLIP + def OAMF_PAL0 equ OAM_PAL0 + def OAMF_PAL1 equ OAM_PAL1 + def OAMF_BANK0 equ OAM_BANK0 + def OAMF_BANK1 equ OAM_BANK1 +def OBJ_B equ OBJ_SIZE + +def OAM_B equ OAM_SIZE + + +;****************************************************************************** +; Boot-up register values +;****************************************************************************** + +def BOOTUPB_B_AGB equ B_BOOTUP_B_AGB + + +;****************************************************************************** +; Aliases +;****************************************************************************** + +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 KEY0F_MODE equ SYSF_MODE + def KEY0F_CGB equ SYSF_CGB + def KEY0F_DMG equ SYSF_DMG + def KEY0F_PGB1 equ SYSF_PGB1 + def KEY0F_PGB2 equ SYSF_PGB2 + +def KEY1F_DBLSPEED equ SPDF_DBLSPEED +def KEY1F_PREPARE equ SPDF_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 + +def BCPSB_AUTOINC equ BGPIB_AUTOINC + def BCPSF_AUTOINC equ BGPIF_AUTOINC + +def OCPSB_AUTOINC equ OBPIB_AUTOINC + def OCPSF_AUTOINC equ OBPIF_AUTOINC + +def rSMBK equ rWBK + + +;****************************************************************************** +; Memory regions +;****************************************************************************** + +; Prefer RGBASM and RGBLINK features instead of these values. +; 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)`) + + +;****************************************************************************** +; Cartridge header +;****************************************************************************** + +; Prefer RGBFIX instead of these values. +; 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 +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 ; 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 ; default value if header is zero-filled +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 ; default value if header is zero-filled +def CART_DEST_NON_JAPANESE equ $01 ; prefer `rgbfix -j/--non-japanese` + + +;****************************************************************************** +; Deprecated constants +;****************************************************************************** + +def AUDLENF_DUTY equ AUD1LENF_DUTY + def AUDLEN_DUTY_12_5 equ AUD1LEN_DUTY_12_5 + def AUDLEN_DUTY_25 equ AUD1LEN_DUTY_25 + def AUDLEN_DUTY_50 equ AUD1LEN_DUTY_50 + def AUDLEN_DUTY_75 equ AUD1LEN_DUTY_75 + +def AUDLENF_TIMER equ AUD1LENF_TIMER + +def AUDENVF_INIT_VOL equ AUD1ENVF_INIT_VOL + +def AUDENVB_DIR equ AUD1ENVB_DIR + def AUDENVF_DIR equ AUD1ENVF_DIR + def AUDENV_DOWN equ AUD1ENV_DOWN + def AUDENV_UP equ AUD1ENV_UP + +def AUDENVF_PACE equ AUD1ENVF_PACE + +def AUDHIGHB_RESTART equ AUD1HIGHB_RESTART +def AUDHIGHB_LEN_ENABLE equ AUD1HIGHB_LEN_ENABLE + def AUDHIGH_RESTART equ AUD1HIGH_RESTART + def AUDHIGH_LENGTH_OFF equ AUD1HIGH_LENGTH_OFF + def AUDHIGH_LENGTH_ON equ AUD1HIGH_LENGTH_ON + +def AUDHIGHF_PERIOD_HIGH equ AUD1HIGHF_PERIOD_HIGH + +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 + +def _VRAM8000 equ _VRAM +def _VRAM8800 equ _VRAM + $800 +def _VRAM9000 equ _VRAM + $1000 + +endc ; HARDWARE_COMPAT_INC