Skip to content

Instantly share code, notes, and snippets.

@jjbarr
Created May 18, 2020 16:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jjbarr/3dc2823a2ae7b1b342ea9066b401811e to your computer and use it in GitHub Desktop.
Save jjbarr/3dc2823a2ae7b1b342ea9066b401811e to your computer and use it in GitHub Desktop.
C/GB hardware include.
;;; -*-mode: asm-mode-*-
;;; Derived (somewhat) from GABY's gbhw.inc
;;; By Thoth
IF !DEF(HW_INC)
HW_INC EQU 1
;;; Header Definition
CGB_NO EQU $00
CGB_YES EQU $80
CGB_ONLY EQU $C0
SGB_NO EQU $00
SGB_YES EQU $03
CART_ROM_ONLY EQU $00
CART_MBC1 EQU $01
CART_MBC1_RAM EQU $02
CART_MBC1_RAM_BATT EQU $03
CART_MBC2 EQU $05
CART_MBC2_BATT EQU $06
CART_ROM_RAM EQU $08
CART_ROM_RAM_BATT EQU $09
CART_MMM01 EQU $0B
CART_MMM01_RAM EQU $0C
CART_MMM01_RAM_BATT EQU $0D
CART_MBC3_TIMER_BATT EQU $0F
CART_MBC3_TIMER_RAM_BATT EQU $10
CART_MBC3 EQU $11
CART_MBC3_RAM EQU $12
CART_MBC3_RAM_BATT EQU $13
CART_MBC5 EQU $19
CART_MBC5_RAM EQU $1A
CART_MBC5_RAM_BATT EQU $1B
CART_MBC5_RUMBLE EQU $1C
CART_MBC5_RUMBLE_RAM EQU $1D
CART_MBC5_RUMBLE_RAM_BATT EQU $1E
CART_MBC6 EQU $20
CART_MBC7_SENSOR_RUMBLE_RAM_BATT EQU $22
CART_CAMERA EQU $FC
CART_TAMA5 EQU $FD
CART_HUC3 EQU $FE
CART_HUC1_RAM_BATT EQU $FF
ROM_32K EQU $00
ROM_64K EQU $01
ROM_128K EQU $02
ROM_256K EQU $03
ROM_512K EQU $04
ROM_1M EQU $05
ROM_1M1 EQU $52 ;1.1MB ROM
ROM_1M2 EQU $53 ;1.2MB ROM
ROM_1M5 EQU $54 ;1.5MB ROM
ROM_2M EQU $06
ROM_4M EQU $07
ROM_8M EQU $08
RAM_NONE EQU $00
RAM_2K EQU $01
RAM_8K EQU $02
RAM_32K EQU $03
RAM_64K EQU $05
RAM_128K EQU $04
NINTENDO: MACRO
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
ROM_HEADER: MACRO
NINTENDO
DB 11, $00 ;NAME (use RGBFIX to change this)
DB 4, $00 ;MANFC
DB \4 ;CGBFLG
DB $00, $00 ;LICENSECID
DB \5 ;SGBFLG
DB \1 ;CART
DB \2 ;ROM
DB \3 ;RAM
DB $00 ;DEST
DB $33 ;OLICID
DB $00 ;VERSION
DB $00 ;HCHK (use RGBFIX)
DB 2, $00 ;ROMCHECK (RGBFIX if you want it)
ENDM
;;; Boot register test values (for determining hardware)
BOOT_A_DMG EQU $01 ;DMG/SGB
BOOT_A_GBP EQU $FF ;GPB/SGB2
BOOT_A_CGB EQU $11 ;CGB/GBA
BOOT_B_GBA EQU $01 ;GBA
;;; MBC Definitions
;; MBC1
;; Write RAM_ENABLE (or anything with a low nybble A) to $0000-1FFF, for RAM
;; ROM bank number (low 5 bits) is written to $2000-3FFF
;; RAM bank number (2bits) is written to $4000-5FFF if BANK_RAM is written
;; to $6000-7FFF
;; Otherwise, write the upper two bits of the ROM Bank number to $4000-5FFF
;; Also note that banks $20, $40, and $60 are inaccessable: $21,
;; $41, and $61 will be selected instead. Likewise, trying to select
;; bank $00 will select bank $01
MBC1_RAM_ENABLE EQU $0A
MBC1_BANK_ROM EQU $00
MBC1_BANK_RAM EQU $01
;; MBC2
;; ROM bank number is 4bits, written to $2000-3FFF. 16 Banks only.
;; The LSB of the high byte of the address must be one. 21 high suggested.
;; Writes to 0000-1FFF with a high byte LSB of zero enable RAM. Use 00.
;; RAM is mapped from A000-A1FF, but only stores nybbles (low nybble)
MBC2_RAM_ENABLE EQU $0A ;I assume. Please test.
;; MBC3
;; MBC3 has an RTC. Write $0A to 0000-1FFF to enable RAM and Timer
;; Write 2000-3FFFF to switch bank. Bank 00 cannot be chosen, but all
;; 7 bits are used: it's not 5/3 like MBC1. Banks 20/40/60 are now usable.
;; Writing 00-03 to 4000 to 5FFF banks RAM at A000-BFFF. Writing an RTC
;; register number (08-0C) will map in an RTC register for read/write to
;; that space instead.
;; 6000-7FFF is write-only space. Writing 0 and then 1 will latch clock data
;; for reading. A 4ms delay is recommended between RTC register accesses.
MBC3_ENABLE_RAM_TIMER EQU $0A
MBC3_RTC_S EQU $08 ;Seconds
MBC3_RTC_M EQU $09 ;Minutes
MBC3_RTC_H EQU $0A ;Hours
MBC3_RTC_DL EQU $0B ;Day (Low byte)
MBC3_RTC_DH EQU $0C ;Day (Ninth bit + flags)
MBC3_RTC_HALT EQU $40 ;Write to DH to stop timer
MBC3_RTC_OVR EQU $80 ;Carry bit on day counter. 1=overflow
MBC3_RTC_LATCH1 EQU $00 ;Write LATCH1/LATCH2 in sequence to 60-7F
MBC3_RTC_LATCH2 EQU $01 ;to latch clock data for reading. Clock still
;ticks while latched.
;; MBC5
;; MBC5 is the only mapper guaranteed to support CGB doublespeed.
;; It's also by far the most popular for homebrew. There is no MBC4.
;; Write low 8 bits of bank to 2000-2FFF. Writing 0 actually gives Bank 0.
;; The high bit of the bank is written to 3000-3FFF.
;; Write the four bit RAM bank to A000-BFFF after writing ram enable to
;; 0000-1FFF.
MBC5_ENABLE_RAM EQU $0A
;; If you're using a HuC1, MBC6, or MBC7, you're on your own. Check pan.
;; Ditto for Bung/EMS/Wisdom Tree/MBC1M/MMM01.
;;; Memory Map
_ROM0 EQU $0000 ;Rom Bank 0
_ROMX EQU $4000 ;Rom Bank X (part of bank 0 if no MBC)
;; VRAM MAP
_VRAM EQU $8000
_TBLOCK0 EQU $8000 ;Tile Blocks
_TBLOCK1 EQU $8800
_TBLOCK2 EQU $9000
TILESIZE EQU $10 ;16 bytes, 2 bytes per line, 2bpp, 8x8
_BGW0 EQU $9800 ;BG/Window Map 0
_BGW1 EQU $9C00 ;BG/Window Map 1
_BGATTR0 EQU $9800 ;Tile attribute map (Bank 1, CGB ONLY)
_BGATTR1 EQU $9C00
BGATTR_BANK0 EQU $00 ;What bank is the tile in?
BGATTR_BANK1 EQU $08
BGATTR_HFLIP EQU $20 ;Flip tile horizontally
BGATTR_VFLIP EQU $40 ;Flip tile vertically
BGATTR_BGPRIO EQU $80 ;Unconditional BG-over-OAM priority on 1
;; RAM BANKS
_XRAM EQU $A000 ;Xternal RAM
_WRAM0 EQU $C000 ;Work RAM
_WRAMX EQU $D000 ;Work RAM *banks* (CGB only)
;; OAM
_OAM EQU $FE00 ;Ends at $FE9F
RSRESET ;struct oam_t
OAM_Y RB 1 ;Y position-16: Y=0 and Y>=160 are offscreen
OAM_X RB 1 ;X position-8: X=0 and X>=168 are offscreen
OAM_TILENO RB 1 ;In 8x16, low bit is ignored, and the 0 and 1
;are upper and lower
OAM_ATTR RB 1 ;Sprite attributes
OAM_ATTR_LOWPRIO EQU $80 ;Obj behind BG color 1-3
OAM_ATTR_VFLIP EQU $40 ;Vertical flip obj
OAM_ATTR_HFLIP EQU $20 ;Horizontal flip obj
OAM_ATTR_PAL EQU $10 ;OBPx in DMG mode
OAM_ATTR_VBANK EQU $08 ;Tile VRAM bank (CGB ONLY)
;; bits 2-0 determine OBP0-7 in CGB mode
;; IO/HRAM
_IO EQU $FF00 ;Ends at $FF7F
_HRAM EQU $FF80 ;Ends at $FFFE
;;; Registers -- Video
;; LCDC - LCD Control
LCDC EQU $FF40
LCDC_DON EQU $80 ;Display ON
LCDC_DOFF EQU $00 ;Display OFF
LCDC_WIN98 EQU $00 ;Window Tile Map = 9800
LCDC_WIN9C EQU $40 ;Window Tile Map = 9C00
LCDC_WINON EQU $20 ;Window ON
LCDC_WINOFF EQU $00 ;Window OFF
LCDC_BGT80 EQU $10 ;BG/Win Tile Data = 8000
LCDC_BGT88 EQU $00 ;BG/Win Tile Data = 9000 (signed index)
LCDC_BG98 EQU $00 ;BG Tile Map = 9800
LCDC_BG9C EQU $08 ;BG Tile Map = 9C00
LCDC_OBJ8 EQU $00 ;Objects are 8x8
LCDC_OBJ16 EQU $04 ;Objects are 8x16
LCDC_OBJOFF EQU $00 ;Objects OFF
LCDC_OBJON EQU $02 ;Objects ON
LCDC_BGON EQU $01 ;Background/Window On (DMG ONLY)
LCDC_BGPRIO EQU $01 ;Background/Window High Priority (CGB ONLY)
LCDC_BGOFF EQU $00 ;Background/Window Off (DMG ONLY)
LCDC_BGNOPRIO EQU $00 ;Background/Window Low Priority (CGB ONLY)
;; STAT - LCD STATUS
;; The EI* flags trigger an LCD STAT interrupt (INT 40h).
STAT EQU $FF41
STAT_EILYC EQU $40 ;LYC=LY Coincidence Interrupt
STAT_EIOAM EQU $20 ;Mode 2 -- OAM Search Interrupt
STAT_EIVBL EQU $10 ;Mode 1 -- VBlank Interrupt
STAT_EIHBL EQU $08 ;Mode 0 -- HBlank Interrupt
STAT_LYC EQU $04 ;LYC=LY Coincidence Flag
STAT_HBL EQU $00 ;HBlank Flag (or rather lack of flag)
STAT_VBL EQU $01 ;VBlank Flag
STAT_OAM EQU $02 ;OAM Search Flag
STAT_LCDTF EQU $03 ;LCD Transfer "Flag" (Here There Be Dragons)
;; Position/Scroll registers
SCY EQU $FF42 ;Vertical scroll
SCX EQU $FF43 ;Horizontal scroll
LY EQU $FF44 ;Current Line: 0-143 Display 144-153==vbk
LYC EQU $FF45 ;LY Compare. See interrupts
WY EQU $FF4A ;Window Y Position
WX EQU $FF4B ;Window X - 7. WX=0 triggers weirdness
;; VRAM Banks
VBK EQU $FF4F ;Bit 0 controls which bank of VRAM is loaded.
;; DMG Palettes
BGP EQU $FF47 ;Four colors, 2bpp.
OBP0 EQU $FF48 ;Same thing, but colors: Color 0 is transparent.
OBP1 EQU $FF49 ;See above
;; CGB Palettes
BPGI EQU $FF68 ;00-3F, index into GBC BG Palette. 2 bytes per
;color, 8 bytes per palette. 7 Palettes.
BPGI_AI EQU $80 ;Auto-increment BGP address?
BGPD EQU $FF69 ;BG Palette Data: Index chosen by BGPI.
;Colors are 16 bits, with 5 bits per color.
OBPI EQU $FF6A ;Obj Palette data:
OBPI_AI EQU $80 ;See above, save that color 0 is transparent.
OBPD EQU $FF6B
;; OAM DMA
ODMA EQU $FF46 ;Copy routine into HRAM and write start address
;from there or else. DMA00-DMA9F is copied into
;OAM on write, takes 160 cycles.
;; CGB VRAM DMA (HDMA)
HDMASRC_H EQU $FF51 ;Source for DMA. Must be ROM/SRAM/WRAM.
HDMASRC_L EQU $FF51 ;Last four bits ignored: 16-byte aligned
HDMADEST_H EQU $FF53 ;DMA dest=8000+VDMADEST. Only bits 12-4
HDMADEST_L EQU $FF54 ;are respected: once again, 16-byte aligned.
HDMACTRL EQU $FF55 ;Write starts HDMA.
;DMA Size = ((HDMA_CTRL & $7F)<<4)+1
HDMACTRL_GPDMA EQU $00 ;Flag for GPDMA: All data is transferred
;immediately, irrespective of current LCD state
;program is halted during transfer.
;HDMA_CTRL will be $FF when control is returned.
HDMACRTL_HDMA EQU $80 ;H-Blank DMA: 10h bytes are transferred each
;H-blank. No data is transferred during V-Blank.
;Execution is halted during transfer.
;Reading HDMA_CTRL returns the remaining length.
;$FF signals transfer completion.
;A write of 0 to bit 7 of HDMA_CTRL will
;terminate transfer.
;Transfer must not start during Hblank.
;Transfer is 8 cycles/16 bytes,
;or 16 per 16 bytes in CGB fast mode
HDMACTRL_INACTIVE EQU $80 ;Test this bit to see if transfer is occuring.
;;; Registers -- Sound
;; Duty and freq flag values are constant across all audio registers
;; that use them
PDUTY125 EQU $00 ;12.5% Duty cycle
PDUTY25 EQU $40 ;25% Duty cycle
PDUTY50 EQU $80 ;50% Duty Cycle
PDUTY75 EQU $C0 ;75% Duty Cycle
FREQ_INIT EQU $80 ;Write high to restart sound. Write only
FREQ_CNT EQU $40 ;Stop when length in LEN expires
;; P0--First pulse
P0SWEEP EQ $FF10 ;Pulse 0 Sweep: 6-4=time in n/128Hz,
;Bits 2-0: sweep number
P0SWEEP_NEG EQU $08 ;Drop freq in sweep. otherwise freq increases
P0LEN EQU $FF11 ;7-6 = Duty cycle, 5-0 = length
P0VOL EQU $FF12 ;7-4: initial volume. 3: direction (0 decrease).
;2-0 number of sweep
P0FREQ_L EQU $FF13 ;Freq is 11 bits. Low bits read only
P0FREQ_H EQU $FF14 ;High 3 bits and sound control registers
;; P1--Second pulse
P1LEN EQU $FF16 ;Same as P0LEN, duty control also available.
P1VOL EQU $FF17 ;Some as P0VOL
P1FREQ_L EQU $FF18 ;Same again
P1FREQ_H EQU $FF19
;; WAV -- Wave output
WAVENABLE EQU $FF1A ;Sound on or off?
WAVENABLE_ON EQU $80
WAVENABLE_OFF EQU $00
WAVLEN EQU $FF1B ;No duty: Full 0-255 range
WAVLEVEL EQU $FF1C ;Output volume. This is a weird one.
WAVLEVEL_0 EQU $00 ;0% volume
WAVLEVEL_100 EQU $20 ;100% volume
WAVLEVEL_50 EQU $40 ;50% volume
WAVLEVEL_25 EQU $60 ;25% volume
WAVFREQ_L EQU $FF1D
WAVFREQ_H EQU $FF1E ;Same as with P0
WAVPATTERN EQU $FF30 ;16 bytes, 32 4-bit samples.
;Disable WAV with WAVENABLE before writing.
;; NOI -- Noise channel
NOILEN EQU $FF20 ;Only 5 bits, but no duty
NOIVOL EQU $FF21 ;Works like the pulse volume registers
NOIPC EQU $FF22 ;The NOIse Polynomial Counter.
;Bit 3 (step/width) makes the noise more regular
;bits 7-4 (freq) make it softer.
;Bits 2-0 are the dividing ratio, which
;alters the freq more dramatically than 7-4
NOICC EQU $FF23 ;Noise Counter/Consecutive: Freq flags go here.
;; SND -- Sound Control
SNDCC EQU $FF24 ;Channel Control: 6-4 left volume, 2-0 right
SNDCC_VINL EQU $80 ;Output sound from cartridge (VIN) to L/R
SNDCC_VINR EQU $08
SNDSEL EQU $FF25 ;Select output terminal (panning) for channel
SNDSEL_NOIL $80 ;Noise Left Bit
SNDSEL_NOIR $08 ;Noise Right Bit
SNDSEL_WAVL $40 ;Wave Left Bit (NOTE: Wave should be disabled)
SNDSEL_WAVR $04 ;Wave Right Bit(before update on GBA: it spikes)
SNDSEL_P1L $20 ;Pulse 1 Left Bit
SNDSEL_P1R $02 ;Pulse 1 Right Bit
SNDSEL_P0L $10 ;Pulse 0 Left Bit
SNDSEL_P0R $01 ;Pulse 0 Right Bit
SNDENABL EQU $FF26 ;Toggle Sound on/off. The low bits provide
SNDENABL_YES EQU $80 ;information about the status of audio.
SNDENABL_NO EQU $00
SNDENABL_NOIP EQU $08 ;Noise channel on?
SNDENABL_WAVP EQU $04 ;Wave on?
SNDENABL_P1P EQU $02 ;Pulse 1 on?
SNDENABL_P0P EQU $01 ;Pulse 0 on?
;;; Registers -- Joy
JOYP EQU $FF00 ;You must write 0 to 5 or 4 to select button/dir
JOYP_BTN EQU $10 ;Write 0 to 5, 1 to 4
JOYP_DIR EQU $20 ;Write 1 to 5, 0 to 4
JOYP_BTN_A EQU $01 ;Bit is high if button is low. Either take the
JOYP_BTN_B EQU $02 ;CPL (dumb) or JP Z on the AND/BIT
JOYP_BTN_SEL EQU $04
JOYP_BTN_START EQU $08
JOYP_DIR_R EQU $01
JOYP_DIR_L EQU $02
JOYP_DIR_U EQU $04
JOYP_DIR_D EQU $08
;; What follows is defintions for SGB Joypad Line (ab)use
JOYP_SGB_RESET EQU $00
JOYP_SGB_ZERO EQU $20 ;4=LOW (maintain for 5us)
JOYP_SGB_ONE EQU $10 ;5=LOW
JOYP_SGB_HIGH EQU $30 ;Must bring high for 15us between pulses
;; Packet strucutre
;; RESET
;; BYTE COMMAND<<3+Len (in packets, 1-7)
;; 15 BYTE data
;; STOP BIT (0)
;; (Following packets, if any)
;; RESET
;; 16 BYTE data
;; STOP BIT (0)
;; 4 frames must be placed between each packet transfer
;; Bytes are little endian bit order
;; 4K blocks can be sent through VRAM using the TRN commands.
;; Prepare data before sending TRN, put data in $8000-$8FFF. BG map must
;; show unsigned chars 0-FFh on screen, display must be on, not scrolled, no
;; OBJ sprites overlapping background tiles, and BGP must be set to $E4
;; Transfer lasts five frames AFTER the command has been sent. Displayed
;; data must not be modified during this period.
;; SGB Command Codes: See pandoc for usage. I'm not writing all that.
;; Palette Commands
JOYP_SGBCC_PAL01 EQU $00 ;Set SGB Palette commands: PALXY sets
JOYP_SGBCC_PAL23 EQU $01
JOYP_SGBCC_PAL03 EQU $02
JOYP_SGBCC_PAL12 EQU $02
JOYP_SGBCC_PAL_SET EQU $0A ;Set palettes 0-4 to saved palettes
JOYP_SGBCC_PAL_TRN EQU $0B ;Define 512 saved palettes using VRAM transfer
;; Attr Commands
JOYP_SGBCC_ATTR_BLK EQU $04 ;Spec color attrs in rectangular area
JOYP_SGBCC_ATTR_LIN EQU $05 ;Specify attrs for character lines
JOYP_SGBCC_ATTR_DIV EQU $06 ;Split the screen, spec attrs for halves/line
JOYP_SGBCC_ATTR_CHR EQU $07 ;Spec attr for specific char
JOYP_SGBCC_ATTR_TRN EQU $15 ;VRAM transfer ATFs
JOYP_SGBCC_ATTR_SET EQU $16 ;select ATF
;; Sound Commands
JOYP_SGBCC_SND EQU $08 ;Start/stop internal sound effect (SOUND in pan)
JOYP_SGBCC_SND_TRN EQU $09 ;VRAM transfer to APU (SOU_TRN in pan)
;; System Control (misc)
JOYP_SGBCC_MASK_EN EQU $17 ;mask the window (useful for vram transfer)
JOYP_SGBCC_ATRC_EN EQU $0C ;Enable/disable Attraction Mode
JOYP_SGBCC_TEST_EN EQU $0D ;Enable varclock test mode
JOYP_SGBCC_ICON_EN EQU $0E ;Enable/disable ICON
JOYP_SGBCC_DATA_SND EQU $0F ;Write bytes directly to SNES work RAM
JOYP_SGBCC_DATA_TRN EQU $10 ;VRAM transfer data to SNES RAM
JOYP_SGBCC_JUMP EQU $12 ;Set SNES PC/NMI (VBL Int) to specific address.
;; Multiplayer
JOYP_SGBCC_MLT_REQ EQU $11 ;Request MP mode
JOYP_PAD1 EQU $0F ;In MP mode, set JOYP_BTN/JOYP_DIR to high
JOYP_PAD2 EQU $0E ;Low bits of JOYP now contain JOYP_PADX
JOYP_PAD3 EQU $0D ;YOu can read state normally.
JOYP_PAD4 EQU $0C ;Bringing BTN/DIR high again increments joypad
;; Boarder/Obj commands
JOYP_SGBCC_CHR_TRN EQU $13 ;Transfer tile data to SNES
JOYP_SGBCC_PCT_TRN EQU $14 ;Transfer tile map/palette data to SNES
JOYP_SGBCC_OBJ_TRN EQU $18 ;Trasfer OAM (every frame from lowest tile line)
;;; Registers -- Serial
SB EQU $FF01 ;Transfer shift register. Your standard SPI.
SC EQU $FF02 ;Serial Transfer Control
SC_TRQ EQU $80 ;Transfer ReQuest flag.
;Cleared when transfer ends.
SC_HICLK EQU $02 ;Enable CGB fast transfer
SC_MASTER EQU $01 ;If this is not set, the Gameboy is in
;external clock (slave) mode.
;; Transfer is triggered by master, and will occur regardless of if slave
;; sets TRQ. If you're doing bidirectional transfer, take this into account
;; delay setting TRQ on the master so the slave has time to reload.
;; TRQ is always cleared at the end of transfer, and serial interrupt is
;; called on both master and slave.
;; Serial transfer never times out. One bit per month is totally acceptable
;; to the gameboy. Write a timeout if you want one.
;; Even the DMG will acepts clocks up to 500KHz if you're using an external
;; clock.
;;; Registers -- Timer
DIV EQU $FF04 ;Incremented at ~16KHz (~32KHz in CGB2x).
;All writes reset to zero.
TIMA EQU $FF05 ;Timer increments at speed set by TAC.
;Resets to TMA value on overflow, fires int.
TMA EQU $FF06 ;Reloads TIMA on overflow
TAC EQU $FF07 ;Timer Control
TAC_ENABLE $04 ;Bit set to enable timer
TAC_SPEED4K $00 ;Set timer to 4.096KHz
TAC_SPEED262K $01 ;Set timer to 262.144KHz
TAC_SPEED65K $02 ;Set timer to 65.536KHz
TAC_SPEED16K $03 ;Set timer to 16.384KHz
;; NOTE: Timer speeds double in CGB 2x mode.
;;; Registers -- Misc. CGB Special
PSS EQU $FF4D ;Prepare Speed Swich: Swap between 1x and 2x.
PSS_SLO EQU $00 ;We're currently at normal speed
PSS_FAST EQU $80 ;We're at CGB2X
PSS_REQ EQU $01 ;Write to request speed switch.
;Bit 0 will be reset after speed is switched.
;; Timer/Div, Serial port, CPU, and OAM DMA are all doubled in speed in
;; CGB2x. LCD controller, HDMA, and sound remain the same.
;; Switching speeds causes the display to flicker.
RP EQU $FF56 ;IR Port
RP_LEDON EQU $01 ;LED ON
RP_LEDOFF EQU $00 ;Disable LED
RP_DREN EQU $C0 ;Data Read Enable: Don't write while reading!
RP_SIG EQU $C0 ;Receiving IR pulse (Read bits included)
RP_NOSIG EQU $C2 ;Not reciving IR pulse
RP_OFF EQU $00 ;Stop reading/writing.
WBK EQU $FF70 ;(Pan calls it SVBK) RAM Bank 1-7 select
;;; Registers -- Undocumented
;;; Registers -- Interrupt Control
IE EQU $FFFF ;Interrupt Enable: set bits to enable interrupts
IE_VBL EQU $01 ;VBlank Interrupt (40h)
IE_STAT EQU $02 ;LCD STAT programmable interrupt (48h)
IE_TIM EQU $04 ;Timer Interrupt (50h)
IE_SERIAL EQU $08 ;Serial Transfer Complete (58h)
IE_JOY EQU $10 ;Joypad Interrupt (60h)
IF EQU FF0F ;Interrupt Flag: Signal IRQ.
;Can be written to to manually request/discard
;interrupt. Interrupt will only be raised if
;IME/IE permits.
IF_VBL EQU $01
IF_STAT EQU $02
IF_TIM EQU $04
IF_SERIAL EQU $08
IF_JOY EQU $10
ENDC ;HW.INC ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment