Fixed AT&T 6300 keyboard controller

This commit is contained in:
Jeff Parsons 2016-03-22 22:27:56 -07:00
commit fec1440718
7 changed files with 2296 additions and 2248 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -57,11 +57,11 @@ if (NODE) {
* monitor: none|tv|color|mono|ega|vga (if no sw1 value provided, default is "ega" for 5170, "mono" otherwise)
* rtcDate: optional RTC date/time (in GMT) to use on reset; use the ISO 8601 format; eg: "2014-10-01T08:00:00"
*
* As support for IBM-compatible machines grows, we should refrain from adding new model strings (eg, "deskpro386")
* and instead add more ChipSet configuration properties, such as:
* As support for IBM-compatible machines grows, we should refrain from adding new model strings (eg, "att6300")
* and corresponding model checks, and instead add more ChipSet configuration properties, such as:
*
* pit1: 0x48 to enable PIT1 at base port 0x48 (as used by COMPAQ_DESKPRO386); default is undefined
* kc: 8041 to enable 8041 emulation (eg, for ATT_6300); default is 8255 for MODEL_5150/MODEL_5160, 8042 for MODEL_5170
* pit1: 0x48 to enable PIT1 at base port 0x48 (as used by COMPAQ_DESKPRO386); default to undefined
* kc: 8041 to select 8041 emulation (eg, for ATT_6300); default to 8255 for MODEL_5150/MODEL_5160, 8042 for MODEL_5170
*
* @constructor
* @extends Component
@ -271,10 +271,12 @@ ChipSet.MODEL_5170_OTHER = 5170.9;
/*
* Assorted non-IBM models (we don't put "IBM" in the IBM models, but non-IBM models should include the company name).
*/
ChipSet.MODEL_ATT_6300 = 5160.101; // AT&T Personal Computer 6300/Olivetti M24 ("COPYRIGHT (C) OLIVETTI 1984","04/03/86",v1.43)
ChipSet.MODEL_CDP_MPC1600 = 5150.101; // Columbia Data Products MPC 1600 ("Copyright Columbia Data Products 1983, ROM/BIOS Ver 4.34")
ChipSet.MODEL_ZENITH_Z150 = 5160.150; // Zenith Data Systems Z-150 ("08/11/88 (C)ZDS CORP")
ChipSet.MODEL_COMPAQ_PORTABLE = 5150.102; // COMPAQ Portable (COMPAQ's first PC)
ChipSet.MODEL_ATT_6300 = 5160.101; // AT&T Personal Computer 6300/Olivetti M24 ("COPYRIGHT (C) OLIVETTI 1984","04/03/86",v1.43)
ChipSet.MODEL_ZENITH_Z150 = 5160.150; // Zenith Data Systems Z-150 ("08/11/88 (C)ZDS CORP")
ChipSet.MODEL_COMPAQ_DESKPRO386 = 5180; // COMPAQ DeskPro 386 (COMPAQ's first 80386-based PC); should be > MODEL_5170
/*
@ -288,10 +290,13 @@ ChipSet.MODELS = {
"mpc1600": ChipSet.MODEL_CDP_MPC1600,
"z150": ChipSet.MODEL_ZENITH_Z150,
"compaq": ChipSet.MODEL_COMPAQ_PORTABLE,
"deskpro386": ChipSet.MODEL_COMPAQ_DESKPRO386,
"other": ChipSet.MODEL_5150_OTHER
};
if (DESKPRO386) {
ChipSet.MODELS["deskpro386"] = ChipSet.MODEL_COMPAQ_DESKPRO386;
}
ChipSet.CONTROLS = {
SW1: "sw1",
SW2: "sw2",
@ -1220,6 +1225,10 @@ ChipSet.prototype.initBus = function(cmp, bus, cpu, dbg)
} else {
bus.addPortInputTable(this, ChipSet.aPortInput5170);
bus.addPortOutputTable(this, ChipSet.aPortOutput5170);
if (DESKPRO386 && (this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386) {
bus.addPortInputTable(this, ChipSet.aPortInputDeskPro386);
bus.addPortOutputTable(this, ChipSet.aPortOutputDeskPro386);
}
}
if (DEBUGGER) {
if (dbg) {
@ -1335,8 +1344,7 @@ ChipSet.prototype.reset = function(fHard)
this.bNMI = ChipSet.NMI.DISABLE;// tracks writes to the NMI Mask Register
if (this.model == ChipSet.MODEL_ATT_6300) {
this.b8041Ctrl = 0;
this.b8041Status = 0;
this.b8041Status = 0; // similar to b8042Status (but apparently only bits 0 and 1 are used)
}
/*
@ -1370,7 +1378,7 @@ ChipSet.prototype.reset = function(fHard)
this.b8042InPort |= ChipSet.KC8042.INPORT.MONO;
}
if (COMPAQ386 && (this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386) {
if (DESKPRO386 && (this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386) {
this.b8042InPort |= ChipSet.KC8042.INPORT.COMPAQ_NO80387 | ChipSet.KC8042.INPORT.COMPAQ_NOWEITEK;
}
@ -2994,7 +3002,7 @@ ChipSet.prototype.outDMAPageSpare = function(iSpare, port, bOut, addrFrom)
{
/*
* TODO: Remove this DEBUG-only DESKPRO386 code once we're done debugging DeskPro 386 ROMs;
* it enables logging of all DeskPro ROM checkpoint I/O to port 0x84.
* it enables logging of all DeskPro 386 ROM checkpoint I/O to port 0x84.
*/
if (this.messageEnabled(Messages.DMA | Messages.PORT) || DEBUG && (this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386 && port == 0x84) {
this.printMessageIO(port, bOut, addrFrom, "DMA.SPARE" + iSpare + ".PAGE", null, true);
@ -3843,10 +3851,10 @@ ChipSet.prototype.outTimer = function(iPIT, iPITTimer, port, bOut, addrFrom)
timer.fCounting = true;
/*
* I believe MODE0 is the only mode where "OUT" (fOUT) starts out "low" (false); for the rest of the modes,
* "OUT" (fOUT) starts "high" (true). It's also my understanding that the way edge-triggered interrupts work
* on the original PC is that an interrupt is requested only when the corresponding "OUT" transitions from
* "low" to "high".
* I believe MODE0 is the only mode where OUT (fOUT) starts out low (false); for the rest of the modes,
* OUT (fOUT) starts high (true). It's also my understanding that the way edge-triggered interrupts work
* on the original PC is that an interrupt is requested only when the corresponding OUT transitions from
* low to high.
*/
timer.fOUT = (timer.mode != ChipSet.PIT_CTRL.MODE0);
@ -4249,11 +4257,11 @@ ChipSet.prototype.updateTimer = function(iTimer, fCycleReset)
* where TIMER1 is programmed for MODE2, LSB (the same settings, incidentally, used immediately afterward
* for TIMER1 in conjunction with DMA channel 0 memory refreshes).
*
* Now this mode generates interrupts. Note that "OUT" goes "low" when the count reaches 1, then "high"
* Now this mode generates interrupts. Note that OUT goes low when the count reaches 1, then high
* one tick later, at which point the count is reloaded and counting continues.
*
* Chances are, we will often miss the exact point at which the count becomes 1 (or more importantly, one
* tick later, when the count *would* become 0, since that's when "OUT" transitions from "low" to "high"),
* Chances are, we will often miss the exact point at which the count becomes 1 (or more importantly,
* one tick later, when the count *would* become 0, since that's when OUT transitions from low to high),
* but as with MODE3, hopefully no one will mind.
*
* FYI, technically, it appears that the count is never supposed to reach 0, and that an initial count of 1
@ -4385,35 +4393,6 @@ ChipSet.prototype.outPPIA = function(port, bOut, addrFrom)
};
/**
* in8041Kbd(port, addrFrom)
*
* @this {ChipSet}
* @param {number} port (0x60)
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
* @return {number} simulated port value
*/
ChipSet.prototype.in8041Kbd = function(port, addrFrom)
{
var b = this.kbd? this.kbd.readScanCode() : 0;
this.printMessageIO(port, null, addrFrom, "8041_KBD", b);
return b;
};
/**
* out8041Kbd(port, bOut, addrFrom)
*
* @this {ChipSet}
* @param {number} port (0x60)
* @param {number} bOut
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
*/
ChipSet.prototype.out8041Kbd = function(port, bOut, addrFrom)
{
this.printMessageIO(port, bOut, addrFrom, "8041_KBD");
// if (this.kbd) this.kbd.sendCmd(bOut);
};
/**
* inPPIB(port, addrFrom)
*
@ -4480,35 +4459,6 @@ ChipSet.prototype.updatePPIB = function(bOut)
}
};
/**
* in8041Ctrl(port, addrFrom)
*
* @this {ChipSet}
* @param {number} port (0x61)
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
* @return {number} simulated port value
*/
ChipSet.prototype.in8041Ctrl = function(port, addrFrom)
{
var b = this.b8041Ctrl;
this.printMessageIO(port, null, addrFrom, "8041_CTRL", b);
return b;
};
/**
* out8041Ctrl(port, bOut, addrFrom)
*
* @this {ChipSet}
* @param {number} port (0x61)
* @param {number} bOut
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
*/
ChipSet.prototype.out8041Ctrl = function(port, bOut, addrFrom)
{
this.printMessageIO(port, bOut, addrFrom, "8041_CTRL");
this.b8041Ctrl = bOut;
};
/**
* inPPIC(port, addrFrom)
*
@ -4600,6 +4550,80 @@ ChipSet.prototype.outPPICtrl = function(port, bOut, addrFrom)
this.bPPICtrl = bOut;
};
/**
* in8041Kbd(port, addrFrom)
*
* @this {ChipSet}
* @param {number} port (0x60)
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
* @return {number} simulated port value
*/
ChipSet.prototype.in8041Kbd = function(port, addrFrom)
{
var b = this.kbd? this.kbd.readScanCode() : 0;
this.printMessageIO(port, null, addrFrom, "8041_KBD", b);
this.b8041Status &= ~ChipSet.KC8042.STATUS.OUTBUFF_FULL;
return b;
};
/**
* out8041Kbd(port, bOut, addrFrom)
*
* @this {ChipSet}
* @param {number} port (0x60)
* @param {number} bOut
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
*/
ChipSet.prototype.out8041Kbd = function(port, bOut, addrFrom)
{
this.printMessageIO(port, bOut, addrFrom, "8041_KBD");
// if (this.kbd) this.kbd.sendCmd(bOut);
};
/**
* in8041Ctrl(port, addrFrom)
*
* @this {ChipSet}
* @param {number} port (0x61)
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
* @return {number} simulated port value
*/
ChipSet.prototype.in8041Ctrl = function(port, addrFrom)
{
var b = this.bPPIB;
this.printMessageIO(port, null, addrFrom, "8041_CTRL", b);
return b;
};
/**
* out8041Ctrl(port, bOut, addrFrom)
*
* @this {ChipSet}
* @param {number} port (0x61)
* @param {number} bOut
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
*/
ChipSet.prototype.out8041Ctrl = function(port, bOut, addrFrom)
{
this.printMessageIO(port, bOut, addrFrom, "8041_CTRL");
this.updatePPIB(bOut);
};
/**
* in8041Status(port, addrFrom)
*
* @this {ChipSet}
* @param {number} port (0x64)
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
* @return {number} simulated port value
*/
ChipSet.prototype.in8041Status = function(port, addrFrom)
{
var b = this.b8041Status;
this.printMessageIO(port, null, addrFrom, "8041_STATUS", b);
return b;
};
/**
* in8042OutBuff(port, addrFrom)
*
@ -5124,6 +5148,7 @@ ChipSet.prototype.notifyKbdData = function(b)
* TODO: Should we be checking bPPI for PPI_B.CLK_KBD on these older machines, before calling setIRR()?
*/
this.setIRR(ChipSet.IRQ.KBD, 4);
this.b8041Status |= ChipSet.KC8042.STATUS.OUTBUFF_FULL;
}
else {
if (!(this.b8042CmdData & ChipSet.KC8042.DATA.CMD.NO_CLOCK)) {
@ -5153,21 +5178,6 @@ ChipSet.prototype.notifyKbdData = function(b)
}
};
/**
* in8041Status(port, addrFrom)
*
* @this {ChipSet}
* @param {number} port (0x64)
* @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
* @return {number} simulated port value
*/
ChipSet.prototype.in8041Status = function(port, addrFrom)
{
var b = this.b8041Status;
this.printMessageIO(port, null, addrFrom, "8041_STATUS", b);
return b;
};
/**
* in6300SysConf(iConf, port, addrFrom)
*
@ -5589,6 +5599,15 @@ ChipSet.aPortInput6300 = {
0x67: /** @this {ChipSet} */ function(port, addrFrom) { return this.in6300SysConf(1, port, addrFrom); }
};
if (DESKPRO386) {
ChipSet.aPortInputDeskPro386 = {
0x48: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER3, port, addrFrom); },
0x49: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER4, port, addrFrom); },
0x4A: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER5, port, addrFrom); },
0x4B: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimerCtrl(ChipSet.PIT1.INDEX, port, addrFrom); }
};
}
/*
* Port output notification tables
*/
@ -5671,6 +5690,15 @@ ChipSet.aPortOutput6300 = {
0xA0: ChipSet.prototype.outNMI
};
if (DESKPRO386) {
ChipSet.aPortOutputDeskPro386 = {
0x48: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER3, port, bOut, addrFrom); },
0x49: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER4, port, bOut, addrFrom); },
0x4A: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER5, port, bOut, addrFrom); },
0x4B: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimerCtrl(ChipSet.PIT1.INDEX, port, bOut, addrFrom); }
};
}
/**
* ChipSet.init()
*

View file

@ -125,9 +125,9 @@ var I386 = true;
/**
* @define {boolean}
*
* COMPAQ386 enables COMPAQ DeskPro 386 support. Requires I386 support as well (duh).
* DESKPRO386 enables COMPAQ DeskPro 386 support. Requires I386 support as well (duh).
*/
var COMPAQ386 = I386;
var DESKPRO386 = I386;
/**
* @define {boolean}
@ -153,7 +153,7 @@ if (NODE) {
global.SYMBOLS = SYMBOLS;
global.BUGS_8086 = BUGS_8086;
global.I386 = I386;
global.COMPAQ386 = COMPAQ386;
global.DESKPRO386 = DESKPRO386;
global.PAGEBLOCKS = PAGEBLOCKS;
/*
* TODO: When we're "required" by Node, should we return anything via module.exports?

View file

@ -197,7 +197,7 @@ RAM.prototype.reset = function()
*
* See CompaqController for more details.
*/
if (COMPAQ386) {
if (DESKPRO386) {
if (this.idComponent == "ramCPQ") {
this.controller = new CompaqController(this);
this.bus.addMemory(CompaqController.ADDR, 4, Memory.TYPE.CTRL, this.controller);
@ -218,7 +218,7 @@ RAM.prototype.reset = function()
* Don't add the "ramCPQ" memory to the CMOS total, because addCMOSMemory() will add it to the extended
* memory total, which will just confuse the COMPAQ BIOS.
*/
if (!COMPAQ386 || this.idComponent != "ramCPQ") {
if (!DESKPRO386 || this.idComponent != "ramCPQ") {
if (this.chipset) this.chipset.addCMOSMemory(this.addrRAM, this.sizeRAM);
}
} else {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff