mirror of
https://github.com/pkimpel/retro-220.git
synced 2026-01-24 11:21:29 +00:00
1. Commit original paper tape images B220_Paper_Tapes.zip and TR1101_TR1301.zip archives from http://bitsavers.org/bits/Burroughs/B220/. 2. Update and reorganize software/Diagnostics folder; Add README.txt. 3. Commit Michael Mahon's consolidation of the TR1202..TR1206 tests as Mahon-Regression-Test.pt. 4. Correct formatting of "*" (current assembler location) operand in BAC-Disassembler.html. 5. Minor corrections to 220-Paper-Tape-Decoder.html. 6. Commit new 220-Format-Band-Disassembler.html script to generate BAC- Assembler FBGR pseudo ops from memory images of Cardatron format bands.
294 lines
13 KiB
HTML
294 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<head>
|
|
<title>Burroughs 220 Paper Tape Decoder</title>
|
|
<meta name="Author" content="Paul Kimpel">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
<meta http-equiv="Content-Script-Type" content="text/javascript">
|
|
<meta http-equiv="Content-Style-Type" content="text/css">
|
|
|
|
<script>
|
|
/***********************************************************************
|
|
* retro-220/tools 220-Paper-Tape-Decoder.html
|
|
************************************************************************
|
|
* Copyright (c) 2020, Paul Kimpel.
|
|
* Licensed under the MIT License,
|
|
* see http://www.opensource.org/licenses/mit-license.php
|
|
************************************************************************
|
|
* Raw paper tape image file conversion to Burroughs 220 paper tape format.
|
|
*
|
|
* This script reads a Burroughs Burroughs 220 paper tape image as one
|
|
* large blob and extracts the data, converting the punch pattern bytes
|
|
* to 8-bit ASCII.
|
|
*
|
|
* The blob is assumed to be in the so-called ".ptp" format. Each 7-bit
|
|
* frame from the tape is represented as one 8-bit unsigned byte.
|
|
* The bits in a frame, from most- to least-significant, are:
|
|
*
|
|
* X 0 P 8 4 2 1
|
|
*
|
|
* where "P" is the odd-parity bit, "X" has the value 32, and "0" has the
|
|
* value 16. The 8, 4, 2, and 1 bits have their respective values
|
|
*
|
|
* To use, select the .ptp file using the file selection control on the
|
|
* page. The script writes a log of activity to the web page.
|
|
*
|
|
* This version outputs the converted data by opening a browser window for
|
|
* each file and inserting the converted text into a <textarea> element in
|
|
* that window. From there you can copy the text and paste into another
|
|
* program that can save the data to a local filesystem. This approach is
|
|
* being used until we can figure out a better way to get data out of a
|
|
* browser environment and into a local filesystem. Ugh.
|
|
************************************************************************
|
|
* 2020-08-02 P.Kimpel
|
|
* Original version, from retro-B5500 tools/B5500LibMaintExtract.html.
|
|
***********************************************************************/
|
|
"use strict";
|
|
|
|
window.onload = function() {
|
|
var debug = false;
|
|
var endOfWord = 0x0D;
|
|
var panel = document.getElementById("TextPanel");
|
|
var tapeBlob = null; // blob read from .ptp file
|
|
var tapeData = null; // tape blob as a DataView
|
|
|
|
var codeXlate = [ // translate internal B220 code to ANSI
|
|
// Note that ANSI new-line sequences are used for end-of-word characters,
|
|
// 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 "^".
|
|
// 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
|
|
" ", "?", "_", ".", "<", ">", "\\","?", "?", "?", "!", "!", "!", "!", "!", "!", // 00-0F
|
|
"&", "?", "]", "$", "*", "^", "|", "?", "?", "?", "!", "!", "!", "!", "!", "!", // 10-1F
|
|
"-", "/", "{", ",", "%", "}", "~", ":", "?", "?", "!", "!", "!", "!", "!", "!", // 20-2F
|
|
"?", "?", "[", "#", "@", "\n","\"","`", "?", "?", "!", "!", "!", "!", "!", "!", // 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
|
|
"!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", // A0-AF
|
|
"!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", // B0-BF
|
|
"!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", // C0-CF
|
|
"!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", // D0-DF
|
|
"!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", // E0-EF
|
|
"!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"]; // F0-FF
|
|
|
|
var ptXlate = [ // translate 220 paper tape punch patterns to ANSI
|
|
// 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
|
|
"?", "1", "2", "?", "4", "?", "?", "7", "8", "?", "?", "#", "?", "\n","\"","?", // 00-0F
|
|
" ", "?", "?", "3", "?", "5", "6", "?", "?", "9", "[", "?", "@", "?", "?", "`", // 10-1F
|
|
"0", "?", "?", "T", "?", "V", "W", "?", "?", "Z", "{", "?", "%", "?", "?", ":", // 20-2F
|
|
"?", "/", "S", "?", "U", "?", "?", "X", "Y", "?", "?", ",", "?", "}", "~", "?", // 30-3F
|
|
"-", "?", "?", "L", "?", "N", "O", "?", "?", "R", "]", "?", "*", "?", "?", "?", // 40-4F
|
|
"?", "J", "K", "?", "M", "?", "?", "P", "Q", "?", "?", "$", "?", "^", "|", "?", // 50-5F
|
|
"?", "A", "B", "?", "D", "?", "?", "G", "H", "?", "?", ".", "?", ">", "\\","?", // 60-6F
|
|
"&", "?", "?", "C", "?", "E", "F", "?", "?", "I", "_", "?", "<", "?", "?", "?", // 70-7F
|
|
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 80-8F
|
|
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 90-9F
|
|
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // A0-AF
|
|
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // B0-BF
|
|
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // C0-CF
|
|
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // D0-DF
|
|
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // E0-EF
|
|
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]; // F0-FF
|
|
|
|
var pow2 = [ // powers of 2 from 0 to 52
|
|
0x1, 0x2, 0x4, 0x8,
|
|
0x10, 0x20, 0x40, 0x80,
|
|
0x100, 0x200, 0x400, 0x800,
|
|
0x1000, 0x2000, 0x4000, 0x8000,
|
|
0x10000, 0x20000, 0x40000, 0x80000,
|
|
0x100000, 0x200000, 0x400000, 0x800000,
|
|
0x1000000, 0x2000000, 0x4000000, 0x8000000,
|
|
0x10000000, 0x20000000, 0x40000000, 0x80000000,
|
|
0x100000000, 0x200000000, 0x400000000, 0x800000000,
|
|
0x1000000000, 0x2000000000, 0x4000000000, 0x8000000000,
|
|
0x10000000000, 0x20000000000, 0x40000000000, 0x80000000000,
|
|
0x100000000000, 0x200000000000, 0x400000000000, 0x800000000000,
|
|
0x1000000000000, 0x2000000000000, 0x4000000000000, 0x8000000000000,
|
|
0x10000000000000];
|
|
|
|
function bit(word, bit) {
|
|
/* Extracts and returns the specified bit from the word */
|
|
var e = 47-bit; // word lower power exponent
|
|
var p; // bottom portion of word power of 2
|
|
|
|
if (e > 0) {
|
|
return ((word - word % (p = pow2[e]))/p) % 2;
|
|
} else {
|
|
return word % 2;
|
|
}
|
|
};
|
|
|
|
function fieldIsolate(word, start, width) {
|
|
/* Extracts a bit field [start:width] from word and returns the field */
|
|
var le = 48-start-width; // lower power exponent
|
|
var p; // bottom portion of word power of 2
|
|
|
|
return (le == 0 ? word : (word - word % (p = pow2[le]))/p) % pow2[width];
|
|
};
|
|
|
|
function spout(text) {
|
|
/* Appends "text"+NL as a new text node to the panel DOM element */
|
|
var e = document.createTextNode(text + "\n");
|
|
|
|
panel.appendChild(e);
|
|
}
|
|
|
|
function clearPanel() {
|
|
/* Clears the text panel */
|
|
var kid;
|
|
|
|
while (kid = panel.firstChild) {
|
|
panel.removeChild(kid);
|
|
}
|
|
}
|
|
|
|
function rtrim(s) {
|
|
/* Trims trailing spaces from "s" and returns the resulting string */
|
|
var m = s.match(/^(.*?) *$/);
|
|
|
|
return m[1];
|
|
}
|
|
|
|
function extractFile(data, fileNr, fileName) {
|
|
/* Extracts the 220 digits from the tape blob, converts the data
|
|
to ASCII, and writes it to a new window object within the browser.
|
|
Returns true if no more files should be converted */
|
|
var box = null;
|
|
var frame = 0;
|
|
var hex = "";
|
|
var len = data.byteLength;
|
|
var line = "";
|
|
var result = false;
|
|
var text = "";
|
|
var win = null;
|
|
var x = 0;
|
|
|
|
spout(" ");
|
|
spout("Extracting #" + fileNr + ": " + fileName);
|
|
|
|
win = window.open("", fileName, "width=800,height=600,status,scrollbars");
|
|
win.moveTo((screen.availWidth - 800)/2, (screen.availHeight - 600)/2);
|
|
win.focus();
|
|
|
|
box = win.document.createElement("code");
|
|
box.appendChild(win.document.createTextNode(fileName));
|
|
win.document.body.appendChild(box);
|
|
win.document.body.appendChild(win.document.createElement("br"));
|
|
|
|
box = win.document.createElement("textarea");
|
|
box.cols = 90;
|
|
box.rows = 30;
|
|
win.document.body.appendChild(box);
|
|
|
|
for (x=0; x<len; ++x) {
|
|
frame = data.getUint8(x) & 0x7F;
|
|
switch (frame) {
|
|
case 0: // ignore blank tape
|
|
case 0x7F: // ignore tape feed (punches in all channels)
|
|
break;
|
|
case 0x0D: // End of Word code
|
|
if (!debug) {
|
|
text += line + "\n";
|
|
} else {
|
|
while (line.length < 15) {
|
|
line += " ";
|
|
}
|
|
text += line + hex + " 0d\n";
|
|
hex = "";
|
|
}
|
|
|
|
line = "";
|
|
break;
|
|
default:
|
|
line += ptXlate[frame];
|
|
if (debug) {
|
|
hex += " " + (frame+0x100).toString(16).substring(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
box.value = text;
|
|
box.focus();
|
|
box.select();
|
|
//result = !confirm("Copy and save " + fileName + " from the sub-window.\n" +
|
|
// "Then click OK to continue or Cancel to quit.");
|
|
//win.close();
|
|
return result;
|
|
}
|
|
|
|
function fileLoader_onLoad(ev) {
|
|
/* Handle the onload event for an ArrayBuffer FileReader */
|
|
var tapeBlob = ev.target.result;
|
|
var tapeData = new DataView(tapeBlob); // use DataView() to avoid problems with little-endians.
|
|
|
|
extractFile(tapeData, ev.target._fileNr, ev.target._fileName);
|
|
}
|
|
|
|
function fileSelector_onChange(ev) {
|
|
/* Handle the <input type=file> onchange event when afiles are selected */
|
|
var f = null;
|
|
var reader = null;
|
|
var x = 0; // for now...
|
|
|
|
clearPanel();
|
|
f = ev.target.files[x];
|
|
//alert("File selected: " + f.name +
|
|
// "\nModified " + f.lastModifiedDate +
|
|
// "\nType=" + f.type + ", Size=" + f.size + " octets");
|
|
|
|
reader = new FileReader();
|
|
reader.onload = fileLoader_onLoad;
|
|
reader._fileNr = x;
|
|
reader._fileName = f.name;
|
|
reader.readAsArrayBuffer(f);
|
|
}
|
|
|
|
function checkBrowser() {
|
|
/* Checks whether this browser can support the necessary stuff */
|
|
var missing = "";
|
|
|
|
if (!window.File) {missing += ", File"}
|
|
if (!window.FileReader) {missing += ", FileReader"}
|
|
if (!window.FileList) {missing += ", FileList"}
|
|
if (!window.Blob) {missing += ", Blob"}
|
|
if (!window.ArrayBuffer) {missing += ", ArrayBuffer"}
|
|
if (!window.DataView) {missing += ", DataView"}
|
|
|
|
if (missing.length == 0) {
|
|
return false;
|
|
} else {
|
|
alert("No can do... your browser does not support the following features:\n" +
|
|
missing.substring(2));
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/* Start of window.onload() */
|
|
if (checkBrowser()) {
|
|
return;
|
|
}
|
|
document.getElementById("FileSelector").addEventListener("change", fileSelector_onChange, false);
|
|
}
|
|
</script>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div style="position:relative; width:100%; height:3em">
|
|
<div style="position:absolute; left:0; top:0; width:auto">
|
|
retro-220 Paper Tape Tape Decoder Utility
|
|
</div>
|
|
<div style="position:absolute; top:0; right:0; width:auto">
|
|
<input id=FileSelector type=file size=60>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<pre id=TextPanel>
|
|
</pre>
|
|
|
|
</body>
|
|
</html> |