NEW
  AUTO 3,1
*--------------------------------------
       .MA JTBL
       .DA #$]1,]2-1
       .EM
*--------------------------------
CHAR.TABLES
CHARS.FOR.COMMANDS .EQ *-CHAR.TABLES
       >JTBL 22,ECHO.LINE         "--ECHO REST OF LINE
       >JTBL 2D,PASS.CMD.TO.PRODOS  DASH COMMAND
       >JTBL 2E,USER.CMD          .--USER DOT COMMAND
       >JTBL 2F,LINK.FSE          /--LINK TO F.S.E.
       >JTBL 3F,HELP              ?--list commands
       >JTBL 00,NML            other, try numbered line
*--------------------------------
CHARS.FOR.READ.LINE.1 .EQ *-CHAR.TABLES
       >JTBL 83,RDL.CATALOG   ^C--MACRO FOR "CATALOG"
       >JTBL 85,RDL.EDIT      ^E--MACRO FOR "EDIT "
       >JTBL 86,RDL.FIND      ^F--MACRO FOR "FIND "
       >JTBL 8C,RDL.LIST      ^L--MACRO FOR "LIST "
       >JTBL 90,RDL.PREFIX    ^P--MACRO FOR "PREFIX"
CHARS.FOR.READ.LINE.2 .EQ *-CHAR.TABLES
       >JTBL 88,RDL.BACKSPACE ^H--BACKSPACE
       >JTBL 8A,RDL.DOWN      ^J--DOWN ARROW KEY
       >JTBL 8B,RDL.UP        ^K--UP ARROW KEY
       >JTBL 8D,RDL.EOL       ^M--CARRIAGE RETURN
       >JTBL 8F,RDL.OVERRIDE  ^O--OVERRIDE
       >JTBL 93,RDL.TOGGLE    ^S--TOGGLE CASE FLAG
       >JTBL 95,RDL.RITARR    ^U--RIGHT ARROW
       >JTBL 98,RDL.RUBOUT    ^X--RUBOUT LINE
       >JTBL 9B,RDL.ESCAPE   ESC--ESCAPE MODE
       >JTBL 00,RDL.ERR
*--------------------------------
CHARS.FOR.ESCAPE      .EQ *-CHAR.TABLES
       >JTBL C0,IO.HOME        @--CLEAR SCREEN AND HOME
       >JTBL C1,IO.RIGHT       A--MOVE CURSOR RIGHT
       >JTBL C2,IO.LEFT        B--MOVE CURSOR LEFT
       >JTBL C3,IO.DOWN        C--MOVE CURSOR DOWN
       >JTBL C4,IO.UP          D--MOVE CURSOR UP
       >JTBL C5,IO.CLREOL      E--CLEAR TO END OF LINE
       >JTBL C6,IO.CLREOP      F--CLEAR TO END OF SCREEN
       >JTBL C9,IO.UP          I--MOVE CURSOR UP
       >JTBL CA,IO.LEFT        J--MOVE CURSOR LEFT
       >JTBL CB,IO.RIGHT       K--MOVE CURSOR RIGHT
       >JTBL CC,ESCAPE.L       L--"LOAD ..." OR "*---..."
       >JTBL CD,IO.DOWN        M--MOVE CURSOR DOWN
       >JTBL D3,ESCAPE.S       S--AUTO-SAVE LINE
       >JTBL D5,USER.ESC.U     U--USER COMMAND
       >JTBL AE,ESCAPE.DOT     .--LIS., COMMAND
       >JTBL 88,IO.LEFT       ^H--LEFT ARROW KEY
       >JTBL 95,IO.RIGHT      ^U--RIGHT ARROW KEY
       >JTBL 8A,IO.DOWN       ^J--DOWN ARROW KEY
       >JTBL 8B,IO.UP         ^K--UP ARROW KEY
       >JTBL 00,RDL.ESC.END   END ESCAPE MODE
