summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/mips/r3000.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/mips/r3000.h')
-rw-r--r--src/devices/cpu/mips/r3000.h319
1 files changed, 319 insertions, 0 deletions
diff --git a/src/devices/cpu/mips/r3000.h b/src/devices/cpu/mips/r3000.h
new file mode 100644
index 00000000000..a29ea5cd163
--- /dev/null
+++ b/src/devices/cpu/mips/r3000.h
@@ -0,0 +1,319 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/***************************************************************************
+
+ r3000.h
+ Interface file for the portable MIPS R3000 emulator.
+ Written by Aaron Giles
+
+***************************************************************************/
+
+#ifndef __R3000_H__
+#define __R3000_H__
+
+
+/***************************************************************************
+ 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, DEVCB_##_devcb);
+
+#define MCFG_R3000_BRCOND1_INPUT(_devcb) \
+ devcb = &r3000_device::static_set_brcond1_input(*device, DEVCB_##_devcb);
+
+#define MCFG_R3000_BRCOND2_INPUT(_devcb) \
+ devcb = &r3000_device::static_set_brcond2_input(*device, DEVCB_##_devcb);
+
+#define MCFG_R3000_BRCOND3_INPUT(_devcb) \
+ devcb = &r3000_device::static_set_brcond3_input(*device, DEVCB_##_devcb);
+
+
+/***************************************************************************
+ REGISTER ENUMERATION
+***************************************************************************/
+
+enum
+{
+ R3000_PC=1,R3000_SR,
+ R3000_R0,R3000_R1,R3000_R2,R3000_R3,R3000_R4,R3000_R5,R3000_R6,R3000_R7,
+ R3000_R8,R3000_R9,R3000_R10,R3000_R11,R3000_R12,R3000_R13,R3000_R14,R3000_R15,
+ R3000_R16,R3000_R17,R3000_R18,R3000_R19,R3000_R20,R3000_R21,R3000_R22,R3000_R23,
+ R3000_R24,R3000_R25,R3000_R26,R3000_R27,R3000_R28,R3000_R29,R3000_R30,R3000_R31
+};
+
+
+/***************************************************************************
+ INTERRUPT CONSTANTS
+***************************************************************************/
+
+#define R3000_IRQ0 0 /* IRQ0 */
+#define R3000_IRQ1 1 /* IRQ1 */
+#define R3000_IRQ2 2 /* IRQ2 */
+#define R3000_IRQ3 3 /* IRQ3 */
+#define R3000_IRQ4 4 /* IRQ4 */
+#define R3000_IRQ5 5 /* IRQ5 */
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> r3000_device
+
+class r3000_device : public cpu_device
+{
+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, const char *shortname, const char *source);
+ 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 devcb_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 devcb_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 devcb_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 devcb_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, std::string &str);
+
+ // 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(offs_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;
+ std::vector<UINT32> m_icache;
+ std::vector<UINT32> m_dcache;
+ size_t m_cache_size;
+ size_t m_icache_size;
+ size_t m_dcache_size;
+
+ // I/O
+ devcb_read_line m_in_brcond0;
+ devcb_read_line m_in_brcond1;
+ devcb_read_line m_in_brcond2;
+ devcb_read_line m_in_brcond3;
+};
+
+
+// ======================> 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);
+};
+
+
+// device type definition
+
+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__ */