       NAM    JBUG
* REV 1.8  9-6-76
*
*A MONITOR PROGRAM WITH AN INTERNAL KEYBOARD/DISPLAY
*
* ASSEMBLED ON THE EXORCISER FOR MOTOROLA
* INC. -- FALL OF 76
*
* COPYRIGHT 1976 BY MOTOROLA SPG
*
       OPT    S,O      SYMBOL TABLE;OBJECT TAPE
*
*
*
**COMMAND SYMBOLS
****P - PUNCH DESIGNATED MEMORY TO AUDIO CASSETTE
****L - LOAD AUDIO CASSETTE TO MEMORY
****N - TRACE ONE INSTRUCTION
*        USES NMI INTERUPT
*        N CLEARS ANY BRKPTS IF SET
*        SINCE TRACE USES HARDWARE IT CAN
*        TRACE THRU ROM AND INTERRUPTS
****V - SET AND CLEAR BREAKPOINTS (FIVE ALLOWED)
*        IF THE ADDRESS NOT= ZERO THEN A BRKPT
*        IS INSERTED AT THE ADDRESS. IF THE
*        ADDRESS = 0 THEN ALL 5 BRKPTS ARE CLEARED.
****M - MEMORY EXAMINE AND CHANGE
****E - ESCAPE (ABORT)
****R - REGISTER DISPLAY
*        ORDER OF DISPLAY IS: PC,X,A,B,CC,SP
****G - GO TO USERS PROGRAM/ADVANCE/PROCEED.
*        IF ADDRESS NOT = 0 SET USER'S PC TO
*        NEW VALUE AND GO TO USER'S PROGRAM.
*        IF ADDRESS=0 THEN RETURN TO PROGRAM AT
*        PREVIOUS LOCATION (PROCEED MODE).
*        IF IN R,G MEANS ADVANCE TO NEXT REGISTER.
*        IF IN M,G MEANS ADVANCE TO NEXT MEMORY.
*
*
****************************************************
**CONTROL STACK AT $A078**
** RAM STARTS AT $A000
** ROM IS AT LOCATIONS $E000-$E3FF
** ACIA IS AT $8008-8009
** PIA IS AT $8020-8023
****************************************************
****************************************************
*
* THE RESTART ENTRY IS AT LABEL 'RESTAR' AT
* LOCATION $E08D.
*
****************************************************
       PAGE
        ORG    $E000
*
****ROUTINE TO CALCULATE OFFSETS****
***SETUP STACK AS FOLLOWS:
*   B-REG (SP+2) = HIGH BYTE OF DESTINATION ADDR
*   A-REG (SP+3) = LOW BYTE OF DEST ADDR
*   X-REG (SP+4,5) = ADDR OF OPCODE OF BRANCH
*                    INSTRUCTION
       INX
       STX    BPADR    ;STORE OFFSET ADDR
       INX
       STX    TEMP1    ;ADDR OF NEXT OP CODE
       SUBA   TEMP1+1  ;LOW BYTES
       SBCB   TEMP1    ;HIGH BYTES
       LDX    BPADR    ;GET OFFSET ADDR
       STAA   0,X      ;CHANGE OFFSET
       SWI             ;STACK AND DISPLAY
***REGISTERS ON STACK CONTAIN THE FOLLOWING:
*****INDEX - ADDR OF OFFSET BYTE THAT WAS CHANGED
*****A ACCM - VALUE OF OFFSET
*****B ACCM - 00 - FORWARD BRANCH WITHIN RANGE
*****         FF - REVERSE BRANCH WITHIN RANGE
*****         -ANY OTHER VALUE IMPLIES A BRANCH
*****          OUT OF RANGE.
****************************************************
*
* HERE ON IRQ INTERUPT
*
****IRQ INTERRUPT SERVICE****
IO     LDX    IOV      ;PICK UP PSEUDO VECTOR
       JMP    0,X      ;GO TO IT
*
* HERE ON NMI INTERUPT
*    MAY BE TRACE OR A TRACE TO PROCEED
*    OR A KEYBOARD INTERUPT.
*
****NMI INTERRUPT SERVICE****
NONMSK STS    SP       ;SAVE USER'S STACK PTR
       BSR    DISNMI   ;DISABLE NMI INTERUPTS
       TST    NFLAG    ;TRACE MODE?
       BEQ    NONMK1   ;NO
