diff --git a/CMakeLists.txt b/CMakeLists.txt index 070ebac67..de77160e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,7 +191,6 @@ cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) -cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) diff --git a/src/acpi.c b/src/acpi.c index ccd51ebca..e9549adb0 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -2387,6 +2387,14 @@ acpi_reset(void *priv) dev->regs.gpi_val = 0xfff57fc1; if (!strcmp(machine_get_internal_name(), "ficva503a") || !strcmp(machine_get_internal_name(), "6via90ap")) dev->regs.gpi_val |= 0x00000004; + /* + TriGem Delhi-III second GPI word: + - Bit 7 = Save CMOS (must be set); + - Bit 6 = Password jumper (must be set); + - Bit 5 = Enable Setup (must be set). + */ + else if (!strcmp(machine_get_internal_name(), "delhi3")) + dev->regs.gpi_val |= 0x00008000; } if (acpi_power_on) { diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 519afaa4c..6bc284fd3 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -2016,6 +2016,10 @@ image_open(cdrom_t *dev, const char *path) img->has_audio = 0; else if (ret) img->has_audio = 1; + else { + image_close(img); + img = NULL; + } } else { ret = image_load_iso(img, path); @@ -2033,7 +2037,8 @@ image_open(cdrom_t *dev, const char *path) img->log = log_open(n); dev->ops = &image_ops; - } + } else + warning("Unable to load CD-ROM image: %s\n", path); } return img; diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index 4bf976794..cf132c560 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -782,9 +782,8 @@ viso_close(void *priv) if (viso->entry_map) free(viso->entry_map); - if (tf->log != NULL) { - - } + if (tf->log != NULL) + log_close(tf->log); free(viso); } @@ -1607,10 +1606,12 @@ end: return &viso->tf; } else { - image_viso_log(viso->tf.log, "Initialization failed\n"); - if (data) - free(data); - viso_close(&viso->tf); + if (viso != NULL) { + image_viso_log(viso->tf.log, "Initialization failed\n"); + if (data) + free(data); + viso_close(&viso->tf); + } return NULL; } } diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 6969d3274..ed9fd9460 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -59,7 +59,6 @@ typedef struct piix_io_trap_t { } piix_io_trap_t; typedef struct _piix_ { - uint8_t cur_readout_reg; uint8_t rev; uint8_t type; uint8_t func_shift; @@ -67,7 +66,6 @@ typedef struct _piix_ { uint8_t pci_slot; uint8_t no_mirq0; uint8_t regs[4][256]; - uint8_t readout_regs[256]; uint16_t func0_id; uint16_t nvr_io_base; uint16_t acpi_io_base; @@ -1185,31 +1183,6 @@ piix_read(int func, int addr, void *priv) return ret; } -static void -board_write(uint16_t port, uint8_t val, void *priv) -{ - piix_t *dev = (piix_t *) priv; - - if (port == 0x00e0) - dev->cur_readout_reg = val; - else if (port == 0x00e1) - dev->readout_regs[dev->cur_readout_reg] = val; -} - -static uint8_t -board_read(uint16_t port, void *priv) -{ - const piix_t *dev = (piix_t *) priv; - uint8_t ret = 0x64; - - if (port == 0x00e0) - ret = dev->cur_readout_reg; - else if (port == 0x00e1) - ret = dev->readout_regs[dev->cur_readout_reg]; - - return ret; -} - static void piix_reset_hard(piix_t *dev) { @@ -1624,40 +1597,6 @@ piix_init(const device_t *info) if (dev->type < 3) pci_enable_mirq(1); - dev->readout_regs[0] = 0xff; - dev->readout_regs[1] = 0x40; - dev->readout_regs[2] = 0xff; - - /* Port E1 register 01 (TODO: Find how multipliers > 3.0 are defined): - - Bit 6: 1 = can boot, 0 = no; - Bit 7, 1 = multiplier (00 = 2.5, 01 = 2.0, 10 = 3.0, 11 = 1.5); - Bit 5, 4 = bus speed (00 = 50 MHz, 01 = 66 MHz, 10 = 60 MHz, 11 = ????): - Bit 7, 5, 4, 1: 0000 = 125 MHz, 0010 = 166 MHz, 0100 = 150 MHz, 0110 = ??? MHz; - 0001 = 100 MHz, 0011 = 133 MHz, 0101 = 120 MHz, 0111 = ??? MHz; - 1000 = 150 MHz, 1010 = 200 MHz, 1100 = 180 MHz, 1110 = ??? MHz; - 1001 = 75 MHz, 1011 = 100 MHz, 1101 = 90 MHz, 1111 = ??? MHz */ - - if (cpu_busspeed <= 40000000) - dev->readout_regs[1] |= 0x30; - else if ((cpu_busspeed > 40000000) && (cpu_busspeed <= 50000000)) - dev->readout_regs[1] |= 0x00; - else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) - dev->readout_regs[1] |= 0x20; - else if (cpu_busspeed > 60000000) - dev->readout_regs[1] |= 0x10; - - if (cpu_dmulti <= 1.5) - dev->readout_regs[1] |= 0x82; - else if ((cpu_dmulti > 1.5) && (cpu_dmulti <= 2.0)) - dev->readout_regs[1] |= 0x02; - else if ((cpu_dmulti > 2.0) && (cpu_dmulti <= 2.5)) - dev->readout_regs[1] |= 0x00; - else if (cpu_dmulti > 2.5) - dev->readout_regs[1] |= 0x80; - - io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev); - #if 0 device_add(&i8254_sec_device); #endif diff --git a/src/chipset/sis_5511_h2p.c b/src/chipset/sis_5511_h2p.c index b94e69f26..c8cb44a0a 100644 --- a/src/chipset/sis_5511_h2p.c +++ b/src/chipset/sis_5511_h2p.c @@ -259,7 +259,7 @@ sis_5511_host_to_pci_write(int addr, uint8_t val, void *priv) case 0x7a: /* DRAM Bank Register 2-1 */ case 0x7c: /* DRAM Bank Register 3-0 */ case 0x7e: /* DRAM Bank Register 3-1 */ - spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x82); + spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x02); break; case 0x71: /* DRAM Bank Register 0-0 */ diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index 51f7fd4e6..f715c5272 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -33,6 +33,7 @@ #include <86box/mem.h> #include <86box/smram.h> #include <86box/pic.h> +#include <86box/plat_fallthrough.h> #include <86box/keyboard.h> #include <86box/machine.h> #include <86box/chipset.h> @@ -82,6 +83,14 @@ static uint8_t ram_471[64] = { 0x00, 0x00, 0x01, 0x01, 0x02, 0x20, 0x09, 0x09, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d }; +static uint8_t ram_asus[64] = { 0x00, 0x00, 0x01, 0x10, 0x10, 0x20, 0x03, 0x11, + 0x11, 0x05, 0x05, 0x12, 0x12, 0x13, 0x13, 0x13, + 0x13, 0x21, 0x06, 0x14, 0x14, 0x15, 0x15, 0x15, + 0x15, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, + 0x1d, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, + 0x17, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f }; static uint8_t ram_tg486g[64] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, @@ -162,17 +171,32 @@ sis_85c471_get_row(ram_bank_t *dev, uint32_t addr) uint32_t ret = 0x00000000; switch (dev->virt_size) { - case 0x04000000: - ret = (addr >> 14) & 0x00000fff; - break; - case 0x01000000: - ret = (addr >> 13) & 0x000007ff; + case 0x00100000: + case 0x00200000: + ret |= (addr >> 13) & 0x00000001; + ret |= ((addr >> 12) & 0x00000001) << 1; + ret |= ((addr >> 14) & 0x0000003f) << 2; + ret |= ((addr >> 11) & 0x00000001) << 8; + ret |= ((addr >> 20) & 0x00000001) << 9; + ret |= ((addr >> 22) & 0x00000001) << 10; + ret |= ((addr >> 24) & 0x00000001) << 11; break; case 0x00400000: - ret = (addr >> 12) & 0x000003ff; + case 0x00800000: + ret |= (addr >> 13) & 0x00000001; + ret |= ((addr >> 12) & 0x00000001) << 1; + ret |= ((addr >> 14) & 0x000000ff) << 2; + ret |= ((addr >> 22) & 0x00000001) << 10; + ret |= ((addr >> 24) & 0x00000001) << 11; break; - case 0x00100000: - ret = (addr >> 11) & 0x000001ff; + case 0x01000000: + case 0x02000000: + case 0x04000000: + ret |= (addr >> 13) & 0x00000001; + ret |= ((addr >> 22) & 0x00000001) << 1; + ret |= ((addr >> 14) & 0x000000ff) << 2; + ret |= ((addr >> 23) & 0x00000001) << 10; + ret |= ((addr >> 24) & 0x00000001) << 11; break; } @@ -185,17 +209,31 @@ sis_85c471_get_col(ram_bank_t *dev, uint32_t addr) uint32_t ret = 0x00000000; switch (dev->virt_size) { - case 0x04000000: - ret = (addr >> 2) & 0x00000fff; - break; - case 0x01000000: - ret = (addr >> 2) & 0x000007ff; + case 0x00100000: + case 0x00200000: + ret |= (addr >> 3) & 0x00000001; + ret |= ((addr >> 2) & 0x00000001) << 1; + ret |= ((addr >> 4) & 0x0000003f) << 2; + ret |= ((addr >> 10) & 0x00000001) << 8; + ret |= ((addr >> 21) & 0x00000001) << 9; + ret |= ((addr >> 23) & 0x00000001) << 10; + ret |= ((addr >> 25) & 0x00000001) << 11; break; case 0x00400000: - ret = (addr >> 2) & 0x000003ff; + case 0x00800000: + ret |= (addr >> 3) & 0x00000001; + ret |= ((addr >> 2) & 0x00000001) << 1; + ret |= ((addr >> 4) & 0x000000ff) << 2; + ret |= ((addr >> 23) & 0x00000001) << 10; + ret |= ((addr >> 25) & 0x00000001) << 11; break; - case 0x00100000: - ret = (addr >> 2) & 0x000001ff; + case 0x01000000: + case 0x02000000: + case 0x04000000: + ret |= (addr >> 3) & 0x00000001; + ret |= ((addr >> 2) & 0x00000001) << 1; + ret |= ((addr >> 4) & 0x000001ff) << 2; + ret |= ((addr >> 25) & 0x00000001) << 11; break; } @@ -208,17 +246,26 @@ sis_85c471_set_row(ram_bank_t *dev, uint32_t addr) uint32_t ret = 0x00000000; switch (dev->phys_size) { - case 0x04000000: - ret = (addr & 0x00000fff) << 14; + case 0x00100000: + ret = (addr & 0x1ff) << 11; break; - case 0x01000000: - ret = (addr & 0x000007ff) << 13; + case 0x00200000: + ret = (addr & 0x3ff) << 11; break; case 0x00400000: - ret = (addr & 0x000003ff) << 12; + ret = (addr & 0x3ff) << 12; break; - case 0x00100000: - ret = (addr & 0x000002ff) << 11; + case 0x00800000: + ret = (addr & 0x7ff) << 12; + break; + case 0x01000000: + ret = (addr & 0x7ff) << 13; + break; + case 0x02000000: + ret = (addr & 0xfff) << 13; + break; + case 0x04000000: + ret = (addr & 0xfff) << 14; break; } @@ -231,23 +278,28 @@ sis_85c471_set_col(ram_bank_t *dev, uint32_t addr) uint32_t ret = 0x00000000; switch (dev->phys_size) { - case 0x04000000: - ret = (addr & 0x00000fff) << 2; - break; - case 0x01000000: - ret = (addr & 0x000007ff) << 2; + case 0x00100000: + case 0x00200000: + ret = (addr & 0x1ff) << 2; break; case 0x00400000: - ret = (addr & 0x000003ff) << 2; + case 0x00800000: + ret = (addr & 0x3ff) << 2; break; - case 0x00100000: - ret = (addr & 0x000002ff) << 2; + case 0x01000000: + case 0x02000000: + ret = (addr & 0x7ff) << 2; + break; + case 0x04000000: + ret = (addr & 0xfff) << 2; break; } return ret; } +uint8_t reg09 = 0x00; + static uint8_t sis_85c471_read_ram(uint32_t addr, void *priv) { @@ -255,12 +307,10 @@ sis_85c471_read_ram(uint32_t addr, void *priv) uint32_t rel = addr - dev->virt_base; uint8_t ret = 0xff; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -277,12 +327,10 @@ sis_85c471_read_ramw(uint32_t addr, void *priv) uint32_t rel = addr - dev->virt_base; uint16_t ret = 0xffff; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -299,12 +347,10 @@ sis_85c471_read_raml(uint32_t addr, void *priv) uint32_t rel = addr - dev->virt_base; uint32_t ret = 0xffffffff; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -320,12 +366,10 @@ sis_85c471_write_ram(uint32_t addr, uint8_t val, void *priv) ram_bank_t *dev = (ram_bank_t *) priv; uint32_t rel = addr - dev->virt_base; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -339,12 +383,10 @@ sis_85c471_write_ramw(uint32_t addr, uint16_t val, void *priv) ram_bank_t *dev = (ram_bank_t *) priv; uint32_t rel = addr - dev->virt_base; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -358,12 +400,10 @@ sis_85c471_write_raml(uint32_t addr, uint32_t val, void *priv) ram_bank_t *dev = (ram_bank_t *) priv; uint32_t rel = addr - dev->virt_base; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -492,6 +532,8 @@ sis_85c471_banks_split(uint32_t *b_ex, uint32_t *banks) static void sis_85c471_banks_recalc(sis_85c4xx_t *dev) { + reg09 = dev->regs[0x09]; + for (uint8_t i = 0; i < 8; i++) mem_mapping_disable(&dev->ram_banks[i].mapping); @@ -553,12 +595,14 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) switch (rel_reg) { case 0x00: - if (val & 0x01) { - kbc_at_set_fast_reset(0); - cpu_cpurst_on_sr = 1; - } else { - kbc_at_set_fast_reset(1); - cpu_cpurst_on_sr = 0; + if (dev->is_471) { + if (val & 0x01) { + kbc_at_set_fast_reset(0); + cpu_cpurst_on_sr = 1; + } else { + kbc_at_set_fast_reset(1); + cpu_cpurst_on_sr = 0; + } } break; @@ -572,7 +616,7 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) case 0x08: if (valxor) sis_85c4xx_recalcmapping(dev); - if (rel_reg == 0x08) + if ((rel_reg == 0x08) && dev->is_471) flushmmucache(); break; @@ -694,17 +738,25 @@ sis_85c4xx_reset(void *priv) if (dev->is_471) { dev->regs[0x09] = 0x40; - if (mem_size_mb >= 64) { + + if (!strcmp(machine_get_internal_name(), "vli486sv2g")) { + if (mem_size_mb == 64) + dev->regs[0x09] |= 0x1f; + else + dev->regs[0x09] |= ram_asus[mem_size_mb]; + } else if (mem_size_mb >= 64) { if ((mem_size_mb >= 64) && (mem_size_mb < 68)) dev->regs[0x09] |= 0x33; - if ((mem_size_mb >= 68) && (mem_size_mb < 72)) + else if ((mem_size_mb >= 68) && (mem_size_mb < 72)) dev->regs[0x09] |= 0x2b; - if ((mem_size_mb >= 72) && (mem_size_mb < 80)) + else if ((mem_size_mb >= 72) && (mem_size_mb < 80)) dev->regs[0x09] |= 0x2d; - if ((mem_size_mb >= 80) && (mem_size_mb < 96)) + else if ((mem_size_mb >= 80) && (mem_size_mb < 96)) dev->regs[0x09] |= 0x2f; + else if ((mem_size_mb >= 96) && (mem_size_mb < 128)) + dev->regs[0x09] |= 0x34; else - dev->regs[0x09] |= 0x29; + dev->regs[0x09] |= 0x35; } else if (!strcmp(machine_get_internal_name(), "tg486g")) dev->regs[0x09] |= ram_tg486g[mem_size_mb]; else diff --git a/src/cpu/x86.c b/src/cpu/x86.c index a8ab9d866..1b0de661b 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -326,7 +326,6 @@ reset_common(int hard) resetreadlookup(); makemod1table(); cpu_set_edx(); - mmu_perm = 4; } x86seg_reset(); #ifdef USE_DYNAREC diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index 338948af5..9a2d797a8 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -22,12 +22,12 @@ } #define MMX_ENTER() \ - if (!cpu_has_feature(CPU_FEATURE_MMX)) { \ + if (!cpu_has_feature(CPU_FEATURE_MMX) || (cr0 & 0x4)) { \ cpu_state.pc = cpu_state.oldpc; \ x86illegal(); \ return 1; \ } \ - if (cr0 & 0xc) { \ + if (cr0 & 0x8) { \ x86_int(7); \ return 1; \ } \ diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index 253dc059e..3f5d6a4d7 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -201,8 +201,6 @@ opMOV_CRx_r_a16(uint32_t fetchdat) cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm = 4; if (hascache && !(cr0 & (1 << 30))) cpu_cache_int_enabled = 1; else @@ -267,8 +265,6 @@ opMOV_CRx_r_a32(uint32_t fetchdat) cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm = 4; if (hascache && !(cr0 & (1 << 30))) cpu_cache_int_enabled = 1; else diff --git a/src/cpu/x86_ops_mov_ctrl_2386.h b/src/cpu/x86_ops_mov_ctrl_2386.h index 8827d29b2..0d13cc833 100644 --- a/src/cpu/x86_ops_mov_ctrl_2386.h +++ b/src/cpu/x86_ops_mov_ctrl_2386.h @@ -193,8 +193,6 @@ opMOV_CRx_r_a16(uint32_t fetchdat) cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm = 4; if (hascache && !(cr0 & (1 << 30))) cpu_cache_int_enabled = 1; else @@ -255,8 +253,6 @@ opMOV_CRx_r_a32(uint32_t fetchdat) cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm = 4; if (hascache && !(cr0 & (1 << 30))) cpu_cache_int_enabled = 1; else diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 447c07780..aaa746570 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -509,9 +509,6 @@ kbc_scan_kbd_at(atkbc_t *dev) } } -static void -write_p2(atkbc_t *dev, uint8_t val); - static void kbc_at_poll_at(atkbc_t *dev) { @@ -778,6 +775,7 @@ static void write_p2(atkbc_t *dev, uint8_t val) { uint8_t old = dev->p2; + kbc_at_log("ATkbc: write P2: %02X (old: %02X)\n", val, dev->p2); uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; @@ -851,6 +849,25 @@ write_p2(atkbc_t *dev, uint8_t val) } } +uint8_t +kbc_at_read_p(void *priv, uint8_t port, uint8_t mask) +{ + atkbc_t *dev = (atkbc_t *) priv; + uint8_t *p = (port == 2) ? &dev->p2 : &dev->p1; + uint8_t ret = *p & mask; + + return ret; +} + +void +kbc_at_write_p(void *priv, uint8_t port, uint8_t mask, uint8_t val) +{ + atkbc_t *dev = (atkbc_t *) priv; + uint8_t *p = (port == 2) ? &dev->p2 : &dev->p1; + + *p = (*p & mask) | val; +} + static void write_p2_fast_a20(atkbc_t *dev, uint8_t val) { diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 0fd342e55..800e7fb8e 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -64,10 +64,11 @@ static int keydelay[512]; #endif static scancode *scan_table; /* scancode table for keyboard */ -static uint8_t caps_lock = 0; -static uint8_t num_lock = 0; -static uint8_t scroll_lock = 0; -static uint8_t shift = 0; +static volatile uint8_t caps_lock = 0; +static volatile uint8_t num_lock = 0; +static volatile uint8_t scroll_lock = 0; +static volatile uint8_t kana_lock = 0; +static uint8_t shift = 0; static int key5576mode = 0; @@ -108,6 +109,7 @@ keyboard_init(void) num_lock = 0; caps_lock = 0; scroll_lock = 0; + kana_lock = 0; shift = 0; memset(recv_key, 0x00, sizeof(recv_key)); @@ -310,13 +312,16 @@ keyboard_input(int down, uint16_t scan) shift &= ~0x80; break; case 0x03a: /* Caps Lock */ - caps_lock ^= 1; + if (!(machine_has_bus(machine, MACHINE_AT) > 0)) + caps_lock ^= 1; break; case 0x045: - num_lock ^= 1; + if (!(machine_has_bus(machine, MACHINE_AT) > 0)) + num_lock ^= 1; break; case 0x046: - scroll_lock ^= 1; + if (!(machine_has_bus(machine, MACHINE_AT) > 0)) + scroll_lock ^= 1; break; default: @@ -367,11 +372,12 @@ keyboard_do_break(uint16_t scan) Caps Lock, Num Lock, and Scroll Lock when receving the "Set keyboard LEDs" command. */ void -keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl) +keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl, uint8_t kl) { caps_lock = cl; num_lock = nl; scroll_lock = sl; + kana_lock = kl; } uint8_t @@ -381,7 +387,7 @@ keyboard_get_shift(void) } void -keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl) +keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl, uint8_t *kl) { if (cl) *cl = caps_lock; @@ -389,6 +395,8 @@ keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl) *nl = num_lock; if (sl) *sl = scroll_lock; + if (kl) + *kl = kana_lock; } /* Called by the UI to update the states of Caps Lock, Num Lock, and Scroll Lock. */ @@ -432,7 +440,7 @@ keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl) } } - keyboard_update_states(cl, nl, sl); + keyboard_update_states(cl, nl, sl, kana_lock); } int diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index e61b8547a..fbf167e3f 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -3276,7 +3276,7 @@ add_data_kbd(uint16_t val) dev->ignore = 1; - keyboard_get_states(NULL, &num_lock, NULL); + keyboard_get_states(NULL, &num_lock, NULL, NULL); shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; switch (val) { @@ -3476,6 +3476,7 @@ keyboard_at_bat(void *priv) keyboard_scan = 1; + keyboard_update_states(0, 0, 0, 0); kbc_at_dev_queue_add(dev, 0xaa, 0); } else { bat_counter--; @@ -3510,6 +3511,7 @@ keyboard_at_write(void *priv) switch (dev->command) { case 0xed: /* Set/reset LEDs */ kbc_at_dev_queue_add(dev, 0xfa, 0); + keyboard_update_states(!!(val & 0x4), !!(val & 0x2), val & 0x1, !!(val & 0x8)); keyboard_at_log("%s: Set/reset LEDs [%02X]\n", dev->name, val); break; @@ -3767,6 +3769,7 @@ keyboard_at_init(const device_t *info) keyboard_send = add_data_kbd; SavedKbd = dev; + keyboard_update_states(0, 0, 0, 0); inv_cmd_response = (dev->type & FLAG_PS2) ? 0xfe : 0xfa; @@ -3785,6 +3788,8 @@ keyboard_at_close(void *priv) /* Disable the scancode maps. */ keyboard_set_table(NULL); + keyboard_update_states(0, 0, 0, 0); + SavedKbd = NULL; free(dev); diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index 3c616a2ab..7e419b39d 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -742,7 +742,7 @@ kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val)) if (!adddata) return; - keyboard_get_states(NULL, &num_lock, NULL); + keyboard_get_states(NULL, &num_lock, NULL, NULL); shift_states = keyboard_get_shift() & STATE_LSHIFT; if (is_amstrad) @@ -1312,7 +1312,6 @@ const device_t keyboard_xt_t1x00_device = { .config = NULL }; -#ifdef USE_LASERXT const device_t keyboard_xt_lxt3_device = { .name = "VTech Laser Turbo XT Keyboard", .internal_name = "keyboard_xt_lxt", @@ -1326,7 +1325,6 @@ const device_t keyboard_xt_lxt3_device = { .force_redraw = NULL, .config = NULL }; -#endif /* USE_LASERXT */ const device_t keyboard_xt_olivetti_device = { .name = "Olivetti XT Keyboard", diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 3f6a4d018..bdbb9e74c 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -31,6 +31,7 @@ add_library(hdd OBJECT hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c + hdc_ide_rz1000.c hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c diff --git a/src/disk/hdc_ide_rz1000.c b/src/disk/hdc_ide_rz1000.c new file mode 100644 index 000000000..d93e83859 --- /dev/null +++ b/src/disk/hdc_ide_rz1000.c @@ -0,0 +1,322 @@ +/* + * 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 PC Technology RZ-1000 controller. + * + * Authors: Miran Grca, + * + * Copyright 2025 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 rz1000_t { + uint8_t vlb_idx; + uint8_t id; + uint8_t in_cfg; + uint8_t channels; + uint8_t pci; + uint8_t irq_state; + uint8_t pci_slot; + uint8_t pad0; + uint8_t regs[256]; + uint32_t local; + int irq_mode[2]; + int irq_pin; + int irq_line; +} rz1000_t; + +static int next_id = 0; + +#define ENABLE_RZ1000_LOG 1 +#ifdef ENABLE_RZ1000_LOG +int rz1000_do_log = ENABLE_RZ1000_LOG; + +static void +rz1000_log(const char *fmt, ...) +{ + va_list ap; + + if (rz1000_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define rz1000_log(fmt, ...) +#endif + +static void +rz1000_ide_handlers(rz1000_t *dev) +{ + uint16_t main; + uint16_t side; + + if (dev->channels & 0x01) { + ide_pri_disable(); + + main = 0x1f0; + side = 0x3f6; + + ide_set_base(0, main); + ide_set_side(0, side); + + if (dev->regs[0x04] & 0x01) + ide_pri_enable(); + } + + if (dev->channels & 0x02) { + ide_sec_disable(); + + main = 0x170; + side = 0x376; + + ide_set_base(1, main); + ide_set_side(1, side); + + if (dev->regs[0x04] & 0x01) + ide_sec_enable(); + } +} + +static void +rz1000_pci_write(int func, int addr, uint8_t val, void *priv) +{ + rz1000_t *dev = (rz1000_t *) priv; + + rz1000_log("rz1000_pci_write(%i, %02X, %02X)\n", func, addr, val); + + if (func == 0x00) + switch (addr) { + case 0x04: + dev->regs[addr] = (val & 0x41); + rz1000_ide_handlers(dev); + break; + case 0x07: + dev->regs[addr] &= ~(val & 0x80); + 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); + rz1000_ide_handlers(dev); + } + break; + case 0x10: + dev->regs[0x10] = (val & 0xf8) | 1; + rz1000_ide_handlers(dev); + break; + case 0x11: + dev->regs[0x11] = val; + rz1000_ide_handlers(dev); + break; + case 0x14: + dev->regs[0x14] = (val & 0xfc) | 1; + rz1000_ide_handlers(dev); + break; + case 0x15: + dev->regs[0x15] = val; + rz1000_ide_handlers(dev); + break; + case 0x18: + dev->regs[0x18] = (val & 0xf8) | 1; + rz1000_ide_handlers(dev); + break; + case 0x19: + dev->regs[0x19] = val; + rz1000_ide_handlers(dev); + break; + case 0x1c: + dev->regs[0x1c] = (val & 0xfc) | 1; + rz1000_ide_handlers(dev); + break; + case 0x1d: + dev->regs[0x1d] = val; + rz1000_ide_handlers(dev); + break; + case 0x40 ... 0x4f: + dev->regs[addr] = val; + break; + } +} + +static uint8_t +rz1000_pci_read(int func, int addr, void *priv) +{ + rz1000_t *dev = (rz1000_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = dev->regs[addr]; + + rz1000_log("rz1000_pci_read(%i, %02X, %02X)\n", func, addr, ret); + + return ret; +} + +static void +rz1000_reset(void *priv) +{ + rz1000_t *dev = (rz1000_t *) priv; + int i = 0; + int min_channel; + int max_channel; + + switch (dev->channels) { + default: + case 0x00: + min_channel = max_channel = 0; + break; + case 0x01: + min_channel = 0; + max_channel = 1; + break; + case 0x02: + min_channel = 2; + max_channel = 3; + break; + case 0x03: + min_channel = 0; + max_channel = 3; + break; + } + + for (i = 0; i < CDROM_NUM; i++) { + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel >= min_channel) && + (cdrom[i].ide_channel <= max_channel) && 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 >= min_channel) && + (zip_drives[i].ide_channel <= max_channel) && 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 >= min_channel) && + (mo_drives[i].ide_channel <= max_channel) && mo_drives[i].priv) + mo_reset((scsi_common_t *) mo_drives[i].priv); + } + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + rz1000_log("dev->local = %08X\n", dev->local); + + dev->regs[0x00] = 0x42; /* PC Technology */ + dev->regs[0x01] = 0x10; + dev->regs[0x02] = 0x00; /* RZ-1000 */ + dev->regs[0x03] = 0x10; + dev->regs[0x04] = 0x01; + 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 */ + + 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; + + rz1000_ide_handlers(dev); +} + +static void +rz1000_close(void *priv) +{ + rz1000_t *dev = (rz1000_t *) priv; + + free(dev); + + next_id = 0; +} + +static void * +rz1000_init(const device_t *info) +{ + rz1000_t *dev = (rz1000_t *) calloc(1, sizeof(rz1000_t)); + + dev->id = next_id | 0x60; + + dev->pci = !!(info->flags & DEVICE_PCI); + dev->local = info->local; + + dev->channels = ((info->local & 0x60000) >> 17) & 0x03; + + device_add(&ide_pci_2ch_device); + + if (info->local & 0x80000) + pci_add_card(PCI_ADD_NORMAL, rz1000_pci_read, rz1000_pci_write, dev, &dev->pci_slot); + else + pci_add_card(PCI_ADD_IDE, rz1000_pci_read, rz1000_pci_write, dev, &dev->pci_slot); + + if (dev->channels & 0x01) + ide_board_set_force_ata3(0, 1); + + if (dev->channels & 0x02) + ide_board_set_force_ata3(1, 1); + + next_id++; + + rz1000_reset(dev); + + return dev; +} + +const device_t ide_rz1000_pci_device = { + .name = "PC Technology RZ-1000 PCI", + .internal_name = "ide_rz1000_pci", + .flags = DEVICE_PCI, + .local = 0x6000a, + .init = rz1000_init, + .close = rz1000_close, + .reset = rz1000_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_rz1000_pci_single_channel_device = { + .name = "PC Technology RZ-1000 PCI", + .internal_name = "ide_rz1000_pci_single_channel", + .flags = DEVICE_PCI, + .local = 0x2000a, + .init = rz1000_init, + .close = rz1000_close, + .reset = rz1000_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index c32b1f442..de8508e69 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -81,6 +81,7 @@ int fdc_current[FDC_MAX] = { 0, 0 }; volatile int fdcinited = 0; +// #define ENABLE_FDC_LOG 1 #ifdef ENABLE_FDC_LOG int fdc_do_log = ENABLE_FDC_LOG; @@ -395,6 +396,20 @@ fdc_update_rwc(fdc_t *fdc, int drive, int rwc) fdc_rate(fdc, drive); } +uint8_t +fdc_get_media_id(fdc_t *fdc, int id) +{ + uint8_t ret = fdc->media_id & (1 << id); + + return ret; +} + +void +fdc_set_media_id(fdc_t *fdc, int id, int set) +{ + fdc->media_id = (fdc->media_id & ~(1 << id)) | (set << id); +} + int fdc_get_boot_drive(fdc_t *fdc) { @@ -1369,7 +1384,7 @@ fdc_read(uint16_t addr, void *priv) } else if (!fdc->enh_mode) ret = 0x20; else - ret = fdc->rwc[drive] << 4; + ret = (fdc->rwc[drive] << 4) | (fdc->media_id << 6); break; case 4: /*Status*/ ret = fdc->stat; @@ -2352,6 +2367,8 @@ fdc_reset(void *priv) } fdc->power_down = 0; + + fdc->media_id = 0; } static void diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 2d17380d0..36cfaeb7a 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -119,6 +119,8 @@ typedef struct fdc_t { uint8_t lock; uint8_t dsr; + uint8_t media_id; + uint8_t params[15]; uint8_t specify[2]; uint8_t res[11]; @@ -166,6 +168,9 @@ extern void fdc_3f1_enable(fdc_t *fdc, int enable); extern int fdc_get_bit_rate(fdc_t *fdc); extern int fdc_get_bitcell_period(fdc_t *fdc); +extern uint8_t fdc_get_media_id(fdc_t *fdc, int id); +extern void fdc_set_media_id(fdc_t *fdc, int id, int set); + /* A few functions to communicate between Super I/O chips and the FDC. */ extern void fdc_update_enh_mode(fdc_t *fdc, int enh_mode); extern int fdc_get_rwc(fdc_t *fdc, int drive); diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 71f83e5e6..0a5985370 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -60,6 +60,8 @@ extern const device_t ide_pci_device; /* pci_ide */ extern const device_t ide_pci_sec_device; /* pci_ide sec */ extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */ +extern const device_t ide_pci_ter_qua_2ch_device; /* pci_ide_ter_qua_2ch */ + extern const device_t ide_ali1489_device; /* ALi M1489 */ extern const device_t ide_ali5213_device; /* ALi M5213 */ @@ -76,10 +78,14 @@ extern const device_t ide_cmd640_pci_single_channel_sec_device; /* CMD PCI-640B 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_cmd646_ter_qua_device; /* CMD PCI-646 (Tertiary and quaternary channels) */ extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ extern const device_t ide_opti611_vlb_sec_device; /* OPTi 82c611/611A VLB (Secondary channel) */ +extern const device_t ide_rz1000_pci_device; /* PC Technology RZ-1000 PCI */ +extern const device_t ide_rz1000_pci_single_channel_device; /* PC Technology RZ-1000 PCI (Only primary channel) */ + extern const device_t ide_um8673f_device; /* UMC UM8673F */ extern const device_t ide_um8886af_device; /* UMC UM8886AF */ diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index e21fa60d9..f62896106 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -224,9 +224,7 @@ extern const device_t keyboard_xt86_device; extern const device_t keyboard_xt_compaq_device; extern const device_t keyboard_xt_t1x00_device; extern const device_t keyboard_tandy_device; -# ifdef USE_LASERXT extern const device_t keyboard_xt_lxt3_device; -# endif /* USE_LASERXT */ extern const device_t keyboard_xt_olivetti_device; extern const device_t keyboard_xt_zenith_device; extern const device_t keyboard_xt_hyundai_device; @@ -273,9 +271,9 @@ extern void keyboard_process(void); extern uint16_t keyboard_convert(int ch); extern void keyboard_input(int down, uint16_t scan); extern void keyboard_all_up(void); -extern void keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl); +extern void keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl, uint8_t kl); extern uint8_t keyboard_get_shift(void); -extern void keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl); +extern void keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl, uint8_t *kl); extern void keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl); extern int keyboard_recv(uint16_t key); extern int keyboard_recv_ui(uint16_t key); @@ -285,6 +283,7 @@ extern int keyboard_isfsexit(void); extern int keyboard_isfsexit_up(void); extern void keyboard_set_is_amstrad(int ams); extern void kbc_at_set_ps2(void *priv, uint8_t ps2); +extern uint8_t kbc_at_read_p(void *priv, uint8_t port, uint8_t mask); extern void kbc_at_write_p(void *priv, uint8_t port, uint8_t mask, uint8_t val); extern void kbc_at_set_fast_reset(uint8_t new_fast_reset); diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 4469b55c2..d8c213d53 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -101,7 +101,7 @@ #define MACHINE_GAMEPORT 0x00008000 /* sys has int game port */ #define MACHINE_SOUND 0x00010000 /* sys has int sound */ #define MACHINE_NIC 0x00020000 /* sys has int NIC */ -#define MACHINE_MODEM 0x00040000 /* sys has int modem */ +#define MACHINE_AX 0x00040000 /* sys adheres to Japanese AX standard */ /* Feature flags for advanced devices. */ #define MACHINE_APM 0x00080000 /* sys has APM */ #define MACHINE_ACPI 0x00100000 /* sys has ACPI */ @@ -782,6 +782,7 @@ extern int machine_at_ax59pro_init(const machine_t *); extern int machine_at_mvp3_init(const machine_t *); extern int machine_at_ficva503a_init(const machine_t *); extern int machine_at_5emapro_init(const machine_t *); +extern int machine_at_delhi3_init(const machine_t *); extern int machine_at_5sg100_init(const machine_t *); @@ -806,6 +807,7 @@ extern int machine_at_p65up5_cp6nd_init(const machine_t *); /* m_at_slot1.c */ extern int machine_at_m729_init(const machine_t *); +extern int machine_at_acerv62x_init(const machine_t *); extern int machine_at_p65up5_cpknd_init(const machine_t *); extern int machine_at_kn97_init(const machine_t *); @@ -969,10 +971,14 @@ extern int machine_xt_compaq_deskpro_init(const machine_t *); extern int machine_xt_compaq_portable_init(const machine_t *); /* m_xt_laserxt.c */ -#ifdef USE_LASERXT extern int machine_xt_laserxt_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t laserxt_device; +#endif extern int machine_xt_lxt3_init(const machine_t *); -#endif /* USE_LASERXT */ +#ifdef EMU_DEVICE_H +extern const device_t lxt3_device; +#endif /* m_xt_philips.c */ extern int machine_xt_p3105_init(const machine_t *); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index f8d0f659a..62cb493a5 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -300,7 +300,6 @@ extern int writelnum; extern int memspeed[11]; -extern int mmu_perm; extern uint8_t high_page; /* if a high (> 4 gb) page was detected */ extern uint8_t *_mem_exec[MEM_MAPPINGS_NO]; diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 7fcb376b9..bdff29f7f 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -48,14 +48,22 @@ extern const device_t fdc37c669_370_device; extern const device_t fdc37c67x_device; -extern const device_t fdc37c931apm_device; -extern const device_t fdc37c931apm_compaq_device; -extern const device_t fdc37c932fr_device; -extern const device_t fdc37c932qf_device; -extern const device_t fdc37c932_device; -extern const device_t fdc37c935_device; -extern const device_t fdc37c935_370_device; -extern const device_t fdc37c935_no_nvr_device; +#define FDC37C93X_NORMAL 0x0002 +#define FDC37C93X_FR 0x0003 +#define FDC37C93X_APM 0x0030 +#define FDC37C93X_CHIP_ID 0x00ff + +#define FDC37C931 0x0100 /* Compaq KBC firmware and configuration registers on GPIO ports. */ +#define FDC37C932 0x0200 /* AMI '5' Megakey KBC firmware. */ +#define FDC37C933 0x0300 /* IBM KBC firmware. */ +#define FDC37C935 0x0500 /* Phoenix Multikey/42 1.38 KBC firmware. */ +#define FDC37C937 0x0700 /* Phoenix Multikey/42i 4.16 KBC firmware. */ +#define FDC37C93X_KBC 0x0f00 + +#define FDC37C93X_NO_NVR 0x1000 +#define FDC37C93X_370 0x2000 + +extern const device_t fdc37c93x_device; extern const device_t fdc37m60x_device; extern const device_t fdc37m60x_370_device; diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index ff6a66801..4098f2553 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -20,6 +20,7 @@ add_library(mch OBJECT machine_table.c m_xt.c m_xt_compaq.c + m_xt_laserxt.c m_xt_philips.c m_xt_t1000.c m_xt_t1000_vid.c @@ -64,11 +65,6 @@ if(DESKPRO386) target_compile_definitions(mch PRIVATE USE_DESKPRO386) endif() -if(LASERXT) - target_sources(mch PRIVATE m_xt_laserxt.c) - target_compile_definitions(mch PRIVATE USE_LASERXT) -endif() - if(OLIVETTI) target_compile_definitions(mch PRIVATE USE_OLIVETTI) endif() diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 5b746e3ef..ed8f75a84 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -700,6 +700,8 @@ static const device_config_t pb450_config[] = { .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/OPTI802.bin", "" } }, { .name = "PNP 1.1A", .internal_name = "pnp11a", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/PNP11A.bin", "" } }, + { .name = "P4HS20 (Micro Firmware/Phoenix 4.05)", .internal_name = "p4hs20", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/p4hs20.bin", "" } }, { .files_no = 0 } }, }, diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index a3ff921e3..b2f05d33e 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -40,6 +40,36 @@ #include <86box/clock.h> #include <86box/snd_ac97.h> +int +machine_at_acerv62x_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/acerv62x/v62xc0s1.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 5, 0, 0, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + device_add(&i440fx_device); + device_add(&piix3_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C935 | FDC37C93X_APM)); + device_add(&sst_flash_29ee020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 128); + + return ret; +} + int machine_at_p65up5_cpknd_init(const machine_t *model) { @@ -131,7 +161,7 @@ machine_at_spitfire_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init_ex(model, 2); + machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -143,7 +173,7 @@ machine_at_spitfire_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440lx_device); device_add(&piix4e_device); - device_add(&fdc37c935_no_nvr_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C935 | FDC37C93X_NORMAL | FDC37C93X_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); device_add(&lm78_device); /* no reporting in BIOS */ diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index c747d8cc0..92f88fbe6 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -58,7 +58,8 @@ machine_at_premiere_common_init(const machine_t *model, int pci_switch) pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_phoenix_device); device_add(&sio_zb_device); - device_add(&fdc37c665_device); + device_add(&ide_rz1000_pci_single_channel_device); + device_add(&fdc37c665_ide_sec_device); device_add(&intel_flash_bxt_ami_device); } diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 02922b425..0d748b85e 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -169,8 +169,8 @@ machine_at_tek932_init(const machine_t *model) device_add(&keyboard_ps2_intel_ami_pci_device); device_add(&i430nx_device); device_add(&sio_zb_device); - device_add(&fdc37c665_ide_device); device_add(&ide_vlb_device); + device_add(&fdc37c665_ide_pri_device); device_add(&intel_flash_bxt_ami_device); return ret; diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 3fe883323..319856d41 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -69,7 +69,8 @@ machine_at_acerv35n_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&fdc37c932fr_device); + /* The chip is not marked FR but the BIOS accesses register 06h of GPIO. */ + device_add_params(&fdc37c93x_device, (void *) (FDC37C935 | FDC37C93X_FR)); device_add(&sst_flash_29ee010_device); return ret; @@ -160,7 +161,7 @@ machine_at_m7shi_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C935 | FDC37C93X_NORMAL)); device_add(&intel_flash_bxt_device); return ret; @@ -568,7 +569,7 @@ machine_at_presario2240_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c932qf_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C932 | FDC37C93X_NORMAL)); device_add(&sst_flash_29ee020_device); return ret; @@ -598,7 +599,7 @@ machine_at_presario4500_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c931apm_compaq_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C931 | FDC37C93X_APM)); device_add(&sst_flash_29ee020_device); return ret; @@ -631,7 +632,7 @@ machine_at_dellhannibalp_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c932fr_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C932 | FDC37C93X_FR)); device_add(&intel_flash_bxt_ami_device); return ret; @@ -659,7 +660,7 @@ machine_at_p55va_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c932fr_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C932 | FDC37C93X_FR)); device_add(&intel_flash_bxt_device); return ret; @@ -687,7 +688,7 @@ machine_at_brio80xx_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c935_370_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C935 | FDC37C93X_NORMAL | FDC37C93X_370)); device_add(&sst_flash_29ee020_device); return ret; @@ -756,7 +757,7 @@ machine_at_pb810_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c935_370_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C935 | FDC37C93X_NORMAL | FDC37C93X_370)); device_add(&intel_flash_bxt_device); return ret; @@ -851,7 +852,7 @@ machine_at_gw2kte_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c932fr_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C932 | FDC37C93X_FR)); device_add(&intel_flash_bxt_ami_device); return ret; @@ -1553,7 +1554,7 @@ machine_at_thunderbolt_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init_ex(model, 2); + machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -1564,7 +1565,7 @@ machine_at_thunderbolt_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 0, 1, 2); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&fdc37c935_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C935 | FDC37C93X_NORMAL | FDC37C93X_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 4b980f2b0..913c82518 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -455,7 +455,7 @@ machine_at_pb640_init(const machine_t *model) device_add(&piix_rev02_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5440_onboard_pci_device); + device_add(machine_get_vid_device(machine)); device_add(&keyboard_ps2_intel_ami_pci_device); device_add(&pc87306_device); @@ -546,7 +546,7 @@ machine_at_acerm3a_init(const machine_t *model) pci_register_slot(0x10, PCI_CARD_VIDEO, 4, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C935 | FDC37C93X_NORMAL)); device_add(&sst_flash_29ee010_device); @@ -700,7 +700,7 @@ machine_at_gw2kma_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c932fr_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C932 | FDC37C93X_FR)); device_add(&intel_flash_bxt_ami_device); return ret; @@ -819,7 +819,7 @@ machine_at_vectra54_init(const machine_t *model) device_add(&i430fx_device); device_add(&piix_device); - device_add(&fdc37c932_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C932 | FDC37C93X_NORMAL)); device_add(&sst_flash_29ee010_device); return ret; diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 935a26fb2..006e0f419 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -188,8 +188,9 @@ machine_at_acerv60n_init(const machine_t *model) pci_register_slot(0x0C, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C935 | FDC37C93X_NORMAL)); device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 128); return ret; } @@ -216,9 +217,7 @@ machine_at_lgibmx61_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - // device_add(&keyboard_ps2_ami_pci_device); device_add(&keyboard_ps2_ami_device); - // device_add(&w83787f_device); device_add(&w83877f_president_device); device_add(&sst_flash_29ee010_device); @@ -389,7 +388,7 @@ machine_at_m6mi_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37C935 | FDC37C93X_NORMAL)); device_add(&intel_flash_bxt_device); return ret; diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index 0360b5650..b7ffc03b3 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -343,6 +343,38 @@ machine_at_5emapro_init(const machine_t *model) return ret; } +int +machine_at_delhi3_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/delhi3/DELHI3.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + + device_add(&via_mvp3_device); + device_add(&via_vt82c596a_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 256); + + if ((sound_card_current[0] == SOUND_INTERNAL) && machine_get_snd_device(machine)) + device_add(machine_get_snd_device(machine)); + + return ret; +} + int machine_at_5sg100_init(const machine_t *model) { diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index ca9e72fca..d4d3b09cf 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -1566,7 +1566,8 @@ machine_pcjr_init(UNUSED(const machine_t *model)) device_add(&fdc_pcjr_device); device_add(&ns8250_pcjr_device); - serial_set_next_inst(SERIAL_MAX); /* So that serial_standalone_init() won't do anything. */ + /* So that serial_standalone_init() won't do anything. */ + serial_set_next_inst(SERIAL_MAX - 1); /* "All the inputs are 'read' with one 'IN' from address hex 201." - PCjr Technical Reference (Nov. 83), p.2-119 diff --git a/src/machine/m_xt_laserxt.c b/src/machine/m_xt_laserxt.c index c0405f99a..d298e726b 100644 --- a/src/machine/m_xt_laserxt.c +++ b/src/machine/m_xt_laserxt.c @@ -1,6 +1,7 @@ /*This is the chipset used in the LaserXT series model*/ #include #include +#include #include #include #include <86box/86box.h> @@ -21,125 +22,411 @@ #include <86box/keyboard.h> #include <86box/plat_unused.h> -static int laserxt_emspage[4]; -static int laserxt_emscontrol[4]; -static mem_mapping_t laserxt_ems_mapping[4]; -static int laserxt_ems_baseaddr_index = 0; -static int laserxt_is_lxt3 = 0; +#define EMS_TOTAL_MAX 0x00100000 -static uint32_t -get_laserxt_ems_addr(uint32_t addr) +typedef struct { - if (laserxt_emspage[(addr >> 14) & 3] & 0x80) { - addr = (!laserxt_is_lxt3 ? 0x70000 + (((mem_size + 64) & 255) << 10) : 0x30000 + (((mem_size + 320) & 511) << 10)) + ((laserxt_emspage[(addr >> 14) & 3] & 0x0F) << 14) + ((laserxt_emspage[(addr >> 14) & 3] & 0x40) << 12) + (addr & 0x3FFF); - } + uint8_t page; + uint8_t ctrl; - return addr; + uint32_t phys; + uint32_t virt; + + mem_mapping_t mapping; + + uint8_t *ram; + + void *parent; +} lxt_ems_t; + +typedef struct +{ + int ems_base_idx; + + lxt_ems_t ems[4]; + + uint16_t io_base; + uint32_t base; + + uint32_t mem_size; + + uint8_t *ram; + + void *parent; +} lxt_ems_board_t; + +typedef struct +{ + int is_lxt3; + + lxt_ems_board_t *ems_boards[2]; +} lxt_t; + +static void +ems_update_virt(lxt_ems_t *dev, uint8_t new_page) +{ + lxt_ems_board_t *board = (lxt_ems_board_t *) dev->parent; + lxt_t *lxt = (lxt_t *) board->parent; + + dev->page = new_page; + + if (new_page & 0x80) { + if (lxt->is_lxt3) { + /* Point invalid pages at 1 MB which is outside the maximum. */ + if ((new_page & 0x7f) >= 0x40) + dev->virt = EMS_TOTAL_MAX; + else + dev->virt = ((new_page & 0x7f) << 14); + } else + dev->virt = ((new_page & 0x0f) << 14) + ((new_page & 0x40) << 12); + + if (dev->virt >= board->mem_size) + dev->virt = EMS_TOTAL_MAX; + } else + dev->virt = EMS_TOTAL_MAX; + + dev->ram = board->ram + dev->virt; + + if ((new_page & 0x80) && (dev->virt != EMS_TOTAL_MAX)) { + mem_mapping_enable(&dev->mapping); + + mem_mapping_set_exec(&dev->mapping, dev->ram); + mem_mapping_set_p(&dev->mapping, dev->ram); + } else + mem_mapping_disable(&dev->mapping); + + flushmmucache(); } static void -laserxt_write(uint16_t port, uint8_t val, UNUSED(void *priv)) +lxt_ems_out(uint16_t port, uint8_t val, void *priv) { - uint32_t paddr; - uint32_t vaddr; - switch (port) { - case 0x0208: - case 0x4208: - case 0x8208: - case 0xC208: - laserxt_emspage[port >> 14] = val; - paddr = 0xC0000 + (port & 0xC000) + (((laserxt_ems_baseaddr_index + (4 - (port >> 14))) & 0x0C) << 14); - if (val & 0x80) { - mem_mapping_enable(&laserxt_ems_mapping[port >> 14]); - vaddr = get_laserxt_ems_addr(paddr); - mem_mapping_set_exec(&laserxt_ems_mapping[port >> 14], ram + vaddr); - } else { - mem_mapping_disable(&laserxt_ems_mapping[port >> 14]); - } - flushmmucache(); - break; - case 0x0209: - case 0x4209: - case 0x8209: - case 0xC209: - laserxt_emscontrol[port >> 14] = val; - laserxt_ems_baseaddr_index = 0; + lxt_ems_board_t *dev = (lxt_ems_board_t *) priv; + uint8_t reg = port >> 14; + uint32_t saddrs[8] = { 0xc4000, 0xc8000, 0xcc000, 0xd0000, + 0xd4000, 0xd8000, 0xdc000, 0xe0000 }; + uint32_t saddr; + + if (port & 0x0001) { + dev->ems[reg].ctrl = val; + + if (reg < 0x03) { + dev->ems_base_idx = (dev->ems_base_idx & ~(0x04 >> (2 - reg))) | + ((dev->ems[reg].ctrl & 0x80) >> (7 - reg)); + + saddr = saddrs[dev->ems_base_idx]; + for (uint8_t i = 0; i < 4; i++) { - laserxt_ems_baseaddr_index |= (laserxt_emscontrol[i] & 0x80) >> (7 - i); + uint32_t base = saddr + (i * 0x4000); + mem_mapping_set_addr(&dev->ems[i].mapping, base, 0x4000); + if (!(dev->ems[i].page & 0x80) || (dev->ems[i].virt == EMS_TOTAL_MAX)) + mem_mapping_disable(&dev->ems[i].mapping); } + } - mem_mapping_set_addr(&laserxt_ems_mapping[0], 0xC0000 + (((laserxt_ems_baseaddr_index + 4) & 0x0C) << 14), 0x4000); - mem_mapping_set_addr(&laserxt_ems_mapping[1], 0xC4000 + (((laserxt_ems_baseaddr_index + 3) & 0x0C) << 14), 0x4000); - mem_mapping_set_addr(&laserxt_ems_mapping[2], 0xC8000 + (((laserxt_ems_baseaddr_index + 2) & 0x0C) << 14), 0x4000); - mem_mapping_set_addr(&laserxt_ems_mapping[3], 0xCC000 + (((laserxt_ems_baseaddr_index + 1) & 0x0C) << 14), 0x4000); - flushmmucache(); - break; - - default: - break; + flushmmucache(); + } else if (!(port & 0x0001)) { + dev->ems[reg].page = val; + ems_update_virt(&dev->ems[reg], val); } } static uint8_t -laserxt_read(uint16_t port, UNUSED(void *priv)) +lxt_ems_in(uint16_t port, void *priv) { - switch (port) { - case 0x0208: - case 0x4208: - case 0x8208: - case 0xC208: - return laserxt_emspage[port >> 14]; - case 0x0209: - case 0x4209: - case 0x8209: - case 0xC209: - return laserxt_emscontrol[port >> 14]; + lxt_ems_board_t *dev = (lxt_ems_board_t *) priv; + uint8_t reg = port >> 14; + uint8_t ret = 0xff; - default: - break; - } - return 0xff; + if (port & 0x0001) + ret = dev->ems[reg].ctrl; + else + ret = dev->ems[reg].page; + + return ret; } static void -mem_write_laserxtems(uint32_t addr, uint8_t val, UNUSED(void *priv)) +lxt_ems_write(uint32_t addr, uint8_t val, void *priv) { - addr = get_laserxt_ems_addr(addr); - if (addr < (mem_size << 10)) - ram[addr] = val; + uint8_t *mem = (uint8_t *) priv; + + mem[addr & 0x3fff] = val; } static uint8_t -mem_read_laserxtems(uint32_t addr, UNUSED(void *priv)) +lxt_ems_read(uint32_t addr, void *priv) { - uint8_t val = 0xFF; - addr = get_laserxt_ems_addr(addr); - if (addr < (mem_size << 10)) - val = ram[addr]; - return val; + uint8_t *mem = (uint8_t *) priv; + uint8_t ret = 0xff; + + ret = mem[addr & 0x3fff]; + + return ret; +} + +static lxt_ems_board_t * +lxt_ems_init(lxt_t *parent, int en, uint16_t io, uint32_t mem) +{ + lxt_ems_board_t *dev = (lxt_ems_board_t *) calloc(1, sizeof(lxt_ems_board_t)); + + if (en) { + dev->parent = parent; + + if (io != 0x0000) { + io_sethandler(io , 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev); + io_sethandler(io | 0x4000, 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev); + io_sethandler(io | 0x8000, 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev); + io_sethandler(io | 0xc000, 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev); + } + + dev->ram = (uint8_t *) calloc(mem, sizeof(uint8_t)); + dev->mem_size = mem; + + for (uint8_t i = 0; i < 4; i++) { + uint8_t *ptr = dev->ram + (i << 14); + + mem_mapping_add(&dev->ems[i].mapping, 0xe0000 + (i << 14), 0x4000, + lxt_ems_read, NULL, NULL, + lxt_ems_write, NULL, NULL, + ptr, 0, ptr); + mem_mapping_disable(&dev->ems[i].mapping); + + dev->ems[i].page = 0x7f; + dev->ems[i].ctrl = (i == 3) ? 0x00 : 0x80; + + dev->ems[i].parent = dev; + + ems_update_virt(&(dev->ems[i]), dev->ems[i].page); + } + } + + return dev; } static void -laserxt_init(int is_lxt3) +lxt_close(void *priv) { - if (mem_size > 640) { - io_sethandler(0x0208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - io_sethandler(0x4208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - io_sethandler(0x8208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - io_sethandler(0xc208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - mem_mapping_set_addr(&ram_low_mapping, 0, !is_lxt3 ? 0x70000 + (((mem_size + 64) & 255) << 10) : 0x30000 + (((mem_size + 320) & 511) << 10)); + lxt_t *dev = (lxt_t *) priv; + int ems_boards = (1 - dev->is_lxt3) + 1; + + for (int i = 0; i < ems_boards; i++) + if (dev->ems_boards[i] != NULL) { + if (dev->ems_boards[i]->ram != NULL) + free(dev->ems_boards[i]->ram); + free(dev->ems_boards[i]); + } + + free(dev); +} + +static void * +lxt_init(const device_t *info) +{ + lxt_t * dev = (lxt_t *) calloc(1, sizeof(lxt_t)); + int ems_boards = (1 - info->local) + 1; + int ems_en[2] = { 0 }; + uint16_t ems_io[2] = { 0 }; + uint32_t ems_mem[2] = { 0 }; + char conf_str[512] = { 0 }; + + dev->is_lxt3 = info->local; + + for (int i = 0; i < ems_boards; i++) { + sprintf(conf_str, "ems_%i_enable", i + 1); + ems_en[i] = device_get_config_int(conf_str); + + sprintf(conf_str, "ems_%i_base", i + 1); + ems_io[i] = device_get_config_hex16(conf_str); + + sprintf(conf_str, "ems_%i_mem_size", i + 1); + ems_mem[i] = device_get_config_int(conf_str) << 10; + + dev->ems_boards[i] = lxt_ems_init(dev, ems_en[i], ems_io[i], ems_mem[i]); } - for (uint8_t i = 0; i < 4; i++) { - laserxt_emspage[i] = 0x7F; - laserxt_emscontrol[i] = (i == 3) ? 0x00 : 0x80; - mem_mapping_add(&laserxt_ems_mapping[i], 0xE0000 + (i << 14), 0x4000, mem_read_laserxtems, NULL, NULL, mem_write_laserxtems, NULL, NULL, ram + 0xA0000 + (i << 14), 0, NULL); - mem_mapping_disable(&laserxt_ems_mapping[i]); - } mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - laserxt_is_lxt3 = is_lxt3; + + return dev; } +static const device_config_t laserxt_config[] = { + { + .name = "ems_1_base", + .description = "EMS 1 Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "0x208", .value = 0x208 }, + { .description = "0x218", .value = 0x218 }, + { .description = "0x258", .value = 0x258 }, + { .description = "0x268", .value = 0x268 }, + { .description = "0x2A8", .value = 0x2a8 }, + { .description = "0x2B8", .value = 0x2b8 }, + { .description = "0x2E8", .value = 0x2e8 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "ems_2_base", + .description = "EMS 2 Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "0x208", .value = 0x208 }, + { .description = "0x218", .value = 0x218 }, + { .description = "0x258", .value = 0x258 }, + { .description = "0x268", .value = 0x268 }, + { .description = "0x2A8", .value = 0x2a8 }, + { .description = "0x2B8", .value = 0x2b8 }, + { .description = "0x2E8", .value = 0x2e8 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "ems_1_mem_size", + .description = "EMS 1 Memory Size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 512, + .step = 32 + }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "ems_2_mem_size", + .description = "EMS 2 Memory Size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 512, + .step = 32 + }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "ems_1_enable", + .description = "Enable EMS 1", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "ems_2_enable", + .description = "Enable EMS 2", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +const device_t laserxt_device = { + .name = "VTech Laser Turbo XT", + .internal_name = "laserxt", + .flags = 0, + .local = 0, + .init = lxt_init, + .close = lxt_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = laserxt_config +}; + +static const device_config_t lxt3_config[] = { + { + .name = "ems_1_base", + .description = "EMS Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "0x208", .value = 0x208 }, + { .description = "0x218", .value = 0x218 }, + { .description = "0x258", .value = 0x258 }, + { .description = "0x268", .value = 0x268 }, + { .description = "0x2A8", .value = 0x2a8 }, + { .description = "0x2B8", .value = 0x2b8 }, + { .description = "0x2E8", .value = 0x2e8 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "ems_1_mem_size", + .description = "EMS Memory Size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 1024, + .step = 32 + }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "ems_1_enable", + .description = "Enable EMS", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +const device_t lxt3_device = { + .name = "VTech Laser Turbo XT", + .internal_name = "laserxt", + .flags = 0, + .local = 1, + .init = lxt_init, + .close = lxt_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = lxt3_config +}; + static void machine_xt_laserxt_common_init(const machine_t *model,int is_lxt3) { @@ -153,7 +440,7 @@ machine_xt_laserxt_common_init(const machine_t *model,int is_lxt3) nmi_init(); standalone_gameport_type = &gameport_device; - laserxt_init(is_lxt3); + device_add(is_lxt3 ? &lxt3_device : &laserxt_device); device_add(&keyboard_xt_lxt3_device); } diff --git a/src/machine/m_xt_zenith.c b/src/machine/m_xt_zenith.c index 6c5d556f2..62c6496d1 100644 --- a/src/machine/m_xt_zenith.c +++ b/src/machine/m_xt_zenith.c @@ -146,7 +146,8 @@ machine_xt_z184_init(const machine_t *model) lpt2_remove(); lpt1_setup(LPT2_ADDR); device_add(&ns8250_device); - serial_set_next_inst(SERIAL_MAX); /* So that serial_standalone_init() won't do anything. */ + /* So that serial_standalone_init() won't do anything. */ + serial_set_next_inst(SERIAL_MAX - 1); device_add(&cga_device); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 77132b6b5..7e0ae8d64 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1709,7 +1709,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#ifdef USE_LASERXT { .name = "[8088] VTech Laser Turbo XT", .internal_name = "ltxt", @@ -1735,21 +1734,20 @@ const machine_t machines[] = { .ram = { .min = 256, .max = 640, - .step = 256 + .step = 64 }, .nvrmask = 0, .kbc_device = &keyboard_xt_device, .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &laserxt_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, .snd_device = NULL, .net_device = NULL }, -#endif /* USE_LASERXT */ /* Has a standard PS/2 KBC (so, use IBM PS/2 Type 1). */ { .name = "[8088] Xi8088", @@ -2612,8 +2610,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - -#ifdef USE_LASERXT { .name = "[8086] VTech Laser XT3", .internal_name = "lxt3", @@ -2637,23 +2633,22 @@ const machine_t machines[] = { .bus_flags = MACHINE_PC, .flags = MACHINE_FLAGS_NONE, .ram = { - .min = 256, + .min = 512, .max = 640, - .step = 256 + .step = 64 }, .nvrmask = 0, .kbc_device = &keyboard_xt_lxt3_device, .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &lxt3_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, .snd_device = NULL, .net_device = NULL }, -#endif /* USE_LASERXT */ /* 286 AT machines */ /* Has IBM AT KBC firmware. */ @@ -4809,7 +4804,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_VIDEO_FIXED, + .flags = MACHINE_VIDEO_FIXED | MACHINE_AX, .ram = { .min = 1024, .max = 4096, @@ -8156,7 +8151,10 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* I'm going to assume this as an AMIKey-2 like the other two 486SP3's. */ + /* + This has an AMIKey (and an on-board NCR 53C810 PCI SCSI controller), thanks, eBay! + The keyboard port is AT. + */ { .name = "[i420TX] ASUS PCI/I-486SP3", .internal_name = "486sp3", @@ -8392,7 +8390,7 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &gd5434_onboard_pci_device, .snd_device = NULL, .net_device = NULL }, @@ -10092,7 +10090,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_SCSI | MACHINE_APM, + .flags = MACHINE_IDE /*| MACHINE_SCSI */ | MACHINE_APM, .ram = { .min = 2048, .max = 524288, @@ -14015,6 +14013,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has the VIA VT82C596A southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA MVP3] eMachines eTower 3xxc", + .internal_name = "delhi3", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, + .init = machine_at_delhi3_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 124242424, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Has internal video: ATI 3D Rage IIc AGP (Rage 2) */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_SOUND | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cs4235_device, + .net_device = NULL + }, /* SiS 5591 */ /* Has the SiS 5591 chipset with on-chip KBC. */ @@ -14168,7 +14207,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, - .max = 786432, + .max = 393216, .step = 8192 }, .nvrmask = 511, @@ -14593,6 +14632,47 @@ const machine_t machines[] = { }, /* 440FX */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ + { + .name = "[i440FX] Acer V62X", + .internal_name = "acerv62x", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_acerv62x_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 83333333, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 393216, + .step = 8192 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* The base board has a Holtek HT6542B KBC with AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440FX] ASUS P/I-P65UP5 (C-PKND)", @@ -14780,7 +14860,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Has internal video: SGS Thompson Riva 128 AGP, network: NEC PK-UG-X006 (Intel 82558B chip) and sound: OAK Audia 3D (OTI-610) */ .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, diff --git a/src/mem/mem.c b/src/mem/mem.c index 8c2cfd6cc..07d897172 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -108,7 +108,6 @@ int mem_a20_alt = 0; int mem_a20_state = 0; int mmuflush = 0; -int mmu_perm = 4; #ifdef USE_NEW_DYNAREC uint64_t *byte_dirty_mask; @@ -125,10 +124,6 @@ mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; uint8_t *_mem_exec[MEM_MAPPINGS_NO]; -/* FIXME: re-do this with a 'mem_ops' struct. */ -static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */ -static uint8_t *readlookupp; -static uint8_t *writelookupp; static mem_mapping_t *base_mapping; static mem_mapping_t *last_mapping; static mem_mapping_t *read_mapping_bus[MEM_MAPPINGS_NO]; @@ -187,10 +182,8 @@ resetreadlookup(void) /* Initialize the tables for high (> 1024K) RAM. */ memset(readlookup2, 0xff, (1 << 20) * sizeof(uintptr_t)); - memset(readlookupp, 0x04, (1 << 20) * sizeof(uint8_t)); memset(writelookup2, 0xff, (1 << 20) * sizeof(uintptr_t)); - memset(writelookupp, 0x04, (1 << 20) * sizeof(uint8_t)); readlnext = 0; writelnext = 0; @@ -204,14 +197,11 @@ flushmmucache(void) for (uint16_t c = 0; c < 256; c++) { if (readlookup[c] != (int) 0xffffffff) { readlookup2[readlookup[c]] = LOOKUP_INV; - readlookupp[readlookup[c]] = 4; readlookup[c] = 0xffffffff; } if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; - page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; - writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -231,9 +221,7 @@ flushmmucache_write(void) for (uint16_t c = 0; c < 256; c++) { if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; - page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; - writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -259,14 +247,11 @@ flushmmucache_nopc(void) for (uint16_t c = 0; c < 256; c++) { if (readlookup[c] != (int) 0xffffffff) { readlookup2[readlookup[c]] = LOOKUP_INV; - readlookupp[readlookup[c]] = 4; readlookup[c] = 0xffffffff; } if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; - page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; - writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -348,7 +333,6 @@ mmutranslatereal_normal(uint32_t addr, int rw) return 0xffffffffffffffffULL; } - mmu_perm = temp & 4; rammap(addr2) |= (rw ? 0x60 : 0x20); uint64_t page = temp & ~0x3fffff; @@ -371,7 +355,6 @@ mmutranslatereal_normal(uint32_t addr, int rw) return 0xffffffffffffffffULL; } - mmu_perm = temp & 4; rammap(addr2) |= 0x20; rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw ? 0x60 : 0x20); @@ -435,7 +418,6 @@ mmutranslatereal_pae(uint32_t addr, int rw) return 0xffffffffffffffffULL; } - mmu_perm = temp & 4; rammap64(addr3) |= (rw ? 0x60 : 0x20); return ((temp & ~0x1fffffULL) + (addr & 0x1fffffULL)) & 0x000000ffffffffffULL; @@ -456,7 +438,6 @@ mmutranslatereal_pae(uint32_t addr, int rw) return 0xffffffffffffffffULL; } - mmu_perm = temp & 4; rammap64(addr3) |= 0x20; rammap64(addr4) |= (rw ? 0x60 : 0x20); @@ -631,7 +612,6 @@ addreadlookup(uint32_t virt, uint32_t phys) else readlookup2[virt >> 12] = (uintptr_t) &ram[a]; #endif - readlookupp[virt >> 12] = mmu_perm; readlookup[readlnext++] = virt >> 12; readlnext &= (cachesize - 1); @@ -671,7 +651,6 @@ addwritelookup(uint32_t virt, uint32_t phys) # endif #endif page_lookup[virt >> 12] = &pages[phys >> 12]; - page_lookupp[virt >> 12] = mmu_perm; } else { #if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) writelookup2[virt >> 12] = (uintptr_t) &ram[(uintptr_t) (phys & ~0xFFF) - (uintptr_t) (virt & ~0xfff)]; @@ -684,7 +663,6 @@ addwritelookup(uint32_t virt, uint32_t phys) writelookup2[virt >> 12] = (uintptr_t) &ram[a]; #endif } - writelookupp[virt >> 12] = mmu_perm; writelookup[writelnext++] = virt >> 12; writelnext &= (cachesize - 1); @@ -973,10 +951,8 @@ readmemwl(uint32_t addr) } return readmembl_no_mmut(addr, addr64a[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) return *(uint16_t *) (readlookup2[addr >> 12] + addr); - } } if (cr0 >> 31) { @@ -1044,7 +1020,6 @@ writememwl(uint32_t addr, uint16_t val) writemembl_no_mmut(addr + 1, addr64a[1], val >> 8); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; *(uint16_t *) (writelookup2[addr >> 12] + addr) = val; return; } @@ -1052,7 +1027,6 @@ writememwl(uint32_t addr, uint16_t val) if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); - mmu_perm = page_lookupp[addr >> 12]; return; } @@ -1100,10 +1074,8 @@ readmemwl_no_mmut(uint32_t addr, uint32_t *a64) } return readmembl_no_mmut(addr, a64[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) return *(uint16_t *) (readlookup2[addr >> 12] + addr); - } } if (cr0 >> 31) { @@ -1149,14 +1121,12 @@ writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val) writemembl_no_mmut(addr + 1, a64[1], val >> 8); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; *(uint16_t *) (writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { - mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); return; } @@ -1231,10 +1201,8 @@ readmemll(uint32_t addr) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ return readmemwl_no_mmut(addr, addr64a) | (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) return *(uint32_t *) (readlookup2[addr >> 12] + addr); - } } if (cr0 >> 31) { @@ -1316,14 +1284,12 @@ writememll(uint32_t addr, uint32_t val) writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; *(uint32_t *) (writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { - mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); return; } @@ -1378,10 +1344,8 @@ readmemll_no_mmut(uint32_t addr, uint32_t *a64) } return readmemwl_no_mmut(addr, a64) | ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) return *(uint32_t *) (readlookup2[addr >> 12] + addr); - } } if (cr0 >> 31) { @@ -1429,14 +1393,12 @@ writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val) writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; *(uint32_t *) (writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { - mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); return; } @@ -1516,10 +1478,8 @@ readmemql(uint32_t addr) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ return readmemll_no_mmut(addr, addr64a) | (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64a[4]))) << 32); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) return *(uint64_t *) (readlookup2[addr >> 12] + addr); - } } if (cr0 >> 31) { @@ -1611,14 +1571,12 @@ writememql(uint32_t addr, uint64_t val) writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; *(uint64_t *) (writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { - mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); page_lookup[addr >> 12]->write_l(addr + 4, val >> 32, page_lookup[addr >> 12]); return; @@ -1702,8 +1660,7 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); a64[i] = (uint32_t) a; } - } else - mmu_perm = page_lookupp[addr >> 12]; + } addr++; } @@ -2914,7 +2871,6 @@ mem_reset(void) pages = (page_t *) malloc(m * sizeof(page_t)); memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); - memset(page_lookupp, 0x04, (1 << 20) * sizeof(uint8_t)); memset(pages, 0x00, pages_sz * sizeof(page_t)); @@ -3033,11 +2989,8 @@ mem_init(void) /* Allocate the lookup tables. */ page_lookup = (page_t **) malloc((1 << 20) * sizeof(page_t *)); - page_lookupp = (uint8_t *) malloc((1 << 20) * sizeof(uint8_t)); readlookup2 = malloc((1 << 20) * sizeof(uintptr_t)); - readlookupp = malloc((1 << 20) * sizeof(uint8_t)); writelookup2 = malloc((1 << 20) * sizeof(uintptr_t)); - writelookupp = malloc((1 << 20) * sizeof(uint8_t)); } static void diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index 1a2782237..ebf062d95 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -211,7 +211,6 @@ mmutranslatereal_2386(uint32_t addr, int rw) return 0xffffffffffffffffULL; } - mmu_perm = temp & 4; mem_writel_map(addr2, mem_readl_map(addr2) | (rw ? 0x60 : 0x20)); return (temp & ~0x3fffff) + (addr & 0x3fffff); @@ -231,7 +230,6 @@ mmutranslatereal_2386(uint32_t addr, int rw) return 0xffffffffffffffffULL; } - mmu_perm = temp & 4; mem_writel_map(addr2, mem_readl_map(addr2) | 0x20); mem_writel_map((temp2 & ~0xfff) + ((addr >> 10) & 0xffc), mem_readl_map((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) | (rw ? 0x60 : 0x20)); diff --git a/src/qt/icons/caps_lock_off.ico b/src/qt/icons/caps_lock_off.ico new file mode 100644 index 000000000..6895c735c Binary files /dev/null and b/src/qt/icons/caps_lock_off.ico differ diff --git a/src/qt/icons/caps_lock_on.ico b/src/qt/icons/caps_lock_on.ico new file mode 100644 index 000000000..2cfd48aad Binary files /dev/null and b/src/qt/icons/caps_lock_on.ico differ diff --git a/src/qt/icons/kana_lock_off.ico b/src/qt/icons/kana_lock_off.ico new file mode 100644 index 000000000..27c9b88c2 Binary files /dev/null and b/src/qt/icons/kana_lock_off.ico differ diff --git a/src/qt/icons/kana_lock_on.ico b/src/qt/icons/kana_lock_on.ico new file mode 100644 index 000000000..ec171b52b Binary files /dev/null and b/src/qt/icons/kana_lock_on.ico differ diff --git a/src/qt/icons/num_lock_off.ico b/src/qt/icons/num_lock_off.ico new file mode 100644 index 000000000..5b14da1d4 Binary files /dev/null and b/src/qt/icons/num_lock_off.ico differ diff --git a/src/qt/icons/num_lock_on.ico b/src/qt/icons/num_lock_on.ico new file mode 100644 index 000000000..0dd08d7ae Binary files /dev/null and b/src/qt/icons/num_lock_on.ico differ diff --git a/src/qt/icons/scroll_lock_off.ico b/src/qt/icons/scroll_lock_off.ico new file mode 100644 index 000000000..85cb09ec6 Binary files /dev/null and b/src/qt/icons/scroll_lock_off.ico differ diff --git a/src/qt/icons/scroll_lock_on.ico b/src/qt/icons/scroll_lock_on.ico new file mode 100644 index 000000000..33476406a Binary files /dev/null and b/src/qt/icons/scroll_lock_on.ico differ diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 7c2b36650..dcb3dbf50 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -37,7 +37,7 @@ msgid "&Hide status bar" msgstr "&Skrij statusno vrstico" msgid "Hide &toolbar" -msgstr "Hide &toolbar" +msgstr "Skrij &orodno vrstico" msgid "&Resizeable window" msgstr "S&premenljiva velikost okna" @@ -55,7 +55,7 @@ msgid "Qt (&OpenGL)" msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" -msgstr "Open&GL (Jedro 3.0)" +msgstr "Open&GL (jedro 3.0)" msgid "&VNC" msgstr "&VNC" @@ -64,10 +64,10 @@ msgid "Specify dimensions..." msgstr "&Določi velikost..." msgid "F&orce 4:3 display ratio" -msgstr "&Vsili 4:3 razmerje zaslona" +msgstr "&Vsili razmerje zaslona 4:3" msgid "&Window scale factor" -msgstr "&Faktor velikosti okna" +msgstr "&Faktor povečave okna" msgid "&0.5x" msgstr "&0.5x" @@ -100,7 +100,7 @@ msgid "&8x" msgstr "&8x" msgid "Filter method" -msgstr "&Metoda filtriranja" +msgstr "&Vrsta filtriranja" msgid "&Nearest" msgstr "&Najbližja" @@ -241,7 +241,7 @@ msgid "E&ject" msgstr "I&zvrzi" msgid "&Image..." -msgstr "Slika..." +msgstr "S&lika..." msgid "E&xport to 86F..." msgstr "&Izvozi v 86F..." @@ -355,7 +355,7 @@ msgid "Speed:" msgstr "Hitrost:" msgid "Frequency:" -msgstr "Pogostost:" +msgstr "Takt:" msgid "FPU:" msgstr "Procesor plavajoče vejice:" @@ -367,7 +367,7 @@ msgid "MB" msgstr "MB" msgid "Memory:" -msgstr "Spomin:" +msgstr "Pomnilnik:" msgid "Time synchronization" msgstr "Sinhronizacija časa" @@ -445,7 +445,7 @@ msgid "FM synth driver" msgstr "Gonilnik sintetizacije FM" msgid "Nuked (more accurate)" -msgstr "Nuked (točnejši)" +msgstr "Nuked (natančnejši)" msgid "YMFM (faster)" msgstr "YMFM (hitrejši)" @@ -487,22 +487,22 @@ msgid "Serial port 4" msgstr "Serijska vrata 4" msgid "Parallel port 1" -msgstr "Paralelna vrata 1" +msgstr "Vzporedna vrata 1" msgid "Parallel port 2" -msgstr "Paralelna vrata 2" +msgstr "Vzporedna vrata 2" msgid "Parallel port 3" -msgstr "Paralelna vrata 3" +msgstr "Vzporedna vrata 3" msgid "Parallel port 4" -msgstr "Paralelna vrata 4" +msgstr "Vzporedna vrata 4" msgid "HD Controller:" msgstr "Krmilnik trdega diska:" msgid "FD Controller:" -msgstr "Krmilnik disketnika:" +msgstr "Disketni krmilnik:" msgid "Tertiary IDE Controller" msgstr "Terciarni krmilnik IDE" @@ -550,7 +550,7 @@ msgid "ID:" msgstr "ID:" msgid "&Specify..." -msgstr "Določi..." +msgstr "&Določi..." msgid "Sectors:" msgstr "Sektorji:" @@ -595,7 +595,7 @@ msgid "ZIP 250" msgstr "ZIP 250" msgid "ISA RTC:" -msgstr "Ura v realnem času ISA:" +msgstr "Ura realnega časa ISA:" msgid "ISA Memory Expansion" msgstr "Razširitev pomnilnika ISA" @@ -643,7 +643,7 @@ msgid "ZIP images" msgstr "ZIP slike" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box ni našel nobenih uporabnih ROM slik.\n\nProsim prenesite set ROM-ov in ga razširite v mapo \"roms\"." +msgstr "86Box ni našel nobenih uporabnih ROM slik.\n\nProsim prenesite komplet ROM-ov in ga razširite v mapo \"roms\"." msgid "(empty)" msgstr "(prazno)" @@ -751,7 +751,7 @@ msgid "Type" msgstr "Vrsta" msgid "No PCap devices found" -msgstr "Nobena naprava PCap ni bila najdena" +msgstr "Najdena ni bila nobena naprava PCap" msgid "Invalid PCap device" msgstr "Neveljavna naprava PCap" @@ -874,16 +874,16 @@ msgid "Don't exit" msgstr "Prekliči izhod" msgid "Reset" -msgstr "Resetiraj" +msgstr "Znova zaženi" msgid "Don't reset" -msgstr "Ne resetiraj" +msgstr "Ne zaženi znova" msgid "CD-ROM images" msgstr "Slike CD-ROM" msgid "%1 Device Configuration" -msgstr "Konfiguracija naprave %1" +msgstr "Nastavitev naprave %1" msgid "Monitor in sleep mode" msgstr "Zaslon v načinu spanja" @@ -946,7 +946,7 @@ msgid "Add New Hard Disk" msgstr "Dodaj nov trdi disk" msgid "Add Existing Hard Disk" -msgstr "Dodaj obstoječ trdi disk" +msgstr "Dodaj obstoječi trdi disk" msgid "HDI disk images cannot be larger than 4 GB." msgstr "Slike diska HDI ne morejo biti večje od 4 GB." @@ -1048,13 +1048,13 @@ msgid "VHD files" msgstr "Datoteke VHD" msgid "Select the parent VHD" -msgstr "Izberite starševsko sliko VHD" +msgstr "Izberite nadrejeno sliko VHD" msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" -msgstr "To lahko pomeni, da je bila starševska slika spremenjena potem, ko je že bila ustvarjena diferencialna slika.\n\nDo tega lahko pride tudi kadar so datoteke slik diska premaknjene ali kopirane, ali pa gre za hrošča v programu, ki je ustvaril ta disk.\n\nŽelite popraviti časovni žig?" +msgstr "To lahko pomeni, da je bila nadrejena slika spremenjena po ustvaritvi diferencialne slike.\n\nDo tega lahko pride tudi kadar so datoteke slik diska premaknjene ali kopirane, ali pa gre za hrošča v programu, ki je ustvaril ta disk.\n\nŽelite popraviti časovni žig?" msgid "Parent and child disk timestamps do not match" -msgstr "Časovna žiga starševske slike diska in slike diska otroka se ne ujemata" +msgstr "Časovna žiga nadrejene in podrejene slike diska se ne ujemata" msgid "Could not fix VHD timestamp." msgstr "Ne morem popraviti časovnega žiga slike VHD." @@ -1105,10 +1105,10 @@ msgid "1.44 MB" msgstr "1.44 MB" msgid "DMF (cluster 1024)" -msgstr "DMF (grozd 1024)" +msgstr "DMF (gruča 1024)" msgid "DMF (cluster 2048)" -msgstr "DMF (grozd 2048)" +msgstr "DMF (gruča 2048)" msgid "2.88 MB" msgstr "2.88 MB" @@ -1162,7 +1162,7 @@ msgid "(System Default)" msgstr "(Sistemsko privzeto)" msgid "Failed to initialize network driver" -msgstr "Ni uspelo inicializirati omrežnega gonilnika" +msgstr "Inicializacija omrežnega gonilnika ni uspela" msgid "The network configuration will be switched to the null driver" msgstr "Omrežne nastavitve bodo preklopljene na ničelni gonilnik" @@ -1234,7 +1234,7 @@ msgid "Open screenshots folder..." msgstr "Odprite mapo s posnetki zaslona..." msgid "Apply fullscreen stretch mode when maximized" -msgstr "Uporabi način celozaslonskega raztezanja v povečanem stanju" +msgstr "Uporabi način celozaslonskega raztezanja v maksimiranem stanju" msgid "Cursor/Puck" msgstr "Kazalec/ključ" @@ -1243,19 +1243,19 @@ msgid "Pen" msgstr "Pisalo" msgid "Host CD/DVD Drive (%1:)" -msgstr "Pogon CD/DVD gostitelja (%1:)" +msgstr "Gostiteljski pogon CD/DVD (%1:)" msgid "&Connected" msgstr "&Povezan" msgid "Clear image history" -msgstr "Jasna zgodovina slik" +msgstr "Počisti zgodovino slik" msgid "Create..." msgstr "Ustvari..." msgid "Host CD/DVD Drive (%1)" -msgstr "Pogon CD/DVD gostitelja (%1)" +msgstr "Gostiteljski pogon CD/DVD (%1)" msgid "Unknown Bus" msgstr "Neznano vodilo" @@ -1288,7 +1288,7 @@ msgid "Remove" msgstr "Odstrani" msgid "Browse..." -msgstr "Brskaj..." +msgstr "Prerskaj..." msgid "Couldn't create OpenGL context." msgstr "Ni bilo mogoče ustvariti konteksta OpenGL." @@ -1297,13 +1297,13 @@ msgid "Couldn't switch to OpenGL context." msgstr "Ni bilo mogoče preklopiti na kontekst OpenGL." msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" -msgstr "Zahteva se različica OpenGL 3.0 ali novejša. Trenutna različica je %1.%2" +msgstr "Potrebna je OpenGL različica 3.0 ali novejša. Trenutna različica je %1.%2" msgid "Error initializing OpenGL" msgstr "Napaka pri inicializaciji OpenGL" msgid "\nFalling back to software rendering." -msgstr "\nVrnitev k programskemu upodabljanju." +msgstr "\nVrnitev na programsko upodabljanje." msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" msgstr "<html><head/><body><p>Pri izbiri medijskih slik (CD-ROM, disketa itd.) se bo odprto pogovorno okno začelo v istem imeniku kot konfiguracijska datoteka 86Box. Ta nastavitev bo verjetno imela pomen le v operacijskem sistemu MacOS.</p></body></html>" @@ -1312,7 +1312,7 @@ msgid "This machine might have been moved or copied." msgstr "Ta naprava je bila morda premeščena ali kopirana." msgid "In order to ensure proper networking functionality, 86Box needs to know if this machine was moved or copied.\n\nSelect \"I Copied It\" if you are not sure." -msgstr "Da bi zagotovili pravilno delovanje omrežja, mora 86Box vedeti, ali je bil ta stroj prestavljen ali kopiran.\n\nČe niste prepričani, izberite \"Kopiral sem jo\"." +msgstr "Da bi zagotovili pravilno delovanje omrežja, mora 86Box vedeti, ali je bil ta virtualna naprava prestavljena ali kopirana.\n\nČe niste prepričani, izberite \"Kopiral sem jo\"." msgid "I Moved It" msgstr "Premaknil sem jo" @@ -1348,7 +1348,7 @@ msgid "Interface:" msgstr "Vmesnik:" msgid "Adapter:" -msgstr "Adapter:" +msgstr "Mrežna kartica:" msgid "VDE Socket:" msgstr "Vtičnica VDE:" @@ -1396,7 +1396,7 @@ msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (serijska)" msgid "[COM] Standard Hayes-compliant Modem" -msgstr "[COM] Standardni modem v skladu s standardom Hayes" +msgstr "[COM] Standardni modem v skladen s Hayes" msgid "Roland MT-32 Emulation" msgstr "Emulacija Roland MT-32" @@ -1411,10 +1411,10 @@ msgid "Roland CM-32LN Emulation" msgstr "Emulacija Roland CM-32LN" msgid "OPL4-ML Daughterboard" -msgstr "Hčerinska plošča OPL4-ML" +msgstr "Dodatna kartica OPL4-ML" msgid "System MIDI" -msgstr "Sistem MIDI" +msgstr "Sistemski MIDI" msgid "MIDI Input Device" msgstr "Vhodna naprava MIDI" @@ -1423,7 +1423,7 @@ msgid "BIOS Address" msgstr "Naslov BIOS-a" msgid "Enable BIOS extension ROM Writes" -msgstr "Omogočanje razširitve BIOS-a ROM piše" +msgstr "Omogoči zapisovanje razširitev BIOS ROM-a" msgid "Address" msgstr "Naslov" @@ -1435,7 +1435,7 @@ msgid "BIOS Revision" msgstr "Revizija BIOS-a" msgid "Translate 26 -> 17" -msgstr "Prevesti 26 -> 17" +msgstr "Prevedi 26 -> 17" msgid "Language" msgstr "Jezik" @@ -1450,25 +1450,25 @@ msgid "BIOS size" msgstr "Velikost BIOS-a" msgid "Map C0000-C7FFF as UMB" -msgstr "Zemljevid C0000-C7FFF kot UMB" +msgstr "Preslikaj C0000-C7FFF kot UMB" msgid "Map C8000-CFFFF as UMB" -msgstr "Zemljevid C8000-CFFFF kot UMB" +msgstr "Preslikaj C8000-CFFFF kot UMB" msgid "Map D0000-D7FFF as UMB" -msgstr "Zemljevid D0000-D7FFF kot UMB" +msgstr "Preslikaj D0000-D7FFF kot UMB" msgid "Map D8000-DFFFF as UMB" -msgstr "Zemljevid D8000-DFFFF kot UMB" +msgstr "Preslikaj D8000-DFFFF kot UMB" msgid "Map E0000-E7FFF as UMB" -msgstr "Zemljevid E0000-E7FFF kot UMB" +msgstr "Preslikaj E0000-E7FFF kot UMB" msgid "Map E8000-EFFFF as UMB" -msgstr "Zemljevid E8000-EFFFF kot UMB" +msgstr "Preslikaj E8000-EFFFF kot UMB" msgid "JS9 Jumper (JIM)" -msgstr "JS9 Jumper (JIM)" +msgstr "JS9 mostiček (JIM)" msgid "MIDI Output Device" msgstr "Izhodna naprava MIDI" @@ -1582,10 +1582,10 @@ msgid "RAM Address" msgstr "Naslov RAM" msgid "RAM size" -msgstr "Velikost pomnilnika RAM" +msgstr "Velikost pomnilnika" msgid "Initial RAM size" -msgstr "Začetna velikost pomnilnika RAM" +msgstr "Začetna velikost pomnilnika" msgid "Serial Number" msgstr "Serijska številka" @@ -1597,7 +1597,7 @@ msgid "FDC Address" msgstr "Naslov FDC" msgid "MPU-401 Address" -msgstr "MPU-401 Naslov" +msgstr "Naslov MPU-401" msgid "MPU-401 IRQ" msgstr "MPU-401 IRQ" @@ -1633,7 +1633,7 @@ msgid "Enable OPL" msgstr "Omogoči OPL" msgid "Receive MIDI input (MPU-401)" -msgstr "Sprejemaj vhod MIDI (MPU-401)" +msgstr "Vhod MIDI za sprejem (MPU-401)" msgid "SB low DMA" msgstr "Nizki DMA SB" @@ -1666,7 +1666,7 @@ msgid "Codec" msgstr "Kodek" msgid "GUS type" -msgstr "Tip GUS" +msgstr "Vrsta GUS" msgid "Enable 0x04 \"Exit 86Box\" command" msgstr "Omogoči ukaz 0x04 \"Zapusti 86Box\"" @@ -1681,7 +1681,7 @@ msgid "RGB type" msgstr "Vrsta RGB zaslona" msgid "Line doubling type" -msgstr "Vrsta podvojitve črt" +msgstr "Vrsta podvojevanja črt" msgid "Snow emulation" msgstr "Emulacija snega" @@ -1693,16 +1693,16 @@ msgid "Character set" msgstr "Nabor znakov" msgid "XGA type" -msgstr "Tip kartice XGA" +msgstr "Vrsta kartice XGA" msgid "Instance" -msgstr "Primer" +msgstr "Primerek" msgid "MMIO Address" msgstr "Naslov MMIO" msgid "RAMDAC type" -msgstr "Vrsta čipa RAMDAC" +msgstr "Vrsta RAMDAC" msgid "Blend" msgstr "Mešanica" @@ -1714,13 +1714,13 @@ msgid "Dithering" msgstr "Barvno stresanje" msgid "Enable NMI for CGA emulation" -msgstr "Omogočite NMI za emulacijo CGA" +msgstr "Omogoči NMI za emulacijo CGA" msgid "Voodoo type" -msgstr "Tip kartice Voodoo" +msgstr "Vrsta kartice Voodoo" msgid "Framebuffer memory size" -msgstr "Velikost pomnilnika predpomnilnika okvirja" +msgstr "Velikost videopomnilnika" msgid "Texture memory size" msgstr "Velikost pomnilnika tekstur" @@ -1732,7 +1732,7 @@ msgid "Screen Filter" msgstr "Filter zaslona" msgid "Render threads" -msgstr "Nitke za upodabljanje" +msgstr "Niti za upodabljanje" msgid "SLI" msgstr "SLI" @@ -1795,7 +1795,7 @@ msgid "Non-timed (original)" msgstr "Brez časovnika (izvirnik)" msgid "45 Hz (JMP2 not populated)" -msgstr "45 Hz (brez mostička na JMP2)" +msgstr "45 Hz (brez mostička JMP2)" msgid "Two" msgstr "Dva" @@ -1804,13 +1804,13 @@ msgid "Three" msgstr "Tri" msgid "Wheel" -msgstr "Kolesa" +msgstr "Kolesce" msgid "Five + Wheel" -msgstr "Pet + kolo" +msgstr "Pet + kolesce" msgid "Five + 2 Wheels" -msgstr "" +msgstr "Pet + 2 kolesci" msgid "A3 - SMT2 Serial / SMT3(R)V" msgstr "A3 - SMT2 serijska / SMT3(R)V" @@ -1885,13 +1885,13 @@ msgid "Color (generic)" msgstr "Barvni (generični)" msgid "Green Monochrome" -msgstr "Zeleni enobvarni" +msgstr "Zeleni monokromatski" msgid "Amber Monochrome" -msgstr "Jantarni enobarvni" +msgstr "Jantarni monokromatski" msgid "Gray Monochrome" -msgstr "Sivi enobarvni" +msgstr "Sivi monokromatski" msgid "Color (no brown)" msgstr "Barvni (brez rjave)" @@ -1912,13 +1912,13 @@ msgid "128 KB" msgstr "128 KB" msgid "Monochrome (5151/MDA) (white)" -msgstr "Enobarvni (5151/MDA) (beli)" +msgstr "Monokromatski (5151/MDA) (beli)" msgid "Monochrome (5151/MDA) (green)" -msgstr "Enobarvni (5151/MDA) (zeleni)" +msgstr "Monokromatski (5151/MDA) (zeleni)" msgid "Monochrome (5151/MDA) (amber)" -msgstr "Enobarvni (5151/MDA) (jantarni)" +msgstr "Monokromatski (5151/MDA) (jantarni)" msgid "Color 40x25 (5153/CGA)" msgstr "Barvni 40x25 (5153/CGA)" @@ -1930,7 +1930,7 @@ msgid "Enhanced Color - Normal Mode (5154/ECD)" msgstr "Izboljšani barvni - običajni način (5154/ECD)" msgid "Enhanced Color - Enhanced Mode (5154/ECD)" -msgstr "Izboljšani barvni - Izboljšani način (5154/ECD)" +msgstr "Izboljšani barvni - izboljšani način (5154/ECD)" msgid "Green" msgstr "Zeleni" @@ -2008,7 +2008,7 @@ msgid "Generic PCL5e Printer" msgstr "Generični tiskalnik PCL5e" msgid "Parallel Line Internet Protocol" -msgstr "Internetni protokol za paralelno linijo" +msgstr "Internetni protokol za vzporedno linijo" msgid "Protection Dongle for Savage Quest" msgstr "Zaščitni ključek za Savage Quest" @@ -2029,7 +2029,7 @@ msgid "Data bits" msgstr "Podatkovni biti" msgid "Stop bits" -msgstr "Stop biti" +msgstr "Zaključni biti" msgid "Baud Rate of Passthrough" msgstr "Baudna hitrost prepusta" @@ -2038,7 +2038,7 @@ msgid "Named Pipe (Server)" msgstr "Poimenovana cev (Strežnik)" msgid "Host Serial Passthrough" -msgstr "Prepustno serijskih vrat gostitelja" +msgstr "Prepust serijskih vrat gostitelja" msgid "E&ject %1" msgstr "I&zvrzi %1" @@ -2053,7 +2053,7 @@ msgid "High performance impact" msgstr "Visok učinek na hitrost delovanja" msgid "[Generic] RAM Disk (max. speed)" -msgstr "[Generic] Pogon RAM (največja hitrost)" +msgstr "[Generic] Pomnilniški disk (največja hitrost)" msgid "[Generic] 1989 (3500 RPM)" msgstr "" @@ -2089,28 +2089,28 @@ msgid "Generic PC/AT Memory Expansion" msgstr "Generična razširitev pomnilnika PC/AT" msgid "Unable to find Dot-Matrix fonts" -msgstr "Matričnih pisav ni bilo mogoče najti" +msgstr "Ni bilo mogoče najti matričnih pisav" msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for the emulation of the Generic ESC/P Dot-Matrix Printer." -msgstr "Matrične pisave v imeniku \"roms/printer/fonts\" so potrebne za emulacijo generičnega matričnega tiskalnika ESC/P." +msgstr "Za emulacijo generičnega ESC/P matričnega tiskalnika so potrebne TrueType pisave v imeniku \"roms/printer/fonts\"." msgid "Inhibit multimedia keys" -msgstr "" +msgstr "Blokiraj multimedijske tipke" msgid "Ask for confirmation before saving settings" -msgstr "" +msgstr "Vprašaj za potrditev pred shranjevanjem nastavitev" msgid "Ask for confirmation before hard resetting" -msgstr "" +msgstr "Vprašaj za potrditev pred ponovnim zagonom" msgid "Ask for confirmation before quitting" -msgstr "" +msgstr "Vprašaj za potrditev pred izhodom" msgid "Display hotkey message when entering full-screen mode" -msgstr "" +msgstr "Prikaži obvestilo o bližnjični tipki pri prehodu v celozaslonski način" msgid "Options" -msgstr "" +msgstr "Možnosti" msgid "Model" msgstr "" @@ -2119,40 +2119,40 @@ msgid "Model:" msgstr "" msgid "Failed to initialize Vulkan renderer." -msgstr "" +msgstr "Inicializacija upodobljevalnika Vulkan ni uspela." msgid "GLSL Error" -msgstr "" +msgstr "Napaka GLSL" msgid "Could not load shader: %1" -msgstr "" +msgstr "Ni bilo mogoče naložiti senčilnika: %1" msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "" +msgstr "Potrebna je OpenGL različica 3.0 ali novejša. Trenutna različica GLSL je %1.%2" msgid "Could not load texture: %1" -msgstr "" +msgstr "Ni bilo mogoče naložiti teksture: %1" msgid "Could not compile shader:\n\n%1" -msgstr "" +msgstr "Ni bilo mogoče prevesti senčilnika:\n\n%1" msgid "Program not linked:\n\n%1" -msgstr "" +msgstr "Program ni povezan:\n\n%1" msgid "Shader Manager" -msgstr "" +msgstr "Upravljalnik senčilnikov" msgid "Shader Configuration" -msgstr "" +msgstr "Nastavitve senčilnikov" msgid "Add" -msgstr "" +msgstr "Dodaj" msgid "Move up" -msgstr "" +msgstr "Premakni gor" msgid "Move down" -msgstr "" +msgstr "Premakni dol" msgid "Could not load file %1" -msgstr "" +msgstr "Ni bilo mogoče naložiti datoteke %1" diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index dc0b923b4..c552ce0f4 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -189,6 +189,53 @@ MainWindow::MainWindow(QWidget *parent) ui->menuEGA_S_VGA_settings->menuAction()->setMenuRole(QAction::NoRole); ui->stackedWidget->setMouseTracking(true); statusBar()->setVisible(!hide_status_bar); + + num_icon = QIcon(":/settings/qt/icons/num_lock_on.ico"); + num_icon_off = QIcon(":/settings/qt/icons/num_lock_off.ico"); + scroll_icon = QIcon(":/settings/qt/icons/scroll_lock_on.ico"); + scroll_icon_off = QIcon(":/settings/qt/icons/scroll_lock_off.ico"); + caps_icon = QIcon(":/settings/qt/icons/caps_lock_on.ico"); + caps_icon_off = QIcon(":/settings/qt/icons/caps_lock_off.ico"); + kana_icon = QIcon(":/settings/qt/icons/kana_lock_on.ico"); + kana_icon_off = QIcon(":/settings/qt/icons/kana_lock_off.ico"); + + num_label = new QLabel; + num_label->setPixmap(num_icon_off.pixmap(QSize(16, 16))); + statusBar()->addPermanentWidget(num_label); + + caps_label = new QLabel; + caps_label->setPixmap(caps_icon_off.pixmap(QSize(16, 16))); + statusBar()->addPermanentWidget(caps_label); + + scroll_label = new QLabel; + scroll_label->setPixmap(scroll_icon_off.pixmap(QSize(16, 16))); + statusBar()->addPermanentWidget(scroll_label); + + kana_label = new QLabel; + kana_label->setPixmap(kana_icon_off.pixmap(QSize(16, 16))); + statusBar()->addPermanentWidget(kana_label); + + QTimer* ledKeyboardTimer = new QTimer(this); + ledKeyboardTimer->setTimerType(Qt::CoarseTimer); + ledKeyboardTimer->setInterval(1); + connect(ledKeyboardTimer, &QTimer::timeout, this, [this] () { + uint8_t caps, num, scroll, kana; + keyboard_get_states(&caps, &num, &scroll, &kana); + + if (num_label->isVisible()) + num_label->setPixmap(num ? this->num_icon.pixmap(QSize(16, 16)) : this->num_icon_off.pixmap(QSize(16, 16))); + if (caps_label->isVisible()) + caps_label->setPixmap(caps ? this->caps_icon.pixmap(QSize(16, 16)) : this->caps_icon_off.pixmap(QSize(16, 16))); + if (scroll_label->isVisible()) + scroll_label->setPixmap(scroll ? this->scroll_icon.pixmap(QSize(16, 16)) : + this->scroll_icon_off.pixmap(QSize(16, 16))); + + if (kana_label->isVisible()) + kana_label->setPixmap(kana ? this->kana_icon.pixmap(QSize(16, 16)) : + this->kana_icon_off.pixmap(QSize(16, 16))); + }); + ledKeyboardTimer->start(); + #ifdef Q_OS_WINDOWS util::setWin11RoundedCorners(this->winId(), (hide_status_bar ? false : true)); #endif @@ -216,6 +263,12 @@ MainWindow::MainWindow(QWidget *parent) connect(this, &MainWindow::hardResetCompleted, this, [this]() { ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); + num_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + scroll_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + caps_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + /* TODO: Base this on keyboard type instead when that's done. */ + kana_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD) && + machine_has_flags(machine, MACHINE_AX)); while (QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); #ifdef USE_WACOM @@ -1458,6 +1511,12 @@ MainWindow::refreshMediaMenu() status->refresh(ui->statusbar); ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); ui->actionACPI_Shutdown->setEnabled(!!acpi_enabled); + + num_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + scroll_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + caps_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + kana_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD) && + machine_has_flags(machine, MACHINE_AX)); } void diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 1798c8a75..5cda49fa8 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -5,7 +5,9 @@ #include #include #include +#include #include +#include #include #include @@ -190,6 +192,10 @@ private: friend class RendererStack; // For UI variable access by non-primary renderer windows. friend class WindowsRawInputFilter; // Needed to reload renderers on style sheet changes. + QLabel *caps_label, *scroll_label, *num_label, *kana_label; + QIcon caps_icon, scroll_icon, num_icon, kana_icon; + QIcon caps_icon_off, scroll_icon_off, num_icon_off, kana_icon_off; + bool isShowMessage = false; }; diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 306da575f..e94101a77 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -64,6 +64,8 @@ extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1); #include "qt_rendererstack.hpp" #include "ui_qt_mainwindow.h" +static bool NewDarkMode = FALSE; + bool windows_is_light_theme() { // based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application @@ -220,6 +222,14 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess if ((((void *) msg->lParam) != nullptr) && (wcscmp(L"ImmersiveColorSet", (wchar_t*)msg->lParam) == 0)) { + bool OldDarkMode = NewDarkMode; +#if 0 + if (do_auto_pause && !dopause) { + auto_paused = 1; + plat_pause(1); + } +#endif + if (!windows_is_light_theme()) { QFile f(":qdarkstyle/dark/darkstyle.qss"); @@ -228,45 +238,39 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess else { f.open(QFile::ReadOnly | QFile::Text); QTextStream ts(&f); - qApp->setStyleSheet(ts.readAll()); + qApp->setStyleSheet(ts.readAll()); } - QTimer::singleShot(1000, [this] () { - BOOL DarkMode = TRUE; - auto vid_stack = (RendererStack::Renderer) vid_api; - DwmSetWindowAttribute((HWND) window->winId(), - DWMWA_USE_IMMERSIVE_DARK_MODE, - (LPCVOID) &DarkMode, - sizeof(DarkMode)); - window->ui->stackedWidget->switchRenderer(vid_stack); - for (int i = 1; i < MONITORS_NUM; i++) { - if ((window->renderers[i] != nullptr) && - !window->renderers[i]->isHidden()) - window->renderers[i]->switchRenderer(vid_stack); - } - }); + NewDarkMode = TRUE; } else { qApp->setStyleSheet(""); - QTimer::singleShot(1000, [this] () { - BOOL DarkMode = FALSE; - DwmSetWindowAttribute((HWND) window->winId(), - DWMWA_USE_IMMERSIVE_DARK_MODE, - (LPCVOID) &DarkMode, - sizeof(DarkMode)); - }); + NewDarkMode = FALSE; } - QTimer::singleShot(1000, [this] () { + if (NewDarkMode != OldDarkMode) QTimer::singleShot(1000, [this] () { + BOOL DarkMode = NewDarkMode; + DwmSetWindowAttribute((HWND) window->winId(), + DWMWA_USE_IMMERSIVE_DARK_MODE, + (LPCVOID) &DarkMode, + sizeof(DarkMode)); + window->resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y); + for (int i = 1; i < MONITORS_NUM; i++) { auto mon = &(monitors[i]); if ((window->renderers[i] != nullptr) && !window->renderers[i]->isHidden()) window->resizeContentsMonitor(mon->mon_scrnsz_x, - mon->mon_scrnsz_y, - i); + mon->mon_scrnsz_y, i); } + +#if 0 + if (auto_paused) { + plat_pause(0); + auto_paused = 0; + } +#endif }); } break; diff --git a/src/qt_resources.qrc b/src/qt_resources.qrc index bc553ac61..a5963c152 100644 --- a/src/qt_resources.qrc +++ b/src/qt_resources.qrc @@ -34,6 +34,14 @@ qt/icons/86Box-green.ico qt/icons/86Box-red.ico qt/icons/86Box-yellow.ico + qt/icons/caps_lock_off.ico + qt/icons/caps_lock_on.ico + qt/icons/kana_lock_off.ico + qt/icons/kana_lock_on.ico + qt/icons/num_lock_off.ico + qt/icons/num_lock_on.ico + qt/icons/scroll_lock_off.ico + qt/icons/scroll_lock_on.ico qt/icons/acpi_shutdown.ico diff --git a/src/sio/sio_fdc37c6xx.c b/src/sio/sio_fdc37c6xx.c index 0f3460565..3afd92e4c 100644 --- a/src/sio/sio_fdc37c6xx.c +++ b/src/sio/sio_fdc37c6xx.c @@ -232,7 +232,7 @@ fdc37c6xx_read(uint16_t port, void *priv) uint8_t ret = 0xff; if (dev->tries == 2) { - if (port == 0x3f1) + if ((port == 0x3f1) && (dev->cur_reg <= dev->max_reg)) ret = dev->regs[dev->cur_reg]; } diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 8d8f76cb6..ebc500c96 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -15,8 +15,9 @@ * * Copyright 2016-2018 Miran Grca. */ -#include +#include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include <86box/timer.h> #include <86box/device.h> #include <86box/pci.h> +#include <86box/pic.h> #include <86box/lpt.h> #include <86box/serial.h> #include <86box/hdc.h> @@ -37,20 +39,28 @@ #include <86box/apm.h> #include <86box/access_bus.h> #include <86box/acpi.h> -#include <86box/sio.h> +#include <86box/plat.h> #include <86box/plat_unused.h> +#include <86box/video.h> +#include <86box/sio.h> +#include "cpu.h" typedef struct fdc37c93x_t { uint8_t chip_id; uint8_t is_apm; uint8_t is_compaq; uint8_t has_nvr; + uint8_t max_ld; uint8_t tries; uint8_t port_370; - uint8_t gpio_regs[2]; + uint8_t gpio_reg; + uint8_t gpio_regs[256]; + uint8_t gpio_pulldn[8]; uint8_t auxio_reg; uint8_t regs[48]; + uint8_t alt_regs[3][8]; uint8_t ld_regs[11][256]; + uint16_t kbc_type; uint16_t superio_base; uint16_t fdc_base; uint16_t lpt_base; @@ -73,6 +83,15 @@ typedef struct fdc37c93x_t { static void fdc37c93x_write(uint16_t port, uint8_t val, void *priv); static uint8_t fdc37c93x_read(uint16_t port, void *priv); +static uint8_t gp_func_regs[8][8] = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, /* GP00-GP07 */ + { 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7 }, /* GP10-GP17 */ + { 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef }, /* GP20-GP27 */ + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, /* GP30-GP37 */ + { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 }, /* GP40-GP47 */ + { 0xc8, 0xc9, 0xff, 0xcb, 0xcc, 0xff, 0xff, 0xff }, /* GP50-GP57 */ + { 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7 }, /* GP60-GP67 */ + { 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf } }; /* GP70-GP77 */ + static uint16_t make_port_superio(const fdc37c93x_t *dev) { @@ -122,14 +141,562 @@ fdc37c93x_auxio_write(UNUSED(uint16_t port), uint8_t val, void *priv) dev->auxio_reg = val; } +static __inline uint8_t +fdc37c93x_do_read_gp(fdc37c93x_t *dev, int reg, int bit) +{ + /* Update bit 2 on the Acer V35N according to the selected graphics card type. */ + if ((reg == 2) && (strstr(machine_get_internal_name(), "acer") != NULL)) + dev->gpio_pulldn[reg] = (dev->gpio_pulldn[reg] & 0xfb) | (video_is_mda() ? 0x00 : 0x04); + + return dev->gpio_regs[reg] & dev->gpio_pulldn[reg] & (1 << bit); +} + +static __inline uint8_t +fdc37c93x_do_read_alt(const fdc37c93x_t *dev, int alt, int reg, int bit) +{ + return dev->alt_regs[alt][reg] & (1 << bit); +} + +static uint8_t +fdc37c93x_read_gp(const fdc37c93x_t *dev, int reg, int bit) +{ + uint8_t gp_reg = gp_func_regs[reg][bit]; + uint8_t gp_func_reg = dev->ld_regs[0x08][gp_reg]; + uint8_t gp_func; + uint8_t ret = 1 << bit; + + if (gp_func_reg & 0x01) switch (reg) { + default: + /* Do nothing, this GP does not exist. */ + break; + case 1: + switch (bit) { + default: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + else + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + gp_func = (gp_func_reg >> 3) & 0x03; + if (!(gp_func & 0x01)) { + if (gp_func & 0x02) + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + else + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + } + break; + case 3: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x01) + /* TODO: Write to power LED if it's ever implemented. */ + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + else + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 6: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 1 ... 3: + ret = fdc37c93x_do_read_alt(dev, gp_func - 1, reg, bit); + break; + } + break; + } + break; + case 2: + switch (bit) { + default: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + else + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 0: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 2: + ret = kbc_at_read_p(dev->kbc, 2, 0x01) ? (1 << bit) : 0x00; + break; + } + break; + case 1: case 2: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 1: case 2: + ret = fdc37c93x_do_read_alt(dev, gp_func - 1, reg, bit); + break; + } + break; + case 5: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + else + ret = kbc_at_read_p(dev->kbc, 2, 0x02) ? (1 << bit) : 0x00; + break; + case 6: case 7: + /* Do nothing, these bits do not exist. */ + break; + } + break; + case 4: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + } + break; + case 0: case 1: + switch (gp_func) { + case 0: + ret = fdc_get_media_id(dev->fdc, bit ^ 1) ? (1 << bit) : 0x00; + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + } + break; + case 6: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 2: + /* TODO: Write to power LED if it's ever implemented. */ + ret = fdc37c93x_do_read_alt(dev, 1, reg, bit); + break; + case 3: + ret = fdc37c93x_do_read_alt(dev, 2, reg, bit); + break; + } + break; + case 7: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 2: + ret = fdc37c93x_do_read_alt(dev, 1, reg, bit); + break; + } + break; + } + break; + case 5: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + break; + case 0: case 3: case 4: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + } + break; + case 1: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + } + break; + } + break; + case 6: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 2: + ret = kbc_at_read_p(dev->kbc, 1, 1 << bit); + break; + } + break; + case 0: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 2: + /* TODO: Write to power LED if it's ever implemented. */ + ret = fdc37c93x_do_read_alt(dev, 1, reg, bit); + break; + } + break; + case 1: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 2: + ret = fdc37c93x_do_read_alt(dev, 1, reg, bit); + break; + } + break; + } + break; + case 7: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + } + break; + } + break; + } + + if (gp_func_reg & 0x02) + ret ^= (1 << bit); + + return ret; +} + +static __inline void +fdc37c93x_do_write_gp(fdc37c93x_t *dev, int reg, int bit, int set) +{ + dev->gpio_regs[reg] = (dev->gpio_regs[reg] & ~(1 << bit)) | + (set << bit); +} + +static __inline void +fdc37c93x_do_write_alt(fdc37c93x_t *dev, int alt, int reg, int bit, int set) +{ + dev->alt_regs[alt][reg] = (dev->alt_regs[alt][reg] & ~(1 << bit)) | + (set << bit); +} + +static void +fdc37c93x_write_gp(fdc37c93x_t *dev, int reg, int bit, int set) +{ + uint8_t gp_func_reg = dev->ld_regs[0x08][gp_func_regs[reg][bit]]; + uint8_t gp_func; + + if (gp_func_reg & 0x02) + set = !set; + + if (!(gp_func_reg & 0x01)) switch (reg) { + default: + /* Do nothing, this GP does not exist. */ + break; + case 1: + switch (bit) { + default: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + fdc37c93x_do_write_gp(dev, reg, bit, set); + else + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + gp_func = (gp_func_reg >> 3) & 0x03; + if (!(gp_func & 0x01)) { + if (gp_func & 0x02) { + set ? picint(1 << 13) : picintc(1 << 13); + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + } else + fdc37c93x_do_write_gp(dev, reg, bit, set); + } + break; + case 3: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x01) + /* TODO: Write to power LED if it's ever implemented. */ + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + else + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 6: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 1 ... 3: + fdc37c93x_do_write_alt(dev, gp_func - 1, reg, bit, set); + break; + } + break; + } + break; + case 2: + switch (bit) { + default: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + fdc37c93x_do_write_gp(dev, reg, bit, set); + else + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 0: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 2: + kbc_at_write_p(dev->kbc, 2, 0xfe, set); + break; + } + break; + case 1: case 2: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 1: case 2: + fdc37c93x_do_write_alt(dev, gp_func - 1, reg, bit, set); + break; + } + break; + case 5: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + fdc37c93x_do_write_gp(dev, reg, bit, set); + else + kbc_at_write_p(dev->kbc, 2, 0xfd, set << 1); + break; + case 6: case 7: + /* Do nothing, these bits do not exist. */ + break; + } + break; + case 4: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + } + break; + case 0: case 1: + switch (gp_func) { + case 0: + fdc_set_media_id(dev->fdc, bit ^ 1, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + } + break; + case 6: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 2: + /* TODO: Write to power LED if it's ever implemented. */ + fdc37c93x_do_write_alt(dev, 1, reg, bit, set); + break; + case 3: + fdc37c93x_do_write_alt(dev, 2, reg, bit, set); + break; + } + break; + case 7: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 2: + fdc37c93x_do_write_alt(dev, 1, reg, bit, set); + if (!set) + smi_raise(); + break; + } + break; + } + break; + case 5: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + break; + case 0: case 3: case 4: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + } + break; + case 1: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + if (set) + plat_power_off(); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + } + break; + } + break; + case 6: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 2: + kbc_at_write_p(dev->kbc, 1, ~(1 << bit), set << bit); + break; + } + break; + case 0: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 2: + /* TODO: Write to power LED if it's ever implemented. */ + fdc37c93x_do_write_alt(dev, 1, reg, bit, set); + break; + } + break; + case 1: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 2: + fdc37c93x_do_write_alt(dev, 1, reg, bit, set); + break; + } + break; + } + break; + case 7: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + } + break; + } + break; + } +} + static uint8_t fdc37c93x_gpio_read(uint16_t port, void *priv) { const fdc37c93x_t *dev = (fdc37c93x_t *) priv; uint8_t ret = 0xff; - if (strcmp(machine_get_internal_name(), "vectra54")) - ret = dev->gpio_regs[port & 1]; + if (dev->locked) { + if (dev->is_compaq) + ret = fdc37c93x_read(port & 0x0001, priv); + } else if (port & 0x0001) switch (dev->gpio_reg) { + case 0x01: case 0x02: + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, dev->gpio_reg, i); + break; + case 0x03: + ret = dev->ld_regs[0x08][0xf4]; + break; + case 0x04 ... 0x07: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, dev->gpio_reg, i); + } + break; + case 0x08 ... 0x0f: + if (dev->chip_id >= FDC37C93X_FR) + ret = dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08]; + break; + } else + ret = dev->gpio_reg; return ret; } @@ -139,8 +706,52 @@ fdc37c93x_gpio_write(uint16_t port, uint8_t val, void *priv) { fdc37c93x_t *dev = (fdc37c93x_t *) priv; - if (!(port & 1)) - dev->gpio_regs[0] = (dev->gpio_regs[0] & 0xfc) | (val & 0x03); + if (dev->locked) { + if (dev->is_compaq) + fdc37c93x_write(port & 0x0001, val, priv); + } else if (port & 0x0001) switch (dev->gpio_reg) { + case 0x01: case 0x02: + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, dev->gpio_reg, i, val & (1 << i)); + break; + case 0x03: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x08][0xf4] = val & 0xef; + else + dev->ld_regs[0x08][0xf4] = val & 0x0f; + break; + case 0x04 ... 0x07: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, dev->gpio_reg, i, val & (1 << i)); + break; + case 0x08: case 0x0a: + case 0x0c: case 0x0e: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val; + break; + case 0x09: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0xd3; + break; + case 0x0b: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0x17; + break; + case 0x0d: + if (dev->chip_id == FDC37C93X_APM) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val; + else if (dev->chip_id == FDC37C93X_FR) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0xbf; + break; + case 0x0f: + if (dev->chip_id == FDC37C93X_APM) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0x7f; + else if (dev->chip_id == FDC37C93X_FR) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0x3f; + break; + } else + dev->gpio_reg = val; } static void @@ -226,7 +837,14 @@ fdc37c93x_serial_handler(fdc37c93x_t *dev, const int uart) serial_setup(dev->uart[uart], dev->uart_base[uart], dev->ld_regs[uart_no][0x70]); } - serial_irq(dev->uart[uart], dev->ld_regs[uart_no][0x70]); + /* + TODO: If UART 2's own IRQ pin is also enabled when shared, + it should also be asserted. + */ + if ((dev->chip_id >= FDC37C93X_FR) && (dev->ld_regs[4][0xf0] & 0x80)) + serial_irq(dev->uart[uart], dev->ld_regs[4][0x70]); + else + serial_irq(dev->uart[uart], dev->ld_regs[uart_no][0x70]); } static void @@ -304,7 +922,8 @@ fdc37c93x_auxio_handler(fdc37c93x_t *dev) static void fdc37c93x_gpio_handler(fdc37c93x_t *dev) { - const uint8_t local_enable = !dev->locked && !!(dev->regs[0x03] & 0x80); + const uint8_t local_enable = !!(dev->regs[0x03] & 0x80) || + (dev->is_compaq && dev->locked); const uint16_t old_base = dev->gpio_base; dev->gpio_base = 0x0000; @@ -383,23 +1002,15 @@ static void fdc37c93x_write(uint16_t port, uint8_t val, void *priv) { fdc37c93x_t *dev = (fdc37c93x_t *) priv; - uint8_t index = (port & 1) ? 0 : 1; + uint8_t index = !(port & 1); uint8_t valxor; - /* Compaq Presario 4500: Unlock at FB, Register at EA, Data at EB, Lock at F9. */ - if (port == 0xea) - index = 1; - else if (port == 0xeb) - index = 0; - - if (port == 0xfb) { + if (port == 0x00fb) { fdc37c93x_state_change(dev, 1); dev->tries = 0; - return; - } else if (port == 0xf9) { + } else if (port == 0x00f9) fdc37c93x_state_change(dev, 0); - return; - } else if (index) { + else if (index) { if ((!dev->is_compaq) && (val == 0x55) && !dev->locked) { if (dev->tries) { fdc37c93x_state_change(dev, 1); @@ -407,338 +1018,480 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) } else dev->tries++; } else if (dev->locked) { - if ((!dev->is_compaq) && (val == 0xaa)) { + if ((!dev->is_compaq) && (val == 0xaa)) fdc37c93x_state_change(dev, 0); - return; - } - dev->cur_reg = val; + else + dev->cur_reg = val; } else if ((!dev->is_compaq) && dev->tries) dev->tries = 0; - return; - } else { - if (dev->locked) { - if (dev->cur_reg < 48) { - valxor = val ^ dev->regs[dev->cur_reg]; - if ((val == 0x20) || (val == 0x21)) - return; - dev->regs[dev->cur_reg] = val; - } else { - uint8_t keep = 0x00; + } else if (dev->locked) { + if (dev->cur_reg < 0x30) { + valxor = val ^ dev->regs[dev->cur_reg]; - valxor = val ^ dev->ld_regs[dev->regs[7]][dev->cur_reg]; - if (((dev->cur_reg & 0xF0) == 0x70) && (dev->regs[7] < 4)) - return; - /* Block writes to some logical devices. */ - if (dev->regs[7] > 0x0a) - return; - else - switch (dev->regs[7]) { - // case 0x01: - // case 0x02: - // return; - case 0x06: - if (!dev->has_nvr) - return; - /* Bits 0 to 3 of logical device 6 (RTC) register F0h must stay set - once they are set. */ - else if (dev->cur_reg == 0xf0) - keep = dev->ld_regs[dev->regs[7]][dev->cur_reg] & 0x0f; - break; - case 0x09: - /* If we're on the FDC37C935, return as this is not a valid - logical device there. */ - if (!dev->is_apm && (dev->chip_id == 0x02)) - return; - break; - case 0x0a: - /* If we're not on the FDC37C931APM, return as this is not a - valid logical device there. */ - if (!dev->is_apm) - return; - break; - - default: - break; - } - dev->ld_regs[dev->regs[7]][dev->cur_reg] = val | keep; - } - } else - return; - } - - if (dev->cur_reg < 48) { - switch (dev->cur_reg) { - case 0x02: - if (val == 0x02) - fdc37c93x_state_change(dev, 0); - break; - case 0x03: - dev->regs[0x03] &= 0x83; - break; - case 0x22: - if (valxor & 0x01) - fdc37c93x_fdc_handler(dev); - if (valxor & 0x08) - fdc37c93x_lpt_handler(dev); - if (valxor & 0x10) - fdc37c93x_serial_handler(dev, 0); - if (valxor & 0x20) - fdc37c93x_serial_handler(dev, 1); - if ((valxor & 0x40) && (dev->chip_id != 0x02)) - fdc37c93x_access_bus_handler(dev); - break; - - case 0x27: - if (dev->chip_id != 0x02) - fdc37c93x_superio_handler(dev); - break; - - default: - break; - } - - return; - } - - switch (dev->regs[7]) { - case 0: - /* FDD */ switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x01; - if (valxor) - fdc37c93x_fdc_handler(dev); + case 0x02: + dev->regs[dev->cur_reg] = val; + if (val == 0x02) + fdc37c93x_state_change(dev, 0); break; - case 0xF0: + case 0x03: + dev->regs[dev->cur_reg] = val & 0x83; + break; + case 0x07: case 0x26: + case 0x2e ... 0x2f: + dev->regs[dev->cur_reg] = val; + break; + case 0x22: + if (dev->chip_id >= FDC37C93X_FR) + dev->regs[dev->cur_reg] = val & 0x7f; + else + dev->regs[dev->cur_reg] = val & 0x6f; + if (valxor & 0x01) - fdc_update_enh_mode(dev->fdc, val & 0x01); - if (valxor & 0x10) - fdc_set_swap(dev->fdc, (val & 0x10) >> 4); - break; - case 0xF1: - if (valxor & 0xC) - fdc_update_densel_force(dev->fdc, (val & 0xc) >> 2); - break; - case 0xF2: - if (valxor & 0xC0) - fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); - if (valxor & 0x30) - fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); - if (valxor & 0x0C) - fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); - if (valxor & 0x03) - fdc_update_rwc(dev->fdc, 0, (val & 0x03)); - break; - case 0xF4: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 0, (val & 0x18) >> 3); - break; - case 0xF5: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 1, (val & 0x18) >> 3); - break; - case 0xF6: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 2, (val & 0x18) >> 3); - break; - case 0xF7: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 3, (val & 0x18) >> 3); - break; - - default: - break; - } - break; - case 3: - /* Parallel port */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x08; - if (valxor) + fdc37c93x_fdc_handler(dev); + if (valxor & 0x08) fdc37c93x_lpt_handler(dev); - break; - - default: - break; - } - break; - case 4: - /* Serial port 1 */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x10; - if (valxor) + if (valxor & 0x10) fdc37c93x_serial_handler(dev, 0); - break; - - default: - break; - } - break; - case 5: - /* Serial port 2 */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x20; - if (valxor) + if (valxor & 0x20) fdc37c93x_serial_handler(dev, 1); - break; - - default: - break; - } - break; - case 6: - /* RTC/NVR */ - if (!dev->has_nvr) - return; - switch (dev->cur_reg) { - case 0x30: - if (valxor) { - fdc37c93x_nvr_pri_handler(dev); - if (dev->chip_id != 0x02) - fdc37c93x_nvr_sec_handler(dev); - } - break; - case 0x62: - case 0x63: - if ((dev->chip_id != 0x02) && valxor) - fdc37c93x_nvr_sec_handler(dev); - break; - case 0xf0: - if (valxor) { - nvr_lock_set(0x80, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x01), dev->nvr); - nvr_lock_set(0xa0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x02), dev->nvr); - nvr_lock_set(0xc0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x04), dev->nvr); - nvr_lock_set(0xe0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x08), dev->nvr); - if ((dev->chip_id == 0x02) && (dev->ld_regs[6][dev->cur_reg] & 0x80)) - nvr_bank_set(0, 1, dev->nvr); - else if ((dev->chip_id != 0x02) && (dev->ld_regs[6][dev->cur_reg] & 0x80)) - switch ((dev->ld_regs[6][dev->cur_reg] >> 4) & 0x07) { - default: - case 0x00: - nvr_bank_set(0, 0xff, dev->nvr); - nvr_bank_set(1, 1, dev->nvr); - break; - case 0x01: - nvr_bank_set(0, 0, dev->nvr); - nvr_bank_set(1, 1, dev->nvr); - break; - case 0x02: - case 0x04: - nvr_bank_set(0, 0xff, dev->nvr); - nvr_bank_set(1, 0xff, dev->nvr); - break; - case 0x03: - case 0x05: - nvr_bank_set(0, 0, dev->nvr); - nvr_bank_set(1, 0xff, dev->nvr); - break; - case 0x06: - nvr_bank_set(0, 0xff, dev->nvr); - nvr_bank_set(1, 2, dev->nvr); - break; - case 0x07: - nvr_bank_set(0, 0, dev->nvr); - nvr_bank_set(1, 2, dev->nvr); - break; - } - else { - nvr_bank_set(0, 0, dev->nvr); - if (dev->chip_id != 0x02) - nvr_bank_set(1, 0xff, dev->nvr); - } - - fdc37c93x_nvr_pri_handler(dev); - if (dev->chip_id != 0x02) - fdc37c93x_nvr_sec_handler(dev); - } - break; - - default: - break; - } - break; - case 7: - /* Keyboard */ - switch (dev->cur_reg) { - case 0x30: - if (valxor) - fdc37c93x_kbc_handler(dev); - break; - - default: - break; - } - break; - case 8: - /* Auxiliary I/O */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if (valxor) - fdc37c93x_auxio_handler(dev); - break; - - default: - break; - } - break; - case 9: - /* Access bus (FDC37C932FR and FDC37C931APM only) */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x40; - if (valxor) + if ((dev->chip_id >= FDC37C93X_FR) && (valxor & 0x40)) fdc37c93x_access_bus_handler(dev); break; + case 0x23: + if (dev->chip_id >= FDC37C93X_FR) + dev->regs[dev->cur_reg] = val & 0x7f; + else + dev->regs[dev->cur_reg] = val & 0x6f; + break; + case 0x24: + if (dev->chip_id >= FDC37C93X_FR) + dev->regs[dev->cur_reg] = val & 0xcf; + else + dev->regs[dev->cur_reg] = val & 0xcc; + + if ((dev->chip_id >= FDC37C93X_FR) && (valxor & 0x01)) { + serial_set_clock_src(dev->uart[0], (val & 0x01) ? + 48000000.0 : 24000000.0); + serial_set_clock_src(dev->uart[1], (val & 0x01) ? + 48000000.0 : 24000000.0); + } + break; + case 0x27: + if (dev->chip_id >= FDC37C93X_FR) { + dev->regs[dev->cur_reg] = val; + + fdc37c93x_superio_handler(dev); + } + break; + case 0x28: + if (dev->chip_id >= FDC37C93X_FR) + dev->regs[dev->cur_reg] = val & 0x1f; + break; default: break; } - break; - case 10: - /* Access bus (FDC37C931APM only) */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x70: - if (valxor) - fdc37c93x_acpi_handler(dev); - break; + } else { + valxor = val ^ dev->ld_regs[dev->regs[7]][dev->cur_reg]; - default: + if ((dev->regs[7] <= dev->max_ld) && ((dev->regs[7] != 0x08) || + (dev->cur_reg < 0xb0) || (dev->cur_reg > 0xdf) || + (dev->chip_id >= FDC37C93X_FR))) switch (dev->regs[7]) { + case 0x00: /* FDD */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x01; + if (valxor) + fdc37c93x_fdc_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1f; + + if (valxor & 0x01) + fdc_update_enh_mode(dev->fdc, val & 0x01); + if (valxor & 0x10) + fdc_set_swap(dev->fdc, (val & 0x10) >> 4); + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xfc; + + if (valxor & 0x0c) + fdc_update_densel_force(dev->fdc, (val & 0xc) >> 2); + break; + case 0xf2: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, (val & 0x03)); + break; + case 0xf4 ... 0xf7: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x5b; + + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, dev->cur_reg - 0xf4, + (val & 0x18) >> 3); + break; + } + break; + case 0x01: /* IDE1 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x02; + break; + case 0xf0: case 0xf1: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1f; + else if (dev->cur_reg == 0xf0) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + } + break; + case 0x02: /* IDE2 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x04; + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x01; + break; + } + break; + case 0x03: /* Parallel Port */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x08; + if (valxor) + fdc37c93x_lpt_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xf1: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + break; + } + break; + case 0x04: /* Serial port 1 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x10; + if (valxor) + fdc37c93x_serial_handler(dev, 0); + break; + /* TODO: Bit 0 = MIDI Mode, Bit 1 = High speed. */ + case 0xf0: + if (dev->chip_id >= FDC37C93X_FR) { + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x83; + } else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + + if (valxor & 0x83) { + fdc37c93x_serial_handler(dev, 0); + fdc37c93x_serial_handler(dev, 1); + } + break; + } + break; + case 0x05: /* Serial port 2 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + case 0x74: + if (((dev->cur_reg != 0x62) && (dev->cur_reg != 0x63)) || + (dev->chip_id == FDC37C93X_FR)) { + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x20; + if (valxor) + fdc37c93x_serial_handler(dev, 1); + } + break; + /* TODO: Bit 0 = MIDI Mode, Bit 1 = High speed. */ + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + + if (valxor & 0x03) { + fdc37c93x_serial_handler(dev, 0); + fdc37c93x_serial_handler(dev, 1); + } + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x7f; + break; + case 0xf2: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + } + break; + case 0x06: /* RTC */ + switch (dev->cur_reg) { + case 0x30: + // case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + if (((dev->cur_reg != 0x62) && (dev->cur_reg != 0x63)) || + (dev->chip_id >= FDC37C93X_FR)) { + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) { + fdc37c93x_nvr_pri_handler(dev); + + if (dev->chip_id >= FDC37C93X_FR) + fdc37c93x_nvr_sec_handler(dev); + } + } + break; + case 0xf0: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x8f; + + if (valxor) { + nvr_lock_set(0x80, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x01), dev->nvr); + nvr_lock_set(0xa0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x02), dev->nvr); + nvr_lock_set(0xc0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x04), dev->nvr); + nvr_lock_set(0xe0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x08), dev->nvr); + if (dev->ld_regs[6][dev->cur_reg] & 0x80) { + if (dev->chip_id == FDC37C93X_NORMAL) + nvr_bank_set(0, 1, dev->nvr); + else switch ((dev->ld_regs[6][dev->cur_reg] >> 4) & 0x07) { + case 0x00: + default: + nvr_bank_set(0, 0xff, dev->nvr); + nvr_bank_set(1, 1, dev->nvr); + break; + case 0x01: + nvr_bank_set(0, 0, dev->nvr); + nvr_bank_set(1, 1, dev->nvr); + break; + case 0x02: case 0x04: + nvr_bank_set(0, 0xff, dev->nvr); + nvr_bank_set(1, 0xff, dev->nvr); + break; + case 0x03: case 0x05: + nvr_bank_set(0, 0, dev->nvr); + nvr_bank_set(1, 0xff, dev->nvr); + break; + case 0x06: + nvr_bank_set(0, 0xff, dev->nvr); + nvr_bank_set(1, 2, dev->nvr); + break; + case 0x07: + nvr_bank_set(0, 0, dev->nvr); + nvr_bank_set(1, 2, dev->nvr); + break; + } + } else { + nvr_bank_set(0, 0, dev->nvr); + if (dev->chip_id >= FDC37C93X_FR) + nvr_bank_set(1, 0xff, dev->nvr); + } + + fdc37c93x_nvr_pri_handler(dev); + if (dev->chip_id >= FDC37C93X_FR) + fdc37c93x_nvr_sec_handler(dev); + } + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1f; + break; + case 0xf2: case 0xf3: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xf4: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x83; + break; + } + break; + case 0x07: /* Keyboard */ + switch (dev->cur_reg) { + case 0x30: + case 0x70: case 0x71: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + fdc37c93x_kbc_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x87; + break; + } + break; + case 0x08: /* Aux. I/O */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + fdc37c93x_auxio_handler(dev); + break; + case 0xb0: case 0xb2: + case 0xb4: case 0xb6: + case 0xe0: case 0xe1: + case 0xe9: case 0xf2: + case 0xf3: + case 0xc0 ... 0xc9: + case 0xcb ... 0xcc: + case 0xd0 ... 0xdf: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xb1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xd3; + break; + case 0xb3: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x17; + break; + case 0xb5: + if (dev->chip_id == FDC37C93X_APM) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xbf; + break; + case 0xb7: + if (dev->chip_id == FDC37C93X_APM) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x7f; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x3f; + break; + case 0xb8: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x3f; + break; + case 0x18: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x18; + break; + case 0xe2 ... 0xe5: + case 0xe7: + case 0xeb ... 0xed: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0f; + break; + case 0xe6: case 0xe8: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1f; + break; + case 0xea: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x9f; + break; + case 0xef: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xf8; + break; + case 0xf1: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x83; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + break; + case 0xf4: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xef; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0f; + break; + case 0xf6: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 1, i, val & (1 << i)); + break; + case 0xf7: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 2, i, val & (1 << i)); + break; + case 0xf8: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 4, i, val & (1 << i)); + break; + case 0xf9: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 5, i, val & (1 << i)); + break; + case 0xfa: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 6, i, val & (1 << i)); + break; + case 0xfb: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 7, i, val & (1 << i)); + break; + } + break; + case 0x09: /* Access.Bus */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x40; + if (valxor) + fdc37c93x_access_bus_handler(dev); + break; + } + break; + case 0x0a: /* ACPI */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + fdc37c93x_acpi_handler(dev); + break; + } break; } - break; - - default: - break; + } } } @@ -764,11 +1517,58 @@ fdc37c93x_read(uint16_t port, void *priv) ret = dev->chip_id; else ret = dev->regs[dev->cur_reg]; - } else { - if ((dev->regs[7] == 0) && (dev->cur_reg == 0xF2)) { - ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); - } else + } else if (dev->regs[7] <= dev->max_ld) { + if ((dev->regs[7] == 0x00) && (dev->cur_reg == 0xf2)) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | + (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); + else if ((dev->regs[7] != 0x06) || (dev->cur_reg != 0xf3)) ret = dev->ld_regs[dev->regs[7]][dev->cur_reg]; + else if ((dev->regs[7] == 0x08) && (dev->cur_reg >= 0xf6) && + (dev->cur_reg <= 0xfb) && + (dev->chip_id >= FDC37C93X_FR)) switch (dev->cur_reg) { + case 0xf6: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 1, i); + } + break; + case 0xf7: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 2, i); + } + break; + case 0xf8: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 4, i); + } + break; + case 0xf9: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 5, i); + } + break; + case 0xfa: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 6, i); + } + break; + case 0xfb: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 7, i); + } + break; + } } } } @@ -786,10 +1586,12 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->regs[0x21] = 0x01; dev->regs[0x22] = 0x39; dev->regs[0x24] = 0x04; - dev->regs[0x26] = dev->port_370 ? 0x70 : 0xf0; + if (dev->chip_id >= FDC37C93X_FR) + dev->regs[0x26] = dev->port_370 ? 0x70 : 0xf0; dev->regs[0x27] = 0x03; - memset(dev->ld_regs, 0x00, sizeof(dev->ld_regs)); + for (uint8_t i = 0; i <= 0x0a; i++) + memset(dev->ld_regs[i], 0x00, 256); /* Logical device 0: FDD */ dev->ld_regs[0x00][0x30] = 0x00; @@ -807,7 +1609,8 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->ld_regs[0x01][0x62] = 0x03; dev->ld_regs[0x01][0x63] = 0xf6; dev->ld_regs[0x01][0x70] = 0x0e; - dev->ld_regs[0x01][0xf0] = 0x0c; + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x01][0xf0] = 0x0c; /* Logical device 2: IDE2 */ dev->ld_regs[0x02][0x30] = 0x00; @@ -840,7 +1643,8 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->ld_regs[0x05][0x70] = 0x03; dev->ld_regs[0x05][0x74] = 0x04; dev->ld_regs[0x05][0xf1] = 0x02; - dev->ld_regs[0x05][0xf2] = 0x03; + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x05][0xf2] = 0x03; serial_irq(dev->uart[1], dev->ld_regs[5][0x70]); /* Logical device 6: RTC */ @@ -858,16 +1662,34 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->ld_regs[0x08][0x30] = 0x00; dev->ld_regs[0x08][0x60] = 0x00; dev->ld_regs[0x08][0x61] = 0x00; + if (dev->chip_id >= FDC37C93X_FR) { + dev->ld_regs[0x08][0xb1] = 0x80; + dev->ld_regs[0x08][0xc0] = 0x01; + dev->ld_regs[0x08][0xc1] = 0x01; + dev->ld_regs[0x08][0xc5] = 0x01; + dev->ld_regs[0x08][0xc6] = 0x01; + dev->ld_regs[0x08][0xc7] = 0x01; + dev->ld_regs[0x08][0xc8] = 0x01; + dev->ld_regs[0x08][0xc9] = 0x80; + dev->ld_regs[0x08][0xcb] = 0x01; + dev->ld_regs[0x08][0xcc] = 0x01; + memset(&(dev->ld_regs[0x08][0xd0]), 0x01, 16); + } + memset(&(dev->ld_regs[0x08][0xe0]), 0x01, 14); /* Logical device 9: ACCESS.bus */ - dev->ld_regs[0x09][0x30] = 0x00; - dev->ld_regs[0x09][0x60] = 0x00; - dev->ld_regs[0x09][0x61] = 0x00; + if (dev->chip_id >= FDC37C93X_FR) { + dev->ld_regs[0x09][0x30] = 0x00; + dev->ld_regs[0x09][0x60] = 0x00; + dev->ld_regs[0x09][0x61] = 0x00; + } /* Logical device A: ACPI */ - dev->ld_regs[0x0a][0x30] = 0x00; - dev->ld_regs[0x0a][0x60] = 0x00; - dev->ld_regs[0x0a][0x61] = 0x00; + if (dev->chip_id == FDC37C93X_APM) { + dev->ld_regs[0x0a][0x30] = 0x00; + dev->ld_regs[0x0a][0x60] = 0x00; + dev->ld_regs[0x0a][0x61] = 0x00; + } fdc37c93x_gpio_handler(dev); fdc37c93x_lpt_handler(dev); @@ -899,6 +1721,62 @@ fdc37c93x_reset(fdc37c93x_t *dev) if (dev->chip_id != 0x02) fdc37c93x_superio_handler(dev); + if (dev->chip_id >= FDC37C93X_FR) { + serial_set_clock_src(dev->uart[0], 24000000.0); + serial_set_clock_src(dev->uart[1], 24000000.0); + } + + memset(dev->gpio_regs, 0xff, 256); + memset(dev->gpio_pulldn, 0xff, 8); + + /* Acer V62X requires bit 0 to be clear to not be stuck in "clear password" mode. */ + if (!strcmp(machine_get_internal_name(), "vectra54")) { + dev->gpio_pulldn[1] = 0x40; + + /* + HP Vectra VL/5 Series 4 GPIO + (TODO: Find how multipliers > 3.0 are defined): + + Bit 6: 1 = can boot, 0 = no; + Bit 7, 1 = multiplier (00 = 2.5, 01 = 2.0, + 10 = 3.0, 11 = 1.5); + Bit 5, 4 = bus speed (00 = 50 MHz, 01 = 66 MHz, + 10 = 60 MHz, 11 = ????): + Bit 7, 5, 4, 1: 0000 = 125 MHz, 0010 = 166 MHz, + 0100 = 150 MHz, 0110 = ??? MHz; + 0001 = 100 MHz, 0011 = 133 MHz, + 0101 = 120 MHz, 0111 = ??? MHz; + 1000 = 150 MHz, 1010 = 200 MHz, + 1100 = 180 MHz, 1110 = ??? MHz; + 1001 = 75 MHz, 1011 = 100 MHz, + 1101 = 90 MHz, 1111 = ??? MHz + */ + if (cpu_busspeed <= 40000000) + dev->gpio_pulldn[1] |= 0x30; + else if ((cpu_busspeed > 40000000) && (cpu_busspeed <= 50000000)) + dev->gpio_pulldn[1] |= 0x00; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + dev->gpio_pulldn[1] |= 0x20; + else if (cpu_busspeed > 60000000) + dev->gpio_pulldn[1] |= 0x10; + + if (cpu_dmulti <= 1.5) + dev->gpio_pulldn[1] |= 0x82; + else if ((cpu_dmulti > 1.5) && (cpu_dmulti <= 2.0)) + dev->gpio_pulldn[1] |= 0x02; + else if ((cpu_dmulti > 2.0) && (cpu_dmulti <= 2.5)) + dev->gpio_pulldn[1] |= 0x00; + else if (cpu_dmulti > 2.5) + dev->gpio_pulldn[1] |= 0x80; + } else if (!strcmp(machine_get_internal_name(), "acerv62x")) + dev->gpio_pulldn[1] = 0xfe; + else + dev->gpio_pulldn[1] = (dev->chip_id == 0x30) ? 0xff : 0xfd; + + if (strstr(machine_get_internal_name(), "acer") != NULL) + /* Bit 2 on the Acer V35N is the text/graphics toggle, bits 1 and 3 = ????. */ + dev->gpio_pulldn[2] = 0x10; + dev->locked = 0; } @@ -920,41 +1798,59 @@ fdc37c93x_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); - dev->chip_id = info->local & 0xff; - dev->is_apm = (info->local >> 8) & 0x01; - dev->is_compaq = (info->local >> 8) & 0x02; - dev->has_nvr = !((info->local >> 8) & 0x04); - dev->port_370 = ((info->local >> 8) & 0x08); + dev->chip_id = info->local & FDC37C93X_CHIP_ID; + dev->kbc_type = info->local & FDC37C93X_KBC; - dev->gpio_regs[0] = 0xff; -#if 0 - dev->gpio_regs[1] = (info->local == 0x0030) ? 0xff : 0xfd; -#endif - dev->gpio_regs[1] = (dev->chip_id == 0x30) ? 0xff : 0xfd; + dev->is_apm = (dev->chip_id == FDC37C93X_APM); + dev->is_compaq = (dev->kbc_type == FDC37C931); + + dev->has_nvr = !(info->local & FDC37C93X_NO_NVR); + dev->port_370 = !!(info->local & FDC37C93X_370); if (dev->has_nvr) { - dev->nvr = device_add(&at_nvr_device); + dev->nvr = device_add(&amstrad_megapc_nvr_device); nvr_bank_set(0, 0, dev->nvr); nvr_bank_set(1, 0xff, dev->nvr); } - if (dev->is_apm || (dev->chip_id == 0x03)) - dev->access_bus = device_add(&access_bus_device); + dev->max_ld = 8; - if (dev->is_apm) + if (dev->chip_id >= FDC37C93X_FR) { + dev->access_bus = device_add(&access_bus_device); + dev->max_ld++; + } + + if (dev->chip_id == FDC37C93X_APM) { dev->acpi = device_add(&acpi_smc_device); + dev->max_ld++; + } if (dev->is_compaq) { - io_sethandler(0x0ea, 0x0002, - fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); io_sethandler(0x0f9, 0x0001, fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); io_sethandler(0x0fb, 0x0001, fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); } - dev->kbc = device_add(&keyboard_ps2_ami_pci_device); + switch (dev->kbc_type) { + case FDC37C931: + dev->kbc = device_add(&keyboard_ps2_compaq_device); + break; + case FDC37C932: + dev->kbc = device_add(&keyboard_ps2_intel_ami_pci_device); + break; + case FDC37C933: + default: + dev->kbc = device_add(&keyboard_ps2_pci_device); + break; + case FDC37C935: + dev->kbc = device_add(&keyboard_ps2_phoenix_device); + break; + case FDC37C937: + dev->kbc = device_add(&keyboard_ps2_phoenix_pci_device); + break; + } /* Set the defaults here so the ports can be removed by fdc37c93x_reset(). */ dev->fdc_base = 0x03f0; @@ -978,109 +1874,11 @@ fdc37c93x_init(const device_t *info) return dev; } -const device_t fdc37c931apm_device = { - .name = "SMC FDC37C931APM Super I/O", - .internal_name = "fdc37c931apm", +const device_t fdc37c93x_device = { + .name = "SMC FDC37C93x Super I/O", + .internal_name = "fdc37c93x", .flags = 0, - .local = 0x130, /* Share the same ID with the 932QF. */ - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c931apm_compaq_device = { - .name = "SMC FDC37C931APM Super I/O (Compaq Presario 4500)", - .internal_name = "fdc37c931apm_compaq", - .flags = 0, - .local = 0x330, /* Share the same ID with the 932QF. */ - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c932_device = { - .name = "SMC FDC37C932 Super I/O", - .internal_name = "fdc37c932", - .flags = 0, - .local = 0x02, - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c932fr_device = { - .name = "SMC FDC37C932FR Super I/O", - .internal_name = "fdc37c932fr", - .flags = 0, - .local = 0x03, - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c932qf_device = { - .name = "SMC FDC37C932QF Super I/O", - .internal_name = "fdc37c932qf", - .flags = 0, - .local = 0x30, - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c935_device = { - .name = "SMC FDC37C935 Super I/O", - .internal_name = "fdc37c935", - .flags = 0, - .local = 0x02, - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c935_370_device = { - .name = "SMC FDC37C935 Super I/O (Port 370h)", - .internal_name = "fdc37c935_370", - .flags = 0, - .local = 0x802, - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c935_no_nvr_device = { - .name = "SMC FDC37C935 Super I/O", - .internal_name = "fdc37c935", - .flags = 0, - .local = 0x402, + .local = 0, .init = fdc37c93x_init, .close = fdc37c93x_close, .reset = NULL, diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index ce6ee12d5..8423f096b 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2681,7 +2681,6 @@ ati_render_32bpp(svga_t *svga) When ATI mode is selected, allow complete auto-detection. But when 8514/A mode is selected, allow detection based on the shadow register sets. */ - static void mach_set_resolution(mach_t *mach, svga_t *svga) { @@ -2707,15 +2706,27 @@ mach_set_resolution(mach_t *mach, svga_t *svga) if (dev->interlace) dev->v_syncstart >>= 1; - if ((mach->accel.clock_sel & 0x01) && !(mach->old_on2 & 0x01) && - !(dev->accel.advfunc_cntl & 0x01)) - ret = 2; - else if ((dev->accel.advfunc_cntl & 0x01) && !(mach->old_on1 & 0x01) && - !(mach->accel.clock_sel & 0x01)) - ret = 1; - else if ((!(dev->accel.advfunc_cntl & 0x01) && (mach->old_on1 & 0x01)) || - (!(mach->accel.clock_sel & 0x01) && (mach->old_on2 & 0x01))) - ret = 0; + if (ATI_8514A_ULTRA) { + if ((mach->accel.clock_sel & 0x01) && + !(dev->accel.advfunc_cntl & 0x01)) + ret = 2; + else if ((dev->accel.advfunc_cntl & 0x01) && + !(mach->accel.clock_sel & 0x01)) + ret = 1; + else if ((!(dev->accel.advfunc_cntl & 0x01) && (mach->old_on1 & 0x01)) || + (!(mach->accel.clock_sel & 0x01) && (mach->old_on2 & 0x01))) + ret = 0; + } else { + if ((mach->accel.clock_sel & 0x01) && !(mach->old_on2 & 0x01) && + !(dev->accel.advfunc_cntl & 0x01)) + ret = 2; + else if ((dev->accel.advfunc_cntl & 0x01) && !(mach->old_on1 & 0x01) && + !(mach->accel.clock_sel & 0x01)) + ret = 1; + else if ((!(dev->accel.advfunc_cntl & 0x01) && (mach->old_on1 & 0x01)) || + (!(mach->accel.clock_sel & 0x01) && (mach->old_on2 & 0x01))) + ret = 0; + } if (ret) { if (ret == 2) @@ -2730,11 +2741,13 @@ mach_set_resolution(mach_t *mach, svga_t *svga) if (dev->hdisp == 640) { dev->hdisp = 1024; dev->vdisp = 768; + mach_log("1024x768.\n"); } } else { if (dev->hdisp == 1024) { dev->hdisp = 640; dev->vdisp = 480; + mach_log("640x480.\n"); } } svga_recalctimings(svga); @@ -2764,7 +2777,6 @@ ati8514_recalctimings(svga_t *svga) mach_log("ON=%d, vgahdisp=%d.\n", dev->on, svga->hdisp); if (dev->on) { - mach_log("8514/A ON, pitch=%d.\n", dev->ext_pitch); dev->interlace = !!(dev->disp_cntl & 0x10); dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; @@ -2773,16 +2785,19 @@ ati8514_recalctimings(svga_t *svga) mach->accel.crt_offset = (mach->accel.crt_offset_lo | (mach->accel.crt_offset_hi << 16)) << 2; dev->accel.ge_offset -= mach->accel.crt_offset; + mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x, clocksel=%02x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x05, mach->accel.clock_sel & 0x01); - mach->accel.src_pitch = ((mach->accel.ge_pitch & 0xff) << 3); - mach->accel.dst_pitch = ((mach->accel.ge_pitch & 0xff) << 3); + mach->accel.src_pitch = dev->pitch; + mach->accel.dst_pitch = dev->pitch; mach->accel.src_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)) << 2; mach->accel.dst_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)) << 2; mach->accel.src_ge_offset -= mach->accel.crt_offset; mach->accel.dst_ge_offset -= mach->accel.crt_offset; + mach_log("8514/A ON, pitch=%d, GE offset=%08x.\n", ((mach->accel.ge_pitch & 0xff) << 3), dev->accel.ge_offset); + dev->h_disp = dev->hdisp; dev->dispend = dev->vdisp; if (dev->dispend == 600) @@ -2809,6 +2824,7 @@ ati8514_recalctimings(svga_t *svga) } dev->accel_bpp = 8; svga->render8514 = ibm8514_render_8bpp; + } else mach->crt_resolution = 0; } @@ -3009,17 +3025,12 @@ mach_recalctimings(svga_t *svga) } } } else { - mach->accel.src_pitch = ((mach->accel.ge_pitch & 0xff) << 3); - mach->accel.dst_pitch = ((mach->accel.ge_pitch & 0xff) << 3); + mach->accel.src_pitch = dev->pitch; + mach->accel.dst_pitch = dev->pitch; mach->accel.src_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); mach->accel.dst_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); - if (dev->bpp) { - mach->accel.src_ge_offset <<= 1; - mach->accel.dst_ge_offset <<= 1; - } else { - mach->accel.src_ge_offset <<= 2; - mach->accel.dst_ge_offset <<= 2; - } + mach->accel.src_ge_offset <<= 2; + mach->accel.dst_ge_offset <<= 2; mach->accel.src_ge_offset -= mach->accel.crt_offset; mach->accel.dst_ge_offset -= mach->accel.crt_offset; @@ -4264,12 +4275,14 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in if (dev->force_busy) { temp |= 0x0200; /*Hardware busy*/ if (mach->accel.cmd_type >= 0) { + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; mono_src = (mach->accel.dp_config >> 5) & 3; switch (mach->accel.cmd_type) { case 2: if (dev->accel.sy >= mach->accel.height) dev->force_busy = 0; - else if (mono_src == 2) + else if ((mono_src == 2) || (frgd_sel == 2) || (bkgd_sel == 2)) dev->force_busy = 0; break; case 5: @@ -7219,7 +7232,6 @@ ati8514_init(svga_t *svga, void *ext8514, void *dev8514) dev->v_sync_start = 0x0600; dev->disp_cntl = 0x33; mach->accel.clock_sel = 0x1c; - mach->shadow_set = 0x02; dev->accel.cmd_back = 1; io_sethandler(0x02ea, 4, ati8514_in, NULL, NULL, ati8514_out, NULL, NULL, svga); diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 4988b3797..43c4e22b2 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -4141,8 +4141,6 @@ gd54xx_reset(void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - pclog("gd54xx_reset()\n"); - memset(svga->crtc, 0x00, sizeof(svga->crtc)); memset(svga->seqregs, 0x00, sizeof(svga->seqregs)); memset(svga->gdcreg, 0x00, sizeof(svga->gdcreg)); diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 8fa392891..6897aed60 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -234,6 +234,8 @@ typedef struct s3_t { uint8_t advfunc_cntl; uint16_t cur_y, cur_y2; uint16_t cur_x, cur_x2; + uint16_t cur_x_overflow; + uint16_t destx_overflow; uint16_t x2, ropmix; uint16_t pat_x, pat_y; int16_t desty_axstp, desty_axstp2; @@ -286,8 +288,11 @@ typedef struct s3_t { int color_16bit_check; int color_16bit_check_pixtrans; int16_t minus; + int16_t minus_src_24bpp; int rd_mask_16bit_check; int start; + int mix_dat_upper; + int overflow; /*For non-threaded FIFO*/ int setup_fifo_slot; @@ -657,22 +662,31 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) val = (val >> 8) | (val << 8); s3->accel_start(16, 1, val | (val << 16), 0, s3); - } else + } else { + if (s3->accel.rd_mask_16bit_check) { + if ((s3->accel.cmd == 0x53f1) || (s3->accel.cmd == 0x53b1)) { + if (s3->accel.cur_x & 0x400) + val = (val >> 8) | (val << 8); + + s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + + val = (val >> 8) | (val << 8); + } + } s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } } else { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cmd == 0x53f1) { + if ((s3->accel.cmd == 0x53f1) || (s3->accel.cmd == 0x53b1)) { if (s3->accel.cur_x & 0x400) val = (val >> 8) | (val << 8); s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); val = (val >> 8) | (val << 8); - s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } else - s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } else - s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } + } + s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); } break; case 0x400: @@ -793,6 +807,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x82e9: s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x0f) << 8); s3->accel.poly_cy = s3->accel.cur_y; + s3_log("[%04X:%08X] OUT PORTB=%04x, valy=%d.\n", CS, cpu_state.pc, port - 1, s3->accel.cur_y); break; case 0x814a: case 0x82ea: @@ -808,15 +823,17 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x8548: case 0x86e8: s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; + s3->accel.cur_x_overflow = (s3->accel.cur_x_overflow & 0xff00) | val; s3->accel.poly_cx = s3->accel.cur_x << 20; s3->accel.poly_x = s3->accel.poly_cx >> 20; break; case 0x8549: case 0x86e9: s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x0f) << 8); + s3->accel.cur_x_overflow = (s3->accel.cur_x_overflow & 0xff) | (val << 8); s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; s3->accel.poly_x = s3->accel.poly_cx >> 20; - s3_log("[%04X:%08X] OUT PORTB=%04x, val=%04x.\n", CS, cpu_state.pc, port - 1, s3->accel.cur_x); + s3_log("[%04X:%08X] OUT PORTB=%04x, valx=%d, valxover=%d.\n", CS, cpu_state.pc, port - 1, s3->accel.cur_x, s3->accel.cur_x_overflow); break; case 0x854a: case 0x86ea: @@ -859,11 +876,13 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x8d48: case 0x8ee8: s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; + s3->accel.destx_overflow = (s3->accel.destx_overflow & 0xff00) | val; s3->accel.point_1_updated = 1; break; case 0x8d49: case 0x8ee9: s3->accel.destx_distp = (s3->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); + s3->accel.destx_overflow = (s3->accel.destx_overflow & 0xff) | (val << 8); if (val & 0x20) s3->accel.destx_distp |= ~0x3fff; s3->accel.point_1_updated = 1; @@ -907,6 +926,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x9459: case 0x96e9: s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8); + s3_log("[%04X:%08X] OUT PORTB=%04x, valmajx=%d.\n", CS, cpu_state.pc, port - 1, s3->accel.maj_axis_pcnt); break; case 0x954a: case 0x96ea: @@ -2951,7 +2971,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) break; case 0x40: - s3->enable_8514 = (val & 0x01); + s3->enable_8514 = val & 0x01; break; case 0x50: @@ -5763,6 +5783,8 @@ s3_accel_in_w(uint16_t port, void *priv) s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; uint16_t temp = 0x0000; + uint16_t temp1 = 0x0000; + uint16_t temp2 = 0x0000; const uint16_t *vram_w = (uint16_t *) svga->vram; if (!s3->enable_8514) @@ -5774,7 +5796,7 @@ s3_accel_in_w(uint16_t port, void *priv) switch (s3->accel.cmd & 0x600) { case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 0x02)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) temp = (temp >> 8) | (temp << 8); @@ -5782,33 +5804,51 @@ s3_accel_in_w(uint16_t port, void *priv) s3->accel_start(8, 1, temp | (temp << 16), 0, s3); } else { if ((s3->bpp == 0) && s3->color_16bit) { - if (s3->accel.cur_x & 0x400) - temp = ((temp >> 8) | (temp << 8)) & 0xffff; - + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.cur_x & 0x400) + temp = (temp >> 8) | (temp << 8); + } s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } else s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); } } else { if ((s3->bpp == 0) && s3->color_16bit) { - if (s3->accel.cur_x & 0x400) - temp = ((temp >> 8) | (temp << 8)) & 0xffff; - + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.cur_x & 0x400) + temp = (temp >> 8) | (temp << 8); + } s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } else s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); } break; case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 0x02)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) temp = (temp >> 8) | (temp << 8); + s3->accel_start(16, 1, temp | (temp << 16), 0, s3); } else s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } else { - s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.cmd == 0x53b0) { + temp1 = vram_w[dword_remap_w(svga, s3->accel.dest + s3->accel.cx - s3->accel.minus) & (s3->vram_mask >> 1)]; + temp2 = vram_w[dword_remap_w(svga, s3->accel.dest + s3->accel.cx - s3->accel.minus + 1) & (s3->vram_mask >> 1)]; + if (s3->accel.cur_x & 0x400) { + temp = temp1 >> 8; + temp |= (temp2 >> 8) << 8; + } else { + temp = temp1 & 0xff; + temp |= ((temp2 & 0xff) << 8); + } + s3->accel_start(4, 1, 0xffffffff, temp | (temp << 16), s3); + } else + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + } else + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } break; @@ -7878,7 +7918,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ - s3_log("CMD=%d, full=%04x, s3bpp=%x, clr=%d, clb=%d, sourcedisplay=%x, mmio=%02x, srcbase=%08x, dstbase=%08x, cpu=%04x, mix=%04x, count=%d, rd_mask=%04x, wrt_mask=%04x, width=%d, s=%d,%d, c=%d,%d, d=%d,%d, 16bitcolor=%x, frgdcolor=%04x, bkgdcolor=%04x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, curx=%d, cury=%d, cll=%d, b2e8pix=%x.\n", cmd, s3->accel.cmd, s3->bpp, clip_r, clip_b, vram_mask, svga->crtc[0x53] & 0x18, srcbase, dstbase, cpu_dat & 0xffff, mix_dat & 0xffff, count, rd_mask, wrt_mask, s3->width, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->color_16bit, frgd_color, bkgd_color, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.cur_x, s3->accel.cur_y, clip_l, s3->accel.b2e8_pix); + s3_log("CMD=%d, full=%04x, s3bpp=%x, clr=%d, clb=%d, sourcedisplay=%02x, mmio=%02x, srcbase=%08x, dstbase=%08x, cpu=%04x, mix=%04x, count=%d, rd_mask=%04x, wrt_mask=%04x, width=%d, s=%d,%d, c=%d,%d, d=%d,%d, 16bitcolor=%x, frgdcolor=%04x, bkgdcolor=%04x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, curx=%d, cury=%d, cll=%d, b2e8pix=%x.\n", cmd, s3->accel.cmd, s3->bpp, clip_r, clip_b, s3->accel.multifunc[0x0a] & 0xc4, svga->crtc[0x53] & 0x18, srcbase, dstbase, cpu_dat & 0xffff, mix_dat & 0xffff, count, rd_mask, wrt_mask, s3->width, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->color_16bit, frgd_color, bkgd_color, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.cur_x, s3->accel.cur_y, clip_l, s3->accel.b2e8_pix); switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ @@ -7989,18 +8029,30 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi case 1: /*Draw line*/ if (!cpu_input) { + s3->accel.rd_mask_16bit_check = 0; s3->accel.minus = 0; s3->accel.color_16bit_check_pixtrans = 0; s3->accel.cx = s3->accel.cur_x & 0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; - s3->accel.sy = s3->accel.maj_axis_pcnt; - if ((s3->bpp == 0) && s3->color_16bit) - s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00); - else - s3->accel.rd_mask_16bit_check = 0; - if ((s3->bpp == 0) && s3->color_16bit && (s3->accel.cur_x & 0x400) && s3->accel.rd_mask_16bit_check) - s3->accel.minus = 0x400; + s3->accel.sy = s3->accel.maj_axis_pcnt; + if ((s3->bpp == 0) && s3->color_16bit) { + s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00); + if (s3->accel.rd_mask_16bit_check) { + if ((s3->accel.cur_x_overflow & 0xc00) == 0xc00) + s3->accel.start = 1; + else { + if (s3->accel.start) { + s3->accel.start = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.start = 0; + if (s3->accel.cur_x_overflow & 0x400) + s3->accel.minus = 0x400; + } + } + } + } if (s3_cpu_src(s3)) return; /*Wait for data from CPU*/ @@ -8009,7 +8061,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (s3->accel.cmd & 0x08) { /*Radial*/ if ((s3->bpp == 0) && s3->color_16bit) { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cur_x & 0x400) { + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); @@ -8076,11 +8128,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi cpu_dat >>= 16; if (!s3->accel.sy) { - if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.cur_x & 0x400)) - s3->accel.color_16bit_check = 1; - else + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; } break; } @@ -8130,7 +8182,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.temp_cnt = 16; if ((s3->bpp == 0) && s3->color_16bit) { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cur_x & 0x400) { + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); @@ -8146,7 +8198,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } else { if ((s3->bpp == 0) && s3->color_16bit) { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cur_x & 0x400) { + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); @@ -8161,12 +8213,18 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } } - while (count-- && s3->accel.sy >= 0) { + if (!s3->accel.b2e8_pix) + s3_log("CMDFULL=%04x, FRGDMIX=%x, FRGDCOLR=%04x, RDMASK=%04x, MINUS=%d, WRTMASK=%04X, MIX=%04x, CX=%d, CY=%d, SX=%d, SY=%d, PIXCNTL=%02x, 16BITCOLOR=%x, RDCHECK=%x, CLIPL=%d, CLIPR=%d, CLIPT=%d, CLIPB=%d.\n", s3->accel.cmd, frgd_mix, s3->accel.frgd_color, rd_mask, s3->accel.minus, wrt_mask, mix_dat & 0xffff, s3->accel.cx, s3->accel.cy, s3->accel.sx, s3->accel.sy, s3->accel.multifunc[0x0a] & 0xc4, s3->accel.color_16bit_check, s3->accel.rd_mask_16bit_check, clip_l, clip_r, clip_t, clip_b); + + while (count-- && (s3->accel.sy >= 0)) { if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { mix_dat >>= 16; s3->accel.temp_cnt = 16; } + if (s3->accel.minus) + s3_log("Total pixel cx=%d, cy=%d.\n", s3->accel.cx - s3->accel.minus, s3->accel.cy); + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: @@ -8228,11 +8286,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi cpu_dat >>= 16; if (!s3->accel.sy) { - if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.cur_x & 0x400)) - s3->accel.color_16bit_check = 1; - else + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; } break; } @@ -8279,8 +8337,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi case 2: /*Rectangle fill*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ { - s3->accel.start = 0; s3->accel.minus = 0; + s3->accel.mix_dat_upper = 0; s3->accel.color_16bit_check_pixtrans = 0; s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; @@ -8292,15 +8350,41 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->bpp == 0) && s3->color_16bit) { s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00); if (s3->accel.rd_mask_16bit_check) { - s3->accel.start = 1; - if (s3->accel.cur_x & 0x400) { - s3->accel.minus = 0x400; - if ((s3->accel.cmd == 0x41b3) && (frgd_mix == 0)) - s3->accel.minus = 0; + if (s3->accel.cmd == 0x41b3) { + if (frgd_mix == 0) { + if (!(s3->accel.cur_x & 0x400)) + s3->accel.color_16bit_check = 0; + } else { + if ((s3->accel.cur_x_overflow & 0xc00) == 0xc00) + s3->accel.start = 1; + else { + if (s3->accel.start) { + s3->accel.start = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.start = 0; + if (s3->accel.cur_x_overflow & 0x400) + s3->accel.minus = 0x400; + } + } + } + } else { + if ((s3->accel.cur_x_overflow & 0xc00) == 0xc00) + s3->accel.start = 1; + else { + if (s3->accel.start) { + s3->accel.start = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.start = 0; + if (s3->accel.cur_x_overflow & 0x400) + s3->accel.minus = 0x400; + } + } } } else { if (s3->accel.cmd & 0x100) { - if (!(s3->accel.cmd & 0x200)) { + if (mix_mask == 0x80) { if (s3->accel.cur_x & 0x400) s3->accel.minus = 0x400; else @@ -8330,19 +8414,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi count = s3->accel.maj_axis_pcnt + 1; s3->accel.temp_cnt = 16; if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cur_x & 0x400) { - if (s3->accel.start) { - s3->accel.minus = 0x400; - s3->accel.start = 0; - } + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); } else { - if (s3->accel.start) { - s3->accel.minus = 0; - s3->accel.start = 0; - } wrt_mask = s3->accel.wrt_mask_actual[0]; frgd_color = s3->accel.frgd_color_actual[0]; bkgd_color = s3->accel.bkgd_color_actual[0]; @@ -8355,7 +8431,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (s3->accel.cmd == 0x41b3) { if (frgd_mix != 0) { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cur_x & 0x400) { + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); @@ -8367,39 +8443,33 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi rd_mask &= 0x00ff; } else if (!s3->accel.rd_mask_16bit_check && (s3->accel.cur_x & 0x400)) break; + } else { + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) { + wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); + frgd_color = (s3->accel.frgd_color_actual[1] << 8); + bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); + } else { + wrt_mask = s3->accel.wrt_mask_actual[0]; + frgd_color = s3->accel.frgd_color_actual[0]; + bkgd_color = s3->accel.bkgd_color_actual[0]; + s3->accel.mix_dat_upper = !!(mix_dat & 0xff00); + } + rd_mask &= 0x00ff; + } } } else { if (s3->accel.rd_mask_16bit_check) { - rd_mask &= 0x00ff; - if (s3->accel.cmd == 0x53b3) { - if (clip_l & 0x400) { - if (s3->accel.start) { - s3->accel.minus = 0x400; - s3->accel.start = 0; - } - wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); - frgd_color = (s3->accel.frgd_color_actual[1] << 8); - bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); - } else { - if (s3->accel.start) { - s3->accel.minus = 0; - s3->accel.start = 0; - } - wrt_mask = s3->accel.wrt_mask_actual[0]; - frgd_color = s3->accel.frgd_color_actual[0]; - bkgd_color = s3->accel.bkgd_color_actual[0]; - } + if (s3->accel.minus) { + wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); + frgd_color = (s3->accel.frgd_color_actual[1] << 8); + bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); } else { - if (s3->accel.cur_x & 0x400) { - wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); - frgd_color = (s3->accel.frgd_color_actual[1] << 8); - bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); - } else { - wrt_mask = s3->accel.wrt_mask_actual[0]; - frgd_color = s3->accel.frgd_color_actual[0]; - bkgd_color = s3->accel.bkgd_color_actual[0]; - } + wrt_mask = s3->accel.wrt_mask_actual[0]; + frgd_color = s3->accel.frgd_color_actual[0]; + bkgd_color = s3->accel.bkgd_color_actual[0]; } + rd_mask &= 0x00ff; } else { if ((s3_cpu_src(s3)) && !(s3->accel.cmd & 0x200)) { s3_log("FIXME: S3 911/924 15/16bpp documentation needed.\n"); @@ -8414,6 +8484,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } } + s3_log("CMDFULL=%04x, FRGDSEL=%x, BKGDSEL=%x, FRGDMIX=%02x, BKGDMIX=%02x, MASKCHECK=%x, RDMASK=%04x, MINUS=%d, WRTMASK=%04X, MIX=%04x, CX=%d, CY=%d, DX=%d, DY=%d, SX=%d, SY=%d, PIXCNTL=%02x, 16BITCOLOR=%x, RDCHECK=%x, CLIPL=%d, CLIPR=%d, OVERFLOW=%d, pitch=%d.\n", s3->accel.cmd, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.bkgd_mix & 0x0f, s3->accel.rd_mask_16bit_check, rd_mask, s3->accel.minus, wrt_mask, mix_dat & 0xffff, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->accel.sx, s3->accel.sy, s3->accel.multifunc[0x0a] & 0xc4, s3->accel.color_16bit_check, s3->accel.rd_mask_16bit_check, clip_l, clip_r, (s3->accel.destx_overflow & 0xc00) == 0xc00, s3->width); + while (count-- && (s3->accel.sy >= 0)) { if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { mix_dat >>= 16; @@ -8535,15 +8607,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (cpu_input) { if (s3->accel.sy < 0) { if ((s3->bpp == 0) && s3->color_16bit) { - if ((s3->accel.cmd == 0x53b3) && !s3->accel.b2e8_pix) { - if (!(clip_l & 0x400)) - s3->accel.color_16bit_check = 1; - else + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) s3->accel.color_16bit_check = 0; - } else { - if (!(s3->accel.cur_x & 0x400)) - s3->accel.color_16bit_check = 1; else + s3->accel.color_16bit_check = 1; + + if ((s3->accel.cmd == 0x41b3) && (frgd_mix == 0)) s3->accel.color_16bit_check = 0; } } @@ -8556,10 +8626,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } if (s3->accel.sy < 0) { if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.cur_x & 0x400)) - s3->accel.color_16bit_check = 1; - else - s3->accel.color_16bit_check = 0; + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) + s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; + } } s3->accel.cur_x = s3->accel.cx; s3->accel.cur_y = s3->accel.cy; @@ -8669,25 +8741,39 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi case 6: /*BitBlt*/ if (!cpu_input) { /*!cpu_input is trigger to start operation*/ s3->accel.minus = 0; + s3->accel.minus_src_24bpp = 0; s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; s3->accel.dx = s3->accel.destx_distp & 0xfff; s3->accel.dy = s3->accel.desty_axstp & 0xfff; - s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00); - if ((s3->bpp == 0) && s3->color_16bit && (s3->accel.destx_distp & 0x400) && s3->accel.rd_mask_16bit_check) - s3->accel.minus = 0x400; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + + if ((s3->bpp == 0) && s3->color_16bit) { + s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00); + if (s3->accel.rd_mask_16bit_check) { + if (!(clip_r & 0x400)) + s3->accel.start = 1; + else { + if (s3->accel.start) { + s3->accel.start = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.start = 0; + if (s3->accel.destx_distp & 0x400) + s3->accel.minus = 0x400; + } + } + } + } if (s3->accel.destx_distp & 0x400) { s3_log("BitBLT + 1024 FULLCMD=%04x: frgdcolor=%04x, s=%d,%d, d=%d,%d, frmix=%x, bkmix=%x, pixcntl=%02x.\n", s3->accel.cmd, frgd_color, s3->accel.sx, s3->accel.sy, s3->accel.dx, s3->accel.dy, frgd_mix, bkgd_mix, s3->accel.multifunc[0xa] & 0xc0); } else { s3_log("BitBLT + 0 FULLCMD=%04x: frgdcolor=%04x, s=%d,%d, d=%d,%d, frmix=%x, bkmix=%x, pixcntl=%02x.\n", s3->accel.cmd, frgd_color, s3->accel.sx, s3->accel.sy, s3->accel.dx, s3->accel.dy, frgd_mix, bkgd_mix, s3->accel.multifunc[0xa] & 0xc0); } - - s3->accel.cx = s3->accel.cur_x & 0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3_log("BitBLT: D(%d,%d).\n", s3->accel.dx, s3->accel.dy); @@ -8698,7 +8784,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->bpp == 0) && s3->color_16bit) { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.destx_distp & 0x400) { + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); @@ -8712,7 +8798,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } + s3_log("CMDFULL=%04x, FRGDSEL=%x, BKGDSEL=%x, FRGDMIX=%02x, BKGDMIX=%02x, MASKCHECK=%x, RDMASK=%04x, MINUS=%d, WRTMASK=%04X, MIX=%04x, CX=%d, CY=%d, DX=%d, DY=%d, SX=%d, SY=%d, PIXCNTL=%02x, 16BITCOLOR=%x, RDCHECK=%x, CLIPL=%d, CLIPR=%d, OVERFLOW=%d, pitch=%d.\n", s3->accel.cmd, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.bkgd_mix & 0x0f, s3->accel.rd_mask_16bit_check, rd_mask, s3->accel.minus, wrt_mask, mix_dat & 0xffff, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->accel.sx, s3->accel.sy, s3->accel.multifunc[0x0a] & 0xc4, s3->accel.color_16bit_check, s3->accel.rd_mask_16bit_check, clip_l, clip_r, (s3->accel.destx_overflow & 0xc00) == 0xc00, s3->width); + if (!cpu_input && (frgd_mix == 3) && !vram_mask && !(s3->accel.multifunc[0xe] & 0x100) && ((s3->accel.cmd & 0xa0) == 0xa0) && ((s3->accel.frgd_mix & 0xf) == 7) && ((s3->accel.bkgd_mix & 0xf) == 7)) { + s3_log("Special BitBLT.\n"); + while (1) { if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) { READ(s3->accel.src + s3->accel.cx - s3->accel.minus, src_dat); @@ -8728,6 +8818,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.dx++; s3->accel.sx--; s3->accel.dx &= 0xfff; + if (s3->accel.sx < 0) { s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; @@ -8742,11 +8833,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.sy--; if (s3->accel.sy < 0) { - if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.destx_distp & 0x400)) - s3->accel.color_16bit_check = 1; - else + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; } s3->accel.destx_distp = s3->accel.dx; s3->accel.desty_axstp = s3->accel.dy; @@ -8755,6 +8846,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } } } else { + s3_log("Normal blit.\n"); while (count-- && (s3->accel.sy >= 0)) { if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) { if (vram_mask && (s3->accel.cmd & 0x10)) { @@ -8824,7 +8916,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx--; s3->accel.dx--; } - s3->accel.dx &= 0xfff; + if (s3->accel.rd_mask_16bit_check) + s3->accel.dx &= 0x7ff; + else + s3->accel.dx &= 0xfff; + s3->accel.sx--; if (s3->accel.sx < 0) { if (s3->accel.cmd & 0x20) { @@ -8843,6 +8939,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cy--; s3->accel.dy--; } + s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; @@ -8850,21 +8947,24 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (cpu_input) { if (s3->accel.sy < 0) { - if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.destx_distp & 0x400)) - s3->accel.color_16bit_check = 1; - else + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; } } return; } if (s3->accel.sy < 0) { - if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.destx_distp & 0x400)) - s3->accel.color_16bit_check = 1; + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) + s3->accel.color_16bit_check = 0; else + s3->accel.color_16bit_check = 1; + + if (s3->accel.mix_dat_upper && !vram_mask && (frgd_mix == 3)) s3->accel.color_16bit_check = 0; } s3->accel.destx_distp = s3->accel.dx;