MONDEB.asm
crsjones_68Retro/6800-BUGS/MONDEB/MONDEB.asm
        NAM   MONDEB
        ;CPU   6800
;THIS SOURCE CODE WAS SENT TO WALTER BANKS AT
;THE UNIVERSITY OF WATERLOO BY DON PETERS ON PAPER TAPE
;CROSS ASSEMBLY WAS DONE ON THE U OF W HONEYWELL 66/60
;THE BARCODE AND LISTING WERE SET ON A PHOTON PHOTO-
;TYPESETTER DRIVEN BY THE HONEYWELL.
;
;       M O N D E B  - A MONITOR/DEBUGGER FOR THE M6800 MICROPROCESSOR

; AUTHOR: DON PETERS
; DATE: APRIL 1977
; MEMORY REQ'D: 3K BYTES AT HIGH END OF ADDRESS SPACE

; SEE USER MANUAL FOR CAPABILITIES & INSTRUCTIONS ON USE

;      * =     $400    ;DEBUG ORG AT 1K
;       * =    $F400    ;NORMAL ORIGIN AT 61K
       ORG     $F400


;I/O DEVICE ADDRESSES
ACIA1  EQU    $7F01    ;ACIA #1 - MAIN TERMINAL ACIA
ACIA2  EQU    $7F05    ;ACIA #2 - AUXILIARY TERMINAL ACIA

;OTHER CONSTANTS
CR     EQU    13       ;CARRIAGE RETURN
LF     EQU    10       ;LINE FEED



START  EQU    *        ;PROGRAM ENTRY POINT
       LDS    #STACK   ;INITIALIZE THE STACK POINTER
       STS    SP       ;SAVE THE POINTER
       JSR    INITAL   ;INITIALIZE VARIABLES


;TYPE OUT MONITOR NAME & VERSION
       JSR    DOCRLF   ;ADVANCE TO A CLEAN LINE
       LDX    #MSGHED  ;GET ADDRESS OF HEADER
       JSR    OUTSTR   ;TYPE IT

;SET UP DESTINATION OF INPUT LINE
;DEFINE BEGINNING OF INPUT BUFFER
       LDX    #TTYBUF-1   ;GET ADDRESS OF TERMINAL INPUT BUFFER
       STX    BUFBEG   ;SAVE IT

;DEFINE END OF INPUT BUFFER - 72 CHAR CAPACITY, INCL CR
       LDX    #TTYEND
       STX    BUFEND

;DELIMITER CLASS DEFINITION - SPACE OR COMMA (CODE 3)
       LDAA   #3
       STAA   DELIM
       BRA    PROMP1

;PREPARE TO GET A NEW COMMAND
PROMPT JSR    DOCRLF   ;TYPE CR-LF
       INC    BOLFLG   ;SET "BEGINNING OF LINE" FLAG
       LDX    SYNPTR   ;POINT TO CURRENT CHARACTER
       LDAA   ,X       ;GET IT
       CMPA   #';'     ;SEMICOLON?
       BEQ    GETCMD   ;CONTINUE SCAN IF IT IS, SKIPPING THE PROMPT

;TYPE PROMPT
PROMP1 LDX    #MSGPRM
       JSR    OUTSTR

       JSR    GETLIN  ;GET LINE OF INPUT

;ABORT LINE ON A CONTROL-C
       CMPB   #3
       BEQ    PROMPT

;SET SYNTAX SCANNING POINTER TO BEGINNING OF BUFFER/LINE
       LDX    BUFBEG
       STX    SYNPTR

;REPROMPT ON AN EMPTY LINE (FIRST CHAR = CR, LF, OR ;)
       LDAA   1,X      ;GET FIRST CHAR
       JSR    TSTEOL   ;TEST IT
       BEQ    PROMPT   ;IF IT IS, PROMPT AGAIN

;USE LIST 1 WHEN MATCHING
GETCMD LDAA   #1

;NOW GO FOR A MATCH
       JSR    COMAND

;-AND TEST THE RESULT OF THE SCAN
       BEQ    PROMPT   ;REPROMPT IF JUST A CR WAS TYPED
       BGT    JMPCMD   ;GOOD COMMAND IF POSITIVE

;*****
;UNRECOGNIZABLE SYNTAX - POINT TO ERROR
BADSYN LDX    BUFBEG   ;GET START OF LINE
;SPACE OVER TO ERROR IN SYNTAX
BADS1  CPX    LINPTR   ;AT ERROR?

       BEQ    BADS2
       JSR    OUTSP    ;OUTPUT A SPACE
       INX             ;NO, MOVE ON
       BRA    BADS1

;THE "EXTRA" CHAR "1" IS COMPENSATED FOR BY THE PROMPT CHAR ON THE PRECEDING LINE
BADS2  LDAA   #'^'     ;AT ERROR - GET AN UP-ARROW
       JSR    OUTCHR   ;PRINT IT
       JSR    DOCRLF
       BRA    PROMP1   ;IGNORE ANY SUCCEEDING PACKED
;                        COMMANDS

;*****
;THERE SHOULD BE NO MORE CHARACTERS ON THE INPUT LINE
;                       (EXCEPT DELIMITERS)
NOMORE JSR    SKPDLM
       BCS    PROMPT   ;IF CARRY BIT SET, END OF LINE (NORMAL)
;THERE IS SOMETHING THERE BUT SHOULDN'T BE
       BRA    BADSYN

;*****
;EXECUTE A COMPUTED "GOTO" TO THE PROPER COMMAND
JMPCMD TAB             ;SAVE COMMAND # IN ACCB
       ASLA            ;MULTIPLY COMMAND BY 2
       ABA             ;ACCA NOW HOLDS COMMAND # MULTIPLIED BY 3
;ADD IT TO BASE OF JUMP TABLE
       LDAB   #JMPHI   ;GET HI BYTE OF START OF JUMP TABLE IN ACCB
       ADDA   #JMPLO   ;ADD LO BYTE OF START OF JUMP TABLE TO ACCA
       ADCB   #0       ;ADD CARRY IF THERE WAS ONE
;MOVE ACCA & ACCB TO IX (CODE IS WEIRD, BUT BRIEF)
       PSHA
       PSHB
       TSX             ;PUT ADDRESS OF "GOTO" INTO X
       LDX    ,X       ;GET THE ADDRESS ITSELF
       PULB            ;RESTORE THE STACK
       PULA

       JMP    ,X       ;JUMP TO RIGHT COMMAND

JMPTBL EQU    *-3

JMPHI  EQU    JMPTBL/256
JMP256 EQU    JMPHI*256
JMPLO  EQU    JMPTBL-JMP256

       JMP    REG
       JMP    GOTO
       JMP    LSEI
       JMP    LCLI
       JMP    COPY
       JMP    BREAK
       JMP    IBASE
       JMP    DBASE
       JMP    CONTIN
       JMP    DISPLA
       JMP    SET
       JMP    VERIFY
       JMP    SEARCH
       JMP    TEST
       JMP    INT
       JMP    NMI
       JMP    LSWI
       JMP    COMPAR
       JMP    DUMP
       JMP    LOAD
       JMP    DELAY
;*****
;REG - DISPLAY REGISTERS
REG    EQU    *
;PRINT STACK STORED SWI DATA
DISREG LDX    SP       ;GET SAVED STACK POINTER
       INX
;REGISTER NAME TYPEOUT INITIALIZATION
       CLR    COMNUM   ;START AT BEGINNING OF THE REGISTER NAME LIST

       BSR    OUT2     ;TYPE CONDITION CODES
       BSR    OUT2     ;TYPE ACCB
       BSR    OUT2     ;TYPE ACCA

       BSR    OUT4     ;TYPE INDEX REG
       BSR    OUT4     ;TYPE PROGRAM COUNTER

;TYPE THE STACK POINTER LOCATION
       BSR    OUT2A4   ;TYPE STACK POINTER ID
       LDX    #SP
       JSR    OUT2BY   ;TYPE THE VALUE

       JMP    NOMORE

;OUTPUT CONTENT OF A 1 BYTE REGISTER
OUT2   BSR    OUT2A4
       JSR    OUT1BY
       INX
       RTS

;OUTPUT CONTENT OF A 2 BYTE RESISTER
OUT4   BSR    OUT2A4
       JSR    OUT2BY
       INX             ;SKIP TO NEXT BYTE IN STACK
       INX             ;SKIP TO NEXT BYTE IN STACK
       RTS

;MISC SETUP FOR REGISTER DISPLAY
OUT2A4 JSR    OUTSP    ;OUTPUT A SPACE
       INC    COMNUM   ;SKIP TO NEXT REGISTER NAME
       LDAA   #5       ;REGISTER NAME IS IN LIST 5
       JSR    TYPCMD   ;TYPE IT
       JSR    OUTEQ    ;TYPE AN "="
       RTS

;ENTER HERE FROM SOFTWARE INTERRUPT
TYPSWI LDX    #MSGSWI
       JSR    OUTSTR
;DECREMENT PC SO IT POINTS TO "SWI" INSTRUCTION
       LDX    SP
       TST    7,X      ;TEST LO BYTE OF PC FOR PENDING BORROW
       BNE    TYPSW1
       DEC    6,X      ;NEED TO BORROW, DEC HI BYTE OF PC
TYPSW1 DEC    7,X      ;DECR LO BYTE OF PC
       BRA    DISREG   ;GO DISPLAY REGISTERS
;*****
;GOTO - GO TO MEMORY ADDRESS
GOTO   JSR    NUMBER   ;GET DESTINATION
       BEQ    GOTO1    ;IF NONE, USE DEFAULT
       LDX    NBRHI
       STX    LASTGO   ;SAVE IT
       JMP    ,X       ;GO TO DESTINATION

GOTO1  LDX   LASTGO    ;GET LAST GOTO ADDRESS
       JMP   ,X        ;GO TO IT
;*****
;SEI - SET INTERRUPT MASK
LSEI   SEI
       BRA    COPY3

;*****
;CLI - CLEAR INTERRUPT MASK
LCLI   CLI
       BRA    COPY3

;*****
;COPY - COPY FROM ONE LOCATION TO ANOTHER
COPY   JSR    GTRANG   ;GET SOURCE RANGE INTO RANGLO & RANGHI
       BLE    COPY2    ;ERROR IF NO SOURCE
       JSR    NUMBER   ;GET DESTINATION
       BLE    COPY2    ;ERROR IF NO DESTINATION

       LDX    RANGLO   ;GET SOURCE ADDRESS POINTER
COPY1  LDAA   ,X       ;GET BYTE FROM SOURCE
       LDX    NBRHI    ;GET DESTINATION ADDRESS POINTER
       STAA   ,X       ;SAVE BYTE IN DESTINATION
       INX             ;INC DESTINATION POINTER
       STX    NBRHI    ;SAVE IT
       LDX    RANGLO   ;GET SOURCE ADDRESS POINTER
       CPX    RANGHI   ;COMPARE TO END OF INPUT RANGE
       BEQ    COPY3    ;DONE IF EQUAL
       INX             ;NOT EQUAL, INC SOURCE POINTER
       STX    RANGLO   ;SAVE IT
       BRA    COPY1    ;LOOP FOR NEXT BYTE

COPY2  JMP    BADSYN   ;BAD SYNTAX
COPY3  JMP    NOMORE   ;SHOULD BE NO MORE ON THE INPUT LINE

;*****
;BREAK - SET BREAKPOINT AT SPECIFIED ADDRESS & REMOVE OLD ONE
BREAK  JSR    NUMBER   ;GET BREAKPOINT LOCATION
       BMI    BREAK3   ;IF NOT NUMERIC, LOOK FOR "?"
       BEQ    BREAK2   ;IF NO MODIFIER, REMOVE OLD BREAKPOINT

;*****
;CHECK IF A "SWI" IS STORED AT THE BREAK ADDRESS
       LDX    BRKADR   ;GET CURRENT BREAK ADDRESS
       LDAA   ,X       ;AND THE CHAR THERE
       CMPA   #$3F     ;COMPARE TO "SWI"
       BNE    BREAK1   ;EQUAL?
;YES, RESTORE THE OLD INSTRUCTION
       LDAA   BRKINS   ;GET IT
       STAA   ,X       ;RESTORE IT

;PUT BREAK AT NEWLY SPECIFIED LOCATION
BREAK1 LDX    NBRHI    ;GET NEW BREAKPOINT (BREAK ADDRESS)
       STX    BRKADR   ;SAVE IT
       LDAA   ,X       ;GET INSTRUCTION STORED THERE
       STAA   BRKINS   ;SAVE IT
       LDAA   #$3F     ;GET CODE FOR SOFTWARE INTERRUPT
       STAA   ,X       ;PUT IT AT BREAKPOINT
       BRA    BREAK5   ;ALL DONE

