summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/sh2/sh2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/sh2/sh2.cpp')
-rw-r--r--src/devices/cpu/sh2/sh2.cpp134
1 files changed, 90 insertions, 44 deletions
diff --git a/src/devices/cpu/sh2/sh2.cpp b/src/devices/cpu/sh2/sh2.cpp
index fb9e564fe73..1877196a013 100644
--- a/src/devices/cpu/sh2/sh2.cpp
+++ b/src/devices/cpu/sh2/sh2.cpp
@@ -93,10 +93,14 @@
*****************************************************************************/
#include "emu.h"
-#include "debugger.h"
#include "sh2.h"
#include "sh2comn.h"
+#include "debugger.h"
+
+//#define VERBOSE 1
+#include "logmacro.h"
+
/***************************************************************************
DEBUGGING
@@ -105,8 +109,6 @@
#define DISABLE_FAST_REGISTERS (0) // set to 1 to turn off usage of register caching
#define SINGLE_INSTRUCTION_MODE (0)
-#define VERBOSE 0
-#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
/***************************************************************************
CONSTANTS
@@ -122,9 +124,9 @@
#define COMPILE_MAX_SEQUENCE 64
-const device_type SH1 = device_creator<sh1_device>;
-const device_type SH2 = device_creator<sh2_device>;
-const device_type SH2A = device_creator<sh2a_device>;
+DEFINE_DEVICE_TYPE(SH1, sh1_device, "sh1", "SH-1")
+DEFINE_DEVICE_TYPE(SH2, sh2_device, "sh2", "SH-2")
+DEFINE_DEVICE_TYPE(SH2A, sh2a_device, "sh21", "SH-2A")
/*-------------------------------------------------
sh2_internal_a5 - read handler for
@@ -170,30 +172,8 @@ static ADDRESS_MAP_START( sh7032_map, AS_PROGRAM, 32, sh1_device )
ADDRESS_MAP_END
sh2_device::sh2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cpu_device(mconfig, SH2, "SH-2", tag, owner, clock, "sh2", __FILE__)
- , m_program_config("program", ENDIANNESS_BIG, 32, 32, 0, ADDRESS_MAP_NAME(sh7604_map))
- , m_decrypted_program_config("decrypted_opcodes", ENDIANNESS_BIG, 32, 32, 0)
- , m_is_slave(0)
- , m_cpu_type(CPU_TYPE_SH2)
- , m_cache(CACHE_SIZE + sizeof(internal_sh2_state))
- , m_drcuml(nullptr)
-// , m_drcuml(*this, m_cache, 0, 1, 32, 1)
- , m_drcfe(nullptr)
- , m_drcoptions(0)
- , m_sh2_state(nullptr)
- , m_entry(nullptr)
- , m_read8(nullptr)
- , m_write8(nullptr)
- , m_read16(nullptr)
- , m_write16(nullptr)
- , m_read32(nullptr)
- , m_write32(nullptr)
- , m_interrupt(nullptr)
- , m_nocode(nullptr)
- , m_out_of_cycles(nullptr)
- , m_debugger_temp(0)
+ : sh2_device(mconfig, SH2, tag, owner, clock, CPU_TYPE_SH2, ADDRESS_MAP_NAME(sh7604_map), 32)
{
- m_isdrc = allow_drc();
}
@@ -202,8 +182,8 @@ void sh2_device::device_stop()
}
-sh2_device::sh2_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source, int cpu_type, address_map_constructor internal_map, int addrlines )
- : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
+sh2_device::sh2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cpu_type, address_map_constructor internal_map, int addrlines)
+ : cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", ENDIANNESS_BIG, 32, addrlines, 0, internal_map)
, m_decrypted_program_config("decrypted_opcodes", ENDIANNESS_BIG, 32, addrlines, 0)
, m_is_slave(0)
@@ -224,17 +204,18 @@ sh2_device::sh2_device(const machine_config &mconfig, device_type type, const ch
, m_interrupt(nullptr)
, m_nocode(nullptr)
, m_out_of_cycles(nullptr)
+ , m_debugger_temp(0)
{
m_isdrc = allow_drc();
}
sh2a_device::sh2a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : sh2_device(mconfig, SH2A, "SH-2A", tag, owner, clock, "sh2a", __FILE__, CPU_TYPE_SH2, ADDRESS_MAP_NAME(sh7021_map), 28)
+ : sh2_device(mconfig, SH2A, tag, owner, clock, CPU_TYPE_SH2, ADDRESS_MAP_NAME(sh7021_map), 28)
{
}
sh1_device::sh1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : sh2_device(mconfig, SH1, "SH-1", tag, owner, clock, "sh1", __FILE__, CPU_TYPE_SH1, ADDRESS_MAP_NAME(sh7032_map), 28)
+ : sh2_device(mconfig, SH1, tag, owner, clock, CPU_TYPE_SH1, ADDRESS_MAP_NAME(sh7032_map), 28)
{
}
@@ -258,10 +239,6 @@ offs_t sh2_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uin
/* speed up delay loops, bail out of tight loops */
#define BUSY_LOOP_HACKS 1
-#define VERBOSE 0
-
-#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
-
uint8_t sh2_device::RB(offs_t A)
{
if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000)
@@ -2609,13 +2586,13 @@ void sh2_device::execute_set_input(int irqline, int state)
return;
m_nmi_line_state = state;
- if( state == CLEAR_LINE )
+ if (state == CLEAR_LINE)
{
- LOG(("SH-2 '%s' cleared nmi\n", tag()));
+ LOG("SH-2 cleared nmi\n");
}
else
{
- LOG(("SH-2 '%s' assert nmi\n", tag()));
+ LOG("SH-2 asserted nmi\n");
sh2_exception("Set IRQ line", 16);
@@ -2629,14 +2606,14 @@ void sh2_device::execute_set_input(int irqline, int state)
return;
m_irq_line_state[irqline] = state;
- if( state == CLEAR_LINE )
+ if (state == CLEAR_LINE)
{
- LOG(("SH-2 '%s' cleared irq #%d\n", tag(), irqline));
+ LOG("SH-2 cleared irq #%d\n", irqline);
m_sh2_state->pending_irq &= ~(1 << irqline);
}
else
{
- LOG(("SH-2 '%s' assert irq #%d\n", tag(), irqline));
+ LOG("SH-2 asserted irq #%d\n", irqline);
m_sh2_state->pending_irq |= 1 << irqline;
if (m_isdrc)
{
@@ -2651,5 +2628,74 @@ void sh2_device::execute_set_input(int irqline, int state)
}
}
-#include "sh2comn.cpp"
+void sh2_device::sh2_exception(const char *message, int irqline)
+{
+ int vector;
+
+ if (irqline != 16)
+ {
+ if (irqline <= ((m_sh2_state->sr >> 4) & 15)) /* If the cpu forbids this interrupt */
+ return;
+
+ // if this is an sh2 internal irq, use its vector
+ if (m_sh2_state->internal_irq_level == irqline)
+ {
+ vector = m_internal_irq_vector;
+ /* avoid spurious irqs with this (TODO: needs a better fix) */
+ m_sh2_state->internal_irq_level = -1;
+ LOG("SH-2 exception #%d (internal vector: $%x) after [%s]\n", irqline, vector, message);
+ }
+ else
+ {
+ if(m_m[0x38] & 0x00010000)
+ {
+ vector = standard_irq_callback(irqline);
+ LOG("SH-2 exception #%d (external vector: $%x) after [%s]\n", irqline, vector, message);
+ }
+ else
+ {
+ standard_irq_callback(irqline);
+ vector = 64 + irqline/2;
+ LOG("SH-2 exception #%d (autovector: $%x) after [%s]\n", irqline, vector, message);
+ }
+ }
+ }
+ else
+ {
+ vector = 11;
+ LOG("SH-2 nmi exception (autovector: $%x) after [%s]\n", vector, message);
+ }
+
+ if (m_isdrc)
+ {
+ m_sh2_state->evec = RL( m_sh2_state->vbr + vector * 4 );
+ m_sh2_state->evec &= AM;
+ m_sh2_state->irqsr = m_sh2_state->sr;
+
+ /* set I flags in SR */
+ if (irqline > SH2_INT_15)
+ m_sh2_state->sr = m_sh2_state->sr | I;
+ else
+ m_sh2_state->sr = (m_sh2_state->sr & ~I) | (irqline << 4);
+
+// printf("sh2_exception [%s] irqline %x evec %x save SR %x new SR %x\n", message, irqline, m_sh2_state->evec, m_sh2_state->irqsr, m_sh2_state->sr);
+ } else {
+ m_sh2_state->r[15] -= 4;
+ WL( m_sh2_state->r[15], m_sh2_state->sr ); /* push SR onto stack */
+ m_sh2_state->r[15] -= 4;
+ WL( m_sh2_state->r[15], m_sh2_state->pc ); /* push PC onto stack */
+
+ /* set I flags in SR */
+ if (irqline > SH2_INT_15)
+ m_sh2_state->sr = m_sh2_state->sr | I;
+ else
+ m_sh2_state->sr = (m_sh2_state->sr & ~I) | (irqline << 4);
+
+ /* fetch PC */
+ m_sh2_state->pc = RL( m_sh2_state->vbr + vector * 4 );
+ }
+
+ if(m_sh2_state->sleep_mode == 1) { m_sh2_state->sleep_mode = 2; }
+}
+
#include "sh2drc.cpp"