mirror of
https://github.com/pkimpel/retro-b5500.git
synced 2026-02-22 07:28:14 +00:00
Commit DCMCP transcription as of 2012-07-14; implement Exit Char
Mode & Exit Char Mode In-line; change falsy/truthy values to 0 & 1, respectively.
This commit is contained in:
@@ -6571,3 +6571,103 @@ PROCEDURE TABLEOFCONTENTS(B,COUNT);% 07268000
|
||||
DS~6 LIT " THRU ";% 07295190
|
||||
SI~SI+4; DS~4 CHR;% 07295200
|
||||
END;% 07295210
|
||||
DS~LIT "~"; 07295220
|
||||
END;% 07295230
|
||||
SPOUT(I);% 07295235
|
||||
END ELSE FORGETSPACE(I);% 07295240
|
||||
$ POP OMIT 07295241
|
||||
UNLOCKCONTROLKECKS; 07296000
|
||||
END;% 07297000
|
||||
PROCEDURE REMOVEDECK(N,TUSTA);VALUE N,TUSTA;REAL N,TUSTA; 07298000
|
||||
BEGIN REAL I,T,A,L1,J=I,L2,V;% 07299000
|
||||
$ SET OMIT = NOT(PACKETS) 07299499
|
||||
REAL L3; 07299500
|
||||
LABEL FAIL,CONTINUE; 07299600
|
||||
$ POP OMIT 07299601
|
||||
LABEL L,EXIT,REMOVE;% 07300000
|
||||
LOCKCONTROLDECKS; 07301000
|
||||
IF (I ~ DIRECTORYSEARCH("DECK ",N,5)) = 0 THEN% 07303000
|
||||
$ SET OMIT = NOT(PACKETS) 07303499
|
||||
FAIL: 07303500
|
||||
$ POP OMIT 07303501
|
||||
BEGIN I ~ SPACE(5);% 07304000
|
||||
STREAM(N,I);% 07305000
|
||||
$ SET OMIT = NOT(PACKETS) 07305099
|
||||
BEGIN DS:=5 LIT " PKT "; 07305100
|
||||
$ POP OMIT 07305101
|
||||
$ SET OMIT = PACKETS 07305999
|
||||
SI ~ LOC N; SI ~ SI+1; DS ~ 5 CHR;% 07307000
|
||||
DS ~ 13 LIT " NOT ON DISK~";% 07308000
|
||||
END;% 07309000
|
||||
GO TO EXIT;% 07310000
|
||||
END;% 07311000
|
||||
$ SET OMIT = NOT(SHAREDISK) 07311199
|
||||
$ SET OMIT = NOT(PACKETS) 07311499
|
||||
L3:=M[I+6].[FF]; 07311500
|
||||
$ POP OMIT 07311501
|
||||
L2:=M[I+6].[CF]; 07312000
|
||||
IF (A:=FIRSTDECK)=(L1:=I.[FF]) THEN 07313000
|
||||
BEGIN 07314000
|
||||
$ SET OMIT = PACKETS 07314099
|
||||
$ SET OMIT = NOT(PACKETS) 07314109
|
||||
FIRSTDECK:=IF L3 NEQ 0 THEN L3 ELSE L2; 07314110
|
||||
IF L2=0 THEN LASTDECK~IF L3 NEQ 0 THEN L3 ELSE 0; 07314120
|
||||
$ POP OMIT 07314121
|
||||
DISKWAIT(KLUMP,3,DIRECTORYTOP+3); 07314200
|
||||
$ SET OMIT = NOT(PACKETS) 07314289
|
||||
IF L3 NEQ 0 THEN GO TO CONTINUE ELSE 07314290
|
||||
$ POP OMIT 07314291
|
||||
GO TO REMOVE; 07314300
|
||||
END; 07314400
|
||||
J ~ I.[33:15];% 07315000
|
||||
L: 07316000
|
||||
DISKWAIT(-J,30,A); 07317000
|
||||
IF (V:=M[J+6].[CF])=0 THEN 07318000
|
||||
$ SET OMIT = NOT(PACKETS) 07318009
|
||||
IF A=L1 THEN GO REMOVE ELSE BEGIN FORGETSPACE(I); GO FAIL 07318010
|
||||
END; 07318012
|
||||
$ POP OMIT 07318013
|
||||
$ SET OMIT = PACKETS 07318019
|
||||
IF V ! L1 THEN% 07319000
|
||||
BEGIN A ~ V; GO TO L END;% 07320000
|
||||
$ SET OMIT = PACKETS 07320999
|
||||
$ SET OMIT = NOT(PACKETS) 07321099
|
||||
M[J+6].[CF]~IF L3!0 THEN L3 ELSE L2; 07321100
|
||||
$ POP OMIT 07321101
|
||||
DISKWAIT(J,30,A); 07322000
|
||||
IF L2 = 0 THEN% 07324000
|
||||
BEGIN 07325000
|
||||
$ SET OMIT = PACKETS 07325999
|
||||
$ SET OMIT = NOT(PACKETS) 07326099
|
||||
LASTDECK:=IF L3 NEQ 0 THEN L3 ELSE A; 07326100
|
||||
$ POP OMIT 07326101
|
||||
DISKWAIT(KLUMP,3,DIRECTORYTOP+3); 07327000
|
||||
$ SET OMIT = PACKETS 07327999
|
||||
$ SET OMIT = NOT(PACKETS) 07329999
|
||||
END ELSE IF L3=0 THEN ELSE 07330000
|
||||
CONTINUE: 07330050
|
||||
BEGIN J~I INX 0; 07330100
|
||||
DISKWAIT(-J,30,L3); 07330200
|
||||
M[J+6].[CF]~L2; 07330300
|
||||
DISKWAIT(J,30,L3); 07330400
|
||||
END; 07330500
|
||||
$ POP OMIT 07330501
|
||||
REMOVE: 07331000
|
||||
FORGETSPACE(I); 07332000
|
||||
I:=DIRECTORYSEARCH("DECK ",N,8).[CF]; 07333000
|
||||
T ~ M[I+9];% 07343000
|
||||
FOR V ~ 1 STEP 1 UNTIL T DO% 07344000
|
||||
IF M[I+V+9]!0 THEN FORGETUSREDISK(M[I+V+9],M[I+8]); 07345000
|
||||
STREAM(N,I);% 07346000
|
||||
$ SET OMIT = NOT(PACKETS) 07346099
|
||||
BEGIN DS:=5 LIT " PKT "; 07346100
|
||||
$ POP OMIT 07346101
|
||||
$ SET OMIT = PACKETS 07346999
|
||||
SI ~ LOC N; SI ~ SI+1; DS ~ 5 CHR;% 07348000
|
||||
DS ~ 9 LIT " REMOVED~";% 07349000
|
||||
END;% 07350000
|
||||
$ SET OMIT = PACKETS 07350099
|
||||
EXIT: SPOUTER(I&TUSTA[9:9:9],TUSTA,LIBMSG) 07351000
|
||||
$ SET OMIT = PACKETS 07351099
|
||||
;UNLOCKCONTROLDECKS; 07352000
|
||||
END;% 07353000
|
||||
|
||||
@@ -32,7 +32,7 @@ function B5500CentralControl() {
|
||||
this.MemMod = new Array(8); // Array of memory module words as Float64s (8 x 4KW each)
|
||||
|
||||
// Instance variables and flags
|
||||
this.poweredUp = false; // System power indicator
|
||||
this.poweredUp = 0; // System power indicator
|
||||
|
||||
this.PB1L = 0; // 0=> PA is P1, 1=> PB is P1
|
||||
this.cardLoadSelect = 0; // 0=> load from disk/drum; 1=> load from cards
|
||||
@@ -504,7 +504,7 @@ B5500CentralControl.prototype.halt = function() {
|
||||
/* Halts the processors. Any in-process I/Os are allowed to complete */
|
||||
|
||||
if (this.PA && this.PA.busy) {
|
||||
this.PA.busy = false;
|
||||
this.PA.busy = 0;
|
||||
this.PA.cycleLimit = 0;
|
||||
if (this.PA.scheduler) {
|
||||
clearTimeout(this.PA.scheduler);
|
||||
@@ -513,7 +513,7 @@ B5500CentralControl.prototype.halt = function() {
|
||||
}
|
||||
|
||||
if (this.PB && this.PB.busy) {
|
||||
this.PB.busy = false;
|
||||
this.PB.busy = 0;
|
||||
this.PB.cycleLimit = 0;
|
||||
if (this.PB.scheduler) {
|
||||
clearTimeout(this.PB.scheduler);
|
||||
@@ -604,7 +604,7 @@ B5500CentralControl.prototype.powerOn = function() {
|
||||
|
||||
if (!this.poweredUp) {
|
||||
this.configureSystem();
|
||||
this.poweredUp = true;
|
||||
this.poweredUp = 1;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -634,6 +634,6 @@ B5500CentralControl.prototype.powerOff = function() {
|
||||
this.AddressSpace[x] = null;
|
||||
}
|
||||
|
||||
this.poweredUp = false;
|
||||
this.poweredUp = 0;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -98,7 +98,7 @@ B5500Processor.prototype.clear = function() {
|
||||
this.totalCycles = 0; // Total cycles executed on this processor
|
||||
this.procTime = 0; // Current processor running time, based on cycles executed
|
||||
this.scheduleSlack = 0; // Total processor throttling delay, milliseconds
|
||||
this.busy = false; // Proessor is running, not idle or halted
|
||||
this.busy = 0; // Proessor is running, not idle or halted
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
@@ -185,14 +185,14 @@ B5500Processor.prototype.access = function(eValue) {
|
||||
if (this.NCSF || this !== cc.P1) {
|
||||
cc.signalInterrupt();
|
||||
} else {
|
||||
this.busy = false; // P1 invalid address in control state stops the proc
|
||||
this.busy = 0; // P1 invalid address in control state stops the proc
|
||||
}
|
||||
} else if (acc.MPED) {
|
||||
this.I |= 0x01; // set I01F - memory parity error
|
||||
if (this.NCSF || this !== cc.P1) {
|
||||
cc.signalInterrupt();
|
||||
} else {
|
||||
this.busy = false; // P1 memory parity in control state stops the proc
|
||||
this.busy = 0; // P1 memory parity in control state stops the proc
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -430,7 +430,7 @@ B5500Processor.storeForInterrupt = function(forTest) {
|
||||
this.T = 0; // idle the processor
|
||||
this.TROF = 0;
|
||||
this.PROF = 0;
|
||||
this.busy = false;
|
||||
this.busy = 0;
|
||||
cc.HP2F = 1;
|
||||
cc.P2BF = 0;
|
||||
if (cc.P2.scheduler) {
|
||||
@@ -454,7 +454,7 @@ B5500Processor.storeForInterrupt = function(forTest) {
|
||||
this.T = 0; // idle the processor
|
||||
this.TROF = 0;
|
||||
this.PROF = 0;
|
||||
this.busy = false;
|
||||
this.busy = 0;
|
||||
cc.HP2F = 1;
|
||||
cc.P2BF = 0;
|
||||
if (cc.P2.scheduler) {
|
||||
@@ -558,7 +558,7 @@ B5500Processor.initiate = function(forTest) {
|
||||
}
|
||||
} else {
|
||||
this.NCSF = 1;
|
||||
this.busy = true;
|
||||
this.busy = 1;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -612,11 +612,11 @@ B5500Processor.prototype.computeRelativeAddr = function(offset, cEnabled) {
|
||||
/**************************************/
|
||||
B5500Processor.prototype.indexDescriptor = function() {
|
||||
/* Indexes a descriptor and, if successful leaves the indexed value in
|
||||
the A register. Returns true if an interrupt is set and the syllable is
|
||||
the A register. Returns 1 if an interrupt is set and the syllable is
|
||||
to be exited */
|
||||
var aw = this.A; // local copy of A reg
|
||||
var bw; // local copy of B reg
|
||||
var interrupted = false; // fatal error, interrupt set
|
||||
var interrupted = 0; // fatal error, interrupt set
|
||||
var xe; // index exponent
|
||||
var xm; // index mantissa
|
||||
var xo; // last index octade shifted off
|
||||
@@ -643,7 +643,7 @@ B5500Processor.prototype.indexDescriptor = function() {
|
||||
xm *= 8;
|
||||
} else { // oops... integer overflow normalizing the index
|
||||
xe = 0; // kill the loop
|
||||
interrupted = true;
|
||||
interrupted = 1;
|
||||
if (this.NCSF) {
|
||||
this.I = (this.I & 0x0F) | 0xC0; // set I07/8: int-overflow
|
||||
cc.signalInterrupt();
|
||||
@@ -657,13 +657,13 @@ B5500Processor.prototype.indexDescriptor = function() {
|
||||
// Now we have an integerized index value in xm
|
||||
if (!interrupted) {
|
||||
if (xm && cc.bit(bw, 1)) { // oops... negative index
|
||||
interrupted = true;
|
||||
interrupted = 1;
|
||||
if (this.NCSF) {
|
||||
this.I = (this.I & 0x0F) | 0x90; // set I05/8: invalid-index
|
||||
cc.signalInterrupt();
|
||||
}
|
||||
} else if (xm >= cc.fieldIsolate(bw, 8, 10)) {
|
||||
interrupted = true; // oops... index out of bounds
|
||||
interrupted = 1; // oops... index out of bounds
|
||||
if (this.NCSF) {
|
||||
this.I = (this.I & 0x0F) | 0x90; // set I05/8: invalid-index
|
||||
cc.signalInterrupt();
|
||||
@@ -736,12 +736,17 @@ B5500Processor.prototype.buildRCW = function(descriptorCall) {
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B5500Processor.prototype.applyRCW = function(word) {
|
||||
B5500Processor.prototype.applyRCW = function(word, inline) {
|
||||
/* Set processor state from fields of the Return Control Word in
|
||||
the "word" parameter. Returns the state of the OPDC/DESC bit [2:1] */
|
||||
the "word" parameter. If "inline" is truthy, C & L are NOT restored from
|
||||
the RCW. Returns the state of the OPDC/DESC bit [2:1] */
|
||||
var f;
|
||||
|
||||
this.C = f = word % 0x8000; // [33:15]
|
||||
f = word % 0x8000; // [33:15]
|
||||
if (!inline) {
|
||||
this.C = f;
|
||||
this.access(0x30); // P = [C], fetch new program word
|
||||
}
|
||||
word = (word-f)/0x8000;
|
||||
this.F = f = word % 0x8000; // [18:15]
|
||||
word = (word-f)/0x8000;
|
||||
@@ -749,7 +754,10 @@ B5500Processor.prototype.applyRCW = function(word) {
|
||||
word = (word-f)/0x08;
|
||||
this.G = f = word % 0x08; // [12:3]
|
||||
word = (word-f)/0x08;
|
||||
this.L = f = word % 0x04; // [10:2]
|
||||
f = word % 0x04; // [10:2]
|
||||
if (!inline) {
|
||||
this.L = f;
|
||||
}
|
||||
word = (word-f)/0x04;
|
||||
this.V = f = word % 0x08; // [7:3]
|
||||
word = (word-f)/0x08;
|
||||
@@ -770,7 +778,7 @@ B5500Processor.prototype.enterCharModeInline() {
|
||||
} else {
|
||||
this.access(0x02) // A = [S]: tank the DI address
|
||||
}
|
||||
this.B = this.buildRCW(false);
|
||||
this.B = this.buildRCW(0);
|
||||
this.adjustBEmpty();
|
||||
this.MSFF = 0;
|
||||
this.SALF = 1;
|
||||
@@ -852,9 +860,10 @@ B5500Processor.prototype.enterSubroutine = function(descriptorCall) {
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B5500Processor.prototype.exitSubroutine = function() {
|
||||
B5500Processor.prototype.exitSubroutine = function(inline) {
|
||||
/* Exits a subroutine by restoring the processor state from RCW and MSCW words
|
||||
in the stack. The RCW is assumed to be in the B register, pointing to the MSCW.
|
||||
in the stack. "inline" indicates the C & L registers are NOT restored from the
|
||||
RCW. The RCW is assumed to be in the B register, pointing to the MSCW.
|
||||
The A register is not affected by this routine. If SALF & MSFF bits in the MSCW
|
||||
are set, link back through the MSCWs until one is found that has either bit not
|
||||
set, and store that MSCW at [R]+7. This is the last prior MSCW that actually
|
||||
@@ -873,9 +882,8 @@ B5500Processor.prototype.exitSubroutine = function() {
|
||||
cc.signalInterrupt();
|
||||
}
|
||||
} else { // flag bit is set
|
||||
result = this.applyRCW(this.B);
|
||||
result = this.applyRCW(this.B, inline);
|
||||
this.X = this.B % 0x8000000000; // save F setting from MSCW to restore S at end
|
||||
this.access(0x30); // P = [C], C set from RCW
|
||||
|
||||
this.S = this.F;
|
||||
this.access(0x03); // B = [S], fetch the MSCW
|
||||
@@ -902,7 +910,7 @@ B5500Processor.prototype.operandCall = function() {
|
||||
machines. Assumes the syllable has already loaded a word into A.
|
||||
See Figures 6-1, 6-3, and 6-4 in the B5500 Reference Manual */
|
||||
var aw; // local copy of A reg value
|
||||
var interrupted = false; // interrupt occurred
|
||||
var interrupted = 0; // interrupt occurred
|
||||
|
||||
aw = this.A;
|
||||
if (aw >= 0x800000000000) {
|
||||
@@ -928,7 +936,7 @@ B5500Processor.prototype.operandCall = function() {
|
||||
|
||||
case 7:
|
||||
// Present program descriptor
|
||||
this.enterSubroutine(false);
|
||||
this.enterSubroutine(0);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
@@ -962,7 +970,7 @@ B5500Processor.prototype.descriptorCall = function() {
|
||||
that the address of that word is in M.
|
||||
See Figures 6-2, 6-3, and 6-4 in the B5500 Reference Manual */
|
||||
var aw = this.A; // local copy of A reg value
|
||||
var interrupted = false; // interrupt occurred
|
||||
var interrupted = 0; // interrupt occurred
|
||||
|
||||
if (aw < 0x800000000000) {
|
||||
// It's a simple operand
|
||||
@@ -982,7 +990,7 @@ B5500Processor.prototype.descriptorCall = function() {
|
||||
|
||||
case 7:
|
||||
// Present program descriptor
|
||||
this.enterSubroutine(true);
|
||||
this.enterSubroutine(1);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
@@ -1039,6 +1047,13 @@ B5500Processor.prototype.run = function() {
|
||||
variant = opcode >>> 6;
|
||||
switch (opcode & 0x3F) {
|
||||
case 0x00: // XX00: CMX, EXC: Exit character mode
|
||||
this.adjustBEmpty(); // store destination string
|
||||
this.S = this.F;
|
||||
this.access(0x03); // B = [S], fetch the RCW
|
||||
this.exitSubroutine(variant & 0x01); // exit vs. exit inline
|
||||
this.AROF = this.BROF = 0;
|
||||
this.X = this.M = this.N = 0;
|
||||
this.CWMF = 0;
|
||||
break;
|
||||
|
||||
case 0x02: // XX02: BSD=Skip bit destination
|
||||
@@ -1082,11 +1097,11 @@ B5500Processor.prototype.run = function() {
|
||||
break;
|
||||
|
||||
case 0x18: // 3011: SFI=Store for Interrupt
|
||||
this.storeForInterrupt(false);
|
||||
this.storeForInterrupt(0);
|
||||
break;
|
||||
|
||||
case 0x1C: // 3411: SFT=Store for Test
|
||||
this.storeForInterrupt(true);
|
||||
this.storeForInterrupt(1);
|
||||
break;
|
||||
|
||||
default: // Anything else is a no-op
|
||||
@@ -1253,14 +1268,14 @@ B5500Processor.prototype.run = function() {
|
||||
|
||||
case 2: // OPDC: Operand Call
|
||||
this.adjustAEmpty();
|
||||
computeRelativeAddr(opcode >>> 2, true);
|
||||
computeRelativeAddr(opcode >>> 2, 1);
|
||||
this.access(0x04); // A = [M]
|
||||
this.operandCall();
|
||||
break;
|
||||
|
||||
case 3: // DESC: Descriptor (name) Call
|
||||
this.adjustAEmpty();
|
||||
computeRelativeAddr(opcode >>> 2, true);
|
||||
computeRelativeAddr(opcode >>> 2, 1);
|
||||
this.access(0x04); // A = [M]
|
||||
this.descriptorCall();
|
||||
break;
|
||||
@@ -1346,7 +1361,7 @@ B5500Processor.prototype.run = function() {
|
||||
if (!this.NCSF && cc.P2 && cc.P2BF) {
|
||||
cc.HP2F = 1;
|
||||
// We know P2 is not currently running on this thread, so save its registers
|
||||
cc.P2.storeForInterrupt(false);
|
||||
cc.P2.storeForInterrupt(0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1354,16 +1369,16 @@ B5500Processor.prototype.run = function() {
|
||||
break;
|
||||
|
||||
case 0x18: // 3011: SFI=Store for Interrupt
|
||||
this.storeForInterrupt(false);
|
||||
this.storeForInterrupt(0);
|
||||
break;
|
||||
|
||||
case 0x1C: // 3411: SFT=Store for Test
|
||||
this.storeForInterrupt(true);
|
||||
this.storeForInterrupt(1);
|
||||
break;
|
||||
|
||||
case 0x21: // 4111: IP1=Initiate Processor 1
|
||||
if (!this.NCSF) {
|
||||
this.initiate(false);
|
||||
this.initiate(0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1652,7 +1667,7 @@ B5500Processor.prototype.run = function() {
|
||||
this.adjustAFull();
|
||||
this.S = this.F;
|
||||
this.access(0x03); // B = [S], fetch the RCW
|
||||
switch (this.exitSubroutine()) {
|
||||
switch (this.exitSubroutine(0)) {
|
||||
case 0:
|
||||
this.X = 0;
|
||||
operandCall();
|
||||
@@ -1667,13 +1682,13 @@ B5500Processor.prototype.run = function() {
|
||||
this.AROF = 0;
|
||||
this.S = this.F;
|
||||
this.access(0x03); // B = [S], fetch the RCW
|
||||
this.exitSubroutine();
|
||||
this.exitSubroutine(0);
|
||||
break;
|
||||
|
||||
case 0x0A: // 1235: RTS=return special
|
||||
this.adjustAFull();
|
||||
this.access(0x03); // B = [S], fetch the RCW
|
||||
switch (this.exitSubroutine()) {
|
||||
switch (this.exitSubroutine(0)) {
|
||||
case 0:
|
||||
this.X = 0;
|
||||
operandCall();
|
||||
@@ -1681,6 +1696,8 @@ B5500Processor.prototype.run = function() {
|
||||
this.Q |= 0x10; // set Q05F, for display only
|
||||
this.X = 0;
|
||||
descriptorCall();
|
||||
case 2: // flag-bit interrupt occurred, do nothing
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1709,7 +1726,7 @@ B5500Processor.prototype.run = function() {
|
||||
this.adjustBEmpty();
|
||||
this.F = this.S;
|
||||
if (!this.MSFF) {
|
||||
if (this.SALF) {
|
||||
if (this.SALF) { // store the MSCW at R+7
|
||||
this.M = (this.R*64) + 7;
|
||||
this.access(0x0D); // [M] = B
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user