Fixed PS/2 mouse to PCI (PIIX) wiring, fixes recently introduced PS/2 mouse hangs;
The AT keyboard "write to mouse" command now returns 0xFF (error) when no PS/2 mouse is attached - fixes hangs on AOpen AP53, ASUS P/I-P55T2S, and Tyan Titan Pro/ATX when not using PS/2 mouse; Fixed the emulation of the SMC FDC37C669 Super I/O chip - serial ports now work correctly on the AOpen AP53 and the ASUS P/I-P55T2S.
This commit is contained in:
@@ -28,6 +28,9 @@
|
||||
#include "sound/snd_speaker.h"
|
||||
#include "keyboard.h"
|
||||
#include "keyboard_at.h"
|
||||
#include "cpu/cpu.h"
|
||||
#include "device.h"
|
||||
#include "machine/machine.h"
|
||||
|
||||
|
||||
#define STAT_PARITY 0x80
|
||||
@@ -96,36 +99,12 @@ static int key_queue_start = 0, key_queue_end = 0;
|
||||
static uint8_t mouse_queue[16];
|
||||
int mouse_queue_start = 0, mouse_queue_end = 0;
|
||||
|
||||
static uint8_t mouse_enabled;
|
||||
|
||||
int first_write = 1;
|
||||
int dtrans = 0;
|
||||
|
||||
/* Bits 0 - 1 = scan code set, bit 6 = translate or not. */
|
||||
uint8_t mode = 0x42;
|
||||
|
||||
#if 0
|
||||
/* Translated to non-translated scan codes. */
|
||||
/* Assuming we get XSET1, SET1/XSET2/XSET3 = T_TO_NONT(XSET1), and then we go through
|
||||
T_TO_NONT again to get SET2/SET3. */
|
||||
/* static uint8_t t_to_nont[256] = { 0xFF, 0x76, 0x16, 0x1E, 0x26, 0x25, 0x2E, 0x36, 0x3D, 0x3E, 0x46, 0x45, 0x4E, 0x55, 0x66, 0x0D,
|
||||
0x15, 0x1D, 0x24, 0x2D, 0x2C, 0x35, 0x3C, 0x43, 0x44, 0x4D, 0x54, 0x5B, 0x5A, 0x14, 0x1C, 0x1B,
|
||||
0x23, 0x2B, 0x34, 0x33, 0x3B, 0x42, 0x4B, 0x4C, 0x52, 0x0E, 0x12, 0x5D, 0x1A, 0x22, 0x21, 0x2A,
|
||||
0x32, 0x31, 0x3A, 0x41, 0x49, 0x4A, 0x59, 0x7C, 0x11, 0x29, 0x58, 0x05, 0x06, 0x04, 0x0C, 0x03,
|
||||
0x0B, 0x02, 0x0A, 0x01, 0x09, 0x77, 0x7E, 0x6C, 0x75, 0x7D, 0x7B, 0x6B, 0x73, 0x74, 0x79, 0x69,
|
||||
0x72, 0x7A, 0x70, 0x71, 0x7F, 0x60, 0x61, 0x78, 0x07, 0x0F, 0x17, 0x1F, 0x27, 0x2F, 0x37, 0x3F,
|
||||
0x47, 0x4F, 0x56, 0x5E, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x40, 0x48, 0x50, 0x57, 0x6F,
|
||||
0x13, 0x19, 0x39, 0x51, 0x53, 0x5C, 0x5F, 0x62, 0x63, 0x64, 0x65, 0x67, 0x68, 0x6A, 0x6D, 0x6E,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; */
|
||||
#endif
|
||||
|
||||
/* Non-translated to translated scan codes. */
|
||||
static uint8_t nont_to_t[256] = { 0xFF, 0x43, 0x41, 0x3F, 0x3D, 0x3B, 0x3C, 0x58, 0x64, 0x44, 0x42, 0x40, 0x3E, 0x0F, 0x29, 0x59,
|
||||
0x65, 0x38, 0x2A, 0x70, 0x1D, 0x10, 0x02, 0x5A, 0x66, 0x71, 0x2C, 0x1F, 0x1E, 0x11, 0x03, 0x5B,
|
||||
@@ -144,16 +123,33 @@ static uint8_t nont_to_t[256] = { 0xFF, 0x43, 0x41, 0x3F, 0x3D, 0x3B, 0x3C, 0x58
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF };
|
||||
|
||||
int keyboard_at_do_log = 0;
|
||||
|
||||
void keyboard_at_log(const char *format, ...)
|
||||
{
|
||||
#ifdef ENABLE_KEYBOARD_AT_LOG
|
||||
if (keyboard_at_do_log)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vprintf(format, ap);
|
||||
va_end(ap);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void keyboard_at_poll(void)
|
||||
{
|
||||
keybsenddelay += (1000 * TIMER_USEC);
|
||||
|
||||
if (keyboard_at.out_new != -1 && !keyboard_at.last_irq)
|
||||
if ((keyboard_at.out_new != -1) && !keyboard_at.last_irq)
|
||||
{
|
||||
keyboard_at.wantirq = 0;
|
||||
if (keyboard_at.out_new & 0x100)
|
||||
{
|
||||
if ((keyboard_at.mem[0] & 0x02) && mouse_enabled)
|
||||
keyboard_at_log("Want mouse data\n");
|
||||
if (keyboard_at.mem[0] & 0x02)
|
||||
picint(0x1000);
|
||||
keyboard_at.out = keyboard_at.out_new & 0xff;
|
||||
keyboard_at.out_new = -1;
|
||||
@@ -164,6 +160,7 @@ static void keyboard_at_poll(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboard_at_log("Want keyboard data\n");
|
||||
if (keyboard_at.mem[0] & 0x01)
|
||||
picint(2);
|
||||
keyboard_at.out = keyboard_at.out_new;
|
||||
@@ -181,14 +178,14 @@ static void keyboard_at_poll(void)
|
||||
keyboard_at.out_new = key_ctrl_queue[key_ctrl_queue_start];
|
||||
key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf;
|
||||
}
|
||||
else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && /*!(keyboard_at.mem[0] & 0x20) &&*/
|
||||
mouse_queue_start != mouse_queue_end)
|
||||
else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1/* && !(keyboard_at.mem[0] & 0x20)*/ &&
|
||||
(mouse_queue_start != mouse_queue_end))
|
||||
{
|
||||
keyboard_at.out_new = mouse_queue[mouse_queue_start] | 0x100;
|
||||
mouse_queue_start = (mouse_queue_start + 1) & 0xf;
|
||||
}
|
||||
else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 &&
|
||||
!(keyboard_at.mem[0] & 0x10) && key_queue_start != key_queue_end)
|
||||
!(keyboard_at.mem[0] & 0x10) && (key_queue_start != key_queue_end))
|
||||
{
|
||||
keyboard_at.out_new = key_queue[key_queue_start];
|
||||
key_queue_start = (key_queue_start + 1) & 0xf;
|
||||
@@ -279,6 +276,8 @@ write_register:
|
||||
if (!(val & 1) && keyboard_at.wantirq)
|
||||
keyboard_at.wantirq = 0;
|
||||
mouse_scan = !(val & 0x20);
|
||||
keyboard_at_log("Mouse is now %s\n", mouse_scan ? "enabled" : "disabled");
|
||||
keyboard_at_log("Mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled");
|
||||
|
||||
/* Addition by OBattler: Scan code translate ON/OFF. */
|
||||
mode &= 0x93;
|
||||
@@ -304,6 +303,7 @@ write_register:
|
||||
break;
|
||||
|
||||
case 0xaf: /*AMI - set extended controller RAM*/
|
||||
keyboard_at_log("AMI - set extended controller RAM\n");
|
||||
if (keyboard_at.secr_phase == 0)
|
||||
{
|
||||
goto bad_command;
|
||||
@@ -322,15 +322,18 @@ write_register:
|
||||
break;
|
||||
|
||||
case 0xcb: /*AMI - set keyboard mode*/
|
||||
keyboard_at_log("AMI - set keyboard mode\n");
|
||||
break;
|
||||
|
||||
case 0xcf: /*??? - sent by MegaPC BIOS*/
|
||||
keyboard_at_log("??? - sent by MegaPC BIOS\n");
|
||||
/* To make sure the keyboard works correctly on the MegaPC. */
|
||||
mode &= 0xFC;
|
||||
mode |= 2;
|
||||
break;
|
||||
|
||||
case 0xd1: /*Write output port*/
|
||||
keyboard_at_log("Write output port\n");
|
||||
if ((keyboard_at.output_port ^ val) & 0x02) /*A20 enable change*/
|
||||
{
|
||||
mem_a20_key = val & 0x02;
|
||||
@@ -341,21 +344,26 @@ write_register:
|
||||
break;
|
||||
|
||||
case 0xd2: /*Write to keyboard output buffer*/
|
||||
keyboard_at_log("Write to keyboard output buffer\n");
|
||||
keyboard_at_adddata_keyboard(val);
|
||||
break;
|
||||
|
||||
case 0xd3: /*Write to mouse output buffer*/
|
||||
keyboard_at_log("Write to mouse output buffer\n");
|
||||
keyboard_at_adddata_mouse(val);
|
||||
break;
|
||||
|
||||
case 0xd4: /*Write to mouse*/
|
||||
if (keyboard_at.mouse_write)
|
||||
keyboard_at_log("Write to mouse (%02X)\n", val);
|
||||
if (keyboard_at.mouse_write && (machines[machine].flags & MACHINE_PS2))
|
||||
keyboard_at.mouse_write(val, keyboard_at.mouse_p);
|
||||
else
|
||||
keyboard_at_adddata_mouse(0xff);
|
||||
break;
|
||||
|
||||
default:
|
||||
bad_command:
|
||||
pclog("Bad AT keyboard controller 0060 write %02X command %02X\n", val, keyboard_at.command);
|
||||
keyboard_at_log("Bad AT keyboard controller 0060 write %02X command %02X\n", val, keyboard_at.command);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -392,7 +400,7 @@ bad_command:
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("Bad AT keyboard 0060 write %02X command %02X\n", val, keyboard_at.key_command);
|
||||
keyboard_at_log("Bad AT keyboard 0060 write %02X command %02X\n", val, keyboard_at.key_command);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -493,7 +501,7 @@ bad_command:
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("Bad AT keyboard command %02X\n", val);
|
||||
keyboard_at_log("Bad AT keyboard command %02X\n", val);
|
||||
keyboard_at_adddata_keyboard(0xfe);
|
||||
}
|
||||
}
|
||||
@@ -554,22 +562,50 @@ bad_command:
|
||||
keyboard_at.want60 = 1;
|
||||
break;
|
||||
|
||||
case 0xa1: /*AMI - get controlled version*/
|
||||
case 0xa1: /*AMI - get controller version*/
|
||||
keyboard_at_log("AMI - get controller version\n");
|
||||
break;
|
||||
|
||||
case 0xa7: /*Disable mouse port*/
|
||||
mouse_scan = 0;
|
||||
if (machines[machine].flags & MACHINE_PS2)
|
||||
{
|
||||
keyboard_at_log("Disable mouse port\n");
|
||||
mouse_scan = 0;
|
||||
keyboard_at.mem[0] |= 0x20;
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboard_at_log("Write Cache Bad\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa8: /*Enable mouse port*/
|
||||
mouse_scan = 1;
|
||||
if (machines[machine].flags & MACHINE_PS2)
|
||||
{
|
||||
keyboard_at_log("Enable mouse port\n");
|
||||
mouse_scan = 1;
|
||||
keyboard_at.mem[0] &= 0xDF;
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboard_at_log("Write Cache Good\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa9: /*Test mouse port*/
|
||||
keyboard_at_adddata(0x00); /*no error*/
|
||||
keyboard_at_log("Test mouse port\n");
|
||||
if (machines[machine].flags & MACHINE_PS2)
|
||||
{
|
||||
keyboard_at_adddata(0x00); /*no error*/
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboard_at_adddata(0xff); /*no mouse*/
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xaa: /*Self-test*/
|
||||
keyboard_at_log("Self-test\n");
|
||||
if (!keyboard_at.initialised)
|
||||
{
|
||||
keyboard_at.initialised = 1;
|
||||
@@ -590,10 +626,12 @@ bad_command:
|
||||
break;
|
||||
|
||||
case 0xab: /*Interface test*/
|
||||
keyboard_at_log("Interface test\n");
|
||||
keyboard_at_adddata(0x00); /*no error*/
|
||||
break;
|
||||
|
||||
case 0xac: /*Diagnostic dump*/
|
||||
keyboard_at_log("Diagnostic dump\n");
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
keyboard_at_adddata(keyboard_at.mem[i]);
|
||||
@@ -604,10 +642,12 @@ bad_command:
|
||||
break;
|
||||
|
||||
case 0xad: /*Disable keyboard*/
|
||||
keyboard_at_log("Disable keyboard\n");
|
||||
keyboard_at.mem[0] |= 0x10;
|
||||
break;
|
||||
|
||||
case 0xae: /*Enable keyboard*/
|
||||
keyboard_at_log("Enable keyboard\n");
|
||||
keyboard_at.mem[0] &= ~0x10;
|
||||
break;
|
||||
|
||||
@@ -628,12 +668,14 @@ bad_command:
|
||||
case ROM_AP53:
|
||||
case ROM_P55T2S:
|
||||
case ROM_S1668:
|
||||
/*Set extended controlled RAM*/
|
||||
/*Set extended controller RAM*/
|
||||
keyboard_at_log("Set extended controller RAM\n");
|
||||
keyboard_at.want60 = 1;
|
||||
keyboard_at.secr_phase = 1;
|
||||
break;
|
||||
default:
|
||||
/*Read keyboard version*/
|
||||
keyboard_at_log("Read keyboard version\n");
|
||||
keyboard_at_adddata(0x00);
|
||||
break;
|
||||
}
|
||||
@@ -642,60 +684,74 @@ bad_command:
|
||||
case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
|
||||
case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
|
||||
/*Set keyboard lines low (B0-B7) or high (B8-BF)*/
|
||||
keyboard_at_log("Set keyboard lines low (B0-B7) or high (B8-BF)\n");
|
||||
keyboard_at_adddata(0x00);
|
||||
break;
|
||||
|
||||
case 0xc0: /*Read input port*/
|
||||
keyboard_at_log("Read input port\n");
|
||||
keyboard_at_adddata(keyboard_at.input_port | 4 | fdc_ps1_525());
|
||||
keyboard_at.input_port = ((keyboard_at.input_port + 1) & 3) | (keyboard_at.input_port & 0xfc) | fdc_ps1_525();
|
||||
break;
|
||||
|
||||
case 0xc1: /*Copy bits 0 to 3 of input port to status bits 4 to 7*/
|
||||
keyboard_at_log("Copy bits 0 to 3 of input port to status bits 4 to 7\n");
|
||||
keyboard_at.status &= 0xf;
|
||||
keyboard_at.status |= ((((keyboard_at.input_port & 0xfc) | 0x84 | fdc_ps1_525()) & 0xf) << 4);
|
||||
break;
|
||||
|
||||
case 0xc2: /*Copy bits 4 to 7 of input port to status bits 4 to 7*/
|
||||
keyboard_at_log("Copy bits 4 to 7 of input port to status bits 4 to 7\n");
|
||||
keyboard_at.status &= 0xf;
|
||||
keyboard_at.status |= (((keyboard_at.input_port & 0xfc) | 0x84 | fdc_ps1_525()) & 0xf0);
|
||||
break;
|
||||
|
||||
case 0xc9: /*AMI - block P22 and P23 ??? */
|
||||
case 0xc9: /*AMI - block P22 and P23 ???*/
|
||||
keyboard_at_log("AMI - block P22 and P23 ???\n");
|
||||
break;
|
||||
|
||||
case 0xca: /*AMI - read keyboard mode*/
|
||||
keyboard_at_log("AMI - read keyboard mode\n");
|
||||
keyboard_at_adddata(0x00); /*ISA mode*/
|
||||
break;
|
||||
|
||||
case 0xcb: /*AMI - set keyboard mode*/
|
||||
keyboard_at_log("AMI - set keyboard mode\n");
|
||||
keyboard_at.want60 = 1;
|
||||
break;
|
||||
|
||||
case 0xcf: /*??? - sent by MegaPC BIOS*/
|
||||
keyboard_at_log("??? - sent by MegaPC BIOS\n");
|
||||
keyboard_at.want60 = 1;
|
||||
break;
|
||||
|
||||
case 0xd0: /*Read output port*/
|
||||
keyboard_at_log("Read output port\n");
|
||||
keyboard_at_adddata(keyboard_at.output_port);
|
||||
break;
|
||||
|
||||
case 0xd1: /*Write output port*/
|
||||
keyboard_at_log("Write output port\n");
|
||||
keyboard_at.want60 = 1;
|
||||
break;
|
||||
|
||||
case 0xd2: /*Write keyboard output buffer*/
|
||||
keyboard_at_log("Write keyboard output buffer\n");
|
||||
keyboard_at.want60 = 1;
|
||||
break;
|
||||
|
||||
case 0xd3: /*Write mouse output buffer*/
|
||||
keyboard_at_log("Write mouse output buffer\n");
|
||||
keyboard_at.want60 = 1;
|
||||
break;
|
||||
|
||||
case 0xd4: /*Write to mouse*/
|
||||
keyboard_at_log("Write to mouse\n");
|
||||
keyboard_at.want60 = 1;
|
||||
break;
|
||||
|
||||
case 0xdd: /* Disable A20 Address Line */
|
||||
keyboard_at_log("Disable A20 Address Line\n");
|
||||
keyboard_at.output_port &= ~0x02;
|
||||
mem_a20_key = 0;
|
||||
mem_a20_recalc();
|
||||
@@ -703,6 +759,7 @@ bad_command:
|
||||
break;
|
||||
|
||||
case 0xdf: /* Enable A20 Address Line */
|
||||
keyboard_at_log("Enable A20 Address Line\n");
|
||||
keyboard_at.output_port |= 0x02;
|
||||
mem_a20_key = 2;
|
||||
mem_a20_recalc();
|
||||
@@ -710,14 +767,17 @@ bad_command:
|
||||
break;
|
||||
|
||||
case 0xe0: /*Read test inputs*/
|
||||
keyboard_at_log("Read test inputs\n");
|
||||
keyboard_at_adddata(0x00);
|
||||
break;
|
||||
|
||||
case 0xef: /*??? - sent by AMI486*/
|
||||
keyboard_at_log("??? - sent by AMI486\n");
|
||||
break;
|
||||
|
||||
case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
|
||||
case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
|
||||
keyboard_at_log("Pulse\n");
|
||||
if (!(val & 1))
|
||||
{
|
||||
/* Pin 0 selected. */
|
||||
@@ -728,15 +788,31 @@ bad_command:
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("Bad AT keyboard controller command %02X\n", val);
|
||||
keyboard_at_log("Bad AT keyboard controller command %02X\n", val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_at_mouse_set_enabled(uint8_t enabled)
|
||||
uint8_t keyboard_at_get_mouse_scan(void)
|
||||
{
|
||||
/* pclog("Keyboard AT mouse: %i\n", enabled); */
|
||||
mouse_enabled = enabled;
|
||||
return mouse_scan ? 0x10 : 0x00;
|
||||
}
|
||||
|
||||
void keyboard_at_set_mouse_scan(uint8_t val)
|
||||
{
|
||||
uint8_t temp_mouse_scan = val ? 1 : 0;
|
||||
|
||||
if (temp_mouse_scan == mouse_scan)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mouse_scan = val ? 1 : 0;
|
||||
|
||||
keyboard_at.mem[0] &= 0xDF;
|
||||
keyboard_at.mem[0] |= (val ? 0x00 : 0x20);
|
||||
|
||||
keyboard_at_log("Mouse scan %sabled via PCI\n", mouse_scan ? "en" : "dis");
|
||||
}
|
||||
|
||||
uint8_t keyboard_at_read(uint16_t port, void *priv)
|
||||
@@ -747,16 +823,7 @@ uint8_t keyboard_at_read(uint16_t port, void *priv)
|
||||
case 0x60:
|
||||
temp = keyboard_at.out;
|
||||
keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/);
|
||||
if (PCI)
|
||||
{
|
||||
/* The PIIX/PIIX3 datasheet mandates that both of these interrupts are cleared on any read of port 0x60. */
|
||||
picintc(1 << 1);
|
||||
if (mouse_enabled)
|
||||
{
|
||||
picintc(1 << 12);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (keyboard_at.last_irq != 0x1000)
|
||||
{
|
||||
picintc(keyboard_at.last_irq);
|
||||
}
|
||||
@@ -789,7 +856,7 @@ void keyboard_at_reset(void)
|
||||
{
|
||||
keyboard_at.initialised = 0;
|
||||
keyboard_at.status = STAT_LOCK | STAT_CD;
|
||||
keyboard_at.mem[0] = 0x11;
|
||||
keyboard_at.mem[0] = 0x31;
|
||||
mode = 0x02 | dtrans;
|
||||
keyboard_at.default_mode = 2;
|
||||
first_write = 1;
|
||||
@@ -804,6 +871,8 @@ void keyboard_at_reset(void)
|
||||
|
||||
keyboard_scan = 1;
|
||||
|
||||
mouse_scan = 0;
|
||||
|
||||
sc_or = 0;
|
||||
|
||||
memset(set3_flags, 0, 272);
|
||||
|
@@ -27,4 +27,5 @@ extern void keyboard_at_reset(void);
|
||||
extern void keyboard_at_adddata_keyboard_raw(uint8_t val);
|
||||
extern void keyboard_at_adddata_mouse(uint8_t val);
|
||||
extern void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p);
|
||||
extern void keyboard_at_mouse_set_enabled(uint8_t enabled);
|
||||
uint8_t keyboard_at_get_mouse_scan(void);
|
||||
void keyboard_at_set_mouse_scan(uint8_t val);
|
||||
|
@@ -136,10 +136,10 @@ machine_t machines[] =
|
||||
|
||||
{"[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_AT | MACHINE_PS2 | MACHINE_HAS_IDE | MACHINE_PCI, 1, 128, 1, 127, machine_at_plato_init, NULL },
|
||||
|
||||
{"[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_AT | MACHINE_PS2 | MACHINE_HAS_IDE | MACHINE_PCI, 1, 256, 1, 127, machine_at_p54tp4xe_init, NULL },
|
||||
{"[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_AT | MACHINE_HAS_IDE | MACHINE_PCI, 1, 256, 1, 127, machine_at_p54tp4xe_init, NULL },
|
||||
{"[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_AT | MACHINE_PS2 | MACHINE_HAS_IDE | MACHINE_PCI, 1, 128, 1, 127, machine_at_endeavor_init, NULL },
|
||||
{"[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_AT | MACHINE_PS2 | MACHINE_HAS_IDE | MACHINE_PCI, 1, 128, 1, 127, machine_at_zappa_init, NULL },
|
||||
{"[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_AT | MACHINE_PS2 | MACHINE_HAS_IDE | MACHINE_PCI, 1, 128, 1, 127, machine_at_mb500n_init, NULL },
|
||||
{"[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_AT | MACHINE_HAS_IDE | MACHINE_PCI, 1, 128, 1, 127, machine_at_mb500n_init, NULL },
|
||||
{"[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_AT | MACHINE_HAS_IDE | MACHINE_PCI, 1, 128, 1, 127, machine_at_president_init, NULL },
|
||||
|
||||
{"[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_AT | MACHINE_PS2 | MACHINE_HAS_IDE | MACHINE_PCI, 1, 256, 1, 127, machine_at_thor_init, NULL },
|
||||
|
@@ -127,7 +127,7 @@ void mouse_ps2_write(uint8_t val, void *p)
|
||||
keyboard_at_adddata_mouse(0xaa);
|
||||
keyboard_at_adddata_mouse(0x00);
|
||||
break;
|
||||
|
||||
|
||||
// default:
|
||||
// fatal("mouse_ps2 : Bad command %02X\n", val, mouse->command);
|
||||
}
|
||||
|
@@ -42,12 +42,12 @@ static pci_mirq_t pci_mirqs[2];
|
||||
static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key;
|
||||
int pci_burst_time, pci_nonburst_time;
|
||||
|
||||
int pci_do_log = 0;
|
||||
|
||||
static int trc_reg = 0;
|
||||
|
||||
PCI_RESET pci_reset_handler;
|
||||
|
||||
int pci_do_log = 0;
|
||||
|
||||
void pci_log(const char *format, ...)
|
||||
{
|
||||
#ifdef ENABLE_PCI_LOG
|
||||
|
10
src/pic.c
10
src/pic.c
@@ -214,6 +214,7 @@ void pic2_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 1: /*ICW2*/
|
||||
pic2.vector=val&0xF8;
|
||||
pclog("PIC2 vector now: %02X\n", pic2.vector);
|
||||
if (pic2.icw1&2) pic2.icw=3;
|
||||
else pic2.icw=2;
|
||||
break;
|
||||
@@ -378,6 +379,14 @@ void picintc(uint16_t num)
|
||||
pic_updatepending();
|
||||
}
|
||||
|
||||
/* TODO: Verify this whole level-edge thing... edge/level mode is supposedly handled by bit 3 of ICW1,
|
||||
but the PIIX spec mandates it being able to be edge/level per IRQ... maybe the PCI-era on-board
|
||||
PIC ignores bit 3 of ICW1 but instead uses whatever is set in ELCR?
|
||||
|
||||
Edit: Yes, the PIIX (and I suppose also the SIO) disables bit 3 of ICW1 and instead, uses the ELCR.
|
||||
|
||||
Also, shouldn't there be only one picint(), and then edge/level is handled on processing? */
|
||||
|
||||
static uint8_t pic_process_interrupt(PIC* target_pic, int c)
|
||||
{
|
||||
uint8_t pending = target_pic->pend & ~target_pic->mask;
|
||||
@@ -441,6 +450,7 @@ uint8_t picinterrupt()
|
||||
for (c = 8; c <= 15; c++)
|
||||
{
|
||||
ret = pic_process_interrupt(&pic2, c);
|
||||
pclog("Processing IRQ %i: %02X\n", c, ret);
|
||||
if (ret != 0xFF) return ret;
|
||||
}
|
||||
}
|
||||
|
12
src/piix.c
12
src/piix.c
@@ -200,10 +200,7 @@ void piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
}
|
||||
else if (addr == 0x4E)
|
||||
{
|
||||
if ((val ^ card_piix[addr]) & 0x10)
|
||||
{
|
||||
keyboard_at_mouse_set_enabled((val & 0x10) ? 1 : 0);
|
||||
}
|
||||
keyboard_at_set_mouse_scan((val & 0x10) ? 1 : 0);
|
||||
card_piix[addr] = val;
|
||||
}
|
||||
else if (addr == 0x6A)
|
||||
@@ -304,6 +301,10 @@ uint8_t piix_read(int func, int addr, void *priv)
|
||||
else if (piix_type == 3)
|
||||
return card_piix[addr];
|
||||
}
|
||||
else if (addr == 0x4E)
|
||||
{
|
||||
return (card_piix[addr] & 0xEF) | keyboard_at_get_mouse_scan();
|
||||
}
|
||||
else if (addr == 0x69)
|
||||
{
|
||||
return card_piix[addr] & 0xFE;
|
||||
@@ -693,7 +694,8 @@ void piix3_reset(void)
|
||||
card_piix[0x09] = 0x00; card_piix[0x0a] = 0x01; card_piix[0x0b] = 0x06;
|
||||
card_piix[0x0e] = 0x80; /*Multi-function device*/
|
||||
card_piix[0x4c] = 0x4d;
|
||||
card_piix[0x4e] = card_piix[0x4f] = 0x03;
|
||||
card_piix[0x4e] = 0x03;
|
||||
card_piix[0x4f] = 0x00;
|
||||
card_piix[0x60] = card_piix[0x61] = card_piix[0x62] = card_piix[0x63] = 0x80;
|
||||
card_piix[0x69] = 0x02;
|
||||
card_piix[0x70] = 0xc0;
|
||||
|
@@ -30,74 +30,34 @@ static int fdc37c669_curreg = 0;
|
||||
static uint8_t fdc37c669_regs[42];
|
||||
static uint8_t tries;
|
||||
|
||||
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, 0x338, 0x3E8, 0x2E8, 0x220, 0x238, 0x2E0, 0x228};
|
||||
static uint16_t com2_valid_ports[9] = {0x3F8, 0x2F8, 0x338, 0x3E8, 0x2E8, 0x220, 0x238, 0x2E0, 0x228};
|
||||
|
||||
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;
|
||||
|
||||
uint16_t mask = 0;
|
||||
|
||||
switch(reg)
|
||||
{
|
||||
case 0x20:
|
||||
p = ((uint16_t) (fdc37c669_regs[reg] & 0xfc)) << 2;
|
||||
p &= 0xFF0;
|
||||
if ((p < 0x100) || (p > 0x3F0)) p = 0x3F0;
|
||||
if (!(is_in_array(fdc_valid_ports, 2, p))) p = 0x3F0;
|
||||
fdc37c669_regs[reg] = ((p >> 2) & 0xfc) | (fdc37c669_regs[reg] & 3);
|
||||
break;
|
||||
case 0x21:
|
||||
p = ((uint16_t) (fdc37c669_regs[reg] & 0xfc)) << 2;
|
||||
p &= 0xFF0;
|
||||
if ((p < 0x100) || (p > 0x3F0)) p = 0x1F0;
|
||||
if (!(is_in_array(ide_valid_ports, 2, p))) p = 0x1F0;
|
||||
fdc37c669_regs[reg] = ((p >> 2) & 0xfc) | (fdc37c669_regs[reg] & 3);
|
||||
break;
|
||||
case 0x22:
|
||||
p = ((uint16_t) (fdc37c669_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;
|
||||
fdc37c669_regs[reg] = ((p >> 2) & 0xfc) | (fdc37c669_regs[reg] & 3);
|
||||
mask = 0xfc;
|
||||
break;
|
||||
case 0x23:
|
||||
p = ((uint16_t) (fdc37c669_regs[reg] & 0xff)) << 2;
|
||||
p &= 0xFFC;
|
||||
if ((p < 0x100) || (p > 0x3F8)) p = 0x378;
|
||||
if (!(is_in_array(lpt1_valid_ports, 3, p))) p = 0x378;
|
||||
fdc37c669_regs[reg] = (p >> 2);
|
||||
mask = 0xff;
|
||||
break;
|
||||
case 0x24:
|
||||
p = ((uint16_t) (fdc37c669_regs[reg] & 0xfe)) << 2;
|
||||
p &= 0xFF8;
|
||||
if ((p < 0x100) || (p > 0x3F8)) p = 0x3F8;
|
||||
if (!(is_in_array(com1_valid_ports, 9, p))) p = 0x3F8;
|
||||
fdc37c669_regs[reg] = ((p >> 2) & 0xfe) | (fdc37c669_regs[reg] & 1);
|
||||
break;
|
||||
case 0x25:
|
||||
p = ((uint16_t) (fdc37c669_regs[reg] & 0xfe)) << 2;
|
||||
p &= 0xFF8;
|
||||
if ((p < 0x100) || (p > 0x3F8)) p = 0x2F8;
|
||||
if (!(is_in_array(com2_valid_ports, 9, p))) p = 0x2F8;
|
||||
fdc37c669_regs[reg] = ((p >> 2) & 0xfe) | (fdc37c669_regs[reg] & 1);
|
||||
mask = 0xfe;
|
||||
break;
|
||||
}
|
||||
|
||||
p = ((uint16_t) (fdc37c669_regs[reg] & mask)) << 2;
|
||||
if (reg == 0x22)
|
||||
{
|
||||
p |= 6;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -106,7 +66,7 @@ void fdc37c669_write(uint16_t port, uint8_t val, void *priv)
|
||||
uint8_t index = (port & 1) ? 0 : 1;
|
||||
uint8_t valxor = 0;
|
||||
uint8_t max = 42;
|
||||
pclog("fdc37c669_write : port=%04x reg %02X = %02X locked=%i\n", port, fdc37c669_curreg, val, fdc37c669_locked);
|
||||
/* pclog("fdc37c669_write : port=%04x reg %02X = %02X locked=%i\n", port, fdc37c669_curreg, val, fdc37c669_locked); */
|
||||
|
||||
if (index)
|
||||
{
|
||||
@@ -154,12 +114,14 @@ process_value:
|
||||
switch(fdc37c669_curreg)
|
||||
{
|
||||
case 0:
|
||||
#if 0
|
||||
if (valxor & 3)
|
||||
{
|
||||
ide_pri_disable();
|
||||
if ((fdc37c669_regs[0] & 3) == 2) ide_pri_enable_ex();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (valxor & 8)
|
||||
{
|
||||
fdc_remove();
|
||||
@@ -169,8 +131,13 @@ process_value:
|
||||
case 1:
|
||||
if (valxor & 4)
|
||||
{
|
||||
/* pclog("Removing LPT1\n"); */
|
||||
lpt1_remove();
|
||||
if ((fdc37c669_regs[1] & 4) && (fdc37c669_regs[0x23] & 0xc0)) lpt1_init(make_port(0x23));
|
||||
if ((fdc37c669_regs[1] & 4) && (fdc37c669_regs[0x23] >= 0x40))
|
||||
{
|
||||
/* pclog("LPT1 init (%02X)\n", make_port(0x23)); */
|
||||
lpt1_init(make_port(0x23));
|
||||
}
|
||||
}
|
||||
if (valxor & 7)
|
||||
{
|
||||
@@ -180,13 +147,23 @@ process_value:
|
||||
case 2:
|
||||
if (valxor & 8)
|
||||
{
|
||||
/* pclog("Removing UART1\n"); */
|
||||
serial_remove(1);
|
||||
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8);
|
||||
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] >= 0x40))
|
||||
{
|
||||
/* pclog("UART1 init (%02X, %i)\n", make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 4); */
|
||||
serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 4);
|
||||
}
|
||||
}
|
||||
if (valxor & 0x80)
|
||||
{
|
||||
/* pclog("Removing UART2\n"); */
|
||||
serial_remove(2);
|
||||
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF);
|
||||
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] >= 0x40))
|
||||
{
|
||||
/* pclog("UART2 init (%02X, %i)\n", make_port(0x25), fdc37c669_regs[0x28] & 0x0F); */
|
||||
serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0x0F);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@@ -209,6 +186,7 @@ process_value:
|
||||
break;
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
#if 0
|
||||
if (valxor & 0xfc)
|
||||
{
|
||||
ide_pri_disable();
|
||||
@@ -223,40 +201,64 @@ process_value:
|
||||
}
|
||||
if ((fdc37c669_regs[0] & 3) == 2) ide_pri_enable_ex();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 0x23:
|
||||
if (valxor)
|
||||
{
|
||||
/* pclog("Removing LPT1\n"); */
|
||||
lpt1_remove();
|
||||
if ((fdc37c669_regs[1] & 4) && (fdc37c669_regs[0x23] & 0xc0)) lpt1_init(make_port(0x23));
|
||||
if ((fdc37c669_regs[1] & 4) && (fdc37c669_regs[0x23] >= 0x40))
|
||||
{
|
||||
/* pclog("LPT1 init (%02X)\n", make_port(0x23)); */
|
||||
lpt1_init(make_port(0x23));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x24:
|
||||
if (valxor & 0xfe)
|
||||
{
|
||||
/* pclog("Removing UART1\n"); */
|
||||
serial_remove(1);
|
||||
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8);
|
||||
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] >= 0x40))
|
||||
{
|
||||
/* pclog("UART1 init (%02X, %i)\n", make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 4); */
|
||||
serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x25:
|
||||
if (valxor & 0xfe)
|
||||
{
|
||||
/* pclog("Removing UART2\n"); */
|
||||
serial_remove(2);
|
||||
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF);
|
||||
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] >= 0x40))
|
||||
{
|
||||
/* pclog("UART2 init (%02X, %i)\n", make_port(0x25), fdc37c669_regs[0x28] & 0x0F); */
|
||||
serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0x0F);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x28:
|
||||
if (valxor & 0xf)
|
||||
{
|
||||
/* pclog("Removing UART2\n"); */
|
||||
serial_remove(2);
|
||||
if ((fdc37c669_regs[0x28] & 0xf) == 0) fdc37c669_regs[0x28] |= 0x3;
|
||||
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF);
|
||||
if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] >= 0x40))
|
||||
{
|
||||
/* pclog("UART2 init (%02X, %i)\n", make_port(0x25), fdc37c669_regs[0x28] & 0x0F); */
|
||||
serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0x0F);
|
||||
}
|
||||
}
|
||||
if (valxor & 0xf0)
|
||||
{
|
||||
/* pclog("Removing UART1\n"); */
|
||||
serial_remove(1);
|
||||
if ((fdc37c669_regs[0x28] & 0xf0) == 0) fdc37c669_regs[0x28] |= 0x40;
|
||||
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8);
|
||||
if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] >= 0x40))
|
||||
{
|
||||
/* pclog("UART1 init (%02X, %i)\n", make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 4); */
|
||||
serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -266,7 +268,7 @@ uint8_t fdc37c669_read(uint16_t port, void *priv)
|
||||
{
|
||||
uint8_t index = (port & 1) ? 0 : 1;
|
||||
|
||||
pclog("fdc37c669_read : port=%04x reg %02X locked=%i\n", port, fdc37c669_curreg, fdc37c669_locked);
|
||||
/* pclog("fdc37c669_read : port=%04x reg %02X locked=%i\n", port, fdc37c669_curreg, fdc37c669_locked); */
|
||||
|
||||
if (!fdc37c669_locked)
|
||||
{
|
||||
@@ -277,7 +279,7 @@ uint8_t fdc37c669_read(uint16_t port, void *priv)
|
||||
return fdc37c669_curreg;
|
||||
else
|
||||
{
|
||||
pclog("0x03F1: %02X\n", fdc37c669_regs[fdc37c669_curreg]);
|
||||
/* pclog("0x03F1: %02X\n", fdc37c669_regs[fdc37c669_curreg]); */
|
||||
if ((fdc37c669_curreg < 0x18) && (fdc37c669_rw_locked)) return 0xff;
|
||||
return fdc37c669_regs[fdc37c669_curreg];
|
||||
}
|
||||
|
Reference in New Issue
Block a user