Merge pull request #1 from 86Box/master

Bring up to par with main 86Box master.
This commit is contained in:
Miran Grča
2025-05-22 06:25:16 +02:00
committed by GitHub
25 changed files with 1445 additions and 676 deletions

View File

@@ -36,6 +36,7 @@
#include <86box/pit.h>
#include <86box/apm.h>
#include <86box/acpi.h>
#include <86box/dma.h>
#include <86box/machine.h>
#include <86box/i2c.h>
#include <86box/video.h>
@@ -1025,8 +1026,13 @@ acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *p
nvr_reg_write(0x000f, 0xff, dev->nvr);
}
if (sus_typ & SUS_RESET_PCI)
if (sus_typ & SUS_RESET_PCI) {
/* DMA is part of the southbridge so it responds to PCI reset. */
dma_reset();
dma_set_at(1);
device_reset_all(DEVICE_PCI);
}
if (sus_typ & SUS_RESET_CPU)
cpu_alt_reset = 0;

View File

@@ -155,6 +155,7 @@ piix_ide_handlers(piix_t *dev, int bus)
uint16_t side;
if (bus & 0x01) {
piix_log("Disabling primary IDE...\n");
ide_pri_disable();
if (dev->type == 5) {
@@ -170,11 +171,14 @@ piix_ide_handlers(piix_t *dev, int bus)
ide_set_side(0, side);
}
if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x41] & 0x80))
if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x41] & 0x80)) {
piix_log("Enabling primary IDE...\n");
ide_pri_enable();
}
}
if (bus & 0x02) {
piix_log("Disabling secondary IDE...\n");
ide_sec_disable();
if (dev->type == 5) {
@@ -190,8 +194,10 @@ piix_ide_handlers(piix_t *dev, int bus)
ide_set_side(1, side);
}
if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x43] & 0x80))
if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x43] & 0x80)) {
piix_log("Enabling secondary IDE...\n");
ide_sec_enable();
}
}
}
@@ -465,6 +471,13 @@ piix_write(int func, int addr, uint8_t val, void *priv)
uint8_t *fregs;
uint16_t base;
/* Dell OptiPlex Gn+ shows that register 02:FF is aliased in 01:FF. */
if ((dev->type == 4) && (func == 1) && (addr == 0xff))
func = 2;
if ((func == 1) || (addr == 0xf8) || (addr == 0xf9))
piix_log("[W] %02X:%02X = %02X\n", func, addr, val);
/* Return on unsupported function. */
if (dev->max_func > 0) {
if (func > dev->max_func)
@@ -736,6 +749,8 @@ piix_write(int func, int addr, uint8_t val, void *priv)
fregs[addr] = val;
break;
case 0xb0:
if (val & 0x10)
warning("Write %02X to B0\n", val);
if (dev->type == 4)
fregs[addr] = (fregs[addr] & 0x8c) | (val & 0x73);
else if (dev->type == 5)
@@ -745,6 +760,8 @@ piix_write(int func, int addr, uint8_t val, void *priv)
alt_access = !!(val & 0x20);
break;
case 0xb1:
if (val & 0x18)
warning("Write %02X to B1\n", val);
if (dev->type > 3)
fregs[addr] = val & 0xdf;
break;
@@ -923,6 +940,12 @@ piix_write(int func, int addr, uint8_t val, void *priv)
if (dev->type > 4)
fregs[addr] = val;
break;
case 0xf8:
case 0xf9:
/* Undocumented! */
if (dev->type == 4)
fregs[addr] = val;
break;
default:
break;
}
@@ -1169,6 +1192,10 @@ piix_read(int func, int addr, void *priv)
uint8_t ret = 0xff;
const uint8_t *fregs;
/* Dell OptiPlex Gn+ shows that register 02:FF is aliased in 01:FF. */
if ((dev->type == 4) && (func == 1) && (addr == 0xff))
func = 2;
if ((dev->type == 3) && (func == 2) && (dev->max_func == 1) && (addr >= 0x40))
ret = 0x00;
@@ -1199,7 +1226,7 @@ piix_reset_hard(piix_t *dev)
sff_set_slot(dev->bm[1], dev->pci_slot);
sff_set_irq_pin(dev->bm[1], PCI_INTA);
sff_set_irq_line(dev->bm[1], 14);
sff_set_irq_line(dev->bm[1], 15);
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
}
@@ -1315,6 +1342,10 @@ piix_reset_hard(piix_t *dev)
fregs[0x45] = 0x55;
fregs[0x46] = 0x01;
}
if (dev->type == 4) {
fregs[0xf8] = 0x30;
fregs[0xf9] = 0x0f;
}
if ((dev->type == 1) && (dev->rev == 2))
dev->max_func = 0; /* It starts with IDE disabled, then enables it. */
else
@@ -1678,7 +1709,7 @@ const device_t piix4_device = {
.name = "Intel 82371AB/EB (PIIX4/PIIX4E)",
.internal_name = "piix4",
.flags = DEVICE_PCI,
.local = 0x71100004,
.local = 0x71100014,
.init = piix_init,
.close = piix_close,
.reset = piix_reset,

View File

@@ -145,6 +145,11 @@ typedef struct atkbc_t {
/* Internal FIFO for the purpose of commands with multi-byte output. */
uint8_t key_ctrl_queue[64];
uint8_t handler_enable[2];
uint16_t base_addr[2];
uint16_t irq[2];
uint32_t flags;
/* Main timers. */
@@ -157,8 +162,13 @@ typedef struct atkbc_t {
/* Local copies of the pointers to both ports for easier swapping (AMI '5' MegaKey). */
kbc_at_port_t *ports[2];
uint8_t (*write60_ven)(void *priv, uint8_t val);
uint8_t (*write64_ven)(void *priv, uint8_t val);
struct {
uint8_t (*read)(uint16_t port, void *priv);
void (*write)(uint16_t port, uint8_t val, void *priv);
} handlers[2];
uint8_t (*write_cmd_data_ven)(void *priv, uint8_t val);
uint8_t (*write_cmd_ven)(void *priv, uint8_t val);
} atkbc_t;
/* Keyboard controller ports. */
@@ -167,8 +177,6 @@ kbc_at_port_t *kbc_at_ports[2] = { NULL, NULL };
static uint8_t kbc_ami_revision = '8';
static uint8_t kbc_award_revision = 0x42;
static uint8_t kbc_handler_set = 0;
static void (*kbc_at_do_poll)(atkbc_t *dev);
/* Non-translated to translated scan codes. */
@@ -362,12 +370,19 @@ kbc_do_irq(atkbc_t *dev)
if (dev->do_irq) {
/* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly
written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */
picint_common(1 << 1, 0, 0, NULL);
picint_common(1 << 12, 0, 0, NULL);
if (dev->channel >= 2)
picint_common(1 << 12, 0, 1, NULL);
else
picint_common(1 << 1, 0, 1, NULL);
if (dev->irq[0] != 0xffff)
picint_common(1 << dev->irq[0], 0, 0, NULL);
if (dev->irq[1] != 0xffff)
picint_common(1 << dev->irq[1], 0, 0, NULL);
if (dev->channel >= 2) {
if (dev->irq[1] != 0xffff)
picint_common(1 << dev->irq[1], 0, 1, NULL);
} else {
if (dev->irq[0] != 0xffff)
picint_common(1 << dev->irq[0], 0, 1, NULL);
}
dev->do_irq = 0;
}
@@ -404,7 +419,9 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi)
} else if (dev->mem[0x20] & 0x01)
kbc_set_do_irq(dev, channel);
} else if (dev->mem[0x20] & 0x01)
picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */
/* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */
if (dev->irq[0] != 0xffff)
picintlevel(1 << dev->irq[0], &dev->irq_state);
#ifdef WRONG_CONDITION
if ((dev->channel > 0) || dev->is_asic || (kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM))
@@ -784,10 +801,12 @@ write_p2(atkbc_t *dev, uint8_t val)
/* PS/2: Handle IRQ's. */
if (dev->misc_flags & FLAG_PS2) {
/* IRQ 12 */
picint_common(1 << 12, 0, val & 0x20, NULL);
if (dev->irq[1] != 0xffff)
picint_common(1 << dev->irq[1], 0, val & 0x20, NULL);
/* IRQ 1 */
picint_common(1 << 1, 0, val & 0x10, NULL);
if (dev->irq[0] != 0xffff)
picint_common(1 << dev->irq[0], 0, val & 0x10, NULL);
}
#endif
@@ -932,7 +951,7 @@ pulse_poll(void *priv)
}
static uint8_t
write64_generic(void *priv, uint8_t val)
write_cmd_generic(void *priv, uint8_t val)
{
atkbc_t *dev = (atkbc_t *) priv;
uint8_t current_drive;
@@ -1106,6 +1125,14 @@ write64_generic(void *priv, uint8_t val)
*/
uint8_t p1 = 0x30;
kbc_delay_to_ob(dev, p1, 0, 0x00);
} else if (!strcmp(machine_get_internal_name(), "dellplato") || !strcmp(machine_get_internal_name(), "dellhannibalp")) {
/*
Dell Dimension XPS Pxxx & Pxxxa/Mxxxa:
- Bit 3: Password disable jumper (must be clear);
- Bit 4: Clear CMOS jumper (must be set);
*/
uint8_t p1 = 0x10;
kbc_delay_to_ob(dev, p1, 0, 0x00);
} else {
/* (B0 or F0) | (0x08 or 0x0c) */
uint8_t p1_out = ((dev->p1 | fixed_bits) & 0xf0) |
@@ -1170,7 +1197,7 @@ write64_generic(void *priv, uint8_t val)
}
static uint8_t
write60_ami(void *priv, uint8_t val)
write_cmd_data_ami(void *priv, uint8_t val)
{
atkbc_t *dev = (atkbc_t *) priv;
@@ -1240,7 +1267,7 @@ kbc_at_set_ps2(void *priv, const uint8_t ps2)
}
static uint8_t
write64_ami(void *priv, uint8_t val)
write_cmd_ami(void *priv, uint8_t val)
{
atkbc_t *dev = (atkbc_t *) priv;
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
@@ -1445,11 +1472,11 @@ write64_ami(void *priv, uint8_t val)
break;
}
return write64_generic(dev, val);
return write_cmd_generic(dev, val);
}
static uint8_t
write60_phoenix(void *priv, uint8_t val)
write_cmd_data_phoenix(void *priv, uint8_t val)
{
atkbc_t *dev = (atkbc_t *) priv;
@@ -1522,7 +1549,7 @@ write60_phoenix(void *priv, uint8_t val)
}
static uint8_t
write64_phoenix(void *priv, uint8_t val)
write_cmd_phoenix(void *priv, uint8_t val)
{
atkbc_t *dev = (atkbc_t *) priv;
@@ -1668,11 +1695,11 @@ write64_phoenix(void *priv, uint8_t val)
break;
}
return write64_generic(dev, val);
return write_cmd_generic(dev, val);
}
static uint8_t
write64_siemens(void *priv, uint8_t val)
write_cmd_siemens(void *priv, uint8_t val)
{
atkbc_t *dev = (atkbc_t *) priv;
@@ -1701,11 +1728,11 @@ write64_siemens(void *priv, uint8_t val)
break;
}
return write64_ami(dev, val);
return write_cmd_ami(dev, val);
}
static uint8_t
write60_quadtel(void *priv, UNUSED(uint8_t val))
write_cmd_data_quadtel(void *priv, UNUSED(uint8_t val))
{
const atkbc_t *dev = (atkbc_t *) priv;
@@ -1722,7 +1749,7 @@ write60_quadtel(void *priv, UNUSED(uint8_t val))
}
static uint8_t
write64_olivetti(void *priv, uint8_t val)
write_cmd_olivetti(void *priv, uint8_t val)
{
atkbc_t *dev = (atkbc_t *) priv;
@@ -1743,11 +1770,11 @@ write64_olivetti(void *priv, uint8_t val)
break;
}
return write64_generic(dev, val);
return write_cmd_generic(dev, val);
}
static uint8_t
write64_quadtel(void *priv, uint8_t val)
write_cmd_quadtel(void *priv, uint8_t val)
{
atkbc_t *dev = (atkbc_t *) priv;
@@ -1766,11 +1793,11 @@ write64_quadtel(void *priv, uint8_t val)
break;
}
return write64_generic(dev, val);
return write_cmd_generic(dev, val);
}
static uint8_t
write60_toshiba(void *priv, uint8_t val)
write_cmd_data_toshiba(void *priv, uint8_t val)
{
const atkbc_t *dev = (atkbc_t *) priv;
@@ -1788,7 +1815,7 @@ write60_toshiba(void *priv, uint8_t val)
}
static uint8_t
write64_toshiba(void *priv, uint8_t val)
write_cmd_toshiba(void *priv, uint8_t val)
{
atkbc_t *dev = (atkbc_t *) priv;
@@ -1877,7 +1904,7 @@ write64_toshiba(void *priv, uint8_t val)
break;
}
return write64_generic(dev, val);
return write_cmd_generic(dev, val);
}
static void
@@ -1921,8 +1948,10 @@ kbc_at_process_cmd(void *priv)
/* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */
dev->p1 = dev->p1 & 0xff;
write_p2(dev, 0x4b);
picintc(0x1000);
picintc(0x0002);
if (dev->irq[1] != 0xffff)
picintc(1 << dev->irq[1]);
if (dev->irq[0] != 0xffff)
picintc(1 << dev->irq[0]);
}
dev->status = (dev->status & 0x0f) | 0x60;
@@ -1941,7 +1970,8 @@ kbc_at_process_cmd(void *priv)
/* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */
dev->p1 = dev->p1 & 0xff;
write_p2(dev, 0xcf);
picintclevel(0x0002, &dev->irq_state);
if (dev->irq[0] != 0xffff)
picintclevel(1 << dev->irq[0], &dev->irq_state);
dev->irq_state = 0;
}
@@ -2056,8 +2086,8 @@ kbc_at_process_cmd(void *priv)
* that. Otherwise, or if that handler fails,
* log a bad command.
*/
if (dev->write64_ven)
bad = dev->write64_ven(dev, dev->ib);
if (dev->write_cmd_ven)
bad = dev->write_cmd_ven(dev, dev->ib);
kbc_at_log(bad ? "ATkbc: bad controller command %02X\n" : "", dev->ib);
}
@@ -2143,8 +2173,8 @@ kbc_at_process_cmd(void *priv)
* it returns an error, log a bad
* controller command.
*/
if (dev->write60_ven)
bad = dev->write60_ven(dev, dev->ib);
if (dev->write_cmd_data_ven)
bad = dev->write_cmd_data_ven(dev, dev->ib);
if (bad) {
kbc_at_log("ATkbc: bad controller command %02x data %02x\n", dev->command, dev->ib);
@@ -2154,7 +2184,7 @@ kbc_at_process_cmd(void *priv)
}
static void
kbc_at_write(uint16_t port, uint8_t val, void *priv)
kbc_at_port_1_write(uint16_t port, uint8_t val, void *priv)
{
atkbc_t *dev = (atkbc_t *) priv;
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
@@ -2162,83 +2192,89 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv)
kbc_at_log("ATkbc: [%04X:%08X] write(%04X) = %02X\n", CS, cpu_state.pc, port, val);
switch (port) {
case 0x60:
dev->status &= ~STAT_CD;
if (fast_a20 && dev->wantdata && (dev->command == 0xd1)) {
kbc_at_log("ATkbc: write P2\n");
dev->status &= ~STAT_CD;
/* Fast A20 - ignore all other bits. */
write_p2_fast_a20(dev, (dev->p2 & 0xfd) | (val & 0x02));
if (fast_a20 && dev->wantdata && (dev->command == 0xd1)) {
kbc_at_log("ATkbc: write P2\n");
dev->wantdata = 0;
dev->state = STATE_MAIN_IBF;
/* Fast A20 - ignore all other bits. */
write_p2_fast_a20(dev, (dev->p2 & 0xfd) | (val & 0x02));
/*
Explicitly clear IBF so that any preceding
command is not executed.
*/
dev->status &= ~STAT_IFULL;
return;
}
break;
dev->wantdata = 0;
dev->state = STATE_MAIN_IBF;
case 0x64:
dev->status |= STAT_CD;
if (fast_a20 && (val == 0xd1)) {
kbc_at_log("ATkbc: write P2\n");
dev->wantdata = 1;
dev->state = STATE_KBC_PARAM;
dev->command = 0xd1;
/*
Explicitly clear IBF so that any preceding
command is not executed.
*/
dev->status &= ~STAT_IFULL;
return;
}
/*
Explicitly clear IBF so that any preceding
command is not executed.
*/
dev->status &= ~STAT_IFULL;
return;
} else if (fast_reset && ((val & 0xf0) == 0xf0)) {
pulse_output(dev, val & 0x0f);
dev->ib = val;
dev->status |= STAT_IFULL;
}
dev->state = STATE_MAIN_IBF;
static void
kbc_at_port_2_write(uint16_t port, uint8_t val, void *priv)
{
atkbc_t *dev = (atkbc_t *) priv;
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
uint8_t fast_a20 = (kbc_ven != KBC_VEN_SIEMENS);
/*
Explicitly clear IBF so that any preceding
command is not executed.
*/
dev->status &= ~STAT_IFULL;
return;
} else if (val == 0xad) {
/* Fast track it because of the Bochs BIOS. */
kbc_at_log("ATkbc: disable keyboard\n");
set_enable_kbd(dev, 0);
kbc_at_log("ATkbc: [%04X:%08X] write(%04X) = %02X\n", CS, cpu_state.pc, port, val);
dev->state = STATE_MAIN_IBF;
dev->status |= STAT_CD;
/*
Explicitly clear IBF so that any preceding
command is not executed.
*/
dev->status &= ~STAT_IFULL;
return;
} else if (val == 0xae) {
/* Fast track it because of the LG MultiNet. */
kbc_at_log("ATkbc: enable keyboard\n");
set_enable_kbd(dev, 1);
if (fast_a20 && (val == 0xd1)) {
kbc_at_log("ATkbc: write P2\n");
dev->wantdata = 1;
dev->state = STATE_KBC_PARAM;
dev->command = 0xd1;
dev->state = STATE_MAIN_IBF;
/*
Explicitly clear IBF so that any preceding
command is not executed.
*/
dev->status &= ~STAT_IFULL;
return;
} else if (fast_reset && ((val & 0xf0) == 0xf0)) {
pulse_output(dev, val & 0x0f);
/*
Explicitly clear IBF so that any preceding
command is not executed.
*/
dev->status &= ~STAT_IFULL;
return;
}
break;
dev->state = STATE_MAIN_IBF;
default:
break;
/*
Explicitly clear IBF so that any preceding
command is not executed.
*/
dev->status &= ~STAT_IFULL;
return;
} else if (val == 0xad) {
/* Fast track it because of the Bochs BIOS. */
kbc_at_log("ATkbc: disable keyboard\n");
set_enable_kbd(dev, 0);
dev->state = STATE_MAIN_IBF;
/*
Explicitly clear IBF so that any preceding
command is not executed.
*/
dev->status &= ~STAT_IFULL;
return;
} else if (val == 0xae) {
/* Fast track it because of the LG MultiNet. */
kbc_at_log("ATkbc: enable keyboard\n");
set_enable_kbd(dev, 1);
dev->state = STATE_MAIN_IBF;
/*
Explicitly clear IBF so that any preceding
command is not executed.
*/
dev->status &= ~STAT_IFULL;
return;
}
dev->ib = val;
@@ -2246,7 +2282,7 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv)
}
static uint8_t
kbc_at_read(uint16_t port, void *priv)
kbc_at_port_1_read(uint16_t port, void *priv)
{
atkbc_t *dev = (atkbc_t *) priv;
uint8_t ret = 0xff;
@@ -2254,26 +2290,32 @@ kbc_at_read(uint16_t port, void *priv)
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)
cycles -= ISA_CYCLES(8);
switch (port) {
case 0x60:
ret = dev->ob;
dev->status &= ~STAT_OFULL;
/* TODO: IRQ is only tied to OBF on the AT KBC, on the PS/2 KBC, it is controlled by a P2 bit.
This also means that in AT mode, the IRQ is level-triggered. */
if (!(dev->misc_flags & FLAG_PS2))
picintclevel(1 << 1, &dev->irq_state);
if ((strstr(machine_get_internal_name(), "pb41") != NULL) && (cpu_override_dynarec == 1))
cpu_override_dynarec = 0;
break;
ret = dev->ob;
dev->status &= ~STAT_OFULL;
/*
TODO: IRQ is only tied to OBF on the AT KBC, on the PS/2 KBC, it is controlled by a P2 bit.
This also means that in AT mode, the IRQ is level-triggered.
*/
if (!(dev->misc_flags & FLAG_PS2) && (dev->irq[0] != 0xffff))
picintclevel(1 << dev->irq[0], &dev->irq_state);
if ((strstr(machine_get_internal_name(), "pb41") != NULL) && (cpu_override_dynarec == 1))
cpu_override_dynarec = 0;
case 0x64:
ret = dev->status;
break;
kbc_at_log("ATkbc: [%04X:%08X] read (%04X) = %02X\n", CS, cpu_state.pc, port, ret);
default:
kbc_at_log("ATkbc: read(%04x) invalid!\n",port);
break;
}
return ret;
}
static uint8_t
kbc_at_port_2_read(uint16_t port, void *priv)
{
atkbc_t *dev = (atkbc_t *) priv;
uint8_t ret = 0xff;
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)
cycles -= ISA_CYCLES(8);
ret = dev->status;
kbc_at_log("ATkbc: [%04X:%08X] read (%04X) = %02X\n", CS, cpu_state.pc, port, ret);
@@ -2312,11 +2354,14 @@ kbc_at_reset(void *priv)
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
dev->misc_flags |= FLAG_PS2;
kbc_at_do_poll = kbc_at_poll_ps2;
picintc(0x1000);
picintc(0x0002);
if (dev->irq[1] != 0xffff)
picintc(1 << dev->irq[1]);
if (dev->irq[0] != 0xffff)
picintc(1 << dev->irq[0]);
} else {
kbc_at_do_poll = kbc_at_poll_at;
picintclevel(0x0002, &dev->irq_state);
if (dev->irq[0] != 0xffff)
picintclevel(1 << dev->irq[0], &dev->irq_state);
dev->irq_state = 0;
}
@@ -2359,19 +2404,44 @@ kbc_at_close(void *priv)
}
void
kbc_at_handler(int set, void *priv)
kbc_at_port_handler(int num, int set, uint16_t port, void *priv)
{
if (kbc_handler_set) {
io_removehandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv);
io_removehandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv);
atkbc_t *dev = (atkbc_t *) priv;
if (dev->handler_enable[num] && (dev->base_addr[num] != 0x0000))
io_removehandler(dev->base_addr[num], 1,
dev->handlers[num].read, NULL, NULL,
dev->handlers[num].write, NULL, NULL, priv);
dev->handler_enable[num] = set;
dev->base_addr[num] = port;
if (dev->handler_enable[num] && (dev->base_addr[num] != 0x0000))
io_sethandler(dev->base_addr[num], 1,
dev->handlers[num].read, NULL, NULL,
dev->handlers[num].write, NULL, NULL, priv);
}
void
kbc_at_handler(int set, uint16_t port, void *priv)
{
kbc_at_port_handler(0, set, port, priv);
kbc_at_port_handler(1, set, port + 0x0004, priv);
}
void
kbc_at_set_irq(int num, uint16_t irq, void *priv)
{
atkbc_t *dev = (atkbc_t *) priv;
if (dev->irq[num] != 0xffff) {
if ((num == 0) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1))
picintclevel(1 << dev->irq[num], &dev->irq_state);
else
picintc(1 << dev->irq[num]);
}
kbc_handler_set = set;
if (kbc_handler_set) {
io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv);
io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv);
}
dev->irq[num] = irq;
}
static void *
@@ -2392,16 +2462,21 @@ kbc_at_init(const device_t *info)
if (info->flags & DEVICE_PCI)
dev->misc_flags |= FLAG_PCI;
kbc_handler_set = 0;
kbc_at_handler(1, dev);
dev->handlers[0].read = kbc_at_port_1_read;
dev->handlers[0].write = kbc_at_port_1_write;
dev->handlers[1].read = kbc_at_port_2_read;
dev->handlers[1].write = kbc_at_port_2_write;
dev->irq[0] = 1;
dev->irq[1] = 12;
timer_add(&dev->kbc_poll_timer, kbc_at_poll, dev, 1);
timer_add(&dev->pulse_cb, pulse_poll, dev, 0);
timer_add(&dev->kbc_dev_poll_timer, kbc_at_dev_poll, dev, 1);
dev->write60_ven = NULL;
dev->write64_ven = NULL;
dev->write_cmd_data_ven = NULL;
dev->write_cmd_ven = NULL;
kbc_ami_revision = '8';
kbc_award_revision = 0x42;
@@ -2410,8 +2485,8 @@ kbc_at_init(const device_t *info)
case KBC_VEN_SIEMENS:
kbc_ami_revision = '8';
kbc_award_revision = 0x42;
dev->write60_ven = write60_ami;
dev->write64_ven = write64_siemens;
dev->write_cmd_data_ven = write_cmd_data_ami;
dev->write_cmd_ven = write_cmd_siemens;
break;
case KBC_VEN_ACER:
@@ -2420,24 +2495,24 @@ kbc_at_init(const device_t *info)
case KBC_VEN_IBM_PS1:
case KBC_VEN_IBM:
case KBC_VEN_COMPAQ:
dev->write64_ven = write64_generic;
dev->write_cmd_ven = write_cmd_generic;
break;
case KBC_VEN_OLIVETTI:
dev->write64_ven = write64_olivetti;
dev->write_cmd_ven = write_cmd_olivetti;
break;
case KBC_VEN_ALI:
kbc_ami_revision = 'F';
kbc_award_revision = 0x43;
dev->write60_ven = write60_ami;
dev->write64_ven = write64_ami;
dev->write_cmd_data_ven = write_cmd_data_ami;
dev->write_cmd_ven = write_cmd_ami;
break;
case KBC_VEN_TRIGEM_AMI:
kbc_ami_revision = 'Z';
dev->write60_ven = write60_ami;
dev->write64_ven = write64_ami;
dev->write_cmd_data_ven = write_cmd_data_ami;
dev->write_cmd_ven = write_cmd_ami;
break;
case KBC_VEN_AMI:
@@ -2460,23 +2535,23 @@ kbc_at_init(const device_t *info)
else
kbc_ami_revision = 'F';
dev->write60_ven = write60_ami;
dev->write64_ven = write64_ami;
dev->write_cmd_data_ven = write_cmd_data_ami;
dev->write_cmd_ven = write_cmd_ami;
break;
case KBC_VEN_PHOENIX:
dev->write60_ven = write60_phoenix;
dev->write64_ven = write64_phoenix;
dev->write_cmd_data_ven = write_cmd_data_phoenix;
dev->write_cmd_ven = write_cmd_phoenix;
break;
case KBC_VEN_QUADTEL:
dev->write60_ven = write60_quadtel;
dev->write64_ven = write64_quadtel;
dev->write_cmd_data_ven = write_cmd_data_quadtel;
dev->write_cmd_ven = write_cmd_quadtel;
break;
case KBC_VEN_TOSHIBA:
dev->write60_ven = write60_toshiba;
dev->write64_ven = write64_toshiba;
dev->write_cmd_data_ven = write_cmd_data_toshiba;
dev->write_cmd_ven = write_cmd_toshiba;
break;
default:
@@ -2502,6 +2577,8 @@ kbc_at_init(const device_t *info)
fast_reset = 0x00;
kbc_at_handler(1, 0x0060, dev);
return dev;
}

