summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Phil Bennett <philipjbennett@users.noreply.github.com>2013-01-19 12:25:09 +0000
committer Phil Bennett <philipjbennett@users.noreply.github.com>2013-01-19 12:25:09 +0000
commit444777967b206fc3ca9badec3028198394d30da2 (patch)
tree341ea7de1b13e015ea763fbcd7d5542412e54451 /src
parent7a2733507797e1a2e8a71449722192cce2bfd77c (diff)
Modernised the R3000 core: [Phil Bennett]
* The following variants are supported: R3041, R3051, R3052, R3071 and R3081 * Endianness is now specified by MCFG_R3000_ENDIANNESS() (default is big-endian) * Removed configuration struct. Cache sizes and FPU availability are now determined from the CPU type * Added state saving * Added BrCond input callbacks
Diffstat (limited to 'src')
-rw-r--r--src/emu/cpu/mips/r3000.c1723
-rw-r--r--src/emu/cpu/mips/r3000.h282
-rw-r--r--src/mame/drivers/jaguar.c16
-rw-r--r--src/mame/drivers/policetr.c12
-rw-r--r--src/mame/drivers/speglsht.c11
-rw-r--r--src/mame/drivers/srmp5.c11
-rw-r--r--src/mame/drivers/turrett.c11
7 files changed, 1125 insertions, 941 deletions
diff --git a/src/emu/cpu/mips/r3000.c b/src/emu/cpu/mips/r3000.c
index c0f8caf8cf8..47fe080445d 100644
--- a/src/emu/cpu/mips/r3000.c
+++ b/src/emu/cpu/mips/r3000.c
@@ -1,6 +1,6 @@
/***************************************************************************
- r3000->c
+ r3000.c
Core implementation for the portable MIPS R3000 emulator.
Written by Aaron Giles
@@ -10,8 +10,6 @@
#include "debugger.h"
#include "r3000.h"
-CPU_DISASSEMBLE( r3000be );
-CPU_DISASSEMBLE( r3000le );
#define ENABLE_OVERFLOWS 0
@@ -73,378 +71,689 @@ CPU_DISASSEMBLE( r3000le );
#define EXCEPTION_TRAP 13
-
/***************************************************************************
HELPER MACROS
***************************************************************************/
-#define RSREG ((op >> 21) & 31)
-#define RTREG ((op >> 16) & 31)
-#define RDREG ((op >> 11) & 31)
-#define SHIFT ((op >> 6) & 31)
+#define RSREG ((m_op >> 21) & 31)
+#define RTREG ((m_op >> 16) & 31)
+#define RDREG ((m_op >> 11) & 31)
+#define SHIFT ((m_op >> 6) & 31)
+
+#define RSVAL m_r[RSREG]
+#define RTVAL m_r[RTREG]
+#define RDVAL m_r[RDREG]
+
+#define SIMMVAL ((INT16)m_op)
+#define UIMMVAL ((UINT16)m_op)
+#define LIMMVAL (m_op & 0x03ffffff)
+
+#define ADDPC(x) do { m_nextpc = m_pc + ((x) << 2); } while (0)
+#define ADDPCL(x,l) do { m_nextpc = m_pc + ((x) << 2); m_r[l] = m_pc + 4; } while (0)
+#define ABSPC(x) do { m_nextpc = (m_pc & 0xf0000000) | ((x) << 2); } while (0)
+#define ABSPCL(x,l) do { m_nextpc = (m_pc & 0xf0000000) | ((x) << 2); m_r[l] = m_pc + 4; } while (0)
+#define SETPC(x) do { m_nextpc = (x); } while (0)
+#define SETPCL(x,l) do { m_nextpc = (x); m_r[l] = m_pc + 4; } while (0)
+
+#define RBYTE(x) (this->*m_cur->m_read_byte)(x)
+#define RWORD(x) (this->*m_cur->m_read_word)(x)
+#define RLONG(x) (this->*m_cur->m_read_dword)(x)
+
+#define WBYTE(x,v) (this->*m_cur->m_write_byte)(x, v)
+#define WWORD(x,v) (this->*m_cur->m_write_word)(x, v)
+#define WLONG(x,v) (this->*m_cur->m_write_dword)(x, v)
+
+#define SR m_cpr[0][COP0_Status]
+#define CAUSE m_cpr[0][COP0_Cause]
+
+
+//**************************************************************************
+// DEVICE INTERFACE
+//**************************************************************************
+
+const device_type R3041 = &device_creator<r3041_device>;
+const device_type R3051 = &device_creator<r3051_device>;
+const device_type R3052 = &device_creator<r3052_device>;
+const device_type R3071 = &device_creator<r3071_device>;
+const device_type R3081 = &device_creator<r3081_device>;
+
+
+//-------------------------------------------------
+// r3000_device - constructor
+//-------------------------------------------------
+
+r3000_device::r3000_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, chip_type chiptype)
+ : cpu_device(mconfig, type, name, tag, owner, clock),
+ m_program_config_be("program", ENDIANNESS_BIG, 32, 29),
+ m_program_config_le("program", ENDIANNESS_LITTLE, 32, 29),
+ m_program(NULL),
+ m_direct(NULL),
+ m_chip_type(chiptype),
+ m_hasfpu(false),
+ m_endianness(ENDIANNESS_BIG),
+ m_pc(0),
+ m_nextpc(0),
+ m_hi(0),
+ m_lo(0),
+ m_ppc(0),
+ m_op(0),
+ m_icount(0),
+ m_interrupt_cycles(0),
+ m_in_brcond0(*this),
+ m_in_brcond1(*this),
+ m_in_brcond2(*this),
+ m_in_brcond3(*this)
+{
+ // set our instruction counter
+ m_icountptr = &m_icount;
-#define RSVAL r[RSREG]
-#define RTVAL r[RTREG]
-#define RDVAL r[RDREG]
+ // clear some additional state
+ memset(m_r, 0, sizeof(m_r));
+ memset(m_cpr, 0, sizeof(m_cpr));
+ memset(m_ccr, 0, sizeof(m_ccr));
+}
-#define SIMMVAL ((INT16)op)
-#define UIMMVAL ((UINT16)op)
-#define LIMMVAL (op & 0x03ffffff)
-#define ADDPC(R,x) do { (R)->nextpc = (R)->pc + ((x) << 2); } while (0)
-#define ADDPCL(R,x,l) do { (R)->nextpc = (R)->pc + ((x) << 2); (R)->r[l] = (R)->pc + 4; } while (0)
-#define ABSPC(R,x) do { (R)->nextpc = ((R)->pc & 0xf0000000) | ((x) << 2); } while (0)
-#define ABSPCL(R,x,l) do { (R)->nextpc = ((R)->pc & 0xf0000000) | ((x) << 2); (R)->r[l] = (R)->pc + 4; } while (0)
-#define SETPC(R,x) do { (R)->nextpc = (x); } while (0)
-#define SETPCL(R,x,l) do { (R)->nextpc = (x); (R)->r[l] = (R)->pc + 4; } while (0)
+//-------------------------------------------------
+// ~r3000_device - destructor
+//-------------------------------------------------
-#define RBYTE(R,x) (*(R)->cur.read_byte)(*(R)->program, x)
-#define RWORD(R,x) (*(R)->cur.read_word)(*(R)->program, x)
-#define RLONG(R,x) (*(R)->cur.read_dword)(*(R)->program, x)
+r3000_device::~r3000_device()
+{
+}
-#define WBYTE(R,x,v) (*(R)->cur.write_byte)(*(R)->program, x, v)
-#define WWORD(R,x,v) (*(R)->cur.write_word)(*(R)->program, x, v)
-#define WLONG(R,x,v) (*(R)->cur.write_dword)(*(R)->program, x, v)
-#define SR cpr[0][COP0_Status]
-#define CAUSE cpr[0][COP0_Cause]
+//-------------------------------------------------
+// r3041_device - constructor
+//-------------------------------------------------
+r3041_device::r3041_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : r3000_device(mconfig, R3041, "R3041", tag, owner, clock, CHIP_TYPE_R3041) { }
-/***************************************************************************
- STRUCTURES & TYPEDEFS
-***************************************************************************/
+//-------------------------------------------------
+// r3051_device - constructor
+//-------------------------------------------------
-/* R3000 Registers */
-struct r3000_state
-{
- /* core registers */
- UINT32 pc;
- UINT32 hi;
- UINT32 lo;
- UINT32 r[32];
-
- /* COP registers */
- UINT32 cpr[4][32];
- UINT32 ccr[4][32];
- UINT8 cf[4];
-
- /* internal stuff */
- UINT32 ppc;
- UINT32 nextpc;
- int op;
- int icount;
- int interrupt_cycles;
- int hasfpu;
- device_irq_acknowledge_callback irq_callback;
- legacy_cpu_device *device;
- address_space *program;
- direct_read_data *direct;
-
- /* endian-dependent load/store */
- void (*lwl)(r3000_state *r3000, UINT32 op);
- void (*lwr)(r3000_state *r3000, UINT32 op);
- void (*swl)(r3000_state *r3000, UINT32 op);
- void (*swr)(r3000_state *r3000, UINT32 op);
-
- /* memory accesses */
- UINT8 bigendian;
- data_accessors cur;
- data_accessors memory_hand;
- const data_accessors *cache_hand;
-
- /* cache memory */
- UINT32 * cache;
- UINT32 * icache;
- UINT32 * dcache;
- size_t cache_size;
- size_t icache_size;
- size_t dcache_size;
-};
-
-INLINE r3000_state *get_safe_token(device_t *device)
-{
- assert(device != NULL);
- assert(device->type() == R3000BE ||
- device->type() == R3000LE ||
- device->type() == R3041BE ||
- device->type() == R3041LE);
- return (r3000_state *)downcast<legacy_cpu_device *>(device)->token();
-}
+r3051_device::r3051_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : r3000_device(mconfig, R3051, "R3051", tag, owner, clock, CHIP_TYPE_R3051) { }
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
+//-------------------------------------------------
+// r3052_device - constructor
+//-------------------------------------------------
-static void lwl_be(r3000_state *r3000, UINT32 op);
-static void lwr_be(r3000_state *r3000, UINT32 op);
-static void swl_be(r3000_state *r3000, UINT32 op);
-static void swr_be(r3000_state *r3000, UINT32 op);
+r3052_device::r3052_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : r3000_device(mconfig, R3052, "R3052", tag, owner, clock, CHIP_TYPE_R3052) { }
-static void lwl_le(r3000_state *r3000, UINT32 op);
-static void lwr_le(r3000_state *r3000, UINT32 op);
-static void swl_le(r3000_state *r3000, UINT32 op);
-static void swr_le(r3000_state *r3000, UINT32 op);
-static UINT8 readcache_be(address_space &space, offs_t offset);
-static UINT16 readcache_be_word(address_space &space, offs_t offset);
-static UINT32 readcache_be_dword(address_space &space, offs_t offset);
-static void writecache_be(address_space &space, offs_t offset, UINT8 data);
-static void writecache_be_word(address_space &space, offs_t offset, UINT16 data);
-static void writecache_be_dword(address_space &space, offs_t offset, UINT32 data);
+//-------------------------------------------------
+// r3071_device - constructor
+//-------------------------------------------------
-static UINT8 readcache_le(address_space &space, offs_t offset);
-static UINT16 readcache_le_word(address_space &space, offs_t offset);
-static UINT32 readcache_le_dword(address_space &space, offs_t offset);
-static void writecache_le(address_space &space, offs_t offset, UINT8 data);
-static void writecache_le_word(address_space &space, offs_t offset, UINT16 data);
-static void writecache_le_dword(address_space &space, offs_t offset, UINT32 data);
+r3071_device::r3071_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : r3000_device(mconfig, R3071, "R3071", tag, owner, clock, CHIP_TYPE_R3071) { }
+//-------------------------------------------------
+// r3081_device - constructor
+//-------------------------------------------------
+
+r3081_device::r3081_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : r3000_device(mconfig, R3081, "R3081", tag, owner, clock, CHIP_TYPE_R3081) { }
-/***************************************************************************
- PRIVATE GLOBAL VARIABLES
-***************************************************************************/
-static const data_accessors be_cache =
+//-------------------------------------------------
+// device_start - start up the device
+//-------------------------------------------------
+
+void r3000_device::device_start()
{
- readcache_be, readcache_be_word, NULL, readcache_be_dword, NULL, NULL, NULL,
- writecache_be, writecache_be_word, NULL, writecache_be_dword, NULL, NULL, NULL
-};
+ // get our address spaces
+ m_program = &space(AS_PROGRAM);
+ m_direct = &m_program->direct();
-static const data_accessors le_cache =
+ // determine the cache sizes
+ switch (m_chip_type)
+ {
+ case CHIP_TYPE_R3041:
+ {
+ m_icache_size = 2048;
+ m_dcache_size = 512;
+ break;
+ }
+ case CHIP_TYPE_R3051:
+ {
+ m_icache_size = 4096;
+ m_dcache_size = 2048;
+ break;
+ }
+ case CHIP_TYPE_R3052:
+ {
+ m_icache_size = 8192;
+ m_dcache_size = 2048;
+ break;
+ }
+
+ // TODO: R3071 and R3081 have configurable cache sizes
+ case CHIP_TYPE_R3071:
+ {
+ m_icache_size = 16384; // or 8kB
+ m_dcache_size = 4096; // or 8kB
+ break;
+ }
+ case CHIP_TYPE_R3081:
+ {
+ m_icache_size = 16384; // or 8kB
+ m_dcache_size = 4096; // or 8kB
+ m_hasfpu = true;
+ break;
+ }
+ }
+
+ // allocate cache memory
+ m_icache = auto_alloc_array(machine(), UINT32, m_icache_size/4);
+ m_dcache = auto_alloc_array(machine(), UINT32, m_dcache_size/4);
+
+ m_cache = m_dcache;
+ m_cache_size = m_dcache_size;
+
+ // set up memory handlers
+ m_memory_hand.m_read_byte = &r3000_device::readmem;
+ m_memory_hand.m_read_word = &r3000_device::readmem_word;
+ m_memory_hand.m_read_dword = &r3000_device::readmem_dword;
+ m_memory_hand.m_write_byte = &r3000_device::writemem;
+ m_memory_hand.m_write_word = &r3000_device::writemem_word;
+ m_memory_hand.m_write_dword = &r3000_device::writemem_dword;
+
+ if (m_endianness == ENDIANNESS_BIG)
+ {
+ m_lwl = &r3000_device::lwl_be;
+ m_lwr = &r3000_device::lwr_be;
+ m_swl = &r3000_device::swl_be;
+ m_swr = &r3000_device::swr_be;
+
+ m_cache_hand.m_read_byte = &r3000_device::readcache_be;
+ m_cache_hand.m_read_word = &r3000_device::readcache_be_word;
+ m_cache_hand.m_read_dword = &r3000_device::readcache_be_dword;
+ m_cache_hand.m_write_byte = &r3000_device::writecache_be;
+ m_cache_hand.m_write_word = &r3000_device::writecache_be_word;
+ m_cache_hand.m_write_dword = &r3000_device::writecache_be_dword;
+ }
+ else
+ {
+ m_lwl = &r3000_device::lwl_le;
+ m_lwr = &r3000_device::lwr_le;
+ m_swl = &r3000_device::swl_le;
+ m_swr = &r3000_device::swr_le;
+
+ m_cache_hand.m_read_byte = &r3000_device::readcache_le;
+ m_cache_hand.m_read_word = &r3000_device::readcache_le_word;
+ m_cache_hand.m_read_dword = &r3000_device::readcache_le_dword;
+ m_cache_hand.m_write_byte = &r3000_device::writecache_le;
+ m_cache_hand.m_write_word = &r3000_device::writecache_le_word;
+ m_cache_hand.m_write_dword = &r3000_device::writecache_le_dword;
+ }
+
+ // resolve conditional branch input handlers
+ m_in_brcond0.resolve_safe(0);
+ m_in_brcond1.resolve_safe(0);
+ m_in_brcond2.resolve_safe(0);
+ m_in_brcond3.resolve_safe(0);
+
+ // register our state for the debugger
+ state_add(STATE_GENPC, "GENPC", m_pc).noshow();
+ state_add(STATE_GENPCBASE, "GENPCBASE", m_ppc).noshow();
+ state_add(STATE_GENSP, "GENSP", m_r[31]).noshow();
+ state_add(STATE_GENFLAGS, "GENFLAGS", SR).callimport().callexport().formatstr("%6s").noshow();
+ state_add(R3000_PC, "PC", m_pc);
+ state_add(R3000_SR, "SR", SR);
+ state_add(R3000_R0, "R0", m_r[0]);
+ state_add(R3000_R1, "R1", m_r[1]);
+ state_add(R3000_R2, "R2", m_r[2]);
+ state_add(R3000_R3, "R3", m_r[3]);
+ state_add(R3000_R4, "R4", m_r[4]);
+ state_add(R3000_R5, "R5", m_r[5]);
+ state_add(R3000_R6, "R6", m_r[6]);
+ state_add(R3000_R7, "R7", m_r[7]);
+ state_add(R3000_R8, "R8", m_r[8]);
+ state_add(R3000_R9, "R9", m_r[9]);
+ state_add(R3000_R10, "R10", m_r[10]);
+ state_add(R3000_R11, "R11", m_r[11]);
+ state_add(R3000_R12, "R12", m_r[12]);
+ state_add(R3000_R13, "R13", m_r[13]);
+ state_add(R3000_R14, "R14", m_r[14]);
+ state_add(R3000_R15, "R15", m_r[15]);
+ state_add(R3000_R16, "R16", m_r[16]);
+ state_add(R3000_R17, "R17", m_r[17]);
+ state_add(R3000_R18, "R18", m_r[18]);
+ state_add(R3000_R19, "R19", m_r[19]);
+ state_add(R3000_R20, "R20", m_r[20]);
+ state_add(R3000_R21, "R21", m_r[21]);
+ state_add(R3000_R22, "R22", m_r[22]);
+ state_add(R3000_R23, "R23", m_r[23]);
+ state_add(R3000_R24, "R24", m_r[24]);
+ state_add(R3000_R25, "R25", m_r[25]);
+ state_add(R3000_R26, "R26", m_r[26]);
+ state_add(R3000_R27, "R27", m_r[27]);
+ state_add(R3000_R28, "R28", m_r[28]);
+ state_add(R3000_R29, "R29", m_r[29]);
+ state_add(R3000_R30, "R30", m_r[30]);
+ state_add(R3000_R31, "R31", m_r[31]);
+
+ // register our state for saving
+ save_item(NAME(m_pc));
+ save_item(NAME(m_nextpc));
+ save_item(NAME(m_hi));
+ save_item(NAME(m_lo));
+ save_item(NAME(m_r));
+ save_item(NAME(m_cpr));
+ save_item(NAME(m_ccr));
+ save_item(NAME(m_ppc));
+ save_item(NAME(m_op));
+ save_item(NAME(m_interrupt_cycles));
+ save_pointer(NAME(m_icache), m_icache_size/4);
+ save_pointer(NAME(m_dcache), m_dcache_size/4);
+}
+
+
+//-------------------------------------------------
+// device_post_load -
+//-------------------------------------------------
+void r3000_device::device_post_load()
{
- readcache_le, readcache_le_word, NULL, readcache_le_dword, NULL, NULL, NULL,
- writecache_le, writecache_le_word, NULL, writecache_le_dword, NULL, NULL, NULL
-};
+ if (m_cpr[0][COP0_Status] & SR_IsC)
+ m_cur = &m_cache_hand;
+ else
+ m_cur = &m_memory_hand;
+}
+//-------------------------------------------------
+// device_reset - reset the device
+//-------------------------------------------------
-/***************************************************************************
- MEMORY ACCESSORS
-***************************************************************************/
+void r3000_device::device_reset()
+{
+ // initialize the rest of the config
+ m_cur = &m_memory_hand;
+
+ // initialize the state
+ m_pc = 0xbfc00000;
+ m_nextpc = ~0;
+ m_cpr[0][COP0_PRId] = 0x0200;
+ m_cpr[0][COP0_Status] = 0x0000;
+}
-#define ROPCODE(R,pc) (R)->direct->read_decrypted_dword(pc)
+//-------------------------------------------------
+// memory_space_config - return the configuration
+// of the specified address space, or NULL if
+// the space doesn't exist
+//-------------------------------------------------
+const address_space_config *r3000_device::memory_space_config(address_spacenum spacenum) const
+{
+ if (spacenum == AS_PROGRAM)
+ return (m_endianness == ENDIANNESS_BIG) ? &m_program_config_be : &m_program_config_le;
+ else
+ return NULL;
+}
-/***************************************************************************
- EXECEPTION HANDLING
-***************************************************************************/
-INLINE void generate_exception(r3000_state *r3000, int exception)
+//-------------------------------------------------
+// state_import - import state into the device,
+// after it has been set
+//-------------------------------------------------
+
+void r3000_device::state_import(const device_state_entry &entry)
{
- /* set the exception PC */
- r3000->cpr[0][COP0_EPC] = r3000->pc;
+ switch (entry.index())
+ {
+ case STATE_GENFLAGS:
+ break;
+
+ default:
+ fatalerror("r3000_device::state_import called for unexpected value\n");
+ break;
+ }
+}
- /* put the cause in the low 8 bits and clear the branch delay flag */
- r3000->CAUSE = (r3000->CAUSE & ~0x800000ff) | (exception << 2);
- /* if we were in a branch delay slot, adjust */
- if (r3000->nextpc != ~0)
+//-------------------------------------------------
+// state_export - export state out of the device
+//-------------------------------------------------
+
+void r3000_device::state_export(const device_state_entry &entry)
+{
+ switch (entry.index())
{
- r3000->nextpc = ~0;
- r3000->cpr[0][COP0_EPC] -= 4;
- r3000->CAUSE |= 0x80000000;
+ case STATE_GENFLAGS:
+ break;
+
+ default:
+ fatalerror("r3000_device::state_export called for unexpected value\n");
+ break;
}
+}
- /* shift the exception bits */
- r3000->SR = (r3000->SR & 0xffffffc0) | ((r3000->SR << 2) & 0x3c);
- /* based on the BEV bit, we either go to ROM or RAM */
- r3000->pc = (r3000->SR & SR_BEV) ? 0xbfc00000 : 0x80000000;
+//-------------------------------------------------
+// state_string_export - export state as a string
+// for the debugger
+//-------------------------------------------------
- /* most exceptions go to offset 0x180, except for TLB stuff */
- if (exception >= EXCEPTION_TLBMOD && exception <= EXCEPTION_TLBSTORE)
- r3000->pc += 0x80;
+void r3000_device::state_string_export(const device_state_entry &entry, astring &string)
+{
+ switch (entry.index())
+ {
+ case STATE_GENFLAGS:
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// disasm_min_opcode_bytes - return the length
+// of the shortest instruction, in bytes
+//-------------------------------------------------
+
+UINT32 r3000_device::disasm_min_opcode_bytes() const
+{
+ return 4;
+}
+
+
+//-------------------------------------------------
+// disasm_max_opcode_bytes - return the length
+// of the longest instruction, in bytes
+//-------------------------------------------------
+
+UINT32 r3000_device::disasm_max_opcode_bytes() const
+{
+ return 4;
+}
+
+
+//-------------------------------------------------
+// disasm_disassemble - call the disassembly
+// helper function
+//-------------------------------------------------
+
+offs_t r3000_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE( r3000le );
+ extern CPU_DISASSEMBLE( r3000be );
+
+ if (m_endianness == ENDIANNESS_BIG)
+ return CPU_DISASSEMBLE_NAME(r3000be)(NULL, buffer, pc, oprom, opram, 0);
else
- r3000->pc += 0x180;
+ return CPU_DISASSEMBLE_NAME(r3000le)(NULL, buffer, pc, oprom, opram, 0);
}
-INLINE void invalid_instruction(r3000_state *r3000, UINT32 op)
+/***************************************************************************
+ MEMORY ACCESSORS
+***************************************************************************/
+
+inline UINT32 r3000_device::readop(off_t pc)
{
- generate_exception(r3000, EXCEPTION_INVALIDOP);
+ return m_direct->read_decrypted_dword(pc);
}
+UINT8 r3000_device::readmem(offs_t offset)
+{
+ return m_program->read_byte(offset);
+}
+
+UINT16 r3000_device::readmem_word(offs_t offset)
+{
+ return m_program->read_word(offset);
+}
+
+UINT32 r3000_device::readmem_dword(offs_t offset)
+{
+ return m_program->read_dword(offset);
+}
+
+void r3000_device::writemem(offs_t offset, UINT8 data)
+{
+ m_program->write_byte(offset, data);
+}
+
+void r3000_device::writemem_word(offs_t offset, UINT16 data)
+{
+ m_program->write_word(offset, data);
+}
+
+void r3000_device::writemem_dword(offs_t offset, UINT32 data)
+{
+ m_program->write_dword(offset, data);
+}
/***************************************************************************
- IRQ HANDLING
+ BIG ENDIAN CACHE I/O
***************************************************************************/
-static void check_irqs(r3000_state *r3000)
+UINT8 r3000_device::readcache_be(offs_t offset)
{
- if ((r3000->CAUSE & r3000->SR & 0xff00) && (r3000->SR & SR_IEc))
- generate_exception(r3000, EXCEPTION_INTERRUPT);
+ offset &= 0x1fffffff;
+ return (offset * 4 < m_cache_size) ? m_cache[BYTE4_XOR_BE(offset)] : 0xff;
}
+UINT16 r3000_device::readcache_be_word(offs_t offset)
+{
+ offset &= 0x1fffffff;
+ return (offset * 4 < m_cache_size) ? *(UINT16 *)&m_cache[WORD_XOR_BE(offset)] : 0xffff;
+}
-static void set_irq_line(r3000_state *r3000, int irqline, int state)
+UINT32 r3000_device::readcache_be_dword(offs_t offset)
{
- if (state != CLEAR_LINE)
- r3000->CAUSE |= 0x400 << irqline;
- else
- r3000->CAUSE &= ~(0x400 << irqline);
- check_irqs(r3000);
+ offset &= 0x1fffffff;
+ return (offset * 4 < m_cache_size) ? *(UINT32 *)&m_cache[offset] : 0xffffffff;
}
+void r3000_device::writecache_be(offs_t offset, UINT8 data)
+{
+ offset &= 0x1fffffff;
+ if (offset * 4 < m_cache_size) m_cache[BYTE4_XOR_BE(offset)] = data;
+}
+
+void r3000_device::writecache_be_word(offs_t offset, UINT16 data)
+{
+ offset &= 0x1fffffff;
+ if (offset * 4 < m_cache_size) *(UINT16 *)&m_cache[WORD_XOR_BE(offset)] = data;
+}
+
+void r3000_device::writecache_be_dword(offs_t offset, UINT32 data)
+{
+ offset &= 0x1fffffff;
+ if (offset * 4 < m_cache_size) *(UINT32 *)&m_cache[offset] = data;
+}
+
+UINT8 r3000_device::readcache_le(offs_t offset)
+{
+ offset &= 0x1fffffff;
+ return (offset * 4 < m_cache_size) ? m_cache[BYTE4_XOR_LE(offset)] : 0xff;
+}
/***************************************************************************
- INITIALIZATION AND SHUTDOWN
+ LITTLE ENDIAN CACHE I/O
***************************************************************************/
-static CPU_INIT( r3000 )
+UINT16 r3000_device::readcache_le_word(offs_t offset)
+{
+ offset &= 0x1fffffff;
+ return (offset * 4 < m_cache_size) ? *(UINT16 *)&m_cache[WORD_XOR_LE(offset)] : 0xffff;
+}
+
+UINT32 r3000_device::readcache_le_dword(offs_t offset)
{
- const r3000_cpu_core *configdata = (const r3000_cpu_core *)device->static_config();
- r3000_state *r3000 = get_safe_token(device);
+ offset &= 0x1fffffff;
+ return (offset * 4 < m_cache_size) ? *(UINT32 *)&m_cache[offset] : 0xffffffff;
+}
- /* allocate memory */
- r3000->icache = auto_alloc_array(device->machine(), UINT32, configdata->icache/4);
- r3000->dcache = auto_alloc_array(device->machine(), UINT32, configdata->dcache/4);
+void r3000_device::writecache_le(offs_t offset, UINT8 data)
+{
+ offset &= 0x1fffffff;
+ if (offset * 4 < m_cache_size) m_cache[BYTE4_XOR_LE(offset)] = data;
+}
- r3000->icache_size = configdata->icache;
- r3000->dcache_size = configdata->dcache;
- r3000->hasfpu = configdata->hasfpu;
+void r3000_device::writecache_le_word(offs_t offset, UINT16 data)
+{
+ offset &= 0x1fffffff;
+ if (offset * 4 < m_cache_size) *(UINT16 *)&m_cache[WORD_XOR_LE(offset)] = data;
+}
- r3000->irq_callback = irqcallback;
- r3000->device = device;
- r3000->program = &device->space(AS_PROGRAM);
- r3000->direct = &r3000->program->direct();
+void r3000_device::writecache_le_dword(offs_t offset, UINT32 data)
+{
+ offset &= 0x1fffffff;
+ if (offset * 4 < m_cache_size) *(UINT32 *)&m_cache[offset] = data;
}
-static void r3000_reset(r3000_state *r3000, int bigendian)
+/***************************************************************************
+ EXECEPTION HANDLING
+***************************************************************************/
+
+inline void r3000_device::generate_exception(int exception)
{
- /* set up the endianness */
- r3000->bigendian = bigendian;
- r3000->program->accessors(r3000->memory_hand);
- if (r3000->bigendian)
- {
- r3000->cache_hand = &be_cache;
- r3000->lwl = lwl_be;
- r3000->lwr = lwr_be;
- r3000->swl = swl_be;
- r3000->swr = swr_be;
- }
- else
+ // set the exception PC
+ m_cpr[0][COP0_EPC] = m_pc;
+
+ // put the cause in the low 8 bits and clear the branch delay flag
+ CAUSE = (CAUSE & ~0x800000ff) | (exception << 2);
+
+ // if we were in a branch delay slot, adjust
+ if (m_nextpc != ~0)
{
- r3000->cache_hand = &le_cache;
- r3000->lwl = lwl_le;
- r3000->lwr = lwr_le;
- r3000->swl = swl_le;
- r3000->swr = swr_le;
+ m_nextpc = ~0;
+ m_cpr[0][COP0_EPC] -= 4;
+ CAUSE |= 0x80000000;
}
- /* initialize the rest of the config */
- r3000->cur = r3000->memory_hand;
- r3000->cache = r3000->dcache;
- r3000->cache_size = r3000->dcache_size;
+ // shift the exception bits
+ SR = (SR & 0xffffffc0) | ((SR << 2) & 0x3c);
- /* initialize the state */
- r3000->pc = 0xbfc00000;
- r3000->nextpc = ~0;
- r3000->cpr[0][COP0_PRId] = 0x0200;
- r3000->cpr[0][COP0_Status] = 0x0000;
+ // based on the BEV bit, we either go to ROM or RAM
+ m_pc = (SR & SR_BEV) ? 0xbfc00000 : 0x80000000;
+
+ // most exceptions go to offset 0x180, except for TLB stuff
+ if (exception >= EXCEPTION_TLBMOD && exception <= EXCEPTION_TLBSTORE)
+ m_pc += 0x80;
+ else
+ m_pc += 0x180;
}
-static CPU_RESET( r3000be )
+
+inline void r3000_device::invalid_instruction()
{
- r3000_reset(get_safe_token(device), 1);
+ generate_exception(EXCEPTION_INVALIDOP);
}
-static CPU_RESET( r3000le )
+
+/***************************************************************************
+ IRQ HANDLING
+***************************************************************************/
+
+void r3000_device::check_irqs()
{
- r3000_reset(get_safe_token(device), 0);
+ if ((CAUSE & SR & 0xff00) && (SR & SR_IEc))
+ generate_exception(EXCEPTION_INTERRUPT);
}
-static CPU_EXIT( r3000 )
+void r3000_device::set_irq_line(int irqline, int state)
{
-}
+ if (state != CLEAR_LINE)
+ CAUSE |= 0x400 << irqline;
+ else
+ CAUSE &= ~(0x400 << irqline);
+ check_irqs();
+}
/***************************************************************************
COP0 (SYSTEM) EXECUTION HANDLING
***************************************************************************/
-INLINE UINT32 get_cop0_reg(r3000_state *r3000, int idx)
+inline UINT32 r3000_device::get_cop0_reg(int idx)
{
- return r3000->cpr[0][idx];
+ return m_cpr[0][idx];
}
-INLINE void set_cop0_reg(r3000_state *r3000, int idx, UINT32 val)
+inline void r3000_device::set_cop0_reg(int idx, UINT32 val)
{
if (idx == COP0_Cause)
{
- r3000->CAUSE = (r3000->CAUSE & 0xfc00) | (val & ~0xfc00);
+ CAUSE = (CAUSE & 0xfc00) | (val & ~0xfc00);
- /* update interrupts -- software ints can occur this way */
- check_irqs(r3000);
+ // update interrupts -- software ints can occur this way
+ check_irqs();
}
else if (idx == COP0_Status)
{
- UINT32 oldsr = r3000->cpr[0][idx];
+ UINT32 oldsr = m_cpr[0][idx];
UINT32 diff = oldsr ^ val;
- /* handle cache isolation */
+ // handle cache isolation
if (diff & SR_IsC)
{
if (val & SR_IsC)
- r3000->cur = *r3000->cache_hand;
+ m_cur = &m_cache_hand;
else
- r3000->cur = r3000->memory_hand;
+ m_cur = &m_memory_hand;
}
- /* handle cache switching */
+ // handle cache switching
if (diff & SR_SwC)
{
if (val & SR_SwC)
- r3000->cache = r3000->icache, r3000->cache_size = r3000->icache_size;
+ m_cache = m_icache, m_cache_size = m_icache_size;
else
- r3000->cache = r3000->dcache, r3000->cache_size = r3000->dcache_size;
+ m_cache = m_dcache, m_cache_size = m_dcache_size;
}
- r3000->cpr[0][idx] = val;
+ m_cpr[0][idx] = val;
- /* update interrupts */
- check_irqs(r3000);
+ // update interrupts
+ check_irqs();
}
else
- r3000->cpr[0][idx] = val;
+ m_cpr[0][idx] = val;
}
-INLINE UINT32 get_cop0_creg(r3000_state *r3000, int idx)
+inline UINT32 r3000_device::get_cop0_creg(int idx)
{
- return r3000->ccr[0][idx];
+ return m_ccr[0][idx];
}
-INLINE void set_cop0_creg(r3000_state *r3000, int idx, UINT32 val)
+inline void r3000_device::set_cop0_creg(int idx, UINT32 val)
{
- r3000->ccr[0][idx] = val;
+ m_ccr[0][idx] = val;
}
-INLINE void handle_cop0(r3000_state *r3000, UINT32 op)
+inline void r3000_device::handle_cop0()
{
- if (!(r3000->SR & SR_COP0) && (r3000->SR & SR_KUc))
- generate_exception(r3000, EXCEPTION_BADCOP);
+ if (!(SR & SR_COP0) && (SR & SR_KUc))
+ generate_exception(EXCEPTION_BADCOP);
switch (RSREG)
{
- case 0x00: /* MFCz */ if (RTREG) r3000->RTVAL = get_cop0_reg(r3000, RDREG); break;
- case 0x02: /* CFCz */ if (RTREG) r3000->RTVAL = get_cop0_creg(r3000, RDREG); break;
- case 0x04: /* MTCz */ set_cop0_reg(r3000, RDREG, r3000->RTVAL); break;
- case 0x06: /* CTCz */ set_cop0_creg(r3000, RDREG, r3000->RTVAL); break;
+ case 0x00: /* MFCz */ if (RTREG) RTVAL = get_cop0_reg(RDREG); break;
+ case 0x02: /* CFCz */ if (RTREG) RTVAL = get_cop0_creg(RDREG); break;
+ case 0x04: /* MTCz */ set_cop0_reg(RDREG, RTVAL); break;
+ case 0x06: /* CTCz */ set_cop0_creg(RDREG, RTVAL); break;
case 0x08: /* BC */
switch (RTREG)
{
- case 0x00: /* BCzF */ if (!r3000->cf[0]) ADDPC(r3000, SIMMVAL); break;
- case 0x01: /* BCzF */ if (r3000->cf[0]) ADDPC(r3000, SIMMVAL); break;
- case 0x02: /* BCzFL */ invalid_instruction(r3000, op); break;
- case 0x03: /* BCzTL */ invalid_instruction(r3000, op); break;
- default: invalid_instruction(r3000, op); break;
+ case 0x00: /* BCzF */ if (!m_in_brcond0()) ADDPC(SIMMVAL); break;
+ case 0x01: /* BCzT */ if (m_in_brcond0()) ADDPC(SIMMVAL); break;
+ case 0x02: /* BCzFL */ invalid_instruction(); break;
+ case 0x03: /* BCzTL */ invalid_instruction(); break;
+ default: invalid_instruction(); break;
}
break;
case 0x10:
@@ -463,68 +772,67 @@ INLINE void handle_cop0(r3000_state *r3000, UINT32 op)
case 0x1d:
case 0x1e:
case 0x1f: /* COP */
- switch (op & 0x01ffffff)
+ switch (m_op & 0x01ffffff)
{
case 0x01: /* TLBR */ break;
case 0x02: /* TLBWI */ break;
case 0x06: /* TLBWR */ break;
case 0x08: /* TLBP */ break;
- case 0x10: /* RFE */ r3000->SR = (r3000->SR & 0xfffffff0) | ((r3000->SR >> 2) & 0x0f); break;
- case 0x18: /* ERET */ invalid_instruction(r3000, op); break;
- default: invalid_instruction(r3000, op); break;
+ case 0x10: /* RFE */ SR = (SR & 0xfffffff0) | ((SR >> 2) & 0x0f); break;
+ case 0x18: /* ERET */ invalid_instruction(); break;
+ default: invalid_instruction(); break;
}
break;
- default: invalid_instruction(r3000, op); break;
+ default: invalid_instruction(); break;
}
}
-
/***************************************************************************
COP1 (FPU) EXECUTION HANDLING
***************************************************************************/
-INLINE UINT32 get_cop1_reg(r3000_state *r3000, int idx)
+inline UINT32 r3000_device::get_cop1_reg(int idx)
{
- return r3000->cpr[1][idx];
+ return m_cpr[1][idx];
}
-INLINE void set_cop1_reg(r3000_state *r3000, int idx, UINT32 val)
+inline void r3000_device::set_cop1_reg(int idx, UINT32 val)
{
- r3000->cpr[1][idx] = val;
+ m_cpr[1][idx] = val;
}
-INLINE UINT32 get_cop1_creg(r3000_state *r3000, int idx)
+inline UINT32 r3000_device::get_cop1_creg(int idx)
{
- return r3000->ccr[1][idx];
+ return m_ccr[1][idx];
}
-INLINE void set_cop1_creg(r3000_state *r3000, int idx, UINT32 val)
+inline void r3000_device::set_cop1_creg(int idx, UINT32 val)
{
- r3000->ccr[1][idx] = val;
+ m_ccr[1][idx] = val;
}
-INLINE void handle_cop1(r3000_state *r3000, UINT32 op)
+inline void r3000_device::handle_cop1()
{
- if (!(r3000->SR & SR_COP1))
- generate_exception(r3000, EXCEPTION_BADCOP);
- if (!r3000->hasfpu)
+ if (!(SR & SR_COP1))
+ generate_exception(EXCEPTION_BADCOP);
+ if (!m_hasfpu)
return;
switch (RSREG)
{
- case 0x00: /* MFCz */ if (RTREG) r3000->RTVAL = get_cop1_reg(r3000, RDREG); break;
- case 0x02: /* CFCz */ if (RTREG) r3000->RTVAL = get_cop1_creg(r3000, RDREG); break;
- case 0x04: /* MTCz */ set_cop1_reg(r3000, RDREG, r3000->RTVAL); break;
- case 0x06: /* CTCz */ set_cop1_creg(r3000, RDREG, r3000->RTVAL); break;
+ case 0x00: /* MFCz */ if (RTREG) RTVAL = get_cop1_reg(RDREG); break;
+ case 0x02: /* CFCz */ if (RTREG) RTVAL = get_cop1_creg(RDREG); break;
+ case 0x04: /* MTCz */ set_cop1_reg(RDREG, RTVAL); break;
+ case 0x06: /* CTCz */ set_cop1_creg(RDREG, RTVAL); break;
case 0x08: /* BC */
switch (RTREG)
{
- case 0x00: /* BCzF */ if (!r3000->cf[1]) ADDPC(r3000, SIMMVAL); break;
- case 0x01: /* BCzF */ if (r3000->cf[1]) ADDPC(r3000, SIMMVAL); break;
- case 0x02: /* BCzFL */ invalid_instruction(r3000, op); break;
- case 0x03: /* BCzTL */ invalid_instruction(r3000, op); break;
- default: invalid_instruction(r3000, op); break;
+ case 0x00: /* BCzF */ if (!m_in_brcond1()) ADDPC(SIMMVAL); break;
+ case 0x01: /* BCzT */ if (m_in_brcond1()) ADDPC(SIMMVAL); break;
+ case 0x02: /* BCzFL */ invalid_instruction(); break;
+ case 0x03: /* BCzTL */ invalid_instruction(); break;
+ default: invalid_instruction(); break;
}
break;
case 0x10:
@@ -542,56 +850,55 @@ INLINE void handle_cop1(r3000_state *r3000, UINT32 op)
case 0x1c:
case 0x1d:
case 0x1e:
- case 0x1f: /* COP */ invalid_instruction(r3000, op); break;
- default: invalid_instruction(r3000, op); break;
+ case 0x1f: /* COP */ invalid_instruction(); break;
+ default: invalid_instruction(); break;
}
}
-
/***************************************************************************
COP2 (CUSTOM) EXECUTION HANDLING
***************************************************************************/
-INLINE UINT32 get_cop2_reg(r3000_state *r3000, int idx)
+inline UINT32 r3000_device::get_cop2_reg(int idx)
{
- return r3000->cpr[2][idx];
+ return m_cpr[2][idx];
}
-INLINE void set_cop2_reg(r3000_state *r3000, int idx, UINT32 val)
+inline void r3000_device::set_cop2_reg(int idx, UINT32 val)
{
- r3000->cpr[2][idx] = val;
+ m_cpr[2][idx] = val;
}
-INLINE UINT32 get_cop2_creg(r3000_state *r3000, int idx)
+inline UINT32 r3000_device::get_cop2_creg(int idx)
{
- return r3000->ccr[2][idx];
+ return m_ccr[2][idx];
}
-INLINE void set_cop2_creg(r3000_state *r3000, int idx, UINT32 val)
+inline void r3000_device::set_cop2_creg(int idx, UINT32 val)
{
- r3000->ccr[2][idx] = val;
+ m_ccr[2][idx] = val;
}
-INLINE void handle_cop2(r3000_state *r3000, UINT32 op)
+inline void r3000_device::handle_cop2()
{
- if (!(r3000->SR & SR_COP2))
- generate_exception(r3000, EXCEPTION_BADCOP);
+ if (!(SR & SR_COP2))
+ generate_exception(EXCEPTION_BADCOP);
switch (RSREG)
{
- case 0x00: /* MFCz */ if (RTREG) r3000->RTVAL = get_cop2_reg(r3000, RDREG); break;
- case 0x02: /* CFCz */ if (RTREG) r3000->RTVAL = get_cop2_creg(r3000, RDREG); break;
- case 0x04: /* MTCz */ set_cop2_reg(r3000, RDREG, r3000->RTVAL); break;
- case 0x06: /* CTCz */ set_cop2_creg(r3000, RDREG, r3000->RTVAL); break;
+ case 0x00: /* MFCz */ if (RTREG) RTVAL = get_cop2_reg(RDREG); break;
+ case 0x02: /* CFCz */ if (RTREG) RTVAL = get_cop2_creg(RDREG); break;
+ case 0x04: /* MTCz */ set_cop2_reg(RDREG, RTVAL); break;
+ case 0x06: /* CTCz */ set_cop2_creg(RDREG, RTVAL); break;
case 0x08: /* BC */
switch (RTREG)
{
- case 0x00: /* BCzF */ if (!r3000->cf[2]) ADDPC(r3000, SIMMVAL); break;
- case 0x01: /* BCzF */ if (r3000->cf[2]) ADDPC(r3000, SIMMVAL); break;
- case 0x02: /* BCzFL */ invalid_instruction(r3000, op); break;
- case 0x03: /* BCzTL */ invalid_instruction(r3000, op); break;
- default: invalid_instruction(r3000, op); break;
+ case 0x00: /* BCzF */ if (!m_in_brcond2()) ADDPC(SIMMVAL); break;
+ case 0x01: /* BCzT */ if (m_in_brcond2()) ADDPC(SIMMVAL); break;
+ case 0x02: /* BCzFL */ invalid_instruction(); break;
+ case 0x03: /* BCzTL */ invalid_instruction(); break;
+ default: invalid_instruction(); break;
}
break;
case 0x10:
@@ -609,56 +916,55 @@ INLINE void handle_cop2(r3000_state *r3000, UINT32 op)
case 0x1c:
case 0x1d:
case 0x1e:
- case 0x1f: /* COP */ invalid_instruction(r3000, op); break;
- default: invalid_instruction(r3000, op); break;
+ case 0x1f: /* COP */ invalid_instruction(); break;
+ default: invalid_instruction(); break;
}
}
-
/***************************************************************************
COP3 (CUSTOM) EXECUTION HANDLING
***************************************************************************/
-INLINE UINT32 get_cop3_reg(r3000_state *r3000, int idx)
+inline UINT32 r3000_device::get_cop3_reg(int idx)
{
- return r3000->cpr[3][idx];
+ return m_cpr[3][idx];
}
-INLINE void set_cop3_reg(r3000_state *r3000, int idx, UINT32 val)
+inline void r3000_device::set_cop3_reg(int idx, UINT32 val)
{
- r3000->cpr[3][idx] = val;
+ m_cpr[3][idx] = val;
}
-INLINE UINT32 get_cop3_creg(r3000_state *r3000, int idx)
+inline UINT32 r3000_device::get_cop3_creg(int idx)
{
- return r3000->ccr[3][idx];
+ return m_ccr[3][idx];
}
-INLINE void set_cop3_creg(r3000_state *r3000, int idx, UINT32 val)
+inline void r3000_device::set_cop3_creg(int idx, UINT32 val)
{
- r3000->ccr[3][idx] = val;
+ m_ccr[3][idx] = val;
}
-INLINE void handle_cop3(r3000_state *r3000, UINT32 op)
+inline void r3000_device::handle_cop3()
{
- if (!(r3000->SR & SR_COP3))
- generate_exception(r3000, EXCEPTION_BADCOP);
+ if (!(SR & SR_COP3))
+ generate_exception(EXCEPTION_BADCOP);
switch (RSREG)
{
- case 0x00: /* MFCz */ if (RTREG) r3000->RTVAL = get_cop3_reg(r3000, RDREG); break;
- case 0x02: /* CFCz */ if (RTREG) r3000->RTVAL = get_cop3_creg(r3000, RDREG); break;
- case 0x04: /* MTCz */ set_cop3_reg(r3000, RDREG, r3000->RTVAL); break;
- case 0x06: /* CTCz */ set_cop3_creg(r3000, RDREG, r3000->RTVAL); break;
+ case 0x00: /* MFCz */ if (RTREG) RTVAL = get_cop3_reg(RDREG); break;
+ case 0x02: /* CFCz */ if (RTREG) RTVAL = get_cop3_creg(RDREG); break;
+ case 0x04: /* MTCz */ set_cop3_reg(RDREG, RTVAL); break;
+ case 0x06: /* CTCz */ set_cop3_creg(RDREG, RTVAL); break;
case 0x08: /* BC */
switch (RTREG)
{
- case 0x00: /* BCzF */ if (!r3000->cf[3]) ADDPC(r3000, SIMMVAL); break;
- case 0x01: /* BCzF */ if (r3000->cf[3]) ADDPC(r3000, SIMMVAL); break;
- case 0x02: /* BCzFL */ invalid_instruction(r3000, op); break;
- case 0x03: /* BCzTL */ invalid_instruction(r3000, op); break;
- default: invalid_instruction(r3000, op); break;
+ case 0x00: /* BCzF */ if (!m_in_brcond3()) ADDPC(SIMMVAL); break;
+ case 0x01: /* BCzT */ if (m_in_brcond3()) ADDPC(SIMMVAL); break;
+ case 0x02: /* BCzFL */ invalid_instruction(); break;
+ case 0x03: /* BCzTL */ invalid_instruction(); break;
+ default: invalid_instruction(); break;
}
break;
case 0x10:
@@ -676,701 +982,366 @@ INLINE void handle_cop3(r3000_state *r3000, UINT32 op)
case 0x1c:
case 0x1d:
case 0x1e:
- case 0x1f: /* COP */ invalid_instruction(r3000, op); break;
- default: invalid_instruction(r3000, op); break;
+ case 0x1f: /* COP */ invalid_instruction(); break;
+ default: invalid_instruction(); break;
}
}
-
/***************************************************************************
CORE EXECUTION LOOP
***************************************************************************/
-static CPU_EXECUTE( r3000 )
+//-------------------------------------------------
+// execute_min_cycles - return minimum number of
+// cycles it takes for one instruction to execute
+//-------------------------------------------------
+
+UINT32 r3000_device::execute_min_cycles() const
+{
+ return 1;
+}
+
+
+//-------------------------------------------------
+// execute_max_cycles - return maximum number of
+// cycles it takes for one instruction to execute
+//-------------------------------------------------
+
+UINT32 r3000_device::execute_max_cycles() const
{
- r3000_state *r3000 = get_safe_token(device);
+ return 40;
+}
+
- /* count cycles and interrupt cycles */
- r3000->icount -= r3000->interrupt_cycles;
- r3000->interrupt_cycles = 0;
+//-------------------------------------------------
+// execute_input_lines - return the number of
+// input/interrupt lines
+//-------------------------------------------------
- /* check for IRQs */
- check_irqs(r3000);
+UINT32 r3000_device::execute_input_lines() const
+{
+ return 6;
+}
+
+
+//-------------------------------------------------
+// execute_set_input
+//-------------------------------------------------
+
+void r3000_device::execute_set_input(int inputnum, int state)
+{
+ set_irq_line(inputnum, state);
+}
+
+
+//-------------------------------------------------
+// execute_run
+//-------------------------------------------------
+
+void r3000_device::execute_run()
+{
+ // count cycles and interrupt cycles
+ m_icount -= m_interrupt_cycles;
+ m_interrupt_cycles = 0;
- /* core execution loop */
+ // check for IRQs
+ check_irqs();
+
+ // core execution loop
do
{
- UINT32 op;
UINT64 temp64;
int temp;
- /* debugging */
- r3000->ppc = r3000->pc;
- debugger_instruction_hook(device, r3000->pc);
+ // debugging
+ m_ppc = m_pc;
+ debugger_instruction_hook(this, m_pc);
- /* instruction fetch */
- op = ROPCODE(r3000, r3000->pc);
+ // instruction fetch
+ m_op = readop(m_pc);
- /* adjust for next PC */
- if (r3000->nextpc != ~0)
+ // adjust for next PC
+ if (m_nextpc != ~0)
{
- r3000->pc = r3000->nextpc;
- r3000->nextpc = ~0;
+ m_pc = m_nextpc;
+ m_nextpc = ~0;
}
else
- r3000->pc += 4;
+ m_pc += 4;
- /* parse the instruction */
- switch (op >> 26)
+ // parse the instruction
+ switch (m_op >> 26)
{
case 0x00: /* SPECIAL */
- switch (op & 63)
+ switch (m_op & 63)
{
- case 0x00: /* SLL */ if (RDREG) r3000->RDVAL = r3000->RTVAL << SHIFT; break;
- case 0x02: /* SRL */ if (RDREG) r3000->RDVAL = r3000->RTVAL >> SHIFT; break;
- case 0x03: /* SRA */ if (RDREG) r3000->RDVAL = (INT32)r3000->RTVAL >> SHIFT; break;
- case 0x04: /* SLLV */ if (RDREG) r3000->RDVAL = r3000->RTVAL << (r3000->RSVAL & 31); break;
- case 0x06: /* SRLV */ if (RDREG) r3000->RDVAL = r3000->RTVAL >> (r3000->RSVAL & 31); break;
- case 0x07: /* SRAV */ if (RDREG) r3000->RDVAL = (INT32)r3000->RTVAL >> (r3000->RSVAL & 31); break;
- case 0x08: /* JR */ SETPC(r3000, r3000->RSVAL); break;
- case 0x09: /* JALR */ SETPCL(r3000, r3000->RSVAL, RDREG); break;
- case 0x0c: /* SYSCALL */ generate_exception(r3000, EXCEPTION_SYSCALL); break;
- case 0x0d: /* BREAK */ generate_exception(r3000, EXCEPTION_BREAK); break;
- case 0x0f: /* SYNC */ invalid_instruction(r3000, op); break;
- case 0x10: /* MFHI */ if (RDREG) r3000->RDVAL = r3000->hi; break;
- case 0x11: /* MTHI */ r3000->hi = r3000->RSVAL; break;
- case 0x12: /* MFLO */ if (RDREG) r3000->RDVAL = r3000->lo; break;
- case 0x13: /* MTLO */ r3000->lo = r3000->RSVAL; break;
+ case 0x00: /* SLL */ if (RDREG) RDVAL = RTVAL << SHIFT; break;
+ case 0x02: /* SRL */ if (RDREG) RDVAL = RTVAL >> SHIFT; break;
+ case 0x03: /* SRA */ if (RDREG) RDVAL = (INT32)RTVAL >> SHIFT; break;
+ case 0x04: /* SLLV */ if (RDREG) RDVAL = RTVAL << (RSVAL & 31); break;
+ case 0x06: /* SRLV */ if (RDREG) RDVAL = RTVAL >> (RSVAL & 31); break;
+ case 0x07: /* SRAV */ if (RDREG) RDVAL = (INT32)RTVAL >> (RSVAL & 31); break;
+ case 0x08: /* JR */ SETPC(RSVAL); break;
+ case 0x09: /* JALR */ SETPCL(RSVAL, RDREG); break;
+ case 0x0c: /* SYSCALL */ generate_exception(EXCEPTION_SYSCALL); break;
+ case 0x0d: /* BREAK */ generate_exception(EXCEPTION_BREAK); break;
+ case 0x0f: /* SYNC */ invalid_instruction(); break;
+ case 0x10: /* MFHI */ if (RDREG) RDVAL = m_hi; break;
+ case 0x11: /* MTHI */ m_hi = RSVAL; break;
+ case 0x12: /* MFLO */ if (RDREG) RDVAL = m_lo; break;
+ case 0x13: /* MTLO */ m_lo = RSVAL; break;
case 0x18: /* MULT */
- temp64 = (INT64)(INT32)r3000->RSVAL * (INT64)(INT32)r3000->RTVAL;
- r3000->lo = (UINT32)temp64;
- r3000->hi = (UINT32)(temp64 >> 32);
- r3000->icount -= 11;
+ temp64 = (INT64)(INT32)RSVAL * (INT64)(INT32)RTVAL;
+ m_lo = (UINT32)temp64;
+ m_hi = (UINT32)(temp64 >> 32);
+ m_icount -= 11;
break;
case 0x19: /* MULTU */
- temp64 = (UINT64)r3000->RSVAL * (UINT64)r3000->RTVAL;
- r3000->lo = (UINT32)temp64;
- r3000->hi = (UINT32)(temp64 >> 32);
- r3000->icount -= 11;
+ temp64 = (UINT64)RSVAL * (UINT64)RTVAL;
+ m_lo = (UINT32)temp64;
+ m_hi = (UINT32)(temp64 >> 32);
+ m_icount -= 11;
break;
case 0x1a: /* DIV */
- if (r3000->RTVAL)
+ if (RTVAL)
{
- r3000->lo = (INT32)r3000->RSVAL / (INT32)r3000->RTVAL;
- r3000->hi = (INT32)r3000->RSVAL % (INT32)r3000->RTVAL;
+ m_lo = (INT32)RSVAL / (INT32)RTVAL;
+ m_hi = (INT32)RSVAL % (INT32)RTVAL;
}
- r3000->icount -= 34;
+ m_icount -= 34;
break;
case 0x1b: /* DIVU */
- if (r3000->RTVAL)
+ if (RTVAL)
{
- r3000->lo = r3000->RSVAL / r3000->RTVAL;
- r3000->hi = r3000->RSVAL % r3000->RTVAL;
+ m_lo = RSVAL / RTVAL;
+ m_hi = RSVAL % RTVAL;
}
- r3000->icount -= 34;
+ m_icount -= 34;
break;
case 0x20: /* ADD */
- if (ENABLE_OVERFLOWS && r3000->RSVAL > ~r3000->RTVAL) generate_exception(r3000, EXCEPTION_OVERFLOW);
- else r3000->RDVAL = r3000->RSVAL + r3000->RTVAL;
+ if (ENABLE_OVERFLOWS && RSVAL > ~RTVAL) generate_exception(EXCEPTION_OVERFLOW);
+ else RDVAL = RSVAL + RTVAL;
break;
- case 0x21: /* ADDU */ if (RDREG) r3000->RDVAL = r3000->RSVAL + r3000->RTVAL; break;
+ case 0x21: /* ADDU */ if (RDREG) RDVAL = RSVAL + RTVAL; break;
case 0x22: /* SUB */
- if (ENABLE_OVERFLOWS && r3000->RSVAL < r3000->RTVAL) generate_exception(r3000, EXCEPTION_OVERFLOW);
- else r3000->RDVAL = r3000->RSVAL - r3000->RTVAL;
+ if (ENABLE_OVERFLOWS && RSVAL < RTVAL) generate_exception(EXCEPTION_OVERFLOW);
+ else RDVAL = RSVAL - RTVAL;
break;
- case 0x23: /* SUBU */ if (RDREG) r3000->RDVAL = r3000->RSVAL - r3000->RTVAL; break;
- case 0x24: /* AND */ if (RDREG) r3000->RDVAL = r3000->RSVAL & r3000->RTVAL; break;
- case 0x25: /* OR */ if (RDREG) r3000->RDVAL = r3000->RSVAL | r3000->RTVAL; break;
- case 0x26: /* XOR */ if (RDREG) r3000->RDVAL = r3000->RSVAL ^ r3000->RTVAL; break;
- case 0x27: /* NOR */ if (RDREG) r3000->RDVAL = ~(r3000->RSVAL | r3000->RTVAL); break;
- case 0x2a: /* SLT */ if (RDREG) r3000->RDVAL = (INT32)r3000->RSVAL < (INT32)r3000->RTVAL; break;
- case 0x2b: /* SLTU */ if (RDREG) r3000->RDVAL = (UINT32)r3000->RSVAL < (UINT32)r3000->RTVAL; break;
- case 0x30: /* TEQ */ invalid_instruction(r3000, op); break;
- case 0x31: /* TGEU */ invalid_instruction(r3000, op); break;
- case 0x32: /* TLT */ invalid_instruction(r3000, op); break;
- case 0x33: /* TLTU */ invalid_instruction(r3000, op); break;
- case 0x34: /* TGE */ invalid_instruction(r3000, op); break;
- case 0x36: /* TNE */ invalid_instruction(r3000, op); break;
- default: /* ??? */ invalid_instruction(r3000, op); break;
+ case 0x23: /* SUBU */ if (RDREG) RDVAL = RSVAL - RTVAL; break;
+ case 0x24: /* AND */ if (RDREG) RDVAL = RSVAL & RTVAL; break;
+ case 0x25: /* OR */ if (RDREG) RDVAL = RSVAL | RTVAL; break;
+ case 0x26: /* XOR */ if (RDREG) RDVAL = RSVAL ^ RTVAL; break;
+ case 0x27: /* NOR */ if (RDREG) RDVAL = ~(RSVAL | RTVAL); break;
+ case 0x2a: /* SLT */ if (RDREG) RDVAL = (INT32)RSVAL < (INT32)RTVAL; break;
+ case 0x2b: /* SLTU */ if (RDREG) RDVAL = (UINT32)RSVAL < (UINT32)RTVAL; break;
+ case 0x30: /* TEQ */ invalid_instruction(); break;
+ case 0x31: /* TGEU */ invalid_instruction(); break;
+ case 0x32: /* TLT */ invalid_instruction(); break;
+ case 0x33: /* TLTU */ invalid_instruction(); break;
+ case 0x34: /* TGE */ invalid_instruction(); break;
+ case 0x36: /* TNE */ invalid_instruction(); break;
+ default: /* ??? */ invalid_instruction(); break;
}
break;
case 0x01: /* REGIMM */
switch (RTREG)
{
- case 0x00: /* BLTZ */ if ((INT32)r3000->RSVAL < 0) ADDPC(r3000, SIMMVAL); break;
- case 0x01: /* BGEZ */ if ((INT32)r3000->RSVAL >= 0) ADDPC(r3000, SIMMVAL); break;
- case 0x02: /* BLTZL */ invalid_instruction(r3000, op); break;
- case 0x03: /* BGEZL */ invalid_instruction(r3000, op); break;
- case 0x08: /* TGEI */ invalid_instruction(r3000, op); break;
- case 0x09: /* TGEIU */ invalid_instruction(r3000, op); break;
- case 0x0a: /* TLTI */ invalid_instruction(r3000, op); break;
- case 0x0b: /* TLTIU */ invalid_instruction(r3000, op); break;
- case 0x0c: /* TEQI */ invalid_instruction(r3000, op); break;
- case 0x0e: /* TNEI */ invalid_instruction(r3000, op); break;
- case 0x10: /* BLTZAL */ if ((INT32)r3000->RSVAL < 0) ADDPCL(r3000,SIMMVAL,31); break;
- case 0x11: /* BGEZAL */ if ((INT32)r3000->RSVAL >= 0) ADDPCL(r3000,SIMMVAL,31); break;
- case 0x12: /* BLTZALL */ invalid_instruction(r3000, op); break;
- case 0x13: /* BGEZALL */ invalid_instruction(r3000, op); break;
- default: /* ??? */ invalid_instruction(r3000, op); break;
+ case 0x00: /* BLTZ */ if ((INT32)RSVAL < 0) ADDPC(SIMMVAL); break;
+ case 0x01: /* BGEZ */ if ((INT32)RSVAL >= 0) ADDPC(SIMMVAL); break;
+ case 0x02: /* BLTZL */ invalid_instruction(); break;
+ case 0x03: /* BGEZL */ invalid_instruction(); break;
+ case 0x08: /* TGEI */ invalid_instruction(); break;
+ case 0x09: /* TGEIU */ invalid_instruction(); break;
+ case 0x0a: /* TLTI */ invalid_instruction(); break;
+ case 0x0b: /* TLTIU */ invalid_instruction(); break;
+ case 0x0c: /* TEQI */ invalid_instruction(); break;
+ case 0x0e: /* TNEI */ invalid_instruction(); break;
+ case 0x10: /* BLTZAL */ if ((INT32)RSVAL < 0) ADDPCL(SIMMVAL,31); break;
+ case 0x11: /* BGEZAL */ if ((INT32)RSVAL >= 0) ADDPCL(SIMMVAL,31); break;
+ case 0x12: /* BLTZALL */ invalid_instruction(); break;
+ case 0x13: /* BGEZALL */ invalid_instruction(); break;
+ default: /* ??? */ invalid_instruction(); break;
}
break;
- case 0x02: /* J */ ABSPC(r3000, LIMMVAL); break;
- case 0x03: /* JAL */ ABSPCL(r3000, LIMMVAL,31); break;
- case 0x04: /* BEQ */ if (r3000->RSVAL == r3000->RTVAL) ADDPC(r3000, SIMMVAL); break;
- case 0x05: /* BNE */ if (r3000->RSVAL != r3000->RTVAL) ADDPC(r3000, SIMMVAL); break;
- case 0x06: /* BLEZ */ if ((INT32)r3000->RSVAL <= 0) ADDPC(r3000, SIMMVAL); break;
- case 0x07: /* BGTZ */ if ((INT32)r3000->RSVAL > 0) ADDPC(r3000, SIMMVAL); break;
+ case 0x02: /* J */ ABSPC(LIMMVAL); break;
+ case 0x03: /* JAL */ ABSPCL(LIMMVAL,31); break;
+ case 0x04: /* BEQ */ if (RSVAL == RTVAL) ADDPC(SIMMVAL); break;
+ case 0x05: /* BNE */ if (RSVAL != RTVAL) ADDPC(SIMMVAL); break;
+ case 0x06: /* BLEZ */ if ((INT32)RSVAL <= 0) ADDPC(SIMMVAL); break;
+ case 0x07: /* BGTZ */ if ((INT32)RSVAL > 0) ADDPC(SIMMVAL); break;
case 0x08: /* ADDI */
- if (ENABLE_OVERFLOWS && r3000->RSVAL > ~SIMMVAL) generate_exception(r3000, EXCEPTION_OVERFLOW);
- else if (RTREG) r3000->RTVAL = r3000->RSVAL + SIMMVAL;
+ if (ENABLE_OVERFLOWS && RSVAL > ~SIMMVAL) generate_exception(EXCEPTION_OVERFLOW);
+ else if (RTREG) RTVAL = RSVAL + SIMMVAL;
break;
- case 0x09: /* ADDIU */ if (RTREG) r3000->RTVAL = r3000->RSVAL + SIMMVAL; break;
- case 0x0a: /* SLTI */ if (RTREG) r3000->RTVAL = (INT32)r3000->RSVAL < (INT32)SIMMVAL; break;
- case 0x0b: /* SLTIU */ if (RTREG) r3000->RTVAL = (UINT32)r3000->RSVAL < (UINT32)SIMMVAL; break;
- case 0x0c: /* ANDI */ if (RTREG) r3000->RTVAL = r3000->RSVAL & UIMMVAL; break;
- case 0x0d: /* ORI */ if (RTREG) r3000->RTVAL = r3000->RSVAL | UIMMVAL; break;
- case 0x0e: /* XORI */ if (RTREG) r3000->RTVAL = r3000->RSVAL ^ UIMMVAL; break;
- case 0x0f: /* LUI */ if (RTREG) r3000->RTVAL = UIMMVAL << 16; break;
- case 0x10: /* COP0 */ handle_cop0(r3000, op); break;
- case 0x11: /* COP1 */ handle_cop1(r3000, op); break;
- case 0x12: /* COP2 */ handle_cop2(r3000, op); break;
- case 0x13: /* COP3 */ handle_cop3(r3000, op); break;
- case 0x14: /* BEQL */ invalid_instruction(r3000, op); break;
- case 0x15: /* BNEL */ invalid_instruction(r3000, op); break;
- case 0x16: /* BLEZL */ invalid_instruction(r3000, op); break;
- case 0x17: /* BGTZL */ invalid_instruction(r3000, op); break;
- case 0x20: /* LB */ temp = RBYTE(r3000, SIMMVAL+r3000->RSVAL); if (RTREG) r3000->RTVAL = (INT8)temp; break;
- case 0x21: /* LH */ temp = RWORD(r3000, SIMMVAL+r3000->RSVAL); if (RTREG) r3000->RTVAL = (INT16)temp; break;
- case 0x22: /* LWL */ (*r3000->lwl)(r3000, op); break;
- case 0x23: /* LW */ temp = RLONG(r3000, SIMMVAL+r3000->RSVAL); if (RTREG) r3000->RTVAL = temp; break;
- case 0x24: /* LBU */ temp = RBYTE(r3000, SIMMVAL+r3000->RSVAL); if (RTREG) r3000->RTVAL = (UINT8)temp; break;
- case 0x25: /* LHU */ temp = RWORD(r3000, SIMMVAL+r3000->RSVAL); if (RTREG) r3000->RTVAL = (UINT16)temp; break;
- case 0x26: /* LWR */ (*r3000->lwr)(r3000, op); break;
- case 0x28: /* SB */ WBYTE(r3000, SIMMVAL+r3000->RSVAL, r3000->RTVAL); break;
- case 0x29: /* SH */ WWORD(r3000, SIMMVAL+r3000->RSVAL, r3000->RTVAL); break;
- case 0x2a: /* SWL */ (*r3000->swl)(r3000, op); break;
- case 0x2b: /* SW */ WLONG(r3000, SIMMVAL+r3000->RSVAL, r3000->RTVAL); break;
- case 0x2e: /* SWR */ (*r3000->swr)(r3000, op); break;
- case 0x2f: /* CACHE */ invalid_instruction(r3000, op); break;
- case 0x30: /* LL */ invalid_instruction(r3000, op); break;
- case 0x31: /* LWC1 */ set_cop1_reg(r3000, RTREG, RLONG(r3000, SIMMVAL+r3000->RSVAL)); break;
- case 0x32: /* LWC2 */ set_cop2_reg(r3000, RTREG, RLONG(r3000, SIMMVAL+r3000->RSVAL)); break;
- case 0x33: /* LWC3 */ set_cop3_reg(r3000, RTREG, RLONG(r3000, SIMMVAL+r3000->RSVAL)); break;
- case 0x34: /* LDC0 */ invalid_instruction(r3000, op); break;
- case 0x35: /* LDC1 */ invalid_instruction(r3000, op); break;
- case 0x36: /* LDC2 */ invalid_instruction(r3000, op); break;
- case 0x37: /* LDC3 */ invalid_instruction(r3000, op); break;
- case 0x38: /* SC */ invalid_instruction(r3000, op); break;
- case 0x39: /* LWC1 */ WLONG(r3000, SIMMVAL+r3000->RSVAL, get_cop1_reg(r3000, RTREG)); break;
- case 0x3a: /* LWC2 */ WLONG(r3000, SIMMVAL+r3000->RSVAL, get_cop2_reg(r3000, RTREG)); break;
- case 0x3b: /* LWC3 */ WLONG(r3000, SIMMVAL+r3000->RSVAL, get_cop3_reg(r3000, RTREG)); break;
- case 0x3c: /* SDC0 */ invalid_instruction(r3000, op); break;
- case 0x3d: /* SDC1 */ invalid_instruction(r3000, op); break;
- case 0x3e: /* SDC2 */ invalid_instruction(r3000, op); break;
- case 0x3f: /* SDC3 */ invalid_instruction(r3000, op); break;
- default: /* ??? */ invalid_instruction(r3000, op); break;
+ case 0x09: /* ADDIU */ if (RTREG) RTVAL = RSVAL + SIMMVAL; break;
+ case 0x0a: /* SLTI */ if (RTREG) RTVAL = (INT32)RSVAL < (INT32)SIMMVAL; break;
+ case 0x0b: /* SLTIU */ if (RTREG) RTVAL = (UINT32)RSVAL < (UINT32)SIMMVAL; break;
+ case 0x0c: /* ANDI */ if (RTREG) RTVAL = RSVAL & UIMMVAL; break;
+ case 0x0d: /* ORI */ if (RTREG) RTVAL = RSVAL | UIMMVAL; break;
+ case 0x0e: /* XORI */ if (RTREG) RTVAL = RSVAL ^ UIMMVAL; break;
+ case 0x0f: /* LUI */ if (RTREG) RTVAL = UIMMVAL << 16; break;
+ case 0x10: /* COP0 */ handle_cop0(); break;
+ case 0x11: /* COP1 */ handle_cop1(); break;
+ case 0x12: /* COP2 */ handle_cop2(); break;
+ case 0x13: /* COP3 */ handle_cop3(); break;
+ case 0x14: /* BEQL */ invalid_instruction(); break;
+ case 0x15: /* BNEL */ invalid_instruction(); break;
+ case 0x16: /* BLEZL */ invalid_instruction(); break;
+ case 0x17: /* BGTZL */ invalid_instruction(); break;
+ case 0x20: /* LB */ temp = RBYTE(SIMMVAL+RSVAL); if (RTREG) RTVAL = (INT8)temp; break;
+ case 0x21: /* LH */ temp = RWORD(SIMMVAL+RSVAL); if (RTREG) RTVAL = (INT16)temp; break;
+ case 0x22: /* LWL */ (*this.*m_lwl)(); break;
+ case 0x23: /* LW */ temp = RLONG(SIMMVAL+RSVAL); if (RTREG) RTVAL = temp; break;
+ case 0x24: /* LBU */ temp = RBYTE(SIMMVAL+RSVAL); if (RTREG) RTVAL = (UINT8)temp; break;
+ case 0x25: /* LHU */ temp = RWORD(SIMMVAL+RSVAL); if (RTREG) RTVAL = (UINT16)temp; break;
+ case 0x26: /* LWR */ (*this.*m_lwr)(); break;
+ case 0x28: /* SB */ WBYTE(SIMMVAL+RSVAL, RTVAL); break;
+ case 0x29: /* SH */ WWORD(SIMMVAL+RSVAL, RTVAL); break;
+ case 0x2a: /* SWL */ (*this.*m_swl)(); break;
+ case 0x2b: /* SW */ WLONG(SIMMVAL+RSVAL, RTVAL); break;
+ case 0x2e: /* SWR */ (*this.*m_swr)(); break;
+ case 0x2f: /* CACHE */ invalid_instruction(); break;
+ case 0x30: /* LL */ invalid_instruction(); break;
+ case 0x31: /* LWC1 */ set_cop1_reg(RTREG, RLONG(SIMMVAL+RSVAL)); break;
+ case 0x32: /* LWC2 */ set_cop2_reg(RTREG, RLONG(SIMMVAL+RSVAL)); break;
+ case 0x33: /* LWC3 */ set_cop3_reg(RTREG, RLONG(SIMMVAL+RSVAL)); break;
+ case 0x34: /* LDC0 */ invalid_instruction(); break;
+ case 0x35: /* LDC1 */ invalid_instruction(); break;
+ case 0x36: /* LDC2 */ invalid_instruction(); break;
+ case 0x37: /* LDC3 */ invalid_instruction(); break;
+ case 0x38: /* SC */ invalid_instruction(); break;
+ case 0x39: /* LWC1 */ WLONG(SIMMVAL+RSVAL, get_cop1_reg(RTREG)); break;
+ case 0x3a: /* LWC2 */ WLONG(SIMMVAL+RSVAL, get_cop2_reg(RTREG)); break;
+ case 0x3b: /* LWC3 */ WLONG(SIMMVAL+RSVAL, get_cop3_reg(RTREG)); break;
+ case 0x3c: /* SDC0 */ invalid_instruction(); break;
+ case 0x3d: /* SDC1 */ invalid_instruction(); break;
+ case 0x3e: /* SDC2 */ invalid_instruction(); break;
+ case 0x3f: /* SDC3 */ invalid_instruction(); break;
+ default: /* ??? */ invalid_instruction(); break;
}
- r3000->icount--;
+ m_icount--;
- } while (r3000->icount > 0 || r3000->nextpc != ~0);
+ } while (m_icount > 0 || m_nextpc != ~0);
- r3000->icount -= r3000->interrupt_cycles;
- r3000->interrupt_cycles = 0;
+ m_icount -= m_interrupt_cycles;
+ m_interrupt_cycles = 0;
}
-
-/***************************************************************************
- DISASSEMBLY HOOK
-***************************************************************************/
-
-
-/***************************************************************************
- CACHE I/O
-***************************************************************************/
-
-static UINT8 readcache_be(address_space &space, offs_t offset)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- return (offset * 4 < r3000->cache_size) ? r3000->cache[BYTE4_XOR_BE(offset)] : 0xff;
-}
-
-static UINT16 readcache_be_word(address_space &space, offs_t offset)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- return (offset * 4 < r3000->cache_size) ? *(UINT16 *)&r3000->cache[WORD_XOR_BE(offset)] : 0xffff;
-}
-
-static UINT32 readcache_be_dword(address_space &space, offs_t offset)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- return (offset * 4 < r3000->cache_size) ? *(UINT32 *)&r3000->cache[offset] : 0xffffffff;
-}
-
-static void writecache_be(address_space &space, offs_t offset, UINT8 data)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- if (offset * 4 < r3000->cache_size) r3000->cache[BYTE4_XOR_BE(offset)] = data;
-}
-
-static void writecache_be_word(address_space &space, offs_t offset, UINT16 data)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- if (offset * 4 < r3000->cache_size) *(UINT16 *)&r3000->cache[WORD_XOR_BE(offset)] = data;
-}
-
-static void writecache_be_dword(address_space &space, offs_t offset, UINT32 data)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- if (offset * 4 < r3000->cache_size) *(UINT32 *)&r3000->cache[offset] = data;
-}
-
-static UINT8 readcache_le(address_space &space, offs_t offset)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- return (offset * 4 < r3000->cache_size) ? r3000->cache[BYTE4_XOR_LE(offset)] : 0xff;
-}
-
-static UINT16 readcache_le_word(address_space &space, offs_t offset)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- return (offset * 4 < r3000->cache_size) ? *(UINT16 *)&r3000->cache[WORD_XOR_LE(offset)] : 0xffff;
-}
-
-static UINT32 readcache_le_dword(address_space &space, offs_t offset)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- return (offset * 4 < r3000->cache_size) ? *(UINT32 *)&r3000->cache[offset] : 0xffffffff;
-}
-
-static void writecache_le(address_space &space, offs_t offset, UINT8 data)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- if (offset * 4 < r3000->cache_size) r3000->cache[BYTE4_XOR_LE(offset)] = data;
-}
-
-static void writecache_le_word(address_space &space, offs_t offset, UINT16 data)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- if (offset * 4 < r3000->cache_size) *(UINT16 *)&r3000->cache[WORD_XOR_LE(offset)] = data;
-}
-
-static void writecache_le_dword(address_space &space, offs_t offset, UINT32 data)
-{
- r3000_state *r3000 = get_safe_token(&space.device());
- offset &= 0x1fffffff;
- if (offset * 4 < r3000->cache_size) *(UINT32 *)&r3000->cache[offset] = data;
-}
-
-
-
/***************************************************************************
COMPLEX OPCODE IMPLEMENTATIONS
***************************************************************************/
-static void lwl_be(r3000_state *r3000, UINT32 op)
+void r3000_device::lwl_be()
{
- offs_t offs = SIMMVAL + r3000->RSVAL;
- UINT32 temp = RLONG(r3000, offs & ~3);
+ offs_t offs = SIMMVAL + RSVAL;
+ UINT32 temp = RLONG(offs & ~3);
if (RTREG)
{
- if (!(offs & 3)) r3000->RTVAL = temp;
+ if (!(offs & 3)) RTVAL = temp;
else
{
int shift = 8 * (offs & 3);
- r3000->RTVAL = (r3000->RTVAL & (0x00ffffff >> (24 - shift))) | (temp << shift);
+ RTVAL = (RTVAL & (0x00ffffff >> (24 - shift))) | (temp << shift);
}
}
}
-static void lwr_be(r3000_state *r3000, UINT32 op)
+void r3000_device::lwr_be()
{
- offs_t offs = SIMMVAL + r3000->RSVAL;
- UINT32 temp = RLONG(r3000, offs & ~3);
+ offs_t offs = SIMMVAL + RSVAL;
+ UINT32 temp = RLONG(offs & ~3);
if (RTREG)
{
- if ((offs & 3) == 3) r3000->RTVAL = temp;
+ if ((offs & 3) == 3) RTVAL = temp;
else
{
int shift = 8 * (offs & 3);
- r3000->RTVAL = (r3000->RTVAL & (0xffffff00 << shift)) | (temp >> (24 - shift));
+ RTVAL = (RTVAL & (0xffffff00 << shift)) | (temp >> (24 - shift));
}
}
}
-static void swl_be(r3000_state *r3000, UINT32 op)
+void r3000_device::swl_be()
{
- offs_t offs = SIMMVAL + r3000->RSVAL;
- if (!(offs & 3)) WLONG(r3000, offs, r3000->RTVAL);
+ offs_t offs = SIMMVAL + RSVAL;
+ if (!(offs & 3)) WLONG(offs, RTVAL);
else
{
- UINT32 temp = RLONG(r3000, offs & ~3);
+ UINT32 temp = RLONG(offs & ~3);
int shift = 8 * (offs & 3);
- WLONG(r3000, offs & ~3, (temp & (0xffffff00 << (24 - shift))) | (r3000->RTVAL >> shift));
+ WLONG(offs & ~3, (temp & (0xffffff00 << (24 - shift))) | (RTVAL >> shift));
}
}
-static void swr_be(r3000_state *r3000, UINT32 op)
+void r3000_device::swr_be()
{
- offs_t offs = SIMMVAL + r3000->RSVAL;
- if ((offs & 3) == 3) WLONG(r3000, offs & ~3, r3000->RTVAL);
+ offs_t offs = SIMMVAL + RSVAL;
+ if ((offs & 3) == 3) WLONG(offs & ~3, RTVAL);
else
{
- UINT32 temp = RLONG(r3000, offs & ~3);
+ UINT32 temp = RLONG(offs & ~3);
int shift = 8 * (offs & 3);
- WLONG(r3000, offs & ~3, (temp & (0x00ffffff >> shift)) | (r3000->RTVAL << (24 - shift)));
+ WLONG(offs & ~3, (temp & (0x00ffffff >> shift)) | (RTVAL << (24 - shift)));
}
}
-static void lwl_le(r3000_state *r3000, UINT32 op)
+void r3000_device::lwl_le()
{
- offs_t offs = SIMMVAL + r3000->RSVAL;
- UINT32 temp = RLONG(r3000, offs & ~3);
+ offs_t offs = SIMMVAL + RSVAL;
+ UINT32 temp = RLONG(offs & ~3);
if (RTREG)
{
- if (!(offs & 3)) r3000->RTVAL = temp;
+ if (!(offs & 3)) RTVAL = temp;
else
{
int shift = 8 * (offs & 3);
- r3000->RTVAL = (r3000->RTVAL & (0xffffff00 << (24 - shift))) | (temp >> shift);
+ RTVAL = (RTVAL & (0xffffff00 << (24 - shift))) | (temp >> shift);
}
}
}
-static void lwr_le(r3000_state *r3000, UINT32 op)
+void r3000_device::lwr_le()
{
- offs_t offs = SIMMVAL + r3000->RSVAL;
- UINT32 temp = RLONG(r3000, offs & ~3);
+ offs_t offs = SIMMVAL + RSVAL;
+ UINT32 temp = RLONG(offs & ~3);
if (RTREG)
{
- if ((offs & 3) == 3) r3000->RTVAL = temp;
+ if ((offs & 3) == 3) RTVAL = temp;
else
{
int shift = 8 * (offs & 3);
- r3000->RTVAL = (r3000->RTVAL & (0x00ffffff >> shift)) | (temp << (24 - shift));
+ RTVAL = (RTVAL & (0x00ffffff >> shift)) | (temp << (24 - shift));
}
}
}
-static void swl_le(r3000_state *r3000, UINT32 op)
+void r3000_device::swl_le()
{
- offs_t offs = SIMMVAL + r3000->RSVAL;
- if (!(offs & 3)) WLONG(r3000, offs, r3000->RTVAL);
+ offs_t offs = SIMMVAL + RSVAL;
+ if (!(offs & 3)) WLONG(offs, RTVAL);
else
{
- UINT32 temp = RLONG(r3000, offs & ~3);
+ UINT32 temp = RLONG(offs & ~3);
int shift = 8 * (offs & 3);
- WLONG(r3000, offs & ~3, (temp & (0x00ffffff >> (24 - shift))) | (r3000->RTVAL << shift));
+ WLONG(offs & ~3, (temp & (0x00ffffff >> (24 - shift))) | (RTVAL << shift));
}
}
-static void swr_le(r3000_state *r3000, UINT32 op)
+void r3000_device::swr_le()
{
- offs_t offs = SIMMVAL + r3000->RSVAL;
- if ((offs & 3) == 3) WLONG(r3000, offs & ~3, r3000->RTVAL);
+ offs_t offs = SIMMVAL + RSVAL;
+ if ((offs & 3) == 3) WLONG(offs & ~3, RTVAL);
else
{
- UINT32 temp = RLONG(r3000, offs & ~3);
+ UINT32 temp = RLONG(offs & ~3);
int shift = 8 * (offs & 3);
- WLONG(r3000, offs & ~3, (temp & (0xffffff00 << shift)) | (r3000->RTVAL >> (24 - shift)));
- }
-}
-
-
-
-/**************************************************************************
- * Generic set_info
- **************************************************************************/
-
-static CPU_SET_INFO( r3000 )
-{
- r3000_state *r3000 = get_safe_token(device);
- switch (state)
- {
- /* --- the following bits of info are set as 64-bit signed integers --- */
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ0: set_irq_line(r3000, R3000_IRQ0, info->i); break;
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ1: set_irq_line(r3000, R3000_IRQ1, info->i); break;
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ2: set_irq_line(r3000, R3000_IRQ2, info->i); break;
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ3: set_irq_line(r3000, R3000_IRQ3, info->i); break;
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ4: set_irq_line(r3000, R3000_IRQ4, info->i); break;
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ5: set_irq_line(r3000, R3000_IRQ5, info->i); break;
-
- case CPUINFO_INT_PC:
- case CPUINFO_INT_REGISTER + R3000_PC: r3000->pc = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_SR: r3000->SR = info->i; break;
-
- case CPUINFO_INT_REGISTER + R3000_R0: r3000->r[0] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R1: r3000->r[1] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R2: r3000->r[2] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R3: r3000->r[3] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R4: r3000->r[4] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R5: r3000->r[5] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R6: r3000->r[6] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R7: r3000->r[7] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R8: r3000->r[8] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R9: r3000->r[9] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R10: r3000->r[10] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R11: r3000->r[11] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R12: r3000->r[12] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R13: r3000->r[13] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R14: r3000->r[14] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R15: r3000->r[15] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R16: r3000->r[16] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R17: r3000->r[17] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R18: r3000->r[18] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R19: r3000->r[19] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R20: r3000->r[20] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R21: r3000->r[21] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R22: r3000->r[22] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R23: r3000->r[23] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R24: r3000->r[24] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R25: r3000->r[25] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R26: r3000->r[26] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R27: r3000->r[27] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R28: r3000->r[28] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R29: r3000->r[29] = info->i; break;
- case CPUINFO_INT_REGISTER + R3000_R30: r3000->r[30] = info->i; break;
- case CPUINFO_INT_SP:
- case CPUINFO_INT_REGISTER + R3000_R31: r3000->r[31] = info->i; break;
- }
-}
-
-
-
-/**************************************************************************
- * Generic get_info
- **************************************************************************/
-
-static CPU_GET_INFO( r3000 )
-{
- r3000_state *r3000 = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
- switch (state)
- {
- /* --- the following bits of info are returned as 64-bit signed integers --- */
- case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(r3000_state); break;
- case CPUINFO_INT_INPUT_LINES: info->i = 6; break;
- case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
- case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break;
- case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
- case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
- case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 4; break;
- case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break;
- case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
- case CPUINFO_INT_MAX_CYCLES: info->i = 40; break;
-
- case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 32; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 29; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break;
-
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ0: info->i = (r3000->cpr[0][COP0_Cause] & 0x400) ? ASSERT_LINE : CLEAR_LINE; break;
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ1: info->i = (r3000->cpr[0][COP0_Cause] & 0x800) ? ASSERT_LINE : CLEAR_LINE; break;
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ2: info->i = (r3000->cpr[0][COP0_Cause] & 0x1000) ? ASSERT_LINE : CLEAR_LINE; break;
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ3: info->i = (r3000->cpr[0][COP0_Cause] & 0x2000) ? ASSERT_LINE : CLEAR_LINE; break;
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ4: info->i = (r3000->cpr[0][COP0_Cause] & 0x4000) ? ASSERT_LINE : CLEAR_LINE; break;
- case CPUINFO_INT_INPUT_STATE + R3000_IRQ5: info->i = (r3000->cpr[0][COP0_Cause] & 0x8000) ? ASSERT_LINE : CLEAR_LINE; break;
-
- case CPUINFO_INT_PREVIOUSPC: info->i = r3000->ppc; break;
-
- case CPUINFO_INT_PC: info->i = r3000->pc & 0x1fffffff; break;
- case CPUINFO_INT_REGISTER + R3000_PC: info->i = r3000->pc; break;
- case CPUINFO_INT_REGISTER + R3000_SR: info->i = r3000->SR; break;
-
- case CPUINFO_INT_REGISTER + R3000_R0: info->i = r3000->r[0]; break;
- case CPUINFO_INT_REGISTER + R3000_R1: info->i = r3000->r[1]; break;
- case CPUINFO_INT_REGISTER + R3000_R2: info->i = r3000->r[2]; break;
- case CPUINFO_INT_REGISTER + R3000_R3: info->i = r3000->r[3]; break;
- case CPUINFO_INT_REGISTER + R3000_R4: info->i = r3000->r[4]; break;
- case CPUINFO_INT_REGISTER + R3000_R5: info->i = r3000->r[5]; break;
- case CPUINFO_INT_REGISTER + R3000_R6: info->i = r3000->r[6]; break;
- case CPUINFO_INT_REGISTER + R3000_R7: info->i = r3000->r[7]; break;
- case CPUINFO_INT_REGISTER + R3000_R8: info->i = r3000->r[8]; break;
- case CPUINFO_INT_REGISTER + R3000_R9: info->i = r3000->r[9]; break;
- case CPUINFO_INT_REGISTER + R3000_R10: info->i = r3000->r[10]; break;
- case CPUINFO_INT_REGISTER + R3000_R11: info->i = r3000->r[11]; break;
- case CPUINFO_INT_REGISTER + R3000_R12: info->i = r3000->r[12]; break;
- case CPUINFO_INT_REGISTER + R3000_R13: info->i = r3000->r[13]; break;
- case CPUINFO_INT_REGISTER + R3000_R14: info->i = r3000->r[14]; break;
- case CPUINFO_INT_REGISTER + R3000_R15: info->i = r3000->r[15]; break;
- case CPUINFO_INT_REGISTER + R3000_R16: info->i = r3000->r[16]; break;
- case CPUINFO_INT_REGISTER + R3000_R17: info->i = r3000->r[17]; break;
- case CPUINFO_INT_REGISTER + R3000_R18: info->i = r3000->r[18]; break;
- case CPUINFO_INT_REGISTER + R3000_R19: info->i = r3000->r[19]; break;
- case CPUINFO_INT_REGISTER + R3000_R20: info->i = r3000->r[20]; break;
- case CPUINFO_INT_REGISTER + R3000_R21: info->i = r3000->r[21]; break;
- case CPUINFO_INT_REGISTER + R3000_R22: info->i = r3000->r[22]; break;
- case CPUINFO_INT_REGISTER + R3000_R23: info->i = r3000->r[23]; break;
- case CPUINFO_INT_REGISTER + R3000_R24: info->i = r3000->r[24]; break;
- case CPUINFO_INT_REGISTER + R3000_R25: info->i = r3000->r[25]; break;
- case CPUINFO_INT_REGISTER + R3000_R26: info->i = r3000->r[26]; break;
- case CPUINFO_INT_REGISTER + R3000_R27: info->i = r3000->r[27]; break;
- case CPUINFO_INT_REGISTER + R3000_R28: info->i = r3000->r[28]; break;
- case CPUINFO_INT_REGISTER + R3000_R29: info->i = r3000->r[29]; break;
- case CPUINFO_INT_REGISTER + R3000_R30: info->i = r3000->r[30]; break;
- case CPUINFO_INT_SP: info->i = r3000->r[31] & 0x1fffffff; break;
- case CPUINFO_INT_REGISTER + R3000_R31: info->i = r3000->r[31]; break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(r3000); break;
- case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(r3000); break;
- case CPUINFO_FCT_RESET: /* provided per-CPU */ break;
- case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(r3000); break;
- case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(r3000); break;
- case CPUINFO_FCT_BURN: info->burn = NULL; break;
- case CPUINFO_FCT_DISASSEMBLE: /* provided per-CPU */ break;
- case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &r3000->icount; break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "R3000"); break;
- case CPUINFO_STR_FAMILY: strcpy(info->s, "MIPS II"); break;
- case CPUINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
- case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
- case CPUINFO_STR_CREDITS: strcpy(info->s, "Copyright Aaron Giles"); break;
-
- case CPUINFO_STR_FLAGS: strcpy(info->s, " "); break;
-
- case CPUINFO_STR_REGISTER + R3000_PC: sprintf(info->s, "PC: %08X", r3000->pc); break;
- case CPUINFO_STR_REGISTER + R3000_SR: sprintf(info->s, "SR: %08X", r3000->SR); break;
-
- case CPUINFO_STR_REGISTER + R3000_R0: sprintf(info->s, "R0: %08X", r3000->r[0]); break;
- case CPUINFO_STR_REGISTER + R3000_R1: sprintf(info->s, "R1: %08X", r3000->r[1]); break;
- case CPUINFO_STR_REGISTER + R3000_R2: sprintf(info->s, "R2: %08X", r3000->r[2]); break;
- case CPUINFO_STR_REGISTER + R3000_R3: sprintf(info->s, "R3: %08X", r3000->r[3]); break;
- case CPUINFO_STR_REGISTER + R3000_R4: sprintf(info->s, "R4: %08X", r3000->r[4]); break;
- case CPUINFO_STR_REGISTER + R3000_R5: sprintf(info->s, "R5: %08X", r3000->r[5]); break;
- case CPUINFO_STR_REGISTER + R3000_R6: sprintf(info->s, "R6: %08X", r3000->r[6]); break;
- case CPUINFO_STR_REGISTER + R3000_R7: sprintf(info->s, "R7: %08X", r3000->r[7]); break;
- case CPUINFO_STR_REGISTER + R3000_R8: sprintf(info->s, "R8: %08X", r3000->r[8]); break;
- case CPUINFO_STR_REGISTER + R3000_R9: sprintf(info->s, "R9: %08X", r3000->r[9]); break;
- case CPUINFO_STR_REGISTER + R3000_R10: sprintf(info->s, "R10:%08X", r3000->r[10]); break;
- case CPUINFO_STR_REGISTER + R3000_R11: sprintf(info->s, "R11:%08X", r3000->r[11]); break;
- case CPUINFO_STR_REGISTER + R3000_R12: sprintf(info->s, "R12:%08X", r3000->r[12]); break;
- case CPUINFO_STR_REGISTER + R3000_R13: sprintf(info->s, "R13:%08X", r3000->r[13]); break;
- case CPUINFO_STR_REGISTER + R3000_R14: sprintf(info->s, "R14:%08X", r3000->r[14]); break;
- case CPUINFO_STR_REGISTER + R3000_R15: sprintf(info->s, "R15:%08X", r3000->r[15]); break;
- case CPUINFO_STR_REGISTER + R3000_R16: sprintf(info->s, "R16:%08X", r3000->r[16]); break;
- case CPUINFO_STR_REGISTER + R3000_R17: sprintf(info->s, "R17:%08X", r3000->r[17]); break;
- case CPUINFO_STR_REGISTER + R3000_R18: sprintf(info->s, "R18:%08X", r3000->r[18]); break;
- case CPUINFO_STR_REGISTER + R3000_R19: sprintf(info->s, "R19:%08X", r3000->r[19]); break;
- case CPUINFO_STR_REGISTER + R3000_R20: sprintf(info->s, "R20:%08X", r3000->r[20]); break;
- case CPUINFO_STR_REGISTER + R3000_R21: sprintf(info->s, "R21:%08X", r3000->r[21]); break;
- case CPUINFO_STR_REGISTER + R3000_R22: sprintf(info->s, "R22:%08X", r3000->r[22]); break;
- case CPUINFO_STR_REGISTER + R3000_R23: sprintf(info->s, "R23:%08X", r3000->r[23]); break;
- case CPUINFO_STR_REGISTER + R3000_R24: sprintf(info->s, "R24:%08X", r3000->r[24]); break;
- case CPUINFO_STR_REGISTER + R3000_R25: sprintf(info->s, "R25:%08X", r3000->r[25]); break;
- case CPUINFO_STR_REGISTER + R3000_R26: sprintf(info->s, "R26:%08X", r3000->r[26]); break;
- case CPUINFO_STR_REGISTER + R3000_R27: sprintf(info->s, "R27:%08X", r3000->r[27]); break;
- case CPUINFO_STR_REGISTER + R3000_R28: sprintf(info->s, "R28:%08X", r3000->r[28]); break;
- case CPUINFO_STR_REGISTER + R3000_R29: sprintf(info->s, "R29:%08X", r3000->r[29]); break;
- case CPUINFO_STR_REGISTER + R3000_R30: sprintf(info->s, "R30:%08X", r3000->r[30]); break;
- case CPUINFO_STR_REGISTER + R3000_R31: sprintf(info->s, "R31:%08X", r3000->r[31]); break;
- }
-}
-
-
-/**************************************************************************
- * CPU-specific set_info
- **************************************************************************/
-
-CPU_GET_INFO( r3000be )
-{
- switch (state)
- {
- /* --- the following bits of info are returned as 64-bit signed integers --- */
- case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(r3000be); break;
- case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(r3000be); break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "R3000 (big)"); break;
-
- default: CPU_GET_INFO_CALL(r3000); break;
- }
-}
-
-
-CPU_GET_INFO( r3000le )
-{
- switch (state)
- {
- /* --- the following bits of info are returned as 64-bit signed integers --- */
- case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(r3000le); break;
- case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(r3000le); break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "R3000 (little)"); break;
-
- default: CPU_GET_INFO_CALL(r3000); break;
- }
-}
-
-
-CPU_GET_INFO( r3041be )
-{
- switch (state)
- {
- /* --- the following bits of info are returned as 64-bit signed integers --- */
- case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(r3000be); break;
- case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(r3000be); break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "R3041 (big)"); break;
-
- default: CPU_GET_INFO_CALL(r3000); break;
+ WLONG(offs & ~3, (temp & (0xffffff00 << shift)) | (RTVAL >> (24 - shift)));
}
}
-
-
-CPU_GET_INFO( r3041le )
-{
- switch (state)
- {
- /* --- the following bits of info are returned as 64-bit signed integers --- */
- case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(r3000le); break;
- case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(r3000le); break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "R3041 (little)"); break;
-
- default: CPU_GET_INFO_CALL(r3000); break;
- }
-}
-
-DEFINE_LEGACY_CPU_DEVICE(R3000BE, r3000be);
-DEFINE_LEGACY_CPU_DEVICE(R3000LE, r3000le);
-
-DEFINE_LEGACY_CPU_DEVICE(R3041BE, r3041be);
-DEFINE_LEGACY_CPU_DEVICE(R3041LE, r3041le);
diff --git a/src/emu/cpu/mips/r3000.h b/src/emu/cpu/mips/r3000.h
index 6163a2bdb82..af2785b308a 100644
--- a/src/emu/cpu/mips/r3000.h
+++ b/src/emu/cpu/mips/r3000.h
@@ -10,10 +10,24 @@
#define __R3000_H__
-
/***************************************************************************
- COMPILE-TIME DEFINITIONS
+ INTERFACE CONFIGURATION MACROS
***************************************************************************/
+
+#define MCFG_R3000_ENDIANNESS(_endianness) \
+ r3000_device::static_set_endianness(*device, _endianness);
+
+#define MCFG_R3000_BRCOND0_INPUT(_devcb) \
+ devcb = &r3000_device::static_set_brcond0_input(*device, DEVCB2_##_devcb);
+
+#define MCFG_R3000_BRCOND1_INPUT(_devcb) \
+ devcb = &r3000_device::static_set_brcond1_input(*device, DEVCB2_##_devcb);
+
+#define MCFG_R3000_BRCOND2_INPUT(_devcb) \
+ devcb = &r3000_device::static_set_brcond2_input(*device, DEVCB2_##_devcb);
+
+#define MCFG_R3000_BRCOND3_INPUT(_devcb) \
+ devcb = &r3000_device::static_set_brcond3_input(*device, DEVCB2_##_devcb);
/***************************************************************************
@@ -42,26 +56,262 @@ enum
#define R3000_IRQ5 5 /* IRQ5 */
-/***************************************************************************
- STRUCTURES
-***************************************************************************/
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
-struct r3000_cpu_core
+// ======================> r3000_device
+
+class r3000_device : public cpu_device
{
- UINT8 hasfpu; /* 1 if we have an FPU, 0 otherwise */
- size_t icache; /* code cache size */
- size_t dcache; /* data cache size */
+protected:
+ enum chip_type
+ {
+ CHIP_TYPE_R3041,
+ CHIP_TYPE_R3051,
+ CHIP_TYPE_R3052,
+ CHIP_TYPE_R3071,
+ CHIP_TYPE_R3081,
+ };
+
+ // construction/destruction
+ r3000_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, chip_type chiptype);
+ virtual ~r3000_device();
+
+public:
+ // inline configuration helpers
+ static void static_set_endianness(device_t &device, endianness_t endianness)
+ {
+ downcast<r3000_device &>(device).m_endianness = endianness;
+ }
+
+ template<class _Object> static devcb2_base &static_set_brcond0_input(device_t &device, _Object object)
+ {
+ return downcast<r3000_device &>(device).m_in_brcond0.set_callback(object);
+ }
+
+ template<class _Object> static devcb2_base &static_set_brcond1_input(device_t &device, _Object object)
+ {
+ return downcast<r3000_device &>(device).m_in_brcond1.set_callback(object);
+ }
+
+ template<class _Object> static devcb2_base &static_set_brcond2_input(device_t &device, _Object object)
+ {
+ return downcast<r3000_device &>(device).m_in_brcond2.set_callback(object);
+ }
+
+ template<class _Object> static devcb2_base &static_set_brcond3_input(device_t &device, _Object object)
+ {
+ return downcast<r3000_device &>(device).m_in_brcond3.set_callback(object);
+ }
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+ virtual void device_post_load();
+
+ // device_execute_interface overrides
+ virtual UINT32 execute_min_cycles() const;
+ virtual UINT32 execute_max_cycles() const;
+ virtual UINT32 execute_input_lines() const;
+ virtual void execute_run();
+ virtual void execute_set_input(int inputnum, int state);
+
+ // device_memory_interface overrides
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
+
+ // device_state_interface overrides
+ virtual void state_import(const device_state_entry &entry);
+ virtual void state_export(const device_state_entry &entry);
+ virtual void state_string_export(const device_state_entry &entry, astring &string);
+
+ // device_disasm_interface overrides
+ virtual UINT32 disasm_min_opcode_bytes() const;
+ virtual UINT32 disasm_max_opcode_bytes() const;
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+ // memory accessors
+ struct r3000_data_accessors
+ {
+ UINT8 (r3000_device::*m_read_byte)(offs_t byteaddress);
+ UINT16 (r3000_device::*m_read_word)(offs_t byteaddress);
+ UINT32 (r3000_device::*m_read_dword)(offs_t byteaddress);
+ void (r3000_device::*m_write_byte)(offs_t byteaddress, UINT8 data);
+ void (r3000_device::*m_write_word)(offs_t byteaddress, UINT16 data);
+ void (r3000_device::*m_write_dword)(offs_t byteaddress, UINT32 data);
+ };
+
+ UINT32 readop(off_t pc);
+ UINT8 readmem(offs_t offset);
+ UINT16 readmem_word(offs_t offset);
+ UINT32 readmem_dword(offs_t offset);
+ void writemem(offs_t offset, UINT8 data);
+ void writemem_word(offs_t offset, UINT16 data);
+ void writemem_dword(offs_t offset, UINT32 data);
+
+ UINT8 readcache_be(offs_t offset);
+ UINT16 readcache_be_word(offs_t offset);
+ UINT32 readcache_be_dword(offs_t offset);
+ void writecache_be(offs_t offset, UINT8 data);
+ void writecache_be_word(offs_t offset, UINT16 data);
+ void writecache_be_dword(offs_t offset, UINT32 data);
+
+ UINT8 readcache_le(offs_t offset);
+ UINT16 readcache_le_word(offs_t offset);
+ UINT32 readcache_le_dword(offs_t offset);
+ void writecache_le(offs_t offset, UINT8 data);
+ void writecache_le_word(offs_t offset, UINT16 data);
+ void writecache_le_dword(offs_t offset, UINT32 data);
+
+ // interrupts
+ void generate_exception(int exception);
+ void check_irqs();
+ void set_irq_line(int irqline, int state);
+ void invalid_instruction();
+
+ // instructions
+ UINT32 get_cop0_reg(int idx);
+ void set_cop0_reg(int idx, UINT32 val);
+ UINT32 get_cop0_creg(int idx);
+ void set_cop0_creg(int idx, UINT32 val);
+ void handle_cop0();
+
+ UINT32 get_cop1_reg(int idx);
+ void set_cop1_reg(int idx, UINT32 val);
+ UINT32 get_cop1_creg(int idx);
+ void set_cop1_creg(int idx, UINT32 val);
+ void handle_cop1();
+
+ UINT32 get_cop2_reg(int idx);
+ void set_cop2_reg(int idx, UINT32 val);
+ UINT32 get_cop2_creg(int idx);
+ void set_cop2_creg(int idx, UINT32 val);
+ void handle_cop2();
+
+ UINT32 get_cop3_reg(int idx);
+ void set_cop3_reg(int idx, UINT32 val);
+ UINT32 get_cop3_creg(int idx);
+ void set_cop3_creg(int idx, UINT32 val);
+ void handle_cop3();
+
+ // complex opcodes
+ void lwl_be();
+ void lwr_be();
+ void swl_be();
+ void swr_be();
+
+ void lwl_le();
+ void lwr_le();
+ void swl_le();
+ void swr_le();
+
+ // address spaces
+ const address_space_config m_program_config_be;
+ const address_space_config m_program_config_le;
+ address_space *m_program;
+ direct_read_data *m_direct;
+
+ // configuration
+ chip_type m_chip_type;
+ bool m_hasfpu;
+ endianness_t m_endianness;
+
+ // core registers
+ UINT32 m_pc;
+ UINT32 m_nextpc;
+ UINT32 m_hi;
+ UINT32 m_lo;
+ UINT32 m_r[32];
+
+ // COP registers
+ UINT32 m_cpr[4][32];
+ UINT32 m_ccr[4][32];
+
+ // internal stuff
+ UINT32 m_ppc;
+ UINT32 m_op;
+ int m_icount;
+ int m_interrupt_cycles;
+
+ // endian-dependent load/store
+ void (r3000_device::*m_lwl)();
+ void (r3000_device::*m_lwr)();
+ void (r3000_device::*m_swl)();
+ void (r3000_device::*m_swr)();
+
+ // memory accesses
+ r3000_data_accessors *m_cur;
+ r3000_data_accessors m_memory_hand;
+ r3000_data_accessors m_cache_hand;
+
+ // cache memory
+ UINT32 * m_cache;
+ UINT32 * m_icache;
+ UINT32 * m_dcache;
+ size_t m_cache_size;
+ size_t m_icache_size;
+ size_t m_dcache_size;
+
+ // I/O
+ devcb2_read_line m_in_brcond0;
+ devcb2_read_line m_in_brcond1;
+ devcb2_read_line m_in_brcond2;
+ devcb2_read_line m_in_brcond3;
};
-/***************************************************************************
- PUBLIC FUNCTIONS
-***************************************************************************/
+// ======================> r3041_device
+
+class r3041_device : public r3000_device
+{
+public:
+ r3041_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+// ======================> r3051_device
+
+class r3051_device : public r3000_device
+{
+public:
+ r3051_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+// ======================> r3052_device
+
+class r3052_device : public r3000_device
+{
+public:
+ r3052_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+// ======================> r3071_device
+
+class r3071_device : public r3000_device
+{
+public:
+ r3071_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+// ======================> r3081_device
+
+class r3081_device : public r3000_device
+{
+public:
+ r3081_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
-DECLARE_LEGACY_CPU_DEVICE(R3000BE, r3000be);
-DECLARE_LEGACY_CPU_DEVICE(R3000LE, r3000le);
+// device type definition
-DECLARE_LEGACY_CPU_DEVICE(R3041BE, r3041be);
-DECLARE_LEGACY_CPU_DEVICE(R3041LE, r3041le);
+extern const device_type R3041;
+extern const device_type R3051;
+extern const device_type R3052;
+extern const device_type R3071;
+extern const device_type R3081;
#endif /* __R3000_H__ */
diff --git a/src/mame/drivers/jaguar.c b/src/mame/drivers/jaguar.c
index 5579fe7419a..c4b46cb61b7 100644
--- a/src/mame/drivers/jaguar.c
+++ b/src/mame/drivers/jaguar.c
@@ -1545,15 +1545,7 @@ INPUT_PORTS_END
*
*************************************/
-static const r3000_cpu_core r3000_config =
-{
- 0, /* 1 if we have an FPU, 0 otherwise */
- 4096, /* code cache size */
- 4096 /* data cache size */
-};
-
-
-static const jaguar_cpu_config gpu_config =
+ static const jaguar_cpu_config gpu_config =
{
&jaguar_state::gpu_cpu_int
};
@@ -1567,8 +1559,8 @@ static const jaguar_cpu_config dsp_config =
static MACHINE_CONFIG_START( cojagr3k, jaguar_state )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", R3041BE, R3000_CLOCK)
- MCFG_CPU_CONFIG(r3000_config)
+ MCFG_CPU_ADD("maincpu", R3041, R3000_CLOCK)
+ MCFG_R3000_ENDIANNESS(ENDIANNESS_BIG)
MCFG_CPU_PROGRAM_MAP(r3000_map)
MCFG_CPU_ADD("gpu", JAGUARGPU, COJAG_CLOCK/2)
@@ -2263,7 +2255,7 @@ void jaguar_state::cojag_common_init(UINT16 gpu_jump_offs, UINT16 spin_pc)
m_is_cojag = true;
/* copy over the ROM */
- m_is_r3000 = (m_main_cpu->type() == R3041BE);
+ m_is_r3000 = (m_main_cpu->type() == R3041);
/* install synchronization hooks for GPU */
if (m_is_r3000)
diff --git a/src/mame/drivers/policetr.c b/src/mame/drivers/policetr.c
index eace70c09ab..d1d772b33ee 100644
--- a/src/mame/drivers/policetr.c
+++ b/src/mame/drivers/policetr.c
@@ -402,19 +402,11 @@ INPUT_PORTS_END
*
*************************************/
-static const r3000_cpu_core r3000_config =
-{
- 0, /* 1 if we have an FPU, 0 otherwise */
- 4096, /* code cache size */
- 4096 /* data cache size */
-};
-
-
static MACHINE_CONFIG_START( policetr, policetr_state )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", R3000BE, MASTER_CLOCK/2)
- MCFG_CPU_CONFIG(r3000_config)
+ MCFG_CPU_ADD("maincpu", R3041, MASTER_CLOCK/2)
+ MCFG_R3000_ENDIANNESS(ENDIANNESS_BIG)
MCFG_CPU_PROGRAM_MAP(policetr_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", policetr_state, irq4_gen)
diff --git a/src/mame/drivers/speglsht.c b/src/mame/drivers/speglsht.c
index 402cbce49ed..65ca007c079 100644
--- a/src/mame/drivers/speglsht.c
+++ b/src/mame/drivers/speglsht.c
@@ -326,13 +326,6 @@ static const st0016_interface st0016_config =
&st0016_charram
};
-static const r3000_cpu_core r3000_config =
-{
- 0,
- 4096, /* code cache size */
- 2048 /* data cache size */
-};
-
MACHINE_RESET_MEMBER(speglsht_state,speglsht)
{
memset(m_shared,0,0x1000);
@@ -393,8 +386,8 @@ static MACHINE_CONFIG_START( speglsht, speglsht_state )
MCFG_CPU_VBLANK_INT_DRIVER("screen", speglsht_state, irq0_line_hold)
- MCFG_CPU_ADD("sub", R3000LE, 25000000)
- MCFG_CPU_CONFIG(r3000_config)
+ MCFG_CPU_ADD("sub", R3051, 25000000)
+ MCFG_R3000_ENDIANNESS(ENDIANNESS_LITTLE)
MCFG_CPU_PROGRAM_MAP(speglsht_mem)
MCFG_CPU_VBLANK_INT_DRIVER("screen", speglsht_state, irq4_line_assert)
diff --git a/src/mame/drivers/srmp5.c b/src/mame/drivers/srmp5.c
index e56bfb573c8..3ea157bd03d 100644
--- a/src/mame/drivers/srmp5.c
+++ b/src/mame/drivers/srmp5.c
@@ -501,13 +501,6 @@ static const st0016_interface st0016_config =
&st0016_charram
};
-static const r3000_cpu_core r3000_config =
-{
- 1, /* 1 if we have an FPU, 0 otherwise */
- 4096, /* code cache size */
- 4096 /* data cache size */
-};
-
static const gfx_layout tile_16x8x8_layout =
{
16,8,
@@ -545,8 +538,8 @@ static MACHINE_CONFIG_START( srmp5, srmp5_state )
MCFG_CPU_IO_MAP(st0016_io)
MCFG_CPU_VBLANK_INT_DRIVER("screen", srmp5_state, irq0_line_hold)
- MCFG_CPU_ADD("sub", R3000LE, 25000000)
- MCFG_CPU_CONFIG(r3000_config)
+ MCFG_CPU_ADD("sub", R3051, 25000000)
+ MCFG_R3000_ENDIANNESS(ENDIANNESS_LITTLE)
MCFG_CPU_PROGRAM_MAP(srmp5_mem)
MCFG_CPU_VBLANK_INT_DRIVER("screen", srmp5_state, irq4_line_assert)
diff --git a/src/mame/drivers/turrett.c b/src/mame/drivers/turrett.c
index 529d9feab97..8467bb4a3ce 100644
--- a/src/mame/drivers/turrett.c
+++ b/src/mame/drivers/turrett.c
@@ -115,19 +115,12 @@ static INPUT_PORTS_START( turrett )
INPUT_PORTS_END
-static const r3000_cpu_core r3000_config =
-{
- 0, /* 1 if we have an FPU, 0 otherwise */
- 2048, /* code cache size */
- 512 /* data cache size */
-};
-
static MACHINE_CONFIG_START( turrett, turrett_state )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", R3041BE, R3041_CLOCK)
+ MCFG_CPU_ADD("maincpu", R3041, R3041_CLOCK)
+ MCFG_R3000_ENDIANNESS(ENDIANNESS_BIG)
MCFG_CPU_PROGRAM_MAP(cpu_map)
- MCFG_CPU_CONFIG(r3000_config)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)