Added the missing IT8661F

This commit is contained in:
Panagiotis
2021-04-21 22:05:59 +03:00
committed by GitHub
parent 0847ff171a
commit c5be6e3e0a
3 changed files with 314 additions and 1 deletions

View File

@@ -35,6 +35,7 @@ extern const device_t fdc37c932qf_device;
extern const device_t fdc37c935_device;
extern const device_t fdc37m60x_device;
extern const device_t fdc37m60x_370_device;
extern const device_t it8661f_device;
extern const device_t i82091aa_device;
extern const device_t i82091aa_398_device;
extern const device_t i82091aa_ide_device;
@@ -62,7 +63,6 @@ extern const device_t um8669f_device;
extern const device_t via_vt82c686_sio_device;
extern const device_t w83787f_device;
extern const device_t w83787f_ide_device;
extern const device_t w83787f_ide_sec_device;
extern const device_t w83877f_device;
extern const device_t w83877f_president_device;
extern const device_t w83877tf_device;

View File

@@ -15,6 +15,7 @@
add_library(sio OBJECT sio_acc3221.c sio_f82c710.c sio_82091aa.c sio_fdc37c661.c
sio_fdc37c66x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c
sio_it8661f.c
sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87310.c sio_pc87311.c sio_pc87332.c
sio_prime3b.c sio_prime3c.c
sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c

312
src/sio/sio_it8661f.c Normal file
View File

@@ -0,0 +1,312 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the ITE IT8661F chipset.
*
* Note: This Super I/O is partially incomplete and intended only for having the intended machine to function
*
* Authors: Tiseno100
*
* Copyright 2021 Tiseno100
*
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdd_common.h>
#include <86box/sio.h>
#define LDN dev->regs[7]
typedef struct
{
fdc_t *fdc_controller;
serial_t *uart[2];
uint8_t index, regs[256], device_regs[6][256];
int unlocked, enumerator;
} it8661f_t;
uint8_t mb_pnp_key[32] = {0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b, 0x0d, 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0xe8, 0x74, 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39};
static void it8661f_reset(void *priv);
void it8661_fdc(uint16_t addr, uint8_t val, it8661f_t *dev)
{
fdc_remove(dev->fdc_controller);
if (((addr == 0x30) && (val & 1)) || (dev->device_regs[0][0x30] & 1))
{
switch (addr)
{
case 0x30:
dev->device_regs[0][addr] = val & 1;
break;
case 0x31:
dev->device_regs[0][addr] = val & 3;
if (val & 1)
dev->device_regs[0][addr] |= 0x55;
break;
case 0x60:
case 0x61:
dev->device_regs[0][addr] = val & ((addr == 0x61) ? 0xff : 0xf8);
break;
case 0x70:
dev->device_regs[0][addr] = val & 0x0f;
break;
case 0x74:
dev->device_regs[0][addr] = val & 7;
break;
case 0xf0:
dev->device_regs[0][addr] = val & 0x0f;
break;
}
fdc_set_base(dev->fdc_controller, (dev->device_regs[0][0x60] << 8) | (dev->device_regs[0][0x61]));
fdc_set_irq(dev->fdc_controller, dev->device_regs[0][0x70] & 0x0f);
fdc_set_dma_ch(dev->fdc_controller, dev->device_regs[0][0x74] & 7);
if (dev->device_regs[0][0xf0] & 1)
fdc_writeprotect(dev->fdc_controller);
// if (dev->device_regs[0][0xf0] & 4)
// fdc_swap(dev->fdc_controller);
pclog("ITE 8661-FDC: BASE %04x IRQ %02x\n", (dev->device_regs[0][0x60] << 8) | (dev->device_regs[0][0x61]), dev->device_regs[0][0x70] & 0x0f);
}
}
void it8661_serial(int uart, uint16_t addr, uint8_t val, it8661f_t *dev)
{
serial_remove(dev->uart[uart]);
if (((addr == 0x30) && (val & 1)) || (dev->device_regs[1 + uart][0x30] & 1))
{
switch (addr)
{
case 0x30:
dev->device_regs[1 + uart][addr] = val & 1;
break;
case 0x60:
case 0x61:
dev->device_regs[1 + uart][addr] = val & ((addr == 0x61) ? 0xff : 0xf8);
break;
case 0x70:
dev->device_regs[1 + uart][addr] = val & 0x0f;
break;
case 0x74:
dev->device_regs[1 + uart][addr] = val & 7;
break;
case 0xf0:
dev->device_regs[1 + uart][addr] = val & 3;
break;
}
serial_setup(dev->uart[uart], (dev->device_regs[1 + uart][0x60] << 8) | (dev->device_regs[1 + uart][0x61]), dev->device_regs[1 + uart][0x70] & 0x0f);
pclog("ITE 8661-UART%01x: BASE %04x IRQ %02x\n", 1 + (LDN % 1), (dev->device_regs[1 + uart][0x60] << 8) | (dev->device_regs[1 + uart][0x61]), dev->device_regs[1 + uart][0x70] & 0x0f);
}
}
void it8661_lpt(uint16_t addr, uint8_t val, it8661f_t *dev)
{
lpt1_remove();
if (((addr == 0x30) && (val & 1)) || (dev->device_regs[3][0x30] & 1))
{
switch (addr)
{
case 0x30:
dev->device_regs[3][addr] = val & 1;
break;
case 0x60:
case 0x61:
dev->device_regs[3][addr] = val & ((addr == 0x61) ? 0xff : 0xf8);
break;
case 0x70:
dev->device_regs[3][addr] = val & 0x0f;
break;
case 0x74:
dev->device_regs[3][addr] = val & 7;
break;
case 0xf0:
dev->device_regs[3][addr] = val & 3;
break;
}
lpt1_init((dev->device_regs[3][0x60] << 8) | (dev->device_regs[3][0x61]));
lpt1_irq(dev->device_regs[3][0x70] & 0x0f);
pclog("ITE 8661-LPT: BASE %04x IRQ %02x\n", (dev->device_regs[3][0x60] << 8) | (dev->device_regs[3][0x61]), dev->device_regs[3][0x70] & 0x0f);
}
}
void it8661_ldn(uint16_t addr, uint8_t val, it8661f_t *dev)
{
switch (LDN)
{
case 0:
it8661_fdc(addr, val, dev);
break;
case 1:
case 2:
it8661_serial(LDN & 2, addr, val, dev);
break;
case 3:
it8661_lpt(addr, val, dev);
break;
}
}
static void
it8661f_write(uint16_t addr, uint8_t val, void *priv)
{
it8661f_t *dev = (it8661f_t *)priv;
switch (addr)
{
case 0x370:
if (!dev->unlocked)
{
(val == mb_pnp_key[dev->enumerator]) ? dev->enumerator++ : (dev->enumerator = 0);
if (dev->enumerator == 31)
{
dev->unlocked = 1;
pclog("ITE8661F: Unlocked!\n");
}
}
else
dev->index = val;
break;
case 0x371:
if (dev->unlocked)
{
switch (dev->index)
{
case 0x02:
dev->regs[dev->index] = val;
if (val & 1)
it8661f_reset(dev);
if (val & 2)
dev->unlocked = 0;
break;
case 0x07:
dev->regs[dev->index] = val;
break;
case 0x22:
dev->regs[dev->index] = val & 0x30;
break;
case 0x23:
dev->regs[dev->index] = val & 0x1f;
break;
default:
it8661_ldn(dev->index, val, dev);
break;
}
}
break;
}
return;
}
static uint8_t
it8661f_read(uint16_t addr, void *priv)
{
it8661f_t *dev = (it8661f_t *)priv;
pclog("IT8661F:\n", addr, dev->regs[dev->index]);
return (addr == 0xa79) ? dev->regs[dev->index] : 0xff;
}
static void
it8661f_reset(void *priv)
{
it8661f_t *dev = (it8661f_t *)priv;
dev->regs[0x20] = 0x86;
dev->regs[0x21] = 0x61;
dev->device_regs[0][0x60] = 3;
dev->device_regs[0][0x61] = 0xf0;
dev->device_regs[0][0x70] = 6;
dev->device_regs[0][0x71] = 2;
dev->device_regs[0][0x74] = 2;
dev->device_regs[1][0x60] = 3;
dev->device_regs[1][0x61] = 0xf8;
dev->device_regs[1][0x70] = 4;
dev->device_regs[1][0x71] = 2;
dev->device_regs[2][0x60] = 2;
dev->device_regs[2][0x61] = 0xf8;
dev->device_regs[2][0x70] = 3;
dev->device_regs[2][0x71] = 2;
dev->device_regs[3][0x60] = 3;
dev->device_regs[3][0x61] = 0x78;
dev->device_regs[3][0x70] = 7;
dev->device_regs[3][0x71] = 2;
dev->device_regs[3][0x74] = 3;
dev->device_regs[3][0xf0] = 3;
}
static void
it8661f_close(void *priv)
{
it8661f_t *dev = (it8661f_t *)priv;
free(dev);
}
static void *
it8661f_init(const device_t *info)
{
it8661f_t *dev = (it8661f_t *)malloc(sizeof(it8661f_t));
memset(dev, 0, sizeof(it8661f_t));
dev->fdc_controller = device_add(&fdc_at_smc_device);
fdc_reset(dev->fdc_controller);
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
io_sethandler(0x0370, 0x0002, it8661f_read, NULL, NULL, it8661f_write, NULL, NULL, dev);
dev->enumerator = 0;
dev->unlocked = 0;
it8661f_reset(dev);
return dev;
}
const device_t it8661f_device = {
"ITE IT8661F",
0,
0,
it8661f_init,
it8661f_close,
NULL,
{NULL},
NULL,
NULL,
NULL};