Migrating to V3
Migrating your Classpad HHK (v2) project to HH3 (v3) require a few tweaks to your codebase.
What Needs to Be Done
Section titled “What Needs to Be Done”Update Environment Files
Section titled “Update Environment Files”Update configuration files to reflect the new SDK requirements:
- Makefile: Adjust compiler flags and target settings.
- CI Configurations: Update build pipelines to use the new toolchain.
- Devcontainer: Modify container setup to include V3 dependencies.
- clangd: Regenerate
compile_commands.json
and restart clangd for proper IDE support. - .gitignore: Update to include new build artifacts:
*.bin*.elf*.hh3*.map# temporary files under WSL*~.*~
Remove linker.ld
Section titled “Remove linker.ld”The linker.ld
file can be safely removed as the SDK now handles linking automatically.
Update the Makefile
Section titled “Update the Makefile”Replace your old Makefile with the new structure:
Before:
APP_NAME:=tetris
ifndef SDK_DIR$(error You need to define the SDK_DIR environment variable, and point it to the sdk/ folder)endif
AS:=sh4-elf-asAS_FLAGS:=
CC:=sh4-elf-gccCC_FLAGS:=-ffreestanding -fshort-wchar -Wall -Wextra -O2 -I $(SDK_DIR)/include/
CXX:=sh4-elf-g++CXX_FLAGS:=-ffreestanding -fno-exceptions -fno-rtti -fshort-wchar -Wall -Wextra -O2 -I $(SDK_DIR)/include/
LD:=sh4-elf-ldLD_FLAGS:=-nostdlib --no-undefined
READELF:=sh4-elf-readelfOBJCOPY:=sh4-elf-objcopy
AS_SOURCES:=$(wildcard *.s)CC_SOURCES:=$(wildcard *.c)CXX_SOURCES:=$(wildcard *.cpp)OBJECTS:=$(AS_SOURCES:.s=.o) $(CC_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)
APP_ELF:=$(APP_NAME).hhk
all: $(APP_ELF) Makefile
clean: rm -f $(OBJECTS) $(APP_ELF)
$(APP_ELF): $(OBJECTS) $(SDK_DIR)/sdk.o linker.ld $(LD) -T linker.ld -o $@ $(LD_FLAGS) $(OBJECTS) $(SDK_DIR)/sdk.o $(OBJCOPY) --set-section-flags .hollyhock_name=contents,strings,readonly $(APP_ELF) $(APP_ELF) $(OBJCOPY) --set-section-flags .hollyhock_description=contents,strings,readonly $(APP_ELF) $(APP_ELF) $(OBJCOPY) --set-section-flags .hollyhock_author=contents,strings,readonly $(APP_ELF) $(APP_ELF) $(OBJCOPY) --set-section-flags .hollyhock_version=contents,strings,readonly $(APP_ELF) $(APP_ELF)
After:
APP_NAME:=tetris
ifndef SDK_DIR$(error You need to define the SDK_DIR environment variable, and point it to the sdk/ folder)endif
AS:=sh4a_nofpueb-elf-gccAS_FLAGS:=
FUNCTION_FLAGS=-flto -ffat-lto-objects -ffunction-sections -fdata-sections -O2 -gdwarf-5
CC:=sh4a_nofpueb-elf-gccCC_FLAGS:=$(FUNCTION_FLAGS) -Wall -Wextra -I $(SDK_DIR)/include/
CXX:=sh4a_nofpueb-elf-g++CXX_FLAGS:=$(FUNCTION_FLAGS) -Wall -Wextra -I $(SDK_DIR)/include/
LD:=sh4a_nofpueb-elf-g++LD_FLAGS:=$(FUNCTION_FLAGS) -Wl,--gc-sections -L$(SDK_DIR)
READELF:=sh4a_nofpueb-elf-readelfOBJCOPY:=sh4a_nofpueb-elf-objcopySTRIP:=sh4a_nofpueb-elf-strip
AS_SOURCES:=$(wildcard *.S)CC_SOURCES:=$(wildcard *.c)CXX_SOURCES:=$(wildcard *.cpp)OBJECTS:=$(AS_SOURCES:.S=.o) $(CC_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)
APP_ELF:=$(APP_NAME).elfAPP_OUT:=$(APP_NAME).hh3
elf: $(APP_ELF) Makefilehh3: $(APP_OUT) Makefileall: $(APP_ELF) $(APP_OUT) Makefile
.DEFAULT_GOAL := all
clean: rm -f $(OBJECTS) $(APP_ELF) $(APP_ELF).map $(APP_OUT)
$(APP_ELF): $(OBJECTS) $(SDK_DIR)/libsdk.a $(LD) -Wl,-Map $@.map -o $@ $(LD_FLAGS) $(OBJECTS) -lsdk
$(APP_OUT): $(APP_ELF) $(STRIP) -o $@ $^
Update Include Headers
Section titled “Update Include Headers”Rename header extensions from .hpp
to .h
, except for GUI-related headers.
Before:
#include <appdef.hpp>#include <sdk/os/debug.hpp>#include <sdk/os/input.hpp>#include <sdk/os/lcd.hpp>#include <sdk/os/mem.hpp>
After:
#include <appdef.h>#include <sdk/os/debug.h>#include <sdk/os/input.h>#include <sdk/os/lcd.h>#include <sdk/os/mem.h>
Modernize Code Syntax
Section titled “Modernize Code Syntax”Update deprecated syntax patterns:
char *num = "0000"
→char num[] = "0000"
for (int x = ...
→for (auto x = ...
- Use
static_cast<type>(value)
instead of C-style casts - Use proper types:
int32_t
→int
, etc.
Update Main Function Signature
Section titled “Update Main Function Signature”Change the main function:
Before:
extern "C" void main() { // code}
After:
int main() { // code return 0;}
Or for full environment access:
int main(int argc, char **argv, char **envp) { // code return 0;}
Remove Obsolete Functions
Section titled “Remove Obsolete Functions”- Remove
LCD_VRAMBackup()
andLCD_VRAMRestore()
- Remove
calcInit()
andcalcEnd()
calls - Remove global VRAM declarations like
uint16_t *vram;
Update Memory Operations
Section titled “Update Memory Operations”Replace old memory functions:
memset
→Mem_Memset
- And other similar memory operations
Add App Definitions
Section titled “Add App Definitions”Ensure your main file contains proper app metadata:
APP_NAME("Your App Demo")APP_DESCRIPTION("Displays a demo on the ClassPad.")APP_AUTHOR("your_name")APP_VERSION("1.0.0")
Update Struct Names
Section titled “Update Struct Names”Rename structures to match new conventions:
InputEvent
→Input_Event
InputScancode
→Input_Scancode
Use New Features
Section titled “Use New Features”Take advantage of V3 improvements:
- Use
__builtin_unreachable();
for unreachable code paths - Add
return 0;
at the end of main function - Initialize LFSR directly:
uint16_t lfsr = 0x453A;
Review calcInit
and calcEnd
Section titled “Review calcInit and calcEnd”Check if calcInit
and calcEnd
are still needed. In most cases, they are no longer required and can be removed.
Refactor to Use libc / libstdc++
Section titled “Refactor to Use libc / libstdc++”Take advantage of the new support for libc and libstdc++ by refactoring code to use standard library functions where appropriate.
Embed Binary Files into the ELF
Section titled “Embed Binary Files into the ELF”Consider embedding binary assets directly into the ELF file instead of loading them separately to simplify deployment.
Address New Compiler Warnings and Errors
Section titled “Address New Compiler Warnings and Errors”Review and fix any new warnings or errors reported by the updated compiler.
VRAM Backup Handling
Section titled “VRAM Backup Handling”If your app loads into VRAM:
- You no longer need a special launcher.
- Load directly into
vbak
. - Override
calcInit
andcalcEnd
(they are weak by default) to implement custom VRAM backup logic and avoid overwriting your own data.
Known Issues
Section titled “Known Issues”- PEG (System) UI is currently not working.
- Input_GetKeyState is not functional in this version.
Example Update Snippet
Section titled “Example Update Snippet”Before:
#include <appdef.hpp>#include <sdk/os/debug.hpp>
extern "C" void main() { Debug_PrintString("Hello World");}
After:
#include <appdef.h>#include <sdk/os/debug.h>
APP_NAME("Hello World App")APP_DESCRIPTION("Displays Hello World")APP_AUTHOR("Developer")APP_VERSION("1.0.0")
int main() { DebugPrintString("Hello World"); return 0;}