Fixed a few more MMU bugs uncovered by the EKBEE1 diagnostics; the end is in sight
This commit is contained in:
parent
861d78e6d2
commit
7088a185fd
5 changed files with 116 additions and 112 deletions
|
|
@ -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))) {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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, //
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue