summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/bus
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/bus')
-rw-r--r--src/emu/bus/bus.mak18
-rw-r--r--src/emu/bus/wangpc/emb.c178
-rw-r--r--src/emu/bus/wangpc/emb.h58
-rw-r--r--src/emu/bus/wangpc/lic.c162
-rw-r--r--src/emu/bus/wangpc/lic.h56
-rw-r--r--src/emu/bus/wangpc/lvc.c361
-rw-r--r--src/emu/bus/wangpc/lvc.h71
-rw-r--r--src/emu/bus/wangpc/mcc.c320
-rw-r--r--src/emu/bus/wangpc/mcc.h63
-rw-r--r--src/emu/bus/wangpc/mvc.c354
-rw-r--r--src/emu/bus/wangpc/mvc.h71
-rw-r--r--src/emu/bus/wangpc/rtc.c353
-rw-r--r--src/emu/bus/wangpc/rtc.h69
-rw-r--r--src/emu/bus/wangpc/tig.c342
-rw-r--r--src/emu/bus/wangpc/tig.h68
-rw-r--r--src/emu/bus/wangpc/wangpc.c346
-rw-r--r--src/emu/bus/wangpc/wangpc.h224
-rw-r--r--src/emu/bus/wangpc/wdc.c357
-rw-r--r--src/emu/bus/wangpc/wdc.h84
19 files changed, 3555 insertions, 0 deletions
diff --git a/src/emu/bus/bus.mak b/src/emu/bus/bus.mak
index c7963f80a63..b947076a1a4 100644
--- a/src/emu/bus/bus.mak
+++ b/src/emu/bus/bus.mak
@@ -76,3 +76,21 @@ BUSOBJS += $(BUSOBJ)/s100/nsmdsa.o
BUSOBJS += $(BUSOBJ)/s100/nsmdsad.o
BUSOBJS += $(BUSOBJ)/s100/wunderbus.o
endif
+
+
+#-------------------------------------------------
+#
+#@src/emu/bus/wangpc/wangpc.h,BUSES += WANGPC
+#-------------------------------------------------
+
+ifneq ($(filter WANGPC,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/wangpc/wangpc.o
+BUSOBJS += $(BUSOBJ)/wangpc/emb.o
+BUSOBJS += $(BUSOBJ)/wangpc/lic.o
+BUSOBJS += $(BUSOBJ)/wangpc/lvc.o
+BUSOBJS += $(BUSOBJ)/wangpc/mcc.o
+BUSOBJS += $(BUSOBJ)/wangpc/mvc.o
+BUSOBJS += $(BUSOBJ)/wangpc/rtc.o
+BUSOBJS += $(BUSOBJ)/wangpc/tig.o
+BUSOBJS += $(BUSOBJ)/wangpc/wdc.o
+endif
diff --git a/src/emu/bus/wangpc/emb.c b/src/emu/bus/wangpc/emb.c
new file mode 100644
index 00000000000..d10072e6865
--- /dev/null
+++ b/src/emu/bus/wangpc/emb.c
@@ -0,0 +1,178 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC-PM031-B Extended Memory Board emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "emb.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+#define OPTION_ID 0x3f
+
+#define RAM_SIZE 0x40000
+
+#define A19_A18_A17 ((offset >> 16) & 0x07)
+#define BASE(bank) ((m_option >> (bank * 4)) & 0x07)
+#define ENABLE(bank) BIT(m_option, (bank * 4) + 3)
+#define RAM_BANK(bank) m_ram[(bank * 0x10000) | (offset & 0xffff)]
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type WANGPC_EMB = &device_creator<wangpc_emb_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// wangpc_emb_device - constructor
+//-------------------------------------------------
+
+wangpc_emb_device::wangpc_emb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, WANGPC_EMB, "Wang PC-PM031-B", tag, owner, clock, "wangpc_emb", __FILE__),
+ device_wangpcbus_card_interface(mconfig, *this),
+ m_ram(*this, "ram")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void wangpc_emb_device::device_start()
+{
+ // allocate memory
+ m_ram.allocate(RAM_SIZE);
+
+ // state saving
+ save_item(NAME(m_option));
+ save_item(NAME(m_parity_error));
+ save_item(NAME(m_parity_odd));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void wangpc_emb_device::device_reset()
+{
+ m_option = 0;
+ m_parity_error = 0;
+ m_parity_odd = 1;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_mrdc_r - memory read
+//-------------------------------------------------
+
+UINT16 wangpc_emb_device::wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 data = 0xffff;
+
+ for (int bank = 0; bank < 4; bank++)
+ {
+ if (ENABLE(bank) && (A19_A18_A17 == BASE(bank)))
+ {
+ data &= RAM_BANK(bank);
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_amwc_w - memory write
+//-------------------------------------------------
+
+void wangpc_emb_device::wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
+{
+ for (int bank = 0; bank < 4; bank++)
+ {
+ if (ENABLE(bank) && (A19_A18_A17 == BASE(bank)))
+ {
+ RAM_BANK(bank) = data;
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// wangpcbus_iorc_r - I/O read
+//-------------------------------------------------
+
+UINT16 wangpc_emb_device::wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 data = 0xffff;
+
+ if (sad(offset))
+ {
+ switch (offset & 0x7f)
+ {
+ case 0xc0/2:
+ data = m_option;
+ break;
+
+ case 0xfe/2:
+ data = 0xfc00 | (m_parity_odd << 9) | (m_parity_error << 8) | OPTION_ID;
+ break;
+ }
+
+ logerror("emb read %06x:%02x\n", offset*2, data);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_aiowc_w - I/O write
+//-------------------------------------------------
+
+void wangpc_emb_device::wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
+{
+ if (sad(offset))
+ {
+ logerror("emb write %06x:%02x\n", offset*2, data);
+
+ switch (offset & 0x7f)
+ {
+ case 0xc0/2:
+ m_option = data;
+ break;
+
+ case 0xce/2:
+ m_parity_error = 0;
+ break;
+
+ case 0xfc/2:
+ device_reset();
+ break;
+
+ case 0xfe/2:
+ m_parity_odd = BIT(data, 9);
+ break;
+ }
+ }
+}
diff --git a/src/emu/bus/wangpc/emb.h b/src/emu/bus/wangpc/emb.h
new file mode 100644
index 00000000000..ff2eb2a97cb
--- /dev/null
+++ b/src/emu/bus/wangpc/emb.h
@@ -0,0 +1,58 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC-PM031-B Extended Memory Board emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __WANGPC_EMB__
+#define __WANGPC_EMB__
+
+#include "emu.h"
+#include "wangpc.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> wangpc_emb_device
+
+class wangpc_emb_device : public device_t,
+ public device_wangpcbus_card_interface
+{
+public:
+ // construction/destruction
+ wangpc_emb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_wangpcbus_card_interface overrides
+ virtual UINT16 wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+ virtual UINT16 wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+
+private:
+ optional_shared_ptr<UINT16> m_ram;
+ UINT16 m_option;
+ int m_parity_error;
+ int m_parity_odd;
+};
+
+
+// device type definition
+extern const device_type WANGPC_EMB;
+
+
+#endif
diff --git a/src/emu/bus/wangpc/lic.c b/src/emu/bus/wangpc/lic.c
new file mode 100644
index 00000000000..0d7c3f370bf
--- /dev/null
+++ b/src/emu/bus/wangpc/lic.c
@@ -0,0 +1,162 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC Network card emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "lic.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define OPTION_ID 0x30
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type WANGPC_LIC = &device_creator<wangpc_lic_device>;
+
+
+//-------------------------------------------------
+// ROM( wangpc_lic )
+//-------------------------------------------------
+
+ROM_START( wangpc_lic )
+ ROM_REGION( 0x1000, "network", 0 )
+ ROM_LOAD( "7025.l22", 0x0000, 0x1000, CRC(487e5f04) SHA1(81e52e70e0c6e34715119b121ec19a7758cd6772) )
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *wangpc_lic_device::device_rom_region() const
+{
+ return ROM_NAME( wangpc_lic );
+}
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( wangpc_lic )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( wangpc_lic )
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor wangpc_lic_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( wangpc_lic );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// wangpc_lic_device - constructor
+//-------------------------------------------------
+
+wangpc_lic_device::wangpc_lic_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, WANGPC_LIC, "Wang PC-PM070", tag, owner, clock, "wangpc_lic", __FILE__),
+ device_wangpcbus_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void wangpc_lic_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void wangpc_lic_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// wangpcbus_mrdc_r - memory read
+//-------------------------------------------------
+
+UINT16 wangpc_lic_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_lic_device::wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
+{
+}
+
+
+//-------------------------------------------------
+// wangpcbus_iorc_r - I/O read
+//-------------------------------------------------
+
+UINT16 wangpc_lic_device::wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 data = 0xffff;
+
+ if (sad(offset))
+ {
+ switch (offset & 0x7f)
+ {
+ case 0xfe/2:
+ data = 0xff00 | OPTION_ID;
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_aiowc_w - I/O write
+//-------------------------------------------------
+
+void wangpc_lic_device::wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
+{
+ if (sad(offset))
+ {
+ switch (offset & 0x7f)
+ {
+ case 0xfc/2:
+ device_reset();
+ break;
+ }
+ }
+}
diff --git a/src/emu/bus/wangpc/lic.h b/src/emu/bus/wangpc/lic.h
new file mode 100644
index 00000000000..af3b0a0213a
--- /dev/null
+++ b/src/emu/bus/wangpc/lic.h
@@ -0,0 +1,56 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC-PM070 Local Interconnect option card emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __WANGPC_LIC__
+#define __WANGPC_LIC__
+
+#include "emu.h"
+#include "wangpc.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> wangpc_lic_device
+
+class wangpc_lic_device : public device_t,
+ public device_wangpcbus_card_interface
+{
+public:
+ // construction/destruction
+ wangpc_lic_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_wangpcbus_card_interface overrides
+ virtual UINT16 wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+ virtual UINT16 wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+};
+
+
+// device type definition
+extern const device_type WANGPC_LIC;
+
+
+#endif
diff --git a/src/emu/bus/wangpc/lvc.c b/src/emu/bus/wangpc/lvc.c
new file mode 100644
index 00000000000..8670875c25f
--- /dev/null
+++ b/src/emu/bus/wangpc/lvc.c
@@ -0,0 +1,361 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC Low-Resolution Video Controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+/*
+
+ TODO:
+
+ - cursor
+ - scroll
+ - option bit 1?
+
+*/
+
+#include "lvc.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+#define OPTION_ID 0x10
+
+#define MC6845_TAG "mc6845"
+#define SCREEN_TAG "screen"
+
+#define RAM_SIZE 0x8000
+
+#define OPTION_VRAM BIT(m_option, 0)
+#define OPTION_UNKNOWN BIT(m_option, 1)
+#define OPTION_80_COL BIT(m_option, 2)
+#define OPTION_VSYNC BIT(m_option, 3)
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type WANGPC_LVC = &device_creator<wangpc_lvc_device>;
+
+
+//-------------------------------------------------
+// mc6845_interface crtc_intf
+//-------------------------------------------------
+
+void wangpc_lvc_device::crtc_update_row(mc6845_device *device, bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 ma, UINT8 ra, UINT16 y, UINT8 x_count, INT8 cursor_x, void *param)
+{
+ offs_t scroll_y = (((m_scroll >> 8) + 0x15) & 0xff) * 0x80;
+
+ if (OPTION_80_COL)
+ {
+ for (int column = 0; column < x_count; column++)
+ {
+ offs_t addr = scroll_y + (m_scroll & 0x3f) + ((ma / 80) * 0x480) + (((ra & 0x0f) << 7) | (column & 0x7f));
+ UINT16 data = m_video_ram[addr & 0x7fff];
+
+ for (int bit = 0; bit < 8; bit++)
+ {
+ int x = (column * 8) + bit;
+ int color = (BIT(data, 15) << 1) | BIT(data, 7);
+
+ if (column == cursor_x) color = 0x03;
+
+ bitmap.pix32(y, x) = m_palette[color];
+
+ data <<= 1;
+ }
+ }
+ }
+ else
+ {
+ //offs_t addr = scroll_y + ((m_scroll & 0x3f) << 1) + ((ma / 40) * 0x480) + (((ra & 0x0f) << 7));
+ offs_t addr = scroll_y + ((m_scroll & 0x3f) << 1) + (y * 0x80);
+
+ for (int column = 0; column < x_count; column++)
+ {
+ UINT32 data = (m_video_ram[(addr + 1) & 0x7fff] << 16) | m_video_ram[addr & 0x7fff];
+
+ for (int bit = 0; bit < 8; bit++)
+ {
+ int x = (column * 8) + bit;
+ int color = (BIT(data, 31) << 3) | (BIT(data, 23) << 2) | (BIT(data, 15) << 1) | BIT(data, 7);
+
+ if (column == cursor_x) color = 0x03;
+
+ bitmap.pix32(y, x) = m_palette[color];
+
+ data <<= 1;
+ }
+
+ addr += 2;
+ }
+ }
+}
+
+static MC6845_UPDATE_ROW( wangpc_lvc_update_row )
+{
+ wangpc_lvc_device *lvc = downcast<wangpc_lvc_device *>(device->owner());
+
+ lvc->crtc_update_row(device, bitmap, cliprect, ma, ra, y, x_count, cursor_x, param);
+}
+
+WRITE_LINE_MEMBER( wangpc_lvc_device::vsync_w )
+{
+ if (OPTION_VSYNC && state)
+ {
+ set_irq(ASSERT_LINE);
+ }
+}
+
+static MC6845_INTERFACE( crtc_intf )
+{
+ false,
+ 8,
+ NULL,
+ wangpc_lvc_update_row,
+ NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, wangpc_lvc_device, vsync_w),
+ NULL
+};
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( wangpc_lvc )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( wangpc_lvc )
+ MCFG_SCREEN_ADD(SCREEN_TAG, RASTER)
+ MCFG_SCREEN_UPDATE_DEVICE(MC6845_TAG, mc6845_device, screen_update)
+ MCFG_SCREEN_SIZE(80*8, 25*9)
+ MCFG_SCREEN_VISIBLE_AREA(0, 80*8-1, 0, 25*9-1)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
+ MCFG_SCREEN_REFRESH_RATE(60)
+
+ MCFG_MC6845_ADD(MC6845_TAG, MC6845_1, SCREEN_TAG, XTAL_14_31818MHz/16, crtc_intf)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor wangpc_lvc_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( wangpc_lvc );
+}
+
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+//-------------------------------------------------
+// set_irq -
+//-------------------------------------------------
+
+inline void wangpc_lvc_device::set_irq(int state)
+{
+ m_irq = state;
+
+ m_bus->irq3_w(m_irq);
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// wangpc_lvc_device - constructor
+//-------------------------------------------------
+
+wangpc_lvc_device::wangpc_lvc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, WANGPC_LVC, "Wang PC Low Resolution Video Card", tag, owner, clock, "wangpc_lvc", __FILE__),
+ device_wangpcbus_card_interface(mconfig, *this),
+ m_crtc(*this, MC6845_TAG),
+ m_video_ram(*this, "video_ram"),
+ m_option(0),
+ m_irq(CLEAR_LINE)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void wangpc_lvc_device::device_start()
+{
+ // allocate memory
+ m_video_ram.allocate(RAM_SIZE);
+
+ // state saving
+ save_item(NAME(m_option));
+ save_item(NAME(m_scroll));
+ save_item(NAME(m_irq));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void wangpc_lvc_device::device_reset()
+{
+ m_option = 0;
+
+ set_irq(CLEAR_LINE);
+}
+
+
+//-------------------------------------------------
+// wangpcbus_mrdc_r - memory read
+//-------------------------------------------------
+
+UINT16 wangpc_lvc_device::wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 data = 0xffff;
+
+ if (OPTION_VRAM && (offset >= 0xe0000/2) && (offset < 0xf0000/2))
+ {
+ offs_t addr = offset & 0x7fff;
+
+ data = m_video_ram[addr];
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_amwc_w - memory write
+//-------------------------------------------------
+
+void wangpc_lvc_device::wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
+{
+ if (OPTION_VRAM && (offset >= 0xe0000/2) && (offset < 0xf0000/2))
+ {
+ offs_t addr = offset & 0x7fff;
+
+ m_video_ram[addr] = data;
+ }
+}
+
+
+//-------------------------------------------------
+// wangpcbus_iorc_r - I/O read
+//-------------------------------------------------
+
+UINT16 wangpc_lvc_device::wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 data = 0xffff;
+
+ if (sad(offset))
+ {
+ switch (offset & 0x7f)
+ {
+ case 0x02/2:
+ data = 0xff00 | m_crtc->register_r(space, 0);
+ break;
+
+ case 0x30/2:
+ data = 0xffe3;
+ data |= m_crtc->de_r() << 2;
+ data |= m_crtc->vsync_r() << 3;
+ data |= m_crtc->hsync_r() << 4;
+ break;
+
+ case 0xfe/2:
+ data = 0xff00 | (m_irq << 7) | OPTION_ID;
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_aiowc_w - I/O write
+//-------------------------------------------------
+
+void wangpc_lvc_device::wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
+{
+ if (sad(offset))
+ {
+ switch (offset & 0x7f)
+ {
+ case 0x00/2:
+ if (ACCESSING_BITS_0_7)
+ {
+ m_crtc->address_w(space, 0, data & 0xff);
+ }
+ break;
+
+ case 0x02/2:
+ if (ACCESSING_BITS_0_7)
+ {
+ m_crtc->register_w(space, 0, data & 0xff);
+ }
+ break;
+
+ case 0x10/2:
+ if (ACCESSING_BITS_0_7)
+ {
+ if (LOG) logerror("LVC option %02x\n", data & 0xff);
+ m_option = data & 0xff;
+
+ if (OPTION_80_COL)
+ {
+ m_crtc->set_clock(XTAL_14_31818MHz / 8);
+ }
+ else
+ {
+ m_crtc->set_clock(XTAL_14_31818MHz / 16);
+ }
+ }
+ break;
+
+ case 0x20/2:
+ if (LOG) logerror("LVC scroll %04x\n", data);
+ m_scroll = data;
+ break;
+
+ case 0x40/2: case 0x42/2: case 0x44/2: case 0x46/2: case 0x48/2: case 0x4a/2: case 0x4c/2: case 0x4e/2:
+ case 0x50/2: case 0x52/2: case 0x55/2: case 0x56/2: case 0x58/2: case 0x5a/2: case 0x5c/2: case 0x5e/2:
+ {
+ offs_t index = offset & 0x0f;
+
+ int i = BIT(data, 15);
+ int r = BIT(data, 11) ? (i ? 0xff : 0x80) : 0;
+ int g = BIT(data, 7) ? (i ? 0xff : 0x80) : 0;
+ int b = BIT(data, 3) ? (i ? 0xff : 0x80) : 0;
+
+ m_palette[index] = MAKE_RGB(r, g, b);
+ }
+ break;
+
+ case 0x70/2:
+ set_irq(CLEAR_LINE);
+ break;
+ }
+ }
+}
diff --git a/src/emu/bus/wangpc/lvc.h b/src/emu/bus/wangpc/lvc.h
new file mode 100644
index 00000000000..1e4e8c86226
--- /dev/null
+++ b/src/emu/bus/wangpc/lvc.h
@@ -0,0 +1,71 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC Low-Resolution Video Controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __WANGPC_LVC__
+#define __WANGPC_LVC__
+
+#include "emu.h"
+#include "wangpc.h"
+#include "video/mc6845.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> wangpc_lvc_device
+
+class wangpc_lvc_device : public device_t,
+ public device_wangpcbus_card_interface
+{
+public:
+ // construction/destruction
+ wangpc_lvc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+ // not really public
+ void crtc_update_row(mc6845_device *device, bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 ma, UINT8 ra, UINT16 y, UINT8 x_count, INT8 cursor_x, void *param);
+ DECLARE_WRITE_LINE_MEMBER( vsync_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_wangpcbus_card_interface overrides
+ virtual UINT16 wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+ virtual UINT16 wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+
+private:
+ inline void set_irq(int state);
+
+ required_device<mc6845_device> m_crtc;
+ optional_shared_ptr<UINT16> m_video_ram;
+
+ rgb_t m_palette[16];
+ UINT8 m_option;
+ UINT16 m_scroll;
+ int m_irq;
+};
+
+
+// device type definition
+extern const device_type WANGPC_LVC;
+
+
+#endif
diff --git a/src/emu/bus/wangpc/mcc.c b/src/emu/bus/wangpc/mcc.c
new file mode 100644
index 00000000000..c496277af49
--- /dev/null
+++ b/src/emu/bus/wangpc/mcc.c
@@ -0,0 +1,320 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC-PM043 Multiport Communications Controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+/*
+
+ TODO:
+
+ - all
+
+*/
+
+#include "mcc.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+#define OPTION_ID 0x1f
+
+#define Z80SIO2_TAG "z80sio2"
+#define Z80DART_TAG "z80dart"
+
+#define FUNCTION_PORT1_EXT_CLK BIT(m_option, 0)
+#define FUNCTION_PORT1_NRZI BIT(m_option, 1)
+#define FUNCTION_PORT1_RI_IE BIT(m_option, 2)
+#define FUNCTION_PORT2_EXT_CLK BIT(m_option, 3)
+#define FUNCTION_PORT2_NRZI BIT(m_option, 4)
+#define FUNCTION_PORT2_RI_IE BIT(m_option, 5)
+#define FUNCTION_IRQ_MASK (m_option & 0xc0)
+#define FUNCTION_IRQ2 0x00
+#define FUNCTION_IRQ3 0x40
+#define FUNCTION_IRQ4 0x80
+#define FUNCTION_IRQ_INVALID 0xc0
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type WANGPC_MCC = &device_creator<wangpc_mcc_device>;
+
+
+//-------------------------------------------------
+// Z80SIO_INTERFACE( sio_intf )
+//-------------------------------------------------
+
+static Z80SIO_INTERFACE( sio_intf )
+{
+ 0, 0, 0, 0,
+
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+
+ DEVCB_NULL
+};
+
+
+//-------------------------------------------------
+// Z80DART_INTERFACE( dart_intf )
+//-------------------------------------------------
+
+static Z80DART_INTERFACE( dart_intf )
+{
+ 0, 0, 0, 0,
+
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+
+ DEVCB_NULL
+};
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( wangpc_mcc )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( wangpc_mcc )
+ MCFG_Z80SIO2_ADD(Z80SIO2_TAG, 4000000, sio_intf)
+ MCFG_Z80DART_ADD(Z80DART_TAG, 4000000, dart_intf)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor wangpc_mcc_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( wangpc_mcc );
+}
+
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+//-------------------------------------------------
+// set_irq -
+//-------------------------------------------------
+
+inline void wangpc_mcc_device::set_irq(int state)
+{
+ m_irq = state;
+
+ switch (FUNCTION_IRQ_MASK)
+ {
+ case FUNCTION_IRQ2: m_bus->irq2_w(m_irq); break;
+ case FUNCTION_IRQ3: m_bus->irq3_w(m_irq); break;
+ case FUNCTION_IRQ4: m_bus->irq4_w(m_irq); break;
+ }
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// wangpc_mcc_device - constructor
+//-------------------------------------------------
+
+wangpc_mcc_device::wangpc_mcc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, WANGPC_MCC, "Wang PC-PM043", tag, owner, clock, "wangpc_mcc", __FILE__),
+ device_wangpcbus_card_interface(mconfig, *this),
+ m_sio(*this, Z80SIO2_TAG),
+ m_dart(*this, Z80DART_TAG)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void wangpc_mcc_device::device_start()
+{
+ // state saving
+ save_item(NAME(m_option));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void wangpc_mcc_device::device_reset()
+{
+ m_option = 0;
+
+ set_irq(CLEAR_LINE);
+}
+
+
+//-------------------------------------------------
+// wangpcbus_iorc_r - I/O read
+//-------------------------------------------------
+
+UINT16 wangpc_mcc_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:
+ case 0x02/2:
+ case 0x04/2:
+ case 0x06/2:
+ if (ACCESSING_BITS_0_7)
+ {
+ data = 0xff00 | m_sio->cd_ba_r(space, offset >> 1);
+ }
+ break;
+
+ case 0x08/2:
+ case 0x0a/2:
+ case 0x0c/2:
+ case 0x0e/2:
+ if (ACCESSING_BITS_0_7)
+ {
+ data = 0xff00 | m_dart->cd_ba_r(space, offset >> 1);
+ }
+ break;
+
+ case 0x10/2:
+ // board status
+ /*
+
+ bit description
+
+ 0 SIO channel A WAIT/RDY
+ 1 SIO channel B WAIT/RDY
+ 2 SIO channel A DSR
+ 3 SIO channel B DSR
+ 4 SIO channel A RI
+ 5 SIO channel B RI
+ 6 DART channel A WAIT/RDY
+ 7 DART channel A DSR
+ 8 DART channel B WAIT/RDY
+ 9 0 (1 for PC-PM042)
+ 10 0 (1 for PC-PM042)
+ 11 0 (1 for PC-PM042)
+ 12 1
+ 13 1
+ 14 1
+ 15 1
+
+ */
+ data = 0xf000;
+ break;
+
+ case 0xfe/2:
+ data = 0xff00 | (m_irq << 7) | OPTION_ID;
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_aiowc_w - I/O write
+//-------------------------------------------------
+
+void wangpc_mcc_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 0x00/2:
+ case 0x02/2:
+ case 0x04/2:
+ case 0x06/2:
+ m_sio->cd_ba_w(space, offset >> 1, data & 0xff);
+ break;
+
+ case 0x08/2:
+ case 0x0a/2:
+ case 0x0c/2:
+ case 0x0e/2:
+ m_dart->cd_ba_w(space, offset >> 1, data & 0xff);
+ break;
+
+ case 0x12/2:
+ // port 1 baud rate
+ break;
+
+ case 0x14/2:
+ // port 2 baud rate
+ break;
+
+ case 0x16/2:
+ {
+ // ports 1 and 2 function
+ bool irq = (m_irq == ASSERT_LINE);
+ bool changed = (FUNCTION_IRQ_MASK != (data & 0xc0));
+
+ if (irq && changed) set_irq(CLEAR_LINE);
+
+ m_option = data & 0xff;
+
+ if (irq && changed) set_irq(ASSERT_LINE);
+ }
+ break;
+
+ case 0x18/2:
+ // port 3 channel A baud rate
+ break;
+
+ case 0x1a/2:
+ // port 3 channel B baud rate
+ break;
+
+ case 0xfc/2:
+ device_reset();
+ break;
+ }
+ }
+}
diff --git a/src/emu/bus/wangpc/mcc.h b/src/emu/bus/wangpc/mcc.h
new file mode 100644
index 00000000000..11efcc9417d
--- /dev/null
+++ b/src/emu/bus/wangpc/mcc.h
@@ -0,0 +1,63 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC-PM043 Multiport Communications Controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __WANGPC_MCC__
+#define __WANGPC_MCC__
+
+#include "emu.h"
+#include "wangpc.h"
+#include "machine/z80dart.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> wangpc_mcc_device
+
+class wangpc_mcc_device : public device_t,
+ public device_wangpcbus_card_interface
+{
+public:
+ // construction/destruction
+ wangpc_mcc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_wangpcbus_card_interface overrides
+ virtual UINT16 wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+
+private:
+ inline void set_irq(int state);
+
+ required_device<z80dart_device> m_sio;
+ required_device<z80dart_device> m_dart;
+
+ UINT8 m_option;
+ int m_irq;
+};
+
+
+// device type definition
+extern const device_type WANGPC_MCC;
+
+
+#endif
diff --git a/src/emu/bus/wangpc/mvc.c b/src/emu/bus/wangpc/mvc.c
new file mode 100644
index 00000000000..53d9e008a74
--- /dev/null
+++ b/src/emu/bus/wangpc/mvc.c
@@ -0,0 +1,354 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC PM-001B Medium-Resolution Video Controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+/*
+
+ TODO:
+
+ - character clock
+ - blink
+
+*/
+
+#include "mvc.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+#define OPTION_ID 0x15
+
+#define MC6845_TAG "mc6845"
+#define SCREEN_TAG "screen"
+
+#define VIDEO_RAM_SIZE 0x800
+#define CHAR_RAM_SIZE 0x1000
+#define BITMAP_RAM_SIZE 0x4000
+
+#define OPTION_VRAM BIT(m_option, 0)
+#define OPTION_VSYNC BIT(m_option, 3)
+
+#define ATTR_BLINK BIT(attr, 0)
+#define ATTR_REVERSE BIT(attr, 1)
+#define ATTR_BLANK BIT(attr, 2)
+#define ATTR_BOLD BIT(attr, 3)
+#define ATTR_OVERSCORE BIT(attr, 4)
+#define ATTR_UNDERSCORE BIT(attr, 5)
+#define ATTR_SUBSCRIPT BIT(attr, 6)
+#define ATTR_SUPERSCRIPT BIT(attr, 7)
+
+static const rgb_t PALETTE[] =
+{
+ RGB_BLACK,
+ MAKE_RGB(0x00, 0x80, 0x00),
+ MAKE_RGB(0x00, 0xff, 0x00)
+};
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type WANGPC_MVC = &device_creator<wangpc_mvc_device>;
+
+
+//-------------------------------------------------
+// mc6845_interface crtc_intf
+//-------------------------------------------------
+
+void wangpc_mvc_device::crtc_update_row(mc6845_device *device, bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 ma, UINT8 ra, UINT16 y, UINT8 x_count, INT8 cursor_x, void *param)
+{
+ for (int sx = 0; sx < 50; sx++)
+ {
+ offs_t addr = (y * 50) + sx;
+ UINT16 data = m_bitmap_ram[addr];
+
+ for (int bit = 0; bit < 16; bit++)
+ {
+ int x = (sx * 16) + bit;
+ int color = BIT(data, 15);
+
+ bitmap.pix32(y, x) = PALETTE[color];
+
+ data <<= 1;
+ }
+ }
+
+ for (int column = 0; column < x_count; column++)
+ {
+ UINT16 code = m_video_ram[((ma + column) & 0x7ff)];
+ UINT8 attr = code & 0xff;
+
+ UINT8 new_ra = ra + 1;
+
+ if (ATTR_SUPERSCRIPT)
+ {
+ new_ra = ra + 3;
+ }
+ else if (ATTR_SUBSCRIPT)
+ {
+ new_ra = ra;
+ }
+
+ offs_t addr = ((code >> 8) << 4) | (new_ra & 0x0f);
+ UINT16 data = m_char_ram[addr & 0xfff];
+
+ if ((column == cursor_x) || (!ra && ATTR_OVERSCORE) || ((ra == 9) && ATTR_UNDERSCORE))
+ {
+ data = 0xffff;
+ }
+
+ for (int bit = 0; bit < 10; bit++)
+ {
+ int x = (column * 10) + bit;
+ int color = ((BIT(data, 9) & !ATTR_BLANK) ^ ATTR_REVERSE);
+
+ if ((color | bitmap.pix32(y, x)) & ATTR_BOLD) color = 2;
+ if (color) bitmap.pix32(y, x) = PALETTE[color];
+
+ data <<= 1;
+ }
+ }
+}
+
+static MC6845_UPDATE_ROW( wangpc_mvc_update_row )
+{
+ wangpc_mvc_device *mvc = downcast<wangpc_mvc_device *>(device->owner());
+
+ mvc->crtc_update_row(device, bitmap, cliprect, ma, ra, y, x_count, cursor_x, param);
+}
+
+WRITE_LINE_MEMBER( wangpc_mvc_device::vsync_w )
+{
+ if (OPTION_VSYNC && state)
+ {
+ set_irq(ASSERT_LINE);
+ }
+}
+
+static MC6845_INTERFACE( crtc_intf )
+{
+ false,
+ 10,
+ NULL,
+ wangpc_mvc_update_row,
+ NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, wangpc_mvc_device, vsync_w),
+ NULL
+};
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( wangpc_mvc )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( wangpc_mvc )
+ MCFG_SCREEN_ADD(SCREEN_TAG, RASTER)
+ MCFG_SCREEN_UPDATE_DEVICE(MC6845_TAG, mc6845_device, screen_update)
+ MCFG_SCREEN_SIZE(80*10, 25*12)
+ MCFG_SCREEN_VISIBLE_AREA(0, 80*10-1, 0, 25*12-1)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
+ MCFG_SCREEN_REFRESH_RATE(60)
+
+ MCFG_MC6845_ADD(MC6845_TAG, MC6845_1, SCREEN_TAG, XTAL_14_31818MHz/16, crtc_intf)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor wangpc_mvc_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( wangpc_mvc );
+}
+
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+//-------------------------------------------------
+// set_irq -
+//-------------------------------------------------
+
+inline void wangpc_mvc_device::set_irq(int state)
+{
+ m_irq = state;
+
+ m_bus->irq3_w(m_irq);
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// wangpc_mvc_device - constructor
+//-------------------------------------------------
+
+wangpc_mvc_device::wangpc_mvc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, WANGPC_MVC, "Wang PC Medium Resolution Video Card", tag, owner, clock, "wangpc_mvc", __FILE__),
+ device_wangpcbus_card_interface(mconfig, *this),
+ m_crtc(*this, MC6845_TAG),
+ m_video_ram(*this, "video_ram"),
+ m_char_ram(*this, "char_ram"),
+ m_bitmap_ram(*this, "bitmap_ram"),
+ m_option(0),
+ m_irq(CLEAR_LINE)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void wangpc_mvc_device::device_start()
+{
+ // allocate memory
+ m_video_ram.allocate(VIDEO_RAM_SIZE);
+ m_char_ram.allocate(CHAR_RAM_SIZE);
+ m_bitmap_ram.allocate(BITMAP_RAM_SIZE);
+
+ // state saving
+ save_item(NAME(m_option));
+ save_item(NAME(m_irq));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void wangpc_mvc_device::device_reset()
+{
+ m_option = 0;
+
+ set_irq(CLEAR_LINE);
+}
+
+
+//-------------------------------------------------
+// wangpcbus_mrdc_r - memory read
+//-------------------------------------------------
+
+UINT16 wangpc_mvc_device::wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 data = 0xffff;
+
+ if (OPTION_VRAM)
+ {
+ if (offset >= 0xe0000/2 && offset < 0xe8000/2)
+ {
+ data = m_bitmap_ram[offset & 0x3fff];
+ }
+ else if (offset >= 0xf0000/2 && offset < 0xf1000/2)
+ {
+ data = m_video_ram[offset & 0x7ff];
+ }
+ else if (offset >= 0xf2000/2 && offset < 0xf4000/2)
+ {
+ data = m_char_ram[offset & 0xfff];
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_amwc_w - memory write
+//-------------------------------------------------
+
+void wangpc_mvc_device::wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
+{
+ if (OPTION_VRAM)
+ {
+ if (offset >= 0xe0000/2 && offset < 0xe8000/2)
+ {
+ m_bitmap_ram[offset & 0x3fff] = data;
+ }
+ else if (offset >= 0xf0000/2 && offset < 0xf1000/2)
+ {
+ m_video_ram[offset & 0x7ff] = data;
+ }
+ else if (offset >= 0xf2000/2 && offset < 0xf4000/2)
+ {
+ m_char_ram[offset & 0xfff] = data;
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// wangpcbus_iorc_r - I/O read
+//-------------------------------------------------
+
+UINT16 wangpc_mvc_device::wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 data = 0xffff;
+
+ if (sad(offset))
+ {
+ switch (offset & 0x7f)
+ {
+ case 0xfe/2:
+ data = 0xff00 | (m_irq << 7) | OPTION_ID;
+
+ set_irq(CLEAR_LINE);
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_aiowc_w - I/O write
+//-------------------------------------------------
+
+void wangpc_mvc_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 0x00/2:
+ m_crtc->address_w(space, 0, data & 0xff);
+ break;
+
+ case 0x02/2:
+ m_crtc->register_w(space, 0, data & 0xff);
+ break;
+
+ case 0x10/2:
+ case 0x12/2:
+ if (LOG) logerror("MVC option %02x\n", data & 0xff);
+
+ m_option = data & 0xff;
+ break;
+ }
+ }
+}
diff --git a/src/emu/bus/wangpc/mvc.h b/src/emu/bus/wangpc/mvc.h
new file mode 100644
index 00000000000..a5cde914559
--- /dev/null
+++ b/src/emu/bus/wangpc/mvc.h
@@ -0,0 +1,71 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC PM-001B Medium-Resolution Video Controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __WANGPC_MVC__
+#define __WANGPC_MVC__
+
+#include "emu.h"
+#include "wangpc.h"
+#include "video/mc6845.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> wangpc_mvc_device
+
+class wangpc_mvc_device : public device_t,
+ public device_wangpcbus_card_interface
+{
+public:
+ // construction/destruction
+ wangpc_mvc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+ // not really public
+ void crtc_update_row(mc6845_device *device, bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 ma, UINT8 ra, UINT16 y, UINT8 x_count, INT8 cursor_x, void *param);
+ DECLARE_WRITE_LINE_MEMBER( vsync_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_wangpcbus_card_interface overrides
+ virtual UINT16 wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+ virtual UINT16 wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+
+private:
+ inline void set_irq(int state);
+
+ required_device<mc6845_device> m_crtc;
+ optional_shared_ptr<UINT16> m_video_ram;
+ optional_shared_ptr<UINT16> m_char_ram;
+ optional_shared_ptr<UINT16> m_bitmap_ram;
+
+ UINT8 m_option;
+ int m_irq;
+};
+
+
+// device type definition
+extern const device_type WANGPC_MVC;
+
+
+#endif
diff --git a/src/emu/bus/wangpc/rtc.c b/src/emu/bus/wangpc/rtc.c
new file mode 100644
index 00000000000..bb8396589da
--- /dev/null
+++ b/src/emu/bus/wangpc/rtc.c
@@ -0,0 +1,353 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC-PM040-B Remote Telecommunication controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "rtc.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define OPTION_ID 0x1c
+
+#define Z80_TAG "z80"
+#define AM9517A_TAG "am9517"
+#define Z80CTC_0_TAG "z80ctc_0"
+#define Z80CTC_1_TAG "z80ctc_1"
+#define Z80SIO_TAG "z80sio"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type WANGPC_RTC = &device_creator<wangpc_rtc_device>;
+
+
+//-------------------------------------------------
+// ROM( wangpc_rtc )
+//-------------------------------------------------
+
+ROM_START( wangpc_rtc )
+ ROM_REGION( 0x1000, Z80_TAG, 0 )
+ ROM_LOAD( "remotecomms-l28.bin", 0x0000, 0x1000, CRC(c05a1bee) SHA1(6b3f0d787d014b1fd3925812c905ddb63c5055f1) )
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *wangpc_rtc_device::device_rom_region() const
+{
+ return ROM_NAME( wangpc_rtc );
+}
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( wangpc_rtc_mem )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( wangpc_rtc_mem, AS_PROGRAM, 8, wangpc_rtc_device )
+ AM_RANGE(0x0000, 0x0fff) AM_ROM AM_REGION(Z80_TAG, 0)
+ AM_RANGE(0x1000, 0xffff) AM_RAM
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( wangpc_rtc_io )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( wangpc_rtc_io, AS_IO, 8, wangpc_rtc_device )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x00, 0x03) AM_DEVREADWRITE(Z80SIO_TAG, z80sio0_device, cd_ba_r, cd_ba_w)
+ AM_RANGE(0x10, 0x1f) AM_DEVREADWRITE(AM9517A_TAG, am9517a_device, read, write)
+ AM_RANGE(0x20, 0x23) AM_DEVREADWRITE(Z80CTC_0_TAG, z80ctc_device, read, write)
+ AM_RANGE(0x30, 0x30) //AM_WRITE(clear_char_w)
+ AM_RANGE(0x31, 0x31) //AM_WRITE(set_char_w)
+ AM_RANGE(0x40, 0x40) AM_READ_PORT("SW1") //AM_WRITE(control_w)
+ AM_RANGE(0x44, 0x44) //AM_READ(i8086_status_r) AM_WRITE(reset_w)
+ AM_RANGE(0x48, 0x48) //AM_WRITE(dte_ready_w)
+ AM_RANGE(0x4c, 0x4c) //AM_READWRITE(8232_acu_r, 8232_acu_w)
+ AM_RANGE(0x50, 0x50) //AM_READ(outbound_data_r)
+ AM_RANGE(0x51, 0x52) //AM_WRITE(status_w)
+ AM_RANGE(0x54, 0x54) //AM_WRITE(enable_inbound_data_w)
+ AM_RANGE(0x51, 0x52) //AM_WRITE(inbound_data_w)
+ AM_RANGE(0x60, 0x63) AM_DEVREADWRITE(Z80CTC_1_TAG, z80ctc_device, read, write)
+ AM_RANGE(0x70, 0x70) //AM_READWRITE(led_toggle_r, odd_parity_w)
+ AM_RANGE(0x71, 0x71) //AM_WRITE(even_parity_w)
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// z80_daisy_config wangpc_rtc_daisy_chain
+//-------------------------------------------------
+
+static const z80_daisy_config wangpc_rtc_daisy_chain[] =
+{
+ { Z80SIO_TAG },
+ { Z80CTC_0_TAG },
+ { Z80CTC_1_TAG },
+ { NULL }
+};
+
+
+//-------------------------------------------------
+// I8237_INTERFACE( dmac_intf )
+//-------------------------------------------------
+
+static I8237_INTERFACE( dmac_intf )
+{
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ { DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL, },
+ { DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL, },
+ { DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL }
+};
+
+
+//-------------------------------------------------
+// Z80CTC_INTERFACE( ctc0_intf )
+//-------------------------------------------------
+
+static Z80CTC_INTERFACE( ctc0_intf )
+{
+ DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0),
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL
+};
+
+
+//-------------------------------------------------
+// Z80CTC_INTERFACE( ctc1_intf )
+//-------------------------------------------------
+
+static Z80CTC_INTERFACE( ctc1_intf )
+{
+ DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0),
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL
+};
+
+
+//-------------------------------------------------
+// Z80SIO_INTERFACE( sio_intf )
+//-------------------------------------------------
+
+static Z80SIO_INTERFACE( sio_intf )
+{
+ 0, 0, 0, 0,
+
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+
+ DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0)
+};
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( wangpc_rtc )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( wangpc_rtc )
+ MCFG_CPU_ADD(Z80_TAG, Z80, 2000000)
+ MCFG_CPU_CONFIG(wangpc_rtc_daisy_chain)
+ MCFG_CPU_PROGRAM_MAP(wangpc_rtc_mem)
+ MCFG_CPU_IO_MAP(wangpc_rtc_io)
+
+ MCFG_I8237_ADD(AM9517A_TAG, 2000000, dmac_intf)
+ MCFG_Z80CTC_ADD(Z80CTC_0_TAG, 2000000, ctc0_intf)
+ MCFG_Z80CTC_ADD(Z80CTC_1_TAG, 2000000, ctc1_intf)
+ MCFG_Z80SIO0_ADD(Z80SIO_TAG, 2000000, sio_intf)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor wangpc_rtc_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( wangpc_rtc );
+}
+
+
+//-------------------------------------------------
+// INPUT_PORTS( wangpc_rtc )
+//-------------------------------------------------
+
+INPUT_PORTS_START( wangpc_rtc )
+ PORT_START("SW1")
+ PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:1")
+ PORT_DIPSETTING( 0x01, DEF_STR( On ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:2")
+ PORT_DIPSETTING( 0x02, DEF_STR( On ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:3")
+ PORT_DIPSETTING( 0x04, DEF_STR( On ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:4")
+ PORT_DIPSETTING( 0x08, DEF_STR( On ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:5")
+ PORT_DIPSETTING( 0x10, DEF_STR( On ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:6")
+ PORT_DIPSETTING( 0x20, DEF_STR( On ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:7")
+ PORT_DIPSETTING( 0x40, DEF_STR( On ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:8")
+ PORT_DIPSETTING( 0x80, DEF_STR( On ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor wangpc_rtc_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( wangpc_rtc );
+}
+
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// wangpc_rtc_device - constructor
+//-------------------------------------------------
+
+wangpc_rtc_device::wangpc_rtc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, WANGPC_RTC, "Wang PC-PM040-B", tag, owner, clock, "wangpc_rtc", __FILE__),
+ device_wangpcbus_card_interface(mconfig, *this),
+ m_maincpu(*this, Z80_TAG),
+ m_dmac(*this, AM9517A_TAG),
+ m_ctc0(*this, Z80CTC_0_TAG),
+ m_ctc1(*this, Z80CTC_1_TAG),
+ m_sio(*this, Z80SIO_TAG),
+ m_char_ram(*this, "char_ram")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void wangpc_rtc_device::device_start()
+{
+ m_char_ram.allocate(0x100);
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void wangpc_rtc_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// wangpcbus_mrdc_r - memory read
+//-------------------------------------------------
+
+UINT16 wangpc_rtc_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_rtc_device::wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
+{
+}
+
+
+//-------------------------------------------------
+// wangpcbus_iorc_r - I/O read
+//-------------------------------------------------
+
+UINT16 wangpc_rtc_device::wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 data = 0xffff;
+
+ if (sad(offset))
+ {
+ switch (offset & 0x7f)
+ {
+ case 0xfe/2:
+ data = 0xff00 | OPTION_ID;
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_aiowc_w - I/O write
+//-------------------------------------------------
+
+void wangpc_rtc_device::wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data)
+{
+ if (sad(offset))
+ {
+ switch (offset & 0x7f)
+ {
+ case 0xfc/2:
+ device_reset();
+ break;
+ }
+ }
+}
diff --git a/src/emu/bus/wangpc/rtc.h b/src/emu/bus/wangpc/rtc.h
new file mode 100644
index 00000000000..46c04e6ff6a
--- /dev/null
+++ b/src/emu/bus/wangpc/rtc.h
@@ -0,0 +1,69 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC-PM040-B Remote Telecommunication controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __WANGPC_RTC__
+#define __WANGPC_RTC__
+
+#include "emu.h"
+#include "wangpc.h"
+#include "cpu/z80/z80.h"
+#include "machine/am9517a.h"
+#include "machine/z80ctc.h"
+#include "machine/z80dart.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> wangpc_rtc_device
+
+class wangpc_rtc_device : public device_t,
+ public device_wangpcbus_card_interface
+{
+public:
+ // construction/destruction
+ wangpc_rtc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+ virtual ioport_constructor device_input_ports() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_wangpcbus_card_interface overrides
+ virtual UINT16 wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+ virtual UINT16 wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+
+private:
+ required_device<cpu_device> m_maincpu;
+ required_device<am9517a_device> m_dmac;
+ required_device<z80ctc_device> m_ctc0;
+ required_device<z80ctc_device> m_ctc1;
+ required_device<z80dart_device> m_sio;
+ optional_shared_ptr<UINT8> m_char_ram;
+};
+
+
+// device type definition
+extern const device_type WANGPC_RTC;
+
+
+#endif
diff --git a/src/emu/bus/wangpc/tig.c b/src/emu/bus/wangpc/tig.c
new file mode 100644
index 00000000000..55b1bdb7c9e
--- /dev/null
+++ b/src/emu/bus/wangpc/tig.c
@@ -0,0 +1,342 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC Text/Image/Graphics controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+/*
+
+ TODO:
+
+ - all
+
+*/
+
+#include "tig.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define LOG 1
+
+#define OPTION_ID_0 0x13
+#define OPTION_ID_1 0x17
+
+#define UPD7720_0_TAG "upd7220_0"
+#define UPD7720_1_TAG "upd7220_1"
+#define SCREEN_TAG "screen"
+
+#define DMA_GRAPHICS BIT(m_option, 0)
+#define DMA_DREQ1 BIT(m_option, 1)
+#define DMA_DREQ2 BIT(m_option, 2)
+#define DMA_DREQ3 BIT(m_option, 3)
+#define DMA_ID BIT(m_option, 4)
+
+#define ATTR_ALT_FONT BIT(data, 8)
+#define ATTR_UNDERSCORE BIT(data, 9)
+#define ATTR_BLINK BIT(data, 10)
+#define ATTR_REVERSE BIT(data, 11)
+#define ATTR_BLANK BIT(data, 12)
+#define ATTR_BOLD BIT(data, 13)
+#define ATTR_SUBSCRIPT BIT(data, 14)
+#define ATTR_SUPERSCRIPT BIT(data, 15)
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type WANGPC_TIG = &device_creator<wangpc_tig_device>;
+
+
+//-------------------------------------------------
+// ROM( wangpc_tig )
+//-------------------------------------------------
+
+ROM_START( wangpc_tig )
+ ROM_REGION( 0x100, "plds", 0 )
+ ROM_LOAD( "377-3072.l26", 0x000, 0x100, NO_DUMP ) // PAL10L8
+ ROM_LOAD( "377-3073.l16", 0x000, 0x100, NO_DUMP ) // PAL10L8
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *wangpc_tig_device::device_rom_region() const
+{
+ return ROM_NAME( wangpc_tig );
+}
+
+
+//-------------------------------------------------
+// UPD7220_INTERFACE( hgdc0_intf )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( upd7220_0_map, AS_0, 8, wangpc_tig_device )
+ ADDRESS_MAP_GLOBAL_MASK(0x7fff)
+ AM_RANGE(0x0000, 0x0fff) AM_MIRROR(0x1000) AM_RAM // frame buffer
+ AM_RANGE(0x4000, 0x7fff) AM_RAM // font memory
+ADDRESS_MAP_END
+
+static UPD7220_DRAW_TEXT_LINE( hgdc_display_text)
+{
+}
+
+static UPD7220_INTERFACE( hgdc0_intf )
+{
+ NULL,
+ hgdc_display_text,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL
+};
+
+
+//-------------------------------------------------
+// UPD7220_INTERFACE( hgdc1_intf )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( upd7220_1_map, AS_0, 8, wangpc_tig_device )
+ ADDRESS_MAP_GLOBAL_MASK(0xffff)
+ AM_RANGE(0x0000, 0xffff) AM_RAM // graphics memory
+ADDRESS_MAP_END
+
+static UPD7220_DISPLAY_PIXELS( hgdc_display_pixels )
+{
+}
+
+static UPD7220_INTERFACE( hgdc1_intf )
+{
+ hgdc_display_pixels,
+ NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL
+};
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( wangpc_tig )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( wangpc_tig )
+ MCFG_SCREEN_ADD(SCREEN_TAG, RASTER)
+ MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, wangpc_tig_device, screen_update)
+ MCFG_SCREEN_SIZE(80*10, 25*12)
+ MCFG_SCREEN_VISIBLE_AREA(0, 80*10-1, 0, 25*12-1)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
+ MCFG_SCREEN_REFRESH_RATE(60)
+
+ MCFG_PALETTE_LENGTH(3)
+
+ MCFG_UPD7220_ADD(UPD7720_0_TAG, XTAL_52_832MHz/28, hgdc0_intf, upd7220_0_map) // was /10?
+ MCFG_UPD7220_ADD(UPD7720_1_TAG, XTAL_52_832MHz/28, hgdc1_intf, upd7220_1_map) // was /16?
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor wangpc_tig_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( wangpc_tig );
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// wangpc_tig_device - constructor
+//-------------------------------------------------
+
+wangpc_tig_device::wangpc_tig_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, WANGPC_TIG, "Wang PC TIG Controller", tag, owner, clock, "wangpc_tig", __FILE__),
+ device_wangpcbus_card_interface(mconfig, *this),
+ m_hgdc0(*this, UPD7720_0_TAG),
+ m_hgdc1(*this, UPD7720_1_TAG),
+ m_option(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void wangpc_tig_device::device_start()
+{
+ // initialize palette
+ palette_set_color_rgb(machine(), 0, 0, 0, 0);
+ palette_set_color_rgb(machine(), 1, 0, 0x80, 0);
+ palette_set_color_rgb(machine(), 2, 0, 0xff, 0);
+
+ // state saving
+ save_item(NAME(m_option));
+ save_item(NAME(m_attr));
+ save_item(NAME(m_underline));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void wangpc_tig_device::device_reset()
+{
+ m_option = 0;
+}
+
+
+//-------------------------------------------------
+// screen_update -
+//-------------------------------------------------
+
+UINT32 wangpc_tig_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ m_hgdc0->screen_update(screen, bitmap, cliprect);
+ m_hgdc1->screen_update(screen, bitmap, cliprect);
+
+ return 0;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_iorc_r - I/O read
+//-------------------------------------------------
+
+UINT16 wangpc_tig_device::wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask)
+{
+ UINT16 data = 0xffff;
+
+ if (sad(offset))
+ {
+ switch (offset & 0x7f)
+ {
+ case 0x20/2:
+ case 0x22/2:
+ data = m_hgdc0->read(space, offset);
+ break;
+
+ case 0x24/2:
+ case 0x26/2:
+ data = m_hgdc1->read(space, offset);
+ break;
+
+ case 0xfe/2:
+ data = 0xff00 | (DMA_ID ? OPTION_ID_1 : OPTION_ID_0);
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_aiowc_w - I/O write
+//-------------------------------------------------
+
+void wangpc_tig_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 0x00/2: case 0x02/2: case 0x04/2: case 0x06/2: case 0x08/2: case 0x0a/2: case 0x0c/2: case 0x0e/2:
+ case 0x10/2: case 0x12/2: case 0x14/2: case 0x16/2: case 0x18/2: case 0x1a/2: case 0x1c/2: case 0x1e/2:
+ if (LOG) logerror("TIG attribute %u: %02x\n", offset, data & 0xff);
+
+ m_attr[offset] = data & 0xff;
+ break;
+
+ case 0x20/2:
+ case 0x22/2:
+ m_hgdc0->write(space, offset, data);
+ break;
+
+ case 0x24/2:
+ case 0x26/2:
+ m_hgdc1->write(space, offset, data);
+ break;
+
+ case 0x28/2:
+ if (LOG) logerror("TIG underline %02x\n", data & 0xff);
+
+ m_underline = data & 0xff;
+ break;
+
+ case 0x2a/2:
+ if (LOG) logerror("TIG option %02x\n", data & 0xff);
+
+ m_option = data & 0xff;
+ break;
+
+ case 0xfc/2:
+ device_reset();
+ break;
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// wangpcbus_dack_r - DMA read
+//-------------------------------------------------
+
+UINT8 wangpc_tig_device::wangpcbus_dack_r(address_space &space, int line)
+{
+ UINT8 data = 0;
+
+ if (DMA_GRAPHICS)
+ {
+ data = m_hgdc1->dack_r(space, 0);
+ }
+ else
+ {
+ data = m_hgdc0->dack_r(space, 0);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// wangpcbus_dack_w - DMA write
+//-------------------------------------------------
+
+void wangpc_tig_device::wangpcbus_dack_w(address_space &space, int line, UINT8 data)
+{
+ if (DMA_GRAPHICS)
+ {
+ m_hgdc1->dack_w(space, 0, data);
+ }
+ else
+ {
+ m_hgdc0->dack_w(space, 0, data);
+ }
+}
+
+
+//-------------------------------------------------
+// wangpcbus_have_dack - DMA acknowledge
+//-------------------------------------------------
+
+bool wangpc_tig_device::wangpcbus_have_dack(int line)
+{
+ return (line == 1 && DMA_DREQ1) || (line == 2 && DMA_DREQ2) || (line == 3 && DMA_DREQ3);
+}
diff --git a/src/emu/bus/wangpc/tig.h b/src/emu/bus/wangpc/tig.h
new file mode 100644
index 00000000000..ed92acb091c
--- /dev/null
+++ b/src/emu/bus/wangpc/tig.h
@@ -0,0 +1,68 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang PC PM-001B Medium-Resolution Video Controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __WANGPC_TIG__
+#define __WANGPC_TIG__
+
+#include "emu.h"
+#include "wangpc.h"
+#include "video/upd7220.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> wangpc_tig_device
+
+class wangpc_tig_device : public device_t,
+ public device_wangpcbus_card_interface
+{
+public:
+ // construction/destruction
+ wangpc_tig_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+ UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_wangpcbus_card_interface overrides
+ virtual UINT16 wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+ virtual UINT8 wangpcbus_dack_r(address_space &space, int line);
+ virtual void wangpcbus_dack_w(address_space &space, int line, UINT8 data);
+ virtual bool wangpcbus_have_dack(int line);
+
+private:
+ // internal state
+ required_device<upd7220_device> m_hgdc0;
+ required_device<upd7220_device> m_hgdc1;
+
+ UINT8 m_option;
+ UINT8 m_attr[16];
+ UINT8 m_underline;
+};
+
+
+// device type definition
+extern const device_type WANGPC_TIG;
+
+
+#endif
diff --git a/src/emu/bus/wangpc/wangpc.c b/src/emu/bus/wangpc/wangpc.c
new file mode 100644
index 00000000000..1b7fe913e6c
--- /dev/null
+++ b/src/emu/bus/wangpc/wangpc.c
@@ -0,0 +1,346 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang Professional Computer bus emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "emu.h"
+#include "emuopts.h"
+#include "wangpc.h"
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type WANGPC_BUS_SLOT = &device_creator<wangpcbus_slot_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// wangpcbus_slot_device - constructor
+//-------------------------------------------------
+
+wangpcbus_slot_device::wangpcbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, WANGPC_BUS_SLOT, "Wang PC bus slot", tag, owner, clock, "wangpcbus_slot", __FILE__),
+ device_slot_interface(mconfig, *this)
+{
+}
+
+void wangpcbus_slot_device::static_set_wangpcbus_slot(device_t &device, int sid)
+{
+ wangpcbus_slot_device &wangpcbus_card = dynamic_cast<wangpcbus_slot_device &>(device);
+ wangpcbus_card.m_sid = sid;
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void wangpcbus_slot_device::device_start()
+{
+ m_bus = machine().device<wangpcbus_device>(WANGPC_BUS_TAG);
+ device_wangpcbus_card_interface *dev = dynamic_cast<device_wangpcbus_card_interface *>(get_card_device());
+ if (dev) m_bus->add_wangpcbus_card(dev, m_sid);
+}
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type WANGPC_BUS = &device_creator<wangpcbus_device>;
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void wangpcbus_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const wangpcbus_interface *intf = reinterpret_cast<const wangpcbus_interface *>(static_config());
+ if (intf != NULL)
+ {
+ *static_cast<wangpcbus_interface *>(this) = *intf;
+ }
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_irq2_cb, 0, sizeof(m_out_irq2_cb));
+ memset(&m_out_irq3_cb, 0, sizeof(m_out_irq3_cb));
+ memset(&m_out_irq4_cb, 0, sizeof(m_out_irq4_cb));
+ memset(&m_out_irq5_cb, 0, sizeof(m_out_irq5_cb));
+ memset(&m_out_irq6_cb, 0, sizeof(m_out_irq6_cb));
+ memset(&m_out_irq7_cb, 0, sizeof(m_out_irq7_cb));
+ memset(&m_out_drq1_cb, 0, sizeof(m_out_drq1_cb));
+ memset(&m_out_drq2_cb, 0, sizeof(m_out_drq2_cb));
+ memset(&m_out_drq3_cb, 0, sizeof(m_out_drq3_cb));
+ memset(&m_out_ioerror_cb, 0, sizeof(m_out_ioerror_cb));
+ }
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// wangpcbus_device - constructor
+//-------------------------------------------------
+
+wangpcbus_device::wangpcbus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, WANGPC_BUS, "Wang PC bus", tag, owner, clock, "wangpcbus", __FILE__)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void wangpcbus_device::device_start()
+{
+ // resolve callbacks
+ m_out_irq2_func.resolve(m_out_irq2_cb, *this);
+ m_out_irq3_func.resolve(m_out_irq3_cb, *this);
+ m_out_irq4_func.resolve(m_out_irq4_cb, *this);
+ m_out_irq5_func.resolve(m_out_irq5_cb, *this);
+ m_out_irq6_func.resolve(m_out_irq6_cb, *this);
+ m_out_irq7_func.resolve(m_out_irq7_cb, *this);
+ m_out_drq1_func.resolve(m_out_drq1_cb, *this);
+ m_out_drq2_func.resolve(m_out_drq2_cb, *this);
+ m_out_drq3_func.resolve(m_out_drq3_cb, *this);
+ m_out_ioerror_func.resolve(m_out_ioerror_cb, *this);
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void wangpcbus_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// add_wangpcbus_card - add S100 card
+//-------------------------------------------------
+
+void wangpcbus_device::add_wangpcbus_card(device_wangpcbus_card_interface *card, int sid)
+{
+ m_device_list.append(*card);
+
+ card->m_bus = this;
+ card->m_sid = sid;
+}
+
+
+//-------------------------------------------------
+// mrdc_r - memory read
+//-------------------------------------------------
+
+READ16_MEMBER( wangpcbus_device::mrdc_r )
+{
+ UINT16 data = 0xffff;
+
+ device_wangpcbus_card_interface *entry = m_device_list.first();
+
+ while (entry)
+ {
+ data &= entry->wangpcbus_mrdc_r(space, offset + 0x40000/2, mem_mask);
+ entry = entry->next();
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// amwc_w - memory write
+//-------------------------------------------------
+
+WRITE16_MEMBER( wangpcbus_device::amwc_w )
+{
+ device_wangpcbus_card_interface *entry = m_device_list.first();
+
+ while (entry)
+ {
+ entry->wangpcbus_amwc_w(space, offset + 0x40000/2, mem_mask, data);
+ entry = entry->next();
+ }
+}
+
+
+//-------------------------------------------------
+// sad_r - I/O read
+//-------------------------------------------------
+
+READ16_MEMBER( wangpcbus_device::sad_r )
+{
+ UINT16 data = 0xffff;
+
+ device_wangpcbus_card_interface *entry = m_device_list.first();
+
+ while (entry)
+ {
+ data &= entry->wangpcbus_iorc_r(space, offset + 0x1100/2, mem_mask);
+ entry = entry->next();
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// sad_w - I/O write
+//-------------------------------------------------
+
+WRITE16_MEMBER( wangpcbus_device::sad_w )
+{
+ device_wangpcbus_card_interface *entry = m_device_list.first();
+
+ while (entry)
+ {
+ entry->wangpcbus_aiowc_w(space, offset + 0x1100/2, mem_mask, data);
+ entry = entry->next();
+ }
+}
+
+
+WRITE_LINE_MEMBER( wangpcbus_device::irq2_w ) { m_out_irq2_func(state); }
+WRITE_LINE_MEMBER( wangpcbus_device::irq3_w ) { m_out_irq3_func(state); }
+WRITE_LINE_MEMBER( wangpcbus_device::irq4_w ) { m_out_irq4_func(state); }
+WRITE_LINE_MEMBER( wangpcbus_device::irq5_w ) { m_out_irq5_func(state); }
+WRITE_LINE_MEMBER( wangpcbus_device::irq6_w ) { m_out_irq6_func(state); }
+WRITE_LINE_MEMBER( wangpcbus_device::irq7_w ) { m_out_irq7_func(state); }
+WRITE_LINE_MEMBER( wangpcbus_device::drq1_w ) { m_out_drq1_func(state); }
+WRITE_LINE_MEMBER( wangpcbus_device::drq2_w ) { m_out_drq2_func(state); }
+WRITE_LINE_MEMBER( wangpcbus_device::drq3_w ) { m_out_drq3_func(state); }
+WRITE_LINE_MEMBER( wangpcbus_device::ioerror_w ) { m_out_ioerror_func(state); }
+
+
+//-------------------------------------------------
+// dack_r - DMA read
+//-------------------------------------------------
+
+UINT8 wangpcbus_device::dack_r(address_space &space, int line)
+{
+ UINT8 retVal = 0xff;
+ device_wangpcbus_card_interface *entry = m_device_list.first();
+
+ while (entry)
+ {
+ if (entry->wangpcbus_have_dack(line))
+ {
+ retVal = entry->wangpcbus_dack_r(space, line);
+ break;
+ }
+
+ entry = entry->next();
+ }
+
+ return retVal;
+}
+
+
+//-------------------------------------------------
+// dack_w - DMA write
+//-------------------------------------------------
+
+void wangpcbus_device::dack_w(address_space &space, int line, UINT8 data)
+{
+ device_wangpcbus_card_interface *entry = m_device_list.first();
+
+ while (entry)
+ {
+ if (entry->wangpcbus_have_dack(line))
+ {
+ entry->wangpcbus_dack_w(space, line, data);
+ }
+
+ entry = entry->next();
+ }
+}
+
+READ8_MEMBER( wangpcbus_device::dack0_r ) { return dack_r(space, 0); }
+WRITE8_MEMBER( wangpcbus_device::dack0_w ) { dack_w(space, 0, data); }
+READ8_MEMBER( wangpcbus_device::dack1_r ) { return dack_r(space, 1); }
+WRITE8_MEMBER( wangpcbus_device::dack1_w ) { dack_w(space, 1, data); }
+READ8_MEMBER( wangpcbus_device::dack2_r ) { return dack_r(space, 2); }
+WRITE8_MEMBER( wangpcbus_device::dack2_w ) { dack_w(space, 2, data); }
+READ8_MEMBER( wangpcbus_device::dack3_r ) { return dack_r(space, 3); }
+WRITE8_MEMBER( wangpcbus_device::dack3_w ) { dack_w(space, 3, data); }
+
+
+//-------------------------------------------------
+// tc_w - terminal count
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( wangpcbus_device::tc_w )
+{
+ device_wangpcbus_card_interface *entry = m_device_list.first();
+
+ while (entry)
+ {
+ entry->wangpcbus_tc_w(state);
+ entry = entry->next();
+ }
+}
+
+
+
+//**************************************************************************
+// DEVICE WANG PC BUS CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_wangpcbus_card_interface - constructor
+//-------------------------------------------------
+
+device_wangpcbus_card_interface::device_wangpcbus_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device)
+{
+ m_slot = dynamic_cast<wangpcbus_slot_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_wangpcbus_card_interface - destructor
+//-------------------------------------------------
+
+device_wangpcbus_card_interface::~device_wangpcbus_card_interface()
+{
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( wangpc_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( wangpc_cards )
+ SLOT_INTERFACE("emb", WANGPC_EMB) // extended memory board
+ SLOT_INTERFACE("lic", WANGPC_LIC) // local interconnect option card
+ SLOT_INTERFACE("lvc", WANGPC_LVC) // low-resolution video controller
+ SLOT_INTERFACE("mcc", WANGPC_MCC) // multiport communications controller
+ SLOT_INTERFACE("mvc", WANGPC_MVC) // medium-resolution video controller
+ SLOT_INTERFACE("rtc", WANGPC_RTC) // remote telecommunications controller
+ SLOT_INTERFACE("tig", WANGPC_TIG) // text/image/graphics controller
+ SLOT_INTERFACE("wdc", WANGPC_WDC) // Winchester disk controller
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/wangpc/wangpc.h b/src/emu/bus/wangpc/wangpc.h
new file mode 100644
index 00000000000..45e8ab79033
--- /dev/null
+++ b/src/emu/bus/wangpc/wangpc.h
@@ -0,0 +1,224 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Wang Professional Computer bus emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __WANGPC_BUS__
+#define __WANGPC_BUS__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define WANGPC_BUS_TAG "wangpcbus"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_WANGPC_BUS_ADD(_config) \
+ MCFG_DEVICE_ADD(WANGPC_BUS_TAG, WANGPC_BUS, 0) \
+ MCFG_DEVICE_CONFIG(_config)
+
+
+#define WANGPC_BUS_INTERFACE(_name) \
+ const wangpcbus_interface (_name) =
+
+
+#define MCFG_WANGPC_BUS_SLOT_ADD(_tag, _sid, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, WANGPC_BUS_SLOT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
+ wangpcbus_slot_device::static_set_wangpcbus_slot(*device, _sid);
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> wangpcbus_slot_device
+
+class wangpcbus_device;
+
+class wangpcbus_slot_device : public device_t,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ wangpcbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual void device_start();
+
+ // inline configuration
+ static void static_set_wangpcbus_slot(device_t &device, int sid);
+
+private:
+ // configuration
+ wangpcbus_device *m_bus;
+ int m_sid;
+};
+
+
+// device type definition
+extern const device_type WANGPC_BUS_SLOT;
+
+
+// ======================> wangpcbus_interface
+
+struct wangpcbus_interface
+{
+ devcb_write_line m_out_irq2_cb;
+ devcb_write_line m_out_irq3_cb;
+ devcb_write_line m_out_irq4_cb;
+ devcb_write_line m_out_irq5_cb;
+ devcb_write_line m_out_irq6_cb;
+ devcb_write_line m_out_irq7_cb;
+ devcb_write_line m_out_drq1_cb;
+ devcb_write_line m_out_drq2_cb;
+ devcb_write_line m_out_drq3_cb;
+ devcb_write_line m_out_ioerror_cb;
+};
+
+class device_wangpcbus_card_interface;
+
+
+// ======================> wangpcbus_device
+
+class wangpcbus_device : public device_t,
+ public wangpcbus_interface
+{
+public:
+ // construction/destruction
+ wangpcbus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ void add_wangpcbus_card(device_wangpcbus_card_interface *card, int sid);
+
+ // computer interface
+ DECLARE_READ16_MEMBER( mrdc_r );
+ DECLARE_WRITE16_MEMBER( amwc_w );
+
+ DECLARE_READ16_MEMBER( sad_r );
+ DECLARE_WRITE16_MEMBER( sad_w );
+
+ UINT8 dack_r(address_space &space, int line);
+ void dack_w(address_space &space, int line, UINT8 data);
+
+ DECLARE_READ8_MEMBER( dack0_r );
+ DECLARE_WRITE8_MEMBER( dack0_w );
+ DECLARE_READ8_MEMBER( dack1_r );
+ DECLARE_WRITE8_MEMBER( dack1_w );
+ DECLARE_READ8_MEMBER( dack2_r );
+ DECLARE_WRITE8_MEMBER( dack2_w );
+ DECLARE_READ8_MEMBER( dack3_r );
+ DECLARE_WRITE8_MEMBER( dack3_w );
+
+ DECLARE_WRITE_LINE_MEMBER( tc_w );
+
+ // peripheral interface
+ DECLARE_WRITE_LINE_MEMBER( irq2_w );
+ DECLARE_WRITE_LINE_MEMBER( irq3_w );
+ DECLARE_WRITE_LINE_MEMBER( irq4_w );
+ DECLARE_WRITE_LINE_MEMBER( irq5_w );
+ DECLARE_WRITE_LINE_MEMBER( irq6_w );
+ DECLARE_WRITE_LINE_MEMBER( irq7_w );
+ DECLARE_WRITE_LINE_MEMBER( drq1_w );
+ DECLARE_WRITE_LINE_MEMBER( drq2_w );
+ DECLARE_WRITE_LINE_MEMBER( drq3_w );
+ DECLARE_WRITE_LINE_MEMBER( ioerror_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+ virtual void device_config_complete();
+
+private:
+ devcb_resolved_write_line m_out_irq2_func;
+ devcb_resolved_write_line m_out_irq3_func;
+ devcb_resolved_write_line m_out_irq4_func;
+ devcb_resolved_write_line m_out_irq5_func;
+ devcb_resolved_write_line m_out_irq6_func;
+ devcb_resolved_write_line m_out_irq7_func;
+ devcb_resolved_write_line m_out_drq1_func;
+ devcb_resolved_write_line m_out_drq2_func;
+ devcb_resolved_write_line m_out_drq3_func;
+ devcb_resolved_write_line m_out_ioerror_func;
+
+ simple_list<device_wangpcbus_card_interface> m_device_list;
+};
+
+
+// device type definition
+extern const device_type WANGPC_BUS;
+
+
+// ======================> device_wangpcbus_card_interface
+
+// class representing interface-specific live wangpcbus card
+class device_wangpcbus_card_interface : public device_slot_card_interface
+{
+ friend class wangpcbus_device;
+
+public:
+ // construction/destruction
+ device_wangpcbus_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_wangpcbus_card_interface();
+
+ device_wangpcbus_card_interface *next() const { return m_next; }
+
+ // memory access
+ virtual UINT16 wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask) { return 0; };
+ virtual void wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data) { };
+
+ // I/O access
+ virtual UINT16 wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask) { return 0; };
+ virtual void wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data) { };
+ bool sad(offs_t offset) { return ((offset & 0xf80) == (0x800 | (m_sid << 7))) ? true : false; }
+
+ // DMA
+ virtual UINT8 wangpcbus_dack_r(address_space &space, int line) { return 0; }
+ virtual void wangpcbus_dack_w(address_space &space, int line, UINT8 data) { }
+ virtual void wangpcbus_tc_w(int state) { }
+ virtual bool wangpcbus_have_dack(int line) { return false; }
+
+ wangpcbus_device *m_bus;
+ wangpcbus_slot_device *m_slot;
+
+ int m_sid;
+ device_wangpcbus_card_interface *m_next;
+};
+
+
+// slot devices
+#include "emb.h"
+#include "lic.h"
+#include "lvc.h"
+#include "mcc.h"
+#include "mvc.h"
+#include "rtc.h"
+#include "tig.h"
+#include "wdc.h"
+
+SLOT_INTERFACE_EXTERN( wangpc_cards );
+
+
+
+#endif
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); };
diff --git a/src/emu/bus/wangpc/wdc.h b/src/emu/bus/wangpc/wdc.h
new file mode 100644
index 00000000000..ac0dab4f125
--- /dev/null
+++ b/src/emu/bus/wangpc/wdc.h
@@ -0,0 +1,84 @@
+// 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.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __WANGPC_WDC__
+#define __WANGPC_WDC__
+
+#include "emu.h"
+#include "wangpc.h"
+#include "cpu/z80/z80.h"
+#include "imagedev/harddriv.h"
+#include "machine/z80ctc.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> wangpc_wdc_device
+
+class wangpc_wdc_device : public device_t,
+ public device_wangpcbus_card_interface
+{
+public:
+ // construction/destruction
+ wangpc_wdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+ // not really public
+ DECLARE_READ8_MEMBER( port_r );
+ DECLARE_WRITE8_MEMBER( status_w );
+ DECLARE_READ8_MEMBER( ctc_ch0_r );
+ DECLARE_WRITE8_MEMBER( ctc_ch0_w );
+ DECLARE_READ8_MEMBER( ctc_ch1_r );
+ DECLARE_WRITE8_MEMBER( ctc_ch1_w );
+ DECLARE_READ8_MEMBER( ctc_ch2_r );
+ DECLARE_WRITE8_MEMBER( ctc_ch2_w );
+ DECLARE_READ8_MEMBER( ctc_ch3_r );
+ DECLARE_WRITE8_MEMBER( ctc_ch3_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_wangpcbus_card_interface overrides
+ virtual UINT16 wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+ virtual UINT16 wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask);
+ virtual void wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data);
+ virtual UINT8 wangpcbus_dack_r(address_space &space, int line);
+ virtual void wangpcbus_dack_w(address_space &space, int line, UINT8 data);
+ virtual bool wangpcbus_have_dack(int line);
+
+private:
+ inline void set_irq(int state);
+
+ required_device<cpu_device> m_maincpu;
+ required_device<z80ctc_device> m_ctc;
+
+ UINT8 m_status;
+ UINT8 m_option;
+ int m_irq;
+};
+
+
+// device type definition
+extern const device_type WANGPC_WDC;
+
+
+#endif