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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user