Added preliminary PDP-10 opcode decoding

This commit is contained in:
Jeff Parsons 2017-02-26 09:13:16 -08:00 committed by Jeff Parsons
commit e3ab5b1ed5
4 changed files with 1302 additions and 904 deletions

View file

@ -124,6 +124,9 @@ class CPUStatePDP10 extends CPUPDP10 {
this.model = model;
this.addrReset = +parmsCPU['addrReset'] || 0;
this.opDecode = PDP10.opKA10.bind(this);
this.opUndefined = PDP10.opUndefined.bind(this);
/** @type {IRQ|null} */
this.irqNext = null; // the head of the active IRQ list, in priority order
@ -171,7 +174,8 @@ class CPUStatePDP10 extends CPUPDP10 {
*/
initCPU()
{
this.regPC = this.pcLast = this.addrReset;
this.regEA = 0;
this.regPC = this.lastPC = this.addrReset;
/*
* This is queried and displayed by the Panel when it's not displaying its own ADDRESS register
@ -180,7 +184,7 @@ class CPUStatePDP10 extends CPUPDP10 {
*
* We initialize it to the current PC.
*/
this.addrLast = this.regPC;
this.lastAddr = this.regPC;
/*
* opFlags contains various conditions that stepCPU() needs to be aware of.
@ -272,9 +276,10 @@ class CPUStatePDP10 extends CPUPDP10 {
{
var state = new State(this);
state.set(0, [
this.regEA,
this.regPC,
this.pcLast,
this.addrLast,
this.lastPC,
this.lastAddr,
this.opFlags
]);
state.set(1, []);
@ -298,9 +303,10 @@ class CPUStatePDP10 extends CPUPDP10 {
* of what save() does when it collects a bunch of object properties into an array.
*/
[
this.regEA,
this.regPC,
this.pcLast,
this.addrLast,
this.lastPC,
this.lastAddr,
this.opFlags
] = data[0];
@ -317,17 +323,44 @@ class CPUStatePDP10 extends CPUPDP10 {
/**
* getOpcode()
*
* NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.
* This fetches the next opcode, decodes the low 23 bits (I,X,Y), sets regEA, and returns the
* the high 18 bits for further decoding. While it's true that, in general, only the high 13 bits
* are relevant to the operation, it's cleaner to treat the original opcode as two half-words.
*
* @this {CPUStatePDP10}
* @return {number}
*/
getOpcode()
{
var pc = this.pcLast = this.regPC;
var pc = this.lastPC = this.regPC;
var opCode = this.readWord(pc);
this.regPC = (pc + 1) % PDP10.ADDR_LIMIT;
return opCode;
var e, x, r = opCode, nMaxIndirect = 4;
while (true) {
/*
* Bits 0-22 (I,X,Y) contain what we call a "reference address" (R), which is used to calculate the
* "effective address" (E). To determine E from R, we must extract I, X, and Y from R, set E to Y,
* then add [X] to E if X is non-zero. If I is zero, then we're done; otherwise, we must set R to [E]
* and repeat the process.
*/
e = r & PDP10.OPCODE.Y_MASK;
x = (r >> PDP10.OPCODE.X_SHIFT) & PDP10.OPCODE.X_MASK;
if (x) e = (e + this.readWord(x)) & PDP10.ADDR_MASK;
if (!(r & PDP10.OPCODE.I_BIT)) break;
/*
* We allow this process to repeat only a few times, because more than that suggests we're executing
* garbage. Also, allowing this to loop endlessly would hang the simulation; if it turns out there is
* real-world PDP-10 code that requires a long series of indirections, we should factor this logic out
* as a separate operation. Note that would mean passing the full opcode on to the next level of decoding.
*/
if (--nMaxIndirect < 0) {
this.bus.fault(r);
break;
}
r = this.readWord(e);
}
this.regEA = e;
return (opCode / PDP10.ADDR_LIMIT)|0;
}
/**
@ -367,7 +400,7 @@ class CPUStatePDP10 extends CPUPDP10 {
*/
getLastAddr()
{
return this.addrLast;
return this.lastAddr;
}
/**
@ -378,7 +411,7 @@ class CPUStatePDP10 extends CPUPDP10 {
*/
getLastPC()
{
return this.pcLast;
return this.lastPC;
}
/**
@ -659,7 +692,7 @@ class CPUStatePDP10 extends CPUPDP10 {
*/
readWordFromPhysical(addr)
{
return this.bus.getWord(this.addrLast = addr);
return this.bus.getWord(this.lastAddr = addr);
}
/**
@ -673,7 +706,7 @@ class CPUStatePDP10 extends CPUPDP10 {
*/
writeWordToPhysical(addr, data)
{
this.bus.setWord(this.addrLast = addr, data);
this.bus.setWord(this.lastAddr = addr, data);
}
/**
@ -775,8 +808,7 @@ class CPUStatePDP10 extends CPUPDP10 {
this.opFlags &= PDP10.OPFLAG.PRESERVE;
var opCode = this.getOpcode();
// this.decode(opCode);
this.opDecode(opCode);
} while (this.nStepCycles > 0);