capricorn, hphybrid, nanoprocessor: Use devcb_read8 for interrupt vectoring (nw)

This commit is contained in:
AJR 2020-04-22 17:57:32 -04:00
parent 7245ef60b9
commit 65ad8907a4
14 changed files with 48 additions and 30 deletions

View File

@ -176,7 +176,7 @@ WRITE16_MEMBER(hp98034_io_card_device::reg_w)
LOG("%.06f WR R%u=%04x %s\n" , machine().time().as_double() , offset + 4 , data , machine().describe_context());
}
WRITE8_MEMBER(hp98034_io_card_device::dc_w)
void hp98034_io_card_device::dc_w(uint8_t data)
{
if (data != m_dc) {
LOG("%.06f DC=%02x\n" , machine().time().as_double() , data);
@ -185,7 +185,7 @@ WRITE8_MEMBER(hp98034_io_card_device::dc_w)
}
}
READ8_MEMBER(hp98034_io_card_device::dc_r)
uint8_t hp98034_io_card_device::dc_r()
{
uint8_t res;
@ -281,11 +281,11 @@ READ8_MEMBER(hp98034_io_card_device::switch_r)
return m_sw1->read() | 0xc0;
}
IRQ_CALLBACK_MEMBER(hp98034_io_card_device::irq_callback)
uint8_t hp98034_io_card_device::int_ack_r()
{
int res = 0xff;
if (irqline == 0 && !m_ieee488->ifc_r()) {
if (!m_ieee488->ifc_r()) {
BIT_CLR(res, 1);
}
@ -400,7 +400,7 @@ void hp98034_io_card_device::device_add_mconfig(machine_config &config)
m_cpu->set_addrmap(AS_IO, &hp98034_io_card_device::np_io_map);
m_cpu->dc_changed().set(FUNC(hp98034_io_card_device::dc_w));
m_cpu->read_dc().set(FUNC(hp98034_io_card_device::dc_r));
m_cpu->set_irq_acknowledge_callback(FUNC(hp98034_io_card_device::irq_callback));
m_cpu->int_ack().set(FUNC(hp98034_io_card_device::int_ack_r));
IEEE488_SLOT(config , "ieee_dev" , 0 , hp_ieee488_devices , nullptr);
IEEE488_SLOT(config , "ieee_rem" , 0 , remote488_devices , nullptr);

View File

@ -37,8 +37,9 @@ protected:
virtual DECLARE_WRITE16_MEMBER(reg_w) override;
private:
DECLARE_WRITE8_MEMBER(dc_w);
DECLARE_READ8_MEMBER(dc_r);
void dc_w(uint8_t data);
uint8_t dc_r();
uint8_t int_ack_r();
DECLARE_WRITE8_MEMBER(hpib_data_w);
DECLARE_WRITE8_MEMBER(hpib_ctrl_w);
@ -53,8 +54,6 @@ private:
void np_io_map(address_map &map);
void np_program_map(address_map &map);
IRQ_CALLBACK_MEMBER(irq_callback);
DECLARE_WRITE_LINE_MEMBER(ieee488_ctrl_w);
required_device<hp_nanoprocessor_device> m_cpu;

View File

@ -143,7 +143,8 @@ capricorn_cpu_device::capricorn_cpu_device(const machine_config &mconfig, const
: cpu_device(mconfig, HP_CAPRICORN, tag, owner, clock),
m_program_config("program" , ENDIANNESS_LITTLE , 8 , 16),
m_opcode_func(*this),
m_lma_out(*this)
m_lma_out(*this),
m_intack_in(*this)
{
}
@ -184,6 +185,7 @@ void capricorn_cpu_device::device_start()
m_opcode_func.resolve_safe();
m_lma_out.resolve_safe();
m_intack_in.resolve_safe(0);
}
void capricorn_cpu_device::device_reset()
@ -1534,8 +1536,9 @@ void capricorn_cpu_device::take_interrupt()
// Int. ack sequence takes 9 cycles
// Microcode FSM runs through this state sequence (see patent):
// 31-15-26-13-23-22-30-16-20
standard_irq_callback(0);
m_icount -= 9;
push_pc();
uint8_t vector = (uint8_t)standard_irq_callback(0);
uint8_t vector = m_intack_in();
vector_to_pc(vector);
}

View File

@ -28,6 +28,9 @@ public:
// Tap into fetched opcodes
auto opcode_cb() { return m_opcode_func.bind(); }
// Interrupt vector fetch (INTACK: /LMA = /RD = /WR = all 0)
auto intack_cb() { return m_intack_in.bind(); }
protected:
// device_t overrides
virtual void device_start() override;
@ -74,6 +77,7 @@ private:
devcb_write8 m_opcode_func;
devcb_write_line m_lma_out;
devcb_read8 m_intack_in;
// Effective Addresses
// When b17 = 0, b15..b0 hold 16-bit memory address

View File

@ -177,6 +177,7 @@ hp_hybrid_cpu_device::hp_hybrid_cpu_device(const machine_config &mconfig, device
, m_pa_changed_func(*this)
, m_opcode_func(*this)
, m_stm_func(*this)
, m_int_func(*this)
, m_addr_mask((1U << addrwidth) - 1)
, m_relative_mode(true)
, m_r_cycles(DEF_MEM_R_CYCLES)
@ -245,6 +246,7 @@ void hp_hybrid_cpu_device::device_start()
m_pa_changed_func.resolve_safe();
m_opcode_func.resolve_safe();
m_stm_func.resolve();
m_int_func.resolve_safe(0xff);
}
void hp_hybrid_cpu_device::device_reset()
@ -1322,8 +1324,10 @@ void hp_hybrid_cpu_device::check_for_interrupts()
return;
}
standard_irq_callback(irqline);
// Get interrupt vector in low byte
uint8_t vector = uint8_t(standard_irq_callback(irqline));
uint8_t vector = m_int_func();
uint8_t new_PA;
// Get highest numbered 1

