summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author arbee <rb6502@users.noreply.github.com>2023-04-29 21:21:49 -0400
committer arbee <rb6502@users.noreply.github.com>2023-04-29 21:21:49 -0400
commit59baa6640b17b4baad328d5b9ec3401fac9ce122 (patch)
treeb07226eb397932aad3ef1dcbd77667b6f1b4a1d1
parent47202637e6da3c4f86f90b93cd1ab8b4ec2b5c52 (diff)
machine/mpc106.cpp: properly endian-swap PPC/PCI transactions, support LE PPC, use logmacro. [R. Belmont]
apple/bandit.cpp: properly endian-swap PPC/PCI transactions, use logmacro. [R. Belmont] apple/heathrow.cpp: interrupt controller filled out, audio CODEC interface defined, added audio DMA channels. [R. Belmont] apple/dbdma.cpp: New device, a single Descriptor Based DMA channel. [R. Belmont] apple/awacs_macrisc.cpp: New device, the AWACS and Screamer CODECs in their MacRISC compatible form. [R. Belmont] apple/burgundy.cpp: New device, MacRISC compatible CODEC used in the iMac G3 and "Blue & White" G3. apple/imacg3.cpp: Boot chime now plays. [R. Belmont] apple/powermacg3.cpp: Boot chime now plays. [R. Belmont]
-rwxr-xr-xsrc/devices/machine/mpc106.cpp97
-rw-r--r--src/devices/machine/mpc106.h6
-rw-r--r--src/mame/apple/awacs_macrisc.cpp210
-rw-r--r--src/mame/apple/awacs_macrisc.h76
-rw-r--r--src/mame/apple/bandit.cpp10
-rw-r--r--src/mame/apple/burgundy.cpp169
-rw-r--r--src/mame/apple/burgundy.h62
-rw-r--r--src/mame/apple/dbdma.cpp273
-rw-r--r--src/mame/apple/dbdma.h69
-rw-r--r--src/mame/apple/heathrow.cpp253
-rw-r--r--src/mame/apple/heathrow.h84
-rw-r--r--src/mame/apple/imacg3.cpp19
-rw-r--r--src/mame/apple/pippin.cpp56
-rw-r--r--src/mame/apple/powermacg3.cpp19
14 files changed, 1277 insertions, 126 deletions
diff --git a/src/devices/machine/mpc106.cpp b/src/devices/machine/mpc106.cpp
index c8e57c72912..15bdb9645ef 100755
--- a/src/devices/machine/mpc106.cpp
+++ b/src/devices/machine/mpc106.cpp
@@ -22,6 +22,8 @@ enum
AS_PCI_IO = 2
};
+constexpr u32 PICR1_LE_MODE = 0x00000020; // Host CPU is little-endian if set, big-endian if clear
+
DEFINE_DEVICE_TYPE(MPC106, mpc106_host_device, "mpc106", "Motorola MPC106 PCI Bridge/Memory Controller")
void mpc106_host_device::config_map(address_map &map)
@@ -32,6 +34,7 @@ void mpc106_host_device::config_map(address_map &map)
map(0x80, 0x8f).rw(FUNC(mpc106_host_device::memory_start_r), FUNC(mpc106_host_device::memory_start_w));
map(0x90, 0x9f).rw(FUNC(mpc106_host_device::memory_end_r), FUNC(mpc106_host_device::memory_end_w));
map(0xa0, 0xa0).rw(FUNC(mpc106_host_device::memory_enable_r), FUNC(mpc106_host_device::memory_enable_w));
+ map(0xa8, 0xab).rw(FUNC(mpc106_host_device::picr1_r), FUNC(mpc106_host_device::picr1_w));
}
mpc106_host_device::mpc106_host_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
@@ -42,6 +45,7 @@ mpc106_host_device::mpc106_host_device(const machine_config &mconfig, const char
{
set_ids_host(0x10570002, 0x40, 0x000006);
m_memory_bank_enable = 0;
+ m_picr1 = 0;
}
void mpc106_host_device::set_ram_info(u8 *ram_ptr, int ram_size)
@@ -108,7 +112,14 @@ void mpc106_host_device::device_start()
m_cpu_space->install_read_handler (0xfe800000, 0xfebfffff, read32s_delegate(*this, FUNC(mpc106_host_device::pci_io_r<0x00800000>)));
m_cpu_space->install_write_handler(0xfe800000, 0xfebfffff, write32s_delegate(*this, FUNC(mpc106_host_device::pci_io_w<0x00800000>)));
- m_cpu_space->install_device(0xfec00000, 0xfeefffff, *static_cast<mpc106_host_device *>(this), &mpc106_host_device::access_map);
+ if (m_picr1 & PICR1_LE_MODE)
+ {
+ m_cpu_space->install_device(0xfec00000, 0xfeefffff, *static_cast<mpc106_host_device *>(this), &mpc106_host_device::access_map_le);
+ }
+ else
+ {
+ m_cpu_space->install_device(0xfec00000, 0xfeefffff, *static_cast<mpc106_host_device *>(this), &mpc106_host_device::access_map_be);
+ }
}
save_item(NAME(m_pwrconfig1));
@@ -116,6 +127,7 @@ void mpc106_host_device::device_start()
save_item(NAME(m_memory_starts));
save_item(NAME(m_memory_ends));
save_item(NAME(m_memory_bank_enable));
+ save_item(NAME(m_picr1));
}
device_memory_interface::space_config_vector mpc106_host_device::memory_space_config() const
@@ -136,7 +148,13 @@ void mpc106_host_device::device_reset()
pci_host_device::device_reset();
}
-void mpc106_host_device::access_map(address_map &map)
+void mpc106_host_device::access_map_le(address_map &map)
+{
+ map(0x00000000, 0x001fffff).rw(FUNC(mpc106_host_device::config_address_r), FUNC(mpc106_host_device::config_address_w));
+ map(0x00200000, 0x002fffff).rw(FUNC(mpc106_host_device::config_data_r), FUNC(mpc106_host_device::config_data_w));
+}
+
+void mpc106_host_device::access_map_be(address_map &map)
{
map(0x00000000, 0x001fffff).rw(FUNC(mpc106_host_device::be_config_address_r), FUNC(mpc106_host_device::be_config_address_w));
map(0x00200000, 0x002fffff).rw(FUNC(mpc106_host_device::be_config_data_r), FUNC(mpc106_host_device::be_config_data_w));
@@ -149,32 +167,43 @@ u32 mpc106_host_device::be_config_address_r()
void mpc106_host_device::be_config_address_w(offs_t offset, u32 data, u32 mem_mask)
{
- const u32 tempdata = swapendian_int32(data);
- pci_host_device::config_address_w(offset, tempdata, mem_mask);
+ pci_host_device::config_address_w(offset, swapendian_int32(data), swapendian_int32(mem_mask));
}
u32 mpc106_host_device::be_config_data_r(offs_t offset, u32 mem_mask)
{
- return swapendian_int32(pci_host_device::config_data_r(offset, mem_mask));
+ return swapendian_int32(pci_host_device::config_data_r(offset, swapendian_int32(mem_mask)));
}
void mpc106_host_device::be_config_data_w(offs_t offset, u32 data, u32 mem_mask)
{
- const u32 tempdata = swapendian_int32(data);
- pci_host_device::config_data_w(offset, tempdata, mem_mask);
+ pci_host_device::config_data_w(offset, swapendian_int32(data), swapendian_int32(mem_mask));
}
template <u32 Base>
u32 mpc106_host_device::cpu_memory_r(offs_t offset, u32 mem_mask)
{
- const u32 result = m_cpu_space->read_dword(Base + (offset * 4), mem_mask);
- return result;
+ if (m_picr1 & PICR1_LE_MODE)
+ {
+ return m_cpu_space->read_dword(Base + (offset * 4), mem_mask);
+ }
+ else
+ {
+ return swapendian_int32(m_cpu_space->read_dword(Base + (offset * 4), swapendian_int32(mem_mask)));
+ }
}
template <u32 Base>
void mpc106_host_device::cpu_memory_w(offs_t offset, u32 data, u32 mem_mask)
{
- m_cpu_space->write_dword(Base + (offset * 4), data, mem_mask);
+ if (m_picr1 & PICR1_LE_MODE)
+ {
+ m_cpu_space->write_dword(Base + (offset * 4), data, mem_mask);
+ }
+ else
+ {
+ m_cpu_space->write_dword(Base + (offset * 4), swapendian_int32(data), swapendian_int32(mem_mask));
+ }
}
template u32 mpc106_host_device::cpu_memory_r<0>(offs_t offset, u32 mem_mask);
@@ -186,14 +215,27 @@ template void mpc106_host_device::cpu_memory_w<0xff800000>(offs_t offset, u32 da
template <u32 Base>
u32 mpc106_host_device::pci_memory_r(offs_t offset, u32 mem_mask)
{
- const u32 result = this->space(AS_PCI_MEM).read_dword(Base + (offset * 4), mem_mask);
- return result;
+ if (m_picr1 & PICR1_LE_MODE)
+ {
+ return this->space(AS_PCI_MEM).read_dword(Base + (offset * 4), mem_mask);
+ }
+ else
+ {
+ return swapendian_int32(this->space(AS_PCI_MEM).read_dword(Base + (offset * 4), swapendian_int32(mem_mask)));
+ }
}
template <u32 Base>
void mpc106_host_device::pci_memory_w(offs_t offset, u32 data, u32 mem_mask)
{
- this->space(AS_PCI_MEM).write_dword(Base + (offset * 4), data, mem_mask);
+ if (m_picr1 & PICR1_LE_MODE)
+ {
+ this->space(AS_PCI_MEM).write_dword(Base + (offset * 4), data, mem_mask);
+ }
+ else
+ {
+ this->space(AS_PCI_MEM).write_dword(Base + (offset * 4), swapendian_int32(data), swapendian_int32((mem_mask)));
+ }
}
template u32 mpc106_host_device::pci_memory_r<0>(offs_t offset, u32 mem_mask);
@@ -205,14 +247,27 @@ template void mpc106_host_device::pci_memory_w<0x80000000>(offs_t offset, u32 da
template <u32 Base>
u32 mpc106_host_device::pci_io_r(offs_t offset, u32 mem_mask)
{
- u32 result = this->space(AS_PCI_IO).read_dword(Base + (offset * 4), mem_mask);
- return result;
+ if (m_picr1 & PICR1_LE_MODE)
+ {
+ return this->space(AS_PCI_IO).read_dword(Base + (offset * 4), mem_mask);
+ }
+ else
+ {
+ return swapendian_int32(this->space(AS_PCI_IO).read_dword(Base + (offset * 4), swapendian_int32(mem_mask)));
+ }
}
template <u32 Base>
void mpc106_host_device::pci_io_w(offs_t offset, u32 data, u32 mem_mask)
{
- this->space(AS_PCI_IO).write_dword(Base + (offset * 4), data, mem_mask);
+ if (m_picr1 & PICR1_LE_MODE)
+ {
+ this->space(AS_PCI_IO).write_dword(Base + (offset * 4), data, mem_mask);
+ }
+ else
+ {
+ this->space(AS_PCI_IO).write_dword(Base + (offset * 4), swapendian_int32(data), swapendian_int32((mem_mask)));
+ }
}
template u32 mpc106_host_device::pci_io_r<0>(offs_t offset, u32 mem_mask);
@@ -319,3 +374,13 @@ void mpc106_host_device::memory_enable_w(offs_t offset, u8 data)
end2 >>= 8;
}
}
+
+u32 mpc106_host_device::picr1_r()
+{
+ return m_picr1;
+}
+
+void mpc106_host_device::picr1_w(u32 data)
+{
+ m_picr1 = data;
+}
diff --git a/src/devices/machine/mpc106.h b/src/devices/machine/mpc106.h
index 84d0a1780d6..da4ecca061f 100644
--- a/src/devices/machine/mpc106.h
+++ b/src/devices/machine/mpc106.h
@@ -51,7 +51,8 @@ protected:
virtual space_config_vector memory_space_config() const override;
private:
- void access_map(address_map &map);
+ void access_map_le(address_map &map);
+ void access_map_be(address_map &map);
u32 be_config_address_r();
void be_config_address_w(offs_t offset, u32 data, u32 mem_mask = ~0);
u32 be_config_data_r(offs_t offset, u32 mem_mask = ~0);
@@ -73,6 +74,8 @@ private:
void memory_end_w(offs_t offset, u32 data, u32 mem_mask);
u8 memory_enable_r();
void memory_enable_w(offs_t offset, u8 data);
+ u32 picr1_r();
+ void picr1_w(u32 data);
address_space_config m_mem_config, m_io_config;
const char *m_rom_tag;
@@ -87,6 +90,7 @@ private:
u8 m_pwrconfig2;
u32 m_memory_starts[4];
u32 m_memory_ends[4];
+ u32 m_picr1;
u8 m_memory_bank_enable;
};
diff --git a/src/mame/apple/awacs_macrisc.cpp b/src/mame/apple/awacs_macrisc.cpp
new file mode 100644
index 00000000000..6b18b3e835e
--- /dev/null
+++ b/src/mame/apple/awacs_macrisc.cpp
@@ -0,0 +1,210 @@
+// license:BSD-3-Clause
+// copyright-holders:R. Belmont
+/***************************************************************************
+
+ awacs_macrisc.cpp
+
+ AWACS/Screamer 16-bit audio I/O for "MacRisc" architecture Macs (PCI-based)
+
+ AWACS and Screamer are audio CODECs that comply with a specification.
+ Data transfer to and from them is done in terms of serial frames.
+
+ Screamer is back-compatible with AWACS but supports more mixer inputs and
+ better power management.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "awacs_macrisc.h"
+
+#define LOG_GENERAL (1U << 0)
+#define LOG_REGISTERS (1U << 0)
+
+#define VERBOSE (0)
+#include "logmacro.h"
+
+constexpr u16 REGISTER_1_MUTE = 0x100;
+
+// device type definition
+DEFINE_DEVICE_TYPE(AWACS_MACRISC, awacs_macrisc_device, "awacsmr", "AWACS MacRisc audio I/O")
+DEFINE_DEVICE_TYPE(SCREAMER, screamer_device, "screamer", "Screamer audio I/O")
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// awacs_macrisc_device - constructor
+//-------------------------------------------------
+
+awacs_macrisc_device::awacs_macrisc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_sound_interface(mconfig, *this)
+ , m_output_cb(*this)
+ , m_input_cb(*this)
+ , m_stream(nullptr)
+{
+}
+
+awacs_macrisc_device::awacs_macrisc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : awacs_macrisc_device(mconfig, AWACS_MACRISC, tag, owner, clock)
+ {
+ }
+
+ screamer_device::screamer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : awacs_macrisc_device(mconfig, SCREAMER, tag, owner, clock)
+ {
+ }
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void awacs_macrisc_device::device_start()
+{
+ // create the stream
+ m_stream = stream_alloc(0, 2, clock()/1024, STREAM_SYNCHRONOUS);
+
+ m_output_cb.resolve_safe(0);
+ m_input_cb.resolve_safe();
+
+ save_item(NAME(m_phase));
+ save_item(NAME(m_active));
+ save_item(NAME(m_registers));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void awacs_macrisc_device::device_reset()
+{
+ m_phase = 0;
+ m_active = ACTIVE_OUT; // AWACS is always running, Screamer has a real enable/disable bit
+ m_registers[1] = REGISTER_1_MUTE;
+ m_stream->set_sample_rate(clock() / 1024);
+}
+
+void screamer_device::device_reset()
+{
+ awacs_macrisc_device::device_reset();
+ m_active = 0;
+}
+
+//-------------------------------------------------
+// sound_stream_update - handle update requests for
+// our sound stream
+//-------------------------------------------------
+
+void awacs_macrisc_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
+{
+ // if we're active and not muted
+ if ((m_active & ACTIVE_OUT) && !(m_registers[1] & REGISTER_1_MUTE))
+ {
+ const s16 atten_L = 0xf - (m_registers[2] >> 6) & 0xf;
+ const s16 atten_R = 0xf - m_registers[2] & 0xf;
+
+ const u32 data = swapendian_int32(m_output_cb(m_phase));
+ const s16 l_raw = (s16)(data >> 16);
+ const s16 r_raw = (s16)(data & 0xffff);
+
+ const s32 left = ((s32)l_raw * atten_L) >> 4;
+ const s32 right = ((s32)r_raw * atten_R) >> 4;
+ outputs[0].put_int(0, left, 32768);
+ outputs[1].put_int(0, right, 32768);
+ }
+ else
+ {
+ outputs[0].put_int(0, 0, 32768);
+ outputs[1].put_int(0, 0, 32768);
+ }
+
+ m_phase = (m_phase + 1) & 0xfff;
+}
+
+uint32_t awacs_macrisc_device::read_macrisc(offs_t offset)
+{
+ LOGMASKED(LOG_REGISTERS, "read AWACS @ %x\n", offset);
+ switch (offset)
+ {
+ case 0: // Audio Control
+ return 0;
+
+ case 4: // Audio CODEC Control
+ return 0;
+
+ case 8: // Audio CODEC Status
+ return 0x314000; // Screamer info
+ }
+
+ return 0;
+}
+
+void awacs_macrisc_device::write_macrisc(offs_t offset, uint32_t data)
+{
+ static const int rates[8] = { 512, 768, 1024, 1280, 1536, 2048, 2560, 3072 };
+
+ LOGMASKED(LOG_REGISTERS, "%s: %08x @ %x\n", tag(), data, offset*4);
+ switch (offset)
+ {
+ case 0: // Audio Control
+ m_stream->set_sample_rate(clock() / rates[(data >> 8) & 7]);
+ LOGMASKED(LOG_GENERAL, "%s: sample rate to %d Hz\n", tag(), clock() / rates[(data >> 8) & 7]);
+ break;
+
+ case 4: // Audio CODEC Control
+ {
+ int subframe = (data >> 22) & 0x3;
+ int codec_addr = (data >> 12) & 0xfff;
+ int codec_data = (data & 0xfff);
+
+ LOGMASKED(LOG_REGISTERS, "%s: CODEC control: %x to addr %x (subframe %d)\n", tag(), codec_data, codec_addr, subframe);
+
+ m_registers[codec_addr] = codec_data;
+ }
+ break;
+
+ case 8: // Audio CODEC Status
+ break;
+
+ case 12: // Byte swap
+ printf("CODEC byte swap: %08x\n", data);
+ break;
+ }
+}
+
+// Screamer
+uint32_t screamer_device::read_macrisc(offs_t offset)
+{
+ switch (offset)
+ {
+ case 0: // Audio Control
+ return 0;
+
+ case 4: // Audio CODEC Control
+ return 0;
+
+ case 8: // Audio CODEC Status
+ return swapendian_int32((0x40 << 8) | // indicate CODEC is present
+ (1 << 16) | // manufacturer is Crystal Semiconductor
+ (3 << 20)); // CODEC version 3 (Screamer)
+ }
+
+ return 0;
+}
+
+void screamer_device::write_macrisc(offs_t offset, uint32_t data)
+{
+ awacs_macrisc_device::write_macrisc(offset, data);
+
+ // if IDLE bit is off, we're active
+ if (!BIT(m_registers[6], 1))
+ {
+ m_active |= ACTIVE_OUT;
+ }
+ else
+ {
+ m_active &= ~ACTIVE_OUT;
+ }
+ LOGMASKED(LOG_GENERAL, "%s: Playback %s reg 6 %x)\n", tag(), !BIT(m_registers[6], 1) ? "on" : "off", m_registers[6]);
+}
diff --git a/src/mame/apple/awacs_macrisc.h b/src/mame/apple/awacs_macrisc.h
new file mode 100644
index 00000000000..3941fb29062
--- /dev/null
+++ b/src/mame/apple/awacs_macrisc.h
@@ -0,0 +1,76 @@
+// license:BSD-3-Clause
+// copyright-holders:R. Belmont
+/***************************************************************************
+
+ awacs_macrisc.h
+
+ AWACS/Screamer 16-bit audio I/O for "MacRisc" architecture Macs (PCI-based)
+
+***************************************************************************/
+
+#ifndef MAME_APPLE_AWACS_MACRISC_H
+#define MAME_APPLE_AWACS_MACRISC_H
+
+#pragma once
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> awacs_macrisc_device
+
+class awacs_macrisc_device : public device_t, public device_sound_interface
+{
+public:
+ // construction/destruction
+ awacs_macrisc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ auto dma_output() { return m_output_cb.bind(); }
+ auto dma_input() { return m_input_cb.bind(); }
+
+ virtual u32 read_macrisc(offs_t offset);
+ virtual void write_macrisc(offs_t offset, u32 data);
+
+protected:
+ awacs_macrisc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
+ enum {
+ ACTIVE_OUT = 0x01,
+ ACTIVE_IN = 0x02
+ };
+
+ static const u8 divider[4];
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
+
+ devcb_read32 m_output_cb;
+ devcb_write32 m_input_cb;
+
+ sound_stream *m_stream;
+
+ u32 m_registers[16];
+ u8 m_active;
+ u16 m_phase;
+};
+
+class screamer_device : public awacs_macrisc_device
+{
+public:
+ screamer_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ virtual u32 read_macrisc(offs_t offset) override;
+ virtual void write_macrisc(offs_t offset, u32 data) override;
+
+protected:
+ virtual void device_reset() override;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(AWACS_MACRISC, awacs_macrisc_device)
+DECLARE_DEVICE_TYPE(SCREAMER, screamer_device)
+
+#endif // MAME_APPLE_AWACS_MACRISC_H
diff --git a/src/mame/apple/bandit.cpp b/src/mame/apple/bandit.cpp
index ee2008417b3..3bed4f837fd 100644
--- a/src/mame/apple/bandit.cpp
+++ b/src/mame/apple/bandit.cpp
@@ -156,14 +156,13 @@ void bandit_host_device::be_config_data_w(offs_t offset, u32 data, u32 mem_mask)
template <u32 Base>
u32 bandit_host_device::pci_memory_r(offs_t offset, u32 mem_mask)
{
- u32 result = this->space(AS_PCI_MEM).read_dword(Base + (offset * 4), mem_mask);
- return result;
+ return swapendian_int32(this->space(AS_PCI_MEM).read_dword(Base + (offset * 4), swapendian_int32(mem_mask)));
}
template <u32 Base>
void bandit_host_device::pci_memory_w(offs_t offset, u32 data, u32 mem_mask)
{
- this->space(AS_PCI_MEM).write_dword(Base + (offset * 4), data, mem_mask);
+ this->space(AS_PCI_MEM).write_dword(Base + (offset * 4), swapendian_int32(data), swapendian_int32((mem_mask)));
}
template u32 bandit_host_device::pci_memory_r<0x80000000>(offs_t offset, u32 mem_mask);
@@ -180,14 +179,13 @@ template void bandit_host_device::pci_memory_w<0xf7000000>(offs_t offset, u32 da
template <u32 Base>
u32 bandit_host_device::pci_io_r(offs_t offset, u32 mem_mask)
{
- u32 result = this->space(AS_PCI_IO).read_dword(Base + (offset * 4), mem_mask);
- return result;
+ return swapendian_int32(this->space(AS_PCI_IO).read_dword(Base + (offset * 4), swapendian_int32(mem_mask)));
}
template <u32 Base>
void bandit_host_device::pci_io_w(offs_t offset, u32 data, u32 mem_mask)
{
- this->space(AS_PCI_IO).write_dword(Base + (offset * 4), data, mem_mask);
+ this->space(AS_PCI_IO).write_dword(Base + (offset * 4), swapendian_int32(data), swapendian_int32((mem_mask)));
}
// map PCI memory and I/O space stuff here
diff --git a/src/mame/apple/burgundy.cpp b/src/mame/apple/burgundy.cpp
new file mode 100644
index 00000000000..2f071929c00
--- /dev/null
+++ b/src/mame/apple/burgundy.cpp
@@ -0,0 +1,169 @@
+// license:BSD-3-Clause
+// copyright-holders:R. Belmont
+/***************************************************************************
+
+ burgundy.cpp
+
+ "Burgundy" stereo 16-bit audio CODEC (iMac, Blue & White G3)
+
+***************************************************************************/
+
+#include "emu.h"
+#include "burgundy.h"
+
+#define LOG_GENERAL (1U << 0)
+#define LOG_REGISTERS (1U << 0)
+
+#define VERBOSE (0)
+#include "logmacro.h"
+
+// device type definition
+DEFINE_DEVICE_TYPE(BURGUNDY, burgundy_device, "burgundy", "Burgundy audio I/O")
+
+constexpr u32 CODEC_BUSY = (1 << 23);
+constexpr u32 CODEC_PRESENT = (1 << 22);
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// burgundy_device - constructor
+//-------------------------------------------------
+
+burgundy_device::burgundy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, BURGUNDY, tag, owner, clock)
+ , device_sound_interface(mconfig, *this)
+ , m_output_cb(*this)
+ , m_input_cb(*this)
+ , m_stream(nullptr)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void burgundy_device::device_start()
+{
+ // create the stream
+ m_stream = stream_alloc(0, 2, clock() / 512, STREAM_SYNCHRONOUS);
+
+ m_output_cb.resolve_safe(0);
+ m_input_cb.resolve_safe();
+
+ save_item(NAME(m_phase));
+ save_item(NAME(m_active));
+ save_item(NAME(m_registers));
+ save_item(NAME(m_codec_status));
+ save_item(NAME(m_counter));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void burgundy_device::device_reset()
+{
+ m_phase = 0;
+ m_codec_status = 0;
+ m_counter = 0;
+ m_stream->set_sample_rate(clock() / 512);
+}
+
+
+//-------------------------------------------------
+// sound_stream_update - handle update requests for
+// our sound stream
+//-------------------------------------------------
+
+void burgundy_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
+{
+ if (m_codec_status & CODEC_BUSY)
+ {
+ m_codec_status &= ~CODEC_BUSY; // clear busy
+ m_counter++;
+ m_counter &= 3;
+ }
+
+ if (m_active & ACTIVE_OUT)
+ {
+ const u32 data = swapendian_int32(m_output_cb(m_phase));
+ const s16 left = data >> 16;
+ const s16 right = data;
+ outputs[0].put_int(0, left, 32768);
+ outputs[1].put_int(0, right, 32768);
+ }
+ else
+ {
+ outputs[0].put_int(0, 0, 32768);
+ outputs[1].put_int(0, 0, 32768);
+ }
+
+ m_phase = (m_phase + 1) & 0xfff;
+}
+
+uint32_t burgundy_device::read_macrisc(offs_t offset)
+{
+ switch (offset)
+ {
+ case 0: // Audio Control
+ return 0;
+
+ case 4: // Audio CODEC Control
+ return m_last_codec_control;
+
+ case 8: // Audio CODEC Status
+ return m_codec_status;
+ }
+
+ return 0;
+}
+
+void burgundy_device::write_macrisc(offs_t offset, uint32_t data)
+{
+ switch (offset)
+ {
+ case 0: // Audio Control
+ break;
+
+ case 4: // Audio CODEC Control
+ m_last_codec_control = data;
+
+ m_reg_addr = (data >> 12) & 0xff;
+ m_cur_byte = (data >> 8) & 3;
+ m_last_byte = (data >> 10) & 3;
+
+ if (BIT(data, 21))
+ {
+ u32 reg_mask = 0xff << (m_cur_byte << 3);
+ m_registers[m_reg_addr] &= ~reg_mask;
+ m_registers[m_reg_addr] |= ((data & 0xff) << (m_cur_byte << 3));
+ LOGMASKED(LOG_REGISTERS, "%s: reg %x is now %x\n", tag(), m_reg_addr, m_registers[m_reg_addr]);
+
+ if (m_reg_addr == 0x60)
+ {
+ if ((m_registers[0x60] & 6) != 0)
+ {
+ LOGMASKED(LOG_GENERAL, "%s: Playback enabled\n", tag());
+ m_active |= ACTIVE_OUT;
+ }
+ else
+ {
+ LOGMASKED(LOG_GENERAL, "%s: Playback disabled\n", tag());
+ m_active &= ~ACTIVE_OUT;
+ }
+ }
+ }
+ else
+ {
+ u8 reg_data = (m_registers[m_reg_addr] >> (m_cur_byte << 3)) & 0xff;
+ m_codec_status = CODEC_BUSY | CODEC_PRESENT | (m_counter << 14) | (m_cur_byte << 12) | (reg_data << 4);
+ }
+ break;
+
+ case 8: // Audio CODEC Status
+ break;
+ }
+}
diff --git a/src/mame/apple/burgundy.h b/src/mame/apple/burgundy.h
new file mode 100644
index 00000000000..ca40ab29443
--- /dev/null
+++ b/src/mame/apple/burgundy.h
@@ -0,0 +1,62 @@
+// license:BSD-3-Clause
+// copyright-holders:R. Belmont
+/***************************************************************************
+
+ burgundy.h
+
+ "Burgundy" stereo 16-bit audio CODEC (iMac, Blue & White G3)
+
+***************************************************************************/
+
+#ifndef MAME_APPLE_BURGUNDY_H
+#define MAME_APPLE_BURGUNDY_H
+
+#pragma once
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> awacs_macrisc_device
+
+class burgundy_device : public device_t, public device_sound_interface
+{
+public:
+ // construction/destruction
+ burgundy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ auto dma_output() { return m_output_cb.bind(); }
+ auto dma_input() { return m_input_cb.bind(); }
+
+ virtual u32 read_macrisc(offs_t offset);
+ virtual void write_macrisc(offs_t offset, u32 data);
+
+protected:
+ enum {
+ ACTIVE_OUT = 0x01,
+ ACTIVE_IN = 0x02
+ };
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
+
+ devcb_read32 m_output_cb;
+ devcb_write32 m_input_cb;
+
+ sound_stream *m_stream;
+
+ u32 m_registers[256];
+ u8 m_active;
+ u16 m_phase;
+ u16 m_reg_addr, m_cur_byte, m_last_byte;
+ u32 m_codec_status, m_last_codec_control;
+ u8 m_counter;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(BURGUNDY, burgundy_device)
+
+#endif // MAME_APPLE_BURGUNDY_H
diff --git a/src/mame/apple/dbdma.cpp b/src/mame/apple/dbdma.cpp
new file mode 100644
index 00000000000..cd10acc5561
--- /dev/null
+++ b/src/mame/apple/dbdma.cpp
@@ -0,0 +1,273 @@
+// license:BSD-3-Clause
+// copyright-holders:R. Belmont
+/*
+ Apple "Descriptor-Based DMA" channel device
+ Emulation by R. Belmont
+*/
+
+#include "emu.h"
+#include "dbdma.h"
+
+#define LOG_GENERAL (1U << 0)
+
+#define VERBOSE (0)
+#include "logmacro.h"
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(DBDMA_CHANNEL, dbdma_device, "appledbdma", "Apple descriptor-based DMA channel")
+
+static constexpr u16 STATUS_RUN = 0x8000;
+static constexpr u16 STATUS_PAUSE = 0x4000;
+static constexpr u16 STATUS_FLUSH = 0x2000;
+static constexpr u16 STATUS_WAKE = 0x1000;
+[[maybe_unused]] static constexpr u16 STATUS_DEAD = 0x0800;
+static constexpr u16 STATUS_ACTIVE = 0x0400;
+
+//-------------------------------------------------
+// dbdma_device - constructor
+//-------------------------------------------------
+
+dbdma_device::dbdma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, DBDMA_CHANNEL, tag, owner, clock),
+ write_irq(*this)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void dbdma_device::device_start()
+{
+ write_irq.resolve_safe();
+
+ save_item(NAME(m_status));
+ save_item(NAME(m_command_pointer));
+ save_item(NAME(m_intselect));
+ save_item(NAME(m_branchselect));
+ save_item(NAME(m_waitselect));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void dbdma_device::device_reset()
+{
+ m_status = 0;
+ m_command_pointer = 0;
+ m_intselect = m_branchselect = m_waitselect = 0;
+}
+
+// 00 = control (write only)
+// 04 = status (read only)
+// 0c = command pointer (read/write)
+// 10 = interrupt select
+// 14 = branch select
+// 18 = wait select
+
+void dbdma_device::map(address_map &map)
+{
+ map(0x00, 0x03).w(FUNC(dbdma_device::control_w));
+ map(0x04, 0x07).r(FUNC(dbdma_device::status_r));
+ map(0x0c, 0x0f).rw(FUNC(dbdma_device::cmdpointer_r), FUNC(dbdma_device::cmdpointer_w));
+ map(0x10, 0x13).rw(FUNC(dbdma_device::intselect_r), FUNC(dbdma_device::intselect_w));
+ map(0x14, 0x17).rw(FUNC(dbdma_device::branchselect_r), FUNC(dbdma_device::branchselect_w));
+ map(0x18, 0x1b).rw(FUNC(dbdma_device::waitselect_r), FUNC(dbdma_device::waitselect_w));
+}
+
+void dbdma_device::control_w(u32 data)
+{
+ // the top 16 bits of data are a mask selecting which bits of
+ // the status are changed by the write.
+ const u16 mask = (data >> 16);
+
+ m_status &= (mask ^ 0xffff);
+ m_status |= (data & mask);
+ LOGMASKED(LOG_GENERAL, "%s: channel status/control to %04x (raw %08x)\n", tag(), m_status, data);
+
+ if (m_status & STATUS_RUN)
+ {
+ LOGMASKED(LOG_GENERAL, "%s: channel set to RUN, also setting ACTIVE\n", tag());
+ m_status |= STATUS_ACTIVE;
+ }
+ else
+ {
+ m_status &= ~STATUS_ACTIVE;
+ }
+
+ if (m_status & STATUS_PAUSE)
+ {
+ m_status &= ~STATUS_ACTIVE;
+ }
+
+ if (m_status & STATUS_FLUSH)
+ {
+ // TODO
+ }
+
+ if (m_status & STATUS_WAKE)
+ {
+ // TODO
+ }
+}
+
+u32 dbdma_device::status_r()
+{
+ return m_status;
+}
+
+u32 dbdma_device::cmdpointer_r()
+{
+ return m_command_pointer;
+}
+
+void dbdma_device::cmdpointer_w(u32 data)
+{
+ if (!(m_status & STATUS_ACTIVE))
+ {
+ LOGMASKED(LOG_GENERAL, "%s: %08x to command pointer\n", tag(), swapendian_int32(data));
+ m_command_pointer = data;
+
+ new_command();
+ }
+}
+
+u32 dbdma_device::intselect_r()
+{
+ return m_intselect;
+}
+
+void dbdma_device::intselect_w(u32 data)
+{
+ m_intselect = data;
+}
+
+u32 dbdma_device::branchselect_r()
+{
+ return m_branchselect;
+}
+
+void dbdma_device::branchselect_w(u32 data)
+{
+ m_branchselect = data;
+}
+
+u32 dbdma_device::waitselect_r()
+{
+ return m_waitselect;
+}
+
+void dbdma_device::waitselect_w(u32 data)
+{
+ m_waitselect = data;
+}
+
+u32 dbdma_device::dma_read(u32 offset)
+{
+ step_program();
+ return m_xfer_word;
+}
+
+void dbdma_device::dma_write(u32 offset, u32 data)
+{
+ m_xfer_word = data;
+ step_program();
+}
+
+void dbdma_device::step_program()
+{
+ if ((m_status & STATUS_PAUSE) || !(m_status & STATUS_ACTIVE))
+ {
+ return;
+ }
+
+ switch (m_opcode >> 28)
+ {
+ case 0: // OUTPUT MORE
+ case 1: // OUTPUT LAST
+ m_xfer_word = m_pci_memory->read_dword(m_address);
+ m_address += 4;
+ m_currentXfer += 4;
+ break;
+
+ case 2: // INPUT MORE
+ case 3: // INPUT LAST
+ m_pci_memory->write_dword(m_address, m_xfer_word);
+ m_address += 4;
+ m_currentXfer += 4;
+ break;
+
+ case 4: // STORE QUAD
+ switch (m_xferLimit & 7)
+ {
+ case 1:
+ m_pci_memory->write_byte(m_address, m_cmdDep);
+ break;
+
+ case 2:
+ m_pci_memory->write_word(m_address, m_cmdDep);
+ break;
+
+ case 4:
+ m_pci_memory->write_dword(m_address, m_cmdDep);
+ break;
+ }
+ m_currentXfer += m_opcode & 7;
+ break;
+
+ case 5: // LOAD QUAD
+ switch (m_xferLimit & 7)
+ {
+ case 1:
+ m_xfer_word = m_pci_memory->read_byte(m_address);
+ m_pci_memory->write_byte(m_cmdDep, m_xfer_word);
+ break;
+
+ case 2:
+ m_xfer_word = m_pci_memory->read_word(m_address);
+ m_pci_memory->write_word(m_cmdDep, m_xfer_word);
+ break;
+
+ case 4:
+ m_xfer_word = m_pci_memory->read_dword(m_address);
+ m_pci_memory->write_dword(m_cmdDep, m_xfer_word);
+ break;
+ }
+ m_currentXfer += m_opcode & 7;
+ break;
+
+ case 6: // NOP
+ break;
+
+ case 7: // STOP
+ m_status &= ~STATUS_ACTIVE;
+ break;
+ }
+
+ if (m_status & STATUS_ACTIVE)
+ {
+ if (m_currentXfer >= m_xferLimit)
+ {
+ m_command_pointer += 16;
+ LOGMASKED(LOG_GENERAL, "%s: Advancing command pointer to %08x\n", tag(), m_command_pointer);
+ new_command();
+ }
+ }
+}
+
+void dbdma_device::new_command()
+{
+ m_opcode = m_pci_memory->read_dword(m_command_pointer);
+ m_address = m_pci_memory->read_dword(m_command_pointer + 4);
+ m_cmdDep = m_pci_memory->read_dword(m_command_pointer + 8);
+ m_statusCount = m_pci_memory->read_dword(m_command_pointer + 12);
+ m_currentXfer = m_statusCount & 0xffff;
+ m_xferLimit = m_opcode & 0xffff;
+
+ LOGMASKED(LOG_GENERAL, "%s: new command %08x %08x %08x %08x\n", tag(), m_opcode, m_address, m_cmdDep, m_statusCount);
+ LOGMASKED(LOG_GENERAL, "%s: opcode %d\n", tag(), m_opcode >> 28);
+}
diff --git a/src/mame/apple/dbdma.h b/src/mame/apple/dbdma.h
new file mode 100644
index 00000000000..191109805d2
--- /dev/null
+++ b/src/mame/apple/dbdma.h
@@ -0,0 +1,69 @@
+// license:BSD-3-Clause
+// copyright-holders:R. Belmont
+
+#ifndef MAME_APPLE_DBDMA_H
+#define MAME_APPLE_DBDMA_H
+
+#pragma once
+
+
+// ======================> dbdma_device
+
+class dbdma_device : public device_t
+{
+public:
+ // construction/destruction
+ dbdma_device(const machine_config &mconfig, const char *tag, device_t *owner)
+ : dbdma_device(mconfig, tag, owner, (uint32_t)0)
+ {
+ }
+
+ dbdma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ u32 dma_read(u32 offset);
+ void dma_write(u32 offset, u32 data);
+
+ auto irq_callback() { return write_irq.bind(); }
+
+ void set_address_space(address_space *space) { m_pci_memory = space; }
+
+ void map(address_map &map);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ devcb_write_line write_irq;
+
+ address_space *m_pci_memory;
+
+ u16 m_status;
+ u32 m_command_pointer;
+ u32 m_intselect;
+ u32 m_branchselect;
+ u32 m_waitselect;
+ u32 m_xfer_word;
+ u32 m_opcode, m_address, m_cmdDep, m_statusCount;
+ u16 m_currentXfer, m_xferLimit;
+
+ void control_w(u32 data);
+ u32 status_r();
+ u32 cmdpointer_r();
+ void cmdpointer_w(u32 data);
+ u32 intselect_r();
+ void intselect_w(u32 data);
+ u32 branchselect_r();
+ void branchselect_w(u32 data);
+ u32 waitselect_r();
+ void waitselect_w(u32 data);
+
+ void step_program();
+ void new_command();
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(DBDMA_CHANNEL, dbdma_device)
+
+#endif // MAME_APPLE_DBDMA_H
diff --git a/src/mame/apple/heathrow.cpp b/src/mame/apple/heathrow.cpp
index 83c06520d62..d69a096dc79 100644
--- a/src/mame/apple/heathrow.cpp
+++ b/src/mame/apple/heathrow.cpp
@@ -6,7 +6,7 @@
These ASICs sit on the PCI bus and provide what came to be known as "Mac I/O",
including:
- - A VIA to interface with Cuda
+ - A VIA to interface with Cuda / an enhanced VIA that can speak SPI to interface with PG&E (O'Hare and later)
- Serial
- SWIM3 floppy
- MESH SCSI ("Macintosh Enhanced SCSI Handler"), a 5394/96 clone with some features Apple didn't use removed)
@@ -22,6 +22,12 @@
#include "bus/rs232/rs232.h"
#include "formats/ap_dsk35.h"
+#define LOG_GENERAL (1U << 0)
+#define LOG_IRQ (1U << 1)
+
+#define VERBOSE (0)
+#include "logmacro.h"
+
static constexpr u32 C7M = 7833600;
static constexpr u32 C15M = (C7M * 2);
@@ -37,27 +43,51 @@ DEFINE_DEVICE_TYPE(GRAND_CENTRAL, grandcentral_device, "grndctrl", "Apple Grand
//-------------------------------------------------
// ADDRESS_MAP
//-------------------------------------------------
-/*
- A "Kanga" G3 PowerBook says:
- 16000 : VIA
- 12000 : SCC Rd
- 12000 : SCC Wr
- 15000 : IWM/SWIM
- 10000 : SCSI
-
- DMA is at 8xxx (audio DMA at 88xx)
- ATA is at 20000
+/* Grand Central O'Hare Heathrow/Paddington
+0x10000 SCSI0 SCSI0 SCSI
+0x11000 MACE Ethernet (unused) "BigMac" Ethernet
+0x12000 SCC "compatibility" SCC compat SCC compat
+0x13000 SCC "MacRisc" SCC MacRisc SCC MacRisc
+0x14000 Audio Audio Audio
+0x15000 SWIM3 SWIM3 SWIM3
+0x16000 VIA VIA VIA
+0x17000 VIA VIA VIA
+0x18000 SCSI1 (unused) (unused)
+0x19000 Ethernet MAC PROM (unused) ADB Master Cell
+0x1a000 (external IOBus) (external IOBus) (external IOBus)
+0x1b000 (external IOBus) (external IOBus) (external IOBus)
+0x1c000 (external IOBus) (external IOBus) (external IOBus)
+0x1d000 (external IOBus) (external IOBus) (external IOBus)
+0x1e000 (external IOBus) (unused)
+0x1f000 (external IOBus) (unused)
+0x20000 (external IOBus) ATA bus 0 ATA bus 0
+0x21000 (external IOBus) ATA bus 1 ATA bus 1
+0x60000 (128K BAR, no) PRAM PRAM
+0x70000 (128K BAR, no) PRAM PRAM
*/
+void grandcentral_device::map(address_map &map)
+{
+ map(0x00000, 0x00fff).rw(FUNC(grandcentral_device::macio_r), FUNC(grandcentral_device::macio_w));
+ map(0x08800, 0x0881f).m(m_dma_audio_out, FUNC(dbdma_device::map));
+ map(0x08900, 0x0891f).m(m_dma_audio_in, FUNC(dbdma_device::map));
+ map(0x12000, 0x12fff).rw(FUNC(grandcentral_device::scc_r), FUNC(grandcentral_device::scc_w));
+ map(0x13000, 0x13fff).rw(FUNC(grandcentral_device::scc_macrisc_r), FUNC(grandcentral_device::scc_macrisc_w));
+ map(0x14000, 0x140ff).rw(FUNC(heathrow_device::codec_r), FUNC(heathrow_device::codec_w));
+ map(0x15000, 0x15fff).rw(FUNC(grandcentral_device::fdc_r), FUNC(grandcentral_device::fdc_w));
+ map(0x16000, 0x17fff).rw(FUNC(grandcentral_device::mac_via_r), FUNC(grandcentral_device::mac_via_w));
+}
+
void heathrow_device::map(address_map &map)
{
map(0x00000, 0x00fff).rw(FUNC(heathrow_device::macio_r), FUNC(heathrow_device::macio_w));
+ map(0x08800, 0x0881f).m(m_dma_audio_out, FUNC(dbdma_device::map));
+ map(0x08900, 0x0891f).m(m_dma_audio_in, FUNC(dbdma_device::map));
map(0x12000, 0x12fff).rw(FUNC(heathrow_device::scc_r), FUNC(heathrow_device::scc_w));
map(0x13000, 0x13fff).rw(FUNC(heathrow_device::scc_macrisc_r), FUNC(heathrow_device::scc_macrisc_w));
- map(0x14000, 0x1401f).rw(m_awacs, FUNC(awacs_device::read), FUNC(awacs_device::write));
- map(0x14020, 0x14023).r(FUNC(heathrow_device::unk_r));
+ map(0x14000, 0x140ff).rw(FUNC(heathrow_device::codec_r), FUNC(heathrow_device::codec_w));
map(0x15000, 0x15fff).rw(FUNC(heathrow_device::fdc_r), FUNC(heathrow_device::fdc_w));
map(0x16000, 0x17fff).rw(FUNC(heathrow_device::mac_via_r), FUNC(heathrow_device::mac_via_w));
- map(0x60000, 0x7ffff).rw(FUNC(heathrow_device::nvram_r), FUNC(heathrow_device::nvram_w));
+ map(0x60000, 0x7ffff).rw(FUNC(heathrow_device::nvram_r), FUNC(heathrow_device::nvram_w)).umask32(0x000000ff);
}
//-------------------------------------------------
@@ -71,16 +101,13 @@ void heathrow_device::device_add_mconfig(machine_config &config)
m_via1->writepa_handler().set(FUNC(heathrow_device::via_out_a));
m_via1->writepb_handler().set(FUNC(heathrow_device::via_out_b));
m_via1->cb2_handler().set(FUNC(heathrow_device::via_out_cb2));
- m_via1->irq_handler().set(FUNC(heathrow_device::via1_irq));
+ m_via1->irq_handler().set(FUNC(heathrow_device::set_irq_line<18>));
- AWACS(config, m_awacs, 45.1584_MHz_XTAL / 2);
- m_awacs->dma_output().set(FUNC(heathrow_device::sound_dma_output));
- m_awacs->dma_input().set(FUNC(heathrow_device::sound_dma_input));
+ DBDMA_CHANNEL(config, m_dma_audio_out, 0);
+ m_dma_audio_out->irq_callback().set(FUNC(heathrow_device::set_irq_line<8>));
- SPEAKER(config, "lspeaker").front_left();
- SPEAKER(config, "rspeaker").front_right();
- m_awacs->add_route(0, "lspeaker", 1.0);
- m_awacs->add_route(1, "rspeaker", 1.0);
+ DBDMA_CHANNEL(config, m_dma_audio_in, 0);
+ m_dma_audio_in->irq_callback().set(FUNC(heathrow_device::set_irq_line<9>));
SWIM3(config, m_fdc, C15M);
m_fdc->devsel_cb().set(FUNC(heathrow_device::devsel_w));
@@ -116,16 +143,21 @@ void heathrow_device::config_map(address_map &map)
heathrow_device::heathrow_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: pci_device(mconfig, type, tag, owner, clock),
+ write_irq(*this),
write_pb4(*this),
write_pb5(*this),
write_cb2(*this),
read_pb3(*this),
+ read_codec(*this),
+ write_codec(*this),
m_maincpu(*this, finder_base::DUMMY_TAG),
m_via1(*this, "via1"),
m_fdc(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U),
- m_awacs(*this, "awacs"),
m_scc(*this, "scc"),
+ m_dma_audio_in(*this, "dma_audin"),
+ m_dma_audio_out(*this, "dma_audout"),
+ m_pci_memory(*this, ":pci:00.0", AS_DATA),
m_cur_floppy(nullptr),
m_hdsel(0)
{
@@ -158,41 +190,58 @@ ohare_device::ohare_device(const machine_config &mconfig, const char *tag, devic
void heathrow_device::common_init()
{
+ write_irq.resolve_safe();
write_pb4.resolve_safe();
write_pb5.resolve_safe();
write_cb2.resolve_safe();
read_pb3.resolve_safe(0);
+ read_codec.resolve_safe(0);
+ write_codec.resolve_safe();
- m_6015_timer = timer_alloc(FUNC(heathrow_device::mac_6015_tick), this);
- m_6015_timer->adjust(attotime::never);
- save_item(NAME(m_hdsel));
+ m_dma_audio_out->set_address_space(m_pci_memory);
- add_map(0x80000, M_MEM, FUNC(heathrow_device::map));
command = 2; // enable our memory range
revision = 1;
+
+ m_InterruptEvents = m_InterruptMask = m_InterruptLevels = 0;
+ m_InterruptEvents2 = m_InterruptMask2 = m_InterruptLevels2 = 0;
+ recalc_irqs();
+
+ save_item(NAME(m_hdsel));
+ save_item(NAME(m_InterruptEvents));
+ save_item(NAME(m_InterruptMask));
+ save_item(NAME(m_InterruptLevels));
+ save_item(NAME(m_InterruptEvents2));
+ save_item(NAME(m_InterruptMask2));
+ save_item(NAME(m_InterruptLevels2));
+ save_item(NAME(m_nvram));
}
void heathrow_device::device_start()
{
common_init();
+ add_map(0x80000, M_MEM, FUNC(heathrow_device::map));
set_ids(0x106b0010, 0x01, 0xff000001, 0x000000);
}
void paddington_device::device_start()
{
common_init();
+ add_map(0x80000, M_MEM, FUNC(heathrow_device::map));
set_ids(0x106b0017, 0x01, 0xff000001, 0x000000);
}
void grandcentral_device::device_start()
{
common_init();
+ add_map(0x20000, M_MEM, FUNC(heathrow_device::map)); // Grand Central only has 128K of BAR space, the others have 512K
set_ids(0x106b0002, 0x01, 0xff000001, 0x000000);
}
void ohare_device::device_start()
{
common_init();
+ add_map(0x80000, M_MEM, FUNC(heathrow_device::map));
set_ids(0x106b0007, 0x01, 0xff000001, 0x000000);
}
@@ -202,18 +251,9 @@ void ohare_device::device_start()
void heathrow_device::device_reset()
{
- // start 60.15 Hz timer
- m_6015_timer->adjust(attotime::from_hz(60.15), 0, attotime::from_hz(60.15));
-
m_hdsel = 0;
}
-TIMER_CALLBACK_MEMBER(heathrow_device::mac_6015_tick)
-{
- m_via1->write_ca1(CLEAR_LINE);
- m_via1->write_ca1(ASSERT_LINE);
-}
-
u8 heathrow_device::via_in_a()
{
return 0x80;
@@ -248,10 +288,6 @@ void heathrow_device::via_out_b(u8 data)
write_pb5(BIT(data, 5));
}
-WRITE_LINE_MEMBER(heathrow_device::via1_irq)
-{
-}
-
WRITE_LINE_MEMBER(heathrow_device::cb1_w)
{
m_via1->write_cb1(state);
@@ -353,13 +389,126 @@ void heathrow_device::devsel_w(u8 devsel)
u32 heathrow_device::macio_r(offs_t offset)
{
+ // InterruptLevels = live status of all interrupt lines
+ // InterruptMask = mask to determine which bits of InterruptLevels matter
+ // InterruptEvents = interrupts allowed to fire by InterruptMask
// printf("macio_r: offset %x (%x)\n", offset, offset*4);
+ switch (offset << 2)
+ {
+ case 0x10:
+ return swapendian_int32(m_InterruptEvents2 & m_InterruptMask2);
+ case 0x14:
+ return swapendian_int32(m_InterruptMask2);
+ case 0x1c:
+ return swapendian_int32(m_InterruptLevels2);
+ case 0x20:
+ return swapendian_int32(m_InterruptEvents & m_InterruptMask);
+ case 0x24:
+ return swapendian_int32(m_InterruptMask);
+ case 0x2c:
+ return swapendian_int32(m_InterruptLevels);
+ }
return 0;
}
void heathrow_device::macio_w(offs_t offset, u32 data, u32 mem_mask)
{
+ data = swapendian_int32(data);
+ mem_mask = swapendian_int32(mem_mask);
// printf("macio_w: offset %x (%x) data %08x mask %08x\n", offset, offset*4, data, mem_mask);
+ switch (offset << 2)
+ {
+ case 0x14:
+ m_InterruptMask2 = data;
+ recalc_irqs();
+ break;
+ case 0x18: // InterruptClear
+ // which interrupt mode?
+ if (BIT(m_InterruptMask2, 31))
+ {
+ // in Mode 1, "1" to bit 31 clears all active interrupts
+ if (BIT(data, 31))
+ {
+ m_InterruptEvents2 = 0;
+ }
+ else
+ {
+ m_InterruptEvents2 &= (data ^ 0xffffffff);
+ }
+ }
+ else
+ {
+ m_InterruptEvents2 &= (data ^ 0xffffffff);
+ }
+ recalc_irqs();
+ break;
+ case 0x24:
+ m_InterruptMask = data;
+ recalc_irqs();
+ break;
+ case 0x28: // InterruptClear
+ // which interrupt mode?
+ if (BIT(m_InterruptMask, 31))
+ {
+ // in Mode 1, "1" to bit 31 clears all active interrupts
+ if (BIT(data, 31))
+ {
+ m_InterruptEvents = 0;
+ }
+ else
+ {
+ m_InterruptEvents &= (data ^ 0xffffffff);
+ }
+ }
+ else
+ {
+ m_InterruptEvents &= (data ^ 0xffffffff);
+ }
+ recalc_irqs();
+ break;
+ }
+}
+
+void heathrow_device::recalc_irqs()
+{
+ LOGMASKED(LOG_IRQ, "%s recalc_irqs: events %08x levels %08x mask %08x\n", tag(), m_InterruptEvents, m_InterruptLevels, m_InterruptMask);
+ m_InterruptEvents = m_InterruptLevels & m_InterruptMask;
+ m_InterruptEvents2 = m_InterruptLevels2 & m_InterruptMask2;
+ if (m_InterruptEvents || m_InterruptEvents2)
+ {
+ write_irq(ASSERT_LINE);
+ }
+ else
+ {
+ write_irq(CLEAR_LINE);
+ }
+}
+
+template<int bit> WRITE_LINE_MEMBER(heathrow_device::set_irq_line)
+{
+ if (bit < 32)
+ {
+ if (state == ASSERT_LINE)
+ {
+ m_InterruptLevels |= (1 << bit);
+ }
+ else
+ {
+ m_InterruptLevels &= ((1 << bit) ^ 0xffffffff);
+ }
+ }
+ else
+ {
+ if (state == ASSERT_LINE)
+ {
+ m_InterruptLevels2 |= (1 << (bit-32));
+ }
+ else
+ {
+ m_InterruptLevels2 &= ((1 << (bit-32)) ^ 0xffffffff);
+ }
+ }
+ recalc_irqs();
}
u8 heathrow_device::fdc_r(offs_t offset)
@@ -374,12 +523,12 @@ void heathrow_device::fdc_w(offs_t offset, u8 data)
u8 heathrow_device::nvram_r(offs_t offset)
{
- return m_nvram[offset >> 2];
+ return m_nvram[offset>>2];
}
void heathrow_device::nvram_w(offs_t offset, u8 data)
{
- m_nvram[offset >> 2] = data;
+ m_nvram[offset>>2] = data;
}
u16 heathrow_device::scc_r(offs_t offset)
@@ -430,21 +579,23 @@ void heathrow_device::scc_macrisc_w(offs_t offset, u8 data)
}
}
-u32 heathrow_device::unk_r(offs_t offset)
+// Audio support
+uint32_t heathrow_device::codec_r(offs_t offset)
{
- m_toggle ^= 0xffffffff;
- return m_toggle;
+ return read_codec(offset);
}
-// *****************************************************
-// DMA
-// *****************************************************
+void heathrow_device::codec_w(offs_t offset, uint32_t data)
+{
+ write_codec(offset, data);
+}
-u32 heathrow_device::sound_dma_output(offs_t offset)
+u32 heathrow_device::codec_dma_read(u32 offset)
{
- return 0;
+ return m_dma_audio_out->dma_read(offset);
}
-void heathrow_device::sound_dma_input(offs_t offset, u32 value)
+void heathrow_device::codec_dma_write(u32 offset, u32 data)
{
+ m_dma_audio_in->dma_write(offset, data);
}
diff --git a/src/mame/apple/heathrow.h b/src/mame/apple/heathrow.h
index 8ceecf19195..548db815697 100644
--- a/src/mame/apple/heathrow.h
+++ b/src/mame/apple/heathrow.h
@@ -6,13 +6,14 @@
#pragma once
+#include "dbdma.h"
+
#include "machine/pci.h"
#include "machine/6522via.h"
#include "machine/applefdintf.h"
#include "machine/swim3.h"
#include "machine/z80scc.h"
#include "speaker.h"
-#include "sound/awacs.h"
// ======================> heathrow_device
@@ -24,19 +25,32 @@ public:
heathrow_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// interface routines
+ auto irq_callback() { return write_irq.bind(); }
auto pb4_callback() { return write_pb4.bind(); }
auto pb5_callback() { return write_pb5.bind(); }
auto cb2_callback() { return write_cb2.bind(); }
auto pb3_callback() { return read_pb3.bind(); }
- void map(address_map &map);
+ auto codec_r_callback() { return read_codec.bind(); }
+ auto codec_w_callback() { return write_codec.bind(); }
+
+ virtual void map(address_map &map);
template <typename... T> void set_maincpu_tag(T &&... args) { m_maincpu.set_tag(std::forward<T>(args)...); }
+ template <typename... T> void set_pci_root_tag(T &&... args) { m_pci_memory.set_tag(std::forward<T>(args)...); }
DECLARE_WRITE_LINE_MEMBER(cb1_w);
DECLARE_WRITE_LINE_MEMBER(cb2_w);
DECLARE_WRITE_LINE_MEMBER(scc_irq_w);
+ template <int bit> DECLARE_WRITE_LINE_MEMBER(set_irq_line);
+
+ u32 codec_dma_read(u32 offset);
+ void codec_dma_write(u32 offset, u32 data);
+
+ u32 codec_r(offs_t offset);
+ void codec_w(offs_t offset, u32 data);
+
protected:
// device-level overrides
virtual void device_start() override;
@@ -47,25 +61,45 @@ protected:
void common_init();
-private:
- emu_timer *m_6015_timer;
- devcb_write_line write_pb4, write_pb5, write_cb2;
+ uint16_t swim_r(offs_t offset, u16 mem_mask);
+ void swim_w(offs_t offset, u16 data, u16 mem_mask);
+
+ u32 macio_r(offs_t offset);
+ void macio_w(offs_t offset, u32 data, u32 mem_mask);
+
+ u8 fdc_r(offs_t offset);
+ void fdc_w(offs_t offset, u8 data);
+
+ u8 nvram_r(offs_t offset);
+ void nvram_w(offs_t offset, u8 data);
+
+ u16 scc_r(offs_t offset);
+ void scc_w(offs_t offset, u16 data);
+ u8 scc_macrisc_r(offs_t offset);
+ void scc_macrisc_w(offs_t offset, u8 data);
+
+ u16 mac_via_r(offs_t offset);
+ void mac_via_w(offs_t offset, u16 data, u16 mem_mask);
+
+ devcb_write_line write_irq, write_pb4, write_pb5, write_cb2;
devcb_read_line read_pb3;
+ devcb_read32 read_codec;
+ devcb_write32 write_codec;
+
required_device<cpu_device> m_maincpu;
required_device<via6522_device> m_via1;
required_device<applefdintf_device> m_fdc;
required_device_array<floppy_connector, 2> m_floppy;
- required_device<awacs_device> m_awacs;
required_device<z80scc_device> m_scc;
+ required_device<dbdma_device> m_dma_audio_in, m_dma_audio_out;
+ required_address_space m_pci_memory;
+private:
floppy_image_device *m_cur_floppy = nullptr;
int m_hdsel;
- u8 m_nvram[0x20000/4];
-
- u16 mac_via_r(offs_t offset);
- void mac_via_w(offs_t offset, u16 data, u16 mem_mask);
+ u8 m_nvram[0x20000];
u8 via_in_a();
u8 via_in_b();
@@ -74,36 +108,16 @@ private:
void via_sync();
void field_interrupts();
DECLARE_WRITE_LINE_MEMBER(via_out_cb2);
- DECLARE_WRITE_LINE_MEMBER(via1_irq);
- DECLARE_WRITE_LINE_MEMBER(via2_irq);
- DECLARE_WRITE_LINE_MEMBER(asc_irq);
- TIMER_CALLBACK_MEMBER(mac_6015_tick);
void phases_w(u8 phases);
void devsel_w(u8 devsel);
- uint16_t swim_r(offs_t offset, u16 mem_mask);
- void swim_w(offs_t offset, u16 data, u16 mem_mask);
-
- u32 macio_r(offs_t offset);
- void macio_w(offs_t offset, u32 data, u32 mem_mask);
-
- u8 fdc_r(offs_t offset);
- void fdc_w(offs_t offset, u8 data);
-
- u8 nvram_r(offs_t offset);
- void nvram_w(offs_t offset, u8 data);
-
- u16 scc_r(offs_t offset);
- void scc_w(offs_t offset, u16 data);
- u8 scc_macrisc_r(offs_t offset);
- void scc_macrisc_w(offs_t offset, u8 data);
u32 m_toggle;
- u32 unk_r(offs_t offset);
- // DMA
- u32 sound_dma_output(offs_t offset);
- void sound_dma_input(offs_t offset, u32 value);
+ // Interrupts
+ void recalc_irqs();
+ u32 m_InterruptEvents, m_InterruptMask, m_InterruptLevels;
+ u32 m_InterruptEvents2, m_InterruptMask2, m_InterruptLevels2;
};
class paddington_device : public heathrow_device
@@ -123,6 +137,8 @@ public:
// construction/destruction
grandcentral_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ void map(address_map &map) override;
+
protected:
// device-level overrides
virtual void device_start() override;
diff --git a/src/mame/apple/imacg3.cpp b/src/mame/apple/imacg3.cpp
index 19f793e330e..7bf0bbab2ed 100644
--- a/src/mame/apple/imacg3.cpp
+++ b/src/mame/apple/imacg3.cpp
@@ -25,6 +25,7 @@
#include "machine/pci.h"
#include "machine/pci-ide.h"
#include "machine/ram.h"
+#include "burgundy.h"
#include "cuda.h"
#include "heathrow.h"
#include "macadb.h"
@@ -54,6 +55,11 @@ private:
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
m_maincpu->set_input_line(INPUT_LINE_RESET, state);
}
+
+ WRITE_LINE_MEMBER(irq_w)
+ {
+ m_maincpu->set_input_line(PPC_IRQ, state);
+ }
};
imac_state::imac_state(const machine_config &mconfig, device_type type, const char *tag) :
@@ -116,6 +122,8 @@ void imac_state::imac(machine_config &config)
paddington_device &paddington(PADDINGTON(config, "pci:10.0", 0));
paddington.set_maincpu_tag("maincpu");
+ paddington.set_pci_root_tag(":pci:00.0", AS_DATA);
+ paddington.irq_callback().set(FUNC(imac_state::irq_w));
MACADB(config, m_macadb, 15.6672_MHz_XTAL);
@@ -151,6 +159,17 @@ void imac_state::imac(machine_config &config)
RAM(config, m_ram);
m_ram->set_default_size("32M");
m_ram->set_extra_options("32M,64M,128M");
+
+ burgundy_device &burgundy(BURGUNDY(config, "codec", 45.1584_MHz_XTAL / 2));
+ burgundy.dma_output().set(paddington, FUNC(heathrow_device::codec_dma_read));
+
+ paddington.codec_r_callback().set(burgundy, FUNC(burgundy_device::read_macrisc));
+ paddington.codec_w_callback().set(burgundy, FUNC(burgundy_device::write_macrisc));
+
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+ burgundy.add_route(0, "lspeaker", 1.0);
+ burgundy.add_route(1, "rspeaker", 1.0);
}
ROM_START(imac)
diff --git a/src/mame/apple/pippin.cpp b/src/mame/apple/pippin.cpp
index 488d2f3749d..db7f54026c9 100644
--- a/src/mame/apple/pippin.cpp
+++ b/src/mame/apple/pippin.cpp
@@ -52,6 +52,7 @@
#include "machine/ram.h"
#include "sound/cdda.h"
+#include "awacs_macrisc.h"
#include "bandit.h"
#include "cuda.h"
#include "heathrow.h"
@@ -59,15 +60,15 @@
#include "softlist.h"
#include "speaker.h"
-class macpci_state : public driver_device
+class pippin_state : public driver_device
{
public:
void pippin(machine_config &config);
- macpci_state(const machine_config &mconfig, device_type type, const char *tag);
+ pippin_state(const machine_config &mconfig, device_type type, const char *tag);
required_device<cpu_device> m_maincpu;
- required_device<aspen_host_device> m_bandit;
+ required_device<aspen_host_device> m_aspen;
required_device<cuda_device> m_cuda;
required_device<macadb_device> m_macadb;
required_device<ram_device> m_ram;
@@ -85,29 +86,34 @@ private:
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
m_maincpu->set_input_line(INPUT_LINE_RESET, state);
}
+
+ WRITE_LINE_MEMBER(irq_w)
+ {
+ m_maincpu->set_input_line(PPC_IRQ, state);
+ }
};
-macpci_state::macpci_state(const machine_config &mconfig, device_type type, const char *tag) :
+pippin_state::pippin_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
- m_bandit(*this, "pci:00.0"),
+ m_aspen(*this, "pci:00.0"),
m_cuda(*this, "cuda"),
m_macadb(*this, "macadb"),
m_ram(*this, RAM_TAG)
{
}
-void macpci_state::machine_start()
+void pippin_state::machine_start()
{
}
-void macpci_state::machine_reset()
+void pippin_state::machine_reset()
{
// the PPC can't run until Cuda's ready
m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
}
-void macpci_state::pippin_map(address_map &map)
+void pippin_state::pippin_map(address_map &map)
{
map(0x00000000, 0x005fffff).ram();
@@ -118,19 +124,20 @@ void macpci_state::pippin_map(address_map &map)
map(0x03c00000, 0x03c01007).ram();
map(0x40000000, 0x403fffff).rom().region("bootrom", 0).mirror(0x0fc00000); // mirror of ROM for 680x0 emulation
+ map(0x40000000, 0x40000000).lr8(NAME([]() { return 0x80; })); // hack to make flash ROM status check pass (causes 0xe1 to be written to VRAM, which is important later)
map(0x5ffffffc, 0x5fffffff).lr32(NAME([](offs_t offset) { return 0xa55a7001; }));
- map(0xf00dfff8, 0xf00dffff).lr64(NAME([](offs_t offset) { return (uint64_t)0xe1 << 32; })); // PC=0xfff04810
+ map(0xf0000000, 0xf00fffff).ram(); // VRAM
map(0xffc00000, 0xffffffff).rom().region("bootrom", 0);
}
-void macpci_state::cdmcu_mem(address_map &map)
+void pippin_state::cdmcu_mem(address_map &map)
{
map(0x0000, 0xffff).rom().region("cdrom", 0);
}
-void macpci_state::cdmcu_data(address_map &map)
+void pippin_state::cdmcu_data(address_map &map)
{
map(0x0000, 0x0001).noprw();
map(0x0003, 0x0003).noprw();
@@ -155,14 +162,14 @@ void macpci_state::cdmcu_data(address_map &map)
static INPUT_PORTS_START( pippin )
INPUT_PORTS_END
-void macpci_state::pippin(machine_config &config)
+void pippin_state::pippin(machine_config &config)
{
/* basic machine hardware */
PPC603(config, m_maincpu, 66000000);
- m_maincpu->set_addrmap(AS_PROGRAM, &macpci_state::pippin_map);
+ m_maincpu->set_addrmap(AS_PROGRAM, &pippin_state::pippin_map);
PCI_ROOT(config, "pci", 0);
- ASPEN(config, m_bandit, 66000000, "maincpu").set_dev_offset(1);
+ ASPEN(config, m_aspen, 66000000, "maincpu").set_dev_offset(1);
cdrom_image_device &cdrom(CDROM(config, "cdrom", 0));
cdrom.set_interface("pippin_cdrom");
@@ -173,11 +180,24 @@ void macpci_state::pippin(machine_config &config)
grandcentral_device &grandcentral(GRAND_CENTRAL(config, "pci:0d.0", 0));
grandcentral.set_maincpu_tag("maincpu");
+ grandcentral.set_pci_root_tag(":pci:00.0", AS_DATA);
+ grandcentral.irq_callback().set(FUNC(pippin_state::irq_w));
+
+ awacs_macrisc_device &awacs(AWACS_MACRISC(config, "codec", 45.1584_MHz_XTAL / 2));
+ awacs.dma_output().set(grandcentral, FUNC(heathrow_device::codec_dma_read));
+
+ grandcentral.codec_r_callback().set(awacs, FUNC(awacs_macrisc_device::read_macrisc));
+ grandcentral.codec_w_callback().set(awacs, FUNC(awacs_macrisc_device::write_macrisc));
+
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+ awacs.add_route(0, "lspeaker", 1.0);
+ awacs.add_route(1, "rspeaker", 1.0);
MACADB(config, m_macadb, 15.6672_MHz_XTAL);
CUDA(config, m_cuda, CUDA_341S0060);
- m_cuda->reset_callback().set(FUNC(macpci_state::cuda_reset_w));
+ m_cuda->reset_callback().set(FUNC(pippin_state::cuda_reset_w));
m_cuda->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
m_cuda->via_clock_callback().set(grandcentral, FUNC(heathrow_device::cb1_w));
m_cuda->via_data_callback().set(grandcentral, FUNC(heathrow_device::cb2_w));
@@ -190,8 +210,8 @@ void macpci_state::pippin(machine_config &config)
grandcentral.cb2_callback().set(m_cuda, FUNC(cuda_device::set_via_data));
mn1880_device &cdmcu(MN1880(config, "cdmcu", 8388608)); // type and clock unknown
- cdmcu.set_addrmap(AS_PROGRAM, &macpci_state::cdmcu_mem);
- cdmcu.set_addrmap(AS_DATA, &macpci_state::cdmcu_data);
+ cdmcu.set_addrmap(AS_PROGRAM, &pippin_state::cdmcu_mem);
+ cdmcu.set_addrmap(AS_DATA, &pippin_state::cdmcu_data);
cdmcu.set_disable();
}
@@ -235,4 +255,4 @@ ROM_END
/* Driver */
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
-COMP( 1996, pippin, 0, 0, pippin, pippin, macpci_state, empty_init, "Apple / Bandai", "Pippin @mark", MACHINE_NOT_WORKING)
+COMP( 1996, pippin, 0, 0, pippin, pippin, pippin_state, empty_init, "Apple / Bandai", "Pippin @mark", MACHINE_NOT_WORKING)
diff --git a/src/mame/apple/powermacg3.cpp b/src/mame/apple/powermacg3.cpp
index 318a59ee856..45564c81941 100644
--- a/src/mame/apple/powermacg3.cpp
+++ b/src/mame/apple/powermacg3.cpp
@@ -24,6 +24,7 @@
#include "machine/pci.h"
#include "machine/pci-ide.h"
#include "machine/ram.h"
+#include "awacs_macrisc.h"
#include "cuda.h"
#include "heathrow.h"
#include "macadb.h"
@@ -53,6 +54,11 @@ private:
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
m_maincpu->set_input_line(INPUT_LINE_RESET, state);
}
+
+ WRITE_LINE_MEMBER(irq_w)
+ {
+ m_maincpu->set_input_line(PPC_IRQ, state);
+ }
};
pwrmacg3_state::pwrmacg3_state(const machine_config &mconfig, device_type type, const char *tag) :
@@ -123,6 +129,7 @@ void pwrmacg3_state::pwrmacg3(machine_config &config)
heathrow_device &heathrow(HEATHROW(config, "pci:10.0", 0));
heathrow.set_maincpu_tag("maincpu");
+ heathrow.set_pci_root_tag(":pci:00.0", AS_DATA);
MACADB(config, m_macadb, 15.6672_MHz_XTAL);
@@ -134,6 +141,7 @@ void pwrmacg3_state::pwrmacg3(machine_config &config)
m_macadb->adb_data_callback().set(m_cuda, FUNC(cuda_device::set_adb_line));
config.set_perfect_quantum(m_maincpu);
+ heathrow.irq_callback().set(FUNC(pwrmacg3_state::irq_w));
heathrow.pb3_callback().set(m_cuda, FUNC(cuda_device::get_treq));
heathrow.pb4_callback().set(m_cuda, FUNC(cuda_device::set_byteack));
heathrow.pb5_callback().set(m_cuda, FUNC(cuda_device::set_tip));
@@ -163,6 +171,17 @@ void pwrmacg3_state::pwrmacg3(machine_config &config)
RAM(config, m_ram);
m_ram->set_default_size("32M");
m_ram->set_extra_options("32M,64M,96M,128M,256M");
+
+ screamer_device &screamer(SCREAMER(config, "codec", 45.1584_MHz_XTAL / 2));
+ screamer.dma_output().set(heathrow, FUNC(heathrow_device::codec_dma_read));
+
+ heathrow.codec_r_callback().set(screamer, FUNC(screamer_device::read_macrisc));
+ heathrow.codec_w_callback().set(screamer, FUNC(screamer_device::write_macrisc));
+
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+ screamer.add_route(0, "lspeaker", 1.0);
+ screamer.add_route(1, "rspeaker", 1.0);
}
/*