summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/thomson.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/thomson.cpp')
-rw-r--r--src/mame/video/thomson.cpp1432
1 files changed, 0 insertions, 1432 deletions
diff --git a/src/mame/video/thomson.cpp b/src/mame/video/thomson.cpp
deleted file mode 100644
index 120f1cf1167..00000000000
--- a/src/mame/video/thomson.cpp
+++ /dev/null
@@ -1,1432 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Antoine Mine
-/**********************************************************************
-
- Copyright (C) Antoine Mine' 2006
-
- Thomson 8-bit computers
-
-**********************************************************************/
-
-#include "emu.h"
-#include "includes/thomson.h"
-
-#include <algorithm>
-#include <cmath>
-
-//#define VERBOSE 1
-#include "logmacro.h"
-
-
-/* One GPL is what is drawn in 1 us by the video system in the active window.
- Most of the time, it corresponds to a 8-pixel wide horizontal span.
- For some TO8/9/9+/MO6 modes, it can be 4-pixel or 16-pixel wide.
- There are always 40 GPLs in an active row, and it is always defined by
- two bytes in video memory (0x2000 bytes appart).
-*/
-
-#define THOM_GPL_PER_LINE 40
-
-
-/****************** dynamic screen size *****************/
-
-
-bool thomson_state::update_screen_size()
-{
- const rectangle &visarea = m_screen->visible_area();
- uint8_t p = m_io_vconfig->read();
- bool changed = false;
-
- switch ( p & 3 )
- {
- case 0: m_thom_bwidth = 56; m_thom_bheight = 47; break; /* as in original (?) */
- case 1: m_thom_bwidth = 16; m_thom_bheight = 16; break; /* small */
- default: m_thom_bwidth = 0; m_thom_bheight = 0; break; /* none */
- }
-
- switch ( p & 0xc )
- {
- case 0: m_thom_hires = 0; break; /* low */
- case 4: m_thom_hires = 1; break; /* high */
- default: m_thom_hires = m_thom_hires_better; break; /* auto */
- }
-
- int new_w = ( 320 + m_thom_bwidth * 2 ) * ( m_thom_hires + 1 ) - 1;
- int new_h = ( 200 + m_thom_bheight * 2 ) /** (m_thom_hires + 1 )*/ - 1;
- if ( ( visarea.max_x != new_w ) || ( visarea.max_y != new_h ) )
- {
- changed = true;
- m_screen->set_visible_area(0, new_w, 0, new_h );
- }
-
- return changed;
-}
-
-
-
-/*********************** video timing ******************************/
-
-
-/* elapsed time from beginning of frame, in us */
-unsigned thomson_state::thom_video_elapsed()
-{
- unsigned u;
- attotime elapsed = m_thom_video_timer->elapsed();
- u = (elapsed * 1000000 ).seconds();
- if ( u >= 19968 )
- u = 19968;
- return u;
-}
-
-
-
-struct thom_vsignal thomson_state::thom_get_vsignal()
-{
- struct thom_vsignal v;
- int gpl = thom_video_elapsed() - 64 * THOM_BORDER_HEIGHT - 7;
- if ( gpl < 0 )
- gpl += 19968;
-
- v.inil = ( gpl & 63 ) <= 40;
-
- v.init = gpl < (64 * THOM_ACTIVE_HEIGHT - 24);
-
- v.lt3 = ( gpl & 8 ) ? 1 : 0;
-
- v.line = gpl >> 6;
-
- v.count = v.line * 320 + ( gpl & 63 ) * 8;
-
- return v;
-}
-
-
-
-/************************** lightpen *******************************/
-
-
-
-void thomson_state::thom_get_lightpen_pos( int*x, int* y )
-{
- *x = m_io_lightpen_x->read();
- *y = m_io_lightpen_y->read();
-
- if ( *x < 0 )
- *x = 0;
-
- if ( *y < 0 )
- *y = 0;
-
- if ( *x > 2 * m_thom_bwidth + 319 )
- *x = 2 * m_thom_bwidth + 319;
-
- if ( *y > 2 * m_thom_bheight + 199 )
- *y = 2 * m_thom_bheight + 199;
-}
-
-
-
-struct thom_vsignal thomson_state::thom_get_lightpen_vsignal( int xdec, int ydec, int xdec2 )
-{
- struct thom_vsignal v;
- int x, y;
- int gpl;
-
- thom_get_lightpen_pos( &x, &y );
- x += xdec - m_thom_bwidth;
- y += ydec - m_thom_bheight;
-
- gpl = (x >> 3) + y * 64;
- if ( gpl < 0 )
- gpl += 19968;
-
- v.inil = (gpl & 63) <= 41;
-
- v.init = (gpl <= 64 * THOM_ACTIVE_HEIGHT - 24);
-
- v.lt3 = ( gpl & 8 ) ? 1 : 0;
-
- v.line = y;
-
- if ( v.inil && v.init )
- v.count =
- ( gpl >> 6 ) * 320 + /* line */
- ( gpl & 63 ) * 8 + /* gpl inside line */
- ( (x + xdec2) & 7 ); /* pixel inside gpl */
- else
- v.count = 0;
-
- return v;
-}
-
-
-
-void thomson_state::thom_set_lightpen_callback( int nb )
-{
- LOG("%f thom_set_lightpen_callback called\n", machine().time().as_double());
- m_thom_lightpen_nb = nb;
-}
-
-TIMER_CALLBACK_MEMBER( thomson_state::thom_lightpen_step )
-{
- int step = param;
-
- if ( m_thom_lightpen_cb )
- (this->*m_thom_lightpen_cb)( step );
-
- if ( step < m_thom_lightpen_nb )
- m_thom_lightpen_timer->adjust(attotime::from_usec( 64 ), step + 1);
-}
-
-
-
-/***************** scan-line oriented engine ***********************/
-
-/* This code, common for all Thomson machines, emulates the TO8
- video hardware, with its 16-colors chosen among 4096, 9 video modes,
- and 4 video pages. Moreover, it emulates changing the palette several times
- per frame to simulate more than 16 colors per frame (and the same for mode
- and page switchs) and cooper effects (distinguishing the left and right
- border color of each row).
-
- TO7, TO7/70 and MO5 video hardware are much simpler (8 or 16 fixed colors,
- one mode and one video page). Although the three are different, they can all
- be emulated by the TO8 video hardware.
- Thus, we use the same TO8-emulation code to deal with these simpler
- hardware (although it is somewhat of an overkill).
-*/
-
-
-
-/* ---------------- state & state changes ---------------- */
-
-
-/* returns 1 if the mode is 640 pixel wide, 0 if it is 160 or 320 */
-int thomson_state::thom_mode_is_hires( int mode )
-{
- return ( mode == THOM_VMODE_80 ) || ( mode == THOM_VMODE_80_TO9 );
-}
-
-
-
-/* either the border index or its palette entry has changed */
-void thomson_state::thom_border_changed()
-{
- unsigned l = thom_video_elapsed();
- unsigned y = l >> 6;
- unsigned x = l & 63;
- unsigned color = m_thom_pal[ m_thom_border_index ];
-
- if ( y >= THOM_TOTAL_HEIGHT )
- {
- /* end of page */
- m_thom_border_r[ THOM_TOTAL_HEIGHT ] = color;
- }
- else if ( ! x )
- {
- /* start of line */
- m_thom_border_l[ y ] = color;
- m_thom_border_r[ y ] = color;
- }
- else if ( x <= 19 )
- {
- /* between left and right border */
- /* NOTE: this makes the lower right part of the color picker blink
- in the TO8/TO9/TO9+, which actually happens on the real computer!
- */
- m_thom_border_r[ y ] = color;
- m_thom_border_l[ y + 1 ] = color;
- }
- else
- {
- /* end of line */
- m_thom_border_l[ y + 1 ] = color;
- m_thom_border_r[ y + 1 ] = color;
- }
- m_thom_vstate_dirty = true;
-}
-
-
-
-/* the video mode or page has changed */
-void thomson_state::thom_gplinfo_changed()
-{
- unsigned l = thom_video_elapsed() - THOM_BORDER_HEIGHT * 64 - 7;
- unsigned y = l >> 6;
- unsigned x = l & 63;
- int modepage = ((int)m_thom_vmode << 8) | m_thom_vpage;
- if ( y >= 200 || x>= 40 )
- m_thom_vmodepage[ 40 ] = modepage;
- else
- m_thom_vmodepage[ x ] = modepage;
- m_thom_vmodepage_changed = 1;
-}
-
-
-
-void thomson_state::thom_set_border_color( unsigned index )
-{
- assert( index < 16 );
- if ( index != m_thom_border_index )
- {
- LOG("thom_set_border_color: %i at line %i col %i\n", index, thom_video_elapsed() / 64, thom_video_elapsed() % 64);
- m_thom_border_index = index;
- thom_border_changed();
- }
-}
-
-
-
-void thomson_state::thom_set_palette( unsigned index, uint16_t color )
-{
- assert( index < 16 );
-
- if ( color != 0x1000 )
- color &= 0xfff;
-
- if ( m_thom_pal[ index ] == color )
- return;
-
- LOG("thom_set_palette: %i to %03x at line %i col %i\n", index, color, thom_video_elapsed() / 64, thom_video_elapsed() % 64);
-
- m_thom_pal[ index ] = color;
- if ( index == m_thom_border_index )
- thom_border_changed();
- m_thom_pal_changed = true;
- m_thom_vstate_dirty = true;
-}
-
-
-
-void thomson_state::thom_set_video_mode( unsigned mode )
-{
- assert( mode < THOM_VMODE_NB );
-
- if ( mode != m_thom_vmode )
- {
- LOG("thom_set_video_mode: %i at line %i, col %i\n", mode, thom_video_elapsed() / 64, thom_video_elapsed() % 64);
- m_thom_vmode = mode;
- thom_gplinfo_changed();
- m_thom_vstate_dirty = true;
- m_thom_hires_better |= thom_mode_is_hires( mode );
- }
-}
-
-
-
-void thomson_state::thom_set_video_page( unsigned page )
-{
- assert( page < THOM_NB_PAGES );
-
- if ( page != m_thom_vpage )
- {
- LOG("thom_set_video_page: %i at line %i col %i\n", page, thom_video_elapsed() / 64, thom_video_elapsed() % 64);
- m_thom_vpage = page;
- thom_gplinfo_changed();
- m_thom_vstate_dirty = true;
- }
-}
-
-
-
-/* -------------- drawing --------------- */
-
-
-
-typedef void ( thomson_state::*thom_scandraw ) ( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
-
-
-
-#define UPDATE( name, res ) \
- void thomson_state::name##_scandraw_##res ( \
- uint8_t* vram, uint16_t* dst, uint16_t* pal, \
- int org, int len ) \
- { \
- unsigned gpl; \
- vram += org; \
- dst += org * res; \
- for ( gpl = 0; gpl < len; gpl++, dst += res, vram++ ) { \
- uint8_t rama = vram[ 0 ]; \
- uint8_t ramb = vram[ 0x2000 ];
-
-#define END_UPDATE \
- } \
- }
-
-#define UPDATE_HI( name ) UPDATE( name, 16 )
-#define UPDATE_LOW( name ) UPDATE( name, 8 )
-
-
-
-/* 320x200, 16-colors, constraints: 2 distinct colors per GPL (8 pixels) */
-/* this also works for TO7, assuming the 2 top bits of each color byte are 1 */
-
-UPDATE_HI( to770 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ ((ramb & 7) | ((ramb>>4) & 8)) ^ 8 ];
- c[1] = pal[ ((ramb >> 3) & 15) ^ 8 ];
- for ( i = 0; i < 16; i += 2, rama >>= 1 )
- dst[ 15 - i ] = dst[ 14 - i ] = c[ rama & 1 ];
-}
-END_UPDATE
-
-UPDATE_LOW( to770 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ ((ramb & 7) | ((ramb>>4) & 8)) ^ 8 ];
- c[1] = pal[ ((ramb >> 3) & 15) ^ 8 ];
- for ( i = 0; i < 8; i++, rama >>= 1 )
- dst[ 7 - i ] = c[ rama & 1 ];
-}
-END_UPDATE
-
-
-
-/* as above, different (more logical but TO7-incompatible) color encoding */
-
-UPDATE_HI( mo5 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ ramb & 15 ];
- c[1] = pal[ ramb >> 4 ];
- for ( i = 0; i < 16; i += 2, rama >>= 1 )
- dst[ 15 - i ] = dst[ 14 - i ] = c[ rama & 1 ];
-}
-END_UPDATE
-
-UPDATE_LOW( mo5 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ ramb & 15 ];
- c[1] = pal[ ramb >> 4 ];
- for ( i = 0; i < 8; i++, rama >>= 1 )
- dst[ 7 - i ] = c[ rama & 1 ];
-}
-END_UPDATE
-
-
-/* as mo5, but with pastel bit switched */
-
-UPDATE_HI( mo5alt )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ (ramb & 15) ^ 8 ];
- c[1] = pal[ (ramb >> 4) ^ 8 ];
- for ( i = 0; i < 16; i += 2, rama >>= 1 )
- dst[ 15 - i ] = dst[ 14 - i ] = c[ rama & 1 ];
-}
-END_UPDATE
-
-UPDATE_LOW( mo5alt )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ (ramb & 15) ^ 8 ];
- c[1] = pal[ (ramb >> 4) ^ 8 ];
- for ( i = 0; i < 8; i++, rama >>= 1 )
- dst[ 7 - i ] = c[ rama & 1 ];
-}
-END_UPDATE
-
-
-
-/* as to770, but with pastel color bit unswitched */
-
-UPDATE_HI( to9 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ (ramb & 7) | ((ramb>>4) & 8) ];
- c[1] = pal[ (ramb >> 3) & 15 ];
- for ( i = 0; i < 16; i += 2, rama >>= 1 )
- dst[ 15 - i ] = dst[ 14 - i ] = c[ rama & 1 ];
-}
-END_UPDATE
-
-UPDATE_LOW( to9 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ (ramb & 7) | ((ramb>>4) & 8) ];
- c[1] = pal[ (ramb >> 3) & 15 ];
- for ( i = 0; i < 8; i++, rama >>= 1 )
- dst[ 7 - i ] = c[ rama & 1 ];
-}
-END_UPDATE
-
-
-
-/* 320x200, 4-colors, no constraint */
-
-UPDATE_HI( bitmap4 )
-{
- int i;
- pen_t c[2][2];
- c[0][0] = pal[ 0 ];
- c[0][1] = pal[ 1 ];
- c[1][0] = pal[ 2 ];
- c[1][1] = pal[ 3 ];
- for ( i = 0; i < 16; i += 2, rama >>= 1, ramb >>= 1 )
- dst[ 15 - i ] = dst[ 14 - i ] = c[ rama & 1 ] [ ramb & 1 ];
-}
-END_UPDATE
-
-UPDATE_LOW( bitmap4 )
-{
- int i;
- pen_t c[2][2];
- c[0][0] = pal[ 0 ];
- c[0][1] = pal[ 1 ];
- c[1][0] = pal[ 2 ];
- c[1][1] = pal[ 3 ];
- for ( i = 0; i < 8; i++, rama >>= 1, ramb >>= 1 )
- dst[ 7 - i ] = c[ rama & 1 ] [ ramb & 1 ];
-}
-END_UPDATE
-
-
-
-/* as above, but using 2-bit pixels instead of 2 planes of 1-bit pixels */
-
-UPDATE_HI( bitmap4alt )
-{
- int i;
- pen_t c[4];
- c[0] = pal[ 0 ];
- c[1] = pal[ 1 ];
- c[2] = pal[ 2 ];
- c[3] = pal[ 3 ];
- for ( i = 0; i < 8; i += 2, ramb >>= 2 )
- dst[ 15 - i ] = dst[ 14 - i ] = c[ ramb & 3 ];
- for ( i = 0; i < 8; i += 2, rama >>= 2 )
- dst[ 7 - i ] = dst[ 6 - i ] = c[ rama & 3 ];
-}
-END_UPDATE
-
-UPDATE_LOW( bitmap4alt )
-{
- int i;
- pen_t c[4];
- c[0] = pal[ 0 ];
- c[1] = pal[ 1 ];
- c[2] = pal[ 2 ];
- c[3] = pal[ 3 ];
- for ( i = 0; i < 4; i++, ramb >>= 2 )
- dst[ 7 - i ] = c[ ramb & 3 ];
- for ( i = 0; i < 4; i++, rama >>= 2 )
- dst[ 3 - i ] = c[ rama & 3 ];
-}
-END_UPDATE
-
-
-/* 160x200, 4 colors, no constraint, using only one memory page (undocumented) */
-
-UPDATE_HI( bitmap4althalf )
-{
- dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = pal[ rama >> 6 ];
- dst[ 4] = dst[ 5] = dst[ 6] = dst[ 7] = pal[ (rama >> 4) & 3 ];
- dst[ 8] = dst[ 9] = dst[10] = dst[11] = pal[ (rama >> 2) & 3];
- dst[12] = dst[13] = dst[14] = dst[15] = pal[ rama & 3 ];
- (void)ramb; // ramb is not used
-}
-END_UPDATE
-
-UPDATE_LOW( bitmap4althalf )
-{
- dst[0] = dst[1] = pal[ rama >> 6 ];
- dst[2] = dst[3] = pal[ (rama >> 4) & 3 ];
- dst[4] = dst[5] = pal[ (rama >> 2) & 3];
- dst[6] = dst[7] = pal[ rama & 3 ];
- (void)ramb; // ramb is not used
-}
-END_UPDATE
-
-
-
-/* 160x200, 16-colors, no constraint */
-
-UPDATE_HI( bitmap16 )
-{
- dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = pal[ rama >> 4 ];
- dst[ 4] = dst[ 5] = dst[ 6] = dst[ 7] = pal[ rama & 15 ];
- dst[ 8] = dst[ 9] = dst[10] = dst[11] = pal[ ramb >> 4 ];
- dst[12] = dst[13] = dst[14] = dst[15] = pal[ ramb & 15 ];
-}
-END_UPDATE
-
-UPDATE_LOW( bitmap16 )
-{
- dst[0] = dst[1] = pal[ rama >> 4 ];
- dst[2] = dst[3] = pal[ rama & 15 ];
- dst[4] = dst[5] = pal[ ramb >> 4 ];
- dst[6] = dst[7] = pal[ ramb & 15 ];
-}
-END_UPDATE
-
-
-/* 160x200, 16-colors, no constraint, alternate encoding, undocumented, tested */
-
-static constexpr unsigned tbl_bit16[4][4] = {
- { 0, 2, 8, 10 },
- { 1, 3, 9, 11 },
- { 4, 6, 12, 14 },
- { 5, 7, 13, 15 } };
-
-UPDATE_HI( bitmap16alt )
-{
- unsigned p0 = tbl_bit16[ramb >> 6][rama >> 6];
- unsigned p1 = tbl_bit16[(ramb >> 4) & 3][(rama >> 4) & 3];
- unsigned p2 = tbl_bit16[(ramb >> 2) & 3][(rama >> 2) & 3];
- unsigned p3 = tbl_bit16[ramb & 3][rama & 3];
- dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = pal[ p0 ];
- dst[ 4] = dst[ 5] = dst[ 6] = dst[ 7] = pal[ p1 ];
- dst[ 8] = dst[ 9] = dst[10] = dst[11] = pal[ p2 ];
- dst[12] = dst[13] = dst[14] = dst[15] = pal[ p3 ];
-}
-END_UPDATE
-
-UPDATE_LOW( bitmap16alt )
-{
- unsigned p0 = tbl_bit16[ramb >> 6][rama >> 6];
- unsigned p1 = tbl_bit16[(ramb >> 4) & 3][(rama >> 4) & 3];
- unsigned p2 = tbl_bit16[(ramb >> 2) & 3][(rama >> 2) & 3];
- unsigned p3 = tbl_bit16[ramb & 3][rama & 3];
- dst[0] = dst[1] = pal[ p0 ];
- dst[2] = dst[3] = pal[ p1 ];
- dst[4] = dst[5] = pal[ p2 ];
- dst[6] = dst[7] = pal[ p3 ];
-}
-END_UPDATE
-
-
-
-/* 640x200 (80 text column), 2-colors, no constraint */
-
-UPDATE_HI( mode80 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ 0 ];
- c[1] = pal[ 1 ];
- for ( i = 0; i < 8; i++, ramb >>= 1 )
- dst[ 15 - i ] = c[ ramb & 1 ];
- for ( i = 0; i < 8; i++, rama >>= 1 )
- dst[ 7 - i ] = c[ rama & 1 ];
-}
-END_UPDATE
-
-UPDATE_LOW( mode80 )
-{
- /* 640-pixel mode but 320 pixels emulated => we merge pixels */
- int i;
- pen_t c[4];
- c[0] = pal[ 0 ];
- c[1] = c[2] = c[3] = pal[ 1 ];
- for ( i = 0; i < 4; i++, ramb >>= 2 )
- dst[ 7 - i ] = c[ ramb & 3 ];
- for ( i = 0; i < 4; i++, rama >>= 2 )
- dst[ 3 - i ] = c[ rama & 3 ];
-}
-END_UPDATE
-
-
-
-/* as above, but TO9 flavor */
-
-UPDATE_HI( mode80_to9 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ 0 ];
- c[1] = pal[ 6 ];
- for ( i = 0; i < 8; i++, ramb >>= 1 )
- dst[ 15 - i ] = c[ ramb & 1 ];
- for ( i = 0; i < 8; i++, rama >>= 1 )
- dst[ 7 - i ] = c[ rama & 1 ];
-}
-END_UPDATE
-
-UPDATE_LOW( mode80_to9 )
-{
- int i;
- pen_t c[4];
- c[0] = pal[ 0 ];
- c[1] = c[2] = c[3] = pal[ 6 ];
- for ( i = 0; i < 4; i++, ramb >>= 2 )
- dst[ 7 - i ] = c[ ramb & 3 ];
- for ( i = 0; i < 4; i++, rama >>= 2 )
- dst[ 3 - i ] = c[ rama & 3 ];
-}
-END_UPDATE
-
-
-
-/* 320x200, 2-colors, two pages (untested) */
-
-UPDATE_HI( page1 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ 0 ];
- c[1] = pal[ 1 ];
- for ( i = 0; i < 16; i += 2, rama >>= 1 )
- dst[ 15 - i ] = dst[ 14 - i ] = c[ rama & 1 ];
- (void)ramb;
-}
-END_UPDATE
-
-UPDATE_LOW( page1 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ 0 ];
- c[1] = pal[ 1 ];
- for ( i = 0; i < 8; i++, rama >>= 1 )
- dst[ 7 - i ] = c[ rama & 1 ];
- (void)ramb;
-}
-END_UPDATE
-
-UPDATE_HI( page2 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ 0 ];
- c[1] = pal[ 2 ];
- for ( i = 0; i < 16; i += 2, ramb >>= 1 )
- dst[ 15 - i ] = dst[ 14 - i ] = c[ ramb & 1 ];
- (void)rama;
-}
-END_UPDATE
-
-UPDATE_LOW( page2 )
-{
- int i;
- pen_t c[2];
- c[0] = pal[ 0 ];
- c[1] = pal[ 2 ];
- for ( i = 0; i < 8; i++, ramb >>= 1 )
- dst[ 7 - i ] = c[ ramb & 1 ];
- (void)rama;
-}
-END_UPDATE
-
-
-
-/* 320x200, 2-colors, two overlaid pages */
-
-UPDATE_HI( overlay )
-{
- int i;
- pen_t c[2][2];
- c[0][0] = pal[ 0 ];
- c[0][1] = c[1][1] = pal[ 1 ];
- c[1][0] = pal[ 2 ];
- for ( i = 0; i < 16; i += 2, rama >>= 1, ramb >>= 1 )
- dst[ 15 - i ] = dst[ 14 - i ] = c[ ramb & 1 ] [ rama & 1 ];
-}
-END_UPDATE
-
-UPDATE_LOW( overlay )
-{
- int i;
- pen_t c[2][2];
- c[0][0] = pal[ 0 ];
- c[0][1] = c[1][1] = pal[ 1 ];
- c[1][0] = pal[ 2 ];
- for ( i = 0; i < 8; i++, rama >>= 1, ramb >>= 1 )
- dst[ 7 - i ] = c[ ramb & 1 ] [ rama & 1 ];
-}
-END_UPDATE
-
-
-/* 160x200 undocumented variant of the above (2-colors, two overlaid pages) */
-
-UPDATE_HI( overlayhalf )
-{
- int i;
- pen_t c[2][2];
- c[0][0] = pal[ 0 ];
- c[0][1] = c[1][1] = pal[ 1 ];
- c[1][0] = pal[ 2 ];
- rama >>= 4;
- ramb >>= 4;
- for ( i = 0; i < 16; i += 4, rama >>= 1, ramb >>= 1 )
- dst[ 15 - i ] = dst[ 14 - i ] = dst[ 13 - i ] = dst[ 12 - i ] =
- c[ ramb & 1 ] [ rama & 1 ];
-}
-END_UPDATE
-
-UPDATE_LOW( overlayhalf )
-{
- int i;
- pen_t c[2][2];
- c[0][0] = pal[ 0 ];
- c[0][1] = c[1][1] = pal[ 1 ];
- c[1][0] = pal[ 2 ];
- rama >>= 4;
- ramb >>= 4;
- for ( i = 0; i < 8; i += 2, rama >>= 1, ramb >>= 1 )
- dst[ 7 - i ] = dst[ 6 - i ] = c[ ramb & 1 ] [ rama & 1 ];
-}
-END_UPDATE
-
-
-
-/* 160x200, 4-colors, four overlaid pages */
-
-UPDATE_HI( overlay3 )
-{
- /* Note: "Manuel Technique" doc implies that the palette entries are 0,1,2,4,8;
- we now use palette entries 0,1,2,3,4 instead, as this is what the TEO emulator uses and it has been confirmed correct
- */
- static const int p[2][2][2][2] = {
- { { { 0, 1 }, { 2, 1 } }, { { 3, 1 }, { 2, 1 } } },
- { { { 4, 1 }, { 2, 1 } }, { { 3, 1 }, { 2, 1 } } }
- };
- int i;
- for ( i = 0; i < 16; i += 4, rama >>= 1, ramb >>= 1 )
- dst[ 15 - i ] = dst[ 14 - i ] = dst[ 13 - i ] = dst[ 12 - i ] =
- pal[ p[ ramb & 1 ] [ (ramb >> 4) & 1 ]
- [ rama & 1 ] [ (rama >> 4) & 1 ] ];
-}
-END_UPDATE
-
-UPDATE_LOW( overlay3 )
-{
- static const int p[2][2][2][2] = {
- { { { 0, 1 }, { 2, 1 } }, { { 3, 1 }, { 2, 1 } } },
- { { { 4, 1 }, { 2, 1 } }, { { 3, 1 }, { 2, 1 } } }
- };
- int i;
- for ( i = 0; i < 8; i += 2, rama >>= 1, ramb >>= 1 )
- dst[ 7 - i ] = dst[ 6 - i ] =
- pal[ p[ ramb & 1 ] [ (ramb >> 4) & 1 ]
- [ rama & 1 ] [ (rama >> 4) & 1 ] ];
-}
-END_UPDATE
-
-
-
-#define FUN(x) { &thomson_state::x##_scandraw_8, &thomson_state::x##_scandraw_16 }
-
-
-static const thom_scandraw thom_scandraw_funcs[THOM_VMODE_NB][2] =
-{
- FUN(to770), FUN(mo5), FUN(bitmap4), FUN(bitmap4alt), FUN(mode80),
- FUN(bitmap16), FUN(page1), FUN(page2), FUN(overlay), FUN(overlay3),
- FUN(to9), FUN(mode80_to9),
- FUN(bitmap4althalf), FUN(mo5alt), FUN(overlayhalf),
- FUN(bitmap16alt)
-};
-
-
-
-/* called at the start of each scanline in the active area, just after
- left border (-1<=y<199), and also after the last scanline (y=199)
-*/
-TIMER_CALLBACK_MEMBER( thomson_state::thom_scanline_start )
-{
- int y = param;
-
- /* update active-area */
- if ( y >= 0 && (m_thom_vstate_dirty || m_thom_vstate_last_dirty || m_thom_vmem_dirty[y]) )
- {
- int x = 0;
- while ( x < 40 )
- {
- int xx = x;
- unsigned mode = m_thom_vmodepage[x] >> 8;
- unsigned page = m_thom_vmodepage[x] & 0xff;
- assert( mode < THOM_VMODE_NB );
- assert( page < 4 );
- if ( m_thom_vmodepage_changed )
- {
- do
- {
- xx++;
- }
- while ( xx < 40 && m_thom_vmodepage[xx] == -1 );
- }
- else
- {
- xx = 40;
- }
- (this->*thom_scandraw_funcs[ mode ][ m_thom_hires ])
- ( m_thom_vram + y * 40 + page * 0x4000,
- m_thom_vbody + y * 320 * (m_thom_hires+1),
- m_thom_last_pal, x, xx-x );
- x = xx;
- }
- m_thom_vmem_dirty[y] = false;
- }
-
- /* prepare for next scanline */
- if ( y == 199 )
- m_thom_scanline_timer->adjust(attotime::never);
- else
- {
- if ( m_thom_vmodepage_changed )
- {
- int x, m = 0;
- for ( x = 0; x <= 40; x++ )
- {
- if ( m_thom_vmodepage[x] !=-1 )
- {
- m = m_thom_vmodepage[x];
- m_thom_vmodepage[x] = -1;
- }
- }
- m_thom_vmodepage[0] = m;
- m_thom_vmodepage_changed = 0;
- }
-
- if ( m_thom_pal_changed )
- {
- std::copy_n(&m_thom_pal[0], 16, &m_thom_last_pal[0]);
- m_thom_pal_changed = false;
- }
-
- m_thom_scanline_timer->adjust(attotime::from_usec(64), y + 1);
- }
-}
-
-
-
-/* -------------- misc --------------- */
-
-
-#define FLOP_STATE (m_thom_floppy_wcount ? 2 : m_thom_floppy_rcount ? 1 : 0)
-
-
-
-void thomson_state::thom_set_mode_point( int point )
-{
- assert( point >= 0 && point <= 1 );
- m_thom_mode_point = ( ! point ) * 0x2000;
- m_vrambank->set_entry( ! point );
-}
-
-
-
-void thomson_state::thom_floppy_active( int write )
-{
- int fold = FLOP_STATE, fnew;
-
- /* stays up for a few frames */
- if ( write )
- m_thom_floppy_wcount = 25;
- else
- m_thom_floppy_rcount = 25;
-
- /* update icon */
- fnew = FLOP_STATE;
- if ( fold != fnew )
- m_floppy_led = fnew;
-}
-
-
-
-/* -------------- main update function --------------- */
-
-
-
-uint32_t thomson_state::screen_update_thom(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- int y, ypos;
- const int scale = m_thom_hires ? 2 : 1;
- const int xbleft = m_thom_bwidth * scale;
- const int xbright = ( m_thom_bwidth + THOM_ACTIVE_WIDTH ) * scale;
- const int xright = ( m_thom_bwidth * 2 + THOM_ACTIVE_WIDTH ) * scale;
- const int xwidth = THOM_ACTIVE_WIDTH * scale;
- const int yup = THOM_BORDER_HEIGHT + THOM_ACTIVE_HEIGHT;
- const int ybot = THOM_BORDER_HEIGHT + m_thom_bheight + 200;
- uint16_t* v = m_thom_vbody;
- pen_t border = 0;
- rectangle wrect(0, xright - 1, 0, 0);
- rectangle lrect(0, xbleft - 1, 0, 0);
- rectangle rrect(xbright, xright - 1, 0, 0);
-
- //LOG("%f thom: video update called\n", machine().time().as_double());
-
- /* upper border */
- for ( y = 0; y < THOM_BORDER_HEIGHT - m_thom_bheight; y++ )
- {
- if ( m_thom_border_l[ y ] != -1 )
- border = m_thom_border_l[ y ];
- }
- ypos = 0;
- while ( y < THOM_BORDER_HEIGHT )
- {
- if ( m_thom_border_l[ y ] != -1 )
- border = m_thom_border_l[ y ];
- wrect.min_y = ypos;
- do
- {
- y++;
- ypos ++ /* += scale */;
- }
- while ( y < THOM_BORDER_HEIGHT && m_thom_border_l[ y ] == -1 );
- wrect.max_y = ypos - 1;
- bitmap.fill(border, wrect );
- }
-
- /* left border */
- while ( y < yup )
- {
- if ( m_thom_border_l[ y ] != -1 )
- border = m_thom_border_l[ y ];
- lrect.min_y = ypos;
- do
- {
- y++;
- ypos ++ /* += scale */;
- }
- while ( y < yup && m_thom_border_l[ y ] == -1 );
- lrect.max_y = ypos - 1;
- bitmap.fill(border, lrect );
- }
-
- /* lower border */
- while (y < ybot )
- {
- if ( m_thom_border_l[ y ] != -1 )
- border = m_thom_border_l[ y ];
- wrect.min_y = ypos;
- do
- {
- y++;
- ypos ++ /* += scale */;
- } while ( y < ybot && m_thom_border_l[ y ] == -1 );
- wrect.max_y = ypos - 1;
- bitmap.fill(border, wrect );
- }
-
- /* right border */
- for ( y = 0; y < THOM_BORDER_HEIGHT; y++ ) {
- if ( m_thom_border_r[ y ] != -1 )
- border = m_thom_border_r[ y ];
- }
- ypos = m_thom_bheight /* * scale */;
- while ( y < yup )
- {
- if ( m_thom_border_r[ y ] != -1 )
- border = m_thom_border_r[ y ];
- rrect.min_y = ypos;
- do
- {
- y++;
- ypos ++ /* += scale */;
- }
- while ( y < yup && m_thom_border_r[ y ] == -1 );
- rrect.max_y = ypos - 1;
- bitmap.fill(border, rrect );
- }
-
- /* active area */
- ypos = m_thom_bheight /* * scale */;
- for ( y = 0; y < 200; v += xwidth, y++ , ypos ++ /* += scale */ )
- {
- draw_scanline16( bitmap, xbleft, ypos, xwidth, v, nullptr );
-#if 0
- if ( thom_hires )
- draw_scanline16( bitmap, xbleft, ypos+1, xwidth, v, nullptr );
-#endif
- }
-
- return 0;
-}
-
-
-
-/* -------------- frame start ------------------ */
-
-
-TIMER_CALLBACK_MEMBER( thomson_state::thom_set_init )
-{
- int init = param;
- LOG("%f thom_set_init: %i, at line %i col %i\n", machine().time().as_double(), init, thom_video_elapsed() / 64, thom_video_elapsed() % 64);
-
- if ( m_thom_init_cb )
- (this->*m_thom_init_cb)( init );
- if ( ! init )
- m_thom_init_timer->adjust(attotime::from_usec( 64 * THOM_ACTIVE_HEIGHT - 24 ), 1-init);
-}
-
-/* call this at the very beginning of each new frame */
-WRITE_LINE_MEMBER(thomson_state::thom_vblank)
-{
- // rising edge
- if (state)
- {
- int fnew, fold = FLOP_STATE;
- int i;
- uint16_t b = 0;
- struct thom_vsignal l = thom_get_lightpen_vsignal( 0, -1, 0 );
-
- LOG("%f thom: video eof called\n", machine().time().as_double());
-
- /* floppy indicator count */
- if ( m_thom_floppy_wcount )
- m_thom_floppy_wcount--;
- if ( m_thom_floppy_rcount )
- m_thom_floppy_rcount--;
- fnew = FLOP_STATE;
- if ( fnew != fold )
- m_floppy_led = fnew;
-
- /* prepare state for next frame */
- for ( i = 0; i <= THOM_TOTAL_HEIGHT; i++ )
- {
- if ( m_thom_border_l[ i ] != -1 )
- b = m_thom_border_l[ i ];
- if ( m_thom_border_r[ i ] != -1 )
- b = m_thom_border_r[ i ];
- }
- std::fill(std::begin(m_thom_border_l), std::end(m_thom_border_l), -1);
- std::fill(std::begin(m_thom_border_r), std::end(m_thom_border_r), -1);
- m_thom_border_l[ 0 ] = b;
- m_thom_border_r[ 0 ] = b;
- m_thom_vstate_last_dirty = m_thom_vstate_dirty;
- m_thom_vstate_dirty = false;
-
- /* schedule first init signal */
- m_thom_init_timer->adjust(attotime::from_usec( 64 * THOM_BORDER_HEIGHT + 7 ));
-
- /* schedule first lightpen signal */
- l.line &= ~1; /* hack (avoid lock in MO6 palette selection) */
- m_thom_lightpen_timer->adjust(
- attotime::from_usec( 64 * ( THOM_BORDER_HEIGHT + l.line - 2 ) + 16 ), 0);
-
- /* schedule first active-area scanline call-back */
- m_thom_scanline_timer->adjust(attotime::from_usec( 64 * THOM_BORDER_HEIGHT + 7), -1);
-
- /* reset video frame time */
- m_thom_video_timer->adjust(attotime::zero);
-
- /* update screen size according to user options */
- if ( update_screen_size() )
- m_thom_vstate_dirty = true;
-
- /* hi-res automatic */
- m_thom_hires_better = thom_mode_is_hires( m_thom_vmode );
- }
-}
-
-
-
-/* -------------- initialization --------------- */
-
-
-/* TO7, TO7/70 palette, hardcoded in ROM
- without further information, we assume that the hardcoded values
- are the same as those setup by the TO8/TO9+/MO6 when booting up
- */
-static const uint16_t thom_pal_init[16] =
-{
- 0x1000, /* 0: black */ 0x000f, /* 1: red */
- 0x00f0, /* 2: geen */ 0x00ff, /* 3: yellow */
- 0x0f00, /* 4: blue */ 0x0f0f, /* 5: purple */
- 0x0ff0, /* 6: cyan */ 0x0fff, /* 7: white */
- 0x0777, /* 8: gray */ 0x033a, /* 9: pink */
- 0x03a3, /* a: light green */ 0x03aa, /* b: light yellow */
- 0x0a33, /* c: light blue */ 0x0a3a, /* d: redish pink */
- 0x0ee7, /* e: light cyan */ 0x007b, /* f: orange */
-};
-
-/* MO5 palette, hardcoded in a ROM
- values are from "Manuel Technique du MO5", p.19
- */
-static const uint16_t mo5_pal_init[16] =
-{
- 0x1000, /* 0: black */ 0x055f, /* 1: red */
- 0x00f0, /* 2: geen */ 0x00ff, /* 3: yellow */
- 0x0f55, /* 4: blue */ 0x0f0f, /* 5: purple */
- 0x0ff5, /* 6: cyan */ 0x0fff, /* 7: white */
- 0x0aaa, /* 8: gray */ 0x0aaf, /* 9: pink */
- 0x0afa, /* a: light green */ 0x0aff, /* b: light yellow */
- 0x0fa5, /* c: light blue */ 0x0faf, /* d: parama pink */
- 0x0ffa, /* e: light cyan */ 0x05af, /* f: orange */
-};
-
-
-void thomson_state::video_start()
-{
- LOG("thom: video start called\n");
-
- /* scan-line state */
- std::fill(std::begin(m_thom_border_l), std::end(m_thom_border_l), -1);
- std::fill(std::begin(m_thom_border_r), std::end(m_thom_border_r), -1);
- std::fill(std::begin(m_thom_vbody), std::end(m_thom_vbody), 0);
- std::fill(std::begin(m_thom_vmodepage), std::end(m_thom_vmodepage), -1);
- std::fill(std::begin(m_thom_vmem_dirty), std::end(m_thom_vmem_dirty), false);
- m_thom_border_l[ 0 ] = 0;
- m_thom_border_r[ 0 ] = 0;
- m_thom_vmodepage[ 0 ] = 0;
- m_thom_vmodepage_changed = 0;
- m_thom_vmode = 0;
- m_thom_vpage = 0;
- m_thom_border_index = 0;
- m_thom_vstate_dirty = true;
- m_thom_vstate_last_dirty = true;
- save_pointer(NAME(m_thom_last_pal), sizeof(m_thom_last_pal));
- save_pointer(NAME(m_thom_pal), sizeof(m_thom_pal));
- save_pointer(NAME(m_thom_border_l), sizeof(m_thom_border_l));
- save_pointer(NAME(m_thom_border_r), sizeof(m_thom_border_r));
- save_pointer(NAME(m_thom_vbody), sizeof(m_thom_vbody));
- save_pointer(NAME(m_thom_vmodepage), sizeof(m_thom_vmodepage));
- save_pointer(NAME(m_thom_vmem_dirty), sizeof(m_thom_vmem_dirty));
- save_item(NAME(m_thom_pal_changed));
- save_item(NAME(m_thom_vmodepage_changed));
- save_item(NAME(m_thom_vmode));
- save_item(NAME(m_thom_vpage));
- save_item(NAME(m_thom_border_index));
- save_item(NAME(m_thom_vstate_dirty));
- save_item(NAME(m_thom_vstate_last_dirty));
-
- m_thom_mode_point = 0;
- save_item(NAME(m_thom_mode_point));
- m_vrambank->set_entry( 0 );
-
- m_thom_floppy_rcount = 0;
- m_thom_floppy_wcount = 0;
- save_item(NAME(m_thom_floppy_wcount));
- save_item(NAME(m_thom_floppy_rcount));
- m_floppy_led.resolve();
-
- m_caps_led.resolve();
-
- m_thom_video_timer = machine().scheduler().timer_alloc(timer_expired_delegate());
-
- m_thom_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(thomson_state::thom_scanline_start),this));
-
- m_thom_lightpen_nb = 0;
- m_thom_lightpen_cb = nullptr;
- m_thom_lightpen_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(thomson_state::thom_lightpen_step),this));
- save_item(NAME(m_thom_lightpen_nb));
-
- m_thom_init_cb = nullptr;
- m_thom_init_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(thomson_state::thom_set_init),this));
-
- m_thom_bwidth = 0;
- m_thom_bheight = 0;
- m_thom_hires = 0;
- m_thom_hires_better = 0;
- save_item(NAME(m_thom_bwidth));
- save_item(NAME(m_thom_bheight));
- save_item(NAME(m_thom_hires));
- save_item(NAME(m_thom_hires_better));
-}
-
-
-/* sets the fixed palette (for MO5,TO7,TO7/70) and gamma correction */
-void thomson_state::thom_configure_palette(double gamma, const uint16_t* pal, palette_device& palette)
-{
- std::copy_n(&pal[0], 16, &m_thom_last_pal[0]);
- std::copy_n(&pal[0], 16, &m_thom_pal[0]);
-
- for ( int i = 0; i < 4097; i++ )
- {
- uint8_t r = 255. * pow( (i & 15) / 15., gamma );
- uint8_t g = 255. * pow( ((i>> 4) & 15) / 15., gamma );
- uint8_t b = 255. * pow( ((i >> 8) & 15) / 15., gamma );
- /* uint8_t alpha = i & 0x1000 ? 0 : 255; TODO: transparency */
- palette.set_pen_color(i, r, g, b );
- }
-}
-
-
-void thomson_state::thom_palette(palette_device &palette)
-{
- LOG("thom: palette init called\n");
-
- /* TO8 and later use an EF9369 color palette chip
- The spec shows a built-in gamma correction for gamma=2.8
- i.e., output is out = in ^ (1/2.8)
-
- For the TO7, the gamma correction is irrelevant.
-
- For the TO7/70, we use the same palette and gamma has the TO8,
- which gives good results (but is not verified).
- */
- thom_configure_palette(1.0 / 2.8, thom_pal_init, palette);
-}
-
-void thomson_state::mo5_palette(palette_device &palette)
-{
- LOG("thom: MO5 palette init called\n");
-
- /* The MO5 has a different fixed palette than the TO7/70.
- We use a smaller gamma correction which gives intutively better
- results (but is not verified).
- */
- thom_configure_palette(1.0, mo5_pal_init, palette);
-}
-
-
-
-/***************************** TO7 / T9000 *************************/
-
-
-
-/* write to video memory through addresses 0x4000-0x5fff */
-void thomson_state::to7_vram_w(offs_t offset, uint8_t data)
-{
- assert( offset < 0x2000 );
- /* force two topmost color bits to 1 */
- if ( m_thom_mode_point )
- data |= 0xc0;
- if ( m_thom_vram[ offset + m_thom_mode_point ] == data )
- return;
- m_thom_vram[ offset + m_thom_mode_point ] = data;
- /* dirty whole scanline */
- m_thom_vmem_dirty[ offset / 40 ] = true;
-}
-
-
-
-/* bits 0-13 : latched gpl of lightpen position */
-/* bit 14: latched INIT */
-/* bit 15: latched INIL */
-unsigned thomson_state::to7_lightpen_gpl ( int decx, int decy )
-{
- int x,y;
- thom_get_lightpen_pos( &x, &y );
- x -= m_thom_bwidth;
- y -= m_thom_bheight;
- if ( x < 0 || y < 0 || x >= 320 || y >= 200 )
- return 0;
- x += decx;
- y += decy;
- return y*40 + x/8 + (x < 320 ? 0x4000 : 0) + 0x8000;
-}
-
-
-
-/************************** TO7/70 / MO5 ****************************/
-
-
-
-/* write to video memory through addresses 0x4000-0x5fff (TO)
- or 0x0000-0x1fff (MO) */
-void thomson_state::to770_vram_w(offs_t offset, uint8_t data)
-{
- assert( offset < 0x2000 );
- if ( m_thom_vram[ offset + m_thom_mode_point ] == data )
- return;
- m_thom_vram[ offset + m_thom_mode_point ] = data;
- /* dirty whole scanline */
- m_thom_vmem_dirty[ offset / 40 ] = true;
-}
-
-
-
-
-/***************************** TO8 ******************************/
-
-
-
-/* write to video memory through system space (always page 1) */
-
-void thomson_state::to8_sys_lo_w(offs_t offset, uint8_t data)
-{
- uint8_t* dst = m_thom_vram + offset + 0x6000;
- assert( offset < 0x2000 );
- if ( *dst == data )
- return;
- *dst = data;
- /* dirty whole scanline */
- m_thom_vmem_dirty[ offset / 40 ] = true;
-}
-
-
-
-void thomson_state::to8_sys_hi_w(offs_t offset, uint8_t data)
-{
- uint8_t* dst = m_thom_vram + offset + 0x4000;
- assert( offset < 0x2000 );
- if ( *dst == data ) return;
- *dst = data;
- /* dirty whole scanline */
- m_thom_vmem_dirty[ offset / 40 ] = true;
-}
-
-
-
-/* write to video memory through data space */
-
-void thomson_state::to8_data_lo_w(offs_t offset, uint8_t data)
-{
- uint8_t* dst = m_thom_vram + ( ( offset + 0x4000 * m_to8_data_vpage + 0x2000 ) & m_ram->mask() );
- assert( offset < 0x2000 );
- if ( *dst == data )
- return;
- *dst = data;
- /* dirty whole scanline */
- if ( m_to8_data_vpage >= 4 )
- return;
- m_thom_vmem_dirty[ offset / 40 ] = true;
-}
-
-
-
-void thomson_state::to8_data_hi_w(offs_t offset, uint8_t data)
-{
- uint8_t* dst = m_thom_vram + ( ( offset + 0x4000 * m_to8_data_vpage ) & m_ram->mask() );
- assert( offset < 0x2000 );
- if ( *dst == data )
- return;
- *dst = data;
- /* dirty whole scanline */
- if ( m_to8_data_vpage >= 4 )
- return;
- m_thom_vmem_dirty[ offset / 40 ] = true;
-}
-
-
-
-/* write to video memory page through cartridge addresses space */
-void thomson_state::to8_vcart_w(offs_t offset, uint8_t data)
-{
- uint8_t* dst = m_thom_vram + ( ( offset + 0x4000 * m_to8_cart_vpage ) & m_ram->mask() );
- assert( offset < 0x4000 );
- if ( *dst == data )
- return;
- *dst = data;
- /* dirty whole scanline */
- if ( m_to8_cart_vpage >= 4 )
- return;
- m_thom_vmem_dirty[ (offset & 0x1fff) / 40 ] = true;
-}
-
-void thomson_state::mo6_vcart_lo_w(offs_t offset, uint8_t data)
-{
- uint8_t* dst = m_thom_vram + ( ( offset + 0x3000 + 0x4000 * m_to8_cart_vpage ) & m_ram->mask() );
- assert( offset < 0x1000 );
- if ( *dst == data )
- return;
- *dst = data;
- /* dirty whole scanline */
- if ( m_to8_cart_vpage >= 4 )
- return;
- m_thom_vmem_dirty[ (offset & 0x1fff) / 40 ] = true;
-}
-
-void thomson_state::mo6_vcart_hi_w(offs_t offset, uint8_t data)
-{
- uint8_t* dst = m_thom_vram + ( ( offset + 0x4000 * m_to8_cart_vpage ) & m_ram->mask() );
- assert( offset < 0x3000 );
- if ( *dst == data )
- return;
- *dst = data;
- /* dirty whole scanline */
- if ( m_to8_cart_vpage >= 4 )
- return;
- m_thom_vmem_dirty[ (offset & 0x1fff) / 40 ] = true;
-}