/* MSP430 Emulator Copyright (C) 2020 Rudolf Geosits (rgeosits@live.esu.edu) "MSP430 Emulator" is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. "MSP430 Emulator" is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "main.h" #include // This is an ugly solution but heh Emulator *emuInst; static PyObject *method_run(PyObject *self, PyObject *args) { unsigned int port; if(!PyArg_ParseTuple(args, "H", &port)) { return NULL; } Py_BEGIN_ALLOW_THREADS run(port); Py_END_ALLOW_THREADS return Py_None; } static PyObject *method_stop(PyObject *self, PyObject *args) { if(emuInst != NULL) { emuInst->debugger->quit = true; } return Py_None; } static PyMethodDef RunMethods[] = { {"run", method_run, METH_VARARGS, "Python function to start msp430 emulator"}, {"stop", method_stop, METH_NOARGS, "Python function to stop msp430 emulator"}, {NULL, NULL, 0, NULL} }; static struct PyModuleDef msp430module = { PyModuleDef_HEAD_INIT, "_msp430emu", "Python interface for msp430 emulator", -1, RunMethods }; PyMODINIT_FUNC PyInit__msp430emu(void) { return PyModule_Create(&msp430module); } int run(unsigned int port) { emuInst = (Emulator *) calloc( 1, sizeof(Emulator) ); Cpu *cpu = NULL; Debugger *deb = NULL; emuInst->cpu = (Cpu *) calloc(1, sizeof(Cpu)); emuInst->cpu->bcm = (Bcm *) calloc(1, sizeof(Bcm)); emuInst->cpu->timer_a = (Timer_a *) calloc(1, sizeof(Timer_a)); emuInst->cpu->p1 = (Port_1 *) calloc(1, sizeof(Port_1)); emuInst->cpu->usci = (Usci *) calloc(1, sizeof(Usci)); emuInst->debugger = (Debugger *) calloc(1, sizeof(Debugger)); setup_debugger(emuInst); cpu = emuInst->cpu; deb = emuInst->debugger; deb->server = (Server *) calloc(1, sizeof(Server)); if (deb->web_interface == true) { deb->ws_port = port; pthread_t *t = &deb->web_server_thread; if ( pthread_create(t, NULL, web_server, (void *)emuInst ) ) { fprintf(stderr, "Error creating web server thread\n"); return 1; } while (!deb->web_server_ready) usleep(10000); print_console(emuInst, " [MSP430 Emulator]\n Copyright (C) 2020 Rudolf Geosits (rgeosits@live.esu.edu)\n"); // print_console(emuInst, " [!] Upload your firmware (ELF format only); Type 'h' for debugger options.\n\n"); while (!deb->web_firmware_uploaded) usleep(10000); } //register_signal(SIGINT); // Register Callback for CONTROL-c initialize_msp_memspace(); initialize_msp_registers(emuInst); setup_bcm(emuInst); setup_timer_a(emuInst); setup_port_1(emuInst); setup_usci(emuInst); load_bootloader(0x0C00); if (deb->web_interface) load_firmware(emuInst, (char*)"tmp.bin", 0xC000); // display first round of registers display_registers(emuInst); disassemble(emuInst, cpu->pc, 1); update_register_display(emuInst); // Fetch-Decode-Execute Cycle (run machine) while (!deb->quit) { // Handle debugger when CPU is not running if (!cpu->running) { usleep(10000); continue; } // Handle Breakpoints handle_breakpoints(emuInst); // Instruction Decoder decode(emuInst, fetch(emuInst), EXECUTE); // Handle Peripherals handle_bcm(emuInst); handle_timer_a(emuInst); handle_port_1(emuInst); handle_usci(emuInst); // Average of 4 cycles per instruction mclk_wait_cycles(emuInst, 4); } uninitialize_msp_memspace(); free(cpu->timer_a); free(cpu->bcm); free(cpu->p1); free(cpu->usci); free(cpu); free(deb->server); free(deb); free(emuInst); return 0; } int main(int argc, char *argv[]) { if (argv[1] == NULL) { puts("Need port argument"); return(1); } return run(strtoul(argv[1], NULL, 10)); }