ams40041: Move PC1512 VDU emulation down into device

This commit is contained in:
AJR 2020-05-13 11:30:19 -04:00
parent 14dde3b679
commit 04c5294ca0
7 changed files with 212 additions and 174 deletions

View File

@ -1666,7 +1666,8 @@ files {
MAME_DIR .. "src/mame/includes/pc1512.h",
MAME_DIR .. "src/mame/machine/pc1512kb.cpp",
MAME_DIR .. "src/mame/machine/pc1512kb.h",
MAME_DIR .. "src/mame/video/pc1512.cpp",
MAME_DIR .. "src/mame/video/ams40041.cpp",
MAME_DIR .. "src/mame/video/ams40041.h",
MAME_DIR .. "src/mame/drivers/pcw.cpp",
MAME_DIR .. "src/mame/includes/pcw.h",
MAME_DIR .. "src/mame/video/pcw.cpp",

View File

@ -66,7 +66,6 @@ DEFINE_DEVICE_TYPE(HD6845S, hd6845s_device, "hd6845s", "Hitachi HD6845S CRTC"
DEFINE_DEVICE_TYPE(SY6545_1, sy6545_1_device, "sy6545_1", "Synertek SY6545-1 CRTC")
DEFINE_DEVICE_TYPE(SY6845E, sy6845e_device, "sy6845e", "Synertek SY6845E CRTC")
DEFINE_DEVICE_TYPE(HD6345, hd6345_device, "hd6345", "Hitachi HD6345 CRTC")
DEFINE_DEVICE_TYPE(AMS40041, ams40041_device, "ams40041", "AMS40041 CRTC")
DEFINE_DEVICE_TYPE(AMS40489, ams40489_device, "ams40489", "AMS40489 ASIC (CRTC)")
DEFINE_DEVICE_TYPE(MOS8563, mos8563_device, "mos8563", "MOS 8563 VDC")
DEFINE_DEVICE_TYPE(MOS8568, mos8568_device, "mos8568", "MOS 8568 VDC")
@ -1348,28 +1347,6 @@ void hd6345_device::device_start()
}
void ams40041_device::device_start()
{
mc6845_device::device_start();
m_horiz_char_total = 113;
m_horiz_disp = 80;
m_horiz_sync_pos = 90;
m_sync_width = 10;
m_vert_char_total = 127;
m_vert_total_adj = 6;
m_vert_disp = 100;
m_vert_sync_pos = 112;
m_mode_control = 2;
m_supports_disp_start_addr_r = false;
m_supports_vert_sync_width = false;
m_supports_status_reg_d5 = false;
m_supports_status_reg_d6 = false;
m_supports_status_reg_d7 = false;
m_supports_transparent = false;
}
void ams40489_device::device_start()
{
mc6845_device::device_start();
@ -1505,7 +1482,6 @@ void c6545_1_device::device_reset() { mc6845_device::device_reset(); }
void sy6545_1_device::device_reset() { mc6845_device::device_reset(); }
void sy6845e_device::device_reset() { mc6845_device::device_reset(); }
void hd6345_device::device_reset() { mc6845_device::device_reset(); }
void ams40041_device::device_reset() { mc6845_device::device_reset(); }
void ams40489_device::device_reset() { mc6845_device::device_reset(); }
void mos8563_device::device_reset()
@ -1586,11 +1562,6 @@ hd6345_device::hd6345_device(const machine_config &mconfig, const char *tag, dev
}
ams40041_device::ams40041_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: mc6845_device(mconfig, AMS40041, tag, owner, clock)
{
}
ams40489_device::ams40489_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: mc6845_device(mconfig, AMS40489, tag, owner, clock)
{

View File

@ -373,16 +373,6 @@ protected:
virtual void device_reset() override;
};
class ams40041_device : public mc6845_device
{
public:
ams40041_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void device_start() override;
virtual void device_reset() override;
};
class ams40489_device : public mc6845_device
{
public:
@ -481,7 +471,6 @@ DECLARE_DEVICE_TYPE(HD6845S, hd6845s_device)
DECLARE_DEVICE_TYPE(SY6545_1, sy6545_1_device)
DECLARE_DEVICE_TYPE(SY6845E, sy6845e_device)
DECLARE_DEVICE_TYPE(HD6345, hd6345_device)
DECLARE_DEVICE_TYPE(AMS40041, ams40041_device)
DECLARE_DEVICE_TYPE(AMS40489, ams40489_device)
DECLARE_DEVICE_TYPE(MOS8563, mos8563_device)
DECLARE_DEVICE_TYPE(MOS8568, mos8568_device)

View File

@ -96,6 +96,7 @@ PC1640-HD30: Western Digital 95038 [-chs 615,6,17 -ss 512]
#include "includes/pc1512.h"
#include "bus/rs232/rs232.h"
#include "bus/isa/ega.h"
#include "screen.h"
#include "softlist.h"
#include "speaker.h"
@ -610,7 +611,7 @@ uint8_t pc1640_state::io_r(offs_t offset)
void pc1512_state::pc1512_mem(address_map &map)
{
map(0x00000, 0x9ffff).ram();
map(0xb8000, 0xbbfff).rw(FUNC(pc1512_state::video_ram_r), FUNC(pc1512_state::video_ram_w));
map(0xb8000, 0xbbfff).rw(m_vdu, FUNC(ams40041_device::video_ram_r), FUNC(ams40041_device::video_ram_w));
map(0xfc000, 0xfffff).rom().region(I8086_TAG, 0);
}
@ -635,7 +636,7 @@ void pc1512_state::pc1512_io(address_map &map)
map(0x080, 0x083).w(FUNC(pc1512_state::dma_page_w));
map(0x0a1, 0x0a1).w(FUNC(pc1512_state::nmi_mask_w));
map(0x378, 0x37b).rw(FUNC(pc1512_state::printer_r), FUNC(pc1512_state::printer_w));
map(0x3d0, 0x3df).rw(FUNC(pc1512_state::vdu_r), FUNC(pc1512_state::vdu_w));
map(0x3d0, 0x3df).rw(m_vdu, FUNC(ams40041_device::vdu_r), FUNC(ams40041_device::vdu_w));
map(0x3f0, 0x3f7).m(m_fdc, FUNC(pc_fdc_xt_device::map));
map(0x3f8, 0x3ff).rw(m_uart, FUNC(ins8250_device::ins8250_r), FUNC(ins8250_device::ins8250_w));
}
@ -1092,18 +1093,6 @@ void pc1512_state::machine_start()
address_space &program = m_maincpu->space(AS_PROGRAM);
program.unmap_readwrite(ram_size, 0x9ffff);
}
// state saving
save_item(NAME(m_toggle));
save_item(NAME(m_lpen));
save_item(NAME(m_blink));
save_item(NAME(m_cursor));
save_item(NAME(m_blink_ctr));
save_item(NAME(m_vdu_mode));
save_item(NAME(m_vdu_color));
save_item(NAME(m_vdu_plane));
save_item(NAME(m_vdu_rdsel));
save_item(NAME(m_vdu_border));
}
void pc1512_base_state::machine_reset()
@ -1119,18 +1108,7 @@ void pc1512_state::machine_reset()
{
pc1512_base_state::machine_reset();
m_toggle = 0;
m_pit2 = 1;
m_lpen = 0;
m_blink = 0;
m_cursor = 0;
m_blink_ctr = 0;
m_vdu_mode = 0;
m_vdu_color = 0;
m_vdu_rdsel = 0;
m_vdu_plane = 0x0f;
m_vdu_border = 0;
}
@ -1163,7 +1141,13 @@ void pc1512_state::pc1512(machine_config &config)
m_maincpu->set_irq_acknowledge_callback(I8259A2_TAG, FUNC(pic8259_device::inta_cb));
// video
pc1512_video(config);
screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER));
screen.set_raw(28.636363_MHz_XTAL, 912, 0, 910, 262, 0, 260);
screen.set_screen_update(m_vdu, FUNC(ams40041_device::screen_update));
AMS40041(config, m_vdu, 28.636363_MHz_XTAL);
m_vdu->set_screen(SCREEN_TAG);
m_vdu->set_show_border_area(true);
// sound
SPEAKER(config, "mono").front_center();
@ -1332,10 +1316,10 @@ void pc1640_state::pc1640(machine_config &config)
m_dmac->out_dack_callback<2>().set(FUNC(pc1640_state::dack2_w));
m_dmac->out_dack_callback<3>().set(FUNC(pc1640_state::dack3_w));
PIC8259(config, m_pic, 0);
PIC8259(config, m_pic);
m_pic->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
PIT8253(config, m_pit, 0);
PIT8253(config, m_pit);
m_pit->set_clk<0>(28.636363_MHz_XTAL / 24);
m_pit->out_handler<0>().set(m_pic, FUNC(pic8259_device::ir0_w));
m_pit->set_clk<1>(28.636363_MHz_XTAL / 24);

