    title   CUBIX LINE EDITOR
*
* EDIT: A line oriented text editor
*
* ?COPY.TXT 1983-2005 Dave Dunfield
* **See COPY.TXT**.
*
    ORG OSRAM       DOS APPLICATION SPACE
*
RAM EQU OSRAM+$600  START OF AVAILABLE RAM, COMMAND BUFFER
EDBUF   EQU RAM+128     EDIT BUFFER
SERBUF  EQU EDBUF+128   SERIAL BUFFER
TEMP    EQU SERBUF+522  TEMPORARY STORAGE
TEMP1   EQU TEMP+2      TEMPORARY STORAGE
SAVPTR  EQU TEMP1+2     SAVED FILE POSITION (FOR :S AND :R)
FILNAM  EQU SAVPTR+2    SAVED FILENAME
AUTSTR  EQU FILNAM+25   STRING FOR AUTOMATIC COMMAND
STACK   EQU RAM+1024    EDITOR STACK
TEXT    EQU STACK       RAM TEXT AREA
*
EDIT    CMPA    #'?'        HELP COMMAND
    BNE QUAL        NO, LOOK FOR QUALIFIERS
    SSR 25
    FCCZ    'Use: EDIT[/BATCH/QUIET] <file> [<cmd file>]'
    SSR 0
QUAL    LDA ,Y      GET CHARACTER FROM OPERAND
    CMPA    #'/'        QUALIFIER?
    BNE MAIN        NO, CONTINUE
    LDX #QTABLE     POINT TO QUALIFIER TABLE
    SSR 18      LOOK IT UP
    CMPB    #QMAX       IS IT VALID?
    BHS QERR        NO, GET UPSET
    LDX #FCMD       POINT TO FLAG COMMAND SPACE
    CLR B,X     SET THIS FLAG
    BRA QUAL        CONTINUE
* QUALIFIER WAS NOT FOUND
QERR    SSR 24      DISPLAY MSG
    FCCZ    /Invalid Qualifier: '/
    LDA ,Y+     GET CHAR
DSQU1   SSR 33      DISPLAY
    SSR 5       TEST FOR TERMINATOR
    BEQ GOABO       YES, EXIT
    CMPA    #'/'        NEXT QUALIFIER?
    BNE DSQU1       NO, CONTINUE
GOABO   SSR 25      DISPLAY MESSAGE
    FCB $27,0       QUOTE, LF, CR
    LDA #1      RETURN CODE = 1
    SSR 0
* CONTINUE WITH EDITOR
MAIN    PSHS    Y       SAVE POINTER TO FILENAME
    LDX #FILNAM     POINT TO SAVED NAME
EDI1    LDA ,Y+     GET CHAR FROM PARAMETER LINE
    STA ,X+     SAVE IN SAVED FILENAME
    BEQ EDI2        ZERO EXITS
    CMPA    #' '        SO DUZ SPACE
    BEQ EDI2        EXIT
    CMPA    #$0D        END OF FILE?
    BNE EDI1        NO, KEEP SAVEING
EDI2    PULS    Y       RESTORE FILENAME POINTER
    SSR 10      GET FILENAME
    BNE ABORT       INVALID, GET UPSET
    SSR 68      DOES IT EXIST?
    BEQ FILEXI      IF SO, IT EXISTS
    LDA #$FF        END OF FILE MARKER
    STA TEXT        CLEAR THE FILE
    TST QCMD        QUIET?
    BEQ GOEDIT      YES, DON'T DISPLAY MESSAGE
    SSR 25      DISPLAY MESSAGE
    FCCZ    'NEW FILE:'
    BRA GOEDIT      GET COMMAND
FILEXI  LDX #TEXT       POINT TO TEXT BUFFER
    SSR 53      LOAD FILE
    BNE ABORT       FAILED, GIVE UP
GOEDIT  TST FCMD        IS FILE INPUT?
    BNE GOED1       NO, SKIP IT
    SSR 10      GET FILENAME
    BNE ABORT       UPSET
    LBSR    OPENR       OPEN INPUT FILE
    BNE ABORT       ERROR, EXIT
