int test_CPD() { asic_t *device = asic_init(TI83p); uint8_t test[] = { 0xED, 0xA9 }; // CPD device->cpu->registers.HL = 0xC002; device->cpu->registers.BC = 5; device->cpu->registers.A = 0x11; cpu_write_byte(device->cpu, 0xC000, 0x11); cpu_write_byte(device->cpu, 0xC001, 0x22); cpu_write_byte(device->cpu, 0xC002, 0x33); flash(device, test, sizeof(test)); int cycles = cpu_execute(device->cpu, 16); if (device->cpu->registers.flags.Z != 0 || device->cpu->registers.HL != 0xC001 || device->cpu->registers.BC != 4 || cycles != 0) { asic_free(device); return 1; } device->cpu->registers.PC = 0; cpu_execute(device->cpu, 16); device->cpu->registers.PC = 0; cpu_execute(device->cpu, 16); if (device->cpu->registers.flags.Z != 1 || device->cpu->registers.HL != 0xBFFF || device->cpu->registers.BC != 2) { asic_free(device); return 1; } asic_free(device); return 0; }
void emu_loop(bool reset) { if (reset) { emu_reset(); } exiting = false; #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(emu_inner_loop, -1, 1); #else while (!exiting) { if (cpu_events & EVENT_RESET) { cpu_events = EVENT_NONE; gui_console_printf("CPU Reset triggered..."); emu_reset(); } if (cpu_events & EVENT_DEBUG_STEP) { cpu_events = EVENT_NONE; debugger(DBG_STEP, 0); } sched_process_pending_events(); if (cycle_count_delta < 0) { cpu_execute(); // execute instructions with available clock cycles } else { QThread::yieldCurrentThread(); } } emu_cleanup(); #endif }
int test_LDDR() { asic_t *device = asic_init(TI83p); uint8_t test[] = { 0xED, 0xB8 }; // LDDR device->cpu->registers.HL = 0xC004; device->cpu->registers.DE = 0xD004; device->cpu->registers.BC = 5; cpu_write_byte(device->cpu, 0xC000, 0x11); cpu_write_byte(device->cpu, 0xC001, 0x22); cpu_write_byte(device->cpu, 0xC002, 0x33); cpu_write_byte(device->cpu, 0xC003, 0x44); cpu_write_byte(device->cpu, 0xC004, 0x55); flash(device, test, sizeof(test)); int cycles = cpu_execute(device->cpu, 100); if (cpu_read_byte(device->cpu, 0xD000) != 0x11 || cpu_read_byte(device->cpu, 0xD001) != 0x22 || cpu_read_byte(device->cpu, 0xD002) != 0x33 || cpu_read_byte(device->cpu, 0xD003) != 0x44 || cpu_read_byte(device->cpu, 0xD004) != 0x55 || device->cpu->registers.HL != 0xBFFF || device->cpu->registers.DE != 0xCFFF || device->cpu->registers.BC != 0 || cycles != 0) { asic_free(device); return 1; } asic_free(device); return 0; }
// TODO : Make sure it works with the recent commits. void emu_inner_loop(void) { while (!exiting) { sched_process_pending_events(); if (cpu_events & EVENT_RESET) { gui_console_printf("CPU Reset triggered..."); emu_reset(); } if (cycle_count_delta < 0) { cpu_execute(); // execute instructions with available clock cycles } } }
int test_CPDR() { asic_t *device = asic_init(TI83p); uint8_t test[] = { 0xED, 0xB9 }; // CPDR device->cpu->registers.HL = 0xC004; device->cpu->registers.BC = 5; device->cpu->registers.A = 0x33; cpu_write_byte(device->cpu, 0xC001, 0x22); cpu_write_byte(device->cpu, 0xC002, 0x33); cpu_write_byte(device->cpu, 0xC003, 0x44); cpu_write_byte(device->cpu, 0xC004, 0x55); flash(device, test, sizeof(test)); int cycles = cpu_execute(device->cpu, 58); if (device->cpu->registers.HL != 0xC001 || device->cpu->registers.BC != 2 || cycles != 0) { asic_free(device); return 1; } asic_free(device); return 0; }
int main(int argc, char* argv[]) { int numtasks,rank,len,rc; char hostname[MPI_MAX_PROCESSOR_NAME]; FILE * fp = fopen(source, "r"); if (fp == NULL) { printf("Can't find input file!\n"); return 1; } rc=MPI_Init(&argc, &argv); if (rc != MPI_SUCCESS) { printf("Error starting MPI program. Terminating.\n"); MPI_Abort(MPI_COMM_WORLD, rc); } MPI_Comm_size(MPI_COMM_WORLD, &numtasks); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Get_processor_name(hostname, &len); printf ("Number of tasks = %d My rank = %d Running on %s\n",numtasks,rank,hostname); switch(rank) { case 0: cpu_issue(fp); break; // This steps reads the register values received from last process case 1: cpu_decode(); break; case 2: cpu_execute(); break; // Registers and memory access in one step case 3: cpu_data_access(); break; default: printf("This process does nothing."); } MPI_Finalize(); }
static void emu_main_loop_inner(void) { if (!emulationPaused) { if (cpuEvents & EVENT_RESET) { gui_console_printf("[CEmu] Calculator reset triggered...\n"); cpu_reset(); cpuEvents &= ~EVENT_RESET; } #ifdef DEBUG_SUPPORT if (!cpu.halted && (cpuEvents & EVENT_DEBUG_STEP)) { cpuEvents &= ~EVENT_DEBUG_STEP; open_debugger(DBG_STEP, 0); } #endif if (!asic.shipModeEnabled) { sched_process_pending_events(); cpu_execute(); } else { gui_emu_sleep(50); } } else { gui_emu_sleep(50); } }
int test_LDI() { asic_t *device = asic_init(TI83p, NULL); uint8_t test[] = { 0xED, 0xA0 }; // LDI device->cpu->registers.HL = 0xC000; device->cpu->registers.DE = 0xD000; device->cpu->registers.BC = 5; cpu_write_byte(device->cpu, 0xC000, 0x11); cpu_write_byte(device->cpu, 0xC001, 0x22); cpu_write_byte(device->cpu, 0xC002, 0x33); cpu_write_byte(device->cpu, 0xC003, 0x44); cpu_write_byte(device->cpu, 0xC004, 0x55); flash(device, test, sizeof(test)); int cycles = cpu_execute(device->cpu, 16); if (cpu_read_byte(device->cpu, 0xD000) != 0x11 || device->cpu->registers.HL != 0xC001 || device->cpu->registers.DE != 0xD001 || device->cpu->registers.BC != 4 || cycles != 0) { asic_free(device); return 1; } asic_free(device); return 0; }
int main(int argc, char **argv) { struct parg_state ps; int c; int interactive = 0; char *execute = NULL; int t = 0; int p = 0; parg_init(&ps); while((c = parg_getopt(&ps, argc, argv, "pthie:")) != -1) { switch(c) { case 1: printf("nonoption '%s'\n", ps.optarg); break; case 'i': interactive++; break; case 'e': execute = (char *)ps.optarg; break; case 't': t++; break; case 'p': p++; break; case 'h': printf("usage: stir [-i input]\n"); return EXIT_SUCCESS; default: printf("unknown option: %c", (char)c); } } if (t) { uint8_t memory[32]; uint32_t instructions[] = { bytecode_iconst(32), bytecode_iconst(10), bytecode_pop(0, 4), bytecode_pop(1, 4), bytecode_iadd(0, 1, 2), bytecode_store(2, 0), bytecode_push(2, 4), bytecode_halt(0) }; int ret = cpu_execute(instructions, sizeof(instructions) / sizeof(instructions[0]), memory, sizeof(memory) / sizeof(memory[0]), 0); printf("[%d]\n", ret); int i = 0; for(; i < sizeof(memory) / sizeof(memory[0]); i++) { if ((i % 16) == 0) { printf("\n"); } printf("%02x ", memory[i]); } } printf("\n----------\n"); parser_t parser_val; parser_t *parser = &parser_val; parser_init(parser); if (execute != NULL) { uint32_t* instructions; uint8_t* data; uint32_t i_count; uint32_t d_count; token_t* tokens; int t_count; parser_process(parser, execute, &tokens, &t_count); code_generator_generate(tokens, t_count, &instructions, &i_count, &data, &d_count); printf("ptr %p", instructions); // TODO(sebe): copy over the data to the memory // and structure the program's memory sanely uint8_t memory[32]; d_count = 32; if (!p) { int ret = cpu_execute(instructions, i_count, memory, d_count, 0); printf("[%d]\n", ret); int i = 0; for(; i < d_count; i++) { if ((i % 16) == 0) { printf("\n"); } printf("%02x ", memory[i]); } } } if (interactive) { printf("\n>"); char* line; while ((line = read_stdin())) { if (line != NULL) { token_t* tokens; int t_count; printf("%s", line); parser_process(parser, line, &tokens, &t_count); } printf("\n>"); } } parser_free(parser); return 0; }
void runloop_tick_cycles(runloop_state_t *state, int cycles) { int total_cycles = 0; int cycles_until_next_tick = cycles; int current_tick = 0; int i; for (i = 0; i < state->asic->timers->max_timers; i++) { z80_hardware_timer_t *timer = &state->asic->timers->timers[i]; if (!(timer->flags & TIMER_IN_USE)) { continue; } int tot_cycles = cycles; if (timer->cycles_until_tick < tot_cycles) { retry: state->ticks[current_tick].index = i; state->ticks[current_tick].after_cycle = timer->cycles_until_tick + (cycles - tot_cycles); tot_cycles -= timer->cycles_until_tick; timer->cycles_until_tick = state->asic->clock_rate / timer->frequency; current_tick++; if (current_tick == state->max_tick_count) { state->max_tick_count += 10; state->ticks = realloc(state->ticks, sizeof(timer_tick_t) * state->max_tick_count); } if (timer->cycles_until_tick <= tot_cycles) { goto retry; } } else { timer->cycles_until_tick -= tot_cycles; } } qsort(state->ticks, current_tick, sizeof(timer_tick_t), runloop_compare); if (current_tick > 0) { cycles_until_next_tick = state->ticks[0].after_cycle; } int tick_i = 0; while (cycles > 0) { int ran = cycles_until_next_tick - cpu_execute(state->asic->cpu, cycles_until_next_tick); total_cycles += ran; cycles -= ran; if (total_cycles >= state->ticks[tick_i].after_cycle) { tick_i++; if (tick_i <= current_tick) { int index = state->ticks[tick_i - 1].index; z80_hardware_timer_t *timer = &state->asic->timers->timers[index]; timer->on_tick(state->asic, timer->data); cycles_until_next_tick = state->ticks[tick_i].after_cycle - total_cycles; } else { cycles_until_next_tick = cycles; } } } state->spare_cycles = cycles; }
/* Proper USB emulation should really be a thing at some point :P */ bool sendVariableLink(const char *var_name) { FILE *file; uint8_t tmp_buf[0x80]; uint8_t var_size_low, var_size_high, var_type, var_arc; uint8_t *run_asm_safe = phys_mem_ptr(safe_ram_loc, 1), *cxCurApp = phys_mem_ptr(0xD007E0, 1), *op1 = phys_mem_ptr(0xD005F8, 1), *var_ptr; uint16_t var_size; const size_t h_size = sizeof(header_data); const size_t op_size = 9; /* Return if we are at an error menu */ if(*cxCurApp == 0x52) { return false; } file = fopen_utf8(var_name,"rb"); if (!file) return false; if (fread(tmp_buf, 1, h_size, file) != h_size) goto r_err; if (memcmp(tmp_buf, header_data, h_size)) goto r_err; if (fseek(file, 0x48, 0)) goto r_err; if (fread(&var_size_low, 1, 1, file) != 1) goto r_err; if (fread(&var_size_high, 1, 1, file) != 1) goto r_err; if (fseek(file, 0x3B, 0)) goto r_err; if (fread(&var_type, 1, 1, file) != 1) goto r_err; if (fseek(file, 0x45, 0)) goto r_err; if (fread(&var_arc, 1, 1, file) != 1) goto r_err; cpu.halted = cpu.IEF_wait = 0; cpu.registers.PC = safe_ram_loc; memcpy(run_asm_safe, jforcegraph, sizeof(jforcegraph)); cycle_count_delta = -5000000; cpu_execute(); if (fseek(file, 0x3B, 0)) goto r_err; if (fread(op1, 1, op_size, file) != op_size) goto r_err; cpu.halted = cpu.IEF_wait = 0; cpu.registers.PC = safe_ram_loc; run_asm_safe[0] = 0x21; run_asm_safe[1] = var_size_low; run_asm_safe[2] = var_size_high; run_asm_safe[3] = 0x00; run_asm_safe[4] = 0x3E; run_asm_safe[5] = var_type; memcpy(&run_asm_safe[6], pgrm_loader, sizeof(pgrm_loader)); cycle_count_delta = -10000000; cpu_execute(); var_ptr = phys_mem_ptr((run_asm_safe[0]) | (run_asm_safe[1] << 8) | (run_asm_safe[2] << 16), 1); var_size = (var_size_high << 8) | var_size_low; if (fseek(file, 0x4A, 0)) goto r_err; if (fread(var_ptr, 1, var_size, file) != var_size) goto r_err; if (var_arc == 0x80) { cpu.halted = cpu.IEF_wait = 0; cpu.registers.PC = safe_ram_loc; memcpy(run_asm_safe, archivevar, sizeof(archivevar)); cycle_count_delta = -1000000; cpu_execute(); } cpu.halted = cpu.IEF_wait = 0; cpu.registers.PC = safe_ram_loc; memcpy(run_asm_safe, jforcehome, sizeof(jforcehome)); cycle_count_delta = -5000000; cpu_execute(); return !fclose(file); r_err: fclose(file); return false; }
void cpu_cycle(struct cpu* cpu) { cpu_fetch(cpu); cpu_execute(cpu); cpu_update_timers(cpu); }
LRESULT CALLBACK DebuggerDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { SCROLLINFO si; breakpoint_t *bp; switch(message) { case WM_INITDIALOG: pc = nes->cpu.pc; si.cbSize = sizeof(SCROLLINFO); si.fMask = SIF_PAGE | SIF_RANGE; si.nMin = 0; si.nMax = 0xFFFF; si.nPage = 0x400; SetScrollInfo(GetDlgItem(hDlg,IDC_DISASMSCROLL),SB_CTL,&si,TRUE); update(hDlg); return(TRUE); case WM_COMMAND: switch(LOWORD(wParam)) { //control case IDC_STEPBUTTON: cpu_execute(1); pc = nes->cpu.pc; update(hDlg); return(TRUE); case IDC_RUNBUTTON: return(TRUE); case IDC_SOFTRESETBUTTON: nes_reset(0); return(TRUE); case IDC_HARDRESETBUTTON: nes_reset(1); return(TRUE); //seeking case IDC_SEEKCURRENTPCBUTTON: pc = nes->cpu.pc; update(hDlg); return(TRUE); case IDC_SEEKADDRESSBUTTON: update(hDlg); return(TRUE); //breakpoint handling case IDC_ADDBPBUTTON: bp = DialogBoxParam(hInst,(LPCTSTR)IDD_BREAKPOINT,hWnd,BreakpointDlg,(LPARAM)0); return(TRUE); case IDOK: case IDCANCEL: EndDialog(hDlg,LOWORD(wParam)); return(TRUE); } break; case WM_VSCROLL: if((HWND)lParam == GetDlgItem(hDlg,IDC_DISASMSCROLL)) { log_printf("scrolling\n"); si.cbSize = sizeof(SCROLLINFO); si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; GetScrollInfo((HWND)lParam,SB_CTL,&si); switch(LOWORD(wParam)) { case SB_LINEUP: pc--; break; case SB_LINEDOWN: pc++; break; case SB_PAGEUP: pc -= si.nPage; break; case SB_PAGEDOWN: pc += si.nPage; break; case SB_THUMBPOSITION: pc = HIWORD(wParam); break; } if(pc < si.nMin) pc = si.nMin; if(pc > si.nMax) pc = si.nMax; update_disasm(hDlg); } break; } return(FALSE); }