From 972703281dae54715b2d1f59f7b9fea5b8f5e77a Mon Sep 17 00:00:00 2001 From: Sven Schnelle <41547105+svenschnelle@users.noreply.github.com> Date: Sat, 25 Mar 2023 04:35:18 +0100 Subject: bus/ISA: Added HP82321A BASIC Language coprocessor (#10926) * emu: add defer_access() method, which is useful for keeping the cpu in a loop restarting the current instruction to emulate waitstates. * add HP82321A Basic Language Coprocessor This adds support for the HP82321A Basic language coprocessor, which emulates a HP9816 system with a 68K cpu. See http://www.hpmuseum.net/display_item.php?hw=681 for more details and software to run on this card. --- scripts/src/bus.lua | 1 + src/devices/bus/isa/hpblp.cpp | 552 ++++++++++++++++++++++++++++++++++++++ src/devices/bus/isa/hpblp.h | 95 +++++++ src/devices/bus/isa/isa_cards.cpp | 2 + src/emu/devcpu.cpp | 5 + src/emu/devcpu.h | 1 + 6 files changed, 656 insertions(+) create mode 100644 src/devices/bus/isa/hpblp.cpp create mode 100644 src/devices/bus/isa/hpblp.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 2d083d46f75..d5658030f0b 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -1783,6 +1783,7 @@ if (BUSES["ISA"]~=null) then MAME_DIR .. "src/devices/bus/isa/lrk330.h", MAME_DIR .. "src/devices/bus/isa/opus100pm.cpp", MAME_DIR .. "src/devices/bus/isa/opus100pm.h", + MAME_DIR .. "src/devices/bus/isa/hpblp.cpp", } end diff --git a/src/devices/bus/isa/hpblp.cpp b/src/devices/bus/isa/hpblp.cpp new file mode 100644 index 00000000000..d9571d7ed02 --- /dev/null +++ b/src/devices/bus/isa/hpblp.cpp @@ -0,0 +1,552 @@ +// license:BSD-3-Clause +// copyright-holders:Sven Schnelle +/*************************************************************************** + + HP Basic Language Coprocessor (82321A) + +***************************************************************************/ + +#include "emu.h" +#include "bus/isa/isa.h" +#include "bus/ieee488/ieee488.h" +#include "bus/hp_dio/hp_dio.h" +#include "cpu/m68000/m68000.h" +#include "machine/tms9914.h" +#include "hpblp.h" +#include "logmacro.h" + +#define BLP_TAG "blpcpu" +#define TMS_TAG "tms9914" + +DEFINE_DEVICE_TYPE(HPBLP, isa8_hpblp_device, "hpblp", "HP Basic Language Coprocessor") + +static INPUT_PORTS_START(hpblp) + PORT_START("BLPPORT") + PORT_DIPNAME(3, 0, "IO Address") PORT_DIPLOCATION("SW2:0,1") + PORT_DIPSETTING(0, "250h-257h") + PORT_DIPSETTING(1, "280h-287h") + PORT_DIPSETTING(2, "330h-337h") + PORT_DIPSETTING(3, "390h-397h") + + PORT_START("BLPIRQ") + PORT_DIPNAME(7, 3, "Interrupt") PORT_DIPLOCATION("SW3:0,1,2") + PORT_DIPSETTING(0x0, "IRQ 3") + PORT_DIPSETTING(0x1, "IRQ 4") + PORT_DIPSETTING(0x2, "IRQ 5") + PORT_DIPSETTING(0x3, "IRQ 7") + PORT_DIPSETTING(0x4, "IRQ 9") +INPUT_PORTS_END + +ioport_constructor isa8_hpblp_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(hpblp); +} + + +isa8_hpblp_device::isa8_hpblp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, HPBLP, tag, owner, clock), + device_isa8_card_interface(mconfig, *this), + m_maincpu(*this, BLP_TAG), + m_tms9914(*this, TMS_TAG), + m_ieee488(*this, IEEE488_TAG), + m_timer_10ms(nullptr), + m_reset(false) +{ +} + +void isa8_hpblp_device::device_add_mconfig(machine_config &config) +{ + M68000(config, m_maincpu, 16_MHz_XTAL / 2); + m_maincpu->set_addrmap(AS_PROGRAM, &isa8_hpblp_device::m68map); + + TMS9914(config, m_tms9914, XTAL(5'000'000)); + m_tms9914->eoi_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_eoi_w)); + m_tms9914->dav_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dav_w)); + m_tms9914->nrfd_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_nrfd_w)); + m_tms9914->ndac_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ndac_w)); + m_tms9914->ifc_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ifc_w)); + m_tms9914->srq_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_srq_w)); + m_tms9914->atn_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_atn_w)); + m_tms9914->ren_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ren_w)); + m_tms9914->dio_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dio_w)); + m_tms9914->dio_read_cb().set(IEEE488_TAG, FUNC(ieee488_device::dio_r)); + m_tms9914->dio_read_cb().set(IEEE488_TAG, FUNC(ieee488_device::dio_r)); + m_tms9914->dio_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dio_w)); + m_tms9914->int_write_cb().set(FUNC(isa8_hpblp_device::gpib_irq)); + + IEEE488(config, m_ieee488, 0); + m_ieee488->eoi_callback().set(m_tms9914, FUNC(tms9914_device::eoi_w)); + m_ieee488->dav_callback().set(m_tms9914, FUNC(tms9914_device::dav_w)); + m_ieee488->nrfd_callback().set(m_tms9914, FUNC(tms9914_device::nrfd_w)); + m_ieee488->ndac_callback().set(m_tms9914, FUNC(tms9914_device::ndac_w)); + m_ieee488->ifc_callback().set(m_tms9914, FUNC(tms9914_device::ifc_w)); + m_ieee488->srq_callback().set(m_tms9914, FUNC(tms9914_device::srq_w)); + m_ieee488->atn_callback().set(m_tms9914, FUNC(tms9914_device::atn_w)); + m_ieee488->ren_callback().set(m_tms9914, FUNC(tms9914_device::ren_w)); + + ieee488_slot_device &slot0(IEEE488_SLOT(config, "ieee0", 0)); + hp_ieee488_devices(slot0); + slot0.set_default_option("hp9122c"); + + bus::hp_dio::dio16_device &dio16(DIO16(config, "diobus", 0)); + dio16.set_program_space(m_maincpu, AS_PROGRAM); + m_maincpu->reset_cb().set(dio16, FUNC(bus::hp_dio::dio16_device::reset_in)); + + dio16.irq1_out_cb().set_inputline(m_maincpu, M68K_IRQ_1); + dio16.irq2_out_cb().set_inputline(m_maincpu, M68K_IRQ_2); + dio16.irq3_out_cb().set_inputline(m_maincpu, M68K_IRQ_3); + dio16.irq4_out_cb().set_inputline(m_maincpu, M68K_IRQ_4); + dio16.irq5_out_cb().set_inputline(m_maincpu, M68K_IRQ_5); + dio16.irq6_out_cb().set_inputline(m_maincpu, M68K_IRQ_6); + dio16.irq7_out_cb().set_inputline(m_maincpu, M68K_IRQ_7); + + DIO32_SLOT(config, "sl0", 0, "diobus", dio16_cards, nullptr, false); + DIO32_SLOT(config, "sl1", 0, "diobus", dio16_cards, nullptr, false); + +} + +offs_t isa8_hpblp_device::get_bus_address(offs_t offset, uint16_t mem_mask) +{ + if (mem_mask == 0xff) + offset++; + return offset; +} + +bool isa8_hpblp_device::forward_to_host(offs_t offset) +{ + if (offset >= 0x200000 && offset <= 0x2fffff) + return true; + if (offset >= 0x420000 && offset <= 0x42ffff) + return true; + if (offset >= 0x510000 && offset <= 0x51ffff) + return true; + if (offset >= 0x520000 && offset <= 0x52ffff) + return true; + if (offset >= 0x538000 && offset <= 0x53ffff) + return true; + if (offset >= 0x5f2000 && offset <= 0x5f3fff) + return true; + if (offset >= 0x690000 && offset <= 0x69ffff) + return true; + if (offset >= 0x6f0000 && offset <= 0x6fffff) + return true; + if (offset >= 0x730000 && offset <= 0x73ffff) + return true; + if (offset >= 0x7a0000 && offset <= 0x7affff) + return true; + return false; +} + +uint8_t isa8_hpblp_device::status_val(offs_t offset) +{ + if (offset >= 0x200000 && offset <= 0x2fffff) + return 0x30; + if (offset >= 0x512000 && offset <= 0x517fff) + return 0x70; + if (offset >= 0x51ff00 && offset <= 0x51ffff) + return 0x50; + if (offset >= 0x538000 && offset <= 0x53ffff) + return 0xb0; + return 0xd0; +} + +uint16_t isa8_hpblp_device::bus_r(offs_t offset, uint16_t mem_mask) +{ + offset <<= 1; + + if (machine().side_effects_disabled()) + return m_bus_data; + + if (!forward_to_host(offset)) { + LOG("%s: %06x -> BERR\n", __func__, offset); + m_maincpu->trigger_bus_error(); + return 0xffff; + } + + if (m_ack_buscycle) { + m_ack_buscycle = false; + m_bus_read = false; + m_bus_address = 0; + LOG("%s: %06x %04x (%04x)\n", __func__, offset, m_bus_data, mem_mask); + return m_bus_data; + } else { + m_bus_address = get_bus_address(offset, mem_mask); + m_bus_mem_mask = mem_mask; + m_bus_read = true; + } + m_maincpu->defer_access(); + return 0xffff; +} + +void isa8_hpblp_device::bus_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + offset <<= 1; + + if (!forward_to_host(offset)) { + LOG("%s: %06x -> BERR\n", __func__, offset); + m_maincpu->trigger_bus_error(); + return; + } + + if (m_ack_buscycle) { + m_ack_buscycle = false; + m_bus_write = false; + m_bus_address = 0; + return; + } + + if (!m_bus_write) { + m_bus_address = get_bus_address(offset, mem_mask); + m_bus_mem_mask = mem_mask; + m_bus_write = true; + m_bus_data = data; + } + m_maincpu->defer_access(); +} + +void isa8_hpblp_device::gpib_w(offs_t offset, uint16_t data) +{ + if (offset & 0x08) { + m_tms9914->write(offset & 0x07, data); + return; + } + + switch (offset) { + case 0: + m_tms9914->reset(); + break; + + case 1: + if (data >> 8 == 0) + m_gpib_reg1 = 0x84; + else if (data >> 8 == 1) + m_gpib_reg1 = 0xbf; + else + m_gpib_reg1 = 0xbe; + break; + default: + break; + } +} + +uint16_t isa8_hpblp_device::gpib_r(offs_t offset) +{ + uint8_t data = 0xff; + + if (offset & 0x8) + return m_tms9914->read(offset & 0x07); + + switch(offset) { + case 0: /* ID */ + data = 0x31; + break; + case 1: + /* Int control */ + data = m_gpib_reg1; + break; + case 2: + /* Address */ + data = 0xbe; + break; + default: + break; + } + return data; +} + +void isa8_hpblp_device::update_gpib_irq() +{ + if ((m_gpib_reg1 & 0x40) && (m_gpib_reg1 & 0x80)) + m_maincpu->set_input_line(M68K_IRQ_3, ASSERT_LINE); + else + m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE); +} + +WRITE_LINE_MEMBER(isa8_hpblp_device::gpib_irq) +{ + if (state) { + m_gpib_reg1 |= 0x40; + } else { + m_gpib_reg1 &= ~0x40; + } + update_gpib_irq(); +} + +void isa8_hpblp_device::m68map(address_map &map) +{ + map(0x000000, 0xffffff).rw(FUNC(isa8_hpblp_device::bus_r), FUNC(isa8_hpblp_device::bus_w)); + map(0x000000, 0x00ffff).rom().nopw(); + map(0x470000, 0x47001f).mirror(0x00ffe0).rw(FUNC(isa8_hpblp_device::gpib_r), FUNC(isa8_hpblp_device::gpib_w)); + map(0xc00000, 0xffffff).ram(); +} + +WRITE_LINE_MEMBER(isa8_hpblp_device::hpblp_interrupt) +{ + switch(m_irq) { + case 0: + m_isa->irq3_w(state); + break; + case 1: + m_isa->irq4_w(state); + break; + case 2: + m_isa->irq5_w(state); + break; + case 3: + m_isa->irq7_w(state); + break; + case 4: + m_isa->irq2_w(state); + break; + default: + break; + } +} + +uint8_t isa8_hpblp_device::get_bus_address_partial(int shift) +{ + offs_t addr; + + // The value read from the bus address registers (isa reg 2,3,4) is + // either the address during a waiting 68k bus cycle, or, if the + // processor is running the current bus address which might be a data + // read/write or program fetch. The DOS software checks whether these + // register changes during normal operation. Therefore just invert + // the address on every read if the CPU is not waiting for the host. + + if (!m_bus_read && !m_bus_write) + m_bus_address ^= 0xffffff; + + addr = m_bus_address; + return (addr >> shift) & 0xff; +} + +uint8_t isa8_hpblp_device::addrl_r(offs_t offset) +{ + return get_bus_address_partial(0); +} + +uint8_t isa8_hpblp_device::addrm_r(offs_t offset) +{ + return get_bus_address_partial(8); +} + +uint8_t isa8_hpblp_device::addrh_r(offs_t offset) +{ + return get_bus_address_partial(16); +} + +uint8_t isa8_hpblp_device::datal_r(offs_t offset) +{ + return m_bus_data & 0xff; +} + +uint8_t isa8_hpblp_device::datah_r(offs_t offset) +{ + return m_bus_data >> 8; +} + +void isa8_hpblp_device::datal_w(offs_t offset, uint8_t data) +{ + m_bus_data &= ~0xff; + m_bus_data |= data; +} + +void isa8_hpblp_device::datah_w(offs_t offset, uint8_t data) +{ + m_bus_data &= ~0xff00; + m_bus_data |= (data << 8); +} + +uint8_t isa8_hpblp_device::status_r(offs_t offset) +{ + uint8_t ret; + + // bits: + // 7-5: type of buscycle (exact encoding unknown) + // 4 - INT status + // 2 - CPU RW# + + if (m_bus_read || m_bus_write) + ret = status_val(m_bus_address); + else + ret = 0xe4; + + if (m_bus_read) + ret |= 0x04; + + if (!m_irq_state) + ret |= 0x10; + return ret; +} + +void isa8_hpblp_device::irq_w(offs_t offset, uint8_t data) +{ + hpblp_interrupt(1); +} + +uint8_t isa8_hpblp_device::reg5_r(offs_t offset) +{ + // state bits: + // 3-0: OS running + // 0: BOOTROM + // 1: HPBASIC + // 2: PASCAL + // 4: Is a 82324A card + return m_reg5; +} + +uint8_t isa8_hpblp_device::reg6_r(offs_t offset) +{ + return m_reg6; +} + +void isa8_hpblp_device::reg2_w(offs_t offset, uint8_t data) +{ + // bit 0 - CPU RESET# line + m_reset = data & 1; + if (m_reset) + device_reset(); +} + +// reg 3: force BERR# on current bus cycle +void isa8_hpblp_device::reg3_w(offs_t offset, uint8_t data) +{ + m_ack_buscycle = false; + m_bus_read = false; + m_bus_write = false; + m_maincpu->trigger_bus_error(); + machine().scheduler().synchronize(); +} + +// reg 4: clear pending 10ms timer interrupt to host +void isa8_hpblp_device::reg4_w(offs_t offset, uint8_t data) +{ + hpblp_interrupt(0); +} + +// reg 5: OS status +void isa8_hpblp_device::reg5_w(offs_t offset, uint8_t data) +{ + m_reg5 = data; +} + +// reg 6: seems to be used to trigger interrupts on the 68k. +// Only seen with keyboard irqs so far. +void isa8_hpblp_device::reg6_w(offs_t offset, uint8_t data) +{ + // bit 2-0: IPL? + if (data == 6) { + m_maincpu->set_input_line(M68K_IRQ_1, ASSERT_LINE); + } else { + m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); + } + m_reg6 = data; +} + +// reg 7: acknowledge current 68k bus cycle +void isa8_hpblp_device::reg7_w(address_space &space, offs_t offset, uint8_t data) +{ + if (m_reset) { + // DOS software write to this reg during reset, so we need to ignore + // this write in order to not acknowledge the first bus cycle early + return; + } + + m_bus_read = false; + m_bus_write = false; + m_ack_buscycle = true; + // It looks like the DOS software assumes that the m68k is always faster starting + // the next buscycle than the PC reading the data registers. So it seems they + // "optimized" the code to skip checking the bus status registers before accessing + // the data registers during a 32 bit instruction. (which will be split into 2x 16 + // bit bus transactions by 68k. Eat all cycles to make the scheduler switch to 68k + // before the x86 CPU can read the registers again. + machine().scheduler().synchronize(); +} + +void isa8_hpblp_device::isamap(address_map &map) +{ + map(0, 0).rw(FUNC(isa8_hpblp_device::datal_r), FUNC(isa8_hpblp_device::datal_w)); + map(1, 1).rw(FUNC(isa8_hpblp_device::datah_r), FUNC(isa8_hpblp_device::datah_w)); + map(2, 2).rw(FUNC(isa8_hpblp_device::addrl_r), FUNC(isa8_hpblp_device::reg2_w)); + map(3, 3).rw(FUNC(isa8_hpblp_device::addrm_r), FUNC(isa8_hpblp_device::reg3_w)); + map(4, 4).rw(FUNC(isa8_hpblp_device::addrh_r), FUNC(isa8_hpblp_device::reg4_w)); + map(5, 5).rw(FUNC(isa8_hpblp_device::reg5_r), FUNC(isa8_hpblp_device::reg5_w)); + map(6, 6).rw(FUNC(isa8_hpblp_device::reg6_r), FUNC(isa8_hpblp_device::reg6_w)); + map(7, 7).rw(FUNC(isa8_hpblp_device::status_r), FUNC(isa8_hpblp_device::reg7_w)); +} + +TIMER_CALLBACK_MEMBER(isa8_hpblp_device::timer10ms) +{ + if (m_reg6 & 2) + hpblp_interrupt(1); + m_timer_10ms->adjust(attotime::from_msec(10)); +} + +void isa8_hpblp_device::device_start() +{ + set_isa_device(); + m_installed = false; + m_timer_10ms = timer_alloc(FUNC(isa8_hpblp_device::timer10ms), this); + m_timer_10ms->adjust(attotime::from_msec(10)); + + save_item(NAME(m_bus_address)); + save_item(NAME(m_bus_mem_mask)); + save_item(NAME(m_bus_data)); + save_item(NAME(m_gpib_reg1)); + save_item(NAME(m_reg5)); + save_item(NAME(m_reg6)); + save_item(NAME(m_ack_buscycle)); + save_item(NAME(m_bus_read)); + save_item(NAME(m_bus_write)); + save_item(NAME(m_irq_state)); + save_item(NAME(m_reset)); +} + +void isa8_hpblp_device::device_reset() +{ + uint16_t port; + + if (!m_installed) { + // MAME doesn't allow reading ioport at device_start + m_irq = ioport("BLPIRQ")->read(); + switch(ioport("BLPPORT")->read()) { + case 1: + port = 0x280; + break; + case 2: + port = 0x330; + break; + case 3: + port = 0x390; + break; + default: + port = 0x250; + break; + } + m_isa->install_device(port, port + 7, *this, &isa8_hpblp_device::isamap); + m_installed = true; + } + + m_ack_buscycle = false; + m_bus_read = false; + m_bus_write = false; + m_bus_address = 0; + m_reg5 = 0; + m_reg6 = 0; + m_maincpu->reset(); + m_gpib_reg1 = 0xbe; + m_tms9914->reset(); +} + +ROM_START(hpblp) + ROM_REGION(0x20000, BLP_TAG, 0) + ROM_LOAD16_BYTE( "1818-4576.bin", 0x000000, 0x008000, CRC(8beb6bdb) SHA1(9b620c577aea54841608d0d46f7e8077eef607c6)) + ROM_LOAD16_BYTE( "1818-4577.bin", 0x000001, 0x008000, CRC(e8a5c071) SHA1(9e13c0ef2aed6565c33795780b7102f2647cf2a0)) +ROM_END + +const tiny_rom_entry *isa8_hpblp_device::device_rom_region() const +{ + return ROM_NAME(hpblp); +} diff --git a/src/devices/bus/isa/hpblp.h b/src/devices/bus/isa/hpblp.h new file mode 100644 index 00000000000..5cc7f37eadc --- /dev/null +++ b/src/devices/bus/isa/hpblp.h @@ -0,0 +1,95 @@ +// license:BSD-3-Clause +// copyright-holders:Sven Schnelle +#ifndef MAME_BUS_ISA_HPBLP_H +#define MAME_BUS_ISA_HPBLP_H + +#pragma once + +#include "isa.h" +#include "bus/hp_dio/hp_dio.h" +#include "bus/ieee488/ieee488.h" +#include "cpu/m68000/m68000.h" +#include "machine/tms9914.h" + +class isa8_hpblp_device : + public device_t, + public device_isa8_card_interface +{ +public: + isa8_hpblp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual ioport_constructor device_input_ports() const override; + 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; +private: + // ISA part + void isamap(address_map &map); + + uint8_t datal_r(offs_t offset); + uint8_t datah_r(offs_t offset); + uint8_t status_r(offs_t offset); + uint8_t addrh_r(offs_t offset); + uint8_t addrm_r(offs_t offset); + uint8_t addrl_r(offs_t offset); + uint8_t reg5_r(offs_t offset); + uint8_t reg6_r(offs_t offset); + + void datal_w(offs_t offset, uint8_t data); + void datah_w(offs_t offset, uint8_t data); + void irq_w(offs_t offset, uint8_t data); + void reg2_w(offs_t offset, uint8_t data); + void reg3_w(offs_t offset, uint8_t data); + void reg4_w(offs_t offset, uint8_t data); + void reg5_w(offs_t offset, uint8_t data); + void reg6_w(offs_t offset, uint8_t data); + void reg7_w(address_space &space, offs_t offset, uint8_t data); + + static uint8_t status_val(offs_t offset); + + DECLARE_WRITE_LINE_MEMBER(hpblp_interrupt); + TIMER_CALLBACK_MEMBER(timer10ms); + + // M68000 part + DECLARE_WRITE_LINE_MEMBER(gpib_irq); + void m68map(address_map &map); + + uint16_t bus_r(offs_t offset, uint16_t mem_mask); + void bus_w(offs_t offset, uint16_t data, uint16_t mem_mask); + uint16_t gpib_r(offs_t offset); + void gpib_w(offs_t offset, uint16_t data); + + static offs_t get_bus_address(offs_t offset, uint16_t mem_mask); + uint8_t get_bus_address_partial(int shift); + + static bool forward_to_host(offs_t offset); + void update_gpib_irq(); + + required_device m_maincpu; + required_device m_tms9914; + required_device m_ieee488; + emu_timer *m_timer_10ms; + + uint32_t m_bus_address; + uint16_t m_bus_mem_mask; + uint16_t m_bus_data; + uint8_t m_gpib_reg1; + uint8_t m_reg5; + uint8_t m_reg6; + uint8_t m_irq; + + bool m_installed; + bool m_ack_buscycle; + bool m_bus_read; + bool m_bus_write; + bool m_irq_state; + bool m_reset; +}; + +// device type definition +DECLARE_DEVICE_TYPE(HPBLP, isa8_hpblp_device) + +#endif // MAME_BUS_ISA_HPBLP_H diff --git a/src/devices/bus/isa/isa_cards.cpp b/src/devices/bus/isa/isa_cards.cpp index 0b01c16d501..f085f7af70b 100644 --- a/src/devices/bus/isa/isa_cards.cpp +++ b/src/devices/bus/isa/isa_cards.cpp @@ -81,6 +81,7 @@ #include "pds.h" // other +#include "hpblp.h" #include "chessmdr.h" #include "chessmsr.h" #include "finalchs.h" @@ -235,4 +236,5 @@ void pc_isa16_cards(device_slot_interface &device) device.option_add("dc820b", TEKRAM_DC820B); // actually an EISA card device.option_add("omti8621", ISA16_OMTI8621); device.option_add("lrk331", LRK331); + device.option_add("hpblp", HPBLP); } diff --git a/src/emu/devcpu.cpp b/src/emu/devcpu.cpp index 6dbdd9f9fa1..1554fe5b6fc 100644 --- a/src/emu/devcpu.cpp +++ b/src/emu/devcpu.cpp @@ -59,6 +59,11 @@ bool cpu_device::cpu_is_interruptible() const return false; } +void cpu_device::defer_access(void) +{ + m_access_to_be_redone = true; + *m_icountptr = 0; +} bool cpu_device::access_before_time(u64 access_time, u64 current_time) { diff --git a/src/emu/devcpu.h b/src/emu/devcpu.h index 6b077529fb7..8c95fdeb58c 100644 --- a/src/emu/devcpu.h +++ b/src/emu/devcpu.h @@ -48,6 +48,7 @@ public: // The access has already happened, nothing to abort void access_after_delay(u32 cycles); + void defer_access(void); protected: // construction/destruction -- cgit v1.2.3