GOED1   LDU #TEXT       LOOK FOR TEXT
    STU SAVPTR      SAVE FOR LATER
    LDA #$0D        GET CR
    STA AUTSTR      INIT AUTO COMMAND STRING
EDMSG   TST QCMD        QUIET?
    BEQ GOCMD       NO OUTPUT
    SSR 25      DISPLAY MESSAGE
    FCCZ    'EDIT:'
GOCMD   LDS #STACK      POINT TO STACK
    LBSR    GETLIN      GET A LINE
    SSR 4       NULL?
    BNE COM1        NO, TRY PRINT
GODISP  LBSR    DSPLIN      DISPLAY IT
    BRA GOCMD       AND AGAIN
* LOOK FOR COMMAND
COM1    LDA ,Y+     GET COMMAND
    CMPA    #$61        LOWER CASE?
    BLO NOCP        NO, ITS OK
    ANDA    #$5F        CONVERT TO UPPER
NOCP    LDB ,Y      GET NEXT CHAR
    ANDB    #$5F        CONVERT TO UPPER
* 'QUIT' COMMAND
    CMPA    #'Q'        QUIT?
    BNE PRINT       NO, TRY NEXT
    CMPB    #'U'        REQUIRE AT LEAST 'QU'
    LBNE    UNCMDB      GET UPSET
    CLRA            ZERO RETURN CODE
ABORT   SSR 0       GO HOME
* 'PRINT' COMMAND
PRINT   CMPA    #'P'        IS IT PRINT?
    BNE COM2        NO, TRY NEXT
    LBSR    GETOP1      GET OPERAND
PR1 STU TEMP        SAVE FOR LATER
    TST ,U      AT END OF FILE?
    BMI EOF     YES, REPORT
    LBSR    DSPADV      DISPLAY AND ADVANCE
    DECB            REDUCE COUNT
    BNE PR1     CONTINUE
    LDU TEMP        BACKUP TO LAST LINE
    BRA GOCMD       BACK FOR NEXT COMMAND. 
* 'NEXT' COMMAND
COM2    CMPA    #'N'        IS IT 'NEXT'
    BNE COM3        NO, TRY NEXT
    LBSR    GETOP1      GET OPERAND
NEX1    LBSR    ADVLIN      ADVANCE
    BMI EOF     REPORT EOF
    DECB            REDUCE COUNT
    BNE NEX1        CONTINUE
    BRA GODISP      NEXT COMMAND
* END OF FILE WAS FOUND
EOF LBSR    DSPEOF      DISPLAY END OF FILE
    BRA GOCMD       NEXT COMMAND
TOF TST QCMD        QUIET MODE?
    BEQ GOCMD       YES, DON'T DISPLAY
    SSR 24      DISPLAY MSG
    FCCZ    'TOF:'
GOLFCR  SSR 22      NEW LINE
    BRA GOCMD
* 'UP' COMMAND
COM3    CMPA    #'U'        WAS IT UP?
    BNE COM4        NO, TRY NEXT
    LBSR    GETOP1      GET OPERAND
UP1 LBSR    BAKLIN      BACKUP
    BNE TOF     TOP OF FILE
    DECB            REDUCE COUNT
    BNE UP1     CONTINUE
    LBRA    GODISP      GO SHO IT
* INSERT COMMAND
COM4    CMPA    #'I'        INSERT?
    BNE COM5        NO, TRY DELETE
    TST QCMD        QUIET?
    BEQ INSP
    SSR 25      DISPLAY MESSAGE
    FCCZ    'INPUT:'
INSP    LBSR    GETLIN      GET A LINE
    LDA ,Y      GET LINE
    CMPA    #$0D        NULL (ZERO LENGTH)?
    LBEQ    EDMSG       IF SO, EXIT
    LBSR    INSERT      INSERT THE LINE
    BRA INSP        GET NEXT COMMAND
