(WIP) new binary format
Some checks failed
Build-StoryEditor / build_win32 (push) Has been cancelled
Build-StoryEditor / build_linux (push) Has been cancelled

This commit is contained in:
anthony@rabine.fr 2025-10-12 20:39:32 +02:00
parent 9ab7b9bb14
commit c6da4b891a
10 changed files with 128 additions and 219 deletions

2
.vscode/launch.json vendored
View file

@ -73,7 +73,7 @@
"type": "cppdbg", "type": "cppdbg",
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/core/tests/build/core_tests", // Remplacez par le chemin de votre exécutable "program": "${workspaceFolder}/core/tests/build/core_tests", // Remplacez par le chemin de votre exécutable
"args": [], "args": ["[vm]"],
"stopAtEntry": false, "stopAtEntry": false,
"cwd": "${workspaceFolder}/core/tests/build", "cwd": "${workspaceFolder}/core/tests/build",
"environment": [], "environment": [],

View file

@ -109,7 +109,9 @@
"serializers.h": "c", "serializers.h": "c",
"ni_parser.h": "c", "ni_parser.h": "c",
"*.m": "cpp", "*.m": "cpp",
"*.inc": "cpp" "*.inc": "cpp",
"chip32_binary_format.h": "c",
"hash_map": "c"
} }
} }

View file

@ -365,7 +365,7 @@ bool Assembler::BuildBinary(std::vector<uint8_t> &program, Result &result)
// ======================================================================== // ========================================================================
// PHASE 1: Créer les sections temporaires // PHASE 1: Créer les sections temporaires
// ======================================================================== // ========================================================================
std::vector<uint8_t> dataSection; // DC - ROM constants only std::vector<uint8_t> constSection; // DC - ROM constants only
std::vector<uint8_t> codeSection; // Executable code std::vector<uint8_t> codeSection; // Executable code
std::vector<uint8_t> initDataSection; // DV values + DZ zeros (RAM init) std::vector<uint8_t> initDataSection; // DV values + DZ zeros (RAM init)
@ -471,10 +471,10 @@ bool Assembler::BuildBinary(std::vector<uint8_t> &program, Result &result)
if (!isDvInitData) if (!isDvInitData)
{ {
// C'est une vraie constante DC - va dans dataSection // C'est une vraie constante DC - va dans constSection
std::copy(i.compiledArgs.begin(), std::copy(i.compiledArgs.begin(),
i.compiledArgs.end(), i.compiledArgs.end(),
std::back_inserter(dataSection)); std::back_inserter(constSection));
result.constantsSize += i.compiledArgs.size(); result.constantsSize += i.compiledArgs.size();
} }
@ -511,7 +511,7 @@ bool Assembler::BuildBinary(std::vector<uint8_t> &program, Result &result)
chip32_binary_header_t header; chip32_binary_header_t header;
chip32_binary_header_init(&header); chip32_binary_header_init(&header);
header.data_size = static_cast<uint32_t>(dataSection.size()); header.const_size = static_cast<uint32_t>(constSection.size());
header.bss_size = bssSize; header.bss_size = bssSize;
header.code_size = static_cast<uint32_t>(codeSection.size()); header.code_size = static_cast<uint32_t>(codeSection.size());
header.entry_point = entryPoint; header.entry_point = entryPoint;
@ -530,7 +530,7 @@ bool Assembler::BuildBinary(std::vector<uint8_t> &program, Result &result)
uint32_t bytesWritten = chip32_binary_write( uint32_t bytesWritten = chip32_binary_write(
&header, &header,
dataSection.empty() ? nullptr : dataSection.data(), constSection.empty() ? nullptr : constSection.data(),
codeSection.empty() ? nullptr : codeSection.data(), codeSection.empty() ? nullptr : codeSection.data(),
initDataSection.empty() ? nullptr : initDataSection.data(), initDataSection.empty() ? nullptr : initDataSection.data(),
program.data(), program.data(),
@ -548,8 +548,8 @@ bool Assembler::BuildBinary(std::vector<uint8_t> &program, Result &result)
// PHASE 7: Remplir les statistiques // PHASE 7: Remplir les statistiques
// ======================================================================== // ========================================================================
result.ramUsageSize = bssSize; result.ramUsageSize = bssSize;
result.romUsageSize = header.data_size + header.code_size; result.romUsageSize = header.const_size + header.code_size;
result.constantsSize = header.data_size; result.constantsSize = header.const_size;
return true; return true;
} }

