diff --git a/src/Makefile.mingw b/src/Makefile.mingw index e6651d08b..87c4c790d 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -187,7 +187,7 @@ SYSOBJ = model.o \ tandy_eeprom.o tandy_rom.o DEVOBJ = bugger.o lpt.o $(SERIAL) \ fdc37c665.o fdc37c669.o fdc37c932fr.o \ - pc87306.o sis85c471.o w83877f.o \ + pc87306.o sis85c471.o w83877f.o um8669f.o \ keyboard.o \ keyboard_xt.o keyboard_at.o keyboard_pcjr.o \ keyboard_amstrad.o keyboard_olim24.o \ diff --git a/src/mem.c b/src/mem.c index 0fe8a0dd7..7634c3622 100644 --- a/src/mem.c +++ b/src/mem.c @@ -441,16 +441,6 @@ int loadbios() fclose(f); return 1; - case ROM_SIS496: - f = romfopen(L"roms/machines/sis496/SIS496_3.AWA", L"rb"); - if (!f) break; - fread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]); - return 1; - -#if 0 case ROM_430VX: f = romfopen(L"roms/machines/430vx/55XWUQ0E.BIN", L"rb"); if (!f) break; @@ -458,7 +448,6 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; -#endif case ROM_REVENGE: f = romfopen(L"roms/machines/revenge/1009AF2_.BIO", L"rb"); diff --git a/src/model.c b/src/model.c index 7980dcc88..3e0efa828 100644 --- a/src/model.c +++ b/src/model.c @@ -66,9 +66,7 @@ #endif #include "tandy_eeprom.h" #include "tandy_rom.h" -#if 0 #include "um8669f.h" -#endif #include "video/vid_pcjr.h" #include "video/vid_tandy.h" #include "w83877f.h" @@ -102,6 +100,7 @@ extern void at_wd76c10_init(void); extern void at_ali1429_init(void); extern void at_headland_init(void); extern void at_opti495_init(void); +extern void at_i430vx_init(void); extern void at_batman_init(void); #if 0 extern void at_586mc1_init(void); @@ -224,6 +223,7 @@ MODEL models[] = {"[Socket 7 HX] ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL }, {"[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL }, + {"[Socket 7 VX] Award 430VX PCI", ROM_430VX, "430vx", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i430vx_init, NULL }, {"[Socket 7 VX] Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL }, {"[Socket 8 FX] Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL }, @@ -875,6 +875,20 @@ void at_p55tvp4_init(void) device_add(&intel_flash_bxt_device); } +void at_i430vx_init(void) +{ + at_ide_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); + i430vx_init(); + piix_init(7, 18, 17, 20, 19); + um8669f_init(); + device_add(&intel_flash_bxt_device); +} + void at_p55va_init(void) { at_ide_init(); diff --git a/src/um8669f.c b/src/um8669f.c new file mode 100644 index 000000000..5e089aaec --- /dev/null +++ b/src/um8669f.c @@ -0,0 +1,277 @@ +/*um8669f : + + aa to 108 unlocks + next 108 write is register select (Cx?) + data read/write to 109 + 55 to 108 locks + +C1 +bit 7 - enable PnP registers + +PnP registers : + +07 - device : + 0 = FDC + 1 = COM1 + 2 = COM2 + 3 = LPT1 + 5 = Game port +30 - enable +60/61 - addr +70 - IRQ +74 - DMA*/ + +#include "ibm.h" + +#include "disc.h" +#include "fdd.h" +#include "fdc.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" +#include "um8669f.h" + +typedef struct um8669f_t +{ + int locked; + int cur_reg_108; + uint8_t regs_108[256]; + + int cur_reg; + int cur_device; + struct + { + int enable; + uint16_t addr; + int irq; + int dma; + } dev[8]; +} um8669f_t; + +static um8669f_t um8669f_global; + +#define DEV_FDC 0 +#define DEV_COM1 1 +#define DEV_COM2 2 +#define DEV_LPT1 3 +#define DEV_GAME 5 + +#define REG_DEVICE 0x07 +#define REG_ENABLE 0x30 +#define REG_ADDRHI 0x60 +#define REG_ADDRLO 0x61 +#define REG_IRQ 0x70 +#define REG_DMA 0x74 + +void um8669f_pnp_write(uint16_t port, uint8_t val, void *p) +{ + um8669f_t *um8669f = (um8669f_t *)p; + + uint8_t valxor = 0; + + if (port == 0x279) + um8669f->cur_reg = val; + else + { + if (um8669f->cur_reg == REG_DEVICE) + um8669f->cur_device = val & 7; + else + { +/* pclog("Write UM8669F %02x [%02x] %02x\n", um8669f->cur_reg, um8669f->cur_device, val); */ + switch (um8669f->cur_reg) + { + case REG_ENABLE: + valxor = um8669f->dev[um8669f->cur_device].enable ^ val; + um8669f->dev[um8669f->cur_device].enable = val; + break; + case REG_ADDRLO: + valxor = (um8669f->dev[um8669f->cur_device].addr & 0xff) ^ val; + um8669f->dev[um8669f->cur_device].addr = (um8669f->dev[um8669f->cur_device].addr & 0xff00) | val; + break; + case REG_ADDRHI: + valxor = ((um8669f->dev[um8669f->cur_device].addr >> 8) & 0xff) ^ val; + um8669f->dev[um8669f->cur_device].addr = (um8669f->dev[um8669f->cur_device].addr & 0x00ff) | (val << 8); + break; + case REG_IRQ: + valxor = um8669f->dev[um8669f->cur_device].irq ^ val; + um8669f->dev[um8669f->cur_device].irq = val; + break; + case REG_DMA: + valxor = um8669f->dev[um8669f->cur_device].dma ^ val; + um8669f->dev[um8669f->cur_device].dma = val; + break; + default: + valxor = 0; + break; + } + + /* pclog("UM8669F: Write %02X to [%02X][%02X]...\n", val, um8669f->cur_device, um8669f->cur_reg); */ + + switch (um8669f->cur_device) + { + case DEV_FDC: + if ((um8669f->cur_reg == REG_ENABLE) && valxor) + { + fdc_remove(); + if (um8669f->dev[DEV_FDC].enable & 1) + fdc_add(); + } + break; + case DEV_COM1: + if (valxor) + { + serial_remove(1); + if (um8669f->dev[DEV_COM1].enable & 1) + serial_setup(1, um8669f->dev[DEV_COM1].addr, um8669f->dev[DEV_COM1].irq); + } + break; + case DEV_COM2: + if (valxor) + { + serial_remove(2); + if (um8669f->dev[DEV_COM2].enable & 1) + serial_setup(2, um8669f->dev[DEV_COM2].addr, um8669f->dev[DEV_COM2].irq); + } + break; + case DEV_LPT1: + if (valxor) + { + lpt1_remove(); + if (um8669f->dev[DEV_LPT1].enable & 1) + lpt1_init(um8669f->dev[DEV_LPT1].addr); + } + break; + } + } + } +} + +uint8_t um8669f_pnp_read(uint16_t port, void *p) +{ + um8669f_t *um8669f = (um8669f_t *)p; + +/* pclog("Read UM8669F %02x\n", um8669f->cur_reg); */ + + switch (um8669f->cur_reg) + { + case REG_DEVICE: + return um8669f->cur_device; + case REG_ENABLE: + return um8669f->dev[um8669f->cur_device].enable; + case REG_ADDRLO: + return um8669f->dev[um8669f->cur_device].addr & 0xff; + case REG_ADDRHI: + return um8669f->dev[um8669f->cur_device].addr >> 8; + case REG_IRQ: + return um8669f->dev[um8669f->cur_device].irq; + case REG_DMA: + return um8669f->dev[um8669f->cur_device].dma; + } + + return 0xff; +} + +void um8669f_write(uint16_t port, uint8_t val, void *p) +{ + um8669f_t *um8669f = (um8669f_t *)p; + + if (um8669f->locked) + { + if (port == 0x108 && val == 0xaa) + um8669f->locked = 0; + } + else + { + if (port == 0x108) + { + if (val == 0x55) + um8669f->locked = 1; + else + um8669f->cur_reg_108 = val; + } + else + { +/* pclog("Write UM8669f register %02x %02x %04x:%04x %i\n", um8669f_curreg, val, CS,cpu_state.pc, ins); */ + um8669f->regs_108[um8669f->cur_reg_108] = val; + + io_removehandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); + io_removehandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); + io_removehandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, um8669f); + if (um8669f->regs_108[0xc1] & 0x80) + { + io_sethandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); + io_sethandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); + io_sethandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, um8669f); + } + } + } +} + +uint8_t um8669f_read(uint16_t port, void *p) +{ + um8669f_t *um8669f = (um8669f_t *)p; + +/* pclog("um8669f_read : port=%04x reg %02X locked=%i %02x\n", port, um8669f_curreg, um8669f_locked, um8669f_regs[um8669f_curreg]); */ + if (um8669f->locked) + return 0xff; + + if (port == 0x108) + return um8669f->cur_reg_108; /*???*/ + else + return um8669f->regs_108[um8669f->cur_reg_108]; +} + +void um8669f_reset(void) +{ + fdc_update_is_nsc(0); + + serial_remove(1); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); + + serial_remove(2); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); + + lpt2_remove(); + + lpt1_remove(); + lpt1_init(0x378); + + memset(&um8669f_global, 0, sizeof(um8669f_t)); + + um8669f_global.locked = 1; + + fdc_update_densel_polarity(1); + fdc_update_densel_force(0); + + fdd_swap = 0; + + io_removehandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, &um8669f_global); + io_removehandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, &um8669f_global); + io_removehandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, &um8669f_global); + + um8669f_global.dev[DEV_FDC].enable = 1; + um8669f_global.dev[DEV_FDC].addr = 0x03f0; + um8669f_global.dev[DEV_FDC].irq = 6; + um8669f_global.dev[DEV_FDC].dma = 2; + + um8669f_global.dev[DEV_COM1].enable = 1; + um8669f_global.dev[DEV_COM1].addr = 0x03f8; + um8669f_global.dev[DEV_COM1].irq = 4; + + um8669f_global.dev[DEV_COM2].enable = 1; + um8669f_global.dev[DEV_COM2].addr = 0x02f8; + um8669f_global.dev[DEV_COM2].irq = 3; + + um8669f_global.dev[DEV_LPT1].enable = 1; + um8669f_global.dev[DEV_LPT1].addr = 0x0378; + um8669f_global.dev[DEV_LPT1].irq = 7; +} + +void um8669f_init() +{ + io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, &um8669f_global); + + um8669f_reset(); + + pci_reset_handler.super_io_reset = um8669f_reset; +} diff --git a/src/um8669f.h b/src/um8669f.h new file mode 100644 index 000000000..409ad51c2 --- /dev/null +++ b/src/um8669f.h @@ -0,0 +1 @@ +extern void um8669f_init();