1
0
mirror of https://github.com/pkimpel/retro-220.git synced 2026-01-24 11:21:29 +00:00
pkimpel.retro-220/software/tools/220-Paper-Tape-Decoder.html
Paul Kimpel 4773bec4eb Update and reorganize 220 diagnostics tests from bitsavers.org.
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.
2021-09-04 18:04:11 -07:00

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>