py_functions.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. #include "py_functions.h"
  2. #ifdef _MSC_VER
  3. #include <Windows.h>
  4. #else
  5. #include <time.h>
  6. #endif
  7. uint64_t getnano() {
  8. #ifdef _MSC_VER
  9. static LARGE_INTEGER frequency;
  10. if (frequency.QuadPart == 0) QueryPerformanceFrequency(&frequency);
  11. LARGE_INTEGER now;
  12. QueryPerformanceCounter(&now);
  13. double x = (double)now.QuadPart / (double)frequency.QuadPart;
  14. return (uint64_t)(x * 1000000000.0);
  15. #else
  16. struct timespec now;
  17. clock_gettime(CLOCK_MONOTONIC, &now);
  18. return now.tv_sec * 1000000000 + now.tv_nsec;
  19. #endif
  20. }
  21. // This is an ugly solution but heh
  22. Emulator *emuInst = NULL;
  23. void play_emu() {
  24. emuInst->cpu->running = true;
  25. emuInst->debugger->debug_mode = false;
  26. }
  27. void pause_emu() {
  28. if (emuInst->cpu->running) {
  29. emuInst->cpu->running = false;
  30. emuInst->debugger->debug_mode = true;
  31. // display first round of registers
  32. // display_registers(emu);
  33. // disassemble(emu, cpu->pc, 1);
  34. // update_register_display(emu);
  35. }
  36. }
  37. void reset_emu() {
  38. if(emuInst == NULL) return;
  39. cpu_reset(emuInst);
  40. print_console(emuInst, "CPU Reset\n");
  41. }
  42. void set_reg(uint8_t reg_type, uint8_t value) {
  43. if(emuInst == NULL) return;
  44. Port_1 *p = emuInst->cpu->p1;
  45. switch(reg_type) {
  46. case SET_REG_P1_EN:
  47. p->EXT_EN = value;
  48. break;
  49. case SET_REG_P1_DIR:
  50. p->EXT_DIR = value;
  51. break;
  52. }
  53. }
  54. PyObject *get_misc_data() {
  55. if(emuInst == NULL) return Py_None;
  56. Cpu *cpu = emuInst->cpu;
  57. Bcm *bcm = cpu->bcm;
  58. PyObject *dict = PyDict_New();
  59. PyDict_SetItemString(dict, "period", PyLong_FromUnsignedLongLong(cpu->nsecs));
  60. PyDict_SetItemString(dict, "mclk", PyLong_FromUnsignedLongLong(bcm->mclk_freq));
  61. PyDict_SetItemString(dict, "aclk", PyLong_FromUnsignedLongLong(bcm->aclk_freq));
  62. PyDict_SetItemString(dict, "smclk", PyLong_FromUnsignedLongLong(bcm->smclk_freq));
  63. PyDict_SetItemString(dict, "uart_baud", PyLong_FromUnsignedLong(cpu->usci->UART_baud));
  64. PyDict_SetItemString(dict, "timer_a0_freq", PyFloat_FromDouble(cpu->timer_a->timer_0_freq));
  65. PyDict_SetItemString(dict, "timer_a0_duty", PyFloat_FromDouble(cpu->timer_a->timer_0_duty));
  66. uint8_t pwm_pins = ~*cpu->p1->_OUT & *cpu->p1->_SEL & ~*cpu->p1->_SEL2;
  67. PyDict_SetItemString(dict, "timer_pwm_pins", PyBytes_FromStringAndSize(&pwm_pins, 1));
  68. return dict;
  69. }
  70. PyObject *get_port1_regs() {
  71. if(emuInst == NULL) return Py_None;
  72. char regs[9];
  73. Port_1 *p = emuInst->cpu->p1;
  74. regs[0] = *p->_OUT;
  75. regs[1] = *p->_DIR;
  76. regs[2] = *p->_IFG;
  77. regs[3] = *p->_IES;
  78. regs[4] = *p->_IE;
  79. regs[5] = *p->_SEL;
  80. regs[6] = *p->_SEL2;
  81. regs[7] = *p->_REN;
  82. regs[8] = *p->_IN;
  83. return PyBytes_FromStringAndSize(regs, 9);
  84. }
  85. PyObject *get_cpu_regs() {
  86. if(emuInst == NULL) return Py_None;
  87. Cpu *cpu = emuInst->cpu;
  88. uint16_t regs[] = {
  89. cpu->pc, cpu->sp, sr_to_value(emuInst), cpu->cg2,
  90. cpu->r4, cpu->r5, cpu->r6, cpu->r7,
  91. cpu->r8, cpu->r9, cpu->r10, cpu->r11,
  92. cpu->r12, cpu->r13, cpu->r14, cpu->r15
  93. };
  94. return PyBytes_FromStringAndSize((char *)regs, sizeof(regs));
  95. }
  96. PyObject *get_bcm_regs() {
  97. if(emuInst == NULL) return Py_None;
  98. char regs[6];
  99. Bcm *bcm = emuInst->cpu->bcm;
  100. regs[0] = *bcm->DCOCTL;
  101. regs[1] = *bcm->BCSCTL1;
  102. regs[2] = *bcm->BCSCTL2;
  103. regs[3] = *bcm->BCSCTL3;
  104. regs[4] = *bcm->IE1;
  105. regs[5] = *bcm->IFG1;
  106. return PyBytes_FromStringAndSize(regs, 6);
  107. }
  108. PyObject *get_timer_regs() {
  109. if(emuInst == NULL) return Py_None;
  110. uint16_t regs[18];
  111. Timer_a *timer = emuInst->cpu->timer_a;
  112. regs[0] = *timer->TA0CTL;
  113. regs[1] = *timer->TA0R;
  114. regs[2] = *timer->TA0CCTL0;
  115. regs[3] = *timer->TA0CCR0;
  116. regs[4] = *timer->TA0CCTL1;
  117. regs[5] = *timer->TA0CCR1;
  118. regs[6] = *timer->TA0CCTL2;
  119. regs[7] = *timer->TA0CCR2;
  120. regs[8] = *timer->TA0IV;
  121. regs[9] = *timer->TA1CTL;
  122. regs[10] = *timer->TA1R;
  123. regs[11] = *timer->TA1CCTL0;
  124. regs[12] = *timer->TA1CCR0;
  125. regs[13] = *timer->TA1CCTL1;
  126. regs[14] = *timer->TA1CCR1;
  127. regs[15] = *timer->TA1CCTL2;
  128. regs[16] = *timer->TA1CCR2;
  129. regs[17] = *timer->TA1IV;
  130. return PyBytes_FromStringAndSize((char*)regs, 18*2);
  131. }
  132. PyObject *get_usci_regs() {
  133. if(emuInst == NULL) return Py_None;
  134. char regs[12];
  135. Usci *usci = emuInst->cpu->usci;
  136. regs[0] = *usci->UCA0CTL0;
  137. regs[1] = *usci->UCA0CTL1;
  138. regs[2] = *usci->UCA0BR0;
  139. regs[3] = *usci->UCA0BR1;
  140. regs[4] = *usci->UCA0MCTL;
  141. regs[5] = *usci->UCA0STAT;
  142. regs[6] = *usci->UCA0RXBUF;
  143. regs[7] = *usci->UCA0TXBUF;
  144. regs[8] = *usci->UCA0ABCTL;
  145. regs[9] = *usci->UCA0IRTCTL;
  146. regs[10] = *usci->UCA0IRRCTL;
  147. regs[11] = *usci->IFG2;
  148. return PyBytes_FromStringAndSize(regs, 12);
  149. }
  150. void cmd_emu(char *line, int len) {
  151. if(emuInst == NULL) return;
  152. if (!emuInst->cpu->running && emuInst->debugger->debug_mode) {
  153. exec_cmd(emuInst, line, len);
  154. // update_register_display(emu);
  155. }
  156. }
  157. void stop_emu() {
  158. if(emuInst == NULL) return;
  159. emuInst->debugger->quit = true;
  160. print_console(emuInst, "Stopping emulator..\n");
  161. }
  162. void write_serial(uint8_t *data, int len) {
  163. if(emuInst == NULL) return;
  164. set_uart_buf(emuInst, data, len);
  165. //// int i = 0;
  166. //// uint8_t *bytes = data;
  167. // *usci->UCA0RXBUF = data[0];
  168. // *usci->IFG2 |= RXIFG;
  169. // puts("Setting interrupt");
  170. // service_interrupt(emuInst, USCIAB0RX_VECTOR);
  171. // printf("len is %d\n", len);
  172. // for(int i=0; i < len; i++) {
  173. // usleep(333);
  174. // printf("waiting.. ");
  175. // while (*usci->IFG2 & RXIFG) {
  176. // usleep(333);
  177. // if(emuInst->debugger->quit) {
  178. // puts("debugger stopped");
  179. // return;
  180. // }
  181. // }
  182. //// uint8_t thing = *(bytes);
  183. // *usci->UCA0RXBUF = data[i];
  184. // *usci->IFG2 |= RXIFG;
  185. // printf("0x%04X in UCA0RXBUF\n", (uint8_t)*usci->UCA0RXBUF);
  186. // printf("waiting.. ");
  187. // while (*usci->IFG2 & RXIFG) {
  188. // usleep(333);
  189. // if(emuInst->debugger->quit) {
  190. // puts("debugger stopped");
  191. // return;
  192. // }
  193. // }
  194. // puts("done\n");
  195. // }
  196. // while (true) {
  197. // usleep(333);
  198. // while (*usci->IFG2 & RXIFG);
  199. // uint8_t thing = *(bytes);
  200. //
  201. //// if (thing == '\n') {
  202. //// thing = '\r';
  203. //// }
  204. // *usci->UCA0RXBUF = thing;
  205. // *usci->IFG2 |= RXIFG;
  206. //
  207. // //printf("\n0x%04X in UCA0RXBUF\n", (uint8_t)*usci->UCA0RXBUF);
  208. // //puts("waiting..");
  209. // while (*usci->IFG2 & RXIFG);
  210. // //puts("done");
  211. // //*usci->IFG2 |= RXIFG;
  212. // if (*usci->UCA0RXBUF == '\r' || *usci->UCA0RXBUF == '\n') break;
  213. // ++bytes;
  214. // }
  215. }
  216. void start_emu(char *file) {
  217. emuInst = (Emulator *) calloc( 1, sizeof(Emulator) );
  218. Cpu *cpu = NULL; Debugger *deb = NULL;
  219. emuInst->cpu = (Cpu *) calloc(1, sizeof(Cpu));
  220. emuInst->cpu->bcm = (Bcm *) calloc(1, sizeof(Bcm));
  221. emuInst->cpu->timer_a = (Timer_a *) calloc(1, sizeof(Timer_a));
  222. emuInst->cpu->p1 = (Port_1 *) calloc(1, sizeof(Port_1));
  223. emuInst->cpu->usci = (Usci *) calloc(1, sizeof(Usci));
  224. emuInst->debugger = (Debugger *) calloc(1, sizeof(Debugger));
  225. setup_debugger(emuInst);
  226. cpu = emuInst->cpu;
  227. deb = emuInst->debugger;
  228. // deb->server = (Server *) calloc(1, sizeof(Server));
  229. initialize_msp_memspace();
  230. initialize_msp_registers(emuInst);
  231. setup_bcm(emuInst);
  232. setup_timer_a(emuInst);
  233. setup_port_1(emuInst);
  234. setup_usci(emuInst);
  235. print_console(emuInst, "[MSP430 Emulator]\n Copyright (C) 2020 Rudolf Geosits (rgeosits@live.esu.edu)\n");
  236. load_bootloader(0x0C00);
  237. if(load_firmware(emuInst, file, 0xC000) == 0) {
  238. // display_registers(emuInst);
  239. disassemble(emuInst, cpu->pc, 1);
  240. // update_register_display(emuInst);
  241. uint16_t counter = 0;
  242. uint64_t time_delta = 0;
  243. uint64_t time_last = getnano();
  244. while (!deb->quit) {
  245. // Handle debugger when CPU is not running
  246. if (!cpu->running) {
  247. counter = 0;
  248. time_delta = 0;
  249. time_last = getnano();
  250. usleep(10000);
  251. continue;
  252. }
  253. // Handle Breakpoints
  254. //handle_breakpoints(emuInst);
  255. cpu_step(emuInst);
  256. counter++;
  257. if(counter > 500) {
  258. uint64_t time_now = getnano();
  259. if(cpu->bcm->mclk_period == 0) break;
  260. // Average of 4 cycles per instruction
  261. uint64_t cycles_time = cpu->bcm->cpu_period * 500;
  262. uint64_t delta = time_now - time_last;
  263. if(time_last > time_now) delta = 0;
  264. uint64_t sleep_time = cycles_time - delta;
  265. if(delta > cycles_time) {
  266. time_delta += (delta - cycles_time);
  267. } else if(time_delta > sleep_time) {
  268. time_delta -= sleep_time;
  269. } else {
  270. sleep_time += time_delta;
  271. time_delta = 0;
  272. usleep(sleep_time/1000);
  273. }
  274. time_last = time_now;
  275. counter = 0;
  276. }
  277. }
  278. }
  279. uninitialize_msp_memspace();
  280. free(cpu->usci->UART_buf_data);
  281. free(cpu->timer_a);
  282. free(cpu->bcm);
  283. free(cpu->p1);
  284. free(cpu->usci);
  285. free(cpu);
  286. free(deb->server);
  287. free(deb);
  288. free(emuInst);
  289. return;
  290. }
  291. //void init_packet_queue (Emulator *emu){
  292. // Server *s = emu->debugger->server;
  293. // s->pending_packets_head = NULL;
  294. // s->pending_packets_tail = NULL;
  295. // s->packets_queued = 0;
  296. // s->spin_lock = false;
  297. //}
  298. //void *emulator (void *ctxt) {
  299. // emu = (Emulator *) ctxt;
  300. // Debugger *deb = emu->debugger;
  301. //
  302. // init_packet_queue(emu);
  303. // printf("starting emulator...\n");
  304. //}