View File

@ -23,8 +23,7 @@
#include "machine/pc_fdc.h"
#include "machine/ram.h"
#include "sound/spkrdev.h"
#include "video/mc6845.h"
#include "screen.h"
#include "video/ams40041.h"
#include "formats/pc_dsk.h"
@ -202,31 +201,11 @@ public:
pc1512_state(const machine_config &mconfig, device_type type, const char *tag)
: pc1512_base_state(mconfig, type, tag)
, m_vdu(*this, AMS40041_TAG)
, m_video_ram(*this, "video_ram")
, m_char_rom(*this, AMS40041_TAG)
, m_screen(*this, SCREEN_TAG) { }
{ }
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
int get_display_mode(uint8_t mode);
offs_t get_char_rom_offset();
int get_color(uint8_t data);
MC6845_UPDATE_ROW(draw_alpha);
MC6845_UPDATE_ROW(draw_graphics_1);
MC6845_UPDATE_ROW(draw_graphics_2);
MC6845_UPDATE_ROW(crtc_update_row);
uint8_t video_ram_r(offs_t offset);
void video_ram_w(offs_t offset, uint8_t data);
uint8_t vdu_r(offs_t offset);
void vdu_w(offs_t offset, uint8_t data);
void pc1512_video(machine_config &config);
void pc1512hd(machine_config &config);
void pc1512(machine_config &config);
void pc1512dd(machine_config &config);
@ -234,21 +213,6 @@ public:
void pc1512_mem(address_map &map);
required_device<ams40041_device> m_vdu;
optional_shared_ptr<uint8_t> m_video_ram;
required_memory_region m_char_rom;
required_device<screen_device> m_screen;
// video state
int m_toggle;
int m_lpen;
int m_blink;
int m_cursor;
int m_blink_ctr;
uint8_t m_vdu_mode;
uint8_t m_vdu_color;
uint8_t m_vdu_plane;
uint8_t m_vdu_rdsel;
uint8_t m_vdu_border;
};
class pc1640_state : public pc1512_base_state
@ -275,6 +239,4 @@ public:
void pc1640_mem(address_map &map);
};
// ---------- defined in video/pc1512.c ----------
#endif // MAME_INCLUDES_PC1512_H

