diff --git a/src/86box.c b/src/86box.c index 6e8fa52dd..2c29b69ea 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1362,6 +1362,36 @@ set_screen_size_monitor(int x, int y, int monitor_index) monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 1); monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 1); break; + + case 4: /* 300% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 3); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 3); + break; + + case 5: /* 400% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 2); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 2); + break; + + case 6: /* 500% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 5); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 5); + break; + + case 7: /* 600% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 6); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 6); + break; + + case 8: /* 700% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 7); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 7); + break; + + case 9: /* 800% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 3); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 3); + break; } plat_resize_request(monitors[monitor_index].mon_scrnsz_x, monitors[monitor_index].mon_scrnsz_y, monitor_index); diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c index d85ed4f54..76989481e 100644 --- a/src/chipset/opti5x7.c +++ b/src/chipset/opti5x7.c @@ -34,7 +34,8 @@ typedef struct { - uint8_t idx, regs[16]; + uint8_t idx, is_pci, + regs[16]; } opti5x7_t; #ifdef ENABLE_OPTI5X7_LOG @@ -75,11 +76,20 @@ opti5x7_shadow_map(int cur_reg, opti5x7_t *dev) 0 1 Read from DRAM (write protected) */ if (cur_reg == 0x06) { - mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[6] & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); - mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + if (dev->is_pci) { + mem_set_mem_state_cpu_both(0xe0000, 0x10000, ((dev->regs[6] & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + mem_set_mem_state_cpu_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + } else { + mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[6] & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + } } else { - for (int i = 0; i < 4; i++) - mem_set_mem_state_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + for (int i = 0; i < 4; i++) { + if (dev->is_pci) + mem_set_mem_state_cpu_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + else + mem_set_mem_state_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + } } flushmmucache_nopc(); @@ -161,6 +171,8 @@ opti5x7_init(const device_t *info) opti5x7_t *dev = (opti5x7_t *) malloc(sizeof(opti5x7_t)); memset(dev, 0, sizeof(opti5x7_t)); + dev->is_pci = info->local; + io_sethandler(0x0022, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev); io_sethandler(0x0024, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev); @@ -182,3 +194,17 @@ const device_t opti5x7_device = { .force_redraw = NULL, .config = NULL }; + +const device_t opti5x7_pci_device = { + .name = "OPTi 82C5x6/82C5x7 (PCI)", + .internal_name = "opti5x7_pci", + .flags = 0, + .local = 1, + .init = opti5x7_init, + .close = opti5x7_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index ec8ce699e..2605c27b9 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -6,14 +6,15 @@ * * This file is part of the 86Box distribution. * - * Implementation of the OPTi 82C822 VESA Local Bus to PCI Bridge Interface. + * Implementation of the OPTi 82C822 VESA Local Bus to PCI + * Bridge Interface. * * - * Authors: Tiseno100, * - * Copyright 2021 Tiseno100. + * Authors: Miran Grca, + * + * Copyright 2022 Miran Grca. */ - #include #include #include @@ -22,22 +23,30 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> -#include "cpu.h" -#include <86box/timer.h> -#include <86box/io.h> #include <86box/device.h> - +#include <86box/io.h> +#include <86box/apm.h> +#include <86box/dma.h> #include <86box/mem.h> +#include <86box/smram.h> #include <86box/pci.h> - +#include <86box/timer.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/port_92.h> +#include <86box/hdc_ide.h> +#include <86box/hdc.h> +#include <86box/machine.h> #include <86box/chipset.h> +#include <86box/spd.h> -/* Shadow RAM */ -#define SYSTEM_READ ((dev->pci_conf[0x44] & 2) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) -#define SYSTEM_WRITE ((dev->pci_conf[0x44] & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) -#define SHADOW_READ ((dev->pci_conf[cur_reg] & (1 << (4 + i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) -#define SHADOW_WRITE ((dev->pci_conf[cur_reg] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) +typedef struct +{ + uint8_t irq_convert, + pci_regs[256]; +} opti822_t; +// #define ENABLE_OPTI822_LOG 1 #ifdef ENABLE_OPTI822_LOG int opti822_do_log = ENABLE_OPTI822_LOG; @@ -47,247 +56,321 @@ opti822_log(const char *fmt, ...) va_list ap; if (opti822_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -# define opti822_log(fmt, ...) +#define opti822_log(fmt, ...) #endif -typedef struct opti822_t { - uint8_t pci_conf[256]; -} opti822_t; - -int opti822_irq_routing[7] = { 5, 9, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f }; - -void -opti822_shadow(int cur_reg, opti822_t *dev) +/* NOTE: We currently cheat and pass all PCI shadow RAM accesses to ISA as well. + This is because we currently do not have separate access mappings for + PCI and ISA at all. */ +static void +opti822_recalc(opti822_t *dev) { - if (cur_reg == 0x44) - mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE); - else - for (int i = 0; i < 4; i++) - mem_set_mem_state_both(0xe0000 - (((cur_reg & 3) - 1) << 16) + (i << 14), 0x4000, SHADOW_READ | SHADOW_WRITE); + int i, reg, bit_r, bit_w; + int state; + uint32_t base; - flushmmucache_nopc(); + for (i = 0; i < 12; i++) { + base = 0x000c0000 + (i << 14); + reg = 0x44 + ((i >> 2) ^ 3); + bit_w = (i & 3); + bit_r = bit_w + 4; + bit_w = 1 << bit_w; + bit_r = 1 << bit_r; + state = (dev->pci_regs[reg] & bit_w) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + state |= (dev->pci_regs[reg] & bit_r) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + mem_set_mem_state_bus_both(base, 0x00004000, state); + } + + state = (dev->pci_regs[0x44] & 0x01) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + state |= (dev->pci_regs[0x44] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + mem_set_mem_state_bus_both(0x000f0000, 0x00010000, state); +} + +/* NOTE: We cheat here. The real ALi M1435 uses a level to edge triggered IRQ converter + when the most siginificant bit is set. We work around that by manipulating the + emulated PIC's ELCR register. */ +static void +opti822_update_irqs(opti822_t *dev, int set) +{ + uint8_t val; + int i, reg; + int shift, irq; + int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; + pic_t *temp_pic; + + // dev->irq_convert = (dev->pci_regs[0x53] & 0x08); + dev->irq_convert = 1; + + for (i = 0; i < 16; i++) { + reg = 0x88 + (i >> 1); + shift = (i & 1) << 2; + val = (dev->pci_regs[reg] >> shift) & 0x0f; + irq = irq_map[val & 0x07]; + if (irq == -1) + continue; + temp_pic = (irq >= 8) ? &pic2 : &pic; + irq &= 7; + if (dev->irq_convert && set && (val & 0x08)) + temp_pic->elcr |= (1 << irq); + else + temp_pic->elcr &= ~(1 << irq); + } } static void -opti822_write(int func, int addr, uint8_t val, void *priv) +opti822_pci_write(int func, int addr, uint8_t val, void *priv) { - opti822_t *dev = (opti822_t *) priv; + int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; + int pin, slot; - switch (func) { - case 0x04: /* Command Register */ - dev->pci_conf[addr] = val & 0x40; + opti822_log("opti822_write(%02X, %02X, %02X)\n", func, addr, val); + + if (func > 0) + return; + + switch (addr) { + /* Command Register */ + case 0x04: + dev->pci_regs[addr] = (val & 0x40) | 0x07; break; - case 0x05: /* Command Register */ - dev->pci_conf[addr] = val & 1; + /* Status Register */ + case 0x06: + if (!(dev->pci_regs[0x52] & 0x04)) + dev->pci_regs[addr] = (val & 0x80); + break; + case 0x07: + dev->pci_regs[addr] &= ~(val & 0xf9); break; - case 0x06: /* Status Register */ - dev->pci_conf[addr] |= val & 0xc0; - break; - - case 0x07: /* Status Register */ - dev->pci_conf[addr] = val & 0xa9; + /* Master Latency Timer Register */ + case 0x0d: + dev->pci_regs[addr] = val; break; case 0x40: - dev->pci_conf[addr] = val & 0xc0; + dev->pci_regs[addr] = (val & 0xc0) | 0x01; break; - case 0x41: - dev->pci_conf[addr] = val & 0xcf; + /* TODO: Bit 15th enable the PCI Bridge when 1. */ + dev->pci_regs[addr] = val & 0xcf; break; case 0x42: - dev->pci_conf[addr] = val & 0xf8; + dev->pci_regs[addr] = val & 0xf8; break; - case 0x43: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; break; - case 0x44: /* Shadow RAM */ - case 0x45: - case 0x46: - case 0x47: - dev->pci_conf[addr] = (addr == 0x44) ? (val & 0xcb) : val; - opti822_shadow(addr, dev); + case 0x44: + dev->pci_regs[addr] = val & 0xcb; + opti822_recalc(dev); + break; + case 0x45 ... 0x47: + dev->pci_regs[addr] = val; + opti822_recalc(dev); + break; + + /* Memory hole stuff. */ + case 0x48 ... 0x51: + dev->pci_regs[addr] = val; break; - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - case 0x50: - case 0x51: case 0x52: + dev->pci_regs[addr] = val; + break; + case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; + opti822_update_irqs(dev, 0); + opti822_update_irqs(dev, 1); + break; + + case 0x54 ... 0x57: + dev->pci_regs[addr] = val; break; case 0x58: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xfc; + break; + case 0x59 ... 0x5b: + dev->pci_regs[addr] = val; break; - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: - dev->pci_conf[addr] = val; + case 0x5c ... 0x5f: + dev->pci_regs[addr] = val; break; case 0x60: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xfc; + break; + case 0x61 ... 0x63: + dev->pci_regs[addr] = val; break; - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - dev->pci_conf[addr] = val; + case 0x64 ... 0x67: + dev->pci_regs[addr] = val; break; case 0x68: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xfc; + break; + case 0x69 ... 0x6b: + dev->pci_regs[addr] = val; break; - case 0x69: - case 0x6a: - case 0x6b: - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f: - dev->pci_conf[addr] = val; + case 0x6c ... 0x6f: + dev->pci_regs[addr] = val; break; case 0x70: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xfc; break; - - case 0x71: - case 0x72: - case 0x73: - dev->pci_conf[addr] = val; + case 0x71 ... 0x73: + dev->pci_regs[addr] = val; break; case 0x74: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xf8; break; + /* ROMCS# and NVMCS# stuff. */ case 0x75: + dev->pci_regs[addr] = val; + break; + case 0x76: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; break; case 0x77: - dev->pci_conf[addr] = val & 0xe7; + dev->pci_regs[addr] = val; break; + /* Enabling of memory blocks at ISA bus. */ case 0x78: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; break; - case 0x79: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xfc; break; case 0x7a: - case 0x7b: - case 0x7c: - case 0x7d: - case 0x7e: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; + break; + + case 0x7b ... 0x7c: + dev->pci_regs[addr] = val; + break; + + case 0x7d ... 0x7e: + dev->pci_regs[addr] = val; break; case 0x7f: - dev->pci_conf[addr] = val & 3; + dev->pci_regs[addr] = val & 0x03; break; - case 0x80: - case 0x81: + case 0x80 ... 0x81: + dev->pci_regs[addr] = val; + break; case 0x82: - case 0x84: - case 0x85: + dev->pci_regs[addr] = val; + break; + + case 0x84 ... 0x85: + dev->pci_regs[addr] = val; + break; case 0x86: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; break; - case 0x88: /* PCI IRQ Routing */ - case 0x89: /* Very hacky implementation. Needs surely a rewrite after */ - case 0x8a: /* a PCI rework happens. */ - case 0x8b: - case 0x8c: - case 0x8d: - case 0x8e: - case 0x8f: - dev->pci_conf[addr] = val; - if (addr % 2) { - pci_set_irq_routing(PCI_INTB, ((val & 0x0f) != 0) ? opti822_irq_routing[(val & 7) - 1] : PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTA, (((val >> 4) & 0x0f) != 0) ? opti822_irq_routing[((val >> 4) & 7) - 1] : PCI_IRQ_DISABLED); - } else { - pci_set_irq_routing(PCI_INTD, ((val & 0x0f) != 0) ? opti822_irq_routing[(val & 7) - 1] : PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTC, (((val >> 4) & 0x0f) != 0) ? opti822_irq_routing[((val >> 4) & 7) - 1] : PCI_IRQ_DISABLED); - } - break; + case 0x88 ... 0x8f: + dev->pci_regs[addr] = val; + opti822_update_irqs(dev, 0); + irq = irq_map[val & 0x07]; + pin = 4 - ((addr & 0x01) << 1); + slot = ((addr & 0x06) >> 1); + if (irq >= 0) { + opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); + pci_set_irq_routing(pin + (slot << 2), irq); + pci_set_irq_level(pin + (slot << 2), !!(val & 0x07)); + } else { + opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); + pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); + } + irq = irq_map[(val >> 4) & 0x07]; + pin = 3 - ((addr & 0x01) << 1); + slot = ((addr & 0x06) >> 1); + if (irq >= 0) { + opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); + pci_set_irq_routing(pin + (slot << 2), irq); + pci_set_irq_level(pin + (slot << 2), !!((val >> 4) & 0x07)); + } else { + opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); + pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); + } + opti822_update_irqs(dev, 1); + break; } - - opti822_log("OPTI822: dev->pci_conf[%02x] = %02x\n", addr, dev->pci_conf[addr]); } static uint8_t -opti822_read(int func, int addr, void *priv) +opti822_pci_read(int func, int addr, void *priv) { opti822_t *dev = (opti822_t *) priv; - return dev->pci_conf[addr]; + uint8_t ret; + + ret = 0xff; + + if (func == 0) + ret = dev->pci_regs[addr]; + + opti822_log("opti822_read(%02X, %02X) = %02X\n", func, addr, ret); + + return ret; } static void opti822_reset(void *priv) { opti822_t *dev = (opti822_t *) priv; + int i; - dev->pci_conf[0x00] = 0x45; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x22; - dev->pci_conf[0x03] = 0xc8; - dev->pci_conf[0x04] = 7; - dev->pci_conf[0x06] = 0x40; - dev->pci_conf[0x07] = 1; - dev->pci_conf[0x08] = 1; - dev->pci_conf[0x0b] = 6; - dev->pci_conf[0x0d] = 0x20; - dev->pci_conf[0x40] = 1; - dev->pci_conf[0x43] = 0x20; - dev->pci_conf[0x52] = 6; - dev->pci_conf[0x53] = 0x90; + memset(dev->pci_regs, 0, 256); + + dev->pci_regs[0x00] = 0x45; dev->pci_regs[0x01] = 0x10; /*OPTi*/ + dev->pci_regs[0x02] = 0x22; dev->pci_regs[0x03] = 0xc8; /*82C822 PCIB*/ + dev->pci_regs[0x04] = 0x07; + dev->pci_regs[0x06] = 0x80; + dev->pci_regs[0x07] = 0x02; + dev->pci_regs[0x08] = 0x01; + dev->pci_regs[0x0b] = 0x06; + dev->pci_regs[0x0d] = 0x20; + + dev->pci_regs[0x40] = 0x01; dev->pci_regs[0x41] = 0x0c; + dev->pci_regs[0x43] = 0x02; + dev->pci_regs[0x52] = 0x06; + dev->pci_regs[0x53] = 0x90; + + dev->irq_convert = 1 /*0*/; + + for (i = 0; i < 16; i++) + pci_set_irq_routing(PCI_INTA + i, PCI_IRQ_DISABLED); } static void -opti822_close(void *priv) +opti822_close(void *p) { - opti822_t *dev = (opti822_t *) priv; + opti822_t *dev = (opti822_t *)p; free(dev); } @@ -298,7 +381,7 @@ opti822_init(const device_t *info) opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t)); memset(dev, 0, sizeof(opti822_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_read, opti822_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev); opti822_reset(dev); diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index b2e9ae0e0..95aaf4cb6 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -35,6 +35,7 @@ typedef struct { uint8_t idx, forced_green, + is_pci, regs[256], scratch[2]; @@ -78,7 +79,10 @@ opti895_recalc(opti895_t *dev) shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED; } - mem_set_mem_state_both(0xf0000, 0x10000, shflags); + if (dev->is_pci) + mem_set_mem_state_cpu_both(0xf0000, 0x10000, shflags); + else + mem_set_mem_state_both(0xf0000, 0x10000, shflags); for (i = 0; i < 8; i++) { base = 0xd0000 + (i << 14); @@ -98,7 +102,10 @@ opti895_recalc(opti895_t *dev) } } - mem_set_mem_state_both(base, 0x4000, shflags); + if (dev->is_pci) + mem_set_mem_state_cpu_both(base, 0x4000, shflags); + else + mem_set_mem_state_both(base, 0x4000, shflags); } for (i = 0; i < 4; i++) { @@ -119,7 +126,10 @@ opti895_recalc(opti895_t *dev) } } - mem_set_mem_state_both(base, 0x4000, shflags); + if (dev->is_pci) + mem_set_mem_state_cpu_both(base, 0x4000, shflags); + else + mem_set_mem_state_both(base, 0x4000, shflags); } flushmmucache_nopc(); @@ -232,6 +242,8 @@ opti895_init(const device_t *info) io_sethandler(0x0022, 0x0003, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev); + dev->is_pci = info->local; + dev->scratch[0] = dev->scratch[1] = 0xff; dev->regs[0x01] = 0xc0; @@ -276,6 +288,20 @@ const device_t opti802g_device = { .config = NULL }; +const device_t opti802g_pci_device = { + .name = "OPTi 82C802G (PCI)", + .internal_name = "opti802g_pci", + .flags = 0, + .local = 1, + .init = opti895_init, + .close = opti895_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t opti895_device = { .name = "OPTi 82C895", .internal_name = "opti895", diff --git a/src/config.c b/src/config.c index 11c8bdf50..e433e4071 100644 --- a/src/config.c +++ b/src/config.c @@ -123,8 +123,8 @@ load_general(void) force_43 = !!ini_section_get_int(cat, "force_43", 0); scale = ini_section_get_int(cat, "scale", 1); - if (scale > 3) - scale = 3; + if (scale > 9) + scale = 9; dpi_scale = ini_section_get_int(cat, "dpi_scale", 1); enable_overscan = !!ini_section_get_int(cat, "enable_overscan", 0); diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index 3da048dd5..16215b525 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -293,11 +293,11 @@ static int opPOPFD(uint32_t fetchdat) else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; else cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; - templ &= (is486) ? 0x3c0000 : 0; + templ &= (is486 || isibm486) ? 0x3c0000 : 0; templ |= ((cpu_state.eflags&3) << 16); if (cpu_CR4_mask & CR4_VME) cpu_state.eflags = (templ >> 16) & 0x3f; else if (CPUID) cpu_state.eflags = (templ >> 16) & 0x27; - else if (is486) cpu_state.eflags = (templ >> 16) & 7; + else if (is486 || isibm486) cpu_state.eflags = (templ >> 16) & 7; else cpu_state.eflags = (templ >> 16) & 3; flags_extract(); diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 685ef8427..2f51699cf 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -87,6 +87,19 @@ #include <86box/hdc.h> #include <86box/hdd.h> +#define ST506_XT_TYPE_XEBEC 0 +#define ST506_XT_TYPE_DTC_5150X 1 +#define ST506_XT_TYPE_ST11M 11 +#define ST506_XT_TYPE_ST11R 12 +#define ST506_XT_TYPE_WD1002A_WX1 21 +#define ST506_XT_TYPE_WD1002A_WX1_NOBIOS 22 +#define ST506_XT_TYPE_WD1002A_27X 23 +#define ST506_XT_TYPE_WD1004A_WX1 24 +#define ST506_XT_TYPE_WD1004_27X 25 +#define ST506_XT_TYPE_WD1004A_27X 26 +#define ST506_XT_TYPE_VICTOR_V86P 27 +#define ST506_XT_TYPE_TOSHIBA_T1200 28 + #define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.bin" #define DTC_BIOS_FILE "roms/hdd/st506/dtc_cxd21a.bin" #define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin" @@ -394,7 +407,7 @@ get_chs(hdc_t *dev, drive_t *drive) /* 6 bits are used for the sector number even on the IBM PC controller. */ dev->sector = dev->command[2] & 0x3f; dev->count = dev->command[4]; - if (((dev->type == 11) || (dev->type == 12)) && (dev->command[0] >= 0xf0)) + if (((dev->type == ST506_XT_TYPE_ST11M) || (dev->type == ST506_XT_TYPE_ST11R)) && (dev->command[0] >= 0xf0)) dev->cylinder = 0; else { dev->cylinder = dev->command[3] | ((dev->command[2] & 0xc0) << 2); @@ -565,7 +578,7 @@ st506_callback(void *priv) break; case CMD_FORMAT_ST11: /* This is really "Format cylinder 0" */ - if ((dev->type < 11) || (dev->type > 12)) { + if ((dev->type < ST506_XT_TYPE_ST11M) || (dev->type > ST506_XT_TYPE_ST11R)) { st506_error(dev, ERR_BAD_COMMAND); st506_complete(dev); break; @@ -608,7 +621,7 @@ st506_callback(void *priv) break; case CMD_GET_GEOMETRY_ST11: /* "Get geometry" is really "Read cylinder 0" */ - if ((dev->type < 11) || (dev->type > 12)) { + if ((dev->type < ST506_XT_TYPE_ST11M) || (dev->type > ST506_XT_TYPE_ST11R)) { st506_error(dev, ERR_BAD_COMMAND); st506_complete(dev); break; @@ -700,11 +713,11 @@ st506_callback(void *priv) break; case CMD_SET_GEOMETRY_ST11: /* "Set geometry" is really "Write cylinder 0" */ - if (dev->type == 1) { + if (dev->type == ST506_XT_TYPE_DTC_5150X) { /* DTC sends this... */ st506_complete(dev); break; - } else if ((dev->type < 11) || (dev->type > 12)) { + } else if ((dev->type < ST506_XT_TYPE_ST11M) || (dev->type > ST506_XT_TYPE_ST11R)) { st506_error(dev, ERR_BAD_COMMAND); st506_complete(dev); break; @@ -821,7 +834,7 @@ st506_callback(void *priv) /* For a 615/4/26 we get 666/2/31 geometry. */ st506_xt_log("ST506: drive%i: cyls=%i, heads=%i\n", dev->drive_sel, drive->cfg_cyl, drive->cfg_hpc); - if ((dev->type >= 23) && (drive->cfg_hpc == 2)) { + if ((dev->type >= ST506_XT_TYPE_VICTOR_V86P) && (drive->cfg_hpc == 2)) { /* * On Victor V86P, there's a disagreement between * the physical geometry, what the controller @@ -950,7 +963,7 @@ st506_callback(void *priv) break; case CMD_INQUIRY_ST11: - if (dev->type == 11 || dev->type == 12) + if (dev->type == ST506_XT_TYPE_ST11M || dev->type == ST506_XT_TYPE_ST11R) switch (dev->state) { case STATE_START_COMMAND: st506_xt_log("ST506: INQUIRY (type=%i)\n", dev->type); @@ -975,7 +988,7 @@ st506_callback(void *priv) break; case CMD_V86P_POWEROFF: - if (dev->type >= 23) { + if (dev->type >= ST506_XT_TYPE_VICTOR_V86P) { /* * Main BIOS (not the option ROM on disk) issues this. * Not much we can do, since we don't have a physical disk @@ -1017,10 +1030,10 @@ st506_callback(void *priv) break; case CMD_SET_STEP_RATE_DTC: - if (dev->type == 1) { + if (dev->type == ST506_XT_TYPE_DTC_5150X) { /* For DTC, we are done. */ st506_complete(dev); - } else if (dev->type == 11 || dev->type == 12) { + } else if (dev->type == ST506_XT_TYPE_ST11M || dev->type == ST506_XT_TYPE_ST11R) { /* * For Seagate ST-11, this is WriteGeometry. * @@ -1259,8 +1272,8 @@ mem_write(uint32_t addr, uint8_t val, void *priv) addr -= dev->bios_addr; switch (dev->type) { - case 11: /* ST-11M */ - case 12: /* ST-11R */ + case ST506_XT_TYPE_ST11M: /* ST-11M */ + case ST506_XT_TYPE_ST11R: /* ST-11R */ mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ break; @@ -1290,7 +1303,7 @@ mem_read(uint32_t addr, void *priv) addr -= dev->bios_addr; switch (dev->type) { - case 0: /* Xebec */ + case ST506_XT_TYPE_XEBEC: /* Xebec */ if (addr >= 0x001000) { #ifdef ENABLE_ST506_XT_LOG st506_xt_log("ST506: Xebec ROM access(0x%06lx)\n", addr); @@ -1299,7 +1312,7 @@ mem_read(uint32_t addr, void *priv) } break; - case 1: /* DTC */ + case ST506_XT_TYPE_DTC_5150X: /* DTC */ default: if (addr >= 0x002000) { #ifdef ENABLE_ST506_XT_LOG @@ -1309,8 +1322,8 @@ mem_read(uint32_t addr, void *priv) } break; - case 11: /* ST-11M */ - case 12: /* ST-11R */ + case ST506_XT_TYPE_ST11M: /* ST-11M */ + case ST506_XT_TYPE_ST11R: /* ST-11R */ mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ break; @@ -1468,20 +1481,20 @@ st506_init(const device_t *info) dev->nr_err = ERR_NOT_READY; switch (dev->type) { - case 0: /* Xebec (MFM) */ + case ST506_XT_TYPE_XEBEC: /* Xebec (MFM) */ fn = XEBEC_BIOS_FILE; break; - case 1: /* DTC5150 (MFM) */ + case ST506_XT_TYPE_DTC_5150X: /* DTC5150 (MFM) */ fn = DTC_BIOS_FILE; dev->switches = 0xff; break; - case 12: /* Seagate ST-11R (RLL) */ + case ST506_XT_TYPE_ST11R: /* Seagate ST-11R (RLL) */ dev->spt = RLL_SECTORS; /*FALLTHROUGH*/ - case 11: /* Seagate ST-11M (MFM) */ + case ST506_XT_TYPE_ST11M: /* Seagate ST-11M (MFM) */ dev->nr_err = ERR_NOT_AVAILABLE; dev->switches = 0x01; /* fixed */ dev->misc = device_get_config_int("revision"); @@ -1511,7 +1524,7 @@ st506_init(const device_t *info) dev->cyl_off = 1; break; - case 21: /* Western Digital WD1002A-WX1 (MFM) */ + case ST506_XT_TYPE_WD1002A_WX1: /* Western Digital WD1002A-WX1 (MFM) */ dev->nr_err = ERR_NOT_AVAILABLE; fn = WD1002A_WX1_BIOS_FILE; /* The switches are read in reverse: 0 = closed, 1 = open. @@ -1524,7 +1537,33 @@ st506_init(const device_t *info) dev->bios_addr = device_get_config_hex20("bios_addr"); break; - case 22: /* Western Digital WD1002A-27X (RLL) */ + case ST506_XT_TYPE_WD1002A_WX1_NOBIOS: /* Western Digital WD1002A-WX1 (MFM, No BIOS) */ + dev->nr_err = ERR_NOT_AVAILABLE; + fn = NULL; + /* The switches are read in reverse: 0 = closed, 1 = open. + Both open means MFM, 17 sectors per track. */ + dev->switches = 0x30; /* autobios */ + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + if (dev->irq == 2) + dev->switches |= 0x40; + dev->bios_addr = device_get_config_hex20("bios_addr"); + break; + + case ST506_XT_TYPE_WD1004A_WX1: /* Western Digital WD1004A-WX1 (MFM) */ + dev->nr_err = ERR_NOT_AVAILABLE; + fn = WD1004A_WX1_BIOS_FILE; + /* The switches are read in reverse: 0 = closed, 1 = open. + Both open means MFM, 17 sectors per track. */ + dev->switches = 0x10; /* autobios */ + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + if (dev->irq == 2) + dev->switches |= 0x40; + dev->bios_addr = device_get_config_hex20("bios_addr"); + break; + + case ST506_XT_TYPE_WD1002A_27X: /* Western Digital WD1002A-27X (RLL) */ dev->nr_err = ERR_NOT_AVAILABLE; fn = WD1002A_27X_BIOS_FILE; /* The switches are read in reverse: 0 = closed, 1 = open. @@ -1539,11 +1578,41 @@ st506_init(const device_t *info) dev->bios_addr = device_get_config_hex20("bios_addr"); break; - case 23: /* Victor V86P (RLL) */ + case ST506_XT_TYPE_WD1004_27X: /* Western Digital WD1004-27X (RLL) */ + dev->nr_err = ERR_NOT_AVAILABLE; + fn = WD1004_27X_BIOS_FILE; + /* The switches are read in reverse: 0 = closed, 1 = open. + Both closed means translate 26 sectors per track to 17, + SW6 closed, SW5 open means 26 sectors per track. */ + dev->switches = device_get_config_int("translate") ? 0x00 : 0x10; /* autobios */ + dev->spt = RLL_SECTORS; + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + if (dev->irq == 2) + dev->switches |= 0x40; + dev->bios_addr = device_get_config_hex20("bios_addr"); + break; + + case ST506_XT_TYPE_WD1004A_27X: /* Western Digital WD1004A-27X (RLL) */ + dev->nr_err = ERR_NOT_AVAILABLE; + fn = WD1004A_27X_BIOS_FILE; + /* The switches are read in reverse: 0 = closed, 1 = open. + Both closed means translate 26 sectors per track to 17, + SW6 closed, SW5 open means 26 sectors per track. */ + dev->switches = device_get_config_int("translate") ? 0x00 : 0x10; /* autobios */ + dev->spt = RLL_SECTORS; + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + if (dev->irq == 2) + dev->switches |= 0x40; + dev->bios_addr = device_get_config_hex20("bios_addr"); + break; + + case ST506_XT_TYPE_VICTOR_V86P: /* Victor V86P (RLL) */ fn = VICTOR_V86P_BIOS_FILE; break; - case 24: /* Toshiba T1200 */ + case ST506_XT_TYPE_TOSHIBA_T1200: /* Toshiba T1200 */ fn = NULL; dev->base = 0x01f0; dev->switches = 0x0c; @@ -1580,7 +1649,7 @@ st506_init(const device_t *info) st506_xt_log("ST506: %i disks loaded.\n", c); /* For the Xebec, set the switches now. */ - if (dev->type == 0) + if (dev->type == ST506_XT_TYPE_XEBEC) set_switches(dev); /* Initial "active" drive parameters. */ @@ -1807,6 +1876,38 @@ static const device_config_t wd_config[] = { { .name = "", .description = "", .type = CONFIG_END } }; +static const device_config_t wd_nobios_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0320, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "320H", .value = 0x0320 }, + { .description = "324H", .value = 0x0324 }, + { .description = "" } + } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "" } + } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + static const device_config_t wd_rll_config[] = { { .name = "bios_addr", @@ -1984,7 +2085,7 @@ const device_t st506_xt_xebec_device = { .name = "IBM PC Fixed Disk Adapter (MFM)", .internal_name = "st506_xt", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 0, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_XEBEC, .init = st506_init, .close = st506_close, .reset = NULL, @@ -1998,7 +2099,7 @@ const device_t st506_xt_dtc5150x_device = { .name = "DTC 5150X MFM Fixed Disk Adapter", .internal_name = "st506_xt_dtc5150x", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 1, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_DTC_5150X, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2012,7 +2113,7 @@ const device_t st506_xt_st11_m_device = { .name = "ST-11M MFM Fixed Disk Adapter", .internal_name = "st506_xt_st11_m", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 11, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_ST11M, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2026,7 +2127,7 @@ const device_t st506_xt_st11_r_device = { .name = "ST-11R RLL Fixed Disk Adapter", .internal_name = "st506_xt_st11_r", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 12, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_ST11R, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2040,7 +2141,7 @@ const device_t st506_xt_wd1002a_wx1_device = { .name = "WD1002A-WX1 MFM Fixed Disk Adapter", .internal_name = "st506_xt_wd1002a_wx1", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 21, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1002A_WX1, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2050,11 +2151,25 @@ const device_t st506_xt_wd1002a_wx1_device = { .config = wd_config }; +const device_t st506_xt_wd1002a_wx1_nobios_device = { + .name = "WD1002A-WX1 MFM Fixed Disk Adapter (No BIOS)", + .internal_name = "st506_xt_wd1002a_wx1", + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1002A_WX1_NOBIOS, + .init = st506_init, + .close = st506_close, + .reset = NULL, + { .available = wd1002a_wx1_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = wd_nobios_config +}; + const device_t st506_xt_wd1002a_27x_device = { .name = "WD1002A-27X RLL Fixed Disk Adapter", .internal_name = "st506_xt_wd1002a_27x", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 22, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1002A_27X, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2068,11 +2183,11 @@ const device_t st506_xt_wd1004a_wx1_device = { .name = "WD1004A-WX1 MFM Fixed Disk Adapter", .internal_name = "st506_xt_wd1004a_wx1", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 21, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1004A_WX1, .init = st506_init, .close = st506_close, .reset = NULL, - { wd1004a_wx1_available }, + { .available = wd1004a_wx1_available }, .speed_changed = NULL, .force_redraw = NULL, .config = wd1004a_config @@ -2082,7 +2197,7 @@ const device_t st506_xt_wd1004_27x_device = { .name = "WD1004-27X RLL Fixed Disk Adapter", .internal_name = "st506_xt_wd1004_27x", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 22, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1004_27X, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2096,7 +2211,7 @@ const device_t st506_xt_wd1004a_27x_device = { .name = "WD1004a-27X RLL Fixed Disk Adapter", .internal_name = "st506_xt_wd1004a_27x", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 22, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1004A_27X, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2110,7 +2225,7 @@ const device_t st506_xt_victor_v86p_device = { .name = "Victor V86P RLL Fixed Disk Adapter", .internal_name = "st506_xt_victor_v86p", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 23, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_VICTOR_V86P, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2124,7 +2239,7 @@ const device_t st506_xt_toshiba_t1200_device = { .name = "Toshiba T1200 RLL Fixed Disk Adapter", .internal_name = "st506_xt_toshiba_t1200", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 24, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_TOSHIBA_T1200, .init = st506_init, .close = st506_close, .reset = NULL, diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 99c16b3d4..a09914c6d 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -112,10 +112,12 @@ extern const device_t opti291_device; extern const device_t opti493_device; extern const device_t opti495_device; extern const device_t opti802g_device; +extern const device_t opti802g_pci_device; extern const device_t opti822_device; extern const device_t opti895_device; extern const device_t opti5x7_device; +extern const device_t opti5x7_pci_device; /* SiS */ extern const device_t rabbit_device; diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 677f1a620..d2c1f9e8e 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -27,9 +27,10 @@ #define PCI_COMMAND_IO 0x01 #define PCI_COMMAND_MEM 0x02 -#define PCI_NO_IRQ_STEERING 0x8000 -#define PCI_CAN_SWITCH_TYPE 0x10000 -#define PCI_NO_BRIDGES 0x20000 +#define PCI_NO_IRQ_STEERING 0x8000 +#define PCI_CAN_SWITCH_TYPE 0x10000 +#define PCI_NO_BRIDGES 0x20000 +#define PCI_ALWAYS_EXPOSE_DEV0 0x40000 #define PCI_CONFIG_TYPE_1 1 #define PCI_CONFIG_TYPE_2 2 diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 1f616b791..4d0b27b98 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -632,12 +632,15 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth return ret; machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&opti802g_device); + device_add(&opti802g_pci_device); device_add(&opti822_device); device_add(&keyboard_ps2_device); device_add(&fdc37c665_device); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index f47a6f6df..a5bff87d7 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -385,12 +385,16 @@ machine_at_p5vl_init(const machine_t *model) return ret; machine_at_common_init(model); + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&opti5x7_device); + pci_register_slot(0x12, PCI_CARD_NORMAL, 5, 6, 7, 8); + pci_register_slot(0x13, PCI_CARD_NORMAL, 9, 10, 11, 12); + pci_register_slot(0x14, PCI_CARD_NORMAL, 13, 14, 15, 16); + + device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); device_add(&keyboard_at_ami_device); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 4e51acb47..c0c18f3c7 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -335,12 +335,15 @@ machine_at_hot543_init(const machine_t *model) return ret; machine_at_common_init(model); + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&opti5x7_device); + + device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); device_add(&keyboard_at_device); diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index 7e55766df..51d23da40 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -888,7 +888,7 @@ machine_xt_t1000_init(const machine_t *model) machine_common_init(model); pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); - device_add(&keyboard_xt_device); + device_add(&keyboard_xt_t1x00_device); t1000.fdc = device_add(&fdc_xt_device); nmi_init(); @@ -948,7 +948,7 @@ machine_xt_t1200_init(const machine_t *model) NULL, MEM_MAPPING_EXTERNAL, &t1000); pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); - device_add(&keyboard_xt_device); + device_add(&keyboard_xt_t1x00_device); t1000.fdc = device_add(&fdc_xt_t1x00_device); nmi_init(); diff --git a/src/mem/mem.c b/src/mem/mem.c index ecda875a6..2aea1748f 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -302,7 +302,7 @@ mmutranslatereal_normal(uint32_t addr, int rw) if ((temp & 0x80) && (cr4 & CR4_PSE)) { /*4MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) { + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { cr2 = addr; temp &= 1; if (CPL == 3) @@ -323,7 +323,7 @@ mmutranslatereal_normal(uint32_t addr, int rw) temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); temp3 = temp & temp2; - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) { + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { cr2 = addr; temp &= 1; if (CPL == 3) diff --git a/src/pci.c b/src/pci.c index b4078167c..6b51b0769 100644 --- a/src/pci.c +++ b/src/pci.c @@ -59,14 +59,15 @@ static uint8_t pci_irqs[16], pci_irq_level[16]; static uint64_t pci_irq_hold[16]; static pci_mirq_t pci_mirqs[8]; static int pci_type, - pci_switch, - pci_index, - pci_func, - pci_card, - pci_bus, - pci_enable, - pci_key; -static int trc_reg = 0; + pci_switch, + pci_index, + pci_func, + pci_card, + pci_bus, + pci_enable, + pci_key; +static int trc_reg = 0; +static uint32_t pci_base = 0xc000, pci_size = 0x1000; static void pci_reset_regs(void); @@ -388,22 +389,40 @@ static uint8_t pci_type2_read(uint16_t port, void *priv); void pci_set_pmc(uint8_t pmc) { - pci_reset_regs(); + pci_log("pci_set_pmc(%02X)\n", pmc); + // pci_reset_regs(); if (!pci_pmc && (pmc & 0x01)) { + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + io_removehandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_removehandler(0x0cfa, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); + io_sethandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); io_sethandler(0x0cfc, 4, - pci_read, NULL, NULL, pci_write, NULL, NULL, NULL); + pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); } else if (pci_pmc && !(pmc & 0x01)) { + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + if (pci_key) { + io_sethandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + } + io_removehandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); + io_removehandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); io_removehandler(0x0cfc, 4, - pci_read, NULL, NULL, pci_write, NULL, NULL, NULL); + pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, @@ -421,19 +440,36 @@ pci_type2_write(uint16_t port, uint8_t val, void *priv) if (port == 0xcf8) { pci_func = (val >> 1) & 7; - if (!pci_key && (val & 0xf0)) - io_sethandler(0xc000, 0x1000, + if (!pci_key && (val & 0xf0)) { + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + io_sethandler(pci_base, pci_size, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - else if (pci_key && !(val & 0xf0)) - io_removehandler(0xc000, 0x1000, + } else if (pci_key && !(val & 0xf0)) + io_removehandler(pci_base, pci_size, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); pci_key = val & 0xf0; - } else if (port == 0xcfa) + } else if (port == 0xcfa) { pci_bus = val; - else if (port == 0xcfb) { + + pci_log("Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); + + /* Evidently, writing here, we should also enable the + configuration space. */ + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + io_sethandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + + /* Mark as enabled. */ + pci_key |= 0x100; + } else if (port == 0xcfb) { pci_log("Write %02X to port 0CFB\n", val); pci_set_pmc(val); } else { @@ -473,32 +509,36 @@ static uint8_t pci_type2_read(uint16_t port, void *priv) { uint8_t slot = 0; + uint8_t ret = 0xff; if (port == 0xcf8) - return pci_key | (pci_func << 1); + ret = pci_key | (pci_func << 1); else if (port == 0xcfa) - return pci_bus; + ret = pci_bus; else if (port == 0xcfb) - return pci_pmc; + ret = pci_pmc; + else { + pci_card = (port >> 8) & 0xf; + pci_index = port & 0xff; - pci_card = (port >> 8) & 0xf; - pci_index = port & 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].read) - return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != 0xff) { + if (pci_cards[slot].read) + ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); +#endif + } #ifdef ENABLE_PCI_LOG else - pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); + pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); #endif - return 0xff; + pci_log("Reading %02X at PCI register %02X at bus %02X, card %02X, function %02X\n", ret, pci_index, pci_bus, pci_card, pci_func); + } + + return ret; } void @@ -610,7 +650,7 @@ pci_set_irq(uint8_t card, uint8_t pci_int) if (pci_type & PCI_NO_IRQ_STEERING) irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); else { - irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3; + irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 15; pci_log("pci_set_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); irq_line = pci_irqs[irq_routing]; @@ -735,7 +775,7 @@ pci_clear_irq(uint8_t card, uint8_t pci_int) if (pci_type & PCI_NO_IRQ_STEERING) irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); else { - irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3; + irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 15; // pci_log("pci_clear_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); irq_line = pci_irqs[irq_routing]; @@ -782,7 +822,7 @@ pci_reset_regs(void) { pci_index = pci_card = pci_func = pci_bus = pci_key = 0; - io_removehandler(0xc000, 0x1000, + io_removehandler(pci_base, pci_size, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); } @@ -816,12 +856,17 @@ void pci_reset(void) { if (pci_switch) { + pci_log("pci_reset(): Switchable configuration mechanism\n"); pci_pmc = 0x00; io_removehandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); io_removehandler(0x0cfc, 4, - pci_read, NULL, NULL, pci_write, NULL, NULL, NULL); + pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); + io_removehandler(0x0cf8, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + io_removehandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, @@ -931,6 +976,9 @@ pci_init(int type) { int c; + pci_base = 0xc000; + pci_size = 0x1000; + pci_slots_clear(); pci_reset_hard(); @@ -941,6 +989,7 @@ pci_init(int type) pci_switch = !!(type & PCI_CAN_SWITCH_TYPE); if (pci_switch) { + pci_log("PCI: Switchable configuration mechanism\n"); pci_pmc = 0x00; io_sethandler(0x0cfb, 1, @@ -956,17 +1005,29 @@ pci_init(int type) } if ((type & PCI_CONFIG_TYPE_MASK) == PCI_CONFIG_TYPE_1) { + pci_log("PCI: Configuration mechanism #1\n"); io_sethandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); io_sethandler(0x0cfc, 4, pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); pci_pmc = 1; } else { + pci_log("PCI: Configuration mechanism #2\n"); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); pci_pmc = 0; + + if (type & PCI_ALWAYS_EXPOSE_DEV0) { + pci_log("PCI: Always expose device 0\n"); + pci_base = 0xc100; + pci_size = 0x0f00; + + io_sethandler(0xc000, 0x0100, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + } } for (c = 0; c < 4; c++) { diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 4b5c8d30d..d6ce352ef 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Metoda &filtrování" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 45f344a9e..2897b23f5 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -76,6 +76,24 @@ msgstr "1,&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Filteringmethode" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 9ea707546..48e978f86 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Filter method" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 916619b02..a6b577322 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Filter method" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 0923b9948..4c803a442 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "&Método de filtrado" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index ea250563d..2bfc8c1fc 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "&Suodatusmetodi" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 98a5f60fa..beb98e567 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Methode Filtre" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 7b9cd71ea..c39644c00 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -76,6 +76,24 @@ msgstr "1,&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Metoda filtriranja" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 022523ff9..7d3d524c9 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -76,6 +76,24 @@ msgstr "1,&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Szűrési mód" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index a32efc320..d7b2c5006 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Metodo filtro" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 146275c74..790ea1ebc 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -76,6 +76,24 @@ msgstr "1.5x(&5)" msgid "&2x" msgstr "2x(&2)" +msgid "&3x" +msgstr "3x(&3)" + +msgid "&4x" +msgstr "4x(&4)" + +msgid "&5x" +msgstr "5x(&5)" + +msgid "&6x" +msgstr "6x(&6)" + +msgid "&7x" +msgstr "7x(&7)" + +msgid "&8x" +msgstr "8x(&8)" + msgid "Filter method" msgstr "フィルター方式" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 13f5be067..05d8dcf59 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -76,6 +76,24 @@ msgstr "1.5배(&5)" msgid "&2x" msgstr "2배(&2)" +msgid "&3x" +msgstr "3배(&3)" + +msgid "&4x" +msgstr "4배(&4)" + +msgid "&5x" +msgstr "5배(&5)" + +msgid "&6x" +msgstr "6배(&6)" + +msgid "&7x" +msgstr "7배(&7)" + +msgid "&8x" +msgstr "8배(&8)" + msgid "Filter method" msgstr "필터 형식" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 1a17217d6..71d109e2a 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Metoda filtrowania" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 44c03cfec..29e6031a6 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -76,6 +76,24 @@ msgstr "1,&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Método de filtragem" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 1cf187a0c..8349f7035 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Método de filtragem" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index b483fabb3..9e0b4101d 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Метод фильтрации" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 6ea64a7c2..80f36a022 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "&Metoda filtriranja" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 58f2c08bb..aa0273c79 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "&Filtre metodu" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 5b16fa84c..f40e4d826 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Метод фільтрації" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index b83ab1d46..a863fc4b3 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -76,6 +76,24 @@ msgstr "1.5x(&5)" msgid "&2x" msgstr "2x(&2)" +msgid "&3x" +msgstr "3x(&3)" + +msgid "&4x" +msgstr "4x(&4)" + +msgid "&5x" +msgstr "5x(&5)" + +msgid "&6x" +msgstr "6x(&6)" + +msgid "&7x" +msgstr "7x(&7)" + +msgid "&8x" +msgstr "8x(&8)" + msgid "Filter method" msgstr "过滤方式" diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index 29b3613ea..006eb1d77 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -46,7 +46,9 @@ void HardwareRenderer::initializeGL() { m_context->makeCurrent(this); initializeOpenGLFunctions(); - m_texture = new QOpenGLTexture(QImage(2048,2048, QImage::Format::Format_RGB32)); + auto image = QImage(2048, 2048, QImage::Format_RGB32); + image.fill(0xff000000); + m_texture = new QOpenGLTexture(image); m_blt = new QOpenGLTextureBlitter; m_blt->setRedBlueSwizzle(true); m_blt->create(); @@ -138,6 +140,7 @@ void HardwareRenderer::initializeGL() pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); glClearColor(0, 0, 0, 1); m_texture->setWrapMode(QOpenGLTexture::ClampToEdge); + update(); } void HardwareRenderer::paintGL() { diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e43db23e7..0f3c152f5 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -154,7 +154,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->stackedWidget->setMouseTracking(true); statusBar()->setVisible(!hide_status_bar); statusBar()->setStyleSheet("QStatusBar::item {border: None; } QStatusBar QLabel { margin-right: 2px; margin-bottom: 1px; }"); - this->setStyleSheet("#centralWidget { background-color: black; }"); + this->centralWidget()->setStyleSheet("background-color: black;"); ui->toolBar->setVisible(!hide_tool_bar); renderers[0].reset(nullptr); auto toolbar_spacer = new QWidget(); @@ -416,12 +416,36 @@ MainWindow::MainWindow(QWidget *parent) : case 3: ui->action2x->setChecked(true); break; + case 4: + ui->action3x->setChecked(true); + break; + case 5: + ui->action4x->setChecked(true); + break; + case 6: + ui->action5x->setChecked(true); + break; + case 7: + ui->action6x->setChecked(true); + break; + case 8: + ui->action7x->setChecked(true); + break; + case 9: + ui->action8x->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->action0_5x); actGroup->addAction(ui->action1x); actGroup->addAction(ui->action1_5x); actGroup->addAction(ui->action2x); + actGroup->addAction(ui->action3x); + actGroup->addAction(ui->action4x); + actGroup->addAction(ui->action5x); + actGroup->addAction(ui->action6x); + actGroup->addAction(ui->action7x); + actGroup->addAction(ui->action8x); switch (video_filter_method) { case 0: ui->actionNearest->setChecked(true); @@ -507,15 +531,6 @@ MainWindow::MainWindow(QWidget *parent) : #endif if (!vnc_enabled) video_setblit(qt_blit); - if (start_in_fullscreen) { - connect(ui->stackedWidget, &RendererStack::blit, this, [this] () { - if (start_in_fullscreen) { - QTimer::singleShot(100, ui->actionFullscreen, &QAction::trigger); - start_in_fullscreen = 0; - } - }); - } - #ifdef MTR_ENABLED { ui->actionBegin_trace->setVisible(true); @@ -711,6 +726,10 @@ void MainWindow::showEvent(QShowEvent *event) { QApplication::processEvents(); this->adjustSize(); } + if (start_in_fullscreen) { + start_in_fullscreen = 0; + QTimer::singleShot(0, ui->actionFullscreen, &QAction::trigger); + } } void MainWindow::on_actionKeyboard_requires_capture_triggered() { @@ -1631,7 +1650,7 @@ void MainWindow::showMessage_(int flags, const QString &header, const QString &m void MainWindow::keyPressEvent(QKeyEvent* event) { - if (send_keyboard_input && !(kbd_req_capture && !mouse_capture && !video_fullscreen)) + if (send_keyboard_input && !(kbd_req_capture && !mouse_capture)) { // Windows keys in Qt have one-to-one mapping. if (event->key() == Qt::Key_Pause && !keyboard_recv(0x38) && !keyboard_recv(0x138)) { @@ -1770,6 +1789,12 @@ static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) { ui->action1x->setChecked(ui->action1x == selected); ui->action1_5x->setChecked(ui->action1_5x == selected); ui->action2x->setChecked(ui->action2x == selected); + ui->action3x->setChecked(ui->action3x == selected); + ui->action4x->setChecked(ui->action4x == selected); + ui->action5x->setChecked(ui->action5x == selected); + ui->action6x->setChecked(ui->action6x == selected); + ui->action7x->setChecked(ui->action7x == selected); + ui->action8x->setChecked(ui->action8x == selected); reset_screen_size(); device_force_redraw(); @@ -1799,6 +1824,36 @@ void MainWindow::on_action2x_triggered() { update_scaled_checkboxes(ui, ui->action2x); } +void MainWindow::on_action3x_triggered() { + scale = 4; + update_scaled_checkboxes(ui, ui->action3x); +} + +void MainWindow::on_action4x_triggered() { + scale = 5; + update_scaled_checkboxes(ui, ui->action4x); +} + +void MainWindow::on_action5x_triggered() { + scale = 6; + update_scaled_checkboxes(ui, ui->action5x); +} + +void MainWindow::on_action6x_triggered() { + scale = 7; + update_scaled_checkboxes(ui, ui->action6x); +} + +void MainWindow::on_action7x_triggered() { + scale = 8; + update_scaled_checkboxes(ui, ui->action7x); +} + +void MainWindow::on_action8x_triggered() { + scale = 9; + update_scaled_checkboxes(ui, ui->action8x); +} + void MainWindow::on_actionNearest_triggered() { video_filter_method = 0; ui->actionLinear->setChecked(false); diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index ef70a0826..692b9c3f0 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -81,6 +81,12 @@ private slots: void on_action1x_triggered(); void on_action1_5x_triggered(); void on_action2x_triggered(); + void on_action3x_triggered(); + void on_action4x_triggered(); + void on_action5x_triggered(); + void on_action6x_triggered(); + void on_action7x_triggered(); + void on_action8x_triggered(); void on_actionLinear_triggered(); void on_actionNearest_triggered(); void on_actionFullScreen_int_triggered(); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 3551eddb1..fcc337cb3 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -118,6 +118,12 @@ + + + + + + @@ -478,6 +484,54 @@ &2x + + + true + + + &3x + + + + + true + + + &4x + + + + + true + + + &5x + + + + + true + + + &6x + + + + + true + + + &7x + + + + + true + + + &8x + + true diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index bea1af22f..560249660 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -18,7 +18,6 @@ * Copyright 2021-2022 Cacodemon345 * Copyright 2021-2022 Teemu Korhonen */ -#include "qt_mediamenu.hpp" #include "qt_progsettings.hpp" #include "qt_machinestatus.hpp" @@ -55,6 +54,7 @@ extern "C" { #include "qt_util.hpp" #include "qt_deviceconfig.hpp" #include "qt_mediahistorymanager.hpp" +#include "qt_mediamenu.hpp" std::shared_ptr MediaMenu::ptr; diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index b3e771fea..6d5b36d80 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -194,6 +194,9 @@ OpenGLRenderer::initialize() emit initialized(); + glClear(GL_COLOR_BUFFER_BIT); + + context->swapBuffers(this); } catch (const opengl_init_error &e) { /* Mark all buffers as in use */ for (auto &flag : buf_usage) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 670a0d0da..2d32f24a8 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -416,6 +416,7 @@ RendererStack::createRenderer(Renderer renderer) current->setFocusPolicy(Qt::NoFocus); current->setFocusProxy(this); current->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + current->setStyleSheet("background-color: black"); addWidget(current.get()); this->setStyleSheet("background-color: black"); diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 1e5ec5a71..e798093c0 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -174,7 +174,7 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) RAWKEYBOARD rawKB = raw->data.keyboard; scancode = rawKB.MakeCode; - if (kbd_req_capture && !mouse_capture && !video_fullscreen) + if (kbd_req_capture && !mouse_capture) return; /* If it's not a scan code that starts with 0xE1 */ diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index c004a8044..bee60bb5f 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -551,12 +551,24 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) case 0x08: case 0x28: case 0xa8: - /* Round it to the nearest 2048 bytes. */ - dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11; - /* FALLTHROUGH */ - case 0xb9: case 0xbe: + /* Round it to the nearest (block length) bytes. */ + if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { + /* READ CD MSF and READ CD: Round the request length to the sector size - the device must ensure + that a media access comand does not DRQ in the middle of a sector. One of the drivers that + relies on the correctness of this behavior is MTMCDAI.SYS (the Mitsumi CD-ROM driver) for DOS + which uses the READ CD command to read data on some CD types. */ + if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { + /* Round to sector length. */ + dlen = ((double) dev->max_transfer_len) / ((double) block_len); + dev->max_transfer_len = ((uint16_t) floor(dlen)) * block_len; + } + } else { + /* Round it to the nearest 2048 bytes. */ + dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11; + } + /* Make sure total length is not bigger than sum of the lengths of all the requested blocks. */ bt = (dev->requested_blocks * block_len); @@ -574,7 +586,8 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) break; } } - /*FALLTHROUGH*/ + /* FALLTHROUGH */ + default: dev->packet_len = len; break; @@ -591,16 +604,6 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) else if (len > dev->max_transfer_len) dev->request_length = dev->max_transfer_len; - /* READ CD MSF and READ CD: Round the request length to the sector size - the device must ensure - that a media access comand does not DRQ in the middle of a sector. One of the drivers that - relies on the correctness of this behavior is MTMCDAI.SYS (the Mitsumi CD-ROM driver) for DOS - which uses the READ CD command to read data on some CD types. */ - if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { - /* Round to sector length. */ - dlen = ((double) dev->request_length) / ((double) block_len); - dev->request_length = ((uint16_t) floor(dlen)) * block_len; - } - return; } diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index d1521ce05..faf35c945 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -2857,7 +2857,8 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int } if (!banshee->has_bios) - mem_size = info->local; /* fixed size for on-board chips */ + // mem_size = info->local; /* fixed size for on-board chips */ + mem_size = device_get_config_int("memory"); /* MS-6168 / Bora Pro can do both 8 and 16 MB. */ else if (has_sgram) { if (banshee->type == TYPE_VELOCITY100) mem_size = 8; /* Velocity 100 only supports 8 MB */ @@ -3001,7 +3002,7 @@ v3_2000_agp_init(const device_t *info) static void * v3_2000_agp_onboard_init(const device_t *info) { - return banshee_init_common(info, NULL, 0, TYPE_V3_2000, VOODOO_3, 1); + return banshee_init_common(info, NULL, 1, TYPE_V3_2000, VOODOO_3, 1); } static void * v3_3000_init(const device_t *info) @@ -3144,7 +3145,7 @@ const device_t voodoo_3_2000_agp_onboard_8m_device = { { .available = NULL }, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, - banshee_sdram_config + banshee_sgram_config }; const device_t voodoo_3_3000_device = { diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index 66fd0503d..98eb4739f 100644 --- a/src/win/win_dynld.c +++ b/src/win/win_dynld.c @@ -25,59 +25,63 @@ #include <86box/86box.h> #include <86box/plat_dynld.h> + #ifdef ENABLE_DYNLD_LOG int dynld_do_log = ENABLE_DYNLD_LOG; + static void dynld_log(const char *fmt, ...) { va_list ap; if (dynld_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -# define dynld_log(fmt, ...) +#define dynld_log(fmt, ...) #endif + void * dynld_module(const char *name, dllimp_t *table) { - HMODULE h; + HMODULE h; dllimp_t *imp; - void *func; + void *func; /* See if we can load the desired module. */ if ((h = LoadLibrary(name)) == NULL) { - dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); - return (NULL); + dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); + return(NULL); } /* Now load the desired function pointers. */ - for (imp = table; imp->name != NULL; imp++) { - func = GetProcAddress(h, imp->name); - if (func == NULL) { - dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", - name, imp->name, GetLastError()); - FreeLibrary(h); - return (NULL); - } + for (imp=table; imp->name!=NULL; imp++) { + func = GetProcAddress(h, imp->name); + if (func == NULL) { + dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", + name, imp->name, GetLastError()); + FreeLibrary(h); + return(NULL); + } - /* To overcome typing issues.. */ - *(char **) imp->func = (char *) func; + /* To overcome typing issues.. */ + *(char **)imp->func = (char *)func; } /* All good. */ dynld_log("loaded %s\n", name); - return ((void *) h); + return((void *)h); } + void dynld_close(void *handle) { if (handle != NULL) - FreeLibrary((HMODULE) handle); + FreeLibrary((HMODULE)handle); }