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:
| M | Makefile | | | 30 | +++++++++++++++++++++--------- |
| M | main.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;
}