From 57337ab9d101f2276b8bb1d4595e45e57e1e2915 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Sun, 23 Feb 2025 13:21:12 +0000 Subject: [PATCH 1/6] pico: sync stdio_usb changes to loader --- 32blit-pico/loader/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/32blit-pico/loader/CMakeLists.txt b/32blit-pico/loader/CMakeLists.txt index 00197c234..473abdc17 100644 --- a/32blit-pico/loader/CMakeLists.txt +++ b/32blit-pico/loader/CMakeLists.txt @@ -10,7 +10,10 @@ else() endif() pico_enable_stdio_uart(blit-loader 1) -pico_enable_stdio_usb(blit-loader 0) +if(NOT BLIT_USB_DRIVER STREQUAL "host") + pico_enable_stdio_usb(blit-loader 1) + target_compile_definitions(blit-loader PRIVATE PICO_STDIO_USB_ENABLE_RESET_VIA_BAUD_RATE=1 PICO_STDIO_USB_RESET_MAGIC_BAUD_RATE=1200 PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK=0) +endif() pico_add_extra_outputs(blit-loader) From 7c59c5ef509a7d03d18a724a7734bec6f8bda739 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Wed, 4 Mar 2026 16:07:09 +0000 Subject: [PATCH 2/6] pico: prioritise loading a launcher over whatever thing is found first Now it's possible to restore the launcher from storage if it is lost, but there are still other things installed --- 32blit-pico/loader/loader.cpp | 60 ++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/32blit-pico/loader/loader.cpp b/32blit-pico/loader/loader.cpp index a8703ab0b..f0c80a063 100644 --- a/32blit-pico/loader/loader.cpp +++ b/32blit-pico/loader/loader.cpp @@ -1,26 +1,76 @@ +#include + #include "32blit.hpp" #include "engine/api_private.hpp" +#include "executable.hpp" + using namespace blit; -void init() { +const char *get_category(const uint8_t *ptr) { + // check headers + auto header = (const BlitGameHeader *)ptr; + + if(header->magic != blit_game_magic) + return nullptr; + + auto metadata_ptr = ptr + header->end; + + if(memcmp(metadata_ptr, "BLITMETA", 8) != 0) + return nullptr; + + // skip straight to the type block + metadata_ptr += 10 + sizeof(RawMetadata); + + if(memcmp(metadata_ptr, "BLITTYPE", 8) != 0) + return nullptr; + + // get the category from the type block + auto type_meta = (const RawTypeMetadata *)(metadata_ptr + 8); + + return type_meta->category; +} + +static bool try_launch(bool launcher) { bool done = false; - // launch the first thing we find - // TODO: find launcher - api.list_installed_games([&done](const uint8_t *ptr, uint32_t block, uint32_t size){ + + api.list_installed_games([&done, launcher](const uint8_t *ptr, uint32_t block, uint32_t size){ if(!done) { + + if(launcher) { + // check category + auto category = get_category(ptr); + + if(!category || strcmp(category, "launcher") != 0) + return; + } + auto path = "flash:/" + std::to_string(block) + ".blit"; done = api.launch(path.c_str()); } }); + return done; +} + +void init() { + bool done = false; + + // try to find and launch a launcher + done = try_launch(true); + if(!done) { // fall back to launcher in storage // TODO: auto-update if(file_exists("launcher.blit")) { - api.launch("launcher.blit"); + done = api.launch("launcher.blit"); } } + + if(!done) { + // as a last resort launch the first thing we find + try_launch(false); + } } void render(uint32_t time) { From 85bfce9ecb8c6b3c83c9fe2ef61edb16950b76f0 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Sun, 8 Mar 2026 12:59:27 +0000 Subject: [PATCH 3/6] pico: clear progress message on PROG/SAVE write error --- 32blit-pico/usb.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/32blit-pico/usb.cpp b/32blit-pico/usb.cpp index 12057373f..c5aa42047 100644 --- a/32blit-pico/usb.cpp +++ b/32blit-pico/usb.cpp @@ -150,8 +150,10 @@ class CDCProgCommand final : public CDCCommand { // got full page or final part of file auto buf_off = buf.get_offset(); if(buf_off == FLASH_PAGE_SIZE || buf_off == writer.get_remaining()) { - if(!writer.write(buf.get_data(), buf_off)) + if(!writer.write(buf.get_data(), buf_off)) { + cdc_command_progress(nullptr, 0, 0); // clear progress return Status::Error; + } cdc_command_progress(nullptr, writer.get_offset(), writer.get_length()); @@ -257,6 +259,7 @@ class CDCSaveCommand final : public CDCCommand { auto written = blit::api.write_file(file, file_offset, read, (const char *)buf.get_data()); if(written != read) { blit::api.close_file(file); + cdc_command_progress(nullptr, 0, 0); // clear progress return Status::Error; } From acc8c640e3ee73c64a82795c4394fa15c796587f Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Sun, 8 Mar 2026 13:00:39 +0000 Subject: [PATCH 4/6] pico: fail prepare_write if there isn't enough space Instead of erasing the loader, launcher and whaterver is after that --- 32blit-pico/blit_launch.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/32blit-pico/blit_launch.cpp b/32blit-pico/blit_launch.cpp index 9f6d2bdca..64e37c89e 100644 --- a/32blit-pico/blit_launch.cpp +++ b/32blit-pico/blit_launch.cpp @@ -489,6 +489,11 @@ bool BlitWriter::prepare_write(const uint8_t *buf) { // we can use address translation for this, so flash in any free space flash_offset = find_flash_offset(file_len); } + + if(!flash_offset) { + blit::debugf("Not enough space!"); + return false; + } #endif disable_user_code(); From a7f795bb39b4085290682e448e75d2473e4701b0 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Sun, 8 Mar 2026 15:10:05 +0000 Subject: [PATCH 5/6] pico: don't pass type meta to cleanup_duplicates It doesn't need it --- 32blit-pico/blit_launch.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/32blit-pico/blit_launch.cpp b/32blit-pico/blit_launch.cpp index 64e37c89e..ccda4e0c2 100644 --- a/32blit-pico/blit_launch.cpp +++ b/32blit-pico/blit_launch.cpp @@ -163,7 +163,7 @@ static uint32_t find_installed_blit(RawMetadata &meta) { return ~0u; } -static bool cleanup_duplicates(RawMetadata &meta, RawTypeMetadata &type_meta, uint32_t new_offset) { +static bool cleanup_duplicates(RawMetadata &meta, uint32_t new_offset) { bool ret = false; for(uint32_t off = 0; off < flash_end;) { auto size = get_installed_file_size(off); @@ -261,7 +261,7 @@ bool launch_file(const char *path) { flash_offset = writer.get_flash_offset(); - cleanup_duplicates(meta, type_meta, flash_offset); + cleanup_duplicates(meta, flash_offset); } else close_file(file); } From dbc48298bf87606a4d52adb8c659b25cbe820c97 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Sun, 8 Mar 2026 15:32:09 +0000 Subject: [PATCH 6/6] pico: cleanup duplicates when doing PROG command --- 32blit-pico/blit_launch.cpp | 6 ++++++ 32blit-pico/blit_launch.hpp | 2 ++ 32blit-pico/usb.cpp | 2 ++ 3 files changed, 10 insertions(+) diff --git a/32blit-pico/blit_launch.cpp b/32blit-pico/blit_launch.cpp index ccda4e0c2..590b31c66 100644 --- a/32blit-pico/blit_launch.cpp +++ b/32blit-pico/blit_launch.cpp @@ -456,6 +456,12 @@ bool BlitWriter::write(const uint8_t *buf, uint32_t len) { return true; } +void BlitWriter::cleanup_duplicates() { + auto header = (BlitGameHeader *)(FLASH_BASE + flash_offset); + auto meta = (RawMetadata *)(FLASH_BASE + flash_offset + header->end + 10); + ::cleanup_duplicates(*meta, flash_offset); +} + uint32_t BlitWriter::get_offset() const { return file_offset; } diff --git a/32blit-pico/blit_launch.hpp b/32blit-pico/blit_launch.hpp index 7933e3544..69c203fbc 100644 --- a/32blit-pico/blit_launch.hpp +++ b/32blit-pico/blit_launch.hpp @@ -25,6 +25,8 @@ class BlitWriter final { bool write(const uint8_t *buf, uint32_t len); + void cleanup_duplicates(); + uint32_t get_offset() const; uint32_t get_length() const; uint32_t get_remaining() const; diff --git a/32blit-pico/usb.cpp b/32blit-pico/usb.cpp index c5aa42047..d8233742e 100644 --- a/32blit-pico/usb.cpp +++ b/32blit-pico/usb.cpp @@ -164,6 +164,8 @@ class CDCProgCommand final : public CDCCommand { if(writer.get_remaining() == 0) { cdc_command_progress(nullptr, 0, 0); // clear progress + writer.cleanup_duplicates(); + // send response auto block = writer.get_flash_offset() >> 16; uint8_t res_data[]{'3', '2', 'B', 'L', '_', '_', 'O', 'K', uint8_t(block), uint8_t(block >> 8)};