summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m68000/m68kcpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m68000/m68kcpu.h')
-rw-r--r--src/devices/cpu/m68000/m68kcpu.h104
1 files changed, 77 insertions, 27 deletions
diff --git a/src/devices/cpu/m68000/m68kcpu.h b/src/devices/cpu/m68000/m68kcpu.h
index 0326c0f4bd1..93507a2a283 100644
--- a/src/devices/cpu/m68000/m68kcpu.h
+++ b/src/devices/cpu/m68000/m68kcpu.h
@@ -8,7 +8,7 @@
* Version 4.50
*
* A portable Motorola M680x0 processor emulation engine.
- * Copyright Karl Stenerud. All rights reserved.
+ * Copyright Karl Stenerud
*
*/
@@ -21,7 +21,7 @@
#undef REG_SP
#undef REG_PC
#else
-#include <limits.h>
+#include <climits>
#endif
/* ======================================================================== */
@@ -604,11 +604,14 @@ inline u32 m68ki_read_imm_16()
result = MASK_OUT_ABOVE_16(m_pref_data);
m_pc += 2;
if (!m_mmu_tmp_buserror_occurred) {
+
// prefetch only if no bus error occurred in opcode fetch
m_pref_data = m68ki_ic_readimm16(m_pc);
m_pref_addr = m_mmu_tmp_buserror_occurred ? ~0 : m_pc;
- // ignore bus error on prefetch
- m_mmu_tmp_buserror_occurred = 0;
+ if (!CPU_TYPE_IS_010())
+ {
+ m_mmu_tmp_buserror_occurred = 0;
+ }
}
return result;
@@ -656,6 +659,16 @@ inline u32 m68ki_read_8_fc(u32 address, u32 fc)
m_mmu_tmp_fc = fc;
m_mmu_tmp_rw = 1;
m_mmu_tmp_sz = M68K_SZ_BYTE;
+ // Check for reading the FPU's CIRs if this is an '020 or '030.
+ // In CPU space (FC 7), addresses 0x0002xxxx are coprocessor interface registers.
+ // Bits 15-13 are the coprocessor ID, and bits 0-4 are the register select.
+ if ((fc == 7) && CPU_TYPE_IS_020_PLUS() && !CPU_TYPE_IS_040_PLUS())
+ {
+ if ((address & 0xffffeff0) == 0x00022000)
+ {
+ return m6888x_read_cir(address);
+ }
+ }
return m_read8(address);
}
inline u32 m68ki_read_16_fc(u32 address, u32 fc)
@@ -667,6 +680,13 @@ inline u32 m68ki_read_16_fc(u32 address, u32 fc)
m_mmu_tmp_fc = fc;
m_mmu_tmp_rw = 1;
m_mmu_tmp_sz = M68K_SZ_WORD;
+ if ((fc == 7) && CPU_TYPE_IS_020_PLUS() && !CPU_TYPE_IS_040_PLUS())
+ {
+ if ((address & 0xffffeff0) == 0x00022000)
+ {
+ return m6888x_read_cir(address);
+ }
+ }
return m_read16(address);
}
inline u32 m68ki_read_32_fc(u32 address, u32 fc)
@@ -678,6 +698,13 @@ inline u32 m68ki_read_32_fc(u32 address, u32 fc)
m_mmu_tmp_fc = fc;
m_mmu_tmp_rw = 1;
m_mmu_tmp_sz = M68K_SZ_LONG;
+ if ((fc == 7) && CPU_TYPE_IS_020_PLUS() && !CPU_TYPE_IS_040_PLUS())
+ {
+ if ((address & 0xffffeff0) == 0x00022000)
+ {
+ return m6888x_read_cir(address);
+ }
+ }
return m_read32(address);
}
@@ -686,6 +713,14 @@ inline void m68ki_write_8_fc(u32 address, u32 fc, u32 value)
m_mmu_tmp_fc = fc;
m_mmu_tmp_rw = 0;
m_mmu_tmp_sz = M68K_SZ_BYTE;
+ if ((fc == 7) && CPU_TYPE_IS_020_PLUS() && !CPU_TYPE_IS_040_PLUS())
+ {
+ if ((address & 0xffffeff0) == 0x00022000)
+ {
+ m6888x_write_cir(address, value);
+ return;
+ }
+ }
m_write8(address, value);
}
inline void m68ki_write_16_fc(u32 address, u32 fc, u32 value)
@@ -697,6 +732,14 @@ inline void m68ki_write_16_fc(u32 address, u32 fc, u32 value)
m_mmu_tmp_fc = fc;
m_mmu_tmp_rw = 0;
m_mmu_tmp_sz = M68K_SZ_WORD;
+ if ((fc == 7) && CPU_TYPE_IS_020_PLUS() && !CPU_TYPE_IS_040_PLUS())
+ {
+ if ((address & 0xffffeff0) == 0x00022000)
+ {
+ m6888x_write_cir(address, value);
+ return;
+ }
+ }
m_write16(address, value);
}
inline void m68ki_write_32_fc(u32 address, u32 fc, u32 value)
@@ -708,6 +751,14 @@ inline void m68ki_write_32_fc(u32 address, u32 fc, u32 value)
m_mmu_tmp_fc = fc;
m_mmu_tmp_rw = 0;
m_mmu_tmp_sz = M68K_SZ_LONG;
+ if ((fc == 7) && CPU_TYPE_IS_020_PLUS() && !CPU_TYPE_IS_040_PLUS())
+ {
+ if ((address & 0xffffeff0) == 0x00022000)
+ {
+ m6888x_write_cir(address, value);
+ return;
+ }
+ }
m_write32(address, value);
}
@@ -1108,8 +1159,10 @@ inline void m68ki_set_sr(u32 value)
/* ------------------------- Exception Processing ------------------------- */
/* Initiate exception processing */
-inline u32 m68ki_init_exception()
+inline u32 m68ki_init_exception(u32 vector)
{
+ debugger_exception_hook(vector);
+
/* Save the old status register */
u32 sr = m68ki_get_sr();
@@ -1186,8 +1239,11 @@ inline void m68ki_stack_frame_buserr(u32 sr)
/* Format 8 stack frame (68010).
* 68010 only. This is the 29 word bus/address error frame.
*/
-inline void m68ki_stack_frame_1000(u32 pc, u32 sr, u32 vector)
+inline void m68ki_stack_frame_1000(u32 pc, u32 sr, u32 vector, u32 fault_address)
{
+ int orig_rw = m_mmu_tmp_buserror_rw; // this gets splatted by the following pushes, so save it now
+ int orig_fc = m_mmu_tmp_buserror_fc;
+
/* VERSION
* NUMBER
* INTERNAL INFORMATION, 16 WORDS
@@ -1220,10 +1276,10 @@ inline void m68ki_stack_frame_1000(u32 pc, u32 sr, u32 vector)
m68ki_fake_push_16();
/* FAULT ADDRESS */
- m68ki_push_32(0);
+ m68ki_push_32(fault_address);
/* SPECIAL STATUS WORD */
- m68ki_push_16(0);
+ m68ki_push_16(orig_fc | (orig_rw<<8));
/* 1000, VECTOR OFFSET */
m68ki_push_16(0x8000 | (vector<<2));
@@ -1238,7 +1294,7 @@ inline void m68ki_stack_frame_1000(u32 pc, u32 sr, u32 vector)
/* Format 15 stack frame (68070).
* 68070 only. This is the 17 word bus/address error frame.
*/
-inline void m68ki_stack_frame_1111(uint32_t pc, uint32_t sr, uint32_t vector)
+inline void m68ki_stack_frame_1111(u32 pc, u32 sr, u32 vector, u32 fault_address)
{
/* INTERNAL INFORMATION */
m68ki_fake_push_16();
@@ -1253,7 +1309,7 @@ inline void m68ki_stack_frame_1111(uint32_t pc, uint32_t sr, uint32_t vector)
m68ki_push_32(0);
/* FAULT ADDRESS */
- m68ki_push_32(0);
+ m68ki_push_32(fault_address);
/* DATA OUTPUT BUFFER */
m68ki_push_32(0);
@@ -1454,7 +1510,7 @@ inline void m68ki_stack_frame_0111(u32 sr, u32 vector, u32 pc, u32 fault_address
*/
inline void m68ki_exception_trap(u32 vector)
{
- u32 sr = m68ki_init_exception();
+ u32 sr = m68ki_init_exception(vector);
if(CPU_TYPE_IS_010_LESS())
m68ki_stack_frame_0000(m_pc, sr, vector);
@@ -1470,7 +1526,7 @@ inline void m68ki_exception_trap(u32 vector)
/* Trap#n stacks a 0 frame but behaves like group2 otherwise */
inline void m68ki_exception_trapN(u32 vector)
{
- u32 sr = m68ki_init_exception();
+ u32 sr = m68ki_init_exception(vector);
m68ki_stack_frame_0000(m_pc, sr, vector);
m68ki_jump_vector(vector);
@@ -1481,7 +1537,7 @@ inline void m68ki_exception_trapN(u32 vector)
/* Exception for trace mode */
inline void m68ki_exception_trace()
{
- u32 sr = m68ki_init_exception();
+ u32 sr = m68ki_init_exception(EXCEPTION_TRACE);
if(CPU_TYPE_IS_010_LESS())
{
@@ -1506,7 +1562,7 @@ inline void m68ki_exception_trace()
/* Exception for privilege violation */
inline void m68ki_exception_privilege_violation()
{
- u32 sr = m68ki_init_exception();
+ u32 sr = m68ki_init_exception(EXCEPTION_PRIVILEGE_VIOLATION);
if(CPU_TYPE_IS_000())
{
@@ -1523,9 +1579,7 @@ inline void m68ki_exception_privilege_violation()
/* Exception for A-Line instructions */
inline void m68ki_exception_1010()
{
- u32 sr;
-
- sr = m68ki_init_exception();
+ u32 sr = m68ki_init_exception(EXCEPTION_1010);
m68ki_stack_frame_0000(m_ppc, sr, EXCEPTION_1010);
m68ki_jump_vector(EXCEPTION_1010);
@@ -1536,9 +1590,7 @@ inline void m68ki_exception_1010()
/* Exception for F-Line instructions */
inline void m68ki_exception_1111()
{
- u32 sr;
-
- sr = m68ki_init_exception();
+ u32 sr = m68ki_init_exception(EXCEPTION_1111);
m68ki_stack_frame_0000(m_ppc, sr, EXCEPTION_1111);
m68ki_jump_vector(EXCEPTION_1111);
@@ -1549,9 +1601,7 @@ inline void m68ki_exception_1111()
/* Exception for illegal instructions */
inline void m68ki_exception_illegal()
{
- u32 sr;
-
- sr = m68ki_init_exception();
+ u32 sr = m68ki_init_exception(EXCEPTION_ILLEGAL_INSTRUCTION);
if(CPU_TYPE_IS_000())
{
@@ -1568,7 +1618,7 @@ inline void m68ki_exception_illegal()
/* Exception for format errror in RTE */
inline void m68ki_exception_format_error()
{
- u32 sr = m68ki_init_exception();
+ u32 sr = m68ki_init_exception(EXCEPTION_FORMAT_ERROR);
m68ki_stack_frame_0000(m_pc, sr, EXCEPTION_FORMAT_ERROR);
m68ki_jump_vector(EXCEPTION_FORMAT_ERROR);
@@ -1579,7 +1629,7 @@ inline void m68ki_exception_format_error()
/* Exception for address error */
inline void m68ki_exception_address_error()
{
- u32 sr = m68ki_init_exception();
+ u32 sr = m68ki_init_exception(EXCEPTION_ADDRESS_ERROR);
/* If we were processing a bus error, address error, or reset,
* this is a catastrophic failure.
@@ -1602,12 +1652,12 @@ inline void m68ki_exception_address_error()
else if (CPU_TYPE_IS_010())
{
/* only the 68010 throws this unique type-1000 frame */
- m68ki_stack_frame_1000(m_ppc, sr, EXCEPTION_BUS_ERROR);
+ m68ki_stack_frame_1000(m_ppc, sr, EXCEPTION_BUS_ERROR, m_mmu_tmp_buserror_address);
}
else if (CPU_TYPE_IS_070())
{
/* only the 68070 throws this unique type-1111 frame */
- m68ki_stack_frame_1111(m_ppc, sr, EXCEPTION_BUS_ERROR);
+ m68ki_stack_frame_1111(m_ppc, sr, EXCEPTION_BUS_ERROR, m_mmu_tmp_buserror_address);
}
else if (m_mmu_tmp_buserror_address == m_ppc)
{