mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
applepic: Add timer and remaining GPIO
This commit is contained in:
parent
aa78efa47f
commit
88589c115d
@ -11,6 +11,9 @@
|
||||
#include "emu.h"
|
||||
#include "applepic.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
#include "logmacro.h"
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(APPLEPIC, applepic_device, "applepic", "Apple 343S1021 PIC")
|
||||
|
||||
@ -22,10 +25,12 @@ applepic_device::applepic_device(const machine_config &mconfig, const char *tag,
|
||||
, m_prd_callback(*this)
|
||||
, m_pwr_callback(*this)
|
||||
, m_hint_callback(*this)
|
||||
, m_gpin_callback(*this)
|
||||
, m_gpout_callback(*this)
|
||||
, m_timer1(nullptr)
|
||||
, m_timer_last_expired(attotime::zero)
|
||||
, m_ram_address(0)
|
||||
, m_status_reg(0x80)
|
||||
, m_timer_counter(0)
|
||||
, m_timer_latch(0)
|
||||
, m_scc_control(0)
|
||||
, m_io_control(0)
|
||||
@ -69,15 +74,19 @@ void applepic_device::device_resolve_objects()
|
||||
m_prd_callback.resolve_safe(0);
|
||||
m_pwr_callback.resolve_safe();
|
||||
m_hint_callback.resolve_safe();
|
||||
m_gpin_callback.resolve_safe(0);
|
||||
m_gpout_callback.resolve_all_safe();
|
||||
}
|
||||
|
||||
void applepic_device::device_start()
|
||||
{
|
||||
// Initialize timer
|
||||
m_timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(applepic_device::timer1_callback), this));
|
||||
|
||||
// Save internal state
|
||||
save_item(NAME(m_timer_last_expired));
|
||||
save_item(NAME(m_ram_address));
|
||||
save_item(NAME(m_status_reg));
|
||||
save_item(NAME(m_timer_counter));
|
||||
save_item(NAME(m_timer_latch));
|
||||
save_item(STRUCT_MEMBER(m_dma_channel, control));
|
||||
save_item(STRUCT_MEMBER(m_dma_channel, map));
|
||||
@ -151,7 +160,7 @@ void applepic_device::host_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (BIT(m_status_reg, 2) != BIT(data, 2))
|
||||
{
|
||||
logerror("%s: /RSTPIC %dactive\n", machine().describe_context(), BIT(data, 2) ? "in" : "");
|
||||
LOG("%s: /RSTPIC %dactive\n", machine().describe_context(), BIT(data, 2) ? "in" : "");
|
||||
m_iopcpu->set_input_line(INPUT_LINE_RESET, BIT(data, 2) ? CLEAR_LINE : ASSERT_LINE);
|
||||
}
|
||||
if (BIT(data, 3))
|
||||
@ -161,7 +170,7 @@ void applepic_device::host_w(offs_t offset, u8 data)
|
||||
m_status_reg &= ~(data & 0x30);
|
||||
if ((m_status_reg & 0x30) == 0)
|
||||
{
|
||||
logerror("%s: Host interrupts acknowledged\n", machine().describe_context());
|
||||
LOG("%s: Host interrupts acknowledged\n", machine().describe_context());
|
||||
m_hint_callback(CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
@ -191,15 +200,23 @@ WRITE_LINE_MEMBER(applepic_device::pint_w)
|
||||
|
||||
WRITE_LINE_MEMBER(applepic_device::reqa_w)
|
||||
{
|
||||
if (state == ASSERT_LINE)
|
||||
m_dma_channel[0].control |= 0x02;
|
||||
else
|
||||
m_dma_channel[0].control &= 0xfd;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(applepic_device::reqb_w)
|
||||
{
|
||||
if (state == ASSERT_LINE)
|
||||
m_dma_channel[1].control |= 0x02;
|
||||
else
|
||||
m_dma_channel[1].control &= 0xfd;
|
||||
}
|
||||
|
||||
u8 applepic_device::timer_r(offs_t offset)
|
||||
{
|
||||
u16 reg = BIT(offset, 1) ? m_timer_latch : m_timer_counter;
|
||||
u16 reg = BIT(offset, 1) ? m_timer_latch : get_timer_count();
|
||||
if (BIT(offset, 0))
|
||||
return (reg & 0xff00) >> 8;
|
||||
else
|
||||
@ -214,14 +231,34 @@ void applepic_device::timer_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (BIT(offset, 0))
|
||||
{
|
||||
m_timer_latch = u16(data) << 8 | (m_timer_latch & 0xff00);
|
||||
m_timer_latch = u16(data) << 8 | (m_timer_latch & 0x00ff);
|
||||
if (offset == 1)
|
||||
{
|
||||
reset_interrupt(5);
|
||||
m_timer1->adjust(clocks_to_attotime(m_timer_latch * 8 + 12));
|
||||
}
|
||||
}
|
||||
else
|
||||
m_timer_latch = (m_timer_latch & 0xff00) | data;
|
||||
}
|
||||
|
||||
u16 applepic_device::get_timer_count() const
|
||||
{
|
||||
if (m_timer1->enabled())
|
||||
return u16((attotime_to_clocks(m_timer1->remaining()) - 4) / 8);
|
||||
else
|
||||
return 0xffff - u16((attotime_to_clocks(machine().time() - m_timer_last_expired) + 4) / 8);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(applepic_device::timer1_callback)
|
||||
{
|
||||
set_interrupt(5);
|
||||
if (BIT(m_timer_dpll_control, 0))
|
||||
m_timer1->adjust(clocks_to_attotime((m_timer_latch + 2) * 8));
|
||||
else
|
||||
m_timer_last_expired = machine().time();
|
||||
}
|
||||
|
||||
u8 applepic_device::dma_channel_r(offs_t offset)
|
||||
{
|
||||
dma_channel &channel = m_dma_channel[BIT(offset, 3)];
|
||||
@ -257,7 +294,7 @@ void applepic_device::dma_channel_w(offs_t offset, u8 data)
|
||||
switch (offset & 7)
|
||||
{
|
||||
case 0:
|
||||
channel.control = data;
|
||||
channel.control = (data & 0xfd) | (channel.control & 0x02);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
@ -309,12 +346,13 @@ void applepic_device::io_control_w(u8 data)
|
||||
|
||||
u8 applepic_device::timer_dpll_control_r()
|
||||
{
|
||||
return m_timer_dpll_control;
|
||||
return m_timer_dpll_control | (m_gpin_callback() & 3) << 2;
|
||||
}
|
||||
|
||||
void applepic_device::timer_dpll_control_w(u8 data)
|
||||
{
|
||||
m_timer_dpll_control = data;
|
||||
m_timer_dpll_control = (m_timer_dpll_control & 0xa0) | (data & 0x53);
|
||||
m_gpout_callback[0](BIT(data, 1));
|
||||
}
|
||||
|
||||
u8 applepic_device::int_mask_r()
|
||||
@ -326,7 +364,7 @@ void applepic_device::int_mask_w(u8 data)
|
||||
{
|
||||
for (int which = 1; which <= 5; which++)
|
||||
if (BIT(m_int_mask, which) != BIT(data, which))
|
||||
logerror("%s: %sabling %s interrupt\n", machine().describe_context(), BIT(data, which) ? "En" : "Dis", s_interrupt_names[which]);
|
||||
LOG("%s: %sabling %s interrupt\n", machine().describe_context(), BIT(data, which) ? "En" : "Dis", s_interrupt_names[which]);
|
||||
|
||||
m_int_mask = data & 0x3e;
|
||||
m_iopcpu->set_input_line(r65c02_device::IRQ_LINE, (m_int_mask & m_int_reg) != 0 ? ASSERT_LINE : CLEAR_LINE);
|
||||
@ -344,7 +382,7 @@ void applepic_device::int_reg_w(u8 data)
|
||||
m_int_reg &= ~data;
|
||||
if ((m_int_mask & m_int_reg) == 0)
|
||||
{
|
||||
logerror("%s: 6502 interrupts acknowledged\n", machine().describe_context());
|
||||
LOG("%s: 6502 interrupts acknowledged\n", machine().describe_context());
|
||||
m_iopcpu->set_input_line(r65c02_device::IRQ_LINE, CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
@ -354,7 +392,7 @@ void applepic_device::set_interrupt(int which)
|
||||
{
|
||||
if (!BIT(m_int_reg, which))
|
||||
{
|
||||
logerror("%s: Setting %s interrupt\n", machine().describe_context(), s_interrupt_names[which]);
|
||||
LOG("%s: Setting %s interrupt\n", machine().describe_context(), s_interrupt_names[which]);
|
||||
m_int_reg |= (1 << which);
|
||||
if ((m_int_reg & m_int_mask) == (1 << which))
|
||||
m_iopcpu->set_input_line(r65c02_device::IRQ_LINE, ASSERT_LINE);
|
||||
@ -365,7 +403,7 @@ void applepic_device::reset_interrupt(int which)
|
||||
{
|
||||
if (BIT(m_int_reg, which))
|
||||
{
|
||||
logerror("%s: Resetting %s interrupt\n", machine().describe_context(), s_interrupt_names[which]);
|
||||
LOG("%s: Resetting %s interrupt\n", machine().describe_context(), s_interrupt_names[which]);
|
||||
if ((m_int_reg & m_int_mask) == (1 << which))
|
||||
m_iopcpu->set_input_line(r65c02_device::IRQ_LINE, CLEAR_LINE);
|
||||
m_int_reg &= ~(1 << which);
|
||||
@ -379,7 +417,7 @@ u8 applepic_device::host_reg_r()
|
||||
|
||||
void applepic_device::host_reg_w(u8 data)
|
||||
{
|
||||
logerror("%s: INTHST0 %srequested, INTHST1 %srequested\n", machine().describe_context(), BIT(data, 2) ? "" : "not ", BIT(data, 3) ? "" : "not ");
|
||||
LOG("%s: INTHST0 %srequested, INTHST1 %srequested\n", machine().describe_context(), BIT(data, 2) ? "" : "not ", BIT(data, 3) ? "" : "not ");
|
||||
m_status_reg |= (data & 0x0c) << 2;
|
||||
if ((data & 0x0c) != 0)
|
||||
m_hint_callback(ASSERT_LINE);
|
||||
|
@ -24,6 +24,7 @@ public:
|
||||
auto prd_callback() { return m_prd_callback.bind(); }
|
||||
auto pwr_callback() { return m_pwr_callback.bind(); }
|
||||
auto hint_callback() { return m_hint_callback.bind(); }
|
||||
auto gpin_callback() { return m_gpin_callback.bind(); }
|
||||
auto gpout0_callback() { return m_gpout_callback[0].bind(); }
|
||||
auto gpout1_callback() { return m_gpout_callback[1].bind(); }
|
||||
|
||||
@ -55,7 +56,8 @@ private:
|
||||
|
||||
u8 timer_r(offs_t offset);
|
||||
void timer_w(offs_t offset, u8 data);
|
||||
void reset_timer_interrupt();
|
||||
u16 get_timer_count() const;
|
||||
TIMER_CALLBACK_MEMBER(timer1_callback);
|
||||
u8 dma_channel_r(offs_t offset);
|
||||
void dma_channel_w(offs_t offset, u8 data);
|
||||
u8 scc_control_r();
|
||||
@ -84,12 +86,14 @@ private:
|
||||
devcb_read8 m_prd_callback;
|
||||
devcb_write8 m_pwr_callback;
|
||||
devcb_write_line m_hint_callback;
|
||||
devcb_read8 m_gpin_callback;
|
||||
devcb_write_line::array<2> m_gpout_callback;
|
||||
|
||||
// internal state
|
||||
emu_timer *m_timer1;
|
||||
attotime m_timer_last_expired;
|
||||
u16 m_ram_address;
|
||||
u8 m_status_reg;
|
||||
u16 m_timer_counter;
|
||||
u16 m_timer_latch;
|
||||
dma_channel m_dma_channel[2];
|
||||
u8 m_scc_control;
|
||||
|
@ -463,7 +463,12 @@ uint32_t mac_state::buserror_r()
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t mac_state::maciifx_unknown_r()
|
||||
uint8_t mac_state::maciifx_8010_r()
|
||||
{
|
||||
return 0x40;
|
||||
}
|
||||
|
||||
uint8_t mac_state::maciifx_8040_r()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -569,7 +574,8 @@ void mac_state::maciifx_map(address_map &map)
|
||||
map(0x50000000, 0x50001fff).rw(FUNC(mac_state::mac_via_r), FUNC(mac_state::mac_via_w)).mirror(0x00f00000);
|
||||
map(0x50004000, 0x50005fff).rw("sccpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0xff00ff00);
|
||||
map(0x50004000, 0x50005fff).rw("sccpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0x00ff00ff);
|
||||
map(0x50008040, 0x50008040).r(FUNC(mac_state::maciifx_unknown_r)).mirror(0x00f00000);
|
||||
map(0x50008010, 0x50008010).r(FUNC(mac_state::maciifx_8010_r)).mirror(0x00f00000);
|
||||
map(0x50008040, 0x50008040).r(FUNC(mac_state::maciifx_8040_r)).mirror(0x00f00000);
|
||||
map(0x5000a000, 0x5000bfff).rw(FUNC(mac_state::macplus_scsi_r), FUNC(mac_state::macii_scsi_w)).mirror(0x00f00000);
|
||||
map(0x5000c060, 0x5000c063).r(FUNC(mac_state::macii_scsi_drq_r)).mirror(0x00f00000);
|
||||
map(0x5000d000, 0x5000d003).w(FUNC(mac_state::macii_scsi_drq_w)).mirror(0x00f00000);
|
||||
|
@ -311,7 +311,8 @@ private:
|
||||
uint8_t oss_r(offs_t offset);
|
||||
void oss_w(offs_t offset, uint8_t data);
|
||||
uint32_t buserror_r();
|
||||
uint8_t maciifx_unknown_r();
|
||||
uint8_t maciifx_8010_r();
|
||||
uint8_t maciifx_8040_r();
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(nubus_irq_9_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(nubus_irq_a_w);
|
||||
|
Loading…
Reference in New Issue
Block a user