* BEGINNING OF FILE COMMAND
COM5    CMPA    #'B'        BEGIN?
    BNE COM6        NO, SKIP IT
    LDU #TEXT       POINT TO BEGINNING
    TST ,U      IS IT NULL
    BMI TOF     NO, DISPLAY IT
    LBRA    GODISP      INDICATE TOP OF FILE
* END OF FILE COMMAND
COM6    CMPA    #'E'        GO TO END OF FILE?
    BNE COM7        NO, TRY NEXT
    CMPB    #'X'        IS IT EXIT
    LBEQ    EXIT
    LBSR    FNDEOF      LOCATE END OF FILE
    LEAU    -1,U        BACKUP TO IT
EOF1    BRA EOF     INDICATE WE ARE THERE
* DELETE LINES COMMAND
COM7    CMPA    #'D'        DELETE?
    BNE COM8        NO, TRY NEXT
    CMPB    #'E'        IS IT 'DE'?
    LBNE    UNCMDB      NO, COMPLAIN
    LEAY    1,Y     SKIP 'E'
    LBSR    GETOP1      GET OPERAND
    PSHS    U       SAVE POINTER
DEL1    LBSR    ADVLIN      ADVANCE A LINE
    BMI GODEL       GO DELETE IT
    DECB            REDUCE COUNT
    BNE DEL1        GOT FOR IT
GODEL   LDX ,S      GET POINT TO START
GODEL1  LDA ,U+     GET CHARACTER FROM LINE
    STA ,X+     SAVE
    BPL GODEL1      SAVE IT ALL
    PULS    U       RESTORE POINTER
EOFTST  LDA ,U      GET STATUS
    BMI EOF1        INDICATE IF EOF
    LBRA    GOCMD       GET NEXT COMMAND
* 'CHANGE' COMMAND
COM8    CMPA    #'C'        TEST FOR CHANGE
    LBNE    LOCATE      NO, TRY NEXT
    CMPB    #'A'        CHANGE ALL?
    BEQ CHA1        IF SO, SKIP IT
    CMPB    #'D'        IS IT CHANGE DISPLAY?
    BEQ CHA1        YES
    CMPB    #'H'        CHANGE LINE?
    BNE CHA     NO, SKIP IT
CHA1    LEAY    1,Y     SKIP
CHA CLR TEMP+1      INDICATE NO DISPLAY
    CLR TEMP1
    CLR TEMP1+1
    SSR 4       SKIP AHEAD
    LBEQ    BADOPR      NO OPERATOR
    STA TEMP        SAVE DELIMITER
    LEAY    1,Y     SKIP DELIMITER
    PSHS    U       SAVE U
* TEST FOR CHANGE LINE
    CMPB    #'H'        CHANGE LINE?
    BNE CHAL        NO, TRY CHANGE ALL
    LBSR    DOCHG       DO CHANGE
    LBNE    CNOTR       NOT FOUND
CHL1    LDD TEMP1
    ADDD    #1
    STD TEMP1
    LBSR    DOCH1       DO IT AGAIN
    BEQ CHL1        CONTINUE
    LDU ,S      RESTORE
    LBSR    DELETE      DELETE THIS LINE
    LDY #EDBUF      POINT TO BUFFER
    LBSR    INSERT      INSERT IT
    PULS    U       RESTORE
    BSR SHOCHG      DISPLAY IT
    LBRA    GODISP
CNOTR   PULS    U       RESTORE TEXT POINTER
CNOTF   SSR 25
    FCCZ    'Not found.'
    LBRA    GOCMD
SHOCHG  LDA QCMD
    BEQ SHOR
    LDD TEMP1
    BEQ CNOTF
    SSR 26      OUTPUT IN DEC
    SSR 25
    FCCZ    ' occurances changed.'
SHOR    RTS
* CHANGE ALL OCCURENCES
CHAL    CMPB    #'A'        CHANGE FILE?
    BEQ GOCHG       YES
    CMPB    #'D'        CHANGE DISPLAY?
    BNE CHGF        NO, JUST FIRST OCCURRANCE
    DEC TEMP+1      SET FLAG
