/* * Brings the kernel a swift halt displaying a * message AND CPU registers as an added bonus * @param format The format of the message to display */ void panic_cpu(struct regs *r, const char *format, ...) { release_all_locks(); va_list argp; va_start(argp, format); display_message(format, argp); va_end(argp); display_registers(r); shut_it_down_charlie_brown(); }
void SAM(C64 *the_c64) { bool done = false; char c; TheCPU = the_c64->TheCPU; TheCPU1541 = the_c64->TheCPU1541; TheVIC = the_c64->TheVIC; TheSID = the_c64->TheSID; TheCIA1 = the_c64->TheCIA1; TheCIA2 = the_c64->TheCIA2; // Get CPU registers and current memory configuration TheCPU->GetState(&R64); TheCPU->ExtConfig = (~R64.ddr | R64.pr) & 7; TheCPU1541->GetState(&R1541); #ifdef __riscos__ Wimp_CommandWindow((int)"SAM"); #endif #ifdef AMIGA if (!(fin = fout = ferr = fopen("CON:0/0/640/480/SAM", "w+"))) return; #else fin = stdin; fout = stdout; ferr = stdout; #endif access_1541 = false; address = R64.pc; fprintf(ferr, "\n *** SAM - Simple Assembler and Monitor ***\n *** Press 'h' for help ***\n\n"); init_abort(); display_registers(); while (!done) { if (access_1541) fprintf(ferr, "1541> "); else fprintf(ferr, "C64> "); fflush(ferr); read_line(); while ((c = get_char()) == ' ') ; switch (c) { case 'a': // Assemble get_token(); assemble(); break; case 'b': // Binary dump get_token(); binary_dump(); break; case 'c': // Compare get_token(); compare(); break; case 'd': // Disassemble get_token(); disassemble(); break; case 'e': // Interrupt vectors int_vectors(); break; case 'f': // Fill get_token(); fill(); break; case 'h': // Help help(); break; case 'i': // ASCII dump get_token(); ascii_dump(); break; case 'k': // Memory configuration get_token(); mem_config(); break; case 'l': // Load data get_token(); load_data(); break; case 'm': // Memory dump get_token(); memory_dump(); break; case 'n': // Screen code dump get_token(); screen_dump(); break; case 'o': // Redirect output get_token(); redir_output(); break; case 'p': // Sprite dump get_token(); sprite_dump(); break; case 'r': // Registers get_reg_token(); registers(); break; case 's': // Save data get_token(); save_data(); break; case 't': // Transfer get_token(); transfer(); break; case 'v': // View machine state view_state(); break; case 'x': // Exit done = true; break; case ':': // Change memory get_token(); modify(); break; case '1': // Switch to 1541 mode access_1541 = true; break; case '6': // Switch to C64 mode access_1541 = false; break; case '?': // Compute expression get_token(); print_expr(); break; case '\n': // Blank line break; default: // Unknown command error("Unknown command"); break; } } exit_abort(); #ifdef AMIGA fclose(fin); #endif if (fout != ferr) fclose(fout); #ifdef __riscos__ Wimp_CommandWindow(-1); #endif // Set CPU registers TheCPU->SetState(&R64); TheCPU1541->SetState(&R1541); }
static void registers(void) { enum Token the_reg; uint16 value; if (the_token != T_END) switch (the_reg = the_token) { case T_A: case T_X: case T_Y: case T_PC: case T_SP: case T_DR: case T_PR: get_token(); if (!expression(&value)) return; switch (the_reg) { case T_A: if (access_1541) R1541.a = value; else R64.a = value; break; case T_X: if (access_1541) R1541.x = value; else R64.x = value; break; case T_Y: if (access_1541) R1541.y = value; else R64.y = value; break; case T_PC: if (access_1541) R1541.pc = value; else R64.pc = value; break; case T_SP: if (access_1541) R1541.sp = (value & 0xff) | 0x0100; else R64.sp = (value & 0xff) | 0x0100; break; case T_DR: if (!access_1541) R64.ddr = value; break; case T_PR: if (!access_1541) R64.pr = value; break; default: break; } break; default: return; } display_registers(); }
/* * 表示コマンド */ static UW display_command(B *command) { INT point=0; B cmd=0; T_RTST rtst; UB b; UH h; UW w, value1, value2; int no, count; char tstate[TSTATE_LEN]; count = sizeof(mon_display) / sizeof(struct SUBCOMMAND_TABLE); if(command[point]){ for(no = 0 ; no < count ; no++){ if(compare_word(mon_display[no].subcommand, command, 0)){ skip_word(command, &point); cmd = mon_display[no].type; break; } } } switch(cmd){ default: /* デフォルト */ cmd = mon_datatype; case MONDISPLAY_BYTE: /* バイト単位メモリ表示 */ case MONDISPLAY_HALF: /* ハーフ単位メモリ表示 */ case MONDISPLAY_WORD: /* ワード単位メモリ表示 */ value2 = 128; if(!get_value(command, &point, &value1, HEX_BASE)) value1 = mon_address; value1 = MonAlignAddress(value1); if(command[point] == '+'){ point++; if(!get_value(command, &point, &value2, HEX_BASE)) value2 = 128; } else{ if(!get_value(command, &point, &value2, HEX_BASE)) value2 = value1 + 128; value2 -= value1; } mon_datatype = cmd; while((W)value2 > 0){ printf("%08lx ", (long)value1); for(no = 0 ; no < 16 ; no += mon_datatype){ if(no == 8) putchar(' '); switch(mon_datatype){ case DATA_HALF: if(MemoryRead(value1+no, &h, 2) == 0) h = -1; printf("%04x ", h); break; case DATA_WORD: if(MemoryRead(value1+no, &w, 4) == 0) w = -1; printf("%08lx ", (long)w); break; default: if(MemoryRead(value1+no, &b, 1) == 0) b = -1; printf("%02x ", b); break; } } if(getMemoryType(value1+no, 0) == MEMORY_AREA){ for(no = 0 ; no < 16 ; no++){ if(MemoryRead(value1+no, &b, 1)){ if(b < ' ' || b >= 0xE0) b = '.'; else if(b >= 127 && b < 0xA0) b = '.'; } else b = '.'; putchar(b); } } putchar('\n'); value1 += 16; value2 -= 16; tslp_tsk(50); if(monitor_break()) value2 = 0; } mon_address = value1; break; case MONDISPLAY_TASK: /* タスク状態表示 */ printf("cur id pri state pc stack inistack inisize\n"); for(no = 0 ; no < tmax_tskid ; no++){ ref_tst(no+TMIN_TSKID, &rtst); if(current_tskid == (no+TMIN_TSKID)) printf(" * "); else printf(" "); if(MONTASK == (no+TMIN_TSKID)) printf(" mon"); else printf(" %03d", no+TMIN_TSKID); value1 = get_taskstate(rtst.tskstat); for(count = 0 ; count < TSTATE_LEN-1 ; count++){ if((tstate[count] = task_state[value1][count]) == 0) tstate[count] = ' '; } tstate[count] = 0; printf(" %3d %s", rtst.tskpri, (VP_INT)tstate); if(rtst.tskstat == TTS_RUN) printf(" "); else printf(" %08lx", (unsigned long)rtst.tskpc); printf(" %08lx %08lx %5ld\n", (unsigned long)rtst.tsksp, (unsigned long)rtst.inistk, (unsigned long)rtst.inistksz); } putchar('\n'); break; case MONDISPLAY_REG: /* レジスタの表示 */ if(current_tskid != MONTASK) display_registers(current_tskid); break; } return 0; }
int callback_emu ( struct lws *wsi, //enum lws_callback_reasons reason, enum lws_callback_reasons reason, void *user, void *in, size_t len) { Cpu *cpu = emu->cpu; Port_1 *p1 = emu->cpu->p1; Debugger *deb = emu->debugger; switch (reason) { case LWS_CALLBACK_ESTABLISHED: { puts("connection established"); // Flip ready flag for the emulator to begin deb->web_server_ready = true; // get the ball rolling //libwebsocket_callback_on_writable(this, wsi); lws_callback_on_writable(wsi); break; } case LWS_CALLBACK_SERVER_WRITEABLE: { if ( !packet_queue_empty(emu) ) { Packet p = packet_dequeue(emu); void *msg = p.message; size_t msg_len = p.length; uint8_t op = p.opcode; //printf("[%s] of len %u, opcode: %u\n\n", //(char *)msg, (unsigned int)msg_len, op); // Leave room for websock header/trailer & opcode size_t pack_len = msg_len + sizeof(op) + LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING; void *packet = malloc(pack_len); // Zero out our packet memset( (packet + LWS_SEND_BUFFER_PRE_PADDING), 0, msg_len + sizeof(op) ); // Place opcode into packet *((uint8_t *)(packet + LWS_SEND_BUFFER_PRE_PADDING)) = op; // Place message into packet memcpy( (packet + LWS_SEND_BUFFER_PRE_PADDING + sizeof(op)), (const void *)p.message, msg_len); /* int i; for (i = 0;i < pack_len;i++){ printf( "%02X (%c) | ", *((uint8_t *)(packet+i)), *((char *)(packet+i)) ); } puts("\n"); */ lws_write(wsi, packet+LWS_SEND_BUFFER_PRE_PADDING, msg_len + sizeof(op), LWS_WRITE_BINARY); free(p.message); free(packet); } static bool p1_0_on = false; static bool p1_1_on = false; static bool p1_2_on = false; static bool p1_3_on = false; static bool p1_4_on = false; static bool p1_5_on = false; static bool p1_6_on = false; static bool p1_7_on = false; // P1.0 ON/OFF if (p1->DIR_0 == OUT) { if (p1->OUT_0 == HIGH) { if (p1_0_on == false) { send_control(emu, P1_0_ON_PACKET, NULL, 0); p1_0_on = true; } } else if (p1->OUT_0 == LOW) { if (p1_0_on == true) { send_control(emu, P1_0_OFF_PACKET, NULL, 0); p1_0_on = false; } } } // P1.1 ON/OFF if (p1->DIR_1 == OUT) { if (p1->OUT_1 == HIGH) { if (p1_1_on == false) { send_control(emu, P1_1_ON_PACKET, NULL, 0); p1_1_on = true; } } else if (p1->OUT_1 == LOW) { if (p1_1_on == true) { send_control(emu, P1_1_OFF_PACKET, NULL, 0); p1_1_on = false; } } } // P1.2 ON/OFF if (p1->DIR_2 == OUT) { if (p1->OUT_2 == HIGH) { if (p1_2_on == false) { send_control(emu, P1_2_ON_PACKET, NULL, 0); p1_2_on = true; } } else if (p1->OUT_2 == LOW) { if (p1_2_on == true) { send_control(emu, P1_2_OFF_PACKET, NULL, 0); p1_2_on = false; } } } // P1.3 ON/OFF if (p1->DIR_3 == OUT) { if (p1->OUT_3 == HIGH) { if (p1_3_on == false) { send_control(emu, P1_3_ON_PACKET, NULL, 0); p1_3_on = true; } } else if (p1->OUT_3 == LOW) { if (p1_3_on == true) { send_control(emu, P1_3_OFF_PACKET, NULL, 0); p1_3_on = false; } } } // P1.4 ON/OFF if (p1->DIR_4 == OUT) { if (p1->OUT_4 == HIGH) { if (p1_4_on == false) { send_control(emu, P1_4_ON_PACKET, NULL, 0); p1_4_on = true; } } else if (p1->OUT_4 == LOW) { if (p1_4_on == true) { send_control(emu, P1_4_OFF_PACKET, NULL, 0); p1_4_on = false; } } } // P1.5 ON/OFF if (p1->DIR_5 == OUT) { if (p1->OUT_5 == HIGH) { if (p1_5_on == false) { send_control(emu, P1_5_ON_PACKET, NULL, 0); p1_5_on = true; } } else if (p1->OUT_5 == LOW) { if (p1_5_on == true) { send_control(emu, P1_5_OFF_PACKET, NULL, 0); p1_5_on = false; } } } // P1.6 ON/OFF if (p1->DIR_6 == OUT) { if (p1->OUT_6 == HIGH) { if (p1_6_on == false) { send_control(emu, P1_6_ON_PACKET, NULL, 0); p1_6_on = true; } } else if (p1->OUT_6 == LOW) { if (p1_6_on == true) { send_control(emu, P1_6_OFF_PACKET, NULL, 0); p1_6_on = false; } } } // P1.7 ON/OFF if (p1->DIR_7 == OUT) { if (p1->OUT_7 == HIGH) { if (p1_7_on == false) { send_control(emu, P1_7_ON_PACKET, NULL, 0); p1_7_on = true; } } else if (p1->OUT_7 == LOW) { if (p1_7_on == true) { send_control(emu, P1_7_OFF_PACKET, NULL, 0); p1_7_on = false; } } } lws_callback_on_writable( wsi); break; } case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: { puts("Connection Error"); break; } case LWS_CALLBACK_CLOSED: { puts("Connection Closed"); exit(0); break; } case LWS_CALLBACK_CLIENT_WRITEABLE: { puts("cli writable"); break; } case LWS_CALLBACK_RECEIVE: { static FILE *fp = NULL; static bool upload_in_progress = false; static uint32_t uploaded_bytes, file_size; char *buf = (char *)in; if (upload_in_progress) { // Continue transaction of upload int i; for (i = 0;i < len;i++){ fwrite(&buf[i], 1, 1, fp); uploaded_bytes++; if (uploaded_bytes >= file_size) { puts("met bytes"); fclose(fp); system("msp430-objcopy -O binary tmp.elf tmp.bin"); deb->web_firmware_uploaded = true; upload_in_progress = false; return 0; } } return 0; } unsigned char opcode = buf[0]; printf("opcode: %02X\n", *(uint8_t*)in); switch (opcode) { case 0x00: { // Upload File uint8_t byte1 = *((uint8_t *)(in+1)); uint8_t byte2 = *((uint8_t *)(in+2)); uint8_t byte3 = *((uint8_t *)(in+3)); uint8_t byte4 = *((uint8_t *)(in+4)); file_size = 0; file_size = byte1; file_size <<= 3*8; file_size |= ((0x00000000 | byte2) << 2*8); file_size |= ((0x00000000 | byte3) << 1*8); file_size |= ((0x00000000 | byte4)); printf("got in with file_size %u, but got len %d\n", (unsigned int)file_size, (unsigned int)len); if (file_size >= 40000) { exit(1); deb->quit = true; } upload_in_progress = true; uploaded_bytes = 0; fp = fopen("tmp.elf", "wb"); // Get Any Bytes that are in with this packet int i; for (i = 5;i < len;i++){ fwrite(&buf[i], 1, 1, fp); uploaded_bytes++; if (uploaded_bytes >= file_size) { puts("met bytes"); fclose(fp); system("msp430-objcopy -O binary tmp.elf tmp.bin"); deb->web_firmware_uploaded = true; upload_in_progress = false; return 0; } } break; } case 0x01: { // PLAY printf("Got play\n"); cpu->running = true; deb->debug_mode = false; update_register_display(emu); return 0; } case 0x02: { // PAUSE printf("Got pause\n"); if (cpu->running) { cpu->running = false; deb->debug_mode = true; // display first round of registers display_registers(emu); disassemble(emu, cpu->pc, 1); update_register_display(emu); } return 0; } case 0x03: { // SERIAL DATA if (len > 1000) exit(1); lent = len - 1; data = (uint8_t *) (in + 1); pthread_t t; if( pthread_create(&t, NULL, thrd, (void *)cpu->usci ) ) { fprintf(stderr, "Error creating thread\n"); } //printf("Got serial data %s ... %d bytes long\n", //(char *)(in + 1), (unsigned int)len - 1); return 0; } case 0x04: { // Console Input Data if (len > 1000) exit(1); buf = buf + 1; printf("%s\n", buf); if (!cpu->running && deb->debug_mode) { exec_cmd(emu, buf, len); update_register_display(emu); } return 0; } default: break; } } default: { break; } } return 0; }