mupen64plus-core/src/device/r4300/interpreter_cop0.def
Bobby Smiles efdeaf32c7 Fix interrupt spelling.
s/interupt/interrupt/
2017-03-07 06:17:04 +01:00

144 lines
5.1 KiB
Modula-2

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - interpreter_cop0.def *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
DECLARE_INSTRUCTION(MFC0)
{
uint32_t* cp0_regs = r4300_cp0_regs();
switch(rfs)
{
case CP0_RANDOM_REG:
DebugMessage(M64MSG_ERROR, "MFC0 instruction reading un-implemented Random register");
*r4300_stop()=1;
break;
case CP0_COUNT_REG:
cp0_update_count();
/* fall through */
default:
rrt = SE32(cp0_regs[rfs]);
}
ADD_TO_PC(1);
}
DECLARE_INSTRUCTION(MTC0)
{
uint32_t* cp0_regs = r4300_cp0_regs();
unsigned int* cp0_next_interrupt = r4300_cp0_next_interrupt();
switch(rfs)
{
case CP0_INDEX_REG:
cp0_regs[CP0_INDEX_REG] = rrt32 & UINT32_C(0x8000003F);
if ((cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F)) > UINT32_C(31))
{
DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31");
*r4300_stop()=1;
}
break;
case CP0_RANDOM_REG:
break;
case CP0_ENTRYLO0_REG:
cp0_regs[CP0_ENTRYLO0_REG] = rrt32 & UINT32_C(0x3FFFFFFF);
break;
case CP0_ENTRYLO1_REG:
cp0_regs[CP0_ENTRYLO1_REG] = rrt32 & UINT32_C(0x3FFFFFFF);
break;
case CP0_CONTEXT_REG:
cp0_regs[CP0_CONTEXT_REG] = (rrt32 & UINT32_C(0xFF800000))
| (cp0_regs[CP0_CONTEXT_REG] & UINT32_C(0x007FFFF0));
break;
case CP0_PAGEMASK_REG:
cp0_regs[CP0_PAGEMASK_REG] = rrt32 & UINT32_C(0x01FFE000);
break;
case CP0_WIRED_REG:
cp0_regs[CP0_WIRED_REG] = rrt32;
cp0_regs[CP0_RANDOM_REG] = UINT32_C(31);
break;
case CP0_BADVADDR_REG:
break;
case CP0_COUNT_REG:
cp0_update_count();
g_dev.r4300.cp0.interrupt_unsafe_state = 1;
if (*cp0_next_interrupt <= cp0_regs[CP0_COUNT_REG]) gen_interrupt();
g_dev.r4300.cp0.interrupt_unsafe_state = 0;
translate_event_queue(rrt32);
cp0_regs[CP0_COUNT_REG] = rrt32;
break;
case CP0_ENTRYHI_REG:
cp0_regs[CP0_ENTRYHI_REG] = rrt32 & UINT32_C(0xFFFFE0FF);
break;
case CP0_COMPARE_REG:
cp0_update_count();
remove_event(COMPARE_INT);
add_interrupt_event_count(COMPARE_INT, rrt32);
cp0_regs[CP0_COMPARE_REG] = rrt32;
cp0_regs[CP0_CAUSE_REG] &= ~CP0_CAUSE_IP7;
break;
case CP0_STATUS_REG:
if((rrt32 & CP0_STATUS_FR) != (cp0_regs[CP0_STATUS_REG] & CP0_STATUS_FR))
{
shuffle_fpr_data(cp0_regs[CP0_STATUS_REG], rrt32);
set_fpr_pointers(rrt32);
}
cp0_regs[CP0_STATUS_REG] = rrt32;
cp0_update_count();
ADD_TO_PC(1);
check_interrupt();
g_dev.r4300.cp0.interrupt_unsafe_state = 1;
if (*cp0_next_interrupt <= cp0_regs[CP0_COUNT_REG]) gen_interrupt();
g_dev.r4300.cp0.interrupt_unsafe_state = 0;
ADD_TO_PC(-1);
break;
case CP0_CAUSE_REG:
if (rrt32!=0)
{
DebugMessage(M64MSG_ERROR, "MTC0 instruction trying to write Cause register with non-0 value");
*r4300_stop() = 1;
}
else cp0_regs[CP0_CAUSE_REG] = rrt32;
break;
case CP0_EPC_REG:
cp0_regs[CP0_EPC_REG] = rrt32;
break;
case CP0_PREVID_REG:
break;
case CP0_CONFIG_REG:
cp0_regs[CP0_CONFIG_REG] = rrt32;
break;
case CP0_WATCHLO_REG:
cp0_regs[CP0_WATCHLO_REG] = rrt32;
break;
case CP0_WATCHHI_REG:
cp0_regs[CP0_WATCHHI_REG] = rrt32;
break;
case CP0_TAGLO_REG:
cp0_regs[CP0_TAGLO_REG] = rrt32 & UINT32_C(0x0FFFFFC0);
break;
case CP0_TAGHI_REG:
cp0_regs[CP0_TAGHI_REG] = 0;
break;
default:
DebugMessage(M64MSG_ERROR, "Unknown MTC0 write: %d", rfs);
*r4300_stop()=1;
}
ADD_TO_PC(1);
}