diff options
Diffstat (limited to 'src/devices/cpu')
27 files changed, 414 insertions, 128 deletions
diff --git a/src/devices/cpu/am29000/am29ops.h b/src/devices/cpu/am29000/am29ops.h index 74f6eef48f9..e111af99cd1 100644 --- a/src/devices/cpu/am29000/am29ops.h +++ b/src/devices/cpu/am29000/am29ops.h @@ -1396,7 +1396,7 @@ void am29000_cpu_device::CLZ() { uint32_t b = INST_M_BIT ? I8: GET_RB_VAL; - m_r[RC] = count_leading_zeros(b); + m_r[RC] = count_leading_zeros_32(b); } void am29000_cpu_device::SETIP() diff --git a/src/devices/cpu/arm7/arm7ops.cpp b/src/devices/cpu/arm7/arm7ops.cpp index cb08ff8fed4..f5a8f435762 100644 --- a/src/devices/cpu/arm7/arm7ops.cpp +++ b/src/devices/cpu/arm7/arm7ops.cpp @@ -1697,7 +1697,7 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) uint32_t rm = insn&0xf; uint32_t rd = (insn>>12)&0xf; - SetRegister(rd, count_leading_zeros(GetRegister(rm))); + SetRegister(rd, count_leading_zeros_32(GetRegister(rm))); R15 += 4; } diff --git a/src/devices/cpu/drcbec.cpp b/src/devices/cpu/drcbec.cpp index d8b30535d6e..f54e6416696 100644 --- a/src/devices/cpu/drcbec.cpp +++ b/src/devices/cpu/drcbec.cpp @@ -1062,11 +1062,11 @@ int drcbe_c::execute(code_handle &entry) break; case MAKE_OPCODE_SHORT(OP_LZCNT, 4, 0): // LZCNT dst,src - PARAM0 = count_leading_zeros(PARAM1); + PARAM0 = count_leading_zeros_32(PARAM1); break; case MAKE_OPCODE_SHORT(OP_LZCNT, 4, 1): - temp32 = count_leading_zeros(PARAM1); + temp32 = count_leading_zeros_32(PARAM1); flags = FLAGS32_NZ(temp32); PARAM0 = temp32; break; @@ -1675,17 +1675,11 @@ int drcbe_c::execute(code_handle &entry) break; case MAKE_OPCODE_SHORT(OP_LZCNT, 8, 0): // DLZCNT dst,src - if ((uint32_t)(DPARAM1 >> 32) != 0) - DPARAM0 = count_leading_zeros(DPARAM1 >> 32); - else - DPARAM0 = 32 + count_leading_zeros(DPARAM1); + DPARAM0 = count_leading_zeros_64(DPARAM1); break; case MAKE_OPCODE_SHORT(OP_LZCNT, 8, 1): - if ((uint32_t)(DPARAM1 >> 32) != 0) - temp64 = count_leading_zeros(DPARAM1 >> 32); - else - temp64 = 32 + count_leading_zeros(DPARAM1); + temp64 = count_leading_zeros_64(DPARAM1); flags = FLAGS64_NZ(temp64); DPARAM0 = temp64; break; diff --git a/src/devices/cpu/dspp/dspp.cpp b/src/devices/cpu/dspp/dspp.cpp index ac7ece3cfb5..3479e461af5 100644 --- a/src/devices/cpu/dspp/dspp.cpp +++ b/src/devices/cpu/dspp/dspp.cpp @@ -1588,7 +1588,7 @@ void dspp_device::update_fifo_dma() while (mask != 0) { - uint32_t channel = 31 - count_leading_zeros(mask); + uint32_t channel = 31 - count_leading_zeros_32(mask); const fifo_dma & dma = m_fifo_dma[channel]; diff --git a/src/devices/cpu/h8500/h8500.cpp b/src/devices/cpu/h8500/h8500.cpp index c96fed16f7f..765988ceeaa 100644 --- a/src/devices/cpu/h8500/h8500.cpp +++ b/src/devices/cpu/h8500/h8500.cpp @@ -12,10 +12,11 @@ #include "h8500.h" #include "h8500dasm.h" -h8500_device::h8500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, int buswidth, int ramsize, address_map_constructor map) +h8500_device::h8500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, int buswidth, int ramsize, int defmode, address_map_constructor map) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_BIG, buswidth, addrbits, 0, map) , m_ram_config("internal RAM", ENDIANNESS_BIG, 16, ramsize, 0, address_map_constructor(FUNC(h8500_device::ram_map), this)) + , m_mode_control(defmode) , m_pc(0) , m_ppc(0) , m_sr(0) diff --git a/src/devices/cpu/h8500/h8500.h b/src/devices/cpu/h8500/h8500.h index ede393687a9..3755ab7a4ab 100644 --- a/src/devices/cpu/h8500/h8500.h +++ b/src/devices/cpu/h8500/h8500.h @@ -18,8 +18,10 @@ public: H8500_R4, H8500_R5, H8500_FP, H8500_SP }; + void set_mode(u8 mode) { assert(!configured()); m_mode_control = mode; } + protected: - h8500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, int buswidth, int ramsize, address_map_constructor map); + h8500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, int buswidth, int ramsize, int defmode, address_map_constructor map); // device-level overrides virtual void device_config_complete() override; @@ -40,7 +42,8 @@ protected: // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - virtual bool h8_maximum_mode() const noexcept { return true; } + u8 mode_control() const { return m_mode_control; } + virtual bool h8_maximum_mode() const noexcept { return m_mode_control == 3 || m_mode_control == 4; } // all except H8/570 private: void ram_map(address_map &map); @@ -52,6 +55,9 @@ private: address_space *m_program; memory_access<11, 1, 0, ENDIANNESS_BIG>::cache m_ram_cache; + // misc. configuration + u8 m_mode_control; + // internal registers u16 m_pc; u16 m_ppc; diff --git a/src/devices/cpu/h8500/h8510.cpp b/src/devices/cpu/h8500/h8510.cpp index 413f99cc248..b4ade58d8d5 100644 --- a/src/devices/cpu/h8500/h8510.cpp +++ b/src/devices/cpu/h8500/h8510.cpp @@ -12,7 +12,7 @@ DEFINE_DEVICE_TYPE(HD6415108, hd6415108_device, "hd6415108", "Hitachi HD6415108 (H8/510)") h8510_device::h8510_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : h8500_device(mconfig, type, tag, owner, clock, 24, 16, 0, address_map_constructor(FUNC(h8510_device::internal_map), this)) + : h8500_device(mconfig, type, tag, owner, clock, 24, 16, 0, 4, address_map_constructor(FUNC(h8510_device::internal_map), this)) { } diff --git a/src/devices/cpu/h8500/h8520.cpp b/src/devices/cpu/h8500/h8520.cpp index 9a3a076d5e4..459a979da98 100644 --- a/src/devices/cpu/h8500/h8520.cpp +++ b/src/devices/cpu/h8500/h8520.cpp @@ -10,9 +10,10 @@ #include "h8520.h" DEFINE_DEVICE_TYPE(HD6435208, hd6435208_device, "hd6435208", "Hitachi HD6435208 (H8/520)") +DEFINE_DEVICE_TYPE(HD6475208, hd6475208_device, "hd6475208", "Hitachi HD6475208 (H8/520)") h8520_device::h8520_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 9, address_map_constructor(FUNC(h8520_device::internal_map), this)) + : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 9, 4, address_map_constructor(FUNC(h8520_device::internal_map), this)) { } @@ -21,9 +22,15 @@ hd6435208_device::hd6435208_device(const machine_config &mconfig, const char *ta { } +hd6475208_device::hd6475208_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : h8520_device(mconfig, HD6475208, tag, owner, clock) +{ +} + void h8520_device::internal_map(address_map &map) { - map(0x0000, 0x3fff).rom().region(DEVICE_SELF, 0); // modes 2, 4, 7 + if (mode_control() == 2 || mode_control() == 4 || mode_control() == 7) + map(0x0000, 0x3fff).rom().region(DEVICE_SELF, 0); #if 0 map(0xff80, 0xff80).w(FUNC(h8520_device::p1ddr_w)); map(0xff81, 0xff81).w(FUNC(h8520_device::p2ddr_w)); diff --git a/src/devices/cpu/h8500/h8520.h b/src/devices/cpu/h8500/h8520.h index fc8795e7425..7f66327c796 100644 --- a/src/devices/cpu/h8500/h8520.h +++ b/src/devices/cpu/h8500/h8520.h @@ -24,6 +24,14 @@ public: hd6435208_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; +class hd6475208_device : public h8520_device +{ +public: + // device type constructor + hd6475208_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + DECLARE_DEVICE_TYPE(HD6435208, hd6435208_device) +DECLARE_DEVICE_TYPE(HD6475208, hd6475208_device) #endif // MAME_CPU_H8500_H8520_H diff --git a/src/devices/cpu/h8500/h8532.cpp b/src/devices/cpu/h8500/h8532.cpp index 9d0be448e3f..20c9869c4ee 100644 --- a/src/devices/cpu/h8500/h8532.cpp +++ b/src/devices/cpu/h8500/h8532.cpp @@ -10,9 +10,10 @@ #include "h8532.h" DEFINE_DEVICE_TYPE(HD6435328, hd6435328_device, "hd6435328", "Hitachi HD6435328 (H8/532)") +DEFINE_DEVICE_TYPE(HD6475328, hd6475328_device, "hd6475328", "Hitachi HD6475328 (H8/532)") h8532_device::h8532_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 10, address_map_constructor(FUNC(h8532_device::internal_map), this)) + : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 10, 4, address_map_constructor(FUNC(h8532_device::internal_map), this)) { } @@ -21,9 +22,15 @@ hd6435328_device::hd6435328_device(const machine_config &mconfig, const char *ta { } +hd6475328_device::hd6475328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : h8532_device(mconfig, HD6475328, tag, owner, clock) +{ +} + void h8532_device::internal_map(address_map &map) { - map(0x0000, 0x7fff).rom().region(DEVICE_SELF, 0); // modes 2, 4, 7 + if (mode_control() == 2 || mode_control() == 4 || mode_control() == 7) + map(0x0000, 0x7fff).rom().region(DEVICE_SELF, 0); #if 0 map(0xff80, 0xff80).w(FUNC(h8532_device::p1ddr_w)); map(0xff81, 0xff81).w(FUNC(h8532_device::p2ddr_w)); diff --git a/src/devices/cpu/h8500/h8532.h b/src/devices/cpu/h8500/h8532.h index c9b08ee1d00..71ec652a465 100644 --- a/src/devices/cpu/h8500/h8532.h +++ b/src/devices/cpu/h8500/h8532.h @@ -24,6 +24,14 @@ public: hd6435328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; +class hd6475328_device : public h8532_device +{ +public: + // device type constructor + hd6475328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + DECLARE_DEVICE_TYPE(HD6435328, hd6435328_device) +DECLARE_DEVICE_TYPE(HD6475328, hd6475328_device) #endif // MAME_CPU_H8500_H8532_H diff --git a/src/devices/cpu/h8500/h8534.cpp b/src/devices/cpu/h8500/h8534.cpp index dd33af71128..06c9b0dc24f 100644 --- a/src/devices/cpu/h8500/h8534.cpp +++ b/src/devices/cpu/h8500/h8534.cpp @@ -9,11 +9,13 @@ #include "emu.h" #include "h8534.h" +DEFINE_DEVICE_TYPE(HD6435348, hd6435348_device, "hd6435348", "Hitachi HD6435348 (H8/534)") DEFINE_DEVICE_TYPE(HD6475348, hd6475348_device, "hd6475348", "Hitachi HD6475348 (H8/534)") DEFINE_DEVICE_TYPE(HD6435368, hd6435368_device, "hd6435368", "Hitachi HD6435368 (H8/536)") +DEFINE_DEVICE_TYPE(HD6475368, hd6475368_device, "hd6475368", "Hitachi HD6475368 (H8/536)") h8534_device::h8534_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor map) - : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 11, map) + : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 11, 4, map) { } @@ -22,6 +24,11 @@ h8534_device::h8534_device(const machine_config &mconfig, device_type type, cons { } +hd6435348_device::hd6435348_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : h8534_device(mconfig, HD6435348, tag, owner, clock) +{ +} + hd6475348_device::hd6475348_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : h8534_device(mconfig, HD6475348, tag, owner, clock) { @@ -37,16 +44,24 @@ hd6435368_device::hd6435368_device(const machine_config &mconfig, const char *ta { } +hd6475368_device::hd6475368_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : h8536_device(mconfig, HD6475368, tag, owner, clock) +{ +} + void h8534_device::internal_map(address_map &map) { - map(0x0000, 0x7fff).rom().region(DEVICE_SELF, 0); // modes 2, 4, 7 + if (mode_control() == 2 || mode_control() == 4 || mode_control() == 7) + map(0x0000, 0x7fff).rom().region(DEVICE_SELF, 0); register_field_map(map); } void h8536_device::internal_map(address_map &map) { - //map(0x0000, 0xee7f).rom().region(DEVICE_SELF, 0); // mode 2? - //map(0x0000, 0xf67f).rom().region(DEVICE_SELF, 0); // modes 4, 7 + if (mode_control() == 2) + map(0x0000, 0xee7f).rom().region(DEVICE_SELF, 0); + else if (mode_control() == 4 || mode_control() == 7) + map(0x0000, 0xf67f).rom().region(DEVICE_SELF, 0); register_field_map(map); } diff --git a/src/devices/cpu/h8500/h8534.h b/src/devices/cpu/h8500/h8534.h index 8e5c357ff1b..2fad7985a70 100644 --- a/src/devices/cpu/h8500/h8534.h +++ b/src/devices/cpu/h8500/h8534.h @@ -11,9 +11,8 @@ class h8534_device : public h8500_device { protected: - // delegating constructor + // delegating constructors h8534_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); - h8534_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor map); void register_field_map(address_map &map); @@ -22,6 +21,13 @@ private: void internal_map(address_map &map); }; +class hd6435348_device : public h8534_device +{ +public: + // device type constructor + hd6435348_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + class hd6475348_device : public h8534_device { public: @@ -45,7 +51,16 @@ public: hd6435368_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; +class hd6475368_device : public h8536_device +{ +public: + // device type constructor + hd6475368_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + +DECLARE_DEVICE_TYPE(HD6435348, hd6435348_device) DECLARE_DEVICE_TYPE(HD6475348, hd6475348_device) DECLARE_DEVICE_TYPE(HD6435368, hd6435368_device) +DECLARE_DEVICE_TYPE(HD6475368, hd6475368_device) #endif // MAME_CPU_H8500_H8534_H diff --git a/src/devices/cpu/m68000/m68kfpu.cpp b/src/devices/cpu/m68000/m68kfpu.cpp index ed439f2fe5f..7cd10e84b84 100644 --- a/src/devices/cpu/m68000/m68kfpu.cpp +++ b/src/devices/cpu/m68000/m68kfpu.cpp @@ -241,6 +241,53 @@ inline void m68000_base_device::store_pack_float80(u32 ea, int k, floatx80 fpr) m68ki_write_32(ea+8, dw3); } +inline floatx80 propagateFloatx80NaNOneArg(floatx80 a) +{ + if (floatx80_is_signaling_nan(a)) + float_raise(float_flag_invalid); + + a.low |= 0xC000000000000000U; + + return a; +} + +static void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr, uint64_t *zSigPtr) +{ + int shiftCount = countLeadingZeros64(aSig); + *zSigPtr = aSig << shiftCount; + *zExpPtr = 1 - shiftCount; +} + +inline floatx80 getman(floatx80 src) +{ + const flag sign = (src.high >> 15); + int32_t exp = (src.high & 0x7fff); + uint64_t signific = src.low; + + if (exp == 0x7fff) + { + if ((uint64_t)(signific << 1)) + { + return propagateFloatx80NaNOneArg(src); + } + else + { + return packFloatx80(0, 0xffff, 0xffffffffffffffffU); + } + } + + if (exp == 0) + { + if (signific == 0) + { + return packFloatx80(sign, 0, 0); + } + normalizeFloatx80Subnormal(signific, &exp, &signific); + } + + return packFloatx80(sign, 0x3fff, signific); +} + inline void m68000_base_device::SET_CONDITION_CODES(floatx80 reg) { // u64 *regi; @@ -347,6 +394,10 @@ u8 m68000_base_device::READ_EA_8(int ea) { return REG_D()[reg]; } + case 1: // An + { + return REG_A()[reg]; + } case 2: // (An) { u32 ea = REG_A()[reg]; @@ -423,6 +474,10 @@ u16 m68000_base_device::READ_EA_16(int ea) { return (u16)(REG_D()[reg]); } + case 1: // An + { + return (u16)REG_A()[reg]; + } case 2: // (An) { u32 ea = REG_A()[reg]; @@ -500,6 +555,10 @@ u32 m68000_base_device::READ_EA_32(int ea) { return REG_D()[reg]; } + case 1: // An + { + return REG_A()[reg]; + } case 2: // (An) { u32 ea = REG_A()[reg]; @@ -1106,6 +1165,13 @@ void m68000_base_device::WRITE_EA_FPE(int mode, int reg, floatx80 fpr, uint32 di break; } + case 6: // (An) + (Xn) + d8 + { + u32 ea = EA_AY_IX_32(); + store_extended_float80(ea, fpr); + break; + } + case 7: { switch (reg) @@ -1163,11 +1229,11 @@ void m68000_base_device::WRITE_EA_PACK(int ea, int k, floatx80 fpr) void m68000_base_device::fpgen_rm_reg(u16 w2) { - int ea = m_ir & 0x3f; - int rm = (w2 >> 14) & 0x1; - int src = (w2 >> 10) & 0x7; - int dst = (w2 >> 7) & 0x7; - int opmode = w2 & 0x7f; + const int ea = m_ir & 0x3f; + const int rm = (w2 >> 14) & 0x1; + const int src = (w2 >> 10) & 0x7; + const int dst = (w2 >> 7) & 0x7; + const int opmode = w2 & 0x7f; floatx80 source; // fmovecr #$f, fp0 f200 5c0f @@ -1383,7 +1449,7 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) } case 0x06: // FLOGNP1 { - m_fpr[dst] = floatx80_flognp1 (source); + m_fpr[dst] = floatx80_flognp1(source); SET_CONDITION_CODES(m_fpr[dst]); m_icount -= 594; // for MC68881 break; @@ -1460,6 +1526,13 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) m_icount -= 6; break; } + case 0x1f: // FGETMAN + { + m_fpr[dst] = getman(source); + SET_CONDITION_CODES(m_fpr[dst]); + m_icount -= 31; + break; + } case 0x60: // FSDIVS case 0x20: // FDIV { @@ -1534,6 +1607,24 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) m_icount -= 9; break; } + case 0x30: // FSINCOS + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + { + m_fpr[dst] = source; + floatx80_fsin(m_fpr[dst]); + SET_CONDITION_CODES(m_fpr[dst]); // condition codes are set for the sine result + + m_fpr[(w2 & 0x7)] = source; + floatx80_fcos(m_fpr[(w2 & 0x7)]); + m_icount -= 451; + break; + } case 0x38: // FCMP { floatx80 res; @@ -1743,17 +1834,6 @@ void m68000_base_device::fmovem(u16 w2) int mode = (w2 >> 11) & 0x3; int reglist = w2 & 0xff; - u32 mem_addr = 0; - switch (ea >> 3) - { - case 5: // (d16, An) - mem_addr= EA_AY_DI_32(); - break; - case 6: // (An) + (Xn) + d8 - mem_addr= EA_AY_IX_32(); - break; - } - if (dir) // From FP regs to mem { switch (mode) @@ -1797,8 +1877,7 @@ void m68000_base_device::fmovem(u16 w2) { int imode = (ea >> 3) & 0x7; int reg = (ea & 0x7); - int di_mode = imode == 5; - + int di_mode = (imode == 5); uint32 di_mode_ea = di_mode ? (REG_A()[reg] + MAKE_INT_16(m68ki_read_imm_16())) : 0; for (i=0; i < 8; i++) @@ -1832,23 +1911,17 @@ void m68000_base_device::fmovem(u16 w2) { int imode = (ea >> 3) & 0x7; int reg = (ea & 0x7); - int di_mode = imode == 5; + int di_mode = (imode == 5); uint32 di_mode_ea = di_mode ? (REG_A()[reg] + MAKE_INT_16(m68ki_read_imm_16())) : 0; for (i=0; i < 8; i++) { if (reglist & (1 << i)) { - switch (ea >> 3) + m_fpr[7 - i] = READ_EA_FPE(imode, reg, di_mode_ea); + if (di_mode) { - case 5: // (d16, An) - case 6: // (An) + (Xn) + d8 - m_fpr[7-i] = load_extended_float80(mem_addr); - mem_addr += 12; - break; - default: - m_fpr[7 - i] = READ_EA_FPE(imode, reg, di_mode_ea); - break; + di_mode_ea += 12; } m_icount -= 2; } diff --git a/src/devices/cpu/m88000/m88000.cpp b/src/devices/cpu/m88000/m88000.cpp index 130888d8cc3..b45a74b830e 100644 --- a/src/devices/cpu/m88000/m88000.cpp +++ b/src/devices/cpu/m88000/m88000.cpp @@ -996,14 +996,14 @@ void mc88100_device::execute(u32 const inst) break; case 0x740: // ff1: find first bit set { - unsigned const count = count_leading_zeros(m_r[S2]); + unsigned const count = count_leading_zeros_32(m_r[S2]); m_r[D] = (count == 32) ? count : 31 - count; } break; case 0x760: // ff0: find first bit clear { - unsigned const count = count_leading_ones(m_r[S2]); + unsigned const count = count_leading_ones_32(m_r[S2]); m_r[D] = (count == 32) ? count : 31 - count; } diff --git a/src/devices/cpu/mips/r4000.cpp b/src/devices/cpu/mips/r4000.cpp index eb2cff471d2..2b12a2089f5 100644 --- a/src/devices/cpu/mips/r4000.cpp +++ b/src/devices/cpu/mips/r4000.cpp @@ -1175,7 +1175,7 @@ void r4000_base_device::cpu_exception(u32 exception, u16 const vector) u32 const iphw = CAUSE & SR & CAUSE_IPHW; if (iphw) - debug()->interrupt_hook(22 - count_leading_zeros((iphw - 1) & ~iphw)); + debug()->interrupt_hook(22 - count_leading_zeros_32((iphw - 1) & ~iphw)); } } else @@ -1530,7 +1530,7 @@ void r4000_base_device::cp0_tlbwi(u8 const index) entry.pfn[0] = m_cp0[CP0_EntryLo0] & EL_WM; entry.pfn[1] = m_cp0[CP0_EntryLo1] & EL_WM; - entry.low_bit = 32 - count_leading_zeros((entry.mask >> 1) | 0xfff); + entry.low_bit = 32 - count_leading_zeros_32((entry.mask >> 1) | 0xfff); LOGMASKED(LOG_TLB, "tlb write index %02d mask 0x%016x vpn2 0x%016x %c asid 0x%02x pfn0 0x%016x %c%c pfn1 0x%016x %c%c (%s)\n", index, entry.mask, diff --git a/src/devices/cpu/pdp8/hd6120.cpp b/src/devices/cpu/pdp8/hd6120.cpp index ec72498d272..947225ae603 100644 --- a/src/devices/cpu/pdp8/hd6120.cpp +++ b/src/devices/cpu/pdp8/hd6120.cpp @@ -86,20 +86,34 @@ Register”), PC and the two stack pointers, include several which are only implicitly used in execution: a TEMP register that latches ALU outputs, the instruction register IR, and the output latch register OL - that holds all addresses and data to be output on the DX bus. HD-6120 - also internally maintains a group of 3-bit registers whose path - connects to TEMP, each of which contains the current memory extension - fields, their mirrors or various flags. (This emulation extends the - field registers to 4 bits to include the CTRLFF, PDF and PEX flags, - which are neither readable nor output directly at any time.) - Particular flag registers are enabled on the C0, C1 and EMA2 lines - during the final writes of ISZ, DCA and JMS. The most important of - these flag registers includes LINK, the interrupt enable flip-flop and - the GT flag hitherto provided only on arithmetic extensions of some - previous PDP-8 CPUs, though like MQ it conveys no specific purpose - here. Another flag register contains the inverse of the active-low - INTREQ input, the PWRON flag (set if STRTUP = VSS at RESET time, - causing entry into panel mode) and 0 in its LSB. + that holds all addresses and data to be output on the DX bus. + + HD-6120 also maintains a group of 3-bit internal registers whose data + path connects to TEMP. These are used to hold the current memory + extension fields, their mirrors and various flags. (This emulation + extends the field registers to 4 bits to include the CTRLFF, PDF and + PEX flags, which are neither readable nor output directly at any + time.) These 3-bit registers may be enabled on the C0, C1 and EMA2 + lines at particular times, and the GTF, GCF, PRS, RDF, RIF and RIB + internal IOTs read various combinations of them into AC. They include: + + MSB LSB Output conditions + ----------------------------------------- + IF0 IF1 IF2 IFETCH, direct operands (except if FZ) + IB0 IB1 IB2 None (until transferred to IF) + ISF0 ISF1 ISF2 None + DF0 DF1 DF2 Indirect operand addressing, IOTs, etc. + DSF0 DSF1 DSF2 None + LINK GT IEFF DCA AC writes + INTREQ* PWRON 0 ISZ result writes + BTSTRAP PNLTRP HLTFLG JMS PC writes + + The GT flag, like MQ, is not used for any specific purpose on the + HD-6120, unlike the arithmetic extensions of previous PDP-8 CPUs which + originally implemented them. The INTREQ flag is 1 when the input pin + is sampled active low and 0 when it is inactive. The PWRON flag is set + if STRTUP is sampled as VSS at RESET time; it causes the CPU to trap + into panel mode before executing its first instruction. Undefined Group 3 OPRs and internal IOTs have no effect on the HD-6120 except that both interrupts and panel requests are blocked @@ -1001,6 +1015,7 @@ void hd6120_device::execute_run() break; case minor_state::PEX_1: + m_temp = m_ac; m_state = minor_state::PEX_2; break; diff --git a/src/devices/cpu/psx/gte.cpp b/src/devices/cpu/psx/gte.cpp index d48b206e84f..6305b4d7412 100644 --- a/src/devices/cpu/psx/gte.cpp +++ b/src/devices/cpu/psx/gte.cpp @@ -215,7 +215,7 @@ void gte::setcp2dr( uint32_t pc, int reg, uint32_t value ) break; case 30: - LZCR = (value & 0x80000000) == 0 ? count_leading_zeros(value) : count_leading_ones(value); + LZCR = (value & 0x80000000) == 0 ? count_leading_zeros_32(value) : count_leading_ones_32(value); break; case 31: @@ -314,7 +314,7 @@ static inline uint32_t gte_divide( uint16_t numerator, uint16_t denominator ) 0x00 }; - int shift = count_leading_zeros( denominator ) - 16; + int shift = count_leading_zeros_32( denominator ) - 16; int r1 = ( denominator << shift ) & 0x7fff; int r2 = table[ ( ( r1 + 0x40 ) >> 7 ) ] + 0x101; diff --git a/src/devices/cpu/romp/romp.cpp b/src/devices/cpu/romp/romp.cpp index d68988cb876..94e3da8591c 100644 --- a/src/devices/cpu/romp/romp.cpp +++ b/src/devices/cpu/romp/romp.cpp @@ -887,7 +887,7 @@ void romp_device::execute_run() flags_log(m_gpr[R2]); break; case 0xf5: // clz: count leading zeros - m_gpr[R2] = count_leading_zeros(u16(m_gpr[R3])) - 16; + m_gpr[R2] = count_leading_zeros_32(u16(m_gpr[R3])) - 16; break; case 0xf9: // mc03: move character zero from three diff --git a/src/devices/cpu/sharc/sharc.cpp b/src/devices/cpu/sharc/sharc.cpp index ded941af415..134611079a8 100644 --- a/src/devices/cpu/sharc/sharc.cpp +++ b/src/devices/cpu/sharc/sharc.cpp @@ -343,7 +343,10 @@ void adsp21062_device::iop_w(offs_t offset, uint32_t data) case 0x1c: { m_core->dma[6].control = data; - sharc_iop_delayed_w(0x1c, data, 1); + if (data & 0x1) + { + sharc_iop_delayed_w(0x1c, data, 1); + } break; } @@ -360,9 +363,12 @@ void adsp21062_device::iop_w(offs_t offset, uint32_t data) // DMA 7 case 0x1d: - { + { m_core->dma[7].control = data; - sharc_iop_delayed_w(0x1d, data, 30); + if (data & 0x1) + { + sharc_iop_delayed_w(0x1d, data, 30); + } break; } @@ -442,7 +448,7 @@ void adsp21062_device::external_dma_write(uint32_t address, uint64_t data) All addresses in the 17-bit index registers are offset by 0x0002 0000, the first internal RAM location, before they are used by the DMA controller. */ - + switch ((m_core->dma[6].control >> 6) & 0x3) { case 2: // 16/48 packing @@ -972,6 +978,19 @@ void adsp21062_device::set_flag_input(int flag_num, int state) } } +WRITE_LINE_MEMBER(adsp21062_device::write_stall) +{ + m_core->write_stalled = (state == 0) ? false : true; + + if (m_enable_drc) + { + if (m_core->write_stalled) + spin_until_trigger(45757); + else + machine().scheduler().trigger(45757); + } +} + void adsp21062_device::check_interrupts() { int i; @@ -1028,8 +1047,24 @@ void adsp21062_device::execute_run() } else { + if (m_core->write_stalled) + eat_cycles(m_core->icount); + if (m_core->idle && m_core->irq_pending == 0) { + int dma_count = m_core->icount; + + // run active DMAs even while idling + while (dma_count > 0 && m_core->dma_status & ((1 << 6) | (1 << 7))) + { + if (!m_core->write_stalled) + { + dma_run_cycle(6); + dma_run_cycle(7); + } + dma_count--; + } + m_core->icount = 0; debugger_instruction_hook(m_core->daddr); } @@ -1037,9 +1072,9 @@ void adsp21062_device::execute_run() { check_interrupts(); m_core->idle = 0; - } + } - while (m_core->icount > 0 && !m_core->idle) + while (m_core->icount > 0 && !m_core->idle && !m_core->write_stalled) { m_core->pc = m_core->daddr; m_core->daddr = m_core->faddr; @@ -1126,6 +1161,12 @@ void adsp21062_device::execute_run() } } + if (!m_core->write_stalled) + { + dma_run_cycle(6); + dma_run_cycle(7); + } + --m_core->icount; }; } diff --git a/src/devices/cpu/sharc/sharc.h b/src/devices/cpu/sharc/sharc.h index 6c9292c5193..f7d2d8701cd 100644 --- a/src/devices/cpu/sharc/sharc.h +++ b/src/devices/cpu/sharc/sharc.h @@ -103,6 +103,8 @@ public: TIMER_CALLBACK_MEMBER(sharc_iop_delayed_write_callback); TIMER_CALLBACK_MEMBER(sharc_dma_callback); + WRITE_LINE_MEMBER(write_stall); + void sharc_cfunc_unimplemented(); void sharc_cfunc_read_iop(); void sharc_cfunc_write_iop(); @@ -270,6 +272,7 @@ private: int32_t chained_direction; emu_timer *timer; bool active; + bool chained; }; @@ -379,6 +382,7 @@ private: SHARC_DMA_OP dma_op[12]; uint32_t dma_status; + bool write_stalled; int32_t interrupt_active; @@ -475,6 +479,7 @@ private: void schedule_dma_op(int channel, uint32_t src, uint32_t dst, int src_modifier, int dst_modifier, int src_count, int dst_count, int pmode); void dma_op(int channel); void sharc_dma_exec(int channel); + void dma_run_cycle(int channel); void add_systemreg_write_latency_effect(int sysreg, uint32_t data, uint32_t prev_data); inline void swap_register(uint32_t *a, uint32_t *b); void systemreg_write_latency_effect(); diff --git a/src/devices/cpu/sharc/sharcdma.hxx b/src/devices/cpu/sharc/sharcdma.hxx index fdbf7a0f635..e0df2cb5e54 100644 --- a/src/devices/cpu/sharc/sharcdma.hxx +++ b/src/devices/cpu/sharc/sharcdma.hxx @@ -10,7 +10,7 @@ void adsp21062_device::schedule_chained_dma_op(int channel, uint32_t dma_chain_ptr, int chained_direction) { - uint32_t op_ptr = 0x20000 + dma_chain_ptr; + uint32_t op_ptr = 0x20000 + (dma_chain_ptr & 0x1ffff); uint32_t int_index = dm_read32(op_ptr - 0); uint32_t int_modifier = dm_read32(op_ptr - 1); @@ -49,10 +49,14 @@ void adsp21062_device::schedule_chained_dma_op(int channel, uint32_t dma_chain_p m_core->dma_op[channel].chain_ptr = chain_ptr; m_core->dma_op[channel].chained_direction = chained_direction; + m_core->dma_op[channel].chained = true; m_core->dma_op[channel].active = true; - int cycles = m_core->dma_op[channel].src_count / 4; - m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel); + if (m_enable_drc) + { + int cycles = m_core->dma_op[channel].src_count / 4; + m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel); + } // enable busy flag m_core->dma_status |= (1 << channel); @@ -74,15 +78,107 @@ void adsp21062_device::schedule_dma_op(int channel, uint32_t src, uint32_t dst, m_core->dma_op[channel].pmode = pmode; m_core->dma_op[channel].chain_ptr = 0; + m_core->dma_op[channel].chained = false; m_core->dma_op[channel].active = true; - int cycles = src_count / 4; - m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel); + if (m_enable_drc) + { + int cycles = src_count / 4; + m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel); + } // enable busy flag m_core->dma_status |= (1 << channel); } +void adsp21062_device::dma_run_cycle(int channel) +{ + if (m_core->dma_status & (1 << channel)) + { + uint32_t src = m_core->dma_op[channel].src; + uint32_t dst = m_core->dma_op[channel].dst; + int src_modifier = m_core->dma_op[channel].src_modifier; + int dst_modifier = m_core->dma_op[channel].dst_modifier; + int src_count = m_core->dma_op[channel].src_count; + //int dst_count = m_core->dma_op[channel].dst_count; + int pmode = m_core->dma_op[channel].pmode; + + switch (pmode) + { + case DMA_PMODE_NO_PACKING: + { + uint32_t data = dm_read32(src); + dm_write32(dst, data); + src += src_modifier; + dst += dst_modifier; + src_count--; + break; + } + case DMA_PMODE_16_32: + { + uint32_t data = ((dm_read32(src + 0) & 0xffff) << 16) | (dm_read32(src + 1) & 0xffff); + + dm_write32(dst, data); + src += src_modifier * 2; + dst += dst_modifier; + src_count -= 2; + break; + } + case DMA_PMODE_8_48: + { + uint64_t data = ((uint64_t)(dm_read32(src + 0) & 0xff) << 0) | + ((uint64_t)(dm_read32(src + 1) & 0xff) << 8) | + ((uint64_t)(dm_read32(src + 2) & 0xff) << 16) | + ((uint64_t)(dm_read32(src + 3) & 0xff) << 24) | + ((uint64_t)(dm_read32(src + 4) & 0xff) << 32) | + ((uint64_t)(dm_read32(src + 5) & 0xff) << 40); + + pm_write48(dst, data); + src += src_modifier * 6; + dst += dst_modifier; + src_count -= 6; + break; + } + default: + { + fatalerror("SHARC: dma_op: unimplemented packing mode %d\n", pmode); + } + } + + m_core->dma_op[channel].src_count = src_count; + m_core->dma_op[channel].src = src; + m_core->dma_op[channel].dst = dst; + + if (src_count <= 0) + { + // clear busy flag + m_core->dma_status &= ~(1 << channel); + + m_core->dma_op[channel].active = false; + + // raise interrupt if + // * non-chained DMA + // * chained-DMA with PCI set in the next chain pointer + if (!m_core->dma_op[channel].chained || (m_core->dma_op[channel].chained && (m_core->dma_op[channel].chain_ptr & 0x20000))) + { + m_core->irptl |= (1 << (channel + 10)); + + // DMA interrupt + if (m_core->imask & (1 << (channel + 10))) + { + m_core->irq_pending |= 1 << (channel + 10); + } + } + + // schedule chained op if chaining + if ((m_core->dma_op[channel].chain_ptr & 0x1ffff) != 0) + { + schedule_chained_dma_op(channel, m_core->dma_op[channel].chain_ptr, m_core->dma_op[channel].chained_direction); + } + } + } +} + void adsp21062_device::dma_op(int channel) { int i; @@ -94,7 +190,7 @@ void adsp21062_device::dma_op(int channel) //int dst_count = m_core->dma_op[channel].dst_count; int pmode = m_core->dma_op[channel].pmode; - //printf("dma_op: %08X, %08X, %08X, %08X, %08X, %d\n", src, dst, src_modifier, dst_modifier, src_count, pmode); + //printf("dma_op: ch %d: %08X, %08X, %08X, %08X, %08X, %d at %08X\n", channel, src, dst, src_modifier, dst_modifier, src_count, pmode, m_core->pc); switch (pmode) { @@ -191,36 +287,36 @@ void adsp21062_device::sharc_dma_exec(int channel) { uint32_t dma_chain_ptr = m_core->dma[channel].chain_ptr & 0x1ffff; - schedule_chained_dma_op(channel, dma_chain_ptr, tran); + schedule_chained_dma_op(channel, dma_chain_ptr, tran); } else { if (tran) // Transmit to external { - dst = m_core->dma[channel].ext_index; - dst_modifier = m_core->dma[channel].ext_modifier; - dst_count = m_core->dma[channel].ext_count; - src = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000; - src_modifier = m_core->dma[channel].int_modifier; - src_count = m_core->dma[channel].int_count; + dst = m_core->dma[channel].ext_index; + dst_modifier = m_core->dma[channel].ext_modifier; + dst_count = m_core->dma[channel].ext_count; + src = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000; + src_modifier = m_core->dma[channel].int_modifier; + src_count = m_core->dma[channel].int_count; } else // Receive from external { - src = m_core->dma[channel].ext_index; - src_modifier = m_core->dma[channel].ext_modifier; - src_count = m_core->dma[channel].ext_count; - dst = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000; - dst_modifier = m_core->dma[channel].int_modifier; - dst_count = m_core->dma[channel].int_count; + src = m_core->dma[channel].ext_index; + src_modifier = m_core->dma[channel].ext_modifier; + src_count = m_core->dma[channel].ext_count; + dst = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000; + dst_modifier = m_core->dma[channel].int_modifier; + dst_count = m_core->dma[channel].int_count; } if (dtype) - //if (src_count != dst_count) + //if (src_count != dst_count) { pmode = DMA_PMODE_8_48; } - schedule_dma_op(channel, src, dst, src_modifier, dst_modifier, src_count, dst_count, pmode); + schedule_dma_op(channel, src, dst, src_modifier, dst_modifier, src_count, dst_count, pmode); } } @@ -239,7 +335,7 @@ TIMER_CALLBACK_MEMBER(adsp21062_device::sharc_dma_callback) } dma_op(channel); - if (m_core->dma_op[channel].chain_ptr != 0) + if ((m_core->dma_op[channel].chain_ptr & 0x1ffff) != 0) { schedule_chained_dma_op(channel, m_core->dma_op[channel].chain_ptr, m_core->dma_op[channel].chained_direction); } diff --git a/src/devices/cpu/tms32031/32031ops.hxx b/src/devices/cpu/tms32031/32031ops.hxx index da59340b7d9..06533f09abb 100644 --- a/src/devices/cpu/tms32031/32031ops.hxx +++ b/src/devices/cpu/tms32031/32031ops.hxx @@ -393,7 +393,7 @@ void tms3203x_device::int2float(tmsreg &srcdst) // positive values; count leading zeros and shift else if ((int32_t)man > 0) { - cnt = count_leading_zeros(man); + cnt = count_leading_zeros_32(man); man <<= cnt; exp = 31 - cnt; } @@ -401,7 +401,7 @@ void tms3203x_device::int2float(tmsreg &srcdst) // negative values; count leading ones and shift else { - cnt = count_leading_ones(man); + cnt = count_leading_ones_32(man); man <<= cnt; exp = 31 - cnt; } @@ -585,13 +585,13 @@ void tms3203x_device::addf(tmsreg &dst, tmsreg &src1, tmsreg &src2) { if (man > 0) { - cnt = count_leading_zeros((uint32_t)man); + cnt = count_leading_zeros_32((uint32_t)man); man <<= cnt; exp -= cnt; } else { - cnt = count_leading_ones((uint32_t)man); + cnt = count_leading_ones_32((uint32_t)man); man <<= cnt; exp -= cnt; } @@ -698,13 +698,13 @@ void tms3203x_device::subf(tmsreg &dst, tmsreg &src1, tmsreg &src2) { if (man > 0) { - cnt = count_leading_zeros((uint32_t)man); + cnt = count_leading_zeros_32((uint32_t)man); man <<= cnt; exp -= cnt; } else { - cnt = count_leading_ones((uint32_t)man); + cnt = count_leading_ones_32((uint32_t)man); man <<= cnt; exp -= cnt; } @@ -847,13 +847,13 @@ void tms3203x_device::norm(tmsreg &dst, tmsreg &src) int cnt; if (man > 0) { - cnt = count_leading_zeros((uint32_t)man); + cnt = count_leading_zeros_32((uint32_t)man); man <<= cnt; exp -= cnt; } else { - cnt = count_leading_ones((uint32_t)man); + cnt = count_leading_ones_32((uint32_t)man); man <<= cnt; exp -= cnt; } diff --git a/src/devices/cpu/tms34010/34010ops.hxx b/src/devices/cpu/tms34010/34010ops.hxx index 1c71439107e..aa398e3c776 100644 --- a/src/devices/cpu/tms34010/34010ops.hxx +++ b/src/devices/cpu/tms34010/34010ops.hxx @@ -2458,16 +2458,16 @@ void tms340x0_device::setcdp(uint16_t op) // .. only single bit set, pitch is power of two! case 1: { - m_convdp = 32 - count_leading_zeros(dptch); + m_convdp = 32 - count_leading_zeros_32(dptch); COUNT_CYCLES(4); return; } // .. two bits, we can decompose it to sum of two power of two numbers case 2: { - uint8_t first_one = count_leading_zeros(dptch); + uint8_t first_one = count_leading_zeros_32(dptch); uint8_t v1 = 32 - first_one; - uint8_t v2 = 32 - count_leading_zeros(dptch & ~(1 << (first_one - 1))); + uint8_t v2 = 32 - count_leading_zeros_32(dptch & ~(1 << (first_one - 1))); m_convdp = v2 | (v1 << 8); COUNT_CYCLES(6); diff --git a/src/devices/cpu/uml.cpp b/src/devices/cpu/uml.cpp index 8b0c7023f58..6a81d63400e 100644 --- a/src/devices/cpu/uml.cpp +++ b/src/devices/cpu/uml.cpp @@ -631,14 +631,9 @@ void uml::instruction::simplify() if (m_param[1].is_immediate()) { if (m_size == 4) - convert_to_mov_immediate(count_leading_zeros(m_param[1].immediate())); + convert_to_mov_immediate(count_leading_zeros_32(m_param[1].immediate())); else if (m_size == 8) - { - if ((m_param[1].immediate() >> 32) == 0) - convert_to_mov_immediate(32 + count_leading_zeros(m_param[1].immediate())); - else - convert_to_mov_immediate(count_leading_zeros(m_param[1].immediate() >> 32)); - } + convert_to_mov_immediate(count_leading_zeros_64(m_param[1].immediate())); } break; diff --git a/src/devices/cpu/unsp/unsp_fxxx.cpp b/src/devices/cpu/unsp/unsp_fxxx.cpp index 4c1f41245ad..13b7bd27995 100644 --- a/src/devices/cpu/unsp/unsp_fxxx.cpp +++ b/src/devices/cpu/unsp/unsp_fxxx.cpp @@ -396,11 +396,11 @@ void unsp_12_device::execute_fxxx_101_group(uint16_t op) if (r4 & 0x8000) { - m_core->m_r[REG_R2] = count_leading_ones(0xffff0000 | r4) - 17; + m_core->m_r[REG_R2] = count_leading_ones_32(0xffff0000 | r4) - 17; } else { - m_core->m_r[REG_R2] = count_leading_zeros(r4) - 17; // -17 because count_leading_zeros works with 32-bit values + m_core->m_r[REG_R2] = count_leading_zeros_32(r4) - 17; // -17 because count_leading_zeros_32 works with 32-bit values } return; diff --git a/src/devices/cpu/z80/kp69.cpp b/src/devices/cpu/z80/kp69.cpp index 84be060c4c7..0e194138b2c 100644 --- a/src/devices/cpu/z80/kp69.cpp +++ b/src/devices/cpu/z80/kp69.cpp @@ -409,14 +409,14 @@ int kp69_base_device::z80daisy_irq_ack() // Restrict to high-priority interrupts if any of those are pending if ((m_irr & m_pgr) != 0) { - level = 31 - count_leading_zeros(u32(m_irr & m_pgr)); + level = 31 - count_leading_zeros_32(u32(m_irr & m_pgr)); assert(level >= 0 && level < 16); if ((1 << level) < (m_isr & m_pgr)) level = -1; } else if (m_irr != 0 && (m_isr & m_pgr) == 0) { - level = 31 - count_leading_zeros(u32(m_irr)); + level = 31 - count_leading_zeros_32(u32(m_irr)); assert(level >= 0 && level < 16); if ((1 << level) < m_isr) level = -1; @@ -461,7 +461,7 @@ void kp69_base_device::z80daisy_irq_reti() } else if (m_isr != 0) { - int level = 31 - count_leading_zeros(u32((m_isr & m_pgr) != 0 ? (m_isr & m_pgr) : m_isr)); + int level = 31 - count_leading_zeros_32(u32((m_isr & m_pgr) != 0 ? (m_isr & m_pgr) : m_isr)); assert(level >= 0 && level < 16); m_isr &= ~(1 << level); |
