diff --git a/SYMBOL/DCMCP.esp_m b/SYMBOL/DCMCP.esp_m index 4db1a1b..a62baa8 100644 --- a/SYMBOL/DCMCP.esp_m +++ b/SYMBOL/DCMCP.esp_m @@ -22687,3 +22687,202 @@ BEGIN REAL Z,L;% 37359000 IF P THEN BEGIN TERMINATE(P1MIX); TERMINALMESSAGE(-L) END;% 37382000 SPOUTER(L,0,TYPE); 37383000 END FILEMESS;% 37384000 +PROCEDURE FILLBUFFERS(CURRENT,FINAL,COBOL,NR); 37385000 + VALUE CURRENT,FINAL,COBOL,NR; 37385500 + REAL CURRENT,FINAL,COBOL,NR; 37386000 +BEGIN ARRAY LOCAT[*];% 37387000 + INTEGER I,J,K,D;% 37388000 + INTEGER FIRSTLOC=J,PRELOC=K,CURLOC=D; 37388100 + REAL T=LOCAT; 37388200 + REAL T1; 37388250 + REAL NF=T1+1; % MUST BE AT THE TOP OF THE STACK37388275 + LABEL LINK; 37388300 + REAL BSIZE=CURRENT,N=FINAL,U=COBOL,ALPHA=NR; 37388400 + IF ALPHA<512 THEN 37388500 + BEGIN 37388600 + P(NR-(COBOL GTR 0)); % INITIALIZE NF 37388700 + IF COBOL THEN FINAL:=CURRENT; 37388800 + J~FINAL.[33:15]-K~CURRENT.[33:15];% 37389000 + D~2&(NOT CURRENT)[1:22:1];% 37390000 + LOCAT~M[K+D]; NR~NR-1;% 37391000 + FOR I~1 STEP 1 UNTIL NF DO% 37392000 + BEGIN IORREQUEST(FLAG(FINAL),CURRENT,LOCAT);% 37393000 + M[LOCAT]~M[LOCAT]&0[26:26:7] AND NOT(M OR IOMASK);% 37394000 + IF NOT COBOL THEN 37394025 + IF I=1 THEN IF P(FINAL.[3:5],DUP)=6 OR P(XCH)=7 THEN 37394050 + BEGIN 37394100 + SLEEP(LOCAT & 0 [3:3:30],IOMASK); 37394150 + STREAM(N~0,L~0:NDIV64~0,BACC~T1~FINAL.[7:1], 37394200 + BUF ~ (M[LOCAT] INX T1)-(1-T1)); 37394250 + BEGIN DI ~ LOC N; SI ~ BUF; BACC(SI ~ SI+4); 37394260 + IF 4 SC!DC THEN GO OWT; 37394280 + DI ~ LOC N; BACC(SI ~ BUF); DS ~ 4 OCT; 37394300 + SI ~ LOC L; DI ~ LOC BACC; SI ~ SI-2; DI ~ DI-1; 37394350 + DS ~ 1 CHR; SI ~ BUF; 37394360 + CI ~ CI+BACC; GO FWD; 37394400 + NDIV64(SI ~ SI-32; SI ~ SI-32); SI ~ SI-N; SI ~ SI+4; 37394450 + GO ON; 37394460 + FWD: NDIV64(SI ~ SI+32; SI ~ SI+32); SI ~ SI+N; 37394500 + ON: DI ~ LOC L; DS ~ 4 OCT; 37394550 + OWT: 37394560 + END STREAM; 37394600 + T1 ~ P; 37394650 + IF P(DUP)=0 OR P(XCH)!T1 THEN TERMINATE(P1MIX&108[CTF]); 37394700 + END; 37394800 + IF NR>0 THEN STREAM(NR,T~M[LOCAT],LOCAT);% 37395000 + BEGIN SI~LOCAT; SI~SI+8; DS~NR WDS;% 37396000 + SI~LOC T; DS~WDS END;% 37397000 + CURRENT.[33:15]~K~M[K+D].[18:15];% 37398000 + FINAL.[33:15]~K+J;% 37399000 + END END ELSE 37400000 + BEGIN 37401000 + T~ALPHA&U[12:42:6] OR M;% 37404000 + FOR I~N-1 STEP -1 UNTIL 0 DO% 37405000 + BEGIN M[ALPHA+I]~(CURLOC~GETSPACE(BSIZE+4,2,1)+2)+2; 37406000 + $ SET OMIT = NOT(BREAKOUT) 37406099 + IF FIRSTLOC=0 THEN FIRSTLOC~CURLOC;% 37407000 + M[CURLOC+1]~0; MOVE(BSIZE+1,CURLOC+1,CURLOC+2); 37408000 +LINK: M[CURLOC]~FLAG(T)&(PREVLOC+2)[18:33:15];% 37412000 + M[CURLOC+BSIZE+3]~FLAG(T)&(PREVLOC+BSIZE+1)[18:33:15];% 37413000 + PREVLOC~CURLOC;% 37414000 + END;% 37415000 + IF I=(-1) THEN BEGIN CURLOC~FIRSTLOC; GO TO LINK END;% 37416000 + END END FILL OR GET BUFFERS; 37417000 +REAL PROCEDURE FILEHEADER(MID,FID,NROWS,SIZE,BLEN,RLEN,S);% 37418000 + VALUE MID,FID,NROWS,SIZE,BLEN,RLEN,S;% 37419000 + REAL MID,FID;% 37420000 + INTEGER NROWS,SIZE,BLEN,RLEN,S;% 37421000 +BEGIN REAL Q,LPER,SPER; ARRAY T=Q[*]; 37422000 + INTEGER N1,R1,L1,W; 37422100 + $ SET OMIT = NOT SHAREDISK 37422199 + LABEL T1FILL,EXIT; 37422300 + SPER~(BLEN+29) DIV 30;% 37424000 + IF SPER>63 THEN 37424100 + FILEMESS(-"INVALID","BLOCK ",MID,FID,RLEN,BLEN,SPER); 37424200 + IF S.[42:6]=0 THEN RLEN~BLEN;% 37425000 + $ SET OMIT = SHAREDISK 37425499 + Q:=S.[13:3]; 37425500 + $ POP OMIT 37425501 + $ SET OMIT = NOT SHAREDISK 37425599 + LPER~BLEN DIV RLEN;% 37426000 + IF (NROWS+SIZE)=0 THEN% 37427000 + BEGIN 37428000 + IF (N1:=SECURITYCHECK(MID,FID,USERCODE[P1MIX],Q)) LSS 0 THEN 37428100 + $ SET OMIT = NOT SHAREDISK 37428199 + GO TO EXIT; 37428300 + $ SET OMIT = NOT SHAREDISK 37428399 + T:=N1&P(.T,LOD,XCH)[CTF]; 37429000 + $ SET OMIT = NOT SHAREDISK 37429099 + N1~T[7]+1; 37430000 + IF(L1~T[0].[1:14])=0 THEN L1~30; 37431000 + R1~T[0].[30:12]; 37432000 + W ~N1 DIV R1 | T[0].[42:6]|30 +N1 MOD R1|L1; 37433000 + T[7]~ W~ W DIV 30 DIV SPER|LPER 37434000 + +(W DIV 30 MOD SPER|30 + W MOD 30 + RLEN-1) 37435000 + DIV RLEN-1; 37436000 +T1FILL: T[1]~(T[8] DIV SPER)| SPER; 37437000 + T[4]:=(*P(DUP))&0[11:47:1] OR 1; 37437500 + END ELSE% 37439000 + $ SET OMIT = SHAREDISK 37439999 + BEGIN T:=M OR (GETSPACE(30,8,1)+@360000700002); 37440000 + STREAM(T); BEGIN 60(DS~4 LIT "0") END;% 37441000 + $ POP OMIT 37441001 + $ SET OMIT = NOT SHAREDISK 37441099 + T[3]~XCLOCK+P(RTR); 37441500 + T[7] ~ -1; 37442000 + T[1]:=T[8]:=((SIZE+(LPER-1))DIV LPER)| SPER; 37443000 + T[9] ~ NROWS; 37444000 + END;% 37445000 + T[0] ~SPER&LPER[30:36:12]&BLEN[15:33:15]&RLEN[1:34:14]; 37446000 + FILEHEADER ~ NFLAG(T); 37447000 +EXIT: 37447500 +END FILEHEADER;% 37448000 +PROCEDURE PURGEIT(U); VALUE U; INTEGER U;% 37449000 +BEGIN ARRAY LABLE=+1[*];% 37450000 + REAL RCW=+0,EOF=+2;% 37451000 + REAL MSCW=-2; 37451500 + P(0,0); 37453000 + P(WAITIO(@4200000000,@377,U),DEL); 37453100 + LABLE~[M[SPACE(10)]]&10[8:38:10]&5[21:45:3];% 37454000 + BUILDLABEL(LABLE,0,"X",1,0,1,0,PRNTABLE[U].[30:18],0,0,0);% 37455000 + P(WAITIO(LABLE,@37700000,U),DEL);% 37456000 + EOF~@1737000000000000;% 37457000 + P(WAITIO([EOF],@37700000,U),DEL);% 37458000 + FORGETSPACE(LABLE.[33:15]); 37463000 + SETNOTINUSE(U,0); 37464000 + KILL([MSCW]); 37465000 +END PURGEIT; 37466000 + PROCEDURE KRUNCHER(H) ARRAY H[*]; 37500000 + BEGIN DEFINE E=H[7]#,RL=H[1]#,RPB=H[0].[30:12]#, 37501000 + MAXROWS=H[9]#, 37501500 + BCL=H[0].[42:6]#,BRL=H[8]#; 37502000 + ARRAY A[*]; 37504000 + LABEL FORGET,EXIT,AGAIN,DONE; 37505000 + INTEGER NB,NBR; 37506000 + REAL I,J,K,T; 37507000 + A:=[M[SPACE(41)]]&40[8:38:10]; 37508000 + MOVE(41,A.[CF]-1,A); 37509000 + IF E LSS 0 THEN GO TO EXIT; 37510000 + NB:=E DIV RPB; 37511000 + NBR:=RL DIV BCL; 37512000 + IF RL NEQ BRL THEN 37513000 + FOR I:=10 STEP 1 UNTIL 29 DO 37514000 + IF H[I] NEQ 0 THEN 37515000 + $ SET OMIT = SHAREDISK 37515995 + FORGETUSERDISK(H[I]+RL,BRL-RL); 37516000 + $ SET OMIT = NOT SHAREDISK 37516050 + BRL=RL; 37517000 + IF NB LSS NBR THEN 37520000 + BEGIN A[0]:=H[NT2:=10]; 37521000 + NT4:=1; 37521100 + RL:=(NB+1)|BCL; 37521200 + GO TO FORGET; 37521300 + END; 37521400 + T:=(K:=J:=1)+NBR|20; 37522000 + AGAIN: IF(NT1:=NBR DIV J)=0 THEN GO TO DONE; 37523000 + IF (NT2:=NB DIV NT1) GTR 19 THEN GO TO DONE; 37524000 + IF NBR MOD J=0 THEN 37525000 + BEGIN IF (NT3:=NT1|NT2+NT1) LSS T THEN 37526000 + BEGIN K:=J; T:=NT3; NT4:=NT2+1 END; 37527000 + END; 37528000 + J:=J+1; 37529000 + GO TO AGAIN; 37530000 + DONE: IF K=1 THEN GO TO EXIT; 37530100 + NT2:=NB DIV NBR + 10; 37530200 + RL:=RL DIV K; 37531000 + FOR I:=10 STEP 1 UNTIL NT2 DO 37532000 + BEGIN IF (NT1:=H[I]-RL) GTR 0 THEN 37533000 + FOR J:=1 STEP 1 UNTIL K DO 37534000 + A[(I-10)|K+J-1]:=NT1+J|RL; 37535000 + END; 37536000 + FOR K:=NT4 STEP 1 UNTIL 19 DO A[K]:=0; 37538000 + IF MAXROWS LSS (NT5:=(NT4!20)+NT4) THEN MAXROWS:=NT5; 37538500 + FORGET: IF NB+1 NEQ NBR THEN 37539000 + $ SET OMIT = SHAREDISK 37541995 + FORGETUSERDISK(A[NT4-1]+RL,(NT2-9)|BRL-NT4|RL); 37542000 + $ SET OMIT = NOT SHAREDISK 37542005 + MOVE(20,A,[H[10]]); 37543000 + BRK:=RL; 37544000 + EXIT: FORGETSPACE(A); 37545000 + END; 37546000 +PROCEDURE DISKFILEOPEN(ALPHA); VALUE ALPHA; INTEGER ALPHA; 38000000 +BEGIN REAL RCW=+0,MSCW=-2; 38001000 + REAL IOM=IOMASK,IOMASK=+1; 38002000 + INTEGER NBUFS=+2,FNUM=+3,RLEN=+4,TYPE=+5,IO=+6,BLEN=+7,U=+8, 38003000 + KIND=+9,MODE=+10,DIREC=+11,FORMS=+12,COBOL=+13, 38004000 + UNLABELED=+14,OPTIONAL=+15,CNTCTL=+16; 38005000 + REAL T1=+17,T2=+18,MASK=+19,STATE=+20; 38006000 + REAL MFID=+21,FID=+22; INTEGER REEL=+23,CDATE=+24,CYCLE=+25; 38007000 + ARRAY FIB=+26[*],FPB=+27[*];% 38008000 + INTEGER ACCESS=+28,FIB7=+29; 38009000 + LABEL AGN,EXIT; 38009100 + ARRAY HEADER=+30[*];% 38010000 + REAL TOG=+31;% 38010100 + SUBROUTINE DISKSETUP;% 38011000 + BEGIN IF STATE.[42:1] THEN% 38012000 + BEGIN 38013000 + IF MFID=0 AND USERCODE[P1MIX] ! 0 THEN %126-38013010 + BEGIN %126-38013020 + FPB[FNUM ]:=MFID:=FID; %126-38013030 + FPB[FNUM+1]:=FID :=USERCODE[P1MIX]; %126-38013040 + END; %126-38013050 diff --git a/emulator/B5500CentralControl.js b/emulator/B5500CentralControl.js index 55d13c8..e5d760d 100644 --- a/emulator/B5500CentralControl.js +++ b/emulator/B5500CentralControl.js @@ -63,7 +63,7 @@ function B5500CentralControl() { /**************************************/ /* Global constants */ -B5500CentralControl.version = "0.03"; +B5500CentralControl.version = "0.04"; B5500CentralControl.rtcTick = 1000/60; // Real-time clock period, milliseconds diff --git a/emulator/B5500IOUnit.js b/emulator/B5500IOUnit.js index 80b8623..60ab67c 100644 --- a/emulator/B5500IOUnit.js +++ b/emulator/B5500IOUnit.js @@ -62,6 +62,10 @@ function B5500IOUnit(ioUnitID, cc) { // Establish contexts for asynchronously-called methods this.boundForkIO = B5500CentralControl.bindMethod(this.forkIO, this); + this.boundFinishGeneric = this.makeFinish(this.finishGeneric); + this.boundFinishBusy = this.makeFinish(this.finishBusy); + this.boundFinishDiskRead = this.makeFinish(this.finishDiskRead); + this.boundFinishSPORead = this.makeFinish(this.finishSPORead); this.clear(); // Create and initialize the processor state } @@ -570,6 +574,18 @@ B5500IOUnit.prototype.decodeErrorMask = function(errorMask) { if (errorMask & 0x40) {this.D26F = 1} }; +/**************************************/ +B5500IOUnit.prototype.finishBusy = function(errorMask, length) { + /* Handles a generic I/O finish when no word-count update or input data + transfer is needed, but leaves the unit marked as busy in CC. This is needed + by device operations that have a separate completion signal, such as line + printer finish and disk read-check. The completion signal is responsible for + resetting unit busy status */ + + this.decodeErrorMask(errorMask); + this.finish(); +}; + /**************************************/ B5500IOUnit.prototype.finishGeneric = function(errorMask, length) { /* Handles a generic I/O finish when no word-count update or input data @@ -636,15 +652,15 @@ B5500IOUnit.prototype.initiateDiskIO = function(u) { } if (this.D18F) { // mem inhibit => read check operation - u.readCheck(this.makeFinish(this.finishGeneric), segChars, segAddr); + u.readCheck(this.boundFinishBusy, segChars, segAddr); } else if (this.D23F && this.DwordCount == 0) { if (this.D24F) { // read interrogate operation - u.readInterrogate(this.makeFinish(this.finishGeneric), segAddr); + u.readInterrogate(this.boundFinishGeneric, segAddr); } else { // write interrogate operation - u.writeInterrogate(this.makeFinish(this.finishGeneric), segAddr); + u.writeInterrogate(this.boundFinishGeneric, segAddr); } } else if (this.D24F) { // it's a read data operation - u.read(this.makeFinish(this.finishDiskRead), this.buffer, segChars, this.D21F, segAddr); + u.read(this.boundFinishDiskRead, this.buffer, segChars, this.D21F, segAddr); } else { // it's a write data operation memWords = (this.D23F ? this.DwordCount : segWords); if (segWords <= memWords) { // transfer size is limited by number of segs @@ -656,11 +672,47 @@ B5500IOUnit.prototype.initiateDiskIO = function(u) { this.buffer[x++] = c; } } - u.write(this.makeFinish(this.finishGeneric), this.buffer, segChars, this.D21F, segAddr); + u.write(this.boundFinishGeneric, this.buffer, segChars, this.D21F, segAddr); } } }; +/**************************************/ +B5500IOUnit.prototype.initiatePrinterIO = function(u) { + /* Initiates an I/O to a Line Printer unit */ + var addr = this.Daddress; // initial data transfer address + var cc; // carriage control value to driver + var chars; // characters to print + var memWords; // words to fetch from memory + + if (this.D24F) { + this.D30F = 1; // can't read from the printer + this.finish(); + } else { + memWords = this.DwordCount; + if (memWords > 0) { + chars = memWords*8; + } else { + memWords = 17; // assume a 132-character printer + chars = 132; + } + cc = this.LP; + if (cc & 0x0F) { + cc = -(cc & 0x0F); // skip to channel after print + } else if (cc & 0x10) { + cc = 2; // double space after print + } else if (cc & 0x20) { + cc = 1; // single space after print + } else { + cc = 0; // zero space after print + } + this.fetchBuffer(1, memWords); + this.DwordCount = memWords*32; // actual word count in D.[8:5], D.[13:5]=0 + this.Daddress = addr-1; // printer accesses memory backwards, so final address is initial-1 + u.write(this.boundFinishBusy, this.buffer, chars, 0, cc); + } +}; + /**************************************/ B5500IOUnit.prototype.forkIO = function forkIO() { /* Asynchronously initiates an I/O operation on this I/O Unit for a peripheral device */ @@ -673,8 +725,8 @@ B5500IOUnit.prototype.forkIO = function forkIO() { this.forkHandle = null; // clear the setTimeout() handle x = this.D; // explode the D-register into its fields - this.Dunit = this.cc.fieldIsolate(x, 3, 5); - this.DwordCount = this.cc.fieldIsolate(x, 8, 10); + this.Dunit = (x%0x200000000000 - x%0x10000000000)/0x10000000000; // [3:5] + this.DwordCount = (x%0x10000000000 - x%0x40000000)/0x40000000; // [8:10] x = x % 0x40000000; // isolate low-order 30 bits this.D18F = (x >>> 29) & 1; // memory inhibit this.D21F = (x >>> 26) & 1; // mode @@ -704,7 +756,7 @@ B5500IOUnit.prototype.forkIO = function forkIO() { // printer designates case 22: case 26: - this.D30F = 1; this.finish(); // >>> temp until implemented <<< + this.initiatePrinterIO(u); break; // datacom designate @@ -725,10 +777,10 @@ B5500IOUnit.prototype.forkIO = function forkIO() { // SPO designate case 30: if (this.D24F) { - u.read(this.makeFinish(this.finishSPORead), this.buffer, 0x7FFF, 0, 0); + u.read(this.boundFinishSPORead, this.buffer, 0x7FFF, 0, 0); } else { chars = this.fetchBufferWithGM(1, 0x7FFF); - u.write(this.makeFinish(this.finishGeneric), this.buffer, chars, 0, 0); + u.write(this.boundFinishGeneric, this.buffer, chars, 0, 0); } break; diff --git a/webUI/tools/B5500ColdLoader.html b/webUI/B5500ColdLoader.html similarity index 96% rename from webUI/tools/B5500ColdLoader.html rename to webUI/B5500ColdLoader.html index 25c961d..dca71d9 100644 --- a/webUI/tools/B5500ColdLoader.html +++ b/webUI/B5500ColdLoader.html @@ -1654,14 +1654,17 @@ window.onload = function() { /* Initializes the directory structure on EU0. "config" is the database CONFIG structure */ var b55Date; + var b55Time; var stamp = new Date(); var x; // Compute a 1980s date based on today's date, formatted as BIC - x = stamp.getTime() - new Date(stamp.getFullYear, stamp.getMonth(), 1); + x = stamp.getTime() - new Date(stamp.getFullYear(), 0, 1).getTime(); x = Math.floor(x/86400000) + 1; // day-of-year number b55Date = (((8*64 + stamp.getYear()%10)*64 + Math.floor(x/100))*64 + Math.floor(x/10)%10)*64 + x%10; + b55Time = Math.floor(((stamp.getHours()*60 + stamp.getMinutes())*60 + + stamp.getSeconds())*60 + stamp.getMilliseconds()*60/1000); // Initialize the directory labels segment stringToANSI("0000001?", fileLabels, 14*16); // @114, last-entry marker @@ -1690,8 +1693,8 @@ window.onload = function() { pow2[47-44] + // 44: print EOJ pow2[47-43] + // 43: type file open pow2[47-42] + // 42: call TERMINATE procedure - pow2[47-41] + // 41: initialize date @ H/L - pow2[47-40] + // 40: initialize time @ H/L + // 41: initialize date @ H/L + // 40: initialize time @ H/L // 39: use only one breakout tape // 38: automatically print pbt pow2[47-37] + // 37: clear write ready status @ terminal @@ -1733,7 +1736,7 @@ window.onload = function() { // 1: UNUSED 0; // 0: (flag bit) - info[ 1] = b55Date; // date as BIC + info[ 1] = b55Date; // YYDDD date as BIC info[ 2] = config.eus; // number of EUs info[ 3] = 0; // not used info[ 4] = directoryEnd; // DIRECT deck option @@ -1741,7 +1744,7 @@ window.onload = function() { info[ 6] = 0; // first control deck queued info[ 7] = 0; // last control deck queued info[ 8] = 0; // next number available for printer backup disk - info[ 9] = 100; // multiprocessing core factor + info[ 9] = 100*0x40000000; // multiprocessing core factor * 100 info[10] = 0; // SPO stations (through info[15]) info[11] = 0; info[12] = 0; @@ -1750,7 +1753,7 @@ window.onload = function() { info[15] = 0; info[16] = 15; // Q value for datacom input info[17] = 0; // remote SPO mask - info[18] = 0; // time of day (XCLOCK) + info[18] = b55Time; // time of day (XCLOCK) info[19] = 0; // FENCE address (TSSMCP only) info[20] = 0; // log pointer info[21] = 0; // status of schedule lines (TSSMCP only) diff --git a/webUI/B5500Console.css b/webUI/B5500Console.css index 191f794..3f0605e 100644 --- a/webUI/B5500Console.css +++ b/webUI/B5500Console.css @@ -39,7 +39,8 @@ DIV#B5500Logo { padding-right: 4px; position: absolute; top: 72px; - right: 32px} + right: 32px; + z-index: 15} IMG#BurroughsLogoImage { width: 150px; @@ -138,14 +139,27 @@ BUTTON#PowerOnBtn { BUTTON#PowerOffBtn { top: 31px; left: 822px} + +TABLE#CentralControl { + position: absolute; + bottom: 0; + color: #666; + font-family: Arial Rounded, Arial, Helvetica, sans-serif; + font-size: 10px; + font-weight: bold} + +.busy { + color: white} +.idle { + color: #666} + .center { text-align: center} .data { font-family: Courier New, Courier, monospace; text-align: left} - .number { font-family: Courier New, Courier, monospace; text-align: right} diff --git a/webUI/B5500Console.html b/webUI/B5500Console.html index 3356b5b..f17adc6 100644 --- a/webUI/B5500Console.html +++ b/webUI/B5500Console.html @@ -24,6 +24,7 @@ window.onload = function() { var bNormal; var boundBlinkenlicht; var cc = new B5500CentralControl(); + var lastBusyMask = 0; var timer; var timerInterval = 50; // milliseconds @@ -62,10 +63,12 @@ window.onload = function() { cc.halt(); $$("HaltBtn").disabled = true; $$("LoadBtn").disabled = false; + /***** if (timer) { clearTimeout(timer); timer = null; } + *****/ } function LoadBtn_Click(ev) { @@ -75,6 +78,38 @@ window.onload = function() { boundBlinkenlicht(); } + function displayCentralControl() { + /* Displays the I/O and interrupt status in Central Control */ + var cells; + var s; + var busyMask = cc.unitBusyMask; + var busyChange = lastBusyMask ^ busyMask; + var x; + + lastBusyMask = busyMask; + + $$("AD1F").className = (cc.AD1F ? "busy" : ""); + $$("AD2F").className = (cc.AD2F ? "busy" : ""); + $$("AD3F").className = (cc.AD3F ? "busy" : ""); + $$("AD4F").className = (cc.AD4F ? "busy" : ""); + + for (x=3; x<=16; x++) { + s = "CCI" + (x+100).toString().substring(1) + "F"; + $$(s).className = (cc[s] ? "busy" : ""); + } + + cells = $$("CCPeripheralRow").cells; + x = 47; + while (busyChange) { + if (busyChange & 0x01) { + cells[x-17].className = (busyMask & 0x01 ? "busy" : ""); + } + busyMask >>>= 1; + busyChange >>>= 1; + x--; + } + } + function dasBlinkenlicht() { var pa = cc.PA; var pb = cc.PB; @@ -107,22 +142,45 @@ window.onload = function() { } } } - + displayCentralControl(); timer = setTimeout(boundBlinkenlicht, timerInterval); } + function checkBrowser() { + /* Checks whether this browser can support the necessary stuff */ + var missing = ""; + + if (!window.indexedDB) {missing += ", IndexedDB"} + if (!window.ArrayBuffer) {missing += ", ArrayBuffer"} + if (!window.DataView) {missing += ", DataView"} + if (!window.Blob) {missing += ", Blob"} + if (!window.File) {missing += ", File"} + if (!window.FileReader) {missing += ", FileReader"} + if (!window.FileList) {missing += ", FileList"} + + if (missing.length == 0) { + return false; + } else { + alert("No can do... your browser does not support the following features:\n" + + missing.substring(2)); + return true; + } + } + /***** window.onload() outer block *****/ - $$("PowerOnBtn").addEventListener("click", PowerOnBtn_Click); - $$("PowerOffBtn").addEventListener("click", PowerOffBtn_Click); - $$("HaltBtn").addEventListener("click", HaltBtn_Click); - $$("LoadBtn").addEventListener("click", LoadBtn_Click); + if (!checkBrowser()) { + $$("PowerOnBtn").addEventListener("click", PowerOnBtn_Click); + $$("PowerOffBtn").addEventListener("click", PowerOffBtn_Click); + $$("HaltBtn").addEventListener("click", HaltBtn_Click); + $$("LoadBtn").addEventListener("click", LoadBtn_Click); - aControl = $$("AControlBtn"); - aNormal = $$("ANormalBtn"); - bControl = $$("BControlBtn"); - bNormal = $$("BNormalBtn"); - boundBlinkenlicht = bindMethod(dasBlinkenlicht, this); + aControl = $$("AControlBtn"); + aNormal = $$("ANormalBtn"); + bControl = $$("BControlBtn"); + bNormal = $$("BNormalBtn"); + boundBlinkenlicht = bindMethod(dasBlinkenlicht, this); + } }; @@ -149,6 +207,65 @@ window.onload = function() { + + + + + + + + +
IOU1 + IOU2 + IOU3 + IOU4 + TIMR + IOBZ + KBD + PR1F + PR2F + IO1F + IO2F + IO3F + IO4F + P2BZ + INQ + SPEC + DK1F + DK2F + +
DCA + PPB + PRB + PRA + PPA + SPO + CRB + CRA + CPA + LPB + LPA + DKB + DKA + DRB + DRA + MTT + MTS + MTR + MTP + MTN + MTM + MTL + MTK + MTJ + MTH + MTF + MTE + MTD + MTC + MTB + MTA +
diff --git a/webUI/B5500DiskUnit.js b/webUI/B5500DiskUnit.js index 850b513..7794e05 100644 --- a/webUI/B5500DiskUnit.js +++ b/webUI/B5500DiskUnit.js @@ -128,7 +128,7 @@ B5500DiskUnit.prototype.copySegment = function(seg, buffer, offset) { } } else { for (x=offset+239; x>=offset; x--) { - buffer[x] = 0; + buffer[x] = 0x23; // ASCII "#", translates as alpha to BIC "0" = @00 } } }; @@ -363,9 +363,11 @@ B5500DiskUnit.prototype.readCheck = function(finish, length, control) { euSize = this.config[euName]; if (!euSize) { // EU does not exist finish(this.errorMask | 0x20, 0); // set D27F for EU not ready + this.signal(); // DO NOT clear the error mask } else if (segAddr < 0) { finish(this.errorMask | 0x20, 0); // set D27F for invalid starting seg address + this.signal(); // DO NOT clear the error mask } else { if (endAddr >= euSize) { // if read is past end of disk @@ -379,10 +381,12 @@ B5500DiskUnit.prototype.readCheck = function(finish, length, control) { if (segs < 1) { // No length specified, so just finish the I/O finish(this.errorMask, 0); + this.signal(); // DO NOT clear the error mask -- will return it on the next interrogate } else { // A multi-segment read range = window.IDBKeyRange.bound(segAddr, endAddr); - txn = this.disk.transacation(euName); + txn = this.disk.transaction(euName); + finish(that.errorMask, length); // post I/O complete now -- DFCU will signal when check finished req = txn.objectStore(euName).openCursor(range); req.onsuccess = function(ev) { @@ -392,7 +396,7 @@ B5500DiskUnit.prototype.readCheck = function(finish, length, control) { cursor.continue(); } else { // at end of range setTimeout(function() { - finish(that.errorMask, length); + that.signal(); // DO NOT clear the error mask }, finishTime - new Date().getTime()); } diff --git a/webUI/B5500SPOUnit.js b/webUI/B5500SPOUnit.js index ee8cfb9..a35e425 100644 --- a/webUI/B5500SPOUnit.js +++ b/webUI/B5500SPOUnit.js @@ -41,7 +41,7 @@ function B5500SPOUnit(mnemonic, unitIndex, designate, statusChange, signal) { this.window.close(); // destroy the previously-existing window this.window = null; } - this.window = window.open("./B5500SPOUnit.html", "SPOWin", "scrollbars,resizable,width=600,height=500"); + this.window = window.open("/B5500/webUI/B5500SPOUnit.html", "SPOWin", "scrollbars,resizable,width=600,height=500"); this.window.onload = function() { that.spoOnload(); }; @@ -459,12 +459,12 @@ B5500SPOUnit.prototype.spoOnload = function() { }; this.window.onkeypress = function(ev) { - if (ev.keyCode == 191) ev.preventDefault(); + if (ev.keyCode == 191) {ev.preventDefault()}; that.keyPress(ev); }; this.window.onkeydown = function(ev) { - if (ev.keyCode == 191) ev.preventDefault(); + if (ev.keyCode == 191) {ev.preventDefault()}; that.keyDown(ev); }; diff --git a/webUI/tools/B5500SyllableDebugger.css b/webUI/B5500SyllableDebugger.css similarity index 100% rename from webUI/tools/B5500SyllableDebugger.css rename to webUI/B5500SyllableDebugger.css diff --git a/webUI/tools/B5500SyllableDebugger.html b/webUI/B5500SyllableDebugger.html similarity index 96% rename from webUI/tools/B5500SyllableDebugger.html rename to webUI/B5500SyllableDebugger.html index 38a661c..105be4a 100644 --- a/webUI/tools/B5500SyllableDebugger.html +++ b/webUI/B5500SyllableDebugger.html @@ -741,9 +741,7 @@ function runIt(ev) { runBtn.value = "Run"; running = false; cc.inhCCI03F = true; - if (runSilently) { - displaySystemState(); - } + displaySystemState(); } } @@ -1080,7 +1078,7 @@ window.onload = function() {