*--------------------------------
CHARS.FOR.EDIT        .EQ *-CHAR.TABLES
       >JTBL 80,E.ZAP   ^@ -- Clear to EOL
       >JTBL 81,E.INS   ^A -- Add (Insert)
       >JTBL 82,E.BEG   ^B
       >JTBL 84,E.DEL   ^D
       >JTBL 86,E.FIND  ^F
       >JTBL 88,E.BKSP  ^H
       >JTBL 89,E.TABI  ^I -- Clear to tab
       >JTBL 8C,E.DOWN  ^L
       >JTBL 8D,E.RET   ^M
       >JTBL 8E,E.END   ^N
       >JTBL 8F,E.OVR   ^O
       >JTBL 91,E.RETQ  ^Q -- Clear to EOL, Quit
       >JTBL 92,E.RESTORE ^R -- Restore original line
       >JTBL 93,E.TOGGLE  ^S -- TOGGLE CASE FLAG
       >JTBL 94,E.TAB   ^T
       >JTBL 95,E.RIT   ^U
       >JTBL 98,E.ABORT ^X
       >JTBL 00,E.ILLCHAR
*--------------------------------
RDL.TOGGLE
       JSR IO.CASE.TOGGLE
       JMP RDL3
*--------------------------------
RDL.UP
       JSR IO.UP 
       JMP RDL3
*--------------------------------
RDL.DOWN
       JSR IO.DOWN
       JMP RDL3
*--------------------------------
*      HANDLE TABULATION
*--------------------------------
TAB    TXA          SEE IF IN COLUMN 1
       BEQ .4       YES, AUTO-LINE-NUMBER
.3     JSR E.CHECK.TAB
       BCS .5            ONE MORE SPACE
       LDA #CHR.BLANK
       JSR INSTALL.CHAR
       BCC .3       MORE TO GO
       JMP RDL.RUBOUT
*--------------------------------
.4     CLC          ADD INCREMENT TO CURRENT LINE #
       LDA CURLNO
       ADC INCREMENT.VALUE
       STA CURRENT.LINE.NUMBER
       LDA CURLNO+1
       ADC INCREMENT.VALUE+1
       STA CURRENT.LINE.NUMBER+1
       LDY #0
       JSR CONVERT.LINE.NUMBER.BOTH   STORE AND PRINT NUMBER
       TYA
       TAX
*--------------------------------
.5     LDA #CHR.BLANK
       JMP RDL.ADD.CHAR
*--------------------------------
*      READ LINE SUBROUTINE
*--------------------------------
READ.LINE
       JSR GET.HORIZ.POSN
       TAX          TEST FOR POSITION=0
       BEQ RDL1     DON'T OUTPUT CRLF
RDL0   JSR CRLF
RDL1   LDA PROMPT.FLAG
       JSR CHO      NULL, "I", OR "H"
       LDA #':'     COLON PROMPT
       JSR CHO
       LDX #0       START NEW LINE
       STX WBUF     CLEAR OUT "$" FROM COL. 1 (JUST IN CASE)
       BIT AUTOLN.FLAG    SEE IF IN "AUTO" MODE
       BMI TAB           ...YES
RDL3   JSR READ.KEY.WITH.CASE
       BCS RDL.ESCAPE.2E
       LDY WBUF     SEE IF IN $ OR " MODE
       CPY #$A2     "?
       BEQ .2
       CPY #$A4     $?
       BEQ .2
       CMP TAB.CHAR <<ALLOW TAB.CHAR TO BE NON-CTRL
       BEQ TAB
       LDY #CHARS.FOR.READ.LINE.1
       .HS 2C
.2     LDY #CHARS.FOR.READ.LINE.2
       CMP #CHR.BLANK    SEE IF CONTROL CHAR
       BCS RDL.ADD.CHAR     NO
       STA CURRENT.CHAR
       JMP SEARCH.CHAR.TABLES
*--------------------------------
RDL.ERR
       JSR MON.BELL  ALARM IF NOT ONE OF THE ABOVE
       JMP RDL3      AND IGNORE IT
*--------------------------------
RDL.OVERRIDE
       JSR READ.KEY.WITH.CASE
       JMP RDL.ADD.CHAR
*--------------------------------
RDL.RITARR
       JSR GET.HORIZ.POSN
       TAY
       JSR IO.PICK.SCREEN
RDL.ADD.CHAR
       JSR INSTALL.CHAR 
       BCC RDL3     STILL ROOM FOR MORE
RDL.RUBOUT
       LDA #CHR.BSLASH
       JSR MON.COUT
       JMP READ.LINE
*--------------------------------
RDL.BACKSPACE
       LDA #$88
       JSR MON.COUT PRINT BACKSPACE
       TXA          SEE IF OVER PROMPT
       BEQ RDL0     YES, START NEW LINE
       DEX          NO, BACK UP BUFFER POINTER
       JMP RDL3
*--------------------------------
RDL.PREFIX  LDY #QM.PREFIX-QM.
            .HS 2C
