rvemu

RISC-V RV32I execution engine
git clone git://mcdim.xyz/revemu.git
Log | Files | Refs

commit 4f6ec22e8cb9e98e786ab20e830f52cf1042e019
parent feb123c9c5c8b0cdcee6cb11bcf14344a44adf98
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date:   Mon,  7 Sep 2026 10:59:35 +0300

Optional readline in dbg, new makefile

Diffstat:
MMakefile | 30+++++++++++++++++++++---------
Mmain.c | 56+++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,13 +1,25 @@ -all: - gcc -g main.c exec.c disasm.c \ - -Wall -Wextra -Wpedantic \ - -Wconversion -Wsign-conversion \ - -Wshadow -Wstrict-prototypes \ - -Wmissing-prototypes -Wformat=2 +CC=gcc +CPPFLAGS= +CFLAGS= -g -Wall -Wextra -Wpedantic \ + -Wconversion -Wsign-conversion \ + -Wshadow -Wstrict-prototypes \ + -Wmissing-prototypes -Wformat=2 +LFLAGS= + +ifeq ($(READLINE),1) + CPPFLAGS += -DHAVE_READLINE + LFLAGS += -lreadline +endif -test: - gcc -g rtests.c exec.c disasm.c \ - -Wall -Wextra -Wpedantic \ + +CFLAGS= -lreadline \ + -g -Wall -Wextra -Wpedantic \ -Wconversion -Wsign-conversion \ -Wshadow -Wstrict-prototypes \ -Wmissing-prototypes -Wformat=2 + +emu: exec.c exec.h disasm.c disasm.h trap.h mem.h main.c + $(CC) $(CPPFLAGS) $(CFLAGS) main.c exec.c disasm.c $(LFLAGS) -o $@ + +test: exec.c exec.h disasm.c disasm.h trap.h mem.h rtests.c test.h + $(CC) $(CFLAGS) rtests.c exec.c disasm.c -o $@ diff --git a/main.c b/main.c @@ -4,6 +4,11 @@ #include <stdlib.h> #include <string.h> +#ifdef HAVE_READLINE +#include <readline/history.h> +#include <readline/readline.h> +#endif + //#include "disasm.h" #include "exec.h" #include "mem.h" @@ -17,7 +22,7 @@ typedef enum { static void load_program(uint8_t *mem) { - /* program */ + /* PROGRAM */ uint32_t arr[] = { 0x10000593, //li a1,256 0xfff00513, //li a0,-1 @@ -38,6 +43,13 @@ load_program(uint8_t *mem) 0x0085a503, //lw a0,8(a1) 0x00000593, //li a1,0 0x00100073 //ebreak +/* + 0x20400093, // addi x1,x0,0x204 + 0x12300113, // addi x2,x0,0x123 + 0xfe20ae23, // sw x2,-4(x1) -> address 0x200 + 0xffc0a183, // lw x3,-4(x1) + 0x00100073, // ebreak +*/ }; size_t len = sizeof(arr) / sizeof(arr[0]); @@ -99,12 +111,27 @@ trap_handler(cpu_state_t *cpu) static emu_mode_t debugger(cpu_state_t *cpu, uint8_t *mem) { +#ifdef HAVE_READLINE + char prompt[10]; + snprintf(prompt, 10, "PC 0x%x>", cpu->pc); + char *line; + line = readline(prompt); + rl_bind_key('\t', rl_complete); + + if (!line) { + free(line); + return MODE_STEP; + } + + add_history(line); +#else printf("PC 0x%x>", cpu->pc); char line[256]; if (!fgets(line, sizeof(line), stdin)) { fprintf(stderr, "Error reading" "interactive input\n"); } +#endif if (strncmp(line, "s", 1) == 0 || strncmp(line, "step", 4) == 0 || @@ -123,10 +150,23 @@ debugger(cpu_state_t *cpu, uint8_t *mem) for (int i=0; i<32; i++) { printf("x%d: 0x%x\n", i, cpu->x[i]); } - } else if (strncmp(line, "m", 1) == 0 || - strncmp(line, "memory", 6) == 0) { - printf("Memory:\n"); - for (uint32_t i=0; i<0x110; i+=4) { + } else if (strncmp(line, "x", 1) == 0) { + uint32_t from_addr = 0; + uint32_t count = 1; + sscanf(line, "x/%" SCNu32 " %" SCNx32, &count, &from_addr); + + uint32_t xtarget = count*4 + from_addr; + /* TODO: probably some kind or helper or something */ +/* if (xtarget+3 > MEMSIZE) { + printf("Out of bounds\n"); +#ifdef HAVE_READLINE + free(line); +#endif + return MODE_RUN; + } +*/ + + for (uint32_t i=from_addr; i<xtarget; i+=4) { if (cpu->pc == i) { printf("-> "); } else { @@ -141,9 +181,15 @@ debugger(cpu_state_t *cpu, uint8_t *mem) printf("Instruction poiter:\n"); printf("PC: %" PRIu32 "\n", cpu->pc); } else if (strncmp(line, "e", 1) == 0) { +#ifdef HAVE_READLINE + free(line); +#endif return MODE_RUN; } +#ifdef HAVE_READLINE + free(line); +#endif return MODE_STEP; }