TNM1   CLR    NFLAG    ;RESET FLAG
       BSR    GETXB    ;GET TAB ADDR AND VFLAG
       BEQ    TDISP    ;NO BP, DISPLAY REGS
       JMP    TGB      ;BP ACTIVE
* MUST BE KEYBOARD INTERUPT
NONMK1 LDX    NIO
       JMP    0,X      ;DECODE KEYBOARD
*
* HERE ON SOFTWARE INTERUPT
*    USUALLY A BREAKPOINT
*
****SWI SERVICE ROUTINE****
SWIR   STS    SP       ;SAVE USER'S SP
       BSR    DISNMI   ;DISABLE NMI INTERRUPTS
       TSX             ;DECR PC BY 1
       TST    6,X      ;BACKUP PC ON STACK
       BNE    *+4
       DEC    5,X
       DEC    6,X
       BSR    GETXB    ;GET TAB ADDR AND VFLAG
       BEQ    TDISP    ;NO BRKPTS, GO DISPLAY REGS
*
* REMOVE BRKPTS WHILE WE ARE IN JBUG. THEY
* WILL BE RESTORED ON A GO OR PROCEED
*
******HERE TO REMOVE BREAKPOINTS******
TZONK  STX    BPADR    ;SAVE IN TEMP
       LDAA   2,X      ;GET OP CODE TO RESTORE
* SAFEGUARD AGAINST MULTI DEFINED BRKPTS
*     
       CMPA   #$3F
       BEQ    GENA     ;BRANCH IF MULTI-DEF
       LDX    0,X      ;GET ADDR OF BKPT
       STAA   0,X      ;RESTORE OP CODE
       LDX    BPADR    ;GET TABLE POSITION
GENA   BSR    ADD3X    ;GET NEXT POSITION AND DECB
       BNE    TZONK    ;GO AGAIN
TDISP  STS    SP       ;SAVE USER'S STACK POINTER
       JMP    KEYDCE   ;GO DISPLAY REGS
*
****SUBROUTINE TO GET NEXT TABLE ENTRY
*
ADD3X  INX
       INX
       INX
       DECB            ;DEC CTR
       RTS             ;LET CALLED DO CTR CHECK
*
****SUB TO GET TABLE ADDR IN X VFLAG IN B
*
GETXB  LDX    #BPTAB   ;GET TABLE BASE ADDR
       LDAB   VFLAG
       RTS
*
**SUBROUTINE TO SET A BREAKPOINT (MAKE AN
****ENTRY INTO BREAKPOINT TABLE) IF ENOUGH
****SPACE EXISTS
*   THE ACTUAL BRKPTS ARE PUT IN MEMORY
*   ON THE 'G' COMMAND
*
SETBR  BSR    GETXB    ;GET TAB ADDR AND VFLAG
       BEQ    TZOT     ;NO BKPTS, GO INSERT ONE
       CMPB   #$5      ;ENOUGH ROOM?
       BGE    CLRDS    ;NO, CLEAR DISPLAY AND RTS
******GET TO FIRST FREE SPACE IN TABLE******
TPIG   BSR    ADD3X    ;ADD 3 TO X AND DECB
       BNE    TPIG     ;BRANCH IF NOT DONE
******INSERT NEW BKPT IN TABLE*****
TZOT   INC    VFLAG    ;INCR FLAG
       LDAA   BPADR    ;INSERT IN TABLE
       STAA   0,X
       LDAA   BPADR+1
       STAA   1,X
       RTS
*
****SUBROUTINE TO DISABLE NMI INTERRUPTS****
*
DISNMI LDAA   #$3C
       STAA   DISCTR   ;INTR MASKED CA1 ACTIVE LOW
       STAA   SCNCTR   ;INTR MASKED CB1 ACTIVE LOW
       RTS
*
*
****RESTART ROUTINE****
*
*
RESTAR LDS    #$A078
       STS    SP       ;INITALIZE STACK POINTER
       LDX    #KEYDC   ;GO DECODE KEYBOARD
       STX    NIO      ;INITALIZE NMI INTERRUPT
*INITALIZE KEYBOARD/DISPLAY PIA
       LDAA   #$FF
       STAA   SCNREG   ;PBO-PB7 OUTPUTS
       LSRA 
       STAA   DISREG   ;PA0-PA6 OUTPUTS,PA7 INPUT
       BSR    DISNMI   ;DISABLE KEYBOARD/TRACE
