summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/cpu.lua20
-rw-r--r--src/devices/cpu/tms1000/tms0270.cpp181
-rw-r--r--src/devices/cpu/tms1000/tms0270.h71
-rw-r--r--src/devices/cpu/tms1000/tms0970.cpp161
-rw-r--r--src/devices/cpu/tms1000/tms0970.h57
-rw-r--r--src/devices/cpu/tms1000/tms0980.cpp231
-rw-r--r--src/devices/cpu/tms1000/tms0980.h60
-rw-r--r--src/devices/cpu/tms1000/tms1000.cpp126
-rw-r--r--src/devices/cpu/tms1000/tms1000.h45
-rw-r--r--src/devices/cpu/tms1000/tms1100.cpp87
-rw-r--r--src/devices/cpu/tms1000/tms1100.h56
-rw-r--r--src/devices/cpu/tms1000/tms1400.cpp143
-rw-r--r--src/devices/cpu/tms1000/tms1400.h61
-rw-r--r--src/devices/cpu/tms1000/tms1k_base.cpp831
-rw-r--r--src/devices/cpu/tms1000/tms1k_base.h286
-rw-r--r--src/devices/cpu/tms1000/tp0320.cpp40
-rw-r--r--src/devices/cpu/tms1000/tp0320.h32
-rw-r--r--src/mame/drivers/microvsn.cpp4
-rw-r--r--src/mame/includes/hh_tms1k.h7
19 files changed, 1383 insertions, 1116 deletions
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua
index c4e505bb37a..4d3f98a3e4c 100644
--- a/scripts/src/cpu.lua
+++ b/scripts/src/cpu.lua
@@ -1844,13 +1844,32 @@ end
--------------------------------------------------
-- Texas Instruments TMS1000 series
--@src/devices/cpu/tms1000/tms1000.h,CPUS["TMS1000"] = true
+--@src/devices/cpu/tms1000/tms1100.h,CPUS["TMS1000"] = true
+--@src/devices/cpu/tms1000/tms1400.h,CPUS["TMS1000"] = true
+--@src/devices/cpu/tms1000/tms0970.h,CPUS["TMS1000"] = true
+--@src/devices/cpu/tms1000/tms0980.h,CPUS["TMS1000"] = true
+--@src/devices/cpu/tms1000/tms0270.h,CPUS["TMS1000"] = true
+--@src/devices/cpu/tms1000/tp0320.h,CPUS["TMS1000"] = true
--------------------------------------------------
if (CPUS["TMS1000"]~=null) then
files {
MAME_DIR .. "src/devices/cpu/tms1000/tms1k_base.cpp",
MAME_DIR .. "src/devices/cpu/tms1000/tms1k_base.h",
+ MAME_DIR .. "src/devices/cpu/tms1000/tms1000.cpp",
MAME_DIR .. "src/devices/cpu/tms1000/tms1000.h",
+ MAME_DIR .. "src/devices/cpu/tms1000/tms1100.cpp",
+ MAME_DIR .. "src/devices/cpu/tms1000/tms1100.h",
+ MAME_DIR .. "src/devices/cpu/tms1000/tms1400.cpp",
+ MAME_DIR .. "src/devices/cpu/tms1000/tms1400.h",
+ MAME_DIR .. "src/devices/cpu/tms1000/tms0970.cpp",
+ MAME_DIR .. "src/devices/cpu/tms1000/tms0970.h",
+ MAME_DIR .. "src/devices/cpu/tms1000/tms0980.cpp",
+ MAME_DIR .. "src/devices/cpu/tms1000/tms0980.h",
+ MAME_DIR .. "src/devices/cpu/tms1000/tms0270.cpp",
+ MAME_DIR .. "src/devices/cpu/tms1000/tms0270.h",
+ MAME_DIR .. "src/devices/cpu/tms1000/tp0320.cpp",
+ MAME_DIR .. "src/devices/cpu/tms1000/tp0320.h",
}
end
@@ -1880,7 +1899,6 @@ end
--@src/devices/cpu/tms9900/tms9900.h,CPUS["TMS9900"] = true
--@src/devices/cpu/tms9900/tms9980a.h,CPUS["TMS9900"] = true
--@src/devices/cpu/tms9900/tms9995.h,CPUS["TMS9900"] = true
-
--------------------------------------------------
if (CPUS["TMS9900"]~=null) then
diff --git a/src/devices/cpu/tms1000/tms0270.cpp b/src/devices/cpu/tms1000/tms0270.cpp
new file mode 100644
index 00000000000..fae494efc47
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0270.cpp
@@ -0,0 +1,181 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS0270
+
+*/
+
+#include "tms0270.h"
+#include "debugger.h"
+
+// TMS0270 is a TMS0980 with earrings and a new hat. The new changes look like a quick afterthought, almost hacky
+// - RAM, ROM, and main instructions PLAs is the same as TMS0980
+// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions plus optional separate lines for custom opcode handling
+// - 48-term output PLA above the RAM (rotate opla 90 degrees)
+const device_type TMS0270 = &device_creator<tms0270_cpu_device>; // 40-pin DIP, 16 O pins, 8+ R pins (some R pins are internally hooked up to support more I/O)
+// newer TMS0270 chips (eg. Speak & Math) have 42 pins
+
+// TMS0260 is same or similar?
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device)
+ AM_RANGE(0x000, 0xfff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_64x9_as4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ AM_RANGE(0x80, 0x8f) AM_RAM AM_MIRROR(0x70) // DAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms0270_cpu_device::tms0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0980_cpu_device(mconfig, TMS0270, "TMS0270", tag, owner, clock, 16 /* o pins */, 16 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_64x9_as4), "tms0270", __FILE__)
+ , m_read_ctl(*this)
+ , m_write_ctl(*this)
+ , m_write_pdc(*this)
+{ }
+
+
+// machine configs
+static MACHINE_CONFIG_FRAGMENT(tms0270)
+
+ // main opcodes PLA, microinstructions PLA, output PLA
+ MCFG_PLA_ADD("ipla", 9, 22, 24)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("mpla", 6, 22, 64)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 6, 16, 48)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms0270_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms0270);
+}
+
+
+// device_start/reset
+void tms0270_cpu_device::device_start()
+{
+ // common init
+ tms1k_base_device::device_start();
+
+ m_read_ctl.resolve_safe(0);
+ m_write_ctl.resolve_safe();
+ m_write_pdc.resolve_safe();
+
+ // zerofill
+ m_r_prev = 0;
+ m_chipsel = 0;
+ m_ctl_dir = 0;
+ m_ctl_out = 0;
+ m_pdc = -1; // !
+
+ m_o_latch_low = 0;
+ m_o_latch = 0;
+ m_o_latch_prev = 0;
+
+ // register for savestates
+ save_item(NAME(m_r_prev));
+ save_item(NAME(m_chipsel));
+ save_item(NAME(m_ctl_dir));
+ save_item(NAME(m_ctl_out));
+ save_item(NAME(m_pdc));
+
+ save_item(NAME(m_o_latch_low));
+ save_item(NAME(m_o_latch));
+ save_item(NAME(m_o_latch_prev));
+}
+
+void tms0270_cpu_device::device_reset()
+{
+ // common reset
+ tms0980_cpu_device::device_reset();
+
+ m_o_latch_low = 0;
+ m_o_latch = 0;
+ m_o_latch_prev = 0;
+}
+
+
+// i/o handling
+void tms0270_cpu_device::dynamic_output()
+{
+ // R11: TMS5100 CTL port direction (0=read from TMS5100, 1=write to TMS5100)
+ m_ctl_dir = m_r >> 11 & 1;
+
+ // R12: chip select (off=display via OPLA, on=TMS5100 via ACC/CKB)
+ m_chipsel = m_r >> 12 & 1;
+
+ if (m_chipsel)
+ {
+ // ACC via SEG G,B,C,D: TMS5100 CTL pins
+ if (m_ctl_dir && m_a != m_ctl_out)
+ {
+ m_ctl_out = m_a;
+ m_write_ctl(0, m_ctl_out, 0xff);
+ }
+
+ // R10 via SEG E: TMS5100 PDC pin
+ if (m_pdc != (m_r >> 10 & 1))
+ {
+ m_pdc = m_r >> 10 & 1;
+ m_write_pdc(m_pdc);
+ }
+ }
+ else
+ {
+ // standard O-output
+ if (m_o_latch != m_o_latch_prev)
+ {
+ write_o_output(m_o_latch);
+ m_o_latch_prev = m_o_latch;
+ }
+ }
+
+ // standard R-output
+ if (m_r != m_r_prev)
+ {
+ m_write_r(0, m_r & m_r_mask, 0xffff);
+ m_r_prev = m_r;
+ }
+}
+
+UINT8 tms0270_cpu_device::read_k_input()
+{
+ // external: TMS5100 CTL port via SEG G,B,C,D
+ if (m_chipsel)
+ return (m_ctl_dir) ? m_ctl_out : m_read_ctl(0, 0xff) & 0xf;
+
+ // standard K-input otherwise
+ UINT8 k = m_read_k(0, 0xff) & 0x1f;
+ return (k & 0x10) ? 0xf : k; // the TMS0270 KF line asserts all K-inputs
+}
+
+
+// opcode deviations
+void tms0270_cpu_device::op_setr()
+{
+ // same as default, but handle write to output in dynamic_output
+ m_r = m_r | (1 << m_y);
+}
+
+void tms0270_cpu_device::op_rstr()
+{
+ // same as default, but handle write to output in dynamic_output
+ m_r = m_r & ~(1 << m_y);
+}
+
+void tms0270_cpu_device::op_tdo()
+{
+ // TDO: transfer data out
+ if (m_status)
+ m_o_latch_low = m_a;
+ else
+ m_o_latch = m_o_latch_low | (m_a << 4 & 0x30);
+
+ // write to output is done in dynamic_output
+}
diff --git a/src/devices/cpu/tms1000/tms0270.h b/src/devices/cpu/tms1000/tms0270.h
new file mode 100644
index 00000000000..6d4e0142f3a
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0270.h
@@ -0,0 +1,71 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS0270
+
+*/
+
+#ifndef _TMS0270_H_
+#define _TMS0270_H_
+
+#include "tms0980.h"
+
+
+// TMS0270 was designed to interface with TMS5100, set it up at driver level
+#define MCFG_TMS0270_READ_CTL_CB(_devcb) \
+ tms0270_cpu_device::set_read_ctl_callback(*device, DEVCB_##_devcb);
+
+#define MCFG_TMS0270_WRITE_CTL_CB(_devcb) \
+ tms0270_cpu_device::set_write_ctl_callback(*device, DEVCB_##_devcb);
+
+#define MCFG_TMS0270_WRITE_PDC_CB(_devcb) \
+ tms0270_cpu_device::set_write_pdc_callback(*device, DEVCB_##_devcb);
+
+
+class tms0270_cpu_device : public tms0980_cpu_device
+{
+public:
+ tms0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // static configuration helpers
+ template<class _Object> static devcb_base &set_read_ctl_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_read_ctl.set_callback(object); }
+ template<class _Object> static devcb_base &set_write_ctl_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_write_ctl.set_callback(object); }
+ template<class _Object> static devcb_base &set_write_pdc_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_write_pdc.set_callback(object); }
+
+protected:
+ // overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual void write_o_output(UINT8 index) override { tms1k_base_device::write_o_output(index); }
+ virtual UINT8 read_k_input() override;
+ virtual void dynamic_output() override;
+
+ virtual void op_setr() override;
+ virtual void op_rstr() override;
+ virtual void op_tdo() override;
+
+private:
+ // state specific to interface with TMS5100
+ UINT16 m_r_prev;
+ UINT8 m_chipsel;
+ UINT8 m_ctl_out;
+ UINT8 m_ctl_dir;
+ int m_pdc;
+
+ UINT8 m_o_latch_low;
+ UINT8 m_o_latch;
+ UINT8 m_o_latch_prev;
+
+ devcb_read8 m_read_ctl;
+ devcb_write8 m_write_ctl;
+ devcb_write_line m_write_pdc;
+};
+
+
+extern const device_type TMS0270;
+
+#endif /* _TMS0270_H_ */
diff --git a/src/devices/cpu/tms1000/tms0970.cpp b/src/devices/cpu/tms1000/tms0970.cpp
new file mode 100644
index 00000000000..2eabe847bb9
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0970.cpp
@@ -0,0 +1,161 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS0950, TMS0970, TMS1990
+
+*/
+
+#include "tms0970.h"
+#include "debugger.h"
+
+// TMS0950 is a TMS1000 with a TMS0980 style opla, it was quickly succeeded by the TMS0970
+// - RAM, ROM, microinstructions is the same as TMS1000
+// - 10-term inverted output PLA and segment PLA on the top-left
+const device_type TMS0950 = &device_creator<tms0950_cpu_device>; // 28-pin DIP, 8 O pins, 11? R pins
+
+// TMS0970 is a stripped-down version of the TMS0980, itself acting more like a TMS1000
+// - RAM and ROM is the same as TMS1000
+// - main instructions PLAs at the top half, to the right of the midline
+// * see TMS0980 notes, except that the fixed instruction list differs:
+// RETN, SETR, RBIT, SBIT, LDX, COMX, TDO, ..., redir(----0-00), LDP
+// - 32-term microinstructions PLA between the RAM and ROM, supporting 15 microinstructions
+// - 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees)
+const device_type TMS0970 = &device_creator<tms0970_cpu_device>; // 28-pin DIP, 11 R pins (note: pinout may slightly differ from chip to chip)
+const device_type TMS1990 = &device_creator<tms1990_cpu_device>; // 28-pin DIP, ? R pins..
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_10bit_8, AS_PROGRAM, 8, tms1k_base_device)
+ AM_RANGE(0x000, 0x3ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_64x4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x3f) AM_RAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms0970_cpu_device::tms0970_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1000_cpu_device(mconfig, TMS0970, "TMS0970", tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 2 /* x width */, 10 /* prg width */, ADDRESS_MAP_NAME(program_10bit_8), 6 /* data width */, ADDRESS_MAP_NAME(data_64x4), "tms0970", __FILE__)
+{ }
+
+tms0970_cpu_device::tms0970_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms1000_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms0950_cpu_device::tms0950_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0970_cpu_device(mconfig, TMS0950, "TMS0950", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms0950", __FILE__)
+{ }
+
+tms1990_cpu_device::tms1990_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0970_cpu_device(mconfig, TMS1990, "TMS1990", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1990", __FILE__)
+{ }
+
+
+// machine configs
+static MACHINE_CONFIG_FRAGMENT(tms0950)
+
+ // microinstructions PLA, output PLA, segment PLA
+ MCFG_PLA_ADD("mpla", 8, 16, 30)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 4, 8, 10)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("spla", 3, 8, 8)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms0950_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms0950);
+}
+
+static MACHINE_CONFIG_FRAGMENT(tms0970)
+
+ // main opcodes PLA, microinstructions PLA, output PLA, segment PLA
+ MCFG_PLA_ADD("ipla", 8, 15, 18)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("mpla", 5, 15, 32)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 4, 8, 16)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("spla", 3, 8, 8)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms0970_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms0970);
+}
+
+
+// device_reset
+void tms0970_cpu_device::device_reset()
+{
+ // common reset
+ tms1k_base_device::device_reset();
+
+ // pre-decode instructionset
+ m_fixed_decode.resize(0x100);
+ memset(&m_fixed_decode[0], 0, 0x100*sizeof(UINT32));
+ m_micro_decode.resize(0x100);
+ memset(&m_micro_decode[0], 0, 0x100*sizeof(UINT32));
+
+ for (int op = 0; op < 0x100; op++)
+ {
+ // upper half of the opcodes is always branch/call
+ if (op & 0x80)
+ m_fixed_decode[op] = (op & 0x40) ? F_CALL: F_BR;
+
+ // 5 output bits select a microinstruction index
+ UINT32 imask = m_ipla->read(op);
+ UINT8 msel = imask & 0x1f;
+
+ // but if (from bottom to top) term 1 is active and output bit 5 is 0, R2,R4-R7 directly select a microinstruction index
+ if (imask & 0x40 && (imask & 0x20) == 0)
+ msel = (op & 0xf) | (op >> 1 & 0x10);
+
+ msel = BITSWAP8(msel,7,6,5,0,1,2,3,4); // lines are reversed
+ UINT32 mmask = m_mpla->read(msel);
+ mmask ^= 0x09fe; // invert active-negative
+
+ // _____ _____ _____ _____ ______ _____ ______ _____ _____
+ const UINT32 md[15] = { M_CKM, M_CKP, M_YTP, M_MTP, M_ATN, M_NATN, M_MTN, M_15TN, M_CKN, M_NE, M_C8, M_CIN, M_AUTA, M_AUTY, M_STO };
+
+ for (int bit = 0; bit < 15; bit++)
+ if (mmask & (1 << bit))
+ m_micro_decode[op] |= md[bit];
+
+ // the other ipla terms each select a fixed instruction
+ const UINT32 id[8] = { F_LDP, F_TDO, F_COMX, F_LDX, F_SBIT, F_RBIT, F_SETR, F_RETN };
+
+ for (int bit = 0; bit < 8; bit++)
+ if (imask & (0x80 << bit))
+ m_fixed_decode[op] |= id[bit];
+ }
+}
+
+
+// i/o handling
+void tms0970_cpu_device::write_o_output(UINT8 index)
+{
+ m_o = m_spla->read(index);
+ m_write_o(0, m_o & m_o_mask, 0xffff);
+}
+
+
+// opcode deviations
+void tms0970_cpu_device::op_setr()
+{
+ // SETR: set output register
+ // DDIG line is a coincidence between the selected output pla row(s) and segment pla row(s)
+ int ddig = (m_opla->read(m_a) & m_o) ? 1 : 0;
+ m_r = (m_r & ~(1 << m_y)) | (ddig << m_y);
+}
+
+void tms0970_cpu_device::op_tdo()
+{
+ // TDO: transfer digits to output
+ write_o_output(m_a & 0x7);
+ m_write_r(0, m_r & m_r_mask, 0xffff);
+}
diff --git a/src/devices/cpu/tms1000/tms0970.h b/src/devices/cpu/tms1000/tms0970.h
new file mode 100644
index 00000000000..627dfa24c69
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0970.h
@@ -0,0 +1,57 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS0950, TMS0970, TMS1990
+
+*/
+
+#ifndef _TMS0970_H_
+#define _TMS0970_H_
+
+#include "tms1000.h"
+
+
+class tms0970_cpu_device : public tms1000_cpu_device
+{
+public:
+ tms0970_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms0970_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+
+protected:
+ // overrides
+ virtual void device_reset() override;
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual void write_o_output(UINT8 index) override;
+
+ virtual void op_setr() override;
+ virtual void op_tdo() override;
+};
+
+class tms0950_cpu_device : public tms0970_cpu_device
+{
+public:
+ tms0950_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // overrides
+ virtual void device_reset() override { tms1000_cpu_device::device_reset(); }
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual void op_rstr() override { ; } // assume it has no RSTR or CLO
+ virtual void op_clo() override { ; } // "
+};
+
+class tms1990_cpu_device : public tms0970_cpu_device
+{
+public:
+ tms1990_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+extern const device_type TMS0950;
+extern const device_type TMS0970;
+extern const device_type TMS1990;
+
+#endif /* _TMS0970_H_ */
diff --git a/src/devices/cpu/tms1000/tms0980.cpp b/src/devices/cpu/tms1000/tms0980.cpp
new file mode 100644
index 00000000000..cda96386b38
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0980.cpp
@@ -0,0 +1,231 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS0980, TMS1980
+
+*/
+
+#include "tms0980.h"
+#include "debugger.h"
+
+// TMS0980
+// - 64x9bit RAM array at the bottom-left (set up as 144x4)
+// - 2048x9bit ROM array at the bottom-left
+// - main instructions PLAs at the top half, to the right of the midline
+// * top section is assumed to be the CKI bus select
+// * middle section is for microinstruction redirection, this part may differ per die
+// * rest is fixed instructions select, from top-to-bottom: SEAC, LDX, COMX, COMX8,
+// TDO, SBIT, RETN, SETR, REAC, XDA, SAL, RBIT, ..., OFF, SBL, LDP, redir(------00- + R0^BL)
+// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions
+// - 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees)
+const device_type TMS0980 = &device_creator<tms0980_cpu_device>; // 28-pin DIP, 9 R pins
+
+// TMS1980 is a TMS0980 with a TMS1x00 style opla
+// - RAM, ROM, and main instructions PLAs is the same as TMS0980
+// - one of the microinstructions redirects to a RSTR instruction, like on TMS0270
+// - 32-term inverted output PLA above the RAM, 7 bits! (rotate opla 270 degrees)
+const device_type TMS1980 = &device_creator<tms1980_cpu_device>; // 28-pin DIP, 7 O pins, 10 R pins, high voltage
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device)
+ AM_RANGE(0x000, 0xfff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_64x9_as4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ AM_RANGE(0x80, 0x8f) AM_RAM AM_MIRROR(0x70) // DAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0970_cpu_device(mconfig, TMS0980, "TMS0980", tag, owner, clock, 8 /* o pins */, 9 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_64x9_as4), "tms0980", __FILE__)
+{ }
+
+tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms0970_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms1980_cpu_device::tms1980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0980_cpu_device(mconfig, TMS1980, "TMS1980", tag, owner, clock, 7, 10, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tms1980", __FILE__)
+{ }
+
+
+// machine configs
+static MACHINE_CONFIG_FRAGMENT(tms0980)
+
+ // main opcodes PLA, microinstructions PLA, output PLA, segment PLA
+ MCFG_PLA_ADD("ipla", 9, 22, 24)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("mpla", 6, 20, 64)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 4, 8, 16)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("spla", 3, 8, 8)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms0980_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms0980);
+}
+
+static MACHINE_CONFIG_FRAGMENT(tms1980)
+
+ // main opcodes PLA, microinstructions PLA, output PLA
+ MCFG_PLA_ADD("ipla", 9, 22, 24)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("mpla", 6, 22, 64)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 5, 7, 32)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms1980_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms1980);
+}
+
+
+// disasm
+offs_t tms0980_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE(tms0980);
+ return CPU_DISASSEMBLE_NAME(tms0980)(this, buffer, pc, oprom, opram, options);
+}
+
+
+// device_reset
+UINT32 tms0980_cpu_device::decode_micro(UINT8 sel)
+{
+ UINT32 decode = 0;
+
+ sel = BITSWAP8(sel,7,6,0,1,2,3,4,5); // lines are reversed
+ UINT32 mask = m_mpla->read(sel);
+ mask ^= 0x43fc3; // invert active-negative
+
+ // M_RSTR is specific to TMS02x0/TMS1980, it redirects to F_RSTR
+ // M_UNK1 is specific to TMS0270, unknown/unused yet and apparently not connected on every TMS0270
+ // _______ ______ _____ _____ _____ _____ ______ _____ ______ _____ _____
+ const UINT32 md[22] = { M_NDMTP, M_DMTP, M_AUTY, M_AUTA, M_CKM, M_SSE, M_CKP, M_YTP, M_MTP, M_ATN, M_NATN, M_MTN, M_15TN, M_CKN, M_NE, M_C8, M_SSS, M_CME, M_CIN, M_STO, M_RSTR, M_UNK1 };
+
+ for (int bit = 0; bit < 22 && bit < m_mpla->outputs(); bit++)
+ if (mask & (1 << bit))
+ decode |= md[bit];
+
+ return decode;
+}
+
+void tms0980_cpu_device::device_reset()
+{
+ // common reset
+ tms1k_base_device::device_reset();
+
+ // pre-decode instructionset
+ m_fixed_decode.resize(0x200);
+ memset(&m_fixed_decode[0], 0, 0x200*sizeof(UINT32));
+ m_micro_decode.resize(0x200);
+ memset(&m_micro_decode[0], 0, 0x200*sizeof(UINT32));
+
+ for (int op = 0; op < 0x200; op++)
+ {
+ // upper half of the opcodes is always branch/call
+ if (op & 0x100)
+ m_fixed_decode[op] = (op & 0x80) ? F_CALL: F_BR;
+
+ UINT32 imask = m_ipla->read(op);
+
+ // 6 output bits select a microinstruction index
+ m_micro_decode[op] = decode_micro(imask & 0x3f);
+
+ // the other ipla terms each select a fixed instruction
+ const UINT32 id[15] = { F_LDP, F_SBL, F_OFF, F_RBIT, F_SAL, F_XDA, F_REAC, F_SETR, F_RETN, F_SBIT, F_TDO, F_COMX8, F_COMX, F_LDX, F_SEAC };
+
+ for (int bit = 0; bit < 15; bit++)
+ if (imask & (0x80 << bit))
+ m_fixed_decode[op] |= id[bit];
+ }
+
+ // like on TMS0970, one of the terms directly select a microinstruction index (via R4-R8),
+ // but it can't be pre-determined when it's active
+ m_micro_direct.resize(0x40);
+ memset(&m_micro_decode[0], 0, 0x40*sizeof(UINT32));
+
+ for (int op = 0; op < 0x40; op++)
+ m_micro_direct[op] = decode_micro(op);
+}
+
+
+// program counter/opcode decode
+void tms0980_cpu_device::read_opcode()
+{
+ debugger_instruction_hook(this, m_rom_address << 1);
+ m_opcode = m_program->read_word(m_rom_address << 1) & 0x1ff;
+ m_c4 = BITSWAP8(m_opcode,7,6,5,4,0,1,2,3) & 0xf; // opcode operand is bitswapped for most opcodes
+
+ m_fixed = m_fixed_decode[m_opcode];
+
+ // if ipla term 0 is active, R4-R8 directly select a microinstruction index when R0 or R0^BL is 0
+ int r0 = m_opcode >> 8 & 1;
+ if (m_ipla->read(m_opcode) & 0x40 && !((r0 & m_bl) ^ r0))
+ m_micro = m_micro_direct[m_opcode & 0x3f];
+ else
+ m_micro = m_micro_decode[m_opcode];
+
+ // redirect mpla fixed instructions
+ if (m_micro & M_RSTR) m_fixed |= F_RSTR;
+ if (m_micro & M_SETR) m_fixed |= F_SETR;
+
+ next_pc();
+}
+
+
+// i/o handling
+UINT8 tms0980_cpu_device::read_k_input()
+{
+ UINT8 k = m_read_k(0, 0xff) & 0x1f;
+ UINT8 k3 = (k & 0x10) ? 3: 0; // the TMS0980 K3 line is simply K1|K2
+ return (k & 0xf) | k3;
+}
+
+void tms0980_cpu_device::set_cki_bus()
+{
+ switch (m_opcode & 0x1f8)
+ {
+ // 000001XXX: K-inputs
+ case 0x008:
+ m_cki_bus = read_k_input();
+ break;
+
+ // 0X0100XXX: select bit
+ case 0x020: case 0x0a0:
+ m_cki_bus = 1 << (m_c4 >> 2) ^ 0xf;
+ break;
+
+ // 0X1XXXXXX: constant
+ case 0x040: case 0x048: case 0x050: case 0x058: case 0x060: case 0x068: case 0x070: case 0x078:
+ case 0x0c0: case 0x0c8: case 0x0d0: case 0x0d8: case 0x0e0: case 0x0e8: case 0x0f0: case 0x0f8:
+ m_cki_bus = m_c4;
+ break;
+
+ default:
+ m_cki_bus = 0;
+ break;
+ }
+}
+
+
+// opcode deviations
+void tms0980_cpu_device::op_comx()
+{
+ // COMX: complement X register, but not the MSB
+ m_x ^= (m_x_mask >> 1);
+}
+
+void tms1980_cpu_device::op_tdo()
+{
+ // TDO: transfer accumulator and status(not status_latch!) to O-output
+ write_o_output(m_status << 4 | m_a);
+}
diff --git a/src/devices/cpu/tms1000/tms0980.h b/src/devices/cpu/tms1000/tms0980.h
new file mode 100644
index 00000000000..793c32cb1fc
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0980.h
@@ -0,0 +1,60 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS0980, TMS1980
+
+*/
+
+#ifndef _TMS0980_H_
+#define _TMS0980_H_
+
+#include "tms0970.h"
+
+
+class tms0980_cpu_device : public tms0970_cpu_device
+{
+public:
+ tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+
+protected:
+ // overrides
+ virtual void device_reset() override;
+
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual UINT32 disasm_min_opcode_bytes() const override { return 2; }
+ virtual UINT32 disasm_max_opcode_bytes() const override { return 2; }
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
+
+ virtual UINT8 read_k_input() override;
+ virtual void set_cki_bus() override;
+ virtual void read_opcode() override;
+
+ virtual void op_comx() override;
+
+ UINT32 decode_micro(UINT8 sel);
+};
+
+class tms1980_cpu_device : public tms0980_cpu_device
+{
+public:
+ tms1980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // overrides
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual void write_o_output(UINT8 index) override { tms1k_base_device::write_o_output(index); }
+ virtual UINT8 read_k_input() override { return tms1k_base_device::read_k_input(); }
+
+ virtual void op_setr() override { tms1k_base_device::op_setr(); }
+ virtual void op_tdo() override;
+};
+
+
+extern const device_type TMS0980;
+extern const device_type TMS1980;
+
+#endif /* _TMS0980_H_ */
diff --git a/src/devices/cpu/tms1000/tms1000.cpp b/src/devices/cpu/tms1000/tms1000.cpp
new file mode 100644
index 00000000000..2edb517155f
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1000.cpp
@@ -0,0 +1,126 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS1000, TMS1070, TMS1040, TMS1200
+
+*/
+
+#include "tms1000.h"
+#include "debugger.h"
+
+// TMS1000
+// - 64x4bit RAM array at the bottom-left
+// - 1024x8bit ROM array at the bottom-right
+// * FYI, the row-selector to the left of it is laid out as:
+// 3,4,11,12,19,20,27,28,35,36,43,44,51,52,59,60,0,7,8,15,16,23,24,31,32,39,40,47,48,55,56,63,
+// 2,5,10,13,18,21,26,29,34,37,42,45,50,53,58,61,1,6,9,14,17,22,25,30,33,38,41,46,49,54,57,62
+// - 30-term microinstructions PLA(mpla) at the top half, to the right of the midline, supporting 16 microinstructions
+// - 20-term output PLA(opla) at the top-left
+// - the ALU is between the opla and mpla
+const device_type TMS1000 = &device_creator<tms1000_cpu_device>; // 28-pin DIP, 11 R pins
+const device_type TMS1070 = &device_creator<tms1070_cpu_device>; // high voltage version
+const device_type TMS1040 = &device_creator<tms1040_cpu_device>; // same as TMS1070 with just a different pinout?
+const device_type TMS1200 = &device_creator<tms1200_cpu_device>; // 40-pin DIP, 13 R pins
+// TMS1270 has 10 O pins, how does that work?
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_10bit_8, AS_PROGRAM, 8, tms1k_base_device)
+ AM_RANGE(0x000, 0x3ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_64x4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x3f) AM_RAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1k_base_device(mconfig, TMS1000, "TMS1000", tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 2 /* x width */, 10 /* prg width */, ADDRESS_MAP_NAME(program_10bit_8), 6 /* data width */, ADDRESS_MAP_NAME(data_64x4), "tms1000", __FILE__)
+{ }
+
+tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms1k_base_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms1070_cpu_device::tms1070_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1000_cpu_device(mconfig, TMS1070, "TMS1070", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1070", __FILE__)
+{ }
+
+tms1040_cpu_device::tms1040_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1000_cpu_device(mconfig, TMS1040, "TMS1040", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1040", __FILE__)
+{ }
+
+tms1200_cpu_device::tms1200_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1000_cpu_device(mconfig, TMS1200, "TMS1200", tag, owner, clock, 8, 13, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1200", __FILE__)
+{ }
+
+
+// machine configs
+static MACHINE_CONFIG_FRAGMENT(tms1000)
+
+ // microinstructions PLA, output PLA
+ MCFG_PLA_ADD("mpla", 8, 16, 30)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 5, 8, 20)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms1000_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms1000);
+}
+
+
+// disasm
+offs_t tms1000_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE(tms1000);
+ return CPU_DISASSEMBLE_NAME(tms1000)(this, buffer, pc, oprom, opram, options);
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void tms1000_cpu_device::device_reset()
+{
+ // common reset
+ tms1k_base_device::device_reset();
+
+ // pre-decode instructionset
+ m_fixed_decode.resize(0x100);
+ memset(&m_fixed_decode[0], 0, 0x100*sizeof(UINT32));
+ m_micro_decode.resize(0x100);
+ memset(&m_micro_decode[0], 0, 0x100*sizeof(UINT32));
+
+ for (int op = 0; op < 0x100; op++)
+ {
+ // _____ _____ ______ _____ ______ _____ _____ _____ _____
+ const UINT32 md[16] = { M_STSL, M_AUTY, M_AUTA, M_CIN, M_C8, M_NE, M_CKN, M_15TN, M_MTN, M_NATN, M_ATN, M_MTP, M_YTP, M_CKP, M_CKM, M_STO };
+ UINT16 mask = m_mpla->read(op);
+ mask ^= 0x3fc8; // invert active-negative
+
+ for (int bit = 0; bit < 16; bit++)
+ if (mask & (1 << bit))
+ m_micro_decode[op] |= md[bit];
+ }
+
+ // the fixed instruction set is not programmable
+ m_fixed_decode[0x00] = F_COMX;
+ m_fixed_decode[0x0a] = F_TDO;
+ m_fixed_decode[0x0b] = F_CLO;
+ m_fixed_decode[0x0c] = F_RSTR;
+ m_fixed_decode[0x0d] = F_SETR;
+ m_fixed_decode[0x0f] = F_RETN;
+
+ for (int i = 0x10; i < 0x20; i++) m_fixed_decode[i] = F_LDP;
+ for (int i = 0x30; i < 0x34; i++) m_fixed_decode[i] = F_SBIT;
+ for (int i = 0x34; i < 0x38; i++) m_fixed_decode[i] = F_RBIT;
+ for (int i = 0x3c; i < 0x40; i++) m_fixed_decode[i] = F_LDX;
+
+ for (int i = 0x80; i < 0xc0; i++) m_fixed_decode[i] = F_BR;
+ for (int i = 0xc0; i < 0x100; i++) m_fixed_decode[i] = F_CALL;
+}
diff --git a/src/devices/cpu/tms1000/tms1000.h b/src/devices/cpu/tms1000/tms1000.h
index 8b042b78cf8..1a2d98822e5 100644
--- a/src/devices/cpu/tms1000/tms1000.h
+++ b/src/devices/cpu/tms1000/tms1000.h
@@ -1,5 +1,10 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS1000, TMS1070, TMS1040, TMS1200
+
+*/
#ifndef _TMS1000_H_
#define _TMS1000_H_
@@ -7,4 +12,44 @@
#include "tms1k_base.h"
+class tms1000_cpu_device : public tms1k_base_device
+{
+public:
+ tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms1000_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+
+protected:
+ // overrides
+ virtual void device_reset() override;
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
+};
+
+class tms1070_cpu_device : public tms1000_cpu_device
+{
+public:
+ tms1070_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class tms1040_cpu_device : public tms1000_cpu_device
+{
+public:
+ tms1040_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+class tms1200_cpu_device : public tms1000_cpu_device
+{
+public:
+ tms1200_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+extern const device_type TMS1000;
+extern const device_type TMS1070;
+extern const device_type TMS1040;
+extern const device_type TMS1200;
+
#endif /* _TMS1000_H_ */
diff --git a/src/devices/cpu/tms1000/tms1100.cpp b/src/devices/cpu/tms1000/tms1100.cpp
new file mode 100644
index 00000000000..39b6ed70e6f
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1100.cpp
@@ -0,0 +1,87 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS1100, TMS1170, TMS1300, TMS1370
+
+*/
+
+#include "tms1100.h"
+#include "debugger.h"
+
+// TMS1100 is nearly the same as TMS1000, some different opcodes, and with double the RAM and ROM
+const device_type TMS1100 = &device_creator<tms1100_cpu_device>; // 28-pin DIP, 11 R pins
+const device_type TMS1170 = &device_creator<tms1170_cpu_device>; // high voltage version
+const device_type TMS1300 = &device_creator<tms1300_cpu_device>; // 40-pin DIP, 16 R pins
+const device_type TMS1370 = &device_creator<tms1370_cpu_device>; // high voltage version
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_11bit_8, AS_PROGRAM, 8, tms1k_base_device)
+ AM_RANGE(0x000, 0x7ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_128x4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1000_cpu_device(mconfig, TMS1100, "TMS1100", tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 3 /* x width */, 11 /* prg width */, ADDRESS_MAP_NAME(program_11bit_8), 7 /* data width */, ADDRESS_MAP_NAME(data_128x4), "tms1100", __FILE__)
+{ }
+
+tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms1000_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms1170_cpu_device::tms1170_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1100_cpu_device(mconfig, TMS1170, "TMS1170", tag, owner, clock, 8, 11, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1170", __FILE__)
+{ }
+
+tms1300_cpu_device::tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1100_cpu_device(mconfig, TMS1300, "TMS1300", tag, owner, clock, 8, 16, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1300", __FILE__)
+{ }
+
+tms1370_cpu_device::tms1370_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1100_cpu_device(mconfig, TMS1370, "TMS1370", tag, owner, clock, 8, 16, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1370", __FILE__)
+{ }
+
+
+// disasm
+offs_t tms1100_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE(tms1100);
+ return CPU_DISASSEMBLE_NAME(tms1100)(this, buffer, pc, oprom, opram, options);
+}
+
+
+// device_reset
+void tms1100_cpu_device::device_reset()
+{
+ tms1000_cpu_device::device_reset();
+
+ // small differences in 00-3f area
+ m_fixed_decode[0x00] = 0;
+ m_fixed_decode[0x09] = F_COMX8; // !
+ m_fixed_decode[0x0b] = F_COMC;
+
+ for (int i = 0x28; i < 0x30; i++) m_fixed_decode[i] = F_LDX;
+ for (int i = 0x3c; i < 0x40; i++) m_fixed_decode[i] = 0;
+}
+
+
+// opcode deviations
+void tms1100_cpu_device::op_setr()
+{
+ // SETR: same, but X register MSB must be clear
+ if (~m_x & (1 << (m_x_bits-1)))
+ tms1k_base_device::op_setr();
+}
+
+void tms1100_cpu_device::op_rstr()
+{
+ // RSTR: same, but X register MSB must be clear
+ if (~m_x & (1 << (m_x_bits-1)))
+ tms1k_base_device::op_rstr();
+}
diff --git a/src/devices/cpu/tms1000/tms1100.h b/src/devices/cpu/tms1000/tms1100.h
new file mode 100644
index 00000000000..ae3c5868532
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1100.h
@@ -0,0 +1,56 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS1100, TMS1170, TMS1300, TMS1370
+
+*/
+
+#ifndef _TMS1100_H_
+#define _TMS1100_H_
+
+#include "tms1000.h"
+
+
+class tms1100_cpu_device : public tms1000_cpu_device
+{
+public:
+ tms1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms1100_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+
+protected:
+ // overrides
+ virtual void device_reset() override;
+
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
+
+ virtual void op_setr() override;
+ virtual void op_rstr() override;
+};
+
+class tms1170_cpu_device : public tms1100_cpu_device
+{
+public:
+ tms1170_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class tms1300_cpu_device : public tms1100_cpu_device
+{
+public:
+ tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class tms1370_cpu_device : public tms1100_cpu_device
+{
+public:
+ tms1370_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+extern const device_type TMS1100;
+extern const device_type TMS1170;
+extern const device_type TMS1300;
+extern const device_type TMS1370;
+
+
+#endif /* _TMS1100_H_ */
diff --git a/src/devices/cpu/tms1000/tms1400.cpp b/src/devices/cpu/tms1000/tms1400.cpp
new file mode 100644
index 00000000000..f1bada9c6c9
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1400.cpp
@@ -0,0 +1,143 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS1400, TMS1470, TMS1600, TMS1670
+
+ TODO:
+ - emulate TMS1600 L-pins
+
+*/
+
+#include "tms1400.h"
+#include "debugger.h"
+
+// TMS1400 follows the TMS1100, it doubles the ROM size again (4 chapters of 16 pages), and adds a 3-level callstack
+// - rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100
+// - the opla size is increased from 20 to 32 terms
+const device_type TMS1400 = &device_creator<tms1400_cpu_device>; // 28-pin DIP, 11 R pins (TMS1400CR is same, but with TMS1100 pinout)
+const device_type TMS1470 = &device_creator<tms1470_cpu_device>; // high voltage version, 1 R pin removed for Vdd
+
+// TMS1600 adds more I/O to the TMS1400, input pins are doubled with added L1,2,4,8
+// - rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100
+// - the opla size is increased from 20 to 32 terms
+const device_type TMS1600 = &device_creator<tms1600_cpu_device>; // 40-pin DIP, 16 R pins
+const device_type TMS1670 = &device_creator<tms1670_cpu_device>; // high voltage version
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_12bit_8, AS_PROGRAM, 8, tms1k_base_device)
+ AM_RANGE(0x000, 0xfff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_128x4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms1400_cpu_device::tms1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1100_cpu_device(mconfig, TMS1400, "TMS1400", tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 3 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_12bit_8), 7 /* data width */, ADDRESS_MAP_NAME(data_128x4), "tms1400", __FILE__)
+{ }
+
+tms1400_cpu_device::tms1400_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms1100_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms1470_cpu_device::tms1470_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1400_cpu_device(mconfig, TMS1470, "TMS1470", tag, owner, clock, 8, 10, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1470", __FILE__)
+{ }
+
+
+tms1600_cpu_device::tms1600_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1400_cpu_device(mconfig, TMS1600, "TMS1600", tag, owner, clock, 8, 16, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1600", __FILE__)
+{ }
+
+tms1600_cpu_device::tms1600_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms1400_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms1670_cpu_device::tms1670_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1600_cpu_device(mconfig, TMS1670, "TMS1670", tag, owner, clock, 8, 16, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1670", __FILE__)
+{ }
+
+
+// machine configs
+static MACHINE_CONFIG_FRAGMENT(tms1400)
+
+ // microinstructions PLA, output PLA
+ MCFG_PLA_ADD("mpla", 8, 16, 30)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 5, 8, 32)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms1400_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms1400);
+}
+
+
+// device_reset
+void tms1400_cpu_device::device_reset()
+{
+ tms1100_cpu_device::device_reset();
+
+ // small differences in 00-3f area
+ m_fixed_decode[0x0b] = F_TPC;
+}
+
+
+// opcode deviations
+void tms1400_cpu_device::op_br()
+{
+ // BR/BL: conditional branch
+ if (m_status)
+ {
+ m_pa = m_pb; // don't care about clatch
+ m_ca = m_cb;
+ m_pc = m_opcode & m_pc_mask;
+ }
+}
+
+void tms1400_cpu_device::op_call()
+{
+ // CALL/CALLL: conditional call
+ if (m_status)
+ {
+ // 3-level stack, mask clatch 3 bits (no need to mask others)
+ m_clatch = (m_clatch << 1 | 1) & 7;
+
+ m_sr = m_sr << m_pc_bits | m_pc;
+ m_pc = m_opcode & m_pc_mask;
+
+ m_ps = m_ps << 4 | m_pa;
+ m_pa = m_pb;
+
+ m_cs = m_cs << 2 | m_ca;
+ m_ca = m_cb;
+ }
+ else
+ {
+ m_pb = m_pa;
+ m_cb = m_ca;
+ }
+}
+
+void tms1400_cpu_device::op_retn()
+{
+ // RETN: return from subroutine
+ if (m_clatch & 1)
+ {
+ m_clatch >>= 1;
+
+ m_pc = m_sr & m_pc_mask;
+ m_sr >>= m_pc_bits;
+
+ m_pa = m_pb = m_ps & 0xf;
+ m_ps >>= 4;
+
+ m_ca = m_cb = m_cs & 3;
+ m_cs >>= 2;
+ }
+}
diff --git a/src/devices/cpu/tms1000/tms1400.h b/src/devices/cpu/tms1000/tms1400.h
new file mode 100644
index 00000000000..f4c2f177d16
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1400.h
@@ -0,0 +1,61 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TMS1400, TMS1470, TMS1600, TMS1670
+
+*/
+
+#ifndef _TMS1400_H_
+#define _TMS1400_H_
+
+#include "tms1100.h"
+
+
+class tms1400_cpu_device : public tms1100_cpu_device
+{
+public:
+ tms1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms1400_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+
+protected:
+ // overrides
+ virtual void device_reset() override;
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual void op_br() override;
+ virtual void op_call() override;
+ virtual void op_retn() override;
+
+ virtual void op_setr() override { tms1k_base_device::op_setr(); } // no anomaly with MSB of X register
+ virtual void op_rstr() override { tms1k_base_device::op_rstr(); } // "
+};
+
+class tms1470_cpu_device : public tms1400_cpu_device
+{
+public:
+ tms1470_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+class tms1600_cpu_device : public tms1400_cpu_device
+{
+public:
+ tms1600_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms1600_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+};
+
+class tms1670_cpu_device : public tms1600_cpu_device
+{
+public:
+ tms1670_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+extern const device_type TMS1400;
+extern const device_type TMS1470;
+extern const device_type TMS1600;
+extern const device_type TMS1670;
+
+
+#endif /* _TMS1400_H_ */
diff --git a/src/devices/cpu/tms1000/tms1k_base.cpp b/src/devices/cpu/tms1000/tms1k_base.cpp
index b09d8b11273..10e041b5104 100644
--- a/src/devices/cpu/tms1000/tms1k_base.cpp
+++ b/src/devices/cpu/tms1000/tms1k_base.cpp
@@ -2,10 +2,9 @@
// copyright-holders:Wilbert Pol, hap
/*
- TMS0980/TMS1000-family MCU cores
+ TMS1000 family - base/shared
TODO:
- - emulate TMS1600 L-pins
- fix debugger disasm view
@@ -69,378 +68,7 @@ unknown cycle: CME, SSE, SSS
#include "tms1k_base.h"
#include "debugger.h"
-// supported types:
-// note: dice information assumes the orientation is pictured with RAM at the bottom-left, except where noted
-
-// TMS1000
-// - 64x4bit RAM array at the bottom-left
-// - 1024x8bit ROM array at the bottom-right
-// * FYI, the row-selector to the left of it is laid out as:
-// 3,4,11,12,19,20,27,28,35,36,43,44,51,52,59,60,0,7,8,15,16,23,24,31,32,39,40,47,48,55,56,63,
-// 2,5,10,13,18,21,26,29,34,37,42,45,50,53,58,61,1,6,9,14,17,22,25,30,33,38,41,46,49,54,57,62
-// - 30-term microinstructions PLA(mpla) at the top half, to the right of the midline, supporting 16 microinstructions
-// - 20-term output PLA(opla) at the top-left
-// - the ALU is between the opla and mpla
-const device_type TMS1000 = &device_creator<tms1000_cpu_device>; // 28-pin DIP, 11 R pins
-const device_type TMS1070 = &device_creator<tms1070_cpu_device>; // high voltage version
-const device_type TMS1040 = &device_creator<tms1040_cpu_device>; // same as TMS1070 with just a different pinout?
-const device_type TMS1200 = &device_creator<tms1200_cpu_device>; // 40-pin DIP, 13 R pins
-// TMS1270 has 10 O pins, how does that work?
-
-// TMS1100 is nearly the same as TMS1000, some different opcodes, and with double the RAM and ROM
-const device_type TMS1100 = &device_creator<tms1100_cpu_device>; // 28-pin DIP, 11 R pins
-const device_type TMS1170 = &device_creator<tms1170_cpu_device>; // high voltage version
-const device_type TMS1300 = &device_creator<tms1300_cpu_device>; // 40-pin DIP, 16 R pins
-const device_type TMS1370 = &device_creator<tms1370_cpu_device>; // high voltage version
-
-// TMS1400 follows the TMS1100, it doubles the ROM size again (4 chapters of 16 pages), and adds a 3-level callstack
-// - rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100
-// - the opla size is increased from 20 to 32 terms
-const device_type TMS1400 = &device_creator<tms1400_cpu_device>; // 28-pin DIP, 11 R pins (TMS1400CR is same, but with TMS1100 pinout)
-const device_type TMS1470 = &device_creator<tms1470_cpu_device>; // high voltage version, 1 R pin removed for Vdd
-
-// TMS1600 adds more I/O to the TMS1400, input pins are doubled with added L1,2,4,8
-// - rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100
-// - the opla size is increased from 20 to 32 terms
-const device_type TMS1600 = &device_creator<tms1600_cpu_device>; // 40-pin DIP, 16 R pins
-const device_type TMS1670 = &device_creator<tms1670_cpu_device>; // high voltage version
-
-// TMS0980
-// - 64x9bit RAM array at the bottom-left (set up as 144x4)
-// - 2048x9bit ROM array at the bottom-left
-// - main instructions PLAs at the top half, to the right of the midline
-// * top section is assumed to be the CKI bus select
-// * middle section is for microinstruction redirection, this part may differ per die
-// * rest is fixed instructions select, from top-to-bottom: SEAC, LDX, COMX, COMX8,
-// TDO, SBIT, RETN, SETR, REAC, XDA, SAL, RBIT, ..., OFF, SBL, LDP, redir(------00- + R0^BL)
-// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions
-// - 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees)
-const device_type TMS0980 = &device_creator<tms0980_cpu_device>; // 28-pin DIP, 9 R pins
-
-// TMS1980 is a TMS0980 with a TMS1x00 style opla
-// - RAM, ROM, and main instructions PLAs is the same as TMS0980
-// - one of the microinstructions redirects to a RSTR instruction, like on TMS0270
-// - 32-term inverted output PLA above the RAM, 7 bits! (rotate opla 270 degrees)
-const device_type TMS1980 = &device_creator<tms1980_cpu_device>; // 28-pin DIP, 7 O pins, 10 R pins, high voltage
-
-// TMS0950 is a TMS1000 with a TMS0980 style opla, it was quickly succeeded by the TMS0970
-// - RAM, ROM, microinstructions is the same as TMS1000
-// - 10-term inverted output PLA and segment PLA on the top-left
-const device_type TMS0950 = &device_creator<tms0950_cpu_device>; // 28-pin DIP, 8 O pins, 11? R pins
-
-// TMS0970 is a stripped-down version of the TMS0980, itself acting more like a TMS1000
-// - RAM and ROM is the same as TMS1000
-// - main instructions PLAs at the top half, to the right of the midline
-// * see TMS0980 notes, except that the fixed instruction list differs:
-// RETN, SETR, RBIT, SBIT, LDX, COMX, TDO, ..., redir(----0-00), LDP
-// - 32-term microinstructions PLA between the RAM and ROM, supporting 15 microinstructions
-// - 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees)
-const device_type TMS0970 = &device_creator<tms0970_cpu_device>; // 28-pin DIP, 11 R pins (note: pinout may slightly differ from chip to chip)
-const device_type TMS1990 = &device_creator<tms1990_cpu_device>; // 28-pin DIP, ? R pins..
-
-// TMS0270 on the other hand, is a TMS0980 with earrings and a new hat. The new changes look like a quick afterthought, almost hacky
-// - RAM, ROM, and main instructions PLAs is the same as TMS0980
-// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions plus optional separate lines for custom opcode handling
-// - 48-term output PLA above the RAM (rotate opla 90 degrees)
-const device_type TMS0270 = &device_creator<tms0270_cpu_device>; // 40-pin DIP, 16 O pins, 8+ R pins (some R pins are internally hooked up to support more I/O)
-// newer TMS0270 chips (eg. Speak & Math) have 42 pins
-// TMS0260 is same or similar?
-
-// TP0320 is TI's first CMOS MCU with integrated LCD controller, the die is still very similar to TMS0980
-// - ROM and main RAM is same as on TMS0980 with different row-select
-// -
-const device_type TP0320 = &device_creator<tp0320_cpu_device>; // 28-pin SDIP, ..
-
-
-// internal memory maps
-static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device)
- AM_RANGE(0x000, 0xfff) AM_ROM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START(program_10bit_8, AS_PROGRAM, 8, tms1k_base_device)
- AM_RANGE(0x000, 0x3ff) AM_ROM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START(program_11bit_8, AS_PROGRAM, 8, tms1k_base_device)
- AM_RANGE(0x000, 0x7ff) AM_ROM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START(program_12bit_8, AS_PROGRAM, 8, tms1k_base_device)
- AM_RANGE(0x000, 0xfff) AM_ROM
-ADDRESS_MAP_END
-
-
-static ADDRESS_MAP_START(data_64x4, AS_DATA, 8, tms1k_base_device)
- AM_RANGE(0x00, 0x3f) AM_RAM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START(data_128x4, AS_DATA, 8, tms1k_base_device)
- AM_RANGE(0x00, 0x7f) AM_RAM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START(data_64x9_as4, AS_DATA, 8, tms1k_base_device)
- AM_RANGE(0x00, 0x7f) AM_RAM
- AM_RANGE(0x80, 0x8f) AM_RAM AM_MIRROR(0x70) // DAM
-ADDRESS_MAP_END
-
-
-// device definitions
-tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1k_base_device(mconfig, TMS1000, "TMS1000", tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 2 /* x width */, 10 /* prg width */, ADDRESS_MAP_NAME(program_10bit_8), 6 /* data width */, ADDRESS_MAP_NAME(data_64x4), "tms1000", __FILE__)
-{ }
-
-tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms1k_base_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms1070_cpu_device::tms1070_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1000_cpu_device(mconfig, TMS1070, "TMS1070", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1070", __FILE__)
-{ }
-
-tms1040_cpu_device::tms1040_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1000_cpu_device(mconfig, TMS1040, "TMS1040", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1040", __FILE__)
-{ }
-
-tms1200_cpu_device::tms1200_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1000_cpu_device(mconfig, TMS1200, "TMS1200", tag, owner, clock, 8, 13, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1200", __FILE__)
-{ }
-
-
-tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1000_cpu_device(mconfig, TMS1100, "TMS1100", tag, owner, clock, 8, 11, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1100", __FILE__)
-{ }
-
-tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms1000_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms1170_cpu_device::tms1170_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1100_cpu_device(mconfig, TMS1170, "TMS1170", tag, owner, clock, 8, 11, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1170", __FILE__)
-{ }
-
-tms1300_cpu_device::tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1100_cpu_device(mconfig, TMS1300, "TMS1300", tag, owner, clock, 8, 16, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1300", __FILE__)
-{ }
-
-tms1370_cpu_device::tms1370_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1100_cpu_device(mconfig, TMS1370, "TMS1370", tag, owner, clock, 8, 16, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1370", __FILE__)
-{ }
-
-
-tms1400_cpu_device::tms1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1100_cpu_device(mconfig, TMS1400, "TMS1400", tag, owner, clock, 8, 11, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1400", __FILE__)
-{ }
-
-tms1400_cpu_device::tms1400_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms1100_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms1470_cpu_device::tms1470_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1400_cpu_device(mconfig, TMS1470, "TMS1470", tag, owner, clock, 8, 10, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1470", __FILE__)
-{ }
-
-
-tms1600_cpu_device::tms1600_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1400_cpu_device(mconfig, TMS1600, "TMS1600", tag, owner, clock, 8, 16, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1600", __FILE__)
-{ }
-
-tms1600_cpu_device::tms1600_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms1400_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms1670_cpu_device::tms1670_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1600_cpu_device(mconfig, TMS1670, "TMS1670", tag, owner, clock, 8, 16, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1670", __FILE__)
-{ }
-
-
-tms0970_cpu_device::tms0970_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1000_cpu_device(mconfig, TMS0970, "TMS0970", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms0970", __FILE__)
-{ }
-
-tms0970_cpu_device::tms0970_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms1000_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms0950_cpu_device::tms0950_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0970_cpu_device(mconfig, TMS0950, "TMS0950", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms0950", __FILE__)
-{ }
-
-tms1990_cpu_device::tms1990_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0970_cpu_device(mconfig, TMS1990, "TMS1990", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1990", __FILE__)
-{ }
-
-
-tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0970_cpu_device(mconfig, TMS0980, "TMS0980", tag, owner, clock, 8, 9, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tms0980", __FILE__)
-{ }
-
-tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms0970_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms1980_cpu_device::tms1980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0980_cpu_device(mconfig, TMS1980, "TMS1980", tag, owner, clock, 7, 10, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tms1980", __FILE__)
-{ }
-
-
-tms0270_cpu_device::tms0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0980_cpu_device(mconfig, TMS0270, "TMS0270", tag, owner, clock, 16, 16, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tms0270", __FILE__)
- , m_read_ctl(*this)
- , m_write_ctl(*this)
- , m_write_pdc(*this)
-{ }
-
-
-tp0320_cpu_device::tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0980_cpu_device(mconfig, TP0320, "TP0320", tag, owner, clock, 7, 10, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tp0320", __FILE__)
-{ }
-
-
-// machine configs
-static MACHINE_CONFIG_FRAGMENT(tms1000)
-
- // microinstructions PLA, output PLA
- MCFG_PLA_ADD("mpla", 8, 16, 30)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 5, 8, 20)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms1000_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms1000);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms1400)
-
- // microinstructions PLA, output PLA
- MCFG_PLA_ADD("mpla", 8, 16, 30)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 5, 8, 32)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms1400_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms1400);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms0950)
-
- // microinstructions PLA, output PLA, segment PLA
- MCFG_PLA_ADD("mpla", 8, 16, 30)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 4, 8, 10)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("spla", 3, 8, 8)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms0950_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms0950);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms0970)
-
- // main opcodes PLA, microinstructions PLA, output PLA, segment PLA
- MCFG_PLA_ADD("ipla", 8, 15, 18)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("mpla", 5, 15, 32)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 4, 8, 16)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("spla", 3, 8, 8)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms0970_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms0970);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms0980)
-
- // main opcodes PLA, microinstructions PLA, output PLA, segment PLA
- MCFG_PLA_ADD("ipla", 9, 22, 24)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("mpla", 6, 20, 64)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 4, 8, 16)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("spla", 3, 8, 8)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms0980_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms0980);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms1980)
-
- // main opcodes PLA, microinstructions PLA, output PLA
- MCFG_PLA_ADD("ipla", 9, 22, 24)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("mpla", 6, 22, 64)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 5, 7, 32)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms1980_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms1980);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms0270)
-
- // main opcodes PLA, microinstructions PLA, output PLA
- MCFG_PLA_ADD("ipla", 9, 22, 24)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("mpla", 6, 22, 64)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 6, 16, 48)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms0270_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms0270);
-}
-
-
// disasm
-offs_t tms1000_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
-{
- extern CPU_DISASSEMBLE(tms1000);
- return CPU_DISASSEMBLE_NAME(tms1000)(this, buffer, pc, oprom, opram, options);
-}
-
-offs_t tms1100_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
-{
- extern CPU_DISASSEMBLE(tms1100);
- return CPU_DISASSEMBLE_NAME(tms1100)(this, buffer, pc, oprom, opram, options);
-}
-
-offs_t tms0980_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
-{
- extern CPU_DISASSEMBLE(tms0980);
- return CPU_DISASSEMBLE_NAME(tms0980)(this, buffer, pc, oprom, opram, options);
-}
-
-offs_t tp0320_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
-{
- extern CPU_DISASSEMBLE(tp0320);
- return CPU_DISASSEMBLE_NAME(tp0320)(this, buffer, pc, oprom, opram, options);
-}
-
void tms1k_base_device::state_string_export(const device_state_entry &entry, std::string &str) const
{
switch (entry.index())
@@ -452,7 +80,6 @@ void tms1k_base_device::state_string_export(const device_state_entry &entry, std
}
-
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
@@ -571,38 +198,6 @@ void tms1k_base_device::device_start()
m_icountptr = &m_icount;
}
-void tms0270_cpu_device::device_start()
-{
- // common init
- tms1k_base_device::device_start();
-
- m_read_ctl.resolve_safe(0);
- m_write_ctl.resolve_safe();
- m_write_pdc.resolve_safe();
-
- // zerofill
- m_r_prev = 0;
- m_chipsel = 0;
- m_ctl_dir = 0;
- m_ctl_out = 0;
- m_pdc = -1; // !
-
- m_o_latch_low = 0;
- m_o_latch = 0;
- m_o_latch_prev = 0;
-
- // register for savestates
- save_item(NAME(m_r_prev));
- save_item(NAME(m_chipsel));
- save_item(NAME(m_ctl_dir));
- save_item(NAME(m_ctl_out));
- save_item(NAME(m_pdc));
-
- save_item(NAME(m_o_latch_low));
- save_item(NAME(m_o_latch));
- save_item(NAME(m_o_latch_prev));
-}
-
//-------------------------------------------------
@@ -637,184 +232,6 @@ void tms1k_base_device::device_reset()
}
-void tms1000_cpu_device::device_reset()
-{
- // common reset
- tms1k_base_device::device_reset();
-
- // pre-decode instructionset
- m_fixed_decode.resize(0x100);
- memset(&m_fixed_decode[0], 0, 0x100*sizeof(UINT32));
- m_micro_decode.resize(0x100);
- memset(&m_micro_decode[0], 0, 0x100*sizeof(UINT32));
-
- for (int op = 0; op < 0x100; op++)
- {
- // _____ _____ ______ _____ ______ _____ _____ _____ _____
- const UINT32 md[16] = { M_STSL, M_AUTY, M_AUTA, M_CIN, M_C8, M_NE, M_CKN, M_15TN, M_MTN, M_NATN, M_ATN, M_MTP, M_YTP, M_CKP, M_CKM, M_STO };
- UINT16 mask = m_mpla->read(op);
- mask ^= 0x3fc8; // invert active-negative
-
- for (int bit = 0; bit < 16; bit++)
- if (mask & (1 << bit))
- m_micro_decode[op] |= md[bit];
- }
-
- // the fixed instruction set is not programmable
- m_fixed_decode[0x00] = F_COMX;
- m_fixed_decode[0x0a] = F_TDO;
- m_fixed_decode[0x0b] = F_CLO;
- m_fixed_decode[0x0c] = F_RSTR;
- m_fixed_decode[0x0d] = F_SETR;
- m_fixed_decode[0x0f] = F_RETN;
-
- for (int i = 0x10; i < 0x20; i++) m_fixed_decode[i] = F_LDP;
- for (int i = 0x30; i < 0x34; i++) m_fixed_decode[i] = F_SBIT;
- for (int i = 0x34; i < 0x38; i++) m_fixed_decode[i] = F_RBIT;
- for (int i = 0x3c; i < 0x40; i++) m_fixed_decode[i] = F_LDX;
-
- for (int i = 0x80; i < 0xc0; i++) m_fixed_decode[i] = F_BR;
- for (int i = 0xc0; i < 0x100; i++) m_fixed_decode[i] = F_CALL;
-}
-
-void tms1100_cpu_device::device_reset()
-{
- tms1000_cpu_device::device_reset();
-
- // small differences in 00-3f area
- m_fixed_decode[0x00] = 0;
- m_fixed_decode[0x09] = F_COMX8; // !
- m_fixed_decode[0x0b] = F_COMC;
-
- for (int i = 0x28; i < 0x30; i++) m_fixed_decode[i] = F_LDX;
- for (int i = 0x3c; i < 0x40; i++) m_fixed_decode[i] = 0;
-}
-
-void tms1400_cpu_device::device_reset()
-{
- tms1100_cpu_device::device_reset();
-
- // small differences in 00-3f area
- m_fixed_decode[0x0b] = F_TPC;
-}
-
-
-void tms0970_cpu_device::device_reset()
-{
- // common reset
- tms1k_base_device::device_reset();
-
- // pre-decode instructionset
- m_fixed_decode.resize(0x100);
- memset(&m_fixed_decode[0], 0, 0x100*sizeof(UINT32));
- m_micro_decode.resize(0x100);
- memset(&m_micro_decode[0], 0, 0x100*sizeof(UINT32));
-
- for (int op = 0; op < 0x100; op++)
- {
- // upper half of the opcodes is always branch/call
- if (op & 0x80)
- m_fixed_decode[op] = (op & 0x40) ? F_CALL: F_BR;
-
- // 5 output bits select a microinstruction index
- UINT32 imask = m_ipla->read(op);
- UINT8 msel = imask & 0x1f;
-
- // but if (from bottom to top) term 1 is active and output bit 5 is 0, R2,R4-R7 directly select a microinstruction index
- if (imask & 0x40 && (imask & 0x20) == 0)
- msel = (op & 0xf) | (op >> 1 & 0x10);
-
- msel = BITSWAP8(msel,7,6,5,0,1,2,3,4); // lines are reversed
- UINT32 mmask = m_mpla->read(msel);
- mmask ^= 0x09fe; // invert active-negative
-
- // _____ _____ _____ _____ ______ _____ ______ _____ _____
- const UINT32 md[15] = { M_CKM, M_CKP, M_YTP, M_MTP, M_ATN, M_NATN, M_MTN, M_15TN, M_CKN, M_NE, M_C8, M_CIN, M_AUTA, M_AUTY, M_STO };
-
- for (int bit = 0; bit < 15; bit++)
- if (mmask & (1 << bit))
- m_micro_decode[op] |= md[bit];
-
- // the other ipla terms each select a fixed instruction
- const UINT32 id[8] = { F_LDP, F_TDO, F_COMX, F_LDX, F_SBIT, F_RBIT, F_SETR, F_RETN };
-
- for (int bit = 0; bit < 8; bit++)
- if (imask & (0x80 << bit))
- m_fixed_decode[op] |= id[bit];
- }
-}
-
-
-UINT32 tms0980_cpu_device::decode_micro(UINT8 sel)
-{
- UINT32 decode = 0;
-
- sel = BITSWAP8(sel,7,6,0,1,2,3,4,5); // lines are reversed
- UINT32 mask = m_mpla->read(sel);
- mask ^= 0x43fc3; // invert active-negative
-
- // M_RSTR is specific to TMS02x0/TMS1980, it redirects to F_RSTR
- // M_UNK1 is specific to TMS0270, unknown/unused yet and apparently not connected on every TMS0270
- // _______ ______ _____ _____ _____ _____ ______ _____ ______ _____ _____
- const UINT32 md[22] = { M_NDMTP, M_DMTP, M_AUTY, M_AUTA, M_CKM, M_SSE, M_CKP, M_YTP, M_MTP, M_ATN, M_NATN, M_MTN, M_15TN, M_CKN, M_NE, M_C8, M_SSS, M_CME, M_CIN, M_STO, M_RSTR, M_UNK1 };
-
- for (int bit = 0; bit < 22 && bit < m_mpla->outputs(); bit++)
- if (mask & (1 << bit))
- decode |= md[bit];
-
- return decode;
-}
-
-void tms0980_cpu_device::device_reset()
-{
- // common reset
- tms1k_base_device::device_reset();
-
- // pre-decode instructionset
- m_fixed_decode.resize(0x200);
- memset(&m_fixed_decode[0], 0, 0x200*sizeof(UINT32));
- m_micro_decode.resize(0x200);
- memset(&m_micro_decode[0], 0, 0x200*sizeof(UINT32));
-
- for (int op = 0; op < 0x200; op++)
- {
- // upper half of the opcodes is always branch/call
- if (op & 0x100)
- m_fixed_decode[op] = (op & 0x80) ? F_CALL: F_BR;
-
- UINT32 imask = m_ipla->read(op);
-
- // 6 output bits select a microinstruction index
- m_micro_decode[op] = decode_micro(imask & 0x3f);
-
- // the other ipla terms each select a fixed instruction
- const UINT32 id[15] = { F_LDP, F_SBL, F_OFF, F_RBIT, F_SAL, F_XDA, F_REAC, F_SETR, F_RETN, F_SBIT, F_TDO, F_COMX8, F_COMX, F_LDX, F_SEAC };
-
- for (int bit = 0; bit < 15; bit++)
- if (imask & (0x80 << bit))
- m_fixed_decode[op] |= id[bit];
- }
-
- // like on TMS0970, one of the terms directly select a microinstruction index (via R4-R8),
- // but it can't be pre-determined when it's active
- m_micro_direct.resize(0x40);
- memset(&m_micro_decode[0], 0, 0x40*sizeof(UINT32));
-
- for (int op = 0; op < 0x40; op++)
- m_micro_direct[op] = decode_micro(op);
-}
-
-void tms0270_cpu_device::device_reset()
-{
- // common reset
- tms0980_cpu_device::device_reset();
-
- m_o_latch_low = 0;
- m_o_latch = 0;
- m_o_latch_prev = 0;
-}
-
-
//-------------------------------------------------
// program counter/opcode decode
@@ -847,28 +264,6 @@ void tms1k_base_device::read_opcode()
next_pc();
}
-void tms0980_cpu_device::read_opcode()
-{
- debugger_instruction_hook(this, m_rom_address << 1);
- m_opcode = m_program->read_word(m_rom_address << 1) & 0x1ff;
- m_c4 = BITSWAP8(m_opcode,7,6,5,4,0,1,2,3) & 0xf; // opcode operand is bitswapped for most opcodes
-
- m_fixed = m_fixed_decode[m_opcode];
-
- // if ipla term 0 is active, R4-R8 directly select a microinstruction index when R0 or R0^BL is 0
- int r0 = m_opcode >> 8 & 1;
- if (m_ipla->read(m_opcode) & 0x40 && !((r0 & m_bl) ^ r0))
- m_micro = m_micro_direct[m_opcode & 0x3f];
- else
- m_micro = m_micro_decode[m_opcode];
-
- // redirect mpla fixed instructions
- if (m_micro & M_RSTR) m_fixed |= F_RSTR;
- if (m_micro & M_SETR) m_fixed |= F_SETR;
-
- next_pc();
-}
-
//-------------------------------------------------
@@ -882,81 +277,12 @@ void tms1k_base_device::write_o_output(UINT8 index)
m_write_o(0, m_o & m_o_mask, 0xffff);
}
-void tms0970_cpu_device::write_o_output(UINT8 index)
-{
- m_o = m_spla->read(index);
- m_write_o(0, m_o & m_o_mask, 0xffff);
-}
-
-
-void tms0270_cpu_device::dynamic_output()
-{
- // R11: TMS5100 CTL port direction (0=read from TMS5100, 1=write to TMS5100)
- m_ctl_dir = m_r >> 11 & 1;
-
- // R12: chip select (off=display via OPLA, on=TMS5100 via ACC/CKB)
- m_chipsel = m_r >> 12 & 1;
-
- if (m_chipsel)
- {
- // ACC via SEG G,B,C,D: TMS5100 CTL pins
- if (m_ctl_dir && m_a != m_ctl_out)
- {
- m_ctl_out = m_a;
- m_write_ctl(0, m_ctl_out, 0xff);
- }
-
- // R10 via SEG E: TMS5100 PDC pin
- if (m_pdc != (m_r >> 10 & 1))
- {
- m_pdc = m_r >> 10 & 1;
- m_write_pdc(m_pdc);
- }
- }
- else
- {
- // standard O-output
- if (m_o_latch != m_o_latch_prev)
- {
- write_o_output(m_o_latch);
- m_o_latch_prev = m_o_latch;
- }
- }
-
- // standard R-output
- if (m_r != m_r_prev)
- {
- m_write_r(0, m_r & m_r_mask, 0xffff);
- m_r_prev = m_r;
- }
-}
-
-
UINT8 tms1k_base_device::read_k_input()
{
// K1,2,4,8 (KC test pin is not emulated)
return m_read_k(0, 0xff) & 0xf;
}
-UINT8 tms0980_cpu_device::read_k_input()
-{
- UINT8 k = m_read_k(0, 0xff) & 0x1f;
- UINT8 k3 = (k & 0x10) ? 3: 0; // the TMS0980 K3 line is simply K1|K2
- return (k & 0xf) | k3;
-}
-
-UINT8 tms0270_cpu_device::read_k_input()
-{
- // external: TMS5100 CTL port via SEG G,B,C,D
- if (m_chipsel)
- return (m_ctl_dir) ? m_ctl_out : m_read_ctl(0, 0xff) & 0xf;
-
- // standard K-input otherwise
- UINT8 k = m_read_k(0, 0xff) & 0x1f;
- return (k & 0x10) ? 0xf : k; // the TMS0270 KF line asserts all K-inputs
-}
-
-
void tms1k_base_device::set_cki_bus()
{
switch (m_opcode & 0xf8)
@@ -983,32 +309,6 @@ void tms1k_base_device::set_cki_bus()
}
}
-void tms0980_cpu_device::set_cki_bus()
-{
- switch (m_opcode & 0x1f8)
- {
- // 000001XXX: K-inputs
- case 0x008:
- m_cki_bus = read_k_input();
- break;
-
- // 0X0100XXX: select bit
- case 0x020: case 0x0a0:
- m_cki_bus = 1 << (m_c4 >> 2) ^ 0xf;
- break;
-
- // 0X1XXXXXX: constant
- case 0x040: case 0x048: case 0x050: case 0x058: case 0x060: case 0x068: case 0x070: case 0x078:
- case 0x0c0: case 0x0c8: case 0x0d0: case 0x0d8: case 0x0e0: case 0x0e8: case 0x0f0: case 0x0f8:
- m_cki_bus = m_c4;
- break;
-
- default:
- m_cki_bus = 0;
- break;
- }
-}
-
//-------------------------------------------------
@@ -1068,62 +368,6 @@ void tms1k_base_device::op_retn()
}
-// TMS1400-specific
-
-void tms1400_cpu_device::op_br()
-{
- // BR/BL: conditional branch
- if (m_status)
- {
- m_pa = m_pb; // don't care about clatch
- m_ca = m_cb;
- m_pc = m_opcode & m_pc_mask;
- }
-}
-
-void tms1400_cpu_device::op_call()
-{
- // CALL/CALLL: conditional call
- if (m_status)
- {
- // 3-level stack, mask clatch 3 bits (no need to mask others)
- m_clatch = (m_clatch << 1 | 1) & 7;
-
- m_sr = m_sr << m_pc_bits | m_pc;
- m_pc = m_opcode & m_pc_mask;
-
- m_ps = m_ps << 4 | m_pa;
- m_pa = m_pb;
-
- m_cs = m_cs << 2 | m_ca;
- m_ca = m_cb;
- }
- else
- {
- m_pb = m_pa;
- m_cb = m_ca;
- }
-}
-
-void tms1400_cpu_device::op_retn()
-{
- // RETN: return from subroutine
- if (m_clatch & 1)
- {
- m_clatch >>= 1;
-
- m_pc = m_sr & m_pc_mask;
- m_sr >>= m_pc_bits;
-
- m_pa = m_pb = m_ps & 0xf;
- m_ps >>= 4;
-
- m_ca = m_cb = m_cs & 3;
- m_cs >>= 2;
- }
-}
-
-
// handle other:
// TMS1000/common
@@ -1198,20 +442,6 @@ void tms1k_base_device::op_ldp()
// TMS1100-specific
-void tms1100_cpu_device::op_setr()
-{
- // SETR: same, but X register MSB must be clear
- if (~m_x & (1 << (m_x_bits-1)))
- tms1k_base_device::op_setr();
-}
-
-void tms1100_cpu_device::op_rstr()
-{
- // RSTR: same, but X register MSB must be clear
- if (~m_x & (1 << (m_x_bits-1)))
- tms1k_base_device::op_rstr();
-}
-
void tms1k_base_device::op_comc()
{
// COMC: complement chapter buffer
@@ -1228,32 +458,8 @@ void tms1k_base_device::op_tpc()
}
-// TMS0970-specific (and possibly child classes)
-
-void tms0970_cpu_device::op_setr()
-{
- // SETR: set output register
- // DDIG line is a coincidence between the selected output pla row(s) and segment pla row(s)
- int ddig = (m_opla->read(m_a) & m_o) ? 1 : 0;
- m_r = (m_r & ~(1 << m_y)) | (ddig << m_y);
-}
-
-void tms0970_cpu_device::op_tdo()
-{
- // TDO: transfer digits to output
- write_o_output(m_a & 0x7);
- m_write_r(0, m_r & m_r_mask, 0xffff);
-}
-
-
// TMS0980-specific (and possibly child classes)
-void tms0980_cpu_device::op_comx()
-{
- // COMX: complement X register, but not the MSB
- m_x ^= (m_x_mask >> 1);
-}
-
void tms1k_base_device::op_xda()
{
// XDA: exchange DAM and A
@@ -1292,41 +498,6 @@ void tms1k_base_device::op_sbl()
}
-// TMS1980-specific
-
-void tms1980_cpu_device::op_tdo()
-{
- // TDO: transfer accumulator and status(not status_latch!) to O-output
- write_o_output(m_status << 4 | m_a);
-}
-
-
-// TMS0270-specific
-
-void tms0270_cpu_device::op_setr()
-{
- // same as default, but handle write to output in dynamic_output
- m_r = m_r | (1 << m_y);
-}
-
-void tms0270_cpu_device::op_rstr()
-{
- // same as default, but handle write to output in dynamic_output
- m_r = m_r & ~(1 << m_y);
-}
-
-void tms0270_cpu_device::op_tdo()
-{
- // TDO: transfer data out
- if (m_status)
- m_o_latch_low = m_a;
- else
- m_o_latch = m_o_latch_low | (m_a << 4 & 0x30);
-
- // write to output is done in dynamic_output
-}
-
-
//-------------------------------------------------
// execute_run
diff --git a/src/devices/cpu/tms1000/tms1k_base.h b/src/devices/cpu/tms1000/tms1k_base.h
index c1585bd22f0..9ad108b1dca 100644
--- a/src/devices/cpu/tms1000/tms1k_base.h
+++ b/src/devices/cpu/tms1000/tms1k_base.h
@@ -2,7 +2,10 @@
// copyright-holders:Wilbert Pol, hap
/*
- TMS0980/TMS1000-family MCU cores
+ TMS1000 family - base/shared
+
+ Don't include this file, include the specific device header instead,
+ for example tms1000.h
*/
@@ -35,17 +38,6 @@
tms1k_base_device::set_power_off_callback(*device, DEVCB_##_devcb);
-// TMS0270 was designed to interface with TMS5100, set it up at driver level
-#define MCFG_TMS0270_READ_CTL_CB(_devcb) \
- tms0270_cpu_device::set_read_ctl_callback(*device, DEVCB_##_devcb);
-
-#define MCFG_TMS0270_WRITE_CTL_CB(_devcb) \
- tms0270_cpu_device::set_write_ctl_callback(*device, DEVCB_##_devcb);
-
-#define MCFG_TMS0270_WRITE_PDC_CB(_devcb) \
- tms0270_cpu_device::set_write_pdc_callback(*device, DEVCB_##_devcb);
-
-
// pinout reference
/*
@@ -304,274 +296,4 @@ protected:
};
-
-class tms1000_cpu_device : public tms1k_base_device
-{
-public:
- tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms1000_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-
-protected:
- // overrides
- virtual void device_reset() override;
- virtual machine_config_constructor device_mconfig_additions() const override;
-
-
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
-};
-
-class tms1070_cpu_device : public tms1000_cpu_device
-{
-public:
- tms1070_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-class tms1040_cpu_device : public tms1000_cpu_device
-{
-public:
- tms1040_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms1200_cpu_device : public tms1000_cpu_device
-{
-public:
- tms1200_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms1100_cpu_device : public tms1000_cpu_device
-{
-public:
- tms1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms1100_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-
-protected:
- // overrides
- virtual void device_reset() override;
-
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
-
- virtual void op_setr() override;
- virtual void op_rstr() override;
-};
-
-class tms1170_cpu_device : public tms1100_cpu_device
-{
-public:
- tms1170_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-class tms1300_cpu_device : public tms1100_cpu_device
-{
-public:
- tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-class tms1370_cpu_device : public tms1100_cpu_device
-{
-public:
- tms1370_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms1400_cpu_device : public tms1100_cpu_device
-{
-public:
- tms1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms1400_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-
-protected:
- // overrides
- virtual void device_reset() override;
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual void op_br() override;
- virtual void op_call() override;
- virtual void op_retn() override;
-
- virtual void op_setr() override { tms1k_base_device::op_setr(); } // no anomaly with MSB of X register
- virtual void op_rstr() override { tms1k_base_device::op_rstr(); } // "
-};
-
-class tms1470_cpu_device : public tms1400_cpu_device
-{
-public:
- tms1470_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms1600_cpu_device : public tms1400_cpu_device
-{
-public:
- tms1600_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms1600_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-};
-
-class tms1670_cpu_device : public tms1600_cpu_device
-{
-public:
- tms1670_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms0970_cpu_device : public tms1000_cpu_device
-{
-public:
- tms0970_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms0970_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-
-protected:
- // overrides
- virtual void device_reset() override;
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual void write_o_output(UINT8 index) override;
-
- virtual void op_setr() override;
- virtual void op_tdo() override;
-};
-
-class tms0950_cpu_device : public tms0970_cpu_device
-{
-public:
- tms0950_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-
-protected:
- // overrides
- virtual void device_reset() override { tms1000_cpu_device::device_reset(); }
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual void op_rstr() override { ; } // assume it has no RSTR or CLO
- virtual void op_clo() override { ; } // "
-};
-
-class tms1990_cpu_device : public tms0970_cpu_device
-{
-public:
- tms1990_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms0980_cpu_device : public tms0970_cpu_device
-{
-public:
- tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-
-protected:
- // overrides
- virtual void device_reset() override;
-
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual UINT32 disasm_min_opcode_bytes() const override { return 2; }
- virtual UINT32 disasm_max_opcode_bytes() const override { return 2; }
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
-
- virtual UINT8 read_k_input() override;
- virtual void set_cki_bus() override;
- virtual void read_opcode() override;
-
- virtual void op_comx() override;
-
- UINT32 decode_micro(UINT8 sel);
-};
-
-class tms1980_cpu_device : public tms0980_cpu_device
-{
-public:
- tms1980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-
-protected:
- // overrides
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual void write_o_output(UINT8 index) override { tms1k_base_device::write_o_output(index); }
- virtual UINT8 read_k_input() override { return tms1k_base_device::read_k_input(); }
-
- virtual void op_setr() override { tms1k_base_device::op_setr(); }
- virtual void op_tdo() override;
-};
-
-
-class tms0270_cpu_device : public tms0980_cpu_device
-{
-public:
- tms0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-
- // static configuration helpers
- template<class _Object> static devcb_base &set_read_ctl_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_read_ctl.set_callback(object); }
- template<class _Object> static devcb_base &set_write_ctl_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_write_ctl.set_callback(object); }
- template<class _Object> static devcb_base &set_write_pdc_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_write_pdc.set_callback(object); }
-
-protected:
- // overrides
- virtual void device_start() override;
- virtual void device_reset() override;
-
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual void write_o_output(UINT8 index) override { tms1k_base_device::write_o_output(index); }
- virtual UINT8 read_k_input() override;
- virtual void dynamic_output() override;
-
- virtual void op_setr() override;
- virtual void op_rstr() override;
- virtual void op_tdo() override;
-
-private:
- // state specific to interface with TMS5100
- UINT16 m_r_prev;
- UINT8 m_chipsel;
- UINT8 m_ctl_out;
- UINT8 m_ctl_dir;
- int m_pdc;
-
- UINT8 m_o_latch_low;
- UINT8 m_o_latch;
- UINT8 m_o_latch_prev;
-
- devcb_read8 m_read_ctl;
- devcb_write8 m_write_ctl;
- devcb_write_line m_write_pdc;
-};
-
-
-class tp0320_cpu_device : public tms0980_cpu_device
-{
-public:
- tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-
-protected:
- // overrides
- //virtual void device_start() override;
- //virtual void device_reset() override;
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
-
- //virtual machine_config_constructor device_mconfig_additions() const override;
-};
-
-
-extern const device_type TMS1000;
-extern const device_type TMS1070;
-extern const device_type TMS1040;
-extern const device_type TMS1200;
-extern const device_type TMS1100;
-extern const device_type TMS1170;
-extern const device_type TMS1300;
-extern const device_type TMS1370;
-extern const device_type TMS1400;
-extern const device_type TMS1470;
-extern const device_type TMS1600;
-extern const device_type TMS1670;
-extern const device_type TMS0950;
-extern const device_type TMS0970;
-extern const device_type TMS1990;
-extern const device_type TMS0980;
-extern const device_type TMS1980;
-extern const device_type TMS0270;
-extern const device_type TP0320;
-
-
#endif /* _TMS1KBASE_H_ */
diff --git a/src/devices/cpu/tms1000/tp0320.cpp b/src/devices/cpu/tms1000/tp0320.cpp
new file mode 100644
index 00000000000..71a5eda71f1
--- /dev/null
+++ b/src/devices/cpu/tms1000/tp0320.cpp
@@ -0,0 +1,40 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TP0320
+
+*/
+
+#include "tp0320.h"
+#include "debugger.h"
+
+// TP0320 is TI's first CMOS MCU with integrated LCD controller, the die is still very similar to TMS0980
+// - ROM and main RAM is same as on TMS0980 with different row-select
+// -
+const device_type TP0320 = &device_creator<tp0320_cpu_device>; // 28-pin SDIP, ..
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device)
+ AM_RANGE(0x000, 0xfff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_64x9_as4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ AM_RANGE(0x80, 0x8f) AM_RAM AM_MIRROR(0x70) // DAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tp0320_cpu_device::tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0980_cpu_device(mconfig, TP0320, "TP0320", tag, owner, clock, 7 /* o pins */, 10 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_64x9_as4), "tp0320", __FILE__)
+{ }
+
+
+// disasm
+offs_t tp0320_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE(tp0320);
+ return CPU_DISASSEMBLE_NAME(tp0320)(this, buffer, pc, oprom, opram, options);
+}
diff --git a/src/devices/cpu/tms1000/tp0320.h b/src/devices/cpu/tms1000/tp0320.h
new file mode 100644
index 00000000000..32e18e5159f
--- /dev/null
+++ b/src/devices/cpu/tms1000/tp0320.h
@@ -0,0 +1,32 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - TP0320
+
+*/
+
+#ifndef _TP0320_H_
+#define _TP0320_H_
+
+#include "tms0980.h"
+
+
+class tp0320_cpu_device : public tms0980_cpu_device
+{
+public:
+ tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // overrides
+ //virtual void device_start() override;
+ //virtual void device_reset() override;
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
+
+ //virtual machine_config_constructor device_mconfig_additions() const override;
+};
+
+
+extern const device_type TP0320;
+
+#endif /* _TP0320_H_ */
diff --git a/src/mame/drivers/microvsn.cpp b/src/mame/drivers/microvsn.cpp
index e936ac16deb..33f0795ff1a 100644
--- a/src/mame/drivers/microvsn.cpp
+++ b/src/mame/drivers/microvsn.cpp
@@ -17,7 +17,7 @@ of the games were clocked at around 500KHz, 550KHz, or 300KHz.
#include "emu.h"
#include "cpu/mcs48/mcs48.h"
-#include "cpu/tms1000/tms1000.h"
+#include "cpu/tms1000/tms1100.h"
#include "sound/dac.h"
#include "rendlay.h"
@@ -547,7 +547,7 @@ DEVICE_IMAGE_LOAD_MEMBER(microvision_state, microvsn_cart)
if (pla)
m_pla = 1;
- tms1k_base_device::set_output_pla(m_tms1100, m_pla ? microvision_output_pla_1 : microvision_output_pla_0);
+ tms1100_cpu_device::set_output_pla(m_tms1100, m_pla ? microvision_output_pla_1 : microvision_output_pla_0);
// Set default setting for PCB type and RC type
m_pcb_type = microvision_state::PCB_TYPE_UNKNOWN;
diff --git a/src/mame/includes/hh_tms1k.h b/src/mame/includes/hh_tms1k.h
index aa1c2da67aa..46372415b47 100644
--- a/src/mame/includes/hh_tms1k.h
+++ b/src/mame/includes/hh_tms1k.h
@@ -9,9 +9,14 @@
#ifndef _HH_TMS1K_H_
#define _HH_TMS1K_H_
-
#include "emu.h"
#include "cpu/tms1000/tms1000.h"
+#include "cpu/tms1000/tms1100.h"
+#include "cpu/tms1000/tms1400.h"
+#include "cpu/tms1000/tms0970.h"
+#include "cpu/tms1000/tms0980.h"
+#include "cpu/tms1000/tms0270.h"
+#include "cpu/tms1000/tp0320.h"
#include "sound/speaker.h"