#ifndef GBSDK_HARDWARE_H #define GBSDK_HARDWARE_H // Register for reading joy pad info. (R/W) static volatile __sfr __at(0x00) rP1; #define P1_5 0b00100000 // P15 out port, set to 0 to get buttons #define P1_4 0b00010000 // P14 out port, set to 0 to get dpad #define P1_3 0b00001000 // P13 in port #define P1_2 0b00000100 // P12 in port #define P1_1 0b00000010 // P11 in port #define P1_0 0b00000001 // P10 in port #define P1_GET_DPAD P1_5 #define P1_GET_BTN P1_4 #define P1_GET_NONE (P1_4 | P1_5) // Serial Transfer Data (R/W) static volatile __sfr __at(0x01) rSB; // Serial I/O Control (R/W) static volatile __sfr __at(0x02) rSC; // Divider register (R/W) static volatile __sfr __at(0x04) rDIV; // Timer counter (R/W) static volatile __sfr __at(0x05) rTIMA; // Timer modulo (R/W) static volatile __sfr __at(0x06) rTMA; // Timer control (R/W) static volatile __sfr __at(0x07) rTAC; #define TAC_START 0b00000100 #define TAC_STOP 0b00000000 #define TAC_4KHZ 0b00000000 #define TAC_16KHZ 0b00000011 #define TAC_65KHZ 0b00000010 #define TAC_262KHZ 0b00000001 // Interrupt Flag (R/W) static volatile __sfr __at(0x0F) rIF; // AUD1SWEEP/NR10 ($FF10) // Sweep register (R/W) // // Bit 6-4 - Sweep Time // Bit 3 - Sweep Increase/Decrease // 0: Addition (frequency increases???) // 1: Subtraction (frequency increases???) // Bit 2-0 - Number of sweep shift (# 0-7) // Sweep Time: (n*7.8ms) static volatile __sfr __at(0x10) rNR10; #define rAUD1SWEEP rNR10 #define AUD1SWEEP_UP 0b00000000 #define AUD1SWEEP_DOWN 0b00001000 // AUD1LEN/NR11 ($FF11) // Sound length/Wave pattern duty (R/W) // // Bit 7-6 - Wave Pattern Duty (00:12.5% 01:25% 10:50% 11:75%) // Bit 5-0 - Sound length data (# 0-63) static volatile __sfr __at(0x11) rNR11; #define rAUD1LEN rNR11 // AUD1ENV/NR12 ($FF12) // Envelope (R/W) // // Bit 7-4 - Initial value of envelope // Bit 3 - Envelope UP/DOWN // 0: Decrease // 1: Range of increase // Bit 2-0 - Number of envelope sweep (# 0-7) static volatile __sfr __at(0x12) rNR12; #define rAUD1ENV rNR12 // AUD1LOW/NR13 ($FF13) // Frequency low byte (W) static volatile __sfr __at(0x13) rNR13; #define rAUD1LOW rNR13 // AUD1HIGH/NR14 ($FF14) // Frequency high byte (W) // // Bit 7 - Initial (when set, sound restarts) // Bit 6 - Counter/consecutive selection // Bit 2-0 - Frequency's higher 3 bits static volatile __sfr __at(0x14) rNR14; #define rAUD1HIGH rNR14 // AUD2LEN/NR21 ($FF16) // Sound Length; Wave Pattern Duty (R/W) // // see AUD1LEN for info static volatile __sfr __at(0x16) rNR21; #define rAUD2LEN rNR21 // AUD2ENV/NR22 ($FF17) // Envelope (R/W) // // see AUD1ENV for info static volatile __sfr __at(0x17) rNR22; #define rAUD2ENV rNR22 // AUD2LOW/NR23 ($FF18) // Frequency low byte (W) static volatile __sfr __at(0x18) rNR23; #define rAUD2LOW rNR23 // AUD2HIGH/NR24 ($FF19) // Frequency high byte (W) // // see AUD1HIGH for info static volatile __sfr __at(0x19) rNR24; #define rAUD2HIGH rNR24 // AUD3ENA/NR30 ($FF1A) // Sound on/off (R/W) // // Bit 7 - Sound ON/OFF (1=ON,0=OFF) static volatile __sfr __at(0x1A) rNR30; #define rAUD3ENA rNR30 // AUD3LEN/NR31 ($FF1B) // Sound length (R/W) // // Bit 7-0 - Sound length static volatile __sfr __at(0x1B) rNR31; #define rAUD3LEN rNR31 // AUD3LEVEL/NR32 ($FF1C) // Select output level // // Bit 6-5 - Select output level // 00: 0/1 (mute) // 01: 1/1 // 10: 1/2 // 11: 1/4 static volatile __sfr __at(0x1C) rNR32; #define rAUD3LEVEL rNR32 // AUD3LOW/NR33 ($FF1D) // Frequency low byte (W) // // see AUD1LOW for info static volatile __sfr __at(0x1D) rNR33; #define rAUD3LOW rNR33 // AUD3HIGH/NR34 ($FF1E) // Frequency high byte (W) // // see AUD1HIGH for info static volatile __sfr __at(0x1E) rNR34; #define rAUD3HIGH rNR34 // AUD4LEN/NR41 ($FF20) // Sound length (R/W) // // Bit 5-0 - Sound length data (# 0-63) static volatile __sfr __at(0x20) rNR41; #define rAUD4LEN rNR41 // AUD4ENV/NR42 ($FF21) // Envelope (R/W) // // see AUD1ENV for info static volatile __sfr __at(0x21) rNR42; #define rAUD4ENV rNR42 // AUD4POLY/NR43 ($FF22) // Polynomial counter (R/W) // // Bit 7-4 - Selection of the shift clock frequency of the (scf) // polynomial counter (0000-1101) // freq=drf*1/2^scf (not sure) // Bit 3 - Selection of the polynomial counter's step // 0: 15 steps // 1: 7 steps // Bit 2-0 - Selection of the dividing ratio of frequencies (drf) // 000: f/4 001: f/8 010: f/16 011: f/24 // 100: f/32 101: f/40 110: f/48 111: f/56 (f=4.194304 Mhz) static volatile __sfr __at(0x22) rNR43; #define rAUD4POLY rNR43 // AUD4GO/NR44 ($FF23) // // Bit 7 - Inital // Bit 6 - Counter/consecutive selection static volatile __sfr __at(0x23) rNR44; #define rAUD4GO rNR44 // AUDVOL/NR50 ($FF24) // Channel control / ON-OFF / Volume (R/W) // // Bit 7 - Vin->SO2 ON/OFF (Vin??) // Bit 6-4 - SO2 output level (volume) (# 0-7) // Bit 3 - Vin->SO1 ON/OFF (Vin??) // Bit 2-0 - SO1 output level (volume) (# 0-7) static volatile __sfr __at(0x24) rNR50; #define rAUDVOL rNR50 #define AUDVOL_VIN_LEFT 0b10000000 // SO2 #define AUDVOL_VIN_RIGHT 0b00001000 // SO1 // AUDTERM/NR51 ($FF25) // Selection of Sound output terminal (R/W) // // Bit 7 - Output sound 4 to SO2 terminal // Bit 6 - Output sound 3 to SO2 terminal // Bit 5 - Output sound 2 to SO2 terminal // Bit 4 - Output sound 1 to SO2 terminal // Bit 3 - Output sound 4 to SO1 terminal // Bit 2 - Output sound 3 to SO1 terminal // Bit 1 - Output sound 2 to SO1 terminal // Bit 0 - Output sound 0 to SO1 terminal static volatile __sfr __at(0x25) rNR51; #define rAUDTERM rNR51 // SO2 #define AUDTERM_4_LEFT 0b10000000 #define AUDTERM_3_LEFT 0b01000000 #define AUDTERM_2_LEFT 0b00100000 #define AUDTERM_1_LEFT 0b00010000 // SO1 #define AUDTERM_4_RIGHT 0b00001000 #define AUDTERM_3_RIGHT 0b00000100 #define AUDTERM_2_RIGHT 0b00000010 #define AUDTERM_1_RIGHT 0b00000001 // AUDENA/NR52 ($FF26) // Sound on/off (R/W) // // Bit 7 - All sound on/off (sets all audio regs to 0!) // Bit 3 - Sound 4 ON flag (read only) // Bit 2 - Sound 3 ON flag (read only) // Bit 1 - Sound 2 ON flag (read only) // Bit 0 - Sound 1 ON flag (read only) static volatile __sfr __at(0x26) rNR52; #define rAUDENA rNR52 #define AUDENA_ON 0b10000000 #define AUDENA_OFF 0b00000000 // sets all audio regs to 0! // LCDC ($FF40) // LCD Control (R/W) static volatile __sfr __at(0x40) rLCDC; #define LCDC_OFF 0b00000000 // LCD Control Operation #define LCDC_ON 0b10000000 // LCD Control Operation #define LCDC_WIN9800 0b00000000 // Window Tile Map Display Select #define LCDC_WIN9C00 0b01000000 // Window Tile Map Display Select #define LCDC_WINOFF 0b00000000 // Window Display #define LCDC_WINON 0b00100000 // Window Display #define LCDC_BG8800 0b00000000 // BG & Window Tile Data Select #define LCDC_BG8000 0b00010000 // BG & Window Tile Data Select #define LCDC_BG9800 0b00000000 // BG Tile Map Display Select #define LCDC_BG9C00 0b00001000 // BG Tile Map Display Select #define LCDC_OBJ8 0b00000000 // OBJ Construction #define LCDC_OBJ16 0b00000100 // OBJ Construction #define LCDC_OBJOFF 0b00000000 // OBJ Display #define LCDC_OBJON 0b00000010 // OBJ Display #define LCDC_BGOFF 0b00000000 // BG Display #define LCDC_BGON 0b00000001 // BG Display // STAT ($FF41) // LCDC Status (R/W) static volatile __sfr __at(0x41) rSTAT; #define STAT_LYC 0b01000000 // LYC=LY Coincidence (Selectable) #define STAT_MODE10 0b00100000 // Mode 10 #define STAT_MODE01 0b00010000 // Mode 01 (V-Blank) #define STAT_MODE00 0b00001000 // Mode 00 (H-Blank) #define STAT_LYCF 0b00000100 // Coincidence Flag #define STAT_HBL 0b00000000 // H-Blank #define STAT_VBL 0b00000001 // V-Blank #define STAT_OAM 0b00000010 // OAM-RAM is used by system #define STAT_LCD 0b00000011 // Both OAM and VRAM used by system #define STAT_BUSY 0b00000010 // When set, VRAM access is unsafe // SCY ($FF42) // Scroll Y (R/W) static volatile __sfr __at(0x42) rSCY; // SCX ($FF43) // Scroll X (R/W) static volatile __sfr __at(0x43) rSCX; // LY ($FF44) // LCDC Y-Coordinate (R) // // Values range from 0->153. 144->153 is the VBlank period. static volatile __sfr __at(0x44) rLY; // LYC ($FF45) // LY Compare (R/W) // // When LY==LYC, STATF_LYCF will be set in STAT static volatile __sfr __at(0x45) rLYC; // DMA ($FF46) // DMA Transfer and Start Address (W) static volatile __sfr __at(0x46) rDMA; // BGP ($FF47) // BG Palette Data (W) // // Bit 7-6 - Intensity for %11 // Bit 5-4 - Intensity for %10 // Bit 3-2 - Intensity for %01 // Bit 1-0 - Intensity for %00 static volatile __sfr __at(0x47) rBGP; // OBP0 ($FF48) // Object Palette 0 Data (W) // // See BGP for info static volatile __sfr __at(0x48) rOBP0; // OBP1 ($FF49) // Object Palette 1 Data (W) // // See BGP for info static volatile __sfr __at(0x49) rOBP1; // WY ($FF4A) // Window Y Position (R/W) // // 0 <= WY <= 143 // When WY = 0, the window is displayed from the top edge of the LCD screen. static volatile __sfr __at(0x4A) rWY; // WX ($FF4B) // Window X Position (R/W) // // 7 <= WX <= 166 // When WX = 7, the window is displayed from the left edge of the LCD screen. // Values of 0-6 and 166 are unreliable due to hardware bugs. static volatile __sfr __at(0x4B) rWX; #if CGB // SPEED ($FF4D) // Select CPU Speed (R/W) static volatile __sfr __at(0x4D) rKEY1; #define rSPD rKEY1 #define KEY1_DBLSPEED 0b10000000 // 0=Normal Speed, 1=Double Speed (R) #define KEY1_PREPARE 0b00000001 // 0=No, 1=Prepare (R/W) // VBK ($FF4F) // Select Video RAM Bank (R/W) // // Bit 0 - Bank Specification (0: Specify Bank 0; 1: Specify Bank 1) static volatile __sfr __at(0x4F) rVBK; // HDMA1 ($FF51) // High byte for Horizontal Blanking/General Purpose DMA source address (W) static volatile __sfr __at(0x51) rHDMA1; // HDMA2 ($FF52) // Low byte for Horizontal Blanking/General Purpose DMA source address (W) static volatile __sfr __at(0x52) rHDMA2; // HDMA3 ($FF53) // High byte for Horizontal Blanking/General Purpose DMA destination address (W) static volatile __sfr __at(0x53) rHDMA3; // HDMA4 ($FF54) // Low byte for Horizontal Blanking/General Purpose DMA destination address (W) static volatile __sfr __at(0x54) rHDMA4; // HDMA5 ($FF55) // Transfer length (in tiles minus 1)/mode/start for Horizontal Blanking, General Purpose DMA (R/W) static volatile __sfr __at(0x55) rHDMA5; #define HDMA5_MODE_GP 0b00000000 // General Purpose DMA (W) #define HDMA5_MODE_HBL 0b10000000 // HBlank DMA (W) // Once DMA has started, use HDMA5F_BUSY to check when the transfer is complete #define HDMA5_BUSY 0b10000000 // 0=Busy (DMA still in progress), 1=Transfer complete (R) // RP ($FF56) // Infrared Communications Port (R/W) static volatile __sfr __at(0x56) rRP; #define RP_ENREAD 0b11000000 #define RP_DATAIN 0b00000010 // 0=Receiving IR Signal, 1=Normal #define RP_WRITE_HI 0b00000001 #define RP_WRITE_LO 0b00000000 // BCPS ($FF68) // Background Color Palette Specification (R/W) static volatile __sfr __at(0x68) rBCPS; #define BCPS_AUTOINC 0b10000000 // Auto Increment (0=Disabled, 1=Increment after Writing) // BCPD ($FF69) // Background Color Palette Data (R/W) static volatile __sfr __at(0x69) rBCPD; // OCPS ($FF6A) // Object Color Palette Specification (R/W) static volatile __sfr __at(0x6A) rOCPS; #define OCPS_AUTOINC 0b10000000 // Auto Increment (0=Disabled, 1=Increment after Writing) // OCPD ($FF6B) // Object Color Palette Data (R/W) static volatile __sfr __at(0x6B) rOCPD; // SMBK/SVBK ($FF70) // Select Main RAM Bank (R/W) // // Bit 2-0 - Bank Specification (0,1: Specify Bank 1; 2-7: Specify Banks 2-7) static volatile __sfr __at(0x70) rSVBK; #define rSMBK rSVBK // PCM12 ($FF76) // Sound channel 1&2 PCM amplitude (R) // // Bit 7-4 - Copy of sound channel 2's PCM amplitude // Bit 3-0 - Copy of sound channel 1's PCM amplitude static volatile __sfr __at(0x76) rPCM12; // PCM34 ($FF77) // Sound channel 3&4 PCM amplitude (R) // // Bit 7-4 - Copy of sound channel 4's PCM amplitude // Bit 3-0 - Copy of sound channel 3's PCM amplitude static volatile __sfr __at(0x77) rPCM34; #endif //CGB // IE ($FFFF) // Interrupt Enable (R/W) static volatile __sfr __at(0xFF) rIE; #define IE_HILO 0b00010000 // Transition from High to Low of Pin number P10-P13 #define IE_SERIAL 0b00001000 // Serial I/O transfer end #define IE_TIMER 0b00000100 // Timer Overflow #define IE_LCDC 0b00000010 // LCDC (see STAT) #define IE_VBLANK 0b00000001 // V-Blank /*************************************************************************** * * Flags common to multiple sound channels * ***************************************************************************/ // Square wave duty cycle // // Can be used with AUD1LEN and AUD2LEN // See AUD1LEN for more info #define AUDLEN_DUTY_12_5 0b00000000 // 12.5% #define AUDLEN_DUTY_25 0b01000000 // 25% #define AUDLEN_DUTY_50 0b10000000 // 50% #define AUDLEN_DUTY_75 0b11000000 // 75% // Audio envelope flags // // Can be used with AUD1ENV, AUD2ENV, AUD4ENV // See AUD1ENV for more info #define AUDENV_UP 0b00001000 #define AUDENV_DOWN 0b00000000 // Audio trigger flags // // Can be used with AUD1HIGH, AUD2HIGH, AUD3HIGH // See AUD1HIGH for more info #define AUDHIGH_RESTART 0b10000000 #define AUDHIGH_LENGTH_ON 0b01000000 #define AUDHIGH_LENGTH_OFF 0b00000000 // Shared bits between the OAM attributes and the CGB background attributes. #define ATTR_PRI 0b10000000 #define ATTR_YFLIP 0b01000000 #define ATTR_XFLIP 0b00100000 #define ATTR_PAL0 0b00000000 #define ATTR_PAL1 0b00010000 #if CGB #define ATTR_BANK0 0b00000000 #define ATTR_BANK1 0b00001000 #define ATTR_PALMASK 0b00000111 #endif // Defines for specific instructions #define HALT() __asm__("halt") #define DISABLE_INTERRUPTS() __asm__("di") #define ENABLE_INTERRUPTS() __asm__("ei") #endif