diff --git a/include/gb.h b/include/gb.h index d2d2306..ee384ef 100644 --- a/include/gb.h +++ b/include/gb.h @@ -88,18 +88,22 @@ enum { }; typedef struct gb_dmg_ppu_t { + GBPixBuf *pixbuf; ut64 seek; ut8 buf[GB_PPU_N_REGS]; int reg_fd; int vram_fd; } GBPPU; +//these are in STAT #define GB_PPU_MODE0 0 -#define GB_PPU_MODE1 0x10000 -#define GB_PPU_MODE2 0x20000 -#define GB_PPU_MODE3 0x30000 -#define GB_PPU_MODE_MASK 0x30000 -#define GB_PPU_DOUBLE_SPEED 0x40000 +#define GB_PPU_MODE1 1 +#define GB_PPU_MODE2 2 +#define GB_PPU_MODE3 3 +#define GB_PPU_MODE_MASK 3 + +//this is in seek +#define GB_PPU_DOUBLE_SPEED 0x10000 typedef struct gameboy_t { RIO *io; @@ -108,9 +112,8 @@ typedef struct gameboy_t { GBJoypad *joypad; GBDMA *dma; GBPPU *ppu; - GBPixBuf *pixbuf; + ut64 addr; int cartrigde_fd; - } GB; GBPPU *gb_ppu_open (RIO *io); diff --git a/io/ppu.c b/io/ppu.c new file mode 100644 index 0000000..99a373b --- /dev/null +++ b/io/ppu.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include + +RIOPlugin r_io_plugin_gb_ppu; + +static ut64 __lseek(RIO* io, RIODesc *desc, ut64 offset, int whence) { + GBPPU *ppu = desc->data; + ut64 seek = ppu->seek & 0xffff; + switch (whence) { + case R_IO_SEEK_SET: + seek = R_MIN (GB_PPU_N_REGS, offset); + break; + case R_IO_SEEK_CUR: + seek = R_MIN (GB_PPU_N_REGS, seek + offset); + break; + case R_IO_SEEK_END: + seek = GB_PPU_N_REGS; + break; + } + ppu->seek = (ppu->seek & (~0xffff)) | seek; + return seek; +} + +static bool __check(RIO *io, const char *pathname, bool many) { + return r_str_startswith (pathname, "gb_ppu://"); +} + +static int __read(RIO *io, RIODesc *desc, ut8 *buf, int len) { + GBPPU *ppu = desc->data; + ut64 seek = ppu->seek & 0xffff; + if (ppu->seek >= GB_PPU_N_REGS || len < 1) { + return 0; + } + len = R_MIN (len, GB_PPU_N_REGS - seek); + memcpy (buf, &ppu->buf[ppu->seek], len); + seek += len; + ppu->seek = (ppu->seek & (~0xffff)) | seek; + return len; +} + +static int __write(RIO *io, RIODesc *desc, const ut8 *buf, int len) { + GBPPU *ppu = desc->data; + ut64 seek = ppu->seek & 0xffff; + if (ppu->seek >= GB_PPU_N_REGS || len < 1) { + return 0; + } + len = R_MIN (len, GB_PPU_N_REGS - seek); + ut32 i; + for (i = 0; i < len; i++) { + switch (seek) { + case GB_PPU_STAT: + ppu->buf[GB_PPU_STAT] = (buf[i] & 0xf8) | (ppu->buf[GB_PPU_STAT] & 0x7); + case GB_PPU_LY: + break; + default: + ppu->buf[seek] = buf[i]; + break; + } + seek++; + } + return len; +} + +static bool __close(RIODesc *desc) { + return true; +} + +static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { + if (!r_str_startswith (pathname, "gb_ppu://")) { + return NULL; + } + GBPPU *ppu = NULL; + sscanf (pathname, "gb_ppu://%p", &ppu); + RIODesc *desc = r_io_desc_new (io, &r_io_plugin_gb_ppu, pathname, + R_PERM_RWX, mode, ppu); + return desc; +} + +RIOPlugin r_io_plugin_gb_ppu = { + .meta = { + .name = "gb_ppu", + .desc = "gb_ppu", + .license = "LGPL", + }, + .uris = "gb_ppu://", + .open = __open, + .close = __close, + .read = __read, + .check = __check, + .seek = __lseek, + .write = __write, +};