summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/bus/isa/3c505.cpp28
-rw-r--r--src/devices/cpu/hmcs40/hmcs40d.cpp66
-rw-r--r--src/devices/cpu/hmcs40/hmcs40d.h15
-rw-r--r--src/devices/cpu/i386/cpuidmsrs.hxx33
-rw-r--r--src/devices/cpu/i386/i386.cpp4
-rw-r--r--src/devices/cpu/i386/i386.h2
-rw-r--r--src/devices/cpu/mips/mips1.cpp24
-rw-r--r--src/devices/cpu/mips/mips1.h2
-rw-r--r--src/devices/cpu/mips/r4000.cpp32
-rw-r--r--src/devices/cpu/mips/r4000.h2
-rw-r--r--src/devices/cpu/sm510/sm500core.cpp14
-rw-r--r--src/devices/cpu/sm510/sm510.h4
-rw-r--r--src/devices/cpu/sm510/sm510base.cpp7
-rw-r--r--src/devices/cpu/sm510/sm510core.cpp7
-rw-r--r--src/devices/cpu/sm510/sm510d.cpp103
-rw-r--r--src/devices/cpu/sm510/sm510d.h18
-rw-r--r--src/devices/cpu/sm510/sm510op.cpp17
-rw-r--r--src/devices/cpu/sm510/sm511core.cpp21
-rw-r--r--src/devices/cpu/sm510/sm530.h20
-rw-r--r--src/devices/cpu/sm510/sm530core.cpp121
-rw-r--r--src/devices/cpu/sm510/sm530op.cpp59
-rw-r--r--src/devices/cpu/sm510/sm590core.cpp28
-rw-r--r--src/devices/cpu/sm510/sm590op.cpp1
-rw-r--r--src/devices/cpu/sm510/sm5acore.cpp28
-rw-r--r--src/devices/cpu/tms1000/tms1k_dasm.cpp143
-rw-r--r--src/devices/cpu/tms1000/tms1k_dasm.h3
-rw-r--r--src/devices/machine/genpc.cpp121
-rw-r--r--src/devices/machine/genpc.h23
-rw-r--r--src/devices/machine/netlist.cpp20
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 &params)
{
@@ -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 &params) 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 &params)
{
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 &params, 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 &params) 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;