Create Simulator target scaffold
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
file(GLOB_RECURSE CORE_SOURCES CONFIGURE_DEPENDS "src/*.c")
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(nova64_core VERSION 1.0.0 LANGUAGES C)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
if(ESP_PLATFORM)
|
||||
# --------------------------------------------------------------------------
|
||||
# 1. ESP-IDF BUILD MODE (Target: ESP32-P4)
|
||||
# --------------------------------------------------------------------------
|
||||
message(STATUS "[Nova64] Building as ESP-IDF Component for ESP32...")
|
||||
|
||||
idf_component_register(
|
||||
SRCS
|
||||
${CORE_SOURCES}
|
||||
INCLUDE_DIRS
|
||||
"include"
|
||||
REQUIRES
|
||||
freertos
|
||||
wamr
|
||||
)
|
||||
|
||||
else()
|
||||
# --------------------------------------------------------------------------
|
||||
# 2. DESKTOP BUILD MODE (Target: Windows .dll / Linux .so / macOS .dylib)
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
message(STATUS "[Nova64] Building as Desktop Shared Library...")
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# FreeRTOS Configuration
|
||||
# --------------------------------------------------------------------------
|
||||
add_library(freertos_config INTERFACE)
|
||||
|
||||
target_include_directories(freertos_config SYSTEM
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
target_compile_definitions(freertos_config
|
||||
INTERFACE
|
||||
projCOVERAGE_TEST=0
|
||||
)
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# FreeRTOS Kernel via FetchContent
|
||||
# --------------------------------------------------------------------------
|
||||
include(FetchContent)
|
||||
|
||||
# Download FreeRTOS-Kernel Repository
|
||||
FetchContent_Declare(
|
||||
FreeRTOS_Kernel
|
||||
GIT_REPOSITORY https://github.com/FreeRTOS/FreeRTOS-Kernel.git
|
||||
GIT_TAG V11.3.0
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(FREERTOS_PORT "MSVC_MINGW" CACHE STRING "")
|
||||
else()
|
||||
set(FREERTOS_PORT "GCC/POSIX" CACHE STRING "")
|
||||
endif()
|
||||
# Select FreeRTOS heap implementation (provides pvPortMalloc/vPortFree)
|
||||
set(FREERTOS_HEAP 4 CACHE STRING "FreeRTOS Heap Implementation")
|
||||
# Disable FreeRTOS Demos/Tests
|
||||
set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
|
||||
|
||||
# define Target 'freertos_kernel'
|
||||
FetchContent_MakeAvailable(FreeRTOS_Kernel)
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Nova64 Core Target
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
# Shared Library (.dll / .so / .dylib)
|
||||
add_library(nova64_core SHARED ${CORE_SOURCES})
|
||||
|
||||
target_include_directories(nova64_core PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
)
|
||||
|
||||
# Link FreeRTOS Kernel to the nova64_core library
|
||||
target_link_libraries(nova64_core PRIVATE freertos_kernel freertos_config)
|
||||
|
||||
target_compile_definitions(nova64_core PRIVATE NOVA64_EXPORTS)
|
||||
|
||||
if (WIN32)
|
||||
set_target_properties(nova64_core PROPERTIES
|
||||
C_VISIBILITY_PRESET hidden
|
||||
VISIBILITY_INLINES_HIDDEN YES
|
||||
PREFIX ""
|
||||
)
|
||||
else()
|
||||
set_target_properties(nova64_core PROPERTIES
|
||||
C_VISIBILITY_PRESET hidden
|
||||
VISIBILITY_INLINES_HIDDEN YES
|
||||
)
|
||||
endif()
|
||||
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
endif()
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/* Desktop Simulator Settings */
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
||||
#define configMAX_PRIORITIES ( 5 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 64 * 1024 ) )
|
||||
#define configMAX_TASK_NAME_LEN ( 16 )
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
|
||||
/* Synchronisation Objects */
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_QUEUE_SETS 1
|
||||
|
||||
/* Memory Management */
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||
|
||||
/* Disable API Functions */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskCleanUpResources 0
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
@@ -0,0 +1,106 @@
|
||||
#ifndef NOVA64_CORE_H
|
||||
#define NOVA64_CORE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Cross-platform DLL export/import visibility macros
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#ifdef NOVA64_EXPORTS
|
||||
#define NOVA64_API __declspec(dllexport)
|
||||
#else
|
||||
#define NOVA64_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#if __GNUC__ >= 4
|
||||
#define NOVA64_API __attribute__((visibility("default")))
|
||||
#else
|
||||
#define NOVA64_API
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ========================================================================== */
|
||||
/* I/O Callback Typedefs */
|
||||
/* ========================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Callback to flush a frame buffer to the display.
|
||||
* @param buffer Pointer to raw pixel data (e.g., RGB565 / RGBA8888).
|
||||
* @param width Frame width in pixels.
|
||||
* @param height Frame height in pixels.
|
||||
*/
|
||||
typedef void (*nova64_display_flush_cb_t)(const uint16_t *buffer,
|
||||
uint16_t width, uint16_t height);
|
||||
|
||||
/**
|
||||
* @brief Callback to output audio samples.
|
||||
* @param samples Pointer to PCM audio sample buffer.
|
||||
* @param count Number of samples in the buffer.
|
||||
*/
|
||||
typedef void (*nova64_audio_output_cb_t)(const int16_t *samples,
|
||||
uint32_t count);
|
||||
|
||||
/**
|
||||
* @brief Callback to read sectors from the SD card.
|
||||
* @param sector_idx The zero-based sector index to read.
|
||||
* @param destination_buffer Pointer to memory where sector data should be
|
||||
* copied.
|
||||
* @param sector_count Number of 512-byte sectors to read.
|
||||
* @return True on success, false on read error.
|
||||
*/
|
||||
typedef bool (*nova64_sd_read_sector_cb_t)(uint32_t sector_idx,
|
||||
uint8_t *destination_buffer,
|
||||
uint32_t sector_count);
|
||||
|
||||
/**
|
||||
* @brief Callback triggered when a cartridge state change occurs (e.g.
|
||||
* inserted/removed).
|
||||
* @param slot_idx Zero-based cartridge slot index.
|
||||
* @param is_inserted True if a cartridge is detected, false if ejected.
|
||||
*/
|
||||
typedef void (*nova64_cartridge_status_cb_t)(uint32_t slot_idx,
|
||||
bool is_inserted);
|
||||
|
||||
/* ========================================================================== */
|
||||
/* I/O Interface Configuration Struct */
|
||||
/* ========================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Struct containing all I/O hardware abstraction callbacks.
|
||||
* Pass NULL for any unneeded callback.
|
||||
*/
|
||||
typedef struct {
|
||||
nova64_display_flush_cb_t display_flush;
|
||||
nova64_audio_output_cb_t audio_output;
|
||||
nova64_sd_read_sector_cb_t sd_read_sector;
|
||||
nova64_cartridge_status_cb_t cartridge_status;
|
||||
} nova64_io_interface_t;
|
||||
|
||||
/* ========================================================================== */
|
||||
/* Engine Core API */
|
||||
/* ========================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Initializes the core engine and registers host I/O interface
|
||||
* callbacks.
|
||||
* @param io_interface Pointer to filled struct containing I/O function
|
||||
* pointers.
|
||||
* @return True if initialized successfully, false if already initialized or
|
||||
* invalid.
|
||||
*/
|
||||
NOVA64_API bool nova64_init_io(const nova64_io_interface_t *io_interface);
|
||||
|
||||
/**
|
||||
* @brief Executes one engine processing tick.
|
||||
* @param delta_ms Elapsed time in milliseconds since the last tick.
|
||||
* @return 0 on success, negative error code on failure.
|
||||
*/
|
||||
NOVA64_API int32_t nova64_process_tick(uint32_t delta_ms);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the engine version integer.
|
||||
* @return 24-bit packed version number (0xMMmmPP -> Major, Minor, Patch).
|
||||
*/
|
||||
NOVA64_API uint32_t nova64_get_version(void);
|
||||
|
||||
#endif // NOVA64_CORE_H
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "nova64_core.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
#include "task.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(ESP_PLATFORM)
|
||||
/* ESP32-spezifische Header für Low-Power & Watchdog */
|
||||
#include "esp_pm.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_task_wdt.h"
|
||||
#elif defined(_WIN32)
|
||||
/* Windows API für Schlafen im Desktop-Thread */
|
||||
#include <windows.h>
|
||||
#else
|
||||
/* POSIX / Linux / macOS Sleep */
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
static bool is_initialized = false;
|
||||
static QueueHandle_t event_queue = NULL;
|
||||
|
||||
|
||||
NOVA64_API bool nova64_init_io(const nova64_io_interface_t *io_interface) {
|
||||
printf("[Nova64 Core] System Initializing...\n");
|
||||
|
||||
event_queue = xQueueCreate(10, sizeof(uint32_t));
|
||||
|
||||
is_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
NOVA64_API int32_t nova64_process_tick(uint32_t delta_ms) {
|
||||
if (!is_initialized)
|
||||
return -1;
|
||||
// Core Game-Logic & State Machine Ticks
|
||||
return 0; // OK
|
||||
}
|
||||
|
||||
NOVA64_API uint32_t nova64_get_version(void) {
|
||||
return 0x010000; // v1.0.0
|
||||
}
|
||||
|
||||
/* FreeRTOS hook: called by the kernel when the idle task runs.
|
||||
* Required because configUSE_IDLE_HOOK is enabled in FreeRTOSConfig.h
|
||||
*/
|
||||
void vApplicationIdleHook(void) {
|
||||
#if defined(ESP_PLATFORM)
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// ESP32-specific idle hook code
|
||||
// -------------------------------------------------------------------------
|
||||
#if CONFIG_ESP_TASK_WDT
|
||||
// Feed the watchdog to prevent reset
|
||||
esp_task_wdt_reset();
|
||||
#endif
|
||||
asm volatile("wfi"); // Wait for interrupt to save power
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Windows-specific idle hook code
|
||||
// -------------------------------------------------------------------------
|
||||
Sleep(1); // Sleep for 1 millisecond to yield CPU
|
||||
|
||||
#else
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// POSIX-specific idle hook code
|
||||
// -------------------------------------------------------------------------
|
||||
struct timespec ts = {0, 1000000}; // 1 millisecond
|
||||
nanosleep(&ts, NULL);
|
||||
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user