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