diff options
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 |
commit | c971eca603f3f1c35aa32ee72e1dedcfa58ee1a1 (patch) | |
tree | eecef635d5eff2f5f2b44f8687dcc934b4598593 | |
parent | 42838dabefe34b0d3efd83f39d09972486b927c9 (diff) |
m68k: implement FTRAP instruction, add "68020 with FPU" CPU type. [R. Belmont]
-rw-r--r-- | src/emu/cpu/m68000/m68000.h | 22 | ||||
-rw-r--r-- | src/emu/cpu/m68000/m68k_in.c | 12 | ||||
-rw-r--r-- | src/emu/cpu/m68000/m68kcpu.c | 21 | ||||
-rw-r--r-- | src/emu/cpu/m68000/m68kfpu.inc | 29 |
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; + } + } +} + |