Codify reasons for assorted traps
This commit is contained in:
parent
0ad98dc68b
commit
c858fd0699
7 changed files with 375 additions and 295 deletions
|
|
@ -219,10 +219,18 @@ BusPDP11.IOController = {
|
|||
var bus = this.controller;
|
||||
var afn = bus.aIOHandlers[off];
|
||||
if (afn) {
|
||||
/*
|
||||
* If a writeByte() handler exists, call it; we're done
|
||||
*/
|
||||
if (afn[1]) {
|
||||
afn[1](b, addr);
|
||||
return;
|
||||
} else if (afn[3]) {
|
||||
}
|
||||
/*
|
||||
* If a writeWord() handler exists, call the readWord() handler first to get the original data,
|
||||
* then call writeWord() with the new data pre-inserted into the original data.
|
||||
*/
|
||||
if (afn[3]) {
|
||||
w = afn[2]? afn[2](addr) : 0;
|
||||
if (!(addr & 0x1)) {
|
||||
afn[3]((w & ~0xff) | b, addr)
|
||||
|
|
@ -232,6 +240,11 @@ BusPDP11.IOController = {
|
|||
return;
|
||||
}
|
||||
} else if (addr & 0x1) {
|
||||
/*
|
||||
* If no handler existed, and this address was odd, then perhaps a handler exists for the even address;
|
||||
* if so, call the readWord() handler first to get the original data, then call writeWord() with the new
|
||||
* data pre-inserted into (the high byte of) the original data.
|
||||
*/
|
||||
afn = bus.aIOHandlers[off & ~0x1];
|
||||
if (afn[3]) {
|
||||
addr &= ~0x1;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,22 @@ if (NODE) {
|
|||
var PDP11 = require("./defines");
|
||||
}
|
||||
|
||||
/*
|
||||
* Decoding starts at the bottom of this file, in op1170(). The basic decoding approach is to
|
||||
* dispatch on the top 4 bits of the opcode, and if further decoding is required, then dispatch on
|
||||
* the next 4 bits, and so on (although some of the intermediate levels dispatch only on 2 bits).
|
||||
*
|
||||
* Eventually, every opcode should end up either in an opXXX() function or opUndefined(). For
|
||||
* opcodes that perform a simple read and/or write operation, the entire functionality is handled
|
||||
* by the opXXX() function. For opcodes that perform a more extensive read/modify/write operation
|
||||
* (also known as an update operation), those opXXX() functions usually rely on a corresponding
|
||||
* fnXXX() helper function.
|
||||
*
|
||||
* For example, opADD() passes the helper function fnADD() to the appropriate update method. This
|
||||
* allows the update method to perform the entire read/modify/write operation, because the modification
|
||||
* is handled by the helper function.
|
||||
*/
|
||||
|
||||
/**
|
||||
* fnADD(src, dst)
|
||||
*
|
||||
|
|
@ -803,7 +819,7 @@ PDP11.opBPL = function(opCode)
|
|||
*/
|
||||
PDP11.opBPT = function(opCode)
|
||||
{
|
||||
this.trap(PDP11.TRAP.BREAKPOINT, 6);
|
||||
this.trap(PDP11.TRAP.BREAKPOINT, PDP11.REASON.BPT);
|
||||
this.nStepCycles -= 1;
|
||||
};
|
||||
|
||||
|
|
@ -1061,7 +1077,7 @@ PDP11.opDIV = function(opCode)
|
|||
*/
|
||||
PDP11.opEMT = function(opCode)
|
||||
{
|
||||
this.trap(PDP11.TRAP.EMULATOR, 2);
|
||||
this.trap(PDP11.TRAP.EMULATOR, PDP11.REASON.EMT);
|
||||
this.nStepCycles -= 1;
|
||||
};
|
||||
|
||||
|
|
@ -1075,7 +1091,7 @@ PDP11.opHALT = function(opCode)
|
|||
{
|
||||
if (this.regPSW & PDP11.PSW.CMODE) {
|
||||
this.regErr |= PDP11.CPUERR.BADHALT;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 46);
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.HALT);
|
||||
} else {
|
||||
this.runState = 3;
|
||||
this.endBurst();
|
||||
|
|
@ -1115,7 +1131,7 @@ PDP11.opINCB = function(opCode)
|
|||
*/
|
||||
PDP11.opIOT = function(opCode)
|
||||
{
|
||||
this.trap(PDP11.TRAP.IOT, 8);
|
||||
this.trap(PDP11.TRAP.IOT, PDP11.REASON.IOT);
|
||||
this.nStepCycles -= 1;
|
||||
};
|
||||
|
||||
|
|
@ -1548,7 +1564,7 @@ PDP11.opSXT = function(opCode)
|
|||
*/
|
||||
PDP11.opTRAP = function(opCode)
|
||||
{
|
||||
this.trap(PDP11.TRAP.TRAP, 4);
|
||||
this.trap(PDP11.TRAP.TRAP, PDP11.REASON.TRAP);
|
||||
this.nStepCycles -= 1;
|
||||
};
|
||||
|
||||
|
|
@ -1612,18 +1628,7 @@ PDP11.opXOR = function(opCode)
|
|||
*/
|
||||
PDP11.opUndefined = function(opCode)
|
||||
{
|
||||
this.trap(PDP11.TRAP.RESERVED, 48);
|
||||
};
|
||||
|
||||
/**
|
||||
* op1170(opCode)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.op1170 = function(opCode)
|
||||
{
|
||||
PDP11.aOpsXnnn_1170[opCode >> 12].call(this, opCode);
|
||||
this.trap(PDP11.TRAP.RESERVED, PDP11.REASON.RESERVED);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1802,6 +1807,17 @@ PDP11.op8DXn_1170 = function(opCode)
|
|||
PDP11.aOps8DXn_1170[(opCode >> 6) & 0x3].call(this, opCode);
|
||||
};
|
||||
|
||||
/**
|
||||
* op1170(opCode)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.op1170 = function(opCode)
|
||||
{
|
||||
PDP11.aOpsXnnn_1170[opCode >> 12].call(this, opCode);
|
||||
};
|
||||
|
||||
PDP11.aOpsXnnn_1170 = [
|
||||
PDP11.op0Xnn_1170, // 0x0nnn
|
||||
PDP11.opMOV, // 0x1nnn 01SSDD
|
||||
|
|
|
|||
|
|
@ -184,10 +184,10 @@ CPUStatePDP11.prototype.resetRegs = function()
|
|||
this.regSL = 0xff; // 177774
|
||||
this.regErr = 0; // 177766
|
||||
this.regPIR = 0; // 177772
|
||||
this.MMR0 = 0; // 177572
|
||||
this.MMR1 = 0; // 177574
|
||||
this.MMR2 = 0; // 177576
|
||||
this.MMR3 = 0; // 172516
|
||||
this.regMMR0 = 0; // 177572
|
||||
this.regMMR1 = 0; // 177574
|
||||
this.regMMR2 = 0; // 177576
|
||||
this.regMMR3 = 0; // 172516
|
||||
this.mmuEnable = 0; // MMU enabled for PDP11.ACCESS.READ or PDP11.ACCESS.WRITE
|
||||
this.mmuLastMode = 0;
|
||||
this.mmuMask = [ // mask to control I&D access for each mode
|
||||
|
|
@ -230,7 +230,7 @@ CPUStatePDP11.prototype.initMemoryAccess = function()
|
|||
*/
|
||||
CPUStatePDP11.prototype.getMMR0 = function()
|
||||
{
|
||||
return (this.MMR0 & 0xf381) | (this.mmuLastMode << 5) | (this.mmuLastPage << 1);
|
||||
return (this.regMMR0 & 0xf381) | (this.mmuLastMode << 5) | (this.mmuLastPage << 1);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -242,7 +242,7 @@ CPUStatePDP11.prototype.getMMR0 = function()
|
|||
*/
|
||||
CPUStatePDP11.prototype.setMMR0 = function(newMMR0)
|
||||
{
|
||||
this.MMR0 = newMMR0 &= 0xf381;
|
||||
this.regMMR0 = newMMR0 &= 0xf381;
|
||||
this.mmuLastMode = (newMMR0 >> 5) & 3;
|
||||
this.mmuLastPage = (newMMR0 >> 1) & 0xf;
|
||||
if (newMMR0 & 0x101) {
|
||||
|
|
@ -255,7 +255,7 @@ CPUStatePDP11.prototype.setMMR0 = function(newMMR0)
|
|||
this.mmuEnable = 0;
|
||||
}
|
||||
this.initMemoryAccess();
|
||||
return this.MMR0;
|
||||
return this.regMMR0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -655,9 +655,9 @@ CPUStatePDP11.prototype.checkInterruptQueue = function()
|
|||
}
|
||||
if (savePSW > (this.regPSW & 0xe0)) {
|
||||
if (!interruptEvent) {
|
||||
this.trap(PDP11.TRAP.PIRQ, 42);
|
||||
this.trap(PDP11.TRAP.PIRQ, PDP11.REASON.INTERRUPT);
|
||||
} else {
|
||||
this.trap(interruptEvent.vector, 44);
|
||||
this.trap(interruptEvent.vector, PDP11.REASON.INTERRUPT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -882,9 +882,9 @@ CPUStatePDP11.prototype.trap = function(vector, reason)
|
|||
doubleTrap = true;
|
||||
}
|
||||
|
||||
if (!(this.MMR0 & 0xe000)) {
|
||||
this.MMR1 = 0xf6f6;
|
||||
this.MMR2 = vector;
|
||||
if (!(this.regMMR0 & 0xe000)) {
|
||||
this.regMMR1 = 0xf6f6;
|
||||
this.regMMR2 = vector;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -897,7 +897,7 @@ CPUStatePDP11.prototype.trap = function(vector, reason)
|
|||
/*
|
||||
* Set new PSW with previous mode
|
||||
*/
|
||||
this.setPSW((newPSW & 0xcfff) | ((this.trapPSW >> 2) & 0x3000));
|
||||
this.setPSW((newPSW & ~PDP11.PSW.PMODE) | ((this.trapPSW >> 2) & PDP11.PSW.PMODE));
|
||||
|
||||
if (doubleTrap) {
|
||||
this.regErr |= PDP11.CPUERR.RED;
|
||||
|
|
@ -911,7 +911,11 @@ CPUStatePDP11.prototype.trap = function(vector, reason)
|
|||
this.opFlags &= ~PDP11.OPFLAG.TRAP_MASK; // lose interest in traps after an abort
|
||||
this.trapPSW = -1; // reset flag that we have a trap within a trap
|
||||
|
||||
if (DEBUG && this.dbg) this.dbg.println("trap to vector " + this.dbg.toBase(vector) + (reason? " (reason " + reason + ")" : ""));
|
||||
if (DEBUG && this.dbg) {
|
||||
if (reason != PDP11.REASON.INTERRUPT) {
|
||||
this.dbg.println("trap to vector " + this.dbg.toBase(vector, 0, true) + (reason? " (reason " + reason + ")" : ""));
|
||||
}
|
||||
}
|
||||
|
||||
throw vector;
|
||||
};
|
||||
|
|
@ -954,7 +958,7 @@ CPUStatePDP11.prototype.mapUnibus = function(unibusAddress)
|
|||
{
|
||||
var idx = (unibusAddress >> 13) & 0x1f;
|
||||
if (idx < 31) {
|
||||
if (this.MMR3 & PDP11.MMR3.UNIBUS_MAP) {
|
||||
if (this.regMMR3 & PDP11.MMR3.UNIBUS_MAP) {
|
||||
unibusAddress = (this.unibusMap[idx] + (unibusAddress & 0x1ffe)) & 0x3ffffe;
|
||||
if (unibusAddress >= BusPDP11.IOPAGE_UNIBUS && unibusAddress < BusPDP11.IOPAGE_22BIT) this.panic(898);
|
||||
}
|
||||
|
|
@ -1026,7 +1030,7 @@ CPUStatePDP11.prototype.mapVirtualToPhysical = function(virtualAddress, accessFl
|
|||
} else { // no max_memory check in 16 bit mode
|
||||
if ((physicalAddress & 1) && !(accessFlags & PDP11.ACCESS.BYTE)) {
|
||||
this.regErr |= PDP11.CPUERR.ODDADDR;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 22);
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.ODDMEMADDR);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1034,7 +1038,7 @@ CPUStatePDP11.prototype.mapVirtualToPhysical = function(virtualAddress, accessFl
|
|||
page = (virtualAddress >> 13) & this.mmuMask[this.mmuMode];
|
||||
pdr = this.mmuMap[this.mmuMode][page];
|
||||
physicalAddress = ((this.mmuMap[this.mmuMode][page + 16] << 6) + (virtualAddress & 0x1fff)) & 0x3fffff;
|
||||
if (this.MMR3 & 0x10) { // if 22 bit MM mode
|
||||
if (this.regMMR3 & 0x10) { // if 22 bit MM mode
|
||||
if (physicalAddress >= BusPDP11.IOPAGE_UNIBUS && physicalAddress < BusPDP11.IOPAGE_22BIT) {
|
||||
physicalAddress = this.mapUnibus(physicalAddress & 0x3ffff); // 18bit unibus space
|
||||
}
|
||||
|
|
@ -1045,11 +1049,11 @@ CPUStatePDP11.prototype.mapVirtualToPhysical = function(virtualAddress, accessFl
|
|||
if (physicalAddress < BusPDP11.IOPAGE_UNIBUS) {
|
||||
if (physicalAddress >= BusPDP11.MAX_MEMORY) {
|
||||
this.regErr |= PDP11.CPUERR.NOMEMORY;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 24); // KB11-EM does this after ABORT handling - KB11-CM before
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.NOMEMORY); // KB11-EM does this after ABORT handling - KB11-CM before
|
||||
}
|
||||
if ((physicalAddress & 1) && !(accessFlags & PDP11.ACCESS.BYTE)) {
|
||||
this.regErr |= PDP11.CPUERR.ODDADDR;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 26);
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.ODDMMUADDR);
|
||||
}
|
||||
}
|
||||
switch (pdr & 0x7) {
|
||||
|
|
@ -1100,16 +1104,16 @@ CPUStatePDP11.prototype.mapVirtualToPhysical = function(virtualAddress, accessFl
|
|||
if (errorMask) {
|
||||
if (errorMask & 0xe000) {
|
||||
if (this.trapPSW >= 0) errorMask |= 0x80; // Instruction complete
|
||||
if (!(this.MMR0 & 0xe000)) {
|
||||
this.MMR0 |= errorMask | (this.mmuLastMode << 5) | (this.mmuLastPage << 1);
|
||||
if (!(this.regMMR0 & 0xe000)) {
|
||||
this.regMMR0 |= errorMask | (this.mmuLastMode << 5) | (this.mmuLastPage << 1);
|
||||
}
|
||||
this.trap(PDP11.TRAP.MMU_FAULT, 28);
|
||||
this.trap(PDP11.TRAP.MMU_FAULT, PDP11.REASON.MAPERROR);
|
||||
}
|
||||
if (!(this.MMR0 & 0xf000)) {
|
||||
if (!(this.regMMR0 & 0xf000)) {
|
||||
//if (physicalAddress < 017772200 || physicalAddress > 017777677) {
|
||||
if (physicalAddress < 0x3ff480 || physicalAddress > 0x3fffbf) {
|
||||
this.MMR0 |= 0x1000; // MMU trap flag
|
||||
if (this.MMR0 & 0x0200) {
|
||||
this.regMMR0 |= 0x1000; // MMU trap flag
|
||||
if (this.regMMR0 & 0x0200) {
|
||||
this.opFlags |= PDP11.OPFLAG.TRAP_MMU;
|
||||
}
|
||||
}
|
||||
|
|
@ -1214,15 +1218,15 @@ CPUStatePDP11.prototype.pushWord = function(data)
|
|||
|
||||
this.regsGen[6] = virtualAddress; // BSD needs SP updated before any fault :-(
|
||||
|
||||
if (!(this.MMR0 & 0xe000)) {
|
||||
this.MMR1 = (this.MMR1 << 8) | 0xf6;
|
||||
if (!(this.regMMR0 & 0xe000)) {
|
||||
this.regMMR1 = (this.regMMR1 << 8) | 0xf6;
|
||||
}
|
||||
|
||||
if ((!this.mmuMode) && virtualAddress <= this.regSL && virtualAddress > 4) {
|
||||
if (virtualAddress <= this.regSL - 32) {
|
||||
this.regErr |= PDP11.CPUERR.RED;
|
||||
this.regsGen[6] = 4;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 32);
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.PUSHERROR);
|
||||
} else {
|
||||
this.regErr |= PDP11.CPUERR.YELLOW;
|
||||
this.opFlags |= 4;
|
||||
|
|
@ -1274,7 +1278,7 @@ CPUStatePDP11.prototype.getVirtualByMode = function(addressMode, accessFlags)
|
|||
* Mode 0: Registers don't have a virtual address so trap
|
||||
*/
|
||||
case 0:
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 34);
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.NOREGADDR);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
|
@ -1286,7 +1290,7 @@ CPUStatePDP11.prototype.getVirtualByMode = function(addressMode, accessFlags)
|
|||
if (this.regsGen[6] <= this.regSL - 32 || this.regsGen[6] >= 0xfffe) {
|
||||
this.regErr |= PDP11.CPUERR.RED;
|
||||
this.regsGen[6] = 4;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 36);
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.STACKMODE1);
|
||||
} else {
|
||||
this.regErr |= PDP11.CPUERR.YELLOW;
|
||||
this.opFlags |= PDP11.OPFLAG.TRAP_SP;
|
||||
|
|
@ -1383,15 +1387,15 @@ CPUStatePDP11.prototype.getVirtualByMode = function(addressMode, accessFlags)
|
|||
|
||||
this.regsGen[reg] = (this.regsGen[reg] + stepSize) & 0xffff;
|
||||
|
||||
if (addrDSpace && !(this.MMR0 & 0xe000)) {
|
||||
this.MMR1 = (this.MMR1 << 8) | ((stepSize << 3) & 0xf8) | reg;
|
||||
if (addrDSpace && !(this.regMMR0 & 0xe000)) {
|
||||
this.regMMR1 = (this.regMMR1 << 8) | ((stepSize << 3) & 0xf8) | reg;
|
||||
}
|
||||
|
||||
if (reg === 6 && (!this.mmuMode) && (accessFlags & PDP11.ACCESS.WRITE) && stepSize <= 0 && (this.regsGen[6] <= this.regSL || this.regsGen[6] >= 0xfffe)) {
|
||||
if (reg == 6 && (!this.mmuMode) && (accessFlags & PDP11.ACCESS.WRITE) && stepSize <= 0 && (this.regsGen[6] <= this.regSL || this.regsGen[6] >= 0xfffe)) {
|
||||
if (this.regsGen[6] <= this.regSL - 32) {
|
||||
this.regErr |= PDP11.CPUERR.RED;
|
||||
this.regsGen[6] = 4;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 38);
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.STACKERROR);
|
||||
} else {
|
||||
this.regErr |= PDP11.CPUERR.YELLOW;
|
||||
this.opFlags |= PDP11.OPFLAG.TRAP_SP;
|
||||
|
|
@ -1469,8 +1473,8 @@ CPUStatePDP11.prototype.readWordFromPrevSpace = function(opCode, accessFlags)
|
|||
*/
|
||||
CPUStatePDP11.prototype.writeWordToPrevSpace = function(opCode, accessFlags, data)
|
||||
{
|
||||
if (!(this.MMR0 & 0xe000)) {
|
||||
this.MMR1 = 0x16;
|
||||
if (!(this.regMMR0 & 0xe000)) {
|
||||
this.regMMR1 = 0x16;
|
||||
}
|
||||
if (!(opCode & 0x38)) {
|
||||
var reg = opCode & 7;
|
||||
|
|
@ -1702,13 +1706,13 @@ CPUStatePDP11.prototype.stepCPU = function(nMinCycles)
|
|||
*/
|
||||
if (this.opFlags & PDP11.OPFLAG.TRAP_MASK) {
|
||||
if (this.opFlags & PDP11.OPFLAG.TRAP_MMU) {
|
||||
this.trap(PDP11.TRAP.MMU_FAULT, 52); // MMU trap has priority
|
||||
this.trap(PDP11.TRAP.MMU_FAULT, PDP11.REASON.TRAPMMU); // MMU trap has priority
|
||||
} else {
|
||||
if (this.opFlags & PDP11.OPFLAG.TRAP_SP) {
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 54); // then SP trap
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.TRAPSP); // then SP trap
|
||||
} else {
|
||||
if (this.opFlags & PDP11.OPFLAG.TRAP_TF) {
|
||||
this.trap(PDP11.TRAP.BREAKPOINT, 56); // and finally a TF trap
|
||||
this.trap(PDP11.TRAP.BREAKPOINT, PDP11.REASON.TRAPTF); // and finally a TF trap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1719,9 +1723,9 @@ CPUStatePDP11.prototype.stepCPU = function(nMinCycles)
|
|||
this.checkInterruptQueue();
|
||||
}
|
||||
|
||||
if (!(this.MMR0 & 0xe000)) {
|
||||
this.MMR1 = 0;
|
||||
this.MMR2 = this.regsGen[7];
|
||||
if (!(this.regMMR0 & 0xe000)) {
|
||||
this.regMMR1 = 0;
|
||||
this.regMMR2 = this.regsGen[7];
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -218,6 +218,26 @@ var PDP11 = {
|
|||
PIRQ: 0xA0, // 240 PIRQ, program interrupt request
|
||||
MMU_FAULT: 0xA8 // 250 MMU aborts and traps
|
||||
},
|
||||
REASON: {
|
||||
BPT: 1,
|
||||
EMT: 2,
|
||||
HALT: 3,
|
||||
IOT: 4,
|
||||
TRAP: 5,
|
||||
RESERVED: 6,
|
||||
ODDMEMADDR: 22,
|
||||
NOMEMORY: 24,
|
||||
ODDMMUADDR: 26,
|
||||
MAPERROR: 28,
|
||||
PUSHERROR: 32,
|
||||
NOREGADDR: 34,
|
||||
STACKMODE1: 36,
|
||||
STACKERROR: 38,
|
||||
INTERRUPT: 44,
|
||||
TRAPMMU: 52,
|
||||
TRAPSP: 54,
|
||||
TRAPTF: 56
|
||||
},
|
||||
/*
|
||||
* Internal memory access flags
|
||||
*/
|
||||
|
|
@ -366,11 +386,12 @@ var PDP11 = {
|
|||
|
||||
MMR3: 0o172516, // 772516 17772516
|
||||
|
||||
XBUF: 0o177566, // Console Terminal: Transmitter Data Buffer Register
|
||||
XCSR: 0o177564, // Console Terminal: Transmitter Status Register
|
||||
RBUF: 0o177562, // Console Terminal: Receiver Data Buffer Register
|
||||
RCSR: 0o177560, // Console Terminal: Receiver Status Register
|
||||
LKS: 0o177546, // KW11-L Clock Status
|
||||
|
||||
RCSR: 0o177560, // Console Terminal: Receiver Status Register
|
||||
RBUF: 0o177562, // Console Terminal: Receiver Data Buffer Register
|
||||
XCSR: 0o177564, // Console Terminal: Transmitter Status Register
|
||||
XBUF: 0o177566, // Console Terminal: Transmitter Data Buffer Register
|
||||
DISPLAY: 0o177570, // Console Switch and Display
|
||||
|
||||
MMR0: 0o177572, // 777572 17777572
|
||||
|
|
|
|||
|
|
@ -263,11 +263,35 @@ DevicePDP11.prototype.writeMMR0 = function(data, addr)
|
|||
var idx = 4;
|
||||
data = this.cpu.setMMR0(data);
|
||||
if (data & PDP11.MMR0.ENABLED | PDP11.MMR0.DSTMODE) {
|
||||
idx = (this.cpu.MMR3 & PDP11.MMR3.MMU_22BIT)? 1 : 2;
|
||||
idx = (this.cpu.regMMR3 & PDP11.MMR3.MMU_22BIT)? 1 : 2;
|
||||
}
|
||||
this.display.misc = (this.display.misc & ~7) | idx;
|
||||
};
|
||||
|
||||
/**
|
||||
* readRCSR(addr)
|
||||
*
|
||||
* @this {DevicePDP11}
|
||||
* @param {number} addr (eg, PDP11.UNIBUS.RCSR or 177560)
|
||||
* @return {number}
|
||||
*/
|
||||
DevicePDP11.prototype.readRCSR = function(addr)
|
||||
{
|
||||
return this.tty.rcsr;
|
||||
};
|
||||
|
||||
/**
|
||||
* writeRCSR(data, addr)
|
||||
*
|
||||
* @this {DevicePDP11}
|
||||
* @param {number} data
|
||||
* @param {number} addr (eg, PDP11.UNIBUS.RCSR or 177560)
|
||||
*/
|
||||
DevicePDP11.prototype.writeRCSR = function(data, addr)
|
||||
{
|
||||
this.tty.rcsr = (this.tty.rcsr & 0x80) | (data & ~0x80);
|
||||
};
|
||||
|
||||
/**
|
||||
* readXCSR(addr)
|
||||
*
|
||||
|
|
@ -1090,26 +1114,26 @@ DevicePDP11.prototype.access = function(physicalAddress, data, byteFlag)
|
|||
var kw11 = this.kw11;
|
||||
switch (physicalAddress & ~1) {
|
||||
case 0x3FFF7E: /*017777576*/ // MMR2
|
||||
result = this.insertData(cpu.MMR2, physicalAddress, data, byteFlag);
|
||||
if (result >= 0) cpu.MMR2 = result;
|
||||
result = this.insertData(cpu.regMMR2, physicalAddress, data, byteFlag);
|
||||
if (result >= 0) cpu.regMMR2 = result;
|
||||
break;
|
||||
case 0x3FFF7C: /*017777574*/ // MMR1
|
||||
result = cpu.MMR1;
|
||||
result = cpu.regMMR1;
|
||||
if (result & 0xff00) result = ((result << 8) | (result >> 8)) & 0xffff;
|
||||
break;
|
||||
// case 0x3FFF7A: /*017777572*/ // MMR0
|
||||
// cpu.MMR0 = (cpu.MMR0 & 0xf381) | (cpu.mmuLastMode << 5) | (cpu.mmuLastPage << 1);
|
||||
// cpu.regMMR0 = (cpu.regMMR0 & 0xf381) | (cpu.mmuLastMode << 5) | (cpu.mmuLastPage << 1);
|
||||
// if (data < 0) {
|
||||
// result = cpu.MMR0;
|
||||
// result = cpu.regMMR0;
|
||||
// } else {
|
||||
// result = this.insertData(cpu.MMR0, physicalAddress, data, byteFlag);
|
||||
// result = this.insertData(cpu.regMMR0, physicalAddress, data, byteFlag);
|
||||
// if (result >= 0) {
|
||||
// cpu.MMR0 = result &= 0xf381;
|
||||
// cpu.regMMR0 = result &= 0xf381;
|
||||
// cpu.mmuLastMode = (result >> 5) & 3;
|
||||
// cpu.mmuLastPage = (result >> 1) & 0xf;
|
||||
// if (result & 0x101) {
|
||||
// idx = 2; // 18 bit
|
||||
// if (cpu.MMR3 & 0x10) idx = 1; // 22 bit
|
||||
// if (cpu.regMMR3 & 0x10) idx = 1; // 22 bit
|
||||
// if (result & 0x1) {
|
||||
// cpu.mmuEnable = PDP11.ACCESS.READ | PDP11.ACCESS.WRITE;
|
||||
// } else {
|
||||
|
|
@ -1421,18 +1445,18 @@ DevicePDP11.prototype.access = function(physicalAddress, data, byteFlag)
|
|||
switch (physicalAddress & ~1) {
|
||||
case 0x3FF54E: /*017772516*/ // MMR3 - UB 22 x K S U
|
||||
if (data < 0) {
|
||||
result = cpu.MMR3;
|
||||
result = cpu.regMMR3;
|
||||
} else {
|
||||
result = this.insertData(cpu.MMR3, physicalAddress, data, byteFlag);
|
||||
result = this.insertData(cpu.regMMR3, physicalAddress, data, byteFlag);
|
||||
if (result >= 0) {
|
||||
if (cpu.cpuType !== 70) result &= ~0x30; // don't allow 11/45 to do 22 bit or use unibus map
|
||||
cpu.MMR3 = result;
|
||||
cpu.regMMR3 = result;
|
||||
cpu.mmuMask[0] = (result & 4 ? 0xf : 0x7);
|
||||
cpu.mmuMask[1] = (result & 2 ? 0xf : 0x7);
|
||||
cpu.mmuMask[3] = (result & 1 ? 0xf : 0x7);
|
||||
if (cpu.mmuEnable) {
|
||||
idx = 2; // 18 bit
|
||||
if (cpu.MMR3 & 0x10) idx = 1; // 22 bit
|
||||
if (cpu.regMMR3 & 0x10) idx = 1; // 22 bit
|
||||
this.display.misc = (this.display.misc & ~7) | idx;
|
||||
}
|
||||
}
|
||||
|
|
@ -1514,10 +1538,11 @@ DevicePDP11.prototype.access = function(physicalAddress, data, byteFlag)
|
|||
* ES6 ALERT: As you can see below, I've finally started using computed property names.
|
||||
*/
|
||||
DevicePDP11.UNIBUS_TABLE = {
|
||||
[PDP11.UNIBUS.LKS]: [null, null, DevicePDP11.prototype.readLKS, DevicePDP11.prototype.writeLKS],
|
||||
[PDP11.UNIBUS.MMR0]: [null, null, DevicePDP11.prototype.readMMR0, DevicePDP11.prototype.writeMMR0],
|
||||
[PDP11.UNIBUS.XCSR]: [null, null, DevicePDP11.prototype.readXCSR, DevicePDP11.prototype.writeXCSR],
|
||||
[PDP11.UNIBUS.PSW]: [null, null, DevicePDP11.prototype.readPSW, DevicePDP11.prototype.writePSW]
|
||||
[PDP11.UNIBUS.LKS]: /* 177546 */ [null, null, DevicePDP11.prototype.readLKS, DevicePDP11.prototype.writeLKS],
|
||||
[PDP11.UNIBUS.RCSR]: /* 177560 */ [null, null, DevicePDP11.prototype.readRCSR, DevicePDP11.prototype.writeRCSR],
|
||||
[PDP11.UNIBUS.XCSR]: /* 177564 */ [null, null, DevicePDP11.prototype.readXCSR, DevicePDP11.prototype.writeXCSR],
|
||||
[PDP11.UNIBUS.MMR0]: /* 177572 */ [null, null, DevicePDP11.prototype.readMMR0, DevicePDP11.prototype.writeMMR0],
|
||||
[PDP11.UNIBUS.PSW]: /* 177776 */ [null, null, DevicePDP11.prototype.readPSW, DevicePDP11.prototype.writePSW]
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue