Improved emulation of the SiS 496 chip;
The SMC FDC37C665 Super I/O chip's IDE handler is now disabled for the Rise Computer R418 (the real board by passes that chip's IDE and uses the SiS 496B IDE controller so this is correct and not a hack), fixes hard disks disappearing on soft reset.
This commit is contained in:
@@ -31,7 +31,7 @@ static void write_lock(uint8_t val)
|
|||||||
static void ide_handler()
|
static void ide_handler()
|
||||||
{
|
{
|
||||||
uint16_t or_value = 0;
|
uint16_t or_value = 0;
|
||||||
if (romset == ROM_440FX)
|
if ((romset == ROM_440FX) || (romset == ROM_R418))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -50,10 +50,6 @@ static void ide_handler()
|
|||||||
ide_set_side(0, 0x376 | or_value);
|
ide_set_side(0, 0x376 | or_value);
|
||||||
ide_pri_enable_ex();
|
ide_pri_enable_ex();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
pclog("Disabling IDE...\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_com34_addr()
|
static void set_com34_addr()
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ void i430fx_reset(void)
|
|||||||
|
|
||||||
void i430fx_pci_reset(void)
|
void i430fx_pci_reset(void)
|
||||||
{
|
{
|
||||||
i430fx_write(0, 0x59, 0xf, NULL);
|
i430fx_write(0, 0x59, 0x00, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void i430fx_init()
|
void i430fx_init()
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ void i430hx_reset(void)
|
|||||||
|
|
||||||
void i430hx_pci_reset(void)
|
void i430hx_pci_reset(void)
|
||||||
{
|
{
|
||||||
i430hx_write(0, 0x59, 0xf, NULL);
|
i430hx_write(0, 0x59, 0x00, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void i430hx_init()
|
void i430hx_init()
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ void i430lx_reset(void)
|
|||||||
|
|
||||||
void i430lx_pci_reset(void)
|
void i430lx_pci_reset(void)
|
||||||
{
|
{
|
||||||
i430lx_write(0, 0x59, 0xf, NULL);
|
i430lx_write(0, 0x59, 0x00, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void i430lx_init()
|
void i430lx_init()
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ void i430nx_reset(void)
|
|||||||
|
|
||||||
void i430nx_pci_reset(void)
|
void i430nx_pci_reset(void)
|
||||||
{
|
{
|
||||||
i430nx_write(0, 0x59, 0xf, NULL);
|
i430nx_write(0, 0x59, 0x00, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void i430nx_init()
|
void i430nx_init()
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ void i430vx_reset(void)
|
|||||||
|
|
||||||
void i430vx_pci_reset(void)
|
void i430vx_pci_reset(void)
|
||||||
{
|
{
|
||||||
i430vx_write(0, 0x59, 0xf, NULL);
|
i430vx_write(0, 0x59, 0x00, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void i430vx_init()
|
void i430vx_init()
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ void i440fx_reset(void)
|
|||||||
|
|
||||||
void i440fx_pci_reset(void)
|
void i440fx_pci_reset(void)
|
||||||
{
|
{
|
||||||
i440fx_write(0, 0x59, 0xf, NULL);
|
i440fx_write(0, 0x59, 0x00, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void i440fx_init()
|
void i440fx_init()
|
||||||
|
|||||||
@@ -581,7 +581,8 @@ void at_sis496_init()
|
|||||||
at_ide_init();
|
at_ide_init();
|
||||||
memregs_init();
|
memregs_init();
|
||||||
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
||||||
device_add(&sis496_device);
|
sis496_init();
|
||||||
|
trc_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void at_r418_init()
|
void at_r418_init()
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ void trc_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
trc_reg = val & 0xfd;
|
trc_reg = val & 0xfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void trc_init()
|
void trc_init(void)
|
||||||
{
|
{
|
||||||
trc_reg = 0;
|
trc_reg = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/* Copyright holders: Tenshi
|
/* Copyright holders: Tenshi
|
||||||
see COPYING for more details
|
see COPYING for more details
|
||||||
*/
|
*/
|
||||||
|
void trc_init(void);
|
||||||
void sio_init(int card);
|
void sio_init(int card);
|
||||||
|
|||||||
89
src/sis496.c
89
src/sis496.c
@@ -15,16 +15,18 @@ typedef struct sis496_t
|
|||||||
uint8_t pci_conf[256];
|
uint8_t pci_conf[256];
|
||||||
} sis496_t;
|
} sis496_t;
|
||||||
|
|
||||||
void sis496_recalcmapping(sis496_t *sis496)
|
sis496_t sis496;
|
||||||
|
|
||||||
|
void sis496_recalcmapping(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
for (c = 0; c < 8; c++)
|
for (c = 0; c < 8; c++)
|
||||||
{
|
{
|
||||||
uint32_t base = 0xc0000 + (c << 15);
|
uint32_t base = 0xc0000 + (c << 15);
|
||||||
if (sis496->pci_conf[0x44] & (1 << c))
|
if (sis496.pci_conf[0x44] & (1 << c))
|
||||||
{
|
{
|
||||||
switch (sis496->pci_conf[0x45] & 3)
|
switch (sis496.pci_conf[0x45] & 3)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||||
@@ -45,68 +47,77 @@ void sis496_recalcmapping(sis496_t *sis496)
|
|||||||
}
|
}
|
||||||
|
|
||||||
flushmmucache();
|
flushmmucache();
|
||||||
shadowbios = (sis496->pci_conf[0x44] & 0xf0);
|
shadowbios = (sis496.pci_conf[0x44] & 0xf0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sis496_write(int func, int addr, uint8_t val, void *p)
|
void sis496_write(int func, int addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
sis496_t *sis496 = (sis496_t *)p;
|
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x44: /*Shadow configure*/
|
case 0x44: /*Shadow configure*/
|
||||||
if ((sis496->pci_conf[0x44] & val) ^ 0xf0)
|
if ((sis496.pci_conf[0x44] & val) ^ 0xf0)
|
||||||
{
|
{
|
||||||
sis496->pci_conf[0x44] = val;
|
sis496.pci_conf[0x44] = val;
|
||||||
sis496_recalcmapping(sis496);
|
sis496_recalcmapping();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x45: /*Shadow configure*/
|
case 0x45: /*Shadow configure*/
|
||||||
if ((sis496->pci_conf[0x45] & val) ^ 0x01)
|
if ((sis496.pci_conf[0x45] & val) ^ 0x01)
|
||||||
{
|
{
|
||||||
sis496->pci_conf[0x45] = val;
|
sis496.pci_conf[0x45] = val;
|
||||||
sis496_recalcmapping(sis496);
|
sis496_recalcmapping();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((addr >= 4 && addr < 8) || addr >= 0x40)
|
if ((addr >= 4 && addr < 8) || addr >= 0x40)
|
||||||
sis496->pci_conf[addr] = val;
|
sis496.pci_conf[addr] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t sis496_read(int func, int addr, void *p)
|
uint8_t sis496_read(int func, int addr, void *p)
|
||||||
{
|
{
|
||||||
sis496_t *sis496 = (sis496_t *)p;
|
return sis496.pci_conf[addr];
|
||||||
|
|
||||||
return sis496->pci_conf[addr];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *sis496_init()
|
void sis496_reset(void)
|
||||||
{
|
{
|
||||||
sis496_t *sis496 = malloc(sizeof(sis496_t));
|
memset(&sis496, 0, sizeof(sis496_t));
|
||||||
memset(sis496, 0, sizeof(sis496_t));
|
|
||||||
|
|
||||||
pci_add_specific(5, sis496_read, sis496_write, sis496);
|
sis496.pci_conf[0x00] = 0x39; /*SiS*/
|
||||||
|
sis496.pci_conf[0x01] = 0x10;
|
||||||
|
sis496.pci_conf[0x02] = 0x96; /*496/497*/
|
||||||
|
sis496.pci_conf[0x03] = 0x04;
|
||||||
|
|
||||||
sis496->pci_conf[0x00] = 0x39; /*SiS*/
|
sis496.pci_conf[0x04] = 7;
|
||||||
sis496->pci_conf[0x01] = 0x10;
|
sis496.pci_conf[0x05] = 0;
|
||||||
sis496->pci_conf[0x02] = 0x96; /*496/497*/
|
|
||||||
sis496->pci_conf[0x03] = 0x04;
|
|
||||||
|
|
||||||
sis496->pci_conf[0x04] = 7;
|
sis496.pci_conf[0x06] = 0x80;
|
||||||
sis496->pci_conf[0x05] = 0;
|
sis496.pci_conf[0x07] = 0x02;
|
||||||
|
|
||||||
sis496->pci_conf[0x06] = 0x80;
|
sis496.pci_conf[0x08] = 2; /*Device revision*/
|
||||||
sis496->pci_conf[0x07] = 0x02;
|
|
||||||
|
|
||||||
sis496->pci_conf[0x08] = 2; /*Device revision*/
|
sis496.pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/
|
||||||
|
sis496.pci_conf[0x0a] = 0x00;
|
||||||
|
sis496.pci_conf[0x0b] = 0x06;
|
||||||
|
|
||||||
sis496->pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/
|
sis496.pci_conf[0x0e] = 0x00; /*Single function device*/
|
||||||
sis496->pci_conf[0x0a] = 0x00;
|
}
|
||||||
sis496->pci_conf[0x0b] = 0x06;
|
|
||||||
|
|
||||||
sis496->pci_conf[0x0e] = 0x00; /*Single function device*/
|
void sis496_pci_reset(void)
|
||||||
|
{
|
||||||
|
uint8_t val = 0;
|
||||||
|
|
||||||
return sis496;
|
val = sis496_read(0, 0x44, NULL); /* Read current value of 0x44. */
|
||||||
|
sis496_write(0, 0x44, val & 0xf, NULL); /* Turn off shadow BIOS but keep the lower 4 bits. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void sis496_init(void)
|
||||||
|
{
|
||||||
|
pci_add_specific(5, sis496_read, sis496_write, NULL);
|
||||||
|
|
||||||
|
sis496_reset();
|
||||||
|
|
||||||
|
pci_reset_handler.pci_master_reset = sis496_pci_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sis496_close(void *p)
|
void sis496_close(void *p)
|
||||||
@@ -115,15 +126,3 @@ void sis496_close(void *p)
|
|||||||
|
|
||||||
free(sis496);
|
free(sis496);
|
||||||
}
|
}
|
||||||
|
|
||||||
device_t sis496_device =
|
|
||||||
{
|
|
||||||
"SiS 496/497",
|
|
||||||
0,
|
|
||||||
sis496_init,
|
|
||||||
sis496_close,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright holders: Sarah Walker
|
/* Copyright holders: Kotori
|
||||||
see COPYING for more details
|
see COPYING for more details
|
||||||
*/
|
*/
|
||||||
extern device_t sis496_device;
|
void sis496_init(void);
|
||||||
|
|||||||
Reference in New Issue
Block a user