100 ; THE PROGRAM NAME IS 'EDITOR' 8 JUN 87
110 ;
120 DIM AP[4096],CP[4096],T[4096],A$74,C$80,C1$80,E$4,LBL$8,S$4,Z$1
130 CLS:HTAB 20:PRINT "DBASIC TEXT EDITOR  <VER. 1.00>"
140 ;
150 VTAB 8:PRINT " THIS EDITOR CAN USE EITHER ONE OR TWO DISK DRIVES":PRINT
160 PRINT " IF A SECOND DRIVE IS USED, THEN THE SOURCE FILES MUST BE ON IT."
170 PRINT:INPUT "NUMBER OF DRIVES (1 OR 2) ? ",DR%
180 IF DR%<1 GOTO 130 ELSE IF DR%>2 GOTO 130
190 ;
200 CLS:HTAB 20:PRINT "DBASIC TEXT EDITOR  <VER. 1.00>":CMD$="ACDEILOPS"
210 ;
220 C$="":EDIT C$:C1$="":FOR I%=1 TO LEN(C$)
230 IF MID$(C$,I%,1)<>" " THEN C1$=C1$+MID$(C$,I%,1)
240 NEXT I%:Z$=LEFT$(C1$,1):CMD%=INSTR(CMD$,Z$)+1
250 ON CMD% GOSUB BAD_CMD,ADD,CUT,DELETE,EDIT,INSERT,LIST,OPEN,PASTE,SAVE
260 GOTO 220
270 ;
280  "ADD"
290 IF MID$(C1$,1,3)<>"ADD" GOTO APPEND
300 TXSIZN T[],SIZE%,LINE%:IF SIZE%>32600 GOTO ALMOST_FULL
310 A$="":PRINT LINE%+1;:EDIT A$:IF A$="" THEN RETURN
320 TXAPP T[],A$:GOTO 300
330 ;
340  "ALMOST_FULL"
350 PRINT "THE ARRAY IS ALMOST FULL.  SUGGEST SAVE.":RETURN
360 ;
370  "APPEND"
380 IF MID$(C1$,1,6)<>"APPEND" GOTO BAD_CMD
390 LT%=LEN(C1$):IF LT%>6 THEN FT$=MID$(C1$,7,LT%-6) ELSE RETURN
400 TXLOC AP[],AT:DR DR%:BLOAD FT$,AT:DR 1:TXSIZN AP[],ST%,NT%
410 TXSIZN T[],S%,N%:TOTSIZE=FLT(ST%)+FLT(S%):IF TOTSIZE<32601 GOTO 430
420 PRINT "THE TEXT ARRAY IS TOO LARGE TO APPEND":RETURN
430 FOR I%=1 TO NT%:TXGET AP[],A$,I%:TXAPP T[],A$:NEXT I%:RETURN
440 ;
450  "BAD_CMD"
460 PRINT "COMMAND NOT UNDERSTOOD":RETURN
470 ;
480  "CUT"
490 IF CUT%=0 GOTO 530
500 PRINT:INPUT "CLEAR OLD CUT (Y,N) ? ",Z$
510 IF Z$="N" THEN RETURN ELSE IF Z$="n" THEN RETURN
520 IF Z$="Y" GOTO 530 ELSE IF Z$<>"y" GOTO 500
530 CUT%=0:CP[0]=0:TXSIZN T[],SIZE%,X%
540 IF X%=0 THEN PRINT "THERE ARE NO LINES TO CUT !  SORRY !":RETURN
550 INPUT "THE FIRST LINE TO CUT ?",L1%
560 IF L1%>X% THEN PRINT "THERE AIN'T THAT MANY LINES, CLYDE !":GOTO 550
570 IF L1%=X% THEN L2%=X%:GOTO 600
580 INPUT "THE LAST LINE TO CUT ? ",L2%
590 IF L2%>X% THEN PRINT "THERE AIN'T THAT MANY LINES, CLYDE !":GOTO 580
600 L3%=L2%-L1%+1
610 INPUT "CUT OR COPY (0 = CUT,  1 = COPY) ? ",X%
620 IF X%<0 GOTO 610 ELSE IF X%>1 GOTO 610
630 PRINT:PRINT "COPYING THE CUT TO THE TEMPORARY TEXT ARRAY"
640 FOR I%=L1% TO L2%:TXGET T[],A$,I%:TXAPP CP[],A$:NEXT I%:CUT%=1
650 IF X%=0 THEN PRINT "DELETING THE CUT FROM THE TEXT":TXDELN T[],L1%,L3%
660 RETURN
670 ;
680  "DELETE"
690 IF MID$(C1$,1,2)="DR" GOTO DR
700 GOSUB GET_PARMS:IF BAD%>0 THEN RETURN
710 IF S%=0 THEN IF E%=0 THEN RETURN
720 IF S%=0 THEN S%=1
730 IF E%=0 THEN TXSIZN T[],SIZE%,E%
740 TXDELN T[],S%,E%-S%+1:RETURN
750 ;
760  "DR"
770 IF C1$="DR1" THEN DR%=1:RETURN
780 IF C1$="DR2" THEN DR%=2:RETURN ELSE GOTO BAD_CMD
790 ;
800  "EDIT"
810 IF C1$="END" THEN DR 1:END ELSE IF C1$="EXIT" THEN DR 1:END
820 GOSUB GET_PARMS:IF BAD%>0 THEN RETURN
830 IF S%=0 THEN IF E%=0 THEN RETURN
840 IF S%=0 THEN S%=1
850 IF E%=0 THEN TXSIZN T[],SIZE%,E%
860 FOR I%=S% TO E%:TXGET T[],A$,I%
870 PRINT I%;:EDIT A$:TXRPL T[],A$,I%:NEXT I%:RETURN
880 ;
890  "GET_PARMS"
900 ; S%= START, E%= END
910 S%=0:E%=0:BAD%=0:X$="":S$="":E$="":FOR I%=1 TO LEN(C1$)
920 Z$=MID$(C1$,I%,1):IF Z$="-" THEN S$=X$:X$="":GOTO 940
930 IF Z$>="0" THEN IF Z$=<"9" THEN X$=X$+Z$
940 NEXT I%:IF LEN(X$)>4 THEN BAD%=1:GOTO BAD_CMD
950 IF INSTR(C1$,"-")=0 THEN S$=X$
960 E$=X$:IF LEN(S$)=0 GOTO 980
970 FOR I%=1 TO LEN(S$):S%=10*S%+(ASC(MID$(S$,I%,1))-48):NEXT I%
980 IF LEN(E$)=0 GOTO 1000
990 FOR I%=1 TO LEN(E$):E%=10*E%+(ASC(MID$(E$,I%,1))-48):NEXT I%
1000 TXSIZN T[],SIZE%,X%:IF X%=<E% THEN E%=X%
1010 IF S%>X% THEN S%=X%
1020 RETURN
1030 ;
1040  "INSERT"
1050 GOSUB GET_PARMS:IF BAD%>0 THEN RETURN ELSE IF S%=0 THEN RETURN
1060 TXSIZN T[],SIZE%,X%:IF S%>X% THEN RETURN
1070 A$="":PRINT S%;:EDIT A$:IF A$="" THEN RETURN
1080 TXINS T[],A$,S%:S%=S%+1:GOTO 1070
1090 ;
1100  "LIST"
1110 IF LEFT$(C1$,4)="LOAD" GOTO LOAD ELSE GOSUB GET_PARMS:IF BAD%>0 THEN RETURN
1120 IF E%=0 THEN TXSIZN T[],SIZE%,E%
1130 IF S%=0 THEN S%=1
1140 IF E%=0 THEN PRINT "SORRY, NO LINES TO LIST!":RETURN
1150 FOR I%=S% TO E%:TXGET T[],A$,I%:LINE%=I%:GOSUB PR_LINE:NEXT I%:RETURN
1160 ;
1170  "LOAD"
1180 P%=INSTR(C1$,";"):IF P%=0 GOTO 1220
1190 LEN%=LEN(C1$):IF LEN%<>P%+1 GOTO BAD_CMD ELSE Z$=RIGHT$(C1$,1)
1200 IF Z$="1" THEN DR%=1 ELSE IF Z$="2" THEN DR%=2 ELSE GOTO BAD_CMD
1210 C1$=LEFT$(C1$,P%-1)
1220 IF LEN(C1$)<5 THEN RETURN ELSE F$=MID$(C1$,5)
1230 TXLOC T[],A:DR DR%:BLOAD F$,A:DR 1:RETURN
1240 ;
1250  "OPEN"
1260 IF LEN(C1$)>4 THEN F$=MID$(C1$,5):RETURN
1270 ;
1280  "PASTE"
1290 IF LEFT$(C1$,2)="PR" GOTO PRINT ELSE IF LEFT$(C1$,2)<>"PA" GOTO BAD_CMD
1300 IF CUT%=0 THEN PRINT "NOTHING IN THE CUT/PASTE TEMP ARRAY !":RETURN
1310 TXSIZN T[],SIZE%,X%:PRINT
1320 INPUT "INSERT CUT JUST BEFORE WHAT LINE NUMBER ? ",L1%
1330 IF L1%<1 GOTO 1320 ELSE IF L1%=<X%+1 GOTO 1360
1340 INPUT "DO YOU MEAN TO APPEND THE CUT (Y,N) ? ",Z$
1350 IF Z$="Y" GOTO 1360 ELSE IF Z$="y" GOTO 1360 ELSE GOTO 1320
1360 TXSIZN CP[],SIZE%,L3%:IF L1%>X%+1 THEN L1%=X%+1
1370 PRINT "PASTING";L3%;"LINES INTO THE TEXT":PRINT
1380 FOR I%=1 TO L3%:TXGET CP[],A$,I%:TXINS T[],A$,L1%:L1%=L1%+1:NEXT I%
1390 RETURN
1400 ;
1410  "PRINT"
1420 GOSUB GET_PARMS:IF BAD%>0 THEN RETURN
1430 IF E%=0 THEN TXSIZN T[],SIZE%,E%
1440 SELECT PRINT 1:IF S%=0 THEN S%=1
1450 FOR I%=S% TO E%:TXGET T[],A$,I%:LINE%=I%:GOSUB PR_LINE:NEXT I%
1460 SELECT PRINT 0:RETURN
1470 ;
1480  "SAVE"
1490 IF MID$(C1$,1,4)<>"SAVE" GOTO BAD_CMD
1500 P%=INSTR(C1$,";"):IF P%=0 GOTO 1540
1510 LEN%=LEN(C1$):IF LEN%<>P%+1 GOTO BAD_CMD ELSE Z$=RIGHT$(C1$,1)
1520 IF Z$="1" THEN DR%=1 ELSE IF Z$="2" THEN DR%=2 ELSE GOTO BAD_CMD
1530 C1$=LEFT$(C1$,P%-1)
1540 IF LEN(C1$)>4 THEN F$=MID$(C1$,5)
1550 IF F$="" THEN PRINT "NO FILE NAME ASSIGNED YET!":RETURN
1560 TXLOC T[],A:TXSIZN T[],S%,N%:LEN=FLT(S%)
1570 DR DR%:BSAVE F$,A,LEN:DR 1:RETURN
1580 ;
1590 ;
1600 ;
1610 ;
1620 ; THIS IS THE END OF THE ASSEMBLER'S SOURCE EDITOR PROGRAM;
1630 ; UTILITY SUBROUTINES FOLLOW.
1640 ;
1650 ;
1660  "PR_LINE"
1670 H%=10:IF LINE%<100 THEN H%=12 ELSE IF LINE%<1000 THEN H%=11
1680 IF LINE%<10 THEN H%=13
1690 FOR P%=1 TO H%:PRINT " ";:NEXT P%:PRINT LINE%;:Z$=LEFT$(A$,1)
1700 IF Z$=" " THEN PRINT "         ";:GOTO NO_LABEL
1710 IF Z$=";" THEN PRINT A$:RETURN
1720 ;
1730 ; RECOVER AND PRINT THE LABEL
1740 ;
1750 P%=INSTR(A$," "):IF P%=<9 GOTO 1770
1760 PRINT:SELECT PRINT 0:PRINT "THE LABEL IS TOO LONG !":RETURN
1770 LBL$="        ":IF P%=0 THEN PRINT A$:RETURN
1780 MID$(LBL$,1,8)=LEFT$(A$,P%-1):PRINT LBL$;" ";
1790 L%=LEN(A$)+1-P%:A$=MID$(A$,P%,L%)
1800 ;
1810  "NO_LABEL"
1820 C$="":P%=INSTR(A$,";"):IF P%=0 GOTO NO_COMMENT
1830 C$=MID$(A$,P%,22):A$=MID$(A$,1,P%-1)
1840 ;
1850  "NO_COMMENT"
1860 LBL$="        ":P%=INSTR(2,A$," "):IF P%=<9 GOTO 1880
1870 PRINT:SELECT PRINT 0:PRINT "THE MNEMONIC IS TOO LONG !":RETURN
1880 IF P%>0 GOTO 1900 ELSE MNE$="                           "
1890 MID$(MNE$,1,27)=MID$(A$,2,255):PRINT MNE$;:PRINT C$:RETURN
1900 MID$(LBL$,1,8)=MID$(A$,2,P%-2):PRINT LBL$;:MNE$="               "
1910 MID$(MNE$,1,15)=MID$(A$,P%+1):PRINT MNE$;:PRINT C$:RETURN
1920 ;