GOCHG   LDU #TEXT       POINT TO RAM
CHAL1   PSHS    U       SAVE IT
    LBSR    DOCHG       PERFORM CHANGE
    BNE NEXTL       NOT ON THIS LINE
CHAL2   LDD TEMP1
    ADDD    #1
    STD TEMP1
    LBSR    DOCH1
    BEQ CHAL2
    PULS    U
    PSHS    Y,U
    LBSR    DELETE
    LDY #EDBUF
    LBSR    INSERT
    PULS    Y,U
    LDA TEMP+1      TEST FOR CHANGE DISPLAY
    BEQ CHAL3       NO, OK
    LBSR    DSPADV      DSPLAY LINE
    BRA CHAL5       TEST FOR END OF FILE
CHAL3   LDA ,U+
    BMI CHAL4
    CMPA    #$0D
    BNE CHAL3
    BRA CHAL5
NEXTL   LEAS    2,S
CHAL5   LDA ,U
    BPL CHAL1
CHAL4   PULS    U
    BSR SHOCHG
    LBRA    GOCMD
* CHANGE FIRST OCCURANCE
CHGF    LBSR    DOCHG
    LBNE    CNOTR
* COPY REMAINDER OF LINE OVER
MTC3    LDA ,U+     GET CHARACTER FROM LINE
    STA ,X+     SAVE IN OUTPUT
    CMPA    #$0D        END OF LINE?
    BNE MTC3        COPY REMAINDER OF LINE OVER
    LDU ,S      GET TEXT POINTER
    LBSR    DELETE      DELETE THIS LINE
    LDY #EDBUF      POINT TO EDIT BUFFER
    LBSR    INSERT      PUT IT IN
    PULS    U
    LBRA    GODISP
* PERFORM CHANGE TO TEXT, ON ENTRY, Y POINTS TO CHANGE COMMAND OPERANDS
* ON EXIT, Z FLAG IS SET IT CHANGE WAS FOUND, AND U POINTS TO REMAINDER
* OF LINE, OTHERWISE, U POINTS TO START OF NEXT LINE
DOCHG   LDX #EDBUF      POINT TO EDITING BUFFER
    LDA ,U      CHECK POSITION
    LBMI    EOF     WE ARE AT END OF TEXT
DOCH1   EQU *
MTCH1   PSHS    X,Y,U       SAVE POINTERS
MTCH    LDA ,Y+     GET CHARACTER
    CMPA    TEMP        IS IT DELIMITER?
    BEQ MTCF        WE FOUND IT
    LDA ,U+     GET CHAR FROM BUFFER
    STA ,X+     SAVE IN EDIT BUFFER
    CMPA    #$0D        DID WE HIT END
    BEQ MTNOTF      NOT FOUND
    CMPA    -1,Y        DOES IT MATCH US
    BEQ MTCH        WE FOUND
    PULS    X,Y,U       RESTORE REGS
    LEAX    1,X     ADVANCE IN BUFFER
    LEAU    1,U     ADVANCE IN TEXT
    BRA MTCH1       NOT FOUND
MTNOTF  LDY 2,S     RESTORE
    LEAS    6,S     SKIP TWO SAVED U'S
    LDA #1      CLEAR Z FLAG
    RTS
* INSERT CHANGE BUFFER CONTENTS
MTCF    LDX ,S++        GET POINTER TO THIS PART
MTC1    LDA ,Y+     GET CHARACTER FROM LINE
    CMPA    #$0D        END OF LINE
    BEQ MTC2        INVALID OPERATOR
    CMPA    TEMP        DELIMITER?
    BEQ MTC2        IF SO, QUIT
    STA ,X+     SAVE IN BUFFER
    BRA MTC1        AND CONTINUE
MTC2    PULS    Y       RESTORE Y
    LEAS    2,S     SKIP SAVED U
    RTS
* LOCATE COMMAND
LOCATE  CMPA    #'/'        LOCATE?
    BNE REPEAT      NO, SKIP IT
