From 752f1a331d281df7436e9454435f7d36bda4862b Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Tue, 22 Jan 2019 19:18:04 +0700 Subject: ims_cvc: basic graphics output working --- src/devices/video/ims_cvc.cpp | 283 ++++++++++++++++++++++++++++++++++++------ src/devices/video/ims_cvc.h | 144 +++++++++++++++------ 2 files changed, 352 insertions(+), 75 deletions(-) diff --git a/src/devices/video/ims_cvc.cpp b/src/devices/video/ims_cvc.cpp index 60b76604ef5..1f329c96672 100644 --- a/src/devices/video/ims_cvc.cpp +++ b/src/devices/video/ims_cvc.cpp @@ -10,7 +10,7 @@ * http://bitsavers.org/components/inmos/graphics/72-TRN-204-01_Graphics_Databook_Second_Edition_1990.pdf * * TODO - * - everything (skeleton only) + * - cursor */ #include "emu.h" @@ -18,7 +18,10 @@ #include "screen.h" -#define VERBOSE 0 +#define LOG_GENERAL (1U << 0) +#define LOG_CONFIG (1U << 1) + +//#define VERBOSE (LOG_GENERAL|LOG_CONFIG) #include "logmacro.h" DEFINE_DEVICE_TYPE(G300, g300_device, "g300", "INMOS G300 Colour Video Controller") @@ -27,9 +30,9 @@ DEFINE_DEVICE_TYPE(G364, g364_device, "g364", "INMOS G364 Colour Video Controlle ims_cvc_device::ims_cvc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) - , device_memory_interface(mconfig, *this) , device_palette_interface(mconfig, *this) - , m_space_config("shared", ENDIANNESS_LITTLE, 32, 24) + , m_screen(*this, finder_base::DUMMY_TAG) + , m_vram(*this, finder_base::DUMMY_TAG) { } @@ -40,11 +43,12 @@ g300_device::g300_device(const machine_config &mconfig, const char *tag, device_ g332_device::g332_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t 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) - : ims_cvc_device(mconfig, G332, tag, owner, clock) + : g332_device(mconfig, G332, tag, owner, clock) { } @@ -53,11 +57,9 @@ g364_device::g364_device(const machine_config &mconfig, const char *tag, device_ { } -device_memory_interface::space_config_vector ims_cvc_device::memory_space_config() const +void g332_device::device_add_mconfig(machine_config &config) { - return space_config_vector{ - std::make_pair(0, &m_space_config) - }; + ADDRESS_MAP_BANK(config, m_microport).set_map(&g332_device::microport_map).set_options(ENDIANNESS_LITTLE, 32, 32); } void g300_device::map(address_map &map) @@ -69,18 +71,18 @@ void g300_device::map(address_map &map) map(0x000 << shift, (0x0ff << shift) | 0x3).rw(FUNC(g300_device::colour_palette_r), FUNC(g300_device::colour_palette_w)); // data path registers - map(0x121, (0x121 << shift) | 0x3).rw(FUNC(g300_device::halfsync_r), FUNC(g300_device::halfsync_w)); - map(0x122, (0x122 << shift) | 0x3).rw(FUNC(g300_device::backporch_r), FUNC(g300_device::backporch_w)); - map(0x123, (0x123 << shift) | 0x3).rw(FUNC(g300_device::display_r), FUNC(g300_device::display_w)); - map(0x124, (0x124 << shift) | 0x3).rw(FUNC(g300_device::shortdisplay_r), FUNC(g300_device::shortdisplay_w)); - map(0x125, (0x125 << shift) | 0x3).rw(FUNC(g300_device::broadpulse_r), FUNC(g300_device::broadpulse_w)); - map(0x126, (0x126 << shift) | 0x3).rw(FUNC(g300_device::vsync_r), FUNC(g300_device::vsync_w)); - map(0x127, (0x127 << shift) | 0x3).rw(FUNC(g300_device::vblank_r), FUNC(g300_device::vblank_w)); - map(0x128, (0x128 << shift) | 0x3).rw(FUNC(g300_device::vdisplay_r), FUNC(g300_device::vdisplay_w)); - map(0x129, (0x129 << shift) | 0x3).rw(FUNC(g300_device::linetime_r), FUNC(g300_device::linetime_w)); - map(0x12a, (0x12a << shift) | 0x3).rw(FUNC(g300_device::tos_r), FUNC(g300_device::tos_w)); - map(0x12b, (0x12b << shift) | 0x3).rw(FUNC(g300_device::meminit_r), FUNC(g300_device::meminit_w)); - map(0x12c, (0x12c << shift) | 0x3).rw(FUNC(g300_device::transferdelay_r), FUNC(g300_device::transferdelay_w)); + map(0x121 << shift, (0x121 << shift) | 0x3).rw(FUNC(g300_device::halfsync_r), FUNC(g300_device::halfsync_w)); + map(0x122 << shift, (0x122 << shift) | 0x3).rw(FUNC(g300_device::backporch_r), FUNC(g300_device::backporch_w)); + map(0x123 << shift, (0x123 << shift) | 0x3).rw(FUNC(g300_device::display_r), FUNC(g300_device::display_w)); + map(0x124 << shift, (0x124 << shift) | 0x3).rw(FUNC(g300_device::shortdisplay_r), FUNC(g300_device::shortdisplay_w)); + map(0x125 << shift, (0x125 << shift) | 0x3).rw(FUNC(g300_device::broadpulse_r), FUNC(g300_device::broadpulse_w)); + map(0x126 << shift, (0x126 << shift) | 0x3).rw(FUNC(g300_device::vsync_r), FUNC(g300_device::vsync_w)); + map(0x127 << shift, (0x127 << shift) | 0x3).rw(FUNC(g300_device::vblank_r), FUNC(g300_device::vblank_w)); + map(0x128 << shift, (0x128 << shift) | 0x3).rw(FUNC(g300_device::vdisplay_r), FUNC(g300_device::vdisplay_w)); + map(0x129 << shift, (0x129 << shift) | 0x3).rw(FUNC(g300_device::linetime_r), FUNC(g300_device::linetime_w)); + map(0x12a << shift, (0x12a << shift) | 0x3).rw(FUNC(g300_device::tos_r), FUNC(g300_device::tos_w)); + map(0x12b << shift, (0x12b << shift) | 0x3).rw(FUNC(g300_device::meminit_r), FUNC(g300_device::meminit_w)); + map(0x12c << shift, (0x12c << shift) | 0x3).rw(FUNC(g300_device::transferdelay_r), FUNC(g300_device::transferdelay_w)); map(0x140 << shift, (0x140 << shift) | 0x3).rw(FUNC(g300_device::mask_r), FUNC(g300_device::mask_w)); map(0x160 << shift, (0x160 << shift) | 0x3).rw(FUNC(g300_device::control_r), FUNC(g300_device::control_w)); @@ -90,26 +92,32 @@ void g300_device::map(address_map &map) void g332_device::map(address_map &map) { - // datasheet gives unshifted addresses - const int shift = 2; // TODO: 64 bit mode + map(0x0000, 0x1fff).m(m_microport, FUNC(address_map_bank_device::amap32)); +} + +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; map(0x000 << shift, (0x000 << shift) | 0x3).w(FUNC(g332_device::boot_w)); // data path registers - map(0x021, (0x021 << shift) | 0x3).rw(FUNC(g332_device::halfsync_r), FUNC(g332_device::halfsync_w)); - map(0x022, (0x022 << shift) | 0x3).rw(FUNC(g332_device::backporch_r), FUNC(g332_device::backporch_w)); - map(0x023, (0x023 << shift) | 0x3).rw(FUNC(g332_device::display_r), FUNC(g332_device::display_w)); - map(0x024, (0x024 << shift) | 0x3).rw(FUNC(g332_device::shortdisplay_r), FUNC(g332_device::shortdisplay_w)); - map(0x025, (0x025 << shift) | 0x3).rw(FUNC(g332_device::broadpulse_r), FUNC(g332_device::broadpulse_w)); - map(0x026, (0x026 << shift) | 0x3).rw(FUNC(g332_device::vsync_r), FUNC(g332_device::vsync_w)); - map(0x027, (0x027 << shift) | 0x3).rw(FUNC(g332_device::vpreequalise_r), FUNC(g332_device::vpreequalise_w)); - map(0x028, (0x028 << shift) | 0x3).rw(FUNC(g332_device::vpostequalise_r), FUNC(g332_device::vpostequalise_w)); - map(0x029, (0x029 << shift) | 0x3).rw(FUNC(g332_device::vblank_r), FUNC(g332_device::vblank_w)); - map(0x02a, (0x02a << shift) | 0x3).rw(FUNC(g332_device::vdisplay_r), FUNC(g332_device::vdisplay_w)); - map(0x02b, (0x02b << shift) | 0x3).rw(FUNC(g332_device::linetime_r), FUNC(g332_device::linetime_w)); - map(0x02c, (0x02c << shift) | 0x3).rw(FUNC(g332_device::linestart_r), FUNC(g332_device::linestart_w)); - map(0x02d, (0x02d << shift) | 0x3).rw(FUNC(g332_device::meminit_r), FUNC(g332_device::meminit_w)); - map(0x02e, (0x02e << shift) | 0x3).rw(FUNC(g332_device::transferdelay_r), FUNC(g332_device::transferdelay_w)); + map(0x021 << shift, (0x021 << shift) | 0x3).rw(FUNC(g332_device::halfsync_r), FUNC(g332_device::halfsync_w)); + map(0x022 << shift, (0x022 << shift) | 0x3).rw(FUNC(g332_device::backporch_r), FUNC(g332_device::backporch_w)); + map(0x023 << shift, (0x023 << shift) | 0x3).rw(FUNC(g332_device::display_r), FUNC(g332_device::display_w)); + map(0x024 << shift, (0x024 << shift) | 0x3).rw(FUNC(g332_device::shortdisplay_r), FUNC(g332_device::shortdisplay_w)); + map(0x025 << shift, (0x025 << shift) | 0x3).rw(FUNC(g332_device::broadpulse_r), FUNC(g332_device::broadpulse_w)); + map(0x026 << shift, (0x026 << shift) | 0x3).rw(FUNC(g332_device::vsync_r), FUNC(g332_device::vsync_w)); + map(0x027 << shift, (0x027 << shift) | 0x3).rw(FUNC(g332_device::vpreequalise_r), FUNC(g332_device::vpreequalise_w)); + map(0x028 << shift, (0x028 << shift) | 0x3).rw(FUNC(g332_device::vpostequalise_r), FUNC(g332_device::vpostequalise_w)); + map(0x029 << shift, (0x029 << shift) | 0x3).rw(FUNC(g332_device::vblank_r), FUNC(g332_device::vblank_w)); + map(0x02a << shift, (0x02a << shift) | 0x3).rw(FUNC(g332_device::vdisplay_r), FUNC(g332_device::vdisplay_w)); + map(0x02b << shift, (0x02b << shift) | 0x3).rw(FUNC(g332_device::linetime_r), FUNC(g332_device::linetime_w)); + map(0x02c << shift, (0x02c << shift) | 0x3).rw(FUNC(g332_device::linestart_r), FUNC(g332_device::linestart_w)); + map(0x02d << shift, (0x02d << shift) | 0x3).rw(FUNC(g332_device::meminit_r), FUNC(g332_device::meminit_w)); + map(0x02e << shift, (0x02e << shift) | 0x3).rw(FUNC(g332_device::transferdelay_r), FUNC(g332_device::transferdelay_w)); map(0x040 << shift, (0x040 << shift) | 0x3).rw(FUNC(g332_device::mask_r), FUNC(g332_device::mask_w)); map(0x060 << shift, (0x060 << shift) | 0x3).rw(FUNC(g332_device::control_a_r), FUNC(g332_device::control_a_w)); @@ -117,6 +125,8 @@ void g332_device::map(address_map &map) map(0x080 << shift, (0x080 << shift) | 0x3).rw(FUNC(g332_device::tos_r), FUNC(g332_device::tos_w)); // cursor palette (0a1-0a3) + map(0x0a1 << shift, (0x0a3 << shift) | 0x3).rw(FUNC(g332_device::cursor_palette_r), FUNC(g332_device::cursor_palette_w)); + // checksum registers (0c0-0c2) // colour palette @@ -128,13 +138,208 @@ void g332_device::map(address_map &map) void ims_cvc_device::device_start() { - m_space = &space(0); + save_item(NAME(m_halfsync)); + save_item(NAME(m_backporch)); + save_item(NAME(m_display)); + save_item(NAME(m_shortdisplay)); + save_item(NAME(m_broadpulse)); + save_item(NAME(m_vsync)); + save_item(NAME(m_vblank)); + save_item(NAME(m_vdisplay)); + save_item(NAME(m_linetime)); + save_item(NAME(m_meminit)); + save_item(NAME(m_transferdelay)); + + save_item(NAME(m_mask)); + save_item(NAME(m_tos)); + save_item(NAME(m_boot)); } void ims_cvc_device::device_reset() { } -void ims_cvc_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +void g300_device::device_start() +{ + ims_cvc_device::device_start(); + + save_item(NAME(m_control)); +} + +void g332_device::device_start() +{ + ims_cvc_device::device_start(); + + 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)); +} + +void g332_device::device_reset() +{ + m_control_a = 0; +} + +u32 g300_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + offs_t address = m_tos; + + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++) + bitmap.pix(y, x) = pen_color(m_vram->read(address++) & m_mask); + + return 0; +} + +u32 g332_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + offs_t address = m_tos; + + switch (m_control_a & PIXEL_BITS) + { + case BPP_1: + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 8) + { + u8 pixel_data = m_vram->read(address++); + + bitmap.pix(y, x + 0) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 1) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 2) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 3) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 4) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 5) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 6) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 7) = pen_color(pixel_data & 0x1 & m_mask); + } + break; + + case BPP_2: + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 4) + { + u8 pixel_data = m_vram->read(address++); + + bitmap.pix(y, x + 0) = pen_color(pixel_data & 0x3 & m_mask); pixel_data >>= 2; + bitmap.pix(y, x + 1) = pen_color(pixel_data & 0x3 & m_mask); pixel_data >>= 2; + bitmap.pix(y, x + 2) = pen_color(pixel_data & 0x3 & m_mask); pixel_data >>= 2; + bitmap.pix(y, x + 3) = pen_color(pixel_data & 0x3 & m_mask); + } + break; + + case BPP_4: + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 2) + { + u8 pixel_data = m_vram->read(address++); + + bitmap.pix(y, x + 0) = pen_color(pixel_data & 0xf & m_mask); pixel_data >>= 4; + bitmap.pix(y, x + 1) = pen_color(pixel_data & 0xf & m_mask); + } + break; + + case BPP_8: + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++) + bitmap.pix(y, x) = pen_color(m_vram->read(address++) & m_mask); + break; + } + + 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) +{ + LOG("boot_w %s clock, multiplier %d, %d bit alignment (%s)\n", + (data & PLL_SELECT) ? "PLL" : "external", (data & PLL_MULTIPLIER), + (data & ALIGN_64) ? 64 : 32, machine().describe_context()); + + m_microport->set_shift((data & ALIGN_64) ? 0 : 1); + + mem_mask &= 0x00ffffffU; + COMBINE_DATA(&m_boot); +} + +void g332_device::control_a_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOG("control_a_w 0x%08x (%s)\n", data, machine().describe_context()); + + mem_mask &= 0x00ffffffU; + COMBINE_DATA(&m_control_a); + + 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 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, "%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, "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, "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"); + + 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); + + 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); + + rectangle const visarea(hbend, hbend + (m_display << 2) - 1, vbend, height - 1); + + 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 25c0163642d..82acfe5c6eb 100644 --- a/src/devices/video/ims_cvc.h +++ b/src/devices/video/ims_cvc.h @@ -5,15 +5,22 @@ #pragma once -class ims_cvc_device : - public device_t, - public device_memory_interface, - public device_palette_interface +#include "machine/bankdev.h" +#include "machine/ram.h" + +class ims_cvc_device + : public device_t + , public device_palette_interface { public: - virtual void map(address_map &map) = 0; + static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } + + // 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)); } - void screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + virtual void map(address_map &map) = 0; + virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) = 0; protected: ims_cvc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -22,51 +29,47 @@ protected: virtual void device_start() override; virtual void device_reset() override; - // device_memory_interface overrides - virtual space_config_vector memory_space_config() const override; - // device_palette_interface overrides - virtual u32 palette_entries() const override { return 256; } // FIXME + virtual u32 palette_entries() const override { return 256; } - u32 colour_palette_r(const offs_t offset) { return 0; } - void colour_palette_w(const offs_t offset, const u32 data) {} + u32 colour_palette_r(const offs_t offset); + void colour_palette_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU); u32 halfsync_r() { return m_halfsync; } - void halfsync_w(const u32 data) { m_halfsync = data; } + 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(const u32 data) { m_backporch = data; } + 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(const u32 data) { m_display = data; } + 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(const u32 data) { m_shortdisplay = data; } + 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(const u32 data) { m_broadpulse = data; } + 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(const u32 data) { m_vsync = data; } + 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(const u32 data) { m_vblank = data; } + 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(const u32 data) { m_vdisplay = data; } + 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(const u32 data) { m_linetime = data; } + 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(const u32 data) { m_meminit = data; } + 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(const u32 data) { m_transferdelay = data; } + 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(const u32 data) { m_mask = data; } + 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(const u32 data) { m_tos = data; } + void tos_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_tos); } - void boot_w(const u32 data) { m_boot = data; } + virtual void boot_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_boot); } -private: - // device_memory_interface members - const address_space_config m_space_config; - address_space *m_space; + required_device m_screen; + required_device m_vram; +protected: // device state u32 m_halfsync; u32 m_backporch; @@ -92,9 +95,13 @@ public: virtual void map(address_map &map) override; + virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override; + protected: + virtual void device_start() override; + u32 control_r() { return m_control; } - void control_w(const u32 data) { m_control = data; } + void control_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_control); } private: u32 m_control; @@ -107,21 +114,86 @@ public: virtual void map(address_map &map) override; + virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override; + + enum boot_mask : u32 + { + PLL_MULTIPLIER = 0x000001f, // pll multiplier + PLL_SELECT = 0x0000020, // pll clock select + ALIGN_64 = 0x0000040, // 64 bit address alignment + }; + + enum control_a_mask + { + VTG_ENABLE = 0x000001, // video timing generator enable + INTL_ENABLE = 0x000002, // interlace enable + INTL_FORMAT = 0x000004, // ccir/eia interlace format + SLAVE_MODE = 0x000008, // slave/master operating mode + SYNC_PATTERN = 0x000010, // plain/tesselated sync + SYNC_FORMAT = 0x000020, // separate/composite sync + VIDEO_FORMAT = 0x000040, // video only/composite video + sync + BLANK_LEVEL = 0x000080, // blanking pedestal/no blank pedestal + BLANK_IO = 0x000100, // CBlank is output/input + BLANK_FUNC = 0x000200, // undelayed ClkDisable/delayed CBlank + BLANK_FORCE = 0x000400, // screen blanked/no action + BLANK_DISABLE = 0x000800, // blanking disabled/enabled + ADDR_INC = 0x003000, // VRAM address increment + DMA_DISABLE = 0x004000, // DMA disabled/enabled + SYNC_DELAY = 0x038000, + INTERLEAVE = 0x040000, // interleave enabled/disabled + SAMPLE_DELAY = 0x080000, + PIXEL_BITS = 0x700000, // bits per pixel + CURSOR_DISABLE = 0x800000, // cursor disabled/enabled + }; + enum control_a_addr_inc_mask + { + INC_1 = 0x000000, + INC_256 = 0x001000, + INC_512 = 0x002000, + INC_1024 = 0x003000, + }; + enum control_a_bpp_mask + { + BPP_1 = 0x000000, + BPP_2 = 0x100000, + BPP_4 = 0x200000, + BPP_8 = 0x300000, + BPP_15 = 0x400000, + BPP_16 = 0x500000, + }; + protected: g332_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + // device_t overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + + // device_palette_interface overrides + virtual u32 palette_entries() const override { return 256 + 3; } + + 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); + u32 vpreequalise_r() { return m_vpreequalise; } - void vpreequalise_w(const u32 data) { m_vpreequalise = data; } + 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(const u32 data) { m_vpostequalise = data; } + 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(const u32 data) { m_linestart = data; } + 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(const u32 data) { m_control_a = data; } + 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(const u32 data) { m_control_b = data; } + void control_b_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_control_b); } private: + required_device m_microport; + u32 m_vpreequalise; u32 m_vpostequalise; u32 m_linestart; -- cgit v1.2.3