Fixed a few more MMU bugs uncovered by the EKBEE1 diagnostics; the end is in sight

This commit is contained in:
Jeff 2016-11-17 23:51:30 -08:00 committed by Jeff Parsons
commit 7088a185fd
5 changed files with 116 additions and 112 deletions

View file

@ -1552,6 +1552,8 @@ CPUStatePDP11.prototype.mapVirtualToPhysical = function(virtualAddress, accessFl
pdr = this.mmuPDR[this.mmuMode][page];
physicalAddress = ((this.mmuPAR[this.mmuMode][page] << 6) + (virtualAddress & 0x1fff)) & this.mmuMask;
if (this.nDisableTraps) return physicalAddress;
var newMMR0 = 0;
switch (pdr & PDP11.PDR.ACF.MASK) {
@ -1620,16 +1622,16 @@ CPUStatePDP11.prototype.mapVirtualToPhysical = function(virtualAddress, accessFl
newMMR0 |= PDP11.MMR0.COMPLETED;
}
if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {
newMMR0 |= (this.mmuLastMode << 5) | (this.mmuLastPage << 1);
newMMR0 |= (this.regMMR0 & PDP11.MMR0.TRAP_MMU) | (this.mmuLastMode << 5) | (this.mmuLastPage << 1);
this.assert(!(newMMR0 & ~PDP11.MMR0.UPDATE));
this.setMMR0((this.regMMR0 & ~PDP11.MMR0.UPDATE) | newMMR0);
/*
* I've decided to NOT abort if MMR0 already indicates an ABORT condition,
* because otherwise we run the risk of infinitely looping; eg, we call trap(), which
* calls mapVirtualToPhysical() on the trap vector, which faults again, etc.
*/
this.trap(PDP11.TRAP.MMU, PDP11.OPFLAG.TRAP_MMU, PDP11.REASON.ABORT);
this.setMMR0((this.regMMR0 & ~PDP11.MMR0.UPDATE) | (newMMR0 & PDP11.MMR0.UPDATE));
}
/*
* TODO: In unusual circumstances, if regMMR0 already indicated an ABORT condition above,
* we run the risk of infinitely looping; eg, we call trap(), which calls mapVirtualToPhysical()
* on the trap vector, which faults again, etc. We should add some safeguards against that.
*/
this.trap(PDP11.TRAP.MMU, PDP11.OPFLAG.TRAP_MMU, PDP11.REASON.ABORT);
}
if (!(this.regMMR0 & (PDP11.MMR0.ABORT | PDP11.MMR0.TRAP_MMU))) {
/*

View file

@ -342,7 +342,7 @@ var PDP11 = {
ABORT_PL: 0x4000, // 040000 abort: page length
ABORT_NR: 0x8000, // 100000 abort: non-resident
ABORT: 0xE000, // 160000 (all of the ABORT bits)
UPDATE: 0xE0FE // Includes all of: ABORT, COMPLETED, MODE, and PAGE bits
UPDATE: 0xF0FE // Includes all of: ABORT, TRAP, COMPLETED, MODE, and PAGE bits
},
MMR1: { // 177574: general purpose auto-inc/auto-dec register (11/44 and 11/70 only)
REG1_NUM: 0x0007, //

View file

@ -1063,19 +1063,20 @@ PanelPDP11.prototype.updateDisplay = function(nUpdate)
};
/**
* readCNSW(addr)
* readCNSW(addr, fPreWrite)
*
* If addr is set, then this a normal read, so we should return the SWITCH register (ie, regSwitches).
* If fPreWrite, this is a read-before-write, so we must return the DISPLAY register (ie, regDisplay);
* otherwise, this a normal read, so we should return the SWITCH register (ie, regSwitches).
*
* if addr is NOT set, then this is a read-before-write, so we must return the DISPLAY register (ie, regDisplay).
*
* @this {PanelPDP11}
* @param {number} addr (eg, PDP11.UNIBUS.CNSW or 177570)
* @param {boolean} [fPreWrite]
* @return {number}
*/
PanelPDP11.prototype.readCNSW = function(addr)
PanelPDP11.prototype.readCNSW = function(addr, fPreWrite)
{
return (addr? this.regSwitches : this.regDisplay) & 0xffff;
return (fPreWrite? this.regDisplay : this.regSwitches) & 0xffff;
};
/**