// license:BSD-3-Clause
// copyright-holders:Curt Coder, Olivier Galibert
/*
TODO:
- rewrite shifter
- STe pixelofs
- blitter hog
- high resolution
*/
#include "emu.h"
#include "video/atarist.h"
#include "includes/atarist.h"
//**************************************************************************
// CONSTANTS / MACROS
//**************************************************************************
#define LOG 0
static const int BLITTER_NOPS[16][4] =
{
{ 1, 1, 1, 1 },
{ 2, 2, 3, 3 },
{ 2, 2, 3, 3 },
{ 1, 1, 2, 2 },
{ 2, 2, 3, 3 },
{ 2, 2, 2, 2 },
{ 2, 2, 3, 3 },
{ 2, 2, 3, 3 },
{ 2, 2, 3, 3 },
{ 2, 2, 3, 3 },
{ 2, 2, 2, 2 },
{ 2, 2, 3, 3 },
{ 1, 1, 2, 2 },
{ 2, 2, 3, 3 },
{ 2, 2, 3, 3 },
{ 1, 1, 1, 1 }
};
//**************************************************************************
// SHIFTER
//**************************************************************************
//-------------------------------------------------
// shift_mode_0 -
//-------------------------------------------------
inline pen_t st_state::shift_mode_0()
{
int color = (BIT(m_shifter_rr[3], 15) << 3) | (BIT(m_shifter_rr[2], 15) << 2) | (BIT(m_shifter_rr[1], 15) << 1) | BIT(m_shifter_rr[0], 15);
m_shifter_rr[0] <<= 1;
m_shifter_rr[1] <<= 1;
m_shifter_rr[2] <<= 1;
m_shifter_rr[3] <<= 1;
return m_palette->pen(color);
}
//-------------------------------------------------
// shift_mode_1 -
//-------------------------------------------------
inline pen_t st_state::shift_mode_1()
{
int color = (BIT(m_shifter_rr[1], 15) << 1) | BIT(m_shifter_rr[0], 15);
m_shifter_rr[0] <<= 1;
m_shifter_rr[1] <<= 1;
m_shifter_shift++;
if (m_shifter_shift == 16)
{
m_shifter_rr[0] = m_shifter_rr[2];
m_shifter_rr[1] = m_shifter_rr[3];
m_shifter_rr[2] = m_shifter_rr[3] = 0;
m_shifter_shift = 0;
}
return m_palette->pen(color);
}
//-------------------------------------------------
// shift_mode_2 -
//-------------------------------------------------
inline pen_t st_state::shift_mode_2()
{
int color = BIT(m_shifter_rr[0], 15);
m_shifter_rr[0] <<= 1;
m_shifter_shift++;
switch (m_shifter_shift)
{
case 16:
m_shifter_rr[0] = m_shifter_rr[1];
m_shifter_rr[1] = m_shifter_rr[2];
m_shifter_rr[2] = m_shifter_rr[3];
m_shifter_rr[3] = 0;
break;
case 32:
m_shifter_rr[0] = m_shifter_rr[1];
m_shifter_rr[1] = m_shifter_rr[2];
m_shifter_rr[2] = 0;
break;
case 48:
m_shifter_rr[0] = m_shifter_rr[1];
m_shifter_rr[1] = 0;
m_shifter_shift = 0;
break;
}
return m_palette->pen(color);
}
//-------------------------------------------------
// shifter_tick -
//-------------------------------------------------
void st_state::shifter_tick()
{
int y = m_screen->vpos();
int x = m_screen->hpos();
pen_t pen;
switch (m_shifter_mode)
{
case 0:
pen = shift_mode_0();
break;
case 1:
pen = shift_mode_1();
break;
case 2:
pen = shift_mode_2();
break;
default:
pen = m_palette->black_pen();
break;
}
m_bitmap.pix32(y, x) = pen;
}
//-------------------------------------------------
// shifter_load -
//-------------------------------------------------
inline void st_state::shifter_load()
{
address_space &program = m_maincpu->space(AS_PROGRAM);
uint16_t data = program.read_word(m_shifter_ofs);
m_shifter_ir[m_shifter_bitplane] = data;
m_shifter_bitplane++;
m_shifter_ofs += 2;
if (m_shifter_bitplane == 4)
{
m_shifter_bitplane = 0;
m_shifter_rr[0] = m_shifter_ir[0];
m_shifter_rr[1] = m_shifter_ir[1];
m_shifter_rr[2] = m_shifter_ir[2];
m_shifter_rr[3] = m_shifter_ir[3];
}
}
//-------------------------------------------------
// glue_tick -
//-------------------------------------------------
void st_state::draw_pixel(int x, int y, u32 pen)
{
if(x < m_bitmap.width() && y < m_bitmap.height())
m_bitmap.pix32(y, x) = pen;
}
void st_state::glue_tick()
{
int y = m_screen->vpos();
int x = m_screen->hpos();
int v = (y >= m_shifter_y_start) && (y < m_shifter_y_end);
int h = (x >= m_shifter_x_start) && (x < m_shifter_x_end);
if(m_shifter_mode == 1) {
int dt = 8;
h = (x >= m_shifter_x_start-dt) && (x < m_shifter_x_end-dt);
}
int de = h && v;
if(!x) {
m_shifter_bitplane = 0;
m_shifter_shift = 0;
}
if (de != m_shifter_de)
{
m_mfp->tbi_w(de);
m_shifter_de = de;
}
if (de)
{
shifter_load();
}
if ((y == m_shifter_vblank_start) && (x == 0))
{
m_maincpu->set_input_line(M68K_IRQ_4, HOLD_LINE);
m_shifter_ofs = m_shifter_base;
}
if (x == m_shifter_hblank_start)
{
m_maincpu->set_input_line(M68K_IRQ_2, HOLD_LINE);
// m_shifter_ofs += (m_shifter_lineofs * 2); // STe
}
pen_t pen;
switch (m_shifter_mode)
{
case 0:
pen = shift_mode_0();
draw_pixel(x, y, pen);
draw_pixel(x+1, y, pen);
pen = shift_mode_0();
draw_pixel(x+2, y, pen);
draw_pixel(x+3, y, pen);
pen = shift_mode_0();
draw_pixel(x+4, y, pen);
draw_pixel(x+5, y, pen);
pen = shift_mode_0();
draw_pixel(x+6, y, pen);
draw_pixel(x+7, y, pen);
break;
case 1:
pen = shift_mode_1();
draw_pixel(x, y, pen);
pen = shift_mode_1();
draw_pixel(x+1, y, pen);
pen = shift_mode_1();
draw_pixel(x+2, y, pen);
pen = shift_mode_1();
draw_pixel(x+3, y, pen);
pen = shift_mode_1();
draw_pixel(x+4, y, pen);
pen = shift_mode_1();
draw_pixel(x+5, y, pen);
pen = shift_mode_1();
draw_pixel(x+6, y, pen);
pen = shift_mode_1();
draw_pixel(x+7, y, pen);
break;
case 2:
pen = shift_mode_2();
break;
default:
pen = m_palette->black_pen();
break;
}
}
//-------------------------------------------------
// set_screen_parameters -
//-------------------------------------------------
void st_state::set_screen_parameters()
{
if (m_shifter_sync & 0x02)
{
m_shifter_x_start = ATARIST_HBDEND_PAL*2;
m_shifter_x_end = ATARIST_HBDSTART_PAL*2;
m_shifter_y_start = ATARIST_VBDEND_PAL;
m_shifter_y_end = ATARIST_VBDSTART_PAL;
m_shifter_hblank_start = ATARIST_HBSTART_PAL*2;
m_shifter_vblank_start = ATARIST_VBSTART_PAL;
}
else
{
m_shifter_x_start = ATARIST_HBDEND_NTSC*2;
m_shifter_x_end = ATARIST_HBDSTART_NTSC*2;
m_shifter_y_start = ATARIST_VBDEND_NTSC;
m_shifter_y_end = ATARIST_VBDSTART_NTSC;
m_shifter_hblank_start = ATARIST_HBSTART_NTSC*2;
m_shifter_vblank_start = ATARIST_VBSTART_NTSC;
}
}
//-------------------------------------------------
// shifter_base_r -
//-------------------------------------------------
READ8_MEMBER( st_state::shifter_base_r )
{
uint8_t data = 0;
switch (offset)
{
case 0x00:
data = (m_shifter_base >> 16) & 0x3f;
break;
case 0x01:
data = (m_shifter_base >> 8) & 0xff;
break;
}
return data;
}
//-------------------------------------------------
// shifter_base_w -
//-------------------------------------------------
WRITE8_MEMBER( st_state::shifter_base_w )
{
switch (offset)
{
case 0x00:
m_shifter_base = (m_shifter_base & 0x00ff00) | (data & 0x3f) << 16;
logerror("SHIFTER Video Base Address %06x\n", m_shifter_base);
break;
case 0x01:
m_shifter_base = (m_shifter_base & 0x3f0000) | (data << 8);
logerror("SHIFTER Video Base Address %06x\n", m_shifter_base);
break;
}
}
//-------------------------------------------------
// shifter_counter_r -
//-------------------------------------------------
READ8_MEMBER( st_state::shifter_counter_r )
{
uint8_t data = 0;
switch (offset)
{
case 0x00:
data = (m_shifter_ofs >> 16) & 0x3f;
break;
case 0x01:
data = (m_shifter_ofs >> 8) & 0xff;
break;
case 0x02:
data = m_shifter_ofs & 0xff;
break;
}
return data;
}
//-------------------------------------------------
// shifter_sync_r -
//-------------------------------------------------
READ8_MEMBER( st_state::shifter_sync_r )
{
return m_shifter_sync;
}
//-------------------------------------------------
// shifter_sync_w -
//-------------------------------------------------
WRITE8_MEMBER( st_state::shifter_sync_w )
{
m_shifter_sync = data;
logerror("SHIFTER Sync %x\n", m_shifter_sync);
set_screen_parameters();
}
//-------------------------------------------------
// shifter_mode_r -
//-------------------------------------------------
READ8_MEMBER( st_state::shifter_mode_r )
{
return m_shifter_mode;
}
//-------------------------------------------------
// shifter_mode_w -
//-------------------------------------------------
WRITE8_MEMBER( st_state::shifter_mode_w )
{
m_shifter_mode = data;
logerror("SHIFTER Mode %x\n", m_shifter_mode);
}
//-------------------------------------------------
// shifter_palette_r -
//-------------------------------------------------
READ16_MEMBER( st_state::shifter_palette_r )
{
return m_shifter_palette[offset] | 0xf888;
}
//-------------------------------------------------
// shifter_palette_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::shifter_palette_w )
{
m_shifter_palette[offset] = data;
// logerror("SHIFTER Palette[%x] = %x\n", offset, data);
m_palette->set_pen_color(offset, pal3bit(data >> 8), pal3bit(data >> 4), pal3bit(data));
}
//**************************************************************************
// STE SHIFTER
//**************************************************************************
//-------------------------------------------------
// shifter_base_low_r -
//-------------------------------------------------
READ8_MEMBER( ste_state::shifter_base_low_r )
{
return m_shifter_base & 0xfe;
}
//-------------------------------------------------
// shifter_base_low_w -
//-------------------------------------------------
WRITE8_MEMBER( ste_state::shifter_base_low_w )
{
m_shifter_base = (m_shifter_base & 0x3fff00) | (data & 0xfe);
logerror("SHIFTER Video Base Address %06x\n", m_shifter_base);
}
//-------------------------------------------------
// shifter_counter_r -
//-------------------------------------------------
READ8_MEMBER( ste_state::shifter_counter_r )
{
uint8_t data = 0;
switch (offset)
{
case 0x00:
data = (m_shifter_ofs >> 16) & 0x3f;
break;
case 0x01:
data = (m_shifter_ofs >> 8) & 0xff;
break;
case 0x02:
data = m_shifter_ofs & 0xfe;
break;
}
return data;
}
//-------------------------------------------------
// shifter_counter_w -
//-------------------------------------------------
WRITE8_MEMBER( ste_state::shifter_counter_w )
{
switch (offset)
{
case 0x00:
m_shifter_ofs = (m_shifter_ofs & 0x00fffe) | (data & 0x3f) << 16;
logerror("SHIFTER Video Address Counter %06x\n", m_shifter_ofs);
break;
case 0x01:
m_shifter_ofs = (m_shifter_ofs & 0x3f00fe) | (data << 8);
logerror("SHIFTER Video Address Counter %06x\n", m_shifter_ofs);
break;
case 0x02:
m_shifter_ofs = (m_shifter_ofs & 0x3fff00) | (data & 0xfe);
logerror("SHIFTER Video Address Counter %06x\n", m_shifter_ofs);
break;
}
}
//-------------------------------------------------
// shifter_palette_w -
//-------------------------------------------------
WRITE16_MEMBER( ste_state::shifter_palette_w )
{
int r = ((data >> 7) & 0x0e) | BIT(data, 11);
int g = ((data >> 3) & 0x0e) | BIT(data, 7);
int b = ((data << 1) & 0x0e) | BIT(data, 3);
m_shifter_palette[offset] = data;
logerror("SHIFTER palette %x = %x\n", offset, data);
m_palette->set_pen_color(offset, r, g, b);
}
//-------------------------------------------------
// shifter_lineofs_r -
//-------------------------------------------------
READ8_MEMBER( ste_state::shifter_lineofs_r )
{
return m_shifter_lineofs;
}
//-------------------------------------------------
// shifter_lineofs_w -
//-------------------------------------------------
WRITE8_MEMBER( ste_state::shifter_lineofs_w )
{
m_shifter_lineofs = data;
logerror("SHIFTER Line Offset %x\n", m_shifter_lineofs);
}
//-------------------------------------------------
// shifter_pixelofs_r -
//-------------------------------------------------
READ8_MEMBER( ste_state::shifter_pixelofs_r )
{
return m_shifter_pixelofs;
}
//-------------------------------------------------
// shifter_pixelofs_w -
//-------------------------------------------------
WRITE8_MEMBER( ste_state::shifter_pixelofs_w )
{
m_shifter_pixelofs = data & 0x0f;
logerror("SHIFTER Pixel Offset %x\n", m_shifter_pixelofs);
}
//**************************************************************************
// BLITTER
//**************************************************************************
//-------------------------------------------------
// blitter_source -
//-------------------------------------------------
void st_state::blitter_source()
{
address_space &program = m_maincpu->space(AS_PROGRAM);
uint16_t data = program.read_word(m_blitter_src);
if (m_blitter_src_inc_x < 0)
{
m_blitter_srcbuf = (data << 16) | (m_blitter_srcbuf >> 16);
}
else
{
m_blitter_srcbuf = (m_blitter_srcbuf << 16) | data;
}
}
//-------------------------------------------------
// blitter_hop -
//-------------------------------------------------
uint16_t st_state::blitter_hop()
{
uint16_t source = m_blitter_srcbuf >> (m_blitter_skew & 0x0f);
uint16_t halftone = m_blitter_halftone[m_blitter_ctrl & 0x0f];
if (m_blitter_ctrl & ATARIST_BLITTER_CTRL_SMUDGE)
{
halftone = m_blitter_halftone[source & 0x0f];
}
switch (m_blitter_hop)
{
case 0:
return 0xffff;
case 1:
return halftone;
case 2:
return source;
case 3:
return source & halftone;
}
return 0;
}
//-------------------------------------------------
// blitter_op -
//-------------------------------------------------
void st_state::blitter_op(uint16_t s, uint32_t dstaddr, uint16_t mask)
{
address_space &program = m_maincpu->space(AS_PROGRAM);
uint16_t d = program.read_word(dstaddr);
uint16_t result = 0;
if (m_blitter_op & 0x08) result = (~s & ~d);
if (m_blitter_op & 0x04) result |= (~s & d);
if (m_blitter_op & 0x02) result |= (s & ~d);
if (m_blitter_op & 0x01) result |= (s & d);
program.write_word(dstaddr, result);
}
//-------------------------------------------------
// blitter_tick -
//-------------------------------------------------
void st_state::blitter_tick()
{
do
{
if (m_blitter_skew & ATARIST_BLITTER_SKEW_FXSR)
{
blitter_source();
m_blitter_src += m_blitter_src_inc_x;
}
blitter_source();
blitter_op(blitter_hop(), m_blitter_dst, m_blitter_endmask1);
m_blitter_xcount--;
while (m_blitter_xcount > 0)
{
m_blitter_src += m_blitter_src_inc_x;
m_blitter_dst += m_blitter_dst_inc_x;
if (m_blitter_xcount == 1)
{
if (!(m_blitter_skew & ATARIST_BLITTER_SKEW_NFSR))
{
blitter_source();
}
blitter_op(blitter_hop(), m_blitter_dst, m_blitter_endmask3);
}
else
{
blitter_source();
blitter_op(blitter_hop(), m_blitter_dst, m_blitter_endmask2);
}
m_blitter_xcount--;
}
m_blitter_src += m_blitter_src_inc_y;
m_blitter_dst += m_blitter_dst_inc_y;
if (m_blitter_dst_inc_y < 0)
{
m_blitter_ctrl = (m_blitter_ctrl & 0xf0) | (((m_blitter_ctrl & 0x0f) - 1) & 0x0f);
}
else
{
m_blitter_ctrl = (m_blitter_ctrl & 0xf0) | (((m_blitter_ctrl & 0x0f) + 1) & 0x0f);
}
m_blitter_xcount = m_blitter_xcountl;
m_blitter_ycount--;
}
while (m_blitter_ycount > 0);
m_blitter_ctrl &= 0x7f;
m_mfp->i3_w(0);
}
//-------------------------------------------------
// blitter_halftone_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_halftone_r )
{
return m_blitter_halftone[offset];
}
//-------------------------------------------------
// blitter_src_inc_x_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_src_inc_x_r )
{
return m_blitter_src_inc_x;
}
//-------------------------------------------------
// blitter_src_inc_y_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_src_inc_y_r )
{
return m_blitter_src_inc_y;
}
//-------------------------------------------------
// blitter_src_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_src_r )
{
switch (offset)
{
case 0:
return (m_blitter_src >> 16) & 0xff;
case 1:
return m_blitter_src & 0xfffe;
}
return 0;
}
//-------------------------------------------------
// blitter_end_mask_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_end_mask_r )
{
switch (offset)
{
case 0:
return m_blitter_endmask1;
case 1:
return m_blitter_endmask2;
case 2:
return m_blitter_endmask3;
}
return 0;
}
//-------------------------------------------------
// blitter_dst_inc_x_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_dst_inc_x_r )
{
return m_blitter_dst_inc_x;
}
//-------------------------------------------------
// blitter_dst_inc_y_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_dst_inc_y_r )
{
return m_blitter_dst_inc_y;
}
//-------------------------------------------------
// blitter_dst_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_dst_r )
{
switch (offset)
{
case 0:
return (m_blitter_dst >> 16) & 0xff;
case 1:
return m_blitter_dst & 0xfffe;
}
return 0;
}
//-------------------------------------------------
// blitter_count_x_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_count_x_r )
{
return m_blitter_xcount;
}
//-------------------------------------------------
// blitter_count_y_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_count_y_r )
{
return m_blitter_ycount;
}
//-------------------------------------------------
// blitter_op_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_op_r )
{
if (ACCESSING_BITS_0_7)
{
return m_blitter_hop;
}
else
{
return m_blitter_op;
}
}
//-------------------------------------------------
// blitter_ctrl_r -
//-------------------------------------------------
READ16_MEMBER( st_state::blitter_ctrl_r )
{
if (ACCESSING_BITS_0_7)
{
return m_blitter_ctrl;
}
else
{
return m_blitter_skew;
}
}
//-------------------------------------------------
// blitter_halftone_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_halftone_w )
{
m_blitter_halftone[offset] = data;
}
//-------------------------------------------------
// blitter_src_inc_x_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_src_inc_x_w )
{
m_blitter_src_inc_x = data & 0xfffe;
}
//-------------------------------------------------
// blitter_src_inc_y_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_src_inc_y_w )
{
m_blitter_src_inc_y = data & 0xfffe;
}
//-------------------------------------------------
// blitter_src_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_src_w )
{
switch (offset)
{
case 0:
m_blitter_src = (data & 0xff) | (m_blitter_src & 0xfffe);
break;
case 1:
m_blitter_src = (m_blitter_src & 0xff0000) | (data & 0xfffe);
break;
}
}
//-------------------------------------------------
// blitter_end_mask_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_end_mask_w )
{
switch (offset)
{
case 0:
m_blitter_endmask1 = data;
break;
case 1:
m_blitter_endmask2 = data;
break;
case 2:
m_blitter_endmask3 = data;
break;
}
}
//-------------------------------------------------
// blitter_dst_inc_x_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_dst_inc_x_w )
{
m_blitter_dst_inc_x = data & 0xfffe;
}
//-------------------------------------------------
// blitter_dst_inc_y_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_dst_inc_y_w )
{
m_blitter_dst_inc_y = data & 0xfffe;
}
//-------------------------------------------------
// blitter_dst_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_dst_w )
{
switch (offset)
{
case 0:
m_blitter_dst = (data & 0xff) | (m_blitter_dst & 0xfffe);
break;
case 1:
m_blitter_dst = (m_blitter_dst & 0xff0000) | (data & 0xfffe);
break;
}
}
//-------------------------------------------------
// blitter_count_x_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_count_x_w )
{
m_blitter_xcount = data;
}
//-------------------------------------------------
// blitter_count_y_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_count_y_w )
{
m_blitter_ycount = data;
}
//-------------------------------------------------
// blitter_op_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_op_w )
{
if (ACCESSING_BITS_0_7)
{
m_blitter_hop = (data >> 8) & 0x03;
}
else
{
m_blitter_op = data & 0x0f;
}
}
//-------------------------------------------------
// blitter_ctrl_w -
//-------------------------------------------------
WRITE16_MEMBER( st_state::blitter_ctrl_w )
{
if (ACCESSING_BITS_0_7)
{
m_blitter_ctrl = (data >> 8) & 0xef;
if (!(m_blitter_ctrl & ATARIST_BLITTER_CTRL_BUSY))
{
if ((data >> 8) & ATARIST_BLITTER_CTRL_BUSY)
{
m_mfp->i3_w(1);
int nops = BLITTER_NOPS[m_blitter_op][m_blitter_hop]; // each NOP takes 4 cycles
timer_set(attotime::from_hz((Y2/4)/(4*nops)), TIMER_BLITTER_TICK);
}
}
}
else
{
m_blitter_skew = data & 0xcf;
}
}
//**************************************************************************
// VIDEO
//**************************************************************************
void st_state::video_start()
{
m_shifter_timer = timer_alloc(TIMER_SHIFTER_TICK);
m_glue_timer = timer_alloc(TIMER_GLUE_TICK);
// m_shifter_timer->adjust(m_screen->time_until_pos(0), 0, attotime::from_hz(Y2/4)); // 125 ns
m_glue_timer->adjust(m_screen->time_until_pos(0), 0, attotime::from_hz(Y2/16)); // 500 ns
m_screen->register_screen_bitmap(m_bitmap);
/* register for state saving */
save_item(NAME(m_shifter_base));
save_item(NAME(m_shifter_ofs));
save_item(NAME(m_shifter_sync));
save_item(NAME(m_shifter_mode));
save_item(NAME(m_shifter_palette));
save_item(NAME(m_shifter_rr));
save_item(NAME(m_shifter_ir));
save_item(NAME(m_shifter_bitplane));
save_item(NAME(m_shifter_shift));
save_item(NAME(m_shifter_h));
save_item(NAME(m_shifter_v));
save_item(NAME(m_shifter_de));
save_item(NAME(m_blitter_halftone));
save_item(NAME(m_blitter_src_inc_x));
save_item(NAME(m_blitter_src_inc_y));
save_item(NAME(m_blitter_dst_inc_x));
save_item(NAME(m_blitter_dst_inc_y));
save_item(NAME(m_blitter_src));
save_item(NAME(m_blitter_dst));
save_item(NAME(m_blitter_endmask1));
save_item(NAME(m_blitter_endmask2));
save_item(NAME(m_blitter_endmask3));
save_item(NAME(m_blitter_xcount));
save_item(NAME(m_blitter_ycount));
save_item(NAME(m_blitter_xcountl));
save_item(NAME(m_blitter_hop));
save_item(NAME(m_blitter_op));
save_item(NAME(m_blitter_ctrl));
save_item(NAME(m_blitter_skew));
set_screen_parameters();
}
void ste_state::video_start()
{
st_state::video_start();
// register for state saving
save_item(NAME(m_shifter_lineofs));
save_item(NAME(m_shifter_pixelofs));
}
void stbook_state::video_start()
{
}
uint32_t st_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
return 0;
}