1
0
mirror of https://github.com/pkimpel/retro-220.git synced 2026-04-14 07:49:53 +00:00

Commit retro-220 version 0.02:

1. Finish implementation of Cardatron input and output units.
2. Minor corrections to BAC-Assembler script and BALGOL-Generator transcription.
3. Apply band-select "punches" in column 1 of WINTER.PI.card assembler deck.
4. Implement striping on Console register displays to highlight the opcode (62) fields.
5. Implement List-Cards utility to read cards from CR1 and list them on LP2.
This commit is contained in:
Paul Kimpel
2017-05-24 09:09:08 -07:00
parent 33c195ae84
commit 8b6199afd8
13 changed files with 471 additions and 310 deletions

View File

@@ -260,7 +260,7 @@ function B220Processor(config, devices) {
* Global Constants *
***********************************************************************/
B220Processor.version = "0.01a";
B220Processor.version = "0.02";
B220Processor.tick = 1000/200000; // milliseconds per clock cycle (200KHz)
B220Processor.cyclesPerMilli = 1/B220Processor.tick;
@@ -2672,6 +2672,7 @@ B220Processor.prototype.cardatronOutputWord = function cardatronOutputWord() {
} else if (this.MET.value) { // previous memory access error
word = 0;
} else {
this.opTime += 0.117; // time for full-word transfer
word = this.readMemory(); // address in E was previously set
if (this.MET.value) {
word = 0;
@@ -2715,6 +2716,7 @@ B220Processor.prototype.cardatronReceiveWord = function cardatronReceiveWord(wor
// Memory error has occurred: just ignore further data from Cardatron
} else {
// Full word accumulated -- process it and initialize for the next word
this.opTime += 0.117; // time for full-word transfer
this.D.set(word);
word %= 0x10000000000; // strip the sign digit
sign = (this.D.value - word)/0x10000000000; // get D-sign
@@ -3642,13 +3644,28 @@ B220Processor.prototype.execute = function execute() {
break;
case 0x61: //--------------------- CWR Card write
this.setProgramCheck(1);
this.operationComplete();
this.opTime = 1.600; // rough minimum estimage
this.E.set(this.CADDR);
this.D.set(0);
if (!this.cardatron) {
this.setCardatronCheck(1);
this.operationComplete();
} else {
this.selectedUnit = (this.CCONTROL >>> 12) & 0x0F;
this.rDigit = this.CCONTROL & 0x0F;
this.vDigit = (this.CCONTROL >>> 4) & 0x0F;
this.ioInitiate();
d = this.cardatron.outputInitiate(this.selectedUnit, this.rDigit, this.vDigit,
this.boundCardatronOutputWord, this.boundCardatronOutputFinished);
if (d < 0) { // invalid unit
this.setCardatronCheck(1);
this.ioComplete(true);
}
}
break;
case 0x62: //--------------------- CRF Card read, format load
this.setProgramCheck(1);
this.opTime = 2.940; // rough minimum estimage
this.opTime = 1.600; // rough minimum estimage
this.E.set(this.CADDR);
this.D.set(0);
if (!this.cardatron) {
@@ -3665,12 +3682,26 @@ B220Processor.prototype.execute = function execute() {
this.ioComplete(true);
}
}
this.operationComplete();
break;
case 0x63: //--------------------- CWF Card write, format load
this.setProgramCheck(1);
this.operationComplete();
this.opTime = 1.600; // rough minimum estimage
this.E.set(this.CADDR);
this.D.set(0);
if (!this.cardatron) {
this.setCardatronCheck(1);
this.operationComplete();
} else {
this.selectedUnit = (this.CCONTROL >>> 12) & 0x0F;
this.rDigit = this.CCONTROL & 0x0F;
this.ioInitiate();
d = this.cardatron.outputFormatInitiate(this.selectedUnit, this.rDigit,
this.boundCardatronOutputWord, this.boundCardatronOutputFinished);
if (d < 0) { // invalid unit
this.setCardatronCheck(1);
this.ioComplete(true);
}
}
break;
case 0x64: //--------------------- CRI Card read interrogate, branch
@@ -3680,7 +3711,6 @@ B220Processor.prototype.execute = function execute() {
if (!this.cardatron) {
this.setCardatronCheck(1);
} else {
this.E.set(this.CADDR);
this.selectedUnit = (this.CCONTROL >>> 12) & 0x0F;
d = this.cardatron.inputReadyInterrogate(this.selectedUnit);
if (d < 0) { // invalid unit
@@ -3694,7 +3724,21 @@ B220Processor.prototype.execute = function execute() {
break;
case 0x65: //--------------------- CWI Card write interrogate, branch
this.setProgramCheck(1);
this.opTime = 0.265; // average
this.E.set(this.CADDR);
this.D.set(0);
if (!this.cardatron) {
this.setCardatronCheck(1);
} else {
this.selectedUnit = (this.CCONTROL >>> 12) & 0x0F;
d = this.cardatron.outputReadyInterrogate(this.selectedUnit);
if (d < 0) { // invalid unit
this.setCardatronCheck(1);
} else if (d > 0) {
this.opTime += 0.020;
this.P.set(this.CADDR);
}
}
this.operationComplete();
break;
@@ -3835,11 +3879,11 @@ B220Processor.prototype.operationComplete = function operationComplete() {
/* Implements Operation Complete for the Execute cycle. If we're not locked
in Execute, switch to Fetch cycle next */
this.execClock += this.opTime;
if (this.FETCHEXECUTELOCKSW != 1) {
this.EXT.set(0); // set to FETCH state
}
this.execClock += this.opTime;
if (this.ORDERCOMPLEMENTSW) {
this.C.flipBit(16); // complement low order bit of op code
this.COP ^= 0x01;

View File

@@ -1455,7 +1455,7 @@ SEQ PLAC ADDR WORD LABEL OPCODE OPERAND ' IS A 4
1412 1826 0 0000 00 0000 RR3 (0)
1413 1827 0 1000 00 0000 SCRATCHML (1)(11)
1414 SCRATCHDUMP
1415 1828 0 1010 00 0000 (101)(33)
1415 1828 0 1010 00 0000 (101)(33)
1416
1417
1418 1829 0 0000 00 0000 SYMBOL FILL 0,10

View File

@@ -0,0 +1,13 @@
777 LIST CARDS FROM READER 1 TO LINE PRINTER 2 USING FORMAT 5
666 61000600905
66661000600946010006209690200863099901000600939020086109390100064090200000300904
66661000600952333333333333333333333333333333333333333333333333333333333333333333
66661000600958333333333333333333333333333333333333333333333333333333300000000000
66661000600964000000000002111111111121111111111211111111112111111111121111111111
66661000600969211111111112111111111121111111111211111111112111111111121111111111
666 610006009762111111111121111111111211111111112111111111121111111111
66661000600982333333333333333333333333333333333333333333333333333333333333333000
66661000600988000000000000031111111111311111111113111111111131111111111311111111
66661000600994113111111111131111111111311111111113111111111131111111111311111111
66661001600999113111111111131111111111311111111113111111111131111111111000000000
666 600003009000000000000000000000000000000000000000000000000000000000

View File

@@ -0,0 +1,15 @@
1 REM LIST CARDS FROM CR1 TO LP2 USING FORMAT BAND 5
1 LOCN 0900
1 CRF FR1+28,11 LOAD READER FORMAT 1
1 CWF FW5+28,52 LOAD PRINTER FORMAT 5
1 L1 CRD BUF+28,1 READ A CARD
1 CWR BUF+28,2,5 PRINT A CARD
1 L2 CRI L1,1 LOOP BACK IF READER READY
1 BUN L2 SPIN UNTIL READER IS READY
1 REM
1 BUF DEFN 0911 CARD BUFFER (USES 0922-0939)
1 LOCN 0941
1 FR1 FBGR INPUT,P10Z,16(T5A)
1 LOCN 0971
1 FW5 FBGR PRINT,8B,16(T5A),32B
1 FINI 900

View File

@@ -0,0 +1,84 @@
Assembler for the Burroughs 220 BALGOL Compiler & Intrinsics
END OF PASS 1, ERRORS = 0
SYMBOL TABLE
1 BMOD 911 BUF 941 FR1 971 FW5 902 L1
904 L2 1 RLO
LIST CARDS FROM CR1 TO LP2 USING FORMAT BAND 5
2 0000 LOCN 0900
3 0900 0 1000 62 0969 CRF FR1+28,11 LOAD READER FORMAT 1
4 0901 0 2008 63 0999 CWF FW5+28,52 LOAD PRINTER FORMAT 5
5 0902 0 1000 60 0939 L1 CRD BUF+28,1 READ A CARD
6 0903 0 2008 61 0939 CWR BUF+28,2,5 PRINT A CARD
7 0904 0 1000 64 0902 L2 CRI L1,1 LOOP BACK IF READER READY
8 0905 0 0000 30 0904 BUN L2 SPIN UNTIL READER IS READY
10 0906 BUF DEFN 0911 CARD BUFFER (USES 0922-0939)
11 0906 LOCN 0941
12 0941 3 3333 33 3333 FR1 FBGR INPUT,P10Z,16(T5A)
0942 3 3333 33 3333
0943 3 3333 33 3333
0944 3 3333 33 3333
0945 3 3333 33 3333
0946 3 3333 33 3333
0947 3 3333 33 3333
0948 3 3333 33 3333
0949 3 3333 33 3333
0950 3 3333 33 3333
0951 3 3333 33 3333
0952 0 0000 00 0000
0953 0 0000 00 0000
0954 2 1111 11 1111
0955 2 1111 11 1111
0956 2 1111 11 1111
0957 2 1111 11 1111
0958 2 1111 11 1111
0959 2 1111 11 1111
0960 2 1111 11 1111
0961 2 1111 11 1111
0962 2 1111 11 1111
0963 2 1111 11 1111
0964 2 1111 11 1111
0965 2 1111 11 1111
0966 2 1111 11 1111
0967 2 1111 11 1111
0968 2 1111 11 1111
0969 2 1111 11 1111
13 0970 LOCN 0971
14 0971 3 3333 33 3333 FW5 FBGR PRINT,8B,16(T5A),32B
0972 3 3333 33 3333
0973 3 3333 33 3333
0974 3 3333 33 3333
0975 3 3333 33 3333
0976 3 3333 33 3000
0977 0 0000 00 0000
0978 0 0311 11 1111
0979 1 1311 11 1111
0980 1 1311 11 1111
0981 1 1311 11 1111
0982 1 1311 11 1111
0983 1 1311 11 1111
0984 1 1311 11 1111
0985 1 1311 11 1111
0986 1 1311 11 1111
0987 1 1311 11 1111
0988 1 1311 11 1111
0989 1 1311 11 1111
0990 1 1311 11 1111
0991 1 1311 11 1111
0992 1 1311 11 1111
0993 1 1311 11 1111
0994 1 1000 00 0000
0995 0 0000 00 0000
0996 0 0000 00 0000
0997 0 0000 00 0000
0998 0 0000 00 0000
0999 0 0000 00 0000
15 1000 FINI 900
END OF PASS 2, ERRORS = 0

View File

@@ -1,93 +1,93 @@
1 REM PRINT FIRST 800 DIGITS OF PI
1 REM ADAPTED FROM C PROGRAM B DIK WINTER OF CWI, AMSTERDAM
LOCN 0300
CAD FLIM
STA C C=FLIM
CAD A
SRT 10
DIV FIVE A DIV 5
LDB C FOR (B=C; B>=0; --B)
STA - F F[B]=A DIV 5
DBB *-1,1
REM
L1 CAD C START OF OUTER LOOP
MUL TWO
STR G G=C*2
BFR ENDL1,00,00 IF G EQL 0, BRANCH OUT OF LOOP
CLL D D=0
CAD C
STA B B=C
LDB B
REM
DO CAD - F START OF INNER LOOP
MUL A F[B]*A
SLT 10 SHIFT PRODUCT TO RA
ADD D
STA D D+=F[B]*A
SRT 10 SAVE NEW D IN RR
DFL G,00,1 G-=1
DIV G D DIV G
STR - F F[B]=D MOD G
STA D D=D DIV G
DFL G,00,1 G-=1
CAD B
SUB ONE
STA B B-=1
BFA ENDDO,00,00 IF B EQL 0, BRANCH OUT OF INNER LOOP
MUL D
STR D D*=B
DBB DO,1 DECREMENT RB, REPEAT INNER LOOP IF >= 0
REM
ENDDO DFL C,00,14 C-=14
CAD D
SRT 10
DIV A D DIV A
ADD E RA=E+D DIV A
STR E E=D MOD A
REM
REM FORMAT 4 DIGITS FOR SPO OUTPUT
SRT 3 ISOLATE HIGH-ORDER DIGIT IN A
ADD N80 CONVERT 1ST DIGIT TO ALPHA
SLA 1
SLT 1
ADD N80 CONVERT 2ND DIGIT TO ALPHA
SLA 1
SLT 1
ADD N80 CONVERT 3RD DIGIT TO ALPHA
SLA 1
SLT 1
ADD N80 CONVERT 4TH DIGIT TO ALPHA
SLA 2 INSERT TRAILING SPACE
LSA 2 SET SIGN TO TWO FOR ALPHA WORD
STA B STORE IN WORD BUFFER
SPO B,1
IFL COL,04,5 CHECK FOR FULL LINE ON SPO
CAD COL
CFA ECOL
BCL L1 IF COL < ECOL, BRANCH
SPO CR,1 OUTPUT NEWLINES
CLL COL CLEAR COLUMN COUNTER
BUN L1
ENDL1 HLT 7557
REM
REM SCALARS
A CNST 10000
B CNST 0
C CNST 0
D CNST 0
E CNST 0
G CNST 0
COL CNST 0
ECOL CNST 50
FLIM CNST 2800
ZERO CNST 0
ONE CNST 1
TWO CNST 2
FIVE CNST 5
N80 CNST 80
CR CNST 20202021616 NEWLINES
REM
LOCN 1000
F DEFN *
LOCN *+2800
FINI 300
1 LOCN 0300
1 CAD FLIM
1 STA C C=FLIM
1 CAD A
1 SRT 10
1 DIV FIVE A DIV 5
1 LDB C FOR (B=C; B>=0; --B)
1 STA - F F[B]=A DIV 5
1 DBB *-1,1
1 REM
1 L1 CAD C START OF OUTER LOOP
1 MUL TWO
1 STR G G=C*2
1 BFR ENDL1,00,00 IF G EQL 0, BRANCH OUT OF LOOP
1 CLL D D=0
1 CAD C
1 STA B B=C
1 LDB B
1 REM
1 DO CAD - F START OF INNER LOOP
1 MUL A F[B]*A
1 SLT 10 SHIFT PRODUCT TO RA
1 ADD D
1 STA D D+=F[B]*A
1 SRT 10 SAVE NEW D IN RR
1 DFL G,00,1 G-=1
1 DIV G D DIV G
1 STR - F F[B]=D MOD G
1 STA D D=D DIV G
1 DFL G,00,1 G-=1
1 CAD B
1 SUB ONE
1 STA B B-=1
1 BFA ENDDO,00,00 IF B EQL 0, BRANCH OUT OF INNER LOOP
1 MUL D
1 STR D D*=B
1 DBB DO,1 DECREMENT RB, REPEAT INNER LOOP IF >= 0
1 REM
1 ENDDO DFL C,00,14 C-=14
1 CAD D
1 SRT 10
1 DIV A D DIV A
1 ADD E RA=E+D DIV A
1 STR E E=D MOD A
1 REM
1 REM FORMAT 4 DIGITS FOR SPO OUTPUT
1 SRT 3 ISOLATE HIGH-ORDER DIGIT IN A
1 ADD N80 CONVERT 1ST DIGIT TO ALPHA
1 SLA 1
1 SLT 1
1 ADD N80 CONVERT 2ND DIGIT TO ALPHA
1 SLA 1
1 SLT 1
1 ADD N80 CONVERT 3RD DIGIT TO ALPHA
1 SLA 1
1 SLT 1
1 ADD N80 CONVERT 4TH DIGIT TO ALPHA
1 SLA 2 INSERT TRAILING SPACE
1 LSA 2 SET SIGN TO TWO FOR ALPHA WORD
1 STA B STORE IN WORD BUFFER
1 SPO B,1
1 IFL COL,04,5 CHECK FOR FULL LINE ON SPO
1 CAD COL
1 CFA ECOL
1 BCL L1 IF COL < ECOL, BRANCH
1 SPO CR,1 OUTPUT NEWLINES
1 CLL COL CLEAR COLUMN COUNTER
1 BUN L1
1 ENDL1 HLT 7557
1 REM
1 REM SCALARS
1 A CNST 10000
1 B CNST 0
1 C CNST 0
1 D CNST 0
1 E CNST 0
1 G CNST 0
1 COL CNST 0
1 ECOL CNST 50
1 FLIM CNST 2800
1 ZERO CNST 0
1 ONE CNST 1
1 TWO CNST 2
1 FIVE CNST 5
1 N80 CNST 80
1 CR CNST 20202021616 NEWLINES
1 REM
1 LOCN 1000
1 F DEFN *
1 LOCN *+2800
1 FINI 300

View File

@@ -255,6 +255,7 @@ window.addEventListener("load", function() {
* 13 = BU pair for CRF/CWF: (B-1)*2 in (41) U in (11)
* 14 = reload-lockout value added to (41)
* 15 = digit inserted in (11); if specified, insert 1 in (41)
* 16 = format band digit in (41): (B-1)*2
* 19 = resolved address only
***************************************/
@@ -366,7 +367,7 @@ window.addEventListener("load", function() {
"MIB": [ 59, 1, -1, 4, -1, 8, 0],
"MIE": [159, 1, -1, 4, -1, 8, 0],
"CRD": [ 60, 1, -1, 4, -1, 5, 0, 8, 0],
"CWR": [ 61, 1, -1, 4, -1, 13, -1, 8, 0],
"CWR": [ 61, 1, -1, 4, -1, 16, -1, 8, 0],
"CRF": [ 62, 1, -1, 13, -1, 14, 0],
"CWF": [ 63, 1, -1, 13, -1, 14, 0],
"CRI": [ 64, 1, -1, 4, -1],
@@ -1199,6 +1200,11 @@ window.addEventListener("load", function() {
word += p10[6] - w2;
}
break;
case 16: // format band digit in (41): (B-1)*2
w1 = word % p10[7]; // band in (41)
w2 = w1 - w1 % p10[6];
word += (f%10-1)*2*p10[6] - w2;
break;
case 19: // resolved address only
w2 = word % p10[4];
word += f%p10[4] - w2;

View File

@@ -171,7 +171,7 @@ B220CardatronControl.prototype.cardatronOnLoad = function cardatronOnLoad() {
};
/**************************************/
B220CardatronControl.prototype.inputInitiate = function inputInitiate(unitNr, kDigit, wordSender) {
B220CardatronControl.prototype.inputInitiate = function inputInitiate(unitNr, rDigit, wordSender) {
/* Initiates the read from one of the Cardatron input devices.
Returns 0 if device exists and the I/O was initiated; returns -1 if device
not present */
@@ -185,7 +185,7 @@ B220CardatronControl.prototype.inputInitiate = function inputInitiate(unitNr, kD
if (!this.inputUnit[unitNr]) {
return -1; // just terminate the I/O
} else {
this.inputUnit[unitNr].inputInitiate(kDigit, wordSender);
this.inputUnit[unitNr].inputInitiate(rDigit, wordSender);
return 0;
}
};
@@ -195,6 +195,7 @@ B220CardatronControl.prototype.inputReadyInterrogate = function inputReadyInterr
/* Interrogates the ready status of a Cardatron input device.
Returns -1 if device not present, 0 if device not ready, 1 if device is ready */
this.setUnitDesignateLamps(unitNr);
if (!this.inputUnit[unitNr]) {
return -1;
} else {
@@ -204,7 +205,7 @@ B220CardatronControl.prototype.inputReadyInterrogate = function inputReadyInterr
/**************************************/
B220CardatronControl.prototype.inputFormatInitiate = function inputFormatInitiate(
unitNr, kDigit, requestNextWord, signalFinished) {
unitNr, rDigit, requestNextWord, signalFinished) {
/* Initiates loading a format band for one of the Cardatron input devices.
Returns 0 if device exists and the I/O was initiated; returns -1 if device
not present */
@@ -218,58 +219,63 @@ B220CardatronControl.prototype.inputFormatInitiate = function inputFormatInitiat
if (!this.inputUnit[unitNr]) {
return -1; // just terminate the I/O
} else {
this.inputUnit[unitNr].inputFormatInitiate(kDigit, requestNextWord, signalFinished);
this.inputUnit[unitNr].inputFormatInitiate(rDigit, requestNextWord, signalFinished);
return 0;
}
};
/**************************************/
B220CardatronControl.prototype.outputInitiate = function outputInitiate(
unitNr, kDigit, tDigit, requestNextWord, signalFinished) {
/* Initiates writing to one of the Cardatron output devices */
unitNr, fDigit, cDigit, requestNextWord, signalFinished) {
/* Initiates writing to one of the Cardatron output devices.
Returns 0 if device exists and the I/O was initiated; returns -1 if device
not present */
this.bufferReadLamp.set(0);
this.bufferWriteLamp.set(1);
this.formatLoadLamp.set(0);
this.outputUnitLamp.set(1);
this.setRelayDesignateLamps(tDigit);
this.setRelayDesignateLamps(cDigit);
this.setUnitDesignateLamps(unitNr);
if (!this.outputUnit[unitNr]) {
// ?? what happens if the unitNr is invalid? Halt?
signalFinished(); // just terminate the I/O
return -1; // just terminate the I/O
} else {
this.setUnitDesignateLamps(unitNr);
this.outputUnit[unitNr].outputInitiate(kDigit, tDigit, requestNextWord, signalFinished);
this.outputUnit[unitNr].outputInitiate(fDigit, cDigit, requestNextWord, signalFinished);
return 0;
}
};
/**************************************/
B220CardatronControl.prototype.outputReadyInterrogate = function outputReadyInterrogate(unitNr) {
/* Interrogates the ready status of a Cardatron output device */
/* Interrogates the ready status of a Cardatron output device.
Returns -1 if device not present, 0 if device not ready, 1 if device is ready */
this.setUnitDesignateLamps(unitNr);
if (!this.outputUnit[unitNr]) {
// ?? what happens if the unitNr is invalid? Halt?
return false;
return -1; // just terminate the I/O
} else {
return this.outputUnit[unitNr].outputReadyInterrogate();
return (this.outputUnit[unitNr].outputReadyInterrogate() ? 1 : 0);
}
};
/**************************************/
B220CardatronControl.prototype.outputFormatInitiate = function outputFormatInitiate(
unitNr, kDigit, requestNextWord, signalFinished) {
/* Initiates loading a format band for one of the Cardatron output devices */
unitNr, fDigit, requestNextWord, signalFinished) {
/* Initiates loading a format band for one of the Cardatron output devices.
Returns 0 if device exists and the I/O was initiated; returns -1 if device
not present */
this.bufferReadLamp.set(0);
this.bufferWriteLamp.set(0);
this.formatLoadLamp.set(1);
this.outputUnitLamp.set(1);
this.setRelayDesignateLamps(0);
this.setUnitDesignateLamps(unitNr);
if (!this.outputUnit[unitNr]) {
// ?? what happens if the unitNr is invalid? Halt?
signalFinished(); // just terminate the I/O
return -1; // just terminate the I/O
} else {
this.setUnitDesignateLamps(unitNr);
this.outputUnit[unitNr].outputFormatInitiate(kDigit, requestNextWord, signalFinished);
this.outputUnit[unitNr].outputFormatInitiate(fDigit, requestNextWord, signalFinished);
return 0;
}
};

View File

@@ -29,8 +29,6 @@ function B220CardatronInput(mnemonic, unitIndex, config) {
this.unitIndex = unitIndex; // Input unit number
this.timer = 0; // setCallback() token
this.boundFinishCardRead = B220Util.bindMethod(this, B220CardatronInput.prototype.finishCardRead);
this.boundInputFormatWord = B220Util.bindMethod(this, B220CardatronInput.prototype.inputFormatWord);
this.clear();
@@ -79,9 +77,8 @@ B220CardatronInput.prototype.cardsPerMinute = 240; // IBM Type 087/089 coll
B220CardatronInput.prototype.eodBias = -0x900000000000; // signals end-of-data to Processor
B220CardatronInput.trackSize = 319; // digits
B220CardatronInput.drumTransferTime = 60000/21600*1.5;
// one drum rotation, plus a half rotation for
// average latency, about 4.17 ms
B220CardatronInput.drumTransferTime = 60000/21600;
// one drum rotation, about 2.78 ms
// Filter ASCII character values to buffer drum info band zone/numeric digits.
// See U.S. Patent 3,000,556, September 16, 1961, L.L. Bewley et al, Figure 2.
@@ -139,6 +136,7 @@ B220CardatronInput.prototype.clear = function clear() {
this.pendingCall = null; // stashed pending function reference
this.pendingParams = null; // stashed pending function parameters
this.pendingFinish = null; // stashed pending signalFinish() reference
};
/**************************************/
@@ -262,7 +260,6 @@ B220CardatronInput.prototype.CIStopBtn_onClick = function CIStopBtn_onClick(ev)
if (this.ready) {
this.setReaderReady(false);
this.startMachineLamp.set(0);
this.setFormatSelectLamps(0);
}
};
@@ -346,7 +343,7 @@ B220CardatronInput.prototype.format_onChange = function format_onChange(ev) {
this.config.putNode("Cardatron.units", prefs, this.unitIndex);
break;
case "FormatSelect":
x = this.formatColumnList.selectedIndex;
x = this.formatSelectList.selectedIndex;
prefs.formatSelect = this.formatSelect = x;
this.config.putNode("Cardatron.units", prefs, this.unitIndex);
break;
@@ -546,6 +543,7 @@ B220CardatronInput.prototype.finishCardRead = function finishCardRead() {
if (this.readRequested) { // fire up any pending read from Processor
this.readRequested = false;
this.pendingCall.apply(this, this.pendingParams);
this.pendingCall = null;
}
}
};
@@ -559,7 +557,7 @@ B220CardatronInput.prototype.initiateCardRead = function initiateCardRead() {
this.setNoFormatAlarm(false);
this.clearInfoBand();
this.timer = setCallback(this.mnemonic, this,
60000/this.cardsPerMinute, this.boundFinishCardRead);
60000/this.cardsPerMinute, this.finishCardRead);
}
};
@@ -636,45 +634,6 @@ B220CardatronInput.prototype.readerOnLoad = function readerOnLoad() {
de.scrollHeight - this.window.innerHeight);
};
/**************************************/
B220CardatronInput.prototype.inputInitiate = function inputInitiate(rDigit, wordReceiver) {
/* Initiates a read against the buffer drum on this unit. rDigit is the
(41) numeric digit from the instruction word, with odd values indicating
reload-lockout should be imposed at the end of the read. wordReceiver is the
callback function that will receive one word at a time for return to the
Processor. If the buffer is not ready, simply sets the readRequested flag
and exits after stashing rDigit and the wordReceiver callback */
if (!this.bufferReady) {
this.readRequested = true; // wait for the buffer to be filled
this.pendingCall = inputInitiate;
this.pendingParams = [rDigit, wordReceiver];
if (!this.ready) {
this.window.focus();
}
} else {
this.rDigit = rDigit;
this.infoIndex = 0; // start at the beginning of the info band
this.digitCount = 0;
this.pendingInputWord = 0;
this.togNumeric = true;
this.lastNumericDigit = 0;
setCallback(this.mnemonic, this, B220CardatronInput.drumTransferTime,
this.inputTransfer, wordReceiver);
}
};
/**************************************/
B220CardatronInput.prototype.inputTransfer = function inputTransfer(wordReceiver) {
/* Driver for sending words assembled from the info band to the Processor */
while (this.infoIndex < this.info.length) {
this.inputWord(wordReceiver);
}
this.inputStop();
};
/**************************************/
B220CardatronInput.prototype.inputWord = function inputWord(wordReceiver) {
/* Reads the next word of digits from the info band of the buffer drum,
@@ -687,6 +646,7 @@ B220CardatronInput.prototype.inputWord = function inputWord(wordReceiver) {
var d; // result digit
var eod; // finished with current digit
var eow = false; // finished with word
var info = this.info; // local reference to info band
var ix = this.infoIndex; // current info/format band index
var lastNumeric = this.lastNumericDigit;
var nu = this.togNumeric; // numeric/zone digit toggle
@@ -698,7 +658,7 @@ B220CardatronInput.prototype.inputWord = function inputWord(wordReceiver) {
eod = false;
do {
if (ix >= this.info.length) {
if (ix >= info.length) {
// At end of info band -- finish the I/O
d = 0;
word = word + this.eodBias; // flag this as the final word of the I/O
@@ -712,7 +672,7 @@ B220CardatronInput.prototype.inputWord = function inputWord(wordReceiver) {
eod = true;
break;
case 1: // translate zone/numeric digit
d = this.info[ix];
d = info[ix];
if (nu) {
// Numeric digit: straight translation except for 3-8 and 4-8 punches
nu = false; // next is a zone digit
@@ -739,7 +699,7 @@ B220CardatronInput.prototype.inputWord = function inputWord(wordReceiver) {
default: // (3) delete the digit
if (nu) {
nu = false; // next is a zone digit
lastNumeric = this.info[ix];
lastNumeric = info[ix];
} else {
nu = true; // next is a numeric digit
}
@@ -768,7 +728,7 @@ B220CardatronInput.prototype.inputWord = function inputWord(wordReceiver) {
// Send the word to the Processor
if (wordReceiver(word) < 0) {
this.infoIndex = this.info.length; // stop the I/O
this.infoIndex = info.length; // stop the I/O
} else {
this.infoIndex = ix;
}
@@ -793,6 +753,45 @@ B220CardatronInput.prototype.inputStop = function inputStop() {
}
};
/**************************************/
B220CardatronInput.prototype.inputTransfer = function inputTransfer(wordReceiver) {
/* Driver for sending words assembled from the info band to the Processor */
while (this.infoIndex < this.info.length) {
this.inputWord(wordReceiver);
}
this.inputStop();
};
/**************************************/
B220CardatronInput.prototype.inputInitiate = function inputInitiate(rDigit, wordReceiver) {
/* Initiates a read against the buffer drum on this unit. rDigit is the
(41) numeric digit from the instruction word, with odd values indicating
reload-lockout should be imposed at the end of the read. wordReceiver is the
callback function that will receive one word at a time for return to the
Processor. If the buffer is not ready, simply sets the readRequested flag
and exits after stashing rDigit and the wordReceiver callback */
if (!this.bufferReady) {
this.readRequested = true; // wait for the buffer to be filled
this.pendingCall = inputInitiate;
this.pendingParams = [rDigit, wordReceiver];
if (!this.ready) {
this.window.focus();
}
} else {
this.rDigit = rDigit;
this.infoIndex = 0; // start at the beginning of the info band
this.digitCount = 0;
this.pendingInputWord = 0;
this.togNumeric = true;
this.lastNumericDigit = 0;
setCallback(this.mnemonic, this, B220CardatronInput.drumTransferTime*(Math.random()+1),
this.inputTransfer, wordReceiver);
}
};
/**************************************/
B220CardatronInput.prototype.inputReadyInterrogate = function inputReadyInterrogate() {
/* Returns the current ready status of the input unit */
@@ -800,6 +799,38 @@ B220CardatronInput.prototype.inputReadyInterrogate = function inputReadyInterrog
return this.bufferReady;
};
/**************************************/
B220CardatronInput.prototype.inputFormatTransfer = function inputFormatTransfer(requestNextWord) {
/* Receives input format band words from the Processor and stores the
digits from each word into the next 11 format band digits */
var band = this.formatBand[this.selectedFormat];
var d; // current format digit
var ix = 0; // current format band digit index
var word; // band word from Processor
var x; // word-digit index
while (ix < B220CardatronInput.trackSize) {
word = requestNextWord();
if (word < 0) { // transfer terminated
ix = B220CardatronInput.tracksize;
} else {
for (x=0; x<11; ++x) {
d = word % 0x10;
word = (word-d)/0x10;
if (ix < B220CardatronInput.trackSize) {
band[ix++] = d % 4;
} else {
break; // out of for loop
}
} // for x
}
}
this.pendingFinish(); // call signalFinished();
this.pendingFinish = null;
this.inputStop();
};
/**************************************/
B220CardatronInput.prototype.inputFormatInitiate = function inputFormatInitiate(
rDigit, requestNextWord, signalFinished) {
@@ -807,7 +838,7 @@ B220CardatronInput.prototype.inputFormatInitiate = function inputFormatInitiate(
(41) numeric digit from the instruction word, with odd values indicating
reload-lockout should be imposed at the end of the read and the remaining
three bits indicating the format band to be loaded. requestNextWord is the
callback function that will trigger the Processor to send the next digit.
callback function that will trigger the Processor to send the next word.
signalFinished is the callback function that will signal the Processor to
terminate the I/O */
@@ -816,55 +847,11 @@ B220CardatronInput.prototype.inputFormatInitiate = function inputFormatInitiate(
} else {
this.rDigit = rDigit;
this.selectedFormat = ((rDigit >>> 1) & 0x07) + 1;
this.infoIndex = 0; // start at the beginning of the format band
this.digitCount = 0;
this.togNumeric = true;
this.lastNumericDigit = 0;
this.pendingCall = signalFinished; // stash the call-back function
this.pendingFinish = signalFinished; // stash the call-back function
this.setFormatSelectLamps(this.selectedFormat);
setCallback(this.mnemonic, this, B220CardatronInput.drumTransferTime*1.67,
setCallback(this.mnemonic, this, B220CardatronInput.drumTransferTime*(Math.random()+2),
this.inputFormatTransfer, requestNextWord);
}
};
/**************************************/
B220CardatronInput.prototype.inputFormatTransfer = function inputFormatTransfer(requestNextWord) {
/* Driver for sending words assembled from the info band to the Processor */
while (this.infoIndex < B220CardatronInput.trackSize) {
this.inputFormatWord(requestNextWord);
}
this.pendingCall(); // call signalFinished();
this.inputStop();
};
/**************************************/
B220CardatronInput.prototype.inputFormatWord = function inputFormatWord(requestNextWord) {
/* Receives the next input format band word from the Processor and
stores the digits from the word into the next 11 format band digits */
var band = this.formatBand[this.selectedFormat];
var d; // current format digit
var ix = this.infoIndex; // current format band digit index
var word = requestNextWord(); // band word from Processor
var x; // word-digit index
if (word < 0) { // transfer terminated
ix = B220CardatronInput.tracksize;
} else {
for (x=0; x<11; ++x) {
d = word % 0x10;
word = (word-d)/0x10;
if (ix < B220CardatronInput.trackSize) {
band[ix++] = d % 4;
} else {
break; // out of for loop
}
} // for x
}
this.infoIndex = ix;
};
/**************************************/

View File

@@ -37,9 +37,6 @@ function B220CardatronOutput(mnemonic, unitIndex, config) {
this.useGreenbar = false; // format "greenbar" shading on the paper (printer only)
this.lpi = 6; // lines/inch (actually, lines per greenbar group, should be even)
this.boundOutputFormatWord = B220Util.bindMethod(this, B220CardatronOutput.prototype.outputFormatWord);
this.boundOutputWord = B220Util.bindMethod(this, B220CardatronOutput.prototype.outputWord);
this.clear();
// Line buffer for assembling the print/punch line
@@ -67,7 +64,7 @@ function B220CardatronOutput(mnemonic, unitIndex, config) {
this.supply = null; // the "paper" or "cards" we print/punch on
this.endOfSupply = null; // dummy element used to control scrolling
this.supplyMeter = null; // <meter> element showing amount of paper/card supply remaining
w = (this.isPrinter ? 780 : 608);
w = (this.isPrinter ? 790 : 608);
this.window = window.open("../webUI/B220CardatronOutput.html", mnemonic,
"location=no,scrollbars,resizable,width=" + w + ",height=" + h +
",left=" + (screen.availWidth - w) +
@@ -82,11 +79,9 @@ B220CardatronOutput.prototype.maxSupplyLines = 150000; // maximum output scroll
B220CardatronOutput.prototype.rtrimRex = /\s+$/; // regular expression for right-trimming lines
B220CardatronOutput.prototype.theColorGreen = "#CFC"; // for greenbar shading
B220CardatronOutput.trackSize = 316; // digits
B220CardatronOutput.digitTime = 60/21600/B220CardatronOutput.trackSize;
// one digit time, about 8.8 µs at 21600rpm
B220CardatronOutput.digitsPerMilli = 0.001/B220CardatronOutput.digitTime;
// digit times per millisecond: 113.8
B220CardatronOutput.trackSize = 319; // digits
B220CardatronOutput.drumTransferTime = 60000/21600;
// one drum rotation, about 2.78 ms
// Translate info band zone & numeric digits to ASCII character codes.
// See U.S. Patent 3,072,328, January 8, 1963, L.L. Bewley et al, Figure 2;
@@ -157,6 +152,7 @@ B220CardatronOutput.prototype.clear = function clear() {
this.bufferReady = true; // buffer drum info band is ready to accept data from Processor
this.writeRequested = false; // Processor has initiated a write, waiting for buffer
this.togNumeric = false; // current digit came from zone (false) or numeric (true) punches
this.suppress12Mode = false; // suppresses 12 zones for sign digits
this.supplyLeft = this.maxSupplyLines; // lines/cards remaining in output supply
this.runoutSupplyCount = 0; // counter for triple-formfeed => rip paper/empty hopper
@@ -166,8 +162,9 @@ B220CardatronOutput.prototype.clear = function clear() {
this.pendingCall = null; // stashed pending function reference
this.pendingParams = null; // stashed pending function parameters
this.kDigit = 0; // stashed reload-format band number
this.tDigit = 0; // stashed Tab Select relay digit
this.pendingFinish = null; // stashed pending signalFinished() reference
this.cDigit = 0; // stashed Tab Select relay digit
this.fDigit = 0; // stashed format band number
this.lastNumericDigit = 0; // last numeric digit encountered
this.infoIndex = 0; // 0-relative offset into info band on drum
this.selectedFormat = 0; // currently-selected format band
@@ -347,6 +344,7 @@ B220CardatronOutput.prototype.finishWrite = function finishWrite() {
if (this.writeRequested) {
this.writeRequested = false;
this.pendingCall.apply(this, this.pendingParams);
this.pendingCall = null;
}
};
@@ -431,7 +429,7 @@ B220CardatronOutput.prototype.initiateWrite = function initiateWrite() {
} else {
line = line.replace(this.rtrimRex, '');
}
switch (this.tDigit) {
switch (this.cDigit) {
case 1: // Relay 1 (eject page after printing)
case 9: // same as 1
this.printLine(line, this.pendingSpaceBefore);
@@ -791,8 +789,7 @@ B220CardatronOutput.prototype.deviceOnLoad = function deviceOnLoad() {
};
/**************************************/
B220CardatronOutput.prototype.outputWord = function outputWord(
word, requestNextWord, signalFinished) {
B220CardatronOutput.prototype.outputWord = function outputWord(requestNextWord) {
/* Receives the next info band word from the Processor and stores its digits
under control of the selected format band. requestNextWord is the callback function
to request the next word from the Processor; signalFinished is the callback
@@ -805,14 +802,11 @@ B220CardatronOutput.prototype.outputWord = function outputWord(
var info = this.info; // local reference to info band
var ix = this.infoIndex; // current info/format band index
var lastNumeric = this.lastNumericDigit;
var latency = 0; // drum latency for first digit of a word
var nu = this.togNumeric; // numeric vs. zone digit toggle
var nu = this.togNumeric; // numeric/zone digit toggle
var word = requestNextWord(); // word received from processor
var x = 0; // word-digit index
band = this.formatBand[this.selectedFormat];
// For the first digit of a word, note the current buffer drum digit address
drumAddr = (performance.now()*B220CardatronOutput.digitsPerMilli) % B220CardatronOutput.trackSize;
latency = (ix - drumAddr + B220CardatronOutput.trackSize) % B220CardatronOutput.trackSize;
// Loop through the digits in the word, processing each one
do {
@@ -845,7 +839,11 @@ B220CardatronOutput.prototype.outputWord = function outputWord(
if (x > 9) {
// For a zone digit in the sign position, store a 5 (+) or 6 (-)
// so that the sign will be printed/punched as a zone 11/12.
info[ix] = (d & 0x01) + 5;
if (d == 0 && this.suppress12Mode) {
info[ix] = 0; // suppress the 12-zone output
} else {
info[ix] = (d & 0x01) + 5;
}
} else if (d > 3) {
info[ix] = this.zoneXlate[d][lastNumeric];
} else {
@@ -884,24 +882,27 @@ B220CardatronOutput.prototype.outputWord = function outputWord(
this.lastNumericDigit = lastNumeric;
this.togNumeric = nu;
this.infoIndex = ix;
if (ix < info.length) {
// Delay requesting the next word for the amount of time until buffer drum was in position
setCallback(this.mnemonic, this, latency/B220CardatronOutput.digitsPerMilli,
requestNextWord, this.boundOutputWord);
// requestNextWord(this.boundOutputWord); // until we get the timing fixed
} else {
// At end of info band -- finish the data transfer and start the I/O to the device
this.initiateWrite();
signalFinished();
}
/**************************************/
B220CardatronOutput.prototype.outputTransfer = function outputTransfer(requestNextWord) {
/* Driver for receiving info band words from the Processor */
while (this.infoIndex < this.info.length) {
this.outputWord(requestNextWord);
}
this.pendingFinish(); // call signalFinished()
this.pendingFinish = null;
this.initiateWrite();
};
/**************************************/
B220CardatronOutput.prototype.outputInitiate = function outputInitiate(
kDigit, tDigit, requestNextWord, signalFinished) {
/* Initiates a write to the buffer drum on this unit. kDigit is the
second numeric digit from the instruction word containing the format number.
tDigit is the first numeric digit from the instruction word and sets the
fDigit, cDigit, requestNextWord, signalFinished) {
/* Initiates a write to the buffer drum on this unit. fDigit is the
(41) numeric digit from the instruction word containing the format number.
cDigit is the (31) numeric digit from the instruction word and sets the
Tab Select relays for the IBM device. We use it for carriage control as
implemented by the standard Burroughs 205/220 plugboard for the 407:
0 = No relays (single space before printing)
@@ -918,27 +919,28 @@ B220CardatronOutput.prototype.outputInitiate = function outputInitiate(
requestNextWord is the callback function that will request the next word from the
processor. signalFinished is the callback function that tells the Processor
we're done. If the buffer is not ready, simply sets the writeRequested flag
and exits after stashing kDigit, tDigit, and the callbacks. Note that if the
and exits after stashing fDigit, cDigit, and the callbacks. Note that if the
device is not ready, the buffer can still be loaded */
if (!this.bufferReady) {
this.writeRequested = true; // wait for the buffer to be emptied
this.pendingCall = outputInitiate;
this.pendingParams = [kDigit, tDigit, requestNextWord, signalFinished];
} else if (kDigit > 9) {
this.pendingParams = [fDigit, cDigit, requestNextWord, signalFinished];
} else if (fDigit > 9) {
signalFinished();
} else {
this.kDigit = kDigit;
this.tDigit = (this.isPrinter ? tDigit : 0);
this.selectedFormat = ((kDigit >>> 1) & 0x07) + 1;
this.cDigit = (this.isPrinter ? cDigit : 0);
this.fDigit = fDigit;
this.suppress12Mode = (fDigit%2 == 0);
this.selectedFormat = ((fDigit >>> 1) & 0x07) + 1;
this.setFormatSelectLamps(this.selectedFormat);
this.togNumeric = true;
this.lastNumericDigit = 0;
this.bufferReady = false;
this.clearInfoBand();
setCallback(this.mnemonic, this,
B220CardatronOutput.trackSize/B220CardatronOutput.digitsPerMilli*2.5,
requestNextWord, this.boundOutputWord); // request the first data word
this.pendingFinish = signalFinished; // stash the callback function
setCallback(this.mnemonic, this, B220CardatronOutput.drumTransferTime*(Math.random()+2),
this.outputTransfer, requestNextWord);
}
};
@@ -949,57 +951,56 @@ B220CardatronOutput.prototype.outputReadyInterrogate = function outputReadyInter
return this.bufferReady;
};
/**************************************/
B220CardatronOutput.prototype.outputFormatTransfer = function outputFormatTransfer(requestNextWord) {
/* Receives output format band words from the Processor and stores the
digits from each word into the next 11 format band digits */
var band = this.formatBand[this.selectedFormat];
var d; // current format digit
var ix = 0; // current format band digit index
var word; // band word received from Processor
var x; // word-digit index
while (ix < B220CardatronOutput.trackSize) {
word = requestNextWord();
if (word < 0) { // transfer terminated
ix = B220CardatronOutput.tracksize;
} else {
for (x=0; x<11; ++x) {
d = word % 0x10;
word = (word-d)/0x10;
if (ix < B220CardatronOutput.trackSize) {
band[ix++] = d % 4;
} else {
break; // out of for loop
}
} // for x
}
}
this.pendingFinish(); // call signalFinished();
this.pendingFinish = null;
};
/**************************************/
B220CardatronOutput.prototype.outputFormatInitiate = function outputFormatInitiate(
kDigit, requestNextWord, signalFinished) {
/* Initiates the loading of a format band on this unit. kDigit is the
second numeric digit from the instruction word, the low-order bit is ignored
fDigit, requestNextWord, signalFinished) {
/* Initiates the loading of a format band on this unit. fDigit is the
(41) numeric digit from the instruction word, the low-order bit is ignored,
and the remaining three bits indicate the format band to be loaded. requestNextWord
is the callback function that will trigger the Processor to send the next word.
signalFinished is the callback function that will signal the Processor to
terminate the I/O */
if (kDigit > 9) {
if (fDigit > 9) {
signalFinished();
} else {
this.kDigit = kDigit;
this.selectedFormat = ((kDigit >>> 1) & 0x07) + 1;
this.infoIndex = 0; // start at the beginning of the format band
this.togNumeric = true;
this.lastNumericDigit = 0;
this.fDigit = fDigit;
this.selectedFormat = ((fDigit >>> 1) & 0x07) + 1;
this.pendingFinish = signalFinished; // stash the call-back function
this.setFormatSelectLamps(this.selectedFormat);
setCallback(this.mnemonic, this,
B220CardatronOutput.trackSize/B220CardatronOutput.digitsPerMilli*2.5,
requestNextWord, this.boundOutputFormatWord); // request the first format word
}
};
/**************************************/
B220CardatronOutput.prototype.outputFormatWord = function outputFormatWord(
word, requestNextWord, signalFinished) {
/* Receives the next output format band word from the Processor and
stores the digits from the word into the next 11 format band digits */
var band = this.formatBand[this.selectedFormat];
var d; // current format digit
var ix = this.infoIndex; // current format band digit index
var x; // word-digit index
for (x=0; x<11; ++x) {
d = word % 0x10;
word = (word-d)/0x10;
if (ix < B220CardatronOutput.trackSize) {
band[ix++] = d % 4;
} else {
break; // out of for loop
}
} // for x
this.infoIndex = ix;
if (ix < B220CardatronOutput.trackSize) {
requestNextWord(this.boundOutputFormatWord);
} else {
this.setFormatSelectLamps(0);
signalFinished();
setCallback(this.mnemonic, this, B220CardatronOutput.drumTransferTime*(Math.random()+2),
this.outputFormatTransfer, requestNextWord);
}
};

View File

@@ -529,6 +529,11 @@ B220ControlConsole.prototype.consoleOnLoad = function consoleOnLoad() {
this.regP = new PanelRegister(this.$$("PRegPanel"), 4*4, 4, "P_", "P");
this.regS = new PanelRegister(this.$$("SRegPanel"), 4*4, 4, "S_", "S");
this.regA.drawBox(6, 2, 4, "2px solid white", "2px solid white");
this.regC.drawBox(5, 2, 4, "2px solid white", "2px solid white");
this.regD.drawBox(6, 2, 4, "2px solid white", "2px solid white");
this.regR.drawBox(6, 2, 4, "2px solid white", "2px solid white");
// Status Panels
panel = this.$$("AlarmPanel");

View File

@@ -1,5 +1,5 @@
CACHE MANIFEST
# retro-220 emulator 0.01a, 2017-05-20 18:30
# retro-220 emulator 0.02, 2017-05-24 09:00
CACHE:
../emulator/B220Processor.js
B220.css

View File

@@ -827,10 +827,10 @@ PanelRegister.prototype.drawBox = function drawBox(col, lamps, rows, leftStyle,
var rightBias = (rightStyle ? 1 : 0);
box.style.position = "absolute";
box.style.left = (this.xCoord(col) - (PanelRegister.hSpacing-PanelRegister.lampDiameter)/2).toString() + "px";
box.style.width = (PanelRegister.hSpacing*lamps - rightBias).toString() + "px";
box.style.left = (this.xCoord(col) - (PanelRegister.hSpacing-PanelRegister.lampDiameter)/2 + 1).toString() + "px";
box.style.width = (PanelRegister.hSpacing*lamps - 2).toString() + "px";
box.style.top = this.yCoord(1).toString() + "px";
box.style.height = (this.yCoord(rows) - this.yCoord(1) + PanelRegister.lampDiameter).toString() + "px";
box.style.height = (this.yCoord(rows+1) - this.yCoord(1)).toString() + "px";
box.style.borderLeft = leftStyle;
box.style.borderRight = rightStyle;
box.appendChild(document.createTextNode("\xA0"));