mirror of
https://github.com/mupen64plus/mupen64plus-core.git
synced 2024-06-02 19:27:51 -04:00
efdeaf32c7
s/interupt/interrupt/
144 lines
5.1 KiB
Modula-2
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);
|
|
}
|