**INITALIZE ACIA**
       LDAA   #3
       STAA   ACIAS    ;RESET THE ACIA
       CLR    VFLAG    ;INITALIZE VFLAG
INIT   BSR    CLFLG    ;CLEAR DISPLAY AND FLAGS
       BSR    HDR      ;WRITE PROMPT "-"
       BRA    OUTDS
*
****SUBROUTINE TO CLEAR DISPLAY BUFFER AND FLAGS****
*
CLFLG  LDX    #DIGIN4
       CLRA            ;CLEARS DIGIN4 AND DIGIN8
CLFLG1 STAA   0,X      ;CLEARS MFLAG AND RFLAG
       INX             ;CLEARS NFLAG AND TEMP2
       CPX    #DIGIN4+6  ;END?
       BNE    CLFLG1   ;NO LOOP BACK
       LDX    #DISBUF
       STX    XKEYBF   ;INITALIZE XKEYBF
CLRDS  LDAA   #$7F
       STAA   DISREG   ;BLANK DISPLAY
       LDAA   #17
       LDX    #DISBUF
CLRDS1 STAA   0,X      ;CLEAR OUT DISPLAY BUFFER
       INX
       CPX    #DISBUF+8  ;END?
       BNE    CLRDS1
       RTS
*
*SUBROUTINE TO WRITE PROMPT ON DISPLAY
*
HDR    LDAA   #16
       STAA   DISBUF   ;OUTPUT -
       RTS
*
*SUBROUTINE TO DELAY 20 MS OR X MS
*   WHEN ENTERING AT DLY1 THE XREG MUST CONTAIN
*   THE DESIRED DELAY CT (APX 13USEC/COUNT)
*
DLY20  LDX    #$0600
DLY1   DEX
       BNE    DLY1
       RTS
*
****SUBROUTINE TO BUILD TWO BYTE ADDRESS FROM
******FIRST LOCATIONS OF DISBUF
*   ADDRESS IS IN X-REG AND 'BPADR' ON EXIT
*
BLDX   LDX    #DISBUF
       LDAA   0,X      ;GET FIRST BYTE
       ASLA 
       ASLA 
       ASLA 
       ASLA            ;MOVE TO HIGH NIBBLE
       ORAA   1,X      ;OR WITH LOW NIBBLE
       STAA   BPADR-DISBUF,X  ;STORE IN BPADR
       LDAA   2,X      ;GET SECOND BYTE
       ASLA 
       ASLA 
       ASLA 
       ASLA            ;MOVE TO HIGH NIBBLE
       ORAA   3,X      ;OR WITH LOW NIBBLE
       STAA   BPADR+1-DISBUF,X  ;STORE IN BPADR+1
       LDX    BPADR-DISBUF,X  ;ADDRESS TO XREG
       RTS
*
*
****ROUTINE TO DISPLAY 6 DIGITS IN DISBUF
*
*
OUTDS  LDX    #DISBUF  ;GET STARTING ADDRESS
OUTDS1 LDAA   0,X      ;GET FIRST DIGIT
       INCA 
       INX
       STX    XDSBUF   ;SAVE POINTER
       LDX    #DIGTBL-1
OUTDS2 INX
       DECA            ;POINT TO PATTERN
       BNE    OUTDS2
       CLR    SCNREG   ;BLANK DISPLAY
       LDAA   0,X      ;GET PATTERN
       STAA   DISREG   ;SET UP SEGMENTS
       LDAA   SCNCNT
       STAA   SCNREG   ;SELECT DIGIT
       LDX    #$4D     ;SETUP FOR 1MS DELAY
       BSR    DLY1     ;DELAY 1 MS
       LDX    XDSBUF   ;RECOVER POINTER
       CPX    #DISBUF+6
       BEQ    OUTDS3
       LSR    SCNCNT   ;NO,MOVE TO NEXT DIGIT
       BRA    OUTDS1
*
****SUBROUTINE TO SCAN KEYBOARD****
*
KEYCL  LDAA   #$FF
       LDX    #DISREG
       STAA   0,X      ;BLANK DISPLAY
       LDAA   #$3F
       STAA   2,X      ;ALL ROWS LOW
KEYCL1 LDAA   2,X
       TST    0,X
       BPL    KEYCL2   ;KEY DOWN?
       ADDA   #64
       STAA   2,X      ;SELECT NEXT COLUMN
       ANDA   #$C0
       BNE    KEYCL1   ;LAST COLUMN SCANNED?
