More XGA fixes:

These make XGAKIT report 1MB of VRAM (from DOS).
This commit is contained in:
TC1995
2023-08-24 00:30:21 +02:00
parent f0fd4b0909
commit 23a2923724
3 changed files with 120 additions and 61 deletions

View File

@@ -42,6 +42,7 @@ typedef struct xga_t {
PALETTE extpal;
uint8_t test;
uint8_t test2;
uint8_t atest[2];
uint8_t testpixel;
@@ -157,10 +158,10 @@ typedef struct xga_t {
uint32_t rom_addr;
uint32_t ma;
uint32_t maback;
uint32_t extpallook[256];
uint32_t read_bank;
uint32_t write_bank;
uint32_t px_map_base;
uint32_t pallook[512];
uint64_t dispontime;
uint64_t dispofftime;

View File

@@ -212,6 +212,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
if (ibm8514_active)
dev->on = (val & 0x01) ? 0 : 1;
svga_log("3C3: XGA ON = %d.\n", xga->on);
vga_on = val & 0x01;
break;
case 0x3c4:
@@ -512,6 +513,7 @@ void
svga_set_ramdac_type(svga_t *svga, int type)
{
ibm8514_t *dev = &svga->dev8514;
xga_t *xga = &svga->xga;
if (svga->ramdac_type != type) {
svga->ramdac_type = type;
@@ -525,6 +527,14 @@ svga_set_ramdac_type(svga_t *svga, int type)
(svga->vgapal[c].g & 0x3f) * 4,
(svga->vgapal[c].b & 0x3f) * 4);
}
if (xga_active) {
if (svga->ramdac_type == RAMDAC_8BIT)
xga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
else
xga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4,
(svga->vgapal[c].g & 0x3f) * 4,
(svga->vgapal[c].b & 0x3f) * 4);
}
if (svga->ramdac_type == RAMDAC_8BIT)
svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
else
@@ -820,8 +830,10 @@ svga_poll(void *priv)
return;
}
if (xga_active && xga->on) {
xga_poll(xga, svga);
return;
if ((xga->disp_cntl_2 & 7) >= 3) {
xga_poll(xga, svga);
return;
}
}
if (!svga->linepos) {
@@ -1236,14 +1248,25 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
if (val == 0xa5) { /*Memory size test of XGA*/
xga->test = val;
xga->a5_test = 1;
xga->on = 0;
vga_on = 1;
xga->disp_cntl_2 = 0;
xga->clk_sel_1 = 0;
svga_log("XGA test1 addr = %05x.\n", addr);
return;
} else if (val == 0x5a) {
xga->test = val;
xga->on = 0;
vga_on = 1;
xga->disp_cntl_2 = 0;
xga->clk_sel_1 = 0;
return;
} else if ((val == 0x12) || (val == 0x34)) {
} else if ((addr == 0xa0000) || (addr == 0xa0010)) {
addr += xga->write_bank;
xga->vram[addr & xga->vram_mask] = val;
xga->linear_endian_reverse = 1;
svga_log("XGA Linear endian reverse write, val = %02x, addr = %05x, banked mask = %04x.\n", val, addr, svga->banked_mask);
if (!xga->a5_test)
xga->linear_endian_reverse = 1;
return;
}
} else {
@@ -1441,13 +1464,26 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv)
if (xga_active) {
if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) {
if (xga->test == 0xa5) { /*Memory size test of XGA*/
xga->on = 1;
vga_on = 0;
return xga->test;
if (addr == 0xa0001) {
ret = xga->test;
xga->on = 1;
vga_on = 0;
} else if ((addr == 0xa0000) && xga->a5_test) { /*This is required by XGAKIT to pass the memory test*/
addr += xga->read_bank;
ret = xga->vram[addr & xga->vram_mask];
} else {
ret = xga->test;
xga->on = 1;
vga_on = 0;
}
svga_log("A5 read: XGA ON = %d, addr = %05x.\n", xga->on, addr);
return ret;
} else if (xga->test == 0x5a) {
ret = xga->test;
xga->on = 1;
vga_on = 0;
return xga->test;
svga_log("5A read: XGA ON = %d.\n", xga->on);
return ret;
} else if ((addr == 0xa0000) || (addr == 0xa0010)) {
addr += xga->read_bank;
return xga->vram[addr & xga->vram_mask];

View File

@@ -49,6 +49,9 @@ static uint8_t xga_ext_inb(uint16_t addr, void *priv);
static void xga_writew(uint32_t addr, uint16_t val, void *priv);
static uint16_t xga_readw(uint32_t addr, void *priv);
static void xga_render_8bpp(svga_t *svga);
static void xga_render_16bpp(svga_t *svga);
int xga_active = 0;
#ifdef ENABLE_XGA_LOG
@@ -148,7 +151,6 @@ xga_updatemapping(svga_t *svga)
if (((xga->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) {
if ((xga->aperture_cntl == 1) || (xga->aperture_cntl == 2)) {
mem_mapping_disable(&svga->mapping);
if (xga->aperture_cntl == 1)
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
else
@@ -159,7 +161,6 @@ xga_updatemapping(svga_t *svga)
if (!xga->linear_endian_reverse)
mem_mapping_disable(&xga->linear_mapping);
} else if (xga->aperture_cntl == 0) {
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
mem_mapping_enable(&xga->video_mapping);
xga->banked_mask = 0xffff;
@@ -167,22 +168,18 @@ xga_updatemapping(svga_t *svga)
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->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && xga->on)
xga->linear_endian_reverse = 1;
else if (((xga->op_mode & 7) == 0) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && !xga->on) {
xga->linear_endian_reverse = 1;
}
if (xga->a5_test && (xga->access_mode & 8) && !xga->linear_endian_reverse) {
xga->on = 0;
vga_on = !xga->on;
vga_on = 1;
xga_log("A5 test valid.\n");
}
}
xga_log("XGA opmode (extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7,
xga->disp_cntl_2 & 7, xga->aperture_cntl);
}
xga_log("VGA on = %d.\n", vga_on);
xga_log("VGA on = %d, map = %02x.\n", vga_on, svga->gdcreg[6] & 0x0c);
}
void
@@ -214,15 +211,17 @@ xga_recalctimings(svga_t *svga)
xga->ma_latch = xga->disp_start_addr;
xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80);
switch ((xga->clk_sel_1 >> 2) & 3) {
case 0:
if (xga->clk_sel_2 & 0x80) {
xga_log("HDISP VGA0 = %d, XGA = %d.\n", svga->hdisp, xga->h_disp);
if (xga->clk_sel_2 & 0x80)
svga->clock = (cpuclock * (double) (1ULL << 32)) / 41539000.0;
} else {
else
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
}
break;
case 1:
xga_log("HDISP VGA1 = %d, XGA = %d.\n", svga->hdisp, xga->h_disp);
svga->clock = (cpuclock * (double) (1ULL << 32)) / 28322000.0;
break;
case 3:
@@ -369,11 +368,13 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
break;
case 0x50:
xga_log("Reg50 write = %02x.\n", val);
xga->disp_cntl_1 = val;
svga_recalctimings(svga);
break;
case 0x51:
xga_log("Reg51 write = %02x.\n", val);
xga->disp_cntl_2 = val;
xga->on = ((val & 7) >= 3);
vga_on = !xga->on;
@@ -381,6 +382,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
break;
case 0x54:
xga_log("Reg54 write = %02x.\n", val);
xga->clk_sel_1 = val;
svga_recalctimings(svga);
break;
@@ -404,7 +406,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
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) > 3))
else if ((xga->sprite_pos >= 1) || ((xga->disp_cntl_2 & 7) == 4))
xga->cursor_data_on = 1;
else if (xga->aperture_cntl == 0) {
if (xga->linear_endian_reverse && !(xga->access_mode & 8))
@@ -458,7 +460,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
svga->vgapal[index].r = svga->dac_r;
svga->vgapal[index].g = svga->dac_g;
svga->vgapal[index].b = xga->pal_b;
svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b);
xga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b);
svga->dac_pos = 0;
svga->dac_addr = (svga->dac_addr + 1) & 0xff;
break;
@@ -488,6 +490,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
break;
case 0x70:
xga_log("Reg70 write = %02x.\n", val);
xga->clk_sel_2 = val;
svga_recalctimings(svga);
break;
@@ -525,8 +528,18 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv)
if ((xga->op_mode & 7) < 4) {
xga->write_bank = xga->read_bank = 0;
} else {
xga->write_bank = (xga->ap_idx & 0x3f) << 16;
xga->read_bank = xga->write_bank;
if (xga->base_addr_1mb) {
if (xga->aperture_cntl) {
xga->write_bank = (xga->ap_idx & 0x3f) << 16;
xga->read_bank = xga->write_bank;
} else {
xga->write_bank = (xga->ap_idx & 0x30) << 16;
xga->read_bank = xga->write_bank;
}
} else {
xga->write_bank = (xga->ap_idx & 0x3f) << 16;
xga->read_bank = xga->write_bank;
}
}
break;
case 9:
@@ -1017,7 +1030,7 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
switch (xga->accel.px_map_format[map] & 7) {
case 0: /*1-bit*/
addr += (y * width >> 3);
addr += (y * (width >> 3));
addr += (x >> 3);
if (!skip) {
READ(addr, byte);
@@ -2343,8 +2356,9 @@ xga_render_overscan_right(xga_t *xga, svga_t *svga)
}
static void
xga_render_8bpp(xga_t *xga, svga_t *svga)
xga_render_8bpp(svga_t *svga)
{
xga_t *xga = &svga->xga;
uint32_t *p;
uint32_t dat;
@@ -2360,16 +2374,16 @@ xga_render_8bpp(xga_t *xga, svga_t *svga)
for (int x = 0; x <= xga->h_disp; x += 8) {
dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]);
p[0] = svga->pallook[dat & 0xff];
p[1] = svga->pallook[(dat >> 8) & 0xff];
p[2] = svga->pallook[(dat >> 16) & 0xff];
p[3] = svga->pallook[(dat >> 24) & 0xff];
p[0] = xga->pallook[dat & 0xff];
p[1] = xga->pallook[(dat >> 8) & 0xff];
p[2] = xga->pallook[(dat >> 16) & 0xff];
p[3] = xga->pallook[(dat >> 24) & 0xff];
dat = *(uint32_t *) (&xga->vram[(xga->ma + 4) & xga->vram_mask]);
p[4] = svga->pallook[dat & 0xff];
p[5] = svga->pallook[(dat >> 8) & 0xff];
p[6] = svga->pallook[(dat >> 16) & 0xff];
p[7] = svga->pallook[(dat >> 24) & 0xff];
p[4] = xga->pallook[dat & 0xff];
p[5] = xga->pallook[(dat >> 8) & 0xff];
p[6] = xga->pallook[(dat >> 16) & 0xff];
p[7] = xga->pallook[(dat >> 24) & 0xff];
xga->ma += 8;
p += 8;
@@ -2379,8 +2393,9 @@ xga_render_8bpp(xga_t *xga, svga_t *svga)
}
static void
xga_render_16bpp(xga_t *xga, svga_t *svga)
xga_render_16bpp(svga_t *svga)
{
xga_t *xga = &svga->xga;
int x;
uint32_t *p;
uint32_t dat;
@@ -2449,7 +2464,7 @@ static void
xga_writew(uint32_t addr, uint16_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
const xga_t *xga = &svga->xga;
xga_t *xga = &svga->xga;
if (!xga->on) {
svga_writew(addr, val, svga);
@@ -2464,7 +2479,7 @@ static void
xga_writel(uint32_t addr, uint32_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
const xga_t *xga = &svga->xga;
xga_t *xga = &svga->xga;
if (!xga->on) {
svga_writel(addr, val, svga);
@@ -2481,11 +2496,13 @@ static uint8_t
xga_read(uint32_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
const xga_t *xga = &svga->xga;
xga_t *xga = &svga->xga;
uint8_t ret = 0xff;
if (!xga->on)
return svga_read(addr, svga);
if (!xga->on) {
ret = svga_read(addr, svga);
return ret;
}
addr &= xga->banked_mask;
addr += xga->read_bank;
@@ -2509,11 +2526,13 @@ static uint16_t
xga_readw(uint32_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
const xga_t *xga = &svga->xga;
xga_t *xga = &svga->xga;
uint16_t ret = 0xffff;
if (!xga->on)
return svga_readw(addr, svga);
if (!xga->on) {
ret = svga_readw(addr, svga);
return ret;
}
ret = xga_read(addr, svga);
ret |= (xga_read(addr + 1, svga) << 8);
@@ -2525,11 +2544,13 @@ static uint32_t
xga_readl(uint32_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
const xga_t *xga = &svga->xga;
xga_t *xga = &svga->xga;
uint32_t ret = 0xffffffff;
if (!xga->on)
return svga_readl(addr, svga);
if (!xga->on) {
ret = svga_readl(addr, svga);
return ret;
}
ret = xga_read(addr, svga);
ret |= (xga_read(addr + 1, svga) << 8);
@@ -2555,7 +2576,7 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv)
if (addr >= xga->vram_size)
return;
cycles -= video_timing_write_b;
cycles -= svga->monitor->mon_video_timing_write_b;
if (xga->linear_endian_reverse) {
if ((xga->access_mode & 7) == 4) {
@@ -2618,7 +2639,7 @@ xga_read_linear(uint32_t addr, void *priv)
if (addr >= xga->vram_size)
return ret;
cycles -= video_timing_read_b;
cycles -= svga->monitor->mon_video_timing_read_b;
if (xga->linear_endian_reverse) {
if ((xga->access_mode & 7) == 4) {
@@ -2672,14 +2693,14 @@ xga_do_render(svga_t *svga)
{
xga_t *xga = &svga->xga;
xga_log("DISPCNTL = %d, vga = %d.\n", xga->disp_cntl_2 & 7, vga_on);
switch (xga->disp_cntl_2 & 7) {
case 3:
xga_render_8bpp(xga, svga);
xga_render_8bpp(svga);
break;
case 4:
xga_render_16bpp(xga, svga);
xga_render_16bpp(svga);
break;
default:
break;
}
@@ -2725,7 +2746,7 @@ xga_poll(xga_t *xga, svga_t *svga)
if (xga->firstline == 2000) {
xga->firstline = xga->displine;
video_wait_for_buffer();
video_wait_for_buffer_monitor(svga->monitor_index);
}
if (xga->hwcursor_on) {
@@ -2869,7 +2890,7 @@ xga_mca_write(int port, uint8_t val, void *priv)
mem_mapping_disable(&xga->bios_rom.mapping);
mem_mapping_disable(&xga->memio_mapping);
xga->on = 0;
vga_on = !xga->on;
vga_on = 1;
xga->linear_endian_reverse = 0;
xga->a5_test = 0;
@@ -2912,8 +2933,10 @@ xga_mca_reset(void *priv)
svga_t *svga = (svga_t *) priv;
xga_t *xga = &svga->xga;
mem_mapping_disable(&xga->bios_rom.mapping);
mem_mapping_disable(&xga->memio_mapping);
xga->on = 0;
vga_on = !xga->on;
vga_on = 1;
xga_mca_write(0x102, 0, svga);
}
@@ -2926,7 +2949,7 @@ xga_reset(void *priv)
mem_mapping_disable(&xga->bios_rom.mapping);
mem_mapping_disable(&xga->memio_mapping);
xga->on = 0;
vga_on = !xga->on;
vga_on = 1;
xga->linear_endian_reverse = 0;
xga->a5_test = 0;
}
@@ -3131,7 +3154,7 @@ xga_init(const device_t *info)
rom = malloc(xga->bios_rom.sz);
memset(rom, 0xff, xga->bios_rom.sz);
(void) !fread(rom, xga->bios_rom.sz, 1, fp);
(void) fread(rom, xga->bios_rom.sz, 1, fp);
(void) fclose(fp);
xga->bios_rom.rom = rom;
@@ -3148,9 +3171,9 @@ xga_init(const device_t *info)
xga->rom_addr = 0;
rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, 0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
} else {
if (!xga_standalone_enabled) {
if (!xga_standalone_enabled)
rom_init(&xga->vga_bios_rom, INMOS_XGA_BIOS_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
} else
else
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa);
xga->pos_regs[2] = 1 | (xga->instance_isa << 1) | xga->ext_mem_addr;
@@ -3170,7 +3193,6 @@ xga_init(const device_t *info)
xga_memio_writeb, xga_memio_writew, xga_memio_writel,
!xga_standalone_enabled ? xga->vga_bios_rom.rom : xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga);
mem_mapping_disable(&xga->video_mapping);
mem_mapping_disable(&xga->linear_mapping);
mem_mapping_disable(&xga->memio_mapping);