mame/apple: Added preliminary Apple DFAC audio filter/volume implementation. [R. Belmont]

- Initial DFAC with volume control and master on/off
- Hooked up to LC, LC II, LC III, IIvx, IIvi, Quadra 700, Quadra 800
This commit is contained in:
arbee 2024-06-17 21:49:58 -04:00
parent 3f3275dcf3
commit 8517445efa
15 changed files with 370 additions and 32 deletions

170
src/mame/apple/dfac.cpp Normal file
View File

@ -0,0 +1,170 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/***************************************************************************
dfac.cpp - Apple Digitally Filtered Audio Chip, which controls input and
output gain and filtering.
DFAC uses a 3-wire serial interface, where it caches the last
8 bits seen over a data/clock pair and writes that byte to the
working space when a low/high transition occurs on a third
"latch" line.
________________________
/ 4 3 2 1 28 27 26 |
| * |
| 5 25 |
| 6 344S1033 24 |
| 7 23 |
| 8 (C)'90 APPLE 22 |
| 9 21 |
| 10 20 |
| 11 19 |
|____12_13_14_15_16_17_18__|
1 - Vcom - AC ground reference output, 1/2 of Vdd
2 - Bypass - Connect 10 uF electrolytic here for Vcom stablity
3 - Vdd2 - Chip's Vdd supply, 8 volts DC
4 - Vdd1 - " " " " " "
5 - IV out - Current-to-voltage op-amp output
6 - IV- - inverted output of current-to-voltage op-amp
7 - NFin - Noise Filter op-amp non-inverting input
8 - AmpOut - Output for either the record gain or playback PWM.
Typically connected to SCFin.
9 - /REDUCEGAIN - Open-drain pulldown digital output used to decrease the gain
of an external op-amp.
10 - SoundOut - Analog audio output
11 - SCFin - Switched Capacitor Filter input
12 - SCFout - output of Switched Capacitor Filter
13 - ADin - A/D converter input. Goes through volume control attenuator and
ends up at the pin 10 output.
14 - /RESET
15 - SerDOut - A/D converter serial digital output
16 - SampleClk - Sample clock
17 - SerClk - Serial clock, used to clock individual bits of the sample
18 - VssD - Digital ground
19 - ConfigClk - Configuration bit clock
20 - ConfigData - Configuration bit data. Latched on the rising edge of ConfigClk.
21 - ConfigLE - Configuration Latch Enable. Causes the last 8 bits seen on the
rising edge of ConfigClk to become the new configuraiton byte.
22 - PWMin - PWM-encoded input pulse. TTL compatible.
23 - PWMout - Level shifted version of PWMin. Output swings between Vss and Vdd.
24 - LPFin - Low Pass Filter input. Used to remove harmonics from PWMout.
25 - LPFout - Output from LPFin. Normally connected to SCFin.
26 - VssA - Analog ground
27 - Vlow - A/D converter's low reference voltage (1 volt less than Vcom)
28 - Vhigh - A/D converter's high reference voltage (1 volt more than Vcom)
The control byte is as follows:
7654 3210
VVV - volume
T - playthrough enable (input is mixed with output)
GG - 0 = /REDUCE_GAIN low (enabled), 2 = /REDUCE_GAIN reacts to a comparitor
on the input. If 1 or 3, /REDUCE_GAIN is tristated.
L - LPF In to mix with Noise input and go to Amp Out (0=Off, 1=On)
N - Noise input enable: 0 = enabled, 1 = disabled
Signal flow through the chip:
PWM In -> PWM Out (level shifts the PWM signal from TTL to the chip's voltage range)
LPF In -> LPF Out (no change) and to (switch on config bit 1) -> Amp Out
NF In -> (switch on config bit 0) -> Amp Out
SCF In -> switched capacitor filter -> SCF Out
AD In -> volume attenuator (top 3 bits of config byte) -> Sound Out
Standard hookup verified on schematics for LC/LC II/LC III/Classic II:
PWM from system ASIC -> PWM In, PWM Out -> LPF In, Amp Out -> SCF In, SCF Out -> AD In.
TODO: SCF and external 2-pole RC lowpass filter.
***************************************************************************/
#include "emu.h"
#include "dfac.h"
#define VERBOSE (0)
#include "logmacro.h"
DEFINE_DEVICE_TYPE(APPLE_DFAC, dfac_device, "apldfac", "Apple Digitally Filtered Audio Chip")
static constexpr double atten_table[8] =
{
0.0, // -infinite
0.125892541179417, // -18dB
0.177827941003892, // -15dB
0.251188643150958, // -12dB
0.354813389233575, // -9dB
0.501187233627272, // -6dB
0.707945784384138, // -3dB
1.0 // No attenuation
};
dfac_device::dfac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, APPLE_DFAC, tag, owner, clock),
device_sound_interface(mconfig, *this),
m_stream(nullptr),
m_data(false),
m_clock(false),
m_dfaclatch(false),
m_settings_byte(0),
m_latch_byte(0)
{
}
void dfac_device::device_start()
{
m_stream = stream_alloc(8, 2, clock(), STREAM_SYNCHRONOUS);
save_item(NAME(m_clock));
save_item(NAME(m_data));
save_item(NAME(m_dfaclatch));
save_item(NAME(m_settings_byte));
}
void dfac_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
{
if (BIT(m_settings_byte, 1)) // LPF In can go through to Amp Out
{
for (int i = 0; i < inputs[0].samples(); i++)
{
stream_buffer::sample_t l = inputs[0].get(i);
stream_buffer::sample_t r = inputs[1].get(i);
outputs[0].put(i, l * atten_table[m_settings_byte >> 5]);
outputs[1].put(i, r * atten_table[m_settings_byte >> 5]);
}
}
else
{
for (int i = 0; i < inputs[0].samples(); i++)
{
outputs[0].put(i, 0.0);
outputs[1].put(i, 0.0);
}
}
}
void dfac_device::clock_write(int state)
{
// take a bit on the rising edge of SCL
if (state && !m_clock)
{
m_latch_byte >>= 1;
m_latch_byte |= m_data ? 0x80 : 0;
}
m_clock = state;
}
void dfac_device::latch_write(int state)
{
// commit settings byte on the rising edge of the latch
if (state && !m_dfaclatch)
{
m_settings_byte = m_latch_byte;
LOG("DFAC: applying new settings byte %02x (volume %d, atten %f)\n", m_settings_byte, m_settings_byte >> 5, atten_table[m_settings_byte >> 5]);
}
m_dfaclatch = state;
}

