git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

gbdk-lib/include/sms/sms.h

      1 /** @file sms/sms.h
      2     SMS/GG specific functions.
      3 */
      4 #ifndef _SMS_H
      5 #define _SMS_H
      6 
      7 #include <types.h>
      8 #include <stdint.h>
      9 #include <gbdk/version.h>
     10 #include <sms/hardware.h>
     11 
     12 #define SEGA
     13 
     14 // Here NINTENDO means Game Boy & related clones
     15 #ifdef NINTENDO
     16 #undef NINTENDO
     17 #endif
     18 
     19 #ifdef NINTENDO_NES
     20 #undef NINTENDO_NES
     21 #endif
     22 
     23 #ifdef MSX
     24 #undef MSX
     25 #endif
     26 
     27 #if defined(__TARGET_sms)
     28 #define MASTERSYSTEM
     29 #elif defined(__TARGET_gg)
     30 #define GAMEGEAR
     31 #endif
     32 
     33 
     34 extern const UBYTE _BIOS;
     35 
     36 extern const uint8_t _SYSTEM;
     37 
     38 #define SYSTEM_60HZ     0x00
     39 #define SYSTEM_50HZ     0x01
     40 
     41 #define VBK_REG VDP_ATTR_SHIFT
     42 
     43 /** Joypad bits.
     44     A logical OR of these is used in the wait_pad and joypad
     45     functions.  For example, to see if the B button is pressed
     46     try
     47 
     48     uint8_t keys;
     49     keys = joypad();
     50     if (keys & J_B) {
     51     	...
     52     }
     53 
     54     @see joypad
     55  */
     56 #define	J_UP         0b00000001
     57 #define	J_DOWN       0b00000010
     58 #define	J_LEFT       0b00000100
     59 #define	J_RIGHT      0b00001000
     60 #define	J_B          0b00010000
     61 #define	J_A          0b00100000
     62 #define	J_START      0b01000000
     63 #define	J_SELECT     0b10000000
     64 
     65 /** Screen modes.
     66     Normally used by internal functions only.
     67     @see mode()
     68  */
     69 #define	M_TEXT_OUT   0x02U
     70 #define	M_TEXT_INOUT 0x03U
     71 /** Set this in addition to the others to disable scrolling
     72 
     73     If scrolling is disabled, the cursor returns to (0,0)
     74     @see mode()
     75 */
     76 #define M_NO_SCROLL  0x04U
     77 /** Set this to disable interpretation
     78     @see mode()
     79 */
     80 #define M_NO_INTERP  0x08U
     81 
     82 /** The nineth bit of the tile id
     83 */
     84 #define S_BANK       0x01U
     85 /** If set the background tile will be flipped horizontally.
     86  */
     87 #define S_FLIPX      0x02U
     88 /** If set the background tile will be flipped vertically.
     89  */
     90 #define S_FLIPY      0x04U
     91 /** If set the background tile palette.
     92  */
     93 #define S_PALETTE    0x08U
     94 /** If set the background tile priority.
     95  */
     96 #define S_PRIORITY   0x10U
     97 /** Dummy function used by other platforms.
     98     Required for the png2asset tool's metasprite output.
     99 */
    100 #define S_PAL(n)     (((n) & 0x01U) << 3)
    101 
    102 // VDP helper macros
    103 #define __WRITE_VDP_REG_UNSAFE(REG, v) shadow_##REG=(v),VDP_CMD=(shadow_##REG),VDP_CMD=REG
    104 #define __WRITE_VDP_REG(REG, v) shadow_##REG=(v);__asm__("di");VDP_CMD=(shadow_##REG);VDP_CMD=REG;__asm__("ei")
    105 #define __READ_VDP_REG(REG) shadow_##REG
    106 
    107 void WRITE_VDP_CMD(uint16_t cmd) Z88DK_FASTCALL PRESERVES_REGS(b, c, d, e, iyh, iyl);
    108 void WRITE_VDP_DATA(uint16_t data) Z88DK_FASTCALL PRESERVES_REGS(b, c, d, e, iyh, iyl);
    109 
    110 /** Set the current screen mode - one of M_* modes
    111 
    112     Normally used by internal functions only.
    113 
    114     @see M_TEXT_OUT, M_TEXT_INOUT, M_NO_SCROLL, M_NO_INTERP
    115 */
    116 void mode(uint8_t m) OLDCALL;
    117 
    118 /** Returns the current mode
    119 
    120     @see M_TEXT_OUT, M_TEXT_INOUT, M_NO_SCROLL, M_NO_INTERP
    121 */
    122 uint8_t get_mode(void) OLDCALL;
    123 
    124 /** Returns the system gbdk is running on.
    125 
    126 */
    127 inline uint8_t get_system(void) {
    128     return _SYSTEM;
    129 }
    130 
    131 /* Interrupt flags */
    132 /** Disable calling of interrupt service routines
    133  */
    134 #define EMPTY_IFLAG  0x00U
    135 /** VBlank Interrupt occurs at the start of the vertical blank.
    136 
    137     During this period the video ram may be freely accessed.
    138     @see set_interrupts(), @see add_VBL
    139  */
    140 #define VBL_IFLAG    0x01U
    141 /** LCD Interrupt when triggered by the STAT register.
    142     @see set_interrupts(), @see add_LCD
    143 */
    144 #define LCD_IFLAG    0x02U
    145 /** Does nothing on SMS/GG
    146  */
    147 #define TIM_IFLAG    0x04U
    148 /** Does nothing on SMS/GG
    149  */
    150 #define SIO_IFLAG    0x08U
    151 /** Does nothing on SMS/GG
    152  */
    153 #define JOY_IFLAG    0x10U
    154 
    155 void set_interrupts(uint8_t flags) Z88DK_FASTCALL;
    156 
    157 /* Limits */
    158 /** Width of the visible screen in pixels.
    159  */
    160 #define SCREENWIDTH  DEVICE_SCREEN_PX_WIDTH
    161 /** Height of the visible screen in pixels.
    162  */
    163 #define SCREENHEIGHT DEVICE_SCREEN_PX_HEIGHT
    164 /** The Minimum X position of the Window Layer (Left edge of screen) @see move_win()
    165  */
    166 #define MINWNDPOSX   0x00U
    167 /** The Minimum Y position of the Window Layer (Top edge of screen) @see move_win()
    168  */
    169 #define MINWNDPOSY   0x00U
    170 /** The Maximum X position of the Window Layer (Right edge of screen) @see move_win()
    171  */
    172 #define MAXWNDPOSX   0x00U
    173 /** The Maximum Y position of the Window Layer (Bottom edge of screen) @see move_win()
    174  */
    175 #define MAXWNDPOSY   0x00U
    176 
    177 
    178 /** Interrupt handlers
    179  */
    180 typedef void (*int_handler)(void) NONBANKED;
    181 
    182 /** Removes the VBL interrupt handler.
    183     @see add_VBL()
    184 */
    185 void remove_VBL(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(iyh, iyl);
    186 
    187 /** Removes the LCD interrupt handler.
    188     @see add_LCD(), remove_VBL()
    189 */
    190 void remove_LCD(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(b, c, iyh, iyl);
    191 
    192 void remove_TIM(int_handler h) Z88DK_FASTCALL;
    193 void remove_SIO(int_handler h) Z88DK_FASTCALL;
    194 void remove_JOY(int_handler h) Z88DK_FASTCALL;
    195 
    196 /** Adds a V-blank interrupt handler.
    197 */
    198 void add_VBL(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(d, e, iyh, iyl);
    199 
    200 /** Adds a LCD interrupt handler.
    201 */
    202 void add_LCD(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(b, c, iyh, iyl);
    203 
    204 /** Does nothing on SMS/GG
    205  */
    206 void add_TIM(int_handler h) Z88DK_FASTCALL;
    207 
    208 /** Does nothing on SMS/GG
    209  */
    210 void add_SIO(int_handler h) Z88DK_FASTCALL;
    211 
    212 /** Does nothing on SMS/GG
    213  */
    214 void add_JOY(int_handler h) Z88DK_FASTCALL;
    215 
    216 /** Cancel pending interrupts
    217  */
    218 inline uint8_t cancel_pending_interrupts(void) {
    219     return VDP_STATUS;
    220 }
    221 
    222 inline void move_bkg(uint8_t x, uint8_t y) {
    223     __WRITE_VDP_REG(VDP_RSCX, -x);
    224     __WRITE_VDP_REG(VDP_RSCY, y);
    225 }
    226 
    227 inline void scroll_bkg(int8_t x, int8_t y) {
    228     __WRITE_VDP_REG(VDP_RSCX, __READ_VDP_REG(VDP_RSCX) - x);
    229     int16_t tmp = __READ_VDP_REG(VDP_RSCY) + y;
    230     __WRITE_VDP_REG(VDP_RSCY, (tmp < 0) ? 224 + tmp : tmp % 224u);
    231 }
    232 
    233 /** HALTs the CPU and waits for the vertical blank interrupt.
    234 
    235     This is often used in main loops to idle the CPU at low power
    236     until it's time to start the next frame. It's also useful for
    237     syncing animation with the screen re-draw.
    238 
    239     Warning: If the VBL interrupt is disabled, this function will
    240     never return. If the screen is off this function returns
    241     immediately.
    242 */
    243 void vsync(void) PRESERVES_REGS(b, c, d, e, h, l, iyh, iyl);
    244 
    245 /** Obsolete. This function has been replaced by vsync(), which has identical behavior.
    246 */
    247 void wait_vbl_done(void) PRESERVES_REGS(b, c, d, e, h, l, iyh, iyl);
    248 
    249 /** Turns the display off.
    250 
    251     @see DISPLAY_ON
    252 */
    253 inline void display_off(void) {
    254     __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) &= (~R1_DISP_ON));
    255 }
    256 
    257 /** Turns the display back on.
    258     @see display_off, DISPLAY_OFF
    259 */
    260 #define DISPLAY_ON \
    261     __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) |= R1_DISP_ON)
    262 
    263 /** Turns the display off immediately.
    264     @see display_off, DISPLAY_ON
    265 */
    266 #define DISPLAY_OFF \
    267 	display_off();
    268 
    269 /** Copies data from shadow OAM to OAM
    270  */
    271 void refresh_OAM(void);
    272 
    273 /** Blanks leftmost column, so it is not garbaged when you use horizontal scroll
    274     @see SHOW_LEFT_COLUMN
    275 */
    276 #define HIDE_LEFT_COLUMN \
    277     __WRITE_VDP_REG(VDP_R0, __READ_VDP_REG(VDP_R0) |= R0_LCB)
    278 
    279 /** Shows leftmost column
    280     @see HIDE_LEFT_COLUMN
    281 */
    282 #define SHOW_LEFT_COLUMN \
    283     __WRITE_VDP_REG(VDP_R0, __READ_VDP_REG(VDP_R0) &= (~R0_LCB))
    284 
    285 /** Sets border color
    286  */
    287 #define SET_BORDER_COLOR(C) __WRITE_VDP_REG(VDP_R7, ((C) | 0xf0u))
    288 
    289 /** Turns on the background layer.
    290     Not yet implemented
    291 */
    292 #define SHOW_BKG
    293 
    294 /** Turns off the background layer.
    295     Not yet implemented
    296 */
    297 #define HIDE_BKG
    298 
    299 /** Turns on the window layer
    300     Not yet implemented
    301 */
    302 #define SHOW_WIN
    303 
    304 /** Turns off the window layer.
    305     Not yet implemented
    306 */
    307 #define HIDE_WIN
    308 
    309 /** Turns on the sprites layer.
    310 */
    311 #define SHOW_SPRITES \
    312     (_sprites_OFF = 0)
    313 
    314 /** Turns off the sprites layer.
    315 */
    316 #define HIDE_SPRITES \
    317     (_sprites_OFF = 1)
    318 
    319 /** Sets sprite size to 8x16 pixels, two tiles one above the other.
    320 */
    321 #define SPRITES_8x16 \
    322     __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) |= R1_SPR_8X16)
    323 
    324 /** Sets sprite size to 8x8 pixels, one tile.
    325 */
    326 #define SPRITES_8x8 \
    327     __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) &= (~R1_SPR_8X16))
    328 
    329 /** Macro returns TRUE if device supports color
    330  *  (it always does on SMS/GG)
    331  */
    332 #define DEVICE_SUPPORTS_COLOR (TRUE)
    333 
    334 /** Macro returns TRUE if device supports window layer
    335  */
    336 #define DEVICE_SUPPORTS_WINDOW (FALSE)
    337 
    338 /** Macro returns TRUE if device supports reading from VRAM
    339  */
    340 #define DEVICE_SUPPORTS_VRAM_READ (FALSE)
    341 
    342 /** Global Time Counter in VBL periods (60Hz)
    343 
    344     Increments once per Frame
    345 
    346     Will wrap around every ~18 minutes (unsigned 16 bits = 65535 / 60 / 60 = 18.2)
    347 */
    348 extern volatile uint16_t sys_time;
    349 
    350 /** Flag indicating the VBlank ISR has run
    351 
    352    Flag gets cleared at the start of @ref vsync() / @ref wait_vbl_done()
    353    and set in the default VBlank ISR handler.
    354 */
    355 extern volatile uint8_t _vbl_done;
    356 #define VBL_DONE _vbl_done
    357 
    358 
    359 /** Return R register for the DIV_REG emulation
    360 
    361     Increments once per CPU instruction (fetches the Z80 CPU R register)
    362 
    363 */
    364 uint8_t get_r_reg(void) PRESERVES_REGS(b, c, d, e, h, l, iyh, iyl);
    365 
    366 #define DIV_REG get_r_reg()
    367 
    368 /** Tracks current active ROM bank in frame 1
    369 */
    370 #define _current_bank MAP_FRAME1
    371 #define CURRENT_BANK MAP_FRAME1
    372 
    373 /** Obtains the __bank number__ of VARNAME
    374 
    375     @param VARNAME Name of the variable which has a __bank_VARNAME companion symbol which is adjusted by bankpack
    376 
    377     Use this to obtain the bank number from a bank reference
    378     created with @ref BANKREF().
    379 
    380     @see BANKREF_EXTERN(), BANKREF()
    381 */
    382 #ifndef BANK
    383 #define BANK(VARNAME) ( (uint8_t) & __bank_ ## VARNAME )
    384 #endif
    385 
    386 /** Creates a reference for retrieving the bank number of a variable or function
    387 
    388     @param VARNAME Variable name to use, which may be an existing identifier
    389 
    390     @see BANK() for obtaining the bank number of the included data.
    391 
    392     More than one `BANKREF()` may be created per file, but each call should
    393     always use a unique VARNAME.
    394 
    395     Use @ref BANKREF_EXTERN() within another source file
    396     to make the variable and it's data accesible there.
    397 */
    398 #define BANKREF(VARNAME) void __func_ ## VARNAME(void) __banked __naked { \
    399 __asm \
    400     .local b___func_ ## VARNAME \
    401     ___bank_ ## VARNAME = b___func_ ## VARNAME \
    402     .globl ___bank_ ## VARNAME \
    403 __endasm; \
    404 }
    405 
    406 /** Creates extern references for accessing a BANKREF() generated variable.
    407 
    408     @param VARNAME Name of the variable used with @ref BANKREF()
    409 
    410     This makes a @ref BANKREF() reference in another source
    411     file accessible in the current file for use with @ref BANK().
    412 
    413     @see BANKREF(), BANK()
    414 */
    415 #define BANKREF_EXTERN(VARNAME) extern const void __bank_ ## VARNAME;
    416 
    417 
    418 /** Makes switch the active ROM bank in frame 1
    419     @param b   ROM bank to switch to
    420 */
    421 
    422 #define SWITCH_ROM(b) MAP_FRAME1=(b)
    423 #define SWITCH_ROM1 SWITCH_ROM
    424 
    425 /** Makes switch the active ROM bank in frame 2
    426     @param b   ROM bank to switch to
    427 */
    428 
    429 #define SWITCH_ROM2(b) MAP_FRAME2=(b)
    430 
    431 /** Switches RAM bank
    432     @param b   SRAM bank to switch to
    433 */
    434 
    435 #define SWITCH_RAM(b) RAM_CONTROL=((b)&1)?RAM_CONTROL|RAMCTL_BANK:RAM_CONTROL&(~RAMCTL_BANK)
    436 
    437 /** Enables RAM
    438 */
    439 
    440 #define ENABLE_RAM RAM_CONTROL|=RAMCTL_RAM
    441 
    442 /** Disables RAM
    443 */
    444 
    445 #define DISABLE_RAM RAM_CONTROL&=(~RAMCTL_RAM)
    446 
    447 
    448 /** Delays the given number of milliseconds.
    449     Uses no timers or interrupts, and can be called with
    450     interrupts disabled
    451  */
    452 void delay(uint16_t d) Z88DK_FASTCALL;
    453 
    454 
    455 /** Reads and returns the current state of the joypad.
    456 */
    457 uint8_t joypad(void) OLDCALL PRESERVES_REGS(b, c, d, e, iyh, iyl);
    458 
    459 /** Waits until at least one of the buttons given in mask are pressed.
    460 */
    461 uint8_t waitpad(uint8_t mask) Z88DK_FASTCALL PRESERVES_REGS(d, e, iyh, iyl);
    462 
    463 /** Waits for the directional pad and all buttons to be released.
    464 
    465     Note: Checks in a loop that doesn't HALT at all, so the CPU
    466     will be maxed out until this call returns.
    467 */
    468 void waitpadup(void) PRESERVES_REGS(d, e, iyh, iyl);
    469 
    470 /** Multiplayer joypad structure.
    471 
    472     Must be initialized with @ref joypad_init() first then it
    473     may be used to poll all avaliable joypads with @ref joypad_ex()
    474 */
    475 typedef struct {
    476     uint8_t npads;
    477     union {
    478         struct {
    479             uint8_t joy0, joy1, joy2, joy3;
    480         };
    481         uint8_t joypads[4];
    482     };
    483 } joypads_t;
    484 
    485 /** Initializes joypads_t structure for polling multiple joypads
    486     @param npads	number of joypads requested (1, 2 or 4)
    487     @param joypads	pointer to joypads_t structure to be initialized
    488 
    489     Only required for @ref joypad_ex, not required for calls to regular @ref joypad()
    490     @returns number of joypads avaliable
    491     @see joypad_ex(), joypads_t
    492 */
    493 uint8_t joypad_init(uint8_t npads, joypads_t * joypads) Z88DK_CALLEE;
    494 
    495 /** Polls all avaliable joypads
    496     @param joypads	pointer to joypads_t structure to be filled with joypad statuses,
    497     	   must be previously initialized with joypad_init()
    498 
    499     @see joypad_init(), joypads_t
    500 */
    501 void joypad_ex(joypads_t * joypads) Z88DK_FASTCALL PRESERVES_REGS(iyh, iyl);
    502 
    503 /** Enables unmasked interrupts
    504 
    505     @note Use @ref CRITICAL {...} instead for creating a block of
    506           of code which should execute with interrupts  temporarily
    507           turned off.
    508 
    509     @see disable_interrupts, set_interrupts, CRITICAL
    510 */
    511 inline void enable_interrupts(void) PRESERVES_REGS(a, b, c, d, e, h, l, iyh, iyl) {
    512     __asm__("ei");
    513 }
    514 
    515 /** Disables interrupts
    516 
    517     @note Use @ref CRITICAL {...} instead for creating a block of
    518           of code which should execute with interrupts  temporarily
    519           turned off.
    520 
    521     This function may be called as many times as you like;
    522     however the first call to @ref enable_interrupts will re-enable
    523     them.
    524 
    525     @see enable_interrupts, set_interrupts, CRITICAL
    526 */
    527 inline void disable_interrupts(void) PRESERVES_REGS(a, b, c, d, e, h, l, iyh, iyl) {
    528     __asm__("di");
    529 }
    530 
    531 
    532 #if defined(__TARGET_sms)
    533 
    534 #define RGB(r,g,b)        ((r) | ((g) << 2) | ((b) << 4))
    535 #define RGB8(r,g,b)       (((r) >> 6) | (((g) >> 6) << 2) | (((b) >> 6) << 4))
    536 #define RGBHTML(RGB24bit) (((RGB24bit) >> 22) | ((((RGB24bit) & 0xFFFF) >> 14) << 2) | ((((RGB24bit) & 0xFF) >> 6) << 4))
    537 
    538 /** Common colors based on the EGA default palette.
    539  */
    540 #define RGB_RED        RGB( 3,  0,  0)
    541 #define RGB_DARKRED    RGB( 2,  0,  0)
    542 #define RGB_GREEN      RGB( 0,  3,  0)
    543 #define RGB_DARKGREEN  RGB( 0,  2,  0)
    544 #define RGB_BLUE       RGB( 0,  0,  3)
    545 #define RGB_DARKBLUE   RGB( 0,  0,  2)
    546 #define RGB_YELLOW     RGB( 3,  3,  0)
    547 #define RGB_DARKYELLOW RGB( 2,  2,  0)
    548 #define RGB_CYAN       RGB( 0,  3,  3)
    549 #define RGB_AQUA       RGB( 3,  1,  2)
    550 #define RGB_PINK       RGB( 3,  0,  3)
    551 #define RGB_PURPLE     RGB( 2,  0,  2)
    552 #define RGB_BLACK      RGB( 0,  0,  0)
    553 #define RGB_DARKGRAY   RGB( 1,  1,  1)
    554 #define RGB_LIGHTGRAY  RGB( 2,  2,  2)
    555 #define RGB_WHITE      RGB( 3,  3,  3)
    556 
    557 typedef uint8_t palette_color_t;
    558 
    559 #elif defined(__TARGET_gg)
    560 
    561 #define RGB(r,g,b)        ((uint16_t)(r) | (uint16_t)((g) << 4) | (uint16_t)((b) << 8))
    562 #define RGB8(r,g,b)       ((uint16_t)((r) >> 4) | ((uint16_t)((g) >> 4) << 4) | ((uint16_t)((b) >> 4) << 8))
    563 #define RGBHTML(RGB24bit) (((RGB24bit) >> 20) | ((((RGB24bit) & 0xFFFF) >> 12) << 4)|((((RGB24bit) & 0xFF) >> 4) << 8))
    564 
    565 /** Common colors based on the EGA default palette.
    566  */
    567 #define RGB_RED        RGB(15,  0,  0)
    568 #define RGB_DARKRED    RGB( 7,  0,  0)
    569 #define RGB_GREEN      RGB( 0, 15,  0)
    570 #define RGB_DARKGREEN  RGB( 0,  7,  0)
    571 #define RGB_BLUE       RGB( 0,  0, 15)
    572 #define RGB_DARKBLUE   RGB( 0,  0,  7)
    573 #define RGB_YELLOW     RGB(15, 15,  0)
    574 #define RGB_DARKYELLOW RGB( 7,  7,  0)
    575 #define RGB_CYAN       RGB( 0, 15, 15)
    576 #define RGB_AQUA       RGB(14,  2, 11)
    577 #define RGB_PINK       RGB(15,  0, 15)
    578 #define RGB_PURPLE     RGB(10,  0, 10)
    579 #define RGB_BLACK      RGB( 0,  0,  0)
    580 #define RGB_DARKGRAY   RGB( 5,  5,  5)
    581 #define RGB_LIGHTGRAY  RGB(10, 10, 10)
    582 #define RGB_WHITE      RGB(15, 15, 15)
    583 
    584 #define RGB_LIGHTFLESH RGB(15, 10,  7)
    585 #define RGB_BROWN      RGB( 5,  5,  0)
    586 #define RGB_ORANGE     RGB(15, 10,  0)
    587 #define RGB_TEAL       RGB( 7,  7,  0)
    588 
    589 typedef uint16_t palette_color_t;
    590 
    591 #else
    592 #error Unrecognized port
    593 #endif
    594 
    595 void set_default_palette(void);
    596 inline void cgb_compatibility(void) {
    597     set_default_palette();
    598 }
    599 
    600 inline void cpu_fast(void) {}
    601 
    602 void set_palette_entry(uint8_t palette, uint8_t entry, uint16_t rgb_data) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
    603 #define set_bkg_palette_entry set_palette_entry
    604 #define set_sprite_palette_entry(palette,entry,rgb_data) set_palette_entry(1,entry,rgb_data)
    605 
    606 
    607 /** Set color palette(s)
    608 
    609     @param first_palette  Index of the first 16 color palette to write (0-1)
    610     @param nb_palettes    Number of palettes to write (1-2, max depends on first_palette)
    611     @param rgb_data       Pointer to source palette data
    612 
    613     Writes __nb_palettes__ to palette data starting
    614     at __first_palette__, Palette data is sourced from __rgb_data__.
    615 
    616     \li Palette 0 can be used for the Background.
    617     \li Palette 1 is shared between Background and Sprites.
    618 
    619     On the Game Gear
    620     \li Each Palette is 32 bytes in size: 16 colors x 2 bytes per palette color entry.
    621     \li Each color (16 per palette) is packed as BGR-444 format (x:4:4:4, MSBits [15..12] are unused).
    622     \li Each component (R, G, B) may have values from 0 - 15 (4 bits), 15 is brightest.
    623 
    624     On the SMS
    625     \li On SMS each Palette is 16 bytes in size: 16 colors x 1 byte per palette color entry.
    626     \li Each color (16 per palette) is packed as BGR-222 format (x:2:2:2, MSBits [7..6] are unused).
    627     \li Each component (R, G, B) may have values from 0 - 3 (2 bits), 3 is brightest.
    628 
    629     @see RGB(), set_sprite_palette(), set_bkg_palette(), set_palette_entry(), set_sprite_palette_entry(), set_bkg_palette_entry(), set_sprite_palette()
    630 */
    631 void set_palette(uint8_t first_palette, uint8_t nb_palettes, const palette_color_t *rgb_data) Z88DK_CALLEE;
    632 #define set_bkg_palette set_palette
    633 #define set_sprite_palette(first_palette,nb_palettes,rgb_data) set_palette(1,1,rgb_data)
    634 
    635 void set_native_tile_data(uint16_t start, uint16_t ntiles, const void *src) PRESERVES_REGS(iyh, iyl);
    636 void set_bkg_4bpp_data(uint16_t start, uint16_t ntiles, const void *src) PRESERVES_REGS(iyh, iyl);
    637 void set_bkg_native_data(uint16_t start, uint16_t ntiles, const void *src) PRESERVES_REGS(iyh, iyl);
    638 
    639 void set_sprite_4bpp_data(uint8_t start, uint16_t ntiles, const void *src) PRESERVES_REGS(iyh, iyl);
    640 void set_sprite_native_data(uint8_t start, uint16_t ntiles, const void *src) PRESERVES_REGS(iyh, iyl);
    641 
    642 #define COMPAT_PALETTE(C0,C1,C2,C3) (((uint16_t)(C3) << 12) | ((uint16_t)(C2) << 8) | ((uint16_t)(C1) << 4) | (uint16_t)(C0))
    643 extern uint16_t _current_2bpp_palette;
    644 inline void set_2bpp_palette(uint16_t palette) {
    645     _current_2bpp_palette = palette;
    646 }
    647 void set_tile_2bpp_data(uint16_t start, uint16_t ntiles, const void *src, uint16_t palette) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
    648 inline void set_bkg_data(uint16_t start, uint16_t ntiles, const void *src) {
    649     set_tile_2bpp_data(start, ntiles, src, _current_2bpp_palette);
    650 }
    651 inline void set_sprite_data(uint16_t start, uint16_t ntiles, const void *src) {
    652     set_tile_2bpp_data((uint8_t)(start) + 0x100u, ntiles, src, _current_2bpp_palette);
    653 }
    654 inline void set_bkg_2bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
    655     set_tile_2bpp_data(start, ntiles, src, _current_2bpp_palette);
    656 }
    657 inline void set_sprite_2bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
    658     set_tile_2bpp_data((uint8_t)(start) + 0x100u, ntiles, src, _current_2bpp_palette);
    659 }
    660 
    661 extern uint16_t _current_1bpp_colors;
    662 inline void set_1bpp_colors(uint8_t fgcolor, uint8_t bgcolor) {
    663     _current_1bpp_colors = ((uint16_t)bgcolor << 8) | fgcolor;
    664 }
    665 void set_tile_1bpp_data(uint16_t start, uint16_t ntiles, const void *src, uint16_t colors) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
    666 inline void set_bkg_1bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
    667     set_tile_1bpp_data(start, ntiles, src, _current_1bpp_colors);
    668 }
    669 inline void set_sprite_1bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
    670     set_tile_1bpp_data((uint8_t)(start) + 0x100u, ntiles, src, _current_1bpp_colors);
    671 }
    672 
    673 
    674 /** Copies arbitrary data to an address in VRAM
    675 
    676     @param dst       destination VRAM Address
    677     @param src       Pointer to source buffer
    678     @param size      Number of bytes to copy
    679 
    680     Copies __size__ bytes from a buffer at _src__ to VRAM starting at __dst__.
    681 */
    682 void set_data(uint16_t dst, const void *src, uint16_t size) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
    683 void vmemcpy(uint16_t dst, const void *src, uint16_t size) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
    684 
    685 void set_tile_map(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles) Z88DK_CALLEE;
    686 void set_tile_map_compat(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles) Z88DK_CALLEE;
    687 #define set_bkg_tiles set_tile_map_compat
    688 #define set_win_tiles set_tile_map_compat
    689 
    690 extern uint8_t _map_tile_offset;
    691 inline void set_bkg_based_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles, uint8_t base_tile) {
    692     _map_tile_offset = base_tile;
    693     set_tile_map_compat(x, y, w, h, tiles);
    694     _map_tile_offset = 0;
    695 }
    696 inline void set_win_based_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles, uint8_t base_tile) {
    697     _map_tile_offset = base_tile;
    698     set_tile_map_compat(x, y, w, h, tiles);
    699     _map_tile_offset = 0;
    700 }
    701 
    702 inline void set_bkg_attributes(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles)
    703 {
    704     VBK_REG = VBK_ATTRIBUTES;
    705     set_bkg_tiles(x, y, w, h, tiles);
    706     VBK_REG = VBK_TILES;
    707 }
    708 
    709 void set_tile_submap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w) Z88DK_CALLEE;
    710 void set_tile_submap_compat(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w) Z88DK_CALLEE;
    711 #define set_bkg_submap set_tile_submap_compat
    712 #define set_win_submap set_tile_submap_compat
    713 
    714 extern uint8_t _submap_tile_offset;
    715 inline void set_bkg_based_submap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w, uint8_t base_tile) {
    716     _submap_tile_offset = base_tile;
    717     set_tile_submap_compat(x, y, w, h, map, map_w);
    718     _submap_tile_offset = 0;
    719 }
    720 inline void set_win_based_submap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w, uint8_t base_tile) {
    721     _submap_tile_offset = base_tile;
    722     set_tile_submap_compat(x, y, w, h, map, map_w);
    723     _submap_tile_offset = 0;
    724 }
    725 
    726 inline void set_bkg_submap_attributes(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w) {
    727     VBK_REG = VBK_ATTRIBUTES;
    728     set_tile_submap_compat(x, y, w, h, map, map_w);
    729     VBK_REG = VBK_TILES;
    730 }
    731 
    732 inline void set_win_submap_attributes(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w) {
    733     VBK_REG = VBK_ATTRIBUTES;
    734     set_tile_submap_compat(x, y, w, h, map, map_w);
    735     VBK_REG = VBK_TILES;
    736 }
    737 
    738 void fill_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint16_t tile) Z88DK_CALLEE;
    739 void fill_rect_compat(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint16_t tile) Z88DK_CALLEE;
    740 #define fill_bkg_rect fill_rect_compat
    741 #define fill_win_rect fill_rect_compat
    742 
    743 inline void fill_bkg_rect_attributes(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint16_t attribute) {
    744     VBK_REG = VBK_ATTRIBUTES;
    745     fill_bkg_rect(x, y, w, h, attribute);
    746     VBK_REG = VBK_TILES;
    747 }
    748 
    749 /** Shadow OAM array in WRAM, that is transferred into the real OAM each VBlank
    750 */
    751 extern volatile uint8_t shadow_OAM[];
    752 
    753 /** MSB of shadow_OAM address is used by OAM copying routine
    754 */
    755 extern volatile uint8_t _shadow_OAM_base;
    756 
    757 /** Flag for disabling of OAM copying routine
    758 
    759     Values:
    760     \li 1: OAM copy routine is disabled (non-isr VDP operation may be in progress)
    761     \li 0: OAM copy routine is enabled
    762 
    763     This flag is modified by all sms/gg GBDK API calls that write to the VDP.
    764     It is set to DISABLED when they start and ENABLED when they complete.
    765 
    766     @note It is recommended to avoid writing to the Video Display Processor
    767     (VDP) during an interrupt service routine (ISR) since it can corrupt
    768     the VDP pointer of an VDP operation already in progress.
    769 
    770     If it is necessary, this flag can be used during an ISR to determine
    771     whether a VDP operation is already in progress. If the value is `1`
    772     then avoid writing to the VDP (tiles, map, scrolling, colors, etc).
    773 
    774     \code{.c}
    775     // at the beginning of and ISR that would write to the VDP
    776     if (_shadow_OAM_OFF) return;
    777     \endcode
    778 
    779     @see @ref docs_consoles_safe_display_controller_access
    780 */
    781 extern volatile uint8_t _shadow_OAM_OFF;
    782 
    783 extern volatile uint8_t _sprites_OFF;
    784 
    785 /** Disable shadow OAM to VRAM copy on each VBlank
    786 */
    787 #define DISABLE_VBL_TRANSFER \
    788     _shadow_OAM_base = 0
    789 
    790 /** Enable shadow OAM to VRAM copy on each VBlank
    791 */
    792 #define ENABLE_VBL_TRANSFER \
    793     _shadow_OAM_base = (uint8_t)((uint16_t)&shadow_OAM >> 8)
    794 
    795 /** Amount of hardware sprites in OAM
    796 */
    797 #define MAX_HARDWARE_SPRITES 64
    798 
    799 /** True if sprite hardware can flip sprites by X (horizontally)
    800 */
    801 #define HARDWARE_SPRITE_CAN_FLIP_X 0
    802 
    803 /** True if sprite hardware can flip sprites by Y (vertically)
    804 */
    805 #define HARDWARE_SPRITE_CAN_FLIP_Y 0
    806 
    807 /** Sets address of 256-byte aligned array of shadow OAM to be transferred on each VBlank
    808 */
    809 inline void SET_SHADOW_OAM_ADDRESS(void * address) {
    810     _shadow_OAM_base = (uint8_t)((uint16_t)address >> 8);
    811 }
    812 
    813 /** Sets sprite number __nb__in the OAM to display tile number __tile__.
    814 
    815     @param nb    Sprite number, range 0 - 39
    816     @param tile  Selects a tile (0 - 255) from memory at 8000h - 8FFFh
    817                  \n In CGB Mode this could be either in VRAM Bank
    818                  \n 0 or 1, depending on Bit 3 of the OAM Attribute Flag
    819                  \n (see @ref set_sprite_prop)
    820 
    821     In 8x16 mode:
    822     \li The sprite will also display the next tile (__tile__ + 1)
    823         directly below (y + 8) the first tile.
    824     \li The lower bit of the tile number is ignored:
    825         the upper 8x8 tile is (__tile__ & 0xFE), and
    826         the lower 8x8 tile is (__tile__ | 0x01).
    827     \li See: @ref SPRITES_8x16
    828 */
    829 inline void set_sprite_tile(uint8_t nb, uint8_t tile) {
    830     shadow_OAM[0x41+(nb << 1)] = tile;
    831 }
    832 
    833 
    834 /** Returns the tile number of sprite number __nb__ in the OAM.
    835 
    836 @param nb    Sprite number, range 0 - 39
    837 
    838 @see set_sprite_tile for more details
    839 */
    840 inline uint8_t get_sprite_tile(uint8_t nb) {
    841     return shadow_OAM[0x41+(nb << 1)];
    842 }
    843 
    844 /** Function has no affect on sms.
    845 
    846   This function is only here to enable game portability
    847 */
    848 
    849 inline void set_sprite_prop(uint8_t nb, uint8_t prop) {
    850     nb; prop;
    851 }
    852 
    853 inline uint8_t get_sprite_prop(uint8_t nb) {
    854     nb;
    855     return 0;
    856 }
    857 
    858 /** Moves sprite number __nb__ to the __x__, __y__ position on the screen.
    859 
    860     @param nb  Sprite number, range 0 - 39
    861     @param x   X Position. Specifies the sprites horizontal position on the screen (minus 8).
    862                \n An offscreen value (X=0 or X>=168) hides the sprite, but the sprite
    863                still affects the priority ordering - a better way to hide a sprite is to set
    864                its Y-coordinate offscreen.
    865     @param y   Y Position. Specifies the sprites vertical position on the screen (minus 16).
    866                \n An offscreen value (for example, Y=0 or Y>=160) hides the sprite.
    867 
    868     Moving the sprite to 0,0 (or similar off-screen location) will hide it.
    869 */
    870 inline void move_sprite(uint8_t nb, uint8_t x, uint8_t y) {
    871     shadow_OAM[nb] = (y < VDP_SAT_TERM) ? y : 0xC0;
    872     shadow_OAM[0x40+(nb << 1)] = x;
    873 }
    874 
    875 
    876 /** Moves sprite number __nb__ relative to its current position.
    877 
    878     @param nb  Sprite number, range 0 - 39
    879     @param x   Number of pixels to move the sprite on the __X axis__
    880                \n Range: -128 - 127
    881     @param y   Number of pixels to move the sprite on the __Y axis__
    882                \n Range: -128 - 127
    883 
    884     @see move_sprite for more details about the X and Y position
    885  */
    886 inline void scroll_sprite(uint8_t nb, int8_t x, int8_t y) {
    887     uint8_t new_y = shadow_OAM[nb] + y;
    888     shadow_OAM[nb] = (new_y < VDP_SAT_TERM) ? new_y : 0xC0;
    889     shadow_OAM[0x40+(nb << 1)] += x;
    890 }
    891 
    892 
    893 /** Hides sprite number __nb__ by moving it to zero position by Y.
    894 
    895     @param nb  Sprite number, range 0 - 39
    896  */
    897 inline void hide_sprite(uint8_t nb) {
    898     shadow_OAM[nb] = 0xC0;
    899 }
    900 
    901 /**
    902  * Set byte in vram at given memory location
    903  *
    904  * @param addr address to write to
    905  * @param v value
    906  */
    907 void set_vram_byte(uint8_t * addr, uint8_t v) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
    908 
    909 /**
    910  * Set single tile t with attributes on background layer at x,y
    911  * @param x X-coordinate
    912  * @param y Y-coordinate
    913  * @param t tile index
    914  * @return returns the address of tile, so you may use faster set_vram_byte() later
    915  */
    916 uint8_t * set_attributed_tile_xy(uint8_t x, uint8_t y, uint16_t t) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
    917 
    918 /**
    919  * Set single tile t on background layer at x,y
    920  * @param x X-coordinate
    921  * @param y Y-coordinate
    922  * @param t tile index
    923  * @return returns the address of tile, so you may use faster set_vram_byte() later
    924  */
    925 uint8_t * set_tile_xy(uint8_t x, uint8_t y, uint8_t t) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
    926 #define set_bkg_tile_xy set_tile_xy
    927 #define set_win_tile_xy set_tile_xy
    928 
    929 /**
    930  * Set single tile attribute a on background layer at x,y
    931  * @param x X-coordinate
    932  * @param y Y-coordinate
    933  * @param a tile attributes
    934  * @return returns the address of tile attribute, so you may use faster set_vram_byte() later
    935  */
    936 uint8_t * set_attribute_xy(uint8_t x, uint8_t y, uint8_t a) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
    937 #define set_bkg_attribute_xy set_attribute_xy
    938 #define set_win_attribute_xy set_attribute_xy
    939 
    940 /**
    941  * Get address of X,Y tile of background map
    942  */
    943 uint8_t * get_bkg_xy_addr(uint8_t x, uint8_t y) PRESERVES_REGS(iyh, iyl);
    944 #define get_win_xy_addr get_bkg_xy_addr
    945 
    946 #endif /* _SMS_H */

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.