diff options
Diffstat (limited to 'src/devices')
29 files changed, 645 insertions, 321 deletions
diff --git a/src/devices/bus/isa/3c505.cpp b/src/devices/bus/isa/3c505.cpp index 622a11d48dd..cdf1f26e88e 100644 --- a/src/devices/bus/isa/3c505.cpp +++ b/src/devices/bus/isa/3c505.cpp @@ -12,14 +12,12 @@ * http://lxr.free-electrons.com/source/drivers/net/3c505.h * http://lxr.free-electrons.com/source/drivers/net/3c505.c * http://stason.org/TULARC/pc/network-cards/O/OLIVETTI-Ethernet-NPU-9144-3C505.html - * http://www.bitsavers.org/pdf/3Com/3c505_Etherlink_Plus_Developers_Guide_May86.pdf' + * http://www.bitsavers.org/pdf/3Com/3c505_Etherlink_Plus_Developers_Guide_May86.pdf * http://www.bitsavers.org/pdf/3Com/1569-03_EtherLink_Plus_Technical_Reference_Jan89.pdf * * TODO * - resolve intermittent diagnostics bug on 8-bit dma channels - * - testing on Apollo Domain/OS - * - externalize mac address - * - 8 bit isa slot support + * - 8-bit isa slot support * - revision 1.0 and 2.0 hardware/firmware variants * - 8023 loopback mode */ @@ -42,14 +40,19 @@ ROM_START(3c505) ROM_LOAD16_BYTE("0729-12_a.3h", 0x00000, 0x02000, CRC(5415fccd) SHA1(6a42d7f3acdb3e0213e1037fee1864819ac33991)) ROM_LOAD16_BYTE("0729-62_a.3f", 0x00001, 0x02000, CRC(4240bd9d) SHA1(015d2f7282def85681bcf1a7c5a7f501a16d5a6c)) - ROM_REGION(0x02000, "host", 0) ROM_SYSTEM_BIOS(0, "unused", "Unused") - ROM_SYSTEM_BIOS(1, "apollo", "Apollo") - ROMX_LOAD("3000_3c505_010728-00.bin", 0x00000, 0x02000, CRC(69b77ec6) SHA1(7ac36cc6fc90b90ddfc56c45303b514cbe18ae58), ROM_BIOS(1)) - ROM_SYSTEM_BIOS(2, "netware", "3C505-NW EtherLink Plus NetWare Boot PROM") + + // host firmware + ROM_REGION(0x02000, "host", 0) + ROMX_LOAD("3000_3c505_010728-00.bin", 0x00000, 0x02000, CRC(69b77ec6) SHA1(7ac36cc6fc90b90ddfc56c45303b514cbe18ae58), ROM_BIOS(1)) ROMX_LOAD("3c505-nw.bin", 0x00000, 0x02000, NO_DUMP, ROM_BIOS(2)) + + // station address prom + ROM_REGION16_LE(0x10, "mac", 0) + ROM_LOAD("3com.9h", 0x00, 0x10, CRC(8e207354) SHA1(ca5ddcb272ab2851e00473dc960b23039746e3d2)) + ROMX_LOAD("apollo.9h", 0x00, 0x10, CRC(490f283e) SHA1(fe4c26b6a41e643f4397990b066fdc04b6f4c5ae), ROM_BIOS(1)) ROM_END static INPUT_PORTS_START(3c505) @@ -349,14 +352,7 @@ void isa16_3c505_device::map_io(address_map &map) map(0x0103, 0x0103).rw(FUNC(isa16_3c505_device::asr_r), FUNC(isa16_3c505_device::acr_w)); map(0x0104, 0x0105).rw(FUNC(isa16_3c505_device::adata_r), FUNC(isa16_3c505_device::adata_w)); - map(0x0180, 0x018f).lr16("mac", - [](offs_t offset) - { - // TODO: hard-code to 3Com dummy address for now - static const u8 mac[] = { 0x02, 0x60, 0x8c, 0x12, 0x34, 0x56, 0xff, 0xff}; - - return mac[offset]; - }); + map(0x0180, 0x018f).rom().region("mac", 0); } void isa16_3c505_device::map_isa(address_map &map) diff --git a/src/devices/cpu/hmcs40/hmcs40d.cpp b/src/devices/cpu/hmcs40/hmcs40d.cpp index 96e4b6399ea..d845b7545ae 100644 --- a/src/devices/cpu/hmcs40/hmcs40d.cpp +++ b/src/devices/cpu/hmcs40/hmcs40d.cpp @@ -11,6 +11,33 @@ #include "emu.h" #include "hmcs40d.h" +// constructor + +hmcs40_disassembler::hmcs40_disassembler() +{ + // init lfsr pc lut + for (u32 i = 0, pc = 0; i < 0x40; i++) + { + m_l2r[i] = pc; + m_r2l[pc] = i; + + // see hmcs40_cpu_device::increment_pc() + u32 mask = 0x3f; + u32 low = pc & mask; + u32 fb = (low << 1 & 0x20) == (low & 0x20); + + if (low == (mask >> 1)) + fb = 1; + else if (low == mask) + fb = 0; + + pc = (pc & ~mask) | ((pc << 1 | fb) & mask); + } +} + + +// common lookup tables + const char *const hmcs40_disassembler::s_mnemonics[] = { "?", @@ -152,6 +179,7 @@ const u8 hmcs40_disassembler::hmcs40_mnemonic[0x400] = }; +// disasm offs_t hmcs40_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { @@ -197,41 +225,3 @@ offs_t hmcs40_disassembler::disassemble(std::ostream &stream, offs_t pc, const d return 1 | s_flags[instr] | SUPPORTED; } - -u32 hmcs40_disassembler::opcode_alignment() const -{ - return 1; -} - -u32 hmcs40_disassembler::interface_flags() const -{ - return NONLINEAR_PC | PAGED; -} - -u32 hmcs40_disassembler::page_address_bits() const -{ - return 6; -} - -offs_t hmcs40_disassembler::pc_linear_to_real(offs_t pc) const -{ - static const u8 l2r[64] = { - 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x3e, 0x3d, 0x3b, 0x37, 0x2f, 0x1e, 0x3c, 0x39, 0x33, - 0x27, 0x0e, 0x1d, 0x3a, 0x35, 0x2b, 0x16, 0x2c, 0x18, 0x30, 0x21, 0x02, 0x05, 0x0b, 0x17, 0x2e, - 0x1c, 0x38, 0x31, 0x23, 0x06, 0x0d, 0x1b, 0x36, 0x2d, 0x1a, 0x34, 0x29, 0x12, 0x24, 0x08, 0x11, - 0x22, 0x04, 0x09, 0x13, 0x26, 0x0c, 0x19, 0x32, 0x25, 0x0a, 0x15, 0x2a, 0x14, 0x28, 0x10, 0x20, - }; - return (pc & ~0x3f) | l2r[pc & 0x3f]; -} - -offs_t hmcs40_disassembler::pc_real_to_linear(offs_t pc) const -{ - static const u8 r2l[64] = { - 0x00, 0x01, 0x1b, 0x02, 0x31, 0x1c, 0x24, 0x03, 0x2e, 0x32, 0x39, 0x1d, 0x35, 0x25, 0x11, 0x04, - 0x3e, 0x2f, 0x2c, 0x33, 0x3c, 0x3a, 0x16, 0x1e, 0x18, 0x36, 0x29, 0x26, 0x20, 0x12, 0x0c, 0x05, - 0x3f, 0x1a, 0x30, 0x23, 0x2d, 0x38, 0x34, 0x10, 0x3d, 0x2b, 0x3b, 0x15, 0x17, 0x28, 0x1f, 0x0b, - 0x19, 0x22, 0x37, 0x0f, 0x2a, 0x14, 0x27, 0x0a, 0x21, 0x0e, 0x13, 0x09, 0x0d, 0x08, 0x07, 0x06, - }; - return (pc & ~0x3f) | r2l[pc & 0x3f]; -} - diff --git a/src/devices/cpu/hmcs40/hmcs40d.h b/src/devices/cpu/hmcs40/hmcs40d.h index 04f534bdc4c..0da5f51d3d9 100644 --- a/src/devices/cpu/hmcs40/hmcs40d.h +++ b/src/devices/cpu/hmcs40/hmcs40d.h @@ -14,14 +14,14 @@ class hmcs40_disassembler : public util::disasm_interface { public: - hmcs40_disassembler() = default; + hmcs40_disassembler(); virtual ~hmcs40_disassembler() = default; - virtual u32 opcode_alignment() const override; - virtual u32 interface_flags() const override; - virtual u32 page_address_bits() const override; - virtual offs_t pc_linear_to_real(offs_t pc) const override; - virtual offs_t pc_real_to_linear(offs_t pc) const override; + virtual u32 opcode_alignment() const override { return 1; } + virtual u32 interface_flags() const override { return NONLINEAR_PC | PAGED; } + virtual u32 page_address_bits() const override { return 6; } + virtual offs_t pc_linear_to_real(offs_t pc) const override { return (pc & ~0x3f) | m_l2r[pc & 0x3f]; } + virtual offs_t pc_real_to_linear(offs_t pc) const override { return (pc & ~0x3f) | m_r2l[pc & 0x3f]; } virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; private: @@ -45,6 +45,9 @@ private: static const s8 s_bits[]; static const u32 s_flags[]; static const u8 hmcs40_mnemonic[0x400]; + + u8 m_l2r[0x40]; + u8 m_r2l[0x40]; }; #endif diff --git a/src/devices/cpu/i386/cpuidmsrs.hxx b/src/devices/cpu/i386/cpuidmsrs.hxx index 8b02d7828cd..f16868216a5 100644 --- a/src/devices/cpu/i386/cpuidmsrs.hxx +++ b/src/devices/cpu/i386/cpuidmsrs.hxx @@ -236,7 +236,7 @@ void athlonxp_device::opcode_cpuid() case 0x80000007: { - REG32(EDX) = 1; + REG32(EDX) = 1; // Advanced power management information, temperature sensor present CYCLES(CYCLES_CPUID); break; } @@ -368,7 +368,21 @@ uint64_t athlonxp_device::opcode_rdmsr(bool &valid_msr) break; case 0xC001001D: // TOP_MEM2 break; + case 0xC0010111: // SMM_BASE + // address of system management mode area + ret = (uint64_t)m_msr_smm_base; + break; case 0xC0010113: // SMM_MASK + // 1 TValid - Enable TSeg SMRAM Range + // 0 AValid - Enable ASeg SMRAM Range + /* Access to the ASeg (a0000-bffff) depends on bit 0 of smm_mask + if the bit is 0 use the associated fixed mtrr + if the bit is 1 + if smm is active + access goes to dram (wrmem 1 rdmem 1) + if smm not active + access goes to mmio (wrmem 0 rdmem 0) */ + ret = m_msr_smm_mask; break; } valid_msr = true; @@ -414,6 +428,11 @@ void athlonxp_device::opcode_wrmsr(uint64_t data, bool &valid_msr) break; case 0x259: // MTRRfix16K_A0000 m_msr_mtrrfix[2] = data; + if (m_msr_smm_mask & 1) + { + // data = 0x1818181818181818; // when smm is implemented + data = 0; // when smm is not active + } parse_mtrrfix(data, 0xa0000, 16); break; case 0x268: // MTRRfix4K_C0000-F8000 @@ -448,7 +467,19 @@ void athlonxp_device::opcode_wrmsr(uint64_t data, bool &valid_msr) case 0xC001001A: // TOP_MEM m_msr_top_mem = (offs_t)data; break; + case 0xC0010111: // SMM_BASE + m_msr_smm_base = (offs_t)data; + break; case 0xC0010113: // SMM_MASK + m_msr_smm_mask = data; + if (m_msr_smm_mask & 1) + { + // data = 0x1818181818181818; // when smm is implemented + data = 0; // when smm is not active + } + else + data = m_msr_mtrrfix[2]; + parse_mtrrfix(data, 0xa0000, 16); break; } valid_msr = true; diff --git a/src/devices/cpu/i386/i386.cpp b/src/devices/cpu/i386/i386.cpp index 97dd5e5a8b6..6256b4de996 100644 --- a/src/devices/cpu/i386/i386.cpp +++ b/src/devices/cpu/i386/i386.cpp @@ -4708,6 +4708,8 @@ void athlonxp_device::device_start() save_item(NAME(m_processor_name_string)); save_item(NAME(m_msr_top_mem)); save_item(NAME(m_msr_sys_cfg)); + save_item(NAME(m_msr_smm_base)); + save_item(NAME(m_msr_smm_mask)); save_item(NAME(m_msr_mtrrfix)); save_item(NAME(m_memory_ranges_1m)); } @@ -4761,6 +4763,8 @@ void athlonxp_device::device_reset() m_memory_ranges_1m[n] = 0; m_msr_top_mem = 1024 * 1024; m_msr_sys_cfg = 0; + m_msr_smm_base = 0x30000; + m_msr_smm_mask = 0; m_cpuid_max_input_value_eax = 0x01; m_cpu_version = REG32(EDX); diff --git a/src/devices/cpu/i386/i386.h b/src/devices/cpu/i386/i386.h index e3182fcfb81..42eed546f41 100644 --- a/src/devices/cpu/i386/i386.h +++ b/src/devices/cpu/i386/i386.h @@ -1677,6 +1677,8 @@ private: uint8_t m_processor_name_string[48]; offs_t m_msr_top_mem; uint64_t m_msr_sys_cfg; + offs_t m_msr_smm_base; + uint64_t m_msr_smm_mask; uint64_t m_msr_mtrrfix[11]; uint8_t m_memory_ranges_1m[1024 / 4]; cpucache<17, 9, Cache2Way, CacheLineBytes64> cache; // 512 sets, 2 ways (cachelines per set), 64 bytes per cacheline diff --git a/src/devices/cpu/mips/mips1.cpp b/src/devices/cpu/mips/mips1.cpp index 1ed202c0d63..a5f99fcc993 100644 --- a/src/devices/cpu/mips/mips1.cpp +++ b/src/devices/cpu/mips/mips1.cpp @@ -1408,10 +1408,23 @@ void mips1_device_base::handle_cop1(u32 const op) if (f32_lt(float32_t{ u32(m_f[FSREG >> 1]) }, float32_t{ 0 })) set_cop1_reg(FDREG >> 1, f32_mul(float32_t{ u32(m_f[FSREG >> 1]) }, i32_to_f32(-1)).v); else - set_cop1_reg(FDREG >> 1, m_f[FSREG >> 1]); + set_cop1_reg(FDREG >> 1, u32(m_f[FSREG >> 1])); break; case 0x06: // MOV.S - m_f[FDREG >> 1] = m_f[FSREG >> 1]; + if (FDREG & 1) + if (FSREG & 1) + // move high half to high half + m_f[FDREG >> 1] = (m_f[FSREG >> 1] & ~0xffffffffULL) | u32(m_f[FDREG >> 1]); + else + // move low half to high half + m_f[FDREG >> 1] = (m_f[FSREG >> 1] << 32) | u32(m_f[FDREG >> 1]); + else + if (FSREG & 1) + // move high half to low half + m_f[FDREG >> 1] = (m_f[FDREG >> 1] & ~0xffffffffULL) | (m_f[FSREG >> 1] >> 32); + else + // move low half to low half + m_f[FDREG >> 1] = (m_f[FDREG >> 1] & ~0xffffffffULL) | u32(m_f[FSREG >> 1]); break; case 0x07: // NEG.S set_cop1_reg(FDREG >> 1, f32_mul(float32_t{ u32(m_f[FSREG >> 1]) }, i32_to_f32(-1)).v); @@ -1802,7 +1815,7 @@ void mips1_device_base::handle_cop1(u32 const op) } } -void mips1_device_base::set_cop1_reg(unsigned const reg, u64 const data) +template <typename T> void mips1_device_base::set_cop1_reg(unsigned const reg, T const data) { // translate softfloat exception flags to cause register if (softfloat_exceptionFlags) @@ -1829,7 +1842,10 @@ void mips1_device_base::set_cop1_reg(unsigned const reg, u64 const data) m_fcr31 |= ((m_fcr31 & FCR31_CM) >> 10); } - m_f[reg] = data; + if (sizeof(T) == 4) + m_f[reg] = (m_f[reg] & ~0xffffffffULL) | data; + else + m_f[reg] = data; } bool mips1_device_base::memory_translate(int spacenum, int intention, offs_t &address) diff --git a/src/devices/cpu/mips/mips1.h b/src/devices/cpu/mips/mips1.h index 3ae34e4b69f..3a442fa914c 100644 --- a/src/devices/cpu/mips/mips1.h +++ b/src/devices/cpu/mips/mips1.h @@ -298,7 +298,7 @@ protected: virtual u32 get_cop0_reg(unsigned const reg) override; virtual void handle_cop1(u32 const op) override; - virtual void set_cop1_reg(unsigned const reg, u64 const data); + template <typename T> void set_cop1_reg(unsigned const reg, T const data); private: u64 m_reset_time; diff --git a/src/devices/cpu/mips/r4000.cpp b/src/devices/cpu/mips/r4000.cpp index ca95b107c65..28adcda0e15 100644 --- a/src/devices/cpu/mips/r4000.cpp +++ b/src/devices/cpu/mips/r4000.cpp @@ -1642,7 +1642,7 @@ void r4000_base_device::cp1_execute(u32 const op) break; case 0x04: // MTC1 if (SR & SR_FR) - m_f[RDREG] = u32(m_r[RTREG]); + m_f[RDREG] = (m_f[RDREG] & ~0xffffffffULL) | u32(m_r[RTREG]); else if (RDREG & 1) // load the high half of the even floating point register @@ -1761,12 +1761,27 @@ void r4000_base_device::cp1_execute(u32 const op) if (f32_lt(float32_t{ u32(m_f[FSREG]) }, float32_t{ 0 })) cp1_set(FDREG, f32_mul(float32_t{ u32(m_f[FSREG]) }, i32_to_f32(-1)).v); else - cp1_set(FDREG, m_f[FSREG]); + cp1_set(FDREG, u32(m_f[FSREG])); } break; case 0x06: // MOV.S - if ((SR & SR_FR) || !(op & ODD_REGS)) - m_f[FDREG] = m_f[FSREG]; + if (SR & SR_FR) + m_f[FDREG] = (m_f[FDREG] & ~0xffffffffULL) | u32(m_f[FSREG]); + else + if (FDREG & 1) + if (FSREG & 1) + // move high half to high half + m_f[FDREG & ~1] = (m_f[FSREG & ~1] & ~0xffffffffULL) | u32(m_f[FDREG & ~1]); + else + // move low half to high half + m_f[FDREG & ~1] = (m_f[FSREG & ~1] << 32) | u32(m_f[FDREG & ~1]); + else + if (FSREG & 1) + // move high half to low half + m_f[FDREG & ~1] = (m_f[FDREG & ~1] & ~0xffffffffULL) | (m_f[FSREG & ~1] >> 32); + else + // move low half to low half + m_f[FDREG & ~1] = (m_f[FDREG & ~1] & ~0xffffffffULL) | u32(m_f[FSREG & ~1]); break; case 0x07: // NEG.S if ((SR & SR_FR) || !(op & ODD_REGS)) @@ -2358,7 +2373,7 @@ void r4000_base_device::cp1_execute(u32 const op) [this, op](u32 data) { if (SR & SR_FR) - m_f[RTREG] = data; + m_f[RTREG] = (m_f[RTREG] & ~0xffffffffULL) | data; else if (RTREG & 1) // load the high half of the even floating point register @@ -2397,7 +2412,7 @@ void r4000_base_device::cp1_execute(u32 const op) } } -void r4000_base_device::cp1_set(unsigned const reg, u64 const data) +template <typename T> void r4000_base_device::cp1_set(unsigned const reg, T const data) { // translate softfloat exception flags to cause register if (softfloat_exceptionFlags) @@ -2424,7 +2439,10 @@ void r4000_base_device::cp1_set(unsigned const reg, u64 const data) m_fcr31 |= ((m_fcr31 & FCR31_CM) >> 10); } - m_f[reg] = data; + if (sizeof(T) == 4) + m_f[reg] = (m_f[reg] & ~0xffffffffULL) | data; + else + m_f[reg] = data; } void r4000_base_device::cp2_execute(u32 const op) diff --git a/src/devices/cpu/mips/r4000.h b/src/devices/cpu/mips/r4000.h index 8c3a1760ba3..57e37b6dfe1 100644 --- a/src/devices/cpu/mips/r4000.h +++ b/src/devices/cpu/mips/r4000.h @@ -347,7 +347,7 @@ protected: // cp1 implementation void cp1_execute(u32 const op); - void cp1_set(unsigned const reg, u64 const data); + template <typename T> void cp1_set(unsigned const reg, T const data); // cp2 implementation void cp2_execute(u32 const op); diff --git a/src/devices/cpu/sm510/sm500core.cpp b/src/devices/cpu/sm510/sm500core.cpp index abe34e55fa3..8396d8e3107 100644 --- a/src/devices/cpu/sm510/sm500core.cpp +++ b/src/devices/cpu/sm510/sm500core.cpp @@ -36,16 +36,14 @@ void sm500_device::data_4x10x4(address_map &map) // device definitions -sm500_device::sm500_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : sm500_device(mconfig, SM500, tag, owner, clock, 1 /* stack levels */, 7 /* o group pins */, 11 /* prg width */, address_map_constructor(FUNC(sm500_device::program_1_2k), this), 6 /* data width */, address_map_constructor(FUNC(sm500_device::data_4x10x4), this)) -{ -} +sm500_device::sm500_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + sm500_device(mconfig, SM500, tag, owner, clock, 1 /* stack levels */, 7 /* o group pins */, 11 /* prg width */, address_map_constructor(FUNC(sm500_device::program_1_2k), this), 6 /* data width */, address_map_constructor(FUNC(sm500_device::data_4x10x4), this)) +{ } -sm500_device::sm500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_pins, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) - : sm510_base_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data), +sm500_device::sm500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_pins, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) : + sm510_base_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data), m_o_pins(o_pins) -{ -} +{ } // disasm diff --git a/src/devices/cpu/sm510/sm510.h b/src/devices/cpu/sm510/sm510.h index 03cd24efe89..6171de9ee6e 100644 --- a/src/devices/cpu/sm510/sm510.h +++ b/src/devices/cpu/sm510/sm510.h @@ -149,6 +149,7 @@ protected: u8 m_bl; u8 m_bm; bool m_sbm; + bool m_sbl; u8 m_c; bool m_skip; u8 m_w; @@ -164,7 +165,7 @@ protected: emu_timer *m_lcd_timer; u8 m_l, m_x; u8 m_y; - bool m_bp; + u8 m_bp; bool m_bc; u16 get_lcd_row(int column, u8* ram); @@ -214,6 +215,7 @@ protected: // opcode handlers virtual void op_lb(); virtual void op_lbl(); + virtual void op_sbl(); virtual void op_sbm(); virtual void op_exbla(); virtual void op_incb(); diff --git a/src/devices/cpu/sm510/sm510base.cpp b/src/devices/cpu/sm510/sm510base.cpp index 919fcea9e17..ab7b659cbb2 100644 --- a/src/devices/cpu/sm510/sm510base.cpp +++ b/src/devices/cpu/sm510/sm510base.cpp @@ -61,6 +61,7 @@ void sm510_base_device::device_start() m_acc = 0; m_bl = 0; m_bm = 0; + m_sbl = false; m_sbm = false; m_c = 0; m_skip = false; @@ -73,7 +74,7 @@ void sm510_base_device::device_start() m_l = 0; m_x = 0; m_y = 0; - m_bp = false; + m_bp = 0; m_bc = false; m_halt = false; m_melody_rd = 0; @@ -93,6 +94,7 @@ void sm510_base_device::device_start() save_item(NAME(m_acc)); save_item(NAME(m_bl)); save_item(NAME(m_bm)); + save_item(NAME(m_sbl)); save_item(NAME(m_sbm)); save_item(NAME(m_c)); save_item(NAME(m_skip)); @@ -147,13 +149,14 @@ void sm510_base_device::device_reset() // ACL m_skip = false; m_halt = false; + m_sbl = false; m_sbm = false; m_op = m_prev_op = 0; reset_vector(); m_prev_pc = m_pc; // lcd is on (Bp on, BC off, bs(y) off) - m_bp = true; + m_bp = 1; m_bc = false; m_y = 0; diff --git a/src/devices/cpu/sm510/sm510core.cpp b/src/devices/cpu/sm510/sm510core.cpp index 4d5edbef5f1..80ab6bf6ab3 100644 --- a/src/devices/cpu/sm510/sm510core.cpp +++ b/src/devices/cpu/sm510/sm510core.cpp @@ -37,10 +37,9 @@ void sm510_device::data_96_32x4(address_map &map) // device definitions -sm510_device::sm510_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : sm510_base_device(mconfig, SM510, tag, owner, clock, 2 /* stack levels */, 12 /* prg width */, address_map_constructor(FUNC(sm510_device::program_2_7k), this), 7 /* data width */, address_map_constructor(FUNC(sm510_device::data_96_32x4), this)) -{ -} +sm510_device::sm510_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + sm510_base_device(mconfig, SM510, tag, owner, clock, 2 /* stack levels */, 12 /* prg width */, address_map_constructor(FUNC(sm510_device::program_2_7k), this), 7 /* data width */, address_map_constructor(FUNC(sm510_device::data_96_32x4), this)) +{ } // disasm diff --git a/src/devices/cpu/sm510/sm510d.cpp b/src/devices/cpu/sm510/sm510d.cpp index 5f107babd4c..2525d5a3670 100644 --- a/src/devices/cpu/sm510/sm510d.cpp +++ b/src/devices/cpu/sm510/sm510d.cpp @@ -9,6 +9,40 @@ #include "emu.h" #include "sm510d.h" +// constructor + +sm510_common_disassembler::sm510_common_disassembler() +{ + // init 6-bit lfsr pc lut + for (u32 i = 0, pc = 0; i < 0x3f; i++) + { + m_l2r6[i] = pc; + m_r2l6[pc] = i; + pc = increment_pc(pc, 6); + } + + m_l2r6[0x3f] = 0x3f; + m_r2l6[0x3f] = 0x3f; + + // init 7-bit lfsr pc lut + for (u32 i = 0, pc = 0; i < 0x7f; i++) + { + m_l2r7[i] = pc; + m_r2l7[pc] = i; + pc = increment_pc(pc, 7); + } + + m_l2r7[0x7f] = 0x7f; + m_r2l7[0x7f] = 0x7f; +} + +offs_t sm510_common_disassembler::increment_pc(offs_t pc, u8 pclen) +{ + u32 feed = ((pc >> 1 ^ pc) & 1) ? 0 : (1 << (pclen - 1)); + u32 mask = (1 << pclen) - 1; + return feed | (pc >> 1 & (mask >> 1)) | (pc & ~mask); +} + // common lookup tables @@ -127,18 +161,7 @@ offs_t sm510_common_disassembler::common_disasm(const u8 *lut_mnemonic, const u8 u16 param = mask; if (bits >= 8) { - if (pclen == 6) - { - int feed = ((pc >> 1 ^ pc) & 1) ? 0 : 0x20; - pc = feed | (pc >> 1 & 0x1f) | (pc & ~0x3f); - } - else if (pclen == 7) - { - int feed = ((pc >> 1 ^ pc) & 1) ? 0 : 0x40; - pc = feed | (pc >> 1 & 0x3f) | (pc & ~0x7f); - } - else - abort(); + pc = increment_pc(pc, pclen); param = params.r8(pc); len++; } @@ -391,63 +414,7 @@ const u8 sm590_disassembler::sm590_mnemonic[0x100] = mTR7, mTR7, mTR7, mTR7, mTR7, mTR7, mTR7, mTR7, mTR7, mTR7, mTR7, mTR7, mTR7, mTR7, mTR7, mTR7 // F }; - offs_t sm590_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { return common_disasm(sm590_mnemonic, nullptr, stream, pc, opcodes, params, 7); } - - -// Sarayan's little helpers - -offs_t sm510_common_disassembler::pc_linear_to_real(offs_t pc) const -{ - static const u8 l2r[64] = { - 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x1f, 0x2f, 0x37, 0x3b, 0x3d, 0x1e, 0x0f, 0x27, 0x33, 0x39, - 0x1c, 0x2e, 0x17, 0x2b, 0x35, 0x1a, 0x0d, 0x06, 0x03, 0x21, 0x10, 0x28, 0x34, 0x3a, 0x1d, 0x0e, - 0x07, 0x23, 0x31, 0x18, 0x2c, 0x36, 0x1b, 0x2d, 0x16, 0x0b, 0x25, 0x12, 0x09, 0x04, 0x22, 0x11, - 0x08, 0x24, 0x32, 0x19, 0x0c, 0x26, 0x13, 0x29, 0x14, 0x2a, 0x15, 0x0a, 0x05, 0x02, 0x01, 0x3f, - }; - return (pc & ~0x3f) | l2r[pc & 0x3f]; -} - -offs_t sm510_common_disassembler::pc_real_to_linear(offs_t pc) const -{ - static const u8 r2l[64] = { - 0x00, 0x3e, 0x3d, 0x18, 0x2d, 0x3c, 0x17, 0x20, 0x30, 0x2c, 0x3b, 0x29, 0x34, 0x16, 0x1f, 0x0c, - 0x1a, 0x2f, 0x2b, 0x36, 0x38, 0x3a, 0x28, 0x12, 0x23, 0x33, 0x15, 0x26, 0x10, 0x1e, 0x0b, 0x06, - 0x01, 0x19, 0x2e, 0x21, 0x31, 0x2a, 0x35, 0x0d, 0x1b, 0x37, 0x39, 0x13, 0x24, 0x27, 0x11, 0x07, - 0x02, 0x22, 0x32, 0x0e, 0x1c, 0x14, 0x25, 0x08, 0x03, 0x0f, 0x1d, 0x09, 0x04, 0x0a, 0x05, 0x3f, - }; - return (pc & ~0x3f) | r2l[pc & 0x3f]; -} - -offs_t sm590_disassembler::pc_linear_to_real(offs_t pc) const -{ - static const u8 l2r[128] = { - 0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x3f, 0x5f, 0x6f, 0x77, 0x7b, 0x7d, 0x3e, 0x1f, 0x4f, - 0x67, 0x73, 0x79, 0x3c, 0x5e, 0x2f, 0x57, 0x6b, 0x75, 0x3a, 0x1d, 0x0e, 0x07, 0x43, 0x61, 0x30, - 0x58, 0x6c, 0x76, 0x3b, 0x5d, 0x2e, 0x17, 0x4b, 0x65, 0x32, 0x19, 0x0c, 0x46, 0x23, 0x51, 0x28, - 0x54, 0x6a, 0x35, 0x1a, 0x0d, 0x06, 0x03, 0x41, 0x20, 0x50, 0x68, 0x74, 0x7a, 0x3d, 0x1e, 0x0f, - 0x47, 0x63, 0x71, 0x38, 0x5c, 0x6e, 0x37, 0x5b, 0x6d, 0x36, 0x1b, 0x4d, 0x26, 0x13, 0x49, 0x24, - 0x52, 0x29, 0x14, 0x4a, 0x25, 0x12, 0x09, 0x04, 0x42, 0x21, 0x10, 0x48, 0x64, 0x72, 0x39, 0x1c, - 0x4e, 0x27, 0x53, 0x69, 0x34, 0x5a, 0x2d, 0x16, 0x0b, 0x45, 0x22, 0x11, 0x08, 0x44, 0x62, 0x31, - 0x18, 0x4c, 0x66, 0x33, 0x59, 0x2c, 0x56, 0x2b, 0x55, 0x2a, 0x15, 0x0a, 0x05, 0x02, 0x01, 0x7f, - }; - return (pc & ~0x7f) | l2r[pc & 0x7f]; -} - -offs_t sm590_disassembler::pc_real_to_linear(offs_t pc) const -{ - static const u8 r2l[128] = { - 0x00, 0x7e, 0x7d, 0x36, 0x57, 0x7c, 0x35, 0x1c, 0x6c, 0x56, 0x7b, 0x68, 0x2b, 0x34, 0x1b, 0x3f, - 0x5a, 0x6b, 0x55, 0x4d, 0x52, 0x7a, 0x67, 0x26, 0x70, 0x2a, 0x33, 0x4a, 0x5f, 0x1a, 0x3e, 0x0e, - 0x38, 0x59, 0x6a, 0x2d, 0x4f, 0x54, 0x4c, 0x61, 0x2f, 0x51, 0x79, 0x77, 0x75, 0x66, 0x25, 0x15, - 0x1f, 0x6f, 0x29, 0x73, 0x64, 0x32, 0x49, 0x46, 0x43, 0x5e, 0x19, 0x23, 0x13, 0x3d, 0x0d, 0x07, - 0x01, 0x37, 0x58, 0x1d, 0x6d, 0x69, 0x2c, 0x40, 0x5b, 0x4e, 0x53, 0x27, 0x71, 0x4b, 0x60, 0x0f, - 0x39, 0x2e, 0x50, 0x62, 0x30, 0x78, 0x76, 0x16, 0x20, 0x74, 0x65, 0x47, 0x44, 0x24, 0x14, 0x08, - 0x02, 0x1e, 0x6e, 0x41, 0x5c, 0x28, 0x72, 0x10, 0x3a, 0x63, 0x31, 0x17, 0x21, 0x48, 0x45, 0x09, - 0x03, 0x42, 0x5d, 0x11, 0x3b, 0x18, 0x22, 0x0a, 0x04, 0x12, 0x3c, 0x0b, 0x05, 0x0c, 0x06, 0x7f, - }; - return (pc & ~0x7f) | r2l[pc & 0x7f]; -} diff --git a/src/devices/cpu/sm510/sm510d.h b/src/devices/cpu/sm510/sm510d.h index a29a1f201a0..258d8205617 100644 --- a/src/devices/cpu/sm510/sm510d.h +++ b/src/devices/cpu/sm510/sm510d.h @@ -14,15 +14,15 @@ class sm510_common_disassembler : public util::disasm_interface { public: - sm510_common_disassembler() = default; + sm510_common_disassembler(); virtual ~sm510_common_disassembler() = default; virtual u32 opcode_alignment() const override { return 1; } virtual u32 interface_flags() const override { return NONLINEAR_PC | PAGED2LEVEL; } virtual u32 page_address_bits() const override { return 6; } virtual u32 page2_address_bits() const override { return 4; } - virtual offs_t pc_linear_to_real(offs_t pc) const override; - virtual offs_t pc_real_to_linear(offs_t pc) const override; + virtual offs_t pc_linear_to_real(offs_t pc) const override { return (pc & ~0x3f) | m_l2r6[pc & 0x3f]; } + virtual offs_t pc_real_to_linear(offs_t pc) const override { return (pc & ~0x3f) | m_r2l6[pc & 0x3f]; } protected: enum e_mnemonics @@ -62,6 +62,12 @@ protected: static const u8 s_bits[]; static const u32 s_flags[]; + u8 m_l2r6[0x40]; + u8 m_r2l6[0x40]; + u8 m_l2r7[0x80]; + u8 m_r2l7[0x80]; + + offs_t increment_pc(offs_t pc, u8 pclen); offs_t common_disasm(const u8 *lut_mnemonic, const u8 *lut_extended, std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms, const u8 pclen); }; @@ -125,6 +131,8 @@ public: virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + virtual u32 interface_flags() const override { return NONLINEAR_PC | PAGED; } + private: static const u8 sm530_mnemonic[0x100]; }; @@ -139,8 +147,8 @@ public: virtual u32 page_address_bits() const override { return 7; } virtual u32 page2_address_bits() const override { return 2; } - virtual offs_t pc_linear_to_real(offs_t pc) const override; - virtual offs_t pc_real_to_linear(offs_t pc) const override; + virtual offs_t pc_linear_to_real(offs_t pc) const override { return (pc & ~0x7f) | m_l2r7[pc & 0x7f]; } + virtual offs_t pc_real_to_linear(offs_t pc) const override { return (pc & ~0x7f) | m_r2l7[pc & 0x7f]; } private: static const u8 sm590_mnemonic[0x100]; diff --git a/src/devices/cpu/sm510/sm510op.cpp b/src/devices/cpu/sm510/sm510op.cpp index 654ce20a5d2..acaf607f9df 100644 --- a/src/devices/cpu/sm510/sm510op.cpp +++ b/src/devices/cpu/sm510/sm510op.cpp @@ -11,15 +11,17 @@ u8 sm510_base_device::ram_r() { + int blh = (m_sbl) ? 8 : 0; // from SBL (optional) int bmh = (m_sbm) ? (1 << (m_datawidth-1)) : 0; // from SBM - u8 address = (bmh | m_bm << 4 | m_bl) & m_datamask; + u8 address = (bmh | blh | m_bm << 4 | m_bl) & m_datamask; return m_data->read_byte(address) & 0xf; } void sm510_base_device::ram_w(u8 data) { + int blh = (m_sbl) ? 8 : 0; // from SBL (optional) int bmh = (m_sbm) ? (1 << (m_datawidth-1)) : 0; // from SBM - u8 address = (bmh | m_bm << 4 | m_bl) & m_datamask; + u8 address = (bmh | blh | m_bm << 4 | m_bl) & m_datamask; m_data->write_byte(address, data & 0xf); } @@ -40,7 +42,7 @@ void sm510_base_device::push_stack() void sm510_base_device::do_branch(u8 pu, u8 pm, u8 pl) { // set new PC(Pu/Pm/Pl) - m_pc = ((pu << 10 & 0xc00) | (pm << 6 & 0x3c0) | (pl & 0x03f)) & m_prgmask; + m_pc = ((pu << 10) | (pm << 6 & 0x3c0) | (pl & 0x03f)) & m_prgmask; } u8 sm510_base_device::bitmask(u16 param) @@ -69,6 +71,11 @@ void sm510_base_device::op_lbl() m_bm = (m_param & m_datamask) >> 4; } +void sm510_base_device::op_sbl() +{ + // SBL: set BL high bit for next opcode - handled in execute_one() +} + void sm510_base_device::op_sbm() { // SBM: set BM high bit for next opcode - handled in execute_one() @@ -139,7 +146,7 @@ void sm510_base_device::op_tml() void sm510_base_device::op_tm() { - // TM x: indirect subroutine call, pointers(IDX) are in page 0 + // TM x: indirect subroutine call, pointers(IDX) are on page 0 m_icount--; push_stack(); u8 idx = m_program->read_byte(m_op & 0x3f); @@ -225,7 +232,7 @@ void sm510_base_device::op_kta() void sm510_base_device::op_atbp() { // ATBP: output ACC to BP(internal LCD backplate signal) - m_bp = ((m_acc & 1) != 0); + m_bp = m_acc & 1; } void sm510_base_device::op_atx() diff --git a/src/devices/cpu/sm510/sm511core.cpp b/src/devices/cpu/sm510/sm511core.cpp index 6585f18febf..c7a26de07e2 100644 --- a/src/devices/cpu/sm510/sm511core.cpp +++ b/src/devices/cpu/sm510/sm511core.cpp @@ -54,20 +54,17 @@ std::unique_ptr<util::disasm_interface> sm511_device::create_disassembler() // device definitions -sm511_device::sm511_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : sm511_device(mconfig, SM511, tag, owner, clock, 2 /* stack levels */, 12 /* prg width */, address_map_constructor(FUNC(sm511_device::program_4k), this), 7 /* data width */, address_map_constructor(FUNC(sm511_device::data_96_32x4), this)) -{ -} +sm511_device::sm511_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + sm511_device(mconfig, SM511, tag, owner, clock, 2 /* stack levels */, 12 /* prg width */, address_map_constructor(FUNC(sm511_device::program_4k), this), 7 /* data width */, address_map_constructor(FUNC(sm511_device::data_96_32x4), this)) +{ } -sm511_device::sm511_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) - : sm510_base_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data) -{ -} +sm511_device::sm511_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) : + sm510_base_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data) +{ } -sm512_device::sm512_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : sm511_device(mconfig, SM512, tag, owner, clock, 2, 12, address_map_constructor(FUNC(sm512_device::program_4k), this), 7, address_map_constructor(FUNC(sm512_device::data_80_48x4), this)) -{ -} +sm512_device::sm512_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + sm511_device(mconfig, SM512, tag, owner, clock, 2, 12, address_map_constructor(FUNC(sm512_device::program_4k), this), 7, address_map_constructor(FUNC(sm512_device::data_80_48x4), this)) +{ } diff --git a/src/devices/cpu/sm510/sm530.h b/src/devices/cpu/sm510/sm530.h index 64e03884481..8837ea1e2cd 100644 --- a/src/devices/cpu/sm510/sm530.h +++ b/src/devices/cpu/sm510/sm530.h @@ -25,14 +25,30 @@ protected: void program_2k(address_map &map); void data_64_24x4(address_map &map); + virtual void device_start() override; virtual void device_reset() override; virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return (clocks + 3 - 1) / 3; } // 3 cycles per machine cycle + virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return (cycles * 3); } // " virtual void execute_one() override; virtual void get_opcode_param() override; - virtual u8 ram_r() override; - virtual void ram_w(u8 data) override; + using sm510_base_device::do_branch; + virtual void do_branch(u8 pu, u8 pl); // does not have Pm + virtual void reset_vector() override { do_branch(0xf, 0); } + virtual void wakeup_vector() override { reset_vector(); } + + // opcode handlers + virtual void op_lb() override; + virtual void op_incb() override; + + virtual void op_tl() override; + virtual void op_trs(); + + virtual void op_adx() override; + + virtual void op_atbp() override; }; class sm531_device : public sm530_device diff --git a/src/devices/cpu/sm510/sm530core.cpp b/src/devices/cpu/sm510/sm530core.cpp index 1a1b00b392f..3d3a424ad90 100644 --- a/src/devices/cpu/sm510/sm530core.cpp +++ b/src/devices/cpu/sm510/sm530core.cpp @@ -5,7 +5,7 @@ Sharp SM530 MCU core implementation TODO: - - everything + - almost everything */ @@ -29,8 +29,8 @@ void sm530_device::program_2k(address_map &map) void sm530_device::data_64_24x4(address_map &map) { map(0x00, 0x3f).ram(); - map(0x40, 0x4b).ram(); - map(0x50, 0x5b).ram(); + map(0x40, 0x4b).mirror(0x20).ram().share("lcd_ram_a"); + map(0x50, 0x5b).mirror(0x20).ram().share("lcd_ram_b"); } @@ -42,19 +42,28 @@ std::unique_ptr<util::disasm_interface> sm530_device::create_disassembler() // device definitions -sm530_device::sm530_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : sm530_device(mconfig, SM530, tag, owner, clock, 1 /* stack levels */, 11 /* prg width */, address_map_constructor(FUNC(sm530_device::program_2k), this), 7 /* data width */, address_map_constructor(FUNC(sm530_device::data_64_24x4), this)) -{ -} +sm530_device::sm530_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + sm530_device(mconfig, SM530, tag, owner, clock, 1 /* stack levels */, 11 /* prg width */, address_map_constructor(FUNC(sm530_device::program_2k), this), 7 /* data width */, address_map_constructor(FUNC(sm530_device::data_64_24x4), this)) +{ } -sm530_device::sm530_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) - : sm511_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data) -{ -} +sm530_device::sm530_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) : + sm511_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data) +{ } + +sm531_device::sm531_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + sm530_device(mconfig, SM531, tag, owner, clock, 1, 11, address_map_constructor(FUNC(sm531_device::program_2k), this), 7, address_map_constructor(FUNC(sm531_device::data_64_24x4), this)) +{ } + + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- -sm531_device::sm531_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : sm530_device(mconfig, SM531, tag, owner, clock, 1, 11, address_map_constructor(FUNC(sm531_device::program_2k), this), 7, address_map_constructor(FUNC(sm531_device::data_64_24x4), this)) +void sm530_device::device_start() { + // common init + sm511_device::device_start(); } @@ -65,7 +74,8 @@ sm531_device::sm531_device(const machine_config &mconfig, const char *tag, devic void sm530_device::device_reset() { - sm510_base_device::device_reset(); + // common reset + sm511_device::device_reset(); } @@ -76,8 +86,91 @@ void sm530_device::device_reset() void sm530_device::get_opcode_param() { + // LBL, PRE, TL opcodes are 2 bytes + if (m_op == 0x6b || m_op == 0x78 || ((m_op & 0xf8) == 0x60)) + { + m_icount--; + m_param = m_program->read_byte(m_pc); + increment_pc(); + } } void sm530_device::execute_one() { + switch (m_op & 0xf0) + { + case 0x00: op_adx(); break; + case 0x10: op_lax(); break; + case 0x30: op_lb(); break; + + case 0x80: case 0x90: case 0xa0: case 0xb0: + op_t(); break; // TR + case 0xc0: case 0xd0: case 0xe0: case 0xf0: + op_trs(); break; + + default: + switch (m_op & 0xfc) + { + case 0x20: op_lda(); break; + case 0x24: op_exc(); break; + case 0x28: op_exci(); break; + case 0x2c: op_excd(); break; + case 0x40: op_rm(); break; + case 0x44: op_sm(); break; + case 0x48: op_tmi(); break; // TM + case 0x60: case 0x64: op_tl(); break; + //case 0x6c: op_tg(); break; + + default: + switch (m_op) + { + case 0x4c: op_incb(); break; + case 0x4d: op_decb(); break; + //case 0x4e: op_rds(); break; + //case 0x4f: op_sds(); break; + + case 0x50: op_kta(); break; + //case 0x51: op_keta(); break; + //case 0x52: op_dta(); break; + case 0x53: op_coma(); break; + case 0x54: op_add(); break; + case 0x55: op_add11(); break; // ADDC + case 0x56: op_rc(); break; + case 0x57: op_sc(); break; + case 0x58: op_tabl(); break; + case 0x59: op_tam(); break; + case 0x5a: op_exbla(); break; // EXBL + case 0x5b: op_tc(); break; + //case 0x5c: op_ats(); break; + //case 0x5d: op_atf(); break; + case 0x5e: op_atbp(); break; + + case 0x68: op_rtn0(); break; // RTN + case 0x69: op_rtn1(); break; // RTNS + case 0x6a: op_atpl(); break; + case 0x6b: op_lbl(); break; + + //case 0x70: op_idiv(); break; + //case 0x71: op_inis(); break; + case 0x72: op_sbm(); break; // SABM + case 0x73: op_sbl(); break; // SABL + case 0x74: op_cend(); break; + case 0x75: op_tmel(); break; + case 0x76: op_rme(); break; + case 0x77: op_sme(); break; + case 0x78: op_pre(); break; + case 0x79: op_tal(); break; // TBA + + default: op_illegal(); break; + } + break; // 0xff + + } + break; // 0xfc + + } // big switch + + // SABL/SABM is only valid for 1 step + m_sbl = (m_op == 0x73); + m_sbm = (m_op == 0x72); } diff --git a/src/devices/cpu/sm510/sm530op.cpp b/src/devices/cpu/sm510/sm530op.cpp index 256feccdb4b..3aec192b0a0 100644 --- a/src/devices/cpu/sm510/sm530op.cpp +++ b/src/devices/cpu/sm510/sm530op.cpp @@ -9,15 +9,66 @@ // internal helpers -u8 sm530_device::ram_r() +void sm530_device::do_branch(u8 pu, u8 pl) { - return 0; + // set new PC(Pu/Pl) + m_pc = ((pu << 6) | (pl & 0x3f)) & m_prgmask; } -void sm530_device::ram_w(u8 data) + + +// instruction set + +// RAM address instructions + +void sm530_device::op_lb() +{ + // LB x: load BM/BL with 4-bit immediate value (partial) + m_bl = (m_op << 2 & 8) | (m_op & 1) | 6; + m_bm = m_op >> 2 & 3; +} + +void sm530_device::op_incb() { + // INCB: increment BL, but overflow on 3rd bit! + sm510_base_device::op_incb(); + m_skip = (m_bl == 8); } +// ROM address instructions -// instruction set +void sm530_device::op_tl() +{ + // TL xy: long jump + do_branch((m_op << 2) | (m_param >> 6 & 3), m_param & 0x3f); +} + +void sm530_device::op_trs() +{ + // TRS x: indirect subroutine call, jump vectors are on page 14 + m_icount--; + push_stack(); + u8 jump = m_program->read_byte((14 << 6) | (m_op & 0x3f)); + do_branch(jump >> 5 & 7, jump & 0x1f); +} + + +// Arithmetic instructions + +void sm530_device::op_adx() +{ + // ADX x: add immediate value to ACC, skip next on carry + m_acc += (m_op & 0xf); + m_skip = bool(m_acc & 0x10); + m_acc &= 0xf; +} + + +// I/O instructions + +void sm530_device::op_atbp() +{ + // ATBP: output ACC to BP + m_bp = m_acc; +} diff --git a/src/devices/cpu/sm510/sm590core.cpp b/src/devices/cpu/sm510/sm590core.cpp index 8086732ac23..54e4267d7de 100644 --- a/src/devices/cpu/sm510/sm590core.cpp +++ b/src/devices/cpu/sm510/sm590core.cpp @@ -35,25 +35,21 @@ void sm590_device::data_16x2x4(address_map &map) } // device definitions -sm590_device::sm590_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : sm590_device(mconfig, SM590, tag, owner, clock, 4 /* stack levels */, 9 /* prg width */, address_map_constructor(FUNC(sm590_device::program_1x128x4), this), 5 /* data width */, address_map_constructor(FUNC(sm590_device::data_16x2x4), this)) -{ -} +sm590_device::sm590_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + sm590_device(mconfig, SM590, tag, owner, clock, 4 /* stack levels */, 9 /* prg width */, address_map_constructor(FUNC(sm590_device::program_1x128x4), this), 5 /* data width */, address_map_constructor(FUNC(sm590_device::data_16x2x4), this)) +{ } -//sm591_device::sm591_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) -// : sm510_base_device(mconfig, SM591, tag, owner, clock, 4 /* stack levels */, 10 /* prg width */, address_map_constructor(FUNC(sm591_device::program_2x128x4), this), 6 /* data width */, address_map_constructor(FUNC(sm591_device::data_16x3.5x4), this)) -//{ -//} +//sm591_device::sm591_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : +// sm510_base_device(mconfig, SM591, tag, owner, clock, 4 /* stack levels */, 10 /* prg width */, address_map_constructor(FUNC(sm591_device::program_2x128x4), this), 6 /* data width */, address_map_constructor(FUNC(sm591_device::data_16x3.5x4), this)) +//{ } -//sm595_device::sm595_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) -// : sm510_base_device(mconfig, SM595, tag, owner, clock, 4 /* stack levels */, 10 /* prg width */, address_map_constructor(FUNC(sm595_device::program_1x128x4_1x128x2), this), 5 /* data width */, address_map_constructor(FUNC(sm595_device::data_16x2x4), this)) -//{ -//} +//sm595_device::sm595_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : +// sm510_base_device(mconfig, SM595, tag, owner, clock, 4 /* stack levels */, 10 /* prg width */, address_map_constructor(FUNC(sm595_device::program_1x128x4_1x128x2), this), 5 /* data width */, address_map_constructor(FUNC(sm595_device::data_16x2x4), this)) +//{ } -sm590_device::sm590_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) - : sm510_base_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data) -{ -} +sm590_device::sm590_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) : + sm510_base_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data) +{ } std::unique_ptr<util::disasm_interface> sm590_device::create_disassembler() diff --git a/src/devices/cpu/sm510/sm590op.cpp b/src/devices/cpu/sm510/sm590op.cpp index 99b1c7189b7..c9ead123360 100644 --- a/src/devices/cpu/sm510/sm590op.cpp +++ b/src/devices/cpu/sm510/sm590op.cpp @@ -8,6 +8,7 @@ // internal helpers + void sm590_device::do_branch(u8 pu, u8 pm, u8 pl) { // set new PC(Pu/Pm/Pl) diff --git a/src/devices/cpu/sm510/sm5acore.cpp b/src/devices/cpu/sm510/sm5acore.cpp index d32f46a24bf..a48ffb8110d 100644 --- a/src/devices/cpu/sm510/sm5acore.cpp +++ b/src/devices/cpu/sm510/sm5acore.cpp @@ -44,25 +44,21 @@ void sm5a_device::data_5x13x4(address_map &map) // device definitions -sm5a_device::sm5a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : sm5a_device(mconfig, SM5A, tag, owner, clock, 1 /* stack levels */, 9 /* o group pins */, 11 /* prg width */, address_map_constructor(FUNC(sm5a_device::program_1_8k), this), 7 /* data width */, address_map_constructor(FUNC(sm5a_device::data_5x13x4), this)) -{ -} +sm5a_device::sm5a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + sm5a_device(mconfig, SM5A, tag, owner, clock, 1 /* stack levels */, 9 /* o group pins */, 11 /* prg width */, address_map_constructor(FUNC(sm5a_device::program_1_8k), this), 7 /* data width */, address_map_constructor(FUNC(sm5a_device::data_5x13x4), this)) +{ } -sm5a_device::sm5a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_pins, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) - : sm500_device(mconfig, type, tag, owner, clock, stack_levels, o_pins, prgwidth, program, datawidth, data) -{ -} +sm5a_device::sm5a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_pins, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) : + sm500_device(mconfig, type, tag, owner, clock, stack_levels, o_pins, prgwidth, program, datawidth, data) +{ } -sm5l_device::sm5l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : sm5a_device(mconfig, SM5L, tag, owner, clock, 1, 9, 11, address_map_constructor(FUNC(sm5l_device::program_1_8k), this), 7, address_map_constructor(FUNC(sm5l_device::data_5x13x4), this)) -{ -} +sm5l_device::sm5l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + sm5a_device(mconfig, SM5L, tag, owner, clock, 1, 9, 11, address_map_constructor(FUNC(sm5l_device::program_1_8k), this), 7, address_map_constructor(FUNC(sm5l_device::data_5x13x4), this)) +{ } -kb1013vk12_device::kb1013vk12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : sm5a_device(mconfig, KB1013VK12, tag, owner, clock, 1, 9, 11, address_map_constructor(FUNC(kb1013vk12_device::program_1_8k), this), 7, address_map_constructor(FUNC(kb1013vk12_device::data_5x13x4), this)) -{ -} +kb1013vk12_device::kb1013vk12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + sm5a_device(mconfig, KB1013VK12, tag, owner, clock, 1, 9, 11, address_map_constructor(FUNC(kb1013vk12_device::program_1_8k), this), 7, address_map_constructor(FUNC(kb1013vk12_device::data_5x13x4), this)) +{ } // disasm diff --git a/src/devices/cpu/tms1000/tms1k_dasm.cpp b/src/devices/cpu/tms1000/tms1k_dasm.cpp index 1cd05a57ab3..af1af973697 100644 --- a/src/devices/cpu/tms1000/tms1k_dasm.cpp +++ b/src/devices/cpu/tms1000/tms1k_dasm.cpp @@ -9,6 +9,65 @@ #include "emu.h" #include "tms1k_dasm.h" +// constructor + +tms1000_base_disassembler::tms1000_base_disassembler(const u8 *lut_mnemonic, bool opcode_9bits, int pc_bits) : + m_lut_mnemonic(lut_mnemonic), + m_opcode_9bits(opcode_9bits), + m_pc_bits(pc_bits) +{ + // init lfsr pc lut + const u32 len = 1 << pc_bits; + m_l2r = std::make_unique<u8[]>(len); + m_r2l = std::make_unique<u8[]>(len); + + for (u32 i = 0, pc = 0; i < len; i++) + { + m_l2r[i] = pc; + m_r2l[pc] = i; + + // see tms1k_base_device::next_pc() + u32 mask = (1 << pc_bits) - 1; + u32 high = 1 << (pc_bits - 1); + u32 fb = (pc << 1 & high) == (pc & high); + + if (pc == (mask >> 1)) + fb = 1; + else if (pc == mask) + fb = 0; + + pc = (pc << 1 | fb) & mask; + } +} + +tms1000_disassembler::tms1000_disassembler() : tms1000_base_disassembler(tms1000_mnemonic, false, 6) +{ } + +tms1100_disassembler::tms1100_disassembler() : tms1000_base_disassembler(tms1100_mnemonic, false, 6) +{ } + +tms0980_disassembler::tms0980_disassembler() : tms1000_base_disassembler(tms0980_mnemonic, true, 7) +{ } + +tp0320_disassembler::tp0320_disassembler() : tms1000_base_disassembler(tp0320_mnemonic, true, 7) +{ } + + +offs_t tms1000_base_disassembler::pc_linear_to_real(offs_t pc) const +{ + const u32 mask = (1 << m_pc_bits) - 1; + return (pc & ~mask) | m_l2r[pc & mask]; +} + +offs_t tms1000_base_disassembler::pc_real_to_linear(offs_t pc) const +{ + const u32 mask = (1 << m_pc_bits) - 1; + return (pc & ~mask) | m_r2l[pc & mask]; +} + + +// common lookup tables + const char *const tms1000_base_disassembler::s_mnemonic[] = { "?", @@ -46,7 +105,6 @@ const u8 tms1000_base_disassembler::s_addressing[] = }; - // opcode luts const u8 tms1000_disassembler::tms1000_mnemonic[256] = @@ -72,7 +130,6 @@ const u8 tms1000_disassembler::tms1000_mnemonic[256] = /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ }; - const u8 tms1100_disassembler::tms1100_mnemonic[256] = { /* 0x00 */ @@ -96,7 +153,6 @@ const u8 tms1100_disassembler::tms1100_mnemonic[256] = /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ }; - const u8 tms0980_disassembler::tms0980_mnemonic[512] = { /* 0x000 */ @@ -138,7 +194,6 @@ const u8 tms0980_disassembler::tms0980_mnemonic[512] = /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ }; - const u8 tp0320_disassembler::tp0320_mnemonic[512] = { /* 0x000 */ @@ -181,7 +236,6 @@ const u8 tp0320_disassembler::tp0320_mnemonic[512] = }; - // disasm const u8 tms1000_base_disassembler::i2_value[4] = @@ -227,82 +281,3 @@ offs_t tms1000_base_disassembler::disassemble(std::ostream &stream, offs_t pc, c return 1 | s_flags[instr] | SUPPORTED; } - -tms1000_disassembler::tms1000_disassembler() : tms1000_base_disassembler(tms1000_mnemonic, false, 6) -{ -} - -tms1100_disassembler::tms1100_disassembler() : tms1000_base_disassembler(tms1100_mnemonic, false, 6) -{ -} - -tms0980_disassembler::tms0980_disassembler() : tms1000_base_disassembler(tms0980_mnemonic, true, 7) -{ -} - -tp0320_disassembler::tp0320_disassembler() : tms1000_base_disassembler(tp0320_mnemonic, true, 7) -{ -} - -tms1000_base_disassembler::tms1000_base_disassembler(const u8 *lut_mnemonic, bool opcode_9bits, int pc_bits) : m_lut_mnemonic(lut_mnemonic), m_opcode_9bits(opcode_9bits), m_pc_bits(pc_bits) -{ -} - -offs_t tms1000_base_disassembler::pc_linear_to_real(offs_t pc) const -{ - switch(m_pc_bits) { - case 6: { - static const u8 l2r6[64] = { - 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x3e, 0x3d, 0x3b, 0x37, 0x2f, 0x1e, 0x3c, 0x39, 0x33, - 0x27, 0x0e, 0x1d, 0x3a, 0x35, 0x2b, 0x16, 0x2c, 0x18, 0x30, 0x21, 0x02, 0x05, 0x0b, 0x17, 0x2e, - 0x1c, 0x38, 0x31, 0x23, 0x06, 0x0d, 0x1b, 0x36, 0x2d, 0x1a, 0x34, 0x29, 0x12, 0x24, 0x08, 0x11, - 0x22, 0x04, 0x09, 0x13, 0x26, 0x0c, 0x19, 0x32, 0x25, 0x0a, 0x15, 0x2a, 0x14, 0x28, 0x10, 0x20, - }; - return (pc & ~0x3f) | l2r6[pc & 0x3f]; - } - case 7: { - static const u8 l2r7[128] = { - 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0x7e, 0x7d, 0x7b, 0x77, 0x6f, 0x5f, 0x3e, 0x7c, - 0x79, 0x73, 0x67, 0x4f, 0x1e, 0x3d, 0x7a, 0x75, 0x6b, 0x57, 0x2e, 0x5c, 0x38, 0x70, 0x61, 0x43, - 0x06, 0x0d, 0x1b, 0x37, 0x6e, 0x5d, 0x3a, 0x74, 0x69, 0x53, 0x26, 0x4c, 0x18, 0x31, 0x62, 0x45, - 0x0a, 0x15, 0x2b, 0x56, 0x2c, 0x58, 0x30, 0x60, 0x41, 0x02, 0x05, 0x0b, 0x17, 0x2f, 0x5e, 0x3c, - 0x78, 0x71, 0x63, 0x47, 0x0e, 0x1d, 0x3b, 0x76, 0x6d, 0x5b, 0x36, 0x6c, 0x59, 0x32, 0x64, 0x49, - 0x12, 0x25, 0x4a, 0x14, 0x29, 0x52, 0x24, 0x48, 0x10, 0x21, 0x42, 0x04, 0x09, 0x13, 0x27, 0x4e, - 0x1c, 0x39, 0x72, 0x65, 0x4b, 0x16, 0x2d, 0x5a, 0x34, 0x68, 0x51, 0x22, 0x44, 0x08, 0x11, 0x23, - 0x46, 0x0c, 0x19, 0x33, 0x66, 0x4d, 0x1a, 0x35, 0x6a, 0x55, 0x2a, 0x54, 0x28, 0x50, 0x20, 0x40, - }; - return (pc & ~0x7f) | l2r7[pc & 0x7f]; - } - } - return 0; -} - -offs_t tms1000_base_disassembler::pc_real_to_linear(offs_t pc) const -{ - switch(m_pc_bits) { - case 6: { - static const u8 r2l6[64] = { - 0x00, 0x01, 0x1b, 0x02, 0x31, 0x1c, 0x24, 0x03, 0x2e, 0x32, 0x39, 0x1d, 0x35, 0x25, 0x11, 0x04, - 0x3e, 0x2f, 0x2c, 0x33, 0x3c, 0x3a, 0x16, 0x1e, 0x18, 0x36, 0x29, 0x26, 0x20, 0x12, 0x0c, 0x05, - 0x3f, 0x1a, 0x30, 0x23, 0x2d, 0x38, 0x34, 0x10, 0x3d, 0x2b, 0x3b, 0x15, 0x17, 0x28, 0x1f, 0x0b, - 0x19, 0x22, 0x37, 0x0f, 0x2a, 0x14, 0x27, 0x0a, 0x21, 0x0e, 0x13, 0x09, 0x0d, 0x08, 0x07, 0x06, - }; - return (pc & ~0x3f) | r2l6[pc & 0x3f]; - } - case 7: { - static const u8 r2l7[128] = { - 0x00, 0x01, 0x39, 0x02, 0x5b, 0x3a, 0x20, 0x03, 0x6d, 0x5c, 0x30, 0x3b, 0x71, 0x21, 0x44, 0x04, - 0x58, 0x6e, 0x50, 0x5d, 0x53, 0x31, 0x65, 0x3c, 0x2c, 0x72, 0x76, 0x22, 0x60, 0x45, 0x14, 0x05, - 0x7e, 0x59, 0x6b, 0x6f, 0x56, 0x51, 0x2a, 0x5e, 0x7c, 0x54, 0x7a, 0x32, 0x34, 0x66, 0x1a, 0x3d, - 0x36, 0x2d, 0x4d, 0x73, 0x68, 0x77, 0x4a, 0x23, 0x1c, 0x61, 0x26, 0x46, 0x3f, 0x15, 0x0e, 0x06, - 0x7f, 0x38, 0x5a, 0x1f, 0x6c, 0x2f, 0x70, 0x43, 0x57, 0x4f, 0x52, 0x64, 0x2b, 0x75, 0x5f, 0x13, - 0x7d, 0x6a, 0x55, 0x29, 0x7b, 0x79, 0x33, 0x19, 0x35, 0x4c, 0x67, 0x49, 0x1b, 0x25, 0x3e, 0x0d, - 0x37, 0x1e, 0x2e, 0x42, 0x4e, 0x63, 0x74, 0x12, 0x69, 0x28, 0x78, 0x18, 0x4b, 0x48, 0x24, 0x0c, - 0x1d, 0x41, 0x62, 0x11, 0x27, 0x17, 0x47, 0x0b, 0x40, 0x10, 0x16, 0x0a, 0x0f, 0x09, 0x08, 0x07, - }; - return (pc & ~0x7f) | r2l7[pc & 0x7f]; - } - } - return 0; -} - diff --git a/src/devices/cpu/tms1000/tms1k_dasm.h b/src/devices/cpu/tms1000/tms1k_dasm.h index 64e9e6f5082..18aad27fe1a 100644 --- a/src/devices/cpu/tms1000/tms1k_dasm.h +++ b/src/devices/cpu/tms1000/tms1k_dasm.h @@ -52,6 +52,9 @@ protected: const u8 *m_lut_mnemonic; bool m_opcode_9bits; int m_pc_bits; + + std::unique_ptr<u8[]> m_l2r; + std::unique_ptr<u8[]> m_r2l; }; class tms1000_disassembler : public tms1000_base_disassembler diff --git a/src/devices/machine/genpc.cpp b/src/devices/machine/genpc.cpp index e626bf96b30..50528d17aa7 100644 --- a/src/devices/machine/genpc.cpp +++ b/src/devices/machine/genpc.cpp @@ -778,7 +778,118 @@ WRITE8_MEMBER( ibm5150_mb_device::pc_ppi_portb_w ) // GLOBAL VARIABLES //************************************************************************** -DEFINE_DEVICE_TYPE(EC1841_MOTHERBOARD, ec1841_mb_device, "ec1841_mb", "EC-1840 motherboard") +DEFINE_DEVICE_TYPE(EC1840_MOTHERBOARD, ec1840_mb_device, "ec1840_mb", "EC-1840 motherboard") + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void ec1840_mb_device::device_add_mconfig(machine_config &config) +{ + ec1841_mb_device::device_add_mconfig(config); + + m_ppi8255->in_pc_callback().set(FUNC(ec1840_mb_device::pc_ppi_portc_r)); +} + +// via http://oldpc.su/pc/ec1840/ec1840rep.html +static INPUT_PORTS_START( ec1840_mb ) + PORT_START("DSW0") /* SA1 */ + PORT_DIPNAME( 0xc0, 0x40, "Number of floppy drives") + PORT_DIPSETTING( 0x00, "1" ) + PORT_DIPSETTING( 0x40, "2" ) + PORT_DIPSETTING( 0x80, "3" ) + PORT_DIPSETTING( 0xc0, "4" ) + PORT_DIPNAME( 0x30, 0x30, "Graphics adapter") + PORT_DIPSETTING( 0x00, "Reserved" ) + PORT_DIPSETTING( 0x10, "Color 40x25" ) + PORT_DIPSETTING( 0x20, "Color 80x25" ) + PORT_DIPSETTING( 0x30, "Monochrome" ) + PORT_BIT( 0x0c, 0x0c, IPT_UNUSED ) + PORT_DIPNAME( 0x02, 0x02, "DMAC installed") + PORT_DIPSETTING( 0x00, DEF_STR(No) ) + PORT_DIPSETTING( 0x02, DEF_STR(Yes) ) + PORT_DIPNAME( 0x01, 0x01, "Boot from floppy") + PORT_DIPSETTING( 0x00, DEF_STR(No) ) + PORT_DIPSETTING( 0x01, DEF_STR(Yes) ) + + PORT_START("SA2") + PORT_BIT( 0xcf, 0x00, IPT_UNUSED ) + PORT_DIPNAME( 0x20, 0x20, "SA2.5") + PORT_DIPSETTING( 0x00, DEF_STR(No) ) + PORT_DIPSETTING( 0x20, DEF_STR(Yes) ) + PORT_DIPNAME( 0x10, 0x10, "SA2.4") + PORT_DIPSETTING( 0x00, DEF_STR(No) ) + PORT_DIPSETTING( 0x10, DEF_STR(Yes) ) +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor ec1840_mb_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( ec1840_mb ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// ec1840_mb_device - constructor +//------------------------------------------------- + +ec1840_mb_device::ec1840_mb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : ec1841_mb_device(mconfig, EC1840_MOTHERBOARD, tag, owner, clock) +{ +} + +void ec1840_mb_device::device_start() +{ +} + +READ8_MEMBER( ec1840_mb_device::pc_ppi_portc_r ) +{ + int data = 0xff; + + data &= ~0x80; // no parity error + data &= ~0x40; // no error on expansion board + + if (m_ppi_portc_switch_high) + { + /* read hi nibble of SW2 */ + data = data & 0xf0; + + switch (m_ram->size()) + { + case 128 * 1024: data |= 0x00; break; + case 256 * 1024: data |= 0x01; break; + case 384 * 1024: data |= 0x02; break; + case 512 * 1024: data |= 0x03; break; + case 640 * 1024: data |= 0x04; break; + } + + PIO_LOG(1,"PIO_C_r (hi)",("$%02x\n", data)); + } + else + { + /* read lo nibble of S2 */ + data = (data & 0xf0) | (ioport("DSW0")->read() >> 4); + PIO_LOG(1,"PIO_C_r (lo)",("$%02x\n", data)); + } + + data = ( data & ~0x20 ) | ( m_pit_out2 ? 0x20 : 0x00 ); + + return data; +} + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(EC1841_MOTHERBOARD, ec1841_mb_device, "ec1841_mb", "EC-1841 motherboard") //------------------------------------------------- @@ -820,6 +931,7 @@ static INPUT_PORTS_START( ec1841_mb ) PORT_DIPSETTING( 0x00, DEF_STR(No) ) PORT_START("SA2") + PORT_BIT( 0xcb, 0x00, IPT_UNUSED ) PORT_DIPNAME( 0x04, 0x04, "Speech synthesizer") PORT_DIPSETTING( 0x00, "Installed" ) PORT_DIPSETTING( 0x04, "Not installed" ) @@ -847,6 +959,11 @@ ec1841_mb_device::ec1841_mb_device(const machine_config &mconfig, const char *ta { } +ec1841_mb_device::ec1841_mb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : ibm5160_mb_device(mconfig, type, tag, owner, clock) +{ +} + void ec1841_mb_device::device_start() { } @@ -875,7 +992,7 @@ WRITE8_MEMBER( ec1841_mb_device::pc_ppi_portb_w ) m_pc_kbdc->clock_write_from_mb(m_ppi_clock_signal); } -READ8_MEMBER ( ec1841_mb_device::pc_ppi_portc_r ) +READ8_MEMBER( ec1841_mb_device::pc_ppi_portc_r ) { int data=0xff; diff --git a/src/devices/machine/genpc.h b/src/devices/machine/genpc.h index e222b975873..876005d0a26 100644 --- a/src/devices/machine/genpc.h +++ b/src/devices/machine/genpc.h @@ -158,6 +158,7 @@ private: // device type definition DECLARE_DEVICE_TYPE(IBM5150_MOTHERBOARD, ibm5150_mb_device) + class ec1841_mb_device : public ibm5160_mb_device { public: @@ -165,6 +166,8 @@ public: ec1841_mb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: + ec1841_mb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + // optional information overrides virtual void device_add_mconfig(machine_config &config) override; virtual ioport_constructor device_input_ports() const override; @@ -180,6 +183,26 @@ private: DECLARE_DEVICE_TYPE(EC1841_MOTHERBOARD, ec1841_mb_device) +class ec1840_mb_device : public ec1841_mb_device +{ +public: + // construction/destruction + ec1840_mb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; + virtual void device_start() override; + +private: + DECLARE_READ8_MEMBER ( pc_ppi_portc_r ); + DECLARE_WRITE8_MEMBER( pc_ppi_portb_w ); +}; + +DECLARE_DEVICE_TYPE(EC1840_MOTHERBOARD, ec1840_mb_device) + + class pc_noppi_mb_device : public ibm5160_mb_device { public: diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 6abd1bb7195..9d7bed491e0 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -1012,6 +1012,18 @@ void netlist_mame_device::common_dev_start(netlist::netlist_t *lnetlist) const { auto &lsetup = lnetlist->nlstate().setup(); + // Override log statistics + pstring p = plib::util::environment("NL_STATS", ""); + if (p != "") + { + bool err=false; + bool v = plib::pstonum_ne<bool, true>(p, err); + if (err) + lsetup.log().warning("NL_STATS: invalid value {1}", p); + else + lnetlist->enable_stats(v); + } + // register additional devices nl_register_devices(lsetup); @@ -1308,11 +1320,11 @@ offs_t netlist_disassembler::disassemble(std::ostream &stream, offs_t pc, const { unsigned startpc = pc; int relpc = pc - m_dev->genPC(); - if (relpc >= 0 && relpc < m_dev->netlist().queue().size()) + if (relpc >= 0 && relpc < m_dev->netlist().queuex().size()) { - int dpc = m_dev->netlist().queue().size() - relpc - 1; - util::stream_format(stream, "%c %s @%10.7f", (relpc == 0) ? '*' : ' ', m_dev->netlist().queue()[dpc].m_object->name().c_str(), - m_dev->netlist().queue()[dpc].m_exec_time.as_double()); + int dpc = m_dev->netlist().queuex().size() - relpc - 1; + util::stream_format(stream, "%c %s @%10.7f", (relpc == 0) ? '*' : ' ', m_dev->netlist().queuex()[dpc].m_object->name().c_str(), + m_dev->netlist().queuex()[dpc].m_exec_time.as_double()); } pc+=1; |