34
src/mame/apple/dfac.h Normal file
View File

@ -0,0 +1,34 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
#ifndef MAME_APPLE_DFAC_H
#define MAME_APPLE_DFAC_H
#pragma once
class dfac_device : public device_t, public device_sound_interface
{
public:
dfac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// DFAC uses a serial 3-wire interface where a single control byte is shifted in, and it ignores
// writes with the gate is not at the right level. This allowed it to be used on the Egret's I2C bus
// without it being disturbed by actual I2C transactions.
void data_write(int state) { m_data = state; }
void clock_write(int state);
void latch_write(int state);
protected:
// device_r overrides
virtual void device_start() override;
// device_sound_interface overrides
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
private:
sound_stream *m_stream;
bool m_data, m_clock, m_dfaclatch;
u8 m_settings_byte, m_latch_byte;
};
DECLARE_DEVICE_TYPE(APPLE_DFAC, dfac_device)
#endif // MAME_APPLE_DFAC_H

View File

@ -81,6 +81,7 @@ void iosb_base::device_add_mconfig(machine_config &config)
R65NC22(config, m_via2, C7M / 10);
m_via2->readpa_handler().set(FUNC(iosb_base::via2_in_a));
m_via2->writepb_handler().set(FUNC(iosb_base::via2_out_b));
m_via2->irq_handler().set(FUNC(iosb_base::via2_irq));
SPEAKER(config, "lspeaker").front_left();
@ -115,6 +116,9 @@ iosb_base::iosb_base(const machine_config &mconfig, device_type type, const char
m_adb_st(*this),
m_cb1(*this),
m_cb2(*this),
m_dfac_clock_w(*this),
m_dfac_data_w(*this),
m_dfac_latch_w(*this),
m_pa1(*this, 0),
m_pa2(*this, 0),
m_pa4(*this, 0),
@ -268,6 +272,13 @@ void iosb_base::via1_irq(int state)
field_interrupts();
}
void iosb_base::via2_out_b(uint8_t data)
{
m_dfac_latch_w(BIT(data, 0));
m_dfac_data_w(BIT(data, 3));
m_dfac_clock_w(BIT(data, 4));
}
void iosb_base::via2_irq(int state)
{
m_via2_interrupt = state;

View File

@ -28,6 +28,9 @@ public:
auto write_adb_st() { return m_adb_st.bind(); } // ADB state
auto write_cb1() { return m_cb1.bind(); } // ADB clock
auto write_cb2() { return m_cb2.bind(); } // ADB data
auto write_dfac_clock() { return m_dfac_clock_w.bind(); }
auto write_dfac_data() { return m_dfac_data_w.bind(); }
auto write_dfac_latch() { return m_dfac_latch_w.bind(); }
auto read_pa1() { return m_pa1.bind(); } // ID bits
auto read_pa2() { return m_pa2.bind(); }
@ -69,7 +72,7 @@ protected:
virtual void iosb_regs_w(offs_t offset, u16 data, u16 mem_mask);
devcb_write8 m_adb_st;
devcb_write_line m_cb1, m_cb2;
devcb_write_line m_cb1, m_cb2, m_dfac_clock_w, m_dfac_data_w, m_dfac_latch_w;
devcb_read_line m_pa1, m_pa2, m_pa4, m_pa6;
required_device<m68000_musashi_device> m_maincpu;
@ -107,6 +110,7 @@ private:
void field_interrupts();
void via_out_cb1(int state);
void via_out_cb2(int state);
void via2_out_b(uint8_t data);
void via1_irq(int state);
void via2_irq(int state);
void asc_irq(int state);

View File

@ -19,6 +19,7 @@
#include "emu.h"
#include "dfac.h"
#include "egret.h"
#include "macadb.h"
#include "macscsi.h"
@ -42,6 +43,7 @@
#include "emupal.h"
#include "screen.h"
#include "softlist_dev.h"
#include "speaker.h"
namespace {
@ -58,6 +60,7 @@ public:
m_macadb(*this, "macadb"),
m_ram(*this, RAM_TAG),
m_vasp(*this, "vasp"),
m_dfac(*this, "dfac"),
m_fdc(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U),
m_scsibus1(*this, "scsi"),
@ -82,6 +85,7 @@ private:
required_device<macadb_device> m_macadb;
required_device<ram_device> m_ram;
required_device<vasp_device> m_vasp;
required_device<dfac_device> m_dfac;
required_device<applefdintf_device> m_fdc;
required_device_array<floppy_connector, 2> m_floppy;
required_device<nscsi_bus_device> m_scsibus1;
@ -298,8 +302,8 @@ void maciivx_state::maciiv_base(machine_config &config)
NSCSI_CONNECTOR(config, "scsi:3").option_set("cdrom", NSCSI_CDROM_APPLE).machine_config(
[](device_t *device)
{
device->subdevice<cdda_device>("cdda")->add_route(0, "^^vasp:lspeaker", 1.0);
device->subdevice<cdda_device>("cdda")->add_route(1, "^^vasp:rspeaker", 1.0);
device->subdevice<cdda_device>("cdda")->add_route(0, "^^lspeaker", 1.0);
device->subdevice<cdda_device>("cdda")->add_route(1, "^^rspeaker", 1.0);
});
NSCSI_CONNECTOR(config, "scsi:4", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:5", mac_scsi_devices, nullptr);
@ -338,10 +342,19 @@ void maciivx_state::maciiv_base(machine_config &config)
rs232b.dcd_handler().set(m_scc, FUNC(z80scc_device::dcdb_w));
rs232b.cts_handler().set(m_scc, FUNC(z80scc_device::ctsb_w));
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
APPLE_DFAC(config, m_dfac, 22257);
m_dfac->add_route(0, "lspeaker", 1.0);
m_dfac->add_route(1, "rspeaker", 1.0);
VASP(config, m_vasp, C15M);
m_vasp->set_maincpu_tag("maincpu");
m_vasp->set_rom_tag("bootrom");
m_vasp->hdsel_callback().set(FUNC(maciivx_state::hdsel_w));
m_vasp->add_route(0, m_dfac, 1.0);
m_vasp->add_route(1, m_dfac, 1.0);
MACADB(config, m_macadb, C15M);
@ -374,6 +387,9 @@ void maciivx_state::maciivx(machine_config &config)
EGRET(config, m_egret, XTAL(32'768));
m_egret->set_default_bios_tag("341s0851");
m_egret->reset_callback().set(FUNC(maciivx_state::egret_reset_w));
m_egret->dfac_scl_callback().set(m_dfac, FUNC(dfac_device::clock_write));
m_egret->dfac_sda_callback().set(m_dfac, FUNC(dfac_device::data_write));
m_egret->dfac_latch_callback().set(m_dfac, FUNC(dfac_device::latch_write));
m_egret->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
m_egret->via_clock_callback().set(m_vasp, FUNC(vasp_device::cb1_w));
m_egret->via_data_callback().set(m_vasp, FUNC(vasp_device::cb2_w));

View File

@ -10,7 +10,7 @@
controller, which has a 10 MB hard limit on RAM (8MB in the Mac TV).
Mac TV video input chips:
TEA63330T - Sound fader control unit for car stereos
TEA6330T - Sound fader control unit for car stereos
I2C: address 1000000x
TDA8708BT - Video analog input interface
SAA7197 T - Clock signal generator circuit for desktop video systems
@ -24,6 +24,7 @@
#include "emu.h"
#include "cuda.h"
#include "dfac.h"
#include "egret.h"
#include "macadb.h"
#include "macscsi.h"
@ -48,7 +49,7 @@
#include "emupal.h"
#include "screen.h"
#include "softlist_dev.h"
#include "speaker.h"
namespace {
#define C32M (31.3344_MHz_XTAL)
@ -64,6 +65,7 @@ public:
m_macadb(*this, "macadb"),
m_ram(*this, RAM_TAG),
m_v8(*this, "v8"),
m_dfac(*this, "dfac"),
m_fdc(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U),
m_scsibus1(*this, "scsi"),
@ -91,6 +93,7 @@ private:
required_device<macadb_device> m_macadb;
required_device<ram_device> m_ram;
required_device<v8_device> m_v8;
optional_device<dfac_device> m_dfac;
optional_device<applefdintf_device> m_fdc;
optional_device_array<floppy_connector, 2> m_floppy;
required_device<nscsi_bus_device> m_scsibus1;
@ -324,8 +327,8 @@ void maclc_state::maclc_base(machine_config &config)
NSCSI_CONNECTOR(config, "scsi:3").option_set("cdrom", NSCSI_CDROM_APPLE).machine_config(
[](device_t *device)
{
device->subdevice<cdda_device>("cdda")->add_route(0, "^^v8:lspeaker", 1.0);
device->subdevice<cdda_device>("cdda")->add_route(1, "^^v8:rspeaker", 1.0);
device->subdevice<cdda_device>("cdda")->add_route(0, "^^lspeaker", 1.0);
device->subdevice<cdda_device>("cdda")->add_route(1, "^^rspeaker", 1.0);
});
NSCSI_CONNECTOR(config, "scsi:4", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:5", mac_scsi_devices, nullptr);
@ -364,11 +367,20 @@ void maclc_state::maclc_base(machine_config &config)
rs232b.dcd_handler().set(m_scc, FUNC(z80scc_device::dcdb_w));
rs232b.cts_handler().set(m_scc, FUNC(z80scc_device::ctsb_w));
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
APPLE_DFAC(config, m_dfac, 22257);
m_dfac->add_route(0, "lspeaker", 1.0);
m_dfac->add_route(1, "rspeaker", 1.0);
V8(config, m_v8, C15M);
m_v8->set_maincpu_tag("maincpu");
m_v8->set_rom_tag("bootrom");
m_v8->hdsel_callback().set(FUNC(maclc_state::hdsel_w));
m_v8->hmmu_enable_callback().set(FUNC(maclc_state::set_hmmu));
m_v8->add_route(0, m_dfac, 1.0);
m_v8->add_route(1, m_dfac, 1.0);
nubus_device &nubus(NUBUS(config, "pds", 0));
nubus.set_space(m_maincpu, AS_PROGRAM);
@ -382,6 +394,9 @@ void maclc_state::maclc_base(machine_config &config)
EGRET(config, m_egret, XTAL(32'768));
m_egret->set_default_bios_tag("341s0850");
m_egret->reset_callback().set(FUNC(maclc_state::egret_reset_w));
m_egret->dfac_scl_callback().set(m_dfac, FUNC(dfac_device::clock_write));
m_egret->dfac_sda_callback().set(m_dfac, FUNC(dfac_device::data_write));
m_egret->dfac_latch_callback().set(m_dfac, FUNC(dfac_device::latch_write));
m_egret->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
m_egret->via_clock_callback().set(m_v8, FUNC(v8_device::cb1_w));
m_egret->via_data_callback().set(m_v8, FUNC(v8_device::cb2_w));
@ -441,7 +456,7 @@ void maclc_state::maccclas(machine_config &config)
config.device_remove("fdc");
CUDA_V2XX(config, m_cuda, XTAL(32'768));
m_cuda->set_default_bios_tag("341s0788");
m_cuda->set_default_bios_tag("341s0417");
m_cuda->reset_callback().set(FUNC(maclc_state::egret_reset_w));
m_cuda->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
m_cuda->via_clock_callback().set(m_v8, FUNC(v8_device::cb1_w));
@ -457,6 +472,10 @@ void maclc_state::maccclas(machine_config &config)
m_v8->pb4_callback().set(m_cuda, FUNC(cuda_device::set_byteack));
m_v8->pb5_callback().set(m_cuda, FUNC(cuda_device::set_tip));
m_v8->cb2_callback().set(m_cuda, FUNC(cuda_device::set_via_data));
m_v8->add_route(0, "lspeaker", 1.0);
m_v8->add_route(1, "rspeaker", 1.0);
config.device_remove("dfac");
NUBUS_SLOT(config, "lcpds", "pds", mac_pdslc_cards, nullptr);
@ -479,7 +498,7 @@ void maclc_state::mactv(machine_config &config)
config.device_remove("fdc");
CUDA_V2XX(config, m_cuda, XTAL(32'768));
m_cuda->set_default_bios_tag("341s0788");
m_cuda->set_default_bios_tag("341s0788"); // TODO: 0789 freezes during boot, possible VIA bug or 6522/6523 difference?
m_cuda->reset_callback().set(FUNC(maclc_state::egret_reset_w));
m_cuda->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
m_cuda->via_clock_callback().set(m_v8, FUNC(v8_device::cb1_w));
@ -495,6 +514,10 @@ void maclc_state::mactv(machine_config &config)
m_v8->pb4_callback().set(m_cuda, FUNC(cuda_device::set_byteack));
m_v8->pb5_callback().set(m_cuda, FUNC(cuda_device::set_tip));
m_v8->cb2_callback().set(m_cuda, FUNC(cuda_device::set_via_data));
m_v8->add_route(0, "lspeaker", 1.0);
m_v8->add_route(1, "rspeaker", 1.0);
config.device_remove("dfac");
// Mac TV doesn't have an LC PDS
config.device_remove("pds");
@ -522,6 +545,8 @@ void maclc_state::macclas2(machine_config &config)
m_v8->pb4_callback().set(m_egret, FUNC(egret_device::set_via_full));
m_v8->pb5_callback().set(m_egret, FUNC(egret_device::set_sys_session));
m_v8->cb2_callback().set(m_egret, FUNC(egret_device::set_via_data));
m_v8->add_route(0, m_dfac, 1.0);
m_v8->add_route(1, m_dfac, 1.0);
// Classic II doesn't have an LC PDS slot (and its ROM has the Slot Manager disabled)
config.device_remove("pds");

View File

@ -18,6 +18,7 @@
#include "emu.h"
#include "cuda.h"
#include "dfac.h"
#include "egret.h"
#include "macadb.h"
#include "macscsi.h"
@ -38,6 +39,7 @@
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "softlist_dev.h"
namespace {
@ -54,6 +56,7 @@ public:
m_macadb(*this, "macadb"),
m_ram(*this, RAM_TAG),
m_sonora(*this, "sonora"),
m_dfac(*this, "dfac"),
m_scsibus1(*this, "scsi"),
m_ncr5380(*this, "scsi:7:ncr5380"),
m_scsihelp(*this, "scsihelp"),
@ -79,6 +82,7 @@ private:
optional_device<macadb_device> m_macadb;
required_device<ram_device> m_ram;
required_device<sonora_device> m_sonora;
optional_device<dfac_device> m_dfac;
required_device<nscsi_bus_device> m_scsibus1;
required_device<ncr5380_device> m_ncr5380;
required_device<mac_scsi_helper_device> m_scsihelp;
@ -247,8 +251,8 @@ void macvail_state::maclc3_base(machine_config &config)
NSCSI_CONNECTOR(config, "scsi:3").option_set("cdrom", NSCSI_CDROM_APPLE).machine_config(
[](device_t *device)
{
device->subdevice<cdda_device>("cdda")->add_route(0, "^^sonora:lspeaker", 1.0);
device->subdevice<cdda_device>("cdda")->add_route(1, "^^sonora:rspeaker", 1.0);
device->subdevice<cdda_device>("cdda")->add_route(0, "^^lspeaker", 1.0);
device->subdevice<cdda_device>("cdda")->add_route(1, "^^rspeaker", 1.0);
});
NSCSI_CONNECTOR(config, "scsi:4", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:5", mac_scsi_devices, nullptr);
@ -287,9 +291,18 @@ void macvail_state::maclc3_base(machine_config &config)
rs232b.dcd_handler().set(m_scc, FUNC(z80scc_device::dcdb_w));
rs232b.cts_handler().set(m_scc, FUNC(z80scc_device::ctsb_w));
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
APPLE_DFAC(config, m_dfac, 22257);
m_dfac->add_route(0, "lspeaker", 1.0);
m_dfac->add_route(1, "rspeaker", 1.0);
SONORA(config, m_sonora, C15M);
m_sonora->set_maincpu_tag("maincpu");
m_sonora->set_rom_tag("bootrom");
m_sonora->add_route(0, m_dfac, 1.0);
m_sonora->add_route(1, m_dfac, 1.0);
nubus_device &nubus(NUBUS(config, "pds", 0));
nubus.set_space(m_maincpu, AS_PROGRAM);
@ -310,6 +323,9 @@ void macvail_state::maclc3(machine_config &config)
EGRET(config, m_egret, XTAL(32'768));
m_egret->set_default_bios_tag("341s0851");
m_egret->reset_callback().set(FUNC(macvail_state::cuda_reset_w));
m_egret->dfac_scl_callback().set(m_dfac, FUNC(dfac_device::clock_write));
m_egret->dfac_sda_callback().set(m_dfac, FUNC(dfac_device::data_write));
m_egret->dfac_latch_callback().set(m_dfac, FUNC(dfac_device::latch_write));
m_egret->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
m_egret->via_clock_callback().set(m_sonora, FUNC(sonora_device::cb1_w));
m_egret->via_data_callback().set(m_sonora, FUNC(sonora_device::cb2_w));
@ -347,6 +363,12 @@ void macvail_state::maclc520(machine_config &config)
m_sonora->pb4_callback().set(m_cuda, FUNC(cuda_device::set_byteack));
m_sonora->pb5_callback().set(m_cuda, FUNC(cuda_device::set_tip));
m_sonora->cb2_callback().set(m_cuda, FUNC(cuda_device::set_via_data));
// DFAC only is found in machines with Egret, and not the IIsi
m_sonora->reset_routes();
m_sonora->add_route(0, "lspeaker", 1.0);
m_sonora->add_route(1, "rspeaker", 1.0);
config.device_remove("dfac");
}
void macvail_state::maclc550(machine_config &config)

View File

@ -13,6 +13,7 @@
#include "adbmodem.h"
#include "dafb.h"
#include "dfac.h"
#include "macadb.h"
#include "macrtc.h"
#include "mactoolbox.h"
@ -44,7 +45,6 @@
#define C7M (C32M/4)
namespace {
class macquadra_state : public driver_device
{
public:
@ -64,6 +64,7 @@ public:
m_sonic(*this, "sonic"),
m_dafb(*this, "dafb"),
m_easc(*this, "easc"),
m_dfac(*this, "dfac"),
m_scc(*this, "scc"),
m_cur_floppy(nullptr),
m_hdsel(0)
@ -89,6 +90,7 @@ private:
required_device<dp83932c_device> m_sonic;
required_device<dafb_device> m_dafb;
required_device<asc_device> m_easc;
required_device<dfac_device> m_dfac;
required_device<z80scc_device> m_scc;
virtual void machine_start() override;
@ -535,6 +537,10 @@ void macquadra_state::mac_via2_out_b(u8 data)
{
// chain 60.15 Hz to VIA1
m_via1->write_ca1(data>>7);
m_dfac->data_write(BIT(data, 3));
m_dfac->clock_write(BIT(data, 4));
m_dfac->latch_write(BIT(data, 0));
}
void macquadra_state::phases_w(u8 phases)
@ -675,6 +681,9 @@ void macquadra_state::macqd700(machine_config &config)
m_easc->add_route(0, "lspeaker", 1.0);
m_easc->add_route(1, "rspeaker", 1.0);
// DFAC is only for audio input on Q700/Q800
APPLE_DFAC(config, m_dfac, 22257);
/* internal ram */
RAM(config, m_ram);
m_ram->set_default_size("4M");

View File

@ -20,6 +20,7 @@
#include "emu.h"
#include "adbmodem.h"
#include "dfac.h"
#include "djmemc.h"
#include "iosb.h"
#include "macadb.h"
@ -54,6 +55,7 @@ public:
m_maincpu(*this, "maincpu"),
m_djmemc(*this, "djmemc"),
m_iosb(*this, "iosb"),
m_dfac(*this, "dfac"),
m_macadb(*this, "macadb"),
m_adbmodem(*this, "adbmodem"),
m_scc(*this, "scc"),
@ -78,6 +80,7 @@ private:
required_device<m68040_device> m_maincpu;
required_device<djmemc_device> m_djmemc;
required_device<iosb_device> m_iosb;
required_device<dfac_device> m_dfac;
required_device<macadb_device> m_macadb;
required_device<adbmodem_device> m_adbmodem;
required_device<z80scc_device> m_scc;
@ -193,6 +196,11 @@ void quadra800_state::macqd800(machine_config &config)
m_iosb->read_pa4().set_constant(1);
m_iosb->read_pa6().set_constant(0);
APPLE_DFAC(config, m_dfac, 22257);
m_iosb->write_dfac_clock().set(m_dfac, FUNC(dfac_device::clock_write));
m_iosb->write_dfac_data().set(m_dfac, FUNC(dfac_device::data_write));
m_iosb->write_dfac_latch().set(m_dfac, FUNC(dfac_device::latch_write));
SCC85C30(config, m_scc, C7M);
m_scc->configure_channels(3'686'400, 3'686'400, 3'686'400, 3'686'400);
m_scc->out_int_callback().set(m_iosb, FUNC(iosb_device::scc_irq_w));

View File

@ -77,11 +77,10 @@ void sonora_device::device_add_mconfig(machine_config &config)
m_via1->cb2_handler().set(FUNC(sonora_device::via_out_cb2));
m_via1->irq_handler().set(FUNC(sonora_device::via1_irq));
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
ASC(config, m_asc, C15M, asc_device::asc_type::SONORA);
m_asc->add_route(0, "lspeaker", 1.0);
m_asc->add_route(1, "rspeaker", 1.0);
m_asc->add_route(0, tag(), 1.0);
m_asc->add_route(1, tag(), 1.0);
m_asc->irqf_callback().set(FUNC(sonora_device::asc_irq));
SWIM2(config, m_fdc, C15M);
@ -98,6 +97,7 @@ void sonora_device::device_add_mconfig(machine_config &config)
sonora_device::sonora_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SONORA, tag, owner, clock),
device_sound_interface(mconfig, *this),
write_pb4(*this),
write_pb5(*this),
write_cb2(*this),
@ -123,6 +123,8 @@ void sonora_device::device_start()
{
m_vram = std::make_unique<u32[]>(0x100000 / sizeof(u32));
m_stream = stream_alloc(8, 2, m_asc->clock(), STREAM_SYNCHRONOUS);
m_6015_timer = timer_alloc(FUNC(sonora_device::mac_6015_tick), this);
m_6015_timer->adjust(attotime::never);
@ -176,6 +178,15 @@ void sonora_device::device_reset()
space.install_rom(0x00000000, memory_end & ~memory_mirror, memory_mirror, m_rom_ptr);
}
void sonora_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
{
for (int i = 0; i < inputs[0].samples(); i++)
{
outputs[0].put(i, inputs[0].get(i));
outputs[1].put(i, inputs[1].get(i));
}
}
u32 sonora_device::rom_switch_r(offs_t offset)
{
// disable the overlay

View File

@ -15,7 +15,7 @@
// ======================> sonora_device
class sonora_device : public device_t
class sonora_device : public device_t, public device_sound_interface
{
public:
// construction/destruction
@ -49,6 +49,8 @@ protected:
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
private:
devcb_write_line write_pb4, write_pb5, write_cb2;
devcb_read_line read_pb3;
@ -62,6 +64,7 @@ private:
required_region_ptr<u32> m_rom;
std::unique_ptr<u32[]> m_vram;
sound_stream *m_stream;
emu_timer *m_6015_timer;
int m_via_interrupt, m_via2_interrupt, m_scc_interrupt, m_last_taken_interrupt;
uint8_t m_pseudovia_regs[256], m_pseudovia_ier, m_pseudovia_ifr;

View File

@ -114,12 +114,10 @@ void v8_device::device_add_mconfig(machine_config &config)
m_via1->cb2_handler().set(FUNC(v8_device::via_out_cb2));
m_via1->irq_handler().set(FUNC(v8_device::via1_irq));
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
ASC(config, m_asc, C15M, asc_device::asc_type::V8);
m_asc->add_route(0, "lspeaker", 1.0);
m_asc->add_route(1, "rspeaker", 1.0);
m_asc->irqf_callback().set(FUNC(v8_device::asc_irq));
m_asc->add_route(0, tag(), 1.0);
m_asc->add_route(1, tag(), 1.0);
}
//-------------------------------------------------
@ -133,6 +131,7 @@ v8_device::v8_device(const machine_config &mconfig, const char *tag, device_t *o
v8_device::v8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
device_t(mconfig, type, tag, owner, clock),
device_sound_interface(mconfig, *this),
m_maincpu(*this, finder_base::DUMMY_TAG),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
@ -159,6 +158,8 @@ void v8_device::device_start()
{
m_vram = std::make_unique<u32[]>(0x100000 / sizeof(u32));
m_stream = stream_alloc(8, 2, m_asc->clock(), STREAM_SYNCHRONOUS);
m_6015_timer = timer_alloc(FUNC(v8_device::mac_6015_tick), this);
m_6015_timer->adjust(attotime::never);
@ -214,6 +215,15 @@ void v8_device::device_reset()
space.install_rom(0x00000000, memory_end & ~memory_mirror, memory_mirror, &m_rom[0]);
}
void v8_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
{
for (int i = 0; i < inputs[0].samples(); i++)
{
outputs[0].put(i, inputs[0].get(i));
outputs[1].put(i, inputs[1].get(i));
}
}
u32 v8_device::rom_switch_r(offs_t offset)
{
// disable the overlay
@ -877,8 +887,8 @@ void eagle_device::device_add_mconfig(machine_config &config)
m_screen->set_raw(15.6672_MHz_XTAL, 704, 0, 512, 370, 0, 342);
ASC(config.replace(), m_asc, C15M, asc_device::asc_type::EAGLE);
m_asc->add_route(0, "lspeaker", 1.0);
m_asc->add_route(1, "rspeaker", 1.0);
m_asc->add_route(0, tag(), 1.0);
m_asc->add_route(1, tag(), 1.0);
m_asc->irqf_callback().set(FUNC(eagle_device::asc_irq));
}
@ -958,8 +968,8 @@ void spice_device::device_add_mconfig(machine_config &config)
m_screen->set_raw(15.6672_MHz_XTAL, 640, 0, 512, 407, 0, 384);
ASC(config.replace(), m_asc, C15M, asc_device::asc_type::SONORA);
m_asc->add_route(0, "lspeaker", 1.0);
m_asc->add_route(1, "rspeaker", 1.0);
m_asc->add_route(0, tag(), 1.0);
m_asc->add_route(1, tag(), 1.0);
m_asc->irqf_callback().set(FUNC(spice_device::asc_irq));
SWIM2(config, m_fdc, C15M);

View File

@ -11,12 +11,11 @@
#include "machine/swim2.h"
#include "sound/asc.h"
#include "emupal.h"
#include "speaker.h"
#include "screen.h"
// ======================> v8_device
class v8_device : public device_t
class v8_device : public device_t, public device_sound_interface
{
public:
// construction/destruction
@ -63,6 +62,8 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
virtual u8 pseudovia_r(offs_t offset);
void asc_irq(int state);
@ -77,6 +78,7 @@ private:
required_device<via6522_device> m_via1;
required_region_ptr<u32> m_rom;
sound_stream *m_stream;
emu_timer *m_6015_timer;
int m_via_interrupt, m_via2_interrupt, m_scc_interrupt, m_last_taken_interrupt;
u8 m_pseudovia_ier, m_pseudovia_ifr;

View File

@ -85,11 +85,9 @@ void vasp_device::device_add_mconfig(machine_config &config)
m_via1->cb2_handler().set(FUNC(vasp_device::via_out_cb2));
m_via1->irq_handler().set(FUNC(vasp_device::via1_irq));
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
ASC(config, m_asc, C15M, asc_device::asc_type::VASP);
m_asc->add_route(0, "lspeaker", 1.0);
m_asc->add_route(1, "rspeaker", 1.0);
m_asc->add_route(0, tag(), 1.0);
m_asc->add_route(1, tag(), 1.0);
m_asc->irqf_callback().set(FUNC(vasp_device::asc_irq));
}
@ -99,6 +97,7 @@ void vasp_device::device_add_mconfig(machine_config &config)
vasp_device::vasp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, VASP, tag, owner, clock),
device_sound_interface(mconfig, *this),
write_pb4(*this),
write_pb5(*this),
write_cb2(*this),
@ -123,6 +122,8 @@ void vasp_device::device_start()
{
m_vram = std::make_unique<u32[]>(0x100000 / sizeof(u32));
m_stream = stream_alloc(8, 2, m_asc->clock(), STREAM_SYNCHRONOUS);
m_6015_timer = timer_alloc(FUNC(vasp_device::mac_6015_tick), this);
m_6015_timer->adjust(attotime::never);
@ -181,6 +182,15 @@ void vasp_device::device_reset()
space.install_rom(0x00000000, memory_end & ~memory_mirror, memory_mirror, m_rom_ptr);
}
void vasp_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
{
for (int i = 0; i < inputs[0].samples(); i++)
{
outputs[0].put(i, inputs[0].get(i));
outputs[1].put(i, inputs[1].get(i));
}
}
u32 vasp_device::rom_switch_r(offs_t offset)
{
// disable the overlay

View File

@ -14,7 +14,7 @@
// ======================> vasp_device
class vasp_device : public device_t
class vasp_device : public device_t, public device_sound_interface
{
public:
// construction/destruction
@ -53,6 +53,8 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
private:
devcb_write_line write_pb4, write_pb5, write_cb2, write_hdsel;
devcb_read_line read_pb3;
@ -66,6 +68,7 @@ private:
required_region_ptr<u32> m_rom;
std::unique_ptr<u32[]> m_vram;
sound_stream *m_stream;
emu_timer *m_6015_timer;
int m_via_interrupt, m_via2_interrupt, m_scc_interrupt, m_last_taken_interrupt;
u8 m_pseudovia_regs[256], m_pseudovia_ier, m_pseudovia_ifr;