summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/rs232/mboardd.cpp
blob: 2af648bd8319f5fc2742060668623ce585791056 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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")