Vendor-specific ECP configuration register B readout, assorted Super I/O chip fixes, and gave the IBM ValuePointer 433/DXi its Super I/O chip.
This commit is contained in:
@@ -322,7 +322,7 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv)
|
||||
lpt_t *dev = (lpt_t *) priv;
|
||||
uint16_t mask = 0x0407;
|
||||
|
||||
lpt_log("[W] %04X = %02X\n", port, val);
|
||||
lpt_log("[W] %04X = %02X (ECR = %02X)\n", port, val, dev->ecr);
|
||||
|
||||
/* This is needed so the parallel port at 3BC works. */
|
||||
if (dev->addr & 0x0004)
|
||||
@@ -353,7 +353,7 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv)
|
||||
|
||||
case 0x0002:
|
||||
if (dev->dt && dev->dt->write_ctrl && dev->dt->priv) {
|
||||
if (dev->ecp)
|
||||
if (dev->ecp && ((dev->ecr & 0xe0) >= 0x20))
|
||||
dev->dt->write_ctrl((val & 0xfc) | dev->autofeed | dev->strobe, dev->dt->priv);
|
||||
else
|
||||
dev->dt->write_ctrl(val, dev->dt->priv);
|
||||
@@ -402,6 +402,7 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv)
|
||||
case 0x05:
|
||||
dev->ext_regs[0x00] = val;
|
||||
dev->cnfga_readout = (val & 0x80) ? 0x1c : 0x14;
|
||||
dev->cnfgb_readout = (dev->cnfgb_readout & 0xc0) | (val & 0x3b);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -658,11 +659,7 @@ lpt_read(const uint16_t port, void *priv)
|
||||
case 0x0401:
|
||||
if ((dev->ecr & 0xe0) == 0xe0) {
|
||||
/* CNFGB */
|
||||
ret = 0x08;
|
||||
ret |= (dev->irq_state ? 0x40 : 0x00);
|
||||
ret |= ((dev->irq == 0x05) ? 0x30 : 0x00);
|
||||
if ((dev->dma >= 1) && (dev->dma <= 3))
|
||||
ret |= dev->dma;
|
||||
ret = dev->cnfgb_readout | (dev->irq_state ? 0x40 : 0x00);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -775,6 +772,13 @@ lpt_set_cnfga_readout(lpt_t *dev, const uint8_t cnfga_readout)
|
||||
dev->cnfga_readout = cnfga_readout;
|
||||
}
|
||||
|
||||
void
|
||||
lpt_set_cnfgb_readout(lpt_t *dev, const uint8_t cnfgb_readout)
|
||||
{
|
||||
if (lpt_ports[dev->id].enabled)
|
||||
dev->cnfgb_readout = (dev->cnfgb_readout & 0xc0) | (cnfgb_readout & 0x3f);
|
||||
}
|
||||
|
||||
void
|
||||
lpt_port_setup(lpt_t *dev, const uint16_t port)
|
||||
{
|
||||
@@ -967,6 +971,7 @@ lpt_init(const device_t *info)
|
||||
dev->ecr = 0x15;
|
||||
dev->ret_ecr = 0x15;
|
||||
dev->cnfga_readout = 0x10;
|
||||
dev->cnfgb_readout = 0x00;
|
||||
|
||||
memset(dev->ext_regs, 0x00, 8);
|
||||
dev->ext_regs[0x02] = 0x80;
|
||||
|
||||
@@ -62,10 +62,11 @@ typedef struct lpt_t {
|
||||
uint8_t strobe;
|
||||
uint8_t lv2;
|
||||
uint8_t cnfga_readout;
|
||||
uint8_t cnfgb_readout;
|
||||
uint8_t cfg_regs_enabled;
|
||||
uint8_t inst;
|
||||
uint8_t eir;
|
||||
uint8_t pad[2];
|
||||
uint8_t pad;
|
||||
uint8_t ext_regs[8];
|
||||
uint16_t addr;
|
||||
uint16_t id;
|
||||
@@ -134,6 +135,7 @@ extern void lpt_set_lv2(lpt_t *dev, uint8_t lv2);
|
||||
extern void lpt_set_cfg_regs_enabled(lpt_t *dev, uint8_t cfg_regs_enabled);
|
||||
extern void lpt_set_fifo_threshold(lpt_t *dev, int threshold);
|
||||
extern void lpt_set_cnfga_readout(lpt_t *dev, const uint8_t cnfga_readout);
|
||||
extern void lpt_set_cnfgb_readout(lpt_t *dev, const uint8_t cnfgb_readout);
|
||||
extern void lpt_port_setup(lpt_t *dev, uint16_t port);
|
||||
extern void lpt_port_irq(lpt_t *dev, uint8_t irq);
|
||||
extern void lpt_port_dma(lpt_t *dev, uint8_t dma);
|
||||
|
||||
@@ -236,6 +236,7 @@ machine_at_valuepoint433_init(const machine_t *model) // hangs without the PS/2
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&et4000w32_onboard_device);
|
||||
|
||||
device_add_params(&fdc37c6xx_device, (void *) (FDC37C661 | FDC37C6XX_IDE_PRI));
|
||||
device_add(&kbc_ps2_device);
|
||||
|
||||
if (fdc_current[0] == FDC_INTERNAL)
|
||||
|
||||
@@ -293,7 +293,9 @@ i82091aa_init(const device_t *info)
|
||||
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
||||
|
||||
dev->lpt = device_add_inst(&lpt_port_device, 1);
|
||||
|
||||
lpt_set_cnfga_readout(dev->lpt, 0x90);
|
||||
lpt_set_cnfgb_readout(dev->lpt, 0x00);
|
||||
|
||||
dev->has_ide = (info->local >> 9) & 0x03;
|
||||
|
||||
|
||||
@@ -89,6 +89,8 @@ ali5123_lpt_handler(ali5123_t *dev)
|
||||
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;
|
||||
uint8_t irq_readout[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x08,
|
||||
0x00, 0x10, 0x18, 0x20, 0x00, 0x28, 0x30, 0x00 };
|
||||
|
||||
if (lpt_irq > 15)
|
||||
lpt_irq = 0xff;
|
||||
@@ -137,6 +139,9 @@ ali5123_lpt_handler(ali5123_t *dev)
|
||||
}
|
||||
lpt_port_irq(dev->lpt, lpt_irq);
|
||||
lpt_port_dma(dev->lpt, lpt_dma);
|
||||
|
||||
lpt_set_cnfgb_readout(dev->lpt, ((lpt_irq > 15) ? 0x00 : irq_readout[lpt_irq]) |
|
||||
((lpt_dma >= 4) ? 0x00 : lpt_dma));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/sio.h>
|
||||
#include "cpu.h"
|
||||
|
||||
typedef struct fdc37c669_t {
|
||||
uint8_t id;
|
||||
@@ -410,6 +411,7 @@ fdc37c669_init(const device_t *info)
|
||||
dev->uart[1] = device_add_inst(&ns16550_device, (next_id << 1) + 2);
|
||||
|
||||
dev->lpt = device_add_inst(&lpt_port_device, next_id + 1);
|
||||
lpt_set_cnfgb_readout(dev->lpt, 0x00);
|
||||
|
||||
io_sethandler((info->local & FDC37C6XX_370) ? FDC_SECONDARY_ADDR : (next_id ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR),
|
||||
0x0002, fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, dev);
|
||||
|
||||
@@ -179,6 +179,8 @@ fdc37c67x_lpt_handler(fdc37c67x_t *dev)
|
||||
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;
|
||||
uint8_t irq_readout[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x08,
|
||||
0x00, 0x10, 0x18, 0x20, 0x00, 0x00, 0x28, 0x30 };
|
||||
|
||||
if (lpt_irq > 15)
|
||||
lpt_irq = 0xff;
|
||||
@@ -225,6 +227,9 @@ fdc37c67x_lpt_handler(fdc37c67x_t *dev)
|
||||
}
|
||||
lpt_port_irq(dev->lpt, lpt_irq);
|
||||
lpt_port_dma(dev->lpt, lpt_dma);
|
||||
|
||||
lpt_set_cnfgb_readout(dev->lpt, ((lpt_irq > 15) ? 0x00 : irq_readout[lpt_irq]) |
|
||||
((lpt_dma >= 4) ? 0x00 : lpt_dma));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/sio.h>
|
||||
#include "cpu.h"
|
||||
|
||||
typedef struct fdc37c6xx_t {
|
||||
uint8_t max_reg;
|
||||
@@ -225,7 +226,7 @@ fdc37c6xx_write(uint16_t port, uint8_t val, void *priv)
|
||||
fdc_handler(dev);
|
||||
break;
|
||||
case 0x01:
|
||||
if (valxor & 0x03)
|
||||
if (valxor & 0x0b)
|
||||
lpt_handler(dev);
|
||||
if (valxor & 0x60) {
|
||||
set_com34_addr(dev);
|
||||
@@ -259,6 +260,10 @@ fdc37c6xx_write(uint16_t port, uint8_t val, void *priv)
|
||||
if (valxor & 0x20)
|
||||
fdc_set_swap(dev->fdc, (dev->regs[5] & 0x20) >> 5);
|
||||
break;
|
||||
case 0x0a:
|
||||
if (valxor)
|
||||
lpt_handler(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -374,6 +379,7 @@ fdc37c6xx_init(const device_t *info)
|
||||
}
|
||||
|
||||
dev->lpt = device_add_inst(&lpt_port_device, 1);
|
||||
lpt_set_cnfgb_readout(dev->lpt, 0x00);
|
||||
|
||||
if (info->local & FDC37C6XX_370)
|
||||
io_sethandler(FDC_SECONDARY_ADDR, 0x0002,
|
||||
|
||||
@@ -797,6 +797,8 @@ fdc37c93x_lpt_handler(fdc37c93x_t *dev)
|
||||
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;
|
||||
uint8_t irq_readout[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x08,
|
||||
0x00, 0x10, 0x18, 0x20, 0x00, 0x00, 0x28, 0x30 };
|
||||
|
||||
if (lpt_irq > 15)
|
||||
lpt_irq = 0xff;
|
||||
@@ -843,6 +845,9 @@ fdc37c93x_lpt_handler(fdc37c93x_t *dev)
|
||||
}
|
||||
lpt_port_irq(dev->lpt, lpt_irq);
|
||||
lpt_port_dma(dev->lpt, lpt_dma);
|
||||
|
||||
lpt_set_cnfgb_readout(dev->lpt, ((lpt_irq > 15) ? 0x00 : irq_readout[lpt_irq]) |
|
||||
((lpt_dma >= 4) ? 0x00 : lpt_dma));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -130,6 +130,8 @@ fdc37m60x_lpt_handler(fdc37m60x_t *dev)
|
||||
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;
|
||||
uint8_t irq_readout[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x08,
|
||||
0x00, 0x10, 0x18, 0x20, 0x00, 0x00, 0x28, 0x30 };
|
||||
|
||||
if (lpt_irq > 15)
|
||||
lpt_irq = 0xff;
|
||||
@@ -176,6 +178,9 @@ fdc37m60x_lpt_handler(fdc37m60x_t *dev)
|
||||
}
|
||||
lpt_port_irq(dev->lpt, lpt_irq);
|
||||
lpt_port_dma(dev->lpt, lpt_dma);
|
||||
|
||||
lpt_set_cnfgb_readout(dev->lpt, ((lpt_irq > 15) ? 0x00 : irq_readout[lpt_irq]) |
|
||||
((lpt_dma >= 4) ? 0x00 : lpt_dma));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -348,6 +348,7 @@ gm82c803ab_init(const device_t *info)
|
||||
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
||||
|
||||
dev->lpt = device_add_inst(&lpt_port_device, 1);
|
||||
lpt_set_cnfgb_readout(dev->lpt, 0x00);
|
||||
|
||||
io_sethandler(0x0398, 0x0002,
|
||||
gm82c803ab_read, NULL, NULL, gm82c803ab_write, NULL, NULL, dev);
|
||||
|
||||
@@ -345,6 +345,7 @@ gm82c803c_init(const device_t *info)
|
||||
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
||||
|
||||
dev->lpt = device_add_inst(&lpt_port_device, 1);
|
||||
lpt_set_cnfgb_readout(dev->lpt, 0x00);
|
||||
|
||||
io_sethandler(0x0398, 0x0002,
|
||||
gm82c803c_read, NULL, NULL, gm82c803c_write, NULL, NULL, dev);
|
||||
|
||||
@@ -842,6 +842,8 @@ it86x1f_init(UNUSED(const device_t *info))
|
||||
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
||||
|
||||
dev->lpt = device_add_inst(&lpt_port_device, 1);
|
||||
|
||||
lpt_set_cnfgb_readout(dev->lpt, 0x00);
|
||||
lpt_set_ext(dev->lpt, 1);
|
||||
|
||||
dev->gameport = gameport_add(&gameport_sio_device);
|
||||
|
||||
@@ -125,6 +125,7 @@ lpt_handler(pc87306_t *dev)
|
||||
uint16_t lptba;
|
||||
uint16_t lpt_port = LPT1_ADDR;
|
||||
uint8_t lpt_irq = LPT2_IRQ;
|
||||
uint8_t cnfgb_readout = 0x08;
|
||||
|
||||
lpt_port_remove(dev->lpt);
|
||||
|
||||
@@ -159,6 +160,10 @@ lpt_handler(pc87306_t *dev)
|
||||
if (dev->regs[0x1b] & 0x10)
|
||||
lpt_irq = (dev->regs[0x1b] & 0x20) ? 7 : 5;
|
||||
|
||||
cnfgb_readout |= (lpt_irq == 5) ? 0x30 : 0x00;
|
||||
cnfgb_readout |= (dev->regs[0x18] & 0x06) >> 1;
|
||||
|
||||
lpt_set_cnfgb_readout(dev->lpt, cnfgb_readout);
|
||||
lpt_set_ext(dev->lpt, !!(dev->regs[0x02] & 0x80));
|
||||
|
||||
lpt_set_epp(dev->lpt, !!(dev->regs[0x04] & 0x01));
|
||||
@@ -168,6 +173,9 @@ lpt_handler(pc87306_t *dev)
|
||||
lpt_port_setup(dev->lpt, lpt_port);
|
||||
|
||||
lpt_port_irq(dev->lpt, lpt_irq);
|
||||
|
||||
if ((dev->regs[0x18] & 0x06) != 0x00)
|
||||
lpt_port_dma(dev->lpt, (dev->regs[0x18] & 0x08) ? 3 : 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -382,7 +390,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv)
|
||||
pc87306_gpio_handler(dev);
|
||||
break;
|
||||
case 0x18:
|
||||
if (valxor & (0x06)) {
|
||||
if (valxor & (0x0e)) {
|
||||
lpt_port_remove(dev->lpt);
|
||||
if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01))
|
||||
lpt_handler(dev);
|
||||
@@ -430,15 +438,21 @@ pc87306_read(uint16_t port, void *priv)
|
||||
|
||||
index = (port & 1) ? 0 : 1;
|
||||
|
||||
if (dev->tries == 0xff) {
|
||||
ret = 0x88;
|
||||
dev->tries = 0xfe;
|
||||
} else if (dev->tries == 0xfe) {
|
||||
ret = 0x00;
|
||||
dev->tries = 0;
|
||||
|
||||
if (index)
|
||||
} else if (index) {
|
||||
ret = dev->cur_reg & 0x1f;
|
||||
else {
|
||||
dev->tries = 0;
|
||||
} else {
|
||||
if (dev->cur_reg == 8)
|
||||
ret = 0x70;
|
||||
else if (dev->cur_reg < 28)
|
||||
ret = dev->regs[dev->cur_reg];
|
||||
dev->tries = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -451,6 +465,8 @@ pc87306_reset_common(void *priv)
|
||||
|
||||
memset(dev->regs, 0, 29);
|
||||
|
||||
dev->tries = 0xff;
|
||||
|
||||
dev->regs[0x00] = 0x0B;
|
||||
dev->regs[0x01] = 0x01;
|
||||
dev->regs[0x03] = 0x01;
|
||||
|
||||
@@ -85,6 +85,7 @@ lpt_handler(pc873xx_t *dev)
|
||||
break;
|
||||
}
|
||||
|
||||
lpt_set_cnfgb_readout(dev->lpt, (lpt_irq == 5) ? 0x38 : 0x08);
|
||||
lpt_set_ext(dev->lpt, !!(dev->regs[0x02] & 0x80));
|
||||
|
||||
if (dev->is_332) {
|
||||
@@ -363,6 +364,7 @@ pc873xx_init(const device_t *info)
|
||||
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
||||
|
||||
dev->lpt = device_add_inst(&lpt_port_device, 1);
|
||||
lpt_set_cnfgb_readout(dev->lpt, 0x08);
|
||||
|
||||
dev->is_332 = !!(info->local & PC87332);
|
||||
dev->max_reg = dev->is_332 ? 0x08 : 0x02;
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
*
|
||||
* Emulation of the UMC UM8669F Super I/O chip.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* RichardG, <richardg867@gmail.com>
|
||||
@@ -349,6 +347,8 @@ um8669f_init(const device_t *info)
|
||||
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
||||
|
||||
dev->lpt = device_add_inst(&lpt_port_device, 1);
|
||||
|
||||
lpt_set_cnfgb_readout(dev->lpt, 0x00);
|
||||
lpt_set_ext(dev->lpt, 1);
|
||||
|
||||
dev->ide = (uint8_t) (info->local - 1);
|
||||
|
||||
@@ -294,6 +294,7 @@ um866x_init(UNUSED(const device_t *info))
|
||||
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
||||
|
||||
dev->lpt = device_add_inst(&lpt_port_device, 1);
|
||||
lpt_set_cnfgb_readout(dev->lpt, 0x00);
|
||||
|
||||
dev->ide = info->local & 0xff;
|
||||
if (dev->ide < IDE_BUS_MAX)
|
||||
|
||||
@@ -147,16 +147,16 @@ w837x7_lpt_handler(w837x7_t *dev)
|
||||
uint8_t lpt_mode = (dev->regs[0x09] & 0x80) | (dev->regs[0x00] & 0x0c);
|
||||
|
||||
switch (ptras) {
|
||||
case 0x01:
|
||||
case 0x00:
|
||||
lpt_port = LPT_MDA_ADDR;
|
||||
lpt_irq = LPT_MDA_IRQ;
|
||||
break;
|
||||
case 0x02:
|
||||
lpt_port = LPT1_ADDR;
|
||||
case 0x01:
|
||||
lpt_port = LPT2_ADDR;
|
||||
lpt_irq = LPT1_IRQ /*LPT2_IRQ*/;
|
||||
break;
|
||||
case 0x03:
|
||||
lpt_port = LPT2_ADDR;
|
||||
case 0x02:
|
||||
lpt_port = LPT1_ADDR;
|
||||
lpt_irq = LPT1_IRQ /*LPT2_IRQ*/;
|
||||
break;
|
||||
|
||||
@@ -449,6 +449,7 @@ w837x7_init(const device_t *info)
|
||||
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
||||
|
||||
dev->lpt = device_add_inst(&lpt_port_device, 1);
|
||||
lpt_set_cnfgb_readout(dev->lpt, 0x3f);
|
||||
|
||||
dev->gameport = gameport_add(&gameport_sio_1io_device);
|
||||
|
||||
|
||||
@@ -201,6 +201,8 @@ w83877_lpt_handler(w83877_t *dev)
|
||||
|
||||
lpt_port_irq(dev->lpt, lpt_irq);
|
||||
lpt_port_dma(dev->lpt, dev->dma_map[dev->regs[0x26] & 0x03]);
|
||||
|
||||
lpt_set_cnfgb_readout(dev->lpt, ((dev->regs[0x26] & 0xe0) >> 2) | 0x07);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -390,6 +390,8 @@ w83977_lpt_handler(w83977_t *dev)
|
||||
uint8_t lpt_irq = dev->ld_regs[1][0x70];
|
||||
uint8_t lpt_dma = dev->ld_regs[1][0x74];
|
||||
uint8_t lpt_mode = dev->ld_regs[1][0xf0] & 0x07;
|
||||
uint8_t irq_readout[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x08,
|
||||
0x00, 0x10, 0x18, 0x20, 0x00, 0x00, 0x28, 0x30 };
|
||||
|
||||
if (lpt_irq > 15)
|
||||
lpt_irq = 0xff;
|
||||
@@ -436,6 +438,8 @@ w83977_lpt_handler(w83977_t *dev)
|
||||
}
|
||||
lpt_port_irq(dev->lpt, lpt_irq);
|
||||
lpt_port_dma(dev->lpt, lpt_dma);
|
||||
|
||||
lpt_set_cnfgb_readout(dev->lpt, ((lpt_irq > 15) ? 0x00 : irq_readout[lpt_irq]) | 0x07);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
Reference in New Issue
Block a user