Implement read_tile_data
This commit is contained in:
parent
3436097c6d
commit
5d113adc77
21
include/gb.h
21
include/gb.h
|
@ -87,6 +87,11 @@ enum {
|
||||||
GB_PPU_N_REGS,
|
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 {
|
enum {
|
||||||
GB_PPU_STAT_MODE_HBLANK = 0,
|
GB_PPU_STAT_MODE_HBLANK = 0,
|
||||||
GB_PPU_STAT_MODE_VBLANK,
|
GB_PPU_STAT_MODE_VBLANK,
|
||||||
|
@ -102,10 +107,19 @@ typedef struct oam_scan_table {
|
||||||
ut8 addr;
|
ut8 addr;
|
||||||
} OAMScanTable;
|
} 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 {
|
typedef struct pixel_fifo_t {
|
||||||
ut64 data;
|
ut64 data;
|
||||||
ut32 fetch;
|
PixelFifoFetch fetch[2];
|
||||||
ut32 obj_fetch;
|
|
||||||
ut8 shift_out; //lower nibble is sourch info, pallet, color
|
ut8 shift_out; //lower nibble is sourch info, pallet, color
|
||||||
// 0b....spcc
|
// 0b....spcc
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -114,9 +128,8 @@ win - 01
|
||||||
obj p0 - 10
|
obj p0 - 10
|
||||||
obj p1 - 11
|
obj p1 - 11
|
||||||
#endif
|
#endif
|
||||||
ut8 n_fpixel; //number of pixel that are currently in the upper half of the fifo - 1
|
ut8 n_fpixel; //number of pixel that are currently in the fifo
|
||||||
ut8 x;
|
ut8 x;
|
||||||
ut8 y;
|
|
||||||
} PixelFifo;
|
} PixelFifo;
|
||||||
|
|
||||||
typedef struct gb_dmg_ppu_t {
|
typedef struct gb_dmg_ppu_t {
|
||||||
|
|
50
io/ppu.c
50
io/ppu.c
|
@ -139,7 +139,7 @@ static ut32 gb_ppu_oam_scan_update (GB *gb, ut32 cycles) {
|
||||||
cycles -= running_cycles;
|
cycles -= running_cycles;
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
const ut8 height = gb->ppu->buf[GB_PPU_LCDC] & 0x3? 16: 8;
|
const ut8 height = (gb->ppu->buf[GB_PPU_LCDC] & GB_PPU_LCDC_BIG_OBJ)? 16: 8;
|
||||||
const ut8 ly = gb->ppu->buf[GB_PPU_LY] + 16;
|
const ut8 ly = gb->ppu->buf[GB_PPU_LY] + 16;
|
||||||
while (cycles && gb->ppu->ost.addr <= 0xa0) {
|
while (cycles && gb->ppu->ost.addr <= 0xa0) {
|
||||||
if (gb->ppu->ost.n_entries < 10) {
|
if (gb->ppu->ost.n_entries < 10) {
|
||||||
|
@ -164,20 +164,64 @@ beach:
|
||||||
return cycles;
|
return cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void read_tile_data (GB *gb, ut8 *tile) {
|
||||||
|
const bool use_window = !!(gb->ppu->fifo.shift_out & GB_PIXEL_FIFO_FETCH_WINDOW);
|
||||||
|
ut64 addr;
|
||||||
|
if (use_window) {
|
||||||
|
const ut8 x = ((gb->ppu->fifo.x + ((!!gb->ppu->fifo.n_fpixel) << 3)) -
|
||||||
|
gb->ppu->buf[GB_PPU_WX]) & 0xf8;
|
||||||
|
//maybe store this at begin of line
|
||||||
|
const ut8 y = (gb->ppu->buf[GB_PPU_LY] - gb->ppu->buf[GB_PPU_WY]) & 0xf8;
|
||||||
|
addr = ((gb->ppu->buf[GB_PPU_LCDC] & GB_PPU_LCDC_WIN_TILE_MAP)?
|
||||||
|
0x1800: 0x1c00) + y * 32 + x;
|
||||||
|
} else {
|
||||||
|
const ut8 x = (gb->ppu->fifo.x + gb->ppu->buf[GB_PPU_SCX] +
|
||||||
|
((!!gb->ppu->fifo.n_fpixel) << 3)) & 0xf8;
|
||||||
|
const ut8 y = (gb->ppu->buf[GB_PPU_LY] + gb->ppu->buf[GB_PPU_SCY]) & 0xf8;
|
||||||
|
addr = ((gb->ppu->buf[GB_PPU_LCDC] & GB_PPU_LCDC_BG_TILE_MAP)?
|
||||||
|
0x1800: 0x1c00) + y * 32 + x;
|
||||||
|
}
|
||||||
|
r_io_fd_read_at (gb->io, gb->ppu->vram_fd, addr, tile, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static void gb_ppu_pixel_fifo_merge_opixels (PixelFifo *pxf, bool priority) {
|
static void gb_ppu_pixel_fifo_merge_opixels (PixelFifo *pxf, bool priority) {
|
||||||
ut32 pixels = pxf->data >> 32;
|
ut32 pixels = pxf->data >> 32;
|
||||||
ut32 newpixels = 0;
|
ut32 newpixels = 0;
|
||||||
ut32 i;
|
ut32 i;
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if (!(pixels & (0x3 << 28))) {
|
if (!(pixels & (0x3 << 28))) { //check for transparency
|
||||||
newpixels = (newpixels << 4) |
|
newpixels = (newpixels << 4) |
|
||||||
((pxf->obj_fetch & (0xf << ((i - 1) << 2))) >> ((i - 1) << 2));
|
((pxf->fetch[1].fetched & (0xf << ((i - 1) << 2))) >> ((i - 1) << 2));
|
||||||
pixels = pixels << 4;
|
pixels = pixels << 4;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gb_pixel_fifo_fetch_continue (GB *gb) {
|
||||||
|
PixelFifo *fifo = &gb->ppu->fifo;
|
||||||
|
ut8 fetcher = !!(fifo->shift_out & GB_PIXEL_FIFO_FETCH_SELECT);
|
||||||
|
ut8 tile;
|
||||||
|
switch (fifo->fetch[fetcher].state_ctr) {
|
||||||
|
case 0:
|
||||||
|
read_tile_data (gb, &tile);
|
||||||
|
if (gb->ppu->buf[GB_PPU_LCDC] & GB_PPU_LCDC_TILE_BASE) {
|
||||||
|
fifo->fetch[fetcher].addr = tile * 16;
|
||||||
|
} else {
|
||||||
|
st8 stile = (st8)tile;
|
||||||
|
fifo->fetch[fetcher].addr = 0x1000 + stile * 16;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
fifo->fetch[fetcher].addr++;
|
||||||
|
case 5:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ut32 gb_ppu_render_update (GB *gb, ut32 cycles) {
|
static ut32 gb_ppu_render_update (GB *gb, ut32 cycles) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user