View File

@@ -30,11 +30,13 @@
#include "cpu.h"
uint8_t postcard_codes[POSTCARDS_NUM];
char postcard_diags[5] = { 0 };
static uint16_t postcard_port;
static uint8_t postcard_written[POSTCARDS_NUM];
static uint8_t postcard_ports_num = 1;
static uint8_t postcard_prev_codes[POSTCARDS_NUM];
static char postcard_prev_diags[5] = { 0 };
#define UISTR_LEN 32
static char postcard_str[UISTR_LEN]; /* UI output string */
@@ -97,6 +99,22 @@ postcard_setui(void)
ps[1][0], ps[1][1], ps[1][2], ps[1][3]);
break;
}
} else if (strstr(machines[machine].name, " Dell ")) {
char dell_diags[10] = { 0 };
if (!postcard_written[1])
snprintf(dell_diags, sizeof(dell_diags), "---- ----");
else if (postcard_written[1] == 1)
snprintf(dell_diags, sizeof(dell_diags), "%s ----", postcard_diags);
else
snprintf(dell_diags, sizeof(dell_diags), "%s %s", postcard_diags, postcard_prev_diags);
if (!postcard_written[0])
snprintf(postcard_str, sizeof(postcard_str), "POST: -- -- %s", dell_diags);
else if (postcard_written[0] == 1)
snprintf(postcard_str, sizeof(postcard_str), "POST: %02X -- %s", postcard_codes[0], dell_diags);
else
snprintf(postcard_str, sizeof(postcard_str), "POST: %02X %02X %s", postcard_codes[0], postcard_prev_codes[0], dell_diags);
} else {
if (!postcard_written[0])
snprintf(postcard_str, sizeof(postcard_str), "POST: -- --");
@@ -122,6 +140,9 @@ postcard_reset(void)
memset(postcard_codes, 0x00, POSTCARDS_NUM * sizeof(uint8_t));
memset(postcard_prev_codes, 0x00, POSTCARDS_NUM * sizeof(uint8_t));
memset(postcard_diags, 0x00, 5 * sizeof(char));
memset(postcard_prev_diags, 0x00, 5 * sizeof(char));
postcard_setui();
}
@@ -140,6 +161,35 @@ postcard_write(uint16_t port, uint8_t val, UNUSED(void *priv))
postcard_setui();
}
static int
postcard_cmp_diags(uint32_t val)
{
int ret = 0;
char *pv = (char *) &val;
for (int i = 0; i < 4; i++)
ret = ret || (pv[i] != postcard_diags[3 - i]);
return ret;
}
static void
postcard_writel(uint16_t port, uint32_t val, UNUSED(void *priv))
{
char *pv = (char *) &val;
if (postcard_written[1] && !postcard_cmp_diags(val))
return;
*(uint32_t *) postcard_prev_diags = *(uint32_t *) postcard_diags;
for (int i = 0; i < 4; i++)
postcard_diags[i] = pv[3 - i];
if (postcard_written[1] < 2)
postcard_written[1]++;
postcard_setui();
}
static void *
postcard_init(UNUSED(const device_t *info))
{
@@ -173,6 +223,10 @@ postcard_init(UNUSED(const device_t *info))
io_sethandler(postcard_port, postcard_ports_num,
NULL, NULL, NULL, postcard_write, NULL, NULL, NULL);
if (strstr(machines[machine].name, " Dell "))
io_sethandler(0x00e0, 0x0001,
NULL, NULL, NULL, NULL, NULL, postcard_writel, NULL);
return postcard_write;
}

View File

@@ -856,7 +856,7 @@ dma16_read(uint16_t addr, UNUSED(void *priv))
break;
}
dma_log("dma16_read(%08X) = %02X\n", port, ret);
dma_log("dma16_read(%08X) = %02X\n", addr, ret);
return ret;
}

View File

@@ -377,6 +377,15 @@ fdc_set_power_down(fdc_t *fdc, uint8_t power_down)
fdc->power_down = power_down;
}
void
fdc_toggle_flag(fdc_t *fdc, int flag, int on)
{
if (on)
fdc->flags |= flag;
else
fdc->flags &= ~flag;
}
void
fdc_update_max_track(fdc_t *fdc, int max_track)
{
@@ -1484,7 +1493,7 @@ fdc_read(uint16_t addr, void *priv)
fdc->step = 0;
break;
default:
ret = 0xFF;
ret = 0xff;
}
fdc_log("[%04X:%08X] Read FDC %04X %02X [%i:%02X]\n", CS, cpu_state.pc, addr, ret, drive, fdc->dor & (0x10 << drive));
return ret;
@@ -2235,9 +2244,13 @@ fdc_set_base(fdc_t *fdc, int base)
{
int super_io = (fdc->flags & FDC_FLAG_SUPERIO);
if (base == 0x0000) {
fdc->base_address = base;
return;
}
if (fdc->flags & FDC_FLAG_NSC) {
io_sethandler(base + 2, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 4, 0x0002, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 2, 0x0004, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {
@@ -2266,10 +2279,12 @@ fdc_remove(fdc_t *fdc)
{
int super_io = (fdc->flags & FDC_FLAG_SUPERIO);
if (fdc->base_address == 0x0000)
return;
fdc_log("FDC Removed (%04X)\n", fdc->base_address);
if (fdc->flags & FDC_FLAG_NSC) {
io_removehandler(fdc->base_address + 2, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 4, 0x0002, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 2, 0x0004, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {

View File

@@ -183,6 +183,7 @@ extern uint8_t fdc_get_densel_polarity(fdc_t *fdc);
extern void fdc_update_densel_force(fdc_t *fdc, int densel_force);
extern void fdc_update_drvrate(fdc_t *fdc, int drive, int drvrate);
extern void fdc_update_drv2en(fdc_t *fdc, int drv2en);
extern void fdc_toggle_flag(fdc_t *fdc, int flag, int on);
extern void fdc_noidam(fdc_t *fdc);
extern void fdc_nosector(fdc_t *fdc);

View File

@@ -289,7 +289,9 @@ 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);
extern void kbc_at_handler(int set, void *priv);
extern void kbc_at_port_handler(int num, int set, uint16_t port, void *priv);
extern void kbc_at_handler(int set, uint16_t port, void *priv);
extern void kbc_at_set_irq(int num, uint16_t irq, void *priv);
extern void kbc_at_dev_queue_reset(atkbc_dev_t *dev, uint8_t reset_main);
extern uint8_t kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main);

View File

@@ -752,6 +752,7 @@ extern int machine_at_gw2kte_init(const machine_t *);
extern int machine_at_ma23c_init(const machine_t *);
extern int machine_at_nupro592_init(const machine_t *);
extern int machine_at_tx97_init(const machine_t *);
extern int machine_at_optiplex_gn_init(const machine_t *);
#ifdef USE_AN430TX
extern int machine_at_an430tx_init(const machine_t *);
#endif /* USE_AN430TX */

View File

@@ -92,13 +92,23 @@ extern const device_t pc87332_398_ide_device;
extern const device_t pc87332_398_ide_sec_device;
extern const device_t pc87332_398_ide_fdcon_device;
#define PCX7307_PC87307 0x00c0
#define PCX7307_PC97307 0x00cf
#define PC87309_PC87309 0x00e0
#define PCX730X_CHIP_ID 0x00ff
#define PCX730X_AMI 0x0200 /* AMI '5' Megakey KBC firmware. */
#define PCX730X_PHOENIX_42 0x0500 /* Phoenix Multikey/42 1.37 KBC firmware. */
#define PCX730X_PHOENIX_42I 0x0700 /* Phoenix Multikey/42i 4.16 KBC firmware. */
#define PCX730X_KBC 0x0f00
#define PCX730X_15C 0x2000
extern const device_t pc87307_device;
extern const device_t pc87307_15c_device;
extern const device_t pc87307_both_device;
extern const device_t pc97307_device;
extern const device_t pc87309_device;
extern const device_t pc87309_15c_device;
/* LG Prime */
extern const device_t prime3b_device;

View File

@@ -229,9 +229,9 @@ void
lpt_port_setup(int i, uint16_t port)
{
if (lpt_ports[i].enabled) {
if (lpt_ports[i].addr != 0xffff)
if ((lpt_ports[i].addr != 0xffff) && (lpt_ports[i].addr != 0x0000))
io_removehandler(lpt_ports[i].addr, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
if (port != 0xffff)
if ((port != 0xffff) && (port != 0x0000))
io_sethandler(port, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
lpt_ports[i].addr = port;
} else

View File

@@ -396,7 +396,7 @@ machine_at_pb410a_init(const machine_t *model)
device_add(&phoenix_486_jumper_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&ht216_32_pb410a_device);
device_add(machine_get_vid_device(machine));
return ret;
}

View File

@@ -584,8 +584,7 @@ machine_at_s1846_init(const machine_t *model)
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&pc87309_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add_params(&pc87309_device, (void *) (PCX730X_AMI | PC87309_PC87309));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);

View File

@@ -140,8 +140,7 @@ machine_at_fw6400gx_init(const machine_t *model)
device_add(&i440gx_device);
device_add(&piix4e_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&pc87309_15c_device);
device_add_params(&pc87309_device, (void *) (PCX730X_15C | PCX730X_AMI | PC87309_PC87309));
device_add(ics9xxx_get(ICS9250_08));
device_add(&sst_flash_29ee020_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 512);

View File

@@ -969,6 +969,42 @@ machine_at_tx97_init(const machine_t *model)
return ret;
}
int
machine_at_optiplex_gn_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/optiplex_gn/DELL.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, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 2, 1);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 1, 3, 4);
pci_register_slot(0x10, PCI_CARD_VIDEO, 4, 0, 0, 0); /* Trio64V2/GX, temporarily Trio64V2/DX is given */
pci_register_slot(0x11, PCI_CARD_NETWORK, 4, 0, 0, 0); /* 3C905, not yet emulated */
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4);
if (gfxcard[0] == VID_INTERNAL)
device_add(machine_get_vid_device(machine));
if ((sound_card_current[0] == SOUND_INTERNAL) && machine_get_snd_device(machine)->available())
machine_snd = device_add(machine_get_snd_device(machine));
device_add(&i430tx_device);
device_add(&piix4_device);
device_add_params(&pc87307_device, (void *) (PCX730X_PHOENIX_42 | PCX7307_PC87307));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
return ret;
}
#ifdef USE_AN430TX
int
machine_at_an430tx_init(const machine_t *model)
@@ -1006,8 +1042,7 @@ machine_at_an430tx_init(const machine_t *model)
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&i430tx_device);
device_add(&piix4_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&pc87307_both_device);
device_add_params(&pc87307_device, (void *) (PCX730X_PHOENIX_42I | PCX7307_PC97307));
device_add(&intel_flash_bxt_ami_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 128);

View File

@@ -250,8 +250,7 @@ machine_at_vs440fx_init(const machine_t *model)
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i440fx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_intel_ami_pci_device);
device_add(&pc87307_device);
device_add_params(&pc87307_device, (void *) (PCX730X_AMI | PCX7307_PC87307));
device_add(&intel_flash_bxt_ami_device);
@@ -287,8 +286,7 @@ machine_at_gw2kvenus_init(const machine_t *model)
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i440fx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_intel_ami_pci_device);
device_add(&pc87307_device);
device_add_params(&pc87307_device, (void *) (PCX730X_AMI | PCX7307_PC87307));
device_add(&intel_flash_bxt_ami_device);
@@ -324,8 +322,7 @@ machine_at_ap440fx_init(const machine_t *model)
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4);
device_add(&i440fx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&pc87307_device);
device_add_params(&pc87307_device, (void *) (PCX730X_AMI | PCX7307_PC87307));
device_add(&intel_flash_bxt_ami_device);
if (sound_card_current[0] == SOUND_INTERNAL)

View File

@@ -6647,7 +6647,7 @@ const machine_t machines[] = {
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.vid_device = &ht216_32_pb410a_device,
.snd_device = NULL,
.net_device = NULL
},
@@ -13143,6 +13143,56 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/*
According to Dell specifications, it can have either National Semiconductor
PC87307 or PC87309 Super I/O. All known instances have the former, although
other similar Dells of the era have pinouts for accompanying either so this
likely also does.
The KBC is either an AMI '5' MegaKey, Phoenix MultiKey/42 1.37, or Phoenix
MultiKey/42i 4.16.
*/
{
.name = "[i430TX] Dell OptiPlex GN+",
.internal_name = "optiplex_gn",
.type = MACHINE_TYPE_SOCKET7,
.chipset = MACHINE_CHIPSET_INTEL_430TX,
.init = machine_at_optiplex_gn_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 = 50000000,
.max_bus = 66666667,
.min_voltage = 2500,
.max_voltage = 3520,
.min_multi = 1.5,
.max_multi = 3.5
},
.bus_flags = MACHINE_PS2_PCI,
/* Video: S3 86C785 (Trio64V2/GX), ethernet: 3C905. */
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND,
.ram = {
.min = 8192,
.max = 262144,
.step = 8192
},
.nvrmask = 255,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
/* Stop-gap measure until the Trio64V2/GX is emulated, as both use the same VBIOS. */
.vid_device = &s3_trio64v2_dx_onboard_pci_device,
.snd_device = &sb_vibra16xv_onboard_device,
.net_device = NULL
},
/* [TEST] Has AMI Megakey '5' KBC firmware on the SM(S)C FDC37C67x Super I/O chip. */
{
.name = "[i430TX] Gateway E-1000",

View File

@@ -1107,9 +1107,10 @@ nvr_at_init(const device_t *info)
case 1: /* standard AT */
case 5: /* AMI WinBIOS 1994 */
case 6: /* AMI BIOS 1995 */
if ((info->local & 0x1f) == 0x11)
if ((info->local & 0x1f) == 0x11) {
local->flags |= FLAG_PIIX4;
else {
local->def = 0x00;
} else {
local->def = 0x00;
if ((info->local & 0x1f) == 0x15)
local->flags |= FLAG_AMI_1994_HACK;

View File

@@ -61,6 +61,11 @@ struct mouseinputdata {
static mouseinputdata mousedata;
extern MainWindow *main_window;
#ifdef Q_OS_WINDOWS
HWND rw_hwnd;
#endif
RendererStack::RendererStack(QWidget *parent, int monitor_index)
: QStackedWidget(parent)
, ui(new Ui::RendererStack)
@@ -251,7 +256,9 @@ RendererStack::mouseMoveEvent(QMouseEvent *event)
leaveEvent((QEvent *) event);
ignoreNextMouseEvent--;
}
#if !defined _WIN32
QCursor::setPos(mapToGlobal(QPoint(width() / 2, height() / 2)));
#endif
ignoreNextMouseEvent = 2;
oldPos = event->pos();
#endif
@@ -405,8 +412,15 @@ RendererStack::createRenderer(Renderer renderer)
}
#endif
}
if (current.get() == nullptr)
if (current.get() == nullptr) {
#ifdef Q_OS_WINDOWS
rw_hwnd = NULL;
#endif
return;
}
#ifdef Q_OS_WINDOWS
rw_hwnd = (HWND) this->winId();
#endif
current->setFocusPolicy(Qt::NoFocus);
current->setFocusProxy(this);
current->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
@@ -649,6 +663,14 @@ RendererStack::setFocusRenderer()
void
RendererStack::onResize(int width, int height)
{
#ifdef Q_OS_WINDOWS
if (mouse_capture) {
RECT rect;
if (GetWindowRect((HWND)this->winId(), &rect)) {
ClipCursor(&rect);
}
}
#endif
if (rendererWindow) {
rendererWindow->r_monitor_index = m_monitor_index;
rendererWindow->onResize(width, height);

View File

@@ -23,6 +23,7 @@
#include <QMessageBox>
#include <QStatusBar>
#include <QApplication>
#include "qt_mainwindow.hpp"
#include "qt_machinestatus.hpp"
@@ -122,6 +123,10 @@ plat_resize(int w, int h, int monitor_index)
main_window->resizeContents(w, h);
}
#if defined _WIN32
extern HWND rw_hwnd;
#endif
void
plat_mouse_capture(int on)
{
@@ -129,6 +134,26 @@ plat_mouse_capture(int on)
return;
main_window->setMouseCapture(on > 0 ? true : false);
#if defined _WIN32
if (on) {
QCursor cursor(Qt::BlankCursor);
QApplication::setOverrideCursor(cursor);
QApplication::changeOverrideCursor(cursor);
RECT rect;
GetWindowRect(rw_hwnd, &rect);
ClipCursor(&rect);
} else {
ClipCursor(NULL);
QApplication::restoreOverrideCursor();
}
#endif
}
int

View File

@@ -395,7 +395,7 @@ WindowsRawInputFilter::mouse_handle(PRAWINPUT raw)
mouse_scale(delta_x, delta_y);
HWND wnd = (HWND)window->winId();
/* HWND wnd = (HWND)window->winId();
RECT rect;
@@ -404,5 +404,5 @@ WindowsRawInputFilter::mouse_handle(PRAWINPUT raw)
int left = rect.left + (rect.right - rect.left) / 2;
int top = rect.top + (rect.bottom - rect.top) / 2;
SetCursorPos(left, top);
SetCursorPos(left, top); */
}

View File

@@ -894,7 +894,7 @@ fdc37c93x_kbc_handler(fdc37c93x_t *dev)
dev->kbc_base = local_enable ? 0x0060 : 0x0000;
if (dev->kbc_base != old_base)
kbc_at_handler(local_enable, dev->kbc);
kbc_at_handler(local_enable, dev->kbc_base, dev->kbc);
}
static void

File diff suppressed because it is too large Load Diff

View File

@@ -8,60 +8,97 @@
*
* Emulation of the NatSemi PC87309 Super I/O chip.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2020 Miran Grca.
* Copyright 2020-2025 Miran Grca.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/lpt.h>
#include <86box/machine.h>
#include <86box/mem.h>
#include <86box/nvr.h>
#include <86box/pci.h>
#include <86box/rom.h>
#include <86box/serial.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/keyboard.h>
#include <86box/sio.h>
#include <86box/plat_fallthrough.h>
#include "cpu.h"
typedef struct pc87309_t {
uint8_t id;
uint8_t baddr;
uint8_t pm_idx;
uint8_t regs[48];
uint8_t ld_regs[256][208];
uint8_t pm[8];
uint8_t baddr;
uint16_t superio_base;
uint16_t pm_base;
int cur_reg;
void *kbc;
fdc_t *fdc;
serial_t *uart[2];
} pc87309_t;
enum {
LD_FDC = 0,
LD_LPT,
LD_UART2,
LD_UART1,
LD_PM,
LD_KBD,
LD_MOUSE
} pc87309_ld_t;
#define LD_MIN LD_FDC
#define LD_MAX LD_MOUSE
static void fdc_handler(pc87309_t *dev);
static void lpt1_handler(pc87309_t *dev);
static void serial_handler(pc87309_t *dev, int uart);
static void kbc_handler(pc87309_t *dev);
static void pc87309_write(uint16_t port, uint8_t val, void *priv);
static uint8_t pc87309_read(uint16_t port, void *priv);
#ifdef ENABLE_PC87309_LOG
int pc87309_do_log = ENABLE_PC87309_LOG;
static void
pc87309_log(const char *fmt, ...)
{
va_list ap;
if (pc87309_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define pc87309_log(fmt, ...)
#endif
static void
pc87309_pm_write(uint16_t port, uint8_t val, void *priv)
{
pc87309_t *dev = (pc87309_t *) priv;
if (port & 1) {
if (port & 1)
dev->pm[dev->pm_idx] = val;
else {
dev->pm_idx = val & 0x07;
switch (dev->pm_idx) {
case 0x00:
@@ -74,8 +111,7 @@ pc87309_pm_write(uint16_t port, uint8_t val, void *priv)
default:
break;
}
} else
dev->pm_idx = val & 0x07;
}
}
uint8_t
@@ -109,43 +145,48 @@ pc87309_pm_init(pc87309_t *dev, uint16_t addr)
}
static void
superio_handler(pc87309_t *dev)
kbc_handler(pc87309_t *dev)
{
io_removehandler(0x15c, 0x0002,
pc87309_read, NULL, NULL, pc87309_write, NULL, NULL, dev);
io_removehandler(0x02e, 0x0002,
pc87309_read, NULL, NULL, pc87309_write, NULL, NULL, dev);
uint8_t active = (dev->ld_regs[LD_KBD][0x00] & 0x01) &&
(dev->pm[0x00] & 0x01);
uint8_t active_2 = dev->ld_regs[LD_MOUSE][0x00] & 0x01;
uint8_t irq = (dev->ld_regs[LD_KBD][0x40] & 0x0f);
uint8_t irq_2 = (dev->ld_regs[LD_MOUSE][0x40] & 0x0f);
uint16_t addr = (dev->ld_regs[LD_KBD][0x30] << 8) |
dev->ld_regs[LD_KBD][0x31];
uint16_t addr_2 = (dev->ld_regs[LD_KBD][0x32] << 8) |
dev->ld_regs[LD_KBD][0x33];
switch (dev->regs[0x21] & 0x0b) {
case 0x02:
case 0x08:
case 0x0a:
io_sethandler(0x15c, 0x0002,
pc87309_read, NULL, NULL, pc87309_write, NULL, NULL, dev);
break;
case 0x03:
case 0x09:
case 0x0b:
io_sethandler(0x02e, 0x0002,
pc87309_read, NULL, NULL, pc87309_write, NULL, NULL, dev);
break;
pc87309_log("%02X, %02X, %02X, %02X, %04X, %04X\n",
active, active_2, irq, irq_2, addr, addr_2);
if (addr <= 0xfff8) {
pc87309_log("Enabling KBC #1 on %04X...\n", addr);
kbc_at_port_handler(0, active, addr, dev->kbc);
}
if (addr_2 <= 0xfff8) {
pc87309_log("Enabling KBC #2 on %04X...\n", addr_2);
kbc_at_port_handler(1, active, addr_2, dev->kbc);
}
kbc_at_set_irq(0, active ? irq : 0xffff, dev->kbc);
kbc_at_set_irq(1, (active && active_2) ? irq_2 : 0xffff, dev->kbc);
}
static void
fdc_handler(pc87309_t *dev)
{
uint8_t irq;
uint8_t active;
uint16_t addr;
fdc_remove(dev->fdc);
active = (dev->ld_regs[0x00][0x00] & 0x01) && (dev->pm[0x00] & 0x08);
addr = ((dev->ld_regs[0x00][0x30] << 8) | dev->ld_regs[0x00][0x31]) - 0x0002;
irq = (dev->ld_regs[0x00][0x40] & 0x0f);
uint8_t active = (dev->ld_regs[LD_FDC][0x00] & 0x01) &&
(dev->pm[0x00] & 0x08);
uint8_t irq = (dev->ld_regs[LD_FDC][0x40] & 0x0f);
uint16_t addr = ((dev->ld_regs[LD_FDC][0x30] << 8) |
dev->ld_regs[LD_FDC][0x31]) & 0xfff8;
if (active) {
if (active && (addr <= 0xfff8)) {
pc87309_log("Enabling FDC on %04X, IRQ %i...\n", addr, irq);
fdc_set_base(dev->fdc, addr);
fdc_set_irq(dev->fdc, irq);
}
@@ -154,222 +195,351 @@ fdc_handler(pc87309_t *dev)
static void
lpt1_handler(pc87309_t *dev)
{
uint8_t irq;
uint8_t active;
uint16_t addr;
uint8_t active = (dev->ld_regs[LD_LPT][0x00] & 0x01) &&
(dev->pm[0x00] & 0x10);
uint8_t irq = (dev->ld_regs[LD_LPT][0x40] & 0x0f);
uint16_t addr = (dev->ld_regs[LD_LPT][0x30] << 8) |
dev->ld_regs[LD_LPT][0x31];
lpt1_remove();
active = (dev->ld_regs[0x01][0x00] & 0x01) && (dev->pm[0x00] & 0x10);
addr = (dev->ld_regs[0x01][0x30] << 8) | dev->ld_regs[0x01][0x31];
irq = (dev->ld_regs[0x01][0x40] & 0x0f);
if (active) {
if (active && (addr <= 0xfffc)) {
pc87309_log("Enabling LPT1 on %04X...\n", addr);
lpt1_setup(addr);
lpt1_irq(irq);
}
} else
lpt1_setup(0xffff);
lpt1_irq(irq);
}
static void
serial_handler(pc87309_t *dev, int uart)
{
uint8_t irq;
uint8_t active;
uint16_t addr;
serial_remove(dev->uart[uart]);
active = (dev->ld_regs[0x03 - uart][0x00] & 0x01) && (dev->pm[0x00] & (1 << (6 - uart)));
addr = (dev->ld_regs[0x03 - uart][0x30] << 8) | dev->ld_regs[0x03 - uart][0x31];
irq = (dev->ld_regs[0x03 - uart][0x40] & 0x0f);
uint8_t active = (dev->ld_regs[LD_UART1 - uart][0x00] & 0x01) &&
(dev->pm[0x00] & (1 << (6 - uart)));
uint8_t irq = (dev->ld_regs[LD_UART1 - uart][0x40] & 0x0f);
uint16_t addr = (dev->ld_regs[LD_UART1 - uart][0x30] << 8) |
dev->ld_regs[LD_UART1 - uart][0x31];
if (active)
if (active && (addr <= 0xfff8)) {
pc87309_log("Enabling COM%i on %04X...\n", uart + 1, addr);
serial_setup(dev->uart[uart], addr, irq);
} else
serial_setup(dev->uart[uart], 0x0000, irq);
}
static void
pm_handler(pc87309_t *dev)
{
uint8_t active;
uint16_t addr;
pc87309_pm_remove(dev);
active = (dev->ld_regs[0x04][0x00] & 0x01);
addr = (dev->ld_regs[0x04][0x30] << 8) | dev->ld_regs[0x04][0x31];
uint8_t active = (dev->ld_regs[LD_PM][0x00] & 0x01);
uint16_t addr = (dev->ld_regs[LD_PM][0x30] << 8) |
dev->ld_regs[LD_PM][0x31];
if (active)
if (active) {
pc87309_log("Enabling power management on %04X...\n", addr);
pc87309_pm_init(dev, addr);
}
}
static void
superio_handler(pc87309_t *dev)
{
if (dev->superio_base != 0x0000)
io_removehandler(dev->superio_base, 0x0002,
pc87309_read, NULL, NULL,
pc87309_write, NULL, NULL, dev);
switch (dev->regs[0x21] & 0x0b) {
default:
dev->superio_base = 0x0000;
break;
case 0x02:
case 0x08: case 0x0a:
dev->superio_base = 0x015c;
break;
case 0x03:
case 0x09: case 0x0b:
dev->superio_base = 0x002e;
break;
}
if (dev->superio_base != 0x0000) {
pc87309_log("Enabling Super I/O on %04X...\n", dev->superio_base);
io_sethandler(dev->superio_base, 0x0002,
pc87309_read, NULL, NULL,
pc87309_write, NULL, NULL, dev);
}
}
static void
pc87309_write(uint16_t port, uint8_t val, void *priv)
{
pc87309_t *dev = (pc87309_t *) priv;
uint8_t index;
index = (port & 1) ? 0 : 1;
pc87309_t *dev = (pc87309_t *) priv;
uint8_t ld = dev->regs[0x07];
uint8_t reg = dev->cur_reg - 0x30;
uint8_t index = (port & 1) ? 0 : 1;
uint8_t old = dev->regs[dev->cur_reg];
if (index) {
dev->cur_reg = val;
return;
} else {
#ifdef ENABLE_PC87309_LOG
if (dev->cur_reg >= 0x30)
pc87309_log("[%04X:%08X] [W] (%04X) %02X:%02X = %02X\n",
CS, cpu_state.pc, port, ld, dev->cur_reg, val);
else
pc87309_log("[%04X:%08X] [W] (%04X) %02X = %02X\n",
CS, cpu_state.pc, port, dev->cur_reg, val);
#endif
switch (dev->cur_reg) {
case 0x00:
case 0x02:
case 0x03:
case 0x06:
case 0x07:
case 0x02: case 0x03:
case 0x06: case 0x07:
dev->regs[dev->cur_reg] = val;
break;
case 0x21:
dev->regs[dev->cur_reg] = val;
fdc_toggle_flag(dev->fdc, FDC_FLAG_PS2_MCA, !(val & 0x04));
superio_handler(dev);
break;
case 0x22:
dev->regs[dev->cur_reg] = val & 0x7f;
dev->regs[dev->cur_reg] = val;
break;
default:
if (dev->cur_reg >= 0x30) {
if ((dev->regs[0x07] != 0x06) || !(dev->regs[0x21] & 0x10))
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val;
}
if (dev->cur_reg >= 0x30)
old = dev->ld_regs[ld][reg];
break;
}
}
switch (dev->cur_reg) {
case 0x30:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x01;
switch (dev->regs[0x07]) {
case 0x00:
switch (ld) {
default:
break;
case LD_KBD: case LD_MOUSE:
dev->ld_regs[ld][reg] = val;
kbc_handler(dev);
break;
case LD_FDC:
dev->ld_regs[ld][reg] = val;
fdc_handler(dev);
break;
case 0x01:
case LD_LPT:
dev->ld_regs[ld][reg] = val;
lpt1_handler(dev);
break;
case 0x02:
case LD_UART2:
dev->ld_regs[ld][reg] = val;
serial_handler(dev, 1);
break;
case 0x03:
case LD_UART1:
dev->ld_regs[ld][reg] = val;
serial_handler(dev, 0);
break;
case 0x04:
case LD_PM:
dev->ld_regs[ld][reg] = val;
pm_handler(dev);
break;
default:
break;
}
break;
/* I/O Range Check. */
case 0x31:
switch (ld) {
default:
break;
case LD_MIN ... LD_MAX:
if (ld != LD_MOUSE)
dev->ld_regs[ld][reg] = val;
break;
}
break;
/* Base Address 0 MSB. */
case 0x60:
case 0x62:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x07;
if (dev->cur_reg == 0x62)
break;
switch (dev->regs[0x07]) {
case 0x00:
switch (ld) {
default:
break;
case LD_KBD:
dev->ld_regs[ld][reg] = val;
kbc_handler(dev);
break;
case LD_FDC:
dev->ld_regs[ld][reg] = val;
fdc_handler(dev);
break;
case 0x01:
case LD_LPT:
dev->ld_regs[ld][reg] = (old & 0xfc) | (val & 0x03);
lpt1_handler(dev);
break;
case 0x02:
case LD_UART2:
dev->ld_regs[ld][reg] = val;
serial_handler(dev, 1);
break;
case 0x03:
case LD_UART1:
dev->ld_regs[ld][reg] = val;
serial_handler(dev, 0);
break;
case 0x04:
case LD_PM:
dev->ld_regs[ld][reg] = val;
pm_handler(dev);
break;
default:
break;
}
break;
case 0x63:
if (dev->regs[0x07] == 0x06)
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = (val & 0xf8) | 0x04;
break;
/* Base Address 0 LSB. */
case 0x61:
switch (dev->regs[0x07]) {
case 0x00:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = (val & 0xfa) | 0x02;
switch (ld) {
default:
break;
case LD_KBD:
dev->ld_regs[ld][reg] = (old & 0x04) | (val & 0xfb);
kbc_handler(dev);
break;
case LD_FDC:
dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8);
fdc_handler(dev);
break;
case 0x01:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfc;
case LD_LPT:
dev->ld_regs[ld][reg] = (old & 0x03) | (val & 0xfc);
lpt1_handler(dev);
break;
case 0x02:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8;
case LD_UART2:
dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8);
serial_handler(dev, 1);
break;
case 0x03:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8;
case LD_UART1:
dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8);
serial_handler(dev, 0);
break;
case 0x04:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfe;
case LD_PM:
dev->ld_regs[ld][reg] = (old & 0x01) | (val & 0xfe);
pm_handler(dev);
break;
case 0x06:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8;
break;
default:
break;
}
break;
/* Base Address 1 MSB (undocumented for Logical Device 7). */
case 0x62:
switch (ld) {
default:
break;
case LD_KBD:
dev->ld_regs[ld][reg] = val;
kbc_handler(dev);
break;
}
break;
/* Base Address 1 LSB (undocumented for Logical Device 7). */
case 0x63:
switch (ld) {
default:
break;
case LD_KBD:
dev->ld_regs[ld][reg] = (old & 0x04) | (val & 0xfb);
kbc_handler(dev);
break;
}
break;
/* Interrupt Select. */
case 0x70:
case 0x74:
case 0x75:
switch (dev->regs[0x07]) {
case 0x00:
switch (ld) {
default:
break;
case LD_KBD: case LD_MOUSE:
dev->ld_regs[ld][reg] = val;
kbc_handler(dev);
break;
case LD_FDC:
dev->ld_regs[ld][reg] = val;
fdc_handler(dev);
break;
case 0x01:
case LD_LPT:
dev->ld_regs[ld][reg] = val;
lpt1_handler(dev);
break;
case 0x02:
case LD_UART2:
dev->ld_regs[ld][reg] = val;
serial_handler(dev, 1);
break;
case 0x03:
case LD_UART1:
dev->ld_regs[ld][reg] = val;
serial_handler(dev, 0);
break;
case 0x04:
pm_handler(dev);
break;
default:
break;
}
break;
/* Interrupt Type. */
case 0x71:
switch (ld) {
default:
break;
case LD_MIN ... LD_MAX:
if ((ld == LD_KBD) || (ld == LD_MOUSE))
dev->ld_regs[ld][reg] = (old & 0xfc) | (val & 0x03);
else
dev->ld_regs[ld][reg] = (old & 0xfd) | (val & 0x02);
break;
}
break;
/* DMA Channel Select 0. */
case 0x74:
switch (ld) {
default:
break;
case LD_FDC:
dev->ld_regs[ld][reg] = val;
fdc_handler(dev);
break;
case LD_LPT:
dev->ld_regs[ld][reg] = val;
lpt1_handler(dev);
break;
case LD_UART2:
dev->ld_regs[ld][reg] = val;
break;
}
break;
/* DMA Channel Select 1. */
case 0x75:
switch (ld) {
default:
break;
case LD_UART2:
dev->ld_regs[ld][reg] = val;
break;
}
break;
/* Configuration Register 0. */
case 0xf0:
switch (dev->regs[0x07]) {
case 0x00:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xe1;
switch (ld) {
default:
break;
case LD_KBD:
dev->ld_regs[ld][reg] = val;
break;
case LD_FDC:
dev->ld_regs[ld][reg] = val;
fdc_update_densel_polarity(dev->fdc, (val & 0x20) ? 1 : 0);
fdc_update_enh_mode(dev->fdc, (val & 0x40) ? 1 : 0);
break;
case 0x01:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf3;
case LD_LPT:
dev->ld_regs[ld][reg] = val;
lpt1_handler(dev);
break;
case 0x02:
case 0x03:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x87;
break;
case 0x06:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xc1;
break;
default:
case LD_UART2: case LD_UART1:
dev->ld_regs[ld][reg] = val;
break;
}
break;
/* Configuration Register 1. */
case 0xf1:
if (dev->regs[0x07] == 0x00)
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x0f;
switch (ld) {
default:
break;
case LD_FDC:
dev->ld_regs[ld][reg] = val;
break;
}
break;
default:
@@ -377,30 +547,44 @@ pc87309_write(uint16_t port, uint8_t val, void *priv)
}
}
uint8_t
static uint8_t
pc87309_read(uint16_t port, void *priv)
{
const pc87309_t *dev = (pc87309_t *) priv;
uint8_t ret = 0xff;
uint8_t index;
index = (port & 1) ? 0 : 1;
const pc87309_t *dev = (pc87309_t *) priv;
uint8_t ld = dev->regs[0x07];
uint8_t reg = dev->cur_reg - 0x30;
uint8_t index = (port & 1) ? 0 : 1;
uint8_t ret = 0xff;
if (index)
ret = dev->cur_reg & 0x1f;
ret = dev->cur_reg;
else {
if (dev->cur_reg >= 0x30)
ret = dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30];
ret = dev->ld_regs[ld][reg];
/* Write-only registers. */
else if ((dev->cur_reg == 0x00) ||
(dev->cur_reg == 0x02) || (dev->cur_reg == 0x03))
ret = 0x00;
else
ret = dev->regs[dev->cur_reg];
#ifdef ENABLE_PC87309_LOG
if (dev->cur_reg >= 0x30)
pc87309_log("[%04X:%08X] [R] (%04X) %02X:%02X = %02X\n",
CS, cpu_state.pc, port, ld, dev->cur_reg, ret);
else
pc87309_log("[%04X:%08X] [R] (%04X) %02X = %02X\n",
CS, cpu_state.pc, port, dev->cur_reg, ret);
#endif
}
return ret;
}
void
pc87309_reset(pc87309_t *dev)
pc87309_reset(void *priv)
{
pc87309_t *dev = (pc87309_t *) priv;
memset(dev->regs, 0x00, 0x30);
for (uint16_t i = 0; i < 256; i++)
memset(dev->ld_regs[i], 0x00, 0xd0);
@@ -409,65 +593,56 @@ pc87309_reset(pc87309_t *dev)
dev->regs[0x20] = dev->id;
dev->regs[0x21] = 0x04 | dev->baddr;
dev->ld_regs[0x00][0x01] = 0x01;
dev->ld_regs[0x00][0x30] = 0x03;
dev->ld_regs[0x00][0x31] = 0xf2;
dev->ld_regs[0x00][0x40] = 0x06;
dev->ld_regs[0x00][0x41] = 0x03;
dev->ld_regs[0x00][0x44] = 0x02;
dev->ld_regs[0x00][0x45] = 0x04;
dev->ld_regs[0x00][0xc0] = 0x02;
dev->ld_regs[LD_KBD ][0x00] = 0x01;
dev->ld_regs[LD_KBD ][0x31] = 0x60;
dev->ld_regs[LD_KBD ][0x33] = 0x64;
dev->ld_regs[LD_KBD ][0x40] = 0x01;
dev->ld_regs[LD_KBD ][0x41] = 0x02;
dev->ld_regs[LD_KBD ][0x44] = 0x04;
dev->ld_regs[LD_KBD ][0x45] = 0x04;
dev->ld_regs[LD_KBD ][0xc0] = 0x40;
dev->ld_regs[0x01][0x30] = 0x02;
dev->ld_regs[0x01][0x31] = 0x78;
dev->ld_regs[0x01][0x40] = 0x07;
dev->ld_regs[0x01][0x44] = 0x04;
dev->ld_regs[0x01][0x45] = 0x04;
dev->ld_regs[0x01][0xc0] = 0xf2;
dev->ld_regs[LD_MOUSE][0x40] = 0x0c;
dev->ld_regs[LD_MOUSE][0x41] = 0x02;
dev->ld_regs[LD_MOUSE][0x44] = 0x04;
dev->ld_regs[LD_MOUSE][0x45] = 0x04;
dev->ld_regs[0x02][0x30] = 0x02;
dev->ld_regs[0x02][0x31] = 0xf8;
dev->ld_regs[0x02][0x40] = 0x03;
dev->ld_regs[0x02][0x41] = 0x03;
dev->ld_regs[0x02][0x44] = 0x04;
dev->ld_regs[0x02][0x45] = 0x04;
dev->ld_regs[0x02][0xc0] = 0x02;
dev->ld_regs[LD_FDC ][0x01] = 0x01;
dev->ld_regs[LD_FDC ][0x30] = 0x03;
dev->ld_regs[LD_FDC ][0x31] = 0xf0;
dev->ld_regs[LD_FDC ][0x32] = 0x03;
dev->ld_regs[LD_FDC ][0x33] = 0xf7;
dev->ld_regs[LD_FDC ][0x40] = 0x06;
dev->ld_regs[LD_FDC ][0x41] = 0x03;
dev->ld_regs[LD_FDC ][0x44] = 0x02;
dev->ld_regs[LD_FDC ][0x45] = 0x04;
dev->ld_regs[LD_FDC ][0xc0] = 0x02;
dev->ld_regs[0x03][0x30] = 0x03;
dev->ld_regs[0x03][0x31] = 0xf8;
dev->ld_regs[0x03][0x40] = 0x04;
dev->ld_regs[0x03][0x41] = 0x03;
dev->ld_regs[0x03][0x44] = 0x04;
dev->ld_regs[0x03][0x45] = 0x04;
dev->ld_regs[0x03][0xc0] = 0x02;
dev->ld_regs[LD_LPT ][0x30] = 0x02;
dev->ld_regs[LD_LPT ][0x31] = 0x78;
dev->ld_regs[LD_LPT ][0x40] = 0x07;
dev->ld_regs[LD_LPT ][0x44] = 0x04;
dev->ld_regs[LD_LPT ][0x45] = 0x04;
dev->ld_regs[LD_LPT ][0xc0] = 0xf2;
dev->ld_regs[0x04][0x44] = 0x04;
dev->ld_regs[0x04][0x45] = 0x04;
dev->ld_regs[LD_UART2][0x30] = 0x02;
dev->ld_regs[LD_UART2][0x31] = 0xf8;
dev->ld_regs[LD_UART2][0x40] = 0x03;
dev->ld_regs[LD_UART2][0x41] = 0x03;
dev->ld_regs[LD_UART2][0x44] = 0x04;
dev->ld_regs[LD_UART2][0x45] = 0x04;
dev->ld_regs[LD_UART2][0xc0] = 0x02;
dev->ld_regs[0x05][0x40] = 0x0c;
dev->ld_regs[0x05][0x41] = 0x02;
dev->ld_regs[0x05][0x44] = 0x04;
dev->ld_regs[0x05][0x45] = 0x04;
dev->ld_regs[LD_UART1][0x30] = 0x03;
dev->ld_regs[LD_UART1][0x31] = 0xf8;
dev->ld_regs[LD_UART1][0x40] = 0x04;
dev->ld_regs[LD_UART1][0x41] = 0x03;
dev->ld_regs[LD_UART1][0x44] = 0x04;
dev->ld_regs[LD_UART1][0x45] = 0x04;
dev->ld_regs[LD_UART1][0xc0] = 0x02;
dev->ld_regs[0x06][0x01] = 0x01;
dev->ld_regs[0x06][0x31] = 0x60;
dev->ld_regs[0x06][0x33] = 0x64;
dev->ld_regs[0x06][0x40] = 0x01;
dev->ld_regs[0x06][0x41] = 0x02;
dev->ld_regs[0x06][0x44] = 0x04;
dev->ld_regs[0x06][0x45] = 0x04;
dev->ld_regs[0x06][0xc0] = 0x40;
dev->regs[0x00] = 0x0B;
dev->regs[0x01] = 0x01;
dev->regs[0x03] = 0x01;
dev->regs[0x05] = 0x0D;
dev->regs[0x08] = 0x70;
dev->regs[0x09] = 0xC0;
dev->regs[0x0b] = 0x80;
dev->regs[0x0f] = 0x1E;
dev->regs[0x12] = 0x30;
dev->regs[0x19] = 0xEF;
dev->ld_regs[LD_PM ][0x44] = 0x04;
dev->ld_regs[LD_PM ][0x45] = 0x04;
dev->pm[0] = 0x79;
dev->pm[4] = 0x0e;
@@ -478,11 +653,15 @@ pc87309_reset(pc87309_t *dev)
0 = 360 rpm @ 500 kbps for 3.5"
1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5"
*/
lpt1_remove();
serial_remove(dev->uart[0]);
serial_remove(dev->uart[1]);
fdc_toggle_flag(dev->fdc, FDC_FLAG_PS2_MCA, 0);
fdc_reset(dev->fdc);
kbc_handler(dev);
fdc_handler(dev);
lpt1_handler(dev);
serial_handler(dev, 0);
serial_handler(dev, 1);
pm_handler(dev);
superio_handler(dev);
}
@@ -503,7 +682,27 @@ pc87309_init(const device_t *info)
dev->fdc = device_add(&fdc_at_nsc_device);
dev->baddr = (info->local & 0x100) ? 8 : 9;
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
switch (info->local & PCX730X_KBC) {
default:
case PCX730X_AMI:
dev->kbc = device_add(&keyboard_ps2_intel_ami_pci_device);
break;
/* Optiplex! */
case PCX730X_PHOENIX_42:
dev->kbc = device_add(&keyboard_ps2_phoenix_device);
break;
case PCX730X_PHOENIX_42I:
dev->kbc = device_add(&keyboard_ps2_phoenix_pci_device);
break;
}
if (info->local & PCX730X_15C)
dev->baddr = 0x0a;
else
dev->baddr = 0x0b;
pc87309_reset(dev);
@@ -514,24 +713,10 @@ const device_t pc87309_device = {
.name = "National Semiconductor PC87309 Super I/O",
.internal_name = "pc87309",
.flags = 0,
.local = 0xe0,
.local = 0,
.init = pc87309_init,
.close = pc87309_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t pc87309_15c_device = {
.name = "National Semiconductor PC87309 Super I/O (Port 15Ch)",
.internal_name = "pc87309_15c",
.flags = 0,
.local = 0x1e0,
.init = pc87309_init,
.close = pc87309_close,
.reset = NULL,
.reset = pc87309_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,

View File

@@ -8042,7 +8042,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
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);
s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask;
if (s3->accel.rd_mask_16bit_check) {
if ((s3->accel.cur_x_overflow & 0xc00) == 0xc00)
s3->accel.start = 1;
@@ -8353,7 +8353,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
s3->accel.dest = dstbase + s3->accel.cy * s3->width;
if ((s3->bpp == 0) && s3->color_16bit) {
s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00);
s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask;
if (s3->accel.rd_mask_16bit_check) {
if (s3->accel.cmd == 0x41b3) {
if (frgd_mix == 0) {
@@ -8478,9 +8478,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
if ((s3_cpu_src(s3)) && !(s3->accel.cmd & 0x200)) {
s3_log("FIXME: S3 911/924 15/16bpp documentation needed.\n");
} else {
if (!cpu_input && (s3->accel.cur_x & 0x400))
if (!cpu_input && (s3->accel.cur_x & 0x400)) {
s3_log("No Input.\n");
break;
else if (cpu_input && (s3->accel.cmd == 0x53b3) && (s3->accel.cur_x & 0x400))
} else if (cpu_input && (s3->accel.cmd == 0x53b3) && (s3->accel.cur_x & 0x400))
break;
}
}
@@ -8756,7 +8757,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
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);
s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask;
if (s3->accel.rd_mask_16bit_check) {
if (!(clip_r & 0x400))
s3->accel.start = 1;
@@ -8805,7 +8806,7 @@ 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);
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)) {
pclog("Special BitBLT.\n");
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);