2016-08-14 22:07:17 -04:00
|
|
|
/* Copyright holders: Tenshi
|
|
|
|
|
see COPYING for more details
|
|
|
|
|
*/
|
2016-06-26 00:34:39 +02:00
|
|
|
/*
|
|
|
|
|
Winbond W83877F Super I/O Chip
|
|
|
|
|
Used by the Award 430HX
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "ibm.h"
|
|
|
|
|
|
|
|
|
|
#include "fdc.h"
|
|
|
|
|
#include "fdd.h"
|
|
|
|
|
#include "disc.h"
|
|
|
|
|
#include "io.h"
|
|
|
|
|
#include "lpt.h"
|
|
|
|
|
// #include "mouse_serial.h"
|
|
|
|
|
#include "serial.h"
|
|
|
|
|
#include "w83877f.h"
|
|
|
|
|
|
|
|
|
|
static int w83877f_locked;
|
|
|
|
|
static int w83877f_rw_locked = 0;
|
|
|
|
|
static int w83877f_curreg = 0;
|
|
|
|
|
static uint8_t w83877f_regs[0x2A];
|
|
|
|
|
static uint8_t tries;
|
|
|
|
|
|
|
|
|
|
static int winbond_port = 0x3f0;
|
|
|
|
|
static int winbond_key = 0x89;
|
|
|
|
|
static int winbond_key_times = 1;
|
|
|
|
|
|
|
|
|
|
void w83877f_write(uint16_t port, uint8_t val, void *priv);
|
|
|
|
|
uint8_t w83877f_read(uint16_t port, void *priv);
|
|
|
|
|
|
|
|
|
|
#define OCSS0 (w83877f_regs[0] & 1)
|
|
|
|
|
#define OCSS1 ((w83877f_regs[0] >> 1) & 1)
|
|
|
|
|
#define PRTMODS0 ((w83877f_regs[0] >> 2) & 1)
|
|
|
|
|
#define PRTMODS1 ((w83877f_regs[0] >> 3) & 1)
|
|
|
|
|
|
|
|
|
|
#define ABCHG (w83877f_regs[1] >> 7)
|
|
|
|
|
|
|
|
|
|
#define CEA (w83877f_regs[2] & 1)
|
|
|
|
|
#define EA3 ((w83877f_regs[2] >> 1) & 1)
|
|
|
|
|
#define EA4 ((w83877f_regs[2] >> 2) & 1)
|
|
|
|
|
#define EA5 ((w83877f_regs[2] >> 3) & 1)
|
|
|
|
|
#define EA6 ((w83877f_regs[2] >> 4) & 1)
|
|
|
|
|
#define EA7 ((w83877f_regs[2] >> 5) & 1)
|
|
|
|
|
#define EA8 ((w83877f_regs[2] >> 6) & 1)
|
|
|
|
|
#define EA9 (w83877f_regs[2] >> 7)
|
|
|
|
|
|
|
|
|
|
#define SUBMIDI (w83877f_regs[3] & 1)
|
|
|
|
|
#define SUAMIDI ((w83877f_regs[3] >> 1) & 1)
|
|
|
|
|
#define GMODS ((w83877f_regs[3] >> 4) & 1)
|
|
|
|
|
#define EPPVER ((w83877f_regs[3] >> 5) & 1)
|
|
|
|
|
#define GMENL ((w83877f_regs[3] >> 6) & 1)
|
|
|
|
|
|
|
|
|
|
#define URBTRI (w83877f_regs[4] & 1)
|
|
|
|
|
#define URATRI ((w83877f_regs[4] >> 1) & 1)
|
|
|
|
|
#define GMTRI ((w83877f_regs[4] >> 2) & 1)
|
|
|
|
|
#define PRTTRI ((w83877f_regs[4] >> 3) & 1)
|
|
|
|
|
#define URBPWD ((w83877f_regs[4] >> 4) & 1)
|
|
|
|
|
#define URAPWD ((w83877f_regs[4] >> 5) & 1)
|
|
|
|
|
#define GMPWD ((w83877f_regs[4] >> 6) & 1)
|
|
|
|
|
#define PRTPWD (w83877f_regs[4] >> 7)
|
|
|
|
|
|
|
|
|
|
#define ECPFTHR0 (w83877f_regs[5] & 1)
|
|
|
|
|
#define ECPFTHR1 ((w83877f_regs[5] >> 1) & 1)
|
|
|
|
|
#define ECPFTHR2 ((w83877f_regs[5] >> 2) & 1)
|
|
|
|
|
#define ECPFTHR3 ((w83877f_regs[5] >> 3) & 1)
|
|
|
|
|
|
|
|
|
|
#define IDETRI (w83877f_regs[6] & 1)
|
|
|
|
|
#define FDCTRI ((w83877f_regs[6] >> 1) & 1)
|
|
|
|
|
#define IDEPWD ((w83877f_regs[6] >> 2) & 1)
|
|
|
|
|
#define FDCPWD ((w83877f_regs[6] >> 3) & 1)
|
|
|
|
|
#define FIPURDWM ((w83877f_regs[6] >> 4) & 1)
|
|
|
|
|
#define SEL4FDD ((w83877f_regs[6] >> 5) & 1)
|
|
|
|
|
#define OSCS2 ((w83877f_regs[6] >> 6) & 1)
|
|
|
|
|
|
|
|
|
|
#define FDDA_TYPE (w83877f_regs[7] & 3)
|
|
|
|
|
#define FDDB_TYPE ((w83877f_regs[7] >> 2) & 3)
|
|
|
|
|
#define FDDC_TYPE ((w83877f_regs[7] >> 4) & 3)
|
|
|
|
|
#define FDDD_TYPE ((w83877f_regs[7] >> 6) & 3)
|
|
|
|
|
|
|
|
|
|
#define FD_BOOT (w83877f_regs[8] & 3)
|
|
|
|
|
#define MEDIA_ID ((w83877f_regs[8] >> 2) & 3)
|
|
|
|
|
#define SWWP ((w83877f_regs[8] >> 4) & 1)
|
|
|
|
|
#define DISFDDWR ((w83877f_regs[8] >> 5) & 1)
|
|
|
|
|
#define APDTMS2 ((w83877f_regs[8] >> 6) & 1)
|
|
|
|
|
#define APDTMS1 (w83877f_regs[8] >> 7)
|
|
|
|
|
|
|
|
|
|
#define CHIP_ID (w83877f_regs[9] & 0xF)
|
|
|
|
|
#define EN3MODE ((w83877f_regs[9] >> 5) & 1)
|
|
|
|
|
#define LOCKREG ((w83877f_regs[9] >> 6) & 1)
|
|
|
|
|
#define PRTMODS2 ((w83877f_regs[9] >> 7) & 1)
|
|
|
|
|
|
|
|
|
|
#define PEXTECPP (w83877f_regs[0xA] & 1)
|
|
|
|
|
#define PEXT_ECP ((w83877f_regs[0xA] >> 1) & 1)
|
|
|
|
|
#define PEXT_EPP ((w83877f_regs[0xA] >> 2) & 1)
|
|
|
|
|
#define PEXT_ADP ((w83877f_regs[0xA] >> 3) & 1)
|
|
|
|
|
#define PDCACT ((w83877f_regs[0xA] >> 4) & 1)
|
|
|
|
|
#define PDIRHOP ((w83877f_regs[0xA] >> 5) & 1)
|
|
|
|
|
#define PEXT_ACT ((w83877f_regs[0xA] >> 6) & 1)
|
|
|
|
|
#define PFDCACT (w83877f_regs[0xA] >> 7)
|
|
|
|
|
|
|
|
|
|
#define DRV2EN_NEG (w83877f_regs[0xB] & 1) /* 0 = drive 2 installed */
|
|
|
|
|
#define INVERTZ ((w83877f_regs[0xB] >> 1) & 1) /* 0 = invert DENSEL polarity */
|
|
|
|
|
#define MFM ((w83877f_regs[0xB] >> 2) & 1)
|
|
|
|
|
#define IDENT ((w83877f_regs[0xB] >> 3) & 1)
|
|
|
|
|
#define ENIFCHG ((w83877f_regs[0xB] >> 4) & 1)
|
|
|
|
|
|
|
|
|
|
#define TX2INV (w83877f_regs[0xC] & 1)
|
|
|
|
|
#define RX2INV ((w83877f_regs[0xC] >> 1) & 1)
|
|
|
|
|
#define URIRSEL ((w83877f_regs[0xC] >> 3) & 1)
|
|
|
|
|
#define HEFERE ((w83877f_regs[0xC] >> 5) & 1)
|
|
|
|
|
#define TURB ((w83877f_regs[0xC] >> 6) & 1)
|
|
|
|
|
#define TURA (w83877f_regs[0xC] >> 7)
|
|
|
|
|
|
|
|
|
|
#define IRMODE0 (w83877f_regs[0xD] & 1)
|
|
|
|
|
#define IRMODE1 ((w83877f_regs[0xD] >> 1) & 1)
|
|
|
|
|
#define IRMODE2 ((w83877f_regs[0xD] >> 2) & 1)
|
|
|
|
|
#define HDUPLX ((w83877f_regs[0xD] >> 3) & 1)
|
|
|
|
|
#define SIRRX0 ((w83877f_regs[0xD] >> 4) & 1)
|
|
|
|
|
#define SIRRX1 ((w83877f_regs[0xD] >> 5) & 1)
|
|
|
|
|
#define SIRTX0 ((w83877f_regs[0xD] >> 6) & 1)
|
|
|
|
|
#define SIRTX1 (w83877f_regs[0xD] >> 7)
|
|
|
|
|
|
2016-08-06 17:17:01 +02:00
|
|
|
#define GIO0AD (w83877f_regs[0x10] | (((uint16_t) w83877f_regs[0x11] & 7) << 8))
|
2016-06-26 00:34:39 +02:00
|
|
|
#define GIO0CADM (w83877f_regs[0x11] >> 6)
|
|
|
|
|
#define GIO1AD (w83877f_regs[0x12] | (((uint16_t) w83877f_regs[0x13] & 7) << 8))
|
|
|
|
|
#define GIO1CADM (w83877f_regs[0x13] >> 6)
|
|
|
|
|
|
|
|
|
|
#define GDA0IPI (w83877f_regs[0x14] & 1)
|
|
|
|
|
#define GDA0OPI ((w83877f_regs[0x14] >> 1) & 1)
|
|
|
|
|
#define GCS0IOW ((w83877f_regs[0x14] >> 2) & 1)
|
|
|
|
|
#define GCS0IOR ((w83877f_regs[0x14] >> 3) & 1)
|
|
|
|
|
#define GIO0CSH ((w83877f_regs[0x14] >> 4) & 1)
|
|
|
|
|
#define GIOP0MD ((w83877f_regs[0x14] >> 5) & 7)
|
|
|
|
|
|
|
|
|
|
#define GDA1IPI (w83877f_regs[0x15] & 1)
|
|
|
|
|
#define GDA1OPI ((w83877f_regs[0x15] >> 1) & 1)
|
|
|
|
|
#define GCS1IOW ((w83877f_regs[0x15] >> 2) & 1)
|
|
|
|
|
#define GCS1IOR ((w83877f_regs[0x15] >> 3) & 1)
|
|
|
|
|
#define GIO1CSH ((w83877f_regs[0x15] >> 4) & 1)
|
|
|
|
|
#define GIOP1MD ((w83877f_regs[0x15] >> 5) & 7)
|
|
|
|
|
|
|
|
|
|
#define HEFRAS (w83877f_regs[0x16] & 1)
|
|
|
|
|
#define IRIDE ((w83877f_regs[0x16] >> 1) & 1)
|
|
|
|
|
#define PNPCVS ((w83877f_regs[0x16] >> 2) & 1)
|
|
|
|
|
#define GMDRQ ((w83877f_regs[0x16] >> 3) & 1)
|
|
|
|
|
#define GOIQSEL ((w83877f_regs[0x16] >> 4) & 1)
|
|
|
|
|
|
|
|
|
|
#define DSUBLGRQ (w83877f_regs[0x17] & 1)
|
|
|
|
|
#define DSUALGRQ ((w83877f_regs[0x17] >> 1) & 1)
|
|
|
|
|
#define DSPRLGRQ ((w83877f_regs[0x17] >> 2) & 1)
|
|
|
|
|
#define DSFDLGRQ ((w83877f_regs[0x17] >> 3) & 1)
|
|
|
|
|
#define PRIRQOD ((w83877f_regs[0x17] >> 4) & 1)
|
|
|
|
|
|
|
|
|
|
#define GMAS (w83877f_regs[0x1E] & 3)
|
|
|
|
|
#define GMAD (w83877f_regs[0x1E] & 0xFC)
|
|
|
|
|
|
|
|
|
|
#define FDCAD ((w83877f_regs[0x20] & 0xFC) << 2)
|
|
|
|
|
|
|
|
|
|
/* Main IDE base address. */
|
|
|
|
|
#define IDE0AD ((w83877f_regs[0x21] & 0xFC) << 2)
|
|
|
|
|
/* IDE Alternate status base address. */
|
|
|
|
|
#define IDE1AD ((w83877f_regs[0x22] & 0xFC) << 2)
|
|
|
|
|
|
|
|
|
|
#define PRTAD (((uint16_t) w83877f_regs[0x23]) << 2)
|
|
|
|
|
|
|
|
|
|
#define URAAD (((uint16_t) w83877f_regs[0x24] & 0xFE) << 2)
|
|
|
|
|
#define URBAD (((uint16_t) w83877f_regs[0x25] & 0xFE) << 2)
|
|
|
|
|
|
|
|
|
|
#define PRTDQS (w83877f[regs[0x26] & 0xF)
|
|
|
|
|
#define FDCDQS (w83877f[regs[0x26] >> 4)
|
|
|
|
|
|
|
|
|
|
#define PRTIQS (w83877f[regs[0x27] & 0xF)
|
|
|
|
|
#define ECPIRQx (w83877f[regs[0x27] >> 5)
|
|
|
|
|
|
|
|
|
|
#define URBIQS (w83877f[regs[0x28] & 0xF)
|
|
|
|
|
#define URAIQS (w83877f[regs[0x28] >> 4)
|
|
|
|
|
|
|
|
|
|
#define IQNIQS (w83877f[regs[0x29] & 0xF)
|
|
|
|
|
#define FDCIQS (w83877f[regs[0x29] >> 4)
|
|
|
|
|
|
|
|
|
|
#define W83757 (!PRTMODS2 && !PRTMODS1 && !PRTMODS0)
|
|
|
|
|
#define EXTFDC (!PRTMODS2 && !PRTMODS1 && PRTMODS0)
|
|
|
|
|
#define EXTADP (!PRTMODS2 && PRTMODS1 && !PRTMODS0)
|
|
|
|
|
#define EXT2FDD (!PRTMODS2 && PRTMODS1 && PRTMODS0)
|
|
|
|
|
#define JOYSTICK (PRTMODS2 && !PRTMODS1 && !PRTMODS0)
|
|
|
|
|
#define EPP_SPP (PRTMODS2 && !PRTMODS1 && PRTMODS0)
|
|
|
|
|
#define ECP (PRTMODS2 && PRTMODS1 && !PRTMODS0)
|
|
|
|
|
#define ECP_EPP (PRTMODS2 && PRTMODS1 && PRTMODS0)
|
|
|
|
|
|
|
|
|
|
static uint16_t fdc_valid_ports[2] = {0x3F0, 0x370};
|
|
|
|
|
static uint16_t ide_valid_ports[2] = {0x1F0, 0x170};
|
|
|
|
|
static uint16_t ide_as_valid_ports[2] = {0x3F6, 0x376};
|
|
|
|
|
static uint16_t lpt1_valid_ports[3] = {0x3BC, 0x378, 0x278};
|
|
|
|
|
static uint16_t com1_valid_ports[9] = {0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
|
|
|
|
static uint16_t com2_valid_ports[9] = {0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
|
|
|
|
|
|
|
|
|
static void w83877f_remap()
|
|
|
|
|
{
|
|
|
|
|
io_removehandler(0x250, 0x0002, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, NULL);
|
|
|
|
|
io_removehandler(0x3f0, 0x0002, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, NULL);
|
|
|
|
|
io_sethandler(HEFRAS ? 0x3f0 : 0x250, 0x0002, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, NULL);
|
|
|
|
|
winbond_port = (HEFRAS ? 0x3f0 : 0x250);
|
|
|
|
|
winbond_key_times = HEFRAS + 1;
|
|
|
|
|
winbond_key = (HEFRAS ? 0x86 : 0x88) | HEFERE;
|
|
|
|
|
// pclog("W83877F mapped to %04X, with key %02X required %i times\n", winbond_port, winbond_key, winbond_key_times);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint8_t is_in_array(uint16_t *port_array, uint8_t max, uint16_t port)
|
|
|
|
|
{
|
|
|
|
|
uint8_t i = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < max; i++)
|
|
|
|
|
{
|
|
|
|
|
if (port_array[i] == port) return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint16_t make_port(uint8_t reg)
|
|
|
|
|
{
|
|
|
|
|
uint16_t p = 0;
|
|
|
|
|
|
|
|
|
|
switch(reg)
|
|
|
|
|
{
|
|
|
|
|
case 0x20:
|
|
|
|
|
p = ((uint16_t) (w83877f_regs[reg] & 0xfc)) << 2;
|
|
|
|
|
p &= 0xFF0;
|
|
|
|
|
if ((p < 0x100) || (p > 0x3F0)) p = 0x3F0;
|
|
|
|
|
if (!(is_in_array(fdc_valid_ports, 2, p))) p = 0x3F0;
|
|
|
|
|
w83877f_regs[reg] = ((p >> 2) & 0xfc) | (w83877f_regs[reg] & 3);
|
|
|
|
|
break;
|
|
|
|
|
case 0x21:
|
|
|
|
|
p = ((uint16_t) (w83877f_regs[reg] & 0xfc)) << 2;
|
|
|
|
|
p &= 0xFF0;
|
|
|
|
|
if ((p < 0x100) || (p > 0x3F0)) p = 0x1F0;
|
|
|
|
|
if (!(is_in_array(ide_valid_ports, 2, p))) p = 0x1F0;
|
|
|
|
|
w83877f_regs[reg] = ((p >> 2) & 0xfc) | (w83877f_regs[reg] & 3);
|
|
|
|
|
break;
|
|
|
|
|
case 0x22:
|
|
|
|
|
p = ((uint16_t) (w83877f_regs[reg] & 0xfc)) << 2;
|
|
|
|
|
p &= 0xFF0;
|
|
|
|
|
if ((p < 0x106) || (p > 0x3F6)) p = 0x3F6;
|
|
|
|
|
if (!(is_in_array(ide_as_valid_ports, 2, p))) p = 0x3F6;
|
|
|
|
|
w83877f_regs[reg] = ((p >> 2) & 0xfc) | (w83877f_regs[reg] & 3);
|
|
|
|
|
break;
|
|
|
|
|
case 0x23:
|
|
|
|
|
p = ((uint16_t) (w83877f_regs[reg] & 0xff)) << 2;
|
|
|
|
|
p &= 0xFFC;
|
|
|
|
|
if ((p < 0x100) || (p > 0x3F8)) p = 0x378;
|
|
|
|
|
if (!(is_in_array(lpt1_valid_ports, 3, p))) p = 0x378;
|
|
|
|
|
w83877f_regs[reg] = (p >> 2);
|
|
|
|
|
break;
|
|
|
|
|
case 0x24:
|
|
|
|
|
p = ((uint16_t) (w83877f_regs[reg] & 0xfe)) << 2;
|
|
|
|
|
p &= 0xFF8;
|
|
|
|
|
if ((p < 0x100) || (p > 0x3F8)) p = 0x3F8;
|
|
|
|
|
if (!(is_in_array(com1_valid_ports, 9, p))) p = 0x3F8;
|
|
|
|
|
w83877f_regs[reg] = ((p >> 2) & 0xfe) | (w83877f_regs[reg] & 1);
|
|
|
|
|
break;
|
|
|
|
|
case 0x25:
|
|
|
|
|
p = ((uint16_t) (w83877f_regs[reg] & 0xfe)) << 2;
|
|
|
|
|
p &= 0xFF8;
|
|
|
|
|
if ((p < 0x100) || (p > 0x3F8)) p = 0x2F8;
|
|
|
|
|
if (!(is_in_array(com2_valid_ports, 9, p))) p = 0x2F8;
|
|
|
|
|
w83877f_regs[reg] = ((p >> 2) & 0xfe) | (w83877f_regs[reg] & 1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// pclog("Made port %04X (reg %02X)\n", p, reg);
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void w83877f_write(uint16_t port, uint8_t val, void *priv)
|
|
|
|
|
{
|
|
|
|
|
uint8_t index = (port & 1) ? 0 : 1;
|
|
|
|
|
uint8_t valxor = 0;
|
|
|
|
|
uint8_t max = 0x2A;
|
|
|
|
|
int temp;
|
|
|
|
|
|
|
|
|
|
if (index)
|
|
|
|
|
{
|
|
|
|
|
// pclog("w83877f_write : port=%04x = %02X locked=%i\n", port, val, w83877f_locked);
|
|
|
|
|
|
|
|
|
|
if ((val == winbond_key) && !w83877f_locked)
|
|
|
|
|
{
|
|
|
|
|
if (winbond_key_times == 2)
|
|
|
|
|
{
|
|
|
|
|
if (tries)
|
|
|
|
|
{
|
|
|
|
|
// pclog("W83877F Locked (2 tries)\n");
|
|
|
|
|
w83877f_locked = 1;
|
|
|
|
|
// fdc_3f1_enable(0);
|
|
|
|
|
tries = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tries++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// pclog("W83877F Locked (1 try)\n");
|
|
|
|
|
w83877f_locked = 1;
|
|
|
|
|
// fdc_3f1_enable(0);
|
|
|
|
|
tries = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// pclog("w83877f_write : port=%04x reg %02X = %02X locked=%i\n", port, w83877f_curreg, val, w83877f_locked);
|
|
|
|
|
|
|
|
|
|
if (w83877f_locked)
|
|
|
|
|
{
|
|
|
|
|
if (val < max) w83877f_curreg = val;
|
|
|
|
|
if (val == 0xaa)
|
|
|
|
|
{
|
|
|
|
|
w83877f_locked = 0;
|
|
|
|
|
// fdc_3f1_enable(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (tries)
|
|
|
|
|
tries = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// pclog("w83877f_write : port=%04x reg %02X = %02X locked=%i\n", port, w83877f_curreg, val, w83877f_locked);
|
|
|
|
|
|
|
|
|
|
if (w83877f_locked)
|
|
|
|
|
{
|
|
|
|
|
if (w83877f_rw_locked) return;
|
|
|
|
|
if ((w83877f_curreg >= 0x26) && (w83877f_curreg <= 0x27)) return;
|
|
|
|
|
if (w83877f_curreg == 0x29) return;
|
|
|
|
|
if (w83877f_curreg == 6) val &= 0xF3;
|
|
|
|
|
valxor = val ^ w83877f_regs[w83877f_curreg];
|
|
|
|
|
w83877f_regs[w83877f_curreg] = val;
|
|
|
|
|
goto process_value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
process_value:
|
|
|
|
|
switch(w83877f_curreg)
|
|
|
|
|
{
|
2016-09-17 20:22:02 +02:00
|
|
|
case 1:
|
|
|
|
|
if (valxor & 0x80)
|
|
|
|
|
{
|
|
|
|
|
fdd_setswap((w83877f_regs[1] & 0x80) ? 1 : 0);
|
|
|
|
|
}
|
2016-06-26 00:34:39 +02:00
|
|
|
case 4:
|
|
|
|
|
if (valxor & 0x10)
|
|
|
|
|
{
|
|
|
|
|
serial2_remove();
|
|
|
|
|
if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF);
|
|
|
|
|
}
|
|
|
|
|
if (valxor & 0x20)
|
|
|
|
|
{
|
|
|
|
|
serial1_remove();
|
|
|
|
|
if (!(w83877f_regs[4] & 0x20))
|
|
|
|
|
{
|
|
|
|
|
serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8);
|
|
|
|
|
// mouse_serial_init();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (valxor & 0x80)
|
|
|
|
|
{
|
|
|
|
|
lpt1_remove();
|
|
|
|
|
if (!(w83877f_regs[4] & 0x80)) lpt1_init(make_port(0x23));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 6:
|
|
|
|
|
if (valxor & 0x08)
|
|
|
|
|
{
|
|
|
|
|
fdc_remove();
|
|
|
|
|
if (!(w83877f_regs[6] & 0x08)) fdc_add();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
|
|
|
|
// pclog("W83877F Write [Reg. %02X]: %02X\n", w83877f_curreg, val);
|
2016-07-25 21:32:37 +02:00
|
|
|
if (valxor & 3) fdc_update_rwc(0, FDDA_TYPE);
|
|
|
|
|
if (valxor & 0xC) fdc_update_rwc(1, FDDB_TYPE);
|
2016-06-26 00:34:39 +02:00
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
// pclog("W83877F Write [Reg. %02X]: %02X\n", w83877f_curreg, val);
|
|
|
|
|
if (valxor & 3) fdc_update_boot_drive(FD_BOOT);
|
|
|
|
|
if (valxor & 0x10) swwp = SWWP ? 1 : 0;
|
|
|
|
|
if (valxor & 0x20) disable_write = DISFDDWR ? 1 : 0;
|
|
|
|
|
break;
|
|
|
|
|
case 9:
|
|
|
|
|
// pclog("W83877F Write [Reg. %02X]: %02X\n", w83877f_curreg, val);
|
|
|
|
|
if (valxor & 0x20)
|
|
|
|
|
{
|
|
|
|
|
fdc_update_enh_mode(EN3MODE ? 1 : 0);
|
|
|
|
|
}
|
|
|
|
|
if (valxor & 0x40)
|
|
|
|
|
{
|
|
|
|
|
w83877f_rw_locked = (val & 0x40) ? 1 : 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0xB:
|
|
|
|
|
// pclog("W83877F Write [Reg. %02X]: %02X\n", w83877f_curreg, val);
|
|
|
|
|
if (valxor & 1) fdc_update_drv2en(DRV2EN_NEG ? 0 : 1);
|
|
|
|
|
if (valxor & 2) fdc_update_densel_polarity(INVERTZ ? 1 : 0);
|
|
|
|
|
break;
|
|
|
|
|
case 0xC:
|
|
|
|
|
if (valxor & 0x20) w83877f_remap();
|
|
|
|
|
break;
|
|
|
|
|
case 0x16:
|
|
|
|
|
if (valxor & 1) w83877f_remap();
|
|
|
|
|
break;
|
|
|
|
|
case 0x23:
|
|
|
|
|
if (valxor)
|
|
|
|
|
{
|
|
|
|
|
lpt1_remove();
|
|
|
|
|
if (!(w83877f_regs[4] & 0x80)) lpt1_init(make_port(0x23));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0x24:
|
|
|
|
|
if (valxor & 0xfe)
|
|
|
|
|
{
|
|
|
|
|
if (!(w83877f_regs[4] & 0x20))
|
|
|
|
|
{
|
|
|
|
|
serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8);
|
|
|
|
|
// mouse_serial_init();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0x25:
|
|
|
|
|
if (valxor & 0xfe)
|
|
|
|
|
{
|
|
|
|
|
if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0x28:
|
|
|
|
|
if (valxor & 0xf)
|
|
|
|
|
{
|
|
|
|
|
if ((w83877f_regs[0x28] & 0xf) == 0) w83877f_regs[0x28] |= 0x3;
|
|
|
|
|
if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF);
|
|
|
|
|
}
|
|
|
|
|
if (valxor & 0xf0)
|
|
|
|
|
{
|
|
|
|
|
if ((w83877f_regs[0x28] & 0xf0) == 0) w83877f_regs[0x28] |= 0x40;
|
|
|
|
|
if (!(w83877f_regs[4] & 0x20))
|
|
|
|
|
{
|
|
|
|
|
serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8);
|
|
|
|
|
// mouse_serial_init();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t w83877f_read(uint16_t port, void *priv)
|
|
|
|
|
{
|
|
|
|
|
uint8_t index = (port & 1) ? 0 : 1;
|
|
|
|
|
|
|
|
|
|
if (!w83877f_locked)
|
|
|
|
|
{
|
|
|
|
|
// pclog("w83877f_read : port=%04x = FF locked=%i\n", port, w83877f_locked);
|
|
|
|
|
return 0xff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (index)
|
|
|
|
|
{
|
|
|
|
|
// pclog("w83877f_read : port=%04x = %02X locked=%i\n", port, w83877f_curreg, w83877f_locked);
|
|
|
|
|
return w83877f_curreg;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((w83877f_curreg < 0x18) && w83877f_rw_locked) return 0xff;
|
|
|
|
|
if (w83877f_curreg == 7)
|
|
|
|
|
{
|
|
|
|
|
// pclog("w83877f_read : port=%04x reg %02X = %02X locked=%i\n", port, w83877f_curreg, (fdc_get_rwc(0) | (fdc_get_rwc(1) << 2)), w83877f_locked);
|
|
|
|
|
return (fdc_get_rwc(0) | (fdc_get_rwc(1) << 2));
|
|
|
|
|
}
|
|
|
|
|
// pclog("w83877f_read : port=%04x reg %02X = %02X locked=%i\n", port, w83877f_curreg, w83877f_regs[w83877f_curreg], w83877f_locked);
|
|
|
|
|
return w83877f_regs[w83877f_curreg];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void w83877f_init()
|
|
|
|
|
{
|
|
|
|
|
fdc_remove();
|
|
|
|
|
fdc_add_for_superio();
|
|
|
|
|
lpt1_remove();
|
|
|
|
|
lpt1_init(0x378);
|
|
|
|
|
lpt2_remove();
|
|
|
|
|
w83877f_regs[3] = 0x30;
|
|
|
|
|
w83877f_regs[7] = 0xF5;
|
|
|
|
|
w83877f_regs[9] = 0x0A;
|
|
|
|
|
w83877f_regs[0xA] = 0x1F;
|
|
|
|
|
w83877f_regs[0xC] = 0x28;
|
|
|
|
|
w83877f_regs[0xD] = 0xA3;
|
|
|
|
|
w83877f_regs[0x16] = 5;
|
|
|
|
|
w83877f_regs[0x1E] = 0x81;
|
|
|
|
|
w83877f_regs[0x20] = (0x3f0 >> 2) & 0xfc;
|
|
|
|
|
w83877f_regs[0x21] = (0x1f0 >> 2) & 0xfc;
|
|
|
|
|
w83877f_regs[0x22] = ((0x3f6 >> 2) & 0xfc) | 1;
|
|
|
|
|
w83877f_regs[0x23] = (0x378 >> 2);
|
|
|
|
|
w83877f_regs[0x24] = (0x3f8 >> 2) & 0xfe;
|
|
|
|
|
w83877f_regs[0x25] = (0x2f8 >> 2) & 0xfe;
|
|
|
|
|
w83877f_regs[0x26] = (2 << 4) | 4;
|
|
|
|
|
w83877f_regs[0x27] = (6 << 4) | 7;
|
|
|
|
|
w83877f_regs[0x28] = (4 << 4) | 3;
|
|
|
|
|
w83877f_regs[0x29] = 0x62;
|
|
|
|
|
|
|
|
|
|
fdc_update_densel_polarity(1);
|
|
|
|
|
fdc_update_densel_force(0);
|
|
|
|
|
fdc_update_rwc(0, 1);
|
|
|
|
|
fdc_update_rwc(1, 1);
|
|
|
|
|
fdc_update_drvrate(0, 0);
|
|
|
|
|
fdc_update_drvrate(1, 0);
|
|
|
|
|
fdc_update_enh_mode(0);
|
2016-09-14 23:18:14 +02:00
|
|
|
fdc_update_max_track(85);
|
2016-06-26 00:34:39 +02:00
|
|
|
swwp = 0;
|
|
|
|
|
disable_write = 0;
|
|
|
|
|
fdc_update_drv2en(1);
|
2016-09-17 20:22:02 +02:00
|
|
|
fdd_setswap(0);
|
2016-06-26 00:34:39 +02:00
|
|
|
serial1_set(0x3f8, 4);
|
|
|
|
|
serial2_set(0x2f8, 3);
|
|
|
|
|
w83877f_remap();
|
|
|
|
|
w83877f_locked = 0;
|
|
|
|
|
w83877f_rw_locked = 0;
|
|
|
|
|
}
|