// license:BSD-3-Clause
// copyright-holders:Patrick Mackinlay
#ifndef MAME_VIDEO_IMS_CVC_H
#define MAME_VIDEO_IMS_CVC_H
#pragma once
#include "machine/bankdev.h"
#include "machine/ram.h"
class ims_cvc_device
: public device_t
, public device_palette_interface
{
public:
static u32 const MASK24 = 0xffffffU;
// configuration
template <typename T> void set_screen(T &&tag) { m_screen.set_tag(std::forward<T>(tag)); }
template <typename T> void set_vram(T &&tag) { m_vram.set_tag(std::forward<T>(tag)); }
virtual void map(address_map &map) = 0;
virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect) = 0;
virtual void set_swapped(bool swapped) { m_swap = swapped ? 3 : 0; }
protected:
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;
virtual void device_reset() override;
// device_palette_interface overrides
virtual u32 palette_entries() const noexcept override { return 256; }
virtual void boot_w(u32 data) { m_boot = data & MASK24; }
// register read handlers
u32 halfsync_r() { return m_halfsync; }
u32 backporch_r() { return m_backporch; }
u32 display_r() { return m_display; }
u32 shortdisplay_r() { return m_shortdisplay; }
u32 broadpulse_r() { return m_broadpulse; }
u32 vsync_r() { return m_vsync; }
u32 vblank_r() { return m_vblank; }
u32 vdisplay_r() { return m_vdisplay; }
u32 linetime_r() { return m_linetime; }
u32 meminit_r() { return m_meminit; }
u32 transferdelay_r() { return m_transferdelay; }
u32 mask_r() { return m_mask; }
u32 tos_r() { return m_tos; }
// 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<screen_device> m_screen;
required_device<ram_device> m_vram;
protected:
// device state
u32 m_halfsync;
u32 m_backporch;
u32 m_display;
u32 m_shortdisplay;
u32 m_broadpulse;
u32 m_vsync;
u32 m_vblank;
u32 m_vdisplay;
u32 m_linetime;
u32 m_meminit;
u32 m_transferdelay;
u32 m_mask;
u32 m_tos;
u32 m_boot;
unsigned m_swap = 0;
};
class g300_device : public ims_cvc_device
{
public:
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, rectangle const &cliprect) override;
protected:
virtual void device_start() override;
u32 control_r() { return m_control; }
void control_w(u32 data) { m_control = data & MASK24; }
private:
u32 m_control;
};
class g332_device : public ims_cvc_device
{
public:
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, rectangle const &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(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;
virtual void device_start() override;
virtual void device_reset() override;
// device_palette_interface overrides
virtual u32 palette_entries() const noexcept override { return 256 + 3; }
virtual void microport_map(address_map &map);
virtual void boot_w(u32 data) override;
// register read handlers
u32 vpreequalise_r() { return m_vpreequalise; }
u32 vpostequalise_r() { return m_vpostequalise; }
u32 linestart_r() { return m_linestart; }
u32 control_a_r() { return m_control_a; }
u32 control_b_r() { return 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<address_map_bank_device> m_microport;
u32 m_vpreequalise;
u32 m_vpostequalise;
u32 m_linestart;
u32 m_control_a;
u32 m_control_b;
u32 m_cursor_start;
std::unique_ptr<u16[]> m_cursor_store;
};
class g364_device : public g332_device
{
public:
g364_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
virtual void set_swapped(bool swapped) override { m_swap = swapped ? 7 : 0; }
};
DECLARE_DEVICE_TYPE(G300, g300_device)
DECLARE_DEVICE_TYPE(G332, g332_device)
DECLARE_DEVICE_TYPE(G364, g364_device)
#endif // MAME_VIDEO_IMS_CVC_H