MGA updates for the vram detection and stuff.

1. The Debian issue mystery lies around chain2_read/write being required when the LFB mapping is enabled too when MGA modes are set without blitting, however, when it is blitting, immediately tell chain2 to not interfere with the mapping. Fixes Debian once and for all as well as VRAM detection correctly while keeping existing compatibility fine.
2. Undev branch the G100 per above. (Revert if more bugs are revealed).
3. An AND with 0 is not tolerable as it nulls the LFB, fixes hang ups with Win2000 using the Millennium II and possibly the G100.
4. the Extended CRTCs now have a call for timing recalculation, fixes mode changes when blitting is going on.
This commit is contained in:
TC1995
2024-02-15 23:10:05 +01:00
parent 0b8f02d702
commit e9f0af21a0
3 changed files with 96 additions and 69 deletions

View File

@@ -440,9 +440,7 @@ extern const device_t millennium_device;
extern const device_t mystique_device;
extern const device_t mystique_220_device;
extern const device_t millennium_ii_device;
# if defined(DEV_BRANCH) && defined(USE_MGA2)
extern const device_t productiva_g100_device;
# endif
/* Oak OTI-0x7 */
extern const device_t oti037c_device;

View File

@@ -815,6 +815,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv)
}
}
}
svga_recalctimings(svga);
break;
default:
@@ -2814,18 +2815,12 @@ mystique_readb_linear(uint32_t addr, void *priv)
cycles -= svga->monitor->mon_video_timing_read_b;
if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) {
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
return 0xff;
return svga->vram[addr & svga->vram_mask];
} else if (svga->chain4 && !svga->force_old_addr) {
addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
} else if (svga->chain2_read) {
if (!svga->fast) {
if (svga->chain2_read) {
addr &= ~1;
addr <<= 2;
}
}
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
@@ -2870,14 +2865,12 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv)
cycles -= svga->monitor->mon_video_timing_write_b;
if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) {
addr &= ~3;
} else if (svga->chain4 && (svga->writemode < 4)) {
addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
} else if (svga->chain2_write) {
if (!svga->fast) {
if (svga->chain2_write) {
addr &= ~1;
addr <<= 2;
}
}
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
@@ -5835,9 +5828,14 @@ blit_iload_highv(mystique_t *mystique)
static void
mystique_start_blit(mystique_t *mystique)
{
svga_t *svga = &mystique->svga;
uint64_t start_time = plat_timer_read();
uint64_t end_time;
/*Make sure we don't get any artifacts.*/
svga->chain2_write = 0;
svga->chain2_read = 0;
mystique->dwgreg.dwgctrl_running = mystique->dwgreg.dwgctrl;
mystique->maccess_running = mystique->maccess;
@@ -5969,15 +5967,6 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
mystique_t *mystique = (mystique_t *) priv;
uint8_t ret = 0x00;
if (mystique->type >= MGA_1164SG)
{
/* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */
if (addr >= 0x10 && addr <= 0x13)
addr += 0x4;
else if (addr >= 0x14 && addr <= 0x17)
addr -= 0x4;
}
if ((addr >= 0x30) && (addr <= 0x33) && !(mystique->pci_regs[0x43] & 0x40))
ret = 0x00;
else
@@ -6032,24 +6021,45 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
case 0x10:
ret = 0x00;
break; /*Control aperture*/
break; /*Control aperture for Millennium and Mystique, LFB for Mystique 220 and later*/
case 0x11:
if (mystique->type >= MGA_1164SG)
ret = 0x00;
else
ret = (mystique->ctrl_base >> 8) & 0xc0;
break;
case 0x12:
if (mystique->type >= MGA_1164SG)
ret = (mystique->type >= MGA_2164W) ? 0x00 : ((mystique->lfb_base >> 16) & 0x80);
else
ret = mystique->ctrl_base >> 16;
break;
case 0x13:
if (mystique->type >= MGA_1164SG)
ret = mystique->lfb_base >> 24;
else
ret = mystique->ctrl_base >> 24;
break;
case 0x14:
ret = 0x00;
break; /*Linear frame buffer*/
break; /*LFB for Millennium and Mystique, Control aperture for Mystique 220 and later*/
case 0x15:
if (mystique->type >= MGA_1164SG)
ret = (mystique->ctrl_base >> 8) & 0xc0;
else
ret = 0x00;
break;
case 0x16:
ret = (mystique->type >= MGA_2164W) ? 0x00 : ((mystique->lfb_base >> 16) & 0x80);
if (mystique->type >= MGA_1164SG)
ret = mystique->ctrl_base >> 16;
else
ret = (mystique->lfb_base >> 16) & 0x80;
break;
case 0x17:
if (mystique->type >= MGA_1164SG)
ret = mystique->ctrl_base >> 24;
else
ret = mystique->lfb_base >> 24;
break;
@@ -6090,7 +6100,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
break;
case 0x34:
ret = mystique->type == MGA_G100 ? 0xdc : 0x00;
ret = (mystique->type == MGA_G100) ? 0xdc : 0x00;
break;
case 0x3c:
@@ -6193,15 +6203,6 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
{
mystique_t *mystique = (mystique_t *) priv;
if (mystique->type >= MGA_1164SG)
{
/* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */
if (addr >= 0x10 && addr <= 0x13)
addr += 0x4;
else if (addr >= 0x14 && addr <= 0x17)
addr -= 0x4;
}
switch (addr) {
case PCI_REG_COMMAND:
mystique->pci_regs[PCI_REG_COMMAND] = (val & 0x27) | 0x80;
@@ -6217,27 +6218,61 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
break;
case 0x11:
if (mystique->type >= MGA_1164SG)
break;
else {
mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8);
mystique_recalc_mapping(mystique);
}
break;
case 0x12:
mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16);
mystique_recalc_mapping(mystique);
break;
case 0x13:
mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24);
mystique_recalc_mapping(mystique);
break;
case 0x16:
if (mystique->type >= MGA_1164SG) {
if (mystique->type >= MGA_2164W)
break;
mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16);
mystique_recalc_mapping(mystique);
} else {
mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16);
mystique_recalc_mapping(mystique);
}
break;
case 0x13:
if (mystique->type >= MGA_1164SG) {
if (mystique->type >= MGA_2164W)
mystique->lfb_base = val << 24;
else
mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24);
mystique_recalc_mapping(mystique);
} else {
mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24);
mystique_recalc_mapping(mystique);
}
break;
case 0x15:
if (mystique->type >= MGA_1164SG) {
mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8);
mystique_recalc_mapping(mystique);
}
break;
case 0x16:
if (mystique->type >= MGA_1164SG) {
mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16);
mystique_recalc_mapping(mystique);
} else {
mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16);
mystique_recalc_mapping(mystique);
}
break;
case 0x17:
mystique->lfb_base = (mystique->lfb_base & ((mystique->type >= MGA_2164W) ? 0x00000000 : 0x00800000)) | (val << 24);
if (mystique->type >= MGA_1164SG) {
mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24);
mystique_recalc_mapping(mystique);
} else {
mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24);
mystique_recalc_mapping(mystique);
}
break;
case 0x1a:
@@ -6258,8 +6293,8 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
if (addr == 0x30)
mystique->pci_regs[addr] &= 1;
if (mystique->pci_regs[0x30] & 0x01) {
uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24);
mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000);
uint32_t biosaddr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24);
mem_mapping_set_addr(&mystique->bios_rom.mapping, biosaddr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000);
} else
mem_mapping_disable(&mystique->bios_rom.mapping);
return;
@@ -6282,8 +6317,8 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
if (addr == 0x43) {
if (val & 0x40) {
if (mystique->pci_regs[0x30] & 0x01) {
uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24);
mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000);
uint32_t biosaddr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24);
mem_mapping_set_addr(&mystique->bios_rom.mapping, biosaddr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000);
} else
mem_mapping_disable(&mystique->bios_rom.mapping);
} else
@@ -6557,13 +6592,11 @@ millennium_ii_available(void)
return rom_present(ROM_MILLENNIUM_II);
}
#if defined(DEV_BRANCH) && defined(USE_MGA2)
static int
matrox_g100_available(void)
{
return rom_present(ROM_G100);
}
#endif
static void
mystique_speed_changed(void *priv)
@@ -6701,7 +6734,6 @@ const device_t millennium_ii_device = {
.config = millennium_ii_config
};
#if defined(DEV_BRANCH) && defined(USE_MGA2)
const device_t productiva_g100_device = {
.name = "Matrox Productiva G100",
.internal_name = "productiva_g100",
@@ -6715,4 +6747,3 @@ const device_t productiva_g100_device = {
.force_redraw = mystique_force_redraw,
.config = millennium_ii_config
};
#endif

View File

@@ -260,9 +260,7 @@ video_cards[] = {
{ &s3_virge_357_agp_device },
{ &s3_diamond_stealth_4000_agp_device },
{ &s3_trio3d2x_agp_device },
#if defined(DEV_BRANCH) && defined(USE_MGA2)
{ &productiva_g100_device, VIDEO_FLAG_TYPE_SPECIAL },
#endif
{ &velocity_100_agp_device },
{ &velocity_200_agp_device },
{ &voodoo_3_1000_agp_device },