KEYCL2 RTS             ;NO KEY FOUND
OUTDS3 LDAA   #$20
       STAA   SCNCNT   ;INITALIZE SCNCNT
*
****ROUTINE TO SCAN AND DECODE KEYBOARD****
*
KEYDC  BSR    KEYCL
       BEQ    OUTDS    ;NO KEY CLOSED
       BSR    DLY20
       LDX    #DISREG  ;RESTORE X
       LDAA   #$01     ;SETUP SCAN FOR FIRST ROW
       STAA   2,X
KEYDC1 BSR    KEYCL1   ;SCAN KEYBOARD,GET KEY
       BNE    KEYDC2   ;KEY FOUND
       LDAA   2,X      ;CLEARS NMI INTERRUPT
       CMPA   #$20
       BEQ    OUTDS    ;LAST ROW
       ASL    2,X      ;SHIFT LEFT
       BRA    KEYDC1
KEYDC2 CLRB            ;INITIALIZE COUNTER
       LDX    #KEYTBL
KEYDC3 CMPA   0,X      ;SEARCH TABLE
       BEQ    KEYDC4
       CPX    #KEYTBL+24  ;END OF TABLE?
       BEQ    KEYD0F   ;NO KEY FOUND IN TABLE
       INX
       INCB            ;ADVANCE
       BRA    KEYDC3
KEYDC4 BSR    KEYCL    ;WAIT FOR KEY RELEASE
       BNE    KEYDC4
       JSR    DLY20    ;DELAY 20 MSEC
       CMPB   #$0F
       BGT    KEYDC5
       LDX    XKEYBF   ;POINTER IN DISBUF
       STAB   0,X      ;STORE KEY VALUE
       CPX    #DISBUF+3  ;4 DIGITS IN?
       BNE    KEYDC7   ;NO
       INC    DIGIN4   ;YES
KEYDC6 INX
       STX    XKEYBF
       BRA    KEYD0F
KEYDC7 CPX    #DISBUF+7  ;8 DIGITS IN?
       BNE    KEYDC6
       INC    DIGIN8   ;SET FLAG
       JSR    MDIS1    ;DISPLAY NEW DATA
       LDX    XKEYBF
       DEX             ;BACK UP POINTER
       STX    XKEYBF   ;SAVE
       BRA    KEYD0F
*
* HERE TO DISPATCH TO A KEYBOARD OPTION
**
*
KEYDC5 LDX    #JMPTAB-32
KYDC5  INX             ;GET TO ADDRESS IN JUMP TABLE
       INX
       DECB 
       BNE    KYDC5    ;THIS ONE?
       JMP    0,X      ;YES
JMPTAB BRA    KEYDC8   ;P KEY
       BRA    KEYDC9   ;L KEY
       BRA    KEYDCA   ;N KEY
       BRA    KEYDCB   ;V KEY
       BRA    KEYDCC   ;M KEY
       BRA    KEYDCD   ;E KEY
       BRA    KEYDCE   ;R KEY
       BRA    KEYDCF   ;G KEY
*
* HERE ON P KEY
*   PUNCH MEMORY TO AUDIO CASSETTE
*
KEYDC8 JSR    CLRDS    ;CLEAR DISPLAY
       JSR    PNCH     ;PUNCH DATA TO CASSETTE
       BRA    KEYDCH
*
* HERE ON L KEY
*   LOAD MEMORY FROM AUDIO CASSETTE 
*
KEYDC9 JSR    CLRDS    ;CLEAR DISPLAY
       JSR    LOAD     ;LOAD DATA FROM CASSETTE
KEYDCH JSR    HDR      ;WRITE HEADER
* RETURN TO DISPLAY HEADER
KEYD0F JMP    OUTDS    ;DISPLAY HEADER
*
* HERE ON N KEY
*   TRACE ONE INSTRUCTION
*
KEYDCA CLR    VFLAG
TRACE  INC    NFLAG
       LDAA   #$34     ;SET UP HARDWARE TO TRACE
       STAA   DISCTR   ;CA2 LOW START TRACE
       RTI
*
* HERE ON V KEY
*   IF ADDRESS HAS 4 DIGITS INSERT A BRKPT
*   AT ADDRESS OTHERWISE CLEAR ALL 5 BRKPTS
*
KEYDCB TST    DIGIN4   ;4 DIGITS IN?
       BNE    *+7      ;YES, INSERT BP
       CLR    VFLAG
       BRA    KEYD0F   ;GO DISPLAY
       BSR    KEYD3F   ;YES, INSERT BREAKPOINT
       JSR    SETBR
       BRA    KEYD0F
