From c1eaec3cee27803f88d4520b9284f29391612394 Mon Sep 17 00:00:00 2001 From: hap Date: Mon, 1 Dec 2014 21:45:19 +0100 Subject: (MESS) Rewrote TMS1xxx MCU core and added support for a couple of classic Texas Instruments handheld calculators. [hap, seanriddle] --- src/emu/cpu/tms0980/tms0980.c | 1759 +++++++++++++++++++++-------------------- src/emu/cpu/tms0980/tms0980.h | 296 ++++--- src/mess/drivers/comp4.c | 139 +++- src/mess/drivers/merlin.c | 94 +-- src/mess/drivers/microvsn.c | 8 +- src/mess/drivers/simon.c | 42 +- src/mess/drivers/stopthie.c | 21 +- src/mess/drivers/ticalc1x.c | 742 +++++++++++++++-- src/mess/layout/comp4.lay | 45 ++ src/mess/layout/merlin.lay | 30 +- src/mess/layout/ti1270.lay | 39 + src/mess/layout/ti30.lay | 42 + src/mess/layout/tisr16.lay | 51 ++ src/mess/layout/wizatron.lay | 68 ++ src/mess/mess.lst | 17 +- src/mess/mess.mak | 5 + 16 files changed, 2185 insertions(+), 1213 deletions(-) create mode 100644 src/mess/layout/comp4.lay create mode 100644 src/mess/layout/ti1270.lay create mode 100644 src/mess/layout/ti30.lay create mode 100644 src/mess/layout/tisr16.lay create mode 100644 src/mess/layout/wizatron.lay 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; // 28-pin DIP, 11 R pins +const device_type TMS1200 = &device_creator; // 40-pin DIP, 13 R pins +const device_type TMS1070 = &device_creator; // 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; // 28-pin DIP, 11 R pins +const device_type TMS1300 = &device_creator; // 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; // 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; // 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; -const device_type TMS1000 = &device_creator; -const device_type TMS0970 = &device_creator; -const device_type TMS1070 = &device_creator; -const device_type TMS1200 = &device_creator; -const device_type TMS1270 = &device_creator; -const device_type TMS1100 = &device_creator; -const device_type TMS1300 = &device_creator; +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; #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; #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 static devcb_base &set_read_k(device_t &device, _Object object) { return downcast(device).m_read_k.set_callback(object); } - template static devcb_base &set_write_o(device_t &device, _Object object) { return downcast(device).m_write_o.set_callback(object); } - template static devcb_base &set_write_r(device_t &device, _Object object) { return downcast(device).m_write_r.set_callback(object); } + template static devcb_base &set_read_k_callback(device_t &device, _Object object) { return downcast(device).m_read_k.set_callback(object); } + template static devcb_base &set_write_o_callback(device_t &device, _Object object) { return downcast(device).m_write_o.set_callback(object); } + template static devcb_base &set_write_r_callback(device_t &device, _Object object) { return downcast(device).m_write_r.set_callback(object); } + template static devcb_base &set_power_off_callback(device_t &device, _Object object) { return downcast(device).m_power_off.set_callback(object); } static void set_output_pla(device_t &device, const UINT16 *output_pla) { downcast(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 m_mpla; + optional_device m_ipla; + optional_device m_opla; + optional_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 m_fixed_decode; + dynamic_array m_micro_decode; + dynamic_array 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 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,10 +46,50 @@ 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 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ - + @@ -267,7 +267,7 @@ - + @@ -277,7 +277,7 @@ - + @@ -287,7 +287,7 @@ - + @@ -298,7 +298,7 @@ - + @@ -308,7 +308,7 @@ - + @@ -318,7 +318,7 @@ - + @@ -329,7 +329,7 @@ - + @@ -339,7 +339,7 @@ - + @@ -349,7 +349,7 @@ - + @@ -360,7 +360,7 @@ - + @@ -371,7 +371,7 @@ - + @@ -379,7 +379,7 @@ - + @@ -387,7 +387,7 @@ - + @@ -395,7 +395,7 @@ - + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 -- cgit v1.2.3