From 96f5a4f9c000854c008d7b7b51bb556a28d73647 Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 7 Jan 2024 15:03:11 -0500 Subject: [PATCH] epic14e: Connect DIP switches properly; add speaker sound --- src/mame/skeleton/epic14e.cpp | 244 +++++++++++++++++++++------------- 1 file changed, 152 insertions(+), 92 deletions(-) diff --git a/src/mame/skeleton/epic14e.cpp b/src/mame/skeleton/epic14e.cpp index 23a1d06aeb9..5eccbdfcf20 100644 --- a/src/mame/skeleton/epic14e.cpp +++ b/src/mame/skeleton/epic14e.cpp @@ -16,8 +16,10 @@ #include "machine/input_merger.h" #include "machine/6522via.h" #include "machine/mos6551.h" +#include "sound/spkrdev.h" #include "video/scn2674.h" #include "screen.h" +#include "speaker.h" namespace { @@ -29,18 +31,29 @@ public: : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_via(*this, "via") + , m_speaker(*this, "speaker") , m_charram(*this, "charram") , m_attrram(*this, "attrram") , m_chargen(*this, "chargen") , m_dsw(*this, "DSW%u", 1U) + , m_pa_select(0) + , m_invert_screen(false) { } void epic14e(machine_config &config); +protected: + virtual void machine_start() override; + private: SCN2672_DRAW_CHARACTER_MEMBER(draw_character); + u8 pa_r(); + void pa_w(u8 data); + void pb_w(u8 data); + void ca2_w(int state); + u8 vram_r(offs_t offset); void vram_w(offs_t offset, u8 data); @@ -50,17 +63,29 @@ private: required_device m_maincpu; required_device m_via; + required_device m_speaker; required_shared_ptr m_charram; required_shared_ptr m_attrram; required_region_ptr m_chargen; required_ioport_array<3> m_dsw; + + u8 m_pa_select; + bool m_invert_screen; }; +void epic14e_state::machine_start() +{ + save_item(NAME(m_pa_select)); + save_item(NAME(m_invert_screen)); +} + SCN2672_DRAW_CHARACTER_MEMBER(epic14e_state::draw_character) { const u8 chardata = m_chargen[charcode << 4 | linecount]; u16 dots = ((chardata & 0x7f) << 2) | (BIT(chardata, 7) ? 3 : 0); + if (m_invert_screen) + dots = ~dots; for (int i = 0; i < 9; i++) { @@ -70,6 +95,31 @@ SCN2672_DRAW_CHARACTER_MEMBER(epic14e_state::draw_character) } +u8 epic14e_state::pa_r() +{ + u8 state = 0x8f; // TODO: PA7 = shift data from keyboard? + for (int n = 0; n < 3; n++) + if (!BIT(m_dsw[n]->read(), m_pa_select)) + state |= 0x10 << n; + return state; +} + +void epic14e_state::pa_w(u8 data) +{ + m_pa_select = data & 0x0f; +} + +void epic14e_state::pb_w(u8 data) +{ + m_speaker->level_w(BIT(data, 7)); +} + +void epic14e_state::ca2_w(int state) +{ + m_invert_screen = !state; +} + + u8 epic14e_state::vram_r(offs_t offset) { return (BIT(offset, 0) ? m_charram : m_attrram)[offset >> 1]; @@ -104,101 +154,104 @@ void epic14e_state::attr_map(address_map &map) static INPUT_PORTS_START(epic14e) PORT_START("DSW1") - PORT_DIPNAME(0x001, 0x001, "Modem Stop Bits") PORT_DIPLOCATION("SW1:1") - PORT_DIPSETTING(0x001, "1") - PORT_DIPSETTING(0x000, "2") - PORT_DIPNAME(0x002, 0x002, "Modem Data Bits") PORT_DIPLOCATION("SW1:2") - PORT_DIPSETTING(0x000, "7") - PORT_DIPSETTING(0x002, "8") - PORT_DIPNAME(0x004, 0x004, "Modem Protocol") PORT_DIPLOCATION("SW1:3") - PORT_DIPSETTING(0x004, "X-ON/X-OFF") - PORT_DIPSETTING(0x000, "CTS") - PORT_DIPNAME(0x078, 0x040, "Modem Baud Rate") PORT_DIPLOCATION("SW1:4,5,6,7") - PORT_DIPSETTING(0x038, "50") - PORT_DIPSETTING(0x058, "75") - PORT_DIPSETTING(0x018, "110") - PORT_DIPSETTING(0x068, "135") - PORT_DIPSETTING(0x028, "150") - PORT_DIPSETTING(0x048, "300") - PORT_DIPSETTING(0x008, "600") - PORT_DIPSETTING(0x070, "1200") - PORT_DIPSETTING(0x030, "1800") - PORT_DIPSETTING(0x050, "2400") - PORT_DIPSETTING(0x010, "3600") - PORT_DIPSETTING(0x060, "4800") - PORT_DIPSETTING(0x020, "7200") - PORT_DIPSETTING(0x040, "9600") - PORT_DIPSETTING(0x000, "19200") - PORT_DIPNAME(0x380, 0x380, "Modem Parity") PORT_DIPLOCATION("SW1:8,9,10") - PORT_DIPSETTING(0x380, "Disable") - PORT_DIPSETTING(0x180, "Odd") - PORT_DIPSETTING(0x080, "Even") - PORT_DIPSETTING(0x100, "Mark") - PORT_DIPSETTING(0x000, "Space") + PORT_DIPNAME(0x0200, 0x0200, "Modem Stop Bits") PORT_DIPLOCATION("SW1:1") + PORT_DIPSETTING(0x0200, "1") + PORT_DIPSETTING(0x0000, "2") + PORT_DIPNAME(0x0100, 0x0100, "Modem Data Bits") PORT_DIPLOCATION("SW1:2") + PORT_DIPSETTING(0x0000, "7") + PORT_DIPSETTING(0x0100, "8") + PORT_DIPNAME(0x0080, 0x0080, "Modem Protocol") PORT_DIPLOCATION("SW1:3") + PORT_DIPSETTING(0x0080, "X-ON/X-OFF") + PORT_DIPSETTING(0x0000, "CTS") + PORT_DIPNAME(0x0078, 0x0008, "Modem Baud Rate") PORT_DIPLOCATION("SW1:7,6,5,4") + PORT_DIPSETTING(0x0070, "50") + PORT_DIPSETTING(0x0068, "75") + PORT_DIPSETTING(0x0060, "110") + PORT_DIPSETTING(0x0058, "135") + PORT_DIPSETTING(0x0050, "150") + PORT_DIPSETTING(0x0048, "300") + PORT_DIPSETTING(0x0040, "600") + PORT_DIPSETTING(0x0038, "1200") + PORT_DIPSETTING(0x0030, "1800") + PORT_DIPSETTING(0x0028, "2400") + PORT_DIPSETTING(0x0020, "3600") + PORT_DIPSETTING(0x0018, "4800") + PORT_DIPSETTING(0x0010, "7200") + PORT_DIPSETTING(0x0008, "9600") + PORT_DIPSETTING(0x0000, "19200") + PORT_DIPNAME(0x0007, 0x0007, "Modem Parity") PORT_DIPLOCATION("SW1:10,9,8") + PORT_DIPSETTING(0x0007, "Disable") + PORT_DIPSETTING(0x0006, "Odd") + PORT_DIPSETTING(0x0004, "Even") + PORT_DIPSETTING(0x0002, "Mark") + PORT_DIPSETTING(0x0000, "Space") + PORT_BIT(0xfc00, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("DSW2") - PORT_DIPNAME(0x001, 0x001, "Auxiliary Stop Bits") PORT_DIPLOCATION("SW2:1") - PORT_DIPSETTING(0x001, "1") - PORT_DIPSETTING(0x000, "2") - PORT_DIPNAME(0x002, 0x002, "Auxiliary Data Bits") PORT_DIPLOCATION("SW2:2") - PORT_DIPSETTING(0x000, "7") - PORT_DIPSETTING(0x002, "8") - PORT_DIPNAME(0x004, 0x004, "Auxiliary Protocol") PORT_DIPLOCATION("SW2:3") - PORT_DIPSETTING(0x004, "X-ON/X-OFF") - PORT_DIPSETTING(0x000, "DTR") - PORT_DIPNAME(0x078, 0x040, "Auxiliary Baud Rate") PORT_DIPLOCATION("SW1:4,5,6,7") - PORT_DIPSETTING(0x038, "50") - PORT_DIPSETTING(0x058, "75") - PORT_DIPSETTING(0x018, "110") - PORT_DIPSETTING(0x068, "135") - PORT_DIPSETTING(0x028, "150") - PORT_DIPSETTING(0x048, "300") - PORT_DIPSETTING(0x008, "600") - PORT_DIPSETTING(0x070, "1200") - PORT_DIPSETTING(0x030, "1800") - PORT_DIPSETTING(0x050, "2400") - PORT_DIPSETTING(0x010, "3600") - PORT_DIPSETTING(0x060, "4800") - PORT_DIPSETTING(0x020, "7200") - PORT_DIPSETTING(0x040, "9600") - PORT_DIPSETTING(0x000, "19200") - PORT_DIPNAME(0x380, 0x380, "Auxiliary Parity") PORT_DIPLOCATION("SW2:8,9,10") - PORT_DIPSETTING(0x380, "Disable") - PORT_DIPSETTING(0x180, "Odd") - PORT_DIPSETTING(0x080, "Even") - PORT_DIPSETTING(0x100, "Mark") - PORT_DIPSETTING(0x000, "Space") + PORT_DIPNAME(0x0200, 0x0200, "Auxiliary Stop Bits") PORT_DIPLOCATION("SW2:1") + PORT_DIPSETTING(0x0200, "1") + PORT_DIPSETTING(0x0000, "2") + PORT_DIPNAME(0x0100, 0x0100, "Auxiliary Data Bits") PORT_DIPLOCATION("SW2:2") + PORT_DIPSETTING(0x0000, "7") + PORT_DIPSETTING(0x0100, "8") + PORT_DIPNAME(0x0080, 0x0080, "Auxiliary Protocol") PORT_DIPLOCATION("SW2:3") + PORT_DIPSETTING(0x0080, "X-ON/X-OFF") + PORT_DIPSETTING(0x0000, "DTR") + PORT_DIPNAME(0x0078, 0x008, "Auxiliary Baud Rate") PORT_DIPLOCATION("SW2:7,6,5,4") + PORT_DIPSETTING(0x0070, "50") + PORT_DIPSETTING(0x0068, "75") + PORT_DIPSETTING(0x0060, "110") + PORT_DIPSETTING(0x0058, "135") + PORT_DIPSETTING(0x0050, "150") + PORT_DIPSETTING(0x0048, "300") + PORT_DIPSETTING(0x0040, "600") + PORT_DIPSETTING(0x0038, "1200") + PORT_DIPSETTING(0x0030, "1800") + PORT_DIPSETTING(0x0028, "2400") + PORT_DIPSETTING(0x0020, "3600") + PORT_DIPSETTING(0x0018, "4800") + PORT_DIPSETTING(0x0010, "7200") + PORT_DIPSETTING(0x0008, "9600") + PORT_DIPSETTING(0x0000, "19200") + PORT_DIPNAME(0x0007, 0x0007, "Auxiliary Parity") PORT_DIPLOCATION("SW2:10,9,8") + PORT_DIPSETTING(0x0007, "Disable") + PORT_DIPSETTING(0x0006, "Odd") + PORT_DIPSETTING(0x0004, "Even") + PORT_DIPSETTING(0x0002, "Mark") + PORT_DIPSETTING(0x0000, "Space") + PORT_BIT(0xfc00, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("DSW3") - PORT_DIPNAME(0x003, 0x003, "Communications Mode") PORT_DIPLOCATION("SW3:1,2") - PORT_DIPSETTING(0x003, "Full Duplex") - PORT_DIPSETTING(0x001, "Half Duplex") - PORT_DIPSETTING(0x002, "Block") - PORT_DIPSETTING(0x000, "Local") - PORT_DIPNAME(0x004, 0x004, "Screen Mode") PORT_DIPLOCATION("SW3:3") - PORT_DIPSETTING(0x004, "Green on Black") - PORT_DIPSETTING(0x000, "Black on Green") - PORT_DIPNAME(0x008, 0x008, "Key Click") PORT_DIPLOCATION("SW3:4") - PORT_DIPSETTING(0x008, DEF_STR(Off)) - PORT_DIPSETTING(0x000, DEF_STR(On)) - PORT_DIPNAME(0x010, 0x010, "Screen Refresh") PORT_DIPLOCATION("SW3:5") - PORT_DIPSETTING(0x000, "50 Hz") - PORT_DIPSETTING(0x010, "60 Hz") - PORT_DIPNAME(0x020, 0x020, "Terminal Emulation") PORT_DIPLOCATION("SW3:6") - PORT_DIPSETTING(0x020, "Epic 14E") - PORT_DIPSETTING(0x000, "Other") - PORT_DIPNAME(0x040, 0x040, "Page/Line Attributes") PORT_DIPLOCATION("SW3:7") - PORT_DIPSETTING(0x040, "Page") - PORT_DIPSETTING(0x000, "Line") - PORT_DIPNAME(0x080, 0x080, "Edit Keys") PORT_DIPLOCATION("SW3:8") - PORT_DIPSETTING(0x080, "Transmitted") - PORT_DIPSETTING(0x000, "Local") - PORT_DIPNAME(0x100, 0x100, "Return Key") PORT_DIPLOCATION("SW3:9") - PORT_DIPSETTING(0x100, "CR") - PORT_DIPSETTING(0x000, "CR/LF") - PORT_DIPNAME(0x200, 0x200, "CRT Saver") PORT_DIPLOCATION("SW3:10") - PORT_DIPSETTING(0x200, DEF_STR(Off)) - PORT_DIPSETTING(0x000, DEF_STR(On)) + PORT_DIPNAME(0x0300, 0x0300, "Communications Mode") PORT_DIPLOCATION("SW3:2,1") + PORT_DIPSETTING(0x0300, "Full Duplex") + PORT_DIPSETTING(0x0200, "Half Duplex") + PORT_DIPSETTING(0x0100, "Block") + PORT_DIPSETTING(0x0000, "Local") + PORT_DIPNAME(0x0080, 0x0080, "Screen Mode") PORT_DIPLOCATION("SW3:3") + PORT_DIPSETTING(0x0080, "Green on Black") + PORT_DIPSETTING(0x0000, "Black on Green") + PORT_DIPNAME(0x0040, 0x0040, "Key Click") PORT_DIPLOCATION("SW3:4") + PORT_DIPSETTING(0x0040, DEF_STR(Off)) + PORT_DIPSETTING(0x0000, DEF_STR(On)) + PORT_DIPNAME(0x0020, 0x0020, "Screen Refresh") PORT_DIPLOCATION("SW3:5") + PORT_DIPSETTING(0x0000, "50 Hz") + PORT_DIPSETTING(0x0020, "60 Hz") + PORT_DIPNAME(0x0010, 0x0010, "Terminal Emulation") PORT_DIPLOCATION("SW3:6") + PORT_DIPSETTING(0x0010, "Epic 14E") + PORT_DIPSETTING(0x0000, "Other") + PORT_DIPNAME(0x0008, 0x0008, "Page/Line Attributes") PORT_DIPLOCATION("SW3:7") + PORT_DIPSETTING(0x0008, "Page") + PORT_DIPSETTING(0x0000, "Line") + PORT_DIPNAME(0x0004, 0x0004, "Edit Keys") PORT_DIPLOCATION("SW3:8") + PORT_DIPSETTING(0x0004, "Transmitted") + PORT_DIPSETTING(0x0000, "Local") + PORT_DIPNAME(0x0002, 0x0002, "Return Key") PORT_DIPLOCATION("SW3:9") + PORT_DIPSETTING(0x0002, "CR") + PORT_DIPSETTING(0x0000, "CR/LF") + PORT_DIPNAME(0x0001, 0x0001, "CRT Saver") PORT_DIPLOCATION("SW3:10") + PORT_DIPSETTING(0x0001, DEF_STR(Off)) + PORT_DIPSETTING(0x0000, DEF_STR(On)) + PORT_BIT(0xfc00, IP_ACTIVE_LOW, IPT_UNUSED) INPUT_PORTS_END @@ -210,8 +263,15 @@ void epic14e_state::epic14e(machine_config &config) INPUT_MERGER_ANY_HIGH(config, "mainirq").output_handler().set_inputline(m_maincpu, m6502_device::IRQ_LINE); MOS6522(config, m_via, 17.01_MHz_XTAL / 9); // SY6522A + m_via->readpa_handler().set(FUNC(epic14e_state::pa_r)); + m_via->writepa_handler().set(FUNC(epic14e_state::pa_w)); + m_via->writepb_handler().set(FUNC(epic14e_state::pb_w)); + m_via->ca2_handler().set(FUNC(epic14e_state::ca2_w)); m_via->irq_handler().set("mainirq", FUNC(input_merger_device::in_w<0>)); + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.5); + I8748(config, "keybmcu", 4608000).set_disable(); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); @@ -256,4 +316,4 @@ ROM_END } // anonymous namespace -COMP(1982, epic14e, 0, 0, epic14e, epic14e, epic14e_state, empty_init, "Epic Computer Products", "Epic 14E (v1.0)", MACHINE_IS_SKELETON) +COMP(1982, epic14e, 0, 0, epic14e, epic14e, epic14e_state, empty_init, "Epic Computer Products", "Epic 14E (v1.0)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE)