From 12439b7c62ff05aeca1e12d43d4dc13346bda68f Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 4 May 2019 15:53:46 +0100 Subject: [PATCH] Add 82091AA AIP SuperIO for Packard Bell PB520R. Fixes floppy drives and duplicate ports in Windows 95. --- src/82091aa.c | 196 +++++++++++++++++++++++++++++ src/82091aa.h | 1 + src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/model.c | 2 + 6 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 src/82091aa.c create mode 100644 src/82091aa.h diff --git a/src/82091aa.c b/src/82091aa.c new file mode 100644 index 0000000..bd95071 --- /dev/null +++ b/src/82091aa.c @@ -0,0 +1,196 @@ +#include "ibm.h" +#include "82091aa.h" +#include "fdc.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" + +#define AIP_AIPID 0x00 +#define AIP_AIPREV 0x01 +#define AIP_AIPCFG1 0x02 +#define AIP_AIPCFG2 0x03 +#define AIP_FCFG1 0x10 +#define AIP_FCFG2 0x11 +#define AIP_PCFG1 0x20 +#define AIP_PCFG2 0x21 +#define AIP_SACFG1 0x30 +#define AIP_SACFG2 0x31 +#define AIP_SBCFG1 0x40 +#define AIP_SBCFG2 0x41 +#define AIP_IDECFG 0x50 + +#define FCFG1_FDC_ENA (1 << 0) +#define FCFG1_FDC_ADDR (1 << 1) + +#define PCFG1_PP_ENA (1 << 0) +#define PCFG1_PP_ADDR (3 << 1) +#define PCFG1_PP_ADDR_378 (0 << 1) +#define PCFG1_PP_ADDR_278 (1 << 1) +#define PCFG1_PP_ADDR_3BC (2 << 1) + +#define SxCFG1_ENA (1 << 0) +#define SxCFG1_ADDR (7 << 1) +#define SxCFG1_ADDR_3F8 (0 << 1) +#define SxCFG1_ADDR_2F8 (1 << 1) +#define SxCFG1_ADDR_220 (2 << 1) +#define SxCFG1_ADDR_228 (3 << 1) +#define SxCFG1_ADDR_238 (4 << 1) +#define SxCFG1_ADDR_2E8 (5 << 1) +#define SxCFG1_ADDR_338 (6 << 1) +#define SxCFG1_ADDR_3E8 (7 << 1) +#define SxCFG1_IRQ (1 << 4) +#define SxCFG1_IRQ_3 (0 << 4) +#define SxCFG1_IRQ_4 (1 << 4) + +static struct +{ + int idx; + uint8_t regs[256]; +} aip; + +static uint8_t aip_read(uint16_t addr, void *p) +{ + uint8_t temp; + + if (!(addr & 1)) + temp = aip.idx; + else + temp = aip.regs[aip.idx]; + +// pclog("aip_read: addr=%04x val=%02x\n", addr, temp); + return temp; +} + +static void aip_write(uint16_t addr, uint8_t val, void *p) +{ +// pclog("aip_write: addr=%04x val=%02x\n", addr, val); + if (!(addr & 1)) + aip.idx = val; + else + { +// pclog("AIP register write: idx=%02x val=%02x\n", aip.idx, val); + switch (aip.idx) + { + case AIP_AIPCFG1: + aip.regs[AIP_AIPCFG1] = (val & ~0x4e) | (aip.regs[AIP_AIPCFG1] & 0x48); + break; + case AIP_AIPCFG2: + aip.regs[AIP_AIPCFG2] = val & 0xf8; + break; + case AIP_FCFG1: + aip.regs[AIP_FCFG1] = val & 0x83; + fdc_remove(); + if ((aip.regs[AIP_FCFG1] & FCFG1_FDC_ENA) && !(aip.regs[AIP_FCFG1] & FCFG1_FDC_ADDR)) + fdc_add(); + break; + case AIP_FCFG2: + aip.regs[AIP_FCFG2] = (val & 0x0d) | (aip.regs[AIP_FCFG2] & 0x02); + break; + case AIP_PCFG1: + aip.regs[AIP_PCFG1] = val & 0xef; + lpt1_remove(); + if (aip.regs[AIP_PCFG1] & PCFG1_PP_ENA) + { + switch (aip.regs[AIP_PCFG1] & PCFG1_PP_ADDR) + { + case PCFG1_PP_ADDR_378: + lpt1_init(0x378); + break; + case PCFG1_PP_ADDR_278: + lpt1_init(0x278); + break; + case PCFG1_PP_ADDR_3BC: + lpt1_init(0x3bc); + break; + } + } + break; + case AIP_PCFG2: + aip.regs[AIP_PCFG2] = (val & 0x0d) | (aip.regs[AIP_PCFG2] & 0x22); + break; + case AIP_SACFG1: + aip.regs[AIP_SACFG1] = val & 0x9f; + serial1_remove(); + if (aip.regs[AIP_SACFG1] & SxCFG1_ENA) + { + uint16_t base = 0; + int irq = 0; + + switch (aip.regs[AIP_SACFG1] & SxCFG1_ADDR) + { + case SxCFG1_ADDR_3F8: base = 0x3f8; break; + case SxCFG1_ADDR_2F8: base = 0x2f8; break; + case SxCFG1_ADDR_220: base = 0x220; break; + case SxCFG1_ADDR_228: base = 0x228; break; + case SxCFG1_ADDR_238: base = 0x238; break; + case SxCFG1_ADDR_2E8: base = 0x2e8; break; + case SxCFG1_ADDR_338: base = 0x338; break; + case SxCFG1_ADDR_3E8: base = 0x3e8; break; + } + switch (aip.regs[AIP_SACFG1] & SxCFG1_IRQ) + { + case SxCFG1_IRQ_3: irq = 3; break; + case SxCFG1_IRQ_4: irq = 4; break; + } + serial1_set(base, irq); + } + break; + case AIP_SACFG2: + aip.regs[AIP_SACFG2] = (val & 0x01d) | (aip.regs[AIP_SACFG2] & 0x02); + break; + case AIP_SBCFG1: + aip.regs[AIP_SBCFG1] = val & 0x9f; + serial2_remove(); + if (aip.regs[AIP_SBCFG1] & SxCFG1_ENA) + { + uint16_t base = 0; + int irq = 0; + + switch (aip.regs[AIP_SBCFG1] & SxCFG1_ADDR) + { + case SxCFG1_ADDR_3F8: base = 0x3f8; break; + case SxCFG1_ADDR_2F8: base = 0x2f8; break; + case SxCFG1_ADDR_220: base = 0x220; break; + case SxCFG1_ADDR_228: base = 0x228; break; + case SxCFG1_ADDR_238: base = 0x238; break; + case SxCFG1_ADDR_2E8: base = 0x2e8; break; + case SxCFG1_ADDR_338: base = 0x338; break; + case SxCFG1_ADDR_3E8: base = 0x3e8; break; + } + switch (aip.regs[AIP_SBCFG1] & SxCFG1_IRQ) + { + case SxCFG1_IRQ_3: irq = 3; break; + case SxCFG1_IRQ_4: irq = 4; break; + } + serial2_set(base, irq); + } + break; + case AIP_SBCFG2: + aip.regs[AIP_SACFG2] = (val & 0x01d) | (aip.regs[AIP_SACFG2] & 0x02); + break; + case AIP_IDECFG: + aip.regs[AIP_IDECFG] = val & 0x07; + break; + } + } +} + +void aip_82091aa_init(uint16_t base) +{ + io_sethandler(base, 0x0002, aip_read, NULL, NULL, aip_write, NULL, NULL, NULL); + + memset(&aip.regs, 0xff, sizeof(aip.regs)); + aip.regs[AIP_AIPID] = 0xa0; + aip.regs[AIP_AIPREV] = 0x00; + aip.regs[AIP_AIPCFG1] = 0x40; + aip.regs[AIP_AIPCFG2] = 0x00; + aip.regs[AIP_FCFG1] = 0x01; + aip.regs[AIP_FCFG2] = 0x00; + aip.regs[AIP_PCFG1] = 0x00; + aip.regs[AIP_PCFG2] = 0x00; + aip.regs[AIP_SACFG1] = 0x00; + aip.regs[AIP_SACFG2] = 0x02; + aip.regs[AIP_SBCFG1] = 0x00; + aip.regs[AIP_SBCFG2] = 0x02; + aip.regs[AIP_IDECFG] = 0x01; +} diff --git a/src/82091aa.h b/src/82091aa.h new file mode 100644 index 0000000..79467d6 --- /dev/null +++ b/src/82091aa.h @@ -0,0 +1 @@ +void aip_82091aa_init(uint16_t base); diff --git a/src/Makefile.am b/src/Makefile.am index 416bc92..e92dc82 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,7 +23,7 @@ wx-resources.cpp : pc.xrc -wxrc -c pc.xrc -o wx-resources.cpp # PCem -pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acc2168.c acc3221.c acer386sx.c \ +pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c 820911.c acc2036.c acc2168.c acc3221.c acer386sx.c \ ali1429.c amstrad.c cassette.c cbm_io.c cdrom-image.cc cdrom-null.c cmd640.c codegen.c codegen_accumulate.c \ codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c \ codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 7d195ab..afab4b2 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = e:/MinGWget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ +OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 820911.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ cbm_io.o cdrom-ioctl.o cdrom-image.o cmd640.o codegen.o codegen_accumulate.o codegen_allocator.o \ codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o codegen_backend_x86_ops_sse.o \ codegen_backend_x86_uops.o codegen_block.o codegen_ir.o codegen_ops.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 4e8907e..7f26ab5 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = e:/mingwget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ +OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 820911.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ cbm_io.o cdrom-ioctl.o cdrom-image.o cmd640.o codegen.o codegen_accumulate.o codegen_allocator.o \ codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o codegen_backend_x86_ops_sse.o \ codegen_backend_x86_uops.o codegen_block.o codegen_ir.o codegen_ops.o \ diff --git a/src/model.c b/src/model.c index 9dcf5e2..84ca918 100644 --- a/src/model.c +++ b/src/model.c @@ -4,6 +4,7 @@ #include "io.h" #include "mouse.h" +#include "82091aa.h" #include "acc2036.h" #include "acc2168.h" #include "acc3221.h" @@ -660,6 +661,7 @@ void at_pb520r_init() i430lx_init(); sio_init(2, 0xc, 0xe, 0x6, 0); cmd640b_init(1); + aip_82091aa_init(0x22); intel_batman_init(); device_add(&intel_flash_bxt_ami_device); }