From 63b431cc9ebc7af5d632db54d36cea92df97fe0b Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Mar 2018 22:10:52 +0000 Subject: [PATCH] Fix S3 Vision864 & Trio cursor colours in XFree86. --- src/vid_s3.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index 461facf..db851d5 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -136,6 +136,9 @@ typedef struct s3_t uint64_t status_time; uint8_t subsys_cntl, subsys_stat; + + uint32_t hwc_fg_col, hwc_bg_col; + int hwc_col_stack_pos; } s3_t; #define INT_VSY (1 << 0) @@ -883,6 +886,37 @@ void s3_out(uint16_t addr, uint8_t val, void *p) if ((s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) && svga->bpp == 32) svga->hwcursor.x <<= 1; break; + + case 0x4a: + switch (s3->hwc_col_stack_pos) + { + case 0: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_fg_col = (s3->hwc_fg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + break; + case 0x4b: + switch (s3->hwc_col_stack_pos) + { + case 0: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_bg_col = (s3->hwc_bg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + break; case 0x53: case 0x58: case 0x59: case 0x5a: @@ -959,6 +993,7 @@ uint8_t s3_in(uint16_t addr, void *p) case 0x30: return s3->id; /*Chip ID*/ case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); + case 0x45: s3->hwc_col_stack_pos = 0; break; case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); case 0x69: return s3->ma_ext; case 0x6a: return s3->bank; @@ -2015,11 +2050,44 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat void s3_hwcursor_draw(svga_t *svga, int displine) { + s3_t *s3 = (s3_t *)svga->p; int x; uint16_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - + uint32_t fg = 0, bg = 0; + + switch (svga->bpp) + { + case 15: + fg = video_15to32[s3->hwc_fg_col & 0xffff]; + bg = video_15to32[s3->hwc_bg_col & 0xffff]; + break; + + case 16: + fg = video_16to32[s3->hwc_fg_col & 0xffff]; + bg = video_16to32[s3->hwc_bg_col & 0xffff]; + break; + + case 24: case 32: + fg = s3->hwc_fg_col; + bg = s3->hwc_bg_col; + break; + + default: + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) + { + fg = svga->pallook[s3->hwc_fg_col & 0xff]; + bg = svga->pallook[s3->hwc_bg_col & 0xff]; + } + else + { + fg = svga->pallook[svga->crtc[0xe]]; + bg = svga->pallook[svga->crtc[0xf]]; + } + break; + } + if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; @@ -2033,7 +2101,7 @@ void s3_hwcursor_draw(svga_t *svga, int displine) if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x8000)) - ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? 0xffffff : 0; + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? fg : bg; else if (dat[1] & 0x8000) ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; // pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]);