Add 9122c floppy (#3647)

* hp9k_3xx: fix timer connection for /320 models

Signed-off-by: Sven Schnelle <svens@stackframe.org>

* hp9k_3xx: add HP9122C floppy

Remove HP9895 from the default configuration. 3.5" where
standard on /300 and there's almost no software on it available.
If a user really needs 8" floppy drives on /300, he can do that via
commandline.

Signed-off-by: Sven Schnelle <svens@stackframe.org>

* add Intel i8291a GPIB Talker/Listener

Required for the HP 9122C floppy, and used in many other devices.
Basic functionality was implemented to make the HP 9122C work, a few
things are still missing and will be added later. Most of the missing
things where simply not used in the HP9122C so i cannot test them.

Signed-off-by: Sven Schnelle <svens@stackframe.org>

* Add HP 9122C floppy drive

These drives where common on HP9000/300 workstations. With the current
implementation TD0's from hpmuseum can be used to boot, and initializing,
reading and writing discs in HP basic works. Tested both high and double
density media. Supported Media formats are TD0 and MFI.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
This commit is contained in:
Sven Schnelle 2018-06-10 23:43:49 +02:00 committed by R. Belmont
parent e8983ff6a3
commit c63c4e111e
8 changed files with 2033 additions and 3 deletions

View File

@ -914,6 +914,8 @@ if (BUSES["IEEE488"]~=null) then
MAME_DIR .. "src/devices/bus/ieee488/hardbox.h",
MAME_DIR .. "src/devices/bus/ieee488/shark.cpp",
MAME_DIR .. "src/devices/bus/ieee488/shark.h",
MAME_DIR .. "src/devices/bus/ieee488/hp9122c.cpp",
MAME_DIR .. "src/devices/bus/ieee488/hp9122c.h",
MAME_DIR .. "src/devices/bus/ieee488/hp9895.cpp",
MAME_DIR .. "src/devices/bus/ieee488/hp9895.h",
MAME_DIR .. "src/devices/bus/ieee488/remote488.cpp",

View File

@ -3530,3 +3530,17 @@ if (MACHINES["Z80DAISY"]~=null) then
MAME_DIR .. "src/devices/machine/z80daisy_generic.h",
}
end
---------------------------------------------------
--
--@src/devices/machine/i8291a.h,MACHINES["I8291A"] = true
---------------------------------------------------
if (MACHINES["I8291A"]~=null) then
files {
MAME_DIR .. "src/devices/machine/i8291a.cpp",
MAME_DIR .. "src/devices/machine/i8291a.h",
}
end

View File

@ -0,0 +1,363 @@
// license:BSD-3-Clause
// copyright-holders: Sven Schnelle
/*********************************************************************
hp9122c.cpp
HP9122c dual floppy disk drive
*********************************************************************/
#include "emu.h"
#include "hp9122c.h"
#include "cpu/m6809/m6809.h"
#include "machine/i8291a.h"
#include "machine/wd_fdc.h"
DEFINE_DEVICE_TYPE(HP9122C, hp9122c_device, "hp9122c", "HP9122C Dual High density disk drive")
hp9122c_device::hp9122c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, HP9122C, tag, owner, clock),
device_ieee488_interface(mconfig, *this),
m_cpu{*this , "cpu"},
m_i8291a{*this, "i8291a"},
m_fdc{*this, "mb8876"},
m_floppy{*this, "floppy%u", 0},
m_hpib_addr{*this , "HPIB address"},
m_testmode{*this, "Testmode"},
m_intsel{3},
m_fdc_irq{false},
m_i8291a_irq{false},
m_fdc_drq{false},
m_i8291a_drq{false},
m_cpuirq{false},
m_cpufirq{false},
m_index_int{false},
m_ds0{false},
m_ds1{false}
{
}
static INPUT_PORTS_START(hp9122c_port)
PORT_START("HPIB address")
PORT_CONFNAME(0x1f, 0x00 , "HPIB address")
PORT_CONFSETTING(0, "0")
PORT_CONFSETTING(1, "1")
PORT_CONFSETTING(2, "2")
PORT_CONFSETTING(3, "3")
PORT_CONFSETTING(4, "4")
PORT_CONFSETTING(5, "5")
PORT_CONFSETTING(6, "6")
PORT_CONFSETTING(7, "7")
PORT_CONFSETTING(7, "8")
PORT_CONFSETTING(7, "9")
PORT_CONFSETTING(7, "10")
PORT_CONFSETTING(7, "11")
PORT_CONFSETTING(7, "12")
PORT_CONFSETTING(7, "13")
PORT_CONFSETTING(7, "14")
PORT_CONFSETTING(7, "15")
PORT_START("Testmode")
PORT_CONFNAME(0x01, 0x00, "Testmode")
PORT_CONFSETTING(1, "Off")
PORT_CONFSETTING(0, "On")
INPUT_PORTS_END
ioport_constructor hp9122c_device::device_input_ports() const
{
return INPUT_PORTS_NAME(hp9122c_port);
}
void hp9122c_device::device_start()
{
for(auto floppy : m_floppy)
floppy->get_device()->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&hp9122c_device::index_pulse_cb, this));
}
void hp9122c_device::device_reset()
{
}
void hp9122c_device::ieee488_eoi(int state)
{
m_i8291a->eoi_w(state);
}
void hp9122c_device::ieee488_dav(int state)
{
m_i8291a->dav_w(state);
}
void hp9122c_device::ieee488_nrfd(int state)
{
m_i8291a->nrfd_w(state);
}
void hp9122c_device::ieee488_ndac(int state)
{
m_i8291a->ndac_w(state);
}
void hp9122c_device::ieee488_ifc(int state)
{
m_i8291a->ifc_w(state);
}
void hp9122c_device::ieee488_srq(int state)
{
m_i8291a->srq_w(state);
}
void hp9122c_device::ieee488_atn(int state)
{
m_i8291a->atn_w(state);
}
void hp9122c_device::ieee488_ren(int state)
{
m_i8291a->ren_w(state);
}
WRITE_LINE_MEMBER(hp9122c_device::i8291a_eoi_w)
{
m_bus->eoi_w(this , state);
}
WRITE_LINE_MEMBER(hp9122c_device::i8291a_dav_w)
{
m_bus->dav_w(this , state);
}
WRITE_LINE_MEMBER(hp9122c_device::i8291a_nrfd_w)
{
m_bus->nrfd_w(this , state);
}
WRITE_LINE_MEMBER(hp9122c_device::i8291a_ndac_w)
{
m_bus->ndac_w(this , state);
}
WRITE_LINE_MEMBER(hp9122c_device::i8291a_ifc_w)
{
m_bus->ifc_w(this , state);
}
WRITE_LINE_MEMBER(hp9122c_device::i8291a_srq_w)
{
m_bus->srq_w(this , state);
}
WRITE_LINE_MEMBER(hp9122c_device::i8291a_atn_w)
{
m_bus->atn_w(this , state);
}
WRITE_LINE_MEMBER(hp9122c_device::i8291a_ren_w)
{
m_bus->ren_w(this , state);
}
WRITE_LINE_MEMBER(hp9122c_device::i8291a_int_w)
{
m_i8291a_irq = state;
update_intsel();
}
WRITE_LINE_MEMBER(hp9122c_device::i8291a_dreq_w)
{
m_i8291a_drq = state;
update_intsel();
}
WRITE_LINE_MEMBER(hp9122c_device::fdc_intrq_w)
{
m_fdc_irq = state;
update_intsel();
}
WRITE_LINE_MEMBER(hp9122c_device::fdc_drq_w)
{
m_fdc_drq = state;
update_intsel();
}
void hp9122c_device::update_intsel()
{
bool irq = false, firq = false;
switch(m_intsel & 3) {
case 0:
/* fdc int connected */
irq = m_fdc_drq;
firq = m_fdc_irq;
break;
case 1:
/* i8291a ints connected */
irq = m_i8291a_drq;
firq = m_i8291a_irq;
break;
case 2:
irq = m_index_int;
firq = false;
break;
case 3:
irq = false;
firq = false;
break;
}
if (m_cpufirq != firq)
m_cpu->set_input_line(M6809_FIRQ_LINE, firq ? ASSERT_LINE : CLEAR_LINE);
if (m_cpuirq != irq)
m_cpu->set_input_line(M6809_IRQ_LINE, irq ? ASSERT_LINE : CLEAR_LINE);
m_cpuirq = irq;
m_cpufirq = firq;
}
READ8_MEMBER(hp9122c_device::i8291a_dio_r)
{
return m_bus->read_dio();
}
WRITE8_MEMBER(hp9122c_device::i8291a_dio_w)
{
m_bus->dio_w(this , data);
}
READ8_MEMBER(hp9122c_device::status_r)
{
uint8_t ret = REG_STATUS_DUAL|REG_STATUS_DISKCHG;
auto addr = m_hpib_addr->read();
if (!m_testmode->read())
ret |= 0x10;
ret |= ((addr & 0x08) << 3) | (addr & 0x07);
floppy_image_device *floppy = nullptr;
if (m_ds0)
floppy = m_floppy[0]->get_device();
if (m_ds1)
floppy = m_floppy[1]->get_device();
if (floppy) {
auto variant = floppy->get_variant();
if (variant == floppy_image::DSDD || variant == floppy_image::SSDD)
ret |= REG_STATUS_LOW_DENSITY;
}
return ret;
}
WRITE8_MEMBER(hp9122c_device::cmd_w)
{
auto floppy0 = m_floppy[0]->get_device();
auto floppy1 = m_floppy[1]->get_device();
m_ds0 = !(data & REG_CNTL_DS0) && floppy0;
m_ds1 = !(data & REG_CNTL_DS1) && floppy1;
if (m_ds0) {
floppy0->mon_w(0);
floppy0->ss_w(!!!(data & REG_CNTL_HEADSEL));
m_fdc->set_floppy(floppy0);
} else if (m_ds1) {
floppy1->mon_w(0);
floppy1->ss_w(!!!(data & REG_CNTL_HEADSEL));
m_fdc->set_floppy(floppy1);
}
if (data & REG_CNTL_CLOCK_SEL)
m_fdc->set_clock(XTAL(8'000'000)/4);
else
m_fdc->set_clock(XTAL(8'000'000)/8);
m_intsel = ((data & REG_CNTL_INTSEL0) >> 7) | ((data & REG_CNTL_INTSEL1) >> 2);
update_intsel();
}
void hp9122c_device::index_pulse_cb(floppy_image_device *floppy, int state)
{
m_fdc->index_callback(floppy, state);
if (state)
m_index_int = true;
update_intsel();
}
WRITE8_MEMBER(hp9122c_device::clridx_w)
{
m_index_int = false;
update_intsel();
}
ROM_START(hp9122c)
ROM_REGION(0x10000 , "cpu" , 0)
ROM_LOAD("09122-15515.bin" , 0xc000, 0x4000 , CRC(d385e488) SHA1(93b2015037d76cc68b6252df03d6f184104605b9))
ROM_END
static void hp9122c_floppies(device_slot_interface &device)
{
device.option_add("35dd" , FLOPPY_35_DD);
device.option_add("35hd" , FLOPPY_35_HD);
}
static const floppy_format_type hp9122c_floppy_formats[] = {
FLOPPY_MFI_FORMAT,
FLOPPY_TD0_FORMAT,
nullptr
};
const tiny_rom_entry *hp9122c_device::device_rom_region() const
{
return ROM_NAME(hp9122c);
}
void hp9122c_device::cpu_map(address_map &map)
{
map(0x0000, 0x0800).ram();
map(0x2000, 0x2003).rw(m_fdc, FUNC(mb8876_device::read), FUNC(mb8876_device::write)).mirror(0x1ff4);
map(0x4000, 0x4007).m("i8291a", FUNC(i8291a_device::map)).mirror(0x1ff8);
map(0x6000, 0x7fff).rw(FUNC(hp9122c_device::status_r), FUNC(hp9122c_device::cmd_w));
map(0x8000, 0x8001).w(FUNC(hp9122c_device::clridx_w));
map(0xc000, 0xffff).rom();
}
MACHINE_CONFIG_START(hp9122c_device::device_add_mconfig)
MCFG_DEVICE_ADD("cpu" , MC6809 , XTAL(8'000'000))
MCFG_DEVICE_PROGRAM_MAP(cpu_map)
// without this flag, 'DMA' transfer via SYNC instruction
// will not work
MCFG_QUANTUM_PERFECT_CPU("cpu")
MCFG_DEVICE_ADD("mb8876", MB8876, 8_MHz_XTAL / 4)
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(*this, hp9122c_device, fdc_intrq_w))
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(*this,hp9122c_device, fdc_drq_w))
MCFG_DEVICE_ADD("i8291a", I8291A, XTAL(2'000'000))
MCFG_I8291A_EOI_WRITE_CB(WRITELINE(*this, hp9122c_device, i8291a_eoi_w))
MCFG_I8291A_DAV_WRITE_CB(WRITELINE(*this, hp9122c_device, i8291a_dav_w))
MCFG_I8291A_NRFD_WRITE_CB(WRITELINE(*this, hp9122c_device, i8291a_nrfd_w))
MCFG_I8291A_NDAC_WRITE_CB(WRITELINE(*this, hp9122c_device, i8291a_ndac_w))
MCFG_I8291A_SRQ_WRITE_CB(WRITELINE(*this, hp9122c_device, i8291a_srq_w))
MCFG_I8291A_DIO_WRITE_CB(WRITE8(*this, hp9122c_device, i8291a_dio_w))
MCFG_I8291A_DIO_READ_CB(READ8(*this, hp9122c_device, i8291a_dio_r))
MCFG_I8291A_INT_WRITE_CB(WRITELINE(*this, hp9122c_device, i8291a_int_w))
MCFG_I8291A_DREQ_WRITE_CB(WRITELINE(*this, hp9122c_device, i8291a_dreq_w))
MCFG_FLOPPY_DRIVE_ADD("floppy0" , hp9122c_floppies , "35hd" , hp9122c_floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_SLOT_FIXED(true)
MCFG_FLOPPY_DRIVE_ADD("floppy1" , hp9122c_floppies , "35hd" , hp9122c_floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_SLOT_FIXED(true)
MACHINE_CONFIG_END

View File

@ -0,0 +1,151 @@
// license:BSD-3-Clause
// copyright-holders: Sven Schnelle
/*********************************************************************
hp9122c.h
HP9122C floppy/hard disk drive
*********************************************************************/
#ifndef MAME_BUS_IEEE488_HP9122C_H
#define MAME_BUS_IEEE488_HP9122C_H
#pragma once
#include "ieee488.h"
#include "cpu/m6809/m6809.h"
#include "machine/i8291a.h"
#include "machine/wd_fdc.h"
#include "imagedev/floppy.h"
#include "machine/fdc_pll.h"
class hp9122c_device : public device_t,
public device_ieee488_interface
{
public:
// construction/destruction
hp9122c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void device_start() override;
virtual void device_reset() override;
// device-level overrides
virtual ioport_constructor device_input_ports() const override;
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
// device_ieee488_interface overrides
virtual void ieee488_eoi(int state) override;
virtual void ieee488_dav(int state) override;
virtual void ieee488_nrfd(int state) override;
virtual void ieee488_ndac(int state) override;
virtual void ieee488_ifc(int state) override;
virtual void ieee488_srq(int state) override;
virtual void ieee488_atn(int state) override;
virtual void ieee488_ren(int state) override;
private:
/* Control register bits:
* 0 - Head select
* 1 - unused
* 2 - FDC Clock selector - 0 - 1Mhz, 1 - 2Mhz
* 3 - IntSel1
* 4 - DS1#
* 5 - DS0#
* 6 - LED
* 7 - IntSel0
*
* Intsel:
* * - FIRQ IRQ
* 0 - FDCIRQ FDCOrg
* 1 - HPIBINT HPIBDReq
* 2 - GND IndexInt
* 3 - GND GND
*/
constexpr static int REG_CNTL_HEADSEL = (1 << 0);
constexpr static int REG_CNTL_CLOCK_SEL = (1 << 2);
constexpr static int REG_CNTL_INTSEL1 = (1 << 3);
constexpr static int REG_CNTL_DS1 = (1 << 4);
constexpr static int REG_CNTL_DS0 = (1 << 5);
constexpr static int REG_CNTL_LED = ( 1 << 6);
constexpr static int REG_CNTL_INTSEL0 = (1 << 7);
/* Status register bits:
* 0 - Addr0
* 1 - Addr1
* 2 - Addr2
* 3 - Dual(H)/Single(L)
* 4 - T(L)
* 5 - Diskchg#
* 6 - Addr3
* 7 - density indicatior: H - DD, L - HD
*/
constexpr static int REG_STATUS_DUAL = (1 << 3);
constexpr static int REG_STATUS_TEST = (1 << 4);
constexpr static int REG_STATUS_DISKCHG = (1 << 5);
constexpr static int REG_STATUS_LOW_DENSITY = (1 << 7);
DECLARE_WRITE_LINE_MEMBER(i8291a_eoi_w);
DECLARE_WRITE_LINE_MEMBER(i8291a_dav_w);
DECLARE_WRITE_LINE_MEMBER(i8291a_nrfd_w);
DECLARE_WRITE_LINE_MEMBER(i8291a_ndac_w);
DECLARE_WRITE_LINE_MEMBER(i8291a_ifc_w);
DECLARE_WRITE_LINE_MEMBER(i8291a_srq_w);
DECLARE_WRITE_LINE_MEMBER(i8291a_atn_w);
DECLARE_WRITE_LINE_MEMBER(i8291a_ren_w);
DECLARE_READ8_MEMBER(i8291a_dio_r);
DECLARE_WRITE8_MEMBER(i8291a_dio_w);
DECLARE_WRITE_LINE_MEMBER(i8291a_int_w);
DECLARE_WRITE_LINE_MEMBER(i8291a_dreq_w);
DECLARE_WRITE_LINE_MEMBER(fdc_intrq_w);
DECLARE_WRITE_LINE_MEMBER(fdc_drq_w);
DECLARE_WRITE8_MEMBER(cmd_w);
DECLARE_READ8_MEMBER(status_r);
DECLARE_WRITE8_MEMBER(clridx_w);
// Floppy drive interface
DECLARE_READ8_MEMBER(fdc_read);
DECLARE_WRITE8_MEMBER(fdc_write);
void cpu_map(address_map &map);
required_device<cpu_device> m_cpu;
required_device<i8291a_device> m_i8291a;
required_device<mb8876_device> m_fdc;
required_device_array<floppy_connector, 2> m_floppy;
required_ioport m_hpib_addr;
required_ioport m_testmode;
void index_pulse_cb(floppy_image_device *floppy, int state);
int m_intsel;
void update_intsel(void);
bool m_fdc_irq;
bool m_i8291a_irq;
bool m_fdc_drq;
bool m_i8291a_drq;
bool m_cpuirq;
bool m_cpufirq;
bool m_index_int;
bool m_ds0;
bool m_ds1;
};
// device type definition
DECLARE_DEVICE_TYPE(HP9122C, hp9122c_device)
#endif // MAME_BUS_IEEE488_HP9122C_H

View File

@ -423,10 +423,12 @@ void cbm_ieee488_devices(device_slot_interface &device)
//-------------------------------------------------
// slot devices
#include "hp9122c.h"
#include "hp9895.h"
void hp_ieee488_devices(device_slot_interface &device)
{
device.option_add("hp9122c", HP9122C);
device.option_add("hp9895", HP9895);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,415 @@
// license:BSD-3-Clause
// copyright-holders: Sven Schnelle
/*********************************************************************
i8291a.h
I8291A GPIB controller
*********************************************************************/
#ifndef MAME_MACHINE_I8291A_H
#define MAME_MACHINE_I8291A_H
#pragma once
#define MCFG_I8291A_INT_WRITE_CB(_write) \
downcast<i8291a_device &>(*device).set_int_write_cb(DEVCB_##_write);
#define MCFG_I8291A_DREQ_WRITE_CB(_write) \
downcast<i8291a_device &>(*device).set_dreq_write_cb(DEVCB_##_write);
#define MCFG_I8291A_TRIG_WRITE_CB(_write) \
downcast<i8291a_device &>(*device).set_trig_write_cb(DEVCB_##_write);
#define MCFG_I8291A_DIO_READ_CB(_read) \
downcast<i8291a_device &>(*device).set_dio_read_cb(DEVCB_##_read);
#define MCFG_I8291A_DIO_WRITE_CB(_write) \
downcast<i8291a_device &>(*device).set_dio_write_cb(DEVCB_##_write);
#define MCFG_I8291A_EOI_WRITE_CB(_write) \
downcast<i8291a_device &>(*device).set_eoi_write_cb(DEVCB_##_write);
#define MCFG_I8291A_DAV_WRITE_CB(_write) \
downcast<i8291a_device &>(*device).set_dav_write_cb(DEVCB_##_write);
#define MCFG_I8291A_NRFD_WRITE_CB(_write) \
downcast<i8291a_device &>(*device).set_nrfd_write_cb(DEVCB_##_write);
#define MCFG_I8291A_NDAC_WRITE_CB(_write) \
downcast<i8291a_device &>(*device).set_ndac_write_cb(DEVCB_##_write);
#define MCFG_I8291A_SRQ_WRITE_CB(_write) \
downcast<i8291a_device &>(*device).set_srq_write_cb(DEVCB_##_write);
class i8291a_device : public device_t
{
public:
// construction/destruction
i8291a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <class Object> devcb_base& set_int_write_cb(Object &&cb)
{ return m_int_write_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base& set_dreq_write_cb(Object &&cb)
{ return m_dreq_write_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base& set_trig_write_cb(Object &&cb)
{ return m_trig_write_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base& set_eoi_write_cb(Object &&cb)
{ return m_eoi_write_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base& set_dav_write_cb(Object &&cb)
{ return m_dav_write_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base& set_nrfd_write_cb(Object &&cb)
{ return m_nrfd_write_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base& set_ndac_write_cb(Object &&cb)
{ return m_ndac_write_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base& set_srq_write_cb(Object &&cb)
{ return m_srq_write_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base& set_dio_write_cb(Object &&cb)
{ return m_dio_write_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base& set_dio_read_cb(Object &&cb)
{ return m_dio_read_func.set_callback(std::forward<Object>(cb)); }
// Signal inputs
DECLARE_WRITE_LINE_MEMBER(reset_w);
DECLARE_WRITE_LINE_MEMBER(dack_w);
// signal output
devcb_write_line m_int_write_func;
devcb_write_line m_dreq_write_func;
devcb_write_line m_trig_write_func;
devcb_write_line m_eoi_write_func;
devcb_write_line m_dav_write_func;
devcb_write_line m_nrfd_write_func;
devcb_write_line m_ndac_write_func;
devcb_write_line m_srq_write_func;
devcb_write8 m_dio_write_func;
devcb_read8 m_dio_read_func;
void set_dav(bool state);
void set_nrfd(bool state);
void set_ndac(bool state);
void set_eoi(bool state);
void set_srq(bool state);
// GPIB port
DECLARE_WRITE_LINE_MEMBER(eoi_w);
DECLARE_WRITE_LINE_MEMBER(dav_w);
DECLARE_WRITE_LINE_MEMBER(nrfd_w);
DECLARE_WRITE_LINE_MEMBER(ndac_w);
DECLARE_WRITE_LINE_MEMBER(ifc_w);
DECLARE_WRITE_LINE_MEMBER(srq_w);
DECLARE_WRITE_LINE_MEMBER(atn_w);
DECLARE_WRITE_LINE_MEMBER(ren_w);
DECLARE_WRITE8_MEMBER(dio_w);
// register r/w functions
DECLARE_WRITE8_MEMBER(dout_w);
DECLARE_WRITE8_MEMBER(ie1_w);
DECLARE_WRITE8_MEMBER(ie2_w);
DECLARE_WRITE8_MEMBER(spoll_mode_w);
DECLARE_WRITE8_MEMBER(addr_mode_w);
DECLARE_WRITE8_MEMBER(aux_mode_w);
DECLARE_WRITE8_MEMBER(addr01_w);
DECLARE_WRITE8_MEMBER(eos_w);
DECLARE_READ8_MEMBER(din_r);
DECLARE_READ8_MEMBER(ints1_r);
DECLARE_READ8_MEMBER(ints2_r);
DECLARE_READ8_MEMBER(spoll_stat_r);
DECLARE_READ8_MEMBER(addr_stat_r);
DECLARE_READ8_MEMBER(cpt_r);
DECLARE_READ8_MEMBER(addr0_r);
DECLARE_READ8_MEMBER(addr1_r);
void map(address_map &map);
private:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
void update_int(void);
void handle_command(void);
void run_fsm();
void run_sh_fsm();
void run_ah_fsm();
void run_dt_fsm();
void run_dc_fsm();
void run_l_fsm();
void run_lp_fsm();
void run_t_fsm();
void run_tp_fsm();
void run_tsp_fsm();
void run_sp_fsm();
void run_pp_fsm();
void run_rl_fsm();
// registers
uint8_t m_din;
uint8_t m_dout;
uint8_t m_ints1;
uint8_t m_ints2;
uint8_t m_ie1;
uint8_t m_ie2;
uint8_t m_address0;
uint8_t m_address1;
uint8_t m_eos;
uint8_t m_spoll_mode;
uint8_t m_address_mode;
uint8_t m_address_status;
uint8_t m_cpt;
uint8_t m_auxa;
uint8_t m_auxb;
bool m_atn;
bool m_ren;
bool m_nrfd;
bool m_ndac;
bool m_dav;
bool m_srq;
bool m_ifc;
bool m_eoi;
uint8_t m_dio;
bool m_nrfd_out;
bool m_ndac_out;
bool m_dav_out;
bool m_srq_out;
bool m_eoi_out;
// internal signals
bool m_pon;
bool m_rdy;
bool m_lpe;
bool m_ist;
bool m_rtl;
bool m_apt_flag;
bool m_cpt_flag;
bool m_din_flag;
bool m_nba;
bool m_pp_sense;
bool m_pp_line;
bool m_send_eoi;
static constexpr int REG_INTS1_BI = (1 << 0);
static constexpr int REG_INTS1_BO = (1 << 1);
static constexpr int REG_INTS1_ERR = (1 << 2);
static constexpr int REG_INTS1_DEC = (1 << 3);
static constexpr int REG_INTS1_END = (1 << 4);
static constexpr int REG_INTS1_GET = (1 << 5);
static constexpr int REG_INTS1_APT = (1 << 6);
static constexpr int REG_INTS1_CPT = (1 << 7);
static constexpr int REG_INTS2_ADSC = (1 << 0);
static constexpr int REG_INTS2_REMC = (1 << 1);
static constexpr int REG_INTS2_LLOC = (1 << 2);
static constexpr int REG_INTS2_SPC = (1 << 3);
static constexpr int REG_INTS2_REM = (1 << 4);
static constexpr int REG_INTS2_LLO = (1 << 5);
static constexpr int REG_INTS2_SPAS = (1 << 6);
static constexpr int REG_INTS2_INT = (1 << 7);
static constexpr int REG_IE2_DMAI = (1 << 4);
static constexpr int REG_IE2_DMAO = (1 << 5);
static constexpr int REG_ADDRESS01_ARS = (1 << 7);
static constexpr int REG_ADDRESS0_INT = (1 << 7);
static constexpr int REG_ADDRESS_DT = (1 << 6);
static constexpr int REG_ADDRESS_DL = (1 << 5);
static constexpr int REG_ADDRESS_STATUS_MJMN = 1 << 0;
static constexpr int REG_ADDRESS_STATUS_TA = 1 << 1;
static constexpr int REG_ADDRESS_STATUS_LA = 1 << 2;
static constexpr int REG_ADDRESS_STATUS_TPAS = 1 << 3;
static constexpr int REG_ADDRESS_STATUS_LPAS = 1 << 4;
static constexpr int REG_ADDRESS_STATUS_EOI = 1 << 5;
static constexpr int REG_ADDRESS_STATUS_LON = 1 << 6;
static constexpr int REG_ADDRESS_STATUS_TON = 1 << 7;
static constexpr int REG_AUXB_CPT_ENABLE = 1 << 0;
static constexpr int REG_AUXB_EOI_SPAS_ENABLE = 1 << 1;
static constexpr int REG_AUXB_HS_TRANSFER = 1 << 2;
static constexpr int REG_AUXB_INT_ACTIVE_LOW = 1 << 3;
static constexpr int REG_AUXB_RFD_HOLDOFF_GET_DEC = 1 << 4;
static constexpr int REG_AUXA_RFD_HOLDOFF_DATA = 1 << 0;
static constexpr int REG_AUXA_RFD_HOLDOFF_END = 1 << 1;
static constexpr int REG_AUXA_END_ON_EOS = 1 << 2;
static constexpr int REG_AUXA_EOI_ON_EOS = 1 << 3;
static constexpr int REG_AUXA_EOS_8BIT = 1 << 4;
// AUX CMDs
static constexpr int AUXCMD_IMMEDIATE_EXEC_PON = 0;
static constexpr int AUXCMD_CLEAR_PP = 1;
static constexpr int AUXCMD_CHIP_RESET = 2;
static constexpr int AUXCMD_FINISH_HANDSHAKE = 3;
static constexpr int AUXCMD_TRIGGER = 4;
static constexpr int AUXCMD_CLEAR_RTL = 5;
static constexpr int AUXCMD_SEND_EOI = 6;
static constexpr int AUXCMD_NON_VALID_SA = 7;
static constexpr int AUXCMD_PON = 8;
static constexpr int AUXCMD_SET_PP = 9;
static constexpr int AUXCMD_SET_RTL = 13;
static constexpr int AUXCMD_VALID_SA = 15;
// Interface commands
// TODO: stolen from tms9914, move to common header file. PHI also defines this
static constexpr uint8_t IFCMD_MASK = 0x7f; // Mask of valid bits in if. commands
static constexpr uint8_t IFCMD_ACG_MASK = 0x70; // Mask of ACG commands
static constexpr uint8_t IFCMD_ACG_VALUE = 0x00; // Value of ACG commands
static constexpr uint8_t IFCMD_UCG_MASK = 0x70; // Mask of UCG commands
static constexpr uint8_t IFCMD_UCG_VALUE = 0x10; // Value of UCG commands
static constexpr uint8_t IFCMD_GROUP_MASK = 0x60; // Mask of group id
static constexpr uint8_t IFCMD_LAG_VALUE = 0x20; // Value of LAG commands
static constexpr uint8_t IFCMD_TAG_VALUE = 0x40; // Value of TAG commands
static constexpr uint8_t IFCMD_SCG_VALUE = 0x60; // Value of SCG commands
static constexpr uint8_t IFCMD_GTL = 0x01; // Go to local
static constexpr uint8_t IFCMD_SDC = 0x04; // Selected device clear
static constexpr uint8_t IFCMD_GET = 0x08; // Group execute trigger
static constexpr uint8_t IFCMD_TCT = 0x09; // Take control
static constexpr uint8_t IFCMD_LLO = 0x11; // Local lock-out
static constexpr uint8_t IFCMD_DCL = 0x14; // Device clear
static constexpr uint8_t IFCMD_SPE = 0x18; // Serial poll enable
static constexpr uint8_t IFCMD_SPD = 0x19; // Serial poll disable
static constexpr uint8_t IFCMD_UNL = 0x3f; // Unlisten
static constexpr uint8_t IFCMD_UNT = 0x5f; // Untalk
enum class SourceHandshake {
SIDS,
SGNS,
SDYS,
STRS
};
enum class AcceptorHandshake {
AIDS,
ANRS,
ACRS,
AWNS,
ADYS,
ACDS
};
enum class TalkerState {
TIDS,
TADS,
SPAS,
TACS
};
enum class TalkerPrimaryState {
TPIS,
TPAS
};
enum class ListenerPrimaryState {
LPIS,
LPAS
};
enum class TalkerSerialPollState {
SPIS,
SPMS
};
enum class SerialPollState {
NPRS,
SRQS,
APRS
};
enum class ListenerState {
LIDS,
LADS,
LACS
};
enum class RemoteLocalState {
LOCS,
REMS,
RWLS,
LWLS
};
enum class ParallelPollState {
PPIS,
PPSS,
PPAS
};
enum class DeviceClearState {
DCIS,
DCAS
};
enum class DeviceTriggerState {
DTIS,
DTAS
};
const char *get_state_name(AcceptorHandshake state);
const char *get_state_name(SourceHandshake state);
const char *get_state_name(TalkerState state);
const char *get_state_name(TalkerPrimaryState state);
const char *get_state_name(TalkerSerialPollState state);
const char *get_state_name(ListenerState state);
const char *get_state_name(ListenerPrimaryState state);
const char *get_state_name(DeviceClearState state);
const char *get_state_name(DeviceTriggerState state);
const char *get_state_name(ParallelPollState state);
const char *get_state_name(SerialPollState state);
const char *get_state_name(RemoteLocalState state);
template<typename T> void update_state(T &name, T state, int timeout = 0)
{
if (name != state) {
m_state_changed = true;
//logerror("%s: %s -> %s\n", __FUNCTION__,
// get_state_name(name),
// get_state_name(state));
name = state;
}
}
SourceHandshake m_sh_state;
AcceptorHandshake m_ah_state;
TalkerState m_t_state;
TalkerPrimaryState m_tp_state;
TalkerSerialPollState m_tsp_state;
ListenerState m_l_state;
ListenerPrimaryState m_lp_state;
RemoteLocalState m_rl_state;
SerialPollState m_sp_state;
ParallelPollState m_pp_state;
DeviceClearState m_dc_state;
DeviceTriggerState m_dt_state;
bool m_state_changed;
bool m_ignore_ext_signals;
bool m_intr_out;
bool m_dreq_out;
};
// device type definition
DECLARE_DEVICE_TYPE(I8291A, i8291a_device)
#endif // MAME_MACHINE_I8291A_H

View File

@ -479,7 +479,7 @@ MACHINE_CONFIG_START(hp9k3xx_state::hp9k310)
MCFG_TMS9914_ATN_WRITE_CB(WRITELINE(IEEE488_TAG, ieee488_device, atn_w))
MCFG_TMS9914_REN_WRITE_CB(WRITELINE(IEEE488_TAG, ieee488_device, ren_w))
MCFG_IEEE488_SLOT_ADD("ieee0", 0, hp_ieee488_devices, "hp9895")
MCFG_IEEE488_SLOT_ADD("ieee0", 0, hp_ieee488_devices, "hp9122c")
MCFG_IEEE488_SLOT_ADD("ieee_rem", 0, remote488_devices, nullptr)
MCFG_IEEE488_BUS_ADD()
@ -509,7 +509,8 @@ MACHINE_CONFIG_START(hp9k3xx_state::hp9k320)
MCFG_HP_HIL_SLOT_ADD(MLC_TAG, "hil1", hp_hil_devices, "hp_46021a")
MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 250000) // from oscillator module next to the 6840
MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f)
MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 0.0f, 250000.0f)
MCFG_PTM6840_O3_CB(WRITELINE(PTM6840_TAG, ptm6840_device , set_c2))
SPEAKER(config, "mono").front_center();
MCFG_DEVICE_ADD(SN76494_TAG, SN76494, SN76494_CLOCK)
@ -534,7 +535,7 @@ MACHINE_CONFIG_START(hp9k3xx_state::hp9k320)
MCFG_TMS9914_ATN_WRITE_CB(WRITELINE(IEEE488_TAG, ieee488_device, atn_w))
MCFG_TMS9914_REN_WRITE_CB(WRITELINE(IEEE488_TAG, ieee488_device, ren_w))
MCFG_IEEE488_SLOT_ADD("ieee0", 0, hp_ieee488_devices, "hp9895")
MCFG_IEEE488_SLOT_ADD("ieee0", 0, hp_ieee488_devices, "hp9122c")
MCFG_IEEE488_SLOT_ADD("ieee_rem", 0, remote488_devices, nullptr)
MCFG_IEEE488_BUS_ADD()