LOC1    LBSR    ADVLIN      ADVANCE A LINE
    LBMI    EOF     INDICATE WE HIT THE END
LOC2    PSHS    Y,U     SAVE POINTERS
LOC3    LDA ,U      GET CHARACTER FROM BUFFER
    BMI HITEOF      FOUND END OF FILE
    LDA ,Y+     DO WE HAVE IT
    CMPA    #$0D        END OF LINE
    BEQ FNDIT       IF SO, WE FOUND
    CMPA    ,U+     IS THIS IT?
    BEQ LOC3        IF CONTINUES TO MATCH, GO FOR IT
    PULS    Y,U     RESTORE REGS
    LEAU    1,U     SKIP TO NEXT
    BRA LOC2        KEEP LOOKING
HITEOF  LEAU    -1,Y        BACKUP
    LBRA    EOF     GET UPSET
FNDIT   LDA ,-U     BACKUP
    CMPA    #$0D        LOOK FOR CR
    BNE FNDIT       KEEP LOOKING
    LEAU    1,U     SKIP AEHEAD
    LBRA    GODISP
* REPEAT A LINE
REPEAT  CMPA    #'+'        REPEAT?
    BNE WRITE       NO, TRY NEXT
    LBSR    GETOP1      GET OPERAND
    LDX #EDBUF      POINT TO EDIT BUFFER
    PSHS    U       SAVE POINTER
REP1    LDA ,U+     GET CHAR. FROM TEXT
    STA ,X+     SAVE IN TEXT
    CMPA    #$0D        END?
    BNE REP1        NO, MOVE ENTIRE LINE
    PULS    U       RESTORE POINTER
    STB TEMP        SAVE FOR LATER
REP2    LDY #EDBUF      POINT TO BUFFER
    LBSR    INSERT      PUT IT IN
    DEC TEMP        REDUCE COUNT
    BNE REP2        KEEP AT IT
    BRA GOCMD1      GET NEXT COMMAND
* WRITE FILE TO SEPERATE FILE
WRITE   CMPA    #'W'        IS IT 'WRITE'?
    BNE READ        NO, TRY NEXT
    LBSR    GETOP1      GET OPERAND
    PSHS    B       SAVE COUNT
    LBSR    UCASE       CONVERT TO UPPER
    SSR 10      GET FILENAME
    BNE GOCMD1      INVALID, QUIT
    LDB ,S+     RESTORE B
    BNE WRLINS      YES
    LBSR    SAVFIL      SAVE IT
    BRA GOCMD1      QUIT
WRLINS  LBSR    OPENW       OPEN FOR WRITE
    BNE GOCMD1      BAD, QUIT
    TFR U,X     COPY POINTER
    LDY #0      START WITH ZERO
WRLI1   LDA ,X      GET CHAR
    BMI WRLI2       IF END, CLOSE IT
    LBSR    WRITEC      WRITE CHAR
    BNE GOCMD1      ERROR, QUIT
    LDA ,X+     GET CHAR BACK
    CMPA    #$0D        END OF LINE?
    BNE WRLI1       OK
    LEAY    1,Y     ADVANCE LINE COUNT
    DECB            REDUCE COUNT
    BNE WRLI1       CONTINUE
WRLI2   LBSR    CLOSE       CLOSE FILE
    TST QCMD        BEING QUIET?
    BEQ GOCMD1      IF SO, SAY NOTHING
    TFR Y,D     COPY TO D
    SSR 26      DISPLAY IN DECIMAL
    SSR 25
    FCCZ    ' lines written.'
GOCMD1  LBRA    GOCMD       BACK FOR ANOTHER COMMAND
* READ ANOTHER FILE INTO THIS ONE
READ    CMPA    #'R'        IS IT READ?
    BNE QUERY       NO, TRY NEXT
    LBSR    UCASE       CONVERT TO UPPER
    SSR 10      GET FILE NAME
    BNE GOCMD1      INVALID
    LDA ,U      ARE WE AT EOF?
    BPL READ1       NO, DO IT HARD WAY
    TFR U,X     POINT AT END OF FILE
    SSR 53      LOAD FILE
    BRA GOCMD1      AND CONTINUE
