gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 0396889861b38456558a67deca5faab0cfc153e0 parent 7537c2cf15458483693fcd888311fa04d7af8f5a Author: bbbbbr <reg+github@roughhousing.com> Date: Thu, 16 Sep 2021 01:02:11 -0700 Merge pull request #262 from bbbbbr/docs_4_0_5 Docs: updates for 4.0.5 Diffstat:
| M | docs/pages/02_links_and_tools.md | 8 | ++++++++ |
| M | docs/pages/05_banking_mbcs.md | 4 | ++-- |
| M | docs/pages/06b_supported_consoles.md | 102 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- |
| M | gbdk-lib/include/gb/gb.h | 12 | ++++++++++++ |
| M | gbdk-lib/include/gb/hardware.h | 114 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
| M | gbdk-lib/include/sms/sms.h | 22 | ++++++++++++++++++++++ |
6 files changed, 191 insertions(+), 71 deletions(-)
diff --git a/docs/pages/02_links_and_tools.md b/docs/pages/02_links_and_tools.md @@ -32,6 +32,14 @@ This is a brief list of useful tools and information. It is not meant to be comp https://gbdev.io/list.html +@anchor links_sms_gg_docs +# Sega Master System / Game Gear Documentation + - @anchor smspower + __SMS Power!__ + Community site with technical documentation, reviews and other content related to the Sega 8-bit systems. + https://www.smspower.org/ + + @anchor links_gbdk_tutorials # Tutorials - @anchor tutorials_gamingmonsters diff --git a/docs/pages/05_banking_mbcs.md b/docs/pages/05_banking_mbcs.md @@ -90,10 +90,10 @@ The bank number for a banked function, variable or source file can be stored and @anchor banked_keywords ### BANKED/NONBANKED keywords -- @ref BANKED: +- `BANKED`: - The function will use banked sdcc calls - Placed in the bank selected by it's source file (or compiler switches) -- @ref NONBANKED: +- `NONBANKED`: - Placed in the non-banked lower 16K region (bank 0), regardless of the bank selected by it's source file. - `<not-specified>`: - The function does not use sdcc banked calls (`near` instead of `far`) diff --git a/docs/pages/06b_supported_consoles.md b/docs/pages/06b_supported_consoles.md @@ -1,13 +1,13 @@ @page docs_supported_consoles Supported Consoles & Cross Compiling -@anchor docs_consoles_supproted_list +@anchor docs_consoles_supported_list # Consoles Supported by GBDK -As of version `4.0.5` GBDK includes support for other consoles in addition to the Game Boy. +As of version `4.0.5` GBDK includes support for other consoles in addition to the Game Boy. - - Nintendo Game Boy / Game Boy Color - - Analogue Pocket - - Sega Master System - - Sega Game Gear + - Nintendo Game Boy / Game Boy Color (GB/GBC) + - Analogue Pocket (AP) + - Sega Master System (SMS) + - Sega Game Gear (GG) While the GBDK API has many convenience functions that work the same or similar across different consoles, it's important to keep their different capabilities in mind when writing code intended to run on more than one. Some (but not all) of the differences are screen sizes, color abilities, memory layouts, processor type (z80 vs gbz80/sm83) and speed. @@ -95,15 +95,93 @@ GBDK includes an number of cross platform example projects. These projects show They also show how to build for multiple target consoles with a single build command and `Makefile`. The `Makefile.targets` allows selecting different `port` and `plat` settings when calling the build stages. -# Porting from the Game Boy to the Analogue Pocket -The Analogue Pocket is (for practical purposes) functionally identical to the Game Boy / Color, but has a couple altered register flag and address definitions and a different boot logo. In order for software to be ported to the Analogue Pocket, or to run on both, the following practices should be used. - -## Boot logo -As long as the target console is @ref docs_consoles_compiling "set during build time" then the correct boot logo will be automatically selected. +# Porting From Game Boy to Analogue Pocket +The Analogue Pocket is (for practical purposes) functionally identical to the Game Boy / Color, but has a couple altered register flag and address definitions and a different boot logo. In order for software to be easily ported to the Analogue Pocket, or to run on both, use the following practices. ## Registers and Flags -Change these hardwired registers and register flags to use API defined ones. +Use API defined registers and register flags instead of hardwired ones - LCDC register: @ref LCDC_REG or @ref rLCDC - STAT register: @ref STAT_REG or @ref rSTAT - LCDC flags: -> LCDCF_... (example: @ref LCDCF_ON) - STAT flags: -> STATF_... (example: @ref STATF_LYC) + +## Boot logo +As long as the target console is @ref docs_consoles_compiling "set during build time" then the correct boot logo will be automatically selected. + + +# Porting From Game Boy to SMS/GG + +## Tile Data and Tile Map loading + +### Tile and Map Data in 2bpp Game Boy Format +- @ref set_bkg_data() and @ref set_sprite_data() will load 2bpp tile data in "game boy" format on both GB and SMS/GG. +- On the SMS/GG @ref set_2bpp_palette() sets 4 colors that will be used when loading 2bpp assets with set_bkg_data(). This allows GB assets to be easily colorized without changing the asset format. There is some performance penalty for using the conversion. +- @ref set_bkg_tiles() loads 1-byte-per-tile tilemaps both for the GB and SMS/GG + +### Tile and Map Data in Native Format +Use the following api calls when assets are avaialble in the native format for each platform. + +@ref set_native_tile_data() + - GB/AP: loads 2bpp tiles data + - SMS/GG: loads 4bpp tile data + +@ref set_tile_map() + - GB/AP: loads 1-byte-per-tile tilemaps + - SMS/GG: loads 2-byte-per-tile tilemaps + +### Emulated Game Boy Color map attributes on the SMS/Game Gear +On the Game Boy Color, @ref VBK_REG is used to select between the regular background tile map and the background attribute tile map (for setting tile color palette and other properties). + +This behavior is emulated for the SMS/GG when using @ref set_bkg_tiles() and @ref VBK_REG. It allows writing a 1-byte tile map separately from a 1-byte attributes map. + +@note Tile map attributes on SMS/Game Gear use different control bits than the Game Boy Color, so a modified attribute map must be used. + +# Hardware Comparison +The specs below reflect the typical configuration of hardware when used with GBDK and is not meant as a complete list of their capabilities. + +GB/AP +- Sprites: + - 256 tiles (upper 128 are shared with background) (amount is doubled in CGB mode) + - tile flipping/mirroring: yes + - 10 per line + - 2 x 4 color palette (color 0 transparent). 8 x 4 color palettes in CGB mode +- Background: 256 tiles (typical setup: upper 128 are shared with sprites) (amount is doubled in CGB mode) + - tile flipping/mirroring: no (yes in CGB mode) + - 1 x 4 color palette. 8 x 4 color palettes in CGB mode +- Window "layer": available +- Screen: 160 x 144 +- Hardware Map: 256 x 256 + + +SMS/GG +- Sprites: + - 256 tiles (a bit less in the default setup) + - tile flipping/mirroring: no + - 8 per line + - 1 x 16 color palette (color 0 transparent) +- Background: 512 tiles (upper 256 are shared with sprites) + - tile flipping/mirroring: yes + - 2 x 16 color palettes +- Window "layer": not available +- SMS + - Screen: 256 x 192 + - Hardware Map: 256 x 224 +- GG + - Screen: 160 x 144 + - Hardware Map: 256 x 224 + + +@anchor docs_consoles_safe_display_controller_access +## Safe VRAM / Display Controller Access + +GB/AP +- VRAM / Display Controller (PPU) + - VRAM and some other display data / registers should only be written to when the @ref STATF_B_BUSY bit of @ref STAT_REG is off. Most GBDK API calls manage this automatically. + +SMS/GG +- Display Controller (VDP) + - Writing to the VDP should not be interrupted while an operation is already in progress (since that will interfere with the internal data pointer causing data to be written to the wrong location). + - Recommended approach: Avoid writing to the VDP (tiles, map, scrolling, colors, etc) during an interrupt routine (ISR). + - Alternative, not recommended: Make sure writes to the VDP during an ISR are only performed when the @ref _shadow_OAM_OFF flag indicates it is safe to do so. + + diff --git a/gbdk-lib/include/gb/gb.h b/gbdk-lib/include/gb/gb.h @@ -1525,6 +1525,18 @@ void get_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t *vram_addr, u /** Sets VRAM Tile Pattern data in the native format + + @param first_tile Index of the first tile to write (0 - 511) + @param nb_tiles Number of tiles to write + @param data Pointer to source Tile Pattern data. + + When `first_tile` is larger than 256 on the GB/AP, it + will write to sprite data instead of background data. + + The bit depth of the source Tile Pattern data depends + on which console is being used: + \li Game Boy/Analogue Pocket: loads 2bpp tiles data + \li SMS/GG: loads 4bpp tile data */ inline void set_native_tile_data(uint16_t first_tile, uint8_t nb_tiles, const uint8_t *data) { if (first_tile < 256) { diff --git a/gbdk-lib/include/gb/hardware.h b/gbdk-lib/include/gb/hardware.h @@ -38,7 +38,7 @@ __BYTE_REG rRAMB; /** IO Registers */ -__REG P1_REG; /** Joystick: 1.1.P15.P14.P13.P12.P11.P10 */ +__REG P1_REG; /**< Joystick: 1.1.P15.P14.P13.P12.P11.P10 */ #define rP1 P1_REG #define P1F_5 0b00100000 @@ -52,17 +52,17 @@ __REG P1_REG; /** Joystick: 1.1.P15.P14.P13.P12.P11.P10 */ #define P1F_GET_BTN P1F_4 #define P1F_GET_NONE (P1F_4 | P1F_5) -__REG SB_REG; /** Serial IO data buffer */ +__REG SB_REG; /**< Serial IO data buffer */ #define rSB SB_REG -__REG SC_REG; /** Serial IO control register */ +__REG SC_REG; /**< Serial IO control register */ #define rSC SC_REG -__REG DIV_REG; /** Divider register */ +__REG DIV_REG; /**< Divider register */ #define rDIV DIV_REG -__REG TIMA_REG; /** Timer counter */ +__REG TIMA_REG; /**< Timer counter */ #define rTIMA TIMA_REG -__REG TMA_REG; /** Timer modulo */ +__REG TMA_REG; /**< Timer modulo */ #define rTMA TMA_REG -__REG TAC_REG; /** Timer control */ +__REG TAC_REG; /**< Timer control */ #define rTAC TAC_REG #define TACF_START 0b00000100 @@ -72,56 +72,56 @@ __REG TAC_REG; /** Timer control */ #define TACF_65KHZ 0b00000010 #define TACF_262KHZ 0b00000001 -__REG IF_REG; /** Interrupt flags: 0.0.0.JOY.SIO.TIM.LCD.VBL */ +__REG IF_REG; /**< Interrupt flags: 0.0.0.JOY.SIO.TIM.LCD.VBL */ #define rIF IF_REG -__REG NR10_REG; /** Sound Channel 1 Sweep */ +__REG NR10_REG; /**< Sound Channel 1 Sweep */ #define rAUD1SWEEP NR10_REG #define AUD1SWEEP_UP 0b00000000 #define AUD1SWEEP_DOWN 0b00001000 #define AUD1SWEEP_TIME(x) ((x) << 4) #define AUD1SWEEP_LENGTH(x) (x) -__REG NR11_REG; /** Sound Channel 1 Sound length/Wave pattern duty */ +__REG NR11_REG; /**< Sound Channel 1 Sound length/Wave pattern duty */ #define rAUD1LEN NR11_REG -__REG NR12_REG; /** Sound Channel 1 Volume Envelope */ +__REG NR12_REG; /**< Sound Channel 1 Volume Envelope */ #define rAUD1ENV NR12_REG -__REG NR13_REG; /** Sound Channel 1 Frequency Low */ +__REG NR13_REG; /**< Sound Channel 1 Frequency Low */ #define rAUD1LOW NR13_REG -__REG NR14_REG; /** Sound Channel 1 Frequency High */ +__REG NR14_REG; /**< Sound Channel 1 Frequency High */ #define rAUD1HIGH NR14_REG -__REG NR21_REG; /** Sound Channel 2 Tone */ +__REG NR21_REG; /**< Sound Channel 2 Tone */ #define rAUD2LEN NR21_REG -__REG NR22_REG; /** Sound Channel 2 Volume Envelope */ +__REG NR22_REG; /**< Sound Channel 2 Volume Envelope */ #define rAUD2ENV NR22_REG -__REG NR23_REG; /** Sound Channel 2 Frequency data Low */ +__REG NR23_REG; /**< Sound Channel 2 Frequency data Low */ #define rAUD2LOW NR23_REG -__REG NR24_REG; /** Sound Channel 2 Frequency data High */ +__REG NR24_REG; /**< Sound Channel 2 Frequency data High */ #define rAUD2HIGH NR24_REG -__REG NR30_REG; /** Sound Channel 3 Sound on/off */ +__REG NR30_REG; /**< Sound Channel 3 Sound on/off */ #define rAUD3ENA NR30_REG -__REG NR31_REG; /** Sound Channel 3 Sound Length */ +__REG NR31_REG; /**< Sound Channel 3 Sound Length */ #define rAUD3LEN NR31_REG -__REG NR32_REG; /** Sound Channel 3 Select output level */ +__REG NR32_REG; /**< Sound Channel 3 Select output level */ #define rAUD3LEVEL NR32_REG -__REG NR33_REG; /** Sound Channel 3 Frequency data Low */ +__REG NR33_REG; /**< Sound Channel 3 Frequency data Low */ #define rAUD3LOW NR33_REG -__REG NR34_REG; /** Sound Channel 3 Frequency data High */ +__REG NR34_REG; /**< Sound Channel 3 Frequency data High */ #define rAUD3HIGH NR34_REG -__REG NR41_REG; /** Sound Channel 4 Sound Length */ +__REG NR41_REG; /**< Sound Channel 4 Sound Length */ #define rAUD4LEN NR41_REG -__REG NR42_REG; /** Sound Channel 4 Volume Envelope */ +__REG NR42_REG; /**< Sound Channel 4 Volume Envelope */ #define rAUD4ENV NR42_REG -__REG NR43_REG; /** Sound Channel 4 Polynomial Counter */ +__REG NR43_REG; /**< Sound Channel 4 Polynomial Counter */ #define rAUD4POLY NR43_REG #define AUD4POLY_WIDTH_15BIT 0x00 #define AUD4POLY_WIDTH_7BIT 0x08 -__REG NR44_REG; /** Sound Channel 4 Counter / Consecutive and Inital */ +__REG NR44_REG; /**< Sound Channel 4 Counter / Consecutive and Inital */ #define rAUD4GO NR44_REG -__REG NR50_REG; /** Sound Channel control / ON-OFF / Volume */ +__REG NR50_REG; /**< Sound Channel control / ON-OFF / Volume */ #define rAUDVOL NR50_REG #define AUDVOL_VOL_LEFT(x) ((x) << 4) @@ -129,7 +129,7 @@ __REG NR50_REG; /** Sound Channel control / ON-OFF / Volume */ #define AUDVOL_VIN_LEFT 0b10000000 #define AUDVOL_VIN_RIGHT 0b00001000 -__REG NR51_REG; /** Sound Selection of Sound output terminal */ +__REG NR51_REG; /**< Sound Selection of Sound output terminal */ #define rAUDTERM NR51_REG #define AUDTERM_4_LEFT 0b10000000 @@ -141,7 +141,7 @@ __REG NR51_REG; /** Sound Selection of Sound output terminal */ #define AUDTERM_2_RIGHT 0b00000010 #define AUDTERM_1_RIGHT 0b00000001 -__REG NR52_REG; /** Sound Master on/off */ +__REG NR52_REG; /**< Sound Master on/off */ #define rAUDENA NR52_REG #define AUDENA_ON 0b10000000 @@ -149,7 +149,7 @@ __REG NR52_REG; /** Sound Master on/off */ __BYTE_REG AUD3WAVE[16]; -__REG LCDC_REG; /** LCD control */ +__REG LCDC_REG; /**< LCD control */ #define rLCDC LCDC_REG #ifdef __TARGET_ap @@ -204,7 +204,7 @@ __REG LCDC_REG; /** LCD control */ #define LCDCF_B_BGON 0 /**< Bit for Background Display Visible/Hidden Select */ #endif -__REG STAT_REG; /** LCD status */ +__REG STAT_REG; /**< LCD status */ #define rSTAT STAT_REG #ifdef __TARGET_ap @@ -247,44 +247,44 @@ __REG STAT_REG; /** LCD status */ #define STATF_B_BUSY 1 /**< Bit for when VRAM access is unsafe */ #endif -__REG SCY_REG; /** Scroll Y */ +__REG SCY_REG; /**< Scroll Y */ #define rSCY -__REG SCX_REG; /** Scroll X */ +__REG SCX_REG; /**< Scroll X */ #define rSCX SCX_REG -__REG LY_REG; /** LCDC Y-coordinate */ +__REG LY_REG; /**< LCDC Y-coordinate */ #define rLY LY_REG -__REG LYC_REG; /** LY compare */ +__REG LYC_REG; /**< LY compare */ #define rLYC LYC_REG -__REG DMA_REG; /** DMA transfer */ +__REG DMA_REG; /**< DMA transfer */ #define rDMA DMA_REG -__REG BGP_REG; /** BG palette data */ +__REG BGP_REG; /**< BG palette data */ #define rBGP BGP_REG -__REG OBP0_REG; /** OBJ palette 0 data */ +__REG OBP0_REG; /**< OBJ palette 0 data */ #define rOBP0 OBP0_REG -__REG OBP1_REG; /** OBJ palette 1 data */ +__REG OBP1_REG; /**< OBJ palette 1 data */ #define rOBP1 OBP1_REG -__REG WY_REG; /** Window Y coordinate */ +__REG WY_REG; /**< Window Y coordinate */ #define rWY WY_REG -__REG WX_REG; /** Window X coordinate */ +__REG WX_REG; /**< Window X coordinate */ #define rWX WX_REG -__REG KEY1_REG; /** CPU speed */ +__REG KEY1_REG; /**< CPU speed */ #define rKEY1 KEY1_REG #define rSPD KEY1_REG #define KEY1F_DBLSPEED 0b10000000 #define KEY1F_PREPARE 0b00000001 -__REG VBK_REG; /** VRAM bank */ +__REG VBK_REG; /**< VRAM bank */ #define rVBK VBK_REG -__REG HDMA1_REG; /** DMA control 1 */ +__REG HDMA1_REG; /**< DMA control 1 */ #define rHDMA1 HDMA1_REG -__REG HDMA2_REG; /** DMA control 2 */ +__REG HDMA2_REG; /**< DMA control 2 */ #define rHDMA2 HDMA2_REG -__REG HDMA3_REG; /** DMA control 3 */ +__REG HDMA3_REG; /**< DMA control 3 */ #define rHDMA3 HDMA3_REG -__REG HDMA4_REG; /** DMA control 4 */ +__REG HDMA4_REG; /**< DMA control 4 */ #define rHDMA4 HDMA4_REG -__REG HDMA5_REG; /** DMA control 5 */ +__REG HDMA5_REG; /**< DMA control 5 */ #define rHDMA5 HDMA5_REG #define HDMA5F_MODE_GP 0b00000000 @@ -292,7 +292,7 @@ __REG HDMA5_REG; /** DMA control 5 */ #define HDMA5F_BUSY 0b10000000 -__REG RP_REG; /** IR port */ +__REG RP_REG; /**< IR port */ #define rRP RP_REG #define RPF_ENREAD 0b11000000 @@ -300,29 +300,29 @@ __REG RP_REG; /** IR port */ #define RPF_WRITE_HI 0b00000001 #define RPF_WRITE_LO 0b00000000 -__REG BCPS_REG; /** BG color palette specification */ +__REG BCPS_REG; /**< BG color palette specification */ #define rBCPS BCPS_REG #define BCPSF_AUTOINC 0b10000000 -__REG BCPD_REG; /** BG color palette data */ +__REG BCPD_REG; /**< BG color palette data */ #define rBCPD BCPD_REG -__REG OCPS_REG; /** OBJ color palette specification */ +__REG OCPS_REG; /**< OBJ color palette specification */ #define rOCPS OCPS_REG #define OCPSF_AUTOINC 0b10000000 -__REG OCPD_REG; /** OBJ color palette data */ +__REG OCPD_REG; /**< OBJ color palette data */ #define rOCPD OCPD_REG -__REG SVBK_REG; /** WRAM bank */ +__REG SVBK_REG; /**< WRAM bank */ #define rSVBK SVBK_REG #define rSMBK SVBK_REG -__REG PCM12_REG; /** Sound channel 1&2 PCM amplitude (R) */ +__REG PCM12_REG; /**< Sound channel 1&2 PCM amplitude (R) */ #define rPCM12 PCM12_REG -__REG PCM34_REG; /** Sound channel 3&4 PCM amplitude (R) */ +__REG PCM34_REG; /**< Sound channel 3&4 PCM amplitude (R) */ #define rPCM34 PCM34_REG -__REG IE_REG; /** Interrupt enable */ +__REG IE_REG; /**< Interrupt enable */ #define rIE IE_REG #define IEF_HILO 0b00010000 diff --git a/gbdk-lib/include/sms/sms.h b/gbdk-lib/include/sms/sms.h @@ -593,6 +593,28 @@ extern volatile uint8_t shadow_OAM[]; extern volatile uint8_t _shadow_OAM_base; /** Flag for disabling of OAM copying routine + + Values: + \li 1: OAM copy routine is disabled (non-isr VDP operation may be in progress) + \li 0: OAM copy routine is enabled + + This flag is modified by all sms/gg GBDK API calls that write to the VDP. + It is set to DISABLED when they start and ENABLED when they complete. + + @note It is recommended to avoid writing to the Video Display Processor + (VDP) during an interrupt service routine (ISR) since it can corrupt + the VDP pointer of an VDP operation already in progress. + + If it is necessary, this flag can be used during an ISR to determine + whether a VDP operation is already in progress. If the value is `1` + then avoid writing to the VDP (tiles, map, scrolling, colors, etc). + + \code{.c} + // at the beginning of and ISR that would write to the VDP + if (_shadow_OAM_OFF) return; + \endcode + + @see @ref docs_consoles_safe_display_controller_access */ extern volatile uint8_t _shadow_OAM_OFF;
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.