*
* HERE ON M KEY
*   DISPLAY MEMORY CONTENTS
*
KEYDCC INC    MFLAG    ;SET FLAG
       TST    DIGIN4   ;4 DIGITS IN?
       BEQ    KEYD0F   ;NO
       BSR    MDIS     ;YES,DISPLAY MEMORY
       BRA    KEYD0F
*
* HERE ON E KEY
*   ESCAPE (ABORT) USER PGM
*
KEYDCD JMP    INIT     ;CLEAR DISPLAY AND FLAGS
*
* HERE ON R KEY
*   DISPLAY USER REGISTERS
*
KEYDCE INC    RFLAG    ;REGISTER DISPLAY
       JSR    REGST
* MUTUAL RETURN TO DISPLAY
KEYDCG BRA    KEYD0F
*
* HERE ON G KEY
*   IF IN 'M' DISPLAY NEXT MEMORY LOCATION
*   IF IN 'R' DISPLAY NEXT REGISTER
*   IF 4 DIGIT ADDRESS WAS PUNCHED GO TO
*      ADDRESS IN USER PROGRAM
*   IF 4 DIGITS WEREN'T INPUT RETURN TO USERS
*      PGM AT CURRENT USER PC (PROCEED)
*
KEYDCF TST    MFLAG    ;MEMORY MODE?
       BNE    KEYD1F   ;YES
       TST    RFLAG
       BNE    KEYD2F
* IS IT A 'GO' OR 'PROCEED'?
       TST    DIGIN4   ;4 DIGITS IN?
       BNE    KEYDCJ   ;NO, PROCEED MODE
* HERE ON PROCEED
       JSR    GETXB    ;GET ADDR AND VFLAG
       BEQ    TGC      ;BRANCH IF NO BREAKPOINTS
       BRA    TRACE    ;GO TRACE
* HERE ON GO MODE
KEYDCJ BSR    KEYD3F   ;GET ADDR
       TSX
       STAA   6,X      ;MODIFY LOW BYTE
       LDAB   BPADR    ;GET LOW BYTE
       STAB   5,X      ;MODIFY HIGH BYTE
       JSR    CLRDS    ;CLEAR DISPLAY
       JSR    GETXB    ;GET TAB ADDR&VFLAG
       BEQ    TGC      ;BRANCH IF NO  BP
****INSTALL ALL BREAKPOINTS****
TGB    STX    BPADR    ;SAVE IN TEMP
       LDX    0,X      ;GET ADDR OF BP
       LDAA   0,X      ;GET OP-CODE     
       PSHA            ;SAVE
       LDAA   #$3F     ;INSTALL A SWI
       STAA   0,X
       LDX    BPADR    ;GET BACK CURR TAB LOC
       PULA            ;GET BACK OP-CODE
       STAA   2,X      ;SAVE IT IN A TABLE
       JSR    ADD3X    ;GET NEXT TAB LOC
       BNE    TGB      ;MORE TO DO?
* PREPARE TO RETURN TO USER
TGC    LDAA   #$20
       STAA   SCNREG   ;SETUP FOR KB INTR
       LDAB   SCNREG   ;DUMMY READ TO CLEAR INTR
       LDAA   #$3D
       STAA   SCNCTR   ;ENABLE KB INTR
       RTI             ;BACK TO USER
* HERE TO DISPLAY NEXT ;MEM LOC
KEYD1F BSR    MINC     ;MEMORY INCREMENT
       BSR    MDIS0    ;MEMORY DISPLAY
       BRA    KEYDCG
* HERE ON DISPLAY NEXT REGISTER
KEYD2F JSR    REGST1   ;REGISTER DISPLAY
       BRA    KEYDCG
KEYD3F JMP    BLDX
**
*
**SUBROUTINE TO DISPLAY MEMORY AND CHANGE IT**
*
*
MDIS   LDX    XKEYBF
       INX
       INX
       STX    XKEYBF   ;UPDATE POINTER
MDIS0  BSR    KEYD3F   ;GET ADDR OF MEM LOCATION
       LDAA   0,X      ;GET MEMORY DATA
       BSR    MDIS2    ;FORMAT DATA
       STAA   DISBUF+4 ;STORE DATA IN DISBUF
       STAB   DISBUF+5
       RTS
