; THIS FILE HAS BEEN STRIPPED TO LEAVE ONLY THE SOURCE THAT PRODUCES
; THE CODE THAT MATCHES THE SHEPARDSON ASSEMBLER/EDITOR CARTRIDGE.
; ALL DEBUG, APPLE, & MATHPACK CODE HAS BEEN REMOVED.
;                                                MIKE LORENZEN
;
;
       .TITLE 'SHEPARDSON ATARI EDITOR - 2/3/81- TANDEM JUN 11,81  (ML)'
;     .LIST X
;       5.6     12-10-79
;       PROGRAMMER KATHY O'BRIEN
;       8 BIT ASSEMBLER
;
;******************************************************************************
;       (C) COPYRIGHT 1978 SHEPARDSON MICROSYSTEMS, INC.
;******************************************************************************
;
DEFRA   MACRO   LABEL
        .BYTE   $C0+(LABEL-*)
        ENDM
;
CVAFP   =       $D800
AFP     =       $D800
FASC    =       $D8E6
IFP     =       $D9AA
FPI     =       $D9D2
INTLBF  =       $DA51
ILSHFT  =       $DA5A
SKPBLK  =       $DBA1
TSTNUM  =       $DBAF
;
;                                 ATARI VERSION
ZICB    =       $20             ; ZERO PAGE IOCB
ZPG1    =       $80
ZPG2    =       $E6
ZPG3    =       $FB
MISCRAM =       $500
RAM2    =       $480
CIO     =       $E456
SETBVB  =       $E45C
XITVBV  =       $E462
IOCBORG =       $340
DCBORG  =       $300
ROM     =       $A000
ZFP     =       $D2
CR      =       $9B
TC      =       $7F
BELL    =       $FD
LMADR   =       $2E7
HMADR   =       $2E5
FPORG   =       $D800
BRKVEC  =       $206
BRKBYT  =       $11
WARMFLG =       $08
DOSLOC  =       $0A
BYELOC  =       $E471
DSPFLG  =       $2FE            ; ATARI DISPLAY FLAG
SKCTL   =       $D20F           ; AUDIO
CRTGI   =       $BFFC-3         ; CART END ADDR
APHM    =       $E              ; APPLICATION HI MEM
;
        .PAGE 'ZERO PAGE'
;
; RAM TABLE POINTERS - MUST BE IN ZERO PAGE
;
        *=ZPG1
LOMEM                           ; LOW MEMORY POINTER
OUTBUFF *=*+2                   ; SYNTAX OUTPUT BUFFER
EXBUFF                          ; EXECUTION BUFFER
OBJBUF  *=*+2                   ; OBJECT BUFFER
OBJEND                          ; END JOB, SET BUFFER
TXTTAB  *=*+2                   ; TEXT TABLE POINTER
STMCUR  *=*+2                   ; CURRENT PGM PTR
TXTEND                          ; END OF TEXT
SMBLTP  *=*+2                   ; SYMBOL TABLE POINTER
SMBLEND *=*+2                   ; SYMBOL TABLE END
SMBLD                           ; SYMBOL TABLE DUMMY END
TITLEP  *=*+2                   ; TITLE BUFFER POINTER
TITLEND                         ; END OF TITLE BUFFER
PAGEP   *=*+2                   ; PAGE BUFFER POINTER
PAGEND                          ; END OF PAGE BUFFER
MEMTOP  *=*+2                   ; TOP OF USED MEMORY
;
;
HIMEM   =       HMADR           ; HIGHEST AVAIABLE MEMORY ADDR (+1)
        .PAGE
;
;       MISC ZERO PAGE RAM
;               USED FOR FREQUENCY USED VALUES
;               TO DECREASE ROM SIZE AND INCREASE
;               EXECUTION SPEED.  ALSO USED FOR VARIOUS
;               INDIRECT ADDRESS POINTERS.
;
COX     *=*+1                   ; CURRENT OUTPUT INDEX
PTBUFF                          ; PAGE/TITLE BUFFER PTR
MSGADR
SRCADR  *=*+2                   ; SEARCH ADR
CSADR                           ; CHANGE START ADDR
SVESA   *=*+2                   ; SAVE EXPAND START ADR
LEADR                           ; LIST END ADDR
CPC     *=*+2                   ; CUR SYNTAX PGM COUNTER
OBJDEX                          ; OBJECT BUFFER INDEX
AQ1FLG                          ; ALL QUERRY 1ST FLAG
MAXCIX  *=*+1                   ; MAX SYNTAX CIX
DSADR                           ; DISPLAY START ADDR
TSLNUM  *=*+2                   ;TEST LINE NO
LSADR                           ; LIST START ADDR
MVLNG   *=*+2                   ; MOVE LENGTH
MVFEA                           ; MOVE FROM END ADDR
ECSIZE  *=*+2                   ; MOVE SIZE
STR1LNG                         ; STRING 1 LENGTH
STKLVL  *=*+1                   ; SYNTAX STACK LEVEL
WORDFLG                         ;WORD/DBYTE FLAG
OLBCNT                          ; # BYTES OF OBJECT PER LINE
ERRNUM                          ; SAVED ERROR #
LINLNG                          ; LINE LENGTH
SRCCNT                          ; # BYTES TO SEARCH
SRCSKP  *=*+1                   ; SEARCH SKP FACTOR
COPTR                           ; CURRENT ORG POINTER
RTNADR                          ; RETURN ADDR FROM STEP
CURLN                           ; CURLN FOR AUTO
DEADR                           ; DISPLAY END ADDR
LELNUM  *=*+2                   ; LIST END LINE #
;  NEXT SEVEN BYTES MUST STAY TOGETHER
LOMFLG  *=*+1                   ; LOW MEM VALID FLAG
PASSFLG *=*+1                   ; PASS FLAF FOR ASM
AUTOFLG *=*+1                   ; AUTO LINE # FLAG
MODEFLG *=*+1                   ; MODEFLAG
ERRDEX  *=*+1                   ; ERROR BUFFER INDEX
ENTDTD  *=*+1                   ; ENTER DEVICE TB
LISTDTD *=*+1                   ; LIST DEIVCE TBL
LNINCR                          ; INCR FOR AUTO
UPC     *=*+2                   ; USER P.C.
;
LOCCNT  *=*+2                   ; LOCATION COUNTER
;
NULFLG                          ; USED AS TEMP IN STRING SYNTAX
ZT1     *=*+1                   ; LOCAL TEMPS
;
;
;       MISC PRINT FLAG
;
        *=ZPG2                  ; DOUBLE USE FR2
MVFA    *=*+2                   ; MOVE FROM ADR
MVTA    *=*+2                   ; MOVE TO ADR
        *=ZPG3
;
;********   POISON - DO NOT USE     ********
DEGFLG
RADFLG  *=*+1
;
SVCIX                           ; SAVE CIX FOR IF
PRCNT   *=*+1                   ;# CHARS TO PRINT
OUTCNT                          ; # OF BYTES MOVED
BLKCNT  *=*+1                   ; # OF BLANKS TO PRINT
TOBJDEX *=*+1                   ; TEMPORARY OBJECT INDEX
SVLENG  *=*+1                   ; SAVED STRING LENGTH FOR IF
        .PAGE
        *=ZFP-2
STOP                            ; SAVE TRIAL OP
TABCNT                          ;INDEX TO WHICH TAB
PTDEX                           ; INDEX FOR TITLE/PAGE BUFFER
TPCIX                           ; CIX FOR PRINUM
TVSCIX                          ; SAVE CIX FOR TVAT
TSCOX   *=*+1                   ; TSCOW LENGTH BYTE PTR
RESBYT                          ; RESOLVED BYTE
LTYPFLG
STRDEL
STENUM  *=*+1                   ; SEARCH TABLE ENTRY NUMBER
DISFLG                          ; DISASM CONTROL FLAG
LINDEX                          ; LINE INDEX
STMSTRT *=*+1                   ; STMT START CIX
REPFLG                          ; REPLACE FIND FLAG
OBJDTD  *=*+1                   ;OBJECT DEVICE #
        .PAGE    'FLOATING POINT WORK AREA'
;
;       FLOATING POINT WORK AREA
;
        *=ZFP+2
FPREC   =       6
FMPREC  =       FPREC-1         ; LENGTH OF FLOATING POINT MANTISSA
;
BININT                          ; FP REGO
FR0     *=*+1                   ; FP REG0
FR0M    *=*+FPREC-1             ; FP REG0MANT
FR0EX   =       FR0+2
FRE     *=*+FPREC               ; FP REG0 EXP
FR1     *=*+1                   ; FP REG 1
FR1M    *=*+FPREC-1             ; FP REG1 MANT
FR2     *=*+FPREC               ; FP REG 2
FRX     *=*+1                   ; FP SPARE
;
;       RMB FOR ASCII TO FLOATING POINT CONVERSION
;
EEXP    *=*+1                   ; VALUE OF E
FRSIGN
NSIGN   *=*+1                   ; SIGN OF #
SQRCNT
PLYCNT
ESIGN   *=*+1                   ; SIGN OF EXPONENT
SGNFLG
FCHRFLG *=*+1                   ; 1ST CHAR FLAG
XFMFLG
DIGRT   *=*+1                   ; # OF DIGITS RIGHT OF DECIMAL
;
;       INPUT BUFFER
;
CIX     *=*+1                   ; CURRENT INPUT INDEX
INBUFF  *=*+2                   ; LINE INPUT BUFFER
;
;
;
ZTEMP1  *=*+2                   ; LOW LEVEL ZERO PAGE TEMPS
ZTEMP4  *=*+2                   ; X
ZTEMP3  *=*+2                   ; X
        .PAGE    'MISC NON-ZERO PAGE RAM'
;
;       MISC NON-ZERO PAGE RAM
;               USED FOR VALUES NOT ACCESSED FREQUENTLY
        *=MISCRAM
SSTACK  =*                      ; SYNTAX STACK
SIX     *=*+1                   ; INPUT INDEX
SOX     *=*+1                   ; OUTPUT INDEX
SPC     *=*+2                   ; PGM COUNTER
        *=SSTACK+126
LBPR1   *=*+1                   ; LBUFF PREFIX 1
LBPR2   *=*+1                   ; BLUFF PREFIX 2
LBUFF   *=*+128                 ; LINE BUFFER
;
        .PAGE
;
;       RAM
;
        *=RAM2
;
; USER-ACCESSIBLE FLAGS
;
LINESPERPAGE
        *=*+1                   ; SET TO DEFAULT BY COLDSTART
FFOK    *=*+1                   ; DEFAULT: FF NOT OK
;
FNBUFF  *=*+20                  ; FILE NAME BUFFER
ERRCNT  *=*+1                   ; HOW MANY, DURING ASM
TAB1    *=*+1                   ; TAB 1 FOR ASSM LISTING
ILEN                            ; INSTRUCTION LENGTH
TAB2                            ; TAB 2 FOR ASM LISTING
STRDEX  *=*+1                   ; INDEX INTO STRING1
PMASK                           ; PRINT MASK
TAB3    *=*+1                   ; TAB 3 FOR ASM LISTING
LNCNT   *=*+1                   ; LINE COUNT FOR ASM + DISASM
EOFFLG  *=*+1                   ; EOF FLAG
IOCMD   *=*+1                   ; I/O COMMAND
IODVC   *=*+1                   ; I/O DEVICE
;
ERRBUF  *=*+3                   ; ERROR BUFFER
;
LMSAV   *=*+2                   ; LOMEM SAVE AREA
;
TEMPRL                          ; TEMPORARY RECORD LENGTH FOR POINT
UREG    *=*+5                   ; USER REGISTER
URA     =       UREG            ;
URX     =       UREG+1
URY     =       UREG+2
URP     =       UREG+3
URS     =       UREG+4
;       ASM FIELDS
;
STR2LNG                         ; STRING 2 LENGTH
IDISPL  *=*+1                   ; DISPL TO START OF INSTRUCTION
ADISPL  *=*+1                   ; DISPL TO ADDR
CDISPL  *=*+1                   ; DISPL TO COMMENT
OPTFLG  *=*+1                   ; OPTION FLAG
POX     *=*+1                   ; PRINT OUTPUT INDEX
ZT2     *=*+1
        .PAGE    'IOCB AREA'
        *=IOCBORG
;
;       IOCB - I/O CONTROL BLOCK
;               THERE ARE 8 I/O CONTROL BLOCKS
;               1 IOCB IS REQUIRED FOR EACH
;               CURRENTLY OPEN DEVICE OF FILE.
;
IOCB
ICHID   *=*+1                   ; DEVICE HANDLER ID
ICDNO   *=*+1                   ; DEVICE NUMBER
ICCOM   *=*+1                   ; I/O COMMAND
ICSTA   *=*+1                   ; I/O STATUS
ICBAL   *=*+1
ICBAH   *=*+1                   ; BUFFER ADR (H,L)
ICPUT   *=*+2                   ; PUT ADDR
ICBLL   *=*+1
ICBLH   *=*+1                   ; BUFFER LENGTH (H,L)
ICAUX1  *=*+1                   ; AUXILLIARY 1
ICAUX2  *=*+1                   ; AUXILLIARY 2
ICAUX3  *=*+1                   ; AUXILLARY 3
ICAUX4  *=*+1                   ; AUXILLARY 4
ICAUX5  *=*+1                   ; AUX 5
        *=*+1                   ; SPARE
ICLEN   =       *-IOCB
;
        *=*+ICLEN*7             ; SPACE FOR 7 MORE IOCBS
;
;       ICCOM VALUE EQUATES
;
ICOIN   =       $01             ; OPEN INPUT
ICOOUT  =       $02             ; OPEN OUTPUT
ICOIO   =       $03             ; OPEN UN/OUT
ICGBR   =       $04             ; GET BINARY RECORD
ICGTR   =       $05             ; GET TEXT RECORDS
ICGBC   =       $06             ; GET BINARY CHAR
ICGTC   =       $07             ; GET TEXT CHAR
ICPBR   =       $08             ; PUT BINARY RECORD
ICPTR   =       $09             ; PUT TEXT RECORD
ICPBC   =       $0A             ; PUT BINARY CHAR
ICPTC   =       $0B             ; PUT TEXT CHAR
ICCLOSE =       $0C             ; CLOSE FILE
ICSTAT  =       $0D             ; GET STATUS
ICDDC   =       $0E             ; DEVICE DEPENDENT
ICMAX   =       $0E             ; MAX VALUE
ICFREE  =       $FF             ; IOCB FREE INDICATOR
;
;       ICSTA VALUE EQUATES
;
ICSOK   =       $01             ; STATUS GOOD, NO ERRORS
ICSTR   =       $02             ; TRUNCATED RECORD
ICSEOF  =       $03             ; END OF FILE
ICSBRK  =       $80             ; BREAK KEY ABORT
ICSDNR  =       $81             ; DEVICE NOT READY
ICSNED  =       $82             ; NON-EXISTENT DEVICE
ICSDER  =       $83             ; DATA ERROR
ICSIVC  =       $84             ; INVALID COMMAND
ICSNOP  =       $85             ; DEVICE/FILE NOT OPEN
ICSIVN  =       $86             ; INVALID IOCB NUMBER
ICSWPE  =       $87             ; WRITE PROTECTION
PTCMD   =       $25             ; POINT COMMAND
NTCMD   =       $26             ; NOTE COMMAND
        .PAGE
;
;       MISC EQUATES
;
KWSTRT  =       $08             ; 1ST KW TOKEN -1
PEJECT  =       $0C             ; PAGE EJECT CHAR
DELIM   =       $3C             ; DELIMITER FOR DEBUG
LCHK1   =       $FF             ; LOAD CHECK CHAR 1
LCHK2   =       $FF             ; LOAD CHECK CHAR 2
;
;       MODEFLAG
EMODE   =       0               ; DEIT MODE INDICATOR
DMODE   =       1               ; DEBUG MODE
AMODE   =       -1              ; ASM MODE
MAMODE  =       $80             ; MINI-ASM MODE
;       AUTOFLAG
AUTON   =       $80             ; AUTOLINE # ON
AUTOFF  =       0               ; AUTO LINE # OFF
;
;       LIST TYPE FLAG
LNUMON  =       0               ; LIST LINE NUMBERS
LNUMOFF =       $80             ; DO NOT LIST LINE NUMBERS
;
;       PASS FLAG/LABEL DEFINE BYTE
;
PASS1   =       $80             ; THIS IS PASS 1
PASS2   =       $40             ; THIS IS PASS 2
NZ      =       1               ; NOT ZERO PAGE
EQULBL  =       2               ; EQUATE TYPE LABEL
;
;       OPTION FLAG
;
OLIST   =       $80             ; NO GENERATE LISTING
OOBJ    =       $40             ; NO GENERATE OBJECT
OERR    =       $20             ; NO GENERATE ERROR MESSAGE
OPAGE   =       $01             ; NO PAGE AFTER 56 LINES
;
;       DEVICE EQUATES
;
SCRDV   =       0               ; SCREEN
LISDV   =       1               ; LIST
OBJDV   =       2               ; OBJECT
LOADDV  =       3               ; LOAD
TXTDV   =       3               ; TEXT SOURCE
;
;       AQ1FLG - (ALL QUERRY,1)
;
SETA    =       1               ; FIND (REPLACE) ALL OCCURENCES
SETQ    =       -1              ; QUERRY USED ON EACH OCCURENCE
SET1    =       0               ; FIND (REPLACE) 1ST OCCURENCE
;
;       REPFLG - REPLACE/FIND
;
REPON   =       $80             ; DO REPLACE
FINDON  =       0               ; DO FIND
;
;       REPLACE QUERRY RESPONCE
;
CDO     =       $59             ; DO REPLACE
CNODO   =       CR              ; DON'T DO REPLACE
;
;       MOVE TYPE FLAG/DISASM FLAG
;
ADDRON  =       0               ; ADDR TYPE
FILEON  =       $80             ; FILE TYPE
CNTON   =       $80             ; CONTROL BY COUNT
;
;       WORDFLG - WORD/DBYTE
;
WORDON  =       $0
DBYTEON =       $80
;
;       OLBCNT
;
TWOBYTE =       2
ONEBYTE =       1
THRBYTE =       3
;
PLST    =       12              ; START OF PRINT OF EMPTY LINE
        .PAGE
;
;       SPECIAL TOKEN EQU
;
THEX2   =       $01             ; 2 BYTE HEX # OR ADDR
TSTR    =       $02             ; STRING
TSOE    =       $03             ; START OF EXPRESSION
TEOE    =       $04             ; END OF EXPRESSION
TLBL    =       $01             ; LABEL
TNLBL   =       $00             ; NO LABEL
TCOMM   =       $00             ; COMMENT CODE
TDIR    =       $01             ; DIRECTIVE
TIMP    =       $02             ; IMPLIED ADDR INST.
TREL    =       $03             ; RELATIVE ADDR INST.
TMISC   =       $04             ; MISC INST.
TMULTI  =       $05             ; MULTI ADDR INST.
TMACRO  =       $06             ; MACRO
;
;       ADDRESSING MODES
;
TINDX   =       $00
TINDY   =       $01
TIMM    =       $02
TACU    =       $03
TZPG    =       $04
TZPGY   =       $05
TZPGX   =       $06
TABS    =       $07
TABSY   =       $08
TABSX   =       $09
        .PAGE
;
;       ERROR MESSAGE NUMBERS
;
MEMFULL =       1               ; MEMORY FULL - ABORT IF IN ASM
ERNLN   =       2               ; 1ST LINE IN DELETE RANGE NOT FOUND
ERMSYN  =       3               ; ERROR IN MINI ASSM ADDR
ERLOAD  =       4               ; FILE NOT A LOADABLE FILE
ERNDEF  =       5               ; UNDIFINED REFERENCE
ERASYN  =       6               ; ASSEMBLER SYNTAX ERROR
ERDUP   =       7               ; DUP LABEL
EROVR   =       8               ; BUFFER OVERFLOW
EREQU   =       9               ; EQU HAS NO LABEL
ERVAL   =       10              ; VALUE OF EXPRESSION > 255
ERNSTR  =       11              ; NULL STRING
ERADR   =       12              ; INVALID ADDRESS OR ADDRESS TYPE
ERPHAS  =       13              ; PHASE ERROR
ERUFR   =       14              ; UNDEFINED FORWARD REFERENCE (*=) - ABORT
ERLBIG  =       15              ; LINE TOO BIG
ERGARB  =       16              ; INPUT TO ASSM IS GARABAGE
ERLNUM  =       17              ; LINE # TO BIG
ERLMEM  =       18              ; LOW MEM COMMAND VALID AS 1ST COMMAND ONLY
ERNORG  =       19              ; NO ORG GIVEN
EROVFL  =       20              ; OVERFLOW ON NUMBER FOR NUM OR RENUM
        .PAGE    'ROM START'
;
;       START OF ROM CODE
;
        *=ROM
        .PAGE    'COLD START'
;
;       COLD START - REINITIZES ALL MEMORY
;                    WIPES OUT ANY EXISTING PROGRAM
COLDSTART
        LDA     WARMFLG         ; IF WARMSTART
        BNE     WARMSTART       ; THEN BR
        LDX     #$FF            ;GET STACK VALUE
        TXS                     ; SET STACK
        CLD                     ; CLEAR DECIMAL MODE
        JSR     CLRMEM
;
;
        LDA     #0
        LDX     #6              ; SET SEVERAL FLAGS TO ZERO
_CLFLG
        STA     LOMFLG,X
        DEX
        BPL     _CLFLG
;
        STA     FFOK            ; USE "STX FFOK" TO CHANGE DEFAULT
        LDA     #59             ; DEFAULT LINES PER PAGE
        STA     LINESPERPAGE
;
        .PAGE 'WARM START'
;
;       WARMSTART - BASIC RESTART
;                   DOES NOT DESTROY CURRENT PGM
WARMSTART
        CLD                     ; CLEAR DECIMAL MODE
        .PAGE    'ESYNTAX'
;
;       ESYNTAX - SYNTAX ONE LINE FOR EDITOR
;
ESYN2
        LDA     #3              ; RESET AUDIO
        STA     SKCTL
        JSR     PRCR
        LDX     #.LOW.EDMSG     ; PRINT READY MESSAGE
        LDY     #.HIGH.EDMSG
        JSR     MSGXYCR
ESYNTAX
        LDX     #$FF
        TXS
        JSR     SYNINIT         ; DO GENERAL SYNTAX INIT
        BNE     ESYNTAX         ; BR IF BREAK
;
        JSR     _GETLNUM        ; GET LINE #
        BCS     ECOM            ; NO #, IT'S A COMMAND
        JMP     ETXT            ; PROCESS TEXT
;
ECOM
        JSR     SKPBLK        ; SKIP BKANKS
        LDY     CIX             ; GET INDEX
        STY     STMSTRT         ; SAVE IN CASE OF SYNTAX ERROR
;
        JSR     KWSRCH          ; SEARCH KWTAB
;
        CPX     #6              ; IS IT AN EDITOR COMMAND
        BNE     _ESERR          ; IF NOT, ERROR
        JSR     COMSYN          ; SYNTAX
        BCS     _ESERR          ; BR IF ERR
;
;
        JSR     COMEXEC
        LDA     #$80            ; SET LOMEM NOT VALID COMMAND
        STA     LOMFLG          ; X
        JMP     ESYN2
;
;
;
EDMSG
        .BYTE    'EDI',$80+'T'
        .PAGE    'DSYNTAX'
;
;       DSYNTAX - SYNTAX ONE LINE FOR DEBUG
;
DSYN2
        JSR     PRCR
        LDX     #.LOW.BUGMSG    ; PUT OUT READY
        LDY     #.HIGH.BUGMSG
        JSR     MSGXYCR
DSYNTAX
        JSR     SYNINIT         ; DO SYNTAX INIT
        BNE     DSYNTAX
;
        LDY     CIX             ; GET INPUT LINE INDEX
        STY     STMSTRT         ; SAVE IN CASE OF SYNTAX ERROR
;
        JSR     KWSRCH          ; SEARCH FOR COMMAND
;
        CPX     #7              ; IS IT DEBUG COMMAND
        BNE     _DSERR          ; IF NOT, ERROR
;
        JSR     COMSYN          ; SYNTAX COMMAND
        BCS     _DSERR
;
;       EXECUTE COMMAND
;
        JSR     COMEXEC
        JMP     DSYN2
;
;
;
BUGMSG
        .BYTE    'DEBU',$80+'G'
        .PAGE
;
;       COMSYN - COMMON SYNTAXING FOR EDITOR AND DEBUG
;
;
COMSYN
        JSR     SKPBLK
;
;       GET SYNTAX TABLE ADDR
;
        LDA     STENUM          ; GET EDITOR COMMAND #
        ASLA                    ; MULT BY 2
        TAY                     ; PUT IN Y AS INDEX
        PHA                     ; SAVE
        LDA     ESTBL-CSEDIT-CSEDIT,Y     ; GET SYNTAX TABLE ADDR LOW
        LDX     ESTBL-CSEDIT-CSEDIT+1,Y   ; ADDR HI
;
        JSR     _SYNENT         ; DO BASIC SYNTAX
        PLA                     ; GET INDEX
        RTS
_ESERR
        JSR     WHAT            ; PRINT WHAT?
        JMP     ESYN2
_DSERR
        JSR     WHAT            ; PRINT WHAT?
        JMP     DSYN2
;
;
;
;
;       WHAT - PRINT WHAT? MESSAGE
;
WHAT
        LDA     #BELL           ; PUT OUT BELL
        JSR     PRCHAR
        LDX     #.LOW.WHTMSG
        LDY     #.HIGH.WHTMSG
        JMP     MSGXYCR
;
;
;
WHTMSG
        .BYTE    'WHAT',$80+'?'
        .PAGE
;
;       COMEXEC - EXECUTE COMMAND FOR DEBUG AND EDITOR
;
;       ON ENTRY A - CONTAINS COMMAND # * 2
COMEXEC
;
;       GET EXECUTION ROUTINE ADDR
;
        JSR     _EDUM           ;
;       RETURN HERE FROM COMMAND EXC
        RTS
;
_EDUM
        TAY                     ; GET INDEX
        LDA     EXTBL-CSEDIT-CSEDIT+1,Y  ; X
        PHA                     ; X
        LDA     EXTBL-CSEDIT-CSEDIT,Y  ; GO TO ROUTINE
        PHA                     ; X
        LDY     #0              ; GET ZERO
        STY     COX             ; RESET OUTPUT INDEX
        RTS
        .PAGE    'ASSEMBLER SYNTAX'
;
;       ASYNTAX - SYNTAX LINE FOR ASM
;
;       ON EXIT    CARRY SET - IF SYNTAX ERROR
;                  CARRY CLEAR - IF NOT
;
ASYNTAX
;
;       PROCESS POSSIBLE LABEL
;
        LDY     CIX             ; GET 1ST CHAR
        LDA     (INBUFF),Y      ; X
        CMP     #';             ; IS IT COMMENT CARD
        BEQ     _COMMENT        ; BR IF YES
        CMP     #$20            ; IS IT BLANK
        BEQ     _NOLBL          ; IF YES, NO LABEL
;
        JSR     LBLSRCH         ; GO SEARCH FOR LABEL
        BCS     _ASERR          ; IF INVALID BRANCH
;
        LDY     #2              ; GET DEFINE BYTE
        LDA     (SRCADR),Y      ; X
        PHA                     ; SAVE DEFINE BYTE
        BMI     _DLBL1          ; IF PASS 1 DEFINE BIT ON, BR
;
        LDA     LOCCNT+1        ; SET ADDR IN LABEL TABLE
        DEY                     ; X
        STA     (SRCADR),Y      ; X
        LDA     LOCCNT          ; X
        DEY                     ; X
        STA     (SRCADR),Y      ; X
        JMP     _DLBL3
_DLBL1
;
;       TEST FOR PHASE ERROR
;
        AND     #EQULBL         ;IS THIS AN EQU ?
        BNE     _DLBL3          ;IF YES DO NOT CHECK PHASE
        LDA     LOCCNT+1        ; CURRENT LOCATION COUNTER
        DEY                     ; MUST = TABLE ADDR
        CMP     (SRCADR),Y      ; X
        BNE     _PHERR          ; X
        LDA     LOCCNT          ; X
        DEY                     ; X
        CMP     (SRCADR),Y      ; X
        BEQ     _DLBL3          ; X
;
_PHERR
        LDA     #ERPHAS         ; PHASE ERROR
        JSR     ERROR
;
_DLBL3
        PLA                     ; GET DEFINE BYTE
        PHA                     ; SAVE DEFINE BYTE
        ASLA                    ; SHIFT
        BPL     _DLBL2          ; IF PASS 2 DEFINE BIT OFF, THEN BR
        LDA     #ERDUP          ; PUT ERROR # IN BUFFER
        JSR     ERROR           ; X
_DLBL2
        PLA                     ; GET DEFINE BYTE
        ORA     PASSFLG         ; OR IN PASSFLG
        LDY     #2
        STA     (SRCADR),Y      ; SAVE IN LABEL TABLE
;
;       PUT LABEL CODE & ADDR IN OUTPUT LINE
;
        LDA     #TLBL           ; SET LABEL CODE IN OUTPUT
        JSR     _SETCODE        ; X
        LDA     SRCADR          ; PUT LABEL ADDR IN OUTPUT
        LDX     SRCADR+1
        JSR     _SETC2
        JMP     _ASYN1
;
;
;
;
;
_ASERR
        LDA     #ERASYN
        JSR     ERROR
_COMMENT
        LDY     #3              ; SET LABEL CODE
        LDA     #TCOMM          ; IN OUTPUT BUFFER
        STA     (OUTBUFF),Y     ; X
        SEC
        RTS
_NOLBL
        LDA     #TNLBL          ; GET NO LABEL CODE
        JSR     _SETCODE        ; PUT IN OUTPUT
        INC     COX             ; INCR TO OP CODE DISPL
        INC     COX             ; X
        .PAGE
;
;       SYNTAX OPERATOR
;
_ASYN1
        JSR     SKPBLK        ; SKIP BLANKS
        LDY     CIX
        LDA     (INBUFF),Y
        CMP     #CR             ; IS THIS BLANK LINE OR LABEL ONLY?
        BEQ     _COMMENT
        LDA     CIX             ; SET DISPL TO INST OP
        STA     IDISPL          ; X
;
        JSR     KWSRCH          ; FIND OP
        BCS     _ASERR          ; ERROR IF NOT FOUND
        CPX     #6              ; IS IT ASSM COMMAND?
        BCS     _ASERR          ; IF NOT ERROR
;
        TXA
        JSR     _SETCODE        ; SET TYPE IN OUTPUT
        LDA     STENUM          ; GO SEARSH TABLE ENTRY #
        JSR     _SETCODE        ; PUT IN OUTPUT
        CPX     #TDIR           ; IS IT DIRECTIVE?
        BEQ     _ASYN3
;
;       GET TRIAL OP CODE
;
_ASYN2
        TAY                     ; GET TRIAL OP
        LDA     TOPTBL-CSMNEM,Y ; X
        JSR     _SETCODE        ; SET I OUTPUT
;
_ASYN3
        JSR     SKPBLK        ; SET DIAPL ADDR
        LDY     CIX             ; X
        STY     ADISPL          ; X
;
;       PROCESS ADDR
;
        TXA
        ASLA                    ; GET ROUTINE ADDR
        TAY                     ; BY COMMAND TYPE
        LDA     ASTBL+1,Y       ; X
        PHA
        LDA     ASTBL,Y         ; X
        PHA                     ; X
        RTS                     ; GO TO ROUTINE
        .PAGE
;
;
;       ASMULT - SYNTAX MULTI ADDR TYPE INSTR
;
ASMULT
        LDA     #.LOW._SMULT    ; GET SYNTAX TABLE ADDR
        LDX     #.HIGH._SMULT
;
;
;
;
OPSYN
        JSR     _SYNENT         ; DO BASIC SYNTAX
        BCS     _ASERR
;
;
;
;
;       ASIMP - SYNTAX IMPLIED INSTRUCTION
;
ASIMP
        JSR     SKPBLK        ;SKIP BLANKS
        LDY     CIX             ; SET DISPL TO COMMENT
        STY     CDISPL          ; X
        LDA     #CEOL           ; SET END OF LINE IN OUTPUT
        JSR     _SETCODE        ; X
        RTS
;
;
;
;       ASDIR - SYNTAX ASM DIRECTIVE
;
;       ON ENTRY   SEARCH TABLE ENTRY # IN A
;
ASDIR
        LDA     STENUM          ; GET WHICH DIRECTIVE
        ASLA                    ; SET SYNTAX TABLE
        TAY                     ; ADDR IN
        LDA     ADSTBL-CSDIR-CSDIR,Y ; PROGRAM COUNTER
        LDX     ADSTBL-CSDIR-CSDIR+1,Y
        BNE     OPSYN           ; DO SYNTAX
;
;
;
;
;
;       ASREL - SYNTAX RELATIVE INSTRUCTION
;
ASREL
        LDA     #.LOW._SREL     ; SET SYNTAX ROUTINE ADDR
        LDX     #.HIGH._SREL
;
        BNE     OPSYN           ; DO SYNTAX
;
;
;
;
;       ASMISC - SYNTAX MISCELLANEOUS INSTRUCTION
;
ASMISC
        LDA     STENUM          ; GET SEARCH TABLE ENTRY #
        CMP     #CJSR           ; IS IT JSR
        BEQ     ASREL           ; IF YES, SYNTAX LIKE BR
