From 5b70a9e547c0119097844dad717a71d4b3e4fcc0 Mon Sep 17 00:00:00 2001 From: Erick Date: Mon, 7 Feb 2022 15:04:29 +0100 Subject: [PATCH] split files for better overall performance --- src/lc3_lib.c | 126 +++++++++++++++++++++++++ src/lc3_lib.h | 32 +++++++ src/{includes.h => preprocessor.h} | 13 ++- src/{registers.h => registers.c} | 0 src/tyvm.c | 143 +---------------------------- 5 files changed, 173 insertions(+), 141 deletions(-) create mode 100644 src/lc3_lib.c create mode 100644 src/lc3_lib.h rename src/{includes.h => preprocessor.h} (63%) rename src/{registers.h => registers.c} (100%) diff --git a/src/lc3_lib.c b/src/lc3_lib.c new file mode 100644 index 0000000..10a47f0 --- /dev/null +++ b/src/lc3_lib.c @@ -0,0 +1,126 @@ +//FIXME: all includes maybe unnecessary +#include "preprocessor.h" +#include "registers.c" +#include "lc3_lib.h" + +uint16_t sign_extend(uint16_t n, int bit_count) { + if((n >> (bit_count - 1)) & 1) { + n |= (0xFFFF << bit_count); + } + return n; +} + +int swap16(uint16_t x) { + return (x << 8) || (x >> 8); +} + +void update_flags(uint16_t r) { + if(reg[r] == 0) reg[RG_COND] = FL_Z; + else if(reg[r] >> 15) reg[RG_COND] = FL_N; + else reg[RG_COND] = FL_P; +} + +/* function to load assembly programs*/ +void read_image_file(FILE* file) { + /* image placement memory location */ + uint16_t origin; + fread(&origin, sizeof(origin), 1, file); + origin = swap16(origin); + + uint16_t max_read = UINT16_MAX - origin; + uint16_t* p = memory + origin; + size_t read = fread(p, sizeof(uint16_t), max_read, file); + + /* swapping to little endian */ + while (read-- > 0) { + *p = swap16(*p); + ++p; + } +} + +int read_image(const char* file) { + FILE* image= fopen(file,"rb"); + if(!image){ + return 0; + } + uint16_t origin; + fread(&origin,sizeof(origin),1,image); + origin = swap16(origin); + uint16_t max_read = UINT16_MAX - origin; + uint16_t* i = memory + origin; + size_t read = fread(i,sizeof(uint16_t),max_read,image); + + while(read-- > 0){ + *i = swap16(*i); + ++i; + } + return 1; +} + +/* Defining functions for Unix or Windows based systems */ +#ifdef __UNIX + uint16_t check_key() { + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(STDIN_FILENO, &readfds); + + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + return select(1, &readfds, NULL, NULL, &timeout) != 0; + + struct termios original_tio; + + void disable_input_buffering() { + tcgetattr(STDIN_FILENO, &original_tio); + struct termios new_tio = original_tio; + new_tio.c_lflag &= ~ICANON & ~ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &new_tio); + } + + void restore_input_buffering() { + tcsetattr(STDIN_FILENO, TCSANOW, &original_tio); + } +} +#else + uint16_t check_key() { + return WaitForSingleObject(hStdin, 1000) == WAIT_OBJECT_0 && _kbhit(); + } + + DWORD fdwMode, fdwOldMode; + + void disable_input_buffering() { + hStdin = GetStdHandle(STD_INPUT_HANDLE); + GetConsoleMode(hStdin, &fdwOldMode); // save old mode + fdwMode = fdwOldMode + ^ ENABLE_ECHO_INPUT // no input echo + ^ ENABLE_LINE_INPUT; // return when one or more characters are available + SetConsoleMode(hStdin, fdwMode); // set new mode + FlushConsoleInputBuffer(hStdin); // clear buffer + } + + void restore_input_buffering() { + SetConsoleMode(hStdin, fdwOldMode); + } +#endif + +void mem_write(uint16_t address, uint16_t val) { + memory[address] = val; +} + +int mem_read(uint16_t address) { + if(address == MMR_KSR) { + if(check_key()) { + memory[MMR_KSR] = 1 << 15; + memory[MMR_KDR] = getchar(); + } else memory[MMR_KSR] = 0; + } + + return memory[address]; +} + +void handle_interrupt(int signal) { + restore_input_buffering(); + printf("\n"); + exit(-2); +} diff --git a/src/lc3_lib.h b/src/lc3_lib.h new file mode 100644 index 0000000..b9858a2 --- /dev/null +++ b/src/lc3_lib.h @@ -0,0 +1,32 @@ +/* Library of functions used in tyvm.c */ + + +/* Sign extension function for immediate add mode (imm5[0:4]) +transforms 5bit number to 8bit number preserving sign*/ +uint16_t sign_extend(uint16_t n, int bit_count); + +/* Swap to big endian */ +int swap16(uint16_t x); + +/* Flag update function +Every time a value is written to a register the flag will be updated */ +void update_flags(uint16_t r); + +/* Load assembly file*/ +void read_image_file(FILE* file); + +/* Read loaded assembly file */ +int read_image(const char* file); + +/* Input buffering */ +void disable_input_buffering(); +void restore_input_buffering(); + +/* Write to memory address */ +void mem_write(uint16_t address, uint16_t val); + +/* Read memory address */ +int mem_read(uint16_t address); + +/* Handle interrupt */ +void handle_interrupt(int signal); \ No newline at end of file diff --git a/src/includes.h b/src/preprocessor.h similarity index 63% rename from src/includes.h rename to src/preprocessor.h index 2157a35..48ae596 100644 --- a/src/includes.h +++ b/src/preprocessor.h @@ -1,4 +1,6 @@ -/* List of all the libraries needed to run tyvm.c */ +/* preprocessor directves needed to run tyvm.c */ + +#define __UNIX // used to modify code whether compiling on a Unix-based OS or a Windows machine /* universal libraries */ #include @@ -21,4 +23,11 @@ #else #include #include -#endif \ No newline at end of file +#endif + +#ifndef __UNIX + HANDLE hStdin = INVALID_HANDLE_VALUE; +#endif + +#define TRUE 1 +#define FALSE 0 \ No newline at end of file diff --git a/src/registers.h b/src/registers.c similarity index 100% rename from src/registers.h rename to src/registers.c diff --git a/src/tyvm.c b/src/tyvm.c index a03dc90..98dedf0 100644 --- a/src/tyvm.c +++ b/src/tyvm.c @@ -4,151 +4,16 @@ Open-source software distributed under GNU GPL v.3 license */ -#define __UNIX // used to modify code whether compiling on a Unix-based OS or a Windows machine - -#include "includes.h" -#include "registers.h" - -#ifndef __UNIX - HANDLE hStdin = INVALID_HANDLE_VALUE; -#endif - -#define TRUE 1 -#define FALSE 0 +#include "preprocessor.h" +#include "registers.c" +#include "lc3_lib.h" -/* Sign extension function for immediate add mode (imm5[0:4]) -transforms 5bit number to 8bit number preserving sign*/ -uint16_t sign_extend(uint16_t n, int bit_count) { - if((n >> (bit_count - 1)) & 1) { - n |= (0xFFFF << bit_count); - } - return n; -} - -/* function to swap to big endian */ -int swap16(uint16_t x) { - return (x << 8) || (x >> 8); -} - -/* Flag update function -Every time a value is written to a register the flag will be updated */ -void update_flags(uint16_t r) { - if(reg[r] == 0) reg[RG_COND] = FL_Z; - else if(reg[r] >> 15) reg[RG_COND] = FL_N; - else reg[RG_COND] = FL_P; -} - -/* function to load assembly programs*/ -void read_image_file(FILE* file) { - /* image placement memory location */ - uint16_t origin; - fread(&origin, sizeof(origin), 1, file); - origin = swap16(origin); - - uint16_t max_read = UINT16_MAX - origin; - uint16_t* p = memory + origin; - size_t read = fread(p, sizeof(uint16_t), max_read, file); - - /* swapping to little endian */ - while (read-- > 0) { - *p = swap16(*p); - ++p; - } -} - -int read_image(const char* file) { - FILE* image= fopen(file,"rb"); - if(!image){ - return 0; - } - uint16_t origin; - fread(&origin,sizeof(origin),1,image); - origin = swap16(origin); - uint16_t max_read = UINT16_MAX - origin; - uint16_t* i = memory + origin; - size_t read = fread(i,sizeof(uint16_t),max_read,image); - - while(read-- > 0){ - *i = swap16(*i); - ++i; - } - return 1; -} - -#ifdef __UNIX - uint16_t check_key() { - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(STDIN_FILENO, &readfds); - - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 0; - return select(1, &readfds, NULL, NULL, &timeout) != 0; -} -#else - uint16_t check_key() { - return WaitForSingleObject(hStdin, 1000) == WAIT_OBJECT_0 && _kbhit(); - } -#endif - -void mem_write(uint16_t address, uint16_t val) { - memory[address] = val; -} - -int mem_read(uint16_t address) { - if(address == MMR_KSR) { - if(check_key()) { - memory[MMR_KSR] = 1 << 15; - memory[MMR_KDR] = getchar(); - } else memory[MMR_KSR] = 0; - } - - return memory[address]; -} - -#ifdef __UNIX - struct termios original_tio; - - void disable_input_buffering() { - tcgetattr(STDIN_FILENO, &original_tio); - struct termios new_tio = original_tio; - new_tio.c_lflag &= ~ICANON & ~ECHO; - tcsetattr(STDIN_FILENO, TCSANOW, &new_tio); - } - - void restore_input_buffering() { - tcsetattr(STDIN_FILENO, TCSANOW, &original_tio); - } -#else - DWORD fdwMode, fdwOldMode; - - void disable_input_buffering() { - hStdin = GetStdHandle(STD_INPUT_HANDLE); - GetConsoleMode(hStdin, &fdwOldMode); // save old mode - fdwMode = fdwOldMode - ^ ENABLE_ECHO_INPUT // no input echo - ^ ENABLE_LINE_INPUT; // return when one or more characters are available - SetConsoleMode(hStdin, fdwMode); // set new mode - FlushConsoleInputBuffer(hStdin); // clear buffer - } - - void restore_input_buffering() { - SetConsoleMode(hStdin, fdwOldMode); - } -#endif - -void handle_interrupt(int signal) { - restore_input_buffering(); - printf("\n"); - exit(-2); -} int main(int argc, const char* argv[]) { if(argc != 2) { - printf("usage: [image-file1] ...\n"); + printf("loading image: %s\n", argv[2]); exit(2); }