;REMOVE BREAKPOINT
BREAK2 LDX    BRKADR   ;GET ADDRESS OF BREAK
       LDAA   ,X       ;GET INST. THERE
       CMPA   #$3F     ;SWI?
       BNE    BREAK5   ;IF NOT,, RETURN & PROMPT
       LDAA   BRKINS   ;WAS A SWI - GET PREVIOUS INST.
       STAA   ,X       ;& RESTORE IT
       BRA    BREAK5

;LOOK FOR A QUESTION MARK IN LIST 4
BREAK3 LDAA   #4
       JSR    COMAND   ;SCAN FOR IT
       BLE    BREAK6   ;BAD SYNTAX IF NOT "?"
       LDX    BRKADR   ;IT IS, GET BREAK ADDRESS
       LDAA   ,X       ;GET INSTRUCTION THERE
       CMPA   #$3F     ;IS IT A "SWI"?
       BEQ    BREAK4   ;IF YES, SAY SO
;NO BREAKPOINT SET
       LDX    #MSGNBR  ;GET THAT MESSAGE
       JSR    OUTSTR   ;SAY IT
       BRA    BREAK5
;BREAKPOINT SET
BREAK4 LDX    #MSGBAT  ;GET THAT MESSAGE
       JSR    OUTSTR   ;SAY IT
       LDX    #BRKADR  ;GET BREAK ADDRESS
       JSR    OUT2BY   ;TYPE IT

BREAK5 JMP    NOMORE
BREAK6 JMP    BADSYN

;*****
;IBASE - SET INPUT BASE
;LOOK FOR HEX, DEC, OR OCT IN LIST #3
IBASE  LDAA   #3
       JSR    COMAND
       BMI    IBASE2   ;UNRECOGNIZABLE BASE, TRY "?"
       BGT    IBASE1
       LDAA   #1       ;NO BASE GIVEN - DEFAULT TO HEX
IBASE1 STAA   IBCODE   ;SAVE BASE CODE
       BRA    BREAK5

;LOOK FOR "?" IN LIST #4
IBASE2 LDAA   IBCODE   ;GET IB CODE IN CASE ITS NEEDED
       PSHA            ;SAVE IT ON STACK TEMPORARILY
       BRA    DBASE4

;*****
;DBASE - SET DISPLAY BASE
;LOOK FOR HEX,DEC,OCT OR BIN IN LIST #3
DBASE  LDAA   #3
       JSR    COMAND
       BMI    DBASE3   ;UNRECOGNIZABLE BASE, TRY "?"
       BGT    DBASE1
       LDAA   #1       ;NO BASE GIVEN - DEFAULT TO HEX
DBASE1 STAA   DBCODE

;COMPUTE THE NUMERIC DISPLAY BASE (FOR THE "DISPLAY" COMMAND)
       LDX    #DBTBL-1 ;POINT TO HEAD OF DISPLAY BASE TABLE
DBASE2 INX             ;INC TABLE POINTER
       DECA            ;DECR DISPLAY BASE CODE
       BNE    DBASE2   ;LOOP IF NOT EQUAL
       LDAA   ,X       ;EQUAL - GET NUMERIC BASE FROM TABLE
       STAA   DBNBR    ;SAVE IT
       BRA    BREAK5   ;DONE

;DISPLAY BASE TABLE
DBTBL  FCB     16
       FCB     10
       FCB     8
       FCB     2

;LOOK FOR "?" IN LIST #4
DBASE3 LDAA   DBCODE   ;GET DB CODE IN CASE ITS NEEDED
       PSHA            ;SAVE IT ON STACK TEMPORARILY
DBASE4 LDAA   #4
       JSR    COMAND
       PULB            ;RETRIEVE INPUT BASE/DISPLAY BASE CODE
       BLE    BREAK6   ;ERROR IF THE "SOMETHING" WAS NOT AN "?"
;SET UP FOR TYPEOUT OF BASE CODE
       LDAA   #3       ;ITS IN LIST
       STAB   COMNUM   ;STORE BASE CODE
       JSR    TYPCMD   ;TYPE OUT BASE
       BRA    BREAK5
;*****
;CONTINUE - CONTINUE FROM A "SWI"
;RETURN TO LOCATION WHERE SWI WAS
CONTIN LDS    SP       ;IN CASE SP WAS MODIFIED VIA SET COMMAND
       RTI

;*****
;DISPLAY - DISPLAY MEMORY DATA
DISPLA JSR    GTRANG   ;GET MEMORY DISPLAY RANGE
       BLE    DISPL9   ;ADDRESS IS REQUIRED

;INITIALIZE ADDRESS POINTER TO START OF MEMORY
       LDX    RANGLO
       STX    MEMADR

;SEARCH LIST 6 FOR DISPLAY MODIFIERS "DATA" OR "USED"
       LDAA   #6
       JSR    COMAND
       BMI    DISPL9   ;ANY OTHER MODIFIER IS ILLEGAL
;ADJ DISPLAY MODIFIER CODE SO THAT: -1=ADDR & DATA, 0=DATA, I=USED
       DECA
       STAA   COMNUM   ;SAVE FOR LATER TESTS
;INIT "DATA VALUES PER LINE" COUNTER
       CLRB
       INCB
DISPL1 LDX    #MEMADR
       TST    COMNUM   ;WHICH DISPLAY OPTION?
       BMI    DISPL6   ;IF "ADDRESS & DATA", GO THERE

;OUTPUT DATA WITH ADDRESS ONLY AT LINE BEGINNING
       DECB            ;COUNT DATA VALUES PER LINE
       BNE    DISPL2   ;IF COUNT NOT UP, SKIP ADDRESS OUTPUT

       JSR    DOCRLF   ;GET TO LINE BEGINNING
       JSR    OUT2BY   ;OUTPUT ADDRESS
       JSR    OUTSP    ;AND A SPACE
       LDAB   DBNBR    ;RESET LINE COUNTER

DISPL2 LDX    MEMADR   ;POINT TO DATA AT THAT ADDRESS
       TST    COMNUM   ;WANT "DATA" OPTION?
       BGT    DISPL3   ;IF NOT, GO TO "USES" CODE

;"DATA" OPTION
       JSR    OUTSP    ;OUTPUT PRECEDING SPACE
       BRA    DISPL7
;"USED" OPTION
DISPL3 LDAA   ,X       ;GET THE DATA
       TSTA            ;EXAMINE IT FOR ZERO
       BNE    DISPL4
       LDAA   #'.'     ;ITS ZERO, GET A "."
       BRA    DISPL5
DISPL4 LDAA   #'+'     ;ITS NON-ZERO. GET A "+"
DISPL5 JSR    OUTCHR   ;OUTPUT THE "." OR "+"
       BRA    DISPL8

DISPL6 JSR    OUTSP    ;OUTPUT A PRECEDING SPACE
       JSR    OUT2BY   ;TYPE ADDRESS
       JSR    OUTEQ    ;TYPE "="
       LDX    ,X       ;GET CONTENT
DISPL7 JSR    OUT1BY   ;TYPE IT

DISPL8 CPX    RANGHI   ;ARE WE DONE?
       BEQ    DISP10   ;IF YES, BACK TO PROMPT
       INX             ;NO, INC MEMORY ADDRESS
       STX    MEMADR   ;SAVE IT
       BRA    DISPL1

DISPL9 JMP    BADSYN
DISP10 JMP    NOMORE

;*****
;SET - SET MEMORY LOCATIONS
SET    JSR    GTRANG   ;GET MEMORY LOCATION/RANGE
       BMI    SET5     ;IF NOT AN ADDRESS, LOOK FOR A REGISTER NAME
       BEQ    DISPL9   ;AN ADDRESS MODIFIER IS REQUIRED

;RANGE OF ADDRESSES SPECIFIED?
       LDX    RANGLO
       CPX    RANGHI
       BEQ    SET2     ;IF SINGLE ADDRESS, SET UP ADDRESSES INDIVIDUALLY
;SET A RANGE OF ADDRESSES TO A SINGLE VALUE
       JSR    NUMBER   ;GET THAT VALUE
       BLE    DISPL9   ;ITS REQUIRED
       LDAA   NBRLO    ;PUT IT IN ACCA
SET1   STAA   ,X       ;STORE IT IN DESTINATION
       CPX    RANGHI   ;END OF RANGE HIT?
       BEQ    DISP10   ;IF YES,ALL DONE
       INX             ;NO, ON TO NEXT ADDRESS IN RANGE
       BRA    SET1     ;LOOP TO SET IT
;SET ADDRESSES UP INDIVIDUALLY
SET2   STX    MEMADR   ;SAVE MEMORY LOC
SET3   JSR    NUMBER   ;GET DATA TO PUT THERE
       BEQ    SET4     ;END OF LINE?
       BLT    DISPL9   ;ABORT IF BAD SYNTAX
       LDAA   NBRLO    ;LOAD DATA BYTE
       LDX    MEMADR   ;LOAD ADDRESS
       STAA   ,X       ;STORE DATA

;INCREMENT ADDRESS IN CASE USER WANTS TO INDIVIDUALLY SET SEVERAL
;SUCCESSIVE LOCATIONS
       INX
       BRA    SET2

;END OF LINE - WAS IT TERMINATED WITH A LINE FEED?
SET4   LDX    SYNPTR   ;POINT TO END OF LINE
       LDAA   ,X       ;GET CHAR THERE
       CMPA   #LF      ;LINE FEED?
       BNE    SET12    ;IF NOT, BACK TO PROMPT
       LDX    #MEMADR  ;YES, GET NEXT ADDRESS TO BE SET
       JSR    OUT2BY   ;TYPE IT
       JSR    OUTSP    ;AND A SPACE
       JSR    GETLIN   ;GET A NEW LINE
       LDX    BUFBEG   ;GET BUFFER BEGINNING
       STX    SYNPTR   ;EQUATE IT TO SYNTAX SCAN POINTER
       BRA    SET3     ;GO PICK UP DATA


;LOOK FOR (REGISTER NAME, REGISTER VALUE) PAIRS
SET5   LDAA   #5
       JSR    COMAND   ;PICK UP A REGISTER NAME
       BMI    SET11    ;ERROR IF UNRECOGNIZABLE
       BEQ    SET12    ;DONE IF END OF LINE
       PSHA            ;SAVE REGISTER NAME(NUMBER)
       JSR    NUMBER   ;GET NEW REGISTER VALUE
       PULA            ;RESTORE REGISTER NAME(NUMBER)
       BLE    SET11    ;GOT GOOD REGISTER VALUE?
       LDX    SP       ;YES, POINT TO TOP OF STACK
       LDAB   NBRLO    ;GET REGISTER VALUE

;CONDITION CODES
       CMPA   #1
       BNE    SET6
       STAB   1,X
       BRA    SET5
;ACCB
SET6   CMPA   #2
       BNE    SET7
       STAB   2,X
       BRA    SET5

;ACCA
SET7   CMPA   #3
       BNE    SET8
       STAB   3,X
       BRA    SET5

;IX
SET8   CMPA   #4
       BNE    SET9
       LDAA   NBRHI
       STAA   4,X      ;UPDATE HI BYTE
       STAB   5,X      ;UPDATE LO BYTE
       BRA    SET5

;PC
SET9   CMPA   #5
       BNE    SET10
       LDAA   NBRHI
       STAA   6,X      ;UPDATE HI BYTE
       STAB   7,X      ;UPDATE LO BYTE
       BRA    SET5

;SP
SET10  CMPA   #6
       BNE    SET11
       LDX    NBRHI    ;DON'T NEED IX TO SET SP
       STX    SP
       BRA    SET5

SET11  JMP    BADSYN
SET12  JMP    NOMORE
;*****
;VERIFY - CHECKSUM VERIFY A BLOCK OF MEMORY
VERIFY JSR    GTRANG   ;GET A NUMBER RANGE
       BEQ    VERIF1   ;NO MODIFIER MEANS CHECK WHAT WE HAVE
       BMI    SET11    ;ANYTHING ELSE IS ILLEGAL
;GOOD RANGE GIVEN, TRANSFER IT TO CHECKSUM ADDRESSES
       LDX    RANGLO
       STX    VERFRM
       LDX    RANGHI
       STX    VERTO

       BSR    CKSUM    ;COMPUTE CHECKSUM
       STAA   CHKSUM   ;SAVE IT
       LDX    #CHKSUM  ;TYPE THE CHECKSUM
       JSR    OUT1BY
       BRA    SET12

;NO MODIFIER GIVEN - JUST VERIFY CHECKSUM
VERIF1 BSR    CKSUM    ;COMPUTE CHECKSUM
       CMPA   CHKSUM   ;SAME AS STORED CHECKSUM?
       BNE    VERIF2

;THEY VERIFY - SAY SO
       LDX    #MSGVER
       JSR    OUTSTR
       BRA    SET12

;THEY DON'T - SAY SO
VERIF2 LDX    #MSGNVE
       JSR    OUTSTR
       BRA    SET12

