summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2014-12-01 21:45:19 +0100
committer hap <happppp@users.noreply.github.com>2014-12-01 21:45:19 +0100
commitc1eaec3cee27803f88d4520b9284f29391612394 (patch)
tree48a90908b6d5b333b536fb4efdb760fe8bacb3a1
parent90547df63b1d0a535d7e84c529c8fea2f715185d (diff)
(MESS) Rewrote TMS1xxx MCU core and added support for a couple of classic Texas Instruments handheld calculators. [hap, seanriddle]
-rw-r--r--src/emu/cpu/tms0980/tms0980.c1759
-rw-r--r--src/emu/cpu/tms0980/tms0980.h296
-rw-r--r--src/mess/drivers/comp4.c139
-rw-r--r--src/mess/drivers/merlin.c94
-rw-r--r--src/mess/drivers/microvsn.c8
-rw-r--r--src/mess/drivers/simon.c42
-rw-r--r--src/mess/drivers/stopthie.c21
-rw-r--r--src/mess/drivers/ticalc1x.c742
-rw-r--r--src/mess/layout/comp4.lay45
-rw-r--r--src/mess/layout/merlin.lay30
-rw-r--r--src/mess/layout/ti1270.lay39
-rw-r--r--src/mess/layout/ti30.lay42
-rw-r--r--src/mess/layout/tisr16.lay51
-rw-r--r--src/mess/layout/wizatron.lay68
-rw-r--r--src/mess/mess.lst17
-rw-r--r--src/mess/mess.mak5
16 files changed, 2185 insertions, 1213 deletions
diff --git a/src/emu/cpu/tms0980/tms0980.c b/src/emu/cpu/tms0980/tms0980.c
index d5bdd0801b4..c50ee63c765 100644
--- a/src/emu/cpu/tms0980/tms0980.c
+++ b/src/emu/cpu/tms0980/tms0980.c
@@ -1,47 +1,13 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
/*
+ TMS0980/TMS1000-family MCU cores
-TMS0980/TMS1000-family CPU cores
-
-The tms0980 and tms1000-family cpu cores are very similar. The tms0980 has a
-slightly bigger addressable area and uses 9bit instructions where the tms1000
+The TMS0980 and TMS1000-family MCU cores are very similar. The TMS0980 has a
+slightly bigger addressable area and uses 9bit instructions where the TMS1000
family uses 8bit instruction. The instruction set themselves are very similar
-though. The table below shows the differences between the different models.
-
-Mode | ROM | RAM | R pins | O pins | K pins | ids
----------+-----------+----------+--------+--------+--------|----------
-tms0970 | 1024 * 8 | 64 * 4 | | | | tms0972
-tms0920* | 511?* 9 | 40 * 5 | | | | tmc0921
-tms0980 | 2048 * 9 | 64 * 9 | | | | tmc0981
-tms1000 | 1024 * 8 | 64 * 4 | 11 | 8 | 4 | tms1001
-tms1040* | 1024 * 8 | 64 * 4 | | | | tms1043
-tms1070 | 1024 * 8 | 64 * 4 | 11 | 8 | 4 | tms1071
-tms1100 | 2048 * 8 | 128 * 4 | 11 | 8 | 4 | tms1111/tms1115
-tms1170* | 2048 * 8 | 128 * 4 | | | | tmc1172
-tms1200 | 1024 * 8 | 64 * 4 | 13 | 8 | 4 | tms1215
-tms1270 | 1024 * 8 | 64 * 4 | 13 | 10 | 4 | tms1278
-tms1300 | 2048 * 8 | 128 * 4 | 16 | 8 | 4 | tms1309
-tms1370* | 2048 * 8 | 128 * 4 | | | | za0543
-tms1400* | 4096 * 8 | 128 * 4 | | | |
-tms1470* | 4096 * 8 | 128 * 4 | | | | tms1470
-tms1500* | 2048 * 13 | 64 * 20 | | | | tmc1501
-tms1600* | 4096 * 8 | 128 * 4 | | | |
-tms1670* | 4096 * 8 | 128 * 4 | | | |
-tms1700* | 512 * 8 | 32 * 4 | | | |
-tms1980* | 2048 * 9 | 64 * 9 | | | | tmc1982
-tms1990* | 1024 * 8 | 64 * 4 | | | | tmc1991
-tp0310* | 511?* 9 | 40 * 5 | | | | tp0311
-tp0320* | 2048 * 9 | 64 * 13 | | | | tp0321
-tp0455* | | | | | | cd4501
-tp0456* | | | | | | cd4555
-tp0458* | | | | | | cd4812
-tp0485* | | | | | | cd2901
-tp0530* | | | | | | cd5402
-
-* = not supported yet
-
-The TMS1000 core has been tested with some example code, the other models
-have not been tested lacking rom dumps.
+though.
Each instruction takes 12 cycles to execute in 2 phases: a fetch phase and an
execution phase. The execution phase takes place at the same time as the fetch
@@ -83,64 +49,247 @@ cycle #5
1. Execute BRANCH/CALL/RETN part #1
-The CPU cores contains a set of fixed instructions and a set of
+The MCU cores contains a set of fixed instructions and a set of
instructions created using microinstructions. A subset of the
instruction set could be defined from the microinstructions by
-TI customers. Currently we only support the standard instruction
-set as defined by TI.
-
-The microinstructions are:
-15TN - 15 to -ALU
-ATN - ACC to -ALU
-AUTA - ALU to ACC
-AUTY - ALU to Y
-C8 - CARRY8 to STATUS
-CIN - Carry In to ALU
-CKM - CKB to MEM
-CKN - CKB to -ALU
-CKP - CKB to +ALU
-CME - Conditional Memory Enable
-DMTP - DAM to +ALU
-MTN - MEM to -ALU
-MTP - MEM to +ALU
-NATN - ~ACC to -ALU
-NDMTP - ~DAM to +ALU
-NE - COMP to STATUS
-SSE - Special Status Enable
-SSS - Special Status Sample
-STO - ACC to MEM
-YTP - Y to +ALU
+TI customers.
cycle #0: 15TN, ATN, CIN, CKN, CKP, DMTP, MTN, MTP, NATN, NDMTP, YTP
cycle #2: C8(?), CKM, NE(?), STO
cycle #3,#4: AUTA, AUTY
-unknown cycle: CME, SSE, SSS
-
*/
-#include "emu.h"
-#include "debugger.h"
#include "tms0980.h"
+#include "debugger.h"
+
+// supported types:
+// note: dice information assumes the orientation is pictured with RAM at the bottom-left
+
+// 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 TMS1200 = &device_creator<tms1200_cpu_device>; // 40-pin DIP, 13 R pins
+const device_type TMS1070 = &device_creator<tms1070_cpu_device>; // same as tms1000, just supports higher voltage
+
+// 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 TMS1300 = &device_creator<tms1300_cpu_device>; // 40-pin DIP, 16 R pins
+
+// TMS0980
+// - 64x9bit RAM array at the bottom-left (set up as 144x4)
+// - 2048x9bit ROM array at the bottom-left
+// - main instructions PLA at the top half, to the right of the midline
+// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions
+// - 16-term output PLA and segment PLA above the RAM
+const device_type TMS0980 = &device_creator<tms0980_cpu_device>; // 28-pin DIP, 9 R pins
+
+
+// TMS0970 is a stripped-down version of the TMS0980, itself acting more like a TMS1000
+// - 64x4bit RAM array at the bottom-left
+// - 1024x8bit ROM array at the bottom-right
+// - main instructions PLA at the top half, to the right of the midline
+// - 32-term microinstructions PLA between the RAM and ROM, supporting 15 microinstructions
+// - 16-term output PLA and segment PLA above the RAM
+const device_type TMS0970 = &device_creator<tms0970_cpu_device>; // 28-pin DIP, 11 R pins
+
+
+
+static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1xxx_cpu_device)
+ AM_RANGE(0x000, 0xfff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(program_10bit_8, AS_PROGRAM, 8, tms1xxx_cpu_device)
+ AM_RANGE(0x000, 0x3ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(program_11bit_8, AS_PROGRAM, 8, tms1xxx_cpu_device)
+ AM_RANGE(0x000, 0x7ff) AM_ROM
+ADDRESS_MAP_END
+
+
+static ADDRESS_MAP_START(data_64x4, AS_DATA, 8, tms1xxx_cpu_device)
+ AM_RANGE(0x00, 0x3f) AM_RAM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_128x4, AS_DATA, 8, tms1xxx_cpu_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_64x9_as4, AS_DATA, 8, tms1xxx_cpu_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ AM_RANGE(0x80, 0x8f) AM_RAM AM_MIRROR(0x70) // DAM
+ADDRESS_MAP_END
+
+
+tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1xxx_cpu_device(mconfig, TMS1000, "TMS1000", tag, owner, clock, 8, 11, 4, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, 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 k_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)
+ : tms1xxx_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, k_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, 4, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1070", __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, 4, 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, 4, 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 k_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, k_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{
+}
+
+tms1300_cpu_device::tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1100_cpu_device(mconfig, TMS1300, "TMS1200", tag, owner, clock, 8, 16, 4, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1300", __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, 4, 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 k_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, k_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{
+}
+
+
+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, 5, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tms0980", __FILE__)
+{
+}
+
+
+
+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(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);
+}
+
+
+
+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);
+}
-const device_type TMS0980 = &device_creator<tms0980_cpu_device>;
-const device_type TMS1000 = &device_creator<tms1000_cpu_device>;
-const device_type TMS0970 = &device_creator<tms0970_cpu_device>;
-const device_type TMS1070 = &device_creator<tms1070_cpu_device>;
-const device_type TMS1200 = &device_creator<tms1200_cpu_device>;
-const device_type TMS1270 = &device_creator<tms1270_cpu_device>;
-const device_type TMS1100 = &device_creator<tms1100_cpu_device>;
-const device_type TMS1300 = &device_creator<tms1300_cpu_device>;
+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);
+}
-#define MICRO_MASK 0x80000000
-#define FIXED_INSTRUCTION 0x00000000
+void tms1000_cpu_device::state_string_export(const device_state_entry &entry, astring &string)
+{
+ switch (entry.index())
+ {
+ case STATE_GENPC:
+ string.printf("%03X", (m_pa << 6) | m_pc);
+ break;
+ }
+}
+void tms1100_cpu_device::state_string_export(const device_state_entry &entry, astring &string)
+{
+ switch (entry.index())
+ {
+ case STATE_GENPC:
+ string.printf("%03X", (m_ca << 10) | (m_pa << 6) | m_pc);
+ break;
+ }
+}
-/* Standard/fixed intructions */
-#define F_ILL 0x00000000
+void tms0980_cpu_device::state_string_export(const device_state_entry &entry, astring &string)
+{
+ switch (entry.index())
+ {
+ case STATE_GENPC:
+ string.printf("%03X", ((m_pa << 7) | m_pc) << 1);
+ break;
+ }
+}
+
+
+
+/* Standard/fixed instructions */
#define F_BR 0x00000001
#define F_CALL 0x00000002
#define F_CLO 0x00000004
@@ -160,7 +309,7 @@ const device_type TMS1300 = &device_creator<tms1300_cpu_device>;
#define F_SEAC 0x00010000
#define F_SETR 0x00020000
#define F_TDO 0x00040000
-
+#define F_XDA 0x00080000
/* Microinstructions */
#define M_15TN 0x00000001
@@ -186,308 +335,116 @@ const device_type TMS1300 = &device_creator<tms1300_cpu_device>;
#define M_YTP 0x00100000
-/* instructions built from microinstructions */
-#define I_AC1AC ( MICRO_MASK | M_CKP | M_ATN | M_CIN | M_C8 | M_AUTA )
-#define I_A6AAC I_ACACC
-#define I_A8AAC I_ACACC
-#define I_A10AAC I_ACACC
-#define I_ACACC ( MICRO_MASK | M_CKP | M_ATN | M_C8 | M_AUTA )
-#define I_ACNAA ( MICRO_MASK | M_CKP | M_NATN | M_AUTA )
-#define I_ALEC ( MICRO_MASK | M_CKP | M_NATN | M_CIN | M_C8 )
-#define I_ALEM ( MICRO_MASK | M_MTP | M_NATN | M_CIN | M_C8 )
-#define I_AMAAC ( MICRO_MASK | M_MTP | M_ATN | M_C8 | M_AUTA )
-#define I_CCLA ( MICRO_MASK | M_AUTA | M_SSS )
-#define I_CLA ( MICRO_MASK | M_AUTA )
-#define I_CPAIZ ( MICRO_MASK | M_NATN | M_CIN | M_C8 | M_AUTA )
-#define I_CTMDYN ( MICRO_MASK | M_YTP | M_15TN | M_C8 | M_AUTY | M_CME )
-#define I_DAN ( MICRO_MASK | M_CKP | M_ATN | M_CIN | M_C8 | M_AUTA )
-#define I_DMAN ( MICRO_MASK | M_MTP | M_15TN | M_C8 | M_AUTA )
-#define I_DMEA ( MICRO_MASK | M_MTP | M_DMTP | M_SSS | M_AUTA )
-#define I_NDMEA ( MICRO_MASK | M_MTN | M_NDMTP | M_SSS | M_AUTA )
-#define I_DNAA ( MICRO_MASK | M_DMTP | M_NATN | M_SSS | M_AUTA )
-#define I_DYN ( MICRO_MASK | M_YTP | M_15TN | M_C8 | M_AUTY )
-#define I_IA ( MICRO_MASK | M_ATN | M_CIN | M_AUTA )
-#define I_IMAC ( MICRO_MASK | M_MTP | M_CIN | M_C8 | M_AUTA )
-#define I_IYC ( MICRO_MASK | M_YTP | M_CIN | M_C8 | M_AUTY )
-#define I_KNEZ ( MICRO_MASK | M_CKP | M_NE )
-#define I_MNEA ( MICRO_MASK | M_MTP | M_ATN | M_NE )
-#define I_MNEZ ( MICRO_MASK | M_MTP | M_NE )
-#define I_SAMAN ( MICRO_MASK | M_MTP | M_NATN | M_CIN | M_C8 | M_AUTA )
-#define I_SETR ( MICRO_MASK | M_YTP | M_15TN | M_AUTY | M_C8 )
-#define I_TAM ( MICRO_MASK | M_STO )
-#define I_TAMACS ( MICRO_MASK | M_STO | M_ATN | M_CKP | M_AUTA | M_SSE )
-#define I_TAMDYN ( MICRO_MASK | M_STO | M_YTP | M_15TN | M_AUTY | M_C8 )
-#define I_TAMIY ( MICRO_MASK | M_STO | M_YTP | M_CIN | M_AUTY )
-#define I_TAMIYC ( MICRO_MASK | M_STO | M_YTP | M_CIN | M_C8 | M_AUTY )
-#define I_TAMZA ( MICRO_MASK | M_STO | M_AUTA )
-#define I_TAY ( MICRO_MASK | M_ATN | M_AUTY )
-#define I_TBIT ( MICRO_MASK | M_CKP | M_CKN | M_MTP | M_NE )
-#define I_TCY ( MICRO_MASK | M_CKP | M_AUTY )
-#define I_TCMIY ( MICRO_MASK | M_CKM | M_YTP | M_CIN | M_AUTY )
-#define I_TKA ( MICRO_MASK | M_CKP | M_AUTA )
-#define I_TKM ( MICRO_MASK | M_CKM )
-#define I_TMA ( MICRO_MASK | M_MTP | M_AUTA )
-#define I_TMY ( MICRO_MASK | M_MTP | M_AUTY )
-#define I_TYA ( MICRO_MASK | M_YTP | M_AUTA )
-#define I_XDA ( MICRO_MASK | M_DMTP | M_AUTA | M_STO )
-#define I_XMA ( MICRO_MASK | M_MTP | M_STO | M_AUTA )
-#define I_YMCY ( MICRO_MASK | M_CIN | M_YTP | M_CKN | M_AUTY )
-#define I_YNEA ( MICRO_MASK | M_YTP | M_ATN | M_NE )
-#define I_YNEC ( MICRO_MASK | M_YTP | M_CKN | M_NE )
-
-
-static const UINT8 tms0980_c2_value[4] = { 0, 2, 1, 3 };
-static const UINT8 tms0980_c3_value[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
-static const UINT8 tms0980_c4_value[16] = { 0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF };
-static const UINT8 tms0980_bit_value[4] = { 1, 4, 2, 8 };
-static const UINT8 tms0980_nbit_value[4] = { 0xE, 0xB, 0xD, 0x7 };
-
-
-static const UINT32 tms0980_decode[512] =
-{
- /* 0x000 */
- F_COMX, I_ALEM, I_YNEA, I_XMA, I_DYN, I_IYC, I_CLA, I_DMAN,
- I_TKA, I_MNEA, I_TKM, F_ILL, F_ILL, F_SETR, I_KNEZ, F_ILL,
- I_DMEA, I_DNAA, I_CCLA, I_NDMEA, F_ILL, I_AMAAC, F_ILL, F_ILL,
- I_CTMDYN, I_XDA, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL,
- I_TBIT, I_TBIT, I_TBIT, I_TBIT, F_ILL, F_ILL, F_ILL, F_ILL,
- I_TAY, I_TMA, I_TMY, I_TYA, I_TAMDYN, I_TAMIYC, I_TAMZA, I_TAM,
- I_SAMAN, I_CPAIZ, I_IMAC, I_MNEZ, F_ILL, F_ILL, F_ILL, F_ILL,
- I_TCY, I_YNEC, I_TCMIY, I_ACACC, I_ACNAA, I_TAMACS, I_ALEC, I_YMCY,
- /* 0x040 */
- I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY,
- I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY,
- I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC,
- I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC,
- I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY,
- I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY,
- I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC,
- I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC,
- /* 0x080 */
- F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP,
- F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP,
- F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX,
- F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX,
- F_SBIT, F_SBIT, F_SBIT, F_SBIT, F_RBIT, F_RBIT, F_RBIT, F_RBIT,
- F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL,
- F_TDO, F_SAL, F_COMX8, F_SBL, F_REAC, F_SEAC, F_OFF, F_ILL,
- F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_RETN,
- /* 0x0c0 */
- I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA,
- I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA,
- I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS,
- I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS,
- I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC,
- I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC,
- I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY,
- I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY,
- /* 0x100 */
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- /* 0x140 */
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- /* 0x180 */
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- /* 0x1c0 */
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL
-};
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
-static const UINT32 tms1000_default_decode[256] =
+enum
{
- /* 0x00 */
- F_COMX, I_A8AAC, I_YNEA, I_TAM, I_TAMZA, I_A10AAC, I_A6AAC, I_DAN,
- I_TKA, I_KNEZ, F_TDO, F_CLO, F_RSTR, F_SETR, I_IA, F_RETN,
- F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP,
- F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP,
- /* 0x20 */
- I_TAMIY, I_TMA, I_TMY, I_TYA, I_TAY, I_AMAAC, I_MNEZ, I_SAMAN,
- I_IMAC, I_ALEM, I_DMAN, I_IYC, I_DYN, I_CPAIZ, I_XMA, I_CLA,
- F_SBIT, F_SBIT, F_SBIT, F_SBIT, F_RBIT, F_RBIT, F_RBIT, F_RBIT,
- I_TBIT, I_TBIT, I_TBIT, I_TBIT, F_LDX, F_LDX, F_LDX, F_LDX,
- /* 0x40 */
- I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY,
- I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY,
- I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC,
- I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC,
- /* 0x60 */
- I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY,
- I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY,
- I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC,
- I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC,
- /* 0x80 */
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- /* 0xC0 */
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
+ TMS0980_PC=1, TMS0980_SR, TMS0980_PA, TMS0980_PB,
+ TMS0980_A, TMS0980_X, TMS0980_Y, TMS0980_STATUS
};
-
-static const UINT32 tms1100_default_decode[256] =
-{
- /* 0x00 */
- I_MNEA, I_ALEM, I_YNEA, I_XMA, I_DYN, I_IYC, I_AMAAC, I_DMAN,
- I_TKA, F_COMX, F_TDO, F_COMC, F_RSTR, F_SETR, I_KNEZ, F_RETN,
- F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP,
- F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP,
- /* 0x20 */
- I_TAY, I_TMA, I_TMY, I_TYA, I_TAMDYN, I_TAMIYC, I_TAMZA, I_TAM,
- F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX,
- F_SBIT, F_SBIT, F_SBIT, F_SBIT, F_RBIT, F_RBIT, F_RBIT, F_RBIT,
- I_TBIT, I_TBIT, I_TBIT, I_TBIT, I_SAMAN, I_CPAIZ, I_IMAC, I_MNEZ,
- /* 0x40 */
- I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY,
- I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY,
- I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC,
- I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC,
- /* 0x60 */
- I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY,
- I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY,
- I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC,
- I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_CLA,
- /* 0x80 */
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR,
- /* 0xC0 */
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
- F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL,
-};
-
-
-static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1xxx_cpu_device)
- AM_RANGE( 0x000, 0xfff ) AM_ROM
-ADDRESS_MAP_END
-
-
-static ADDRESS_MAP_START(program_10bit_8, AS_PROGRAM, 8, tms1xxx_cpu_device)
- AM_RANGE( 0x000, 0x3ff ) AM_ROM
-ADDRESS_MAP_END
-
-
-static ADDRESS_MAP_START(program_11bit_8, AS_PROGRAM, 8, tms1xxx_cpu_device)
- AM_RANGE( 0x000, 0x7ff ) AM_ROM
-ADDRESS_MAP_END
-
-
-static ADDRESS_MAP_START(data_64x4, AS_DATA, 8, tms1xxx_cpu_device)
- AM_RANGE( 0x00, 0x3f ) AM_RAM
-ADDRESS_MAP_END
-
-
-static ADDRESS_MAP_START(data_128x4, AS_DATA, 8, tms1xxx_cpu_device)
- AM_RANGE( 0x00, 0x7f ) AM_RAM
-ADDRESS_MAP_END
-
-
-static ADDRESS_MAP_START(data_64x9_as4, AS_DATA, 8, tms1xxx_cpu_device)
- AM_RANGE( 0x00, 0x8f ) AM_RAM
- AM_RANGE( 0x90, 0xff ) AM_NOP
-ADDRESS_MAP_END
-
-
void tms1xxx_cpu_device::device_start()
{
- m_program = &space( AS_PROGRAM );
- m_data = &space( AS_DATA );
+ m_program = &space(AS_PROGRAM);
+ m_data = &space(AS_DATA);
- m_read_k.resolve_safe(0xff);
+ m_read_k.resolve_safe(0);
m_write_o.resolve_safe();
m_write_r.resolve_safe();
+ m_power_off.resolve_safe();
+
+ m_o_mask = (1 << m_o_pins) - 1;
+ m_r_mask = (1 << m_r_pins) - 1;
+ m_k_mask = (1 << m_k_pins) - 1;
+ m_pc_mask = (1 << m_pc_bits) - 1;
+ m_x_mask = (1 << m_x_bits) - 1;
+
+ // zerofill
+ m_pc = 0;
+ m_sr = 0;
+ m_pa = 0;
+ m_pb = 0;
+ m_a = 0;
+ m_x = 0;
+ m_y = 0;
+ m_ca = 0;
+ m_cb = 0;
+ m_cs = 0;
+ m_r = 0;
+ m_o = 0;
+ m_cki_bus = 0;
+ m_c4 = 0;
+ m_p = 0;
+ m_n = 0;
+ m_adder_out = 0;
+ m_carry_in = 0;
+ m_carry_out = 0;
+ m_status = 0;
+ m_status_latch = 0;
+ m_eac = 0;
+ m_clatch = 0;
+ m_add = 0;
+ m_bl = 0;
+
+ m_ram_in = 0;
+ m_dam_in = 0;
+ m_ram_out = 0;
+ m_ram_address = 0;
+ m_rom_address = 0;
+ m_opcode = 0;
+ m_fixed = 0;
+ m_micro = 0;
+ m_subcycle = 0;
- save_item( NAME(m_prev_pc) );
- save_item( NAME(m_prev_pa) );
- save_item( NAME(m_pc) );
- save_item( NAME(m_pa) );
- save_item( NAME(m_sr) );
- save_item( NAME(m_pb) );
- save_item( NAME(m_a) );
- save_item( NAME(m_x) );
- save_item( NAME(m_y) );
- save_item( NAME(m_dam) );
- save_item( NAME(m_ca) );
- save_item( NAME(m_cb) );
- save_item( NAME(m_cs) );
- save_item( NAME(m_r) );
- save_item( NAME(m_o) );
- save_item( NAME(m_cki_bus) );
- save_item( NAME(m_p) );
- save_item( NAME(m_n) );
- save_item( NAME(m_adder_result) );
- save_item( NAME(m_carry_in) );
- save_item( NAME(m_status) );
- save_item( NAME(m_status_latch) );
- save_item( NAME(m_special_status) );
- save_item( NAME(m_call_latch) );
- save_item( NAME(m_add_latch) );
- save_item( NAME(m_branch_latch) );
- save_item( NAME(m_subcycle) );
- save_item( NAME(m_ram_address) );
- save_item( NAME(m_ram_data) );
- save_item( NAME(m_rom_address) );
- save_item( NAME(m_opcode) );
- save_item( NAME(m_decode) );
-
- // Register state for debugger
- state_add( TMS0980_PC, "PC", m_pc ).callimport().callexport().formatstr("%02X");
- state_add( TMS0980_SR, "SR", m_sr ).callimport().callexport().formatstr("%01X");
- state_add( TMS0980_PA, "PA", m_pa ).callimport().callexport().formatstr("%01X");
- state_add( TMS0980_PB, "PB", m_pb ).callimport().callexport().formatstr("%01X");
- state_add( TMS0980_A, "A", m_a ).callimport().callexport().formatstr("%01X");
- state_add( TMS0980_X, "X", m_x ).callimport().callexport().formatstr("%01X");
- state_add( TMS0980_Y, "Y", m_y ).callimport().callexport().formatstr("%01X");
- state_add( TMS0980_STATUS, "STATUS", m_status ).callimport().callexport().formatstr("%01X");
+ // register for savestates
+ save_item(NAME(m_pc));
+ save_item(NAME(m_sr));
+ save_item(NAME(m_pa));
+ save_item(NAME(m_pb));
+ save_item(NAME(m_a));
+ save_item(NAME(m_x));
+ save_item(NAME(m_y));
+ save_item(NAME(m_ca));
+ save_item(NAME(m_cb));
+ save_item(NAME(m_cs));
+ save_item(NAME(m_r));
+ save_item(NAME(m_o));
+ save_item(NAME(m_cki_bus));
+ save_item(NAME(m_c4));
+ save_item(NAME(m_p));
+ save_item(NAME(m_n));
+ save_item(NAME(m_adder_out));
+ save_item(NAME(m_carry_in));
+ save_item(NAME(m_carry_out));
+ save_item(NAME(m_status));
+ save_item(NAME(m_status_latch));
+ save_item(NAME(m_eac));
+ save_item(NAME(m_clatch));
+ save_item(NAME(m_add));
+ save_item(NAME(m_bl));
+
+ save_item(NAME(m_ram_in));
+ save_item(NAME(m_dam_in));
+ save_item(NAME(m_ram_out));
+ save_item(NAME(m_ram_address));
+ save_item(NAME(m_rom_address));
+ save_item(NAME(m_opcode));
+ save_item(NAME(m_fixed));
+ save_item(NAME(m_micro));
+ save_item(NAME(m_subcycle));
+
+ // register state for debugger
+ state_add(TMS0980_PC, "PC", m_pc ).callimport().callexport().formatstr("%02X");
+ state_add(TMS0980_SR, "SR", m_sr ).callimport().callexport().formatstr("%01X");
+ state_add(TMS0980_PA, "PA", m_pa ).callimport().callexport().formatstr("%01X");
+ state_add(TMS0980_PB, "PB", m_pb ).callimport().callexport().formatstr("%01X");
+ state_add(TMS0980_A, "A", m_a ).callimport().callexport().formatstr("%01X");
+ state_add(TMS0980_X, "X", m_x ).callimport().callexport().formatstr("%01X");
+ state_add(TMS0980_Y, "Y", m_y ).callimport().callexport().formatstr("%01X");
+ state_add(TMS0980_STATUS, "STATUS", m_status).callimport().callexport().formatstr("%01X");
state_add(STATE_GENPC, "curpc", m_pc).callimport().callexport().formatstr("%8s").noshow();
state_add(STATE_GENFLAGS, "GENFLAGS", m_sr).callimport().callexport().formatstr("%8s").noshow();
@@ -496,614 +453,658 @@ void tms1xxx_cpu_device::device_start()
}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
void tms1xxx_cpu_device::device_reset()
{
- m_pa = 0xF;
- m_pb = 0xF;
+ m_pa = 0xf;
+ m_pb = 0xf;
m_pc = 0;
- m_dam = 0;
m_ca = 0;
m_cb = 0;
m_cs = 0;
+
+ m_eac = 0;
+ m_bl = 0;
+ m_add = 0;
+
+ m_opcode = 0;
+ m_micro = 0;
+ m_fixed = 0;
+
m_subcycle = 0;
- m_status = 1;
- m_status_latch = 0;
- m_call_latch = 0;
- m_add_latch = 0;
- m_branch_latch = 0;
+
+ // clear outputs
m_r = 0;
- m_o = 0;
- m_ram_address = 0;
- m_decode = F_ILL;
- m_opcode = 0;
+ m_write_r(0, m_r & m_r_mask, 0xffff);
+ write_o_output(0);
+ m_write_r(0, m_r & m_r_mask, 0xffff);
}
-/*
-The program counter is implemented using PRNG logic and gets incremented as follows:
-
-00, 01, 03, 07, 0F, 1F, 3F, 3E,
-3D, 3B, 37, 2F, 1E, 3C, 39, 33
-27, 0E, 1D, 3A, 35, 2B, 16, 2C,
-18, 30, 21, 02, 05, 0B, 17, 2E,
-1C, 38, 31, 23, 06, 0D, 1B, 36,
-2D, 1A, 34, 29, 12, 24, 08, 11,
-22, 04, 09, 13, 26, 0C, 19, 32,
-25, 0A, 15, 2A, 14, 28, 10, 20
-
-There is also a strange address (AD) to location (LOC) mapping performed by the
-tms1000 family.
-
-From tms1000 family pdf:
-AD LOC
-000 000000 003 000011
-001 000001 004 000100
-003 000011 00C 001100
-007 000111 01C 011100
-00F 001111 03C 111100
-01F 011111 03F 111111
-03F 111111 03E 111110
-03E 111110 039 111001
-03D 111101 036 110110
-03B 111011 02E 101110
-037 110111 01E 011110
-02F 101111 03D 111101
-01E 011110 038 111000
-03C 111100 031 110001
-039 111001 026 100110
-033 110011 00E 001110
-027 100111 01D 011101
-00E 001110 03B 111011
-01D 011101 037 110111
-03A 111010 029 101001
-035 110101 016 010110
-02B 101011 02D 101101
-016 010110 018 011000
-02C 101100 032 110010
-018 011000 020 100000
-030 110000 001 000001
-021 100001 005 000101
-002 000010 00B 001011
-005 000101 014 010100
-00B 001011 02C 101100
-017 010111 01F 011111
-02E 101110 03A 111010
-01C 011100 030 110000
-038 111000 021 100001
-031 110001 006 000110
-023 100011 00D 001101
-006 000110 01B 011011
-00D 001101 034 110100
-01B 011011 02F 101111
-036 110110 019 011001
-02D 101101 035 110101
-01A 011010 028 101000
-034 110100 011 010001
-029 101001 025 100101
-012 010010 008 001000
-024 100100 012 010010
-008 001000 023 100011
-011 010001 007 000111
-022 100010 00A 001010
-004 000100 013 010011
-009 001001 024 100100
-013 010011 00F 001111
-026 100110 01A 011010
-00C 001100 033 110011
-019 011001 027 100111
-032 110010 009 001001
-025 100101 015 010101
-00A 001010 02B 101011
-015 010101 017 010111
-02A 101010 02A 101010
-014 010100 010 010000
-028 101000 022 100010
-010 010000 000 000000
-020 100000 002 000010
-
-The following formula seems to be used to decode a program counter
-into a rom address:
-location{5:2} = pc{3:0}
-location{1:0} = ( pc{5:4} == 00 && pc{0} == 0 ) => 11
- ( pc{5:4} == 00 && pc{0} == 1 ) => 00
- ( pc{5:4} == 01 && pc{0} == 0 ) => 00
- ( pc{5:4} == 01 && pc{0} == 1 ) => 11
- ( pc{5:4} == 10 && pc{0} == 0 ) => 10
- ( pc{5:4} == 10 && pc{0} == 1 ) => 01
- ( pc{5:4} == 11 && pc{0} == 0 ) => 01
- ( pc{5:4} == 11 && pc{0} == 1 ) => 10
+void tms1000_cpu_device::device_reset()
+{
+ // common reset
+ tms1xxx_cpu_device::device_reset();
+
+ // pre-decode instructionset
+ m_fixed_decode.resize_and_clear(0x100);
+ m_micro_decode.resize_and_clear(0x100);
+
+ 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];
+ }
-*/
-static const UINT8 tms1000_next_pc[64] =
+ // 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()
{
- 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,
- 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3F,
- 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E,
- 0x21, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3B, 0x3D, 0x3E,
-};
+ 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;
+}
-/* emulator for the program counter increment on the tms0980/tmc0980 mcu;
- see patent 4064554 figure 19 (on page 13) for an explanation of feedback:
-
- nand324 = NAND of PC0 through pc4, i.e. output is true if ((pc&0x1f) != 0x1f)
- nand323 = NAND of pc5, pc6 and nand324
- i.e. output is true, if ((pc&0x1f)==0x1f) || pc5 is 0 || pc 6 is 0
- or321 = OR of pc5 and pc6, i.e. output is true if ((pc&0x60) != 0)
- nand322 = NAND of pc0 through pc5 plus /pc6,
- i.e. output is true if (pc != 0x3f)
- nand325 = nand of nand323, or321 and nand322
- This one is complex:
- / or321 means if pc&0x60 is zero, output MUST be true
- \ nand323 means if (pc&0x60=0x60) && (pc&0x1f != 0x1f), output MUST be true
- nand322 means if pc = 0x3f, output MUST be true
- hence, nand325 is if pc = 0x7f, false. if pc = 0x3f, true. if pc&0x60 is zero OR pc&0x60 is 0x60, true. otherwise, false.
-
- tms0980_next_pc below implements an identical function to this in a somewhat more elegant way.
-*/
-void tms1xxx_cpu_device::next_pc()
+
+void tms0970_cpu_device::device_reset()
{
- if ( m_byte_size > 8 )
- {
- UINT8 xorval = ( m_pc & 0x3F ) == 0x3F ? 1 : 0;
- UINT8 new_bit = ( ( m_pc ^ ( m_pc << 1 ) ) & 0x40 ) ? xorval : 1 - xorval;
+ // common reset
+ tms1xxx_cpu_device::device_reset();
- m_pc = ((m_pc << 1) | new_bit) & ((1 << m_pc_size) - 1);
- }
- else
+ // pre-decode instructionset
+ m_fixed_decode.resize_and_clear(0x100);
+ m_micro_decode.resize_and_clear(0x100);
+
+ for (int op = 0; op < 0x100; op++)
{
- m_pc = tms1000_next_pc[ m_pc & 0x3f ];
+ // 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];
}
}
-static const UINT8 tms1000_pc_decode[64] =
+UINT32 tms0980_cpu_device::decode_micro(UINT8 sel)
{
- 0x03, 0x04, 0x0B, 0x0C, 0x13, 0x14, 0x1B, 0x1C,
- 0x23, 0x24, 0x2B, 0x2C, 0x33, 0x34, 0x3B, 0x3C,
- 0x00, 0x07, 0x08, 0x0F, 0x10, 0x17, 0x18, 0x1F,
- 0x20, 0x27, 0x28, 0x2F, 0x30, 0x37, 0x38, 0x3F,
- 0x02, 0x05, 0x0A, 0x0D, 0x12, 0x15, 0x1A, 0x1D,
- 0x22, 0x25, 0x2A, 0x2D, 0x32, 0x35, 0x3A, 0x3D,
- 0x01, 0x06, 0x09, 0x0E, 0x11, 0x16, 0x19, 0x1E,
- 0x21, 0x26, 0x29, 0x2E, 0x31, 0x36, 0x39, 0x3E
-};
-
+ 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
+
+ // _______ ______ _____ _____ _____ _____ ______ _____ ______ _____ _____
+ const UINT32 md[20] = { 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 };
+
+ for (int bit = 0; bit < 20; bit++)
+ if (mask & (1 << bit))
+ decode |= md[bit];
+
+ return decode;
+}
-void tms1xxx_cpu_device::set_cki_bus()
+void tms0980_cpu_device::device_reset()
{
- switch( m_opcode & 0x1F8 )
+ // common reset
+ tms1xxx_cpu_device::device_reset();
+
+ // pre-decode instructionset
+ m_fixed_decode.resize_and_clear(0x200);
+ m_micro_decode.resize_and_clear(0x200);
+
+ for (int op = 0; op < 0x200; op++)
{
- case 0x008:
- m_cki_bus = m_read_k( 0, 0xff );
- break;
- case 0x020: case 0x028:
- m_cki_bus = 0;
- break;
- case 0x030: case 0x038:
- m_cki_bus = tms0980_nbit_value[ m_opcode & 0x03 ];
- break;
- case 0x000:
- case 0x040: case 0x048:
- case 0x050: case 0x058:
- case 0x060: case 0x068:
- case 0x070: case 0x078:
- case 0x080: case 0x088:
- case 0x090: case 0x098:
- case 0x0c0: case 0x0c8:
- case 0x0d0: case 0x0d8:
- case 0x0e0: case 0x0e8:
- case 0x0f0: case 0x0f8:
- m_cki_bus = tms0980_c4_value[ m_opcode & 0x0F ];
- break;
- default:
- m_cki_bus = 0x0F;
- break;
+ // 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_and_clear(0x40);
+
+ for (int op = 0; op < 0x40; op++)
+ m_micro_direct[op] = decode_micro(op);
}
-void tms1xxx_cpu_device::execute_run()
+
+
+
+void tms1xxx_cpu_device::next_pc()
{
- do
- {
- m_icount--;
- switch( m_subcycle )
- {
- case 0:
- /* fetch: rom address 0 */
- /* execute: read ram, alu input, execute br/call, k input valid */
- set_cki_bus();
- m_ram_data = m_data->read_byte( m_ram_address );
- m_status = 1;
- m_p = 0;
- m_n = 0;
- m_carry_in = 0;
- break;
- case 1:
- /* fetch: rom address 1 */
- m_rom_address = ( m_ca << ( m_pc_size + 4 ) ) | ( m_pa << m_pc_size ) | m_pc;
- /* execute: k input valid */
- if ( m_decode & MICRO_MASK )
- {
- /* Check N inputs */
- if ( m_decode & ( M_15TN | M_ATN | M_CKN | M_MTN | M_NATN ) )
- {
- m_n = 0;
- if ( m_decode & M_15TN )
- {
- m_n |= 0x0F;
- }
- if ( m_decode & M_ATN )
- {
- m_n |= m_a;
- }
- if ( m_decode & M_CKN )
- {
- m_n |= m_cki_bus;
- }
- if ( m_decode & M_MTN )
- {
- m_n |= m_ram_data;
- }
- if ( m_decode & M_NATN )
- {
- m_n |= ( ( ~m_a ) & 0x0F );
- }
- }
+ // The program counter is a LFSR. To put it simply, the feedback bit is a XOR of the two highest bits,
+ // but it makes an exception when all low bits are set (eg. in TMS1000 case, when PC is 0x1f or 0x3f).
+ int high = 1 << (m_pc_bits - 1);
+ int fb = (m_pc << 1 & high) == (m_pc & high);
+
+ if (m_pc == (m_pc_mask >> 1))
+ fb = 1;
+ else if (m_pc == m_pc_mask)
+ fb = 0;
+
+ m_pc = (m_pc << 1 | fb) & m_pc_mask;
+}
+void tms1xxx_cpu_device::read_opcode()
+{
+ debugger_instruction_hook(this, m_rom_address);
+ m_opcode = m_program->read_byte(m_rom_address);
+ m_c4 = BITSWAP8(m_opcode,7,6,5,4,0,1,2,3) & 0xf; // opcode operand is bitswapped for most opcodes
- /* Check P inputs */
- if ( m_decode & ( M_CKP | M_DMTP | M_MTP | M_NDMTP | M_YTP ) )
- {
- m_p = 0;
- if ( m_decode & M_CKP )
- {
- m_p |= m_cki_bus;
- }
- if ( m_decode & M_DMTP )
- {
- m_p |= m_dam;
- }
- if ( m_decode & M_MTP )
- {
- m_p |= m_ram_data;
- }
- if ( m_decode & M_NDMTP )
- {
- m_p |= ( ( ~m_dam ) & 0x0F );
- }
- if ( m_decode & M_YTP )
- {
- m_p |= m_y;
- }
- }
+ m_fixed = m_fixed_decode[m_opcode];
+ m_micro = m_micro_decode[m_opcode];
- /* Carry In input */
- if ( m_decode & M_CIN )
- {
- m_carry_in = 1;
- }
- }
+ 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];
+
+ next_pc();
+}
+
+
+void tms1xxx_cpu_device::write_o_output(UINT8 data)
+{
+ // a hardcoded table is supported if the output pla is unknown
+ m_o = (c_output_pla == NULL) ? m_opla->read(data) : c_output_pla[data];
+
+ if ((m_o & 0xff00) == 0xff00)
+ logerror("unknown output pla mapping for index %02X\n", data);
+
+ m_write_o(0, m_o & m_o_mask, 0xffff);
+}
+
+void tms0970_cpu_device::write_o_output(UINT8 data)
+{
+ m_o = m_spla->read(data);
+ m_write_o(0, m_o & m_o_mask, 0xffff);
+}
+
+UINT8 tms1xxx_cpu_device::read_k_input()
+{
+ // K1,2,4,8,3 (KC test pin is not emulated)
+ UINT8 k = m_read_k(0, 0xff) & m_k_mask;
+ UINT8 k3 = (k & 0x10) ? 3: 0; // the K3 line that is on some chips, is simply K1|K2
+ return (k & 0xf) | k3;
+}
+
+
+void tms1xxx_cpu_device::set_cki_bus()
+{
+ switch (m_opcode & 0xf8)
+ {
+ // 00001XXX: K-inputs
+ case 0x08:
+ m_cki_bus = read_k_input();
break;
- case 2:
- /* fetch: nothing */
- /* execute: write ram */
- /* perform adder logic */
- m_adder_result = m_p + m_n + m_carry_in;
- if ( m_decode & MICRO_MASK )
- {
- if ( m_decode & M_NE )
- {
- if ( m_n == m_p )
- {
- m_status = 0;
- }
- }
- if ( m_decode & M_C8 )
- {
- m_status = m_adder_result >> 4;
- }
- if ( m_decode & M_STO )
- {
- m_data->write_byte( m_ram_address, m_a );
- }
- if ( m_decode & M_CKM )
- {
- m_data->write_byte( m_ram_address, m_cki_bus );
- }
- }
- else
- {
- if ( m_decode & F_SBIT )
- {
- m_data->write_byte( m_ram_address, m_ram_data | tms0980_bit_value[ m_opcode & 0x03 ] );
- }
- if ( m_decode & F_RBIT )
- {
- m_data->write_byte( m_ram_address, m_ram_data & tms0980_nbit_value[ m_opcode & 0x03 ] );
- }
- if ( m_decode & F_SETR )
- {
- m_r = m_r | ( 1 << m_y );
- m_write_r( 0, m_r & m_r_mask, 0xffff );
- }
- if ( m_decode & F_RSTR )
- {
- m_r = m_r & ( ~( 1 << m_y ) );
- m_write_r( 0, m_r & m_r_mask, 0xffff );
- }
- if ( m_decode & F_TDO )
- {
- /* Calculate O-outputs based on status latch, A, and the output PLA configuration */
- m_o = c_output_pla[ ( m_status_latch << 4 ) | m_a ];
- if ( ( c_output_pla[ ( m_status_latch << 4 ) | m_a ] & 0xFF00 ) == 0xFF00 )
- {
- logerror("unknown output pla mapping for status latch = %d and a = %X\n", m_status_latch, m_a);
- }
- m_write_o( 0, m_o & m_o_mask, 0xffff );
- }
- if ( m_decode & F_CLO )
- {
- m_o = 0;
- m_write_o( 0, m_o & m_o_mask, 0xffff );
- }
- if ( m_decode & F_LDX )
- {
- switch( m_x_bits )
- {
- case 2:
- m_x = tms0980_c2_value[ m_opcode & 0x03 ];
- break;
- case 3:
- m_x = tms0980_c3_value[ m_opcode & 0x07 ];
- break;
- case 4:
- m_x = tms0980_c4_value[ m_opcode & 0x0f ];
- break;
- }
- }
- if ( m_decode & F_COMX )
- {
- switch ( m_x_bits )
- {
- case 2:
- m_x = m_x ^ 0x03;
- break;
- case 3:
- m_x = m_x ^ 0x07;
- break;
- case 4:
- m_x = m_x ^ 0x0f;
- break;
- }
- }
- if ( m_decode & F_COMC )
- {
- m_cb = m_cb ^ 0x01;
- }
- if ( m_decode & F_LDP )
- {
- m_pb = tms0980_c4_value[ m_opcode & 0x0F ];
- }
- if ( m_decode & F_REAC )
- {
- m_special_status = 0;
- }
- if ( m_decode & F_SEAC )
- {
- m_special_status = 1;
- }
- if ( m_decode == F_SAL )
- {
- m_add_latch = 1;
- }
- if ( m_decode == F_SBL )
- {
- m_branch_latch = 1;
- }
- }
+ // 0011XXXX: select bit
+ case 0x30: case 0x38:
+ m_cki_bus = 1 << (m_c4 >> 2) ^ 0xf;
break;
- case 3:
- /* fetch: fetch, update pc, ram address */
- /* execute: register store */
+
+ // 01XXXXXX: constant
+ case 0x00: // R2,3,4 are NANDed with eachother, and then ORed with R1, making 00000XXX valid too
+ case 0x40: case 0x48: case 0x50: case 0x58: case 0x60: case 0x68: case 0x70: case 0x78:
+ m_cki_bus = m_c4;
break;
- case 4:
- /* execute: register store */
- if ( m_decode & MICRO_MASK )
- {
- if ( m_decode & M_AUTA )
- {
- m_a = m_adder_result & 0x0F;
- }
- if ( m_decode & M_AUTY )
- {
- m_y = m_adder_result & 0x0F;
- }
- if ( m_decode & M_STSL )
- {
- m_status_latch = m_status;
- }
- }
- /* fetch: fetch, update pc, ram address */
- if ( m_byte_size > 8 )
- {
- debugger_instruction_hook( this, m_rom_address << 1 );
- m_opcode = m_program->read_word( m_rom_address << 1 ) & 0x1FF;
- }
- else
- {
- debugger_instruction_hook( this, m_rom_address );
- m_opcode = m_program->read_byte( m_rom_address );
- }
- next_pc();
- /* ram address */
- m_ram_address = ( m_x << 4 ) | m_y;
- break;
- case 5:
- /* fetch: instruction decode */
- m_decode = m_decode_table[ m_opcode ];
- /* execute: execute br/call */
- if ( m_status )
- {
- if ( m_decode == F_BR )
- {
- m_ca = m_cb;
- if ( m_call_latch == 0 )
- {
- m_pa = m_pb;
- }
- m_pc = m_opcode & ( ( 1 << m_pc_size ) - 1 );
- }
- if ( m_decode == F_CALL )
- {
- UINT8 t = m_pa;
- if ( m_call_latch == 0 )
- {
- m_sr = m_pc;
- m_call_latch = 1;
- m_pa = m_pb;
- m_cs = m_ca;
- }
- m_ca = m_cb;
- m_pb = t;
- m_pc = m_opcode & ( ( 1 << m_pc_size ) - 1 );
- }
- }
- if ( m_decode == F_RETN )
- {
- if ( m_call_latch == 1 )
- {
- m_pc = m_sr;
- m_call_latch = 0;
- m_ca = m_cs;
- }
- m_add_latch = 0;
- m_pa = m_pb;
- } else {
- m_branch_latch = 0;
- }
+ default:
+ m_cki_bus = 0;
break;
- }
- m_subcycle = ( m_subcycle + 1 ) % 6;
- } while( m_icount > 0 );
+ }
}
-
-void tms0980_cpu_device::state_string_export(const device_state_entry &entry, astring &string)
+void tms0980_cpu_device::set_cki_bus()
{
- switch( entry.index() )
+ switch (m_opcode & 0x1f8)
{
- case STATE_GENPC:
- string.printf( "%03X", ( ( m_pa << 7 ) | m_pc ) << 1 );
+ // 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;
}
}
-void tms1000_cpu_device::state_string_export(const device_state_entry &entry, astring &string)
+// fixed opcode set
+
+// TMS1000/common:
+
+void tms1xxx_cpu_device::op_sbit()
{
- switch( entry.index() )
- {
- case STATE_GENPC:
- string.printf( "%03X", ( m_pa << 6 ) | tms1000_pc_decode[ m_pc ] );
- break;
- }
+ // SBIT: set memory bit
+ if (m_ram_out == -1)
+ m_ram_out = m_ram_in;
+ m_ram_out |= (m_cki_bus ^ 0xf);
}
+void tms1xxx_cpu_device::op_rbit()
+{
+ // RBIT: reset memory bit
+ if (m_ram_out == -1)
+ m_ram_out = m_ram_in;
+ m_ram_out &= m_cki_bus;
+}
-void tms1100_cpu_device::state_string_export(const device_state_entry &entry, astring &string)
+void tms1xxx_cpu_device::op_setr()
{
- switch( entry.index() )
- {
- case STATE_GENPC:
- string.printf( "%03X", ( m_ca << 10 ) | ( m_pa << 6 ) | m_pc );
- break;
- }
+ // SETR: set one R-output line
+ m_r = m_r | (1 << m_y);
+ m_write_r(0, m_r & m_r_mask, 0xffff);
}
+void tms1xxx_cpu_device::op_rstr()
+{
+ // RSTR: reset one R-output line
+ m_r = m_r & ~(1 << m_y);
+ m_write_r(0, m_r & m_r_mask, 0xffff);
+}
-tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1xxx_cpu_device( mconfig, TMS0980, "TMS0980", tag, owner, clock, tms0980_decode, 0x00ff, 0x07ff, 7, 9, 4
- , 12, ADDRESS_MAP_NAME( program_11bit_9 ), 8, ADDRESS_MAP_NAME( data_64x9_as4 ), "tms0980", __FILE__)
+void tms1xxx_cpu_device::op_tdo()
{
+ // TDO: transfer accumulator and status latch to O-output
+ write_o_output(m_status_latch << 4 | m_a);
}
+void tms1xxx_cpu_device::op_clo()
+{
+ // CLO: clear O-output
+ write_o_output(0);
+}
-offs_t tms0980_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+void tms1xxx_cpu_device::op_ldx()
{
- extern CPU_DISASSEMBLE( tms0980 );
- return CPU_DISASSEMBLE_NAME(tms0980)(this, buffer, pc, oprom, opram, options);
+ // LDX: load X register with (x_bits) constant
+ m_x = m_c4 >> (4-m_x_bits);
}
+void tms1xxx_cpu_device::op_comx()
+{
+ // COMX: complement X register
+ m_x ^= m_x_mask;
+}
-tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1xxx_cpu_device( mconfig, TMS1000, "TMS1000", tag, owner, clock, tms1000_default_decode, 0x00ff, 0x07ff, 6, 8, 2
- , 10, ADDRESS_MAP_NAME( program_10bit_8 ), 6, ADDRESS_MAP_NAME( data_64x4 ), "tms1000", __FILE__)
+void tms1xxx_cpu_device::op_comx8()
+{
+ // COMX8: complement MSB of X register
+ // note: on TMS1100, the mnemonic is simply called "COMX"
+ m_x ^= 1 << (m_x_bits-1);
+}
+
+void tms1xxx_cpu_device::op_ldp()
{
+ // LDP: load page buffer with constant
+ m_pb = m_c4;
}
-tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, device_type type, const char*name, const char *tag, device_t *owner, UINT32 clock, UINT16 o_mask, UINT16 r_mask, const char *shortname, const char *source)
- : tms1xxx_cpu_device( mconfig, type, name, tag, owner, clock, tms1000_default_decode, o_mask, r_mask, 6, 8, 2
- , 10, ADDRESS_MAP_NAME( program_10bit_8 ), 6, ADDRESS_MAP_NAME( data_64x4 ), shortname, source )
+// 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)))
+ tms1xxx_cpu_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)))
+ tms1xxx_cpu_device::op_rstr();
+}
-offs_t tms1000_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+void tms1xxx_cpu_device::op_comc()
{
- extern CPU_DISASSEMBLE( tms1000 );
- return CPU_DISASSEMBLE_NAME(tms1000)(this, buffer, pc, oprom, opram, options);
+ // COMC: complement chapter buffer
+ m_cb ^= 1;
}
-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, 0x00ff, 0x07ff, "tms0970", __FILE__)
+// TMS09x0-specific
+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) ? 0 : 1;
+ m_r = (m_r & ~(1 << m_y)) | (ddig << m_y);
}
-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, 0x00ff, 0x07ff, "tms1070", __FILE__)
+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);
}
-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, 0x00ff, 0x1fff, "tms1200", __FILE__)
+// TMS0980-specific
+void tms0980_cpu_device::op_comx()
{
+ // COMX: complement X register, but not the MSB
+ m_x ^= (m_x_mask >> 1);
}
+void tms1xxx_cpu_device::op_xda()
+{
+ // XDA: exchange DAM and A
+ // note: setting A to DAM is done with DMTP and AUTA during this instruction
+ m_ram_address |= (0x10 << (m_x_bits-1));
+}
-tms1270_cpu_device::tms1270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1000_cpu_device( mconfig, TMS1270, "TMS1270", tag, owner, clock, 0x03ff, 0x1fff, "tms1270", __FILE__)
+void tms1xxx_cpu_device::op_off()
{
+ // OFF: request power off
+ logerror("%s: power-off request\n", tag());
+ m_power_off(1);
}
+void tms1xxx_cpu_device::op_seac()
+{
+ // SEAC: set end around carry
+ m_eac = 1;
+}
-tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1xxx_cpu_device( mconfig, TMS1100, "TMS1100", tag, owner, clock, tms1100_default_decode, 0x00ff, 0x07ff, 6, 8, 3
- , 11, ADDRESS_MAP_NAME( program_11bit_8 ), 7, ADDRESS_MAP_NAME( data_128x4 ), "tms1100", __FILE__ )
+void tms1xxx_cpu_device::op_reac()
{
+ // REAC: reset end around carry
+ m_eac = 0;
}
+void tms1xxx_cpu_device::op_sal()
+{
+ // SAL: set add latch (reset is done with RETN)
+ m_add = 1;
+}
-tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, device_type type, const char*name, const char *tag, device_t *owner, UINT32 clock, UINT16 o_mask, UINT16 r_mask, const char *shortname, const char *source)
- : tms1xxx_cpu_device( mconfig, type, name, tag, owner, clock, tms1100_default_decode, o_mask, r_mask, 6, 8, 3
- , 11, ADDRESS_MAP_NAME( program_11bit_8 ), 7, ADDRESS_MAP_NAME( data_128x4 ), shortname, source )
+void tms1xxx_cpu_device::op_sbl()
{
+ // SBL: set branch latch (reset is done with RETN)
+ m_bl = 1;
}
-offs_t tms1100_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+void tms1xxx_cpu_device::execute_fixed_opcode()
{
- extern CPU_DISASSEMBLE( tms1100 );
- return CPU_DISASSEMBLE_NAME(tms1100)(this, buffer, pc, oprom, opram, options);
+ switch (m_fixed)
+ {
+ case F_SBIT: op_sbit(); break;
+ case F_RBIT: op_rbit(); break;
+ case F_SETR: op_setr(); break;
+ case F_RSTR: op_rstr(); break;
+ case F_TDO: op_tdo(); break;
+ case F_CLO: op_clo(); break;
+ case F_LDX: op_ldx(); break;
+ case F_COMX: op_comx(); break;
+ case F_COMX8:op_comx8();break;
+ case F_LDP: op_ldp(); break;
+ case F_COMC: op_comc(); break;
+ case F_OFF: op_off(); break;
+ case F_SEAC: op_seac(); break;
+ case F_REAC: op_reac(); break;
+ case F_SAL: op_sal(); break;
+ case F_SBL: op_sbl(); break;
+ case F_XDA: op_xda(); break;
+
+ default:
+ // BR, CALL, RETN are handled in execute_run
+ if (m_fixed & ~(F_BR | F_CALL | F_RETN))
+ fatalerror("%s unsupported fixed opcode %03X %04X!\n", tag(), m_opcode, m_fixed);
+ break;
+ }
}
-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, 0x00ff, 0xffff, "tms1300", __FILE__ )
+
+void tms1xxx_cpu_device::execute_run()
{
+ do
+ {
+ m_icount--;
+ switch (m_subcycle)
+ {
+ case 0:
+ // fetch: rom address 1/2
+
+ // execute: br/call 2/2
+ // note: add(latch) and bl(branch latch) are specific to 0980 series,
+ // c(chapter) bits are specific to 1100 series
+ if (m_status)
+ {
+ UINT8 new_pc = m_opcode & m_pc_mask;
+
+ // BR: conditional branch
+ if (m_fixed & F_BR)
+ {
+ if (m_clatch == 0)
+ m_pa = m_pb;
+ m_ca = m_cb;
+ m_pc = new_pc;
+ }
+
+ // CALL: conditional call
+ if (m_fixed & F_CALL)
+ {
+ UINT8 prev_pa = m_pa;
+ if (m_clatch == 0)
+ {
+ m_sr = m_pc;
+ m_clatch = 1;
+ m_pa = m_pb;
+ m_cs = m_ca;
+ }
+ m_ca = m_cb;
+ m_pb = prev_pa;
+ m_pc = new_pc;
+ }
+ }
+
+ // RETN: return from subroutine
+ if (m_fixed & F_RETN)
+ {
+ if (m_clatch == 1)
+ {
+ m_pc = m_sr;
+ m_clatch = 0;
+ m_ca = m_cs;
+ }
+ m_add = 0;
+ m_bl = 0;
+ m_pa = m_pb;
+ }
+
+ // execute: k input valid, read ram, clear alu inputs
+ set_cki_bus();
+ m_ram_in = m_data->read_byte(m_ram_address) & 0xf;
+ m_dam_in = m_data->read_byte(m_ram_address | (0x10 << (m_x_bits-1))) & 0xf;
+ m_ram_out = -1;
+ m_status = 1;
+ m_p = 0;
+ m_n = 0;
+ m_carry_in = 0;
+
+ break;
+
+ case 1:
+ // fetch: rom address 2/2
+ m_rom_address = (m_ca << (m_pc_bits+4)) | (m_pa << m_pc_bits) | m_pc;
+
+ // execute: update alu inputs
+ // N inputs
+ if (m_micro & M_15TN) m_n |= 0xf;
+ if (m_micro & M_ATN) m_n |= m_a;
+ if (m_micro & M_NATN) m_n |= (~m_a & 0xf);
+ if (m_micro & M_CKN) m_n |= m_cki_bus;
+ if (m_micro & M_MTN) m_n |= m_ram_in;
+
+ // P inputs
+ if (m_micro & M_CKP) m_p |= m_cki_bus;
+ if (m_micro & M_MTP) m_p |= m_ram_in;
+ if (m_micro & M_YTP) m_p |= m_y;
+ if (m_micro & M_DMTP) m_p |= m_dam_in;
+ if (m_micro & M_NDMTP) m_p |= (~m_dam_in & 0xf);
+
+ // carry input
+ if (m_micro & M_CIN) m_carry_in |= 1;
+ if (m_micro & M_SSS) m_carry_in |= m_eac;
+
+ break;
+
+ case 2:
+ {
+ // fetch: nothing
+
+ // execute: perform alu logic
+ // note: officially, only 1 alu operation is allowed per opcode
+ m_adder_out = m_p + m_n + m_carry_in;
+ int carry_out = m_adder_out >> 4 & 1;
+
+ if (m_micro & M_C8) m_status &= carry_out;
+ if (m_micro & M_NE) m_status &= (m_n != m_p); // COMP
+
+ if (m_micro & M_CKM) m_ram_out = m_cki_bus;
+
+ // special status circuit
+ if (m_micro & M_SSE)
+ {
+ m_eac = m_carry_out;
+ if (m_add)
+ m_eac |= carry_out;
+ }
+ m_carry_out = carry_out;
+
+ if (m_micro & M_STO || (m_micro & M_CME && m_eac == m_add))
+ m_ram_out = m_a;
+
+ // handle the fixed opcodes here
+ execute_fixed_opcode();
+
+ // execute: write ram
+ if (m_ram_out != -1)
+ m_data->write_byte(m_ram_address, m_ram_out);
+
+ break;
+ }
+
+ case 3:
+ // fetch: update pc, ram address 1/2
+ // execute: register store 1/2
+ break;
+
+ case 4:
+ // execute: register store 2/2
+ if (m_micro & M_AUTA) m_a = m_adder_out & 0xf;
+ if (m_micro & M_AUTY) m_y = m_adder_out & 0xf;
+ if (m_micro & M_STSL) m_status_latch = m_status;
+
+ // fetch: update pc, ram address 2/2
+ read_opcode();
+ m_ram_address = m_x << 4 | m_y;
+ break;
+
+ case 5:
+ // fetch: instruction decode (handled above, before next_pc)
+ // execute: br/call 1/2
+ break;
+ }
+ m_subcycle = (m_subcycle + 1) % 6;
+ } while (m_icount > 0);
}
diff --git a/src/emu/cpu/tms0980/tms0980.h b/src/emu/cpu/tms0980/tms0980.h
index c24dcacab25..4f00d2b5b74 100644
--- a/src/emu/cpu/tms0980/tms0980.h
+++ b/src/emu/cpu/tms0980/tms0980.h
@@ -1,61 +1,65 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS0980/TMS1000-family MCU cores
+
+*/
#ifndef _TMS0980_H_
#define _TMS0980_H_
-
-/* Registers */
-enum {
- TMS0980_PC=1, TMS0980_SR, TMS0980_PA, TMS0980_PB,
- TMS0980_A, TMS0980_X, TMS0980_Y, TMS0980_STATUS
-};
+#include "emu.h"
+#include "machine/pla.h"
#define MCFG_TMS1XXX_OUTPUT_PLA(_pla) \
tms1xxx_cpu_device::set_output_pla(*device, _pla);
-#define MCFG_TMS1XXX_READ_K(_devcb) \
- tms1xxx_cpu_device::set_read_k(*device, DEVCB_##_devcb);
+#define MCFG_TMS1XXX_READ_K_CB(_devcb) \
+ tms1xxx_cpu_device::set_read_k_callback(*device, DEVCB_##_devcb);
+
+#define MCFG_TMS1XXX_WRITE_O_CB(_devcb) \
+ tms1xxx_cpu_device::set_write_o_callback(*device, DEVCB_##_devcb);
-#define MCFG_TMS1XXX_WRITE_O(_devcb) \
- tms1xxx_cpu_device::set_write_o(*device, DEVCB_##_devcb);
+#define MCFG_TMS1XXX_WRITE_R_CB(_devcb) \
+ tms1xxx_cpu_device::set_write_r_callback(*device, DEVCB_##_devcb);
-#define MCFG_TMS1XXX_WRITE_R(_devcb) \
- tms1xxx_cpu_device::set_write_r(*device, DEVCB_##_devcb);
+#define MCFG_TMS1XXX_POWER_OFF_CB(_devcb) \
+ tms1xxx_cpu_device::set_power_off_callback(*device, DEVCB_##_devcb);
class tms1xxx_cpu_device : public cpu_device
{
public:
// construction/destruction
- tms1xxx_cpu_device( const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock
- , const UINT32* decode_table, UINT16 o_mask, UINT16 r_mask, UINT8 pc_size, UINT8 byte_size, UINT8 x_bits
- , int program_addrbus_width, address_map_constructor program, int data_addrbus_width, address_map_constructor data, const char *shortname, const char *source)
- : cpu_device( mconfig, type, name, tag, owner, clock, shortname, source)
- , m_program_config("program", ENDIANNESS_BIG, byte_size > 8 ? 16 : 8, program_addrbus_width, 0, program )
- , m_data_config("data", ENDIANNESS_BIG, 8, data_addrbus_width, 0, data )
- , m_pc(0)
- , m_pa(0)
- , m_sr(0)
- , m_pb(0)
- , m_a(0)
- , m_x(0)
- , m_y(0)
- , m_status(0)
- , m_o_mask( o_mask )
- , m_r_mask( r_mask )
- , m_pc_size( pc_size )
- , m_byte_size( byte_size )
- , m_x_bits( x_bits )
- , m_decode_table( decode_table )
- , c_output_pla( NULL )
- , m_read_k( *this )
- , m_write_o( *this )
- , m_write_r( *this )
+ tms1xxx_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 k_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)
+ : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
+ , m_program_config("program", ENDIANNESS_BIG, byte_bits > 8 ? 16 : 8, prgwidth, 0, program)
+ , m_data_config("data", ENDIANNESS_BIG, 8, datawidth, 0, data)
+ , m_mpla(*this, "mpla")
+ , m_ipla(*this, "ipla")
+ , m_opla(*this, "opla")
+ , m_spla(*this, "spla")
+ , m_o_pins(o_pins)
+ , m_r_pins(r_pins)
+ , m_k_pins(k_pins)
+ , m_pc_bits(pc_bits)
+ , m_byte_bits(byte_bits)
+ , m_x_bits(x_bits)
+ , c_output_pla(NULL)
+ , m_read_k(*this)
+ , m_write_o(*this)
+ , m_write_r(*this)
+ , m_power_off(*this)
{ }
// static configuration helpers
- template<class _Object> static devcb_base &set_read_k(device_t &device, _Object object) { return downcast<tms1xxx_cpu_device &>(device).m_read_k.set_callback(object); }
- template<class _Object> static devcb_base &set_write_o(device_t &device, _Object object) { return downcast<tms1xxx_cpu_device &>(device).m_write_o.set_callback(object); }
- template<class _Object> static devcb_base &set_write_r(device_t &device, _Object object) { return downcast<tms1xxx_cpu_device &>(device).m_write_r.set_callback(object); }
+ template<class _Object> static devcb_base &set_read_k_callback(device_t &device, _Object object) { return downcast<tms1xxx_cpu_device &>(device).m_read_k.set_callback(object); }
+ template<class _Object> static devcb_base &set_write_o_callback(device_t &device, _Object object) { return downcast<tms1xxx_cpu_device &>(device).m_write_o.set_callback(object); }
+ template<class _Object> static devcb_base &set_write_r_callback(device_t &device, _Object object) { return downcast<tms1xxx_cpu_device &>(device).m_write_r.set_callback(object); }
+ template<class _Object> static devcb_base &set_power_off_callback(device_t &device, _Object object) { return downcast<tms1xxx_cpu_device &>(device).m_power_off.set_callback(object); }
static void set_output_pla(device_t &device, const UINT16 *output_pla) { downcast<tms1xxx_cpu_device &>(device).c_output_pla = output_pla; }
protected:
@@ -65,62 +69,96 @@ protected:
// device_execute_interface overrides
virtual UINT32 execute_min_cycles() const { return 1; }
- virtual UINT32 execute_max_cycles() const { return 6; }
+ virtual UINT32 execute_max_cycles() const { return 1; }
virtual UINT32 execute_input_lines() const { return 1; }
virtual void execute_run();
// device_memory_interface overrides
- virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_DATA ) ? &m_data_config : NULL ); }
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return(spacenum == AS_PROGRAM) ? &m_program_config :((spacenum == AS_DATA) ? &m_data_config : NULL); }
// device_disasm_interface overrides
virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
virtual UINT32 disasm_max_opcode_bytes() const { return 1; }
void next_pc();
- void set_cki_bus();
+ void execute_fixed_opcode();
+
+ virtual void write_o_output(UINT8 data);
+ virtual UINT8 read_k_input();
+ virtual void set_cki_bus();
+ virtual void read_opcode();
+
+ virtual void op_sbit();
+ virtual void op_rbit();
+ virtual void op_setr();
+ virtual void op_rstr();
+ virtual void op_tdo();
+ virtual void op_clo();
+ virtual void op_ldx();
+ virtual void op_comx();
+ virtual void op_comx8();
+ virtual void op_ldp();
+
+ virtual void op_comc();
+ virtual void op_xda();
+ virtual void op_off();
+ virtual void op_seac();
+ virtual void op_reac();
+ virtual void op_sal();
+ virtual void op_sbl();
address_space_config m_program_config;
address_space_config m_data_config;
- UINT8 m_prev_pc; /* previous program counter */
- UINT8 m_prev_pa; /* previous page address register */
- UINT8 m_pc; /* program counter is a 7 bit register on tms0980, 6 bit register on tms1000/1070/1200/1270/1100/1300 */
- UINT8 m_pa; /* page address register is a 4 bit register */
- UINT8 m_sr; /* subroutine return register is a 7 bit register */
- UINT8 m_pb; /* page buffer register is a 4 bit register */
- UINT8 m_a; /* Accumulator is a 4 bit register (?) */
- UINT8 m_x; /* X-register is a 2, 3, or 4 bit register */
- UINT8 m_y; /* Y-register is a 4 bit register */
- UINT8 m_dam; /* DAM register is a 4 bit register */
- UINT8 m_ca; /* Chapter address bit */
- UINT8 m_cb; /* Chapter buffer bit */
- UINT8 m_cs; /* Chapter subroutine bit */
+ optional_device<pla_device> m_mpla;
+ optional_device<pla_device> m_ipla;
+ optional_device<pla_device> m_opla;
+ optional_device<pla_device> m_spla;
+
+ UINT8 m_pc; // 6 or 7-bit program counter
+ UINT8 m_sr; // 6 or 7-bit subroutine return register
+ UINT8 m_pa; // 4-bit page address register
+ UINT8 m_pb; // 4-bit page buffer register
+ UINT8 m_a; // 4-bit accumulator
+ UINT8 m_x; // 2,3,or 4-bit RAM X register
+ UINT8 m_y; // 4-bit RAM Y register
+ UINT8 m_ca; // chapter address bit
+ UINT8 m_cb; // chapter buffer bit
+ UINT8 m_cs; // chapter subroutine bit
UINT16 m_r;
- UINT8 m_o;
- UINT8 m_cki_bus; /* CKI bus */
- UINT8 m_p; /* adder p-input */
- UINT8 m_n; /* adder n-input */
- UINT8 m_adder_result; /* adder result */
- UINT8 m_carry_in; /* carry in */
+ UINT16 m_o;
+ UINT8 m_cki_bus;
+ UINT8 m_c4;
+ UINT8 m_p; // 4-bit adder p(lus)-input
+ UINT8 m_n; // 4-bit adder n(egative)-input
+ UINT8 m_adder_out; // adder result
+ UINT8 m_carry_in; // adder carry-in bit
+ UINT8 m_carry_out; // adder carry-out bit
UINT8 m_status;
UINT8 m_status_latch;
- UINT8 m_special_status;
- UINT8 m_call_latch;
- UINT8 m_add_latch;
- UINT8 m_branch_latch;
- int m_subcycle;
+ UINT8 m_eac; // end around carry bit
+ UINT8 m_clatch; // call latch bit
+ UINT8 m_add; // add latch bit
+ UINT8 m_bl; // branch latch bit
+
+ UINT8 m_ram_in;
+ UINT8 m_dam_in;
+ int m_ram_out; // signed!
UINT8 m_ram_address;
- UINT16 m_ram_data;
UINT16 m_rom_address;
UINT16 m_opcode;
- UINT32 m_decode;
+ UINT32 m_fixed;
+ UINT32 m_micro;
+ int m_subcycle;
int m_icount;
- UINT16 m_o_mask; /* mask to determine the number of O outputs */
- UINT16 m_r_mask; /* mask to determine the number of R outputs */
- UINT8 m_pc_size; /* how bits in the PC register */
- UINT8 m_byte_size; /* 8 or 9 bit bytes */
- UINT8 m_x_bits; /* determine the number of bits in the X register */
- const UINT32 *m_decode_table;
+
+ UINT8 m_o_pins; // how many O pins
+ UINT8 m_r_pins; // how many R pins
+ UINT8 m_k_pins; // how many K pins
+ UINT8 m_pc_bits; // how many program counter bits
+ UINT8 m_byte_bits; // how many bits per 'byte'
+ UINT8 m_x_bits; // how many X register bits
+
address_space *m_program;
address_space *m_data;
@@ -128,47 +166,38 @@ protected:
devcb_read8 m_read_k;
devcb_write16 m_write_o;
devcb_write16 m_write_r;
-
+ devcb_write_line m_power_off;
+
+ UINT32 m_o_mask;
+ UINT32 m_r_mask;
+ UINT32 m_k_mask;
+ UINT32 m_pc_mask;
+ UINT32 m_x_mask;
+
+ // lookup tables
+ dynamic_array<UINT32> m_fixed_decode;
+ dynamic_array<UINT32> m_micro_decode;
+ dynamic_array<UINT32> m_micro_direct;
};
-class tms0980_cpu_device : public tms1xxx_cpu_device
-{
-public:
- tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-
-protected:
- // device_state_interface overrides
- void state_string_export(const device_state_entry &entry, astring &string);
-
- // device_disasm_interface overrides
- virtual UINT32 disasm_min_opcode_bytes() const { return 2; }
- virtual UINT32 disasm_max_opcode_bytes() const { return 2; }
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
-};
-
class tms1000_cpu_device : public tms1xxx_cpu_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, UINT16 o_mask, UINT16 r_mask, const char *shortname, const char *source);
+ 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 k_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:
- // device_state_interface overrides
+ // overrides
+ virtual void device_reset();
+ virtual machine_config_constructor device_mconfig_additions() const;
+
void state_string_export(const device_state_entry &entry, astring &string);
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
};
-
-class tms0970_cpu_device : public tms1000_cpu_device
-{
-public:
- tms0970_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
class tms1070_cpu_device : public tms1000_cpu_device
{
public:
@@ -183,45 +212,82 @@ public:
};
-class tms1270_cpu_device : public tms1000_cpu_device
+class tms1100_cpu_device : public tms1000_cpu_device
{
public:
- tms1270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ 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 k_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();
+
+ void state_string_export(const device_state_entry &entry, astring &string);
+
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+ virtual void op_setr();
+ virtual void op_rstr();
};
+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 tms1100_cpu_device : public tms1xxx_cpu_device
+
+class tms0970_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, UINT16 o_mask, UINT16 r_mask, const char *shortname, const char *source);
+ 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 k_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:
- // device_state_interface overrides
- void state_string_export(const device_state_entry &entry, astring &string);
+ // overrides
+ virtual void device_reset();
+ virtual machine_config_constructor device_mconfig_additions() const;
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+ virtual void write_o_output(UINT8 data);
+
+ virtual void op_setr();
+ virtual void op_tdo();
};
-class tms1300_cpu_device : public tms1100_cpu_device
+class tms0980_cpu_device : public tms0970_cpu_device
{
public:
- tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // overrides
+ virtual void device_reset();
+
+ void state_string_export(const device_state_entry &entry, astring &string);
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+ virtual UINT32 disasm_min_opcode_bytes() const { return 2; }
+ virtual UINT32 disasm_max_opcode_bytes() const { return 2; }
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+ virtual void set_cki_bus();
+ virtual void read_opcode();
+
+ virtual void op_comx();
+private:
+ UINT32 decode_micro(UINT8 sel);
};
-/* 9-bit family */
-extern const device_type TMS0980;
-/* 8-bit family */
extern const device_type TMS1000;
-extern const device_type TMS0970;
extern const device_type TMS1070;
extern const device_type TMS1200;
-extern const device_type TMS1270;
extern const device_type TMS1100;
extern const device_type TMS1300;
+extern const device_type TMS0970;
+extern const device_type TMS0980;
#endif /* _TMS0980_H_ */
diff --git a/src/mess/drivers/comp4.c b/src/mess/drivers/comp4.c
index 6259553bfa7..707661393ad 100644
--- a/src/mess/drivers/comp4.c
+++ b/src/mess/drivers/comp4.c
@@ -4,24 +4,23 @@
Milton Bradley Comp IV
* TMC0904NL CP0904A (die labeled 4A0970D-04A)
-
+
This is a handheld Mastermind game; a code-breaking game where the player
needs to find out the correct sequence of colours (numbers in our case).
It is known as Logic 5 in Europe, and as Pythaligoras in Japan.
-
+
Press the R key to start, followed by a set of unique numbers and E.
Refer to the official manual for more information.
- TODO:
- - write_r doesn't look right, maybe something missing in cpu emulation
- - layout
-
***************************************************************************/
#include "emu.h"
#include "cpu/tms0980/tms0980.h"
+#include "comp4.lh"
+
+
// master clock is cpu internal, the value below is an approximation
#define MASTER_CLOCK (250000)
@@ -38,6 +37,8 @@ public:
required_device<cpu_device> m_maincpu;
required_ioport_array<3> m_button_matrix;
+ UINT16 m_leds_state;
+ UINT8 m_leds_decay[0x10];
UINT16 m_r;
UINT16 m_o;
@@ -45,12 +46,52 @@ public:
DECLARE_WRITE16_MEMBER(write_o);
DECLARE_WRITE16_MEMBER(write_r);
+ TIMER_DEVICE_CALLBACK_MEMBER(leds_decay_tick);
+ void leds_update();
+
virtual void machine_start();
};
/***************************************************************************
+ LEDs
+
+***************************************************************************/
+
+// The device strobes the outputs very fast, it is unnoticeable to the user.
+// To prevent flickering here, we need to simulate a decay.
+
+// decay time, in steps of 10ms
+#define LEDS_DECAY_TIME 2
+
+void comp4_state::leds_update()
+{
+ for (int i = 0; i < 0x10; i++)
+ {
+ // turn on powered leds
+ if (m_leds_state >> i & 1)
+ m_leds_decay[i] = LEDS_DECAY_TIME;
+
+ // send to output
+ output_set_lamp_value(i, (m_leds_decay[i] != 0) ? 1 : 0);
+ }
+}
+
+TIMER_DEVICE_CALLBACK_MEMBER(comp4_state::leds_decay_tick)
+{
+ // slowly turn off unpowered leds
+ for (int i = 0; i < 0x10; i++)
+ if (!(m_leds_state >> i & 1) && m_leds_decay[i])
+ m_leds_decay[i]--;
+
+ leds_update();
+}
+
+
+
+/***************************************************************************
+
I/O
***************************************************************************/
@@ -63,19 +104,27 @@ READ8_MEMBER(comp4_state::read_k)
for (int i = 0; i < 3; i++)
if (m_o & (1 << (i + 1)))
k |= m_button_matrix[i]->read();
-
+
return k;
}
WRITE16_MEMBER(comp4_state::write_r)
{
- // R..: LEDs
+ // LEDs:
+ // R4 R9
+ // R10! R8
+ // R2 R7
+ // R1 R6
+ // R0 R5
m_r = data;
+
+ m_leds_state = m_r;
+ leds_update();
}
WRITE16_MEMBER(comp4_state::write_o)
{
- // O0?: LEDs (common)
+ // O0: LEDs common (always writes 1)
// O1-O3: input mux
// other bits: N/C
m_o = data;
@@ -90,23 +139,23 @@ WRITE16_MEMBER(comp4_state::write_o)
***************************************************************************/
static INPUT_PORTS_START( comp4 )
- PORT_START("IN.0")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("R")
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
-
- PORT_START("IN.1")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2")
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
-
- PORT_START("IN.2")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("E")
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
+ PORT_START("IN.0") // O1
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("R")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
+
+ PORT_START("IN.1") // O2
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
+
+ PORT_START("IN.2") // O3
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("E")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
INPUT_PORTS_END
@@ -119,32 +168,27 @@ INPUT_PORTS_END
void comp4_state::machine_start()
{
+ m_leds_state = 0;
+ memset(m_leds_decay, 0, sizeof(m_leds_decay));
m_r = 0;
m_o = 0;
-
+
save_item(NAME(m_r));
save_item(NAME(m_o));
}
-static const UINT16 comp4_output_pla[0x20] =
-{
- // many unused bits, only O0 is actually used as external out
- 0xda, 0x96, 0x9b, 0x97, 0x98, 0x94, 0x99, 0x95,
- 0x9a, 0xa0, 0x94, 0x02, 0x35, 0x4a, 0x41, 0x00,
- 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00,
- 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00
-};
-
-
static MACHINE_CONFIG_START( comp4, comp4_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", TMS0970, MASTER_CLOCK)
- MCFG_TMS1XXX_OUTPUT_PLA(comp4_output_pla)
- MCFG_TMS1XXX_READ_K(READ8(comp4_state, read_k))
- MCFG_TMS1XXX_WRITE_O(WRITE16(comp4_state, write_o))
- MCFG_TMS1XXX_WRITE_R(WRITE16(comp4_state, write_r))
+ MCFG_TMS1XXX_READ_K_CB(READ8(comp4_state, read_k))
+ MCFG_TMS1XXX_WRITE_O_CB(WRITE16(comp4_state, write_o))
+ MCFG_TMS1XXX_WRITE_R_CB(WRITE16(comp4_state, write_r))
+
+ MCFG_TIMER_DRIVER_ADD_PERIODIC("leds_decay", comp4_state, leds_decay_tick, attotime::from_msec(10))
+
+ MCFG_DEFAULT_LAYOUT(layout_comp4)
/* no video! */
@@ -161,8 +205,17 @@ MACHINE_CONFIG_END
ROM_START( comp4 )
ROM_REGION( 0x0400, "maincpu", 0 )
- ROM_LOAD( "cp0904a", 0x0000, 0x0400, CRC(c502c8a1) SHA1(f82ff1a85c4849621d32344964d8b2233fc978d0) )
+ ROM_LOAD( "tmc0904nl_cp0904a", 0x0000, 0x0400, CRC(6233ee1b) SHA1(738e109b38c97804b4ec52bed80b00a8634ad453) )
+
+ ROM_REGION( 782, "maincpu:ipla", 0 )
+ ROM_LOAD( "tms0970_default_ipla.pla", 0, 782, CRC(e038fc44) SHA1(dfc280f6d0a5828d1bb14fcd59ac29caf2c2d981) )
+ ROM_REGION( 860, "maincpu:mpla", 0 )
+ ROM_LOAD( "tms0970_comp4_mpla.pla", 0, 860, CRC(ee9d7d9e) SHA1(25484e18f6a07f7cdb21a07220e2f2a82fadfe7b) )
+ ROM_REGION( 352, "maincpu:opla", 0 )
+ ROM_LOAD( "tms0970_comp4_opla.pla", 0, 352, CRC(a0f887d1) SHA1(3c666663d484d5bed81e1014f8715aab8a3d489f) )
+ ROM_REGION( 157, "maincpu:spla", 0 )
+ ROM_LOAD( "tms0970_comp4_spla.pla", 0, 157, CRC(e5bddd90) SHA1(4b1c6512c70e5bcd23c2dbf0c88cd8aa2c632a10) )
ROM_END
-CONS( 1977, comp4, 0, 0, comp4, comp4, driver_device, 0, "Milton Bradley", "Comp IV", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW )
+CONS( 1977, comp4, 0, 0, comp4, comp4, driver_device, 0, "Milton Bradley", "Comp IV", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW )
diff --git a/src/mess/drivers/merlin.c b/src/mess/drivers/merlin.c
index 7934b30c4b8..07eb35dd14f 100644
--- a/src/mess/drivers/merlin.c
+++ b/src/mess/drivers/merlin.c
@@ -1,8 +1,10 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
/***************************************************************************
Parker Bros Merlin handheld computer game
* TMS1100NLL MP3404A-N2 (has internal ROM)
-
+
To start a game, press NEW GAME, followed by a number:
1: Tic-Tac-Toe
2: Music Machine
@@ -10,15 +12,15 @@
4: Blackjack 13
5: Magic Square
6: Mindbender
-
+
Refer to the official manual for more information on the games.
-
-
+
+
Other handhelds assumed to be on similar hardware:
- Dr. Smith - by Tomy, released in Japan (basically a white version of Merlin,
let's assume for now that the ROM contents is identical)
- Master Merlin
-
+
Another sequel, called Split Second, looks like different hardware.
@@ -45,7 +47,7 @@ public:
merlin_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
- m_button_matrix(*this, "O"),
+ m_button_matrix(*this, "IN"),
m_speaker(*this, "speaker")
{ }
@@ -70,33 +72,10 @@ protected:
***************************************************************************/
-/* The keypad is a 4*4 matrix, connected like so:
-
- +----+ +----+ +----+ +----+
-O0 o---| R0 |--| R1 |--| R2 |--| R3 |
- +----+ +----+ +----+ +----+
- | | | |
- +----+ +----+ +----+ +----+
-O1 o---| R4 |--| R5 |--| R6 |--| R7 |
- +----+ +----+ +----+ +----+
- | | | |
- +----+ +----+ +----+ +----+
-O2 o---| R8 |--| R9 |--|R10 |--| SG |
- +----+ +----+ +----+ +----+
- | | | |
- | +----+ +----+ +----+
-O3 o------+----| CT |--| NG |--| HM |
- | +----+ +----+ +----+
- | | | |
- o o o o
- K1 K2 K8 K4
-
-SG = same game, CT = comp turn, NG = new game, HM = hit me */
-
READ8_MEMBER(merlin_state::read_k)
{
UINT8 k = 0;
-
+
// read selected button rows
for (int i = 0; i < 4; i++)
if (m_o & (1 << i))
@@ -143,29 +122,29 @@ WRITE16_MEMBER(merlin_state::write_r)
***************************************************************************/
static INPUT_PORTS_START( merlin )
- PORT_START("O.0")
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_SLASH_PAD) PORT_NAME("Button 0")
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("Button 1")
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Button 3")
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Button 2")
-
- PORT_START("O.1")
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Button 4")
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Button 5")
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Button 7")
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Button 6")
-
- PORT_START("O.2")
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Button 8")
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Button 9")
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_S) PORT_NAME("Same Game")
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_MINUS) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Button 10")
-
- PORT_START("O.3")
+ PORT_START("IN.0") // O0
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_SLASH_PAD) PORT_NAME("Button 0")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("Button 1")
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Button 3")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Button 2")
+
+ PORT_START("IN.1") // O1
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Button 4")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Button 5")
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON8) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Button 7")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Button 6")
+
+ PORT_START("IN.2") // O2
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON9) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Button 8")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON10) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Button 9")
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON12) PORT_CODE(KEYCODE_S) PORT_NAME("Same Game")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON11) PORT_CODE(KEYCODE_MINUS) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Button 10")
+
+ PORT_START("IN.3") // O3
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED)
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_C) PORT_NAME("Comp Turn")
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_H) PORT_NAME("Hit Me")
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_N) PORT_NAME("New Game")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON13) PORT_CODE(KEYCODE_C) PORT_NAME("Comp Turn")
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON15) PORT_CODE(KEYCODE_H) PORT_NAME("Hit Me")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON14) PORT_CODE(KEYCODE_N) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("New Game")
INPUT_PORTS_END
@@ -200,9 +179,9 @@ static MACHINE_CONFIG_START( merlin, merlin_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", TMS1100, MERLIN_RC_CLOCK)
MCFG_TMS1XXX_OUTPUT_PLA(merlin_output_pla)
- MCFG_TMS1XXX_READ_K(READ8( merlin_state, read_k))
- MCFG_TMS1XXX_WRITE_O(WRITE16( merlin_state, write_o))
- MCFG_TMS1XXX_WRITE_R(WRITE16( merlin_state, write_r))
+ MCFG_TMS1XXX_READ_K_CB(READ8( merlin_state, read_k))
+ MCFG_TMS1XXX_WRITE_O_CB(WRITE16( merlin_state, write_o))
+ MCFG_TMS1XXX_WRITE_R_CB(WRITE16( merlin_state, write_r))
MCFG_DEFAULT_LAYOUT(layout_merlin)
@@ -230,6 +209,11 @@ ROM_START( merlin )
// 0x5E to 0x1E to make 'Music Machine' working.
// The hashes below are from the manually changed dump
ROM_LOAD( "mp3404", 0x0000, 0x800, BAD_DUMP CRC(7515a75d) SHA1(76ca3605d3fde1df62f79b9bb1f534c2a2ae0229) )
+
+ ROM_REGION( 867, "maincpu:mpla", 0 )
+ ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, BAD_DUMP CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) ) // not verified
+ ROM_REGION( 365, "maincpu:opla", 0 )
+ ROM_LOAD( "tms1100_merlin_opla.pla", 0, 365, NO_DUMP )
ROM_END
diff --git a/src/mess/drivers/microvsn.c b/src/mess/drivers/microvsn.c
index 6b73f81c454..0660179bbe4 100644
--- a/src/mess/drivers/microvsn.c
+++ b/src/mess/drivers/microvsn.c
@@ -655,9 +655,9 @@ static MACHINE_CONFIG_START( microvision, microvision_state )
MCFG_CPU_IO_MAP( microvision_8021_io )
MCFG_CPU_ADD("maincpu2", TMS1100, 500000) // most games seem to be running at approximately this speed
MCFG_TMS1XXX_OUTPUT_PLA( microvision_output_pla_0 )
- MCFG_TMS1XXX_READ_K( READ8( microvision_state, tms1100_read_k ) )
- MCFG_TMS1XXX_WRITE_O( WRITE16( microvision_state, tms1100_write_o ) )
- MCFG_TMS1XXX_WRITE_R( WRITE16( microvision_state, tms1100_write_r ) )
+ MCFG_TMS1XXX_READ_K_CB( READ8( microvision_state, tms1100_read_k ) )
+ MCFG_TMS1XXX_WRITE_O_CB( WRITE16( microvision_state, tms1100_write_o ) )
+ MCFG_TMS1XXX_WRITE_R_CB( WRITE16( microvision_state, tms1100_write_r ) )
MCFG_SCREEN_ADD("screen", LCD)
MCFG_SCREEN_REFRESH_RATE(60)
@@ -695,6 +695,8 @@ MACHINE_CONFIG_END
ROM_START( microvsn )
ROM_REGION( 0x800, "maincpu1", ROMREGION_ERASE00 )
ROM_REGION( 0x800, "maincpu2", ROMREGION_ERASE00 )
+ ROM_REGION( 867, "maincpu2:mpla", ROMREGION_ERASE00 )
+ ROM_REGION( 365, "maincpu2:opla", ROMREGION_ERASE00 )
ROM_END
diff --git a/src/mess/drivers/simon.c b/src/mess/drivers/simon.c
index 48d1d4b2545..eb3a0d6d63f 100644
--- a/src/mess/drivers/simon.c
+++ b/src/mess/drivers/simon.c
@@ -3,14 +3,14 @@
/***************************************************************************
Milton Bradley Simon
-
+
Revision A hardware:
* TMS1000 (has internal ROM), DS75494 lamp driver
-
+
Newer revisions have a smaller 16-pin MB4850 chip instead of the TMS1000.
This one has been decapped too, but we couldn't find an internal ROM.
It is possibly a cost-reduced custom ASIC specifically for Simon.
-
+
Other games assumed to be on similar hardware:
- Pocket Simon, but there's a chance it only exists with MB4850 chip
- Super Simon (TMS1100)
@@ -61,11 +61,11 @@ public:
READ8_MEMBER(simon_state::read_k)
{
UINT8 k = 0;
-
+
// read selected button rows
for (int i = 0; i < 4; i++)
{
- static int r[4] = { 0, 1, 2, 9 };
+ const int r[4] = { 0, 1, 2, 9 };
if (m_r & (1 << r[i]))
k |= m_button_matrix[i]->read();
}
@@ -82,7 +82,7 @@ WRITE16_MEMBER(simon_state::write_r)
// R7 -> 75494 IN2 -> blue lamp
for (int i = 0; i < 4; i++)
output_set_lamp_value(i, data >> (4 + i) & 1);
-
+
// R8 -> 75494 IN0 -> speaker
m_speaker->level_w(data >> 8 & 1);
@@ -106,26 +106,26 @@ WRITE16_MEMBER(simon_state::write_o)
***************************************************************************/
static INPUT_PORTS_START( simon )
- PORT_START("IN.0")
+ PORT_START("IN.0") // R0
PORT_CONFNAME( 0x07, 0x02, "Game Select")
PORT_CONFSETTING( 0x02, "1" )
PORT_CONFSETTING( 0x01, "2" )
PORT_CONFSETTING( 0x04, "3" )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
- PORT_START("IN.1")
+ PORT_START("IN.1") // R1
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Green Button")
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Red Button")
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("Yellow Button")
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_NAME("Blue Button")
- PORT_START("IN.2")
+ PORT_START("IN.2") // R2
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("Start")
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Last")
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Longest")
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
- PORT_START("IN.3")
+ PORT_START("IN.3") // R9
PORT_CONFNAME( 0x0f, 0x01, "Skill Level")
PORT_CONFSETTING( 0x02, "1" )
PORT_CONFSETTING( 0x04, "2" )
@@ -148,24 +148,13 @@ void simon_state::machine_start()
}
-static const UINT16 simon_output_pla[0x20] =
-{
- /* The output PLA just maps 1 2 4 8 and SL to O0-O4 */
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
-};
-
-
static MACHINE_CONFIG_START( simon, simon_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", TMS1000, SIMON_RC_CLOCK)
- MCFG_TMS1XXX_OUTPUT_PLA(simon_output_pla)
- MCFG_TMS1XXX_READ_K(READ8(simon_state, read_k))
- MCFG_TMS1XXX_WRITE_O(WRITE16(simon_state, write_o))
- MCFG_TMS1XXX_WRITE_R(WRITE16(simon_state, write_r))
+ MCFG_TMS1XXX_READ_K_CB(READ8(simon_state, read_k))
+ MCFG_TMS1XXX_WRITE_O_CB(WRITE16(simon_state, write_o))
+ MCFG_TMS1XXX_WRITE_R_CB(WRITE16(simon_state, write_r))
MCFG_DEFAULT_LAYOUT(layout_simon)
@@ -188,6 +177,11 @@ MACHINE_CONFIG_END
ROM_START( simon )
ROM_REGION( 0x0400, "maincpu", 0 )
ROM_LOAD( "tms1000.u1", 0x0000, 0x0400, CRC(9961719d) SHA1(35dddb018a8a2b31f377ab49c1f0cb76951b81c0) )
+
+ ROM_REGION( 867, "maincpu:mpla", 0 )
+ ROM_LOAD( "tms1000_simon_mpla.pla", 0, 867, CRC(52f7c1f1) SHA1(dbc2634dcb98eac173ad0209df487cad413d08a5) )
+ ROM_REGION( 365, "maincpu:opla", 0 )
+ ROM_LOAD( "tms1000_simon_opla.pla", 0, 365, CRC(2943c71b) SHA1(bd5bb55c57e7ba27e49c645937ec1d4e67506601) )
ROM_END
diff --git a/src/mess/drivers/stopthie.c b/src/mess/drivers/stopthie.c
index b462d2c17c3..32eceb1350b 100644
--- a/src/mess/drivers/stopthie.c
+++ b/src/mess/drivers/stopthie.c
@@ -51,24 +51,16 @@ WRITE16_MEMBER(stopthie_state::stopthie_write_r)
}
-static const UINT16 stopthie_output_pla[0x20] =
-{
- /* O output PLA configuration currently unknown */
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
-};
+
static MACHINE_CONFIG_START( stopthie, stopthie_state )
/* basic machine hardware */
MCFG_CPU_ADD( "maincpu", TMS0980, 500000 ) /* Clock is wrong */
- MCFG_TMS1XXX_OUTPUT_PLA( stopthie_output_pla )
- MCFG_TMS1XXX_READ_K( READ8( stopthie_state, stopthie_read_k ) )
- MCFG_TMS1XXX_WRITE_O( WRITE16( stopthie_state, stopthie_write_o ) )
- MCFG_TMS1XXX_WRITE_R( WRITE16( stopthie_state, stopthie_write_r ) )
+ MCFG_TMS1XXX_READ_K_CB( READ8( stopthie_state, stopthie_read_k ) )
+ MCFG_TMS1XXX_WRITE_O_CB( WRITE16( stopthie_state, stopthie_write_o ) )
+ MCFG_TMS1XXX_WRITE_R_CB( WRITE16( stopthie_state, stopthie_write_r ) )
MCFG_DEFAULT_LAYOUT(layout_stopthie)
MACHINE_CONFIG_END
@@ -76,6 +68,11 @@ MACHINE_CONFIG_END
ROM_START( stopthie )
ROM_REGION( 0x1000, "maincpu", 0 )
ROM_LOAD16_WORD( "stopthie.bin", 0x0000, 0x1000, CRC(03691115) SHA1(bdcd212aa50bb1c26cb2d0ee97e5cfc04841c108) )
+
+ ROM_REGION( 1246, "maincpu:ipla", 0 )
+ ROM_REGION( 1982, "maincpu:mpla", 0 )
+ ROM_REGION( 352, "maincpu:opla", 0 )
+ ROM_REGION( 157, "maincpu:spla", 0 )
ROM_END
/***************************************************************************
diff --git a/src/mess/drivers/ticalc1x.c b/src/mess/drivers/ticalc1x.c
index 2b5ad7adcda..6bf481f10da 100644
--- a/src/mess/drivers/ticalc1x.c
+++ b/src/mess/drivers/ticalc1x.c
@@ -2,26 +2,25 @@
// copyright-holders:hap
/***************************************************************************
- Texas Instruments TMS1xxx/0970/0980 handheld calculators
-
- Texas Instruments WIZ-A-TRON
- * TMC0907NL DP0907BS (die labeled 0970F-07B)
-
- Other handhelds assumed to be on similar hardware:
- - Math Magic
- - Little Professor
-
+ Texas Instruments TMS1xxx/0970/0980 handheld calculators (mostly single-chip)
+
+ Refer to their official manuals on how to use them.
+
TODO:
- - the rom goes in an infinite loop very soon, cpu missing emulation?
+ - ON/OFF button callbacks, and support OFF callback from the 0980
+ - CPU clocks are unknown
+
***************************************************************************/
#include "emu.h"
#include "cpu/tms0980/tms0980.h"
-// master clock is cpu internal, the value below is an approximation
-#define MASTER_CLOCK (250000)
+#include "ti1270.lh"
+#include "ti30.lh"
+#include "tisr16.lh"
+#include "wizatron.lh"
class ticalc1x_state : public driver_device
@@ -34,26 +33,181 @@ public:
{ }
required_device<cpu_device> m_maincpu;
- required_ioport_array<4> m_button_matrix;
+ optional_ioport_array<11> m_button_matrix; // up to 11 rows
UINT16 m_r;
UINT16 m_o;
- DECLARE_READ8_MEMBER(read_k);
- DECLARE_WRITE16_MEMBER(write_o);
- DECLARE_WRITE16_MEMBER(write_r);
+ UINT16 m_leds_state[0x10];
+ UINT16 m_leds_cache[0x10];
+ UINT8 m_leds_decay[0x100];
+
+ DECLARE_READ8_MEMBER(tisr16_read_k);
+ DECLARE_WRITE16_MEMBER(tisr16_write_o);
+ DECLARE_WRITE16_MEMBER(tisr16_write_r);
+ void tisr16_leds_update();
+
+ DECLARE_READ8_MEMBER(ti1270_read_k);
+ DECLARE_WRITE16_MEMBER(ti1270_write_o);
+ DECLARE_WRITE16_MEMBER(ti1270_write_r);
+
+ DECLARE_READ8_MEMBER(wizatron_read_k);
+ DECLARE_WRITE16_MEMBER(wizatron_write_o);
+ DECLARE_WRITE16_MEMBER(wizatron_write_r);
+
+ DECLARE_READ8_MEMBER(ti30_read_k);
+ DECLARE_WRITE16_MEMBER(ti30_write_o);
+ DECLARE_WRITE16_MEMBER(ti30_write_r);
+
+ TIMER_DEVICE_CALLBACK_MEMBER(leds_decay_tick);
+ void leds_update();
virtual void machine_start();
};
+
+/***************************************************************************
+
+ LEDs
+
+***************************************************************************/
+
+// Devices with TMS09x0 strobe the outputs very fast, it is unnoticeable to the user.
+// To prevent flickering here, we need to simulate a decay.
+
+// decay time, in steps of 10ms
+#define LEDS_DECAY_TIME 4
+
+void ticalc1x_state::leds_update()
+{
+ UINT16 active_state[0x10];
+
+ for (int i = 0; i < 0x10; i++)
+ {
+ active_state[i] = 0;
+
+ for (int j = 0; j < 0x10; j++)
+ {
+ int di = j << 4 | i;
+
+ // turn on powered leds
+ if (m_leds_state[i] >> j & 1)
+ m_leds_decay[di] = LEDS_DECAY_TIME;
+
+ // determine active state
+ int ds = (m_leds_decay[di] != 0) ? 1 : 0;
+ active_state[i] |= (ds << j);
+ }
+ }
+
+ // on difference, send to output
+ for (int i = 0; i < 0x10; i++)
+ if (m_leds_cache[i] != active_state[i])
+ output_set_digit_value(i, active_state[i]);
+
+ memcpy(m_leds_cache, active_state, sizeof(m_leds_cache));
+}
+
+TIMER_DEVICE_CALLBACK_MEMBER(ticalc1x_state::leds_decay_tick)
+{
+ // slowly turn off unpowered leds
+ for (int i = 0; i < 0x100; i++)
+ if (!(m_leds_state[i & 0xf] >> (i>>4) & 1) && m_leds_decay[i])
+ m_leds_decay[i]--;
+
+ leds_update();
+}
+
+
+
/***************************************************************************
I/O
***************************************************************************/
-READ8_MEMBER(ticalc1x_state::read_k)
+// TMS1000 - SR-16
+
+void ticalc1x_state::tisr16_leds_update()
+{
+ // update leds state
+ for (int i = 0; i < 11; i++)
+ if (m_r >> i & 1)
+ m_leds_state[i] = m_o;
+
+ // exponent sign
+ m_leds_state[11] = (m_leds_state[0] | m_leds_state[1]) ? 0x40 : 0;
+
+ // send to output
+ for (int i = 0; i < 12; i++)
+ output_set_digit_value(i, m_leds_state[i]);
+}
+
+READ8_MEMBER(ticalc1x_state::tisr16_read_k)
+{
+ UINT8 k = 0;
+
+ // read selected button rows
+ for (int i = 0; i < 11; i++)
+ if (m_r & (1 << i))
+ k |= m_button_matrix[i]->read();
+
+ return k;
+}
+
+WRITE16_MEMBER(ticalc1x_state::tisr16_write_r)
+{
+ // R0-R10: input mux
+ // R0-R10: select digit (right-to-left)
+ m_r = data;
+
+ tisr16_leds_update();
+}
+
+WRITE16_MEMBER(ticalc1x_state::tisr16_write_o)
+{
+ // O0-O7: digit segments
+ m_o = data;
+
+ tisr16_leds_update();
+}
+
+
+// TMS0970 - TI-1270
+
+READ8_MEMBER(ticalc1x_state::ti1270_read_k)
+{
+ UINT8 k = 0;
+
+ // read selected button rows
+ for (int i = 0; i < 7; i++)
+ if (m_o & (1 << (i + 1)))
+ k |= m_button_matrix[i]->read();
+
+ return k;
+}
+
+WRITE16_MEMBER(ticalc1x_state::ti1270_write_r)
+{
+ // R0-R7: select digit (right-to-left)
+ for (int i = 0; i < 8; i++)
+ m_leds_state[i] = (data >> i & 1) ? m_o : 0;
+
+ leds_update();
+}
+
+WRITE16_MEMBER(ticalc1x_state::ti1270_write_o)
+{
+ // O1-O5,O7: input mux
+ // O0-O7: digit segments
+ m_o = data;
+}
+
+
+// TMS0970 - WIZ-A-TRON (educational toy)
+
+READ8_MEMBER(ticalc1x_state::wizatron_read_k)
{
UINT8 k = 0;
@@ -65,16 +219,63 @@ READ8_MEMBER(ticalc1x_state::read_k)
return k;
}
-WRITE16_MEMBER(ticalc1x_state::write_r)
+WRITE16_MEMBER(ticalc1x_state::wizatron_write_r)
{
- // R..: select digit
- m_r = data;
+ // R0-R8: select digit (right-to-left)
+ for (int i = 0; i < 9; i++)
+ m_leds_state[i] = (data >> i & 1) ? m_o : 0;
+
+ // 3rd digit has more segments, for math symbols
+ // let's assume it's a 14-seg led
+ m_leds_state[6] = BITSWAP16(m_leds_state[6],15,14,2,1,6,4,3,0,5,5,11,10,9,13,12,8);
+
+ // 6th digit only has A and G for =
+ m_leds_state[3] &= 0x41;
+
+ leds_update();
}
-WRITE16_MEMBER(ticalc1x_state::write_o)
+WRITE16_MEMBER(ticalc1x_state::wizatron_write_o)
{
- // O0-O6: digit segments A-G
// O1-O4: input mux
+ // O0-O6: digit segments A-G
+ // O7: N/C
+ m_o = data & 0x7f;
+}
+
+
+// TMS0980 - TI-30, TI Programmer, TI Business Analyst-I
+
+READ8_MEMBER(ticalc1x_state::ti30_read_k)
+{
+ // the top row is always on
+ UINT8 k = m_button_matrix[8]->read();
+
+ // read selected button rows
+ for (int i = 0; i < 8; i++)
+ if (m_o & (1 << i))
+ k |= m_button_matrix[i]->read();
+
+ return k;
+}
+
+WRITE16_MEMBER(ticalc1x_state::ti30_write_r)
+{
+ // R0-R8: select digit
+ UINT8 o = BITSWAP8(m_o,7,5,2,1,4,0,6,3);
+ for (int i = 0; i < 9; i++)
+ m_leds_state[i] = (data >> i & 1) ? o : 0;
+
+ // 1st digit only has segments B,F,G,DP
+ m_leds_state[0] &= 0xe2;
+
+ leds_update();
+}
+
+WRITE16_MEMBER(ticalc1x_state::ti30_write_o)
+{
+ // O1-O5,O7: input mux
+ // O0-O7: digit segments
m_o = data;
}
@@ -86,42 +287,346 @@ WRITE16_MEMBER(ticalc1x_state::write_o)
***************************************************************************/
+static INPUT_PORTS_START( tisr16 )
+ PORT_START("IN.0") // R0
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("-")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_NAME("RCL")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
+
+ PORT_START("IN.1") // R1
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("+")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_NAME("CE")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
+
+ PORT_START("IN.2") // R2
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ASTERISK) PORT_NAME(UTF8_MULTIPLY)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_NAME("+/-")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2")
+
+ PORT_START("IN.3") // R3
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH_PAD) PORT_NAME(UTF8_DIVIDE)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_NAME(".")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
+
+ PORT_START("IN.4") // R4
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("=")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_NAME("EE")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
+
+ PORT_START("IN.5") // R5
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_NAME(UTF8_CAPITAL_SIGMA)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_NAME("STO")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
+
+ PORT_START("IN.6") // R6
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_NAME("1/x")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_NAME("y"UTF8_POW_X)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
+
+ PORT_START("IN.7") // R7
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_NAME("x"UTF8_POW_2)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
+
+ PORT_START("IN.8") // R8
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_NAME("10"UTF8_POW_X)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_NAME("e"UTF8_POW_X)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
+
+ PORT_START("IN.9") // R9
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_NAME(UTF8_SQUAREROOT"x")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
+
+ PORT_START("IN.10") // R10
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("C")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_NAME("log")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_NAME("ln(x)")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
+INPUT_PORTS_END
+
+
+static INPUT_PORTS_START( ti1270 )
+ PORT_START("IN.0") // O1
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_NAME("CE/C")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_NAME("0")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_NAME(".")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_NAME("=")
+
+ PORT_START("IN.1") // O2
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_NAME("1")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_NAME("2")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_NAME("3")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_NAME("+")
+
+ PORT_START("IN.2") // O3
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_NAME("4")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_NAME("5")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_NAME("6")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_NAME("-")
+
+ PORT_START("IN.3") // O4
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_NAME("7")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_NAME("8")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_NAME("9")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_NAME(UTF8_MULTIPLY)
+
+ PORT_START("IN.4") // O5
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_NAME("STO")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_NAME("RCL")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_NAME(UTF8_SMALL_PI)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_NAME(UTF8_DIVIDE)
+
+ PORT_START("IN.5") // O6
+ PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("IN.6") // O7
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_NAME("1/x")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_NAME("x"UTF8_POW_2)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_NAME(UTF8_SQUAREROOT"x")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_NAME("+/-")
+INPUT_PORTS_END
+
+
static INPUT_PORTS_START( wizatron )
- PORT_START("IN.0")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 )
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 )
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 )
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 )
-
- PORT_START("IN.1")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER )
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER )
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER )
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER )
-
- PORT_START("IN.2")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER )
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER )
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER )
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER )
-
- PORT_START("IN.3")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER )
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER )
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER )
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER )
+ PORT_START("IN.0") // O1
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("CLEAR")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("=")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("+")
+
+ PORT_START("IN.1") // O2
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("-")
+
+ PORT_START("IN.2") // O3
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ASTERISK) PORT_NAME(UTF8_MULTIPLY)
+
+ PORT_START("IN.3") // O4
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH_PAD) PORT_NAME(UTF8_DIVIDE)
+INPUT_PORTS_END
+
+
+static INPUT_PORTS_START( ti30 )
+ PORT_START("IN.0") // O0
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_NAME("y"UTF8_POW_X)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_NAME("K")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_NAME("log")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_NAME("EE"UTF8_DOWN)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("ln(x)")
+
+ PORT_START("IN.1") // O1
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_NAME(UTF8_MULTIPLY)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_NAME("STO")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_NAME("8")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_NAME("7")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
+
+ PORT_START("IN.2") // O2
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_NAME("-")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_NAME("RCL")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_NAME("5")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_NAME("4")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
+
+ PORT_START("IN.3") // O3
+ PORT_BIT( 0x1f, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("IN.4") // O4
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_NAME(UTF8_DIVIDE)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_NAME(UTF8_SMALL_PI)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_NAME("(")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_NAME("%")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_NAME(")")
+
+ PORT_START("IN.5") // O5
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_NAME("+")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_NAME("SUM")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_NAME("2")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_NAME("1")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
+
+ PORT_START("IN.6") // O6
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_NAME("DRG")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_NAME("INV")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_NAME("cos")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_NAME("sin")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("tan")
+
+ PORT_START("IN.7") // O7
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_NAME("=")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_NAME("EXC")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_NAME(".")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_NAME("0")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("+/-")
+
+ // note: even though power buttons are on the matrix, they are not CPU-controlled
+ PORT_START("IN.8") // Vss!
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_NAME("ON/C")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_NAME("1/x")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_NAME(UTF8_SQUAREROOT"x")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_NAME("x"UTF8_POW_2)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("OFF")
+INPUT_PORTS_END
+
+
+static INPUT_PORTS_START( tiprog )
+ PORT_START("IN.0") // O0
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_NAME("K")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_NAME("SHF")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_NAME("E")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_NAME("d")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("F")
+
+ PORT_START("IN.1") // O1
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_NAME(UTF8_MULTIPLY)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_NAME("OR")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_NAME("8")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_NAME("7")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
+
+ PORT_START("IN.2") // O2
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_NAME("-")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_NAME("AND")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_NAME("5")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_NAME("4")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
+
+ PORT_START("IN.3") // O3
+ PORT_BIT( 0x1f, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("IN.4") // O4
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_NAME(UTF8_DIVIDE)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_NAME("1'sC")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_NAME("b")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_NAME("A")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("C")
+
+ PORT_START("IN.5") // O5
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_NAME("+")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_NAME("XOR")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_NAME("2")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_NAME("1")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
+
+ PORT_START("IN.6") // O6
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_NAME(")")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_NAME("STO")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_NAME("SUM")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_NAME("RCL")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("(")
+
+ PORT_START("IN.7") // O7
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_NAME("=")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_NAME("CE")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_NAME(".")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_NAME("0")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("+/-")
+
+ // note: even though power buttons are on the matrix, they are not CPU-controlled
+ PORT_START("IN.8") // Vss!
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_NAME("C/ON")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_NAME("DEC")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_NAME("OCT")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_NAME("HEX")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("OFF")
+INPUT_PORTS_END
+
+
+static INPUT_PORTS_START( tibusan1 )
+ // PORT_NAME lists functions under [2nd] as secondaries.
+ PORT_START("IN.0") // O0
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_NAME("y"UTF8_POW_X" "UTF8_POW_X""UTF8_SQUAREROOT"y") // 2nd one implies xth root of y
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_NAME("% "UTF8_CAPITAL_DELTA"%")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_NAME("SEL")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_NAME("CST")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("MAR")
+
+ PORT_START("IN.1") // O1
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_NAME(UTF8_MULTIPLY)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_NAME("STO m")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_NAME("8")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_NAME("7")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
+
+ PORT_START("IN.2") // O2
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_NAME("-")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_NAME("RCL b")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_NAME("5")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_NAME("4")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
+
+ PORT_START("IN.3") // O3
+ PORT_BIT( 0x1f, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("IN.4") // O4
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_NAME(UTF8_DIVIDE)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_NAME(UTF8_CAPITAL_SIGMA"+ "UTF8_CAPITAL_SIGMA"-")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_NAME("( AN-CI\"")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_NAME("x<>y L.R.")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_NAME(") 1/x")
+
+ PORT_START("IN.5") // O5
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_NAME("+")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_NAME("SUM x"UTF8_PRIME)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_NAME("2")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_NAME("1")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
+
+ PORT_START("IN.6") // O6
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_NAME("FV")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_NAME("N")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_NAME("PMT")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_NAME("%i")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("PV")
+
+ PORT_START("IN.7") // O7
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_NAME("=")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_NAME("EXC x"UTF8_PRIME)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_NAME(".")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_NAME("0")
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("+/-")
+
+ // note: even though power buttons are on the matrix, they are not CPU-controlled
+ PORT_START("IN.8") // Vss!
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_NAME("ON/C")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_NAME("2nd")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_NAME("x"UTF8_POW_2" "UTF8_SQUAREROOT"x")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_NAME("ln(x) e"UTF8_POW_X)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("OFF")
INPUT_PORTS_END
/***************************************************************************
- Machine Config
+ Machine Config(s)
***************************************************************************/
void ticalc1x_state::machine_start()
{
+ memset(m_leds_state, 0, sizeof(m_leds_state));
+ memset(m_leds_cache, 0, sizeof(m_leds_cache));
+ memset(m_leds_decay, 0, sizeof(m_leds_decay));
m_r = 0;
m_o = 0;
@@ -130,30 +635,62 @@ void ticalc1x_state::machine_start()
}
-static const UINT16 wizatron_output_pla[0x20] =
-{
- // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +, -, X, /, r
- 0x7e, 0x30, 0x6d, 0x79, 0x33, 0x5b, 0x5f, 0x70,
- 0x7f, 0x7b, 0x26, 0x02, 0x35, 0x4a, 0x05, 0x00,
- 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00,
- 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00
-};
+static MACHINE_CONFIG_START( tisr16, ticalc1x_state )
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", TMS1000, 250000)
+ MCFG_TMS1XXX_READ_K_CB(READ8(ticalc1x_state, tisr16_read_k))
+ MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, tisr16_write_o))
+ MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, tisr16_write_r))
-static MACHINE_CONFIG_START( wizatron, ticalc1x_state )
+ MCFG_DEFAULT_LAYOUT(layout_tisr16)
+MACHINE_CONFIG_END
+
+
+static MACHINE_CONFIG_START( t9base, ticalc1x_state )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", TMS0970, MASTER_CLOCK)
- MCFG_TMS1XXX_OUTPUT_PLA(wizatron_output_pla)
- MCFG_TMS1XXX_READ_K(READ8(ticalc1x_state, read_k))
- MCFG_TMS1XXX_WRITE_O(WRITE16(ticalc1x_state, write_o))
- MCFG_TMS1XXX_WRITE_R(WRITE16(ticalc1x_state, write_r))
+ MCFG_TIMER_DRIVER_ADD_PERIODIC("leds_decay", ticalc1x_state, leds_decay_tick, attotime::from_msec(10))
/* no video! */
/* no sound! */
MACHINE_CONFIG_END
+static MACHINE_CONFIG_DERIVED( ti1270, t9base )
+
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", TMS0970, 250000)
+ MCFG_TMS1XXX_READ_K_CB(READ8(ticalc1x_state, ti1270_read_k))
+ MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, ti1270_write_o))
+ MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, ti1270_write_r))
+
+ MCFG_DEFAULT_LAYOUT(layout_ti1270)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( wizatron, t9base )
+
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", TMS0970, 250000)
+ MCFG_TMS1XXX_READ_K_CB(READ8(ticalc1x_state, wizatron_read_k))
+ MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, wizatron_write_o))
+ MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, wizatron_write_r))
+
+ MCFG_DEFAULT_LAYOUT(layout_wizatron)
+MACHINE_CONFIG_END
+
+
+static MACHINE_CONFIG_DERIVED( ti30, t9base )
+
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", TMS0980, 250000)
+ MCFG_TMS1XXX_READ_K_CB(READ8(ticalc1x_state, ti30_read_k))
+ MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, ti30_write_o))
+ MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, ti30_write_r))
+
+ MCFG_DEFAULT_LAYOUT(layout_ti30)
+MACHINE_CONFIG_END
+
/***************************************************************************
@@ -162,10 +699,93 @@ MACHINE_CONFIG_END
***************************************************************************/
+ROM_START( tisr16 )
+ ROM_REGION( 0x0400, "maincpu", 0 )
+ ROM_LOAD( "tms1001nl", 0x0000, 0x0400, CRC(b7ce3c1d) SHA1(95cdb0c6be31043f4fe06314ed41c0ca1337bc46) )
+
+ ROM_REGION( 867, "maincpu:mpla", 0 )
+ ROM_LOAD( "tms1000_sr16_mpla.pla", 0, 867, CRC(5b35019c) SHA1(730d3b9041ed76d57fbedd73b009477fe432b386) )
+ ROM_REGION( 365, "maincpu:opla", 0 )
+ ROM_LOAD( "tms1000_sr16_opla.pla", 0, 365, CRC(29b08739) SHA1(d55f01e40a2d493d45ea422f12e63b01bcde08fb) )
+ROM_END
+
+ROM_START( ti1270 )
+ ROM_REGION( 0x0400, "maincpu", 0 )
+ ROM_LOAD( "tms0974nl", 0x0000, 0x0400, CRC(48e09b4b) SHA1(17f27167164df223f9f06082ece4c3fc3900eda3) )
+
+ ROM_REGION( 782, "maincpu:ipla", 0 )
+ ROM_LOAD( "tms0970_ti1270_ipla.pla", 0, 782, CRC(05306ef8) SHA1(60a0a3c49ce330bce0c27f15f81d61461d0432ce) )
+ ROM_REGION( 860, "maincpu:mpla", 0 )
+ ROM_LOAD( "tms0970_ti1270_mpla.pla", 0, 860, CRC(6ff5d51d) SHA1(59d3e5de290ba57694068ddba78d21a0c1edf427) )
+ ROM_REGION( 352, "maincpu:opla", 0 )
+ ROM_LOAD( "tms0970_ti1270_opla.pla", 0, 352, CRC(f39bf0a4) SHA1(160341490043eb369720d5f487cf0f59f458a93e) )
+ ROM_REGION( 157, "maincpu:spla", 0 )
+ ROM_LOAD( "tms0970_ti1270_spla.pla", 0, 157, CRC(56c37a4f) SHA1(18ecc20d2666e89673739056483aed5a261ae927) )
+ROM_END
+
ROM_START( wizatron )
ROM_REGION( 0x0400, "maincpu", 0 )
ROM_LOAD( "dp0907bs", 0x0000, 0x0400, CRC(5a6af094) SHA1(b1f27e1f13f4db3b052dd50fb08dbf9c4d8db26e) )
+
+ ROM_REGION( 782, "maincpu:ipla", 0 )
+ ROM_LOAD( "tms0970_wizatron_ipla.pla", 0, 782, CRC(05306ef8) SHA1(60a0a3c49ce330bce0c27f15f81d61461d0432ce) )
+ ROM_REGION( 860, "maincpu:mpla", 0 )
+ ROM_LOAD( "tms0970_wizatron_mpla.pla", 0, 860, CRC(7f50ab2e) SHA1(bff3be9af0e322986f6e545b567c97d70e135c93) )
+ ROM_REGION( 352, "maincpu:opla", 0 )
+ ROM_LOAD( "tms0970_wizatron_opla.pla", 0, 352, CRC(745a3900) SHA1(031b55a0cf783c8a88eec4289d4373eb8538f374) )
+ ROM_REGION( 157, "maincpu:spla", 0 )
+ ROM_LOAD( "tms0970_wizatron_spla.pla", 0, 157, CRC(56c37a4f) SHA1(18ecc20d2666e89673739056483aed5a261ae927) )
ROM_END
+ROM_START( ti30 )
+ ROM_REGION( 0x1000, "maincpu", 0 )
+ ROM_LOAD16_WORD( "tmc0981nl", 0x0000, 0x1000, CRC(41298a14) SHA1(06f654c70add4044a612d3a38b0c2831c188fd0c) )
+
+ ROM_REGION( 1246, "maincpu:ipla", 0 )
+ ROM_LOAD( "tms0980_default_ipla.pla", 0, 1246, CRC(42db9a38) SHA1(2d127d98028ec8ec6ea10c179c25e447b14ba4d0) )
+ ROM_REGION( 1982, "maincpu:mpla", 0 )
+ ROM_LOAD( "tms0980_default_mpla.pla", 0, 1982, CRC(3709014f) SHA1(d28ee59ded7f3b9dc3f0594a32a98391b6e9c961) )
+ ROM_REGION( 352, "maincpu:opla", 0 )
+ ROM_LOAD( "tms0980_ti30_opla.pla", 0, 352, CRC(38788410) SHA1(cb3d1a61190b887cd2e6d9c60b4fdb9b901f7eed) )
+ ROM_REGION( 157, "maincpu:spla", 0 )
+ ROM_LOAD( "tms0980_ti30_spla.pla", 0, 157, CRC(399aa481) SHA1(72c56c58fde3fbb657d69647a9543b5f8fc74279) )
+ROM_END
+
+ROM_START( tibusan1 )
+ ROM_REGION( 0x1000, "maincpu", 0 )
+ ROM_LOAD16_WORD( "tmc0982nl", 0x0000, 0x1000, CRC(6954560a) SHA1(6c153a0c9239a811e3514a43d809964c06f8f88e) )
+
+ ROM_REGION( 1246, "maincpu:ipla", 0 )
+ ROM_LOAD( "tms0980_default_ipla.pla", 0, 1246, CRC(42db9a38) SHA1(2d127d98028ec8ec6ea10c179c25e447b14ba4d0) )
+ ROM_REGION( 1982, "maincpu:mpla", 0 )
+ ROM_LOAD( "tms0980_default_mpla.pla", 0, 1982, CRC(3709014f) SHA1(d28ee59ded7f3b9dc3f0594a32a98391b6e9c961) )
+ ROM_REGION( 352, "maincpu:opla", 0 )
+ ROM_LOAD( "tms0980_tibusan1_opla.pla", 0, 352, CRC(38788410) SHA1(cb3d1a61190b887cd2e6d9c60b4fdb9b901f7eed) )
+ ROM_REGION( 157, "maincpu:spla", 0 )
+ ROM_LOAD( "tms0980_tibusan1_spla.pla", 0, 157, CRC(399aa481) SHA1(72c56c58fde3fbb657d69647a9543b5f8fc74279) )
+ROM_END
+
+ROM_START( tiprog )
+ ROM_REGION( 0x1000, "maincpu", 0 )
+ ROM_LOAD16_WORD( "za0675nl", 0x0000, 0x1000, CRC(82355854) SHA1(03fab373bce04df8ea3fe25352525e8539213626) )
+
+ ROM_REGION( 1246, "maincpu:ipla", 0 )
+ ROM_LOAD( "tms0980_default_ipla.pla", 0, 1246, CRC(42db9a38) SHA1(2d127d98028ec8ec6ea10c179c25e447b14ba4d0) )
+ ROM_REGION( 1982, "maincpu:mpla", 0 )
+ ROM_LOAD( "tms0980_tiprog_mpla.pla", 0, 1982, CRC(57043284) SHA1(0fa06d5865830ecdb3d870271cb92ac917bed3ca) )
+ ROM_REGION( 352, "maincpu:opla", 0 )
+ ROM_LOAD( "tms0980_tiprog_opla.pla", 0, 352, BAD_DUMP CRC(2a63956f) SHA1(26a62ca2b5973d8564e580e12230292f6d2888d9) ) // corrected by hand
+ ROM_REGION( 157, "maincpu:spla", 0 )
+ ROM_LOAD( "tms0980_tiprog_spla.pla", 0, 157, CRC(399aa481) SHA1(72c56c58fde3fbb657d69647a9543b5f8fc74279) )
+ROM_END
+
+
+
+COMP( 1974, tisr16, 0, 0, tisr16, tisr16, driver_device, 0, "Texas Instruments", "SR-16 (Texas Instruments)", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW )
+
+COMP( 1976, ti1270, 0, 0, ti1270, ti1270, driver_device, 0, "Texas Instruments", "TI-1270", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW )
+COMP( 1977, wizatron, 0, 0, wizatron, wizatron, driver_device, 0, "Texas Instruments", "Wiz-A-Tron", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW )
-CONS( 1977, wizatron, 0, 0, wizatron, wizatron, driver_device, 0, "Texas Instruments", "Wiz-A-Tron", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW )
+COMP( 1976, ti30, 0, 0, ti30, ti30, driver_device, 0, "Texas Instruments", "TI-30", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW )
+COMP( 1977, tiprog, 0, 0, ti30, tiprog, driver_device, 0, "Texas Instruments", "TI Programmer", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW )
+COMP( 1979, tibusan1, 0, 0, ti30, tibusan1, driver_device, 0, "Texas Instruments", "TI Business Analyst-I", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW )
diff --git a/src/mess/layout/comp4.lay b/src/mess/layout/comp4.lay
new file mode 100644
index 00000000000..e85b68eadcb
--- /dev/null
+++ b/src/mess/layout/comp4.lay
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<mamelayout version="2">
+
+ <element name="lamp_disk_red" defstate="0">
+ <disk state="1"><color red="1.0" green="0.3" blue="0.2" /></disk>
+ <disk state="0"><color red="0.2" green="0.05" blue="0.03" /></disk>
+ </element>
+
+ <view name="Internal Layout">
+ <bounds left="0" right="180" top="0" bottom="100" />
+
+ <bezel name="lamp4" element="lamp_disk_red">
+ <bounds x="10" y="50" width="5" height="5" />
+ </bezel>
+ <bezel name="lamp10" element="lamp_disk_red">
+ <bounds x="10" y="60" width="5" height="5" />
+ </bezel>
+ <bezel name="lamp2" element="lamp_disk_red">
+ <bounds x="10" y="70" width="5" height="5" />
+ </bezel>
+ <bezel name="lamp1" element="lamp_disk_red">
+ <bounds x="10" y="80" width="5" height="5" />
+ </bezel>
+ <bezel name="lamp0" element="lamp_disk_red">
+ <bounds x="10" y="90" width="5" height="5" />
+ </bezel>
+
+ <bezel name="lamp9" element="lamp_disk_red">
+ <bounds x="30" y="50" width="5" height="5" />
+ </bezel>
+ <bezel name="lamp8" element="lamp_disk_red">
+ <bounds x="30" y="60" width="5" height="5" />
+ </bezel>
+ <bezel name="lamp7" element="lamp_disk_red">
+ <bounds x="30" y="70" width="5" height="5" />
+ </bezel>
+ <bezel name="lamp6" element="lamp_disk_red">
+ <bounds x="30" y="80" width="5" height="5" />
+ </bezel>
+ <bezel name="lamp5" element="lamp_disk_red">
+ <bounds x="30" y="90" width="5" height="5" />
+ </bezel>
+
+ </view>
+</mamelayout>
diff --git a/src/mess/layout/merlin.lay b/src/mess/layout/merlin.lay
index d9e47ebf09e..32d5691e253 100644
--- a/src/mess/layout/merlin.lay
+++ b/src/mess/layout/merlin.lay
@@ -256,7 +256,7 @@
<bezel name="lamp0" element="led">
<bounds x="34" y="20" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.0" inputmask="0x01">
+ <bezel element="button" inputtag="IN.0" inputmask="0x01">
<bounds x="34" y="20" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -267,7 +267,7 @@
<bezel name="lamp1" element="led">
<bounds x="10" y="44" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.0" inputmask="0x02">
+ <bezel element="button" inputtag="IN.0" inputmask="0x02">
<bounds x="10" y="44" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -277,7 +277,7 @@
<bezel name="lamp2" element="led">
<bounds x="34" y="44" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.0" inputmask="0x08">
+ <bezel element="button" inputtag="IN.0" inputmask="0x08">
<bounds x="34" y="44" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -287,7 +287,7 @@
<bezel name="lamp3" element="led">
<bounds x="58" y="44" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.0" inputmask="0x04">
+ <bezel element="button" inputtag="IN.0" inputmask="0x04">
<bounds x="58" y="44" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -298,7 +298,7 @@
<bezel name="lamp4" element="led">
<bounds x="10" y="68" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.1" inputmask="0x01">
+ <bezel element="button" inputtag="IN.1" inputmask="0x01">
<bounds x="10" y="68" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -308,7 +308,7 @@
<bezel name="lamp5" element="led">
<bounds x="34" y="68" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.1" inputmask="0x02">
+ <bezel element="button" inputtag="IN.1" inputmask="0x02">
<bounds x="34" y="68" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -318,7 +318,7 @@
<bezel name="lamp6" element="led">
<bounds x="58" y="68" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.1" inputmask="0x08">
+ <bezel element="button" inputtag="IN.1" inputmask="0x08">
<bounds x="58" y="68" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -329,7 +329,7 @@
<bezel name="lamp7" element="led">
<bounds x="10" y="92" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.1" inputmask="0x04">
+ <bezel element="button" inputtag="IN.1" inputmask="0x04">
<bounds x="10" y="92" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -339,7 +339,7 @@
<bezel name="lamp8" element="led">
<bounds x="34" y="92" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.2" inputmask="0x01">
+ <bezel element="button" inputtag="IN.2" inputmask="0x01">
<bounds x="34" y="92" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -349,7 +349,7 @@
<bezel name="lamp9" element="led">
<bounds x="58" y="92" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.2" inputmask="0x02">
+ <bezel element="button" inputtag="IN.2" inputmask="0x02">
<bounds x="58" y="92" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -360,7 +360,7 @@
<bezel name="lamp10" element="led">
<bounds x="34" y="116" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.2" inputmask="0x08">
+ <bezel element="button" inputtag="IN.2" inputmask="0x08">
<bounds x="34" y="116" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -371,7 +371,7 @@
<bezel element="panel_newgame">
<bounds x="21" y="156" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.3" inputmask="0x08">
+ <bezel element="button" inputtag="IN.3" inputmask="0x08">
<bounds x="21" y="156" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -379,7 +379,7 @@
<bezel element="panel_samegame">
<bounds x="47" y="156" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.2" inputmask="0x04">
+ <bezel element="button" inputtag="IN.2" inputmask="0x04">
<bounds x="47" y="156" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -387,7 +387,7 @@
<bezel element="panel_hitme">
<bounds x="21" y="182" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.3" inputmask="0x04">
+ <bezel element="button" inputtag="IN.3" inputmask="0x04">
<bounds x="21" y="182" width="20" height="20" />
<color alpha="0.2" />
</bezel>
@@ -395,7 +395,7 @@
<bezel element="panel_compturn">
<bounds x="47" y="182" width="20" height="20" />
</bezel>
- <bezel element="button" inputtag="O.3" inputmask="0x02">
+ <bezel element="button" inputtag="IN.3" inputmask="0x02">
<bounds x="47" y="182" width="20" height="20" />
<color alpha="0.2" />
</bezel>
diff --git a/src/mess/layout/ti1270.lay b/src/mess/layout/ti1270.lay
new file mode 100644
index 00000000000..6b18f6b9111
--- /dev/null
+++ b/src/mess/layout/ti1270.lay
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<mamelayout version="2">
+
+<!-- note: the digits were very small, wide space between them, and not the same style as (MAME's-)default -->
+
+ <element name="digit" defstate="0">
+ <led7seg><color red="1.0" green="0.15" blue="0.08" /></led7seg>
+ </element>
+
+ <view name="Internal Layout">
+ <bounds left="0" right="120" top="0" bottom="15" />
+
+ <bezel name="digit7" element="digit">
+ <bounds x="0" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit6" element="digit">
+ <bounds x="15" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit5" element="digit">
+ <bounds x="30" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit4" element="digit">
+ <bounds x="45" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit3" element="digit">
+ <bounds x="60" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit2" element="digit">
+ <bounds x="75" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit1" element="digit">
+ <bounds x="90" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit0" element="digit">
+ <bounds x="105" y="0" width="10" height="15" />
+ </bezel>
+
+ </view>
+</mamelayout>
diff --git a/src/mess/layout/ti30.lay b/src/mess/layout/ti30.lay
new file mode 100644
index 00000000000..b369924c7e6
--- /dev/null
+++ b/src/mess/layout/ti30.lay
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<mamelayout version="2">
+
+<!-- note: the digits were very small, wide space between them, and not the same style as (MAME's-)default -->
+
+ <element name="digit" defstate="0">
+ <led7seg><color red="1.0" green="0.15" blue="0.08" /></led7seg>
+ </element>
+
+ <view name="Internal Layout">
+ <bounds left="0" right="135" top="0" bottom="15" />
+
+ <bezel name="digit0" element="digit">
+ <bounds x="0" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit1" element="digit">
+ <bounds x="15" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit2" element="digit">
+ <bounds x="30" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit3" element="digit">
+ <bounds x="45" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit4" element="digit">
+ <bounds x="60" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit5" element="digit">
+ <bounds x="75" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit6" element="digit">
+ <bounds x="90" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit7" element="digit">
+ <bounds x="105" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit8" element="digit">
+ <bounds x="120" y="0" width="10" height="15" />
+ </bezel>
+
+ </view>
+</mamelayout>
diff --git a/src/mess/layout/tisr16.lay b/src/mess/layout/tisr16.lay
new file mode 100644
index 00000000000..b092f8a809c
--- /dev/null
+++ b/src/mess/layout/tisr16.lay
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<mamelayout version="2">
+
+<!-- note: the digits were very small, wide space between them, and not the same style as (MAME's-)default -->
+
+ <element name="digit" defstate="0">
+ <led7seg><color red="1.0" green="0.15" blue="0.08" /></led7seg>
+ </element>
+
+ <view name="Internal Layout">
+ <bounds left="0" right="180" top="0" bottom="15" />
+
+ <bezel name="digit10" element="digit">
+ <bounds x="0" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit9" element="digit">
+ <bounds x="15" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit8" element="digit">
+ <bounds x="30" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit7" element="digit">
+ <bounds x="45" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit6" element="digit">
+ <bounds x="60" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit5" element="digit">
+ <bounds x="75" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit4" element="digit">
+ <bounds x="90" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit3" element="digit">
+ <bounds x="105" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit2" element="digit">
+ <bounds x="120" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit11" element="digit">
+ <bounds x="135" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit1" element="digit">
+ <bounds x="150" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit0" element="digit">
+ <bounds x="165" y="0" width="10" height="15" />
+ </bezel>
+
+ </view>
+</mamelayout>
diff --git a/src/mess/layout/wizatron.lay b/src/mess/layout/wizatron.lay
new file mode 100644
index 00000000000..86934ea88c8
--- /dev/null
+++ b/src/mess/layout/wizatron.lay
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<mamelayout version="2">
+
+<!-- note: the digits were very small, wide space between them, and not the same style as (MAME's-)default -->
+<!-- note 2: yes, the PLUS sign is supposed to be lopsided like that -->
+<!-- note 3: yes, the EQUALS sign is supposed to be that high up, but newer releases improved this -->
+
+ <element name="static_black">
+ <rect><color red="0.0" green="0.0" blue="0.0" /></rect>
+ </element>
+
+ <element name="digit" defstate="0">
+ <led7seg><color red="1.0" green="0.3" blue="0.2" /></led7seg>
+ </element>
+ <element name="digit14" defstate="0">
+ <led14seg><color red="1.0" green="0.3" blue="0.2" /></led14seg>
+ </element>
+
+
+ <view name="Internal Layout">
+ <bounds left="0" right="135" top="0" bottom="15" />
+
+ <bezel name="digit8" element="digit">
+ <bounds x="0" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit7" element="digit">
+ <bounds x="15" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit6" element="digit14">
+ <bounds x="30" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit5" element="digit">
+ <bounds x="45" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit4" element="digit">
+ <bounds x="60" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit3" element="digit">
+ <bounds x="75" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit2" element="digit">
+ <bounds x="90" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit1" element="digit">
+ <bounds x="105" y="0" width="10" height="15" />
+ </bezel>
+ <bezel name="digit0" element="digit">
+ <bounds x="120" y="0" width="10" height="15" />
+ </bezel>
+
+<!-- mask out DIVIDE sign -->
+
+ <bezel element="static_black">
+ <bounds x="34.5" y="1.80" width="1.8" height="2.00" />
+ </bezel>
+ <bezel element="static_black">
+ <bounds x="34.3" y="5.1" width="1.75" height="1.3" />
+ </bezel>
+
+ <bezel element="static_black">
+ <bounds x="33.75" y="11.25" width="1.8" height="2.00" />
+ </bezel>
+ <bezel element="static_black">
+ <bounds x="33.95" y="8.65" width="1.75" height="1.3" />
+ </bezel>
+
+ </view>
+</mamelayout>
diff --git a/src/mess/mess.lst b/src/mess/mess.lst
index 4eb6d518518..34918634421 100644
--- a/src/mess/mess.lst
+++ b/src/mess/mess.lst
@@ -1063,26 +1063,31 @@ avigo_es // 1997 Avigo (Spanish)
avigo_it // 1997 Avigo (Italian)
// Texas Instruments Calculators
+tisr16 // 1974 SR-16
+ti1270
+ti30 // 1976 TI-30
+tiprog
+tibusan1
+wizatron
ti73 // 1990 TI-73
ti74 // 1985 TI-74
ti95 // 1986 TI-95
ti81 // 1990 TI-81 (Z80 2 MHz)
-ti81v2 // 1990 TI-81 (Z80 2 MHz)
+ti81v2 // 1990 TI-81 (Z80 2 MHz)
ti85 // 1992 TI-85 (Z80 6 MHz)
ti82 // 1993 TI-82 (Z80 6 MHz)
ti83 // 1996 TI-83 (Z80 6 MHz)
ti86 // 1997 TI-86 (Z80 6 MHz)
-ti83p // 1999 TI-83 Plus (Z80 6 MHz)
+ti83p // 1999 TI-83 Plus (Z80 6 MHz)
ti83pse // 2001 TI-83 Plus Silver Edition
-ti84p // 2004 TI-84 Plus
+ti84p // 2004 TI-84 Plus
ti84pse // 2004 TI-84 Plus Silver Edition
//ti84cse // 2013 TI-84 Plus C Silver Edition (color screen)
ti89 // 1998 TI-89
ti92 // 1995 TI-92
-ti92p // 1999 TI-92 Plus
+ti92p // 1999 TI-92 Plus
v200 // 2002 Voyage 200 PLT
-ti89t // 2004 TI-89 Titanium
-wizatron
+ti89t // 2004 TI-89 Titanium
evmbug
// Exelvision (founded by former TI employees)
diff --git a/src/mess/mess.mak b/src/mess/mess.mak
index 1a78afa29c0..d42e690be10 100644
--- a/src/mess/mess.mak
+++ b/src/mess/mess.mak
@@ -2074,6 +2074,7 @@ $(MAME_DRIVERS)/cdi.o: $(MAME_LAYOUT)/cdi.lh
$(MESS_DRIVERS)/chessmst.o: $(MESS_LAYOUT)/chessmst.lh
$(MESS_DRIVERS)/chesstrv.o: $(MESS_LAYOUT)/chesstrv.lh \
$(MESS_LAYOUT)/borisdpl.lh
+$(MESS_DRIVERS)/comp4.o: $(MESS_LAYOUT)/comp4.lh
$(MESS_DRIVERS)/cp1.o: $(MESS_LAYOUT)/cp1.lh
$(MESS_DRIVERS)/cvicny.o: $(MESS_LAYOUT)/cvicny.lh
$(MESS_DRIVERS)/coco3.o: $(MESS_LAYOUT)/coco3.lh
@@ -2154,6 +2155,10 @@ $(MESS_DRIVERS)/tec1.o: $(MESS_LAYOUT)/tec1.lh
$(MESS_DRIVERS)/tecnbras.o: $(MESS_LAYOUT)/tecnbras.lh
$(MESS_DRIVERS)/ti74.o: $(MESS_LAYOUT)/ti74.lh \
$(MESS_LAYOUT)/ti95.lh
+$(MESS_DRIVERS)/ticalc1x.o: $(MESS_LAYOUT)/ti1270.lh \
+ $(MESS_LAYOUT)/ti30.lh \
+ $(MESS_LAYOUT)/tisr16.lh \
+ $(MESS_LAYOUT)/wizatron.lh
$(MESS_DRIVERS)/tk80.o: $(MESS_LAYOUT)/tk80.lh
$(MESS_DRIVERS)/tm990189.o: $(MESS_LAYOUT)/tm990189.lh \
$(MESS_LAYOUT)/tm990189v.lh