static void restore_state(void) { struct strbuf sb = STRBUF_INIT; const char *args[] = { "stash", "apply", NULL, NULL }; if (is_null_sha1(stash)) return; reset_hard(head, 1); args[2] = sha1_to_hex(stash); /* * It is OK to ignore error here, for example when there was * nothing to restore. */ run_command_v_opt(args, RUN_GIT_CMD); strbuf_release(&sb); refresh_cache(REFRESH_QUIET); }
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; } } }
int cmd_merge(int argc, const char **argv, const char *prefix) { unsigned char result_tree[20]; struct strbuf buf = STRBUF_INIT; const char *head_arg; int flag, head_invalid = 0, i; int best_cnt = -1, merge_was_ok = 0, automerge_was_ok = 0; struct commit_list *common = NULL; const char *best_strategy = NULL, *wt_strategy = NULL; struct commit_list **remotes = &remoteheads; if (file_exists(git_path("MERGE_HEAD"))) die("You have not concluded your merge. (MERGE_HEAD exists)"); if (read_cache_unmerged()) die("You are in the middle of a conflicted merge." " (index unmerged)"); /* * Check if we are _not_ on a detached HEAD, i.e. if there is a * current branch. */ branch = resolve_ref("HEAD", head, 0, &flag); if (branch && !prefixcmp(branch, "refs/heads/")) branch += 11; if (is_null_sha1(head)) head_invalid = 1; git_config(git_merge_config, NULL); /* for color.ui */ if (diff_use_color_default == -1) diff_use_color_default = git_use_color_default; argc = parse_options(argc, argv, prefix, builtin_merge_options, builtin_merge_usage, 0); if (verbosity < 0) show_diffstat = 0; if (squash) { if (!allow_fast_forward) die("You cannot combine --squash with --no-ff."); option_commit = 0; } if (!allow_fast_forward && fast_forward_only) die("You cannot combine --no-ff with --ff-only."); if (!argc) usage_with_options(builtin_merge_usage, builtin_merge_options); /* * This could be traditional "merge <msg> HEAD <commit>..." and * the way we can tell it is to see if the second token is HEAD, * but some people might have misused the interface and used a * committish that is the same as HEAD there instead. * Traditional format never would have "-m" so it is an * additional safety measure to check for it. */ if (!have_message && is_old_style_invocation(argc, argv)) { strbuf_addstr(&merge_msg, argv[0]); head_arg = argv[1]; argv += 2; argc -= 2; } else if (head_invalid) { struct object *remote_head; /* * If the merged head is a valid one there is no reason * to forbid "git merge" into a branch yet to be born. * We do the same for "git pull". */ if (argc != 1) die("Can merge only exactly one commit into " "empty head"); if (squash) die("Squash commit into empty head not supported yet"); if (!allow_fast_forward) die("Non-fast-forward commit does not make sense into " "an empty head"); remote_head = peel_to_type(argv[0], 0, NULL, OBJ_COMMIT); if (!remote_head) die("%s - not something we can merge", argv[0]); update_ref("initial pull", "HEAD", remote_head->sha1, NULL, 0, DIE_ON_ERR); reset_hard(remote_head->sha1, 0); return 0; } else { struct strbuf msg = STRBUF_INIT; /* We are invoked directly as the first-class UI. */ head_arg = "HEAD"; /* * All the rest are the commits being merged; * prepare the standard merge summary message to * be appended to the given message. If remote * is invalid we will die later in the common * codepath so we discard the error in this * loop. */ if (!have_message) { for (i = 0; i < argc; i++) merge_name(argv[i], &msg); fmt_merge_msg(option_log, &msg, &merge_msg); if (merge_msg.len) strbuf_setlen(&merge_msg, merge_msg.len-1); } } if (head_invalid || !argc) usage_with_options(builtin_merge_usage, builtin_merge_options); strbuf_addstr(&buf, "merge"); for (i = 0; i < argc; i++) strbuf_addf(&buf, " %s", argv[i]); setenv("GIT_REFLOG_ACTION", buf.buf, 0); strbuf_reset(&buf); for (i = 0; i < argc; i++) { struct object *o; struct commit *commit; o = peel_to_type(argv[i], 0, NULL, OBJ_COMMIT); if (!o) die("%s - not something we can merge", argv[i]); commit = lookup_commit(o->sha1); commit->util = (void *)argv[i]; remotes = &commit_list_insert(commit, remotes)->next; strbuf_addf(&buf, "GITHEAD_%s", sha1_to_hex(o->sha1)); setenv(buf.buf, argv[i], 1); strbuf_reset(&buf); } if (!use_strategies) { if (!remoteheads->next) add_strategies(pull_twohead, DEFAULT_TWOHEAD); else add_strategies(pull_octopus, DEFAULT_OCTOPUS); } for (i = 0; i < use_strategies_nr; i++) { if (use_strategies[i]->attr & NO_FAST_FORWARD) allow_fast_forward = 0; if (use_strategies[i]->attr & NO_TRIVIAL) allow_trivial = 0; } if (!remoteheads->next) common = get_merge_bases(lookup_commit(head), remoteheads->item, 1); else { struct commit_list *list = remoteheads; commit_list_insert(lookup_commit(head), &list); common = get_octopus_merge_bases(list); free(list); } update_ref("updating ORIG_HEAD", "ORIG_HEAD", head, NULL, 0, DIE_ON_ERR); if (!common) ; /* No common ancestors found. We need a real merge. */ else if (!remoteheads->next && !common->next && common->item == remoteheads->item) { /* * If head can reach all the merge then we are up to date. * but first the most common case of merging one remote. */ finish_up_to_date("Already up-to-date."); return 0; } else if (allow_fast_forward && !remoteheads->next && !common->next && !hashcmp(common->item->object.sha1, head)) { /* Again the most common case of merging one remote. */ struct strbuf msg = STRBUF_INIT; struct object *o; char hex[41]; strcpy(hex, find_unique_abbrev(head, DEFAULT_ABBREV)); if (verbosity >= 0) printf("Updating %s..%s\n", hex, find_unique_abbrev(remoteheads->item->object.sha1, DEFAULT_ABBREV)); strbuf_addstr(&msg, "Fast-forward"); if (have_message) strbuf_addstr(&msg, " (no commit created; -m option ignored)"); o = peel_to_type(sha1_to_hex(remoteheads->item->object.sha1), 0, NULL, OBJ_COMMIT); if (!o) return 1; if (checkout_fast_forward(head, remoteheads->item->object.sha1)) return 1; finish(o->sha1, msg.buf); drop_save(); return 0; } else if (!remoteheads->next && common->next) ; /* * We are not doing octopus and not fast-forward. Need * a real merge. */ else if (!remoteheads->next && !common->next && option_commit) { /* * We are not doing octopus, not fast-forward, and have * only one common. */ refresh_cache(REFRESH_QUIET); if (allow_trivial && !fast_forward_only) { /* See if it is really trivial. */ git_committer_info(IDENT_ERROR_ON_NO_NAME); printf("Trying really trivial in-index merge...\n"); if (!read_tree_trivial(common->item->object.sha1, head, remoteheads->item->object.sha1)) return merge_trivial(); printf("Nope.\n"); } } else { /* * An octopus. If we can reach all the remote we are up * to date. */ int up_to_date = 1; struct commit_list *j; for (j = remoteheads; j; j = j->next) { struct commit_list *common_one; /* * Here we *have* to calculate the individual * merge_bases again, otherwise "git merge HEAD^ * HEAD^^" would be missed. */ common_one = get_merge_bases(lookup_commit(head), j->item, 1); if (hashcmp(common_one->item->object.sha1, j->item->object.sha1)) { up_to_date = 0; break; } } if (up_to_date) { finish_up_to_date("Already up-to-date. Yeeah!"); return 0; } } if (fast_forward_only) die("Not possible to fast-forward, aborting."); /* We are going to make a new commit. */ git_committer_info(IDENT_ERROR_ON_NO_NAME); /* * At this point, we need a real merge. No matter what strategy * we use, it would operate on the index, possibly affecting the * working tree, and when resolved cleanly, have the desired * tree in the index -- this means that the index must be in * sync with the head commit. The strategies are responsible * to ensure this. */ if (use_strategies_nr != 1) { /* * Stash away the local changes so that we can try more * than one. */ save_state(); } else { memcpy(stash, null_sha1, 20); } for (i = 0; i < use_strategies_nr; i++) { int ret; if (i) { printf("Rewinding the tree to pristine...\n"); restore_state(); } if (use_strategies_nr != 1) printf("Trying merge strategy %s...\n", use_strategies[i]->name); /* * Remember which strategy left the state in the working * tree. */ wt_strategy = use_strategies[i]->name; ret = try_merge_strategy(use_strategies[i]->name, common, head_arg); if (!option_commit && !ret) { merge_was_ok = 1; /* * This is necessary here just to avoid writing * the tree, but later we will *not* exit with * status code 1 because merge_was_ok is set. */ ret = 1; } if (ret) { /* * The backend exits with 1 when conflicts are * left to be resolved, with 2 when it does not * handle the given merge at all. */ if (ret == 1) { int cnt = evaluate_result(); if (best_cnt <= 0 || cnt <= best_cnt) { best_strategy = use_strategies[i]->name; best_cnt = cnt; } } if (merge_was_ok) break; else continue; } /* Automerge succeeded. */ write_tree_trivial(result_tree); automerge_was_ok = 1; break; } /* * If we have a resulting tree, that means the strategy module * auto resolved the merge cleanly. */ if (automerge_was_ok) return finish_automerge(common, result_tree, wt_strategy); /* * Pick the result from the best strategy and have the user fix * it up. */ if (!best_strategy) { restore_state(); if (use_strategies_nr > 1) fprintf(stderr, "No merge strategy handled the merge.\n"); else fprintf(stderr, "Merge with strategy %s failed.\n", use_strategies[0]->name); return 2; } else if (best_strategy == wt_strategy) ; /* We already have its result in the working tree. */ else { printf("Rewinding the tree to pristine...\n"); restore_state(); printf("Using the %s to prepare resolving by hand.\n", best_strategy); try_merge_strategy(best_strategy, common, head_arg); } if (squash) finish(NULL, NULL); else { int fd; struct commit_list *j; for (j = remoteheads; j; j = j->next) strbuf_addf(&buf, "%s\n", sha1_to_hex(j->item->object.sha1)); fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666); if (fd < 0) die_errno("Could not open '%s' for writing", git_path("MERGE_HEAD")); if (write_in_full(fd, buf.buf, buf.len) != buf.len) die_errno("Could not write to '%s'", git_path("MERGE_HEAD")); close(fd); strbuf_addch(&merge_msg, '\n'); fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666); if (fd < 0) die_errno("Could not open '%s' for writing", git_path("MERGE_MSG")); if (write_in_full(fd, merge_msg.buf, merge_msg.len) != merge_msg.len) die_errno("Could not write to '%s'", git_path("MERGE_MSG")); close(fd); fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd < 0) die_errno("Could not open '%s' for writing", git_path("MERGE_MODE")); strbuf_reset(&buf); if (!allow_fast_forward) strbuf_addf(&buf, "no-ff"); if (write_in_full(fd, buf.buf, buf.len) != buf.len) die_errno("Could not write to '%s'", git_path("MERGE_MODE")); close(fd); } if (merge_was_ok) { fprintf(stderr, "Automatic merge went well; " "stopped before committing as requested\n"); return 0; } else return suggest_conflicts(); }
void gen_interrupt(void) { if (stop == 1) { g_gs_vi_counter = 0; /* debug */ dyna_stop(); } if (!interrupt_unsafe_state) { if (reset_hard_job) { reset_hard(); reset_hard_job = 0; return; } } if (skip_jump) { uint32_t dest = skip_jump; uint32_t count = g_cp0_regs[CP0_COUNT_REG]; skip_jump = 0; next_interrupt = (q.first->data.count > count || (count - q.first->data.count) < UINT32_C(0x80000000)) ? q.first->data.count : 0; last_addr = dest; generic_jump_to(dest); return; } switch(q.first->data.type) { case SPECIAL_INT: special_int_handler(); break; case VI_INT: remove_interrupt_event(); vi_vertical_interrupt_event(&g_dev.vi); retro_return(false); break; case COMPARE_INT: compare_int_handler(); break; case CHECK_INT: remove_interrupt_event(); wrapped_exception_general(); break; case SI_INT: remove_interrupt_event(); si_end_of_dma_event(&g_dev.si); break; case PI_INT: remove_interrupt_event(); pi_end_of_dma_event(&g_dev.pi); break; case AI_INT: remove_interrupt_event(); ai_end_of_dma_event(&g_dev.ai); break; case SP_INT: remove_interrupt_event(); rsp_interrupt_event(&g_dev.sp); break; case DP_INT: remove_interrupt_event(); rdp_interrupt_event(&g_dev.dp); break; case HW2_INT: hw2_int_handler(); break; case NMI_INT: nmi_int_handler(); break; case CART_INT: g_cp0_regs[CP0_CAUSE_REG] |= 0x00000800; /* set IP3 */ g_cp0_regs[CP0_CAUSE_REG] &= 0xFFFFFF83; /* mask out old exception code */ remove_interrupt_event(); #if 0 if (dd_end_of_dma_event(&g_dd) == 1) { remove_interrupt_event(); g_cp0_regs[CP0_CAUSE_REG] &= ~0x00000800; } #endif break; default: DebugMessage(M64MSG_ERROR, "Unknown interrupt queue event type %.8X.", q.first->data.type); remove_interrupt_event(); wrapped_exception_general(); break; } }
int main (int argc, char **argv) { git_index *index = NULL; pthread_t updateThread, hashThread; int rc, difficulty; void *status; hash_args args; timing_info timing; git_oid curr_commit; reset_timing(&timing); pthread_mutex_init(&commit_mutex, NULL); pthread_mutex_init(&update_mutex, NULL); push_commit = NULL; difficulty = init_args(&args); init_git(&index); init_hasher(difficulty); check_updates(); reset_hard(); puts("Starting update thread"); rc = pthread_create(&updateThread, NULL, check_updates_worker, NULL); if (rc){ printf("ERROR creating update thread %d\n", rc); exit(-1); } signal (SIGINT, int_handler); while(!stop){ start_timing(&timing); args.found = 0; time_point(&timing); pthread_mutex_lock(&commit_mutex); pthread_mutex_lock(&update_mutex); if(updated){ reset_hard(); updated = 0; push_commit = NULL; } pthread_mutex_unlock(&update_mutex); pthread_mutex_unlock(&commit_mutex); time_point(&timing); puts("Preparing index"); prepare_index(index, args.msg); time_point(&timing); puts("Starting brute force thread"); rc = pthread_create(&hashThread, NULL, force_hash, &args); time_point(&timing); if (rc){ printf("ERROR creating hash thread %d\n", rc); stop = 1; } else { pthread_join(hashThread, &status); } time_point(&timing); if(!stop && !updated && args.found){ puts("Found one!"); while(push_commit){ usleep(10); } time_point(&timing); if(!stop && !updated){ pthread_mutex_lock(&commit_mutex); commit_result(args.msg, &curr_commit); push_commit = &curr_commit; pthread_mutex_unlock(&commit_mutex); } } else { puts("Reset while looking for a hash"); time_point(&timing); } time_point(&timing); print_timing(&timing); } pthread_join(updateThread, &status); free_hasher(); free(args.msg); git_index_free(index); git_repository_free(repo); git_threads_shutdown(); return 0; }
void gen_interupt(void) { if (stop == 1) { g_gs_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) { uint32_t dest = skip_jump; skip_jump = 0; next_interupt = (q.first->data.count > g_cp0_regs[CP0_COUNT_REG] || (g_cp0_regs[CP0_COUNT_REG] - q.first->data.count) < UINT32_C(0x80000000)) ? q.first->data.count : 0; last_addr = dest; generic_jump_to(dest); return; } switch(q.first->data.type) { case SPECIAL_INT: special_int_handler(); break; case VI_INT: remove_interupt_event(); vi_vertical_interrupt_event(&g_vi); break; case COMPARE_INT: compare_int_handler(); break; case CHECK_INT: remove_interupt_event(); wrapped_exception_general(); break; case SI_INT: remove_interupt_event(); si_end_of_dma_event(&g_si); break; case PI_INT: remove_interupt_event(); pi_end_of_dma_event(&g_pi); break; case AI_INT: remove_interupt_event(); ai_end_of_dma_event(&g_ai); break; case SP_INT: remove_interupt_event(); rsp_interrupt_event(&g_sp); break; case DP_INT: remove_interupt_event(); rdp_interrupt_event(&g_dp); break; case HW2_INT: hw2_int_handler(); break; case NMI_INT: nmi_int_handler(); break; default: DebugMessage(M64MSG_ERROR, "Unknown interrupt queue event type %.8X.", q.first->data.type); remove_interupt_event(); wrapped_exception_general(); break; } if (!interupt_unsafe_state) { if (savestates_get_job() == savestates_job_save) { savestates_save(); return; } } }
void osal_fastcall gen_interupt(usf_state_t * state) { if (state->stop == 1) { state->g_gs_vi_counter = 0; // debug dyna_stop(state); } if (!state->interupt_unsafe_state) { if (state->reset_hard_job) { reset_hard(state); state->reset_hard_job = 0; return; } } if (state->skip_jump) { unsigned int dest = state->skip_jump; state->skip_jump = 0; state->next_interupt = (state->q.first->data.count > state->g_cp0_regs[CP0_COUNT_REG] || (state->g_cp0_regs[CP0_COUNT_REG] - state->q.first->data.count) < 0x80000000) ? state->q.first->data.count : 0; state->last_addr = dest; generic_jump_to(state, dest); return; } switch(state->q.first->data.type) { case SPECIAL_INT: special_int_handler(state); break; case VI_INT: remove_interupt_event(state); vi_vertical_interrupt_event(&state->g_vi); break; case COMPARE_INT: compare_int_handler(state); break; case CHECK_INT: remove_interupt_event(state); wrapped_exception_general(state); break; case SI_INT: remove_interupt_event(state); si_end_of_dma_event(&state->g_si); break; case PI_INT: remove_interupt_event(state); pi_end_of_dma_event(&state->g_pi); break; case AI_INT: remove_interupt_event(state); ai_end_of_dma_event(&state->g_ai); break; case SP_INT: remove_interupt_event(state); rsp_interrupt_event(&state->g_sp); break; case DP_INT: remove_interupt_event(state); rdp_interrupt_event(&state->g_dp); break; case HW2_INT: hw2_int_handler(state); break; case NMI_INT: nmi_int_handler(state); break; default: DebugMessage(state, M64MSG_ERROR, "Unknown interrupt queue event type %.8X.", state->q.first->data.type); remove_interupt_event(state); wrapped_exception_general(state); break; } }