From b9dd0160640adcbb1b5a66247b274bf99a7de705 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Sun, 12 May 2024 01:26:32 +0200 Subject: First real program running! --- emulator/main.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++---------- main.asm | 23 ++++++++++++++++++----- 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/emulator/main.c b/emulator/main.c index d48c049..ed875a3 100644 --- a/emulator/main.c +++ b/emulator/main.c @@ -216,6 +216,8 @@ struct Hart { uint32_t pc; uint32_t regs[32]; + char* mem; + uint32_t mem_size; }; void execute_op_imm(struct Hart* hart, uint32_t instruction) @@ -334,24 +336,61 @@ void execute_branch(struct Hart* hart, uint32_t instruction) } } -uint32_t load_byte(struct Hart* hart, uint32_t address) +inline uint32_t load_size(struct Hart* hart, uint32_t address, uint32_t size) { + if ((address & 0x80000000) == 0) + { + assert(address + size < hart->mem_size); + uint32_t value = 0; + memcpy(&value, hart->mem + address, size); + return value; + } + return 0; } +uint32_t load_byte(struct Hart* hart, uint32_t address) +{ + return load_size(hart, address, 1); +} + uint32_t load_half(struct Hart* hart, uint32_t address) { - return 0; + return load_size(hart, address, 2); } uint32_t load_word(struct Hart* hart, uint32_t address) { - return 0; + return load_size(hart, address, 4); } -void store_byte(struct Hart* hart, uint32_t address, uint8_t value) {} -void store_half(struct Hart* hart, uint32_t address, uint16_t value) {} -void store_word(struct Hart* hart, uint32_t address, uint32_t value) {} +inline void store_size(struct Hart* hart, uint32_t address, uint32_t value, uint32_t size) +{ + if ((address & 0x80000000) == 0) + { + assert(address + size < hart->mem_size); + memcpy(hart->mem + address, &value, size); + } + else if (address == 0x80000000) + { + fwrite(&value, 1, size, stdout); + } +} + +void store_byte(struct Hart* hart, uint32_t address, uint8_t value) +{ + store_size(hart, address, value, 1); +} + +void store_half(struct Hart* hart, uint32_t address, uint16_t value) +{ + store_size(hart, address, value, 2); +} + +void store_word(struct Hart* hart, uint32_t address, uint32_t value) +{ + store_size(hart, address, value, 4); +} void execute_op_load(struct Hart* hart, uint32_t instruction) { @@ -786,14 +825,13 @@ int main(int argc, char* argv[]) struct Hart hart = {0}; hart.pc = start_address; + hart.mem = mem; + hart.mem_size = mem_size; while (true) { - uint32_t instruction = *(uint32_t*)(mem + hart.pc); + uint32_t instruction = load_word(&hart, hart.pc); execute(&hart, instruction); - printf("pc=%x x1=%d x2=%d x3=%d x4=%d\n", - hart.pc, hart.regs[1], hart.regs[2], hart.regs[3], hart.regs[4]); - fgetc(stdout); } return EXIT_SUCCESS; diff --git a/main.asm b/main.asm index e90d6a2..2d41e48 100644 --- a/main.asm +++ b/main.asm @@ -1,9 +1,22 @@ .section .text .global _main + +print: + li t1, 0x80000000 +l0: + lb t0, 0(a0) + beqz t0, l1 + sb t0, 0(t1) + addi a0, a0, 1 + j l0 +l1: + ret + _main: - li x1, 5 - addi x2, x1, 45 + la a0, my_str + call print + +halt: j halt -loop: - addi x2, x2, 1 - j loop +.section .rodata +my_str: .string "Hello, world!\n" -- cgit