diff options
Diffstat (limited to 'src/emu/bus')
-rw-r--r-- | src/emu/bus/bus.mak | 18 | ||||
-rw-r--r-- | src/emu/bus/wangpc/emb.c | 178 | ||||
-rw-r--r-- | src/emu/bus/wangpc/emb.h | 58 | ||||
-rw-r--r-- | src/emu/bus/wangpc/lic.c | 162 | ||||
-rw-r--r-- | src/emu/bus/wangpc/lic.h | 56 | ||||
-rw-r--r-- | src/emu/bus/wangpc/lvc.c | 361 | ||||
-rw-r--r-- | src/emu/bus/wangpc/lvc.h | 71 | ||||
-rw-r--r-- | src/emu/bus/wangpc/mcc.c | 320 | ||||
-rw-r--r-- | src/emu/bus/wangpc/mcc.h | 63 | ||||
-rw-r--r-- | src/emu/bus/wangpc/mvc.c | 354 | ||||
-rw-r--r-- | src/emu/bus/wangpc/mvc.h | 71 | ||||
-rw-r--r-- | src/emu/bus/wangpc/rtc.c | 353 | ||||
-rw-r--r-- | src/emu/bus/wangpc/rtc.h | 69 | ||||
-rw-r--r-- | src/emu/bus/wangpc/tig.c | 342 | ||||
-rw-r--r-- | src/emu/bus/wangpc/tig.h | 68 | ||||
-rw-r--r-- | src/emu/bus/wangpc/wangpc.c | 346 | ||||
-rw-r--r-- | src/emu/bus/wangpc/wangpc.h | 224 | ||||
-rw-r--r-- | src/emu/bus/wangpc/wdc.c | 357 | ||||
-rw-r--r-- | src/emu/bus/wangpc/wdc.h | 84 |
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 |