mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
(WIP) new binary format
This commit is contained in:
parent
9ab7b9bb14
commit
c6da4b891a
10 changed files with 128 additions and 219 deletions
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
|
|
@ -73,7 +73,7 @@
|
|||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/core/tests/build/core_tests", // Remplacez par le chemin de votre exécutable
|
||||
"args": [],
|
||||
"args": ["[vm]"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}/core/tests/build",
|
||||
"environment": [],
|
||||
|
|
|
|||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
|
@ -109,7 +109,9 @@
|
|||
"serializers.h": "c",
|
||||
"ni_parser.h": "c",
|
||||
"*.m": "cpp",
|
||||
"*.inc": "cpp"
|
||||
"*.inc": "cpp",
|
||||
"chip32_binary_format.h": "c",
|
||||
"hash_map": "c"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -365,7 +365,7 @@ bool Assembler::BuildBinary(std::vector<uint8_t> &program, Result &result)
|
|||
// ========================================================================
|
||||
// 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> initDataSection; // DV values + DZ zeros (RAM init)
|
||||
|
||||
|
|
@ -471,10 +471,10 @@ bool Assembler::BuildBinary(std::vector<uint8_t> &program, Result &result)
|
|||
|
||||
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(),
|
||||
i.compiledArgs.end(),
|
||||
std::back_inserter(dataSection));
|
||||
std::back_inserter(constSection));
|
||||
|
||||
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_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.code_size = static_cast<uint32_t>(codeSection.size());
|
||||
header.entry_point = entryPoint;
|
||||
|
|
@ -530,7 +530,7 @@ bool Assembler::BuildBinary(std::vector<uint8_t> &program, Result &result)
|
|||
|
||||
uint32_t bytesWritten = chip32_binary_write(
|
||||
&header,
|
||||
dataSection.empty() ? nullptr : dataSection.data(),
|
||||
constSection.empty() ? nullptr : constSection.data(),
|
||||
codeSection.empty() ? nullptr : codeSection.data(),
|
||||
initDataSection.empty() ? nullptr : initDataSection.data(),
|
||||
program.data(),
|
||||
|
|
@ -548,8 +548,8 @@ bool Assembler::BuildBinary(std::vector<uint8_t> &program, Result &result)
|
|||
// PHASE 7: Remplir les statistiques
|
||||
// ========================================================================
|
||||
result.ramUsageSize = bssSize;
|
||||
result.romUsageSize = header.data_size + header.code_size;
|
||||
result.constantsSize = header.data_size;
|
||||
result.romUsageSize = header.const_size + header.code_size;
|
||||
result.constantsSize = header.const_size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_ctx_t *ctx,
|
||||
uint8_t* binary,
|
||||
uint32_t size,
|
||||
chip32_loaded_binary_t* out_loaded
|
||||
uint32_t binary_size,
|
||||
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;
|
||||
}
|
||||
|
||||
// Clear output structure
|
||||
memset(out_loaded, 0, sizeof(chip32_loaded_binary_t));
|
||||
|
||||
// Check minimum size
|
||||
if (size < sizeof(chip32_binary_header_t)) {
|
||||
out_loaded->error = CHIP32_BIN_ERR_TOO_SMALL;
|
||||
if (binary_size < sizeof(chip32_binary_header_t)) {
|
||||
return CHIP32_BIN_ERR_TOO_SMALL;
|
||||
}
|
||||
|
||||
// Copy header
|
||||
memcpy(&out_loaded->header, binary, sizeof(chip32_binary_header_t));
|
||||
memcpy(&header, binary, sizeof(chip32_binary_header_t));
|
||||
|
||||
// Verify magic number
|
||||
if (out_loaded->header.magic != CHIP32_MAGIC) {
|
||||
out_loaded->error = CHIP32_BIN_ERR_INVALID_MAGIC;
|
||||
if (header.magic != CHIP32_MAGIC) {
|
||||
return CHIP32_BIN_ERR_INVALID_MAGIC;
|
||||
}
|
||||
|
||||
// Check version
|
||||
if (out_loaded->header.version > CHIP32_VERSION) {
|
||||
out_loaded->error = CHIP32_BIN_ERR_UNSUPPORTED_VERSION;
|
||||
if (header.version > CHIP32_VERSION) {
|
||||
return CHIP32_BIN_ERR_UNSUPPORTED_VERSION;
|
||||
}
|
||||
|
||||
// Calculate expected size
|
||||
uint32_t expected_size = sizeof(chip32_binary_header_t) +
|
||||
out_loaded->header.data_size +
|
||||
out_loaded->header.code_size +
|
||||
out_loaded->header.init_data_size;
|
||||
header.const_size +
|
||||
header.code_size +
|
||||
header.init_data_size;
|
||||
|
||||
if (size != expected_size) {
|
||||
out_loaded->error = CHIP32_BIN_ERR_SIZE_MISMATCH;
|
||||
if (binary_size != expected_size) {
|
||||
return CHIP32_BIN_ERR_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
// Set section pointers
|
||||
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;
|
||||
}
|
||||
// Skip header for ROM executable (must start at a valide code address)
|
||||
ctx->rom.mem = binary + offset;
|
||||
ctx->rom.size = binary_size - offset;
|
||||
ctx->rom.addr = 0;
|
||||
|
||||
if (out_loaded->header.code_size > 0) {
|
||||
out_loaded->code_section = binary + offset;
|
||||
offset += out_loaded->header.code_size;
|
||||
}
|
||||
// RAM and ROM are in the same logical memory plane
|
||||
// So we set it begin after the ROM (why not)
|
||||
ctx->ram.mem = ram;
|
||||
ctx->ram.addr = ctx->rom.size;
|
||||
ctx->ram.size = ram_size;
|
||||
|
||||
if (out_loaded->header.init_data_size > 0) {
|
||||
out_loaded->init_data_section = binary + offset;
|
||||
}
|
||||
// Set entry point (DATA size + entry point offset in CODE)
|
||||
ctx->registers[PC] = header.entry_point;
|
||||
|
||||
out_loaded->error = CHIP32_BIN_OK;
|
||||
return CHIP32_BIN_OK;
|
||||
}
|
||||
// Load data initialized values
|
||||
const uint8_t *data = binary + header.code_size;
|
||||
memcpy(ram, data, header.init_data_size);
|
||||
|
||||
void chip32_binary_get_stats(
|
||||
const chip32_loaded_binary_t* loaded,
|
||||
chip32_binary_stats_t* out_stats
|
||||
)
|
||||
{
|
||||
if (!loaded || !out_stats) {
|
||||
return;
|
||||
}
|
||||
|
||||
out_stats->data_size = loaded->header.data_size;
|
||||
out_stats->bss_size = loaded->header.bss_size;
|
||||
out_stats->code_size = loaded->header.code_size;
|
||||
out_stats->init_data_size = loaded->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) +
|
||||
loaded->header.data_size +
|
||||
loaded->header.code_size +
|
||||
loaded->header.init_data_size;
|
||||
header.const_size +
|
||||
header.code_size +
|
||||
header.init_data_size;
|
||||
|
||||
out_stats->total_rom_size = loaded->header.data_size +
|
||||
loaded->header.code_size;
|
||||
out_stats->total_rom_size = header.const_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)
|
||||
|
|
@ -146,7 +144,7 @@ uint32_t chip32_binary_calculate_size(const chip32_binary_header_t* header)
|
|||
}
|
||||
|
||||
return sizeof(chip32_binary_header_t) +
|
||||
header->data_size +
|
||||
header->const_size +
|
||||
header->code_size +
|
||||
header->init_data_size;
|
||||
}
|
||||
|
|
@ -178,12 +176,12 @@ uint32_t chip32_binary_write(
|
|||
offset += sizeof(chip32_binary_header_t);
|
||||
|
||||
// Write DATA section
|
||||
if (header->data_size > 0) {
|
||||
if (header->const_size > 0) {
|
||||
if (!data_section) {
|
||||
return 0; // Data expected but NULL pointer
|
||||
}
|
||||
memcpy(out_buffer + offset, data_section, header->data_size);
|
||||
offset += header->data_size;
|
||||
memcpy(out_buffer + offset, data_section, header->const_size);
|
||||
offset += header->const_size;
|
||||
}
|
||||
|
||||
// Write CODE section
|
||||
|
|
@ -207,35 +205,6 @@ uint32_t chip32_binary_write(
|
|||
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
|
||||
|
|
@ -260,7 +229,7 @@ void chip32_binary_print_header(const chip32_binary_header_t* header)
|
|||
printf(" (has init data)");
|
||||
}
|
||||
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("CODE section: %u bytes\n", header->code_size);
|
||||
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("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("CODE section: %u bytes (ROM, executable)\n", stats->code_size);
|
||||
printf("Init data: %u bytes (RAM initialization)\n", stats->init_data_size);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,24 @@
|
|||
* - Initial RAM values: DV values + zeros for DZ areas
|
||||
* - Size = sum of all DV and DZ declarations
|
||||
* - 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
|
||||
|
|
@ -44,6 +62,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "chip32_vm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -74,7 +93,7 @@ typedef struct {
|
|||
uint32_t magic; // Magic number "C32\0"
|
||||
uint16_t version; // Format version
|
||||
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 code_size; // Size of CODE section in bytes
|
||||
uint32_t entry_point; // Entry point offset in CODE section
|
||||
|
|
@ -82,18 +101,9 @@ typedef struct {
|
|||
} chip32_binary_header_t;
|
||||
#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
|
||||
typedef struct {
|
||||
uint32_t data_size; // ROM constants
|
||||
uint32_t const_size; // ROM constants
|
||||
uint32_t bss_size; // Total RAM needed
|
||||
uint32_t code_size; // Executable code
|
||||
uint32_t init_data_size; // RAM initialization data
|
||||
|
|
@ -114,21 +124,15 @@ typedef struct {
|
|||
* @return Error code
|
||||
*/
|
||||
chip32_binary_error_t chip32_binary_load(
|
||||
chip32_ctx_t *ctx,
|
||||
uint8_t* binary,
|
||||
uint32_t size,
|
||||
chip32_loaded_binary_t* out_loaded
|
||||
);
|
||||
|
||||
/**
|
||||
* 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,
|
||||
uint32_t binary_size,
|
||||
uint8_t* ram,
|
||||
uint32_t ram_size,
|
||||
chip32_binary_stats_t *out_stats
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Get error string from error code
|
||||
* @param error Error code
|
||||
|
|
@ -156,7 +160,7 @@ uint32_t chip32_binary_calculate_size(const chip32_binary_header_t* header);
|
|||
/**
|
||||
* Write a complete binary to memory
|
||||
* @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 init_data_section INIT DATA section (can be NULL if init_data_size is 0)
|
||||
* @param out_buffer Output buffer (must be large enough)
|
||||
|
|
@ -172,24 +176,6 @@ uint32_t chip32_binary_write(
|
|||
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
|
||||
// ============================================================================
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ public:
|
|||
m_syscallHandler = std::bind(&Machine::HandleSyscall, this,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2);
|
||||
m_ram.resize(1024);
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
|
|
@ -64,12 +65,15 @@ public:
|
|||
|
||||
result.Print();
|
||||
|
||||
// Load binary using new format
|
||||
chip32_loaded_binary_t loaded;
|
||||
// Load binary using executable format
|
||||
chip32_binary_stats_t stats;
|
||||
chip32_binary_error_t error = chip32_binary_load(
|
||||
&ctx,
|
||||
program.data(),
|
||||
static_cast<uint32_t>(program.size()),
|
||||
&loaded
|
||||
m_ram.data(),
|
||||
static_cast<uint32_t>(m_ram.size()),
|
||||
&stats
|
||||
);
|
||||
|
||||
if (error != CHIP32_BIN_OK) {
|
||||
|
|
@ -78,29 +82,6 @@ public:
|
|||
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
|
||||
ctx.syscall = SyscallWrapper;
|
||||
ctx.user_data = this;
|
||||
|
|
@ -108,8 +89,6 @@ public:
|
|||
// Initialize VM
|
||||
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::dec << std::endl;
|
||||
|
|
@ -281,13 +260,6 @@ public:
|
|||
uint8_t *ram_buffer,
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -104,14 +104,14 @@ void chip32_initialize(chip32_ctx_t *ctx)
|
|||
{
|
||||
memset(ctx->ram.mem, 0, ctx->ram.size);
|
||||
memset(ctx->registers, 0, REGISTER_COUNT * sizeof(uint32_t));
|
||||
ctx->instrCount = 0;
|
||||
ctx->instr_count = 0;
|
||||
ctx->registers[SP] = ctx->ram.size;
|
||||
}
|
||||
|
||||
chip32_result_t chip32_run(chip32_ctx_t *ctx)
|
||||
{
|
||||
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);
|
||||
|
||||
|
|
@ -434,7 +434,7 @@ chip32_result_t chip32_step(chip32_ctx_t *ctx)
|
|||
}
|
||||
|
||||
ctx->registers[PC]++;
|
||||
ctx->instrCount++;
|
||||
ctx->instr_count++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ struct chip32_ctx_t
|
|||
virtual_mem_t rom;
|
||||
virtual_mem_t ram;
|
||||
uint16_t stack_size;
|
||||
uint32_t instrCount;
|
||||
uint32_t instr_count;
|
||||
uint16_t prog_size;
|
||||
uint32_t max_instr;
|
||||
uint32_t registers[REGISTER_COUNT];
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ TEST_CASE("Binary format validation")
|
|||
REQUIRE(loaded.header.magic == CHIP32_MAGIC);
|
||||
REQUIRE(loaded.header.version == CHIP32_VERSION);
|
||||
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.code_size > 0); // Has code
|
||||
REQUIRE(loaded.header.init_data_size == loaded.header.bss_size); // Must match
|
||||
|
|
|
|||
|
|
@ -24,59 +24,37 @@ THE SOFTWARE.
|
|||
|
||||
#include <iostream>
|
||||
#include "catch.hpp"
|
||||
#include "chip32_assembler.h"
|
||||
#include "chip32_vm.h"
|
||||
#include "chip32_machine.h" // Inclure chip32_machine.h au lieu de assembler et vm
|
||||
|
||||
/*
|
||||
Purpose: test all opcodes
|
||||
*/
|
||||
|
||||
void hexdump(void *ptr, int buflen);
|
||||
|
||||
static uint8_t story_player_syscall(chip32_ctx_t *ctx, uint8_t code)
|
||||
{
|
||||
uint8_t retCode = SYSCALL_RET_OK;
|
||||
|
||||
return retCode;
|
||||
}
|
||||
|
||||
// Suppression des fonctions et classes de configuration de la VM
|
||||
// qui sont maintenant encapsulées dans Chip32::Machine.
|
||||
|
||||
class VmTestContext
|
||||
{
|
||||
public:
|
||||
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)
|
||||
{
|
||||
// --------- BUILD BINARY ---------
|
||||
REQUIRE( assembler.Parse(assemblyCode) == true );
|
||||
REQUIRE( assembler.BuildBinary(program, result) == true );
|
||||
result.Print();
|
||||
// Utiliser la méthode QuickExecute de Machine pour Parse, Build et Run
|
||||
machine.QuickExecute(assemblyCode);
|
||||
|
||||
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();
|
||||
chip32_ctx.rom.addr = 18*1024;
|
||||
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 );
|
||||
// Vérification que l'exécution a fini normalement (HALT)
|
||||
REQUIRE( machine.runResult == VM_FINISHED );
|
||||
}
|
||||
|
||||
uint8_t data[8*1024];
|
||||
std::vector<uint8_t> program;
|
||||
Chip32::Assembler assembler;
|
||||
Chip32::Result result;
|
||||
chip32_ctx_t chip32_ctx;
|
||||
Chip32::Machine machine; // Instance de la Machine à utiliser pour les tests
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -89,7 +67,8 @@ TEST_CASE_METHOD(VmTestContext, "MUL", "[vm]") {
|
|||
)";
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -102,6 +81,7 @@ TEST_CASE_METHOD(VmTestContext, "DIV", "[vm]") {
|
|||
)";
|
||||
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));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue