summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/bus/wangpc/wdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/bus/wangpc/wdc.c')
-rw-r--r--src/emu/bus/wangpc/wdc.c357
1 files changed, 357 insertions, 0 deletions
diff --git a/src/emu/bus/wangpc/wdc.c b/src/emu/bus/wangpc/wdc.c
new file mode 100644
index 00000000000..ed65af7da25
--- /dev/null
+++ b/src/emu/bus/wangpc/wdc.c
@@ -0,0 +1,357 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC-PM001 Winchester Disk Controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "wdc.h"
+#include "machine/scsihd.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define OPTION_ID 0x01
+
+#define Z80_TAG "l53"
+#define MK3882_TAG "l07"
+
+#define OPTION_DREQ1 BIT(m_option, 1)
+#define OPTION_DREQ2 BIT(m_option, 2)
+#define OPTION_DREQ3 BIT(m_option, 3)
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type WANGPC_WDC = &device_creator<wangpc_wdc_device>;
+
+
+//-------------------------------------------------
+// ROM( wangpc_wdc )
+//-------------------------------------------------
+
+ROM_START( wangpc_wdc )
+ ROM_REGION( 0x1000, Z80_TAG, 0 )
+ ROM_LOAD( "378-9040 r9.l19", 0x0000, 0x1000, CRC(282770d2) SHA1(a0e3bad5041e0dfd6087907015b07a093b576bc0) )
+
+ ROM_REGION( 0x1000, "address", 0 )
+ ROM_LOAD( "378-9041.l54", 0x0000, 0x1000, CRC(94e9a17d) SHA1(060c576d70069ece2d0dbce86ffc448df2b169e7) )
+
+ ROM_REGION( 0x100, "prom", 0 )
+ ROM_LOAD( "376-8002.l66", 0x000, 0x100, NO_DUMP ) // DL2212-105
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *wangpc_wdc_device::device_rom_region() const
+{
+ return ROM_NAME( wangpc_wdc );
+}
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( wangpc_wdc_mem )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( wangpc_wdc_mem, AS_PROGRAM, 8, wangpc_wdc_device )
+ AM_RANGE(0x0000, 0x0fff) AM_ROM AM_REGION(Z80_TAG, 0)
+ AM_RANGE(0x1000, 0x17ff) AM_RAM
+ AM_RANGE(0x2000, 0x27ff) AM_RAM
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( wangpc_wdc_io )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( wangpc_wdc_io, AS_IO, 8, wangpc_wdc_device )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x01, 0x01) AM_READ(port_r)
+ AM_RANGE(0x03, 0x03) AM_WRITE(status_w)
+ AM_RANGE(0x10, 0x10) AM_READWRITE(ctc_ch0_r, ctc_ch0_w)
+ AM_RANGE(0x14, 0x14) AM_READWRITE(ctc_ch1_r, ctc_ch1_w)
+ AM_RANGE(0x18, 0x18) AM_READWRITE(ctc_ch2_r, ctc_ch2_w)
+ AM_RANGE(0x1c, 0x1c) AM_READWRITE(ctc_ch3_r, ctc_ch3_w)
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// Z80CTC_INTERFACE( ctc_intf )
+//-------------------------------------------------
+
+static Z80CTC_INTERFACE( ctc_intf )
+{
+ DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0), // interrupt handler
+ DEVCB_NULL, // ZC/TO0 callback
+ DEVCB_NULL, // ZC/TO1 callback
+ DEVCB_NULL // ZC/TO2 callback
+};
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( wangpc_wdc )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( wangpc_wdc )
+ MCFG_CPU_ADD(Z80_TAG, Z80, 2000000) // XTAL_10MHz / ?
+ //MCFG_CPU_CONFIG(wangpc_wdc_daisy_chain)
+ MCFG_CPU_PROGRAM_MAP(wangpc_wdc_mem)
+ MCFG_CPU_IO_MAP(wangpc_wdc_io)
+
+ MCFG_Z80CTC_ADD(MK3882_TAG, 2000000, ctc_intf)
+
+ MCFG_DEVICE_ADD("harddisk0", SCSIHD, 0)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor wangpc_wdc_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( wangpc_wdc );
+}
+
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+//-------------------------------------------------
+// set_irq -
+//-------------------------------------------------
+
+inline void wangpc_wdc_device::set_irq(int state)
+{
+ m_irq = state;
+
+ if (OPTION_DREQ1) m_bus->irq5_w(m_irq);
+ if (OPTION_DREQ2) m_bus->irq6_w(m_irq);
+ if (OPTION_DREQ3) m_bus->irq7_w(m_irq);
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// wangpc_wdc_device - constructor
+//-------------------------------------------------
+
+wangpc_wdc_device::wangpc_wdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, WANGPC_WDC, "Wang PC-PM001", tag, owner, clock, "wangpc_wdc", __FILE__),
+ device_wangpcbus_card_interface(mconfig, *this),
+ m_maincpu(*this, Z80_TAG),
+ m_ctc(*this, MK3882_TAG)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void wangpc_wdc_device::device_start()
+{
+ // state saving
+ save_item(NAME(m_status));
+ save_item(NAME(m_option));
+ save_item(NAME(m_irq));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void wangpc_wdc_device::device_reset()
+{
+ m_status = 0;
+ m_option = 0;
+
+ set_irq(CLEAR_LINE);
+}
+
+
+//-------------------------------------------------
+// wangpcbus_mrdc_r - memory read
+//-------------------------------------------------
+
+UINT16 wangpc_wdc_device::wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 data = 0xffff;
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_amwc_w - memory write
+//-------------------------------------------------
+
+void wangpc_wdc_device::wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
+{
+}
+
+
+//-------------------------------------------------
+// wangpcbus_iorc_r - I/O read
+//-------------------------------------------------
+
+UINT16 wangpc_wdc_device::wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 data = 0xffff;
+
+ if (sad(offset))
+ {
+ switch (offset & 0x7f)
+ {
+ case 0x00/2:
+ data = m_status;
+ break;
+
+ case 0x02/2:
+ // TODO operation status register
+ break;
+
+ case 0x04/2:
+ set_irq(CLEAR_LINE);
+ break;
+
+ case 0xfe/2:
+ data = 0xff00 | (m_irq << 7) | OPTION_ID;
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_aiowc_w - I/O write
+//-------------------------------------------------
+
+void wangpc_wdc_device::wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
+{
+ if (sad(offset) && ACCESSING_BITS_0_7)
+ {
+ switch (offset & 0x7f)
+ {
+ case 0x02/2:
+ // TODO command register
+ break;
+
+ case 0xfc/2:
+ device_reset();
+ break;
+
+ case 0xfe/2:
+ {
+ bool irq = (m_irq == ASSERT_LINE);
+ bool changed = ((m_option & 0x0e) != (data & 0x0e));
+
+ if (irq && changed) set_irq(CLEAR_LINE);
+
+ m_option = data & 0xff;
+
+ if (irq && changed) set_irq(ASSERT_LINE);
+ }
+ break;
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// wangpcbus_dack_r - DMA acknowledge read
+//-------------------------------------------------
+
+UINT8 wangpc_wdc_device::wangpcbus_dack_r(address_space &space, int line)
+{
+ return 0;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_dack_r - DMA acknowledge write
+//-------------------------------------------------
+
+void wangpc_wdc_device::wangpcbus_dack_w(address_space &space, int line, UINT8 data)
+{
+}
+
+
+//-------------------------------------------------
+// wangpcbus_have_dack -
+//-------------------------------------------------
+
+bool wangpc_wdc_device::wangpcbus_have_dack(int line)
+{
+ return (OPTION_DREQ1 && (line == 1)) || (OPTION_DREQ2 && (line == 2)) || (OPTION_DREQ3 && (line == 3));
+}
+
+
+//-------------------------------------------------
+// port_r -
+//-------------------------------------------------
+
+READ8_MEMBER( wangpc_wdc_device::port_r )
+{
+ /*
+
+ bit description
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+
+ */
+
+ return 0x72; // TODO
+}
+
+
+//-------------------------------------------------
+// status_w - status register write
+//-------------------------------------------------
+
+WRITE8_MEMBER( wangpc_wdc_device::status_w )
+{
+ logerror("WDC status %02x\n", data);
+
+ m_status = data;
+}
+
+
+READ8_MEMBER( wangpc_wdc_device::ctc_ch0_r ) { return m_ctc->read(0); };
+WRITE8_MEMBER( wangpc_wdc_device::ctc_ch0_w ) { m_ctc->write(0, data); };
+READ8_MEMBER( wangpc_wdc_device::ctc_ch1_r ) { return m_ctc->read(1); };
+WRITE8_MEMBER( wangpc_wdc_device::ctc_ch1_w ) { m_ctc->write(1, data); };
+READ8_MEMBER( wangpc_wdc_device::ctc_ch2_r ) { return m_ctc->read(2); };
+WRITE8_MEMBER( wangpc_wdc_device::ctc_ch2_w ) { m_ctc->write(2, data); };
+READ8_MEMBER( wangpc_wdc_device::ctc_ch3_r ) { return m_ctc->read(3); };
+WRITE8_MEMBER( wangpc_wdc_device::ctc_ch3_w ) { m_ctc->write(3, data); };