FDC37c67x rewrite, c93x and m60x fixes, and hooked up ECP+EPP to all three.

This commit is contained in:
OBattler
2025-08-02 21:14:43 +02:00
parent 1b4f5241c7
commit 711e09e08b
5 changed files with 720 additions and 519 deletions

View File

@@ -244,8 +244,7 @@ machine_at_ma30d_init(const machine_t *model)
device_add(&i440lx_device);
device_add(&piix4e_device);
device_add(&nec_mate_unk_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c67x_device);
device_add_params(&fdc37c67x_device, (void *) (FDC37C932 | FDC37C93X_370));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);

View File

@@ -890,8 +890,7 @@ machine_at_ma23c_init(const machine_t *model)
device_add(&i430tx_device);
device_add(&piix4_device);
device_add(&nec_mate_unk_device);
device_add(&kbc_ps2_ami_pci_device);
device_add(&fdc37c67x_device);
device_add_params(&fdc37c67x_device, (void *) (FDC37C932 | FDC37C93X_370));
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
@@ -1235,8 +1234,7 @@ machine_at_tomahawk_init(const machine_t *model)
pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&i430tx_device);
device_add(&piix4_device);
device_add(&kbc_ps2_intel_ami_pci_device);
device_add(&fdc37c67x_device);
device_add_params(&fdc37c67x_device, (void *) (FDC37C932 | FDC37C93X_370));
device_add(&amd_flash_29f020a_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */

File diff suppressed because it is too large Load Diff

View File

@@ -6,10 +6,7 @@
*
* This file is part of the 86Box distribution.
*
* Implementation of the SMC FDC37C932FR and FDC37C935 Super
* I/O Chips.
*
*
* Implementation of the SMC FDC37C93x Super I/O Chips.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
@@ -793,28 +790,59 @@ fdc37c93x_fdc_handler(fdc37c93x_t *dev)
static void
fdc37c93x_lpt_handler(fdc37c93x_t *dev)
{
const uint8_t global_enable = !!(dev->regs[0x22] & (1 << 3));
const uint8_t local_enable = !!dev->ld_regs[3][0x30];
uint8_t lpt_irq = dev->ld_regs[3][0x70];
const uint16_t old_base = dev->lpt_base;
uint16_t ld_port = 0x0000;
uint16_t mask = 0xfffc;
uint8_t global_enable = !!(dev->regs[0x22] & (1 << 3));
uint8_t local_enable = !!dev->ld_regs[3][0x30];
uint8_t lpt_irq = dev->ld_regs[3][0x70];
uint8_t lpt_dma = dev->ld_regs[3][0x74];
uint8_t lpt_mode = dev->ld_regs[3][0xf0] & 0x07;
if (lpt_irq > 15)
lpt_irq = 0xff;
dev->lpt_base = 0x0000;
if (lpt_dma >= 4)
lpt_dma = 0xff;
if (global_enable && local_enable)
dev->lpt_base = make_port(dev, 3) & 0xfffc;
if (dev->lpt_base != old_base) {
if ((old_base >= 0x0100) && (old_base <= 0x0ffc))
lpt_port_remove(dev->lpt);
if ((dev->lpt_base >= 0x0100) && (dev->lpt_base <= 0x0ffc))
lpt_port_setup(dev->lpt, dev->lpt_base);
lpt_port_remove(dev->lpt);
lpt_set_fifo_threshold(dev->lpt, (dev->ld_regs[3][0xf0] & 0x78) >> 3);
switch (lpt_mode) {
default:
case 0x04:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 0);
break;
case 0x00:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 1);
break;
case 0x01: case 0x05:
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 0);
break;
case 0x02:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
case 0x03: case 0x07:
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
}
if (global_enable && local_enable) {
ld_port = (make_port(dev, 3) & 0xfffc) & mask;
if ((ld_port >= 0x0100) && (ld_port <= (0x0ffc & mask)))
lpt_port_setup(dev->lpt, ld_port);
}
lpt_port_irq(dev->lpt, lpt_irq);
lpt_port_dma(dev->lpt, lpt_dma);
}
static void
@@ -918,6 +946,9 @@ fdc37c93x_kbc_handler(fdc37c93x_t *dev)
if (dev->kbc_base != old_base)
kbc_at_handler(local_enable, dev->kbc_base, dev->kbc);
kbc_at_set_irq(0, dev->ld_regs[7][0x70], dev->kbc);
kbc_at_set_irq(1, dev->ld_regs[7][0x72], dev->kbc);
}
static void
@@ -1059,6 +1090,7 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
break;
case 0x03:
dev->regs[dev->cur_reg] = val & 0x83;
fdc37c93x_gpio_handler(dev);
break;
case 0x07: case 0x26:
case 0x2e ... 0x2f:
@@ -1229,8 +1261,20 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
if (valxor)
fdc37c93x_lpt_handler(dev);
break;
/*
Bits 2:0: Mode:
- 000: Bi-directional (SPP);
- 001: EPP-1.9 and SPP;
- 010: ECP;
- 011: ECP and EPP-1.9;
- 101: EPP-1.7 and SPP;
- 110: ECP and EPP-1.7.
Bits 6:3: ECP FIFO Threshold.
*/
case 0xf0:
dev->ld_regs[dev->regs[7]][dev->cur_reg] = val;
if (valxor & 0x7f)
fdc37c93x_lpt_handler(dev);
break;
case 0xf1:
if (dev->chip_id >= FDC37C93X_FR)
@@ -1381,7 +1425,7 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
case 0x07: /* Keyboard */
switch (dev->cur_reg) {
case 0x30:
case 0x70: case 0x71:
case 0x70: case 0x72:
dev->ld_regs[dev->regs[7]][dev->cur_reg] = val;
if (valxor)
@@ -1609,8 +1653,10 @@ fdc37c93x_read(uint16_t port, void *priv)
}
static void
fdc37c93x_reset(fdc37c93x_t *dev)
fdc37c93x_reset(void *priv)
{
fdc37c93x_t *dev = (fdc37c93x_t *) priv;
memset(dev->regs, 0x00, sizeof(dev->regs));
dev->regs[0x03] = 0x03;
@@ -1689,6 +1735,7 @@ fdc37c93x_reset(fdc37c93x_t *dev)
dev->ld_regs[0x07][0x30] = 0x00;
dev->ld_regs[0x07][0x61] = 0x60;
dev->ld_regs[0x07][0x70] = 0x01;
dev->ld_regs[0x07][0x72] = 0x0c;
/* Logical device 8: Auxiliary I/O */
dev->ld_regs[0x08][0x30] = 0x00;
@@ -1912,7 +1959,7 @@ const device_t fdc37c93x_device = {
.local = 0,
.init = fdc37c93x_init,
.close = fdc37c93x_close,
.reset = NULL,
.reset = fdc37c93x_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,

View File

@@ -6,14 +6,11 @@
*
* This file is part of the 86Box distribution.
*
* Implementation of the SMC FDC37C932FR and FDC37C935 Super
* I/O Chips.
*
*
* Implementation of the SMC FDC37M60x Super I/O Chips.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2018 Miran Grca.
* Copyright 2025 Miran Grca.
*/
#include <inttypes.h>
#include <stdint.h>
@@ -47,7 +44,6 @@ typedef struct fdc37m60x_t {
uint8_t max_ld;
uint8_t tries;
uint8_t port_370;
uint8_t auxio_reg;
uint8_t regs[48];
uint8_t ld_regs[11][256];
uint16_t kbc_type;
@@ -55,7 +51,6 @@ typedef struct fdc37m60x_t {
uint16_t fdc_base;
uint16_t lpt_base;
uint16_t kbc_base;
uint16_t auxio_base;
uint16_t uart_base[2];
int locked;
int cur_reg;
@@ -90,22 +85,6 @@ make_port(const fdc37m60x_t *dev, const uint8_t ld)
return p;
}
static uint8_t
fdc37m60x_auxio_read(UNUSED(uint16_t port), void *priv)
{
const fdc37m60x_t *dev = (fdc37m60x_t *) priv;
return dev->auxio_reg;
}
static void
fdc37m60x_auxio_write(UNUSED(uint16_t port), uint8_t val, void *priv)
{
fdc37m60x_t *dev = (fdc37m60x_t *) priv;
dev->auxio_reg = val;
}
static void
fdc37m60x_superio_handler(fdc37m60x_t *dev)
{
@@ -144,28 +123,59 @@ fdc37m60x_fdc_handler(fdc37m60x_t *dev)
static void
fdc37m60x_lpt_handler(fdc37m60x_t *dev)
{
const uint8_t global_enable = !!(dev->regs[0x22] & (1 << 3));
const uint8_t local_enable = !!dev->ld_regs[3][0x30];
uint8_t lpt_irq = dev->ld_regs[3][0x70];
const uint16_t old_base = dev->lpt_base;
uint16_t ld_port = 0x0000;
uint16_t mask = 0xfffc;
uint8_t global_enable = !!(dev->regs[0x22] & (1 << 3));
uint8_t local_enable = !!dev->ld_regs[3][0x30];
uint8_t lpt_irq = dev->ld_regs[3][0x70];
uint8_t lpt_dma = dev->ld_regs[3][0x74];
uint8_t lpt_mode = dev->ld_regs[3][0xf0] & 0x07;
if (lpt_irq > 15)
lpt_irq = 0xff;
dev->lpt_base = 0x0000;
if (lpt_dma >= 4)
lpt_dma = 0xff;
if (global_enable && local_enable)
dev->lpt_base = make_port(dev, 3) & 0xfffc;
if (dev->lpt_base != old_base) {
if ((old_base >= 0x0100) && (old_base <= 0x0ffc))
lpt_port_remove(dev->lpt);
if ((dev->lpt_base >= 0x0100) && (dev->lpt_base <= 0x0ffc))
lpt_port_setup(dev->lpt, dev->lpt_base);
lpt_port_remove(dev->lpt);
lpt_set_fifo_threshold(dev->lpt, (dev->ld_regs[3][0xf0] & 0x78) >> 3);
switch (lpt_mode) {
default:
case 0x04:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 0);
break;
case 0x00:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 1);
break;
case 0x01: case 0x05:
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 0);
lpt_set_ext(dev->lpt, 0);
break;
case 0x02:
lpt_set_epp(dev->lpt, 0);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
case 0x03: case 0x07:
mask = 0xfff8;
lpt_set_epp(dev->lpt, 1);
lpt_set_ecp(dev->lpt, 1);
lpt_set_ext(dev->lpt, 0);
break;
}
if (global_enable && local_enable) {
ld_port = (make_port(dev, 3) & 0xfffc) & mask;
if ((ld_port >= 0x0100) && (ld_port <= (0x0ffc & mask)))
lpt_port_setup(dev->lpt, ld_port);
}
lpt_port_irq(dev->lpt, lpt_irq);
lpt_port_dma(dev->lpt, lpt_dma);
}
static void
@@ -231,28 +241,9 @@ fdc37m60x_kbc_handler(fdc37m60x_t *dev)
if (dev->kbc_base != old_base)
kbc_at_handler(local_enable, dev->kbc_base, dev->kbc);
}
static void
fdc37m60x_auxio_handler(fdc37m60x_t *dev)
{
const uint8_t local_enable = !!dev->ld_regs[8][0x30];
const uint16_t old_base = dev->auxio_base;
if (local_enable)
dev->auxio_base = make_port(dev, 8);
else
dev->auxio_base = 0x0000;
if (dev->auxio_base != old_base) {
if ((old_base >= 0x0100) && (old_base <= 0x0fff))
io_removehandler(old_base, 0x0001,
fdc37m60x_auxio_read, NULL, NULL, fdc37m60x_auxio_write, NULL, NULL, dev);
if ((dev->auxio_base >= 0x0100) && (dev->auxio_base <= 0x0fff))
io_sethandler(dev->auxio_base, 0x0001,
fdc37m60x_auxio_read, NULL, NULL, fdc37m60x_auxio_write, NULL, NULL, dev);
}
kbc_at_set_irq(0, dev->ld_regs[7][0x70], dev->kbc);
kbc_at_set_irq(1, dev->ld_regs[7][0x72], dev->kbc);
}
static void
@@ -295,7 +286,7 @@ fdc37m60x_write(uint16_t port, uint8_t val, void *priv)
if (val == 0x02)
fdc37m60x_state_change(dev, 0);
break;
case 0x07:
case 0x07: case 0x26:
case 0x2b ... 0x2f:
dev->regs[dev->cur_reg] = val;
break;
@@ -317,7 +308,7 @@ fdc37m60x_write(uint16_t port, uint8_t val, void *priv)
case 0x24:
dev->regs[dev->cur_reg] = val & 0x4e;
break;
case 0x26: case 0x27:
case 0x27:
dev->regs[dev->cur_reg] = val;
fdc37m60x_superio_handler(dev);
break;
@@ -403,6 +394,8 @@ fdc37m60x_write(uint16_t port, uint8_t val, void *priv)
break;
case 0xf0:
dev->ld_regs[dev->regs[7]][dev->cur_reg] = val;
if (valxor & 0x7f)
fdc37m60x_lpt_handler(dev);
break;
}
break;
@@ -461,7 +454,7 @@ fdc37m60x_write(uint16_t port, uint8_t val, void *priv)
case 0x07: /* Keyboard */
switch (dev->cur_reg) {
case 0x30:
case 0x70: case 0x71:
case 0x70: case 0x72:
dev->ld_regs[dev->regs[7]][dev->cur_reg] = val;
if (valxor)
@@ -475,13 +468,7 @@ fdc37m60x_write(uint16_t port, uint8_t val, void *priv)
case 0x08: /* Aux. I/O */
switch (dev->cur_reg) {
case 0x30:
case 0x60: case 0x61:
case 0x62: case 0x63:
case 0x70:
dev->ld_regs[dev->regs[7]][dev->cur_reg] = val;
if (valxor)
fdc37m60x_auxio_handler(dev);
break;
case 0xb8:
dev->ld_regs[dev->regs[7]][dev->cur_reg] = val;
@@ -547,12 +534,13 @@ fdc37m60x_read(uint16_t port, void *priv)
}
static void
fdc37m60x_reset(fdc37m60x_t *dev)
fdc37m60x_reset(void *priv)
{
fdc37m60x_t *dev = (fdc37m60x_t *) priv;
memset(dev->regs, 0x00, sizeof(dev->regs));
dev->regs[0x20] = 0x47;
dev->regs[0x21] = 0x00;
dev->regs[0x22] = 0x39;
dev->regs[0x24] = 0x04;
dev->regs[0x26] = dev->port_370 ? 0x70 : 0xf0;
@@ -610,7 +598,6 @@ fdc37m60x_reset(fdc37m60x_t *dev)
fdc37m60x_lpt_handler(dev);
fdc37m60x_serial_handler(dev, 0);
fdc37m60x_serial_handler(dev, 1);
fdc37m60x_auxio_handler(dev);
fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA);
fdc_reset(dev->fdc);
@@ -700,7 +687,7 @@ const device_t fdc37m60x_device = {
.local = 0,
.init = fdc37m60x_init,
.close = fdc37m60x_close,
.reset = NULL,
.reset = fdc37m60x_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,