summaryrefslogtreecommitdiff
path: root/gb.h
diff options
context:
space:
mode:
Diffstat (limited to 'gb.h')
-rw-r--r--gb.h123
1 files changed, 123 insertions, 0 deletions
diff --git a/gb.h b/gb.h
new file mode 100644
index 0000000..6be3a94
--- /dev/null
+++ b/gb.h
@@ -0,0 +1,123 @@
+#ifndef GB_H
+#define GB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdint.h>
+
+typedef enum {
+ STATE_RUN,
+ STATE_STOP,
+ STATE_HALT,
+ STATE_INVALID,
+ STATE_NOT_IMPLEMENTED,
+ STATE_LAST,
+} gb_cpu_state_t;
+
+#define GB_BTN_UP 1
+#define GB_BTN_DOWN (1 << 1)
+#define GB_BTN_LEFT (1 << 2)
+#define GB_BTN_RIGHT (1 << 3)
+#define GB_BTN_A (1 << 4)
+#define GB_BTN_B (1 << 5)
+#define GB_BTN_SELECT (1 << 6)
+#define GB_BTN_START (1 << 7)
+
+typedef struct {
+ struct {
+ _Bool in_bios;
+
+ // FIXME: combine these?
+ uint8_t bios[0x100]; // bios (256 bytes)
+ uint8_t ram[0x2000]; // working ram (8k)
+ uint8_t eram[65536]; // external ram (banked, up to 64k)
+ uint8_t vram[0x2000]; // vram (8k)
+ uint8_t oam[0xA0]; // oam (160 bytes)
+ uint8_t zram[0x7F]; // zram (128 bytes)
+
+ // rom (at least 32k)
+ const uint8_t *rom;
+ uint32_t rom_size;
+
+ union {
+ struct {
+ // current rom bank (5 bits); see note about
+ // rom_ram_mode below
+ uint8_t rom_bank;
+
+ // is external ram enabled?
+ _Bool ram_enable;
+
+ // ram bank
+ // rom_ram_mode == 0: high two bits of rom bank
+ // rom_ram_mode == 1: ram bank
+ uint8_t ram_bank;
+
+ // set interpretation of ram_bank
+ _Bool rom_ram_mode;
+ } mbc1;
+
+ struct {
+ // current rom bank (4 bits)
+ uint8_t rom_bank;
+
+ // is eram enabled?
+ _Bool ram_enable;
+ } mbc2;
+ };
+
+ // interrupts
+ // ie: interrupt enable (addr: 0xFFFF)
+ // iv: interrupt vector (addr: 0xFF0F)
+ // (gb-manual, p26)
+ uint8_t ie;
+ uint8_t iv;
+
+ // buttons (addr: 0xFF00)
+ // gb-manual, p23
+ uint8_t p1_mode;
+ uint8_t btns;
+ } mmu;
+
+ struct {
+ uint16_t clock;
+ uint8_t mode,
+ lcdc,
+ stat,
+ scy,
+ scx,
+ wy,
+ wx,
+ bgp,
+ obp0,
+ obp1,
+ line,
+ lyc;
+ uint8_t rgb[3 * 160 * 144];
+ uint32_t frame;
+ } gpu;
+
+ struct {
+ uint16_t div;
+ uint32_t tima; // NOTE: cannot be uint16_t because of 10-bit shift
+ uint8_t tma,
+ tac;
+ } timer;
+
+ struct {
+ uint16_t rs[6 /* RW_LAST */];
+ uint32_t clock; /* FIXME: uint16_t? */
+ gb_cpu_state_t state;
+
+ // interrupt master enable
+ _Bool ime;
+ } cpu;
+} gb_t;
+
+#ifdef __cplusplus
+};
+#endif /* __cplusplus */
+
+#endif /* GB_H */