From 738446fea60bdaad2453c04c07b3d718d46b7e09 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Apr 2024 22:52:58 +0200 Subject: [PATCH] Cleanup of the XGA mapping to be less messed up. As well as the cursor/sprite being finally fixed when the xoff goes from 0x20 onwards. This makes Win3.x' XGA cursor look normal and everything else as well. (as in, intact). --- src/video/vid_xga.c | 157 +++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 76 deletions(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index fad5e4124..e62a14a61 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -151,37 +151,50 @@ xga_updatemapping(svga_t *svga) xga->aperture_cntl, xga->access_mode, svga->gdcreg[6] & 0x0c, xga->linear_endian_reverse, xga->a5_test, xga->on); - if (((xga->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) { - if ((xga->aperture_cntl == 1) || (xga->aperture_cntl == 2)) { - if (xga->aperture_cntl == 1) - mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); - else - mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); + switch (xga->op_mode & 7) { + case 0: + xga_log("XGA: VGA mode address decode disabled.\n"); + break; + case 1: + xga_log("XGA: VGA mode address decode enabled.\n"); + break; + case 2: + xga_log("XGA: 132-Column mode address decode disabled.\n"); + break; + case 3: + xga_log("XGA: 132-Column mode address decode enabled.\n"); + break; + default: + xga_log("XGA: Extended Graphics mode.\n"); + switch (xga->aperture_cntl) { + case 0: + xga_log("XGA: No 64KB aperture.\n"); + if (xga->base_addr_1mb) + mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); + else if (xga->linear_base) + mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); + else + mem_mapping_disable(&xga->linear_mapping); - mem_mapping_enable(&xga->video_mapping); - xga->banked_mask = 0xffff; - if (!xga->linear_endian_reverse) - mem_mapping_disable(&xga->linear_mapping); - } else if (xga->aperture_cntl == 0) { - mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); - mem_mapping_enable(&xga->video_mapping); - xga->banked_mask = 0xffff; - if (xga->base_addr_1mb) - mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); - else - mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); - - if (xga->a5_test && (xga->access_mode & 8) && !xga->linear_endian_reverse) { - xga->on = 0; - vga_on = 1; - xga_log("A5 test valid.\n"); + mem_mapping_disable(&xga->video_mapping); + break; + case 1: + xga_log("XGA: 64KB aperture at A0000.\n"); + mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); + mem_mapping_enable(&xga->video_mapping); + xga->banked_mask = 0xffff; + break; + case 2: + xga_log("XGA: 64KB aperture at B0000.\n"); + mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); + mem_mapping_enable(&xga->video_mapping); + xga->banked_mask = 0xffff; + break; + default: + break; } - } - - xga_log("XGA opmode (extended) = %d, disp mode = %d, aperture = %d, on = %d, linear endian reverse = %d.\n", xga->op_mode & 7, - xga->disp_cntl_2 & 7, xga->aperture_cntl, xga->on, xga->linear_endian_reverse); + break; } - xga_log("VGA on = %d, map = %02x.\n", vga_on, svga->gdcreg[6] & 0x0c); } void @@ -410,28 +423,6 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) case 0x61: xga->sprite_pal_addr_idx = (xga->sprite_pal_addr_idx & 0xff) | ((val & 0x3f) << 8); xga->sprite_pos = xga->sprite_pal_addr_idx & 0x1ff; - if ((xga->sprite_pos >= 0) && (xga->sprite_pos <= 16)) { - if ((xga->op_mode & 7) >= 5) - xga->cursor_data_on = 1; - else if ((xga->sprite_pos >= 1) || (((xga->disp_cntl_2 & 7) == 2) || (xga->disp_cntl_2 & 7) == 4)) - xga->cursor_data_on = 1; - else if (!xga->aperture_cntl) { - if (xga->linear_endian_reverse && !(xga->access_mode & 8)) - xga->cursor_data_on = 0; - } - } - - if ((xga->sprite_pos > 16) && (xga->sprite_pos <= 0x1ff)) { - if (xga->aperture_cntl) { - if (xga->sprite_pos & 0x0f) - xga->cursor_data_on = 1; - else - xga->cursor_data_on = 0; - } else - xga->cursor_data_on = 0; - } else if (!xga->sprite_pos && xga->cursor_data_on && !xga->aperture_cntl && xga->linear_endian_reverse) - xga->cursor_data_on = 0; - xga_log("Sprite POS = %d, data on = %d, idx = %d, apcntl = %d\n", xga->sprite_pos, xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl); @@ -515,13 +506,12 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) xga_t *xga = (xga_t *) svga->xga; xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); - switch (addr & 0x0f) { case 0: xga->op_mode = val; break; case 1: - xga->aperture_cntl = val; + xga->aperture_cntl = val & 3; xga_updatemapping(svga); break; case 4: @@ -561,6 +551,7 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) case 0x0e: case 0x0f: xga->regs[xga->regs_idx] = val; + xga_log("EXT OUT Reg=%02x, val=%02x.\n", xga->regs_idx, val); xga_ext_out_reg(xga, svga, xga->regs_idx, xga->regs[xga->regs_idx]); break; @@ -801,6 +792,8 @@ xga_ext_inb(uint16_t addr, void *priv) default: ret = xga->regs[xga->regs_idx]; + if ((xga->regs_idx == 0x0c) || (xga->regs_idx == 0x0d)) + xga_log("EXT IN Reg=%02x, val=%02x.\n", xga->regs_idx, ret); break; } break; @@ -1760,6 +1753,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) switch (addr & 0x7f) { case 0x11: xga->accel.control = val; + xga_log("Control=%02x.\n", val); break; case 0x12: @@ -2303,6 +2297,12 @@ xga_mem_read(uint32_t addr, xga_t *xga, UNUSED(svga_t *svga)) temp = xga->vga_bios_rom.rom[addr]; } else { switch (addr & 0x7f) { + case 0x0c: + temp = xga->regs[0x0c]; + break; + case 0x0d: + temp = xga->regs[0x0d]; + break; case 0x11: temp = xga->accel.control; if (xga->accel.control & 0x08) @@ -2423,42 +2423,45 @@ xga_memio_readl(uint32_t addr, void *priv) static void xga_hwcursor_draw(svga_t *svga, int displine) { - xga_t *xga = (xga_t *) svga->xga; - uint8_t dat = 0; - int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff; - int x_pos; - int y_pos; - int comb = 0; - uint32_t *p; - int idx = xga->cursor_data_on ? 32 : 0; + xga_t *xga = (xga_t *) svga->xga; + int comb; + uint8_t dat = 0; + int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff; + int idx = 0; + int x_pos; + int y_pos; + uint32_t *p; + const uint8_t *cd; + + if (xga->hwcursor_latch.xoff & 0x20) + idx = 32; + + cd = (uint8_t *) xga->sprite_data; if (xga->interlace && xga->hwcursor_oddeven) xga->hwcursor_latch.addr += 16; - y_pos = displine; - x_pos = offset + svga->x_add; - p = buffer32->line[y_pos]; + for (uint8_t x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { + dat = cd[xga->hwcursor_latch.addr & 0x3ff]; + + comb = (dat >> ((x & 0x03) << 1)) & 0x03; + + y_pos = displine; + x_pos = offset + svga->x_add; + p = buffer32->line[y_pos]; - for (int x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { if (x >= idx) { - if (!(x & 0x03)) - dat = xga->sprite_data[xga->hwcursor_latch.addr & 0x3ff]; - - comb = (dat >> ((x & 0x03) << 1)) & 0x03; - - x_pos = offset + svga->x_add + x; - switch (comb) { case 0x00: - /* Cursor Color 1 */ + /* Cursor Color 1 */ p[x_pos] = xga->hwc_color0; break; case 0x01: - /* Cursor Color 2 */ + /* Cursor Color 2 */ p[x_pos] = xga->hwc_color1; break; case 0x03: - /* Complement */ + /* Complement */ p[x_pos] ^= 0xffffff; break; @@ -2466,6 +2469,8 @@ xga_hwcursor_draw(svga_t *svga, int displine) break; } } + offset++; + xga_log("P=%08x, xpos=%d, comb=%x, ypos=%d, offset=%d, latchx=%d, latchxoff=%d.\n", p[x_pos], x_pos, comb, y_pos, offset, xga->hwcursor_latch.x, xga->hwcursor_latch.xoff); if ((x & 0x03) == 0x03) xga->hwcursor_latch.addr++; @@ -2927,12 +2932,12 @@ xga_poll(void *priv, svga_t *svga) if (!xga->linepos) { if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - (xga->cursor_data_on ? 32 : 0); + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize; xga->hwcursor_oddeven = 0; } if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - (xga->cursor_data_on ? 33 : 1); + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - 1; xga->hwcursor_oddeven = 1; }