/* Copyright (c) 2024 Freya Murphy */ #ifndef __SIM_H__ #define __SIM_H__ #include #include /// arguments struct simulator_args { char *executable; bool memchk; bool debug; }; // when loading the executable, we need to bounds check to // make sure its within the file size // // this checks that // 1. the end is in the file // 2. the off and len doesnt integer overflow #define BOUND_CHK(size, len, off) \ ((off) > UINT32_MAX - (len) || (off) + (len) > (size)) /// /// data must start at these /// addresses or the executable is /// invalid /// #define MEM_TEXT_ADDR 0x00400000 #define MEM_DATA_ADDR 0x10000000 struct simulator { struct simulator_args *args; /// the registers uint32_t reg[32]; /// the program counter uint32_t pc; /// the current executing pc uint32_t current_pc; /// low and hi uint32_t low; uint32_t hi; /// memory address bounds uint32_t data_min; uint32_t data_max; uint32_t text_min; uint32_t text_max; // entrypoint uint32_t entry; }; /* initalize a simulator */ int sim_init(struct simulator *sim, struct simulator_args *args); /* load a file into a simulator */ int sim_load_file(struct simulator *sim); /* execute and instruction */ void sim_ins(struct simulator *sim, uint32_t ins); /* execute the next instruction in the simulator */ void sim_step(struct simulator *sim); /* run the simulator with the loaded state */ _Noreturn void sim_run(struct simulator *sim); /* run the debugger for a simulator */ _Noreturn void sim_debug(struct simulator *sim); /* panics the simulator */ __attribute__((format(printf, 2, 3))) _Noreturn void sim_dump(struct simulator *sim, const char *format, ...); /* dumps registers */ void sim_dump_reg(struct simulator *sim); #endif /* __SIM_H__ */