// license:GPL-2.0+ // copyright-holders:Kevin Thacker #include "emu.h" #include "includes/pcw16.h" #include "machine/ram.h" #include "screen.h" #if 0 /* 16 colours, + 1 for border */ static const unsigned short pcw16_colour_table[PCW16_NUM_COLOURS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; #endif static constexpr rgb_t pcw16_palette[PCW16_NUM_COLOURS] = { { 0x080, 0x080, 0x080 }, // light grey { 0x080, 0x080, 0x080 }, // light grey { 0x000, 0x080, 0x080 }, // magenta { 0x000, 0x080, 0x080 }, // magenta { 0x080, 0x080, 0x080 }, // light grey { 0x080, 0x080, 0x080 }, // light grey { 0x0ff, 0x080, 0x080 }, // pastel green { 0x0ff, 0x080, 0x080 }, // pastel green { 0x000, 0x000, 0x080 }, // blue { 0x000, 0x000, 0x000 }, // black { 0x000, 0x080, 0x0ff }, // mauve { 0x000, 0x000, 0x0ff }, // bright blue { 0x000, 0x080, 0x000 }, // red { 0x000, 0x0ff, 0x000 }, // bright red { 0x000, 0x0ff, 0x080 }, // purple { 0x000, 0x0ff, 0x0ff }, // bright magenta { 0x0ff, 0x000, 0x080 }, // sea green { 0x0ff, 0x000, 0x0ff }, // bright green { 0x0ff, 0x080, 0x0ff }, // pastel cyan { 0x0ff, 0x000, 0x0ff }, // bright cyan { 0x0ff, 0x080, 0x000 }, // lime green { 0x0ff, 0x0ff, 0x000 }, // bright yellow { 0x0ff, 0x0ff, 0x080 }, // pastel yellow { 0x0ff, 0x0ff, 0x0ff }, // bright white { 0x080, 0x000, 0x080 }, // cyan { 0x080, 0x000, 0x000 }, // green { 0x080, 0x080, 0x0ff }, // pastel blue { 0x080, 0x000, 0x0ff }, // sky blue { 0x080, 0x080, 0x000 }, // yellow { 0x080, 0x0ff, 0x000 }, // orange { 0x080, 0x0ff, 0x080 }, // pink { 0x080, 0x0ff, 0x0ff } // pastel magenta }; inline void pcw16_state::pcw16_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color) { bitmap.pix(y, x) = (uint16_t)color; } /* Initialise the palette */ void pcw16_state::pcw16_colours(palette_device &palette) const { palette.set_pen_colors(0, pcw16_palette); } void pcw16_state::video_start() { } /* 640, 1 bit per pixel */ void pcw16_state::pcw16_vh_decode_mode0(bitmap_ind16 &bitmap, int x, int y, uint8_t byte) { int b; int local_byte; int cols[2]; int px; local_byte = byte; cols[0] = m_colour_palette[0]; cols[1] = m_colour_palette[1]; px = x; for (b=0; b<8; b++) { pcw16_plot_pixel(bitmap, px, y, cols[(local_byte>>7) & 0x01]); px++; local_byte = local_byte<<1; } } /* 320, 2 bits per pixel */ void pcw16_state::pcw16_vh_decode_mode1(bitmap_ind16 &bitmap, int x, int y, uint8_t byte) { int b; int px; int local_byte; int cols[4]; for (b=0; b<3; b++) { cols[b] = m_colour_palette[b]; } local_byte = byte; px = x; for (b=0; b<4; b++) { int col; col = cols[((local_byte>>6) & 0x03)]; pcw16_plot_pixel(bitmap, px, y, col); px++; pcw16_plot_pixel(bitmap, px, y, col); px++; local_byte = local_byte<<2; } } /* 160, 4 bits per pixel */ void pcw16_state::pcw16_vh_decode_mode2(bitmap_ind16 &bitmap, int x, int y, uint8_t byte) { int px; int b; int local_byte; int cols[2]; cols[0] = m_colour_palette[0]; cols[1] = m_colour_palette[1]; local_byte = byte; px = x; for (b=0; b<2; b++) { int col; col = cols[((local_byte>>4)&0x0f)]; pcw16_plot_pixel(bitmap, px, y, col); px++; pcw16_plot_pixel(bitmap, px, y, col); px++; pcw16_plot_pixel(bitmap, px, y, col); px++; pcw16_plot_pixel(bitmap, px, y, col); px++; local_byte = local_byte<<4; } } /*************************************************************************** Draw the game screen in the given bitmap_ind16. Do NOT call osd_update_display() from this function, it will be called by the main emulation engine. ***************************************************************************/ uint32_t pcw16_state::screen_update_pcw16(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { uint8_t *ram = m_ram->pointer(); unsigned char *pScanLine = (unsigned char *)ram + 0x0fc00; //0x03c00; //0x020FC00; int y; int x; int border_colour; border_colour = m_video_control & 31; /* reverse video? */ if (m_video_control & (1<<7)) { /* colour 0 and colour 1 need to be inverted? - what happens in mode 1 and 2 - ignored? or is bit 1 toggled, or is whole lot toggled? */ /* force border to be colour 1 */ border_colour = m_colour_palette[1]; } if ((m_video_control & (1<<6))==0) { /* blank */ rectangle rect(0, PCW16_SCREEN_WIDTH, 0, PCW16_SCREEN_HEIGHT); bitmap.fill(border_colour, rect); } else { /* no blank */ /* render top border */ rectangle rect(0, PCW16_SCREEN_WIDTH, 0, PCW16_BORDER_HEIGHT); bitmap.fill(border_colour, rect); /* render bottom border */ rect.set(0, PCW16_SCREEN_WIDTH, PCW16_BORDER_HEIGHT + PCW16_DISPLAY_HEIGHT, PCW16_BORDER_HEIGHT + PCW16_DISPLAY_HEIGHT + PCW16_BORDER_HEIGHT); bitmap.fill(border_colour, rect); /* render border on either side of display */ bitmap.plot_box(0, PCW16_BORDER_HEIGHT, 8, PCW16_DISPLAY_HEIGHT, border_colour); bitmap.plot_box(PCW16_DISPLAY_WIDTH + PCW16_BORDER_WIDTH, PCW16_BORDER_HEIGHT, 8, PCW16_DISPLAY_HEIGHT, border_colour); /* render display */ for (y=0; y>14) & 0x03); /* set initial x position */ x = PCW16_BORDER_WIDTH; for (b=0; b<80; b++) { int byte; byte = ram[Addr]; switch (mode) { case 0: { pcw16_vh_decode_mode0(bitmap, x, y+PCW16_BORDER_HEIGHT, byte); } break; case 1: { pcw16_vh_decode_mode1(bitmap, x, y+PCW16_BORDER_HEIGHT, byte); } break; case 3: case 2: { pcw16_vh_decode_mode2(bitmap, x, y+PCW16_BORDER_HEIGHT, byte); } break; } /* only lowest 16 bits are incremented between fetches */ Addr = ((Addr+1) & 0x0ffff) | AddrUpper; x=x+8; } pScanLine+=2; } } return 0; }