READ1   LBSR    OPENR       OPEN FILE
    BNE GOCMD1      BAD, QUIT
READ2   LDX #RAM        POINT TO RAM
    TFR X,Y     COPY FOR LATER INSERT
READ3   LBSR    READC       READ A CHAR
    BNE GOCMD1      END OF LINE
    STA ,X+     SAVE IT
    CMPA    #$0D        TEST FOR END OF LINE
    BNE READ3       KEEP READING
    LBSR    INSERT      INSERT LINE
    BRA READ2       AND GO AGAIN,
* '?' QUERY FILE
QUERY   CMPA    #'?'        IS IT QUERY?
    BNE DOSCMD      NO, TRY NEXT
    LDY #TEXT       POINT TO START
    LDX #0      INDICATE NUMBER OF LINE
QUE1    LDA ,Y+     
    BMI QUE2        GET OUT ON END OF FILE
    CMPA    #$0D        IS IT A NEW LINE
    BNE QUE1        NO, KEEP LOOKING
    LEAX    1,X     ADVANCE
    BRA QUE1        AND KEEP LOOKING
QUE2    LEAY    -1,Y        BACKUP TO EOF MARKER
    TFR Y,D     COPY TO D
    SUBD    #TEXT       CONVERT TO SIMPLE NUMBER
    SSR 26      DISPLAY IN DECIMAL
    SSR 24
    FCCZ    ' bytes, '
    TFR X,D     COPY NUMBER OF LINES
    SSR 26      DISPLAY
    SSR 25
    FCCZ    ' lines'
    BRA GOCMD2      GET NEXT COMMAND
* EXECUTE DOS COMMAND
DOSCMD  CMPA    #'*'        IS IT DOS COMMAND?
    BNE AUTCMD      NO, TRY NEXT
    LBSR    UCASE       CONVERT TO UPPER CASE
    PSHS    U       SAVE TEXT POINTER
    SSR 100     EXECUTE COMMAND
    PULS    U       RESTORE POINTER
    BRA GOCMD2      BACK FOR NEXT COMMAND
* SET AUTOMATIC COMMAND
AUTCMD  CMPA    #'$'        SET AUTO?
    BNE SAVREST     NO, TRY NEXT
    LDX #AUTSTR     POINT TO STRING
AUT1    LDA ,Y+     GET STRING
    STA ,X+     SAVE
    CMPA    #$0D        END OF LINE?
    BNE AUT1        CONTINUE
GOCMD2  LBRA    GOCMD       BACK FOR MORE
* SAVE AND RESTORE
SAVREST CMPA    #':'        IS IT COLON COMMAND
    BNE UNCMD       NO, TRY NEXT
    CMPB    #'S'        IS IT A SAVE?
    BNE REST1       IS IT A REPEAT?
    STU SAVPTR      SAVE IT
    LBRA    GOCMD       AND GET NEXT COMMAND
REST1   CMPB    #'R'        RESTORE
    BNE UNCMDB      NO, INDICATE WE ARE UPSET
    LDU SAVPTR      POINT TO SAVED LOCATION
    LEAU    1,U     ADVANCE
    LBSR    BAK1        POSITION TO START OF LINE
    LBRA    GODISP      DISPLAY IT
* DISPLAY VALUE FROM B ACCUMULATOR AS ERROR MESSAGE
UNCMDB  TFR B,A     COPY
* COMMAND WAS NOT RECOGNIZED
UNCMD   SSR 24
    FCB $07
    FCCZ    '?EDIT: '
    LBSR    PUTCHR
    SSR 22
    BRA GCMD
* BAD OPERAND
BADOPR  SSR 25
    FCCZ    'Bad operand.'
GCMD    LBRA    GOCMD
*
* INSERT A LINE(Y) INTO THE TEXT
*
INSERT  CLRB            START WITH ZERO
    PSHS    Y,U     SAVE POINTERS
