Path: blob/master/libmupen64plus/mupen64plus-core/src/r4300/exception.c
2 views
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1* Mupen64plus - exception.c *2* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *3* Copyright (C) 2002 Hacktarux *4* *5* This program is free software; you can redistribute it and/or modify *6* it under the terms of the GNU General Public License as published by *7* the Free Software Foundation; either version 2 of the License, or *8* (at your option) any later version. *9* *10* This program is distributed in the hope that it will be useful, *11* but WITHOUT ANY WARRANTY; without even the implied warranty of *12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *13* GNU General Public License for more details. *14* *15* You should have received a copy of the GNU General Public License *16* along with this program; if not, write to the *17* Free Software Foundation, Inc., *18* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *19* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2021#include "api/m64p_types.h"22#include "api/callbacks.h"23#include "memory/memory.h"2425#include "exception.h"26#include "r4300.h"27#include "macros.h"28#include "recomph.h"2930void TLB_refill_exception(unsigned int address, int w)31{32int usual_handler = 0, i;3334if (r4300emu != CORE_DYNAREC && w != 2) update_count();35if (w == 1) Cause = (3 << 2);36else Cause = (2 << 2);37BadVAddr = address;38Context = (Context & 0xFF80000F) | ((address >> 9) & 0x007FFFF0);39EntryHi = address & 0xFFFFE000;40if (Status & 0x2) // Test de EXL41{42generic_jump_to(0x80000180);43if(delay_slot==1 || delay_slot==3) Cause |= 0x80000000;44else Cause &= 0x7FFFFFFF;45}46else47{48if (r4300emu != CORE_PURE_INTERPRETER)49{50if (w!=2)51EPC = PC->addr;52else53EPC = address;54}55else EPC = PC->addr;5657Cause &= ~0x80000000;58Status |= 0x2; //EXL=15960if (address >= 0x80000000 && address < 0xc0000000)61usual_handler = 1;62for (i=0; i<32; i++)63{64if (/*tlb_e[i].v_even &&*/ address >= tlb_e[i].start_even &&65address <= tlb_e[i].end_even)66usual_handler = 1;67if (/*tlb_e[i].v_odd &&*/ address >= tlb_e[i].start_odd &&68address <= tlb_e[i].end_odd)69usual_handler = 1;70}71if (usual_handler)72{73generic_jump_to(0x80000180);74}75else76{77generic_jump_to(0x80000000);78}79}80if(delay_slot==1 || delay_slot==3)81{82Cause |= 0x80000000;83EPC-=4;84}85else86{87Cause &= 0x7FFFFFFF;88}89if(w != 2) EPC-=4;9091last_addr = PC->addr;9293if (r4300emu == CORE_DYNAREC)94{95dyna_jump();96if (!dyna_interp) delay_slot = 0;97}9899if (r4300emu != CORE_DYNAREC || dyna_interp)100{101dyna_interp = 0;102if (delay_slot)103{104skip_jump = PC->addr;105next_interupt = 0;106}107}108}109110void exception_general(void)111{112update_count();113Status |= 2;114115EPC = PC->addr;116117if(delay_slot==1 || delay_slot==3)118{119Cause |= 0x80000000;120EPC-=4;121}122else123{124Cause &= 0x7FFFFFFF;125}126generic_jump_to(0x80000180);127last_addr = PC->addr;128if (r4300emu == CORE_DYNAREC)129{130dyna_jump();131if (!dyna_interp) delay_slot = 0;132}133if (r4300emu != CORE_DYNAREC || dyna_interp)134{135dyna_interp = 0;136if (delay_slot)137{138skip_jump = PC->addr;139next_interupt = 0;140}141}142}143144145146