Announcements

  • L.E.D.

    L.E.D.

    Line-Oriented Text Editor

    Arnie Lee

    ABACUS SOFTWARE

    Published: Compute! Magazine; Feb, 1981.

    The LED is line-oriented as opposed to word-oriented. As such, it cannot be considered a true word processor although it does provide many of the same capabilities as many of the other commercially available word processors. In fact, a slightly modified version of the LED was used to create this article. Although we wrote the LED to maintain program source statements, its usefulness is by no means limited to that application.

    The LED is a line oriented text editor. The entire source program must be in memory while the user is modifying it. Modifications allowed include appending source to the end of the text, inserting lines of text into the middle of existing text, changing occurrence of a character string to another string, and printing the text to a hard copy device. After creating or modifying the text, the user may then save it onto tape or diskette. Some of the key points to note when using the LED are:

    • Each line is numbered;
    • Each line can contain up to 80 characters;
    • When entering 3 line, the line must be terminated by RETURN key;
    • A maximum of 500 lines of text may be entered (this is subject to the memory capacity of your particular computer);
    • As lines arc inserted or deleted from the source program, the remaining lines arc automatically renumbered;
    • A line of source may extend more than one screen line on your CRT.

    Commands.

    The following arc the descriptions of each of the commands:

    ‘F’

    Enter FILER portion of LED.

    This command allows you to use the LOAD or SAVE commands which arc described below:

    ‘L’

    Load file from tape or diskette.

    This command allows you to load a previously edited source program. The source program may have been saved on tape or diskette. After keying ‘L’ the LED will prompt you for the name of the source program. Key in the filename and depress RETURN. Do not key in the suffix .SOURCE. If you decide that you really don’t want to load a file, then enter a null line instead of a filename. At this point you will be asked if the file was saved on tape or diskette (for the PET version of LED). Type ‘T’ or ‘D’ as appropriate. If the source program is on tape, then you must put the source file tape into cassette #1. For either tape or diskette, the filename that is keyed in must match the filename that is on the storage medium.

    ‘S’

    Save file onto tape or diskette.

    This command allows you to save the current source program onto tape or diskette. After keying ‘S’, the LED will prompt you for the name of the file to be saved. Key in the file-name and then depress RETURN. The file-name is limited to twelve characters. The suffix .SOURCE will be added to the filename by the LED. If you decide that you really don’t want to save a file, then enter a null line instead of a filename.

    At this point you will be asked if you want to save the file onto tape or diskette (for PET version of the LED). Type ‘T’ or ‘D’ as appropriate. If the source is to be saved onto tape, then you must put the tape into cassette #1.

    *** Note that tape is supported only in the PET version.

    ‘A’

    Append the end of source.

    This command allows you to add lines to the end of the current source program. If you have not loaded any source program, then this command will allow you to create a new source program. You may append one or as many lines as you desire. To signal the end of append mode press RETURN when the cursor is sitting at the first character after the line number prompt (null line).

    ‘C’

    Change string.

    This command allows you to change an existing string to a new string. It will make changes to either a single line or to a range of lines. Indicate a single line by keying in its line number followed by RETURN. Indicate a range of lines by keying the line number of the first line to be searched followed by ‘-’ and finally followed by the line number of the last line to be searched followed by RETURN. You will then be prompted for the change siring. The format for the changed string is:

    + from-string + to-string +

    where:

    + is a delimiter — any character may be used but it must not be contained in either the from-string or the to-string.

    from-string is the string of characters which are to be replaced

    to-string is the string of characters which are to replace the from-string in the original source line

    e.g.  /abc/xyz/ 

    in the above example all occurrences of abc will be replaced by xyz.

    e.g.  /abc// 

    in the above example all occurrences of ‘abc’ will be eliminated (replaced by nulls).

    ‘D’

    Delete line or range.

    This command allows you to delete a line or a range of lines from the source program in memory.

    DELETE RANGE(LOW,HIGH)-> 80 will delete line 80

    DELETE RANGE(LOW,HIGH)-> 80-90

    will delete lines 80 thru 90

    DELETE RANGE(LOW-HIGH)-> -20

    will delete all lines thru 20

    ‘I’ insert lines into source program

    This command will allow you to insert lines into the existing source program. LED will prompt you for the line number before which you want to insert the new source statements. You may enter one or as many new lines as you desire. Follow each line with RETURN. To signal the end of INSERT mode press RETURN when the cursor is setting at the first character in the line (null).

    ‘L’ list source program

    This command allows you to list a line or range of lines.

    LIST RANGE(LOW-HIGH)-> 80

    will list line 80

    LIST RANGE(LOW-HIGH)-> 80-100

    will list lines 80 thru 100

    LIST RANGE(LOW-HIGH)-> -20

    will list all lines thru 20

    LIST RANGE(LOW-HIGH)-> NULL

    will list all lines

    With the LIST command only the following features are available:

    PET.

    RUN/STOP key – suspends the listing awaiting the depression of the RETURN key.

    SPACE BAR – scrolls the listing one line at a time

    OFF/RVS key – slows the speeds of the listing

    APPLE II.

    ESC key – suspends the listing awaiting the depression of the RETURN key.

    RETURN key – reverts to normal speed listing after ESC

    SPACE BAR – slows the speed of the listing

    ‘M’

    This command allows you to sec a more complete explanation of the commands than the abbreviated version which prompts you,

    ‘P’

    This command allows you to print a line or range of lines to a hard copy printer. The PET is supported thru the IEEE interface as device 4. The APPLE II is supported thru slot 2. The range specifications are identical as LIST.

    ‘Q’

    Quit LED.

    This command allows you to gracefully exit from the LED. The LED gives you a chance to change your mind so that if you accidentally keyed Q, then you will have another opportunity to save your source file.

    ‘R’

    Replace a line.

    This command allows you to replace a single line only. After keying in the line number to be replaced, the LED will prompt you with that line number. Key in the replacement text and press return.

    e.g. 

    REPLACE -LINE#-> 108

    allows you to replace line 108.

    Listing.

    The listing which follows is the version of the LED for the PET/CBM machines. The version for the APPLE II is very similar to the PET/CBM version and runs under APPLESOFT. The major differences between the two versions are in the routines that handle the disk and printer I/O.

    0 REM LINE EDITOR (c)1980 ABACUS SOFTWARE
    10 DIM T$(500):REM BUFFER SPACE
    20 L$="":REM CURRENT LINE
    30 LL=1:REM LAST LINE #
    40 SP$=" ":DL$=CHR$(20)
    50 EE=0:REM DISK ERROR CHANNEL CLOSED
    60 PR=0: REM PRINT CHANNEL
    90 POKE 144,49:REM DISABLE STOP KEY
    100 PRINT "       ABACUS SOFTWARE LINE EDITOR"
    110 PRINT "      FUNCTIONS:"
    130 PRINT
    140 PRINT TAB(8);"A)PPEND-TO END OF TEXT"
    150 PRINT TAB(8);"C)HANGE-STRING"
    160 PRINT TAB(8);"D)ELETE LINE(S)"
    170 PRINT TAB(8);"F)ILER COMMANDS"
    180 PRINT TAB(8);"I)NSERT BEFORE LINE"
    190 PRINT TAB(8);"L)IST LINE(S)"
    200 PRINT TAB(8);"M)ENU DISPLAY"
    210 PRINT TAB(8);"P)RINT LINE(S)"
    220 PRINT TAB(8);"Q)UIT LEAVE EDITOR"
    230 PRINT TAB(8);"R)EPLACE LINE"
    240 PRINT:PRINT "    ENTER SELECTION-> ";
    250 GOTO 510
    500 PRINT:PRINT "ENTER A,C,D,F,I,L,P,Q,R,M)ENU->";
    510 GET A$:IF A$="" THEN 510
    520 J=0:FOR I=1 TO 10
    530 IF A$=MID$("ACDFILRMQP",I,1) THEN J=I:I=10
    540 NEXT I
    550 PRINT A$
    560 IF J=0 THEN 500
    570 ON J GOTO 1000,2000,3000,4000,5000,6000,7000,100,8000,9000
    1000 PRINT
    1005 PRINT "APPEND TO END OF TEXT"
    1010 PRINT:PRINT LL ">";
    1020 GOSUB 10000:REM GO READ LINE
    1030 IF LEN(L$)=0 THEN 500
    1040 T$(LL)=L$
    1050 LL=LL+1
    1060 GOTO 1010
    2000 REM CHANGE STRING
    2010 PRINT:PRINT "CHANGE";:GOSUB 16000:REM GET RANGE
    2020 IF HI=0 THEN 500
    2025 PRINT "CHANGE STRING->";:GOSUB 10000:REM GET STRING
    2030 L=LEN(L$)
    2040 IF L=0 THEN 500
    2050 IF L<4 THEN 2000
    2060 DM$=LEFT$(L$,1):REM DELIMITER
    2070 IF RIGHT$(L$,1)<>DM$ THEN 2000
    2080 J=0: FOR I=2 TO L-1
    2090     IF MID$(L$,I,1)=DM$ THEN J=I
    2100 NEXT I
    2110 IF J=0 THEN 2000
    2120 IF J=2 THEN 2000
    2130 FR$=MID$(L$,2,J-2)
    2140 IF J+1=L THEN TS$="":GOTO 2160
    2150 TS$=MID$(L$,J+1,L-J-1)
    2160 F=LEN(FR$)
    2170 FOR I=LO TO HI
    2180     T=LEN(T$(I)):S=1:NL$=""
    2190     FOR J=1 TO T-F+1
    2200         IF MID$(T$(I),J,F)<>FR$ THEN 2230
    2210         NL$=NL$+MID$(T$(I),S,J-S)+TS$
    2220         S=J+F:J=S-1
    2230     NEXT J
    2240     IF S<>1 THEN NL$=NL$+RIGHT$(T$(I),T=S+1):T$(I)=NL$
    2250 NEXT I
    2260 GOTO 500
    3000 REM DELETE LINES(S)
    3005 PRINT:PRINT "DELETE ";:GOSUB 16000:REM GET RANGE
    3010 IF NOT DF THEN 3015:REM NOT DEFAULT ON ENTIRE FILE
    3011 PRINT "DELETE ENTIRE FILE? ";
    3012 GET A$:IF A$="" THEN 3012
    3013 PRINT A$:IF A$="N" THEN 500
    3014 IF A$<>"Y" THEN 3011
    3015 IF HI>LL-1 THEN 500
    3020 IF HI=LL-1 THEN LL=LO:GOTO 500
    3030 J=HI-LO+1
    3040 FOR I=LO TO LL-J-1
    3050     T$(I)=T$(I+J)
    3060 NEXT I
    3070 LL=LL-(HI-LO)-1
    3080 GOTO 500
    4000 REM FILER
    4010 PRINT "FILER ENTER L)OAD OR S)AVE-> ";
    4020 GET A$:IF A$="" THEN 4020
    4030 IF A$<>"L" AND A$<>"S" THEN PRINT:GOTO 4000
    4040 PRINT A$:M$=A$
    4050 PRINT "ENTER FILENAME-> ";
    4070 GOSUB 10000
    4075 IF LEN(L$)=0 THEN 500
    4076 IF LEN(L$)>12 THEN 4050
    4080 FI$=L$
    4090 PRINT "ENTER D)ISK OR T)APE-> ";
    4100 GET A$:IF A$="" THEN 4100
    4110 PRINT A$
    4120 IF A$<>"D" AND A$<>"T" THEN 4090
    4130 IF A$="D" THEN 4160:REM DISK ROUTINES
    4140 IF M$="L" THEN 4400
    4150 GOTO 4200
    4160 DR$="":IF LEFT$(FI$,2)<>"0:" AND LEFT$(FI$,2)<>"1:" THEN DR$="0:"
    4170 GOTO 4600
    4200 REM TAPE SAVE
    4210 IF LL=1 THEN PRINT "NO FILE TO SAVE":GOTO 500
    4220 OPEN 2,1,2,FI$+".SOURCE"
    4230 FOR I=1 TO LL-1
    4230     FOR J=1 TO LEN(T$(I))
    4250         PRINT# 2,MID$(T$(I),J,1);
    4260	 NEXT J
    4270     PRINT# 2,CHR$(255);
    4280 NEXT I
    4290 CLOSE 2
    4300 PRINT SPC(6);FI$;" SAVED"
    4310 GOTO 500
    4400 REM TAPE LOAD
    4410 OPEN 2,1,0,FI$+".SOURCE"
    4430 IF=L0:REM LINE COUNT
    4440 LL=LL+1:T$(LL)=""
    4450 GET# 2,A$
    4460 IF ST=64 THEN 4500:REM END OF FILE
    4465 IF ST<>0 THEN PRINT "*** LOAD ERROR ***":GOTO 500
    4470 IF A$=CHR$(255) THEN 4440:REM END OF LINE
    4480 T$(LL)=T$(LL)+A$
    4490 GOTO 4450
    4500 CLOSE 2
    4510 PRINT SPC(6);FI$;" LOADED"
    4520 LL+LL+1
    4530 GOTO 500
    4600 REM DISK SAVE
    4610 IF M$="L" THEN 4800
    4620 IF LL=1 THEN PRINT "NO FILE TO SAVE":GOTO 500
    4630 FL$="@0"+DR$+FI$+".SOURCE,S,W"
    4640 OPEN 2,8,2,FL$
    4650 GOSUB 20000:REM ERROR CHECK
    4655 IF E1<>0 THEN 500
    4660 FOR I=1 TO LL-1
    4670     FOR J=1 TO LEN(T$(I))
    4680         PRINT# 2,MID$(T$(I),J,1);
    4690     NEXT J
    4700     PRINT# 2,CHR$(255);
    4710 NEXT I
    4720 CLOSE 2
    4730 PRINT SPC(6);FI$;" SAVED"
    4740 GOTO 500
    4800 REM DISK LOAD
    4810 FL$=DR$+FI$+".SOURCE,S,R"
    4820 OPEN 2,8,2,FL$
    4830 GOSUB 20000:REM ERROR CHECK
    4835 IF E1<>0 THEN 500
    4840 LL=0:REM LINE COUNT
    4850 LL=LL+1:T$(LL)=""
    4860 GET# 2,A$
    4870 IF ST=64 THEN 4500: REM END OF FILE
    4880 IF ST<>0 THEN GOSUB 20000:GOTO 500
    4890 IF A$=CHR$(255) THEN 4850:REM END OF LINE
    4900 T$(LL)=T$(LL)+A$
    4910 GOTO 4860
    4920 CLOSE 2
    4930 PRINT SPC(6);FI$;" LOADED"
    4940 LL=LL+1
    4950 GOTO 500
    5000 REM INSERT LINE
    5010 PRINT:PRINT "INSERT BEFORE ";:GOSUB 17000:REM GET LINE #
    5015 IF LO>LL OR LO<1 THEN 5000
    5020 PRINT:PRINT LO;">";
    5030 GOSUB 10000:REM READ LINE
    5040 IF LEN(L$)=0 THEN 500
    5050 LL=LL+1
    5060 FOR I=LL TO LO STEP -1
    5070     T$(LO)=L$
    5080 NEXT I
    5090 T$(LO)=L$
    5100 LO=LO+1
    5110 GOTO 5020
    6000 REM LIST LINES
    6010 PRINT:PRINT "LIST ";:GOSUB 16000:REM GET RANGE
    6020 IF HI=0 THEN 500
    6030 SS$="N":PRINT:FOR I=LO TO HI:REM PERFORM LIST
    6040 PRINT I;">";T$(I)
    6050 GET A$:OF A$=CHR$(18) THEN FOR J=1 TO 1024:NEXT J
    6060 IF A$<>CHR$(3) THEN 6110
    6070 SS$="Y"
    6080 GET A$:IF A$=CHR$(13) THEN SS$="N":GOTO 6110
    6090 IF A$<>CHR$(32) THEN 6070
    6100 GOTO 6120
    6110 IF SS$="Y" THEN 6070
    6120 NEXT I
    6130 GOTO 500
    7000 REM REPLACE LINE
    7010 PRINT:PRINT "REPLACE ";:GOSUB 17000:REM GET LINE #
    7020 IF LO>=LL OR LO<1 THEN 7000
    7030 PRINT:PRINT LO;">";
    7040 GOSUB 10000:REM READ LINE
    7050 IF LEN(L$)=0 THEN 500
    7060 T$(LO)=L$
    7070 GOTO 500
    8000 REM QUIT
    8010 PRINT:PRINT "     LEAVE EDITOR-ARE YOU SURE? ";
    8020 GET A$:IF A$="" THEN 8020
    8030 PRINT A$
    8040 IF A$<>"Y" AND A$<>"N" THEN 8000
    8050 IF A$="N" THEN 500
    8060 PRINT:PRINT "           ** END LINE EDITOR **"
    8070 POKE 144,46:REM ENABLE STOP KEY
    8080 END
    9000 REM PRINT LINE
    9010 IF PR=0 THEN PR=4 OPEN PR,PR
    9020 PRINT "PRINT ";:GOSUB 16000:REM GET RANGE
    9030 IF HI=0 THEN 500
    9040 FOR I=LO TO HI:REM PERFORM PRINT
    9050     PRINT# PR,I;": ";T$(I)
    9060 NEXT I
    9070 PRINT# PR
    9080 PRINT# PR,"***";LL-1;"LINES IN BUFFER ***"
    9090 PRINT #PR
    9100 GOTO 500
    10000 REM INPUT A LINE OF TEXT
    10010 L$=""
    10020 PRINT "$<-";
    10030 GET A$:IF A$="" THEN 10030
    10040 IF A$=CHR$(13) THEN PRINT " ":RETURN
    10050 IF LEN(L$)>80 THEN GOTO 15000
    10060 IF A$>=SP$ AND A$<=CHR$(95) THEN 10100
    10065 IF A$>=CHR$(161) AND A$<=CHR$(223) THEN 10100
    10070 IF A$<>DL$ THEN GOTO 10030
    10080 IF LEN(L$)>0 THEN PRINT A$;:L$=LEFT$(L$,LEN(L$)-1)
    10090 GOTO 10020
    10100 L$=L$+A$:PRINT A$;:GOTO 10020
    15000 REM LINE INPUT ERROR
    15010 PRINT:PRINT "ERROR LINE TRUNCATED"
    15020 RETURN
    16000 PRINT "RANGE(LOW,HIGH)-> ";
    16010 GOSUB 10000:REM INPUT RANGE
    16020 LO=1:HI=LL-1:REM DEFAULT LIST ALL
    16025 L=LEN(L$)
    16030 DF=0:IF L=0 THEN DF=-1:GOTO 16150
    16040 J=0:FOR I=1 TO L
    16050 A$=MID$(L$,I,1)
    16060 IF A$>="0" AND A$<="9" THEN 16090
    16070 IF A$="-" THEN J=I:GOTO 16090
    16080 J=99:I=99
    16090 NEXT I
    16100 IF J=99 THEN 16000
    16110 IF J=0 THEN LO=VAL(L$):HI=LO:RETURN
    16120 IF J>1 THEN LO=VAL(LEFT$(L$,J-1))
    16130 IF J<L THEN HI=VAL(RIGHT$(L$,L-J))
    16140 IF LO>HI THEN 16000
    16150 RETURN
    17000 PRINT "-LINE#->";
    17010 GOSUB 10000:REM INPUT LINE#
    17020 L=LEN(L$)
    17030 IF L=0 THEN 17000
    17040 J=0
    17050 FOR I=1 TO L
    17060     A$=MID$(L$,I,1)
    17070     IF A$>="0" AND A$<="9" THEN 17090
    17080     J=99:I=L
    17090 NEXT I
    17100 IF J=99 THEN 17000
    17110 LO=VAL(L$)
    17120 RETURN
    20000 IF EE=0 THEN EE=15:OPEN EE,8,EE
    20010 INPUT# EE,E1,E2$,E3,E4
    20020 IF E1=0 THEN RETURN
    20030 PRINT E1;",";E2$;",";E3:",";E4
    20040 PRINT "*** DISK ERROR ***"
    20050 CLOSE 2
    20060 RETURN
    
  • VIC EDITYPE

    VIC EDITYPE

    A Text Editing And Storage Program

    Paul Bishop

    Compute! Magazine, April 1983, page 50.

    This mini word processor for the VIC lets you cuter, edit, and save text to tape. It works with the VIC 1515 printer and 3K memory expansion.

    If you are at all like me, the minute you saw the VIC-20 sitting there on the showroom table flashing its upper-lowercase mode, you smiled to yourself and said what a wonderful text storage and manipulation device it would make. Wonderful in this context means inexpensive, and Commodore promised us no less in its literature.

    This program is a miniature word processor. It will allow the user to input text, edit it (with certain limitations), and save it to tape. The text may be printed on any line length specified, though it will not right justify. The program uses a word wrapping scheme to minimize the VIC’s limited display size and is meant to be used with the VIC 1515 printer and a 3K memory expansion.

    Entering Text

    The program is menu driven, and we will discuss the options in detail. New mode is used for entering text. It is also the mode in which the for matting features are selected. Centering is done by pressing the up-arrow (next to the restore key) at the beginning of the line that is to be centered. Remember to use the carriage return at the end of the line, and note that the line may not exceed the line length you intend to print.

    The second function is an inset line length. This is selected by pressing the first bracket (shifted colon) at the start of the text to be inset. All text before the next return character will be printed on the alternate line length, which will be specified during printing. Line numbering is something that I use frequently. It is selected with the second bracket, and the line will be printed with a number (numbered sequentially by the computer) before and after the line. Examples of all the formatting options are represented in the demo text.

    Backspacing in the New mode may only be done with the DEL key, and may only continue to the first character of the line on which the cursor rests. Any further DELeting will result in an Illegal Quantity error. If a boo-boo is in an earlier line, it must be corrected in the edit mode. All keys re peat, and the pound symbol (next to CLR HOME) is used to return to the menu. Once the menu is chosen, no further text may be entered in the New mode. (This is something the user could change.)

    A final note: text entry becomes progressively slower as memory fills, and subsequent printing is also adversely affected by large quantities (relatively speaking) of text. So, although the low memory warning should keep you from over-typing the machine’s capacity, it is best to save the text and then continue when the word-wrap starts to slow down.

    Text entered in the New mode can be reviewed and modified in the Edit mode. The mode has three options: Forward, Correct, and Return to Main Menu. The Forward option scrolls through the text one VIC screen line at a time. To make changes in entered text, use the Correct option. You will be given the prompt “error:”, at which point you enter the characters you wish to change as they appear in the text. End your entry with the up-arrow (t) key, not the RETURN key. The next prompt is “correction:”. Enter the text as you wish it to appear in the corrected version. Again follow your input with the up-arrow key rather than RETURN. The computer will then search the text for the “error” and replace it with the “correction.” If the search characters are not found in the text, the program will provide an error message.

    Saving And Printing

    The save mode is straightforward in operation: simply press the S key and RETURN and the text will be stored under the title you entered in the New mode. Load is just like it. If you include a file name, the cassette drive will search for that file; otherwise it will load the first file it comes to. The Load and Print mode is for files too long to be contained in memory and is fairly automatic. You simply set the formatting in the print mode, and let the computer do the rest.

    The Print mode is also straightforward. First it asks for the normal line length. This may be any value up to 80, but between 40 and 70 are recommended. Next you are asked for the inset line length. Again, this should be between 40 and 70. Next you are asked for s for single or d for double spacing. Finally, the computer asks for the number at which it will begin the sequential line numbering. This may be set at any value, but usually will be one.

    Obviously, this program will not meet every one’s writing needs. I am looking forward to further memory expansion which will allow me to implement further editing functions, as well as longer text entry. And you may wish to delete functions which you will not use and add others. That is the beauty of a word processor written in BASIC.

    Before we consider the program in detail, a few comments about operation will be in order here. First, the cursor does not function as well as it should. I am searching for a cure. In the mean time, if you find it more distracting than helpful, you may get rid of it by deleting POKE 204,0 from line 120. Also, from time to time, errors will hap pen which will cause the machine to default to BASIC. This is no cause for alarm. A few moments studying the program listing and a GOTO in the immediate mode will get you out of all but the worst spots. If in doubt, GOTO 51 (the menu).

    Program Structure

    Since I have included no documentation in the body of the program, I will list the various parts of it here. You will want to keep this handy for reference, since every REM you add will cost you valuable memory space.

    Line 42 is initial housekeeping, setting variables and DIMing the text string array.

    Lines 51-67 are the menu.

    Lines 100-280 are the text entry and word wrapping routine, including the delete routine in line 200.

    Lines 3000-3350 are the string search and replace, the “Edit Mode”.

    Lines 3800-4710 are the print routine. Lines 4060-4095 are for getting a string of printing length. Lines 4200-4240 are used in the centering function. 4300-4710 are for tidying up the print strings and sending them to the printer.

    Lines 5000-5080 are the load routine.

    Lines 6000-6080 are for saving text.

    Lines 7000-7009 are for the page numbering function.

    Variable List

    A$ is the actual text string (1 to 200).

    C$ is the get character string in the new mode.

    C4$ is the error string in the edit mode.

    C5$ is the correction string in the edit mode.

    C6$ is the right remainder of the string being searched for the error in the edit mode.

    DE$ is the string of the variable SL.

    J$ is the get character string for the correction string in edit mode.

    M$ is the string for the mode selection in the menu.

    P$ is the print string.

    T1$ is the leftover from P$ after searching for a space at the end of the line.

    W$ is the get string in the edit mode.

    T2$ is the working string of AS in the print mode.

    X$ is the working character in getting an 80-character line for PS.

    Z$ is the get string for the load mode.

    LA is the normal line length.

    LB is the inset line length.

    LC is the line count.

    PC is the page count.

    SL is the line numbering counter.

    Code Listing

    42 PC=1:LC=1:F=0:PRINT CHR$(14): DIM A$(200):PRINT "{CLEAR}":POKE 650,128
    51 M$=""
    53 PRINT "{CLEAR}   MODE SELECTION":PRINT:PRINT:PRINT"LP=LOAD AND PRINT":PRINT
    55 PRINT "N=NEW":PRINT:PRINT"E=EDIT":PRINT:PRINT"P=PRINT"
    58 PRINT:PRINT "S=SAVE":PRINT:PRINT "L=LOAD":PRINT:PRINT "C=CONTINUE"
    60 PRINT:INPUT "SELECT MODE: "; M$
    61 IF M$="E" THEN 3010
    62 IF M$="P" THEN 3800
    63 IF M$="N" THEN 100
    64 IF M$="L" THEN 5000
    65 IF M$="S" THEN 6000
    66 IF M$="LP" THEN 3800
    67 IF M$="C" THEN FOR B=1 TO K-1:PRINT A$(B):NEXT B PRINT A$(K);:GOTO 120
    68 GOTO 51
    100 FOR A=1 TO 200:A$(A)="":NEXT A
    103 INPUT "TYPE FILE NAME";V$
    105 PRINT "{CLEAR}       NEW MODE":K=1
    120 POKE 204,0:POKE 207,0:GET C$:IF C$="" THEN 120:POKE 204:2
    130 IF C$="{DOWN}" THEN 120
    140 IF C$="{UP}" THEN 120
    150 IF C$="{RIGHT}"  THEN 120
    160 IF C$="{LEFT}"  THEN 120
    170 IF C$="@" THEN 51
    171 IF C$="{HOME}" THEN 120
    172 IF C$="{CLEAR}" THEN 120
    175 IF C$=CHR$(20) AND LEN(A$(K))=0 THEN 120
    180 PRINT C$;    
    190 IF C$=CHR$(13) THEN K=K+1:A$(K)=A$(K)+C$:GOTO 120
    200 IF C$=CHR$(20) THEN A$(K)=LEFT$(A$(K),LEN(A$(K))-1):GOTO 120
    210 A$(K)=A$(K)+C$:C$="":IF LEN(A$(K))<22 THEN 120
    220 IF RIGHT$(A$(K),1)=CHR$(32) THEN 240
    221 IF RIGHT$(A$(K),1)=CHR$(160) THEN 240
    230 A$(K+1)=RIGHT$(A$(K),1)+A$(K+1):A$(K)=LEFT$(A$(K),LEN(A$(K))-1):GOTO 220
    240 FOR U=1 TO 22-LEN(A$(K)):PRINT CHR$(20);:NEXT U
    250 IF LEN(A$(K))<11 THEN PRINT,,
    260 IF LEN(A$(K))>10 THEN PRINT,
    264 IF A$(K)="" THEN A$(K)=" "
    265 IF FRE(O)<600 THEN PRINT "{REV}MEMORY LOW{OFF}":PRINT
    266 IF FRE(O)<500 THEN 51
    270 K=K=1:PRINT A$(K);:GOTO 120
    280 GOTO 51
    3010 C4$="":C5$=""
    3015 PRINT "{CLEAR}     EDIT MODE":Q=1
    3025 PRINT:PRINT "F=FORWARD":PRINT "@=RETURN TO MENU":PRINT "C=CORRECT"
    3016 PRINT "SELECTION? "
    3030 GET W$:IF W$="" THEN 3030
    3040 IF W$="F" THEN PRINT A$(Q):Q=Q+1:IF Q>199 THEN 51:GOTO 3030
    3055 IF W$="@" THEN 51
    3066 IF W$="C" THEN 3200
    3061 GOTO 3030
    3200 PRINT "ERROR:"
    3210 FOR A=1 TO 80
    3220     GET J$:IF J$="" THEN 3220
    3225     IF J$="{UP}" THEN 3250
    3226     IF J$=CHR$(20) THEN C4$=LEFT$(C4$,LEN(C4$)-1):GOTO 3235
    3230     C4$=C$+J$
    3235     PRINT J$
    3240 NEXT A
    3250 PRINT:PRINT "CORRECTION: "
    3260 FOR A=1 TO 80
    3270     GET J$:IF J$="" THEN 3270
    3280     IF J$="{UP}" THEN 3310
    3281     IF J$=CHR$(20) THEN C5$=LEFT$(C5$,LEN(C5$)-1):GOTO 3290
    3285     C5$=C5$+J$
    3290     PRINT J$;
    3300 NEXT A
    3310 PRINT "{CLEAR}   {REV}CORRECTING{OFF}"
    3320 FOR A=1 TO 200
    3325     FOR B=1 TO LEN (A$(A))
    3327         O=LEN(C4$)
    3329         IF MID$(A$(A),B,O)=C4$ THEN OO=LEN(A$(A))-B+1-LEN(C4$)
    3330         IF MID$(A$(A),B,O)=C4$ THEN C6$=RIGHT$(A$(A),OO)
    3340         IF MID$(A$(A),B,O)=C4$ THEN A$(A)=LEFT$(A$(A),B-1):GOTO 3344
    3341         GOTO 3346
    3344         A$(A)=A$(A)+C5$+C6$:C4$="":C5$=""
    3345         PRINT "{CLEAR}":FOR H=1 TO A:PRINT A$(H):NEXT H:Q=H::GOTO 3025
    3346     NEXT B
    3347 NEXT A
    3348 PRINT "{CLEAR}{RED}{REV}ERROR NOT FOUND{BLU}{OFF}":PRINT:GOTO 3025
    3350 GOTO 3010
    3800 PRINT:INPUT "NORMAL LINE LENGTH"; LA
    3810 PRINT:INPUT "INSET LINE LENGTH"; LB
    3903 PRINT "SINGLE OR DOUBLE      SPACE? S/D"
    3904 INPUT SD$
    3905 INPUT "LINE NUMBERING #"; SL
    4000 T1$="":N=1:LL=LA
    4002 OPEN 4,4
    4003 T$="":T2$="":P$="":LC=1
    4010 PRINT #4:PRINT #4:PRINT #4
    4016 LC=3
    4040 CLOSE 4,4
    4050 IF A$(N)="" AND M$="LP" THEN 5002
    4051 IF A$(N)="" THEN 4600
    4059 T2$=A$(N)
    4060 FOR A=1 TO LL-LEN(P$)
    4061     T2$="" THEN 4094
    4065     X$=LEFT$(T2$,1):T2$=RIGHT$(T2$,LEN(T2$)-1)
    4075     IF X$="[" THEN LL=LB:GOTO 4060
    4076     IF X$="]" THEN FL=1:GOTO 4060
    4080     IF X$="{UP}" THEN 4200
    4085     IF X$=CHR$(13) THEN 4660
    4090     P$=P$+X$
    4094     IF LEN(T2$)=0 THEN N=N+1:GOTO 4050
    4095 NEXT A
    4100 GOTO 4610
    4200 FOR A=1 TO LA
    4210     X$=LEFT$(T2$,1):T2$=RIGHT$(T2$,LEN(T2$)-1)
    4211     IF LEN(T2$)=0 THEN N=N+1:T2$=A$(N)
    4214     IF A$(N)="" AND LEN (T2$)=0 THEN P$=X$:GOTO 4660
    4220     IF X$=CHR$(13) THEN 4300
    4230     P$=P$+X$
    4240 NEXT A
    4300 IN=(80-LEN(P$))/2:GOTO 4670
    4620 IF RIGHT$(P$,1)=CHR$(32) THEN 4660
    4622 IF RIGHT$(P$,1)=CHR$(160) THEN 4660
    4630 T1$=RIGHT$(P$,1)+T1$:P$=LEFT$(P$,LEN(P$)-1)
    4640 NEXT A
    4660 IF LEFT$(P$,1)=CHR$(32) THEN P$=RIGHT(P$,LEN(P$)-1)
    4661 IF LEFT$(P$,1)=CHR$(160) THEN P$=RIGHT$(P$,LEN(P$)-1)
    4662 PRINT P$
    4665 IN=(80-LL)/2
    4666 DE$=STR$(SL):IF FL=1 THEN OPEN 4,4
    4667 IF FL=1 THEN PRINT #4,CHR$(17)DE$"."SPC(IN-LEN(DE$)-1)P$SPC(75-LEN(P$)-IN)DE$"."
    4668 IF FL=1 THEN CLOSE 4:LC=LC+1:SL=SL+1:P$="":FL=0:P$=T1$:T1$="":GOTO 4680
    4670 OPEN 4,4:PRINT #4,CHR$(17)SPC(IN)P$:CLOSE 4,4:P$="":P$=T1$:T1$="":LC=LC+1
    4680 IF SD$="D" THEN OPEN 4,4:PRINT #4:CLOSE 4:LC=LC+1
    4690 IF LC>60 THEN 7000
    4700 IF X$=CHR$(13) THEN LL=LA
    4701 IF A$(N)="" AND M$="LP" THEN P$=P$+X$:GOTO 5002
    4705 IF A$(N) "" THEN 51
    4710 GOTO 4060
    5000 INPUT "TYPE FILE NAME"; V$
    5002 FOR A=1 TO 200:A$(A)="":NEXT A
    5005 PRINT "{CLEAR}      LOAD MODE"
    5010 OPEN 1,1,0,V$
    5015 PRINT "FILE OPEN, LOADING."
    5020 FOR A=1 TO 200
    5025     FOR B=1 TO 22
    5030         GET #1,Z$
    5031         A$(A)=A$(A)+Z$
    5040         IF Z$="" THEN 5065
    5042     NEXT B
    5050 NEXT A
    5065 CLOSE 1:N=1
    5070 IF M$="LP" THEN N=1:GOTO 4050
    5080 GOTO 51
    6000 PRINT "{CLEAR}SAVE MODE"
    6010 OPEN 1,1,1,V$
    6030 FOR A=1 TO 200
    6040     PRINT #1,A$(A);
    6050     IF A$(A)="" THEN 6075
    6060 NEXT A
    6075 CLOSE 1
    6080 GOTO 51
    7000 OPEN 4,4
    7001 FOR M=1 TO 66-LC
    7002     PRINT #4
    7003 NEXT M
    7004 PRINT #4:PC=PC+1
    7005 PRINT #4,CHR$(17)SPC(70)"PAGE "PC
    7006 PRINT #4
    7007 CLOSE 4
    7008 LC=3
    7009 GOTO 4060
  • PART #1 – Dungeon Of Doom Level Editor

    PART #1 – Dungeon Of Doom Level Editor

    This version for the BBC Micro.

    10 GOSUB 610
    20 COLOUR 3+128:CLS
    30 LET BG=2:LET FG=1:LET T=0:LET L=3:LET LW=W-3:GOSUB 280
    40 COLOUR 2+128:COLOUR 0
    50 PRINT TAB(1,1);"LEVEL GENERATOR";
    60 PRINT TAB(1,2);"THIS IS LEVEL:";LE;
    70 PRINT TAB(1,3);"PRESS H FOR HELP"
    80 LET BG=3:LET FG=2:LET T=5:LET L=15:LET LW=15:GOSUB 280
    90 LET X=1:LET Y=1
    100 LET I$=INKEY$(0)
    110 IF I$="H" THEN GOSUB 360
    120 IF I$="A" AND Y>1 THEN LET Y=Y-1
    130 IF I$="Z" AND Y<15 THEN LET Y=Y+1
    140 IF I$="N" AND X>1 THEN LET X=X-1
    150 IF I$="M" AND X<15 THEN LET X=X+1
    160 IF I$>"/" AND I$<":" THEN GOSUB 230
    170 COLOUR 3+128:COLOUR 0
    180 PRINT TAB(X,Y+5);CHR$(OS);
    190 PRINT TAB(X,Y+5);CHR$(R(X,Y));
    200 IF I$="S" AND IX>0 THEN GOSUB 450:GOTO 20
    210 IF I$<>"F" THEN GOTO 100
    220 STOP
    230 LET I=VAL(I$)
    240 IF I=9 THEN LET I=8+RND(3)
    250 IF I=5 THEN LET IX=X:LET IY=Y
    260 LET R(X,Y)=C0+I
    270 RETURN
    280 PRINT TAB(0,T);
    290 COLOUR FG+128:PRINT LEFT$(B$,LW+2)
    300 COLOUR BG+128:COLOUR FG
    310 FOR I=1 TO L
    320     PRINT TAB(0);CHR$(OS);LEFT$(B$,LW);CHR$(OS)
    330 NEXT I
    340 COLOUR FG+128:PRINT LEFT$(B$,LW+2);
    350 RETURN
    360 COLOUR 128+1:COLOUR 3
    370 FOR H=1 TO 10
    380     PRINT TAB(1,4);H$(H);:GOSUB 430
    390     PRINT TAB(1,4);LEFT$(B$,W-2);
    400 NEXT H
    410 COLOUR 3
    420 RETURN
    430 LET G$=INKEY$(0):IF G$="" THEN GOTO 430
    440 RETURN
    450 PRINT TAB(1,4);"ONE MOMENT PLEASE.";
    460 LET S$=""
    470 FOR J=1 TO 15
    480     FOR K=1 TO 15
    490         LET S$=S$+CHR$(R(K,J))
    500     NEXT K
    510 NEXT J
    520 LET S$=S$+CHR$(IX+OS):LET S$=S$+CHR$(IY+OS)
    530 LET S$=S$+CHR$(LE+OS)
    540 PRINT TAB(1,4);"ANY KEY TO SAVE  ";:GOSUB 430
    550 LET S=OPENOUT "LEVEL"
    560 PRINT#S,S$
    570 CLOSE#S
    580 PRINT TAB(1,4);LEFT$(B$,W)
    590 LET LE=LE+1:GOSUB 700
    600 RETURN
    610 DIM R(15,15),H$(10)
    620 GOSUB 790
    630 DATA "PRESS ANY KEY","TO MOVE A Z N M","1 WALL   2 VASE"
    640 DATA "3 CHEST 4 * IDOL *","5 WAY IN  6 EXIT","7 TRAP","8 SAFE PLACE"
    650 DATA "9 GUARD","0 TO ERASE","S TO SAVE"
    660 LET LE=1
    670 FOR I=1 TO 10
    680     READ H$(I)
    690 NEXT I:GOSUB 810
    700 FOR J=1 TO 15
    710     FOR K=1 TO 15
    720         LET R(J,K)=C0
    730     NEXT K
    740 NEXT J
    750 LET IX=0:LET IY=0
    760 LET B$="":FOR I=1 TO W:LET B$=B$+" ":NEXT I
    770 RETURN
    790 OS=224:C0=OS+6:W=20
    795 MODE 5:VDU 23,0,8202;0;0;0;
    800 RETURN
    810 REM READ THE CHARACTERS
    820 VDU 23,224:FOR I=0 TO 7:READ A:VDU A:NEXT I
    830 FOR I=0 TO 11:VDU 23,230+I
    840     FOR J=0 TO 7:READ A:VDU A:NEXT J
    850 NEXT I:RETURN
    1000 DATA 255,255,255,255,255,255,255,255
    1010 DATA 0,0,0,0,0,0,0,0
    1020 DATA 85,170,85,170,85,170,85,170
    1030 DATA 0,60,24,60,126,126,126,60
    1040 DATA 0,56,100,114,95,73,41,31
    1050 DATA 20,42,20,20,93,93,62,99
    1060 DATA 60,126,255,255,255,253,255,255
    1070 DATA 60,102,195,129,129,129,133,129
    1080 DATA 129,66,36,0,0,36,66,129
    1090 DATA 0,60,66,66,66,66,60,0
    1100 DATA 76,158,170,190,84,30,37,88
    1110 DATA 0,56,84,124,56,44,68,102
    1120 DATA 0,8,28,42,127,85,65,34
    
  • EDIT.BAS

    EDIT.BAS

    Text Editor Prevents “Starvation” and Programming Hassles

    By Donald Fitchhorn

    MITS

    Computer Notes, October 1977.

    Why I wrote an editor

    My main objective in writing an editor was to complement DISK EXTENDED BASIC’s built-in EDIT feature. This feature is invaluable if the location of a needed change is already known. But what about our friend Bob’s problem? He knew WHAT the problem was but not WHERE to find it. What he needs is a program that will search through the entire file until it finds what he wants. Since there isn’t such an editor in Disk Extended BASIC, I wrote my own in BASIC so that it can be easily changed.

    The search command and others like it where the beginnings of my editor, which now has 14 commands. But before we get into an explanation of this editor, let’s review the definition of an editor.

    What is an editor?

    An editor is a program which permits the addition and deletion of lines and characters in one file to make another file. The second file is the new up-to-date file, and the first file is retained as the backup file. Some editors permit the creation of new files and/or use multiple input files. An editor can be as extensive or as minimal as is necessary for an application.

    PROGRAM FILES

    The EDIT program works on ASCII program files. A program file is any file that looks like a program to BASIC. (see EXAMPLE 1.) BASIC doesn’t care if the whole file is REMark statements; it’s only concerned with whether or not there is a line number at the beginning of each line. (See EXAMPLE 2.)

    (NOTE: The EDIT program cannot handle files saved in binary. Save all files in ASCII, i.e. SAVE "FILENAME", 0, A)

    EXAMPLE #1

    10 'THIS IS A PROGRAM FILE
    20 FOR I = 1 TO 100000
    30 PRINT I;RND(I)*1000;I*RND(I)
    40 ' THIS PRINTS SOME NUMBERS
    50 NEXT
    60 END
    

    EXAMPLE #2

    10 'This is a document program file
    20 'here is the
    30 'text of the
    40 'document !
    50 'this is the end.
    
    EXAMPLE #3
    LOWER CASE IS USER TYPED
    
    run"edit
    EDIT -- VERSION 1.0
    INPUT FILE NAME?time
    >r
    EOF1
    CLEARING..........
    >/1
    5 LPRINT"MINUTES","HUNDREDTHS",,"MINUTES","HUNDREDTHS"
    10 FORI=6TO30STEP-1
    20 J=INT(I/60*100)
    21 K=INT((I/30)/60*100)
    30 LPRINTI,J,,I-30,K
    40 NEXT
    >gJ
    20 J
    >cL2
    30 L2=INT(I/60*100)
    >gJ
    30 LPRINTI,J
    >cL2
    30 LPRINTI,L2,,I-30,K
    >gJ
    EOB
    >x
    BACKUP FILE NAME?time.bak
    OK
    load"time
    OK
    list
    5 LPRINT"MINUTES","HUNDREDTHS",,"MINUTES","HUNDREDTHS"
    10 FOR I=60TO30STEP-1
    20 J=INT(I/60*100)
    21 K=INT((I-30)/60*100)
    30 LPRINTI,J,,I-30,K
    40 NEXT
    OK
    

    Saving documents as programs (EXAMPLE 2 format) allows them to be loaded with BASIC. This allows BASIC to be used to alter, delete, and add lines. Of course, line numbers on the finished document may not be wanted, so a short program that reads the file and PRINTs MID$(LINE$, INSTR(LINE$,"'")+1 will print everything to the right of the (‘). Be sure to use LINE INPUT instead of INPUT when reading up LINE$ to prevent truncation because of commas in the text. The (‘)’s in EXAMPLE 2 are necessary if the program file is to be loaded and saved by BASIC. Without the (‘), BASIC will modify the text line.

    BASIC won’t allow lines to be moved around within the file without retyping each line. But with the EDIT program, line numbers can be changed to whatever is wanted. When the edited file is loaded into BASIC, BASIC will put the lines in numerical order.

    Internal structure

    The EDIT program maintains a double-linked list in memory. Each line (L1$(X)) has a pointer to the previous line [M1(X,0)] and to the next line [M1(X,1)] added to it when it is read in. The array (L1$) that the lines are kept in is divided into two parts — ACTIVE CELLS, which have data in them, and INACTIVE CELLS, available for use as data lines. Deleted lines are linked into the INACTIVE CELLS from the ACTIVE CELLS. Inserted lines are written into the first available INACTIVE CELL and then linked into the ACTIVE CELLS. Pointers are maintained for FIRST ACTIVE CELL (LN), FIRST INACTIVE CELL (IN), DOT or position within cell (H) and CELL that DOT is in (J).

    Commands

    My editor, like many others, uses a single letter to select a command. For example, A will advance DOT one line. Most commands may be preceded by a number or a slash (/) to indicate that hey should be executed more than once. 13A will advance DOT 13 lines. OA will position DOT at the beginning of the current line. /A will advance DOT to the end of the page. All commands that allow a prefix will default to one if none is specified. The following is an explanation of the commands. (See TABLE 1 for a list of commands in alphabetical order. See TABLE 2 for a list divided into four main groups).

    TABLE #1
    
                        |-------OPERATES ON --------|--- ALLOWED ---|
    COMMAND DESCRIPTION | LINE | CHAR | DOT  | FILE | 0 | # |-# | / |
    --------------------|------|------|------|------|---|---|---|---|
       A    ADVANCE     |      |      |  *   |      | * | * | * | * |
    --------------------|------|------|------|------|---|---|---|---|
       B    BEGINNING   |      |      |  *   |      |   |   |   |   |
    --------------------|------|------|------|------|---|---|---|---|
       C    CHANGE      |      |  *   |      |      |   |   |   |   |
    --------------------|------|------|------|------|---|---|---|---|
       D    DELETE      |      |  *   |      |      |   | * |   |   |
    --------------------|------|------|------|------|---|---|---|---|
       E    END         |      |      |  *   |      |   |   |   |   |
    --------------------|------|------|------|------|---|---|---|---|
       G    GET         |      |  *   |      |      |   | * |   |   |
    --------------------|------|------|------|------|---|---|---|---|
       I    INSERT      |  *   |  *   |      |      |   |   |   |   |
    --------------------|------|------|------|------|---|---|---|---|
       J    JUMP        |      |      |  *   |      | * | * | * |   |
    --------------------|------|------|------|------|---|---|---|---|
       K    KILL        |  *   |      |      |      |   | * |   | * |
    --------------------|------|------|------|------|---|---|---|---|
       L    LIST        |  *   |      |      |      |   | * |   | * |
    --------------------|------|------|------|------|---|---|---|---|
       N    NEXT        |      |      |      |  *   |   |   |   |   |
    --------------------|------|------|------|------|---|---|---|---|
       R    READ        |      |      |      |  *   |   |   |   |   |
    --------------------|------|------|------|------|---|---|---|---|
       V    VERIFY      |  *   |      |      |      |   |   |   |   |
    --------------------|------|------|------|------|---|---|---|---|
       X    EXIT        |      |      |      |  *   |   |   |   |   |
    --------------------|------|------|------|------|---|---|---|---|
    
    

    TABLE #2
    COMMANDS THAT AFFECT LINES
    I - Inserts lines until, backslash (\) is entered.
    K - Kills entire line. #K & /K are legal.
    L - Lists entire line. #L & /L are legal.
    V - Prints the current line up to DOT.
        (Verify's the position of DOT).
    
    COMMANDS THAT AFFECT CHARACTERS
    C - Changes last character string gotten with G command to
        something else. Use: Ghere
                             Cthere
        will change here to there.
    D - Delete a character. #D legal.
    G - Get string. Searches for occurrence of string.
        Use: 3Gstuff
        Finds third occurrrence of stuff. #G legal.
    I - Insert characters at DOT. Use: Iabcde
        Will insert abcde in current line at DOT.
    
    COMMANDS THAT MOVE DOT
    A - Moves DOT forward or back the number of lines
        specified. 0A, #A, -#A, /A(same as E) legal.
    B - Moves DOT to beginning of page .
    E - Moves DOT to end of page. (same as /A)
    J - Moves DOT forward or back the number of characters
        specified. 0J, #J, -#J legal.
    
    COMMANDS THAT READ AND WRITE THE FILE
    N - Writes out current page and reads in next page.
    R - Read in a new page.
    X - Writes out current page then reads and writes until
        end of file. Closes and renames files.
    

    How to use edit’s commands

    The commands in EDIT are broken up into four groups, as shown in TABLE 2. The use of these commands will be explained in that order.

    The commands that affect lines will work on one line at a time. Or, in the case of K & L, they may be preceded by a number or slash (/) to indicate that they are to be performed on several succeeding lines. TO begin insertion of lines, type I <return> and then the lines to insert. To tell EDIT that the last line to be inserted has been entered, type backslash ().

    Of the commands that affect characters I & C cannot have a # prefix. #D deletes # characters to the right of DOT. G & C work together to allow getting a string and then changing it to something else. G moved DOT ahead of the Nth occurrence of the string. Then C can be used to change the nth occurrence to a new string. It works like C, except instead of changing one string for another, it inserts a new string ahead of DOT.

    The commands that move DOT are A, B, E, and J. B & E require no other specifiers. They simply move DOT to the beginning or end of the current page. A & J move DOT forward or back a specified number of lines or characters.

    The commands N, R, and X read and write the files. R reads the input file until EOF, until it has read 50 lines, or 2000 characters. It then clears and resets the INACTIVE CELLS. N writes out the current page and then executes and R (reads in the next page). X does a series of N’s until the input file is EOF. Then it closes the files and renames them by giving the input file a backup name and the output file the input file’s old name.

    The best way to learn to use EDIT is to load it in and try a few commands. (See EXAMPLE 3). Once you get the hang of it, the power and versatility will be well worth the time it took t type it in.

    The other side of the coin

    All of the above is really wonderful isn’t it? But this program is not without its limitations.

    1. The commands may or may not work the way the user expects them to. This is a typical problem in any new program because the commands take some getting used to. If, after trying it for a while, the user wants a command to work differently or wants to use another command, just remember that the program is written in BASIC, so modifications are easy.
    2. The program allows working on large files by breaking the file into pages. This works out well except for one thing. No matter what the user does, string space is used. Eventually, all available space will be used. At that time, BASIC has to look through all of the string space, shuffling things around and freeing up no-longer-used bytes so that the program will have some more space. This is commonly referred to as GARBAGE COLLECTING. IT can happen at the most unlikely of times and can take as long as five minutes. Unfortunately to the unsuspecting user, it looks as though the program has bombed BASIC out because CTRL-C and RESET don’t help solve the problem. But patience is rewarded and the program does come back to life.

    Modifications and improvements

    I will leave these up to the reader because they are easy to make. For example, suppose a command is needed to exit the program gracefully without making any changes. Follow these steps:

    1. Pick a command character. How about Q for quit?
    2. Alter line 250 to reflect where the program should go if it sees a Q. Let’s make this 1000.
    3. Put in the necessary code to perform the command. 1000 CLOSE:CLEAR 200:END
    4. Save the new program.

    PROGRAM LISTING

    10 '                 == WRITTEN BY D. L. FITCHHORN ==
    15 '                =   *****  ****   *****  *****   =
    20 '               =    *      *   *    *      *      =
    25 '              =     ***    *   *    *      *       =
    30 '               =    *      *   *    *      *      =
    35 '                =   *****  ****     *      *     =
    40 '                 ==   PROGRAMMER - MITS, INC   ==
    45 '
    50 DEFINT A-Z
    55 CLEAR 15000
    60 DIM L1$(100),L2$(13),M1(100,1):FOR I=0 TO 13:READ L2$(I):NEXT
    65 DATA 
       A - ADVANCE,B - BEGINNING,C - CHANGE,D - DELETE,E - END,G - GET,I - INSERT,
       J - JUMP, K - KILL,L -LIST,N = NEXT,R - READ,V - VERIFY,X - EXIT
    70 PRINT "EDIT -- VERSION 1.0":PRINT
    75 LINE INPUT "INPUT FILE NAME?"; N1$
    80 OPEN "I",1,N1$
    85 N2$="EDIT.TMP"
    90 OPEN "O",2,N2$:PRINT #2,""
    95 I=1:J=1:H=1
    100 '---------------------------------------------------------INPUT COMMAND
    105 K=0
    110 IF A$="" THEN FOR Q9=1 TO 5:PRINT CHR$(7);:NEXT:LINE INPUT ">"; A$
    115 A=0:J1=1:U=0:T=1
    120 IF A$="" THEN 105 ELSE I9=INSTR(A$,"\\"):IF I9<>0 THEN S$=LEFT$(A$,I9-1):
        A$=MID$(A$,I9+1) ELSE S$=A$:A$=""
    125 SS=ASC(S$)
    130 IF 64<SS THEN IF 96<SS THEN SS=SS-32:GOTO 170 ELSE GOTO 170
    135 T=VAL(S$)
    140 S=LEN(STR$(T))
    145 IF T=0 THEN IF LEFT$(S$,1)="/" THEN T=400
    150 S$=MID$(S$,S)
    155 IF T<0 THEN S$=MID$(S$,2)
    160 GOTO 125
    165 '             .A  .B  .C  .D  .E  <F> .G  <H> .I  .J  .K  .L  <M>
    170 ON SS-64 GOTO 195,235,245,265,280,180,290,180,320,360,385,425,180,
                      445,180,180,180,465,180,180,180,515,180,525,180,180
    175 '             .N  <O> <P> <Q> .R  <S> <T> <U> .V  <W> .X  <Y> <Z>
    180 FOR N=0 TO 12:PRINT L2$(N):NEXT:GOTO 105
    185 '
    190 '-----------------------------------------------------------A COMMAND
    195 H=1:IF T=0 THEN GOTO 105 ELSE IF T<0 THEN J1=-1
    200 FOR I3=0 TO T-J1 STEP J1
    205     IF M1(J,0)=0 AND J1=-1 THEN GOTO 105
    210     IF M1(J,1)=-1 AND J1=1 THEN J=M1(J,0):GOTO 105
    215     IF J1=1 THEN J=M1(J,1) ELSE J=M1(J,0)
    220 NEXT
    225 GOTO 105
    230 '-----------------------------------------------------------B COMMAND
    235 J=LN:H=1:GOTO 105
    240 '-----------------------------------------------------------C COMMAND
    245 S$=MID$(S$,2):IF K=0 THEN S=LEN(S$):K=H
    250 IF K=1 THEN L1$(J)=S$+MID$(L1$(J),K+S) ELSE L1$(J)=LEFT$(L1$(J),K-1)+
        S$+MID$(L1$(J),K+S)
    255 PRINT L1$(J):H=K+LEN(S$):GOTO 105
    260 '-----------------------------------------------------------D COMMAND
    265 IF H=1 THEN L1$(J)=MID$(L1$(J),H+T):
        ELSE L1$(J)=LEFT$(L1$(J),H-1)+MID$(L1$(J),H+T)
    270 GOTO 105
    275 '-----------------------------------------------------------E COMMAND
    280 IF M1(J,1)=-1 THEN H=1:GOTO 105 ELSE J=M1(J,1):GOTO 280
    285 '-----------------------------------------------------------G COMMAND
    290 S$=MID$(S$,2):S=LEN(S$):IF S=0 THEN GOTO 105
    295 K=INSTR(H,L1$(J),S$):IF K=0 THEN IF M1(J,1)=-1
        THEN PRINT "EOB":A$="":GOTO 105 ELSE J=M1(J,1):H=1:GOTO 295
    300 U=U+1:IF U<T THEN H=K+S:GOTO 295
    305 PRINT LEFT$(L1$(J),K+S-1):H=K
    310 GOTO 110
    315 '-----------------------------------------------------------I COMMAND
    320 IF MID$(S$,2)<>"" THEN 345 ELSE I2=J:IF J=LN THEN LN=IN
    325 LINE INPUT L1$(IN):IF L1$(IN)"\\" THEN 105
    330 I3=M1(IN,1):M1(IN,1)=I2
    335 M1(IN,0)=M1(I2,0):M1(I2,0)=IN:I4=M1(IN,0)
    340 M1(I4,1)=IN:IN=I3:M1(I3,0)=0:GOTO 325
    345 IF H1=1 THEN L1$(J)=MID$(S$,2)+L1$(J) 
        ELSE L1$(J)=LEFT$(L1$(J),H-1)+MID$(S$,2)+MID$(L1$(J),H)
    350 H=H+LEN(S$):GOTO 105
    355 '-----------------------------------------------------------J COMMAND
    360 IF T=0 THEN H=1:GOTO 105
    365 H=H+T:IF H<1 THEN H=1
    370 IF H>LEN(L1$(J)) THEN H=LEN(L1$(J))
    375 GOTO 105
    380 '-----------------------------------------------------------K COMMAND
    385 H=1:I2=J:I3=M1(J,0):FOR J1=1 TO T
    390 IF M1(J,1)=-1 THEN GOTO 410
    395 I4=M1(J,1):L1$(J)="":M1(I4,0)=I3
    400 M1(IN,0)=J:M1(J,0)=0:M1(J,1)=IN:IN=J
    405 J=I4:NEXT
    410 IF I2=LN THEN LN=J ELSE M1(I3,1)=J
    415 GOTO 105
    420 '-----------------------------------------------------------L COMMAND
    425 I2=J:FOR J1=1 TO T
    430 PRINT L1$(I2):IF M1(I2,1)=-1 THEN GOTO 105 ELSE I2=M1(I2,1):NEXT
    435 GOTO 105
    440 '-----------------------------------------------------------N COMMAND
    445 I2=LN
    450 IF M1(I2,1)=-1 THEN GOTO 465 ELSE PRINT #2,L1$(I2):I2=M1(I2,1)
    455 GOTO 450
    460 '-----------------------------------------------------------R COMMAND
    465 J=1:A#=0:LN=1:I=1:FE=0:GOSUB 470:GOTO 105
    470 IF EOF(1) THEN PRINT "EOF1":I=I-1:FE=1:GOTO 495
    475 LINE INPUT #1,L$:IF L$="" THEN GOTO 470
    480 A#=A#+LEN(L$)
    485 L1$(I)=L$:M1(I,0)=I-1:IF I=1 THEN 490 ELSE M1(I-1,1)=I
    490 IF I=50 OR A#>2000 THEN GOTO 495 ELSE I=I+1:GOTO 470
    495 M1(I,1)=I+1:I=I+1:L1$(I)="END OF BUFFER":M1(I,0)=I-1:M1(I,1)=-1:H=1:IN=I+1
    500 FOR I2=IN TO 100:M1(I2,1)=I2+1:M1(I2,0)=I2-1:NEXT
    505 M1(IN,0)=0:M1(I2-1,1)=-1:RETURN
    510 '-----------------------------------------------------------V COMMAND
    515 PRINT LEFT$(L1$(J),H):GOTO 105
    520 '-----------------------------------------------------------X COMMAND
    525 I2=LN
    530 IF M1(I2,1)=-1 THEN GOTO 535 ELSE PRINT #2,L1$(I2):I2=M1(I2,1):GOTO 530
    535 IF FE=0 THEN I=1:A#=0:GOSUB 470 GOTO 525
    540 CLOSE:ON ERROR GOTO 555:LINE INPUT "BACKUP FILE NAME?";N3$:KILL N3$
    545 NAME N1$ AS N3$
    550 NAME N2$ AS N1$: CLEAR 200:END
    555 IF ERR = 53 THEN GOTO 545: ELSE:ON ERROR GOTO 0
  • DESIGN NOTES FOR TINY BASIC

    DESIGN NOTES FOR TINY BASIC

    Dennis Allison, Happy Lady, & friends

    September 1975

    Please see: https://archive.org/details/1975-09-peoples-computer-company/

    SOME MOTIVATIONS

    A lot of people have just gotten into having their own computer. Often they don’t know too much about software and particularly systems software, but would like to be able to program in something other than machine language. The TINY BASIC project is aimed at you if you are one of these people. Our goals are very limited— to provide a minimal BASIC-like language for writing simple programs. Later we may make it more complicated, but now the name of the game is keep it simple. That translates to a limited language (no floating point, no sines and cosines, no arrays, etc, I and even this is a pretty difficult undertaking.

    Originally we had planned to limit ourselves to the 8080, but with a variety of new machines appearing at very low prices, we have decided to try to make a portable TINY BASIC system even at the cost of some efficiency. Most of the language processor will be written in a pseudo language which is good for writing interpreters like TINY BASIC. This pseudo language (which interprets TINY BASIC) will then itself be implemented interpretively.

    To implement TINY BASIC on a new machine, one simply writes a simple interpreter for this pseudo language end not a whole interpreter for TINY BASIC.

    We’d like this to be a participatory design project. This sequence of design notes follows the project which we are doing here at PCC. There may well be errors in content and concept. If you’re making a BASIC along with us, we’d appreciate your help and your corrections.

    Incidentally, were we building a production interpreter or compiler, we would probably structure the whole system quite differently. We chose this scheme because it is easy for people to change without access to specialized tools like parser generator programs.

    THE TINY BASIC LANGUAGE

    There isn’t much to it. TINY BASIC looks like BASIC but all variables are integers. There are no functions yet (we plan to add RND, TAB, and some others later). Statement numbers must be between 1 and 255 so we can store them in a single byte. LIST only works on the whole program. There is no FOR-NEXT statement. We’ve tried to simplify the language to the point where it will fit into a very small memory so impecunious, tyros can use the system.

    The language design was done in consultation with the PCC Dragon. We asked him what he had to have to write a useful program, then we took some of it away. Some other things (computed GOTO labels, for example) come free with our proposed implementation and might be useful.

    The boxes shown define the language. The guide gives a quick reference to what we will include. The formal grammar defines exactly what is a legal TINY BASIC statement. The grammar is important because our interpreter design will be based upon it.

    A SIMPLE TINY BASIC PROGRAM 
    
    100  PRINT  "POWERS” 
    110  INPUT  N 
    120  PRINT  N*N,  N*N*N 
    130  IF  N<>0  THEN  GOTO  110 
    140  END 

    IT’S ALL DONE WITH MIRRORS – OR HOW TINY BASIC WORKS

    All the variables in TINY BASIC: the control information as to which statement is presently being executed and how the next statement is to be found, the return addresses of active GOSUBS — all this information constitutes the state of the TINY BASIC interpreter.

    There are several procedures which act upon this state. One procedure knows how to execute any TINY BASIC statement. Given the starting point in memory of a TINY BASIC statement, it will execute it changing the state of the machine as required. For example,

    100 LET S = A+6 (CR)

    would change the value of S to the sum of the contents of the variable A and the integer 6, and sets the next line counter to whatever line follows 100, if the line exists.

    A second procedure really controls the interpretation process by telling the line interpreter what to do. When TINY BASIC is loaded, this control routine performs some initialization, and then attempts to read a lint of information from the console. The characters typed in are saved in a buffer LBUF. It first checks to see if there is a leading line number. If there is, it incorporates the line into the program by first deleting the line with the same line number (if it is present) then inserting the new line if it is of nonzero length. If there is no line number present, it attempts to execute the line directly. With this strategy, all possible commands, even LIST end CLEAR and RUN are possible inside programs. Suicidal programs are also certainly possible.

    IMPLEMENTATION STRATEGIES AND ONIONS

    When you write a program in TINY BASIC there is an abstract machine which is necessary to execute it. If you had a compiler it would make in the machine language of your computer a program which emulates that abstract machine for your program. An interpreter implements the abstract machine for the entire language and rather than translating the program once to machine code it translates it dynamically as needed. Interpreters are programs and as such have theirs as abstract machines. One can find a better instruction set than that of any general purpose computer for writing a particular interpreter. Then one can write an interpreter to interpret the instructions of the interpreter which is interpreting the TINY BASIC program. And if your machine is microprogrammed (like PACE), the machine which is interpreting the interpreter interpreting the interpreter interpreting BASIC is in fact interpreted.

    TINY BASIC GRAMMAR

    The things in bold face stand for themselves. The names in lower case represent classes of things. “::=” is read “is defined as”. The asterisk denotes zero or more occurrences of the object to its immediate left. Parenthesis group objects, ∅ is the empty set. | denotes the alternative (the exclusive-or).

    line::=number statement (CR) | statement (CR)
    statement::=PRINT expr-list
    IF expression relop expression THEN statement
    GOTO expression
    INPUT var-list
    LET var = expression
    GOSUB expression
    RETURN
    CLEAR
    LIST
    RUN
    END
    expr-list::=(string | expression) ( , (string | expression) * )
    var-list::=var ( , var) *
    expression::=(+ | – | ∅ ) term ( (+ | – ) term) *
    term::=factor ( ( * | / ) factor ) *
    factor::=var | number | ( expression )
    var::=A | B | C … | Y | Z
    number::=digit digit *
    digit::=0 | 1 | 2 … | 8 | 9
    relop::=< ( > | = | ∅ ) | > ( < | = | ∅ ) | =

    A BREAK from the console will interrupt execution of the program.

    QUICK REFERENCE GUIDE FOR TINY BASIC

    LINE FORMAT AND EDITING

    • Lines without numbers executed immediately
    • Lines with numbers appended to program
    • Line numbers must be 1 to 255
    • Line number alone (empty line) deletes line
    • Blanks are not significant, but key words must contain no unneeded blanks
    • “<-” deletes last character
    • XC deletes the entire line

    EXECUTION CONTROL

    CLEAR delete all lines end data  RUN run program
    LIST list program

    EXPRESSIONS

    Operators

    Arithmetic

    + - * /

    Relational

    < > = >= <= <>

    Variables

    A...Z  (26 only) 

    All arithmetic is modulo 215 (± 32762)

    INPUT / OUTPUT

    PRINT  X, Y, Z 
    PRINT  "A  STRING"
    PRINT "THE  ANSWER  IS"
    INPUT  X 
    INPUT  X, Y, Z 

    ASSIGNMENT STATEMENTS

    LET  X=3 
    LET  X=  -3 + 5 * Y 

    CONTROL STATEMENTS

    GOTO  X+10 
    GOTO  35 
    GOSUB  X+35 
    GOSUB 50 
    RETURN 
    IF  X>Y  THEN  GOTO  30 

    This multilayered, onion-like approach gains two things: the interpreter for the interpreter is smaller and simpler to write than an interpreter for all of TINY BASIC, so the resultant system is fairly portable. Secondly, since the major part of the TINY BASIC is programmed in a highly memory efficient, tailored instruction set, the interpreted TINY BASIC will be smaller than direct coding would allow. The cost is in execution speed, but there is not such a thing as a free lunch.

    LINE STORAGE

    The TINY BASIC program is stored, except for line numbers, just as it is entered from the console. In some BASIC interpreters, the program is translated into an intermediate form which speeds execution and saves space. In the TINY BASIC environment, the code necessary to provide the transformation would easily exceed the space saved.

    When a line is read in from the console device, it is saved in a 72-byte array called LBUF (Line BUFfer). At the same time, a pointer, CP, is maintained to indicate the next available space in LBUF. Indexing is, of course, from zero.

    Delete the leading blanks. If the string matches the BASIC line, advance the cursor over the matched string and execute the next IL instruction, If the match fails, continue at the IL instruction labeled lbl.

    The TINY BASIC program is stored as an array called PGM in order of increasing line numbers. A pointer, PGP, indicates the first free place in the array. PGP=0 indicates an empty program; PGP must be less than the dimension of the array PGM, The PGM array must be reorganized when new lines are added, tines replaced, or lines ere deleted.

    Insertion and deletion are carried on simultaneously. When a new line is to be entered, the PGM array searches for a line with a line number greater than or equal to that of the new line.Notice that lines begin at PGM (0) and at PGM (j+1) for every j such that PGM (j) = [carriage return]. If the line numbers are equal, then the length of the existing line is computed. A space equal to the length of the new line is created by moving all lines with line numbers greater than that of the line being inserted up or down as appropriate. The empty line is handled as a special case in that no insertion is made.

    ERRORS AND ERROR RECOVERY

    There are two places that errors can occur, if they occur in the TINY BASIC system, they must be captured and action taken to preserve the system. If the error occurs in the TINY BASIC program entered by the user, the system should report the error and allow the user to fix their problem. An error in TINY BASIC can result from a badly formed statement, an illegal action (attempt to divide by zero, for example), or the exhaustion of some resource such as memory space. In any case, the desired response is some kind of error message. We plan to provide a message of the form:

    ! mmm AT nnn 

    where mmm is the error number and nnn is the line number at which it occurs. For direct statements, the form will be:

    ! mmm 

    since there is no line number.

    Some error indications we know we will need are:

    1. Syntax error
    2. Missing line
    3. Line number too large
    4. Too many GOSUBs
    5. RETURN without GOSUB
    6. Expression too complex
    7. Too many lines
    8. Division by zero

    THE BASIC LINE EXECUTOR

    The execution routine is written in the interpretive language, IL. It consists of a sequence of instructions which may call subroutines written in IL, or invoke special instructions which are really subroutines written in machine language. Two different things are going on at the same time. The routines must determine if the TINY BASIC line is a legal one and determine its form according to the grammar; secondly, it must call appropriate action routines to execute the line. Consider the TINY BASIC statement:

    GOTO 100

    At the start of the line, the interpreter looks for BASIC key words {LET, GO. IF, RETURN, etc.) In this case, it finds GO, and then finds TO. By this time it knows that it has found a GOTO statement. It then calls the routine EXPR to obtain the destination line number of the GOTO. The expression routine calls a whole bunch of other routines, eventually leaving the number 100 (the value of the expression) in a special place, the top of the arithmetic expression stack. Since everything is legal, the XFER operator is invoked to arrange for the execution of line 100 (if it exists) as the next line to be executed.

    Each TINY BASIC statement is handled similarly. Some procedural section of an IL program corresponds to tests for the statement structure and acts to execute the statement.

    ENCODING

    There are a number of different considerations in the TINY BASIC design which fall in this general category. The problem is to make efficient use of the bits available to store information without loosing out by requiring a too complex decoding scheme.

    In a number of places we have to indicate the end of a string of characters (or else we have to provide for its length somewhere). Commonly, one uses a special character (NUL = 00H for example) to indicate the end. This costs one byte per string but is easy to check, A better way depends upon the fact that ASCII code does not use the high order bit; normally It is used for parity on transmission. We can use it to indicate the end (that is, last character) of a string. When we process the characters we must AND the character with 07FH to scrub off the flag bit.

    The interpreter opcodes can be encoded into a single byte. Operations fall into two distinct classes–those which call machine language subroutines, and those which either call or transfer within the IL language itself, The diagram indicates one encoding scheme. The CALL operations have been subsumed into the IL instruction set. Addressing is shown to be relative to PC for IL operations. Given the current IL program size, this seems adequate. If it is not, the address could be used to index an array with the ML class instructions.

    TINY BASIC INTERPRETIVE OPERATIONS

    TST lbl,'string'

    Delete leading blanks.

    If string matches the BASIC line, advance cursor over the matched string and execute the next IL instruction. If a match fails, execute the It instruction at the labeled lbl.

    CALL lbl

    Execute the IL subroutine starting at lbl. Save the IL address following the CALL on the control stack.

    RTN

    Return to the IL location specified by the top of the control stack.

    DONE

    Report a syntax error if after deletion leading blanks the cursor is not positioned to read a carriage return.

    JMP lbl

    Continue execution of IL at the label specified.

    PRS

    Print characters from the BASIC text up to but not including the closing quote mark. If a (CR) is found in the program text, report an error. Move the cursor to the point following the closing quote.

    PRN

    Print number obtained by popping the top of the expression stack.

    SPC

    Insert spaces to move the print head to next zone,

    NLINE

    Output CRLF to Printer.

    NXT

    If the present mode is direct (line number zero), then return to line collection. Otherwise, select the next sequential line and begin interpretation.

    XFER

    Test value at the top of the AE stack to be within range. If not, report an error. If so, attempt to position cursor at that line. If it exists, begin interpretation there; if not report an error.

    SAV

    Place present line number on SBRSTK. Report overflow as error.

    RSTR

    Replace current line number with value on SBRSTK, If stack is empty, report error,

    CMPR

    Compare AESTK(SP), the top of the stack, with AESTK (SP – 2) as per the relation indicated by AESTK(SP – 1). Delete all from stack. If condition specified did not match, then perform NXT action.

    INNUM

    Read a number from the terminal and push its value onto the AESTK.

    FIN

    Return to the line collect routine.

    ERR

    Report syntax error and return to line collect routine.

    ADD

    Replace top two elements of AESTK by their sum.

    SUB

    Replace top two elements of AESTK by their difference.

    NEG

    Replace top of AESTK with its negative.

    MUL

    Replace top two elements of AESTK by their product

    DIV

    Replace top two elements of AESTK by their quotient

    STORE

    Place the value at the top of the AESTK into the variable designated by the index specified by the value immediately below it. Delete both from the stack.

    TSTV lbl

    Test for variable (i.e. letter) if present. Place its index value onto the AESTK and continue execution at next suggested location. Otherwise, continue at lbl.

    TSTN lbl

    Test for number. If present, place Its value onto the AESTK and continue execution at next suggested location. Otherwise, continue at lbl.

    IND

    Replace top of stack by variable value if indexes.

    LST

    List the contents of the program area.

    INIT

    Performs global initialization

    Clears program area, empties GOSUB stack, etc.

    GETLINE

    Input a line to LBUF.

    TSTL lbl

    After editing leading blanks, look for a line number. Report error if invalid; transfer to lbl if not present.

    INSRT

    Insert line after deleting any line with same line number.

    XINIT

    Perform initialization for each stated execution.

    Empties AEXP stack.

    A STATEMENT EXECUTOR WRITTEN IN IL

    This program in IL will execute a TINY BASIC statement. The operators TST, TSTV, TSTN, and PRS all use a cursor to find characteristics of the TINY BASIC line. Other operations (NXT, XPER) move the cursor so it points to another TINY BASIC line.

    THE IL CONTROL SECTION

    START:    INIT                     ; INITIALIZE 
              NLINE                    ; WRITE  CR/LF 
    CO:       GETLINE                  ; WRITE PROMPT & GET A  LINE 
              TSTL      XEC            ; TEST  FOR  LINE  NUMBER 
              INSRT                    ; INSERT IT (MAY BE DELETE) 
              JMP       CO
    STMT:     XINIT                    ; INITIALIZE FOR EXECUTION

    STATEMENT EXECUTOR

    STMT:     TST       S1,'LET'       ; IS STATEMENT A LET?
              TSTV      S16            ; YES. PLACE VAR ADDRESS ON AESTK.
              CALL      EXPR           ; PLACE EXPR VALUE ON AESTK.
              DONE                     ; REPORT ERROR IF (CR) NOT NEXT.
              STORE                    ; STORE RESULT.
              NXT                      ; AND SEQUENCE TO NEXT.
    S1:       TST       S3,'GO'        ; GOTO OR GOSUB?
              TST       S2,'TO'        ; YES ...TO OR ...SUB.
              CALL      EXPR           ; GET LABEL.
              DONE                     ; ERROR IF (CR) NOT NEXT.
              XPER                     ; SET UP AND JUMP. 
    S2:       TST      S14,'SUB'       ; ERROR IF NO MATCH. 
              CALL EXPR                ; GET DESTINATION. 
              DONE                     ; ERROR IF (CR) NOT NEXT.
              SAV                      ; SAVE RETURN LINE.
              XFER                     ; AND JUMP.
    S3:       TST       S8,'PRINT'     ; PRINT.
    S4:       TST       S7,'"'         ; TEST FOR QUOTE.
              PRS                      ; PRINT STRING.
    S5:       TST       S6,','         ; IS THERE MORE?
              SPC                      ; SPACE TO NEXT ZONE.
              JMP       S4             ; YES. JUMP BACK.
    S6:       DONE                     ; NO, ERROR IF NO (CR).
              NLINE
              NXT
    S7:       CALL      EXPR           ; GET EXPR VALUE.
              PRN                      ; PRINT IT.
              JMP       S5             ; IS THERE MORE? 
    S8:       TST       S9,'IF'        ; IF STATEMENT.
              CALL      EXPR           ; GET EXPRESSION.
              CALL      RELOP          ; DETERMINE OPR AND PUT ON STK.
              CALL      EXPR           ; GET EXPRESSION.
              CMPR                     ; PERFORM COMPARISON-PERFORMS NEXT IF FALSE.
              JMP       STMT           ; GET NEXT STATEMENT.
    S9:       TST       S12,'INPUT'    ; INPUT STATEMENT.
    S10:      CALL      VAR            ; GET VAR ADDRESS.
              INNUM                    ; MOVE NUMBER FROM TTY TO AESTK.
              STORE                    ; STORE IT.
              TST       S11,','        ; IS THERE MORE?
              JMP       S10            ; YES.
    S11:      DONE                     ; MUST BE (CR).
              NXT                      ; SEQUENCE TO NEXT.
    S12:      TST       S13,'RETURN'   ; RETURN STATEMENT.
              DONE                     ; MUST BE (CR).
              RSTR                     ; RESTORE LINE NUMBER OF CALL. 
              NXT                      ; SEQUENCE TO NEXT STATEMENT.
    S13:      TST       S14,'END'
              FIN
    S14:      TST       S15,'LIST'     ; LIST COMMAND.
              DONE
              LST
              NXT
    S15:      TST       S16,'RUN'      ; RUN COMMAND. 
              DONE
              NXT 
    S16:      TST       S17,'CLEAR'    ; CLEAR COMMAND.
              DONE
              JMP       START
    
    S17:      ERR                      ; SYNTAX  ERROR.
    
    EXPR:     TST       E0,'-'         ; TEST FOR UNARY -.
              CALL      TERM           ; GET VALUE.
              NEG                      ; NEGATE IT.
              JMP       E1             ; LOOK FOR MORE.
    E0:       TST       E1,'+'         ; TEST FOR UNARY +.
              CALL      TERM           ; LEADING TERM.
    E1:       TST       E2,'+'
              CALL      TERM           ; SUM TERM.
              ADD
              JMP       E1
    E2:       TST       E3,'-'         ; ANY MORE? 
              CALL      TERM           ; DIFFERENCE TERM.
              SUB
              JMP       E3
    E3: T2:   RTN                      ; ANY MORE?
    TERM:     CALL      FACT
    T0:       TST       T1,'*' 
              CALL      FACT           ; PRODUCT FACTOR 
              MPY
              JMP       T0
    T1:       TST       T2,'/'         ; ANY MORE?
              CALL      FACT           ; QUOTIENT FACTOR.
              DIV 
              JMP       T0
    
    FACT:     TSTV      F0             ; VARIABLE.
              IND                      ; YES, GET THE VALUE.
              RTN 
    F0:       TSTN      F1             ; NUMBER, GET ITS VALUE.
              RTN
    F1:       TST       F2,'('         ; PARENTHESIZED EXPR.
              CALL      EXPR
              TST       F2,')'         ; MATCHING PARENTHESIS.
              RTN 
    F2:       ERR                      ; ERROR.
    
    RELOP:    TST       R0,'='
              LIT       0              ; =
              RTN
    R0:       TST       R4,'<'
              TST       R1,'='
              LIT       2              ; <=
              RTN
    R1:       TST       R3,'>'
              LIT       3              ; <>
              RTN
    R3:       LIT       1              ; < 
              RTN
    R4:       TST       S17,'>'
              TST       R5,'=' 
              LIT       5              ; >=
              RTN
    R5:       TST       R6,'<'
              LIT       3              ; <>
    R6:       LIT       4              ; >
              RTN 

    WE’RE NOT DONE YET

    This isn’t everything one needs to make a TINY BASIC. It’s just a beginning and nothing is tested yet. We’ll have more next issue. In the meantime, we welcome your comments, ideas, letters, and corrections.

  • Introduction

    Introduction

    The original purpose of this project was to design and then construct computers that would be able to survive a societal collapse.

    After working on the project, it became apparent that the point of the project should not be to imagine a hypothetical future, but to engage practically with the problems of the present.

    The entire computing stack of the modern era is large, confusing, and unsafe. People would rather excuse themselves from having to learn about it. Who can blame them?

    The first aim of the project is to be exceedingly cost effective: “if the oppressed cannot access some technology, then it is not revolutionary”.

    The second aim of the project is the promotion of digital literacy. Digital literacy should promote a joyful user experience that is non-exploitative. It should also foster a sense of community–“no-one is an island”.

    To this end, the scope of the people’s permacomputer project was deliberately limited to programs around or just over 100 lines. Definitely not more than 200.

    The project therefore decided to investigate BASIC as the paradigmatic human-computer interface for the permacomputer.

    For the application towards which it was targeted, the investigation the project has done so far into BASIC has been fruitful, and even quite surprising–the 70s/80s hobby computing scene was far richer and more creative than the project previously assumed: not less than five (5) different text editors in BASIC were unearthed!

  • Hello world!

    Welcome to WordPress. This is your first post. Edit or delete it, then start writing!