mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
Various changes related to 68000 interrupts (nw)
- Use 8-bit handlers for 68000 vector fetches - mc68307: Use internal map for interrupt acknowledgment (was overlooked) - tti: Change interrupt level from 5 to 2 - mc68901: Add (untested) callback for daisy-chained interrupt acknowledgment
This commit is contained in:
parent
5591de5b03
commit
d012d7d80c
@ -34,11 +34,16 @@ WRITE8_MEMBER(m68307_cpu_device::m68307_internal_serial_w)
|
||||
|
||||
|
||||
|
||||
void m68307_cpu_device::m68307_internal_map(address_map &map)
|
||||
void m68307_cpu_device::internal_map(address_map &map)
|
||||
{
|
||||
map(0x000000f0, 0x000000ff).rw(FUNC(m68307_cpu_device::m68307_internal_base_r), FUNC(m68307_cpu_device::m68307_internal_base_w));
|
||||
}
|
||||
|
||||
void m68307_cpu_device::cpu_space_map(address_map &map)
|
||||
{
|
||||
map(0xfffff0, 0xffffff).r(FUNC(m68307_cpu_device::int_ack)).umask16(0x00ff);
|
||||
}
|
||||
|
||||
|
||||
void m68307_cpu_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
@ -52,7 +57,7 @@ void m68307_cpu_device::device_add_mconfig(machine_config &config)
|
||||
|
||||
|
||||
m68307_cpu_device::m68307_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: m68000_device(mconfig, tag, owner, clock, M68307, 16, 24, address_map_constructor(FUNC(m68307_cpu_device::m68307_internal_map), this)),
|
||||
: m68000_device(mconfig, tag, owner, clock, M68307, 16, 24, address_map_constructor(FUNC(m68307_cpu_device::internal_map), this)),
|
||||
m_write_irq(*this),
|
||||
m_write_a_tx(*this),
|
||||
m_write_b_tx(*this),
|
||||
@ -68,6 +73,8 @@ m68307_cpu_device::m68307_cpu_device(const machine_config &mconfig, const char *
|
||||
m_m68307_scrlow = 0;
|
||||
m_m68307_currentcs = 0;
|
||||
m_ipl = 0;
|
||||
|
||||
m_cpu_space_config.m_internal_map = address_map_constructor(FUNC(m68307_cpu_device::cpu_space_map), this);
|
||||
}
|
||||
|
||||
|
||||
@ -215,10 +222,10 @@ void m68307_cpu_device::licr2_interrupt()
|
||||
set_ipl(prioritylevel);
|
||||
}
|
||||
|
||||
IRQ_CALLBACK_MEMBER(m68307_cpu_device::int_ack)
|
||||
uint8_t m68307_cpu_device::int_ack(offs_t offset)
|
||||
{
|
||||
uint8_t type = m_m68307SIM->get_int_type(this, irqline);
|
||||
logerror("Interrupt acknowledged: level %d, type %01X\n", irqline, type);
|
||||
uint8_t type = m_m68307SIM->get_int_type(this, offset);
|
||||
logerror("Interrupt acknowledged: level %d, type %01X\n", offset, type);
|
||||
|
||||
// UART provides its own vector
|
||||
if (type == 0x0c)
|
||||
@ -227,11 +234,6 @@ IRQ_CALLBACK_MEMBER(m68307_cpu_device::int_ack)
|
||||
return (m_m68307SIM->m_pivr & 0xf0) | type;
|
||||
}
|
||||
|
||||
void m68307_cpu_device::device_config_complete()
|
||||
{
|
||||
set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(m68307_cpu_device::int_ack), this));
|
||||
}
|
||||
|
||||
void m68307_cpu_device::device_start()
|
||||
{
|
||||
init_cpu_m68000();
|
||||
|
@ -36,7 +36,6 @@ protected:
|
||||
class m68307_mbus;
|
||||
class m68307_timer;
|
||||
|
||||
virtual void device_config_complete() override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
@ -52,7 +51,7 @@ private:
|
||||
DECLARE_WRITE_LINE_MEMBER(timer1_interrupt);
|
||||
DECLARE_WRITE_LINE_MEMBER(mbus_interrupt);
|
||||
|
||||
IRQ_CALLBACK_MEMBER(int_ack);
|
||||
uint8_t int_ack(offs_t offset);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(m68307_duart_irq_handler);
|
||||
DECLARE_WRITE_LINE_MEMBER(m68307_duart_txa) { m_write_a_tx(state); }
|
||||
@ -75,7 +74,8 @@ private:
|
||||
DECLARE_READ8_MEMBER( m68307_internal_mbus_r );
|
||||
DECLARE_WRITE8_MEMBER( m68307_internal_mbus_w );
|
||||
|
||||
void m68307_internal_map(address_map &map);
|
||||
void internal_map(address_map &map);
|
||||
void cpu_space_map(address_map &map);
|
||||
|
||||
devcb_write_line m_write_irq, m_write_a_tx, m_write_b_tx;
|
||||
devcb_read8 m_read_inport;
|
||||
|
@ -69,21 +69,20 @@ void m68340_cpu_device::update_ipl()
|
||||
|
||||
void m68340_cpu_device::internal_vectors_r(address_map &map)
|
||||
{
|
||||
map(0xfffff2, 0xffffff).r(FUNC(m68340_cpu_device::int_ack));
|
||||
map(0xfffff0, 0xffffff).r(FUNC(m68340_cpu_device::int_ack)).umask16(0x00ff);
|
||||
}
|
||||
|
||||
|
||||
u16 m68340_cpu_device::int_ack(offs_t offset)
|
||||
uint8_t m68340_cpu_device::int_ack(offs_t offset)
|
||||
{
|
||||
int irqline = offset + 1;
|
||||
uint8_t pit_iarb = pit_arbitrate(irqline);
|
||||
uint8_t scu_iarb = m_serial->arbitrate(irqline);
|
||||
uint8_t t1_iarb = m_timer[0]->arbitrate(irqline);
|
||||
uint8_t t2_iarb = m_timer[1]->arbitrate(irqline);
|
||||
uint8_t pit_iarb = pit_arbitrate(offset);
|
||||
uint8_t scu_iarb = m_serial->arbitrate(offset);
|
||||
uint8_t t1_iarb = m_timer[0]->arbitrate(offset);
|
||||
uint8_t t2_iarb = m_timer[1]->arbitrate(offset);
|
||||
uint8_t iarb = std::max({pit_iarb, scu_iarb, t1_iarb, t2_iarb});
|
||||
LOGMASKED(LOG_IPL, "Level %d interrupt arbitration: PIT = %X, SCU = %X, T1 = %X, T2 = %X\n", irqline, pit_iarb, scu_iarb, t1_iarb, t2_iarb);
|
||||
LOGMASKED(LOG_IPL, "Level %d interrupt arbitration: PIT = %X, SCU = %X, T1 = %X, T2 = %X\n", offset, pit_iarb, scu_iarb, t1_iarb, t2_iarb);
|
||||
int response = 0;
|
||||
uint32_t vector = 0x18; // Spurious interrupt
|
||||
uint8_t vector = 0x18; // Spurious interrupt
|
||||
|
||||
// Valid IARB levels are F (high) to 1 (low) and should be unique among modules using the same interrupt level
|
||||
if (iarb != 0)
|
||||
@ -118,9 +117,9 @@ u16 m68340_cpu_device::int_ack(offs_t offset)
|
||||
}
|
||||
|
||||
if (response == 0)
|
||||
logerror("Spurious interrupt (level %d)\n", irqline);
|
||||
logerror("Spurious interrupt (level %d)\n", offset);
|
||||
else if (response > 1)
|
||||
logerror("%d modules responded to interrupt (level %d, IARB = %X)\n", response, irqline, iarb);
|
||||
logerror("%d modules responded to interrupt (level %d, IARB = %X)\n", response, offset, iarb);
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ private:
|
||||
|
||||
void update_ipl();
|
||||
void internal_vectors_r(address_map &map);
|
||||
u16 int_ack(offs_t offset);
|
||||
uint8_t int_ack(offs_t offset);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(periodic_interrupt_timer_callback);
|
||||
|
||||
|
@ -355,7 +355,7 @@ void mc68328_device::internal_map(address_map &map)
|
||||
|
||||
void mc68328_device::cpu_space_map(address_map &map)
|
||||
{
|
||||
map(0xfffff2, 0xffffff).r(FUNC(mc68328_device::irq_callback));
|
||||
map(0xfffff0, 0xffffff).r(FUNC(mc68328_device::irq_callback)).umask16(0x00ff);
|
||||
}
|
||||
|
||||
|
||||
@ -387,6 +387,7 @@ mc68328_device::mc68328_device(const machine_config &mconfig, const char *tag, d
|
||||
, m_in_spim_cb(*this)
|
||||
, m_spim_xch_trigger_cb(*this)
|
||||
{
|
||||
m_cpu_space_config.m_internal_map = address_map_constructor(FUNC(mc68328_device::cpu_space_map), this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -708,9 +709,9 @@ void mc68328_device::set_port_d_lines(uint8_t state, int bit)
|
||||
poll_port_d_interrupts();
|
||||
}
|
||||
|
||||
u16 mc68328_device::irq_callback(offs_t offset)
|
||||
uint8_t mc68328_device::irq_callback(offs_t offset)
|
||||
{
|
||||
return m_regs.ivr | (offset + 1);
|
||||
return m_regs.ivr | offset;
|
||||
}
|
||||
|
||||
uint32_t mc68328_device::get_timer_frequency(uint32_t index)
|
||||
|
@ -331,7 +331,7 @@ private:
|
||||
void set_interrupt_line(uint32_t line, uint32_t active);
|
||||
void poll_port_d_interrupts();
|
||||
void cpu_space_map(address_map &map);
|
||||
u16 irq_callback(offs_t offset);
|
||||
uint8_t irq_callback(offs_t offset);
|
||||
uint32_t get_timer_frequency(uint32_t index);
|
||||
void maybe_start_timer(uint32_t index, uint32_t new_enable);
|
||||
void timer_compare_event(uint32_t index);
|
||||
|
@ -344,6 +344,7 @@ mc68901_device::mc68901_device(const machine_config &mconfig, const char *tag, d
|
||||
m_out_so_cb(*this),
|
||||
//m_out_rr_cb(*this),
|
||||
//m_out_tr_cb(*this),
|
||||
m_iack_chain_cb(*this),
|
||||
m_aer(0),
|
||||
m_ier(0),
|
||||
m_gpio_input(0),
|
||||
@ -370,6 +371,7 @@ void mc68901_device::device_start()
|
||||
m_out_so_cb.resolve_safe();
|
||||
//m_out_rr_cb.resolve_safe();
|
||||
//m_out_tr_cb.resolve_safe();
|
||||
m_iack_chain_cb.resolve();
|
||||
|
||||
/* create the timers */
|
||||
m_timer[TIMER_A] = timer_alloc(TIMER_A);
|
||||
@ -1114,7 +1116,7 @@ WRITE8_MEMBER( mc68901_device::write )
|
||||
}
|
||||
|
||||
|
||||
u16 mc68901_device::get_vector()
|
||||
uint8_t mc68901_device::get_vector()
|
||||
{
|
||||
for (int ch = 15; ch >= 0; ch--)
|
||||
{
|
||||
@ -1138,6 +1140,9 @@ u16 mc68901_device::get_vector()
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_iack_chain_cb.isnull())
|
||||
return m_iack_chain_cb();
|
||||
else
|
||||
return 0x18; // Spurious irq
|
||||
}
|
||||
|
||||
|
@ -71,11 +71,12 @@ public:
|
||||
auto out_so_cb() { return m_out_so_cb.bind(); }
|
||||
//auto out_rr_cb() { return m_out_rr_cb.bind(); }
|
||||
//auto out_tr_cb() { return m_out_tr_cb.bind(); }
|
||||
auto iack_chain_cb() { return m_iack_chain_cb.bind(); }
|
||||
|
||||
DECLARE_READ8_MEMBER( read );
|
||||
DECLARE_WRITE8_MEMBER( write );
|
||||
|
||||
u16 get_vector();
|
||||
uint8_t get_vector();
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( i0_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( i1_w );
|
||||
@ -220,6 +221,8 @@ private:
|
||||
//devcb_write_line m_out_rr_cb;
|
||||
//devcb_write_line m_out_tr_cb;
|
||||
|
||||
devcb_read8 m_iack_chain_cb;
|
||||
|
||||
//int m_device_type; /* device type */
|
||||
|
||||
/* registers */
|
||||
|
@ -200,19 +200,18 @@ void tmp68301_device::device_reset()
|
||||
|
||||
void tmp68301_device::internal_vectors_r(address_map &map)
|
||||
{
|
||||
map(0xfffff2, 0xffffff).r(FUNC(tmp68301_device::irq_callback));
|
||||
map(0xfffff0, 0xffffff).r(FUNC(tmp68301_device::irq_callback)).umask16(0x00ff);
|
||||
}
|
||||
|
||||
|
||||
u16 tmp68301_device::irq_callback(offs_t offset)
|
||||
uint8_t tmp68301_device::irq_callback(offs_t offset)
|
||||
{
|
||||
int irqline = offset + 1;
|
||||
uint8_t IVNR = m_regs[0x9a/2] & 0xe0; // Interrupt Vector Number Register (IVNR)
|
||||
|
||||
for (int src : { 0, 7, 3, 1, 8, 4, 5, 9, 2 })
|
||||
{
|
||||
// check if the IPL matches
|
||||
if (irqline == (m_icr[src] & 0x07))
|
||||
if (offset == (m_icr[src] & 0x07))
|
||||
{
|
||||
// check if interrupt is pending and not masked out
|
||||
u16 mask = (src > 2 ? 2 : 1) << src;
|
||||
|
@ -92,7 +92,7 @@ private:
|
||||
uint8_t m_icr[10];
|
||||
|
||||
void internal_vectors_r(address_map &map);
|
||||
u16 irq_callback(offs_t offset);
|
||||
uint8_t irq_callback(offs_t offset);
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(TMP68301, tmp68301_device)
|
||||
|
@ -1219,7 +1219,7 @@ void st_state::ikbd_map(address_map &map)
|
||||
void st_state::cpu_space_map(address_map &map)
|
||||
{
|
||||
map(0xfffff0, 0xffffff).m(m_maincpu, FUNC(m68000_base_device::autovectors_map));
|
||||
map(0xfffffc, 0xfffffd).r(m_mfp, FUNC(mc68901_device::get_vector));
|
||||
map(0xfffffd, 0xfffffd).r(m_mfp, FUNC(mc68901_device::get_vector));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
|
@ -53,6 +53,7 @@ private:
|
||||
IRQ_CALLBACK_MEMBER(intack);
|
||||
|
||||
void prg_map(address_map &map);
|
||||
void fc7_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<mc68901_device> m_mfp;
|
||||
@ -126,6 +127,11 @@ void tti_state::prg_map(address_map &map)
|
||||
map(0x8007d, 0x8007d).w(FUNC(tti_state::channel_w));
|
||||
}
|
||||
|
||||
void tti_state::fc7_map(address_map &map)
|
||||
{
|
||||
map(0xffff5, 0xffff5).r(m_mfp, FUNC(mc68901_device::get_vector));
|
||||
}
|
||||
|
||||
static void tti_scsi_devices(device_slot_interface &device)
|
||||
{
|
||||
// FIXME: these device options are placeholders
|
||||
@ -148,14 +154,14 @@ void tti_state::tti(machine_config &config)
|
||||
{
|
||||
M68008(config, m_maincpu, 20_MHz_XTAL / 2); // guess
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &tti_state::prg_map);
|
||||
m_maincpu->set_irq_acknowledge_callback(FUNC(tti_state::intack));
|
||||
m_maincpu->set_addrmap(m68008_device::AS_CPU_SPACE, &tti_state::fc7_map);
|
||||
|
||||
MC68901(config, m_mfp, 20_MHz_XTAL / 2); // guess
|
||||
m_mfp->set_timer_clock(20_MHz_XTAL / 2); // guess
|
||||
m_mfp->set_rx_clock(9600); // for testing (FIXME: actually 16x)
|
||||
m_mfp->set_tx_clock(9600); // for testing (FIXME: actually 16x)
|
||||
m_mfp->out_so_cb().set("rs232", FUNC(rs232_port_device::write_txd));
|
||||
m_mfp->out_irq_cb().set_inputline("maincpu", M68K_IRQ_5);
|
||||
m_mfp->out_irq_cb().set_inputline("maincpu", M68K_IRQ_2); // probably
|
||||
|
||||
NSCSI_BUS(config, "scsibus");
|
||||
NSCSI_CONNECTOR(config, "scsibus:0", tti_scsi_devices, nullptr);
|
||||
|
Loading…
Reference in New Issue
Block a user