diff options
Diffstat (limited to 'src/emu/risci.c')
-rw-r--r-- | src/emu/risci.c | 89 |
1 files changed, 36 insertions, 53 deletions
diff --git a/src/emu/risci.c b/src/emu/risci.c index 8c4e30f..704ece8 100644 --- a/src/emu/risci.c +++ b/src/emu/risci.c @@ -1,9 +1,11 @@ #include <unistd.h> #include <stdlib.h> #include <stdint.h> +#include <inttypes.h> #include <stdbool.h> #include <stdio.h> #include <signal.h> +#include <assert.h> #include <fcntl.h> #include <sys/stat.h> #include <readline/readline.h> @@ -11,13 +13,12 @@ #include "asm.h" #include "cpu.h" #include "log.h" +#include "mem.h" #include "opc.h" bool is_debug = false; -bool is_interactive = false; - -/* global program buffer */ -uint8_t *P = NULL; +size_t mem_size = 64 * 1024 * 1024; +size_t reg_size = 0; static void usage(int rc) @@ -27,27 +28,11 @@ void usage(int rc) } static -void signal_handler(int sig) +void dump_registers(void) { - switch (sig) { - case SIGILL: - /* SIGILL is raised by the cpu for an unknown instruction */ - error("ERROR: illegal instruction."); - if (!is_interactive) - exit(-1); - break; - case SIGSEGV: - /* SIGSEGV is raised for unaligned memory access */ - error("ERROR: unaligned memory access."); - if (!is_interactive) - exit(-1); - break; - case SIGFPE: - /* SIGFPE is raised by devision with zero */ - error("ERROR: division by zero."); - exit(-1); - break; - } + fprintf(stderr, "REGISTER DUMP:\n"); + for (size_t i = 0; i < reg_size; i++) + fprintf(stderr, "\tr%zu = %"PRIu32"\n", i, GPR[i]); } static @@ -57,31 +42,34 @@ void read_program(const char *program) if (lstat(program, &sb) == -1) pdie("cannot stat program"); - if (sb.st_size % sizeof(uint32_t)) - die("program does not align to op-code size of %u bytes", sizeof(uint32_t)); + if (sb.st_size % 4) + die("program does not align to op-code size of 4 bytes"); int pfd; if ((pfd = open(program, O_RDONLY)) == -1) pdie("could not open program"); - P = malloc(sb.st_size + sizeof(uint32_t)); - if (read(pfd, P, sb.st_size) != sb.st_size) - die("premature end of program"); + /* initialize register file */ + assert(read(pfd, ®_size, 4) == 4); + reg_size += 4; + GPR = calloc(reg_size, 4); - memset(P + sb.st_size, 0xFF, sizeof(uint32_t)); + /* initialize pseudo registers */ + BP = reg_size - 3; + SP = reg_size - 2; + RV = reg_size - 1; + GPR[BP] = GPR[SP] = mem_size; + GPR[RV] = 0; + + assert(read(pfd, MEM, sb.st_size - 4) == sb.st_size - 4); + memset(MEM + sb.st_size + 4, 0xFF, 4); } static uint32_t next_instruction(void) { - if (is_interactive) { - /* read next instruction from stdin */ - printf("%03d", PC/4); - return compile(readline("> ")); - } - uint32_t tmp; - memcpy(&tmp, &P[PC], sizeof(uint32_t)); + memcpy(&tmp, &MEM[IP], 4); return tmp; } @@ -89,15 +77,15 @@ int main(int argc, char *argv[]) { int ch; - while ((ch = getopt(argc, argv, "dhi")) != -1) { + while ((ch = getopt(argc, argv, "dhm")) != -1) { switch (ch) { case 'd': is_debug = true; break; case 'h': usage(EXIT_SUCCESS); - case 'i': - is_interactive = true; + case 'm': + mem_size = atoi(optarg) * 4; break; case '?': default: @@ -108,26 +96,21 @@ int main(int argc, char *argv[]) argc -= optind; argv += optind; - /* catch cpu signal traps */ - signal(SIGILL, signal_handler); - signal(SIGFPE, signal_handler); - signal(SIGSEGV, signal_handler); - - /* load program from file if we're not in interactive mode */ - if (!is_interactive) { - if (argc < 1) - usage(EXIT_FAILURE); + /* reserve memory */ + MEM = calloc(mem_size, sizeof(char)); - read_program(argv[0]); - } + /* load program from file */ + if (argc < 1) + usage(EXIT_FAILURE); + read_program(argv[0]); /* reset program counter to first instruction */ - PC = 0; + IP = 0; /* start instruction loop */ while (1) { + //dump_registers(); execute(next_instruction()); - PC += 4; } /* not reached, program is terminated by signal traps from the cpu */ |