;
        LDA     #.LOW._SJMP     ; GET SYNTAX TABLE ADDR
        LDX     #.HIGH._SJMP
;
        BNE     OPSYN           ; DO SYNTAX
        .PAGE
;
ETXT
        LDY     CIX             ; GET INDEX
        LDA     (INBUFF),Y      ; GET 1ST CHAR
        CMP     #CR             ; IS IT CR
        BEQ     _DEL            ; IF YES DELETE LINES
;
;
        LDX     AUTOFLG         ; ARE WE IN AUTO?
        BEQ     _ETXT4          ; IF NOT BR
;
        INY                     ; ELSE GET NEXT CHAR
        LDA     (INBUFF),Y      ; X
        CMP     #CR             ; IS IT CR
        BNE     _ETXT4          ; IF NOT BR
;
        LDA     #AUTOFF         ; ELSE TURN OFF AUTO
        STA     AUTOFLG         ; X
        BEQ     _ETXT3          ; AND THUS GET TO 'ESYNTAX'
;
_ETXT4
        JSR     _SETCODE        ; SET DUMMY FOR LENGTH
;
;       MOVE INPUT TO OUTBUFF
;
_ETXT2
        LDY     CIX             ; GET INDEX
        LDA     (INBUFF),Y      ; GET INPUT CHAR
        JSR     _SETCODE        ; PUT IN OUTBUFF
        INC     CIX             ; INCR INDEX
        CMP     #CR             ; WAS CHAR CR?
        BNE     _ETXT2          ; IF NOT, GET NEXT CHAR
;
_SYN4   LDY     #2              ; SET LINE LENGTH
        LDA     COX             ; INTO STMT
        STA     (OUTBUFF),Y
;
;
_SYN5   JSR     GETSTMT         ;GO GET STMT
        LDA     #0
        BCS     _SYN6           ; IF LINE # DOES NOT EXIT, BR
;
_SYN5A
        JSR     GETLL           ;GO GET LINE LENGTH
_SYN6   SEC
        SBC     COX             ;ACU=LENGTH(OLD-NEW)
        BEQ     _SYNIN          ; BR NEW=OLD
        BCS     _SYNCON         ;BR OLD>NEW
;                               ;OLD<NEW
        JSR     EXPTXT          ; EXPAND
        LDA     SVESA           ;RESET STMCUR
        STA     STMCUR
        LDA     SVESA+1
        STA     STMCUR+1
        BNE     _SYNIN
;
_SYNCON PHA     ; CONTRACT LENGTH
        JSR     GNXTL
        PLA
        JSR     CONTXT          ; CONTRACT
;
_SYNIN  LDY     COX             ; STMT LENGTH
_SYN7   DEY                     ; MINUS ONE
        LDA     (OUTBUFF),Y     ; GET BUFF CHAR
        STA     (STMCUR),Y      ;PUT INTO STMT TBL
        TYA                     ; TEST END
        BNE     _SYN7           ; BR IF NOT
        LDA     AUTOFLG         ; ARE WE IN AUTO?
        BEQ     _ETXT3          ; BR IF NOT
        JSR     UPAUTO          ; GO UPDATE NEXT LINE #
_ETXT3
        JMP     ESYNTAX         ; GO FOR NEXT
;
;
;
;
_DEL
_DEL1
        JSR     GETSTMT
        BCS     _ETXT1          ; BR NOT FOUND
        JSR     DELLN           ;DELETE LINE
_ETXT1
        JMP     ESYNTAX         ; GO FOR NEXT LINE
;
;       DELLN - DELETE LINE POINTED TO BY STMCUR
;
DELLN
        JSR     GETLL           ;GET LINE LENGTH
        PHA                     ;SAVE IT
        JSR     GNXTL           ;GET START OF NEXT LINE
        PLA                     ;GET LENGTH
        TAY                     ;PUT IN Y FOR CONTRACT
        LDX     #STMCUR         ;POINT TO ADDR OF START OF CONTRACT
        JMP     CONTLOW         ; CONTRACT TABLE & DELETE
        .PAGE
;
;GETLNUM-GET A LINE NO FROM ASCLT IN INBUFF
;       TO BINARY INTO OUTBUFF
_GETLNUM
        JSR     AFP             ; GO CONVERT LINE #
        BCC     _GLNUM          ; BR IF GOOD LINE #
;
        LDA     #0              ; SET LINE #
        STA     CIX
        RTS                     ; RETURN FAIL
;
_GLNUM  JSR     FPI             ; CONVERT FP TO INT
        BCS     _LERR
        LDY     BININT+1        ; LOAD RESULT
        LDA     BININT
;
_SLNUM
        STY     TSLNUM+1        ; SET LINE # HIGH
        STA     TSLNUM          ; AND LOW
        JMP     _STNUM          ; GO STORE NUMBER
;
_LERR
        LDA     #ERLNUM
        JSR     ERROR
        .PAGE    'SYNTAX'
;
;       SYNINIT - GENERAL SYNTAX INIT
;
;       ON ENTRY   A - PROMPT CHARACTER
;       ON EXIT    CC SET NOT 0 IF BREAK
;
SYNINIT
        JSR     INTLBF          ; INIT INPUT BUFFER
_SYNB
        JSR     GNLINE          ; GET NEXT LINE
        CMP     #$88            ; WAS IT EOF
        BEQ     _SYNB           ; IF YES, GET NEXT LINE
        LDA     #0              ; GET ZERO
        STA     CIX             ; SET INPUT INDEX TO ZERO
        STA     MAXCIX          ; X
        STA     COX             ; SET OUTPUT INDEX TO ZERO
;
_SYNA
        JSR     SKPBLK         ; SKIP BLANK
;
        JMP     TSTBRK          ; TEST FOR BREAK
        .PAGE
;
;       CLRMEM - CLEAR MEMORY
;
CLRMEM
        LDX     LMADR           ; SAVE LOMEM
        STX     LMSAV
        LDX     LMADR+1
        STX     LMSAV+1
XNEW
XCLR
        LDX     LMSAV           ; LOAD LOW
        LDY     LMSAV+1         ; MEM VALUE
        STX     LOMEM           ; SET LOMEM & OUTBUFF
        STY     LOMEM+1
        INY                     ; ALLOW 256 BOR OUTBUFF
        TXA                     ; GET ADDR LOW FOR OTHER INIT'S
;
        LDX     #OBJBUF         ; GET ZPG DISP TO 1ST SLIDING TABLE
        JSR     CLR1            ; INIT TABLE POINTERS
        LDX     #OBJEND         ;EXPAND OBJECT BUFFER
;
        LDX     #OBJEND         ; EXPAND OBJECT BUFFER
        LDY     #128            ; BY 128 BYTES
        JMP     EXPLOW          ; EXPAND
;
;
;
;
;       CLR1 - INIT TABLE POINTERS
;
CLR1
_CS1    STA     0,X             ; SET TABLE ADR LOW
        INX
        STY     0,X             ; SET TABLE ADR HIGH
        INX
        CPX     #MEMTOP+2       ; AT LIMIT
        BCC     _CS1            ; BR IF NOT
        RTS
        .PAGE
;
; SYNENT-PERFORM BASIC SYNTAX
;
_SYNENT
        STX     CPC+1           ; SAVE P.C.
        STX     SPC+1
        STA     CPC
        STA     SPC
        LDA     #0              ;SET STKLUL
        STA     STKLVL          ;SET STKLUL
        LDA     COX             ;MOVE
        STA     SOX             ;COX TO SOX
        LDA     CIX             ;MOVE
        STA     SIX             ;CIX TO SIX
;
;       NEXT - GET NEXT SYNTAX CODE
;              AS LONG AS NOT FAILING
;
_NEXT   =       *
        JSR     _NXSC           ; GET NEXT CODE
;
        BMI     _ERNTV          ; BR IF REL-NON-TERMINAL
;
        CMP     #1              ; TEST CODE=1
        BCC     _GETADR         ; BR CODE=0 (ABS-NON-TERMINAL)
        BNE     _TSTSUC         ; BR CODE >1
;
        JSR     _GETADR         ; CODE=1 (EXTERNAL SUBROUTINE)
        BCC     _NEXT           ; BR IF SUB REPORTS SUCCESS
        BCS     GO_FAIL
;
_TSTSUC CMP     #5              ; TEST CODE = 5
        BCC     _POP            ; CODE = (2,3,OR 4) POP UP TO NEXT STACK LEVEL
;
        JSR     _TERMTST        ; CODE>5 GO TEST TERMINAL
        BCC     _NEXT           ; BR IF SUCCESS
GO_FAIL =       *
        JMP     _FAIL           ; ELSE GO TO FAIL CODE
;
_ERNTV  SEC                     ; RELATIVE NON TERMINAL
        SBC     #$C1
        BCS     _ERN1           ; BR IF RESULT PLUS
        DEX                     ; X = MINUS ONE
_ERN1   CLC
        ADC     CPC             ; RESULT PLUS CPC
        PHA                     ; IS NEW CPC-1
        TXA
        ADC     CPC+1
        PHA                     ; SAVE NEW PC HIGH
        JMP     _PUSH           ; GO PUSH
_GETADR =       *               ; GET DOUBLE BYTE ADR (-1)
        JSR     _NXSC           ; GET NEXT CODE
        PHA                     ; SAVE ON STACK
        JSR     _NXSC           ; GET NEXT CODE
        PHA                     ; SAVE ON STACK
        BCC     _PUSH           ; BR IF CODE =0
        PLA                     ; EXCHANGE TOP
        TAY                     ; 2 ENTRIES ON
        PLA                     ; CPU STACK
        TAX
        TYA
        PHA
        TXA
        PHA
        RTS                     ; ELSE GOTO EXTERNAL SRT VIA RTS
_TBIG
        LDA     #ERLBIG
        JSR     ERROR
        PLA                     ; CLEAR CPU STACK
        PLA
        SEC
        RTS
;
;       PUSH - PUSH TO NEXT STACK LEVEL
;
_PUSH   =       *
        LDX     STKLVL          ; GET STACK LEVEL
        INX                     ; PLUS 4
        INX
        INX
        INX
        BMI     _TBIG           ; IF MINUS, STACK OVERFLOW
        STX     STKLVL          ; SAVE NEW STACK LEVEL
;
        LDA     CIX             ; CIX TO
        STA     SIX,X           ; STACK IX
        LDA     COX             ; COX TO
        STA     SOX,X           ; STACK OX
        LDA     CPC             ; CPC TO
        STA     SPC,X           ; STACK CPC
        LDA     CPC+1
        STA     SPC+1,X
;
        PLA                     ; MOVE STACKED
        STA     CPC+1           ; PC TO CPC
        PLA
        STA     CPC
GO_NEXT =       *
        JMP     _NEXT           ; GO FOR NEXT
;
;       POP - LOAD CPC FORM STACK PC
;             AND DECREMENT TO PREV STACK LEVEL
;
_POP    =       *
        LDX     STKLVL          ; GET STACK LEVEL
        BNE     _POP1           ; BR NOT TOP OF STACK
;
        RTS                     ; TO SYNTAX CALLER
;
_POP1   LDA SPC,X               ; MOVE STACK PC
        STA     CPC             ; TO CURRENT PC
        LDA     SPC+1,X
        STA     CPC+1
;
        DEX                     ; X=X-4
        DEX
        DEX
        DEX
        STX     STKLVL
;
        BCC     GO_NEXT         ; NOT FAILING
;
;       FAIL - TERMINAL FAILED
;              LOOK FOR ALTERNATIVE (OR) OR
;              A RETURN INDICATOR
;
_FAIL   =       *
        JSR     _NXSC           ; GET NEXT CODE
;
        BMI     _FAIL           ; BR IF RNTV
        CMP     #8              ; IS IT SETCODE?
        BEQ     _INC1           ; IF YES, INCR OVER CODE
;
;
        CMP     #2              ; TEST CODE =2
        BCS     _TSTOR          ; BR IF POSSIBLE OR
;
        JSR     _INCCPC         ; CODE = 0 OR 1
_INC1
        JSR     _INCCPC         ; INC PC BY TWO
        BNE     _FAIL           ; AND CONTINUE FAIL PROCESS
;
_TSTOR  CMP     #3              ; TEST CODE=3
        BEQ     _POP            ; BR CODE =3 (RETURN)
        BCS     _FAIL           ; CODE>3 (RNTV) CONTINUE
;
        LDA     CIX             ; IF THIS CIX
        CMP     MAXCIX          ; IS A NEW MAX
        BCC     _SCIX
        STA     MAXCIX          ; THEN SET NEW MAX
_SCIX
        LDX     STKLVL          ; CODE=2 (OR)
        LDA     SIX,X           ; MOVE STACK INDEXES
        STA     CIX             ; TO CURRENT INDEXES
        LDA     SOX,X
        STA     COX
        JMP     _NEXT           ; TRY FOR SUCCESS HERE
        .PAGE
;
;       INCCPC - INC CPC BY ONE
;
_INCCPC =       *
        INC     CPC
        BNE     _ICPCR
        INC     CPC+1
_ICPCR  RTS
;
;
        .PAGE
;
;       _NXSC - GET NEXT SYNTAX CODE
;
_NXSC
        JSR     _INCCPC         ; INC PC
        LDX     #0
        LDA     (CPC,X)         ; GET NEXT CODE
        RTS                     ; RETURN
        .PAGE
;
;       TERMTST - TEST A TERMINAL CODE
;
_TERMTST
        CMP     #_SCODE         ; TEST CODE = SET CODE
        BEQ     _SET            ; IF YES, GO SET CODE IN OUTPUT
        BCS     _SRCONT         ; IF >, THEN MUST BE OPERATOR
;                                 IF <, THEN DO EXPRESSION
        PLA                     ; POP RTN ADR
        PLA
        LDA     #.LOW._EXP-1    ; PUSH EXP ADR
        PHA                     ; FOR SPECIAL
        LDA     #.HIGH._EXP     ; EXP ANTV CALL
        PHA
        JMP     _PUSH           ; GO PUSH
;
        .PAGE
;
; _SETC2  -- SETCODE FROM BOTH A & X REGS
;
_SETC2
        JSR     _SETCODE
        TXA
; FALL THRU TO _SETCODE
;
;
; SETCODE-SET CODE IN ACV AT COX AND INC COX
;
_SETCODE
        LDY     COX             ;GET COX
        STA     (OUTBUFF),Y     ;SET CHAR
        INC     COX             ;INC COX
        BEQ     _SCOVF          ;BR IF NOT ZERO
        CLC
        RTS                     ;DONE
_SCOVF
        LDA     #EROVR
        JSR     ERROR
        RTS
        .PAGE
;
;       TSTALPH - TEST CIX FOR ALPHA
;
_TSTALPH
TSTALPH
        LDY     CIX
        LDA     (INBUFF),Y
        CMP     #'A-1
        BCC     _TAFAIL
        CMP     #$5B
        RTS
;
_TAFAIL SEC
        RTS
        .PAGE
;
;       _SRCONT - SEARCH FOR OPERATOR
;
_SRCONT
        PHA                     ; SAVE SYNTAX TABLE CODE
        JSR     KWSRCH          ; SEARCH KEYWORD TABLE
        PLA                     ; GET TOKEN
        BCS     _SRFAIL         ; IF ERROR, BR
;
;
        CMP     STENUM          ; COMP TO SEARCH RESULT
        BNE     _SRFAIL         ; IF NOT = THEN FAIL
        BEQ     _LOC1           ; ELSE PUT IN BUFFER
;
_SRFAIL
        SEC
        RTS
        .PAGE
;
;       SET - EXTERNAL CODE TO SET A TOKEN INTO LINE
;
_SET
        JSR     _INCCPC         ; INC PC TO CODE
        LDY     #0
        LDA     (CPC),Y         ; GET CODE
;
        JMP     _SETCODE        ; CODE TO BUFFER
        .PAGE
;
;       LBLREF - EXTERNAL SUBROUTINE FOR LABEL REFERENCE
;
_LBLREF
        JSR     LBLSRCH         ; GO SEARCH FOR LABEL
        BCS     _SRFAIL         ; BR IF FAIL
;
        LDY     #2
        LDA     (SRCADR),Y      ; GET DEFINE BYTE FOR LABEL
        BMI     _LBLR1          ; IF PASS 1 DEF BIT ON, DONE
;
        PHA
        LDA     #ERNDEF         ; GET NOT DEFINED ERROR
        JSR     ERROR
        PLA
_LBLR1
        LDX     #THEX2          ; GET HEX # CODE
        AND     PASSFLG         ; HAS LABEL BEEN DEFINED THIS PASS?
        BNE     _LBLR3          ; IF YES, BR
;
_LBLR2
        LDY     #2              ;GET DEFINE FLAG
        LDA     (SRCADR),Y      ;X
        ORA     #NZ             ;OR IN ABSOLUTE FLAG
        STA     (SRCADR),Y      ;SAVE IT IN TABLE
        LDX     #THEX2+$80      ; GET UNSOLVED REF CODE
_LBLR3
        TXA                     ; PUT # CODE IN A
        JSR     _SETCODE        ; SET IN OUTPUT
        LDY     #1
        LDA     (SRCADR),Y      ; VALUE OF LABEL...HIGH
        DEY
        TAX
        LDA     (SRCADR),Y      ; & LOW
        JMP     _SETC2          ; TO OUTPUT
        .PAGE
;
;       GCHAR - EXTERNAL SUBROUTINE TO GET A SINGLE CHAR
;
;
_GCHAR
        DEC     COX             ; BACK UP OVER QUOTE
;
        JSR     GETIN           ; GET NEXT INPUT CHAR
        TAX                     ; INPUT CHAR TO X
        LDA     #THEX2          ; "2 BYTE HEX" -- CODE
        JSR     _SETC2          ; BOTH TO OUTPUT
;
        LDA     #0              ; SET NUMBER HIGH
        BEQ     _LOC1           ; UNCONDITIONAL BR
;
;
;
;
;       LOC - EXTERNAL SUBROUTINE TO PROCESS LOCATION COUNTER
;
_LOC
        JSR     SKPBLK
        DEC     COX             ; REMOVE * FROM OUTPUT
        LDA     #THEX2          ; PUT HEX # CODE IN PUTPUT
        LDX     LOCCNT
        JSR     _SETC2          ; CODE && LSB TO OUTPUT
        LDA     LOCCNT+1        ; X
_LOC1
        JMP     _SETCODE
        .PAGE
;
;       DEC - EXTERNAL SUBROUTINE TO CHECK FOR DECIMAL #
;
_DEC
        JSR     SKPBLK
        LDA     CIX
        STA     TVSCIX
        JSR     AFP             ; GO TEST AND CONV
        BCS     _TNC3           ; ERROR
        JSR     FPI             ; CONVERT TO INTEGER
        BCC     _TNC1           ; BR IF NUMBER
_TNC3
        LDA     TVSCIX
        STA     CIX
        RTS                     ; RETURN FAIL
;
_TNC1   LDA     #THEX2          ; 2 BYTE HEX CODE
        JSR     _SETCODE
;
;
_STNUM
        LDA     FR0             ; GET # LOW
        LDX     FR0+1           ; & HIGH
        JMP     _SETC2
        .PAGE
;
;       HEX - EXTERNAL SUBROUTINE TO HANDLE HEX NUMBERS
;
;       HEXD - REMOVE $ FROM OUTPUT , THEN PROCESS LIKE HEX
;
_HEXD
        DEC     COX             ; REMOVE $ FROM OUTPUT
GETHEX
_HEX
        JSR     SKPBLK        ;SKIP BLANKS
;
;       CLEAR INTEGER
;
        LDA     #0
        STA     ZTEMP4          ; CLEAR INTEGER RESULT
        STA     ZTEMP4+1        ; X
;
;       DO CONVERT
;
        JSR     _HEXIN          ; GET A HEX DIGIT IN A
        BCS     _HFAIL          ;
;
;       ADD IN DIGIT
;
_HEX1
        CLC                     ; ADD DIGIT TO RESULT
        ADC     ZTEMP4+1        ; X
        STA     ZTEMP4+1        ; X
        LDA     ZTEMP4          ; X
        ADC     #0              ; X
        STA     ZTEMP4          ; X
;
;       GET NEXT DIGIT
;
        JSR     _HEXIN          ; GET NEXT DIGIT IN A
        BCS     _HEX2           ; IF NOT A DIGIT, BR
;
;
;       MULT INTEGER RESULT BY 16
;
        LDX     #4              ; SHIFT 2 BYTE INTEGER 4 TIMES
_SHIFT
        JSR     ILSHFT          ; SHIFT 1 BIT
        BCS     _HFAIL          ; IF CARRY SET, THEN # TOO BIG
;
        DEX                     ; DEC COUNT
        BNE     _SHIFT          ; IF MORE TO DO, BR
;
;
        JMP     _HEX1           ; REPEAT
;
_HEX2
        LDA     #THEX2          ; PUT NUMBER CODE IN OUTPUT
        JSR     _SETCODE        ; X
        LDA     ZTEMP4+1        ; PUT # IN OUTPUT
        LDX     ZTEMP4
        JSR     _SETC2          ; BOTH BYTES
        DEC     CIX             ; BACK UP TO LAST CHAR
_HFAIL
        RTS
        .PAGE
;
;       HEXIN - GET A HEX DIGIT FROM INPUT BUFFER
;
;       ON EXIT    CARRY SET IF CHAR NOT VALID HEX
;                  CARRY CLEAR IF VALID
;                  A - DIGIT
;
_HEXIN
        JSR     GETIN           ; GET INPUT CHAR
        SEC
        SBC     #$30            ; SUBTRACT 30
        BMI     _NHEX           ; IF CHAR <30, THEN NOT HEX
        CMP     #$A             ; IS RESULT < 10?
        BCC     _HEND           ; IF YES, HAVE DIGIT
        SBC     #7              ; SUB 7 MOVE
        CMP     #$A             ; IS IT LESS THAN HEX A?
        BCC     _NHEX           ; IF
        CMP     #$10            ; IS RESULT < 16
        BCC     _HEND           ; IF YES, HAVE DIGIT
;
_NHEX
        SEC                     ; SET RETURN FAIL
_HEND
        RTS
        .PAGE
;
;       STR1 - CHECK FOR STRING WITH ANY DELIMETER
;
;       STR2 - CHECK FOR STRING WITH SAME DELIMETER AS 1ST STRING
;
;       STR3 - CHECK FOR QUOTED STRING
;
;
;
;       _FSTR - EXTERNAL SUBROUTINE TO PROCESS FILE SPEC STRING
;
;       _FSTRM - PROCESS FILE SPEC STRING ENDING IN <
;
_STR1
        LDA     #0              ; SET NULL FLAG
        STA     NULFLG          ; TO NULL NOT VALID
        JSR     SKPBLK
        LDY     CIX             ; GET INPUT INDEX
        LDA     (INBUFF),Y      ; GET CHAR
        CMP     #CR             ; IS IT CR?
        BEQ     _STFAIL         ; IF YES RETURN FAIL
;
        BNE     _ST6            ;UNCONDITIONAL BRANCH
;
_FSTRM
        LDA     #'<             ; GET STRING DELIMETER
        BNE     _FS
;
;
;
_FSTR
        LDA     #',             ; GET COMMA AS DELIMETER
_FS
        LDY     #0              ; SET NULL NOT VALID
        STY     NULFLG
        JSR     _ST2            ; HANDLE STRING
        BCS     _FSTR1          ; IF FIND EOL, FINISH STR
        DEC     CIX             ; BACK UP TO LAST NON-FILE CHAR
        RTS
;
;
;
;
_STR2   DEC     CIX             ; POINT TO DELIMETER
        LDA     #1              ; SET NULL VALID FLAG
        STA     NULFLG
        BNE     _ST3
;
;
;
_STR3
        LDA     #0              ; SET NULL FLAG TO
        STA     NULFLG          ; NULL NOT VALID
        LDA     #'"             ; GET DOUBLE QUOTES
        DEC     COX             ; REMOVE ' FROM OUTPUT
;
;
;
_ST2
        DEC     CIX             ; BACK UP 1 CHAR BEFORE STR
_ST6
        STA     STRDEL          ; GET STRING DELIMETER
;
_ST3
        TAX                     ; SAVE FOR NOW
        LDA     #TSTR           ; GET STRING CODE
        JSR     _SETCODE        ; GO PUT IN OUTPUT
;
        TXA
        LDX     COX
        INX
        STX     TSCOX           ; GET & SAVE OUTPUT INDEX
        JSR     _SETC2          ; & SET AS DUMMY (WITH STRDEL)
_ST4
        INC     CIX             ; POINT TO NEXT INPUT CHAR
        LDY     CIX             ; GET INDEX
        LDA     (INBUFF),Y      ; GET CHAR
        CMP     #CR             ; IS IT CR?
        BEQ     _STFAIL         ; IF YES, IT'S AN ERROR
        CMP     STRDEL          ; IS IT DELIMETER
        BEQ     _ST5            ; IF YES, END OF STRING
        JSR     _SETCODE
        BNE     _ST4            ; BR UNCONDITIONALLY
;
_ST5
        INC     CIX             ; INCR OVER DELIMETER
_FSTR1
        CLC                     ; GET STR LENGTH
        LDA     COX             ; X
        SBC     TSCOX           ; X
        BNE     _STLEN          ; IF NOT NULL, SET LENGTH
        LDY     NULFLG          ; ELSE SEE IF NULL OKAY
        BEQ     _STFAIL         ; IF FLAG =0, NULL IS ERROR
_STLEN
        LDY     TSCOX           ; GET INDEX TO LENGTH IN OUTPUT
        STA     (OUTBUFF),Y     ; SAVE LENGTH
;
        CLC
        RTS                     ; SET RETURN PASS
;
;
_STFAIL
        SEC                     ; SET RETURN FAIL
        RTS
        .PAGE
;
;       LBLSRCH - SEARCH FOR LABEL IN SYMBOL MAP
;
;       ON EXIT    CARRY SET - NOT FOUND
;                  CARRY CLEAR - FOUND
;
LBLSRCH
        LDA     MODEFLG         ; CAN'T HAVE LABEL
        CMP     #MAMODE         ; IN MINI-ASM
        BEQ     _TVFAIL         ; X
        JSR     SKPBLK        ; SKIP BLANKS
        LDA     CIX             ; SAVE INDEX
        STA     TVSCIX          ; X
;
        JSR     _TSTALPH        ; TEST 1ST CHAR FOR ALPHA
        BCS     _TVFAIL         ; IF NOT ALPHA, THEN FAIL
;
_TV1
        INC     CIX             ; INCR TO NEXT CHAR
        JSR     _TSTALPH        ; IS IT ALPHA?
        BCC     _TV1            ; IF YES TRY AGAIN
        CMP     #'.
        BEQ     _TV1            ; IF YES, TRY AGAIN
        JSR     TSTNUM          ; IS IT NUMBER
        BCC     _TV1            ; IF YES TRY AGAIN
        BCS     _LBL1
;
_TVFAIL
        SEC                     ; SET FAIL
        RTS
;
;
_LBL1
        LDA     TVSCIX          ; RESTORE CIX
        STA     CIX             ; X
        STY     TVSCIX          ; SAVE NEW CIX (END OF LBL+1)
;
LBLS1
        LDA     SMBLTP+1        ; SEARCH SYMBOL TABLE
        LDY     SMBLTP
        LDX     #3              ; GET # BYTES TO SKIP
        JSR     SEARCH          ; X
;
_LBL2
        BCS     _LNF            ; BR IF NOT FOUND
        CPX     TVSCIX          ; FOUND RIGHT ONE
        BEQ     _LF             ; IF YES, DONE
        JSR     SRCNXT          ; IF NOT, SEARCH AGAAIN
        JMP     _LBL2           ; TEST THIS RESULT
;
_LNF
        LDA     TVSCIX          ; LABEL LENGTH EQU
        SBC     CIX             ; NEW CIX - OLD CIX
        CMP     #1              ; IS LENGTH = 1?
        BNE     _LNF1           ; IF NOT, THIS CAN'T BE LABEL A
        LDY     CIX             ; GET 1ST CHAR
        LDA     (INBUFF),Y      ; X
        CMP     #'A             ; IS IT A
        BEQ     _TVFAIL         ; IF YES, THEN NOT LABEL
        LDA     #1              ; ELSE OKAY
;
_LNF1
        STA     CIX             ; SAVE LENGTH
;
        LDY     #3              ; EXPAND TABLE BY 3
        LDX     #SMBLEND        ; X
        JSR     EXPLOW          ; X
;
;
        LDY     #2              ; CLEAR THE 3 BYTES OF LABEL ENTRY
        LDA     #0              ; X
_LNF2
        STA     (SVESA),Y       ; X
        DEY                     ; X
        BPL     _LNF2           ; X
;
        LDY     CIX             ; EXPAND BY LABEL LENGTH
        LDX     #SMBLEND        ; X
        JSR     EXPLOW          ; X
;
;
        LDY     CIX             ; AND
        DEY
        LDX     TVSCIX          ; GET DISPL TO EQU+1
        DEX
_TVS1   LDA     LBUFF,X         ; MOVE VAR TO
        STA     (SVESA),Y
        DEX
        DEY
        BPL     _TVS1
;
        LDY     CIX             ;TURN ON MSB
        DEY                     ;OF LAST CHAR
        LDA     (SVESA),Y       ;IN VTVT ENTRY
        ORA     #$80
        STA     (SVESA),Y
;
_LF
        LDA     TVSCIX          ; SET NEW CIX
        STA     CIX             ; X
;
        CLC                     ; SET PASS
        RTS
        .PAGE    'SEARCH ROUTINES'
;
;       KWSRCH - SEARCH KEYWORD TABLE
;
;       ON EXIT    X - COMMAND TYPE
;                      1 - DIRECTIVE
;                      2 - IMPLIED
;                      3 - RELATIVE
;                       4 - MISCELLANEOUS
;                      5 - MULTI-ADDR
;                      6 - EDITOR
;                      7 - DEBUG
;                      10 - OTHER
;
;                  A - ENTRY #
;
;
KWPTBL  .BYTE   CEDIR+1,CEIMP+1,CEREL+1
        .BYTE   CEMISC+1,CEMULT+1
;
KWSRCH
        JSR     SKPBLK
        LDX     #0              ; GET SKIP LENGTH
        LDA     #.HIGH.KWTAB    ; GET KEYWORD TABLE ADDR
        LDY     #.LOW.KWTAB     ; FOR SEARCH
        JSR     SEARCH          ; SEARCH
        STX     CIX             ; SET INPUT INDEX
        LDX     #0              ; SET COMMAND NOT FOUND
        BCS     _KRTN           ; BR IF NOT FOUND
;
;       CLASSIFY AS TYPE OF COMMAND
;
        LDA     STENUM          ; GET ENTRY # RETURNED IN SEARCH
        CLC                     ; ADD 1ST KW #
        ADC     #KWSTRT+1       ; X
        STA     STENUM          ; SAVE NEW ENTRY #
CLASF
        INX                     ; TO NEXT CMD TYPE
        CMP     KWPTBL-1,X      ; DOES THIS MATCH TBL ENTRY?
        BCC     _KRTN           ; YEP
        CPX     #5              ; NO...MORE TO DO?
        BNE     CLASF           ; YES
        INX
        CMP     #CSEDIT         ; IS IT AN OPTION
        BCC     _KRTN2          ; IF YES, NOT A COMMAND
        CMP     #CEEDIT+1
        BCC     _KRTN
;
        INX
        CMP     #CEBUG+1        ; IS IT DEBUG COMMAND?
        BCC     _KRTN
        CLC                     ; CLEAR FOR FOUND
_KRTN2
        LDX     #10             ; SET OTHER
_KRTN
;                                 CLEAR FOR RETURN PASS
        RTS
        .PAGE
;
;       SEARCH - SEARCH A TABLE
;               TABLE FORMAT:
;                  GARBAGE TO SKIP  (N)
;                  ASCII CHAR       (N)
;                    WITH LEAST SIGNIFICANT BYTE HAVING
;                    MOST SIGNIFICANT BIT ON
;               LAST TABLE ENTRY MUST HAVE FIRST ASCII CHAR = 0
;
;               ENTRY PARMS:
;                  X = SKIP LENGTH
;                  A,Y = TABLE ADR (HIGH LOW)
;                  ARGUMENT = INBUFF + CIX
;               EXIT PARMS:
;                  CARRY = CLEAR IF FOUND
;                  X = FOUND AARGUMENT END CIX+1
;                  SRCADR = TABLE ENTRY ADR
;                  STENUM = TABLE ENTRY NUMBER
;
SEARCH
        STX     SRCSKP          ; SAVE SKIP FACTOR
;
        LDX     #$FF            ; SET ENTRY NUMBER
        STX     STENUM          ; TO ZERO
;
_SRC1   STA     SRCADR+1        ; SET SEARCH ADR
        STY     SRCADR
        INC     STENUM          ; INC ENTRY NUMBER
        LDX     CIX             ; GET ARG DISPL
        LDY     SRCSKP          ; GET SKIP LENGTH
        LDA     (SRCADR),Y      ; GET FIRST CHAR
        BEQ     _SRCNF          ; BR IF EOT
;
_SRC2   LDA     LBUFF,X         ; GET INPUT CHAR
        AND     #$7F            ; TURN OFF MSB
        EOR     (SRCADR),Y      ; EX-OR WITH TABLE CHAR
        ASLA                    ; SHIFT MSB TO CARRY
        BEQ     _SRCM1          ; CHAR IN LBUFF = CHAR IN TBL
        BCS     _SRCME          ; NO MATCH & WAS LAST CHAR IN TBL
