Tag: appleII

  • Tetris for Applesoft BASIC

    a tetris game tableau, paused, with a completed line of bricks about to be removed
    a very paused game

    Paleotronic’s Tetris for Applesoft BASIC is a surprisingly decent version for something that’s written in an interpreted language. It’s not what anyone would call zippy, but it’s not so slow that you want to give up.

    Paleotronic want you to type it in, but life’s too short for that. You can play it in your browser on the Internet Archive: Tetris for Applesoft BASIC by Mark Stock

    Or download an auto-booting Apple II disk image:

    Keys:

    • , — move left
    • . — move right
    • A — rotate left
    • R — rotate right
    • Z — drop
    • P — pause
    • Q — quit

    Life’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’s BASIC Tools 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 … and frankly, I am no fan of SmartQuotes when applied to source code, either.

    Here’s the source, straight from the interpreter with all its weird spacing:

    10  GOSUB 1000
    100 W = W +1: IF W >LV  THEN W = 0: GOSUB 350
    110 K =  PEEK(KB): IF K > = H  THEN  POKE KC,H:K = K -H: GOSUB 300
    190  GOTO 100
    200 PY = PY *A2: VLIN PY,PY +A1 AT PX: RETURN 
    225 PY = PY *A2: HLIN X1,X2 AT PY: HLIN X1,X2 AT PY +A1: RETURN 
    300  ON E(K) GOTO 30000,330,340,350,360,30100
    310  RETURN 
    330 X = X -1: GOTO 400
    340 X = X +1: GOTO 400
    350 DN = 1:Y = Y +1: GOSUB 400:DN = 0: RETURN 
    360 S = S +1: IF S/4 =  INT(S/4)  THEN S = S -4
    400  GOSUB 500
    410  GOSUB 800: IF F = 0  THEN X = XX:Y = YY:S = SS: GOSUB 420: IF DN  THEN  GOSUB 900
    420  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 
    500  IF DD  THEN  RETURN 
    510  COLOR= CB: FOR PP = 1 TO 4:PX = XX +X(SS,PP):PY = YY +Y(SS,PP): GOSUB 200: NEXT PP:DD = 0: RETURN 
    800 F = 1: FOR PP = 1 TO 4:PY = Y +Y(SS,PP): ON ( FN PC(X +X(S,PP)) >0) GOTO 805: NEXT PP: RETURN 
    805 F = 0: RETURN 
    850 F = 1: RETURN 
    900 P = 10: GOSUB 30300
    905 RN = 0:Y = YM
    910 X = XL
    920 PY = Y: IF  FN PC(X) = CB  THEN 950
    930 X = X +1: IF X < = XR  THEN 920
    940 R(RN) = Y:RN = RN +1
    950 Y = Y -1: IF Y > = 0  THEN 910
    960  IF RN  THEN  GOSUB 30400
    970 Y = 0
    980 X =  INT((XR -XL)/2) +XL
    985 S =  INT( RND(1) *NS):CF = C(S):S = S *4
    990  GOSUB 800: IF F  THEN  RETURN 
    995  GOTO 31000
    1000  DIM E(127),X(27,4),Y(27,4),R(40)
    1010  TEXT : HOME : GR 
    1011  PRINT "WELCOME..."
    1014 LM = 10
    1015 XM = 10:YM = 15
    1016 XL =  INT((40 -XM)/2)
    1017 XR = XL +XM -1
    1021 A1 = 1
    1022 A2 = 2
    1030  DEF  FN PC(X) =  SCRN( X,PY *A2)
    1040 CB = 0
    1050 XX = 20:YY = 0:SS = 0
    1100 KB =  -16384
    1110 KC =  -16368
    1120 H = 128
    1129  REM KEYBOARD ACTIONS
    1130  REM QUIT
    1131 E( ASC("Q")) = 1
    1132 E( ASC("Q") -64) = 1
    1140  REM MOVE LEFT
    1141 E(8) = 2
    1142 E( ASC(",")) = 2
    1150  REM MOVE RIGHT
    1151 E(21) = 3
    1152 E( ASC(".")) = 3
    1160  REM MOVE DOWN
    1161 E(32) = 4
    1162 E( ASC("Z")) = 4
    1170  REM ROTATE
    1171 E( ASC("R")) = 5
    1172 E(13) = 5
    1173 E( ASC("A")) = 5
    1179  REM PAUSE GAME
    1180 E( ASC("P")) = 6
    1181 E( ASC("P") -64) = 6
    1185  GOSUB 2000
    1186  GOSUB 1300
    1190  PRINT "PRESS ANY KEY TO START..."
    1191  PRINT 
    1192  PRINT "PRESS Q TO QUIT."
    1193  GOTO 31020
    1299  REM DRAW THE GAME
    1300  COLOR= 4: FOR I = 0 TO 19:X1 = 0:X2 = 39:PY = I: GOSUB 225: NEXT 
    1320  COLOR= CB: FOR I = 0 TO YM:X1 = XL:X2 = XR:PY = I: GOSUB 225: NEXT 
    1350  RETURN 
    1400  DATA 1
    1401  DATA 0,0,1,0,0,1,1,1
    1402  DATA 0,0,1,0,0,1,1,1
    1403  DATA 0,0,1,0,0,1,1,1
    1404  DATA 0,0,1,0,0,1,1,1
    1410  DATA 2
    1411  DATA 0,1,1,1,2,1,3,1
    1412  DATA 1,0,1,1,1,2,1,3
    1413  DATA 0,1,1,1,2,1,3,1
    1414  DATA 1,0,1,1,1,2,1,3
    1420  DATA 12
    1421  DATA 1,1,0,1,1,0,2,1
    1422  DATA 1,1,0,1,1,0,1,2
    1423  DATA 1,1,0,1,2,1,1,2
    1424  DATA 1,1,1,0,2,1,1,2
    1430  DATA 13
    1431  DATA 1,1,0,1,2,1,0,2
    1432  DATA 1,1,1,0,1,2,2,2
    1433  DATA 1,1,0,1,2,1,2,0
    1434  DATA 1,1,1,0,1,2,0,0
    1440  DATA 9
    1441  DATA 1,1,0,1,2,1,2,2
    1442  DATA 1,1,1,0,1,2,2,0
    1443  DATA 1,1,0,1,2,1,0,0
    1444  DATA 1,1,1,0,1,2,0,2
    1450  DATA 3
    1451  DATA 1,1,1,0,0,0,2,1
    1452  DATA 1,1,1,0,0,1,0,2
    1453  DATA 1,1,1,0,0,0,2,1
    1454  DATA 1,1,1,0,0,1,0,2
    1460  DATA 6
    1461  DATA 1,1,0,1,1,0,2,0
    1462  DATA 1,1,0,1,0,0,1,2
    1463  DATA 1,1,0,1,1,0,2,0
    1464  DATA 1,1,0,1,0,0,1,2
    1990  DATA  -1
    2000 X = 0:Y = 0
    2010 NS = 0
    2020  READ C: IF C < > -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
    2030  RETURN 
    21210 P = 1: RETURN 
    30000  TEXT : HOME : END 
    30100  HOME 
    30110  PRINT "GAME PAUSED. PRESS P TO CONTINUE..."
    30120 P = 1
    30130 K =  PEEK(KB): IF K > = H  THEN  POKE KC,H:K = K -H: GOSUB 30200
    30140  IF P  THEN 30130
    30150  HOME 
    30160  PRINT "SCORE ";SC; TAB( 21);"LEVEL ";LM -LV +1
    30170  RETURN 
    30200  ON E(K) GOTO 30000,30210,30210,30210,30210,30220
    30210  RETURN 
    30220 P = 0
    30230  RETURN 
    30300 SC = SC +P
    30310  VTAB 21: HTAB 7
    30320  PRINT SC;
    30330  RETURN 
    30400 RN = RN -1
    30410  FOR C = 0 TO 32
    30415  COLOR= C
    30420  FOR I = 0 TO RN:X1 = XL:X2 = XR:PY = R(I): GOSUB 225: NEXT I
    30430  FOR I = 0 TO 2: NEXT I
    30440  NEXT C
    30450  FOR I = 0 TO RN
    30460 Y = R(I) +I
    30470 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 >0  THEN 30470
    30480 P = 100: GOSUB 30300
    30490  NEXT I
    30495  RETURN 
    31000  VTAB 22: PRINT 
    31010  PRINT "              GAME OVER"
    31020 P = 1
    31030 K =  PEEK(KB): IF K > = H  THEN  POKE KC,H:K = K -H: GOSUB 31200
    31040  IF P  THEN 31030
    31050 D = 1
    31060 SC = 0:LV = LM
    31070  GOSUB 30150
    31080  GOSUB 1300
    31090  GOTO 905
    31200  ON E(K) GOTO 30000
    31210 P = 0: RETURN 
    32000  REM END OF LISTING
    

    If only AppleSoft had a RENUM command, the code might not look so messy

  • making Apple II cassette audio using the Epple-II emulator

    Screenshot of "Epple-II" Apple II emulator running a 3D sync wav plot in purple
    yes, it’s PLOTPOURRI

    as requested on reddit:

    • on Linux, you’ll probably need a development system, 6502 assembler and SDL2 libraries: sudo apt install git build-essential autoconf automake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev xa65
    • download from https://github.com/cmosher01/Epple-II/releases or git clone https://github.com/cmosher01/Epple-II.git
    • similarly, download Apple II ROMs from https://github.com/cmosher01/Apple-II-Source/releases or https://github.com/cmosher01/Apple-II-Source.git
    • build Epple-II: cd Epple-II && ./bootstrap && ./configure && make
    • install Epple-II: sudo make install
    • build ROMs: cd ../Apple-II-Source/ && ./bootstrap && ./configure && make
    • install ROMs: sudo make install
    • comment out demo rom and uncomment your rom choice in /usr/local/etc/epple2/epple2.conf
    • start Epple-II: epple2
      (Don’t try epple2 &; the emulator will hang)
    • in the Epple-II console (F5), create a blank tape image: cassette blank prog.wav
    • in the main Epple-II window, paste in your BASIC source (F7) then save it: SAVE. This may take some time, and there will be a beep
    • back in the Epple-II console, write the tape image: cassette save
    • still in the Epple-II console, close the tape image: cassette eject out
    • your Apple II BASIC program is in the file prog.wav.

    For example, here’s Plotpourri‘s BASIC code saved to tape:

    It’s also a pretty decent Apple II emulator, too.

  • Small things that make me happy …

    Chebucto Community Net in Nova Scotia still has all its downloads and instructions for helping to get an Apple II (8 bit) & Apple IIGS (16 bit) online.

  • Apple IIgs: before and after graphics

    Unless you have the heavy analogue Apple CRT that was specially made for it, composite video output on the Apple IIgs is utterly dismal:

    Apple IIgs: composite to LCD display

    Adding an Apple IIgs → SCART cable through a SCART to HDMI converter is much better:

    Apple IIgs: via SCART and HDMI

    There’s still a little bit of shimmer to the background, but at least text is legible.

  • Most of the Logic Apple II Library now on archive.org


    Well, that’s all the disks I can find easily up on archive.org. There are some Apple IIgs disks still to do, and there might be some random disks lurking in another box, but that’s more than 485 disk images uploaded.

    You can find them by going to Internet Archive Search: creator:”LOGIC (“Loyal Ontario Group Interested In Computers”)”.

  • importing Applesoft BASIC programs on the Apple IIe

    Just what no-one has needed since about 1979 or so …

    BASIC on the Apple II has no easy way to import text as a program. When you LOAD a file, it must be in Apple’s tokenized format. While Apple DOS has the EXEC facility to run script files as if they were typed from the keyboard, it’s very picky about the file format:

    1. There must be a carriage return character (CR, ASCII 13) before the first line
    2. All line numbers must have an extra space before and after them
    3. All tokens must be in upper case
    4. All tokens (keywords and functions) must have a space after them.

    The right way to do this conversion would be to write a tokenizer that spits out the correct binary file. But you can (kinda) fudge it with this shell command, operating from BASIC source PROG.BAS:

    sed 's/^[0-9][0-9]*/& /;s/^/ /;1s/^/\n/;s/$/ /;s/[:()]/ & /g;' PROG.BAS | tr '\n' '\r' | ac.sh -p EG.dsk PROG T

    ac.sh is the command line version of AppleCommander, and the file EG.dsk referred to above is an Apple DOS 3.3 image created with

    ac.sh -dos140 EG.dsk

    It still needs work, as there are functions that will mess this up, and Applesoft’s parser makes a mess of code like IF A THEN …, turning it into IF AT HEN ….

    So if I wanted to import the following futile program:

    10 REM A FUTILE PROGRAM BY SCRUSS
    20 HOME
    30 FOR X=1 TO 20
    40 PRINT SPC(X);"FUTILE"
    50 NEXT X

    Run through the script (but before EOL conversion) it would look like this:

     10  REM A FUTILE PROGRAM BY SCRUSS 
     20  HOME 
     30  FOR X=1 TO 20 
     40  PRINT SPC ( X ) ;"FUTILE" 
     50  NEXT X

    Make a disk and put the modified program text on it:

    ac.sh -dos140 futile.dsk
    sed 's/^[0-9][0-9]*/& /;s/^/ /;1s/^/\n/;s/$/ /;s/[:()]/ & /g;' futile.bas | tr '\n' '\r' | ac.sh -p futile.dsk FUT T

    Load the disk into your Apple II, clear out the init program, and import the code with EXEC FUT:

    If all you get is ] cursors printed and no syntax errors, then something might be working. List it:

    Run it:

    Disk image: futile-AppleII-dsk.zip, containing:

    $ ac.sh -l futile.dsk
    
    DISK VOLUME #254
     T 002 FUT 
     A 002 FUTILE 
    DOS 3.3 format; 134,144 bytes free; 9,216 bytes used.
  • The first of many … Logic Apple II library disks

    TL;DR Update — The disk images are here: creator:”LOGIC (“Loyal Ontario Group Interested In Computers”)”

    The Apple II post from the other day wasn’t as random as it might seem. Through a friend, I got given not just the Apple IIe previously pictured, but also an Apple IIgs and the almost-complete disk library from a local Apple user group.

    Logic (“Loyal Ontario Group Interested in Computers”) appears to be defunct now. The Internet Archive has 20+ years of their website logicbbs.org archived, but the domain no longer resolves. It’s a shame if they are completely gone, because user groups contain social history. Once it’s gone, well … never send to know for whom the CtrlG tolls; it tolls for thee.

    I’m going to archive as much of the Logic disk library as I can. I’ve been chatting with Jason Scott, and he’s keen to see that the disk images are preserved.

    I’d never used an Apple II before. They’re quite, um, different from anything else I’d used. Sometimes hideously low-level (slot numbers!), sometimes rather clever (I/O streams from any of the cards can control the computer). Since nothing but an Apple II can read Apple II disks, I’ve got the IIgs running ADTPro sending images via serial to a Linux machine. It’s pretty quick: a 140 K disk image transfers in around 25 seconds, an 800 K image in just under two minutes. I’m marshalling the images with AppleCommander and trying to keep everything intact despite having little idea what I’m doing.

    (Apple II annoyance: searching for the term is harder than it needs to be, as people will try to use the typography of the time and refer to it as “Apple ][”, or “Apple //”. Even though the Unicodely-correct representation should be “Apple Ⅱ”, nobody uses it. I’m going to stick with the two-capital-eyes version ‘cos it’s easier to type.)