gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 32f8c393edff10e011d22e2febd1cc0e4e12f11c parent 9aba0004b835fb994faa4f6d5900e3e3969f0519 Author: bbbbbr <bbbbbr@users.noreply.github.com> Date: Tue, 23 Jan 2024 03:28:53 -0800 Merge pull request #616 from bbbbbr/docs/4_2_next Doc improvements Diffstat:
| M | docs/pages/02_links_and_tools.md | 31 | +++++++++++++++++++++++++++++-- |
| M | docs/pages/05_banking_mbcs.md | 8 | ++++---- |
| M | docs/pages/08_faq.md | 9 | +++++++++ |
| M | gbdk-lib/examples/gb/hblank_copy/src/main.c | 3 | ++- |
| M | gbdk-lib/examples/gb/hicolor/src/gbc_hicolor.c | 2 | +- |
| M | gbdk-lib/examples/gb/hicolor/src/main.c | 2 | +- |
| M | gbdk-lib/examples/sms/wav_sample/src/samptest.c | 6 | ++++-- |
| M | gbdk-lib/include/gb/gb.h | 38 | +++++++++++++++++++++++++++++--------- |
| M | gbdk-lib/include/gb/hardware.h | 14 | +++++++------- |
| M | gbdk-lib/include/gb/hblankcpy.h | 39 | +++++++++++++++++++++++++++++---------- |
| M | gbdk-lib/include/gb/metasprites.h | 9 | +++++++++ |
| M | gbdk-lib/include/gbdk/incbin.h | 12 | +++++++++--- |
| M | gbdk-lib/include/rand.h | 9 | ++++----- |
13 files changed, 137 insertions(+), 45 deletions(-)
diff --git a/docs/pages/02_links_and_tools.md b/docs/pages/02_links_and_tools.md @@ -1,4 +1,4 @@ -@page docs_links_and_tools Links and Third-Party Tools +@page docs_links_and_tools Links, Tools and Debugging This is a brief list of useful tools and information. It is not meant to be complete or exhaustive, for a larger list see the @ref awesome_gb "Awesome Game Boy Development" list. @@ -96,7 +96,6 @@ This is a brief list of useful tools and information. It is not meant to be comp __hUGEtracker__ and __hUGEdriver__ A tracker and music driver that work with GBDK and RGBDS. It is smaller, more efficient and more versatile than gbt_player. - https://github.com/untoxa/hUGEBuild https://github.com/SuperDisk/hUGEDriver https://github.com/SuperDisk/hUGETracker @@ -129,6 +128,34 @@ This is a brief list of useful tools and information. It is not meant to be comp Accurate emulator, has useful debugging tools. http://bgb.bircd.org/ +@anchor code_editors_hinting +Intellisense in VSCode may have trouble identifying some GBDK types or functions, and therefore flag them as warnings or unidentified. + +GBDK platform constants can be declared so that header files are parsed more completely in VSCode. The following `c_cpp_properties.json` example may be adapted for your own project. + + { + "configurations": [ + { + "name": "gameboy", + "includePath": [ + "${workspaceFolder}/src/**", + "${workspaceFolder}/res/**", + "${workspaceFolder}/include/**", + "${workspaceFolder}/../../../gbdk/include/**" + ], + "defines": ["__PORT_sm83", "__TARGET_gb"], + "compilerPath": "", + "cStandard": "c11", + "intelliSenseMode": "${default}", + "compilerArgs": [], + "browse": { + "limitSymbolsToIncludedHeaders": true + } + } + ], + "version": 4 + } + @anchor tools_debug # Debugging tools diff --git a/docs/pages/05_banking_mbcs.md b/docs/pages/05_banking_mbcs.md @@ -233,7 +233,7 @@ An example function which can : // This function is NONBANKED so it resides in fixed Bank 0 void set_banked_bkg_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data, uint8_t bank) NONBANKED { - uint8_t save = _current_bank; + uint8_t save = CURRENT_BANK; SWITCH_ROM(bank); set_bkg_data(first_tile, nb_tiles, data); SWITCH_ROM(save); @@ -245,14 +245,14 @@ set_banked_bkg_data(<first tile>, <num tiles>, tile_data, BANK(tile_data)); @anchor banking_current_bank -## Currently active bank: _current_bank -The global variable @ref _current_bank is updated automatically when calling @ref SWITCH_ROM(), @ref SWITCH_ROM_MBC1() and @ref SWITCH_ROM_MBC5, or when a `BANKED` function is called. +## Currently active bank: CURRENT_BANK +The global variable @ref CURRENT_BANK (a macro for @ref _current_bank) is updated automatically when calling @ref SWITCH_ROM(), @ref SWITCH_ROM_MBC1() and @ref SWITCH_ROM_MBC5, or when a `BANKED` function is called. Normaly banked calls are used and the active bank does not need to be directly managed, but in the case that it does the following shows how to save and restore it. ```{.c} // The current bank can be saved -uint8_t _saved_bank = _current_bank; +uint8_t _saved_bank = CURRENT_BANK; // Call some function which changes the bank but does not restore it // ... diff --git a/docs/pages/08_faq.md b/docs/pages/08_faq.md @@ -17,6 +17,10 @@ - The two main options are: - Use @ref set_bkg_based_tiles(), @ref set_bkg_based_submap(), @ref set_win_based_tiles(), @ref set_win_based_submap() and provide a tile origin offset. - Use @ref utility_png2asset with `-tile_origin` to create a map with the tile index offsets built in. + + - Is it normal for sprites to disappear when they reach the left border of the screen? (NES/SMS/MSX) + - You can hide the leftmost column using @ref HIDE_LEFT_COLUMN to work around this. + - The behavior is due to NES/SMS/MSX having 8-bit Sprite x coordinates while the screen width is also 256 pixels. GB/GG don't have this problem since their screen is smaller and the x-coordinates are larger than the visible screen. <!-- --> # ROM Header Settings @@ -34,6 +38,11 @@ - How do I set the ROM @ref MBC type, and what MBC values are available to use with the `-yt` @ref makebin flag? - See @ref setting_mbc_and_rom_ram_banks <!-- --> +# Editors + - Why is VSCode flagging some GBDK types or functions as unidentified or giving warnings about them? + - See @ref code_editors_hinting + - GBDK platform constants can be declared so that header files are parsed more completely in VSCode. + # Errors and Warnings @anchor faq_gbz80_sm83_old_port_name_error - What does the error `old "gbz80" SDCC PORT name specified (in "-mgbz80:gb"). Use "sm83" instead. You must update your build settings.` mean? diff --git a/gbdk-lib/examples/gb/hblank_copy/src/main.c b/gbdk-lib/examples/gb/hblank_copy/src/main.c @@ -14,8 +14,9 @@ const frame_desc_t * current_frame = frames; // pointer to the current an void LCD_ISR(void) { static bool odd_even_frame = false; - uint8_t _save = _current_bank; + uint8_t _save = CURRENT_BANK; SWITCH_ROM(current_frame->bank); + if (odd_even_frame = !odd_even_frame) { LCDC_REG &= ~LCDCF_BG8000; hblank_copy_destination = _VRAM8000; diff --git a/gbdk-lib/examples/gb/hicolor/src/gbc_hicolor.c b/gbdk-lib/examples/gb/hicolor/src/gbc_hicolor.c @@ -131,7 +131,7 @@ void hicolor_start(const hicolor_data * p_hicolor, uint8_t hicolor_bank) NONBANK if (!p_hicolor) return; hicolor_palettes_bank = hicolor_bank; - uint8_t bank_save = _current_bank; + uint8_t bank_save = CURRENT_BANK; if (hicolor_bank) SWITCH_ROM(hicolor_bank); // Copy address of palette into local var used by HiColor ISR diff --git a/gbdk-lib/examples/gb/hicolor/src/main.c b/gbdk-lib/examples/gb/hicolor/src/main.c @@ -63,7 +63,7 @@ void main(void) { hicolor_bank = hicolors[img_select].bank; p_hicolor = (const hicolor_data *)hicolors[img_select].ptr; - uint8_t bank_save = _current_bank; + uint8_t bank_save = CURRENT_BANK; if (hicolor_bank) SWITCH_ROM(hicolor_bank); // Reset Y scroll and set scroll range based on converted image height diff --git a/gbdk-lib/examples/sms/wav_sample/src/samptest.c b/gbdk-lib/examples/sms/wav_sample/src/samptest.c @@ -22,14 +22,16 @@ void main(void) { uint8_t bank_save; while (true) { PROCESS_INPUT(); + if (KEY_PRESSED(J_A)) { - bank_save = _current_bank; + bank_save = CURRENT_BANK; SWITCH_ROM(BANK(cowbell_8bit_pcm_unsigned)); play_sample(cowbell_8bit_pcm_unsigned, sizeof(cowbell_8bit_pcm_unsigned)); cut_sample(SFX_CH_1 | SFX_CH_2 | SFX_CH_3); SWITCH_ROM(bank_save); + } else if (KEY_PRESSED(J_B)) { - bank_save = _current_bank; + bank_save = CURRENT_BANK; SWITCH_ROM(BANK(risset_drum_8bit_pcm_unsigned)); play_sample(risset_drum_8bit_pcm_unsigned, sizeof(risset_drum_8bit_pcm_unsigned)); cut_sample(SFX_CH_1 | SFX_CH_2 | SFX_CH_3); diff --git a/gbdk-lib/include/gb/gb.h b/gbdk-lib/include/gb/gb.h @@ -330,16 +330,25 @@ void add_SIO(int_handler h); /** Adds a joypad button change interrupt handler. This interrupt occurs on a transition of any of the - keypad input lines from high to low. Due to the fact - that keypad "bounce" is virtually always present, - software should expect this interrupt to occur one - or more times for every button press and one or more + keypad input lines from high to low, if the relevant + @ref P1_REG bits 4 or 5 are set. + + For details about configuring flags or reading the data see: + https://gbdev.io/pandocs/Interrupt_Sources.html#int-60--joypad-interrupt + https://gbdev.io/pandocs/Joypad_Input.html#ff00--p1joyp-joypad + + Due to the fact that keypad "bounce" is virtually always + present, software should expect this interrupt to occur + one or more times for every button press and one or more times for every button release. Up to 4 handlers may be added, with the last added being called last. - @see joypad(), add_VBL() + An example use of this is allowing the user to trigger an + exit from the lower-power STOP cpu state. + + @see joypad(), add_VBL(), IEF_HILO, P1F_5, P1F_4, P1F_3, P1F_2, P1F_1, P1F_0, P1F_GET_DPAD, P1F_GET_BTN, P1F_GET_NONE */ void add_JOY(int_handler h); @@ -482,6 +491,9 @@ extern volatile uint8_t _io_out; /** Tracks current active ROM bank + In most cases the @ref CURRENT_BANK macro for this variable + is recommended for use instead of the variable itself. + The active bank number is not tracked by @ref _current_bank when @ref SWITCH_ROM_MBC5_8M is used. @@ -618,14 +630,14 @@ __endasm; \ #define SWITCH_ROM_MBC5(b) (_current_bank = (b), rROMB1 = 0, rROMB0 = (b)) /** Makes MBC5 to switch the active ROM bank using the full 8MB size. - @see _current_bank + @see CURRENT_BANK @param b ROM bank to switch to This is an alternate to @ref SWITCH_ROM_MBC5 which is limited to 4MB. Note: \li Banked SDCC calls are not supported if you use this macro. - \li The active bank number is not tracked by @ref _current_bank if you use this macro. + \li The active bank number is not tracked by @ref CURRENT_BANK if you use this macro. \li Using @ref SWITCH_ROM_MBC5_8M() should not be mixed with using @ref SWITCH_ROM_MBC5() and @ref SWITCH_ROM(). Note the order used here. Writing the other way around on a MBC1 always selects bank 1 @@ -766,8 +778,16 @@ inline void disable_interrupts(void) PRESERVES_REGS(a, b, c, d, e, h, l) { */ void set_interrupts(uint8_t flags) PRESERVES_REGS(b, c, d, e, h, l); -/** Performs a warm reset by reloading the CPU value - then jumping to the start of crt0 (0x0150) +/** Performs a soft reset. + + For the Game Boy and related it does this by jumping to address 0x0150 + which is in crt0.s (the c-runtime that executes before main() is called). + + This performs various startup steps such as resetting the stack, + clearing WRAM and OAM, resetting initialized variables and some + display registers (scroll, window, LCDC), etc. + + This is not the same a hard power reset. */ void reset(void); 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 register @see joypad(), add_JOY(), IEF_HILO, P1F_5, P1F_4, P1F_3, P1F_2, P1F_1, P1F_0, P1F_GET_DPAD, P1F_GET_BTN, P1F_GET_NONE */ #define rP1 P1_REG #define P1F_5 0b00100000 @@ -85,7 +85,7 @@ __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: @ref IEF_HILO, @ref IEF_SERIAL, @ref IEF_TIMER, @ref IEF_STAT, @ref IEF_VBLANK */ #define rIF IF_REG __REG NR10_REG; /**< Sound Channel 1 Sweep */ @@ -386,11 +386,11 @@ __REG PCM34_REG; /**< Sound channel 3&4 PCM amplitude (R) */ __REG IE_REG; /**< Interrupt enable */ #define rIE IE_REG -#define IEF_HILO 0b00010000 -#define IEF_SERIAL 0b00001000 -#define IEF_TIMER 0b00000100 -#define IEF_STAT 0b00000010 -#define IEF_VBLANK 0b00000001 +#define IEF_HILO 0b00010000 /**< Joypad interrupt enable flag */ +#define IEF_SERIAL 0b00001000 /**< Serial interrupt enable flag */ +#define IEF_TIMER 0b00000100 /**< Timer interrupt enable flag */ +#define IEF_STAT 0b00000010 /**< Stat interrupt enable flag */ +#define IEF_VBLANK 0b00000001 /**< VBlank interrupt enable flag */ /* Square wave duty cycle */ diff --git a/gbdk-lib/include/gb/hblankcpy.h b/gbdk-lib/include/gb/hblankcpy.h @@ -4,27 +4,46 @@ #include <stdint.h> /** HBlank stack copy routine - * takes stack_copy_destination and stack_copy_source global variables as parameters - * manipulates STAT, IE, IF on enter, restores STAT, IE on exit - * interrupts must be disabled on call - @param count number of 16 byte chunks to copy + @param sour Source address to copy from + @param count Number of 16 byte chunks to copy + + Performs the required STAT_REG, IE_REG, IF_REG manipulation + when called and restores STAT_REG and IE_REG on exit + (unlike @ref hblank_cpy_vram()). + + Before calling: + - Set the destination using @ref hblank_copy_destination + - Interrupts must be disabled + + @see hblank_cpy_vram, hblank_copy_destination, hblank_copy */ void hblank_copy_vram(const uint8_t * sour, uint8_t count); /** HBlank stack copy routine - * takes stack_copy_destination and stack_copy_source global variables as parameters - * interrupts must be properly configured - * interrupts must be disabled on call - @param count number of 16 byte chunks to copy + @param sour Source address to copy from + @param count Number of 16 byte chunks to copy + + Unlike @ref hblank_copy_vram() does not perform the required + STAT_REG, IE_REG, IF_REG manipulation, nor does it restore + STAT_REG and IE_REG on exit. + + Before calling: + - Set the destination using @ref hblank_copy_destination + - Interrupts must be properly configured + - Interrupts must be disabled + + @see hblank_copy_vram, hblank_copy_destination, hblank_copy */ void hblank_cpy_vram(const uint8_t * sour, uint8_t count); -extern uint8_t * hblank_copy_destination; +extern uint8_t * hblank_copy_destination; /**< Destination address for hblank copy routine */ -/** HBlank stack copy routine (must be called with disabled interrupts!) +/** HBlank stack copy routine (must be called with interrupts disabled!) @param dest destination pointer @param sour source pointer @param size number of bytes to copy (rounded to 16-byte chunks) + + Performs a fast vram safe copy of data during HBlank. */ inline void hblank_copy(uint8_t * dest, const uint8_t * sour, uint16_t size) { hblank_copy_destination = dest; diff --git a/gbdk-lib/include/gb/metasprites.h b/gbdk-lib/include/gb/metasprites.h @@ -51,6 +51,15 @@ How to use sprite property flags with metasprites: - Primary method: Use the `base_prop` parameter for the move_metasprite_*() functions. + - For more details about the properties on the Game Boy see: https://gbdev.io/pandocs/OAM.html#byte-3--attributesflags + - This can be left at zero for defaults + - Various `OAMF_*` flags can be used depending on the platform: + - @ref OAMF_BANK0, @ref OAMF_BANK1 + - @ref OAMF_CGB_PAL0, @ref OAMF_CGB_PAL1, @ref OAMF_CGB_PAL2, @ref OAMF_CGB_PAL3, + @ref OAMF_CGB_PAL4, @ref OAMF_CGB_PAL5, @ref OAMF_CGB_PAL6, @ref OAMF_CGB_PAL7, + - @ref OAMF_PAL0, @ref OAMF_PAL1, + - @ref OAMF_PALMASK, @ref OAMF_PRI, @ref OAMF_XFLIP, @ref OAMF_YFLIP + - Alternate method: The metasprite structures can have the property flags modified before compilation (such as with `-sp <props>` in the @ref utility_png2asset "png2asset" tool). diff --git a/gbdk-lib/include/gbdk/incbin.h b/gbdk-lib/include/gbdk/incbin.h @@ -59,11 +59,17 @@ extern const void __bank_ ## VARNAME; The variable name is not modified and can be used as-is. - @see INCBIN_SIZE() for obtaining the size of the included data. - @see BANK() for obtaining the bank number of the included data. + The INCBIN() macro will declare the @ref BANK() and @ref INCBIN_SIZE() + helper symbols. Then if @ref INCBIN_EXTERN() is used in the header then + those helper macros can be used in the application code. + - @ref INCBIN_SIZE() for obtaining the size of the included data. + - @ref BANK() for obtaining the bank number of the included data. Use @ref INCBIN_EXTERN() within another source file - to make the variable and it's data accesible there. + to make the variable and it's data accessible there. + +============== + */ #define INCBIN(VARNAME, FILEPATH) void __func_ ## VARNAME(void) __banked __naked { \ __asm \ diff --git a/gbdk-lib/include/rand.h b/gbdk-lib/include/rand.h @@ -16,12 +16,11 @@ The seed should be different each time, otherwise the same pseudo-random sequence will be generated. - The DIV Register (@ref DIV_REG) is sometimes used as a seed, - particularly if read at some variable point in time (such - as when the player presses a button). + One way to do this is sampling (@ref DIV_REG) up to 2 times (high byte of + seed value then the low byte) at variable, non-deterministic points in time + (such as when the player presses buttons on the title screen or in a menu). - Only needs to be called once to initialize, but may be called - again to re-initialize with the same or a different seed. + It only needs to be called once to be initialized. @see rand(), randw() */
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.