From 49f510d2d60129526832bfcd9c0f4049962bc80e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20B=C3=B6hm?= Date: Mon, 18 May 2009 20:53:42 +0200 Subject: move stuff around and create initial source structure --- src/emu/risci.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 src/emu/risci.c (limited to 'src/emu/risci.c') diff --git a/src/emu/risci.c b/src/emu/risci.c new file mode 100644 index 0000000..8c4e30f --- /dev/null +++ b/src/emu/risci.c @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "asm.h" +#include "cpu.h" +#include "log.h" +#include "opc.h" + +bool is_debug = false; +bool is_interactive = false; + +/* global program buffer */ +uint8_t *P = NULL; + +static +void usage(int rc) +{ + fprintf(stderr, "Usage: risci [-dhi] \n"); + exit(rc); +} + +static +void signal_handler(int sig) +{ + 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; + } +} + +static +void read_program(const char *program) +{ + struct stat sb; + 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)); + + 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"); + + memset(P + sb.st_size, 0xFF, sizeof(uint32_t)); +} + +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)); + return tmp; +} + +int main(int argc, char *argv[]) +{ + int ch; + + while ((ch = getopt(argc, argv, "dhi")) != -1) { + switch (ch) { + case 'd': + is_debug = true; + break; + case 'h': + usage(EXIT_SUCCESS); + case 'i': + is_interactive = true; + break; + case '?': + default: + usage(EXIT_FAILURE); + } + } + + 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); + + read_program(argv[0]); + } + + /* reset program counter to first instruction */ + PC = 0; + + /* start instruction loop */ + while (1) { + execute(next_instruction()); + PC += 4; + } + + /* not reached, program is terminated by signal traps from the cpu */ +} -- cgit v1.2.3