diff --git a/src/devices/cpu/t11/t11.cpp b/src/devices/cpu/t11/t11.cpp index 49865438a540f..df0b3e4d264c1 100644 --- a/src/devices/cpu/t11/t11.cpp +++ b/src/devices/cpu/t11/t11.cpp @@ -36,10 +36,24 @@ DEFINE_DEVICE_TYPE(T11, t11_device, "t11", "DEC T11") +DEFINE_DEVICE_TYPE(LSI11, lsi11_device, "lsi11", "DEC LSI-11") DEFINE_DEVICE_TYPE(K1801VM1, k1801vm1_device, "k1801vm1", "K1801VM1") DEFINE_DEVICE_TYPE(K1801VM2, k1801vm2_device, "k1801vm2", "K1801VM2") +/* + * Not implemented: + * + * instruction timing, microcode-related insns, HALT state and ODT, + * traps: double bus error and bus error on vector fetch. + */ +lsi11_device::lsi11_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : t11_device(mconfig, LSI11, tag, owner, clock) + , z80_daisy_chain_interface(mconfig, *this) +{ + c_insn_set = IS_LEIS | IS_MXPS; // EISFIS is an option +} + /* * Not implemented: * @@ -223,6 +237,83 @@ static const struct irq_table_entry irq_table[] = { 7<<5, 0140 } }; +// priorities from LSI-11 Processor Handbook, p. 4-70 +void lsi11_device::t11_check_irqs() +{ + int8_t mcir = MCIR_NONE; + uint16_t vsel = 0; + + if (m_mcir != MCIR_NONE) + { + mcir = m_mcir; + vsel = m_vsel; + } + // 1. bus error + else if (m_bus_error) + { + m_bus_error = false; + mcir = MCIR_IRQ; + vsel = T11_TIMEOUT; + } + // 3. illegal insn + else if (mcir == MCIR_ILL) + { + take_interrupt(vsel); + } + // 4. trace trap + else if (m_trace_trap) + { + if (GET_T) + { + mcir = MCIR_IRQ; + vsel = T11_BPT; + } + else + m_trace_trap = false; + } + else if (GET_T) + { + m_trace_trap = true; + } + // 5. halt line (B HALT L bus signal) -- FIXME not implemented + // 6. power fail (B POK H bus signal) + else if (m_power_fail) + { + m_power_fail = false; + mcir = MCIR_IRQ; + vsel = T11_PWRFAIL; + } + // 7. event line (B EVNT L bus signal) + else if (m_cp[2] && !GET_I) + { + m_cp[2] = false; + mcir = MCIR_IRQ; + vsel = VM1_EVNT; + } + // 8. device interrupt (B IRQ4 L bus signal) + else if (m_vec_active && !GET_I) + { + device_z80daisy_interface *intf = daisy_get_irq_device(); + int vec = (intf != nullptr) ? intf->z80daisy_irq_ack() : m_in_iack_func(0); + if (vec == -1 || vec == 0) + { + m_vec_active = 0; + return; + } + else + { + mcir = MCIR_IRQ; + vsel = vec; + } + } + + if (mcir == MCIR_IRQ) + take_interrupt(vsel); + + m_mcir = MCIR_NONE; +} + + // PSW7 masks external interrupts (except IRQ1) -- IRQ2, IRQ3, VIRQ // PSW11 also masks IRQ1. PSW10 also masks ACLO. void k1801vm1_device::t11_check_irqs() diff --git a/src/devices/cpu/t11/t11.h b/src/devices/cpu/t11/t11.h index 92452d5d866b9..842a70226919f 100644 --- a/src/devices/cpu/t11/t11.h +++ b/src/devices/cpu/t11/t11.h @@ -1196,6 +1196,16 @@ class t11_device : public cpu_device void sub_ixd_ixd(uint16_t op); }; +class lsi11_device : public t11_device, public z80_daisy_chain_interface +{ +public: + // construction/destruction + lsi11_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void t11_check_irqs() override; +}; + class k1801vm1_device : public t11_device, public z80_daisy_chain_interface { public: @@ -1230,6 +1240,7 @@ class k1801vm2_device : public t11_device, public z80_daisy_chain_interface DECLARE_DEVICE_TYPE(T11, t11_device) +DECLARE_DEVICE_TYPE(LSI11, lsi11_device) DECLARE_DEVICE_TYPE(K1801VM1, k1801vm1_device) DECLARE_DEVICE_TYPE(K1801VM2, k1801vm2_device) diff --git a/src/mame/skeleton/terak.cpp b/src/mame/skeleton/terak.cpp index 07e601c13577a..99d199c18e50e 100644 --- a/src/mame/skeleton/terak.cpp +++ b/src/mame/skeleton/terak.cpp @@ -12,8 +12,10 @@ Floppies were 8 inch IBM format. ****************************************************************************/ #include "emu.h" -//#include "bus/qbus/qbus.h" + +#include "bus/qbus/qbus.h" #include "cpu/t11/t11.h" + #include "emupal.h" #include "screen.h" @@ -26,6 +28,7 @@ class terak_state : public driver_device terak_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_qbus(*this, "qbus") { } void terak(machine_config &config); @@ -41,9 +44,14 @@ class terak_state : public driver_device uint8_t m_unit = 0; uint8_t m_cmd = 0; + virtual void machine_reset() override ATTR_COLD; virtual void video_start() override ATTR_COLD; - required_device m_maincpu; + + void reset_w(int state); + + required_device m_maincpu; + required_device m_qbus; }; uint16_t terak_state::terak_fdc_status_r() @@ -91,6 +99,12 @@ static INPUT_PORTS_START( terak ) INPUT_PORTS_END +static const z80_daisy_config daisy_chain[] = +{ + { "qbus" }, + { nullptr } +}; + void terak_state::machine_reset() { } @@ -104,13 +118,23 @@ uint32_t terak_state::screen_update_terak(screen_device &screen, bitmap_ind16 &b return 0; } +void terak_state::reset_w(int state) +{ + if (state == ASSERT_LINE) + { + m_qbus->init_w(); + } +} + void terak_state::terak(machine_config &config) { /* basic machine hardware */ - T11(config, m_maincpu, 4'000'000); // FIXME: actually LSI-11 + LSI11(config, m_maincpu, 4'000'000); m_maincpu->set_initial_mode(6 << 13); m_maincpu->set_addrmap(AS_PROGRAM, &terak_state::mem_map); + m_maincpu->set_daisy_config(daisy_chain); + m_maincpu->out_reset().set(FUNC(terak_state::reset_w)); /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); @@ -122,11 +146,21 @@ void terak_state::terak(machine_config &config) screen.set_palette("palette"); PALETTE(config, "palette", palette_device::MONOCHROME); + + QBUS(config, m_qbus, 0); + m_qbus->set_space(m_maincpu, AS_PROGRAM); + m_qbus->bevnt().set_inputline(m_maincpu, t11_device::CP2_LINE); + m_qbus->birq4().set_inputline(m_maincpu, t11_device::VEC_LINE); + QBUS_SLOT(config, "qbus" ":1", qbus_cards, nullptr); + QBUS_SLOT(config, "qbus" ":2", qbus_cards, nullptr); + QBUS_SLOT(config, "qbus" ":3", qbus_cards, nullptr); + QBUS_SLOT(config, "qbus" ":4", qbus_cards, nullptr); } /* ROM definition */ ROM_START( terak ) ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) + // QX disk bootstrap ROM_LOAD( "terak.rom", 0173000, 0x0080, CRC(fd654b8e) SHA1(273a9933b68a290c5aedcd6d69faa7b1d22c0344)) ROM_REGION( 0x2000, "kbd", 0)