1
0
mirror of https://github.com/pkimpel/retro-b5500.git synced 2026-02-11 10:55:09 +00:00

Commit DCMCP transcription as of 2012-12-28; debug SPO input and several Processor syllables.

This commit is contained in:
paul
2012-12-29 01:17:16 +00:00
parent dcf7733897
commit 8d602643dc
6 changed files with 239 additions and 108 deletions

View File

@@ -18377,3 +18377,110 @@ REAL SUBROUTINE SCAN; 20589950
P(RCW,MYMSCW,STF); 20590010
RCW:=RCW & P(XCH)[CTC]; 20590020
T:= SCAN; CN:= ACCUM[0]; 20590050
T~SCAN; IF T!EQUAL THEN GO ERROR; 20590100
FOR T:= 0 STEP 1 UNTIL 31 DO 20590150
IF CN.[6:18]=TINU[T].[30:18] THEN GO TO U1; 20590200
GO ERROR; 20590250
U1: IF LABELTABLE[T] NEQ @314 THEN BEGIN CCUNIT:=6; GO EXIT END; 20590300
CN:= SCAN; 20590350
MULTITABLE[T]:=RDCTABLE[T]:=0; 20590400
LABELTABLE[T]:= ACCUM[0]; 20590450
IF (CN:= SCAN) = SLASH THEN 20590500
BEGIN MULTITABLE[T]:= LABELTABLE[T]; 20590550
CN~SCAN; LABELTABLE[T]~ACCUM[0]; CN~SCAN; 20590600
END; 20590610
IF CN=COMMA THEN 20590650
BEGIN IF(CN~SCAN)!IDENT OR KOUNT>3 THEN GO ERROR; 20590655
STREAM(R~0:KOUNT,ACCUM); 20590660
BEGIN SI~ACCUM;SI~SI+1;DI~LOC R;DS~KOUNT OCT END; 20590665
RDCTABLE[T]~P(XCH,RDCTABLE[T])&P(XCH)[14:38:10]; 20590668
IF(CN~SCAN)=COMMA THEN 20590670
BEGIN IF(CN~SCAN)!IDENT OR KOUNT>5 THEN GO ERROR; 20590675
STREAM(R~0:KOUNT,ACCUM); 20590680
BEGIN SI~ACCUM;SI~SI+1;DI~LOC R;DS~KOUNT OCT END; 20590685
RDCTABLE[T]~P(XCH,RDCTABLE[T])&P(XCH)[24:31:17]; 20590688
IF(CN~SCAN)=COMMA THEN 20590690
BEGIN IF(CN~SCAN)!IDENT OR KOUNT>2 THEN GO ERROR; 20590695
STREAM(R~0:KOUNT,ACCUM); 20590700
BEGIN SI~ACCUM;SI~SI+1;DI~LOC R;DS~KOUNT OCT END; 20590705
RDCTABLE[T]~P(XCH,RDCTABLE[T])&P(XCH)41:41:17]; 20590710
END %CYCLE 20590715
END %CREATION DATE 20590720
END; %REEL NUMBER 20590725
IF CN! PERIO THEN DO CN~SCAN UNTIL CN=PERIO;CCUNIT~0;GO EXIT; 20590730
ERROR: CCUNIT~6; 20590740
EXIT: RETURNVAL:=PROCVAL; % ADJUST RESULT OF TYPED PROC 20590750
P([RETURNRCW],STS,0,RDS,0,XCH,P&P[CTF],STF); 20590751
END CCUNIT; 20590800
REAL PROCEDURE CCSECMAINT; 20590850
BEGIN LABEL EXIT,CCC; 20590910
DECLARECCVARIABLES; 20591000
REAL SUBROUTINE SCAN; 20591350
SCAN~SCN(UNITNO,CARDLOC,SOURCE,ACCUM,KOUNT,LASTSCAN,DIRECT); 20591400
LABEL OPTNO,OPTN,OPTN2,SEC1,SEC2,SEC5,ST1, 20591500
ST2,LS; 20591550
SWITCH SW:=OPTNO,OPTN1,OPTN2; 20591600
P(RCW,MYMSCW,STF); 20591610
RCW:=RCW & P(XCH)[CTC]; 20591620
GO TO SW[OPTNN]; 20591650
OPTNO: USERID:= ABS(USERID); 20591700
IF SCAN LSS IDENT THEN BEGIN CCSECMAINT:=6;GO EXIT END; 20591750
SMID:= CMM[0]:= ACCUM[0]; CN:=SCAN; 20591800
IF SCAN LSS IDENT THEN BEGIN CCSECMAINT:=6; GO EXIT END; 20591850
SFID:= CMM[1]:= ACCUM[0]; CDEX:= 0; 20591900
IF (SFH:=DIRECTORYSEARCH(SMID,SFID,4))=0 THEN GO TO LS; 20591950
IF NOT(SYSTEMFILE(CMM[CDEX] ,CMM[CDEX+1]) OR 20592000
(SMID EQV "PBD ")=NOT 0) AND (M[SFH+5]=0 20592050
AND M[SFH+2] NEQ 0) THEN 20592100
% INHIBIT USE ON PUBLIC, SECURE FILES 20592150
BEGIN CN:=SCAN; GO TO OPTN2 END; 20592200
OPTN:=0; CMM[2]:= SFH; 20592250
P(DIRECTORYSEARCH(NABS(CMM[0]),CMM[1],14),DEL); 20592300
OPTN1: STREAM(USERID,Q:=USERID>0,B:=[CMM],D:=CN:=SPACE(10)); 20592400
BEGIN Q(SI:=LOC USERID; SI:=SI+1;DS:=LIT " "; DS:= 7CHR;); 20592450
DS:= 17LIB " INVALID USER OF "; SI:=B; 20592500
SI:=SI+1; DS:= 7CHR; DS:=LIT "/"; SI:=SI+1; DS:= 7CHR; 20592550
DS:=LIT"~"; 20592600
END STREAM; 20592650
SPOUTER( CN&CARD[9:9:9], SPOUTUNIT, 1 ); % 20592700
FORGETSPACE(CMM[2]); 20592725
IF OPTN NEQ 0 THEN GO TO SEC5; 20592750
IF UNITNO GEQ 32 THEN BEGIN CCSECMAINT:=5;GO EXIT END; 20592800
GO TO CCC; 20592850
OPTN2: CMM[5]:=USERID; 20592900
ST:= CDEX:= 0; 20592950
SEC1: FOR OPTN:=0 STEP 1 UNTIL 1 DO 20593000
BEGIN CN:=SCAN; 20593050
IF T=OPEN AND CN=UNLOCKV AND OPTN=0 THEN 20593060
BEGIN T:=UNLOCKV; GO TO SEC1 END 20593100
ELSE IF CN LSS IDENT AND CN NEQ EQUAL THEN GO TO ST1; 20593150
CMM[OPTN]:= IF CN=EQUAL THEN -1 ELSE ACCUM[0]; 20593200
CN:=SCAN; 20593250
END; 20593300
IF CN=WITH THEN BEGIN CN~SCAN;CMM[6]~IF CN}IDENT THEN ACCUM[0] 20593310
ELSE USERID; CN~SCAN END ELSE CMM[6]~USERID; 20593320
IF CMM[0] GEQ 0 AND CMM[1] GEQ 0 THEN GO TO SEC2; 20593350
N1:= CMM[0]; N2:= CMM[1]; N3:= 0; ST:= 1; 20593400
ST2: SEEKNAM(N1,N2,N3,CMM[0],CMM[1],T1,P(0)); 20593450
IF N3 NEQ 0 THEN GO TO SEC2; 20593500
ST:= 0; GO TO SEC5; 20593550
SEC2: IF (ABS(USERID)EQV MCP) NEQ NOT 0 THEN 20593600
IF SYSTEMFILE(CMM[CDEX],CMM[CDEX+1]) OR 20593650
(CMM[0] EQV "PBD ")= NOT 0 THEN GO SEC5; 20593700
SECURITYMAINT(T,SMID,SFID,CMM,SFH,SPOUTUNIT); 20593750
SEC5: IF ST THEN GO TO ST2; 20593800
IF CN=COMMA THEN GO SEC1; 20593850
IF T=USEV THEN 20593900
HEADERUNLOCK(SMID,SFID,SFH); 20593950
GO TO CCC; 20594000
LS: LBMESS(CMM[0],CMM[1],-15,0,0,SPOUTUNIT,LIBERR); %149-20594350
IF UNITNO GEQ 32 THEN BEGIN CCSECMAINT:=5; GO EXIT END; 20594400
CCC: DO T~SCAN UNTIL T>IDENT AND T{RESETV; 20594450
IF UNITNO=31 THEN BEGIN CCSECMAINT:=7; GO EXIT; END; 20594500
CCSECMAINT:=1; GO EXIT; 20594550
ST1: IF T=USEV THEN 20594600
HEADERUNLOCK(SMID,SFID,SFH); 20594650
CCSECMAINT:=6; 20594700
EXIT: RETURNVAL:=PROCVAL; % ADJUST RESULT OF TYPED PROC 20594750
P([RETURNRCW],STS,0,RDS,0,XCH,P&P[CTF],STF); 20594751
END CCSECMAINT; 20594800

View File

@@ -390,7 +390,7 @@ B5500CentralControl.prototype.signalInterrupt = function() {
any remaining interrupts after an interrupt is handled. If no interrupt
condition exists, this.IAR is set to zero. */
var p1 = this.P1;
var p2 = this.P2;
var p2;
this.IAR = p1.I & 0x01 ? 0x30 // @60: P1 memory parity error
: p1.I & 0x02 ? 0x31 // @61: P1 invalid address error
@@ -410,7 +410,7 @@ B5500CentralControl.prototype.signalInterrupt = function() {
: this.CCI16F ? 0x1F // @37: Disk file 2 read check finished
: p1.I & 0x04 ? 0x32 // @62: P1 stack overflow
: p1.I & 0xF0 ? (p1.I >>> 4) + 0x30 // @64-75: P1 syllable-dependent
: p2 ?
: (p2 = this.P2) ?
( p2.I & 0x01 ? 0x20 // @40: P2 memory parity error
: p2.I & 0x02 ? 0x21 // @41: P2 invalid address error
: p2.I & 0x04 ? 0x22 // @42: P2 stack overflow
@@ -537,8 +537,10 @@ B5500CentralControl.prototype.tock = function tock() {
that.TM++;
} else {
that.TM = 0;
/********** INHIBIT FOR NOW **********
that.CCI03F = 1; // set timer interrupt
// >>>>> inhibit for now >>>>> that.signalInterrupt();
that.signalInterrupt();
*************************************/
}
interval = (that.nextTimeStamp += B5500CentralControl.rtcTick) - thisTime;
that.timer = setTimeout(function() {that.tock()}, (interval < 0 ? 1 : interval));
@@ -823,13 +825,13 @@ B5500CentralControl.prototype.configureSystem = function() {
function makeSignal(cc, mnemonic) {
switch (mnemonic) {
case "SPO":
return function() {cc.CCIO5F = 1; cc.signalInterrupt()};
return function() {cc.CCI05F = 1; cc.signalInterrupt()};
break;
case "LPA":
return function() {cc.CCIO6F = 1; cc.signalInterrupt()};
return function() {cc.CCI06F = 1; cc.signalInterrupt()};
break;
case "LPB":
return function() {cc.CCIO7F = 1; cc.signalInterrupt()};
return function() {cc.CCI07F = 1; cc.signalInterrupt()};
break;
case "DKA":
return function() {cc.CCI15F = 1; cc.signalInterrupt()};

View File

@@ -285,7 +285,7 @@ B5500IOUnit.prototype.fetchBuffer = function(mode, words) {
this.Daddress = addr;
if (this.D23F) {
this.DwordCount = words % 0x1FF;
this.DwordCount = words & 0x1FF;
}
return count;
};
@@ -341,7 +341,7 @@ B5500IOUnit.prototype.fetchBufferWithGM = function(mode, words) {
this.Daddress = addr;
if (this.D23F) {
this.DwordCount = words % 0x1FF;
this.DwordCount = words & 0x1FF;
}
return count;
};
@@ -359,11 +359,11 @@ B5500IOUnit.prototype.storeBuffer = function(chars, offset, mode, words) {
var buf = this.buffer; // local pointer to buffer
var c; // current character code
var count = 0; // number of characters fetched
var done = (words > 0); // loop control
var done = (words == 0); // loop control
var overflow = false; // memory address overflowed max
var power = 0x40000000000; // factor for character shifting into a word
var s = 0; // character shift counter
var table = (mode ? B5500IOUnit.BICtoANSI : B5500IOUnit.BICtoBCLANSI);
var table = (mode ? B5500IOUnit.ANSItoBIC : B5500IOUnit.BCLANSItoBIC);
var w = 0; // local copy of this.W
while (!done) { // loop through the words
@@ -413,7 +413,7 @@ B5500IOUnit.prototype.storeBuffer = function(chars, offset, mode, words) {
this.Daddress = addr;
if (this.D23F) {
this.DwordCount = words % 0x1FF;
this.DwordCount = words & 0x1FF;
}
return count;
};
@@ -434,11 +434,11 @@ B5500IOUnit.prototype.storeBufferWithGM = function(chars, offset, mode, words) {
var buf = this.buffer; // local pointer to buffer
var c; // current character code
var count = 0; // number of characters fetched
var done = (words > 0); // loop control
var done = (words == 0); // loop control
var overflow = false; // memory address overflowed max
var power = 0x40000000000; // factor for character shifting into a word
var s = 0; // character shift counter
var table = (mode ? B5500IOUnit.BICtoANSI : B5500IOUnit.BICtoBCLANSI);
var table = (mode ? B5500IOUnit.ANSItoBIC : B5500IOUnit.BCLANSItoBIC);
var w = 0; // local copy of this.W
while (!done) { // loop through the words
@@ -471,11 +471,10 @@ B5500IOUnit.prototype.storeBufferWithGM = function(chars, offset, mode, words) {
}
} // while !done
if (!mode) { // alpha transfer terminates with a group-mark
w += 0x1F*power; // set group mark in register
s++;
count++;
}
w += 0x1F*power; // set group mark in register
s++;
count++;
if (s > 0 && words > 0) { // partial word left to be stored
this.W = w;
if (overflow) {
@@ -493,7 +492,7 @@ B5500IOUnit.prototype.storeBufferWithGM = function(chars, offset, mode, words) {
this.Daddress = addr;
if (this.D23F) {
this.DwordCount = words % 0x1FF;
this.DwordCount = words & 0x1FF;
}
return count;
};
@@ -593,7 +592,7 @@ B5500IOUnit.prototype.initiate = function() {
this.finish();
} else {
this.EXNF = 1;
this.Daddress = addr = this.W % 0x7FFF;
this.Daddress = addr = this.W % 0x8000;
if (this.fetch(addr)) { // fetch the IOD from that address
this.finish();
} else {
@@ -608,7 +607,7 @@ B5500IOUnit.prototype.initiate = function() {
this.D23F = (x >>> 24) & 1; // use word counter
this.D24F = (x >>> 23) & 1; // write/read
this.LP = (x >>> 15) & 0x3F;// save control bits for drum and printer
this.Daddress = x % 0x7FFF;
this.Daddress = x % 0x8000;
this.busyUnit = index = B5500CentralControl.unitIndex[this.D24F & 1][this.Dunit & 0x1F];
if (this.cc.testUnitBusy(this.ioUnitID, this.busyUnit)) {

View File

@@ -325,10 +325,8 @@ B5500Processor.prototype.exchangeTOS = function() {
}
} else {
if (this.BROF) {
// A is empty and B is full, so copy B to A and load B from [S]
this.A = this.B;
this.AROF = 1;
this.access(0x03); // B = [S]
// A is empty and B is full, so load A from [S]
this.access(0x02); // A = [S]
this.S--;
} else {
// A and B are empty, so simply load them in reverse order
@@ -1250,11 +1248,6 @@ B5500Processor.prototype.singlePrecisionCompare = function() {
ea = (this.A - ma)/0x8000000000;
sa = ((ea >>> 7) & 0x01);
ea = (ea & 0x40 ? -(ea & 0x3F) : (ea & 0x3F));
while (ma < 0x1000000000 && ea != eb) {
this.cycleCount++;
ma *= 8; // shift left
ea--;
}
}
if (mb == 0) { // if B mantissa is zero
eb = sb = 0; // consider B to be completely zero
@@ -1262,6 +1255,15 @@ B5500Processor.prototype.singlePrecisionCompare = function() {
eb = (this.B - mb)/0x8000000000;
sb = (eb >>> 7) & 0x01;
eb = (eb & 0x40 ? -(eb & 0x3F) : (eb & 0x3F));
}
if (ma) { // normalize the A mantissa
while (ma < 0x1000000000 && ea != eb) {
this.cycleCount++;
ma *= 8; // shift left
ea--;
}
}
if (mb) { // normalize the B mantissa
while (mb < 0x1000000000 && eb != ea) {
this.cycleCount++;
mb *= 8; // shift left
@@ -1272,7 +1274,7 @@ B5500Processor.prototype.singlePrecisionCompare = function() {
// Compare signs, exponents, and normalized magnitudes, in that order.
if (sb == sa) { // if signs are equal:
if (eb == ea) { // if exponents are equal:
if (mb = ma) { // if magnitudes are equal:
if (mb == ma) { // if magnitudes are equal:
return 0; // then the operands are equal
} else if (mb > ma) { // otherwise, if magnitude of B > A:
return (sb ? -1 : 1); // B<A if B negative, B>A if B positive
@@ -3324,7 +3326,7 @@ B5500Processor.prototype.run = function() {
this.L = 0;
this.S = 0x40; // stack address @100
this.cc.clearInterrupt();
this.cc.access(0x30); // P = [C]
this.access(0x30); // P = [C]
}
break;
@@ -3332,6 +3334,7 @@ B5500Processor.prototype.run = function() {
if (!this.NCSF) { // control-state only
this.adjustAEmpty();
this.A = this.cc.CCI03F*64 + this.cc.TM;
this.AROF = 1;
}
break;
@@ -3442,18 +3445,18 @@ B5500Processor.prototype.run = function() {
t2 = (this.A - t1) / 0x1000000;
t3 = this.B % 0x1000000;
t4 = (this.B - t3) / 0x1000000;
this.A = ((t4 & 0x7FFFFF) | (t2 & t4 & 0x7FFFFF))*0x1000000 + (t1 & t3);
this.A = ((t4 & 0x800000) | (t2 & t4 & 0x7FFFFF))*0x1000000 + (t1 & t3);
this.BROF = 0;
break;
case 0x08: // 1015: LQV=logical EQV
this.cycleCount += 8;
this.cycleCount += 16;
this.adjustABFull();
t1 = this.A % 0x1000000;
t2 = (this.A - t1) / 0x1000000;
t3 = this.B % 0x1000000;
t4 = (this.B - t3) / 0x1000000;
this.B = ((t4 & 0x7FFFFF) | ((~(t2 ^ t4)) & 0x7FFFFF))*0x1000000 + ((~(t1 ^ t3)) & 0xFFFFFF);
this.B = ((t4 & 0x800000) | ((~(t2 ^ t4)) & 0x7FFFFF))*0x1000000 + ((~(t1 ^ t3)) & 0xFFFFFF);
this.AROF = 0;
break;
@@ -3521,7 +3524,7 @@ B5500Processor.prototype.run = function() {
case 0x10: // 2025: DUP=Duplicate TOS
if (this.AROF) {
this.AdjustBEmpty();
this.adjustBEmpty();
this.B = this.A;
this.BROF = 1;
} else {

View File

@@ -35,8 +35,13 @@ function B5500SPOUnit(mnemonic, unitIndex, designate, statusChange, signal) {
this.backspaceChar.that = this; // Store object context for these functions
this.printChar.that = this;
this.writeChar.that = this;
this.outputChar.that = this;
this.window = window.open("", "SPOWin");
if (this.window) {
this.window.close(); // destroy the previously-existing window
this.window = null;
}
this.window = window.open("/B5500/B5500SPOUnit.html", "SPOWin", "scrollbars,resizable,width=600,height=500");
this.window.onload = function() {
that.spoOnload();
@@ -58,7 +63,7 @@ B5500SPOUnit.prototype.keyFilter = [ // Filter keyCode values to vali
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, // 40-4F
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x3F,0x5D,0x3F,0x3F, // 50-5F
0x3F,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, // 60-6F
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x3F]; // 70-7F
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x7B,0x7C,0x7D,0x7E,0x3F]; // 70-7F
/**************************************/
B5500SPOUnit.prototype.$$ = function(e) {
@@ -115,11 +120,10 @@ B5500SPOUnit.prototype.removeClass = function(e, name) {
/**************************************/
B5500SPOUnit.prototype.setNotReady = function() {
/* Sets the status of the SPO to Not Ready */
var readyBtn = this.$$("SPOReadyBtn");
if (this.spoState == this.spoLocal) {
this.spoState = this.spoNotReady;
this.removeClass(readyBtn, "yellowLit");
this.removeClass(this.$$("SPOReadyBtn"), "yellowLit");
this.statusChange(0);
}
};
@@ -127,10 +131,9 @@ B5500SPOUnit.prototype.setNotReady = function() {
/**************************************/
B5500SPOUnit.prototype.setReady = function() {
/* Sets the status of the SPO to Ready */
var readyBtn = this.$$("SPOReadyBtn");
if (this.spoState == this.spoNotReady) {
this.addClass(readyBtn, "yellowLit");
this.addClass(this.$$("SPOReadyBtn"), "yellowLit");
this.spoState = this.spoLocal;
}
};
@@ -138,13 +141,11 @@ B5500SPOUnit.prototype.setReady = function() {
/**************************************/
B5500SPOUnit.prototype.setLocal = function() {
/* Sets the status of the SPO to Local */
var localBtn = this.$$("SPOLocalBtn");
var remoteBtn = this.$$("SPORemoteBtn");
if (this.spoState == this.spoRemote) {
this.spoState = this.spoLocal;
this.addClass(localBtn, "yellowLit");
this.removeClass(remoteBtn, "yellowLit");
this.addClass(this.$$("SPOLocalBtn"), "yellowLit");
this.removeClass(this.$$("SPORemoteBtn"), "yellowLit");
this.statusChange(0);
// Set up to echo characters from the keyboard
@@ -160,13 +161,11 @@ B5500SPOUnit.prototype.setLocal = function() {
/**************************************/
B5500SPOUnit.prototype.setRemote = function() {
/* Sets the status of the SPO to Remote */
var localBtn = this.$$("SPOLocalBtn");
var remoteBtn = this.$$("SPORemoteBtn");
if (this.spoState == this.spoLocal) {
this.spoState = this.spoRemote;
this.addClass(remoteBtn, "yellowLit");
this.removeClass(localBtn, "yellowLit");
this.addClass(this.$$("SPORemoteBtn"), "yellowLit");
this.removeClass(this.$$("SPOLocalBtn"), "yellowLit");
this.statusChange(1);
}
};
@@ -217,14 +216,14 @@ B5500SPOUnit.prototype.printChar = function printChar(c) {
};
/**************************************/
B5500SPOUnit.prototype.writeChar = function writeChar() {
B5500SPOUnit.prototype.outputChar = function outputChar() {
/* Outputs one character from the buffer to the SPO. If more characters remain
to be printed, schedules itself 100 ms later to print the next one, otherwise
calls finished(). If the column counter exceeds 72, a CR/LF pair is output.
A CR/LF pair is also output at the end of the message. Note the use of the local
function property "that" (initialized in the constructor), which supplies the
necessary SPOUnit object context across setTimeout() calls */
var that = writeChar.that; // retrieve our object context
var that = outputChar.that; // retrieve our object context
var nextTime = that.nextCharTime + that.charPeriod;
var delay = nextTime - new Date().getTime();
@@ -234,19 +233,19 @@ B5500SPOUnit.prototype.writeChar = function writeChar() {
that.printChar(that.buffer[that.bufIndex]);
that.bufIndex++;
that.printCol++;
setTimeout(that.writeChar, delay);
setTimeout(that.outputChar, delay);
} else { // set up for the final CR/LF
that.printCol = 72;
setTimeout(that.writeChar, delay);
setTimeout(that.outputChar, delay);
}
} else if (that.printCol == 72) { // delay to fake the output of a new-line
that.printCol++;
setTimeout(that.writeChar, delay+that.charPeriod);
setTimeout(that.outputChar, delay+that.charPeriod);
} else { // actually output the CR/LF
that.appendEmptyLine();
if (that.bufIndex < that.bufLength) {
that.printCol = 0; // more characters to print after the CR/LF
setTimeout(that.writeChar, delay);
setTimeout(that.outputChar, delay);
} else { // message text is exhausted
that.finish(that.errorMask, that.bufLength); // report finish with any errors
if (that.spoLocalRequested) {
@@ -261,14 +260,14 @@ B5500SPOUnit.prototype.writeChar = function writeChar() {
/**************************************/
B5500SPOUnit.prototype.terminateInput = function() {
/* Handles the End of Message event. Turns off then Input Request lamp, then
calls writeChar(), which will find bufIndex==bufLength, output a new-line,
calls outputChar(), which will find bufIndex==bufLength, output a new-line,
set the state to Remote, and call finish() for us. Slick, eh? */
if (this.spoState == this.spoInput) {
this.removeClass(this.$$("SPOInputRequestBtn"), "yellowLit");
this.bufLength = this.bufIndex;
this.nextCharTime = new Date().getTime();
this.writeChar();
this.outputChar();
}
};
@@ -282,7 +281,7 @@ B5500SPOUnit.prototype.cancelInput = function() {
this.errorMask |= 0x10; // set parity/error-button bit
this.bufLength = this.bufIndex;
this.nextCharTime = new Date().getTime();
this.writeChar();
this.outputChar();
}
};
@@ -305,13 +304,22 @@ B5500SPOUnit.prototype.keyPress = function(ev) {
}
this.nextCharTime = nextTime;
if (this.spoState == this.spoInput) {
if (c >= 32 && c <= 126) {
if (c >= 32 && c < 126) {
this.buffer[this.bufIndex++] = c = this.keyFilter[c];
if (this.printCol < 72) {
this.printCol++;
}
setTimeout(function() {that.printChar(c)}, nextTime-stamp);
}
if (c == 126) { // "~" (B5500 group-mark)
c = this.keyFilter[c];
if (this.printCol < 72) {
this.printCol++;
}
setTimeout(function() {that.printChar(c)}, nextTime-stamp);
this.nextCharTime = nextTime + this.charPeriod;
this.terminateInput();
}
} else if (this.spoState == this.spoLocal) {
if (c >= 32 && c <= 126) {
c = this.keyFilter[c];
@@ -360,7 +368,6 @@ B5500SPOUnit.prototype.keyDown = function(ev) {
result = false;
break;
case 13: // Enter
case 126: // "~" (B5500 left arrow/group mark)
this.terminateInput();
result = false;
break;
@@ -401,7 +408,7 @@ B5500SPOUnit.prototype.printText = function(msg, finish) {
this.printCol = 0;
this.nextCharTime = new Date().getTime();
this.finish = finish;
this.writeChar(); // start the printing process
this.outputChar(); // start the printing process
};
/**************************************/
@@ -419,7 +426,7 @@ B5500SPOUnit.prototype.spoOnload = function() {
this.window.resizeTo(this.window.outerWidth+this.$$("SPODiv").scrollWidth-this.window.innerWidth+8,
this.window.outerHeight+this.$$("SPODiv").scrollHeight-this.window.innerHeight+8);
this.window.moveTo(screen.availWidth-this.window.outerWidth-8, screen.availHeight-this.window.outerHeight-8);
this.window.moveTo(0/*screen.availWidth-this.window.outerWidth-8*/, screen.availHeight-this.window.outerHeight-8);
this.window.focus();
this.$$("SPORemoteBtn").onclick = function() {
@@ -476,13 +483,14 @@ B5500SPOUnit.prototype.read = function(finish, buffer, length, mode, control) {
switch (this.spoState) {
case this.spoRemote:
this.spoState = this.spoInput;
this.addClass(inputBtn, "yellowLit");
this.addClass(this.$$("SPOInputRequestBtn"), "yellowLit");
this.buffer = buffer;
this.bufLength = length;
this.bufIndex = 0;
this.printCol = 0;
this.nextCharTime = new Date().getTime();
this.finish = finish;
this.window.focus();
break;
case this.spoOutput:
case this.spoInput:
@@ -515,7 +523,8 @@ B5500SPOUnit.prototype.write = function(finish, buffer, length, mode, control) {
this.printCol = 0;
this.nextCharTime = new Date().getTime();
this.finish = finish;
this.writeChar(); // start the printing process
this.window.focus();
this.outputChar(); // start the printing process
break;
case this.spoOutput:
case this.spoInput:

View File

@@ -29,9 +29,13 @@ var accessor = { // Memory access control block
MAED: 0 // Truthy if memory address/inhibit error
};
function $$(id) {
return document.getElementById(id);
}
function setText(id, text) {
/* Replaces the children of the node having id="id" with a text node containing "text" */
var e = document.getElementById(id);
var e = $$(id);
var f;
if (!e) {
@@ -114,7 +118,7 @@ function padOctal(value, octades) {
function displayOctal(id, value, octades) {
/* Formats the "value" as octal of length "octades" and sets the "id".value
property with the result */
var e = document.getElementById(id);
var e = $$(id);
e.value = padOctal(value, octades);
}
@@ -163,16 +167,16 @@ function displayStack() {
displayOctal("AReg", cc.P1.A, 16);
displayNumber("ARegValue", cc.P1.A);
document.getElementById("AROF").checked = (cc.P1.AROF != 0);
$$("AROF").checked = (cc.P1.AROF != 0);
displayOctal("BReg", cc.P1.B, 16);
displayNumber("BRegValue", cc.P1.B);
document.getElementById("BROF").checked = (cc.P1.BROF != 0);
$$("BROF").checked = (cc.P1.BROF != 0);
for (x=0; x<=7; x++) {
addr = cc.P1.S - x;
setText("SAddr" + x, padOctal(addr, 5));
e = document.getElementById("SWord" + x);
e = $$("SWord" + x);
valueID = e.getAttribute("data-b55sd-valueID");
displayMemWord(e, addr, valueID);
}
@@ -194,7 +198,7 @@ function displayMemory() {
} else {
setText("MAddr" + suffix, padOctal(addr, 5));
}
e = document.getElementById("MWord" + suffix);
e = $$("MWord" + suffix);
valueID = e.getAttribute("data-b55sd-valueID");
displayMemWord(e, addr, valueID);
}
@@ -207,9 +211,9 @@ function displayRegisters() {
displayOctal("CReg", cc.P1.C, 5);
displayOctal("LReg", cc.P1.L, 1);
displayOctal("PReg", cc.P1.P, 16);
document.getElementById("PROF").checked = (cc.P1.PROF != 0);
$$("PROF").checked = (cc.P1.PROF != 0);
displayOctal("TReg", cc.P1.T, 4);
document.getElementById("TROF").checked = (cc.P1.TROF != 0);
$$("TROF").checked = (cc.P1.TROF != 0);
displayOctal("EReg", cc.P1.E, 2);
displayOctal("IReg", cc.P1.I, 3);
displayOctal("QReg", cc.P1.Q, 4);
@@ -224,10 +228,10 @@ function displayRegisters() {
displayOctal("YReg", cc.P1.Y, 2);
displayOctal("ZReg", cc.P1.Z, 2);
displayOctal("NReg", cc.P1.N, 2);
document.getElementById("NCSF").checked = (cc.P1.NCSF != 0);
document.getElementById("CWMF").checked = (cc.P1.CWMF != 0);
document.getElementById("SALF").checked = (cc.P1.SALF != 0);
document.getElementById("VARF").checked = (cc.P1.VARF != 0);
$$("NCSF").checked = (cc.P1.NCSF != 0);
$$("CWMF").checked = (cc.P1.CWMF != 0);
$$("SALF").checked = (cc.P1.SALF != 0);
$$("VARF").checked = (cc.P1.VARF != 0);
}
function displayProcessorState() {
@@ -241,7 +245,7 @@ function displayProcessorState() {
function stepIt(exec) {
/* Simple test driver for the Processor arithmetic ops */
var opcode = 0x02D; // NOOP (XX55) by default
var opList = document.getElementById("OpList")
var opList = $$("OpList")
var saveC;
var saveL;
var saveP;
@@ -257,9 +261,6 @@ function stepIt(exec) {
setText("ARegOrig", padOctal(cc.P1.A, 16));
setText("BRegOrig", padOctal(cc.P1.B, 16));
cc.P1.I = 0; // reset any interrupts
cc.IAR = 0;
cc.P1.X = 0;
if (exec) {
saveT = cc.P1.T;
@@ -339,17 +340,27 @@ function tos_onChange(ev, valueID, origID) {
window.onload = function() {
document.getElementById("AReg").onchange = function(ev) {
$$("LogoDiv").onclick = function(ev) {
displayProcessorState();
};
$$("AReg").onchange = function(ev) {
cc.P1.A = tos_onChange(ev, "ARegValue", "ARegOrig");
cc.P1.AROF = 1;
document.getElementById("AROF").checked = true;
$$("AROF").checked = true;
};
document.getElementById("BReg").onchange = function(ev) {
$$("AROF").onclick = function(ev) {
cc.P1.AROF = (ev.target.checked ? 1 : 0);
}
$$("BReg").onchange = function(ev) {
cc.P1.B = tos_onChange(ev, "BRegValue", "BRegOrig");
cc.P1.BROF = 1;
document.getElementById("BROF").checked = true;
$$("BROF").checked = true;
};
document.getElementById("MAddr").onchange = function(ev) {
$$("BROF").onclick = function(ev) {
cc.P1.BROF = (ev.target.checked ? 1 : 0);
}
$$("MAddr").onchange = function(ev) {
var addr = parseToOctal(ev.target);
if (!isNaN(addr)) {
@@ -357,7 +368,7 @@ window.onload = function() {
displayMemory();
}
};
document.getElementById("SReg").onchange = function(ev) {
$$("SReg").onchange = function(ev) {
var addr = parseToOctal(ev.target);
if (!isNaN(addr)) {
@@ -365,28 +376,28 @@ window.onload = function() {
displayStack();
}
};
document.getElementById("SWord0").onchange = word_onChange;
document.getElementById("SWord1").onchange = word_onChange;
document.getElementById("SWord2").onchange = word_onChange;
document.getElementById("SWord3").onchange = word_onChange;
document.getElementById("SWord4").onchange = word_onChange;
document.getElementById("SWord5").onchange = word_onChange;
document.getElementById("SWord6").onchange = word_onChange;
document.getElementById("SWord7").onchange = word_onChange;
document.getElementById("MWordM4").onchange = word_onChange;
document.getElementById("MWordM3").onchange = word_onChange;
document.getElementById("MWordM2").onchange = word_onChange;
document.getElementById("MWordM1").onchange = word_onChange;
document.getElementById("MWordP0").onchange = word_onChange;
document.getElementById("MWordP1").onchange = word_onChange;
document.getElementById("MWordP2").onchange = word_onChange;
document.getElementById("MWordP3").onchange = word_onChange;
document.getElementById("MWordP4").onchange = word_onChange;
document.getElementById("TReg").onchange = function(ev) {
$$("TReg").onchange = function(ev) {
cc.P1.T = reg_onChange(ev);
};
$$("SWord0").onchange = word_onChange;
$$("SWord1").onchange = word_onChange;
$$("SWord2").onchange = word_onChange;
$$("SWord3").onchange = word_onChange;
$$("SWord4").onchange = word_onChange;
$$("SWord5").onchange = word_onChange;
$$("SWord6").onchange = word_onChange;
$$("SWord7").onchange = word_onChange;
$$("MWordM4").onchange = word_onChange;
$$("MWordM3").onchange = word_onChange;
$$("MWordM2").onchange = word_onChange;
$$("MWordM1").onchange = word_onChange;
$$("MWordP0").onchange = word_onChange;
$$("MWordP1").onchange = word_onChange;
$$("MWordP2").onchange = word_onChange;
$$("MWordP3").onchange = word_onChange;
$$("MWordP4").onchange = word_onChange;
cc = new B5500CentralControl();
cc.powerOn();