;COMPUTE THE CHECKSUM FROM ADDRESSES VERFRM TO VERTO
;RETURN THE CHECKSUM IN ACCA
CKSUM  CLRA            ;INIT CHECKSUM TO ZERO
       LDX    VERFRM   ;GET FIRST ADDRESS
       DEX             ;INIT TO ONE LESS
CKSUM1 INX             ;START OF CHECKSUM LOOP
       ADDA   ,X       ;UPDATE CHECKSUM IN ACCA WITH BYTE POINTED TO
       CPX    VERTO    ;HIT END OF RANGE?
       BNE    CKSUM1   ;IF NOT, LOOP BACK
       COMA            ;COMPLEMENT THE SUM
       RTS             ;RETURN WITH IT
;*****
;SEARCH - SEARCH MEMORY FOR A BYTE STRING

;GLOBAL VARIABLES USED
;LINPTR - INPUT LINE CHARACTER POINTER
;LISPTR - COMMAND LIST CHARACTER POINTER
;RANGLO - "SEARCH FROM" ADDRESS
;RANGHI - "SEARCH TO" ADDRESS

;LOCAL VARIABLES USE
;MEMADR - STARTING MEMORY ADDRESS WHERE A MATCH OCCURRED
;BYTPTR - ADDRESS POINTER USED TO FILL BYTSTR AND SUBSTR BUFFERS
;NBYTES - NUMBER OF BYTES IN BYTE STRING
;NBRMAT - NUMBER OF CHARS THAT MATCH SO FAR IN THE MATCHING PROCESS
;BYTSTR - STARTING ADDRESS OF 6 CHARACTER BYTE STRING BUFFER

;THE SEARCH STRING OCCUPIES TEMP4, TEMP5, & TEMP6 (6 BYTES MAX)

;GET SEARCH RANGE BEGINNING (RANGLO) & END (RANGHI)
SEARCH JSR    GTRANG
       BLE    SEARC9   ;ABORT IF NO PAIR

;INITIALIZED BYTE STRING POINTER
       LDX    #BYTSTR  ;GET START OF BYTE STRING TO SEARCH FOR
       STX    BYTPTR   ;SET POINTER TO IT

       CLR    NBYTES   ;ZERO # OF BYES IN BYTE STRING

;GET BYTE STRING
SEARC1 JSR    NUMBER   ;GET A BYTE
       BEQ    SEARC2   ;BEGIN SEARCH IF EOL
       BLT    SEARC9

;GOOD BYTE, ADD IT TO STRING
       INC    NBYTES   ;COUNT THIS BYTE
;DON'T ACCEPT OVER 6 BYTES
       LDAA   NBYTES
       CMPA   #6
       BGT    SEARC9

       LDAA   NBRLO    ;GET (LOW ORDER) BYTE
       LDX    BYTPTR   ;GET BYTE POINTER
       STAA   ,X       ;SAVE BYTE
       INX             ;MOVE BYTE POINTER TO NEXT LOCATION IN STRING
       STX    BYTPTR   ;SAVE IT
       BRA    SEARC1

;BEGIN SEARCH FOR BYTE STRING
;IS # OF BYTES TO LOOK FOR >0
SEARC2 TST    NBYTES
       BEQ    SEARC9   ;IF NOT, BAD SYNTAX

;MAKE USE OF INPUT LINE CHARACTER FETCH & COMMAND LIST CHAR FETCH ROUTINES

;INITIALIZE MEMORY POINTER TO START OF SEARCH RANGE
       LDX    RANGLO
       DEX
       STX    LINPTR

;INITIALIZE BYTE POINTER TO START OF BYTE STRING
SEARC3 LDX    #BYTSTR-1
       STX    LISPTR

       CLR    NBRMAT   ;SET "NUMBER OF BYTES THAT MATCHED" TO ZERO
;GET BYTE FROM BYTE STRING & RETURN IT IN ACCA
       JSR    GETLST
;GET BYTE FROM MEMORY RANGE & RETURN IT IN ACCB
SEARC4 JSR    GETCHR

       CBA             ;COMPARE MEMORY & BYTE STRING CHARACTERS
       BEQ    SEARC5   ;IF NO MATCH, TEST FOR RANGE END
       CPX    RANGHI   ;HAVE WE REACHED THE RANGE SEARCH UPPER LIMIT?
       BEQ    SEAR10   ;YES, GO PROMPT FOR NEXT COMMAND
       BRA    SEARC4

;MATCH ACHIEVED - SAVE ADDRESS OF MATCH
SEARC5 STX    MEMADR
SEARC6 INC    NBRMAT   ;BUMP NUMBER MATCHED
       LDAA   NBRMAT
       CMPA   NBYTES   ;HAVE ALL CHARACTERS MATCHED?
       BEQ    SEARC8   ;IF SO, MATCH ACHIEVED
;HAVEN'T MATCHED ALL YET, GO GET NEXT PAIR EVEN IF PAST "SEARCH TO" ADDRESS
       JSR    GETLST
       JSR    GETCHR
       CBA
       BEQ    SEARC6
;MISMATCH ON SOME BYTE PAST THE FIRST ONE
;RESET THE MEMORY POINTER TO GET NEXT UNTESTED MEMORY LOCATION
SEARC7 LDX    MEMADR
;THIS TEST HANDLES SPECIAL CASE OF A MATCH ON RANGE END
       CPX    RANGHI
       BEQ    SEAR10
       STX    LINPTR
;GO RESET THE BYTE STRING POINTER
       BRA    SEARC3

;MATCH ON BYTE STRING ACHIEVED, TYPE OUT MEMORY ADDRESS
SEARC8 LDX    #MEMADR
       JSR    OUT2BY
       JSR    OUTSP    ;AND A SPACE
