- Some work on the Voodoo Graphics emulation

- Store the Voodoo model in structure bx_voodoo_t.
  - The PCI initEnable register of the Voodoo2 model has a read-only secondary
    revision ID in bits 12..15. Now the Voodoo2 is correctly detected by the
    Windows driver, but display is not yet working (blank screen).
  - Reset now disables VGA override.
- PCI: Moved PCI device base class methods to the end of file devices.cc and
  re-define LOG_THIS to use the correct log module and prefix.
This commit is contained in:
Volker Ruppert 2017-04-28 18:45:45 +00:00
parent 915746a1fd
commit f4bfb6353f
3 changed files with 117 additions and 99 deletions

View File

@ -1167,101 +1167,6 @@ void bx_devices_c::mouse_motion(int delta_x, int delta_y, int delta_z, unsigned
#if BX_SUPPORT_PCI
// generic PCI support
void bx_pci_device_c::init_pci_conf(Bit16u vid, Bit16u did, Bit8u rev, Bit32u classc, Bit8u headt)
{
memset(pci_conf, 0, 256);
pci_conf[0x00] = (Bit8u)(vid & 0xff);
pci_conf[0x01] = (Bit8u)(vid >> 8);
pci_conf[0x02] = (Bit8u)(did & 0xff);
pci_conf[0x03] = (Bit8u)(did >> 8);
pci_conf[0x08] = rev;
pci_conf[0x09] = (Bit8u)(classc & 0xff);
pci_conf[0x0a] = (Bit8u)((classc >> 8) & 0xff);
pci_conf[0x0b] = (Bit8u)((classc >> 16) & 0xff);
pci_conf[0x0e] = headt;
}
void bx_pci_device_c::register_pci_state(bx_list_c *list)
{
new bx_shadow_data_c(list, "pci_conf", pci_conf, 256, 1);
}
void bx_pci_device_c::load_pci_rom(const char *path)
{
struct stat stat_buf;
int fd, ret;
unsigned long size, max_size;
if (*path == '\0') {
BX_PANIC(("PCI ROM image undefined"));
return;
}
// read in PCI ROM image file
fd = open(path, O_RDONLY
#ifdef O_BINARY
| O_BINARY
#endif
);
if (fd < 0) {
BX_PANIC(("couldn't open PCI ROM image file '%s'.", path));
return;
}
ret = fstat(fd, &stat_buf);
if (ret) {
close(fd);
BX_PANIC(("couldn't stat PCI ROM image file '%s'.", path));
return;
}
max_size = 0x20000;
size = (unsigned long)stat_buf.st_size;
if (size > max_size) {
close(fd);
BX_PANIC(("PCI ROM image too large"));
return;
}
if ((size % 512) != 0) {
close(fd);
BX_PANIC(("PCI ROM image size must be multiple of 512 (size = %ld)", size));
return;
}
while ((size - 1) < max_size) {
max_size >>= 1;
}
pci_rom_size = (max_size << 1);
pci_rom = new Bit8u[pci_rom_size];
while (size > 0) {
ret = read(fd, (bx_ptr_t) pci_rom, size);
if (ret <= 0) {
BX_PANIC(("read failed on PCI ROM image: '%s'", path));
}
size -= ret;
}
close(fd);
BX_INFO(("loaded PCI ROM '%s' (size=%u / PCI=%uk)", path, (unsigned) stat_buf.st_size, pci_rom_size >> 10));
}
// pci configuration space read callback handler
Bit32u bx_pci_device_c::pci_read_handler(Bit8u address, unsigned io_len)
{
Bit32u value = 0;
for (unsigned i=0; i<io_len; i++) {
value |= (pci_conf[address+i] << (i*8));
}
if (io_len == 1)
BX_DEBUG(("read PCI register 0x%02X value 0x%02X (len=1)", address, value));
else if (io_len == 2)
BX_DEBUG(("read PCI register 0x%02X value 0x%04X (len=2)", address, value));
else if (io_len == 4)
BX_DEBUG(("read PCI register 0x%02X value 0x%08X (len=4)", address, value));
return value;
}
bx_bool bx_devices_c::register_pci_handlers(bx_pci_device_c *dev,
Bit8u *devfunc, const char *name,
const char *descr)
@ -1387,4 +1292,103 @@ bx_bool bx_devices_c::pci_set_base_io(void *this_ptr, bx_read_handler_t f1, bx_w
}
return 0;
}
// PCI device base class (common methods)
#undef LOG_THIS
#define LOG_THIS
void bx_pci_device_c::init_pci_conf(Bit16u vid, Bit16u did, Bit8u rev, Bit32u classc, Bit8u headt)
{
memset(pci_conf, 0, 256);
pci_conf[0x00] = (Bit8u)(vid & 0xff);
pci_conf[0x01] = (Bit8u)(vid >> 8);
pci_conf[0x02] = (Bit8u)(did & 0xff);
pci_conf[0x03] = (Bit8u)(did >> 8);
pci_conf[0x08] = rev;
pci_conf[0x09] = (Bit8u)(classc & 0xff);
pci_conf[0x0a] = (Bit8u)((classc >> 8) & 0xff);
pci_conf[0x0b] = (Bit8u)((classc >> 16) & 0xff);
pci_conf[0x0e] = headt;
}
void bx_pci_device_c::register_pci_state(bx_list_c *list)
{
new bx_shadow_data_c(list, "pci_conf", pci_conf, 256, 1);
}
void bx_pci_device_c::load_pci_rom(const char *path)
{
struct stat stat_buf;
int fd, ret;
unsigned long size, max_size;
if (*path == '\0') {
BX_PANIC(("PCI ROM image undefined"));
return;
}
// read in PCI ROM image file
fd = open(path, O_RDONLY
#ifdef O_BINARY
| O_BINARY
#endif
);
if (fd < 0) {
BX_PANIC(("couldn't open PCI ROM image file '%s'.", path));
return;
}
ret = fstat(fd, &stat_buf);
if (ret) {
close(fd);
BX_PANIC(("couldn't stat PCI ROM image file '%s'.", path));
return;
}
max_size = 0x20000;
size = (unsigned long)stat_buf.st_size;
if (size > max_size) {
close(fd);
BX_PANIC(("PCI ROM image too large"));
return;
}
if ((size % 512) != 0) {
close(fd);
BX_PANIC(("PCI ROM image size must be multiple of 512 (size = %ld)", size));
return;
}
while ((size - 1) < max_size) {
max_size >>= 1;
}
pci_rom_size = (max_size << 1);
pci_rom = new Bit8u[pci_rom_size];
while (size > 0) {
ret = read(fd, (bx_ptr_t) pci_rom, size);
if (ret <= 0) {
BX_PANIC(("read failed on PCI ROM image: '%s'", path));
}
size -= ret;
}
close(fd);
BX_INFO(("loaded PCI ROM '%s' (size=%u / PCI=%uk)", path, (unsigned) stat_buf.st_size, pci_rom_size >> 10));
}
// pci configuration space read callback handler
Bit32u bx_pci_device_c::pci_read_handler(Bit8u address, unsigned io_len)
{
Bit32u value = 0;
for (unsigned i=0; i<io_len; i++) {
value |= (pci_conf[address+i] << (i*8));
}
if (io_len == 1)
BX_DEBUG(("read PCI register 0x%02X value 0x%02X (len=1)", address, value));
else if (io_len == 2)
BX_DEBUG(("read PCI register 0x%02X value 0x%04X (len=2)", address, value));
else if (io_len == 4)
BX_DEBUG(("read PCI register 0x%02X value 0x%08X (len=4)", address, value));
return value;
}
#endif

