summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author arbee <rb6502@users.noreply.github.com>2014-12-31 23:34:30 -0500
committer arbee <rb6502@users.noreply.github.com>2014-12-31 23:34:30 -0500
commitc971eca603f3f1c35aa32ee72e1dedcfa58ee1a1 (patch)
treeeecef635d5eff2f5f2b44f8687dcc934b4598593
parent42838dabefe34b0d3efd83f39d09972486b927c9 (diff)
m68k: implement FTRAP instruction, add "68020 with FPU" CPU type. [R. Belmont]
-rw-r--r--src/emu/cpu/m68000/m68000.h22
-rw-r--r--src/emu/cpu/m68000/m68k_in.c12
-rw-r--r--src/emu/cpu/m68000/m68kcpu.c21
-rw-r--r--src/emu/cpu/m68000/m68kfpu.inc29
4 files changed, 83 insertions, 1 deletions
diff --git a/src/emu/cpu/m68000/m68000.h b/src/emu/cpu/m68000/m68000.h
index 06b34680507..6890c484307 100644
--- a/src/emu/cpu/m68000/m68000.h
+++ b/src/emu/cpu/m68000/m68000.h
@@ -376,6 +376,7 @@ public:
void init_cpu_m68008(void);
void init_cpu_m68010(void);
void init_cpu_m68020(void);
+ void init_cpu_m68020fpu(void);
void init_cpu_m68020pmmu(void);
void init_cpu_m68020hmmu(void);
void init_cpu_m68ec020(void);
@@ -554,6 +555,26 @@ public:
protected:
};
+class m68020fpu_device : public m68000_base_device
+{
+public:
+ // construction/destruction
+ m68020fpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual UINT32 disasm_min_opcode_bytes() const { return 2; };
+ virtual UINT32 disasm_max_opcode_bytes() const { return 20; };
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+ virtual UINT32 execute_min_cycles() const { return 2; };
+ virtual UINT32 execute_max_cycles() const { return 158; };
+
+ virtual UINT32 execute_default_irq_vector() const { return -1; };
+
+ // device-level overrides
+ virtual void device_start();
+protected:
+};
+
class m68020pmmu_device : public m68000_base_device
{
public:
@@ -773,6 +794,7 @@ extern const device_type M68008PLCC;
extern const device_type M68010;
extern const device_type M68EC020;
extern const device_type M68020;
+extern const device_type M68020FPU;
extern const device_type M68020PMMU;
extern const device_type M68020HMMU;
extern const device_type M68EC030;
diff --git a/src/emu/cpu/m68000/m68k_in.c b/src/emu/cpu/m68000/m68k_in.c
index 29ff095350c..900fb0a502b 100644
--- a/src/emu/cpu/m68000/m68k_in.c
+++ b/src/emu/cpu/m68000/m68k_in.c
@@ -272,6 +272,7 @@ M68KMAKE_OPCODE_HANDLER_HEADER
extern void m68040_fpu_op0(m68000_base_device *m68k);
extern void m68040_fpu_op1(m68000_base_device *m68k);
extern void m68881_mmu_ops(m68000_base_device *m68k);
+extern void m68881_ftrap(m68000_base_device *m68k);
/* ======================================================================== */
/* ========================= INSTRUCTION HANDLERS ========================= */
@@ -551,6 +552,7 @@ cpdbcc 32 . . 1111...001001... .......... . . U U . . U . .
cpgen 32 . . 1111...000...... .......... . . U U . . U . . 4 4 . . .
cpscc 32 . . 1111...001...... .......... . . U U . . U . . 4 4 . . .
cptrapcc 32 . . 1111...001111... .......... . . U U . . U . . 4 4 . . .
+ftrapcc 32 . . 1111001001111... .......... . . U U . . U . . 4 4 . . .
dbt 16 . . 0101000011001... .......... U U U U U U U 12 12 6 6 6 6 6
dbf 16 . . 0101000111001... .......... U U U U U U U 12 12 6 4 4 4 4
dbcc 16 . . 0101....11001... .......... U U U U U U U 12 12 6 6 6 6 6
@@ -4477,6 +4479,16 @@ M68KMAKE_OP(cptrapcc, 32, ., .)
m68ki_exception_1111(mc68kcpu);
}
+M68KMAKE_OP(ftrapcc, 32, ., .)
+{
+ if((mc68kcpu)->has_fpu)
+ {
+ m68881_ftrap(mc68kcpu);
+ return;
+ }
+ m68ki_exception_1111(mc68kcpu);
+}
+
M68KMAKE_OP(dbt, 16, ., .)
{
REG_PC(mc68kcpu) += 2;
diff --git a/src/emu/cpu/m68000/m68kcpu.c b/src/emu/cpu/m68000/m68kcpu.c
index 3bf0b84cc49..6f4f4126bbd 100644
--- a/src/emu/cpu/m68000/m68kcpu.c
+++ b/src/emu/cpu/m68000/m68kcpu.c
@@ -699,7 +699,7 @@ static void m68k_cause_bus_error(m68000_base_device *m68k)
{
/* only the 68010 throws this unique type-1000 frame */
m68ki_stack_frame_1000(m68k, REG_PPC(m68k), sr, EXCEPTION_BUS_ERROR);
- }
+ }
else if (m68k->mmu_tmp_buserror_address == REG_PPC(m68k))
{
m68ki_stack_frame_1010(m68k, sr, EXCEPTION_BUS_ERROR, REG_PPC(m68k), m68k->mmu_tmp_buserror_address);
@@ -1885,6 +1885,12 @@ void m68000_base_device::init_cpu_m68020(void)
define_state();
}
+void m68000_base_device::init_cpu_m68020fpu(void)
+{
+ init_cpu_m68020();
+
+ has_fpu = 1;
+}
void m68000_base_device::init_cpu_m68020pmmu(void)
{
@@ -2243,6 +2249,7 @@ offs_t m68008plcc_device::disasm_disassemble(char *buffer, offs_t pc, const UINT
offs_t m68010_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { return CPU_DISASSEMBLE_NAME(dasm_m68010)(this, buffer, pc, oprom, opram, options); };
offs_t m68ec020_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, buffer, pc, oprom, opram, options); };
offs_t m68020_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, buffer, pc, oprom, opram, options); };
+offs_t m68020fpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, buffer, pc, oprom, opram, options); };
offs_t m68020pmmu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, buffer, pc, oprom, opram, options); };
offs_t m68020hmmu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, buffer, pc, oprom, opram, options); };
offs_t m68ec030_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { return CPU_DISASSEMBLE_NAME(dasm_m68ec030)(this, buffer, pc, oprom, opram, options); };
@@ -2547,6 +2554,7 @@ const device_type M68008PLCC = &device_creator<m68008plcc_device>;
const device_type M68010 = &device_creator<m68010_device>;
const device_type M68EC020 = &device_creator<m68ec020_device>;
const device_type M68020 = &device_creator<m68020_device>;
+const device_type M68020FPU = &device_creator<m68020fpu_device>;
const device_type M68020PMMU = &device_creator<m68020pmmu_device>;
const device_type M68020HMMU = &device_creator<m68020hmmu_device>;
const device_type M68EC030 = &device_creator<m68ec030_device>;
@@ -2646,6 +2654,17 @@ void m68020_device::device_start()
init_cpu_m68020();
}
+
+m68020fpu_device::m68020fpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : m68000_base_device(mconfig, "M68020FPU", tag, owner, clock, M68020, 32,32, "m68020fpu", __FILE__)
+{
+}
+
+void m68020fpu_device::device_start()
+{
+ init_cpu_m68020fpu();
+}
+
// 68020 with 68851 PMMU
m68020pmmu_device::m68020pmmu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: m68000_base_device(mconfig, "M68020PMMU", tag, owner, clock, M68020PMMU, 32,32, "m68020pmmu", __FILE__)
diff --git a/src/emu/cpu/m68000/m68kfpu.inc b/src/emu/cpu/m68000/m68kfpu.inc
index e9f0140264b..47f39d8c4fb 100644
--- a/src/emu/cpu/m68000/m68kfpu.inc
+++ b/src/emu/cpu/m68000/m68kfpu.inc
@@ -2166,3 +2166,32 @@ void m68040_fpu_op1(m68000_base_device *m68k)
default: fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (m68k->ir >> 6) & 0x3, REG_PC(m68k)-2);
}
}
+
+void m68881_ftrap(m68000_base_device *m68k)
+{
+ UINT16 w2 = OPER_I_16(m68k);
+
+ // now check the condition
+ if (TEST_CONDITION(m68k, w2 & 0x3f))
+ {
+ // trap here
+ m68ki_exception_trap(m68k, EXCEPTION_TRAPV);
+ }
+ else // fall through, requires eating the operand
+ {
+ switch (m68k->ir & 0x7)
+ {
+ case 2: // word operand
+ OPER_I_16(m68k);
+ break;
+
+ case 3: // long word operand
+ OPER_I_32(m68k);
+ break;
+
+ case 4: // no operand
+ break;
+ }
+ }
+}
+