Minor progress on gb_ppu_render_continue
This commit is contained in:
parent
feb59859ef
commit
4fe5bd2e15
14
include/gb.h
14
include/gb.h
|
@ -25,7 +25,7 @@ typedef struct gb_timers_t {
|
||||||
} GBTimers;
|
} GBTimers;
|
||||||
|
|
||||||
GBTimers *gb_timers_open(RIO *io);
|
GBTimers *gb_timers_open(RIO *io);
|
||||||
void gb_timers_update(GBTimers *timers, ut32 cycles);
|
void gb_timers_continue(GBTimers *timers, ut32 cycles);
|
||||||
void gb_timers_close(GBTimers *timers, RIO *io);
|
void gb_timers_close(GBTimers *timers, RIO *io);
|
||||||
|
|
||||||
typedef struct gb_joypad_t {
|
typedef struct gb_joypad_t {
|
||||||
|
@ -44,7 +44,7 @@ typedef struct gb_joypad_t {
|
||||||
} GBJoypad;
|
} GBJoypad;
|
||||||
|
|
||||||
GBJoypad *gb_joypad_open(RIO *io);
|
GBJoypad *gb_joypad_open(RIO *io);
|
||||||
void gb_joypad_update(GBJoypad *joypad);
|
void gb_joypad_continue(GBJoypad *joypad);
|
||||||
void gb_joypad_close(GBJoypad *joypad, RIO *io);
|
void gb_joypad_close(GBJoypad *joypad, RIO *io);
|
||||||
|
|
||||||
typedef struct gb_dma_t {
|
typedef struct gb_dma_t {
|
||||||
|
@ -69,7 +69,7 @@ typedef struct gb_dma_t {
|
||||||
|
|
||||||
GBDMA *gb_dma_open(RIO *io);
|
GBDMA *gb_dma_open(RIO *io);
|
||||||
//void gb_dma_enable_cgb(GBDMA *dma);
|
//void gb_dma_enable_cgb(GBDMA *dma);
|
||||||
void gb_dma_update(GBDMA *dma, RIO *io, ut32 cycles, bool pre_exec);
|
void gb_dma_continue(GBDMA *dma, RIO *io, ut32 cycles, bool pre_exec);
|
||||||
void gb_dma_close(GBDMA *dma, RIO *io);
|
void gb_dma_close(GBDMA *dma, RIO *io);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -121,6 +121,8 @@ typedef struct pixel_fifo_fetcher_t {
|
||||||
#define GB_PIXEL_FIFO_FETCH_OBJECT 0x10
|
#define GB_PIXEL_FIFO_FETCH_OBJECT 0x10
|
||||||
#define GB_PIXEL_FIFO_FETCH_WINDOW 0x20
|
#define GB_PIXEL_FIFO_FETCH_WINDOW 0x20
|
||||||
#define GB_PIXEL_FIFO_FETCH_READY 0x40
|
#define GB_PIXEL_FIFO_FETCH_READY 0x40
|
||||||
|
//specifies if scx & 0x7 and wy are copied into fifo
|
||||||
|
#define GB_PIXEL_FIFO_REG_DATA_LOADED 0x80
|
||||||
|
|
||||||
#define GB_OAM_PALLET 0x10
|
#define GB_OAM_PALLET 0x10
|
||||||
#define GB_OAM_FLIP_X 0x20
|
#define GB_OAM_FLIP_X 0x20
|
||||||
|
@ -132,6 +134,7 @@ typedef struct pixel_fifo_fetcher_t {
|
||||||
#define GB_FIFO_OAM_FLIP_Y (GB_OAM_FLIP_Y << 24)
|
#define GB_FIFO_OAM_FLIP_Y (GB_OAM_FLIP_Y << 24)
|
||||||
#define GB_FIFO_OAM_PRIORITY (GB_OAM_PRIORITY << 24)
|
#define GB_FIFO_OAM_PRIORITY (GB_OAM_PRIORITY << 24)
|
||||||
|
|
||||||
|
|
||||||
typedef struct pixel_fifo_t {
|
typedef struct pixel_fifo_t {
|
||||||
ut64 data;
|
ut64 data;
|
||||||
PixelFifoFetcher fetcher[2];
|
PixelFifoFetcher fetcher[2];
|
||||||
|
@ -149,8 +152,9 @@ obj p1 - 11
|
||||||
ut8 flags;
|
ut8 flags;
|
||||||
};
|
};
|
||||||
ut8 n_fpixel; //number of pixel that are currently in the fifo
|
ut8 n_fpixel; //number of pixel that are currently in the fifo
|
||||||
ut8 wy;
|
|
||||||
ut8 x;
|
ut8 x;
|
||||||
|
ut8 wy;
|
||||||
|
ut8 dx; //discard x
|
||||||
} PixelFifo;
|
} PixelFifo;
|
||||||
|
|
||||||
typedef struct gb_dmg_ppu_t {
|
typedef struct gb_dmg_ppu_t {
|
||||||
|
@ -178,7 +182,7 @@ typedef struct gameboy_t {
|
||||||
} GB;
|
} GB;
|
||||||
|
|
||||||
GBPPU *gb_ppu_open (RIO *io, SDL_Renderer *renderer);
|
GBPPU *gb_ppu_open (RIO *io, SDL_Renderer *renderer);
|
||||||
void gb_ppu_update (GB *gb, ut32 cycles);
|
void gb_ppu_continue (GB *gb, ut32 cycles);
|
||||||
void gb_ppu_close (GBPPU *ppu, RIO *io);
|
void gb_ppu_close (GBPPU *ppu, RIO *io);
|
||||||
|
|
||||||
extern RIOPlugin r_io_plugin_gb_timers;
|
extern RIOPlugin r_io_plugin_gb_timers;
|
||||||
|
|
2
io/dma.c
2
io/dma.c
|
@ -221,7 +221,7 @@ GBDMA *gb_dma_open (RIO *io) {
|
||||||
return dma;
|
return dma;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gb_dma_update (GBDMA *dma, RIO *io, ut32 cycles, bool pre_exec) {
|
void gb_dma_continue (GBDMA *dma, RIO *io, ut32 cycles, bool pre_exec) {
|
||||||
if (!(dma->seek & GB_DMA_ACTIVE)) {
|
if (!(dma->seek & GB_DMA_ACTIVE)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ GBJoypad *gb_joypad_open (RIO *io) {
|
||||||
return joypad;
|
return joypad;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gb_joypad_update(GBJoypad *joypad) {
|
void gb_joypad_continue(GBJoypad *joypad) {
|
||||||
joypad->odata &= 0xc0;
|
joypad->odata &= 0xc0;
|
||||||
joypad->odata |= joypad->data & 0x3f;
|
joypad->odata |= joypad->data & 0x3f;
|
||||||
SDL_PumpEvents ();
|
SDL_PumpEvents ();
|
||||||
|
|
60
io/ppu.c
60
io/ppu.c
|
@ -124,7 +124,7 @@ GBPPU *gb_ppu_open (RIO *io, SDL_Renderer *renderer) {
|
||||||
return ppu;
|
return ppu;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ut32 gb_ppu_oam_scan_update (GB *gb, ut32 cycles) {
|
static ut32 gb_ppu_oam_scan_continue (GB *gb, ut32 cycles) {
|
||||||
if (gb->ppu->ost.addr >= 0xa0) {
|
if (gb->ppu->ost.addr >= 0xa0) {
|
||||||
gb->ppu->ost.addr = 0;
|
gb->ppu->ost.addr = 0;
|
||||||
gb->ppu->ost.n_entries = 0;
|
gb->ppu->ost.n_entries = 0;
|
||||||
|
@ -279,6 +279,9 @@ static void gb_pixel_fifo_fetch_continue (GB *gb) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 5:
|
case 5:
|
||||||
|
if (!fetch_obj) {
|
||||||
|
fifo->flags |= GB_PIXEL_FIFO_FETCH_READY;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
if (fetch_obj) {
|
if (fetch_obj) {
|
||||||
|
@ -311,37 +314,74 @@ static void gb_pixel_fifo_fetch_continue (GB *gb) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
fifo->flags |= GB_PIXEL_FIFO_FETCH_READY;
|
if (fetch_obj) {
|
||||||
|
fifo->flags |= GB_PIXEL_FIFO_FETCH_READY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fifo->fetcher[fetch_obj].state_ctr = (fifo->fetcher[fetch_obj].state_ctr + 1) & 0x7;
|
fifo->fetcher[fetch_obj].state_ctr = (fifo->fetcher[fetch_obj].state_ctr + 1) & 0x7;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ut32 gb_ppu_render_update (GB *gb, ut32 cycles) {
|
static void gb_ppu_render_launch (GB *gb) {
|
||||||
|
RIOMap *vram = r_io_map_get (gb->io, gb->ppu->vram_mapid);
|
||||||
|
vram->perm = 0; //disable vram access for rendering
|
||||||
|
gb->ppu->fifo = (const PixelFifo){0};
|
||||||
|
gb->ppu->fifo.remaining_cycles = 376;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ut32 gb_ppu_render_continue (GB *gb, ut32 cycles) {
|
||||||
|
PixelFifo *fifo = &gb->ppu->fifo;
|
||||||
|
if (R_UNLIKELY (!(fifo->flags & GB_PIXEL_FIFO_REG_DATA_LOADED))) {
|
||||||
|
fifo->dx = gb->ppu->buf[GB_PPU_SCX] & 0x7;
|
||||||
|
fifo->wy = gb->ppu->buf[GB_PPU_WY];
|
||||||
|
fifo->flags |= GB_PIXEL_FIFO_REG_DATA_LOADED;
|
||||||
|
}
|
||||||
|
while (cycles) {
|
||||||
|
if (fifo->n_fpixel < 9) {
|
||||||
|
gb_pixel_fifo_fetch_continue (gb);
|
||||||
|
if (fifo->flags & GB_PIXEL_FIFO_FETCH_READY) {
|
||||||
|
if (!fifo->n_fpixel) {
|
||||||
|
fifo->data = ((ut64)fifo->fetcher[0].fetched) << 32;
|
||||||
|
} else {
|
||||||
|
fifo->data |= fifo->fetcher[0].fetched;
|
||||||
|
}
|
||||||
|
fifo->n_fpixel += 8;
|
||||||
|
//I suspect the initial 16 pixels fetch on each line only takes 12 cycles instead of 16,
|
||||||
|
//because the pixel fifo is empty
|
||||||
|
fifo->flags ^= GB_PIXEL_FIFO_FETCH_READY;
|
||||||
|
fifo->fetcher[0].state_ctr = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fifo->remaining_cycles--;
|
||||||
|
cycles--;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ut32 gb_ppu_hblank_update (GB *gb, ut32 cycles) {
|
static ut32 gb_ppu_hblank_continue (GB *gb, ut32 cycles) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ut32 gb_ppu_vblank_update (GB *gb, ut32 cycles) {
|
static ut32 gb_ppu_vblank_continue (GB *gb, ut32 cycles) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gb_ppu_update (GB *gb, ut32 cycles) {
|
void gb_ppu_continue (GB *gb, ut32 cycles) {
|
||||||
while (cycles) {
|
while (cycles) {
|
||||||
switch (gb->ppu->buf[GB_PPU_STAT] & GB_PPU_STAT_MODE_MASK) {
|
switch (gb->ppu->buf[GB_PPU_STAT] & GB_PPU_STAT_MODE_MASK) {
|
||||||
case GB_PPU_STAT_MODE_OAM_SCAN:
|
case GB_PPU_STAT_MODE_OAM_SCAN:
|
||||||
cycles = gb_ppu_oam_scan_update (gb, cycles);
|
cycles = gb_ppu_oam_scan_continue (gb, cycles);
|
||||||
|
if ((gb->ppu->buf[GB_PPU_STAT] & GB_PPU_STAT_MODE_MASK) == GB_PPU_STAT_MODE_RENDER) {
|
||||||
|
gb_ppu_render_launch (gb);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GB_PPU_STAT_MODE_RENDER:
|
case GB_PPU_STAT_MODE_RENDER:
|
||||||
cycles = gb_ppu_render_update (gb, cycles);
|
cycles = gb_ppu_render_continue (gb, cycles);
|
||||||
break;
|
break;
|
||||||
case GB_PPU_STAT_MODE_HBLANK:
|
case GB_PPU_STAT_MODE_HBLANK:
|
||||||
cycles = gb_ppu_hblank_update (gb, cycles);
|
cycles = gb_ppu_hblank_continue (gb, cycles);
|
||||||
break;
|
break;
|
||||||
case GB_PPU_STAT_MODE_VBLANK:
|
case GB_PPU_STAT_MODE_VBLANK:
|
||||||
cycles = gb_ppu_vblank_update (gb, cycles);
|
cycles = gb_ppu_vblank_continue (gb, cycles);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ void gb_timers_close (GBTimers *timers, RIO *io) {
|
||||||
free (timers);
|
free (timers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gb_timers_update (GBTimers *timers, ut32 cycles) {
|
void gb_timers_continue (GBTimers *timers, ut32 cycles) {
|
||||||
bool request_interrupt = false;
|
bool request_interrupt = false;
|
||||||
do {
|
do {
|
||||||
//ensure all falling edges are detected
|
//ensure all falling edges are detected
|
||||||
|
|
Loading…
Reference in New Issue
Block a user