From b42d5e7e677bdbf8369ef36af13b8a8a106d732b Mon Sep 17 00:00:00 2001 From: XOR Date: Tue, 17 Oct 2023 16:41:38 +0200 Subject: [PATCH] Add argp, and executing functionality --- .gitignore | 3 +- Makefile | 2 +- build/eipaemulator | Bin 15680 -> 0 bytes header/argp_commons.h | 9 ++++ header/common.h | 41 ++++++++++++++++ header/execute.h | 13 +++++ header/helpers.h | 9 ++++ src/execute.c | 97 ++++++++++++++++++++++++++++++++++++++ src/helpers.c | 16 +++++++ src/main.c | 107 ++++++++++++++++++++++++++++++++---------- test/loopprint.eimg | Bin 0 -> 32 bytes 11 files changed, 269 insertions(+), 28 deletions(-) delete mode 100755 build/eipaemulator create mode 100755 header/argp_commons.h create mode 100755 header/common.h create mode 100644 header/execute.h create mode 100644 header/helpers.h create mode 100644 src/execute.c create mode 100644 src/helpers.c create mode 100644 test/loopprint.eimg diff --git a/.gitignore b/.gitignore index c155c8d..00ac722 100755 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ dkms.conf *.eipa !test*.eipa *.eipaimg +build/* #Code editor .vscode/* @@ -67,4 +68,4 @@ compile_commands.json *.*~ #Code analysis -softwipe*.* \ No newline at end of file +softwipe*.* diff --git a/Makefile b/Makefile index 82b7936..4479800 100755 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ LIBS := OBJECT_FILES := $(patsubst %.c, %.o, $(wildcard $(SRC_DIR)/*.c)) HEADER_FILES := $(wildcard $(HEADER_DIR)/*.h) OBJECT_FILES := $(patsubst $(SRC_DIR)/%, $(BUILD_DIR)/%, $(OBJECT_FILES)) -MAIN_EXE_NAME := eipaemulator +MAIN_EXE_NAME := eipaemu all build/eipaemulator: $(OBJECT_FILES) $(CC) $(CFLAGS) $^ $(LIBS) -o $(BUILD_DIR)/$(MAIN_EXE_NAME) diff --git a/build/eipaemulator b/build/eipaemulator deleted file mode 100755 index d408ffa649fddf161bab004be6692df8538105e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15680 zcmeHOZEPG@6@9yQ8mFzjj@7ho5}Kj3B|-7VAF(k_)2w5!GY)amCJv+$WxDZ>?G@`? zvtAb`YN)GiA(n}h{t2IgAQd46AyoyTs0F$qRnq{K5>-g%7ZyszT7o`(K@D8@ z<3*mQptQT=X(Wbe_TI%STov@{XeyVQ9EVHWm*NPIH^wMBs*-Mwb#tt9ktRg#j1o_Z z32mJmPd{pCBh&1?Qhwbb*7>oA{RL?ZvIB4DlmE_mkFajNW_P3fxY?nVpp5q@bbM;r z10znm6@1qn(XXo>ew0`&qiDAfoWbe23=FT z_8wH>DODs+^i;kB8-!0%VfLZ+u8&F|q#++N;%F12Hra&x zSCBrg4HX>kT81~lYZd&rEaOj?Wu^X~0k2{68^x-U|E6X5li)RMehY!P*H2R2Fa{?R z#!xDgNT-gPYBZ5fX9vOJJPsP;`9v;nj3!bUHIyAQvCo-_q#B#Z4~`^qYAlz^^54XZCl-9YqVV%eFObQ(#)B|sqws-8|d#&XEWwN;&9r;NW-Jq43A_u zt`!}X3gfB>VITJFsosObkn8sQ&!58OUZwUjH?cOgijs>`Kw;I zTBFabIES^q{#-F1wl3*~*J{q&VX@kO3fj8==h#O!#89I82(``6S+M(mLUmfg&0n(X zFH@bClJiBo{u0$`2|53wT|Yy0TH4K@MxDlQ`CZ@i>er*r)K^(^kquMicb*ackJ|q2y9qX3 z*Qd++xp#Kx=N7B<(Chl;>-js-!JFJcjWstE*?@((=xKga+iRg!6Kx0e!uB)pRQmMW z`C5Hu`#Y#uYrceiX%GkV`id(kh8{nEW4`ByZj>p0)ZhFte0hEc(G}va>C?v+FT@vU z>iSH4Q6KDIC_HprMV`%rxezZ?17HK7aICB%Ux=Y3o-@_Qr{h;=`pakOJiIkG(|`5- z=U#0_`D_bzg=;DjUo3T9x2&0XxlpvGiW)!JQz(FG<{)@LSb^b_r`fGyP#HytnO zg<~ZZdG2-y&=GpK=IH_TRcuqGU;f>8n$u^FVe2pbnAYnrW2-NHoti+Geu0j73N!Kd zoVnStw69(FYK17UAOb-If(Qf=2qF+fAc#N^fgl1w1cC?z5vUjedhc{#%p6P&9nn%5 zyb#ldQfc#6m4kO^UDdXYKzdlOE?d?ofJq=8k5%$r%c3Xp>OWZ43qX3;NftV~Uxg;? zL+fr|S#uIkqr}rY{6^>=Acvln_A9RYP~3{`^zSX}381R0@2zXx9l7l@HB)NG+HD_d zyYF72NlW9-LjMgSy6Wmb7w)dTCHxhP;Iuyl`Vi*x)g|qx>~^983nCCiAc#N^fgl1w z1cC?z5eOm>L?DR3|6&9r4^Z;{=!GB|J+qO~D>&OY(GYLxZ2Mt@gLiXX@(b5-o!-fj zt#v?2o*_M-kxBcXu3K5EpXQ`N$<=$Knph{dnXt(1k`s7_NZ4%-s7A&$i~=lECC)3P z7tLgo4!F;uk_$-ru4I#(tSJ0ho|w$LXnQFoxr;LX-z?{N&}_TnJ*0hn$61e8nRZ>` zjK@^Fp5yjwT$g$CF#mOs{Bi%l9ef@1GJcG4i1A5A(MjIuuI}y!wT;MH-lVm(MO&jS zT5EG_TXSb~iyBNPGQ--FW^O!{&1fwh(Pm`SE@u?CYW1#Fsl5_UCn2QPDF5*|X|Ai? zd~)fJerE`&yWHzV_y4Q=FG; z|E2-%JJ{-R)py2F@YqWzH-sZfKA+NbmUyXn@MkDfKmPg5g4aBLQv3}HtHX_|IVOyQ z3&c}4vgXwJC-{1Gw~ECaf7xF~p+Vtz`8u+H0|K{>{r$)LLA(DtrSTy4 zZ#wYbyv(={gQxlX``Ha%gU)YB@b(W&zJ{m4H-vF_^j+^rBu{0cNF?uhY;RY8UpMl+ zanT!b-RRxl)gL$Xp8d+$wP)YXu06)S-rfW80b`(R=bpGB$>lN0CASmE{psj#D>BV* zmR)Y=tGmwBm7TM0Ag_Jc%o~H*Br?#=WFntXlmnmQl=dYG!=QF2L;au9)s5tM))+}- zl9bBcw+~*)RK}PXH#h6{S4&D8}Yq8#?3O~m!|G7?EuG; zS1LMwWHg^R49w>o9FY<-_s!gxie|ETGdi4^h>qou;h)PN@lb~+QurfBD#=vW&c3F6 zVp!SkBZ=`56-^$=U{v~rSmFkPcxb~CsDTJAI)X$vk^5% zjGQgifr*kr%IG*Tni|BYS@eZn)E>a;3;|cs!R+X$nL$+k6Gq?f zxb)rJ|3?0z5|r|eximB*j zT_sp#M;YIL{9k1KPWF>^nu{Jit>ygsZ-S$kNdNBroA2YYe&ufLxk{PvYuLPcjdg-g zkdw#c>p}3_X!Gi)xIu861cv(%opkwKpI*M_1!a9M{{HLtd#rbd(b$u5EmsBn`d83E z^B4Vk&G8i6>{Q*oUw;uTUcIh4u7VU_ugUon?kyB3kB~pM?*E$P|9XCZsSExJ+K5Ll z&n2@>AYtO?)Na&;|1BEm+L7^PUFrV+k`4|=*FTx)$^2y<)yaClKaJ(JS{|R> z-6qlddC_}Ou02w|oXj0X*R(dL_?!&HExsz&xRv$a+Uf{s KUF$VpRs92)14FO? diff --git a/header/argp_commons.h b/header/argp_commons.h new file mode 100755 index 0000000..a481585 --- /dev/null +++ b/header/argp_commons.h @@ -0,0 +1,9 @@ +#ifndef _ARGP_COMMONS_H_ +#define _ARGP_COMMONS_H_ + +#include "../header/common.h" + +#define ARGUMENT_DOC "INPUT_FILE" +#define LONG_DOC "options:" + +#endif diff --git a/header/common.h b/header/common.h new file mode 100755 index 0000000..318569c --- /dev/null +++ b/header/common.h @@ -0,0 +1,41 @@ +/* +This code is part of the EIPA Platform + +Here, common macros are specified +*/ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +// Maximum Memory Adresses +#define MAX_MEMORY 268435456 + +// Intitial size and grow size for dynamic buffers +#define TABLE_INIT_SIZE 50 +#define TABLE_GROW_SIZE 30 + +#define VER_MAJOR "0" +#define VER_MINOR "0" +#define VER_PATCH "1" + +// alpha, beta or stable +#define TAG "alpha" + +#define INSTR_INP 0b0001 +#define INSTR_OUT 0b0010 +#define INSTR_LDA 0b0011 +#define INSTR_STA 0b0100 +#define INSTR_INC 0b0101 +#define INSTR_DEC 0b0110 +#define INSTR_JPP 0b0111 +#define INSTR_JPZ 0b1000 +#define INSTR_JPN 0b1001 +#define INSTR_JPU 0b1010 +#define INSTR_EOJ 0b1011 + +#define ADRESS_BITS 0b00001111111111111111111111111111 + +// const char *argp_program_bug_address = "eipabugs@outlook.com"; +#define EIPA_BUG_ADRESS "eipabugs@outlook.com" + +#endif diff --git a/header/execute.h b/header/execute.h new file mode 100644 index 0000000..8076118 --- /dev/null +++ b/header/execute.h @@ -0,0 +1,13 @@ +#ifndef _EXECUTE_H_ +#define _EXECUTE_H_ + +#include +#include +#include + +#include "common.h" + +// Executes given memory +int execute(uint32_t *memory); + +#endif diff --git a/header/helpers.h b/header/helpers.h new file mode 100644 index 0000000..03a3715 --- /dev/null +++ b/header/helpers.h @@ -0,0 +1,9 @@ +#ifndef _HELPER_H_ +#define _HELPER_H_ + +#include +#include + +void print_target_code(uint32_t *target_code); + +#endif diff --git a/src/execute.c b/src/execute.c new file mode 100644 index 0000000..16d39d3 --- /dev/null +++ b/src/execute.c @@ -0,0 +1,97 @@ +#include "../header/execute.h" + +int execute(uint32_t *memory) +{ + uint32_t instr_ptr = 0; + uint32_t instr_curr; + uint32_t cpu_register = 0; + while((instr_curr = memory[instr_ptr]) >> 28 != INSTR_EOJ) + { + uint8_t op_code = memory[instr_ptr] >> 28; // Get only the first 4 bits + uint32_t adress = memory[instr_ptr] & ADRESS_BITS; // Discard the first 4 bits + + // This check should be unnecessary when using the official EIPA Assembler, but + // some people might want to hand-craft their EIPA Images + if(adress > MAX_MEMORY) + { + printf("ERROR: Adress on instruction %u is too big\n", instr_ptr); + return 1; + } + + // Run the instruction + switch(op_code) + { + case INSTR_INP: + { + printf("Input: "); + int check = scanf("%u", memory + adress); + fflush(stdin); + if(!check) + { + printf("ERROR: Received invalid input on a INP instruction\n"); + return 1; + } + instr_ptr++; + break; + } + case INSTR_OUT: + printf("%u\n", memory[adress]); + instr_ptr++; + break; + case INSTR_LDA: + cpu_register = memory[adress]; + instr_ptr++; + break; + case INSTR_STA: + memory[adress] = cpu_register; + instr_ptr++; + break; + case INSTR_INC: + cpu_register++; + instr_ptr++; + break; + case INSTR_DEC: + cpu_register--; + instr_ptr++; + break; + case INSTR_JPP: + if(cpu_register > 0) + { + instr_ptr = adress; + } + else + { + instr_ptr++; + } + break; + case INSTR_JPZ: + if(cpu_register == 0) + { + instr_ptr = adress; + } + else + { + instr_ptr++; + } + break; + case INSTR_JPN: + if(cpu_register < 0) + { + instr_ptr = adress; + } + else + { + instr_ptr++; + } + break; + case INSTR_JPU: + instr_ptr = adress; + break; + default: + printf("ERROR: Unknown opcode %u\n", op_code); + } + + } + + return 0; +} diff --git a/src/helpers.c b/src/helpers.c new file mode 100644 index 0000000..ed94b88 --- /dev/null +++ b/src/helpers.c @@ -0,0 +1,16 @@ +#include "../header/helpers.h" + +void print_target_code(uint32_t *target_code) +{ + int instruction_index = 0; + while (target_code[instruction_index] != 0) + { + int i = 0; + for (i = (sizeof(target_code[instruction_index]) * 8) - 1; i >= 0; i--) + { + putchar(target_code[instruction_index] & (1u << i) ? '1' : '0'); + } + printf("\n"); + instruction_index++; + } +} diff --git a/src/main.c b/src/main.c index 682c079..f354d3f 100755 --- a/src/main.c +++ b/src/main.c @@ -2,40 +2,95 @@ // Read an EIPA image and print it out in Binary form +#ifndef WIN_COMPILE +#include +#else +#include "../header/argp/argp.h" +#endif + #include #include -#define MAX_MEMORY 268435456 +#include "../header/argp_commons.h" +#include "../header/common.h" +#include "../header/helpers.h" +#include "../header/execute.h" -void print_target_code(__uint32_t *target_code) +const char *argp_program_version = + VER_MAJOR "." VER_MINOR "." VER_PATCH " || " TAG; + +const char *argp_program_bug_address = EIPA_BUG_ADRESS; + +// Here, the argumets get stored by the parser, so acess them from here +struct cmd_arguments { - int instruction_index = 0; - while (target_code[instruction_index] != 0) + char *input_file; +}; + +// Parses the command line options & arguments +static error_t parser_function(int key, char *arg, struct argp_state *state) +{ + struct cmd_arguments *save_arguments = state->input; + + switch (key) { - int i = 0; - for (i = (sizeof(target_code[instruction_index]) * 8) - 1; i >= 0; i--) + case ARGP_KEY_ARG: + // If we got more than one non-option argument + if (state->arg_num >= 1) { - putchar(target_code[instruction_index] & (1u << i) ? '1' : '0'); + argp_usage(state); } - printf("\n"); - instruction_index++; + save_arguments->input_file = arg; + break; + case ARGP_KEY_END: + // If we didn't receive 1 Argument yet + if (state->arg_num < 1) + { + argp_usage(state); + } + break; + default: + return ARGP_ERR_UNKNOWN; } -} - -int main(int argc, char const *argv[]) -{ - if(argc < 2) - { - printf("Specify input file\n"); - } - FILE *input = fopen(argv[1], "r"); - if(input == NULL) return -1; - - __uint32_t *target_code = malloc(MAX_MEMORY*sizeof(target_code)); - - fread(target_code, sizeof(target_code), MAX_MEMORY, input); - - print_target_code(target_code); - + return 0; +} + +// This array stores structs containing information about the cli options +static struct argp_option argp_options[] = {{0}}; + +// Contains the neccesary stuff for argp +static struct argp argument_parser = + { + .options = argp_options, + .parser = parser_function, + .args_doc = ARGUMENT_DOC, + .doc = LONG_DOC}; + +int main(int argc, char **argv) +{ + // Parse CLI Arguments + // set defaults + struct cmd_arguments arguments; + arguments.input_file = ""; + + if (argp_parse(&argument_parser, argc, argv, 0, 0, &arguments) != 0) + { + printf("Error: Failed to parse CLI Arguments - Error code\n"); + return EXIT_FAILURE; + } + + FILE *input = fopen(arguments.input_file, "r"); + if (input == NULL) + return -1; + + // Allocate the memory of the Emulated device + uint32_t *memory = malloc(MAX_MEMORY * sizeof(memory)); + + // Load the binary into memory + fread(memory, sizeof(memory), MAX_MEMORY, input); + + execute(memory); + + free(memory); return 0; } diff --git a/test/loopprint.eimg b/test/loopprint.eimg new file mode 100644 index 0000000000000000000000000000000000000000..3fb226088f1e166f2ba858eb335393e4fece1895 GIT binary patch literal 32 acmb1RU=WaFU{GLWU|7Jwz_0;`Q2+oX00F)L literal 0 HcmV?d00001