summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gb.h123
-rw-r--r--ops.yaml153
2 files changed, 145 insertions, 131 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 */
diff --git a/ops.yaml b/ops.yaml
index 9f33510..f08a64a 100644
--- a/ops.yaml
+++ b/ops.yaml
@@ -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
) {