Add W83977TF SuperIO chip for Gigabyte GA686BX.

This commit is contained in:
SarahW 2020-11-09 21:50:42 +00:00
commit 5c3069c561
6 changed files with 203 additions and 4 deletions

View file

@ -51,7 +51,7 @@ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.c vid_tandy
vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c vid_voodoo_banshee.c vid_voodoo_banshee_blitter.c \
vid_voodoo_blitter.c vid_voodoo_display.c vid_voodoo_fb.c vid_voodoo_fifo.c vid_voodoo_reg.c \
vid_voodoo_render.c vid_voodoo_setup.c vid_voodoo_texture.c video.c wd76c10.c vid_wy700.c vt82c586b.c \
vl82c480.c w83877tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc
vl82c480.c w83877tf.c w83977tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc
# DOSBox
pcem_SOURCES += dosbox/cdrom_image.cpp dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c

View file

@ -39,7 +39,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_voodoo_banshee.o vid_voodoo_banshee_blitter.o \
vid_voodoo_blitter.o vid_voodoo_display.o vid_voodoo_fb.o vid_voodoo_fifo.o vid_voodoo_reg.o \
vid_voodoo_render.o vid_voodoo_setup.o vid_voodoo_texture.o vid_wy700.o video.o vl82c480.o \
vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \
vt82c586b.o w83877tf.o w83977tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \
wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \
wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \
wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \

View file

@ -39,7 +39,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_voodoo_banshee.o vid_voodoo_banshee_blitter.o \
vid_voodoo_blitter.o vid_voodoo_display.o vid_voodoo_fb.o vid_voodoo_fifo.o vid_voodoo_reg.o \
vid_voodoo_render.o vid_voodoo_setup.o vid_voodoo_texture.o vid_wy700.o video.o vl82c480.o \
vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \
vt82c586b.o w83877tf.o w83977tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \
wx-config_sel.o wx-dialogbox.o wx-hostconfig.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \
wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \
wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \

View file

@ -78,6 +78,7 @@
#include "vl82c480.h"
#include "vt82c586b.h"
#include "w83877tf.h"
#include "w83977tf.h"
#include "wd76c10.h"
#include "xi8088.h"
#include "zenith.h"
@ -847,7 +848,7 @@ void at_ga686bx_init()
pci_slot(0xb);
i440bx_init();
piix4_init(7, 0x8, 0x9, 0xa, 0xb, i440bx_reset);
w83877tf_init(0x250, 0x89);
w83977tf_init(0x3f0, 0x87);
device_add(&intel_flash_28f002bc_device);
}

197
src/w83977tf.c Normal file
View file

