commit 57175a27ad794a246459b553a67f153384079ed4
parent 87d70f6cf0840c340bf35fe8fc794e2ce1150d85
Author: Brian Swetland <swetland@frotz.net>
Date: Wed, 4 Mar 2020 16:47:11 -0800
r5e: features!
- make tracing optional (-t)
- allow loading image from file
- provide exit and printhex io devices
Diffstat:
4 files changed, 59 insertions(+), 13 deletions(-)
diff --git a/src/r5e.c b/src/r5e.c
@@ -1,21 +1,59 @@
#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
#include "risc5emu.h"
uint32_t data[] = {
- 0x40000030, // mov r0, 0x40
+ 0x4000FFD2, // mov r0, 0xFFD2
0x51000100, // mov r1, 0xffff0100
0xA0100000, // sw r0, [r1, 0]
0xE7FFFFFE, // b -3
};
int main(int argc, char** argv) {
- risc_t *r = risc_new();
+ bool trace = false;
+ const char* fn = NULL;
- for (unsigned n = 0; n < sizeof(data); n += 4) {
- risc_store_word(r, n, data[n/4]);
+ while (argc > 1) {
+ if (!strcmp(argv[1], "-t")) {
+ trace = true;
+ } else if (argv[1][0] == '-') {
+ fprintf(stderr, "r5e: unknown option: %s\n", argv[1]);
+ return -1;
+ } else {
+ if (fn != NULL) {
+ fprintf(stderr, "r5e: multiple images not supported\n");
+ return -1;
+ }
+ fn = argv[1];
+ }
+ argc--;
+ argv++;
}
- risc_run(r, 100);
+ risc_t *r = risc_new(trace);
+
+ if (fn == NULL) {
+ for (unsigned n = 0; n < sizeof(data); n += 4) {
+ risc_store_word(r, n, data[n/4]);
+ }
+ } else {
+ int fd = open(fn, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "r5e: cannot open: %s\n", fn);
+ return -1;
+ }
+ unsigned n = 0;
+ uint32_t w;
+ while (read(fd, &w, sizeof(w)) == 4) {
+ risc_store_word(r, n, w);
+ n += 4;
+ }
+ fprintf(stderr,"r5e: loaded %u bytes from '%s'\n", n, fn);
+ }
+
+ risc_run(r, 100000);
return 0;
}
diff --git a/src/risc5emu.c b/src/risc5emu.c
@@ -48,6 +48,7 @@ struct RISC {
uint32_t *RAM;
uint32_t mem_size;
+ bool TRACE;
};
enum {
@@ -60,10 +61,11 @@ enum {
static uint32_t risc_load_io(struct RISC *risc, uint32_t address);
static void risc_store_io(struct RISC *risc, uint32_t address, uint32_t value);
-struct RISC *risc_new() {
+struct RISC *risc_new(bool trace) {
struct RISC *risc = calloc(1, sizeof(*risc));
risc->mem_size = DefaultMemSize;
risc->RAM = calloc(1, risc->mem_size);
+ risc->TRACE = trace;
risc_reset(risc);
return risc;
}
@@ -92,7 +94,7 @@ void risc_single_step(struct RISC *risc) {
return;
}
- disasm(risc->PC << 2, ir);
+ if (risc->TRACE) disasm(risc->PC << 2, ir);
risc->PC++;
const uint32_t pbit = 0x80000000;
@@ -289,7 +291,7 @@ void risc_single_step(struct RISC *risc) {
}
void risc_set_register(struct RISC *risc, int reg, uint32_t value) {
- printf(" R%d = 0x%08x\n", reg, value);
+ if (risc->TRACE) printf(" R%d = 0x%08x\n", reg, value);
risc->R[reg] = value;
risc->Z = value == 0;
risc->N = (int32_t)value < 0;
@@ -310,7 +312,7 @@ uint8_t risc_load_byte(struct RISC *risc, uint32_t address) {
void risc_store_word(struct RISC *risc, uint32_t address, uint32_t value) {
if (address < risc->mem_size) {
- printf(" mem@ 0x%08x = 0x%08x\n", address, value);
+ if (risc->TRACE) printf(" mem@ 0x%08x = 0x%08x\n", address, value);
risc->RAM[address/4] = value;
} else {
risc_store_io(risc, address, value);
@@ -334,11 +336,15 @@ static uint32_t risc_load_io(struct RISC *risc, uint32_t address) {
}
static void risc_store_io(struct RISC *risc, uint32_t address, uint32_t value) {
- printf(" io@ 0x%08x = 0x%08x\n", address, value);
+ if (risc->TRACE) printf(" io@ 0x%08x = 0x%08x\n", address, value);
switch (address - IOStart) {
case 0x100: {
- unsigned char x = value;
- write(1, &x, 1);
+ printf("%08x\nEXIT\n", value);
+ exit(0);
+ break;
+ case 0x104:
+ printf("%08x\n", value);
+ break;
}
}
}
diff --git a/src/risc5emu.h b/src/risc5emu.h
@@ -1,9 +1,10 @@
#include <stdint.h>
+#include <stdbool.h>
typedef struct RISC risc_t;
-struct RISC *risc_new();
+struct RISC *risc_new(bool trace);
void risc_reset(struct RISC *risc);
void risc_run(struct RISC *risc, int cycles);
diff --git a/src/risc5ins.txt b/src/risc5ins.txt
@@ -31,3 +31,4 @@
1101CCCC--------------------cccc bl%C %c
1110CCCCBBBBBBBBBBBBBBBBBBBBBBBB b%C %B
1111CCCCBBBBBBBBBBBBBBBBBBBBBBBB bl%C %B
+-------------------------------- inval