;ASSUME A MISMATCH (I.E., RESET MEMORY & BYTE STRING POINTERS & CONTINUE
       BRA    SEARC7

SEARC9 JMP    BADSYN
SEAR10 JMP    NOMORE

;*****
;TEST - TEST RAM FOR BAD BYTES
;GET AN ADDRESS RANGE
TEST   JSR    GTRANG
       BLE    SEARC9   ;ABORT IF NO PAIR
;RANGLO HOLS STARTING ADDRESS OF RANGE
;RANGHI HOLDS ENDING ADDRESS OF RANGE
       LDX    RANGLO
       STX    MEMADR
;GET BYTE STORED AT TEST LOCATION & SAVE IT
TEST1  LDAA   ,X
       PSHA

       CLR    ,X       ;ZERO THE LOCATION
       TST    ,X       ;TEST IT
       BEQ    TEST2    ;OK IF = ZERO

;CAN'T CLEAR LOCATION
       LDX    #MSGCCL
       BRA    TEST4

TEST2  DEC    ,X       ;SET LOCATION TO FF
       LDAA   #$FF
       CMPA   ,X       ;DID IT GET SET TO FF?
       BEQ    TEST3

;CAN'T SET LOCATION TO ONE'S
       LDX    #MSGCSO
       BRA    TEST4

TEST3  LDX    MEMADR   ;GET LOCATION BEING TESTED
       PULA
       STAA   ,X       ;RESTORE PREVIOUS CONTENT

;HIT END OF TEST RANGE?
       CPX    RANGHI
       BEQ    SEAR10   ;YES, ALL DONE

;NO, MOVE TO TEST NEXT LOCATION
       INX
       STX    MEMADR
       BRA    TEST1

;*LOCATION IS BAD
TEST4  STX    TEMP3    ;SAVE ERROR MESSAGE TEMPORARILY

       LDX    #MEMADR
       JSR    OUT2BY   ;TYPE OUT BAD ADDRESS.
       JSR    OUTEQ    ;AN EQUAL SIGN

       LDX    MEMADR
       JSR    OUT1BY   ;ITS CONTENT.
       JSR    OUTSP    ;A SPACE.
       LDX    TEMP3
       JSR    OUTSTR   ;AND THE TYPE OF ERROR

       JSR    DOCRLF   ;SEND CR-LF
       BRA    TEST3
;*****
;INT - SET UP INTERRUPT POINTER
INT    JSR    NUMINX   ;GET POINTER IN IX
       STX    INTVEC   ;SAVE IT
       BRA    COMPA1

;*****
;NMI - SET UP NON-MASKABLE INTERRUPT POINTER
NMI    JSR    NUMINX   ;GET POINTER IN IX
       STX    NMIVEC   ;SAVE IT
       BRA    COMPA1

;*****
;SWI - SET UP SWI POINTER
LSWI   JSR    NUMINX   ;GET POINTER TO IX
       STX    SWIVEC   ;SAVE IT
       BRA    COMPA1

;*****
;COMPARE - OUTPUT SUM & DIFFERENCE OF TWO INPUT NUMBERS
COMPAR JSR    NUMINX   ;GET FIRST NUMBER
       STX    RANGLO   ;PUT IT IN RANGLO

       JSR    NUMINX   ;GET SECOND NUMBER
       STX    NBRHI    ;SAVE IT IN NBRHI

;COMPUTE AND OUTPUT THE SUM
       JSR    SUMNUM   ;COMPUTE SUM
       LDX    #MSGSIS  ;GETS ITS TITLE
       BSR    OUTSD    ;OUTPUT TITLE & SUM

       JSR    DIFNUM   ;COMPUTE DIFFERENCE
       LDX    #MSGDIS  ;GET ITS TITLE
       BSR    OUTSD    ;OUTPUT TITLE & DIFFERENCE

COMPA1 JMP    NOMORE

;COMPUTE AND OUTPUT THE RESULT
OUTSD  JSR    OUTSTR   ;OUTPUT IT
       LDX    #RANGHI  ;GET RESULT
       JSR    OUT2BY   ;DISPLAY RESULT
       RTS
;*****
;DUMP - DUMP A PORTION OF MEMORY, IN MIKBUG FORMAT, TO A SPECIFIED ACIA ADDRESS

;GET ADDRESS RANGE: START IN RANGLO (2 BYTES), END IN RANGHI (2 BYTES)
;IF NO ADDRESS RANGE IS GIVEN, USE WHATEVER IS IN RANGLO & RANGHI
DUMP   JSR    GTRANG

       CLR    TEMP5    ;INITIALIZE TO DUMP TO TERMINAL

;LOOK FOR A "TO" MODIFIER
DUMP1  LDAA   #2
       JSR    COMAND
       BEQ    DUMP4
DUMP2  BLE    DUMP10   ;ERROR IF BAD SYNTAX
       CMPA   #1       ;TO?
       BEQ    DUMP3
       BRA    DUMP1    ;GO LOOK FOR ANOTHER MODIFIER

DUMP3  JSR    NUMINX   ;GET "TO" ADDRESS
       STX    OUTADR   ;SAVE IT
       INC    TEMP5    ;REMEMBER THIS
       BRA    DUMP1    ;GO LOOK FOR ANOTHER MODIFIER

DUMP4  TST    TEMP5
       BEQ    DUMP5
       INC    OUTFLG   ;SET FLAG FOR PROPER OUTPUT DEVICE
DUMP5  BSR    NULLS    ;SEND SOME NULLS

;MIKBUG MODE
;OUTPUT AN "S0" TYPE RECORD
       LDX    #MSGS0
       JSR    OUTSTR

;COMPUTER # OF BYTES TO OUTPUT (RANGE END - RANGE START + 1)
;SUBTRACT LO BYTES
DUMP6  LDAA   RANGHI+1
       SUBA   RANGLO+1
;SUBTRACT HI BYTES
       LDAB   RANGHI
       SBCB   RANGLO
;NON-ZERO HI BYTE IMPLIES LOTS TO OUTPUT
       BNE    DUMP7
;HI BYTE DIFF IS ZERO
       CMPA   #16      ;LO BYTE OF DIFF 0 TO 15
       BCS    DUMP8    ;IF YES, TO DUMP8
DUMP7  LDAA   #15      ;NO, LO BYTE IS 16-255; SET BYTES TO 15
;TO GET FRAME COUNT, ADD 1 (DIFF OF 0 IMPLIES 1 OUTPUT) + # OF DATA BYTES,
; + 2 ADDR BYTES + 1 CHECKSUM BYTE
DUMP8  ADDA   #4
       STAA   TEMP3    ;TEMP3 IS THE FRAME COUNT
       SUBA   #3
       STAA   TEMP4    ;TEMP4 IS THE RECORD BYTE COUNT
;OUTPUT A MIKBUG "S1" HEADER DATA RECORD
       LDX    #MSGS1
       JSR    OUTSTR
       CLRB            ;ZERO CHECKSUM
;PUNCH FRAME COUNT
       LDX    #TEMP3
       BSR    OUTP2

;PUNCH ADDRESS
       LDX    #RANGLO
       BSR    OUTP2
       BSR    OUTP2

;OUTPUT DATA
       LDX    RANGLO
DUMP9  BSR    OUTP2    ;OUTPUT DATA BYTE
       DEC    TEMP4    ;DEC BYTE COUNT
       BNE    DUMP9

;COMPLEMENT AND PUNCH THE CHECKSUM
       STX    RANGLO   ;SAVE MEMORY POINTER
       COMB            ;COMPLEMENT CHECKSUM
       PSHB            ;PUT IT ON STACK
       TSX             ;LET IX POINT TO IT
       BSR    OUTP2    ;OUTPUT CHECKSUM
       PULB            ;PULL IT OFF STACK
       LDX    RANGLO   ;RESTORE MEMORY POINTER
       DEX
       CPX    RANGHI   ;HIT END OF RANGE?
       BNE    DUMP6

;YES, OUTPUT AN "S9" RECORD
       LDX    #MSGS9
       JSR    OUTSTR
       BSR    NULLS    ;GENERATE BLANK TAPE
       CLR    OUTFLG   ;SET TO TERMINAL OUTPUT
       JMP    NOMORE   ;ALL DONE
DUMP10 JMP    BADSYN   ;BAD SYNTAX

;SEND A STRING OF NULLS
NULLS  LDAB   #30
       CLRA
NULLS1 JSR    OUTCHR
       DECB
       BNE    NULLS1
       RTS

;OUTPUT A BYTE POINTED TO BY IX AS 2 HEX CHARACTERS
OUTP2  ADDB   ,X       ;UPDATE CHECKSUM
       JSR    OUT1BY
       INX
       RTS
;*****
;LOAD - LOAD A MIKBUG TAPE
;LOOK FOR A "FROM" MODIFIER
LOAD   LDAA   #7       ;IN LIST 7
       JSR    COMAND
       BMI    DUMP10   ;ERROR, UNRECOGNIZABLE MODIFIER
       BEQ    LOAD1

       JSR    NUMINX   ;GET "FROM" ADDRESS
       STX    INPADR   ;SAVE IT
       INC    INPFLG   ;SET FLAG FOR NON-TERMINAL ACIA

;KEEP READING CHARACTERS UNTIL AN "S" IS READ
LOAD1  JSR    INPCHR   ;GET A CHAR
       CMPA   #'S'     ;IS IT AN S?
       BNE    LOAD1

;GOT AN "S", EXAMINE NEXT CHARACTER
       JSR   INPCHR
       CMPA   #'9'     ;DONE IF ITS A "9"
       BEQ    LOAD4

       CMPA   #'1'     ;IS IT A "1"?
       BNE    LOAD1    ;IF NOT, LOOK FOR NEXT "S"
;VALID S1 RECORD
       CLR    CKSM     ;CLEAR CHECKSUM
;READ RECORD BYTE COUNT
       JSR    RDBYTE
       SUBA   #2
       STAA   BYTECT   ;SAVE COUNT MINUS 2 ADDRESS BYTES

       BSR    BLDADR   ;BUILD ADDRESS

LOAD2  BSR    RDBYTE   ;READ A DATA BYTE INTO ACCA
       DEC    BYTECT   ;COUNT IT
       BEQ    LOAD3    ;IF DONE WITH RECORD, CHECK CHECKSUM
       STAA   ,X       ;NOT DONE, STORE BYTE IN MEMORY
       INX             ;ON TO NEXT MEMORY ADDRESS
       BRA    LOAD2

;RECORD READ IN COMPLETE
LOAD3  INC    CKSM     ;TEST CHECKSUM BY ADDING 1
       BEQ    LOAD1    ;IF OK, RESULT SHOULD BE ZERO

;RECORD CHECKSUM ERROR
       LDX    #MSGNVE  ;SAY SO
       JSR    OUTSTR
       LDX    #TEMP1   ;GET RECORD ADDRESS OF IT
       JSR    OUT2BY   ;TYPE IT TOO
LOAD4  CLR    INPFLG   ;RESET FLAG TO NORMAL TERMINAL INPUT
       JMP    NOMORE

;BUILD ADDRESS
BLDADR BSR    RDBYTE
       STAA   TEMP1
       BSR    RDBYTE
       STAA   TEMP1+1
       LDX    TEMP1
       RTS
RDBYTE BSR    INHEX    ;GET LEFT HEX DIGIT
;MOVE TO HI 4 BITS
       ASLA
       ASLA
       ASLA
       ASLA
       TAB             ;SAVE IT IN ACCA
       BSR    INHEX    ;GET RIGHT HEX DIGIT
       ABA             ;COMBINE THEM IN ACCA
;UPDATE THE CHECKSUM
       TAB
       ADDB   CKSM
       STAB   CKSM
       RTS

;INPUT A HEX CHAR & CONVERT TO INTERNAL FORM
INHEX  JSR    INPCHR   ;INPUT A CHAR
       SUBA   #$30
       BMI    INHEX2   ;NOT HEX IF BELOW ASCII "1"
       CMPA   #$09
       BLE    INHEX1   ;OK IF ASCII "9" OR LESS
       CMPA   #$11     ;BELOW ASCII "A"?
       BMI    INHEX2   ;ERROR IF IT IS
       CMPA   #$16     ;OVER ASCII "F"?
       BGT    INHEX2   ;ERROR IF IT IS
       SUBA   #7       ;CONVERT ASCII A-F TO HEX A-F
INHEX1 RTS
;ERROR - CHAR NOT HEX, SAY SO
INHEX2 LDX    #MSGCNH
       JSR    OUTSTR
       RTS

;*****
;DELAY - DELAY SPECIFIED # OF MILLISECONDS
DELAY  JSR    NUMINX   ;GET DELAY TIME
       BSR    TIMDEL
       JMP    NOMORE

;**
;TIME DELAY SUBROUTINE
;IX IS INPUT AS THE # OF MILLISECONDS TO DELAY
;ACCA IS ALTERED
;ACCB IS PRESERVED
;ADJ TIMCON SO (6*TIMCON*CYCLE TIME=1 MS)
TIMDEL LDAA   TIMCON
;ENTER A 6 CYCLE LOOP
TIMDE1 DECA
       BNE    TIMDE1

       DEX             ;DECREMENT MILLISECOND COUNTER
       BNE    TIMDEL
       RTS

;====================================================

;  C O M M A N D     L I S T     S C A N N I N G    R O U T I N E

;THIS ROUTINE SEEKS A MATCH OF THE CHARACTERS POINTED AT
;BY THE INPUT LINE SCANNING POINTER TO ONE OF THE COMMANDS
;IN A LIST SPECIFIED BY ACCA.
;
; AS FOLLOWS:
;
;      ACCA=-1: THE MATCH WAS UNSUCCESSFUL.  THE SYNTAX
;               POINTER (SYNPTR) WAS NOT UPDATED (ADVANCED).
;
;      ACCA= 0: THE MATCH WAS UNSUCCESSFUL SINCE THERE WERE
;               NO MORE CHARACTERS, I.E., THE END OF THE
;               LINE WAS REACHED.
;
;      ACCA=+N: SUCCESSFUL MATCH.  THE SYNTAX POINTER WAS UPDATED
;               TO THE FIRST CHARACTER FOLLOWING THE COMMAND
;               DELIMITER.  ACCA HOLDS THE NUMBER OF THE
;               COMMAND MATCHED.
;GLOBAL VARIABLES FOR EXTERNAL COMMUNICATION
;SYNPTR - GOOD SYNTAX INPUT CHAR LINE POINTER
;LINPTR - INPUT LINE CHARACTER POINTER
;DELIM - CLASS OF PERMISSIBLE COMMAND DELIMITERS

;TEMPORARY 2 BYTE INTERNAL VARIABLES
;LISPTR - COMMAND LIST CHARACTER POINTER

;TEMPORARY 1 BYTE INTERNAL VARIABLES
;NUMMAT - NUMBER OF CHARACTERS THAT SUCCESSFULLY MATCH
;LISNUM - # OF LIST WITHIN WHICH A MATCH WILL BE SOUGHT
;COMNUM - COMMAND NUMBER MATCHED

;CONSTANTS USED
;CR - CARRIAGE RETURN
;LF - LINE FEED

;ACCB & IX ARE NOT PRESERVED.

COMAND STAA   LISNUM   ;SAVE LIST # TO MATCH WITHIN
;TEST IF WE ARE AT THE END OF THE LINE
       JSR    SKPDLM
       BCC    INILST
       CLRA
       RTS


;INITIALIZE THE COMMAND LIST POINTER TO ONE LESS THAN
;                       THE BEGINNING OF THE COMMAND LISTS
INILST LDX    COMADR   ;ENTRY POINT

;MOVE TO THE BEGINNING OF THE DESIRED COMMAND LIST
       LDAA   LISNUM   ;SEARCH FOR "STRING" # LISNUM
       LDAB   #LF      ;USE LF AS A "STRING" TERMINATOR
       BSR    FNDSTR
       STX    LISPTR

;THE LIST POINTER, LISPTR, NOW POINTS TO ONE LESS THAN THE FIRST CHARACTER
;OF THE FIRST COMMAND IN THE DESIRED LIST INITIALIZE THE COMMAND # TO 1
       LDAA   #1
       STAA   COMNUM

;RESET INPUT LINE POINTER TO: 1) BEGINNING OF LINE, OR TO
;  2) POINT WHERE LAST SUCCESSFUL SCAN TERMINATED
CMD3   LDX    SYNPTR
       STX    LINPTR

       CLR    NUMMAT   ;CLEAR NUMBER OF CHARACTERS MATCHED
CMD4   JSR    GETCHR   ;GET INPUT LINE CHAR IN ACCB
       JSR    TSTDLM   ;TEST FOR A DELIMITER
       BNE    MATCH    ;SUCCESS (FOUND DELIMITER) IF NOT = ZERO

       JSR    GETLST   ;GET COMMAND LIST CHAR IN ACCA
       CMPA   #LF      ;HAS END OF COMMAND LIST BEEN REACHED?
       BEQ    NMATCH   ;IF SO, POTENTIAL MATCH FAILURE
       CMPA   #CR      ;HAS END OF COMMAND BEEN REACHED?
       BEQ    NMATCH   ;IF SO, POTENTIAL MATCH FAILURE

       CBA             ;COMPARE THE TWO CHARACTERS
       BNE    NEXCOM   ;MATCH NOT POSSIBLE ON THIS COMMAND

;THEY MATCH, COMPARE THE SUCCEEDING CHARACTERS
       INC    NUMMAT   ;INC NUMBER OF CHARACTERS MATCHED
       BRA    CMD4

;;;
;SUCCESSFUL MATCH - RETURN COMMAND NUMBER MATCHED IN ACCA
MATCH  LDAA   COMNUM
       LDX     LINPTR
       STX     SYNPTR  ;UPDATE GOOD SYNTAX POINTER
       RTS

;***
;NO MATCH
;DID AT LEAST ONE MATCH?
NMATCH TST    NUMMAT
       BEQ    NEXCOM   ;TO NEXT COMMAND IF NONE MATCHED

;AT LEAST ONE MATCHED - TEST FOR DELIMITER (NON-MATCHING CHAR)
       JSR    TSTDLM
       BNE    MATCH    ;IF A DELIMITER, MATCH HAS BEEN ACHIEVED
;
;ILLEGAL DELIMITER

;MOVE TO NEXT COMMAND WITHIN LIST
NEXCOM JSR    GETLST   ;GET NEXT COMMAND LIST CHARACTER
       CMPA   #LF      ;END OF THIS LIST?
       BEQ    MFAIL    ;IF SO, NOTHING ON LIST MATCHED
       CMPA   #CR      ;IS IT A CR?
       BNE    NEXCOM   ;IF NOT, MOVE TO NEXT CHARACTER
       INC    COMNUM   ;YES, INC COMMAND NUMBER
       BRA    CMD3

;***
;MATCH FAILURE - NO MATCH POSSIBLE WITHIN THIS LIST
MFAIL  CLRA
       DECA
       RTS

;======================================================
;THIS ROUTINE TYPES OUT COMMAND NUMBER "COMNUM"
;THE LIST IS SPECIFIED IN ACCA
;ACCB & IX ARE PRESERVED
TYPCMD STX    XTEMP
       PSHB
       LDX    #COMLST-1 ;MOVE TO HEAD OF COMMAND LISTS
       LDAB   #LF      ;AND LIST TERMINATOR
       BSR    FNDSTR   ;GO TO HEAD OF DESIRED LIST
       LDAA   COMNUM   ;GET COMMAND NUMBER
       LDAB   #CR      ;GET COMMAND TERMINATOR
       BSR    FNDSTR   ;GO TO HEAD OF DESIRED COMMAND

TYPCM1 INX             ;MOVE TO NEXT CHARACTER
       LDAA   ,X       ;GET A COMMAND CHARACTER
       CMPA   #CR      ;IS IT A COMMAND TERMINATOR?
       BEQ    TYPCM2   ;IF SO, RETURN
       JSR    OUTCHR   ;NO, TYPE IT
       BRA    TYPCM1

TYPCM2 LDX    XTEMP
       PULB
       RTS