@ -0,0 +1,197 @@
#include "ibm.h"
#include "fdc.h"
#include "io.h"
#include "lpt.h"
#include "serial.h"
#include "w83977tf.h"
typedef struct winbond_t
{
int cur_reg;
int cur_device;
int index;
uint8_t unlock_key;
uint8_t key[2];
int enable_regs;
struct
{
int enable;
uint16_t addr;
int irq;
int dma;
} dev[11];
} winbond_t;
static winbond_t winbond_global;
#define DEV_FDC 0x0
#define DEV_LPT 0x1
#define DEV_COM1 0x2
#define DEV_COM2 0x3
#define DEV_KBC 0x5
#define DEV_GPIO 0x7
#define DEV_GPIO_II 0x8
#define DEV_GPIO_III 0x9
#define DEV_ACPI 0xa
#define REG_DEVICE 0x07
#define REG_DEVICE_ID 0x20
#define REG_DEVICE_REV 0x21
#define REG_ENABLE 0x30
#define REG_ADDRHI 0x60
#define REG_ADDRLO 0x61
#define REG_IRQ 0x70
#define REG_DMA 0x74
void winbond_write_reg(winbond_t *winbond, int index, uint8_t val)
{
if (index == REG_DEVICE)
winbond->cur_device = val & 0xf;
else
{
// pclog("Write winbond %02x [%02x] %02x\n", winbond->cur_reg, winbond->cur_device, val);
switch (index)
{
case REG_ENABLE:
if (winbond->cur_device <= DEV_ACPI)
winbond->dev[winbond->cur_device].enable = val;
break;
case REG_ADDRLO:
if (winbond->cur_device <= DEV_ACPI)
winbond->dev[winbond->cur_device].addr = (winbond->dev[winbond->cur_device].addr & 0xff00) | val;
break;
case REG_ADDRHI:
if (winbond->cur_device <= DEV_ACPI)
winbond->dev[winbond->cur_device].addr = (winbond->dev[winbond->cur_device].addr & 0x00ff) | (val << 8);
break;
case REG_IRQ:
if (winbond->cur_device <= DEV_ACPI)
winbond->dev[winbond->cur_device].irq = val;
break;
case REG_DMA:
if (winbond->cur_device <= DEV_ACPI)
winbond->dev[winbond->cur_device].dma = val;
break;
}
switch (winbond->cur_device)
{
case DEV_FDC:
fdc_remove();
if (winbond->dev[DEV_FDC].enable & 1)
fdc_add();
break;
case DEV_COM1:
serial1_remove();
if (winbond->dev[DEV_COM1].enable & 1)
serial1_set(winbond->dev[DEV_COM1].addr, winbond->dev[DEV_COM1].irq);
break;
case DEV_COM2:
serial2_remove();
if (winbond->dev[DEV_COM2].enable & 1)
serial2_set(winbond->dev[DEV_COM2].addr, winbond->dev[DEV_COM2].irq);
break;
case DEV_LPT:
lpt1_remove();
lpt2_remove();
if (winbond->dev[DEV_LPT].enable & 1)
lpt1_init(winbond->dev[DEV_LPT].addr);
break;
}
}
}
uint8_t winbond_read_reg(winbond_t *winbond, int index)
{
// pclog("Read winbond %02x\n", winbond->cur_reg);
switch (index)
{
case REG_DEVICE:
return winbond->cur_device;
case REG_DEVICE_ID:
return 0x97;
case REG_DEVICE_REV:
return 0x73;
case REG_ENABLE:
return winbond->dev[winbond->cur_device].enable;
case REG_ADDRLO:
return winbond->dev[winbond->cur_device].addr & 0xff;
case REG_ADDRHI:
return winbond->dev[winbond->cur_device].addr >> 8;
case REG_IRQ:
return winbond->dev[winbond->cur_device].irq;
case REG_DMA:
return winbond->dev[winbond->cur_device].dma;
}
return 0xff;
}
static void winbond_write_3fx(uint16_t port, uint8_t val, void *p)
{
winbond_t *winbond = (winbond_t *)p;
// pclog("winbond_write: port=%04x val=%02x\n", port, val);
switch (port)
{
case 0x3f0: /*Enable/index register*/
if (val == 0xaa)
{
fdc_3f1_enable(1);
winbond->enable_regs = 0;
}
else if (!winbond->enable_regs)
{
winbond->key[1] = winbond->key[0];
winbond->key[0] = val;
winbond->enable_regs = (winbond->key[0] == winbond->unlock_key && winbond->key[1] == winbond->unlock_key);
/*The FDC conflicts with the 3fx config registers, so disable
it when enabling config registers*/
if (winbond->enable_regs)
fdc_3f1_enable(0);
}
else
winbond->index = val;
break;
case 0x3f1: /*Data*/
if (winbond->enable_regs)
winbond_write_reg(winbond, winbond->index, val);
break;
}
}
static uint8_t winbond_read_3fx(uint16_t port, void *p)
{
winbond_t *winbond = (winbond_t *)p;
uint8_t ret = 0xff;
switch (port)
{
case 0x3f0: /*Index*/
if (winbond->enable_regs)
ret = winbond->index;
break;
case 0x3f1: /*Data*/
if (winbond->enable_regs)
ret = winbond_read_reg(winbond, winbond->index);
break;
}
// pclog("winbond_read: port=%04x val=%02x\n", port, ret);
return ret;
}
void w83977tf_init(uint16_t base, uint8_t key)
{
memset(&winbond_global, 0, sizeof(winbond_t));
winbond_global.unlock_key = key;
io_sethandler(base, 0x0002, winbond_read_3fx, NULL, NULL, winbond_write_3fx, NULL, NULL, &winbond_global);
}

1
src/w83977tf.h Normal file
View file

@ -0,0 +1 @@
void w83977tf_init(uint16_t base, uint8_t key);