summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/ieee488/hp9895.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/ieee488/hp9895.cpp')
-rw-r--r--src/devices/bus/ieee488/hp9895.cpp150
1 files changed, 140 insertions, 10 deletions
diff --git a/src/devices/bus/ieee488/hp9895.cpp b/src/devices/bus/ieee488/hp9895.cpp
index ffc7ae29d70..8d09faddcb1 100644
--- a/src/devices/bus/ieee488/hp9895.cpp
+++ b/src/devices/bus/ieee488/hp9895.cpp
@@ -56,6 +56,12 @@
#include "emu.h"
#include "hp9895.h"
+
+#include "cpu/z80/z80.h"
+#include "imagedev/floppy.h"
+#include "machine/fdc_pll.h"
+#include "machine/phi.h"
+
#include "formats/fs_hp98x5.h"
#include "formats/hpi_dsk.h"
@@ -65,6 +71,9 @@
#define VERBOSE (LOG_LEVEL1)
#include "logmacro.h"
+
+namespace {
+
// Macros to clear/set single bits
#define BIT_MASK(n) (1U << (n))
#define BIT_CLR(w , n) ((w) &= ~BIT_MASK(n))
@@ -124,22 +133,137 @@
#define MIN_SYNC_BITS 29 // Number of bits to synchronize
-// device type definition
-DEFINE_DEVICE_TYPE(HP9895, hp9895_device, "hp9895", "HP9895")
-
// Masks of drive selectors in XV register
static const uint8_t xv_drive_masks[] = {
BIT_MASK(REG_XV_DRIVE0_BIT),
BIT_MASK(REG_XV_DRIVE1_BIT)
};
-hp9895_device::hp9895_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, HP9895, tag, owner, clock),
- device_ieee488_interface(mconfig, *this),
- m_cpu(*this , "cpu"),
- m_phi(*this , "phi"),
- m_drives(*this , "floppy%u" , 0U),
- m_switches{*this , "switches"}
+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);
+
+protected:
+ // device_t implementation
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
+ virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+
+ // device_ieee488_interface implementation
+ 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:
+ // PHI write CBs
+ void phi_eoi_w(int state);
+ void phi_dav_w(int state);
+ void phi_nrfd_w(int state);
+ void phi_ndac_w(int state);
+ void phi_ifc_w(int state);
+ void phi_srq_w(int state);
+ void phi_atn_w(int state);
+ void phi_ren_w(int state);
+
+ // PHI DIO r/w CBs
+ uint8_t phi_dio_r();
+ void phi_dio_w(uint8_t data);
+
+ // PHI IRQ/Z80 NMI
+ void phi_int_w(int state);
+
+ // Z80 IRQ
+ void z80_m1_w(uint8_t data);
+
+ // Floppy interface
+ void data_w(uint8_t data);
+ void clock_w(uint8_t data);
+ void reset_w(uint8_t data);
+ void leds_w(uint8_t data);
+ void cntl_w(uint8_t data);
+ void drv_w(uint8_t data);
+ void xv_w(uint8_t data);
+ uint8_t data_r();
+ uint8_t clock_r();
+ uint8_t drivstat_r();
+ uint8_t switches_r();
+ uint8_t switches2_r();
+
+ // PHI register read
+ uint8_t phi_reg_r(offs_t offset);
+
+ // Floppy drive interface
+ void floppy_ready_cb(floppy_image_device *floppy , int state);
+
+ TIMER_CALLBACK_MEMBER(timeout_timer_tick);
+ TIMER_CALLBACK_MEMBER(byte_timer_tick);
+ TIMER_CALLBACK_MEMBER(half_bit_timer_tick);
+
+ uint8_t get_switches2(void) const;
+ attotime get_half_bit_cell_period(void) const;
+ floppy_image_device *get_write_device(void) const;
+ void preset_crc(void);
+ void update_crc(bool bit);
+ bool shift_sr(uint8_t& sr , bool input_bit);
+ void get_next_transition(const attotime& from_when , attotime& edge);
+ void read_bit(bool crc_upd);
+ void write_bit(bool data_bit , bool clock_bit);
+
+ void z80_io_map(address_map &map) ATTR_COLD;
+ void z80_program_map(address_map &map) ATTR_COLD;
+
+ required_device<z80_device> m_cpu;
+ required_device<phi_device> m_phi;
+ required_device_array<floppy_connector, 2> m_drives;
+ required_ioport m_switches;
+
+ bool m_cpu_irq;
+ floppy_image_device *m_current_drive;
+ unsigned m_current_drive_idx;
+ bool m_dskchg[ 2 ];
+ uint16_t m_crc; // U77
+ bool m_crcerr_syn;
+ bool m_overrun;
+ bool m_accdata;
+ bool m_timeout;
+ uint8_t m_cntl_reg; // U31
+ uint8_t m_clock_sr; // U22 & U4
+ uint8_t m_clock_reg; // U23 & U5
+ uint8_t m_data_sr; // U24 & U6
+ uint8_t m_wr_context;
+ bool m_had_transition;
+ bool m_lckup;
+ bool m_amdt;
+ uint8_t m_sync_cnt; // U28 & U73
+ bool m_hiden;
+ bool m_mgnena;
+
+ // Timers
+ emu_timer *m_timeout_timer;
+ emu_timer *m_byte_timer;
+ emu_timer *m_half_bit_timer;
+
+ // PLL
+ fdc_pll_t m_pll;
+};
+
+hp9895_device::hp9895_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, GPIB_HP9895, tag, owner, clock),
+ device_ieee488_interface(mconfig, *this),
+ m_cpu(*this , "cpu"),
+ m_phi(*this , "phi"),
+ m_drives(*this , "floppy%u" , 0U),
+ m_switches{*this , "switches"}
{
}
@@ -895,3 +1019,9 @@ void hp9895_device::device_add_mconfig(machine_config &config)
FLOPPY_CONNECTOR(config, "floppy0", hp9895_floppies, "8dsdd", hp9895_floppy_formats).set_fixed(true);
FLOPPY_CONNECTOR(config, "floppy1", hp9895_floppies, "8dsdd", hp9895_floppy_formats).set_fixed(true);
}
+
+} // anonymous namespace
+
+
+// device type definition
+DEFINE_DEVICE_TYPE_PRIVATE(GPIB_HP9895, device_ieee488_interface, hp9895_device, "hp9895", "HP9895 floppy drive")