ragb/include/gb.h
2024-11-02 04:09:09 +01:00

169 lines
3.4 KiB
C

#ifndef GB_H
#define GB_H
#include <ragb_sdl.h>
#include <r_io.h>
#include <r_arch.h>
#include <r_esil.h>
enum {
GB_TIMERS_DIV = 0,
GB_TIMERS_TIMA,
GB_TIMERS_TMA,
GB_TIMERS_TAC,
GB_TIMERS_N_REGS,
};
typedef struct gb_timers_t {
ut64 seek;
ut32 fd;
ut16 odiv;
ut16 div;
ut8 buf[4];
ut8 otma;
st8 tima_wait;
bool check_fedge;
} GBTimers;
GBTimers *gb_timers_open(RIO *io);
void gb_timers_update(GBTimers *timers, ut32 cycles);
void gb_timers_close(GBTimers *timers, RIO *io);
typedef struct gb_joypad_t {
ut8 *keys;
int fd;
ut16 up;
ut16 down;
ut16 left;
ut16 right;
ut16 a;
ut16 b;
ut16 start;
ut16 select;
ut8 data;
ut8 odata;
} GBJoypad;
GBJoypad *gb_joypad_open(RIO *io);
void gb_joypad_update(GBJoypad *joypad);
void gb_joypad_close(GBJoypad *joypad, RIO *io);
typedef struct gb_dma_t {
ut64 seek; //17 bit seek and some flags
int dma_fd; //fd representing the dma register
int dma_bus_fd; //fd representing the memory bus while dma occupies it
int oam_fd; //fd representing oam
ut32 dma_bank_id;
ut32 default_bank_id;
// ut16 bus_occupancy_size;
ut8 buf[0xa0];
ut8 dst; //current dst addr low byte
// ut8 todo; //cycles todo
st8 frontrun; //cycles that read/write ops had frontrun the dma copy
ut8 val;
} GBDMA;
#define GB_DMA_LAUNCH 0x20000
#define GB_DMA_RUNNING 0x40000
#define GB_DMA_ACTIVE 0x60000
#define GB_DMA_CGB_MODE 0x80000
GBDMA *gb_dma_open(RIO *io);
//void gb_dma_enable_cgb(GBDMA *dma);
void gb_dma_update(GBDMA *dma, RIO *io, ut32 cycles, bool pre_exec);
void gb_dma_close(GBDMA *dma, RIO *io);
enum {
GB_PPU_LCDC = 0, //0xff40
GB_PPU_STAT, //0xff41
GB_PPU_SCY, //0xff42
GB_PPU_SCX, //0xff43
GB_PPU_LY, //0xff44
GB_PPU_LYC, //0xff45
GB_PPU_BGP, //0xff47
GB_PPU_OBP0, //0xff48
GB_PPU_OBP1, //0xff49
GB_PPU_WY, //0xff4a
GB_PPU_WX, //0xff4b
GB_PPU_N_REGS,
};
#define GB_PPU_LCDC_BIG_OBJ 0x4
#define GB_PPU_LCDC_BG_TILE_MAP 0x8
#define GB_PPU_LCDC_TILE_BASE 0x10
#define GB_PPU_LCDC_WIN_TILE_MAP 0x40
enum {
GB_PPU_STAT_MODE_HBLANK = 0,
GB_PPU_STAT_MODE_VBLANK,
GB_PPU_STAT_MODE_OAM_SCAN,
GB_PPU_STAT_MODE_RENDER,
};
#define GB_PPU_STAT_MODE_MASK 0x3
typedef struct oam_scan_table {
ut16 data[10]; //low byte is x coordinate of sprite; high byte is addr of entry (0xffe0 + high byte)
ut8 n_entries; //max 10
ut8 addr;
} OAMScanTable;
typedef struct pixel_fifo_fetch_t {
ut32 fetched;
ut16 addr;
ut8 data[2];
ut8 state_ctr;
} PixelFifoFetch;
#define GB_PIXEL_FIFO_FETCH_SELECT 0x10
#define GB_PIXEL_FIFO_FETCH_WINDOW 0x20
typedef struct pixel_fifo_t {
ut64 data;
PixelFifoFetch fetch[2];
ut8 shift_out; //lower nibble is sourch info, pallet, color
// 0b....spcc
#if 0
bg - 00
win - 01
obj p0 - 10
obj p1 - 11
#endif
ut8 n_fpixel; //number of pixel that are currently in the fifo
ut8 x;
} PixelFifo;
typedef struct gb_dmg_ppu_t {
GBPixBuf *pixbuf;
ut64 seek;
ut8 buf[GB_PPU_N_REGS];
OAMScanTable ost;
PixelFifo fifo;
int reg_fd;
int vram_fd;
ut32 vram_mapid;
ut32 oam_mapid;
} GBPPU;
typedef struct gameboy_t {
RIO *io;
RArch *arch;
GBTimers *timers;
GBJoypad *joypad;
GBDMA *dma;
GBPPU *ppu;
ut64 addr;
int cartrigde_fd;
bool double_speed;
} GB;
GBPPU *gb_ppu_open (RIO *io, SDL_Renderer *renderer);
void gb_ppu_update (GB *gb, ut32 cycles);
void gb_ppu_close (GBPPU *ppu, RIO *io);
extern RIOPlugin r_io_plugin_gb_timers;
extern RIOPlugin r_io_plugin_gb_mbc1;
extern RIOPlugin r_io_plugin_gb_mbc2;
extern RIOPlugin r_io_plugin_gb_joypad;
#endif