New machines added as NOT_WORKING

---------------------------------
Power Macintosh G3 [R. Belmont]
iMac (Bondi blue) [R. Belmont, Guru]
This commit is contained in:
arbee 2023-02-04 15:44:25 -05:00
parent 3db33c24b1
commit 758fabb885
8 changed files with 1062 additions and 0 deletions

View File

@ -2779,6 +2779,8 @@ if (MACHINES["PCI"]~=null) then
MAME_DIR .. "src/devices/machine/lpc-rtc.h",
MAME_DIR .. "src/devices/machine/lpc-pit.cpp",
MAME_DIR .. "src/devices/machine/lpc-pit.h",
MAME_DIR .. "src/devices/machine/mpc106.cpp",
MAME_DIR .. "src/devices/machine/mpc106.h",
MAME_DIR .. "src/devices/machine/vrc4373.cpp",
MAME_DIR .. "src/devices/machine/vrc4373.h",
MAME_DIR .. "src/devices/machine/vrc5074.cpp",

View File

@ -0,0 +1,246 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/**********************************************************************
mpc106.cpp - Motorola MPC106 PCI host bridge, aka "Grackle".
Can support up to 4 PowerPC CPUs, up to 1 GiB of RAM, and 16 MiB of ROM
**********************************************************************/
#include "emu.h"
#include "mpc106.h"
enum
{
AS_PCI_MEM = 1,
AS_PCI_IO = 2
};
DEFINE_DEVICE_TYPE(MPC106, mpc106_host_device, "mpc106", "Motorola MPC106 PCI Bridge/Memory Controller")
void mpc106_host_device::config_map(address_map &map)
{
pci_host_device::config_map(map);
map(0x70, 0x71).rw(FUNC(mpc106_host_device::pwrconfig1_r), FUNC(mpc106_host_device::pwrconfig1_w));
map(0x72, 0x72).rw(FUNC(mpc106_host_device::pwrconfig2_r), FUNC(mpc106_host_device::pwrconfig2_w));
}
mpc106_host_device::mpc106_host_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: pci_host_device(mconfig, MPC106, tag, owner, clock)
, m_mem_config("memory_space", ENDIANNESS_LITTLE, 32, 32)
, m_io_config("io_space", ENDIANNESS_LITTLE, 32, 32)
, m_cpu(*this, finder_base::DUMMY_TAG)
{
set_ids_host(0x10570002, 0x40, 0x000006);
}
void mpc106_host_device::set_ram_size(int _ram_size)
{
m_ram_size = _ram_size;
}
void mpc106_host_device::set_rom_tag(const char *tag)
{
m_rom_tag = tag;
}
void mpc106_host_device::set_map_type(map_type maptype)
{
m_map_type = maptype;
}
void mpc106_host_device::device_start()
{
pci_host_device::device_start();
m_cpu_space = &m_cpu->space(AS_PCI_CONFIG);
memory_space = &space(AS_PCI_MEM);
io_space = &space(AS_PCI_IO);
memory_window_start = 0;
memory_window_end = 0xffffffff;
memory_offset = 0;
io_window_start = 0;
io_window_end = 0xffffffff;
io_offset = 0;
command = 0x0006;
status = 0x0080;
m_rom = device().machine().root_device().memregion(m_rom_tag)->base();
m_rom_size = device().machine().root_device().memregion(m_rom_tag)->bytes();
m_ram.resize(m_ram_size/4);
m_pwrconfig1 = m_pwrconfig2 = 0;
m_last_config_address = -1;
u64 rom_base = 0x100000000ULL - m_rom_size;
m_cpu_space->install_rom(rom_base, 0xffffffff, m_rom);
if (m_map_type == MAP_TYPE_A)
{ // type A is PReP
m_cpu_space->install_read_handler (0x80000000, 0x807fffff, read32s_delegate(*this, FUNC(mpc106_host_device::pci_io_r<0>)));
m_cpu_space->install_write_handler(0x80000000, 0x807fffff, write32s_delegate(*this, FUNC(mpc106_host_device::pci_io_w<0>)));
m_cpu_space->install_device(0x80000000, 0x80000cff, *static_cast<pci_host_device *>(this), &pci_host_device::io_configuration_access_map);
m_cpu_space->install_read_handler (0x81000000, 0xbf7fffff, read32s_delegate(*this, FUNC(mpc106_host_device::pci_io_r<0x01000000>)));
m_cpu_space->install_write_handler(0x81000000, 0xbf7fffff, write32s_delegate(*this, FUNC(mpc106_host_device::pci_io_w<0x01000000>)));
m_cpu_space->install_read_handler (0xc0000000, 0xfeffffff, read32s_delegate(*this, FUNC(mpc106_host_device::pci_memory_r<0>)));
m_cpu_space->install_write_handler(0xc0000000, 0xfeffffff, write32s_delegate(*this, FUNC(mpc106_host_device::pci_memory_w<0>)));
}
else if (m_map_type == MAP_TYPE_B)
{ // type B is CHRP
m_cpu_space->install_read_handler (0x80000000, 0xfcffffff, read32s_delegate(*this, FUNC(mpc106_host_device::pci_memory_r<0x80000000>)));
m_cpu_space->install_write_handler(0x80000000, 0xfcffffff, write32s_delegate(*this, FUNC(mpc106_host_device::pci_memory_w<0x80000000>)));
m_cpu_space->install_read_handler (0xfd000000, 0xfdffffff, read32s_delegate(*this, FUNC(mpc106_host_device::pci_memory_r<0>)));
m_cpu_space->install_write_handler(0xfd000000, 0xfdffffff, write32s_delegate(*this, FUNC(mpc106_host_device::pci_memory_w<0>)));
m_cpu_space->install_read_handler (0xfe000000, 0xfe00ffff, read32s_delegate(*this, FUNC(mpc106_host_device::pci_io_r<0>)));
m_cpu_space->install_write_handler(0xfe000000, 0xfe00ffff, write32s_delegate(*this, FUNC(mpc106_host_device::pci_io_w<0>)));
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);
}
}
device_memory_interface::space_config_vector mpc106_host_device::memory_space_config() const
{
auto r = pci_bridge_device::memory_space_config();
r.emplace_back(std::make_pair(AS_PCI_MEM, &m_mem_config));
r.emplace_back(std::make_pair(AS_PCI_IO, &m_io_config));
return r;
}
void mpc106_host_device::reset_all_mappings()
{
pci_host_device::reset_all_mappings();
}
void mpc106_host_device::device_reset()
{
pci_host_device::device_reset();
m_last_config_address = -1;
}
void mpc106_host_device::access_map(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));
}
u32 mpc106_host_device::be_config_address_r()
{
u32 temp = pci_host_device::config_address_r();
return (temp>>24) | (temp<<24) | ((temp & 0xff00) << 8) | ((temp & 0xff0000) >> 8);
}
void mpc106_host_device::be_config_address_w(offs_t offset, u32 data, u32 mem_mask)
{
u32 tempdata;
//printf("config_address_w: %08x mask %08x\n", data, mem_mask);
tempdata = (data >> 24) | (data << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8);
pci_host_device::config_address_w(offset, tempdata, mem_mask);
m_last_config_address = tempdata & 0xffffff00;
}
u32 mpc106_host_device::be_config_data_r(offs_t offset, u32 mem_mask)
{
// config registers inside the MPC106 itself are little-endian and must be flipped if the host CPU is BE.
// TODO: we just assume a BE host CPU for now.
if (m_last_config_address == 0x80000000)
{
return pci_host_device::config_data_r(offset, mem_mask);
}
else
{
u32 temp = pci_host_device::config_data_r(offset, mem_mask);
return (temp >> 24) | (temp << 24) | ((temp & 0xff00) << 8) | ((temp & 0xff0000) >> 8);
}
}
void mpc106_host_device::be_config_data_w(offs_t offset, u32 data, u32 mem_mask)
{
if (m_last_config_address == 0x80000000)
{
pci_host_device::config_data_w(offset, data, mem_mask);
}
else
{
u32 tempdata;
//printf("config_data_w: %08x mask %08x\n", data, mem_mask);
tempdata = (data >> 24) | (data << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8);
pci_host_device::config_data_w(offset, tempdata, mem_mask);
}
}
template <u32 Base>
u32 mpc106_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;
}
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);
}
template u32 mpc106_host_device::pci_memory_r<0>(offs_t offset, u32 mem_mask);
template u32 mpc106_host_device::pci_memory_r<0x80000000>(offs_t offset, u32 mem_mask);
template void mpc106_host_device::pci_memory_w<0>(offs_t offset, u32 data, u32 mem_mask);
template void mpc106_host_device::pci_memory_w<0x80000000>(offs_t offset, u32 data, u32 mem_mask);
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;
}
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);
}
template u32 mpc106_host_device::pci_io_r<0>(offs_t offset, u32 mem_mask);
template u32 mpc106_host_device::pci_io_r<0x01000000>(offs_t offset, u32 mem_mask);
template u32 mpc106_host_device::pci_io_r<0x00800000>(offs_t offset, u32 mem_mask);
template void mpc106_host_device::pci_io_w<0>(offs_t offset, u32 data, u32 mem_mask);
template void mpc106_host_device::pci_io_w<0x01000000>(offs_t offset, u32 data, u32 mem_mask);
template void mpc106_host_device::pci_io_w<0x00800000>(offs_t offset, u32 data, u32 mem_mask);
// map PCI memory and I/O space stuff here
void mpc106_host_device::map_extra(u64 memory_window_start, u64 memory_window_end, u64 memory_offset, address_space *memory_space,
u64 io_window_start, u64 io_window_end, u64 io_offset, address_space *io_space)
{
u64 rom_base = 0x100000000ULL - m_rom_size;
memory_space->install_rom(rom_base, 0xffffffff, m_rom);
}
u16 mpc106_host_device::pwrconfig1_r()
{
return m_pwrconfig1;
}
void mpc106_host_device::pwrconfig1_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_pwrconfig1);
}
u8 mpc106_host_device::pwrconfig2_r()
{
return m_pwrconfig2;
}
void mpc106_host_device::pwrconfig2_w(offs_t offset, u8 data)
{
m_pwrconfig2 = data;
}

View File

@ -0,0 +1,86 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/**********************************************************************
mpc106.h - Motorola MPC-106 PCI host bridge, aka "Grackle".
**********************************************************************/
#ifndef MAME_MACHINE_MPC106_H
#define MAME_MACHINE_MPC106_H
#pragma once
#include "pci.h"
class mpc106_host_device : public pci_host_device {
public:
typedef enum
{
MAP_TYPE_A, // Type A is PowerPC Reference Platform (PReP)
MAP_TYPE_B // Type B is Common Hardware Reference Platform (CHRP)
} map_type;
template <typename T>
mpc106_host_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, map_type map, T &&cpu_tag, const char *rom_tag, int ram_size)
: mpc106_host_device(mconfig, tag, owner, clock)
{
set_ids_host(0x10570002, 0x00, 0x00000000);
set_map_type(map);
set_cpu_tag(std::forward<T>(cpu_tag));
set_rom_tag(rom_tag);
set_ram_size(ram_size);
}
mpc106_host_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
template <typename T> void set_cpu_tag(T &&tag) { m_cpu.set_tag(std::forward<T>(tag)); }
void set_ram_size(int ram_size);
void set_rom_tag(const char *tag);
void set_map_type(map_type maptype);
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void reset_all_mappings() override;
virtual void map_extra(u64 memory_window_start, u64 memory_window_end, u64 memory_offset, address_space *memory_space,
u64 io_window_start, u64 io_window_end, u64 io_offset, address_space *io_space) override;
virtual void config_map(address_map &map) override;
virtual space_config_vector memory_space_config() const override;
private:
void access_map(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);
void be_config_data_w(offs_t offset, u32 data, u32 mem_mask = ~0);
template <u32 Base> u32 pci_memory_r(offs_t offset, u32 mem_mask);
template <u32 Base> void pci_memory_w(offs_t offset, u32 data, u32 mem_mask);
template <u32 Base> u32 pci_io_r(offs_t offset, u32 mem_mask);
template <u32 Base> void pci_io_w(offs_t offset, u32 data, u32 mem_mask);
u16 pwrconfig1_r();
void pwrconfig1_w(offs_t offset, u16 data, u16 mem_mask);
u8 pwrconfig2_r();
void pwrconfig2_w(offs_t offset, u8 data);
address_space_config m_mem_config, m_io_config;
const char *m_rom_tag;
int m_ram_size;
map_type m_map_type;
required_device<device_memory_interface> m_cpu;
std::vector<u32> m_ram;
u8 *m_rom;
u32 m_rom_size;
address_space *m_cpu_space;
u16 m_pwrconfig1;
u8 m_pwrconfig2;
u32 m_last_config_address;
};
DECLARE_DEVICE_TYPE(MPC106, mpc106_host_device)
#endif // MAME_MACHINE_MPC106_H

401
src/mame/apple/heathrow.cpp Normal file
View File

@ -0,0 +1,401 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/*
Apple "Heathrow" and "Paddington" PCI ASICs
Emulation by R. Belmont
These ASICs sit on the PCI bus and provide "legacy" Mac I/O,
including:
- A VIA to interface with Cuda
- Serial
- SWIM3 floppy
- MESH SCSI ("Macintosh Enhanced SCSI Handler"), a 5394/96 clone with some features Apple didn't use removed)
- ATA
- Ethernet (10 Mbps for Heathrow, 10/100 for Paddington)
- Audio
- Descriptor-based DMA engine, as originally seen in the "PDM" Power Macs
*/
#include "emu.h"
#include "heathrow.h"
#include "bus/rs232/rs232.h"
#include "formats/ap_dsk35.h"
static constexpr u32 C7M = 7833600;
static constexpr u32 C15M = (C7M * 2);
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(HEATHROW, heathrow_device, "heathrow", "Apple Heathrow PCI I/O ASIC")
DEFINE_DEVICE_TYPE(PADDINGTON, paddington_device, "paddington", "Apple Paddington PCI I/O ASIC")
//-------------------------------------------------
// ADDRESS_MAP
//-------------------------------------------------
/*
A "Kanga" G3 PowerBook says:
F3016000 : VIA
F3012000 : SCC Rd
F3012000 : SCC Wr
F3015000 : IWM/SWIM
F3010000 : SCSI
ATA is at 20000
*/
void heathrow_device::map(address_map &map)
{
map(0x00000, 0x00fff).rw(FUNC(heathrow_device::macio_r), FUNC(heathrow_device::macio_w));
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(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));
}
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void heathrow_device::device_add_mconfig(machine_config &config)
{
R65NC22(config, m_via1, C7M / 10);
m_via1->readpa_handler().set(FUNC(heathrow_device::via_in_a));
m_via1->readpb_handler().set(FUNC(heathrow_device::via_in_b));
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));
AWACS(config, m_awacs, 45.1584_MHz_XTAL / 2);
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);
SWIM3(config, m_fdc, C15M);
m_fdc->devsel_cb().set(FUNC(heathrow_device::devsel_w));
m_fdc->phases_cb().set(FUNC(heathrow_device::phases_w));
applefdintf_device::add_35_hd(config, m_floppy[0]);
applefdintf_device::add_35_nc(config, m_floppy[1]);
SCC85C30(config, m_scc, C7M);
m_scc->configure_channels(3'686'400, 3'686'400, 3'686'400, 3'686'400);
m_scc->out_txda_callback().set("printer", FUNC(rs232_port_device::write_txd));
m_scc->out_txdb_callback().set("modem", FUNC(rs232_port_device::write_txd));
rs232_port_device &rs232a(RS232_PORT(config, "printer", default_rs232_devices, nullptr));
rs232a.rxd_handler().set(m_scc, FUNC(z80scc_device::rxa_w));
rs232a.dcd_handler().set(m_scc, FUNC(z80scc_device::dcda_w));
rs232a.cts_handler().set(m_scc, FUNC(z80scc_device::ctsa_w));
rs232_port_device &rs232b(RS232_PORT(config, "modem", default_rs232_devices, nullptr));
rs232b.rxd_handler().set(m_scc, FUNC(z80scc_device::rxb_w));
rs232b.dcd_handler().set(m_scc, FUNC(z80scc_device::dcdb_w));
rs232b.cts_handler().set(m_scc, FUNC(z80scc_device::ctsb_w));
}
void heathrow_device::config_map(address_map &map)
{
pci_device::config_map(map);
}
//-------------------------------------------------
// heathrow_device - constructor
//-------------------------------------------------
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_pb4(*this),
write_pb5(*this),
write_cb2(*this),
read_pb3(*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_cur_floppy(nullptr),
m_hdsel(0)
{
set_ids(0x106b0010, 0x01, 0xff000001, 0x000000);
}
heathrow_device::heathrow_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: heathrow_device(mconfig, HEATHROW, tag, owner, clock)
{
}
paddington_device::paddington_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: heathrow_device(mconfig, PADDINGTON, tag, owner, clock)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void heathrow_device::common_init()
{
write_pb4.resolve_safe();
write_pb5.resolve_safe();
write_cb2.resolve_safe();
read_pb3.resolve_safe(0);
m_6015_timer = timer_alloc(FUNC(heathrow_device::mac_6015_tick), this);
m_6015_timer->adjust(attotime::never);
save_item(NAME(m_hdsel));
add_map(0x80000, M_MEM, FUNC(heathrow_device::map));
command = 2; // enable our memory range
}
void heathrow_device::device_start()
{
common_init();
}
void paddington_device::device_start()
{
common_init();
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
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;
}
u8 heathrow_device::via_in_b()
{
return read_pb3() << 3;
}
WRITE_LINE_MEMBER(heathrow_device::via_out_cb2)
{
write_cb2(state & 1);
}
void heathrow_device::via_out_a(u8 data)
{
int hdsel = BIT(data, 5);
if (hdsel != m_hdsel)
{
if (m_cur_floppy)
{
m_cur_floppy->ss_w(hdsel);
}
}
m_hdsel = hdsel;
}
void heathrow_device::via_out_b(u8 data)
{
write_pb4(BIT(data, 4));
write_pb5(BIT(data, 5));
}
WRITE_LINE_MEMBER(heathrow_device::via1_irq)
{
}
WRITE_LINE_MEMBER(heathrow_device::cb1_w)
{
m_via1->write_cb1(state);
}
WRITE_LINE_MEMBER(heathrow_device::cb2_w)
{
m_via1->write_cb2(state);
}
u16 heathrow_device::mac_via_r(offs_t offset)
{
u16 data;
offset >>= 8;
offset &= 0x0f;
if (!machine().side_effects_disabled())
via_sync();
data = m_via1->read(offset);
return (data & 0xff) | (data << 8);
}
void heathrow_device::mac_via_w(offs_t offset, u16 data, u16 mem_mask)
{
offset >>= 8;
offset &= 0x0f;
via_sync();
if (ACCESSING_BITS_0_7)
m_via1->write(offset, data & 0xff);
if (ACCESSING_BITS_8_15)
m_via1->write(offset, (data >> 8) & 0xff);
}
void heathrow_device::via_sync()
{
// The via runs at 783.36KHz while the main cpu runs at 15MHz or
// more, so we need to sync the access with the via clock. Plus
// the whole access takes half a (via) cycle and ends when synced
// with the main cpu again.
// Get the main cpu time
u64 cycle = m_maincpu->total_cycles();
// Get the number of the cycle the via is in at that time
u64 via_cycle = cycle * m_via1->clock() / m_maincpu->clock();
// The access is going to start at via_cycle+1 and end at
// via_cycle+1.5, compute what that means in maincpu cycles (the
// +1 rounds up, since the clocks are too different to ever be
// synced).
u64 main_cycle = (via_cycle * 2 + 3) * m_maincpu->clock() / (2 * m_via1->clock()) + 1;
// Finally adjust the main cpu icount as needed.
m_maincpu->adjust_icount(-int(main_cycle - cycle));
}
u16 heathrow_device::swim_r(offs_t offset, u16 mem_mask)
{
if (!machine().side_effects_disabled())
{
m_maincpu->adjust_icount(-5);
}
u16 result = m_fdc->read((offset >> 8) & 0xf);
return result << 8;
}
void heathrow_device::swim_w(offs_t offset, u16 data, u16 mem_mask)
{
if (ACCESSING_BITS_0_7)
m_fdc->write((offset >> 8) & 0xf, data & 0xff);
else
m_fdc->write((offset >> 8) & 0xf, data >> 8);
}
void heathrow_device::phases_w(u8 phases)
{
if (m_cur_floppy)
m_cur_floppy->seek_phase_w(phases);
}
void heathrow_device::devsel_w(u8 devsel)
{
if (devsel == 1)
m_cur_floppy = m_floppy[0]->get_device();
else if (devsel == 2)
m_cur_floppy = m_floppy[1]->get_device();
else
m_cur_floppy = nullptr;
m_fdc->set_floppy(m_cur_floppy);
if (m_cur_floppy)
m_cur_floppy->ss_w(m_hdsel);
}
u32 heathrow_device::macio_r(offs_t offset)
{
// printf("macio_r: offset %x (%x)\n", offset, offset*4);
return 0;
}
void heathrow_device::macio_w(offs_t offset, u32 data, u32 mem_mask)
{
// printf("macio_w: offset %x (%x) data %08x mask %08x\n", offset, offset*4, data, mem_mask);
}
u8 heathrow_device::fdc_r(offs_t offset)
{
return m_fdc->read(offset >> 9);
}
void heathrow_device::fdc_w(offs_t offset, u8 data)
{
m_fdc->write(offset >> 9, data);
}
u8 heathrow_device::nvram_r(offs_t offset)
{
return m_nvram[offset >> 2];
}
void heathrow_device::nvram_w(offs_t offset, u8 data)
{
m_nvram[offset >> 2] = data;
}
u16 heathrow_device::scc_r(offs_t offset)
{
u16 result = m_scc->dc_ab_r(offset);
return (result << 8) | result;
}
void heathrow_device::scc_w(offs_t offset, u16 data)
{
m_scc->dc_ab_w(offset, data >> 8);
}
u8 heathrow_device::scc_macrisc_r(offs_t offset)
{
switch ((offset >> 4) & 0xf)
{
case 0:
return m_scc->cb_r(0);
case 1:
return m_scc->db_r(0);
case 2:
return m_scc->ca_r(0);
case 3:
return m_scc->da_r(0);
}
return 0;
}
void heathrow_device::scc_macrisc_w(offs_t offset, u8 data)
{
switch ((offset >> 4) & 0xf)
{
case 0:
return m_scc->cb_w(0, data);
case 1:
return m_scc->db_w(0, data);
case 2:
return m_scc->ca_w(0, data);
case 3:
return m_scc->da_w(0, data);
}
}

117
src/mame/apple/heathrow.h Normal file
View File

@ -0,0 +1,117 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
#ifndef MAME_APPLE_HEATHROW_H
#define MAME_APPLE_HEATHROW_H
#pragma once
#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
class heathrow_device : public pci_device
{
public:
// construction/destruction
heathrow_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
heathrow_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// interface routines
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);
template <typename... T> void set_maincpu_tag(T &&... args) { m_maincpu.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);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
virtual void config_map(address_map &map) override;
void common_init();
private:
emu_timer *m_6015_timer;
devcb_write_line write_pb4, write_pb5, write_cb2;
devcb_read_line read_pb3;
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;
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 via_in_a();
u8 via_in_b();
void via_out_a(u8 data);
void via_out_b(u8 data);
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);
};
class paddington_device : public heathrow_device
{
public:
// construction/destruction
paddington_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
// device-level overrides
virtual void device_start() override;
};
// device type definition
DECLARE_DEVICE_TYPE(HEATHROW, heathrow_device)
DECLARE_DEVICE_TYPE(PADDINGTON, paddington_device)
#endif // MAME_APPLE_HEATHROW_H

101
src/mame/apple/imacg3.cpp Normal file
View File

@ -0,0 +1,101 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/****************************************************************************
imacg3.cpp
iMac G3 (original hardware)
Preliminary driver by R. Belmont
This is a "New World" PCI-based machine.
CPU: PowerPC 750 "G3" @ 233 MHz
Memory controller/PCI bridge: Motorola MPC106 "Grackle"
Video: ATI Rage IIc w/2MB VRAM, ATI Rage Pro Turbo w/6MB VRAM on revised model
USB: OPTi 82C861 PCI/USB controller
I/O: Paddington PCI I/O ASIC (see heathrow.cpp for details)
****************************************************************************/
#include "emu.h"
#include "cpu/powerpc/ppc.h"
#include "machine/pci.h"
#include "machine/pci-ide.h"
#include "machine/mpc106.h"
#include "cuda.h"
#include "heathrow.h"
class imac_state : public driver_device
{
public:
void imac(machine_config &config);
imac_state(const machine_config &mconfig, device_type type, const char *tag);
required_device<cpu_device> m_maincpu;
required_device<cuda_device> m_cuda;
private:
void imac_map(address_map &map);
virtual void machine_start() override;
virtual void machine_reset() override;
WRITE_LINE_MEMBER(cuda_reset_w)
{
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
m_maincpu->set_input_line(INPUT_LINE_RESET, state);
}
};
imac_state::imac_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_cuda(*this, "cuda")
{
}
void imac_state::machine_start()
{
}
void imac_state::machine_reset()
{
}
void imac_state::imac_map(address_map &map)
{
map.unmap_value_high();
}
void imac_state::imac(machine_config &config)
{
PPC604(config, m_maincpu, 66000000); // actually PPC750
m_maincpu->set_addrmap(AS_PROGRAM, &imac_state::imac_map);
PCI_ROOT(config, "pci", 0);
MPC106(config, "pci:00.0", 0, mpc106_host_device::MAP_TYPE_B, "maincpu", "bootrom", 32 * 1024 * 1024);
paddington_device &paddington(PADDINGTON(config, "pci:10.0", 0));
paddington.set_maincpu_tag("maincpu");
CUDA(config, m_cuda, CUDA_341S0060);
m_cuda->reset_callback().set(FUNC(imac_state::cuda_reset_w));
m_cuda->via_clock_callback().set(paddington, FUNC(paddington_device::cb1_w));
m_cuda->via_data_callback().set(paddington, FUNC(paddington_device::cb2_w));
config.set_perfect_quantum(m_maincpu);
paddington.pb3_callback().set(m_cuda, FUNC(cuda_device::get_treq));
paddington.pb4_callback().set(m_cuda, FUNC(cuda_device::set_byteack));
paddington.pb5_callback().set(m_cuda, FUNC(cuda_device::set_tip));
paddington.cb2_callback().set(m_cuda, FUNC(cuda_device::set_via_data));
}
ROM_START(imac)
ROM_REGION(0x100000, "bootrom", ROMREGION_64BIT | ROMREGION_BE)
ROM_LOAD( "imacboot.u3", 0x000000, 0x100000, CRC(80d3174b) SHA1(e7a0c71822ec1e08435099af87b38bc82d315ed5) )
ROM_END
static INPUT_PORTS_START(imac)
INPUT_PORTS_END
COMP(1998, imac, 0, 0, imac, imac, imac_state, empty_init, "Apple Computer", "iMac (Bondi blue)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)

View File

@ -0,0 +1,103 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/****************************************************************************
powermacg3.cpp
PowerMac G3 (original beige hardware)
Preliminary driver by R. Belmont
The last desktop Old World Mac, with hardware very similar to the first
New World machines.
CPU: PowerPC 750 "G3" @ 233 MHz
Memory controller/PCI bridge: Motorola MPC106 "Grackle"
Video: ATI Rage II+, ATI Rage Pro on rev. B, ATI Rage Pro Turbo on rev. C
I/O: Heathrow PCI I/O ASIC (see heathrow.cpp for details)
****************************************************************************/
#include "emu.h"
#include "cpu/powerpc/ppc.h"
#include "machine/pci.h"
#include "machine/pci-ide.h"
#include "machine/mpc106.h"
#include "heathrow.h"
class pwrmacg3_state : public driver_device
{
public:
void pwrmacg3(machine_config &config);
pwrmacg3_state(const machine_config &mconfig, device_type type, const char *tag);
required_device<cpu_device> m_maincpu;
private:
void pwrmacg3_map(address_map &map);
virtual void machine_start() override;
virtual void machine_reset() override;
};
pwrmacg3_state::pwrmacg3_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu")
{
}
void pwrmacg3_state::machine_start()
{
}
void pwrmacg3_state::machine_reset()
{
}
void pwrmacg3_state::pwrmacg3_map(address_map &map)
{
map.unmap_value_high();
}
void pwrmacg3_state::pwrmacg3(machine_config &config)
{
PPC604(config, m_maincpu, 66000000); // actually PPC750
m_maincpu->set_addrmap(AS_PROGRAM, &pwrmacg3_state::pwrmacg3_map);
PCI_ROOT(config, "pci", 0);
MPC106(config, "pci:00.0", 0, mpc106_host_device::MAP_TYPE_B, "maincpu", "bootrom", 32 * 1024 * 1024);
heathrow_device &heathrow(HEATHROW(config, "pci:10.0", 0));
heathrow.set_maincpu_tag("maincpu");
}
/*
Config register for Gossamer beige G3 and all-in-one
bit 15: 1 = SWIM3, 0 = PC style FDC
bit 14: 1 = slow ROM, 0 = burstable ROM
bit 12 = PCI slot C card present
bit 10 = PCI slot B card present
bit 8 = PCI slot A card present
bits 7-5 = bus to CPU clock ratio (1 for 2:1)
bit 4: 0 = all-in-one "Molar Mac", 1 = Desktop beige G3
bits 3-1: bus speed (0=75 MHz, 1=70, 2=78.75, 3=invalid, 4=75, 5=60, 6=66.82, 7=83)
bit 0: must be 1 (burn-in diagnostics?)
desktop = 0b1001010100111101;
AIO = 0b1001010100101101;
*/
ROM_START(pwrmacg3)
ROM_REGION(0x1000000, "bootrom", ROMREGION_64BIT | ROMREGION_BE | ROMREGION_ERASEFF)
ROM_LOAD( "pmacg3_79d68d63.bin", 0xc00000, 0x400000, CRC(74a3badf) SHA1(e7fc183f62addc6499350c727252d3348184955e) )
// The Gossamer machine config register is at 0xFF000000, which is in the MPC106's ROM space.
// So we're hacking it like this. Hardware is assumed to operate similarly.
ROM_FILL(0, 1, 0b10010101)
ROM_FILL(1, 1, 0b00111101)
ROM_FILL(2, 1, 0b10010101)
ROM_FILL(3, 1, 0b00111101)
ROM_END
static INPUT_PORTS_START(pwrmacg3)
INPUT_PORTS_END
COMP(1997, pwrmacg3, 0, 0, pwrmacg3, pwrmacg3, pwrmacg3_state, empty_init, "Apple Computer", "Power Macintosh G3", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)

View File

@ -802,6 +802,9 @@ apple2gsmt // 1991 "Mark Twain" prototype
@source:apple/apple3.cpp
apple3 // May 1980 Apple ///
@source:apple/imacg3.cpp
imac // August 15, 1998 Apple iMac (Bondi blue)
@source:apple/iphone2g.cpp
iphone2g // (c) 2007 Apple
@ -887,6 +890,9 @@ emate
mp2000
mp2100
@source:apple/powermacg3.cpp
pwrmacg3 // November 10, 1997 Apple Power Macintosh G3 (beige)
@source:apple/superga2.cpp
kuzmich