diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 3ad7dd9413a..956a1a3e305 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -3359,6 +3359,7 @@ files { MAME_DIR .. "src/mame/drivers/cvicny.cpp", MAME_DIR .. "src/mame/drivers/datum.cpp", MAME_DIR .. "src/mame/drivers/dolphunk.cpp", + MAME_DIR .. "src/mame/drivers/emma2.cpp", MAME_DIR .. "src/mame/drivers/instruct.cpp", MAME_DIR .. "src/mame/drivers/mk14.cpp", MAME_DIR .. "src/mame/drivers/pro80.cpp", diff --git a/src/mame/drivers/emma2.cpp b/src/mame/drivers/emma2.cpp new file mode 100644 index 00000000000..7c9b87ce5ca --- /dev/null +++ b/src/mame/drivers/emma2.cpp @@ -0,0 +1,232 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** + +Emma and Emma II by L.J.Technical Systems +These were produced by L.J.Electronics Ltd, Norwich in 1979. + +2018-09-20 Skeleton driver. + +We don't have roms for the Emma, so only the Emma II is emulated. + +Keys: +0-9,A-F: hex input +M : memory mode (modify address, or modify data) +G : go +R : single step (not emulated) +P : insert a forced break +S : save to cassette +L : load from cassette ++ : up (use UP-arrow key) +- : down (use DOWN-arrow key) + +Pasting example: +M0020M01^02^03^04^05^06^07^08^09^M000020 +Press up arrow to see your input. + +To save, press S, enter beginning address, press S, enter end address+1, +press S, start the recorder, press 0 for 300 baud or 1 for 1200 baud. The +data is saved. + +To load, press L, press play, while leader is playing press 0 or 1 as above. +When a row of dots appears, the data has been loaded. + + +There's an expansion unit with its own rom, a 8255, an eprom programmer, +and 16k of static RAM. + + + +To Do: +- Cassette LED doesn't work. +- Code up the expansion unit (rom is there but no schematic exists) + +****************************************************************************/ + +#include "emu.h" +#include "cpu/m6502/m6502.h" +#include "machine/6522via.h" +#include "machine/6821pia.h" +#include "imagedev/cassette.h" +#include "sound/wave.h" +#include "speaker.h" +#include "emma2.lh" + + +class emma2_state : public driver_device +{ +public: + emma2_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_cassette(*this, "cassette") + , m_via(*this, "via") + , m_pia(*this, "pia") + , m_keyboard(*this, "X%u", 0) + , m_digits(*this, "digit%u", 0U) + { } + + void emma2(machine_config &config); + +private: + DECLARE_WRITE8_MEMBER(segment_w); + DECLARE_WRITE8_MEMBER(digit_w); + DECLARE_READ8_MEMBER(keyboard_r); + virtual void machine_reset() override; + virtual void machine_start() override; + + void mem_map(address_map &map); + + uint8_t m_digit; + bool m_dig_change; + required_device m_maincpu; + required_device m_cassette; + required_device m_via; + required_device m_pia; + required_ioport_array<8> m_keyboard; + output_finder<8> m_digits; +}; + +void emma2_state::mem_map(address_map &map) +{ + map.unmap_value_high(); + map(0x0000, 0x03ff).ram(); + map(0x0900, 0x090f).mirror(0x02f0).rw(m_via, FUNC(via6522_device::read), FUNC(via6522_device::write)); + map(0x0a00, 0x0a03).mirror(0x00fc).rw(m_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0x0c00, 0x0fff).ram(); + map(0xd800, 0xdfff).mirror(0x2000).rom(); +} + + +/* Input ports */ +static INPUT_PORTS_START( emma2 ) +/* +M L 0 4 8 C +G R 1 5 9 D +P + 2 6 A E +S - 3 7 B F +*/ + + PORT_START("X0") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + + PORT_START("X1") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') + + PORT_START("X2") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') + + PORT_START("X3") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') + + PORT_START("X4") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') + + PORT_START("X5") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') + + PORT_START("X6") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR('^') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') + + PORT_START("X7") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR('V') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') +INPUT_PORTS_END + + +WRITE8_MEMBER( emma2_state::digit_w ) +{ + m_cassette->output( BIT(data, 6) ? +1.0 : -1.0); + + data &= 7; + if (data != m_digit) + { + m_digit = data; + m_dig_change = true; + } +} + +WRITE8_MEMBER( emma2_state::segment_w ) +{ + if (m_dig_change) + { + m_dig_change = false; + m_digits[m_digit] = data; + } +} + +READ8_MEMBER( emma2_state::keyboard_r ) +{ + u8 data = m_keyboard[m_digit]->read(); + data |= ((m_cassette)->input() < 0.0) ? 0x80 : 0; + return data; +} + +void emma2_state::machine_start() +{ + m_digits.resolve(); +} + +void emma2_state::machine_reset() +{ + m_digit = 0; + m_dig_change = 0; +} + +MACHINE_CONFIG_START(emma2_state::emma2) + /* basic machine hardware */ + MCFG_DEVICE_ADD("maincpu", M6502, 1'000'000) + MCFG_DEVICE_PROGRAM_MAP(mem_map) + + /* video hardware */ + config.set_default_layout(layout_emma2); + + /* Devices */ + VIA6522(config, m_via, 1'000'000); // #2 from cpu + m_via->irq_handler().set_inputline(m_maincpu, m6502_device::IRQ_LINE); + + PIA6821(config, m_pia, 0); + m_pia->writepa_handler().set(FUNC(emma2_state::segment_w)); + m_pia->writepb_handler().set(FUNC(emma2_state::digit_w)); + m_pia->readpb_handler().set(FUNC(emma2_state::keyboard_r)); + m_pia->ca2_handler().set([this] (bool state) { output().set_value("led0", state); }); + m_pia->irqa_handler().set_inputline(m_maincpu, m6502_device::IRQ_LINE); + m_pia->irqb_handler().set_inputline(m_maincpu, m6502_device::IRQ_LINE); + + /* cassette */ + MCFG_CASSETTE_ADD( "cassette" ) + MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED) + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + WAVE(config, "wave", "cassette").add_route(ALL_OUTPUTS, "mono", 0.05); +MACHINE_CONFIG_END + + +/* ROM definition */ +ROM_START( emma2 ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) + ROM_LOAD( "se118a_90-97", 0x9000, 0x0800, CRC(32d36938) SHA1(910fd1c18c7deae83933c7c4f397103a35bf574a) ) + ROM_LOAD( "se116a_d8-dd_fe-ff", 0xd800, 0x0800, CRC(ef0f1513) SHA1(46089ba0402828b4204812a04134b313d9be0f93) ) +ROM_END + + +/* Driver */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1979, emma2, 0, 0, emma2, emma2, emma2_state, empty_init, "L.J.Technical Systems", "Emma II trainer", 0 ) diff --git a/src/mame/layout/emma2.lay b/src/mame/layout/emma2.lay new file mode 100644 index 00000000000..0d60ebe4732 --- /dev/null +++ b/src/mame/layout/emma2.lay @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 384bd1bef8e..e2f807b31b3 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -12324,6 +12324,9 @@ emate // (c) 1997 Apple Computer @source:embargo.cpp embargo // +@source:emma2.cpp +emma2 // 1979 L.J.Technical Systems + @source:enigma2.cpp enigma2 // (c) 1981 Game Plan (Zilec Electronics license) enigma2a // (c) 1984 Zilec Electronics (bootleg?) diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 4ffad605533..75e8efb07fa 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -203,6 +203,7 @@ elektronmono.cpp elf.cpp elwro800.cpp emate.cpp +emma2.cpp enmirage.cpp ep64.cpp esprit.cpp