diff --git a/src/ppu.c b/src/ppu.c index 602527d..8aeca32 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -34,7 +34,6 @@ void create_event_tables_ppu(ppu_t *ppu) { ppu->render_events[dot][i] = PPU_EVENT_IDLE; ppu->prerender_events[dot][i] = PPU_EVENT_IDLE; ppu->vblank_events[dot][i] = PPU_EVENT_IDLE; - ppu->visible_events[dot][i] = PPU_EVENT_IDLE; } // Skip the first cycle of every scanline @@ -96,6 +95,12 @@ void create_event_tables_ppu(ppu_t *ppu) { if (dot >= 257 && dot <= 320) { ppu->render_events[dot][i++] = PPU_EVENT_CLEAR_OAMADDR; } + if (dot <= 64) { + ppu->render_events[dot][i++] = PPU_EVENT_CLEAR_OAM; + } + if (dot >= 65 && dot <= 256) { + ppu->render_events[dot][i++] = PPU_EVENT_EVALUATE_SPRITES; + } } } @@ -373,6 +378,32 @@ void set_vblank_ppu(ppu_t *ppu) { } } +void clear_oam_ppu(ppu_t *ppu) { + // Clear the OAM +} + +void evaluate_sprites_ppu(ppu_t *ppu) { + // Implement sprite evaluation +} + +void fetch_sprite_pattern_lo_ppu(ppu_t *ppu) { + // bool bg_ctrl = ppu->ctrl & PPU_CTRL_PATTERN_TABLE_BG; + // address_t pt_base = bg_ctrl * 0x1000; + // address_t fine_y = (ppu->v >> 12) & 0x7; + // address_t pt_offset = (ppu->nt_latch << 4) | fine_y; + // address_t pt_address = pt_base + pt_offset; + // ppu->pt_latches[0] = read_ppu_bus(ppu->bus, pt_address); +} + +void fetch_sprite_pattern_hi_ppu(ppu_t *ppu) { + // bool bg_ctrl = ppu->ctrl & PPU_CTRL_PATTERN_TABLE_BG; + // address_t pt_base = bg_ctrl * 0x1000; + // address_t fine_y = (ppu->v >> 12) & 0x7; + // address_t pt_offset = (ppu->nt_latch << 4) | fine_y; + // address_t pt_address = pt_base + pt_offset + 8; + // ppu->pt_latches[1] = read_ppu_bus(ppu->bus, pt_address); +} + void draw_dot_ppu(ppu_t *ppu) { unsigned short x_mask = 0x8000 >> ppu->x; @@ -470,6 +501,18 @@ void execute_events_ppu(ppu_t *ppu, ppu_event_t *events) { case PPU_EVENT_SET_VBLANK: set_vblank_ppu(ppu); break; + case PPU_EVENT_CLEAR_OAM: + clear_oam_ppu(ppu); + break; + case PPU_EVENT_EVALUATE_SPRITES: + evaluate_sprites_ppu(ppu); + break; + case PPU_EVENT_FETCH_PATTERN_SPRITE_LO: + fetch_sprite_pattern_lo_ppu(ppu); + break; + case PPU_EVENT_FETCH_PATTERN_SPRITE_HI: + fetch_sprite_pattern_hi_ppu(ppu); + break; case PPU_EVENT_IDLE: break; } diff --git a/src/ppu.h b/src/ppu.h index 3e6898b..041e08d 100644 --- a/src/ppu.h +++ b/src/ppu.h @@ -54,6 +54,8 @@ typedef enum { PPU_EVENT_FETCH_ATTRIBUTE, PPU_EVENT_FETCH_PATTERN_LO, PPU_EVENT_FETCH_PATTERN_HI, + PPU_EVENT_FETCH_PATTERN_SPRITE_LO, + PPU_EVENT_FETCH_PATTERN_SPRITE_HI, PPU_EVENT_SHIFT_REGISTERS, PPU_EVENT_RELOAD_SHIFTERS, PPU_EVENT_COPY_X, @@ -64,6 +66,8 @@ typedef enum { PPU_EVENT_CLEAR_FLAGS, PPU_EVENT_SET_VBLANK, PPU_EVENT_SKIP_CYCLE, + PPU_EVENT_CLEAR_OAM, + PPU_EVENT_EVALUATE_SPRITES, } ppu_event_t; typedef struct { @@ -135,6 +139,18 @@ typedef struct { */ unsigned char pt_latches[2]; + /** + * @brief Palette attribute latches for up to 8 sprites. + * + */ + unsigned char sprite_latches[8]; + + /** + * @brief X-positions for up to 8 sprites. + * + */ + unsigned char sprite_counters[8]; + /** * @brief Pattern table shift registers. The high 8 bits are the current * tile. Every 8 cycles, new data is loaded into the low 8 bits of the @@ -151,6 +167,12 @@ typedef struct { */ unsigned short pa_shift[2]; + /** + * @brief Pattern table shift registers for up to 8 sprites. + * + */ + unsigned short sprite_shift[16]; + /** * @brief Primary object attribute memory. * @@ -181,6 +203,12 @@ typedef struct { */ unsigned char io_databus; + /** + * @brief Buffer for reading from OAM. + * + */ + unsigned char buffer_oam; + /** * @brief Toggle to suppress setting VBlank. * @@ -235,12 +263,6 @@ typedef struct { */ interrupt_t *interrupt; - /** - * @brief Events in the visible scanlines. - * - */ - ppu_event_t visible_events[PPU_LINEDOTS][PPU_EVENTS_PER_DOT]; - /** * @brief Events in the render and pre-render scanlines. *