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