From: Toni Wilen Date: Tue, 1 May 2018 13:24:22 +0000 (+0300) Subject: Implemented horizontal doubling to cirrus logic emulation. X-Git-Tag: 4000~84 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=3ff588f9732e5b2421a040f2df435ef04a4871e1;p=francis%2Fwinuae.git Implemented horizontal doubling to cirrus logic emulation. --- diff --git a/qemuvga/cirrus_vga.cpp b/qemuvga/cirrus_vga.cpp index 9e6f53fc..71bdae36 100644 --- a/qemuvga/cirrus_vga.cpp +++ b/qemuvga/cirrus_vga.cpp @@ -1148,11 +1148,20 @@ static void cirrus_get_resolution(VGACommonState *s, int *pwidth, int *pheight) ((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; @@ -2284,6 +2293,7 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y) 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; @@ -2318,10 +2328,10 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y) 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; @@ -2338,16 +2348,16 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y) 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; } } diff --git a/qemuvga/cirrus_vga_template.h b/qemuvga/cirrus_vga_template.h index 3b282805..f91e907f 100644 --- a/qemuvga/cirrus_vga_template.h +++ b/qemuvga/cirrus_vga_template.h @@ -37,18 +37,25 @@ static void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1, 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: diff --git a/qemuvga/vga.cpp b/qemuvga/vga.cpp index ffd086d0..bdabcb93 100644 --- a/qemuvga/vga.cpp +++ b/qemuvga/vga.cpp @@ -1519,11 +1519,15 @@ enum { 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] = { @@ -1575,37 +1579,69 @@ static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_ 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) @@ -1788,24 +1824,24 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) 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; } } diff --git a/qemuvga/vga_int.h b/qemuvga/vga_int.h index fad7640e..e81854a8 100644 --- a/qemuvga/vga_int.h +++ b/qemuvga/vga_int.h @@ -139,6 +139,7 @@ typedef struct VGACommonState { 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; diff --git a/qemuvga/vga_template.h b/qemuvga/vga_template.h index f6f6a01d..2ea2cabe 100644 --- a/qemuvga/vga_template.h +++ b/qemuvga/vga_template.h @@ -370,6 +370,27 @@ static void glue(vga_draw_line15_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, #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 */ @@ -395,6 +416,27 @@ static void glue(vga_draw_line16_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, #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 */ @@ -421,6 +463,32 @@ static void glue(vga_draw_line24_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, } 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 */ @@ -451,6 +519,32 @@ static void glue(vga_draw_line32_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, #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