RDL.CATALOG LDY #QM.CATALOG-QM.
            .HS 2C
RDL.LIST    LDY #QM.LIST-QM.
            .HS 2C
RDL.FIND    LDY #QM.FIND-QM.
            .HS 2C
RDL.EDIT    LDY #QM.EDIT-QM.
*
       CPX #0       ^C & ^E ONLY EFFECTIVE IN COL. 1
       BNE RDL.ERR  ...ELSE ERRONEOUS
.1     LDA QM.,Y    SPELL OUT "EDIT " OR "CATALOG"
       PHP          SAVE TERMINATION STATUS
       JSR INSTALL.CHAR
       INY
       PLP          GET TERMINATION STATUS
       BPL .1       ...NOT FINISHED YET
       JMP RDL3
*--------------------------------
*      HANDLE ESCAPE EDITING
*--------------------------------
RDL.ESCAPE
       JSR READ.KEY.WITH.CASE
RDL.ESCAPE.2E
       JSR ELIMINATE.CASE
       STA CURRENT.CHAR
       LDY #CHARS.FOR.ESCAPE
       JSR SEARCH.CHAR.TABLES
       LDA CURRENT.CHAR
       CMP #"L"     STAR DASH LINE?
       BEQ RDL.EOL  ...YES, FINISH IT OFF
       CMP #$A0     CHECK FOR ARROW KEYS (//E)
       BCC RDL.ESCAPE     ...YES, STAY IN ESCAPE MODE
       CMP #$C9     IJKM?
       BCC RDL4     ...NO, LEAVE ESCAPE MODE
       CMP #$CE
       BCC RDL.ESCAPE      ...YES, STAY IN ESCAPE MODE
       BCS RDL4     ...NO, LEAVE ESCAPE MODE
RDL.ESC.END
       PLA
       PLA
RDL4   JMP RDL3
*--------------------------------
RDL.EOL
       JSR IO.CLREOL
       LDA #CHR.RETURN
       STA WBUF,X
       JSR MY.COUT
       LDY #0
       STY MON.MODE
       INY
       LDA WBUF     GET FIRST CHAR
       CMP #CHR.DOLLAR
       BEQ FAKE.MONITOR
       JMP RDL.STRIP.LINE
*--------------------------------
*      FAKE MONITOR
*--------------------------------
FMN1   CPX $FBC0    //C ID BYTE (X = 0 OR 1)
       BCC .1       ...NOT //C  (//C = 0, OTHERS > 1)
       DEY
       BMI FMN3     ...NOT VALID COMMAND
       CPY #$13
       BCS FMN2
.1     JSR MON.TOSUB
       LDY MON.YSAV
FAKE.MONITOR
       JSR FMN5     INDIRECT TO MON.GETNUM
       STY MON.YSAV
       CMP #$C6     $8D EOR $B0 PLUS $89
       BEQ FMN4     ...<RETURN>
       LDY #22      # CMDS - 1
FMN2   CMP MON.CHRTBL,Y
       BEQ FMN1     ...FOUND CMD IN TABLE
       DEY          ...NEXT ENTRY
       BPL FMN2     ...NEXT ENTRY
FMN3   JSR MON.BELL ...NOT IN TABLE
       JMP READ.LINE
FMN4   LDA MON.MODE <RETURN> COMMAND
       LDY #0
       DEC MON.YSAV
       JSR MON.BL1
       JMP READ.LINE
FMN5   JMP ($FF74)  MON.GETNUM CALL
*--------------------------------
*      ESCAPE-L
*          COLUMN 0:  LOAD A FILE
*          COL. 1-N:  MAKE "*------" LINE
*--------------------------------
ESCAPE.L
       TXA
       BEQ .3       "LOAD ...."
*---GENERATE STAR-DASH LINE------
       LDA #CHR.STAR
.1     JSR INSTALL.CHAR
       LDA USER.COM.DELIM
       CPX #38
       BCC .1
.2     RTS
*---GENERATE LOAD COMMAND--------
.3     JSR IO.HTABX      HTAB TO FIRST COLUMN
       LDY #QBLOADB " LOAD "
       JSR QT.OUT
       LDX #22
       JSR IO.HTABX
       JSR GET.DOS.CMD.OFF.SCRN
       PLA          POP RETURN ADDRESS
       PLA
       JMP RDL.EOL  SUBMIT COMMAND
*--------------------------------
*   ESC-S   AUTO SAVE LINE
*--------------------------------
ESCAPE.S
       TXA
       BNE .4       ...NOT IN COLUMN 1
       JSR SETUP.TEXT.POINTERS
       LDX #10      MUST APPEAR IN FIRST 10 LINES
.1     LDY #3       POINT TO FIRST TEXT CHAR OF LINE
       LDA (SRCP),Y
       JSR CHECK.COMMENT.CHAR
       BEQ .5
.2     DEX          PAST 10TH LINE?
       BMI .4       ...YES, LOOK NO FURTHER
       LDY #0       POINT TO LENGTH
       LDA (SRCP),Y
       CLC
       ADC SRCP
       STA SRCP
       BCC .3
       INC SRCP+1
.3     JSR CMP.SRCP.ENDP   PAST END OF PROGRAM?
       BCC .1              ...NO, KEEP LOOKING
.4     RTS
.5     INY
       LDA (SRCP),Y
       BEQ .2       ...END OF LINE
       CMP #'S'
       BNE .5
       JSR LIST.CURRENT.LINE
*--------------------------------
GET.DOS.CMD.OFF.SCRN
       JSR IO.CLREOL
       LDY #0       NOW PICK 0...39 OFF SCREEN
       LDX #0       BUT NO BLANKS
.1     JSR IO.PICK.SCREEN
       STA WBUF,X   STORE IN BUFFER
       INY
       CMP #" "     ELIMINATE BLANKS
       BEQ .2       ...BLANK
       INX
.2     CPY #39
       BCC .1
.3     DEY
       JSR IO.PICK.SCREEN
       CMP #" "
       BEQ .3
       INY
       TYA
       JMP IO.HTAB  POSITION AFTER LAST NON-BLANK
*--------------------------------
*      INSTALL CHARACTER IN INPUT BUFFER
*--------------------------------
INSTALL.CHAR
       ORA #$80     ASSURE SIGN BIT ON
       STA WBUF,X   STORE IN INPUT BUFFER
       CMP #$A0     CONTROL CHAR?
       BCS .1       ...NO
       AND #$3F     ...YES, DISPLAY AS INVERSE
.1     JSR IO.COUT  ECHO ON SCREEN
       CPX #WBUF.MAX SEE IF END OF BUFFER
       BCS .2       ...YES
       INX
       RTS
.2     JSR MON.BELL
       SEC
       RTS
*--------------------------------
*      STRIP SIGN BITS OFF ALL BYTES
*      AND CHANGE <CR> TO <EOL>
*--------------------------------
RDL.STRIP.LINE
       LDY #$FF     LOOP TO CLEAR HIGH BITS
.1     INY
       LDA WBUF,Y
       AND #$7F     STRIP OFF BIT
       CMP #$0D     WAS IT THE END?
       BNE .2       NOT YET
       LDA #0       YES, SUBSTITUTE <EOL> FOR <CR>
.2     STA WBUF,Y
       BNE .1       UNTIL <EOL>
       TAX          CLEAR X-REG
       RTS
*--------------------------------
ESCAPE.DOT
       TXA
       BNE .5       NOT IN COLUMN 1, IGNORE IT
       JSR GET.HORIZ.POSN  FIND CURSOR POSITION
       TAY
.1     JSR IO.PICK.SCREEN
       AND #$7F
       JSR CHECK.DIGIT
       BCC .2       NOT A DIGIT
       STA WBUF+4,X
       INX
       INY
       BNE .1       ...ALWAYS
.2     TXA
       BEQ .3       ...NO DIGITS
       LDA #4
       STA CHAR.PNTR
       STA WBUF+4,X
       LDX #CURLNO-A0L
       JSR SCAN.1.DECIMAL.NUMBER
.3     LDY #4
       LDX #0
.4     LDA LDC,Y
       JSR INSTALL.CHAR
       DEY
       BPL .4
       STA CURRENT.CHAR  at end, current.char = comma
       JSR IO.CLREOP
.5     RTS
*--------------------------------
LDC    .AS /,.SIL/
*--------------------------------
QM.
QM.EDIT    .AT /EDIT /
QM.CATALOG .AT /CATALOG/
QM.PREFIX  .AT /PREFIX/
QM.LIST    .AT /LIST /
QM.FIND    .AT /FIND /
*--------------------------------------
MAN
SAVE usr/src/scmasm.31/scmasm.s.rline
LOAD usr/src/scmasm.31/scmasm.s
ASM