;======================================================
;MOVE TO BEGINNING OF DESIRED STRING NUMBER (IN ACCA)
;EACH STRING IS TERMINATED BY AN END OF STRING CHARACTER (IN ACCB)
;THE INDEX REGISTER IS ASSUMED INITIALIZED POINTING TO
;ONE LESS THAT THE FIRST CHARACTER OF THE FIRST STRING
;ACCA, ACCB & IX ARE NOT PRESERVED
;LOCAL VARIABLES
;STRNUM - STRING # TO FIND
;EOSCHR - "END OF STRING" CHARACTER

FNDSTR STAA   STRNUM   ;SAVE STRING NUMBER
       STAB   EOSCHR   ;SAVE TERMINATOR
       CLRB
FNDST1 INCB            ;STRING 1 IS THE FIRST STRING
       CMPB   STRNUM   ;IS THIS THE RIGHT STRING?
       BEQ    FNDST3   ;IF SO, DONE

;NO, SWALLOW UP CHARACTERS UNTIL AND END OF STRING CHAR IS HIT
FNDST2 INX             ;BUMP POINTER TO NEXT ONE
       LDAA   ,X       ;GET CHAR POINTED AT
       CMPA   EOSCHR   ;END OF STRING HIT?
       BEQ    FNDST1   ;IF IT IS, BUMP THE STRING COUNTER
       BRA    FNDST2   ;NO, MOVE ON TO NEXT CHAR
FNDST3 RTS             ;IX SET PROPERLY, RETURN

;======================================================
;SKIP LEADING DELIMITERS
;THIS ROUTINE SHOULD BE CALLED PRIOR TO SCANNING FOR ANY INFORMATION
;ON THE INPUT LINE
;THE CURRENT CHARACTER IS IGNORED IF THE SCANNING POINTER IS AT THE
;BEGINNING OF A LINE.  IF NOT, THE SCANNING POINTER SKIPS OVER SPACES
;AND COMMAS UNTIL AN END OF LINE OR NON-DELIMITER IS FOUND.
;THE CARRY BIT IS SET IF AN END OF LINE IS ENCOUNTERED.

;ACCA, ACCB & IX ARE NOT PRESERVED

SKPDLM CLC
       TST    BOLFLG   ;AT BEGINNING OF LINE?
       BGT    SKPDL2

;LOOK AT CURRENT INPUT CHARACTER
SKPDL1 LDX    SYNPTR   ;GET POINTER TO IT
       LDAA   ,X       ;GET CHAR
       BSR    TSTEOL   ;TEST FOR END OF LINE
       BNE    SKPDL2
       SEC             ;YES, END HIT, SET CARRY
       RTS
;"PEEK" AT NEXT CHAR IN LINE
SKPDL2 LDAB   1,X     ;GET IT
       BSR    TSTDLM  ;SEE IF ITS A DELIMITER
       BNE    SKPDL3
       RTS            ;ITS NOT, RETURN

;NEXT CHAR IS A DELIMITER
SKPDL3 JSR    GETCHR   ;MOVE TO NEXT CHAR IN INPUT LINE
       STX    SYNPTR   ;UPDATE SYNTAX POINTER
       BRA    SKPDL1   ;GO TEST FOR END OF LINE

;======================================================
;TEST FOR END-OF-LINE CHARACTER
;Z BIT OF CC REG SET IF CHAR IN ACCA IS A TERMINATOR
;ACCA, ACCB, & IX ARE PRESERVED
TSTEOL CMPA   #CR      ;CARRIAGE RETURN?
       BEQ    TSTEO1
       CMPA   #LF      ;LINE FEED? (CONTINUED LINES)
       BEQ     TSTEO1
       CMPA    #';'    ;FOR SEVERAL COMMANDS ON ONE LINE
TSTEO1 RTS

;======================================================
;CHECK THE CHARACTER IN ACCB
;AGAINST THE DELIMITER(S) SPECIFIED BY VARIABLE DELIM
;ACCB & IX ARE PRESERVED
;ACCA IS SET TO 0 IF ACCB IS NOT A DELIMITER, TO 1 IF IT IS
;  IF DELIM=1, SPACE IS DELIMITER
;  IF DELIM-2, COMMA IS DELIMITER
;  IF DELIM=3, SPACE OR COMMAND IS DELIMITER
;  IF DELIM=4, ANY NON-ALPHANUMERIC IS A DELIMITER
;TEST FOR END-OF-LINE (LOGICAL OR PHYSICAL)
TSTDLM PSHB
       TBA
       BSR    TSTEOL
       PULB
       BEQ    DLMYES

       LDAA   DELIM
       CMPA   #1
       BNE    ISDLM2
       CMPB   #32      ;WANT A SPACE - IS IT?
       BNE    DLMNO
       BRA    DLMYES

ISDLM2 CMPA   #2
       BNE    ISDLM3
TSTCMA CMPB   #','     ;WANT A COMMA - IS IT?
       BNE    DLMNO
       BRA    DLMYES
ISDLM3 CMPA   #3
       BNE    ISDLM4
       CMPB   #32      ;WANT EITHER, IS IT A SPACE?
       BEQ    DLMYES
       BRA    TSTCMA   ;OR A COMMA?

ISDLM4 CMPA   #4
       BNE    ERROR    ;ERROR IF DELIM NOT 1-4
;TEST IF CHAR IS 0 TO 9 INCLUSIVE
       CMPB   #'0'
       BLT    DLMYES
       CMPB   #'9'
       BLE    DLMNO

;TEST IF CHAR IS A TO 9 INCLUSIVE
       CMPB   #'A'
       BLT    DLMYES
       CMPB   #'Z'
       BLE    DLMNO
;OVER Z - ITS A DELIMITER

;CHAR IN ACCB IS A DELIMITER
DLMYES LDAA   #1
       RTS

;CHAR IN ACCB IS NOT A DELIMITER
DLMNO  CLRA
       RTS

;ERROR IN SPECIFYING DELIMITER CLASS
ERROR  SWI             ;HAVE MONITOR TYPE OUT PERTINENT STATISTICS

;=====================================================
;ADD THE 2 BYE NUMBER STORED IN (RANGLO,RANGLO+1) TO THE NUMBER
;STORED IN (NBRHI,NBRLO) AND PUT THE RESULT IN (RANGHI,RANGHI+1)
;ACCB & IX ARE PRESERVED
;ACCA IS ALTERED

;ADD LO ORDER BYTES
SUMNUM LDAA   RANGLO+1
       ADDA   NBRLO
       STAA   RANGHI+1

;ADD HI ORDER BYTES
       LDAA   RANGLO
       ADCA   NBRHI
       STAA   RANGHI

       RTS

;========================================================
;SUBTRACT THE TWO BYTE NUMBER STORED IN (NBRHI,NBRLO) FROM THE
;TWO BYTE NUMBER STORED IN (RANGLO,RANGLO+1) AND PUT THE
;RESULT IN (RANGHI,RANGHI+1)
;ACCB & IX ARE PRESERVED
;ACCA IS ALTERED

;SUBTRACT LO ORDER BYTES
DIFNUM LDAA   RANGLO+1
       SUBA   NBRLO
       STAA   RANGHI+1

;SUBTRACT HI ORDER BYES
       LDAA   RANGLO
       SBCA   NBRHI
       STAA   RANGHI

       RTS

;======================================================
;THIS ROUTINE SCANS THE INPUT LINE FOR A PAIR OF NUMBERS
;REPRESENTING AN ADDRESS RANGE.  A COLON SEPARATING THE
;PAIR IMPLIES "THRU", WHILE AN "!" IMPLIED "THRU THE FOLLOWING"
;E.G., 100:105 IS EQUIVALENT TO 100!5
;A SINGLE NUMBER IMPLIES A RANGE OF 1
;
;ON RETURN (RANGLO,RANGLO+1) HOLDS THE RANGE START, AND
;          (RANGHI,RANGHI+1) HOLDS THE RANGE END.
;ACCA, ACCB, & IX ARE NOT PRESERVED

GTRANG BSR    NUMBER   ;PICK UP FIRST NUMBER
       BGT    GTRAN1
       BLT    GTRAN2
       RTS             ;NOTHING MORE ON INPUT LINE

;GOOD SINGLE NUMBER - TRANSFER IT TO RANGLO
GTRAN1 LDX    NBRHI
       STX    RANGLO
       BRA    GTRAN3   ;AND TO RANGHI

;BAD NUMBER, BUT IS IT BAD DUE TO A ":" OR "!" DELIMITER?
GTRAN2 LDX    LINPTR
       LDAA   ,X
       CMPA   #':'     ;WAS IT A COLON
       BNE    GTRAN4   ;IF NOT, GO TEST FOR "!"

       BSR    GTRAN8   ;WAS ":", PROCESS NUMBER & GET NEXT ONE
       BLE    GTRAN5   ;ILLEGAL IF END OF LINE OR NON-NUMERIC

;TRANSFER SECOND NUMBER TO RANGHI
GTRAN3 LDX    NBRHI
       STX    RANGHI
       BRA    GTRAN7

GTRAN4 CMPA   #'!'     ;WAS DELIMITER A "!"?
       BEQ    GTRAN6   ;IF YES, GET 2ND NUMBER

;ILLEGAL DELIMITER, RETURN
       CLRA
       DECA
GTRAN5 RTS

GTRAN6 BSR    GTRAN8   ;WAS "!", PROCESS FIRST NUMBER & GET NEXT ONE
       BLE    GTRAN5
       BSR    SUMNUM   ;COMPUTE RANGE END, PUT INTO RANGHI

;SUCCESSFUL EXIT
GTRAN7 LDAA   #1
       RTS

;UPDATE SYNTAX POINTER, MOVE FIRST NUMBER TO RANGLO, & GET 2ND NUMBER
GTRAN8 STX    SYNPTR   ;UPDATE SYNTAX POINTER
       LDX    NBRHI    ;GET FIRST NUMBER OF THE PAIR
       STX    RANGLO   ;SAVE IT IN "LOW RANGE" VALUE
       BSR    NUMBER   ;PICK UP THE SECOND NUMBER OF THE PAIR
       RTS

;======================================================
;GET A 2 BYTE NUMBER & RETURN IT IN THE INDEX REGISTER
NUMINX BSR    NUMBER
       BGT    NUMIN1
       JMP    BADSYN
NUMIN1 LDX    NBRHI
       RTS

;======================================================
;SCAN FOR A NUMBER
;RETURN THE MOST SIGNIFICANT BYTE IN NBRHI
;  AND THE LEAST SIGNIFICANT BYTE IN NBRLO
;THE RESULT OF THE SCAN FOR A NUMBER IF RETURNED IN
;ACCA AS FOLLOWS:
;
;      ACCA=-1: THE MATCH WAS UNSUCCESSFUL.  THE SYNTAX
;               POINTER (SYNPTR) WAS NOT UPDATED.
;
;      ACCA= 0: THE MATCH WAS UNSUCCESSFUL SINCE THERE WERE NO
;               MORE CHARACTERS. (I.E., THE END OF THE
;               LINE WAS ENCOUNTERED.)
;
;      ACCA=+1: THE SCAN WAS SUCCESSFUL.  THE SYNTAX POINTER
;               WAS UPDATED TO THE FIRST CHARACTER FOLLOWING
;               THE COMMAND.

;IX IS PRESERVED
;GLOBAL VARIABLES FOR EXTERNAL COMMUNICATION
;NBRHI - NUMBER HI BYTE
;NBRLO - NUMBER LO BYTE
;IBCODE - INPUT BASE CODE
;DBCODE - DISPLAY BASE CODE

;LOCAL VARIABLES
;NBR2X - USED IN DECIMAL CONVERSION
;XTEMP2 - SAVES IX

;INITIALIZE BOTH BYTES TO ZERO
NUMBER STX    XTEMP2   ;SAVE IX
       CLR    NBRHI
       CLR    NBRLO

;INITIALIZE THE LINE SCANNING POINTER
       LDX    SYNPTR
       STX    LINPTR

;ARE WE AT END OF LINE?
       JSR    SKPDLM
       BCC    NUMLUP
       LDX    XTEMP2
       CLRA            ;YES, ZERO ACCA
       RTS

NUMLUP JSR    GETCHR   ;GET A CHARACTER FROM THE INPUT LINE INTO ACCB

;TEST FOR A DELIMITER
       JSR    TSTDLM
       BNE    GUDNUM   ;GOOD DELIMITER IF ACCA NON-ZERO

;NOT A DELIMITER, TEST IF CHARACTER IS < ASCII 0
       SUBB   #'0'     ;SUBTRACT ASCII 0
       BMI    CONERR   ;ERROR IF LESS

;DETERMINE INPUT BASE & GO TO RIGHT ROUTINE
       LDAA   IBCODE
       CMPA   #1
       BEQ    HEXNUM

       CMPA   #2
       BEQ    DECNUM

       CMPA   #3
       BEQ    OCTNUM

