From 4e286982252176924f6039b813be66fafebf1409 Mon Sep 17 00:00:00 2001 From: hap Date: Mon, 16 Jan 2023 22:17:11 +0100 Subject: tispeak: move k28m2 to its own file --- src/devices/cpu/pic16c5x/pic16c5x.h | 4 +- src/mame/fidelity/phantom.cpp | 2 +- src/mame/fidelity/vcc.cpp | 4 +- src/mame/handheld/hh_sm510.cpp | 2 +- src/mame/handheld/hh_tms1k.cpp | 13 +- src/mame/handheld/tispeak.cpp | 229 ++----------------------- src/mame/mame.lst | 6 +- src/mame/mess.flt | 1 + src/mame/tiger/k28.cpp | 28 ++- src/mame/tiger/k28m2.cpp | 328 ++++++++++++++++++++++++++++++++++++ 10 files changed, 377 insertions(+), 240 deletions(-) create mode 100644 src/mame/tiger/k28m2.cpp diff --git a/src/devices/cpu/pic16c5x/pic16c5x.h b/src/devices/cpu/pic16c5x/pic16c5x.h index 171890538a1..e4d25f6211f 100644 --- a/src/devices/cpu/pic16c5x/pic16c5x.h +++ b/src/devices/cpu/pic16c5x/pic16c5x.h @@ -139,11 +139,11 @@ private: int m_delay_timer; u16 m_temp_config; int m_rtcc; - int m_count_cycles; + u8 m_count_cycles; u8 m_data_mask; u16 m_program_mask; u8 m_status_mask; - int m_inst_cycles; + u8 m_inst_cycles; memory_access<11, 1, -1, ENDIANNESS_LITTLE>::cache m_program; memory_access< 7, 0, 0, ENDIANNESS_LITTLE>::specific m_data; diff --git a/src/mame/fidelity/phantom.cpp b/src/mame/fidelity/phantom.cpp index 510b94f0209..237e08e9a30 100644 --- a/src/mame/fidelity/phantom.cpp +++ b/src/mame/fidelity/phantom.cpp @@ -547,7 +547,7 @@ static INPUT_PORTS_START( cphantom ) PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Move / No/Stop") PORT_START("IN.1") // motion sensor is inverted here, eg. hold down key to pretend noone's there - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F1) PORT_NAME("Motion Sensor") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_NAME("Motion Sensor") INPUT_PORTS_END diff --git a/src/mame/fidelity/vcc.cpp b/src/mame/fidelity/vcc.cpp index a1a95c6b751..569238dd501 100644 --- a/src/mame/fidelity/vcc.cpp +++ b/src/mame/fidelity/vcc.cpp @@ -8,7 +8,9 @@ Fidelity Voice Chess Challenger series hardware - Grandmaster Voice Chess Challenger (Fidelity Deutschland product) - Decorator Challenger (FCC) -Grandmaster and FCC are verified to be the same PCB + ROMs as UVC. +Grandmaster and FCC are verified to be the same PCB + ROMs as UVC. So even though +they have a large wooden chessboard attached instead of a small plastic one, from +MAME's perspective there's nothing to emulate on top of UVC. ******************************************************************************* diff --git a/src/mame/handheld/hh_sm510.cpp b/src/mame/handheld/hh_sm510.cpp index 13d1bd33382..7afef0819a7 100644 --- a/src/mame/handheld/hh_sm510.cpp +++ b/src/mame/handheld/hh_sm510.cpp @@ -5,7 +5,7 @@ Sharp SM5xx family handhelds. List of child drivers: -- rzone: Tiger R-Zone +- rzone.cpp: Tiger R-Zone The LCD screen graphics are provided internally with an SVG file. MAME external artwork is recommended for the backgrounds inlays. diff --git a/src/mame/handheld/hh_tms1k.cpp b/src/mame/handheld/hh_tms1k.cpp index 1c83c62c621..fe7445673a0 100644 --- a/src/mame/handheld/hh_tms1k.cpp +++ b/src/mame/handheld/hh_tms1k.cpp @@ -6,13 +6,14 @@ This driver is a collection of simple dedicated handheld and tabletop toys based around the TMS1000 MCU series. Anything more complex or clearly part of a series is (or will be) in its own driver, see: -- eva: Chrysler EVA-11 (and EVA-24) -- microvsn: Milton Bradley Microvision -- sag: Entex Select-A-Game Machine +- entex/sag.cpp: Entex Select-A-Game Machine +- miltonbradley/microvsn.cpp: Milton Bradley Microvision +- misc/eva.cpp: Chrysler EVA-11 (and EVA-24) +- tiger/k28m2.cpp: Tiger K28: Talking Learning Computer (model 7-232) (contd.) hh_tms1k child drivers: -- tispellb: TI Spelling B series gen. 1 -- tispeak: TI Speak & Spell series gen. 1 +- tispellb.cpp: TI Spelling B series gen. 1 +- tispeak.cpp: TI Speak & Spell series gen. 1 About the approximated MCU frequency everywhere: The RC osc. is not that stable on most of these handhelds. When comparing multiple video recordings @@ -183,7 +184,7 @@ on Joerg Woerner's datamath.org: http://www.datamath.org/IC_List.htm @MP7304 TMS1400 1982, Tiger 7 in 1 Sports Stadium (model 7-555) @MP7313 TMS1400 1980, Parker Brothers Bank Shot @MP7314 TMS1400 1980, Parker Brothers Split Second - MP7324 TMS1400 1985, Tiger K28/Coleco Talking Teacher -> tispeak.cpp + MP7324 TMS1400 1985, Tiger K28/Coleco Talking Teacher -> tiger/k28m2.cpp @MP7332 TMS1400 1981, Milton Bradley Dark Tower @MP7334 TMS1400 1981, Coleco Total Control 4 @MP7351 TMS1400 1982, Parker Brothers Master Merlin diff --git a/src/mame/handheld/tispeak.cpp b/src/mame/handheld/tispeak.cpp index afa9ba0a927..2a84fdf4182 100644 --- a/src/mame/handheld/tispeak.cpp +++ b/src/mame/handheld/tispeak.cpp @@ -14,6 +14,21 @@ note: except for tntell, MAME external artwork is not required. But it is objectively a large improvement. + TODO: + - disconnect from hh_tms1k_state, split driver and move to ti folder + - why doesn't lantransp work? maybe incompatible with released modules? + - emulate other known devices + + Dick Smith catalog numbers, taken from advertisements: + + X-1300, Y-1300 : T.I. Speak & Spell + X-1301 : Super Stumper 1 (for Speak & Spell) + X-1302 : Super Stumper 2 (for Speak & Spell) + X-1305 : Vowel Power (for Speak & Spell) + Y-1310 : T.I. Speak & Math + Y-1313 : T.I. Speak & Read + Y-1320 : T.I. Dataman + ---------------------------------------------------------------------------- Known devices on this hardware: (* denotes not dumped) @@ -382,54 +397,6 @@ Language Teacher modules (only 1 known released): - German For Travel: VSM: 16KB CD3509 - -Other manufacturers: - -Tiger Electronics K28 (model 7-232) Sold in Hong Kong, distributed in US as: -- Coleco: Talking Teacher -- Sears: Talkatron - Learning Computer - -1981 K28 models 7-230 and 7-231 are on different hardware, showing a different -keyboard, VFD, and use the SC-01 speech chip. --> driver tiger/k28.cpp - - K28 model 7-232 (HK), 1985 - - MCU: TMS1400 MP7324 (die label: TMS1400, MP7324, 28L 01D D000 R100) - - TMS51xx: TMS5110A - - VSM: 16KB CM62084 - - LCD: SMOS SMC1112 MCU to 8*14-seg display - -K28 modules: - - - Spelling I: VSM: 16KB CM62086 - - Spelling II: VSM: 16KB CM62085? - - Spelling III: VSM: 16KB CM62087 - - Expansion Module 1: VSM: 16KB CM62214? - assumed same VSM as CM62086 - - Expansion Module 2: VSM: 16KB CM62216 - assumed same VSM as the one in Spelling II - - Expansion Module 3: VSM: 16KB CM62215 - same VSM as CM62087 - - Expansion Module 4: VSM: 16KB CM62217 - - Expansion Module 5: VSM: 16KB CM62218* - - Expansion Module 6: VSM: 16KB CM62219 - - note: these won't work on the 1981 version(s) - ----------------------------------------------------------------------------- - - TODO: - - why doesn't lantransp work? maybe incompatible with released modules? - - emulate k28 LCD - - emulate other known devices - - -Dick Smith catalog numbers, taken from advertisements: - -X-1300, Y-1300 : T.I. Speak & Spell -X-1301 : Super Stumper 1 (for Speak & Spell) -X-1302 : Super Stumper 2 (for Speak & Spell) -X-1305 : Vowell Power (for Speak & Spell) -Y-1310 : T.I. Speak & Math -Y-1313 : T.I. Speak & Read -Y-1320 : T.I. Dataman - ***************************************************************************/ #include "emu.h" @@ -440,12 +407,12 @@ Y-1320 : T.I. Dataman #include "machine/timer.h" #include "machine/tms6100.h" #include "sound/tms5110.h" + #include "softlist_dev.h" #include "speaker.h" #include "render.h" // internal artwork -#include "k28m2.lh" #include "snmath.lh" #include "snread.lh" #include "snspell.lh" @@ -493,7 +460,6 @@ public: void vocaid(machine_config &config); void lantrans(machine_config &config); void lanteach(machine_config &config); - void k28m2(machine_config &config); private: virtual void power_off() override; @@ -510,18 +476,11 @@ private: void snspellc_write_r(u32 data); u8 tntell_read_k(); - void k28_update_display(u8 old, u8 data); - u8 k28_read_k(); - void k28_write_o(u16 data); - void k28_write_r(u32 data); - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load); u8 tntell_get_hexchar(const char c); TIMER_DEVICE_CALLBACK_MEMBER(tntell_get_overlay); - void init_cartridge(); - virtual void machine_start() override; // devices @@ -543,7 +502,6 @@ void tispeak_state::machine_start() hh_tms1k_state::machine_start(); m_ol_out.resolve(); - init_cartridge(); } @@ -554,17 +512,6 @@ void tispeak_state::machine_start() ***************************************************************************/ -void tispeak_state::init_cartridge() -{ - if (m_cart != nullptr && m_cart->exists()) - { - std::string region_tag; - memory_region *src = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str()); - if (src) - memcpy(m_cart_base, src->base(), src->bytes()); - } -} - DEVICE_IMAGE_LOAD_MEMBER(tispeak_state::cart_load) { u32 size = m_cart->common_get_size("rom"); @@ -575,9 +522,7 @@ DEVICE_IMAGE_LOAD_MEMBER(tispeak_state::cart_load) return image_init_result::FAIL; } - m_cart->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - m_cart->common_load_rom(m_cart->get_rom_base(), size, "rom"); - + m_cart->common_load_rom(m_cart_base, size, "rom"); return image_init_result::PASS; } @@ -760,48 +705,6 @@ TIMER_DEVICE_CALLBACK_MEMBER(tispeak_state::tntell_get_overlay) } -// k28 specific - -void tispeak_state::k28_update_display(u8 old, u8 data) -{ - // ? -} - -void tispeak_state::k28_write_r(u32 data) -{ - // R1234: TMS5100 CTL8421 - u16 r = bitswap<5>(data,0,1,2,3,4) | (data & ~0x1f); - m_tms5100->ctl_w(r & 0xf); - - // R0: TMS5100 PDC pin - m_tms5100->pdc_w(data & 1); - - // R5: input mux high bit - m_inp_mux = (m_inp_mux & 0xff) | (data << 3 & 0x100); - - // R7-R10: LCD data - k28_update_display(m_r >> 7 & 0xf, data >> 7 & 0xf); - - // R6: power-off request, on falling edge - if (~data & m_r & 0x40) - power_off(); - - m_r = r; -} - -void tispeak_state::k28_write_o(u16 data) -{ - // O0-O7: input mux low - m_inp_mux = (m_inp_mux & ~0xff) | data; -} - -u8 tispeak_state::k28_read_k() -{ - // K: TMS5100 CTL, multiplexed inputs (also tied to R1234) - return m_tms5100->ctl_r() | read_inputs(9) | (m_r & 0xf); -} - - /*************************************************************************** @@ -1251,63 +1154,6 @@ static INPUT_PORTS_START( tntell ) INPUT_PORTS_END -static INPUT_PORTS_START( k28m2 ) - PORT_START("IN.0") // O0 - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_NAME("Off") // -> auto_power_off - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('A') PORT_NAME("A/1") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('J') PORT_NAME("J/0") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') - - PORT_START("IN.1") // O1 - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_NAME("On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, power_button, true) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('B') PORT_NAME("B/2") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('K') PORT_NAME("K/+") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') - - PORT_START("IN.2") // O2 - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_NAME("Repeat") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('C') PORT_NAME("C/3") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR('L') PORT_NAME("L/-") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') - - PORT_START("IN.3") // O3 - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_NAME("Prompt") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('D') PORT_NAME("D/4") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('M') PORT_NAME(u8"M/×") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') - - PORT_START("IN.4") // O4 - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_HOME) PORT_NAME("Menu") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('E') PORT_NAME("E/5") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR('N') PORT_NAME(u8"N/÷") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') - - PORT_START("IN.5") // O5 - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_END) PORT_NAME("Module") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('F') PORT_NAME("F/6") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') - - PORT_START("IN.6") // O6 - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_NAME("Select") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('G') PORT_NAME("G/7") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') - - PORT_START("IN.7") // O7 - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("Clear") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('H') PORT_NAME("H/8") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') - - PORT_START("IN.8") // R5 - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('I') PORT_NAME("I/9") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter") -INPUT_PORTS_END - - /*************************************************************************** @@ -1520,31 +1366,6 @@ void tispeak_state::tntell(machine_config &config) } -void tispeak_state::k28m2(machine_config &config) -{ - // basic machine hardware - TMS1400(config, m_maincpu, MASTER_CLOCK/2); - m_maincpu->read_k().set(FUNC(tispeak_state::k28_read_k)); - m_maincpu->write_o().set(FUNC(tispeak_state::k28_write_o)); - m_maincpu->write_r().set(FUNC(tispeak_state::k28_write_r)); - - config.set_default_layout(layout_k28m2); - - // sound hardware - TMS6100(config, m_tms6100, MASTER_CLOCK/4); - - SPEAKER(config, "mono").front_center(); - TMS5110A(config, m_tms5100, MASTER_CLOCK); - tms5110_route(config); - - // cartridge - GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, "k28m2", "vsm,bin"); - m_cart->set_device_load(FUNC(tispeak_state::cart_load)); - - SOFTWARE_LIST(config, "cart_list").set_original("k28m2"); -} - - /*************************************************************************** @@ -1929,20 +1750,6 @@ ROM_START( vocaid ) ROM_LOAD( "cd2357.vsm", 0x0000, 0x4000, CRC(19c251fa) SHA1(8f8163069f32413379e7e1681ce6a4d0819d4ebc) ) ROM_END - -ROM_START( k28m2 ) - ROM_REGION( 0x1000, "maincpu", 0 ) - ROM_LOAD( "mp7324", 0x0000, 0x1000, CRC(08d15ab6) SHA1(5b0f6c53e6732a362c4bb25d966d4072fdd33db8) ) - - ROM_REGION( 867, "maincpu:mpla", 0 ) - ROM_LOAD( "tms1100_common1_micro.pla", 0, 867, CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) ) - ROM_REGION( 557, "maincpu:opla", 0 ) - ROM_LOAD( "tms1400_k28m2_output.pla", 0, 557, CRC(3a5c7005) SHA1(3fe5819c138a90e7fc12817415f2622ca81b40b2) ) - - ROM_REGION( 0x10000, "tms6100", ROMREGION_ERASEFF ) // 8000-bfff? = space reserved for cartridge - ROM_LOAD( "cm62084.vsm", 0x0000, 0x4000, CRC(cd1376f7) SHA1(96fa484c392c451599bc083b8376cad9c998df7d) ) -ROM_END - } // anonymous namespace @@ -1980,5 +1787,3 @@ COMP( 1981, tntelluk, tntell, 0, tntell, tntell, tispeak_state, in COMP( 1981, tntellfr, tntell, 0, tntell, tntell, tispeak_state, init_tntell, "Texas Instruments", "Le Livre Magique (France)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND | MACHINE_CLICKABLE_ARTWORK | MACHINE_REQUIRES_ARTWORK ) COMP( 1982, vocaid, 0, 0, vocaid, tntell, tispeak_state, empty_init, "Texas Instruments", "Vocaid", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND | MACHINE_REQUIRES_ARTWORK ) - -COMP( 1985, k28m2, 0, 0, k28m2, k28m2, tispeak_state, init_snspell, "Tiger Electronics", "K28: Talking Learning Computer (model 7-232)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 16a7fca87b5..22f9f511cf0 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -19623,7 +19623,10 @@ movmastr // k1003 // @source:tiger/k28.cpp -k28 // Tiger Electronics +k28 + +@source:tiger/k28m2.cpp +k28m2 @source:robotron/k8915.cpp k8915 // @@ -42118,7 +42121,6 @@ ts2068 // 1983 TS2068 uk2086 // 1986 UK2086 @source:handheld/tispeak.cpp -k28m2 // Tiger Electronics lanteach // lantrans // lantransp // diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 64c3040f73d..5af8ebf827f 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -1083,6 +1083,7 @@ ti/ti990_4.cpp ti/tm990189.cpp tiger/gamecom.cpp tiger/k28.cpp +tiger/k28m2.cpp tigertel/gizmondo.cpp tiki/tiki100.cpp tomy/tomy_princ.cpp diff --git a/src/mame/tiger/k28.cpp b/src/mame/tiger/k28.cpp index f9be588d9a6..0c30952954d 100644 --- a/src/mame/tiger/k28.cpp +++ b/src/mame/tiger/k28.cpp @@ -13,7 +13,7 @@ Tiger Electronics K28: Talking Learning Computer (model 7-230/7-231) 3 models exist: - 7-230: darkblue case, toy-ish looks - 7-231: gray case, hardware is the same -- 7-232: this one is completely different hw --> driver handheld/tispeak.cpp +- 7-232: this one is completely different hw --> driver k28m2.cpp TODO: - external module support (no dumps yet) @@ -21,12 +21,14 @@ TODO: ******************************************************************************/ #include "emu.h" + #include "cpu/mcs48/mcs48.h" +#include "machine/timer.h" +#include "machine/tms6100.h" #include "video/mm5445.h" #include "video/pwm.h" -#include "machine/tms6100.h" -#include "machine/timer.h" #include "sound/votrax.h" + #include "speaker.h" // internal artwork @@ -82,18 +84,8 @@ private: void power_off(); }; - -// machine start/reset/power - void k28_state::machine_start() { - // zerofill - m_power_on = false; - m_inp_mux = 0; - m_phoneme = 0x3f; - m_speech_strobe = 0; - m_vfd_data = 0; - // register for savestates save_item(NAME(m_power_on)); save_item(NAME(m_inp_mux)); @@ -102,6 +94,12 @@ void k28_state::machine_start() save_item(NAME(m_vfd_data)); } + + +/****************************************************************************** + Power +******************************************************************************/ + void k28_state::machine_reset() { m_power_on = true; @@ -139,7 +137,7 @@ void k28_state::vfd_output_w(u64 data) m_display->matrix(data >> 16, seg_data); // O26: power-off request on falling edge - if (~data & m_vfd_data & 0x2000000) + if (~data & m_vfd_data & 1 << 25) power_off(); m_vfd_data = data; } @@ -179,7 +177,7 @@ u8 k28_state::mcu_p1_r() // multiplexed inputs (active low) for (int i = 0; i < 7; i++) - if (m_inp_mux >> i & 1) + if (BIT(m_inp_mux, i)) { data |= m_inputs[i]->read(); diff --git a/src/mame/tiger/k28m2.cpp b/src/mame/tiger/k28m2.cpp new file mode 100644 index 00000000000..80451ff1a45 --- /dev/null +++ b/src/mame/tiger/k28m2.cpp @@ -0,0 +1,328 @@ +// license:BSD-3-Clause +// copyright-holders:hap +// thanks-to:Sean Riddle, David Viens, Kevin Horton +/****************************************************************************** + +Tiger Electronics K28 (model 7-232) Sold in Hong Kong, distributed in US as: +- Coleco: Talking Teacher +- Sears: Talkatron: Learning Computer + +K28 model 7-232 (HK), 1985 +- MCU: TMS1400 MP7324 (die label: TMS1400, MP7324, 28L 01D D000 R100) +- TMS51xx: TMS5110A +- VSM: 16KB CM62084 +- LCD: SMOS SMC1112 MCU to 8*14-seg display + +1981 K28 models 7-230 and 7-231 are on different hardware, showing a different +keyboard, VFD, and use the SC-01 speech chip. --> driver k28.cpp + +K28 modules: (* denotes not dumped) +- Spelling I: VSM: 16KB CM62086 +- Spelling II: VSM: 16KB CM62085? +- Spelling III: VSM: 16KB CM62087 +- Expansion Module 1: VSM: 16KB CM62214? - assumed same VSM as CM62086 +- Expansion Module 2: VSM: 16KB CM62216 - assumed same VSM as the one in Spelling II +- Expansion Module 3: VSM: 16KB CM62215 - same VSM as CM62087 +- Expansion Module 4: VSM: 16KB CM62217 +- Expansion Module 5: VSM: 16KB CM62218* +- Expansion Module 6: VSM: 16KB CM62219 + +note: these won't work on the 1981 version(s) + +TODO: +- emulate LCD + +******************************************************************************/ + +#include "emu.h" + +#include "bus/generic/carts.h" +#include "bus/generic/slot.h" +#include "cpu/tms1000/tms1400.h" +#include "machine/tms6100.h" +#include "sound/tms5110.h" + +#include "softlist_dev.h" +#include "speaker.h" + +// internal artwork +#include "k28m2.lh" + + +namespace { + +class k28m2_state : public driver_device +{ +public: + k28m2_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_tms5100(*this, "tms5100"), + m_tms6100(*this, "tms6100"), + m_cart(*this, "cartslot"), + m_inputs(*this, "IN.%u", 0) + { } + + void k28m2(machine_config &config); + + DECLARE_INPUT_CHANGED_MEMBER(power_on); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + // devices/pointers + required_device m_maincpu; + required_device m_tms5100; + required_device m_tms6100; + optional_device m_cart; + required_ioport_array<9> m_inputs; + + void update_display(u8 old, u8 data); + u8 read_k(); + void write_o(u16 data); + void write_r(u32 data); + + DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load); + void power_off(); + + bool m_power_on = false; + u16 m_inp_mux = 0; + u32 m_r = 0; +}; + +void k28m2_state::machine_start() +{ + // register for savestates + save_item(NAME(m_power_on)); + save_item(NAME(m_inp_mux)); + save_item(NAME(m_r)); +} + + + +/****************************************************************************** + Power +******************************************************************************/ + +void k28m2_state::machine_reset() +{ + m_power_on = true; + m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); +} + +INPUT_CHANGED_MEMBER(k28m2_state::power_on) +{ + if (newval && !m_power_on) + machine_reset(); +} + +void k28m2_state::power_off() +{ + m_power_on = false; + m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); +} + + + +/****************************************************************************** + Cartridge +******************************************************************************/ + +DEVICE_IMAGE_LOAD_MEMBER(k28m2_state::cart_load) +{ + u32 size = m_cart->common_get_size("rom"); + + if (size > 0x4000) + { + image.seterror(image_error::INVALIDIMAGE, "Invalid file size"); + return image_init_result::FAIL; + } + + u8 *base = memregion("tms6100")->base() + 0x8000; + m_cart->common_load_rom(base, size, "rom"); + + return image_init_result::PASS; +} + + + +/****************************************************************************** + I/O +******************************************************************************/ + +void k28m2_state::update_display(u8 old, u8 data) +{ + // ? +} + +void k28m2_state::write_r(u32 data) +{ + // R1234: TMS5100 CTL8421 + u32 r = bitswap<5>(data,0,1,2,3,4) | (data & ~0x1f); + m_tms5100->ctl_w(r & 0xf); + + // R0: TMS5100 PDC pin + m_tms5100->pdc_w(data & 1); + + // R5: input mux high bit + m_inp_mux = (m_inp_mux & 0xff) | (data << 3 & 0x100); + + // R7-R10: LCD data + update_display(m_r >> 7 & 0xf, data >> 7 & 0xf); + + // R6: power-off request, on falling edge + if (~data & m_r & 0x40) + power_off(); + + m_r = r; +} + +void k28m2_state::write_o(u16 data) +{ + // O0-O7: input mux low + m_inp_mux = (m_inp_mux & ~0xff) | data; +} + +u8 k28m2_state::read_k() +{ + u8 data = 0; + + // K: multiplexed inputs + for (int i = 0; i < 9; i++) + if (BIT(m_inp_mux, i)) + data |= m_inputs[i]->read(); + + // and TMS5100 CTL (also tied to R1234) + return data | m_tms5100->ctl_r() | (m_r & 0xf); +} + + + +/****************************************************************************** + Input Ports +******************************************************************************/ + +static INPUT_PORTS_START( k28m2 ) + PORT_START("IN.0") // O0 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_NAME("Off") // -> auto_power_off + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('A') PORT_NAME("A/1") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('J') PORT_NAME("J/0") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') + + PORT_START("IN.1") // O1 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_NAME("On") PORT_CHANGED_MEMBER(DEVICE_SELF, k28m2_state, power_on, 0) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('B') PORT_NAME("B/2") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('K') PORT_NAME("K/+") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') + + PORT_START("IN.2") // O2 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_NAME("Repeat") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('C') PORT_NAME("C/3") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR('L') PORT_NAME("L/-") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') + + PORT_START("IN.3") // O3 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_NAME("Prompt") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('D') PORT_NAME("D/4") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('M') PORT_NAME(u8"M/×") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') + + PORT_START("IN.4") // O4 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_HOME) PORT_NAME("Menu") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('E') PORT_NAME("E/5") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR('N') PORT_NAME(u8"N/÷") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') + + PORT_START("IN.5") // O5 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_END) PORT_NAME("Module") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('F') PORT_NAME("F/6") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') + + PORT_START("IN.6") // O6 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_NAME("Select") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('G') PORT_NAME("G/7") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + + PORT_START("IN.7") // O7 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("Clear") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('H') PORT_NAME("H/8") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') + + PORT_START("IN.8") // R5 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('I') PORT_NAME("I/9") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter") +INPUT_PORTS_END + + + +/****************************************************************************** + Machine Configs +******************************************************************************/ + +void k28m2_state::k28m2(machine_config &config) +{ + static constexpr u32 MASTER_CLOCK = 640'000; // approximation + + // basic machine hardware + TMS1400(config, m_maincpu, MASTER_CLOCK/2); + m_maincpu->read_k().set(FUNC(k28m2_state::read_k)); + m_maincpu->write_o().set(FUNC(k28m2_state::write_o)); + m_maincpu->write_r().set(FUNC(k28m2_state::write_r)); + + config.set_default_layout(layout_k28m2); + + // sound hardware + TMS6100(config, m_tms6100, MASTER_CLOCK/4); + + SPEAKER(config, "mono").front_center(); + TMS5110A(config, m_tms5100, MASTER_CLOCK); + m_tms5100->m0().set(m_tms6100, FUNC(tms6100_device::m0_w)); + m_tms5100->m1().set(m_tms6100, FUNC(tms6100_device::m1_w)); + m_tms5100->addr().set(m_tms6100, FUNC(tms6100_device::add_w)); + m_tms5100->data().set(m_tms6100, FUNC(tms6100_device::data_line_r)); + m_tms5100->romclk().set(m_tms6100, FUNC(tms6100_device::clk_w)); + m_tms5100->add_route(ALL_OUTPUTS, "mono", 0.5); + + // cartridge + GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, "k28m2", "vsm,bin"); + m_cart->set_device_load(FUNC(k28m2_state::cart_load)); + + SOFTWARE_LIST(config, "cart_list").set_original("k28m2"); +} + + + +/****************************************************************************** + ROM Definitions +******************************************************************************/ + +ROM_START( k28m2 ) + ROM_REGION( 0x1000, "maincpu", 0 ) + ROM_LOAD( "mp7324", 0x0000, 0x1000, CRC(08d15ab6) SHA1(5b0f6c53e6732a362c4bb25d966d4072fdd33db8) ) + + ROM_REGION( 867, "maincpu:mpla", 0 ) + ROM_LOAD( "tms1100_common1_micro.pla", 0, 867, CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) ) + ROM_REGION( 557, "maincpu:opla", 0 ) + ROM_LOAD( "tms1400_k28m2_output.pla", 0, 557, CRC(3a5c7005) SHA1(3fe5819c138a90e7fc12817415f2622ca81b40b2) ) + + ROM_REGION( 0x10000, "tms6100", ROMREGION_ERASEFF ) // 8000-bfff? = space reserved for cartridge + ROM_LOAD( "cm62084.vsm", 0x0000, 0x4000, CRC(cd1376f7) SHA1(96fa484c392c451599bc083b8376cad9c998df7d) ) +ROM_END + +} // anonymous namespace + + + +/****************************************************************************** + Drivers +******************************************************************************/ + +// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS +COMP( 1985, k28m2, 0, 0, k28m2, k28m2, k28m2_state, empty_init, "Tiger Electronics", "K28: Talking Learning Computer (model 7-232)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING ) -- cgit v1.2.3