Fixed Cirrus Logic MMIO mapping. Fixes hang when opening Windows 9x DOS box.
This commit is contained in:
parent
cc60e2b2c5
commit
e349e4b14e
1 changed files with 194 additions and 131 deletions
|
|
@ -60,10 +60,16 @@ typedef struct gd5429_t
|
||||||
int card;
|
int card;
|
||||||
|
|
||||||
uint32_t lfb_base;
|
uint32_t lfb_base;
|
||||||
|
|
||||||
|
int mmio_vram_overlap;
|
||||||
} gd5429_t;
|
} gd5429_t;
|
||||||
|
|
||||||
void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p);
|
static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p);
|
||||||
uint8_t gd5429_mmio_read(uint32_t addr, void *p);
|
static void gd5429_mmio_writew(uint32_t addr, uint16_t val, void *p);
|
||||||
|
static void gd5429_mmio_writel(uint32_t addr, uint32_t val, void *p);
|
||||||
|
static uint8_t gd5429_mmio_read(uint32_t addr, void *p);
|
||||||
|
static uint16_t gd5429_mmio_readw(uint32_t addr, void *p);
|
||||||
|
static uint32_t gd5429_mmio_readl(uint32_t addr, void *p);
|
||||||
|
|
||||||
void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p);
|
void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p);
|
||||||
void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p);
|
void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p);
|
||||||
|
|
@ -383,6 +389,8 @@ void gd5429_recalc_mapping(gd5429_t *gd5429)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gd5429->mmio_vram_overlap = 0;
|
||||||
|
|
||||||
// pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04);
|
// pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04);
|
||||||
if (!(svga->seqregs[7] & 0xf0))
|
if (!(svga->seqregs[7] & 0xf0))
|
||||||
{
|
{
|
||||||
|
|
@ -391,26 +399,26 @@ void gd5429_recalc_mapping(gd5429_t *gd5429)
|
||||||
{
|
{
|
||||||
case 0x0: /*128k at A0000*/
|
case 0x0: /*128k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
mem_mapping_disable(&gd5429->mmio_mapping);
|
|
||||||
svga->banked_mask = 0xffff;
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x4: /*64k at A0000*/
|
case 0x4: /*64k at A0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||||
if (svga->seqregs[0x17] & 0x04)
|
|
||||||
mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100);
|
|
||||||
svga->banked_mask = 0xffff;
|
svga->banked_mask = 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x8: /*32k at B0000*/
|
case 0x8: /*32k at B0000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
||||||
mem_mapping_disable(&gd5429->mmio_mapping);
|
|
||||||
svga->banked_mask = 0x7fff;
|
svga->banked_mask = 0x7fff;
|
||||||
break;
|
break;
|
||||||
case 0xC: /*32k at B8000*/
|
case 0xC: /*32k at B8000*/
|
||||||
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
||||||
mem_mapping_disable(&gd5429->mmio_mapping);
|
|
||||||
svga->banked_mask = 0x7fff;
|
svga->banked_mask = 0x7fff;
|
||||||
|
gd5429->mmio_vram_overlap = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (svga->seqregs[0x17] & 0x04)
|
||||||
|
mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100);
|
||||||
|
else
|
||||||
|
mem_mapping_disable(&gd5429->mmio_mapping);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1283,10 +1291,12 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p)
|
static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
gd5429_t *gd5429 = (gd5429_t *)p;
|
gd5429_t *gd5429 = (gd5429_t *)p;
|
||||||
|
|
||||||
|
if ((addr & ~0xff) == 0xb8000)
|
||||||
|
{
|
||||||
// pclog("MMIO write %08X %02X\n", addr, val);
|
// pclog("MMIO write %08X %02X\n", addr, val);
|
||||||
switch (addr & 0xff)
|
switch (addr & 0xff)
|
||||||
{
|
{
|
||||||
|
|
@ -1411,11 +1421,40 @@ void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (gd5429->mmio_vram_overlap)
|
||||||
uint8_t gd5429_mmio_read(uint32_t addr, void *p)
|
gd5429_write(addr, val, gd5429);
|
||||||
|
}
|
||||||
|
static void gd5429_mmio_writew(uint32_t addr, uint16_t val, void *p)
|
||||||
{
|
{
|
||||||
// gd5429_t *gd5429 = (gd5429_t *)p;
|
gd5429_t *gd5429 = (gd5429_t *)p;
|
||||||
|
|
||||||
|
if ((addr & ~0xff) == 0xb8000)
|
||||||
|
{
|
||||||
|
gd5429_mmio_write(addr, val & 0xff, gd5429);
|
||||||
|
gd5429_mmio_write(addr + 1, val >> 8, gd5429);
|
||||||
|
}
|
||||||
|
else if (gd5429->mmio_vram_overlap)
|
||||||
|
gd5429_writew(addr, val, gd5429);
|
||||||
|
}
|
||||||
|
static void gd5429_mmio_writel(uint32_t addr, uint32_t val, void *p)
|
||||||
|
{
|
||||||
|
gd5429_t *gd5429 = (gd5429_t *)p;
|
||||||
|
|
||||||
|
if ((addr & ~0xff) == 0xb8000)
|
||||||
|
{
|
||||||
|
gd5429_mmio_writew(addr, val & 0xffff, gd5429);
|
||||||
|
gd5429_mmio_writew(addr + 2, val >> 16, gd5429);
|
||||||
|
}
|
||||||
|
else if (gd5429->mmio_vram_overlap)
|
||||||
|
gd5429_writel(addr, val, gd5429);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t gd5429_mmio_read(uint32_t addr, void *p)
|
||||||
|
{
|
||||||
|
gd5429_t *gd5429 = (gd5429_t *)p;
|
||||||
|
|
||||||
|
if ((addr & ~0xff) == 0xb8000)
|
||||||
|
{
|
||||||
// pclog("MMIO read %08X\n", addr);
|
// pclog("MMIO read %08X\n", addr);
|
||||||
switch (addr & 0xff)
|
switch (addr & 0xff)
|
||||||
{
|
{
|
||||||
|
|
@ -1424,6 +1463,30 @@ uint8_t gd5429_mmio_read(uint32_t addr, void *p)
|
||||||
}
|
}
|
||||||
return 0xff; /*All other registers read-only*/
|
return 0xff; /*All other registers read-only*/
|
||||||
}
|
}
|
||||||
|
if (gd5429->mmio_vram_overlap)
|
||||||
|
return gd5429_read(addr, gd5429);
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
static uint16_t gd5429_mmio_readw(uint32_t addr, void *p)
|
||||||
|
{
|
||||||
|
gd5429_t *gd5429 = (gd5429_t *)p;
|
||||||
|
|
||||||
|
if ((addr & ~0xff) == 0xb8000)
|
||||||
|
return gd5429_mmio_read(addr, gd5429) | (gd5429_mmio_read(addr+1, gd5429) << 8);
|
||||||
|
if (gd5429->mmio_vram_overlap)
|
||||||
|
return gd5429_readw(addr, gd5429);
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
static uint32_t gd5429_mmio_readl(uint32_t addr, void *p)
|
||||||
|
{
|
||||||
|
gd5429_t *gd5429 = (gd5429_t *)p;
|
||||||
|
|
||||||
|
if ((addr & ~0xff) == 0xb8000)
|
||||||
|
return gd5429_mmio_readw(addr, gd5429) | (gd5429_mmio_readw(addr+2, gd5429) << 16);
|
||||||
|
if (gd5429->mmio_vram_overlap)
|
||||||
|
return gd5429_readl(addr, gd5429);
|
||||||
|
return 0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p)
|
void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p)
|
||||||
{
|
{
|
||||||
|
|
@ -1555,7 +1618,7 @@ static void *cl_init(int type, char *fn)
|
||||||
mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel);
|
mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel);
|
||||||
mem_mapping_set_p(&gd5429->svga.mapping, gd5429);
|
mem_mapping_set_p(&gd5429->svga.mapping, gd5429);
|
||||||
|
|
||||||
mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, NULL, 0, gd5429);
|
mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, gd5429_mmio_readw, gd5429_mmio_readl, gd5429_mmio_write, gd5429_mmio_writew, gd5429_mmio_writel, NULL, 0, gd5429);
|
||||||
mem_mapping_add(&gd5429->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, svga);
|
mem_mapping_add(&gd5429->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, svga);
|
||||||
|
|
||||||
io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
|
io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue