Added some RK11 fixes for the 11/70 CPU EXERCISER, and some Debugger improvements for dumping address info ("da")

This commit is contained in:
Jeff Parsons 2016-12-08 17:05:03 -08:00 • committed by Jeff Parsons
commit ba8771adf1
18 changed files with 847 additions and 793 deletions

View file

@ -263,7 +263,7 @@ CPUStatePDP11.prototype.initRegs = function()
this.regsControl = [ // various control registers (177740-177756) we don't really care about
0, 0, 0, 0, 0, 0, 0, 0
];
this.regMB = 0;
this.regMBR = 0;
/*
* opFlags contains various conditions that stepCPU() needs to be aware of.
@ -312,7 +312,7 @@ CPUStatePDP11.prototype.resetRegs = function()
this.regMMR3 = 0; // 172516
this.regErr = 0; // 177766
this.regPIR = 0; // 177772
this.regSL = 0xff; // 177774
this.regSLR = 0xff; // 177774
this.mmuEnable = 0; // MMU enabled for PDP11.ACCESS.READ or PDP11.ACCESS.WRITE
this.mmuLastMode = 0;
this.mmuLastPage = 0;
@ -586,9 +586,9 @@ CPUStatePDP11.prototype.save = function()
this.regsUniMap,
this.regsControl,
this.regErr,
this.regMB,
this.regMBR,
this.regPIR,
this.regSL,
this.regSLR,
this.getPSW(),
this.pswTrap,
this.pswMode,
@ -1204,25 +1204,25 @@ CPUStatePDP11.prototype.setPSW = function(newPSW)
};
/**
* getSL()
* getSLR()
*
* @this {CPUStatePDP11}
* @return {number}
*/
CPUStatePDP11.prototype.getSL = function()
CPUStatePDP11.prototype.getSLR = function()
{
return this.regSL & 0xff00;
return this.regSLR & 0xff00;
};
/**
* setSL(newSL)
* setSLR(newSL)
*
* @this {CPUStatePDP11}
* @param {number} newSL
* @param {number} newSLR
*/
CPUStatePDP11.prototype.setSL = function(newSL)
CPUStatePDP11.prototype.setSLR = function(newSLR)
{
this.regSL = newSL | 0xff;
this.regSLR = newSLR | 0xff;
};
/**
@ -1561,13 +1561,14 @@ CPUStatePDP11.prototype.getTrapStatus = function()
/**
* mapUnibus(addr)
*
* If bits 18-21 of addr are all set (which callers check using addr >= BusPDP11.UNIBUS_22BIT aka 0x3C0000),
* then we have a 22-bit address pointing to the top 256Kb range, so if the UNIBUS relocation map is enabled,
* we must pass the lower 18 bits of that address through the map.
* Used to convert 18-bit addresses to 22-bit addresses. Since mapUnibus() only looks at the low 18 bits of addr,
* there's no need to mask addr first. Note that if bits 13-17 are all set, then the 18-bit address points to the
* top 8Kb of its 256Kb range, and mapUnibus() will return addr unchanged, since it should already be pointing to
* the top 8Kb of the 4Mb 22-bit range.
*
* Since mapUnibus() only looks at the low 18 bits of addr, there's no need to mask addr first. Note that
* if bits 13-17 are all set, then the 18-bit address points to the top 8Kb of its 256Kb range, and mapUnibus()
* will return addr unchanged, since it should already be pointing to the top 8Kb of the 4Mb 22-bit range.
* Also, when bits 18-21 of addr are ALL set (which callers check using addr >= BusPDP11.UNIBUS_22BIT aka 0x3C0000),
* then we have a 22-bit address pointing to the top 256Kb range, so if the UNIBUS relocation map is enabled, we again
* pass the lower 18 bits of that address through the map.
*
* From the PDP-11/70 Handbook:
*
@ -1585,9 +1586,8 @@ CPUStatePDP11.prototype.getTrapStatus = function()
* order bit of all mapping registers is always a zero, since relocation is always on word boundaries.
*
* Sadly, because these mappings occur at a word-granular level, we can't implement the mappings by simply shuffling
* the underlying block around in the Bus component; it would be much more efficient if we could. That's EXACTLY how
* we move the IOPAGE in response to addressing changes. If it turns out that block-granular addresses are commonly
* stored in the unibusMap registers, we could add code to detect that and perform block remapping in those cases.
* the underlying block around in the Bus component; it would be much more efficient if we could. That's how we move
* the IOPAGE in response to addressing changes.
*
* @this {CPUStatePDP11}
* @param {number} addr
@ -1595,14 +1595,18 @@ CPUStatePDP11.prototype.getTrapStatus = function()
*/
CPUStatePDP11.prototype.mapUnibus = function(addr)
{
var idx = (addr >> 13) & 0x1f;
var idx = (addr >> 13) & 0x1F;
if (idx < 31) {
if (this.regMMR3 & PDP11.MMR3.UNIBUS_MAP) {
/*
* The UNIBUS map relocation is enabled
*/
addr = (this.regsUniMap[idx] + (addr & 0x1ffe)) & 0x3ffffe;
this.assert(addr < BusPDP11.UNIBUS_22BIT || addr >= BusPDP11.IOPAGE_22BIT);
addr = (this.regsUniMap[idx] + (addr & 0x1FFF)) & BusPDP11.MASK_22BIT;
/*
* TODO: Review this assertion.
*
* this.assert(addr < BusPDP11.UNIBUS_22BIT || addr >= BusPDP11.IOPAGE_22BIT);
*/
} else {
/*
* Since UNIBUS map relocation is NOT enabled, then as explained above:
@ -1617,33 +1621,44 @@ CPUStatePDP11.prototype.mapUnibus = function(addr)
};
/**
* getAddrInfo(addrVirtual)
* getAddrInfo(addr, fPhysical)
*
* @this {CPUStatePDP11}
* @param {number} addrVirtual
* @param {number} addr
* @param {boolean} [fPhysical]
* @return {Array}
*/
CPUStatePDP11.prototype.getAddrInfo = function(addrVirtual)
CPUStatePDP11.prototype.getAddrInfo = function(addr, fPhysical)
{
var addr;
var a = [];
var addrPhysical;
if (!this.mmuEnable) {
addr = addrVirtual & 0xffff;
if (addr >= BusPDP11.IOPAGE_16BIT) addr |= this.addrIOPage;
a.push(addr);
if (fPhysical) {
addrPhysical = this.mapUnibus(addr);
var idx = (addr >> 13) & 0x1F;
a.push(addrPhysical);
a.push(idx);
if (this.regMMR3 & PDP11.MMR3.UNIBUS_MAP) {
a.push(this.regsUniMap[idx]);
a.push(addr & 0x1FFF);
}
}
else if (!this.mmuEnable) {
addrPhysical = addr & 0xffff;
if (addrPhysical >= BusPDP11.IOPAGE_16BIT) addrPhysical |= this.addrIOPage;
a.push(addrPhysical);
}
else {
var mode = this.pswMode << 1;
var page = addrVirtual >> 13;
var page = addr >> 13;
if (page > 7) mode |= 1;
if (!(this.regMMR3 & this.mapMMR3[this.pswMode])) page &= 7;
var pdr = this.mmuPDR[this.pswMode][page];
var off = addrVirtual & 0x1fff;
var off = addr & 0x1fff;
var paf = (this.mmuPAR[this.pswMode][page] << 6);
addr = (paf + off) & this.mmuMask;
if (addr >= BusPDP11.UNIBUS_22BIT) addr = this.mapUnibus(addr);
a.push(addr); // a[0]
addrPhysical = (paf + off) & this.mmuMask;
if (addrPhysical >= BusPDP11.UNIBUS_22BIT) addrPhysical = this.mapUnibus(addrPhysical);
a.push(addrPhysical); // a[0]
a.push(off); // a[1]
a.push(mode); // a[2] (0=KI, 1=KD, 2=SI, 3=SD, 4=??, 5=??, 6=UI, 7=UD)
a.push(page & 7); // a[3]
@ -2051,7 +2066,7 @@ CPUStatePDP11.prototype.checkStackLimit1120 = function(access, step, addr)
*
* so if the step parameter is positive, we let it go.
*/
if (!this.pswMode && step <= 0 && addr <= this.regSL) {
if (!this.pswMode && step <= 0 && addr <= this.regSLR) {
/*
* On older machines (eg, the PDP-11/20), there is no "YELLOW" and "RED" distinction, and the
* instruction is always allowed to complete, so the trap must always be issued in this fashion.
@ -2086,12 +2101,12 @@ CPUStatePDP11.prototype.checkStackLimit1145 = function(access, step, addr)
* address tested by the diagnostic (0xFFFE, aka the PSW), by making that address negative.
*/
if (addr >= 0xFFFE) addr |= ~0xFFFF;
if ((access & PDP11.ACCESS.WRITE) && addr <= this.regSL) {
if ((access & PDP11.ACCESS.WRITE) && addr <= this.regSLR) {
/*
* regSL can never fall below 0xFF, so this subtraction can never go negative, so this comparison
* regSLR can never fall below 0xFF, so this subtraction can never go negative, so this comparison
* is always safe.
*/
if (addr <= this.regSL - 32) {
if (addr <= this.regSLR - 32) {
this.trap(PDP11.TRAP.BUS, 0, PDP11.REASON.RED);
} else {
this.regErr |= PDP11.CPUERR.YELLOW;