mirror of
https://github.com/holub/mame
synced 2025-04-22 00:11:58 +03:00
mac: LLE emulate the PIC1654S ADB modem used on early ADB Macs. [R. Belmont, Al Kossow, O. Galibert]
This commit is contained in:
parent
65f248a6ab
commit
c418e92160
190
src/mame/apple/adbmodem.cpp
Normal file
190
src/mame/apple/adbmodem.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
/*
|
||||
Apple ADB Modem 342S0440-B
|
||||
Emulation by R. Belmont
|
||||
|
||||
This is a PIC1654S that converts ADB bit serial to and from bit serial
|
||||
for the VIA shifter.
|
||||
|
||||
Connections:
|
||||
Pin 1 - RA2 - ADB out (inverted)
|
||||
Pin 2 - RA3 - ADB in
|
||||
Pin 3 - RTCC - ADB in
|
||||
Pin 13 - RB2 - to VIA CB1 (shift clock)
|
||||
Pin 14 - RB3 - to VIA CB2 (shift data)
|
||||
Pin 16 - RB4 - to VIA PB3 (IRQ)
|
||||
Pin 27 - RA0 - to VIA PB4 (newaction bit 0)
|
||||
Pin 28 - RA1 - to VIA PB5 (newaction bit 1)
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "adbmodem.h"
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(ADBMODEM, adbmodem_device, "adbmodem", "Apple ADB Modem")
|
||||
|
||||
ROM_START( adbmodem )
|
||||
ROM_REGION(0x400, "adbmodem", 0)
|
||||
ROM_LOAD( "342s0440-b.bin", 0x0000, 0x0400, CRC(cffb33eb) SHA1(4a35a44605073ae6076a0292e2056ee4d938d1bd) )
|
||||
ROM_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// ADDRESS_MAP
|
||||
//-------------------------------------------------
|
||||
|
||||
void adbmodem_device::adbmodem_map(address_map &map)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_add_mconfig - add device configuration
|
||||
//-------------------------------------------------
|
||||
|
||||
void adbmodem_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
PIC1654S(config, m_maincpu, 15.6672_MHz_XTAL/4);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &adbmodem_device::adbmodem_map);
|
||||
m_maincpu->read_a().set(FUNC(adbmodem_device::porta_r));
|
||||
m_maincpu->write_a().set(FUNC(adbmodem_device::porta_w));
|
||||
m_maincpu->read_b().set(FUNC(adbmodem_device::portb_r));
|
||||
m_maincpu->write_b().set(FUNC(adbmodem_device::portb_w));
|
||||
|
||||
#if USE_BUS_ADB
|
||||
ADB_CONNECTOR(config, "adb1", adb_device::default_devices, "a9m0330", false);
|
||||
#endif
|
||||
}
|
||||
|
||||
const tiny_rom_entry *adbmodem_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME( adbmodem );
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
#if USE_BUS_ADB
|
||||
void adbmodem_device::adb_w(int id, int state)
|
||||
{
|
||||
m_adb_device_out[id] = state;
|
||||
adb_change();
|
||||
}
|
||||
|
||||
void adbmodem_device::adb_poweron_w(int id, int state)
|
||||
{
|
||||
m_adb_device_poweron[id] = state;
|
||||
}
|
||||
|
||||
void adbmodem_device::adb_change()
|
||||
{
|
||||
bool adb = m_adb_out & m_adb_device_out[0] & m_adb_device_out[1];
|
||||
logerror("adb c:%d 1:%d 2:%d -> %d (%02x %02x)\n", m_adb_out, m_adb_device_out[0], m_adb_device_out[1], adb, ddrs[0], ports[0]);
|
||||
for (int i = 0; i != 2; i++)
|
||||
if (m_adb_device[i])
|
||||
{
|
||||
m_adb_device[i]->adb_w(adb);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------
|
||||
// adbmodem_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
adbmodem_device::adbmodem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, ADBMODEM, tag, owner, clock),
|
||||
write_reset(*this),
|
||||
write_linechange(*this),
|
||||
write_via_clock(*this),
|
||||
write_via_data(*this),
|
||||
write_irq(*this),
|
||||
m_maincpu(*this, "adbmodem")
|
||||
#if USE_BUS_ADB
|
||||
, m_adb_connector{{*this, "adb1"}, {*this, finder_base::DUMMY_TAG}}
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void adbmodem_device::device_start()
|
||||
{
|
||||
write_reset.resolve_safe();
|
||||
write_linechange.resolve_safe();
|
||||
write_via_clock.resolve_safe();
|
||||
write_via_data.resolve_safe();
|
||||
write_irq.resolve_safe();
|
||||
|
||||
#if USE_BUS_ADB
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_adb_device[i] = m_adb_connector[i] ? m_adb_connector[i]->get_device() : nullptr;
|
||||
if (m_adb_device[i])
|
||||
{
|
||||
m_adb_device[i]->adb_r().set([this, i](int state) { adb_w(i, state); });
|
||||
m_adb_device[i]->poweron_r().set([this, i](int state) { adb_poweron_w(i, state); });
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
save_item(NAME(via_data));
|
||||
save_item(NAME(via_clock));
|
||||
save_item(NAME(adb_in));
|
||||
save_item(NAME(reset_line));
|
||||
save_item(NAME(m_adb_dtime));
|
||||
|
||||
#if USE_BUS_ADB
|
||||
save_item(NAME(m_adb_out));
|
||||
save_item(NAME(m_adb_device_out));
|
||||
save_item(NAME(m_adb_device_poweron));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void adbmodem_device::device_reset()
|
||||
{
|
||||
#if USE_BUS_ADB
|
||||
m_adb_device_out[0] = m_adb_device_out[1] = true;
|
||||
m_adb_device_poweron[0] = m_adb_device_poweron[1] = true;
|
||||
#endif
|
||||
|
||||
adb_in = true; // line is pulled up to +5v, so nothing plugged in would read as "1"
|
||||
reset_line = 0;
|
||||
via_data = 0;
|
||||
via_clock = 0;
|
||||
last_adb_time = m_maincpu->total_cycles();
|
||||
last_adb = 0;
|
||||
}
|
||||
|
||||
u8 adbmodem_device::porta_r()
|
||||
{
|
||||
return (m_via_state & 3) | (adb_in << 3);
|
||||
}
|
||||
|
||||
void adbmodem_device::porta_w(u8 data)
|
||||
{
|
||||
write_linechange(BIT(data, 2) ^ 1);
|
||||
}
|
||||
|
||||
u8 adbmodem_device::portb_r()
|
||||
{
|
||||
return (via_data << 3);
|
||||
}
|
||||
|
||||
void adbmodem_device::portb_w(u8 data)
|
||||
{
|
||||
write_via_data(BIT(data, 3));
|
||||
write_via_clock(BIT(data, 2));
|
||||
write_irq(BIT(data, 4) ^ 1);
|
||||
}
|
||||
|
98
src/mame/apple/adbmodem.h
Normal file
98
src/mame/apple/adbmodem.h
Normal file
@ -0,0 +1,98 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
#ifndef MAME_MACHINE_ADBMODEM_H
|
||||
#define MAME_MACHINE_ADBMODEM_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#define USE_BUS_ADB (0)
|
||||
|
||||
#if USE_BUS_ADB
|
||||
#include "bus/adb/adb.h"
|
||||
#endif
|
||||
|
||||
#include "cpu/pic16c5x/pic16c5x.h"
|
||||
|
||||
// ======================> adbmodem_device
|
||||
|
||||
class adbmodem_device : public device_t
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
adbmodem_device(const machine_config &mconfig, const char *tag, device_t *owner, int type)
|
||||
: adbmodem_device(mconfig, tag, owner, (uint32_t)0)
|
||||
{
|
||||
set_type(type);
|
||||
}
|
||||
|
||||
adbmodem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// inline configuration helpers
|
||||
void set_type(int type) { rom_offset = type; }
|
||||
|
||||
|
||||
#if USE_BUS_ADB
|
||||
void adb_w(int id, int state);
|
||||
void adb_poweron_w(int id, int state);
|
||||
void adb_change();
|
||||
#endif
|
||||
|
||||
// interface routines
|
||||
u8 get_via_data() { return via_data; }
|
||||
void set_via_data(uint8_t dat) { via_data = dat; }
|
||||
u8 get_via_clock() { return via_clock; }
|
||||
void set_adb_line(int linestate) { adb_in = (linestate == ASSERT_LINE) ? true : false; }
|
||||
void set_via_state(u8 state) { m_via_state = state; }
|
||||
|
||||
int rom_offset;
|
||||
|
||||
auto reset_callback() { return write_reset.bind(); }
|
||||
auto linechange_callback() { return write_linechange.bind(); }
|
||||
auto via_clock_callback() { return write_via_clock.bind(); }
|
||||
auto via_data_callback() { return write_via_data.bind(); }
|
||||
auto irq_callback() { return write_irq.bind(); }
|
||||
|
||||
devcb_write_line write_reset, write_linechange;
|
||||
devcb_write_line write_via_clock, write_via_data, write_irq;
|
||||
|
||||
void adbmodem_map(address_map &map);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
|
||||
required_device<pic16c5x_device> m_maincpu;
|
||||
|
||||
private:
|
||||
u8 porta_r();
|
||||
void porta_w(u8 data);
|
||||
u8 portb_r();
|
||||
void portb_w(u8 data);
|
||||
|
||||
u8 via_data = 0;
|
||||
u8 via_clock = 0;
|
||||
u8 last_adb = 0;
|
||||
u8 m_via_state = 0;
|
||||
u64 last_adb_time = 0;
|
||||
bool adb_in = false;
|
||||
int reset_line = 0;
|
||||
int m_adb_dtime = 0;
|
||||
|
||||
#if USE_BUS_ADB
|
||||
optional_device <adb_connector> m_adb_connector[2];
|
||||
adb_device *m_adb_device[2]{};
|
||||
bool m_adb_device_out[2]{};
|
||||
bool m_adb_device_poweron[2]{};
|
||||
bool m_adb_out = false;
|
||||
#endif
|
||||
|
||||
void send_port(uint8_t offset, uint8_t data);
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(ADBMODEM, adbmodem_device)
|
||||
|
||||
#endif // MAME_MACHINE_ADBMODEM_H
|
@ -561,7 +561,6 @@ void mac_state::add_egret(machine_config &config, int type)
|
||||
m_egret->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
|
||||
m_egret->via_clock_callback().set(m_via1, FUNC(via6522_device::write_cb1));
|
||||
m_egret->via_data_callback().set(m_via1, FUNC(via6522_device::write_cb2));
|
||||
m_macadb->set_mcu_mode(true);
|
||||
m_macadb->adb_data_callback().set(m_egret, FUNC(egret_device::set_adb_line));
|
||||
config.set_perfect_quantum(m_maincpu);
|
||||
}
|
||||
@ -633,10 +632,16 @@ void mac_state::macii(machine_config &config, bool cpu, asc_device::asc_type asc
|
||||
add_via1_adb(config, true);
|
||||
add_via2(config);
|
||||
|
||||
ADBMODEM(config, m_adbmodem, C7M);
|
||||
m_adbmodem->via_clock_callback().set(m_via1, FUNC(via6522_device::write_cb1));
|
||||
m_adbmodem->via_data_callback().set(m_via1, FUNC(via6522_device::write_cb2));
|
||||
m_adbmodem->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
|
||||
m_adbmodem->irq_callback().set(FUNC(mac_state::adb_irq_w));
|
||||
m_via1->cb2_handler().set(m_adbmodem, FUNC(adbmodem_device::set_via_data));
|
||||
config.set_perfect_quantum(m_maincpu);
|
||||
|
||||
MACADB(config, m_macadb, C15M);
|
||||
m_macadb->via_clock_callback().set(m_via1, FUNC(via6522_device::write_cb1));
|
||||
m_macadb->via_data_callback().set(m_via1, FUNC(via6522_device::write_cb2));
|
||||
m_macadb->adb_irq_callback().set(FUNC(mac_state::adb_irq_w));
|
||||
m_macadb->adb_data_callback().set(m_adbmodem, FUNC(adbmodem_device::set_adb_line));
|
||||
|
||||
RAM(config, m_ram);
|
||||
m_ram->set_default_size("2M");
|
||||
@ -781,10 +786,16 @@ void mac_state::macse30(machine_config &config)
|
||||
add_via1_adb(config, false);
|
||||
add_via2(config);
|
||||
|
||||
ADBMODEM(config, m_adbmodem, C7M);
|
||||
m_adbmodem->via_clock_callback().set(m_via1, FUNC(via6522_device::write_cb1));
|
||||
m_adbmodem->via_data_callback().set(m_via1, FUNC(via6522_device::write_cb2));
|
||||
m_adbmodem->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
|
||||
m_adbmodem->irq_callback().set(FUNC(mac_state::adb_irq_w));
|
||||
m_via1->cb2_handler().set(m_adbmodem, FUNC(adbmodem_device::set_via_data));
|
||||
config.set_perfect_quantum(m_maincpu);
|
||||
|
||||
MACADB(config, m_macadb, C15M);
|
||||
m_macadb->via_clock_callback().set(m_via1, FUNC(via6522_device::write_cb1));
|
||||
m_macadb->via_data_callback().set(m_via1, FUNC(via6522_device::write_cb2));
|
||||
m_macadb->adb_irq_callback().set(FUNC(mac_state::adb_irq_w));
|
||||
m_macadb->adb_data_callback().set(m_adbmodem, FUNC(adbmodem_device::set_adb_line));
|
||||
|
||||
RAM(config, m_ram);
|
||||
m_ram->set_default_size("2M");
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "machine/nscsi_bus.h"
|
||||
#include "machine/ram.h"
|
||||
#include "machine/timer.h"
|
||||
#include "adbmodem.h"
|
||||
#include "egret.h"
|
||||
#include "macadb.h"
|
||||
#include "bus/nubus/nubus.h"
|
||||
@ -54,6 +55,7 @@ public:
|
||||
m_via2(*this, "via6522_1"),
|
||||
m_asc(*this, "asc"),
|
||||
m_egret(*this, EGRET_TAG),
|
||||
m_adbmodem(*this, "adbmodem"),
|
||||
m_macadb(*this, "macadb"),
|
||||
m_ram(*this, RAM_TAG),
|
||||
m_scc(*this, "scc"),
|
||||
@ -124,6 +126,7 @@ private:
|
||||
optional_device<via6522_device> m_via2;
|
||||
optional_device<asc_device> m_asc;
|
||||
optional_device<egret_device> m_egret;
|
||||
optional_device<adbmodem_device> m_adbmodem;
|
||||
optional_device<macadb_device> m_macadb;
|
||||
required_device<ram_device> m_ram;
|
||||
required_device<scc8530_legacy_device> m_scc;
|
||||
|
@ -84,6 +84,7 @@ Scanline 0 is the start of vblank.
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "adbmodem.h"
|
||||
#include "macrtc.h"
|
||||
#include "mactoolbox.h"
|
||||
|
||||
@ -134,6 +135,7 @@ public:
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_via(*this, "via6522_0"),
|
||||
m_adbmodem(*this, "adbmodem"),
|
||||
m_macadb(*this, "macadb"),
|
||||
m_ram(*this, RAM_TAG),
|
||||
m_scsibus(*this, "scsibus"),
|
||||
@ -170,6 +172,7 @@ public:
|
||||
private:
|
||||
required_device<m68000_device> m_maincpu;
|
||||
required_device<via6522_device> m_via;
|
||||
optional_device<adbmodem_device> m_adbmodem;
|
||||
optional_device<macadb_device> m_macadb;
|
||||
required_device<ram_device> m_ram;
|
||||
optional_device<nscsi_bus_device> m_scsibus;
|
||||
@ -808,7 +811,7 @@ uint8_t mac128_state::mac_via_in_b()
|
||||
|
||||
uint8_t mac128_state::mac_via_in_b_se()
|
||||
{
|
||||
int val = m_macadb->get_adb_state()<<4;
|
||||
int val = 0;
|
||||
|
||||
if (!m_adb_irq_pending)
|
||||
{
|
||||
@ -900,7 +903,7 @@ void mac128_state::mac_via_out_b_se(uint8_t data)
|
||||
|
||||
m_scsiirq_enable = (data & 0x40) ? 0 : 1;
|
||||
|
||||
m_macadb->mac_adb_newaction((data & 0x30) >> 4);
|
||||
m_adbmodem->set_via_state((data & 0x30) >> 4);
|
||||
|
||||
m_rtc->ce_w((data & 0x04)>>2);
|
||||
m_rtc->data_w(data & 0x01);
|
||||
@ -1254,17 +1257,21 @@ void mac128_state::macse(machine_config &config)
|
||||
adapter.drq_handler().set(m_scsihelp, FUNC(mac_scsi_helper_device::drq_w));
|
||||
});
|
||||
|
||||
ADBMODEM(config, m_adbmodem, C7M);
|
||||
m_adbmodem->via_clock_callback().set(m_via, FUNC(via6522_device::write_cb1));
|
||||
m_adbmodem->via_data_callback().set(m_via, FUNC(via6522_device::write_cb2));
|
||||
m_adbmodem->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
|
||||
m_adbmodem->irq_callback().set(FUNC(mac128_state::adb_irq_w));
|
||||
|
||||
MACADB(config, m_macadb, C7M);
|
||||
m_macadb->via_clock_callback().set(m_via, FUNC(via6522_device::write_cb1));
|
||||
m_macadb->via_data_callback().set(m_via, FUNC(via6522_device::write_cb2));
|
||||
m_macadb->adb_irq_callback().set(FUNC(mac128_state::adb_irq_w));
|
||||
m_macadb->adb_data_callback().set(m_adbmodem, FUNC(adbmodem_device::set_adb_line));
|
||||
|
||||
R65NC22(config.replace(), m_via, C7M/10);
|
||||
m_via->readpa_handler().set(FUNC(mac128_state::mac_via_in_a));
|
||||
m_via->readpb_handler().set(FUNC(mac128_state::mac_via_in_b_se));
|
||||
m_via->writepa_handler().set(FUNC(mac128_state::mac_via_out_a_se));
|
||||
m_via->writepb_handler().set(FUNC(mac128_state::mac_via_out_b_se));
|
||||
m_via->cb2_handler().set(m_macadb, FUNC(macadb_device::adb_data_w));
|
||||
m_via->cb2_handler().set(m_adbmodem, FUNC(adbmodem_device::set_via_data));
|
||||
m_via->irq_handler().set(FUNC(mac128_state::mac_via_irq));
|
||||
|
||||
/* internal ram */
|
||||
|
@ -492,13 +492,6 @@ WRITE_LINE_MEMBER(mac_state::mac_adb_via_out_cb2)
|
||||
{
|
||||
m_egret->set_via_data(state & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_macadb)
|
||||
{
|
||||
m_macadb->adb_data_w(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* *************************************************************************
|
||||
@ -577,8 +570,6 @@ uint8_t mac_state::mac_via_in_b()
|
||||
|
||||
if (ADB_IS_BITBANG_CLASS)
|
||||
{
|
||||
val |= m_macadb->get_adb_state()<<4;
|
||||
|
||||
if (!m_adb_irq_pending)
|
||||
{
|
||||
val |= 0x08;
|
||||
@ -602,8 +593,6 @@ uint8_t mac_state::mac_via_in_b_ii()
|
||||
|
||||
if (ADB_IS_BITBANG_CLASS)
|
||||
{
|
||||
val |= m_macadb->get_adb_state()<<4;
|
||||
|
||||
if (!m_adb_irq_pending)
|
||||
{
|
||||
val |= 0x08;
|
||||
@ -655,7 +644,7 @@ void mac_state::mac_via_out_b_bbadb(uint8_t data)
|
||||
}
|
||||
}
|
||||
|
||||
m_macadb->mac_adb_newaction((data & 0x30) >> 4);
|
||||
m_adbmodem->set_via_state((data & 0x30) >> 4);
|
||||
|
||||
m_rtc->ce_w((data & 0x04)>>2);
|
||||
m_rtc->data_w(data & 0x01);
|
||||
|
@ -205,8 +205,7 @@ macadb_device::macadb_device(const machine_config &mconfig, const char *tag, dev
|
||||
write_via_clock(*this),
|
||||
write_via_data(*this),
|
||||
write_adb_data(*this),
|
||||
write_adb_irq(*this),
|
||||
m_bIsMCUMode(false)
|
||||
write_adb_irq(*this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -728,226 +727,119 @@ void macadb_device::adb_talk()
|
||||
|
||||
TIMER_CALLBACK_MEMBER(macadb_device::mac_adb_tick)
|
||||
{
|
||||
if (m_bIsMCUMode)
|
||||
switch (m_adb_linestate)
|
||||
{
|
||||
switch (m_adb_linestate)
|
||||
{
|
||||
case LST_SRQNODATA:
|
||||
set_adb_line(ASSERT_LINE);
|
||||
m_adb_linestate = LST_IDLE;
|
||||
break;
|
||||
case LST_SRQNODATA:
|
||||
set_adb_line(ASSERT_LINE);
|
||||
m_adb_linestate = LST_IDLE;
|
||||
break;
|
||||
|
||||
case LST_TSTOPSTART:
|
||||
LOGMASKED(LOG_LINESTATE, "Send: TStopStart begin\n");
|
||||
set_adb_line(ASSERT_LINE);
|
||||
case LST_TSTOPSTART:
|
||||
LOGMASKED(LOG_LINESTATE, "Send: TStopStart begin\n");
|
||||
set_adb_line(ASSERT_LINE);
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_short, adb_timebase));
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
|
||||
case LST_TSTOPSTARTa:
|
||||
LOGMASKED(LOG_LINESTATE, "Send: TStopStart end\n");
|
||||
set_adb_line(CLEAR_LINE);
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_short, adb_timebase));
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
|
||||
case LST_STARTBIT:
|
||||
LOGMASKED(LOG_LINESTATE, "Send: Start bit\n");
|
||||
set_adb_line(ASSERT_LINE);
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_long, adb_timebase));
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
|
||||
case LST_SENDBIT0:
|
||||
case LST_SENDBIT1:
|
||||
case LST_SENDBIT2:
|
||||
case LST_SENDBIT3:
|
||||
case LST_SENDBIT4:
|
||||
case LST_SENDBIT5:
|
||||
case LST_SENDBIT6:
|
||||
case LST_SENDBIT7:
|
||||
set_adb_line(CLEAR_LINE);
|
||||
if (m_adb_buffer[m_adb_stream_ptr] & 0x80)
|
||||
{
|
||||
LOGMASKED(LOG_LINESTATE, "Send: 1\n");
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_short, adb_timebase));
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
|
||||
case LST_TSTOPSTARTa:
|
||||
LOGMASKED(LOG_LINESTATE, "Send: TStopStart end\n");
|
||||
set_adb_line(CLEAR_LINE);
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_short, adb_timebase));
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
|
||||
case LST_STARTBIT:
|
||||
LOGMASKED(LOG_LINESTATE, "Send: Start bit\n");
|
||||
set_adb_line(ASSERT_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_LINESTATE, "Send: 0\n");
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_long, adb_timebase));
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
}
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
|
||||
case LST_SENDBIT0:
|
||||
case LST_SENDBIT1:
|
||||
case LST_SENDBIT2:
|
||||
case LST_SENDBIT3:
|
||||
case LST_SENDBIT4:
|
||||
case LST_SENDBIT5:
|
||||
case LST_SENDBIT6:
|
||||
case LST_SENDBIT7:
|
||||
set_adb_line(CLEAR_LINE);
|
||||
if (m_adb_buffer[m_adb_stream_ptr] & 0x80)
|
||||
{
|
||||
LOGMASKED(LOG_LINESTATE, "Send: 1\n");
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_short, adb_timebase));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_LINESTATE, "Send: 0\n");
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_long, adb_timebase));
|
||||
}
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
case LST_SENDBIT0a:
|
||||
case LST_SENDBIT1a:
|
||||
case LST_SENDBIT2a:
|
||||
case LST_SENDBIT3a:
|
||||
case LST_SENDBIT4a:
|
||||
case LST_SENDBIT5a:
|
||||
case LST_SENDBIT6a:
|
||||
set_adb_line(ASSERT_LINE);
|
||||
if (m_adb_buffer[m_adb_stream_ptr] & 0x80)
|
||||
{
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_long, adb_timebase));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_short, adb_timebase));
|
||||
}
|
||||
m_adb_buffer[m_adb_stream_ptr] <<= 1;
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
|
||||
case LST_SENDBIT0a:
|
||||
case LST_SENDBIT1a:
|
||||
case LST_SENDBIT2a:
|
||||
case LST_SENDBIT3a:
|
||||
case LST_SENDBIT4a:
|
||||
case LST_SENDBIT5a:
|
||||
case LST_SENDBIT6a:
|
||||
set_adb_line(ASSERT_LINE);
|
||||
if (m_adb_buffer[m_adb_stream_ptr] & 0x80)
|
||||
{
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_long, adb_timebase));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_short, adb_timebase));
|
||||
}
|
||||
m_adb_buffer[m_adb_stream_ptr] <<= 1;
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
|
||||
case LST_SENDBIT7a:
|
||||
set_adb_line(ASSERT_LINE);
|
||||
if (m_adb_buffer[m_adb_stream_ptr] & 0x80)
|
||||
{
|
||||
case LST_SENDBIT7a:
|
||||
set_adb_line(ASSERT_LINE);
|
||||
if (m_adb_buffer[m_adb_stream_ptr] & 0x80)
|
||||
{
|
||||
// printf(" ");
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_long, adb_timebase));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_long, adb_timebase));
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf(" ");
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_short, adb_timebase));
|
||||
}
|
||||
m_adb_timer->adjust(attotime::from_ticks(adb_short, adb_timebase));
|
||||
}
|
||||
|
||||
m_adb_stream_ptr++;
|
||||
if (m_adb_stream_ptr == m_adb_datasize)
|
||||
{
|
||||
m_adb_linestate++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_adb_linestate = LST_SENDBIT0;
|
||||
}
|
||||
break;
|
||||
|
||||
case LST_SENDSTOP:
|
||||
LOGMASKED(LOG_LINESTATE, "Send: Stop bit begin\n");
|
||||
set_adb_line(CLEAR_LINE);
|
||||
m_adb_timer->adjust(attotime::from_ticks((adb_short*2), adb_timebase));
|
||||
m_adb_stream_ptr++;
|
||||
if (m_adb_stream_ptr == m_adb_datasize)
|
||||
{
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_adb_linestate = LST_SENDBIT0;
|
||||
}
|
||||
break;
|
||||
|
||||
case LST_SENDSTOPa:
|
||||
LOGMASKED(LOG_LINESTATE, "Send: Stop bit end\n");
|
||||
set_adb_line(ASSERT_LINE);
|
||||
m_adb_timer->adjust(attotime::never);
|
||||
m_adb_linestate = LST_IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// for input to Mac, the VIA reads on the *other* clock edge, so update this here
|
||||
if (!m_adb_direction)
|
||||
{
|
||||
write_via_data((m_adb_send & 0x80)>>7);
|
||||
m_adb_send <<= 1;
|
||||
}
|
||||
case LST_SENDSTOP:
|
||||
LOGMASKED(LOG_LINESTATE, "Send: Stop bit begin\n");
|
||||
set_adb_line(CLEAR_LINE);
|
||||
m_adb_timer->adjust(attotime::from_ticks((adb_short*2), adb_timebase));
|
||||
m_adb_linestate++;
|
||||
break;
|
||||
|
||||
// do one clock transition on CB1 to advance the VIA shifter
|
||||
//printf("ADB transition (%d)\n", m_adb_timer_ticks);
|
||||
if (m_adb_direction)
|
||||
{
|
||||
write_via_clock(m_adb_extclock ^ 1);
|
||||
write_via_clock(m_adb_extclock);
|
||||
}
|
||||
else
|
||||
{
|
||||
write_via_clock(m_adb_extclock);
|
||||
write_via_clock(m_adb_extclock ^ 1);
|
||||
}
|
||||
|
||||
m_adb_timer_ticks--;
|
||||
if (!m_adb_timer_ticks)
|
||||
{
|
||||
case LST_SENDSTOPa:
|
||||
LOGMASKED(LOG_LINESTATE, "Send: Stop bit end\n");
|
||||
set_adb_line(ASSERT_LINE);
|
||||
m_adb_timer->adjust(attotime::never);
|
||||
|
||||
if ((m_adb_direction) && (!m_bIsMCUMode))
|
||||
{
|
||||
adb_talk();
|
||||
if((m_adb_last_talk == 2) && m_adb_datasize) {
|
||||
m_adb_timer_ticks = 8;
|
||||
m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(100)));
|
||||
}
|
||||
}
|
||||
|
||||
if (!(m_adb_direction) && !(m_bIsMCUMode))
|
||||
{
|
||||
// write_via_clock(m_adb_extclock);
|
||||
write_via_clock(m_adb_extclock ^ 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void macadb_device::mac_adb_newaction(int state)
|
||||
{
|
||||
if (state != m_adb_state)
|
||||
{
|
||||
LOGMASKED(LOG_STATE, "New ADB state: %s\n", adb_statenames[state]);
|
||||
|
||||
m_adb_state = state;
|
||||
m_adb_timer_ticks = 8;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ADB_STATE_NEW_COMMAND:
|
||||
m_adb_command = m_adb_send = 0;
|
||||
m_adb_direction = 1; // Mac is shifting us a command
|
||||
m_adb_waiting_cmd = 1; // we're going to get a command
|
||||
write_adb_irq(CLEAR_LINE);
|
||||
m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(100)));
|
||||
break;
|
||||
|
||||
case ADB_STATE_XFER_EVEN:
|
||||
case ADB_STATE_XFER_ODD:
|
||||
//printf("EVEN/ODD: adb datasize %d\n", m_adb_datasize);
|
||||
if (m_adb_datasize > 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
// is something trying to send to the Mac?
|
||||
if (m_adb_direction == 0)
|
||||
{
|
||||
// set up the byte
|
||||
m_adb_send = m_adb_buffer[0];
|
||||
//printf("ADB sending %02x\n", m_adb_send);
|
||||
m_adb_datasize--;
|
||||
|
||||
// move down the rest of the buffer, if any
|
||||
for (i = 0; i < m_adb_datasize; i++)
|
||||
{
|
||||
m_adb_buffer[i] = m_adb_buffer[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_adb_send = 0;
|
||||
write_adb_irq(ASSERT_LINE);
|
||||
}
|
||||
|
||||
m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(100)));
|
||||
break;
|
||||
|
||||
case ADB_STATE_IDLE:
|
||||
write_adb_irq(CLEAR_LINE);
|
||||
break;
|
||||
}
|
||||
m_adb_linestate = LST_IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void macadb_device::adb_vblank()
|
||||
{
|
||||
#if 0
|
||||
if (m_adb_state == ADB_STATE_IDLE)
|
||||
{
|
||||
if (this->adb_pollmouse())
|
||||
@ -993,6 +885,7 @@ void macadb_device::adb_vblank()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void macadb_device::device_reset()
|
||||
@ -1006,9 +899,7 @@ void macadb_device::device_reset()
|
||||
m_adb_extclock = 0;
|
||||
m_adb_send = 0;
|
||||
m_adb_waiting_cmd = 0;
|
||||
m_adb_state = 0;
|
||||
m_adb_srqflag = false;
|
||||
m_adb_state = ADB_STATE_NOTINIT;
|
||||
m_adb_direction = 0;
|
||||
m_adb_datasize = 0;
|
||||
m_adb_last_talk = -1;
|
||||
|
@ -19,8 +19,6 @@ public:
|
||||
// construction/destruction
|
||||
macadb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void set_mcu_mode(bool bMCUMode) { m_bIsMCUMode = bMCUMode; }
|
||||
|
||||
auto via_clock_callback() { return write_via_clock.bind(); }
|
||||
auto via_data_callback() { return write_via_data.bind(); }
|
||||
auto adb_data_callback() { return write_adb_data.bind(); }
|
||||
@ -34,8 +32,6 @@ public:
|
||||
DECLARE_WRITE_LINE_MEMBER(adb_linechange_w);
|
||||
|
||||
void adb_vblank();
|
||||
void mac_adb_newaction(int state);
|
||||
int32_t get_adb_state(void) { return m_adb_state; }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -44,8 +40,6 @@ protected:
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
bool m_bIsMCUMode;
|
||||
|
||||
uint64_t m_last_adb_time;
|
||||
|
||||
emu_timer *m_adb_timer;
|
||||
@ -54,7 +48,7 @@ private:
|
||||
int m_key_matrix[7];
|
||||
|
||||
// ADB HLE state
|
||||
int32_t m_adb_state, m_adb_waiting_cmd, m_adb_datasize, m_adb_buffer[257];
|
||||
int32_t m_adb_waiting_cmd, m_adb_datasize, m_adb_buffer[257];
|
||||
int32_t m_adb_command, m_adb_send, m_adb_timer_ticks, m_adb_extclock, m_adb_direction;
|
||||
int32_t m_adb_listenreg, m_adb_listenaddr, m_adb_last_talk, m_adb_srq_switch;
|
||||
int32_t m_adb_stream_ptr;
|
||||
|
@ -336,7 +336,6 @@ void maciivx_state::maciiv_base(machine_config &config)
|
||||
m_vasp->hdsel_callback().set(FUNC(maciivx_state::hdsel_w));
|
||||
|
||||
MACADB(config, m_macadb, C15M);
|
||||
m_macadb->set_mcu_mode(true);
|
||||
|
||||
nubus_device &nubus(NUBUS(config, "nubus", 0));
|
||||
nubus.set_space(m_maincpu, AS_PROGRAM);
|
||||
|
@ -351,7 +351,6 @@ void maclc_state::maclc_base(machine_config &config)
|
||||
m_v8->hmmu_enable_callback().set(FUNC(maclc_state::set_hmmu));
|
||||
|
||||
MACADB(config, m_macadb, C15M);
|
||||
m_macadb->set_mcu_mode(true);
|
||||
|
||||
EGRET(config, m_egret, EGRET_341S0850);
|
||||
m_egret->reset_callback().set(FUNC(maclc_state::egret_reset_w));
|
||||
|
@ -266,7 +266,6 @@ void macvail_state::maclc3_base(machine_config &config)
|
||||
m_sonora->set_rom_tag("bootrom");
|
||||
|
||||
MACADB(config, m_macadb, C15M);
|
||||
m_macadb->set_mcu_mode(true);
|
||||
}
|
||||
|
||||
void macvail_state::maclc3(machine_config &config)
|
||||
|
@ -1141,7 +1141,6 @@ void macpdm_state::macpdm(machine_config &config)
|
||||
m_cuda->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
|
||||
m_cuda->via_clock_callback().set(m_via1, FUNC(via6522_device::write_cb1));
|
||||
m_cuda->via_data_callback().set(m_via1, FUNC(via6522_device::write_cb2));
|
||||
m_macadb->set_mcu_mode(true);
|
||||
m_macadb->adb_data_callback().set(m_cuda, FUNC(cuda_device::set_adb_line));
|
||||
config.set_perfect_quantum(m_maincpu);
|
||||
|
||||
|
@ -535,7 +535,6 @@ void macportable_state::macprtb(machine_config &config)
|
||||
m_screen->set_screen_update(FUNC(macportable_state::screen_update));
|
||||
|
||||
MACADB(config, m_macadb, C15M);
|
||||
m_macadb->set_mcu_mode(true);
|
||||
m_macadb->adb_data_callback().set(FUNC(macportable_state::set_adb_line));
|
||||
|
||||
SWIM1(config, m_swim, C15M);
|
||||
|
@ -918,7 +918,6 @@ void macpb030_state::macpb140(machine_config &config)
|
||||
PALETTE(config, m_palette, palette_device::MONOCHROME_INVERTED);
|
||||
|
||||
MACADB(config, m_macadb, C15M);
|
||||
m_macadb->set_mcu_mode(true);
|
||||
m_macadb->adb_data_callback().set(FUNC(macpb030_state::set_adb_line));
|
||||
|
||||
RTC3430042(config, m_rtc, 32.768_kHz_XTAL);
|
||||
@ -1034,7 +1033,6 @@ void macpb030_state::macpb160(machine_config &config)
|
||||
PALETTE(config, m_palette, FUNC(macpb030_state::macgsc_palette), 16);
|
||||
|
||||
MACADB(config, m_macadb, C15M);
|
||||
m_macadb->set_mcu_mode(true);
|
||||
m_macadb->adb_data_callback().set(FUNC(macpb030_state::set_adb_line));
|
||||
|
||||
RTC3430042(config, m_rtc, 32.768_kHz_XTAL);
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "adbmodem.h"
|
||||
#include "macadb.h"
|
||||
#include "macrtc.h"
|
||||
#include "mactoolbox.h"
|
||||
@ -53,6 +54,7 @@ public:
|
||||
m_via1(*this, "via1"),
|
||||
m_via2(*this, "via2"),
|
||||
m_macadb(*this, "macadb"),
|
||||
m_adbmodem(*this, "adbmodem"),
|
||||
m_ram(*this, RAM_TAG),
|
||||
m_swim(*this, "fdc"),
|
||||
m_floppy(*this, "fdc:%d", 0U),
|
||||
@ -78,7 +80,8 @@ public:
|
||||
private:
|
||||
required_device<m68040_device> m_maincpu;
|
||||
required_device<via6522_device> m_via1, m_via2;
|
||||
optional_device<macadb_device> m_macadb;
|
||||
required_device<macadb_device> m_macadb;
|
||||
required_device<adbmodem_device> m_adbmodem;
|
||||
required_device<ram_device> m_ram;
|
||||
required_device<applefdintf_device> m_swim;
|
||||
required_device_array<floppy_connector, 2> m_floppy;
|
||||
@ -157,7 +160,6 @@ private:
|
||||
DECLARE_WRITE_LINE_MEMBER(mac_via_irq);
|
||||
DECLARE_WRITE_LINE_MEMBER(mac_via2_irq);
|
||||
TIMER_CALLBACK_MEMBER(mac_6015_tick);
|
||||
WRITE_LINE_MEMBER(via_cb2_w) { m_macadb->adb_data_w(state); }
|
||||
int m_via_interrupt = 0, m_via2_interrupt = 0, m_scc_interrupt = 0, m_last_taken_interrupt = 0;
|
||||
|
||||
uint32_t rom_switch_r(offs_t offset);
|
||||
@ -821,8 +823,7 @@ uint8_t macquadra_state::mac_via_in_a()
|
||||
|
||||
uint8_t macquadra_state::mac_via_in_b()
|
||||
{
|
||||
int val = m_macadb->get_adb_state()<<4;
|
||||
val |= m_rtc->data_r();
|
||||
int val = m_rtc->data_r();
|
||||
|
||||
if (!m_adb_irq_pending)
|
||||
{
|
||||
@ -850,7 +851,7 @@ void macquadra_state::mac_via_out_a(uint8_t data)
|
||||
void macquadra_state::mac_via_out_b(uint8_t data)
|
||||
{
|
||||
// printf("%s VIA1 OUT B: %02x\n", machine().describe_context().c_str(), data);
|
||||
m_macadb->mac_adb_newaction((data & 0x30) >> 4);
|
||||
m_adbmodem->set_via_state((data & 0x30) >> 4);
|
||||
|
||||
m_rtc->ce_w((data & 0x04)>>2);
|
||||
m_rtc->data_w(data & 0x01);
|
||||
@ -976,7 +977,6 @@ void macquadra_state::macqd700(machine_config &config)
|
||||
m_via1->writepa_handler().set(FUNC(macquadra_state::mac_via_out_a));
|
||||
m_via1->writepb_handler().set(FUNC(macquadra_state::mac_via_out_b));
|
||||
m_via1->irq_handler().set(FUNC(macquadra_state::mac_via_irq));
|
||||
m_via1->cb2_handler().set(FUNC(macquadra_state::via_cb2_w));
|
||||
|
||||
R65NC22(config, m_via2, C7M/10);
|
||||
m_via2->readpa_handler().set(FUNC(macquadra_state::mac_via2_in_a));
|
||||
@ -985,10 +985,16 @@ void macquadra_state::macqd700(machine_config &config)
|
||||
m_via2->writepb_handler().set(FUNC(macquadra_state::mac_via2_out_b));
|
||||
m_via2->irq_handler().set(FUNC(macquadra_state::mac_via2_irq));
|
||||
|
||||
ADBMODEM(config, m_adbmodem, C7M);
|
||||
m_adbmodem->via_clock_callback().set(m_via1, FUNC(via6522_device::write_cb1));
|
||||
m_adbmodem->via_data_callback().set(m_via1, FUNC(via6522_device::write_cb2));
|
||||
m_adbmodem->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
|
||||
m_adbmodem->irq_callback().set(FUNC(macquadra_state::adb_irq_w));
|
||||
m_via1->cb2_handler().set(m_adbmodem, FUNC(adbmodem_device::set_via_data));
|
||||
config.set_maximum_quantum(attotime::from_hz(1000000));
|
||||
|
||||
MACADB(config, m_macadb, C15M);
|
||||
m_macadb->via_clock_callback().set(m_via1, FUNC(via6522_device::write_cb1));
|
||||
m_macadb->via_data_callback().set(m_via1, FUNC(via6522_device::write_cb2));
|
||||
m_macadb->adb_irq_callback().set(FUNC(macquadra_state::adb_irq_w));
|
||||
m_macadb->adb_data_callback().set(m_adbmodem, FUNC(adbmodem_device::set_adb_line));
|
||||
|
||||
SPEAKER(config, "lspeaker").front_left();
|
||||
SPEAKER(config, "rspeaker").front_right();
|
||||
|
Loading…
Reference in New Issue
Block a user