From 77d73ed3c29e016dd45e112adec144a43e24ae07 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 26 Oct 2021 01:54:35 +0200 Subject: [PATCH] Finished the Intel 450KX, changes to the memory and SMRAM API's, removed the ASUS P/I-P6RP4 from the Dev branch, added the CMD646 PCI IDE controller, and fixed some bugs on the CMD640. --- src/chipset/CMakeLists.txt | 6 +- src/chipset/intel_i450kx.c | 630 ++++++++++++++++++--------- src/disk/CMakeLists.txt | 2 +- src/disk/hdc_ide_cmd640.c | 157 ++++--- src/disk/hdc_ide_cmd646.c | 435 ++++++++++++++++++ src/disk/hdc_ide_sff8038i.c | 24 +- src/include/86box/chipset.h | 4 +- src/include/86box/hdc.h | 3 + src/include/86box/hdc_ide_sff8038i.h | 11 +- src/include/86box/machine.h | 2 - src/include/86box/mem.h | 8 + src/include/86box/nvr.h | 1 + src/include/86box/smram.h | 7 + src/machine/CMakeLists.txt | 4 - src/machine/m_at_socket8.c | 14 +- src/machine/machine_table.c | 4 +- src/mem/mem.c | 6 + src/mem/smram.c | 35 +- src/nvr_at.c | 43 +- src/pci.c | 152 ++++++- src/scsi/scsi_cdrom.c | 9 +- src/win/Makefile.mingw | 17 +- 22 files changed, 1269 insertions(+), 305 deletions(-) create mode 100644 src/disk/hdc_ide_cmd646.c diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 770b54006..ce5bded9a 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -15,16 +15,12 @@ add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1489.c ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c headland.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c - intel_4x0.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c + intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c) -if(I450KX) - target_sources(chipset PRIVATE intel_i450kx.c) -endif() - if(OLIVETTI) target_sources(chipset PRIVATE olivetti_eva.c) endif() \ No newline at end of file diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index 5a89f2659..2696db495 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -58,71 +58,95 @@ i450kx_log(const char *fmt, ...) #endif -/* Shadow RAM Flags */ -#define LSB_DECISION (((shadow_value & 1) ? MEM_READ_EXTANY : MEM_READ_INTERNAL) | ((shadow_value & 2) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL)) -#define MSB_DECISION (((shadow_value & 0x10) ? MEM_READ_EXTANY : MEM_READ_INTERNAL) | ((shadow_value & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL)) -#define LSB_DECISION_MC (((shadow_value & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((shadow_value & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)) -#define MSB_DECISION_MC (((shadow_value & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((shadow_value & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)) - -/* SMRAM */ -#define SMRAM_ADDR (((dev->pb_pci_conf[0xb9] << 8) | dev->pb_pci_conf[0xb8]) << 17) -#define SMRAM_ADDR_MC (((dev->mc_pci_conf[0xb9] << 8) | dev->mc_pci_conf[0xb8]) << 16) -#define SMRAM_SIZE (((dev->pb_pci_conf[0xbb] >> 4) + 1) * 64) -#define SMRAM_SIZE_MC (((dev->mc_pci_conf[0xbb] >> 4) + 1) * 64) - -/* Miscellaneous */ -#define ENABLE_SEGMENT (MEM_READ_EXTANY | MEM_WRITE_EXTANY) -#define DISABLE_SEGMENT (MEM_READ_DISABLED | MEM_WRITE_DISABLED) - - +/* TODO: Finish the bus index stuff. */ typedef struct i450kx_t { - smram_t *smram; + smram_t * smram[2]; - uint8_t pb_pci_conf[256], mc_pci_conf[256]; + uint8_t pb_pci_conf[256], mc_pci_conf[256]; + uint8_t mem_state[2][256]; + + uint8_t bus_index; } i450kx_t; static void -i450kx_shadow(int is_mc, int cur_reg, uint8_t shadow_value, i450kx_t *dev) +i450kx_map(i450kx_t *dev, int bus, uint32_t addr, uint32_t size, int state) { - if (cur_reg == 0x59) { - mem_set_mem_state_both(0x80000, 0x20000, (is_mc) ? LSB_DECISION_MC : LSB_DECISION); - mem_set_mem_state_both(0xf0000, 0x10000, (is_mc) ? MSB_DECISION_MC : MSB_DECISION); - } else { - mem_set_mem_state_both(0xc0000 + (((cur_reg & 7) - 2) * 0x8000), 0x4000, (is_mc) ? LSB_DECISION_MC : LSB_DECISION); - mem_set_mem_state_both(0xc4000 + (((cur_reg & 7) - 2) * 0x8000), 0x4000, (is_mc) ? MSB_DECISION_MC : MSB_DECISION); + uint32_t base = addr >> 12; + int states[4] = { MEM_READ_EXTANY | MEM_WRITE_EXTANY, MEM_READ_INTERNAL | MEM_WRITE_EXTANY, + MEM_READ_EXTANY | MEM_WRITE_INTERNAL, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL }; + + state &= 3; + if (dev->mem_state[bus][base] != state) { + if (bus) + mem_set_mem_state_bus_both(addr, size, states[state]); + else + mem_set_mem_state_cpu_both(addr, size, states[state]); + dev->mem_state[bus][base] = state; + flushmmucache_nopc(); } - flushmmucache_nopc(); } static void -i450kx_smm(uint32_t smram_addr, uint32_t smram_size, i450kx_t *dev) +i450kx_smram_recalc(i450kx_t *dev, int bus) { - smram_disable_all(); + uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; + uint32_t addr, size; - if ((smram_addr != 0) && !!(dev->mc_pci_conf[0x57] & 8)) - smram_enable(dev->smram, smram_addr, smram_addr, smram_size, !!(dev->pb_pci_conf[0x57] & 8), 1); + smram_disable(dev->smram[bus]); + + addr = ((uint32_t) regs[0xb8] << 16) | ((uint32_t) regs[0xb9] << 24); + size = (((uint32_t) ((regs[0xbb] >> 4) & 0x0f)) << 16) + 0x00010000; + + if ((addr != 0x00000000) && !!(regs[0x57] & 0x08)) { + if (bus) + smram_enable_ex(dev->smram[bus], addr, addr, size, 0, !!(regs[0x57] & 8), 0, 1); + else + smram_enable_ex(dev->smram[bus], addr, addr, size, !!(regs[0x57] & 8), 0, 1, 0); + } flushmmucache(); } +static void +i450kx_vid_buf_recalc(i450kx_t *dev, int bus) +{ + uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; + + // int state = (regs[0x58] & 0x02) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_DISABLED | MEM_WRITE_DISABLED); + int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if (bus) + mem_set_mem_state_bus_both(0x000a0000, 0x00020000, state); + else + mem_set_mem_state_cpu_both(0x000a0000, 0x00020000, state); + + flushmmucache_nopc(); +} + + static void pb_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *)priv; - switch (addr) { - case 0x04: - dev->pb_pci_conf[addr] &= val & 0xd7; - break; + // pclog("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + i450kx_log("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); - case 0x06: - dev->pb_pci_conf[addr] = val & 0x80; + if (func == 0) switch (addr) { + case 0x04: + dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x04) | (val & 0x53); + break; + case 0x05: + dev->pb_pci_conf[addr] = val & 0x01; break; case 0x07: + dev->pb_pci_conf[addr] &= ~(val & 0xf9); + break; + case 0x0d: dev->pb_pci_conf[addr] = val; break; @@ -131,63 +155,106 @@ pb_write(int func, int addr, uint8_t val, void *priv) dev->pb_pci_conf[addr] = val & 0xcf; break; - case 0x40: - case 0x41: + case 0x40: case 0x41: dev->pb_pci_conf[addr] = val; break; - case 0x43: dev->pb_pci_conf[addr] = val & 0x80; break; case 0x48: - dev->pb_pci_conf[addr] = val & 6; + dev->pb_pci_conf[addr] = val & 0x06; break; - case 0x4a: - case 0x4b: + case 0x4a: case 0x4b: dev->pb_pci_conf[addr] = val; + // if (addr == 0x4a) + // pci_remap_bus(dev->bus_index, val); break; case 0x4c: - dev->pb_pci_conf[addr] = val & 0xd8; + dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x01) | (val & 0xd8); + break; + + case 0x51: + dev->pb_pci_conf[addr] = val; break; case 0x53: - dev->pb_pci_conf[addr] = val & 2; + dev->pb_pci_conf[addr] = val & 0x02; break; case 0x54: dev->pb_pci_conf[addr] = val & 0x7b; break; - case 0x55: - dev->pb_pci_conf[addr] = val & 2; + dev->pb_pci_conf[addr] = val & 0x03; break; case 0x57: - dev->pb_pci_conf[addr] = val & 8; - i450kx_smm(SMRAM_ADDR, SMRAM_SIZE, dev); + dev->pb_pci_conf[addr] = val & 0x08; + i450kx_smram_recalc(dev, 1); break; case 0x58: - dev->pb_pci_conf[addr] = val & 2; - mem_set_mem_state_both(0xa0000, 0x20000, (val & 2) ? ENABLE_SEGMENT : DISABLE_SEGMENT); + dev->pb_pci_conf[addr] = val & 0x02; + i450kx_vid_buf_recalc(dev, 1); break; - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: - dev->pb_pci_conf[addr] = val & 0x33; - i450kx_shadow(0, addr, val, dev); + case 0x59: /* PAM0 */ + if ((dev->pb_pci_conf[0x59] ^ val) & 0x0f) + i450kx_map(dev, 1, 0x80000, 0x20000, val & 0x0f); + if ((dev->pb_pci_conf[0x59] ^ val) & 0xf0) { + i450kx_map(dev, 1, 0xf0000, 0x10000, val >> 4); + shadowbios = (val & 0x10); + } + dev->pb_pci_conf[0x59] = val & 0x33; + break; + case 0x5a: /* PAM1 */ + if ((dev->pb_pci_conf[0x5a] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xc0000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5a] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xc4000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5a] = val & 0x33; + break; + case 0x5b: /*PAM2 */ + if ((dev->pb_pci_conf[0x5b] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xc8000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5b] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xcc000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5b] = val & 0x33; + break; + case 0x5c: /*PAM3 */ + if ((dev->pb_pci_conf[0x5c] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xd0000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5c] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xd4000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5c] = val & 0x33; + break; + case 0x5d: /* PAM4 */ + if ((dev->pb_pci_conf[0x5d] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xd8000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5d] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xdc000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5d] = val & 0x33; + break; + case 0x5e: /* PAM5 */ + if ((dev->pb_pci_conf[0x5e] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xe0000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5e] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xe4000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5e] = val & 0x33; + break; + case 0x5f: /* PAM6 */ + if ((dev->pb_pci_conf[0x5f] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xe8000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5f] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xec000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5f] = val & 0x33; break; case 0x70: - dev->pb_pci_conf[addr] = val & 0xfc; + dev->pb_pci_conf[addr] = val & 0xf8; break; case 0x71: @@ -197,47 +264,49 @@ pb_write(int func, int addr, uint8_t val, void *priv) case 0x78: dev->pb_pci_conf[addr] = val & 0xf0; break; - case 0x79: dev->pb_pci_conf[addr] = val & 0xfc; break; - - case 0x7c: - dev->pb_pci_conf[addr] = val & 0x5f; + case 0x7a: + dev->pb_pci_conf[addr] = val; + break; + case 0x7b: + dev->pb_pci_conf[addr] = val & 0x0f; break; + case 0x7c: + dev->pb_pci_conf[addr] = val & 0x9f; + break; case 0x7d: dev->pb_pci_conf[addr] = val & 0x1a; break; - case 0x7e: dev->pb_pci_conf[addr] = val & 0xf0; break; - case 0x7f: - case 0x88: - case 0x89: - case 0x8a: dev->pb_pci_conf[addr] = val; break; + case 0x88: case 0x89: + dev->pb_pci_conf[addr] = val; + break; case 0x8b: dev->pb_pci_conf[addr] = val & 0x80; break; - - case 0x9c: - dev->pb_pci_conf[addr] = val & 1; - break; - - case 0xa4: - dev->pb_pci_conf[addr] = val & 0xf9; - break; - - case 0xa5: - case 0xa6: + case 0x8c: case 0x8d: dev->pb_pci_conf[addr] = val; break; + case 0x9c: + dev->pb_pci_conf[addr] = val & 0x01; + break; + + case 0xa4: + dev->pb_pci_conf[addr] = val & 0xf8; + break; + case 0xa5: case 0xa6: + dev->pb_pci_conf[addr] = val; + break; case 0xa7: dev->pb_pci_conf[addr] = val & 0x0f; break; @@ -245,36 +314,45 @@ pb_write(int func, int addr, uint8_t val, void *priv) case 0xb0: dev->pb_pci_conf[addr] = val & 0xe0; break; - case 0xb1: - dev->pb_pci_conf[addr] = val & 0x1f; + dev->pb_pci_conf[addr] = val & /*0x1a*/ 0x1f; break; case 0xb4: - dev->pb_pci_conf[addr] = val & 0xe8; + dev->pb_pci_conf[addr] = val & 0xe0; break; - case 0xb5: dev->pb_pci_conf[addr] = val & 0x1f; break; - case 0xb8: - case 0xb9: + case 0xb8: case 0xb9: + dev->pb_pci_conf[addr] = val; + i450kx_smram_recalc(dev, 1); + break; case 0xbb: - dev->pb_pci_conf[addr] = !(addr == 0xbb) ? val : (val & 0xf0); - i450kx_smm(SMRAM_ADDR, SMRAM_SIZE, dev); + dev->pb_pci_conf[addr] = val & 0xf0; + i450kx_smram_recalc(dev, 1); + break; + + case 0xbc: + dev->pb_pci_conf[addr] = val & 0x11; + break; + + case 0xc0: + dev->pb_pci_conf[addr] = val & 0xdf; + break; + case 0xc1: + dev->pb_pci_conf[addr] = val & 0x3f; break; case 0xc4: - dev->pb_pci_conf[addr] = val & 5; + dev->pb_pci_conf[addr] &= ~(val & 0x0f); break; - case 0xc5: - dev->pb_pci_conf[addr] = val & 0x0a; + dev->pb_pci_conf[addr] &= ~(val & 0x0a); break; - case 0xc6: - dev->pb_pci_conf[addr] = val & 0x1d; + dev->pb_pci_conf[addr] &= ~(val & 0x1f); break; case 0xc8: @@ -286,7 +364,6 @@ pb_write(int func, int addr, uint8_t val, void *priv) dev->pb_pci_conf[addr] = val; break; } - i450kx_log("i450KX-PB: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pb_pci_conf[addr], inb(0x80)); } @@ -294,7 +371,30 @@ static uint8_t pb_read(int func, int addr, void *priv) { i450kx_t *dev = (i450kx_t *)priv; - return dev->pb_pci_conf[addr]; + uint8_t ret = 0xff; + + if (func == 0) + ret = dev->pb_pci_conf[addr]; + + // pclog("i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + + return ret; +} + + +/* A way to use spd_write_drbs_interlaved() and convert the output to what we need. */ +static void +mc_fill_drbs(i450kx_t *dev) +{ + int i; + + spd_write_drbs_interleaved(dev->mc_pci_conf, 0x60, 0x6f, 4); + for (i = 0x60; i <= 0x6f; i++) { + if (i & 0x01) + dev->mc_pci_conf[i] = 0x00; + else + dev->mc_pci_conf[i] &= 0x7f; + } } @@ -303,75 +403,97 @@ mc_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *)priv; - switch (addr) - { + // pclog("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + i450kx_log("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + + if (func == 0) switch (addr) { case 0x4c: dev->mc_pci_conf[addr] = val & 0xdf; break; - case 0x4d: - dev->mc_pci_conf[addr] = val & 0xdf; + dev->mc_pci_conf[addr] = val & 0xff; break; case 0x57: - dev->mc_pci_conf[addr] = val & 8; - i450kx_smm(SMRAM_ADDR, SMRAM_SIZE, dev); + dev->mc_pci_conf[addr] = val & 0x08; + i450kx_smram_recalc(dev, 0); break; case 0x58: - dev->mc_pci_conf[addr] = val & 2; + dev->mc_pci_conf[addr] = val & 0x02; + i450kx_vid_buf_recalc(dev, 0); break; - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: - dev->mc_pci_conf[addr] = val & 0x33; - i450kx_shadow(1, addr, val, dev); + case 0x59: /* PAM0 */ + if ((dev->mc_pci_conf[0x59] ^ val) & 0x0f) + i450kx_map(dev, 0, 0x80000, 0x20000, val & 0x0f); + if ((dev->mc_pci_conf[0x59] ^ val) & 0xf0) { + i450kx_map(dev, 0, 0xf0000, 0x10000, val >> 4); + shadowbios = (val & 0x10); + } + dev->mc_pci_conf[0x59] = val & 0x33; + break; + case 0x5a: /* PAM1 */ + if ((dev->mc_pci_conf[0x5a] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xc0000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5a] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xc4000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5a] = val & 0x33; + break; + case 0x5b: /*PAM2 */ + if ((dev->mc_pci_conf[0x5b] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xc8000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5b] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xcc000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5b] = val & 0x33; + break; + case 0x5c: /*PAM3 */ + if ((dev->mc_pci_conf[0x5c] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xd0000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5c] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xd4000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5c] = val & 0x33; + break; + case 0x5d: /* PAM4 */ + if ((dev->mc_pci_conf[0x5d] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xd8000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5d] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xdc000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5d] = val & 0x33; + break; + case 0x5e: /* PAM5 */ + if ((dev->mc_pci_conf[0x5e] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xe0000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5e] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xe4000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5e] = val & 0x33; + break; + case 0x5f: /* PAM6 */ + if ((dev->mc_pci_conf[0x5f] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xe8000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5f] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xec000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5f] = val & 0x33; break; - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6a: - case 0x6b: - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f: - dev->mc_pci_conf[addr] = ((addr & 0x0f) % 2) ? 0 : (val & 0x7f); - spd_write_drbs(dev->mc_pci_conf, 0x60, 0x6f, 4); + case 0x60 ... 0x6f: + dev->mc_pci_conf[addr] = ((addr & 0x0f) & 0x01) ? 0x00 : (val & 0x7f); + mc_fill_drbs(dev); break; - case 0x74: - case 0x75: - case 0x76: - case 0x77: + case 0x74 ... 0x77: dev->mc_pci_conf[addr] = val; break; case 0x78: dev->mc_pci_conf[addr] = val & 0xf0; break; - case 0x79: dev->mc_pci_conf[addr] = val & 0xfe; break; - case 0x7a: dev->mc_pci_conf[addr] = val; break; - case 0x7b: dev->mc_pci_conf[addr] = val & 0x0f; break; @@ -379,45 +501,36 @@ mc_write(int func, int addr, uint8_t val, void *priv) case 0x7c: dev->mc_pci_conf[addr] = val & 0x1f; break; - case 0x7d: dev->mc_pci_conf[addr] = val & 0x0c; break; - case 0x7e: dev->mc_pci_conf[addr] = val & 0xf0; break; - case 0x7f: dev->mc_pci_conf[addr] = val; break; - case 0x88: - case 0x89: + case 0x88: case 0x89: dev->mc_pci_conf[addr] = val; break; - case 0x8b: dev->mc_pci_conf[addr] = val & 0x80; break; - case 0x8c: - case 0x8d: + case 0x8c: case 0x8d: dev->mc_pci_conf[addr] = val; break; case 0xa4: - dev->mc_pci_conf[addr] = val & 1; + dev->mc_pci_conf[addr] = val & 0x01; break; - case 0xa5: dev->pb_pci_conf[addr] = val & 0xf0; break; - case 0xa6: dev->mc_pci_conf[addr] = val; break; - case 0xa7: dev->mc_pci_conf[addr] = val & 0x0f; break; @@ -425,49 +538,56 @@ mc_write(int func, int addr, uint8_t val, void *priv) case 0xa8: dev->mc_pci_conf[addr] = val & 0xfe; break; - - case 0xa9: - case 0xaa: - case 0xab: - case 0xac: - case 0xad: - case 0xae: + case 0xa9 ... 0xab: dev->mc_pci_conf[addr] = val; break; + case 0xac ... 0xae: + dev->mc_pci_conf[addr] = val; + break; case 0xaf: dev->mc_pci_conf[addr] = val & 0x7f; break; - case 0xb8: - case 0xb9: + case 0xb8: case 0xb9: + dev->mc_pci_conf[addr] = val; + i450kx_smram_recalc(dev, 0); + break; case 0xbb: - dev->mc_pci_conf[addr] = !(addr == 0xbb) ? val : (val & 0xf0); - - i450kx_smm(SMRAM_ADDR_MC, SMRAM_SIZE_MC, dev); + dev->mc_pci_conf[addr] = val & 0xf0; + i450kx_smram_recalc(dev, 0); break; case 0xbc: - dev->mc_pci_conf[addr] = val & 1; + dev->mc_pci_conf[addr] = val & 0x01; break; case 0xc0: - dev->mc_pci_conf[addr] = val & 7; + dev->mc_pci_conf[addr] = val & 0x07; break; case 0xc2: - dev->mc_pci_conf[addr] = val & 3; + dev->mc_pci_conf[addr] &= ~(val & 0x03); break; case 0xc4: - dev->mc_pci_conf[addr] = val & 0x3f; + dev->mc_pci_conf[addr] = val & 0xbf; + break; + case 0xc5: + dev->mc_pci_conf[addr] = val & 0x03; break; case 0xc6: - dev->mc_pci_conf[addr] = val & 0x19; + dev->mc_pci_conf[addr] &= ~(val & 0x19); + break; + + case 0xc8: + dev->mc_pci_conf[addr] = val & 0x1f; + break; + case 0xca: case 0xcb: + dev->mc_pci_conf[addr] = val; break; } - i450kx_log("i450KX-MC: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->mc_pci_conf[addr], inb(0x80)); } @@ -475,7 +595,14 @@ static uint8_t mc_read(int func, int addr, void *priv) { i450kx_t *dev = (i450kx_t *)priv; - return dev->mc_pci_conf[addr]; + uint8_t ret = 0xff; + + if (func == 0) + ret = dev->mc_pci_conf[addr]; + + // pclog("i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + + return ret; } @@ -483,57 +610,168 @@ static void i450kx_reset(void *priv) { i450kx_t *dev = (i450kx_t *)priv; + uint32_t i; - /* CONFLICTS WARNING! We do not program anything on reset due to that */ + // pclog("i450KX: i450kx_reset()\n"); /* Defaults PB */ dev->pb_pci_conf[0x00] = 0x86; dev->pb_pci_conf[0x01] = 0x80; dev->pb_pci_conf[0x02] = 0xc4; dev->pb_pci_conf[0x03] = 0x84; - dev->pb_pci_conf[0x05] = 4; + dev->pb_pci_conf[0x04] = 0x07; + dev->pb_pci_conf[0x05] = 0x00; dev->pb_pci_conf[0x06] = 0x40; - dev->pb_pci_conf[0x07] = 2; - dev->pb_pci_conf[0x08] = 2; - dev->pb_pci_conf[0x0b] = 6; - dev->pb_pci_conf[0x0c] = 8; + dev->pb_pci_conf[0x07] = 0x02; + dev->pb_pci_conf[0x08] = 0x02; + dev->pb_pci_conf[0x09] = 0x00; + dev->pb_pci_conf[0x0a] = 0x00; + dev->pb_pci_conf[0x0b] = 0x06; + dev->pb_pci_conf[0x0c] = 0x08; dev->pb_pci_conf[0x0d] = 0x20; - dev->pb_pci_conf[0x49] = 0x14; - dev->pb_pci_conf[0x4c] = 0x39; - dev->pb_pci_conf[0x58] = 2; - dev->pb_pci_conf[0x59] = 0x30; - dev->pb_pci_conf[0x5a] = 0x33; - dev->pb_pci_conf[0x5b] = 0x33; - dev->pb_pci_conf[0x5c] = 0x33; - dev->pb_pci_conf[0x5d] = 0x33; - dev->pb_pci_conf[0x5e] = 0x33; - dev->pb_pci_conf[0x5f] = 0x33; - dev->pb_pci_conf[0xa4] = 1; + dev->pb_pci_conf[0x0e] = 0x00; + dev->pb_pci_conf[0x0f] = 0x00; + dev->pb_pci_conf[0x40] = 0x00; + dev->pb_pci_conf[0x41] = 0x00; + dev->pb_pci_conf[0x42] = 0x00; + dev->pb_pci_conf[0x43] = 0x00; + dev->pb_pci_conf[0x48] = 0x06; + dev->pb_pci_conf[0x49] = 0x19; + dev->pb_pci_conf[0x4a] = 0x00; + dev->pb_pci_conf[0x4b] = 0x00; + dev->pb_pci_conf[0x4c] = 0x19; + dev->pb_pci_conf[0x51] = 0x80; + dev->pb_pci_conf[0x53] = 0x00; + dev->pb_pci_conf[0x54] = 0x00; + dev->pb_pci_conf[0x55] = 0x00; + dev->pb_pci_conf[0x57] = 0x00; + dev->pb_pci_conf[0x58] = 0x02; + dev->pb_pci_conf[0x70] = 0x00; + dev->pb_pci_conf[0x71] = 0x00; + dev->pb_pci_conf[0x78] = 0x00; + dev->pb_pci_conf[0x79] = 0x00; + dev->pb_pci_conf[0x7a] = 0x00; + dev->pb_pci_conf[0x7b] = 0x00; + dev->pb_pci_conf[0x7c] = 0x00; + dev->pb_pci_conf[0x7d] = 0x00; + dev->pb_pci_conf[0x7e] = 0x00; + dev->pb_pci_conf[0x7f] = 0x00; + dev->pb_pci_conf[0x88] = 0x00; + dev->pb_pci_conf[0x89] = 0x00; + dev->pb_pci_conf[0x8a] = 0x00; + dev->pb_pci_conf[0x8b] = 0x00; + dev->pb_pci_conf[0x8c] = 0x00; + dev->pb_pci_conf[0x8d] = 0x00; + dev->pb_pci_conf[0x8e] = 0x00; + dev->pb_pci_conf[0x8f] = 0x00; + dev->pb_pci_conf[0x9c] = 0x00; + dev->pb_pci_conf[0xa4] = 0x01; dev->pb_pci_conf[0xa5] = 0xc0; dev->pb_pci_conf[0xa6] = 0xfe; - dev->pb_pci_conf[0xc8] = 3; - dev->pb_pci_conf[0xb8] = 5; + dev->pb_pci_conf[0xa7] = 0x00; + /* Note: Do NOT reset these two registers on programmed (TRC) hard reset! */ + // dev->pb_pci_conf[0xb0] = 0x00; + // dev->pb_pci_conf[0xb1] = 0x00; + dev->pb_pci_conf[0xb4] = 0x00; + dev->pb_pci_conf[0xb5] = 0x00; + dev->pb_pci_conf[0xb8] = 0x05; + dev->pb_pci_conf[0xb9] = 0x00; + dev->pb_pci_conf[0xba] = 0x00; + dev->pb_pci_conf[0xbb] = 0x00; + dev->pb_pci_conf[0xbc] = 0x01; + dev->pb_pci_conf[0xc0] = 0x02; + dev->pb_pci_conf[0xc1] = 0x00; + dev->pb_pci_conf[0xc2] = 0x00; + dev->pb_pci_conf[0xc3] = 0x00; + dev->pb_pci_conf[0xc4] = 0x00; + dev->pb_pci_conf[0xc5] = 0x00; + dev->pb_pci_conf[0xc6] = 0x00; + dev->pb_pci_conf[0xc7] = 0x00; + dev->pb_pci_conf[0xc8] = 0x03; + dev->pb_pci_conf[0xc9] = 0x00; + dev->pb_pci_conf[0xca] = 0x00; + dev->pb_pci_conf[0xcb] = 0x00; + + // pci_remap_bus(dev->bus_index, 0x00); + i450kx_smram_recalc(dev, 1); + i450kx_vid_buf_recalc(dev, 1); + pb_write(0, 0x59, 0x30, dev); + for (i = 0x5a; i <= 0x5f; i++) + pb_write(0, i, 0x33, dev); /* Defaults MC */ dev->mc_pci_conf[0x00] = 0x86; dev->mc_pci_conf[0x01] = 0x80; dev->mc_pci_conf[0x02] = 0xc5; dev->mc_pci_conf[0x03] = 0x84; + dev->mc_pci_conf[0x04] = 0x00; + dev->mc_pci_conf[0x05] = 0x00; dev->mc_pci_conf[0x06] = 0x80; - dev->mc_pci_conf[0x08] = 4; - dev->mc_pci_conf[0x0b] = 5; + dev->mc_pci_conf[0x07] = 0x00; + dev->mc_pci_conf[0x08] = 0x04; + dev->mc_pci_conf[0x09] = 0x00; + dev->mc_pci_conf[0x0a] = 0x00; + dev->mc_pci_conf[0x0b] = 0x05; dev->mc_pci_conf[0x49] = 0x14; dev->mc_pci_conf[0x4c] = 0x0b; + dev->mc_pci_conf[0x4d] = 0x08; + dev->mc_pci_conf[0x4e] = 0x00; + dev->mc_pci_conf[0x4f] = 0x00; + dev->mc_pci_conf[0x57] = 0x00; + dev->mc_pci_conf[0x58] = 0x00; + dev->mc_pci_conf[0x74] = 0x00; + dev->mc_pci_conf[0x75] = 0x00; + dev->mc_pci_conf[0x76] = 0x00; + dev->mc_pci_conf[0x77] = 0x00; dev->mc_pci_conf[0x78] = 0x10; - dev->mc_pci_conf[0xa4] = 1; + dev->mc_pci_conf[0x79] = 0x00; + dev->mc_pci_conf[0x7a] = 0x00; + dev->mc_pci_conf[0x7b] = 0x00; + dev->mc_pci_conf[0x7c] = 0x00; + dev->mc_pci_conf[0x7d] = 0x00; + dev->mc_pci_conf[0x7e] = 0x10; + dev->mc_pci_conf[0x7f] = 0x00; + dev->mc_pci_conf[0x88] = 0x00; + dev->mc_pci_conf[0x89] = 0x00; + dev->mc_pci_conf[0x8a] = 0x00; + dev->mc_pci_conf[0x8b] = 0x00; + dev->mc_pci_conf[0x8c] = 0x00; + dev->mc_pci_conf[0x8d] = 0x00; + dev->mc_pci_conf[0x8e] = 0x00; + dev->mc_pci_conf[0x8f] = 0x00; + dev->mc_pci_conf[0xa4] = 0x01; dev->mc_pci_conf[0xa5] = 0xc0; dev->mc_pci_conf[0xa6] = 0xfe; + dev->mc_pci_conf[0xa7] = 0x00; + dev->mc_pci_conf[0xa8] = 0x00; + dev->mc_pci_conf[0xa9] = 0x00; + dev->mc_pci_conf[0xaa] = 0x00; + dev->mc_pci_conf[0xab] = 0x00; dev->mc_pci_conf[0xac] = 0x16; dev->mc_pci_conf[0xad] = 0x35; dev->mc_pci_conf[0xae] = 0xdf; dev->mc_pci_conf[0xaf] = 0x30; dev->mc_pci_conf[0xb8] = 0x0a; - dev->mc_pci_conf[0xbc] = 1; + dev->mc_pci_conf[0xb9] = 0x00; + dev->mc_pci_conf[0xba] = 0x00; + dev->mc_pci_conf[0xbb] = 0x00; + dev->mc_pci_conf[0xbc] = 0x01; + dev->mc_pci_conf[0xc0] = 0x00; + dev->mc_pci_conf[0xc1] = 0x00; + dev->mc_pci_conf[0xc2] = 0x00; + dev->mc_pci_conf[0xc3] = 0x00; + dev->mc_pci_conf[0xc4] = 0x00; + dev->mc_pci_conf[0xc5] = 0x00; + dev->mc_pci_conf[0xc6] = 0x00; + dev->mc_pci_conf[0xc7] = 0x00; + + i450kx_smram_recalc(dev, 0); + i450kx_vid_buf_recalc(dev, 0); + mc_write(0, 0x59, 0x03, dev); + for (i = 0x5a; i <= 0x5f; i++) + mc_write(0, i, 0x00, dev); + for (i = 0x60; i <= 0x6f; i++) + dev->mc_pci_conf[i] = 0x01; } @@ -542,7 +780,8 @@ i450kx_close(void *priv) { i450kx_t *dev = (i450kx_t *)priv; - smram_del(dev->smram); + smram_del(dev->smram[1]); + smram_del(dev->smram[0]); free(dev); } @@ -552,10 +791,11 @@ i450kx_init(const device_t *info) { i450kx_t *dev = (i450kx_t *)malloc(sizeof(i450kx_t)); memset(dev, 0, sizeof(i450kx_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev); /* Device 19: Intel 450KX PCI Bridge PB */ - pci_add_card(PCI_ADD_NORTHBRIDGE, mc_read, mc_write, dev); /* Device 14: Intel 450KX Memory Controller MC */ + pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev); /* Device 19h: Intel 450KX PCI Bridge PB */ + pci_add_card(PCI_ADD_AGPBRIDGE, mc_read, mc_write, dev); /* Device 14h: Intel 450KX Memory Controller MC */ - dev->smram = smram_add(); + dev->smram[0] = smram_add(); + dev->smram[1] = smram_add(); cpu_cache_int_enabled = 1; cpu_cache_ext_enabled = 1; diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index f0ec758fe..9a5c72e00 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -15,7 +15,7 @@ add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c - hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_sff8038i.c) + hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c hdc_ide_sff8038i.c) add_library(zip OBJECT zip.c) diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index ad2c739cc..ac6146094 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -7,7 +7,7 @@ * This file is part of the 86Box distribution. * * Implementation of the CMD PCI-0640B controller. - + * * Authors: Miran Grca, * * Copyright 2020 Miran Grca. @@ -42,7 +42,8 @@ typedef struct { uint8_t vlb_idx, id, in_cfg, single_channel, - regs[256]; + pci, regs[256]; + uint32_t local; int slot, irq_mode[2], irq_pin, irq_line; } cmd640_t; @@ -51,15 +52,45 @@ typedef struct static int next_id = 0; +#ifdef ENABLE_CMD640_LOG +int cmd640_do_log = ENABLE_CMD640_LOG; +static void +cmd640_log(const char *fmt, ...) +{ + va_list ap; + + if (cmd640_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define cmd640_log(fmt, ...) +#endif + + void cmd640_set_irq(int channel, void *priv) { cmd640_t *dev = (cmd640_t *) priv; - dev->regs[0x50] &= ~0x04; - dev->regs[0x50] |= (channel >> 4); + int irq = !!(channel & 0x40); + + if (channel & 0x01) { + if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { + dev->regs[0x57] &= ~0x10; + dev->regs[0x57] |= (channel >> 2); + } + } else { + if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { + dev->regs[0x50] &= ~0x04; + dev->regs[0x50] |= (channel >> 4); + } + } channel &= 0x01; - if (dev->regs[0x50] & 0x04) { + if (irq) { if (dev->irq_mode[channel] == 1) pci_set_irq(dev->slot, dev->irq_pin); else @@ -196,6 +227,8 @@ cmd640_vlb_read(uint16_t addr, void *priv) ret = dev->regs[dev->vlb_idx]; if (dev->vlb_idx == 0x50) dev->regs[0x50] &= ~0x04; + else if (dev->vlb_idx == 0x57) + dev->regs[0x57] &= ~0x10; if (dev->regs[0x50] & 0x80) dev->in_cfg = 0; break; @@ -234,6 +267,8 @@ cmd640_pci_write(int func, int addr, uint8_t val, void *priv) { cmd640_t *dev = (cmd640_t *) priv; + cmd640_log("cmd640_pci_write(%i, %02X, %02X)\n", func, addr, val); + if (func == 0x00) switch (addr) { case 0x04: dev->regs[addr] = (val & 0x41); @@ -315,15 +350,20 @@ cmd640_pci_read(int func, int addr, void *priv) ret = dev->regs[addr]; if (addr == 0x50) dev->regs[0x50] &= ~0x04; + else if (addr == 0x57) + dev->regs[0x57] &= ~0x10; } + cmd640_log("cmd640_pci_read(%i, %02X, %02X)\n", func, addr, ret); + return ret; } static void -cmd640_reset(void *p) +cmd640_reset(void *priv) { + cmd640_t *dev = (cmd640_t *) priv; int i = 0; for (i = 0; i < CDROM_NUM; i++) { @@ -342,8 +382,58 @@ cmd640_reset(void *p) mo_reset((scsi_common_t *) mo_drives[i].priv); } - cmd640_set_irq(0x00, p); - cmd640_set_irq(0x01, p); + cmd640_set_irq(0x00, priv); + cmd640_set_irq(0x01, priv); + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + dev->regs[0x50] = 0x02; /* Revision 02 */ + dev->regs[0x50] |= (dev->id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */ + + dev->regs[0x59] = 0x40; + + if (dev->pci) { + cmd640_log("dev->local = %08X\n", dev->local); + if ((dev->local & 0xffff) == 0x0a) { + dev->regs[0x50] |= 0x40; /* Enable Base address register R/W; + If 0, they return 0 and are read-only 8 */ + } + + dev->regs[0x00] = 0x95; /* CMD */ + dev->regs[0x01] = 0x10; + dev->regs[0x02] = 0x40; /* PCI-0640B */ + dev->regs[0x03] = 0x06; + dev->regs[0x04] = 0x01; /* Apparently required by the ASUS PCI/I-P5SP4 AND PCI/I-P54SP4 */ + dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ + dev->regs[0x08] = 0x02; /* Revision 02 */ + dev->regs[0x09] = dev->local; /* Programming interface */ + dev->regs[0x0a] = 0x01; /* IDE controller */ + dev->regs[0x0b] = 0x01; /* Mass storage controller */ + + /* Base addresses (1F0, 3F4, 170, 374) */ + if (dev->regs[0x50] & 0x40) { + dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01; + dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03; + dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01; + dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03; + } + + dev->regs[0x3c] = 0x14; /* IRQ 14 */ + dev->regs[0x3d] = 0x01; /* INTA */ + + dev->irq_mode[0] = dev->irq_mode[1] = 0; + dev->irq_pin = PCI_INTA; + dev->irq_line = 14; + } else { + if ((dev->local & 0xffff) == 0x0078) + dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */ + + /* If bit 7 is 1, then device ID has to be written on port x78h before + accessing the configuration registers */ + dev->in_cfg = 1; /* Configuration registers are accessible */ + } + + cmd640_ide_handlers(dev); } @@ -366,45 +456,13 @@ cmd640_init(const device_t *info) dev->id = next_id | 0x60; - dev->regs[0x50] = 0x02; /* Revision 02 */ - dev->regs[0x50] |= (next_id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */ - - dev->regs[0x59] = 0x40; + dev->pci = !!(info->flags & DEVICE_PCI); + dev->local = info->local; if (info->flags & DEVICE_PCI) { - if ((info->local & 0xffff) == 0x0a) { - dev->regs[0x50] |= 0x40; /* Enable Base address register R/W; - If 0, they return 0 and are read-only 8 */ - } - - dev->regs[0x00] = 0x95; /* CMD */ - dev->regs[0x01] = 0x10; - dev->regs[0x02] = 0x40; /* PCI-0640B */ - dev->regs[0x03] = 0x06; - dev->regs[0x04] = 0x01; /* Apparently required by the ASUS PCI/I-P5SP4 AND PCI/I-P54SP4 */ - dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ - dev->regs[0x08] = 0x02; /* Revision 02 */ - dev->regs[0x09] = info->local; /* Programming interface */ - dev->regs[0x0a] = 0x01; /* IDE controller */ - dev->regs[0x0b] = 0x01; /* Mass storage controller */ - - /* Base addresses (1F0, 3F4, 170, 374) */ - if (dev->regs[0x50] & 0x40) { - dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01; - dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03; - dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01; - dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03; - } - - dev->regs[0x3c] = 0x14; /* IRQ 14 */ - dev->regs[0x3d] = 0x01; /* INTA */ - device_add(&ide_pci_2ch_device); dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev); - dev->irq_mode[0] = dev->irq_mode[1] = 0; - dev->irq_pin = PCI_INTA; - dev->irq_line = 14; ide_set_bus_master(0, NULL, cmd640_set_irq, dev); ide_set_bus_master(1, NULL, cmd640_set_irq, dev); @@ -416,12 +474,6 @@ cmd640_init(const device_t *info) // ide_pri_disable(); } else if (info->flags & DEVICE_VLB) { - if ((info->local & 0xffff) == 0x0078) - dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */ - /* If bit 7 is 1, then device ID has to be written on port x78h before - accessing the configuration registers */ - dev->in_cfg = 1; /* Configuration register are accessible */ - device_add(&ide_vlb_2ch_device); io_sethandler(info->local & 0xffff, 0x0008, @@ -432,11 +484,10 @@ cmd640_init(const device_t *info) dev->single_channel = !!(info->local & 0x20000); - if (!dev->single_channel) - ide_sec_disable(); - next_id++; + cmd640_reset(dev); + return dev; } @@ -445,7 +496,7 @@ const device_t ide_cmd640_vlb_device = { "CMD PCI-0640B VLB", DEVICE_VLB, 0x0078, - cmd640_init, cmd640_close, NULL, + cmd640_init, cmd640_close, cmd640_reset, { NULL }, NULL, NULL, NULL }; @@ -454,7 +505,7 @@ const device_t ide_cmd640_vlb_178_device = { "CMD PCI-0640B VLB (Port 178h)", DEVICE_VLB, 0x0178, - cmd640_init, cmd640_close, NULL, + cmd640_init, cmd640_close, cmd640_reset, { NULL }, NULL, NULL, NULL }; diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c new file mode 100644 index 000000000..4a8e9a176 --- /dev/null +++ b/src/disk/hdc_ide_cmd646.c @@ -0,0 +1,435 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CMD PCI-0646 controller. + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/cdrom.h> +#include <86box/scsi_device.h> +#include <86box/scsi_cdrom.h> +#include <86box/dma.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/timer.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/zip.h> +#include <86box/mo.h> + + +typedef struct +{ + uint8_t vlb_idx, single_channel, + in_cfg, regs[256]; + uint32_t local; + int slot, irq_mode[2], + irq_pin; + sff8038i_t *bm[2]; +} cmd646_t; + + +#ifdef ENABLE_CMD646_LOG +int cmd646_do_log = ENABLE_CMD646_LOG; +static void +cmd646_log(const char *fmt, ...) +{ + va_list ap; + + if (cmd646_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define cmd646_log(fmt, ...) +#endif + + +static void +cmd646_set_irq(int channel, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + + if (channel & 0x01) { + if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { + dev->regs[0x57] &= ~0x10; + dev->regs[0x57] |= (channel >> 2); + } + } else { + if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { + dev->regs[0x50] &= ~0x04; + dev->regs[0x50] |= (channel >> 4); + } + } + + sff_bus_master_set_irq(channel, dev->bm[channel & 0x01]); +} + + +static int +cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + + return sff_bus_master_dma(channel, data, transfer_length, out, dev->bm[channel & 0x01]); +} + + +static void +cmd646_ide_handlers(cmd646_t *dev) +{ + uint16_t main, side; + int irq_mode[2] = { 0, 0 }; + + ide_pri_disable(); + + if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) { + main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8); + side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2; + } else { + main = 0x1f0; + side = 0x3f6; + } + + ide_set_base(0, main); + ide_set_side(0, side); + + if (dev->regs[0x09] & 0x01) + irq_mode[0] = 1; + + sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]); + sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]); + + if (dev->regs[0x04] & 0x01) + ide_pri_enable(); + + if (dev->single_channel) + return; + + ide_sec_disable(); + + if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) { + main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8); + side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2; + } else { + main = 0x170; + side = 0x376; + } + + ide_set_base(1, main); + ide_set_side(1, side); + + if (dev->regs[0x09] & 0x04) + irq_mode[1] = 1; + + sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]); + sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]); + + if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) + ide_sec_enable(); + +} + + +static void +cmd646_ide_bm_handlers(cmd646_t *dev) +{ + uint16_t base = (dev->regs[0x20] & 0xf0) | (dev->regs[0x21] << 8); + + sff_bus_master_handler(dev->bm[0], (dev->regs[0x04] & 1), base); + sff_bus_master_handler(dev->bm[1], (dev->regs[0x04] & 1), base + 8); +} + + +static void +cmd646_pci_write(int func, int addr, uint8_t val, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + + cmd646_log("[%04X:%08X] (%08X) cmd646_pci_write(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, val); + + if (func == 0x00) switch (addr) { + case 0x04: + dev->regs[addr] = (val & 0x45); + cmd646_ide_handlers(dev); + break; + case 0x07: + dev->regs[addr] &= ~(val & 0xb1); + break; + case 0x09: + if ((dev->regs[addr] & 0x0a) == 0x0a) { + dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05); + dev->irq_mode[0] = !!(val & 0x01); + dev->irq_mode[1] = !!(val & 0x04); + cmd646_ide_handlers(dev); + } + break; + case 0x10: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x10] = (val & 0xf8) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x11: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x11] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x14: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x14] = (val & 0xfc) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x15: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x15] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x18: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x18] = (val & 0xf8) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x19: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x19] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x1c: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x1c] = (val & 0xfc) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x1d: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x1d] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x20: + dev->regs[0x20] = (val & 0xf0) | 1; + cmd646_ide_bm_handlers(dev); + break; + case 0x21: + dev->regs[0x21] = val; + cmd646_ide_bm_handlers(dev); + break; + case 0x51: + dev->regs[addr] = val & 0xc8; + cmd646_ide_handlers(dev); + break; + case 0x52: case 0x54: case 0x56: case 0x58: + case 0x59: case 0x5b: + dev->regs[addr] = val; + break; + case 0x53: case 0x55: + dev->regs[addr] = val & 0xc0; + break; + case 0x57: + dev->regs[addr] = (dev->regs[addr] & 0x10) | (val & 0xcc); + break; + case 0x70 ... 0x77: + sff_bus_master_write(addr & 0x0f, val, dev->bm[0]); + break; + case 0x78 ... 0x7f: + sff_bus_master_write(addr & 0x0f, val, dev->bm[1]); + break; + } +} + + +static uint8_t +cmd646_pci_read(int func, int addr, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) { + ret = dev->regs[addr]; + + if (addr == 0x50) + dev->regs[0x50] &= ~0x04; + else if (addr == 0x57) + dev->regs[0x57] &= ~0x10; + else if ((addr >= 0x70) && (addr <= 0x77)) + ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]); + else if ((addr >= 0x78) && (addr <= 0x7f)) + ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]); + } + + cmd646_log("[%04X:%08X] (%08X) cmd646_pci_read(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, ret); + + return ret; +} + + +static void +cmd646_reset(void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + int i = 0; + + for (i = 0; i < CDROM_NUM; i++) { + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && + (cdrom[i].ide_channel < 4) && cdrom[i].priv) + scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); + } + for (i = 0; i < ZIP_NUM; i++) { + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && + (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) + zip_reset((scsi_common_t *) zip_drives[i].priv); + } + for (i = 0; i < MO_NUM; i++) { + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && + (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) + mo_reset((scsi_common_t *) mo_drives[i].priv); + } + + cmd646_set_irq(0x00, priv); + cmd646_set_irq(0x01, priv); + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + dev->regs[0x00] = 0x95; /* CMD */ + dev->regs[0x01] = 0x10; + dev->regs[0x02] = 0x46; /* PCI-0646 */ + dev->regs[0x03] = 0x06; + dev->regs[0x04] = 0x00; + dev->regs[0x06] = 0x80; + dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ + dev->regs[0x09] = dev->local; /* Programming interface */ + dev->regs[0x0a] = 0x01; /* IDE controller */ + dev->regs[0x0b] = 0x01; /* Mass storage controller */ + + if ((dev->local & 0xffff) == 0x8a) { + dev->regs[0x50] = 0x40; /* Enable Base address register R/W; + If 0, they return 0 and are read-only 8 */ + + /* Base addresses (1F0, 3F4, 170, 374) */ + dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01; + dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03; + dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01; + dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03; + } + + dev->regs[0x20] = 0x01; + + dev->regs[0x3c] = 0x0e; /* IRQ 14 */ + dev->regs[0x3d] = 0x01; /* INTA */ + dev->regs[0x3e] = 0x02; /* Min_Gnt */ + dev->regs[0x3f] = 0x04; /* Max_Iat */ + + if (!dev->single_channel) + dev->regs[0x51] = 0x08; + + dev->regs[0x57] = 0x0c; + dev->regs[0x59] = 0x40; + + dev->irq_mode[0] = dev->irq_mode[1] = 0; + dev->irq_pin = PCI_INTA; + + cmd646_ide_handlers(dev); + cmd646_ide_bm_handlers(dev); +} + + +static void +cmd646_close(void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + + free(dev); +} + + +static void * +cmd646_init(const device_t *info) +{ + cmd646_t *dev = (cmd646_t *) malloc(sizeof(cmd646_t)); + memset(dev, 0x00, sizeof(cmd646_t)); + + dev->local = info->local; + + device_add(&ide_pci_2ch_device); + + dev->slot = pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev); + + dev->single_channel = !!(info->local & 0x20000); + + dev->bm[0] = device_add_inst(&sff8038i_device, 1); + if (!dev->single_channel) + dev->bm[1] = device_add_inst(&sff8038i_device, 2); + + ide_set_bus_master(0, cmd646_bus_master_dma, cmd646_set_irq, dev); + if (!dev->single_channel) + ide_set_bus_master(1, cmd646_bus_master_dma, cmd646_set_irq, dev); + + sff_set_irq_mode(dev->bm[0], 0, 0); + sff_set_irq_mode(dev->bm[0], 1, 0); + + if (!dev->single_channel) { + sff_set_irq_mode(dev->bm[1], 0, 0); + sff_set_irq_mode(dev->bm[1], 1, 0); + } + + cmd646_reset(dev); + + return dev; +} + + +const device_t ide_cmd646_device = { + "CMD PCI-0646", + DEVICE_PCI, + 0x8a, + cmd646_init, cmd646_close, cmd646_reset, + { NULL }, NULL, NULL, + NULL +}; + +const device_t ide_cmd646_legacy_only_device = { + "CMD PCI-0646 (Legacy Mode Only)", + DEVICE_PCI, + 0x80, + cmd646_init, cmd646_close, cmd646_reset, + { NULL }, NULL, NULL, + NULL +}; + +const device_t ide_cmd646_single_channel_device = { + "CMD PCI-0646", + DEVICE_PCI, + 0x2008a, + cmd646_init, cmd646_close, cmd646_reset, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 44d9ad545..8fe9fec88 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -47,10 +47,10 @@ static int next_id = 0; -static uint8_t sff_bus_master_read(uint16_t port, void *priv); +uint8_t sff_bus_master_read(uint16_t port, void *priv); static uint16_t sff_bus_master_readw(uint16_t port, void *priv); static uint32_t sff_bus_master_readl(uint16_t port, void *priv); -static void sff_bus_master_write(uint16_t port, uint8_t val, void *priv); +void sff_bus_master_write(uint16_t port, uint8_t val, void *priv); static void sff_bus_master_writew(uint16_t port, uint16_t val, void *priv); static void sff_bus_master_writel(uint16_t port, uint32_t val, void *priv); @@ -112,7 +112,7 @@ sff_bus_master_next_addr(sff8038i_t *dev) } -static void +void sff_bus_master_write(uint16_t port, uint8_t val, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; @@ -138,6 +138,9 @@ sff_bus_master_write(uint16_t port, uint8_t val, void *priv) dev->command = val; break; + case 1: + dev->dma_mode = val & 0x03; + break; case 2: sff_log("sff Status: val = %02X, old = %02X\n", val, dev->status); dev->status &= 0x07; @@ -177,6 +180,7 @@ sff_bus_master_writew(uint16_t port, uint16_t val, void *priv) switch (port & 7) { case 0: + case 1: case 2: sff_bus_master_write(port, val & 0xff, priv); break; @@ -202,6 +206,7 @@ sff_bus_master_writel(uint16_t port, uint32_t val, void *priv) switch (port & 7) { case 0: + case 1: case 2: sff_bus_master_write(port, val & 0xff, priv); break; @@ -214,7 +219,7 @@ sff_bus_master_writel(uint16_t port, uint32_t val, void *priv) } -static uint8_t +uint8_t sff_bus_master_read(uint16_t port, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; @@ -225,6 +230,9 @@ sff_bus_master_read(uint16_t port, void *priv) case 0: ret = dev->command; break; + case 1: + ret = dev->dma_mode & 0x03; + break; case 2: ret = dev->status & 0x67; break; @@ -257,6 +265,7 @@ sff_bus_master_readw(uint16_t port, void *priv) switch (port & 7) { case 0: + case 1: case 2: ret = (uint16_t) sff_bus_master_read(port, priv); break; @@ -283,6 +292,7 @@ sff_bus_master_readl(uint16_t port, void *priv) switch (port & 7) { case 0: + case 1: case 2: ret = (uint32_t) sff_bus_master_read(port, priv); break; @@ -297,7 +307,7 @@ sff_bus_master_readl(uint16_t port, void *priv) } -static int +int sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; @@ -311,8 +321,10 @@ sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, voi sop = out ? "Read" : "Writ"; #endif - if (!(dev->status & 1)) + if (!(dev->status & 1)) { + sff_log("DMA disabled\n"); return 2; /*DMA disabled*/ + } sff_log("SFF-8038i Bus master %s: %i bytes\n", out ? "write" : "read", transfer_length); diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 00160ae13..ae97b156e 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -83,10 +83,7 @@ extern const device_t i440bx_device; extern const device_t i440bx_no_agp_device; extern const device_t i440gx_device; extern const device_t i440zx_device; - -#if defined(DEV_BRANCH) && defined(USE_I450KX) extern const device_t i450kx_device; -#endif extern const device_t sio_device; extern const device_t sio_zb_device; @@ -133,6 +130,7 @@ extern const device_t stpc_serial_device; extern const device_t stpc_lpt_device; /* UMC */ +extern const device_t umc_um82c49x_device; extern const device_t umc_8886f_device; extern const device_t umc_8886af_device; extern const device_t umc_hb4_device; diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 9175dddaf..1008b38c9 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -56,6 +56,9 @@ extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h extern const device_t ide_cmd640_pci_device; /* CMD PCI-640B PCI */ extern const device_t ide_cmd640_pci_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only) */ extern const device_t ide_cmd640_pci_single_channel_device; /* CMD PCI-640B PCI (Only primary channel) */ +extern const device_t ide_cmd646_device; /* CMD PCI-646 */ +extern const device_t ide_cmd646_legacy_only_device; /* CMD PCI-646 (Legacy Mode Only) */ +extern const device_t ide_cmd646_single_channel_device; /* CMD PCI-646 (Only primary channel) */ extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ diff --git a/src/include/86box/hdc_ide_sff8038i.h b/src/include/86box/hdc_ide_sff8038i.h index 305d2d40c..700684dae 100644 --- a/src/include/86box/hdc_ide_sff8038i.h +++ b/src/include/86box/hdc_ide_sff8038i.h @@ -19,8 +19,10 @@ typedef struct { uint8_t command, status, - ptr0, enabled; - uint16_t base, pad; + ptr0, enabled, + dma_mode, pad, + pad0, pad1; + uint16_t base, pad2; uint32_t ptr, ptr_cur, addr; int count, eot, @@ -39,6 +41,11 @@ extern int sff_bus_master_dma_write(int channel, uint8_t *data, int transfer_len extern void sff_bus_master_set_irq(int channel, void *priv); +extern int sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv); + +extern void sff_bus_master_write(uint16_t port, uint8_t val, void *priv); +extern uint8_t sff_bus_master_read(uint16_t port, void *priv); + extern void sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base); extern void sff_set_slot(sff8038i_t *dev, int slot); diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index efedfc6e4..2767789b3 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -539,9 +539,7 @@ extern int machine_at_ficva503a_init(const machine_t *); extern int machine_at_sy_5ema_pro_init(const machine_t *); /* m_at_socket8.c */ -#if defined(DEV_BRANCH) && defined(USE_I450KX) extern int machine_at_p6rp4_init(const machine_t *); -#endif extern int machine_at_686nx_init(const machine_t *); extern int machine_at_v60n_init(const machine_t *); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index dfcbef242..5d1f6848c 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -145,10 +145,18 @@ mem_set_access(ACCESS_SMM, 0, base, size, access) #define mem_set_mem_state_both(base, size, access) \ mem_set_access(ACCESS_ALL, 0, base, size, access) +#define mem_set_mem_state_cpu_both(base, size, access) \ + mem_set_access(ACCESS_CPU_BOTH, 0, base, size, access) +#define mem_set_mem_state_bus_both(base, size, access) \ + mem_set_access(ACCESS_BUS_BOTH, 0, base, size, access) #define mem_set_mem_state_smram(smm, base, size, is_smram) \ mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), 1, base, size, is_smram) #define mem_set_mem_state_smram_ex(smm, base, size, is_smram) \ mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), 2, base, size, is_smram) +#define mem_set_access_smram_cpu(smm, base, size, is_smram) \ + mem_set_access((smm ? ACCESS_CPU_SMM : ACCESS_CPU), 1, base, size, is_smram) +#define mem_set_access_smram_bus(smm, base, size, is_smram) \ + mem_set_access((smm ? ACCESS_BUS_SMM : ACCESS_BUS), 1, base, size, is_smram) #define flushmmucache_cr3 \ flushmmucache_nopc diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index f1776bf79..386954b54 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -95,6 +95,7 @@ extern const device_t piix4_nvr_device; extern const device_t ls486e_nvr_device; extern const device_t ami_apollo_nvr_device; extern const device_t via_nvr_device; +extern const device_t p6rp4_nvr_device; #endif diff --git a/src/include/86box/smram.h b/src/include/86box/smram.h index 6fc89971e..996e5df30 100644 --- a/src/include/86box/smram.h +++ b/src/include/86box/smram.h @@ -39,12 +39,19 @@ extern void smram_recalc_all(int ret); extern void smram_del(smram_t *smr); /* Add a SMRAM mapping. */ extern smram_t *smram_add(void); +/* Set memory state in the specified model (normal or SMM) according to the specified flags, + separately for bus and CPU. */ +extern void smram_map_ex(int bus, int smm, uint32_t addr, uint32_t size, int is_smram); /* Set memory state in the specified model (normal or SMM) according to the specified flags. */ extern void smram_map(int smm, uint32_t addr, uint32_t size, int is_smram); /* Disable a specific SMRAM mapping. */ extern void smram_disable(smram_t *smr); /* Disable all SMRAM mappings. */ extern void smram_disable_all(void); +/* Enable SMRAM mappings according to flags for both normal and SMM modes, separately for bus + and CPU. */ +extern void smram_enable_ex(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, + int flags_normal, int flags_normal_bus, int flags_smm, int flags_smm_bus); /* Enable SMRAM mappings according to flags for both normal and SMM modes. */ extern void smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, int flags_normal, int flags_smm); diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index 6643566ee..c20d21a75 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -28,10 +28,6 @@ if(HEDAKA) target_compile_definitions(mch PRIVATE USE_HEDAKA) endif() -if(I450KX) - target_compile_definitions(mch PRIVATE USE_I450KX) -endif() - if(LASERXT) target_sources(mch PRIVATE m_xt_laserxt.c) target_compile_definitions(mch PRIVATE USE_LASERXT) diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index ab3bc05b7..8067e17b0 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -30,6 +30,8 @@ #include <86box/hdc_ide.h> #include <86box/keyboard.h> #include <86box/flash.h> +#include <86box/timer.h> +#include <86box/nvr.h> #include <86box/sio.h> #include <86box/hwm.h> #include <86box/spd.h> @@ -37,7 +39,7 @@ #include "cpu.h" #include <86box/machine.h> -#if defined(DEV_BRANCH) && defined(USE_I450KX) + int machine_at_p6rp4_init(const machine_t *model) { @@ -49,11 +51,12 @@ machine_at_p6rp4_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + device_add(&p6rp4_nvr_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x19, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x12, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_IDE, 0, 0, 0, 0); pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -62,16 +65,15 @@ machine_at_p6rp4_init(const machine_t *model) pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i450kx_device); device_add(&sio_zb_device); - // device_add(&keyboard_ps2_ami_pci_device); + device_add(&ide_cmd646_device); /* Input port bit 2 must be 1 or CMOS Setup is disabled. */ device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c665_device); - device_add(&ide_cmd640_pci_device); device_add(&intel_flash_bxt_device); return ret; } -#endif + int machine_at_686nx_init(const machine_t *model) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 239fd2f41..0f2479961 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -398,6 +398,8 @@ const machine_t machines[] = { { "[SiS 471] DTK PKM-0038S E-2", "dtk486", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_dtk486_init, NULL }, /* Unknown Epox VLB Socket 3 board, has AMIKey F keyboard BIOS. */ { "[SiS 471] Epox 486SX/DX Green", "ami471", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_ami471_init, NULL }, + /* Has an Intel 82C42PE with Phoenix MultiKey KBC firmware. */ + { "[UMC 491/493] Epson Action Tower 3000", "actiontower3000", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 262144, 1024, 255, machine_at_actiontower3000_init, NULL }, /* 486 machines which utilize the PCI bus */ /* This has an AMIKey-2, which is an updated version of type 'H'. */ @@ -750,10 +752,8 @@ const machine_t machines[] = { /* Socket 8 machines */ /* 450KX */ -#if defined(DEV_BRANCH) && defined(USE_I450KX) /* This has an AMIKey-2, which is an updated version of type 'H'. */ { "[i450KX] ASUS P/I-P6RP4", "p6rp4", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 1.5, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_p6rp4_init, NULL }, -#endif /* 440FX */ /* Has the SMC FDC73C935's on-chip KBC with Phoenix MultiKey firmware. */ diff --git a/src/mem/mem.c b/src/mem/mem.c index de6e0a60b..da2e1f31e 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2247,6 +2247,12 @@ mem_mapping_access_allowed(uint32_t flags, uint16_t access) ret = ret && !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM); } else ret = !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM); + } else { + /* Still allow SMRAM if access is DISABLED but also has CACHE and/or SMRAM flags set. */ + if (access & ACCESS_CACHE) + ret = (flags & MEM_MAPPING_CACHE); + else if (access & ACCESS_SMRAM) + ret = (flags & MEM_MAPPING_SMRAM); } return ret; diff --git a/src/mem/smram.c b/src/mem/smram.c index 8e405af8a..8b1f9fd40 100644 --- a/src/mem/smram.c +++ b/src/mem/smram.c @@ -287,11 +287,24 @@ smram_add(void) } +/* Set memory state in the specified model (normal or SMM) according to the specified flags, + separately for bus and CPU. */ +void +smram_map_ex(int bus, int smm, uint32_t addr, uint32_t size, int is_smram) +{ + if (bus) + mem_set_access_smram_bus(smm, addr, size, is_smram); + else + mem_set_access_smram_cpu(smm, addr, size, is_smram); +} + + /* Set memory state in the specified model (normal or SMM) according to the specified flags. */ void smram_map(int smm, uint32_t addr, uint32_t size, int is_smram) { - mem_set_mem_state_smram(smm, addr, size, is_smram); + smram_map_ex(0, smm, addr, size, is_smram); + smram_map_ex(1, smm, addr, size, is_smram); } @@ -331,9 +344,11 @@ smram_disable_all(void) } -/* Enable SMRAM mappings according to flags for both normal and SMM modes. */ +/* Enable SMRAM mappings according to flags for both normal and SMM modes, separately for bus + and CPU. */ void -smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, int flags_normal, int flags_smm) +smram_enable_ex(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, + int flags_normal, int flags_normal_bus, int flags_smm, int flags_smm_bus) { if (smr == NULL) { fatal("smram_add(): Invalid SMRAM mapping\n"); @@ -362,13 +377,23 @@ smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, mem_mapping_set_exec(&(smr->mapping), smram + 0x30000); } - smram_map(0, host_base, size, flags_normal); - smram_map(1, host_base, size, flags_smm); + smram_map_ex(0, 0, host_base, size, flags_normal); + smram_map_ex(1, 0, host_base, size, flags_normal_bus); + smram_map_ex(0, 1, host_base, size, flags_smm); + smram_map_ex(1, 1, host_base, size, flags_smm_bus); } else smram_disable(smr); } +/* Enable SMRAM mappings according to flags for both normal and SMM modes. */ +void +smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, int flags_normal, int flags_smm) +{ + smram_enable_ex(smr, host_base, ram_base, size, flags_normal, flags_normal, flags_smm, flags_smm); +} + + /* Checks if a SMRAM mapping is enabled or not. */ int smram_enabled(smram_t *smr) diff --git a/src/nvr_at.c b/src/nvr_at.c index 1942f1c1f..03f3ea6bb 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -292,7 +292,8 @@ #define FLAG_LS_HACK 0x01 #define FLAG_APOLLO_HACK 0x02 -#define FLAG_PIIX4 0x04 +#define FLAG_P6RP4_HACK 0x04 +#define FLAG_PIIX4 0x08 typedef struct { @@ -755,10 +756,31 @@ nvr_read(uint16_t addr, void *priv) ret = checksum >> 8; else ret = checksum & 0xff; + } else if (!nvr->new && (local->flags & FLAG_P6RP4_HACK)) { + /* The checksum at 3E-3F is for 37-3D and 40-51. */ + for (i = 0x37; i <= 0x3d; i++) + checksum += nvr->regs[i]; + for (i = 0x40; i <= 0x51; i++) { + if (i == 0x43) + checksum += (nvr->regs[i] | 0x02); + else + checksum += nvr->regs[i]; + } + if (local->addr[addr_id] == 0x3e) + ret = checksum >> 8; + else + ret = checksum & 0xff; } else ret = nvr->regs[local->addr[addr_id]]; break; + case 0x43: + if (!nvr->new && (local->flags & FLAG_P6RP4_HACK)) + ret = nvr->regs[local->addr[addr_id]] | 0x02; + else + ret = nvr->regs[local->addr[addr_id]]; + break; + case 0x52: if (!nvr->new && (local->flags & FLAG_APOLLO_HACK)) ret = nvr->regs[local->addr[addr_id]] & 0xf3; @@ -972,8 +994,14 @@ nvr_at_init(const device_t *info) local->flags = 0x00; switch(info->local & 7) { case 0: /* standard AT, no century register */ - nvr->irq = 8; - local->cent = 0xff; + if (info->local == 16) { + local->flags |= FLAG_P6RP4_HACK; + nvr->irq = 8; + local->cent = RTC_CENTURY_AT; + } else { + nvr->irq = 8; + local->cent = 0xff; + } break; case 1: /* standard AT */ @@ -1162,3 +1190,12 @@ const device_t via_nvr_device = { { NULL }, nvr_at_speed_changed, NULL }; + +const device_t p6rp4_nvr_device = { + "ASUS P/I-P6RP4 PC/AT NVRAM", + DEVICE_ISA | DEVICE_AT, + 16, + nvr_at_init, nvr_at_close, nvr_at_reset, + { NULL }, nvr_at_speed_changed, + NULL +}; diff --git a/src/pci.c b/src/pci.c index 37c9976a5..fc6e1e75e 100644 --- a/src/pci.c +++ b/src/pci.c @@ -150,6 +150,80 @@ pci_write(uint16_t port, uint8_t val, void *priv) } +static void +pci_writew(uint16_t port, uint16_t val, void *priv) +{ + uint8_t slot = 0; + + if (in_smm) + pci_log("(%i) %03x write: %02X\n", pci_enable, port, val); + + switch (port) { + case 0xcfc: case 0xcfe: + if (! pci_enable) + return; + + pci_log("Writing %04X to PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", val, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != 0xff) { + if (pci_cards[slot].write) { + pci_log("Writing to PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); + pci_cards[slot].write(pci_func, pci_index | (port & 3), val & 0xff, pci_cards[slot].priv); + pci_cards[slot].write(pci_func, pci_index | (port & 3) | 1, val >> 8, pci_cards[slot].priv); + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + + break; + } +} + + +static void +pci_writel(uint16_t port, uint32_t val, void *priv) +{ + uint8_t slot = 0; + + if (in_smm) + pci_log("(%i) %03x write: %02X\n", pci_enable, port, val); + + switch (port) { + case 0xcfc: + if (! pci_enable) + return; + + pci_log("Writing %08X to PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", val, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != 0xff) { + if (pci_cards[slot].write) { + pci_log("Writing to PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); + pci_cards[slot].write(pci_func, pci_index | (port & 3), val & 0xff, pci_cards[slot].priv); + pci_cards[slot].write(pci_func, pci_index | (port & 3) | 1, (val >> 8) & 0xff, pci_cards[slot].priv); + pci_cards[slot].write(pci_func, pci_index | (port & 3) | 2, (val >> 16) & 0xff, pci_cards[slot].priv); + pci_cards[slot].write(pci_func, pci_index | (port & 3) | 3, (val >> 24) & 0xff, pci_cards[slot].priv); + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + + break; + } +} + + static uint8_t pci_read(uint16_t port, void *priv) { @@ -185,6 +259,82 @@ pci_read(uint16_t port, void *priv) } +static uint16_t +pci_readw(uint16_t port, void *priv) +{ + uint8_t slot = 0; + uint16_t ret = 0xffff; + + if (in_smm) + pci_log("(%i) %03x read\n", pci_enable, port); + + switch (port) { + case 0xcfc: case 0xcfe: + if (! pci_enable) + return 0xff; + + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != 0xff) { + if (pci_cards[slot].read) { + ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); + ret |= (pci_cards[slot].read(pci_func, pci_index | (port & 3) | 1, pci_cards[slot].priv) << 8); + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } + + pci_log("Reading %04X, from PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", ret, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); + + return ret; +} + + +static uint32_t +pci_readl(uint16_t port, void *priv) +{ + uint8_t slot = 0; + uint32_t ret = 0xffffffff; + + if (in_smm) + pci_log("(%i) %03x read\n", pci_enable, port); + + switch (port) { + case 0xcfc: case 0xcfe: + if (! pci_enable) + return 0xff; + + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != 0xff) { + if (pci_cards[slot].read) { + ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); + ret |= (pci_cards[slot].read(pci_func, pci_index | (port & 3) | 1, pci_cards[slot].priv) << 8); + ret |= (pci_cards[slot].read(pci_func, pci_index | (port & 3) | 2, pci_cards[slot].priv) << 16); + ret |= (pci_cards[slot].read(pci_func, pci_index | (port & 3) | 3, pci_cards[slot].priv) << 24); + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } + + pci_log("Reading %08X, from PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", ret, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); + + return ret; +} + + static void pci_type2_write(uint16_t port, uint8_t val, void *priv); static uint8_t pci_type2_read(uint16_t port, void *priv); @@ -803,7 +953,7 @@ pci_init(int type) io_sethandler(0x0cf8, 1, NULL,NULL,pci_cf8_read, NULL,NULL,pci_cf8_write, NULL); io_sethandler(0x0cfc, 4, - pci_read,NULL,NULL, pci_write,NULL,NULL, NULL); + pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); pci_pmc = 1; } else { io_sethandler(0x0cf8, 1, diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index ce9b9852c..a69413596 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -160,6 +160,7 @@ static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | + (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES); @@ -180,7 +181,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default = { 0, 0 }, { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0, 0 }, + { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -227,7 +228,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_scsi = { 0, 0 }, { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, { 0x8E, 0xE, 5, 4, 0,128, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0, 0 }, + { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -261,7 +262,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = { { { 0, 0 }, { GPMODE_R_W_ERROR_PAGE, 6, 0xFF, 0xFF, 0, 0, 0, 0 }, - { GPMODE_DISCONNECT_PAGE, 0x0e, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }, + { GPMODE_DISCONNECT_PAGE, 0x0E, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -274,7 +275,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = { 0, 0 }, { GPMODE_CDROM_PAGE, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0x8E, 0xE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0, 0 }, + { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index b7680640f..068562028 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -45,9 +45,6 @@ ifeq ($(DEV_BUILD), y) ifndef HEDAKA HEDAKA := y endif - ifndef I450KX - I450KX := y - endif ifndef LASERXT LASERXT := y endif @@ -109,9 +106,6 @@ else ifndef HEDAKA HEDAKA := n endif - ifndef I450KX - I450KX := n - endif ifndef LASERXT LASERXT := n endif @@ -501,11 +495,6 @@ ifeq ($(HEDAKA), y) OPTS += -DUSE_HEDAKA endif -ifeq ($(I450KX), y) -OPTS += -DUSE_I450KX -DEVBROBJ += intel_i450kx.o -endif - ifeq ($(LASERXT), y) OPTS += -DUSE_LASERXT DEVBROBJ += m_xt_laserxt.o @@ -593,7 +582,8 @@ CHIPSETOBJ := 82c100.o acc2168.o \ cs4031.o cs8230.o \ ali1429.o ali1489.o ali1531.o ali1541.o ali1543.o ali1621.o ali6117.o \ gc100.o headland.o \ - ims8848.o intel_82335.o intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ + ims8848.o intel_82335.o intel_420ex.o intel_4x0.o intel_i450kx.o intel_sio.o intel_piix.o \ + ioapic.o \ neat.o \ opti283.o opti291.o opti391.o opti495.o opti822.o opti895.o opti5x7.o \ scamp.o scat.o \ @@ -674,7 +664,8 @@ HDDOBJ := hdd.o \ hdc_esdi_at.o hdc_esdi_mca.o \ hdc_xtide.o hdc_ide.o \ hdc_ide_opti611.o \ - hdc_ide_cmd640.o hdc_ide_sff8038i.o + hdc_ide_cmd640.o hdc_ide_cmd646.o \ + hdc_ide_sff8038i.o MINIVHDOBJ := cwalk.o libxml2_encoding.o minivhd_convert.o \ minivhd_create.o minivhd_io.o minivhd_manage.o \