From f08b0c9c6c08eb72fddf7460d197c67cc663d548 Mon Sep 17 00:00:00 2001 From: arbee Date: Sun, 25 Apr 2021 22:24:44 -0400 Subject: bus/rs232: Preliminary emulation of the Mockingboard D "sound card" for the Apple IIc. [R. Belmont, Apple II Documentation Project] --- scripts/src/bus.lua | 2 + src/devices/bus/rs232/mboardd.cpp | 105 ++++++++++++++++++++++++++++++++++++++ src/devices/bus/rs232/mboardd.h | 45 ++++++++++++++++ src/devices/bus/rs232/rs232.cpp | 2 + 4 files changed, 154 insertions(+) create mode 100644 src/devices/bus/rs232/mboardd.cpp create mode 100644 src/devices/bus/rs232/mboardd.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 27853edd7e9..d98d0b90b48 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -2656,6 +2656,8 @@ if (BUSES["RS232"]~=null) then MAME_DIR .. "src/devices/bus/rs232/exorterm.h", MAME_DIR .. "src/devices/bus/rs232/rs232_sync_io.cpp", MAME_DIR .. "src/devices/bus/rs232/rs232_sync_io.h", + MAME_DIR .. "src/devices/bus/rs232/mboardd.cpp", + MAME_DIR .. "src/devices/bus/rs232/mboardd.h", } end diff --git a/src/devices/bus/rs232/mboardd.cpp b/src/devices/bus/rs232/mboardd.cpp new file mode 100644 index 00000000000..cdbe002c8d1 --- /dev/null +++ b/src/devices/bus/rs232/mboardd.cpp @@ -0,0 +1,105 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont + +/* + mboardd.cpp - Mockingboard D emulation + by R. Belmont + + The Apple IIc didn't have slots, so Sweet Micro Systems came up with this, a Mockingboard + in a little box that attached to the IIc's modem port. There's nothing special about the + IIc though - with a proper cable, anything that speaks 9600 8N1 RS-232 could drive this + device. + + A decent disassembly of the 6803 firmware is available from the Apple II Documentation Project: + https://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Interface%20Cards/Audio/Sweet%20Microsystems%20Mockingboard/Source%20Code/ + +*/ + +#include "emu.h" +#include "mboardd.h" +#include "speaker.h" + +ROM_START(mboardd) + ROM_REGION(0x800, "mbcpu", 0) + ROM_LOAD("mockingboard d rom.bin", 0x000000, 0x000800, CRC(277b1813) SHA1(e8d20f4b59fe867ff76434d35a14d2cbdc8533e3)) +ROM_END + +mockingboard_d_device::mockingboard_d_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SERIAL_MOCKINGBOARD_D, tag, owner, clock) + , device_rs232_port_interface(mconfig, *this) + , m_cpu(*this, "mbdcpu") + , m_ay1(*this, "ay1") + , m_ay2(*this, "ay2") +{ +} + +void mockingboard_d_device::device_add_mconfig(machine_config &config) +{ + M6803(config, m_cpu, 4.9152_MHz_XTAL); // value reverse-engineered from 9600 baud SCI rate needed + m_cpu->set_addrmap(AS_PROGRAM, &mockingboard_d_device::m6803_mem); + m_cpu->in_p2_cb().set(FUNC(mockingboard_d_device::p2_r)); + m_cpu->out_p1_cb().set(FUNC(mockingboard_d_device::p1_w)); + m_cpu->out_ser_tx_cb().set(FUNC(mockingboard_d_device::ser_tx_w)); + + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + AY8913(config, m_ay1, 1022727); + m_ay1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + AY8913(config, m_ay2, 1022727); + m_ay2->add_route(ALL_OUTPUTS, "lspeaker", 0.5); +} + +const tiny_rom_entry *mockingboard_d_device::device_rom_region() const +{ + return ROM_NAME(mboardd); +} + +void mockingboard_d_device::device_start() +{ +} + +void mockingboard_d_device::device_reset() +{ + output_dcd(0); + output_dsr(0); + output_cts(0); +} + +void mockingboard_d_device::m6803_mem(address_map &map) +{ + map(0x8000, 0x83ff).ram(); + // SSI-263 at a000/a001 + map(0xc000, 0xc000).w(FUNC(mockingboard_d_device::c000_w)); + map(0xf800, 0xffff).rom().region("mbcpu", 0); +} + +WRITE_LINE_MEMBER(mockingboard_d_device::input_txd) +{ + m_rx_state = (state & 1); +} + +void mockingboard_d_device::p1_w(u8 data) +{ + if (BIT(data, 3)) + { + m_ay2->address_w(m_c000_latch); + //printf("%02x to AY2 address\n", m_c000_latch); + } + else if (BIT(data, 2)) + { + m_ay2->data_w(m_c000_latch); + //printf("%02x to AY2 data\n", m_c000_latch); + } + else if (BIT(data, 1)) + { + m_ay1->address_w(m_c000_latch); + //printf("%02x to AY1 address\n", m_c000_latch); + } + else if (BIT(data, 0)) + { + m_ay1->data_w(m_c000_latch); + //printf("%02x to AY1 data\n", m_c000_latch); + } +} + +DEFINE_DEVICE_TYPE(SERIAL_MOCKINGBOARD_D, mockingboard_d_device, "mockingboardd", "Sweet Micro Systems Mockingboard D") diff --git a/src/devices/bus/rs232/mboardd.h b/src/devices/bus/rs232/mboardd.h new file mode 100644 index 00000000000..afee0646b42 --- /dev/null +++ b/src/devices/bus/rs232/mboardd.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont + +#ifndef MAME_BUS_RS232_MBOARDD_H +#define MAME_BUS_RS232_MBOARDD_H + +#pragma once + +#include "rs232.h" +#include "cpu/m6800/m6801.h" +#include "sound/ay8910.h" + +class mockingboard_d_device : public device_t, public device_rs232_port_interface +{ +public: + mockingboard_d_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual DECLARE_WRITE_LINE_MEMBER( input_txd ) override; + + required_device m_cpu; + required_device m_ay1; + required_device m_ay2; + +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + +private: + u8 p2_r() { return m_rx_state<<3; }; + void p1_w(u8 data); + + void ser_tx_w(int state) { output_rxd(state); } + + void c000_w(u8 data) { m_c000_latch = data; }; + + void m6803_mem(address_map &map); + int m_rx_state; + u8 m_c000_latch; +}; + +DECLARE_DEVICE_TYPE(SERIAL_MOCKINGBOARD_D, mockingboard_d_device) + +#endif // MAME_BUS_RS232_MBOARDD_H diff --git a/src/devices/bus/rs232/rs232.cpp b/src/devices/bus/rs232/rs232.cpp index ce3446a85b7..828707b0265 100644 --- a/src/devices/bus/rs232/rs232.cpp +++ b/src/devices/bus/rs232/rs232.cpp @@ -172,6 +172,7 @@ device_rs232_port_interface::~device_rs232_port_interface() #include "terminal.h" #include "ie15.h" #include "rs232_sync_io.h" +#include "mboardd.h" void default_rs232_devices(device_slot_interface &device) { @@ -187,4 +188,5 @@ void default_rs232_devices(device_slot_interface &device) device.option_add("sunkbd", SUN_KBD_ADAPTOR); device.option_add("swtpc8212", SERIAL_TERMINAL_SWTPC8212); device.option_add("terminal", SERIAL_TERMINAL); + device.option_add("mockingboard", SERIAL_MOCKINGBOARD_D); } -- cgit v1.2.3