diff options
-rw-r--r-- | gb.h | 123 | ||||
-rw-r--r-- | ops.yaml | 153 |
2 files changed, 145 insertions, 131 deletions
@@ -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 */ @@ -7519,6 +7519,7 @@ templates: main: | #include <stdint.h> #include <stdbool.h> + #include "gb.h" #define UNUSED(a) ((void) (a)) @@ -7550,127 +7551,16 @@ templates: RW_LAST, } rw_t; - typedef enum { - STATE_RUN, - STATE_STOP, - STATE_HALT, - STATE_INVALID, - STATE_NOT_IMPLEMENTED, - STATE_LAST, - } gb_cpu_state_t; - // gb-manual, p23 - typedef enum { - P1_MODE_NONE, - P1_MODE_P14, - P1_MODE_P15, - } p1_mode_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) + #define P1_MODE_NONE 0 + #define P1_MODE_P14 1 + #define P1_MODE_P15 2 #define GPU_MODE_OAM 2 #define GPU_MODE_VRAM 3 #define GPU_MODE_HBLANK 0 #define GPU_MODE_VBLANK 1 - 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_num; - } 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[RW_LAST]; - uint32_t clock; /* FIXME: uint16_t? */ - gb_cpu_state_t state; - - // interrupt master enable - bool ime; - } cpu; - } gb_t; - #define CART_TYPE_ROM_ONLY 0x00 #define CART_TYPE_MBC1 0x01 #define CART_TYPE_MBC1_RAM 0x02 @@ -9625,23 +9515,6 @@ templates: } } - void - gb_btn_set( - gb_t * const ctx, - const uint8_t btn, - const bool set - ) { - if (set) { - ctx->mmu.btns |= btn; - } else { - ctx->mmu.btns &= ~btn; - } - - // trigger p1 interrupt - mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & (1 << 4)); - // TODO: handle HALT and STOP - } - static void cpu_handle_interrupts( gb_t * const ctx @@ -9734,6 +9607,24 @@ templates: } void + gb_set_buttons( + gb_t * const ctx, + const uint8_t btn, + const bool set + ) { + if (set) { + // set buttons + ctx->mmu.btns |= btn; + } else { + // clear buttons + ctx->mmu.btns &= ~btn; + } + + // trigger p1 interrupt + mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & (1 << 4)); + } + + void gb_frame( gb_t * const ctx ) { |