spl

systems programming language
git clone http://frotz.net/git/spl.git
Log | Files | Refs | README | LICENSE

commit 135b4f4aa84f8a7a5f27683899c48e951f32dede
parent 016d9275bc810ebc79378363fd100aa521c3e664
Author: Brian Swetland <swetland@frotz.net>
Date:   Sun, 29 Jun 2025 11:41:39 -0700

sr32emu: accept test vector files

The -x option causes the emulator to read test vectors from a file.

Lines with //< contain input data and lines with //> contain output data.

Reads from io address -1 will return the input data (or abort execution
if it is exhausted).

Writes to io address -1 will abort execution if they do not match the
provided output data.

Diffstat:
Msoftrisc32/src/sr32emu.c | 73++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 66 insertions(+), 7 deletions(-)

diff --git a/softrisc32/src/sr32emu.c b/softrisc32/src/sr32emu.c @@ -9,6 +9,15 @@ #include "sr32emu.h" +#define MAXDATA 1024 +uint32_t indata[MAXDATA]; +uint32_t incount = 0; +uint32_t innext = 0; + +uint32_t outdata[MAXDATA]; +uint32_t outcount = 0; +uint32_t outnext = 0; + #define RAMSIZE (8*1024*1024) #define RAMMASK8 (RAMSIZE - 1) #define RAMMASK32 (RAMMASK8 & (~3)) @@ -36,11 +45,29 @@ void mem_wr8(uint32_t addr, uint32_t val) { } uint32_t io_rd32(uint32_t addr) { + if (addr == -1) { + if (innext == incount) { + fprintf(stderr, "FAIL: input data exhausted\n"); + exit(1); + } + return indata[innext++]; + } return 0; } void io_wr32(uint32_t addr, uint32_t val) { - fprintf(stderr,"IO %08x -> %08x\n", val, addr); + if (addr == -1) { + if (outnext == outcount) { + fprintf(stderr, "FAIL: output data overrun\n"); + exit(1); + } + uint32_t data = outdata[outnext++]; + if (data != val) { + fprintf(stderr, "FAIL: output data %08x should be %08x\n", val, data); + exit(1); + } + } + //fprintf(stderr,"IO %08x -> %08x\n", val, addr); } void do_syscall(CpuState *s, uint32_t n) { @@ -52,13 +79,13 @@ void do_undef(CpuState *s, uint32_t ins) { } void load_hex_image(const char* fn) { + char line[1024]; FILE *fp = fopen(fn, "r"); if (fp == NULL) { fprintf(stderr, "emu: cannot open: %s\n", fn); exit(1); } - char line[256]; - while (fgets(line, 256, fp) != NULL) { + while (fgets(line, sizeof(line), fp) != NULL) { if ((line[0] == '#') || (line[0] == '/')) { continue; } @@ -71,15 +98,48 @@ void load_hex_image(const char* fn) { fclose(fp); } +void load_test_data(const char *fn) { + char line[1024]; + FILE *fp = fopen(fn, "r"); + if (fp == NULL) { + fprintf(stderr, "emu: cannot open: %s\n", fn); + exit(1); + } + while (fgets(line, sizeof(line), fp) != NULL) { + char *x; + uint32_t n; + if ((x = strstr(line, "//>"))) { + n = strtoul(x + 3, 0, 0); + outdata[outcount++] = n; + } + if ((x = strstr(line, "//<"))) { + n = strtoul(x + 3, 0, 0); + indata[incount++] = n; + } + } + fclose(fp); +} + +void usage(int status) { + fprintf(stderr, + "usage: emu <options> <image.hex> <arguments>\n" + "options: -x <testdata>\n"); + exit(status); +} + int main(int argc, char** argv) { CpuState cs; uint32_t entry = 0x100000; const char* fn = NULL; int args = 0; - while (argc > 1) { - if (argv[1][0] == '-') { + if (!strcmp(argv[1], "-x")) { + if (argc < 3) usage(1); + load_test_data(argv[2]); + argc--; + argv++; + } else if (argv[1][0] == '-') { fprintf(stderr, "emu: unknown option: %s\n", argv[1]); return -1; } else { @@ -93,8 +153,7 @@ int main(int argc, char** argv) { argv++; } if (fn == NULL) { - fprintf(stderr, "usage: emu <options> <image.hex> <arguments>\n"); - return -1; + usage(1); } memset(&cs, 0, sizeof(cs));