void runloop_tick(runloop_state_t *state) { long long now = get_time_nsec(); long long ticks_between = now - state->last_end; float seconds = (float)ticks_between / (float)1000000000; int cycles = seconds * (float)state->asic->clock_rate; if (cycles == 0) return; runloop_tick_cycles(state, cycles); state->last_end = now; }
int command_run(debugger_state_t *state, int argc, char **argv) { state->asic->stopped = 0; uint16_t instructions = -1; struct run_disassemble_state dstate; dstate.memory.read_byte = run_command_read_byte; dstate.memory.current = state->asic->cpu->registers.PC; dstate.state = state; int oldHalted = 0; int isFirstInstruction = 1; if ((argc == 2 && strcmp(argv[1], "--help") == 0) || argc > 2) { state->print(state, "run [instructions] - run a specified number of instructions\n" " If no number is specified, the emulator will run until interrupted (^C).\n"); return 0; } else if(argc == 2) { instructions = parse_expression_z80e(state, argv[1]); state->debugger->state = DEBUGGER_LONG_OPERATION; for (; instructions > 0; instructions--) { hook_on_before_execution(state->asic->hook, state->asic->cpu->registers.PC); if (!isFirstInstruction && state->asic->stopped) { state->asic->stopped = 0; break; } if (isFirstInstruction) { state->asic->stopped = 0; isFirstInstruction = 0; } if (state->debugger->flags.echo) { if (!state->asic->cpu->halted) { state->print(state, "0x%04X: ", state->asic->cpu->registers.PC); dstate.memory.current = state->asic->cpu->registers.PC; parse_instruction(&(dstate.memory), run_command_write, state->debugger->flags.knightos); state->print(state, "\n"); } } else { if (state->asic->cpu->halted && !oldHalted) { state->print(state, "CPU is halted\n"); } } if (state->debugger->flags.echo_reg) { print_state(&state->asic->cpu->registers); } oldHalted = state->asic->cpu->halted; int iff1 = state->asic->cpu->IFF1; int iff2 = state->asic->cpu->IFF2; if (state->debugger->flags.nointonstep) { state->asic->cpu->IFF1 = 0; state->asic->cpu->IFF2 = 0; } runloop_tick_cycles(state->asic->runloop, 1); if (state->debugger->flags.nointonstep) { state->asic->cpu->IFF1 = iff1; state->asic->cpu->IFF2 = iff2; } hook_on_after_execution(state->asic->hook, state->asic->cpu->registers.PC); if (state->asic->stopped) { state->asic->stopped = 0; break; } } state->debugger->state = DEBUGGER_ENABLED; return 0; } state->debugger->state = DEBUGGER_LONG_OPERATION_INTERRUPTABLE; while (1) { hook_on_before_execution(state->asic->hook, state->asic->cpu->registers.PC); if (!isFirstInstruction && state->asic->stopped) { state->asic->stopped = 0; break; } if (isFirstInstruction) { state->asic->stopped = 0; isFirstInstruction = 0; } if (state->debugger->flags.echo) { if (!state->asic->cpu->halted) { state->print(state, "0x%04X: ", state->asic->cpu->registers.PC); dstate.memory.current = state->asic->cpu->registers.PC; parse_instruction(&(dstate.memory), run_command_write, state->debugger->flags.knightos); state->print(state, "\n"); } } else { if (state->asic->cpu->halted && !oldHalted) { if (state->debugger->flags.auto_on) { if (!((ti_bw_lcd_t *)state->asic->cpu->devices[0x10].device)->display_on) { state->asic->cpu->halted = 0; state->print(state, "Turned on calculator via auto_on\n"); } } else { state->print(state, "CPU is halted\n"); } } } if (state->debugger->flags.echo_reg) { print_state(&state->asic->cpu->registers); } oldHalted = state->asic->cpu->halted; runloop_tick_cycles(state->asic->runloop, 1); hook_on_before_execution(state->asic->hook, state->asic->cpu->registers.PC); if (state->asic->stopped) { state->debugger->state = DEBUGGER_ENABLED; return 0; } } state->debugger->state = DEBUGGER_ENABLED; return 0; }