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/msx/msx.h

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