View file

@ -13,94 +13,92 @@ _Static_assert(sizeof(chip32_binary_header_t) == 28, "Header must be 28 bytes");
// ============================================================================ // ============================================================================
chip32_binary_error_t chip32_binary_load( chip32_binary_error_t chip32_binary_load(
chip32_ctx_t *ctx,
uint8_t* binary, uint8_t* binary,
uint32_t size, uint32_t binary_size,
chip32_loaded_binary_t* out_loaded uint8_t* ram,
uint32_t ram_size,
chip32_binary_stats_t *out_stats
) )
{ {
if (!binary || !out_loaded) { memset(ctx, 0, sizeof(ctx));
ctx->stack_size = 512; // Can be changed outside this function
// Clear RAM
memset(ram, 0, ram_size);
chip32_binary_header_t header;
if (!binary || !ctx) {
return CHIP32_BIN_ERR_NULL_POINTER; return CHIP32_BIN_ERR_NULL_POINTER;
} }
// Clear output structure
memset(out_loaded, 0, sizeof(chip32_loaded_binary_t));
// Check minimum size // Check minimum size
if (size < sizeof(chip32_binary_header_t)) { if (binary_size < sizeof(chip32_binary_header_t)) {
out_loaded->error = CHIP32_BIN_ERR_TOO_SMALL;
return CHIP32_BIN_ERR_TOO_SMALL; return CHIP32_BIN_ERR_TOO_SMALL;
} }
// Copy header // Copy header
memcpy(&out_loaded->header, binary, sizeof(chip32_binary_header_t)); memcpy(&header, binary, sizeof(chip32_binary_header_t));
// Verify magic number // Verify magic number
if (out_loaded->header.magic != CHIP32_MAGIC) { if (header.magic != CHIP32_MAGIC) {
out_loaded->error = CHIP32_BIN_ERR_INVALID_MAGIC;
return CHIP32_BIN_ERR_INVALID_MAGIC; return CHIP32_BIN_ERR_INVALID_MAGIC;
} }
// Check version // Check version
if (out_loaded->header.version > CHIP32_VERSION) { if (header.version > CHIP32_VERSION) {
out_loaded->error = CHIP32_BIN_ERR_UNSUPPORTED_VERSION;
return CHIP32_BIN_ERR_UNSUPPORTED_VERSION; return CHIP32_BIN_ERR_UNSUPPORTED_VERSION;
} }
// Calculate expected size // Calculate expected size
uint32_t expected_size = sizeof(chip32_binary_header_t) + uint32_t expected_size = sizeof(chip32_binary_header_t) +
out_loaded->header.data_size + header.const_size +
out_loaded->header.code_size + header.code_size +
out_loaded->header.init_data_size; header.init_data_size;
if (size != expected_size) { if (binary_size != expected_size) {
out_loaded->error = CHIP32_BIN_ERR_SIZE_MISMATCH;
return CHIP32_BIN_ERR_SIZE_MISMATCH; return CHIP32_BIN_ERR_SIZE_MISMATCH;
} }
// Set section pointers // Set section pointers
uint32_t offset = sizeof(chip32_binary_header_t); uint32_t offset = sizeof(chip32_binary_header_t);
if (out_loaded->header.data_size > 0) {
out_loaded->data_section = binary + offset;
offset += out_loaded->header.data_size;
}
if (out_loaded->header.code_size > 0) {
out_loaded->code_section = binary + offset;
offset += out_loaded->header.code_size;
}
if (out_loaded->header.init_data_size > 0) {
out_loaded->init_data_section = binary + offset;
}
out_loaded->error = CHIP32_BIN_OK;
return CHIP32_BIN_OK;
}
void chip32_binary_get_stats( // Skip header for ROM executable (must start at a valide code address)
const chip32_loaded_binary_t* loaded, ctx->rom.mem = binary + offset;
chip32_binary_stats_t* out_stats ctx->rom.size = binary_size - offset;
) ctx->rom.addr = 0;
{
if (!loaded || !out_stats) { // RAM and ROM are in the same logical memory plane
return; // So we set it begin after the ROM (why not)
} ctx->ram.mem = ram;
ctx->ram.addr = ctx->rom.size;
out_stats->data_size = loaded->header.data_size; ctx->ram.size = ram_size;
out_stats->bss_size = loaded->header.bss_size;
out_stats->code_size = loaded->header.code_size; // Set entry point (DATA size + entry point offset in CODE)
out_stats->init_data_size = loaded->header.init_data_size; ctx->registers[PC] = header.entry_point;
// Load data initialized values
const uint8_t *data = binary + header.code_size;
memcpy(ram, data, header.init_data_size);
out_stats->const_size = header.const_size;
out_stats->bss_size = header.bss_size;
out_stats->code_size = header.code_size;
out_stats->init_data_size = header.init_data_size;
out_stats->total_file_size = sizeof(chip32_binary_header_t) + out_stats->total_file_size = sizeof(chip32_binary_header_t) +
loaded->header.data_size + header.const_size +
loaded->header.code_size + header.code_size +
loaded->header.init_data_size; header.init_data_size;
out_stats->total_rom_size = loaded->header.data_size + out_stats->total_rom_size = header.const_size +
loaded->header.code_size; header.code_size;
out_stats->total_ram_size = loaded->header.bss_size; out_stats->total_ram_size = header.bss_size;
return CHIP32_BIN_OK;
} }
const char* chip32_binary_error_string(chip32_binary_error_t error) const char* chip32_binary_error_string(chip32_binary_error_t error)
@ -146,7 +144,7 @@ uint32_t chip32_binary_calculate_size(const chip32_binary_header_t* header)
} }
return sizeof(chip32_binary_header_t) + return sizeof(chip32_binary_header_t) +
header->data_size + header->const_size +
header->code_size + header->code_size +
header->init_data_size; header->init_data_size;
} }
@ -178,12 +176,12 @@ uint32_t chip32_binary_write(
offset += sizeof(chip32_binary_header_t); offset += sizeof(chip32_binary_header_t);
// Write DATA section // Write DATA section
if (header->data_size > 0) { if (header->const_size > 0) {
if (!data_section) { if (!data_section) {
return 0; // Data expected but NULL pointer return 0; // Data expected but NULL pointer
} }
memcpy(out_buffer + offset, data_section, header->data_size); memcpy(out_buffer + offset, data_section, header->const_size);
offset += header->data_size; offset += header->const_size;
} }
// Write CODE section // Write CODE section
@ -207,35 +205,6 @@ uint32_t chip32_binary_write(
return offset; return offset;
} }
// ============================================================================
// RAM INITIALIZATION HELPER
// ============================================================================
uint32_t chip32_binary_init_ram(
const chip32_loaded_binary_t* loaded,
uint8_t* ram_buffer,
uint32_t ram_size
)
{
if (!loaded || !ram_buffer) {
return 0;
}
// Check if binary has init data
if (loaded->header.init_data_size == 0 || !loaded->init_data_section) {
return 0;
}
// Copy init data to RAM (respect buffer limits)
uint32_t copy_size = loaded->header.init_data_size;
if (copy_size > ram_size) {
copy_size = ram_size; // Truncate if RAM is smaller
}
memcpy(ram_buffer, loaded->init_data_section, copy_size);
return copy_size;
}
// ============================================================================ // ============================================================================
// DEBUG/UTILITY FUNCTIONS // DEBUG/UTILITY FUNCTIONS
@ -260,7 +229,7 @@ void chip32_binary_print_header(const chip32_binary_header_t* header)
printf(" (has init data)"); printf(" (has init data)");
} }
printf("\n"); printf("\n");
printf("DATA section: %u bytes (ROM constants)\n", header->data_size); printf("DATA section: %u bytes (ROM constants)\n", header->const_size);
printf("BSS section: %u bytes (Total RAM: DV+DZ)\n", header->bss_size); printf("BSS section: %u bytes (Total RAM: DV+DZ)\n", header->bss_size);
printf("CODE section: %u bytes\n", header->code_size); printf("CODE section: %u bytes\n", header->code_size);
printf("Entry point: 0x%08X\n", header->entry_point); printf("Entry point: 0x%08X\n", header->entry_point);
@ -275,7 +244,7 @@ void chip32_binary_print_stats(const chip32_binary_stats_t* stats)
} }
printf("=== Chip32 Binary Statistics ===\n"); printf("=== Chip32 Binary Statistics ===\n");
printf("DATA section: %u bytes (ROM, initialized)\n", stats->data_size); printf("DATA section: %u bytes (ROM, initialized)\n", stats->const_size);
printf("BSS section: %u bytes (RAM, DV+DZ)\n", stats->bss_size); printf("BSS section: %u bytes (RAM, DV+DZ)\n", stats->bss_size);
printf("CODE section: %u bytes (ROM, executable)\n", stats->code_size); printf("CODE section: %u bytes (ROM, executable)\n", stats->code_size);
printf("Init data: %u bytes (RAM initialization)\n", stats->init_data_size); printf("Init data: %u bytes (RAM initialization)\n", stats->init_data_size);

