summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/video/timex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/video/timex.c')
-rw-r--r--src/mess/video/timex.c262
1 files changed, 262 insertions, 0 deletions
diff --git a/src/mess/video/timex.c b/src/mess/video/timex.c
new file mode 100644
index 00000000000..79455ee29fd
--- /dev/null
+++ b/src/mess/video/timex.c
@@ -0,0 +1,262 @@
+/***************************************************************************
+
+ timex.c
+
+ Functions to emulate the video hardware of the Timex ZX Spectrum clones.
+
+ Changes:
+
+ DJR 08/02/00 - Added support for FLASH 1.
+ DJR 16/05/00 - Support for TS2068/TC2048 hires and 64 column modes.
+ DJR 19/05/00 - Speeded up Spectrum 128 screen refresh.
+ DJR 23/05/00 - Preliminary support for border colour emulation.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "includes/spectrum.h"
+#include "machine/ram.h"
+
+INLINE void spectrum_plot_pixel(bitmap_ind16 &bitmap, int x, int y, UINT32 color)
+{
+ bitmap.pix16(y, x) = (UINT16)color;
+}
+
+/* Update FLASH status for ts2068. Assumes flash update every 1/2s. */
+VIDEO_START( ts2068 )
+{
+ spectrum_state *state = machine.driver_data<spectrum_state>();
+ VIDEO_START_CALL( spectrum );
+ state->m_frame_invert_count = 30;
+}
+
+
+/*******************************************************************
+ *
+ * Update the TS2068 display.
+ *
+ * Port ff is used to set the display mode.
+ *
+ * bits 2..0 Video Mode Select
+ * 000 = Primary DFILE active (at 0x4000-0x5aff)
+ * 001 = Secondary DFILE active (at 0x6000-0x7aff)
+ * 010 = Extended Colour Mode (chars at 0x4000-0x57ff, colors 0x6000-0x7aff)
+ * 110 = 64 column mode (columns 0,2,4,...62 from DFILE 1
+ * columns 1,3,5,...63 from DFILE 2)
+ * other = unpredictable results
+ *
+ * bits 5..3 64 column mode ink/paper selection (attribute value in brackets)
+ * 000 = Black/White (56) 100 = Green/Magenta (28)
+ * 001 = Blue/Yellow (49) 101 = Cyan/Red (21)
+ * 010 = Red/Cyan (42) 110 = Yellow/Blue (14)
+ * 011 = Magenta/Green (35) 111 = White/Black (7)
+ *
+ *******************************************************************/
+
+/* Draw a scanline in TS2068/TC2048 hires mode (code modified from COUPE.C) */
+static void ts2068_hires_scanline(running_machine &machine,bitmap_ind16 &bitmap, int y, int borderlines)
+{
+ spectrum_state *state = machine.driver_data<spectrum_state>();
+ int x,b,scrx,scry;
+ unsigned short ink,pap;
+ unsigned char *attr, *scr;
+
+ scrx=TS2068_LEFT_BORDER;
+ scry=((y&7) * 8) + ((y&0x38)>>3) + (y&0xC0);
+
+ scr=machine.device<ram_device>(RAM_TAG)->pointer() + y*32;
+ attr=scr + 0x2000;
+
+ for (x=0;x<32;x++)
+ {
+ /* Get ink and paper colour with bright */
+ if (state->m_flash_invert && (*attr & 0x80))
+ {
+ ink=((*attr)>>3) & 0x0f;
+ pap=((*attr) & 0x07) + (((*attr)>>3) & 0x08);
+ }
+ else
+ {
+ ink=((*attr) & 0x07) + (((*attr)>>3) & 0x08);
+ pap=((*attr)>>3) & 0x0f;
+ }
+
+ for (b=0x80;b!=0;b>>=1)
+ {
+ if (*scr&b)
+ {
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,ink);
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,ink);
+ }
+ else
+ {
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,pap);
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,pap);
+ }
+ }
+ scr++;
+ attr++;
+ }
+}
+
+/* Draw a scanline in TS2068/TC2048 64-column mode */
+static void ts2068_64col_scanline(running_machine &machine,bitmap_ind16 &bitmap, int y, int borderlines, unsigned short inkcolor)
+{
+ int x,b,scrx,scry;
+ unsigned char *scr1, *scr2;
+
+ scrx=TS2068_LEFT_BORDER;
+ scry=((y&7) * 8) + ((y&0x38)>>3) + (y&0xC0);
+
+ scr1=machine.device<ram_device>(RAM_TAG)->pointer() + y*32;
+ scr2=scr1 + 0x2000;
+
+ for (x=0;x<32;x++)
+ {
+ for (b=0x80;b!=0;b>>=1)
+ {
+ if (*scr1&b)
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,inkcolor);
+ else
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,7-inkcolor);
+ }
+ scr1++;
+
+ for (b=0x80;b!=0;b>>=1)
+ {
+ if (*scr2&b)
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,inkcolor);
+ else
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,7-inkcolor);
+ }
+ scr2++;
+ }
+}
+
+/* Draw a scanline in TS2068/TC2048 lores (normal Spectrum) mode */
+static void ts2068_lores_scanline(running_machine &machine,bitmap_ind16 &bitmap, int y, int borderlines, int screen)
+{
+ spectrum_state *state = machine.driver_data<spectrum_state>();
+ int x,b,scrx,scry;
+ unsigned short ink,pap;
+ unsigned char *attr, *scr;
+
+ scrx=TS2068_LEFT_BORDER;
+ scry=((y&7) * 8) + ((y&0x38)>>3) + (y&0xC0);
+
+ scr = machine.device<ram_device>(RAM_TAG)->pointer() + y*32 + screen*0x2000;
+ attr = machine.device<ram_device>(RAM_TAG)->pointer() + ((scry>>3)*32) + screen*0x2000 + 0x1800;
+
+ for (x=0;x<32;x++)
+ {
+ /* Get ink and paper colour with bright */
+ if (state->m_flash_invert && (*attr & 0x80))
+ {
+ ink=((*attr)>>3) & 0x0f;
+ pap=((*attr) & 0x07) + (((*attr)>>3) & 0x08);
+ }
+ else
+ {
+ ink=((*attr) & 0x07) + (((*attr)>>3) & 0x08);
+ pap=((*attr)>>3) & 0x0f;
+ }
+
+ for (b=0x80;b!=0;b>>=1)
+ {
+ if (*scr&b)
+ {
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,ink);
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,ink);
+ }
+ else
+ {
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,pap);
+ spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,pap);
+ }
+ }
+ scr++;
+ attr++;
+ }
+}
+
+SCREEN_UPDATE_IND16( ts2068 )
+{
+ /* for now TS2068 will do a full-refresh */
+ spectrum_state *state = screen.machine().driver_data<spectrum_state>();
+ int count;
+ int full_refresh = 1;
+
+ if ((state->m_port_ff_data & 7) == 6)
+ {
+ /* 64 Column mode */
+ unsigned short inkcolor = (state->m_port_ff_data & 0x38) >> 3;
+ for (count = 0; count < 192; count++)
+ ts2068_64col_scanline(screen.machine(),bitmap, count, TS2068_TOP_BORDER, inkcolor);
+ }
+ else if ((state->m_port_ff_data & 7) == 2)
+ {
+ /* Extended Color mode */
+ for (count = 0; count < 192; count++)
+ ts2068_hires_scanline(screen.machine(),bitmap, count, TS2068_TOP_BORDER);
+ }
+ else if ((state->m_port_ff_data & 7) == 1)
+ {
+ /* Screen 6000-7aff */
+ for (count = 0; count < 192; count++)
+ ts2068_lores_scanline(screen.machine(),bitmap, count, TS2068_TOP_BORDER, 1);
+ }
+ else
+ {
+ /* Screen 4000-5aff */
+ for (count = 0; count < 192; count++)
+ ts2068_lores_scanline(screen.machine(),bitmap, count, TS2068_TOP_BORDER, 0);
+ }
+
+ spectrum_border_draw(screen.machine(), bitmap, full_refresh,
+ TS2068_TOP_BORDER, SPEC_DISPLAY_YSIZE, TS2068_BOTTOM_BORDER,
+ TS2068_LEFT_BORDER, TS2068_DISPLAY_XSIZE, TS2068_RIGHT_BORDER,
+ SPEC_LEFT_BORDER_CYCLES, SPEC_DISPLAY_XSIZE_CYCLES,
+ SPEC_RIGHT_BORDER_CYCLES, SPEC_RETRACE_CYCLES, 200, 0xfe);
+ return 0;
+}
+
+SCREEN_UPDATE_IND16( tc2048 )
+{
+ /* for now TS2068 will do a full-refresh */
+ spectrum_state *state = screen.machine().driver_data<spectrum_state>();
+ int count;
+ int full_refresh = 1;
+
+ if ((state->m_port_ff_data & 7) == 6)
+ {
+ /* 64 Column mode */
+ unsigned short inkcolor = (state->m_port_ff_data & 0x38) >> 3;
+ for (count = 0; count < 192; count++)
+ ts2068_64col_scanline(screen.machine(),bitmap, count, SPEC_TOP_BORDER, inkcolor);
+ }
+ else if ((state->m_port_ff_data & 7) == 2)
+ {
+ /* Extended Color mode */
+ for (count = 0; count < 192; count++)
+ ts2068_hires_scanline(screen.machine(),bitmap, count, SPEC_TOP_BORDER);
+ }
+ else if ((state->m_port_ff_data & 7) == 1)
+ {
+ /* Screen 6000-7aff */
+ for (count = 0; count < 192; count++)
+ ts2068_lores_scanline(screen.machine(),bitmap, count, SPEC_TOP_BORDER, 1);
+ }
+ else
+ {
+ /* Screen 4000-5aff */
+ for (count = 0; count < 192; count++)
+ ts2068_lores_scanline(screen.machine(),bitmap, count, SPEC_TOP_BORDER, 0);
+ }
+
+ spectrum_border_draw(screen.machine(), bitmap, full_refresh,
+ SPEC_TOP_BORDER, SPEC_DISPLAY_YSIZE, SPEC_BOTTOM_BORDER,
+ TS2068_LEFT_BORDER, TS2068_DISPLAY_XSIZE, TS2068_RIGHT_BORDER,
+ SPEC_LEFT_BORDER_CYCLES, SPEC_DISPLAY_XSIZE_CYCLES,
+ SPEC_RIGHT_BORDER_CYCLES, SPEC_RETRACE_CYCLES, 200, 0xfe);
+ return 0;
+}