mirror of
https://github.com/pkimpel/retro-220.git
synced 2026-04-04 21:07:29 +00:00
Commit retro-220 version 0.03:
1. Implementation Paper Tape Reader devices and op codes. 2. Commit standard and inverse-format paper tape loaders for WINTER.PI program. 3. Fix positioning of Cardatron and TTY/Paper Tape Punch device windows.
This commit is contained in:
@@ -12,8 +12,8 @@ The contents of this project are licensed under the [MIT License](http://www.ope
|
||||
|
||||
| Related Sites | URL |
|
||||
| ------------- | ----- |
|
||||
| Emulator hosting site | http://www.phkimpel.us/ElectroData/220/ |
|
||||
| Emulator hosting site | http://www.phkimpel.us/Burroughs-220/ |
|
||||
| Burroughs 205/220 blog | http://datatron.blogspot.com |
|
||||
| Datatron 205 site | http://www.phkimpel.us/ElectroData/205/ |
|
||||
| Datatron 205 site | http://www.phkimpel.us/ElectroData-205/ |
|
||||
| Documents at bitsavers | http://bitsavers.org/pdf/burroughs/electrodata/220/ |
|
||||
|
||||
|
||||
@@ -237,9 +237,9 @@ function B220Processor(config, devices) {
|
||||
this.boundConsoleOutputSign = B220Processor.bindMethod(this, B220Processor.prototype.consoleOutputSign);
|
||||
this.boundConsoleOutputChar = B220Processor.bindMethod(this, B220Processor.prototype.consoleOutputChar);
|
||||
this.boundConsoleOutputFinished = B220Processor.bindMethod(this, B220Processor.prototype.consoleOutputFinished);
|
||||
this.boundConsoleInputDigit = B220Processor.bindMethod(this, B220Processor.prototype.consoleInputDigit);
|
||||
this.boundConsoleReceiveDigit = B220Processor.bindMethod(this, B220Processor.prototype.consoleReceiveDigit);
|
||||
this.boundConsoleReceiveSingleDigit = B220Processor.bindMethod(this, B220Processor.prototype.consoleReceiveSingleDigit);
|
||||
this.boundConsoleInputReceiveChar = B220Processor.bindMethod(this, B220Processor.prototype.consoleInputReceiveChar);
|
||||
this.boundConsoleInputInitiateNormal = B220Processor.bindMethod(this, B220Processor.prototype.consoleInputInitiateNormal);
|
||||
this.boundConsoleInputInitiateInverse = B220Processor.bindMethod(this, B220Processor.prototype.consoleInputInitiateInverse);
|
||||
|
||||
this.boundCardatronOutputWord= B220Processor.bindMethod(this, B220Processor.prototype.cardatronOutputWord);
|
||||
this.boundCardatronOutputFinished = B220Processor.bindMethod(this, B220Processor.prototype.cardatronOutputFinished);
|
||||
@@ -260,7 +260,7 @@ function B220Processor(config, devices) {
|
||||
* Global Constants *
|
||||
***********************************************************************/
|
||||
|
||||
B220Processor.version = "0.02";
|
||||
B220Processor.version = "0.03";
|
||||
|
||||
B220Processor.tick = 1000/200000; // milliseconds per clock cycle (200KHz)
|
||||
B220Processor.cyclesPerMilli = 1/B220Processor.tick;
|
||||
@@ -2470,8 +2470,7 @@ B220Processor.prototype.consoleOutputChar = function consoleOutputChar(printChar
|
||||
this.CADDR = this.C.value%0x10000;
|
||||
printChar(0x35, this.boundConsoleOutputSign);
|
||||
}
|
||||
} else if (this.PZT.value) {
|
||||
// Output alphabetically
|
||||
} else if (this.PZT.value) { // Output alphabetically
|
||||
w = this.D.value % 0x1000000000;
|
||||
d = (this.D.value - w)/0x1000000000; // get next 2 digits
|
||||
this.D.set(w*0x100 + d); // rotate D+sign left by two
|
||||
@@ -2483,8 +2482,7 @@ B220Processor.prototype.consoleOutputChar = function consoleOutputChar(printChar
|
||||
this.EWT.set(1);
|
||||
}
|
||||
printChar(d, this.boundConsoleOutputChar);
|
||||
} else {
|
||||
// Output numerically
|
||||
} else { // Output numerically
|
||||
if (this.DPT.value && !this.LEADINGZEROESSW) {
|
||||
// decimal point may be needed
|
||||
d = this.CCONTROL >>> 12;
|
||||
@@ -2529,130 +2527,191 @@ B220Processor.prototype.consoleOutputFinished = function consoleOutputFinished()
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220Processor.prototype.consoleInputDigit = function consoleInputDigit() {
|
||||
// Solicits the next input digit from the Control Console */
|
||||
B220Processor.prototype.consoleInputFinishWord = function consoleInputFinishWord(result) {
|
||||
/* Finishes the receipt of a word from the Console paper tape reader and
|
||||
either stores it in memory or shunts it to the C register for execution.
|
||||
Updates the C register as necessary and decides whether to initiate receipt
|
||||
of another word */
|
||||
var d;
|
||||
var w;
|
||||
|
||||
this.togTF = 0; // for display only, reset finish pulse
|
||||
this.execTime -= performance.now()*B220Processor.wordsPerMilli; // mark time during I/O
|
||||
this.console.readDigit(this.boundConsoleReceiveDigit);
|
||||
};
|
||||
if (this.sDigit) { // decrement word count
|
||||
d = this.bcdAdd(this.CCONTROL, 0x990, 3);
|
||||
this.CCONTROL += d - this.CCONTROL%0x1000;
|
||||
this.C.set((this.CCONTROL*0x100 + this.COP)*0x10000 + this.CADDR);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
B220Processor.prototype.consoleReceiveDigit = function consoleReceiveDigit(digit) {
|
||||
/* Handles an input digit coming from the Control Console keyboard or
|
||||
paper-tape reader. Negative values indicate a finish pulse; otherwise
|
||||
the digit is data read from the device. Data digits are rotated into
|
||||
the D register; finish pulses are handled according to the sign digit
|
||||
in the D register */
|
||||
var sign; // register sign digit
|
||||
var word; // register word less sign
|
||||
if (this.COP == 0x05) { // read inverse: permute the sign digit
|
||||
d = this.D.value%0x10;
|
||||
w = (this.D.value - d)/0x10;
|
||||
this.D.set(w + d*0x10000000000);
|
||||
if (d == 2) { // alphanumeric translation is invalid for inverse mode
|
||||
this.setPaperTapeCheck(1);
|
||||
this.ioComplete(true);
|
||||
return; // >>> ALARM ERROR EXIT <<<
|
||||
}
|
||||
} else { // sign digit in normal position
|
||||
w = this.D.value%0x10000000000;
|
||||
d = (this.D.value - w)/0x10000000000;
|
||||
}
|
||||
|
||||
this.execTime += performance.now()*B220Processor.wordsPerMilli; // restore time after I/O
|
||||
if (digit >= 0) {
|
||||
this.togTC1 = 1-this.togTC1; // for display only
|
||||
this.togTC2 = 1-this.togTC2; // for display only
|
||||
this.D.set((this.D.value % 0x10000000000)*0x10 + digit);
|
||||
this.consoleInputDigit();
|
||||
} else {
|
||||
this.togTF = 1;
|
||||
this.togTC1 = this.togTC2 = 0; // for display only
|
||||
word = this.D.value%0x10000000000;
|
||||
sign = (this.D.value - word)/0x10000000000; // get D-sign
|
||||
|
||||
if (sign & 0x04) {
|
||||
// D-sign is 4, 5, 6, 7: execute a "tape control" command
|
||||
this.execTime += 2;
|
||||
this.togTF = 0; // for display only
|
||||
this.togSTART = 1-((sign >>> 1)%2); // whether to continue in input mode
|
||||
this.setTimingToggle(0); // Execute mode
|
||||
this.togCOUNT = 1;
|
||||
this.togBTOAIN = 0;
|
||||
this.togADDAB = 1; // for display only
|
||||
this.togADDER = 1; // for display only
|
||||
this.togDPCTR = 1; // for display only
|
||||
this.togCLEAR = 1-(sign%2);
|
||||
this.togSIGN = ((this.A.value - this.A.value%0x10000000000)/0x10000000000)%2; // display only
|
||||
sign &= 0x08;
|
||||
|
||||
// Increment the destination address (except on the first word)
|
||||
this.SHIFTCONTROL = 0x01; // for display only
|
||||
this.SHIFT = 0x13; // for display only
|
||||
if (this.togCOUNT) {
|
||||
this.CCONTROL = this.bcdAdd(this.CADDR, 1, 4);
|
||||
}
|
||||
|
||||
this.CCONTROL = (this.D.value - word%0x1000000)/0x1000000;
|
||||
this.rDigit = (this.CCONTROL >>> 8) & 0x0F;
|
||||
// do not set this.selectedUnit from the word -- keep the same unit
|
||||
|
||||
// Shift D5-D10 into C1-C6, modify by B as necessary, and execute
|
||||
this.D.set(sign*0x100000 + (word - word%0x1000000)/0x1000000);
|
||||
if (this.togCLEAR) {
|
||||
word = this.bcdAdd(word%0x1000000, 0, 11);
|
||||
} else {
|
||||
word = this.bcdAdd(word%0x1000000, this.B.value, 11) % 0x1000000;
|
||||
}
|
||||
this.SHIFT = 0x19; // for display only
|
||||
this.C.set(word*0x10000 + this.CCONTROL); // put C back together
|
||||
this.CADDR = word % 0x10000;
|
||||
this.COP = (word - this.CADDR)/0x10000;
|
||||
this.execute();
|
||||
} else {
|
||||
// D-sign is 0, 1, 2, 3: store word, possibly modified by B
|
||||
this.execTime += 3;
|
||||
this.setTimingToggle(1); // Fetch mode
|
||||
this.togCOUNT = this.togBTOAIN;
|
||||
this.togBTOAIN = 1;
|
||||
this.togADDAB = 1; // for display only
|
||||
this.togADDER = 1; // for display only
|
||||
this.togDPCTR = 1; // for display only
|
||||
this.togCLEAR = 1-((sign >>> 1)%2);
|
||||
this.togSIGN = sign%2;
|
||||
|
||||
// Increment the destination address (except on the first word)
|
||||
this.SHIFTCONTROL = 0x01; // for display only
|
||||
this.SHIFT = 0x15; // for display only
|
||||
if (this.togCOUNT) {
|
||||
this.CADDR = this.bcdAdd(this.CADDR, 1, 4);
|
||||
}
|
||||
this.CCONTROL = this.CADDR;
|
||||
this.C.set((this.COP*0x10000 + this.CADDR)*0x10000 + this.CCONTROL);
|
||||
|
||||
// Modify the word by B as necessary and store it
|
||||
this.D.set((sign & 0x0C)*0x10000000000 + word);
|
||||
if (this.togCLEAR) {
|
||||
this.A.set(this.bcdAdd(this.D.value, 0, 11));
|
||||
} else {
|
||||
this.A.set(this.bcdAdd(this.D.value, this.B.value, 11));
|
||||
}
|
||||
if (this.rDigit & d & 0x08) { // B-modify word before storing
|
||||
this.D.set(w + (d&0x07)*0x10000000000);
|
||||
this.IB.set(this.D.value - w%0x10000 + this.bcdAdd(w, this.B.value, 4));
|
||||
this.C10.set(0);
|
||||
} else { // store word as-is
|
||||
this.IB.set(this.D.value);
|
||||
}
|
||||
|
||||
if (this.rDigit == 1 && (d & 0x0E) == 0x06) { // control word to C register
|
||||
this.ioComplete(false); // terminate I/O but do not restart Processor yet
|
||||
this.fetch(true); // set up to execute control word
|
||||
// Schedule the Processor to give the reader a chance to finish its operation.
|
||||
setCallback(this.mnemonic, this, 0, this.schedule);
|
||||
} else { // just store the word
|
||||
this.writeMemory();
|
||||
if (this.MET.value) { // memory address error
|
||||
this.ioComplete(true);
|
||||
} else if (this.sDigit && this.CCONTROL%0x1000 < 0x10) { // word count exhausted
|
||||
this.ioComplete(true);
|
||||
} else { // initiate input of another word
|
||||
this.D.set(0);
|
||||
word = this.A.value % 0x10000000000;
|
||||
sign = (((this.A.value - word)/0x10000000000) & 0x0E) | (sign%2);
|
||||
this.A.set(sign*0x10000000000 + word);
|
||||
this.writeMemory(this.boundConsoleInputDigit, false);
|
||||
if (this.COP == 0x05) {
|
||||
d = this.console.inputUnitSelect(this.selectedUnit, this.boundConsoleInputInitiateInverse);
|
||||
} else {
|
||||
d = this.console.inputUnitSelect(this.selectedUnit, this.boundConsoleInputInitiateNormal);
|
||||
}
|
||||
if (d < 0) { // no unit available -- set alarm and quit
|
||||
this.setPaperTapeCheck(1);
|
||||
this.ioComplete(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220Processor.prototype.consoleReceiveSingleDigit = function consoleReceiveSingleDigit(digit) {
|
||||
/* Handles a single input digit coming from the Control Console keyboard
|
||||
or paper-tape reader, as in the case of Digit Add (10). Negative values
|
||||
indicate a finish pulse, which is ignored, and causes another digit to be
|
||||
solicited from the Console; otherwise the digit is (virtually) moved to
|
||||
the D register and then (actually) added to the A register */
|
||||
B220Processor.prototype.consoleInputInitiateNormal = function consoleInputInitiateNormal(result) {
|
||||
/* Initiates the receipt into a word of characters from the Console tape
|
||||
reader in normal (sign-first) mode. Increments the C register operand address,
|
||||
rotates the sign digit into the D register, and determines whether the word
|
||||
should be translated numerically or alphanumerically */
|
||||
var code = result.code;
|
||||
|
||||
this.clockIn();
|
||||
if (this.AST.value) { // if false, we've probably been cleared
|
||||
this.E.set(this.CADDR);
|
||||
this.C.inc();
|
||||
this.CADDR = this.C.value%0x10000;
|
||||
|
||||
switch (code) {
|
||||
case 0x17: // invalid character/parity error
|
||||
this.setPaperTapeCheck(1);
|
||||
this.ioComplete(true);
|
||||
break;
|
||||
case 0x35: // end-of-word
|
||||
this.consoleInputFinishWord(result);
|
||||
break;
|
||||
case 0x82: // sign=2, set alpha translation
|
||||
this.PZT.set(!this.HOLDPZTZEROSW);
|
||||
this.D.set(2);
|
||||
result.readChar(this.boundConsoleInputReceiveChar);
|
||||
break;
|
||||
default: // anything else, set numeric translation
|
||||
this.PZT.set(0);
|
||||
if ((code & 0xF0) == 0x80) {// it's a numeric sign -- okay
|
||||
this.D.set(code%0x10);
|
||||
result.readChar(this.boundConsoleInputReceiveChar);
|
||||
} else if (code == 0) { // we'll take a space as a zero
|
||||
this.D.set(0);
|
||||
result.readChar(this.boundConsoleInputReceiveChar);
|
||||
} else { // sign is non-numeric -- invalid
|
||||
this.D.set(0);
|
||||
this.setPaperTapeCheck(1);
|
||||
this.ioComplete(true);
|
||||
}
|
||||
break;
|
||||
} // switch code
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220Processor.prototype.consoleInputInitiateInverse = function consoleInputInitiateInverse(result) {
|
||||
/* Initiates the receipt into a word of characters from the Console tape
|
||||
reader in inverse (sign-last) mode. Increments the C register operand address,
|
||||
rotates the sign digit into the D register, and sets PZT for numeric translation */
|
||||
var code = result.code;
|
||||
|
||||
this.clockIn();
|
||||
if (this.AST.value) { // if false, we've probably been cleared
|
||||
this.E.set(this.CADDR);
|
||||
this.C.inc();
|
||||
this.CADDR = this.C.value%0x10000;
|
||||
|
||||
switch (code) {
|
||||
case 0x17: // invalid character/parity error
|
||||
this.setPaperTapeCheck(1);
|
||||
this.ioComplete(true);
|
||||
break;
|
||||
case 0x35: // end-of-word
|
||||
this.consoleInputFinishWord(result);
|
||||
break;
|
||||
default: // anything else, set numeric translation
|
||||
this.PZT.set(0);
|
||||
if ((code & 0xF0) == 0x80) {// it's a numeric code -- okay
|
||||
this.D.set(code%0x10);
|
||||
result.readChar(this.boundConsoleInputReceiveChar);
|
||||
} else if (code == 0) { // we'll take a space as a zero
|
||||
this.D.set(0);
|
||||
result.readChar(this.boundConsoleInputReceiveChar);
|
||||
} else { // digit is non-numeric -- invalid
|
||||
this.D.set(0);
|
||||
this.setPaperTapeCheck(1);
|
||||
this.ioComplete(true);
|
||||
}
|
||||
break;
|
||||
} // switch code
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220Processor.prototype.consoleInputReceiveChar = function consoleInputReceiveChar(result) {
|
||||
/* Handles an input character coming from the Console paper-tape reader.
|
||||
result.code is the B220 character code read from the device. result.readChar
|
||||
is the callback function to request the next character. Data digits are
|
||||
rotated into the D register; end-of-word (0x35) codes are handled according
|
||||
to the sign digit in the D register */
|
||||
var code = result.code; // character received
|
||||
var sign; // register sign digit
|
||||
var word; // register word less sign
|
||||
|
||||
if (digit < 0) { // ignore finish pulse and just re-solicit
|
||||
this.console.readDigit(this.boundConsoleReceiveSingleDigit);
|
||||
} else {
|
||||
this.execTime += performance.now()*B220Processor.wordsPerMilli + 4; // restore time after I/O
|
||||
this.togSTART = 0;
|
||||
this.D.set(digit);
|
||||
this.integerAdd(false, false);
|
||||
this.schedule();
|
||||
this.clockIn();
|
||||
if (this.AST.value) { // if false, we've probably been cleared
|
||||
switch (code) {
|
||||
case 0x17: // invalid character/parity error
|
||||
this.setPaperTapeCheck(1);
|
||||
this.ioComplete(true);
|
||||
break;
|
||||
case 0x35: // end-of-word
|
||||
this.consoleInputFinishWord(result);
|
||||
break;
|
||||
default: // anything else, accumulate digits in word
|
||||
if (this.PZT.value) { // alphanumeric translation
|
||||
this.D.set((this.D.value % 0x1000000000)*0x100 + code);
|
||||
result.readChar(this.boundConsoleInputReceiveChar);
|
||||
} else { // numeric translation
|
||||
if ((code & 0xF0) == 0x80) {// it's a numeric code -- okay
|
||||
this.D.set((this.D.value % 0x10000000000)*0x10 + code%0x10);
|
||||
result.readChar(this.boundConsoleInputReceiveChar);
|
||||
} else if (code == 0) { // we'll take a space as a zero
|
||||
this.D.set((this.D.value % 0x10000000000)*0x10);
|
||||
result.readChar(this.boundConsoleInputReceiveChar);
|
||||
} else { // code is non-numeric -- invalid
|
||||
this.setPaperTapeCheck(1);
|
||||
this.ioComplete(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} // switch code
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3072,18 +3131,60 @@ B220Processor.prototype.execute = function execute() {
|
||||
break;
|
||||
|
||||
case 0x03: //--------------------- PRD Paper tape read
|
||||
this.setProgramCheck(1);
|
||||
this.operationComplete();
|
||||
this.opTime = 0.185; // just a guess...
|
||||
d = this.CCONTROL >>> 12; // get unit number
|
||||
if (d == 0) {
|
||||
d = 10; // xlate unit 0 to unit 10
|
||||
}
|
||||
|
||||
this.selectedUnit = d;
|
||||
this.rDigit = this.CCONTROL & 0x0F;
|
||||
this.sDigit = 1; // use word count in C (32)
|
||||
this.D.set(0);
|
||||
this.ioInitiate();
|
||||
d = this.console.inputUnitSelect(this.selectedUnit, this.boundConsoleInputInitiateNormal);
|
||||
if (d < 0) { // no unit available -- set alarm and quit
|
||||
this.setPaperTapeCheck(1);
|
||||
this.ioComplete(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x04: //--------------------- PRB Paper tape read, branch
|
||||
this.setProgramCheck(1);
|
||||
this.operationComplete();
|
||||
this.opTime = 0.185; // just a guess...
|
||||
d = this.CCONTROL >>> 12; // get unit number
|
||||
if (d == 0) {
|
||||
d = 10; // xlate unit 0 to unit 10
|
||||
}
|
||||
|
||||
this.selectedUnit = d;
|
||||
this.rDigit = (this.CCONTROL & 0x0E) | 1; // force recognition of control words
|
||||
this.sDigit = 0; // do not use word count in C (32)
|
||||
this.D.set(0);
|
||||
this.ioInitiate();
|
||||
d = this.console.inputUnitSelect(this.selectedUnit, this.boundConsoleInputInitiateNormal);
|
||||
if (d < 0) { // no unit available -- set alarm and quit
|
||||
this.setPaperTapeCheck(1);
|
||||
this.ioComplete(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x05: //--------------------- PRI Paper tape read, inverse format
|
||||
this.setProgramCheck(1);
|
||||
this.operationComplete();
|
||||
this.opTime = 0.185; // just a guess...
|
||||
d = this.CCONTROL >>> 12; // get unit number
|
||||
if (d == 0) {
|
||||
d = 10; // xlate unit 0 to unit 10
|
||||
}
|
||||
|
||||
this.selectedUnit = d;
|
||||
this.rDigit = (this.CCONTROL & 0x0E) | 1; // force recognition of control words
|
||||
this.sDigit = 1; // use word count in C (32)
|
||||
this.D.set(0);
|
||||
this.ioInitiate();
|
||||
d = this.console.inputUnitSelect(this.selectedUnit, this.boundConsoleInputInitiateInverse);
|
||||
if (d < 0) { // no unit available -- set alarm and quit
|
||||
this.setPaperTapeCheck(1);
|
||||
this.ioComplete(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x06: //--------------------- PWR Paper tape write
|
||||
@@ -3093,6 +3194,7 @@ B220Processor.prototype.execute = function execute() {
|
||||
d = 10; // xlate unit 0 to unit 10
|
||||
}
|
||||
|
||||
this.selectedUnit = d;
|
||||
this.ioInitiate();
|
||||
d = this.console.outputUnitSelect(d, this.boundConsoleOutputSign);
|
||||
if (d < 0) { // no unit available -- set alarm and quit
|
||||
@@ -3107,6 +3209,7 @@ B220Processor.prototype.execute = function execute() {
|
||||
d = 10; // xlate unit 0 to unit 10
|
||||
}
|
||||
|
||||
this.selectedUnit = d;
|
||||
d = this.console.outputUnitSelect(d, B220Processor.emptyFunction);
|
||||
if (d < 0) { // if not ready, continue in sequence
|
||||
this.opTime = 0.015;
|
||||
@@ -3762,11 +3865,6 @@ B220Processor.prototype.execute = function execute() {
|
||||
|
||||
|
||||
switch (-1) {
|
||||
case 0x00: //---------------- PTR Paper-tape/keyboard read
|
||||
this.D.set(0);
|
||||
this.togSTART = 1;
|
||||
this.consoleInputDigit();
|
||||
break;
|
||||
|
||||
case 0x40: //---------------- MTR Magnetic Tape Read
|
||||
if (!this.magTape) {
|
||||
@@ -3823,46 +3921,6 @@ B220Processor.prototype.execute = function execute() {
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x54: //---------------- CDW Card Write (Cardatron)
|
||||
if (!this.cardatron) {
|
||||
//this.schedule();
|
||||
} else {
|
||||
this.tog3IO = 1;
|
||||
this.kDigit = (this.CCONTROL >>> 8) & 0x0F;
|
||||
this.selectedUnit = (this.CCONTROL >>> 4) & 0x07;
|
||||
this.SHIFT = 0x19; // start at beginning of a word
|
||||
this.execTime -= performance.now()*B220Processor.wordsPerMilli; // mark time during I/O
|
||||
this.cardatron.outputInitiate(this.selectedUnit, this.kDigit, (this.CCONTROL >>> 12) & 0x0F,
|
||||
this.boundCardatronOutputWord, this.boundCardatronOutputFinished);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x55: //---------------- CDWI Card Write Interrogate
|
||||
this.selectedUnit = (this.CCONTROL >>> 4) & 0x07;
|
||||
if (this.cardatron && this.cardatron.outputReadyInterrogate(this.selectedUnit)) {
|
||||
this.R.set(this.CCONTROL*0x1000000);
|
||||
this.setTimingToggle(0); // stay in Execute
|
||||
this.OFT.set(1); // set overflow
|
||||
this.COP = 0x28; // make into a CC
|
||||
this.C.set((this.COP*0x10000 + this.CADDR)*0x10000 + this.CCONTROL);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x58: //---------------- CDWF Card Write Format
|
||||
if (!this.cardatron) {
|
||||
//this.schedule();
|
||||
} else {
|
||||
this.tog3IO = 1;
|
||||
this.kDigit = (this.CCONTROL >>> 8) & 0x0F;
|
||||
this.selectedUnit = (this.CCONTROL >>> 4) & 0x07;
|
||||
this.SHIFT = 0x19; // start at beginning of a word
|
||||
this.execTime -= performance.now()*B220Processor.wordsPerMilli; // mark time during I/O
|
||||
this.cardatron.outputFormatInitiate(this.selectedUnit, this.kDigit,
|
||||
this.boundCardatronOutputWord, this.boundCardatronOutputFinished);
|
||||
}
|
||||
break;
|
||||
|
||||
default: //---------------- (unimplemented instruction -- alarm)
|
||||
break;
|
||||
} // switch this.COP
|
||||
|
||||
81
software/examples/WINTER.PI.Load-Inverse.pt
Normal file
81
software/examples/WINTER.PI.Load-Inverse.pt
Normal file
@@ -0,0 +1,81 @@
|
||||
61000050500
|
||||
1005710
|
||||
4005650
|
||||
1005630
|
||||
14800100
|
||||
1505750
|
||||
4205650
|
||||
00004010001
|
||||
12105060
|
||||
1005650
|
||||
1405740
|
||||
14005680
|
||||
3705620
|
||||
4605660
|
||||
1005650
|
||||
4005640
|
||||
4205640
|
||||
00001010001
|
||||
1405630
|
||||
14900100
|
||||
1205660
|
||||
4005660
|
||||
14800100
|
||||
12705680
|
||||
1505680
|
||||
00014010001
|
||||
4005660
|
||||
12705680
|
||||
1005640
|
||||
1305730
|
||||
4005640
|
||||
3605340
|
||||
1405660
|
||||
14005660
|
||||
12105160
|
||||
142705650
|
||||
1005660
|
||||
14800100
|
||||
1505630
|
||||
1205670
|
||||
14005670
|
||||
14800030
|
||||
1205760
|
||||
4900010
|
||||
14900010
|
||||
1205760
|
||||
4900010
|
||||
14900010
|
||||
1205760
|
||||
4900010
|
||||
14900010
|
||||
1205760
|
||||
4900020
|
||||
24300000
|
||||
4005640
|
||||
100905640
|
||||
4052605690
|
||||
1005690
|
||||
1805700
|
||||
13405080
|
||||
100905770
|
||||
4605690
|
||||
3005080
|
||||
75570
|
||||
100000
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
500
|
||||
28000
|
||||
0
|
||||
10
|
||||
20
|
||||
50
|
||||
800
|
||||
10000405776
|
||||
20202021616
|
||||
60000300500
|
||||
80
software/examples/WINTER.PI.Load.pt
Normal file
80
software/examples/WINTER.PI.Load.pt
Normal file
@@ -0,0 +1,80 @@
|
||||
61000040500
|
||||
00000100571
|
||||
00000400565
|
||||
00000100563
|
||||
00001480010
|
||||
00000150575
|
||||
00000420565
|
||||
10000401000
|
||||
00001210506
|
||||
00000100565
|
||||
00000140574
|
||||
00001400568
|
||||
00000370562
|
||||
00000460566
|
||||
00000100565
|
||||
00000400564
|
||||
00000420564
|
||||
10000101000
|
||||
00000140563
|
||||
00001490010
|
||||
00000120566
|
||||
00000400566
|
||||
00001480010
|
||||
00001270568
|
||||
00000150568
|
||||
10001401000
|
||||
00000400566
|
||||
00001270568
|
||||
00000100564
|
||||
00000130573
|
||||
00000400564
|
||||
00000360534
|
||||
00000140566
|
||||
00001400566
|
||||
00001210516
|
||||
00014270565
|
||||
00000100566
|
||||
00001480010
|
||||
00000150563
|
||||
00000120567
|
||||
00001400567
|
||||
00001480003
|
||||
00000120576
|
||||
00000490001
|
||||
00001490001
|
||||
00000120576
|
||||
00000490001
|
||||
00001490001
|
||||
00000120576
|
||||
00000490001
|
||||
00001490001
|
||||
00000120576
|
||||
00000490002
|
||||
00002430000
|
||||
00000400564
|
||||
00010090564
|
||||
00405260569
|
||||
00000100569
|
||||
00000180570
|
||||
00001340508
|
||||
00010090577
|
||||
00000460569
|
||||
00000300508
|
||||
00000007557
|
||||
00000010000
|
||||
00000000000
|
||||
00000000000
|
||||
00000000000
|
||||
00000000000
|
||||
00000000000
|
||||
00000000000
|
||||
00000000050
|
||||
00000002800
|
||||
00000000000
|
||||
00000000001
|
||||
00000000002
|
||||
00000000005
|
||||
00000000080
|
||||
2___||
|
||||
60000300500
|
||||
@@ -38,13 +38,12 @@
|
||||
<script src="./B220DataFile.js"></script>
|
||||
<script src="./B220MagTapeDrive.js"></script>
|
||||
<script src="./B220MagTapeControl.js"></script>
|
||||
|
||||
<script src="./B220ConsoleInput.js"></script>
|
||||
-->
|
||||
|
||||
<script src="./B220ConsoleKeyboard.js"></script>
|
||||
<script src="./B220ConsolePrinter.js"></script>
|
||||
<script src="./B220PaperTapePunch.js"></script>
|
||||
<script src="./B220PaperTapeReader.js"></script>
|
||||
<script src="./B220ControlConsole.js"></script>
|
||||
|
||||
<script src="./B220.js"></script>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
/**************************************/
|
||||
function B220CardatronControl(p) {
|
||||
/* Constructor for the CardatronControl object */
|
||||
var left = 660; // left window margin
|
||||
var left = 600; // left window margin
|
||||
var u; // unit config object
|
||||
var x; // unit index
|
||||
|
||||
@@ -27,7 +27,8 @@ function B220CardatronControl(p) {
|
||||
|
||||
this.doc = null;
|
||||
this.window = window.open("../webUI/B220CardatronControl.html", this.mnemonic,
|
||||
"location=no,scrollbars=no,resizable,width=140,height=140,top=0,left=" + left);
|
||||
"location=no,scrollbars=no,resizable,width=140,height=140,left=" + left +
|
||||
",top=" + (screen.availHeight-140));
|
||||
this.window.addEventListener("load",
|
||||
B220Util.bindMethod(this, B220CardatronControl.prototype.cardatronOnLoad));
|
||||
|
||||
@@ -168,6 +169,8 @@ B220CardatronControl.prototype.cardatronOnLoad = function cardatronOnLoad() {
|
||||
B220Util.bindMethod(this, B220CardatronControl.prototype.ClearBtn_onClick));
|
||||
|
||||
this.clear();
|
||||
|
||||
this.window.moveTo(this.window.screenX, screen.availHeight - this.window.outerHeight);
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
|
||||
@@ -65,7 +65,8 @@ function B220CardatronInput(mnemonic, unitIndex, config) {
|
||||
this.formatSelectList = null;
|
||||
this.window = window.open("../webUI/B220CardatronInput.html", mnemonic,
|
||||
"location=no,scrollbars,resizable,width=" + w + ",height=" + h +
|
||||
",left=" + (unitIndex*24) + ",top=" + (unitIndex*24));
|
||||
",left=" + ((unitIndex-1)*32) +
|
||||
",top=" + (screen.availHeight - h - (unitIndex-1)*32));
|
||||
this.window.addEventListener("load",
|
||||
B220Util.bindMethod(this, B220CardatronInput.prototype.readerOnLoad), false);
|
||||
}
|
||||
@@ -522,7 +523,7 @@ B220CardatronInput.prototype.finishCardRead = function finishCardRead() {
|
||||
c = card.charCodeAt(col); // translate char to buffer code
|
||||
if (c < 0x80) {
|
||||
c = this.cardFilter[c];
|
||||
} else if (c == 0xA4) { // the "lozenge" ("¤")
|
||||
} else if (c == 0xA4) { // the "lozenge" ("¤")
|
||||
c = this.cardFilter[0x3C]; // use the code for "<"
|
||||
} else {
|
||||
c = 0;
|
||||
@@ -632,6 +633,8 @@ B220CardatronInput.prototype.readerOnLoad = function readerOnLoad() {
|
||||
|
||||
this.window.resizeBy(de.scrollWidth - this.window.innerWidth + 4, // kludge for right-padding/margin
|
||||
de.scrollHeight - this.window.innerHeight);
|
||||
|
||||
this.window.moveTo(0, screen.availHeight - this.window.outerHeight - (this.unitIndex-1)*32);
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
|
||||
@@ -68,7 +68,7 @@ function B220CardatronOutput(mnemonic, unitIndex, config) {
|
||||
this.window = window.open("../webUI/B220CardatronOutput.html", mnemonic,
|
||||
"location=no,scrollbars,resizable,width=" + w + ",height=" + h +
|
||||
",left=" + (screen.availWidth - w) +
|
||||
",top=" + (screen.availHeight - h - (unitIndex-1)*24));
|
||||
",top=" + (screen.availHeight - h - (unitIndex-3)*32));
|
||||
this.window.addEventListener("load",
|
||||
B220Util.bindMethod(this, B220CardatronOutput.prototype.deviceOnLoad), false);
|
||||
}
|
||||
@@ -786,6 +786,9 @@ B220CardatronOutput.prototype.deviceOnLoad = function deviceOnLoad() {
|
||||
this.$$("COGreenbarCheck").addEventListener("click",
|
||||
B220Util.bindMethod(this, B220CardatronOutput.prototype.COGreenbarCheck_onClick), false);
|
||||
}
|
||||
|
||||
this.window.moveTo(screen.availWidth - this.window.outerWidth,
|
||||
screen.availHeight - this.window.outerHeight - (7-this.unitIndex)*32);
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
|
||||
@@ -18,6 +18,7 @@ function B220ControlConsole(p, systemShutdown) {
|
||||
var h = 600;
|
||||
var w = 1064;
|
||||
var mnemonic = "ControlConsole";
|
||||
var inputConfig = p.config.getNode("ConsoleInput");
|
||||
var outputConfig = p.config.getNode("ConsoleOutput");
|
||||
var u;
|
||||
var x;
|
||||
@@ -36,8 +37,34 @@ function B220ControlConsole(p, systemShutdown) {
|
||||
this.boundResetTimer = B220Util.bindMethod(this, B220ControlConsole.prototype.resetTimer);
|
||||
this.boundUpdatePanel = B220Util.bindMethod(this, B220ControlConsole.prototype.updatePanel);
|
||||
|
||||
// Configure the console input unit objects. These are paper-tape readers.
|
||||
this.inputUnit = [
|
||||
null, // unit[0] not used
|
||||
null, // 1=unit A
|
||||
null, // 2=unit B
|
||||
null, // 3=unit C
|
||||
null, // 4=unit D
|
||||
null, // 5=unit E
|
||||
null, // 6=unit F
|
||||
null, // 7=unit G
|
||||
null, // 8=unit H
|
||||
null, // 9=unit I
|
||||
null]; //10=unit J
|
||||
|
||||
for (x=1; x<inputConfig.units.length; ++x) {
|
||||
u = inputConfig.units[x];
|
||||
switch (u.type.substring(0, 3)) {
|
||||
case "PTR":
|
||||
this.inputUnit[x] = new B220PaperTapeReader(u.type, x, this.config);
|
||||
break;
|
||||
default:
|
||||
this.inputUnit[x] = null;
|
||||
break;
|
||||
} // switch u.type
|
||||
}
|
||||
|
||||
// Configure the console output unit objects. These can be any combination
|
||||
// of paper tape punches and teletype printers.
|
||||
// of paper-tape punches and teletype printers.
|
||||
this.outputUnit = [
|
||||
null, // 0=unit A (usually the SPO)
|
||||
null, // 1=unit B
|
||||
@@ -717,6 +744,8 @@ B220ControlConsole.prototype.consoleOnLoad = function consoleOnLoad() {
|
||||
|
||||
this.$$("EmulatorVersion").textContent = B220Processor.version;
|
||||
|
||||
this.window.moveTo(screen.availWidth - this.window.outerWidth, 0);
|
||||
|
||||
// Power on the system by default...
|
||||
setCallback(this.mnemonic, this, 1000, function powerOnTimer() {
|
||||
this.powerOnSystem();
|
||||
@@ -755,6 +784,30 @@ B220ControlConsole.prototype.outputUnitSelect = function outputUnitSelect(unitNr
|
||||
return result;
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220ControlConsole.prototype.inputUnitSelect = function inputUnitSelect(unitNr, successor) {
|
||||
/* Prepares for paper-tape input by selecting the first ready device
|
||||
having a unitMask matching the unitNr parameter. If one is found, returns
|
||||
that index and schedules initiateInput() for the unit. If no such unit is
|
||||
found, returns -1 */
|
||||
var result = -1; // be pessimistic
|
||||
var u = null; // input unit object
|
||||
var x; // for loop index
|
||||
|
||||
for (x=1; x<this.inputUnit.length; ++x) {
|
||||
u = this.inputUnit[x];
|
||||
if (u && u.ready) {
|
||||
if (u.unitMask & B220Processor.pow2[unitNr]) {
|
||||
result = x;
|
||||
setCallback(this.mnemonic, u, 1, u.initiateInput, successor);
|
||||
break; // out of for loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220ControlConsole.prototype.shutDown = function shutDown() {
|
||||
/* Shuts down the panel */
|
||||
@@ -774,5 +827,12 @@ B220ControlConsole.prototype.shutDown = function shutDown() {
|
||||
}
|
||||
}
|
||||
|
||||
for (x=1; x<this.inputUnit.length; ++x) {
|
||||
if (this.inputUnit[x]) {
|
||||
this.inputUnit[x].shutDown();
|
||||
this.inputUnit[x] = null;
|
||||
}
|
||||
}
|
||||
|
||||
this.window.close();
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
CACHE MANIFEST
|
||||
# retro-220 emulator 0.02, 2017-05-24 09:00
|
||||
# retro-220 emulator 0.03, 2017-05-29 13:30
|
||||
CACHE:
|
||||
../emulator/B220Processor.js
|
||||
B220.css
|
||||
@@ -16,8 +16,6 @@ B220CardatronOutput.html
|
||||
B220CardatronOutput.js
|
||||
B220CardatronZeroSuppressPanel.html
|
||||
B220Common.css
|
||||
#B220ConsoleInput.css
|
||||
#B220ConsoleInput.js
|
||||
B220ConsoleKeyboard.css
|
||||
B220ConsoleKeyboard.html
|
||||
B220ConsoleKeyboard.js
|
||||
@@ -43,7 +41,9 @@ B220PanelUtil.js
|
||||
B220PaperTapePunch.css
|
||||
B220PaperTapePunch.html
|
||||
B220PaperTapePunch.js
|
||||
#B220PaperTapeReader.html
|
||||
B220PaperTapeReader.css
|
||||
B220PaperTapeReader.html
|
||||
B220PaperTapeReader.js
|
||||
B220SetCallback.js
|
||||
B220SystemConfig.css
|
||||
B220SystemConfig.html
|
||||
|
||||
@@ -26,36 +26,6 @@
|
||||
margin: 4px;
|
||||
border-radius: 8px}
|
||||
|
||||
#PunchTape {
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
top: 60px;
|
||||
bottom: 8px;
|
||||
min-height: 32px;
|
||||
min-width: 120px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
color: black;
|
||||
background-color: white;
|
||||
padding: 4px;
|
||||
border: 1px solid gray}
|
||||
|
||||
#Paper {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding: 0}
|
||||
|
||||
#EndOfPaper {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
opacity: 0}
|
||||
#EndOfPaper.hidden {
|
||||
display: none}
|
||||
|
||||
#RemoteSwitch {
|
||||
position: absolute;
|
||||
width: 24px;
|
||||
@@ -92,3 +62,33 @@
|
||||
width: 64px;
|
||||
right: 8px;
|
||||
top: 6px}
|
||||
|
||||
#PunchTape {
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
top: 60px;
|
||||
bottom: 8px;
|
||||
min-height: 32px;
|
||||
min-width: 120px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
color: black;
|
||||
background-color: white;
|
||||
padding: 4px;
|
||||
border: 1px solid gray}
|
||||
|
||||
#Paper {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding: 0}
|
||||
|
||||
#EndOfPaper {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
opacity: 0}
|
||||
#EndOfPaper.hidden {
|
||||
display: none}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
/**************************************/
|
||||
function B220PaperTapePunch(mnemonic, unitIndex, config) {
|
||||
/* Constructor for the Console Paper Tape Punch object */
|
||||
var top = unitIndex*32;
|
||||
var left = unitIndex*32;
|
||||
var top = unitIndex*32 + 360;
|
||||
var left = (unitIndex-1)*32;
|
||||
|
||||
this.config = config; // System configuration object
|
||||
this.mnemonic = mnemonic; // Unit mnemonic
|
||||
@@ -25,8 +25,6 @@ function B220PaperTapePunch(mnemonic, unitIndex, config) {
|
||||
|
||||
this.nextCharTime = 0; // next time a character can be punched
|
||||
this.unitMask = 0; // unit selection mask
|
||||
this.unitSwitch = new Array(11); // unit selection switch objects
|
||||
this.tabStop = []; // 0-relative tab stop positions
|
||||
|
||||
this.boundFlipSwitch = B220Util.bindMethod(this, B220PaperTapePunch.prototype.flipSwitch);
|
||||
this.boundReceiveSign = B220Util.bindMethod(this, B220PaperTapePunch.prototype.receiveSign);
|
||||
@@ -57,18 +55,19 @@ B220PaperTapePunch.maxScrollLines = 45000;
|
||||
|
||||
B220PaperTapePunch.codeXlate = [ // translate internal B220 code to ANSI
|
||||
// Note that ANSI new-line sequences are used for end-of-word characters,
|
||||
// so B220 carriage-return translates to "|". To avoide space-expansion of
|
||||
// tab characters, they are translated to "~".
|
||||
" ", "?", " ", ".", "\u00A4", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 00-0F
|
||||
"&", "?", "?", "$", "*", "\f", "|", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 10-1F
|
||||
"-", "/", "?", ",", "%", "?", "~", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 20-2F
|
||||
"?", "?", "?", "#", "@", "!", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 30-3F
|
||||
"?", "A", "B", "C", "D", "E", "F", "G", "H", "I", "?", "?", "?", "?", "?", "?", // 40-4F
|
||||
"?", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "?", "?", "?", "?", "?", "?", // 50-5F
|
||||
"?", "?", "S", "T", "U", "V", "W", "X", "Y", "Z", "?", "?", "?", "?", "?", "?", // 60-6F
|
||||
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 70-7F
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "?", "?", "?", "?", "?", "?", // 80-8F
|
||||
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]; // 90-9F
|
||||
// so B220 carriage-return (16) translates to "|". To avoid space-expansion
|
||||
// of tabs (26), they are translated to "~". The 02 "blank" code is "_".
|
||||
// Form-feed (15) translates to "^".
|
||||
" ", "?", "_", ".", "\u00A4", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 00-0F
|
||||
"&", "?", "?", "$", "*", "^", "|", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 10-1F
|
||||
"-", "/", "?", ",", "%", "?", "~", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 20-2F
|
||||
"?", "?", "?", "#", "@", "!", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 30-3F
|
||||
"?", "A", "B", "C", "D", "E", "F", "G", "H", "I", "?", "?", "?", "?", "?", "?", // 40-4F
|
||||
"?", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "?", "?", "?", "?", "?", "?", // 50-5F
|
||||
"?", "?", "S", "T", "U", "V", "W", "X", "Y", "Z", "?", "?", "?", "?", "?", "?", // 60-6F
|
||||
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 70-7F
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "?", "?", "?", "?", "?", "?", // 80-8F
|
||||
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]; // 90-9F
|
||||
|
||||
|
||||
/**************************************/
|
||||
@@ -79,16 +78,6 @@ B220PaperTapePunch.prototype.clear = function clear() {
|
||||
this.busy = false; // busy status
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapePunch.prototype.beforeUnload = function beforeUnload(ev) {
|
||||
var msg = "Closing this window will make the device unusable.\n" +
|
||||
"Suggest you stay on the page and minimize this window instead";
|
||||
|
||||
ev.preventDefault();
|
||||
ev.returnValue = msg;
|
||||
return msg;
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapePunch.prototype.$$ = function $$(e) {
|
||||
return this.doc.getElementById(e);
|
||||
@@ -136,6 +125,16 @@ B220PaperTapePunch.prototype.punchChar = function punchChar(code) {
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapePunch.prototype.beforeUnload = function beforeUnload(ev) {
|
||||
var msg = "Closing this window will make the device unusable.\n" +
|
||||
"Suggest you stay on the page and minimize this window instead";
|
||||
|
||||
ev.preventDefault();
|
||||
ev.returnValue = msg;
|
||||
return msg;
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapePunch.prototype.resizeWindow = function resizeWindow(ev) {
|
||||
/* Handles the window onresize event by scrolling the "tape" so it remains at the end */
|
||||
@@ -202,13 +201,13 @@ B220PaperTapePunch.prototype.flipSwitch = function flipSwitch(ev) {
|
||||
B220PaperTapePunch.prototype.punchOnLoad = function punchOnLoad() {
|
||||
/* Initializes the Paper Tape Punch window and user interface */
|
||||
var body;
|
||||
var id;
|
||||
var mask;
|
||||
var prefs = this.config.getNode("ConsoleOutput.units", this.unitIndex);
|
||||
var x;
|
||||
|
||||
this.doc = this.window.document;
|
||||
this.doc.title = "retro-220 Punch - " + this.mnemonic;
|
||||
|
||||
this.punchTape = this.$$("Paper");
|
||||
this.punchEOP = this.$$("EndOfPaper");
|
||||
this.punchEmptyPaper();
|
||||
@@ -248,8 +247,8 @@ B220PaperTapePunch.prototype.punchOnLoad = function punchOnLoad() {
|
||||
this.remoteSwitch.addEventListener("click", this.boundFlipSwitch);
|
||||
this.unitDesignateKnob.addEventListener("change", this.boundFlipSwitch);
|
||||
|
||||
//this.punchWin.moveTo(screen.availWidth-this.punchWin.outerWidth,
|
||||
// screen.availHeight-this.punchWin.outerHeight);
|
||||
//this.punchWin.resizeBy(screen.availWidth - this.punchWin.outerWidth,
|
||||
// screen.availHeight - this.punchWin.outerHeight);
|
||||
//this.punchWin.moveTo(0, 430);
|
||||
this.window.focus();
|
||||
};
|
||||
|
||||
108
webUI/B220PaperTapeReader.css
Normal file
108
webUI/B220PaperTapeReader.css
Normal file
@@ -0,0 +1,108 @@
|
||||
/***********************************************************************
|
||||
* retro-220/webUI B220PaperTapeReader.css
|
||||
************************************************************************
|
||||
* Copyright (c) 2017, Paul Kimpel.
|
||||
* Licensed under the MIT License, see
|
||||
* http://www.opensource.org/licenses/mit-license.php.
|
||||
************************************************************************
|
||||
* Burroughs 220 emulator Paper Tape Reader interface style sheet.
|
||||
************************************************************************
|
||||
* 2017-05-27 P.Kimpel
|
||||
* Original version, from retro-205 D205ConsoleInput.css.
|
||||
***********************************************************************/
|
||||
|
||||
#ReaderBody {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
overflow: hidden;
|
||||
padding: 0}
|
||||
|
||||
#PaperTapeReader {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 4px;
|
||||
border-radius: 8px}
|
||||
|
||||
#RemoteSwitch {
|
||||
position: absolute;
|
||||
width: 24px;
|
||||
left: 18px;
|
||||
top: 12px}
|
||||
#RemoteSwitchOn {
|
||||
width: 36px;
|
||||
left: 12px;
|
||||
top: 6px}
|
||||
#RemoteSwitchOff {
|
||||
width: 36px;
|
||||
left: 12px;
|
||||
top: 42px}
|
||||
|
||||
#ReadyLamp {
|
||||
position: absolute;
|
||||
width: 24px;
|
||||
left: 56px;
|
||||
top: 14px}
|
||||
#ReadyLampCaption {
|
||||
width: 36px;
|
||||
left: 52px;
|
||||
top: 6px}
|
||||
|
||||
#SpeedSwitch {
|
||||
position: absolute;
|
||||
width: 24px;
|
||||
left: 96px;
|
||||
top: 12px}
|
||||
#SpeedSwitchHi {
|
||||
width: 36px;
|
||||
left: 92px;
|
||||
top: 6px}
|
||||
#SpeedSwitchLow {
|
||||
width: 36px;
|
||||
left: 92px;
|
||||
top: 42px}
|
||||
#SpeedSwitchCaption {
|
||||
width: 36px;
|
||||
left: 120px;
|
||||
top: 24px}
|
||||
|
||||
#UnitDesignateKnob {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: 64px;
|
||||
right: 8px;
|
||||
top: 18px;
|
||||
color: white;
|
||||
background-color: #333}
|
||||
#UnitDesignateKnobCaption {
|
||||
width: 64px;
|
||||
right: 8px;
|
||||
top: 6px}
|
||||
|
||||
#PRFileSelector {
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
top: 60px;
|
||||
width: calc(100% - 16px);
|
||||
color: black;
|
||||
border: 1px solid #666}
|
||||
|
||||
#PRTapeSupplyBar {
|
||||
position: absolute;
|
||||
top: 92px;
|
||||
left: 8px;
|
||||
width: calc(100% - 16px);
|
||||
height: 16px;
|
||||
border: 1px solid #666}
|
||||
|
||||
#PRTapeView {
|
||||
position: absolute;
|
||||
text-align: right;
|
||||
bottom: 8px;
|
||||
left: 8px;
|
||||
width: calc(100% - 16px);
|
||||
height: 2em;
|
||||
background-color: white;
|
||||
border: none}
|
||||
61
webUI/B220PaperTapeReader.html
Normal file
61
webUI/B220PaperTapeReader.html
Normal file
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>retro-220 Emulator Paper Tape Reader</title>
|
||||
<!--
|
||||
/***********************************************************************
|
||||
* retro-220/webUI B220PaperTapeReader.html
|
||||
************************************************************************
|
||||
* Copyright (c) 2017, Paul Kimpel.
|
||||
* Licensed under the MIT License, see
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
************************************************************************
|
||||
* Burroughs 220 Paper Tape Reader device page.
|
||||
************************************************************************
|
||||
* 2017-05-27 P.Kimpel
|
||||
* Original version, from retro-205 D205PaperTapeReader.html.
|
||||
***********************************************************************/
|
||||
-->
|
||||
<meta name="Author" content="Paul Kimpel">
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript">
|
||||
<meta http-equiv="Content-Style-Type" content="text/css">
|
||||
<link id=defaultStyleSheet rel=stylesheet type="text/css" href="B220Common.css">
|
||||
<link id=tapeReaderStyleSheet rel=stylesheet type="text/css" href="B220PaperTapeReader.css">
|
||||
</head>
|
||||
|
||||
<body id=ReaderBody class=deviceBody>
|
||||
|
||||
<div id=PaperTapeReader class=panelSurface>
|
||||
<div id=RemoteSwitchOn class=caption>REMOTE</div>
|
||||
<div id=RemoteSwitchOff class=caption>LOCAL</div>
|
||||
|
||||
<div id=ReadyLampCaption class=caption>READY</div>
|
||||
|
||||
<div id=SpeedSwitchHi class=caption>HI</div>
|
||||
<div id=SpeedSwitchLow class=caption>LOW</div>
|
||||
<div id=SpeedSwitchCaption class=caption>SPEED</div>
|
||||
|
||||
<div id=UnitDesignateKnobCaption class=caption>UNIT DESIGNATE</div>
|
||||
<select id=UnitDesignateKnob>
|
||||
<option value= 0>SPO
|
||||
<option value= 1>1
|
||||
<option value= 2>2
|
||||
<option value= 3>3
|
||||
<option value= 4>4
|
||||
<option value= 5>5
|
||||
<option value= 6>6
|
||||
<option value= 7>7
|
||||
<option value= 8>8
|
||||
<option value= 9>9
|
||||
<option value=10>0
|
||||
<option value=99>OFF
|
||||
</select>
|
||||
|
||||
<input id=PRFileSelector type=file size=60 multiple>
|
||||
<meter id=PRTapeSupplyBar min=0 max=100 value=0 title="Click to clear input tape"></meter>
|
||||
<input id=PRTapeView type=text READONLY>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
412
webUI/B220PaperTapeReader.js
Normal file
412
webUI/B220PaperTapeReader.js
Normal file
@@ -0,0 +1,412 @@
|
||||
/***********************************************************************
|
||||
* retro-220/webUI B220PaperTapeReader.js
|
||||
************************************************************************
|
||||
* Copyright (c) 2017, Paul Kimpel.
|
||||
* Licensed under the MIT License, see
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
************************************************************************
|
||||
* Burroughs 220 Paper Tape Reader module.
|
||||
*
|
||||
* Defines the paper tape input devices.
|
||||
*
|
||||
************************************************************************
|
||||
* 2017-05-27 P.Kimpel
|
||||
* Original version, from retro-205 D205ConsoleInput.js.
|
||||
***********************************************************************/
|
||||
"use strict";
|
||||
|
||||
/**************************************/
|
||||
function B220PaperTapeReader(mnemonic, unitIndex, config) {
|
||||
/* Constructor for the PaperTapeReader object */
|
||||
var top = unitIndex*32 + 360;
|
||||
var left = (unitIndex-1)*32 + 250;
|
||||
|
||||
this.config = config; // System configuration object
|
||||
this.mnemonic = mnemonic; // Unit mnemonic
|
||||
this.unitIndex = unitIndex; // Unit index into console output units
|
||||
this.inTimer = 0; // input setCallback() token
|
||||
|
||||
this.charPeriod = B220PaperTapeReader.highSpeedPeriod;
|
||||
// paper-tape reader speed [ms/char]
|
||||
this.nextCharTime = 0; // next time a character can be read
|
||||
this.unitMask = 0; // unit selection mask
|
||||
|
||||
this.boundFlipSwitch = B220Util.bindMethod(this, B220PaperTapeReader.prototype.flipSwitch);
|
||||
this.boundReadTapeChar = B220Util.bindMethod(this, B220PaperTapeReader.prototype.readTapeChar);
|
||||
|
||||
this.readResult = { // object passed back to Processor for each read
|
||||
code: 0,
|
||||
readChar: this.boundReadTapeChar
|
||||
};
|
||||
|
||||
this.clear();
|
||||
|
||||
// Create the reader window and onload event
|
||||
this.doc = null;
|
||||
this.tapeSupplyBar = null;
|
||||
this.tapeView = null;
|
||||
this.window = window.open("../webUI/B220PaperTapeReader.html", mnemonic,
|
||||
"location=no,scrollbars=no,resizable,width=420,height=160,left=" + left + ",top=" + top);
|
||||
this.window.addEventListener("load",
|
||||
B220Util.bindMethod(this, B220PaperTapeReader.prototype.readerOnload), false);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.offSwitchImage = "./resources/ToggleDown.png";
|
||||
B220PaperTapeReader.onSwitchImage = "./resources/ToggleUp.png";
|
||||
|
||||
B220PaperTapeReader.lowSpeedPeriod = 1000/500;
|
||||
// low reader speed: 500 cps
|
||||
B220PaperTapeReader.highSpeedPeriod = 1000/1000;
|
||||
// high reader speed: 1000 cps
|
||||
B220PaperTapeReader.startupTime = 5; // reader start-up delay, ms
|
||||
B220PaperTapeReader.idleTime = 50; // idle time before reader requires start-up delay, ms
|
||||
|
||||
// Translate ANSI character codes to B220 charater codes.
|
||||
// Note that ANSI new-line sequences are used for end-of-word characters,
|
||||
// so "|" translates to B220 carriage-return (16). To avoid space-expansion
|
||||
// of tabs, "~" translates to tab (26). "_" translates to the "blank" code (02).
|
||||
// "^" translates to form-feed (15).
|
||||
B220PaperTapeReader.xlate220 = [
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x26, 0x16, 0x17, 0x15, 0x16, 0x17, 0x17, // 00-0F
|
||||
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // 10-1F
|
||||
0x00, 0x17, 0x17, 0x33, 0x13, 0x24, 0x10, 0x34, 0x24, 0x04, 0x14, 0x10, 0x23, 0x20, 0x03, 0x21, // 20-2F
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x17, 0x13, 0x04, 0x33, 0x17, 0x17, // 30-3F
|
||||
0x34, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, // 40-4F
|
||||
0x57, 0x58, 0x59, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x17, 0x17, 0x17, 0x15, 0x02, // 50-5F
|
||||
0x17, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, // 60-6F
|
||||
0x57, 0x58, 0x59, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x17, 0x16, 0x17, 0x26, 0x17, // 70-7F
|
||||
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // 80-8F
|
||||
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // 90-9F
|
||||
0x17, 0x17, 0x17, 0x17, 0x04, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // A0-AF
|
||||
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // B0-BF
|
||||
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // C0-CF
|
||||
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // D0-DF
|
||||
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, // E0-EF
|
||||
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17];// F0-FF
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.clear = function clear() {
|
||||
/* Initializes (and if necessary, creates) the reader unit state */
|
||||
|
||||
this.ready = false; // a tape has been loaded into the reader
|
||||
this.busy = false; // a request for a digit is outstanding
|
||||
this.pendingReceiver = null; // stashed digit-receiver function
|
||||
|
||||
this.buffer = ""; // reader input buffer (paper-tape reel)
|
||||
this.bufLength = 0; // current input buffer length (characters)
|
||||
this.bufIndex = 0; // 0-relative offset to next character to be read
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.$$ = function $$(e) {
|
||||
return this.doc.getElementById(e);
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.PRTapeSupplyBar_onclick = function PRTapeSupplyBar_onclick(ev) {
|
||||
/* Handle the click event for the "input hopper" meter bar */
|
||||
|
||||
if (!this.ready) {
|
||||
if (this.window.confirm((this.bufLength-this.bufIndex).toString() + " of " + this.bufLength.toString() +
|
||||
" characters remaining to read.\nDo you want to clear the reader input?")) {
|
||||
this.tapeView.value = "";
|
||||
this.setReaderEmpty();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.fileSelector_onChange = function fileSelector_onChange(ev) {
|
||||
/* Handle the <input type=file> onchange event when files are selected. For each
|
||||
file, load it and add it to the input buffer of the reader */
|
||||
var tape;
|
||||
var f = ev.target.files;
|
||||
var that = this;
|
||||
var x;
|
||||
|
||||
function fileLoader_onLoad(ev) {
|
||||
/* Handle the onload event for a Text FileReader */
|
||||
|
||||
if (that.bufIndex >= that.bufLength) {
|
||||
that.buffer = ev.target.result;
|
||||
} else {
|
||||
switch (that.buffer.charAt(that.buffer.length-1)) {
|
||||
case "\r":
|
||||
case "\n":
|
||||
break; // do nothing -- the last word has a delimiter
|
||||
default:
|
||||
that.buffer += "\n"; // so the next tape starts on a new line
|
||||
break;
|
||||
}
|
||||
that.buffer = that.buffer.substring(that.bufIndex) + ev.target.result;
|
||||
}
|
||||
|
||||
that.bufIndex = 0;
|
||||
that.bufLength = that.buffer.length;
|
||||
that.$$("PRTapeSupplyBar").value = that.bufLength;
|
||||
that.$$("PRTapeSupplyBar").max = that.bufLength;
|
||||
that.setReaderReady(true);
|
||||
if (that.busy && that.ready) { // reinitiate the pending read
|
||||
that.readTapeChar(that.pendingReceiver);
|
||||
that.receiver = null;
|
||||
}
|
||||
}
|
||||
|
||||
for (x=f.length-1; x>=0; x--) {
|
||||
tape = new FileReader();
|
||||
tape.onload = fileLoader_onLoad;
|
||||
tape.readAsText(f[x]);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.setReaderReady = function setReaderReady(ready) {
|
||||
/* Sets the reader to a ready or not-ready status */
|
||||
|
||||
this.ready = ready && this.remoteSwitch.state && (this.bufIndex < this.bufLength);
|
||||
this.readyLamp.set(this.ready ? 1 : 0);
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.setReaderEmpty = function setReaderEmpty() {
|
||||
/* Sets the reader to a not-ready status and empties the buffer */
|
||||
|
||||
this.setReaderReady(false);
|
||||
this.tapeSupplyBar.value = 0;
|
||||
this.buffer = ""; // discard the input buffer
|
||||
this.bufLength = 0;
|
||||
this.bufIndex = 0;
|
||||
this.fileSelector.value = null; // reset the control so the same file can be reloaded
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.beforeUnload = function beforeUnload(ev) {
|
||||
var msg = "Closing this window will make the device unusable.\n" +
|
||||
"Suggest you stay on the page and minimize this window instead";
|
||||
|
||||
ev.preventDefault();
|
||||
ev.returnValue = msg;
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.flipSwitch = function flipSwitch(ev) {
|
||||
/* Handler for switch clicks */
|
||||
var id = ev.target.id;
|
||||
var prefs = this.config.getNode("ConsoleInput.units", this.unitIndex);
|
||||
var x;
|
||||
|
||||
switch (id) {
|
||||
case "RemoteSwitch":
|
||||
this.remoteSwitch.flip();
|
||||
prefs.remote = this.remoteSwitch.state;
|
||||
this.setReaderReady(this.remoteSwitch.state != 0);
|
||||
this.fileSelector.disabled = (this.remoteSwitch.state != 0);
|
||||
break;
|
||||
case "SpeedSwitch":
|
||||
this.speedSwitch.flip();
|
||||
prefs.speed = this.speedSwitch.state;
|
||||
this.charPeriod = (this.speedSwitch.state ? B220PaperTapeReader.highSpeedPeriod : B220PaperTapeReader.lowSpeedPeriod);
|
||||
break;
|
||||
case "UnitDesignateKnob":
|
||||
x = this.unitDesignateKnob.selectedIndex;
|
||||
if (x < 0) {
|
||||
x = this.unitDesignateKnob.length-1;
|
||||
this.unitMask = 0;
|
||||
} else {
|
||||
this.unitMask = B220Processor.pow2[x];
|
||||
prefs.unitMask = this.unitMask
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this.config.putNode("ConsoleInput.units", prefs, this.unitIndex);
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.readerOnload = function readerOnload() {
|
||||
/* Initializes the reader window and user interface */
|
||||
var body;
|
||||
var mask;
|
||||
var prefs = this.config.getNode("ConsoleInput.units", this.unitIndex);
|
||||
var x;
|
||||
|
||||
this.doc = this.window.document;
|
||||
//de = this.doc.documentElement;
|
||||
this.doc.title = "retro-220 - Reader - " + this.mnemonic;
|
||||
|
||||
this.fileSelector = this.$$("PRFileSelector");
|
||||
this.tapeSupplyBar = this.$$("PRTapeSupplyBar");
|
||||
this.tapeView = this.$$("PRTapeView");
|
||||
|
||||
body = this.$$("PaperTapeReader")
|
||||
this.remoteSwitch = new ToggleSwitch(body, null, null, "RemoteSwitch",
|
||||
B220PaperTapeReader.offSwitchImage, B220PaperTapeReader.onSwitchImage);
|
||||
this.remoteSwitch.set(prefs.remote);
|
||||
|
||||
this.readyLamp = new ColoredLamp(body, null, null, "ReadyLamp", "blueLamp lampCollar", "blueLit");
|
||||
this.setReaderReady(this.remoteSwitch.state != 0);
|
||||
|
||||
this.speedSwitch = new ToggleSwitch(body, null, null, "SpeedSwitch",
|
||||
B220PaperTapeReader.offSwitchImage, B220PaperTapeReader.onSwitchImage);
|
||||
this.speedSwitch.set(prefs.speed);
|
||||
this.charPeriod = (this.speedSwitch.state ? B220PaperTapeReader.highSpeedPeriod : B220PaperTapeReader.lowSpeedPeriod);
|
||||
|
||||
this.unitDesignateKnob = this.$$("UnitDesignateKnob");
|
||||
mask = 0x001;
|
||||
this.unitMask = prefs.unitMask;
|
||||
if (this.unitMask == 0) {
|
||||
this.unitDesignateKnob.selectedIndex = this.unitDesignateKnob.length-1; // OFF
|
||||
} else {
|
||||
for (x=0; x<this.unitDesignateKnob.length; ++x) {
|
||||
if (this.unitMask & mask) {
|
||||
this.unitDesignateKnob.selectedIndex = x;
|
||||
break; // out of for loop
|
||||
} else {
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.fileSelector.disabled = (this.remoteSwitch.state != 0);
|
||||
|
||||
// Events
|
||||
this.window.addEventListener("beforeunload",
|
||||
B220PaperTapeReader.prototype.beforeUnload, false);
|
||||
this.fileSelector.addEventListener("change",
|
||||
B220Util.bindMethod(this, B220PaperTapeReader.prototype.fileSelector_onChange));
|
||||
this.tapeSupplyBar.addEventListener("click",
|
||||
B220Util.bindMethod(this, B220PaperTapeReader.prototype.PRTapeSupplyBar_onclick));
|
||||
this.remoteSwitch.addEventListener("click", this.boundFlipSwitch);
|
||||
this.speedSwitch.addEventListener("click", this.boundFlipSwitch);
|
||||
this.unitDesignateKnob.addEventListener("change", this.boundFlipSwitch);
|
||||
|
||||
//this.window.resizeBy(de.scrollWidth - this.window.innerWidth + 4, // kludge for right-padding/margin
|
||||
// de.scrollHeight - this.window.innerHeight);
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* Input Entry Points *
|
||||
***********************************************************************/
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.initiateInput = function initiateInput(successor) {
|
||||
/* Initiates input to the reader. This simply calls this.readTapeChar(),
|
||||
which returns the first tape character (which should be the sign digit) to
|
||||
the processor and gets the ball rolling */
|
||||
var stamp = performance.now();
|
||||
|
||||
if (stamp-this.nextCharTime < B220PaperTapeReader.idleTime) {
|
||||
this.readTapeChar(successor);
|
||||
} else {
|
||||
setCallback(this.mnemonic, this, B220PaperTapeReader.startupTime, this.readTapeChar, successor);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.sendTapeChar = function sendTapeChar(c, code, receiver) {
|
||||
/* Sends the character or EOW code read from the tape back to the
|
||||
Processor after an appropriate delay. Updates the TapeView display with the
|
||||
character sent */
|
||||
var delay;
|
||||
var length;
|
||||
var stamp = performance.now();
|
||||
var text = this.tapeView.value;
|
||||
|
||||
this.readResult.code = code;
|
||||
if (this.nextCharTime < stamp) {
|
||||
delay = 0;
|
||||
this.nextCharTime = stamp + this.charPeriod;
|
||||
} else {
|
||||
delay = this.nextCharTime - stamp;
|
||||
this.nextCharTime += this.charPeriod;
|
||||
}
|
||||
|
||||
this.inTimer = setCallback(this.mnemonic, this, delay, receiver, this.readResult);
|
||||
length = text.length;
|
||||
if (length < 120) {
|
||||
this.tapeView.value = text + String.fromCharCode(c);
|
||||
++length;
|
||||
} else {
|
||||
this.tapeView.value = text.substring(length-119) + String.fromCharCode(c);
|
||||
}
|
||||
this.tapeView.setSelectionRange(length-1, length);
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.readTapeChar = function readTapeChar(receiver) {
|
||||
/* Reads one character frame from the paper-tape buffer and passes it to the
|
||||
"receiver" function. If at end-of-line, passes an end-of-word (0x35) code;
|
||||
an error or invalid character is passed as a 0x17 code. Otherwise, the ANSI
|
||||
character is translated to B220 code and that code is passed.
|
||||
If the buffer is empty (this.ready=false) or we are at end of buffer,
|
||||
simply exits after stashing a reference to the receiver function in
|
||||
this.pendingReceiver. This will leave the processor hanging until more tape
|
||||
is loaded into the reader or the processor is cleared. Once more tape is
|
||||
loaded, the fileSelector_onChange event will set ready, notice the hanging
|
||||
read (this.busy=true) and restart the read */
|
||||
var bufLength = this.bufLength; // current buffer length
|
||||
var c; // current character ANSI code
|
||||
var x = this.bufIndex; // current buffer index
|
||||
|
||||
if (!this.ready) {
|
||||
this.busy = true;
|
||||
this.pendingReceiver = receiver;// stash the receiver until tape is loaded
|
||||
this.window.focus(); // call attention to the tape reader
|
||||
} else {
|
||||
this.busy = false;
|
||||
do {
|
||||
if (x >= bufLength) { // end of buffer -- send finish
|
||||
this.sendTapeChar(0x20, 0x35, receiver);
|
||||
this.setReaderEmpty();
|
||||
break; // out of do loop
|
||||
} else {
|
||||
c = this.buffer.charCodeAt(x) % 0x100;
|
||||
if (c == 0x0D) { // carriage return -- send EOW and check for LF
|
||||
if (++x < bufLength && this.buffer.charCodeAt(x) == 0x0A) {
|
||||
++x;
|
||||
}
|
||||
this.sendTapeChar(0x20, 0x35, receiver);
|
||||
if (x >= bufLength) {
|
||||
this.setReaderEmpty();
|
||||
}
|
||||
break; // out of do loop
|
||||
} else if (c == 0x0A) { // line feed -- send EOW
|
||||
++x;
|
||||
this.sendTapeChar(0x20, 0x35, receiver);
|
||||
if (x >= bufLength) {
|
||||
this.setReaderEmpty();
|
||||
}
|
||||
break; // out of do loop
|
||||
} else { // translate character and send its code
|
||||
++x;
|
||||
this.sendTapeChar(c, B220PaperTapeReader.xlate220[c], receiver);
|
||||
break; // out of do loop
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
|
||||
this.tapeSupplyBar.value = bufLength-x;
|
||||
this.bufIndex = x;
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.shutDown = function shutDown() {
|
||||
/* Shuts down the device */
|
||||
|
||||
if (this.inTimer) {
|
||||
clearCallback(this.inTimer);
|
||||
}
|
||||
|
||||
if (this.window) {
|
||||
this.window.removeEventListener("beforeunload", B220PaperTapeReader.prototype.beforeUnload, false);
|
||||
this.window.close();
|
||||
this.window = null;
|
||||
}
|
||||
};
|
||||
@@ -86,6 +86,7 @@
|
||||
#SystemMemorySize {
|
||||
text-align: center}
|
||||
|
||||
#ConsoleInputTable,
|
||||
#ConsoleOutputTable,
|
||||
#CardatronTable,
|
||||
#MagTapeOptionsTable,
|
||||
@@ -93,6 +94,8 @@
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse}
|
||||
|
||||
#ConsoleInputTable TH,
|
||||
#ConsoleInputTable TD,
|
||||
#ConsoleOutputTable TH,
|
||||
#ConsoleOutputTable TD,
|
||||
#CardatronTable TH,
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
<button id=SaveBtn class="greenButton">SAVE</button>
|
||||
<button id=DefaultsBtn class="redButton" title="Set configurartion to original defaults">SET DEFAULTS</button>
|
||||
|
||||
<div class=heading>System Properties:</div>
|
||||
|
||||
<div class=heading>System Properties:</div>
|
||||
|
||||
<select id=SystemMemorySize>
|
||||
<option value=1000>1000
|
||||
@@ -59,6 +59,295 @@
|
||||
<option value=10000>10000
|
||||
</select> Word Memory Size
|
||||
|
||||
|
||||
<div class=heading>Console Input:</div>
|
||||
|
||||
<table id=ConsoleInputTable>
|
||||
<thead>
|
||||
<th>Position<th>Type<th>1<th>2<th>3<th>4<th>5<th>6<th>7<th>8<th>9<th>10
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class=center>1
|
||||
<td class=center>
|
||||
<select id=ConsoleIn1Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=PTRA>Reader
|
||||
<select>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn1_1 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn1_2 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn1_3 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn1_4 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn1_5 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn1_6 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn1_7 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn1_8 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn1_9 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn1_10 type=checkbox value=1>
|
||||
|
||||
<tr>
|
||||
<td class=center>2
|
||||
<td class=center>
|
||||
<select id=ConsoleIn2Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=PTRB>Reader
|
||||
<select>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn2_1 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn2_2 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn2_3 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn2_4 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn2_5 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn2_6 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn2_7 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn2_8 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn2_9 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn2_10 type=checkbox value=1>
|
||||
|
||||
<tr>
|
||||
<td class=center>3
|
||||
<td class=center>
|
||||
<select id=ConsoleIn3Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=PTRC>Reader
|
||||
<select>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn3_1 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn3_2 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn3_3 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn3_4 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn3_5 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn3_6 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn3_7 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn3_8 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn3_9 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn3_10 type=checkbox value=1>
|
||||
|
||||
<tr>
|
||||
<td class=center>4
|
||||
<td class=center>
|
||||
<select id=ConsoleIn4Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=PTRD>Reader
|
||||
<select>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn4_1 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn4_2 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn4_3 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn4_4 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn4_5 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn4_6 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn4_7 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn4_8 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn4_9 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn4_10 type=checkbox value=1>
|
||||
|
||||
<tr>
|
||||
<td class=center>5
|
||||
<td class=center>
|
||||
<select id=ConsoleIn5Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=PTRE>Reader
|
||||
<select>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn5_1 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn5_2 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn5_3 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn5_4 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn5_5 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn5_6 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn5_7 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn5_8 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn5_9 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn5_10 type=checkbox value=1>
|
||||
|
||||
<tr>
|
||||
<td class=center>6
|
||||
<td class=center>
|
||||
<select id=ConsoleIn6Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=PTRF>Reader
|
||||
<select>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn6_1 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn6_2 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn6_3 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn6_4 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn6_5 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn6_6 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn6_7 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn6_8 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn6_9 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn6_10 type=checkbox value=1>
|
||||
|
||||
<tr>
|
||||
<td class=center>7
|
||||
<td class=center>
|
||||
<select id=ConsoleIn7Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=PTRG>Reader
|
||||
<select>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn7_1 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn7_2 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn7_3 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn7_4 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn7_5 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn7_6 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn7_7 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn7_8 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn7_9 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn7_10 type=checkbox value=1>
|
||||
|
||||
<tr>
|
||||
<td class=center>8
|
||||
<td class=center>
|
||||
<select id=ConsoleIn8Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=PTRH>Reader
|
||||
<select>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn8_1 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn8_2 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn8_3 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn8_4 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn8_5 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn8_6 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn8_7 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn8_8 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn8_9 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn8_10 type=checkbox value=1>
|
||||
|
||||
<tr>
|
||||
<td class=center>9
|
||||
<td class=center>
|
||||
<select id=ConsoleIn9Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=PTRI>Reader
|
||||
<select>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn9_1 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn9_2 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn9_3 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn9_4 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn9_5 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn9_6 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn9_7 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn9_8 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn9_9 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn9_10 type=checkbox value=1>
|
||||
|
||||
<tr>
|
||||
<td class=center>10
|
||||
<td class=center>
|
||||
<select id=ConsoleIn10Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=PTRJ>Reader
|
||||
<select>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn10_1 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn10_2 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn10_3 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn10_4 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn10_5 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn10_6 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn10_7 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn10_8 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn10_9 type=checkbox value=1>
|
||||
<td class=center>
|
||||
<input id=ConsoleIn10_10 type=checkbox value=1>
|
||||
</table>
|
||||
|
||||
|
||||
<div class=heading>Console Output:</div>
|
||||
|
||||
<table id=ConsoleOutputTable>
|
||||
@@ -517,6 +806,7 @@
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<div class=heading>Cardatron Unit Selection:</div>
|
||||
|
||||
<table id=CardatronTable>
|
||||
@@ -910,7 +1200,9 @@
|
||||
<td class=center>
|
||||
<input id=MagTape10NotWrite type=checkbox value=1>
|
||||
</table>
|
||||
<p> </p>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -39,6 +39,88 @@ B220SystemConfig.prototype.configStorageName = "retro-220-Config";
|
||||
B220SystemConfig.prototype.configVersion = 1;
|
||||
B220SystemConfig.prototype.flushDelay = 60000; // flush timer setting, ms
|
||||
|
||||
B220SystemConfig.defaultConfig = {
|
||||
version: this.configVersion,
|
||||
memorySize: 5000, // 11-digit words
|
||||
|
||||
ControlConsole: {
|
||||
PCS1SW: 0, // Program Control Switches 1-0
|
||||
PCS2SW: 0,
|
||||
PCS3SW: 0,
|
||||
PCS4SW: 0,
|
||||
PCS5SW: 0,
|
||||
PCW6SW: 0,
|
||||
PCS7SW: 0,
|
||||
PCS8SW: 0,
|
||||
PCS9SW: 0,
|
||||
PCS0SW: 0,
|
||||
SONSW: 0, // S-register on
|
||||
SUNITSSW: 0, // S-register units
|
||||
STOCSW: 0, // S-to-C stop
|
||||
STOPSW: 0}, // S-to-P stop
|
||||
|
||||
ConsoleInput: {
|
||||
units: [
|
||||
null, // unit[0] not used
|
||||
{type: "PTRA", unitMask: 0x002, remote: 1, speed: 0},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"}
|
||||
]},
|
||||
|
||||
ConsoleOutput: {
|
||||
units: [
|
||||
{type: "TTYA", unitMask: 0x001, remote: 1, format: 0, zeroSuppress: 0, mapMemory: 0,
|
||||
columns: 72, tabs: "9,17,25,33,41,49,57,65,73,81"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"}
|
||||
]},
|
||||
|
||||
Cardatron: {
|
||||
hasCardatron: true,
|
||||
units: [
|
||||
null, // unit[0] not used
|
||||
{type: "CR1", formatSelect: 0, formatCol: 1},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "LP2", algolGlyphs: true, greenBar: true, zeroSuppressCols: ""},
|
||||
{type: "CP1", algolGlyphs: true, greenBar: false, zeroSuppressCols: ""}
|
||||
]},
|
||||
|
||||
MagTape: {
|
||||
hasMagTape: true,
|
||||
units: [
|
||||
null, // unit[0] not used
|
||||
{type: "MTA", designate: 0, remoteSwitch: false, rewindReadySwitch: true, notWriteSwitch: false},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "MTD", designate: 3, remoteSwitch: false, rewindReadySwitch: true, notWriteSwitch: false},
|
||||
{type: "MTE", designate: 4, remoteSwitch: false, rewindReadySwitch: true, notWriteSwitch: false},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"}
|
||||
]}
|
||||
};
|
||||
|
||||
|
||||
/**************************************/
|
||||
B220SystemConfig.prototype.$$ = function $$(id) {
|
||||
return this.window.document.getElementById(id);
|
||||
@@ -53,73 +135,7 @@ B220SystemConfig.prototype.createConfigData = function createConfigData() {
|
||||
var prefs;
|
||||
var s;
|
||||
|
||||
this.configData = {
|
||||
version: this.configVersion,
|
||||
memorySize: 5000, // 11-digit words
|
||||
|
||||
ControlConsole: {
|
||||
PCS1SW: 0, // Program Control Switches 1-0
|
||||
PCS2SW: 0,
|
||||
PCS3SW: 0,
|
||||
PCS4SW: 0,
|
||||
PCS5SW: 0,
|
||||
PCW6SW: 0,
|
||||
PCS7SW: 0,
|
||||
PCS8SW: 0,
|
||||
PCS9SW: 0,
|
||||
PCS0SW: 0,
|
||||
SONSW: 0, // S-register on
|
||||
SUNITSSW: 0, // S-register units
|
||||
STOCSW: 0, // S-to-C stop
|
||||
STOPSW: 0}, // S-to-P stop
|
||||
|
||||
ConsoleOutput: {
|
||||
units: [
|
||||
{type: "TTYA", zeroSuppress: 0, mapMemory: 0, unitMask: 0x001, remote: 1, format: 0,
|
||||
columns: 72, tabs: "9,17,25,33,41,49,57,65,73,81"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"}
|
||||
]},
|
||||
|
||||
Cardatron: {
|
||||
hasCardatron: true,
|
||||
units: [
|
||||
null, // unit[0] not used
|
||||
{type: "CR1", formatSelect: 0, formatCol: 1},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "LP2", algolGlyphs: true, greenBar: true, zeroSuppressCols: ""},
|
||||
{type: "CP1", algolGlyphs: true, greenBar: false, zeroSuppressCols: ""}
|
||||
]},
|
||||
|
||||
MagTape: {
|
||||
hasMagTape: true,
|
||||
suppressBSwitch: false, // false => off => suppress B-register modification
|
||||
units: [
|
||||
null, // unit[0] not used
|
||||
{type: "MTA", designate: 0, remoteSwitch: false, rewindReadySwitch: true, notWriteSwitch: false},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "MTD", designate: 3, remoteSwitch: false, rewindReadySwitch: true, notWriteSwitch: false},
|
||||
{type: "MTE", designate: 4, remoteSwitch: false, rewindReadySwitch: true, notWriteSwitch: false},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"},
|
||||
{type: "NONE"}
|
||||
]}
|
||||
};
|
||||
|
||||
this.configData = B220SystemConfig.defaultConfig;
|
||||
this.flushHandler();
|
||||
};
|
||||
|
||||
@@ -280,7 +296,29 @@ B220SystemConfig.prototype.loadConfigDialog = function loadConfigDialog() {
|
||||
// System Properties
|
||||
this.setListValue("SystemMemorySize", cd.memorySize.toString());
|
||||
|
||||
// Console Input units
|
||||
|
||||
if (!cd.ConsoleInput) {
|
||||
cd.ConsoleInput = B220SystemConfig.defaultConfig.ConsoleInput;
|
||||
}
|
||||
|
||||
for (x=1; x<=10; ++x) {
|
||||
unit = cd.ConsoleInput.units[x];
|
||||
prefix = "ConsoleIn" + x;
|
||||
this.setListValue(prefix + "Type", unit.type);
|
||||
mask = 0x001;
|
||||
for (y=1; y<=10; ++y) {
|
||||
mask <<= 1;
|
||||
this.$$(prefix + "_" + y).checked = (unit.unitMask & mask ? true : false);
|
||||
} // for y
|
||||
} // for x
|
||||
|
||||
// Console Output units
|
||||
|
||||
if (!cd.ConsoleOutput) {
|
||||
cd.ConsoleOutput = B220SystemConfig.defaultConfig.ConsoleOutput;
|
||||
}
|
||||
|
||||
for (x=0; x<=10; ++x) {
|
||||
unit = cd.ConsoleOutput.units[x];
|
||||
prefix = "ConsoleOut" + x;
|
||||
@@ -298,6 +336,11 @@ B220SystemConfig.prototype.loadConfigDialog = function loadConfigDialog() {
|
||||
} // for x
|
||||
|
||||
// Cardatron units
|
||||
|
||||
if (!cd.Cardatron) {
|
||||
cd.Cardatron = B220SystemConfig.defaultConfig.Cardatron;
|
||||
}
|
||||
|
||||
for (x=1; x<=7; ++x) {
|
||||
unit = cd.Cardatron.units[x];
|
||||
prefix = "Cardatron" + x;
|
||||
@@ -324,6 +367,10 @@ B220SystemConfig.prototype.loadConfigDialog = function loadConfigDialog() {
|
||||
|
||||
// Magnetic Tape units
|
||||
|
||||
if (!cd.MagTape) {
|
||||
cd.MagTape = B220SystemConfig.defaultConfig.MagTape;
|
||||
}
|
||||
|
||||
this.$$("SuppressBMod").checked = !cd.MagTape.suppressBSwitch;
|
||||
for (x=1; x<=10; ++x) {
|
||||
unit = cd.MagTape.units[x];
|
||||
@@ -372,6 +419,28 @@ B220SystemConfig.prototype.saveConfigDialog = function saveConfigDialog() {
|
||||
x = parseInt(e.options[e.selectedIndex], 10);
|
||||
cd.memorySize = (isNaN(x) ? 5000 : x);
|
||||
|
||||
// Console Input units
|
||||
|
||||
for (x=1; x<=10; ++x) {
|
||||
unit = cd.ConsoleInput.units[x];
|
||||
prefix = "ConsoleIn" + x;
|
||||
e = this.$$(prefix + "Type");
|
||||
unit.type = (e.selectedIndex < 0 ? "NONE" : e.options[e.selectedIndex].value);
|
||||
mask = 0x001;
|
||||
unit.unitMask = 0;
|
||||
for (y=1; y<=10; ++y) {
|
||||
mask <<= 1;
|
||||
if (this.$$(prefix + "_" + y).checked) {
|
||||
unit.unitMask |= mask;
|
||||
}
|
||||
} // for y
|
||||
|
||||
if (unit.type != "NONE") {
|
||||
unit.remote = (unit.remote || 0);
|
||||
unit.speed = (unit.speed || 0);
|
||||
}
|
||||
} // for x
|
||||
|
||||
// Console Output units
|
||||
|
||||
for (x=0; x<=10; ++x) {
|
||||
@@ -391,10 +460,15 @@ B220SystemConfig.prototype.saveConfigDialog = function saveConfigDialog() {
|
||||
}
|
||||
} // for y
|
||||
|
||||
e = this.$$(prefix + "Format");
|
||||
unit.format = (e.selectedIndex < 0 ? "NONE" : e.options[e.selectedIndex].value);
|
||||
unit.columns = (unit.columns ? unit.columns : 72);
|
||||
unit.tabs = (unit.tabs ? unit.tabs : "1,9,17,25,33,41,49,57,65,73");
|
||||
if (unit.type != "NONE") {
|
||||
unit.remote = (unit.remote || 0);
|
||||
unit.zeroSuppress = (unit.zeroSuppress || 0);
|
||||
unit.mapMemory = (unit.mapMemory || 0);
|
||||
e = this.$$(prefix + "Format");
|
||||
unit.format = (e.selectedIndex < 0 ? "NONE" : e.options[e.selectedIndex].value);
|
||||
unit.columns = (unit.columns ? unit.columns : 72);
|
||||
unit.tabs = (unit.tabs ? unit.tabs : "1,9,17,25,33,41,49,57,65,73");
|
||||
}
|
||||
} // for x
|
||||
|
||||
// Cardatron units
|
||||
@@ -410,14 +484,18 @@ B220SystemConfig.prototype.saveConfigDialog = function saveConfigDialog() {
|
||||
cd.Cardatron.hasCardatron = true;
|
||||
unit.algolGlyphs = this.$$(prefix + "AlgolGlyphs").checked;
|
||||
unit.greenBar = this.$$(prefix + "Greenbar").checked;
|
||||
unit.zeroSuppressCols = (unit.zeroSuppressCols || "");
|
||||
break;
|
||||
case "CP":
|
||||
cd.Cardatron.hasCardatron = true;
|
||||
unit.algolGlyphs = this.$$(prefix + "AlgolGlyphs").checked;
|
||||
unit.greenBar = false;
|
||||
unit.zeroSuppressCols = (unit.zeroSuppressCols || "");
|
||||
break;
|
||||
case "CR":
|
||||
cd.Cardatron.hasCardatron = true;
|
||||
unit.formatSelect = (unit.formatSelect || 0);
|
||||
unit.formatCol = (unit.formatCol === undefined ? 1 : unit.formatCol)
|
||||
// no break
|
||||
default:
|
||||
unit.algolGlyphs = false;
|
||||
|
||||
Reference in New Issue
Block a user