View file

@ -37,6 +37,24 @@
* - Initial RAM values: DV values + zeros for DZ areas * - Initial RAM values: DV values + zeros for DZ areas
* - Size = sum of all DV and DZ declarations * - Size = sum of all DV and DZ declarations
* - Layout matches RAM layout exactly * - Layout matches RAM layout exactly
*
*
+--------------------------------------+
| Chip32 Header | <-- Début du fichier
| (Magic, Versions, Sizes, Entry...) |
+--------------------------------------+
| CONST Section (DV) | <-- Données initialisées
| (Variables globales initialisées) | e.g., const int x = 5;
+--------------------------------------+
| CODE Section | <-- Instructions du programme
| (Les opcodes et leurs opérandes) |
+--------------------------------------+
| DATA Section (Optional) | <-- Données pour l'initialisation de la RAM (copie de DV)
| (Contient les valeurs initiales pour la RAM)
+--------------------------------------+
*/ */
#ifndef CHIP32_BINARY_FORMAT_H #ifndef CHIP32_BINARY_FORMAT_H
@ -44,6 +62,7 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "chip32_vm.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -74,7 +93,7 @@ typedef struct {
uint32_t magic; // Magic number "C32\0" uint32_t magic; // Magic number "C32\0"
uint16_t version; // Format version uint16_t version; // Format version
uint16_t flags; // Feature flags uint16_t flags; // Feature flags
uint32_t data_size; // Size of DATA section in bytes (ROM constants) uint32_t const_size; // Size of DATA section in bytes (ROM constants)
uint32_t bss_size; // Total RAM size (DV + DZ) uint32_t bss_size; // Total RAM size (DV + DZ)
uint32_t code_size; // Size of CODE section in bytes uint32_t code_size; // Size of CODE section in bytes
uint32_t entry_point; // Entry point offset in CODE section uint32_t entry_point; // Entry point offset in CODE section
@ -82,18 +101,9 @@ typedef struct {
} chip32_binary_header_t; } chip32_binary_header_t;
#pragma pack(pop) #pragma pack(pop)
// Loaded binary structure
typedef struct {
chip32_binary_header_t header;
uint8_t* data_section; // Points to DATA section (ROM)
uint8_t* code_section; // Points to CODE section
uint8_t* init_data_section; // Points to INIT DATA (RAM initialization)
chip32_binary_error_t error;
} chip32_loaded_binary_t;
// Statistics // Statistics
typedef struct { typedef struct {
uint32_t data_size; // ROM constants uint32_t const_size; // ROM constants
uint32_t bss_size; // Total RAM needed uint32_t bss_size; // Total RAM needed
uint32_t code_size; // Executable code uint32_t code_size; // Executable code
uint32_t init_data_size; // RAM initialization data uint32_t init_data_size; // RAM initialization data
@ -114,20 +124,14 @@ typedef struct {
* @return Error code * @return Error code
*/ */
chip32_binary_error_t chip32_binary_load( chip32_binary_error_t chip32_binary_load(
chip32_ctx_t *ctx,
uint8_t* binary, uint8_t* binary,
uint32_t size, uint32_t binary_size,
chip32_loaded_binary_t* out_loaded uint8_t* ram,
uint32_t ram_size,
chip32_binary_stats_t *out_stats
); );
/**
* Get statistics from a loaded binary
* @param loaded Loaded binary structure
* @param out_stats Output statistics
*/
void chip32_binary_get_stats(
const chip32_loaded_binary_t* loaded,
chip32_binary_stats_t* out_stats
);
/** /**
* Get error string from error code * Get error string from error code
@ -156,7 +160,7 @@ uint32_t chip32_binary_calculate_size(const chip32_binary_header_t* header);
/** /**
* Write a complete binary to memory * Write a complete binary to memory
* @param header Binary header * @param header Binary header
* @param data_section DATA section content (can be NULL if data_size is 0) * @param data_section DATA section content (can be NULL if const_size is 0)
* @param code_section CODE section content (can be NULL if code_size is 0) * @param code_section CODE section content (can be NULL if code_size is 0)
* @param init_data_section INIT DATA section (can be NULL if init_data_size is 0) * @param init_data_section INIT DATA section (can be NULL if init_data_size is 0)
* @param out_buffer Output buffer (must be large enough) * @param out_buffer Output buffer (must be large enough)
@ -172,24 +176,6 @@ uint32_t chip32_binary_write(
uint32_t buffer_size uint32_t buffer_size
); );
// ============================================================================
// RAM INITIALIZATION HELPER
// ============================================================================
/**
* Initialize RAM from binary INIT DATA section
* This copies all initial values (DV) and zeros (DZ) to RAM
* @param loaded Loaded binary with init data
* @param ram_buffer Destination RAM buffer
* @param ram_size Size of RAM buffer
* @return Number of bytes copied, or 0 if no init data
*/
uint32_t chip32_binary_init_ram(
const chip32_loaded_binary_t* loaded,
uint8_t* ram_buffer,
uint32_t ram_size
);
// ============================================================================ // ============================================================================
// DEBUG/UTILITY FUNCTIONS // DEBUG/UTILITY FUNCTIONS
// ============================================================================ // ============================================================================

View file

@ -34,6 +34,7 @@ public:
m_syscallHandler = std::bind(&Machine::HandleSyscall, this, m_syscallHandler = std::bind(&Machine::HandleSyscall, this,
std::placeholders::_1, std::placeholders::_1,
std::placeholders::_2); std::placeholders::_2);
m_ram.resize(1024);
} }
// ======================================================================== // ========================================================================
@ -64,12 +65,15 @@ public:
result.Print(); result.Print();
// Load binary using new format // Load binary using executable format
chip32_loaded_binary_t loaded; chip32_binary_stats_t stats;
chip32_binary_error_t error = chip32_binary_load( chip32_binary_error_t error = chip32_binary_load(
&ctx,
program.data(), program.data(),
static_cast<uint32_t>(program.size()), static_cast<uint32_t>(program.size()),
&loaded m_ram.data(),
static_cast<uint32_t>(m_ram.size()),
&stats
); );
if (error != CHIP32_BIN_OK) { if (error != CHIP32_BIN_OK) {
@ -78,29 +82,6 @@ public:
return; return;
} }
// Allocate and initialize RAM
m_ram.resize(loaded.header.bss_size);
uint32_t init_bytes = chip32_binary_init_ram(&loaded, m_ram.data(), m_ram.size());
if (init_bytes > 0) {
std::cout << "RAM initialized: " << init_bytes << " bytes" << std::endl;
}
// Setup VM context
memset(&ctx, 0, sizeof(ctx));
ctx.stack_size = 512;
// ROM = DATA + CODE (contiguous in loaded binary)
ctx.rom.mem = loaded.data_section;
ctx.rom.addr = 0;
ctx.rom.size = loaded.header.data_size + loaded.header.code_size;
// RAM
ctx.ram.mem = m_ram.data();
ctx.ram.addr = ctx.rom.size;
ctx.ram.size = m_ram.size();
// Set syscall handler using wrapper // Set syscall handler using wrapper
ctx.syscall = SyscallWrapper; ctx.syscall = SyscallWrapper;
ctx.user_data = this; ctx.user_data = this;
@ -108,8 +89,6 @@ public:
// Initialize VM // Initialize VM
chip32_initialize(&ctx); chip32_initialize(&ctx);
// Set entry point (DATA size + entry point offset in CODE)
ctx.registers[PC] = loaded.header.data_size + loaded.header.entry_point;
std::cout << "Starting execution at PC=0x" << std::hex << ctx.registers[PC] std::cout << "Starting execution at PC=0x" << std::hex << ctx.registers[PC]
<< std::dec << std::endl; << std::dec << std::endl;
@ -281,14 +260,7 @@ public:
uint8_t *ram_buffer, uint8_t *ram_buffer,
uint32_t ram_size) uint32_t ram_size)
{ {
// Charger et valider le binaire
chip32_loaded_binary_t loaded;
chip32_binary_error_t err = chip32_binary_load(
binary.data(),
static_cast<uint32_t>(binary.size()),
&loaded
);
if (err != CHIP32_BIN_OK) if (err != CHIP32_BIN_OK)
{ {
std::cerr << "Binary load error: " << chip32_binary_error_string(err) << std::endl; std::cerr << "Binary load error: " << chip32_binary_error_string(err) << std::endl;

View file

@ -104,14 +104,14 @@ void chip32_initialize(chip32_ctx_t *ctx)
{ {
memset(ctx->ram.mem, 0, ctx->ram.size); memset(ctx->ram.mem, 0, ctx->ram.size);
memset(ctx->registers, 0, REGISTER_COUNT * sizeof(uint32_t)); memset(ctx->registers, 0, REGISTER_COUNT * sizeof(uint32_t));
ctx->instrCount = 0; ctx->instr_count = 0;
ctx->registers[SP] = ctx->ram.size; ctx->registers[SP] = ctx->ram.size;
} }
chip32_result_t chip32_run(chip32_ctx_t *ctx) chip32_result_t chip32_run(chip32_ctx_t *ctx)
{ {
chip32_result_t result = VM_OK; chip32_result_t result = VM_OK;
while ((ctx->max_instr == 0) || (ctx->instrCount < ctx->max_instr)) while ((ctx->max_instr == 0) || (ctx->instr_count < ctx->max_instr))
{ {
result = chip32_step(ctx); result = chip32_step(ctx);
@ -434,7 +434,7 @@ chip32_result_t chip32_step(chip32_ctx_t *ctx)
} }
ctx->registers[PC]++; ctx->registers[PC]++;
ctx->instrCount++; ctx->instr_count++;
return result; return result;
} }

View file

@ -208,7 +208,7 @@ struct chip32_ctx_t
virtual_mem_t rom; virtual_mem_t rom;
virtual_mem_t ram; virtual_mem_t ram;
uint16_t stack_size; uint16_t stack_size;
uint32_t instrCount; uint32_t instr_count;
uint16_t prog_size; uint16_t prog_size;
uint32_t max_instr; uint32_t max_instr;
uint32_t registers[REGISTER_COUNT]; uint32_t registers[REGISTER_COUNT];

View file

@ -363,7 +363,7 @@ TEST_CASE("Binary format validation")
REQUIRE(loaded.header.magic == CHIP32_MAGIC); REQUIRE(loaded.header.magic == CHIP32_MAGIC);
REQUIRE(loaded.header.version == CHIP32_VERSION); REQUIRE(loaded.header.version == CHIP32_VERSION);
REQUIRE((loaded.header.flags & CHIP32_FLAG_HAS_INIT_DATA) != 0); REQUIRE((loaded.header.flags & CHIP32_FLAG_HAS_INIT_DATA) != 0);
REQUIRE(loaded.header.data_size > 0); // Has ROM constants REQUIRE(loaded.header.const_size > 0); // Has ROM constants
REQUIRE(loaded.header.bss_size > 0); // Has RAM REQUIRE(loaded.header.bss_size > 0); // Has RAM
REQUIRE(loaded.header.code_size > 0); // Has code REQUIRE(loaded.header.code_size > 0); // Has code
REQUIRE(loaded.header.init_data_size == loaded.header.bss_size); // Must match REQUIRE(loaded.header.init_data_size == loaded.header.bss_size); // Must match

View file

@ -24,59 +24,37 @@ THE SOFTWARE.
#include <iostream> #include <iostream>
#include "catch.hpp" #include "catch.hpp"
#include "chip32_assembler.h" #include "chip32_machine.h" // Inclure chip32_machine.h au lieu de assembler et vm
#include "chip32_vm.h"
/* /*
Purpose: test all opcodes Purpose: test all opcodes
*/ */
void hexdump(void *ptr, int buflen); // Suppression des fonctions et classes de configuration de la VM
// qui sont maintenant encapsulées dans Chip32::Machine.
static uint8_t story_player_syscall(chip32_ctx_t *ctx, uint8_t code)
{
uint8_t retCode = SYSCALL_RET_OK;
return retCode;
}
class VmTestContext class VmTestContext
{ {
public: public:
VmTestContext() { VmTestContext() {
// La RAM est allouée et initialisée à l'intérieur de QuickExecute
// de la classe Machine. On peut laisser le constructeur vide.
} }
void Execute(const std::string &assemblyCode) void Execute(const std::string &assemblyCode)
{ {
// --------- BUILD BINARY --------- // Utiliser la méthode QuickExecute de Machine pour Parse, Build et Run
REQUIRE( assembler.Parse(assemblyCode) == true ); machine.QuickExecute(assemblyCode);
REQUIRE( assembler.BuildBinary(program, result) == true );
result.Print();
chip32_ctx.stack_size = 512; // Vérification de base: le parsing et le build doivent réussir
REQUIRE( machine.parseResult == true );
REQUIRE( machine.buildResult == true );
chip32_ctx.rom.mem = program.data(); // Vérification que l'exécution a fini normalement (HALT)
chip32_ctx.rom.addr = 18*1024; REQUIRE( machine.runResult == VM_FINISHED );
chip32_ctx.rom.size = program.size();
chip32_ctx.ram.mem = data;
chip32_ctx.ram.addr = 56 *1024,
chip32_ctx.ram.size = sizeof(data);
chip32_ctx.syscall = story_player_syscall;
chip32_initialize(&chip32_ctx);
chip32_result_t runResult = chip32_run(&chip32_ctx);
REQUIRE( runResult == VM_FINISHED );
} }
uint8_t data[8*1024]; Chip32::Machine machine; // Instance de la Machine à utiliser pour les tests
std::vector<uint8_t> program;
Chip32::Assembler assembler;
Chip32::Result result;
chip32_ctx_t chip32_ctx;
}; };
@ -89,7 +67,8 @@ TEST_CASE_METHOD(VmTestContext, "MUL", "[vm]") {
)"; )";
Execute(test1); Execute(test1);
uint32_t result = chip32_ctx.registers[R0]; // Accéder directement aux registres de la Machine pour vérifier le résultat
uint32_t result = machine.ctx.registers[R0];
REQUIRE (result == 37 * 0x695); REQUIRE (result == 37 * 0x695);
} }
@ -102,6 +81,7 @@ TEST_CASE_METHOD(VmTestContext, "DIV", "[vm]") {
)"; )";
Execute(test1); Execute(test1);
uint32_t result = chip32_ctx.registers[R0]; // Accéder directement aux registres de la Machine pour vérifier le résultat
uint32_t result = machine.ctx.registers[R0];
REQUIRE (result == (int)(37/8)); REQUIRE (result == (int)(37/8));
} }