.TITLE EDI02 .IDENT /X01/ ; ; EDITOR (TEMP FILE VERSION) ; ; VERSION X01 ; ; DAVID G. CONROY 05-JAN-78 ; .GLOBL ACOM .GLOBL CCOM .GLOBL DCOM .GLOBL ECOM .GLOBL FCOM .GLOBL GCOM .GLOBL ICOM .GLOBL JCOM .GLOBL KCOM .GLOBL MCOM .GLOBL OCOM .GLOBL PCOM .GLOBL PCOM1 .GLOBL QCOM .GLOBL RCOM .GLOBL SCOM .GLOBL VCOM .GLOBL WCOM .GLOBL DEFDOT .MCALL CALL .MCALL CALLR .MCALL RETURN .MCALL FDAT$R .MCALL OPEN$ .MCALL OPEN$W .MCALL PUT$S .MCALL EXIT$S ; ; LOCAL DATA ; FUDGE: .BLKW 1 ;DELTA ADDRESS FOR K VFLAG: .BLKW 1 ;GLOBAL/EXCLUDE FLAG SANY: .BLKW 1 ;ANYTHING AT ALL FOR SUBSTITUTE FP: .BLKW 1 ;FILE I/O POINTER SFLAG: .BLKW 1 ;ONCE FLAG FOR SUBSTITUTE FC: .BLKW 1 ;RECORD COUNT SNUM: .BLKW 1 ;NUMBER IN S# SWNUM: .BLKW 1 ;PER LINE COPY OF SNUM ;+ ; ** COMMAND PROCESSORS ; ; THESE ROUTINES ARE CALLED BY THE COMMAND DISPATCHER TO EXECUTE THE ; USER'S COMMANDS. THEY EITHER RETURN TO THE DISPATCHER SUCCESSFULLY ; OR JUMP DIRECTLY TO ERROR. ;- ; ; APPEND ; ACOM: CALL DEFDOT ;DEFAULTS CALL TDELIM ; CLR OLDCMD ;CLEAR COMMAND ON LINE FLAG MOV #GETTY,R4 ;ROUTINE MOV ADR2,R5 ;WHERE TO APPEND CALLR APPEND ;GO APPEND ; ; CHANGE ; CCOM: CALL NONZER ;DEFAULTS CALL TDELIM ; CLR OLDCMD ;CLEAR COMMAND ON LINE FLAG CALL DELETE ;MAKE TEXT GO AWAY MOV #GETTY,R4 ;ROUTINE MOV ADR1,R5 ;APPEND PLACE TST -(R5) ; CALLR APPEND ; ; ; DELETE ; DCOM: CALL NONZER ;DEFAULTS CALLR DELETE ; ; ; EDIT ; ECOM: CALL NOADDR ;NO ADDRESS IS LEGAL MOV ZERO,DOL ;CLEAR TEXT MOV ZERO,DOT ; CLR TPTR ;START AT TEMPFILE BLOCK 0 MOV ZERO,R5 ;READ IN STUFF FROM FILE CALL READIN ;READ FROM FILE CALLR SAVEFN ;RESET FILE NAME ; ; FACTS ; FCOM: CALL NOADDR ;NO ADDRESS IS ALLOWED 10$: CALL GETC ;SKIP OVER BLANKS CMP R0,#' ; BEQ 10$ ; CMP R0,#NL ;BR IF NO FILENAME BEQ 50$ ; CMP R0,#EOF ; BEQ 50$ ; MOV #SFN,R1 ;GET POINTER TO SAVE FILE BUFFER 20$: CMP R1,#SFN+FNS-1 ;DOES IT FIT BHIS 30$ ;NO, IGNORE MOVB R0,(R1)+ ;SAVE THE CHARACTER 30$: CALL GETC ;CONTINUE TILL NEWLINE CMP R0,#NL ; BEQ 40$ ; CMP R0,#EOF ; BNE 20$ ; 40$: CLRB (R1) ;THEN APPEND A NULL 50$: TSTB SFN ;IS THERE A FILE NAME BEQ 80$ ;NO MOV #SFN,R1 ;YES, POINT AT IT 60$: MOVB (R1)+,R0 ;PRINT TILL THE NULL BEQ 70$ ; CALL TTYC ; BR 60$ ; 70$: CALL TTYNL ;APPEND A NEWLINE, AND 80$: RETURN ;DONE ; ; GLOBAL ; EXCLUDE ; GCOM: CLR VFLAG ;GLOBAL BR GV ; VCOM: MOV #1,VFLAG ;EXCLUDE GV: CALL DEFALL ;DEFAULT TO 1,$ TST GUPTR ;IN A GLOBAL BEQ 20$ ;NO MOV #9.,R1 ;CANNOT NEST GLOBALS JMP ERROR ; 20$: CALL GETC ;GET PATTERN CALL COMPIL ; ; ; MARK ALL LINES FOR WHICH THE COMMAND LINE ; WILL BE EXECUTED. ; MOV ZERO,R1 ;MARK THE LINES 30$: TST (R1)+ ; CMP R1,DOL ;SEE IF DONE BHI 60$ ;YES BIC #1,(R1) ;REMOVE OLD MARK CMP R1,ADR1 ;DUCK OUT IF NOT IN RANGE BLO 30$ ; CMP R1,ADR2 ; BHI 30$ ; MOV (R1),R0 ;MATCH HERE CALL GETLIN ; MOV #LBUF1,R0 ; CALL AMATCH ; BCS 40$ ;BR IF NOT TST VFLAG ;MARK LINE IF GLOBAL BNE 30$ ; INC (R1) ; BR 30$ ; 40$: TST VFLAG ;NO MATCH, MARK IF EXCLUDE BEQ 30$ ; INC (R1) ; BR 30$ ; ; ; COLLECT UP COMMAND LINE ; 60$: MOV #GUBUF,R1 ;COLLECT UP THE LINE 70$: CALL GETC ;UNTIL NEWLINE CMP R0,#'\ ;ESCAPE BNE 72$ ;NO CALL GETC ;GET ACTUAL CHARACTER BR 74$ ; 72$: CMP R0,#NL ; BEQ 80$ ; 74$: CMP R1,#GUBUF+GUBS-1;GIVE ?0 IF THE LINE IS TOO LONG BHIS 90$ ; MOVB R0,(R1)+ ; BR 70$ ; ; ; SET GLOBAL I/O ; RETURN TO COMMAND SCANNER ; 80$: CLRB (R1) ;MARK END MOV R1,GUPTR ;WILL GET EOF IMMEDIATELY RETURN ; 90$: CLR R1 ;?0 JMP ERROR ; ; ; INSERT ; ICOM: CMP ZERO,DOL ;EMPTY BUFFER BNE 10$ ;NO MOV ZERO,ADR2 ;ITS JUST A 0A BR 20$ ; 10$: CALL NONZER ;DEFAULTS SUB #2,ADR2 ; 20$: CALL TDELIM ; CLR OLDCMD ;CLEAR OLD COMMAND FLAG MOV #GETTY,R4 ;ROUTINE MOV ADR2,R5 ;INSERT TEXT CALLR APPEND ; ; ; COPY (KOPY) ; KCOM: CALL NONZER ;DEFAULTS CALL ADDRES ;GET THE COPY DESTINATION MOV R0,PEEK ;PUT THE DELIMITER BACK TST R2 ;MUST GET AN ADDRESS BEQ 20$ ;OR ?9 CLR FUDGE ;ADDRESS ADJUSTMENT FUDGE CMP R2,ADR2 ;EASY BHI 10$ ;YES CMP R2,ADR1 ;IMBEDDED BHIS 20$ ;YES, ?9 MOV #2,FUDGE ;MUST FUDGE ADDRESSES 10$: MOV #30$,R4 ;GET ROUTINE MOV R2,R5 ;APPEND PLACE CALLR APPEND ;APPEND TEXT AND RETURN 20$: MOV #9.,R1 ;?9 JMP ERROR ; 30$: CMP ADR1,ADR2 ;ANY MORE BHI 40$ ;NO MOV ADR1,R1 ;GET SOURCE ADD #2,ADR1 ;FIX ADD FUDGE,ADR1 ;THE ADD FUDGE,ADR2 ;ADDRESSES MOV (R1),R0 ;PICK UP SEEK ADDRESS CALL GETLIN ;PULL LINE CLC ;GOT ONE RETURN ; 40$: SEC ;NO MORE LINES RETURN ; ; ; MOVE ; MCOM: CALL NONZER ;CHECK OUT ADDRESES CALL ADDRES ;GET WHERE TO MOVE TO MOV R0,PEEK ; TST R2 ;MUST GET ONE BEQ 50$ ; CMP R2,ADR2 ;MOVING UP BHI 10$ ;BR IF YES CMP R2,ADR1 ;MOVING INTO THE MIDDLE BHIS 50$ ;NOT LEGAL MOV R2,R1 ;SET UP FOR THE MOVE TST (R1)+ ; MOV ADR2,R2 ; MOV ADR1,R5 ; MOV ADR2,DOT ;RESET CURRENT LINE SUB R5,DOT ; ADD R1,DOT ; CMP R5,R1 ;QUICK CHECK FOR NO WORK BEQ 40$ ;EXIT TST -(R5) ; BR 20$ ;GO DO THE MOVE 10$: MOV ADR1,R1 ;UPWARDS MOVE MOV ADR2,R5 ; MOV R2,DOT ;RESET CURRENT LINE 20$: MOV R5,R3 ;DO THE MOVE TST (R3)+ ; MOV R3,R4 ; TST (R4)+ ; MOV (R3),R0 ;SAVE BOUNDRY 30$: MOV -(R3),-(R4) ;MOVE CMP R3,R1 ; BHI 30$ ; MOV R0,(R3) ;PUT DOWN THE BOUNDRY LINE TST (R1)+ ;MOVE FORWARD TST (R5)+ ; CMP R5,R2 ;DONE BLO 20$ ;NO 40$: RETURN ;DONE 50$: MOV #9.,R1 ;?9 FOR FUNNY STUFF JMP ERROR ; ; ; OPTIONS ; OCOM: CALL NOADDR ;NO ADDRESS FOR OPTIONS COMMAND 10$: CALL GETC ;GET OPTION CHARACTER CMP R0,#NL ;NEWLINE BEQ 60$ ;YES, DONE BIC #' ,R0 ;FORCE UPPER CASE CMP R0,#'T ;OT BNE 20$ ;NO CLR OV ;CLEAR OPTIONS VERBOSE BR 10$ ; 20$: CMP R0,#'V ;OV BNE 30$ ;NO INC OV ;SET OPTIONS VERBOSE BR 10$ ; 30$: CMP R0,#'S ;OS BNE 40$ ;NO INC OS ;SET OPTIONS SENSITIVE CALL REKILL ;KILL OFF SAVED R.E. BR 10$ ; 40$: CMP R0,#'I ;OI BNE 50$ ;NO CLR OS ;SET OPTIONS INSENSITIVE CALL REKILL ;KILL OFF SAVED R.E. BR 10$ ; 50$: MOV #9.,R1 ;?9 IF BAD OPTION JMP ERROR ; 60$: RETURN ;DONE ; ; PRINT ; PCOM: CALL NONZER ;DEFAULTS PCOM1: MOV ADR1,R1 ;GET POINTER TO MOV (R1),R0 ;TEXT CALL GETLIN ; MOV #LBUF1,R0 ;PUT OUT TO THE TTY CALL TTYSTR ; ADD #2,ADR1 ;GET NEXT LINE CMP ADR1,ADR2 ; BLOS PCOM1 ;STILL MORE TO DO MOV ADR2,DOT ;RESET CURRENT LINE RETURN ; ; ; QUIT ; QCOM: CALL NOADDR ;NO ADDRESS ALLOWED EXIT$S ; ; ; READ ; RCOM: CALL DEFDOT ;DEFAULTS MOV ADR2,R5 ;READ STUFF FROM FILE CALL READIN ; TSTB SFN ;IF NO SAVED NAME BNE 10$ ;THEN CALL SAVEFN ;SAVE THE NAME 10$: RETURN ; ; ; SUBSTITUTE ; SCOM: CALL NONZER ;DEFAULTS CLR SNUM ;SET WHICH ONE TO DO CALL GETC ;ZERO MEANS ALL CMP R0,#'0 ; BLO 10$ ; CMP R0,#'9 ; BHI 10$ ; CALL GETNUM ; MOV R1,SNUM ; CALL GETC ; 10$: MOV R0,R2 ;SAVE R.E. DELIMITER CALL COMPIL ;THE PATTERN ; ; COPY RHS TO BUFFER 2. ; MOV #LBUF2,R1 ;COPY OVER R.H.S. 20$: CALL GETC ;GET CHARACTER CMP R0,#NL ;ERROR FOR NEWLINE BEQ 35$ ; CMP R0,#EOF ;OR GLOBAL EOF BEQ 35$ ; CMP R0,#'\ ;ESCAPE BNE 30$ ;NO CALL RSTORE ;SAVE THE ESCAPE CALL GETC ;GET THE ACTUAL CHARACTER CMP R0,#EOF ;CANNOT BE GLOBAL EOF BEQ 35$ ; CALL RSTORE ; BR 20$ ; 30$: CMP R0,R2 ;END OF R.H.S. BEQ 40$ ;YES CALL RSTORE ;SAVE THE CHARACTER BR 20$ ; 35$: MOV #9.,R1 ;?9 IS HERE SO IT REACHES JMP ERROR ; 40$: CLRB (R1) ;PUT NULL ON R.H.S. END CLR SANY ;SET NO MATCHES AT ALL ; ; TOP OF THE ONCE PER LINE LOOP. ; 50$: MOV SNUM,SWNUM ;RESET SOME VARIABLES CLR SFLAG ; MOV @ADR1,R0 ;GET SOURCE LINE CALL GETLIN ; MOV #LBUF1,R2 ;POINT AT ORIGINAL TEXT MOV R2,ORG ;FOR MATCH MOV #PBUF,R1 ;FOR MATCH MOV #LBUF3,R3 ;DESTINATION POINTER ; ; TOP OF THE NEXT MATCH LOOP. ; 60$: TSTB (R2) ;ANY MORE BEQ 160$ ;NO MOV R2,R0 ;TRY FOR A MATCH CALL MATCH ; BCS 85$ ;NO TST SNUM ;DO THEM ALL BEQ 80$ ;YES DEC SWNUM ;NO, DO THIS ONE BNE 85$ ;BR IF NO 80$: CMP R0,R2 ;IS THIS A ZERO LENGTH MATCH BNE 90$ ;NO TST SFLAG ;DO IT BEQ 90$ ;BR IF YES 85$: MOVB (R2)+,R5 ;JUST MOVE ALONG CALL SSTORE ; BR 60$ ; 90$: MOV #LBUF2,R4 ;GET POINTER TO R.H.S. 100$: MOVB (R4)+,R5 ;PICK UP CHARACTER BEQ 150$ ;DONE CMP R5,#'\ ;ESCAPE BNE 110$ ;NO MOVB (R4)+,R5 ;MOVE NEXT CHARACTER BR 140$ ; 110$: CMP R5,#'& ;REPLACE TEXT BNE 140$ ;NO MOV R4,-(SP) ;SAVE R.H.S. POINTER MOV R2,R4 ;GET POINTER TO WHAT GOT MATCHES 120$: CMP R4,R0 ;COPY OVER BHIS 130$ ; MOVB (R4)+,R5 ; CALL SSTORE ; BR 120$ ; 130$: MOV (SP)+,R4 ;RESTORE R.H.S. BR 100$ ; 140$: CALL SSTORE ;STORE DOWN THE CHARACTER BR 100$ ; 150$: INC SFLAG ;SET WE DID ONE INC SANY ;SET WE DID ONE AT ALL MOV R0,R2 ;MOVE ALONG BR 60$ ; ; ; END OF LINE. ; 160$: TST SFLAG ;ANY CHANGES ON THIS LINE BEQ 165$ ;NO, GO ON CLR R5 ;APPEND A NULL CALL SSTORE ; MOV #LBUF1,R0 ;COPY BUF3 TO BUF1 MOV #LBUF3,R1 ; 162$: MOVB (R1)+,(R0)+ ; BNE 162$ ; CALL PUTLIN ;WRITE NEW LINE TO TEMPFILE MOV R0,@ADR1 ;AND UPDATE THE POINTER TO IT MOV ADR1,DOT ;MOVE DOT TO LAST LINE CHANGED ; ; ADVANCE TO NEXT LINE. ; 165$: ADD #2,ADR1 ;ANY MORE CMP ADR1,ADR2 ; BHI 170$ ;NO JMP 50$ ;GO DO ANOTHER LINE 170$: TST GUPTR ;IN A GLOBAL BNE 180$ ;YES TST SANY ;NO, DID ANYTHING CHANGE BNE 180$ ;YES, OK MOV #1,R1 ;?1 JMP ERROR ; 180$: RETURN ;DONE ; ; WRITE ; JOIN ; WCOM: MOV #FO.UPD,R5 ;WRITE, FIRST TEST IS UPDATE BR WJ ; JCOM: MOV #FO.APD,R5 ;JOIN, FIRST TEST IS APPEND WJ: CALL DEFALL ;DEFAULT TO ENTIRE FILE CALL FILE ;GET THE FILE NAME OPEN$ #FDB,R5 ;TRY TO OPEN THE FILE BCC 10$ ;OK CMPB F.ERR(R0),#IE.NSF ;IS THE ERROR NO FILE BNE 60$ ;NO, HARD ERROR OPEN$W ;OPEN FOR PLAIN WRITING BCS 60$ ;ERROR 10$: FDAT$R ,#R.VAR,#FD.CR ;MAKE SURE ATTRIBUTES ARE OK CLR FC ;RECORD COUNT MOV #LBUF2,FP ;WORK POINTER 20$: MOV @ADR1,R0 ;GET ADDRESS OF LINE CALL GETLIN ;GET TEXT MOV #LBUF1,R2 ; 30$: MOVB (R2)+,R0 ;PUT OUT ALL THE CHARACTERS BEQ 40$ ; CALL 70$ ; BR 30$ ; 40$: ADD #2,ADR1 ;BUMP TO NEXT LINE CMP ADR1,ADR2 ;DONE BLOS 20$ ;BR IF NOT MOV #FDB,R0 ;CLOSE FILE WITH TRUNCATION CALL .TRNCL ; TST GUPTR ;IN GLOBAL BNE 50$ ;YES MOV FC,R1 ;PUT OUT THE COUNT CALL TTYNUM ; CALL TTYNL ; 50$: TSTB SFN ;IS THERE A SAVED NAME BNE 55$ ;YES CALL SAVEFN ;NO, SAVE THE NAME 55$: RETURN ; 60$: MOV #8.,R1 ;FILE OPEN ERROR JMP ERROR ; 70$: CMP R0,#NL ;NEWLINE BEQ 80$ ;YES CMP FP,#LBUF2+LBS ;NO, DOES IT FIT BHIS 100$ ;NO ?10 MOVB R0,@FP ;PUT IN THE BUFFER INC FP ; BR 90$ ; 80$: MOV FP,R1 ;COMPUTE RECORD SIZE SUB #LBUF2,R1 ; PUT$S #FDB,#LBUF2,R1 ;PUT OUT THE RECORD BCS 100$ ;ERROR INC FC ;COUNT UP 1 RECORD MOV #LBUF2,FP ;BACK UP POINTER 90$: RETURN ;DONE 100$: CALL .TRNCL ;ERROR, CLOSE THE FILE MOV #10.,R1 ;?10 JMP ERROR ; ;+ ; ** DEFDOT - DEFAULT TO .,. ; ** DEFALL - DEFAULT TO 1,$ ; ** TDELIM - CHECK FOR LEGAL TEXT DELIMITER ; ** NONZER - DISALLOW LINE ZERO ; ** NOADDR - DISALLOW ANY ADDRESS ; ; THESE ROUTINES ARE USED TO VALIDATE THE ADDRESSES OF COMMANDS. ALL ; JUMP DIRECTLY TO ERROR ROUTINES IF THEY MUST. ;- DEFDOT: TST ADR2 ;IS THERE AN ADDRESS BNE 10$ ;YES MOV DOT,ADR1 ;SET BOTH TO DOT MOV DOT,ADR2 ; 10$: RETURN ; TDELIM: CALL GETC ;GET CHARACTER CMP R0,#NL ;IS IT A NEWLINE BEQ 10$ ;YES, OK CMP R0,#' ;IS IT A BLANK BNE ERR9 ;NO, ERROR 10$: RETURN ; NOADDR: TST ADR2 ;ANY ADDRESS BNE ERR9 ;YES, ERROR RETURN ; .ENABL LSB DEFALL: TST ADR2 ;IS THERE AN ADDRESS BNE 10$ ;YES MOV ZERO,ADR1 ;SET 1 ADD #2,ADR1 ; MOV DOL,ADR2 ;SET $ BR 10$ ; NONZER: CALL DEFDOT ;DEFAULT ADDRESS 10$: CMP ADR1,ADR2 ;CHECK FOR WRAPAROUND BLOS 20$ ; MOV #5,R1 ;?5 JMP ERROR ; 20$: CMP ADR1,ZERO ;LINE ZERO BEQ ERR9 ;YES, ERROR RETURN ; .DSABL LSB ERR9: MOV #9.,R1 ;?9 JMP ERROR ; ;+ ; ** RSTORE - STORE R.H.S. CHARACTER ; ** SSTORE - STORE RESULT CHARACTER ; ; THESE TWO SMALL ROUTINES ARE USED BY THE SUBSTITUTE COMMAND. THEY ; PROBABLY SHOULD HAVE BEEN PUT UP WITH IT. ;- RSTORE: CMP R1,#LBUF2+LBS-1 ;WILL IT FIT BHIS ERR0 ;NO MOVB R0,(R1)+ ;YES RETURN ; SSTORE: CMP R3,#LBUF3+LBS-1 ;WILL IT FIT BHIS ERR0 ;NO MOVB R5,(R3)+ ;YES RETURN ; ERR0: CLR R1 ;?0 IF OVERFLOW JMP ERROR ; ;+ ; ** SAVEFN - SAVE THE FILE NAME ; ; THIS LITTLE ROUTINE IS CALLED FROM THE R, E AND W COMMANDS TO SAVE ; THE FILE NAME (IN FN) IN THE SAVED NAME (SFN). ; ; USES: ; R0, R1 ;- SAVEFN: MOV #FN,R0 ;NAME MOV #SFN,R1 ;SAVED NAME 10$: MOVB (R0)+,(R1)+ ;COPY BNE 10$ ; RETURN ; .END