;DEFAULT AN ILLEGAL INPUT BASE TO HEX
;*****
;INPUT A HEX NUMBER
;TEST FOR A LEGAL DIGIT
HEXNUM CMPB   #$09
       BLE    HEXN1    ;OR IF 9 OR LESS
       CMPB   #$11
       BMI    CONERR    ;NOT HEX IF < A
       CMPB   #$16
       BGT    CONERR    ;NOT HEX IF > F
       SUBB   #7        ;MOVE A-F ABOVE 0-9

;SHIFT LO & HI BYTES LEFT 4 BITS
HEXN1  BSR    SHIFT2
       BSR    SHIFT2

       ORAB   NBRLO
       STAB   NBRLO

       BRA    NUMLUP

;*****
;INPUT A DECIMAL NUMBER
;TEST FOR A LEGAL DIGIT
DECNUM CMPB   #$09
       BGT    CONERR   ;NOT DECIMAL IF > 9

;MULTIPLE SAVED VALUE BY 10 & ADD IN NEW DIGIT
;NOTE THAT 10X=2X+8x
;MULTIPLY CURRENT NUMBER BY 2 TO GET 2X VALUE
       BSR    SHIFT
;SAVE THIS *2 NUMBER TEMPORARILY
       LDX    NBRHI
       STX    NBR2X
;MULTIPLY THIS # BY 4 TO GET 8X VALUE
       BSR    SHIFT2
;(NBRHI,NBRLO) NOW HOLDS *8
;GENERATE DIGIT+8x+2x
       CLRA            ;ACCA WILL HOLD MS BYTE
       ADDB   NBR2X+1  ;ADD 2X LS BYTE TO DIGIT
       ADCA   NBR2X    ;ADD 2X MS BYTE
       BCS    CONERR   ;CARRY OUT OF MS BYTE IS AN ERROR
       ADDB   NBRLO    ;ADD 8X LS BYTE
       ADCA   NBRHI    ;ADD 8X MS BYTE
       BCS    CONERR   ;CARRY OUT OF MS BYTE IS AN ERROR
       STAB   NBRLO    ;SAVE FINAL LS BYTE
       STAA   NBRHI    ;SAVE FINAL MS BYTE

       BRA    NUMLUP
;*****
;INPUT AN OCTAL NUMBER
OCTNUM CMPB   #$07
       BGT    CONERR   ;NOT OCTAL IF > 7

;SHIFT HI & LO BYTES 2 PLACES LEFT - CARRY OUT OF HI BYTE IS ILLEGAL
       BSR    SHIFT2
       BSR    SHIFT

       ORAB   NBRLO    ;ADD IN NEW DIGIT
       STAB   NBRLO

       JMP    NUMLUP

;*****
;GOT NUMBER - SCAN WAS SUCCESSFUL
;UPDATE GOOD SYNTAX LINE POINTER
GUDNUM LDX    LINPTR
       STX    SYNPTR
       LDX    XTEMP2
       LDAA   #1       ;SET "GOOD SCAN" FLAG
       RTS

;*****
;CONVERSION ERROR - SCAN WAS UNSUCCESSFUL
CONERR LDX    XTEMP2
       CLRA
       DECA
       RTS
;----------------------------------
;SHIFT LEFT 2 POSITIONS
SHIFT2 BSR    SHIFT
       BSR    SHIFT
       RTS
;----------------------------------
;SHIFT A TWO BYTE NUMBER LEFT ONE POSITION
SHIFT  ASL    NBRLO
       ROL    NBRHI
       BCS    SHFTER
       RTS
;ERROR - HI ORDER BYTE OVERFLOW
;ABORT NUMBER ROUTINE DIRECTLY THRU STACK ADJ. & A JUMP
SHFTER INS
       INS
       BRA    CONERR

;======================================================
;OUTPUT A SPACE
OUTSP  LDAA   #$20
       JSR    OUTCHR
       RTS

;======================================================
;OUTPUT AN "=" SIGN
OUTEQ  LDAA   #'='
       JSR    OUTCHR
       RTS

;======================================================
;OUTPUT A 1 BYTE NUMBER
;ACCA, ACCB, & IX ARE PRESERVED
OUT1BY PSHB
       LDAB   #1
       BSR    OUTNUM
       PULB
       RTS

;======================================================
;OUTPUT A 2 BYTE NUMBER
;ACCA, ACCB, & IX ARE PRESERVED
OUT2BY PSHB
       LDAB   #2
       BSR    OUTNUM
       PULB
       RTS

;======================================================
;DISPLAY THE NUMBER POINTED AT BY THE ADDRESS IN THE INDEX REGISTER
;AND OUTPUT IT ACCORDING TO THE BASE SPECIFIED IN "DBCODE"
;LEADING ZEROES ARE INCLUDED
;ACCA & IX ARE PRESERVED
;ACCB IS INPUT AS THE NUMBER OF BYTES COMPRISING THE NUMBER
;GLOBAL VARIABLES FOR EXTERNAL COMMUNICATION
;IBCODE - INPUT BASE CODE
;DBCODE - DISPLAY BASE CODE

;LOCAL VARIABLES
;DECDIG - DECIMAL DIGIT BEING BUILT
;NUMBHI - HI BYTE OF NUMBER BEING OUTPUT
;NUMBLO - LO BYTE OF NUMBER BEING OUTPUT

OUTNUM STX    XTEMP1
       PSHA
       LDX    ,X       ;GET THE TO BYTES AT THAT ADDRESS
       STX    NUMBHI   ;PUT THEM IN A SCRATCH AREA FOR PROCESSING
       LDAA   DBCODE   ;GET DISPLAY BASE

       CMPA   #1
       BEQ    OUTHEX
       CMPA   #2
       BEQ    OUTDEC
       CMPA   #3
       BEQ    OUTOCT
       CMPA   #4
       BEQ    OUTBIN

;*****
;OUTPUT A HEX NUMBER
OUTHEX ASLB            ;1 BYTE=2 CHARS, 2 BYTES=4 CHARS
;GET NEXT 4 BITS
DISNU1 JSR    LSH2
       JSR    LSH2

       ANDA   #$F      ;EXTRACT 4 BITS
       CMPA   #9
       BLE    DISNU2
       ADDA   #7       ;CONVERT 10:15 TO A:F

DISNU2 BSR    OUTIT
       DECB
       BNE    DISNU1
       BRA    OUTDE5

;*****
;OUTPUT A DECIMAL NUMBER
OUTDEC DECB            ;TEST # OF BYTES TO OUTPUT
       BEQ    OUTDE1
;INITIALIZE FOR OUTPUT OF A 2 BYTE NUMBER
       LDX    #C10K
       LDAA   NUMBHI
       LDAB   NUMBLO
       BRA    OUTDE2

;INITIALIZE FOR OUTPUT OF A 1 BYTE NUMBER
OUTDE1 LDX    #C100
       CLRA
       LDAB   NUMBHI

OUTDE2 CLR    DECDIG   ;CLEAR THE DIGIT TO OUTPUT

;SUBTRACT THE POWER OF 10 CONVERSION CONSTANT
OUTDE3 SUBB   1,X
       SBCA   0,X
       BCS    OUTDE4   ;TEST FOR BORROW (CARRY)

       INC    DECDIG   ;NO BORROW YET - INC DIGIT BEING BUILT
       BRA    OUTDE3   ;REPEAT LOOP
;BORROW GENERATED - CANCEL LAST SUBTRACTION
OUTDE4 ADDB   1,X
       ADCA   0,X

;BUILDING OF DIGIT TO OUTPUT COMPLETE - PRINT IT
       PSHA            ;SAVE LO BYTE OF NUMBER BEING OUTPUT
       LDAA   DECDIG   ;GET DIGIT
       BSR    OUTIT    ;PRINT IT
       PULA            ;RESTORE LO BYTE
;GET NEXT LOWER POWER OF 10
       INX
       INX
       CPX    #C10K+10 ;ARE WE THRU WITH UNITS CONVERSION?
       BNE    OUTDE2   ;IF NOT, BACK TO GET NEXT DIGIT
OUTDE5 PULA            ;IF YES, RESTORE REGISTERS & RETURN
       LDX    XTEMP1
       RTS

;DECIMAL OUTPUT CONVERSION CONSTANTS
C10K   DW     10000
       DW     1000
C100   DW     100
       DW     10
       DW     1

;*****
;OUTPUT AN OCTAL NUMBER
;FIRST DIGIT IS A ONE OR A ZERO
OUTOCT ASLB            ;FIRST APPROXIMATION OF # OF DIGITS TO OUTPUT
       CLRA
       CMPB   #2
       BGT    OUTOC1
       BSR    LSH2     ;1 BYTE - GET FIRST 2 BITS
       BSR    OUTIT
       BRA    DISNU3   ;GO OUTPUT LAST 2 DIGITS
;TWO BYTE # - OUTPUT HI ORDER BIT/DIGIT
OUTOC1 BSR    LEFSHF
       BSR    OUTIT
       INCB           ;5 MORE DIGITS TO GO
;GET NEXT 3 BITS
DISNU3 BSR    LSH2
       BSR    LEFSHF

       ANDA   #7      ;EXTRACT 3 BITS
       BSR    OUTIT
       DECB           ;COUNT THIS DIGIT
       BNE    DISNU3  ;ARE WE DONE?
       BRA    OUTDE5  ;YES
;*****
;OUTPUT A BINARY NUMBER
OUTBIN ASLB
       ASLB
       ASLB
;GET NEXT BIT
DISNU4 BSR    LEFSHF
       ANDA   #1       ;EXTRACT THE BIT

       BSR    OUTIT    ;OUTPUT IT
       DECB            ;COUNT IT
       BNE    DISNU4   ;ARE WE DONE?
       BRA    OUTDE5   ;YES

;**
;CONVERT TO A NUMERIC ASCII DIGIT & OUTPUT IT
OUTIT  ADDA   #$30
       JSR    OUTCHR
       RTS
;**
;LEFT SHIFT 2 BITS
LSH2   BSR    LEFSHF
       BSR    LEFSHF
       RTS

;**
;LEFT SHIFT THE 3 BYTE NUMBER 1 BIT
LEFSHF ASL    NUMBLO
       ROL    NUMBHI
       ROLA
       RTS

;======================================================
;THIS ROUTINE GETS THE NEXT CHARACTER FROM THE INPUT LINE BUFFER
;ACCA IS PRESERVED
;ACCB IS LOADED WITH THE CHARACTER
;IX IS INCREMENTED & LEFT POINTING TO THE CHARACTER RETURNED
GETCHR LDX    LINPTR
       INX
       LDAB   ,X
       STX    LINPTR
       CLR    BOLFLG   ;SET FLAG TO NOT AT "BEGINNING OF LINE"
       RTS

;======================================================
;THIS ROUTINE GETS THE NEXT CHARACTER IN THE COMMAND LISTS
;ACCA IS THE CHARACTER RETRIEVED
;ACCB IS PRESERVED
;IX IS INCREMENTED & LEFT POINTING TO THE CHARACTER RETURNED
GETLST LDX    LISPTR   ;GET CURRENT LIST POINTER
       INX             ;MOVE POINTER TO NEXT CHAR
       LDAA   ,X       ;GET CHARACTER POINTED AT
       STX    LISPTR   ;SAVE POINTER
       RTS             ;AND RETURN

;======================================================
; COMMAND LISTS
;  A CARRIAGE RETURN SIGNIFIES END-OF-COMMAND
;  A LINE FEED SIGNIFIES END-OF-COMMAND-LST
;LIST 1 - MAJOR COMMANDS
COMLST EQU    *
       FCC    "REG"    ; DISPLAY REGISTERS
       FCB     CR
       FCC    "GOTO"   ;GO TO MEMORY ADDRESS
       FCB     CR
       FCC    "SEI"    ;SET INTERRUPT MASK
       FCB     CR
       FCC    "CLI"    ; CLEAR INTERRUPT MAST
       FCB     CR
       FCC    "COPY"   ;COPY FROM ONE LOCATION TO ANOTHER
       FCB     CR
       FCC    "BREAK"  ;SET BREAKPOINT (SWI CODE)
       FCB     CR
       FCC    "IBASE"  ;SET INPUT BASE
       FCB     CR
       FCC    "DBASE"  ;SET DISPLAY BASE
       FCB    CR
       FCC    "CONTINUE" ;CONTINUE FROM "SWI"
       FCB    CR
       FCC    "DISPLAY" ;DISPLAY MEMORY DATA
       FCB    CR
       FCC    "SET"    ;SET MEMORY DATA
       FCB    CR
       FCC    "VERIFY" ;VERIFY THAT MEMORY CONTENT IS UNCHANGED
       FCB    CR
       FCC    "SEARCH" ;SEARCH MEMORY FOR A BYTE STRING
       FCB    CR
       FCC    "TEST"   ;TEST A RANGE OF MEMORY
       FCB    CR
       FCC    "INT"    ;SET INTERRUPT POINTER
       FCB    CR
       FCC    "NMI"    ;SET NON-MASKABLE INTERRUPT POINTER
       FCB    CR
       FCC    "SWI"    ;SET SOFTWARE INTERRUPT POINTER
       FCB    CR
       FCC    "COMPARE" ;PRINT SUM & DIFFERENCE OF 2 NUMBERS
       FCB    CR
       FCC    "DUMP"   ;DUMP MEMORY IN MIKBUG OR IMAGE FORMAT
       FCB    CR
       FCC    "LOAD"   ;LOAD MIKBUG TAPE
       FCB    CR
       FCC    "DELAY"  ;DELAY SPECIFIED # OF MSECS
       FCB    CR
       FCB    LF       ;END OF LIST 1

