Merge pull request #4403 from 86Box/tc1995

Cleanup of the XGA mapping to be less messed up.
This commit is contained in:
Miran Grča
2024-04-26 23:14:02 +02:00
committed by GitHub

View File

@@ -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;
}