View File

@ -1,17 +1,17 @@
// license:BSD-3-Clause
// copyright-holders:Curt Coder
#include "emu.h"
#include "includes/pc1512.h"
#include "ams40041.h"
#include "screen.h"
#define VERBOSE 0
#include "logmacro.h"
//**************************************************************************
// CONSTANTS
//**************************************************************************
#define LOG 0
static const rgb_t PALETTE_1512[] =
{
@ -64,6 +64,92 @@ enum
//**************************************************************************
// AMS40041 DEVICE
//**************************************************************************
DEFINE_DEVICE_TYPE(AMS40041, ams40041_device, "ams40041", "AMS40041 VDU")
//-------------------------------------------------
// ams40041_device - constructor
//-------------------------------------------------
ams40041_device::ams40041_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: mc6845_device(mconfig, AMS40041, tag, owner, clock)
, m_char_rom(*this, DEVICE_SELF)
, m_lk(*this, "^LK") // hack
{
m_clk_scale = 32;
set_char_width(8);
set_update_row_callback(*this, FUNC(ams40041_device::crtc_update_row));
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void ams40041_device::device_start()
{
mc6845_device::device_start();
m_horiz_char_total = 113;
m_horiz_disp = 80;
m_horiz_sync_pos = 90;
m_sync_width = 10;
m_vert_char_total = 127;
m_vert_total_adj = 6;
m_vert_disp = 100;
m_vert_sync_pos = 112;
m_mode_control = 2;
m_supports_disp_start_addr_r = false;
m_supports_vert_sync_width = false;
m_supports_status_reg_d5 = false;
m_supports_status_reg_d6 = false;
m_supports_status_reg_d7 = false;
m_supports_transparent = false;
// allocate memory
m_video_ram = std::make_unique<uint8_t[]>(0x10000);
// state saving
save_pointer(NAME(m_video_ram), 0x10000);
save_item(NAME(m_toggle));
save_item(NAME(m_lpen));
save_item(NAME(m_blink));
save_item(NAME(m_cursor));
save_item(NAME(m_blink_ctr));
save_item(NAME(m_vdu_mode));
save_item(NAME(m_vdu_color));
save_item(NAME(m_vdu_plane));
save_item(NAME(m_vdu_rdsel));
save_item(NAME(m_vdu_border));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void ams40041_device::device_reset()
{
mc6845_device::device_reset();
m_toggle = 0;
m_lpen = 0;
m_blink = 0;
m_cursor = 0;
m_blink_ctr = 0;
m_vdu_mode = 0;
m_vdu_color = 0;
m_vdu_rdsel = 0;
m_vdu_plane = 0x0f;
m_vdu_border = 0;
}
//**************************************************************************
// VIDEO RAM ACCESS
//**************************************************************************
@ -72,7 +158,7 @@ enum
// video_ram_r -
//-------------------------------------------------
uint8_t pc1512_state::video_ram_r(offs_t offset)
uint8_t ams40041_device::video_ram_r(offs_t offset)
{
uint8_t data = 0;
@ -100,7 +186,7 @@ uint8_t pc1512_state::video_ram_r(offs_t offset)
// video_ram_w -
//-------------------------------------------------
void pc1512_state::video_ram_w(offs_t offset, uint8_t data)
void ams40041_device::video_ram_w(offs_t offset, uint8_t data)
{
switch (get_display_mode(m_vdu_mode))
{
@ -130,14 +216,14 @@ void pc1512_state::video_ram_w(offs_t offset, uint8_t data)
// vdu_r -
//-------------------------------------------------
uint8_t pc1512_state::vdu_r(offs_t offset)
uint8_t ams40041_device::vdu_r(offs_t offset)
{
uint8_t data = 0;
switch (offset)
{
case 1: case 3: case 5: case 7:
data = m_vdu->register_r();
data = register_r();
break;
case 0xa: // VDU Status
@ -167,11 +253,11 @@ uint8_t pc1512_state::vdu_r(offs_t offset)
data |= 0x04;
// vertical sync
//data |= m_vdu->vsync_r();
//data |= vsync_r();
int flyback = 0;
if (m_screen->vpos() < VFP_LORES - 16) flyback = 1;
if (m_screen->vpos() > VFP_LORES + 200) flyback = 1;
if (screen().vpos() < VFP_LORES - 16) flyback = 1;
if (screen().vpos() > VFP_LORES + 200) flyback = 1;
data |= flyback << 3;
break;
@ -185,16 +271,16 @@ uint8_t pc1512_state::vdu_r(offs_t offset)
// vdu_w -
//-------------------------------------------------
void pc1512_state::vdu_w(offs_t offset, uint8_t data)
void ams40041_device::vdu_w(offs_t offset, uint8_t data)
{
switch (offset)
{
case 0: case 2: case 4: case 6:
m_vdu->address_w(data);
address_w(data);
break;
case 1: case 3: case 5: case 7:
m_vdu->register_w(data);
register_w(data);
break;
case 8: // VDU Mode Control
@ -213,7 +299,7 @@ void pc1512_state::vdu_w(offs_t offset, uint8_t data)
*/
if (LOG) logerror("VDU Mode Control %02x\n", data);
LOG("VDU Mode Control %02x\n", data);
if ((get_display_mode(m_vdu_mode) != GRAPHICS_2) && (get_display_mode(data) == GRAPHICS_2))
{
@ -232,18 +318,21 @@ void pc1512_state::vdu_w(offs_t offset, uint8_t data)
{
case ALPHA_40:
case GRAPHICS_1:
m_vdu->set_hpixels_per_column(8);
m_vdu->set_unscaled_clock(XTAL(28'636'363)/32);
set_hpixels_per_column(8);
m_clk_scale = 32;
recompute_parameters(true);
break;
case ALPHA_80:
m_vdu->set_hpixels_per_column(8);
m_vdu->set_unscaled_clock(XTAL(28'636'363)/16);
set_hpixels_per_column(8);
m_clk_scale = 16;
recompute_parameters(true);
break;
case GRAPHICS_2:
m_vdu->set_hpixels_per_column(16);
m_vdu->set_unscaled_clock(XTAL(28'636'363)/32);
set_hpixels_per_column(16);
m_clk_scale = 32;
recompute_parameters(true);
break;
}
}
@ -267,23 +356,23 @@ void pc1512_state::vdu_w(offs_t offset, uint8_t data)
*/
if (LOG) logerror("VDU Colour Select %02x\n", data);
LOG("VDU Colour Select %02x\n", data);
m_vdu_color = data;
break;
case 0xb: // Clear Light Pen Latch
if (LOG) logerror("VDU Clear Light Pen Latch\n");
LOG("VDU Clear Light Pen Latch\n");
m_lpen = 0;
break;
case 0xc: // Set Light Pen Latch
if (LOG) logerror("VDU Set Light Pen Latch\n");
LOG("VDU Set Light Pen Latch\n");
if (!m_lpen)
{
m_vdu->assert_light_pen_input();
assert_light_pen_input();
}
m_lpen = 1;
@ -305,7 +394,7 @@ void pc1512_state::vdu_w(offs_t offset, uint8_t data)
*/
if (LOG) logerror("VDU Colour Plane Write %01x\n", data & 0x0f);
LOG("VDU Colour Plane Write %01x\n", data & 0x0f);
if (get_display_mode(m_vdu_mode) == GRAPHICS_2)
{
@ -329,7 +418,7 @@ void pc1512_state::vdu_w(offs_t offset, uint8_t data)
*/
if (LOG) logerror("VDU Colour Plane Read %u\n", data & 0x03);
LOG("VDU Colour Plane Read %u\n", data & 0x03);
if (get_display_mode(m_vdu_mode) == GRAPHICS_2)
{
@ -353,7 +442,7 @@ void pc1512_state::vdu_w(offs_t offset, uint8_t data)
*/
if (LOG) logerror("VDU Graphics Mode 2 Border %u\n", data & 0x0f);
LOG("VDU Graphics Mode 2 Border %u\n", data & 0x0f);
m_vdu_border = data;
break;
@ -365,7 +454,7 @@ void pc1512_state::vdu_w(offs_t offset, uint8_t data)
// mc6845
//-------------------------------------------------
int pc1512_state::get_display_mode(uint8_t mode)
int ams40041_device::get_display_mode(uint8_t mode)
{
if (mode & MODE_GRAPHICS)
{
@ -391,12 +480,12 @@ int pc1512_state::get_display_mode(uint8_t mode)
}
}
offs_t pc1512_state::get_char_rom_offset()
offs_t ams40041_device::get_char_rom_offset()
{
return ((m_lk->read() >> 5) & 0x03) << 11;
}
MC6845_UPDATE_ROW( pc1512_state::draw_alpha )
MC6845_UPDATE_ROW( ams40041_device::draw_alpha )
{
offs_t char_rom_offset = get_char_rom_offset();
uint32_t *p = &bitmap.pix32(y + vbp, hbp);
@ -424,7 +513,7 @@ MC6845_UPDATE_ROW( pc1512_state::draw_alpha )
}
offs_t addr = char_rom_offset | (code << 3) | (ra & 0x07);
uint8_t data = m_char_rom->base()[addr & 0x1fff];
uint8_t data = m_char_rom[addr & 0x1fff];
if ((column == cursor_x) && m_cursor)
{
@ -442,7 +531,7 @@ MC6845_UPDATE_ROW( pc1512_state::draw_alpha )
}
}
int pc1512_state::get_color(uint8_t data)
int ams40041_device::get_color(uint8_t data)
{
if (data == 0) return m_vdu_color & 0x0f;
@ -465,7 +554,7 @@ int pc1512_state::get_color(uint8_t data)
return color;
}
MC6845_UPDATE_ROW( pc1512_state::draw_graphics_1 )
MC6845_UPDATE_ROW( ams40041_device::draw_graphics_1 )
{
if (y > 199) return;
@ -485,7 +574,7 @@ MC6845_UPDATE_ROW( pc1512_state::draw_graphics_1 )
}
}
MC6845_UPDATE_ROW( pc1512_state::draw_graphics_2 )
MC6845_UPDATE_ROW( ams40041_device::draw_graphics_2 )
{
if (y > 199) return;
@ -508,7 +597,7 @@ MC6845_UPDATE_ROW( pc1512_state::draw_graphics_2 )
}
}
MC6845_UPDATE_ROW( pc1512_state::crtc_update_row )
MC6845_UPDATE_ROW( ams40041_device::crtc_update_row )
{
switch (get_display_mode(m_vdu_mode))
{
@ -528,14 +617,7 @@ MC6845_UPDATE_ROW( pc1512_state::crtc_update_row )
}
void pc1512_state::video_start()
{
// allocate memory
m_video_ram.allocate(0x10000);
}
uint32_t pc1512_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
uint32_t ams40041_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
if (m_vdu_mode & MODE_ENABLE_VIDEO)
{
@ -578,7 +660,7 @@ uint32_t pc1512_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap
break;
}
m_vdu->screen_update(screen, bitmap, cliprect);
mc6845_device::screen_update(screen, bitmap, cliprect);
}
else
{
@ -587,24 +669,3 @@ uint32_t pc1512_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap
return 0;
}
//-------------------------------------------------
// machine_config( pc1512 )
//-------------------------------------------------
void pc1512_state::pc1512_video(machine_config &config)
{
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_screen_update(FUNC(pc1512_state::screen_update));
m_screen->set_size(80*8, 24*8);
m_screen->set_visarea(0, 80*8-1, 0, 24*8-1);
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500));
m_screen->set_refresh_hz(50);
AMS40041(config, m_vdu, XTAL(28'636'363)/32);
m_vdu->set_screen(m_screen);
m_vdu->set_show_border_area(true);
m_vdu->set_char_width(8);
m_vdu->set_update_row_callback(FUNC(pc1512_state::crtc_update_row));
}

70
src/mame/video/ams40041.h Normal file
View File

@ -0,0 +1,70 @@
// license:BSD-3-Clause
// copyright-holders:Curt Coder
#ifndef MAME_VIDEO_AMS40041_H
#define MAME_VIDEO_AMS40041_H
#pragma once
#include "video/mc6845.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> ams40041_device
class ams40041_device : public mc6845_device
{
public:
// device type constructor
ams40041_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// screen update callback
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
// memory handlers
uint8_t video_ram_r(offs_t offset);
void video_ram_w(offs_t offset, uint8_t data);
// I/O handlers
uint8_t vdu_r(offs_t offset);
void vdu_w(offs_t offset, uint8_t data);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
// VDU helpers
static int get_display_mode(uint8_t mode);
offs_t get_char_rom_offset();
int get_color(uint8_t data);
MC6845_UPDATE_ROW(draw_alpha);
MC6845_UPDATE_ROW(draw_graphics_1);
MC6845_UPDATE_ROW(draw_graphics_2);
MC6845_UPDATE_ROW(crtc_update_row);
std::unique_ptr<uint8_t[]> m_video_ram;
required_region_ptr<uint8_t> m_char_rom;
required_ioport m_lk;
// video state
int m_toggle;
int m_lpen;
int m_blink;
int m_cursor;
int m_blink_ctr;
uint8_t m_vdu_mode;
uint8_t m_vdu_color;
uint8_t m_vdu_plane;
uint8_t m_vdu_rdsel;
uint8_t m_vdu_border;
};
// device type declaration
DECLARE_DEVICE_TYPE(AMS40041, ams40041_device)
#endif // MAME_VIDEO_AMS40041_H