NAM EDLIN OPT PAG PAG * EDLIN - SIMPLE LINE EDITOR FOR SK*DOS/68K * COPYRIGHT (C) 1987, 1988 BY PETER A. STARK * VERSION 1.1 - 3-2-87 - USE LPOINT INSTEAD OF GETNXT * VERSION 1.2 - 3-7-87 - EXPANDED HELP MESSAGE * VERSION 1.3 - 9-10-87 - FIXED FERROR RETURN * VERSION 1.4 - 1-25-88 - ADDED GLOBAL FIND AND CHANGE * EQUATES TO SK*DOS LIB SKEQUATE START BRA.S START1 DC.W $0104 VERSION RESTRT MOVE.L STACKA(PC),A7 RESET STACK POINTER BRA.L L200 AND GO TO COMMAND LOOP DC.B 'COPYRIGHT (C) 1987 BY PETER A. STARK, ' DC.B 'STAR-K SOFTWARE SYSTEMS CORP.' START1 DC SEENXT LOOK AT NEXT CHAR LEA RESTRT(PC),A5 MOVE.L A5,BREAKA(A6) SET RESTART ADDRESS LEA STACKA(PC),A5 MOVE.L A7,(A5) SAVE STACK POINTER CMP.B #$3F,D5 HELP?? BEQ.L HELP YES *: 25 ON ERROR GOTO 9900 *: 26 MAX-LINE = 255 :REM CALCULATE MAXIMUM NUMBER OF LINES MOVE.L MEMEND(A6),D7 MEMORY END LEA BUFFER(PC),A0 SUB.L A0,D7 MEMORY AVAILABLE DIVU #80,D7 /80 = NUMBER OF LINES LEA MAXLIN(PC),A5 MOVE.W D7,(A5) SAVE MAXLINE CMP.W #5,D7 CHECK FOR AT LEAST 5 LINES BCS.L NOTENU NOT ENOUGH MEMORY IF 0 *: 28 CURRENT-LINE = 0 LEA CURLIN(PC),A5 MOVE.W #0,(A5) *: 30 DIM LINE$(MAX-LINE) * NOT NEEDED *: 40 INPUT "FILE NAME", FILE-NAME$ MOVE.L A6,A4 POINT TO USER FCB DC GETNAM GET FILE SPEC INTO FCB BCS.L HELP GIVE HELP IF INVALID NAME * FILE SPEC WAS OK; DEFAULT TO .TXT MOVE.B #1,D4 DEFAULT EXTENSION CODE DC DEFEXT DEFAULT TO .TXT *: 50 OPEN OLD FILE-NAME$+".TXT" AS 1 *: 60 REM IF EXISTS THEN 100 :REM READ IT IF IT EXISTS * NOW ACTUALLY OPEN THE FILE DC FOPENR OP CODE FOR OPEN FOR READ BEQ.S L100 OK IF OPENED CORRECTLY MOVE.B FCBERR(A4),D7 ELSE CHECK ERROR CODE CMP.B #4,D7 NOT THERE? BEQ.S L70 OK IF NOT THERE QERROR DC PERROR ELSE PRINT ERROR MESSAGE STOP DC WARMST *: 70 LAST-LINE=0 L70 LEA LASLIN(PC),A5 CLR.W (A5) LEA NEWMSG(PC),A4 DC PSTRNG PRINT "NEW FILE:" BRA.L L200 *: 100 FOR I=1 TO MAX-LINE *: 110 INPUT LINE #1, LINE$(I) *: 120 REM IF END OF FILE, THEN 190 *: 130 NEXT I L100 MOVE.L #1,D0 I L100A MOVE.L D0,D1 MULU #80,D1 OFFSET INTO BUFFER LEA BUFFER(PC),A0 ADD.L D1,A0 POINT TO BEGINNING OF LINE MOVE.L #1,D1 CHARACTER COUNTER * MAIN LOOP TO READ EACH LINE RDMAIN DC FREAD GO READ THE NEXT CHARACTER BEQ.S CHAROK GO ON IF NO ERROR * IF THERE WAS AN ERROR, SEE IF END OF FILE CMP.B #8,FCBERR(A4) IS ERROR END OF FILE (IE) ERROR BNE.S QERROR NOT END OF FILE, SO REAL ERROR DC FCLOSE ON E-O-F, JUST CLOSE FILE BEQ.L L190 MOVE.B FCBERR(A4),D7 CHECK ERROR TYPE CMP.B #22,D7 CLOSE ERROR? BNE.L QERROR NO, MUST BE SERIOUS BRA.L L190 TO LINE 190 ON EOF * CONTINUE IF CHARACTER IS OK CHAROK CMP.B #$0A,D5 IS IT LINE FEED? BEQ.S RDMAIN YES, IGNORE IT CMP.B #$0D,D5 BEQ.S CHARO1 ACCEPT CR EVEN IF 80TH CMP.B #80,D1 CHECK COUNTER BCC.S LINFUL IF LINE IS FULL CHARO1 MOVE.B D5,(A0)+ SAVE CHARACTER ADD.B #1,D1 BUMP COUNTER CMP.B #$0D,D5 IS CHAR A CR? BNE.S RDMAIN NO, SO READ NEXT ADD.L #1,D0 ADD 1 TO I COUNTER CMP.W MAXLIN(PC),D0 CHECK IF STILL ROOM BLS.S L100A YES, SO READ NEXT LINE BRA.S L140 LINFUL MOVE.B #$0D,(A0) END LINE WITH CR MOVE.L D5,A2 TEMP SAVE CHARACTER LEA LTLMSG(PC),A4 DC PSTRNG PRINT "LINE " MOVE.L D0,D4 CLR.L D5 DC OUT5D PRINT LINE NUMBER LEA LT2MSG(PC),A4 DC PNSTRN PRINT "TOO LONG ... SPLIT UP' MOVE.L A6,A4 POINT BACK TO FCB MOVE.L A2,D5 RESTORE CHARACTER ADD.L #1,D0 ADD 1 TO I COUNTER CMP.W MAXLIN(PC),D0 CHECK IF STILL ROOM BHI.S L140 NO MOVE.L D0,D1 MULU #80,D1 OFFSET INTO BUFFER LEA BUFFER(PC),A0 ADD.L D1,A0 POINT TO BEGINNING OF LINE MOVE.L #1,D1 CHARACTER COUNTER BRA.S CHAROK AND THEN CONT WITH SAME CHAR *: 140 PRINT "MEMORY FULL" L140 LEA MFLMSG(PC),A4 DC PSTRNG PRINT "MEMORY FULL" *: 190 LAST-LINE = I-1 L190 MOVE.L D0,D7 SUB.W #1,D7 LEA LASLIN(PC),A5 MOVE.W D7,(A5) *: 195 CLOSE 1 MOVE.L A6,A4 DC FCLOSE *: 199 REM COMMAND LOOP *: 200 IF CURRENT-LINE<>0 THEN GOSUB 1700 :REM PRINT CURRENT LINE L200 MOVE.W CURLIN(PC),D7 BEQ.S L210 BSR.L L1700 *: 210 PRINT "#"; L210 DC PCRLF MOVE.B #$23,D4 DC PUTCH *: 212 INPUT A$ DC INLINE *: 213 NUMBER=0 CLR.L D1 NUMBER *: 214 COMMAND$=LEFT$(A$,1) L214 DC GETNXT GET NEXT CHARACTER *: 216 DIGIT = ASC(COMMAND$)-48 MOVE.L D5,D7 SUB.B #$30,D7 *: 218 IF DIGIT<0 OR DIGIT>9 THEN 230 :REM NOT NUMBER CMP.B #9,D7 BHI.S L230 IF >9 *: 220 NUMBER=NUMBER*10 + DIGIT MULU #10,D1 ADD.B D7,D1 *: 222 A$=MID$(A$,2) :REM REMOVE DIGIT * ALREADY DONE WITH GETNXT *: 224 GOTO 214 BRA.S L214 *: 230 IF NUMBER>0 AND NUMBER<=LAST-LINE THEN CURRENT-LINE=NUMBER L230 TST.W D1 BEQ.S L240 SKIP IF ZERO CMP.W LASLIN(PC),D1 BHI.S L240 SKIP IF NUM>LAST-LINE LEA CURLIN(PC),A5 MOVE.W D1,(A5) ELSE SET CURRENT LINE *: 240 A$=MID$(A$,2) :REM SEPARATE INTO COMMAND AND REST OF LINE * ALREADY DONE WITH GETNXT *: 300 IF COMMAND$="P" THEN GOSUB 1000 : GOTO 210 :REM PRINT L240 DC TOUPPR CONVERT TO UPPER CASE CMP.B #$50,D5 BNE.S L310 BSR.L L1000 BRA.S L210 *: 310 IF COMMAND$="S" THEN GOTO 2000 :REM SAVE AND EXIT L310 CMP.B #$53,D5 BEQ.L L2000 *: 320 IF COMMAND$="F" THEN GOSUB 3000 : GOTO 210 :REM FIND CMP.B #$46,D5 BNE.S L330 BSR.L L3000 BRA.S L210 *: 330 IF COMMAND$="C" THEN GOSUB 4000 : GOTO 210 :REM CHANGE L330 CMP.B #$43,D5 BNE.S L340 BSR.L L4000 BRA.L L210 *: 340 IF COMMAND$="I" THEN GOSUB 5000 : GOTO 200 :REM INSERT L340 CMP.B #$49,D5 BNE.S L350 L340A BSR.L L5000 BRA.L L200 *: 350 IF COMMAND$="G" THEN GOSUB 6000 : GOTO 200 :REM GO L350 CMP.B #$47,D5 BNE.S L360 BSR.L L6000 BRA.L L200 *: 360 IF COMMAND$="D" THEN GOSUB 7000 : GOTO 200 :REM DELETE L360 CMP.B #$44,D5 BNE.S L370 BSR.L L7000 BRA.L L200 *: 370 IF COMMAND$="Q" THEN GOSUB 8000 : GOTO 200 :REM QUIT L370 CMP.B #$51,D5 BNE.S L390 BSR.L L8000 BRA.L L200 *: 390 IF COMMAND$="?" THEN GOSUB 9000 : GOTO 200 :REM HELP L390 CMP.B #$3F,D5 BNE.S L500 BSR.L L9000 BRA.L L200 *: 500 PRINT "UNKNOWN COMMAND" : GOTO 200 L500 LEA HUHMSG(PC),A4 DC PSTRNG BRA.L L200 *: 1000 REM PRINT COMMAND P, PNUMBER, P#NUMBER, P! *: 1005 IF CURRENT-LINE = 0 THEN RETURN L1000 MOVE.W CURLIN(PC),D7 BNE.S L1010 RTS *: 1010 IF A$="" THEN GOSUB 1700 : RETURN :REM PRINT 1 L1010 DC SEENXT LOOK AT NEXT CHAR CMP.B #$0D,D5 CR? BEQ.S L1700 YES, PRINT CURRENT LINE *: 1015 IF LEFT$(A$,1)="!" THEN FINAL-LINE=LAST-LINE : GOTO 1200 CMP.B #$21,D5 ! ? BNE.S L1020 NO, SO SKIP MOVE.W LASLIN(PC),D7 YES LEA FINLIN(PC),A5 MOVE.W D7,(A5) FINAL = LAST BRA.S L1200 *: 1020 IF LEFT$(A$,1)<>"#" THEN GOTO 1100 :REM NOT LINE NUMBER L1020 CMP.B #$23,D5 BNE.S L1100 * LINE WAS IN P#NUMBER FORMAT, SO RECOVER THE NUMBER *: 1025 REM SPECIFIED #NUMBER *: 1027 A$=MID$(A$,2) :REM REMOVE # SIGN DC GETNXT *: 1030 GOSUB 1900 :REM GET NUMBER DC DECIN *: 1040 FINAL-LINE = NUMBER LEA FINLIN(PC),A5 MOVE.W D5,(A5) *: 1050 GOTO 1200 BRA.S L1200 *: 1100 REM SPECIFIED INCREMENT *: 1110 GOSUB 1900 :REM GET NUMBER L1100 DC DECIN *: 1120 FINAL-LINE = CURRENT-LINE+NUMBER-1 MOVE.W CURLIN(PC),D7 ADD.W D5,D7 SUB.W #1,D7 LEA FINLIN(PC),A5 MOVE.W D7,(A5) *: 1200 IF FINAL-LINELAST-LINE THEN FINAL-LINE=LAST-LINE CMP.W LASLIN(PC),D7 BLS.S L1220 SKIP IF <= LEA FINLIN(PC),A5 MOVE.W LASLIN(PC),D7 MOVE.W D7,(A5) SET FINAL LINE *: 1220 GOSUB 1700 :REM PRINT CURRENT INE L1220 BSR.L L1700 *: 1230 IF CURRENT-LINE = FINAL-LINE THEN RETURN MOVE.W CURLIN(PC),D7 CMP.W FINLIN(PC),D7 BNE.S L1240 CONTINUE OF <> RTS ELSE RETURN *: 1240 CURRENT-LINE = CURRENT-LINE+1 L1240 LEA CURLIN(PC),A5 MOVE.W (A5),D7 ADD.W #1,D7 MOVE.W D7,(A5) *: 1250 GOTO 1220 BRA.S L1220 *: 1700 REM ROUTINE TO PRINT CURRENT LINE *: 1710 PRINT CURRENT-LINE; ": ";LINE$(CURRENT-LINE) L1700 DC PCRLF MOVE.W CURLIN(PC),D4 CLR.L D6 NO SPACES DC OUT5D MOVE.B #$3A,D4 DC PUTCH MOVE.B #$20,D4 DC PUTCH CLR.L D7 MOVE.W CURLIN(PC),D7 MULU #80,D7 LEA BUFFER(PC),A3 ADD.L D7,A3 POINT TO BEGINNING OF LINE PRLOOP MOVE.B (A3)+,D4 GET NEXT CHAR CMP.B #$0D,D4 CR? BEQ.S L1720 STOP IF YES DC PUTCH ELSE PRINT IT BRA.S PRLOOP AND THEN RETURN FOR NEXT *: 1720 RETURN L1720 RTS * FOLLOWING ROUTINE IS NOT NEEDED; DONE BY DECIN *: 1900 REM GET NUMBER ROUTINE *: 1910 NUMBER = VAL(A$) :REM GET FROM COMMAND *: 1930 RETURN *: 2000 REM SAVE AND EXIT COMMAND S *: 2010 IF LAST-LINE=0 THEN STOP L2000 MOVE.W LASLIN(PC),D7 BEQ.L STOP *: 2015 EXEC, "DELETE " + FILE-NAME$ + ".BAK" MOVE.L A6,A4 POINT TO FCB MOVE.L FCBEXT(A4),D0 SAVE OLD EXTENSION MOVE.L #$42414B00,FCBEXT(A4) PUT IN .BAK EXT DC FDELET AND DELETE OLD BACKUP BEQ.S DELEOK IF DELETE WENT OK MOVE.B FCBERR(A4),D7 ELSE CHECK ERROR CODE CMP.B #4,D7 NOT FOUND IS OK BNE.L FERROR ALL ELSE IS NG DELEOK MOVE.L D0,FCBEXT(A4) ELSE RESTORE OLD EXTENSION *: 2020 EXEC, "RENAME " + FILE-NAME$ + ".TXT " + FILE-NAME$ + ".BAK" MOVE.L FCBNAM(A4),D5 MOVE.L D5,FCBNMS(A4) MOVE.L FCBNAM+4(A4),D5 COPY NAME MOVE.L D5,FCBNMS+4(A4) MOVE.L #$42414B00,FCBNMS+8(A4) NEW EXT IS .BAK DC FRENAM THEN RENAME FILE BEQ.S L2030 IF NO ERROR CMP.B #4,FCBERR(A4) BNE.L FERROR ONLY ERROR 4 IS OK *: 2030 OPEN NEW FILE-NAME$+".TXT" AS 2 L2030 MOVE.L D0,FCBEXT(A4) RESTORE OLD EXTENSION DC FOPENW BNE.L FERROR *: 2040 FOR I = 1 TO LAST-LINE MOVE.L #1,D0 I *: 2050 PRINT #2, LINE$(I) L2050 MOVE.W D0,D7 I MULU #80,D7 *80 LEA BUFFER(PC),A3 ADD.L D7,A3 POINT TO BEGINNING OF LINE WRLOOP MOVE.B (A3)+,D4 GET NEXT CHAR DC FWRITE OUTPUT IT CMP.B #$0D,D4 CR? BEQ.S L2060 STOP IF YES BRA.S WRLOOP AND THEN RETURN FOR NEXT *: 2060 NEXT I L2060 ADD.L #1,D0 INCREMENT I CMP.W LASLIN(PC),D0 COMPARE WITH LAST-LINE BLS.S L2050 REPEAT IF I<= LAST-LINE *: 2070 CLOSE 2 DC FCLOSE BNE.L QERROR *: 2080 STOP DC WARMST *: 3000 REM FIND COMMAND F/STRING/ *: 3010 IF LEN(A$)<2 THEN 500 :REM ERROR *: 3020 DELIMITER$=LEFT$(A$,1) L3000 DC GETNXT GET DELIMITER MOVE.B D5,D3 SAVE DELIMITER IN D3 CMP.B #$0D,D5 BEQ.L L500 ERROR IF NO STRING *: 3030 STRING$="" LEA STRING(PC),A0 *: 3040 FOR S=2 TO LEN(A$) *: 3050 IF MID$(A$,S,1) = DELIMITER$ THEN 3100 *: 3060 STRING$ = STRING$ + MID$(A$,S,1) *: 3070 NEXT S CLR.L D2 LENGTH=0 L3040 BSR.L NEXTCH GET NEXT CHARACTER MOVE.B D5,(A0)+ PUT INTO STRING CMP.B #$0D,D5 CHECK IF CR BEQ.S L3040A QUIT IF HIT CR CMP.B D5,D3 CHECK IF DELIMITER BEQ.S L3040A YES, SO QUIT ADD.B #1,D2 INCREMENT COUNTER BRA.S L3040 L3040A MOVE.B #$0D,-1(A0) END WITH CR *: 3100 LENGTH = LEN(STRING$) * ... LENGTH IS IN D2 TST.W D2 BEQ.L L500 QUIT IF LENGTH - 0 *: 3105 FIND-FLAG=0 : IF MID$(A$,S+1,1) = "*" THEN FIND-FLAG=1 :REM MULTIPLE FIND LEA FIFLAG(PC),A5 MOVE.B #0,(A5) FIND-FLAG=0 BSR.L NEXTCH GET NEXT CHARACTER, IF ANY CMP.B #$2A,D5 CHECK IF * BNE.S L3110 NO, SKIP AHEAD LEA FIFLAG(PC),A5 MOVE.B #1,(A5) ELSE FIND-FLAG=1 *: 3110 FOR I = CURRENT-LINE+1 TO LAST-LINE * TREAT A BIT DIFFERENTLY, DEPENDING ON GLOBAL OR NOT * NON-GLOBAL STARTS ON NEXT LINE, DOESN'T DO CURRENT L3110 MOVE.B FIFLAG(PC),D7 GLOBAL? BNE.S L3110G YES MOVE.W CURLIN(PC),D0 NO CMP.W LASLIN(PC),D0 BEQ.L L500 QUIT IF ON LAST LINE ADD.W #1,D0 START WITH NEXT LINE BRA.S L3120 THEN CONTINUE * GLOBAL DOES EVERY LINE, INCLUDING CURRENT AND LAST L3110G MOVE.W CURLIN(PC),D0 CURRENT CMP.W LASLIN(PC),D0 BHI.L L200 QUIT IF CURRENT>LAST *: 3120 FOR J=1 TO LEN(LINE$(I)) *: 3130 IF MID$(LINE$(I),J,LENGTH) = STRING$ THEN 3170 *: 3140 NEXT J L3120 MOVE.W D0,D1 I MULU #80,D1 *80 LEA BUFFER(PC),A5 POINT TO BEG OF BUFFER ADD.L D1,A5 POINT TO BEGINNING OF LINE MOVE.L A5,A6 POINT TO 1ST CHARACTER FILOOP MOVE.B (A6),D7 GET 1ST CHAR BEING EXAMINED CMP.B #$0D,D7 CR? BEQ.S L3150 NOTHING FOUND, TRY NEXT LINE LEA STRING(PC),A0 POINT TO BEG OF STRING MOVE.L A6,A1 AND SEARCH AREA MOVE.L D2,D7 AND STRING LENGTH FSLOOP CMP.B (A0)+,(A1)+ COMPARE NEXT BYTES BNE.S FSNOMA NO MATCH SUB.B #1,D7 DECREMENT COUNTER BNE.S FSLOOP AND TRY AGAIN BRA.S L3170 IF STRING WAS FOUND FSNOMA ADD.L #1,A6 LOOK AT NEXT CHARACTER IN LINE BRA.S FILOOP AND SEARCH ONE COLUMN OVE *: 3150 NEXT I L3150 ADD.L #1,D0 I=I+1 CMP.W LASLIN(PC),D0 CHECK AGAINST LAST LINE BLS.S L3120 AND CHECK NEXT LINE IF NOT DONE *: 3160 RETURN RTS *: 3170 REM FOUND THE STRING IN LINE I *: 3180 CURRENT-LINE = I L3170 LEA CURLIN(PC),A5 MOVE.W D0,(A5) *: 3190 GOSUB 1700 :REM PRINT LINE BSR.L L1700 *: 3195 IF FIND-FLAG=1 AND CURRENT-LINE 1 MOVE.W CURLIN(PC),D7 CMP.W LASLIN(PC),D7 OR BEQ.S L3200 CURRENT = LAST THEN SKIP LEA CURLIN(PC),A5 ELSE ADD.W #1,D7 CURRENT + 1 MOVE.W D7,(A5) MOVE BACK BRA.S L3110 GOTO 3110 *: 3200 RETURN L3200 RTS * NEXTCH SUBROUTINE - USED INSTEAD OF GETNXT TO GET A CHAR * FROM THE LINE BUFFER, BECAUSE GETNXT ELIMINATES MULTIPLE * SPACES NEXTCH MOVEM.L A5,-(A7) MOVE.L LPOINT(A6),A5 POINT TO NEXT CHAR CLR.L D5 MOVE.B (A5)+,D5 MOVE.L A5,LPOINT(A6) RESTORE LINE POINTER MOVEM.L (A7)+,A5 RTS *: 4000 REM CHANGE COMMAND C *: 4010 IF LEN(A$)<4 THEN 500 :REM ERROR *: 4020 DELIMITER$=LEFT$(A$,1) L4000 DC GETNXT GET DELIMITER MOVE.B D5,D3 SAVE DELIMITER IN D3 CMP.B #$0D,D5 BEQ.L L500 ERROR IF NO STRING *: 4025 CHANGE-FLAG=0 : IF MID$(A$,LEN(A$)-1,2) = DELIMITER$+"*" THEN CHANGE-FLAG=1 *: 4026 LAST-POSITION=1 : REM LAST POSITION LEA CHFLAG(PC),A5 MOVE.B #0,(A5) CHANGE-FLAG = 0 LEA LASPOS(PC),A5 MOVE.B #1,(A5) LAST POSITION = 1 MOVE.L LPOINT(A6),A5 POINT TO NEXT CHAR IN BUF CLR.L D7 * LOOP TO LOOK FOR A * AT THE END OF THE LINE LOOKST LSL.L #8,D7 SHIFT D7 LEFT MOVE.B (A5)+,D7 NEXT CHAR CMP.B #$0D,D7 AT END OF LINE? BNE.S LOOKST NO, GO UNTIL CR LSR.L #8,D7 LAST 2 SHOULD BE DELIM & * CMP.B #$2A,D7 LAST *? BNE.S L4030 NO, SKIP LSR.L #8,D7 CMP.B D3,D7 PREVIOUS DELIMITER? BNE.S L4030 NO, SKIP LEA CHFLAG(PC),A5 YES MOVE.B #1,(A5) CHANGE-FLAG = 1 *: 4030 STRING$="" L4030 LEA STRING(PC),A0 *: 4040 FOR S=2 TO LEN(A$) *: 4050 IF MID$(A$,S,1) = DELIMITER$ THEN 4100 *: 4060 STRING$ = STRING$ + MID$(A$,S,1) *: 4070 NEXT S CLR.L D2 LENGTH=0 L4040 BSR.L NEXTCH GET NEXT CHARACTER MOVE.B D5,(A0)+ PUT INTO STRING CMP.B #$0D,D5 CHECK IF CR BEQ.L L500 QUIT IF HIT CR CMP.B D5,D3 CHECK IF DELIMITER BEQ.S L4040A YES, SO QUIT ADD.B #1,D2 INCREMENT COUNTER BRA.S L4040 L4040A MOVE.B #$0D,-1(A0) END WITH CR MOVE.L LPOINT(A6),D7 LEA LPTMEM(PC),A5 MOVE.L D7,(A5) SAVE LPOINT IN MEM TST.W D2 BEQ.L L500 QUIT IF LENGTH = 0 *: 4100 LENGTH = LEN(STRING$) * ... LENGTH IS IN D2 L4100 DC VPOINT POINT BACK TO USER AREA MOVE.L LPTMEM(PC),D7 MOVE.L D7,LPOINT(A6) RESTORE LPOINT *: 4120 FOR J=LAST-POSITION TO LEN(LINE$(CURRENT-LINE)) *: 4130 IF MID$(LINE$(CURRENT-LINE),J,LENGTH) = STRING$ THEN 4170 *: 4140 NEXT J L4120 MOVE.W CURLIN(PC),D1 I MULU #80,D1 *80 CLR.L D7 MOVE.B LASPOS(PC),D7 LAST-POSITION MARKER SUB.B #1,D7 CVT TO START AT 0 LEA BUFFER(PC),A5 POINT TO BEG OF BUFFER ADD.L D1,A5 A5-> TO BEGINNING OF LINE MOVE.L A5,A6 ADD.L D7,A6 A6->PAST STRING PUT IN CALOOP MOVE.B (A6),D7 GET 1ST CHAR BEING EXAMINED CMP.B #$0D,D7 CR? BEQ.S L4150 NOTHING FOUND LEA STRING(PC),A0 POINT TO BEG OF STRING MOVE.L A6,A1 AND SEARCH AREA MOVE.L D2,D7 AND STRING LENGTH CSLOOP CMP.B (A0)+,(A1)+ COMPARE NEXT BYTES BNE.S CSNOMA NO MATCH SUB.B #1,D7 DECREMENT COUNTER BNE.S CSLOOP AND TRY AGAIN BRA.S L4170 IF STRING WAS FOUND CSNOMA ADD.L #1,A6 LOOK AT NEXT CHARACTER IN LINE BRA.S CALOOP AND SEARCH ONE COLUMN OVER *: 4150 LAST-POSITION=1 L4150 LEA LASPOS(PC),A5 MOVE.B #1,(A5) *: 4152 IF CHANGE-FLAG=2 THEN CHANGE-FLAG=1 : GOSUB 1700 MOVE.B CHFLAG(PC),D7 CMP.B #2,D7 2? BNE.S L4155 NO LEA CHFLAG(PC),A5 YES MOVE.B #1,(A5) CHANGE-FLAG=1 BSR.L L1700 GOSUB 1700 *: 4155 IF CHANGE-FLAG>0 AND CURRENT-LINEBEG OF LINE, A6->WHERE STRING FOUND IN IT L4170 LEA TEMP(PC),A3 POINT TO TEMP LOCATION L1470A CMP.L A5,A6 POINTING TO STRING? BEQ.S L1470B MOVE.B (A5)+,(A3)+ MOVE LINE INTO TEMP BRA.S L1470A L1470B ADD.L D2,A5 POINT TO RIGHT PART *: 4200 RIGHT-PART$ = MID$(TEMP$,J+LENGTH) :REM REMOVE IT *: 4210 STRING2$="" *: 4220 FOR I=S+1 TO LEN(A$) :REM FIND REPLACEMENT STRING *: 4230 IF MID$(A$,I,1) = DELIMITER$ THEN 4300 *: 4240 STRING2$ = STRING2$ + MID$(A$,I,1) *: 4250 NEXT I * NOW COPY REPLACEMENT STRING INTO TEMPORARY DC VPOINT MOVE.L LPTMEM(PC),D7 MOVE.L D7,LPOINT(A6) POINT BACK TO BEGINNING L4250 BSR.L NEXTCH GET NEXT CHARACTER CMP.B #$0D,D5 CHECK IF CR BEQ.S L4300 QUIT IF HIT CR CMP.B D5,D3 CHECK IF DELIMITER BEQ.S L4300 YES, SO QUIT MOVE.B D5,(A3)+ PUT INTO TEMP BRA.S L4250 *: 4300 LINE$(CURRENT-LINE)=LEFT-PART$ + STRING$ + RIGHT-PART$ * USE LEFT PRT OF D4 TO MEASURE LENGTH OF LEFT+STRING, RIGHT * TO MEASURE LENGTH OF RIGHT-PART L4300 LEA TEMP(PC),A2 POINT TO TEMP LOCATION MOVE.L A3,D4 WHERE WE WILL PUT NEXT SUB.L A2,D4 -BEG = LENGTH SWAP D4 LENGTH LEFT, ZERO RIGHT L4300A ADD.B #1,D4 START AT 0 MOVE.B (A5)+,D7 MOVE NEXT CHAR FROM ORIG MOVE.B D7,(A3)+ CMP.B #$0D,D7 CR? BNE.S L4300A NO LEA TEMP(PC),A5 POINT BACK TO TEMP LOCATION SUB.L A5,A3 LENGTH OF NEW LINE MOVE.L A3,D7 CMP.L #80,D7 CHECK IT BLS.S L4300B OK IF <=80 LEA TLMSG(PC),A4 DC PSTRNG PRINT "TOO LONG" RTS * RETURN TEMP STRING TO PLACE IN BUFFER L4300B MOVE.W CURLIN(PC),D1 I MULU #80,D1 *80 LEA BUFFER(PC),A5 POINT TO BEG OF BUFFER ADD.L D1,A5 POINT TO BEGINNING OF LINE LEA TEMP(PC),A3 AND TEMP LINE L4300C MOVE.B (A3)+,D7 MOVE.B D7,(A5)+ MOVE A BYTE CMP.B #$0D,D7 CR? BNE.S L4300C NO *: 4308 REM CHECK IF THIS IS GLOBAL CHANGE *: 4309 IF CHANGE-FLAG=0 THEN GOSUB 1700 : RETURN MOVE.B CHFLAG(PC),D7 =0 IF NOT GLOBAL BNE.S L4310 SKIP IF <>0 BSR.L L1700 PRINT LINE IF NOT GLOBAL RTS AND RETURN *: 4310 CHANGE-FLAG=2 L4310 LEA CHFLAG(PC),A5 MOVE.B #2,(A5) *: 4311 IF LEN(RIGHT-PART$)=0 THEN GOTO 4150 TST.B D4 LENGTH IS IN D4.W BEQ.L L4150 *: 4312 LAST-POSITION=LEN(LEFT-PART$)+LEN(STRING2$)+1 SWAP D4 LENGTH WAS IN D4.LEFT ADD.B #1,D4 +1 LEA LASPOS(PC),A5 MOVE.B D4,(A5) *: 4320 GOTO 4100 BRA.L L4100 *: 5000 REM INSERT COMMAND I *: 5010 IF LAST-LINE = MAX-LINE THEN PRINT "ERROR - MEMORY FULL" :RETURN L5000 MOVE.W LASLIN(PC),D7 CMP.W MAXLIN(PC),D7 BNE.S L5015 OK IF NOT EQUAL LEA EMFMSG(PC),A4 DC PSTRNG PRINT "MEM FULL" RTS *: 5015 PRINT "="; L5015 MOVE.B #$3D,D4 DC PUTCH *: 5020 INPUT NEW-LINE$ DC INLINE *: 5030 IF NEW-LINE$ = "#" THEN RETURN DC SEENXT GET FIRST CHAR CMP.B #$23,D5 #? BNE.S L5035 NO RTS YES, JUST RETURN *: 5035 IF LAST-LINE = 0 THEN 5050 L5035 MOVE.W LASLIN(PC),D7 BEQ.S L5050 *: 5040 IF CURRENT-LINE <> LAST-LINE THEN 5200 CMP.W CURLIN(PC),D7 COMPARE WITH LAST LINE BNE.S L5200 *: 5050 REM APPEND AT END *: 5060 LAST-LINE = LAST-LINE+1 L5050 LEA LASLIN(PC),A5 MOVE.W (A5),D7 ADD.W #1,D7 MOVE.W D7,(A5) *: 5070 LINE$(LAST-LINE) = NEW-LINE$ MOVE.W LASLIN(PC),D7 MULU #80,D7 LEA BUFFER(PC),A3 ADD.L D7,A3 POINT TO WHERE LINE WILL GO MOVE.L LPOINT(A6),A5 MOVE.L #78,D7 COUNTER MOVE.B #$0D,79(A3) END LINE WITH CR L5070A MOVE.B (A5)+,(A3)+ MOVE OVER A BYTE DBRA D7,L5070A *: 5080 CURRENT-LINE = LAST-LINE MOVE.W LASLIN(PC),D7 LEA CURLIN(PC),A5 MOVE.W D7,(A5) *: 5090 GOTO 5010 BRA.S L5000 * INSERT NEW LINE INTO MIDDLE OF CURRENT TEXT *: 5200 FOR I = LAST-LINE TO CURRENT-LINE+1 STEP -1 *: 5210 LINE$(I+1) = LINE$(I) :REM MOVE ALL UP ONE *: 5215 NEXT I L5200 LEA BUFFER(PC),A0 POINT TO BUFFER MOVE.L A0,A1 MOVE.W LASLIN(PC),D7 LAST-LINE NUMBER MULU #80,D7 ADD.L #79,D7 ADD.L D7,A0 POINT TO END OF LAST LINE MOVE.W CURLIN(PC),D7 ADD.W #1,D7 CURRENT-LINE + 1 MULU #80,D7 ADD.L D7,A1 POINT TO CURRENT +1 L5200A MOVE.B (A0),D7 MOVE.B D7,80(A0) MOVE UP CMP.L A0,A1 DONE? BEQ.S L5220 YES SUB.L #1,A0 NO, GO BACK BRA.S L5200A *: 5220 LAST-LINE = LAST-LINE+1 L5220 MOVE.W LASLIN(PC),D7 ADD.W #1,D7 LEA LASLIN(PC),A5 MOVE.W D7,(A5) *: 5230 CURRENT-LINE = CURRENT-LINE+1 MOVE.W CURLIN(PC),D7 ADD.W #1,D7 LEA CURLIN(PC),A5 MOVE.W D7,(A5) *: 5240 LINE$(CURRENT-LINE) = NEW-LINE$ MOVE.W CURLIN(PC),D7 MULU #80,D7 LEA BUFFER(PC),A3 ADD.L D7,A3 POINT TO WHERE LINE WILL GO MOVE.L LPOINT(A6),A5 MOVE.L #78,D7 COUNTER MOVE.B #$0D,79(A3) END LINE WITH CR L5240A MOVE.B (A5)+,(A3)+ MOVE OVER A BYTE DBRA D7,L5240A *: 5250 GOTO 5010 BRA.L L5000 *: 6000 REM GO COMMAND G *: 6010 IF A$ = "T" THEN CURRENT-LINE = 1 : RETURN L6000 DC SEENXT GET NEXT CHARACTER DC TOUPPR CMP.B #$54,D5 T? BNE.S L6020 NO LEA CURLIN(PC),A5 MOVE.W #1,(A5) RTS *: 6020 IF A$ = "B" THEN CURRENT-LINE = LAST-LINE : RETURN L6020 CMP.B #$42,D5 B? BNE.S L6030 NO MOVE.W LASLIN(PC),D7 LEA CURLIN(PC),A5 MOVE.W D7,(A5) RTS *: 6030 GOSUB 1900 :REM GET NUMBER L6030 DC DECIN *: 6040 IF NUMBER<1 OR NUMBER>LAST-LINE THEN 6300 TST.W D5 BEQ.L L6300 IF <1 CMP.W LASLIN(PC),D5 BHI.L L6300 IF >LAST-LINE *: 6050 CURRENT-LINE = NUMBER : RETURN LEA CURLIN(PC),A5 MOVE.W D5,(A5) RTS *: 6300 PRINT "BAD NUMBER" : RETURN L6300 LEA BDNMSG(PC),A4 DC PSTRNG RTS *: 7000 REM DELETE CURRENT LINE *: 7010 IF LAST-LINE=0 THEN RETURN L7000 MOVE.W LASLIN(PC),D7 BNE.S L7020 RTS *: 7020 IF CURRENT-LINE<>LAST-LINE THEN 7100 L7020 MOVE.W CURLIN(PC),D7 CMP.W LASLIN(PC),D7 BNE.S L7100 *: 7030 REM IF CURRENT LINE IS LAST *: 7040 LAST-LINE=LAST-LINE-1 MOVE.W LASLIN(PC),D7 SUB.W #1,D7 LEA LASLIN(PC),A5 MOVE.W D7,(A5) *: 7050 CURRENT-LINE = CURRENT-LINE-1 MOVE.W CURLIN(PC),D7 SUB.W #1,D7 LEA CURLIN(PC),A5 MOVE.W D7,(A5) *: 7060 RETURN RTS * IF CURRENT LINE IS NOT LAST LINE, MOVE UP A LINE *: 7100 FOR I=CURRENT-LINE TO LAST-LINE *: 7110 LINE$(I)=LINE$(I+1) *: 7120 NEXT I L7100 LEA BUFFER(PC),A0 POINT TO BUFFER MOVE.L A0,A1 MOVE.W LASLIN(PC),D7 LAST-LINE NUMBER ADD.W #1,D7 LAST-LINE + 1 MULU #80,D7 ADD.L D7,A0 POINT TO LAST LINE + 1 MOVE.W CURLIN(PC),D7 MULU #80,D7 ADD.L D7,A1 POINT TO CURRENT LINE L7100A MOVE.B 80(A1),D7 MOVE.B D7,(A1)+ MOVE DOWN CMP.L A0,A1 DONE? BLS.S L7100A NO *: 7130 LAST-LINE=LAST-LINE-1 L7130 MOVE.W LASLIN(PC),D7 SUB.W #1,D7 LEA LASLIN(PC),A5 MOVE.W D7,(A5) *: 7140 RETURN RTS *: 8000 REM QUIT *: 8010 PRINT "ARE YOU SURE YOU WISH TO QUIT" L8000 LEA SURMSG(PC),A4 DC PSTRNG *: 8020 INPUT A$ DC GETCH GET ANSWER DC TOUPPR *: 8030 IF A$<>"Y" THEN RETURN CMP.B #$59,D5 BEQ.S L8040 RTS *: 8040 STOP L8040 DC WARMST *: 9000 REM HELP *: 9100 PRINT "POSSIBLE COMMANDS ARE" *: 9110 PRINT " P - PRINT" *: 9120 PRINT " S - SAVE AND EXIT" *: 9130 PRINT " F - FIND A STRING" *: 9140 PRINT " C - CHANGE A STRING" *: 9150 PRINT " I - INSERT NEW LINE" *: 9160 PRINT " G - GO TO LINE NUMBER" *: 9170 PRINT " D - DELETE CURRENT LINE" *: 9180 PRINT " Q - QUIT WITHOUT SAVING" *: 9190 PRINT " ? - PRINT THIS HELP MESSAGE" L9000 LEA CSUMSG(PC),A4 DC PSTRNG PRINT COMMAND SUMMARY *: 9300 RETURN RTS *: 9900 IF ERR=8 THEN RESUME 190 *: 9910 IF ERR=4 THEN RESUME 200 * NOT NEEDED * ERROR MESSAGES NOTENU LEA NENMSG(PC),A4 DC PSTRNG PRINT "NOT ENOUGH MEMORY" DC WARMST * ON FILE OUTPUT ERROR, PRINT MSG BUT STAY IN EDITOR FERROR DC PERROR PRINT ERROR MESSAGE LEA ERRMSG(PC),A4 DC PSTRNG PRINT "TRY AGAIN" BRA.L L200 * PRINT HELP MESSAGE HELP LEA HLPMSG(PC),A4 DC PSTRNG DC WARMST * TEST STRINGS HLPMSG DC.B 'EDLIN is a simple line editor for generating or modifying' DC.B $0D,$0A DC.B 'text files. It is called with' DC.B $0D,$0A DC.B ' EDLIN ' DC.B $0D,$0A DC.B 'where is the name of an old file to be edited' DC.B $0D,$0A DC.B 'or of a new file to be generated; it defaults to .TXT if' DC.B $0D,$0A DC.B 'no extension is specified. If EDLIN is used to edit an existing' DC.B $0D,$0A DC.B 'file, it renames the old file to .BAK when it writes the new' DC.B $0D,$0A DC.B 'file to the disk. For specific help with editing commands' DC.B $0D,$0A DC.B 'once in EDLIN, type a question mark (?) for the command.',4 CSUMSG DC.B 'The EDLIN commands, and some examples, are' DC.B $0D,$0A DC.B ' C - Change a string on the current line' DC.B $0D,$0A DC.B ' Example: C/old string/new string/' DC.B $0D,$0A DC.B ' D - Delete the current line' DC.B $0D,$0A DC.B ' Example: D' DC.B $0D,$0A DC.B ' F - Find a string below the current line' DC.B $0D,$0A DC.B ' Example: F/string to be found/' DC.B $0D,$0A DC.B ' G - Go to a line number' DC.B $0D,$0A DC.B ' Examples: G20 or GT (top) or GB (bottom)' DC.B $0D,$0A DC.B ' I - Insert a new line after the current line' DC.B $0D,$0A DC.B ' Example: I (type # on new line to exit insert mode)' DC.B $0D,$0A DC.B ' P - Print' DC.B $0D,$0A DC.B ' Examples: P or P5 or P#22 or P!' DC.B $0D,$0A DC.B ' Q - Quit without saving the text' DC.B $0D,$0A DC.B ' Example: Q' DC.B $0D,$0A DC.B ' S - Save text and then exit to SK*DOS' DC.B $0D,$0A DC.B ' Example: S' DC.B $0D,$0A DC.B ' ? - Print this Help message' DC.B $0D,$0A DC.B ' Example: ?' DC.B $0D,$0A DC.B 'You may precede any command with a line number. Find and' DC.B $0D,$0A DC.B 'Change become global, starting at the current line, if' DC.B $0D,$0A DC.B 'followed by an asterisk, as in C/old/new/*.',4 NENMSG DC.B 'Not enough memory exists.',4 MFLMSG DC.B 'Not enough memory for input file to be read.',4 HUHMSG DC.B ' What???',4 TLMSG DC.B 'New line too long ... not changed.',7,4 EMFMSG DC.B 'Cannot insert a line - memory is full.',7,4 BDNMSG DC.B "That line doesn't exist.",4 SURMSG DC.B 'Are you sure? ',4 ERRMSG DC.B 'Error in writing output file; try another disk.',7,4 LTLMSG DC.B 'Line ',4 LT2MSG DC.B ' longer than 79 characters; has been split.',7,4 NEWMSG DC.B 'This is a new file; start by inserting text.',4 * DATA AREA MAXLIN DS.W 1 MAXIMUM LINE NUMBER CURLIN DS.W 1 CURRENT LINE NUMBER LASLIN DS.W 1 LAST LINE NUMBER NUMBER DS.W 1 NUMBER ENTERED FINLIN DS.W 1 FINAL LINE TO PRINT FIFLAG DS.B 1 FIND-FLAG: <>0=GLOBAL CHFLAG DS.B 1 CHANGE-FLAG: >0=GLOBAL,2=CHANGED LASPOS DS.B 1 LAST-POSITION SEARCHED IN CHANGE DS.B 1 NOT USED LPTMEM DS.L 1 LPOINT MEMORY IN CHANGE STRING DS.W 65 STRING TEMP DS.W 65 TEMPORARY STRING STACKA DS.L 1 SAVES STACK POINTER BUFFER DS.W 1 BUFFER TO END OF MEMORY END START