1023 lines
40 KiB
PHP
1023 lines
40 KiB
PHP
;******************************************************************************
|
|
; Game Boy hardware constant 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 <min_ver>
|
|
; 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_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
|
|
\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
|
|
|
|
|
|
;******************************************************************************
|
|
; Memory-mapped registers ($FFxx range)
|
|
;******************************************************************************
|
|
|
|
; -- 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 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
|
|
|
|
; 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
|
|
|
|
; 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
|
|
|
|
; -- 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) [r/w]
|
|
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 [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 [r/w]
|
|
|
|
; -- $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) [r/w]
|
|
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 [r/w]
|
|
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 [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) [r/w]
|
|
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 [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 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 [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
|
|
|
|
; -- 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 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) [r/w]
|
|
def AUDVOL_VIN_RIGHT equ 1 << AUDVOLB_VIN_RIGHT
|
|
|
|
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 [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
|
|
|
|
; -- 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
|
|
|
|
; -- $FF27-$FF2F are unused ---------------------------------------------------
|
|
|
|
; -- AUD3WAVE ($FF30-$FF3F) ---------------------------------------------------
|
|
; Audio channel 3 wave pattern RAM [r/w]
|
|
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
|
|
|
|
def AUD3WAVE_SIZE equ 16
|
|
|
|
; -- LCDC ($FF40) -------------------------------------------------------------
|
|
; 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
|
|
|
|
; -- 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
|
|
|
|
; -- SCY ($FF42) --------------------------------------------------------------
|
|
; Background Y scroll offset (in pixels) [r/w]
|
|
def rSCY equ $FF42
|
|
|
|
; -- SCX ($FF43) --------------------------------------------------------------
|
|
; Background X scroll offset (in pixels) [r/w]
|
|
def rSCX equ $FF43
|
|
|
|
; -- 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) --------------------------------------------------------------
|
|
; Value that LY is constantly compared to [r/w]
|
|
def rLYC equ $FF45
|
|
|
|
; -- DMA ($FF46) --------------------------------------------------------------
|
|
; OAM DMA start address (high 8 bits) and start [wo]
|
|
def rDMA equ $FF46
|
|
|
|
; -- BGP ($FF47) --------------------------------------------------------------
|
|
; (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
|
|
|
|
; -- OBP1 ($FF49) -------------------------------------------------------------
|
|
; (DMG only) OBJ color mapping #1 [r/w]
|
|
def rOBP1 equ $FF49
|
|
|
|
; -- WY ($FF4A) ---------------------------------------------------------------
|
|
; Y coordinate of the Window's top-left pixel (0-143) [r/w]
|
|
def rWY equ $FF4A
|
|
|
|
; -- 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 ; subtract this to get the actual Window Y coordinate
|
|
|
|
; -- KEY0 ($FF4C) -------------------------------------------------------------
|
|
; (CGB boot ROM only) CPU mode select
|
|
def rKEY0 equ $FF4C
|
|
|
|
; 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
|
|
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
|
|
|
|
; -- $FF4E is unused ----------------------------------------------------------
|
|
|
|
; -- 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
|
|
|
|
; -- 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
|
|
|
|
; -- 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
|
|
|
|
; -- 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 << 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_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]
|
|
|
|
; -- 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 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
|
|
|
|
; -- $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
|
|
|
|
def BGPIF_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]
|
|
def rBGPD equ $FF69
|
|
|
|
; -- OBPI / OCPS ($FF6A) ------------------------------------------------------
|
|
; (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 OBPIF_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]
|
|
def rOBPD equ $FF6B
|
|
|
|
; -- OPRI ($FF6C) -------------------------------------------------------------
|
|
; (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
|
|
|
|
; -- $FF6D-$FF6F are unused ---------------------------------------------------
|
|
|
|
; -- WBK / SVBK / SMBK ($FF70) ------------------------------------------------
|
|
; (CGB only) WRAM bank number
|
|
def rWBK equ $FF70
|
|
|
|
def WBKF_BANK equ %00000_111 ; mapped WRAM bank (0-7) [r/w]
|
|
|
|
; -- $FF71-$FF75 are unused ---------------------------------------------------
|
|
|
|
; -- 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) ------------------------------------------------------------
|
|
; 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]
|
|
|
|
; -- $FF78-$FF7F are unused ---------------------------------------------------
|
|
|
|
; -- IE ($FFFF) ---------------------------------------------------------------
|
|
; 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
|
|
|
|
|
|
;******************************************************************************
|
|
; 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) -------------------------------------------------------
|
|
; Whether SRAM can be accessed [wo]
|
|
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
|
|
|
|
; -- ROMB0 ($2000-$3FFF) ------------------------------------------------------
|
|
; ROM bank number (low 8 bits when applicable) [wo]
|
|
def rROMB0 equ $2000
|
|
|
|
; -- ROMB1 ($3000-$3FFF) ------------------------------------------------------
|
|
; (MBC5 only) ROM bank number high bit (bit 8) [wo]
|
|
def rROMB1 equ $3000
|
|
|
|
; -- RAMB ($4000-$5FFF) -------------------------------------------------------
|
|
; SRAM bank number [wo]
|
|
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
|
|
|
|
; -- RTCLATCH ($6000-$7FFF) ---------------------------------------------------
|
|
; (MBC3 only) RTC latch clock data [wo]
|
|
def rRTCLATCH equ $6000
|
|
|
|
; 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 [r/w]
|
|
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_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 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 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
|
|
|
|
|
|
;******************************************************************************
|
|
; OBJ-related constants
|
|
;******************************************************************************
|
|
|
|
; OAM attribute field offsets
|
|
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 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 OAM_COUNT equ 40 ; how many OBJs there are room for in OAM
|
|
def OAM_B equ OBJ_B * OAM_COUNT
|
|
|
|
|
|
;******************************************************************************
|
|
; 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
|
|
|
|
|
|
;******************************************************************************
|
|
; 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 BOOTUPB_B_AGB equ 0
|
|
def BOOTUP_B_CGB equ 0 << BOOTUPB_B_AGB
|
|
def BOOTUP_B_AGB equ 1 << BOOTUPB_B_AGB
|
|
|
|
|
|
;******************************************************************************
|
|
; 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 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
|
|
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
|
|
|
|
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(<section_type>)` 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 _VRAM8000 equ _VRAM
|
|
def _VRAM8800 equ _VRAM + $800
|
|
def _VRAM9000 equ _VRAM + $1000
|
|
|
|
|
|
;******************************************************************************
|
|
; (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 <logo_file>` 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 <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 <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 <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 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
|