From 182c737921d961d876382ceb7308a6fd2547b912 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 21 May 2017 19:16:23 +0200 Subject: [PATCH] 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. --- src/fdc37c665.c | 6 +--- src/i430fx.c | 2 +- src/i430hx.c | 2 +- src/i430lx.c | 2 +- src/i430nx.c | 2 +- src/i430vx.c | 2 +- src/i440fx.c | 2 +- src/model.c | 3 +- src/sio.c | 2 +- src/sio.h | 1 + src/sis496.c | 93 ++++++++++++++++++++++++------------------------- src/sis496.h | 4 +-- 12 files changed, 59 insertions(+), 62 deletions(-) diff --git a/src/fdc37c665.c b/src/fdc37c665.c index 1b6904a1a..bbcf157b5 100644 --- a/src/fdc37c665.c +++ b/src/fdc37c665.c @@ -31,7 +31,7 @@ static void write_lock(uint8_t val) static void ide_handler() { uint16_t or_value = 0; - if (romset == ROM_440FX) + if ((romset == ROM_440FX) || (romset == ROM_R418)) { return; } @@ -50,10 +50,6 @@ static void ide_handler() ide_set_side(0, 0x376 | or_value); ide_pri_enable_ex(); } - else - { - pclog("Disabling IDE...\n"); - } } static void set_com34_addr() diff --git a/src/i430fx.c b/src/i430fx.c index 34420f75f..a0324c3ce 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -137,7 +137,7 @@ void i430fx_reset(void) void i430fx_pci_reset(void) { - i430fx_write(0, 0x59, 0xf, NULL); + i430fx_write(0, 0x59, 0x00, NULL); } void i430fx_init() diff --git a/src/i430hx.c b/src/i430hx.c index e13da7606..80c52c02f 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -124,7 +124,7 @@ void i430hx_reset(void) void i430hx_pci_reset(void) { - i430hx_write(0, 0x59, 0xf, NULL); + i430hx_write(0, 0x59, 0x00, NULL); } void i430hx_init() diff --git a/src/i430lx.c b/src/i430lx.c index 624d3f8d0..7494b6c76 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -122,7 +122,7 @@ void i430lx_reset(void) void i430lx_pci_reset(void) { - i430lx_write(0, 0x59, 0xf, NULL); + i430lx_write(0, 0x59, 0x00, NULL); } void i430lx_init() diff --git a/src/i430nx.c b/src/i430nx.c index 9b58d4000..da7b1a5fe 100644 --- a/src/i430nx.c +++ b/src/i430nx.c @@ -120,7 +120,7 @@ void i430nx_reset(void) void i430nx_pci_reset(void) { - i430nx_write(0, 0x59, 0xf, NULL); + i430nx_write(0, 0x59, 0x00, NULL); } void i430nx_init() diff --git a/src/i430vx.c b/src/i430vx.c index ae9aec90e..2eef17d33 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -127,7 +127,7 @@ void i430vx_reset(void) void i430vx_pci_reset(void) { - i430vx_write(0, 0x59, 0xf, NULL); + i430vx_write(0, 0x59, 0x00, NULL); } void i430vx_init() diff --git a/src/i440fx.c b/src/i440fx.c index 3481adfab..9074e2e7a 100644 --- a/src/i440fx.c +++ b/src/i440fx.c @@ -131,7 +131,7 @@ void i440fx_reset(void) void i440fx_pci_reset(void) { - i440fx_write(0, 0x59, 0xf, NULL); + i440fx_write(0, 0x59, 0x00, NULL); } void i440fx_init() diff --git a/src/model.c b/src/model.c index 5be1bab9c..8b36ce114 100644 --- a/src/model.c +++ b/src/model.c @@ -581,7 +581,8 @@ void at_sis496_init() at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); - device_add(&sis496_device); + sis496_init(); + trc_init(); } void at_r418_init() diff --git a/src/sio.c b/src/sio.c index 9092e0c2e..9ad476e38 100644 --- a/src/sio.c +++ b/src/sio.c @@ -142,7 +142,7 @@ void trc_write(uint16_t port, uint8_t val, void *priv) trc_reg = val & 0xfd; } -void trc_init() +void trc_init(void) { trc_reg = 0; diff --git a/src/sio.h b/src/sio.h index 9b705a6b3..38b0ff468 100644 --- a/src/sio.h +++ b/src/sio.h @@ -1,4 +1,5 @@ /* Copyright holders: Tenshi see COPYING for more details */ +void trc_init(void); void sio_init(int card); diff --git a/src/sis496.c b/src/sis496.c index 8cdb87a95..a858102a3 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -15,16 +15,18 @@ typedef struct sis496_t uint8_t pci_conf[256]; } sis496_t; -void sis496_recalcmapping(sis496_t *sis496) +sis496_t sis496; + +void sis496_recalcmapping(void) { int c; for (c = 0; c < 8; c++) { 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: mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); @@ -45,68 +47,77 @@ void sis496_recalcmapping(sis496_t *sis496) } 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) { - sis496_t *sis496 = (sis496_t *)p; switch (addr) { case 0x44: /*Shadow configure*/ - if ((sis496->pci_conf[0x44] & val) ^ 0xf0) + if ((sis496.pci_conf[0x44] & val) ^ 0xf0) { - sis496->pci_conf[0x44] = val; - sis496_recalcmapping(sis496); + sis496.pci_conf[0x44] = val; + sis496_recalcmapping(); } break; case 0x45: /*Shadow configure*/ - if ((sis496->pci_conf[0x45] & val) ^ 0x01) + if ((sis496.pci_conf[0x45] & val) ^ 0x01) { - sis496->pci_conf[0x45] = val; - sis496_recalcmapping(sis496); + sis496.pci_conf[0x45] = val; + sis496_recalcmapping(); } break; } 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) { - 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[0x04] = 7; + sis496.pci_conf[0x05] = 0; + + sis496.pci_conf[0x06] = 0x80; + sis496.pci_conf[0x07] = 0x02; - 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[0x08] = 2; /*Device revision*/ - sis496->pci_conf[0x04] = 7; - sis496->pci_conf[0x05] = 0; + sis496.pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/ + sis496.pci_conf[0x0a] = 0x00; + sis496.pci_conf[0x0b] = 0x06; - sis496->pci_conf[0x06] = 0x80; - sis496->pci_conf[0x07] = 0x02; - - sis496->pci_conf[0x08] = 2; /*Device revision*/ + sis496.pci_conf[0x0e] = 0x00; /*Single function device*/ +} - sis496->pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/ - 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) @@ -115,15 +126,3 @@ void sis496_close(void *p) free(sis496); } - -device_t sis496_device = -{ - "SiS 496/497", - 0, - sis496_init, - sis496_close, - NULL, - NULL, - NULL, - NULL -}; diff --git a/src/sis496.h b/src/sis496.h index 1ee67d59a..fbb73be49 100644 --- a/src/sis496.h +++ b/src/sis496.h @@ -1,4 +1,4 @@ -/* Copyright holders: Sarah Walker +/* Copyright holders: Kotori see COPYING for more details */ -extern device_t sis496_device; +void sis496_init(void);