{"id":16837,"date":"2021-07-18T17:07:20","date_gmt":"2021-07-18T21:07:20","guid":{"rendered":"https:\/\/scruss.com\/blog\/?p=16837"},"modified":"2021-07-18T18:04:00","modified_gmt":"2021-07-18T22:04:00","slug":"tetris-for-applesoft-basic","status":"publish","type":"post","link":"https:\/\/scruss.com\/blog\/2021\/07\/18\/tetris-for-applesoft-basic\/","title":{"rendered":"Tetris for Applesoft BASIC"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"560\" height=\"384\" src=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/07\/Screenshot-2021-07-18-at-16-23-29-Tetris-for-Applesoft-BASIC-Mark-Stock-Free-Download-Borrow-and-Streaming-Internet-Archive.png\" alt=\"a tetris game tableau, paused, with a completed line of bricks about to be removed\" class=\"wp-image-16838\" srcset=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/07\/Screenshot-2021-07-18-at-16-23-29-Tetris-for-Applesoft-BASIC-Mark-Stock-Free-Download-Borrow-and-Streaming-Internet-Archive.png 560w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/07\/Screenshot-2021-07-18-at-16-23-29-Tetris-for-Applesoft-BASIC-Mark-Stock-Free-Download-Borrow-and-Streaming-Internet-Archive-320x219.png 320w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/07\/Screenshot-2021-07-18-at-16-23-29-Tetris-for-Applesoft-BASIC-Mark-Stock-Free-Download-Borrow-and-Streaming-Internet-Archive-160x110.png 160w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><figcaption>a very paused game<\/figcaption><\/figure>\n\n\n\n<p>Paleotronic&#8217;s <a href=\"https:\/\/paleotronic.com\/2018\/06\/26\/tetris-for-applesoft-basic\/\">Tetris for Applesoft BASIC<\/a> is a surprisingly decent version for something that&#8217;s written in an interpreted language. It&#8217;s not what anyone would call zippy, but it&#8217;s not so slow that you want to give up.<\/p>\n\n\n\n<p>Paleotronic want you to type it in, but life&#8217;s too short for that. You can play it in your browser on the Internet Archive: <a href=\"https:\/\/archive.org\/details\/AppleSoftTetris\">Tetris for Applesoft BASIC by Mark Stock<\/a><\/p>\n\n\n\n<p>Or download an auto-booting Apple II disk image:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/07\/AppleSoftTetris.zip\">AppleSoftTetris.zip<\/a><a href=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/07\/AppleSoftTetris.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><strong>Keys<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><kbd>,<\/kbd> \u00e2\u20ac\u201d move left<\/li><li><kbd>.<\/kbd> \u00e2\u20ac\u201d move right<\/li><li><kbd>A<\/kbd> \u00e2\u20ac\u201d rotate left<\/li><li><kbd>R<\/kbd> \u00e2\u20ac\u201d rotate right<\/li><li><kbd>Z<\/kbd> \u00e2\u20ac\u201d drop<\/li><li><kbd>P<\/kbd> \u00e2\u20ac\u201d pause<\/li><li><kbd>Q<\/kbd> \u00e2\u20ac\u201d quit<\/li><\/ul>\n\n\n\n<p>Life&#8217;s also too short for correcting OCR errors in BASIC code. Tesseract is hilariously bad at recognizing source code, so I had to go through this several times. AppleCommander&#8217;s <a href=\"https:\/\/github.com\/AppleCommander\/bastools\">BASIC Tools<\/a> was very handy for catching the last of the errors with its variable dump: caught the cases of the TO keyword converted to the variable T0 \u00e2\u20ac\u00a6 and frankly, I am no fan of SmartQuotes when applied to source code, either.<\/p>\n\n\n\n<p>Here&#8217;s the source, straight from the interpreter with all its weird spacing:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n10  GOSUB 1000\n100 W = W +1: IF W &gt;LV  THEN W = 0: GOSUB 350\n110 K =  PEEK(KB): IF K &gt; = H  THEN  POKE KC,H:K = K -H: GOSUB 300\n190  GOTO 100\n200 PY = PY *A2: VLIN PY,PY +A1 AT PX: RETURN \n225 PY = PY *A2: HLIN X1,X2 AT PY: HLIN X1,X2 AT PY +A1: RETURN \n300  ON E(K) GOTO 30000,330,340,350,360,30100\n310  RETURN \n330 X = X -1: GOTO 400\n340 X = X +1: GOTO 400\n350 DN = 1:Y = Y +1: GOSUB 400:DN = 0: RETURN \n360 S = S +1: IF S\/4 =  INT(S\/4)  THEN S = S -4\n400  GOSUB 500\n410  GOSUB 800: IF F = 0  THEN X = XX:Y = YY:S = SS: GOSUB 420: IF DN  THEN  GOSUB 900\n420  COLOR= CF: FOR PP = 1 TO 4:PX = X +X(S,PP):PY = Y +Y(S,PP): GOSUB 200: NEXT PP:XX = X:YY = Y:SS = S:D = 0: RETURN \n500  IF DD  THEN  RETURN \n510  COLOR= CB: FOR PP = 1 TO 4:PX = XX +X(SS,PP):PY = YY +Y(SS,PP): GOSUB 200: NEXT PP:DD = 0: RETURN \n800 F = 1: FOR PP = 1 TO 4:PY = Y +Y(SS,PP): ON ( FN PC(X +X(S,PP)) &gt;0) GOTO 805: NEXT PP: RETURN \n805 F = 0: RETURN \n850 F = 1: RETURN \n900 P = 10: GOSUB 30300\n905 RN = 0:Y = YM\n910 X = XL\n920 PY = Y: IF  FN PC(X) = CB  THEN 950\n930 X = X +1: IF X &lt; = XR  THEN 920\n940 R(RN) = Y:RN = RN +1\n950 Y = Y -1: IF Y &gt; = 0  THEN 910\n960  IF RN  THEN  GOSUB 30400\n970 Y = 0\n980 X =  INT((XR -XL)\/2) +XL\n985 S =  INT( RND(1) *NS):CF = C(S):S = S *4\n990  GOSUB 800: IF F  THEN  RETURN \n995  GOTO 31000\n1000  DIM E(127),X(27,4),Y(27,4),R(40)\n1010  TEXT : HOME : GR \n1011  PRINT &quot;WELCOME...&quot;\n1014 LM = 10\n1015 XM = 10:YM = 15\n1016 XL =  INT((40 -XM)\/2)\n1017 XR = XL +XM -1\n1021 A1 = 1\n1022 A2 = 2\n1030  DEF  FN PC(X) =  SCRN( X,PY *A2)\n1040 CB = 0\n1050 XX = 20:YY = 0:SS = 0\n1100 KB =  -16384\n1110 KC =  -16368\n1120 H = 128\n1129  REM KEYBOARD ACTIONS\n1130  REM QUIT\n1131 E( ASC(&quot;Q&quot;)) = 1\n1132 E( ASC(&quot;Q&quot;) -64) = 1\n1140  REM MOVE LEFT\n1141 E(8) = 2\n1142 E( ASC(&quot;,&quot;)) = 2\n1150  REM MOVE RIGHT\n1151 E(21) = 3\n1152 E( ASC(&quot;.&quot;)) = 3\n1160  REM MOVE DOWN\n1161 E(32) = 4\n1162 E( ASC(&quot;Z&quot;)) = 4\n1170  REM ROTATE\n1171 E( ASC(&quot;R&quot;)) = 5\n1172 E(13) = 5\n1173 E( ASC(&quot;A&quot;)) = 5\n1179  REM PAUSE GAME\n1180 E( ASC(&quot;P&quot;)) = 6\n1181 E( ASC(&quot;P&quot;) -64) = 6\n1185  GOSUB 2000\n1186  GOSUB 1300\n1190  PRINT &quot;PRESS ANY KEY TO START...&quot;\n1191  PRINT \n1192  PRINT &quot;PRESS Q TO QUIT.&quot;\n1193  GOTO 31020\n1299  REM DRAW THE GAME\n1300  COLOR= 4: FOR I = 0 TO 19:X1 = 0:X2 = 39:PY = I: GOSUB 225: NEXT \n1320  COLOR= CB: FOR I = 0 TO YM:X1 = XL:X2 = XR:PY = I: GOSUB 225: NEXT \n1350  RETURN \n1400  DATA 1\n1401  DATA 0,0,1,0,0,1,1,1\n1402  DATA 0,0,1,0,0,1,1,1\n1403  DATA 0,0,1,0,0,1,1,1\n1404  DATA 0,0,1,0,0,1,1,1\n1410  DATA 2\n1411  DATA 0,1,1,1,2,1,3,1\n1412  DATA 1,0,1,1,1,2,1,3\n1413  DATA 0,1,1,1,2,1,3,1\n1414  DATA 1,0,1,1,1,2,1,3\n1420  DATA 12\n1421  DATA 1,1,0,1,1,0,2,1\n1422  DATA 1,1,0,1,1,0,1,2\n1423  DATA 1,1,0,1,2,1,1,2\n1424  DATA 1,1,1,0,2,1,1,2\n1430  DATA 13\n1431  DATA 1,1,0,1,2,1,0,2\n1432  DATA 1,1,1,0,1,2,2,2\n1433  DATA 1,1,0,1,2,1,2,0\n1434  DATA 1,1,1,0,1,2,0,0\n1440  DATA 9\n1441  DATA 1,1,0,1,2,1,2,2\n1442  DATA 1,1,1,0,1,2,2,0\n1443  DATA 1,1,0,1,2,1,0,0\n1444  DATA 1,1,1,0,1,2,0,2\n1450  DATA 3\n1451  DATA 1,1,1,0,0,0,2,1\n1452  DATA 1,1,1,0,0,1,0,2\n1453  DATA 1,1,1,0,0,0,2,1\n1454  DATA 1,1,1,0,0,1,0,2\n1460  DATA 6\n1461  DATA 1,1,0,1,1,0,2,0\n1462  DATA 1,1,0,1,0,0,1,2\n1463  DATA 1,1,0,1,1,0,2,0\n1464  DATA 1,1,0,1,0,0,1,2\n1990  DATA  -1\n2000 X = 0:Y = 0\n2010 NS = 0\n2020  READ C: IF C &lt; &gt; -1  THEN C(NS) = C: FOR J = 0 TO 3: FOR I = 1 TO 4: READ X(NS *4 +J,I): READ Y(NS *4 +J,I): NEXT I: NEXT J:NS = NS +1: GOTO 2020\n2030  RETURN \n21210 P = 1: RETURN \n30000  TEXT : HOME : END \n30100  HOME \n30110  PRINT &quot;GAME PAUSED. PRESS P TO CONTINUE...&quot;\n30120 P = 1\n30130 K =  PEEK(KB): IF K &gt; = H  THEN  POKE KC,H:K = K -H: GOSUB 30200\n30140  IF P  THEN 30130\n30150  HOME \n30160  PRINT &quot;SCORE &quot;;SC; TAB( 21);&quot;LEVEL &quot;;LM -LV +1\n30170  RETURN \n30200  ON E(K) GOTO 30000,30210,30210,30210,30210,30220\n30210  RETURN \n30220 P = 0\n30230  RETURN \n30300 SC = SC +P\n30310  VTAB 21: HTAB 7\n30320  PRINT SC;\n30330  RETURN \n30400 RN = RN -1\n30410  FOR C = 0 TO 32\n30415  COLOR= C\n30420  FOR I = 0 TO RN:X1 = XL:X2 = XR:PY = R(I): GOSUB 225: NEXT I\n30430  FOR I = 0 TO 2: NEXT I\n30440  NEXT C\n30450  FOR I = 0 TO RN\n30460 Y = R(I) +I\n30470 YP = Y -1: FOR X = XL TO XR:PY = YP: COLOR=  FN PC(X):PX = X:PY = Y: GOSUB 200: NEXT X:Y = Y -1: IF Y &gt;0  THEN 30470\n30480 P = 100: GOSUB 30300\n30490  NEXT I\n30495  RETURN \n31000  VTAB 22: PRINT \n31010  PRINT &quot;              GAME OVER&quot;\n31020 P = 1\n31030 K =  PEEK(KB): IF K &gt; = H  THEN  POKE KC,H:K = K -H: GOSUB 31200\n31040  IF P  THEN 31030\n31050 D = 1\n31060 SC = 0:LV = LM\n31070  GOSUB 30150\n31080  GOSUB 1300\n31090  GOTO 905\n31200  ON E(K) GOTO 30000\n31210 P = 0: RETURN \n32000  REM END OF LISTING\n<\/pre><\/div>\n\n\n<p>If only AppleSoft had a RENUM command, the code might not look so messy<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Paleotronic&#8217;s Tetris for Applesoft BASIC is a surprisingly decent version for something that&#8217;s written in an interpreted language. It&#8217;s not what anyone would call zippy, but it&#8217;s not so slow that you want to give up. Paleotronic want you to type it in, but life&#8217;s too short for that. You can play it in your [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Tetris for Applesoft BASIC, via Paleotronic","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[7],"tags":[3071,2062,2556,3290],"class_list":["post-16837","post","type-post","status-publish","format-standard","hentry","category-computers-suck","tag-appleii","tag-basic","tag-retrocomputing","tag-tetris"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pQNZZ-4nz","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/16837","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/comments?post=16837"}],"version-history":[{"count":4,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/16837\/revisions"}],"predecessor-version":[{"id":16843,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/16837\/revisions\/16843"}],"wp:attachment":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/media?parent=16837"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/categories?post=16837"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/tags?post=16837"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}