From d9bac2034b03f48a68830dd1cbf8c4ca3a5bac84 Mon Sep 17 00:00:00 2001 From: hap Date: Sat, 6 Aug 2022 13:23:59 +0200 Subject: tms2100: add some of the opcodes --- src/devices/cpu/tms1000/tms0270.cpp | 23 +++++---- src/devices/cpu/tms1000/tms0970.cpp | 25 ++++++---- src/devices/cpu/tms1000/tms0980.cpp | 87 +++++++++++++++++++++++--------- src/devices/cpu/tms1000/tms0980.h | 6 +++ src/devices/cpu/tms1000/tms1000.cpp | 53 ++++++++++---------- src/devices/cpu/tms1000/tms1000c.cpp | 24 +++++---- src/devices/cpu/tms1000/tms1100.cpp | 19 +++++-- src/devices/cpu/tms1000/tms1100.h | 1 + src/devices/cpu/tms1000/tms1400.cpp | 21 ++++---- src/devices/cpu/tms1000/tms1k_base.cpp | 70 ++++++++------------------ src/devices/cpu/tms1000/tms1k_base.h | 41 ++++++++++----- src/devices/cpu/tms1000/tms2100.cpp | 91 +++++++++++++++++++++++++++++++--- src/devices/cpu/tms1000/tms2100.h | 11 ++++ src/devices/cpu/tms1000/tms2400.cpp | 18 +++++-- src/devices/cpu/tms1000/tms2400.h | 1 + src/devices/cpu/tms1000/tp0320.cpp | 36 +++++++------- src/devices/cpu/tms1000/tp0320.h | 2 - src/mame/handheld/hh_tms1k.cpp | 34 +++++++++++-- 18 files changed, 374 insertions(+), 189 deletions(-) diff --git a/src/devices/cpu/tms1000/tms0270.cpp b/src/devices/cpu/tms1000/tms0270.cpp index 297cd97d2b1..9741da24903 100644 --- a/src/devices/cpu/tms1000/tms0270.cpp +++ b/src/devices/cpu/tms1000/tms0270.cpp @@ -4,23 +4,26 @@ TMS1000 family - TMS0270 +TMS0270 is a TMS0980 with earrings and a new hat. The new changes look like a quick afterthought, almost hacky +- RAM, ROM, and main instructions PLAs is the same as TMS0980 +- 64-term microinstructions PLA between the RAM and ROM, similar to TMS0980, + plus optional separate lines for custom opcode handling +- 48-term output PLA above the RAM (rotate opla 90 degrees) + +newer TMS0270 chips (eg. Speak & Math) have 42 pins + +TMS0260 is same or similar? + */ #include "emu.h" #include "tms0270.h" -// TMS0270 is a TMS0980 with earrings and a new hat. The new changes look like a quick afterthought, almost hacky -// - RAM, ROM, and main instructions PLAs is the same as TMS0980 -// - 64-term microinstructions PLA between the RAM and ROM, similar to TMS0980, -// plus optional separate lines for custom opcode handling -// - 48-term output PLA above the RAM (rotate opla 90 degrees) -DEFINE_DEVICE_TYPE(TMS0270, tms0270_cpu_device, "tms0270", "Texas Instruments TMS0270") // 40-pin DIP, 16 O pins, 8+ R pins (some R pins are internally hooked up to support more I/O) -// newer TMS0270 chips (eg. Speak & Math) have 42 pins -// TMS0260 is same or similar? +// device definitions +DEFINE_DEVICE_TYPE(TMS0270, tms0270_cpu_device, "tms0270", "Texas Instruments TMS0270") // 40-pin DIP, 16 O pins, 8+ R pins (some R pins are internally hooked up to support more I/O) -// device definitions tms0270_cpu_device::tms0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : tms0980_cpu_device(mconfig, TMS0270, tag, owner, clock, 16 /* o pins */, 16 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 1 /* stack levels */, 11 /* rom width */, address_map_constructor(FUNC(tms0270_cpu_device::rom_11bit), this), 8 /* ram width */, address_map_constructor(FUNC(tms0270_cpu_device::ram_144x4), this)) { } @@ -40,7 +43,7 @@ void tms0270_cpu_device::device_add_mconfig(machine_config &config) void tms0270_cpu_device::device_start() { // common init - tms1k_base_device::device_start(); + tms0980_cpu_device::device_start(); // zerofill m_r_prev = 0; diff --git a/src/devices/cpu/tms1000/tms0970.cpp b/src/devices/cpu/tms1000/tms0970.cpp index f60b638f310..326ecd40d57 100644 --- a/src/devices/cpu/tms1000/tms0970.cpp +++ b/src/devices/cpu/tms1000/tms0970.cpp @@ -4,28 +4,31 @@ TMS1000 family - TMS0950, TMS0970, TMS1990 +TMS0950 is a TMS1000 with a TMS0980 style opla, it was quickly succeeded by the TMS0970 +- RAM, ROM, microinstructions is the same as TMS1000 +- 10-term inverted output PLA and segment PLA on the top-left + +TMS0970 is a stripped-down version of the TMS0980, itself acting more like a TMS1000 +- RAM and ROM is the same as TMS1000 +- main instructions PLAs at the top half, to the right of the midline + * see TMS0980 notes, except that the fixed instruction list differs: + RETN, SETR, RBIT, SBIT, LDX, COMX, TDO, ..., redir(----0-00), LDP +- 32-term microinstructions PLA between the RAM and ROM, supporting 15 microinstructions +- 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees) + */ #include "emu.h" #include "tms0970.h" -// TMS0950 is a TMS1000 with a TMS0980 style opla, it was quickly succeeded by the TMS0970 -// - RAM, ROM, microinstructions is the same as TMS1000 -// - 10-term inverted output PLA and segment PLA on the top-left + +// device definitions DEFINE_DEVICE_TYPE(TMS0950, tms0950_cpu_device, "tms0950", "Texas Instruments TMS0950") // 28-pin DIP, 8 O pins, 11? R pins -// TMS0970 is a stripped-down version of the TMS0980, itself acting more like a TMS1000 -// - RAM and ROM is the same as TMS1000 -// - main instructions PLAs at the top half, to the right of the midline -// * see TMS0980 notes, except that the fixed instruction list differs: -// RETN, SETR, RBIT, SBIT, LDX, COMX, TDO, ..., redir(----0-00), LDP -// - 32-term microinstructions PLA between the RAM and ROM, supporting 15 microinstructions -// - 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees) DEFINE_DEVICE_TYPE(TMS0970, tms0970_cpu_device, "tms0970", "Texas Instruments TMS0970") // 28-pin DIP, 11 R pins (note: pinout may slightly differ from chip to chip) DEFINE_DEVICE_TYPE(TMS1990, tms1990_cpu_device, "tms1990", "Texas Instruments TMS1990") // 28-pin DIP, ? R pins.. -// device definitions tms0970_cpu_device::tms0970_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : tms0970_cpu_device(mconfig, TMS0970, tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 2 /* x width */, 1 /* stack levels */, 10 /* rom width */, address_map_constructor(FUNC(tms0970_cpu_device::rom_10bit), this), 6 /* ram width */, address_map_constructor(FUNC(tms0970_cpu_device::ram_6bit), this)) { } diff --git a/src/devices/cpu/tms1000/tms0980.cpp b/src/devices/cpu/tms1000/tms0980.cpp index 9641c21127a..72f65df3e89 100644 --- a/src/devices/cpu/tms1000/tms0980.cpp +++ b/src/devices/cpu/tms1000/tms0980.cpp @@ -4,40 +4,34 @@ TMS1000 family - TMS0980, TMS1980 +TMS0980 +- 144x4bit RAM array at the bottom-left (128+16, set up as 8x18x4) +- 2048x9bit ROM array at the bottom-left +- main instructions PLAs at the top half, to the right of the midline + * top section is assumed to be the CKI bus select + * middle section is for microinstruction redirection, this part may differ per die + * rest is fixed instructions select, from top-to-bottom: SEAC, LDX, COMX, COMX8, + TDO, SBIT, RETN, SETR, REAC, XDA, SAL, RBIT, ..., OFF, SBL, LDP, redir(------00- + R0^BL) +- 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions +- 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees) + +TMS1980 is a TMS0980 with a TMS1x00 style opla +- RAM, ROM, and main instructions PLAs is the same as TMS0980 +- one of the microinstructions redirects to a RSTR instruction, like on TMS0270 +- 32-term output PLA above the RAM, 7 bits! (rotate opla 270 degrees) + */ #include "emu.h" #include "tms0980.h" #include "tms1k_dasm.h" -// TMS0980 -// - 144x4bit RAM array at the bottom-left (128+16, set up as 8x18x4) -// - 2048x9bit ROM array at the bottom-left -// - main instructions PLAs at the top half, to the right of the midline -// * top section is assumed to be the CKI bus select -// * middle section is for microinstruction redirection, this part may differ per die -// * rest is fixed instructions select, from top-to-bottom: SEAC, LDX, COMX, COMX8, -// TDO, SBIT, RETN, SETR, REAC, XDA, SAL, RBIT, ..., OFF, SBL, LDP, redir(------00- + R0^BL) -// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions -// - 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees) -DEFINE_DEVICE_TYPE(TMS0980, tms0980_cpu_device, "tms0980", "Texas Instruments TMS0980") // 28-pin DIP, 9 R pins -// TMS1980 is a TMS0980 with a TMS1x00 style opla -// - RAM, ROM, and main instructions PLAs is the same as TMS0980 -// - one of the microinstructions redirects to a RSTR instruction, like on TMS0270 -// - 32-term output PLA above the RAM, 7 bits! (rotate opla 270 degrees) +// device definitions +DEFINE_DEVICE_TYPE(TMS0980, tms0980_cpu_device, "tms0980", "Texas Instruments TMS0980") // 28-pin DIP, 9 R pins DEFINE_DEVICE_TYPE(TMS1980, tms1980_cpu_device, "tms1980", "Texas Instruments TMS1980") // 28-pin DIP, 7 O pins, 10 R pins, high voltage -// internal memory maps -void tms0980_cpu_device::ram_144x4(address_map &map) -{ - map(0x00, 0x7f).ram(); - map(0x80, 0x8f).ram().mirror(0x70); // DAM -} - - -// device definitions tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : tms0980_cpu_device(mconfig, TMS0980, tag, owner, clock, 8 /* o pins */, 9 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 1 /* stack levels */, 11 /* rom width */, address_map_constructor(FUNC(tms0980_cpu_device::rom_11bit), this), 8 /* ram width */, address_map_constructor(FUNC(tms0980_cpu_device::ram_144x4), this)) { } @@ -51,6 +45,14 @@ tms1980_cpu_device::tms1980_cpu_device(const machine_config &mconfig, const char { } +// internal memory maps +void tms0980_cpu_device::ram_144x4(address_map &map) +{ + map(0x00, 0x7f).ram(); + map(0x80, 0x8f).ram().mirror(0x70); // DAM +} + + // machine configs void tms0980_cpu_device::device_add_mconfig(machine_config &config) { @@ -216,6 +218,43 @@ void tms0980_cpu_device::op_comx() m_x ^= (m_x_mask >> 1); } +void tms0980_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)); +} + +void tms0980_cpu_device::op_off() +{ + // OFF: request auto power-off + m_power_off(1); +} + +void tms0980_cpu_device::op_seac() +{ + // SEAC: set end around carry + m_eac = 1; +} + +void tms0980_cpu_device::op_reac() +{ + // REAC: reset end around carry + m_eac = 0; +} + +void tms0980_cpu_device::op_sal() +{ + // SAL: set add latch (reset is done with RETN) + m_add = 1; +} + +void tms0980_cpu_device::op_sbl() +{ + // SBL: set branch latch (reset is done with RETN) + m_bl = 1; +} + void tms1980_cpu_device::op_tdo() { // TDO: transfer accumulator and status(not status_latch!) to O-output diff --git a/src/devices/cpu/tms1000/tms0980.h b/src/devices/cpu/tms1000/tms0980.h index ceac05dffd1..9304183b287 100644 --- a/src/devices/cpu/tms1000/tms0980.h +++ b/src/devices/cpu/tms1000/tms0980.h @@ -63,6 +63,12 @@ protected: virtual void read_opcode() override; virtual void op_comx() override; + virtual void op_xda() override; + virtual void op_off() override; + virtual void op_seac() override; + virtual void op_reac() override; + virtual void op_sal() override; + virtual void op_sbl() override; }; class tms1980_cpu_device : public tms0980_cpu_device diff --git a/src/devices/cpu/tms1000/tms1000.cpp b/src/devices/cpu/tms1000/tms1000.cpp index 511bd50b510..6937fc2ab35 100644 --- a/src/devices/cpu/tms1000/tms1000.cpp +++ b/src/devices/cpu/tms1000/tms1000.cpp @@ -5,8 +5,18 @@ TMS1000 family - TMS1000, TMS1070, TMS1040, TMS1200, TMS1700, TMS1730, and second source Motorola MC141000, MC141200. - TODO: - - add TMS1270 (10 O pins, how does that work?) +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 + +TODO: +- add TMS1270 (10 O pins, how does that work?) */ @@ -14,15 +24,8 @@ #include "tms1000.h" #include "tms1k_dasm.h" -// TMS1000 -// - 64x4bit RAM array at the bottom-left -// - 1024x8bit ROM array at the bottom-right -// * FYI, the row-selector to the left of it is laid out as: -// 3,4,11,12,19,20,27,28,35,36,43,44,51,52,59,60,0,7,8,15,16,23,24,31,32,39,40,47,48,55,56,63, -// 2,5,10,13,18,21,26,29,34,37,42,45,50,53,58,61,1,6,9,14,17,22,25,30,33,38,41,46,49,54,57,62 -// - 30-term microinstructions PLA(mpla) at the top half, to the right of the midline, supporting 16 microinstructions -// - 20-term output PLA(opla) at the top-left -// - the ALU is between the opla and mpla + +// device definitions DEFINE_DEVICE_TYPE(TMS1000, tms1000_cpu_device, "tms1000", "Texas Instruments TMS1000") // 28-pin DIP, 11 R pins DEFINE_DEVICE_TYPE(TMS1070, tms1070_cpu_device, "tms1070", "Texas Instruments TMS1070") // high voltage version DEFINE_DEVICE_TYPE(TMS1040, tms1040_cpu_device, "tms1040", "Texas Instruments TMS1040") // same as TMS1070 with just a different pinout? @@ -30,25 +33,10 @@ DEFINE_DEVICE_TYPE(TMS1200, tms1200_cpu_device, "tms1200", "Texas Instruments DEFINE_DEVICE_TYPE(TMS1700, tms1700_cpu_device, "tms1700", "Texas Instruments TMS1700") // 28-pin DIP, RAM/ROM size halved, 9 R pins DEFINE_DEVICE_TYPE(TMS1730, tms1730_cpu_device, "tms1730", "Texas Instruments TMS1730") // 20-pin DIP, same die as TMS1700, package has less pins: 6 R pins, 5 O pins (output PLA is still 8-bit, O1,O3,O5 unused) -// 2nd source Motorola chips DEFINE_DEVICE_TYPE(MC141000, mc141000_cpu_device, "mc141000", "Motorola MC141000") // CMOS, pin-compatible with TMS1000(reverse polarity) DEFINE_DEVICE_TYPE(MC141200, mc141200_cpu_device, "mc141200", "Motorola MC141200") // CMOS, 40-pin DIP, 16 R pins -// internal memory maps -void tms1000_cpu_device::rom_9bitm(address_map &map) -{ - map(0x000, 0x1ff).mirror(0x200).rom(); -} - -void tms1000_cpu_device::ram_32x4(address_map &map) -{ - map(0x00, 0x3f).ram(); - map(0x08, 0x0f).mirror(0x30).noprw(); // override -} - - -// device definitions tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : tms1000_cpu_device(mconfig, TMS1000, tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 2 /* x width */, 1 /* stack levels */, 10 /* rom width */, address_map_constructor(FUNC(tms1000_cpu_device::rom_10bit), this), 6 /* ram width */, address_map_constructor(FUNC(tms1000_cpu_device::ram_6bit), this)) { } @@ -86,6 +74,19 @@ mc141200_cpu_device::mc141200_cpu_device(const machine_config &mconfig, const ch { } +// internal memory maps +void tms1000_cpu_device::rom_9bitm(address_map &map) +{ + map(0x000, 0x1ff).mirror(0x200).rom(); +} + +void tms1000_cpu_device::ram_32x4(address_map &map) +{ + map(0x00, 0x3f).ram(); + map(0x08, 0x0f).mirror(0x30).noprw(); // override +} + + // machine configs void tms1000_cpu_device::device_add_mconfig(machine_config &config) { diff --git a/src/devices/cpu/tms1000/tms1000c.cpp b/src/devices/cpu/tms1000/tms1000c.cpp index bbc29e88114..977c8c90d37 100644 --- a/src/devices/cpu/tms1000/tms1000c.cpp +++ b/src/devices/cpu/tms1000/tms1000c.cpp @@ -4,26 +4,28 @@ TMS1000 family - TMS1000C - TODO: - - add TMS1200C (has L input pins like TMS1600) +TMS1000 CMOS versions (3-level stack, HALT pin) +- RAM at top-left, ROM at top-right(rotate CCW) +- ROM ordering is different: + * row select is linear (0-63) + * bit select is 7-0 instead of 0-7 + * page select doesn't flip in the middle +- 32-term mpla at bottom-right, different order +- 32-term opla at bottom-left, ordered O7-O0(0 or 1), and A8,4,2,1,S + +TODO: +- add TMS1200C (has L input pins like TMS1600) */ #include "emu.h" #include "tms1000c.h" -// TMS1000 CMOS versions (3-level stack, HALT pin) -// - RAM at top-left, ROM at top-right(rotate CCW) -// - ROM ordering is different: -// * row select is linear (0-63) -// * bit select is 7-0 instead of 0-7 -// * page select doesn't flip in the middle -// - 32-term mpla at bottom-right, different order -// - 32-term opla at bottom-left, ordered O7-O0(0 or 1), and A8,4,2,1,S + +// device definitions DEFINE_DEVICE_TYPE(TMS1000C, tms1000c_cpu_device, "tms1000c", "Texas Instruments TMS1000C") // 28-pin SDIP, 10 R pins -// device definitions tms1000c_cpu_device::tms1000c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : tms1000_cpu_device(mconfig, TMS1000C, tag, owner, clock, 8 /* o pins */, 10 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 2 /* x width */, 3 /* stack levels */, 10 /* rom width */, address_map_constructor(FUNC(tms1000c_cpu_device::rom_10bit), this), 6 /* ram width */, address_map_constructor(FUNC(tms1000c_cpu_device::ram_6bit), this)) { } diff --git a/src/devices/cpu/tms1000/tms1100.cpp b/src/devices/cpu/tms1000/tms1100.cpp index fc2310b6a84..6ec5d71b727 100644 --- a/src/devices/cpu/tms1000/tms1100.cpp +++ b/src/devices/cpu/tms1000/tms1100.cpp @@ -4,8 +4,10 @@ TMS1000 family - TMS1100, TMS1170, TMS1300, TMS1370 - TODO: - - add TMS1100C when needed +TMS1100 is nearly the same as TMS1000, some different opcodes, and with double the RAM and ROM + +TODO: +- add TMS1100C when needed */ @@ -13,14 +15,14 @@ #include "tms1100.h" #include "tms1k_dasm.h" -// TMS1100 is nearly the same as TMS1000, some different opcodes, and with double the RAM and ROM + +// device definitions DEFINE_DEVICE_TYPE(TMS1100, tms1100_cpu_device, "tms1100", "Texas Instruments TMS1100") // 28-pin DIP, 11 R pins DEFINE_DEVICE_TYPE(TMS1170, tms1170_cpu_device, "tms1170", "Texas Instruments TMS1170") // high voltage version DEFINE_DEVICE_TYPE(TMS1300, tms1300_cpu_device, "tms1300", "Texas Instruments TMS1300") // 40-pin DIP, 16 R pins DEFINE_DEVICE_TYPE(TMS1370, tms1370_cpu_device, "tms1370", "Texas Instruments TMS1370") // high voltage version, also seen in 28-pin package(some O/R pins unavailable) -// device definitions tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : tms1100_cpu_device(mconfig, TMS1100, tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 3 /* x width */, 1 /* stack levels */, 11 /* rom width */, address_map_constructor(FUNC(tms1100_cpu_device::rom_11bit), this), 7 /* ram width */, address_map_constructor(FUNC(tms1100_cpu_device::ram_7bit), this)) { } @@ -49,7 +51,14 @@ std::unique_ptr tms1100_cpu_device::create_disassembler( } -// device_reset +// device_start/reset +void tms1100_cpu_device::device_start() +{ + tms1000_cpu_device::device_start(); + + state_add(++m_state_count, "CB", m_cb).formatstr("%01X"); // 8 +} + void tms1100_cpu_device::device_reset() { tms1000_cpu_device::device_reset(); diff --git a/src/devices/cpu/tms1000/tms1100.h b/src/devices/cpu/tms1000/tms1100.h index 10b477a8014..3855a3958b4 100644 --- a/src/devices/cpu/tms1000/tms1100.h +++ b/src/devices/cpu/tms1000/tms1100.h @@ -69,6 +69,7 @@ protected: tms1100_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 o_pins, u8 r_pins, u8 pc_bits, u8 byte_bits, u8 x_bits, u8 stack_levels, int rom_width, address_map_constructor rom_map, int ram_width, address_map_constructor ram_map); // overrides + virtual void device_start() override; virtual void device_reset() override; virtual std::unique_ptr create_disassembler() override; diff --git a/src/devices/cpu/tms1000/tms1400.cpp b/src/devices/cpu/tms1000/tms1400.cpp index 7e91c2722ba..26f7a612d05 100644 --- a/src/devices/cpu/tms1000/tms1400.cpp +++ b/src/devices/cpu/tms1000/tms1400.cpp @@ -4,8 +4,16 @@ TMS1000 family - TMS1400, TMS1470, TMS1475, TMS1600, TMS1670 - TODO: - - emulate TMS1600 L-pins +TMS1400 follows the TMS1100, it doubles the ROM size again (4 chapters of 16 pages), and adds a 3-level callstack +- rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100 +- the opla size is increased from 20 to 32 terms + +TMS1600 adds more I/O to the TMS1400, input pins are doubled with added L1,2,4,8 +- rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100 +- the opla size is increased from 20 to 32 terms + +TODO: +- emulate TMS1600 L-pins */ @@ -13,21 +21,16 @@ #include "tms1400.h" #include "tms1k_dasm.h" -// TMS1400 follows the TMS1100, it doubles the ROM size again (4 chapters of 16 pages), and adds a 3-level callstack -// - rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100 -// - the opla size is increased from 20 to 32 terms + +// device definitions DEFINE_DEVICE_TYPE(TMS1400, tms1400_cpu_device, "tms1400", "Texas Instruments TMS1400") // 28-pin DIP, 11 R pins (TMS1400CR is same, but with TMS1100 pinout) DEFINE_DEVICE_TYPE(TMS1470, tms1470_cpu_device, "tms1470", "Texas Instruments TMS1470") // high voltage version, 1 R pin removed for Vpp DEFINE_DEVICE_TYPE(TMS1475, tms1475_cpu_device, "tms1475", "Texas Instruments TMS1475") // 40-pin DIP, 22 R pins -// TMS1600 adds more I/O to the TMS1400, input pins are doubled with added L1,2,4,8 -// - rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100 -// - the opla size is increased from 20 to 32 terms DEFINE_DEVICE_TYPE(TMS1600, tms1600_cpu_device, "tms1600", "Texas Instruments TMS1600") // 40-pin DIP, 16 R pins DEFINE_DEVICE_TYPE(TMS1670, tms1670_cpu_device, "tms1670", "Texas Instruments TMS1670") // high voltage version -// device definitions tms1400_cpu_device::tms1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : tms1400_cpu_device(mconfig, TMS1400, tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 3 /* x width */, 3 /* stack levels */, 12 /* rom width */, address_map_constructor(FUNC(tms1400_cpu_device::rom_12bit), this), 7 /* ram width */, address_map_constructor(FUNC(tms1400_cpu_device::ram_7bit), this)) { } diff --git a/src/devices/cpu/tms1000/tms1k_base.cpp b/src/devices/cpu/tms1000/tms1k_base.cpp index 9f8823ddbf0..c02c85d7d66 100644 --- a/src/devices/cpu/tms1000/tms1k_base.cpp +++ b/src/devices/cpu/tms1000/tms1k_base.cpp @@ -106,6 +106,18 @@ void tms1k_base_device::state_string_export(const device_state_entry &entry, std case STATE_GENPCBASE: str = string_format("%03X", m_rom_address << ((m_byte_bits > 8) ? 1 : 0)); break; + + case STATE_GENFLAGS: + // not a single flags register, first 3 are TMS0980-family + str = string_format("%c%c%c %c%c%c", + m_bl ? 'B':'b', + m_add ? 'A':'a', + m_eac ? 'E':'e', + (m_clatch & 1) ? 'C':'c', + m_status ? 'S':'s', + m_status_latch ? 'L':'l' + ); + break; } } @@ -218,7 +230,7 @@ void tms1k_base_device::device_start() // register state for debugger state_add(STATE_GENPC, "GENPC", m_rom_address).formatstr("%03X").noshow(); state_add(STATE_GENPCBASE, "CURPC", m_rom_address).formatstr("%03X").noshow(); - state_add(STATE_GENFLAGS, "GENFLAGS", m_sr).formatstr("%8s").noshow(); + state_add(STATE_GENFLAGS, "GENFLAGS", m_status).formatstr("%7s").noshow(); m_state_count = 0; state_add(++m_state_count, "PC", m_pc).formatstr("%02X"); // 1 @@ -228,7 +240,6 @@ void tms1k_base_device::device_start() state_add(++m_state_count, "A", m_a).formatstr("%01X"); // 5 state_add(++m_state_count, "X", m_x).formatstr("%01X"); // 6 state_add(++m_state_count, "Y", m_y).formatstr("%01X"); // 7 - state_add(++m_state_count, "STATUS", m_status).formatstr("%01X"); // 8 set_icountptr(m_icount); } @@ -580,18 +591,12 @@ void tms1k_base_device::op_ldp() m_pb = m_c4; } - -// TMS1100-specific - void tms1k_base_device::op_comc() { // COMC: complement chapter buffer m_cb ^= 1; } - -// TMS1400-specific - void tms1k_base_device::op_tpc() { // TPC: transfer page buffer to chapter buffer @@ -599,46 +604,6 @@ void tms1k_base_device::op_tpc() } -// TMS0980-specific (and possibly child classes) - -void tms1k_base_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)); -} - -void tms1k_base_device::op_off() -{ - // OFF: request auto power-off - m_power_off(1); -} - -void tms1k_base_device::op_seac() -{ - // SEAC: set end around carry - m_eac = 1; -} - -void tms1k_base_device::op_reac() -{ - // REAC: reset end around carry - m_eac = 0; -} - -void tms1k_base_device::op_sal() -{ - // SAL: set add latch (reset is done with RETN) - m_add = 1; -} - -void tms1k_base_device::op_sbl() -{ - // SBL: set branch latch (reset is done with RETN) - m_bl = 1; -} - - //------------------------------------------------- // execute @@ -732,6 +697,10 @@ void tms1k_base_device::execute_one() if (m_fixed & F_LDP) op_ldp(); if (m_fixed & F_COMC) op_comc(); if (m_fixed & F_TPC) op_tpc(); + if (m_fixed & F_TAX) op_tax(); + if (m_fixed & F_TAC) op_tac(); + if (m_fixed & F_TADM) op_tadm(); + if (m_fixed & F_TMA) op_tma(); if (m_fixed & F_OFF) op_off(); if (m_fixed & F_SEAC) op_seac(); if (m_fixed & F_REAC) op_reac(); @@ -758,6 +727,11 @@ void tms1k_base_device::execute_one() if (m_micro & M_AUTY) m_y = m_adder_out & 0xf; if (m_micro & M_STSL) m_status_latch = m_status; + // fixed opcodes with accumulator as destination + if (m_fixed & F_TXA) op_txa(); + if (m_fixed & F_TRA) op_tra(); + if (m_fixed & F_TCA) op_tca(); + // fetch: update pc, ram address 2/2 read_opcode(); m_ram_address = m_x << 4 | m_y; diff --git a/src/devices/cpu/tms1000/tms1k_base.h b/src/devices/cpu/tms1000/tms1k_base.h index 3f753cb0712..ce326fd815b 100644 --- a/src/devices/cpu/tms1000/tms1k_base.h +++ b/src/devices/cpu/tms1000/tms1k_base.h @@ -119,12 +119,20 @@ protected: F_TDO = (1<<13), F_TPC = (1<<14), - F_OFF = (1<<15), - F_REAC = (1<<16), - F_SAL = (1<<17), - F_SBL = (1<<18), - F_SEAC = (1<<19), - F_XDA = (1<<20) + F_TAX = (1<<15), + F_TXA = (1<<16), + F_TRA = (1<<17), + F_TAC = (1<<18), + F_TCA = (1<<19), + F_TADM = (1<<20), + F_TMA = (1<<21), + + F_OFF = (1<<22), + F_REAC = (1<<23), + F_SAL = (1<<24), + F_SBL = (1<<25), + F_SEAC = (1<<26), + F_XDA = (1<<27) }; void rom_10bit(address_map &map); @@ -159,12 +167,21 @@ protected: virtual void op_comc(); virtual void op_tpc(); - virtual void op_xda(); - virtual void op_off(); - virtual void op_seac(); - virtual void op_reac(); - virtual void op_sal(); - virtual void op_sbl(); + + virtual void op_tax() { ; } + virtual void op_txa() { ; } + virtual void op_tra() { ; } + virtual void op_tac() { ; } + virtual void op_tca() { ; } + virtual void op_tadm() { ; } + virtual void op_tma() { ; } + + 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; diff --git a/src/devices/cpu/tms1000/tms2100.cpp b/src/devices/cpu/tms1000/tms2100.cpp index 5e2ba58344e..fe1b42290a6 100644 --- a/src/devices/cpu/tms1000/tms2100.cpp +++ b/src/devices/cpu/tms1000/tms2100.cpp @@ -4,8 +4,25 @@ TMS1000 family - TMS2100, TMS2170, TMS2300, TMS2370 - TODO: - - x +TMS2100 is an enhanced version of TMS1100, adding interrupt, timer, A/D converter, and a 4-level callstack +- the mpla has a similar layout as TMS1400, terms reduced to 26 + (looks like it's optimized and not meant to be custom) +- the opla is the same as TMS1400 + +Extra functions are controlled with the R register (not mapped to pins): +- R15: enable external interrupt +- R16: K/J input select +- R17: load initial value register with TMA +- R18: internal/external counter clock control +- R19: A1/A2 input select +- R20: enable A/D +- R21: R0-R3 I/O control +- R22: R0-R3/ACC2 output select +- R23: enable decrementer load +- R24: enable interrupts + +TODO: +- x */ @@ -13,16 +30,14 @@ #include "tms2100.h" #include "tms1k_dasm.h" -// TMS2100 is an enhanced version of TMS1100, adding interrupt, timer, A/D converter, and a 4-level callstack -// - the mpla has a similar layout as TMS1400, terms reduced to 26 (looks like it's optimized and not meant to be custom) -// - the opla is the same as TMS1400 + +// device definitions DEFINE_DEVICE_TYPE(TMS2100, tms2100_cpu_device, "tms2100", "Texas Instruments TMS2100") // 28-pin DIP, 7 R pins DEFINE_DEVICE_TYPE(TMS2170, tms2170_cpu_device, "tms2170", "Texas Instruments TMS2170") // high voltage version, 1 R pin removed for Vpp DEFINE_DEVICE_TYPE(TMS2300, tms2300_cpu_device, "tms2300", "Texas Instruments TMS2300") // 40-pin DIP, 15 R pins, J pins DEFINE_DEVICE_TYPE(TMS2370, tms2370_cpu_device, "tms2370", "Texas Instruments TMS2370") // high voltage version, 1 R pin removed for Vpp -// device definitions tms2100_cpu_device::tms2100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : tms2100_cpu_device(mconfig, TMS2100, tag, owner, clock, 8 /* o pins */, 7 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 3 /* x width */, 4 /* stack levels */, 11 /* rom width */, address_map_constructor(FUNC(tms2100_cpu_device::rom_11bit), this), 7 /* ram width */, address_map_constructor(FUNC(tms2100_cpu_device::ram_7bit), this)) { } @@ -64,10 +79,72 @@ std::unique_ptr tms2100_cpu_device::create_disassembler( } -// device_reset +// device_start/reset +void tms2100_cpu_device::device_start() +{ + tms1100_cpu_device::device_start(); + + // zerofill + m_ac2 = 0; + m_ivr = 0; + + // register for savestates + save_item(NAME(m_ac2)); + save_item(NAME(m_ivr)); + + state_add(++m_state_count, "AC2", m_ac2).formatstr("%01X"); // 9 +} + void tms2100_cpu_device::device_reset() { tms1100_cpu_device::device_reset(); // changed/added fixed instructions + m_fixed_decode[0x09] = F_TAX; + m_fixed_decode[0x0e] = F_TADM; + m_fixed_decode[0x21] = F_TMA; + m_fixed_decode[0x26] = F_TAC; + m_fixed_decode[0x73] = F_TCA; + m_fixed_decode[0x7b] = F_TRA; +} + + +// opcode deviations +void tms2100_cpu_device::op_tax() +{ + // TAX: transfer accumulator to X register + m_x = m_a & m_x_mask; +} + +void tms2100_cpu_device::op_tra() +{ + // TRA: transfer R inputs to accumulator +} + +void tms2100_cpu_device::op_tac() +{ + // TAC: transfer accumulator to AC2 + m_ac2 = m_a; +} + +void tms2100_cpu_device::op_tca() +{ + // TCA: transfer AC2 to accumulator + m_a = m_ac2; +} + +void tms2100_cpu_device::op_tadm() +{ + // TADM: transfer A/D register to memory +} + +void tms2100_cpu_device::op_tma() +{ + // TMA: if R17 is high, destination is IVR instead of A + if (BIT(m_r, 17)) + { + u8 shift = (m_y & 1) * 4; + m_ivr = (m_ivr & ~(0xf << shift)) | (m_ram_in << shift); + m_micro &= ~M_AUTA; // don't store in A + } } diff --git a/src/devices/cpu/tms1000/tms2100.h b/src/devices/cpu/tms1000/tms2100.h index 0d9656727cf..edc9780dbb3 100644 --- a/src/devices/cpu/tms1000/tms2100.h +++ b/src/devices/cpu/tms1000/tms2100.h @@ -69,10 +69,21 @@ protected: tms2100_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 o_pins, u8 r_pins, u8 pc_bits, u8 byte_bits, u8 x_bits, u8 stack_levels, int rom_width, address_map_constructor rom_map, int ram_width, address_map_constructor ram_map); // overrides + virtual void device_start() override; virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; virtual std::unique_ptr create_disassembler() override; + + virtual void op_tax() override; + virtual void op_tra() override; + virtual void op_tac() override; + virtual void op_tca() override; + virtual void op_tadm() override; + virtual void op_tma() override; + + u8 m_ac2; // 4-bit storage register, or R0-R3 output latch + u8 m_ivr; // initial value register }; class tms2170_cpu_device : public tms2100_cpu_device diff --git a/src/devices/cpu/tms1000/tms2400.cpp b/src/devices/cpu/tms1000/tms2400.cpp index d31d7dd5bbb..a8e78e5a91a 100644 --- a/src/devices/cpu/tms1000/tms2400.cpp +++ b/src/devices/cpu/tms1000/tms2400.cpp @@ -4,8 +4,10 @@ TMS1000 family - TMS2400, TMS2470, TMS2600, TMS2670 - TODO: - - x +TMS2400 is a TMS2100 with twice more memory (kind of like TMS1400 is to TMS1100) + +TODO: +- x */ @@ -13,14 +15,14 @@ #include "tms2400.h" #include "tms1k_dasm.h" -// TMS2400 is a TMS2100 with twice more memory (kind of like TMS1400 is to TMS1100) + +// device definitions DEFINE_DEVICE_TYPE(TMS2400, tms2400_cpu_device, "tms2400", "Texas Instruments TMS2400") // 28-pin DIP, 7 R pins DEFINE_DEVICE_TYPE(TMS2470, tms2470_cpu_device, "tms2470", "Texas Instruments TMS2470") // high voltage version, 1 R pin removed for Vpp DEFINE_DEVICE_TYPE(TMS2600, tms2600_cpu_device, "tms2600", "Texas Instruments TMS2600") // 40-pin DIP, 15 R pins, J pins DEFINE_DEVICE_TYPE(TMS2670, tms2670_cpu_device, "tms2670", "Texas Instruments TMS2670") // high voltage version, 1 R pin removed for Vpp -// device definitions tms2400_cpu_device::tms2400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : tms2400_cpu_device(mconfig, TMS2400, tag, owner, clock, 8 /* o pins */, 7 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 4 /* x width */, 4 /* stack levels */, 12 /* rom width */, address_map_constructor(FUNC(tms2400_cpu_device::rom_12bit), this), 8 /* ram width */, address_map_constructor(FUNC(tms2400_cpu_device::ram_8bit), this)) { } @@ -60,6 +62,8 @@ void tms2400_cpu_device::device_reset() // changed/added fixed instructions m_fixed_decode[0x0b] = F_TPC; + m_fixed_decode[0x75] = F_COMX8; + m_fixed_decode[0x7d] = F_TXA; } @@ -70,3 +74,9 @@ void tms2400_cpu_device::op_ldx() tms2100_cpu_device::op_ldx(); m_x >>= 1; } + +void tms2400_cpu_device::op_txa() +{ + // TXA: transfer X register to accumulator + m_a = m_x; +} diff --git a/src/devices/cpu/tms1000/tms2400.h b/src/devices/cpu/tms1000/tms2400.h index 451c4dd425e..25692d3207e 100644 --- a/src/devices/cpu/tms1000/tms2400.h +++ b/src/devices/cpu/tms1000/tms2400.h @@ -28,6 +28,7 @@ protected: virtual std::unique_ptr create_disassembler() override; virtual void op_ldx() override; + virtual void op_txa() override; }; class tms2470_cpu_device : public tms2400_cpu_device diff --git a/src/devices/cpu/tms1000/tp0320.cpp b/src/devices/cpu/tms1000/tp0320.cpp index 12c4da5eccf..54eb8c368b5 100644 --- a/src/devices/cpu/tms1000/tp0320.cpp +++ b/src/devices/cpu/tms1000/tp0320.cpp @@ -4,8 +4,18 @@ TMS1000 family - TP0320 - TODO: - - lots +TP0320 is TI's first CMOS MCU with integrated LCD controller, the die is still very similar to TMS0980 +- 2048x9bit ROM, same as on TMS0980 with different row-select +- 192x4bit RAM array at the bottom-left (set up as 16x12x4) +- 16x4bit LCD RAM, above main RAM array +- main instructions PLAs at the same position as TMS0980, fixed opcodes: + * LDP, RETN, OFF, bb?, be?, b9?, ba?, RBIT, SBIT, COMX8, bc?, LDX, XDA, TDO, SEAC, REAC, SAL, SBL +- 64-term microinstructions PLA between the RAM and ROM, similar to TMS0980, + plus separate lines for custom opcode handling like TMS0270, used for SETR and RSTR +- 24-term output PLA above LCD RAM + +TODO: +- lots */ @@ -13,18 +23,16 @@ #include "tp0320.h" #include "tms1k_dasm.h" -// TP0320 is TI's first CMOS MCU with integrated LCD controller, the die is still very similar to TMS0980 -// - 2048x9bit ROM, same as on TMS0980 with different row-select -// - 192x4bit RAM array at the bottom-left (set up as 16x12x4) -// - 16x4bit LCD RAM, above main RAM array -// - main instructions PLAs at the same position as TMS0980, fixed opcodes: -// * LDP, RETN, OFF, bb?, be?, b9?, ba?, RBIT, SBIT, COMX8, bc?, LDX, XDA, TDO, SEAC, REAC, SAL, SBL -// - 64-term microinstructions PLA between the RAM and ROM, similar to TMS0980, -// plus separate lines for custom opcode handling like TMS0270, used for SETR and RSTR -// - 24-term output PLA above LCD RAM + +// device definitions DEFINE_DEVICE_TYPE(TP0320, tp0320_cpu_device, "tp0320", "Texas Instruments TP0320") // 28-pin SDIP, .. +tp0320_cpu_device::tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + tms0980_cpu_device(mconfig, TP0320, tag, owner, clock, 7 /* o pins */, 10 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 1 /* stack levels */, 11 /* rom width */, address_map_constructor(FUNC(tp0320_cpu_device::rom_11bit), this), 8 /* ram width */, address_map_constructor(FUNC(tp0320_cpu_device::ram_192x4), this)) +{ } + + // internal memory maps void tp0320_cpu_device::ram_192x4(address_map &map) { @@ -33,12 +41,6 @@ void tp0320_cpu_device::ram_192x4(address_map &map) } -// device definitions -tp0320_cpu_device::tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - tms0980_cpu_device(mconfig, TP0320, tag, owner, clock, 7 /* o pins */, 10 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 1 /* stack levels */, 11 /* rom width */, address_map_constructor(FUNC(tp0320_cpu_device::rom_11bit), this), 8 /* ram width */, address_map_constructor(FUNC(tp0320_cpu_device::ram_192x4), this)) -{ } - - // machine configs void tp0320_cpu_device::device_add_mconfig(machine_config &config) { diff --git a/src/devices/cpu/tms1000/tp0320.h b/src/devices/cpu/tms1000/tp0320.h index 6120ba9efda..710dfb5b787 100644 --- a/src/devices/cpu/tms1000/tp0320.h +++ b/src/devices/cpu/tms1000/tp0320.h @@ -23,8 +23,6 @@ protected: void ram_192x4(address_map &map); // overrides - //virtual void device_start() override; - virtual u32 decode_fixed(u16 op) override { return 0; } // not yet virtual u32 decode_micro(u8 sel) override; virtual void device_reset() override; diff --git a/src/mame/handheld/hh_tms1k.cpp b/src/mame/handheld/hh_tms1k.cpp index df513df1f60..ac5f30df851 100644 --- a/src/mame/handheld/hh_tms1k.cpp +++ b/src/mame/handheld/hh_tms1k.cpp @@ -14269,7 +14269,7 @@ ROM_END * PCB label: TOFL003 * TMS2670 M95041 (die label: TMS2400, M95041, 40H-01D-ND02-PHI0032-TTL O300-R300) * TMS1024 I/O expander - * cyan/red/green VFD display NEC FIP9AM31T no. 21-84, 1-bit sound + * cyan/red/green VFD display NEC FIP9AM31T no. 21-84, 2-bit sound ***************************************************************************/ @@ -14287,29 +14287,57 @@ private: required_device m_expander; void expander_w(offs_t offset, u8 data); + void update_display(); virtual void write_r(u32 data); virtual void write_o(u16 data); }; // handlers +void tgpachi_state::update_display() +{ + m_display->matrix(m_grid, m_plate); +} + void tgpachi_state::expander_w(offs_t offset, u8 data) { + // TMS1024 port 4-7: VFD plate + int shift = (offset - tms1024_device::PORT4) * 4; + m_plate = (m_plate & ~(0xf << shift)) | (data << shift); + update_display(); } void tgpachi_state::write_r(u32 data) { + // R9,R10: TMS1024 S0,S1 (S2 forced high) + // R8: TMS1024 STD + m_expander->write_s((data >> 9 & 3) | 4); + m_expander->write_std(BIT(data, 8)); + + // R0-R7: VFD grid + // R11: 1 more VFD plate + m_grid = data & 0xff; + m_plate = (m_plate & 0xfffff) | (BIT(data, 11) << 20); + update_display(); + + // R13,R14: speaker out } void tgpachi_state::write_o(u16 data) { + // O0-O3: TMS1024 H1-H4 + VFD plate + m_expander->write_h(data & 0xf); + m_plate = (m_plate & ~0xf0000) | (data << 16 & 0xf0000); + update_display(); } // config static INPUT_PORTS_START( tgpachi ) PORT_START("IN.0") // K - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_CONFNAME( 0x01, 0x00, "Factory Test" ) + PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) + PORT_CONFSETTING( 0x01, DEF_STR( On ) ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON2 ) // Slot @@ -14330,7 +14358,7 @@ void tgpachi_state::tgpachi(machine_config &config) m_expander->write_port7_callback().set(FUNC(tgpachi_state::expander_w)); // video hardware - PWM_DISPLAY(config, m_display).set_size(8, 20); + PWM_DISPLAY(config, m_display).set_size(8, 21); config.set_default_layout(layout_hh_tms1k_test); // sound hardware -- cgit v1.2.3