View File

@ -200,8 +200,8 @@ void bx_voodoo_c::init(void)
BX_VOODOO_THIS s.vdraw.screen_update_pending = 0;
v = new voodoo_state;
Bit8u model = (Bit8u)SIM->get_param_enum("model", base)->get();
if (model == VOODOO_2) {
BX_VOODOO_THIS s.model = (Bit8u)SIM->get_param_enum("model", base)->get();
if (BX_VOODOO_THIS s.model == VOODOO_2) {
init_pci_conf(0x121a, 0x0002, 0x02, 0x038000, 0x00);
BX_VOODOO_THIS pci_conf[0x10] = 0x08;
} else {
@ -210,7 +210,7 @@ void bx_voodoo_c::init(void)
BX_VOODOO_THIS pci_conf[0x3d] = BX_PCI_INTA;
BX_VOODOO_THIS pci_base_address[0] = 0;
voodoo_init(model);
voodoo_init(BX_VOODOO_THIS s.model);
BX_INFO(("3dfx Voodoo Graphics adapter (model=%s) initialized",
SIM->get_param_enum("model", base)->get_selected()));
@ -244,7 +244,16 @@ void bx_voodoo_c::reset(unsigned type)
for (i = 0; i < sizeof(reset_vals) / sizeof(*reset_vals); ++i) {
BX_VOODOO_THIS pci_conf[reset_vals[i].addr] = reset_vals[i].val;
}
v->pci.init_enable = 0x00;
if (BX_VOODOO_THIS s.model == VOODOO_2) {
BX_VOODOO_THIS pci_conf[0x41] = 0x50;
v->pci.init_enable = 0x5000;
} else {
v->pci.init_enable = 0x0000;
}
if ((!BX_VOODOO_THIS s.vdraw.clock_enabled || !BX_VOODOO_THIS s.vdraw.output_on) && BX_VOODOO_THIS s.vdraw.override_on) {
mode_change_timer_handler(NULL);
}
// Deassert IRQ
set_irq_level(0);
@ -646,6 +655,10 @@ void bx_voodoo_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len
case 0x41:
case 0x42:
case 0x43:
if (((address+i) == 0x41) && (BX_VOODOO_THIS s.model == VOODOO_2)) {
value8 &= 0x0f;
value8 |= 0x50;
}
v->pci.init_enable &= ~(0xff << (i*8));
v->pci.init_enable |= (value8 << (i*8));
break;

View File

@ -25,6 +25,7 @@
#define BX_VOODOO_THIS_PTR theVoodooDevice
typedef struct {
Bit8u model;
struct {
Bit32u width;
Bit32u height;