From e590bd9ca229eaf7fb79fb97e9300f3714925d98 Mon Sep 17 00:00:00 2001 From: TomW Date: Sun, 12 Jul 2015 14:22:47 +0100 Subject: [PATCH] Added FDC37c655 SuperIO chip for Intel Premiere/PCI. --- src/Makefile.mingw | 2 +- src/fdc.c | 9 +++ src/fdc.h | 1 + src/fdc37c665.c | 153 +++++++++++++++++++++++++++++++++++++++++++++ src/fdc37c665.h | 1 + src/model.c | 3 +- 6 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 src/fdc37c665.c create mode 100644 src/fdc37c665.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 2cc5dd0..7033fbd 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -5,7 +5,7 @@ WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_pentium.o codegen_x86.o compaq.o config.o cpu.o dac.o \ - device.o disc.o disc_fdi.o disc_img.o dma.o fdc.o fdi2raw.o gameport.o headland.o i430lx.o i430fx.o \ + device.o disc.o disc_fdi.o disc_img.o dma.o fdc.o fdc37c665.o fdi2raw.o gameport.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o intel.o intel_flash.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o \ diff --git a/src/fdc.c b/src/fdc.c index b6552da..fcca7cb 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -40,6 +40,7 @@ typedef struct FDC int inread; int dskchg_activelow; + int enable_3f1; } FDC; static FDC fdc; @@ -376,6 +377,8 @@ uint8_t fdc_read(uint16_t addr, void *priv) switch (addr&7) { case 1: /*???*/ + if (!fdc.enable_3f1) + return 0xff; // temp=0x50; temp = 0x70; if (fdc.dor & 1) @@ -950,6 +953,7 @@ void fdc_init() { timer_add(fdc_callback, &disctime, &disctime, NULL); fdc.dskchg_activelow = 0; + fdc.enable_3f1 = 1; } void fdc_add() @@ -981,3 +985,8 @@ void fdc_set_dskchg_activelow() { fdc.dskchg_activelow = 1; } + +void fdc_3f1_enable(int enable) +{ + fdc.enable_3f1 = enable; +} diff --git a/src/fdc.h b/src/fdc.h index c40251f..8c5fdc3 100644 --- a/src/fdc.h +++ b/src/fdc.h @@ -7,3 +7,4 @@ void fdc_poll(); void fdc_abort(); void fdc_discchange_clear(int drive); void fdc_set_dskchg_activelow(); +void fdc_3f1_enable(int enable); diff --git a/src/fdc37c665.c b/src/fdc37c665.c new file mode 100644 index 0000000..216e871 --- /dev/null +++ b/src/fdc37c665.c @@ -0,0 +1,153 @@ +#include "ibm.h" + +#include "fdc.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" +#include "fdc37c665.h" + +static uint8_t fdc37c665_lock[2]; +static int fdc37c665_curreg; +static uint8_t fdc37c665_regs[16]; + +static void write_lock(uint8_t val) +{ + if (val == 0x55 && fdc37c665_lock[1] == 0x55) + fdc_3f1_enable(0); + if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55 && val != 0x55) + fdc_3f1_enable(1); + + fdc37c665_lock[0] = fdc37c665_lock[1]; + fdc37c665_lock[1] = val; +} + +void fdc37c665_write(uint16_t port, uint8_t val, void *priv) +{ +// pclog("Write SuperIO %04x %02x\n", port, val); + if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55) + { + if (port == 0x3f0) + { + if (val == 0xaa) + write_lock(val); + else + fdc37c665_curreg = val & 0xf; + } + else + { + uint16_t com3_addr, com4_addr; + fdc37c665_regs[fdc37c665_curreg] = val; +// pclog("Write superIO %02x %02x %04x(%08x):%08x\n", fdc37c665_curreg, val, CS, cs, pc); + + switch (fdc37c665_regs[1] & 0x60) + { + case 0x00: + com3_addr = 0x338; + com4_addr = 0x238; + break; + case 0x20: + com3_addr = 0x3e8; + com4_addr = 0x2e8; + break; + case 0x40: + com3_addr = 0x3e8; + com4_addr = 0x2e0; + break; + case 0x60: + com3_addr = 0x220; + com4_addr = 0x228; + break; + } + + if (!(fdc37c665_regs[2] & 4)) + serial1_remove(); + else switch (fdc37c665_regs[2] & 3) + { + case 0: + serial1_set(0x3f8, 4); + break; + case 1: + serial1_set(0x2f8, 4); + break; + case 2: + serial1_set(com3_addr, 4); + break; + case 3: + serial1_set(com4_addr, 4); + break; + } + + if (!(fdc37c665_regs[2] & 0x40)) + serial2_remove(); + else switch (fdc37c665_regs[2] & 0x30) + { + case 0x00: + serial2_set(0x3f8, 3); + break; + case 0x10: + serial2_set(0x2f8, 3); + break; + case 0x20: + serial2_set(com3_addr, 3); + break; + case 0x30: + serial2_set(com4_addr, 3); + break; + } + + lpt1_remove(); + lpt2_remove(); + switch (fdc37c665_regs[1] & 3) + { + case 1: + lpt1_init(0x3bc); + break; + case 2: + lpt1_init(0x378); + break; + case 3: + lpt1_init(0x278); + break; + } + } + } + else + { + if (port == 0x3f0) + write_lock(val); + } +} + +uint8_t fdc37c665_read(uint16_t port, void *priv) +{ +// pclog("Read SuperIO %04x %02x\n", port, fdc37c665_curreg); + if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55) + { + if (port == 0x3f1) + return fdc37c665_regs[fdc37c665_curreg]; + } + return 0xff; +} + +void fdc37c665_init() +{ + io_sethandler(0x03f0, 0x0002, fdc37c665_read, NULL, NULL, fdc37c665_write, NULL, NULL, NULL); + + fdc37c665_lock[0] = fdc37c665_lock[1] = 0; + fdc37c665_regs[0x0] = 0x3b; + fdc37c665_regs[0x1] = 0x9f; + fdc37c665_regs[0x2] = 0xdc; + fdc37c665_regs[0x3] = 0x78; + fdc37c665_regs[0x4] = 0x00; + fdc37c665_regs[0x5] = 0x00; + fdc37c665_regs[0x6] = 0xff; + fdc37c665_regs[0x7] = 0x00; + fdc37c665_regs[0x8] = 0x00; + fdc37c665_regs[0x9] = 0x00; + fdc37c665_regs[0xa] = 0x00; + fdc37c665_regs[0xb] = 0x00; + fdc37c665_regs[0xc] = 0x00; + fdc37c665_regs[0xd] = 0x65; + fdc37c665_regs[0xe] = 0x01; + fdc37c665_regs[0xf] = 0x00; +} diff --git a/src/fdc37c665.h b/src/fdc37c665.h new file mode 100644 index 0000000..65066b8 --- /dev/null +++ b/src/fdc37c665.h @@ -0,0 +1 @@ +extern void fdc37c665_init(); diff --git a/src/model.c b/src/model.c index 442b149..a5132ab 100644 --- a/src/model.c +++ b/src/model.c @@ -10,6 +10,7 @@ #include "device.h" #include "dma.h" #include "fdc.h" +#include "fdc37c665.h" #include "gameport.h" #include "headland.h" #include "i430fx.h" @@ -300,7 +301,7 @@ void at_batman_init() mouse_ps2_init(); pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10); i430lx_init(); - um8669f_init(); + fdc37c665_init(); intel_batman_init(); } void at_endeavor_init()