uint8_t execute_interpreter_cycle(cpu_registers* registers, bool nmi_flag) { static bool previous_nmi_flag = false; uint8_t cpu_cycles_executed = 0; uint8_t extra_cycles= 0; if(DMA_is_executing()) cpu_cycles_executed = execute_DMA(); else { uint8_t opcode = fetch_opcode(registers); increment_PC(registers); if(nmi_flag && !previous_nmi_flag) cpu_cycles_executed = execute_NMI(registers); else { #ifdef DEBUG print_debug_info(registers, opcode); #endif extra_cycles = execute_instruction(registers, opcode); cpu_cycles_executed = instruction_cycle_length[opcode] + extra_cycles; // Do not increment PC if we jump because it will skip the first instruction at least if(!is_JSR_or_JMP(opcode) && !is_RTI(opcode)) increment_PC_instruction_length(registers, opcode); } } previous_nmi_flag = nmi_flag; odd_cpu_cycle = cpu_cycles_executed & 0x1; return cpu_cycles_executed; }
void execute_loop(chip_8_cpu cpu, FILE *debug_log) { if (pthread_create(&(cpu->delay_decrement_thread), NULL, delay_thread, cpu) != 0) { shutdown_cpu(cpu, 1); } if (pthread_create(&(cpu->sound_decrement_thread), NULL, sound_thread, cpu) != 0) { fprintf(stderr, "Failed to start the sound register thread, exiting...\n"); shutdown_cpu(cpu, 1); } pthread_detach(cpu->delay_decrement_thread); pthread_detach(cpu->sound_decrement_thread); cpu->chip_8_screen = init_ncurses(default_window_height, default_window_width); refresh_window(cpu->chip_8_screen); while (1) { if (cpu->program_counter >= MEMORY_SIZE) { fprintf(stderr, "ERR - Fatal memory error: invalid access at memory cell: '%d'\n", cpu->program_counter); shutdown_cpu(cpu, 1); } if (cpu->halt) { break; } opcode instr = fetch_opcode(cpu); if (debug_log) { print_debug_info(debug_log, instr, cpu); } execute_opcode(instr, cpu); if (cpu->performed_jump) { cpu->performed_jump = false; continue; } if (cpu->skip_opcode) { cpu->program_counter = cpu->program_counter + 2; cpu->skip_opcode = false; } else { cpu->program_counter = cpu->program_counter + 1; } } // allow 0.1 seconds for the threads to clean up their memory usleep(100000); delwin(cpu->chip_8_screen); endwin(); }