Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion components/gbc/gnuboy/src/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,17 @@ void rtc_load()
void loader_unload()
{
sram_save();
// Free the cart SRAM allocated in rom_load(). Previously this static buffer
// was never freed, leaking ~ramsize KB of PSRAM and fragmenting it across
// cart switches; it was also reused as-is on the next ROM via the
// `if (!sram_ptr)` guard, so a larger-ramsize cart would overflow it.
// Freeing (and NULLing) here makes each ROM reallocate at its own size.
if (sram_ptr) {
heap_caps_free(sram_ptr);
sram_ptr = NULL;
}
ram.sbank = NULL;
// rom.bank = NULL;
// ram.sbank = NULL;
mbc.type = mbc.romsize = mbc.ramsize = mbc.batt = 0;
}

Expand Down
9 changes: 9 additions & 0 deletions components/gbc/include/gbc_shared_memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
#include <cstdint>
#include <cstddef>

// Game Boy (Color) audio sizing. The shared PCM buffer allocation (in
// gbc_shared_memory.cpp) and pcm.len (in gameboy.cpp) BOTH derive from these,
// so they cannot diverge: if pcm.len implies a larger buffer than is allocated,
// the gnuboy sound mixer overruns it and corrupts the heap.
#define GAMEBOY_AUDIO_SAMPLE_RATE 32768
// Size (in bytes) of the shared PCM buffer: ~1/5 second of stereo (2ch),
// 16-bit (2 byte) audio. pcm.len = GBC_AUDIO_BUFFER_SIZE / sizeof(int16_t).
#define GBC_AUDIO_BUFFER_SIZE (GAMEBOY_AUDIO_SAMPLE_RATE * 2 * 2 / 5)

#ifdef __cplusplus
extern "C" {
#endif
Expand Down
5 changes: 3 additions & 2 deletions components/gbc/src/gameboy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

static const size_t GAMEBOY_SCREEN_WIDTH = 160;
static const size_t GAMEBOY_SCREEN_HEIGHT = 144;
static const int GAMEBOY_AUDIO_SAMPLE_RATE = 32768;
// GAMEBOY_AUDIO_SAMPLE_RATE / GBC_AUDIO_BUFFER_SIZE come from gbc_shared_memory.hpp

extern "C" {
#include <gnuboy/loader.h>
Expand Down Expand Up @@ -116,7 +116,8 @@ void init_gameboy(const std::string& rom_filename, uint8_t *romdata, size_t rom_
lcd->vbank = vram;
ram.ibank = wram;
pcm.buf = reinterpret_cast<int16_t*>(audio);
static constexpr int GBC_AUDIO_BUFFER_SIZE = GAMEBOY_AUDIO_SAMPLE_RATE * 2 * 2 / 5; // TODO: 5 is a hack to make it work
// GBC_AUDIO_BUFFER_SIZE (bytes) is the size actually allocated for pcm.buf in
// gbc_shared_memory.cpp, so pcm.len matches the buffer exactly.
pcm.len = GBC_AUDIO_BUFFER_SIZE / sizeof(int16_t);

// set native size
Expand Down
3 changes: 2 additions & 1 deletion components/gbc/src/gbc_shared_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ extern "C" {
// GBC memory sizes
#define GBC_VRAM_SIZE (16 * 1024) // 16KB VRAM
#define GBC_WRAM_SIZE (32 * 1024) // 32KB WRAM
#define GBC_AUDIO_BUFFER_SIZE (2048 * sizeof(int16_t)) // 2048 samples at 16-bit per sample
// GBC_AUDIO_BUFFER_SIZE comes from gbc_shared_memory.hpp so the allocation here
// always matches pcm.len in gameboy.cpp (a mismatch overruns the PCM buffer).

// Static pointers to shared memory regions
static uint8_t* vram_ptr = nullptr;
Expand Down
Loading