diff --git a/Mark-XVI/SYMBOL/DCMCP.esp_m b/Mark-XVI/SYMBOL/DCMCP.esp_m index 6a11437..26bd85a 100644 --- a/Mark-XVI/SYMBOL/DCMCP.esp_m +++ b/Mark-XVI/SYMBOL/DCMCP.esp_m @@ -23927,3 +23927,191 @@ ONE: BEGIN STREAM(I: F~"ENDPACK", D~M[ALPHA-2]);% 38711000 I~TALLY;% 38716000 END;% 38717000 IF NOT P THEN% 38718000 + BEGIN BLASTQ(U);% 38719000 + DO UNTIL WAITIO(M[ALPHA-2],@40,U)!0;% 38720000 + GO TO ONE;% 38721000 + END;% 38722000 + END;% 38723000 + BLASTQ(U); 38724000 +CC:: 38725000 + M[M[ALPHA-2] INX NOT 3].[9:6]:=0; 38726000 + LABELTABLE[U]~-@14; 38730000 + RDCTABLE[U]~0; 38731000 + IF 32{U AND U{63 THEN PSEUDOCOPY~PSEUDOCOPY+1; 38732000 + INDEPENDENTRUNNER(P(..CONTROLCARD),(M[ALPHA-2].[CF])& 38732100 + $ SET OMIT = NOT(DATACOM AND RJE ) 38732199 + U[2:42:6]&JAR[P1MIX,6][1:1:1], 38732300 + 192); 38732400 + GO CLOSEOUT;% 38733000 +CP: EMPTY;% 38735000 + IF NOT UNLABELED THEN P(WAITIO(M[ALPHA-2],0,U),DEL);% 38736000 + SETNOTINUSE(U,FORMS OR PUNCHLCK); 38737000 + GO CLOSEOUT;% 38738000 +LP: EMPTY;% 38740000 + IF SEPARATE THEN P(WAITIO(@4000100000,0,U),DEL) %150-38741000 + ELSE P(WAITIO(@4002000000,0,U),DEL); %150-38741100 + IF NOT UNLABELED THEN P(WAITIO(M[ALPHA-2],0,U),DEL);% 38742000 + IF NOT SEPARATE THEN P(WAITIO(@4000100000,0,U),DEL); %150-38742100 + SETNOTINUSE(U,FORMS); 38743000 + GO CLOSEOUT;% 38744000 +SP: IF STATE.[43:1] THEN COOLOFF ELSE EMPTY;% 38746000 + GO CLOSEOUT;% 38747000 +MT: IF NOT STATE.[41:1] THEN% 38749000 + BEGIN IF STATE.[43:1] THEN% 38750000 + BEGIN COOLOFF; BLASTQ(U);% 38751000 + IF NOT REW THEN 38752000 + BEGIN T~@1000000140000005&STATE[22:44:1];% 38753000 + IF I}NBUFS THEN DO UNTIL WAITIO(T,@377,U).[42:1]; 38754000 + IF NOT UNLABELED THEN 38754100 + P(WAITIO(T,@377,U),DEL); 38755000 + END;% 38756000 + END ELSE% 38757000 + BEGIN EMPTY;% 38758000 + EOFIT: T~@1737000000000000;% 38759000 + P(WAITIO([T],@40,U),DEL);% 38760000 + IF NOT UNLABELED THEN% 38761000 + BEGIN;STREAM(BC~FIB[6],RC~FIB[7],D~M[ALPHA-2]);% 38762000 + BEGIN SI~LOC BC; DI~DI+40;% 38763000 + DS~5 dec; DS~7 DEC;% 38764000 + END;% 38765000 + P(WAITIO(M[ALPHA-2],@40,U),DEL);% 38766000 + P(WAITIO([T],@40,U),DEL);% 38767000 + T~@1000000340000005;% 38768000 + P(WAITIO(T,@40,U) ,DEL);% 38769000 + END;% 38770000 + END;% 38771000 + END ELSE% 38772000 + IF FIB[18].[1:1]THEN BEGIN FIB[18].[1:1]~FIB[16]~0; 38773000 + FIB[10].[3:15]:=0; GO EOFIT END; 38773100 + IF REW THEN% 38774000 + BEGIN P(WAITIO(@4200000000,@377,U),DEL);% 38775000 + STATE.[40:1]~0;% 38776000 + END ELSE STATE.[40:1]~NOT STATE.[44:1];% 38777000 +PX: IF REL THEN% 38778000 + BEGIN SETNOTINUSE(U,0); 38779000 + STATE.[41:2]~1;% 38780000 + END ELSE STATE.[41:2]~2;% 38781000 + IF LOCK THEN% 38782000 + BEGIN SETNOTINUSE(U,1); 38783000 + STATE.[41:2]~1;% 38784000 + END;% 38785000 + IF U LSS 16 THEN 38786000 + IF PURGE THEN% 38787000 + BEGIN IF PRNTABLE[U]<0 THEN% 38788000 + BEGIN RDCTABLE[U].[8:6]~0; %538-38788500 + INDEPENDENTRUNNER(P(.PURGEID),U,64) 38789000 + END %538-38789050 + ELSE SETNOTINUSE(U,0); 38789100 + STATE.[41:2]~2;% 38790000 + END;% 38791000 + GO TO CLEANUP;% 38792000 +PP:: IF NOT STATE.[41:1] THEN% 38794000 + BEGIN EMPTY; P(WAITIO(@2004500000000,@40,U),DEL) END;% 38795000 + GO TO PX; 38796000 +PR:: IF NOT STATE.[41:1] THEN BEGIN COOLOFF; BLASTQ(U) END;% 38798000 + IF REW THEN P(WAITIO(@10340000000,@377,U),DEL);% 38799000 + GO TO PX;% 38800000 +CD:: 38802000 + IF M[ALPHA].[27:1] THEN MOVE(10,FIB[16].[33:15],M[ALPHA-2]) ELSE 38803000 +EOD: DO UNTIL READMEFROMDISK(CIDROW[U-32],M[ALPHA-2]); 38804000 + $ SET OMIT = PACKETS 38804999 + IF JAR[P1MIX,0]<0 AND PRT[P1MIX,21]!0 OR JAR[P1MIX,1]<0 THEN 38806000 + BEGIN 38806050 + $ SET OMIT = NOT(PACKETS) 38806099 + PACKETERR[U-32]:=TRUE; 38806200 + IF CIDTABLE[U-32,3] LEQ CIDTABLE[U-32,7] THEN 38806300 + $ POP OMIT 38806301 + BEGIN STREAM(E~"ENDWAIT": Q~@14, D~M[ALPHA-2]); 38807000 + BEGIN SI~LOC Q; SI~SI+7; IF SC!DC THEN DI~DI+1; Q~DI; SI~Q; 38808000 + L: IF SC=" " THEN BEGIN SI~SI+1; GO TO L END; 38809000 + DI~LOC E; DI~DI+1; IF 3 SC!DC THEN TALLY~1; 38810000 + $ SET OMIT = NOT(PACKETS) 38810099 + IF TOGGLE THEN 38810100 + BEGIN SI~SI-3; IF 4 SC=DC THEN TALLY~0; END; 38810200 + $ POP OMIT 38810201 + E~TALLY; 38810500 + END; 38811000 + IF P THEN GO TO EOD; 38812000 + END; 38813000 + END; 38813100 + KIND~0; 38814000 + GO TO CC; 38815000 +CLOSEOUT:: STATE.[39:4]~1; TIME~1; 38817000 +CLEANUP:: CLOSED: DK: BKUP: DC: 38818000 + P(P&RCW[CTC],0,RDS,0,XCH,P&P[CTF],STF); 38819000 +END OTHER CLOSE; 38820000 +PROCEDURE FILEOPEN(XTRA,ALPHA); 39000000 + VALUE ALPHA,XTRA; INTEGER ALPHA,XTRA; 39000100 +BEGIN REAL RCW=+0;% 39001000 + REAL IOM=IOMASK, IOMASK; 39001100 + REAL XTRAR=-4,XTRAC=-6; 39001200 + INTEGER NBUFS,FNUM,RLEN,TYPE,IO,BLEN,U,KIND, 39002000 + MODE,DIREC,FORMS,COBOL,UNLABELED,OPTIONAL,CNTCTL; 39003000 + REAL T1,T2,MASK,STATE; 39004000 + REAL MFID,FID; INTEGER REEL,CDATE,CYCLE; %KEEP THESE TOGETHER 39004100 + ARRAY FIB[*],FPB[*];% 39005000 + INTEGER ACCESS,FIB7; 39006000 + LABEL DCIN,PBS; 39006100 + LABEL DC19; 39006800 + LABEL DKRN,SPN,DKSN,DKUN,DKPN,DCN; 39007000 + SWITCH INSW~DKRN,SPN,DKSN,DKUN,DCIN; 39008000 + LABEL LOOK,EXIT,LOOKOUT,LPS,FINALIN,FINALOUT,SPDC;% 39009000 + REAL SUBROUTINE DSED; DSED:=TERMSET(P1MIX); 39009050 + REAL SUBROUTINE CNTLBITS;% 39026000 + CNTLBITS~IOMASK&MODE[21:47:1]&DIREC[22:47:1]&CNTCTL[23:47:1]39027000 + &IO[24:47:1]&(KIND=7 OR KIND>9 AND KIND{12)[20:47:1] 39028000 + &(IF KIND=1OR KIND=7OR KIND=12THEN@20ELSE 0)[27:42:6];39029000 + SUBROUTINE MAKEIODS;% 39031000 + BEGIN FIB[16]~T1~((BLEN-1)|DIREC+M[ALPHA])&CNTLBITS[18:18:15]% 39032000 + &(IF BLEN{1023 THEN BLEN ELSE 1023)[838:10]% 39033000 + &TINU[IF (KIND=7 OR KIND=12) THEN IF TYPE<20 39034000 + THEN 20 ELSE 22 ELSE 39034050 + IF KIND=11 THEN 23 ELSE U][3:3:5] OR M; 39034100 + FIB[19]~(IF STATE.[46:2]=0 THEN (DIREC INX T1)% 39035000 + &(2|DIREC+(BLEN>1023)+1)[3:43:5] ELSE% 39036000 + IF STATE.[46:2]=1 THEN ((NOT RLEN INX 2)|DIREC INX T1)39037000 + &RLEN[8:38:10]&(3|DIREC+2)[3:43:5] ELSE% 39038000 + (1-DIREC INX T1)&RLEN[8:38:10]&(DIREC+6)[3:43:5])% 39039000 + &IO[25:47:1];% 39040000 + IF NOT (IO OR COBOL)THEN% 39041000 + T1~FIB[19]&T1[3:3:5]&0[25:25:1];% 39042000 + FIB[10],[3:15]~M[ALPHA]-2; %HEAD OF BUFFER RING 39042100 + T2~T1.[33:15]-M[ALPHA];% 39043000 + FOR MASK~0 STEP 1 UNTIL NBUFS-1 DO% 39044000 + BEGIN %P 39045000 + M[ALPHA+MASK]~FLAG((P(DUP,LOD)+T2)&P(T1,XCH)[33:33:15]);% 39046000 + END;% 39047000 + END MAKEIODS;% 39048000 + LABEL DKR0,SPO,DKS0,DKU0,DKP0,DC0; 39049000 + SWITCH OUTSW~DKR0,SPO,DKS0,DKU0,DC0;% 39050000 + LABEL FIXFIB,FIND,SPACER;% 39054000 + LABEL PREFINAL,DK1;% 39055000 + ARRAY HEADER[*];% 39056000 + REAL TOG; 39056100 + LABEL AGN; 39056500 + FIB~M[ALPHA-3]; FPB~PRT[P1MIX,3];% 39083000 + IOMASK:=IOM; 39083100 + NBUFS~FIB[13].[1:9]; FNUM~FIB[4].[13:11]; BLEN~FIB[18].[3:15];% 39084000 + TYPE~FPB[FNUM+3].[43;5];% 39085000 + STREAM(S ~ [FPB[FNUM+2]], D ~ [REEL]);% 39086000 + BEGIN SI:=S;DS:=3OCT;DS:=5OCT;DS:=OCT END;% 39087000 + P(CDATE, RSB, .CDATE,~); 39087100 + IF FPB[FNUM+4]>0 THEN REEL ~ CDATE ~ CYCLE ~ 0; 39087500 + MODE~FIB[13].[24:1]; IO~FIB[13].[27:1]; RLEN~FIB[18].[33:15];% 39088000 + DIREC~FIB[13].[25:1]; FORMS~FPB[FNUM+3].[42:1];% 39089000 + STATE~FIB[5]; UNLABELED~FIB[4].[2:1]; 39090000 + MFID~FPB[FNUM]; FOD~FPB[FNUM+1]; OPTIONAL~FIB[4].[5:1];% 39091000 + COBOL~(FIB[13] AND 1)&([FIB].[8:10]=22)[1:47:1]; % COBOL 60 & 68 39091100 + KIND~FIB[4].[8:4]; IF FIB[13].[28:10]!0 THEN REEL~FIB[13].[28:10]; 39092000 + IF COBOL>0 OR FIB[4].[7:1] THEN % COBOL 60 OR SORT 39092010 + M[FIB INX NOT 1].[3:6]~2 39092020 + ELSE M[ALPHA-7].[3:6]~2; 39092030 + $ SET OMIT = NOT(DATACOM AND RJE ) 39092039 + IF TYPE=19 THEN GO TO DC19 ELSE 39092045 + IF TYPE=26 THEN GO TO DKPN ELSE 39092050 + IF TYPE>26 THEN GO TO DCN; 39092055 + IF (TYPE=0 AND NOT IO) OR TYPE GTR 20 THEN 39092060 + BEGIN IF USEPBD 39092070 + $ SET OMIT = NOT(DATACOM AND RJE ) 39092074 + THEN TYPE:=22; GO TO LOOKOUT; 39092080 + END; 39092090 diff --git a/Mark-XVI/SYMBOL/TSSINT.esp_m b/Mark-XVI/SYMBOL/TSSINT.esp_m new file mode 100644 index 0000000..14914d9 --- /dev/null +++ b/Mark-XVI/SYMBOL/TSSINT.esp_m @@ -0,0 +1,690 @@ +% I N T R I N S I C S M A R K XVI.0.00 10/01/74 + COMMENT: * TITLE: B5500/B5700 MARK XVI SYSTEM RELEASE * + * FILE ID: SYMBOL/INTRINS TAPE ID: SYMBOL1/FILE000 * + * THIS MATERIAL IS PROPRIETARY TO BURROUGHS CORPORATION * + * AND IS NOT TO BE REPRODUCED, USED, OR DISCLOSED * + * EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE OR UPON * + * WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF * + * BURROUGHS CORPORATION, DETROIT, MICHIGAN 48232 * + * * + * COPYRIGHT (C) 1971, 1972, 1974 * + * BURROUGHS CORPORATION * + * AA320206 AA393180 AA332366 *; + BEGIN + DEFINE ETRLNG = 5#, + INTDESC(INTDESC1) = FLAG(INTDESC1 & 85[1:41:7]) #, + INTCALL(INTCALL1,INTCALL2) = P(INTCALL2 & 85[1:41:7], + INTCALL1,COC) #, + CALLINT(CALLINT1) = P(CALLINT1 & 85[1:41:7],XCH,COC) #, + COBOLDCI= @167 #, + FORTERRI= @134 #, + EXPI = @20 #, + LNI = @17 #, + DEXPI = @77 #, + DLOGI = @101 #, + CABSI = @53 #, + SINI = @14 #, + SQRTI = @13 #, + ATAN2I = @114 #, + DMODI = @65 #, + DSINI = @105 #, + DSQRTI = @123 #, + XTOII = @6 #, + CXTOII = @56 #, + COSI = @15 #, + TANI = @111 #, + ARCTANI = @16 #, + DATANI = @113 #, + ARSINI = @116 #, + GAMMAI = @126 #, + EDITIT(EDITIT1,EDITIT2,EDITIT3,EDITIT4,EDITIT5) = P(MKS, + EDITIT1,EDITIT2,EDITIT3,(-1),(EDITIT4),(EDITIT5), + @153&85[1:41:7],XCH,COC) #, + % EDITIT(BUFFADDRESS,FIELDWIDTH(W),TYPE,LOWPART,HIGHPART) + % WILL EDIT THE VALUE (LOWPART,HIGHPART) INTO A FIELD + % STARTING AT BUFFADDRESS. EDITIT RETURNS THE ENDING + % ADDRESS. THE WIDTH OF THE EDITED FIELD IS CONSTRAINED + % TO W CHARACTERS (EDITED VALUE IS RIGHT JUSTIFIED WITH + % LEADING BLANKS IF W IS LARGER THAN NEEDED) -- BUT IF + % W=0, THEN EDITIT WILL ADJUST THE FIELD WIDTH TO + % ACCOMODATE FULL NUMERICAL SIGNIFICANCE. TYPE=2 => EDITIT + % WILL CHOOSE BETWEEN REAL, INTEGER, AND DOUBLEPRECISION + % EDITING (DOUBLEPRECISION IS USED IF LOWPART!0). + % TYPE=1 => USE ONLY INTEGER, TYPE=3 => USE ONLY REAL, + % TYPE=4 => USE ONLY LOGICAL, TYPE=5 => USE ONLY DOUBLE- + % PRECISION. + CTC = 33:33:15#, + CTF = 18:33:15#, + FTC = 33:18:15#, + FTF = 18:18:15#, + CF = 33:15#, + FF = 18:15#; + REAL JUNK = 5; + NAME MEM=2, M=2, MEMORY=2 ; + REAL BLKCNTRL = 5; + DEFINE DUMPNOW(DUMPNOW1)=P(DUMPNOW1,0,48,COM,DEL,DEL)#, + TRACENOW(TRACENOW1,TRACENOW2)= + P(TRACENOW1,1,TRACENOW2 ,+ ,48,COM,DEL,DEL)#; + PROCEDURE OUTPUTINT(TEN, FILX, CHSKP, LNSKP, FI, FRMT, LISX);% %WF + VALUE CHSKP, LNSKP, FI, LISX;% %WF + NAME FILX;% %WF + ARRAY TEN[*], FRMT[*];% %WF + REAL LISX;% %WF + INTEGER CHSKP, LNSKP, FI;% %WF + FORWARD;% CODE=00200000, INTRINSIC NUMBER=@ 1 %WF + PROCEDURE INTRINSIC(DUPE, D, NUMDIM, SIZE, TYPE);% %WF + VALUE DUPE, D, NUMDIM, SIZE, TYPE;% %WF + NAME D;% %WF + ARRAY DUPE[*];% %WF + INTEGER NUMDIM, SIZE, TYPE;% %WF + FORWARD;% CODE=00400000, INTRINSIC NUMBER=@ 2 %WF + PROCEDURE INPUTINT(TEN, FILX, DKADR, ACT,% %WF + FI, FRMT, LISX, EOFL, PARL);% %WF + VALUE ACT, FI;% %WF + NAME FILX, LISX;% %WF + ARRAY TEN[*], FRMT[*];% %WF + REAL EOFL, PARL;% %WF + INTEGER DKADR, ACT, FI;% %WF + FORWARD;% CODE=00600000, INTRINSIC NUMBER=@ 3 %WF + PROCEDURE DISKSORT(T1, T2, RELA, ENDQ, BINGO, IPFIDX,% %WF + OUTPRO, INPRO, OUTF, INF, OPTOG, IPTOG, DKO, DKI,% %WF + TP1, TP2, TP3, TP4, TP5, NT, HIVALU, EQUALS,% %WF + R, ALFA, CORESIZE, DISKSIZE);% %WF + VALUE OPTOG, IPTOG, NT, HIVALU, EQUALS, R, ALFA,% %WF + CORESIZE, DISKSIZE;% %WF + NAME TP1, TP2, TP3, TP4, TP5;% %WF + REAL T1, T2, RELA, ENDQ, BINGO, IPFIDX, OUTPRO, INPRO,% %WF + OUTF, INF, DKO, DKI, NT, HIVALU, EQUALS, CORESIZE;% %WF + BOOLEAN OPTOG, IPTOG, ALFA;% %WF + INTEGER R, DISKSIZE;% %WF + FORWARD;% CODE=00700000, INTRINSIC NUMBER=@ 4 %WF + REAL PROCEDURE DUMPINT(SN, CV, BV, TIPE,% %WF + TENS, ALFA, CHAR, FIEL, FORMT);% %WF + VALUE SN, CV, BV, TIPE, TENS, ALFA, CHAR, FORMT;% %WF + NAME FIEL;% %WF + REAL SN, CV, BV, TIPE, TENS, ALFA, CHAR, FORMT;% %WF + FORWARD;% CODE=42000000, INTRINSIC NUMBER=@ 5 %WF + PROCEDURE XTOTHEIINT(BASE, EXPON, M, LOG, EXP);% %WF + VALUE BASE, EXPON, M, LOG, EXP;% %WF + REAL BASE, EXPON, M, LOG, EXP;% + FORWARD;% CODE=42254000, INTRINSIC NUMBER=@ 6 + REAL PROCEDURE ABSINT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@ 7 + REAL PROCEDURE SIGNINT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@10 + INTEGER PROCEDURE ENTIERINT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@11 + REAL PROCEDURE TIMEINT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@12 + PROCEDURE SQRTINT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@13 + PROCEDURE SININT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@14 + PROCEDURE COSINT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@15 + REAL PROCEDURE ARCTANINT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@16 + PROCEDURE LNINT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@17 + REAL PROCEDURE EXPINT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@20 + REAL PROCEDURE GOTOSOLVERINT(L, X, F, B);% + VALUE L, X, F, B;% + ARRAY F[*];% + REAL L, X, B;% + FORWARD;% CODE= INTRINSIC NUMBER=@21 + PROCEDURE ALGOLWRITE(TEN, FILX, CHSKP, LNSKP, FI, AEXP,% + ARRY, LINESKIP, CHANSKIP, SUPRS, NUMWDS, TANK);% + VALUE CHSKP, LNSKP, FI, AEXP, LINESKIP,% + CHANSKIP, SUPRS, NUMWDS, TANK;% + NAME FILX, TANK;% + ARRAY TEN[*], ARRY[*];% + INTEGER CHSKP, LNSKP, FI, AEXP, LINESKIP,% + CHANSKIP, SUPRS, NUMWDS;% + FORWARD;% CODE=00100100, INTRINSIC NUMBER=@22 + PROCEDURE ALGOLREAD(TEN, FILX, DKADD, ACT, FI, AEXP,% + ARRY, EOFL, PARL, DKADR, CODE, TANK);% + VALUE ACT, FI, AEXP, DKADR, CODE, TANK;% + NAME FILX, TANK;% + ARRAY TEN[*], ARRY[*];% + REAL DKADD, EOFL, PARL, DKADR, CODE;% + INTEGER ACT, FI, AEXP;% + FORWARD;% CODE=00500000, INTRINSIC NUMBER=@23 + PROCEDURE ALGOLSELECT(ACT1, ACT2, TANK, I);% + VALUE ACT1, ACT2, TANK, I;% + NAME TANK;% + INTEGER ACT1, ACT2, I;% + FORWARD;% CODE= INTRINSIC NUMBER=@24 + PROCEDURE COBOLFCR;% + FORWARD;% CODE=43000000, INTRINSIC NUMBER=@25 +PROCEDURE COBOLID;% % GO TO 02700000 + FORWARD;% CODE=43230000, INTRINSIC NUMBER=@26 + PROCEDURE POLYMERGE(T1, T2, T3, ENDQ, BINGO, IPFIDX,% + OUTPRO, INPRO, OUTF, INF, OPTOG, IPTOG, DKO, DKI,% + TP1, TP2, TP3, TP4, TP5, NT, HIVALU, EQUALS,% + R, ALFA, CORESIZE, DISKSIZE);% + VALUE OPTOG, IPTOG, NT, HIVALU, EQUALS, R, ALFA,% + CORESIZE, DISKSIZE;% + NAME TP1, TP2, TP3, TP4, TP5;% + REAL T1, T2, T3, ENDQ, BINGO, IPFIDX, OUTPRO, INPRO,% + OUTF, INF, DKO, DKI, NT, HIVALU, EQUALS, R, CORESIZE; + BOOLEAN OPTOG, IPTOG, ALFA;% + INTEGER DISKSIZE;% + FORWARD;% CODE=40140000, INTRINSIC NUMBER=@27 + PROCEDURE STATUSINT(T, C);% + VALUE T, C;% + REAL T;% + INTEGER C;% + FORWARD;% CODE= INTRINSIC NUMBER=@30 + REAL PROCEDURE MAXINT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@31 + REAL PROCEDURE MININT(X);% + VALUE X;% + REAL X;% + FORWARD;% CODE= INTRINSIC NUMBER=@32 + PROCEDURE DELAYINT(ARRY, MASK, TIME);% + VALUE ARRY, MASK, TIME;% + ARRAY ARRY[*];% + REAL MASK;% + INTEGER TIME;% + FORWARD;% CODE= INTRINSIC NUMBER=@33 + PROCEDURE SUPERMOVERINT(SORCE, DEST, AEXP);% + VALUE AEXP;% + ARRAY SORCE[*], DEST[*];% + INTEGER AEXP;% + FORWARD;% CODE= INTRINSIC NUMBER=@34 + PROCEDURE SISO; FORWARD; %INT#35,SEQ#08400000 + INTEGER PROCEDURE DELTA(P1,P2);%INT#36,SEQ#00022300 + VALUE P1,P2; INTEGER P1,P2; FORWARD; + PROCEDURE ICVD; FORWARD; %INT#37,SEQ#00022500 +PROCEDURE DYNAMICDIALER(B, A, X, F); +VALUE B, A, X, F; +INTEGER B, A, X; BOOLEAN F; + FORWARD;% CODE=00022700, INTRINSIC NUMBER=@40 + PROCEDURE SCAN(UPDPDD,PRT,UPDCDD,HISCOUNT,CASECODE,CHAR); + VALUE PTR, HISCOUNT, CASECODE, CHAR; + NAME UPDPDD, UPDCDD; + INTEGER PTR, HISCOUNT, CASECODE, CHAR; + FORWARD; + PROCEDURE REPL; FORWARD; %INT#42,SEQ#08420000 + PROCEDURE COMPARE;FORWARD; %INT#43,SEQ#08430000 + PROCEDURE BASICPRINT(TYPE); + VALUE TYPE; + REAL TYPE; + FORWARD; CODE=08500000, INTRINSIC NUMBER=@44 + PROCEDURE SWAP; FORWARD; %INT#45,SEQ#00023700 + PROCEDURE BASICINPUT(TYPES); + VALUE TYPES; + REAL TYPES; + FORWARD;% CODE=08700000, INTRINSIC NUMBER=@46 + PROCEDURE READATA(TYPE); + VALUE TYPE; + REAL TYPE; + FORWARD;% CODE=08600000, INTRINSIC NUMBER=@47 + PROCEDURE FTINT ; FORWARD; % 050 + PROCEDURE FTOUT ; FORWARD; % 051 + PROCEDURE DABS ; FORWARD; % 052 + PROCEDURE CABS ; FORWARD; % 053 + PROCEDURE AINT ; FORWARD; % 054 + PROCEDURE MATH ; FORWARD; % 055 + PROCEDURE XTOI ; FORWARD; % 056 + PROCEDURE IDINT ; FORWARD; % 057 + PROCEDURE FLOAT ; FORWARD; % 060 + PROCEDURE SNGL ; FORWARD; % 061 + PROCEDURE DBLE ; FORWARD; % 062 + PROCEDURE AMOD ; FORWARD; % 063 + PROCEDURE TIME ; FORWARD; % 064 + PROCEDURE DMOD ; FORWARD; % 065 + PROCEDURE DMAX1 ; FORWARD; % 066 + PROCEDURE DMIN1 ; FORWARD; % 067 + PROCEDURE SIGNV ; FORWARD; % 070 + PROCEDURE DSIGN ; FORWARD; % 071 + PROCEDURE DIIM ; FORWARD; % 072 + PROCEDURE REALP ; FORWARD; % 073 + PROCEDURE AIMAG ; FORWARD; % 074 + PROCEDURE CMPLX ; FORWARD; % 075 + PROCEDURE CONJG ; FORWARD; % 076 + PROCEDURE DEXP ; FORWARD; % 077 + PROCEDURE CEXP ; FORWARD; % 100 + PROCEDURE DLOG ; FORWARD; % 101 + PROCEDURE CLOG ; FORWARD; % 102 + PROCEDURE ALOG10; FORWARD; % 103 + PROCEDURE DLOG10; FORWARD; % 104 + PROCEDURE DSIN ; FORWARD; % 105 + PROCEDURE CSIN ; FORWARD; % 106 + PROCEDURE DCOS ; FORWARD; % 107 + PROCEDURE CCOS ; FORWARD; % 110 + PROCEDURE TANF ; FORWARD; % 111 + PROCEDURE COTAN ; FORWARD; % 112 + PROCEDURE DATAN ; FORWARD; % 113 + PROCEDURE ATAN2 ; FORWARD; % 114 + PROCEDURE DATAN2; FORWARD; % 115 + PROCEDURE ARSIN ; FORWARD; % 116 + PROCEDURE ARCOS ; FORWARD; % 117 + PROCEDURE SINH ; FORWARD; % 120 + PROCEDURE COSH ; FORWARD; % 121 + PROCEDURE TANH ; FORWARD; % 122 + PROCEDURE DSQRT ; FORWARD; % 123 + PROCEDURE CSQRT ; FORWARD; % 124 + PROCEDURE ERF ; FORWARD; % 125 + PROCEDURE GAMMA ; FORWARD; % 126 + PROCEDURE ALGAMA; FORWARD; % 127 + PROCEDURE ANDI ; FORWARD; % 130 + PROCEDURE ORI ; FORWARD; % 131 + PROCEDURE CMPL ; FORWARD; % 132 + PROCEDURE EQUIVP; FORWARD; % 133 + PROCEDURE FORTERR;FORWARD; % 134 + PROCEDURE MAX; FORWARD; % 135 + PROCEDURE MIN; FORWARD; % 136 + PROCEDURE IMOD; FORWARD; % 137 + PROCEDURE CONCAT; FORWARD; % 140 + PROCEDURE CONCAT; + FORWARD;% CODE=08400000, INTRINSIC NUMBER=@140 + PROCEDURE MATRIXDIDDLER(A, B, C, TYPE); + VALUE A, B, C, TYPE; + ARRAY A[*], B[*], C[*]; + INTEGER TYPE; + FORWARD;% CODE=08800000, INTRINSIC NUMBER=@~4~ + PROCEDURE INVERT(A, B); + VALUE A, B; + ARRAY A[*], B[*]; + FORWARD;% CODE=09100000, INTRINSIC NUMBER=@142 + PROCEDURE TRANSPOSE(A, B); + VALUE A, B; + ARRAY A[*], B[*]; + FORWARD;% CODE=08900000, INTRINSIC NUMBER=@143 + PROCEDURE MATRIXMULTIPLY(A, B, C); + VALUE A, B, C; + ARRAY A[*], B[*], C[*]; + FOWARD;% CODE=09000000, INTRINSIC NUMBER=@144 + PROCEDURE RANDOM(NUMBER, BASE); + VALUE NUMBER; + REAL NUMBER; + INTEGER BASE; + FORWARD;% CODE=00022900, INTRINSIC NUMBER=@145 + PROCEDURE FORTRANFREEREAD; + FORWARD;% CODE=09200000, INTRINSIC NUMBER=@146 + PROCEDURE BASICLOSE(FILX); + VALUE FILX; NAME FILX; + BEGIN REAL SELECT=14, ALGOLWRITE=12; ARRAY AIT=6[*]; + REAL T,I; ARRAY FIB[*]; NAME M=2; + SUBROUTINE MAYBEPRINT; + BEGIN FIB:=FILX[NOT 2]; + IF FIB[5].[41:3]=0 THEN %NOT CLOSED-NOT INPUT + IF FIB[4].[8:4] NEQ 10 THEN %NOT DATA COM + IF FIB[20].[3:15]!0 THEN % DATA LEFT + P(MKS,1,0,0,(FIB[20].[18:10]+1),FILX,ALGOLWRITE); + END; + IF P(.FILX,LOD)=0 THEN %EOJ FILE CLOSE + BEGIN I:=AIT[0]+1; WHILE (T:=AIT[I:=I-1]).[8:10] NEQ 0 + DO IF T.[1:1] THEN + BEGIN FILX:=M[M[T.[18:15]] INX 4]; MAYBEPRINT END; + END ELSE %FILE RESTORE + BEGIN MAYBEPRINT; + P(MKS,2,0,[FILX[NOT 2]],4,SELECT); + FIB[0]:=FIB[8]:=FIB[20]:=FIB[21]:=0; + END; + END BASIC FILE RESTORE; +PROCEDURE FILEATTRIBUTES(T,E,D,V,G,I,TN); VALUE T,I,V,D,G; REAL D,G,I,E; +INTEGER V; ARRAY TN[*]; NAME T; FORWARD; % CODE @ 0043000, INT # @150 +PROCEDURE COBOLDECIMALTOOCTALCONVERT(A); % INT #=@151, CODE=09300000 +VALUE A; NAME A; FORWARD ; +PROCEDURE COBOLOCTOLTODECIMALCONVERT(A,L,H,R,N,S,T); % INT #=@152 +VALUE L,H,R,N,S,T; REAL L,H,R,N,S,T; NAME A; FORWARD; % CODE=09400000 +PROCEDURE FORTRANFREEWRITE(F,D,R,W,L,I,N,S); VALUE I,D,R,W,L; INTEGER R, +W; REAL I,D,L; NAME F; ARRAY S[*],N[*]; FORWARD ;%COD @02976019.INT@153 +PROCEDURE FINNAME; FORWARD; +PROCEDURE FOUTNAME; FORWARD; +PROCEDURE FTINTFIX(F1,D2,F2,F3,L1,E1,E2,P1); VALUE D1,F2,L1,E1,E2,P1 ; +REAL D1,F2,L1,E1,E2,P1; ARRAY F3[*]; NAME F1; FORWARD; % INTRINSIC @156 +PROCEDURE FTOUTFIX(F,D,R,Q,L,E,EL,PL); VALUE D,R,L,E,EL,PL; REAL D,R,L,E +,EL,PL; NAME F; ARRAY Q[*]; FORWARD ; % CODE AT SEQ # 02886040, INT@157 +PROCEDURE FBINBACKBLOCK(F1,D,F2,F3,L,E1,E2,P1); VALUE D,F2,L,E1,E2,P1 ; +REAL D,F2,L,E1,E2,P1; ARRAY F3[*]; NAME F1; FORWARD; % INT # @160. +PROCEDURE COBOLVARSZ; FORWARD;% CODE=09500000 INT #=@161 +PROCEDURE COBOLIONONDSK; FORWARD;% CODE=096000000 INT #=@162 +PROCEDURE COBOLIODSK; FORWARD;% CODE=09700000 INT #=@163 +PROCEDURE FORTRANMEMHANDLER(A,H);VALUE H;REAL H;ARRAY A[*];FORWARD;%164 +PROCEDURE COBOLATT; FORWARD; % CODE = 02650000 INT # = @165 %CJC 103I +PROCEDURE INTERRUPTER; FORWARD; % CODE=09800000; INT #=@166 +PROCEDURE COBOLDC; FORWARD; % CODE = 02690000 INT #=@167 +INTEGER PROCEDURE DELTA(P1,P2); VALUE P1,P2; REAL P1,P2; %@036 +BEGIN + DEFINE + DOT=[18:13]#, AMPER=[18:35:13]#; + COMMENT @4000000=2|20, WHICH IS 1 LARGER THAN ANY 6500 COUNT.; + COMMENT DELTA=2|20 IF DESC(P1)!DESC(P2) OR CSIZE-S ARE !; + IF (P2-P1).[31:17]!0 THEN DELTA~@4000000 ELSE + DELTA~P2.DOT-P1.DOT; +END DELTA; + +PROCEDURE ICVD; %37 +BEGIN + DEFINE DOT=[18:13]#, AMPER=[18:35:13]#, CSIZE=[31:02]#,SIX=0#; + ARRAY STRING[*]; + NAME M = 2; + REAL PTR=-3; INTEGER N=-1; + IF PTR.CSIZE!SIX THEN POLISH(M&1[17:47:01],9999,CDC,DEL); + STRING ~ M[PTR]; + N~N; COMMENT MAKE SURE N IS INTEGERIZED; + IF N>8 THEN POLISH(M&1[14:47:01],N,CDC,DEL); + POLISH([STRING[(PTR.DOT+N-1).[35:10]]], DEL); + STREAM(RESULT~0:S~[STRING[PTR.[18:10]]], N, + SKS~PTR.[28:03]); + BEGIN + DI ~ LOC RESULT; + SI ~ S; SI ~ SI+SKS + DS ~ N OCT; + END; + PTR ~ P; +END ICVD; +PROCEDURE DYNAMICDIALER(A,B,X,F) ; +VALUE B, A, X, F; +INTEGER B, A, X; BOOLEAN F; + BEGIN % A,B,X,Y,Z ARE AS IN Y&Z[A:B:X]. + % F=TRUE => X WAS LITERAL, AND TRB WILL BE DONE AFTER XITING. + REAL Y=-7, Z=-6, C=+1 ; + DEFINE Q= @3403007777777777 #, % MASK FOR ZERO-ING OUT THE G,H,K&V- + % REGISTER PARTS OF THE ROW. + R= @0055005500610065 #, % NOP,DIA,DIB,TRB. + S= @0055703404210435 #; % NOP,LITC Y,STD,XIT. + IF (A~A)<1 OR (B~B)<1 OR (X~X)<1 OR X+A>48 OR X+B>48 + THEN P((-63),26,COM) ; + IF F THEN P(Q,AND,0&(B MOD 6)[4:9:3],A MOD 6,DIB 7,TRB 3, + P&(B DIV 6)[12:45:3],A DIV 6,DIB 15,TRB 3,OR,0,0,XIT) ; + GO P(P(R)&(B DIV 6)[12:45:3],A DIV 6,DIB 24,TRB 3,P&(B MOD 6) + [15:9:3],A MOD 6,DIB 27,TRB 3,P&X[36:42:6],.A,~,S,.B,~,Y,Z,[A]); +END DYNAMICDIALER; + + +PROCEDURE RANDOM(NUMBER, BASE); + VALUE NUMBER; + REAL NUMBER; + INTEGER BASE; + BEGIN INTEGER N; + REAL T; + IF (T := NUMBER MOD 1.0)>0 THEN + BEGIN BASE := T.[9:38]; P(RTN); END; + IF NUMBER!0 THEN + BEGIN T := POLISH(1, 1, COM); + N := 0 & T[10:36:6] & T[16:42:6] & T[22:30:6] + & ((T.[30:18])|P(DUP))[28:22:20]; + END ELSE IF (N := BASE)=0 THEN N := @2631353020000; + T := 3 & (N.[10:26]|6137 + 2197513)[10:12:36]; + POLISH((((BASE := T) OR 0.5) - 0.5) + P(DUP), RTN); +END RANDOM; + + +PROCEDURE SWAP; % 045 +BEGIN + ARRAY A = -2 [*,*], B = -1 [*,*]; + STREAM(A, B, CA~0, CB~0, FA~A.[18:15], FB~B.[18:15]); + BEGIN + SI ~ A; CA ~ SI; + SI ~ B; CB ~ SI; + DI ~ LOC B; DI ~ DI+5; SKIP 3 DB; + SI ~ LOC CA; SI ~ SI+5; SKIP 3 SB; + 3(IF SB THEN DS ~ SET ELSE DS ~ RESET; SKIP SB); DS ~ 2 CHR; + DI ~ DB; SI ~ LOC B; DS ~ WDS; + DI ~ LOC A; DI ~ DI+5; SKIP 3 DB; + SI ~ LOC CB; SI ~ SI+5; SKIP 2 SB; + 3(IF SB THEN DS ~ SET ELSE DS ~ RESET; SKIP SB); DS ~ 2 CHR; + DI ~ FA; SI ~ LOC A; DS ~ WDS; + END; +END SWAP; + + + + +COMMENT ALGOL WRITE INTRINSIC;% +PROCEDURE ALGOLWRITE(TEN, FILX, CHSKP, LNSKP, FI, AEXP, + ARRY, LINESKIP, CHANSKIP, SUPRS, NUMWDS, TANK); + VALUE LINESKIP, CHANSKIP, SUPRS, NUMWDS, TANK, + CHSKP, LNSKP, FI, ARRY; + INTEGER CHSKP, LNSKP, FI, AEXP, + LINESKIP, CHANSKIP, NUMWDS, SUPRS; + NAME FILX, TANK; + ARRAY ARRY[*], TEN[*]; +BEGIN REAL SELECT=14,REED=13,ADDRESS;% + NAME MEM=2;% + LABEL AB,ACTION; + LABEL DS,WINDUP1; + ARRAY FPB=3[*],FIB[*],HEADER[*];% + INTEGER I,RSIZE;% + INTEGER SPOUT; + ARRAY TINK=TANK[*]; + REAL CHNSKP=CHANSKIP; + REAL ALGOLWRITE=12; + DEFINE FNUM = FIB[4].[11:31] #; + $ SET OMIT = NOT(TIMESHARING) +SUBROUTINE WAIT; POLISH(TANK, @2000000000, 36, COM, DEL DEL); + $ POP OMIT + $ SET OMIT = TIMESHARING + LABEL ERR,LP1,MT1,CLOSED,DK1,SP1,CP1,DC1,PP1;% + LABEL DCN1,DCN2,SPIN; + $ SET OMIT = NOT SHAREDISK + SWITCH SW1~ ERR,LP1,MT1,CLOSED,DK1,SP1,CP1,LP1,PP1,ERR,DC1, + ERR,LP1,DCN1; + LABEL LP2,MT2,DK2,SP2,CP2,DC2,PP2;% + SWITCH SW2~ ERR,LP2,MT2,ERR,DK2,SP2,CP2,LP2,PP2,ERR,DC2,ERR, + LP2,DCN2; + LABEL DS1,DR1,DU1;% + SWITCH DSW1~DS1,DR1,DU1,CLOSED; + LABEL UT,PBIT,DWT,D19,RELEASE,STA,EXIT,L1,WINDUP,DBIT;% + LABEL TYPEU,TYPEA,TYPEC;% + SWITCH TYPE~TYPEU,TYPEA,ERR,TYPEC;% + LABEL DS2,DR2,DU2;% + SWITCH DSW2~DS2,DR2,DU2;% + SUBROUTINE BLOCK;% + BEGIN GO TO TYPE[I~FIB[5].[46:2]];% +TYPEC: STREAM(D1~IOD,S~(NUMWDS~NUMWDS+1)|8,% + D2~(TANK[0]~NUMWDS INX IOD));% + BEGIN SI~LOC S; DI~DI-8; DS~4 DEC; DI~D1;% + SI~D2; SI~SI-8; DI~DI-4; DS~4 CHR;% + END;% + IF (FIB[17]~FIB[17]-NUMWDS)>RSIZE+1 THEN BEGIN% +OWT: FIB[7]~FIB[7]+1; P(XIT);% +TYPEA: IF (FIB[17]~FIB[17]-RSIZE)}RSIZE THEN% + BEGIN TANK[0]~RSIZE INX IOD; GO OWT END END;% + NUMWDS~FIB[18].[18:5]-FIB[17]+(I=3);% +TYPEU: END BLOCK;% + REAL SUBROUTINE DISKADDRESS;% + BEGIN% + ADDRESS~(CHANSKIP DIV HEADER[0].[30:12])|HEADER[0].[42:6];% + IF (SUPRS~ADDRESS DIV HEADER[1]+10)}30 THEN + BEGIN P(0); GO TO EXIT END; + IF HEADER[SUPRS]=0 THEN + IF HEADER[9]>(SUPRS-10) THEN% + P(FPB[FNUM+3],FPB[FNUM],FPB[FNUM+1],SUPRS,HEADER, + 4,11,COM,DEL,DEL,DEL,DEL,DEL,DEL) ELSE + BEGIN P(0); GO TO EXIT END;% + ADDRESS~HEADER[SUPRS]+SUPRS+ADDRESS MOD HEADER[1];% + STREAM(D~[ADDRESS]); BEGIN SI~D; DS~8 DEC END; P(1);% + EXIT: DISKADDRESS~P;% + END DISKADDRESS;% + IF TINK=0 THEN %WF + BEGIN FIB ~ FILX[NOT 2]; %WF + IF FIB[5].[11:2]<2 THEN P(MKS,"WRITING",FILX,7,SELECT) ; + IF FIB[5].[43:1] THEN + P(MKS, CHSKP, 0, FILX, 1, SELECT); + IF LNSKP>1 AND ARRY{0 AND (I~FIB[4].[8:4])!1 + $ SET OMIT = NOT(TIMESHARING) + AND I!7 AND I!12 AND I!10 THEN + $ SET OMIT = TIMESHARING + P(XIT);%CARRIAGE CONTROL ON NON-PRINTER FILE + + + RSIZE ~ P(MKS, LNSKP, CHSKP, SUPRS, %WF + (-1), FILX, ALGOLWRITE); %WF + IF ARRY{0 THEN SUPRS ~ 1 ELSE %WF + BEGIN % 11/24/72 - CORRECTED 10/3/73 + IF ARRY.[8:10]=P(DUP,0) THEN % INDEXED WRITE + P(DEL,AEXP) % WRITE MIN(AEXP,RSIZE) WORDS + ELSE % WRITE MIN(ARRY, SIZE,AEXP,RSIZE) WORDS + IF P GTR P(DUP,AEXP) % + THEN P(DEL,AEXP); %WF + IF P(DUP)}RSIZE THEN P(DEL) ELSE RSIZE ~ P; %WF + STREAM(P4 ~ [ARRY[0]], P3 ~ RSIZE, %WF + P2 ~ P(DUP).[36:6], P1 ~ *FILX); %WF + END; %WF + END; %WF + IF RSIZE>0 THEN P(MKS, LNSKP, %WF + CHSKP, SUPRS, RSIZE, FILX, ALGOLWRITE); %WF + FILX[NOT 4] ~ FILX[NOT 3] ~ 0; %WF + P(XIT); %WF + END; %WF + FIB~TANK[NOT 2];% +UT: I~FIB[4].[8:4]; RSIZE~FIB[18].[33:15];% + SPOUT:=(I=5); + $ SET OMIT = TIMESHARING + IF CHNSKP.[4:1] THEN + BEGIN CHNSKP.[4:1]~0; + $ SET OMIT = NOT SHAREDISK + END; + IF NUMWDS<0 THEN GO TO SW1[I]; GO TO SW2[I];% + LP1: MT1: SP1: CP1: PP1: +% +D19: IF IOD.[19:1] THEN% +PBIT: IF IOD.[2:1] THEN P(RSIZE,RTN) ELSE% + IF IOD.[25:1] THEN% +CLOSED: BEGIN + FIB[13].[27:1]~0; + IF (I~(FPB[FNUM+3] AND 31)!10 AND I!12 + AND I!13 AND I!26 THEN FIB[5].[45:1]~0 ELSE + FIB[5].[45:1]~P(TANK[NOT 3],DUP)!0 AND P(XCH)!15; + P(TANK,0,11,COM,DEL,DEL) ; + IF NOT FIB[5].[45:1] THEN GO UT ; + P(TANK[NOT 3]); TANK[NOT 3]~TANK[NOT 4]~0 ; + P(MKS,9,BLKCNTRL,DEL) ;% TAKE PARITY ACTION LBL BRNCH. + P(1); GO TO DS; + END ELSE + IF IOD.[27:1] AND (I=2 OR I=7 OR I=8) THEN% + BEGIN IF NOT FIB[4].[2:1] THEN% + BEGIN HEADER~TANK[NOT 1];HEADER[4].[42:6]~1 END; + IF I=7 THEN FIB[9].[1:1]~1; % MULTI-REEL PBT FILE + I~FIB[13].[28:10]+1;% + P(MKS,6,0,(NOT 2) INX TANK,4,SELECT);% + FIB[13].[28:10]~I; GO TO CLOSED;% + END ELSE% + BEGIN +ERR: P(3); +DS: P(TANK,XCH,11,COM); + END; + WAIT; GO TO PBIT;% +DK1: HEADER~*[FIB[14]]; GO TO DSW1[FIB[4].[27:3]];% +DK2: HEADER~*[FIB[14]]; GO TO DSW2[FIB[4].[27:3]];% +CP2: BLOCK; TANK[0]~FLAG(FIB[16])&CHANSKIP[32:47:1]; GO TO RELEASE;% +LP2: IF SUPRS THEN STREAM(RSIZE,D~IOD); BEGIN RSIZE(DS~8 LIT " ") END; + CHANSKIP~CHANSKIP+LINESKIP.[45:1]; + IF CHANSKIP!0 THEN% + BEGIN IF (I~FIB[17]-RSIZE)>0 THEN% + STREAM(I,D~RSIZE INX IOD); BEGIN I(DS~8 LIT " ") END;% + END ELSE BLOCK;% + TANK[0]~FLAG(FIB[16])&LINESKIP[27:47:1]&LINESKIP[28:46:1]% + &CHANSKIP[29:44:4]&NUMWDS[8:38:10];% + GO TO RELEASE;% +SP2: PP2:% +MT2: BLOCK;% + P(TANK[0]~FLAG(FIB[16])&NUMWDS[8:38:10],NUMWDS,XCH,INX,% + @3700000000000000,XCH,~);% + IF SPOUT THEN % SPO OUTPUT + IF FPB[FNUM+3].[42:6]=43 THEN P(XIT) ELSE %DUMMY + P(0,0,NOT,IOD,INX,15,COM,XIT) + ELSE +RELEASE: P(FLAG(FIB[19])&IOD[3:3:5],TANK,PRL,DEL);% +WINDUP: I~FIB[19].[33:15]-FIB[16].[33:15];% + FIB[16].[33:15]~SUPRS~MEM[P(DUP) INX NOT 1].[18:15];% + FIB[19].[33:15]~SUPRS+I;% + WINDUP1: + FIB[6]~FIB[6]+1; FIB[7]~FIB[7]+1; FIB[17]~FIB[18].[18:15];% + P(XIT);% +DU1:% +DS1: IF LINESKIP!0 THEN% + BEGIN IF IOD.[27:1] AND IOD.[19:1] THEN GO AB; + IF FIB[17]=FIB[18].[18:15] THEN + BEGIN CHANSKIP~FIB[7];% +L1: IF DISKADDRESS THEN% + IF IOD.[19:1] THEN DBIT: IF IOD.[2:1] THEN% + BEGIN + $ SET OMIT = NOT SHAREDISK + MEM[FIB[16]]~ADDRESS; + P(RSIZE,RTN); + END ELSE + IF IOD.[25:1] THEN GO TO CLOSED ELSE + $ SET OMIT = NOT SHAREDISK + BEGIN + $ SET OMIT = NOT SHAREDISK + GO TO AB; + END ELSE + BEGIN WAIT; GO TO DBIT; END ELSE + BEGIN + $ SET OMIT = NOT SHAREDISK + GO TO AB; + END; + END; P(RSIZE,RTN);% + END;% + P(MKS,CHANSKIP,4,TANK,1,SELECT); GO TO L1; +DS2: IF FIB[7]>HEADER[7] THEN HEADER[7]~FIB[7];% + BLOCK; TANK[0]~FLAG(FIB[16]); GO RELEASE;% +DR1: IF LINESKIP!0 THEN CHANSKIP~FIB[7] ELSE FIB[7]~CHANSKIP;% + IF HEADER[7]HEADER[7] THEN HEADER[7]~FIB[7];% + BLOCK;% + CHANSKIP~FIB[7]+FIB[13].[10:9]|HEADER[0].[30:12];% + IF DISKADDRESS THEN% + BEGIN P(TANK[0]~FLAG(FIB[16])&0[24:24:1],(NOT 0),XCH,INX,% + ADDRESS,XCH,~);% + P(FLAG(FIB[19])&1[24:47:1],TANK,PRL,DEL);% + END ELSE% + BEGIN TANK[0]~FLAG(FIB[16])&0[24:24:1];% + P(FLAG(FIB[19]&1[24:44:4],TANK,PRL,DEL);% + END;% + GO TO WINDUP;% + $ SET OMIT = NOT(TIMESHARING) + DC1:: P(RSIZE, RTN); + $ SET OMIT = TIMESHARING + AB:: BEGIN IF(ADDRESS~TANK[NOT 4])=0 THEN GO ERR; + ACTION:: TANK[NOT 3]~TANK[NOT 4] ~0; + TANK[0] := IOD OR MEM; + P(ADDRESS,MKS,9,JUNK); GO TO ERR; + \ No newline at end of file diff --git a/build-release.cmd b/build-release.cmd new file mode 100644 index 0000000..297dbc1 --- /dev/null +++ b/build-release.cmd @@ -0,0 +1 @@ +"%ProgramFiles%\7-Zip\7z.exe" a -tzip releases\retro-b5500-%1.zip build-release.cmd emulator\ webui\ -x!webui\tools\* -x!webui\prototypes\* tools\*.html tools\*.job \ No newline at end of file diff --git a/emulator/B5500CentralControl.js b/emulator/B5500CentralControl.js index 1885255..873d853 100644 --- a/emulator/B5500CentralControl.js +++ b/emulator/B5500CentralControl.js @@ -55,19 +55,16 @@ function B5500CentralControl(global) { this.nextTimeStamp = 0; // Next actual Date.getTime() for timer tick this.timer = null; // Reference to the RTC setCallback id. - // Establish contexts for asynchronously-called methods - this.boundTock = B5500CentralControl.bindMethod(this.tock, this); - this.clear(); // Create and initialize the Central Control state } /**************************************/ /* Global constants */ -B5500CentralControl.version = "0.16"; +B5500CentralControl.version = "0.17"; B5500CentralControl.memReadCycles = 2; // assume 2 µs memory read cycle time (the other option was 3 µs) -B5500CentralControl.memWriteCycles = 3; // assume 4 µs memory write cycle time (the other option was 6 µs) +B5500CentralControl.memWriteCycles = 4; // assume 4 µs memory write cycle time (the other option was 6 µs) B5500CentralControl.rtcTick = 1000/60; // Real-time clock period, milliseconds B5500CentralControl.pow2 = [ // powers of 2 from 0 to 52 @@ -135,21 +132,21 @@ B5500CentralControl.unitSpecs = { DKA: {unitIndex: 29, designate: 6, unitClass: "B5500DiskUnit"}, DRB: {unitIndex: 30, designate: 8, unitClass: null}, DRA: {unitIndex: 31, designate: 4, unitClass: null}, - MTT: {unitIndex: 32, designate: 31, unitClass: null}, - MTS: {unitIndex: 33, designate: 29, unitClass: null}, - MTR: {unitIndex: 34, designate: 27, unitClass: null}, - MTP: {unitIndex: 35, designate: 25, unitClass: null}, - MTN: {unitIndex: 36, designate: 23, unitClass: null}, - MTM: {unitIndex: 37, designate: 21, unitClass: null}, - MTL: {unitIndex: 38, designate: 19, unitClass: null}, - MTK: {unitIndex: 39, designate: 17, unitClass: null}, - MTJ: {unitIndex: 40, designate: 15, unitClass: null}, - MTH: {unitIndex: 41, designate: 13, unitClass: null}, - MTF: {unitIndex: 42, designate: 11, unitClass: null}, - MTE: {unitIndex: 43, designate: 9, unitClass: null}, - MTD: {unitIndex: 44, designate: 7, unitClass: null}, - MTC: {unitIndex: 45, designate: 5, unitClass: null}, - MTB: {unitIndex: 46, designate: 3, unitClass: null}, + MTT: {unitIndex: 32, designate: 31, unitClass: "B5500MagTapeDrive"}, + MTS: {unitIndex: 33, designate: 29, unitClass: "B5500MagTapeDrive"}, + MTR: {unitIndex: 34, designate: 27, unitClass: "B5500MagTapeDrive"}, + MTP: {unitIndex: 35, designate: 25, unitClass: "B5500MagTapeDrive"}, + MTN: {unitIndex: 36, designate: 23, unitClass: "B5500MagTapeDrive"}, + MTM: {unitIndex: 37, designate: 21, unitClass: "B5500MagTapeDrive"}, + MTL: {unitIndex: 38, designate: 19, unitClass: "B5500MagTapeDrive"}, + MTK: {unitIndex: 39, designate: 17, unitClass: "B5500MagTapeDrive"}, + MTJ: {unitIndex: 40, designate: 15, unitClass: "B5500MagTapeDrive"}, + MTH: {unitIndex: 41, designate: 13, unitClass: "B5500MagTapeDrive"}, + MTF: {unitIndex: 42, designate: 11, unitClass: "B5500MagTapeDrive"}, + MTE: {unitIndex: 43, designate: 9, unitClass: "B5500MagTapeDrive"}, + MTD: {unitIndex: 44, designate: 7, unitClass: "B5500MagTapeDrive"}, + MTC: {unitIndex: 45, designate: 5, unitClass: "B5500MagTapeDrive"}, + MTB: {unitIndex: 46, designate: 3, unitClass: "B5500MagTapeDrive"}, MTA: {unitIndex: 47, designate: 1, unitClass: "B5500MagTapeDrive"}}; @@ -206,12 +203,12 @@ B5500CentralControl.prototype.clear = function clear() { this.LOFF = 0; // Load button pressed on console this.CTMF = 0; // Commence timing FF this.P2BF = 0; // Processor 2 busy FF - this.HP2F = 1; // Halt processor 2 FF + this.HP2F = 0; // Halt processor 2 FF + this.ccLatch = 0x20; // I/O Unit busy & P2 latched status (reset by console UI) this.interruptMask = 0; // Interrupt status mask this.interruptLatch = 0; // Interrupt latched status (reset by console UI) this.iouMask = 0; // I/O Unit busy status mask - this.iouLatch = 0; // I/O Unit busy latched status (reset by console UI) this.unitBusyLatch = 0; // Peripheral unit latched status (reset by console UI) this.unitBusyMask = 0; // Peripheral unit busy-status bitmask @@ -225,6 +222,7 @@ B5500CentralControl.prototype.clear = function clear() { this.P2 = (this.PB1L ? this.PA : this.PB); if (!this.P2) { this.P2BF = 1; // mark non-existent P2 as busy + this.ccLatch |= 0x10; } }; @@ -459,18 +457,6 @@ B5500CentralControl.prototype.clearInterrupt = function clearInterrupt() { case 0x12: // @22: Time interval this.CCI03F = 0; break; - case 0x13: // @23: I/O busy - this.CCI04F = 0; - break; - case 0x14: // @24: Keyboard request - this.CCI05F = 0; - break; - case 0x15: // @25: Printer 1 finished - this.CCI06F = 0; - break; - case 0x16: // @26: Printer 2 finished - this.CCI07F = 0; - break; case 0x17: // @27: I/O 1 finished this.CCI08F = 0; this.AD1F = 0; // make unit non-busy @@ -491,31 +477,33 @@ B5500CentralControl.prototype.clearInterrupt = function clearInterrupt() { this.AD4F = 0; // make unit non-busy this.iouMask &= 0x7; break; - case 0x1B: // @33: P2 busy - this.CCI12F = 0; + case 0x15: // @25: Printer 1 finished + this.CCI06F = 0; break; + case 0x16: // @26: Printer 2 finished + this.CCI07F = 0; + break; + + case 0x34: // @64-75: P1 syllable-dependent + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3A: + case 0x3B: + case 0x3C: + case 0x3D: + p1.I &= 0x0F; + break; + case 0x1C: // @34: Inquiry request this.CCI13F = 0; break; - case 0x1D: // @35: Special interrupt 1 - this.CCI14F = 0; - break; - case 0x1E: // @36: Disk file 1 read check finished - this.CCI15F = 0; - break; - case 0x1F: // @37: Disk file 2 read check finished - this.CCI16F = 0; + case 0x14: // @24: Keyboard request + this.CCI05F = 0; break; - case 0x20: // @40: P2 memory parity error - if (p2) {p2.I &= 0xFE} - break; - case 0x21: // @41: P2 invalid address error - if (p2) {p2.I &= 0xFD} - break; - case 0x22: // @42: P2 stack overflow - if (p2) {p2.I &= 0xFB} - break; case 0x24: // @44-55: P2 syllable-dependent case 0x25: case 0x26: @@ -538,19 +526,32 @@ B5500CentralControl.prototype.clearInterrupt = function clearInterrupt() { case 0x32: // @62: P1 stack overflow p1.I &= 0xFB; break; - case 0x34: // @64-75: P1 syllable-dependent - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - p1.I &= 0x0F; + + case 0x20: // @40: P2 memory parity error + if (p2) {p2.I &= 0xFE} + break; + case 0x21: // @41: P2 invalid address error + if (p2) {p2.I &= 0xFD} + break; + case 0x22: // @42: P2 stack overflow + if (p2) {p2.I &= 0xFB} break; + case 0x1E: // @36: Disk file 1 read check finished + this.CCI15F = 0; + break; + case 0x1F: // @37: Disk file 2 read check finished + this.CCI16F = 0; + break; + case 0x13: // @23: I/O busy + this.CCI04F = 0; + break; + case 0x1B: // @33: P2 busy + this.CCI12F = 0; + break; + case 0x1D: // @35: Special interrupt 1 + this.CCI14F = 0; + break; default: // no interrupt vector was set break; } @@ -574,7 +575,7 @@ B5500CentralControl.prototype.tock = function tock() { } } interval = (this.nextTimeStamp += B5500CentralControl.rtcTick) - thisTime; - this.timer = setCallback(this.boundTock, this, interval); + this.timer = setCallback(tock, this, interval); }; /**************************************/ @@ -587,12 +588,18 @@ B5500CentralControl.prototype.readTimer = function readTimer() { /**************************************/ B5500CentralControl.prototype.haltP2 = function haltP2() { - /* Called by P1 to halt P2. storeForInterrupt() will set P2BF=0 */ + /* Called by P1 to halt P2. We know that P2 is not currently running on this + thread, so check to see if it's running at all and has a callback scheduled. + If so, cancel the existing callback and schedule a new one for immediate + execution. With HP2F set, P2 will store its registers and stop at next SECL */ this.HP2F = 1; - // We know P2 is not currently running on this thread, so save its registers - if (this.P2 && this.P2.busy) { - this.P2.storeForInterrupt(1, 0); + this.ccLatch |= 0x20; + if (this.P2 && this.P2BF) { + if (this.P2.scheduler) { + clearCallback(this.P2.scheduler); + } + this.P2.scheduler = setCallback(this.P2.schedule, this.P2, 0); } }; @@ -608,6 +615,7 @@ B5500CentralControl.prototype.initiateP2 = function initiateP2() { this.signalInterrupt(); } else { this.P2BF = 1; + this.ccLatch |= 0x10; this.HP2F = 0; this.P2.initiateAsP2(); } @@ -620,22 +628,22 @@ B5500CentralControl.prototype.initiateIO = function initiateIO() { if (this.IO1 && this.IO1.REMF && !this.AD1F) { this.AD1F = 1; this.iouMask |= 0x1; - this.iouLatch |= 0x1; + this.ccLatch |= 0x1; this.IO1.initiate(); } else if (this.IO2 && this.IO2.REMF && !this.AD2F) { this.AD2F = 1; this.iouMask |= 0x2; - this.iouLatch |= 0x2; + this.ccLatch |= 0x2; this.IO2.initiate(); } else if (this.IO3 && this.IO3.REMF && !this.AD3F) { this.AD3F = 1; this.iouMask |= 0x4; - this.iouLatch |= 0x4; + this.ccLatch |= 0x4; this.IO3.initiate(); } else if (this.IO4 && this.IO4.REMF && !this.AD4F) { this.AD4F = 1; this.iouMask |= 0x8; - this.iouLatch |= 0x8; + this.ccLatch |= 0x8; this.IO4.initiate(); } else { this.CCI04F = 1; // set I/O busy interrupt @@ -700,30 +708,16 @@ B5500CentralControl.prototype.setUnitBusy = function setUnitBusy(index, busy) { }; /**************************************/ -B5500CentralControl.prototype.fetchInterruptLatch = function fetchInterruptLatch() { - /* Returns and resets this.interruptLatch; used by console UI */ - var latch = this.interruptLatch; +B5500CentralControl.prototype.fetchCCLatches = function fetchCCLatches(latches) { + /* Returns the current latches in the "latches" array and and resets them. + Used by the Console UI */ + latches[0] = this.ccLatch; + this.ccLatch = this.iouMask | (this.P2BF << 4) | (this.HP2F << 5); + latches[1] = this.interruptLatch; this.interruptLatch = this.interruptMask; - return latch; -}; - -/**************************************/ -B5500CentralControl.prototype.fetchIOUnitLatch = function fetchIOUnitLatch() { - /* Returns and resets this.iouLatch; used by console UI */ - var latch = this.iouLatch; - - this.iouLatch = this.iouMask; - return latch; -}; - -/**************************************/ -B5500CentralControl.prototype.fetchUnitBusyLatch = function fetchUnitBusyLatch() { - /* Returns and resets this.unitBusyLatch; used by console UI */ - var latch = this.unitBusyLatch; - + latches[2] = this.unitBusyLatch; this.unitBusyLatch = this.unitBusyMask; - return latch; }; /**************************************/ @@ -791,6 +785,7 @@ B5500CentralControl.prototype.load = function load(dontStart) { return function boundLoadCompleteAnon() {return that.loadComplete(dontStart)} }(this, dontStart)); + this.clear(); // initialize P1/P2 configuration if (!this.P1 || this.P1.busy) { // P1 is busy or not available result = 1; } else if (!this.testUnitReady(22)) { // SPO not ready @@ -798,29 +793,28 @@ B5500CentralControl.prototype.load = function load(dontStart) { } else if (this.testUnitBusy(22)) { // SPO is busy result = 3; } else { // ready to rock 'n roll - this.clear(); this.nextTimeStamp = new Date().getTime(); this.tock(); this.LOFF = 1; if (this.IO1 && this.IO1.REMF && !this.AD1F) { this.AD1F = 1; this.iouMask |= 0x1; - this.iouLatch |= 0x1; + this.ccLatch |= 0x1; this.IO1.initiateLoad(this.cardLoadSelect, boundLoadComplete); } else if (this.IO2 && this.IO2.REMF && !this.AD2F) { this.AD2F = 1; this.iouMask |= 0x2; - this.iouLatch |= 0x2; + this.ccLatch |= 0x2; this.IO2.initiateLoad(this.cardLoadSelect, boundLoadComplete); } else if (this.IO3 && this.IO3.REMF && !this.AD3F) { this.AD3F = 1; this.iouMask |= 0x4; - this.iouLatch |= 0x4; + this.ccLatch |= 0x4; this.IO3.initiateLoad(this.cardLoadSelect, boundLoadComplete); } else if (this.IO4 && this.IO4.REMF && !this.AD4F) { this.AD4F = 1; this.iouMask |= 0x8; - this.iouLatch |= 0x8; + this.ccLatch |= 0x8; this.IO4.initiateLoad(this.cardLoadSelect, boundLoadComplete); } else { this.CCI04F = 1; // set I/O busy interrupt diff --git a/emulator/B5500Processor.js b/emulator/B5500Processor.js index 36b906e..547ccf6 100644 --- a/emulator/B5500Processor.js +++ b/emulator/B5500Processor.js @@ -34,13 +34,13 @@ function B5500Processor(procID, cc) { this.processorID = procID; // Processor ID ("A" or "B") this.mnemonic = "P" + procID; // Unit mnemonic - this.cc = cc; // Reference back to Central Control module + this.cc = cc; // Reference back to CentralControl module this.scheduler = null; // Reference to current setCallback token this.accessor = { // Memory access control block requestorID: procID, // Memory requestor ID addr: 0, // Memory address word: 0, // 48-bit data word - MAIL: 0, // Truthy if attempt to access @000-@777 in normal state + MAIL: 0, // Truthy if attempt to access @000-@777 in Normal State MPED: 0, // Truthy if memory parity error MAED: 0 // Truthy if memory address/inhibit error }; @@ -54,9 +54,10 @@ function B5500Processor(procID, cc) { /**************************************/ -B5500Processor.cyclesPerMilli = 1000; // clock cycles per millisecond (1000 = 1.0 MHz) +B5500Processor.cyclesPerMilli = 1000; // clock cycles per millisecond (1000 => 1.0 MHz) B5500Processor.timeSlice = 4000; // this.run() timeslice, clocks -B5500Processor.delaySamples = 1000; // this.delayDeltaAvg sampling average basis +B5500Processor.delayAlpha = 0.999; // decay factor for exponential weighted average delay +B5500Processor.slackAlpha = 0.9999; // decay factor for exponential weighted average slack B5500Processor.collation = [ // index by BIC to get collation value 53, 54, 55, 56, 57, 58, 59, 60, // @00: 0 1 2 3 4 5 6 7 @@ -94,7 +95,7 @@ B5500Processor.prototype.clear = function clear() { this.MSFF = 0; // Mark-stack FF (word mode: MSCW is pending RCW, physically also TFFF & Q12F) this.MWOF = 0; // Memory write obtained FF this.N = 0; // Octal shift counter for B - this.NCSF = 0; // Normal/control state FF (1=normal) + this.NCSF = 0; // Normal/Control State FF (1=normal) this.P = 0; // Current program instruction word register this.PROF = 0; // P contents valid this.Q = 0; // Misc. FFs (bits 1-9 only: Q07F=hardware-induced interrupt, Q09F=enable parallel adder for R-relative addressing) @@ -123,6 +124,8 @@ B5500Processor.prototype.clear = function clear() { this.procStart = 0; // Javascript time that the processor started running, ms this.procTime = 0.001; // Total processor running time, ms this.procSlack = 0; // Total processor throttling delay, ms + this.procSlackAvg = 0; // Average slack time per time slice, ms + this.procRunAvg = 0; // Average run time per time slice, ms }; /**************************************/ @@ -136,7 +139,7 @@ B5500Processor.prototype.accessError = function accessError() { this.I |= 0x01; // set I01F: memory parity error this.cc.signalInterrupt(); if (this.isP1 && !this.NCSF) { - this.stop(); // P1 memory parity in control state stops the proc + this.stop(); // P1 memory parity in Control State stops the proc } } }; @@ -326,10 +329,11 @@ B5500Processor.prototype.adjustAEmpty = function adjustAEmpty() { this.S++; this.storeBviaS(); // [S] = B } + } else { + this.BROF = 1; } this.B = this.A; this.AROF = 0; - this.BROF = 1; // else we're done -- A is already empty } }; @@ -388,23 +392,23 @@ B5500Processor.prototype.adjustABEmpty = function adjustABEmpty() { prior contents into memory, as necessary. */ if (this.BROF) { - this.BROF = 0; if ((this.S >>> 6) == this.R && this.NCSF) { this.I |= 0x04; // set I03F: stack overflow this.cc.signalInterrupt(); } else { this.S++; this.storeBviaS(); // [S] = B + this.BROF = 0; } } if (this.AROF) { - this.AROF = 0; if ((this.S >>> 6) == this.R && this.NCSF) { this.I |= 0x04; // set I03F: stack overflow this.cc.signalInterrupt(); } else { this.S++; this.storeAviaS(); // [S] = A + this.AROF = 0; } } }; @@ -558,7 +562,7 @@ B5500Processor.prototype.streamAdjustDestChar = function streamAdjustDestChar() }; /**************************************/ -B5500Processor.prototype.compareSourceWithDest = function compareSourceWithDest(count) { +B5500Processor.prototype.compareSourceWithDest = function compareSourceWithDest(count, numeric) { /* Compares source characters to destination characters according to the processor collating sequence. "count" is the number of source characters to process. @@ -574,7 +578,11 @@ B5500Processor.prototype.compareSourceWithDest = function compareSourceWithDest( may be required only for the first word in the destination string, if B may have been left in an updated state by a prior syllable */ var aBit; // A register bit nr + var aw; // current A register word var bBit; // B register bit nr + var bw; // current B register word + var Q03F = (this.Q & 0x04) >>> 2; // local copy of Q03F: inequality detected + var Q04F = (this.Q & 0x08) >>> 3; // local copy of Q04F: B not dirty var yc = 0; // local Y register var zc = 0; // local Z register @@ -584,11 +592,11 @@ B5500Processor.prototype.compareSourceWithDest = function compareSourceWithDest( if (count) { if (this.BROF) { if (this.K == 0) { - this.Q |= 0x08; // set Q04F -- at start of word, no need to store B later + Q04F = 1; // set Q04F -- at start of word, no need to store B later } } else { this.loadBviaS(); // B = [S] - this.Q |= 0x08; // set Q04F -- just loaded B, no need to store it later + Q04F = 1; // set Q04F -- just loaded B, no need to store it later } if (!this.AROF) { this.loadAviaM(); // A = [M] @@ -601,15 +609,17 @@ B5500Processor.prototype.compareSourceWithDest = function compareSourceWithDest( this.V = count & 0x07; aBit = this.G*6; // A-bit number + aw = this.A; bBit = this.K*6; // B-bit number + bw = this.B; do { this.cycleCount++; // approximate the timing - if (this.Q & 0x04) { // inequality already detected -- just count down + if (Q03F) { // inequality already detected -- just count down if (count >= 8) { count -= 8; - if (!(this.Q & 0x08)) { // test Q04F to see if B may be dirty + if (!Q04F) { // test Q04F to see if B may be dirty this.storeBviaS(); // [S] = B - this.Q |= 0x08; // set Q04F so we won't store B anymore + Q04F = 1; // set Q04F so we won't store B anymore } this.BROF = 0; this.S++; @@ -620,9 +630,9 @@ B5500Processor.prototype.compareSourceWithDest = function compareSourceWithDest( if (this.K < 7) { this.K++; } else { - if (!(this.Q & 0x08)) { // test Q04F to see if B may be dirty + if (!Q04F) { // test Q04F to see if B may be dirty this.storeBviaS(); // [S] = B - this.Q |= 0x08; // set Q04F so we won't store B anymore + Q04F = 1; // set Q04F so we won't store B anymore } this.K = 0; this.BROF = 0; @@ -637,9 +647,20 @@ B5500Processor.prototype.compareSourceWithDest = function compareSourceWithDest( } } } else { // strings still equal -- check this character - if ((yc = this.cc.fieldIsolate(this.A, aBit, 6)) != (zc = this.cc.fieldIsolate(this.B, bBit, 6))) { - this.Q |= 0x04; // set Q03F to stop further comparison - this.MSFF = (B5500Processor.collation[yc] > B5500Processor.collation[zc] ? 1 : 0); + if (numeric) { + yc = this.cc.fieldIsolate(aw, aBit+2, 4); + zc = this.cc.fieldIsolate(bw, bBit+2, 4); + } else { + yc = this.cc.fieldIsolate(aw, aBit, 6); + zc = this.cc.fieldIsolate(bw, bBit, 6); + } + if (yc != zc) { + Q03F = 1; // set Q03F to stop further comparison + if (numeric) { + this.MSFF = (yc > zc ? 1 : 0); + } else { + this.MSFF = (B5500Processor.collation[yc] > B5500Processor.collation[zc] ? 1 : 0); + } } else { // strings still equal -- advance to next character count--; if (bBit < 42) { @@ -648,13 +669,14 @@ B5500Processor.prototype.compareSourceWithDest = function compareSourceWithDest( } else { bBit = 0; this.K = 0; - if (!(this.Q & 0x08)) { // test Q04F to see if B may be dirty + if (!Q04F) { // test Q04F to see if B may be dirty this.storeBviaS(); // [S] = B - this.Q |= 0x08; // set Q04F so we won't store B anymore + Q04F = 1; // set Q04F so we won't store B anymore } this.S++; if (count > 0) { this.loadBviaS(); // B = [S] + bw = this.B; } else { this.BROF = 0; } @@ -668,6 +690,7 @@ B5500Processor.prototype.compareSourceWithDest = function compareSourceWithDest( this.M++; if (count > 0) { this.loadAviaM(); // A = [M] + aw = this.A; } else { this.AROF = 0; } @@ -676,6 +699,7 @@ B5500Processor.prototype.compareSourceWithDest = function compareSourceWithDest( } } while (count); + this.Q |= (Q03F << 2) | (Q04F << 3); this.Y = yc; // for display only this.Z = zc; // for display only } @@ -687,7 +711,9 @@ B5500Processor.prototype.fieldArithmetic = function fieldArithmetic(count, addin "count" indicates the length of the fields to be operated upon. "adding" will be false if this call is for FSU, otherwise it's for FAD */ var aBit; // A register bit nr + var aw; // current A register word var bBit; // B register bit nr + var bw; // current B register word var carry = 0; // carry/borrow bit var compl = false; // complement addition (i.e., subtract the digits) var TFFF; // local copy of MSFF/TFFF @@ -699,7 +725,7 @@ B5500Processor.prototype.fieldArithmetic = function fieldArithmetic(count, addin var zcompl = false; // complement destination digits var zd; // destination digit - this.compareSourceWithDest(count); + this.compareSourceWithDest(count, true); this.cycleCount += 2; // approximate the timing thus far if (this.Q & 0x20) { // Q06F => count > 0, so there's characters to add this.Q &= ~(0x28); // reset Q06F and Q04F @@ -731,9 +757,11 @@ B5500Processor.prototype.fieldArithmetic = function fieldArithmetic(count, addin this.Q |= 0x80; // set Q08F (for display only) aBit = this.G*6; // A-bit number + aw = this.A; bBit = this.K*6; // B-bit number - yd = (this.cc.fieldIsolate(this.A, aBit, 2) == 2 ? 2 : 0); // source sign - zd = (this.cc.fieldIsolate(this.B, bBit, 2) == 2 ? 2 : 0); // dest sign + bw = this.B; + yd = (this.cc.fieldIsolate(aw, aBit, 2) == 2 ? 2 : 0); // source sign + zd = (this.cc.fieldIsolate(bw, bBit, 2) == 2 ? 2 : 0); // dest sign compl = (yd == zd ? !adding : adding); // determine if complement needed resultNegative = !( // determine sign of result (zd == 0 && !compl) || @@ -755,8 +783,8 @@ B5500Processor.prototype.fieldArithmetic = function fieldArithmetic(count, addin do { count--; this.cycleCount += 2; - yd = this.cc.fieldIsolate(this.A, aBit+2, 4); // get the source digit - zd = this.cc.fieldIsolate(this.B, bBit+2, 4); // get the dest digit + yd = this.cc.fieldIsolate(aw, aBit+2, 4); // get the source digit + zd = this.cc.fieldIsolate(bw, bBit+2, 4); // get the dest digit sd = (ycompl ? 9-yd : yd) + (zcompl ? 9-zd : zd) + carry; // develop binary digit sum if (sd <= 9) { carry = 0; @@ -769,9 +797,10 @@ B5500Processor.prototype.fieldArithmetic = function fieldArithmetic(count, addin resultNegative = false; } - this.B = this.cc.fieldInsert(this.B, bBit, 6, sd); + bw = this.cc.fieldInsert(bw, bBit, 6, sd); if (count == 0) { + this.B = bw; this.storeBviaS(); // [S] = B, store final dest word } else { if (bBit > 0) { @@ -780,9 +809,11 @@ B5500Processor.prototype.fieldArithmetic = function fieldArithmetic(count, addin } else { bBit = 42; this.K = 7; + this.B = bw; this.storeBviaS(); // [S] = B this.S--; this.loadBviaS(); // B = [S] + bw = this.B; } if (aBit > 0) { aBit -= 6; @@ -792,6 +823,7 @@ B5500Processor.prototype.fieldArithmetic = function fieldArithmetic(count, addin this.G = 7; this.M--; this.loadAviaM(); // A = [M] + aw = this.A; } } } while (count); @@ -820,6 +852,8 @@ B5500Processor.prototype.fieldArithmetic = function fieldArithmetic(count, addin this.M++; } } + this.A = aw; + this.B = bw; this.AROF = this.BROF = 0; this.H = this.V = this.N = 0; this.MSFF = (compl ? 1-carry : carry); // MSFF/TFFF = overflow indicator @@ -932,15 +966,13 @@ B5500Processor.prototype.streamProgramToDest = function streamProgramToDest(coun }; /**************************************/ -B5500Processor.prototype.streamSourceToDest = function streamSourceToDest(count, transform) { - /* General driver for character-mode character transfers from source to - destination, such as TRS or TRZ. - "count" is the number of source characters to transfer. - "transform" is a function(bBit, c, count) that determines how the characters - are transferred from the source (A) to destination (B) */ +B5500Processor.prototype.streamCharacterToDest = function streamCharacterToDest(count) { + /* Transfers character transfers from source to destination for the TRS syllable. + "count" is the number of source characters to transfer */ var aBit; // A register bit nr var aw; // current A register word var bBit; // B register bit nr + var bw; // current B register word var c; // current character this.streamAdjustSourceChar(); @@ -952,13 +984,14 @@ B5500Processor.prototype.streamSourceToDest = function streamSourceToDest(count, if (!this.AROF) { this.loadAviaM(); // A = [M] } - this.cycleCount += count*2; // approximate the timing + this.cycleCount += 10 + count*2;// approximate the timing aBit = this.G*6; // A-bit number aw = this.A; bBit = this.K*6; // B-bit number + bw = this.B; do { c = this.cc.fieldIsolate(aw, aBit, 6); - transform.call(this, bBit, c, count) + bw = this.cc.fieldInsert(bw, bBit, 6, c); count--; if (bBit < 42) { bBit += 6; @@ -966,10 +999,12 @@ B5500Processor.prototype.streamSourceToDest = function streamSourceToDest(count, } else { bBit = 0; this.K = 0; + this.B = bw; this.storeBviaS(); // [S] = B this.S++; if (count > 0 && count < 8) { // only need to load B if a partial word is left this.loadBviaS(); // B = [S] + bw = this.B; } else { this.BROF = 0; } @@ -989,31 +1024,115 @@ B5500Processor.prototype.streamSourceToDest = function streamSourceToDest(count, } } } while (count); + this.B = bw; this.Y = c; // for display purposes only } }; /**************************************/ -B5500Processor.prototype.streamToDest = function streamToDest(count, transform) { - /* General driver for character-mode character operations on the destination - from a non-A register source, such as TBN. - "count" is the number of characters to transfer. - "transform" is a function(bBit, count) that determines how the characters - are stored to the destination (B). Returning truthy terminates the process - without incrementing the destination address */ +B5500Processor.prototype.streamNumericToDest = function streamNumericToDest(count, zones) { + /* Transfers character transfers from source to destination for the TRS syllable. + "count" is the number of source characters to transfer */ + var aBit; // A register bit nr + var aw; // current A register word var bBit; // B register bit nr + var bw; // current B register word + var c; // current character + this.streamAdjustSourceChar(); this.streamAdjustDestChar(); if (count) { if (!this.BROF) { this.loadBviaS(); // B = [S] } - this.cycleCount += count*2; // approximate the timing + if (!this.AROF) { + this.loadAviaM(); // A = [M] + } + if (zones) { // approximate the timing + this.cycleCount += 5 + count*4; + } else { + this.cycleCount += 10 + count*3; + } + + aBit = this.G*6; // A-bit number + aw = this.A; bBit = this.K*6; // B-bit number + bw = this.B; do { - if (transform.call(this, bBit, count)) { - count = 0; + c = this.cc.fieldIsolate(aw, aBit, 6); + if (zones) { // transfer only the zone portion of the char + bw = this.cc.fieldInsert(bw, bBit, 2, c >>> 4); + } else { // transfer only the numeric portion of the char + bw = this.cc.fieldInsert(bw, bBit+2, 4, c); + if (count == 1 && (c & 0x30) == 0x20) { + this.MSFF = 1; // neg. sign + } + } + count--; + if (bBit < 42) { + bBit += 6; + this.K++; } else { + bBit = 0; + this.K = 0; + this.B = bw; + this.storeBviaS(); // [S] = B + this.S++; + if (count > 0) { + this.loadBviaS(); // B = [S] + bw = this.B; + } else { + this.BROF = 0; + } + } + if (aBit < 42) { + aBit += 6; + this.G++; + } else { + aBit = 0; + this.G = 0; + this.M++; + if (count > 0) { // only need to load A if there's more to do + this.loadAviaM(); // A = [M] + aw = this.A; + } else { + this.AROF = 0; + } + } + } while (count); + this.B = bw; + this.Y = c; // for display purposes only + } +}; + +/**************************************/ +B5500Processor.prototype.streamBlankForNonNumeric = function streamBlankForNonNumeric(count) { + /* Implements the TBN (Transfer Blanks for Non-Numeric) syllable, which is + generally used to suppress leading zeroes in numeric strings. Transfers blanks + to the destination under control of the count as long as the destination characters + are not in the range "1"-"9". Sets MSFF (TFFF) true if the count is exhausted. + "count" is the maximum number of characters to blank */ + var bBit; // B register bit nr + var bw; // current B register word + var c; // current destination character + + this.MSFF = 1; // assume the count will be exhausted + this.streamAdjustDestChar(); + if (count) { + if (!this.BROF) { + this.loadBviaS(); // B = [S] + } + bBit = this.K*6; // B-bit number + bw = this.B; + do { + this.cycleCount += 2; // approximate the timing + c = this.cc.fieldIsolate(bw, bBit, 6); + if (c > 0 && c <= 9) { + this.MSFF = 0; // is numeric and non-zero: stop blanking + this.Q |= 0x04; // set Q03F (display only) + break; // terminate, pointing at this char + } else { + bw = this.cc.fieldInsert(bw, bBit, 6, 0x30); // replace with blank count--; if (bBit < 42) { bBit += 6; @@ -1021,16 +1140,20 @@ B5500Processor.prototype.streamToDest = function streamToDest(count, transform) } else { bBit = 0; this.K = 0; - this.storeBviaS(); // [S] = B + this.B = bw; + this.storeBviaS(); // [S] = B this.S++; - if (count > 0 && count < 8) { // only need to load B if a partial word is left - this.loadBviaS(); // B = [S] + if (count > 0) { + this.loadBviaS(); // B = [S] + bw = this.B; } else { this.BROF = 0; } } } } while (count); + this.B = bw; + this.Z = c; // for display purposes only } }; @@ -1200,7 +1323,7 @@ B5500Processor.prototype.storeForInterrupt = function storeForInterrupt(forced, var temp; if (forced || forTest) { - this.NCSF = 0; // switch to control state + this.NCSF = 0; // switch to Control State } if (this.CWMF) { @@ -1470,7 +1593,7 @@ B5500Processor.prototype.initiate = function initiate(forTest) { /**************************************/ B5500Processor.prototype.initiateAsP2 = function initiateAsP2() { - /* Called from Central Control to initiate the processor as P2. Fetches the + /* Called from CentralControl to initiate the processor as P2. Fetches the INCW from @10, injects an initiate P2 syllable into T, and calls start() */ this.NCSF = 0; // make sure P2 is in Control State to execute the IP1 & access low mem @@ -1573,7 +1696,7 @@ B5500Processor.prototype.singlePrecisionAdd = function singlePrecisionAdd(adding var xa = 0; // extension to A for scaling (pseudo X) var xb = 0; // extension to B for scaling (pseudo X) - this.cycleCount += 4; // estimate some general overhead + this.cycleCount += 2; // estimate some general overhead this.adjustABFull(); this.AROF = 0; // A is unconditionally marked empty ma = this.A % 0x8000000000; // extract the A mantissa @@ -1731,7 +1854,7 @@ B5500Processor.prototype.singlePrecisionMultiply = function singlePrecisionMulti var sb; // mantissa sign of B (ditto) var xx; // local copy of X for multiplier - this.cycleCount += 4; // estimate some general overhead + this.cycleCount += 2; // estimate some general overhead this.adjustABFull(); this.AROF = 0; // A is unconditionally marked empty ma = this.A % 0x8000000000; // extract the A mantissa @@ -1863,15 +1986,14 @@ B5500Processor.prototype.singlePrecisionDivide = function singlePrecisionDivide( var sb; // mantissa sign of B (ditto) var xx = 0; // local copy of X for quotient development - this.cycleCount += 4; // estimate some general overhead + this.cycleCount += 2; // estimate some general overhead this.adjustABFull(); this.AROF = 0; // A is unconditionally marked empty ma = this.A % 0x8000000000; // extract the A mantissa mb = this.B % 0x8000000000; // extract the B mantissa if (ma == 0) { // if A mantissa is zero - this.A = this.B = 0; // result is all zeroes - if (this.NCSF) { + if (this.NCSF) { // and we're in Normal State this.I = (this.I & 0x0F) | 0xD0; // set I05/7/8: divide by zero this.cc.signalInterrupt(); } @@ -1889,13 +2011,13 @@ B5500Processor.prototype.singlePrecisionDivide = function singlePrecisionDivide( // Normalize A for 39 bits (13 octades) while (ma < 0x1000000000) { this.cycleCount++; - ma *= 8; // shift left + ma *= 8; // shift left ea--; } // Normalize B for 39 bits (13 octades) while (mb < 0x1000000000) { this.cycleCount++; - mb *= 8; // shift left + mb *= 8; // shift left eb--; } @@ -1977,8 +2099,7 @@ B5500Processor.prototype.integerDivide = function integerDivide() { mb = this.B % 0x8000000000; // extract the B mantissa if (ma == 0) { // if A mantissa is zero - this.A = this.B = 0; // result is all zeroes - if (this.NCSF) { + if (this.NCSF) { // and we're in Normal State this.I = (this.I & 0x0F) | 0xD0; // set I05/7/8: divide by zero this.cc.signalInterrupt(); } @@ -2077,8 +2198,7 @@ B5500Processor.prototype.remainderDivide = function remainderDivide() { mb = this.B % 0x8000000000; // extract the B mantissa if (ma == 0) { // if A mantissa is zero - this.A = this.B = 0; // result is all zeroes - if (this.NCSF) { + if (this.NCSF) { // and we're in Normal State this.I = (this.I & 0x0F) | 0xD0; // set I05/7/8: divide by zero this.cc.signalInterrupt(); } @@ -2795,7 +2915,7 @@ B5500Processor.prototype.operandCall = function operandCall() { if (this.NCSF) { this.I = (this.I & 0x0F) | 0x70; // set I05/6/7: p-bit this.cc.signalInterrupt(); - // else if control state, we're done + // else if Control State, we're done } break; @@ -2843,7 +2963,7 @@ B5500Processor.prototype.descriptorCall = function descriptorCall() { if (this.NCSF) { this.I = (this.I & 0x0F) | 0x70; // set I05/6/7: p-bit this.cc.signalInterrupt(); - // else if control state, we're done + // else if Control State, we're done } break; @@ -2864,6 +2984,7 @@ B5500Processor.prototype.run = function run() { current program word must be in P with PROF set, and the C & L registers must point to the next syllable to be executed. This routine will continue to run while this.runCycles < this.cycleLimit */ + var cc = this.cc; // optimize local reference to CentralControl var noSECL = 0; // to support char mode dynamic count from CRF syllable var opcode; // copy of T register var t1; // scratch variable for internal instruction use @@ -2998,7 +3119,7 @@ B5500Processor.prototype.run = function run() { } for (variant=3; variant>0; variant--) { this.B = (this.B % 0x40000000000)*0x40 + - (this.Y = this.cc.fieldIsolate(this.A, this.G*6, 6)); + (this.Y = cc.fieldIsolate(this.A, this.G*6, 6)); if (this.G < 7) { this.G++; } else { @@ -3014,7 +3135,7 @@ B5500Processor.prototype.run = function run() { this.AROF = this.BROF = 0; // invalidate A & B break; - case 0x09: // XX11: control state ops + case 0x09: // XX11: Control State ops switch (variant) { case 0x14: // 2411: ZPI=Conditional Halt if (this.US14X) { // STOP OPERATOR switch on @@ -3035,21 +3156,8 @@ B5500Processor.prototype.run = function run() { } // end switch for XX11 ops break; - case 0x0A: // XX12: TBN=Transfer blank for numeric - this.MSFF = 1; // initialize true-false FF - this.streamToDest(variant, function TBN(bb, count) { - var c = this.Z = this.cc.fieldIsolate(this.B, bb, 6); - var result = 0; - - if (c > 0 && c <= 9) { - this.MSFF = 0; // numeric, non-zero: stop blanking - this.Q |= 0x04; // set Q03F (display only) - result = 1; // terminate, pointing at this char - } else { - this.B = this.cc.fieldInsert(this.B, bb, 6, 0x30); // replace with blank - } - return result; - }); + case 0x0A: // XX12: TBN=Transfer blanks for non-numeric + this.streamBlankForNonNumeric(variant); break; case 0x0C: // XX14: SDA=Store destination address @@ -3118,7 +3226,7 @@ B5500Processor.prototype.run = function run() { if (!this.AROF) { this.loadAviaM(); // A = [M] } - t1 = this.cc.fieldIsolate(this.A, this.G*6, 6); + t1 = cc.fieldIsolate(this.A, this.G*6, 6); this.MSFF = (t1 == variant ? 1 : 0); break; @@ -3127,7 +3235,7 @@ B5500Processor.prototype.run = function run() { if (!this.AROF) { this.loadAviaM(); // A = [M] } - t1 = this.cc.fieldIsolate(this.A, this.G*6, 6); + t1 = cc.fieldIsolate(this.A, this.G*6, 6); this.MSFF = (t1 != variant ? 1 : 0); break; @@ -3136,7 +3244,7 @@ B5500Processor.prototype.run = function run() { if (!this.AROF) { this.loadAviaM(); // A = [M] } - t1 = B5500Processor.collation[this.cc.fieldIsolate(this.A, this.G*6, 6)]; + t1 = B5500Processor.collation[cc.fieldIsolate(this.A, this.G*6, 6)]; t2 = B5500Processor.collation[variant]; this.MSFF = (t1 >= t2 ? 1 : 0); break; @@ -3146,7 +3254,7 @@ B5500Processor.prototype.run = function run() { if (!this.AROF) { this.loadAviaM(); // A = [M] } - t1 = B5500Processor.collation[this.cc.fieldIsolate(this.A, this.G*6, 6)]; + t1 = B5500Processor.collation[cc.fieldIsolate(this.A, this.G*6, 6)]; t2 = B5500Processor.collation[variant]; this.MSFF = (t1 > t2 ? 1 : 0); break; @@ -3186,7 +3294,7 @@ B5500Processor.prototype.run = function run() { if (!this.AROF) { this.loadAviaM(); // A = [M] } - t1 = B5500Processor.collation[this.cc.fieldIsolate(this.A, this.G*6, 6)]; + t1 = B5500Processor.collation[cc.fieldIsolate(this.A, this.G*6, 6)]; t2 = B5500Processor.collation[variant]; this.MSFF = (t1 <= t2 ? 1 : 0); break; @@ -3196,7 +3304,7 @@ B5500Processor.prototype.run = function run() { if (!this.AROF) { this.loadAviaM(); // A = [M] } - t1 = B5500Processor.collation[this.cc.fieldIsolate(this.A, this.G*6, 6)]; + t1 = B5500Processor.collation[cc.fieldIsolate(this.A, this.G*6, 6)]; t2 = B5500Processor.collation[variant]; this.MSFF = (t1 < t2 ? 1 : 0); break; @@ -3206,7 +3314,7 @@ B5500Processor.prototype.run = function run() { if (!this.AROF) { this.loadAviaM(); // A = [M] } - this.Y = t1 = this.cc.fieldIsolate(this.A, this.G*6, 6); + this.Y = t1 = cc.fieldIsolate(this.A, this.G*6, 6); this.Z = variant; // for display only if (B5500Processor.collation[t1] > B5500Processor.collation[variant]) { this.MSFF = (t1 == 0x20 ? 0 : (t1 == 0x3C ? 0 : 1)); // alphanumeric unless | or ! @@ -3220,7 +3328,7 @@ B5500Processor.prototype.run = function run() { if (!this.AROF) { this.loadAviaM(); // A = [M] } - t1 = (this.Y = this.cc.fieldIsolate(this.A, this.G*6, 6)) >>> (5-this.H); + t1 = (this.Y = cc.fieldIsolate(this.A, this.G*6, 6)) >>> (5-this.H); this.MSFF = ((t1 & 0x01) == (variant & 0x01) ? 1 : 0); break; @@ -3269,7 +3377,7 @@ B5500Processor.prototype.run = function run() { if (!this.PROF) { this.loadPviaC(); // fetch the program word, if necessary } - opcode = this.cc.fieldIsolate(this.P, this.L*12, 12); + opcode = cc.fieldIsolate(this.P, this.L*12, 12); if (variant) { // if repeat count from parameter > 0, apply it to the next syllable this.T = opcode = (opcode & 0x3F) + variant*0x40; @@ -3347,18 +3455,18 @@ B5500Processor.prototype.run = function run() { this.A = this.B; // save B in A this.AROF = this.BROF; t1 = this.X; - variant = this.cc.fieldIsolate(t1, 12, 6); // get repeat count + variant = cc.fieldIsolate(t1, 12, 6); // get repeat count if (variant) { // loop count exhausted? - this.C = this.cc.fieldIsolate(t1, 33, 15); // no, restore C, L, and P to loop again - this.L = this.cc.fieldIsolate(t1, 10, 2); + this.C = cc.fieldIsolate(t1, 33, 15); // no, restore C, L, and P to loop again + this.L = cc.fieldIsolate(t1, 10, 2); this.PROF = 0; // require fetch at SECL - this.X = this.cc.fieldInsert(t1, 12, 6, variant-1); // store decremented count in X + this.X = cc.fieldInsert(t1, 12, 6, variant-1); // store decremented count in X } else { t2 = this.S; // save S (not the way the hardware did it) - this.S = this.cc.fieldIsolate(t1, 18, 15); // get prior LCW addr from X value + this.S = cc.fieldIsolate(t1, 18, 15); // get prior LCW addr from X value this.loadBviaS(); // B = [S], fetch prior LCW from stack this.S = t2; // restore S - this.X = this.cc.fieldIsolate(this.B, 9, 39); // store prior LCW (less control bits) in X + this.X = cc.fieldIsolate(this.B, 9, 39); // store prior LCW (less control bits) in X } this.B = this.A; // restore B this.BROF = this.AROF; @@ -3368,16 +3476,16 @@ B5500Processor.prototype.run = function run() { case 0x2A: // XX52: BNS=Begin loop this.cycleCount += 4; this.A = this.B; // save B in A (note that BROF is not altered) - t1 = this.cc.fieldInsert( // construct new LCW: insert repeat count - this.cc.fieldInsert( // insert L - this.cc.fieldInsert(this.X, 33, 15, this.C), // insert C + t1 = cc.fieldInsert( // construct new LCW: insert repeat count + cc.fieldInsert( // insert L + cc.fieldInsert(this.X, 33, 15, this.C), // insert C 10, 2, this.L), - 12, 6, (variant ? variant-1 : 0)); // decrement count for first iteration - this.B = this.cc.fieldInsert(this.X, 0, 2, 3); // set control bits [0:2]=3 + 12, 6, (variant ? variant-1 : 0)); // decrement count for first iteration + this.B = cc.fieldInsert(this.X, 0, 2, 3); // set control bits [0:2]=3 t2 = this.S; // save S (not the way the hardware did it) - this.S = this.cc.fieldIsolate(t1, 18, 15)+1; // get F value from X value and ++ + this.S = cc.fieldIsolate(t1, 18, 15)+1; // get F value from X value and ++ this.storeBviaS(); // [S] = B, save prior LCW in stack - this.X = this.cc.fieldInsert(t1, 18, 15, this.S); // update F value in X + this.X = cc.fieldInsert(t1, 18, 15, this.S); // update F value in X this.S = t2; // restore S this.B = this.A; // restore B (note that BROF is still relevant) this.AROF = 0; // invalidate A @@ -3437,7 +3545,7 @@ B5500Processor.prototype.run = function run() { } for (variant=3; variant>0; variant--) { this.B = (this.B % 0x40000000000)*0x40 + - (this.Y = this.cc.fieldIsolate(this.A, this.G*6, 6)); + (this.Y = cc.fieldIsolate(this.A, this.G*6, 6)); if (this.G < 7) { this.G++; } else { @@ -3457,25 +3565,25 @@ B5500Processor.prototype.run = function run() { break; case 0x30: // XX60: CEQ=Compare equal - this.compareSourceWithDest(variant); + this.compareSourceWithDest(variant, false); this.H = this.V = 0; this.MSFF = (this.Q & 0x04 ? 0 : 1); // if !Q03F, S=D break; case 0x31: // XX61: CNE=Compare not equal - this.compareSourceWithDest(variant); + this.compareSourceWithDest(variant, false); this.H = this.V = 0; this.MSFF = (this.Q & 0x04 ? 1 : 0); // if Q03F, S!=D break; case 0x32: // XX62: CEG=Compare greater or equal - this.compareSourceWithDest(variant); + this.compareSourceWithDest(variant, false); this.H = this.V = 0; this.MSFF = (this.Q & 0x04 ? this.MSFF : 1); // if Q03F&MSFF, S>D; if !Q03F, S=D break; case 0x33: // XX63: CGR=Compare greater - this.compareSourceWithDest(variant); + this.compareSourceWithDest(variant, false); this.H = this.V = 0; this.MSFF = (this.Q & 0x04 ? this.MSFF : 0); // if Q03F&MSFF, S>D break; @@ -3497,13 +3605,13 @@ B5500Processor.prototype.run = function run() { break; case 0x38: // XX70: CEL=Compare equal or less - this.compareSourceWithDest(variant); + this.compareSourceWithDest(variant, false); this.H = this.V = 0; this.MSFF = (this.Q & 0x04 ? 1-this.MSFF : 1); // if Q03F&!MSFF, S>> 4); - }); + this.streamNumericToDest(variant, true); break; case 0x3F: // XX77: TRS=Transfer source characters - this.streamSourceToDest(variant, function TRS(bb, c, count) { - this.B = this.cc.fieldInsert(this.B, bb, 6, c); - }); + this.streamCharacterToDest(variant); break; default: // everything else is a no-op @@ -3644,7 +3742,7 @@ B5500Processor.prototype.run = function run() { } break; - case 0x09: // XX11: control state and communication ops + case 0x09: // XX11: Control State and communication ops switch (variant) { case 0x01: // 0111: PRL=Program Release this.adjustAFull(); @@ -3666,12 +3764,12 @@ B5500Processor.prototype.run = function run() { } else { this.I = (this.I & 0x0F) | 0x60; // set I07/6: continuity bit } - this.cc.signalInterrupt(); + cc.signalInterrupt(); this.A = this.M; this.M = this.R*64 + 9; // store IOD address in PRT[9] this.storeAviaM(); } else { - this.A = this.cc.bitReset(this.A, 2); + this.A = cc.bitReset(this.A, 2); this.storeAviaM(); } this.AROF = 0; @@ -3679,11 +3777,11 @@ B5500Processor.prototype.run = function run() { break; case 0x02: // 0211: ITI=Interrogate Interrupt - if (this.cc.IAR && !this.NCSF) { // control-state only - this.C = this.cc.IAR; + if (cc.IAR && !this.NCSF) { // control-state only + this.C = cc.IAR; this.L = 0; this.S = 0x40; // stack address @100 - this.cc.clearInterrupt(); + cc.clearInterrupt(); this.PROF = 0; // require fetch at SECL } break; @@ -3691,29 +3789,32 @@ B5500Processor.prototype.run = function run() { case 0x04: // 0411: RTR=Read Timer if (!this.NCSF) { // control-state only this.adjustAEmpty(); - this.A = this.cc.readTimer(); + this.A = cc.readTimer(); this.AROF = 1; } break; case 0x08: // 1011: COM=Communicate - if (this.NCSF) { // no-op in control state + if (this.NCSF) { // no-op in Control State this.M = this.R*64 + 9; // address = R+@11 if (this.AROF) { this.storeAviaM(); // [M] = A this.AROF = 0; + } else if (this.BROF) { + this.storeBviaM(); // [M] = B + this.BROF = 0; } else { this.adjustBFull(); this.storeBviaM(); // [M] = B this.BROF = 0; } this.I = (this.I & 0x0F) | 0x40; // set I07: communicate - this.cc.signalInterrupt(); + cc.signalInterrupt(); } break; case 0x11: // 2111: IOR=I/O Release - if (!this.NCSF) { // no-op in normal state + if (!this.NCSF) { // no-op in Normal State this.adjustAFull(); t1 = this.A; if (t1 < 0x800000000000) { // it's an operand @@ -3728,7 +3829,7 @@ B5500Processor.prototype.run = function run() { } if (t2) { this.loadAviaM(); - this.A = this.cc.bitSet(this.A, 2); + this.A = cc.bitSet(this.A, 2); this.storeAviaM(); this.AROF = 0; } @@ -3736,8 +3837,9 @@ B5500Processor.prototype.run = function run() { break; case 0x12: // 2211: HP2=Halt Processor 2 - if (!(this.NCSF || this.cc.HP2F)) { // control-state only - this.cc.haltP2(); + if (!(this.NCSF || cc.HP2F)) { // control-state only + cc.haltP2(); + this.cycleLimit = 0; // give P2 a chance to stop } break; @@ -3775,7 +3877,7 @@ B5500Processor.prototype.run = function run() { this.storeAviaM(); // [M] = A this.AROF = 0; } - this.cc.initiateP2(); + cc.initiateP2(); this.cycleLimit = 0; // give P2 a chance to run } break; @@ -3794,7 +3896,7 @@ B5500Processor.prototype.run = function run() { this.storeAviaM(); // [M] = A this.AROF = 0; } - this.cc.initiateIO(); // let CentralControl choose the I/O Unit + cc.initiateIO(); // let CentralControl choose the I/O Unit this.cycleLimit = 0; // give the I/O a chance to start } break; @@ -4109,7 +4211,7 @@ B5500Processor.prototype.run = function run() { case 0x14: // 2431: TUS=interrogate peripheral status this.adjustAEmpty(); - this.A = this.cc.interrogateUnitStatus(); + this.A = cc.interrogateUnitStatus(); this.AROF = 1; break; @@ -4194,7 +4296,7 @@ B5500Processor.prototype.run = function run() { case 0x34: // 6431: TIO=interrogate I/O channel this.adjustAEmpty(); - this.A = this.cc.interrogateIOChannel(); + this.A = cc.interrogateIOChannel(); this.AROF = 1; break; @@ -4379,11 +4481,11 @@ B5500Processor.prototype.run = function run() { t1 = this.G*6 + this.H; // starting source bit position t2 = t2*6 - (variant & 7) - this.H; // number of bits if (t1+t2 <= 48) { - this.A = this.cc.fieldIsolate(this.A, t1, t2); + this.A = cc.fieldIsolate(this.A, t1, t2); } else { // handle wrap-around in the source value - this.A = this.cc.fieldInsert( - this.cc.fieldIsolate(this.A, 0, t2-48+t1, t1+t2-48), 48-t2, 48-t1, - this.cc.fieldIsolate(this.A, t1, 48-t1)); + this.A = cc.fieldInsert( + cc.fieldIsolate(this.A, 0, t2-48+t1, t1+t2-48), 48-t2, 48-t1, + cc.fieldIsolate(this.A, t1, 48-t1)); } // approximate the shift cycle counts this.cycleCount += (variant >>> 3) + (variant & 7) + this.G + this.H; @@ -4404,7 +4506,7 @@ B5500Processor.prototype.run = function run() { } else { this.adjustABFull(); t2 = variant >>> 2; // field length (1-15 bits) - t1 = this.cc.fieldIsolate(this.B, this.G*6+this.H, t2); + t1 = cc.fieldIsolate(this.B, this.G*6+this.H, t2); this.cycleCount += this.G + this.H + (t2 >>> 1); // approximate the shift counts this.AROF = 0; // A is unconditionally empty at end @@ -4481,7 +4583,7 @@ B5500Processor.prototype.run = function run() { if (t2+variant > 48) { variant = 48-t2; } - this.B = this.cc.fieldTransfer(this.B, t2, variant, this.A, t1); + this.B = cc.fieldTransfer(this.B, t2, variant, this.A, t1); } this.AROF = 0; this.cycleCount += variant + this.G + this.K; // approximate the shift counts @@ -4499,7 +4601,7 @@ B5500Processor.prototype.run = function run() { } if (variant == 0) { this.A = 1; - } else if (this.cc.fieldIsolate(this.B, t2, variant) < this.cc.fieldIsolate(this.A, t1, variant)) { + } else if (cc.fieldIsolate(this.B, t2, variant) < cc.fieldIsolate(this.A, t1, variant)) { this.A = 1; } else { this.A = 0; @@ -4519,7 +4621,7 @@ B5500Processor.prototype.run = function run() { } if (variant == 0) { this.A = 1; - } else if (this.cc.fieldIsolate(this.B, t2, variant) == this.cc.fieldIsolate(this.A, t1, variant)) { + } else if (cc.fieldIsolate(this.B, t2, variant) == cc.fieldIsolate(this.A, t1, variant)) { this.A = 1; } else { this.A = 0; @@ -4538,10 +4640,10 @@ B5500Processor.prototype.run = function run() { * SECL: Syllable Execution Complete Level * ***************************************************************/ - if ((this.isP1 ? this.cc.IAR : this.I) && this.NCSF) { - // there's an interrupt and we're in normal state + if ((this.isP1 ? cc.IAR : (this.I || cc.HP2F)) && this.NCSF) { + // there's an interrupt and we're in Normal State // reset Q09F (R-relative adder mode) and set Q07F (hardware-induced SFI) (for display only) - this.Q = (this.Q & 0xFFFEFF) & 0x40; + this.Q = (this.Q & 0xFFFEFF) | 0x40; this.T = 0x0609; // inject 3011=SFI into T this.storeForInterrupt(1, 0); // call directly to avoid resetting registers at top of loop } else { @@ -4571,7 +4673,7 @@ B5500Processor.prototype.run = function run() { } } - // Accumulate Normal and Control State cycles for use by the Console in + // Accumulate Normal and Control State cycles for use by Console in // making the pretty lights blink. If the processor is no longer busy, // accumulate the cycles as Normal State, as we probably just did SFI. if (this.NCSF || !this.busy) { @@ -4601,15 +4703,22 @@ B5500Processor.prototype.schedule = function schedule() { this.scheduler = null; delayTime = clockOff - this.delayLastStamp; this.procSlack += delayTime; - this.delayDeltaAvg = (this.delayDeltaAvg*(B5500Processor.delaySamples-1) + - delayTime - this.delayRequested)/B5500Processor.delaySamples; + + // Compute the exponential weighted average of scheduling delay + this.delayDeltaAvg = (1-B5500Processor.delayAlpha)*(delayTime - this.delayRequested) + + B5500Processor.delayAlpha*this.delayDeltaAvg; + this.procSlackAvg = (1-B5500Processor.slackAlpha)*delayTime + + B5500Processor.slackAlpha*this.procSlackAvg; if (this.busy) { this.cycleLimit = B5500Processor.timeSlice; this.run(); // execute syllables for the timeslice - this.delayLastStamp = clockOff = new Date().getTime(); + clockOff = new Date().getTime(); + this.procRunAvg = (1-B5500Processor.slackAlpha)*(clockOff - this.delayLastStamp) + + B5500Processor.slackAlpha*this.procRunAvg; + this.delayLastStamp = clockOff; this.totalCycles += this.runCycles; if (!this.busy) { this.delayRequested = 0; diff --git a/webUI/B5500ColdLoader.html b/webUI/B5500ColdLoader.html index ed75a8e..e70440b 100644 --- a/webUI/B5500ColdLoader.html +++ b/webUI/B5500ColdLoader.html @@ -1854,7 +1854,6 @@ window.addEventListener("load", function() { // Create a file entry for the system log createSystemLog(10000); - /** enterFile("SYSTEM", "LOG", 1, 20000); **/ // Store the directory labels segment eu.put(fileLabels, directoryTop + 19); // write the directory block file labels diff --git a/webUI/B5500Console.html b/webUI/B5500Console.html index 1ac561c..ab735a0 100644 --- a/webUI/B5500Console.html +++ b/webUI/B5500Console.html @@ -37,10 +37,13 @@ window.addEventListener("load", function() { var bNormal; var boundBlinkenlicht; var cc = new B5500CentralControl(this); + var ccLatches = [0, 0, 0]; + var ccLightsMap = new Array(6); + var elapsedAverage = 0; + var elapsedLast = 0; var intLightsMap = new Array(48); - var iouLightsMap = new Array(4); var lastInterruptMask = 0; - var lastIOUMask = 0; + var lastCCMask = 0; var lastUnitBusyMask = 0; var lastPANormalRate = -1; var lastPAControlRate = -1; @@ -50,6 +53,9 @@ window.addEventListener("load", function() { var procDelay; var procSlack; var showAnnunciators = true; + var slackAlpha = 0.990; // decay factor for exponential weighted avg. + var slackAverage = 0; // average P1 slack time + var slackLast = 0; // last P1 total slack time var timer; var timerInterval = 50; // milliseconds @@ -78,7 +84,6 @@ window.addEventListener("load", function() { $$("LoadSelectBtn").disabled = false; $$("LoadBtn").disabled = false; $$("HaltBtn").disabled = true; - boundBlinkenlicht(); window.focus(); if (showAnnunciators) { $$("CentralControl").style.visibility = "visible"; @@ -115,17 +120,25 @@ window.addEventListener("load", function() { cc.halt(); $$("HaltBtn").disabled = true; $$("LoadBtn").disabled = false; + if (timer) { + clearTimeout(timer); + timer = null; + } } function LoadBtn_Click(ev) { var result; + window.open("", "SPO").focus(); // re-focus the SPO window result = cc.load(false); switch (result) { case 0: // load initiated successfully $$("HaltBtn").className = "redButton"; $$("HaltBtn").disabled = false; $$("LoadBtn").disabled = true; + elapsedLast = 0; + slackLast = slackAverage = 0; + boundBlinkenlicht(); break; case 1: alert("P1 busy or not available"); @@ -189,41 +202,42 @@ window.addEventListener("load", function() { } function displayCentralControl() { - /* Displays the I/O and interrupt status in Central Control */ + /* Displays the I/O and interrupt status in CentralControl */ var cells; var s; - var interruptMask = cc.fetchInterruptLatch() % 0x4000; - var interruptChange = lastInterruptMask ^ interruptMask; - var iouMask = cc.fetchIOUnitLatch(); - var iouChange = lastIOUMask ^ iouMask; - var unitBusyMask = cc.fetchUnitBusyLatch(); - var unitBusyChange = lastUnitBusyMask ^ unitBusyMask; + var interruptMask; + var interruptChange; + var ccMask; + var ccChange; + var unitBusyMask; + var unitBusyChange; var x; + cc.fetchCCLatches(ccLatches); + ccMask = ccLatches[0]; + ccChange = lastCCMask ^ ccMask; + lastCCMask = ccMask; + + interruptMask = ccLatches[1] % 0x4000; + interruptChange = lastInterruptMask ^ interruptMask; lastInterruptMask = interruptMask; - lastIOUMask = iouMask; + + unitBusyMask = ccLatches[2]; + unitBusyChange = lastUnitBusyMask ^ unitBusyMask; lastUnitBusyMask = unitBusyMask; - $$("AD1F").className = (cc.AD1F ? "busy" : ""); - $$("AD2F").className = (cc.AD2F ? "busy" : ""); - $$("AD3F").className = (cc.AD3F ? "busy" : ""); - $$("AD4F").className = (cc.AD4F ? "busy" : ""); - /********** for P2 debugging ********** - $$("P2BF").className = (cc.P2BF ? "busy" : ""); - $$("HP2F").className = (cc.HP2F ? "busy" : ""); - $$("PABZ").className = (cc.PA && cc.PA.busy ? "busy" : ""); $$("PBBZ").className = (cc.PB && cc.PB.busy ? "busy" : ""); **********/ x = 0; - while (iouChange) { - if (iouChange & 0x01) { - iouLightsMap[x].className = (iouMask & 0x01 ? "busy" : ""); + while (ccChange) { + if (ccChange & 0x01) { + ccLightsMap[x].className = (ccMask & 0x01 ? "busy" : ""); } - iouMask >>>= 1; - iouChange >>>= 1; + ccMask >>>= 1; + ccChange >>>= 1; x++; } @@ -296,7 +310,7 @@ window.addEventListener("load", function() { } } - stateRate = 6 - stateRate; + stateRate = Math.round(pa.controlCycles/cycles*6 + 0.49); if (stateRate != lastPAControlRate) { lastPAControlRate = stateRate; switch (stateRate) { @@ -364,7 +378,7 @@ window.addEventListener("load", function() { } } - stateRate = 6 - stateRate; + stateRate = Math.round(pb.controlCycles/cycles*6 + 0.49); if (stateRate != lastPBControlRate) { lastPBControlRate = stateRate; switch (stateRate) { @@ -400,8 +414,14 @@ window.addEventListener("load", function() { while (et < 0) { et += stamp; } + /************** + elapsedAverage = (et-elapsedLast)*(1-slackAlpha) + elapsedAverage*slackAlpha; + slackAverage = (p1.procSlack-slackLast)*(1-slackAlpha) + slackAverage*slackAlpha; + elapsedLast = et; + slackLast = p1.procSlack; + **************/ procDelay.innerHTML = p1.delayDeltaAvg.toFixed(1); - procSlack.innerHTML = (p1.procSlack/et*100).toFixed(1) + "%"; + procSlack.innerHTML = (p1.procSlackAvg/p1.procRunAvg*100).toFixed(1) + "%"; if (showAnnunciators) { displayCentralControl(); @@ -415,10 +435,12 @@ window.addEventListener("load", function() { var spec; var x; - iouLightsMap[0] = $$("AD1F"); - iouLightsMap[1] = $$("AD2F"); - iouLightsMap[2] = $$("AD3F"); - iouLightsMap[3] = $$("AD4F"); + ccLightsMap[0] = $$("AD1F"); + ccLightsMap[1] = $$("AD2F"); + ccLightsMap[2] = $$("AD3F"); + ccLightsMap[3] = $$("AD4F"); + ccLightsMap[4] = $$("P2BF"); + ccLightsMap[5] = $$("HP2F"); for (x=3; x<=16; x++) { intLightsMap[50-x] = $$("CCI" + (x+100).toString().substring(1) + "F"); @@ -463,6 +485,12 @@ window.addEventListener("load", function() { $$("LoadBtn").addEventListener("click", LoadBtn_Click, false); $$("LoadSelectBtn").addEventListener("click", LoadSelectBtn_Click, false); + // A kludge, for sure + $$("NotReadyBtn").addEventListener("click", function(ev) { + B5500SystemConfiguration.PB ^= true; + $$("RetroVersion").style.color = (B5500SystemConfiguration.PB ? "yellow" : "white"); + }); + aControl = $$("AControlBtn"); aNormal = $$("ANormalBtn"); bControl = $$("BControlBtn"); @@ -531,11 +559,11 @@ window.addEventListener("load", function() { SPEC DK1F DK2F + P2BF HP2F PABZ PBBZ - P1 Slack diff --git a/webUI/B5500MagTapeDrive.js b/webUI/B5500MagTapeDrive.js index f09c12c..34808c4 100644 --- a/webUI/B5500MagTapeDrive.js +++ b/webUI/B5500MagTapeDrive.js @@ -21,7 +21,7 @@ function B5500MagTapeDrive(mnemonic, unitIndex, designate, statusChange, signal) { /* Constructor for the MagTapeDrive object */ var that = this; - var x = (mnemonic == "MTA" ? 30 : 60); + var x = ((mnemonic.charCodeAt(2) - "A".charCodeAt(0) + 1)*30); this.mnemonic = mnemonic; // Unit mnemonic this.unitIndex = unitIndex; // Ready-mask bit number @@ -127,7 +127,7 @@ B5500MagTapeDrive.prototype.clear = function clear() { this.angle = 0; // current rotation angle of reel image [degrees] this.tapeInches = 0; // number of inches up-tape this.writeRing = false; // true if write ring is present and tape is writable - this.atBOT = false; // true if tape at BOT + this.atBOT = true; // true if tape at BOT this.atEOT = false; // true if tape at EOT this.buffer = null; // IOUnit buffer @@ -168,7 +168,8 @@ B5500MagTapeDrive.prototype.removeClass = function removeClass(e, name) { /**************************************/ B5500MagTapeDrive.prototype.spinReel = function spinReel(inches) { /* Rotates the reel image icon an appropriate amount based on the number of - inches of tape movement */ + inches of tape movement. The rotation is limited to 33 degrees in either + direction so that movement remains apparent to the viewer */ var circumference = this.reelCircumference*(1 - this.tapeInches/this.maxTapeLength/2); var angle = inches/circumference*360; @@ -192,6 +193,7 @@ B5500MagTapeDrive.prototype.setAtBOT = function setAtBOT(atBOT) { this.imgIndex = 0; this.tapeInches = 0; this.addClass(this.$$("MTAtBOTLight"), "whiteLit"); + this.progressBar.value = this.imgLength; this.reelIcon.style.transform = "rotate(0deg)"; } else { this.removeClass(this.$$("MTAtBOTLight"), "whiteLit"); @@ -208,6 +210,7 @@ B5500MagTapeDrive.prototype.setAtEOT = function setAtEOT(atEOT) { if (atEOT) { this.imgIndex = this.imgLength; this.addClass(this.$$("MTAtEOTLight"), "whiteLit"); + this.progressBar.value = 0; } else { this.removeClass(this.$$("MTAtEOTLight"), "whiteLit"); } @@ -237,10 +240,14 @@ B5500MagTapeDrive.prototype.setTapeUnloaded = function setTapeUnloaded() { this.addClass(this.$$("MTLocalBtn"), "yellowLit"); this.removeClass(this.$$("MTWriteRingBtn"), "redLit"); this.addClass(this.$$("MTUnloadedLight"), "whiteLit"); - this.progressBar.value = 0; this.setAtBOT(false); this.setAtEOT(false); + this.progressBar.value = 0; this.reelIcon.style.visibility = "hidden"; + if (this.timer) { + clearCallback(this.timer); + this.timer = null; + } } }; @@ -267,6 +274,10 @@ B5500MagTapeDrive.prototype.setTapeRemote = function setTapeRemote(ready) { this.statusChange(0); this.removeClass(this.$$("MTRemoteBtn"), "yellowLit"); this.addClass(this.$$("MTLocalBtn"), "yellowLit"); + if (this.timer) { + clearCallback(this.timer); + this.timer = null; + } } } }; @@ -297,19 +308,29 @@ B5500MagTapeDrive.prototype.setWriteRing = function setWriteRing(writeRing) { /**************************************/ B5500MagTapeDrive.prototype.tapeRewind = function tapeRewind(makeReady) { /* Rewinds the tape. Makes the drive not-ready and delays for an appropriate amount - of time depending on how far up-tape we are. If makeReady is true, then readies - the unit again when the rewind is complete [valid only when called from - this.rewind()] */ + of time depending on how far up-tape we are. If makeReady is true [valid only when + called from this.rewind()], then readies the unit again when the rewind is complete */ var inches; var inchFactor = this.imgIndex/this.tapeInches; var lastStamp = new Date().getTime(); + var updateInterval = 30; // ms + + function rewindFinish() { + this.timer = null; + this.busy = false; + this.removeClass(this.$$("MTRewindingLight"), "whiteLit"); + if (makeReady) { + this.ready = true; + this.statusChange(1); + } + } function rewindDelay() { var stamp = new Date().getTime(); var interval = stamp - lastStamp; if (interval <= 0) { - interval = 1; + interval = updateInterval/2; } if (this.tapeInches > 0) { inches = interval/1000*this.rewindSpeed; @@ -317,27 +338,25 @@ B5500MagTapeDrive.prototype.tapeRewind = function tapeRewind(makeReady) { this.spinReel(-inches); this.progressBar.value = this.imgLength - this.tapeInches*inchFactor; lastStamp = stamp; - this.timer = setCallback(rewindDelay, this, 30); + this.timer = setCallback(rewindDelay, this, updateInterval); } else { - this.busy = false; + this.spinReel(6); this.setAtBOT(true); - this.progressBar.value = this.imgLength; - this.removeClass(this.$$("MTRewindingLight"), "whiteLit"); - if (makeReady) { - this.ready = true; - this.statusChange(1); - } + this.timer = setCallback(rewindFinish, this, 2000); } } - if (this.tapeState != this.tapeUnloaded) { + if (this.timer) { + clearCallback(this.timer); + this.timer = null; + } + if (this.tapeState != this.tapeUnloaded && !this.atBOT) { this.busy = true; this.ready = false; this.statusChange(0); this.setAtEOT(false); this.addClass(this.$$("MTRewindingLight"), "whiteLit"); - this.timer = setCallback(rewindDelay, this, - this.startStopTime*1000 + this.initiateStamp - lastStamp); + this.timer = setCallback(rewindDelay, this, 1000); } }; @@ -399,12 +418,11 @@ B5500MagTapeDrive.prototype.fileSelector_onChange = function fileSelector_onChan that.image = new Uint8Array(ev.target.result); that.imgIndex = 0; that.imgLength = that.image.length; - that.progressBar.value = that.imgLength; that.progressBar.max = that.imgLength; that.removeClass(that.$$("MTUnloadedLight"), "whiteLit"); that.tapeState = that.tapeLocal;// setTapeRemote() requires it not to be unloaded - that.setAtBOT(true); that.setAtEOT(false); + that.setAtBOT(true); that.setTapeRemote(false); that.setWriteRing(false); // read-only for now... that.reelIcon.style.visibility = "visible"; @@ -446,7 +464,9 @@ B5500MagTapeDrive.prototype.bcdSpaceForward = function bcdSpaceForward(checkEOF) var imgLength = this.imgLength; // tape image length var imgIndex = this.imgIndex; // current tape image offset - if (imgIndex < imgLength) { + if (imgIndex >= imgLength) { + this.errorMask |= 0x10; // report parity error if beyond end of tape + } else { if (this.atBOT) { this.setAtBOT(false); } @@ -520,9 +540,6 @@ B5500MagTapeDrive.prototype.bcdSpaceBackward = function bcdSpaceBackward(checkEO } } while (c < 0x80); } - if (imgIndex <= 0) { - this.setAtBOT(true); - } } this.imgIndex = imgIndex; }; @@ -550,7 +567,9 @@ B5500MagTapeDrive.prototype.bcdReadForward = function bcdReadForward(oddParity) var imgIndex = this.imgIndex; // current tape image offset var xlate = (oddParity ? this.bcdXlateInOdd : this.bcdXlateInEven); - if (imgIndex < imgLength) { + if (imgIndex >= imgLength) { + this.errorMask |= 0x10; // report parity error if beyond end of tape + } else { if (this.atBOT) { this.setAtBOT(false); } @@ -681,9 +700,6 @@ B5500MagTapeDrive.prototype.bcdReadBackward = function bcdReadBackward(oddParity } } while (true); } - if (imgIndex <= 0) { - this.setAtBOT(true); - } } this.imgIndex = imgIndex; this.bufIndex = bufIndex; @@ -713,7 +729,8 @@ B5500MagTapeDrive.prototype.tapeDriveOnLoad = function tapeDriveOnLoad() { this.window.addEventListener("beforeunload", this.beforeUnload, false); - this.tapeState = this.tapeLocal; // setTapeUnloaded() requires it not to be unloaded + this.tapeState = this.tapeLocal; // setTapeUnloaded() requires it to be in local + this.atBOT = true; // and also at BOT this.setTapeUnloaded(); this.$$("MTUnloadBtn").addEventListener("click", function startClick(ev) { @@ -849,7 +866,7 @@ B5500MagTapeDrive.prototype.space = function space(finish, length, control) { this.progressBar.value = 0; } } - //console.log(this.mnemonic + " space: c=" + control + ", length=" + length + + //console.log(this.mnemonic + " space: c=" + control + ", length=" + length + // ", count=" + imgCount + ", inches=" + this.tapeInches + // ", index=" + this.imgIndex + ", mask=" + this.errorMask.toString(8)); }; diff --git a/tools/Pow2.html b/webUI/prototypes/Pow2.html similarity index 100% rename from tools/Pow2.html rename to webUI/prototypes/Pow2.html diff --git a/tools/Register-CrockfordStyle.js b/webUI/prototypes/Register-CrockfordStyle.js similarity index 100% rename from tools/Register-CrockfordStyle.js rename to webUI/prototypes/Register-CrockfordStyle.js diff --git a/tools/Register.js b/webUI/prototypes/Register.js similarity index 100% rename from tools/Register.js rename to webUI/prototypes/Register.js diff --git a/tools/RegisterTest.html b/webUI/prototypes/RegisterTest.html similarity index 100% rename from tools/RegisterTest.html rename to webUI/prototypes/RegisterTest.html diff --git a/tools/webkitFileSystemTest.html b/webUI/prototypes/webkitFileSystemTest.html similarity index 100% rename from tools/webkitFileSystemTest.html rename to webUI/prototypes/webkitFileSystemTest.html