diff --git a/include/gb.h b/include/gb.h index ced4190..63c03ab 100644 --- a/include/gb.h +++ b/include/gb.h @@ -102,13 +102,33 @@ typedef struct oam_scan_table { ut8 addr; } OAMScanTable; +typedef struct pixel_fifo_t { + ut64 data; + ut32 fetch; + ut32 obj_fetch; + 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 upper half of the fifo - 1 + ut8 x; + ut8 y; +} 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 { diff --git a/io/ppu.c b/io/ppu.c index 353665f..63a4e89 100644 --- a/io/ppu.c +++ b/io/ppu.c @@ -145,7 +145,7 @@ static ut32 gb_ppu_oam_scan_update (GB *gb, ut32 cycles) { if (gb->ppu->ost.n_entries < 10) { ut8 yx[2]; r_io_fd_read_at (gb->io, gb->dma->oam_fd, (ut64)gb->ppu->ost.addr, yx, 2); - if ((yx[0] <= ly) && (ly < (yx[0] + height))) { + if ((yx[0] <= ly) && (ly < (yx[0] + height)) && yx[1]) { gb->ppu->ost.data[gb->ppu->ost.n_entries] = (gb->ppu->ost.addr << 8) | yx[1]; gb->ppu->ost.n_entries++; @@ -158,10 +158,38 @@ beach: if (gb->ppu->ost.addr == 0xa0) { //indicate next mode gb->ppu->buf[GB_PPU_STAT] |= GB_PPU_STAT_MODE_RENDER; + RIOMap *vram = r_io_map_get (gb->io, gb->ppu->vram_mapid); + vram->perm = 0; //disable vram access for rendering } return cycles; } +static void gb_ppu_pixel_fifo_merge_opixels (PixelFifo *pxf, bool priority) { + ut32 pixels = pxf->data >> 32; + ut32 newpixels = 0; + ut32 i; + for (i = 0; i < 8; i++) { + if (!(pixels & (0x3 << 28))) { + newpixels = (newpixels << 4) | + ((pxf->obj_fetch & (0xf << ((i - 1) << 2))) >> ((i - 1) << 2)); + pixels = pixels << 4; + continue; + } + } +} + +static ut32 gb_ppu_render_update (GB *gb, ut32 cycles) { + return 0; +} + +static ut32 gb_ppu_hblank_update (GB *gb, ut32 cycles) { + return 0; +} + +static ut32 gb_ppu_vblank_update (GB *gb, ut32 cycles) { + return 0; +} + void gb_ppu_update (GB *gb, ut32 cycles) { while (cycles) { switch (gb->ppu->buf[GB_PPU_STAT] & GB_PPU_STAT_MODE_MASK) { @@ -169,10 +197,13 @@ void gb_ppu_update (GB *gb, ut32 cycles) { cycles = gb_ppu_oam_scan_update (gb, cycles); break; case GB_PPU_STAT_MODE_RENDER: + cycles = gb_ppu_render_update (gb, cycles); break; case GB_PPU_STAT_MODE_HBLANK: + cycles = gb_ppu_hblank_update (gb, cycles); break; case GB_PPU_STAT_MODE_VBLANK: + cycles = gb_ppu_vblank_update (gb, cycles); break; } }