Enable the Debugger to get/set front panel switches as register SW

This commit is contained in:
Jeff 2016-11-02 19:41:29 -07:00 committed by Jeff Parsons
commit b3bf213cd9
8 changed files with 563 additions and 454 deletions

View file

@ -266,6 +266,7 @@ if (DEBUGGER) {
* Register numbers 0-7 are reserved for cpu.regsGen, 8-15 are reserved for cpu.regsAlt, and 16-19 for cpu.regsStack.
*/
DebuggerPDP11.REG_PSW = 20;
DebuggerPDP11.REG_SW = 21;
/*
* Operand type masks; anything that's not covered by OP_SRC or OP_DST must be a OP_OTHER value.
@ -465,6 +466,7 @@ if (DEBUGGER) {
this.bus = bus;
this.cpu = cpu;
this.cmp = cmp;
this.panel = cmp.panel;
/*
* Re-initialize Debugger message support if necessary
@ -1125,6 +1127,9 @@ if (DEBUGGER) {
case "PC":
iReg = 7;
break;
case "SW":
iReg = 21;
break;
default:
if (sReg.charAt(0) == "R") {
iReg = +sReg.charAt(1);
@ -1139,7 +1144,7 @@ if (DEBUGGER) {
* getRegName(iReg)
*
* @this {DebuggerPDP11}
* @param {number} iReg
* @param {number} iReg (0-7; not used for other registers)
* @return {string}
*/
DebuggerPDP11.prototype.getRegName = function(iReg)
@ -1151,7 +1156,7 @@ if (DEBUGGER) {
* getRegValue(iReg)
*
* Register numbers 0-7 are reserved for cpu.regsGen, 8-15 are reserved for cpu.regsAlt,
* 16-19 for cpu.regsAltStack, and 20 for regPSW.
* 16-19 for cpu.regsAltStack, 20 for regPSW, and 21 for regSW.
*
* @this {DebuggerPDP11}
* @param {number} iReg
@ -1173,6 +1178,9 @@ if (DEBUGGER) {
else if (iReg == DebuggerPDP11.REG_PSW) {
value = this.cpu.getPSW();
}
else if (iReg == DebuggerPDP11.REG_SW && this.panel && this.panel.hasSwitches()) {
value = this.panel.getSW();
}
}
return value;
};
@ -1362,7 +1370,7 @@ if (DEBUGGER) {
/*
* Make an effort to keep any Front Panel in sync with us.
*/
if (this.cmp.panel && this.cmp.panel.stop) this.cmp.panel.stop();
if (this.panel && this.panel.stop) this.panel.stop();
this.cmp.updateStatus();
}
@ -2390,6 +2398,9 @@ if (DEBUGGER) {
else if (iReg == DebuggerPDP11.REG_PSW) {
sReg = "PS=" + this.toStrBase(cpu.getPSW());
}
else if (iReg == DebuggerPDP11.REG_SW && this.panel && this.panel.hasSwitches()) {
sReg = "SW=" + this.toStrBase(this.panel.getSW(), 3);
}
if (sReg) sReg += ' ';
return sReg;
};
@ -2413,7 +2424,8 @@ if (DEBUGGER) {
sDump += this.getRegOutput(i);
}
sDump += '\n';
sDump += this.getRegOutput(PDP11.REG.SP) + this.getRegOutput(PDP11.REG.PC) + this.getRegOutput(DebuggerPDP11.REG_PSW);
sDump += this.getRegOutput(PDP11.REG.SP) + this.getRegOutput(PDP11.REG.PC);
sDump += this.getRegOutput(DebuggerPDP11.REG_PSW) + this.getRegOutput(DebuggerPDP11.REG_SW);
sDump += this.getFlagOutput('T') + this.getFlagOutput('N') + this.getFlagOutput('Z') + this.getFlagOutput('V') + this.getFlagOutput('C');
return sDump;
};
@ -3406,6 +3418,12 @@ if (DEBUGGER) {
case "C":
if (w) cpu.setCF(); else cpu.clearCF();
break;
case "SW":
if (this.panel && this.panel.hasSwitches()) {
this.panel.setSW(w);
break;
}
/* falls through */
default:
if (sRegMatch.charAt(0) == 'R') {
var iReg = +sRegMatch.charAt(1);
@ -3666,7 +3684,7 @@ if (DEBUGGER) {
* with displayLiveRegs enabled, so once the repeat count has been exhausted, we must
* perform a final updateStatus().
*/
if (dbg.cmp.panel && dbg.cmp.panel.stop) dbg.cmp.panel.stop();
if (dbg.panel && dbg.panel.stop) dbg.panel.stop();
dbg.cmp.updateStatus();
dbg.setBusy(false);
}

View file

@ -57,30 +57,40 @@ function PanelPDP11(parmsPanel)
/*
* If there are any live registers, LEDs, etc, to display, this will provide a count.
*
* TODO: Add some UI for fDisplayLiveRegs (either an XML property, or a UI checkbox, or both).
*/
this.cLiveRegs = 0;
this.fDisplayLiveRegs = true;
this.fLampTest = false;
this.fExamine = this.fDeposit = false;
/*
* regCNSW contains the Console (Front Panel) Switch Register, which is also available as a
* regSwitches contains the Console (Front Panel) Switch Register, which is also available as a
* read-only register at 177570 (but only the low 16 bits).
*
* regAddr is an internal register containing the contents of the Front Panel's ADDRESS display,
* and regData corresponds to the DATA display. They are updated by setAddr() and setData(),
* which in turn take care of calling setLEDArray().
*/
this.regCNSW = 0;
this.regSwitches = 0;
this.regAddr = this.regData = 0;
this.regMisc = 0x14;
/*
* The panel hardware has the following additional (supported) state; note that there are several
* settings on a real Front Panel that we don't support (eg, stepping one cycle vs. one instruction).
*
* While my initial intent is to eventually support all the ADDRSEL switch settings, I probably
* won't bother with any DATASEL switch settings; instead, I will automatically display the data
* register (regData) [the equivalent of selecting 'DISPLAY REGISTER'] except when data is being
* examined or deposited [the equivalent of selecting 'DATA PATHS'].
*/
this.fLampTest = false; // lamp (LED) test in progress
this.fExamine = false; // true if the previously pressed switch was the 'EXAM' switch
this.fDeposit = false; // true if the previously pressed switch was the 'DEP' switch
this.nAddrSel = PanelPDP11.ADDRSEL.CONS_PHY;
/*
* Every LED has a simple numeric value, assigned when setBinding() is called:
*
* 0 if off, 1 if on
* zero if "off", non-zero if "on"
*
* initBus() will call displayLEDs() to ensure that every LED is set to its initial value.
*/
@ -122,6 +132,17 @@ function PanelPDP11(parmsPanel)
Component.subclass(PanelPDP11);
PanelPDP11.ADDRSEL = {
KERNEL_I: 0, // use a 16-bit virtual address where bits 16 to 21 are always OFF
KERNEL_D: 1, // use a 16-bit virtual address where bits 16 to 21 are always OFF
SUPER_I: 2, // use a 16-bit virtual address where bits 16 to 21 are always OFF
SUPER_D: 3, // use a 16-bit virtual address where bits 16 to 21 are always OFF
USER_I: 4, // use a 16-bit virtual address where bits 16 to 21 are always OFF
USER_D: 5, // use a 16-bit virtual address where bits 16 to 21 are always OFF
PROG_PHY: 6, // display the 22-bit physical address of the current bus cycle generated by the MMU
CONS_PHY: 7 // use a 22-bit physical address to perform console operations (e.g., LOAD ADRS, EXAM, & DEP)
};
/*
* To get the current state of a switch; eg::
*
@ -132,6 +153,7 @@ Component.subclass(PanelPDP11);
* "step" behavior when pressed more than once in a row). Ditto for the LED table.
*/
PanelPDP11.SWITCH = {
S0: 'S0',
DEP: 'DEP',
ENABLE: 'ENABLE',
EXAM: 'EXAM',
@ -144,6 +166,28 @@ PanelPDP11.LED = {
B22: 'B22'
};
/**
* getSW()
*
* @this {PanelPDP11}
* @return {number}
*/
PanelPDP11.prototype.getSW = function()
{
return this.regSwitches;
};
/**
* setSW(value)
*
* @this {PanelPDP11}
* @param {number} value
*/
PanelPDP11.prototype.setSW = function(value)
{
this.setSwitches(value);
};
/**
* getSwitch(name)
*
@ -163,7 +207,6 @@ PanelPDP11.prototype.getSwitch = function(name)
*/
PanelPDP11.prototype.reset = function()
{
this.regMisc = (this.regMisc & ~0x77) | 0x14; // kernel 16 bit
};
/**
@ -639,7 +682,15 @@ PanelPDP11.prototype.processDeposit = function(value, index)
if (this.fDeposit) {
this.setAddr(this.regAddr + 2);
}
this.bus.setWordDirect(this.regAddr, this.setData(this.regCNSW));
var w = this.setData(this.regSwitches);
if (this.nAddrSel == PanelPDP11.ADDRSEL.CONS_PHY) {
this.bus.setWordDirect(this.regAddr, w);
} else {
/*
* TODO: This code is obviously incomplete, since it doesn't take into account the precise ADDRSEL mode.
*/
this.cpu.setWordDirect(this.regAddr, w);
}
}
};
@ -656,7 +707,16 @@ PanelPDP11.prototype.processExamine = function(value, index)
if (this.fExamine) {
this.setAddr(this.regAddr + 2);
}
this.setData(this.bus.getWordDirect(this.regAddr));
var w;
if (this.nAddrSel == PanelPDP11.ADDRSEL.CONS_PHY) {
w = this.bus.getWordDirect(this.regAddr);
} else {
/*
* TODO: This code is obviously incomplete, since it doesn't take into account the precise ADDRSEL mode.
*/
w = this.cpu.getWordDirect(this.regAddr);
}
this.setData(w);
}
};
@ -670,7 +730,7 @@ PanelPDP11.prototype.processExamine = function(value, index)
PanelPDP11.prototype.processLoadAddr = function(value, index)
{
if (!value && !this.cpu.isRunning()) {
this.setAddr(this.regCNSW);
this.setAddr(this.regSwitches);
}
};
@ -696,9 +756,9 @@ PanelPDP11.prototype.processLampTest = function(value, index)
PanelPDP11.prototype.processSwitchReg = function(value, index)
{
if (value) {
this.regCNSW |= 1 << index;
this.regSwitches |= 1 << index;
} else {
this.regCNSW &= ~(1 << index);
this.regSwitches &= ~(1 << index);
}
};
@ -746,18 +806,46 @@ PanelPDP11.prototype.setLED = function(sBinding, value)
};
/**
* setLEDArray(sPrefix, data, nLEDs)
* setLEDArray(sPrefix, value, nLEDs)
*
* @this {PanelPDP11}
* @param {string} sPrefix
* @param {number} data
* @param {number} value
* @param {number} nLEDs
*/
PanelPDP11.prototype.setLEDArray = function(sPrefix, data, nLEDs)
PanelPDP11.prototype.setLEDArray = function(sPrefix, value, nLEDs)
{
for (var i = 0; i < nLEDs; i++) {
var sBinding = sPrefix + i;
this.setLED(sBinding, data & (1 << i));
this.setLED(sBinding, value & (1 << i));
}
};
/**
* hasSwitches(value)
*
* @this {PanelPDP11}
* @return {boolean}
*/
PanelPDP11.prototype.hasSwitches = function()
{
return this.bindings[PanelPDP11.SWITCH.S0] !== undefined;
};
/**
* setSwitches(value)
*
* @this {PanelPDP11}
* @param {number} value
*/
PanelPDP11.prototype.setSwitches = function(value)
{
if (this.hasSwitches()) {
this.regSwitches = value;
for (var i = 0; i < 22; i++) {
this.switches['S'+i][0] = (value & (1 << i))? 1 : 0;
}
this.displaySwitches();
}
};
@ -817,7 +905,7 @@ PanelPDP11.prototype.updateStatus = function(fForce)
* readCNSW(addr)
*
* If addr is set, then this a normal read, so we should return normal results (ie, switches);
* if addr is NOT set, then this is a read-before-write, so we must return the value being updated (ie, data).
* if addr is NOT set, then this is a read-before-write, so we must return the value being updated.
*
* @this {PanelPDP11}
* @param {number} addr (eg, PDP11.UNIBUS.CNSW or 177570)
@ -825,19 +913,19 @@ PanelPDP11.prototype.updateStatus = function(fForce)
*/
PanelPDP11.prototype.readCNSW = function(addr)
{
return (addr? this.regCNSW : this.regData) & 0xffff;
return (addr? this.regSwitches : this.regData) & 0xffff;
};
/**
* writeCNSW(data, addr)
* writeCNSW(value, addr)
*
* @this {PanelPDP11}
* @param {number} data
* @param {number} value
* @param {number} addr (eg, PDP11.UNIBUS.CNSW or 177570)
*/
PanelPDP11.prototype.writeCNSW = function(data, addr)
PanelPDP11.prototype.writeCNSW = function(value, addr)
{
this.regData = data;
this.regData = value;
};
PanelPDP11.UNIBUS_IOTABLE = {

View file

@ -681,7 +681,7 @@ if (DEBUGGER) {
var s;
switch(this.nBase) {
case 8:
s = str.toOct(n, nBytes * 3);
s = str.toOct(n, Math.round((8/3) * nBytes));
break;
case 10:
s = n.toString();