From e9e4b0bcca4c40df847449701995b2f090fad598 Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Tue, 7 Jan 2020 14:44:57 +0700 Subject: [PATCH] ims_cvc: implement cursor (nw) * simplify handlers * reduce logging noise --- src/devices/video/ims_cvc.cpp | 187 +++++++++++++++++++--------------- src/devices/video/ims_cvc.h | 89 +++++++++------- 2 files changed, 157 insertions(+), 119 deletions(-) diff --git a/src/devices/video/ims_cvc.cpp b/src/devices/video/ims_cvc.cpp index 14ae0901769..6274028a4f9 100644 --- a/src/devices/video/ims_cvc.cpp +++ b/src/devices/video/ims_cvc.cpp @@ -9,8 +9,6 @@ * * http://bitsavers.org/components/inmos/graphics/72-TRN-204-01_Graphics_Databook_Second_Edition_1990.pdf * - * TODO - * - cursor */ #include "emu.h" @@ -28,7 +26,7 @@ DEFINE_DEVICE_TYPE(G300, g300_device, "g300", "INMOS G300 Colour Video Controlle DEFINE_DEVICE_TYPE(G332, g332_device, "g332", "INMOS G332 Colour Video Controller") DEFINE_DEVICE_TYPE(G364, g364_device, "g364", "INMOS G364 Colour Video Controller") -ims_cvc_device::ims_cvc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +ims_cvc_device::ims_cvc_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) : device_t(mconfig, type, tag, owner, clock) , device_palette_interface(mconfig, *this) , m_screen(*this, finder_base::DUMMY_TAG) @@ -36,23 +34,23 @@ ims_cvc_device::ims_cvc_device(const machine_config &mconfig, device_type type, { } -g300_device::g300_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +g300_device::g300_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : ims_cvc_device(mconfig, G300, tag, owner, clock) { } -g332_device::g332_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +g332_device::g332_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) : ims_cvc_device(mconfig, type, tag, owner, clock) , m_microport(*this, "microport") { } -g332_device::g332_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +g332_device::g332_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : g332_device(mconfig, G332, tag, owner, clock) { } -g364_device::g364_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +g364_device::g364_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : g332_device(mconfig, G364, tag, owner, clock) { } @@ -65,7 +63,7 @@ void g332_device::device_add_mconfig(machine_config &config) void g300_device::map(address_map &map) { // datasheet gives unshifted addresses - const int shift = 2; + unsigned const shift = 2; // colour palette map(0x000 << shift, (0x0ff << shift) | 0x3).rw(FUNC(g300_device::colour_palette_r), FUNC(g300_device::colour_palette_w)); @@ -99,7 +97,7 @@ void g332_device::microport_map(address_map &map) { // datasheet uses unshifted addresses: configure the device map for 64 bit // address mode, bank device does handles additional shift for 32 bit mode - const int shift = 3; + unsigned const shift = 3; map(0x000 << shift, (0x000 << shift) | 0x7).w(FUNC(g332_device::boot_w)); @@ -129,11 +127,14 @@ void g332_device::microport_map(address_map &map) // checksum registers (0c0-0c2) + // cursor start (0c7) + map(0x0c7 << shift, (0x0c7 << shift) | 0x7).rw(FUNC(g332_device::cursor_start_r), FUNC(g332_device::cursor_start_w)); + // colour palette map(0x100 << shift, (0x1ff << shift) | 0x7).rw(FUNC(g332_device::colour_palette_r), FUNC(g332_device::colour_palette_w)); // cursor store (200-3ff) - // cursor position (0c7) + map(0x200 << shift, (0x3ff << shift) | 0x7).rw(FUNC(g332_device::cursor_store_r), FUNC(g332_device::cursor_store_w)); } void ims_cvc_device::device_start() @@ -170,11 +171,16 @@ void g332_device::device_start() { ims_cvc_device::device_start(); + m_cursor_store = std::make_unique(512); + save_item(NAME(m_vpreequalise)); save_item(NAME(m_vpostequalise)); save_item(NAME(m_linestart)); save_item(NAME(m_control_a)); save_item(NAME(m_control_b)); + save_item(NAME(m_cursor_start)); + + save_pointer(NAME(m_cursor_store), 512); } void g332_device::device_reset() @@ -182,7 +188,7 @@ void g332_device::device_reset() m_control_a = 0; } -u32 g300_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +u32 g300_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect) { offs_t address = m_tos; @@ -193,7 +199,7 @@ u32 g300_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, cons return 0; } -u32 g332_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +u32 g332_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect) { offs_t address = m_tos; @@ -247,30 +253,48 @@ u32 g332_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, cons break; } + if (!(m_control_a & CURSOR_DISABLE)) + { + // get cursor origin + int const cursor_x = screen.visible_area().min_x + (s32(m_cursor_start << 8) >> 20); + int const cursor_y = screen.visible_area().min_y + (s32(m_cursor_start << 20) >> 20); + + // intersect cursor with screen + rectangle cursor(cursor_x, cursor_x + 63, cursor_y, cursor_y + 63); + cursor &= bitmap.cliprect(); + + // check if any portion is visible + if (!cursor.empty()) + { + for (int y = 0; y < 64; y++) + { + // get screen y pixel coordinate + int const ypos = cursor_y + y; + + for (int x = 0; x < 8; x++) + { + // retrieve 8 pixels from cursor bitmap + u16 data = m_cursor_store[y * 8 + x]; + + // draw non-transparent pixels + for (int i = 0; data && i < 8; data >>= 2, i++) + { + // get screen x pixel coordinate + int const xpos = cursor_x + x * 8 + i; + + // draw pixel if visible + if ((data & 3) && cursor.contains(xpos, ypos)) + bitmap.pix(ypos, xpos) = pen_color(256 + (data & 3) - 1); + } + } + } + } + } + return 0; } -u32 ims_cvc_device::colour_palette_r(offs_t offset) -{ - return 0; -} - -void ims_cvc_device::colour_palette_w(offs_t offset, u32 data, u32 mem_mask) -{ - set_pen_color(offset >> 1, data >> 16, data >> 8, data >> 0); -} - -u32 g332_device::cursor_palette_r(offs_t offset) -{ - return 0; -} - -void g332_device::cursor_palette_w(offs_t offset, u32 data, u32 mem_mask) -{ - set_pen_color(256 + (offset >> 1), data >> 16, data >> 8, data >> 0); -} - -void g332_device::boot_w(offs_t offset, u32 data, u32 mem_mask) +void g332_device::boot_w(u32 data) { LOG("boot_w %s clock, multiplier %d, %d bit alignment (%s)\n", (data & PLL_SELECT) ? "PLL" : "external", (data & PLL_MULTIPLIER), @@ -278,68 +302,69 @@ void g332_device::boot_w(offs_t offset, u32 data, u32 mem_mask) m_microport->set_shift((data & ALIGN_64) ? 0 : 1); - mem_mask &= 0x00ffffffU; - COMBINE_DATA(&m_boot); + m_boot = data & MASK24; } -void g332_device::control_a_w(offs_t offset, u32 data, u32 mem_mask) +void g332_device::control_a_w(u32 data) { LOG("control_a_w 0x%08x (%s)\n", data, machine().describe_context()); - mem_mask &= 0x00ffffffU; - COMBINE_DATA(&m_control_a); - - if (data & VTG_ENABLE) + if ((data ^ m_control_a) & MASK24) { - LOGMASKED(LOG_CONFIG, "VTG %s, %s, %s mode\n", - (data & VTG_ENABLE) ? "enabled" : "disabled", - (data & INTL_ENABLE) ? ((data & INTL_FORMAT) ? "interlaced (CCIR)" : "interlaced (EIA)") : "non-interlaced", - (data & SLAVE_MODE) ? "slave" : "master"); + m_control_a = data & MASK24; - LOGMASKED(LOG_CONFIG, "%s sync, %s digital sync, analogue %s\n", - (data & SYNC_PATTERN) ? "plain" : "tesselated", - (data & SYNC_FORMAT) ? "separate" : "composite", - (data & VIDEO_FORMAT) ? "video only" : "composite video + sync"); + if (data & VTG_ENABLE) + { + LOGMASKED(LOG_CONFIG, "VTG %s, %s, %s mode\n", + (data & VTG_ENABLE) ? "enabled" : "disabled", + (data & INTL_ENABLE) ? ((data & INTL_FORMAT) ? "interlaced (CCIR)" : "interlaced (EIA)") : "non-interlaced", + (data & SLAVE_MODE) ? "slave" : "master"); - LOGMASKED(LOG_CONFIG, "%s, CBlank is %s, %s, %s\n", - (data & BLANK_LEVEL) ? "blanking pedestal" : "no blank pedestal", - (data & BLANK_IO) ? "ouput" : "input", - (data & BLANK_FUNC) ? "undelayed ClkDisable" : "delayed CBlank", - (data & BLANK_FORCE) ? "screen blanked" : (data & BLANK_DISABLE) ? "blanking disabled" : "blanking enabled"); + LOGMASKED(LOG_CONFIG, "%s sync, %s digital sync, analogue %s\n", + (data & SYNC_PATTERN) ? "plain" : "tesselated", + (data & SYNC_FORMAT) ? "separate" : "composite", + (data & VIDEO_FORMAT) ? "video only" : "composite video + sync"); - LOGMASKED(LOG_CONFIG, "address increment %d, DMA %s, sync delay %d cycles\n", - (data & ADDR_INC) == INC_1 ? 1 : - (data & ADDR_INC) == INC_256 ? (data & INTL_ENABLE) ? 2 : 256 : - (data & ADDR_INC) == INC_512 ? 512 : 1024, - (data & DMA_DISABLE) ? "disabled" : "enabled", - (data & SYNC_DELAY) >> 15); + LOGMASKED(LOG_CONFIG, "%s, CBlank is %s, %s, %s\n", + (data & BLANK_LEVEL) ? "blanking pedestal" : "no blank pedestal", + (data & BLANK_IO) ? "ouput" : "input", + (data & BLANK_FUNC) ? "undelayed ClkDisable" : "delayed CBlank", + (data & BLANK_FORCE) ? "screen blanked" : (data & BLANK_DISABLE) ? "blanking disabled" : "blanking enabled"); - LOGMASKED(LOG_CONFIG, "interleave %s, pixel sampling %s, %s bits per pixel, cursor %s\n", - (data & INTERLEAVE) ? "enabled" : "disabled", - (data & SAMPLE_DELAY) ? "delayed" : "standard", - (data & PIXEL_BITS) == BPP_1 ? "1" : - (data & PIXEL_BITS) == BPP_2 ? "2" : - (data & PIXEL_BITS) == BPP_4 ? "4" : - (data & PIXEL_BITS) == BPP_8 ? "8" : - (data & PIXEL_BITS) == BPP_15 ? "15" : - (data & PIXEL_BITS) == BPP_16 ? "16" : "unknown", - (data & CURSOR_DISABLE) ? "disabled" : "enabled"); + LOGMASKED(LOG_CONFIG, "address increment %d, DMA %s, sync delay %d cycles\n", + (data & ADDR_INC) == INC_1 ? 1 : + (data & ADDR_INC) == INC_256 ? (data & INTL_ENABLE) ? 2 : 256 : + (data & ADDR_INC) == INC_512 ? 512 : 1024, + (data & DMA_DISABLE) ? "disabled" : "enabled", + (data & SYNC_DELAY) >> 15); - LOG("display %d vdisplay %d\n", m_display, m_vdisplay); - LOG("linetime %d halfsync %d backporch %d broadpulse %d\n", m_linetime, m_halfsync, m_backporch, m_broadpulse); - LOG("vsync %d vpreequalise %d vpostequalise %d vblank %d\n", m_vsync, m_vpreequalise, m_vpostequalise, m_vblank); + LOGMASKED(LOG_CONFIG, "interleave %s, pixel sampling %s, %s bits per pixel, cursor %s\n", + (data & INTERLEAVE) ? "enabled" : "disabled", + (data & SAMPLE_DELAY) ? "delayed" : "standard", + (data & PIXEL_BITS) == BPP_1 ? "1" : + (data & PIXEL_BITS) == BPP_2 ? "2" : + (data & PIXEL_BITS) == BPP_4 ? "4" : + (data & PIXEL_BITS) == BPP_8 ? "8" : + (data & PIXEL_BITS) == BPP_15 ? "15" : + (data & PIXEL_BITS) == BPP_16 ? "16" : "unknown", + (data & CURSOR_DISABLE) ? "disabled" : "enabled"); - int const hbend = (m_halfsync + m_halfsync + m_backporch) << 2; - int const vbend = (m_vpreequalise + m_vpostequalise + m_vsync + m_vblank) >> 1; - int const width = m_linetime << 2; - int const height = vbend + (m_vdisplay >> 1); + LOG("display %d vdisplay %d\n", m_display, m_vdisplay); + LOG("linetime %d halfsync %d backporch %d broadpulse %d\n", m_linetime, m_halfsync, m_backporch, m_broadpulse); + LOG("vsync %d vpreequalise %d vpostequalise %d vblank %d\n", m_vsync, m_vpreequalise, m_vpostequalise, m_vblank); - rectangle const visarea(hbend, hbend + (m_display << 2) - 1, vbend, height - 1); + int const hbend = (m_halfsync + m_halfsync + m_backporch) << 2; + int const vbend = (m_vpreequalise + m_vpostequalise + m_vsync + m_vblank) >> 1; + int const width = m_linetime << 2; + int const height = vbend + (m_vdisplay >> 1); - u32 const dotclock = (m_boot & PLL_SELECT) ? clock() * (m_boot & PLL_MULTIPLIER) : clock(); - attotime const refresh = attotime::from_hz(dotclock / (width * height)); + rectangle const visarea(hbend, hbend + (m_display << 2) - 1, vbend, height - 1); - m_screen->configure(width, height, visarea, refresh.as_attoseconds()); - m_screen->reset_origin(); + u32 const dotclock = (m_boot & PLL_SELECT) ? clock() * (m_boot & PLL_MULTIPLIER) : clock(); + attotime const refresh = attotime::from_hz(dotclock / (width * height)); + + m_screen->configure(width, height, visarea, refresh.as_attoseconds()); + m_screen->reset_origin(); + } } } diff --git a/src/devices/video/ims_cvc.h b/src/devices/video/ims_cvc.h index 82acfe5c6eb..dfe61f178c6 100644 --- a/src/devices/video/ims_cvc.h +++ b/src/devices/video/ims_cvc.h @@ -13,17 +13,17 @@ class ims_cvc_device , public device_palette_interface { public: - static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } + static u32 const MASK24 = 0xffffffU; // configuration template void set_screen(T &&tag) { m_screen.set_tag(std::forward(tag)); } template void set_vram(T &&tag) { m_vram.set_tag(std::forward(tag)); } virtual void map(address_map &map) = 0; - virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) = 0; + virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect) = 0; protected: - ims_cvc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + ims_cvc_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock); // device_t overrides virtual void device_start() override; @@ -32,39 +32,41 @@ protected: // device_palette_interface overrides virtual u32 palette_entries() const override { return 256; } - u32 colour_palette_r(const offs_t offset); - void colour_palette_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU); + virtual void boot_w(u32 data) { m_boot = data & MASK24; } + + // register read handlers u32 halfsync_r() { return m_halfsync; } - void halfsync_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_halfsync); } u32 backporch_r() { return m_backporch; } - void backporch_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_backporch); } u32 display_r() { return m_display; } - void display_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_display); } u32 shortdisplay_r() { return m_shortdisplay; } - void shortdisplay_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_shortdisplay); } u32 broadpulse_r() { return m_broadpulse; } - void broadpulse_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_broadpulse); } u32 vsync_r() { return m_vsync; } - void vsync_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_vsync); } u32 vblank_r() { return m_vblank; } - void vblank_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_vblank); } u32 vdisplay_r() { return m_vdisplay; } - void vdisplay_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_vdisplay); } u32 linetime_r() { return m_linetime; } - void linetime_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_linetime); } - //u32 tos_r() { return m_tos; } - //void tos_w(const u32 data) { m_tos = data; } u32 meminit_r() { return m_meminit; } - void meminit_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_meminit); } u32 transferdelay_r() { return m_transferdelay; } - void transferdelay_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_transferdelay); } - u32 mask_r() { return m_mask; } - void mask_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_mask); } u32 tos_r() { return m_tos; } - void tos_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_tos); } - virtual void boot_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_boot); } + // register write handlers + void halfsync_w(u32 data) { m_halfsync = data & MASK24; } + void backporch_w(u32 data) { m_backporch = data & MASK24; } + void display_w(u32 data) { m_display = data & MASK24; } + void shortdisplay_w(u32 data) { m_shortdisplay = data & MASK24; } + void broadpulse_w(u32 data) { m_broadpulse = data & MASK24; } + void vsync_w(u32 data) { m_vsync = data & MASK24; } + void vblank_w(u32 data) { m_vblank = data & MASK24; } + void vdisplay_w(u32 data) { m_vdisplay = data & MASK24; } + void linetime_w(u32 data) { m_linetime = data & MASK24; } + void meminit_w(u32 data) { m_meminit = data & MASK24; } + void transferdelay_w(u32 data) { m_transferdelay = data & MASK24; } + void mask_w(u32 data) { m_mask = data & MASK24; } + void tos_w(u32 data) { m_tos = data & MASK24; } + + // colour palette handlers + u32 colour_palette_r(offs_t offset) { return u32(pen_color(offset >> 1)) & MASK24; } + void colour_palette_w(offs_t offset, u32 data) { set_pen_color(offset >> 1, data >> 16, data >> 8, data >> 0); } required_device m_screen; required_device m_vram; @@ -91,17 +93,17 @@ protected: class g300_device : public ims_cvc_device { public: - g300_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + g300_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); virtual void map(address_map &map) override; - virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override; + virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect) override; protected: virtual void device_start() override; u32 control_r() { return m_control; } - void control_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_control); } + void control_w(u32 data) { m_control = data & MASK24; } private: u32 m_control; @@ -110,11 +112,11 @@ private: class g332_device : public ims_cvc_device { public: - g332_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + g332_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); virtual void map(address_map &map) override; - virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override; + virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect) override; enum boot_mask : u32 { @@ -163,7 +165,7 @@ public: }; protected: - g332_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + g332_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock); // device_t overrides virtual void device_add_mconfig(machine_config &config) override; @@ -175,21 +177,29 @@ protected: virtual void microport_map(address_map &map); - virtual void boot_w(offs_t offset, u32 data, u32 mem_mask = 0x00ffffffU) override; - - u32 cursor_palette_r(const offs_t offset); - void cursor_palette_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU); + virtual void boot_w(u32 data) override; + // register read handlers u32 vpreequalise_r() { return m_vpreequalise; } - void vpreequalise_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_vpreequalise); } u32 vpostequalise_r() { return m_vpostequalise; } - void vpostequalise_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_vpostequalise); } u32 linestart_r() { return m_linestart; } - void linestart_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_linestart); } u32 control_a_r() { return m_control_a; } - void control_a_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU); u32 control_b_r() { return m_control_b; } - void control_b_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_control_b); } + u32 cursor_start_r() { return m_cursor_start; } + + // register write handlers + void vpreequalise_w(u32 data) { m_vpreequalise = data & MASK24; } + void vpostequalise_w(u32 data) { m_vpostequalise = data & MASK24; } + void linestart_w(u32 data) { m_linestart = data & MASK24; } + void control_a_w(u32 data); + void control_b_w(u32 data) { m_control_b = data & MASK24; } + void cursor_start_w(u32 data) { m_cursor_start = data & MASK24; } + + // cursor handlers + u32 cursor_palette_r(offs_t offset) { return u32(pen_color(256 + (offset >> 1)))& MASK24; } + u32 cursor_store_r(offs_t offset) { return m_cursor_store[offset >> 1]; } + void cursor_palette_w(offs_t offset, u32 data) { set_pen_color(256 + (offset >> 1), data >> 16, data >> 8, data >> 0); } + void cursor_store_w(offs_t offset, u32 data) { m_cursor_store[offset >> 1] = u16(data); } private: required_device m_microport; @@ -199,12 +209,15 @@ private: u32 m_linestart; u32 m_control_a; u32 m_control_b; + u32 m_cursor_start; + + std::unique_ptr m_cursor_store; }; class g364_device : public g332_device { public: - g364_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + g364_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); }; DECLARE_DEVICE_TYPE(G300, g300_device)