summaryrefslogtreecommitdiffstats
path: root/gbdk/gbdk-lib/include
diff options
context:
space:
mode:
Diffstat (limited to 'gbdk/gbdk-lib/include')
-rw-r--r--gbdk/gbdk-lib/include/asm/sm83/provides.h4
-rw-r--r--gbdk/gbdk-lib/include/asm/sm83/stdarg.h18
-rw-r--r--gbdk/gbdk-lib/include/asm/sm83/string.h150
-rw-r--r--gbdk/gbdk-lib/include/asm/sm83/types.h70
-rw-r--r--gbdk/gbdk-lib/include/asm/types.h90
-rw-r--r--gbdk/gbdk-lib/include/asm/z80/provides.h4
-rw-r--r--gbdk/gbdk-lib/include/asm/z80/stdarg.h18
-rw-r--r--gbdk/gbdk-lib/include/asm/z80/string.h144
-rw-r--r--gbdk/gbdk-lib/include/asm/z80/types.h76
-rw-r--r--gbdk/gbdk-lib/include/assert.h47
-rw-r--r--gbdk/gbdk-lib/include/ctype.h45
-rw-r--r--gbdk/gbdk-lib/include/gb/bcd.h61
-rw-r--r--gbdk/gbdk-lib/include/gb/bgb_emu.h13
-rw-r--r--gbdk/gbdk-lib/include/gb/cgb.h182
-rw-r--r--gbdk/gbdk-lib/include/gb/crash_handler.h25
-rw-r--r--gbdk/gbdk-lib/include/gb/drawing.h145
-rw-r--r--gbdk/gbdk-lib/include/gb/emu_debug.h13
-rw-r--r--gbdk/gbdk-lib/include/gb/gb.h1732
-rw-r--r--gbdk/gbdk-lib/include/gb/gbdecompress.h62
-rw-r--r--gbdk/gbdk-lib/include/gb/hardware.h420
-rw-r--r--gbdk/gbdk-lib/include/gb/isr.h74
-rw-r--r--gbdk/gbdk-lib/include/gb/metasprites.h245
-rw-r--r--gbdk/gbdk-lib/include/gb/sgb.h65
-rw-r--r--gbdk/gbdk-lib/include/gbdk/bcd.h12
-rw-r--r--gbdk/gbdk-lib/include/gbdk/console.h45
-rw-r--r--gbdk/gbdk-lib/include/gbdk/emu_debug.h179
-rw-r--r--gbdk/gbdk-lib/include/gbdk/far_ptr.h99
-rw-r--r--gbdk/gbdk-lib/include/gbdk/font.h78
-rw-r--r--gbdk/gbdk-lib/include/gbdk/gbdecompress.h12
-rw-r--r--gbdk/gbdk-lib/include/gbdk/gbdk-lib.h26
-rw-r--r--gbdk/gbdk-lib/include/gbdk/incbin.h84
-rw-r--r--gbdk/gbdk-lib/include/gbdk/metasprites.h14
-rw-r--r--gbdk/gbdk-lib/include/gbdk/platform.h16
-rw-r--r--gbdk/gbdk-lib/include/gbdk/rledecompress.h47
-rw-r--r--gbdk/gbdk-lib/include/gbdk/version.h6
-rw-r--r--gbdk/gbdk-lib/include/limits.h69
-rw-r--r--gbdk/gbdk-lib/include/msx/hardware.h201
-rw-r--r--gbdk/gbdk-lib/include/msx/metasprites.h118
-rw-r--r--gbdk/gbdk-lib/include/msx/msx.h751
-rw-r--r--gbdk/gbdk-lib/include/rand.h83
-rw-r--r--gbdk/gbdk-lib/include/setjmp.h83
-rw-r--r--gbdk/gbdk-lib/include/sms/gbdecompress.h24
-rw-r--r--gbdk/gbdk-lib/include/sms/hardware.h216
-rw-r--r--gbdk/gbdk-lib/include/sms/metasprites.h116
-rw-r--r--gbdk/gbdk-lib/include/sms/sms.h780
-rw-r--r--gbdk/gbdk-lib/include/stdarg.h12
-rw-r--r--gbdk/gbdk-lib/include/stdatomic.h21
-rw-r--r--gbdk/gbdk-lib/include/stdbool.h40
-rw-r--r--gbdk/gbdk-lib/include/stddef.h78
-rw-r--r--gbdk/gbdk-lib/include/stdint.h274
-rw-r--r--gbdk/gbdk-lib/include/stdio.h70
-rw-r--r--gbdk/gbdk-lib/include/stdlib.h143
-rw-r--r--gbdk/gbdk-lib/include/stdnoreturn.h7
-rw-r--r--gbdk/gbdk-lib/include/string.h17
-rw-r--r--gbdk/gbdk-lib/include/time.h38
-rw-r--r--gbdk/gbdk-lib/include/typeof.h54
-rw-r--r--gbdk/gbdk-lib/include/types.h25
57 files changed, 7541 insertions, 0 deletions
diff --git a/gbdk/gbdk-lib/include/asm/sm83/provides.h b/gbdk/gbdk-lib/include/asm/sm83/provides.h
new file mode 100644
index 00000000..8e297399
--- /dev/null
+++ b/gbdk/gbdk-lib/include/asm/sm83/provides.h
@@ -0,0 +1,4 @@
+#define USE_C_MEMCPY 0
+#define USE_C_STRCPY 0
+#define USE_C_STRCMP 0
+
diff --git a/gbdk/gbdk-lib/include/asm/sm83/stdarg.h b/gbdk/gbdk-lib/include/asm/sm83/stdarg.h
new file mode 100644
index 00000000..0c6e384e
--- /dev/null
+++ b/gbdk/gbdk-lib/include/asm/sm83/stdarg.h
@@ -0,0 +1,18 @@
+#ifndef ASM_SM83_STDARG_INCLUDE
+#define ASM_SM83_STDARG_INCLUDE
+
+/* sdcc pushes right to left with the real sizes, not cast up
+ to an int.
+ so printf(int, char, long)
+ results in push long, push char, push int
+ On the z80 the stack grows down, so the things seem to be in
+ the correct order.
+ */
+
+typedef unsigned char * va_list;
+#define va_start(list, last) list = (unsigned char *)&last + sizeof(last)
+#define va_arg(list, type) *((type *)((list += sizeof(type)) - sizeof(type)))
+
+#define va_end(list)
+
+#endif
diff --git a/gbdk/gbdk-lib/include/asm/sm83/string.h b/gbdk/gbdk-lib/include/asm/sm83/string.h
new file mode 100644
index 00000000..ceb9298a
--- /dev/null
+++ b/gbdk/gbdk-lib/include/asm/sm83/string.h
@@ -0,0 +1,150 @@
+/** @file string.h
+ Generic string functions.
+ */
+#ifndef STRING_INCLUDE
+#define STRING_INCLUDE
+
+#include <types.h>
+
+/** Copies the string pointed to by __src__ (including the terminating
+ `\0' character) to the array pointed to by __dest__.
+
+ The strings may not overlap, and the destination string dest must
+ be large enough to receive the copy.
+
+ @param dest Array to copy into
+ @param src Array to copy from
+
+ @return A pointer to dest
+*/
+char *strcpy(char *dest, const char *src) OLDCALL PRESERVES_REGS(b, c);
+
+/** Compares strings
+
+ @param s1 First string to compare
+ @param s2 Second string to compare
+
+ Returns:
+ \li > 0 if __s1__ > __s2__
+ \li 0 if __s1__ == __s2__
+ \li < 0 if __s1__ < __s2__
+*/
+int strcmp(const char *s1, const char *s2) OLDCALL PRESERVES_REGS(b, c);
+
+/** Copies n bytes from memory area src to memory area dest.
+
+ The memory areas may not overlap.
+
+ @param dest Buffer to copy into
+ @param src Buffer to copy from
+ @param len Number of Bytes to copy
+*/
+void *memcpy(void *dest, const void *src, size_t len);
+
+/** Copies n bytes from memory area src to memory area dest, areas may overlap
+ */
+void *memmove (void *dest, const void *src, size_t n);
+
+/** Fills the memory region __s__ with __n__ bytes using value __c__
+
+ @param s Buffer to fill
+ @param c char value to fill with (truncated from int)
+ @param n Number of bytes to fill
+*/
+void *memset (void *s, int c, size_t n) OLDCALL PRESERVES_REGS(b, c);
+
+/** Reverses the characters in a string
+
+ @param s Pointer to string to reverse.
+
+ For example 'abcdefg' will become 'gfedcba'.
+
+ Banked as the string must be modifiable.
+
+ Returns: Pointer to __s__
+*/
+char *reverse(char *s) OLDCALL PRESERVES_REGS(b, c);
+
+/** Concatenate Strings. Appends string __s2__ to the end of string __s1__
+
+ @param s1 String to append onto
+ @param s2 String to copy from
+
+ For example 'abc' and 'def' will become 'abcdef'.
+
+ String __s1__ must be large enough to store both __s1__ and __s2__.
+
+ Returns: Pointer to __s1__
+*/
+char *strcat(char *s1, const char *s2);
+
+/** Calculates the length of a string
+
+ @param s String to calculate length of
+
+ Returns: Length of string not including the terminating `\0' character.
+*/
+int strlen(const char *s) OLDCALL PRESERVES_REGS(b, c);
+
+/**Concatenate at most __n__ characters from string __s2__ onto the end of __s1__.
+
+ @param s1 String to append onto
+ @param s2 String to copy from
+ @param n Max number of characters to copy from __s2__
+
+ String __s1__ must be large enough to store both __s1__ and __n__ characters of __s2__
+
+ Returns: Pointer to __s1__
+*/
+char *strncat(char *s1, const char *s2, int n);
+
+/** Compare strings (at most __n__ characters):
+
+ @param s1 First string to compare
+ @param s2 Second string to compare
+ @param n Max number of characters to compare
+
+ Returns zero if the strings are identical, or non-zero
+ if they are not (see below).
+
+ Returns:
+ \li > 0 if __s1__ > __s2__ (at first non-matching byte)
+ \li 0 if __s1__ == __s2__
+ \li < 0 if __s1__ < __s2__ (at first non-matching byte)
+*/
+int strncmp(const char *s1, const char *s2, int n);
+
+/** Copy __n__ characters from string __s2__ to __s1__
+
+
+ @param s1 String to copy into
+ @param s2 String to copy from
+ @param n Max number of characters to copy from __s2__
+
+ If __s2__ is shorter than __n__, the remaining
+ bytes in __s1__ are filled with \0.
+
+ Warning: If there is no \0 in the first __n__ bytes of __s2__ then __s1__
+ will not be null terminated.
+
+ Returns: Pointer to __s1__
+*/
+char *strncpy(char *s1, const char *s2, int n);
+
+/** Compare up to __count__ bytes in buffers __buf1__ and __buf2__
+
+ @param buf1 Pointer to First buffer to compare
+ @param buf2 Pointer to Second buffer to compare
+ @param count Max number of bytes to compare
+
+ Returns zero if the buffers are identical, or non-zero
+ if they are not (see below).
+
+ Returns:
+ \li > 0 if __buf1__ > __buf2__ (at first non-matching byte)
+ \li 0 if __buf1__ == __buf2__
+ \li < 0 if __buf1__ < __buf2__ (at first non-matching byte)
+*/
+int memcmp(const void *buf1, const void *buf2, size_t count) OLDCALL;
+
+#endif
diff --git a/gbdk/gbdk-lib/include/asm/sm83/types.h b/gbdk/gbdk-lib/include/asm/sm83/types.h
new file mode 100644
index 00000000..f6e7e101
--- /dev/null
+++ b/gbdk/gbdk-lib/include/asm/sm83/types.h
@@ -0,0 +1,70 @@
+/** @file asm/sm83/types.h
+ @anchor file_asm_sm83_types_h
+ Types definitions for the gb.
+*/
+#ifndef ASM_SM83_TYPES_INCLUDE
+#define ASM_SM83_TYPES_INCLUDE
+
+#ifndef __PORT_sm83
+ #error sm83 only.
+#endif
+
+#ifdef __SDCC
+
+#define NONBANKED __nonbanked /**< Placed in the non-banked lower 16K region (bank 0), regardless of the bank selected by it's source file. */
+#define BANKED __banked /**< The function will use banked sdcc calls, and is placed in the bank selected by it's source file (or compiler switches). */
+
+/** Use to create a block of of code which should execute with interrupts temporarily turned off.
+
+ __Do not__ use @ref CRITICAL and @ref INTERRUPT attributes for a
+ function added via add_VBL() (or LCD, etc). The attributes
+ are only required when constructing a bare jump from the
+ interrupt vector itself.
+
+ @see enable_interrupts, disable_interrupts
+*/
+#define CRITICAL __critical
+
+/** Indicate to the compiler the function will be used as an interrupt handler.
+
+ __Do not__ use @ref CRITICAL and @ref INTERRUPT attributes for a
+ function added via add_VBL() (or LCD, etc). The attributes
+ are only required when constructing a bare jump from the
+ interrupt vector itself.
+
+ @see ISR_VECTOR(), ISR_NESTED_VECTOR()
+*/
+#define INTERRUPT __interrupt
+
+#endif
+
+/** Signed eight bit.
+ */
+typedef signed char INT8;
+/** Unsigned eight bit.
+ */
+typedef unsigned char UINT8;
+/** Signed sixteen bit.
+ */
+typedef signed int INT16;
+/** Unsigned sixteen bit.
+ */
+typedef unsigned int UINT16;
+/** Signed 32 bit.
+ */
+typedef signed long INT32;
+/** Unsigned 32 bit.
+ */
+typedef unsigned long UINT32;
+
+#ifndef __SIZE_T_DEFINED
+#define __SIZE_T_DEFINED
+typedef unsigned int size_t;
+#endif
+
+/** Returned from clock
+ @see clock
+*/
+typedef unsigned int clock_t;
+
+#endif
diff --git a/gbdk/gbdk-lib/include/asm/types.h b/gbdk/gbdk-lib/include/asm/types.h
new file mode 100644
index 00000000..5ed75f45
--- /dev/null
+++ b/gbdk/gbdk-lib/include/asm/types.h
@@ -0,0 +1,90 @@
+/** @file asm/types.h
+ Shared types definitions.
+*/
+#ifndef ASM_TYPES_INCLUDE
+#define ASM_TYPES_INCLUDE
+
+#if defined(__PORT_sm83)
+#include <asm/sm83/types.h>
+#elif defined(__PORT_z80)
+#include <asm/z80/types.h>
+#else
+#error Unrecognised port
+#endif
+
+#ifndef OLDCALL
+#if __SDCC_REVISION >= 12608
+#define OLDCALL __sdcccall(0)
+#else
+#define OLDCALL
+#endif
+#endif
+
+#ifdef __SDCC
+#define PRESERVES_REGS(...) __preserves_regs(__VA_ARGS__)
+#define NAKED __naked
+#define SFR __sfr
+#define AT(A) __at(A)
+#else
+#define PRESERVES_REGS(...)
+#define NAKED
+#define SFR
+#define AT(A)
+#endif
+
+#ifndef NONBANKED
+#define NONBANKED
+#endif
+#ifndef BANKED
+#define BANKED
+#endif
+#ifndef CRITICAL
+#define CRITICAL
+#endif
+#ifndef INTERRUPT
+#define INTERRUPT
+#endif
+
+/** TRUE or FALSE.
+ @anchor file_asm_types_h
+ */
+typedef INT8 BOOLEAN;
+
+/** Signed 8 bit.
+ */
+typedef INT8 BYTE;
+/** Unsigned 8 bit.
+ */
+typedef UINT8 UBYTE;
+/** Signed 16 bit */
+typedef INT16 WORD;
+/** Unsigned 16 bit */
+typedef UINT16 UWORD;
+/** Signed 32 bit */
+typedef INT32 LWORD;
+/** Unsigned 32 bit */
+typedef UINT32 ULWORD;
+/** Signed 32 bit */
+typedef INT32 DWORD;
+/** Unsigned 32 bit */
+typedef UINT32 UDWORD;
+
+/** Useful definition for working with 8 bit + 8 bit fixed point values
+
+ Use `.w` to access the variable as unsigned 16 bit type.
+
+ Use `.b.h` and `.b.l` (or just `.h` and `.l`) to directly access it's high and low unsigned 8 bit values.
+ */
+typedef union _fixed {
+ struct {
+ UBYTE l;
+ UBYTE h;
+ };
+ struct {
+ UBYTE l;
+ UBYTE h;
+ } b;
+ UWORD w;
+} fixed;
+
+#endif
diff --git a/gbdk/gbdk-lib/include/asm/z80/provides.h b/gbdk/gbdk-lib/include/asm/z80/provides.h
new file mode 100644
index 00000000..d7aa1956
--- /dev/null
+++ b/gbdk/gbdk-lib/include/asm/z80/provides.h
@@ -0,0 +1,4 @@
+#define USE_C_MEMCPY 0
+#define USE_C_STRCPY 0
+#define USE_C_STRCMP 1
+
diff --git a/gbdk/gbdk-lib/include/asm/z80/stdarg.h b/gbdk/gbdk-lib/include/asm/z80/stdarg.h
new file mode 100644
index 00000000..a82642fe
--- /dev/null
+++ b/gbdk/gbdk-lib/include/asm/z80/stdarg.h
@@ -0,0 +1,18 @@
+#ifndef ASM_Z80_STDARG_INCLUDE
+#define ASM_Z80_STDARG_INCLUDE
+
+/* sdcc pushes right to left with the real sizes, not cast up
+ to an int.
+ so printf(int, char, long)
+ results in push long, push char, push int
+ On the z80 the stack grows down, so the things seem to be in
+ the correct order.
+ */
+
+typedef unsigned char * va_list;
+#define va_start(list, last) list = (unsigned char *)&last + sizeof(last)
+#define va_arg(list, type) *((type *)((list += sizeof(type)) - sizeof(type)))
+
+#define va_end(list)
+
+#endif
diff --git a/gbdk/gbdk-lib/include/asm/z80/string.h b/gbdk/gbdk-lib/include/asm/z80/string.h
new file mode 100644
index 00000000..0d4b2e01
--- /dev/null
+++ b/gbdk/gbdk-lib/include/asm/z80/string.h
@@ -0,0 +1,144 @@
+/** @file string.h
+ Generic string functions.
+ */
+#ifndef STRING_INCLUDE
+#define STRING_INCLUDE
+
+#include <types.h>
+
+/** Copies the string pointed to by __src__ (including the terminating
+ `\0' character) to the array pointed to by __dest__.
+
+ The strings may not overlap, and the destination string dest must
+ be large enough to receive the copy.
+
+ @param dest Array to copy into
+ @param src Array to copy from
+
+ @return A pointer to dest
+*/
+char *strcpy(char *dest, const char *src) OLDCALL;
+
+/** Compares strings
+
+ @param s1 First string to compare
+ @param s2 Second string to compare
+
+ Returns:
+ \li > 0 if __s1__ > __s2__
+ \li 0 if __s1__ == __s2__
+ \li < 0 if __s1__ < __s2__
+*/
+int strcmp(const char *s1, const char *s2);
+
+/** Copies n bytes from memory area src to memory area dest.
+
+ The memory areas may not overlap.
+
+ @param dest Buffer to copy into
+ @param src Buffer to copy from
+ @param len Number of Bytes to copy
+*/
+void *memcpy(void *dest, const void *src, size_t len);
+
+/** Copies n bytes from memory area src to memory area dest, areas may overlap
+ */
+void *memmove (void *dest, const void *src, size_t n) OLDCALL;
+
+/** Fills the memory region __s__ with __n__ bytes using value __c__
+
+ @param s Buffer to fill
+ @param c char value to fill with (truncated from int)
+ @param n Number of bytes to fill
+*/
+void *memset (void *s, int c, size_t n) Z88DK_CALLEE;
+
+/** Reverses the characters in a string
+
+ @param s Pointer to string to reverse.
+
+ For example 'abcdefg' will become 'gfedcba'.
+
+ Banked as the string must be modifiable.
+
+ Returns: Pointer to __s__
+*/
+char *reverse(char *s) NONBANKED;
+
+/** Concatenate Strings. Appends string __s2__ to the end of string __s1__
+
+ @param s1 String to append onto
+ @param s2 String to copy from
+
+ For example 'abc' and 'def' will become 'abcdef'.
+
+ String __s1__ must be large enough to store both __s1__ and __s2__.
+
+ Returns: Pointer to __s1__
+*/
+char *strcat(char *s1, const char *s2) NONBANKED;
+
+/** Calculates the length of a string
+
+ @param s String to calculate length of
+
+ Returns: Length of string not including the terminating `\0' character.
+*/
+int strlen(const char *s) OLDCALL;
+
+/**Concatenate at most __n__ characters from string __s2__ onto the end of __s1__.
+
+ @param s1 String to append onto
+ @param s2 String to copy from
+ @param n Max number of characters to copy from __s2__
+
+ String __s1__ must be large enough to store both __s1__ and __n__ characters of __s2__
+
+ Returns: Pointer to __s1__
+*/
+char *strncat(char *s1, const char *s2, int n) NONBANKED;
+
+/** Compare strings (at most n characters):
+
+ @param s1 First string to compare
+ @param s2 Second string to compare
+ @param n Max number of characters to compare
+
+ Returns:
+ \li > 0 if __s1__ > __s2__
+ \li 0 if __s1__ == __s2__
+ \li < 0 if __s1__ < __s2__
+*/
+int strncmp(const char *s1, const char *s2, int n) NONBANKED;
+
+/** Copy __n__ characters from string __s2__ to __s1__
+
+
+ @param s1 String to copy into
+ @param s2 String to copy from
+ @param n Max number of characters to copy from __s2__
+
+ If __s2__ is shorter than __n__, the remaining
+ bytes in __s1__ are filled with \0.
+
+ Warning: If there is no \0 in the first __n__ bytes of __s2__ then __s1__
+ will not be null terminated.
+
+ Returns: Pointer to __s1__
+*/
+char *strncpy(char *s1, const char *s2, int n) NONBANKED;
+
+/** Compares buffers
+
+ @param buf1 First buffer to compare
+ @param buf2 Second buffer to compare
+ @param count Buffer length
+
+ Returns:
+ \li > 0 if __buf1__ > __buf2__
+ \li 0 if __buf1__ == __buf2__
+ \li < 0 if __buf1__ < __buf2__
+*/
+int memcmp(const void *buf1, const void *buf2, size_t count) Z88DK_CALLEE;
+
+#endif
diff --git a/gbdk/gbdk-lib/include/asm/z80/types.h b/gbdk/gbdk-lib/include/asm/z80/types.h
new file mode 100644
index 00000000..bb9dc160
--- /dev/null
+++ b/gbdk/gbdk-lib/include/asm/z80/types.h
@@ -0,0 +1,76 @@
+/** @file asm/z80/types.h
+ @anchor file_asm_z80_types_h
+ Types definitions for the gb.
+*/
+#ifndef ASM_Z80_TYPES_INCLUDE
+#define ASM_Z80_TYPES_INCLUDE
+
+#ifndef __PORT_z80
+ #error z80 only.
+#endif
+
+#ifdef __SDCC
+
+#define Z88DK_CALLEE __sdcccall(0) __z88dk_callee
+#define Z88DK_FASTCALL __z88dk_fastcall
+
+#define NONBANKED __nonbanked /**< Placed in the non-banked lower 16K region (bank 0), regardless of the bank selected by it's source file. */
+#define BANKED __banked /**< The function will use banked sdcc calls, and is placed in the bank selected by it's source file (or compiler switches). */
+
+/** Use to create a block of of code which should execute with interrupts temporarily turned off.
+
+ __Do not__ use @ref CRITICAL and @ref INTERRUPT attributes for a
+ function added via add_VBL() (or LCD, etc). The attributes
+ are only required when constructing a bare jump from the
+ interrupt vector itself.
+
+ @see enable_interrupts, disable_interrupts
+*/
+#define CRITICAL __critical
+
+/** Indicate to the compiler the function will be used as an interrupt handler.
+
+ __Do not__ use @ref CRITICAL and @ref INTERRUPT attributes for a
+ function added via add_VBL() (or LCD, etc). The attributes
+ are only required when constructing a bare jump from the
+ interrupt vector itself.
+*/
+#define INTERRUPT __interrupt
+
+#else
+
+#define Z88DK_CALLEE
+#define Z88DK_FASTCALL
+
+#endif
+
+/** Signed eight bit.
+ */
+typedef signed char INT8;
+/** Unsigned eight bit.
+ */
+typedef unsigned char UINT8;
+/** Signed sixteen bit.
+ */
+typedef signed int INT16;
+/** Unsigned sixteen bit.
+ */
+typedef unsigned int UINT16;
+/** Signed 32 bit.
+ */
+typedef signed long INT32;
+/** Unsigned 32 bit.
+ */
+typedef unsigned long UINT32;
+
+#ifndef __SIZE_T_DEFINED
+#define __SIZE_T_DEFINED
+typedef unsigned int size_t;
+#endif
+
+/** Returned from clock
+ @see clock
+*/
+typedef unsigned int clock_t;
+
+#endif
diff --git a/gbdk/gbdk-lib/include/assert.h b/gbdk/gbdk-lib/include/assert.h
new file mode 100644
index 00000000..6a62a5e6
--- /dev/null
+++ b/gbdk/gbdk-lib/include/assert.h
@@ -0,0 +1,47 @@
+/*-------------------------------------------------------------------------
+ assert.h - header file for assert ANSI routine
+
+ Copyright (C) 2018, Philipp Klaus Krause . pkk@spth.de
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ As a special exception, if you link this library with other files,
+ some of which are compiled with SDCC, to produce an executable,
+ this library does not by itself cause the resulting executable to
+ be covered by the GNU General Public License. This exception does
+ not however invalidate any other reasons why the executable file
+ might be covered by the GNU General Public License.
+-------------------------------------------------------------------------*/
+
+#undef assert
+
+#ifdef NDEBUG
+
+/* Debugging disabled -- do not evaluate assertions. */
+#define assert(x) ((void)0)
+
+#else
+
+/* Debugging enabled -- verify assertions at run time. */
+void __assert(const char *expression, const char *functionname, const char *filename, unsigned int linenumber);
+#define assert(x) ((x) ? (void)0 : __assert(#x, __func__, __FILE__, __LINE__))
+
+#if __STDC_VERSION__ >= 201112L
+#define static_assert _Static_assert
+#endif
+
+#endif
+
diff --git a/gbdk/gbdk-lib/include/ctype.h b/gbdk/gbdk-lib/include/ctype.h
new file mode 100644
index 00000000..91f9c8ec
--- /dev/null
+++ b/gbdk/gbdk-lib/include/ctype.h
@@ -0,0 +1,45 @@
+/** @file ctype.h
+ Character type functions.
+*/
+#ifndef _CTYPE_H
+#define _CTYPE_H
+
+#include <types.h>
+#include <stdbool.h>
+
+/** Returns TRUE if the character __c__ is a letter (a-z, A-Z), otherwise FALSE
+ @param c Character to test
+*/
+bool isalpha(char c);
+
+/** Returns TRUE if the character __c__ is an uppercase letter (A-Z), otherwise FALSE
+ @param c Character to test
+*/
+bool isupper(char c);
+
+/** Returns TRUE if the character __c__ is a lowercase letter (a-z), otherwise FALSE
+ @param c Character to test
+*/
+bool islower(char c);
+
+/** Returns TRUE if the character __c__ is a digit (0-9), otherwise FALSE
+ @param c Character to test
+*/
+bool isdigit(char c);
+
+/** Returns TRUE if the character __c__ is a space (' '), tab (\\t), or newline (\\n) character, otherwise FALSE
+ @param c Character to test
+*/
+bool isspace(char c);
+
+/** Returns uppercase version of character __c__ if it is a letter (a-z), otherwise it returns the input value unchanged.
+ @param c Character to test
+*/
+char toupper(char c);
+
+/** Returns lowercase version of character __c__ if it is a letter (A-Z), otherwise it returns the input value unchanged.
+ @param c Character to test
+*/
+char tolower(char c);
+
+#endif /* _CTYPE_H */
diff --git a/gbdk/gbdk-lib/include/gb/bcd.h b/gbdk/gbdk-lib/include/gb/bcd.h
new file mode 100644
index 00000000..4f3f0049
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/bcd.h
@@ -0,0 +1,61 @@
+#ifndef __BCD_H_INCLUDE
+#define __BCD_H_INCLUDE
+
+#include <types.h>
+#include <stdint.h>
+
+/** @file bcd.h
+ Support for working with BCD (Binary Coded Decimal)
+
+ See the example BCD project for additional details.
+*/
+
+// macro for creating BCD constants
+#define BCD_HEX(v) ((BCD)(v))
+
+/** Converts an integer value into BCD format
+
+ A maximum of 8 digits may be used
+*/
+#define MAKE_BCD(v) BCD_HEX(0x ## v)
+
+typedef uint32_t BCD;
+
+/** Converts integer __i__ into BCD format (Binary Coded Decimal)
+ @param i Numeric value to convert
+ @param value Pointer to a BCD variable to store the converted result
+*/
+void uint2bcd(uint16_t i, BCD * value) OLDCALL;
+
+/** Adds two numbers in BCD format: __sour__ += __value__
+ @param sour Pointer to a BCD value to add to (and where the result is stored)
+ @param value Pointer to the BCD value to add to __sour__
+*/
+void bcd_add(BCD * sour, const BCD * value) OLDCALL;
+
+/** Subtracts two numbers in BCD format: __sour__ -= __value__
+ @param sour Pointer to a BCD value to subtract from (and where the result is stored)
+ @param value Pointer to the BCD value to subtract from __sour__
+*/
+void bcd_sub(BCD * sour, const BCD * value) OLDCALL;
+
+/** Convert a BCD number into an asciiz (null terminated) string and return the length
+ @param bcd Pointer to BCD value to convert
+ @param tile_offset Optional per-character offset value to add (use 0 for none)
+ @param buffer Buffer to store the result in
+
+ Returns: Length in characters (always 8)
+
+ __buffer__ should be large enough to store the converted string
+ (9 bytes: 8 characters + 1 for terminator)
+
+ There are a couple different ways to use __tile_offset__.
+ For example:
+ \li It can be the Index of the Font Tile '0' in VRAM to
+ allow the buffer to be used directly with @ref set_bkg_tiles.
+ \li It can also be set to the ascii value for character '0'
+ so that the buffer is a normal string that can be passed to @ref printf.
+*/
+uint8_t bcd2text(const BCD * bcd, uint8_t tile_offset, uint8_t * buffer) OLDCALL;
+
+#endif
diff --git a/gbdk/gbdk-lib/include/gb/bgb_emu.h b/gbdk/gbdk-lib/include/gb/bgb_emu.h
new file mode 100644
index 00000000..77f204ba
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/bgb_emu.h
@@ -0,0 +1,13 @@
+/** @file gb/bgb_emu.h
+
+ Shim for legacy use of @ref bgb_emu.h which has been
+ migrated to @ref emu_debug.h
+
+ See the `emu_debug` example project included with gbdk.
+*/
+#ifndef __BGB_EMU_INCLUDE
+#define __BGB_EMU_INCLUDE
+
+#include <gbdk/emu_debug.h>
+
+#endif
diff --git a/gbdk/gbdk-lib/include/gb/cgb.h b/gbdk/gbdk-lib/include/gb/cgb.h
new file mode 100644
index 00000000..7cbded42
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/cgb.h
@@ -0,0 +1,182 @@
+/** @file gb/cgb.h
+ Support for the Color GameBoy (CGB).
+
+ __Enabling CGB features__
+
+ To unlock and use CGB features and registers you need to
+ change byte 0143h in the cartridge header. Otherwise, the CGB
+ will operate in monochrome "Non CGB" compatibility mode.
+ \li Use a value of __80h__ for games that support CGB and monochrome gameboys
+ \n (with Lcc: __-Wm-yc__, or makebin directly: __-yc__)
+ \li Use a value of __C0h__ for CGB only games.
+ \n (with Lcc: __-Wm-yC__, or makebin directly: __-yC__)
+
+ See the Pan Docs for more information CGB features.
+*/
+
+#ifndef _CGB_H
+#define _CGB_H
+
+#include <types.h>
+#include <stdint.h>
+
+/** Macro to create a CGB palette color entry out of 5-bit color components.
+
+ @param r 5-bit Red Component, range 0 - 31 (31 brightest)
+ @param g 5-bit Green Component, range 0 - 31 (31 brightest)
+ @param b 5-bit Blue Component, range 0 - 31 (31 brightest)
+
+ The resulting format is bitpacked BGR-555 in a uint16_t.
+
+ @see set_bkg_palette(), set_sprite_palette(), RGB8(), RGBHTML()
+ */
+#define RGB(r, g, b) ((((uint16_t)(b) & 0x1f) << 10) | (((uint16_t)(g) & 0x1f) << 5) | (((uint16_t)(r) & 0x1f) << 0))
+
+/** Macro to create a CGB palette color entry out of 8-bit color components.
+
+ @param r 8-bit Red Component, range 0 - 255 (255 brightest)
+ @param g 8-bit Green Component, range 0 - 255 (255 brightest)
+ @param b 8-bit Blue Component, range 0 - 255 (255 brightest)
+
+ The resulting format is bitpacked BGR-555 in a uint16_t.
+
+ The lowest 3 bits of each color component are dropped during conversion.
+
+ @see set_bkg_palette(), set_sprite_palette(), RGB(), RGBHTML()
+ */
+#define RGB8(r, g, b) ((uint16_t)((r) >> 3) | ((uint16_t)((g) >> 3) << 5) | ((uint16_t)((b) >> 3) << 10))
+
+/** Macro to convert a 24 Bit RGB color to a CGB palette color entry.
+
+ @param RGB24bit Bit packed RGB-888 color (0-255 for each color component).
+
+ The resulting format is bitpacked BGR-555 in a uint16_t.
+
+ The lowest 3 bits of each color component are dropped during conversion.
+
+ @see set_bkg_palette(), set_sprite_palette(), RGB(), RGB8()
+ */
+#define RGBHTML(RGB24bit) (RGB8((((RGB24bit) >> 16) & 0xFF), (((RGB24bit) >> 8) & 0xFF), ((RGB24bit) & 0xFF)))
+
+/** Common colors based on the EGA default palette.
+ */
+#define RGB_RED RGB(31, 0, 0)
+#define RGB_DARKRED RGB(15, 0, 0)
+#define RGB_GREEN RGB( 0, 31, 0)
+#define RGB_DARKGREEN RGB( 0, 15, 0)
+#define RGB_BLUE RGB( 0, 0, 31)
+#define RGB_DARKBLUE RGB( 0, 0, 15)
+#define RGB_YELLOW RGB(31, 31, 0)
+#define RGB_DARKYELLOW RGB(21, 21, 0)
+#define RGB_CYAN RGB( 0, 31, 31)
+#define RGB_AQUA RGB(28, 5, 22)
+#define RGB_PINK RGB(31, 0, 31)
+#define RGB_PURPLE RGB(21, 0, 21)
+#define RGB_BLACK RGB( 0, 0, 0)
+#define RGB_DARKGRAY RGB(10, 10, 10)
+#define RGB_LIGHTGRAY RGB(21, 21, 21)
+#define RGB_WHITE RGB(31, 31, 31)
+
+#define RGB_LIGHTFLESH RGB(30, 20, 15)
+#define RGB_BROWN RGB(10, 10, 0)
+#define RGB_ORANGE RGB(30, 20, 0)
+#define RGB_TEAL RGB(15, 15, 0)
+
+typedef uint16_t palette_color_t; /**< 16 bit color entry */
+
+/** Set CGB background palette(s).
+
+ @param first_palette Index of the first palette to write (0-7)
+ @param nb_palettes Number of palettes to write (1-8, max depends on first_palette)
+ @param rgb_data Pointer to source palette data
+
+ Writes __nb_palettes__ to background palette data starting
+ at __first_palette__, Palette data is sourced from __rgb_data__.
+
+ \li Each Palette is 8 bytes in size: 4 colors x 2 bytes per palette color entry.
+ \li Each color (4 per palette) is packed as BGR-555 format (1:5:5:5, MSBit [15] is unused).
+ \li Each component (R, G, B) may have values from 0 - 31 (5 bits), 31 is brightest.
+
+ @see RGB(), set_bkg_palette_entry()
+ */
+void set_bkg_palette(uint8_t first_palette, uint8_t nb_palettes, palette_color_t *rgb_data) OLDCALL;
+
+/** Set CGB sprite palette(s).
+
+ @param first_palette Index of the first palette to write (0-7)
+ @param nb_palettes Number of palettes to write (1-8, max depends on first_palette)
+ @param rgb_data Pointer to source palette data
+
+ Writes __nb_palettes__ to sprite palette data starting
+ at __first_palette__, Palette data is sourced from __rgb_data__.
+
+ \li Each Palette is 8 bytes in size: 4 colors x 2 bytes per palette color entry.
+ \li Each color (4 per palette) is packed as BGR-555 format (1:5:5:5, MSBit [15] is unused).
+ \li Each component (R, G, B) may have values from 0 - 31 (5 bits), 31 is brightest.
+
+ @see RGB(), set_sprite_palette_entry()
+ */
+void set_sprite_palette(uint8_t first_palette, uint8_t nb_palettes, palette_color_t *rgb_data) OLDCALL;
+
+/** Sets a single color in the specified CGB background palette.
+
+ @param palette Index of the palette to modify (0-7)
+ @param entry Index of color in palette to modify (0-3)
+ @param rgb_data New color data in BGR 15bpp format.
+
+ @see set_bkg_palette(), RGB()
+ */
+
+void set_bkg_palette_entry(uint8_t palette, uint8_t entry, uint16_t rgb_data) OLDCALL;
+
+/** Sets a single color in the specified CGB sprite palette.
+
+ @param palette Index of the palette to modify (0-7)
+ @param entry Index of color in palette to modify (0-3)
+ @param rgb_data New color data in BGR 15bpp format.
+
+ @see set_sprite_palette(), RGB()
+ */
+void set_sprite_palette_entry(uint8_t palette, uint8_t entry, uint16_t rgb_data) OLDCALL;
+
+/** Set CPU speed to slow (Normal Speed) operation.
+
+ Interrupts are temporarily disabled and then re-enabled during this call.
+
+ In this mode the CGB operates at the same speed as the DMG/Pocket/SGB models.
+
+ \li You can check to see if @ref _cpu == @ref CGB_TYPE before using this function.
+
+ @see cpu_fast()
+ */
+void cpu_slow();
+
+/** Set CPU speed to fast (CGB Double Speed) operation.
+
+ On startup the CGB operates in Normal Speed Mode and can be switched
+ into Double speed mode (faster processing but also higher power consumption).
+ See the Pan Docs for more information about which hardware features
+ operate faster and which remain at Normal Speed.
+
+ \li Interrupts are temporarily disabled and then re-enabled during this call.
+ \li You can check to see if @ref _cpu == @ref CGB_TYPE before using this function.
+
+ @see cpu_slow(), _cpu
+*/
+void cpu_fast();
+
+/** Set palette, compatible with the DMG/GBP.
+
+ The default/first CGB palettes for sprites and backgrounds are
+ set to a similar default appearance as on the DMG/Pocket/SGB models.
+ (White, Light Gray, Dark Gray, Black)
+
+ \li You can check to see if @ref _cpu == @ref CGB_TYPE before using this function.
+ */
+void set_default_palette();
+
+/** This function is obsolete
+ */
+void cgb_compatibility();
+
+#endif /* _CGB_H */
diff --git a/gbdk/gbdk-lib/include/gb/crash_handler.h b/gbdk/gbdk-lib/include/gb/crash_handler.h
new file mode 100644
index 00000000..5c82b37c
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/crash_handler.h
@@ -0,0 +1,25 @@
+/** @file gb/crash_handler.h
+
+ When crash_handler.h is included, a crash dump screen
+ will be displayed if the CPU executes uninitalized
+ memory (with a value of 0xFF, the opcode for RST 38).
+ A handler is installed for RST 38 that calls
+ @ref __HandleCrash().
+
+ \code{.c}
+ #include <gb/crash_handler.h>
+ \endcode
+
+ Also see the `crash` example project included with gbdk.
+*/
+#ifndef __CRASH_HANDLER_INCLUDE
+#define __CRASH_HANDLER_INCLUDE
+
+/** Display the crash dump screen.
+
+ See the intro for this file for more details.
+*/
+void __HandleCrash();
+static void * __CRASH_HANDLER_INIT = &__HandleCrash;
+
+#endif \ No newline at end of file
diff --git a/gbdk/gbdk-lib/include/gb/drawing.h b/gbdk/gbdk-lib/include/gb/drawing.h
new file mode 100644
index 00000000..bc53d042
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/drawing.h
@@ -0,0 +1,145 @@
+/** @file gb/drawing.h
+ All Points Addressable (APA) mode drawing library.
+
+ Drawing routines originally by Pascal Felber
+ Legendary overhall by Jon Fuge <jonny@q-continuum.demon.co.uk>
+ Commenting by Michael Hope
+
+ Note: The standard text printf() and putchar() cannot be used
+ in APA mode - use gprintf() and wrtchr() instead.
+
+ Note: Using drawing.h will cause it's custom VBL and LCD ISRs
+ (`drawing_vbl` and `drawing_lcd`) to be installed. Changing
+ the mode (`mode(M_TEXT_OUT);`) will cause them to be de-installed.
+
+ The valid coordinate ranges are from (x,y) 0,0 to 159,143.
+ There is no built-in clipping, so drawing outside valid
+ coordinates will likely produce undesired results (wrapping/etc).
+
+ ----
+
+ __Important note for the drawing API :__
+
+ The Game Boy graphics hardware is not well suited to frame-buffer
+ style graphics such as the kind provided in `drawing.h`.
+ Due to that, __most drawing functions (rectangles, circles, etc) will
+ be slow__ . When possible it's much faster and more efficient
+ to work with the tiles and tile maps that the Game Boy hardware is
+ built around.
+*/
+#ifndef __DRAWING_H
+#define __DRAWING_H
+
+#include <types.h>
+#include <stdint.h>
+
+/** Size of the screen in pixels */
+#define GRAPHICS_WIDTH 160
+#define GRAPHICS_HEIGHT 144
+
+#define SOLID 0x00 /* Overwrites the existing pixels */
+#define OR 0x01 /* Performs a logical OR */
+#define XOR 0x02 /* Performs a logical XOR */
+#define AND 0x03 /* Performs a logical AND */
+
+/** Possible drawing colours */
+#define WHITE 0
+#define LTGREY 1
+#define DKGREY 2
+#define BLACK 3
+
+/** Possible fill styles for box() and circle() */
+#define M_NOFILL 0
+#define M_FILL 1
+
+/** Possible values for signed_value in gprintln() and gprintn() */
+#define SIGNED 1
+#define UNSIGNED 0
+
+#include <types.h>
+
+/** Print the string 'str' with no interpretation
+ @see gotogxy()
+*/
+void gprint(char *str) NONBANKED;
+
+/** Print 16 bit __number__ in __radix__ (base) in the default font at the current text position.
+
+ @param number number to print
+ @param radix radix (base) to print with
+ @param signed_value should be set to SIGNED or UNSIGNED depending on whether the number is signed or not
+
+ The current position is advanced by the numer of characters printed.
+ @see gotogxy()
+*/
+void gprintln(int16_t number, int8_t radix, int8_t signed_value) NONBANKED;
+
+/** Print 8 bit __number__ in __radix__ (base) in the default font at the current text position.
+
+ @see gprintln(), gotogxy()
+*/
+void gprintn(int8_t number, int8_t radix, int8_t signed_value) NONBANKED;
+
+/** Print the string and arguments given by __fmt__ with arguments __...__
+
+ @param fmt The format string as per printf
+ @param ... params
+
+ Currently supported:
+ \li \%c (character)
+ \li \%u (int)
+ \li \%d (int8_t)
+ \li \%o (int8_t as octal)
+ \li \%x (int8_t as hex)
+ \li \%s (string)
+
+ @return Returns the number of items printed, or -1 if there was an error.
+ @see gotogxy()
+*/
+int8_t gprintf(char *fmt,...) NONBANKED;
+
+/** Old style plot - try @ref plot_point() */
+void plot(uint8_t x, uint8_t y, uint8_t colour, uint8_t mode) OLDCALL;
+
+/** Plot a point in the current drawing mode and colour at __x,y__ */
+void plot_point(uint8_t x, uint8_t y) OLDCALL;
+
+/** Exchanges the tile on screen at x,y with the tile pointed by src, original tile
+ is saved in dst. Both src and dst may be NULL - saving or copying to screen is
+ not performed in this case. */
+void switch_data(uint8_t x, uint8_t y, uint8_t *src, uint8_t *dst) OLDCALL;
+
+/** Draw a full screen image at __data__ */
+void draw_image(uint8_t *data) OLDCALL;
+
+/** Draw a line in the current drawing mode and colour from __x1,y1__ to __x2,y2__ */
+void line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) OLDCALL;
+
+/** Draw a box (rectangle) with corners __x1,y1__ and __x2,y2__ using fill mode
+ __style__ (one of NOFILL or FILL) */
+void box(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t style) OLDCALL;
+
+/** Draw a circle with centre at __x,y__ and __radius__ using fill mode
+ __style__ (one of NOFILL or FILL)*/
+void circle(uint8_t x, uint8_t y, uint8_t radius, uint8_t style) OLDCALL;
+
+/** Returns the current colour of the pixel at __x,y__ */
+uint8_t getpix(uint8_t x, uint8_t y) OLDCALL;
+
+/** Prints the character __chr__ in the default font at the current text position.
+
+ The current position is advanced by 1 after the character is printed.
+ @see gotogxy() */
+void wrtchr(char chr) OLDCALL;
+
+/** Sets the current text position to __x,y__.
+
+ Note: __x__ and __y__ have units of tiles (8 pixels per unit)
+ @see wrtchr() */
+void gotogxy(uint8_t x, uint8_t y) OLDCALL;
+
+/** Set the current __foreground__ colour (for pixels), __background__ colour, and
+ draw __mode__ */
+void color(uint8_t forecolor, uint8_t backcolor, uint8_t mode) OLDCALL;
+
+#endif /* __DRAWING_H */
diff --git a/gbdk/gbdk-lib/include/gb/emu_debug.h b/gbdk/gbdk-lib/include/gb/emu_debug.h
new file mode 100644
index 00000000..69d76323
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/emu_debug.h
@@ -0,0 +1,13 @@
+/** @file gb/emu_debug.h
+
+ Shim for legacy use of @ref gb/emu_debug.h which has been
+ migrated to @ref gbdk/emu_debug.h
+
+ See the `emu_debug` example project included with gbdk.
+*/
+#ifndef __EMU_DEBUG_INCLUDE
+#define __EMU_DEBUG_INCLUDE
+
+#include <gbdk/emu_debug.h>
+
+#endif
diff --git a/gbdk/gbdk-lib/include/gb/gb.h b/gbdk/gbdk-lib/include/gb/gb.h
new file mode 100644
index 00000000..32886588
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/gb.h
@@ -0,0 +1,1732 @@
+/** @file gb/gb.h
+ Gameboy specific functions.
+*/
+#ifndef _GB_H
+#define _GB_H
+
+#include <types.h>
+#include <stdint.h>
+#include <gbdk/version.h>
+#include <gb/hardware.h>
+
+#define NINTENDO
+#ifdef SEGA
+#undef SEGA
+#endif
+#if defined(__TARGET_ap)
+#define ANALOGUEPOCKET
+#elif defined(__TARGET_gb)
+#define GAMEBOY
+#elif defined(__TARGET_duck)
+#define MEGADUCK
+#endif
+
+
+/** Joypad bits.
+ A logical OR of these is used in the wait_pad and joypad
+ functions. For example, to see if the B button is pressed
+ try
+
+ uint8_t keys;
+ keys = joypad();
+ if (keys & J_B) {
+ ...
+ }
+
+ @see joypad
+ */
+#define J_UP 0x04U
+#define J_DOWN 0x08U
+#define J_LEFT 0x02U
+#define J_RIGHT 0x01U
+#define J_A 0x10U
+#define J_B 0x20U
+#define J_SELECT 0x40U
+#define J_START 0x80U
+
+/** Screen modes.
+ Normally used by internal functions only.
+ @see mode()
+ */
+#define M_DRAWING 0x01U
+#define M_TEXT_OUT 0x02U
+#define M_TEXT_INOUT 0x03U
+/** Set this in addition to the others to disable scrolling
+
+ If scrolling is disabled, the cursor returns to (0,0)
+ @see mode()
+*/
+#define M_NO_SCROLL 0x04U
+/** Set this to disable interpretation
+ @see mode()
+*/
+#define M_NO_INTERP 0x08U
+
+/** If this is set, sprite colours come from OBJ1PAL. Else
+ they come from OBJ0PAL
+ @see set_sprite_prop().
+*/
+#define S_PALETTE 0x10U
+/** If set the sprite will be flipped horizontally.
+ @see set_sprite_prop()
+ */
+#define S_FLIPX 0x20U
+/** If set the sprite will be flipped vertically.
+ @see set_sprite_prop()
+ */
+#define S_FLIPY 0x40U
+/** If this bit is clear, then the sprite will be displayed
+ on top of the background and window.
+ @see set_sprite_prop()
+*/
+#define S_PRIORITY 0x80U
+
+/* Interrupt flags */
+/** Disable calling of interrupt service routines
+ */
+#define EMPTY_IFLAG 0x00U
+/** VBlank Interrupt occurs at the start of the vertical blank.
+
+ During this period the video ram may be freely accessed.
+ @see set_interrupts(), @see add_VBL
+ */
+#define VBL_IFLAG 0x01U
+/** LCD Interrupt when triggered by the STAT register.
+ @see set_interrupts(), @see add_LCD
+*/
+#define LCD_IFLAG 0x02U
+/** Timer Interrupt when the timer @ref TIMA_REG overflows.
+ @see set_interrupts(), @see add_TIM
+ */
+#define TIM_IFLAG 0x04U
+/** Serial Link Interrupt occurs when the serial transfer has completed.
+ @see set_interrupts(), @see add_SIO
+ */
+#define SIO_IFLAG 0x08U
+/** Joypad Interrupt occurs on a transition of the keypad.
+ @see set_interrupts(), @see add_JOY
+ */
+#define JOY_IFLAG 0x10U
+
+
+/* DMG Palettes */
+#define DMG_BLACK 0x03
+#define DMG_DARK_GRAY 0x02
+#define DMG_LITE_GRAY 0x01
+#define DMG_WHITE 0x00
+/** Macro to create a DMG palette from 4 colors
+
+ @param C0 Color for Index 0
+ @param C1 Color for Index 1
+ @param C2 Color for Index 2
+ @param C3 Color for Index 3
+
+ The resulting format is four greyscale colors
+ packed into a single unsigned byte.
+
+ Example:
+ \code{.c}
+ REG_BGP = DMG_PALETTE(DMG_BLACK, DMG_DARK_GRAY, DMG_LITE_GRAY, DMG_WHITE);
+ \endcode
+
+ @see OBP0_REG, OBP1_REG, BGP_REG
+ @see DMG_BLACK, DMG_DARK_GRAY, DMG_LITE_GRAY, DMG_WHITE
+
+ */
+#define DMG_PALETTE(C0, C1, C2, C3) ((uint8_t)((((C3) & 0x03) << 6) | (((C2) & 0x03) << 4) | (((C1) & 0x03) << 2) | ((C0) & 0x03)))
+
+/* Limits */
+/** Width of the visible screen in pixels.
+ */
+#define SCREENWIDTH DEVICE_SCREEN_PX_WIDTH
+/** Height of the visible screen in pixels.
+ */
+#define SCREENHEIGHT DEVICE_SCREEN_PX_HEIGHT
+/** The Minimum X position of the Window Layer (Left edge of screen) @see move_win()
+ */
+#define MINWNDPOSX 0x07U
+/** The Minimum Y position of the Window Layer (Top edge of screen) @see move_win()
+ */
+#define MINWNDPOSY 0x00U
+/** The Maximum X position of the Window Layer (Right edge of screen) @see move_win()
+ */
+#define MAXWNDPOSX 0xA6U
+/** The Maximum Y position of the Window Layer (Bottom edge of screen) @see move_win()
+ */
+#define MAXWNDPOSY 0x8FU
+
+
+/** Interrupt handlers
+ */
+typedef void (*int_handler)(void) NONBANKED;
+
+/** The remove functions will remove any interrupt handler.
+
+ A handler of NULL will cause bad things
+ to happen if the given interrupt is enabled.
+
+ Removes the VBL interrupt handler. @see add_VBL()
+*/
+void remove_VBL(int_handler h) OLDCALL;
+
+/** Removes the LCD interrupt handler.
+ @see add_LCD(), remove_VBL()
+*/
+void remove_LCD(int_handler h) OLDCALL;
+
+/** Removes the TIM interrupt handler.
+ @see add_TIM(), remove_VBL()
+*/
+void remove_TIM(int_handler h) OLDCALL;
+
+/** Removes the Serial Link / SIO interrupt handler.
+ @see add_SIO(), @see remove_VBL()
+
+ The default SIO ISR gets installed automatically if
+ any of the standard SIO calls are used. These calls
+ include @ref add_SIO(), @ref remove_SIO(),
+ @ref send_byte(), @ref receive_byte().
+
+ The default SIO ISR cannot be removed once installed.
+ Only secondary chained SIO ISRs (added with @ref add_SIO() )
+ can be removed.
+*/
+void remove_SIO(int_handler h) OLDCALL;
+
+/** Removes the JOY interrupt handler.
+ @see add_JOY(), remove_VBL()
+*/
+void remove_JOY(int_handler h) OLDCALL;
+
+/** Adds a V-blank interrupt handler.
+
+ @param h The handler to be called whenever a V-blank
+ interrupt occurs.
+
+ Up to 4 handlers may be added, with the last added being
+ called last. If the @ref remove_VBL function is to be called,
+ only three may be added.
+
+ Do not use @ref CRITICAL and @ref INTERRUPT attributes for a
+ function added via add_VBL() (or LCD, etc). The attributes
+ are only required when constructing a bare jump from the
+ interrupt vector itself.
+
+ Note: The default VBL is installed automatically.
+*/
+void add_VBL(int_handler h) OLDCALL;
+
+/** Adds a LCD interrupt handler.
+
+ Called when the LCD interrupt occurs, which is normally
+ when @ref LY_REG == @ref LYC_REG.
+
+ There are various reasons for this interrupt to occur
+ as described by the @ref STAT_REG register ($FF41). One very
+ popular reason is to indicate to the user when the
+ video hardware is about to redraw a given LCD line.
+ This can be useful for dynamically controlling the
+ @ref SCX_REG / @ref SCY_REG registers ($FF43/$FF42) to perform
+ special video effects.
+
+ @see add_VBL
+*/
+void add_LCD(int_handler h) OLDCALL;
+
+/** Adds a timer interrupt handler.
+
+ Can not be used together with @ref add_low_priority_TIM
+
+ This interrupt occurs when the @ref TIMA_REG
+ register ($FF05) changes from $FF to $00.
+
+ @see add_VBL
+ @see set_interrupts() with TIM_IFLAG
+*/
+void add_TIM(int_handler h) OLDCALL;
+
+/** Adds a timer interrupt handler, that could be
+ interrupted by the other interrupts,
+ as well as itself, if it runs too slow.
+
+ Can not be used together with @ref add_TIM
+
+ This interrupt occurs when the @ref TIMA_REG
+ register ($FF05) changes from $FF to $00.
+
+ @see add_VBL
+ @see set_interrupts() with TIM_IFLAG
+*/
+void add_low_priority_TIM(int_handler h) OLDCALL;
+
+/** Adds a Serial Link transmit complete interrupt handler.
+
+ This interrupt occurs when a serial transfer has
+ completed on the game link port.
+
+ @see send_byte, receive_byte(), add_VBL()
+ @see set_interrupts() with SIO_IFLAG
+*/
+void add_SIO(int_handler h) OLDCALL;
+
+
+/** 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
+ times for every button release.
+
+ @see joypad(), add_VBL()
+*/
+void add_JOY(int_handler h) OLDCALL;
+
+
+/** Interrupt handler chain terminator that does __not__ wait for .STAT
+
+ You must add this handler last in every interrupt handler
+ chain if you want to change the default interrupt handler
+ behaviour that waits for LCD controller mode to become 1 or 0
+ before return from the interrupt.
+
+ Example:
+ \code{.c}
+ CRITICAL {
+ add_SIO(nowait_int_handler); // Disable wait on VRAM state before returning from SIO interrupt
+ }
+ \endcode
+ @see wait_int_handler()
+*/
+void nowait_int_handler();
+
+
+/** Default Interrupt handler chain terminator that waits for
+ @see STAT_REG and __only__ returns at the BEGINNING of
+ either Mode 0 or Mode 1.
+
+ Used by default at the end of interrupt chains to help
+ prevent graphical glitches. The glitches are caused when an
+ ISR interrupts a graphics operation in one mode but returns
+ in a different mode for which that graphics operation is not
+ allowed.
+
+ @see nowait_int_handler()
+*/
+void wait_int_handler();
+
+/** Cancel pending interrupts
+ */
+inline uint8_t cancel_pending_interrupts() {
+ return IF_REG = 0;
+}
+
+/** Set the current screen mode - one of M_* modes
+
+ Normally used by internal functions only.
+
+ @see M_DRAWING, M_TEXT_OUT, M_TEXT_INOUT, M_NO_SCROLL, M_NO_INTERP
+*/
+void mode(uint8_t m) OLDCALL;
+
+/** Returns the current mode
+
+ @see M_DRAWING, M_TEXT_OUT, M_TEXT_INOUT, M_NO_SCROLL, M_NO_INTERP
+*/
+uint8_t get_mode() OLDCALL PRESERVES_REGS(b, c);
+
+/** GB CPU type
+
+ @see DMG_TYPE, MGB_TYPE, CGB_TYPE, cpu_fast(), cpu_slow(), _is_GBA
+*/
+extern uint8_t _cpu;
+
+/** Hardware Model: Original GB or Super GB. @see _cpu
+*/
+#define DMG_TYPE 0x01
+/** Hardware Model: Pocket GB or Super GB 2. @see _cpu
+*/
+#define MGB_TYPE 0xFF
+/** Hardware Model: Color GB. @see _cpu
+*/
+#define CGB_TYPE 0x11
+
+/** GBA detection
+
+ @see GBA_DETECTED, GBA_NOT_DETECTED, _cpu
+*/
+extern uint8_t _is_GBA;
+
+/** Hardware Model: DMG, CGB or MGB. @see _cpu, _is_GBA
+*/
+#define GBA_NOT_DETECTED 0x00
+/** Hardware Model: GBA. @see _cpu, _is_GBA
+*/
+#define GBA_DETECTED 0x01
+
+/** Macro returns TRUE if device supports color
+ */
+#define DEVICE_SUPPORTS_COLOR (_cpu == CGB_TYPE)
+
+/** Global Time Counter in VBL periods (60Hz)
+
+ Increments once per Frame
+
+ Will wrap around every ~18 minutes (unsigned 16 bits = 65535 / 60 / 60 = 18.2)
+*/
+extern volatile uint16_t sys_time;
+
+
+
+/** Serial Link: Send the byte in @ref _io_out out through the serial port
+
+ Make sure to enable interrupts for the
+ Serial Link before trying to transfer data.
+ @see add_SIO(), remove_SIO()
+ @see set_interrupts() with @ref SIO_IFLAG
+*/
+void send_byte();
+
+/** Serial Link: Receive a byte from the serial port into @ref _io_in
+
+ Make sure to enable interrupts for the
+ Serial Link before trying to transfer data.
+ @see add_SIO(), remove_SIO()
+ @see set_interrupts() with @ref SIO_IFLAG
+*/
+void receive_byte();
+
+/** Serial Link: Current IO Status. An OR of IO_* */
+extern volatile uint8_t _io_status;
+
+/** Serial Link: Byte just read after calling @ref receive_byte()
+*/
+extern volatile uint8_t _io_in;
+
+/** Serial Link: Write byte to send here before calling @ref send_byte()
+*/
+extern volatile uint8_t _io_out;
+
+/* Status codes */
+/** Serial Link IO is completed */
+#define IO_IDLE 0x00U
+/** Serial Link Sending data */
+#define IO_SENDING 0x01U
+/** Serial Link Receiving data */
+#define IO_RECEIVING 0x02U
+/** Serial Link Error */
+#define IO_ERROR 0x04U
+
+
+
+/** Tracks current active ROM bank @see SWITCH_ROM_MBC1(), SWITCH_ROM_MBC5()
+ This variable is updated automatically when you call SWITCH_ROM_MBC1 or
+ SWITCH_ROM_MBC5, or call a BANKED function.
+*/
+__REG _current_bank;
+#define CURRENT_BANK _current_bank
+
+/** Obtains the __bank number__ of VARNAME
+
+ @param VARNAME Name of the variable which has a __bank_VARNAME companion symbol which is adjusted by bankpack
+
+ Use this to obtain the bank number from a bank reference
+ created with @ref BANKREF().
+
+ @see BANKREF_EXTERN(), BANKREF()
+*/
+#ifndef BANK
+#define BANK(VARNAME) ( (uint8_t) & __bank_ ## VARNAME )
+#endif
+
+/** Creates a reference for retrieving the bank number of a variable or function
+
+ @param VARNAME Variable name to use, which may be an existing identifier
+
+ @see BANK() for obtaining the bank number of the included data.
+
+ More than one `BANKREF()` may be created per file, but each call should
+ always use a unique VARNAME.
+
+ Use @ref BANKREF_EXTERN() within another source file
+ to make the variable and it's data accesible there.
+*/
+#define BANKREF(VARNAME) void __func_ ## VARNAME() __banked __naked { \
+__asm \
+ .local b___func_ ## VARNAME \
+ ___bank_ ## VARNAME = b___func_ ## VARNAME \
+ .globl ___bank_ ## VARNAME \
+__endasm; \
+}
+
+/** Creates extern references for accessing a BANKREF() generated variable.
+
+ @param VARNAME Name of the variable used with @ref BANKREF()
+
+ This makes a @ref BANKREF() reference in another source
+ file accessible in the current file for use with @ref BANK().
+
+ @see BANKREF(), BANK()
+*/
+#define BANKREF_EXTERN(VARNAME) extern const void __bank_ ## VARNAME;
+
+/** Makes MEGADUCK MBC switch the active ROM bank
+ @param b ROM bank to switch to
+*/
+#define SWITCH_ROM_MEGADUCK(b) \
+ _current_bank = (b), *(uint8_t *)0x0001 = (b)
+
+
+/** Makes MBC1 and other compatible MBCs switch the active ROM bank
+ @param b ROM bank to switch to
+*/
+#define SWITCH_ROM_MBC1(b) \
+ _current_bank = (b), *(uint8_t *)0x2000 = (b)
+
+/** Makes default platform MBC switch the active ROM bank
+ @param b ROM bank to switch to (max 255)
+
+ @see SWITCH_ROM_MBC1, SWITCH_ROM_MBC5, SWITCH_ROM_MEGADUCK
+*/
+#if defined(__TARGET_duck)
+#define SWITCH_ROM SWITCH_ROM_MEGADUCK
+#else
+#define SWITCH_ROM SWITCH_ROM_MBC1
+#endif
+
+/** Switches SRAM bank on MBC1 and other compaticle MBCs
+ @param b SRAM bank to switch to
+*/
+#define SWITCH_RAM_MBC1(b) \
+ *(uint8_t *)0x4000 = (b)
+
+/** Switches SRAM bank on MBC1 and other compaticle MBCs
+ @param b SRAM bank to switch to
+
+ @see SWITCH_RAM_MBC1, SWITCH_RAM_MBC5
+*/
+#define SWITCH_RAM SWITCH_RAM_MBC1
+
+/** Enables SRAM on MBC1
+*/
+#define ENABLE_RAM_MBC1 \
+ *(uint8_t *)0x0000 = 0x0A
+
+#define ENABLE_RAM ENABLE_RAM_MBC1
+
+/** Disables SRAM on MBC1
+*/
+#define DISABLE_RAM_MBC1 \
+ *(uint8_t *)0x0000 = 0x00
+
+#define DISABLE_RAM DISABLE_RAM_MBC1
+
+#define SWITCH_16_8_MODE_MBC1 \
+ *(uint8_t *)0x6000 = 0x00
+
+#define SWITCH_4_32_MODE_MBC1 \
+ *(uint8_t *)0x6000 = 0x01
+
+/** Makes MBC5 switch to the active ROM bank; only 4M roms are supported, @see SWITCH_ROM_MBC5_8M()
+ @param b ROM bank to switch to
+
+ Note the order used here. Writing the other way around on a MBC1 always selects bank 1
+*/
+#define SWITCH_ROM_MBC5(b) \
+ _current_bank = (b), \
+ *(uint8_t *)0x3000 = 0, \
+ *(uint8_t *)0x2000 = (b)
+
+/** Makes MBC5 to switch the active ROM bank; active bank number is not tracked by _current_bank if you use this macro
+ @see _current_bank
+ @param b ROM bank to switch to
+
+ Note the order used here. Writing the other way around on a MBC1 always selects bank 1
+*/
+#define SWITCH_ROM_MBC5_8M(b) \
+ *(uint8_t *)0x3000 = ((uint16_t)(b) >> 8), \
+ *(uint8_t *)0x2000 = (b)
+
+/** Switches SRAM bank on MBC5
+ @param b SRAM bank to switch to
+*/
+#define SWITCH_RAM_MBC5(b) \
+ *(uint8_t *)0x4000 = (b)
+
+/** Enables SRAM on MBC5
+*/
+#define ENABLE_RAM_MBC5 \
+ *(uint8_t *)0x0000 = 0x0A
+
+/** Disables SRAM on MBC5
+*/
+#define DISABLE_RAM_MBC5 \
+ *(uint8_t *)0x0000 = 0x00
+
+
+
+/** Delays the given number of milliseconds.
+ Uses no timers or interrupts, and can be called with
+ interrupts disabled
+ */
+void delay(uint16_t d) OLDCALL;
+
+
+
+/** Reads and returns the current state of the joypad.
+ Follows Nintendo's guidelines for reading the pad.
+ Return value is an OR of J_*
+
+ When testing for multiple different buttons, it's
+ best to read the joypad state *once* into a variable
+ and then test using that variable.
+
+ @see J_START, J_SELECT, J_A, J_B, J_UP, J_DOWN, J_LEFT, J_RIGHT
+*/
+uint8_t joypad() OLDCALL PRESERVES_REGS(b, c, h, l);
+
+/** Waits until at least one of the buttons given in mask are pressed.
+
+ @param mask Bitmask indicating which buttons to wait for
+
+ Normally only used for checking one key, but it will
+ support many, even J_LEFT at the same time as J_RIGHT. :)
+
+ Note: Checks in a loop that doesn't HALT at all, so the CPU
+ will be maxed out until this call returns.
+ @see joypad
+ @see J_START, J_SELECT, J_A, J_B, J_UP, J_DOWN, J_LEFT, J_RIGHT
+*/
+uint8_t waitpad(uint8_t mask) OLDCALL PRESERVES_REGS(b, c);
+
+/** Waits for the directional pad and all buttons to be released.
+
+ Note: Checks in a loop that doesn't HALT at all, so the CPU
+ will be maxed out until this call returns.
+*/
+void waitpadup() PRESERVES_REGS(a, b, c, d, e, h, l);
+
+/** Multiplayer joypad structure.
+
+ Must be initialized with @ref joypad_init() first then it
+ may be used to poll all avaliable joypads with @ref joypad_ex()
+*/
+typedef struct {
+ uint8_t npads;
+ union {
+ struct {
+ uint8_t joy0, joy1, joy2, joy3;
+ };
+ uint8_t joypads[4];
+ };
+} joypads_t;
+
+/** Initializes joypads_t structure for polling multiple joypads
+ (for the GB and ones connected via SGB)
+ @param npads number of joypads requested (1, 2 or 4)
+ @param joypads pointer to joypads_t structure to be initialized
+
+ Only required for @ref joypad_ex, not required for calls to regular @ref joypad()
+ @returns number of joypads avaliable
+ @see joypad_ex(), joypads_t
+*/
+uint8_t joypad_init(uint8_t npads, joypads_t * joypads) OLDCALL;
+
+/** Polls all avaliable joypads (for the GB and ones connected via SGB)
+ @param joypads pointer to joypads_t structure to be filled with joypad statuses,
+ must be previously initialized with joypad_init()
+
+ @see joypad_init(), joypads_t
+*/
+void joypad_ex(joypads_t * joypads) OLDCALL PRESERVES_REGS(b, c);
+
+
+
+/** Enables unmasked interrupts
+
+ @note Use @ref CRITICAL {...} instead for creating a block of
+ of code which should execute with interrupts temporarily
+ turned off.
+
+ @see disable_interrupts, set_interrupts, CRITICAL
+*/
+inline void enable_interrupts() PRESERVES_REGS(a, b, c, d, e, h, l) {
+ __asm__("ei");
+}
+
+/** Disables interrupts
+
+ @note Use @ref CRITICAL {...} instead for creating a block of
+ of code which should execute with interrupts temporarily
+ turned off.
+
+ This function may be called as many times as you like;
+ however the first call to @ref enable_interrupts will re-enable
+ them.
+
+ @see enable_interrupts, set_interrupts, CRITICAL
+*/
+inline void disable_interrupts() PRESERVES_REGS(a, b, c, d, e, h, l) {
+ __asm__("di");
+}
+
+/** Clears any pending interrupts and sets the interrupt mask
+ register IO to flags.
+ @param flags A logical OR of *_IFLAGS
+
+ @note: This disables and then re-enables interrupts so it
+ must be used outside of a critical section.
+
+ @see enable_interrupts(), disable_interrupts()
+ @see VBL_IFLAG, LCD_IFLAG, TIM_IFLAG, SIO_IFLAG, JOY_IFLAG
+*/
+void set_interrupts(uint8_t flags) OLDCALL PRESERVES_REGS(b, c, d, e);
+
+/** Performs a warm reset by reloading the CPU value
+ then jumping to the start of crt0 (0x0150)
+*/
+void reset();
+
+/** HALTs the CPU and waits for the vertical blank interrupt (VBL) to finish.
+
+ This is often used in main loops to idle the CPU at low power
+ until it's time to start the next frame. It's also useful for
+ syncing animation with the screen re-draw.
+
+ Warning: If the VBL interrupt is disabled, this function will
+ never return. If the screen is off this function returns
+ immediately.
+*/
+void wait_vbl_done() PRESERVES_REGS(b, c, d, e, h, l);
+
+/** Turns the display off.
+
+ Waits until the VBL interrupt before turning the display off.
+ @see DISPLAY_ON
+*/
+void display_off() PRESERVES_REGS(b, c, d, e, h, l);
+
+/** Copies data from shadow OAM to OAM
+ */
+void refresh_OAM() PRESERVES_REGS(b, c, d, e, h, l);
+
+
+/** Copies data from somewhere in the lower address space to part of hi-ram.
+ @param dst Offset in high ram (0xFF00 and above) to copy to.
+ @param src Area to copy from
+ @param n Number of bytes to copy.
+*/
+void hiramcpy(uint8_t dst, const void *src, uint8_t n) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** Turns the display back on.
+ @see display_off, DISPLAY_OFF
+*/
+#define DISPLAY_ON \
+ LCDC_REG|=LCDCF_ON
+
+/** Turns the display off immediately.
+ @see display_off, DISPLAY_ON
+*/
+#define DISPLAY_OFF \
+ display_off();
+
+/** Does nothing for GB
+ */
+#define HIDE_LEFT_COLUMN
+
+/** Does nothing for GB
+ */
+#define SHOW_LEFT_COLUMN
+
+/** Turns on the background layer.
+ Sets bit 0 of the LCDC register to 1.
+*/
+#define SHOW_BKG \
+ LCDC_REG|=LCDCF_BGON
+
+/** Turns off the background layer.
+ Sets bit 0 of the LCDC register to 0.
+*/
+#define HIDE_BKG \
+ LCDC_REG&=~LCDCF_BGON
+
+/** Turns on the window layer
+ Sets bit 5 of the LCDC register to 1.
+*/
+#define SHOW_WIN \
+ LCDC_REG|=LCDCF_WINON
+
+/** Turns off the window layer.
+ Clears bit 5 of the LCDC register to 0.
+*/
+#define HIDE_WIN \
+ LCDC_REG&=~LCDCF_WINON
+
+/** Turns on the sprites layer.
+ Sets bit 1 of the LCDC register to 1.
+*/
+#define SHOW_SPRITES \
+ LCDC_REG|=LCDCF_OBJON
+
+/** Turns off the sprites layer.
+ Clears bit 1 of the LCDC register to 0.
+*/
+#define HIDE_SPRITES \
+ LCDC_REG&=~LCDCF_OBJON
+
+/** Sets sprite size to 8x16 pixels, two tiles one above the other.
+ Sets bit 2 of the LCDC register to 1.
+*/
+#define SPRITES_8x16 \
+ LCDC_REG|=LCDCF_OBJ16
+
+/** Sets sprite size to 8x8 pixels, one tile.
+ Clears bit 2 of the LCDC register to 0.
+*/
+#define SPRITES_8x8 \
+ LCDC_REG&=~LCDCF_OBJ16
+
+
+
+/**
+ * Set byte in vram at given memory location
+ *
+ * @param addr address to write to
+ * @param v value
+ */
+void set_vram_byte(uint8_t * addr, uint8_t v) OLDCALL PRESERVES_REGS(b, c);
+
+/**
+ * Get byte from vram at given memory location
+ *
+ * @param addr address to read from
+ * @return read value
+ */
+uint8_t get_vram_byte(uint8_t * addr) OLDCALL PRESERVES_REGS(b, c);
+
+
+/**
+ * Get address of X,Y tile of background map
+ */
+uint8_t * get_bkg_xy_addr(uint8_t x, uint8_t y) OLDCALL PRESERVES_REGS(b, c);
+
+#define COMPAT_PALETTE(C0,C1,C2,C3) ((uint8_t)(((C3) << 6) | ((C2) << 4) | ((C1) << 2) | (C0)))
+
+/** Sets palette for 2bpp color translation for GG/SMS, does nothing on GB
+ */
+inline void set_2bpp_palette(uint16_t palette) {
+ palette;
+}
+
+extern uint16_t _current_1bpp_colors;
+void set_1bpp_colors_ex(uint8_t fgcolor, uint8_t bgcolor, uint8_t mode) OLDCALL;
+inline void set_1bpp_colors(uint8_t fgcolor, uint8_t bgcolor) {
+ set_1bpp_colors_ex(fgcolor, bgcolor, 0);
+}
+
+/** Sets VRAM Tile Pattern data for the Background / Window
+
+ @param first_tile Index of the first tile to write
+ @param nb_tiles Number of tiles to write
+ @param data Pointer to (2 bpp) source tile data
+
+ Writes __nb_tiles__ tiles to VRAM starting at __first_tile__, tile data
+ is sourced from __data__. Each Tile is 16 bytes in size (8x8 pixels, 2 bits-per-pixel).
+
+ Note: Sprite Tiles 128-255 share the same memory region as Background Tiles 128-255.
+
+ GBC only: @ref VBK_REG determines which bank of Background tile patterns are written to.
+ \li VBK_REG=0 indicates the first bank
+ \li VBK_REG=1 indicates the second
+
+ @see set_win_data, set_tile_data
+*/
+void set_bkg_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) OLDCALL PRESERVES_REGS(b, c);
+#define set_bkg_2bpp_data set_bkg_data
+
+/** Sets VRAM Tile Pattern data for the Background / Window using 1bpp source data
+
+ @param first_tile Index of the first Tile to write
+ @param nb_tiles Number of Tiles to write
+ @param data Pointer to (1bpp) source Tile Pattern data
+
+ Similar to @ref set_bkg_data, except source data is 1 bit-per-pixel
+ which gets expanded into 2 bits-per-pixel.
+
+ For a given bit that represent a pixel:
+ \li 0 will be expanded into color 0
+ \li 1 will be expanded into color 1, 2 or 3 depending on color argument
+
+ @see SHOW_BKG, HIDE_BKG, set_bkg_tiles
+*/
+void set_bkg_1bpp_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) OLDCALL PRESERVES_REGS(b, c);
+
+/** Copies from Background / Window VRAM Tile Pattern data into a buffer
+
+ @param first_tile Index of the first Tile to read from
+ @param nb_tiles Number of Tiles to read
+ @param data Pointer to destination buffer for Tile Pattern data
+
+ Copies __nb_tiles__ tiles from VRAM starting at __first_tile__, Tile data
+ is copied into __data__.
+
+ Each Tile is 16 bytes, so the buffer pointed to by __data__
+ should be at least __nb_tiles__ x 16 bytes in size.
+
+ @see get_win_data, get_data
+*/
+void get_bkg_data(uint8_t first_tile, uint8_t nb_tiles, uint8_t *data) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** Sets a rectangular region of Background Tile Map.
+
+ @param x X Start position in Background Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Background Map tile coordinates. Range 0 - 31
+ @param w Width of area to set in tiles. Range 1 - 32
+ @param h Height of area to set in tiles. Range 1 - 32
+ @param tiles Pointer to source tile map data
+
+ Entries are copied from map at __tiles__ to the Background Tile Map starting at
+ __x__, __y__ writing across for __w__ tiles and down for __h__ tiles.
+
+ Use @ref set_bkg_submap() instead when:
+ \li Source map is wider than 32 tiles.
+ \li Writing a width that does not match the source map width __and__ more
+ than one row high at a time.
+
+ One byte per source tile map entry.
+
+ Writes that exceed coordinate 31 on the x or y axis will wrap around to
+ the Left and Top edges.
+
+ Note: Patterns 128-255 overlap with patterns 128-255 of the sprite Tile Pattern table.
+
+ GBC only: @ref VBK_REG determines whether Tile Numbers or Tile Attributes get set.
+ \li VBK_REG=0 Tile Numbers are written
+ \li VBK_REG=1 Tile Attributes are written
+
+ GBC Tile Attributes are defined as:
+ \li Bit 7 - Priority flag. When this is set, it puts the tile above the sprites
+ with colour 0 being transparent.
+ \n 0: Below sprites
+ \n 1: Above sprites
+ \n Note: @ref SHOW_BKG needs to be set for these priorities to take place.
+ \li Bit 6 - Vertical flip. Dictates which way up the tile is drawn vertically.
+ \n 0: Normal
+ \n 1: Flipped Vertically
+ \li Bit 5 - Horizontal flip. Dictates which way up the tile is drawn horizontally.
+ \n 0: Normal
+ \n 1: Flipped Horizontally
+ \li Bit 4 - Not used
+ \li Bit 3 - Character Bank specification. Dictates from which bank of
+ Background Tile Patterns the tile is taken.
+ \n 0: Bank 0
+ \n 1: Bank 1
+ \li Bit 2 - See bit 0.
+ \li Bit 1 - See bit 0.
+ \li Bit 0 - Bits 0-2 indicate which of the 7 BKG colour palettes the tile is
+ assigned.
+
+ @see SHOW_BKG
+ @see set_bkg_data, set_bkg_submap, set_win_tiles, set_tiles
+*/
+void set_bkg_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles) OLDCALL PRESERVES_REGS(b, c);
+#define set_tile_map set_bkg_tiles
+
+
+extern uint8_t _map_tile_offset;
+
+/** Sets a rectangular region of Background Tile Map.
+ The offset value in __base_tile__ is added to
+ the tile ID for each map entry.
+
+ @param x X Start position in Background Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Background Map tile coordinates. Range 0 - 31
+ @param w Width of area to set in tiles. Range 1 - 32
+ @param h Height of area to set in tiles. Range 1 - 32
+ @param tiles Pointer to source tile map data
+ @param base_tile Offset each tile ID entry of the source map by this value. Range 1 - 255
+
+ This is identical to @ref set_bkg_tiles() except that it
+ adds the __base_tile__ parameter for when a tile map's tiles don't
+ start at index zero. (For example, the tiles used by the map
+ range from 100 -> 120 in VRAM instead of 0 -> 20).
+
+ @see set_bkg_tiles for more details
+*/
+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) {
+ _map_tile_offset = base_tile;
+ set_bkg_tiles(x, y, w, h, tiles);
+ _map_tile_offset = 0;
+}
+
+
+/** Sets a rectangular area of the Background Tile Map using a sub-region
+ from a source tile map. Useful for scrolling implementations of maps
+ larger than 32 x 32 tiles.
+
+ @param x X Start position in Background Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Background Map tile coordinates. Range 0 - 31
+ @param w Width of area to set in tiles. Range 1 - 255
+ @param h Height of area to set in tiles. Range 1 - 255
+ @param map Pointer to source tile map data
+ @param map_w Width of source tile map in tiles. Range 1 - 255
+
+ Entries are copied from __map__ to the Background Tile Map starting at
+ __x__, __y__ writing across for __w__ tiles and down for __h__ tiles,
+ using __map_w__ as the rowstride for the source tile map.
+
+ Use this instead of @ref set_bkg_tiles when the source map is wider than
+ 32 tiles or when writing a width that does not match the source map width.
+
+ One byte per source tile map entry.
+
+ Writes that exceed coordinate 31 on the x or y axis will wrap around to
+ the Left and Top edges.
+
+ See @ref set_bkg_tiles for setting CGB attribute maps with @ref VBK_REG.
+
+ @see SHOW_BKG
+ @see set_bkg_data, set_bkg_tiles, set_win_submap, set_tiles
+*/
+void set_bkg_submap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w) OLDCALL;
+#define set_tile_submap set_bkg_submap
+
+
+extern uint8_t _submap_tile_offset;
+
+/** Sets a rectangular area of the Background Tile Map using a sub-region
+ from a source tile map. The offset value in __base_tile__ is added to
+ the tile ID for each map entry.
+
+ @param x X Start position in Background Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Background Map tile coordinates. Range 0 - 31
+ @param w Width of area to set in tiles. Range 1 - 255
+ @param h Height of area to set in tiles. Range 1 - 255
+ @param map Pointer to source tile map data
+ @param map_w Width of source tile map in tiles. Range 1 - 255
+ @param base_tile Offset each tile ID entry of the source map by this value. Range 1 - 255
+
+ This is identical to @ref set_bkg_based_submap() except that it
+ adds the __base_tile__ parameter for when a tile map's tiles don't
+ start at index zero. (For example, the tiles used by the map
+ range from 100 -> 120 in VRAM instead of 0 -> 20).
+
+ @see set_bkg_based_submap for more details
+*/
+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) {
+ _submap_tile_offset = base_tile;
+ set_bkg_submap(x, y, w, h, map, map_w);
+ _submap_tile_offset = 0;
+}
+
+
+/** Copies a rectangular region of Background Tile Map entries into a buffer.
+
+ @param x X Start position in Background Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Background Map tile coordinates. Range 0 - 31
+ @param w Width of area to copy in tiles. Range 0 - 31
+ @param h Height of area to copy in tiles. Range 0 - 31
+ @param tiles Pointer to destination buffer for Tile Map data
+
+
+ Entries are copied into __tiles__ from the Background Tile Map starting at
+ __x__, __y__ reading across for __w__ tiles and down for __h__ tiles.
+
+ One byte per tile.
+
+ The buffer pointed to by __tiles__ should be at least __x__ x __y__ bytes in size.
+
+ @see get_win_tiles, get_bkg_tile_xy, get_tiles, get_vram_byte
+*/
+void get_bkg_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t *tiles) OLDCALL PRESERVES_REGS(b, c);
+
+
+/**
+ * Set single tile t on background layer at x,y
+ * @param x X-coordinate
+ * @param y Y-coordinate
+ * @param t tile index
+ * @return returns the address of tile, so you may use faster set_vram_byte() later
+ */
+uint8_t * set_bkg_tile_xy(uint8_t x, uint8_t y, uint8_t t) OLDCALL PRESERVES_REGS(b, c);
+#define set_tile_xy set_bkg_tile_xy
+
+/**
+ * Get single tile t on background layer at x,y
+ * @param x X-coordinate
+ * @param y Y-coordinate
+ * @return returns tile index
+ */
+uint8_t get_bkg_tile_xy(uint8_t x, uint8_t y) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** Moves the Background Layer to the position specified in __x__ and __y__ in pixels.
+
+ @param x X axis screen coordinate for Left edge of the Background
+ @param y Y axis screen coordinate for Top edge of the Background
+
+ 0,0 is the top left corner of the GB screen. The Background Layer wraps around the screen,
+ so when part of it goes off the screen it appears on the opposite side (factoring in the
+ larger size of the Background Layer versus the screen size).
+
+ The background layer is always under the Window Layer.
+
+ @see SHOW_BKG, HIDE_BKG
+*/
+inline void move_bkg(uint8_t x, uint8_t y) {
+ SCX_REG=x, SCY_REG=y;
+}
+
+
+/** Moves the Background relative to it's current position.
+
+ @param x Number of pixels to move the Background on the __X axis__
+ \n Range: -128 - 127
+ @param y Number of pixels to move the Background on the __Y axis__
+ \n Range: -128 - 127
+
+ @see move_bkg
+*/
+inline void scroll_bkg(int8_t x, int8_t y) {
+ SCX_REG+=x, SCY_REG+=y;
+}
+
+
+
+/**
+ * Get address of X,Y tile of window map
+ */
+uint8_t * get_win_xy_addr(uint8_t x, uint8_t y) OLDCALL PRESERVES_REGS(b, c);
+
+/** Sets VRAM Tile Pattern data for the Window / Background
+
+ @param first_tile Index of the first tile to write
+ @param nb_tiles Number of tiles to write
+ @param data Pointer to (2 bpp) source Tile Pattern data.
+
+ This is the same as @ref set_bkg_data, since the Window Layer and
+ Background Layer share the same Tile pattern data.
+
+ @see set_bkg_data
+ @see set_win_tiles, set_bkg_data, set_data
+ @see SHOW_WIN, HIDE_WIN
+*/
+void set_win_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** Sets VRAM Tile Pattern data for the Window / Background using 1bpp source data
+
+ @param first_tile Index of the first tile to write
+ @param nb_tiles Number of tiles to write
+ @param data Pointer to (1bpp) source Tile Pattern data
+
+ This is the same as @ref set_bkg_1bpp_data, since the Window Layer and
+ Background Layer share the same Tile pattern data.
+
+ @see set_bkg_data, set_bkg_1bpp_data, set_win_data
+*/
+void set_win_1bpp_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** Copies from Window / Background VRAM Tile Pattern data into a buffer
+
+ @param first_tile Index of the first Tile to read from
+ @param nb_tiles Number of Tiles to read
+ @param data Pointer to destination buffer for Tile Pattern Data
+
+ This is the same as @ref get_bkg_data, since the Window Layer and
+ Background Layer share the same Tile pattern data.
+
+ @see get_bkg_data, get_data
+*/
+void get_win_data(uint8_t first_tile, uint8_t nb_tiles, uint8_t *data) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** Sets a rectangular region of the Window Tile Map.
+
+ @param x X Start position in Window Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Window Map tile coordinates. Range 0 - 31
+ @param w Width of area to set in tiles. Range 1 - 32
+ @param h Height of area to set in tiles. Range 1 - 32
+ @param tiles Pointer to source tile map data
+
+ Entries are copied from map at __tiles__ to the Window Tile Map starting at
+ __x__, __y__ writing across for __w__ tiles and down for __h__ tiles.
+
+ Use @ref set_win_submap() instead when:
+ \li Source map is wider than 32 tiles.
+ \li Writing a width that does not match the source map width __and__ more
+ than one row high at a time.
+
+ One byte per source tile map entry.
+
+ Writes that exceed coordinate 31 on the x or y axis will wrap around to
+ the Left and Top edges.
+
+ Note: Patterns 128-255 overlap with patterns 128-255 of the sprite Tile Pattern table.
+
+ GBC only: @ref VBK_REG determines whether Tile Numbers or Tile Attributes get set.
+ \li VBK_REG=0 Tile Numbers are written
+ \li VBK_REG=1 Tile Attributes are written
+
+ For more details about GBC Tile Attributes see @ref set_bkg_tiles.
+
+ @see SHOW_WIN, HIDE_WIN, set_win_submap, set_bkg_tiles, set_bkg_data, set_tiles
+*/
+void set_win_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** Sets a rectangular region of the Window Tile Map.
+ The offset value in __base_tile__ is added to
+ the tile ID for each map entry.
+
+ @param x X Start position in Window Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Window Map tile coordinates. Range 0 - 31
+ @param w Width of area to set in tiles. Range 1 - 32
+ @param h Height of area to set in tiles. Range 1 - 32
+ @param tiles Pointer to source tile map data
+ @param base_tile Offset each tile ID entry of the source map by this value. Range 1 - 255
+
+ This is identical to @ref set_win_tiles() except that it
+ adds the __base_tile__ parameter for when a tile map's tiles don't
+ start at index zero. (For example, the tiles used by the map
+ range from 100 -> 120 in VRAM instead of 0 -> 20).
+
+ @see set_win_tiles for more details
+*/
+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) {
+ _map_tile_offset = base_tile;
+ set_win_tiles(x, y, w, h, tiles);
+ _map_tile_offset = 0;
+}
+
+/** Sets a rectangular area of the Window Tile Map using a sub-region
+ from a source tile map.
+
+ @param x X Start position in Window Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Wimdpw Map tile coordinates. Range 0 - 31
+ @param w Width of area to set in tiles. Range 1 - 255
+ @param h Height of area to set in tiles. Range 1 - 255
+ @param map Pointer to source tile map data
+ @param map_w Width of source tile map in tiles. Range 1 - 255
+
+ Entries are copied from __map__ to the Window Tile Map starting at
+ __x__, __y__ writing across for __w__ tiles and down for __h__ tiles,
+ using __map_w__ as the rowstride for the source tile map.
+
+ Use this instead of @ref set_win_tiles when the source map is wider than
+ 32 tiles or when writing a width that does not match the source map width.
+
+ One byte per source tile map entry.
+
+ Writes that exceed coordinate 31 on the x or y axis will wrap around to
+ the Left and Top edges.
+
+ GBC only: @ref VBK_REG determines whether Tile Numbers or Tile Attributes get set.
+ \li VBK_REG=0 Tile Numbers are written
+ \li VBK_REG=1 Tile Attributes are written
+
+ See @ref set_bkg_tiles for details about CGB attribute maps with @ref VBK_REG.
+
+ @see SHOW_WIN, HIDE_WIN, set_win_tiles, set_bkg_submap, set_bkg_tiles, set_bkg_data, set_tiles
+**/
+void set_win_submap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w) OLDCALL;
+
+
+/** Sets a rectangular area of the Window Tile Map using a sub-region
+ from a source tile map. The offset value in __base_tile__ is added
+ to the tile ID for each map entry.
+
+ @param x X Start position in Window Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Wimdpw Map tile coordinates. Range 0 - 31
+ @param w Width of area to set in tiles. Range 1 - 255
+ @param h Height of area to set in tiles. Range 1 - 255
+ @param map Pointer to source tile map data
+ @param map_w Width of source tile map in tiles. Range 1 - 255
+ @param base_tile Offset each tile ID entry of the source map by this value. Range 1 - 255
+
+ This is identical to @ref set_win_submap() except that it
+ adds the __base_tile__ parameter for when a tile map's tiles don't
+ start at index zero. (For example, the tiles used by the map
+ range from 100 -> 120 in VRAM instead of 0 -> 20).
+
+ @see set_win_submap for more details
+**/
+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) {
+ _submap_tile_offset = base_tile;
+ set_win_submap(x, y, w, h, map, map_w);
+ _submap_tile_offset = 0;
+}
+
+
+/** Copies a rectangular region of Window Tile Map entries into a buffer.
+
+ @param x X Start position in Window Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Window Map tile coordinates. Range 0 - 31
+ @param w Width of area to copy in tiles. Range 0 - 31
+ @param h Height of area to copy in tiles. Range 0 - 31
+ @param tiles Pointer to destination buffer for Tile Map data
+
+ Entries are copied into __tiles__ from the Window Tile Map starting at
+ __x__, __y__ reading across for __w__ tiles and down for __h__ tiles.
+
+ One byte per tile.
+
+ The buffer pointed to by __tiles__ should be at least __x__ x __y__ bytes in size.
+
+ @see get_bkg_tiles, get_bkg_tile_xy, get_tiles, get_vram_byte
+*/
+void get_win_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t *tiles) OLDCALL PRESERVES_REGS(b, c);
+
+
+/**
+ * Set single tile t on window layer at x,y
+ * @param x X-coordinate
+ * @param y Y-coordinate
+ * @param t tile index
+ * @return returns the address of tile, so you may use faster set_vram_byte() later
+ */
+uint8_t * set_win_tile_xy(uint8_t x, uint8_t y, uint8_t t) OLDCALL PRESERVES_REGS(b, c);
+
+
+/**
+ * Get single tile t on window layer at x,y
+ * @param x X-coordinate
+ * @param y Y-coordinate
+ * @return returns the tile index
+ */
+uint8_t get_win_tile_xy(uint8_t x, uint8_t y) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** Moves the Window to the __x__, __y__ position on the screen.
+
+ @param x X coordinate for Left edge of the Window (actual displayed location will be X - 7)
+ @param y Y coordinate for Top edge of the Window
+
+ 7,0 is the top left corner of the screen in Window coordinates. The Window is locked to the bottom right corner.
+
+ The Window is always over the Background layer.
+
+ @see SHOW_WIN, HIDE_WIN
+*/
+inline void move_win(uint8_t x, uint8_t y) {
+ WX_REG=x, WY_REG=y;
+}
+
+
+/** Move the Window relative to its current position.
+
+ @param x Number of pixels to move the window on the __X axis__
+ \n Range: -128 - 127
+ @param y Number of pixels to move the window on the __Y axis__
+ \n Range: -128 - 127
+
+ @see move_win
+*/
+inline void scroll_win(int8_t x, int8_t y) {
+ WX_REG+=x, WY_REG+=y;
+}
+
+
+
+/** Sets VRAM Tile Pattern data for Sprites
+
+ @param first_tile Index of the first tile to write
+ @param nb_tiles Number of tiles to write
+ @param data Pointer to (2 bpp) source Tile Pattern data
+
+ Writes __nb_tiles__ tiles to VRAM starting at __first_tile__, tile data
+ is sourced from __data__. Each Tile is 16 bytes in size (8x8 pixels, 2 bits-per-pixel).
+
+ Note: Sprite Tiles 128-255 share the same memory region as Background Tiles 128-255.
+
+ GBC only: @ref VBK_REG determines which bank of Background tile patterns are written to.
+ \li VBK_REG=0 indicates the first bank
+ \li VBK_REG=1 indicates the second
+*/
+void set_sprite_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) OLDCALL PRESERVES_REGS(b, c);
+#define set_sprite_2bpp_data set_sprite_data
+
+/** Sets VRAM Tile Pattern data for Sprites using 1bpp source data
+
+ @param first_tile Index of the first tile to write
+ @param nb_tiles Number of tiles to write
+ @param data Pointer to (1bpp) source Tile Pattern data
+
+ Similar to @ref set_sprite_data, except source data is 1 bit-per-pixel
+ which gets expanded into 2 bits-per-pixel.
+
+ For a given bit that represent a pixel:
+ \li 0 will be expanded into color 0
+ \li 1 will be expanded into color 3
+
+ @see SHOW_SPRITES, HIDE_SPRITES, set_sprite_tile
+*/
+void set_sprite_1bpp_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) OLDCALL PRESERVES_REGS(b, c);
+
+/** Copies from Sprite VRAM Tile Pattern data into a buffer
+
+ @param first_tile Index of the first tile to read from
+ @param nb_tiles Number of tiles to read
+ @param data Pointer to destination buffer for Tile Pattern data
+
+ Copies __nb_tiles__ tiles from VRAM starting at __first_tile__, tile data
+ is copied into __data__.
+
+ Each Tile is 16 bytes, so the buffer pointed to by __data__
+ should be at least __nb_tiles__ x 16 bytes in size.
+*/
+void get_sprite_data(uint8_t first_tile, uint8_t nb_tiles, uint8_t *data) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** Sprite Attributes structure
+ @param x X Coordinate of the sprite on screen
+ @param y Y Coordinate of the sprite on screen
+ @param tile Sprite tile number (see @ref set_sprite_tile)
+ @param prop OAM Property Flags (see @ref set_sprite_prop)
+*/
+typedef struct OAM_item_t {
+ uint8_t y, x; //< X, Y Coordinates of the sprite on screen
+ uint8_t tile; //< Sprite tile number
+ uint8_t prop; //< OAM Property Flags
+} OAM_item_t;
+
+
+/** Shadow OAM array in WRAM, that is DMA-transferred into the real OAM each VBlank
+*/
+extern volatile struct OAM_item_t shadow_OAM[];
+
+/** MSB of shadow_OAM address is used by OAM DMA copying routine
+*/
+__REG _shadow_OAM_base;
+
+#define DISABLE_OAM_DMA \
+ _shadow_OAM_base = 0
+
+/** Disable OAM DMA copy each VBlank
+*/
+#define DISABLE_VBL_TRANSFER DISABLE_OAM_DMA
+
+#define ENABLE_OAM_DMA \
+ _shadow_OAM_base = (uint8_t)((uint16_t)&shadow_OAM >> 8)
+
+/** Enable OAM DMA copy each VBlank and set it to transfer default shadow_OAM array
+*/
+#define ENABLE_VBL_TRANSFER ENABLE_OAM_DMA
+
+/** Amount of hardware sprites in OAM
+*/
+#define MAX_HARDWARE_SPRITES 40
+
+/** Enable OAM DMA copy each VBlank and set it to transfer any 256-byte aligned array
+*/
+inline void SET_SHADOW_OAM_ADDRESS(void * address) {
+ _shadow_OAM_base = (uint8_t)((uint16_t)address >> 8);
+}
+
+/** Sets sprite number __nb__in the OAM to display tile number __tile__.
+
+ @param nb Sprite number, range 0 - 39
+ @param tile Selects a tile (0 - 255) from memory at 8000h - 8FFFh
+ \n In CGB Mode this could be either in VRAM Bank
+ \n 0 or 1, depending on Bit 3 of the OAM Attribute Flag
+ \n (see @ref set_sprite_prop)
+
+ In 8x16 mode:
+ \li The sprite will also display the next tile (__tile__ + 1)
+ directly below (y + 8) the first tile.
+ \li The lower bit of the tile number is ignored:
+ the upper 8x8 tile is (__tile__ & 0xFE), and
+ the lower 8x8 tile is (__tile__ | 0x01).
+ \li See: @ref SPRITES_8x16
+*/
+inline void set_sprite_tile(uint8_t nb, uint8_t tile) {
+ shadow_OAM[nb].tile=tile;
+}
+
+
+/** Returns the tile number of sprite number __nb__ in the OAM.
+
+@param nb Sprite number, range 0 - 39
+
+@see set_sprite_tile for more details
+*/
+inline uint8_t get_sprite_tile(uint8_t nb) {
+ return shadow_OAM[nb].tile;
+}
+
+
+/** Sets the OAM Property Flags of sprite number __nb__ to those defined in __prop__.
+
+ @param nb Sprite number, range 0 - 39
+ @param prop Property setting (see bitfield description)
+
+ The bits in __prop__ represent:
+ \li Bit 7 - Priority flag. When this is set the sprites appear behind the
+ background and window layer.
+ \n 0: infront
+ \n 1: behind
+ \li Bit 6 - Vertical flip. Dictates which way up the sprite is drawn
+ vertically.
+ \n 0: normal
+ \n 1:upside down
+ \li Bit 5 - Horizontal flip. Dictates which way up the sprite is
+ drawn horizontally.
+ \n 0: normal
+ \n 1:back to front
+ \li Bit 4 - DMG/Non-CGB Mode Only. Assigns either one of the two b/w palettes to the sprite.
+ \n 0: OBJ palette 0
+ \n 1: OBJ palette 1
+ \li Bit 3 - GBC only. Dictates from which bank of Sprite Tile Patterns the tile
+ is taken.
+ \n 0: Bank 0
+ \n 1: Bank 1
+ \li Bit 2 - See bit 0.
+ \li Bit 1 - See bit 0.
+ \li Bit 0 - GBC only. Bits 0-2 indicate which of the 7 OBJ colour palettes the
+ sprite is assigned.
+*/
+inline void set_sprite_prop(uint8_t nb, uint8_t prop) {
+ shadow_OAM[nb].prop=prop;
+}
+
+
+/** Returns the OAM Property Flags of sprite number __nb__.
+
+ @param nb Sprite number, range 0 - 39
+ @see set_sprite_prop for property bitfield settings
+*/
+inline uint8_t get_sprite_prop(uint8_t nb) {
+ return shadow_OAM[nb].prop;
+}
+
+
+/** Moves sprite number __nb__ to the __x__, __y__ position on the screen.
+
+ @param nb Sprite number, range 0 - 39
+ @param x X Position. Specifies the sprites horizontal position on the screen (minus 8).
+ \n An offscreen value (X=0 or X>=168) hides the sprite, but the sprite
+ still affects the priority ordering - a better way to hide a sprite is to set
+ its Y-coordinate offscreen.
+ @param y Y Position. Specifies the sprites vertical position on the screen (minus 16).
+ \n An offscreen value (for example, Y=0 or Y>=160) hides the sprite.
+
+ Moving the sprite to 0,0 (or similar off-screen location) will hide it.
+*/
+inline void move_sprite(uint8_t nb, uint8_t x, uint8_t y) {
+ OAM_item_t * itm = &shadow_OAM[nb];
+ itm->y=y, itm->x=x;
+}
+
+
+/** Moves sprite number __nb__ relative to its current position.
+
+ @param nb Sprite number, range 0 - 39
+ @param x Number of pixels to move the sprite on the __X axis__
+ \n Range: -128 - 127
+ @param y Number of pixels to move the sprite on the __Y axis__
+ \n Range: -128 - 127
+
+ @see move_sprite for more details about the X and Y position
+ */
+inline void scroll_sprite(uint8_t nb, int8_t x, int8_t y) {
+ OAM_item_t * itm = &shadow_OAM[nb];
+ itm->y+=y, itm->x+=x;
+}
+
+
+/** Hides sprite number __nb__ by moving it to zero position by Y.
+
+ @param nb Sprite number, range 0 - 39
+ */
+inline void hide_sprite(uint8_t nb) {
+ shadow_OAM[nb].y = 0;
+}
+
+
+
+/** Copies arbitrary data to an address in VRAM
+ without taking into account the state of LCDC bits 3 or 4.
+
+ @param vram_addr Pointer to destination VRAM Address
+ @param data Pointer to source buffer
+ @param len Number of bytes to copy
+
+ Copies __len__ bytes from a buffer at __data__ to VRAM starting at __vram_addr__.
+
+ GBC only: @ref VBK_REG determines which bank of Background tile patterns are written to.
+ \li VBK_REG=0 indicates the first bank
+ \li VBK_REG=1 indicates the second
+
+ @see set_bkg_data, set_win_data, set_bkg_tiles, set_win_tiles, set_tile_data, set_tiles
+*/
+void set_data(uint8_t *vram_addr, const uint8_t *data, uint16_t len) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** Copies arbitrary data from an address in VRAM into a buffer
+ without taking into account the state of LCDC bits 3 or 4.
+
+ @param vram_addr Pointer to source VRAM Address
+ @param data Pointer to destination buffer
+ @param len Number of bytes to copy
+
+ Copies __len__ bytes from VRAM starting at __vram_addr__ into a buffer at __data__.
+
+ GBC only: @ref VBK_REG determines which bank of Background tile patterns are written to.
+ \li VBK_REG=0 indicates the first bank
+ \li VBK_REG=1 indicates the second
+
+ @see get_bkg_data, get_win_data, get_bkg_tiles, get_win_tiles, get_tiles
+*/
+void get_data(uint8_t *data, uint8_t *vram_addr, uint16_t len) OLDCALL PRESERVES_REGS(b, c);
+
+/** Copies arbitrary data from an address in VRAM into a buffer
+
+ @param dest Pointer to destination buffer (may be in VRAM)
+ @param sour Pointer to source buffer (may be in VRAM)
+ @param len Number of bytes to copy
+
+ Copies __len__ bytes from or to VRAM starting at __sour__ into a buffer or to VRAM at __dest__.
+
+ GBC only: @ref VBK_REG determines which bank of Background tile patterns are written to.
+ \li VBK_REG=0 indicates the first bank
+ \li VBK_REG=1 indicates the second
+*/
+void vmemcpy(uint8_t *dest, uint8_t *sour, uint16_t len) OLDCALL PRESERVES_REGS(b, c);
+
+
+
+/** Sets a rectangular region of Tile Map entries at a given VRAM Address
+ without taking into account the state of LCDC bit 3.
+
+ @param x X Start position in Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Map tile coordinates. Range 0 - 31
+ @param w Width of area to set in tiles. Range 1 - 32
+ @param h Height of area to set in tiles. Range 1 - 32
+ @param vram_addr Pointer to destination VRAM Address
+ @param tiles Pointer to source Tile Map data
+
+ Entries are copied from __tiles__ to Tile Map at address vram_addr starting at
+ __x__, __y__ writing across for __w__ tiles and down for __h__ tiles.
+
+ One byte per source tile map entry.
+
+ There are two 32x32 Tile Maps in VRAM at addresses 9800h-9BFFh and 9C00h-9FFFh.
+
+ GBC only: @ref VBK_REG determines whether Tile Numbers or Tile Attributes get set.
+ \li VBK_REG=0 Tile Numbers are written
+ \li VBK_REG=1 Tile Attributes are written
+
+ @see set_bkg_tiles, set_win_tiles
+*/
+void set_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t *vram_addr, const uint8_t *tiles) OLDCALL;
+
+/** Sets VRAM Tile Pattern data starting from given base address
+ without taking into account the state of LCDC bit 4.
+
+ @param first_tile Index of the first tile to write
+ @param nb_tiles Number of tiles to write
+ @param data Pointer to (2 bpp) source Tile Pattern data.
+ @param base MSB of the destination address in VRAM (usually 0x80 or 0x90 which gives 0x8000 or 0x9000)
+
+ @see set_bkg_data, set_win_data, set_data
+*/
+void set_tile_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data, uint8_t base) OLDCALL PRESERVES_REGS(b, c);
+
+/** Copies a rectangular region of Tile Map entries from a given VRAM Address into a buffer
+ without taking into account the state of LCDC bit 3.
+
+ @param x X Start position in Background Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Background Map tile coordinates. Range 0 - 31
+ @param w Width of area to copy in tiles. Range 0 - 31
+ @param h Height of area to copy in tiles. Range 0 - 31
+ @param vram_addr Pointer to source VRAM Address
+ @param tiles Pointer to destination buffer for Tile Map data
+
+ Entries are copied into __tiles__ from the Background Tile Map starting at
+ __x__, __y__ reading across for __w__ tiles and down for __h__ tiles.
+
+ One byte per tile.
+
+ There are two 32x32 Tile Maps in VRAM at addresses 9800h - 9BFFh and 9C00h - 9FFFh.
+
+ The buffer pointed to by __tiles__ should be at least __x__ x __y__ bytes in size.
+
+ @see get_bkg_tiles, get_win_tiles
+*/
+void get_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t *vram_addr, uint8_t *tiles) OLDCALL;
+
+
+/** 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) {
+ set_bkg_data(first_tile, nb_tiles, data);
+ } else {
+ set_sprite_data(first_tile - 256, nb_tiles, data);
+ }
+}
+
+
+/** Initializes the entire Window Tile Map with Tile Number __c__
+ @param c Tile number to fill with
+
+ Note: This function avoids writes during modes 2 & 3
+*/
+void init_win(uint8_t c) OLDCALL PRESERVES_REGS(b, c);
+
+/** Initializes the entire Background Tile Map with Tile Number __c__
+ @param c Tile number to fill with
+
+ Note: This function avoids writes during modes 2 & 3
+*/
+void init_bkg(uint8_t c) OLDCALL PRESERVES_REGS(b, c);
+
+/** Fills the VRAM memory region __s__ of size __n__ with Tile Number __c__
+ @param s Start address in VRAM
+ @param c Tile number to fill with
+ @param n Size of memory region (in bytes) to fill
+
+ Note: This function avoids writes during modes 2 & 3
+*/
+void vmemset (void *s, uint8_t c, size_t n) OLDCALL PRESERVES_REGS(b, c);
+
+
+
+/** Fills a rectangular region of Tile Map entries for the Background layer with tile.
+
+ @param x X Start position in Background Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Background Map tile coordinates. Range 0 - 31
+ @param w Width of area to set in tiles. Range 0 - 31
+ @param h Height of area to set in tiles. Range 0 - 31
+ @param tile Fill value
+*/
+void fill_bkg_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t tile) OLDCALL PRESERVES_REGS(b, c);
+#define fill_rect fill_bkg_rect
+
+/** Fills a rectangular region of Tile Map entries for the Window layer with tile.
+
+ @param x X Start position in Window Map tile coordinates. Range 0 - 31
+ @param y Y Start position in Window Map tile coordinates. Range 0 - 31
+ @param w Width of area to set in tiles. Range 0 - 31
+ @param h Height of area to set in tiles. Range 0 - 31
+ @param tile Fill value
+*/
+void fill_win_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t tile) OLDCALL PRESERVES_REGS(b, c);
+
+#endif /* _GB_H */
diff --git a/gbdk/gbdk-lib/include/gb/gbdecompress.h b/gbdk/gbdk-lib/include/gb/gbdecompress.h
new file mode 100644
index 00000000..79a6c985
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/gbdecompress.h
@@ -0,0 +1,62 @@
+/** @file gb/gbdecompress.h
+
+ GB-Compress decompressor
+ Compatible with the compression used in GBTD
+ @see utility_gbcompress "gbcompress"
+*/
+
+#ifndef __GBDECOMPRESS_H_INCLUDE
+#define __GBDECOMPRESS_H_INCLUDE
+
+#include <types.h>
+#include <stdint.h>
+
+/** gb-decompress data from sour into dest
+
+ @param sour Pointer to source gb-compressed data
+ @param dest Pointer to destination buffer/address
+
+ @see gb_decompress_bkg_data, gb_decompress_win_data, gb_decompress_sprite_data
+ */
+uint16_t gb_decompress(const uint8_t * sour, uint8_t * dest) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** gb-decompress background tiles into VRAM
+
+ @param first_tile Index of the first tile to write
+ @param sour Pointer to (gb-compressed 2 bpp) source Tile Pattern data.
+
+ Note: This function avoids writes during modes 2 & 3
+
+ @see gb_decompress_bkg_data, gb_decompress_win_data, gb_decompress_sprite_data
+*/
+void gb_decompress_bkg_data(uint8_t first_tile, const uint8_t * sour) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** gb-decompress window tiles into VRAM
+
+ @param first_tile Index of the first tile to write
+ @param sour Pointer to (gb-compressed 2 bpp) source Tile Pattern data.
+
+ This is the same as @ref gb_decompress_bkg_data, since the Window Layer and
+ Background Layer share the same Tile pattern data.
+
+ Note: This function avoids writes during modes 2 & 3
+
+ @see gb_decompress, gb_decompress_bkg_data, gb_decompress_sprite_data
+ */
+void gb_decompress_win_data(uint8_t first_tile, const uint8_t * sour) OLDCALL PRESERVES_REGS(b, c);
+
+
+/** gb-decompress sprite tiles into VRAM
+
+ @param first_tile Index of the first tile to write
+ @param sour Pointer to source compressed data
+
+ Note: This function avoids writes during modes 2 & 3
+
+ @see gb_decompress, gb_decompress_bkg_data, gb_decompress_win_data
+ */
+void gb_decompress_sprite_data(uint8_t first_tile, const uint8_t * sour) OLDCALL PRESERVES_REGS(b, c);
+
+#endif \ No newline at end of file
diff --git a/gbdk/gbdk-lib/include/gb/hardware.h b/gbdk/gbdk-lib/include/gb/hardware.h
new file mode 100644
index 00000000..2edcce41
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/hardware.h
@@ -0,0 +1,420 @@
+/** @file gb/hardware.h
+ Defines that let the GB's hardware registers be accessed
+ from C.
+
+ See the @ref Pandocs for more details on each register.
+*/
+#ifndef _HARDWARE_H
+#define _HARDWARE_H
+
+#include <types.h>
+
+#define __BYTES extern UBYTE
+#define __BYTE_REG extern volatile UBYTE
+#define __REG extern volatile SFR
+
+/** Memoty map */
+
+__BYTES _VRAM[];
+__BYTES _VRAM8000[];
+__BYTES _VRAM8800[];
+__BYTES _VRAM9000[];
+__BYTES _SCRN0[];
+__BYTES _SCRN1[];
+__BYTES _SRAM[];
+__BYTES _RAM[];
+__BYTES _RAMBANK[];
+__BYTES _OAMRAM[];
+__BYTE_REG _IO[];
+__BYTE_REG _AUD3WAVERAM[];
+__BYTE_REG _HRAM[];
+
+/** MBC5 registers */
+
+__BYTE_REG rRAMG;
+__BYTE_REG rROMB0;
+__BYTE_REG rROMB1;
+__BYTE_REG rRAMB;
+
+/** IO Registers */
+
+__REG P1_REG; /**< Joystick: 1.1.P15.P14.P13.P12.P11.P10 */
+#define rP1 P1_REG
+
+#define P1F_5 0b00100000
+#define P1F_4 0b00010000
+#define P1F_3 0b00001000
+#define P1F_2 0b00000100
+#define P1F_1 0b00000010
+#define P1F_0 0b00000001
+
+#define P1F_GET_DPAD P1F_5
+#define P1F_GET_BTN P1F_4
+#define P1F_GET_NONE (P1F_4 | P1F_5)
+
+__REG SB_REG; /**< Serial IO data buffer */
+#define rSB SB_REG
+__REG SC_REG; /**< Serial IO control register */
+#define rSC SC_REG
+__REG DIV_REG; /**< Divider register */
+#define rDIV DIV_REG
+__REG TIMA_REG; /**< Timer counter */
+#define rTIMA TIMA_REG
+__REG TMA_REG; /**< Timer modulo */
+#define rTMA TMA_REG
+__REG TAC_REG; /**< Timer control */
+#define rTAC TAC_REG
+
+#define TACF_START 0b00000100
+#define TACF_STOP 0b00000000
+#define TACF_4KHZ 0b00000000
+#define TACF_16KHZ 0b00000011
+#define TACF_65KHZ 0b00000010
+#define TACF_262KHZ 0b00000001
+
+#define SIOF_CLOCK_EXT 0b00000000 /**< Serial IO: Use External clock */
+#define SIOF_CLOCK_INT 0b00000001 /**< Serial IO: Use Internal clock */
+#define SIOF_SPEED_1X 0b00000000 /**< Serial IO: If internal clock then 8KHz mode, 1KB/s (16Khz in CGB high-speed mode, 2KB/s) */
+#define SIOF_SPEED_32X 0b00000010 /**< Serial IO: **CGB-Mode ONLY** If internal clock then 256KHz mode, 32KB/s (512KHz in CGB high-speed mode, 64KB/s) */
+#define SIOF_XFER_START 0b10000000 /**< Serial IO: Start Transfer. Automatically cleared at the end of transfer */
+#define SIOF_B_CLOCK 0
+#define SIOF_B_SPEED 1
+#define SIOF_B_XFER_START 7
+
+__REG IF_REG; /**< Interrupt flags: 0.0.0.JOY.SIO.TIM.LCD.VBL */
+#define rIF IF_REG
+
+__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 */
+#define rAUD1LEN NR11_REG
+__REG NR12_REG; /**< Sound Channel 1 Volume Envelope */
+#define rAUD1ENV NR12_REG
+__REG NR13_REG; /**< Sound Channel 1 Frequency Low */
+#define rAUD1LOW NR13_REG
+__REG NR14_REG; /**< Sound Channel 1 Frequency High */
+#define rAUD1HIGH NR14_REG
+
+__REG NR21_REG; /**< Sound Channel 2 Tone */
+#define rAUD2LEN NR21_REG
+__REG NR22_REG; /**< Sound Channel 2 Volume Envelope */
+#define rAUD2ENV NR22_REG
+__REG NR23_REG; /**< Sound Channel 2 Frequency data Low */
+#define rAUD2LOW NR23_REG
+__REG NR24_REG; /**< Sound Channel 2 Frequency data High */
+#define rAUD2HIGH NR24_REG
+
+__REG NR30_REG; /**< Sound Channel 3 Sound on/off */
+#define rAUD3ENA NR30_REG
+__REG NR31_REG; /**< Sound Channel 3 Sound Length */
+#define rAUD3LEN NR31_REG
+__REG NR32_REG; /**< Sound Channel 3 Select output level */
+#define rAUD3LEVEL NR32_REG
+__REG NR33_REG; /**< Sound Channel 3 Frequency data Low */
+#define rAUD3LOW NR33_REG
+__REG NR34_REG; /**< Sound Channel 3 Frequency data High */
+#define rAUD3HIGH NR34_REG
+
+__REG NR41_REG; /**< Sound Channel 4 Sound Length */
+#define rAUD4LEN NR41_REG
+__REG NR42_REG; /**< Sound Channel 4 Volume Envelope */
+#define rAUD4ENV NR42_REG
+__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 */
+#define rAUD4GO NR44_REG
+
+__REG NR50_REG; /**< Sound Channel control / ON-OFF / Volume */
+#define rAUDVOL NR50_REG
+
+#define AUDVOL_VOL_LEFT(x) ((x) << 4)
+#define AUDVOL_VOL_RIGHT(x) ((x))
+#define AUDVOL_VIN_LEFT 0b10000000
+#define AUDVOL_VIN_RIGHT 0b00001000
+
+__REG NR51_REG; /**< Sound Selection of Sound output terminal */
+#define rAUDTERM NR51_REG
+
+#define AUDTERM_4_LEFT 0b10000000
+#define AUDTERM_3_LEFT 0b01000000
+#define AUDTERM_2_LEFT 0b00100000
+#define AUDTERM_1_LEFT 0b00010000
+#define AUDTERM_4_RIGHT 0b00001000
+#define AUDTERM_3_RIGHT 0b00000100
+#define AUDTERM_2_RIGHT 0b00000010
+#define AUDTERM_1_RIGHT 0b00000001
+
+__REG NR52_REG; /**< Sound Master on/off */
+#define rAUDENA NR52_REG
+
+#define AUDENA_ON 0b10000000
+#define AUDENA_OFF 0b00000000
+
+__BYTE_REG AUD3WAVE[16];
+__BYTE_REG PCM_SAMPLE[16];
+
+__REG LCDC_REG; /**< LCD control */
+#define rLCDC LCDC_REG
+
+#if defined(__TARGET_ap)
+#define LCDCF_OFF 0b00000000
+#define LCDCF_ON 0b00000001
+#define LCDCF_WIN9800 0b00000000
+#define LCDCF_WIN9C00 0b00000010
+#define LCDCF_WINOFF 0b00000000
+#define LCDCF_WINON 0b00000100
+#define LCDCF_BG8800 0b00000000
+#define LCDCF_BG8000 0b00001000
+#define LCDCF_BG9800 0b00000000
+#define LCDCF_BG9C00 0b00010000
+#define LCDCF_OBJ8 0b00000000
+#define LCDCF_OBJ16 0b00100000
+#define LCDCF_OBJOFF 0b00000000
+#define LCDCF_OBJON 0b01000000
+#define LCDCF_BGOFF 0b00000000
+#define LCDCF_BGON 0b10000000
+#define LCDCF_B_ON 0
+#define LCDCF_B_WIN9C00 1
+#define LCDCF_B_WINON 2
+#define LCDCF_B_BG8000 3
+#define LCDCF_B_BG9C00 4
+#define LCDCF_B_OBJ16 5
+#define LCDCF_B_OBJON 6
+#define LCDCF_B_BGON 7
+#elif defined(__TARGET_duck)
+#define LCDCF_OFF 0b00000000
+#define LCDCF_ON 0b10000000
+#define LCDCF_WIN9800 0b00000000
+#define LCDCF_WIN9C00 0b00001000
+#define LCDCF_WINOFF 0b00000000
+#define LCDCF_WINON 0b00100000
+#define LCDCF_BG8800 0b00000000
+#define LCDCF_BG8000 0b00010000
+#define LCDCF_BG9800 0b00000000
+#define LCDCF_BG9C00 0b00000100
+#define LCDCF_OBJ8 0b00000000
+#define LCDCF_OBJ16 0b00000010
+#define LCDCF_OBJOFF 0b00000000
+#define LCDCF_OBJON 0b00000001
+#define LCDCF_BGOFF 0b00000000
+#define LCDCF_BGON 0b01000000
+#define LCDCF_B_ON 7
+#define LCDCF_B_WIN9C00 3
+#define LCDCF_B_WINON 5
+#define LCDCF_B_BG8000 4
+#define LCDCF_B_BG9C00 2
+#define LCDCF_B_OBJ16 1
+#define LCDCF_B_OBJON 0
+#define LCDCF_B_BGON 6
+#else
+#define LCDCF_OFF 0b00000000 /**< LCD Control: Off */
+#define LCDCF_ON 0b10000000 /**< LCD Control: On */
+#define LCDCF_WIN9800 0b00000000 /**< Window Tile Map: Use 9800 Region */
+#define LCDCF_WIN9C00 0b01000000 /**< Window Tile Map: Use 9C00 Region */
+#define LCDCF_WINOFF 0b00000000 /**< Window Display: Hidden */
+#define LCDCF_WINON 0b00100000 /**< Window Display: Visible */
+#define LCDCF_BG8800 0b00000000 /**< BG & Window Tile Data: Use 8800 Region */
+#define LCDCF_BG8000 0b00010000 /**< BG & Window Tile Data: Use 8000 Region */
+#define LCDCF_BG9800 0b00000000 /**< BG Tile Map: use 9800 Region */
+#define LCDCF_BG9C00 0b00001000 /**< BG Tile Map: use 9C00 Region */
+#define LCDCF_OBJ8 0b00000000 /**< Sprites Size: 8x8 pixels */
+#define LCDCF_OBJ16 0b00000100 /**< Sprites Size: 8x16 pixels */
+#define LCDCF_OBJOFF 0b00000000 /**< Sprites Display: Hidden */
+#define LCDCF_OBJON 0b00000010 /**< Sprites Display: Visible */
+#define LCDCF_BGOFF 0b00000000 /**< Background Display: Hidden */
+#define LCDCF_BGON 0b00000001 /**< Background Display: Visible */
+#define LCDCF_B_ON 7 /**< Bit for LCD On/Off Select */
+#define LCDCF_B_WIN9C00 6 /**< Bit for Window Tile Map Region Select */
+#define LCDCF_B_WINON 5 /**< Bit for Window Display On/Off Control */
+#define LCDCF_B_BG8000 4 /**< Bit for BG & Window Tile Data Region Select */
+#define LCDCF_B_BG9C00 3 /**< Bit for BG Tile Map Region Select */
+#define LCDCF_B_OBJ16 2 /**< Bit for Sprites Size Select */
+#define LCDCF_B_OBJON 1 /**< Bit for Sprites Display Visible/Hidden Select */
+#define LCDCF_B_BGON 0 /**< Bit for Background Display Visible/Hidden Select */
+#endif
+
+__REG STAT_REG; /**< LCD status */
+#define rSTAT STAT_REG
+
+#if defined(__TARGET_ap)
+#define STATF_LYC 0b00000010
+#define STATF_MODE10 0b00000100
+#define STATF_MODE01 0b00001000
+#define STATF_MODE00 0b00010000
+#define STATF_LYCF 0b00100000
+#define STATF_HBL 0b00000000
+#define STATF_VBL 0b10000000
+#define STATF_OAM 0b01000000
+#define STATF_LCD 0b11000000
+#define STATF_BUSY 0b01000000
+#define STATF_B_LYC 1
+#define STATF_B_MODE10 2
+#define STATF_B_MODE01 3
+#define STATF_B_MODE00 4
+#define STATF_B_LYCF 5
+#define STATF_B_VBL 7
+#define STATF_B_OAM 6
+#define STATF_B_BUSY 6
+#else
+#define STATF_LYC 0b01000000 /**< STAT Interrupt: LYC=LY Coincidence Source Enable */
+#define STATF_MODE10 0b00100000 /**< STAT Interrupt: Mode 2 OAM Source Enable */
+#define STATF_MODE01 0b00010000 /**< STAT Interrupt: Mode 1 VBlank Source Enable */
+#define STATF_MODE00 0b00001000 /**< STAT Interrupt: Mode 0 HBlank Source Enable */
+#define STATF_LYCF 0b00000100 /**< LYC=LY Coincidence Status Flag, Set when LY contains the same value as LYC */
+#define STATF_HBL 0b00000000 /**< Current LCD Mode is: 0, in H-Blank */
+#define STATF_VBL 0b00000001 /**< Current LCD Mode is: 1, in V-Blank */
+#define STATF_OAM 0b00000010 /**< Current LCD Mode is: 2, in OAM-RAM is used by system (Searching OAM) */
+#define STATF_LCD 0b00000011 /**< Current LCD Mode is: 3, both OAM and VRAM used by system (Transferring Data to LCD Controller) */
+#define STATF_BUSY 0b00000010 /**< When set, VRAM access is unsafe */
+#define STATF_B_LYC 6 /**< Bit for STAT Interrupt: LYC=LY Coincidence Source Enable */
+#define STATF_B_MODE10 5 /**< Bit for STAT Interrupt: Mode 2 OAM Source Enable */
+#define STATF_B_MODE01 4 /**< Bit for STAT Interrupt: Mode 1 VBlank Source Enable */
+#define STATF_B_MODE00 3 /**< Bit for STAT Interrupt: Mode 0 HBlank Source Enable */
+#define STATF_B_LYCF 2 /**< Bit for LYC=LY Coincidence Status Flag */
+#define STATF_B_VBL 0 /**< */
+#define STATF_B_OAM 1 /**< */
+#define STATF_B_BUSY 1 /**< Bit for when VRAM access is unsafe */
+#endif
+
+__REG SCY_REG; /**< Scroll Y */
+#define rSCY
+__REG SCX_REG; /**< Scroll X */
+#define rSCX SCX_REG
+__REG LY_REG; /**< LCDC Y-coordinate */
+#define rLY LY_REG
+__REG LYC_REG; /**< LY compare */
+#define rLYC LYC_REG
+__REG DMA_REG; /**< DMA transfer */
+#define rDMA DMA_REG
+__REG BGP_REG; /**< BG palette data */
+#define rBGP BGP_REG
+__REG OBP0_REG; /**< OBJ palette 0 data */
+#define rOBP0 OBP0_REG
+__REG OBP1_REG; /**< OBJ palette 1 data */
+#define rOBP1 OBP1_REG
+__REG WY_REG; /**< Window Y coordinate */
+#define rWY WY_REG
+__REG WX_REG; /**< Window X coordinate */
+#define rWX WX_REG
+__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 select */
+#define rVBK VBK_REG
+__REG HDMA1_REG; /**< DMA control 1 */
+#define rHDMA1 HDMA1_REG
+__REG HDMA2_REG; /**< DMA control 2 */
+#define rHDMA2 HDMA2_REG
+__REG HDMA3_REG; /**< DMA control 3 */
+#define rHDMA3 HDMA3_REG
+__REG HDMA4_REG; /**< DMA control 4 */
+#define rHDMA4 HDMA4_REG
+__REG HDMA5_REG; /**< DMA control 5 */
+#define rHDMA5 HDMA5_REG
+
+#define HDMA5F_MODE_GP 0b00000000
+#define HDMA5F_MODE_HBL 0b10000000
+
+#define HDMA5F_BUSY 0b10000000
+
+__REG RP_REG; /**< IR port */
+#define rRP RP_REG
+
+#define RPF_ENREAD 0b11000000
+#define RPF_DATAIN 0b00000010
+#define RPF_WRITE_HI 0b00000001
+#define RPF_WRITE_LO 0b00000000
+
+__REG BCPS_REG; /**< BG color palette specification */
+#define rBCPS BCPS_REG
+
+#define BCPSF_AUTOINC 0b10000000
+__REG BCPD_REG; /**< BG color palette data */
+#define rBCPD BCPD_REG
+__REG OCPS_REG; /**< OBJ color palette specification */
+#define rOCPS OCPS_REG
+
+#define OCPSF_AUTOINC 0b10000000
+__REG OCPD_REG; /**< OBJ color palette data */
+#define rOCPD OCPD_REG
+__REG SVBK_REG; /**< WRAM bank */
+#define rSVBK SVBK_REG
+#define rSMBK SVBK_REG
+
+__REG PCM12_REG; /**< Sound channel 1&2 PCM amplitude (R) */
+#define rPCM12 PCM12_REG
+
+__REG PCM34_REG; /**< Sound channel 3&4 PCM amplitude (R) */
+#define rPCM34 PCM34_REG
+
+__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
+
+
+/* Square wave duty cycle */
+#define AUDLEN_DUTY_12_5 0b00000000
+#define AUDLEN_DUTY_25 0b01000000
+#define AUDLEN_DUTY_50 0b10000000
+#define AUDLEN_DUTY_75 0b11000000
+#define AUDLEN_LENGTH(x) (x)
+
+/* Audio envelope flags */
+#define AUDENV_VOL(x) ((x) << 4)
+#define AUDENV_UP 0b00001000
+#define AUDENV_DOWN 0b00000000
+#define AUDENV_LENGTH(x) (x)
+
+/* Audio trigger flags */
+#define AUDHIGH_RESTART 0b10000000
+#define AUDHIGH_LENGTH_ON 0b01000000
+#define AUDHIGH_LENGTH_OFF 0b00000000
+
+/* OAM attributes flags */
+#define OAMF_PRI 0b10000000 /**< BG and Window over Sprite Enabled */
+#define OAMF_YFLIP 0b01000000 /**< Sprite Y axis flip: Vertically mirrored */
+#define OAMF_XFLIP 0b00100000 /**< Sprite X axis flip: Horizontally mirrored */
+#define OAMF_PAL0 0b00000000 /**< Sprite Palette number: use OBP0 (Non-CGB Mode Only) */
+#define OAMF_PAL1 0b00010000 /**< Sprite Palette number: use OBP1 (Non-CGB Mode Only) */
+#define OAMF_BANK0 0b00000000 /**< Sprite Tile VRAM-Bank: Use Bank 0 (CGB Mode Only) */
+#define OAMF_BANK1 0b00001000 /**< Sprite Tile VRAM-Bank: Use Bank 1 (CGB Mode Only) */
+
+#define OAMF_CGB_PAL0 0b00000000 /**< Sprite CGB Palette number: use OCP0 (CGB Mode Only) */
+#define OAMF_CGB_PAL1 0b00000001 /**< Sprite CGB Palette number: use OCP1 (CGB Mode Only) */
+#define OAMF_CGB_PAL2 0b00000010 /**< Sprite CGB Palette number: use OCP2 (CGB Mode Only) */
+#define OAMF_CGB_PAL3 0b00000011 /**< Sprite CGB Palette number: use OCP3 (CGB Mode Only) */
+#define OAMF_CGB_PAL4 0b00000100 /**< Sprite CGB Palette number: use OCP4 (CGB Mode Only) */
+#define OAMF_CGB_PAL5 0b00000101 /**< Sprite CGB Palette number: use OCP5 (CGB Mode Only) */
+#define OAMF_CGB_PAL6 0b00000110 /**< Sprite CGB Palette number: use OCP6 (CGB Mode Only) */
+#define OAMF_CGB_PAL7 0b00000111 /**< Sprite CGB Palette number: use OCP7 (CGB Mode Only) */
+
+#define OAMF_PALMASK 0b00000111 /**< Mask for Sprite CGB Palette number (CGB Mode Only) */
+
+#define DEVICE_SCREEN_X_OFFSET 0 /**< Offset of visible screen (in tile units) from left edge of hardware map */
+#define DEVICE_SCREEN_Y_OFFSET 0 /**< Offset of visible screen (in tile units) from top edge of hardware map */
+#define DEVICE_SCREEN_WIDTH 20 /**< Width of visible screen in tile units */
+#define DEVICE_SCREEN_HEIGHT 18 /**< Height of visible screen in tile units */
+#define DEVICE_SCREEN_BUFFER_WIDTH 32 /**< Width of hardware map buffer in tile units */
+#define DEVICE_SCREEN_BUFFER_HEIGHT 32 /**< Height of hardware map buffer in tile units */
+#define DEVICE_SCREEN_MAP_ENTRY_SIZE 1 /**< Number of bytes per hardware map entry */
+#define DEVICE_SPRITE_PX_OFFSET_X 8 /**< Offset of sprite X coordinate origin (in pixels) from left edge of visible screen */
+#define DEVICE_SPRITE_PX_OFFSET_Y 16 /**< Offset of sprite Y coordinate origin (in pixels) from top edge of visible screen */
+#define DEVICE_SCREEN_PX_WIDTH (DEVICE_SCREEN_WIDTH * 8) /**< Width of visible screen in pixels */
+#define DEVICE_SCREEN_PX_HEIGHT (DEVICE_SCREEN_HEIGHT * 8) /**< Height of visible screen in pixels */
+
+#endif
diff --git a/gbdk/gbdk-lib/include/gb/isr.h b/gbdk/gbdk-lib/include/gb/isr.h
new file mode 100644
index 00000000..59b2165f
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/isr.h
@@ -0,0 +1,74 @@
+/** @file gb/isr.h
+
+ Macros for creating raw interrupt service routines (ISRs)
+ which do not use the default GBDK ISR dispatcher.
+
+ Handlers installed this way will have less overhead than
+ ones which use the GBDK ISR dispatcher.
+*/
+#ifndef _ISR_H_INCLUDE_
+#define _ISR_H_INCLUDE_
+
+#include <stdint.h>
+#include <types.h>
+
+// #define VECTOR_VBL 0x40 // you can not define raw vector for VBlank interrupt
+#define VECTOR_STAT 0x48 /**< Address for the STAT interrupt vector */
+#define VECTOR_TIMER 0x50 /**< Address for the TIMER interrupt vector */
+#define VECTOR_SERIAL 0x58 /**< Address for the SERIAL interrupt vector */
+#define VECTOR_JOYPAD 0x60 /**< Address for the JOYPAD interrupt vector */
+
+typedef struct isr_vector_t {
+ uint8_t opcode;
+ void * func;
+} isr_vector_t;
+
+/** Creates an interrupt vector at the given address for a raw
+ interrupt service routine (which does not use the GBDK ISR dispatcher)
+
+ @param ADDR Address of the interrupt vector, any of: @ref VECTOR_STAT, @ref VECTOR_TIMER, @ref VECTOR_SERIAL, @ref VECTOR_JOYPAD
+ @param FUNC ISR function supplied by the user
+
+ This cannot be used with the VBLANK interrupt.
+
+ Do not use this in combination with interrupt installers
+ that rely on the default GBDK ISR dispatcher such as
+ @ref add_TIM(), @ref remove_TIM()
+ (and the same for all other interrupts).
+
+ Example:
+ \code{.c}
+ #include <gb/isr.h>
+
+ void TimerISR() __critical __interrupt {
+ // some ISR code here
+ }
+
+ ISR_VECTOR(VECTOR_TIMER, TimerISR)
+ \endcode
+
+ @see ISR_NESTED_VECTOR, set_interrupts
+*/
+#define ISR_VECTOR(ADDR, FUNC) \
+static const isr_vector_t AT((ADDR)) __ISR_ ## ADDR = {0xc3, (void *)&(FUNC)};
+
+typedef struct isr_nested_vector_t {
+ uint8_t opcode[2];
+ void * func;
+} isr_nested_vector_t;
+
+/** Creates an interrupt vector at the given address for a raw
+ interrupt service routine allowing nested interrupts
+
+ @param ADDR Address of the interrupt vector, any of: @ref VECTOR_STAT, @ref VECTOR_TIMER, @ref VECTOR_SERIAL, @ref VECTOR_JOYPAD
+ @param FUNC ISR function
+
+ This cannot be used with the VBLANK interrupt
+
+ @see ISR_VECTOR
+*/
+#define ISR_NESTED_VECTOR(ADDR, FUNC) \
+static const isr_nested_vector_t AT((ADDR)) __ISR_ ## ADDR = {{0xfb, 0xc3}, (void *)&(FUNC)};
+
+
+#endif // _ISR_H_INCLUDE_
diff --git a/gbdk/gbdk-lib/include/gb/metasprites.h b/gbdk/gbdk-lib/include/gb/metasprites.h
new file mode 100644
index 00000000..5bb27974
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/metasprites.h
@@ -0,0 +1,245 @@
+/** @file gb/metasprites.h
+
+ # Metasprite support
+
+ A metasprite is a larger sprite made up from a
+ collection of smaller individual hardware sprites.
+ Different frames of the same metasprites can share
+ tile data.
+
+ The api supports metasprites in both
+ @ref SPRITES_8x8 and @ref SPRITES_8x16 mode. If
+ 8x16 mode is used then the height of the metasprite
+ must be a multiple of 16.
+
+ The origin (pivot) for the metasprite is not required
+ to be in the upper left-hand corner as with regular
+ hardware sprites.
+
+ Use the @ref utility_png2asset tool to convert single
+ or multiple frames of graphics into metasprite
+ structured data for use with the ...metasprite...()
+ functions.
+
+ # Metasprites composed of variable numbers of sprites
+
+ When using png2asset, it's common for the output of
+ different frames to be composed of different numbers
+ of hardware sprites (since it's trying to create each
+ frame as efficiently as possible). Due to that, it's
+ good practice to clear out (hide) unused sprites in the
+ shadow_OAM that have been set by previous frames.
+
+ \code
+ // Example:
+ // Hide rest of the hardware sprites, because amount
+ // of sprites differ between animation frames.
+ // (where hiwater == last hardware sprite used + 1)
+ for (uint8_t i = hiwater; i < 40; i++) shadow_OAM[i].y = 0;
+ \endcode
+
+ @anchor metasprite_and_sprite_properties
+ # Metasprites and sprite properties (including cgb palette)
+
+ When the move_metasprite_*() functions are called they
+ update all properties for the affected sprites in the
+ Shadow OAM. This means any existing property flags set
+ for a sprite (CGB palette, BG/WIN priority, Tile VRAM Bank)
+ will get overwritten.
+
+ How to use sprite property flags with metasprites:
+ - Metsaprite structures can be copied into RAM so their
+ property flags can be modified at runtime.
+ - The metasprite structures can have the property flags
+ modified before compilation (such as with `-sp <props>`
+ in the @ref utility_png2asset "png2asset" tool).
+ - Update properties for the affected sprites after calling
+ a move_metasprite_*() function.
+
+ The following functions are only available for Game Boy and
+ related clone consoles due to lack of hardware support for
+ sprite flipping in other consoles. See @ref docs_consoles_supported_list
+ - @ref move_metasprite_vflip()
+ - @ref move_metasprite_hflip()
+ - @ref move_metasprite_hvflip()
+*/
+
+#ifndef _METASPRITES_H_INCLUDE
+#define _METASPRITES_H_INCLUDE
+
+#include <gb/hardware.h>
+#include <types.h>
+#include <stdint.h>
+
+/** Metasprite sub-item structure
+ @param dy (int8_t) Y coordinate of the sprite relative to the metasprite origin (pivot)
+ @param dx (int8_t) X coordinate of the sprite relative to the metasprite origin (pivot)
+ @param dtile (uint8_t) Start tile relative to the metasprites own set of tiles
+ @param props (uint8_t) Property Flags
+
+ Metasprites are built from multiple metasprite_t items (one for each sub-sprite)
+ and a pool of tiles they reference. If a metasprite has multiple frames then each
+ frame will be built from some number of metasprite_t items (which may vary based
+ on how many sprites are required for that particular frame).
+
+ A metasprite frame is terminated with a {metasprite_end} entry.
+*/
+typedef struct metasprite_t {
+ int8_t dy, dx;
+ uint8_t dtile;
+ uint8_t props;
+} metasprite_t;
+
+#define metasprite_end -128
+#define METASPR_ITEM(dy,dx,dt,a) {(dy),(dx),(dt),(a)}
+#define METASPR_TERM {metasprite_end}
+
+extern const void * __current_metasprite;
+extern uint8_t __current_base_tile;
+extern uint8_t __render_shadow_OAM;
+
+
+static uint8_t __move_metasprite(uint8_t id, uint8_t x, uint8_t y) OLDCALL;
+static uint8_t __move_metasprite_vflip(uint8_t id, uint8_t x, uint8_t y) OLDCALL;
+static uint8_t __move_metasprite_hflip(uint8_t id, uint8_t x, uint8_t y) OLDCALL;
+static uint8_t __move_metasprite_hvflip(uint8_t id, uint8_t x, uint8_t y) OLDCALL;
+static void __hide_metasprite(uint8_t id) OLDCALL;
+
+/**
+ * Hides all hardware sprites in range from <= X < to
+ * @param from start OAM index
+ * @param to finish OAM index
+ */
+void hide_sprites_range(UINT8 from, UINT8 to) OLDCALL PRESERVES_REGS(b, c);
+
+/** Moves metasprite to the absolute position x and y
+
+ @param metasprite Pointer to the first struct of the metasprite (for the desired frame)
+ @param base_tile Number of the first tile where the metasprite's tiles start
+ @param base_sprite Number of the first hardware sprite to be used by the metasprite
+ @param x Absolute x coordinate of the sprite
+ @param y Absolute y coordinate of the sprite
+
+ Moves __metasprite__ to the absolute position __x__ and __y__
+ (with __no flip__ on the X or Y axis). Hardware sprites are
+ allocated starting from __base_sprite__, using tiles
+ starting from __base_tile__.
+
+ Sets:
+ \li __current_metasprite = metasprite;
+ \li __current_base_tile = base_tile;
+
+ Note: Overwrites OAM sprite properties (such as CGB Palette), see
+ @ref metasprite_and_sprite_properties "Metasprites and sprite properties".
+
+ @return Number of hardware sprites used to draw this metasprite
+ */
+inline uint8_t move_metasprite(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_sprite, uint8_t x, uint8_t y) {
+ __current_metasprite = metasprite;
+ __current_base_tile = base_tile;
+ return __move_metasprite(base_sprite, x, y);
+}
+
+/** Moves metasprite to the absolute position x and y, __flipped on the Y axis__
+
+ @param metasprite Pointer to the first struct of the metasprite (for the desired frame)
+ @param base_tile Number of the first tile where the metasprite's tiles start
+ @param base_sprite Number of the first hardware sprite to be used by the metasprite
+ @param x Absolute x coordinate of the sprite
+ @param y Absolute y coordinate of the sprite
+
+ Same as @ref move_metasprite(), but with the metasprite flipped on the Y axis only.
+
+ Sets:
+ \li __current_metasprite = metasprite;
+ \li __current_base_tile = base_tile;
+
+ Note: Overwrites OAM sprite properties (such as CGB palette), see
+ @ref metasprite_and_sprite_properties "Metasprites and sprite properties".
+
+ This function is only available on Game Boy and related clone consoles.
+
+ @return Number of hardware sprites used to draw this metasprite
+
+ @see move_metasprite()
+*/
+inline uint8_t move_metasprite_vflip(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_sprite, uint8_t x, uint8_t y) {
+ __current_metasprite = metasprite;
+ __current_base_tile = base_tile;
+ return __move_metasprite_vflip(base_sprite, x - 8, y);
+}
+
+
+/** Moves metasprite to the absolute position x and y, __flipped on the X axis__
+
+ @param metasprite Pointer to the first struct of the metasprite (for the desired frame)
+ @param base_tile Number of the first tile where the metasprite's tiles start
+ @param base_sprite Number of the first hardware sprite to be used by the metasprite
+ @param x Absolute x coordinate of the sprite
+ @param y Absolute y coordinate of the sprite
+
+ Same as @ref move_metasprite(), but with the metasprite flipped on the X axis only.
+
+ Sets:
+ \li __current_metasprite = metasprite;
+ \li __current_base_tile = base_tile;
+
+ Note: Overwrites OAM sprite properties (such as CGB palette), see
+ @ref metasprite_and_sprite_properties "Metasprites and sprite properties".
+
+ This function is only available on Game Boy and related clone consoles.
+
+ @return Number of hardware sprites used to draw this metasprite
+
+ @see move_metasprite()
+*/
+inline uint8_t move_metasprite_hflip(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_sprite, uint8_t x, uint8_t y) {
+ __current_metasprite = metasprite;
+ __current_base_tile = base_tile;
+ return __move_metasprite_hflip(base_sprite, x, y - ((LCDC_REG & 0x04U) ? 16 : 8) );
+}
+
+/** Moves metasprite to the absolute position x and y, __flipped on the X and Y axis__
+
+ @param metasprite Pointer to the first struct of the metasprite (for the desired frame)
+ @param base_tile Number of the first tile where the metasprite's tiles start
+ @param base_sprite Number of the first hardware sprite to be used by the metasprite
+ @param x Absolute x coordinate of the sprite
+ @param y Absolute y coordinate of the sprite
+
+ Same as @ref move_metasprite(), but with the metasprite flipped on both the X and Y axis.
+
+ Sets:
+ \li __current_metasprite = metasprite;
+ \li __current_base_tile = base_tile;
+
+ Note: Overwrites OAM sprite properties (such as CGB palette), see
+ @ref metasprite_and_sprite_properties "Metasprites and sprite properties".
+
+ This function is only available on Game Boy and related clone consoles.
+
+ @return Number of hardware sprites used to draw this metasprite
+
+ @see move_metasprite()
+*/
+inline uint8_t move_metasprite_hvflip(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_sprite, uint8_t x, uint8_t y) {
+ __current_metasprite = metasprite;
+ __current_base_tile = base_tile;
+ return __move_metasprite_hvflip(base_sprite, x - 8, y - ((LCDC_REG & 0x04U) ? 16 : 8));
+}
+
+/** Hides a metasprite from the screen
+
+ @param metasprite Pointer to first struct of the desired metasprite frame
+ @param base_sprite Number of hardware sprite to start with
+
+ Sets:
+ \li __current_metasprite = metasprite;
+
+ **/
+inline void hide_metasprite(const metasprite_t * metasprite, uint8_t base_sprite) {
+ __current_metasprite = metasprite;
+ __hide_metasprite(base_sprite);
+}
+
+#endif
diff --git a/gbdk/gbdk-lib/include/gb/sgb.h b/gbdk/gbdk-lib/include/gb/sgb.h
new file mode 100644
index 00000000..ab37a04f
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gb/sgb.h
@@ -0,0 +1,65 @@
+/** @file gb/sgb.h
+ Super Gameboy definitions.
+
+ See the example SGB project for additional details.
+*/
+#ifndef _SGB_H
+#define _SGB_H
+
+#include <types.h>
+#include <stdint.h>
+
+#define SGB_PAL_01 0x00U /**< SGB Command: Set SGB Palettes 0 & 1 */
+#define SGB_PAL_23 0x01U /**< SGB Command: Set SGB Palettes 2 & 3 */
+#define SGB_PAL_03 0x02U /**< SGB Command: Set SGB Palettes 0 & 3 */
+#define SGB_PAL_12 0x03U /**< SGB Command: Set SGB Palettes 1 & 2 */
+#define SGB_ATTR_BLK 0x04U /**< SGB Command: Set color attributes for rectangular regions */
+#define SGB_ATTR_LIN 0x05U /**< SGB Command: Set color attributes for horizontal or vertical character lines */
+#define SGB_ATTR_DIV 0x06U /**< SGB Command: Split screen in half and assign separate color attribes to each side and the divider */
+#define SGB_ATTR_CHR 0x07U /**< SGB Command: Set color attributes for separate charactersSet SGB Palette 0,1 Data */
+#define SGB_SOUND 0x08U /**< SGB Command: Start and stop a internal sound effect, and sounds using internal tone data */
+#define SGB_SOU_TRN 0x09U /**< SGB Command: Transfer sound code or data to the SNES APU RAM */
+#define SGB_PAL_SET 0x0AU /**< SGB Command: Apply (previously transferred) SGB system color palettes to actual SNES palettes */
+#define SGB_PAL_TRN 0x0BU /**< SGB Command: Transfer palette data into SGB system color palettes */
+#define SGB_ATRC_EN 0x0CU /**< SGB Command: Enable/disable Attraction mode. It is enabled by default */
+#define SGB_TEST_EN 0x0DU /**< SGB Command: Enable/disable test mode for "SGB-CPU variable clock speed function" */
+#define SGB_ICON_EN 0x0EU /**< SGB Command: Enable/disable ICON functionality */
+#define SGB_DATA_SND 0x0FU /**< SGB Command: Write one or more bytes into SNES Work RAM */
+#define SGB_DATA_TRN 0x10U /**< SGB Command: Transfer code or data into SNES RAM */
+#define SGB_MLT_REQ 0x11U /**< SGB Command: Request multiplayer mode (input from more than one joypad) */
+#define SGB_JUMP 0x12U /**< SGB Command: Set the SNES program counter and NMI (vblank interrupt) handler to specific addresses */
+#define SGB_CHR_TRN 0x13U /**< SGB Command: Transfer tile data (characters) to SNES Tile memory */
+#define SGB_PCT_TRN 0x14U /**< SGB Command: Transfer tile map and palette data to SNES BG Map memory */
+#define SGB_ATTR_TRN 0x15U /**< SGB Command: Transfer data to (color) Attribute Files (ATFs) in SNES RAM */
+#define SGB_ATTR_SET 0x16U /**< SGB Command: Transfer attributes from (color) Attribute Files (ATF) to the Game Boy window */
+#define SGB_MASK_EN 0x17U /**< SGB Command: Modify Game Boy window mask settings */
+#define SGB_OBJ_TRN 0x18U /**< SGB Command: Transfer OBJ attributes to SNES OAM memory */
+
+
+/** Returns a non-null value if running on Super GameBoy */
+uint8_t sgb_check() OLDCALL PRESERVES_REGS(b, c);
+
+/** Transfer a SGB packet
+
+ @param packet Pointer to buffer with SGB packet data.
+
+ The first byte of __packet__ should be a SGB command,
+ then up to 15 bytes of command parameter data.
+
+ See the `sgb_border` GBDK example project for a
+ demo of how to use these the sgb functions.
+
+ When using the SGB with a PAL SNES, a delay should be added
+ just after program startup such as:
+
+ \code{.c}
+ // Wait 4 frames
+ // For PAL SNES this delay is required on startup
+ for (uint8_t i = 4; i != 0; i--) wait_vbl_done();
+ \endcode
+
+ @see sgb_check()
+*/
+void sgb_transfer(uint8_t * packet) OLDCALL PRESERVES_REGS(b, c);
+
+#endif /* _SGB_H */
diff --git a/gbdk/gbdk-lib/include/gbdk/bcd.h b/gbdk/gbdk-lib/include/gbdk/bcd.h
new file mode 100644
index 00000000..f2e9ef3b
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/bcd.h
@@ -0,0 +1,12 @@
+#ifndef __GBDK_BCD_H_INCLUDE
+#define __GBDK_BCD_H_INCLUDE
+
+#if defined(__TARGET_gb) || defined(__TARGET_ap) || defined(__TARGET_duck)
+ #include <gb/bcd.h>
+#elif defined(__TARGET_sms) || defined(__TARGET_gg) || defined(__TARGET_msxdos)
+ #error Not implemented yet
+#else
+ #error Unrecognized port
+#endif
+
+#endif \ No newline at end of file
diff --git a/gbdk/gbdk-lib/include/gbdk/console.h b/gbdk/gbdk-lib/include/gbdk/console.h
new file mode 100644
index 00000000..9458829b
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/console.h
@@ -0,0 +1,45 @@
+/** @file gbdk/console.h
+ Console functions that work like Turbo C's.
+
+ The font is 8x8, making the screen 20x18 characters.
+*/
+#ifndef _CONSOLE_H
+#define _CONSOLE_H
+
+#include <types.h>
+#include <stdint.h>
+
+/** Move the cursor to an absolute position at __x, y__.
+
+ __x__ and __y__ have units of tiles (8 pixels per unit)
+ @see setchar()
+ */
+void gotoxy(uint8_t x, uint8_t y) OLDCALL;
+
+/** Returns the current X position of the cursor.
+
+ @see gotoxy()
+ */
+uint8_t posx() OLDCALL;
+
+/** Returns the current Y position of the cursor.
+
+ @see gotoxy()
+ */
+uint8_t posy() OLDCALL;
+
+/** Writes out a single character at the current cursor
+ position.
+
+ Does not update the cursor or interpret the character.
+
+ @see gotoxy()
+*/
+void setchar(char c) OLDCALL;
+
+/** Clears the screen
+*/
+void cls();
+
+
+#endif /* _CONSOLE_H */
diff --git a/gbdk/gbdk-lib/include/gbdk/emu_debug.h b/gbdk/gbdk-lib/include/gbdk/emu_debug.h
new file mode 100644
index 00000000..33f559af
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/emu_debug.h
@@ -0,0 +1,179 @@
+/** @file gbdk/emu_debug.h
+
+ Debug window logging and profiling support for emulators (BGB, Emulicious, etc).
+
+ Also see the `emu_debug` example project included with gbdk.
+
+ See the BGB Manual for more information
+ ("expressions, breakpoint conditions, and debug messages")
+ http://bgb.bircd.org/manual.html#expressions
+
+*/
+
+#ifndef __GBDK_EMU_DEBUG_H_INCLUDE
+#define __GBDK_EMU_DEBUG_H_INCLUDE
+
+#include <types.h>
+
+#if defined(__TARGET_gb) || defined(__TARGET_ap) || defined(__TARGET_sms) || defined(__TARGET_gg)
+
+/** Macro to display a message in the emulator debug message window
+
+ @param message_text Quoted text string to display in the debug message window
+
+ The following special parameters can be
+ used when bracketed with "%" characters.
+ \li CPU registers: AF, BC, DE, HL, SP, PC, B, C, D,
+ E, H, L, A, ZERO, ZF, Z, CARRY, CY, IME, ALLREGS
+ \li Other state values: ROMBANK, XRAMBANK, SRAMBANK,
+ WRAMBANK, VRAMBANK, TOTALCLKS, LASTCLKS, CLKS2VBLANK
+
+ Example: print a message along with the currently active ROM bank.
+ \code{.c}
+ EMU_MESSAGE("Current ROM Bank is: %ROMBANK%");
+ \endcode
+
+
+ See the BGB Manual for more information
+ ("expressions, breakpoint conditions, and debug messages")
+ http://bgb.bircd.org/manual.html#expressions
+
+ @see EMU_PROFILE_BEGIN(), EMU_PROFILE_END()
+ */
+#define EMU_MESSAGE(message_text) EMU_MESSAGE1(EMU_MACRONAME(__LINE__), message_text)
+#define BGB_MESSAGE(message_text) EMU_MESSAGE(message_text)
+
+/// \cond DOXYGEN_DO_NOT_DOCUMENT
+#define EMU_MACRONAME(A) EMU_MACRONAME1(A)
+#define EMU_MACRONAME1(A) EMULOG##A
+
+#define EMU_MESSAGE1(name, message_text) \
+__asm \
+.MACRO name msg_t, ?llbl\
+ ld d, d \
+ jr llbl \
+ .dw 0x6464 \
+ .dw 0x0000 \
+ .ascii msg_t \
+llbl: \
+.ENDM \
+name ^/message_text/ \
+__endasm
+
+#define EMU_MESSAGE_SUFFIX(message_text, message_suffix) EMU_MESSAGE3(EMU_MACRONAME(__LINE__), message_text, message_suffix)
+#define EMU_MESSAGE3(name, message_text, message_suffix) \
+__asm \
+.MACRO name msg_t, msg_s, ?llbl\
+ ld d, d \
+ jr llbl \
+ .dw 0x6464 \
+ .dw 0x0000 \
+ .ascii msg_t \
+ .ascii msg_s \
+llbl: \
+.ENDM \
+name ^/message_text/, ^/message_suffix/ \
+__endasm
+/// \endcond DOXYGEN_DO_NOT_DOCUMENT
+
+/** Macro to __Start__ a profiling block for the emulator (BGB, Emulicious, etc)
+
+ @param MSG Quoted text string to display in the
+ debug message window along with the result
+
+ To complete the profiling block and print
+ the result call @ref EMU_PROFILE_END.
+
+ @see EMU_PROFILE_END(), EMU_MESSAGE()
+ */
+#define EMU_PROFILE_BEGIN(MSG) EMU_MESSAGE_SUFFIX(MSG, "%ZEROCLKS%");
+#define BGB_PROFILE_BEGIN(MSG) EMU_PROFILE_BEGIN(MSG)
+/** Macro to __End__ a profiling block and print the results in the emulator debug message window
+
+ @param MSG Quoted text string to display in the
+ debug message window along with the result
+
+ This should only be called after a previous call
+ to @ref EMU_PROFILE_BEGIN()
+
+ The results are in Emulator clock units, which are
+ "1 nop in [CGB] doublespeed mode".
+
+ So when running in Normal Speed mode (i.e. non-CGB doublespeed)
+ the printed result should be __divided by 2__ to get the actual
+ ellapsed cycle count.
+
+ If running in CB Double Speed mode use the below call instead,
+ it correctly compensates for the speed difference. In this
+ scenario, the result does __not need to be divided by 2__ to
+ get the ellapsed cycle count.
+ \code{.c}
+ EMU_MESSAGE("NOP TIME: %-4+LASTCLKS%");
+ \endcode
+
+ @see EMU_PROFILE_BEGIN(), EMU_MESSAGE()
+ */
+#if defined(NINTENDO)
+#define EMU_PROFILE_END(MSG) EMU_MESSAGE_SUFFIX(MSG,"%-8+LASTCLKS%");
+#define BGB_PROFILE_END(MSG) EMU_PROFILE_END(MSG)
+#elif defined(SEGA)
+#define EMU_PROFILE_END(MSG) EMU_MESSAGE_SUFFIX(MSG,"%-16+LASTCLKS%");
+#define BGB_PROFILE_END(MSG) EMU_PROFILE_END(MSG)
+#endif
+
+#define EMU_TEXT(MSG) EMU_MESSAGE(MSG)
+#define BGB_TEXT(MSG) EMU_TEXT(MSG)
+
+/** Display preset debug information in the Emulator debug messages window.
+
+ This function is equivalent to:
+ \code{.c}
+ EMU_MESSAGE("PROFILE,%(SP+$0)%,%(SP+$1)%,%A%,%TOTALCLKS%,%ROMBANK%,%WRAMBANK%");
+ \endcode
+
+*/
+#if defined(NINTENDO)
+void EMU_profiler_message();
+#define BGB_profiler_message() EMU_profiler_message()
+#endif // NINTENDO
+
+/** Print the string and arguments given by format to the emulator debug message window
+
+ @param format The format string as per printf
+
+ Does not return the number of characters printed.
+ Result string MUST BE LESS OR EQUAL THAN 128 BYTES LONG, INCLUDING THE TRAILIG ZERO BYTE!
+
+ Currently supported:
+ \li \%hx (char as hex)
+ \li \%hu (unsigned char)
+ \li \%hd (signed char)
+ \li \%c (character)
+ \li \%u (unsigned int)
+ \li \%d (signed int)
+ \li \%x (unsigned int as hex)
+ \li \%s (string)
+
+ Warning: to correctly pass chars for printing as chars, they *must*
+ be explicitly re-cast as such when calling the function.
+ See @ref docs_chars_varargs for more details.
+ */
+void EMU_printf(const char *format, ...) OLDCALL;
+#define BGB_printf(...) EMU_printf(__VA_ARGS__)
+
+#ifdef NINTENDO
+static void * __EMU_PROFILER_INIT = &EMU_profiler_message;
+#endif // NINTENDO
+
+/** The Emulator will break into debugger when encounters this line
+ */
+#define EMU_BREAKPOINT __asm__("ld b, b");
+#define BGB_BREAKPOINT EMU_BREAKPOINT
+
+#elif defined(__TARGET_duck)
+ #error Not implemented yet
+#else
+ #error Unrecognized port
+#endif
+
+#endif \ No newline at end of file
diff --git a/gbdk/gbdk-lib/include/gbdk/far_ptr.h b/gbdk/gbdk-lib/include/gbdk/far_ptr.h
new file mode 100644
index 00000000..39f75d4e
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/far_ptr.h
@@ -0,0 +1,99 @@
+/** @file gbdk/far_ptr.h
+
+ Far pointers include a segment (bank) selector so they are
+ able to point to addresses (functions or data) outside
+ of the current bank (unlike normal pointers which are not
+ bank-aware).
+
+ See the `banks_farptr` example project included with gbdk.
+
+ @todo Add link to a discussion about banking (such as, how to assign code and variables to banks)
+*/
+
+#ifndef __FAR_PTR_H_INCLUDE
+#define __FAR_PTR_H_INCLUDE
+
+#include <types.h>
+#include <stdint.h>
+
+/** Macro to obtain a far pointer at compile-time
+ @param ofs Memory address within the given Segment (Bank)
+ @param seg Segment (Bank) number
+
+ @returns A far pointer (type @ref FAR_PTR)
+*/
+#define TO_FAR_PTR(ofs, seg) (((FAR_PTR)seg << 16) | (FAR_PTR)ofs)
+
+/** Macro to get the Segment (Bank) number of a far pointer
+ @param ptr A far pointer (type @ref FAR_PTR)
+
+ @returns Segment (Bank) of the far pointer (type uint16_t)
+*/
+#define FAR_SEG(ptr) (((union __far_ptr *)&ptr)->segofs.seg)
+
+/** Macro to get the Offset (address) of a far pointer
+ @param ptr A far pointer (type @ref FAR_PTR)
+
+ @returns Offset (address) of the far pointer (type void *)
+*/
+#define FAR_OFS(ptr) (((union __far_ptr *)&ptr)->segofs.ofs)
+
+#define FAR_FUNC(ptr, typ) ((typ)(((union __far_ptr *)&ptr)->segfn.fn))
+
+/** Macro to call a function at far pointer __ptr__ of type __typ__
+ @param ptr Far pointer of a function to call (type @ref FAR_PTR)
+ @param typ Type to cast the function far pointer to.
+ @param ... VA Args list of parameters for the function
+
+ __type__ should match the definition of the function being called. For example:
+ \code{.c}
+ // A function in bank 2
+ #pragma bank 2
+ uint16_t some_function(uint16_t param1, uint16_t param2) __banked { return 1; };
+
+ ...
+ // Code elsewhere, such as unbanked main()
+ // This type declaration should match the above function
+ typedef uint16_t (*some_function_t)(uint16_t, uint16_t) __banked;
+
+ // Using FAR_CALL() with the above as *ptr*, *typ*, and two parameters.
+ result = FAR_CALL(some_function, some_function_t, 100, 50);
+ \endcode
+
+ @returns Value returned by the function (if present)
+*/
+#define FAR_CALL(ptr, typ, ...) (__call_banked_ptr=ptr,((typ)(&__call__banked))(__VA_ARGS__))
+
+/** Type for storing a FAR_PTR
+*/
+typedef uint32_t FAR_PTR;
+
+/** Union for working with members of a FAR_PTR
+*/
+union __far_ptr {
+ FAR_PTR ptr;
+ struct {
+ void * ofs;
+ uint16_t seg;
+ } segofs;
+ struct {
+ void (*fn)();
+ uint16_t seg;
+ } segfn;
+};
+
+extern volatile FAR_PTR __call_banked_ptr;
+extern volatile void * __call_banked_addr;
+extern volatile uint8_t __call_banked_bank;
+
+void __call__banked();
+
+/** Obtain a far pointer at runtime
+ @param ofs Memory address within the given Segment (Bank)
+ @param seg Segment (Bank) number
+
+ @returns A far pointer (type @ref FAR_PTR)
+*/
+uint32_t to_far_ptr(void* ofs, uint16_t seg) OLDCALL;
+
+#endif \ No newline at end of file
diff --git a/gbdk/gbdk-lib/include/gbdk/font.h b/gbdk/gbdk-lib/include/gbdk/font.h
new file mode 100644
index 00000000..05af2e49
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/font.h
@@ -0,0 +1,78 @@
+/** @file gbdk/font.h
+ Multiple font support for the GameBoy
+ Michael Hope, 1999
+ michaelh@earthling.net
+*/
+#ifndef __FONT_H
+#define __FONT_H
+
+#include <types.h>
+#include <stdint.h>
+
+/** Various flags in the font header.
+ */
+#define FONT_256ENCODING 0
+#define FONT_128ENCODING 1
+#define FONT_NOENCODING 2
+
+#define FONT_COMPRESSED 4
+
+/* See gb.h/M_NO_SCROLL and gb.h/M_NO_INTERP */
+
+/** font_t is a handle to a font loaded by font_load().
+ It can be used with @ref font_set() */
+typedef uint16_t font_t;
+
+
+/*! \defgroup gbdk_fonts List of gbdk fonts
+ @{
+*/
+
+/** The default fonts */
+extern uint8_t font_spect[], font_italic[], font_ibm[], font_min[];
+
+/** Backwards compatible font */
+extern uint8_t font_ibm_fixed[];
+
+ /*! @} End of gbdk_fonts */
+
+
+/** Initializes the font system.
+ Should be called before other font functions.
+ */
+void font_init();
+
+/** Load a font and set it as the current font.
+ @param font Pointer to a font to load (usually a gbdk font)
+
+ @return Handle to the loaded font, which can be used with @ref font_set()
+ @see font_init(), font_set(), gbdk_fonts
+ */
+font_t font_load(void *font) OLDCALL;
+
+/** Set the current font.
+ @param font_handle handle of a font returned by @ref font_load()
+
+ @return The previously used font handle.
+ @see font_init(), font_load()
+*/
+font_t font_set(font_t font_handle) OLDCALL;
+
+/* Use mode() and color() to set the font modes and colours */
+
+/** Internal representation of a font.
+ What a font_t really is */
+typedef struct sfont_handle mfont_handle;
+typedef struct sfont_handle *pmfont_handle;
+
+/** Font handle structure
+*/
+struct sfont_handle {
+ uint8_t first_tile; /**< First tile used for font */
+ void *font; /**< Pointer to the base of the font */
+};
+
+/** Set the current __foreground__ colour (for pixels), __background__ colour */
+void font_color(uint8_t forecolor, uint8_t backcolor) OLDCALL;
+
+#endif /* __FONT_H */
diff --git a/gbdk/gbdk-lib/include/gbdk/gbdecompress.h b/gbdk/gbdk-lib/include/gbdk/gbdecompress.h
new file mode 100644
index 00000000..5865dd23
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/gbdecompress.h
@@ -0,0 +1,12 @@
+#ifndef __GB_DECOMPRESS_H_INCLUDE
+#define __GB_DECOMPRESS_H_INCLUDE
+
+#if defined(__TARGET_gb) || defined(__TARGET_ap) || defined(__TARGET_duck)
+ #include <gb/gbdecompress.h>
+#elif defined(__TARGET_sms) || defined(__TARGET_gg)
+ #include <sms/gbdecompress.h>
+#else
+ #error Unrecognized port
+#endif
+
+#endif \ No newline at end of file
diff --git a/gbdk/gbdk-lib/include/gbdk/gbdk-lib.h b/gbdk/gbdk-lib/include/gbdk/gbdk-lib.h
new file mode 100644
index 00000000..8c9a6570
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/gbdk-lib.h
@@ -0,0 +1,26 @@
+/** @file gbdk/gbdk-lib.h
+ Settings for the greater library system.
+*/
+#ifndef GBDK_LIB_INCLUDE
+#define GBDK_LIB_INCLUDE
+
+#if defined(__PORT_sm83)
+ #include <asm/sm83/provides.h>
+#elif defined(__PORT_z80)
+ #include <asm/z80/provides.h>
+#else
+ #error Unrecognized port
+#endif
+
+
+#ifndef USE_C_MEMCPY
+#define USE_C_MEMCPY 1
+#endif
+#ifndef USE_C_STRCPY
+#define USE_C_STRCPY 1
+#endif
+#ifndef USE_C_STRCMP
+#define USE_C_STRCMP 1
+#endif
+
+#endif
diff --git a/gbdk/gbdk-lib/include/gbdk/incbin.h b/gbdk/gbdk-lib/include/gbdk/incbin.h
new file mode 100644
index 00000000..b230c46c
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/incbin.h
@@ -0,0 +1,84 @@
+/** @file gbdk/incbin.h
+
+ Allows binary data from other files to be included
+ into a C source file.
+
+ It is implemented using asm .incbin and macros.
+
+ See the `incbin` example project for a demo of how to use it.
+*/
+#ifndef _INCBIN_H
+#define _INCBIN_H
+
+#include <stdint.h>
+
+
+/** Creates extern entries for accessing a INCBIN() generated
+ variable and it's size in another source file.
+
+ @param VARNAME Name of the variable used with INCBIN
+
+ An entry is created for the variable and it's size variable.
+
+ @ref INCBIN(), INCBIN_SIZE()
+*/
+#define INCBIN_EXTERN(VARNAME) extern const uint8_t VARNAME[]; \
+extern const void __size_ ## VARNAME; \
+extern const void __bank_ ## VARNAME;
+
+/** Obtains the __size in bytes__ of the INCBIN() generated data
+
+ @param VARNAME Name of the variable used with INCBIN
+
+ Requires @ref INCBIN_EXTERN() to have been called earlier in the source file
+
+ @ref INCBIN(), INCBIN_EXTERN()
+*/
+#define INCBIN_SIZE(VARNAME) ( (uint16_t) & __size_ ## VARNAME )
+
+/** Obtains the __bank number__ of the INCBIN() generated data
+
+ @param VARNAME Name of the variable used with INCBIN
+
+ Requires @ref INCBIN_EXTERN() to have been called earlier in the source file
+
+ @ref INCBIN(), INCBIN_EXTERN()
+*/
+#ifndef BANK
+#define BANK(VARNAME) ( (uint8_t) & __bank_ ## VARNAME )
+#endif
+
+/** Includes binary data into a C source file
+
+ @param VARNAME Variable name to use
+ @param FILEPATH Path to the file which will be binary included into the C source file
+
+ __filepath__ is relative to the working directory of the tool
+ that is calling it (often a makefile's working directory), __NOT__
+ to the file it's being included into.
+
+ 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.
+
+ Use @ref INCBIN_EXTERN() within another source file
+ to make the variable and it's data accesible there.
+*/
+#define INCBIN(VARNAME, FILEPATH) void __func_ ## VARNAME() __banked __naked { \
+__asm \
+_ ## VARNAME:: \
+1$: \
+ .incbin FILEPATH \
+2$: \
+ ___size_ ## VARNAME = (2$-1$) \
+ .globl ___size_ ## VARNAME \
+ .local b___func_ ## VARNAME \
+ ___bank_ ## VARNAME = b___func_ ## VARNAME \
+ .globl ___bank_ ## VARNAME \
+__endasm; \
+}
+
+#endif // _INCBIN_H
+
+
diff --git a/gbdk/gbdk-lib/include/gbdk/metasprites.h b/gbdk/gbdk-lib/include/gbdk/metasprites.h
new file mode 100644
index 00000000..4b5ce011
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/metasprites.h
@@ -0,0 +1,14 @@
+#ifndef __PLAT_METASPRITES_H_INVCLUDE
+#define __PLAT_METASPRITES_H_INVCLUDE
+
+#if defined(__TARGET_gb) || defined(__TARGET_ap) || defined(__TARGET_duck)
+ #include <gb/metasprites.h>
+#elif defined(__TARGET_sms) || defined(__TARGET_gg)
+ #include <sms/metasprites.h>
+#elif defined(__TARGET_msxdos)
+ #include <msx/metasprites.h>
+#else
+ #error Unrecognized port
+#endif
+
+#endif \ No newline at end of file
diff --git a/gbdk/gbdk-lib/include/gbdk/platform.h b/gbdk/gbdk-lib/include/gbdk/platform.h
new file mode 100644
index 00000000..b69da550
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/platform.h
@@ -0,0 +1,16 @@
+#ifndef __PLATFORM_H_INCLUDE
+#define __PLATFORM_H_INCLUDE
+
+#if defined(__TARGET_gb) || defined(__TARGET_ap) || defined(__TARGET_duck)
+ #include <gb/gb.h>
+ #include <gb/cgb.h>
+ #include <gb/sgb.h>
+#elif defined(__TARGET_sms) || defined(__TARGET_gg)
+ #include <sms/sms.h>
+#elif defined(__TARGET_msxdos)
+ #include <msx/msx.h>
+#else
+ #error Unrecognized port
+#endif
+
+#endif \ No newline at end of file
diff --git a/gbdk/gbdk-lib/include/gbdk/rledecompress.h b/gbdk/gbdk-lib/include/gbdk/rledecompress.h
new file mode 100644
index 00000000..5c61ea82
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/rledecompress.h
@@ -0,0 +1,47 @@
+/** @file gbdk/rledecompress.h
+
+ Decompressor for RLE encoded data
+
+ Decompresses data which has been compressed with
+ @ref utility_gbcompress "gbcompress" using the `--alg=rle` argument.
+*/
+
+#ifndef __RLEDECOMPRESS_H_INCLUDE
+#define __RLEDECOMPRESS_H_INCLUDE
+
+#include <types.h>
+#include <stdint.h>
+
+#define RLE_STOP 0
+
+#if defined(__TARGET_gb) || defined(__TARGET_ap) || defined(__TARGET_duck)
+/** Initialize the RLE decompressor with RLE data at address __data__
+
+ @param data Pointer to start of RLE compressed data
+
+ @see rle_decompress
+ */
+uint8_t rle_init(void * data) OLDCALL;
+
+/** Decompress RLE compressed data into __dest__ for length __len__ bytes
+
+ @param dest Pointer to destination buffer/address
+ @param len number of bytes to decompress
+
+ Before calling this function @ref rle_init must be called
+ one time to initialize the RLE decompressor.
+
+ Decompresses data which has been compressed with
+ @ref utility_gbcompress "gbcompress" using the `--alg=rle` argument.
+
+ @see rle_init
+ */
+uint8_t rle_decompress(void * dest, uint8_t len) OLDCALL;
+#elif defined(__TARGET_sms) || defined(__TARGET_gg)
+uint8_t rle_init(void * data) Z88DK_FASTCALL;
+uint8_t rle_decompress(void * dest, uint8_t len) Z88DK_CALLEE;
+#else
+ #error Unrecognized port
+#endif
+
+#endif \ No newline at end of file
diff --git a/gbdk/gbdk-lib/include/gbdk/version.h b/gbdk/gbdk-lib/include/gbdk/version.h
new file mode 100644
index 00000000..21ba93a5
--- /dev/null
+++ b/gbdk/gbdk-lib/include/gbdk/version.h
@@ -0,0 +1,6 @@
+#ifndef __VERSION_H_INCLUDE__
+#define __VERSION_H_INCLUDE__
+
+#define __GBDK_VERSION 406
+
+#endif
diff --git a/gbdk/gbdk-lib/include/limits.h b/gbdk/gbdk-lib/include/limits.h
new file mode 100644
index 00000000..5cadc137
--- /dev/null
+++ b/gbdk/gbdk-lib/include/limits.h
@@ -0,0 +1,69 @@
+/*-------------------------------------------------------------------------
+ limits.h - ANSI defines constants for sizes of integral types
+
+ Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ As a special exception, if you link this library with other files,
+ some of which are compiled with SDCC, to produce an executable,
+ this library does not by itself cause the resulting executable to
+ be covered by the GNU General Public License. This exception does
+ not however invalidate any other reasons why the executable file
+ might be covered by the GNU General Public License.
+-------------------------------------------------------------------------*/
+
+#ifndef __SDC51_LIMITS_H
+#define __SDC51_LIMITS_H 1
+
+#define CHAR_BIT 8 /* bits in a char */
+#define SCHAR_MAX 127
+#define SCHAR_MIN -128
+#define UCHAR_MAX 0xff
+
+#ifdef __SDCC_CHAR_UNSIGNED
+#define CHAR_MAX UCHAR_MAX
+#define CHAR_MIN 0
+#else
+#define CHAR_MAX SCHAR_MAX
+#define CHAR_MIN SCHAR_MIN
+#endif
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199409L
+#define MB_LEN_MAX 4
+#endif
+
+#define INT_MIN (-32767 - 1)
+#define INT_MAX 32767
+#define SHRT_MAX INT_MAX
+#define SHRT_MIN INT_MIN
+#define UINT_MAX 0xffff
+#define UINT_MIN 0
+#define USHRT_MAX UINT_MAX
+#define USHRT_MIN UINT_MIN
+#define LONG_MIN (-2147483647L-1)
+#define LONG_MAX 2147483647L
+#define ULONG_MAX 0xffffffff
+#define ULONG_MIN 0
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#define LLONG_MIN (-9223372036854775807LL-1)
+#define LLONG_MAX 9223372036854775807LL
+#define ULLONG_MAX 18446744073709551615ULL
+#endif
+
+#endif
+
diff --git a/gbdk/gbdk-lib/include/msx/hardware.h b/gbdk/gbdk-lib/include/msx/hardware.h
new file mode 100644
index 00000000..1a3b4dcb
--- /dev/null
+++ b/gbdk/gbdk-lib/include/msx/hardware.h
@@ -0,0 +1,201 @@
+/** @file msx/hardware.h
+ Defines that let the MSX hardware registers be accessed
+ from C.
+*/
+#ifndef _HARDWARE_H
+#define _HARDWARE_H
+
+#include <types.h>
+
+#define __BYTES extern UBYTE
+#define __BYTE_REG extern volatile UBYTE
+
+static volatile SFR AT(0x3E) MEMORY_CTL;
+
+#define MEMCTL_JOYON 0b00000000
+#define MEMCTL_JOYOFF 0b00000100
+#define MEMCTL_BASEON 0b00000000
+#define MEMCTL_BASEOFF 0b00001000
+#define MEMCTL_RAMON 0b00000000
+#define MEMCTL_RAMOFF 0b00010000
+#define MEMCTL_CROMON 0b00000000
+#define MEMCTL_CROMOFF 0b00100000
+#define MEMCTL_ROMON 0b00000000
+#define MEMCTL_ROMOFF 0b01000000
+#define MEMCTL_EXTON 0b00000000
+#define MEMCTL_EXTOFF 0b10000000
+
+static volatile SFR AT(0x3F) JOY_CTL;
+
+#define JOY_P1_LATCH 0b00000010
+#define JOY_P2_LATCH 0b00001000
+
+static volatile SFR AT(0x7E) VCOUNTER;
+
+static volatile SFR AT(0x7F) PSG;
+
+#define PSG_LATCH 0x80
+
+#define PSG_CH0 0b00000000
+#define PSG_CH1 0b00100000
+#define PSG_CH2 0b01000000
+#define PSG_CH3 0b01100000
+
+#define PSG_VOLUME 0b00010000
+
+static volatile SFR AT(0x7F) HCOUNTER;
+
+static volatile SFR AT(0x98) VDP_DATA;
+static volatile SFR AT(0x99) VDP_CMD;
+static volatile SFR AT(0x99) VDP_STATUS;
+
+#define STATF_INT_VBL 0b10000000
+#define STATF_9_SPR 0b01000000
+#define STATF_SPR_COLL 0b00100000
+
+#define VDP_REG_MASK 0b10000000
+#define VDP_R0 0b10000000
+extern UBYTE shadow_VDP_R0;
+
+#define R0_DEFAULT 0b00000000
+#define R0_CB_OUTPUT 0b00000000
+#define R0_CB_INPUT 0b01000000
+#define R0_IE2_OFF 0b00000000
+#define R0_IE2 0b00100000
+#define R0_IE1_OFF 0b00000000
+#define R0_IE1 0b00010000
+#define R0_SCR_MODE1 0b00000000
+#define R0_SCR_MODE2 0b00000010
+#define R0_SCR_MODE3 0b00000100
+#define R0_ES_OFF 0b00000000
+#define R0_ES 0b00000001
+
+#define VDP_R1 0b10000001
+extern UBYTE shadow_VDP_R1;
+
+#define R1_DEFAULT 0b10000000
+#define R1_DISP_OFF 0b00000000
+#define R1_DISP_ON 0b01000000
+#define R1_IE_OFF 0b00000000
+#define R1_IE 0b00100000
+#define R1_SCR_MODE1 0b00010000
+#define R1_SCR_MODE2 0b00000000
+#define R1_SCR_MODE3 0b00000000
+#define R1_SPR_8X8 0b00000000
+#define R1_SPR_16X16 0b00000010
+#define R1_SPR_MAG 0b00000001
+#define R1_SPR_MAG_OFF 0b00000000
+
+#define VDP_R2 0b10000010
+extern UBYTE shadow_VDP_R2;
+
+#define R2_MAP_0x3800 0xFF
+#define R2_MAP_0x3000 0xFD
+#define R2_MAP_0x2800 0xFB
+#define R2_MAP_0x2000 0xF9
+#define R2_MAP_0x1800 0xF7
+#define R2_MAP_0x1000 0xF5
+#define R2_MAP_0x0800 0xF3
+#define R2_MAP_0x0000 0xF1
+
+#define VDP_R3 0b10000011
+extern UBYTE shadow_VDP_R3;
+#define VDP_R4 0b10000100
+extern UBYTE shadow_VDP_R4;
+#define VDP_R5 0b10000101
+extern UBYTE shadow_VDP_R5;
+
+#define R5_SAT_0x3F00 0xFF
+#define R5_SAT_MASK 0b10000001
+
+#define VDP_R6 0b10000110
+extern UBYTE shadow_VDP_R6;
+
+#define R6_BANK0 0xFB
+#define R6_DATA_0x0000 0xFB
+#define R6_BANK1 0xFF
+#define R6_DATA_0x2000 0xFF
+
+#define VDP_R7 0b10000111
+extern UBYTE shadow_VDP_R7;
+#define VDP_RBORDER 0b10000111
+extern UBYTE shadow_VDP_RBORDER;
+
+#define R7_COLOR_MASK 0b11110000
+
+#define VDP_R8 0b10001000
+extern UBYTE shadow_VDP_R8;
+#define VDP_RSCX 0b10001000
+extern UBYTE shadow_VDP_RSCX;
+
+#define VDP_R9 0b10001001
+extern UBYTE shadow_VDP_R9;
+#define VDP_RSCY 0b10001001
+extern UBYTE shadow_VDP_RSCY;
+
+#define VDP_R10 0b10001010
+extern UBYTE shadow_VDP_R10;
+
+#define R10_INT_OFF 0xFF
+#define R10_INT_EVERY 0x00
+
+static volatile SFR AT(0xDC) JOY_PORT1;
+
+#define JOY_P1_UP 0b00000001
+#define JOY_P1_DOWN 0b00000010
+#define JOY_P1_LEFT 0b00000100
+#define JOY_P1_RIGHT 0b00001000
+#define JOY_P1_SW1 0b00010000
+#define JOY_P1_TRIGGER 0b00010000
+#define JOY_P1_SW2 0b00100000
+#define JOY_P2_UP 0b01000000
+#define JOY_P2_DOWN 0b10000000
+
+static volatile SFR AT(0xDD) JOY_PORT2;
+
+#define JOY_P2_LEFT 0b00000001
+#define JOY_P2_RIGHT 0b00000010
+#define JOY_P2_SW1 0b00000100
+#define JOY_P2_TRIGGER 0b00000100
+#define JOY_P2_SW2 0b00001000
+#define JOY_RESET 0b00010000
+#define JOY_P1_LIGHT 0b01000000
+#define JOY_P2_LIGHT 0b10000000
+
+static volatile SFR AT(0xF0) FMADDRESS;
+static volatile SFR AT(0xF1) FMDATA;
+static volatile SFR AT(0xF2) AUDIOCTRL;
+
+static volatile SFR AT(0xfc) MAP_FRAME0;
+static volatile SFR AT(0xfd) MAP_FRAME1;
+static volatile SFR AT(0xfe) MAP_FRAME2;
+static volatile SFR AT(0xff) MAP_FRAME3;
+
+extern const UBYTE _BIOS;
+
+extern const UBYTE _SYSTEM;
+
+#define SYSTEM_PAL 0x00
+#define SYSTEM_NTSC 0x01
+
+extern volatile UBYTE VDP_ATTR_SHIFT;
+
+#define VDP_SAT_TERM 0xD0
+
+#if defined(__TARGET_msxdos)
+#define DEVICE_SCREEN_X_OFFSET 0
+#define DEVICE_SCREEN_Y_OFFSET 0
+#define DEVICE_SCREEN_WIDTH 32
+#define DEVICE_SCREEN_HEIGHT 24
+#define DEVICE_SCREEN_BUFFER_WIDTH 32
+#define DEVICE_SCREEN_BUFFER_HEIGHT 28
+#define DEVICE_SCREEN_MAP_ENTRY_SIZE 2
+#define DEVICE_SPRITE_PX_OFFSET_X 0
+#define DEVICE_SPRITE_PX_OFFSET_Y -1
+#else
+#error Unrecognized port
+#endif
+#define DEVICE_SCREEN_PX_WIDTH (DEVICE_SCREEN_WIDTH * 8)
+#define DEVICE_SCREEN_PX_HEIGHT (DEVICE_SCREEN_HEIGHT * 8)
+
+#endif
diff --git a/gbdk/gbdk-lib/include/msx/metasprites.h b/gbdk/gbdk-lib/include/msx/metasprites.h
new file mode 100644
index 00000000..92e7bbc6
--- /dev/null
+++ b/gbdk/gbdk-lib/include/msx/metasprites.h
@@ -0,0 +1,118 @@
+/** @file sms/metasprites.h
+
+ # Metasprite support
+
+ A metasprite is a larger sprite made up from a
+ collection of smaller individual hardware sprites.
+ Different frames of the same metasprites can share
+ tile data.
+
+ The api supports metasprites in both
+ @ref SPRITES_8x8 and @ref SPRITES_8x16 mode. If
+ 8x16 mode is used then the height of the metasprite
+ must be a multiple of 16.
+
+ The origin (pivot) for the metasprite is not required
+ to be in the upper left-hand corner as with regular
+ hardware sprites.
+
+ Use the @ref utility_png2asset tool to convert single
+ or multiple frames of graphics into metasprite
+ structured data for use with the ...metasprite...()
+ functions.
+
+ # Metasprites composed of variable numbers of sprites
+
+ When using png2asset, it's common for the output of
+ different frames to be composed of different numbers
+ of hardware sprites (since it's trying to create each
+ frame as efficiently as possible). Due to that, it's
+ good practice to clear out (hide) unused sprites in the
+ shadow_OAM that have been set by previous frames.
+*/
+
+#ifndef _METASPRITES_H_INCLUDE
+#define _METASPRITES_H_INCLUDE
+
+#include <msx/hardware.h>
+#include <types.h>
+#include <stdint.h>
+
+/** Metasprite sub-item structure
+ @param dy (int8_t) Y coordinate of the sprite relative to the metasprite origin (pivot)
+ @param dx (int8_t) X coordinate of the sprite relative to the metasprite origin (pivot)
+ @param dtile (uint8_t) Start tile relative to the metasprites own set of tiles
+ @param props (uint8_t) Property Flags
+
+ Metasprites are built from multiple metasprite_t items (one for each sub-sprite)
+ and a pool of tiles they reference. If a metasprite has multiple frames then each
+ frame will be built from some number of metasprite_t items (which may vary based
+ on how many sprites are required for that particular frame).
+
+ A metasprite frame is terminated with a {metasprite_end} entry.
+*/
+typedef struct metasprite_t {
+ int8_t dy, dx;
+ uint8_t dtile;
+ uint8_t props;
+} metasprite_t;
+
+#define metasprite_end -128
+#define METASPR_ITEM(dy,dx,dt,a) {(dy),(dx),(dt),(a)}
+#define METASPR_TERM {metasprite_end}
+
+extern const void * __current_metasprite;
+extern uint8_t __current_base_tile;
+extern uint8_t __render_shadow_OAM;
+
+
+static uint8_t __move_metasprite(uint8_t id, uint8_t x, uint8_t y) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+static void __hide_metasprite(uint8_t id) Z88DK_FASTCALL PRESERVES_REGS(iyh, iyl);
+
+/**
+ * Hides all hardware sprites in range from <= X < to
+ * @param from start OAM index
+ * @param to finish OAM index
+ */
+void hide_sprites_range(UINT8 from, UINT8 to) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+
+/** Moves metasprite to the absolute position x and y
+
+ @param metasprite Pointer to the first struct of the metasprite (for the desired frame)
+ @param base_tile Number of the first tile where the metasprite's tiles start
+ @param base_sprite Number of the first hardware sprite to be used by the metasprite
+ @param x Absolute x coordinate of the sprite
+ @param y Absolute y coordinate of the sprite
+
+ Moves __metasprite__ to the absolute position __x__ and __y__
+ (with __no flip__ on the X or Y axis). Hardware sprites are
+ allocated starting from __base_sprite__, using tiles
+ starting from __base_tile__.
+
+ Sets:
+ \li __current_metasprite = metasprite;
+ \li __current_base_tile = base_tile;
+
+ @return Number of hardware sprites used to draw this metasprite
+ */
+inline uint8_t move_metasprite(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_sprite, uint8_t x, uint8_t y) {
+ __current_metasprite = metasprite;
+ __current_base_tile = base_tile;
+ return __move_metasprite(base_sprite, x, y);
+}
+
+/** Hides a metasprite from the screen
+
+ @param metasprite Pointer to first struct of the desired metasprite frame
+ @param base_sprite Number of hardware sprite to start with
+
+ Sets:
+ \li __current_metasprite = metasprite;
+
+ **/
+inline void hide_metasprite(const metasprite_t * metasprite, uint8_t base_sprite) {
+ __current_metasprite = metasprite;
+ __hide_metasprite(base_sprite);
+}
+
+#endif
diff --git a/gbdk/gbdk-lib/include/msx/msx.h b/gbdk/gbdk-lib/include/msx/msx.h
new file mode 100644
index 00000000..58dce3b5
--- /dev/null
+++ b/gbdk/gbdk-lib/include/msx/msx.h
@@ -0,0 +1,751 @@
+/** @file msx/msx.h
+ MSX specific functions.
+*/
+#ifndef _MSX_H
+#define _MSX_H
+
+#include <types.h>
+#include <stdint.h>
+#include <gbdk/version.h>
+#include <msx/hardware.h>
+
+#define MSX
+#ifdef NINTENDO
+#undef NINTENDO
+#endif
+#ifdef SEGA
+#undef SEGA
+#endif
+#if defined(__TARGET_msxdos)
+#define MSXDOS
+#endif
+
+
+#define VBK_REG VDP_ATTR_SHIFT
+
+/** Joypad bits.
+ A logical OR of these is used in the wait_pad and joypad
+ functions. For example, to see if the B button is pressed
+ try
+
+ uint8_t keys;
+ keys = joypad();
+ if (keys & J_B) {
+ ...
+ }
+
+ @see joypad
+ */
+#define J_UP 0b00100000
+#define J_DOWN 0b01000000
+#define J_LEFT 0b00010000
+#define J_RIGHT 0b10000000
+#define J_A 0b00000001
+#define J_B 0b00000100
+#define J_SELECT 0b00001000
+#define J_START 0b00000010
+
+/** Screen modes.
+ Normally used by internal functions only.
+ @see mode()
+ */
+#define M_TEXT_OUT 0x02U
+#define M_TEXT_INOUT 0x03U
+/** Set this in addition to the others to disable scrolling
+
+ If scrolling is disabled, the cursor returns to (0,0)
+ @see mode()
+*/
+#define M_NO_SCROLL 0x04U
+/** Set this to disable interpretation
+ @see mode()
+*/
+#define M_NO_INTERP 0x08U
+
+/** If set the background tile will be flipped horizontally.
+ */
+#define S_FLIPX 0x02U
+/** If set the background tile will be flipped vertically.
+ */
+#define S_FLIPY 0x04U
+/** If set the background tile palette.
+ */
+#define S_PALETTE 0x08U
+/** If set the background tile priority.
+ */
+#define S_PRIORITY 0x10U
+
+// VDP helper macros
+#define __WRITE_VDP_REG(REG, v) shadow_##REG=(v);__critical{VDP_CMD=(shadow_##REG),VDP_CMD=REG;}
+#define __READ_VDP_REG(REG) shadow_##REG
+
+void WRITE_VDP_CMD(uint16_t cmd) Z88DK_FASTCALL PRESERVES_REGS(b, c, d, e, iyh, iyl);
+void WRITE_VDP_DATA(uint16_t data) Z88DK_FASTCALL PRESERVES_REGS(b, c, d, e, iyh, iyl);
+
+/** Set the current screen mode - one of M_* modes
+
+ Normally used by internal functions only.
+
+ @see M_TEXT_OUT, M_TEXT_INOUT, M_NO_SCROLL, M_NO_INTERP
+*/
+void mode(uint8_t m) OLDCALL;
+
+/** Returns the current mode
+
+ @see M_TEXT_OUT, M_TEXT_INOUT, M_NO_SCROLL, M_NO_INTERP
+*/
+uint8_t get_mode() OLDCALL;
+
+/* Interrupt flags */
+/** Disable calling of interrupt service routines
+ */
+#define EMPTY_IFLAG 0x00U
+/** VBlank Interrupt occurs at the start of the vertical blank.
+
+ During this period the video ram may be freely accessed.
+ @see set_interrupts(), @see add_VBL
+ */
+#define VBL_IFLAG 0x01U
+/** LCD Interrupt when triggered by the STAT register.
+ @see set_interrupts(), @see add_LCD
+*/
+#define LCD_IFLAG 0x02U
+/** Does nothing on MSX
+ */
+#define TIM_IFLAG 0x04U
+/** Does nothing on MSX
+ */
+#define SIO_IFLAG 0x08U
+/** Does nothing on MSX
+ */
+#define JOY_IFLAG 0x10U
+
+void set_interrupts(uint8_t flags) Z88DK_FASTCALL;
+
+/* Limits */
+/** Width of the visible screen in pixels.
+ */
+#define SCREENWIDTH DEVICE_SCREEN_PX_WIDTH
+/** Height of the visible screen in pixels.
+ */
+#define SCREENHEIGHT DEVICE_SCREEN_PX_HEIGHT
+/** The Minimum X position of the Window Layer (Left edge of screen) @see move_win()
+ */
+#define MINWNDPOSX 0x00U
+/** The Minimum Y position of the Window Layer (Top edge of screen) @see move_win()
+ */
+#define MINWNDPOSY 0x00U
+/** The Maximum X position of the Window Layer (Right edge of screen) @see move_win()
+ */
+#define MAXWNDPOSX 0x00U
+/** The Maximum Y position of the Window Layer (Bottom edge of screen) @see move_win()
+ */
+#define MAXWNDPOSY 0x00U
+
+
+/** Interrupt handlers
+ */
+typedef void (*int_handler)(void) NONBANKED;
+
+/** Removes the VBL interrupt handler.
+ @see add_VBL()
+*/
+void remove_VBL(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(iyh, iyl);
+
+/** Removes the LCD interrupt handler.
+ @see add_LCD(), remove_VBL()
+*/
+void remove_LCD(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(b, c, iyh, iyl);
+
+void remove_TIM(int_handler h) Z88DK_FASTCALL;
+void remove_SIO(int_handler h) Z88DK_FASTCALL;
+void remove_JOY(int_handler h) Z88DK_FASTCALL;
+
+/** Adds a V-blank interrupt handler.
+*/
+void add_VBL(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(d, e, iyh, iyl);
+
+/** Adds a LCD interrupt handler.
+*/
+void add_LCD(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(b, c, iyh, iyl);
+
+/** Does nothing on MSX
+ */
+void add_TIM(int_handler h) Z88DK_FASTCALL;
+
+/** Does nothing on MSX
+ */
+void add_SIO(int_handler h) Z88DK_FASTCALL;
+
+/** Does nothing on MSX
+ */
+void add_JOY(int_handler h) Z88DK_FASTCALL;
+
+/** Cancel pending interrupts
+ */
+inline uint8_t cancel_pending_interrupts() {
+ return VDP_STATUS;
+}
+
+inline void move_bkg(uint8_t x, uint8_t y) {
+ __WRITE_VDP_REG(VDP_RSCX, -x);
+ __WRITE_VDP_REG(VDP_RSCY, y);
+}
+
+inline void scroll_bkg(int8_t x, int8_t y) {
+ __WRITE_VDP_REG(VDP_RSCX, __READ_VDP_REG(VDP_RSCX) - x);
+ int16_t tmp = __READ_VDP_REG(VDP_RSCY) + y;
+ __WRITE_VDP_REG(VDP_RSCY, (tmp < 0) ? 224 + tmp : tmp % 224u);
+}
+
+/** HALTs the CPU and waits for the vertical blank interrupt (VBL) to finish.
+
+ This is often used in main loops to idle the CPU at low power
+ until it's time to start the next frame. It's also useful for
+ syncing animation with the screen re-draw.
+
+ Warning: If the VBL interrupt is disabled, this function will
+ never return. If the screen is off this function returns
+ immediately.
+*/
+void wait_vbl_done() PRESERVES_REGS(b, c, d, e, h, l, iyh, iyl);
+
+/** Turns the display off.
+
+ @see DISPLAY_ON
+*/
+inline void display_off() {
+ __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) &= (~R1_DISP_ON));
+}
+
+/** Turns the display back on.
+ @see display_off, DISPLAY_OFF
+*/
+#define DISPLAY_ON \
+ __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) |= R1_DISP_ON)
+
+/** Turns the display off immediately.
+ @see display_off, DISPLAY_ON
+*/
+#define DISPLAY_OFF \
+ display_off();
+
+/** Copies data from shadow OAM to OAM
+ */
+void refresh_OAM();
+
+/** Blanks leftmost column, so it is not garbaged when you use horizontal scroll
+ @see SHOW_LEFT_COLUMN
+*/
+#define HIDE_LEFT_COLUMN \
+ __WRITE_VDP_REG(VDP_R0, __READ_VDP_REG(VDP_R0) |= R0_LCB)
+
+/** Shows leftmost column
+ @see HIDE_LEFT_COLUMN
+*/
+#define SHOW_LEFT_COLUMN \
+ __WRITE_VDP_REG(VDP_R0, __READ_VDP_REG(VDP_R0) &= (~R0_LCB))
+
+/** Turns on the background layer.
+ Not yet implemented
+*/
+#define SHOW_BKG
+
+/** Turns off the background layer.
+ Not yet implemented
+*/
+#define HIDE_BKG
+
+/** Turns on the window layer
+ Not yet implemented
+*/
+#define SHOW_WIN
+
+/** Turns off the window layer.
+ Not yet implemented
+*/
+#define HIDE_WIN
+
+/** Turns on the sprites layer.
+ Not yet implemented
+*/
+#define SHOW_SPRITES
+
+/** Turns off the sprites layer.
+ Not yet implemented
+*/
+#define HIDE_SPRITES
+
+/** Sets sprite size to 8x16 pixels, two tiles one above the other.
+*/
+#define SPRITES_16x16 \
+ __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) |= R1_SPR_16X16)
+
+/** Sets sprite size to 8x8 pixels, one tile.
+*/
+#define SPRITES_8x8 \
+ __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) &= (~R1_SPR_16X16))
+
+/** Macro returns TRUE if device supports color
+ * (it always does on MSX)
+ */
+#define DEVICE_SUPPORTS_COLOR (TRUE)
+
+/** Global Time Counter in VBL periods (60Hz)
+
+ Increments once per Frame
+
+ Will wrap around every ~18 minutes (unsigned 16 bits = 65535 / 60 / 60 = 18.2)
+*/
+extern volatile uint16_t sys_time;
+
+/** Tracks current active ROM bank in frame 1
+*/
+extern volatile uint8_t _current_bank;
+#define CURRENT_BANK _current_bank
+
+/** Obtains the __bank number__ of VARNAME
+
+ @param VARNAME Name of the variable which has a __bank_VARNAME companion symbol which is adjusted by bankpack
+
+ Use this to obtain the bank number from a bank reference
+ created with @ref BANKREF().
+
+ @see BANKREF_EXTERN(), BANKREF()
+*/
+#ifndef BANK
+#define BANK(VARNAME) ( (uint8_t) & __bank_ ## VARNAME )
+#endif
+
+/** Creates a reference for retrieving the bank number of a variable or function
+
+ @param VARNAME Variable name to use, which may be an existing identifier
+
+ @see BANK() for obtaining the bank number of the included data.
+
+ More than one `BANKREF()` may be created per file, but each call should
+ always use a unique VARNAME.
+
+ Use @ref BANKREF_EXTERN() within another source file
+ to make the variable and it's data accesible there.
+*/
+#define BANKREF(VARNAME) void __func_ ## VARNAME() __banked __naked { \
+__asm \
+ .local b___func_ ## VARNAME \
+ ___bank_ ## VARNAME = b___func_ ## VARNAME \
+ .globl ___bank_ ## VARNAME \
+__endasm; \
+}
+
+/** Creates extern references for accessing a BANKREF() generated variable.
+
+ @param VARNAME Name of the variable used with @ref BANKREF()
+
+ This makes a @ref BANKREF() reference in another source
+ file accessible in the current file for use with @ref BANK().
+
+ @see BANKREF(), BANK()
+*/
+#define BANKREF_EXTERN(VARNAME) extern const void __bank_ ## VARNAME;
+
+
+/** Makes switch the active ROM bank in frame 1
+ @param b ROM bank to switch to
+*/
+
+void SWITCH_ROM(uint8_t bank) Z88DK_FASTCALL PRESERVES_REGS(b, c, d, e, iyh, iyl);
+#define SWITCH_ROM1 SWITCH_ROM
+
+/** Makes switch the active ROM bank in frame 2
+ @param b ROM bank to switch to
+*/
+
+#define SWITCH_ROM2(b) MAP_FRAME2=(b)
+
+/** Switches RAM bank
+ @param b SRAM bank to switch to
+*/
+
+#define SWITCH_RAM(b) RAM_CONTROL=((b)&1)?RAM_CONTROL|RAMCTL_BANK:RAM_CONTROL&(~RAMCTL_BANK)
+
+/** Enables RAM
+*/
+
+#define ENABLE_RAM RAM_CONTROL|=RAMCTL_RAM
+
+/** Disables RAM
+*/
+
+#define DISABLE_RAM RAM_CONTROL&=(~RAMCTL_RAM)
+
+
+/** Delays the given number of milliseconds.
+ Uses no timers or interrupts, and can be called with
+ interrupts disabled
+ */
+void delay(uint16_t d) Z88DK_FASTCALL;
+
+
+/** Reads and returns the current state of the joypad.
+*/
+uint8_t joypad() OLDCALL PRESERVES_REGS(b, c, d, e, h, iyh, iyl);
+
+/** Waits until at least one of the buttons given in mask are pressed.
+*/
+uint8_t waitpad(uint8_t mask) Z88DK_FASTCALL PRESERVES_REGS(b, c, d, e, iyh, iyl);
+
+/** Waits for the directional pad and all buttons to be released.
+
+ Note: Checks in a loop that doesn't HALT at all, so the CPU
+ will be maxed out until this call returns.
+*/
+void waitpadup() PRESERVES_REGS(b, c, d, e, iyh, iyl);
+
+/** Multiplayer joypad structure.
+
+ Must be initialized with @ref joypad_init() first then it
+ may be used to poll all avaliable joypads with @ref joypad_ex()
+*/
+typedef struct {
+ uint8_t npads;
+ union {
+ struct {
+ uint8_t joy0, joy1, joy2, joy3;
+ };
+ uint8_t joypads[4];
+ };
+} joypads_t;
+
+/** Initializes joypads_t structure for polling multiple joypads
+ @param npads number of joypads requested (1, 2 or 4)
+ @param joypads pointer to joypads_t structure to be initialized
+
+ Only required for @ref joypad_ex, not required for calls to regular @ref joypad()
+ @returns number of joypads avaliable
+ @see joypad_ex(), joypads_t
+*/
+uint8_t joypad_init(uint8_t npads, joypads_t * joypads) Z88DK_CALLEE;
+
+/** Polls all avaliable joypads
+ @param joypads pointer to joypads_t structure to be filled with joypad statuses,
+ must be previously initialized with joypad_init()
+
+ @see joypad_init(), joypads_t
+*/
+void joypad_ex(joypads_t * joypads) Z88DK_FASTCALL PRESERVES_REGS(iyh, iyl);
+
+
+#if defined(__TARGET_msxdos)
+
+#define RGB(r,g,b) ((r) | ((g) << 2) | ((b) << 4))
+#define RGB8(r,g,b) (((r) >> 6) | (((g) >> 6) << 2) | (((b) >> 6) << 4))
+#define RGBHTML(RGB24bit) (((RGB24bit) >> 22) | ((((RGB24bit) & 0xFFFF) >> 14) << 2) | ((((RGB24bit) & 0xFF) >> 6) << 4))
+
+/** Common colors based on the EGA default palette.
+ */
+#define RGB_RED RGB( 3, 0, 0)
+#define RGB_DARKRED RGB( 2, 0, 0)
+#define RGB_GREEN RGB( 0, 3, 0)
+#define RGB_DARKGREEN RGB( 0, 2, 0)
+#define RGB_BLUE RGB( 0, 0, 3)
+#define RGB_DARKBLUE RGB( 0, 0, 2)
+#define RGB_YELLOW RGB( 3, 3, 0)
+#define RGB_DARKYELLOW RGB( 2, 2, 0)
+#define RGB_CYAN RGB( 0, 3, 3)
+#define RGB_AQUA RGB( 3, 1, 2)
+#define RGB_PINK RGB( 3, 0, 3)
+#define RGB_PURPLE RGB( 2, 0, 2)
+#define RGB_BLACK RGB( 0, 0, 0)
+#define RGB_DARKGRAY RGB( 1, 1, 1)
+#define RGB_LIGHTGRAY RGB( 2, 2, 2)
+#define RGB_WHITE RGB( 3, 3, 3)
+
+typedef uint8_t palette_color_t;
+
+#else
+#error Unrecognized port
+#endif
+
+void set_default_palette();
+inline void cpu_fast() {}
+
+void set_palette_entry(uint8_t palette, uint8_t entry, uint16_t rgb_data) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+#define set_bkg_palette_entry set_palette_entry
+#define set_sprite_palette_entry(palette,entry,rgb_data) set_palette_entry(1,entry,rgb_data)
+void set_palette(uint8_t first_palette, uint8_t nb_palettes, palette_color_t *rgb_data) Z88DK_CALLEE;
+#define set_bkg_palette set_palette
+#define set_sprite_palette(first_palette,nb_palettes,rgb_data) set_palette(1,1,rgb_data)
+
+void set_native_tile_data(uint16_t start, uint16_t ntiles, const void *src) Z88DK_CALLEE;
+inline void set_bkg_4bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_native_tile_data(start, ntiles, src);
+}
+void set_sprite_1bpp_data(uint16_t start, uint16_t ntiles, const void *src) Z88DK_CALLEE;
+inline void set_native_sprite_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_sprite_1bpp_data(start, ntiles, src);
+}
+
+#define COMPAT_PALETTE(C0,C1,C2,C3) (((uint16_t)(C3) << 12) | ((uint16_t)(C2) << 8) | ((uint16_t)(C1) << 4) | (uint16_t)(C0))
+extern uint16_t _current_2bpp_palette;
+inline void set_2bpp_palette(uint16_t palette) {
+ _current_2bpp_palette = palette;
+}
+//void set_tile_2bpp_data(uint16_t start, uint16_t ntiles, const void *src, uint16_t palette) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+inline void set_bkg_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_native_tile_data(start, ntiles, src);
+}
+inline void set_sprite_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_sprite_1bpp_data(start, ntiles, src);
+}
+//inline void set_bkg_2bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
+// set_tile_2bpp_data(start, ntiles, src, _current_2bpp_palette);
+//}
+//inline void set_sprite_2bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
+// set_tile_2bpp_data((uint8_t)(start) + 0x100u, ntiles, src, _current_2bpp_palette);
+//}
+
+extern uint16_t _current_1bpp_colors;
+inline void set_1bpp_colors(uint8_t fgcolor, uint8_t bgcolor) {
+ _current_1bpp_colors = ((uint16_t)bgcolor << 8) | fgcolor;
+}
+void set_tile_1bpp_data(uint16_t start, uint16_t ntiles, const void *src, uint16_t colors) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+inline void set_bkg_1bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_tile_1bpp_data(start, ntiles, src, _current_1bpp_colors);
+}
+
+
+/** Copies arbitrary data to an address in VRAM
+
+ @param dst destination VRAM Address
+ @param src Pointer to source buffer
+ @param size Number of bytes to copy
+
+ Copies __size__ bytes from a buffer at _src__ to VRAM starting at __dst__.
+*/
+void set_data(uint16_t dst, const void *src, uint16_t size) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+void vmemcpy(uint16_t dst, const void *src, uint16_t size) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+
+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);
+#define set_bkg_tiles set_tile_map
+#define set_win_tiles set_tile_map
+
+extern uint8_t _map_tile_offset;
+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) {
+ _map_tile_offset = base_tile;
+ set_tile_map(x, y, w, h, tiles);
+ _map_tile_offset = 0;
+}
+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) {
+ _map_tile_offset = base_tile;
+ set_tile_map(x, y, w, h, tiles);
+ _map_tile_offset = 0;
+}
+
+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);
+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);
+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) {
+ set_tile_submap_compat(x, y, w, h, map_w, map);
+}
+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) {
+ set_tile_submap_compat(x, y, w, h, map_w, map);
+}
+
+extern uint8_t _submap_tile_offset;
+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) {
+ _submap_tile_offset = base_tile;
+ set_tile_submap_compat(x, y, w, h, map_w, map);
+ _submap_tile_offset = 0;
+}
+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) {
+ _submap_tile_offset = base_tile;
+ set_tile_submap_compat(x, y, w, h, map_w, map);
+ _submap_tile_offset = 0;
+}
+
+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);
+#define fill_bkg_rect fill_rect
+#define fill_win_rect fill_rect
+
+/** Sprite Attributes structure
+ @param x X Coordinate of the sprite on screen
+ @param y Y Coordinate of the sprite on screen
+ @param tile Sprite tile number (see @ref set_sprite_tile)
+ @param prop OAM Property Flags (see @ref set_sprite_prop)
+*/
+typedef struct OAM_item_t {
+ uint8_t y, x; //< X, Y Coordinates of the sprite on screen
+ uint8_t tile; //< Sprite tile number
+ uint8_t prop; //< OAM Property Flags
+} OAM_item_t;
+
+
+/** Shadow OAM array in WRAM, that is DMA-transferred into the real OAM each VBlank
+*/
+extern volatile struct OAM_item_t shadow_OAM[];
+
+/** MSB of shadow_OAM address is used by OAM copying routine
+*/
+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 MSX 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;
+
+/** Disable shadow OAM to VRAM copy on each VBlank
+*/
+#define DISABLE_VBL_TRANSFER \
+ _shadow_OAM_base = 0
+
+/** Enable shadow OAM to VRAM copy on each VBlank
+*/
+#define ENABLE_VBL_TRANSFER \
+ _shadow_OAM_base = (uint8_t)((uint16_t)&shadow_OAM >> 8)
+
+/** Amount of hardware sprites in OAM
+*/
+#define MAX_HARDWARE_SPRITES 32
+
+/** Sets address of 256-byte aligned array of shadow OAM to be transferred on each VBlank
+*/
+inline void SET_SHADOW_OAM_ADDRESS(void * address) {
+ _shadow_OAM_base = (uint8_t)((uint16_t)address >> 8);
+}
+
+/** Sets sprite number __nb__in the OAM to display tile number __tile__.
+
+ @param nb Sprite number, range 0 - 39
+ @param tile Selects a tile (0 - 255) from memory at 8000h - 8FFFh
+ \n In CGB Mode this could be either in VRAM Bank
+ \n 0 or 1, depending on Bit 3 of the OAM Attribute Flag
+ \n (see @ref set_sprite_prop)
+
+ In 8x16 mode:
+ \li The sprite will also display the next tile (__tile__ + 1)
+ directly below (y + 8) the first tile.
+ \li The lower bit of the tile number is ignored:
+ the upper 8x8 tile is (__tile__ & 0xFE), and
+ the lower 8x8 tile is (__tile__ | 0x01).
+ \li See: @ref SPRITES_8x16
+*/
+inline void set_sprite_tile(uint8_t nb, uint8_t tile) {
+ shadow_OAM[nb].tile=tile;
+}
+
+
+/** Returns the tile number of sprite number __nb__ in the OAM.
+
+@param nb Sprite number, range 0 - 39
+
+@see set_sprite_tile for more details
+*/
+inline uint8_t get_sprite_tile(uint8_t nb) {
+ return shadow_OAM[nb].tile;
+}
+
+inline void set_sprite_prop(uint8_t nb, uint8_t prop) {
+ shadow_OAM[nb].prop = prop;
+}
+
+inline uint8_t get_sprite_prop(uint8_t nb) {
+ return shadow_OAM[nb].prop;
+}
+
+/** Moves sprite number __nb__ to the __x__, __y__ position on the screen.
+
+ @param nb Sprite number, range 0 - 39
+ @param x X Position. Specifies the sprites horizontal position on the screen (minus 8).
+ \n An offscreen value (X=0 or X>=168) hides the sprite, but the sprite
+ still affects the priority ordering - a better way to hide a sprite is to set
+ its Y-coordinate offscreen.
+ @param y Y Position. Specifies the sprites vertical position on the screen (minus 16).
+ \n An offscreen value (for example, Y=0 or Y>=160) hides the sprite.
+
+ Moving the sprite to 0,0 (or similar off-screen location) will hide it.
+*/
+inline void move_sprite(uint8_t nb, uint8_t x, uint8_t y) {
+ OAM_item_t * itm = &shadow_OAM[nb];
+ itm->y=y, itm->x=x;
+}
+
+
+/** Moves sprite number __nb__ relative to its current position.
+
+ @param nb Sprite number, range 0 - 39
+ @param x Number of pixels to move the sprite on the __X axis__
+ \n Range: -128 - 127
+ @param y Number of pixels to move the sprite on the __Y axis__
+ \n Range: -128 - 127
+
+ @see move_sprite for more details about the X and Y position
+ */
+inline void scroll_sprite(uint8_t nb, int8_t x, int8_t y) {
+ OAM_item_t * itm = &shadow_OAM[nb];
+ itm->y+=y, itm->x+=x;
+}
+
+
+/** Hides sprite number __nb__ by moving it to zero position by Y.
+
+ @param nb Sprite number, range 0 - 39
+ */
+inline void hide_sprite(uint8_t nb) {
+ shadow_OAM[nb].y = 0xC0;
+}
+
+/**
+ * Set byte in vram at given memory location
+ *
+ * @param addr address to write to
+ * @param v value
+ */
+void set_vram_byte(uint8_t * addr, uint8_t v) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+
+/**
+ * Set single tile t with attributes on background layer at x,y
+ * @param x X-coordinate
+ * @param y Y-coordinate
+ * @param t tile index
+ * @return returns the address of tile, so you may use faster set_vram_byte() later
+ */
+uint8_t * set_attributed_tile_xy(uint8_t x, uint8_t y, uint16_t t) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+
+/**
+ * Set single tile t on background layer at x,y
+ * @param x X-coordinate
+ * @param y Y-coordinate
+ * @param t tile index
+ * @return returns the address of tile, so you may use faster set_vram_byte() later
+ */
+uint8_t * set_tile_xy(uint8_t x, uint8_t y, uint8_t t) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+#define set_bkg_tile_xy set_tile_xy
+#define set_win_tile_xy set_tile_xy
+
+/**
+ * Get address of X,Y tile of background map
+ */
+uint8_t * get_bkg_xy_addr(uint8_t x, uint8_t y) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+#define get_win_xy_addr get_bkg_xy_addr
+
+#endif /* _MSX_H */
diff --git a/gbdk/gbdk-lib/include/rand.h b/gbdk/gbdk-lib/include/rand.h
new file mode 100644
index 00000000..af477280
--- /dev/null
+++ b/gbdk/gbdk-lib/include/rand.h
@@ -0,0 +1,83 @@
+/** @file rand.h
+ Random generator using the linear congruential method
+
+ @author Luc Van den Borre
+*/
+#ifndef RAND_INCLUDE
+#define RAND_INCLUDE
+
+#include <types.h>
+#include <stdint.h>
+
+/** Initalise the pseudo-random number generator.
+
+ @param seed The value for initializing the random number generator.
+
+ 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).
+
+ Only needs to be called once to initialize, but may be called
+ again to re-initialize with the same or a different seed.
+
+ @see rand(), randw()
+*/
+#if defined(__PORT_sm83)
+void initrand(uint16_t seed) OLDCALL;
+#elif defined(__PORT_z80)
+void initrand(uint16_t seed) Z88DK_FASTCALL;
+#endif
+
+#define RAND_MAX 255
+#define RANDW_MAX 65535
+
+/** The random number seed is stored in __rand_seed and can be
+ saved and restored if needed.
+
+ \code{.c}
+ // Save
+ some_uint16 = __rand_seed;
+ ...
+ // Restore
+ __rand_seed = some_uint16;
+ \endcode
+*/
+extern uint16_t __rand_seed;
+
+/** Returns a random byte (8 bit) value.
+
+ @ref initrand() should be used to initialize the random number generator before using rand()
+ */
+uint8_t rand() OLDCALL;
+
+/** Returns a random word (16 bit) value.
+
+ @ref initrand() should be used to initialize the random number generator before using rand()
+ */
+uint16_t randw() OLDCALL;
+
+/** Random generator using the linear lagged additive method
+
+ @param seed The value for initializing the random number generator.
+
+ Note: initarand() calls @ref initrand() with the same seed value, and
+ uses @ref rand() to initialize the random generator.
+
+ @see initrand() for suggestions about seed values, arand()
+*/
+#if defined(__PORT_sm83)
+void initarand(uint16_t seed) OLDCALL;
+#elif defined(__PORT_z80)
+void initarand(uint16_t seed) Z88DK_FASTCALL;
+#endif
+
+/** Returns a random number generated with the linear lagged additive method.
+
+ @ref initarand() should be used to initialize the random number generator before using arand()
+ */
+uint8_t arand() OLDCALL;
+
+#endif
diff --git a/gbdk/gbdk-lib/include/setjmp.h b/gbdk/gbdk-lib/include/setjmp.h
new file mode 100644
index 00000000..e0572596
--- /dev/null
+++ b/gbdk/gbdk-lib/include/setjmp.h
@@ -0,0 +1,83 @@
+/*-------------------------------------------------------------------------
+ setjmp.h - header file for setjmp & longjmp ANSI routines
+
+ Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ As a special exception, if you link this library with other files,
+ some of which are compiled with SDCC, to produce an executable,
+ this library does not by itself cause the resulting executable to
+ be covered by the GNU General Public License. This exception does
+ not however invalidate any other reasons why the executable file
+ might be covered by the GNU General Public License.
+-------------------------------------------------------------------------*/
+
+#ifndef __SDCC_SETJMP_H
+#define __SDCC_SETJMP_H
+
+#define SP_SIZE 1
+
+#ifdef __SDCC_STACK_AUTO
+#define BP_SIZE SP_SIZE
+#else
+#define BP_SIZE 0
+#endif
+
+#ifdef __SDCC_USE_XSTACK
+#define SPX_SIZE 1
+#else
+#define SPX_SIZE 0
+#endif
+
+#define BPX_SIZE SPX_SIZE
+
+#ifdef __SDCC_MODEL_HUGE
+#define RET_SIZE 3
+#else
+#define RET_SIZE 2
+#endif
+
+#if defined (__SDCC_z80) || defined (__SDCC_z180) || defined (__SDCC_r2k) || defined (__SDCC_r3ka) || defined (__SDCC_tlcs90) || defined (__SDCC_ez80_z80) || defined (__SDCC_z80n)
+typedef unsigned char jmp_buf[6]; /* 2 for the stack pointer, 2 for the return address, 2 for the frame pointer. */
+#elif defined (__SDCC_ds390) || defined (__SDCC_stm8) && defined (__SDCC_MODEL_LARGE)
+typedef unsigned char jmp_buf[5]; /* 2 for the stack pointer, 3 for the return address. */
+#elif defined (__SDCC_stm8) || defined (__SDCC_sm83) || defined (__SDCC_hc08) || defined (__SDCC_s08)
+typedef unsigned char jmp_buf[4]; /* 2 for the stack pointer, 2 for the return address. */
+#elif defined (__SDCC_pdk13) || defined (__SDCC_pdk14) || defined (__SDCC_pdk15)
+typedef unsigned char jmp_buf[3]; /* 1 for the stack pointer, 2 for the return address. */
+#else
+typedef unsigned char jmp_buf[RET_SIZE + SP_SIZE + BP_SIZE + SPX_SIZE + BPX_SIZE];
+#endif
+
+int __setjmp (jmp_buf) OLDCALL;
+
+/* C99 might require setjmp to be a macro. The standard seems self-contradicting on this issue. */
+/* However, it is clear that the standards allow setjmp to be a macro. */
+#define setjmp(jump_buf) __setjmp(jump_buf)
+
+#ifndef __SDCC_HIDE_LONGJMP
+_Noreturn void longjmp(jmp_buf, int) OLDCALL;
+#endif
+
+#undef RET_SIZE
+#undef SP_SIZE
+#undef BP_SIZE
+#undef SPX_SIZE
+#undef BPX_SIZE
+
+#endif
+
diff --git a/gbdk/gbdk-lib/include/sms/gbdecompress.h b/gbdk/gbdk-lib/include/sms/gbdecompress.h
new file mode 100644
index 00000000..4bcbcc12
--- /dev/null
+++ b/gbdk/gbdk-lib/include/sms/gbdecompress.h
@@ -0,0 +1,24 @@
+/** @file gb/gbdecompress.h
+
+ GB-Compress decompressor
+ Compatible with the compression used in GBTD
+*/
+
+#ifndef __GBDECOMPRESS_H_INCLUDE
+#define __GBDECOMPRESS_H_INCLUDE
+
+#include <types.h>
+#include <stdint.h>
+
+/** gb-decompress data from sour into dest
+
+ @param sour Pointer to source gb-compressed data
+ @param dest Pointer to destination buffer/address
+
+ @return Return value is number of bytes decompressed
+
+ @see gb_decompress_bkg_data, gb_decompress_win_data, gb_decompress_sprite_data
+ */
+uint16_t gb_decompress(const uint8_t * sour, uint8_t * dest) Z88DK_CALLEE PRESERVES_REGS(b, c);
+
+#endif \ No newline at end of file
diff --git a/gbdk/gbdk-lib/include/sms/hardware.h b/gbdk/gbdk-lib/include/sms/hardware.h
new file mode 100644
index 00000000..2c3ac1eb
--- /dev/null
+++ b/gbdk/gbdk-lib/include/sms/hardware.h
@@ -0,0 +1,216 @@
+/** @file sms/hardware.h
+ Defines that let the SMS/GG hardware registers be accessed
+ from C.
+*/
+#ifndef _HARDWARE_H
+#define _HARDWARE_H
+
+#include <types.h>
+
+#define __BYTES extern UBYTE
+#define __BYTE_REG extern volatile UBYTE
+
+static volatile SFR AT(0x3E) MEMORY_CTL;
+
+#define MEMCTL_JOYON 0b00000000
+#define MEMCTL_JOYOFF 0b00000100
+#define MEMCTL_BASEON 0b00000000
+#define MEMCTL_BASEOFF 0b00001000
+#define MEMCTL_RAMON 0b00000000
+#define MEMCTL_RAMOFF 0b00010000
+#define MEMCTL_CROMON 0b00000000
+#define MEMCTL_CROMOFF 0b00100000
+#define MEMCTL_ROMON 0b00000000
+#define MEMCTL_ROMOFF 0b01000000
+#define MEMCTL_EXTON 0b00000000
+#define MEMCTL_EXTOFF 0b10000000
+
+static volatile SFR AT(0x3F) JOY_CTL;
+
+#define JOY_P1_LATCH 0b00000010
+#define JOY_P2_LATCH 0b00001000
+
+static volatile SFR AT(0x7E) VCOUNTER;
+
+static volatile SFR AT(0x7F) PSG;
+
+#define PSG_LATCH 0x80
+
+#define PSG_CH0 0b00000000
+#define PSG_CH1 0b00100000
+#define PSG_CH2 0b01000000
+#define PSG_CH3 0b01100000
+
+#define PSG_VOLUME 0b00010000
+
+static volatile SFR AT(0x7F) HCOUNTER;
+
+static volatile SFR AT(0xBE) VDP_DATA;
+static volatile SFR AT(0xBF) VDP_CMD;
+static volatile SFR AT(0xBF) VDP_STATUS;
+
+#define STATF_INT_VBL 0b10000000
+#define STATF_9_SPR 0b01000000
+#define STATF_SPR_COLL 0b00100000
+
+#define VDP_REG_MASK 0b10000000
+#define VDP_R0 0b10000000
+extern UBYTE shadow_VDP_R0;
+
+#define R0_VSCRL 0b00000000
+#define R0_VSCRL_INH 0b10000000
+#define R0_HSCRL 0b00000000
+#define R0_HSCRL_INH 0b01000000
+#define R0_NO_LCB 0b00000000
+#define R0_LCB 0b00100000
+#define R0_IE1_OFF 0b00000000
+#define R0_IE1 0b00010000
+#define R0_SS_OFF 0b00000000
+#define R0_SS 0b00001000
+#define R0_DEFAULT 0b00000110
+#define R0_ES_OFF 0b00000000
+#define R0_ES 0b00000001
+
+#define VDP_R1 0b10000001
+extern UBYTE shadow_VDP_R1;
+
+#define R1_DEFAULT 0b10000000
+#define R1_DISP_OFF 0b00000000
+#define R1_DISP_ON 0b01000000
+#define R1_IE_OFF 0b00000000
+#define R1_IE 0b00100000
+#define R1_SPR_8X8 0b00000000
+#define R1_SPR_8X16 0b00000010
+
+#define VDP_R2 0b10000010
+extern UBYTE shadow_VDP_R2;
+
+#define R2_MAP_0x3800 0xFF
+#define R2_MAP_0x3000 0xFD
+#define R2_MAP_0x2800 0xFB
+#define R2_MAP_0x2000 0xF9
+#define R2_MAP_0x1800 0xF7
+#define R2_MAP_0x1000 0xF5
+#define R2_MAP_0x0800 0xF3
+#define R2_MAP_0x0000 0xF1
+
+#define VDP_R3 0b10000011
+extern UBYTE shadow_VDP_R3;
+#define VDP_R4 0b10000100
+extern UBYTE shadow_VDP_R4;
+#define VDP_R5 0b10000101
+extern UBYTE shadow_VDP_R5;
+
+#define R5_SAT_0x3F00 0xFF
+#define R5_SAT_MASK 0b10000001
+
+#define VDP_R6 0b10000110
+extern UBYTE shadow_VDP_R6;
+
+#define R6_BANK0 0xFB
+#define R6_DATA_0x0000 0xFB
+#define R6_BANK1 0xFF
+#define R6_DATA_0x2000 0xFF
+
+#define VDP_R7 0b10000111
+extern UBYTE shadow_VDP_R7;
+#define VDP_RBORDER 0b10000111
+extern UBYTE shadow_VDP_RBORDER;
+
+#define R7_COLOR_MASK 0b11110000
+
+#define VDP_R8 0b10001000
+extern UBYTE shadow_VDP_R8;
+#define VDP_RSCX 0b10001000
+extern UBYTE shadow_VDP_RSCX;
+
+#define VDP_R9 0b10001001
+extern UBYTE shadow_VDP_R9;
+#define VDP_RSCY 0b10001001
+extern UBYTE shadow_VDP_RSCY;
+
+#define VDP_R10 0b10001010
+extern UBYTE shadow_VDP_R10;
+
+#define R10_INT_OFF 0xFF
+#define R10_INT_EVERY 0x00
+
+static volatile SFR AT(0xDC) JOY_PORT1;
+
+#define JOY_P1_UP 0b00000001
+#define JOY_P1_DOWN 0b00000010
+#define JOY_P1_LEFT 0b00000100
+#define JOY_P1_RIGHT 0b00001000
+#define JOY_P1_SW1 0b00010000
+#define JOY_P1_TRIGGER 0b00010000
+#define JOY_P1_SW2 0b00100000
+#define JOY_P2_UP 0b01000000
+#define JOY_P2_DOWN 0b10000000
+
+static volatile SFR AT(0xDD) JOY_PORT2;
+
+#define JOY_P2_LEFT 0b00000001
+#define JOY_P2_RIGHT 0b00000010
+#define JOY_P2_SW1 0b00000100
+#define JOY_P2_TRIGGER 0b00000100
+#define JOY_P2_SW2 0b00001000
+#define JOY_RESET 0b00010000
+#define JOY_P1_LIGHT 0b01000000
+#define JOY_P2_LIGHT 0b10000000
+
+static volatile SFR AT(0xF0) FMADDRESS;
+static volatile SFR AT(0xF1) FMDATA;
+static volatile SFR AT(0xF2) AUDIOCTRL;
+
+static volatile UBYTE AT(0xfffc) RAM_CONTROL;
+
+#define RAMCTL_BANK 0b00000100
+#define RAMCTL_ROM 0b00000000
+#define RAMCTL_RAM 0b00001000
+#define RAMCTL_RO 0b00010000
+#define RAMCTL_PROT 0b10000000
+
+static volatile UBYTE AT(0xfff8) GLASSES_3D;
+
+static volatile UBYTE AT(0xfffd) MAP_FRAME0;
+static volatile UBYTE AT(0xfffe) MAP_FRAME1;
+static volatile UBYTE AT(0xffff) MAP_FRAME2;
+
+extern const UBYTE _BIOS;
+
+extern const UBYTE _SYSTEM;
+
+#define SYSTEM_PAL 0x00
+#define SYSTEM_NTSC 0x01
+
+extern volatile UBYTE VDP_ATTR_SHIFT;
+
+#define VDP_SAT_TERM 0xD0
+
+#if defined(__TARGET_sms)
+#define DEVICE_SCREEN_X_OFFSET 0
+#define DEVICE_SCREEN_Y_OFFSET 0
+#define DEVICE_SCREEN_WIDTH 32
+#define DEVICE_SCREEN_HEIGHT 24
+#define DEVICE_SCREEN_BUFFER_WIDTH 32
+#define DEVICE_SCREEN_BUFFER_HEIGHT 28
+#define DEVICE_SCREEN_MAP_ENTRY_SIZE 2
+#define DEVICE_SPRITE_PX_OFFSET_X 0
+#define DEVICE_SPRITE_PX_OFFSET_Y -1
+#elif defined(__TARGET_gg)
+#define DEVICE_SCREEN_X_OFFSET 6
+#define DEVICE_SCREEN_Y_OFFSET 3
+#define DEVICE_SCREEN_WIDTH 20
+#define DEVICE_SCREEN_HEIGHT 18
+#define DEVICE_SCREEN_BUFFER_WIDTH 32
+#define DEVICE_SCREEN_BUFFER_HEIGHT 28
+#define DEVICE_SCREEN_MAP_ENTRY_SIZE 2
+#define DEVICE_SPRITE_PX_OFFSET_X 48
+#define DEVICE_SPRITE_PX_OFFSET_Y 23
+#else
+#error Unrecognized port
+#endif
+#define DEVICE_SCREEN_PX_WIDTH (DEVICE_SCREEN_WIDTH * 8)
+#define DEVICE_SCREEN_PX_HEIGHT (DEVICE_SCREEN_HEIGHT * 8)
+
+#endif
diff --git a/gbdk/gbdk-lib/include/sms/metasprites.h b/gbdk/gbdk-lib/include/sms/metasprites.h
new file mode 100644
index 00000000..5719e1a8
--- /dev/null
+++ b/gbdk/gbdk-lib/include/sms/metasprites.h
@@ -0,0 +1,116 @@
+/** @file sms/metasprites.h
+
+ # Metasprite support
+
+ A metasprite is a larger sprite made up from a
+ collection of smaller individual hardware sprites.
+ Different frames of the same metasprites can share
+ tile data.
+
+ The api supports metasprites in both
+ @ref SPRITES_8x8 and @ref SPRITES_8x16 mode. If
+ 8x16 mode is used then the height of the metasprite
+ must be a multiple of 16.
+
+ The origin (pivot) for the metasprite is not required
+ to be in the upper left-hand corner as with regular
+ hardware sprites.
+
+ Use the @ref utility_png2asset tool to convert single
+ or multiple frames of graphics into metasprite
+ structured data for use with the ...metasprite...()
+ functions.
+
+ # Metasprites composed of variable numbers of sprites
+
+ When using png2asset, it's common for the output of
+ different frames to be composed of different numbers
+ of hardware sprites (since it's trying to create each
+ frame as efficiently as possible). Due to that, it's
+ good practice to clear out (hide) unused sprites in the
+ shadow_OAM that have been set by previous frames.
+*/
+
+#ifndef _METASPRITES_H_INCLUDE
+#define _METASPRITES_H_INCLUDE
+
+#include <sms/hardware.h>
+#include <types.h>
+#include <stdint.h>
+
+/** Metasprite sub-item structure
+ @param dy (int8_t) Y coordinate of the sprite relative to the metasprite origin (pivot)
+ @param dx (int8_t) X coordinate of the sprite relative to the metasprite origin (pivot)
+ @param dtile (uint8_t) Start tile relative to the metasprites own set of tiles
+
+ Metasprites are built from multiple metasprite_t items (one for each sub-sprite)
+ and a pool of tiles they reference. If a metasprite has multiple frames then each
+ frame will be built from some number of metasprite_t items (which may vary based
+ on how many sprites are required for that particular frame).
+
+ A metasprite frame is terminated with a {metasprite_end} entry.
+*/
+typedef struct metasprite_t {
+ int8_t dy, dx;
+ uint8_t dtile;
+} metasprite_t;
+
+#define metasprite_end -128
+#define METASPR_ITEM(dy,dx,dt,a) {(dy),(dx),(dt)}
+#define METASPR_TERM {metasprite_end}
+
+extern const void * __current_metasprite;
+extern uint8_t __current_base_tile;
+extern uint8_t __render_shadow_OAM;
+
+
+static uint8_t __move_metasprite(uint8_t id, uint8_t x, uint8_t y) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+static void __hide_metasprite(uint8_t id) Z88DK_FASTCALL PRESERVES_REGS(iyh, iyl);
+
+/**
+ * Hides all hardware sprites in range from <= X < to
+ * @param from start OAM index
+ * @param to finish OAM index
+ */
+void hide_sprites_range(UINT8 from, UINT8 to) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+
+/** Moves metasprite to the absolute position x and y
+
+ @param metasprite Pointer to the first struct of the metasprite (for the desired frame)
+ @param base_tile Number of the first tile where the metasprite's tiles start
+ @param base_sprite Number of the first hardware sprite to be used by the metasprite
+ @param x Absolute x coordinate of the sprite
+ @param y Absolute y coordinate of the sprite
+
+ Moves __metasprite__ to the absolute position __x__ and __y__
+ (with __no flip__ on the X or Y axis). Hardware sprites are
+ allocated starting from __base_sprite__, using tiles
+ starting from __base_tile__.
+
+ Sets:
+ \li __current_metasprite = metasprite;
+ \li __current_base_tile = base_tile;
+
+ @return Number of hardware sprites used to draw this metasprite
+ */
+inline uint8_t move_metasprite(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_sprite, uint8_t x, uint8_t y) {
+ __current_metasprite = metasprite;
+ __current_base_tile = base_tile;
+ return __move_metasprite(base_sprite, x, y);
+}
+
+/** Hides a metasprite from the screen
+
+ @param metasprite Pointer to first struct of the desired metasprite frame
+ @param base_sprite Number of hardware sprite to start with
+
+ Sets:
+ \li __current_metasprite = metasprite;
+
+ **/
+inline void hide_metasprite(const metasprite_t * metasprite, uint8_t base_sprite) {
+ __current_metasprite = metasprite;
+ __hide_metasprite(base_sprite);
+}
+
+#endif
diff --git a/gbdk/gbdk-lib/include/sms/sms.h b/gbdk/gbdk-lib/include/sms/sms.h
new file mode 100644
index 00000000..1c34617d
--- /dev/null
+++ b/gbdk/gbdk-lib/include/sms/sms.h
@@ -0,0 +1,780 @@
+/** @file sms/sms.h
+ SMS/GG specific functions.
+*/
+#ifndef _SMS_H
+#define _SMS_H
+
+#include <types.h>
+#include <stdint.h>
+#include <gbdk/version.h>
+#include <sms/hardware.h>
+
+#define SEGA
+#ifdef NINTENDO
+#undef NINTENDO
+#endif
+#if defined(__TARGET_sms)
+#define MASTERSYSTEM
+#elif defined(__TARGET_gg)
+#define GAMEGEAR
+#endif
+
+
+#define VBK_REG VDP_ATTR_SHIFT
+
+/** Joypad bits.
+ A logical OR of these is used in the wait_pad and joypad
+ functions. For example, to see if the B button is pressed
+ try
+
+ uint8_t keys;
+ keys = joypad();
+ if (keys & J_B) {
+ ...
+ }
+
+ @see joypad
+ */
+#define J_UP 0b00000001
+#define J_DOWN 0b00000010
+#define J_LEFT 0b00000100
+#define J_RIGHT 0b00001000
+#define J_A 0b00010000
+#define J_B 0b00100000
+#if defined(__TARGET_sms)
+#define J_SELECT 0b00100000
+#define J_START 0b00010000
+#elif defined(__TARGET_gg)
+#define J_SELECT 0b00100000
+#define J_START 0b10000000
+#endif
+
+/** Screen modes.
+ Normally used by internal functions only.
+ @see mode()
+ */
+#define M_TEXT_OUT 0x02U
+#define M_TEXT_INOUT 0x03U
+/** Set this in addition to the others to disable scrolling
+
+ If scrolling is disabled, the cursor returns to (0,0)
+ @see mode()
+*/
+#define M_NO_SCROLL 0x04U
+/** Set this to disable interpretation
+ @see mode()
+*/
+#define M_NO_INTERP 0x08U
+
+/** If set the background tile will be flipped horizontally.
+ */
+#define S_FLIPX 0x02U
+/** If set the background tile will be flipped vertically.
+ */
+#define S_FLIPY 0x04U
+/** If set the background tile palette.
+ */
+#define S_PALETTE 0x08U
+/** If set the background tile priority.
+ */
+#define S_PRIORITY 0x10U
+
+// VDP helper macros
+#define __WRITE_VDP_REG(REG, v) shadow_##REG=(v);__critical{VDP_CMD=(shadow_##REG),VDP_CMD=REG;}
+#define __READ_VDP_REG(REG) shadow_##REG
+
+void WRITE_VDP_CMD(uint16_t cmd) Z88DK_FASTCALL PRESERVES_REGS(b, c, d, e, iyh, iyl);
+void WRITE_VDP_DATA(uint16_t data) Z88DK_FASTCALL PRESERVES_REGS(b, c, d, e, iyh, iyl);
+
+/** Set the current screen mode - one of M_* modes
+
+ Normally used by internal functions only.
+
+ @see M_TEXT_OUT, M_TEXT_INOUT, M_NO_SCROLL, M_NO_INTERP
+*/
+void mode(uint8_t m) OLDCALL;
+
+/** Returns the current mode
+
+ @see M_TEXT_OUT, M_TEXT_INOUT, M_NO_SCROLL, M_NO_INTERP
+*/
+uint8_t get_mode() OLDCALL;
+
+/* Interrupt flags */
+/** Disable calling of interrupt service routines
+ */
+#define EMPTY_IFLAG 0x00U
+/** VBlank Interrupt occurs at the start of the vertical blank.
+
+ During this period the video ram may be freely accessed.
+ @see set_interrupts(), @see add_VBL
+ */
+#define VBL_IFLAG 0x01U
+/** LCD Interrupt when triggered by the STAT register.
+ @see set_interrupts(), @see add_LCD
+*/
+#define LCD_IFLAG 0x02U
+/** Does nothing on SMS/GG
+ */
+#define TIM_IFLAG 0x04U
+/** Does nothing on SMS/GG
+ */
+#define SIO_IFLAG 0x08U
+/** Does nothing on SMS/GG
+ */
+#define JOY_IFLAG 0x10U
+
+void set_interrupts(uint8_t flags) Z88DK_FASTCALL;
+
+/* Limits */
+/** Width of the visible screen in pixels.
+ */
+#define SCREENWIDTH DEVICE_SCREEN_PX_WIDTH
+/** Height of the visible screen in pixels.
+ */
+#define SCREENHEIGHT DEVICE_SCREEN_PX_HEIGHT
+/** The Minimum X position of the Window Layer (Left edge of screen) @see move_win()
+ */
+#define MINWNDPOSX 0x00U
+/** The Minimum Y position of the Window Layer (Top edge of screen) @see move_win()
+ */
+#define MINWNDPOSY 0x00U
+/** The Maximum X position of the Window Layer (Right edge of screen) @see move_win()
+ */
+#define MAXWNDPOSX 0x00U
+/** The Maximum Y position of the Window Layer (Bottom edge of screen) @see move_win()
+ */
+#define MAXWNDPOSY 0x00U
+
+
+/** Interrupt handlers
+ */
+typedef void (*int_handler)(void) NONBANKED;
+
+/** Removes the VBL interrupt handler.
+ @see add_VBL()
+*/
+void remove_VBL(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(iyh, iyl);
+
+/** Removes the LCD interrupt handler.
+ @see add_LCD(), remove_VBL()
+*/
+void remove_LCD(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(b, c, iyh, iyl);
+
+void remove_TIM(int_handler h) Z88DK_FASTCALL;
+void remove_SIO(int_handler h) Z88DK_FASTCALL;
+void remove_JOY(int_handler h) Z88DK_FASTCALL;
+
+/** Adds a V-blank interrupt handler.
+*/
+void add_VBL(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(d, e, iyh, iyl);
+
+/** Adds a LCD interrupt handler.
+*/
+void add_LCD(int_handler h) Z88DK_FASTCALL PRESERVES_REGS(b, c, iyh, iyl);
+
+/** Does nothing on SMS/GG
+ */
+void add_TIM(int_handler h) Z88DK_FASTCALL;
+
+/** Does nothing on SMS/GG
+ */
+void add_SIO(int_handler h) Z88DK_FASTCALL;
+
+/** Does nothing on SMS/GG
+ */
+void add_JOY(int_handler h) Z88DK_FASTCALL;
+
+/** Cancel pending interrupts
+ */
+inline uint8_t cancel_pending_interrupts() {
+ return VDP_STATUS;
+}
+
+inline void move_bkg(uint8_t x, uint8_t y) {
+ __WRITE_VDP_REG(VDP_RSCX, -x);
+ __WRITE_VDP_REG(VDP_RSCY, y);
+}
+
+inline void scroll_bkg(int8_t x, int8_t y) {
+ __WRITE_VDP_REG(VDP_RSCX, __READ_VDP_REG(VDP_RSCX) - x);
+ int16_t tmp = __READ_VDP_REG(VDP_RSCY) + y;
+ __WRITE_VDP_REG(VDP_RSCY, (tmp < 0) ? 224 + tmp : tmp % 224u);
+}
+
+/** HALTs the CPU and waits for the vertical blank interrupt (VBL) to finish.
+
+ This is often used in main loops to idle the CPU at low power
+ until it's time to start the next frame. It's also useful for
+ syncing animation with the screen re-draw.
+
+ Warning: If the VBL interrupt is disabled, this function will
+ never return. If the screen is off this function returns
+ immediately.
+*/
+void wait_vbl_done() PRESERVES_REGS(b, c, d, e, h, l, iyh, iyl);
+
+/** Turns the display off.
+
+ @see DISPLAY_ON
+*/
+inline void display_off() {
+ __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) &= (~R1_DISP_ON));
+}
+
+/** Turns the display back on.
+ @see display_off, DISPLAY_OFF
+*/
+#define DISPLAY_ON \
+ __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) |= R1_DISP_ON)
+
+/** Turns the display off immediately.
+ @see display_off, DISPLAY_ON
+*/
+#define DISPLAY_OFF \
+ display_off();
+
+/** Copies data from shadow OAM to OAM
+ */
+void refresh_OAM();
+
+/** Blanks leftmost column, so it is not garbaged when you use horizontal scroll
+ @see SHOW_LEFT_COLUMN
+*/
+#define HIDE_LEFT_COLUMN \
+ __WRITE_VDP_REG(VDP_R0, __READ_VDP_REG(VDP_R0) |= R0_LCB)
+
+/** Shows leftmost column
+ @see HIDE_LEFT_COLUMN
+*/
+#define SHOW_LEFT_COLUMN \
+ __WRITE_VDP_REG(VDP_R0, __READ_VDP_REG(VDP_R0) &= (~R0_LCB))
+
+/** Turns on the background layer.
+ Not yet implemented
+*/
+#define SHOW_BKG
+
+/** Turns off the background layer.
+ Not yet implemented
+*/
+#define HIDE_BKG
+
+/** Turns on the window layer
+ Not yet implemented
+*/
+#define SHOW_WIN
+
+/** Turns off the window layer.
+ Not yet implemented
+*/
+#define HIDE_WIN
+
+/** Turns on the sprites layer.
+ Not yet implemented
+*/
+#define SHOW_SPRITES
+
+/** Turns off the sprites layer.
+ Not yet implemented
+*/
+#define HIDE_SPRITES
+
+/** Sets sprite size to 8x16 pixels, two tiles one above the other.
+*/
+#define SPRITES_8x16 \
+ __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) |= R1_SPR_8X16)
+
+/** Sets sprite size to 8x8 pixels, one tile.
+*/
+#define SPRITES_8x8 \
+ __WRITE_VDP_REG(VDP_R1, __READ_VDP_REG(VDP_R1) &= (~R1_SPR_8X16))
+
+/** Macro returns TRUE if device supports color
+ * (it always does on SMS/GG)
+ */
+#define DEVICE_SUPPORTS_COLOR (TRUE)
+
+/** Global Time Counter in VBL periods (60Hz)
+
+ Increments once per Frame
+
+ Will wrap around every ~18 minutes (unsigned 16 bits = 65535 / 60 / 60 = 18.2)
+*/
+extern volatile uint16_t sys_time;
+
+/** Tracks current active ROM bank in frame 1
+*/
+#define _current_bank MAP_FRAME1
+#define CURRENT_BANK MAP_FRAME1
+
+/** Obtains the __bank number__ of VARNAME
+
+ @param VARNAME Name of the variable which has a __bank_VARNAME companion symbol which is adjusted by bankpack
+
+ Use this to obtain the bank number from a bank reference
+ created with @ref BANKREF().
+
+ @see BANKREF_EXTERN(), BANKREF()
+*/
+#ifndef BANK
+#define BANK(VARNAME) ( (uint8_t) & __bank_ ## VARNAME )
+#endif
+
+/** Creates a reference for retrieving the bank number of a variable or function
+
+ @param VARNAME Variable name to use, which may be an existing identifier
+
+ @see BANK() for obtaining the bank number of the included data.
+
+ More than one `BANKREF()` may be created per file, but each call should
+ always use a unique VARNAME.
+
+ Use @ref BANKREF_EXTERN() within another source file
+ to make the variable and it's data accesible there.
+*/
+#define BANKREF(VARNAME) void __func_ ## VARNAME() __banked __naked { \
+__asm \
+ .local b___func_ ## VARNAME \
+ ___bank_ ## VARNAME = b___func_ ## VARNAME \
+ .globl ___bank_ ## VARNAME \
+__endasm; \
+}
+
+/** Creates extern references for accessing a BANKREF() generated variable.
+
+ @param VARNAME Name of the variable used with @ref BANKREF()
+
+ This makes a @ref BANKREF() reference in another source
+ file accessible in the current file for use with @ref BANK().
+
+ @see BANKREF(), BANK()
+*/
+#define BANKREF_EXTERN(VARNAME) extern const void __bank_ ## VARNAME;
+
+
+/** Makes switch the active ROM bank in frame 1
+ @param b ROM bank to switch to
+*/
+
+#define SWITCH_ROM(b) MAP_FRAME1=(b)
+#define SWITCH_ROM1 SWITCH_ROM
+
+/** Makes switch the active ROM bank in frame 2
+ @param b ROM bank to switch to
+*/
+
+#define SWITCH_ROM2(b) MAP_FRAME2=(b)
+
+/** Switches RAM bank
+ @param b SRAM bank to switch to
+*/
+
+#define SWITCH_RAM(b) RAM_CONTROL=((b)&1)?RAM_CONTROL|RAMCTL_BANK:RAM_CONTROL&(~RAMCTL_BANK)
+
+/** Enables RAM
+*/
+
+#define ENABLE_RAM RAM_CONTROL|=RAMCTL_RAM
+
+/** Disables RAM
+*/
+
+#define DISABLE_RAM RAM_CONTROL&=(~RAMCTL_RAM)
+
+
+/** Delays the given number of milliseconds.
+ Uses no timers or interrupts, and can be called with
+ interrupts disabled
+ */
+void delay(uint16_t d) Z88DK_FASTCALL;
+
+
+/** Reads and returns the current state of the joypad.
+*/
+uint8_t joypad() OLDCALL PRESERVES_REGS(b, c, d, e, h, iyh, iyl);
+
+/** Waits until at least one of the buttons given in mask are pressed.
+*/
+uint8_t waitpad(uint8_t mask) Z88DK_FASTCALL PRESERVES_REGS(b, c, d, e, iyh, iyl);
+
+/** Waits for the directional pad and all buttons to be released.
+
+ Note: Checks in a loop that doesn't HALT at all, so the CPU
+ will be maxed out until this call returns.
+*/
+void waitpadup() PRESERVES_REGS(b, c, d, e, iyh, iyl);
+
+/** Multiplayer joypad structure.
+
+ Must be initialized with @ref joypad_init() first then it
+ may be used to poll all avaliable joypads with @ref joypad_ex()
+*/
+typedef struct {
+ uint8_t npads;
+ union {
+ struct {
+ uint8_t joy0, joy1, joy2, joy3;
+ };
+ uint8_t joypads[4];
+ };
+} joypads_t;
+
+/** Initializes joypads_t structure for polling multiple joypads
+ @param npads number of joypads requested (1, 2 or 4)
+ @param joypads pointer to joypads_t structure to be initialized
+
+ Only required for @ref joypad_ex, not required for calls to regular @ref joypad()
+ @returns number of joypads avaliable
+ @see joypad_ex(), joypads_t
+*/
+uint8_t joypad_init(uint8_t npads, joypads_t * joypads) Z88DK_CALLEE;
+
+/** Polls all avaliable joypads
+ @param joypads pointer to joypads_t structure to be filled with joypad statuses,
+ must be previously initialized with joypad_init()
+
+ @see joypad_init(), joypads_t
+*/
+void joypad_ex(joypads_t * joypads) Z88DK_FASTCALL PRESERVES_REGS(iyh, iyl);
+
+
+#if defined(__TARGET_sms)
+
+#define RGB(r,g,b) ((r) | ((g) << 2) | ((b) << 4))
+#define RGB8(r,g,b) (((r) >> 6) | (((g) >> 6) << 2) | (((b) >> 6) << 4))
+#define RGBHTML(RGB24bit) (((RGB24bit) >> 22) | ((((RGB24bit) & 0xFFFF) >> 14) << 2) | ((((RGB24bit) & 0xFF) >> 6) << 4))
+
+/** Common colors based on the EGA default palette.
+ */
+#define RGB_RED RGB( 3, 0, 0)
+#define RGB_DARKRED RGB( 2, 0, 0)
+#define RGB_GREEN RGB( 0, 3, 0)
+#define RGB_DARKGREEN RGB( 0, 2, 0)
+#define RGB_BLUE RGB( 0, 0, 3)
+#define RGB_DARKBLUE RGB( 0, 0, 2)
+#define RGB_YELLOW RGB( 3, 3, 0)
+#define RGB_DARKYELLOW RGB( 2, 2, 0)
+#define RGB_CYAN RGB( 0, 3, 3)
+#define RGB_AQUA RGB( 3, 1, 2)
+#define RGB_PINK RGB( 3, 0, 3)
+#define RGB_PURPLE RGB( 2, 0, 2)
+#define RGB_BLACK RGB( 0, 0, 0)
+#define RGB_DARKGRAY RGB( 1, 1, 1)
+#define RGB_LIGHTGRAY RGB( 2, 2, 2)
+#define RGB_WHITE RGB( 3, 3, 3)
+
+typedef uint8_t palette_color_t;
+
+#elif defined(__TARGET_gg)
+
+#define RGB(r,g,b) ((uint16_t)(r) | (uint16_t)((g) << 4) | (uint16_t)((b) << 8))
+#define RGB8(r,g,b) ((uint16_t)((r) >> 4) | ((uint16_t)((g) >> 4) << 4) | ((uint16_t)((b) >> 4) << 8))
+#define RGBHTML(RGB24bit) (((RGB24bit) >> 20) | ((((RGB24bit) & 0xFFFF) >> 12) << 4)|((((RGB24bit) & 0xFF) >> 4) << 8))
+
+/** Common colors based on the EGA default palette.
+ */
+#define RGB_RED RGB(15, 0, 0)
+#define RGB_DARKRED RGB( 7, 0, 0)
+#define RGB_GREEN RGB( 0, 15, 0)
+#define RGB_DARKGREEN RGB( 0, 7, 0)
+#define RGB_BLUE RGB( 0, 0, 15)
+#define RGB_DARKBLUE RGB( 0, 0, 7)
+#define RGB_YELLOW RGB(15, 15, 0)
+#define RGB_DARKYELLOW RGB( 7, 7, 0)
+#define RGB_CYAN RGB( 0, 15, 15)
+#define RGB_AQUA RGB(14, 2, 11)
+#define RGB_PINK RGB(15, 0, 15)
+#define RGB_PURPLE RGB(10, 0, 10)
+#define RGB_BLACK RGB( 0, 0, 0)
+#define RGB_DARKGRAY RGB( 5, 5, 5)
+#define RGB_LIGHTGRAY RGB(10, 10, 10)
+#define RGB_WHITE RGB(15, 15, 15)
+
+#define RGB_LIGHTFLESH RGB(15, 10, 7)
+#define RGB_BROWN RGB( 5, 5, 0)
+#define RGB_ORANGE RGB(15, 10, 0)
+#define RGB_TEAL RGB( 7, 7, 0)
+
+typedef uint16_t palette_color_t;
+
+#else
+#error Unrecognized port
+#endif
+
+void set_default_palette();
+inline void cpu_fast() {}
+
+void set_palette_entry(uint8_t palette, uint8_t entry, uint16_t rgb_data) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+#define set_bkg_palette_entry set_palette_entry
+#define set_sprite_palette_entry(palette,entry,rgb_data) set_palette_entry(1,entry,rgb_data)
+void set_palette(uint8_t first_palette, uint8_t nb_palettes, palette_color_t *rgb_data) Z88DK_CALLEE;
+#define set_bkg_palette set_palette
+#define set_sprite_palette(first_palette,nb_palettes,rgb_data) set_palette(1,1,rgb_data)
+
+void set_native_tile_data(uint16_t start, uint16_t ntiles, const void *src) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+inline void set_bkg_4bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_native_tile_data(start, ntiles, src);
+}
+inline void set_sprite_4bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_native_tile_data((uint8_t)(start) + 0x100u, ntiles, src);
+}
+
+#define COMPAT_PALETTE(C0,C1,C2,C3) (((uint16_t)(C3) << 12) | ((uint16_t)(C2) << 8) | ((uint16_t)(C1) << 4) | (uint16_t)(C0))
+extern uint16_t _current_2bpp_palette;
+inline void set_2bpp_palette(uint16_t palette) {
+ _current_2bpp_palette = palette;
+}
+void set_tile_2bpp_data(uint16_t start, uint16_t ntiles, const void *src, uint16_t palette) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+inline void set_bkg_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_tile_2bpp_data(start, ntiles, src, _current_2bpp_palette);
+}
+inline void set_sprite_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_tile_2bpp_data((uint8_t)(start) + 0x100u, ntiles, src, _current_2bpp_palette);
+}
+inline void set_bkg_2bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_tile_2bpp_data(start, ntiles, src, _current_2bpp_palette);
+}
+inline void set_sprite_2bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_tile_2bpp_data((uint8_t)(start) + 0x100u, ntiles, src, _current_2bpp_palette);
+}
+
+extern uint16_t _current_1bpp_colors;
+inline void set_1bpp_colors(uint8_t fgcolor, uint8_t bgcolor) {
+ _current_1bpp_colors = ((uint16_t)bgcolor << 8) | fgcolor;
+}
+void set_tile_1bpp_data(uint16_t start, uint16_t ntiles, const void *src, uint16_t colors) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+inline void set_bkg_1bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_tile_1bpp_data(start, ntiles, src, _current_1bpp_colors);
+}
+inline void set_sprite_1bpp_data(uint16_t start, uint16_t ntiles, const void *src) {
+ set_tile_1bpp_data((uint8_t)(start) + 0x100u, ntiles, src, _current_1bpp_colors);
+}
+
+
+/** Copies arbitrary data to an address in VRAM
+
+ @param dst destination VRAM Address
+ @param src Pointer to source buffer
+ @param size Number of bytes to copy
+
+ Copies __size__ bytes from a buffer at _src__ to VRAM starting at __dst__.
+*/
+void set_data(uint16_t dst, const void *src, uint16_t size) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+void vmemcpy(uint16_t dst, const void *src, uint16_t size) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+
+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);
+void set_tile_map_compat(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+#define set_bkg_tiles set_tile_map_compat
+#define set_win_tiles set_tile_map_compat
+
+extern uint8_t _map_tile_offset;
+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) {
+ _map_tile_offset = base_tile;
+ set_tile_map_compat(x, y, w, h, tiles);
+ _map_tile_offset = 0;
+}
+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) {
+ _map_tile_offset = base_tile;
+ set_tile_map_compat(x, y, w, h, tiles);
+ _map_tile_offset = 0;
+}
+
+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);
+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);
+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) {
+ set_tile_submap_compat(x, y, w, h, map_w, map);
+}
+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) {
+ set_tile_submap_compat(x, y, w, h, map_w, map);
+}
+
+extern uint8_t _submap_tile_offset;
+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) {
+ _submap_tile_offset = base_tile;
+ set_tile_submap_compat(x, y, w, h, map_w, map);
+ _submap_tile_offset = 0;
+}
+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) {
+ _submap_tile_offset = base_tile;
+ set_tile_submap_compat(x, y, w, h, map_w, map);
+ _submap_tile_offset = 0;
+}
+
+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);
+void fill_rect_compat(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint16_t tile) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+#define fill_bkg_rect fill_rect_compat
+#define fill_win_rect fill_rect_compat
+
+/** Shadow OAM array in WRAM, that is transferred into the real OAM each VBlank
+*/
+extern volatile uint8_t shadow_OAM[];
+
+/** MSB of shadow_OAM address is used by OAM copying routine
+*/
+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;
+
+/** Disable shadow OAM to VRAM copy on each VBlank
+*/
+#define DISABLE_VBL_TRANSFER \
+ _shadow_OAM_base = 0
+
+/** Enable shadow OAM to VRAM copy on each VBlank
+*/
+#define ENABLE_VBL_TRANSFER \
+ _shadow_OAM_base = (uint8_t)((uint16_t)&shadow_OAM >> 8)
+
+/** Amount of hardware sprites in OAM
+*/
+#define MAX_HARDWARE_SPRITES 64
+
+/** Sets address of 256-byte aligned array of shadow OAM to be transferred on each VBlank
+*/
+inline void SET_SHADOW_OAM_ADDRESS(void * address) {
+ _shadow_OAM_base = (uint8_t)((uint16_t)address >> 8);
+}
+
+/** Sets sprite number __nb__in the OAM to display tile number __tile__.
+
+ @param nb Sprite number, range 0 - 39
+ @param tile Selects a tile (0 - 255) from memory at 8000h - 8FFFh
+ \n In CGB Mode this could be either in VRAM Bank
+ \n 0 or 1, depending on Bit 3 of the OAM Attribute Flag
+ \n (see @ref set_sprite_prop)
+
+ In 8x16 mode:
+ \li The sprite will also display the next tile (__tile__ + 1)
+ directly below (y + 8) the first tile.
+ \li The lower bit of the tile number is ignored:
+ the upper 8x8 tile is (__tile__ & 0xFE), and
+ the lower 8x8 tile is (__tile__ | 0x01).
+ \li See: @ref SPRITES_8x16
+*/
+inline void set_sprite_tile(uint8_t nb, uint8_t tile) {
+ shadow_OAM[0x41+(nb << 1)] = tile;
+}
+
+
+/** Returns the tile number of sprite number __nb__ in the OAM.
+
+@param nb Sprite number, range 0 - 39
+
+@see set_sprite_tile for more details
+*/
+inline uint8_t get_sprite_tile(uint8_t nb) {
+ return shadow_OAM[0x41+(nb << 1)];
+}
+
+inline void set_sprite_prop(uint8_t nb, uint8_t prop) {
+ nb; prop;
+}
+
+inline uint8_t get_sprite_prop(uint8_t nb) {
+ nb;
+ return 0;
+}
+
+/** Moves sprite number __nb__ to the __x__, __y__ position on the screen.
+
+ @param nb Sprite number, range 0 - 39
+ @param x X Position. Specifies the sprites horizontal position on the screen (minus 8).
+ \n An offscreen value (X=0 or X>=168) hides the sprite, but the sprite
+ still affects the priority ordering - a better way to hide a sprite is to set
+ its Y-coordinate offscreen.
+ @param y Y Position. Specifies the sprites vertical position on the screen (minus 16).
+ \n An offscreen value (for example, Y=0 or Y>=160) hides the sprite.
+
+ Moving the sprite to 0,0 (or similar off-screen location) will hide it.
+*/
+inline void move_sprite(uint8_t nb, uint8_t x, uint8_t y) {
+ shadow_OAM[nb] = (y < VDP_SAT_TERM) ? y : 0xC0;
+ shadow_OAM[0x40+(nb << 1)] = x;
+}
+
+
+/** Moves sprite number __nb__ relative to its current position.
+
+ @param nb Sprite number, range 0 - 39
+ @param x Number of pixels to move the sprite on the __X axis__
+ \n Range: -128 - 127
+ @param y Number of pixels to move the sprite on the __Y axis__
+ \n Range: -128 - 127
+
+ @see move_sprite for more details about the X and Y position
+ */
+inline void scroll_sprite(uint8_t nb, int8_t x, int8_t y) {
+ uint8_t new_y = shadow_OAM[nb] + y;
+ shadow_OAM[nb] = (new_y < VDP_SAT_TERM) ? new_y : 0xC0;
+ shadow_OAM[0x40+(nb << 1)] = x;
+}
+
+
+/** Hides sprite number __nb__ by moving it to zero position by Y.
+
+ @param nb Sprite number, range 0 - 39
+ */
+inline void hide_sprite(uint8_t nb) {
+ shadow_OAM[nb] = 0xC0;
+}
+
+/**
+ * Set byte in vram at given memory location
+ *
+ * @param addr address to write to
+ * @param v value
+ */
+void set_vram_byte(uint8_t * addr, uint8_t v) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+
+/**
+ * Set single tile t with attributes on background layer at x,y
+ * @param x X-coordinate
+ * @param y Y-coordinate
+ * @param t tile index
+ * @return returns the address of tile, so you may use faster set_vram_byte() later
+ */
+uint8_t * set_attributed_tile_xy(uint8_t x, uint8_t y, uint16_t t) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+
+/**
+ * Set single tile t on background layer at x,y
+ * @param x X-coordinate
+ * @param y Y-coordinate
+ * @param t tile index
+ * @return returns the address of tile, so you may use faster set_vram_byte() later
+ */
+uint8_t * set_tile_xy(uint8_t x, uint8_t y, uint8_t t) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+#define set_bkg_tile_xy set_tile_xy
+#define set_win_tile_xy set_tile_xy
+
+/**
+ * Get address of X,Y tile of background map
+ */
+uint8_t * get_bkg_xy_addr(uint8_t x, uint8_t y) Z88DK_CALLEE PRESERVES_REGS(iyh, iyl);
+#define get_win_xy_addr get_bkg_xy_addr
+
+#endif /* _SMS_H */
diff --git a/gbdk/gbdk-lib/include/stdarg.h b/gbdk/gbdk-lib/include/stdarg.h
new file mode 100644
index 00000000..6c870bc8
--- /dev/null
+++ b/gbdk/gbdk-lib/include/stdarg.h
@@ -0,0 +1,12 @@
+#ifndef STDARG_INCLUDE
+#define STDARG_INCLUDE
+
+#if defined(__PORT_sm83)
+#include <asm/sm83/stdarg.h>
+#elif defined(__PORT_z80)
+#include <asm/z80/stdarg.h>
+#else
+#error Unrecognised port.
+#endif
+
+#endif
diff --git a/gbdk/gbdk-lib/include/stdatomic.h b/gbdk/gbdk-lib/include/stdatomic.h
new file mode 100644
index 00000000..747179d0
--- /dev/null
+++ b/gbdk/gbdk-lib/include/stdatomic.h
@@ -0,0 +1,21 @@
+#ifndef __SDCC_STDATOMIC_H
+#define __SDCC_STDATOMIC_H 1
+
+#include <types.h>
+
+typedef struct {unsigned char flag;} atomic_flag;
+
+#if defined(__SDCC_z80) || defined(__SDCC_z180) || defined(__SDCC_ez80_z80) || defined(__SDCC_sm83) || defined(__SDCC_r2k) || defined(__SDCC_r3ka) || defined(__SDCC_stm8) || defined(__SDCC_hc08) || defined(__SDCC_s08)
+#define ATOMIC_FLAG_INIT {1}
+//#elif defined(__SDCC_mcs51)
+//#define ATOMIC_FLAG_INIT {0}
+#else
+#error Support for atomic_flag not implemented
+#endif
+
+_Bool atomic_flag_test_and_set(volatile atomic_flag *object) OLDCALL;
+
+void atomic_flag_clear(volatile atomic_flag *object);
+
+#endif
+
diff --git a/gbdk/gbdk-lib/include/stdbool.h b/gbdk/gbdk-lib/include/stdbool.h
new file mode 100644
index 00000000..018bfe6b
--- /dev/null
+++ b/gbdk/gbdk-lib/include/stdbool.h
@@ -0,0 +1,40 @@
+/*-------------------------------------------------------------------------
+ stdbool.h - ANSI functions forward declarations
+
+ Copyright (C) 2004, Maarten Brock, sourceforge.brock@dse.nl
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ As a special exception, if you link this library with other files,
+ some of which are compiled with SDCC, to produce an executable,
+ this library does not by itself cause the resulting executable to
+ be covered by the GNU General Public License. This exception does
+ not however invalidate any other reasons why the executable file
+ might be covered by the GNU General Public License.
+-------------------------------------------------------------------------*/
+
+#ifndef __SDC51_STDBOOL_H
+#define __SDC51_STDBOOL_H 1
+
+/* Define true and false of type _Bool in a way compatible with the preprocessor (see N 2229 for details). */
+#define true ((_Bool)+1)
+#define false ((_Bool)+0)
+
+#define bool _Bool
+#define __bool_true_false_are_defined 1
+
+#endif
+
diff --git a/gbdk/gbdk-lib/include/stddef.h b/gbdk/gbdk-lib/include/stddef.h
new file mode 100644
index 00000000..fa03894a
--- /dev/null
+++ b/gbdk/gbdk-lib/include/stddef.h
@@ -0,0 +1,78 @@
+/*-------------------------------------------------------------------------
+ stddef.h - ANSI functions forward declarations
+
+ Copyright (C) 2004, Maarten Brock / sourceforge.brock@dse.nl
+ Copyright (C) 2011, Philipp Klaus Krause / pkk@spth.de
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ As a special exception, if you link this library with other files,
+ some of which are compiled with SDCC, to produce an executable,
+ this library does not by itself cause the resulting executable to
+ be covered by the GNU General Public License. This exception does
+ not however invalidate any other reasons why the executable file
+ might be covered by the GNU General Public License.
+-------------------------------------------------------------------------*/
+
+#ifndef __SDCC_STDDEF_H
+#define __SDCC_STDDEF_H 1
+
+#ifndef NULL
+ #define NULL (void *)0
+#endif
+
+#ifndef __PTRDIFF_T_DEFINED
+#define __PTRDIFF_T_DEFINED
+#if defined (__SDCC_mcs51) || defined (__SDCC_ds390)
+ typedef long int ptrdiff_t;
+#else
+ typedef int ptrdiff_t;
+#endif
+#endif
+
+#ifndef __SIZE_T_DEFINED
+#define __SIZE_T_DEFINED
+ typedef unsigned int size_t;
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+ typedef unsigned char max_align_t;
+#endif
+
+#ifndef __WCHAR_T_DEFINED
+#define __WCHAR_T_DEFINED
+ typedef unsigned long int wchar_t;
+#endif
+
+/* Bounds-checking interfaces from annex K of the C11 standard. */
+#if defined (__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__
+
+#ifndef __RSIZE_T_DEFINED
+#define __RSIZE_T_DEFINED
+typedef size_t rsize_t;
+#endif
+
+#ifndef __ERRNO_T_DEFINED
+#define __ERRNO_T_DEFINED
+typedef int errno_t;
+#endif
+
+#endif
+
+#define offsetof(s, m) __builtin_offsetof (s, m)
+
+#endif
+
diff --git a/gbdk/gbdk-lib/include/stdint.h b/gbdk/gbdk-lib/include/stdint.h
new file mode 100644
index 00000000..9401212c
--- /dev/null
+++ b/gbdk/gbdk-lib/include/stdint.h
@@ -0,0 +1,274 @@
+/*-------------------------------------------------------------------------
+ stdint.h - ISO C99 7.18 Integer types <stdint.h>
+
+ Copyright (C) 2005, Maarten Brock, sourceforge.brock@dse.nl
+ Copyright (C) 2011, Philipp Klaus Krause, pkk@spth.de
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ As a special exception, if you link this library with other files,
+ some of which are compiled with SDCC, to produce an executable,
+ this library does not by itself cause the resulting executable to
+ be covered by the GNU General Public License. This exception does
+ not however invalidate any other reasons why the executable file
+ might be covered by the GNU General Public License.
+-------------------------------------------------------------------------*/
+
+#ifndef _STDINT_H
+#define _STDINT_H 1
+
+/* Exact integral types. */
+
+#if !defined(__SDCC_pic14) && !defined(__SDCC_pic16)
+#if __STDC_VERSION__ >= 199901L
+#define __SDCC_LONGLONG
+#endif
+#endif
+
+/* Signed. */
+
+typedef signed char int8_t;
+typedef short int int16_t;
+typedef long int int32_t;
+#ifdef __SDCC_LONGLONG
+typedef long long int int64_t;
+#endif
+
+/* Unsigned. */
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned long int uint32_t;
+#ifdef __SDCC_LONGLONG
+typedef unsigned long long int uint64_t;
+#endif
+
+/* Small types. */
+
+/* Signed. */
+typedef signed char int_least8_t;
+typedef short int int_least16_t;
+typedef long int int_least32_t;
+#ifdef __SDCC_LONGLONG
+typedef long long int int_least64_t;
+#endif
+
+/* Unsigned. */
+typedef unsigned char uint_least8_t;
+typedef unsigned short int uint_least16_t;
+typedef unsigned long int uint_least32_t;
+#ifdef __SDCC_LONGLONG
+typedef unsigned long long int uint_least64_t;
+#endif
+
+/* Fast types. */
+
+/* Signed. */
+typedef signed char int_fast8_t;
+typedef int int_fast16_t;
+typedef long int int_fast32_t;
+#ifdef __SDCC_LONGLONG
+typedef long long int int_fast64_t;
+#endif
+
+/* Unsigned. */
+typedef unsigned char uint_fast8_t;
+typedef unsigned int uint_fast16_t;
+typedef unsigned long int uint_fast32_t;
+#ifdef __SDCC_LONGLONG
+typedef unsigned long long int uint_fast64_t;
+#endif
+
+/* Types for `void *' pointers. */
+#if defined (__SDCC_mcs51) || defined (__SDCC_ds390)
+ typedef long int intptr_t;
+ typedef unsigned long int uintptr_t;
+#else
+ typedef int intptr_t;
+ typedef unsigned int uintptr_t;
+#endif
+
+
+/* Largest integral types. */
+#ifndef __SDCC_LONGLONG
+typedef long int intmax_t;
+typedef unsigned long int uintmax_t;
+#else
+typedef long long int intmax_t;
+typedef unsigned long long int uintmax_t;
+#endif
+
+/* Limits of integral types. */
+
+/* Minimum of signed integral types. */
+#define INT8_MIN (-128)
+#define INT16_MIN (-32767-1)
+#define INT32_MIN (-2147483647L-1)
+#ifdef __SDCC_LONGLONG
+#define INT64_MIN (-9223372036854775807LL-1)
+#endif
+
+/* Maximum of signed integral types. */
+#define INT8_MAX (127)
+#define INT16_MAX (32767)
+#define INT32_MAX (2147483647L)
+#ifdef __SDCC_LONGLONG
+#define INT64_MAX (9223372036854775807LL)
+#endif
+
+/* Maximum of unsigned integral types. */
+#define UINT8_MAX (255)
+#define UINT16_MAX (65535)
+#define UINT32_MAX (4294967295UL)
+#ifdef __SDCC_LONGLONG
+#define UINT64_MAX (18446744073709551615ULL)
+#endif
+
+/* Minimum of signed integral types having a minimum size. */
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST32_MIN INT32_MIN
+#ifdef __SDCC_LONGLONG
+#define INT_LEAST64_MIN INT64_MIN
+#endif
+
+/* Maximum of signed integral types having a minimum size. */
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MAX INT32_MAX
+#ifdef __SDCC_LONGLONG
+#define INT_LEAST64_MAX INT64_MAX
+#endif
+
+/* Maximum of unsigned integral types having a minimum size. */
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#ifdef __SDCC_LONGLONG
+#define UINT_LEAST64_MAX UINT64_MAX
+#endif
+
+/* Minimum of fast signed integral types having a minimum size. */
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST32_MIN INT32_MIN
+#ifdef __SDCC_LONGLONG
+#define INT_FAST64_MIN INT64_MIN
+#endif
+
+/* Maximum of fast signed integral types having a minimum size. */
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MAX INT32_MAX
+#ifdef __SDCC_LONGLONG
+#define INT_FAST64_MAX INT64_MAX
+#endif
+
+/* Maximum of fast unsigned integral types having a minimum size. */
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#ifdef __SDCC_LONGLONG
+#define UINT_FAST64_MAX UINT64_MAX
+#endif
+
+/* Values to test for integral types holding `void *' pointer. */
+#if defined (__SDCC_mcs51) || defined (__SDCC_ds390)
+#define INTPTR_MIN (-2147483647L-1)
+#define INTPTR_MAX (2147483647L)
+#define UINTPTR_MAX (4294967295UL)
+#else
+#define INTPTR_MIN (-32767-1)
+#define INTPTR_MAX (32767)
+#define UINTPTR_MAX (65535)
+#endif
+
+/* Minimum for largest signed integral type. */
+#ifndef __SDCC_LONGLONG
+#define INTMAX_MIN (-2147483647L-1)
+#else
+#define INTMAX_MIN (-9223372036854775807LL-1)
+#endif
+
+/* Maximum for largest signed integral type. */
+#ifndef __SDCC_LONGLONG
+#define INTMAX_MAX (2147483647L)
+#else
+#define INTMAX_MAX (9223372036854775807LL)
+#endif
+
+/* Maximum for largest unsigned integral type. */
+#ifndef __SDCC_LONGLONG
+#define UINTMAX_MAX (4294967295UL)
+#else
+#define UINTMAX_MAX (18446744073709551615ULL)
+#endif
+
+/* Limits of other integer types. */
+
+/* Limits of `ptrdiff_t' type. */
+#if defined (__SDCC_mcs51) || defined (__SDCC_ds390)
+#define PTRDIFF_MIN (-2147483647L-1)
+#define PTRDIFF_MAX (2147483647L)
+#else
+#define PTRDIFF_MIN (-32767-1)
+#define PTRDIFF_MAX (32767)
+#endif
+
+/* */
+#define SIG_ATOMIC_MIN (0)
+#define SIG_ATOMIC_MAX (255)
+
+/* Limit of `size_t' type. */
+#define SIZE_MAX (65535u)
+
+/* Signed. */
+#define INT8_C(c) c
+#define INT16_C(c) c
+#define INT32_C(c) c ## L
+#ifdef __SDCC_LONGLONG
+#define INT64_C(c) c ## LL
+#endif
+
+/* Unsigned. */
+#define UINT8_C(c) c ## U
+#define UINT16_C(c) c ## U
+#define UINT32_C(c) c ## UL
+#ifdef __SDCC_LONGLONG
+#define UINT64_C(c) c ## ULL
+#endif
+
+#define WCHAR_MIN 0
+#define WCHAR_MAX 0xffffffff
+
+#define WINT_MIN 0
+#define WINT_MAX 0xffffffff
+
+/* Maximal type. */
+#ifdef __SDCC_LONGLONG
+#define INTMAX_C(c) c ## LL
+#define UINTMAX_C(c) c ## ULL
+#else
+#define INTMAX_C(c) c ## L
+#define UINTMAX_C(c) c ## UL
+#endif
+
+/* Bounds-checking interfaces from annex K of the C11 standard. */
+#if defined (__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__
+#define RSIZE_MAX SIZE_MAX
+#endif
+
+#endif /* stdint.h */
+
diff --git a/gbdk/gbdk-lib/include/stdio.h b/gbdk/gbdk-lib/include/stdio.h
new file mode 100644
index 00000000..894c3f03
--- /dev/null
+++ b/gbdk/gbdk-lib/include/stdio.h
@@ -0,0 +1,70 @@
+/** @file stdio.h
+ Basic file/console input output functions.
+
+ Including stdio.h will use a large number of the
+ background tiles for font characters. If stdio.h
+ is not included then that space will be available
+ for use with other tiles instead.
+ */
+#ifndef STDIO_INCLUDE
+#define STDIO_INCLUDE
+
+#include <types.h>
+
+/** Print char to stdout.
+ @param c Character to print
+ */
+
+void putchar(char c) OLDCALL;
+
+/** Print the string and arguments given by format to stdout.
+
+ @param format The format string as per printf
+
+ Does not return the number of characters printed.
+
+ Currently supported:
+ \li \%hx (char as hex)
+ \li \%hu (unsigned char)
+ \li \%hd (signed char)
+ \li \%c (character)
+ \li \%u (unsigned int)
+ \li \%d (signed int)
+ \li \%x (unsigned int as hex)
+ \li \%s (string)
+
+ Warning: to correctly pass chars for printing as chars, they *must*
+ be explicitly re-cast as such when calling the function.
+ See @ref docs_chars_varargs for more details.
+ */
+void printf(const char *format, ...) OLDCALL;
+
+/** Print the string and arguments given by format to a buffer.
+
+ @param str The buffer to print into
+ @param format The format string as per @ref printf
+
+ Does not return the number of characters printed.
+ */
+void sprintf(char *str, const char *format, ...) OLDCALL;
+
+/** puts() writes the string __s__ and a trailing newline to stdout.
+*/
+void puts(const char *s);
+
+/** gets() Reads a line from stdin into a buffer pointed to by __s__.
+
+ @param s Buffer to store string in
+
+ Reads until either a terminating newline or an EOF, which it replaces with '\0'. No
+ check for buffer overrun is performed.
+
+ Returns: Buffer pointed to by __s__
+*/
+char *gets(char *s) OLDCALL;
+
+/** getchar() Reads and returns a single character from stdin.
+ */
+char getchar() OLDCALL;
+
+#endif
diff --git a/gbdk/gbdk-lib/include/stdlib.h b/gbdk/gbdk-lib/include/stdlib.h
new file mode 100644
index 00000000..eef0fe73
--- /dev/null
+++ b/gbdk/gbdk-lib/include/stdlib.h
@@ -0,0 +1,143 @@
+/** file stdlib.h
+ 'Standard library' functions, for whatever that means.
+*/
+#ifndef STDLIB_INCLUDE
+#define STDLIB_INCLUDE
+
+#include <types.h>
+
+#if !defined(__SDCC_mcs51) && !defined(__SDCC_ds390) && !defined(__SDCC_ds400) && !defined(__SDCC_hc08) && !defined(__SDCC_s08) && !defined(__SDCC_pic14) && !defined(__SDCC_pic16) && !defined(__SDCC_pdk13) && !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15)
+#define __reentrant
+#endif
+
+/** Causes normal program termination and the value of status is
+ returned to the parent.
+ All open streams are flushed and closed.
+*/
+void exit(int status) OLDCALL;
+
+#if 0
+/** Compatibility function. Not implemented.
+ */
+int getkey(void) OLDCALL;
+#endif
+
+/** Returns the absolute value of int __i__
+ @param i Int to obtain absolute value of
+
+ If i is negative, returns -i; else returns i.
+*/
+int abs(int i) OLDCALL;
+
+
+/** Returns the absolute value of long int __num__
+
+ @param num Long integer to obtain absolute value of
+ */
+long labs(long num) OLDCALL;
+
+
+/** Converts an ASCII string to an int
+
+ @param s String to convert to an int
+
+ The string may be of the format
+ \code{.c}
+ [\s]*[+-][\d]+[\D]*
+ \endcode
+ i.e. any number of spaces, an optional + or -, then an
+ arbitrary number of digits.
+
+ The result is undefined if the number doesnt fit in an int.
+
+ Returns: Int value of string
+ */
+int atoi(const char *s);
+
+
+/** Converts an ASCII string to a long.
+ @param s String to convert to an long int
+ @see atoi()
+
+ Returns: Long int value of string
+ */
+long atol(const char *s);
+
+/** Converts an int into a base 10 ASCII string.
+ @param n Int to convert to a string
+ @param s String to store the converted number
+ @param radix Numerical base for converted number, ex: 10 is decimal base
+ (parameter is required but not utilized on Game Boy and Analogue Pocket)
+
+ Returns: Pointer to converted string
+ */
+char *itoa(int n, char *s, unsigned char radix) OLDCALL;
+
+/** Converts an unsigned int into a base 10 ASCII string.
+ @param n Unsigned Int to convert to a string
+ @param s String to store the converted number
+ @param radix Numerical base for converted number, ex: 10 is decimal base
+ (parameter is required but not utilized on Game Boy and Analogue Pocket)
+
+ Returns: Pointer to converted string
+ */
+char *uitoa(unsigned int n, char *s, unsigned char radix) OLDCALL;
+
+/** Converts a long into a base 10 ASCII string.
+ @param n Long int to convert to a string
+ @param s String to store the converted number
+ @param radix Numerical base for converted number, ex: 10 is decimal base
+ (parameter is required but not utilized on Game Boy and Analogue Pocket)
+
+ Returns: Pointer to converted string
+ */
+char *ltoa(long n, char *s, unsigned char radix) OLDCALL;
+
+/** Converts an unsigned long into a base 10 ASCII string.
+ @param n Unsigned Long Int to convert to a string
+ @param s String to store the converted number
+ @param radix Numerical base for converted number, ex: 10 is decimal base
+ (parameter is required but not utilized on Game Boy and Analogue Pocket)
+
+ Returns: Pointer to converted string
+ */
+char *ultoa(unsigned long n, char *s, unsigned char radix) OLDCALL;
+
+
+/** Memory allocation functions
+ */
+void *calloc (size_t nmemb, size_t size);
+void *malloc (size_t size);
+void *realloc (void *ptr, size_t size);
+#if __STDC_VERSION__ >= 201112L
+inline void *aligned_alloc(size_t alignment, size_t size)
+{
+ (void)alignment;
+ return malloc(size);
+}
+#endif
+extern void free (void * ptr);
+
+/* Searching and sorting utilities (ISO C11 7.22.5) */
+/** search a sorted array of __nmemb__ items
+ @param key Pointer to object that is the key for the search
+ @param base Pointer to first object in the array to search
+ @param nmemb Number of elements in the array
+ @param size Size in bytes of each element in the array
+ @param compar Function used to compare two elements of the array
+
+ Returns: Pointer to array entry that matches the search key.
+ If key is not found, NULL is returned.
+*/
+extern void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *) __reentrant);
+
+
+/** Sort an array of __nmemb__ items
+ @param base Pointer to first object in the array to sort
+ @param nmemb Number of elements in the array
+ @param size Size in bytes of each element in the array
+ @param compar Function used to compare and sort two elements of the array
+*/
+extern void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *) __reentrant);
+
+#endif
diff --git a/gbdk/gbdk-lib/include/stdnoreturn.h b/gbdk/gbdk-lib/include/stdnoreturn.h
new file mode 100644
index 00000000..992f9b96
--- /dev/null
+++ b/gbdk/gbdk-lib/include/stdnoreturn.h
@@ -0,0 +1,7 @@
+#ifndef __SDCC_STDNORETURN_H
+#define __SDCC_STDNORETURN_H 1
+
+#define noreturn _Noreturn
+
+#endif
+
diff --git a/gbdk/gbdk-lib/include/string.h b/gbdk/gbdk-lib/include/string.h
new file mode 100644
index 00000000..d79b5c17
--- /dev/null
+++ b/gbdk/gbdk-lib/include/string.h
@@ -0,0 +1,17 @@
+/** @file string.h
+ Generic string functions.
+ */
+#ifndef STD_STRING_INCLUDE
+#define STD_STRING_INCLUDE
+
+#ifdef __PORT_sm83
+ #include <asm/sm83/string.h>
+#else
+ #ifdef __PORT_z80
+ #include <asm/z80/string.h>
+ #else
+ #error Unrecognised port
+ #endif
+#endif
+
+#endif
diff --git a/gbdk/gbdk-lib/include/time.h b/gbdk/gbdk-lib/include/time.h
new file mode 100644
index 00000000..40e1a100
--- /dev/null
+++ b/gbdk/gbdk-lib/include/time.h
@@ -0,0 +1,38 @@
+/** @file time.h
+ Sort of ANSI compliant time functions.
+*/
+#ifndef TIME_INCLUDE
+#define TIME_INCLUDE
+
+#include <types.h>
+#include <stdint.h>
+
+#define CLOCKS_PER_SEC 60
+
+typedef uint16_t time_t;
+
+/** Returns an approximation of processor time used by the program in Clocks
+
+ The value returned is the CPU time (ticks) used so far as a @ref clock_t.
+
+ To get the number of seconds used, divide by @ref CLOCKS_PER_SEC.
+
+ This is based on @ref sys_time, which will wrap around every ~18 minutes.
+ (unsigned 16 bits = 65535 / 60 / 60 = 18.2)
+
+ @see sys_time, time()
+*/
+clock_t clock() OLDCALL;
+
+/** Converts clock() time to Seconds
+
+ @param t If pointer __t__ is not NULL, it's value will be set to the same seconds calculation as returned by the function.
+
+ The calculation is clock() / CLOCKS_PER_SEC
+
+ Returns: time in seconds
+ @see sys_time, clock()
+*/
+time_t time(time_t *t);
+
+#endif
diff --git a/gbdk/gbdk-lib/include/typeof.h b/gbdk/gbdk-lib/include/typeof.h
new file mode 100644
index 00000000..e1f6f97f
--- /dev/null
+++ b/gbdk/gbdk-lib/include/typeof.h
@@ -0,0 +1,54 @@
+/*-------------------------------------------------------------------------
+ typeof.h - Contains enumerations of values returned by __typeof
+
+ Copyright (C) 2001, Sandeep Dutta . sandeep.dutta@usa.net
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ As a special exception, if you link this library with other files,
+ some of which are compiled with SDCC, to produce an executable,
+ this library does not by itself cause the resulting executable to
+ be covered by the GNU General Public License. This exception does
+ not however invalidate any other reasons why the executable file
+ might be covered by the GNU General Public License.
+-------------------------------------------------------------------------*/
+
+#ifndef __SDC51_TYPEOF_H
+#define __SDC51_TYPEOF_H 1
+
+#define TYPEOF_INT 1
+#define TYPEOF_SHORT 2
+#define TYPEOF_CHAR 3
+#define TYPEOF_LONG 4
+#define TYPEOF_FLOAT 5
+#define TYPEOF_FIXED16X16 6
+#define TYPEOF_BIT 7
+#define TYPEOF_BITFIELD 8
+#define TYPEOF_SBIT 9
+#define TYPEOF_SFR 10
+#define TYPEOF_VOID 11
+#define TYPEOF_STRUCT 12
+#define TYPEOF_ARRAY 13
+#define TYPEOF_FUNCTION 14
+#define TYPEOF_POINTER 15
+#define TYPEOF_FPOINTER 16
+#define TYPEOF_CPOINTER 17
+#define TYPEOF_GPOINTER 18
+#define TYPEOF_PPOINTER 19
+#define TYPEOF_IPOINTER 20
+#define TYPEOF_EEPPOINTER 21
+
+#endif
diff --git a/gbdk/gbdk-lib/include/types.h b/gbdk/gbdk-lib/include/types.h
new file mode 100644
index 00000000..3710bdf8
--- /dev/null
+++ b/gbdk/gbdk-lib/include/types.h
@@ -0,0 +1,25 @@
+/** @file types.h
+ Basic types.
+ Directly include the port specific file.
+*/
+#ifndef TYPES_INCLUDE
+#define TYPES_INCLUDE
+
+#include <asm/types.h>
+
+/** Good 'ol NULL.
+ */
+#define NULL 0
+
+/** A 'false' value.
+ */
+#define FALSE 0
+/** A 'true' value.
+ */
+#define TRUE 1
+
+/** No longer used.
+ */
+typedef void * POINTER;
+
+#endif