static void nmi_int_handler(void) { // Non Maskable Interrupt -- remove interrupt event from queue remove_interupt_event(); // setup r4300 Status flags: reset TS and SR, set BEV, ERL, and SR g_cp0_regs[CP0_STATUS_REG] = (g_cp0_regs[CP0_STATUS_REG] & ~UINT32_C(0x00380000)) | UINT32_C(0x00500004); g_cp0_regs[CP0_CAUSE_REG] = 0x00000000; // simulate the soft reset code which would run from the PIF ROM r4300_reset_soft(); // clear all interrupts, reset interrupt counters back to 0 g_cp0_regs[CP0_COUNT_REG] = 0; g_gs_vi_counter = 0; init_interupt(); // clear the audio status register so that subsequent write_ai() calls will work properly g_ai.regs[AI_STATUS_REG] = 0; // set ErrorEPC with the last instruction address g_cp0_regs[CP0_ERROREPC_REG] = PC->addr; // reset the r4300 internal state if (r4300emu != CORE_PURE_INTERPRETER) { // clear all the compiled instruction blocks and re-initialize free_blocks(); init_blocks(); } // adjust ErrorEPC if we were in a delay slot, and clear the delay_slot and dyna_interp flags if(delay_slot==1 || delay_slot==3) { g_cp0_regs[CP0_ERROREPC_REG]-=4; } delay_slot = 0; dyna_interp = 0; // set next instruction address to reset vector last_addr = UINT32_C(0xa4000040); generic_jump_to(UINT32_C(0xa4000040)); }
void r4300_init(void) { current_instruction_table = cached_interpreter_table; delay_slot=0; stop = 0; rompause = 0; /* clear instruction counters */ #if defined(COUNT_INSTR) memset(instr_count, 0, 131 * sizeof(instr_count[0])); #endif last_addr = 0xa4000040; next_interupt = 624999; init_interupt(); if (r4300emu == CORE_PURE_INTERPRETER) { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Pure Interpreter"); r4300emu = CORE_PURE_INTERPRETER; pure_interpreter_init(); } #if defined(DYNAREC) else if (r4300emu >= 2) { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Dynamic Recompiler"); { r4300emu = CORE_DYNAREC; init_blocks(); #ifdef NEW_DYNAREC new_dynarec_init(); #elif !defined(NO_ASM) && defined(DYNAREC) dyna_start(dynarec_setup_code); #endif } } #endif else /* if (r4300emu == CORE_INTERPRETER) */ { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Cached Interpreter"); r4300emu = CORE_INTERPRETER; init_blocks(); jump_to(0xa4000040); /* Prevent segfault on failed jump_to */ if (!actual->block) return; last_addr = PC->addr; } }
int main(void) { SystemInit(); SystemCoreClockUpdate(); led_init(); init_interupt(); init_pwm(pwm_pin_num, pwm_channel, period, 0); init_coil(); init_timer(); init_ADC(); init_timer(); #ifdef DEBUG_WEIGHT int a; for (a = 0; a < COUNT; a++) { temp[a] = 0; } #endif printf("Weight Meassure. clibration: %d \n Press Button 1 to calibrate \n", calibrate); delay_ms(5000); if (button_pressed_1) { calibrate = true; button_pressed_1 = false; printf("Device will be calibrated \n"); } else { printf("Stock calibration will be used bei Temperatur:%g \n",calibration_temp); calibrate = false; } while (1) { measure_button(); //Funktion zum Start der Messung delay_ms(5); catapult_button(); check_temperatur(MAX_TEMP); delay_ms(2000); // printf("%g\n",compute_temperatur()); } return 0; }
void gen_interupt() { if(!__emulation_run) stop = 1; if (stop == 1) { vi_counter = 0; // debug dyna_stop(); } if (savestates_job & LOADSTATE) { savestates_load(); savestates_job &= ~LOADSTATE; return; } if (skip_jump) { if (q->count > Count || (Count - q->count) < 0x80000000) next_interupt = q->count; else next_interupt = 0; if (interpcore) { interp_addr = skip_jump; last_addr = interp_addr; } else { unsigned int dest = skip_jump; skip_jump=0; jump_to(dest); last_addr = PC->addr; } skip_jump=0; return; } switch(q->type) { case SPECIAL_INT: if (Count > 0x10000000) return; remove_interupt_event(); add_interupt_event_count(SPECIAL_INT, 0); return; break; case VI_INT: if(vi_counter < 60) { if (vi_counter == 0) cheat_apply_cheats(ENTRY_BOOT); vi_counter++; } else { cheat_apply_cheats(ENTRY_VI); } updateScreen(); #ifdef WITH_LIRC lircCheckInput(); #endif SDL_PumpEvents(); refresh_stat(); // if paused, poll for input events if(rompause) { osd_render(); // draw Paused message in case updateScreen didn't do it SDL_GL_SwapBuffers(); while(rompause) { #ifdef __WIN32__ Sleep(10); #else struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 10000000; nanosleep(&ts, NULL); // sleep for 10 milliseconds #endif SDL_PumpEvents(); #ifdef WITH_LIRC lircCheckInput(); #endif //WITH_LIRC } } new_vi(); if (vi_register.vi_v_sync == 0) vi_register.vi_delay = 500000; else vi_register.vi_delay = ((vi_register.vi_v_sync + 1)*1500); next_vi += vi_register.vi_delay; if (vi_register.vi_status&0x40) vi_field=1-vi_field; else vi_field=0; remove_interupt_event(); add_interupt_event_count(VI_INT, next_vi); MI_register.mi_intr_reg |= 0x08; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case COMPARE_INT: remove_interupt_event(); Count+=2; add_interupt_event_count(COMPARE_INT, Compare); Count-=2; Cause = (Cause | 0x8000) & 0xFFFFFF83; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case CHECK_INT: remove_interupt_event(); break; case SI_INT: #ifdef WITH_LIRC lircCheckInput(); #endif //WITH_LIRC SDL_PumpEvents(); PIF_RAMb[0x3F] = 0x0; remove_interupt_event(); MI_register.mi_intr_reg |= 0x02; si_register.si_stat |= 0x1000; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case PI_INT: remove_interupt_event(); MI_register.mi_intr_reg |= 0x10; pi_register.read_pi_status_reg &= ~3; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case AI_INT: if (ai_register.ai_status & 0x80000000) // full { unsigned int ai_event = get_event(AI_INT); remove_interupt_event(); ai_register.ai_status &= ~0x80000000; ai_register.current_delay = ai_register.next_delay; ai_register.current_len = ai_register.next_len; add_interupt_event_count(AI_INT, ai_event+ai_register.next_delay); MI_register.mi_intr_reg |= 0x04; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; } else { remove_interupt_event(); ai_register.ai_status &= ~0x40000000; //------- MI_register.mi_intr_reg |= 0x04; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; } break; case SP_INT: remove_interupt_event(); sp_register.sp_status_reg |= 0x303; //sp_register.signal1 = 1; sp_register.signal2 = 1; sp_register.broke = 1; sp_register.halt = 1; if (!sp_register.intr_break) return; MI_register.mi_intr_reg |= 0x01; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case DP_INT: remove_interupt_event(); dpc_register.dpc_status &= ~2; dpc_register.dpc_status |= 0x81; MI_register.mi_intr_reg |= 0x20; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case HW2_INT: // Hardware Interrupt 2 -- remove interrupt event from queue remove_interupt_event(); // setup r4300 Status flags: reset TS, and SR, set IM2 Status = (Status & ~0x00380000) | 0x1000; Cause = (Cause | 0x1000) & 0xFFFFFF83; /* the exception_general() call below will jump to the interrupt vector (0x80000180) and setup the * interpreter or dynarec */ break; case NMI_INT: // Non Maskable Interrupt -- remove interrupt event from queue remove_interupt_event(); // setup r4300 Status flags: reset TS and SR, set BEV, ERL, and SR Status = (Status & ~0x00380000) | 0x00500004; Cause = 0x00000000; // simulate the soft reset code which would run from the PIF ROM r4300_reset_soft(); // clear all interrupts, reset interrupt counters back to 0 Count = 0; vi_counter = 0; init_interupt(); // clear the audio status register so that subsequent write_ai() calls will work properly ai_register.ai_status = 0; // reset the r4300 internal state if (interpcore) /* pure interpreter only */ { // set ErrorEPC with last instruction address and set next instruction address to reset vector ErrorEPC = interp_addr; interp_addr = 0xa4000040; last_addr = interp_addr; } else /* decode-cached interpreter or dynamic recompiler */ { int i; // clear all the compiled instruction blocks for (i=0; i<0x100000; i++) { if (blocks[i]) { if (blocks[i]->block) { free(blocks[i]->block); blocks[i]->block = NULL; } if (blocks[i]->code) { free(blocks[i]->code); blocks[i]->code = NULL; } if (blocks[i]->jumps_table) { free(blocks[i]->jumps_table); blocks[i]->jumps_table = NULL; } if (blocks[i]->riprel_table) { free(blocks[i]->riprel_table); blocks[i]->riprel_table = NULL; } free(blocks[i]); blocks[i] = NULL; } } // re-initialize init_blocks(); // jump to the start ErrorEPC = PC->addr; jump_to(0xa4000040); last_addr = PC->addr; } // adjust ErrorEPC if we were in a delay slot, and clear the delay_slot and dyna_interp flags if(delay_slot==1 || delay_slot==3) { ErrorEPC-=4; } delay_slot = 0; dyna_interp = 0; return; default: remove_interupt_event(); break; } #ifdef NEW_DYNAREC EPC = pcaddr; pcaddr = 0x80000180; Status |= 2; Cause &= 0x7FFFFFFF; pending_exception=1; #else exception_general(); #endif if (savestates_job & SAVESTATE) { savestates_save(); savestates_job &= ~SAVESTATE; } }
void gen_interupt(void) { if (stop == 1) { vi_counter = 0; // debug dyna_stop(); } if (!interupt_unsafe_state) { if (savestates_get_job() == savestates_job_load) { savestates_load(); return; } if (reset_hard_job) { reset_hard(); reset_hard_job = 0; return; } } if (skip_jump) { unsigned int dest = skip_jump; skip_jump = 0; if (q->count > Count || (Count - q->count) < 0x80000000) next_interupt = q->count; else next_interupt = 0; last_addr = dest; generic_jump_to(dest); return; } switch(q->type) { case SPECIAL_INT: if (Count > 0x10000000) return; remove_interupt_event(); add_interupt_event_count(SPECIAL_INT, 0); return; break; case VI_INT: if(vi_counter < 60) { if (vi_counter == 0) cheat_apply_cheats(ENTRY_BOOT); vi_counter++; } else { cheat_apply_cheats(ENTRY_VI); } gfx.updateScreen(); #ifdef WITH_LIRC lircCheckInput(); #endif SDL_PumpEvents(); refresh_stat(); // if paused, poll for input events if(rompause) { osd_render(); // draw Paused message in case gfx.updateScreen didn't do it VidExt_GL_SwapBuffers(); while(rompause) { SDL_Delay(10); SDL_PumpEvents(); #ifdef WITH_LIRC lircCheckInput(); #endif //WITH_LIRC } } new_vi(); if (vi_register.vi_v_sync == 0) vi_register.vi_delay = 500000; else vi_register.vi_delay = ((vi_register.vi_v_sync + 1)*1500); next_vi += vi_register.vi_delay; if (vi_register.vi_status&0x40) vi_field=1-vi_field; else vi_field=0; remove_interupt_event(); add_interupt_event_count(VI_INT, next_vi); MI_register.mi_intr_reg |= 0x08; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case COMPARE_INT: remove_interupt_event(); Count+=count_per_op; add_interupt_event_count(COMPARE_INT, Compare); Count-=count_per_op; Cause = (Cause | 0x8000) & 0xFFFFFF83; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case CHECK_INT: remove_interupt_event(); break; case SI_INT: #ifdef WITH_LIRC lircCheckInput(); #endif //WITH_LIRC SDL_PumpEvents(); PIF_RAMb[0x3F] = 0x0; remove_interupt_event(); MI_register.mi_intr_reg |= 0x02; si_register.si_stat |= 0x1000; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case PI_INT: remove_interupt_event(); MI_register.mi_intr_reg |= 0x10; pi_register.read_pi_status_reg &= ~3; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case AI_INT: if (ai_register.ai_status & 0x80000000) // full { unsigned int ai_event = get_event(AI_INT); remove_interupt_event(); ai_register.ai_status &= ~0x80000000; ai_register.current_delay = ai_register.next_delay; ai_register.current_len = ai_register.next_len; add_interupt_event_count(AI_INT, ai_event+ai_register.next_delay); MI_register.mi_intr_reg |= 0x04; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; } else { remove_interupt_event(); ai_register.ai_status &= ~0x40000000; //------- MI_register.mi_intr_reg |= 0x04; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; } break; case SP_INT: remove_interupt_event(); sp_register.sp_status_reg |= 0x203; // sp_register.sp_status_reg |= 0x303; if (!(sp_register.sp_status_reg & 0x40)) return; // !intr_on_break MI_register.mi_intr_reg |= 0x01; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case DP_INT: remove_interupt_event(); dpc_register.dpc_status &= ~2; dpc_register.dpc_status |= 0x81; MI_register.mi_intr_reg |= 0x20; if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg) Cause = (Cause | 0x400) & 0xFFFFFF83; else return; if ((Status & 7) != 1) return; if (!(Status & Cause & 0xFF00)) return; break; case HW2_INT: // Hardware Interrupt 2 -- remove interrupt event from queue remove_interupt_event(); // setup r4300 Status flags: reset TS, and SR, set IM2 Status = (Status & ~0x00380000) | 0x1000; Cause = (Cause | 0x1000) & 0xFFFFFF83; /* the exception_general() call below will jump to the interrupt vector (0x80000180) and setup the * interpreter or dynarec */ break; case NMI_INT: // Non Maskable Interrupt -- remove interrupt event from queue remove_interupt_event(); // setup r4300 Status flags: reset TS and SR, set BEV, ERL, and SR Status = (Status & ~0x00380000) | 0x00500004; Cause = 0x00000000; // simulate the soft reset code which would run from the PIF ROM r4300_reset_soft(); // clear all interrupts, reset interrupt counters back to 0 Count = 0; vi_counter = 0; init_interupt(); // clear the audio status register so that subsequent write_ai() calls will work properly ai_register.ai_status = 0; // set ErrorEPC with the last instruction address ErrorEPC = PC->addr; // reset the r4300 internal state if (r4300emu != CORE_PURE_INTERPRETER) { // clear all the compiled instruction blocks and re-initialize free_blocks(); init_blocks(); } // adjust ErrorEPC if we were in a delay slot, and clear the delay_slot and dyna_interp flags if(delay_slot==1 || delay_slot==3) { ErrorEPC-=4; } delay_slot = 0; dyna_interp = 0; // set next instruction address to reset vector last_addr = 0xa4000040; generic_jump_to(0xa4000040); return; default: DebugMessage(M64MSG_ERROR, "Unknown interrupt queue event type %.8X.", q->type); remove_interupt_event(); break; } #ifdef NEW_DYNAREC if (r4300emu == CORE_DYNAREC) { EPC = pcaddr; pcaddr = 0x80000180; Status |= 2; Cause &= 0x7FFFFFFF; pending_exception=1; } else { exception_general(); } #else exception_general(); #endif if (!interupt_unsafe_state) { if (savestates_get_job() == savestates_job_save) { savestates_save(); return; } } }
void r4300_execute(void) { #if (defined(DYNAREC) && defined(PROFILE_R4300)) unsigned int i; #endif current_instruction_table = cached_interpreter_table; delay_slot=0; stop = 0; rompause = 0; /* clear instruction counters */ #if defined(COUNT_INSTR) memset(instr_count, 0, 131*sizeof(instr_count[0])); #endif last_addr = 0xa4000040; next_interupt = 624999; init_interupt(); if (r4300emu == CORE_PURE_INTERPRETER) { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Pure Interpreter"); r4300emu = CORE_PURE_INTERPRETER; pure_interpreter(); } #if defined(DYNAREC) else if (r4300emu >= 2) { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Dynamic Recompiler"); r4300emu = CORE_DYNAREC; init_blocks(); #ifdef NEW_DYNAREC new_dynarec_init(); new_dyna_start(); new_dynarec_cleanup(); #else dyna_start(dynarec_setup_code); PC++; #endif #if defined(PROFILE_R4300) pfProfile = fopen("instructionaddrs.dat", "ab"); for (i=0; i<0x100000; i++) if (invalid_code[i] == 0 && blocks[i] != NULL && blocks[i]->code != NULL && blocks[i]->block != NULL) { unsigned char *x86addr; int mipsop; // store final code length for this block mipsop = -1; /* -1 == end of x86 code block */ x86addr = blocks[i]->code + blocks[i]->code_length; if (fwrite(&mipsop, 1, 4, pfProfile) != 4 || fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *)) DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data"); } fclose(pfProfile); pfProfile = NULL; #endif free_blocks(); } #endif else /* if (r4300emu == CORE_INTERPRETER) */ { DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Cached Interpreter"); r4300emu = CORE_INTERPRETER; init_blocks(); jump_to(0xa4000040); /* Prevent segfault on failed jump_to */ if (!actual->block) return; last_addr = PC->addr; while (!stop) { #ifdef COMPARE_CORE if (PC->ops == cached_interpreter_table.FIN_BLOCK && (PC->addr < 0x80000000 || PC->addr >= 0xc0000000)) virtual_to_physical_address(PC->addr, 2); CoreCompareCallback(); #endif #ifdef DBG if (g_DebuggerActive) update_debugger(PC->addr); #endif PC->ops(); } free_blocks(); } DebugMessage(M64MSG_INFO, "R4300 emulator finished."); /* print instruction counts */ #if defined(COUNT_INSTR) if (r4300emu == CORE_DYNAREC) instr_counters_print(); #endif }