_SRCFAST
        INY                     ; NO MATCH, NOT LAST CHAR
        LDA     (SRCADR),Y      ; ...LOOP...
        BPL     _SRCFAST        ; UNTIL LAST CHAR FND
_SRCME
        INY                     ; BUMP TO PAST OLD LAST CHAR
;   (JOINED HERE BY LABEL TABLE RE-SEARCH)
SRCNXT
        JSR     INCSRC          ; TO NEXT ENTRY
        BNE     _SRC1           ; ALWAYS BRANCHES
;
; WE GET HERE EACH TIME LBUFF CHAR = TABLE CHAR
;
_SRCM1
        INY                     ; NEXT CHAR IN TBL
        INX                     ; NEXT IN BUFF
        BCC     _SRC2           ; IF NOT LAST CHAR, DO IT AGAIN
        CLC
        RTS                     ; WE FOUND A MATCH!
;
_SRCNF  SEC                     ;INDICATE NOT FOUND
        RTS
;
;
;
INCSRC
        CLC
        TYA                     ;ACV=ENTRY LENGTH
        ADC     SRCADR          ;PLUS START ADR (L)
        TAY                     ;TO Y
        LDA     SRCADR+1        ;ETC
        ADC     #0
        RTS
        .PAGE    'KEYWORD NAME TABLES'
;
;       KEYBOARD NAME TABLE
;
KWTAB
C       SET     KWSTRT
;
;
C       SET     C+1
CSASM   =       C               ; 1ST ASM CODE
CSDIR   =       C               ; 1ST DIRECTIVE CODE
        .BYTE   '.I',$80+'F'
;
C       SET     C+1
        .BYTE   '.TITL',$80+'E'
;
C       SET     C+1
        .BYTE   '.PAG',$80+'E'
;
C       SET     C+1
        .BYTE   '.WOR',$80+'D'
;
C       SET     C+1
        .BYTE   '.BYT',$80+'E'
;
C       SET     C+1
        .BYTE   '.DBYT',$80+'E'
;
C       SET     C+1
        .BYTE   '.EN',$80+'D'
;
C       SET     C+1
        .BYTE   '.OP',$80+'T'
;
C       SET     C+1
        .BYTE   '.TA',$80+'B'
;
C       SET     C+1
        .BYTE   '*',$80+'='
;
C       SET     C+1
        .BYTE   $80+'='
CEDIR   =       C               ; LAST DIRECTIVE CODE
;
C       SET     C+1
CSMNEM  =       C               ; 1ST MNEMONIC CODE
CSIMP   =       C               ; 1ST IMPLIED TYPE
;
KWTAB2
;
        .BYTE   'BR',$80+'K'
;
C       SET     C+1
        .BYTE   'CL',$80+'C'
;
C       SET     C+1
        .BYTE   'CL',$80+'D'
;
C       SET     C+1
        .BYTE   'CL',$80+'I'
;
C       SET     C+1
        .BYTE   'CL',$80+'V'
;
C       SET     C+1
        .BYTE   'DE',$80+'X'
;
C       SET     C+1
        .BYTE   'DE',$80+'Y'
;
C       SET     C+1
        .BYTE   'IN',$80+'X'
;
C       SET     C+1
        .BYTE   'IN',$80+'Y'
;
C       SET     C+1
        .BYTE   'NO',$80+'P'
;
C       SET     C+1
        .BYTE   'PH',$80+'A'
;
C       SET     C+1
        .BYTE   'PH',$80+'P'
;
C       SET     C+1
        .BYTE   'PL',$80+'A'
;
C       SET     C+1
        .BYTE   'PL',$80+'P'
;
C       SET     C+1
        .BYTE   'RT',$80+'I'
;
C       SET     C+1
        .BYTE   'RT',$80+'S'
;
C       SET     C+1
        .BYTE   'SE',$80+'C'
;
C       SET     C+1
        .BYTE   'SE',$80+'D'
;
C       SET     C+1
        .BYTE   'SE',$80+'I'
;
C       SET     C+1
        .BYTE   'TA',$80+'X'
;
C       SET     C+1
        .BYTE   'TA',$80+'Y'
;
C       SET     C+1
        .BYTE   'TS',$80+'X'
;
C       SET     C+1
        .BYTE   'TX',$80+'A'
;
C       SET     C+1
        .BYTE   'TX',$80+'S'
;
C       SET     C+1
        .BYTE   'TY',$80+'A'
CEIMP   =       C               ; LAST IMPLIED TYPE
;
C       SET     C+1
CSREL   =       C               ; 1ST RELATIVE TYPE
;
        .BYTE   'BC',$80+'C'
;
C       SET     C+1
        .BYTE   'BC',$80+'S'
;
C       SET     C+1
        .BYTE   'BE',$80+'Q'
;
C       SET     C+1
        .BYTE   'BM',$80+'I'
;
C       SET     C+1
        .BYTE   'BN',$80+'E'
;
C       SET     C+1
        .BYTE   'BP',$80+'L'
;
C       SET     C+1
        .BYTE   'BV',$80+'C'
;
C       SET     C+1
        .BYTE   'BV',$80+'S'
CEREL   =       C               ; LAST RELATIVE TYPE
;
C       SET     C+1
CSMISC  =       C               ; 1ST MISC TYPE
;
CJSR    =       C               ; JSR INST.
        .BYTE   'JS',$80+'R'
;
C       SET     C+1
CJMP    =       C               ; JUMP INST.
        .BYTE   'JM',$80+'P'
;
CEMISC  =       C               ; LAST MISC TYPE
;
C       SET     C+1
CSMULT  =       C               ; 1ST MULTI ADDR
;
        .BYTE   'OR',$80+'A'
;
C       SET     C+1
        .BYTE   'AN',$80+'D'
;
C       SET     C+1
        .BYTE   'EO',$80+'R'
;
C       SET     C+1
        .BYTE   'AD',$80+'C'
;
C       SET     C+1
        .BYTE   'ST',$80+'A'
;
C       SET     C+1
        .BYTE   'LD',$80+'A'
;
C       SET     C+1
        .BYTE   'CM',$80+'P'
;
C       SET     C+1
        .BYTE   'SB',$80+'C'
;
C       SET     C+1
        .BYTE   'AS',$80+'L'
;
C       SET     C+1
        .BYTE   'RO',$80+'L'
;
C       SET     C+1
        .BYTE   'LS',$80+'R'
;
C       SET     C+1
        .BYTE   'RO',$80+'R'
;
C       SET     C+1
        .BYTE   'DE',$80+'C'
;
C       SET     C+1
        .BYTE   'IN',$80+'C'
;
C       SET     C+1
        .BYTE   'LD',$80+'X'
;
C       SET     C+1
        .BYTE   'LD',$80+'Y'
;
C       SET     C+1
        .BYTE   'ST',$80+'X'
;
C       SET     C+1
        .BYTE   'ST',$80+'Y'
;
C       SET     C+1
        .BYTE   'CP',$80+'X'
;
C       SET     C+1
        .BYTE   'CP',$80+'Y'
;
C       SET     C+1
        .BYTE   'BI',$80+'T'
;
CEMULT  =       C               ; LAST MULT ADDR
CEMNEM  =       C               ; LAST MNEMONIC
CEASM   =       C               ; LAST ASM CODE
C       SET     C+1             ; 1ST OPTION
CSOPT   =       C
;
CNO     =       C
        .BYTE   'N',$80+'O'
;
C       SET     C+1
COBJ    =       C
        .BYTE   'OB',$80+'J'
;
C       SET     C+1
CERR    =       C
        .BYTE   'ER',$80+'R'
;
C       SET     C+1
CEJECT  =       C
        .BYTE   'EJEC',$80+'T'
;
C       SET     C+1
;
CSEDIT  =       C               ; 1ST EDITOR COMMAND
CLIST   =       C               ; LIST OPTION
        .BYTE   'LIS',$80+'T'
;
;
CEOPT   =       C               ; LAST OPTION
C       SET     C+1
        .BYTE   'NE',$80+'W'
;
C       SET     C+1
        .BYTE   'DE',$80+'L'
;
C       SET     C+1
        .BYTE   'FIN',$80+'D'
;
C       SET     C+1
        .BYTE   'ENTE',$80+'R'
C       SET     C+1
        .BYTE   'LOA',$80+'D'
;
C       SET     C+1
        .BYTE   'SAV',$80+'E'
;
;
C       SET     C+1
        .BYTE   'NU',$80+'M'
;
C       SET     C+1
        .BYTE   'PRIN',$80+'T'
;
C       SET     C+1
        .BYTE   'RE',$80+'N'
;
C       SET     C+1
        .BYTE   'RE',$80+'P'
;
C       SET     C+1
        .BYTE   'SIZ',$80+'E'
;
C       SET     C+1
        .BYTE   'LOME',$80+'M'
;
C       SET     C+1
        .BYTE   'BY',$80+'E'
;
C       SET     C+1
        .BYTE   'DO',$80+'S'
;
C       SET     C+1
        .BYTE   'AS',$80+'M'
;
C       SET     C+1
        .BYTE   'BU',$80+'G'
CEEDIT  =       C               ; LAST EDITOR COMMAND
;
C       SET     C+1
CSBUG   =       C               ; 1ST DEBUG COMMAND
;
CA      =       C               ; A OPERAND (EDITOR & ASM)
        .BYTE    $80+'A'
;
C       SET     C+1
CM      =       C               ; M OPERAND (EDITOR)
        .BYTE   $80+'M'
;
C       SET     C+1
        .BYTE   'C',$80+'R'
;
C       SET     C+1
        .BYTE   'D',$80+'R'
;
C       SET     C+1
        .BYTE   $80+'G'
;
C       SET     C+1
        .BYTE   $80+'T'
;
C       SET     C+1
        .BYTE   $80+'S'
;
C       SET     C+1
        .BYTE   $80+'D'
;
C       SET     C+1
        .BYTE   $80+'L'
;
C       SET     C+1
        .BYTE   $80+'V'
;
C       SET     C+1
CX      =       C               ; X OPERAND (ASM)
        .BYTE   $80+'X'
;
C       SET     C+1
        .BYTE   $80+'C'
CEBUG   =       C               ; LAST DEBUG
;
C       SET     C+1
CSOP    =       C               ; 1ST OPERATOR
CPLUS   =       C               ; PLUS
        .BYTE   $80+'+'
;
C       SET     C+1
CMINUS  =       C               ; MINUS
        .BYTE   $80+'-'
;
C       SET     C+1
CMUL    =       C               ; MULTIPLY
CLOC    =       C               ; LOCATION COUNTER
        .BYTE   $80+'*'
;
C       SET     C+1
CDIV    =       C               ; DIVIDE
        .BYTE   $80+'/'
;
C       SET     C+1
CAND    =       C               ; AND
        .BYTE   $80+'&'
;
C       SET     C+1
CDQ     =       C               ; DOUBLE QUOTE
        .BYTE  $A2