;LIST 2 - MODIFIER TO DUMP
       FCC    "TO"     ;DESTINATION ACIA
       FCB    CR
       FCB    LF       ;END OF LIST 2

;LIST 3 - NUMBER BASE SPECIFIERS
       FCC    "HEX"    ;BASE 16
       FCB    CR
       FCC    "DEC"    ;BASE 10
       FCB    CR
       FCC    "OCT"    ;BASE 8
       FCB    CR
       FCC    "BIN"    ;BASE 2
       FCB    CR
       FCB    LF       ;END OF LIST 3

;LIST 4 - INFORMATION REQUEST
       FCC    "?"
       FCB     CR
       FCB     LF       ; END OF LIST 4

;LIST 5 - REGISTER NAMES
       FCC    ".CC"
       FCB     CR
       FCC    ".B"
       FCB     CR
       FCC    ".A"
       FCB     CR
       FCC    ".IX"
       FCB     CR
       FCC    ".PC"
       FCB     CR
       FCC    ".SP"
       FCB     CR
       FCB     LF       ;END OF LIST 5

;LIST 6 - MODIFIERS TO "DISPLAY"
       FCC    "DATA"
       FCB     CR
       FCC    "USED"
       FCB     CR
       FCB     LF       ;END OF LIST 6

;LIST 7 - MODIFIER TO "LOAD"
       FCC    "FROM"   ;SOURCE ACIA
       FCB     CR
       FCB     LF       ;END OF LIST 7
;======================================================

; THIS ROUTINE CONSTRUCTS A LINE OF INPUT BY GETTING ALL INPUT
; CHARACTERS UP TO AND INCLUDING A CARRIAGE RETURN (WHICH THEN
; DESIGNATES "END OF LINE").
; TYPING RUBOUT WILL DELETE THE PREVIOUS CHARACTER
; TYPING CONTROL-C WILL ABORT THE LINE
; TYPING CONTROL-Z WILL USE THE PREVIOUS LINE
; THE INPUT LINE IS STORED BEGINNING AT THE ADDRESS STORED IN BUFBEG
; AND ENDING AT THE ADDRESS STORED IN BUFEND
;ACCA, ACCB, & IX ARE NOT PRESERVED
;
;GLOBAL VARIABLES
;BUFBEG - INPUT LINE START OF BUFFER
;BUFEND - INPUT LINE END OF BUFFER

;LOCAL CONSTANTS
BAKSLA EQU    92       ;A BACKSLASH
DELETE EQU    127      ;CODE TO DELETE THE PREVIOUS CHARACTER
;
;
;*** ROUTINE ENTRY POINT

GETLIN LDX    BUFBEG   ;SET POINTER TO ONE LESS THAN THE BEGINNING OF THE LINE BUFFER
       CLRB            ;ACCB HOLS THE LAST INPUT CHAR

NXTCHR CPX    BUFEND   ;CHECK CURRENT LINE END AGAINST BUFFER END
       BNE    GETIT

;LINE TOO LONG - ABORT IT AS IF A CONTROL-C HAD BEEN TYPED
       LDX    #MSGLTL  ;GET MESSAGE
       JSR    OUTSTR   ;OUTPUT IT
       LDAB   #3       ;PUT CTL-C IN ACCB
       RTS

GETIT  JSR    INPCHR   ;GET A CHARACTER (RETURNED IN ACCA)
       ANDA   #127     ;DROP PARITY BIT

;CONTROL-Z COPIES FROM PRESENT POSITION TO PREVIOUS END OF LINE
       CMPA   #26      ;IS CHAR A CONTROL-A?
       BNE    TSTCR
       JSR    DOCRLF   ;YES, TYPE CR-LF
       RTS
TSTCR  CMPA   #13      ;IS CHAR A CR?
       BEQ    TSTCR1
       CMPA   #10      ;OR A LF?
       BNE    NOTEOL
TSTCR1 INX
       STAA   ,X       ;YES, STORE THE TERMINATOR
       TST    HDXFLG   ;TEST FOR HALF-DUPLEX TERMINAL
       BNE    TSTCR2
       JSR    DOCRLF   ;TYPE CR-LF
TSTCR2 RTS             ;NOW RETURN

NOTEOL CMPA   #3       ;IS CHAR A CONTROL-C?
       BNE    NOTCTC
;ECHO AN UP-ARROW
       TAB             ;RETURN CONTROL-C IN ACCB
       LDAA   #'^'
       JSR    OUTCHR
       RTS

NOTCTC CMPA   #DELETE  ;NO, IS IT DELETE
       BEQ    RUBNOW   ;IF YES, GO TO RUBNOW

;CONVERT LOWER CASE TO UPPER CASE
       CMPA   #$60     ;BELOW L.C. A?
       BLS    STORIT
       CMPA   #$7A     ;ABOVE L.C. Z?
       BHI    STORIT
       SUBA   #32      ;CONVERT L.C. ALPHABETIC TO U.C.

STORIT INX             ;NOT A DELETE, SO ADVANCE TO NEXT CHARACTER
       STAA   ,X       ;STORE IT IN INPLIN

       CMPB   #DELETE  ;IS LAST CHAR A DELETE?
       BEQ    OUTBAK   ;IF SO. GO TO OUTBAK
       TAB             ;ITS NOT, UPDATE LAST CHAR
       BRA    ECHO     ;GO ECHO IT

;LAST CHAR WAS A DELETE, BUT THIS ONE ISN'T
OUTBAK TAB             ;UPDATE LAST CHAR
       LDAA   #BAKSLA  ;PRINT A -
       JSR    OUTCHR   ;BACKSLASH
       TBA             ;RESTORE CURRENT CHAR FOR ECHO
ECHO   TST    HDXFLG   ;TEST FOR HALF DUPLEX TERMINAL
       BNE    ECHO1
       JSR    OUTCHR   ;NOW ECHO IT
ECHO1  BRA    NXTCHR   ;GET ANOTHER
;
; CURRENT CHARACTER IS A DELETE
; TEST LINE LENGTH - IT ITS ZERO, IGNORE THIS DELETE SINCE
; WE CAN'T DELETE PRIOR TO FIRST CHARACTER IN INPUT LINE
RUBNOW CPX    BUFBEG
       BEQ    NXTCHR
       CMPB   #DELETE  ;WAS LAST CHAR A DELETE?
       BEQ    LASWAS

;LAST CHAR WASN'T A DELETE
      TAB              ;UPDATE LAST CHAR (WITH A DELETE)
      LDAA    #BAKSLA  ;PRINT A -
      JSR     OUTCHR   ;BACKSLASH
;LAST CHAR WAS A DELETE
LASWAS LDAA   ,X       ;GET THE CHAR TO BE DELETED
       DEX             ;DECREMENT LINE POINTER
       BRA    ECHO     ;ECHO DELETED CHARACTER

;======================================================
;INITIALIZATION ROUTINE
;DISABLE INTERRUPTS
       SEI
INITAL LDAA   #1
       STAA   IBCODE   ;SET INPUT BASE TO HEX
       STAA   DBCODE   ;SET DISPLAY BASE TO HEX
;SET UP DISPLAY BASE NUMBER
       LDAA   #16
       STAA   DBNBR
;MAX # OF CHARACTERS PER LINE
       LDAA   #72
       STAA   CPLMAX
       CLR    INPFLG   ;DEFAULT INPUT FROM THE TERMINAL
       CLR    OUTFLG   ;DEFAULT OUTPUT TO THE TERMINAL
       CLR    HDXFLG   ;CLEAR HALF-DUPLEX FLAG
;INITIALIZE ACIA1 & ACIA2 TO 7 BITS AND EVEN PARITY
;RESET BOTH
       LDAA   #3
       STAA   ACIA1-1
       STAA   ACIA2-1
;SET EM UP
       LDAA   #1
       STAA   ACIA1-1
       STAA   ACIA2-1
;SET UP SWI INTERRUPT ADDRESS POINTER
       LDX    #TYPSWI  ;TYPE "SWI" & DO "REG" COMMAND
       STX    SWIVEC
;INITIALIZE TO MONDEB'S COMMAND LISTS
       LDX    #COMLST-1
       STX    COMADR
;TIME CONSTANT FOR A 2 MICROSECOND CLOCK
       LDAA   #83
       STAA   TIMCON
;ALLOW TIME FOR TTY MOTOR TO COME UP TO SPEED
       LDX    #500
       JSR    TIMDEL
       RTS

;======================================================
;OUTPUT A CHARACTER STRING WHICH BEGINS AT THE ADDRESS IN THE INDEX REGISTER
;ACCA & ACCB ARE PRESERVED
;IX IS LEFT POINTING TO THE STRING TERMINATOR
OUTSTR PSHA
OUTST1 LDAA   ,X       ;GET CHAR POINTED TO
       CMPA   #4       ;IS IT A STRING TERMINATOR?
       BEQ    OUTEND   ;DONE IF IT IS
       BSR    OUTCHR   ;ISN'T, OUTPUT IT
       INX             ;ON TO NEXT CHARACTER
       BRA    OUTST1
OUTEND PULA
       RTS             ;RETURN

;======================================================
;INPUT A CHARACTER FROM AN ACIA TO ACCA
;IF INPFLG = 0, INPUT IS FROM TERMINAL ACIA
;IF INPFLG = 0, INPUT IS FROM ANY ACIA
;ACCB & IX ARE PRESERVED

INPCHR STX    XTEMP    ;SAVE IX
       TST    INPFLG   ;TEST INPUT SOURCE FLAG
       BNE    INPCH1
;INPFLG=0: INPUT FROM TERMINAL ACIA
       LDX    #ACIA1
       BRA    INPCH2
;INPFLG=1: INPUT FROM ANY ACIA
INPCH1 LDX    INPADR   ;GET ITS ADDRESS
INPCH2 DEX             ;POINT TO CONTROL REG
INPCH3 LDAA   ,X       ;GET ACIA STATUS BYTE
       BITA   #1       ;CHAR WAITING?
       BEQ    INPCH3   ;IF NOT, TRY AGAIN
       LDAA   1,X      ;YES, GET IT
       LDX    XTEMP    ;RESTORE IX
       RTS

;======================================================
;OUTPUT THE CHARACTER IN ACCA TO THE DESIRED OUTPUT DEVICE/LOCATION
; IF OUTFLG = 0, OUTPUT IS TO TERMINAL
; IF OUTFLG = 1, OUTPUT IS TO ACIA ADDRESS STORED IN OUTADR
; IF OUTFLG = 2, OUTPUT IS TO ADDRESS IN OUTADR & THIS ADDR IS THEN INCREMENTED
;ACCA, ACCB, & IX ARE PRESERVED
OUTCHR PSHB            ;SAVE ACCB
       TST    OUTFLG   ;TEST OUTPUT DESTINATION FLAG
       BEQ    OUTCH4   ;SKIP THIS CODE IF TERMINAL OUTPUT

;OUTPUT TO SOMETHING OTHER THAN THE TERMINAL
      STX     XTEMP    ;SAVE IX
      LDX     OUTADR   ;GET OUTPUT CHAR DESTINATION ADDRESS
      LDAB    #2
      CMPB    OUTFLG
      BEQ     OUTCH2

;OUTFLG = 1: ANY ACIA OUTPUT
       DEX             ;POINT TO ACIA STATUS REG
OUTCH1 BITB   ,X       ;TEST TDRE BIT
       BEQ    OUTCH1   ;LOOP IF NOT READY TO ACCEPT A NEW CHAR
       STAA   1,X      ;NOW READY - SEND IT
       BRA    OUTCH3

;OUTCLF = 2: MEMORY OUTPUT
OUTCH2 STAA   ,X       ;SAVE CHAR IN MEMORY
       INX
       STX    OUTADR   ; UPDATE OUTPUT ADDRESS

OUTCH3 LDX    XTEMP    ;RESTORE IX
       PULB            ;RESTORE ACCB
       RTS

;OUTFLG = 0: TERMINAL ACIA OUTPUT
;IGNORE LINE FEEDS
OUTCH4 CMPA   #LF
       BNE    OUTCH5
       PULB
       RTS

OUTCH5 CMPA   #CR      ;TEST FOR CARRIAGE RETURN
       BNE    OUTCH6
       BSR    DOCRLF
       PULB
       RTS

OUTCH6 LDAB   CPLCNT   ;GET "CHARACTERS PER LINE" COUNT
       CMPB   CPLMAX   ;COMPARE TO MAX PERMISSIBLE
       BGE    OUTCH7   ;SEND CR-LF IF GREATER
;LESS THAN MAX, BUT ALSO SEND CR-LF IF 10 FROM END AND PRINTING A SPACE
       ADDB   #10
       CMPB   CPLMAX
       BLT    OUTCH8
       CMPA   #$20     ;NEAR END, TEST IF ABOUT TO PRINT A SPACE
       BNE    OUTCH8

;TERMINAL LINE FULL OR NEARLY FULL - INTERJECT A CR-LF
OUTCH7 BSR    DOCRLF
OUTCH8 INC    CPLCNT   ;BUMP COUNTER
       BSR    TOACIA   ;SEND IT TO ACIA1
       PULB
       RTS

;======================================================
;SEND A CARRIAGE RETURN-LINE FEED TO THE TERMINAL
;ACCA, ACCB, & IX ARE PRESERVED
DOCRLF PSHA
       PSHB
       LDAA   #CR
       BSR    TOACIA
       LDAA   #LF
       BSR    TOACIA

;ALLOW TIMER FOR THE CARRIAGE TO RETURN BY SENDING NULL CHARACTERS
;SEND 1 NULL PER 16 CHARACTERS
;DIVIDE CPLCNT BY 16
       LDAB   CPLCNT
       LSRB
       LSRB
       LSRB
       LSRB
       INCB            ;ALWAYS SEND AT LEAST 1 NULL
DOCRL1 CLRA            ;GET A NULL
       BSR    TOACIA   ;SEND IT
       DECB
       BNE    DOCRL1
       CLR    CPLCNT   ;ZERO "CHARACTERS PER LINE" COUNT
       PULB
       PULA
       RTS

;======================================================
;PUT CHAR IN ACCA INTO TERMINAL ACIA
;ACCA, ACCB, & IX ARE PRESERVED
TOACIA PSHA            ;SAVE CHAR
       LDAA   #2       ;GET ACIA TRANSMIT REG STATUS BIT
TOACI1 BITA   ACIA1-1  ;REGISTER EMPTY?
       BEQ    TOACI1   ;IF NOT, LOOP BACK
       PULA            ;YES, RESTORE CHARACTER
       STAA   ACIA1    ;SEND IT
       RTS

;======================================================
;MISC TEST
MSGHED FCC    "MONDEB 1.00" ;MONITOR HEADER TYPEOUT
       FCB     CR,4

MSGPRM FCB     '*'    ;PROMPT STRING
       FCB     4
MSGSWI FCB     CR
       FCC    "SWI:"
       FCB     4

MSGLTL FCC    "TOO LONG" ; TYPED IF INPUT LINE IS TOO LONG
       FCB     4

MSGNBR FCC    "NOT SET" ; BREAK NOT SET
       FCB     4

MSGBAT FCC    "SET @ " ; BREAK AT -
       FCB     4

MSGVER FCC    "OK"     ;CHECKSUM VERIFIES
       FCB     4

MSGNVE FCC    "CHECKSUM ERROR " ; FOR VERIFY & LOAD COMMANDS
       FCB     4

MSGCCL FCC    "CANT CLEAR" ; TEST COMMAND
       FCB     4

MSGCSO FCC    "CANT SET TO ONES" ; TEST COMMAND
       FCB     4

MSGSIS FCC    "SUM IS " ; COMPARE COMMAND
       FCB     4

MSGDIS FCC    ", DIF IS " ; COMPARE COMMAND
       FCB     4

MSGS0  FCB     CR,LF,0
       FCC    "S00600004844521B"
       FCB     4

MSGS1  FCB     CR,LF,0,0,'S'
       FCB     '1'
       FCB     4

MSGS9  FCB     CR,LF,0
       FCC    "S9030000FC"
       FCB     CR,LF,4

MSGCNH FCC    "CHAR NOT HEX" ;USE IN LOAD COMMAND
       FCB     CR,4

;======================================================
;INTERRUPT HANDLING CODE
INTADR LDX    INTVEC
       JMP    ,X
;*****
NMIADR LDX    NMIVEC
       JMP    ,X
;*****
RESADR JMP    START
;*****
SWIADR STS    SP       ;SAVE STACK POINTER OF PROGRAM BEING DEBUGGED
       LDX    SWIVEC
       JMP    ,X
;*****
;      RMB    START+$c00-8-63-* ;BLANK SPACE TO INTERRUPT VECTORS
;       * =    $FFB9    ;AS CALCULATED BY PREVIOUS LINE
       ORG    $FFB9
;**************************************************

       JMP    TIMDEL   ;TIME DELAY FOR # OF MS SPECIFIED BY IX
       JMP    CKSUM    ;RETURN CHECKSUM OF AN ADDRESS RANGE IN ACCA
       JMP    GETCHR   ;RETURN (IN ACCB) CHAR POINTED TO BY LINPTR
       JMP    GETLST   ;RETURN (IN ACCA) CHAR POINTED TO BY LISPTR
       JMP    GTRANG   ;PICK UP AN ADDRESS RANGE IN RANGLO & RANGHI
       JMP    NUMBER   ;PICK UP A NUMBER & RETURN IT IN NBRHI & NBRLO
       JMP    SKPDLM   ;SKIP OVER INPUT LINE DELIMITERS
       JMP    TSTDLM   ;TEST CHAR IN ACCB FOR A DELIMITER
       JMP    TSTEOL   ;TEST CHAR IN ACCA FOR END-OF-LINE
       JMP    COMAND   ;SEARCH SPECIFIED COMMAND LIST FOR A COMMAND
       JMP    TYPCMD   ;TYPES OUT COMMAND NUMBER "COMNUM" IN LIST ACCA
       JMP    OUT1BY   ;DISPLAY THE 1 BYTE NUMBER POINTED AT BY IX
       JMP    OUT2BY   ;DISPLAY THE 2 BYTE NUMBER POINTED AT BY IX
       JMP    GETLIN   ;GET A LINE OF INPUT INTO THE TTY BUFFER
       JMP    OUTSTR   ;OUTPUT CHAR STRING IX POINTS TO
       JMP    DOCRLF   ;SEND CR-LF WITH DELAY & ZERO LINE COUNT
       JMP    OUTCHR   ;LIKE TOACIA, BUT WITH FOLDING, CR DELAY, & LF INSERTION
       JMP    TOACIA   ;SEND ACCA TO ACIA1
       JMP    INPCHR   ;GET A CHAR FROM AN ACIA & RETURN IT IN ACCA
       JMP    PROMPT   ;TO PROMPT FOR A NEW COMMAND
       JMP    START    ;START OF MONDEB
;**************************************************
;INTERRUPT VECTORS
       DW    INTADR    ;REGULAR INTERRUPT
       DW    SWIADR    ;SOFTWARE INTERRUPT
       DW    NMIADR    ;NON-MASKABLE INTERRUPT
       DW    RESADR    ;RESET INTERRUPT

;**************************************************
;VARIABLES FOR INTER-ROUTINE COMMUNICATION
;       * =    $7000
;       ORG    $7000
        ORG    $7000
INTVEC DS     2        ;INTERRUPT ADDRESS POINTER
NMIVEC DS     2        ;NON-MASKABLE INTERRUPT ADDRESS POINTER
SWIVEC DS     2        ;SOFTWARE INTERRUPT ADDRESS POINTER
SP     DS     2        ;SAVED STACK POINTER
COMADR DS     2        ;ADDRESS OF BEGINNING OF COMMAND LISTS FOR COMMAND
SYNPTR DS     2        ;INPUT LINE CHARACTER POINTER FOR GOOD SYNTAX
LINPTR DS     2        ;INPUT LINE CHARACTER POINTER (CONTENT = OR > CONTENT OF SYNPTR)
BOLFLG DS     1        ;"BEGINNING OF LINE" FLAG
DELIM  DS     1        ;CHARACTER(S) PERMITTTED AS VALID COMMAND/MODIFIER DELIMITER
IBCODE DS     1        ;INPUT BASE (1=HEX, 2=DEC, 3=OCT)
DBCODE DS     1        ;DISPLAY BASE (1=HEX, 2=DEC, 3=OCT, 4=BIN)
DBNBR  DS     1        ;DISPLAY BASE NUMBER (E.G., 16,10M8M OR 2)

NBRHI  DS     1        ;MOST SIGNIFICANT BYTE OF SCANNED NUMBER
NBRLO  DS     1        ;LEAST SIGNIFICANT BYTE OF SCANNED NUMBER

RANGLO DS     2        ;RANGE LOWER LIMIT PICKED UP BY GTRANG
RANGHI DS     2        ;RANGE UPPER LIMIT PICKED UP BY GTRANG

LASTGO DS     2        ;LAST SPECIFIED GOTO ADDRESS

VERFRM DS     2        ;BEGINNING ADDRESS OF RANGE TO CHECKSUM VERIFY
VERTO  DS     2        ;ENDING ADDRESS OF RANGE TO CHECKSUM VERIFY

CHKSUM DS     1        ;CHECKSUM OF RANGE GIVEN IN THE VERIFY COMMAND

BRKADR DS     2        ;ADDRESS OF INSERTED BREAKPOINT
BRKINS DS     1        ;INSTRUCTION WHICH SHOULD BE THERE NORMALLY

INPFLG DS     1        ;ALTERNATE INPUT DESTINATION FLAG
INPADR DS     2        ;ALTERNATE ADDRESS THAT THE INPUT CHARACTERS ARE TO COME FROM

OUTFLG DS     1        ;ALTERNATE OUTPUT DESTINATION FLAG
OUTADR DS     2        ;ALTERNATE ADDRESS THAT THE OUTPUT CHARACTERS ARE TO GO TO

HDXFLG DS     1        ;HALF-DUPLEX TERMINAL FLAG (IF NON-ZERO, NO ECHO)

CPLCNT DS     1        ;"CHARACTERS PER LINE" COUNT
CPLMAX DS     1        ;"CHARACTERS PER LINE" MAXIMUM
BUFBEG DS     2        ;INPUT LINE START OF BUFFER
BUFEND DS     2        ;INPUT LINE END OF BUFFER
TTYBUF DS     72       ;START OF INPUT LINE BUFFER
TTYEND DS     1        ;END OF INPUT LINE BUFFER
       DS     56       ;MAIN STACK STORAGE
STACK  DS     7        ;STACK STORAGE FOR RTI INSTRUCTION

;TEMPORARY (LOCALLY USED) VARIABLES
TEMP1  DS     2        ;IN: MAIN
TEMP2  DS     2        ;IN: MAIN
TEMP3  DS     2        ;IN: FNDSTR,MAIN
TEMP4  DS     2        ;IN: MAIN
TEMP5  DS     2        ;IN: MAIN
TEMP6  DS     2        ;IN: MAIN
TEMP7  DS     2        ;IN: MAIN
TEMP8  DS     2        ;IN: MAIN
TEMP9  DS     2        ;IN: MAIN
TEMP10 DS     2        ;IN: MAIN
TEMP11 DS     2        ;IN: MAIN

;XTEMP IS NOT TO BE USED TO SAVE IX BETWEEN ROUTINES
XTEMP  DS     2        ;USED BY DUMP,TYPCMD,OUTNUM
XTEMP1 DS     2        ;USED BY OUTNUM
XTEMP2 DS     2        ;USED BY NUMBER
NUMMAT DS     1        ;USED IN COMMAND
LISNUM DS     1        ;USED ON COMMAND
COMNUM DS     1        ;USED IN COMMAND
LISPTR DS     2        ;USED IN COMMAND
DECDIG DS     1        ;DECIMAL DIGIT BEING BUILT (DECIMAL OUTPUT BASE)
NUMBHI DS     1        ;USED BY OUTNUM
NUMBLO DS     1        ;USED BY OUTNUM
NBR2X  DS     2        ;USED BY NUMBER
TIMCON DS     2        ;DELAY TIME CONSTANT
BYTECT DS     1        ;RECORD BYTE COUNT USED IN LOAD COMMAND
CKSM   DS     1        ;RECORD CHECKSUM USED IN LOAD COMMAND

;CONVENIENT EQUIVALENCES FOR LOCAL VARIABLES
MEMADR EQU    TEMP1    ;DISPLAY,SET,SEARCH,TEST
STRNUM EQU    TEMP2    ;FNDSTR
EOSCHR EQU    TEMP2+1  ;FNDSTR

;FOR "SEARCH" COMMAND
BYTPTR EQU    TEMP2
NBYTES EQU    TEMP3
NBRMAT EQU    TEMP3+1
BYTSTR EQU    TEMP4

;      END
