src/mess/machine/wangpc_tig.c
| r0 | r15422 | |
| 1 | /********************************************************************** |
| 2 | |
| 3 | Wang PC Text/Image/Graphics controller emulation |
| 4 | |
| 5 | Copyright MESS Team. |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. |
| 7 | |
| 8 | **********************************************************************/ |
| 9 | |
| 10 | /* |
| 11 | |
| 12 | TODO: |
| 13 | |
| 14 | - all |
| 15 | |
| 16 | */ |
| 17 | |
| 18 | #include "wangpc_tig.h" |
| 19 | |
| 20 | |
| 21 | |
| 22 | //************************************************************************** |
| 23 | // MACROS/CONSTANTS |
| 24 | //************************************************************************** |
| 25 | |
| 26 | #define LOG 1 |
| 27 | |
| 28 | #define OPTION_ID_0 0x13 |
| 29 | #define OPTION_ID_1 0x17 |
| 30 | |
| 31 | #define UPD7720_0_TAG "upd7220_0" |
| 32 | #define UPD7720_1_TAG "upd7220_1" |
| 33 | #define SCREEN_TAG "screen" |
| 34 | |
| 35 | #define DMA_GRAPHICS BIT(m_option, 0) |
| 36 | #define DMA_DREQ1 BIT(m_option, 1) |
| 37 | #define DMA_DREQ2 BIT(m_option, 2) |
| 38 | #define DMA_DREQ3 BIT(m_option, 3) |
| 39 | #define DMA_ID BIT(m_option, 4) |
| 40 | |
| 41 | |
| 42 | |
| 43 | //************************************************************************** |
| 44 | // DEVICE DEFINITIONS |
| 45 | //************************************************************************** |
| 46 | |
| 47 | const device_type WANGPC_TIG = &device_creator<wangpc_tig_device>; |
| 48 | |
| 49 | |
| 50 | //------------------------------------------------- |
| 51 | // UPD7220_INTERFACE( hgdc0_intf ) |
| 52 | //------------------------------------------------- |
| 53 | |
| 54 | static ADDRESS_MAP_START( upd7220_0_map, AS_0, 8, wangpc_tig_device ) |
| 55 | AM_RANGE(0x0000, 0x0fff) AM_MIRROR(0x1000) AM_RAM // frame buffer |
| 56 | AM_RANGE(0x4000, 0x7fff) AM_RAM // font memory |
| 57 | ADDRESS_MAP_END |
| 58 | |
| 59 | static UPD7220_DRAW_TEXT_LINE( hgdc_display_text) |
| 60 | { |
| 61 | } |
| 62 | |
| 63 | static UPD7220_INTERFACE( hgdc0_intf ) |
| 64 | { |
| 65 | SCREEN_TAG, |
| 66 | NULL, |
| 67 | hgdc_display_text, |
| 68 | DEVCB_NULL, |
| 69 | DEVCB_NULL, |
| 70 | DEVCB_NULL |
| 71 | }; |
| 72 | |
| 73 | |
| 74 | //------------------------------------------------- |
| 75 | // UPD7220_INTERFACE( hgdc1_intf ) |
| 76 | //------------------------------------------------- |
| 77 | |
| 78 | static ADDRESS_MAP_START( upd7220_1_map, AS_0, 8, wangpc_tig_device ) |
| 79 | AM_RANGE(0x0000, 0xffff) AM_RAM // graphics memory |
| 80 | ADDRESS_MAP_END |
| 81 | |
| 82 | static UPD7220_DISPLAY_PIXELS( hgdc_display_pixels ) |
| 83 | { |
| 84 | } |
| 85 | |
| 86 | static UPD7220_INTERFACE( hgdc1_intf ) |
| 87 | { |
| 88 | SCREEN_TAG, |
| 89 | hgdc_display_pixels, |
| 90 | NULL, |
| 91 | DEVCB_NULL, |
| 92 | DEVCB_NULL, |
| 93 | DEVCB_NULL |
| 94 | }; |
| 95 | |
| 96 | |
| 97 | //------------------------------------------------- |
| 98 | // MACHINE_CONFIG_FRAGMENT( wangpc_tig ) |
| 99 | //------------------------------------------------- |
| 100 | |
| 101 | static MACHINE_CONFIG_FRAGMENT( wangpc_tig ) |
| 102 | MCFG_SCREEN_ADD(SCREEN_TAG, RASTER) |
| 103 | MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, wangpc_tig_device, screen_update) |
| 104 | MCFG_SCREEN_SIZE(80*10, 25*12) |
| 105 | MCFG_SCREEN_VISIBLE_AREA(0, 80*10-1, 0, 25*12-1) |
| 106 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) |
| 107 | MCFG_SCREEN_REFRESH_RATE(60) |
| 108 | |
| 109 | MCFG_PALETTE_LENGTH(2) |
| 110 | MCFG_PALETTE_INIT(monochrome_green) |
| 111 | |
| 112 | MCFG_UPD7220_ADD(UPD7720_0_TAG, 4000000, hgdc0_intf, upd7220_0_map) |
| 113 | MCFG_UPD7220_ADD(UPD7720_1_TAG, 4000000, hgdc1_intf, upd7220_1_map) |
| 114 | MACHINE_CONFIG_END |
| 115 | |
| 116 | |
| 117 | //------------------------------------------------- |
| 118 | // machine_config_additions - device-specific |
| 119 | // machine configurations |
| 120 | //------------------------------------------------- |
| 121 | |
| 122 | machine_config_constructor wangpc_tig_device::device_mconfig_additions() const |
| 123 | { |
| 124 | return MACHINE_CONFIG_NAME( wangpc_tig ); |
| 125 | } |
| 126 | |
| 127 | |
| 128 | //************************************************************************** |
| 129 | // LIVE DEVICE |
| 130 | //************************************************************************** |
| 131 | |
| 132 | //------------------------------------------------- |
| 133 | // wangpc_tig_device - constructor |
| 134 | //------------------------------------------------- |
| 135 | |
| 136 | wangpc_tig_device::wangpc_tig_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 137 | device_t(mconfig, WANGPC_TIG, "Wang PC TIG Controller", tag, owner, clock), |
| 138 | device_wangpcbus_card_interface(mconfig, *this), |
| 139 | m_hgdc0(*this, UPD7720_0_TAG), |
| 140 | m_hgdc1(*this, UPD7720_1_TAG), |
| 141 | m_option(0) |
| 142 | { |
| 143 | } |
| 144 | |
| 145 | |
| 146 | //------------------------------------------------- |
| 147 | // device_start - device-specific startup |
| 148 | //------------------------------------------------- |
| 149 | |
| 150 | void wangpc_tig_device::device_start() |
| 151 | { |
| 152 | } |
| 153 | |
| 154 | |
| 155 | //------------------------------------------------- |
| 156 | // device_reset - device-specific reset |
| 157 | //------------------------------------------------- |
| 158 | |
| 159 | void wangpc_tig_device::device_reset() |
| 160 | { |
| 161 | m_option = 0; |
| 162 | } |
| 163 | |
| 164 | |
| 165 | //------------------------------------------------- |
| 166 | // screen_update - |
| 167 | //------------------------------------------------- |
| 168 | |
| 169 | UINT32 wangpc_tig_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 170 | { |
| 171 | m_hgdc0->screen_update(screen, bitmap, cliprect); |
| 172 | m_hgdc1->screen_update(screen, bitmap, cliprect); |
| 173 | |
| 174 | return 0; |
| 175 | } |
| 176 | |
| 177 | |
| 178 | //------------------------------------------------- |
| 179 | // wangpcbus_iorc_r - I/O read |
| 180 | //------------------------------------------------- |
| 181 | |
| 182 | UINT16 wangpc_tig_device::wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask) |
| 183 | { |
| 184 | UINT16 data = 0xffff; |
| 185 | |
| 186 | if (sad(offset)) |
| 187 | { |
| 188 | switch (offset & 0x7f) |
| 189 | { |
| 190 | case 0x20/2: |
| 191 | case 0x22/2: |
| 192 | data = m_hgdc0->read(space, offset); |
| 193 | break; |
| 194 | |
| 195 | case 0x24/2: |
| 196 | case 0x26/2: |
| 197 | data = m_hgdc1->read(space, offset); |
| 198 | break; |
| 199 | |
| 200 | case 0xfe/2: |
| 201 | data = 0xff00 | DMA_ID ? OPTION_ID_1 : OPTION_ID_0; |
| 202 | break; |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | return data; |
| 207 | } |
| 208 | |
| 209 | |
| 210 | //------------------------------------------------- |
| 211 | // wangpcbus_aiowc_w - I/O write |
| 212 | //------------------------------------------------- |
| 213 | |
| 214 | void wangpc_tig_device::wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data) |
| 215 | { |
| 216 | if (sad(offset) && ACCESSING_BITS_0_7) |
| 217 | { |
| 218 | switch (offset & 0x7f) |
| 219 | { |
| 220 | case 0x00/2: case 0x02/2: case 0x04/2: case 0x06/2: case 0x08/2: case 0x0a/2: case 0x0c/2: case 0x0e/2: |
| 221 | case 0x10/2: case 0x12/2: case 0x14/2: case 0x16/2: case 0x18/2: case 0x1a/2: case 0x1c/2: case 0x1e/2: |
| 222 | if (LOG) logerror("TIG attribute %u: %02x\n", offset, data & 0xff); |
| 223 | |
| 224 | m_attr[offset] = data & 0xff; |
| 225 | break; |
| 226 | |
| 227 | case 0x20/2: |
| 228 | case 0x22/2: |
| 229 | m_hgdc0->write(space, offset, data); |
| 230 | break; |
| 231 | |
| 232 | case 0x24/2: |
| 233 | case 0x26/2: |
| 234 | m_hgdc1->write(space, offset, data); |
| 235 | break; |
| 236 | |
| 237 | case 0x28/2: |
| 238 | if (LOG) logerror("TIG underline %02x\n", data & 0xff); |
| 239 | |
| 240 | m_underline = data & 0xff; |
| 241 | break; |
| 242 | |
| 243 | case 0x2a/2: |
| 244 | if (LOG) logerror("TIG option %02x\n", data & 0xff); |
| 245 | |
| 246 | m_option = data & 0xff; |
| 247 | break; |
| 248 | |
| 249 | case 0xfc/2: |
| 250 | device_reset(); |
| 251 | break; |
| 252 | } |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | |
| 257 | //------------------------------------------------- |
| 258 | // wangpcbus_dack_r - DMA read |
| 259 | //------------------------------------------------- |
| 260 | |
| 261 | UINT8 wangpc_tig_device::wangpcbus_dack_r(address_space &space, int line) |
| 262 | { |
| 263 | UINT8 data = 0; |
| 264 | |
| 265 | if (DMA_GRAPHICS) |
| 266 | { |
| 267 | data = m_hgdc1->dack_r(space, 0); |
| 268 | } |
| 269 | else |
| 270 | { |
| 271 | data = m_hgdc0->dack_r(space, 0); |
| 272 | } |
| 273 | |
| 274 | return data; |
| 275 | } |
| 276 | |
| 277 | |
| 278 | //------------------------------------------------- |
| 279 | // wangpcbus_dack_w - DMA write |
| 280 | //------------------------------------------------- |
| 281 | |
| 282 | void wangpc_tig_device::wangpcbus_dack_w(address_space &space, int line, UINT8 data) |
| 283 | { |
| 284 | if (DMA_GRAPHICS) |
| 285 | { |
| 286 | m_hgdc1->dack_w(space, 0, data); |
| 287 | } |
| 288 | else |
| 289 | { |
| 290 | m_hgdc0->dack_w(space, 0, data); |
| 291 | } |
| 292 | } |
| 293 | |
| 294 | |
| 295 | //------------------------------------------------- |
| 296 | // wangpcbus_have_dack - DMA acknowledge |
| 297 | //------------------------------------------------- |
| 298 | |
| 299 | bool wangpc_tig_device::wangpcbus_have_dack(int line) |
| 300 | { |
| 301 | return (line == 1 && DMA_DREQ1) || (line == 2 && DMA_DREQ2) || (line == 3 && DMA_DREQ3); |
| 302 | } |
src/mess/machine/wangpc_tig.h
| r0 | r15422 | |
| 1 | /********************************************************************** |
| 2 | |
| 3 | Wang PC PM-001B Medium-Resolution Video Controller emulation |
| 4 | |
| 5 | Copyright MESS Team. |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. |
| 7 | |
| 8 | **********************************************************************/ |
| 9 | |
| 10 | #pragma once |
| 11 | |
| 12 | #ifndef __WANGPC_TIG__ |
| 13 | #define __WANGPC_TIG__ |
| 14 | |
| 15 | |
| 16 | #include "emu.h" |
| 17 | #include "machine/wangpcbus.h" |
| 18 | #include "video/upd7220.h" |
| 19 | |
| 20 | |
| 21 | |
| 22 | //************************************************************************** |
| 23 | // TYPE DEFINITIONS |
| 24 | //************************************************************************** |
| 25 | |
| 26 | // ======================> wangpc_tig_device |
| 27 | |
| 28 | class wangpc_tig_device : public device_t, |
| 29 | public device_wangpcbus_card_interface |
| 30 | { |
| 31 | public: |
| 32 | // construction/destruction |
| 33 | wangpc_tig_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 34 | |
| 35 | // optional information overrides |
| 36 | virtual machine_config_constructor device_mconfig_additions() const; |
| 37 | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 38 | |
| 39 | protected: |
| 40 | // device-level overrides |
| 41 | virtual void device_start(); |
| 42 | virtual void device_reset(); |
| 43 | virtual void device_config_complete() { m_shortname = "wangpc_tig"; } |
| 44 | |
| 45 | // device_wangpcbus_card_interface overrides |
| 46 | virtual UINT16 wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask); |
| 47 | virtual void wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data); |
| 48 | virtual UINT8 wangpcbus_dack_r(address_space &space, int line); |
| 49 | virtual void wangpcbus_dack_w(address_space &space, int line, UINT8 data); |
| 50 | virtual bool wangpcbus_have_dack(int line); |
| 51 | |
| 52 | private: |
| 53 | // internal state |
| 54 | required_device<upd7220_device> m_hgdc0; |
| 55 | required_device<upd7220_device> m_hgdc1; |
| 56 | |
| 57 | UINT8 m_attr[16]; |
| 58 | UINT8 m_option; |
| 59 | UINT8 m_underline; |
| 60 | }; |
| 61 | |
| 62 | |
| 63 | // device type definition |
| 64 | extern const device_type WANGPC_TIG; |
| 65 | |
| 66 | |
| 67 | #endif |
src/mess/machine/wangpc_mvc.c
| r0 | r15422 | |
| 1 | /********************************************************************** |
| 2 | |
| 3 | Wang PC PM-001B Medium-Resolution Video Controller emulation |
| 4 | |
| 5 | Copyright MESS Team. |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. |
| 7 | |
| 8 | **********************************************************************/ |
| 9 | |
| 10 | /* |
| 11 | |
| 12 | TODO: |
| 13 | |
| 14 | - character clock |
| 15 | - blink |
| 16 | |
| 17 | */ |
| 18 | |
| 19 | #include "wangpc_mvc.h" |
| 20 | |
| 21 | |
| 22 | |
| 23 | //************************************************************************** |
| 24 | // MACROS/CONSTANTS |
| 25 | //************************************************************************** |
| 26 | |
| 27 | #define LOG 0 |
| 28 | |
| 29 | #define OPTION_ID 0x15 |
| 30 | |
| 31 | #define MC6845_TAG "mc6845" |
| 32 | #define SCREEN_TAG "screen" |
| 33 | |
| 34 | #define VIDEO_RAM_SIZE 0x800 |
| 35 | #define CHAR_RAM_SIZE 0x1000 |
| 36 | #define BITMAP_RAM_SIZE 0x4000 |
| 37 | |
| 38 | #define OPTION_VRAM BIT(m_option, 0) |
| 39 | #define OPTION_VSYNC BIT(m_option, 3) |
| 40 | |
| 41 | #define ATTR_BLINK BIT(attr, 0) |
| 42 | #define ATTR_REVERSE BIT(attr, 1) |
| 43 | #define ATTR_BLANK BIT(attr, 2) |
| 44 | #define ATTR_BOLD BIT(attr, 3) |
| 45 | #define ATTR_OVERSCORE BIT(attr, 4) |
| 46 | #define ATTR_UNDERSCORE BIT(attr, 5) |
| 47 | #define ATTR_SUBSCRIPT BIT(attr, 6) |
| 48 | #define ATTR_SUPERSCRIPT BIT(attr, 7) |
| 49 | |
| 50 | |
| 51 | |
| 52 | //************************************************************************** |
| 53 | // DEVICE DEFINITIONS |
| 54 | //************************************************************************** |
| 55 | |
| 56 | const device_type WANGPC_MVC = &device_creator<wangpc_mvc_device>; |
| 57 | |
| 58 | |
| 59 | //------------------------------------------------- |
| 60 | // mc6845_interface crtc_intf |
| 61 | //------------------------------------------------- |
| 62 | |
| 63 | 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) |
| 64 | { |
| 65 | const rgb_t *palette = palette_entry_list_raw(bitmap.palette()); |
| 66 | |
| 67 | for (int sx = 0; sx < 50; sx++) |
| 68 | { |
| 69 | offs_t addr = (y * 50) + sx; |
| 70 | UINT16 data = m_bitmap_ram[addr]; |
| 71 | |
| 72 | for (int bit = 0; bit < 16; bit++) |
| 73 | { |
| 74 | int x = (sx * 16) + bit; |
| 75 | int color = BIT(data, 15); |
| 76 | |
| 77 | bitmap.pix32(y, x) = palette[color]; |
| 78 | |
| 79 | data <<= 1; |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | for (int column = 0; column < x_count; column++) |
| 84 | { |
| 85 | UINT16 code = m_video_ram[((ma + column) & 0x7ff)]; |
| 86 | UINT8 attr = code & 0xff; |
| 87 | |
| 88 | UINT8 new_ra = ra + 1; |
| 89 | |
| 90 | if (ATTR_SUPERSCRIPT) |
| 91 | { |
| 92 | new_ra = ra + 3; |
| 93 | } |
| 94 | else if (ATTR_SUBSCRIPT) |
| 95 | { |
| 96 | new_ra = ra; |
| 97 | } |
| 98 | |
| 99 | offs_t addr = ((code >> 8) << 4) | (new_ra & 0x0f); |
| 100 | UINT16 data = m_char_ram[addr & 0xfff]; |
| 101 | |
| 102 | if ((column == cursor_x) || (!ra && ATTR_OVERSCORE) || ((ra == 9) && ATTR_UNDERSCORE)) |
| 103 | { |
| 104 | data = 0xffff; |
| 105 | } |
| 106 | |
| 107 | for (int bit = 0; bit < 10; bit++) |
| 108 | { |
| 109 | int x = (column * 10) + bit; |
| 110 | int color = ((BIT(data, 9) & !ATTR_BLANK) ^ ATTR_REVERSE); |
| 111 | |
| 112 | if ((color | bitmap.pix32(y, x)) & ATTR_BOLD) color = 2; |
| 113 | if (color) bitmap.pix32(y, x) = palette[color]; |
| 114 | |
| 115 | data <<= 1; |
| 116 | } |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | static MC6845_UPDATE_ROW( wangpc_mvc_update_row ) |
| 121 | { |
| 122 | wangpc_mvc_device *mvc = downcast<wangpc_mvc_device *>(device->owner()); |
| 123 | |
| 124 | mvc->crtc_update_row(device, bitmap, cliprect, ma, ra, y, x_count, cursor_x, param); |
| 125 | } |
| 126 | |
| 127 | WRITE_LINE_MEMBER( wangpc_mvc_device::vsync_w ) |
| 128 | { |
| 129 | if (OPTION_VSYNC && state) |
| 130 | { |
| 131 | set_irq(ASSERT_LINE); |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | static const mc6845_interface crtc_intf = |
| 136 | { |
| 137 | SCREEN_TAG, |
| 138 | 10, |
| 139 | NULL, |
| 140 | wangpc_mvc_update_row, |
| 141 | NULL, |
| 142 | DEVCB_NULL, |
| 143 | DEVCB_NULL, |
| 144 | DEVCB_NULL, |
| 145 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, wangpc_mvc_device, vsync_w), |
| 146 | NULL |
| 147 | }; |
| 148 | |
| 149 | |
| 150 | //------------------------------------------------- |
| 151 | // MACHINE_CONFIG_FRAGMENT( wangpc_mvc ) |
| 152 | //------------------------------------------------- |
| 153 | |
| 154 | static MACHINE_CONFIG_FRAGMENT( wangpc_mvc ) |
| 155 | MCFG_SCREEN_ADD(SCREEN_TAG, RASTER) |
| 156 | MCFG_SCREEN_UPDATE_DEVICE(MC6845_TAG, mc6845_device, screen_update) |
| 157 | MCFG_SCREEN_SIZE(80*10, 25*12) |
| 158 | MCFG_SCREEN_VISIBLE_AREA(0, 80*10-1, 0, 25*12-1) |
| 159 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) |
| 160 | MCFG_SCREEN_REFRESH_RATE(60) |
| 161 | |
| 162 | MCFG_PALETTE_LENGTH(3) |
| 163 | |
| 164 | MCFG_MC6845_ADD(MC6845_TAG, MC6845_1, XTAL_14_31818MHz/16, crtc_intf) |
| 165 | MACHINE_CONFIG_END |
| 166 | |
| 167 | |
| 168 | //------------------------------------------------- |
| 169 | // machine_config_additions - device-specific |
| 170 | // machine configurations |
| 171 | //------------------------------------------------- |
| 172 | |
| 173 | machine_config_constructor wangpc_mvc_device::device_mconfig_additions() const |
| 174 | { |
| 175 | return MACHINE_CONFIG_NAME( wangpc_mvc ); |
| 176 | } |
| 177 | |
| 178 | |
| 179 | |
| 180 | //************************************************************************** |
| 181 | // INLINE HELPERS |
| 182 | //************************************************************************** |
| 183 | |
| 184 | //------------------------------------------------- |
| 185 | // set_irq - |
| 186 | //------------------------------------------------- |
| 187 | |
| 188 | inline void wangpc_mvc_device::set_irq(int state) |
| 189 | { |
| 190 | m_irq = state; |
| 191 | |
| 192 | m_bus->irq3_w(m_irq); |
| 193 | } |
| 194 | |
| 195 | |
| 196 | |
| 197 | //************************************************************************** |
| 198 | // LIVE DEVICE |
| 199 | //************************************************************************** |
| 200 | |
| 201 | //------------------------------------------------- |
| 202 | // wangpc_mvc_device - constructor |
| 203 | //------------------------------------------------- |
| 204 | |
| 205 | wangpc_mvc_device::wangpc_mvc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 206 | device_t(mconfig, WANGPC_MVC, "Wang PC Medium Resolution Video Card", tag, owner, clock), |
| 207 | device_wangpcbus_card_interface(mconfig, *this), |
| 208 | m_crtc(*this, MC6845_TAG), |
| 209 | m_option(0), |
| 210 | m_irq(CLEAR_LINE) |
| 211 | { |
| 212 | } |
| 213 | |
| 214 | |
| 215 | //------------------------------------------------- |
| 216 | // device_start - device-specific startup |
| 217 | //------------------------------------------------- |
| 218 | |
| 219 | void wangpc_mvc_device::device_start() |
| 220 | { |
| 221 | // allocate memory |
| 222 | m_video_ram = auto_alloc_array(machine(), UINT16, VIDEO_RAM_SIZE); |
| 223 | m_char_ram = auto_alloc_array(machine(), UINT16, CHAR_RAM_SIZE); |
| 224 | m_bitmap_ram = auto_alloc_array(machine(), UINT16, BITMAP_RAM_SIZE); |
| 225 | |
| 226 | // initialize palette |
| 227 | palette_set_color_rgb(machine(), 0, 0, 0, 0); |
| 228 | palette_set_color_rgb(machine(), 1, 0, 0x80, 0); |
| 229 | palette_set_color_rgb(machine(), 2, 0, 0xff, 0); |
| 230 | |
| 231 | // state saving |
| 232 | save_pointer(NAME(m_video_ram), VIDEO_RAM_SIZE); |
| 233 | save_pointer(NAME(m_char_ram), CHAR_RAM_SIZE); |
| 234 | save_pointer(NAME(m_bitmap_ram), BITMAP_RAM_SIZE); |
| 235 | save_item(NAME(m_option)); |
| 236 | save_item(NAME(m_irq)); |
| 237 | } |
| 238 | |
| 239 | |
| 240 | //------------------------------------------------- |
| 241 | // device_reset - device-specific reset |
| 242 | //------------------------------------------------- |
| 243 | |
| 244 | void wangpc_mvc_device::device_reset() |
| 245 | { |
| 246 | m_option = 0; |
| 247 | |
| 248 | set_irq(CLEAR_LINE); |
| 249 | } |
| 250 | |
| 251 | |
| 252 | //------------------------------------------------- |
| 253 | // wangpcbus_mrdc_r - memory read |
| 254 | //------------------------------------------------- |
| 255 | |
| 256 | UINT16 wangpc_mvc_device::wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask) |
| 257 | { |
| 258 | UINT16 data = 0xffff; |
| 259 | |
| 260 | if (OPTION_VRAM) |
| 261 | { |
| 262 | if (offset >= 0xe0000/2 && offset < 0xe8000/2) |
| 263 | { |
| 264 | data = m_bitmap_ram[offset & 0x3fff]; |
| 265 | } |
| 266 | else if (offset >= 0xf0000/2 && offset < 0xf1000/2) |
| 267 | { |
| 268 | data = m_video_ram[offset & 0x7ff]; |
| 269 | } |
| 270 | else if (offset >= 0xf2000/2 && offset < 0xf4000/2) |
| 271 | { |
| 272 | data = m_char_ram[offset & 0xfff]; |
| 273 | } |
| 274 | } |
| 275 | |
| 276 | return data; |
| 277 | } |
| 278 | |
| 279 | |
| 280 | //------------------------------------------------- |
| 281 | // wangpcbus_amwc_w - memory write |
| 282 | //------------------------------------------------- |
| 283 | |
| 284 | void wangpc_mvc_device::wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data) |
| 285 | { |
| 286 | if (OPTION_VRAM) |
| 287 | { |
| 288 | if (offset >= 0xe0000/2 && offset < 0xe8000/2) |
| 289 | { |
| 290 | m_bitmap_ram[offset & 0x3fff] = data; |
| 291 | } |
| 292 | else if (offset >= 0xf0000/2 && offset < 0xf1000/2) |
| 293 | { |
| 294 | m_video_ram[offset & 0x7ff] = data; |
| 295 | } |
| 296 | else if (offset >= 0xf2000/2 && offset < 0xf4000/2) |
| 297 | { |
| 298 | m_char_ram[offset & 0xfff] = data; |
| 299 | } |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | |
| 304 | //------------------------------------------------- |
| 305 | // wangpcbus_iorc_r - I/O read |
| 306 | //------------------------------------------------- |
| 307 | |
| 308 | UINT16 wangpc_mvc_device::wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask) |
| 309 | { |
| 310 | UINT16 data = 0xffff; |
| 311 | |
| 312 | if (sad(offset)) |
| 313 | { |
| 314 | switch (offset & 0x7f) |
| 315 | { |
| 316 | case 0xfe/2: |
| 317 | data = 0xff00 | (m_irq << 7) | OPTION_ID; |
| 318 | |
| 319 | set_irq(CLEAR_LINE); |
| 320 | break; |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | return data; |
| 325 | } |
| 326 | |
| 327 | |
| 328 | //------------------------------------------------- |
| 329 | // wangpcbus_aiowc_w - I/O write |
| 330 | //------------------------------------------------- |
| 331 | |
| 332 | void wangpc_mvc_device::wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data) |
| 333 | { |
| 334 | if (sad(offset) && ACCESSING_BITS_0_7) |
| 335 | { |
| 336 | switch (offset & 0x7f) |
| 337 | { |
| 338 | case 0x00/2: |
| 339 | m_crtc->address_w(space, 0, data & 0xff); |
| 340 | break; |
| 341 | |
| 342 | case 0x02/2: |
| 343 | m_crtc->register_w(space, 0, data & 0xff); |
| 344 | break; |
| 345 | |
| 346 | case 0x10/2: |
| 347 | case 0x12/2: |
| 348 | if (LOG) logerror("MVC option %02x\n", data & 0xff); |
| 349 | |
| 350 | m_option = data & 0xff; |
| 351 | break; |
| 352 | } |
| 353 | } |
| 354 | } |
src/mess/machine/wangpc_mvc.h
| r0 | r15422 | |
| 1 | /********************************************************************** |
| 2 | |
| 3 | Wang PC PM-001B Medium-Resolution Video Controller emulation |
| 4 | |
| 5 | Copyright MESS Team. |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. |
| 7 | |
| 8 | **********************************************************************/ |
| 9 | |
| 10 | #pragma once |
| 11 | |
| 12 | #ifndef __WANGPC_MVC__ |
| 13 | #define __WANGPC_MVC__ |
| 14 | |
| 15 | |
| 16 | #include "emu.h" |
| 17 | #include "machine/wangpcbus.h" |
| 18 | #include "video/mc6845.h" |
| 19 | |
| 20 | |
| 21 | |
| 22 | //************************************************************************** |
| 23 | // TYPE DEFINITIONS |
| 24 | //************************************************************************** |
| 25 | |
| 26 | // ======================> wangpc_mvc_device |
| 27 | |
| 28 | class wangpc_mvc_device : public device_t, |
| 29 | public device_wangpcbus_card_interface |
| 30 | { |
| 31 | public: |
| 32 | // construction/destruction |
| 33 | wangpc_mvc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 34 | |
| 35 | // optional information overrides |
| 36 | virtual machine_config_constructor device_mconfig_additions() const; |
| 37 | |
| 38 | // not really public |
| 39 | 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); |
| 40 | DECLARE_WRITE_LINE_MEMBER( vsync_w ); |
| 41 | |
| 42 | protected: |
| 43 | // device-level overrides |
| 44 | virtual void device_start(); |
| 45 | virtual void device_reset(); |
| 46 | virtual void device_config_complete() { m_shortname = "wangpc_mvc"; } |
| 47 | |
| 48 | // device_wangpcbus_card_interface overrides |
| 49 | virtual UINT16 wangpcbus_mrdc_r(address_space &space, offs_t offset, UINT16 mem_mask); |
| 50 | virtual void wangpcbus_amwc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data); |
| 51 | virtual UINT16 wangpcbus_iorc_r(address_space &space, offs_t offset, UINT16 mem_mask); |
| 52 | virtual void wangpcbus_aiowc_w(address_space &space, offs_t offset, UINT16 mem_mask, UINT16 data); |
| 53 | |
| 54 | private: |
| 55 | inline void set_irq(int state); |
| 56 | |
| 57 | // internal state |
| 58 | required_device<mc6845_device> m_crtc; |
| 59 | |
| 60 | UINT16 *m_video_ram; |
| 61 | UINT16 *m_char_ram; |
| 62 | UINT16 *m_bitmap_ram; |
| 63 | UINT8 m_option; |
| 64 | int m_irq; |
| 65 | }; |
| 66 | |
| 67 | |
| 68 | // device type definition |
| 69 | extern const device_type WANGPC_MVC; |
| 70 | |
| 71 | |
| 72 | #endif |
src/mess/machine/wangpcbus.c
| r15421 | r15422 | |
| 238 | 238 | // dack_r - DMA read
|
| 239 | 239 | //-------------------------------------------------
|
| 240 | 240 | |
| 241 | | UINT8 wangpcbus_device::dack_r(int line)
|
| 241 | UINT8 wangpcbus_device::dack_r(address_space &space, int line)
|
| 242 | 242 | {
|
| 243 | 243 | UINT8 retVal = 0xff;
|
| 244 | 244 | device_wangpcbus_card_interface *entry = m_device_list.first();
|
| r15421 | r15422 | |
| 247 | 247 | {
|
| 248 | 248 | if (entry->wangpcbus_have_dack(line))
|
| 249 | 249 | {
|
| 250 | | retVal = entry->wangpcbus_dack_r(line);
|
| 250 | retVal = entry->wangpcbus_dack_r(space, line);
|
| 251 | 251 | break;
|
| 252 | 252 | }
|
| 253 | 253 | |
| r15421 | r15422 | |
| 257 | 257 | return retVal;
|
| 258 | 258 | }
|
| 259 | 259 | |
| 260 | |
| 260 | 261 | //-------------------------------------------------
|
| 261 | 262 | // dack_w - DMA write
|
| 262 | 263 | //-------------------------------------------------
|
| 263 | 264 | |
| 264 | | void wangpcbus_device::dack_w(int line, UINT8 data)
|
| 265 | void wangpcbus_device::dack_w(address_space &space, int line, UINT8 data)
|
| 265 | 266 | {
|
| 266 | 267 | device_wangpcbus_card_interface *entry = m_device_list.first();
|
| 267 | 268 | |
| r15421 | r15422 | |
| 269 | 270 | {
|
| 270 | 271 | if (entry->wangpcbus_have_dack(line))
|
| 271 | 272 | {
|
| 272 | | entry->wangpcbus_dack_w(line,data);
|
| 273 | entry->wangpcbus_dack_w(space, line, data);
|
| 273 | 274 | }
|
| 274 | 275 | |
| 275 | 276 | entry = entry->next();
|
| 276 | 277 | }
|
| 277 | 278 | }
|
| 278 | 279 | |
| 279 | | READ8_MEMBER( wangpcbus_device::dack0_r ) { return dack_r(0); }
|
| 280 | | WRITE8_MEMBER( wangpcbus_device::dack0_w ) { dack_w(0, data); }
|
| 281 | | READ8_MEMBER( wangpcbus_device::dack1_r ) { return dack_r(1); }
|
| 282 | | WRITE8_MEMBER( wangpcbus_device::dack1_w ) { dack_w(1, data); }
|
| 283 | | READ8_MEMBER( wangpcbus_device::dack2_r ) { return dack_r(2); }
|
| 284 | | WRITE8_MEMBER( wangpcbus_device::dack2_w ) { dack_w(2, data); }
|
| 285 | | READ8_MEMBER( wangpcbus_device::dack3_r ) { return dack_r(3); }
|
| 286 | | WRITE8_MEMBER( wangpcbus_device::dack3_w ) { dack_w(3, data); }
|
| 280 | READ8_MEMBER( wangpcbus_device::dack0_r ) { return dack_r(space, 0); }
|
| 281 | WRITE8_MEMBER( wangpcbus_device::dack0_w ) { dack_w(space, 0, data); }
|
| 282 | READ8_MEMBER( wangpcbus_device::dack1_r ) { return dack_r(space, 1); }
|
| 283 | WRITE8_MEMBER( wangpcbus_device::dack1_w ) { dack_w(space, 1, data); }
|
| 284 | READ8_MEMBER( wangpcbus_device::dack2_r ) { return dack_r(space, 2); }
|
| 285 | WRITE8_MEMBER( wangpcbus_device::dack2_w ) { dack_w(space, 2, data); }
|
| 286 | READ8_MEMBER( wangpcbus_device::dack3_r ) { return dack_r(space, 3); }
|
| 287 | WRITE8_MEMBER( wangpcbus_device::dack3_w ) { dack_w(space, 3, data); }
|
| 287 | 288 | |
| 288 | 289 | |
| 289 | 290 | //-------------------------------------------------
|