Add AGP GART implementation
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/video.h>
|
||||
|
||||
|
||||
enum
|
||||
@@ -57,6 +58,7 @@ typedef struct
|
||||
uint8_t regs[256], regs_locked[256];
|
||||
int type;
|
||||
smram_t *smram_low, *smram_high;
|
||||
void *agpgart;
|
||||
} i4x0_t;
|
||||
|
||||
|
||||
@@ -208,14 +210,25 @@ i4x0_smram_handler_phase1(i4x0_t *dev)
|
||||
|
||||
|
||||
static void
|
||||
i4x0_mask_bar(uint8_t *regs)
|
||||
i4x0_mask_bar(uint8_t *regs, void *agpgart)
|
||||
{
|
||||
uint32_t bar;
|
||||
|
||||
/* Make sure the aperture's base is aligned to its size. */
|
||||
bar = (regs[0x13] << 24) | (regs[0x12] << 16);
|
||||
bar &= (((uint32_t) regs[0xb4] << 22) | 0xf0000000);
|
||||
regs[0x12] = (bar >> 16) & 0xff;
|
||||
regs[0x13] = (bar >> 24) & 0xff;
|
||||
|
||||
if (!agpgart)
|
||||
return;
|
||||
|
||||
/* Map aperture and GART. */
|
||||
agpgart_set_aperture(agpgart,
|
||||
bar,
|
||||
((uint32_t) (uint8_t) (~regs[0xb4] & 0x3f) + 1) << 22,
|
||||
!!(regs[0x51] & 0x02));
|
||||
agpgart_set_gart(agpgart, (regs[0xb9] << 8) | (regs[0xba] << 16) | (regs[0xbb] << 24));
|
||||
}
|
||||
|
||||
|
||||
@@ -323,7 +336,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
case INTEL_440BX: case INTEL_440ZX:
|
||||
case INTEL_440GX:
|
||||
regs[0x12] = (val & 0xc0);
|
||||
i4x0_mask_bar(regs);
|
||||
i4x0_mask_bar(regs, dev->agpgart);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -333,7 +346,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
case INTEL_440BX: case INTEL_440ZX:
|
||||
case INTEL_440GX:
|
||||
regs[0x13] = val;
|
||||
i4x0_mask_bar(regs);
|
||||
i4x0_mask_bar(regs, dev->agpgart);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -411,15 +424,19 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case INTEL_440LX:
|
||||
regs[0x51] = (regs[0x51] & 0x40) | (val & 0x87);
|
||||
i4x0_mask_bar(regs, dev->agpgart);
|
||||
break;
|
||||
case INTEL_440EX:
|
||||
regs[0x51] = (val & 0x86);
|
||||
i4x0_mask_bar(regs, dev->agpgart);
|
||||
break;
|
||||
case INTEL_440BX: case INTEL_440ZX:
|
||||
regs[0x51] = (regs[0x51] & 0x70) | (val & 0x8f);
|
||||
i4x0_mask_bar(regs, dev->agpgart);
|
||||
break;
|
||||
case INTEL_440GX:
|
||||
regs[0x51] = (regs[0x51] & 0xb0) | (val & 0x4f);
|
||||
i4x0_mask_bar(regs, dev->agpgart);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1074,7 +1091,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
case INTEL_440BX: case INTEL_440ZX:
|
||||
case INTEL_440GX:
|
||||
regs[0xb4] = (val & 0x3f);
|
||||
i4x0_mask_bar(regs);
|
||||
i4x0_mask_bar(regs, dev->agpgart);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1084,6 +1101,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
case INTEL_440BX: case INTEL_440ZX:
|
||||
case INTEL_440GX:
|
||||
regs[0xb9] = (val & 0xf0);
|
||||
i4x0_mask_bar(regs, dev->agpgart);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1094,6 +1112,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
case INTEL_440BX: case INTEL_440ZX:
|
||||
case INTEL_440GX:
|
||||
regs[addr] = val;
|
||||
i4x0_mask_bar(regs, dev->agpgart);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1593,10 +1612,13 @@ static void
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev);
|
||||
|
||||
if ((dev->type >= INTEL_440BX) && !(regs[0x7a] & 0x02))
|
||||
if ((dev->type >= INTEL_440BX) && !(regs[0x7a] & 0x02)) {
|
||||
device_add((dev->type == INTEL_440GX) ? &i440gx_agp_device : &i440bx_agp_device);
|
||||
else if (dev->type >= INTEL_440LX)
|
||||
dev->agpgart = device_add(&agpgart_device);
|
||||
} else if (dev->type >= INTEL_440LX) {
|
||||
device_add(&i440lx_agp_device);
|
||||
dev->agpgart = device_add(&agpgart_device);
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <86box/pci.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/video.h>
|
||||
|
||||
#define VIA_585 0x05851000
|
||||
#define VIA_595 0x05950000
|
||||
@@ -50,6 +51,7 @@ typedef struct via_apollo_t
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
smram_t *smram;
|
||||
void *agpgart;
|
||||
} via_apollo_t;
|
||||
|
||||
|
||||
@@ -86,6 +88,25 @@ apollo_smram_map(via_apollo_t *dev, int smm, uint32_t host_base, uint32_t size,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
apollo_agp_map(via_apollo_t *dev)
|
||||
{
|
||||
/* Make sure the aperture's base is aligned to its size. */
|
||||
dev->pci_conf[0x12] &= dev->pci_conf[0x84] << 4;
|
||||
dev->pci_conf[0x13] &= 0xf0 | (dev->pci_conf[0x84] >> 4);
|
||||
|
||||
if (!dev->agpgart)
|
||||
return;
|
||||
|
||||
/* Map aperture and GART. */
|
||||
agpgart_set_aperture(dev->agpgart,
|
||||
(dev->pci_conf[0x12] << 16) | (dev->pci_conf[0x13] << 24),
|
||||
((uint32_t) (uint8_t) ~dev->pci_conf[0x84] + 1) << 20,
|
||||
!!(dev->pci_conf[0x88] & 0x02));
|
||||
agpgart_set_gart(dev->agpgart, (dev->pci_conf[0x89] << 8) | (dev->pci_conf[0x8a] << 16) | (dev->pci_conf[0x8b] << 24));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
via_apollo_setup(via_apollo_t *dev)
|
||||
{
|
||||
@@ -221,6 +242,8 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
((addr >= 0xad) && (addr < 0xf0)) || ((addr >= 0xf8) && (addr < 0xfc)) ||
|
||||
(addr == 0xfd))
|
||||
return;
|
||||
if (((addr == 0x12) || (addr == 0x13)) && (dev->id < VIA_597))
|
||||
return;
|
||||
if (((addr == 0x78) || (addr >= 0xad)) && (dev->id == VIA_597))
|
||||
return;
|
||||
if (((addr == 0x67) || ((addr >= 0xf0) && (addr < 0xfc))) && (dev->id < VIA_691))
|
||||
@@ -260,9 +283,11 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0x12: /* Graphics Aperture Base */
|
||||
dev->pci_conf[0x12] = (val & 0xf0);
|
||||
apollo_agp_map(dev);
|
||||
break;
|
||||
case 0x13: /* Graphics Aperture Base */
|
||||
dev->pci_conf[0x13] = val;
|
||||
apollo_agp_map(dev);
|
||||
break;
|
||||
|
||||
case 0x50: /* Cache Control 1 */
|
||||
@@ -580,20 +605,23 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf[0x84] = val;
|
||||
else
|
||||
dev->pci_conf[0x84] = (dev->pci_conf[0x84] & ~0xf0) | (val & 0xf0);
|
||||
apollo_agp_map(dev);
|
||||
break;
|
||||
case 0x88:
|
||||
if((dev->id == VIA_693A) || (dev->id == VIA_8601))
|
||||
dev->pci_conf[0x88] = (dev->pci_conf[0x88] & ~0x06) | (val & 0x06);
|
||||
else
|
||||
dev->pci_conf[0x88] = (dev->pci_conf[0x88] & ~0x07) | (val & 0x07);
|
||||
apollo_agp_map(dev);
|
||||
break;
|
||||
case 0x89:
|
||||
dev->pci_conf[0x89] = val & 0xf0;
|
||||
apollo_agp_map(dev);
|
||||
break;
|
||||
case 0x8a:
|
||||
case 0x8b:
|
||||
if((dev->id == VIA_693A) || (dev->id == VIA_8601))
|
||||
dev->pci_conf[addr] = val;
|
||||
else
|
||||
dev->pci_conf[0x89] = (dev->pci_conf[0x89] & ~0xf0) | (val & 0xf0);
|
||||
dev->pci_conf[addr] = val;
|
||||
apollo_agp_map(dev);
|
||||
break;
|
||||
|
||||
case 0xa8:
|
||||
@@ -706,6 +734,9 @@ via_apollo_init(const device_t *info)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->id >= VIA_597)
|
||||
dev->agpgart = device_add(&agpgart_device);
|
||||
|
||||
if ((dev->id >= VIA_694) && (dev->id != VIA_8601))
|
||||
dev->drb_unit = 16;
|
||||
else if (dev->id >= VIA_597)
|
||||
|
||||
Reference in New Issue
Block a user