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).
This commit is contained in:
TC1995
2024-04-26 22:52:58 +02:00
parent 9c2d0ab545
commit 738446fea6

View File

@@ -151,37 +151,50 @@ xga_updatemapping(svga_t *svga)
xga->aperture_cntl, xga->access_mode, svga->gdcreg[6] & 0x0c, xga->aperture_cntl, xga->access_mode, svga->gdcreg[6] & 0x0c,
xga->linear_endian_reverse, xga->a5_test, xga->on); xga->linear_endian_reverse, xga->a5_test, xga->on);
if (((xga->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) { switch (xga->op_mode & 7) {
if ((xga->aperture_cntl == 1) || (xga->aperture_cntl == 2)) { case 0:
if (xga->aperture_cntl == 1) xga_log("XGA: VGA mode address decode disabled.\n");
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); break;
else case 1:
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); 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); mem_mapping_disable(&xga->video_mapping);
xga->banked_mask = 0xffff; break;
if (!xga->linear_endian_reverse) case 1:
mem_mapping_disable(&xga->linear_mapping); xga_log("XGA: 64KB aperture at A0000.\n");
} else if (xga->aperture_cntl == 0) { mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); mem_mapping_enable(&xga->video_mapping);
mem_mapping_enable(&xga->video_mapping); xga->banked_mask = 0xffff;
xga->banked_mask = 0xffff; break;
if (xga->base_addr_1mb) case 2:
mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); xga_log("XGA: 64KB aperture at B0000.\n");
else mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); mem_mapping_enable(&xga->video_mapping);
xga->banked_mask = 0xffff;
if (xga->a5_test && (xga->access_mode & 8) && !xga->linear_endian_reverse) { break;
xga->on = 0; default:
vga_on = 1; break;
xga_log("A5 test valid.\n");
} }
} 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);
} }
xga_log("VGA on = %d, map = %02x.\n", vga_on, svga->gdcreg[6] & 0x0c);
} }
void void
@@ -410,28 +423,6 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
case 0x61: case 0x61:
xga->sprite_pal_addr_idx = (xga->sprite_pal_addr_idx & 0xff) | ((val & 0x3f) << 8); xga->sprite_pal_addr_idx = (xga->sprite_pal_addr_idx & 0xff) | ((val & 0x3f) << 8);
xga->sprite_pos = xga->sprite_pal_addr_idx & 0x1ff; 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_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); 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_t *xga = (xga_t *) svga->xga;
xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val);
switch (addr & 0x0f) { switch (addr & 0x0f) {
case 0: case 0:
xga->op_mode = val; xga->op_mode = val;
break; break;
case 1: case 1:
xga->aperture_cntl = val; xga->aperture_cntl = val & 3;
xga_updatemapping(svga); xga_updatemapping(svga);
break; break;
case 4: case 4:
@@ -561,6 +551,7 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv)
case 0x0e: case 0x0e:
case 0x0f: case 0x0f:
xga->regs[xga->regs_idx] = val; 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]); xga_ext_out_reg(xga, svga, xga->regs_idx, xga->regs[xga->regs_idx]);
break; break;
@@ -801,6 +792,8 @@ xga_ext_inb(uint16_t addr, void *priv)
default: default:
ret = xga->regs[xga->regs_idx]; 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;
} }
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) { switch (addr & 0x7f) {
case 0x11: case 0x11:
xga->accel.control = val; xga->accel.control = val;
xga_log("Control=%02x.\n", val);
break; break;
case 0x12: 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]; temp = xga->vga_bios_rom.rom[addr];
} else { } else {
switch (addr & 0x7f) { switch (addr & 0x7f) {
case 0x0c:
temp = xga->regs[0x0c];
break;
case 0x0d:
temp = xga->regs[0x0d];
break;
case 0x11: case 0x11:
temp = xga->accel.control; temp = xga->accel.control;
if (xga->accel.control & 0x08) if (xga->accel.control & 0x08)
@@ -2423,42 +2423,45 @@ xga_memio_readl(uint32_t addr, void *priv)
static void static void
xga_hwcursor_draw(svga_t *svga, int displine) xga_hwcursor_draw(svga_t *svga, int displine)
{ {
xga_t *xga = (xga_t *) svga->xga; xga_t *xga = (xga_t *) svga->xga;
uint8_t dat = 0; int comb;
int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff; uint8_t dat = 0;
int x_pos; int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff;
int y_pos; int idx = 0;
int comb = 0; int x_pos;
uint32_t *p; int y_pos;
int idx = xga->cursor_data_on ? 32 : 0; 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) if (xga->interlace && xga->hwcursor_oddeven)
xga->hwcursor_latch.addr += 16; xga->hwcursor_latch.addr += 16;
y_pos = displine; for (uint8_t x = 0; x < xga->hwcursor_latch.cur_xsize; x++) {
x_pos = offset + svga->x_add; dat = cd[xga->hwcursor_latch.addr & 0x3ff];
p = buffer32->line[y_pos];
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 >= 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) { switch (comb) {
case 0x00: case 0x00:
/* Cursor Color 1 */ /* Cursor Color 1 */
p[x_pos] = xga->hwc_color0; p[x_pos] = xga->hwc_color0;
break; break;
case 0x01: case 0x01:
/* Cursor Color 2 */ /* Cursor Color 2 */
p[x_pos] = xga->hwc_color1; p[x_pos] = xga->hwc_color1;
break; break;
case 0x03: case 0x03:
/* Complement */ /* Complement */
p[x_pos] ^= 0xffffff; p[x_pos] ^= 0xffffff;
break; break;
@@ -2466,6 +2469,8 @@ xga_hwcursor_draw(svga_t *svga, int displine)
break; 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) if ((x & 0x03) == 0x03)
xga->hwcursor_latch.addr++; xga->hwcursor_latch.addr++;
@@ -2927,12 +2932,12 @@ xga_poll(void *priv, svga_t *svga)
if (!xga->linepos) { if (!xga->linepos) {
if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { 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; xga->hwcursor_oddeven = 0;
} }
if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { 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; xga->hwcursor_oddeven = 1;
} }