diff options
Diffstat (limited to 'emulator.cpp')
-rw-r--r-- | emulator.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/emulator.cpp b/emulator.cpp new file mode 100644 index 0000000..0e3fb29 --- /dev/null +++ b/emulator.cpp @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: Unlicense + */ + +#include "bus.hpp" +#include "musashi-m68k/m68k.h" + +#include <cstdio> +#include <cstdlib> +#include <cstdarg> +#include <ctime> + +#if !defined(DEBUG_TRACE_INSTRUCTIONS) +# define DEBUG_TRACE_INSTRUCTIONS 0 +#endif + +static void exit_error(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); + exit(EXIT_FAILURE); +} + +/* Called when the CPU pulses the RESET line */ +void m68k_reset_callback(void) +{ + // TODO +} + +/* Called when the CPU acknowledges an interrupt */ +int m68k_irq_ack(int level) +{ + (void) level; + // TODO + exit_error("IRQ ack"); + return M68K_INT_ACK_SPURIOUS; +} + +static void make_hex(char* buff, unsigned int pc, unsigned int length) +{ + char* ptr = buff; + + for (;length>0;length -= 2) + { + sprintf(ptr, "%04x", m68k_read_disassembler_16(pc)); + pc += 2; + ptr += 4; + if (length > 2) + *ptr++ = ' '; + } +} + +void m68k_instr_callback(int pc) +{ + if (!DEBUG_TRACE_INSTRUCTIONS) + return; + char buff[100]; + unsigned int instr_size = + m68k_disassemble(buff, pc, M68K_CPU_TYPE_68000); + char buff2[100]; + make_hex(buff2, pc, instr_size); + printf("E %08X: %-20s: %s\n", pc, buff2, buff); + fflush(stdout); +} + +int main(int argc, char* argv[]) +{ + if (argc != 2) + { + printf("Usage: sim <program file>\n"); + exit(-1); + } + + FILE* const fhandle = fopen(argv[1], "rb"); + + if (fhandle == NULL) + exit_error("Unable to open %s", argv[1]); + + const size_t fread_ret = fread(g_rom, 1, ROM_SIZE, fhandle); + if (fread_ret <= 0) + exit_error("Error reading %s", argv[1]); + printf("Read into ROM %zu bytes\n", fread_ret); + + m68k_init(); + m68k_set_cpu_type(M68K_CPU_TYPE_68000); + m68k_pulse_reset(); + + while (1) + { + // Values to execute determine the interleave rate. + // Smaller values allow for more accurate interleaving with multiple + // devices/CPUs but is more processor intensive. + // 100000 is usually a good value to start at, then work from there. + + // Note that I am not emulating the correct clock speed! + m68k_execute(100000); + } + + return 0; +} |