*
* SUB TO PUT NEW DATA IN MEMORY AND DISPLAY IT
*
MDIS1  LDAB   DISBUF+6 ;GET NEW DATA
       ASLB 
       ASLB 
       ASLB 
       ASLB            ;DATA TO HIGH NIBBLE
       ORAB   DISBUF+7 ;OR WITH LOW NIBBLE
       BSR    KEYD3F   ;GET MEMORY ADDR AGAIN
       STAB   0,X      ;STORE NEW DATA
       LDAA   0,X      ;ACTUAL DATA IN MEMORY
       BSR    MDIS2    ;FORMAT
       STAA   DISBUF+4 ;ACTUAL DATA TO DISPLAY
       STAB   DISBUF+5
       CLR    DIGIN8   ;SETUP FOR NEW DATA ENTRY
       RTS
*
**SUBROUTINE TO MOVE LOW NIBBLE OF A TO B AND TO
****MOVE HIGH NIBBLE OF A TO LOW NIBBLE OF A
*
MDIS2  TAB
       ANDB   #$0F     ;MASK LOW NIBBLE
       ANDA   #$F0     ;MASK HIGH NIBBLE
       LSRA 
       LSRA 
       LSRA 
       LSRA            ;HIGN NIBBLE TO LOW NIBBLE
       RTS
*
* SUBROUTINE TO INC MEMORY DISPLAY AND CHG?
*
MINC   BSR    KEYD3F   ;GET MEMORY ADDRESS
       INX             ;SETUP FOR NEXT MEMORY LOC
       STX    TEMP1    ;SAVE
       LDAA   TEMP1    ;GET HIGH BYTE
       BSR    MDIS2    ;FORMAT FOR DISBUF
       LDX    #DISBUF
       STAA   0,X
       STAB   1,X      ;PUT IN DISPLAY BUFFER
       LDAA   TEMP1+1  ;GET LOW BYTE
       BSR    MDIS2    ;FORMAT
       STAA   2,X
       STAB   3,X
       INC    DIGIN4   ;FOUR DIGITS ENTERED
       INC    MFLAG    ;SETUP FOR MEMORY EXAMINE
       RTS
*
*
**SUBROUTINE TO DISPLAY REGISTERS ON USERS STACK
*
* ORDER OF DISPLAY IS: PC,X,A,B,CC,SP
*   TEMP2 STARTS AT -2 AND ADVANCES TO +3 AND
*   CORRESPONDS TO THE ORDER OF DISPLAY
*
REGST  LDAA   #$FE     ;INITIALIZE COUNTER
       STAA   TEMP2
       LDX    SP       ;GET USER'S SP
       LDAA   #$6
REGST0 INX             ;POINT TO TOP OF STACK
       DECA 
       BNE    REGST0
       STX    TEMP1    ;TEMP X LOCATION
REGST1 JSR    CLRDS    ;CLEAR DISPLAY
       LDX    TEMP1    ;RESTORE X
       LDAA   TEMP2
       BMI    REGST2   ;PC AND X REGS
       CMPA   #$3      ;IS IT SP?
       BEQ    REGST3   ;YES
       CMPA   #$4      ;ALL REGS OUT START OVER
       BEQ    REGST
       LDAA   0,X      ;OUTPUT A,B,CC
       BSR    REGST5   ;DISPLAY ONE BYTE
       BRA    REGST4   ;UPDATE COUNTER
REGST2 PSHA            ;SAVE A
       LDAA   0,X      ;GET HIGH BYTE
       BSR    REGST5   ;DISPLAY
       LDX    TEMP1
       LDAA   1,X      ;GET LOW BYTE
       BSR    REGST6   ;DISPLAY
       PULA            ;RESTORE A
       INCA            ;X REG? (A=0)
       BEQ    REGST4   ;YES
       BSR    REGST8   ;DEC POINTER
       JSR    MDIS0
       BRA    REGST4   ;UPDATE COUNTER
REGST3 LDAA   SP       ;SP TO DISPLAY
       BSR    REGST5   ;DISPLAY
       LDAA   SP+1
       BSR    REGST6
REGST4 INC    TEMP2    ;UPDATE COUNTER
REGST8 LDX    TEMP1    ;INCREMENT X
       DEX
       STX    TEMP1    ;SAVE X
       RTS
*
*SUBROUTINE TO MOVE TWO DIGITS IN A TO FIRST TWO
****LOCATIONS IN THE DISPLAY BUFFER (DISBUF)
*
REGST5 JSR    MDIS2    ;FORMAT
       LDX    #DISBUF
REGST7 STAA   0,X      ;FIRST DIGIT(OR THIRD)
       STAB   1,X      ;SECOND DIGHT
       RTS
*
**SUBROUTINE TO MOVE TWO DIGITS IN A TO SECOND TWO L
****LOCATIONS IN THE DISPLAY BUFFER (DISBUF)
*
REGST6 JSR    MDIS2    ;FORMAT
       LDX    #DISBUF+2  ;THIRD & FOURTH DIGITS
       BRA    REGST7
*
*
****SUBROUTINE TO PUNCH DATA TO CASSETTE TAPE****
* AUDIO CASSETTE WITH KC STANDARD
*
PNCH   LDAA   #%01010001  ;8 BIT CHR PAR 2 STOP
       STAA   ACIAS    ;DIVIDE BY 16 WITH RTS NOT HIG
       LDX    #$03FF
       BSR    PNLDR    ;PUNCH LEADER
PUND10 LDAB   ENDA+1   ;FORM END TEMP REG
       SUBB   BEGA+1
       LDAA   ENDA
       SBCA   BEGA
       BEQ    PUND25   ;DIFF LESS THAN 255
       LDAB   #$FF     ;YES, SET BLOCK=256
PUND25 LDAA   #'B'      ;PUNCH B
       BSR    OUTCH
       PSHB 
       TSX
       BSR    PUN
       PULA            ;GET BYTE COUNT
       INCA            ;ADJUST IT
       STAA   TEMP2
       LDX    #BEGA    ;PUNCH ADDR
       BSR    PUN
       BSR    PUN
       LDX    BEGA     ;PUNCH DATA
PUND30 BSR    PUN
       DEC    TEMP2    ;DONE YET?
       BNE    PUND30   ;NO
       STX    BEGA     ;SAVE XR VALUE
       LDX    #$0019
       BSR    PNLDR    ;PUNCH 25 ONES
       LDX    BEGA     ;RESTORE XR
       DEX
       CPX    ENDA
       BNE    PUND10   ;NO
       LDAA   #'G'      ;PUNCH G
*
***SUBROUTINE TO PUNCH DATA BYTE****
*
OUTCH  PSHB            ;SAVE B
OUTC1  LDAB   ACIAS    ;IS DATA READY YET?
       ASRB 
       ASRB 
       BCC    OUTC1    ;XMIT NOT READY YET
       STAA   ACIAD    ;OUTPUT ONE CHAR
       PULB            ;RESTORE B
       RTS
*
* SUB TO PUNCH ONE BYTE PTED TO BY XREG.
* ALSO INCREMENTS XREG BEFORE RETURN
*
PUN    LDAA   0,X      ;GET DATA
       BSR    OUTCH    ;PUNCH IT
       INX             ;UPDATE ADDR
       RTS
*
***PUNCH LEADER***
*
PNLDR  LDAA   #$FF     ;OUTPUT ALL ONES
       BSR    OUTCH    ;OUTPUT
       DEX             ;DECREMENT COUNTER
       BNE    PNLDR    ;IF NOT DONE THEN LOOP
       RTS
*
*
******SUBROUTINE TO LOAD DATA FROM CASSETTE TAPE****
*
*
LOAD   LDAA   #%00010000  ;DIVIDE BY ONE
       STAA   ACIAS
BILD   BSR    INCHR
       CMPA   #'B'      ;START OF BINARY?
       BEQ    RDBLCK   ;YES
       CMPA   #'G'      ;END OF FILE?
       BNE    BILD
       RTS             ;YES
RDBLCK BSR    INCHR    ;GET BYTE COUNT
       TAB             ;PUT IN B
       INCB            ;ADJUST IT
       BSR    INCHR    ;GET START ADDR HI
       STAA   BEGA
       BSR    INCHR    ;GET START ADDR LO
       STAA   BEGA+1
       LDX    BEGA     ;ADDR TO X REG
STBLCK BSR    INCHR    ;NOT DONE
       STAA   0,X      ;STRE IT
       INX             ;INCA ADDR
       DECB            ;DECB BYTE COUNT
       BNE    STBLCK   ;NOT DONE
       BRA    BILD
