aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c12
-rw-r--r--src/ppu/consts.h6
-rw-r--r--src/ppu/internals.c29
-rw-r--r--src/ppu/internals.h10
-rw-r--r--src/ppu/stm.c15
-rw-r--r--src/ppusim/mem.c14
-rw-r--r--src/stm32/main.c6
7 files changed, 67 insertions, 25 deletions
diff --git a/src/main.c b/src/main.c
index bbb6001..658fc94 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
+ }
}