diff --git a/SYMBOL/DCMCP.esp_m b/SYMBOL/DCMCP.esp_m index eb06a28..13452c3 100644 --- a/SYMBOL/DCMCP.esp_m +++ b/SYMBOL/DCMCP.esp_m @@ -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 diff --git a/emulator/B5500CentralControl.js b/emulator/B5500CentralControl.js index 66b050d..267b97c 100644 --- a/emulator/B5500CentralControl.js +++ b/emulator/B5500CentralControl.js @@ -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()}; diff --git a/emulator/B5500IOUnit.js b/emulator/B5500IOUnit.js index f7e724c..4f39ce8 100644 --- a/emulator/B5500IOUnit.js +++ b/emulator/B5500IOUnit.js @@ -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)) { diff --git a/emulator/B5500Processor.js b/emulator/B5500Processor.js index f553a9b..2db22ec 100644 --- a/emulator/B5500Processor.js +++ b/emulator/B5500Processor.js @@ -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); // BA 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 { diff --git a/webUI/B5500SPOUnit.js b/webUI/B5500SPOUnit.js index 0fe33bd..5361396 100644 --- a/webUI/B5500SPOUnit.js +++ b/webUI/B5500SPOUnit.js @@ -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: diff --git a/webUI/tools/B5500SyllableDebugger.html b/webUI/tools/B5500SyllableDebugger.html index 0ef104e..8e42249 100644 --- a/webUI/tools/B5500SyllableDebugger.html +++ b/webUI/tools/B5500SyllableDebugger.html @@ -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();