*
*****INPUT ONE CHR TO A REG******
*
INCHR  LDAA   ACIAS
       ASRA 
       BCC    INCHR    ;DATA READY?
       LDAA   ACIAD    ;INPUT CHAR
       RTS
*
*****SEVEN SEGMENT PATTERNS - USED BY OUTDS****
*               0   1   2   3   4   5   6   7
DIGTBL FCB    $40,$79,$24,$30,$19,$12,$02,$78

*               8   9   A   B   C   D   E   F
       FCB    $00,$18,$08,$03,$46,$21,$06,$0E

*               -   BLANK
       FCB    $BF,$7F
****KEY VALUE LOOKUP TABLE - USED BY KEYDC
*               0   1   2   3   4   5   6   7
KEYTBL FCB    $01,$02,$42,$82,$04,$44,$84,$08

*               8   9   A   B   C   D   E   F
       FCB    $48,$88,$C8,$C4,$C2,$C1,$81,$41

*               P   L   N   V   M   E   R   G
       FCB    $10,$50,$90,$D0,$20,$60,$A0,$E0

*
******KEYBOARD/DISPLAY REGISTER ASSIGNMENT
*
DISREG EQU    $8020    ;DISPLAY SEGMENTS REGISTER
DISCTR EQU    $8021    ;DISPLAY SEGMENTS CONTROL
SCNREG EQU    $8022    ;KEYBOARD/DISPLAY SCAN REG
SCNCTR EQU    $8023    ;KEYBOARD/DISPLAY SCAN CTR
ACIAS  EQU    $8008    ;ACIA CTRL OR STATUS REG
ACIAD  EQU    $8009    ;ACIA XMIT OR RCV REGS
*
****INTERRUPT VECTORS
*      ORG    $E3F8
       FDB    IO       ;IRQ INTERRUPT VECTOR
       FDB    SWIR     ;SOFTWARE INTERRUPT VECTOR
       FDB    NONMSK   ;NMI INTERRUPT VECTOR
       FDB    RESTAR   ;RESTART INTERRUPT VECTOR     
       PAGE
 *
******VARIABLE PARAMETERS******
*   SYSTEM RAM
*
*
* CAUTION: IF THE USER MODIFY'S THIS PROGRAM
* (GENERATES HIS OWN PROM) THE ORDER OF SOME
* OF THE FOLLOWING VARIABLES IS CRITICAL FOR
* CORRECT OPERATION
*
       ORG    $A000
* THE USER CAN STORE THE ADDRES OF HIS IRQ
* ROUTINE HERE.
IOV    RMB    2        ;IRQ INTERRUPT POINTER
BEGA   RMB    2        ;PUNCH BEGINNING ADDRESS
ENDA   RMB    2        ;PUNCH ENDING ADDRESS
NIO    RMB    2        ;NMI INTERRUPT POINTER
SP     RMB    2        ;TEMP STACK POINTER
TEMP1  RMB    2        ;SCRATCH
DISBUF RMB    8        ;DISPLAY BUFFER
DIGIN4 RMB    1        ;4 DIGITS ENTERED FLAG
DIGIN8 RMB    1        ;8 DIGITS ENTERED FLAG
MFLAG  RMB    1        ;MEMORY CHANGE MODE FLAG
RFLAG  RMB    1        ;REGISTER DISPLAY MODE FLAG
NFLAG  RMB    1        ;TRACE MODE FLAG
TEMP2  RMB    1        ;COUNTER IN REG DISPLAY, AUDIO
XKEYBF RMB    2        ;NEXT LOC IN DISPLAY BUFFER
SCNCNT RMB    1        ;KEYBOARD /DISPLAY SCAN COUNTE
VFLAG  RMB    1        ;CONTAINS THE NBR OF ACTIVE BR
BPADR  RMB    2        ;TEMP ADDR OF BP&XREG TEMP
XDSBUF RMB    2        ;XREG TEMP LOCATION
*
* BREAKPOINT AND OPCODE TABLE
*   EACH BRKPT REQUIRES 3 BYTES,
*   BYTES 1,2 ARE THE ADDRESS OF THE BRKPT
*   BYTE 3 IS THE REPLACED OP CODE
*   CHECK VFLAG TO SEE HOW MANY OF THE BRKPTS
*   ARE VALID
*
BPTAB  RMB    15       ;BREAKPOINT & OP CODE TABLE
       END