INS1    LDA ,Y+     GET CHARACTER FROM LINE
    INCB            ADVANCE COUNTER
    CMPA    #$0D        IS IT CR?
    BNE INS1        NO, KEEP LOOKING
    BSR FNDEOF      LOCATE END OF FILE
    LEAX    B,U     ADVANCE FOR REST
INS2    LDA ,-U     SKIP BACK
    STA ,-X     SAVE BACK
    CMPU    2,S     ARE WE OVER
    BHI INS2        CONTINUE
    PULS    Y,U     RESTORE POSITION
INS3    LDA ,Y+     GET CHAR
    STA ,U+     SAVE
    CMPA    #$0D        END OF LINE?
    BNE INS3        NO, CONTINUE
    RTS
*
* DELETE A LINE FROM THE TEXT(U)
*
DELETE  PSHS    U       SAVE POINTER
    LBSR    ADVLIN      ADVANCE A LINE
    LDX ,S      GET POINTER
DELI1   LDA ,U+     GET CHAR FROM TEXT
    STA ,X+     SAVE IN RAM
    BPL DELI1       DO IT ALL
    PULS    U,PC        GO HOME
*
* FINDS END OF FILE
*
FNDEOF  LDA ,U+     GET CHAR FROM FILE
    BPL FNDEOF      KEEP LOOKING
    RTS
*
* ADVANCE A LINE
*
ADVLIN  LDA ,U+     GET CHAR FROM LINE
    BMI ADVEOF      END OF FILE
    CMPA    #$0D        END OF LINE?
    BNE ADVLIN      NO, KEEP LOOKING
    CLRA            ZERO RET
    RTS
ADVEOF  LEAU    -1,U        BACKUP
    RTS
*
* BACKUP A LINE
*
BAKLIN  LEAU    -1,U        BACK TO CR
BAK1    CMPU    #TEXT       ARE WE OVER
    BLO BAKTOF      AT TOP OF FILE
    BEQ FNDTOP      WE FOUND THE TOP
    LDA ,-U     GET CHAR
    CMPA    #$0D        ARE WE OVER
    BNE BAK1        NO, KEEP LOOKING
    LEAU    1,U     SKIP AHEAD
FNDTOP  RTS
BAKTOF  LDU #TEXT
    LDA #$FF        SET M FLAG
    RTS
*
* DISPLAY A LINE
*
DSPLIN  PSHS    U       SAVE REG
    BSR DSPADV      DISPLAY
    PULS    U,PC
DSPADV  TST ,U      END OF TEXT?
    BMI DSPEOF      IF SO, QUIT
    LDA ,U+     GET CHAR
    BSR PUTCHR      OUTPUT
    CMPA    #$0D        END OF LINE
    BNE DSPADV      CONTINUE
LFCR    LDA #$0D        CR
    BSR PUTCHR
    LDA #$0A        LF
PUTCHR  TST QCMD        QUIET?
    BEQ PUTQC       SKIP IT
    SSR 33      OUTPUT
PUTQC   RTS
DSPEOF  TST QCMD
    BEQ PUTQC
    SSR 25
    FCCZ    'EOF:'
    RTS
*
* GET AN OPERAND
*
GETOP1  SSR 4       ANYTHING ELSE?
    BEQ DEFAU1      DEFAULT TO ONE
    SSR 8       GET NUMBER
    LBNE    GOCMD       NO, SKIP OT
    TFR X,D     COPY TO D
    TSTA            NON ZERO HIGH BYTE
    LBNE    BADOPR      INVALID OPERAND
    RTS
DEFAU1  LDD #1      ASSUME ONE
    RTS
*
* GET AN INPUT LINE FROM THE TERMINAL
*
GETLFCR LBSR    LFCR        NEW LINE
GETLIN  LDY #RAM        POINT TO INPUT BUFFER
    CLRB            START AT POSITION ZERO
    LDA #'.'        PROMPT
    LBSR    PUTCHR      DISPLAY
GETL1   TST FCMD        LOOK FOR FILE COMMAND
    BEQ FINP        FILE INPUT
    SSR 34      GET A CHARACTER
    CMPA    #$1B        ESCAPE <AUTO COMMAND>
    BEQ DOAUTO      IF SO, HANDLE IT
    CMPA    #$08        BACKSPACE?
    BEQ DODEL
    CMPA    #$7F        DELETE?
    BNE NOTDEL      NO, HANDLE AS USUAL
DODEL   TSTB            AT POSITION ZERO?
    BEQ GETL1       DO NOTHING
    DECB            BACKUP
    SSR 24      DISPLAY MSG
    FCB $08,$20,$08,0
    BRA GETL1
FINP    LBSR    READC       READ A CHARACTER
    BNE FINEOF      FILE INPUT END OF FILE
NOTDEL  LBSR    PUTCHR      DISPLAY
    STA B,Y     SAVE IN BUFFER
    INCB            ADVANCE
    BMI GETLFCR     OVERFLOW
    CMPA    #$0D        ARE WE PAST
    BNE GETL1       GO AGAIN
INRT    LBSR    LFCR
    RTS
DOAUTO  LDX #AUTSTR     POINT TO AUTO STRING
DOAUT1  LDA ,X+     GET CHAR FROM AUTO STRING
    STA B,Y     SAVE IN INPUT
    INCB            ADVANCE
    CMPA    #$0D        END OF LINE?
    BEQ INRT        IF SO, QUIT
    LBSR    PUTCHR      DISPLAY
    BRA DOAUT1      CONTINUE
* END OF FILE ON INPUT
FINEOF  SSR 25      DISPLAY MESSAGE
    FCCZ    '?EOF?'
    LDA #9      RC=9
    SSR 0
* CONVERT INPUT BUFFER TO UPPER-CASE
UCASE   TFR Y,X     COPY POINTER
UCASE0  LDA ,X+     GET CHAR
    CMPA    #'A'+$20    <LC 'A'
    BLO UCASE1      OK
    CMPA    #'Z'+$20    >LC 'Z'
    BHI UCASE1      OK
    SUBA    #$20        CONVERT TO UPPER
    STA -1,X        RESAVE
UCASE1  CMPA    #$0D        CR?
    BNE UCASE0      NO, KEEP CONVERTING
    RTS
*
* EXIT EDITOR, TERMINATE AND SAVE THE FILE
*
EXIT    LDY #FILNAM     POINT TO FILENAME
    SSR 10      GET IN BUFFER
    BSR SAVFIL      SAVE IT
    LBNE    GOCMD
    SSR 0       EXIT
* SAVE FILE USING BLOCK WRITE
SAVFIL  LBSR    FNDEOF      FIND END OF FILE
    LEAU    -1,U        REDUCE BY ONE
    TFR U,D     SAVE
    SUBD    #TEXT       GET SIZE OF FILE
    TFR A,B     COPY TO B
    CLRA            ZERO HIGH BYTE
    LSRB            512 BYTE BOUNDARIES
    INCB            INCLUDE LAST SECTOR
    LDX #TEXT       POINT TO RAM BUFFER
    SSR 54      WRITE IT
    RTS
OPENR   PSHS    U
    LDU #SERBUF
    SSR 55
    PULS    U,PC
OPENW   PSHS    U
    LDU #SERBUF
    SSR 56
    PULS    U,PC
READC   PSHS    U
    LDU #SERBUF
    SSR 59
    PULS    U,PC
WRITEC  PSHS    U
    LDU #SERBUF
    SSR 61
    PULS    U,PC
CLOSE   PSHS    U
    LDU #SERBUF
    SSR 57
    PULS    U,PC
*
* QUALIFIER TABLE
*
QTABLE  FCB $82
    FCC '/BATCH'
    FCB $82
    FCC '/QUIET'
    FCB $80
QMAX    EQU 2       MAX. NUMBER OF QUALIFIERS
* EDITOR SWITCHES
FCMD    FCB $FF     FILE COMMAND INPUT
QCMD    FCB $FF
