((s->cr[0x07] & 0x40) << 3);
height = (height + 1);
/* interlace support */
- if (s->cr[0x1a] & 0x01)
- height *= 2;
+ if (s->cr[0x1a] & 0x01) {
+ height *= 2;
+ }
/* multiply vertical registers by two. TW. */
- if (s->cr[0x17] & 0x04)
+ if (s->cr[0x17] & 0x04) {
height *= 2;
+ }
+ /* keep aspect if CGX doublescan mode */
+ if (s->graphic_mode == 1 && cirrus_get_bpp(s) >= 8 && height * 3 / 4 >= width) {
+ width *= 2;
+ s->double_scan2 = 1;
+ } else {
+ s->double_scan2 = 0;
+ }
*pwidth = width;
*pheight = height;
unsigned int color0, color1;
const uint8_t *palette, *src;
uint32_t content;
+ int doublescan2 = s1->double_scan2;
if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW))
return;
return;
w = h;
- x1 = s->hw_cursor_x;
+ x1 = s->hw_cursor_x << doublescan2;
if (x1 >= s->vga.last_scr_width)
return;
- x2 = s->hw_cursor_x + w;
+ x2 = x1 + (w << doublescan2);
if (x2 > s->vga.last_scr_width)
x2 = s->vga.last_scr_width;
w = x2 - x1;
default:
break;
case 8:
- vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff);
+ vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, doublescan2, 0xff);
break;
case 15:
- vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff);
+ vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, doublescan2, 0x7fff);
break;
case 16:
- vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff);
+ vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, doublescan2, 0xffff);
break;
- case 32:
- vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff);
+ case 32:
+ vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, doublescan2, 0xffffff);
break;
}
}
int poffset, int w,
unsigned int color0,
unsigned int color1,
+ unsigned int xdoubled,
unsigned int color_xor)
{
const uint8_t *plane0, *plane1;
- int x, b0, b1;
+ int x, x2, b0, b1;
uint8_t *d;
-
+ int xcount;
+
d = d1;
plane0 = src1;
plane1 = src1 + poffset;
- for (x = 0; x < w; x++) {
- b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
- b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
+ xcount = 0;
+ for (x = 0, x2 = 0; x < w; x++) {
+ b0 = (plane0[x2 >> 3] >> (7 - (x2 & 7))) & 1;
+ b1 = (plane1[x2 >> 3] >> (7 - (x2 & 7))) & 1;
+ if (xcount++ == xdoubled) {
+ x2++;
+ xcount = 0;
+ }
#if DEPTH == 8
switch (b0 | (b1 << 1)) {
case 0:
VGA_DRAW_LINE4D2,
VGA_DRAW_LINE8D2,
VGA_DRAW_LINE8,
- VGA_DRAW_LINE15,
- VGA_DRAW_LINE16,
- VGA_DRAW_LINE24,
- VGA_DRAW_LINE32,
- VGA_DRAW_LINE_NB,
+ VGA_DRAW_LINE15,
+ VGA_DRAW_LINE15X2,
+ VGA_DRAW_LINE16,
+ VGA_DRAW_LINE16X2,
+ VGA_DRAW_LINE24,
+ VGA_DRAW_LINE24X2,
+ VGA_DRAW_LINE32,
+ VGA_DRAW_LINE32X2,
+ VGA_DRAW_LINE_NB,
};
static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
vga_draw_line8_16,
vga_draw_line8_16,
- vga_draw_line15_8,
- vga_draw_line15_15,
- vga_draw_line15_16,
- vga_draw_line15_32,
- vga_draw_line15_32bgr,
- vga_draw_line15_15bgr,
- vga_draw_line15_16bgr,
-
- vga_draw_line16_8,
- vga_draw_line16_15,
- vga_draw_line16_16,
- vga_draw_line16_32,
- vga_draw_line16_32bgr,
- vga_draw_line16_15bgr,
- vga_draw_line16_16bgr,
-
- vga_draw_line24_8,
- vga_draw_line24_15,
- vga_draw_line24_16,
- vga_draw_line24_32,
- vga_draw_line24_32bgr,
- vga_draw_line24_15bgr,
- vga_draw_line24_16bgr,
-
- vga_draw_line32_8,
- vga_draw_line32_15,
- vga_draw_line32_16,
- vga_draw_line32_32,
- vga_draw_line32_32bgr,
- vga_draw_line32_15bgr,
- vga_draw_line32_16bgr,
+ vga_draw_line15_8,
+ vga_draw_line15_15,
+ vga_draw_line15_16,
+ vga_draw_line15_32,
+ vga_draw_line15_32bgr,
+ vga_draw_line15_15bgr,
+ vga_draw_line15_16bgr,
+
+ vga_draw_line15x2_8,
+ vga_draw_line15x2_15,
+ vga_draw_line15x2_16,
+ vga_draw_line15x2_32,
+ vga_draw_line15x2_32bgr,
+ vga_draw_line15x2_15bgr,
+ vga_draw_line15x2_16bgr,
+
+ vga_draw_line16_8,
+ vga_draw_line16_15,
+ vga_draw_line16_16,
+ vga_draw_line16_32,
+ vga_draw_line16_32bgr,
+ vga_draw_line16_15bgr,
+ vga_draw_line16_16bgr,
+
+ vga_draw_line16x2_8,
+ vga_draw_line16x2_15,
+ vga_draw_line16x2_16,
+ vga_draw_line16x2_32,
+ vga_draw_line16x2_32bgr,
+ vga_draw_line16x2_15bgr,
+ vga_draw_line16x2_16bgr,
+
+ vga_draw_line24_8,
+ vga_draw_line24_15,
+ vga_draw_line24_16,
+ vga_draw_line24_32,
+ vga_draw_line24_32bgr,
+ vga_draw_line24_15bgr,
+ vga_draw_line24_16bgr,
+
+ vga_draw_line24x2_8,
+ vga_draw_line24x2_15,
+ vga_draw_line24x2_16,
+ vga_draw_line24x2_32,
+ vga_draw_line24x2_32bgr,
+ vga_draw_line24x2_15bgr,
+ vga_draw_line24x2_16bgr,
+
+ vga_draw_line32_8,
+ vga_draw_line32_15,
+ vga_draw_line32_16,
+ vga_draw_line32_32,
+ vga_draw_line32_32bgr,
+ vga_draw_line32_15bgr,
+ vga_draw_line32_16bgr,
+
+ vga_draw_line32x2_8,
+ vga_draw_line32x2_15,
+ vga_draw_line32x2_16,
+ vga_draw_line32x2_32,
+ vga_draw_line32x2_32bgr,
+ vga_draw_line32x2_15bgr,
+ vga_draw_line32x2_16bgr,
};
static int vga_get_bpp(VGACommonState *s)
break;
case 8:
full_update |= update_palette256(s);
- v = VGA_DRAW_LINE8;
+ v = s->double_scan2 ? VGA_DRAW_LINE8D2 : VGA_DRAW_LINE8;
bits = 8;
break;
case 15:
- v = VGA_DRAW_LINE15;
- bits = 16;
+ v = s->double_scan2 ? VGA_DRAW_LINE15X2 : VGA_DRAW_LINE15;
+ bits = 16;
break;
case 16:
- v = VGA_DRAW_LINE16;
- bits = 16;
+ v = s->double_scan2 ? VGA_DRAW_LINE16X2 : VGA_DRAW_LINE16;
+ bits = 16;
break;
case 24:
- v = VGA_DRAW_LINE24;
- bits = 24;
+ v = s->double_scan2 ? VGA_DRAW_LINE24X2 : VGA_DRAW_LINE24;
+ bits = 24;
break;
case 32:
- v = VGA_DRAW_LINE32;
- bits = 32;
+ v = s->double_scan2 ? VGA_DRAW_LINE32X2 : VGA_DRAW_LINE32;
+ bits = 32;
break;
}
}
int graphic_mode;
uint8_t shift_control;
uint8_t double_scan;
+ uint8_t double_scan2;
uint32_t line_offset;
uint32_t line_compare;
uint32_t start_addr;
#endif
}
+/*
+* 15 bit color, doubled
+*/
+static void glue(vga_draw_line15x2_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+ int w;
+ uint32_t v, r, g, b;
+
+ w = width;
+ do {
+ v = lduw_raw((void *)s);
+ r = (v >> 7) & 0xf8;
+ g = (v >> 2) & 0xf8;
+ b = (v << 3) & 0xf8;
+ ((PIXEL_TYPE *)d)[0] = ((PIXEL_TYPE *)d)[1] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ s += 2;
+ d += BPP * 2;
+ } while (--w != 0);
+}
+
/*
* 16 bit color
*/
#endif
}
+/*
+* 16 bit color, doubled
+*/
+static void glue(vga_draw_line16x2_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+ int w;
+ uint32_t v, r, g, b;
+
+ w = width;
+ do {
+ v = lduw_raw((void *)s);
+ r = (v >> 8) & 0xf8;
+ g = (v >> 3) & 0xfc;
+ b = (v << 3) & 0xf8;
+ ((PIXEL_TYPE *)d)[0] = ((PIXEL_TYPE *)d)[1] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ s += 2;
+ d += BPP * 2;
+ } while (--w != 0);
+}
+
/*
* 24 bit color
*/
} while (--w != 0);
}
+/*
+* 24 bit color, doubled
+*/
+static void glue(vga_draw_line24x2_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+ int w;
+ uint32_t r, g, b;
+
+ w = width;
+ do {
+#if defined(TARGET_WORDS_BIGENDIAN)
+ r = s[0];
+ g = s[1];
+ b = s[2];
+#else
+ b = s[0];
+ g = s[1];
+ r = s[2];
+#endif
+ ((PIXEL_TYPE *)d)[0] = ((PIXEL_TYPE *)d)[1] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ s += 3;
+ d += BPP * 2;
+ } while (--w != 0);
+}
+
/*
* 32 bit color
*/
#endif
}
+/*
+* 32 bit color, doubled
+*/
+static void glue(vga_draw_line32x2_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
+ const uint8_t *s, int width)
+{
+ int w;
+ uint32_t r, g, b;
+
+ w = width;
+ do {
+#if defined(TARGET_WORDS_BIGENDIAN)
+ r = s[1];
+ g = s[2];
+ b = s[3];
+#else
+ b = s[0];
+ g = s[1];
+ r = s[2];
+#endif
+ ((PIXEL_TYPE *)d)[0] = ((PIXEL_TYPE *)d)[1] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+ s += 4;
+ d += BPP * 2;
+ } while (--w != 0);
+}
+
#undef PUT_PIXEL2
#undef DEPTH
#undef BPP