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:
@@ -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
|
||||
|
||||
@@ -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()};
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user