;
C       SET     C+1
CSQ     =       C               ; SINGLE QUOTE
        .BYTE   $80+''''
;
C       SET     C+1
CLPRN   =       C               ; LEFT PAREN
        .BYTE   $80+'('
;
C       SET     C+1
CRPRN   =       C               ; RIGHT PAREN
        .BYTE   $80+')'
;
C       SET     C+1
CDOL    =       C               ; DOLLAR SIGN
        .BYTE   $80+'$'
;
C       SET     C+1
CSC     =       C               ; SEMI COLON
        .BYTE   $80+';'
;
C       SET     C+1
CIMM    =       C               ; IMMEDIATE OPERAND
CFILE   =       C
        .BYTE   $80+'#'
;
C       SET     C+1
CEOL    =       C               ; CARRIAGE RETURN
        .BYTE   CR
;
C       SET     C+1
CCOM    =       C
        .BYTE   $80+','
;
C       SET     C+1
CDELIM  =       C               ; DEBUG DELIMETER
        .BYTE   DELIM+$80
;
C       SET     C+1
CY      =       C               ; Y OPERAND (ASM)
        .BYTE   $80+'Y'
;
C       SET     C+1
CQ      =       C               ; Q OPERAND (EDIT)
        .BYTE   $80+'Q'
;
C       SET     C+1
CIFDEL  =       C               ; IF DELIMITER
        .BYTE   $80+'@'
CEOP    =       C               ; LAST OP
        .BYTE   0,$80           ; END OF TABLE
C       SET     C+2
CDUM    =       C
        .BYTE   '??',$80+'?'
        .PAGE    'SYNTAX TABLE ADDRESSES'
;
;       EDITOR SYNTAX TABLE ADDRESSES
;
ESTBL
        .WORD   _SLIST-1
        .WORD   _SCLR-1
        .WORD   _SDEL-1
        .WORD   _SFIND-1
        .WORD   _SENTER-1
        .WORD   _SLOAD-1
        .WORD   _SSAVE-1
        .WORD   _SNUM-1
        .WORD   _SPRINT-1
        .WORD   _SREN-1
        .WORD   _SREP-1
        .WORD   _SSIZE-1
        .WORD   _SLOMEM-1
        .WORD   _SBYE-1
        .WORD   _SDOS-1
        .WORD   _SASM-1
        .WORD   _SATBUG-1
;
;
;
;       DEBUG SYNTAX TABLE ADDRESS
;
DSTBL
        .WORD   _SA-1
        .WORD   _SM-1
        .WORD   _SCR-1
        .WORD   _SDR-1
        .WORD   _SG-1
        .WORD   _ST-1
        .WORD   _SS-1
        .WORD   _SD-1
        .WORD   _SL-1
        .WORD   _SV-1
        .WORD   _SX-1
        .WORD   _SC-1
;
;
;
;       ASSEMBLE DIRECTIVE SYNTAX TABLE ADDRESSES
;
ADSTBL
        .WORD   _SIF-1
        .WORD   _STITLE-1
        .WORD   _SPAGE-1
        .WORD   _SWORD-1
        .WORD   _SBYTE-1
        .WORD   _SDBYTE-1
        .WORD   _SEND-1
        .WORD   _SOPT-1
        .WORD   _STAB-1
        .WORD   _SORG-1
        .WORD   _SEQU-1
        .PAGE
;
;       ASTBL - SYNTAX ROUTINE ADDRS FOR ASM BY COMMAND TYPE
;
ASTBL
        .BYTE   0,0
        .WORD   ASDIR-1         ; DIRECTIVE
        .WORD   ASIMP-1         ; DIRECTIVE
        .WORD   ASREL-1         ; RELATIVE
        .WORD   ASMISC-1        ; MISC
        .WORD   ASMULT-1        ; MULT ADDR
        .PAGE
;
;       TOPTBL - TRIAL OP CODE TABLE
;
TOPTBL
        .BYTE   $00             ; BRK
        .BYTE   $18             ; CLC
        .BYTE   $D8             ; CLD
        .BYTE   $58             ; CLI
        .BYTE   $B8             ; CLV
        .BYTE   $CA             ; DEX
        .BYTE   $88             ; DEY
        .BYTE   $E8             ; INX
        .BYTE   $C8             ; INY
        .BYTE   $EA             ; NOP
        .BYTE   $48             ; PHA
        .BYTE   $08             ; PHP
        .BYTE   $68             ; PLA
        .BYTE   $28             ; PLP
        .BYTE   $40             ; RTI
        .BYTE   $60             ; RTS
        .BYTE   $38             ; SEC
        .BYTE   $F8             ; SED
        .BYTE   $78             ; SEI
        .BYTE   $AA             ; TAX
        .BYTE   $A8             ; TAY
        .BYTE   $BA             ; TSX
        .BYTE   $8A             ; TXA
        .BYTE   $9A             ; TXS
        .BYTE   $98             ; TYA
;
        .BYTE   $90             ; BCC
        .BYTE   $B0             ; BCS
        .BYTE   $F0             ; BEQ
        .BYTE   $30             ; BMI
        .BYTE   $D0             ; BNE
        .BYTE   $10             ; BPL
        .BYTE   $50             ; BVC
        .BYTE   $70             ; BVS
;
        .BYTE   $20             ; JSR
        .BYTE   $4C             ; JMP
EOP1    =       *-TOPTBL        ; # OF ENTRYS IN NON-MULTI ADDR OP TABLE
TOPT2
;
        .BYTE   $01             ; ORA
        .BYTE   $21             ; AND
        .BYTE   $41             ; EOR
        .BYTE   $61             ; ADC
        .BYTE   $81             ; STA
        .BYTE   $A1             ; LDA
        .BYTE   $C1             ; CMP
        .BYTE   $E1             ; SBC
        .BYTE   $02             ; ASL
        .BYTE   $22             ; ROL
        .BYTE   $42             ; LSR
        .BYTE   $62             ; ROR
        .BYTE   $C2             ; DEC
        .BYTE   $E2             ; INC
        .BYTE   $A2             ; LDX
        .BYTE   $A0             ; LDY
        .BYTE   $82             ; STX
        .BYTE   $80             ; STY
        .BYTE   $E0             ; CPX
        .BYTE   $C0             ; CPY
        .BYTE   $20             ; BIT
EOP2    =       *-TOPT2         ; # OF ENTRIES IN OP TABLE
        .PAGE
;       'SYNTAX TABLES'
;
;       SYNTAX TABLE OP CODES
_ANTV   =       $00             ; ABSOLUTE NON-TERMINAL VECTOR
;                                 FOLLOWED BY 2 BYTE ADDR-1
_ESRT   =       $01             ; EXTERNAL SUBROUTINE CALL
;                                 FOLLOWED BY 2 BYTE ADDR-1
_OR     =       $02             ; ALTERNATIVE - BNF OR (])
_RTN    =       $03             ; RETURN (#)
_VEXP   =       KWSTRT-1        ; SPECIAL NTV FOR EXPR (<EXP>)
_SCODE  =       KWSTRT          ; PUT FOLLOWING TOKEN IN OUTPUT
;
;
;
;
;       DEFRA   -64,+63,$C0
        .PAGE    'SYNTAX TABLES'
;
;       <DEL> = <LNO><OLNO>EOL#
;
_SDEL
        DEFRA   _LNO
        DEFRA   _OLNO
        .BYTE   CEOL
        .BYTE   _RTN
;
;       <OLNO> = , <LNO>]&#
;
_OLNO
        .BYTE   CCOM
        DEFRA   _LNO
        .BYTE   _OR
        .BYTE   _RTN
;
;       <LNO> = EXTERNAL SUBROUTINE CALL TO PROCESS LINE #
;
_DECNUM
_LNO
        .BYTE   _ESRT
        .WORD   _DEC-1
        .BYTE   _RTN
;
;
;
;
;       <FIND> = <STR1><LNRANGE><OA>EOL#
;
_SFIND
        .BYTE   _ESRT
        .WORD   _STR1-1
        DEFRA   _LNRANGE
        DEFRA   _OA
_SNEW
_SCLR
_SSIZE
_SBYE
_SDOS
_SATBUG
        .BYTE   CEOL
        .BYTE   _RTN
;
;
;
;       <REP> = <STR1><STR2><LNRANGE><OQA>EOL#
;
_SREP
        .BYTE   _ESRT
        .WORD   _STR1-1
        .BYTE   _ESRT
        .WORD   _STR2-1
        DEFRA   _LNRANGE
        DEFRA   _OQA
        .BYTE   CEOL
        .BYTE   _RTN
;
;       <OAQ> = ,Q],A]&#
;       <OA> = ,A]&#
;
_OQA
        .BYTE   CCOM
        .BYTE   CQ
        .BYTE   _OR
_OA
        .BYTE   CCOM
        .BYTE   CA
        .BYTE   _OR
        .BYTE   _RTN
;
;
;
;
;
;
;
;       <ASM> = <FEOL>]<F1><FEOL>]
;               <F1><F1><FEOL>]EOL#
;
_SASM
        DEFRA   _FEOL
        .BYTE   _OR
        DEFRA   _F1
        DEFRA   _FEOL
        .BYTE   _OR
        DEFRA   _F1
        DEFRA   _F1
        DEFRA   _FEOL
        .BYTE   _OR
        .BYTE   CEOL
        .BYTE   _RTN
;
;       <LNRANGE> = <LNO><OLNO>]#.
;
_LNRANGE
        DEFRA   _LNO
        DEFRA   _OLNO
        .BYTE   _OR
        .BYTE   _RTN
;
;       <F1> = <FILESPEC>,],#
;
_F1
        DEFRA   _FILES
        .BYTE   CCOM
        .BYTE   _OR
        .BYTE   CCOM
        .BYTE   _RTN
;
;       <FEOL> = <FILESPEC>EOL#
;
_FEOL
        DEFRA   _FILESPEC
        .BYTE   CEOL
        .BYTE   _RTN
;
;       <JSR>
;       <REL INST>
;       <EXP> = <VALUE><OPVAL>#
;
_SREL   =       *-1
_SJSR   =       *-1
_EXP
        DEFRA   _EXPX
        .BYTE   _SCODE,TEOE
        .BYTE   _RTN
_EXPX
        DEFRA   _VALUE
        DEFRA   _OPVAL
        .BYTE   _RTN
;
;       <OPVAL> = <OP><EXP>]&#
;
_OPVAL
        DEFRA   _OP
        DEFRA   _EXPX
        .BYTE   _OR
        .BYTE   _RTN
;
;       <VALUE> = <DECNUM>]$<HEXNUM>]'<GCHAR>
;               ]*]LABREF#
;
_VALUE
        DEFRA   _DECNUM
        .BYTE   _OR
        .BYTE   CDOL,_ESRT
        .WORD   _HEXD-1
        .BYTE   _OR
        .BYTE   CSQ,_ESRT
        .WORD   _GCHAR-1
        .BYTE   _OR
        .BYTE   CLOC,_ESRT
        .WORD   _LOC-1
        .BYTE   _OR
        .BYTE   _ESRT
        .WORD   _LBLREF-1
        .BYTE   _RTN
;
;       <OP> = *]/]+]&]-#
;
_OP
        .BYTE   CMUL
        .BYTE   _OR
        .BYTE   CDIV
        .BYTE   _OR
        .BYTE   CPLUS
        .BYTE   _OR
        .BYTE   CAND
        .BYTE   _OR
        .BYTE   CMINUS
        .BYTE   _RTN
;
;
;       <PRINT>
;       <LIST> = <FILESPEC>EOL]<OFILE><LNRANGE>EOL#
;
;
;       <REN>
;       <NUM> = <LNRANGE>EOL#
;
_SPRINT
_SLIST
        DEFRA   _FILESPEC
        .BYTE   CEOL
        .BYTE   _OR
        DEFRA   _OFILE
_SREN
_SNUM
        DEFRA   _LNRANGE
        .BYTE   CEOL
        .BYTE   _RTN
;
;       <OFILE> = <FILESPEC>,]&#
;
_OFILE
        DEFRA   _FILESPEC
        .BYTE   CCOM
        .BYTE   _OR
        .BYTE   _RTN
;
;
;
;       <LOAD>
;       <FILESPEC> = #<FSTR>
;
_SLOAD
_FILESPEC
        .BYTE   CFILE
        .BYTE   _ESRT
        .WORD   _FSTR-1
        .BYTE   _RTN
;
;
;
;       <ENTER> = <FILESPEC><OM>EOL#
;
_SENTER
        DEFRA   _FILESPEC
        DEFRA   _OM
        .BYTE   CEOL
        .BYTE   _RTN
;
;       <OM> = ,M]&#
;
_OM
        .BYTE   CCOM
        .BYTE   CM
        .BYTE   _OR
        .BYTE   _RTN
;
;       <ADR> = EXTERNAL SUBROUTINE CALL TO PROCESS ADDR
;
_HEXNUM
_ADR
        .BYTE   _ESRT
        .WORD   _HEX-1
        .BYTE   _RTN
;
;
;
;       <SAVE> = <FILESPEC>< <ADR>,<ADR>
;
_SSAVE
        .BYTE   CFILE
        .BYTE   _ESRT
        .WORD   _FSTRM-1
        DEFRA   _ADR2
        .BYTE   _RTN
;
;       <M>
;       <V> = <ADR><<ADR>,<ADR>EOL#
;
_SM
_SV
        DEFRA   _ADR
_ADR2
        .BYTE   CDELIM
        DEFRA   _ADR
        .BYTE   CCOM
;
;       <LOMEM> = <ADR>EOL#
;
_SLOMEM
        DEFRA   _ADR
        .BYTE   CEOL
        .BYTE   _RTN
;
;
;
;
;
;
;       <G> = <S> = <T> = <OADR>EOL#
;
;
_SG
_SS
_ST
        DEFRA   _OADR
_SX
_SDR
_SA
        .BYTE   CEOL
        .BYTE   _RTN
;
;
;
;       <D>
;       <L> = EOL]ADR><OADR>EOL#
;
_SD
_SL
        .BYTE   CEOL
        .BYTE   _OR
        DEFRA   _ADR
        DEFRA   _OADR2
        .BYTE   CEOL
        .BYTE   _RTN
;
;       <OADR> = <ADR>]&#
;
;       <OADR2> = ,<ADR>]&#
;
_OADR2
        .BYTE   CCOM
_OADR
        DEFRA   _ADR
        .BYTE   _OR
        .BYTE   _RTN
;
;
;
;       <C> = <OADR><<DATA>EOL#
;
;
_SC
        DEFRA   _OADR
_SCR
        .BYTE   CDELIM
        DEFRA   _DATA
        .BYTE   CEOL
        .BYTE   _RTN
;
;       <DATA> = ,<DATA>]<HEX1><OHEX>#
;
_DATA
        .BYTE   CCOM
        DEFRA   _DATA
        .BYTE   _OR
        DEFRA   _HEXNUM
        DEFRA   _OHEX
        .BYTE   _RTN
;
;       <OHEX> = ,<DATA>]&#
;
_OHEX
        .BYTE   CCOM
        DEFRA   _DATA
        .BYTE   _OR
        .BYTE   _RTN
;
;       <TITLE>
;       <PAGE> = <QSTR>]#
;
_STITLE
_SPAGE
        DEFRA   _QSTR
        .BYTE   _OR
        .BYTE   _RTN
;
;
;
;       <DBYTE>
;       <DWORD> = <EXP><OWORD>#
;
_SDBYTE
_SWORD
        .BYTE   _VEXP
        DEFRA   _OWORD
        .BYTE   _RTN
;
;       <OWORD> = , <WORD>]&#
;
_OWORD
        .BYTE   CCOM
        DEFRA   _SWORD
        .BYTE   _OR
        .BYTE   _RTN
;
;
;
;       <BYTE> = <BYTE1>#
;
;
_SBYTE
        DEFRA   _BYTE1
        .BYTE   _RTN
;
;       <BYTE1> = <QSTR><OBYTE>]<EXP><OBYTE>#
;
_BYTE1
        DEFRA   _QSTR
        DEFRA   _OBYTE
        .BYTE   _OR
        .BYTE   _VEXP
        DEFRA   _OBYTE
        .BYTE   _RTN
;
;       <OBYTE> = ,<BYTE1>]&#
;
_OBYTE
        .BYTE   CCOM
        DEFRA   _BYTE1
        .BYTE   _OR
        .BYTE   _RTN
;
;       <QSTR> = '<STR2>#
;
_QSTR
        .BYTE   CDQ
        .BYTE   _ESRT
        .WORD   _STR3-1
        .BYTE   _RTN
;
;       <TAB> = <EXP>,<EXP>,<EXP>#
;       <=>
;       <=*> = <EXP>#
;       <END> = #
;
_STAB
        .BYTE   _VEXP
        .BYTE   CCOM
        .BYTE   _VEXP
        .BYTE   CCOM
_SEQU
_SORG
        .BYTE   _VEXP
_SEND
        .BYTE   _RTN
;
;
;
;
;       <IF> = <EXP><LABSTR>
;
_SIF
        .BYTE   _VEXP
        .BYTE   CIFDEL
        .BYTE   _ESRT
        .WORD   _FSTR-1
        .BYTE   _RTN
;
;
;
;
;       <OPT> = <OPT1>#
;
_SOPT
        DEFRA   _OPT1
        .BYTE   _RTN
;
;       <OPT1> = <ONO><LIST><OOPT>#
;
_OPT1
        DEFRA   _ONO
        DEFRA   _LIST
        DEFRA   _OOPT
        .BYTE   _RTN
;
;       <ONO> = NO]#
;       <LIST> = OBJ]ERR]PAGE]SYM]LIST#
;
_ONO
        .BYTE   CNO,_OR,_RTN
_LIST
        .BYTE   COBJ,_OR
        .BYTE   CERR,_OR
        .BYTE   CEJECT,_OR
        .BYTE   CLIST
        .BYTE   _RTN
;
;       <OOPT> = , <OPT1>]&#
;
_OOPT
        .BYTE   CCOM
        DEFRA   _OPT1
        .BYTE   _OR
        .BYTE   _RTN
;
;
;
;
;       <JMP INST> = CLPRN<EXP>CRPRN ]<EXP>
;
_SJMP   =       *-1
        .BYTE   CLPRN
        .BYTE   _VEXP
        .BYTE   CRPRN
        .BYTE   _OR
        .BYTE   _VEXP
        .BYTE   _RTN
;
;
;
;       <MULT ADDR TEST> = <INDX>]<INDY>]<IMM>]<ABSOLUTE><ACU>#
;       LEAVE ACU AS LAST THING
;
_SMULT  =       *-1
;
;       <INDX> = CLPRN<EXP>CCOM CX CRPRN
;
        .BYTE   CLPRN
        .BYTE   _VEXP
        DEFRA   _IND
        .BYTE   _OR
;
;       <IMM> = CIMM<EXP>
;
        .BYTE   CIMM
        .BYTE   _VEXP
        .BYTE   _SCODE,TIMM
        .BYTE   _OR
;
;       <ABSOLUTE> = <EXP><ABS>#
;
        .BYTE   _VEXP
        DEFRA   _ABS
        .BYTE   _OR
;
;       <ACU> = CA
;
        .BYTE   _SCODE,TACU
        .BYTE   CA
        .BYTE   _RTN
;
;       <IND> = ,X)]),Y#
;
_IND
        .BYTE   _SCODE,TINDX
        .BYTE   CCOM
        .BYTE   CX
        .BYTE   CRPRN
        .BYTE   _OR
        .BYTE   _SCODE,TINDY
        .BYTE   CRPRN
        .BYTE   CCOM
        .BYTE   CY
        .BYTE   _RTN
;
;       <ABS> = ,X],Y]#
;
_ABS
        .BYTE   _SCODE,TABSX
        .BYTE   CCOM
        .BYTE   CX
        .BYTE   _OR
        .BYTE   _SCODE,TABSY
        .BYTE   CCOM
        .BYTE   CY
        .BYTE   _OR
        .BYTE   _SCODE,TABS
        .BYTE   _RTN
        .PAGE    'EXECUTION ADDRESS TABLES'
;
;       EDITOR COMMANDS EXECUTION ADDRESS'
;
EXTBL
        .WORD   XLIST-1
        .WORD   XCLR-1
        .WORD   XDEL-1
        .WORD   XFIND-1
        .WORD   XENTER-1
        .WORD   XLOAD-1
        .WORD   XSAVE-1
        .WORD   XNUM-1
        .WORD   XPRINT-1
        .WORD   XREN-1
        .WORD   XREP-1
        .WORD   XSIZE-1
        .WORD   XLOMEM-1
        .WORD   BYELOC-1
        .WORD   XDOS-1
        .WORD   XASM-1
        .WORD   XATBUG-1
;
;
;
;
;       DEBUG COMMAND EXECUTION ADDRESSES
;
DXTBL
        .WORD   XA-1
        .WORD   XM-1
        .WORD   XCR-1
        .WORD   XDR-1
        .WORD   XG-1
        .WORD   XT-1
        .WORD   XS-1
        .WORD   XD-1
        .WORD   XL-1
        .WORD   XV-1
        .WORD   XX-1
        .WORD   XC-1
        .PAGE
;
;       AXTBL - ASEMBLER EXECUTION ROUTINES BY TYPE
;
AXTBL
        .WORD   AXCOM-1         ; COMMENT
        .WORD   AXDIR-1         ; DIRECTIVE
        .WORD   AXIMP-1         ; IMPLIED INSTRUCTION
        .WORD   AXREL-1         ; RELATIVE
        .WORD   AXMISC-1        ; MISCELLANEOUS
        .WORD   AXMULTI-1       ; MULTI-ADDRESS
;
;
;
;
;       ASM DIRECTIVE EXECUTION TABLE
;
ADXTBL
        .WORD   XIF-1
        .WORD   XTITLE-1
        .WORD   XPAGE-1
        .WORD   XWORD-1
        .WORD   XBYTE-1
        .WORD   XDBYTE-1
        .WORD   XEND-1
        .WORD   XOPT-1
        .WORD   XTAB-1
        .WORD   XORG-1
        .WORD   XEQU-1
        .PAGE 'MEMORY MANAGER'
;       LOCAL
;
;       MEMORY MANAGEMENT CONSISTS OF EXPANDING AND
; CONTRACTING TO INFORMATION AREA POINTED TO
; BY THE ZERO PAGE POINTER TABLES.  ROUTINES
;       MODIFY THE ADDRESS IN THE TABLES AND
;       MOVE DATA AS REQUIRED.  THE TWO FUNDAMENTAL
;       ROUTINES ARE 'EXPAND' AND 'CONTRACT'
;
;               ****
;
;       EXPAND-
;               X = ZERO PAGE ADDRESS OF TABLE AT WHICH
;               EXPANSION IS TO START
;               Y = EXPANSION SIZE IN BYTES (LOW)
;               A = EXPANSION SIZE IN BYTES (HIGH)
;
; EXPLOW - FOR EXPANSION < 256 BYTES
;                SETS A = 0
;
;       EXPTXT - EXPAND AT STMCUR
;       COMPLIMENT OF LENGTH IN A
;
;
EXPTXT
        EOR     #$FF            ;COMPLEMENT RESULT
        TAY
        INY
        LDX     #STMCUR         ;POINT TO STMT CURRENT
;
EXPLOW  LDA     #0
;
EXPAND
        STY     ECSIZE          ; SAVE EXPAND SIZE
        STA     ECSIZE+1
;
        SEC
        LDA     MEMTOP          ; TEST MEMORY TO BE FULL
        ADC     ECSIZE
        TAY                     ; MEMTOP+ECSIZE+1
        LDA     MEMTOP+1
        ADC     ECSIZE+1        ; MUST BE LE
        CMP     HIMEM+1
        BCC     _EXP2           ; HIMEM
        BNE     _EXP1
        CPY     HIMEM
        BCC     _EXP2
        BEQ     _EXP2
_EXP1
        LDA     #MEMFULL        ;GET ERROR CODE
        JSR     ERROR
        JSR     PRTERR          ; PRINT ERROR
        JMP     ABRK            ; ABORT
;
_EXP2
        SEC                     ; FORM MOVE LENGTH (MVLNG)
        LDA     MEMTOP          ; MOVE FROM ADR (MVFA)
        SBC     0,X             ; MVLNG = MEMTOP-EXPAND ADR
        STA     MVLNG
        LDA     MEMTOP+1        ; MVFA(L) = EXP ADR (L)
        SBC     1,X
        STA     MVLNG+1         ; MVFA(H) = EXP ADR(H) + MVLNG(H)
        CLC                     ; DURING MOVE MVLNG(L)
        ADC     1,X             ; WILL BE ADDED SUCH
        STA     MVFA+1          ; THAT MVFA = MEMTOP
;
        LDA     0,X             ; SAVE PREMOVE EXPAND AT VALUE
        STA     MVFA            ; SET MVFA LOW
        STA     SVESA           ; FORM MOVE TO ADR (MVTA)
        ADC     ECSIZE          ; MVTA(L) = EXP ADR(L) + ECSIZE(L)
        STA     MVTA            ; MVTA(H) = (CARRY + EXP ADR(H)
        LDA     1,X             ; +ECSIZE(H)) + MVLNG(H)
        STA     SVESA+1
        ADC     ECSIZE+1        ; DURING MOVE MVLNG(L)
        ADC     MVLNG+1         ; WILL BE ADDED SUCH THAT
        STA     MVTA+1          ; MVTA = MEMTOP + ECSIZE
;
_EXP3
        LDA     0,X             ; ADD ECSIZE TO
        ADC     ECSIZE          ; ALL TABLE ENTRIES
        STA     0,X             ; FROM EXPAND AT ADR
        LDA     1,X             ; TO HIMEM
        ADC     ECSIZE+1
        STA     1,X
        INX
        INX
        CPX     #MEMTOP+2
        BCC     _EXP3
;
        STA     APHM+1          ; SET NEW APL
        LDA     MEMTOP          ; HI MEM TO
        STA     APHM            ; MEMTOP
;
        LDX     MVLNG+1         ; X = MVLNG(H)
        INX                     ; PLUS ONE
        LDY     MVLNG           ; Y=MVLNG(L)
        BNE     _EXP6           ; TEST ZERO LENGTH
        BEQ     _EXP7           ; BR IF LOW = 0
;
_EXP4   DEY                     ; DEC MVLNG(L)
        DEC     MVFA+1          ; DEC MVFA(H)
        DEC     MVTA+1          ; DEC MVTA(H)
;
_EXP5   LDA     (MVFA),Y        ; MVFA BYTE
        STA     (MVTA),Y        ; TO MVTA
_EXP6   DEY                     ; DEC COUNT LOW
        BNE     _EXP5           ; BR IF NOT ZERO
;
        LDA     (MVFA),Y        ; MOVE THE ZERO BYTE
        STA     (MVTA),Y
;
_EXP7
        DEX                     ; IF MVLNG(H) IS NOT
        BNE     _EXP4           ; ZERO THEN MOVE 256 MORE
;                                 ELSE
        RTS                     ; DONE
        .PAGE
;
;       CONTRACT
;               X = ZERO PAGE ADR OF TABLE AT WHICH
;                   CONTRACTION WILL START
;               Y = CONTRACT SIZE IN BYTES (LOW)
;               A = CONTRACT SIZE IN BYTES (HI)
;       CONTLOW
;               SETS A = 0
;
;
;       CONTXT - CONTRACT AT STMCUR
;       LENGTH IN A
;
CONTXT
        TAY
        LDX     #STMCUR
CONTLOW LDA     #0
;
CONTRACT
        STY     ECSIZE          ; SAVE CONTRACT SIZE
        STA     ECSIZE+1
;
        SEC                     ; FORM MOVE LENGTH (LOW)
        LDA     MEMTOP
        SBC     0,X             ; MVLNG(L) = $100-
;
        EOR     #$FF            ; (MEMTOP(L)) - CON AT VALUE (L)
        TAY                     ; THIS MAKES START Y AT
        INY                     ; MOVE HAVE A 2'S COMPLIMENT
        STY     MVLNG           ; REMAINDER IN IT
        LDA     MEMTOP+1        ; FORM MOVE LENGTH(HIGH)
        SBC     1,X
        STA     MVLNG+1
;
        LDA     0,X             ; FORM MOVE FROM ADR (MVFA)
        SBC     MVLNG           ; MVFA = CON AT VALUE
        STA     MVFA            ; MINUS MVLNG(L)
        LDA     1,X             ; DURING MOVE MVLNG(L)
        SBC     #0              ; WILL BE ADDED BACK INTO
        STA     MVFA+1          ; MVFA IN (IND),Y INST
;
        STX     MVTA            ; TEMP SAVE OF CON AT DISPL
;
_CONT1  SEC     ; SUBTRACT ECSIZE FROM
        LDA     0,X             ; ALL TABLE ENTRY FROM
        SBC     ECSIZE          ; CON AT ADR TO HIMEM
        STA     0,X
        LDA     1,X
        SBC     ECSIZE+1
        STA     1,X
        INX
        INX
        CPX     #MEMTOP+2
        BCC     _CONT1
        STA     APHM+1          ; SET NEW APL
        LDA     MEMTOP          ; HI MEM TO
        STA     APHM            ; MEMTOP
;
        LDX     MVTA
;
        LDA     0,X             ;FORM MOVE TO ADR (MVTA)
        SBC     MVLNG           ; MVTA = NEW CON AT VALUE
        STA     MVTA            ; MINUS MVLNG (L)
        LDA     1,X             ; DURING MOVE MVLNG(L)
        SBC     #0              ; WILL BE ADDED BACK INTO
        STA     MVTA+1          ; MVTA IN (INO),Y INST
;
FMOVER
        LDX     MVLNG+1         ; GET MOVE LENGTH HIGH
        INX                     ; INC SO MOVE CAN BNE
        LDY     MVLNG           ; GET MOVE LENGTH LOW
        BNE     _CONT2          ; IF NOT ZERO GO
        DEX
        BNE     _CONT2
        RTS
;
_CONT3  INC     MVFA+1          ;INC MVFA(H)
        INC     MVTA+1          ; INC MVTA(H)
;
_CONT2  LDA     (MVFA),Y        ; GET MOVE FROM BYTE
        STA     (MVTA),Y        ; SET MOVE TO BYTE
        INY                     ; INCREMENT COUNT LOW
        BNE     _CONT2          ; BR IF NOT ZERO
;
_CONT4
        DEX                     ; DECREMENT COUNT HIGH
        BNE     _CONT3          ;BR IF NOT ZERO
        RTS                     ; ELSE DONE
        .PAGE   'EXECUTE DOS'
;
;
;
;
;       XDOS - EXECUTE DOS COMMAND
;
XDOS
        JMP     (DOSLOC)
        .PAGE    'EXECUTE DEBUG MONITOR START'
;
;       XATBUG - EXECUTE DEBUG
;       SET BREAK VECTOR
;
XATBUG
        LDY     #7              ; GET LARGEST DEVICE #
        JSR     CLALL7          ; CLOSE ALL DEVICES
BUG1
        LDA     #DMODE          ; SET DEBUG MODE
        STA     MODEFLG         ; X
        JMP     DSYN2
        .PAGE    'EXECUTE NUMBER'
;
;       XNUM - EXECUTE NUMBER COMMAND
;
XNUM
        LDA     #AUTON          ; TURN AUTO FLAG ON
        STA     AUTOFLG         ; X
;
        JSR     PNUM            ; SET UP NUMBER PARMS
        BCC     _NDONE          ; BR IF HAVE SLNO
;
;       ELSE SET UP DEFAULT SLNO
;
        LDA     #0              ; GET 1ST LINE #
        STA     TSLNUM          ; X
        STA     TSLNUM+1        ; X
        JSR     GETSTMT         ; X
;
;       FIND LAST LINE #
;
_NUM2
        JSR     TSTTEND         ; WERE THERE ANY STMTS?
        BCS     _NUM1           ; IF YES, AT END OF STMTS
;
        LDY     #0              ; X
        LDA     (STMCUR),Y      ; SAVE LINE #
        STA     TSLNUM          ;
        INY
        LDA     (STMCUR),Y      ;
        STA     TSLNUM+1        ;
        JSR     GETLL           ; GET NEXT LINE
        JSR     GNXTL           ;
;
        JMP     _NUM2
_NUM1
        CLC                     ; SET START LINE #
        LDA     TSLNUM          ; LAST LINE # + INCR
        ADC     LNINCR          ;
        STA     CURLN
        LDA     TSLNUM+1        ;
        ADC     LNINCR+1        ; X
        STA     CURLN+1
_NDONE
        RTS
        .PAGE
;
;       PNUM - SET UP PARMS FOR NUM & REN
;
;
PNUM
        LDA     #10             ; SET DEFAULT INCR
        STA     CURLN           ; AND START LINE #
        STA     LNINCR          ; X
        LDA     #0
        STA     CURLN+1         ; X
        STA     LNINCR+1        ; X
;
        JSR     GETCODE         ; GET TOKEN
        CMP     #CEOL           ; IS IT END OF LINE
        BEQ     _PSET           ; IF YES, DONE
;
;       ELSE HAVE AT LEAST 1 NUMBER
;
        JSR     GETCODE         ; SET # AS NEW INCR
        STA     LNINCR          ; X
        JSR     GETCODE         ; X
        STA     LNINCR+1        ; X
;
        JSR     GETCODE         ; GET NEXT CODE
        CMP     #CEOL           ; IS IT END OF LINE
        BEQ     _PSET           ; IF YES, DONE
;
        LDA     LNINCR          ; MOVE # TO START LINE #
        STA     CURLN           ; X
        LDA     LNINCR+1        ; X
        STA     CURLN+1         ; X
;
        JSR     GETC1           ; SKIP THEX  CODE
        STA     LNINCR          ; SET AS NEW INCR
        JSR     GETCODE         ; X
        STA     LNINCR+1        ; X
        CLC                     ; SET START LINE # FOUND
        RTS
_PSET
        SEC                     ; SET NEED DEFAULT SLNO
        RTS
        .PAGE    'EXECUTE RENUMBER'
;
;       XREN - EXECUTE RENUMBER COMMAND
;
XREN
        JSR     PNUM            ; SET UP RENUM PARMS
;
;       GET 1ST LINE
;
        LDA     #0
        STA     TSLNUM          ; SET LINE # TO FIND TO 0
        STA     TSLNUM+1        ; X
        JSR     GETSTMT         ; GET 1ST LINE ADDR
;
;
;       RENUMBER
_REN2
        JSR     TSTTEND         ; TST FOR END OF TEXT
        BCS     _REN3           ; IF AT END, THEN DONE
;
        LDY     #0              ; GET INDEX INTO LINE
        LDA     CURLN           ; SET LINE # = CURLN
        STA     (STMCUR),Y      ; Y
        LDA     CURLN+1         ; X
        INY                     ; X
        STA     (STMCUR),Y      ; X
;
        JSR     UPCUR           ; INCR CURLN
;
        JSR     GETLL           ; GET NEXT LINE
        JSR     GNXTL           ; X
        JMP     _REN2           ; REPEAT
        .PAGE    'EXECUTE DELETE'
;
;       XDEL - EXECUTE DELETE
;
XDEL
        JSR     LRANG1          ;SET UP LINE # RANGE
        BCC     DELC            ;IF 1ST LINE EXISTS, NO ERROR
;
        LDA     #ERNLN          ;ELSE PRINT ERROR
        JSR     EDERR
;
DELC
        JSR     TLEND           ;TEST FOR END OF LINE RANGE
        BCS     _DRTN
;
        JSR     DELLN           ;DELETE LINE
        JMP     DELC            ;REPEAT
;
_REN3
_DRTN
        RTS
        .PAGE    'EXECUTE PRINT'
;
;       XPRINT - EXECUTE PRINT
;
XPRINT
        LDA     #LNUMOFF        ; SET TYPE OF LIST
        JSR     LISTJN          ;DO LIST
WAITCR
        JSR     GLGO            ; WAIT FOR INPUT
        JSR     TSTBRK
        BNE     _XPDONE
        LDY     #0
        LDA     (INBUFF),Y
        CMP     #CR
        BNE     WAITCR
_XPDONE
        RTS
        .PAGE    'EXECUTE LIST'
;
;       XLIST - EXECUTE LIST (FOR EDITOR)
;
XLIST
        LDA     #LNUMON         ; SET TYPE OF LIST TO
LIST    =       *
LISTJN  STA     LTYPFLG         ; LIST LINE #
;
        LDA     #$7F
        STA     DSPFLG          ; SET NON-DISPLAY MODE
;
        JSR     PRCR            ; PRINT CARRIDGE RETURN
;
        JSR     GETCODE         ; GET TOKEN FROM OUTBUFF
        CMP     #CFILE          ; IS IT FILESPEC CODE?
        BNE     _LIST1          ; IF NOT, SKIP FILE HANDLING
;
;       OPEN FILE FOR LIST
;
        JSR     FLIST           ; HANDLE FILESPEC
;
        JSR     _LIST2          ; GO LIST
;
;       CLOSE DEVICE
;
        LDA     LISTDTD         ; GET LIST DEVICE #
        JSR     CLSYSD          ; GO CLOSE IT
;
        LDA     #SCRDV          ; RESET OUTPUT DEVICE TO SCREEN
        STA     LISTDTD         ; X
        RTS
        .PAGE
_LIST2
        JSR     GETCODE         ; GET NEXT TOKEN
        CMP     #CEOL           ; IS IT COMMA?
        BEQ     _LIST1          ; IF YES, BR
        JSR     GETCODE         ; GET NEXT CODE
_LIST1
        JSR     LRANGE          ; SET UP LINE # RANGE
;
;
LISTC
        JSR     TSTBRK          ;TEST FOR BREAK
        BNE     _LRTN           ; DONE IF BREAK
;
        JSR     TLEND           ;TEST FOR END OF LINE RANGE
        BCS     _LRTN           ; IF AT END, BR
_LGO
        JSR     LIST1           ; GO LIST ONE LINE
        JSR     TSTBRK          ; TEST FOR BRK
        BNE     _LRTN           ; IF BRK, RETURN
        JSR     GETLL           ; GET LINE LENGTH
        JSR     GNXTL           ;GET NEXT LINE ADDR
        JMP     LISTC           ; GO DO THIS ONE
_LRTN
        LDA     #0
        STA     DSPFLG          ; SET DISPLAY MODE
;
        RTS
        .PAGE
;
;       LIST1 - LIST ONE LINE
;
LIST1
        JSR     MOVLIN          ; MOVE LINE TO LBUFF
        JMP     INBOUT          ; OUTPUT DATA POINTED TO BY INBUFF
        .PAGE
;
;       MOVLIN - MOVE TEXT LINE POINTED TO BY STMCUR TO LBUFF
;
;
;       ON EXIT    OUTCNT - POINTS TO LAST BYTE OF OUTPUT
;
;
MOVLIN
        LDA     #0              ; SET # OF BYTES IN BUFFER TO ZERO
        STA     OUTCNT          ; X
        JSR     INTLBF          ; SET UP INBUFF
        LDA     LTYPFLG         ; GET LISTING TYPE FLAG
        BNE     MOVTXT          ; IF NOT 0, SKIP LINE # LIST
;
        LDY     #0              ; MOVE LINE # TO FR0
        LDA     (STMCUR),Y      ; X
        STA     FR0             ; X
        INY                     ; X
        LDA     (STMCUR),Y      ; Y
        STA     FR0+1           ; X
;
        JSR     IASC            ; CONVERT TO ASCII IN LBUFF
        JSR     INTLBF          ; RESET LBUFF
        LDY     #$FF            ; INIT INDEX INTO LBUFF
_MOVL
        INC     OUTCNT          ; INCR # BYTES IN BUFFER
        INY                     ; POINT NEXT BYTE
        LDA     (INBUFF),Y      ; GET BYTE
        BPL     _MOVL           ; IF MSB OFF, THEN MOVE BYTES
        AND     #$7F            ; AND OUT MSB
        STA     (INBUFF),Y      ; SAVE
;
;
;
;       MOVTXT - MOVE TEXT LINE POINTED TO BY
;               STMCUR TO LBUFF
;
MOVTXT
        LDY     #2              ; GET LINE LENGTH
        LDA     (STMCUR),Y      ; X
        SEC                     ; GET # OF CHARS TO MOVE
        SBC     #3              ; X
        TAX                     ; PUT IN X AS COUNTER
        STY     CIX             ; SET LINE INDEX
;
_LM1
        INC     CIX             ; GET CHAR FROM LINE
        LDY     CIX             ; X
        LDA     (STMCUR),Y      ; X
        LDY     OUTCNT          ; PUT IT IN BUFFER
        STA     (INBUFF),Y      ; X
        INC     OUTCNT          ; POINT TO NEXT BUFFER BYTE
        DEX
        BNE     _LM1
        RTS
        .PAGE
;
;       INBOUT - OUTPUT DATA POINTED TO BY INBUFF
;
;       ON ENTRY   INBUFF - POINTS TO DATA
;                  OUTCNT - LENGTH
;
INBOUT
        LDY     #0              ; GET INDEX
        STY     CIX             ; SAVE
_INB
        LDA     (INBUFF),Y      ; GET CHAR
        PHA
        JSR     PRCHAR          ; PRINT IT
        PLA
        INC     CIX             ; INCR INDEX
        LDY     CIX             ; GET INDEX
        CMP     #CR             ;ARE WE AT END ?
        BNE     _INB            ; IF NOT, DO AGAIN
        RTS
        .PAGE
;
;       STRMOV - MOVE STRING TO LBUFF AND PUT EOL AT END
;
;       ON ENTRY   A - LENGTH
;                  OUTBUF - CONTAINS STRING
;
STRMOV
        JSR     GETC2           ; GET LENGTH TO A-REG
        STA     ZT1             ; SAVE LENGTH
        LDX     #0              ; SET LBUFF DISPL
_STRM1
        JSR     GETCODE         ; GET A STRING CHAR
        STA     FNBUFF,X        ; STORE NAME BYTE
        INX                     ; INCR INDEX
        DEC     ZT1             ; DECR LENGTH
        BNE     _STRM1          ; LOOP IF NOT DONE
;
        LDA     #CR             ; GET CARRRIDE RETURN
        STA     FNBUFF,X        ; END OF NAME STRING
        RTS
        .PAGE
;
;       LRANGE - SET UP LINE # RANGE
;
;                  A - CONTAINS 1ST TOKEN IN LINE RANGE
;                  OUTBUFF - CONTAINS COMMAND
;
LRANG1
        JSR     GETCODE         ;GET 1ST TOKEN
LRANGE
;
;       SET DEFAULT RANGE
;
        LDY     #0              ; SET TABLE SEARCH LINE
        STY     TSLNUM          ; NUMBER TO ZERO
        STY     TSLNUM+1        ; X
        DEY
        STY     LELNUM          ; SET LAST LIST LINE # TO MAX
        STY     LELNUM+1        ; X
;
;       GET 1ST LINE
;
        CMP     #THEX2          ; IS CHAR = NUMBER CODE
        BNE     _LRAN3          ; IF NOT, THEN NO LINE RANGE
;
        JSR     GETCODE         ;GET STARTLINE # FROM COMMAND LINE
        STA     TSLNUM
        STA     LELNUM          ; SET LAST LINE # = 1ST
        JSR     GETCODE         ; X
        STA     TSLNUM+1        ; X
        STA     LELNUM+1        ; X
;
;       SET UP LAST LINE #
;
        JSR     GETCODE         ; GET NEXT PARM
        CMP     #CEOL           ;IS IT EOL ?
        BEQ     _LRAN3          ; IF EQUAL, THEN HAVE LAST LINE # = 1ST
_LRAN2
        JSR     GETCODE         ; GET NEXT TOKEN
        CMP     #THEX2          ; IS IT # CODE
        BNE     _LRAN4          ; IF NOT, LINE RANGE COMPLETE
        JSR     GETCODE
        STA     LELNUM
        JSR     GETCODE         ; X
        STA     LELNUM+1        ; X
        JMP     _LRAN1
_LRAN4
        DEC     COX
_LRAN3
        DEC     COX             ; BACK UP
_LRAN1
        JMP     GETSTMT         ; GET ADDR OF 1ST LINE
        .PAGE
;
;       GETCODE - GET TOKEN FROM OUTPUT
;
;       GETC1 - INCR 1 AND GET TOKEN
;
;       GETC2 - INCR 2 AND GET TOKEN
;
GETC3
        INC     COX
GETC2
        INC     COX
GETC1
        INC     COX
GETCODE
        LDY     COX             ; GET INDEX
        INC     COX             ; INCR INDEX
        LDA     (OUTBUFF),Y     ; GET CHAR
        RTS
;
;
;
;
;
;
;       GETIN - GET NEXT CHAR FROM INBUFF
;
GETIN
        LDY     CIX
        LDA     (INBUFF),Y
        INC     CIX
        RTS
        .PAGE    'EXECUTE FIND & REPLACE'
;
;       XREP - EXECUTE FIND
;
XREP
        JSR     INCPST          ; INCR PAST STRING 1
        BEQ     _FDONE          ; IF STR1 NULL, THEN DONE
        STA     STR1LNG         ; SAVE LENGTH OF STRING 1
        JSR     INCPST          ; INCR PAST STRING 2
        STA     STR2LNG         ; SAVE LENGTH
;
        LDA     #REPON          ; GET REPLACE FLAG
        BNE     _FR             ;
;
;
;
;       XFIND -  EXECUTE FIND
;
XFIND
        JSR     INCPST          ; INCR PAST STR
        STA     STR1LNG         ; SAVE STRING LENGTH
;
;
        LDA     #FINDON         ; GET FIND FLAG
_FR
        STA     REPFLG          ; SET FLAG
        JSR     FRINIT          ; DO INIT
;
;       DO FIND
;
FINDC
        JSR     TSTBRK          ;IF BREAK BIT,
        BNE     _FDONE          ; WE ARE DONE
;
        JSR     TLEND           ; ARE WE AT END OF LINES?
        BCS     _FDONE          ; IF YES, THEN DONE
;
        LDY     #3              ; INIT LINE INDEX
        STY     LINDEX          ; X
_FIND2
        JSR     LSEARCH         ; SEARCH LINE FOR STR
        BCS     _FIND1          ; IF NOT FOUND SEARCH NEEXT LINE
;
        LDA     REPFLG          ; ARE WE DOING REPLACE?
        BNE     CKREP           ; IF YES GO DO IT
;
        JSR     LIST1           ; ELSE, LIST LINE
        LDA     AQ1FLG          ; GET OCCURENCE FLAG
        BEQ     _FDONE          ; IF SET FOR 1ST OCCURENCE THEN DONE
;
_FIND1
        JSR     GETLL           ; GET NEXT LINE
        JSR     GNXTL           ; X
        JMP     FINDC
_FDONE
        RTS
        .PAGE
;
;
;
CKREP
        LDA     AQ1FLG          ; GET FLAG
        BPL     DOREP           ; IF QUERRY NOT SET, SKIP
;
;       QUERRY FOR REPLACE
;
QUERRY
        JSR     LIST1           ; LIST LINE
_Q1
        LDA     #'?             ; GET TEMP PROMPT
        JSR     PRCHAR          ; PRINT PROMPT
        JSR     GLGO            ; GET A LINE
        JSR     TSTBRK
        BEQ     _Q2
        JMP     ESYN2
_Q2
;
        LDY     #0              ; GET 1ST CHAR
        LDA     (INBUFF),Y      ; X
        CMP     #CDO            ; IS IT CHAR FOR REPLACE
        BEQ     DOREP           ; IF YES, GO DO REPLACE
;
        CMP     #CNODO          ; IS IT CHAR FOR NO REPLACE
        BNE     _Q1             ; IF NOT, REPEAT QUERRY
        INC     LINDEX          ; INCR PAST STARTOF STRING
        BNE     _FIND2          ; IF YES, SEARCH REST OF LINE
;
;
DOREP
;
;       SET NEW LINE LENGTH
;
        LDA     STR1LNG         ; GET CONTRACT/EXPAND LENGTH
        SEC
        SBC     STR2LNG         ; X
;
;       LINLNG = LINLNG - (STR1LNG - STR2LNG)
;
        STA     ZT1
        LDA     LINLNG
        SEC
        SBC     ZT1
        LDY     #2
        STA     (STMCUR),Y
;
;       SAVE STMCUR
;
        LDA     STMCUR
        PHA
        LDA     STMCUR+1
        PHA
;
;       POINT TO END OF STRING IN LINE
;       (STMCUR = STMCUR + LINDEX)
;
        LDA     #0              ; IF STRING 2 IS NULL, SET CARRY
        CMP     STR2LNG         ; TO ADD 1 FOR CONTRACT
        LDA     LINDEX
        JSR     GNXTL1
;
;       EXPAND OR CONTRACT
;
        LDA     ZT1             ; GET DIFFERENCE
        PHA                     ; SAVE DIFFERENCE
        BEQ     _REP            ; DO REPLACE (OLD=NEW)
        BPL     _RCON           ; CONTRACT (OLD>NEW)
;
;
;
        JSR     EXPTXT          ; ELSE EXPAND (OLD<NEW)
        JMP     _REP            ; GO REPLACE
;
_RCON
        JSR     CONTXT          ; CONTRACT
;
_REP
;
;       SET NEW LINE INDEX = END OF NEW STRING
;
        PLA                     ; GET DIFFERENCE
        STA     ZT1             ; GET NEW LINE INDEX
        LDA     LINDEX          ; X
        SEC                     ; X
        SBC     ZT1             ; X
        STA     LINDEX          ; X
        INC     LINDEX          ; INCR LINE INDEX
;
;       RESTORE STMCUR
;
        PLA
        STA     STMCUR+1
        PLA
        STA     STMCUR
;
;       MOVE IN NEW STRING
;       TVS CIX - START OF STRING IN LINE
;
        LDA     #0              ; SET OUTBUF INDEX TO ZERO
        STA     COX             ; X
        JSR     INCPST          ; INCR OVER STR1
;
        JSR     GETC2           ; INC COX TO START OF STR2
        TAX                     ; GET STR2 LEN AS COUNTER
        BEQ     _REP3           ; IF STR2 IS NULL, THEN CR
        INC     TVSCIX          ; POINT TO STRAT OF REPLACED STR
_REP2
        LDY     COX             ; GET REPLACEMENT CHAR
        LDA     (OUTBUFF),Y     ; X
        LDY     TVSCIX          ; PUT IN LINE
        STA     (STMCUR),Y      ; X
        INC     COX             ; INCR OUTBUF POINTER
        INC     TVSCIX          ; INCR LINE POINTER
        DEX                     ; DEC COUNT
        BNE     _REP2           ; IF MORE TO DO, DO IT
;
_REP3
        LDA     AQ1FLG          ; GET OCCURENCE FLAG
        BEQ     _NFND           ; IF SET TO 1 THEN DONE
        JMP     _FIND2          ; SEARCH REST OF LINE
        .PAGE
;
;       LSEARCH - SEARCH LINE IN LBUFF FOR STRING
;
;       ON EXIT    CARRY CLEAR - IF MATCH FOUND
;                  CARRY SET IF NO MATCH FOUND
;
;
;
LSEARCH
        JSR     GETLL           ; GET LINE LENGTH
        STA     LINLNG          ; SAVE IT
        DEC     LINDEX          ; INIT LINE INDEX
;
_LS1
        LDY     #2              ; INIT POINTER TO START OF STRING-1
        STY     COX
        LDA     LINDEX          ; SAVE (IF MATCH, THIS IS START OF STRING-1
        STA     TVSCIX          ; X
;
_LS2
        INC     COX             ; POINT TO NEXT STRING CHAR
        LDY     COX             ; X
        CPY     STRDEX          ; ARE WE AT END OF LINE
        BCS     _FND            ; IF YES, WE FOUND IT
;
        LDA     (OUTBUFF),Y     ; GET STRING CHAR
;
;
        INC     LINDEX          ; INCR LINE POINTER
        LDY     LINDEX          ; GET INDEX
        CPY     LINLNG          ; ARE WE AT END OF LINE
        BCS     _NFND           ; IF YES, NO MATCH FOUND
;
        CMP     (STMCUR),Y      ; DOES STR CHAR = LINE CHAR?
        BEQ     _LS2            ; IF = TRY NEXT STR CHAR FOR MATCH
        LDY     TVSCIX          ; GET OLD POSITION IN LINE
        INY                     ; INCR ONE CHARACTER
        STY     LINDEX          ; SET AS CURRENT POSITION IN LINE
        BNE     _LS1            ; BR ALWAYS
;
_FND    CLC                     ; CLEAR FOR FOUND
;
_NFND
        RTS
        .PAGE
;
;       FRINIT - INIT FOR FIND AND REPALCE
;
FRINIT
        JSR     LRANG1          ; SET UP LINE RANGE
;
;       SET ALL OR 1ST OCCURENCE OR QUERRY
;
        JSR     GETCODE         ; GET THE TOKEN
        CMP     #CEOL           ; IF AT END OF LINE
        BEQ     _SET1           ; THEN SET 1ST OCCURENCE
        JSR     GETCODE
        LDX     #SETQ           ; SET FOR QUERRY
        CMP     #CA             ; IS IT A?
        BNE     _SETIT          ;
_SETA
        LDX     #SETA           ; SET ALL OCCURENCES
        BPL     _SETIT
;
_SET1
        LDX     #SET1           ; SET 1ST OCCURENCE
_SETIT
        STX     AQ1FLG          ; SET Q, A OR 1ST
;
        LDA     #LNUMON         ; SET LIST TYPE FOR LINE#'S
        STA     LTYPFLG         ; X
;
        LDX     STR1LNG         ; GET STRING LENGTH
        INX                     ; POINT TO END OF STRING IN OUTBUFF
        INX                     ; X
        INX                     ; X
        STX     STRDEX          ; SAVE AS FOR END OF STR TEST
        RTS
        .PAGE
;
;       INCPST - INCREMENT OUTPUT INDEX PAST STRING
;
;       ON EXIT    A - CONTAINS LENGTH
;
INCPST
        JSR     GETC2           ; GET LENGTH
        PHA                     ; SAVE IT
        CLC                     ; POINT PAST STRING
        ADC     COX             ; X
        STA     COX             ; X
        PLA                     ; GET LENGTH
        RTS
        .PAGE    'EXECUTE STATUS'
;
;       XSIZE -
;
XSIZE
        LDA     LOMEM           ; PRINT LOMEM
        LDY     LOMEM+1         ; X
        JSR     PRHEX2          ; X
;
        JSR     PRBLK3          ; PRINT BLANKS
;
        LDA     TXTEND          ; PRINT TOP OF TEXT ADDR
        LDY     TXTEND+1        ; X
        JSR     PRHEX2          ; X
;
        JSR     PRBLK3          ; PRINT BLANKS
;
        LDA     HIMEM           ; PRINT HIGH MEM
        LDY     HIMEM+1         ; X
        JSR     PRHEX2          ;
;
        JMP     PRCR
        .PAGE    'EXECUTE LOMEM'
;
;       XLOMEM - SET LOW MEM
;
XLOMEM
        LDA     LOMFLG          ; IS LOW MEM COMMAND VALID
        BNE     _LMERR          ; IF NOT, ERROR
;
        JSR     GETC1           ; GET VALUE LOW
        STA     LMSAV           ; SET NEW LOW MEM
        JSR     GETCODE         ; X
        STA     LMSAV+1
        JMP     XNEW            ; SET UP TABLE PTRS
;
_LMERR
        LDA     #ERLMEM
        JSR     ERROR
        .PAGE    'EXECUTE ENTER'
;
;       XENTER - EXECUTE ENTER
;
XENTER
        JSR     FLOAD2          ; HANDLE FILESPEC
        JSR     GETCODE         ; GET NEXT CODE
        CMP     #CEOL           ; IS IT EOL?
        BNE     _NCLR           ; IF NOT, DON'T CLEAR
        JSR     XCLR            ; ELSE CLEAR
;
_NCLR
        JMP     ESYNTAX
        .PAGE    'EXECUTE LOAD OBJECT'
;
;       XLOAD - EXECUTE LOAD
;
XLOAD
        JSR     FLOAD2          ; OPEN ENTER DEVICE
;
        JSR     GOBJ            ; CHECK THE 2 LOAD CHARACTERS
        CMP     #LCHK1
        BNE     __LERR
        JSR     GOBJ
        CMP     #LCHK2
        BNE     __LERR
;
_LOAD2
        JSR     GOBJ            ; GET OBJECT
        STA     MVFA
        JSR     GOBJ
        STA     MVFA+1
        JSR     GOBJ            ; GET END ADDR FROM FILE
        STA     MVFEA
        JSR     GOBJ
        STA     MVFEA+1
_LOAD
        JSR     FAGET           ; TEST ADDRS
        BCS     _LOAD2          ; AT END OF FIRST SEGMENT?
        JSR     GOBJ            ; GET BYTE
        LDY     #0              ; SAVE IT
        STA     (MVFA),Y
        JSR     INCMVF          ; INC ADDR
        JMP     _LOAD
;
;
;
_LEOF
        LDX     ENTDTD          ; CLOSE FILE
_LEOF1
        STX     IODVC
        JMP     CLSYSD
;
;;
__LERR  LDA     #ERLOAD
        JSR     ERROR
;
        .PAGE
;
;
;       GOBJ - GET BYTE FROM OBJECT FILE
;
;       ON EXIT    A - OBJECT BYTE
;
;                  CC = 0 IF END OF FILE
;                  CC NOT = 0 IF NOT END OF FILE
;
GOBJ
        LDX     ENTDTD          ; GET A BYTE
        LDA     #ICGBC          ; X
        JSR     GPCHAR          ; X
        BEQ     _LEOF           ; BR IF EOF
        LDY     #0
        LDA     (INBUFF),Y
        LDX     #$FF            ; SET NOT = FLAG
_GOBJ
        RTS
        .PAGE    'EXECUTE SAVE OBJECT'
;
;       XSAVE - EXECUTE SAVE OBJECT
;
XSAVE
        INC     COX             ; INCR OUTPUT INDEX
        JSR     FOBJ            ; OPEN OBJECT FILE
        JSR     GETC1           ; POINT TO START OF ADDR
        JSR     FADR            ; SET UP MOVE TO & MOVE FROM ADDR
;
        LDA     #LCHK2          ; WRITE LOAD CHECK CHAR FILL
        LDX     #LCHK1          ; X
        JSR     HPUTO2
;
        LDA     MVFA+1          ; OUTPUT START ADDR
        LDX     MVFA            ; X
        JSR     HPUTO2
        LDA     MVFEA+1         ; OUTPUT END ADDR
        LDX     MVFEA           ; X
        JSR     HPUTO2
_SAVE
        JSR     FAGET2          ; GET BYTE
        BCS     _SEOF           ; IF AT EOF, BR
;
        LDX     OBJDTD          ; OUTPUT BYTE TO OBJECT FILE
        LDA     #ICPBC
        JSR     GPCHAR
        JMP     _SAVE           ; REPEAT
;
;
_SEOF
        LDX     OBJDTD          ; CLOSE FILE
        BNE     _LEOF1
        .PAGE
;
;       TLEND - TEST FOR END OF LINE RANGE
;
;       ON EXIT    CARRY SET IF AT END
;                  CARRY CLEAR IF NOT
;
;
TLEND
        JSR     TSTTEND
        BCS     _TLN
        JSR     TSTLST
_TLN
        RTS
        .PAGE
;
;       TSTTEND - TEST TO SEE IF WE ATE AT END OF TEXT
;
;       ON EXIT    CARRY SET IF AT END OF TABLE
;                  CARRY CLEAR IF NOT
TSTTEND
        LDA     STMCUR+1        ;GET CURRENT STMT ADDR HIGH
        CMP     TXTEND+1        ; CMP TO END OF TXT HIGH
        BCC     _TPASS          ; IF < THEN RETURN PASS
        BNE     _TFAIL          ; IF NOT = THEN RETURN FAIL
;                                 ELSE TEST LOW ORDER BYTE
        LDA     STMCUR
        CMP     TXTEND
_TPASS
_TFAIL
        RTS
        .PAGE
;
;       TSTLST - TEST TO SEE IF WE ARE PAST LAST LINE #
;
;       ON EXIT    CARRY SET IF PAST LAST LINE #
;                  CARRY CLEAR IF NOT
;
;
TSTLST
        LDY     #1              ;COMP CURRENT STMT #
        LDA     (STMCUR),Y      ; WITH LAST LINE #
        CMP     LELNUM+1        ; IF CUR <= LAST
        BCC     _LEND           ; THEN RETURN PASS
        BNE     _LEND           ; ELSE RETURN FAIL
        DEY                     ; X
        LDA     (STMCUR),Y      ; X
        CMP     LELNUM          ; X
        BEQ     _LPASS          ; IF = THEN PASS
_LEND
        RTS
_LPASS
        CLC
        RTS
        .PAGE    'EXECUTE DISPLAY'
;
;       XD - EXECUTE DISPLAY
;
XD
;
;       SET DEFAULT START AND END ADDR
;       (DEFAULT START ALREADY SET)
;
;
        JSR     SDEND           ; SET DISPLAU END ADDR
;
        JSR     GETCODE         ; GET TOKEN
        CMP     #CEOL           ; IS IT EOL?
        BEQ     _D3             ; IF YES, S&E ADDRS DONE
;
;       GET NEW START & DEFAULT END ADDR
;
;
        JSR     GETCODE         ; GET START ADDR FROM LINE
        STA     DSADR
        JSR     GETCODE
        STA     DSADR+1
;
        JSR     SDEND           ; SET DEFAULT END
;
        JSR     GETCODE         ; GET TOKEN
        CMP     #CEOL           ; IS IT EOL
        BEQ     _D3             ; IF YES, S&E ADDRS DONE
;
;       GET END ADDRS
;
        JSR     GETC1           ; GET END ADDR FROM LINE
        STA     DEADR           ; X
        JSR     GETCODE
        STA     DEADR+1         ; X
_D3
;
;       SAVE START ADDR FOR CHANGE
;
        LDA     DSADR
        STA     CSADR
        LDA     DEADR+1
        STA     CSADR+1
        .PAGE
;
;       PRINT START ADDR
;
_D1
        JSR     PRCR            ; PRINT CARRIDGE RETURN
;
        LDA     DSADR
        LDY     DSADR+1
        JSR     PRADRB          ; PRINT ADDR + BLANK
;
_D2
        LDY     #0              ; GET DATA BYTE
        LDA     (DSADR),Y       ; X
        JSR     PRHEXB          ; PRINT # & BLANKS
;
;
        JSR     TSTBRK          ; IF BREAK
        BNE     _DDONE          ; THEN END
;
        LDA     DSADR+1         ; GET CURRENT ADDR FOR END TEST
        LDY     DSADR
;
;       INCR TO NEXT ADDR
;
        INC     DSADR           ; GET NEXT ADDR
        BNE     _D5             ; X
        INC     DSADR+1         ; X
_D5
;
;       TEST FOR END
;
        CMP     DEADR+1         ; IF ADDR FOR INCR IS
        BNE     _D4             ; = TO END ADDR
        CPY     DEADR           ; THEN DONE
        BEQ     _DDONE
;
_D4
;
        LDA     DSADR           ; IF ADDR ENDS IN 0 OR 8
        LSRA                    ; THEN PRINT ADDR AGAIN
        BCS     _D2             ; ELSE PRINT NEXT DATA
        LSRA
        BCS     _D2
        LSRA
        BCS     _D2
        BCC     _D1
;
;
;
_DDONE
        RTS
        .PAGE
;
;       SDEND - SET DISPLAY END ADDR
;
;       ENDADDR = START ADDR +7
;
SDEND
        CLC
        LDA     DSADR
        ADC     #7
        STA     DEADR
        LDA     DSADR+1
        ADC     #0
        STA     DEADR+1
        RTS
        .PAGE    'EXECUTE DISPLAY OR CHANGE REGISTERS'
;
;       XDR - EXECUTE DISPLAY REGISTERS
;
XDR
        JSR     PRBLK3          ; PRINT BLANKS
        LDX     #0              ; INITIALIZE
_XDRLP
        STX     ZT1             ; UPDATE CNTR
        LDA     XDRCH,X         ; GET REG. NAME CHAR.
        JSR     PRCHAR          ; PRINT IT
        LDA     #'=
        JSR     PRCHAR          ; PRINT "="
        LDX     ZT1
        LDA     URA,X           ; GET...
        JSR     PRHEXB          ; ...& PRINT REG VALUE
        LDX     ZT1
        INX                     ; BUMP CNTR
        CPX     #5              ; DONE?
        BNE     _XDRLP          ; NO
        RTS                     ; YES
;
XDRCH   .BYTE   'AXYPS'
;
;
;
;
;
;
;       XCR - EXECUTE CHANGE REGISTER
;
XCR
        LDA     #.LOW.UREG      ; SET CHANGE ADDR TO POINT
        STA     CSADR           ; TO USER'S REGISTER'S
        LDA     #.HIGH.UREG     ; X
        STA     CSADR+1         ; X
        BEQ     _C3             ; JOIN CHANGE
        .PAGE    'EXECUTE CHANGE'
;
;       XC - CHANGE DATA IN MEMORY
;
XC
        JSR     GETCODE         ; GET 1ST TOKEN
        CMP     #THEX2          ; IS ADDR PRESENT
        BNE     _C2             ; IF NOT, USE CURRENT ADDR
;
        JSR     GETCODE         ; ELSE GET START ADDR FROM LINE
        STA     CSADR           ; X
        JSR     GETCODE         ; X
        STA     CSADR+1         ; X
_C3
        INC     COX             ; POINT TO DATA TOKEN
_C2
        JSR     TSTBRK          ; IF BREAK BIT
        BNE     _CDONE          ; THEN DONE
        JSR     GETCODE         ; GET TOKEN
_C1
        CMP     #CEOL           ; IS IT EOL?
        BEQ     _CDONE          ; IF YES, WE'RE DONE
        CMP     #CCOM           ; IS IT COMMA?
        BNE     _C4             ; IF NOT, DO CHANGE
;
        JSR     UPCADR          ; UPDATE CHANGE ADDR
        JMP     _C2
;
_C4
;
        JSR     GETCODE         ; GET DATA LOW
        LDY     #0              ; STORE IN MEMORY
        STA     (CSADR),Y       ; X
        JSR     GETCODE         ; GET DATA HIGH
        BEQ     _C2             ; IF =0 THEN REPEAT
;
;
;
;
_CERR
        JSR     VERROR          ; DO ERROR HANDLING
;
;
;
_CDONE
UPCADR
;
;       UPDATE CHANGE ADDR
;
        LDA     CSADR           ; INCR ADDR BY 1
        CLC                     ; X
        ADC     #1              ; X
        STA     CSADR           ; X
        LDA     CSADR+1         ; X
        ADC     #0              ; X
        STA     CSADR+1         ; X
;
        RTS
        .PAGE    'EXECUTE EXIT'
;
;       XX - RETURN TO EDITOR
;       ?? RESET BREAK VECTOR
;
XX
        LDA     #EMODE          ; RESET TO EDIT MODE
        STA     MODEFLG         ; X
;
        JMP     ESYN2           ; GO TO EDITOR
        .PAGE    'EXECUTE GO'
;
;       XG - EXECUTE GO
;
XG
        JSR     SETUPC          ; SET PROGRAM COUNTER
;
_GO
;
;       SET UP TO HANDLE BREAK KEY
;
BRKINIT
        LDY     #.LOW.TPVBLK    ; GET ROUTINE ADDR LOW
        LDX     #.HIGH.TPVBLK   ; GET ROUTINE ADDR HIGH
        LDA     #7              ;
        JSR     SETBVB          ; SET ROUTINE ADDR TO USE AT VERT. BLANK
;
;       SET UP BREAK VECTOR
;
        LDA     #.LOW.VBRKG
        STA     BRKVEC
        LDA     #.HIGH.VBRKG
        STA     BRKVEC+1
;
;       RESTORE REGISTERS
;
        LDY     URY
        LDX     URS
        TXS
        LDX     URX
        LDA     URP
        PHA
        LDA     URA
        PLP
;
        JMP     (UPC)
        .PAGE
;
;       VERTICAL BLANK ROUTINE USED DURING GO
;        - READS BREAK FLAG AND SIMULATE BREAK
;
TPVBLK
        LDA     BRKBYT          ; BREAK KEY HIT?
        BEQ     TPVB1           ; IF YES, GO SIMULATE BREAK
        JMP     XITVBV          ; ELSE EXIT VERT. BLANK
;
;       SIMULATE BREAK (OS ROUTINE HAS PUT ADDR ON STACK)
;
TPVB1
        LDA     #$80            ; SET BREAK KEY FLAG(KEY HAS BEEN READ)
        STA     BRKBYT          ; RESET DEF. VERT. BLANK FROM TEMPORARY
        JSR     RSTVB           ; TO NORMAL VECTOR
        TSX
        TXA
        CLC
        ADC     #5
        TAX
        LDA     $100,X          ; INCR PROGRAM COUNTER
        CLC                     ; UP TWO LOCATIONS TO SIMULATE BRK
        ADC     #2
        STA     $100,X
        INX
        LDA     $100,X
        ADC     #0
        STA     $100,X
        PLA
        TAY                     ; RESTORE REGISTERS
        PLA
        TAX
        PLA
        PLP                     ; IRQ VECTOR FOR FINAL SYSTEMS
        PHP                     ; CHANGE TO JUMP ($216) FOR
        JMP     ($FFFE)         ; DEVELOPMENT SYSTEMS
        .PAGE    'EXECUTE STEP AND TRACE'
;
;       XS - EXECUTE STEP
;
XS
        JSR     SETUPC          ; GET PROGRAM COUNTER
        JSR     STEP            ; EXECUTE ONE INST.
        JMP     DSYN2           ; RETURN TO DEBUG
;
;
;
;
;
;
;       XT - EXECUTE TRACE
;
XT
        JSR     SETUPC          ; GET PROGRAM VCOUNTER
_TI
        JSR     STEP            ; EXECUTE ONE INST.
        JSR     PRCR
        JSR     TSTBRK          ; IF BREAK WAS NOT HIT
        BEQ     _TI             ; THEN CONTINUE
        JMP     DSYN2           ; RETURN TO DEBUG
        .PAGE
;
;       STEP    EXECUTE A SINGLE INST.
;
;       ON ENTRY   UPC - ADDR OF NEXT INST.
;
STEP
        LDA     #.LOW.VBRK      ; SET BREAK VECTOR
        STA     BRKVEC
        LDA     #.HIGH.VBRK
        STA     BRKVEC+1
        PLA                     ; SAVE RETURN ADDR
        STA     RTNADR          ; X
        PLA                     ; X
        STA     RTNADR+1        ; X
        CLD                     ; CLEAR DECIMAL MODE
;
        LDA     UPC             ; SET UP DISASSEMBLED ADDR
        STA     LSADR           ; X
        LDY     UPC+1           ; X
        STY     LSADR+1         ; X
;
        JSR     DISASM          ; DISASSEMBLE 1 INST.
        LDA     STENUM          ; WASTING AN INVALID INST
        CMP     #CDUM
        BEQ     RSTEP2
;
        LDY     #0              ; GET OP CODE
        LDA     (UPC),Y         ; X
        CMP     #$4C            ; IS IT JMP
        BEQ     XJMP            ; IF YES GO DO IT
        CMP     #$6C            ; IS IT IND JMP
        BEQ     XIJMP           ; IF YES, GO DO IT
        PHA                     ; SAVE OP CODE
        ASLA                    ; SHIFT OUT LEFT DIGIT
        ASLA
        ASLA
        ASLA
        BNE     NOROP           ; HANDLE NORMAL OP
;
;       OTHER SPECIAL CASE OP CODES
;
        PLA                     ; GET OP CODE
        TAX                     ; SAVE FOR BR INST.
        LSRA                    ; GET LEFT DIGIT *2
        LSRA
        LSRA
        TAY
        LDA     SPTAB+1,Y       ; GET ROUTINE ADDR
        PHA                     ; FOR SPECIAL OPS
        LDA     SPTAB,Y
        PHA
        RTS                     ; GO DO IT
        .PAGE
;
;       NORMAL OP CODES
;
NOROP
        PLA
NOROP1
        JSR     EXINIT          ; INIT EXECUTION BUFFER
        LDY     ILEN            ; GET INST. LENGTH
        DEY
_NOR
        LDA     (UPC),Y         ; MOVE INST TO EXBUFF
        STA     (EXBUFF),Y      ; X
        DEY
        BPL     _NOR            ; X
;
_NOR2
        LDY     URY             ; RESTORE USER REGS
        LDX     URS
        TXS
        LDX     URX
        LDA     URP
        PHA
        LDA     URA
        PLP
        JMP     (EXBUFF)
        .PAGE
RSTEP
;
;       SAVE USERS REGISTERS
;
        STA     URA             ; SAVE A
        STX     URX             ; X
        STY     URY             ; SAVE Y
        PHP                     ; SAVE STATUS
        PLA
        STA     URP
RSTEP0
        TSX                     ; SAVE STACK POINTERS
        STX     URS
;
;       UPDATE USER PC
;
RSTEP2
        LDA     LSADR
        STA     UPC
        LDA     LSADR+1
        STA     UPC+1
;
RSTEP1
        CLD                     ; CLEAR DECIML MODE
        JSR     XDR             ; PRINT USER REGS
;
        LDA     RTNADR+1
        PHA                     ; RETURN TO CALLER
        LDA     RTNADR
        PHA
        RTS
        .PAGE
;
;       SPECIAL CASE OPS CODES
;
XJSR
        LDX     URS             ; GET USER'S STACK PTR
        TXS
        CLC                     ; PUT RETURN ADDR ON STACK
        LDA     #2
        ADC     UPC
        TAX
        LDA     #0
        ADC     UPC+1
        PHA
        TXA
        PHA
        TSX
        STX     URS             ; SAVE NEW STACK PTR
;
;
;;
;
XJMP
        JSR     GJADR           ; GET JUMP ADDR
;
        JMP     RSTEP1
;
;
;
;
XIJMP
        JSR     GJADR           ; GET INDERICT ADDR
        LDY     #0
        JSR     GJADR1
        JMP     RSTEP1          ; GO DO IT
;
;
;
;
XRTI
        LDX     URS             ; GET USER'S STACK PTR
        TXS
        PLA                     ; GET STATUS FROM STACK
        STA     URP
        TSX                     ; SET NEW STACK
        STX     URS
;
;
;
;
XRTS
        LDX     URS             ; GET USER'S STACK PTR
        TXS
        CLC                     ; PUT RETURN ADDR+1
        PLA                     ; FROM STACK INTO
        ADC     #1              ; USER PC
        STA     UPC
        PLA
        TSX
        STX     URS             ; SET USER'S STACK PTR
        ADC     #0
        STA     UPC+1
        JMP     RSTEP1
;
;
;
;
XBRK
        JMP     (UPC)
;
;       BRANCH INST.
;
;
XBR
        JSR     EXINIT          ; INIT EXECUTION BUFFER
        TXA                     ; GET OP CODE
        LDY     #0              ; PUT IN EXEC. BUFFER
        STA     (EXBUFF),Y
        INY                     ; SET BR PASS DISPL
        LDA     #4              ; X
        STA     (EXBUFF),Y
;
        LDA     #$4C            ; SET UP FOR BR PASS
        LDY     #06
        STA     (EXBUFF),Y
        LDA     #.LOW.XBR1
        INY
        STA     (EXBUFF),Y
        LDA     #.HIGH.XBR1
        INY
        STA     (EXBUFF),Y
;
        JMP     _NOR2
;
;
XBR1
        LDY     #1              ; GET BR DISPL FROM
        LDA     (UPC),Y         ; USER'S CODE
;
        CLD
        JSR     CREL            ; CALC BR ADDR
        STA     UPC+1           ; SET NEW ADDR
        STX     UPC
;
        JMP     RSTEP1
        .PAGE
;
;       EXINIT - INIT EXECUTION BUFFER
;
EXINIT
        LDY     #1
        LDA     #$EA            ; PAD EXBUFF WITH NOP
        STA     (EXBUFF),Y      ; X
        INY
        STA     (EXBUFF),Y
        INY
        LDA     #$4C            ; PUT IN RETURN JUMP
        STA     (EXBUFF),Y
        INY
        LDA     #.LOW.RSTEP
        STA     (EXBUFF),Y
        LDA     #.HIGH.RSTEP
        INY
        STA     (EXBUFF),Y
        RTS
        .PAGE
;
;       SETUPC - GET NEW PROGRAM COUNTER FROM COMMAND BUFFER
;
SETUPC
        JSR     GETCODE         ; GET NEXT CODE
        CMP     #CEOL           ; IS IT END OF LINE
        BEQ     _GPC            ; IF YES, USE CURRENT PC
        JSR     GETCODE         ; ELSE, GET ADDR INTO PC
        STA     UPC
        JSR     GETCODE
        STA     UPC+1
_GPC
        RTS
;
;
;
;
;       GJADR - GET JUMP ADDRESS
;
GJADR
        LDY     #1              ; GET ADDR POINTED TO BY UPC
GJADR1
        LDA     (UPC),Y
        TAX
        INY
        LDA     (UPC),Y
        STA     UPC+1           ; AND SAVE AS NEW UPC
        STX     UPC
        RTS
        .PAGE
;
;       SPTAB - ROUTINES FOR SPECIAL CASE OPS
;
SPTAB
        .WORD   XBRK-1          ; BRK
        .WORD   XBR-1           ; BPL
        .WORD   XJSR-1          ; JSR
        .WORD   XBR-1           ; BMI
        .WORD   XRTI-1          ; RTI
        .WORD   XBR-1           ; BVC
        .WORD   XRTS-1          ; RTS
        .WORD   XBR-1           ; BVS
        *=*+2
        .WORD   XBR-1           ; BCC
        .WORD   NOROP1-1        ; NORMAL OP
        .WORD   XBR-1           ; BCS
        .WORD   NOROP1-1        ; CPY #
        .WORD   XBR-1           ; BNE
        .WORD   NOROP1-1        ; NORMAL OP
        .WORD   XBR-1           ; BEQ
        .PAGE
;
;       VBRKG - BREAK VECTOR FOR SOFTWARE BREAK
;
;       ENTERED HERE IF GET SOFTWARE BREAK OR
;       HIT BREAK KEY DURING GO
;
VBRKG
        STX     URX             ; SAVE X REGISTER
BRKPAT
        STY     URY             ; SAVE X
        PLA                     ; GET A REGISTER PUSHED ON BY
        STA     URA             ; SOFTWARE INTERRUPT
        PLA                     ; GET STATUS
        CLI                     ; CLEAR INTERRUPT JUST IN CASE
        CLD                     ; CLEAR DECIAML
        STA     URP             ; SAVE STATUS
        JSR     RSTVB           ; RESTORE NORMAL BLANK RTN
        PLA                     ; GET PGM COUNTER FROM STACK
        SEC                     ; AND DECR BY 2 SO
        SBC     #2              ; AS TO POINT TO START
        STA     LSADR           ; OF BRK INST.
        PLA                     ; X
        SBC     #0              ; X
        STA     LSADR+1         ; X
        LDA     #.LOW.DSYN2-1   ; SET UP RTN ADDR
        STA     RTNADR
        LDA     #.HIGH.DSYN2-1
        STA     RTNADR+1
        JSR     PRPC            ; PRINT THE USER PC
        JMP     RSTEP0          ; AND JOIN WITH STEP
;
;
;
;       RESET DEFERED VERTICAL BLANK
;
RSTVB
        LDY     #.LOW.XITVBV
        LDX     #.HIGH.XITVBV
        LDA     #7
        JMP     SETBVB
        .PAGE
;
;       VBRK - BREAK VECTOR FOR SOFTWARE BREAK
;
;       ENTER HERE IF GET SOFTWARE BREAK DURING
;       STEP OR TRACE
;
VBRK
        PLA                     ; REMOVE A REG
        PLA                     ; REMOVE STATUS AND RETURN ADDR
        PLA
        PLA
        CLD
        CLI
        JSR     XDR
        JMP     DSYN2
        .PAGE    'EXECUTE VERIFY'
;
;       XV - EXECUTE VERIFY'
;
XV
        JSR     TADR            ; SET UP TO & FROM ADDR
;
;
;
_V1
;
; DO VERIFY
;
        JSR     TSTBRK          ;TEST FOR BREAK
        BNE     _VEOF           ;
;
        LDY     #0              ; GET A BYTE
        LDA     (MVTA),Y        ; X
        STA     LBUFF+1         ; SAVE IT
;
        JSR     FAGET           ; GET FROM BYTE
        BCS     _VEOF           ; BR IF AT END OF DATA
;
        CMP     LBUFF+1         ; ARE THEY = ?
        BEQ     _V2             ; IF YES, DON'T PRINT
;
;
;
;
;       PRINT ADDR & DATA
;
        LDA     MVFA            ; PRINT FROM ADDR
        LDY     MVFA+1          ; X
        JSR     PRADRB          ; X
;
        LDA     LBUFF           ; PRINT FROM DATA
        JSR     PRHEXB          ; X
;
        JSR     PRBLK3          ; PRINT BLANKS
;
        LDA     MVTA            ; PRINT TO ADDR
        LDY     MVTA+1          ; X
        JSR     PRADRB          ; X
;
        LDA     LBUFF+1         ; PRINT TO DATA
        JSR     PRHEXB          ; X
        JSR     PRCR            ; PRINT CR
;
_V2
        JSR     INCMVF          ; INCR FROM ADDR
;
_V3
        INC     MVTA            ; INCR TO ADDR
        BNE     _V1             ; X
        INC     MVTA+1          ; X
        BNE     _V1             ; REPEAT
;
_VEOF
        RTS
        .PAGE    'EXECUTE MOVE'
;
;       XM - EXECUTE MOVE
;
XM
        JSR     TADR            ; SET UP TO & FROM ADDR
;
;       DO MOVE
;
_MOVE
        JSR     TSTBRK          ; IF BREAK HIT
        BNE     _MEOF           ; THEN END
        JSR     FAGET2          ; GET BYTE FROM MEMORY
        BCS     _MEOF           ; BR IF END OF FILE
;
;       DO PUT
;
        LDY     #0
        STA     (MVTA),Y
;
        INC     MVTA            ; INCR TO ADDR
        BNE     _MOVE           ; X
        INC     MVTA+1          ; X
        JMP     _MOVE
        .PAGE
;
;       TADR - GET TO ADDR & FROM ADR
;               COX - POINTS TO 1ST BYTE OF #
;
TADR
        JSR     GETC1           ; GET ADDR FROM COMMAND
        STA     MVTA            ; & STORE AS TO ADDR
        JSR     GETCODE         ; X
        STA     MVTA+1          ; X
        JSR     GETC1           ; INCR INDEX
;
;
;
;
;
;       FADR - GET FROM ADDR
;               COX - POINTS TO 1ST BYTE OF #
;
FADR
        JSR     GETCODE         ; GET ADDR FROM COMMAND
        STA     MVFA            ; & STORE AS FROM START ADDR
        JSR     GETCODE         ; X
        STA     MVFA+1          ; X
;
        JSR     GETC2           ; GET ADDR FROM COMMAND
        STA     MVFEA           ; AND STORE AS FROM END ADDR
        JSR     GETCODE         ; X
        STA     MVFEA+1         ; X
_MEOF
        RTS
        .PAGE
;
;       FAGET - GET FROM ADDRS
;
;
;       ON EXIT    CARRY SET IF AT END OF FILE
;
FAGET
        LDA     MVFA+1          ; IF MOVE FROM END >
        CMP     MVFEA+1         ; MOVE FROM THEN
        BCC     _FA2            ; AT EOF
        BNE     _FAFAIL         ; X
        LDA     MVFA            ; X
        CMP     MVFEA           ; X
        BCC     _FA2            ; X
        BNE     _FAFAIL         ; X
;
;
_FA2
        LDY     #0              ; GET BYTE FROM MVFA
        LDA     (MVFA),Y        ; X
        STA     (INBUFF),Y      ; SAVE FROM BYTE IN BUFFER
        CLC
_FAFAIL
        RTS
;
;
;
;
;       FAGET2 - GET BYTE FROM ADDR + UPDATE ADDR
;
FAGET2
        JSR     FAGET           ; GET BYTE
INCMVF
        INC     MVFA            ; INCR FROM ADDR
        BNE     _FA3
        INC     MVFA+1
_FA3    RTS
        .PAGE
;
;       GPCHAR - GET OR PUT CHARACTER
;
;       ON ENTRY   A - I/O TYPE
;                  X - DEVICE #
;                  LBUFF - PUT BYTE
;
GPCHAR
        JSR     GLPCX           ; GET DEVICE INDEX & SET COMMAND
;
        LDY     #1              ; GET BUFF LENGTH
        JSR     IO3             ; SO I/O
        JMP     IOTEST          ; TEST I/O
        .PAGE    'EXECUTE DEBUG LIST - DISASSEMBLE'
;
;       XL - LIST (DISASSEMBLE)
;
XL
;
;       SET DEFAULT
;       (DEFAULT START ALREADY SET)
;
        LDA     #20             ; SET # OF LINES TO LIST
        STA     LNCNT           ; X
;
        LDA     #CNTON          ; SET DISASSEMBLE CONTROL FLAG
        STA     DISFLG          ; TO CONTROL BY COUNT
;
        JSR     GETCODE         ; GET NEXT TOKEN
        CMP     #CEOL           ; AT END OF LINE
        BEQ     _DL             ; IF YES, SET UP DONE
;
        JSR     GETCODE         ; ELSE, GET START ADDR
        STA     LSADR           ; X
        JSR     GETCODE         ; X
        STA     LSADR+1         ; X
;
        JSR     GETCODE         ; GET NEXT TOKEN
        CMP     #CEOL           ;
        BEQ     _DL
;
        JSR     GETC1           ; GET END ADDR
        STA     LEADR
        JSR     GETCODE
        STA     LEADR+1
;
        LDA     #ADDRON         ; SET DISASSEMBLE CONTROL FLAG
        STA     DISFLG          ; TO CONTROL BY ADDR
;
;       CONTROL DISASSEMBLY
;
_DL
        JSR     TSTBRK          ;TEST FOR BREAK
        BNE     _DLDONE
;
        JSR     DISASM          ; GO DISASSEMBLE LINE
;
        LDA     DISFLG          ; GET CONTROL FLAG
        BEQ     _CADR           ; IFG = ADDR, TEST FOR END ADDR
;
        DEC     LNCNT           ; ELSE TEST FOR END COUNT
        BNE     _DL             ; IF NOT AT END, REPEAT
        RTS
;
_CADR
        LDA     LSADR+1         ; TEST FOR END OF ADDR RANGE
        CMP     LEADR+1
        BCC     _DL             ; IF NOT AT END, REPEAT
        BNE     _DLDONE
        LDA     LSADR
        CMP     LEADR
        BCC     _DL
        BEQ     _DL
_DLDONE
        RTS
        .PAGE    'DISASSEMBLER'
;
;       DISASM - DISASSEMBLE ONE LINE
;
DISASM
        JSR     PRPC            ; PRINT USER PC
;
        LDY     #0              ; GET OP CODE
        LDA     (LSADR),Y       ; X
        STA     STOP            ; SAVE IT
;
;       SEARCH FOR OP AS NON-MULTI ADDR
;
        LDA     #.LOW.TOPTBL    ; GET SEARCH ADDR
        LDY     #.HIGH.TOPTBL
        LDX     #EOP1           ; GET # BYTES TO SEARCH
        JSR     OPSRCH          ; SEARCH OP CODE
        BCC     _DIS2           ; IF FOUND, BR
        LDX     #TMULTI         ; SET TYPE TO MULTI ADDR
        BNE     _DIS3
_DIS2
        CLC
        TYA                     ; ADJUST ENTRY #
        ADC     #CSMNEM         ; X
        STA     STENUM
        LDX     #0
        JSR     CLASF           ; CLASSFY OP BY TYPE
_DIS3
        TXA
        JSR     _DDUM
;
;       RETURN HERE FROM SUBROUTINE
;
        STA     ILEN            ; SAVE LENGTH
        STX     PMASK           ; SAVE PRINT MASK
;
;       PRINT OBJECT CODE
;
        STA     ZT1             ; SAVE LENGTH AS COUNTER
        LDY     #0
        STY     ZT2             ; SET INDEX
_DIS4
        LDY     ZT2
        LDA     (LSADR),Y       ; GET INST
        JSR     PRHEXB
        INC     ZT2             ; INCR INDEX
        DEC     ZT1             ; DECT LENGTH COUNTER
        BNE     _DIS4           ; IF MORE TO DO, BR
;
        .PAGE
;
;       PRINT BLANKS FOR ALIGNMENT
;       # = (3-ILEN)*3+4
;
        SEC
        LDA     #3
        SBC     ILEN
        STA     ZT1
        ASLA
        CLC
        ADC     ZT1
        CLC
        ADC     #4
        JSR     PRBLANK3        ; GO PRINT THEM
;
;       FIND MNEMONIC
;
        LDA     STENUM          ; ADJUST ENTRY # TO
        SEC                     ; COUNT JUST OPS
        SBC     #CSMNEM         ;X
        STA     ZT1
;
        LDY     #.LOW.KWTAB2
        LDA     #.HIGH.KWTAB2   ; GET START OF TABLE
;
_SCAN1
        STA     SRCADR+1        ; SET SCAN ADDR
        STY     SRCADR
        LDY     #$FF
        DEC     ZT1
        BMI     _FMN
;
_SCAN2
        INY
        LDA     (SRCADR),Y      ; GET CHAR OF MNEMONIC
        BPL     _SCAN2
;
        INY
        JSR     INCSRC          ; INCR SEARCH ADDR
        BNE     _SCAN1          ; BR ALWAYS
        .PAGE
;
;
;
;       PRINT MNEMONIC
;
_FMN
        LDY     #0              ; SET UP INDEX
        STY     ZT1
;
_MPR
        LDY     ZT1             ; GET INDEX
        LDA     (SRCADR),Y      ; GET CHAR OF MNEMIC
        PHA
        AND     #$7F            ; TURN OFF HIGH ORDRER BIT, IF ON
        JSR     PRCHAR          ; PRINT CHAR
        INC     ZT1
        PLA
        BPL     _MPR
        JSR     PRBLK3          ; PRINT 3 BLANKS
;
;       PRINT ADDRESS OPERAND
;
        LDA     PMASK           ; GET PRINT MASK
        BEQ     PRA             ; HANDLE ACU
        BMI     PRREL           ; HANDLE REL ADDR
;
        ASLA                    ; SHIFT 1ST MASK BIT TO MSB
        BMI     _DISEND         ; BR IF 1 BYTE INST
        ASLA
        STA     PMASK
;
        LDY     #6              ; SET 6 POSSIBLE COMBOS
        STY     PRCNT
_APR1
        DEC     PRCNT
        BMI     _DISEND
        LDY     PRCNT
        CPY     #2              ;AFTER 3 TRIES, GO PRINT ADDR
        BEQ     PRADR
_APR2
        LDA     PMASK           ;TEST NEXT BIT
        ASLA
        STA     PMASK
        BCC     _APR1           ;IF OFF, NO PRINT
;
;       ELSE PRINT THE CHARS CORRESPONDING TO BIT
;
        LDA     STR1,Y          ;GET CHAR FROM STRING 1
        JSR     PRCHAR
        LDY     PRCNT           ; GET INDEX AGAIN
        LDA     STR2,Y          ;PRINT CHAR FROM STRING 2
        BEQ     _APR1
        JSR     PRCHAR
        JMP     _APR1
PRA
        LDA     #'A             ; PRINT CHAR A
        JSR     PRCHAR
;
_DISEND
        JSR     INCLA           ; INCR LIST ADDRESS
        JMP     PRCR            ; PRINT CARRIDGE RETURN
;
;
;
;
;
;       PRINT ADDR FOR BRANCH
;
PRREL
        LDA     #'$
        JSR     PRCHAR
;
        LDY     #1              ; GET RELATIVE DISPL
        LDA     (LSADR),Y       ; X
        PHA                     ; SAVE
        JSR     INCLA           ; INC LIST ADDR
        PLA
        JSR     CREL            ; CALC RELATIVE BR ADDR
_PRR
        TAY                     ; GO PRINT
        TXA                     ; X
        JSR     PRHEX2          ; X
        JMP     PRCR            ; PRINT CR
        .PAGE
;
;       PRINT THE ADDR OR DATA
;
PRADR
        LDA     (LSADR),Y       ; X
        TAX                     ; X
        DEY                     ; X
        LDA     (LSADR),Y       ; X
;
        LDY     ILEN            ; GET INST LENGTH
        CPY     #3              ; IF INSTR LENGTH NOT = 3
        BNE     _PRAD1          ; GO PRINT 1 BYTE
        PHA                     ; ELSE PRINT 2 BYTE
        TXA
        JSR     PRIHEX
        PLA
_PRAD1
        JSR     PRIHEX
        LDY     #2              ;
        BNE     _APR2
        .PAGE
;
;       PRINT USER PC
;
PRPC
        LDA     LSADR           ; PRINT DISASSEMBLE ADDR
        LDY     LSADR+1         ; X
        JSR     PRADRB          ; X
        JSR     PRBLK3          ; X
        RTS
        .PAGE
;
;
;
;       INCLA - INCREMENT LIST ADDRESS BY ILEN
;
INCLA
        CLC
        LDA     LSADR           ; INCR LIST ADDR
        ADC     ILEN
        STA     LSADR           ; X
        LDA     LSADR+1         ; X
        ADC     #0              ; X
        STA     LSADR+1         ; X
        RTS
;
;
;
;
;       CRCL - CALCULATE RELATIVE BRANCH ADDR
;
;       ON ENTRY   A - DISPL
;       ON EXIT    A - ADDR HIGH
;                  X - ADDR LOW
;
CREL
        BMI     _BBACK          ; IF MINUS, BR BACK
        CLC                     ; ELSE CALC ADDR FOR
        ADC     LSADR           ; FORWARD BR
        TAX                     ; X
        LDA     #0              ; X
        ADC     LSADR+1         ; X
        RTS
_BBACK
        EOR     #$FF            ; TAKE COMPLIMENT OF DISPL
        CLC
        ADC     #1              ; X
        SEC                     ; CALC BACKWARD BR
        STA     ZT1
        LDA     LSADR           ; X
        SBC     ZT1
        TAX
        LDA     LSADR+1         ; X
        SBC     #0              ; X
        RTS
        .PAGE
_DDUM
        ASLA                    ; GET ROUTINE ADDR
        TAY                     ; BY INST TYPE
        LDA     ITTAB-3,Y       ; X
        PHA
        LDA     ITTAB-4,Y
        PHA
        RTS                     ; X
;
;
;
;
;
;       ITTAB - ROUTINE ADDR BY INSTRUCTION TYPE
;
ITTAB
        .WORD   DIMP-1          ; IMPLIED
        .WORD   DREL-1          ; RELATIVE
        .WORD   DMISC-1         ; MISCELLANEOUS
        .WORD   DMULTI-1        ; MULTI - ADDRESS
        .PAGE    'DISASM IMPLIED, RELATIVE & MISC'
;
;       DIMP - DISASSEMBLE IMPLIED INST
;
DIMP
        LDA     #1              ; GET INSTR LENGTH
        LDX     #$40            ; GET PRINT TYPE FROM ADDR
        RTS
;
;
;
;
;       DREL - DISASSEMBLE RELATIVE INSTRUCTION
;
DREL
        LDA     #2              ; SET INST LENGTH
        LDX     #$80            ; GET PRINT TYPE
        RTS
;
;
;
;
;       DMISC - DISASSEMBLE MISCELLANEOUS INST.
;
DMISC
        LDA     #3
        LDX     #PABS.AND.$3F
        RTS
        .PAGE    'DISASSEMBLE MULTI-ADDRESS INSTRUCTION'
;
;       DMULT
;
DMULTI
        LDA     STOP            ; GET OP
        PHA                     ; SAVE IT
        CMP     #$6C            ; IT IS JMP INDERECT
        BEQ     _SIJMP          ; GO SET UP FOR JUMP IND
;
        AND     #$E3            ; OR OUT ADDR BITS
        STA     STOP            ; SAVE FOR SEARCH
;
        LDA     #.LOW.TOPT2     ; GET SEARCH ADDR
        LDY     #.HIGH.TOPT2
        LDX     #EOP2           ; GET # BYTES TO SEARCH
        JSR     OPSRCH          ; GO SEARCH
        BCS     _NF             ; BR IF NOT FOUND
;
        CLC
        TYA                     ; ADJUST ENTRY #
        ADC     #CSMULT         ; X
        STA     STENUM          ; X
        PLA                     ; RESTORE OP
;
;       CHECK FOR INVALID OP
;
        LDY     #NOINV          ; GET # OF ENTRIES IN INVALID OP TABLE
_DM2
        CMP     INVOPT,Y        ; IS OUR CODE INVALID
        BEQ     _NF1            ; IF YES, BR
        DEY                     ; ELSE CHECK NEXT ONE
        BPL     _DM2
;
        AND     #$1F            ; GET ADDR TYPE INDEX
        TAY
        LDA     PMTAB,Y         ; GET PRINT MASK & LEN
        BEQ     _NF1            ; IF MASK = 0 THEN INVALID OP
        TAY                     ; SAVE
        AND     #$3F            ; GET PRINT MASK
        TAX
        TYA
        AND     #$C0            ; GET LENGTH
        LSRA
        LSRA
        LSRA
        LSRA
        LSRA
        LSRA
;
;       SPECIAL CASE STX & LDX
;
        TAY                     ; SAVE IN Y
        LDA     STOP            ; GET TRIAL OP
        AND     #$DF
        CMP     #$82            ; IS IT LDX OR STX?
        BNE     _DM1
;
        CPX     #PABSX.AND.$3F
        BNE     _DM1
        LDX     #PABSY.AND.$3F
_DM1
        TYA                     ; RECOVER LENGTH
        RTS
_NF
        PLA                     ; FIX STACK
_NF1
        LDA     #CDUM           ;
        STA     STENUM          ; SET NOT FOUND
        LDA     #1              ; GET LENGTH
        LDX     #$40
        RTS
;
;
_SIJMP
        PLA                     ; CLEAR STACK
        LDA     #CJMP           ; POINT TO JMP MNEMONICS
        STA     STENUM          ; X
        LDX     #$12            ; GET PRINT MASK
        LDA     #3              ; GET LENGTH
        RTS
        .PAGE
;
;       INVOPT - INVALID OP CODE TABLE
;
INVOPT
        .BYTE   $02
        .BYTE   $22
        .BYTE   $34
        .BYTE   $3C
        .BYTE   $42
        .BYTE   $62
        .BYTE   $82
        .BYTE   $89
        .BYTE   $9C
        .BYTE   $80
        .BYTE   $9E
        .BYTE   $C2
        .BYTE   $D4
        .BYTE   $DC
        .BYTE   $F4
        .BYTE   $FC
        .BYTE   $E2
NOINV   =       *-INVOPT-1
        .PAGE    'SEARCH OP CODE TABLE'
;
;       OPSRCH - SEARCH OP CODE TABLE
;
;                  A - SEARCH ADDR LOW
;                  Y - SEARCH ADDR HIGH
;                  X - # BYTES TO LOOK AT
;
;       ON EXIT    Y - ENTRY #
;
OPSRCH
        STX     SRCCNT          ;SAVE # BYTE TO SEARCH
        STA     SRCADR          ; SAVE TABLE ADDR
        STY     SRCADR+1        ; X
;
        LDY     #0
        LDA     STOP
_OPS1
        CMP     (SRCADR),Y      ; GET TABLE ENTRY
        BEQ     _OPF
;
        INY                     ; INCR INDEX
        CPY     SRCCNT          ;IF MORE TO SEARCH
        BCC     _OPS1           ; DO IT
;
        SEC
        RTS
_OPF
        CLC
        RTS
        .PAGE
;
;       PRINT MASK EQUATES
;
;               LOW ORDER 6 BITS = MASK
;               HIGH ORDER 2 BITS = LENGTH
;
LONE    =       $40
LTWO    =       $80
LTHREE  =       $C0
;
;
PIMM    =       $20+(.LOW.LTWO)
PINDX   =       $16+(.LOW.LTWO)
PINDY   =       $13+(.LOW.LTWO)
PZPG    =       $08+(.LOW.LTWO)
PZPGX   =       $0C+(.LOW.LTWO)
PZPGY   =       $09+(.LOW.LTWO)
PABS    =       $08+(.LOW.LTHREE)
PABSX   =       $0C+(.LOW.LTHREE)
PABSY   =       $09+(.LOW.LTHREE)
PACU    =       0+(.LOW.LONE)
;
;
;
;
;       PRINT CHARACTER STRING
;
STR1    .BYTE   ',),$(#'
STR2    .BYTE   'Y',0,'X',0,'$','$'
        .PAGE
;
;       PMTAB - PRINT CONTROL MASK TABLE
;
PMTAB
        .BYTE   PIMM            ; IMM 0
        .BYTE   PINDX           ; INDX 1
        .BYTE   PIMM            ; IMM 2
        .BYTE   0               ; - 3
        .BYTE   PZPG            ; ZPG 4
        .BYTE   PZPG            ; ZPG 5
        .BYTE   PZPG            ; ZPG 6
        .BYTE   0               ; - 7
        .BYTE   0               ; - 8
        .BYTE   PIMM            ; IMM 9
        .BYTE   PACU            ; ACU 10
        .BYTE   0               ; - 11
        .BYTE   PABS            ;ABS 12
        .BYTE   PABS            ;ABS 13
        .BYTE   PABS            ;ABS 14
        .BYTE   0               ; - 15
        .BYTE   0               ; - 16
        .BYTE   PINDY           ; INDY 17
        .BYTE   0               ; - 18
        .BYTE   0               ; - 19
        .BYTE   PZPGX           ; ZPGX 20
        .BYTE   PZPGX           ; ZPGX 21
        .BYTE   PZPGX           ; ZPGX 22
        .BYTE   0               ; - 23
        .BYTE   0               ; - 24
        .BYTE   PABSY           ; ABSY 25
        .BYTE   0               ; - 26
        .BYTE   0               ; - 27
        .BYTE   PABSX           ; ABSX 28
        .BYTE   PABSX           ; ABSX 29
        .BYTE   PABSX           ; ABSX 30
        .PAGE    'EXECUTE MINI-ASSEMBLER'
;
;       XA - EXECUTE MINI-ASSEMBLER
;
XA
;
        JSR     AINIT           ; GO INIT FOR MINI-ASSEMBLER
;
        LDA     #PASS2          ; SET PASS 2 FLAG
        STA     PASSFLG         ; X
;
        LDA     #MAMODE         ; SET MODE FLAG
        STA     MODEFLG         ; X
MASYNTAX
        LDX     #$FF            ;RESET STACK POINTER
        TXS                     ; X
        JSR     SYNINIT         ; GO GENERASL SYNTAX INIT
        BNE     MASYNTAX        ; BR IF BREAK
;
        JSR     SKPBLK
        JSR     GETIN           ; GET INPUT CHAR
        CMP     #DELIM          ; IS IT DELIMETER
        BEQ     _MINI           ; IF YES, USE CURRENT LOCATION COUNTER
        CMP     #CR             ; IF CR THAN DONE
        BEQ     _MINI2
;
        DEC     CIX             ; BACK UP TO 1ST DIGIT
;
        JSR     GETHEX          ; GET HEX #
        BCS     _MASER
;
        JSR     SKPBLK
        JSR     GETIN           ; GET INPUT CHAR
        CMP     #DELIM          ; X
        BNE     _MASER
;
        LDY     COX             ; GET OUTPUT INDEX
        CPY     #3              ; SHOULD HAVE BEEN 2 BYTES
        BNE     _MASER          ; IF NOT, ERROR
        DEY
        LDA     (OUTBUFF),Y     ; PUT ADDR IN LOC COUNTER
        STA     LOCCNT+1        ; X
        DEY                     ; X
        LDA     (OUTBUFF),Y     ; X
        STA     LOCCNT          ; X
        LDA     #0              ; RESET OUTPUT INDEX
        STA     COX             ; X
_MINI
        JSR     ASM1A           ; GO ASSEMBLE LINE
        BCS     MASYNTAX        ;IF ERROR, GET NEW LINE
        LDA     EOFFLG          ; ARE WE AT EOF (.END)?
        BPL     MASYNTAX        ; IF NOT CONTINUE
;
_MINI2
        JSR     ARESET          ; DO REST
        JMP     BUG1            ; RETURN TO DEBUG
;
;
_MASER
        LDA     #ERMSYN
        JSR     ERROR
_MASE1
        JSR     PRTERR          ; PRINT ERROR
        JMP     MASYNTAX
        .PAGE    'EXECUTE ASM'
;       LOCAL
;
;       XASM - EXECUTE ASM
;
XASM
;
        JSR     AINIT           ; GO INIT COMMON TO MINI-ASM
;
        LDA     TXTTAB          ; POINT TO FIRST LINE IN TEXT
        STA     STMCUR          ; X
        LDA     TXTTAB+1        ; X
        STA     STMCUR+1        ; X
;
        LDA     #AMODE          ; SET ASM MODE
        STA     MODEFLG         ; X
        LDA     #PASS1          ; SET PASS FLAG TO PASS 1
        STA     PASSFLG
;
;       PROCESS PARMS
;
        JSR     GETCODE         ; GET TOKEN
        CMP     #CEOL           ; IS IT EOL?
        BEQ     _PDONE          ; IF YES, PARMS DONE
        CMP     #CCOM           ; IS IT COMMA?
        BEQ     _PARM2          ; IF YES, USE PARM 1 DEFAULT
;
;       SET UP SOURCE FILE
;
;
        JSR     FLOAD           ; OPEN ENTRY FILE
        LDA     #NTCMD          ; DO NOTE FOR SECOND PASS
        LDX     ENTDTD
        JSR     GLPCX
        JSR     IO7
        JSR     IOTEST
;
        LDX     ENTDTD          ; SAVE NOTE VALUES
        JSR     LDDVX
        LDA     ICAUX3,X
        STA     TEMPRL
        LDA     ICAUX4,X
        STA     TEMPRL+1
        JSR     GETCODE         ; GET CODE
        CMP     #CEOL           ; IS IT EOL?
        BEQ     _PDONE          ; IF YES, WE ARE DONE
;
_PARM2
        JSR     GETCODE         ; GET TOKEN
        CMP     #CCOM           ; IS IT COMMA?
        BEQ     _PARM3          ; IF YES, USE PARM 2 DEFAULT
;
        JSR     FLIST           ; OPEN LIST FILE
        JSR     GETCODE         ; GET CODE
        CMP     #CEOL           ; IS IT EOL?
        BEQ     _PDONE          ; IF YES, WE ARE DONE
_PARM3
        JSR     GETCODE         ; GET TOKEN
;
;       SET UP OBJECT FIELD
;
;
        LDX     #OBJDV
        STX     OBJDTD          ; SETUP FOR OBJECT FILE
        JSR     _LEOF1
        JSR     STRMOV
;
;
_PDONE
ASM3
        JSR     TSTBRK          ;IF BREAK
        BNE     _ABRK           ; THEN DONE
;
        JSR     ASM1L           ; ASSEMBLE 1 LINE
;
        LDA     EOFFLG          ; GET EOF FLG
        BPL     ASM3            ; IF NOT EOL, DO NEXT LINE
;
        ASL     PASSFLG         ; TEST FOR PASS 2
        BNE     _ADONE          ; IF PASS 2 BIT ON, BR
        LDA     #PASS2          ; ELSE SET PASS 2
        STA     PASSFLG         ; X
        LDX     #TITLEP+2       ; CONTRACT TITLE & PAGE BUFFER
        LDY     SMBLD+1
        LDA     SMBLD
        JSR     CLR1
        JSR     AINIT2          ; INIT FOR PASS 2
        JSR     TOP3
        LDA     OBJDTD
        BEQ     ASM3            ; NO OBJECT FILE
; AT START OF SECOND PASS, WE OPEN OBJECT FILE
;
        STA     IODVC
        LDA     #8
        JSR     OP2             ; OPEN, PHASE 2
;
        LDA     #LCHK1
        TAX
        JSR     HPUTO2          ; HEADER BYTES
        JMP     ASM3            ; TO SECOND PASS
_ADONE
        LDA     ERRCNT          ; HOW MANY ERRORS?
        BPL     _ADN2           ; SOME
        LDA     #'>             ; TOO MANY
        JSR     PRCHAR
        LDA     #127            ; MAX WE CAN CNT
_ADN2
        JSR     PRNUMA
        LDX     #.LOW.CNTMSG
        LDY     #.HIGH.CNTMSG
        JSR     MSGXYCR
;
ABRK    =       *
_ABRK
        JSR     CLSALL          ; CLOSE ALL DEVICES
ASMR
        JSR     ARES1           ; DO RESET
        JMP     ESYN2           ; RETURN TO EDITOR
CNTMSG  .BYTE   ' ERROR',$80+'S'
        .PAGE
;
;       ASM1L - ASSEMBLE ONE LINE
;
ASM1L
        JSR     GASML           ; GET AN INPUT LINE
        BCS     XEND2           ; IF AT END OF FILL, BR
;
ASM1A
        LDA     #0
        STA     IDISPL          ; CLEAR PRINT DISPL
        STA     ADISPL          ; X
        STA     COX             ; INIT OUTPUT INDEX
;
        JSR     ASYNTAX         ; SYNTAX LINE
        BCS     LSYNER          ; IF ERROR, LIST LINE
;
;       PROCESS TOKEN
;
        LDY     #0
        STY     OBJDEX          ; ZERO OBJECT INDEX
        LDY     #3              ; SET OUTPUT DEVICE
        STY     COX             ; X
        JSR     GETCODE         ;GET TYPE OF STATEMENT
;
        JSR     _ADUM
;
;       RETURN HERE FROM SUBROUTINE
;
OUT
        STA     OLBCNT          ;STORE NUMBER BYTES PER LINE
        JSR     OCNTL           ; TAKE CARE OF ALL OUTPUT
        CLC
        RTS
;
;
LSYNER
        LDA     MODEFLG         ; GET MODEFLAG
        CMP     #MAMODE         ; ARE WE IN MINI-ASM?
        BEQ     _ASYNER
AXCOM                           ; ENTRY POINT FOR COMMAND LISTING
        JSR     TSTLIST         ; DO WE LIST?
        BNE     _ASDONE         ; IF NOT, BR
        JSR     TSTEJT          ; TEST FOR PAGE EJECT
        LDA     #PLST           ;INDENT LINE LIST
        JSR     PRBLANKS        ;X
        JSR     INBOUT
_ASYNER
        JSR     TSTOERR         ;PRINT ERROR IF REQUIRED
_ASDONE
        SEC
        RTS
        .PAGE
_ADUM
        ASLA                    ; GO PROCESS TOKEN BY TYPE
        TAY                     ; X
        LDA     AXTBL+1,Y       ; X
        PHA                     ; X
        LDA     AXTBL,Y         ; X
        PHA
        RTS
        .PAGE
;
;       AXDIR - EXECUTE DIRECTIVES
;
AXDIR
        JSR     GETCODE         ; GET TYPE OF DIRECTIVE
;
        ASLA                    ; GO TO PROPER ROUTINE
        TAY
        LDA     ADXTBL-CSDIR-CSDIR+1,Y
        PHA
        LDA     ADXTBL-CSDIR-CSDIR,Y
        PHA
        RTS
        .PAGE    'EXECUTE DIRECTIVE'
;
;       XEND- EXECUTE END DIRECTIVE
;
XEND
        LDA     ENTDTD          ; GET INPUT DEVICE
        BNE     _END            ; IF NOT = MEMORY, BR
XEND2
        JSR     PORG            ; PROCESS LAST ORG
        LDA     #$80            ; ELSE SET END A FILE
        STA     EOFFLG
        LDA     #0              ; GET # OF BYTES OF OBJECT
_END
        CLC
        RTS
        .PAGE    'EXECUTE IF DIRECTIVE'
;
;       XIF - EXECUTE IF DIRECTIVE
;
XIF
        JSR     XEXP            ; EVALUATE EXP
        BNE     _IF1            ; IF EXP NON-ZERO
        TAX                     ; THEN SKIP SOME USER CODE
        BNE     _IF1            ; ELSE RETURN
;
        LDA     RESBYT          ; GET RESOLVE BYTE
        LSRA                    ; IF UNRESOLVED, TREAT AS
        BCS     _IF1            ; NON-ZERO
        RTS
;
_IF1
        LDA     #0              ; PRINT IF LINE
        JSR     OUT
        JSR     GETC3           ; POINT TO START OF STRING
        STA     SVLENG          ; SAVE LENGTH
        LDY     COX             ; SAVE START OF STRING
        STY     TSCOX           ; X
;
;       SEARCH FOR LABEL IN CODE TO MATCH .LABEL IN IF
;
_IF2
        JSR     GASML           ; GET A LINE
        BCS     _IF4            ; BR IF END OF FILE
        LDA     CIX             ; SAVE CIX
        STA     SVCIX           ; X
        LDX     SVLENG          ; GET STRLENG AS # OF BYTES TO SEARCH
_IF3
        DEX                     ; DEC COUNTER
        BMI     _IFP            ; IF AT END, POSSIBLE PASS
        JSR     GETCODE         ; GET .LABEL CHAR
        LDY     CIX             ; GET INPUT INDEX
        INC     CIX
        CMP     (INBUFF),Y
        BEQ     _IF3
_IFF
        JSR     AXCOM           ; PRINT LINE
        LDA     TSCOX           ; RESTORE OUTPUT INDEX
        STA     COX             ; X
        BNE     _IF2            ; BR
;
;       .LABEL MATCHES LABEL (CHECK FOR END OF LABEL
;
_IFP
        JSR     TSTALPHA        ; IF NOT AT END OF LABEL
        BCC     _IFF            ; THEN .LABEL NOT FOUND
        JSR     TSTNUM          ; X
        BCC     _IFF            ; X
;
        LDA     SVCIX           ; RESTORE CIX FOR THIS LINE
        STA     CIX             ; X
;
;
        PLA                     ; PULL RETURN ADDR
        PLA                     ; FROM STACK
        JMP     ASM1A           ; ASM THE LINE
;
_IF4
        PLA                     ; PULL RETURN ADDR
        PLA
        JMP     XEND2           ; HANDLE LIKE END
        .PAGE
;
;       GASML - GET NEXT ASM LINE
;
GASML
        JSR     INTLBF          ; INIT INBUFF
        LDA     ENTDTD          ; GET INPUT DEVICE
        BEQ     _GLTXT          ; IF = MEMORY GET LINE FROM TABLE
;
;       GET LINE FROM DEVICE
;
        JSR     GLGO
        CMP     #$88            ; ARE WE AT EOF?
        BNE     ASM1B
        RTS
_GLTXT
        JSR     TSTTEND         ; TEST FOR END OF TEXT
        BCS     ASM1D           ; BR IF AT END OF TEXT
;
;
        LDA     #0
        STA     LTYPFLG         ;SET TO LIST LINE #
;
;       MOVE THE LINE
;
        JSR     MOVLIN          ; LIST LINE TO BUFFER
        JSR     GETLL           ; GET NEXT STATEMENT
        JSR     GNXTL           ; X
ASM1B
;
;       CHANGE TABS TO BLANKS
;
        LDY     #127            ; GET BUFFER LENGTH
TSTTC
        LDA     (INBUFF),Y      ; GET A CHARACTER FROM BUFFER
        CMP     #TC             ; IS IT TAB?
        BNE     NOTTAB          ; IF NOT BR
        LDA     #$20            ;
        STA     (INBUFF),Y      ; IF YES REPLACE WITH BLANKX
NOTTAB
        DEY                     ; DEC TO NEXT CHAR IN BUFFER
        BPL     TSTTC           ; IF NOT DONE, BR
;
        LDA     #0
        STA     CIX             ; INIT INPUT INDEX
        JSR     CVAFP           ; SKIP LINE #
        BCS     ASM1C           ; IF ERROR BR
        INC     CIX             ; INCR PAST BLANK
ASM1D
        RTS
;
ASM1C
        LDA     #ERGARB
        JSR     ERROR
        JSR     PRTERR
        SEC
        RTS
        .PAGE    'EXECUTE TITLE DIRECTIVE'
;
;       XTITLE - EXECUTE TITLE DIRECTIVE
;
XTITLE
;
        LDX     #TITLEP         ; SET FOR TITLE BUFFER
;
;
;       MOVE STRING FROM PAGE & TITLE
;       (X CONTAINS POINTER TO TITLE OR PAGE BUFFER ADDR)
;
PTSTR
        JSR     GETCODE         ; GET NEXT CODE
        CMP     #CEOL           ; ARE WE AT END
        BEQ     _PTDONE         ; IF YES, DONE
;
        LDA     0,X             ; GET BUFFER ADDR (TITLE OR PAGE)
        STA     PTBUFF          ; X
        LDA     1,X             ; X
        STA     PTBUFF+1        ; X
;
        JSR     GETC1           ; GET STRING LENGTH
        PHA                     ; SAVE IT
        SEC                     ; SUBTRACT CURRENT BUFFER LENGTH
        LDY     #0              ; TO GET # OF BYTES TO
        SBC     (PTBUFF),Y      ; EXPAND OR CONTRACT (NEW - OLD)
        BEQ     _PTMOV          ; BR NEW = OLD
        BCS     _PTEXP          ; BR NEW > OLD (EXPAND)
;                                 ELSE NEW < OLD (CONTRACT)
        EOR     #$FF            ; COMPLIMENT TO GET +# OF BYTES
        TAY                     ; X
        INY                     ; X
        INX                     ; POINT TO END OF CONTRACT AREA
        INX                     ;
        JSR     CONTLOW         ; GO CONTRACT
        JMP     _PTMOV
_PTEXP
        TAY                     ; PUT # OF BYTES IN Y
        INX                     ; POINT TO EXPAND POINT
        INX
        JSR     EXPLOW          ; GO EXPAND
;
_PTMOV
        PLA                     ; GET STRING LENGTH
        TAX                     ; SAVE AS LOOP CONTROL
        LDY     #0              ; SET INDEX INTO BUFFER
        STY     PTDEX           ; X
_PT2
        STA     (PTBUFF),Y      ; PUT LENGTH IN BUFFER
        JSR     GETCODE         ; GET STRING CHAR
        INC     PTDEX           ; INCR BUFFER POINTER
        LDY     PTDEX           ; GET INDEX
        DEX                     ; DEC COUNTER
        BNE     _PT2            ; BR IF MORE TO DO
;
        ORA     #$80            ;
        STA     (PTBUFF),Y
_PTDONE
        LDA     #0              ; GET # OF BYTES OF ZERO
        RTS
        .PAGE    'EXECUTE PAGE DIRECTIVE'
;
;       XPAGE - EXECUTE PAGE DIRECTIVE
;
XPAGE
        LDX     #PAGEP          ; POINT TO PAGE BUFFER
        JSR     PTSTR           ; MOVE STRING
;
PAGE1
        JSR     TSTLIST         ; TEST FOR LISTING
        BNE     _PTPR1          ; IF NO LIST THAN BR
        LDA     LINESPERPAGE
        SEC
        SBC     LNCNT           ; GETS # OF LINES LEFT
        LDX     FFOK            ; OK TO DO FORM FEED?
        BEQ     PG1NOFF         ; NO
 ;
        LDA     #PEJECT         ; YES
        JSR     PRCHAR          ; FF
        JMP     TOP3
;
PG1NOFF
        CLC
        ADC     #4              ; 4 LINES AT TOP OF PG
        STA     LNCNT
PG1LP
        JSR     PRCR            ; BLANK LINE
        DEC     LNCNT           ; MORE?
        BNE     PG1LP           ; YES
; NO MORE...AND LNCNT=0
;
TOP3
        LDA     #0
        STA     LNCNT
;
        JSR     PRTITLE         ; PRINT TITLE
        JSR     PRPAGE          ; PRINT PAGE
        JSR     PRCR            ; PUT OUT EXTRA CR
_PTPR1
        RTS
        .PAGE
;
;       PRPAGE - PRINT PAGE
;
;       PRTITLE - PRINT TITLE
;
PRTITLE
        LDX     TITLEP          ; GET ADDR LOW
        LDY     TITLEP+1        ; GET ADDR HIGH
        BNE     _PTPR
;
PRPAGE
        LDX     PAGEP           ; GET ADDR LOW
        LDY     PAGEP+1         ; GET ADDR HIGH
;
_PTPR
        INX                     ; INCR LOW ORDER BYTE
        BNE     _PT             ;
        INY                     ; IF ZERO, INCR ADDR HIGH
_PT
        JMP     MSGXYCR         ; PRINT
        .PAGE    'EXECUTE WORD & DBYTE'
;
;       XDBYTE - EXECUTE DBYTE
;
;       XWORD - EXECUTE DWORD
;
;
;
XDBYTE
        LDA     #DBYTEON        ; SET FLAG FOR DBYTE
        BNE     _WORD
;
XWORD
        LDA     #WORDON         ; SET FLAG FOR WORD
_WORD
        STA     WORDFLG         ; STORE FLAG
;
_WORD2
        JSR     XEXP            ; GET VALUE OF EXPRESSION
;
        LDY     WORDFLG         ; GET FLAG
        BEQ     _WORD3          ; IF SET FOR WORD, OUTPUT NON-REVERSE
;
        TXA                     ; ELSE OUTPUT IN REVERSE ORDER
        LDX     FR0             ; X
_WORD3
        JSR     OBJM2           ; PUT OUT 2 BYTE OBJECT
;
        JSR     GETCODE         ; GET CODE
        CMP     #CCOM           ; IS IT COMMA?
        BEQ     _WORD2          ; IF YES, DO NEXT INTEM
        LDA     #TWOBYTE        ; GET 2 BYTES OBJECT PER PRINT LINE
        RTS
        .PAGE    'EXECUTE BYTE'
;
;       XBYTE - EXECUTE BYTE
;
XBYTE
        JSR     GETCODE         ; GET TOKEN
        AND     #$7F            ; OR OUT MSB IF ON
        CMP     #THEX2          ; IS THIS A #?
        BEQ     _BYT1           ; IF YES, OUTPUT VALUE OF EXP
;                                 ELSE IT IS A STRING
;
        JSR     GETC1           ; GET LENGTH
        TAX                     ; USE AS COUNTER
        BEQ     _BERR1
_BYT2
L       JSR     GETCODE         ; GET STRING CHAR
        JSR     OBJMAN          ; PUT IN OBJECT BUFFER
        DEX
        BNE     _BYT2           ; REPEAT IF MORE STRING CHAR
        BEQ     _BYT3
;
_BYT1
        DEC     COX             ; BACK UP TO # CODE FOR EXECUTE EXPRESSION
        JSR     XEXP            ; EVALUATE EXPRESSION
        JSR     BIT8            ; TEST FOR 8 BIT VALUE
        JSR     OBJMAN          ; PUT IN OBJECT BUFFER
;
_BYT3
        JSR     GETCODE         ; GET NEXT CODE
        CMP     #CCOM           ; IS IT COMMA?
        BEQ     XBYTE           ; IF YES,THEN PROCESS NEXT ITEM
;
        LDA     #ONEBYT         ; GET 1 BYTE OBJECT PER LINE
        RTS
;
_BERR1
        LDA     #ERNSTR
        JSR     ERROR
        RTS
        .PAGE    'EXECUTE TAB DIRECTIVE'
;
;       XTAB - EXECUTE TAB
;
XTAB
        LDA     #0              ; GET TAB DISPL = 0
        STA     TABCNT          ; X
_TAB
        JSR     XEXP            ; EVALULATE EXPRESSION
        CLC
        ADC     #PLST           ; ADD DISPL TO INPUT POINT
        LDX     TABCNT          ; X
        STA     TAB1,X          ; X
        INC     COX             ; INCR OVER COMMA
        INX                     ; POINT TO NEXT TAB
        CPX     #3              ; X
        STX     TABCNT          ; X
        BCC     _TAB            ; BR IF HAVE NOT DONE 3
        LDA     #0              ; GET # OF BYTES OF OBJECT
        RTS
        .PAGE    'ORG DIRECTIVE'
;
;       XORG
;
;       ON PASS 1 AN ENTRY IS CREATED FOR EACH ORG IN THE LABEL
;       TABLE WITH A LABEL OF ;
;
;       ON PASS 2 THE NEXT LABEL FOR THE NEXT  ORG IN TABLE IS CHANGED TO *
;
;       THIS IS DONE SO WE CAN KNOW START & END ADDRESS
;       OF THIS SECTION OF OBJECT FOR THE OBJECT FILE
;
;
XORG
        LDA     LOCCNT          ; MOVE LOCATION COUNTER
        STA     MVFA
        LDA     LOCCNT+1
        STA     MVFA+1
;
        JSR     XEXP            ; EVALUATE EXPRESSION
;
        TAY                     ;SAVE VALUE LOW
        LDA     RESBYT          ;GET RESOLVE BYTE
        LSRA                    ;TEST UNRESOLVED BIT
        BCC     _ORG            ;IF NOT ON, VALUE OKAY
;
        LDA     #ERUFR          ;ELSE ERROR
        JSR     ERROR           ;
        JSR     PRTERR
        JMP     _ABRK           ; ABORT
;
_ORG
        LDA     OPTFLG          ; IF OBJ OPT=NO
        AND     #OOBJ           ; THEN DON'T PROCESS ORG AS LABEL
        BNE     _ORGA
        JSR     PORG            ; PROCESS PREVIOUS ORG
;
        JSR     DOORG           ; HANDLE THIS ORG
_ORGA
        LDA     FR0             ; SET LOCATION COUNTER TO NEW ORG VALUE
        STA     LOCCNT
        LDA     FR0+1
        STA     LOCCNT+1
        LDA     MVFA            ; PUT OLD LOCATION IN FR0
        STA     FR0
        LDA     MVFA+1          ; X
        STA     FR0+1           ; X
        JMP     _SPPRT          ; DO SPECIAL PRINT OF THIS LINE
;
;
;
;
;       DOORG - HANDLE LABEL TABLE LOOK-UP
;
;       ON ENTRY - ORG VALUE IS IN FR0
;
DOORG
        LDA     PASSFLG         ; GET PASS FLAG
        BPL     _OP2            ; BR IF PASS 2
;
        LDA     #';             ; ADD ENTRY TO LABEL TABEL
        LDY     #'*
        JSR     OSRCH
;
        LDA     SRCADR          ; SET CURRENT ORG PTR
        STA     COPTR           ; X
        LDA     SRCADR+1
        STA     COPTR+1         ; X
        RTS
;
;;
_OP2
        LDA     #'*             ; SEARCH FOR NEXT ORG
        LDY     #';
        JSR     OSRCH
;
;
;
        LDX     OBJDTD          ; GET OBJECT DEVICE
        BNE     _ORGB           ; IF = FILE THEN BR
        RTS
;
;
;       PUT OUT OBJECT FILE HEADER
;
_ORGB
        LDY     #0
        SEC
        LDA     (SRCADR),Y
        SBC     FR0
        INY
        LDA     (SRCADR),Y
        SBC     FR0+1
        BCC     _OD             ; BRANCH TAKEN => BAD ASSY
        LDX     FR0             ; GET NEW ORG VALUE
        LDA     FR0+1           ;
        JSR     HPUTO2          ; CONDITIONAL : START ADDR
;
        LDY     #0              ; GET END OF THIS ORG
        LDA     (SRCADR),Y      ;
        TAX
        INY
        LDA     (SRCADR),Y
        JSR     HPUTO2          ; CONDITIONAL : END ADDR
_OD
        RTS
        .PAGE
;
;       PORG - PROCESS PREVIOUS ORG
;
;
;       SET CURRENT LOCATION COUNTER -1 AS ADDR IN
;       LABEL TABLE FOR LAST ORG ENTRY
;
PORG
        LDA     COPTR           ; IF = 0 THIS IS 1ST ORG OR PASS 2
        ORA     COPTR+1         ; SO BR
        BEQ     _PO
        LDY     #0              ; SET CURRENT LOC-1
        SEC
        LDA     LOCCNT          ; IN ORG LABEL TABEL
        SBC     #1
        STA     (COPTR),Y       ; ENTRY
        INY
        LDA     LOCCNT+1        ; X
        SBC     #0
        STA     (COPTR),Y       ; X
_PO
        RTS
        .PAGE
;
;       OSRCH - SEARCH FOR ORG
;
;       SEARCH FOR CHARACTER GIVEN IN Y. IF NOT FOUND, IT IS CREATED
;       THE FOUND CHARACTER IS THEN CHANGET TO THE CHARACTER
;       IN A
;
;       ON ENTRY   A - CHANGE CHAR (* OR ;)
;                  Y - SEARCH CHAR
;
OSRCH
        PHA                     ; SAVE CHANGE CHAR
        TYA                     ; GET SEARCH CHAR
;
        LDY     #0
        STY     CIX
        TAX                     ; SAVE SEARCH CHAR
        LDA     (INBUFF),Y      ; GET CHAR FROM BUFFER
        PHA                     ; SAVE IT
        TXA                     ; GET SEARCH CHAR
        STA     (INBUFF),Y      ; SET SEARCH CHAR IN BUFFER
        INY
        STY     TVSCIX          ; SET UP FOR SEARCH
        JSR     LBLS1           ; SEARCH
        LDY     #0              ; RESTORE BUFFER CHAR
        PLA
        STA     (INBUFF),Y
        LDY     #3              ; CHANGE CHAR
        PLA                     ; GET CHANGE CHAR
        ORA     #$80            ; OR IN MSB TO SET END OF STRING
        STA     (SRCADR),Y
        RTS
        .PAGE    'EXECUTE EQU DIRECTIVE'
;
;       XEQU - EXECUTE EQU
;
XEQU
        LDY     #0
        LDA     (OUTBUFF),Y     ; GET 1ST OUTPUT CHAR
        BEQ     _EERR           ; IF NO LABEL - ERROR
;
        INY                     ; MOVE LABEL ADDRESS
        LDA     (OUTBUFF),Y     ; X
        STA     SRCADR          ; X
        INY                     ; X
        LDA     (OUTBUFF),Y     ; X
        STA     SRCADR+1        ; X
;
        JSR     XEXP            ; EVALULATE EXPRESSION
        LDY     #0              ; SET VALUE IN LABEL ENTRY
        STA     (SRCADR),Y      ; X
        TXA                     ; X
        INY                     ; X
        STA     (SRCADR),Y      ; X
;
        INY                     ; SET RESOLVE BYTE
        LDA     RESBYT          ; X
        AND     #$3F            ;AND OUT PASS 1&2 BITS
        ORA     (SRCADR),Y      ;OR WITH DEFINE BYTE IN LABEL TABLE
        ORA     #EQULBL         ;SET EQUATE TYPE
        STA     (SRCADR),Y      ; X
;
; SPECIAL CASE PRINT OUT
;
_SPPRT
        JSR     TSTLIST         ; DO WE LIST
        BNE     _EDONE          ; IF NOT BR
        JSR     TSTEJT          ; TEST FPR PAGING
;
        LDA     #0              ;INIT OUTPUT INDEX
        STA     POX             ;X
;
        LDA     FR0             ; PRINT VALUE
        LDY     FR0+1           ; X
        JSR     PRHEX2          ;PRINT #
        JSR     ALIST1          ;DO LISTING
        PLA                     ; REMOVE RETURN ADDR FROM STACK
        PLA                     ; X
        CLC
_EDONE
        RTS
;
;
;
_EERR
        LDA     #EREQU
        JSR     ERROR
        RTS
        .PAGE    'EXECUTE OPTION DIRECTIVE'
;
;       XOPT - OPTION DIRECTIVE
;
XOPT
        JSR     GETCODE         ; GET TOKEN
        CMP     #CNO            ; IS IT NO CODE
        BEQ     OFF             ; IF YES, TURNS OFF OPRION
;
        CMP     #COBJ           ; IF OPT NOT = OBJECT
        BNE     _ON             ; CONTINUE
        PHA                     ; ELSE SAVE CODE
        LDA     LOCCNT          ; SET CURRENT PC IN
        STA     FR0             ; FR0 FOR ORG
        LDA     LOCCNT+1        ; PROCESSING
        STA     FR0+1           ; X
        JSR     DOORG           ; HANDLE AS ORG
        PLA                     ; GET CODE
_ON
        TAY                     ; ELSE TURN ON OPTION
        LDA     OPTTAB-COBJ,Y
        EOR     #$FF
        AND     OPTFLG
        STA     OPTFLG
        JMP     _OPT
;
OFF                             ; TURN OFF OPTION
        JSR     GETCODE         ; GET NEXT TOKEN
        CMP     #COBJ           ; IF CODE NOT=OBJECT
        BNE     _OFF1           ; CONTINUE
        PHA                     ; ELSE SAVE CODE
        JSR     PORG            ; PROCESS THE PREVIOUS ORG
        PLA                     ; GET CODE
_OFF1
        TAY                     ;
        LDA     OPTTAB-COBJ,Y   ; GET OPTION FLAG
        ORA     OPTFLG          ; OR WITH OTHER OPTIONS
        STA     OPTFLG          ; SAVE
;
_OPT
        JSR     GETCODE         ; GET NEXT CODE
        CMP     #CEOL           ; ARE WE DONE?
        BNE     XOPT            ; IF NOT, DO NEXT OPTION
        LDA     #0              ; GET # OF BYTES OF OBJECT
        STA     ERRDEX          ; ZERO ERROR INDEX INCASE THIS IS ERR ON
        RTS
;
;
;
;
;       INDICATES OFF FOR EACH OPTION
;
;       OPTTAB
;
OPTTAB
        .BYTE   OOBJ            ; OBJECT
        .BYTE   OERR            ; ERROR
        .BYTE   OPAGE           ;PAGE
        .BYTE   OLIST           ; LIST
        .PAGE    'PROCESS IMPLIED INSTRUCTION'
;
;       AXIMP - IMPLIED INSTRUCTION
;
AXIMP
        JSR     GETC1           ; GET OP CODE
        JSR     OBJMAN          ; PUT IN OBJECT BUFFER
        LDA     #ONEBYT         ; GET 1 BYTE OBJECT
        RTS
        .PAGE    'PROCESS RELATIVE BRANCH'
;
;       AXREL - RELATIVE BRANCH
;
AXREL
        JSR     GETC1           ; PUT OP CODE IN OBJ BUFFER
        JSR     OBJMAN          ; X
;
        JSR     XEXP            ; EVAL EXPRESSION IN A & X
        SEC                     ; GET RELATIVE ADDR
        SBC     LOCCNT          ; (EXP-LOCCNT-2)
        TAY                     ; X
        TXA                     ; X
        SBC     LOCCNT+1        ; X
        TAX                     ; X
        TYA                     ; X
        SEC                     ; X
        SBC     #2              ; X
        JSR     OBJMAN          ; X
        TAY                     ; SAVE LOW ORDER BYTE
        TXA                     ; X
        SBC     #0              ; X
        BNE     _BACK           ; THIS IS BR. BACK
        TYA                     ; IS BR FORWARD VALUE <80?
        BMI     _VERR           ; IF NOT ERROR
        BPL     _VALOK          ; ELSE OK
;
_BACK
        TAX                     ; HIGH BYTE SHOULD BE FF
        INX                     ; X
        BNE     _VERR
        TYA
        BMI     _VALOK          ; IF YES, OK
;
;
_VERR
        JSR     VERROR          ; GO DO ERROR PROCESSING
_VALOK
        LDA     #TWOBYT         ; TWO BYTES OF OBJECT
        RTS
        .PAGE    'PROCESS MISC INSTRUCTIONS'
;
;       AXMISC - MISCELLANEOUS INSTRUCTIONS
;               (JSR & JMP)
;
;
AXMISC
        JSR     GETC1           ; GET OP CODE
        TAX                     ; SAVE IT
        JSR     GETCODE         ; GET NEXT TOKEN
        CMP     #CLPRN          ; IS THIS INDIRECT JUMP
        BNE     _JSR            ; IF NOT, WE HAVE CORRECT OP
;
        LDX     #$6C            ; GET OP FOR INDIRECT JUMP
        BNE     _IJMP
_JSR
        DEC     COX             ; BACK UP TO START OF EXP
_IJMP
        TXA                     ; GET OP CODE
        JSR     OBJMAN          ; PUT OP CODE IN OBJECT BUFFER
        JSR     XEXP            ; GET VALUE OF EXP
        JSR     OBJM2           ; PUT BOTH BYTES TO BUFFER
;
        LDA     #THRBYTE        ; SET 3 BYTES OF OBJECT
        RTS
        .PAGE    'PROCESS MULTI ADDRESS INSTRUCTIONS'
;
;       AXMULTI - MULTI-ADDRESS INSTRUCTION
;
AXMULTI
        JSR     GETCODE         ; GET OP CODE INDEX
;
        ASLA                    ; GET VALID ADDR TYPE FOR THIS OP
        TAY
        LDA     OPATYP-CSMULT-CSMULT,Y ; GET VALID ADDR TYPE 1
        STA     ZT1             ; SAVE
        LDA     OPATYP-CSMULT-CSMULT+1,Y  ; GET VALID ADDR TYPE 2
        STA     ZT2             ; SAVE
;
        JSR     GETCODE         ; GET TRIAL OP CODE
        STA     STOP            ; SAVE TRIAL OP
        JSR     GETCODE         ;GET NEXT TOKEN
        AND     #$7F            ;AND OUT MSB
        CMP     #THEX2          ;IS THIS A # CODE ?
        BEQ     _GEXP1          ;BR IF YES
        CMP     #TACU           ; IS THIS ACCUM
        BNE     _GEXP           ; IF NOT, IT'S # OR (
        BEQ     _AXM4
_GEXP1
        DEC     COX
_GEXP
        JSR     XEXP            ; EVALUATE EXP
        JSR     GETCODE         ;GET TRIAL ADDR TYPE
        PHA                     ;SAVE IT
        LDA     RESBYT          ;GET RESOLVED BIT
        LSRA                    ;IS ABS ADR FLAG SET
        BCS     _AXM5           ;IF YES; CAN'T BE ZERO PAGE
;
; TEST FOR POSSIBLE ZERO PAGE
;
        TXA                     ; TEST HIGH ORDER BYTE
        BNE     _AXM5           ; IF NOT ZERO PAGE, BR
;
        PLA
        CMP     #TABS           ;IF TYPE IS NOT ABSOLUTE, BR
        BCC     _AXM4           ; X
        SEC                     ; CHANGE ADDR TYPE
        SBC     #3              ; X
        BNE     _AXM4           ; UNCONDITIONAL BR
;
_AXM5
        PLA                     ; GET ADDR TYPE
        PHA
        CMP     #TACU           ; = IMM, INDY, INDX ?
        BCS     _AXM1           ;IF NOT, THEN OKAY
        CMP     #TIMM           ; IF = IMM
        BNE     _AXM6           ;
        JSR     BIT8            ; TEST FOR 8 BIT VALUE
        JMP     _AXM1
_AXM6
        JSR     _ADRR           ; ELSE ERROR
        .PAGE
;
;
;
;       TEST FOR VALID ADDRESS MATCH
;
_AXM1
        PLA
_AXM4
        ASLA
        TAY
_AXM2
        LDA     ADRBIT,Y        ; IF FIND BIT MATCH
        AND     ZT1
        BNE     _VALID          ; X
        LDA     ADRBIT+1,Y      ; X
        AND     ZT2
        BNE     _VALID          ; X
;
;       ELSE TEST FOR NOT ZERO PAGE
;
        CPY     #TZPGY*2        ;TYPE = ZPGY?
        BNE     _ADRER          ; IF NOT, THEN ERROR
        LDY     #TABSY*2        ;CHANGE TO ABSY
        BNE     _AXM2           ; TRY AGAIN
;
_VALID
        TYA
        LSRA                    ; RESTORE INDEX OF 1 BYTE TABLE
        TAY
        PHA                     ; SAVE INDEX
;
        LDA     MODBYT,Y        ; GET MODIFIER
        PHA
;
;       TEST FOR SPECIAL CASE
;
        LDA     STOP            ; GET TRIAL OP
        LSRA                    ; IS IT EVEN?
        BCS     _SPEND          ; IF NOT, NOT SPECIAL CASE
;
;       HANDLE SPECIAL CASES
;
        CPY     #TIMM           ; IS THIS IMM ADDR TYPE?
        BNE     _SP1            ; IF NOT, TRY NEXT SPECIAL
;
        PLA                     ; CHANGE MODIFIER BYTE
        LDA     #0              ; (FOR LDX, STX, IMM)
        PHA
        BEQ     _SPEND
;
_SP1
        CPY     #TABSY          ; IS THIS ABSOLUTE Y?
        BNE     _SPEND          ; IF NOT, NOT SPECIAL
;
        PLA                     ; CHANGE MODIFIER BYTE
        LDA     #$1C            ; (FOR CPY, ABSY)
        PHA                     ; X
_SPEND
        PLA                     ; GET MODIFIER BYTE
        ORA     STOP            ; OR WITH TRIAL OP
        JSR     OBJMAN          ; PUT IN OBJECT
;
        LDA     FR0             ; PUT VALUE IN OBJECT
        LDX     FR0+1           ; X
        JSR     OBJM2           ; X
;
        PLA                     ; GET INDEX
        TAY
        LDA     LENTAB,Y        ; GET LENGTH BY INSTRUCTION TYPE
        STA     OBJDEX          ; SET AS OBJECT INDEX
        RTS
;;
_ADRER
        LDA     MODEFLG         ; IF MINI ASM
        CMP     #MAMODE         ; DON'T PUT OUT OBJ
        BEQ     _ADRR
        LDA     #0              ; PUT OUT 3 BYTES OF 0
        TAX
        JSR     OBJM2
        JSR     OBJMAN
_ADRR
        LDA     #ERADR          ; PUT OUT ERROR
_ADR1
        JMP     ERROR
        .PAGE
;
;       EQUS FOR ADDR TYPE BITS
;
IMM     =       $01
ABS     =       $02
ZPG     =       $04
ACU     =       $08
INDX    =       $10
INDY    =       $20
ZPGX    =       $40
ABSX    =       $80
ABSY    =       $01
ZPGY    =       $02
        .PAGE
;
;       OPATYP - VALID ADDRESS TYPES BY OP CODE
;
;               STENUM - INDEX TO ADDR TYPE BYTE
;
TYPEN   =       IMM+ZPG+ZPGX+ABS+ABSX+INDX+INDY
TYPEN2  =       ACU+ZPG+ZPGX+ABS+ABSX
OPATYP
        .BYTE   ABSY            ; ORA
        .BYTE   TYPEN
;
        .BYTE   ABSY            ; AND
        .BYTE   TYPEN
;
        .BYTE   ABSY            ; EOR
        .BYTE   TYPEN
;
        .BYTE   ABSY            ; ADC
        .BYTE   TYPEN
;
        .BYTE   ABSY            ; STA
        .BYTE   TYPEN-(.LOW.IMM)
;
        .BYTE   ABSY            ; LDA
        .BYTE   TYPEN
;
        .BYTE   ABSY            ; CMP
        .BYTE   TYPEN
;
        .BYTE   ABSY            ; SBC
        .BYTE   TYPEN
;
        .BYTE   0               ; ASL
        .BYTE   TYPEN2
;
        .BYTE   0               ; ROL
        .BYTE   TYPEN2
;
        .BYTE   0               ; LSR
        .BYTE   TYPEN2
;
        .BYTE   0               ; ROR
        .BYTE   TYPEN2
;
        .BYTE   0               ; DEC
        .BYTE   ZPG+ZPGX+ABS+ABSX
;
        .BYTE   0               ; INC
        .BYTE   ZPG+ZPGX+ABS+ABSX
;
        .BYTE   ZPGY+ABSY       ; LDX
        .BYTE   IMM+ZPG+ABS
;
        .BYTE   0               ; LDY
        .BYTE   IMM+ZPG+ZPGX+ABS+ABSX
;
        .BYTE   ZPGY            ; STX
        .BYTE   ZPG+ABS
;
        .BYTE   0               ; STY
        .BYTE   ZPG+ZPGX+ABS
;
        .BYTE   0               ; CPX
        .BYTE   IMM+ZPG+ABS
;
        .BYTE   0               ; CPY
        .BYTE   IMM+ZPG+ABS
;
        .BYTE   0               ; BIT
        .BYTE   ZPG+ABS
        .PAGE
;
;       ADRBIT - VALID ADDRESS INDICATOR BY ADDRESS TYPE
;
;                ONE BIT SET IN EACH ENTRY TO INDICATE ADDRESS TYPE
;
ADRBIT
        .BYTE   00,INDX         ; INDIRECT X
        .BYTE   00,INDY         ; INDIRECT Y
        .BYTE   00,IMM          ; IMMEDIATE
        .BYTE   00,ACU          ; ACCUMULATOR
        .BYTE   00,ZPG          ; ZERO PAGE
        .BYTE   ZPGY,00         ; ZERO PAGE ]
        .BYTE   00,ZPGX         ; ZERO PAGE X
        .BYTE   00,ABS          ; ABSOLUTE
        .BYTE   ABSY,0          ; ABSOLUTE Y
        .BYTE   00,ABSX         ; ABSOLUTE X
        .PAGE
;
;       MODBIT - MODIFIER BYTE FOR OPCODE BY ADDR TYPE
;
MODBYT
        .BYTE   $00             ; INDIRECT X
        .BYTE   $10             ; INDIRECT Y
        .BYTE   $08             ; IMMEDIATE
        .BYTE   $08             ; ACCUMULATOR
        .BYTE   $04             ; ZERO PAGE
        .BYTE   $14             ; ZERO PAGE Y
        .BYTE   $14             ; ZERO PAGE X
        .BYTE   $0C             ; ABSOLUTE
        .BYTE   $18             ; ABSOLUTE Y
        .BYTE   $1C             ; ABSOLUTE X
;
;
;
;
;       LENTAB - LENGTH OF INSTRUCTION BY ADDR TYPE
;
LENTAB
        .BYTE   2               ; INDIRECT X
        .BYTE   2               ; INDIRECT Y
        .BYTE   2               ; IMMEDIATE
        .BYTE   1               ; ACCUMULATOR
        .BYTE   2               ; ZERO PAGE
        .BYTE   2               ; ZERO PAGE Y
        .BYTE   2               ; ZERO PAGE X
        .BYTE   3               ; ABSOLUTE
        .BYTE   3               ; ABSOLUTE Y
        .BYTE   3               ; ABSOLUTE X
        .PAGE
;
;       AINIT - ASM INIT COMMON TO BOTH MINI & ASM
;
;       AINIT2 - INIT FOR ASM PASS 2 ONLY
;
AINIT
;
;       SET DEFAULT PARMS
;
;
        JSR     ARES2           ;CONTRACT TABLES
        LDX     #SMBLD          ; EXPAND SYMBOL TABLE DUMMYS
        LDY     #4              ; X
        JSR     EXPLOW          ; X
        LDY     #3              ; SET END OF SYMBOLS
        LDA     #0              ; X
        STA     (SMBLTP),Y      ; X
;
        STA     LISTDTD         ; SET LIST DEVICE TO SCREEN
        STA     ENTDTD          ; SET ENTRY DEVICE TO MEMORY
        STA     OBJDTD          ; SET OBJECT DEVICE TO MEMORY
AINIT2
;
;       INIT - TITLE & PAGE BUFFER
;
;
        LDX     #TITLEND        ;EXPAND TITLE BUFFER
        LDY     #2              ; BY 2 BYTES
        JSR     EXPLOW          ; X
;
        LDX     #PAGEND         ;EXPAND PAGE BUFFER
        LDY     #2              ; BY 1 BYTE
        JSR     EXPLOW          ; X
;
        LDY     #0              ; SET LOCATION COUNTER =0
        STY     LOCCNT          ; X
        STY     LOCCNT+1        ; X
        STY     EOFFLG          ; SET NOT END OF FILE
        STY     OPTFLG          ; ZERO OPTION FLAG
        STY     LNCNT           ; # LINES ON PAGE = 0
        STY     COPTR           ; SET CURRENT ORG PTR TO = 0
        STY     COPTR+1         ; X
        STY     ERRDEX          ; CLEAR ERROR INDEX
        STY     ERRCNT          ; AND COUNT OF ERRORS
;
        LDA     #1              ; GET # BBYTES IN TITLE & PAGE
        STA     (TITLEP),Y      ; SET BLANK TITLE
        STA     (PAGEP),Y       ; SET BLANK PAGE
        INY                     ; X
        LDA     #$20+$80
        STA     (TITLEP),Y      ; X
        STA     (PAGEP),Y       ; X
;
;       SET DEFAULT TABS
;
        LDA     #12+PLST
        STA     TAB1
        LDA     #17+PLST
        STA     TAB2
        LDA     #27+PLST
        STA     TAB3
;
; INIT CURRENT STMT POINTER
;
        LDA     TXTTAB
        STA     STMCUR
        LDA     TXTTAB+1
        STA     STMCUR+1
        RTS
        .PAGE
;
;       ARESET - RESET AFTER ASM
;
ARES1
        LDA     #EMODE          ; SET TO EDITOR MODE
        STA     MODEFLG
ARESET
        LDA     #0              ; RESET
        STA     ENTDTD          ; ENTRY DEVICE
        STA     LISTDTD         ; LIST DEVICE
        STA     AUTOFLG         ; AUTO FLAG
        STA     ERRDEX          ; RESET ERROR INDEX
;
ARES2
        LDX     #SMBLTP+2       ;POINT TO START OF CONTRACT
        LDA     TXTEND          ; CONTRACT TABLES
        LDY     TXTEND+1        ; X
        JMP     CLR1            ; X
        .PAGE
;
;       XEXP - EXECUTE EXPRESSION
;
;       ON EXIT    FR0 - VALUE
;                  RESBYT - MINUS IF VALUE UNRESOLVED
;
XEXP
        LDA     #0              ; ZERO RESOLVED BYTE
        STA     RESBYT          ; X
;
        JSR     MOVNUM          ; MOVE # FROM OUTPUT
        STX     FR0             ; SAVE #
        STA     FR0+1
;
_XEXP1
        JSR     GETCODE         ; GET OPERATOR
        CMP     #TEOE           ; IS IT END OF EXPRESSION?
        BEQ     _EXDONE         ; IF YES, DONE
        PHA                     ; SAVE OPERATOR
        JSR     MOVNUM          ; GET OPERAND
        STX     FR1             ; SAVE OPERAND
        STA     FR1+1
;
        PLA                     ; GET SAVED OPERATOR
        JSR     __EDUM          ; GO TO PROPER ROUTINE
;
;       RETURN HERE FROM OPERATOR
;
        JMP     _XEXP1          ; IF OPERATION OK ..DO NEXT
;
;
;
;
;
;
_EXDONE
        LDA     FR0             ;GET RESULTS
        LDX     FR0+1           ;
        RTS
        .PAGE
;
;       GO TO PROPER ROUTINE
;
__EDUM
        ASLA
        TAY
        LDA     TABEXP-CPLUS-CPLUS+1,Y
        PHA
        LDA     TABEXP-CPLUS-CPLUS,Y
        PHA
        RTS
;
;
;
;
;       ROUTINE ADDRESSES FOR EXECUTE EXPRESSION
;
TABEXP
        .WORD   ADD-1           ; +
        .WORD   SUB-1           ; -
        .WORD   MUL-1           ; *
        .WORD   DIV-1           ; /
        .WORD   AND-1           ; &
        .PAGE
;
;       INTEGER ADD
;
AND
        LDA     FR0
        AND     FR1
        STA     FR0
        LDA     FR0+1
        AND     FR1+1
        STA     FR0+1
        RTS
;
;
;
;       INTEGER ADD
;
ADD
        CLC
        LDA     FR0
        ADC     FR1
        STA     FR0
        LDA     FR0+1
        ADC     FR1+1
        STA     FR0+1
        RTS
;
;       INTEGER SUBTRACT
;
SUB
        SEC
        LDA     FR0
        SBC     FR1
        STA     FR0
        LDA     FR0+1
        SBC     FR1+1
        STA     FR0+1
        RTS
;
;       DIV -- DIVIDE, FR0 BY FR1
;
;       ENTER:  16-BIT DIVIDEND IN FR0
;               16-BIT DIVISOR IN FR1
;
;       EXIT:   16-BIT QUIOTIENT IN FR0
;
DIV
        JSR     _MDSU           ; SET UP
;
_DOLP
        ASL     FR0
        ROL     FR0+1
        ROL     FR0EX
        ROL     FR0EX+1         ; SHIFT DIVIDEND LEFT
;
        SEC
        LDA     FR0EX
        SBC     FR1             ; TRIAL SUBTRACT OF LSB
        TAX                     ; (SAVE RESULT)
        LDA     FR0EX+1
        SBC     FR1+1           ; ...& MSB
        BCC     _DVJN           ; TRIAL SUBTRACT DIDN'T WORK
;
        STA     FR0EX+1
        STX     FR0EX           ; SUBTRACT WORKED...UPDATE DIV'D
        INC     FR0             ; ...& QUIOTIENT
;
_DVJN
        DEY
        BNE     _DOLP           ; LOOP TILL DONE
        RTS
;
;
;
;       MUL -- MULTIPLY
;
;       ENTER:  16 BIT ARGUMENTS IN FR0 & FR1
;
;       EXIT:   PRODUCT IN FR0
;
;
MUL
        JSR     _MDSU
;
_MOLP                           ; OUTER LOOP
        LSR     FR0EX+1
        ROR     FR0EX
        ROR     FR0+1
        ROR     FR0             ; SHIFT PARTIAL PROD & MULT'R
        DEY
        BMI     _MDRT           ; DONE WITH 17 SHIFTS 16 ADDS
;
        BCC     _MOLP           ; LS BIT WAS 0 NO ADD LOOP
;
        CLC                     ; LS BIT WAS 1 DO ADD
        LDX     #-2             ; CUTE TRICK
_MILP
        LDA     FR1+2,X         ; +2 BECUZ X STARTS OFF AT -2
        ADC     FR0EX+2,X       ;
        STA     FR0EX+2,X       ; ADD TO PARTIAL PRODUCT
        INX
        BNE     _MILP           ; LOOPS ONLY TWICE
        BEQ     _MOLP           ; TO NEXT BIT
;
;
;       MULTIPLY/DIVIDE SETUP
;
;
_MDSU
        LDA     #0
        STA     FR0EX
        STA     FR0EX+1         ; 0 TO EXTENSION
        LDY     #16             ; LOOP COUNTER
_MDRT   RTS
        .PAGE
;
;       MOVNUM - MOVE # TO FR0 FROM OUTPUT BUFFER
;
;       ON EXIT:   X - LOW ORDER BYTE
;                  A - MSB
;
;       SET RESOLVE BYTE
MOVNUM
        JSR     ORRES           ; OR # CODE WITH RESOLVE BYTE
        JSR     GETCODE
        TAX
        JSR     GETCODE
        RTS
;
;
;
;
;
;       ORRES - OR # CODE WITH RESOLVE BYTE
;
ORRES
        LDX     #0              ;GET RESOLVED CODE
        JSR     GETCODE
        BPL     _RES            ;IF CODE = 1 THEN, VALUE RESOLVED
        LDX     #1              ;ELSE GET UNRESOLVED CODE
_RES
        TXA                     ;PUT IT IN A
        ORA     RESBYT
        STA     RESBYT
        RTS
        .PAGE
;
;       BIT8 - TEST FOR VALID 8 BIT VALUE IN FR0
;
;
BIT8
        LDA     FR0+1           ; GET HI ORDER BYTE
        BEQ     _OKB            ; IF = 0, THEN VALUE OK
;
        CMP     #$FF            ; TEST FOR MINUS 8 BIT VALUE
        BEQ     _OKB
;
_ERRB
        JSR     VERROR          ; PROCESS ERR
_OKB                            ; GET VALUE
        LDA     FR0
        RTS
        .PAGE
;
;       OBJMAN - OBJECT MANGER
;
;
;       OBJM2 - PUT 2 BYTES TO OBJECT BUFFER
;
;       ON ENTRY   A - 1ST BYTE
;                  X - 2ND BYTE
;
OBJM2
        JSR     OBJMAN          ; PUT 1ST BYTE
        TXA                     ; GET SECOND BYTE
;
;       FALL THROUGH TO OBJMAN
;
;
OBJMAN
        LDY     OBJDEX
        STA     (OBJBUFF),Y
        INC     OBJDEX
        RTS
        .PAGE
;
;       ABORT
;
ABORT
        PLA
        LDA     #ERNORG         ; GET NOORG ERROR MESSAGE
        JSR     ERROR           ; PRINT ERROR
        JSR     PRTERR
        JMP     ABRK            ; ABORT
        .PAGE
;
;       OCNTL - OUTPUT CONTROLLER (OBJRCT & LISTING)
;
OCNTL
        LDA     PASSFLG         ; GET PASS FLAG
        BPL     _OC2            ; IF PASS = 2 THEN DO OUTPUT
_OC1
        CLC                     ; INCR LOC COUNTER
        LDA     LOCCNT
        ADC     OBJDEX
        STA     LOCCNT
        LDA     LOCCNT+1
        ADC     #0
        STA     LOCCNT+1
        RTS
_OC2
        LDA     OPTFLG          ; GET OPTION FLAG
        AND     #OOBJ           ; IF OBJ OPT = NO, THEN BR
        BNE     _OC5
;
;       PUT OBJECT TO MEMORY OR FILE
;
        LDA     OBJDEX          ; GET OBJECT INDEX
        BEQ     _OC5            ; IF NONE, BR
        LDA     LOCCNT          ; SAVE LOCATION COUNTER
        PHA                     ; X
        ORA     LOCCNT+1        ; IF LOC =0
        BEQ     ABORT           ; ABORT ASM
        LDA     LOCCNT+1        ; X
        PHA
;
        LDY     #0
        STY     TOBJDEX         ; SET OBJECT INDEX COUNTER
_OC3
        LDA     (OBJBUFF),Y     ; GET OBJECT BYTE
        LDX     OBJDTD          ; GET OBJECT DEVICE
        BNE     _OC6            ; IF = FILE, BR
;
        LDY     #0              ; ELSE PUT TO MEMORY
        STA     (LOCCNT),Y      ; X
        JMP     _OC7            ;
;
_OC6
        JSR     PUTC1           ; PUT TO FILE
;
_OC7
        INC     LOCCNT
        BNE     _OC4
        INC     LOCCNT+1
_OC4
        INC     TOBJDEX
        LDY     TOBJDEX
        CPY     OBJDEX
        BNE     _OC3
;
        PLA                     ; RESTORE LOCATION COUNTER
        STA     LOCCNT+1        ;X
        PLA                     ; X
        STA     LOCCNT                                                       ; ?
        .PAGE
_OC5
;
;       PRINT LISTING
;
ALIST
        LDA     #0              ; INIT OBJECT BUFFER PTR
        STA     TOBJDEX         ; X
        STA     POX             ; INIT OUTPUT INDEX
;
        JSR     TSTLIST         ; DO WE LIST?
        BNE     _OC1            ; DO WE LIST?
_AL6
;
        JSR     POBJL           ; ELSE PRINT OBJECT LINE
;
ALIST1
_AL1
        LDA     MODEFLG         ; GET MODE
        CMP     #MAMODE         ; = MINI ASM
        BEQ     _AL2            ; IF YES, DO CR
;
        JSR     PIN             ; PRINT INPUT LINE
        JMP     _AL4
;
_AL2
        JSR     PRCR            ; PRINT RETURN
_AL4
        LDA     OBJDEX          ; GET OBJECT INDEX
        BEQ     _AL3            ; IF =0 NONE TO PRINT
        JSR     POBJL           ; ELSE PRINT OBJECT LINE
        JMP     _AL2            ; REPEAT
_AL3
TSTOERR
        LDA     OPTFLG          ; GET OPTION FLAG
        AND     #OERR           ; IS ERROR, OPTION = NO
        BNE     _AL5            ; IS SO, SKIP ERROR LISTING
        JSR     PRTERR          ; PRINT ERRORS
_AL5
        RTS
        .PAGE
;
;       POBJL - PRINT 1 LINE OF OBJECT
;
POBJL
;
        JSR     TSTEJT
        LDY     LOCCNT+1
        LDA     LOCCNT          ; P.C. GETS PRINTED
        JSR     PRADRB          ; X
        LDA     OBJDEX          ; GET OBJECT INDEX
        BEQ     _PODONE         ; X=0 NONE TO PRINT
        LDA     OLBCNT          ; GET # OF BYTES TO PRINT ON LINE
        STA     ZT1             ; SAVE AS COUNTER
;
_PO1
        LDY     TOBJDEX         ; GET PTR TO OBJECT BYTE
        LDA     (OBJBUFF),Y     ; GET OBJECT BYTE
        JSR     PRIHEX          ; PRINT AS HEX
        INC     LOCCNT          ; INCR LOCATION COUNTER FOR NEXT PRINT
        BNE     _PO2            ; X
        INC     LOCCNT+1        ; X
_PO2
        INC     TOBJDEX         ; POINT TO NEXT BYTE
        DEC     OBJDEX          ; DEC # BYTES LEFT TO IN BUFFER
        BEQ     _PODONE         ; IF =0 THEN DONE
        DEC     ZT1             ; DEC # BYTES TO PRINT ON LINE
        BNE     _PO1            ; IF NOT = 0 DO AGAIN
_PODONE
        RTS
        .PAGE
;
;       PIN - PRINT INPUT LINE TO ASM LISTING
;
PIN
        LDA     #0              ; INIT INPUT BUFFER PTR
        STA     CIX             ; X
;
        LDA     #PLST           ; GET DISP TO START OF INPUT LINE PRINT OUT
        JSR     PRPAD           ; PRINT BLANKS TO START OF INPUT
;
;       PRINT LABEL
;
        LDA     IDISPL          ; DISPL TO END OF LABEL (ST OF INST)
        JSR     PRPL            ; PRINT PARTIAL LINE
;
        LDA     TAB1            ; PRINT PADDING BLANKS
        JSR     PRPAD           ; X
;
;       PRINT INSTRUCTION
;
        LDA     ADISPL          ; DISPL TO END OF INST (ST OF ADR)
        JSR     PRPL            ; PRINT PARTIAL LINE
        LDA     TAB2            ; PRINT PADDLING BLANKS
        JSR     PRPAD           ; X
;
;       PRINT ADDRESS
;
        LDA     CDISPL          ; PRINT ADDR
        JSR     PRPL            ; X
        LDA     TAB3            ; PRINT PADS
        JSR     PRPAD
;
;       PRINT COMMENT
;
_PIN1
        JSR     GETIN           ; GET CHAR FROM INBUFF
        PHA                     ; SAVE IT
        JSR     PRCHAR          ; PRINT IT
        PLA                     ; GET IT AGAIN
        CMP     #CR             ; IS IT CARRIDGE RETURN?
        BNE     _PIN1           ; IF NOT REPEAT
;
        RTS
        .PAGE
;
;       PRPL - PRINT PARTIAL LINE FOR ASM
;
;       ON ENTRY   A - DISPL TO LAST CHAR TO PRINT +1
;                  CIX - DISPL OF 1ST CHAR TO PRINT
;
PRPL
        SEC                     ; GET # OF BYTES TO PRINT
        SBC     CIX             ; X
        STA     PRCNT           ; SAVE IT AS COUNTER
        BEQ     _PRPL2
        BCC     _PRPL2
;
_PRPL1
        JSR     GETIN           ; GET A CHAR
        JSR     PRCHAR          ; PRINT IT
        DEC     PRCNT           ; DEC COUNTER
        BNE     _PRPL1
_PRPL2
        RTS
        .PAGE
;
;       PRPAD - PRINT PADDING BLANKS FROM
;               POX TO TAB VALUE
;
;       ON ENTRY   A - TAB VALUE
;                  POX - CURRENT OUTPUT CHAR COUNT
;
PRPAD
        SEC
        SBC     POX             ; GET # OF BLANKS TO PRINT
        BCC     _PAD            ; IF TAB <= CURRENT INDEX, BR
        BEQ     _PAD
        BNE     PRBLANKS        ; PRINT BLANKS
        .PAGE
;
;       PRBLANKS - PRINT BLANKS
;
;       ON ENTRY   A - # OF BLANKS TO PRINT
;
;       PRBLK3 - PRINT 3 BLANKS
;
;
;
;
PRBLK3
        LDA     #3              ; GET 3 BLANKS TO PRINT
PRBLANKS
        STA     BLKCNT          ; SAVE # OF BLANKS TO PRINT
_PRB
        JSR     PRBLK1          ; PRINT A BLANK
        DEC     BLKCNT
        BNE     _PRB
_PAD
        RTS
        .PAGE
;
;       TSTLIST - TEST TO SEE IF LINE NEEDS LISTING
;
;       ON EXIT    CC = Z IF LIST
;                  CC = NZ IF NO LIST
;
;
TSTLIST
        LDA     PASSFLG         ; GET PASS FLAG
        BMI     _TL1            ; IF PASS1, DON'T LIST
;
        LDA     OPTFLG          ; GET OPTION FLAG
        AND     #OLIST          ; IF LIST = YES
        BEQ     _TL1            ; THIN LIST (ALREADY SET)
        LDA     OPTFLG          ; ELSE GET OPTION FLAG AGAIN
        AND     #OERR           ; IF ERROR = NO
        BNE     _TL1            ; DON'T LIST (ALREADY SET)
        LDA     ERRDEX          ; ELSE IF NO ERRORS
        BEQ     _NL             ; THIN DON'T LIST
        LDA     #0              ; ELSE SET CC FOR LIST
_TL1
        RTS
;
_NL
        LDA     #$FF
        RTS
        .PAGE
;
;       TSTEJT - TEST FOR PAGE EJECT
;
TSTEJT
        LDA     LNCNT
        CMP     LINESPERPAGE
        BNE     _TSTE1          ; IF NOT, DONE
;
        LDA     OPTFLG          ; GET OPTION FLAG
        AND     #OPAGE          ; IS PAGE OPTION = NO?
        BNE     _TSTE1          ; IF SO, DON'T DO PAGE EJECT
;
        LDA     POX             ; SAVE OUTPUT INDEX
        PHA
        JSR     PAGE1           ; DO PAGE EJECT
        PLA
        STA     POX             ; RESTORE  INDEX
_TSTE1
        INC     LNCNT           ; INCR # LINES ON PAGE
        RTS
        .PAGE    'AUTO'
;
;       AUTO - PUT OUT AUTO LINE NUMBER
;
AUTO
        LDA     CURLN           ; MOVE CUR LINE #
        STA     TSLNUM          ; TO SEARCH LINE #
        STA     FR0             ; & FR0 FOR CONVERT
        LDA     CURLN+1         ; X
        STA     TSLNUM+1        ; X
        STA     FR0+1           ; X
;
        JSR     GETSTMT         ; DOES STMT ALREADY EXISTS?
        BCS     _AUTO           ; IF NOT, DO AUTO
        LDA     #AUTOFF         ; TURN OFF AUTP
        STA     AUTOFLG         ; X
        JMP     ESYNTAX
;
_AUTO
        JSR     PRINUM          ; PRINT THE #
;
        LDY     TPCIX           ; POINT TO LAST DIGIT OF NUM
        LDA     (INBUFF),Y      ; GET IT
        AND     #$7F            ; TURN OFF MSB
        STA     (INBUFF),Y      ; SAVE IT
        INY                     ; POINT TO NEXT SPACE
        LDA     #$20            ; GET BLANCK
        STA     (INBUFF),Y      ; PUT IN INPUT LINE
        INY                     ; POINT TO FREE SPACE
        STY     TPCIX           ; SAVE
;
        JSR     PRCHAR          ; PRINT THE BLANK
;
;       SET UP FOR I/O
;
        CLC                     ; GET INPUT BUFFER ADDR
        LDA     INBUFF          ; X
        ADC     TPCIX           ; X (LINE # LENGTH)
        STA     INBUFF          ; X
        LDA     INBUFF+1        ; X
        ADC     #0              ; X
        STA     INBUFF+1        ; X
;
        LDA     #127            ; GET INPUT BUFFER LENGTH
        SEC                     ; X
        SBC     TPCIX           ; X (LINE # LENGTH)
        TAY
;
        JSR     GCXI            ;SET DEVICE & COMMAND
;
        JSR     IO3             ; DO I/O
        JSR     IOTEST          ; TEST RESULT
        JMP     INTLBF          ; RE-INIT INBUFF
;
;
;
;
;       UPCUR - UPDATE CURRENT LINE # FOR AUTO OR REN
;
UPCUR
UPAUTO
        CLC                     ; NEW CURRENT LINE NUMBER EQU
        LDA     CURLN           ; CUR LINE NUM+INCR
        ADC     LNINCR          ; X
        STA     CURLN           ; X
        LDA     CURLN+1         ; X
        ADC     LNINCR+1        ; X
        STA     CURLN+1         ; X
        BCC     _TSTE1          ; JUST AN 'RTS' IN <= 65535
;
_UPERR
        LDA     #EROVFL
        JSR     ERROR
        .PAGE    'I/O ROUTINE'S'
;       LOCAL
;
;       GETLINE - GET A LINE OF INPUT FOR SOMEONE
;
;
;       GLINE - GET LINE (PROMPT ONLY)
;       GNLINE - GET NEW LINE (CR, PROMPT)
;
GNLINE
        LDA     AUTOFLG         ; GET AUTO FLAG
        BNE     AUTO            ; IF IN AUTO, GO DO IT
;
GLGO
        JSR     GCXI            ; GET COMMAND & DEVICE
        JSR     IO1             ; GO DO I/O
        JMP     IOTEST          ; GO TEST RESULT
        .PAGE
;
; PRINT CR
;
PRCR    LDA     #CR
;       FALL THRU TO PUT THE CHAR
;
;
;       PUTCHAR - PUT ONE CHAR TO LIST DEVICE
;
PRCHAR
PUTCHAR
        LDX     LISTDTD         ; GET LIST DEVICE
PUTC1
PRCX
        INC     POX             ; INCR OUTPUT INDEX
        PHA                     ; SAVE IO BYTE
        JSR     GLPX            ; SET DEVICE
;
        LDA     ICAUX1,X        ; SET UP ZERO PAGE IOCB
        STA     ICAUX1-IOCB+ZICB
        LDA     ICAUX2,X
        STA     ICAUX2-IOCB+ZICB
;
        PLA
        TAY
        JSR     _PDUM
;
;       RETURN HERE FROM ROUTINE
;
        TYA                     ; TEST STATUS
        JMP     IOTES2
;
;
_PDUM
        LDA     ICPUT+1,X       ; GO TO PUT ROUTINE
        PHA
        LDA     ICPUT,X
        PHA
        TYA
        LDY     #$92            ; LOAD VALUE FOR CIO ROUTINE
        RTS
;
;
GCXI
        LDX     ENTDTD          ; GET DEVICE
        LDA     #ICGTR          ; GET COMMAND
;
GLPCX   STA     IOCMD
GLPCX1
GLPX
        STX     IODVC           ; AS I/O DEVICE
        JMP     LDDVX           ; LOAD DEVICE X
        .PAGE
;
; HPUTO2 -- CONDITIONAL PUTO2, HEADER BYTES ONLY
;
HPUTO2
        LDY     OBJDV*16+ICDNO  ; GET DEVICE #
        CPY     #9              ; DEVICE 9?
        BNE     PUTO2           ; NO
        RTS                     ; YES...DON'T DO IT!
;
;
;       PUTO2 - OUTPUT 2 BYTES TO OBJECT FILE
;
;
;       ON ENTRY   A - OBJECT BYTE HIGH
;                  X - OBJECT BYTE LOW
;
;
;       PUTOBJ
;
;       ON ENTRY   A - OBJECT BYTE
;
PUTO2
        PHA
        TXA
        JSR     PUTOBJ
;
        PLA
PUTOBJ
        LDX     OBJDTD
        BNE     PUTC1
        RTS                     ; IN CASE
        .PAGE
;
;       OPEN - OPEN FILE
;       ON ENTRY   A - TYPE OF RECORD
;
;
;       FLIST - OPEN FOR LIST
;
;       FLOAD - OPEN FOR LOAD
;
FLIST
        LDA     #8              ; CODE FOR OUTPUT
        LDY     #LISDV          ; USE LIST DEVICE
        STY     LISTDTD         ; SET LIST DEVICE
        JMP     OPEN            ; OPEN DEVICE
;
;
;
FLOAD2
        INC     COX
FLOAD
        LDA     #4              ; CODE FOR INPUT
        LDY     #LOADDV         ; USE LOAD DEVICE
        STY     ENTDTD
        JMP     OPEN            ; OPEN DEVICE
;
;
;
FOBJ
        LDA     #8              ; CODE FOR OUTPUT
        LDY     #OBJDV          ; USE OBJECT DEVICE
        STY     OBJDTD          ; SET OBJECT DEVICE
;
;
OPEN
        PHA                     ; SAVE TYPE RECORD
        STY     IODVC           ; SET DEVICE #
        JSR     STRMOV          ; MOVESS FNAM TO BUFFER
        PLA
; SECOND ENTRY POINT...FOR OBJECT FILES
OP2     PHA
        JSR     CLSYSD          ; CLOSE THIS FILE
        JSR     LDDVX
        LDA     #ICOIO
        STA     IOCMD           ; "OPEN" COMMAND
        STA     ICCOM,X
        LDA     #.LOW.FNBUFF
        STA     ICBAL,X
        LDA     #.HIGH.FNBUFF
        STA     ICBAH,X
        PLA
        STA     ICAUX1,X
        LDA     #0
        LDY     FNBUFF
        CPY     #'C
        BNE     OP2X
        LDY     FNBUFF+1
        CPY     #'9
        BNE     OP2X
        LDA     #$80
OP2X    STA     ICAUX2,X
        JSR     CIO
        JMP     IOTEST
        .PAGE
;
; LDDVX - LOAD X REG WITH I/O DEVICE OFFSET
;
LDDVX
        LDA     IODVC           ; GET DEVICE
        ASLA                    ; MULT BY 16
        ASLA
        ASLA
        ASLA
        TAX                     ; PUT INTO X
        RTS                     ; AND RETURN
        .PAGE
;
; IOTEST - TEST I/O STATUS
;
IOTEST
        JSR     LDIOSTA         ; LOAD I/O STATUS
IOTES2
        BMI     SICKIO          ; BR IF BAD
        RTS                     ; ELSE RETURN
;
SICKIO
        LDY     #0              ; RESET DISPLAY FLAG
        LDY     DSPFLG
;
        STA     ERRNUM          ; SAVE ERROR #
;
        CMP     #ICSBRK         ; IF BREAK THEN
        BNE     _SIO1           ; SUMULATE ASYNC BR
        LDY     #0
        STY     BRKBYT          ; X
        JMP     CLFILE          ; GO CLEAN UP FILES
_SIO1
;
        LDA     IODVC
        CMP     ENTDTD          ; WAS IT ENTER DEVICE
        BEQ     _SIO2           ; IF YES BR
        BNE     _SIO6           ;
_SIO7
        STA     ERRNUM          ; SAVE ERROR #
        JSR     ARES1           ; RESET FOR EDITOR
;
_SIO2
        LDA     MODEFLG
        BMI     _SIO5
        JSR     CLFILE          ; CLEAR UP FILES
        BNE     _SIO2B          ; IF NOT EOF, PRINT ERROR
        LDY     MODEFLG         ; IF NOT IN EDITOR
        BNE     _SIO2A          ; RETURN TO CALLER
        JMP     ESYN2           ; ELSE GO TO SYNTAX
;
_SIO6
        JSR     CLFILE
        BEQ     _SIO2A          ; DON'T PRINT MESSAGE, IF EOF
_SIO2B
        JSR     ERROR
_SIO2A
        RTS
;
;
_SIO5
        LDA     PASSFLG         ; GET PASSFLAG
        BPL     _SIO6           ; IF PASS 2, CLOSE DEVICE
        LDA     ERRNUM
        CMP     #$88
        BNE     _SIO6
        LDX     ENTDTD          ; GET LOAD DEVICE
        LDA     #PTCMD          ; GET POINT COMMAND
        JSR     GLPCX
;
        LDA     #0              ; SET UP FOR POINT
        STA     ICAUX5,X        ; X
        LDA     TEMPRL          ; GET VALUE LOW FOR PRINT
        STA     ICAUX3,X        ; X
        LDA     TEMPRL+1        ; GET VALUE HIGH FOR POINT
        STA     ICAUX4,X        ; X
        JSR     IO7             ; DO POINT
        JSR     LDIOSTA         ; GET STATUS
        BMI     _SIO7           ; IF ERROR HANDLE IT
        LDA     #$88
        RTS
;
;
CLFILE
        LDA     #SCRDV
        STA     ENTDTD
        STA     LISTDTD         ; RESET LIST DEVICE
        STA     OBJDTD          ; RESET OBJECT DEVICE
        JSR     CLSALL          ; CLOSE ALL DEVICES
        LDA     ERRNUM          ; GET ERROR #
        CMP     #$88            ; IF END OF FILE
        RTS
        .PAGE
;
;       CLSYSD - CLOSE SYSTEM DEVICE
;
CLSYSD  JSR     LDDVX           ; LOAD DEVICE X REG
        BEQ     NOCDO           ; DON'T CLOSE DEVICE # 0
        LDA     #ICCLOSE        ; LOAD CLOSE CORD
        JMP     IO8             ; GO CLOSE
;
;
;       LDIOSTA - LOAD I/O STATUS
;
LDIOSTA
        JSR     LDDVX           ; GET DEVICE X REG
        LDA     ICSTA,X         ; GET STATUS
NOCDO
        RTS                     ; RETURN
;
;
;
;
;       CLSALL - CLOSE ALL DEVICES
;
CLSALL
        LDY     #3              ; START AT 3
CLALL7
        STY     IODVC
CLALL1
        JSR     CLSYSD          ; CLOSE DEVICE
        DEC     IODVC           ; DECR DEVICE #
        BNE     CLALL1          ; BR IF NOT 0
        RTS                     ; DONE IF 0
        .PAGE
;
;       I/O CALL ROUTINE
;
IO1     LDY     #119            ; BUFL = 119
        BNE     IO3
IO2     LDY     #0              ; BUFL = 0
IO3     LDA     #0              ; BUFL < 256
IO4     STA     ICBLH,X         ; SET BUFL
        TYA
        STA     ICBLL,X
IO5     LDA     INBUFF+1        ; LOAD INBUFF VALUE
        LDY     INBUFF
IO6     STA     ICBAH,X         ; SE BUF ADR
        TYA
        STA     ICBAL,X
IO7     LDA     IOCMD           ; LOAD COMMAND
IO8     STA     ICCOM,X         ; SET COMMAND
        LDA     #0              ; CLEAR AUX 2
        STA     ICAUX2,X
        JMP     CIO             ; GO DO I/O
        .PAGE
;
;       TSTBRK - TEST FOR BREAK
;
;       ON EXIT    CC = 0 IF NO BREAK
;                  CC = NOT 0 IF BREAK HIT
;
TSTBRK
        LDY     #0
;
        LDA     BRKBYT          ; LOAD BREAK BYTE
        BNE     _TB2
        LDY     #$FF            ; TURN OFF BRK BYTE
        STY     BRKBYT
_TB2    TYA                     ; SET COND CODE
        RTS                     ; DONE
        .PAGE
;
;       GETSTMT - GET STMT IN STMT TABLE
; SEARCH FOR STMT THAT WAS TSLNUM
;       SET STMCUR TO POINT TO IT IF FOUND
;       OR TO WHERE IT WOULD GO IF NOT FOUND
;       CARRY SET IF NOT FOUND
GETSTMT
        LDA     TXTTAB+1        ; START AT TOP OF TABLE
        LDY     TXTTAB
;
        STA     STMCUR+1        ; SET STMCUR = TOP OF TABLE
        STY     STMCUR
;
;
_GS2
        JSR     TSTTEND         ; TST FOR END OF TXT
        BCS     _GSRT1          ;
        LDY     #1              ; GET INDEX
        LDA     (STMCUR),Y      ; GET STMT LNO (HI)
        CMP     TSLNUM+1        ; TEST WITH TSLNUM
        BCC     _GS3            ; BR IF S<TS
        BNE     _GSRT1          ; BR IF S>TS
        DEY                     ; EQUAL...TEST LOW BYTE
        LDA     (STMCUR),Y
        CMP     TSLNUM
        BCC     _GS3            ; BR S<TS
        BNE     _GSRT1          ; BR S>TS
        CLC                     ; S=TS, CLEAR CARRY
_GSRT1
        RTS                     ; AND RETURN (FOUND)
;
_GS3
        JSR     GETLL           ; GET TO NEXT LINE
        JSR     GNXTL
        JMP     _GS2
;
;
GETLL
        LDY     #2              ;GET STATEMENT LENGTH
        LDA     (STMCUR),Y
        RTS
;
GNXTL
        CLC                     ;GET NEXT STATEMENT
GNXTL1
        ADC     STMCUR
        STA     STMCUR
        TAY
        LDA     STMCUR+1
        ADC     #0
        STA     STMCUR+1
        RTS
        .PAGE    'ERROR ROUTINE'
;
;
;
;
;       ERROR - COMMON ERROR ROUTINE
;
VERROR
        LDA     #ERVAL          ; VALUE ERROR
EDERR
ERROR
        LDX     #0              ; RESET DISPLAY FLAG
        STX     DSPFLG
        LDX     ERRDEX          ; GET INDEX INTO ERROR BUF
        CPX     #3              ; IS BUFFER FULL?
        BCS     _ERTN           ; IF YES, DON'T STORE ERROR #
        DEX                     ;POINT TO LAST ERROR
        CMP     ERRBUF,X        ;IS IT SAME AS CURRENT ERROR ?
        BEQ     _ERTN           ;IF YES DON'T PUT IT IN BUFFER
        INX                     ;POINT TO NEXT ERROR LOCATION
        STA     ERRBUF,X        ; SAVE ERROR #
        INC     ERRDEX          ; INCR INDEX
_ERTN
;
        ASLA                    ; CARRY WILL BE SET IF I/O ERROR
        LDA     MODEFLG
        BPL     _ERTN1          ; BR IF NOT ASM
        BCC     _ASMERR         ; BR IF NOT I/O ERROR
_ERTN1
        JSR     PRTERR
        LDY     MODEFLG         ; GET MODE
        DEY                     ; ONLY DEBUG=(1) MODE WILL BE >=0
                                ; (MINI ASM CAN'T GIVE I/O ERROR
        BMI     _EDERR
        JMP     DSYNTAX
_EDERR
        JMP     ESYNTAX
_PRNON
_ASMERR
        RTS                     ; RETURN TO CALLER
;
;
;
;
;       PRTERR - PRINT ERROR MESSAGE
;
PRTERR
        LDA     ERRDEX          ; GET ERROR INDEX
        BEQ     _PRNON          ; IF NO ERRORS, EXIT
        LDA     MODEFLG         ; IF IN ASM MODE
        BPL     _PRT1           ; X
        JSR     TSTEJT          ; TEST FOR PAGE EJECT
        INC     ERRCNT          ; ANOTHER ERROR
        BNE     _PRT1           ; OK
        DEC     ERRCNT          ; OOPS...256 OR MORE
_PRT1
        LDA     #BELL           ; RING BELL
        JSR     PRCHAR
;
        LDX     #.LOW.ERRMSG    ; GET MESSAGE ADDR LOW
        LDY     #.HIGH.ERRMSG   ; GET MESSAGE ADDR HIGH
        JSR     MSGXY           ; GO PRINT MESSAGE
;
;
_PENUM
        DEC     ERRDEX          ; POINT TO NEXT ERROR #
        BMI     _PEDONE         ; IF NONE LEFT, DONE
        LDX     ERRDEX          ; GET ERROR INDEX
        LDA     ERRBUF,X        ; GET ERROR #
        JSR     PRNUMA          ;PRINT NUMBER IN A
        JSR     PRBLK1          ; PRINT A BLANK
        JMP     _PENUM
;
_PEDONE
        LDX     #0              ; ZERO ERROR INDEX
        STX     ERRDEX          ; X
        JMP     PRCR            ; PRINT RETURN
;
;
;
ERRMSG
        .BYTE    '***ERROR -',$80+' '
        .PAGE    'PRINT ROUTINES'
; PRINT NUMBER IN A-REGISTER
;
PRNUMA  STA     FR0
        LDA     #0              ; UPPER BYTE ASSUMED=0
        STA     FR0+1           ; FALL THRU TO PRINUM
;
;
;       PRINUM - PRINT A DECIMAL NUMBER
;
;       ON ENTRY   FR0 - CONTAINS 2 BYTE NUMBER
;
PRINUM
        JSR     IASC            ; MAKE PRINTBLE
        LDX     INBUFF
        LDY     INBUFF+1
        JSR     MSGXY           ; PRINT IT
        STY     TPCIX
        RTS
;
;
;
;
;       IASC - CONVERT INTEGER TO ASCII
;
;       ON ENTRY   FR0 - CONTAINS INTEGER
;       ON EXIT    INBUFF - POINTS TO START OF #
;
IASC
        JSR     IFP             ; CONVERT TO FP
        JMP     FASC            ; CONVERT TO ASCII
        .PAGE
;
;       PRHEX2 - PRINT A 2 BYTE HEX NUMBER
;
;       ON ENTRY   A - 2ND BYTE TO PRINT (LOW)
;                  Y - 1ST BYTE TO PRINT (HIGH)
;
PRHEX2
        PHA                     ; SAVE 2ND BYTE
        TYA                     ; GET 1ST BYTE TO PRINT
        JSR     PRIHEX          ; GO PRINT IT
;
        PLA                     ; GET 2ND NUMBER
;
;
;
;
;       PRIHEX - PRINT A 1 BYTE HEX NUMBER
;
;       ON ENTRY   A - HEX #
;
PRIHEX
        PHA                     ; SAVE THE HEX #
;
        LSRA                    ; GET LEFT DIGIT
        LSRA
        LSRA
        LSRA
;
        JSR     _PRIH           ; GO PRINT IT
;
        PLA                     ; GET # AGAIN
        AND     #$0F            ; GET RIGHT DIGIT
_PRIH
        ORA     #'0             ; 0-9 OK
        CMP     #'9+1           ; BUT...IF > '9'...
        BCC     _PRIH2
        ADC     #6              ; ADJUST THUSLY
_PRIH2
        JMP     PRCHAR          ; PRINT IT
;
;
;
;
;
;
;
;       PRADRB - PRINT ADDR FOLLOWED BY BLANK
;
;       ON ENTRY   A - ADDR LOW
;                  Y - ADDR HIGH
;
PRADRB
        JSR     PRHEX2          ; PRINT ADDR
; (FALL THRU)
;
; PRINT ONE BLANK
;
PRBLK1
        LDA     #$20
        JMP     PRCHAR
;
;
;
;
;
;       PRHEXB - PRINT HEX NUMBER FOLLOWED BY A BLANK
;
;
;       ON ENTRY   A - HEX #
;
PRHEXB
        JSR     PRIHEX
        JMP     PRBLK1
;
;
;
        .PAGE
;
;       MSGXY - PRINT A MESSAGE
;
;       ON ENTRY   X - MESSAGE ADDR LOW
;                  Y - MESSAGE ADDRHIGH
;                  MESSAGE HAS MSB OF LAST BYTE ON
;
;       (ASSUMES MESSAGES DO NOT CONTAIN CR OR NON-PRINTING CHAR)
;
MSGXY
        STX     MSGADR          ; SAVE ADR
        STY     MSGADR+1        ; X
;
        LDY     #$FF            ; INIT INDEX
_MSG1
        INY
        STY     ZT1             ; INCR & STORE INDEX
        LDA     (MSGADR),Y      ; GET CHAR
        PHA                     ; SAVE CHAR
        AND     #$7F            ; TURN ON MSB
;
        JSR     PRCHAR          ; GO PRINT CHAR
;
        LDY     ZT1             ; RETURN WITH THIS OR BUMP IT
        PLA                     ; GET CHAR AGAIN
        BPL     _MSG1           ; IF NOT END OF MESSAGE - DO AGAIN
        RTS
;
;
;
;
;       MSGXYCR - PRINT A CR AFTER MESSAGE
;
MSGXYCR
        JSR     MSGXY           ; PRINT MESSAGE
        JMP     PRCR            ; PRINT CR
        .PAGE    'ATARI CARTRIDGE VECTORS'
        *=CRTGI
SCVECT
        RTS
        .WORD   COLDSTART
        .BYTE   0               ; CART EXISTS
        .BYTE   5               ; FLAG
        .WORD   SCVECT          ; COLDSTART ENTRY ADDR
        .PAGE    'END OF BASIC'
        .END
