mirror of
https://github.com/mamedev/mame.git
synced 2024-11-18 10:06:19 +01:00
Merge pull request #1926 from fulivi/hp9845_dev9
HP9895 dual-floppy drive (WIP)
This commit is contained in:
commit
4cd61d1c72
10 changed files with 1993 additions and 0 deletions
|
@ -761,6 +761,8 @@ if (BUSES["IEEE488"]~=null) then
|
||||||
MAME_DIR .. "src/devices/bus/ieee488/hardbox.h",
|
MAME_DIR .. "src/devices/bus/ieee488/hardbox.h",
|
||||||
MAME_DIR .. "src/devices/bus/ieee488/shark.cpp",
|
MAME_DIR .. "src/devices/bus/ieee488/shark.cpp",
|
||||||
MAME_DIR .. "src/devices/bus/ieee488/shark.h",
|
MAME_DIR .. "src/devices/bus/ieee488/shark.h",
|
||||||
|
MAME_DIR .. "src/devices/bus/ieee488/hp9895.cpp",
|
||||||
|
MAME_DIR .. "src/devices/bus/ieee488/hp9895.h",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1928,6 +1928,18 @@ if (MACHINES["PCKEYBRD"]~=null) then
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---------------------------------------------------
|
||||||
|
--
|
||||||
|
--@src/devices/machine/phi.h,MACHINES["PHI"] = true
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
if (MACHINES["PHI"]~=null) then
|
||||||
|
files {
|
||||||
|
MAME_DIR .. "src/devices/machine/phi.cpp",
|
||||||
|
MAME_DIR .. "src/devices/machine/phi.h",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
--
|
--
|
||||||
--@src/devices/machine/pic8259.h,MACHINES["PIC8259"] = true
|
--@src/devices/machine/pic8259.h,MACHINES["PIC8259"] = true
|
||||||
|
|
|
@ -492,6 +492,7 @@ MACHINES["PCF8593"] = true
|
||||||
MACHINES["PCI"] = true
|
MACHINES["PCI"] = true
|
||||||
MACHINES["PCKEYBRD"] = true
|
MACHINES["PCKEYBRD"] = true
|
||||||
MACHINES["PDC"] = true
|
MACHINES["PDC"] = true
|
||||||
|
MACHINES["PHI"] = true
|
||||||
MACHINES["PIC8259"] = true
|
MACHINES["PIC8259"] = true
|
||||||
MACHINES["PIT68230"] = true
|
MACHINES["PIT68230"] = true
|
||||||
MACHINES["PIT8253"] = true
|
MACHINES["PIT8253"] = true
|
||||||
|
|
|
@ -132,6 +132,9 @@ READ16_MEMBER(hp98034_io_card::reg_r)
|
||||||
m_force_flg = true;
|
m_force_flg = true;
|
||||||
|
|
||||||
update_flg();
|
update_flg();
|
||||||
|
// PPU yields to let NP see FLG=0 immediately
|
||||||
|
// (horrible race conditions lurking...)
|
||||||
|
space.device().execute().yield();
|
||||||
|
|
||||||
LOG(("read R%u=%04x\n" , offset + 4 , res));
|
LOG(("read R%u=%04x\n" , offset + 4 , res));
|
||||||
return res;
|
return res;
|
||||||
|
@ -152,6 +155,9 @@ WRITE16_MEMBER(hp98034_io_card::reg_w)
|
||||||
m_force_flg = true;
|
m_force_flg = true;
|
||||||
|
|
||||||
update_flg();
|
update_flg();
|
||||||
|
// PPU yields to let NP see FLG=0 immediately
|
||||||
|
// (horrible race conditions lurking...)
|
||||||
|
space.device().execute().yield();
|
||||||
LOG(("write R%u=%04x\n" , offset + 4 , data));
|
LOG(("write R%u=%04x\n" , offset + 4 , data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,6 +362,7 @@ static MACHINE_CONFIG_FRAGMENT(hp98034)
|
||||||
MCFG_HP_NANO_READ_DC_CB(READ8(hp98034_io_card , dc_r))
|
MCFG_HP_NANO_READ_DC_CB(READ8(hp98034_io_card , dc_r))
|
||||||
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(hp98034_io_card , irq_callback)
|
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(hp98034_io_card , irq_callback)
|
||||||
|
|
||||||
|
MCFG_IEEE488_SLOT_ADD("ieee_dev" , 0 , hp_ieee488_devices , nullptr)
|
||||||
MCFG_IEEE488_BUS_ADD()
|
MCFG_IEEE488_BUS_ADD()
|
||||||
MCFG_IEEE488_IFC_CALLBACK(WRITELINE(hp98034_io_card , ieee488_ctrl_w))
|
MCFG_IEEE488_IFC_CALLBACK(WRITELINE(hp98034_io_card , ieee488_ctrl_w))
|
||||||
MCFG_IEEE488_ATN_CALLBACK(WRITELINE(hp98034_io_card , ieee488_ctrl_w))
|
MCFG_IEEE488_ATN_CALLBACK(WRITELINE(hp98034_io_card , ieee488_ctrl_w))
|
||||||
|
|
208
src/devices/bus/ieee488/hp9895.cpp
Normal file
208
src/devices/bus/ieee488/hp9895.cpp
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders: F. Ulivi
|
||||||
|
/*********************************************************************
|
||||||
|
|
||||||
|
hp9895.cpp
|
||||||
|
|
||||||
|
HP9895 floppy disk drive
|
||||||
|
|
||||||
|
Reference manual:
|
||||||
|
HP 09895-90030, feb 81, 9895A Flexible Disc Memory Service Manual
|
||||||
|
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#include "hp9895.h"
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
#define VERBOSE 1
|
||||||
|
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
const device_type HP9895 = &device_creator<hp9895_device>;
|
||||||
|
|
||||||
|
hp9895_device::hp9895_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||||
|
: device_t(mconfig, HP9895, "HP9895", tag, owner, clock, "HP9895", __FILE__),
|
||||||
|
device_ieee488_interface(mconfig, *this),
|
||||||
|
m_cpu(*this , "cpu"),
|
||||||
|
m_phi(*this , "phi")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
ioport_constructor hp9895_device::device_input_ports() const
|
||||||
|
{
|
||||||
|
// TODO: inputs=HPIB address, "S" & "W" switches, "loop" pin
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
void hp9895_device::device_start()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void hp9895_device::device_reset()
|
||||||
|
{
|
||||||
|
m_cpu_irq = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hp9895_device::ieee488_eoi(int state)
|
||||||
|
{
|
||||||
|
m_phi->eoi_w(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hp9895_device::ieee488_dav(int state)
|
||||||
|
{
|
||||||
|
m_phi->dav_w(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hp9895_device::ieee488_nrfd(int state)
|
||||||
|
{
|
||||||
|
m_phi->nrfd_w(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hp9895_device::ieee488_ndac(int state)
|
||||||
|
{
|
||||||
|
m_phi->ndac_w(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hp9895_device::ieee488_ifc(int state)
|
||||||
|
{
|
||||||
|
m_phi->ifc_w(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hp9895_device::ieee488_srq(int state)
|
||||||
|
{
|
||||||
|
m_phi->srq_w(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hp9895_device::ieee488_atn(int state)
|
||||||
|
{
|
||||||
|
m_phi->atn_w(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hp9895_device::ieee488_ren(int state)
|
||||||
|
{
|
||||||
|
m_phi->ren_w(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(hp9895_device::phi_eoi_w)
|
||||||
|
{
|
||||||
|
m_bus->eoi_w(this , state);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(hp9895_device::phi_dav_w)
|
||||||
|
{
|
||||||
|
m_bus->dav_w(this , state);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(hp9895_device::phi_nrfd_w)
|
||||||
|
{
|
||||||
|
m_bus->nrfd_w(this , state);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(hp9895_device::phi_ndac_w)
|
||||||
|
{
|
||||||
|
m_bus->ndac_w(this , state);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(hp9895_device::phi_ifc_w)
|
||||||
|
{
|
||||||
|
m_bus->ifc_w(this , state);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(hp9895_device::phi_srq_w)
|
||||||
|
{
|
||||||
|
m_bus->srq_w(this , state);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(hp9895_device::phi_atn_w)
|
||||||
|
{
|
||||||
|
m_bus->atn_w(this , state);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(hp9895_device::phi_ren_w)
|
||||||
|
{
|
||||||
|
m_bus->ren_w(this , state);
|
||||||
|
}
|
||||||
|
|
||||||
|
READ8_MEMBER(hp9895_device::phi_dio_r)
|
||||||
|
{
|
||||||
|
return m_bus->dio_r();
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(hp9895_device::phi_dio_w)
|
||||||
|
{
|
||||||
|
m_bus->dio_w(this , data);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(hp9895_device::phi_int_w)
|
||||||
|
{
|
||||||
|
m_cpu->set_input_line(INPUT_LINE_NMI , state);
|
||||||
|
}
|
||||||
|
|
||||||
|
READ8_MEMBER(hp9895_device::phi_reg_r)
|
||||||
|
{
|
||||||
|
uint16_t reg = m_phi->reg16_r(space , offset , mem_mask);
|
||||||
|
|
||||||
|
// Reading D1=1 from a register sets the Z80 IRQ line
|
||||||
|
if (BIT(reg , 14) && !m_cpu_irq) {
|
||||||
|
m_cpu_irq = true;
|
||||||
|
m_cpu->set_input_line(INPUT_LINE_IRQ0 , ASSERT_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint8_t)reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(hp9895_device::z80_m1_w)
|
||||||
|
{
|
||||||
|
// Every M1 cycle of Z80 clears the IRQ line
|
||||||
|
if (m_cpu_irq) {
|
||||||
|
m_cpu_irq = false;
|
||||||
|
m_cpu->set_input_line(INPUT_LINE_IRQ0 , CLEAR_LINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ROM_START(hp9895)
|
||||||
|
ROM_REGION(0x2000 , "cpu" , 0)
|
||||||
|
ROM_LOAD("1818-1391a.bin" , 0 , 0x2000 , CRC(b50dbfb5) SHA1(96edf9af78be75fbad2a0245b8af43958ba32752))
|
||||||
|
ROM_END
|
||||||
|
|
||||||
|
static ADDRESS_MAP_START(z80_program_map , AS_PROGRAM , 8 , hp9895_device)
|
||||||
|
ADDRESS_MAP_UNMAP_HIGH
|
||||||
|
AM_RANGE(0x0000 , 0x1fff) AM_ROM AM_REGION("cpu" , 0)
|
||||||
|
AM_RANGE(0x6000 , 0x63ff) AM_RAM
|
||||||
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
|
static ADDRESS_MAP_START(z80_io_map , AS_IO , 8 , hp9895_device)
|
||||||
|
ADDRESS_MAP_UNMAP_HIGH
|
||||||
|
ADDRESS_MAP_GLOBAL_MASK(0xff)
|
||||||
|
AM_RANGE(0x10 , 0x17) AM_DEVWRITE("phi" , phi_device , reg8_w) AM_READ(phi_reg_r)
|
||||||
|
// TODO: 60-67 range
|
||||||
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
|
static MACHINE_CONFIG_FRAGMENT(hp9895)
|
||||||
|
MCFG_CPU_ADD("cpu" , Z80 , 4000000)
|
||||||
|
MCFG_CPU_PROGRAM_MAP(z80_program_map)
|
||||||
|
MCFG_CPU_IO_MAP(z80_io_map)
|
||||||
|
MCFG_Z80_SET_REFRESH_CALLBACK(WRITE16(hp9895_device , z80_m1_w))
|
||||||
|
|
||||||
|
MCFG_DEVICE_ADD("phi" , PHI , 0)
|
||||||
|
MCFG_PHI_EOI_WRITE_CB(WRITELINE(hp9895_device , phi_eoi_w))
|
||||||
|
MCFG_PHI_DAV_WRITE_CB(WRITELINE(hp9895_device , phi_dav_w))
|
||||||
|
MCFG_PHI_NRFD_WRITE_CB(WRITELINE(hp9895_device , phi_nrfd_w))
|
||||||
|
MCFG_PHI_NDAC_WRITE_CB(WRITELINE(hp9895_device , phi_ndac_w))
|
||||||
|
MCFG_PHI_IFC_WRITE_CB(WRITELINE(hp9895_device , phi_ifc_w))
|
||||||
|
MCFG_PHI_SRQ_WRITE_CB(WRITELINE(hp9895_device , phi_srq_w))
|
||||||
|
MCFG_PHI_ATN_WRITE_CB(WRITELINE(hp9895_device , phi_atn_w))
|
||||||
|
MCFG_PHI_REN_WRITE_CB(WRITELINE(hp9895_device , phi_ren_w))
|
||||||
|
MCFG_PHI_DIO_READWRITE_CB(READ8(hp9895_device , phi_dio_r) , WRITE8(hp9895_device , phi_dio_w))
|
||||||
|
MCFG_PHI_INT_WRITE_CB(WRITELINE(hp9895_device , phi_int_w))
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
const tiny_rom_entry *hp9895_device::device_rom_region() const
|
||||||
|
{
|
||||||
|
return ROM_NAME(hp9895);
|
||||||
|
}
|
||||||
|
|
||||||
|
machine_config_constructor hp9895_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME(hp9895);
|
||||||
|
}
|
76
src/devices/bus/ieee488/hp9895.h
Normal file
76
src/devices/bus/ieee488/hp9895.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders: F. Ulivi
|
||||||
|
/*********************************************************************
|
||||||
|
|
||||||
|
hp9895.h
|
||||||
|
|
||||||
|
HP9895 floppy disk drive
|
||||||
|
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef _HP9895_H_
|
||||||
|
#define _HP9895_H_
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "ieee488.h"
|
||||||
|
#include "cpu/z80/z80.h"
|
||||||
|
#include "machine/phi.h"
|
||||||
|
|
||||||
|
class hp9895_device : public device_t,
|
||||||
|
public device_ieee488_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
hp9895_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
//virtual ioport_constructor device_input_ports() const override;
|
||||||
|
virtual void device_start() override;
|
||||||
|
virtual void device_reset() override;
|
||||||
|
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const 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;
|
||||||
|
|
||||||
|
// PHI write CBs
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(phi_eoi_w);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(phi_dav_w);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(phi_nrfd_w);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(phi_ndac_w);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(phi_ifc_w);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(phi_srq_w);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(phi_atn_w);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(phi_ren_w);
|
||||||
|
|
||||||
|
// PHI DIO r/w CBs
|
||||||
|
DECLARE_READ8_MEMBER(phi_dio_r);
|
||||||
|
DECLARE_WRITE8_MEMBER(phi_dio_w);
|
||||||
|
|
||||||
|
// PHI IRQ/Z80 NMI
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(phi_int_w);
|
||||||
|
|
||||||
|
// PHI register read & Z80 IRQ
|
||||||
|
DECLARE_READ8_MEMBER(phi_reg_r);
|
||||||
|
DECLARE_WRITE16_MEMBER(z80_m1_w);
|
||||||
|
|
||||||
|
private:
|
||||||
|
required_device<z80_device> m_cpu;
|
||||||
|
required_device<phi_device> m_phi;
|
||||||
|
|
||||||
|
bool m_cpu_irq;
|
||||||
|
};
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
extern const device_type HP9895;
|
||||||
|
|
||||||
|
#endif /* _HP9895_H_ */
|
|
@ -397,3 +397,14 @@ SLOT_INTERFACE_START( cbm_ieee488_devices )
|
||||||
SLOT_INTERFACE("shark", SHARK)
|
SLOT_INTERFACE("shark", SHARK)
|
||||||
SLOT_INTERFACE("c4023", C4023)
|
SLOT_INTERFACE("c4023", C4023)
|
||||||
SLOT_INTERFACE_END
|
SLOT_INTERFACE_END
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// SLOT_INTERFACE( hp_ieee488_devices )
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
// slot devices
|
||||||
|
#include "hp9895.h"
|
||||||
|
|
||||||
|
SLOT_INTERFACE_START(hp_ieee488_devices)
|
||||||
|
SLOT_INTERFACE("hp9895", HP9895)
|
||||||
|
SLOT_INTERFACE_END
|
||||||
|
|
|
@ -247,6 +247,7 @@ extern const device_type IEEE488_SLOT;
|
||||||
|
|
||||||
|
|
||||||
SLOT_INTERFACE_EXTERN( cbm_ieee488_devices );
|
SLOT_INTERFACE_EXTERN( cbm_ieee488_devices );
|
||||||
|
SLOT_INTERFACE_EXTERN( hp_ieee488_devices );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
1384
src/devices/machine/phi.cpp
Normal file
1384
src/devices/machine/phi.cpp
Normal file
File diff suppressed because it is too large
Load diff
291
src/devices/machine/phi.h
Normal file
291
src/devices/machine/phi.h
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:F. Ulivi
|
||||||
|
/*********************************************************************
|
||||||
|
|
||||||
|
phi.h
|
||||||
|
|
||||||
|
HP PHI (Processor-to-Hpib-Interface) (1AA6-6x04)
|
||||||
|
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#ifndef _PHI_H_
|
||||||
|
#define _PHI_H_
|
||||||
|
|
||||||
|
// Set read and write callbacks to access DIO bus on IEEE-488
|
||||||
|
#define MCFG_PHI_DIO_READWRITE_CB(_read , _write) \
|
||||||
|
phi_device::set_dio_read_cb(*device , DEVCB_##_read); \
|
||||||
|
phi_device::set_dio_write_cb(*device , DEVCB_##_write);
|
||||||
|
|
||||||
|
// Set write callbacks to access uniline signals on IEEE-488
|
||||||
|
#define MCFG_PHI_EOI_WRITE_CB(_write) \
|
||||||
|
phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_EOI , DEVCB_##_write);
|
||||||
|
|
||||||
|
#define MCFG_PHI_DAV_WRITE_CB(_write) \
|
||||||
|
phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_DAV , DEVCB_##_write);
|
||||||
|
|
||||||
|
#define MCFG_PHI_NRFD_WRITE_CB(_write) \
|
||||||
|
phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_NRFD , DEVCB_##_write);
|
||||||
|
|
||||||
|
#define MCFG_PHI_NDAC_WRITE_CB(_write) \
|
||||||
|
phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_NDAC , DEVCB_##_write);
|
||||||
|
|
||||||
|
#define MCFG_PHI_IFC_WRITE_CB(_write) \
|
||||||
|
phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_IFC , DEVCB_##_write);
|
||||||
|
|
||||||
|
#define MCFG_PHI_SRQ_WRITE_CB(_write) \
|
||||||
|
phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_SRQ , DEVCB_##_write);
|
||||||
|
|
||||||
|
#define MCFG_PHI_ATN_WRITE_CB(_write) \
|
||||||
|
phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_ATN , DEVCB_##_write);
|
||||||
|
|
||||||
|
#define MCFG_PHI_REN_WRITE_CB(_write) \
|
||||||
|
phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_REN , DEVCB_##_write);
|
||||||
|
|
||||||
|
// Set write callback for INT signal
|
||||||
|
#define MCFG_PHI_INT_WRITE_CB(_write) \
|
||||||
|
phi_device::set_int_write_cb(*device , DEVCB_##_write);
|
||||||
|
|
||||||
|
// Set write callback for DMARQ signal
|
||||||
|
#define MCFG_PHI_DMARQ_WRITE_CB(_write) \
|
||||||
|
phi_device::set_dmarq_write_cb(*device , DEVCB_##_write);
|
||||||
|
|
||||||
|
// Depth of inbound/outbound FIFOs
|
||||||
|
#define PHI_FIFO_SIZE 8
|
||||||
|
|
||||||
|
class phi_device : public device_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
phi_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname);
|
||||||
|
phi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
// See ieee488.h
|
||||||
|
typedef enum {
|
||||||
|
PHI_488_EOI,
|
||||||
|
PHI_488_DAV,
|
||||||
|
PHI_488_NRFD,
|
||||||
|
PHI_488_NDAC,
|
||||||
|
PHI_488_IFC,
|
||||||
|
PHI_488_SRQ,
|
||||||
|
PHI_488_ATN,
|
||||||
|
PHI_488_REN,
|
||||||
|
PHI_488_SIGNAL_COUNT
|
||||||
|
} phi_488_signal_t;
|
||||||
|
|
||||||
|
template<class _Object> static devcb_base& set_dio_read_cb(device_t &device , _Object object)
|
||||||
|
{ return downcast<phi_device&>(device).m_dio_read_func.set_callback(object); }
|
||||||
|
|
||||||
|
template<class _Object> static devcb_base& set_dio_write_cb(device_t &device , _Object object)
|
||||||
|
{ return downcast<phi_device&>(device).m_dio_write_func.set_callback(object); }
|
||||||
|
|
||||||
|
template<class _Object> static devcb_base& set_488_signal_write_cb(device_t &device , phi_488_signal_t signal , _Object object)
|
||||||
|
{ return downcast<phi_device&>(device).m_signal_wr_fns[ signal ].set_callback(object); }
|
||||||
|
|
||||||
|
template<class _Object> static devcb_base& set_int_write_cb(device_t &device , _Object object)
|
||||||
|
{ return downcast<phi_device&>(device).m_int_write_func.set_callback(object); }
|
||||||
|
|
||||||
|
template<class _Object> static devcb_base& set_dmarq_write_cb(device_t &device , _Object object)
|
||||||
|
{ return downcast<phi_device&>(device).m_dmarq_write_func.set_callback(object); }
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
void set_ext_signal(phi_488_signal_t signal , int state);
|
||||||
|
|
||||||
|
// Register read/write
|
||||||
|
// Mapping of PHI register bits:
|
||||||
|
// Reg. bit PHI bit
|
||||||
|
// =================
|
||||||
|
// 15 0
|
||||||
|
// 14 1
|
||||||
|
// 13 =0=
|
||||||
|
// 12 =0=
|
||||||
|
// 11 =0=
|
||||||
|
// 10 =0=
|
||||||
|
// 9 =0=
|
||||||
|
// 8 =0=
|
||||||
|
// 7 8
|
||||||
|
// 6 9
|
||||||
|
// 5 10
|
||||||
|
// 4 11
|
||||||
|
// 3 12
|
||||||
|
// 2 13
|
||||||
|
// 1 14
|
||||||
|
// 0 15
|
||||||
|
DECLARE_WRITE16_MEMBER(reg16_w);
|
||||||
|
DECLARE_READ16_MEMBER(reg16_r);
|
||||||
|
DECLARE_WRITE8_MEMBER(reg8_w);
|
||||||
|
DECLARE_READ8_MEMBER(reg8_r);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start() override;
|
||||||
|
virtual void device_reset() override;
|
||||||
|
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
devcb_read8 m_dio_read_func;
|
||||||
|
devcb_write8 m_dio_write_func;
|
||||||
|
devcb_write_line m_signal_wr_fns[ PHI_488_SIGNAL_COUNT ];
|
||||||
|
devcb_write_line m_int_write_func;
|
||||||
|
devcb_write_line m_dmarq_write_func;
|
||||||
|
|
||||||
|
bool m_int_line;
|
||||||
|
bool m_dmarq_line;
|
||||||
|
|
||||||
|
// Internal copy of bus signals
|
||||||
|
// These signals have the "right" polarity (i.e. the opposite of bus signals, 1=L)
|
||||||
|
uint8_t m_dio;
|
||||||
|
bool m_signals[ PHI_488_SIGNAL_COUNT ];
|
||||||
|
bool m_ext_signals[ PHI_488_SIGNAL_COUNT ];
|
||||||
|
|
||||||
|
bool m_no_recursion;
|
||||||
|
|
||||||
|
bool m_sys_controller;
|
||||||
|
bool m_loopback;
|
||||||
|
bool m_id_enabled;
|
||||||
|
|
||||||
|
// SH (Source Handshake) states
|
||||||
|
enum {
|
||||||
|
PHI_SH_SIDS, // & SIWS
|
||||||
|
PHI_SH_SGNS, // & SWNS
|
||||||
|
PHI_SH_SDYS,
|
||||||
|
PHI_SH_STRS
|
||||||
|
};
|
||||||
|
|
||||||
|
int m_sh_state;
|
||||||
|
|
||||||
|
// AH (Acceptor Handshake) states
|
||||||
|
enum {
|
||||||
|
PHI_AH_AIDS,
|
||||||
|
PHI_AH_ANRS,
|
||||||
|
PHI_AH_ACRS,
|
||||||
|
PHI_AH_ACDS,
|
||||||
|
PHI_AH_ACDS_FROZEN, // Non-standard state: IF CMD rejected because of even parity
|
||||||
|
PHI_AH_AWNS
|
||||||
|
};
|
||||||
|
|
||||||
|
int m_ah_state;
|
||||||
|
|
||||||
|
// T (Talker) states
|
||||||
|
enum {
|
||||||
|
PHI_T_TIDS,
|
||||||
|
PHI_T_TADS,
|
||||||
|
PHI_T_SPAS,
|
||||||
|
PHI_T_TACS,
|
||||||
|
// The following are non-standard states for IDENTIFY sequencing
|
||||||
|
PHI_T_ID1, // Untalked
|
||||||
|
PHI_T_ID2, // Addressed by secondary address
|
||||||
|
PHI_T_ID3, // Sending 1st byte
|
||||||
|
PHI_T_ID4, // Waiting to send 2nd byte
|
||||||
|
PHI_T_ID5, // Sending 2nd byte
|
||||||
|
PHI_T_ID6 // 2nd byte sent, end of sequence
|
||||||
|
};
|
||||||
|
|
||||||
|
int m_t_state;
|
||||||
|
bool m_t_spms; // False: SPIS, true: SPMS
|
||||||
|
|
||||||
|
// L (Listener) states
|
||||||
|
enum {
|
||||||
|
PHI_L_LIDS,
|
||||||
|
PHI_L_LADS,
|
||||||
|
PHI_L_LACS
|
||||||
|
};
|
||||||
|
|
||||||
|
int m_l_state;
|
||||||
|
|
||||||
|
// SR (Service Request) states
|
||||||
|
enum {
|
||||||
|
PHI_SR_NPRS,
|
||||||
|
PHI_SR_SRQS,
|
||||||
|
PHI_SR_APRS
|
||||||
|
};
|
||||||
|
|
||||||
|
int m_sr_state;
|
||||||
|
|
||||||
|
// PP (Parallel poll) states
|
||||||
|
enum {
|
||||||
|
PHI_PP_PPIS,
|
||||||
|
PHI_PP_PPSS,
|
||||||
|
PHI_PP_PPAS
|
||||||
|
};
|
||||||
|
|
||||||
|
int m_pp_state;
|
||||||
|
bool m_pp_pacs;
|
||||||
|
uint8_t m_ppr_msg;
|
||||||
|
bool m_s_sense;
|
||||||
|
|
||||||
|
// C (Controller) states
|
||||||
|
enum {
|
||||||
|
PHI_C_CIDS,
|
||||||
|
PHI_C_CADS,
|
||||||
|
PHI_C_CACS,
|
||||||
|
PHI_C_CPWS,
|
||||||
|
PHI_C_CPPS,
|
||||||
|
PHI_C_CSBS,
|
||||||
|
PHI_C_CSHS,
|
||||||
|
PHI_C_CAWS,
|
||||||
|
PHI_C_CTRS,
|
||||||
|
PHI_C_CSWS
|
||||||
|
};
|
||||||
|
|
||||||
|
int m_c_state;
|
||||||
|
uint8_t m_be_counter;
|
||||||
|
uint16_t m_reg_status;
|
||||||
|
uint16_t m_reg_int_cond;
|
||||||
|
uint16_t m_reg_int_mask;
|
||||||
|
uint16_t m_reg_1st_id;
|
||||||
|
uint16_t m_reg_2nd_id;
|
||||||
|
uint16_t m_reg_control;
|
||||||
|
uint16_t m_reg_address;
|
||||||
|
util::fifo<uint16_t , PHI_FIFO_SIZE> m_fifo_in;
|
||||||
|
util::fifo<uint16_t , PHI_FIFO_SIZE> m_fifo_out;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NBA_NONE,
|
||||||
|
NBA_CMD_FROM_OFIFO,
|
||||||
|
NBA_BYTE_FROM_OFIFO,
|
||||||
|
NBA_FROM_SPAS,
|
||||||
|
NBA_FROM_ID3,
|
||||||
|
NBA_FROM_ID5
|
||||||
|
} nba_origin_t;
|
||||||
|
|
||||||
|
int m_nba_origin;
|
||||||
|
|
||||||
|
// Timers
|
||||||
|
emu_timer *m_sh_dly_timer;
|
||||||
|
emu_timer *m_c_dly_timer;
|
||||||
|
|
||||||
|
void int_reg_w(offs_t offset , uint16_t data);
|
||||||
|
|
||||||
|
uint8_t get_dio(void);
|
||||||
|
void set_dio(uint8_t data);
|
||||||
|
bool get_signal(phi_488_signal_t signal);
|
||||||
|
void set_signal(phi_488_signal_t signal , bool state);
|
||||||
|
|
||||||
|
void pon_msg(void);
|
||||||
|
void update_488(void);
|
||||||
|
void update_fsm(void);
|
||||||
|
nba_origin_t nba_msg(uint8_t& new_byte , bool& new_eoi) const;
|
||||||
|
void clear_nba(nba_origin_t origin);
|
||||||
|
bool if_cmd_received(uint8_t byte);
|
||||||
|
bool byte_received(uint8_t byte , bool eoi);
|
||||||
|
bool ton_msg(void) const;
|
||||||
|
bool lon_msg(void) const;
|
||||||
|
bool odd_parity(uint8_t byte) const;
|
||||||
|
uint8_t my_address(void) const;
|
||||||
|
bool tcs_msg(void) const;
|
||||||
|
bool rpp_msg(void) const;
|
||||||
|
bool controller_in_charge(void) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
extern const device_type PHI;
|
||||||
|
|
||||||
|
#endif /* _PHI_H_ */
|
Loading…
Reference in a new issue