diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 12 | ||||
-rw-r--r-- | src/ppu/consts.h | 6 | ||||
-rw-r--r-- | src/ppu/internals.c | 29 | ||||
-rw-r--r-- | src/ppu/internals.h | 10 | ||||
-rw-r--r-- | src/ppu/stm.c | 15 | ||||
-rw-r--r-- | src/ppusim/mem.c | 14 | ||||
-rw-r--r-- | src/stm32/main.c | 6 |
7 files changed, 67 insertions, 25 deletions
@@ -6,12 +6,14 @@ bool g_hh_run = true; +bool g_hh_test_complete = false; + void hh_ppu_vblank_interrupt() { - for (unsigned long i = 0; i < HH_PPUINTDEMO_LENGTH; i++) { - uint16_t addr = HH_PPUINTDEMO_ADDR[i]; - uint16_t data = HH_PPUINTDEMO_DATA[i]; - hh_ppu_vram_dwrite(addr, data); - } +#ifdef HH_TARGET_DESKTOP + if (g_hh_test_complete) return; +#endif + hh_ppu_vram_dwrite((uint8_t*) HH_PPUINTDEMO_ARR, HH_PPUINTDEMO_LENGTH); + g_hh_test_complete = true; } int main() { diff --git a/src/ppu/consts.h b/src/ppu/consts.h index a27b7b7..917510f 100644 --- a/src/ppu/consts.h +++ b/src/ppu/consts.h @@ -23,6 +23,12 @@ /** @brief amount of vertical background tiles on background canvas */ #define HH_PPU_BG_CANVAS_TILES_V 30 +/** @brief amount of bytes in command (16 + 16 bits) */ +#define HH_PPU_COMMAND_BYTES 4 +/** @brief command buffer size (large enough to update entire screen + all fg sprites + aux + all palettes) */ +#define HH_PPU_COMMAND_BUFFER_SIZE (HH_PPU_COMMAND_BYTES * \ + (HH_PPU_VRAM_FAM_SIZE + HH_PPU_VRAM_BAM_SIZE + HH_PPU_VRAM_AUX_SIZE + HH_PPU_VRAM_PAL_SIZE)) + #include "ppu/types.h" /** @brief tilemap memory address offset */ diff --git a/src/ppu/internals.c b/src/ppu/internals.c index 66c0ac1..a60cb68 100644 --- a/src/ppu/internals.c +++ b/src/ppu/internals.c @@ -4,6 +4,9 @@ #include "ppu/internals.h" #include "ppu/types.h" +uint8_t g_hh_ppu_vram_buffer[HH_PPU_COMMAND_BUFFER_SIZE] = { 0 }; +size_t g_hh_ppu_vram_buffer_head = 0; + bool hh_ppu_vram_valid_address(hh_ppu_addr_t addr) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wtype-limits" @@ -17,7 +20,16 @@ bool hh_ppu_vram_valid_address(hh_ppu_addr_t addr) { } void hh_ppu_vram_write(hh_s_ppu_vram_data data) { - for (unsigned i = 0; i < data.size; i++) hh_ppu_vram_dwrite(data.offset + i, data.data[i]); + for (unsigned i = 0; i < data.size; i++) { + hh_ppu_addr_t ppu_addr = data.offset + i; + hh_ppu_data_t ppu_data = data.data[i]; + hh_ppu_vram_buffer((uint8_t[4]) { + (ppu_addr >> 8) & 0xff, + (ppu_addr >> 0) & 0xff, + (ppu_data >> 8) & 0xff, + (ppu_data >> 0) & 0xff, + }); + } } hh_s_ppu_vram_data hh_ppu_2nat_bam(hh_s_ppu_loc_bam_entry e) { @@ -73,3 +85,18 @@ hh_s_ppu_vram_data hh_ppu_2nat_color(hh_ppu_rgb_color_t rgb) { hh_s_ppu_vram_data out = {.data = data, .size = HH_PPU_VRAM_PAL_ENTRY_SIZE}; return out; } + +void hh_ppu_vram_buffer(uint8_t data[4]) { + size_t head = g_hh_ppu_vram_buffer_head; + g_hh_ppu_vram_buffer[head+0] = data[0]; + g_hh_ppu_vram_buffer[head+1] = data[1]; + g_hh_ppu_vram_buffer[head+2] = data[2]; + g_hh_ppu_vram_buffer[head+3] = data[3]; + g_hh_ppu_vram_buffer_head += 4; +} + +void hh_ppu_vram_flush() { + hh_ppu_vram_dwrite(g_hh_ppu_vram_buffer, g_hh_ppu_vram_buffer_head); + g_hh_ppu_vram_buffer_head = 0; +} + diff --git a/src/ppu/internals.h b/src/ppu/internals.h index 4a1726e..12c556e 100644 --- a/src/ppu/internals.h +++ b/src/ppu/internals.h @@ -1,6 +1,7 @@ #pragma once #include <stdbool.h> +#include <stdlib.h> #include "ppu/types.h" @@ -18,11 +19,16 @@ typedef struct { /** @brief check if `addr` is a valid PPU address */ bool hh_ppu_vram_valid_address(hh_ppu_addr_t addr); -/** @brief direct write vram word (platform-specific implementation) */ -void hh_ppu_vram_dwrite(hh_ppu_addr_t addr, hh_ppu_data_t data); /** @brief write data block into vram */ void hh_ppu_vram_write(hh_s_ppu_vram_data data); +/** @brief add raw SPI data to ppu command buffer */ +void hh_ppu_vram_buffer(uint8_t data[4]); +/** @brief propagate command buffer (also handles SPI reset) */ +void hh_ppu_vram_flush(); +/** @brief write raw spi bytes in ppu format */ +void hh_ppu_vram_dwrite(uint8_t* data, size_t size); + /** @brief convert local background attribute memory entry to PPU format */ hh_s_ppu_vram_data hh_ppu_2nat_bam(hh_s_ppu_loc_bam_entry); /** @brief convert local foreground attribute memory entry to PPU format */ diff --git a/src/ppu/stm.c b/src/ppu/stm.c index 371e557..18811cf 100644 --- a/src/ppu/stm.c +++ b/src/ppu/stm.c @@ -7,17 +7,10 @@ void hh_ppu_init() {} void hh_ppu_deinit() {} -void hh_ppu_vram_dwrite(hh_ppu_addr_t addr, hh_ppu_data_t data) { - // if (!hh_ppu_vram_valid_address(addr)) return; - - uint8_t spi_data[4] = { - (addr & 0xff00) >> 8, - (addr & 0x00ff) >> 0, - (data & 0xff00) >> 8, - (data & 0x00ff) >> 0, - }; - - HAL_SPI_Transmit(&hspi1, spi_data, 4, HAL_MAX_DELAY); +void hh_ppu_vram_dwrite(uint8_t* data, size_t size) { + HAL_SPI_Transmit(&hspi1, data, size, HAL_MAX_DELAY); + HAL_SPI_Transmit(&hspi1, (uint8_t[4]) { 0xff, 0xff, 0xff, 0xff }, 4, HAL_MAX_DELAY); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, true); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, false); } + diff --git a/src/ppusim/mem.c b/src/ppusim/mem.c index bd8606e..f536727 100644 --- a/src/ppusim/mem.c +++ b/src/ppusim/mem.c @@ -6,8 +6,14 @@ hh_ppu_data_t *g_hh_ppusim_vram = NULL; -void hh_ppu_vram_dwrite(hh_ppu_addr_t addr, hh_ppu_data_t data) { - if (!hh_ppu_vram_valid_address(addr)) return; - // printf("ppu[0x%04x] = %04x\n", addr, data); - g_hh_ppusim_vram[addr] = data; +void hh_ppu_vram_dwrite(uint8_t* data, size_t size) { + for (size_t i = 0; i < size; i += 4) { + if (i+4 > size) break; + hh_ppu_addr_t ppu_addr = (data[i+0] << 8) | (data[i+1] << 0); + hh_ppu_data_t ppu_data = (data[i+2] << 8) | (data[i+3] << 0); + // printf("%04x: %04x\n", ppu_addr, ppu_data); + if (!hh_ppu_vram_valid_address(ppu_addr)) continue; + g_hh_ppusim_vram[ppu_addr] = ppu_data; + } } + diff --git a/src/stm32/main.c b/src/stm32/main.c index 84288c3..d815154 100644 --- a/src/stm32/main.c +++ b/src/stm32/main.c @@ -6,6 +6,8 @@ void hh_ppu_load_tilemap() {} void hh_loop() { - HAL_Delay(1e3); - hh_ppu_vblank_interrupt(); + while (1) { + hh_ppu_vblank_interrupt(); + HAL_Delay(1e3); + } } |