{"id":598,"date":"2022-08-21T20:22:00","date_gmt":"2022-08-21T10:22:00","guid":{"rendered":"http:\/\/www.vk1zdj.net\/?p=598"},"modified":"2023-01-27T10:21:54","modified_gmt":"2023-01-26T23:21:54","slug":"reading-paper-tapes-in-2022","status":"publish","type":"post","link":"https:\/\/www.vk1zdj.net\/?p=598","title":{"rendered":"Reading Paper Tapes in 2022"},"content":{"rendered":"\n<p>I have a couple of old paper tapes &#8211; I also have an ASR33 teletype, which is more than capable of reading a tape, but making the ASR33 operate correctly is a labor of love which I will complete Before-I-Die &#8482;.<\/p>\n\n\n\n<p>One project I was able to obtain a while ago was a reproduction of an optical tape reader originally made by Oliver Audio Engineering (OAD) called the OP-80A.   The OP-80A uses an optical read head consisting of a set of photo transistors that monitor every bit of the tape, including the sprocket hole.  As a tape is pulled through the reader different data patterns are presented to the read head.  When a light pulse is detected by the sprocket hole sensor, a RDY flipflop is asserted to let the host computer know that data is ready to be read.   Depending on how fast the tape is being dragged, you have a reasonable number on Milliseconds to read the data, and clear the flip-flop by toggling the ACK* signal.<\/p>\n\n\n\n<p>I decided that I would interface the OP-80A that I had to an Arduino &#8211; That would provide me with the ability to read tapes and output them using the built in serial port capability of the Arduino.   Easy.  I have a box full of Arduino boards, so i chose an Arduino nano because it was small enough to fit into the existing enclosure that the OP-80A was mounted in.<\/p>\n\n\n\n<p>Firstly &#8211; I identified the pinout of the OP-80A interface.  Michael Holley did a wonderful scan cleanup of the original manual in 2001.  It is available here: <a href=\"https:\/\/deramp.com\/swtpc.com\/OAE80_Reader\/OAE_80A_Manual.pdf\">https:\/\/deramp.com\/swtpc.com\/OAE80_Reader\/OAE_80A_Manual.pdf<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/OP-80A-pinout.png\"><img decoding=\"async\" loading=\"lazy\" width=\"651\" height=\"639\" src=\"http:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/OP-80A-pinout.png\" alt=\"\" class=\"wp-image-599\" srcset=\"https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/OP-80A-pinout.png 651w, https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/OP-80A-pinout-300x294.png 300w, https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/OP-80A-pinout-80x79.png 80w\" sizes=\"(max-width: 651px) 100vw, 651px\" \/><\/a><\/figure>\n\n\n\n<p>  I cut a short 4 inch length of 14 conductor ribbon, and wired the Arduino to the OP-80A using the following schema.<\/p>\n\n\n\n<p class=\"has-text-align-center\"> <code>LED - S1 -&gt; Arduino A0<\/code><\/p>\n\n\n\n<ul><li>LED_S1 -&gt;  Arduino A0<\/li><li>LED_S2 -&gt; Arduino A1<\/li><li>D0 -&gt; Arduino D3  (D0 &amp; D1 are used for the TX\/Rx pins of the Arduino)<\/li><li>D1 -&gt; Arduino D4<\/li><li>D2 -&gt; Arduino D5<\/li><li>D3 -&gt; Arduino D6<\/li><li>D4 -&gt; Arduino D7<\/li><li>D5 -&gt; Arduino D8<\/li><li>D6 -&gt; Arduino D9<\/li><li>D7 -&gt; Arduino D10<\/li><li>RDA -&gt; Arduino D11<\/li><li>ACK*-&gt; Arduino D12<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Arduino.png\"><img decoding=\"async\" loading=\"lazy\" width=\"557\" height=\"205\" src=\"http:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Arduino.png\" alt=\"\" class=\"wp-image-602\" srcset=\"https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Arduino.png 557w, https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Arduino-300x110.png 300w, https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Arduino-80x29.png 80w\" sizes=\"(max-width: 557px) 100vw, 557px\" \/><\/a><\/figure>\n\n\n\n<p>Next, I fired up the Arduino IDE and wrote a short test program to flash the S1 and S2 LEDs to verify I had the wiring correct;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n\/\/\n\/\/OP-80A test - Blink S1 and S2\n\/\/\nconst byte LED_S1 = A0;\nconst byte LED_S2 = A1;\n\n\nvoid setup() {\n  \/\/ put your setup code here, to run once:\n  \/\/ initialize digital pin LED_S1 and LED_S2 as outputs.\n  pinMode(LED_S1, OUTPUT);\n  pinMode(LED_S2, OUTPUT);\n}\n\nvoid loop() {\n  digitalWrite(LED_S1, HIGH);   \/\/ turn the LED on \n  digitalWrite(LED_S2, LOW);    \/\/ turn the LED off\n  delay(1000);                  \/\/ wait for a second\n  digitalWrite(LED_S1, LOW);    \n  digitalWrite(LED_S2, HIGH);   \n\n  delay(1000);                  \/\/ wait for a second\n}<\/code><\/pre>\n\n\n\n<p>That was loaded up and I was instantly rewarded with the status LEDs blinking &#8211; I can still write Arduino C Code !!!!  Wohoo!<\/p>\n\n\n\n<p>Next, I created this code to actually read the data as it became available &#8211; It simply reads the input pins, builds an output character and prints it @ 9600 baud on the USB serial port.  You will see the code that outputs the individual bits &#8211; its commented out for normal operation.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/\n\/\/  OP-80A Interface controller\n\/\/\n\/\/ Input: OP-80A board - Output: USB com port\n\/\/\n\/\/ Copyright 2022 - Doug Jackson - VK1ZDJ\n\/\/ Others are welcome to build upon this code.\n\n\/\/ Read in a tape - One byte at a time\n\/\/ When RDY goes high, bit shift D10-D3 down 3 bits to be D7-D0 and output that as a byte\n\/\/ then toggle ACK* line to reset RDY flipflop.\n\/\/ then do it all again\n\n\/\/ Status LEDS connected to A0 and A1 don't do anything.\n\nconst byte LED_S1 = A0;\nconst byte LED_S2 = A1;\nconst byte IN_D0 = 3;\nconst byte IN_D1 = 4;\nconst byte IN_D2 = 5;\nconst byte IN_D3 = 6;\nconst byte IN_D4 = 7;\nconst byte IN_D5 = 8;\nconst byte IN_D6 = 9;\nconst byte IN_D7 = 10;\n\nconst byte RDA = 11;\nconst byte ACK = 12;\n\n\n\nvoid setup() {\n  \/\/ put your setup code here, to run once:\n  \/\/ initialize digital pin LED_BUILTIN as an output.\n  pinMode(LED_S1, OUTPUT);\n  pinMode(LED_S2, OUTPUT);\n\n  pinMode(IN_D0, INPUT);\n  pinMode(IN_D1, INPUT);\n  pinMode(IN_D2, INPUT);\n  pinMode(IN_D3, INPUT);\n  pinMode(IN_D4, INPUT);\n  pinMode(IN_D5, INPUT);\n  pinMode(IN_D6, INPUT);\n  pinMode(IN_D7, INPUT);\n  pinMode(RDA, INPUT);\n  pinMode(ACK, OUTPUT);\n\nSerial.begin(9600);\nSerial.println(\"Ready for input\");\n\nSerial.println(\"Resetting ACK\");\ndigitalWrite(ACK, HIGH);\ndelay(5);\ndigitalWrite(ACK, LOW);\ndigitalWrite(ACK, HIGH);\n\n}\n\nvoid loop() {\n  \/\/ put your main code here, to run repeatedly:\nchar character;\n\n\nif (digitalRead(RDA)!=0)\n{\n\n\/\/Serial.println(\"Got a RDA\");\n\ncharacter = digitalRead( IN_D7 ) &lt;&lt; 7;\n\/\/if(digitalRead( IN_D7) ==0) Serial.print('0'); else Serial.print('1');\n\ncharacter += digitalRead ( IN_D6 ) &lt;&lt; 6;\n\/\/if(digitalRead( IN_D6) ==0) Serial.print('0'); else Serial.print('1');\n\ncharacter += digitalRead ( IN_D5 ) &lt;&lt; 5;\n\/\/if(digitalRead( IN_D5) ==0) Serial.print('0'); else Serial.print('1');\n\ncharacter += digitalRead ( IN_D4 ) &lt;&lt; 4;\n\/\/if(digitalRead( IN_D4) ==0) Serial.print('0'); else Serial.print('1');\n\ncharacter += digitalRead ( IN_D3 ) &lt;&lt; 3;\n\/\/if(digitalRead( IN_D3) ==0) Serial.print('0'); else Serial.print('1');\n\ncharacter += digitalRead ( IN_D2 ) &lt;&lt; 2;\n\/\/if(digitalRead( IN_D2) ==0) Serial.print('0'); else Serial.print('1');\n\ncharacter += digitalRead ( IN_D1 ) &lt;&lt; 1;\n\/\/if(digitalRead( IN_D1) ==0) Serial.print('0'); else Serial.print('1');\n\ncharacter += digitalRead ( IN_D0 ) ;\n\/\/if(digitalRead( IN_D0) ==0) Serial.println('0'); else Serial.println('1');\n\nSerial.print(character);\n\n\n\/\/ Ack the read byte\ndigitalWrite(ACK, HIGH);\ndelay(5);\ndigitalWrite(ACK, LOW);\ndigitalWrite(ACK, HIGH);\n}\n  \n}<\/code><\/pre>\n\n\n\n<p>After a bit of testing, I cut a small hole in the back of the OP-80A enclosure and secured the arduino in the botton &#8211; Now the OP-80A looks stock, but it has a USB interface built in \ud83d\ude42<\/p>\n\n\n\n<p>I was able to read in a couple of unknown tapes that came with my Dream 6800 system &#8211; they are intel Hex dumps of the 2708 roms on the board.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>:10110000DE2620090F9F129E2634CE0030D62BC437\n:101110000F32A700087C00275A2AF69E120E39D6F5\n:10112000297F003FDE268601971CC40F2602C610C9\n:1011300037DF14A600971E7F001FD62EC40727098D\n:1011400074001E76001F5A26F5D62E8D28961E8D09\n:1011500015D62ECB088D1E961F8D0B7C002FDE140E\n:1011600008335A26CB3916E800AA00E700112704F5\n:101170008601973F39962F841F484848C43F5454EE\n:10118000541B971DDE1C39C6F0CE80106F01E7009E\n:10119000C606E7016F00398DEE7F00188D55E60019\n:1011A0008D159717C60F8DE1E600545454548D07E2\n:1011B00048489B17971739C10F2602D71886FF4C4E\n:1011C0005425FC39DF128DBFA6012B07482AF96D83\n:1011D0000020078DC27D001826EC8D03DE1239C673\n:1011E00004D721C641F780127D002126FBC601F7F6\n:1011F0008012398D0037C6C85A0126FC3339CE809B\n:1012000012C63BE701C67FE700A701C601E7003928\n:101210008D13A6002BFC8DDDC6090D6900468DD30C\n:101220005A26F72017DF12CE8012398DF8366A0061\n:10123000C60A8DBFA7000D465A26F732DE123920A6\n:101240008386378DB9DE02398DF7A6008DDD089CC7\n:101250000426F7200B8DEA8DB7A700089C0426F71B\n:101260008E007FCEC3E9DF00863F8D928D430E8DC9\n:10127000CE4D2A108DC9840327234A27D84A27C870\n:10128000DE066E008D0C97068D0697078D2320DFF6\n:101290008DAD48484848970F8DA59B0F398D12DEBC\n:1012A000068D258D9A4D2B048DE8A70008DF0620BA\n:1012B000EC86108D2BCE01C886FFBDC07DCE00060A\n:1012C0008D06088D038D1539A60036444444448D9F\n:1012D0000132DF12BDC193C6058DC22486049B2E48\n:1012E000972E861A972FDE12397A00207A00217DF8\n:1012F00080123BDE006E0000C3F300800083C360F9<\/code><\/pre>\n\n\n\n<p> I was also able to read a Mandal program that was on tape &#8211; the tape was from 1976 &#8211; I was 10!!!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Mandal-1976.png\"><img decoding=\"async\" loading=\"lazy\" width=\"796\" height=\"429\" src=\"http:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Mandal-1976.png\" alt=\"\" class=\"wp-image-603\" srcset=\"https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Mandal-1976.png 796w, https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Mandal-1976-300x162.png 300w, https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Mandal-1976-768x414.png 768w, https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Mandal-1976-80x43.png 80w\" sizes=\"(max-width: 796px) 100vw, 796px\" \/><\/a><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>10 DIM C$(6),A$(3)\n12 C$ =\"*.  $#\"\n14 P1=3.14159\n22 PRINT\n24 PRINT\"  ** YOU **   DESIGN A MANDALA BY TYPING IN SOME NUMBERS.\"\n26 PRINT\n100 REM ** INITIAL DIALOG **\n110 PRINT\n120 PRINT \"SIZE OF MANDALA IN INCHES \"; \n130 INPUT S\n135 LET S8=S\n140 IF S&gt;=1 AND S&lt;=7 THEN 180 \n150 PRINT \"MANDALAS CAN BE BETWEEN 1 AND 7 INCHES.\"\n160 PRINT \"SIZE \";\n170 GOTO 130\n180 S=INT(2.5*S-.5)\n190 PRINT \"DIP FREQUENCY AND IMPORTANCE \";\n200 INPUT F1,C1\n205 LET F8=F1:C8=C1\n210 PRINT \"RIPPLE FREQUENCY AND IMPORTANCE \";\n220 INPUT F2,C2\n225 LET F9=F2:C9=C2\n230 PRINT \"COMBINATION IMPORTANCE \";\n240 INPUT C3\n245 LET C7=C3\n250 PRINT\n260 PRINT\"HERE IS YOUR MANDALA :\"\n270 PRINT\n280 REM *** PARAMETER NORMALIZATION ***\n290 F1=INT(F1+.5)\n300 F2=INT(F2+.5)\n310 C1=ABS(C1)\n320 C2=ABS(C2)\n330 C3=ABS(C3)\n340 C=C1+C2+C3\n350 C1=3*C1\/C\n360 C2=3*C2\/C\n370 C3=3*C3\/C\n380 PRINT \n1000 REM *** PRINTING LOOP ***\n1010 FOR Y=S TO -S STEP -1\n1020 Y2=Y*Y\n1030 REM FIND EDGE\n1040 X1=S\n1050 X2=-S\n1060 X3=-1\n1070 FOR X=X1 TO X2 STEP X3\n1080 R=SQR(X*X+Y2)\/S\n1090 IF X &lt;&gt; O THEN 1120\n1100 A=P1* SGN(Y)\/2\n1110 GOTO 1150\n1120 A=ATN(Y\/X)\n1130 IF X&gt;0 THEN 1150\n1140 A=A+P1\n1150 G1=SIN(F1*A)\n1160 G2=SIN(F2*R*P1)\n1170 Q=INT(C1*G1+C2*G2+C3*G1*G2+3)+1\n1180 IF X3=1 THEN 1250\n1190 IF Q=3 ORQ=4 THEN 1260\n1200 REM FOUND EDGE\n1210 X1=-S\n1220 X2=X\n1230 X3=1\n1240 GOTO 1070\n1250 PRINT MID$(C$,Q,1);MID$(C$,Q,1);\n1260 NEXT X\n1270 PRINT \n1280 NEXT Y\n9999 END<\/code><\/pre>\n\n\n\n<p>This is the same code as I found on the Microbee website &#8211; but the Microbee version was attributed to ROM B\/GCC III.  It also had a number of dropped spaces that caused MBASIC to barf &#8211; things like 140 IFS&gt;=1 AND S&lt;=7THEN 180 which should have a space between the IF and S&gt; terms.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>0 REM                M A N D A L A\n1 REM\n2 REM  MANDALA   REDONE      VER 1.3     9\/20\/76      ROB C\/GCC III\n10 DIM C$(6),A$(3)\n\netc....<\/code><\/pre>\n\n\n\n<p>To use this, simply plug it into the PC &#8211; Load up your favourite terminal program.  Load the tape, put a desk lamp above the reader and pull the tape through.  I found that I could stop pulling and move my hand back to pull the next length and it was not an issue &#8211; This is because the RDA flip flop waits for a dark-light transition before triggering again.  <\/p>\n\n\n\n<p>Oh &#8211; If anybody is curious what the Mandala output looks like &#8211; I loaded it into my N8 CP\/M system and executed it under MBASIC.  Here is a sample run.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Mandala-run.png\"><img decoding=\"async\" loading=\"lazy\" width=\"433\" height=\"617\" src=\"http:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Mandala-run.png\" alt=\"\" class=\"wp-image-604\" srcset=\"https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Mandala-run.png 433w, https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Mandala-run-211x300.png 211w, https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/Mandala-run-80x114.png 80w\" sizes=\"(max-width: 433px) 100vw, 433px\" \/><\/a><\/figure>\n\n\n\n<p>In all, not a bad afternoon.  Now &#8211; To continue working on the ASR-33 :-).<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have a couple of old paper tapes &#8211; I also have an ASR33 teletype, which is more than capable of reading a tape, but making the ASR33 operate correctly is a labor of love which I will&#8230; <\/p>\n","protected":false},"author":1,"featured_media":601,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false},"categories":[5,34],"tags":[],"jetpack_featured_media_url":"https:\/\/www.vk1zdj.net\/wp-content\/uploads\/2022\/08\/OP-80A-reader.png","_links":{"self":[{"href":"https:\/\/www.vk1zdj.net\/index.php?rest_route=\/wp\/v2\/posts\/598"}],"collection":[{"href":"https:\/\/www.vk1zdj.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vk1zdj.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vk1zdj.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vk1zdj.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=598"}],"version-history":[{"count":4,"href":"https:\/\/www.vk1zdj.net\/index.php?rest_route=\/wp\/v2\/posts\/598\/revisions"}],"predecessor-version":[{"id":619,"href":"https:\/\/www.vk1zdj.net\/index.php?rest_route=\/wp\/v2\/posts\/598\/revisions\/619"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.vk1zdj.net\/index.php?rest_route=\/wp\/v2\/media\/601"}],"wp:attachment":[{"href":"https:\/\/www.vk1zdj.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=598"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vk1zdj.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=598"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vk1zdj.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=598"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}