mupen64plus-oldsvn/r4300/bc.c
Jesse Dean 895a9d3d48 Rewrite of debugger memory breakpoint trap. Memory breakpoints are now
trapped by functions injected into the memory function tables.  
New setup should be MUCH faster, and more flexible
2008-12-22 04:54:03 +00:00

239 lines
5.7 KiB
C

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - bc.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2002 Hacktarux *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "r4300.h"
#include "ops.h"
#include "macros.h"
#include "interupt.h"
#include "../debugger/debugger.h"
void BC1F(void)
{
if (check_cop1_unusable()) return;
PC++;
delay_slot=1;
#ifdef DBG
if (debugger_mode) update_debugger(PC->addr);
#endif
PC->ops();
update_count();
delay_slot=0;
if ((FCR31 & 0x800000)==0 && !skip_jump)
PC += (PC-2)->f.i.immediate-1;
last_addr = PC->addr;
if (next_interupt <= Count) gen_interupt();
}
void BC1F_OUT(void)
{
if (check_cop1_unusable()) return;
jump_target = (int)PC->f.i.immediate;
PC++;
delay_slot=1;
#ifdef DBG
if (debugger_mode) update_debugger(PC->addr);
#endif
PC->ops();
update_count();
delay_slot=0;
if (!skip_jump && (FCR31 & 0x800000)==0)
jump_to(PC->addr + ((jump_target-1)<<2));
last_addr = PC->addr;
if (next_interupt <= Count) gen_interupt();
}
void BC1F_IDLE(void)
{
int skip;
if ((FCR31 & 0x800000)==0)
{
update_count();
skip = next_interupt - Count;
if (skip > 3) Count += (skip & 0xFFFFFFFC);
else BC1F();
}
else BC1F();
}
void BC1T(void)
{
if (check_cop1_unusable()) return;
PC++;
delay_slot=1;
#ifdef DBG
if (debugger_mode) update_debugger(PC->addr);
#endif
PC->ops();
update_count();
delay_slot=0;
if ((FCR31 & 0x800000)!=0 && !skip_jump)
PC += (PC-2)->f.i.immediate-1;
last_addr = PC->addr;
if (next_interupt <= Count) gen_interupt();
}
void BC1T_OUT(void)
{
if (check_cop1_unusable()) return;
jump_target = (int)PC->f.i.immediate;
PC++;
delay_slot=1;
#ifdef DBG
if (debugger_mode) update_debugger(PC->addr);
#endif
PC->ops();
update_count();
delay_slot=0;
if (!skip_jump && (FCR31 & 0x800000)!=0)
jump_to(PC->addr + ((jump_target-1)<<2));
last_addr = PC->addr;
if (next_interupt <= Count) gen_interupt();
}
void BC1T_IDLE(void)
{
int skip;
if ((FCR31 & 0x800000)!=0)
{
update_count();
skip = next_interupt - Count;
if (skip > 3) Count += (skip & 0xFFFFFFFC);
else BC1T();
}
else BC1T();
}
void BC1FL(void)
{
if (check_cop1_unusable()) return;
if ((FCR31 & 0x800000)==0)
{
PC++;
delay_slot=1;
#ifdef DBG
if (debugger_mode) update_debugger(PC->addr);
#endif
PC->ops();
update_count();
delay_slot=0;
if(!skip_jump)
PC += (PC-2)->f.i.immediate-1;
}
else
PC+=2;
last_addr = PC->addr;
if (next_interupt <= Count) gen_interupt();
}
void BC1FL_OUT(void)
{
if (check_cop1_unusable()) return;
if ((FCR31 & 0x800000)==0)
{
jump_target = (int)PC->f.i.immediate;
PC++;
delay_slot=1;
#ifdef DBG
if (debugger_mode) update_debugger(PC->addr);
#endif
PC->ops();
update_count();
delay_slot=0;
if (!skip_jump)
jump_to(PC->addr + ((jump_target-1)<<2));
}
else
PC+=2;
last_addr = PC->addr;
if (next_interupt <= Count) gen_interupt();
}
void BC1FL_IDLE(void)
{
int skip;
if ((FCR31 & 0x800000)==0)
{
update_count();
skip = next_interupt - Count;
if (skip > 3) Count += (skip & 0xFFFFFFFC);
else BC1FL();
}
else BC1FL();
}
void BC1TL(void)
{
if (check_cop1_unusable()) return;
if ((FCR31 & 0x800000)!=0)
{
PC++;
delay_slot=1;
#ifdef DBG
if (debugger_mode) update_debugger(PC->addr);
#endif
PC->ops();
update_count();
delay_slot=0;
if(!skip_jump)
PC += (PC-2)->f.i.immediate-1;
}
else
PC+=2;
last_addr = PC->addr;
if (next_interupt <= Count) gen_interupt();
}
void BC1TL_OUT(void)
{
if (check_cop1_unusable()) return;
if ((FCR31 & 0x800000)!=0)
{
jump_target = (int)PC->f.i.immediate;
PC++;
delay_slot=1;
#ifdef DBG
if (debugger_mode) update_debugger(PC->addr);
#endif
PC->ops();
update_count();
delay_slot=0;
if (!skip_jump)
jump_to(PC->addr + ((jump_target-1)<<2));
}
else
PC+=2;
last_addr = PC->addr;
if (next_interupt <= Count) gen_interupt();
}
void BC1TL_IDLE(void)
{
int skip;
if ((FCR31 & 0x800000)!=0)
{
update_count();
skip = next_interupt - Count;
if (skip > 3) Count += (skip & 0xFFFFFFFC);
else BC1TL();
}
else BC1TL();
}