185 lines
6.9 KiB
CMake
185 lines
6.9 KiB
CMake
# Copyright (c) 2026 Dominic Masters
|
|
#
|
|
# This software is released under the MIT License.
|
|
# https://opensource.org/licenses/MIT
|
|
|
|
# Resolve YAUL_INSTALL_ROOT (already set by the toolchain file, but guard
|
|
# in case cmake/targets/ is loaded standalone for IDE tooling).
|
|
if(NOT DEFINED YAUL_INSTALL_ROOT)
|
|
if(DEFINED ENV{YAUL_INSTALL_ROOT})
|
|
set(YAUL_INSTALL_ROOT "$ENV{YAUL_INSTALL_ROOT}")
|
|
else()
|
|
set(YAUL_INSTALL_ROOT "/opt/yaul")
|
|
endif()
|
|
endif()
|
|
|
|
# Yaul installs headers/libs under the arch-prefix sysroot subdirectory:
|
|
# ${YAUL_INSTALL_ROOT}/sh2eb-elf/include/
|
|
# ${YAUL_INSTALL_ROOT}/sh2eb-elf/lib/
|
|
# Cross-compiled zlib and libzip are installed to the same sysroot.
|
|
set(_YAUL_SYSROOT "${YAUL_INSTALL_ROOT}/sh2eb-elf")
|
|
set(_YAUL_BIN "${YAUL_INSTALL_ROOT}/bin")
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Bypass system find_package calls for libraries we cross-compile into the
|
|
# sh2eb-elf sysroot and install into ${_YAUL_SYSROOT}.
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# zlib
|
|
if(NOT TARGET ZLIB::ZLIB)
|
|
add_library(ZLIB::ZLIB INTERFACE IMPORTED GLOBAL)
|
|
set_target_properties(ZLIB::ZLIB PROPERTIES
|
|
INTERFACE_INCLUDE_DIRECTORIES "${_YAUL_SYSROOT}/include"
|
|
INTERFACE_LINK_LIBRARIES "${_YAUL_SYSROOT}/lib/libz.a"
|
|
)
|
|
endif()
|
|
set(ZLIB_FOUND TRUE CACHE BOOL "" FORCE)
|
|
set(ZLIB_INCLUDE_DIR "${_YAUL_SYSROOT}/include" CACHE PATH "" FORCE)
|
|
set(ZLIB_LIBRARY "${_YAUL_SYSROOT}/lib/libz.a" CACHE FILEPATH "" FORCE)
|
|
|
|
# libzip — pre-installed into the sh2eb-elf sysroot; skip Findlibzip.cmake.
|
|
set(libzip_FOUND TRUE CACHE BOOL "libzip found (Saturn sysroot)" FORCE)
|
|
find_path(_sat_zip_inc NAMES zip.h
|
|
PATHS "${_YAUL_SYSROOT}/include"
|
|
NO_DEFAULT_PATH
|
|
)
|
|
if(_sat_zip_inc)
|
|
target_include_directories(${DUSK_LIBRARY_TARGET_NAME} PRIVATE "${_sat_zip_inc}")
|
|
endif()
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Compile definitions
|
|
# ---------------------------------------------------------------------------
|
|
target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC
|
|
DUSK_SATURN
|
|
DUSK_INPUT_GAMEPAD
|
|
DUSK_PLATFORM_ENDIAN_BIG
|
|
DUSK_DISPLAY_WIDTH=320
|
|
DUSK_DISPLAY_HEIGHT=224
|
|
DUSK_THREAD_NONE
|
|
)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Compile options
|
|
# ---------------------------------------------------------------------------
|
|
target_compile_options(${DUSK_LIBRARY_TARGET_NAME} PRIVATE
|
|
-m2 -mb
|
|
-fno-builtin
|
|
-fomit-frame-pointer
|
|
-w
|
|
)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Include paths
|
|
# ---------------------------------------------------------------------------
|
|
target_include_directories(${DUSK_LIBRARY_TARGET_NAME} PRIVATE
|
|
"${_YAUL_SYSROOT}/include"
|
|
"${_YAUL_SYSROOT}/include/yaul"
|
|
)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Link libraries
|
|
# ---------------------------------------------------------------------------
|
|
target_link_directories(${DUSK_LIBRARY_TARGET_NAME} PRIVATE
|
|
"${_YAUL_SYSROOT}/lib"
|
|
)
|
|
|
|
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PRIVATE
|
|
# --start-group/--end-group allow circular archive references
|
|
# (e.g. libyaul allocator symbols referenced by libzip / yyjson objects).
|
|
-Wl,--start-group
|
|
"${_YAUL_SYSROOT}/lib/libyaul.a"
|
|
"${_YAUL_SYSROOT}/lib/libzip.a"
|
|
"${_YAUL_SYSROOT}/lib/libz.a"
|
|
# GCC soft-float / soft-divide runtime (SH-2 has no FPU or hw divider).
|
|
# -lgcc is resolved by the compiler driver even with -nodefaultlibs.
|
|
-lgcc
|
|
-Wl,--end-group
|
|
)
|
|
|
|
# Yaul linker script (Saturn SH-2 memory map) and startup objects.
|
|
# Startup objects must precede all other objects so use target_link_options
|
|
# (those flags appear before the object-file list in cmake's link command).
|
|
target_link_options(${DUSK_BINARY_TARGET_NAME} PRIVATE
|
|
"-T${_YAUL_SYSROOT}/lib/ldscripts/yaul.x"
|
|
"${_YAUL_SYSROOT}/lib/crt0.o"
|
|
"${_YAUL_SYSROOT}/lib/init.o"
|
|
# Provide SH-2 stack top addresses required by crt0.o/cpu_dual_entries.o.
|
|
# RAM region: 0x06004000 .. 0x06100000 (~1 MB).
|
|
# Master stack grows down from the very top; slave CPU gets 4 KB below.
|
|
"-Wl,--defsym=___master_stack=0x06100000"
|
|
"-Wl,--defsym=___slave_stack=0x060FF000"
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Post-build: ELF → binary → Saturn disc image (ISO + CUE)
|
|
# ---------------------------------------------------------------------------
|
|
set(DUSK_SAT_BIN "${CMAKE_BINARY_DIR}/Dusk.bin")
|
|
set(DUSK_SAT_IP_BIN "${CMAKE_BINARY_DIR}/IP.BIN")
|
|
set(DUSK_SAT_CD_DIR "${CMAKE_BINARY_DIR}/cd")
|
|
set(DUSK_SAT_AUDIO_DIR "${CMAKE_BINARY_DIR}/audio-tracks")
|
|
set(DUSK_SAT_ISO "${CMAKE_BINARY_DIR}/Dusk.iso")
|
|
set(DUSK_SAT_CUE "${CMAKE_BINARY_DIR}/Dusk.cue")
|
|
|
|
# Step 1: ELF → flat binary (loaded into Work RAM by IP.BIN)
|
|
add_custom_command(TARGET ${DUSK_BINARY_TARGET_NAME} POST_BUILD
|
|
COMMAND "${_YAUL_BIN}/sh2eb-elf-objcopy"
|
|
-O binary
|
|
"$<TARGET_FILE:${DUSK_BINARY_TARGET_NAME}>"
|
|
"${DUSK_SAT_BIN}"
|
|
COMMENT "Converting ELF → ${DUSK_SAT_BIN}"
|
|
)
|
|
|
|
# Step 2: flat binary → IP.BIN (boot header with region security blobs)
|
|
# make-ip writes IP.BIN into dirname(arg1), so it lands at ${CMAKE_BINARY_DIR}/IP.BIN.
|
|
# Pass -1 for 1st-read-size so make-ip uses the actual file size.
|
|
add_custom_command(TARGET ${DUSK_BINARY_TARGET_NAME} POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E env
|
|
"YAUL_INSTALL_ROOT=${YAUL_INSTALL_ROOT}"
|
|
"YAUL_ARCH_SH_PREFIX=sh2eb-elf"
|
|
"${_YAUL_BIN}/make-ip"
|
|
"${DUSK_SAT_BIN}"
|
|
"V1.000"
|
|
"20260101"
|
|
"JTUE"
|
|
"J"
|
|
"DUSK"
|
|
"0x06100000"
|
|
"0x060FF000"
|
|
"0x06004000"
|
|
"-1"
|
|
COMMENT "Generating IP.BIN"
|
|
)
|
|
|
|
# Step 3: build CD filesystem tree and create ISO 9660 image
|
|
add_custom_command(TARGET ${DUSK_BINARY_TARGET_NAME} POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${DUSK_SAT_CD_DIR}"
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${DUSK_SAT_AUDIO_DIR}"
|
|
COMMAND ${CMAKE_COMMAND} -E copy "${DUSK_SAT_BIN}" "${DUSK_SAT_CD_DIR}/A.BIN"
|
|
# ISO 9660 requires these auxiliary text files
|
|
COMMAND ${CMAKE_COMMAND} -E touch "${DUSK_SAT_CD_DIR}/ABS.TXT"
|
|
COMMAND ${CMAKE_COMMAND} -E touch "${DUSK_SAT_CD_DIR}/BIB.TXT"
|
|
COMMAND ${CMAKE_COMMAND} -E touch "${DUSK_SAT_CD_DIR}/CPY.TXT"
|
|
COMMAND ${CMAKE_COMMAND} -E env
|
|
"YAUL_INSTALL_ROOT=${YAUL_INSTALL_ROOT}"
|
|
"MAKE_ISO_XORRISOFS=/usr/bin/xorrisofs"
|
|
"${_YAUL_BIN}/make-iso"
|
|
"${DUSK_SAT_CD_DIR}"
|
|
"${DUSK_SAT_IP_BIN}"
|
|
"${CMAKE_BINARY_DIR}"
|
|
"Dusk"
|
|
COMMENT "Generating ${DUSK_SAT_ISO}"
|
|
)
|
|
|
|
# Step 4: ISO → CUE sheet (rename .iso → .bin for a classic BIN/CUE pair
|
|
# if desired; emulators accept .iso+.cue as-is)
|
|
add_custom_command(TARGET ${DUSK_BINARY_TARGET_NAME} POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E env
|
|
"YAUL_INSTALL_ROOT=${YAUL_INSTALL_ROOT}"
|
|
"${_YAUL_BIN}/make-cue"
|
|
"${DUSK_SAT_AUDIO_DIR}"
|
|
"${DUSK_SAT_ISO}"
|
|
COMMENT "Generating ${DUSK_SAT_CUE}"
|
|
)
|