View File

@ -87,6 +87,9 @@ public:
// Tap into fetched opcodes
auto opcode_cb() { return m_opcode_func.bind(); }
// Acknowledge interrupts
auto int_cb() { return m_int_func.bind(); }
protected:
hp_hybrid_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t addrwidth);
@ -159,6 +162,7 @@ protected:
uint8_t m_last_pa;
devcb_write16 m_opcode_func;
devcb_write8 m_stm_func;
devcb_read8 m_int_func;
int m_icount;
uint32_t m_addr_mask;

View File

@ -48,6 +48,7 @@ hp_nanoprocessor_device::hp_nanoprocessor_device(const machine_config &mconfig,
cpu_device(mconfig, HP_NANOPROCESSOR, tag, owner, clock),
m_dc_changed_func(*this),
m_read_dc_func(*this),
m_int_ack_func(*this),
m_program_config("program", ENDIANNESS_BIG, 8, 11),
m_io_config("io", ENDIANNESS_BIG, 8, 4)
{
@ -94,6 +95,7 @@ void hp_nanoprocessor_device::device_start()
m_dc_changed_func.resolve_safe();
m_read_dc_func.resolve_safe(0xff);
m_int_ack_func.resolve_safe(0xff);
}
void hp_nanoprocessor_device::device_reset()
@ -124,8 +126,9 @@ void hp_nanoprocessor_device::execute_run()
// outside of the NP, usually by ANDing the DC7 line with the interrupt
// request signal)
if (BIT(m_flags, NANO_I_BIT)) {
standard_irq_callback(0);
m_reg_ISR = m_reg_PA;
m_reg_PA = (uint16_t)(standard_irq_callback(0) & 0xff);
m_reg_PA = m_int_ack_func();
// Vector fetching takes 1 cycle
m_icount -= 1;
dc_clr(HP_NANO_IE_DC);

View File

@ -72,6 +72,9 @@ public:
// All lines that are not in input are to be reported at "1"
auto read_dc() { return m_read_dc_func.bind(); }
// Callback to fetch interrupt vector
auto int_ack() { return m_int_ack_func.bind(); }
// device_execute_interface overrides
virtual uint32_t execute_min_cycles() const noexcept override { return 2; }
// 3 cycles is for int. acknowledge + 1 instruction
@ -95,6 +98,8 @@ private:
devcb_write8 m_dc_changed_func;
devcb_read8 m_read_dc_func;
devcb_read8 m_int_ack_func;
int m_icount;
// State of processor

View File

@ -192,7 +192,7 @@ private:
DECLARE_READ16_MEMBER(hp64k_rear_sw_r);
IRQ_CALLBACK_MEMBER(hp64k_irq_callback);
uint8_t int_cb();
void hp64k_update_irl(void);
DECLARE_WRITE16_MEMBER(hp64k_irl_mask_w);
@ -527,13 +527,9 @@ READ16_MEMBER(hp64k_state::hp64k_rear_sw_r)
return m_rear_panel_sw->read() | 0x0020;
}
IRQ_CALLBACK_MEMBER(hp64k_state::hp64k_irq_callback)
uint8_t hp64k_state::int_cb()
{
if (irqline == HPHYBRID_IRL) {
return 0xff00 | (m_irl_mask & m_irl_pending);
} else {
return ~0;
}
return m_irl_mask & m_irl_pending;
}
void hp64k_state::hp64k_update_irl(void)
@ -1382,7 +1378,7 @@ void hp64k_state::hp64k(machine_config &config)
m_cpu->set_relative_mode(true);
m_cpu->set_addrmap(AS_PROGRAM, &hp64k_state::cpu_mem_map);
m_cpu->set_addrmap(AS_IO, &hp64k_state::cpu_io_map);
m_cpu->set_irq_acknowledge_callback(FUNC(hp64k_state::hp64k_irq_callback));
m_cpu->int_cb().set(FUNC(hp64k_state::int_cb));
// Actual keyboard refresh rate should be between 1 and 2 kHz
TIMER(config, "kb_timer").configure_periodic(FUNC(hp64k_state::hp64k_kb_scan), attotime::from_hz(100));

View File

@ -128,7 +128,7 @@ protected:
virtual void machine_start() override;
virtual void machine_reset() override;
IRQ_CALLBACK_MEMBER(irq_callback);
uint8_t intack_r();
DECLARE_WRITE8_MEMBER(ginten_w);
DECLARE_WRITE8_MEMBER(gintdis_w);
@ -220,7 +220,7 @@ void hp80_base_state::hp80_base(machine_config &config)
{
HP_CAPRICORN(config, m_cpu, CPU_CLOCK);
m_cpu->set_addrmap(AS_PROGRAM, &hp80_base_state::cpu_mem_map);
m_cpu->set_irq_acknowledge_callback(FUNC(hp80_base_state::irq_callback));
m_cpu->intack_cb().set(FUNC(hp80_base_state::intack_r));
config.set_perfect_quantum(m_cpu);
ADDRESS_MAP_BANK(config, "rombank").set_map(&hp80_base_state::rombank_mem_map).set_options(ENDIANNESS_LITTLE, 8, 21, HP80_OPTROM_SIZE);
@ -356,9 +356,9 @@ static const uint8_t vector_table[] = {
0x00 // No IRQ
};
IRQ_CALLBACK_MEMBER(hp80_base_state::irq_callback)
uint8_t hp80_base_state::intack_r()
{
LOG_IRQ("IRQ ACK %u %u\n" , m_top_pending , m_top_acked);
LOG_IRQ("INTACK %u %u\n" , m_top_pending , m_top_acked);
BIT_SET(m_int_acked , m_top_pending);
m_top_acked = m_top_pending;
if (m_top_pending > IRQ_IOP0_BIT && m_top_pending < IRQ_BIT_COUNT) {

View File

@ -635,7 +635,7 @@ void hp9825_state::hp9825_base(machine_config &config)
m_cpu->set_rw_cycles(6 , 6);
m_cpu->set_relative_mode(false);
m_cpu->set_addrmap(AS_IO , &hp9825_state::cpu_io_map);
m_cpu->set_irq_acknowledge_callback("io_sys" , FUNC(hp98x5_io_sys_device::irq_callback));
m_cpu->int_cb().set(m_io_sys , FUNC(hp98x5_io_sys_device::int_r));
m_cpu->pa_changed_cb().set(m_io_sys , FUNC(hp98x5_io_sys_device::pa_w));
// Needed when 98035 RTC module is connected or time advances at about 1/4 the correct speed (NP misses a lot of 1kHz interrupts)

View File

@ -3663,7 +3663,7 @@ void hp9845_base_state::hp9845_base(machine_config &config)
m_ppu->set_9845_boot_mode(true);
m_ppu->set_rw_cycles(6 , 6);
m_ppu->set_relative_mode(true);
m_ppu->set_irq_acknowledge_callback("io_sys" , FUNC(hp98x5_io_sys_device::irq_callback));
m_ppu->int_cb().set(m_io_sys , FUNC(hp98x5_io_sys_device::int_r));
m_ppu->pa_changed_cb().set(m_io_sys , FUNC(hp98x5_io_sys_device::pa_w));
HP98X5_IO_SYS(config , m_io_sys , 0);

View File

@ -70,9 +70,9 @@ void hp98x5_io_sys_device::device_reset()
update_dmar();
}
IRQ_CALLBACK_MEMBER(hp98x5_io_sys_device::irq_callback)
uint8_t hp98x5_io_sys_device::int_r()
{
if (irqline == HPHYBRID_IRL) {
if ((m_irq_pending & 0xff00) == 0) {
return m_irq_pending & 0xff;
} else {
return m_irq_pending >> 8;

View File

@ -29,7 +29,7 @@ public:
auto flg() { return m_flg_handler.bind(); }
auto dmar() { return m_dmar_handler.bind(); }
IRQ_CALLBACK_MEMBER(irq_callback);
uint8_t int_r();
void pa_w(uint8_t data);
void set_irq(uint8_t sc , int state);