Advanced Troubleshooting & Limits
This guide covers advanced topics that you might encounter as your projects grow in complexity. Here, you’ll find solutions to common limitations and techniques to push what’s possible on the Classpad. As new techniques are discovered, they will be added here, so be sure to check it regularly. If you encounter some issue that isn’t yet known or listed here, feel free to 💬 Join our Discord community or report it as issue in our GitHub bug tracker.
Overcoming the 64kb App Size Limit
Section titled “Overcoming the 64kb App Size Limit”As your application grows, you might run into a strict 64 kilobyte (kb) size limit for your compiled ELF binary that prevent it loading properly. This is a fundamental constraint of the standard memory space allocated for applications.
Issue description
Section titled “Issue description”When your application’s compiled code exceeds 64kb, the calculator’s loader cannot place it in the default memory region. This typically results in your app crashing or freezing immediately upon launch, without any clear error message. The standard memory space allocated for an app is simply not large enough for bigger projects.
Solution: Using VBAK Memory
Section titled “Solution: Using VBAK Memory”To bypass the 64kb limit, you can instruct the linker to place your application’s code in a larger memory area known as vbak or vram. These regions, normally used for system operations like video memory backup, each offer approximately 330kb of space.
To do this, you need to add a specific linker flag to your project’s Makefile.
- Open your
Makefile. - Locate the
LD_FLAGSvariable. - Add the following flag:
-Wl,-Ttext-segment,0x8C052800
Your LD_FLAGS line should look something like this:
LD_FLAGS = -Wl,-Ttext-segment,0x8C052800This flag tells the YAL (HH3/v3) loader to place the executable code segment at the memory address 0x8C052800, which corresponds to the vbak area.
Important Side Effect: Managing the Screen Buffer
Section titled “Important Side Effect: Managing the Screen Buffer”Placing your application code in the vbak region comes with a critical responsibility: you must now manually restore the screen’s contents restore after run. Because your code occupies the memory space the operating system would use to back up the screen (vram), you must save and restore the screen state yourself upon starting and exiting your app.
Doing it is hopefully trivial, you need to override the default calcInit and calcExit functions. The following code allocates a temporary buffer on the heap, copies the current screen content into it, and restores it when the app closes.
#include <type_traits>#include <sdk/os/file.h>#include <sdk/os/debug.h>#include <sdk/os/lcd.h>#include <sdk/os/string.h>#include <sdk/calc/calc.h>#include <cstring>#include <cstdlib>
// A backup pointer for the original vram contentstd::remove_pointer_t<decltype(vram)> (*vram_bak)[width * height];
// This function is called when your app startsvoid calcInit(void){ // Allocate memory on the heap to store the screen backup vram_bak = (decltype(vram_bak))malloc(sizeof(*vram_bak));
// If allocation fails, we can't proceed safely if (!vram_bak) { return; }
// Copy the current screen content to our backup buffer memcpy(vram_bak, vram, sizeof(*vram_bak)); // Clear the screen for the app memset(vram, 0, sizeof(*vram_bak));}
// This function is called when your app exitsvoid calcExit(void){ // Copy the backed-up screen content back to vram memcpy(vram, vram_bak, sizeof(*vram_bak)); // Refresh the LCD to show the restored content LCD_Refresh(); // Free the memory we allocated for the backup free(vram_bak);}For a complete implementation of this technique, you can look at the source code for CPDoom. The project uses the vbak memory region and provides a clear example of overriding calcInit and calcExit in its bootstrap.cpp file.