mikbug2.asm
crsjones_68Retro/6800-BUGS/MIKBUG2/mikbug2.asm
*
* CONVERTED TO AN ASSEMBLY FILE FROM A CRAPPY PDF BY
* MEMBERS OF THE MOTOROLA 6809 / 6309, 6800 ASSEMBLY
* LANGUAGE PROGRAMMING FACEBOOK GROUP
* BY CRAIG JONES,RAY BELLIS
*

       NAM    MIKBUG
       TTL    2.0 WITH AUDIO CASSETTE
*     REV  0
*     COPYRIGHT (C)  1977  BY MOTOROLA INC.
*
*     MIKBUG (TM) MOTOROLA
*
*     AUSTIN, TEXAS
*     MICROCOMPUTER CAPITAL OF THE WORLD!
*
*     L  LOAD
*     M  MEMORY CHANGE
*     P  PRINT/PUNCH DUMP
*     R  DISPLAY CONTENTS OF TARGET STACK
*          CC   B   A   X   P   S
*     S  1,SET SPEED FOR 10 CPS
*        3,SET SPEED FOR 30 CPS
*     B  PRINT OUT ALL BREAKPOINTS
*     C  CONTINUE EXECUTION FROM CURRENT LOCATION
*     N  NEXT INSTRUCTION
*     T  TRACE 'N' INSTRUCTIONS
*     G  GO TO LOCATION 'N'
*     D  DELETE ALL BREAKPOINTS
*     U  RESET BREAKPOINT WITH ADDRESS 'N'
*     V  SET A BREAKPOINT WITH ADDRESS 'N'
*     E  EXORTAPE CASSETTE INTERFACE
*
*      OPT    S,O,LLEN=80,CREF
ACIAS  EQU    $8008
ACIAD  EQU    $8009
SWI    EQU    $3F      SWI OP CODE
*
       ORG    $F800
BASORG EQU    *        BASE ORIGIN
*
*     I/O INTERRUPT SEQUENCE
*
IO     LDX    IOV
       JMP    0,X
*
*     NMI SEQUENCE
*
POWDWN LDX    NIO      GET NMI VECTOR
       JMP    0,X
*
*     SWI INTERRUPT SEQUENCE
*
SFEI   LDX    SWI1
       JMP    0,X
*
* JUMP TABLE TO ROUTINES PERFORMING MIKBUG FCTN'S
*
FCTABL EQU    *
       FCC    /B/      "B" - PRINT ALL BREAKS
       FDB    PNTBRK
       FCC    /C/      "C" - CONTINUE
       FDB    CONT
       FCC    /D/      "D" - DELETE ALL BREAKS
       FDB    DELBRK
       FCC    /G/      "G" - GO TO ENTERED ADDRESS
       FDB    GOTO
       FCC    /L/      "L" - LOAD
       FDB    LOAD
       FCC    /M/      "M" - MEMORY CHANGE
       FDB    CHANGE
       FCC    /N/      "N" - NEXT (TRACE 1 INSTR)
       FDB    NEXT
       FCC    /P/      "P" - PUNCH
       FDB    PUNCH
       FCC    /R/      "R" - PRINT STACK
       FDB    PSTAK1
       FCC    /S/      "S" - CHANGE SPEED FOR TTY
       FDB    SPD
       FCC    /T/      "T" - TRACE N INSTRUCTIONS
       FDB    TRACE
       FCC    /U/      "U" - RESET A BREAKPOINT
       FDB    RSTBRK
       FCC    /E/      "E" - EXORTAPE CASSETT INTERFACE
       FDB    EXORT
       FCC    /V/      "V" - SET A BREAKPOINT
       FDB    SETBRK
FCTBEN EQU    *
*
*      INITIALIZATION/RESET CODE
*
ADRSTR EQU    *
       FDB    STACK    INIT FOR "SP"
       FDB    SWI15    INIT FOR "SWI1"
       FDB    BRKINH   INIT FOR "SWI2"
*
       BRA    BRG      "BRA" INST IS REPLACED BY
       JMP    BRNOGO   COND BRA INST IN ROUT.
BRG    JMP    BRGO     WHICH DETERMINES IF
*                      BRA IS GO/NOGO
*
* BUILD ADDRESS
*
BADDR  BSR    BYTE     READ 2 FRAMES
       STAA   XHI
       BSR    BYTE
       STAA   XLOW
       LDX    XHI      (X) ADDRESS WE BUILT
       RTS
* INPUT BYTE (TWO FRAMES)
BYTE   BSR    INHEX    GET HEX CHAR
BYTE2  ASLA
       ASLA
       ASLA
       ASLA
       TAB
       BSR    INHEX
       ABA
       TAB
       ADDB   CKSM
       STAB   CKSM
       RTS
OUTHL  LSRA            OUT HEX LEFT BCD DIGIT
       LSRA
       LSRA
       LSRA
OUTHR  ANDA   #$F      OUT HEX RIGHT BCD DIGIT
       ADDA   #$30
       CMPA   #$39
       BLS    OUTCH
       ADDA   #$7
* OUTPUT ONE CHAR
OUTCH  JMP    OUTCH1
INCH   JMP    INCH1
* PRINT DATA POINTED AT BY X-REG
PDATA2 BSR    OUTCH
       INX
PDATA1 LDAA   0,X
       CMPA   #4
       BNE    PDATA2
       RTS             STOP ON EOT
*
* INPUT ADDRESS
*
GETADD BSR    PCRLF    PRINT  CR LF
       LDX    #MCL4
       BSR    PDATA1   ASK FOR BEGADDR
       BSR    BADDR    GET BEG ADDR
       STX    BEGA
       BSR    PCRLF    PRINT CR LF
       LDX    #MCL5
       BSR    PDATA1   ASK FOR END ADDR
       BSR    BADDR    GET END ADDRESS
       STX    ENDA
       RTS             *
* PRINT CR LF
*
PCRLF  STX    XHI      SAVE XR
       LDX    #MCL1
       BSR    PDATA1   PRINT CRLF
       LDX    XHI
       RTS

*
INHEX  BSR    INCH
INHEX2 SUBA   #$30
       BMI    C1       NOT HEX
       CMPA   #$09
       BLE    IN1HG
       CMPA   #$11
       BMI    C1       NOT HEX
       CMPA   #$16
       BGT    C1       NOT HEX
       SUBA   #7
IN1HG  RTS
*
OUT2H  LDAA   0,X      OUTPUT 2 HEX CHAR
OUT2HA BSR    OUTHL    OUT LEFT HEX CHAR
       LDAA   0,X      PICK UP BYTE AGAIN
       INX
       BRA    OUTHR    OUTPUT RIGHT HEX CHAR AND RTS
OUT4HS BSR    OUT2H    OUTPUT 4 HEX CHAR + SPACE
OUT2HS BSR    OUT2H    OUTPUT 2 HEX CHAR + SPACE
OUTS   LDAA   #$20     SPACE
       BRA    OUTCH    (BSR & RTS)
LOAD   EQU    *
       LDAA   #@21
       BSR    OUTCH    OUTPUT CHAR
*
* TURN READER RELAY ON
*
       LDAA   ACIAT    GET ACIA CONTROL REG FORMAT
       ORAA   #$40     SET RTS TO TURN RDR RELAY ON
       STAA   ACIAS    TURN IT ON
*
       INC    OUTSW    DO NOT ECHO TAPE
*
LOAD3  BSR    INCH
       BRA    LOAD4
ENTER  JMP    ENT1     MIKBUG 1 ENTRY POINT
LOAD4  EQU    *
       CMPA   #'S
       BNE    LOAD3    1ST CHAR NOT (S)
       BSR    INCH     READ CHAR
       CMPA   #'9
       BEQ    C1
       CMPA   #'1
       BNE    LOAD3    2ND CHAR NOT (1)
       CLR    CKSM     ZERO CHECKSUM
       JSR    BYTE     READ BYTE
       SUBA   #2
       STAA   BYTECT   BYTE COUNT
* BUILD ADDRESS
       JSR    BADDR
* STORE DATA
LOAD11 JSR    BYTE
       DEC    BYTECT
       BEQ    LOAD15   ZERO BYTE COUNT
       STAA   0,X      STORE DATA
       CMPA   0,X      CHECK DATA
       BNE    LOAD19   DATA NOT STORED
       INX
       BRA    LOAD11
*
* DOES CHECKSUM CHECK?
*
LOAD15 INCB
       BEQ    LOAD3
LOAD19 LDAA   #'?      PRINT QUESTION MARK
       BSR    OUTCH1
C1     JMP    CONTRL
*
* CHANGE MEMORY (M AAAA DD NN)
*
CHANGE JSR    BADDR    BUILD ADDRESS
       BSR    OUTS     OUTPUT SPACE
CHANG  LDX    XHI
       BSR    OUT2HS   PRINT DATA OLD
       DEX
CHA1   BSR    INCH1    INPUT CHAR
       CMPA   #$0A
       BEQ    LF       CHECK FOR LINE FEED
       CMPA   #$5E
       BEQ    UA       CHECK FOR ^
       JSR    INHEX2   S BSR BYTE
       JSR    BYTE2    GET NEW BYTE
       STAA   0,X      CHANGE MEMORY
       CMPA   0,X
       BNE    LOAD19   NO CHANGE
       BRA    CHA1
LF     INX             INC ADDR
       BRA    UA1
UA     LDAA   #$0A
       BSR    OUTCH1   OUTPUT LF
       DEX             DEC ADDR
UA1    STX    XHI      SAV DATA ADDR
       LDX    #MCL+1
       JSR    PDATA1   PRINT CR
       LDX    #XHI
       JSR    OUT4HS   OUTPUT DATA ADDR
       BRA    CHANG
*
OUTCH1 PSHB            SAVE BREG
OUTC1  LDAB   ACIAS
       ASRB
       ASRB
       BCC    OUTC1    XMIT NOT READY
       STAA   ACIAD    OUTPUT CHAR
       PULB
       RTS
*
* INPUT ONE CHAR TO AREG
INCH1  LDAA   ACIAS
       ASRA
       BCC    INCH1    RECEIVER NOT READY
       LDAA   ACIAD    INPUT CHAR
       ANDA   #$7F     RESET PARITY BIT
       CMPA   #$7F
       BEQ    INCH1    RUBOUT;DEL
       TST    OUTSW    SHOULD INPUT BE ECHOED?
       BEQ    OUTCH1   IF SO, OUTPUT THE CHAR
       RTS             ELSE,RETURN TO CALLER OF INCH1
*
* CONSTANT INITIALIZATION
* S = POINTER TO ROM BYTES TO BE COPIED TO RAM
* X = POINTER TO RAM BYTES TO BE INITIALIZED
*
START  EQU    *        ACTUAL CODE START
       LDS    #ADRSTR-1 START OF CONSTANT DATA
       LDX    #SP      START OF RAM AREA
*
INILP1 PULA            GET NEXT CONSTANT BYTE
       STAA   0,X      INIT NEXT RAM BYTE
       INX             UPDATE POINTER
       CPX    #BRANEN  END OF CONSTANT RAM AREA?
       BNE    INILP1   NO, CONTINUE INITIALIZATION
*
* INITIALIZATION TO 0
* X HOLDS INDEX OF 1ST BYTE TO BE SET TO 0
*
INILP2 CLR    0,X      CLEAR NEXT BYTE OF RAM
       INX             UPDATE INDEX
       CPX    #ENDIN0  ANY MORE BYTES TO INIT?
       BNE    INILP2   NO, CONTINUE CLEARING
*
* SET CC SO WHEN WE 'GO' TO USER PGM THE 
*   INTERUPT MASK IS SET
*
       LDAA   #$D0
       STAA   $A079    PUT IN STACK TO BE PULLED
*
* INITIALIZE ACIA
*
       LDAA   #3       MASTER RESET CODE
       STAA   ACIAS    RESET ACIA
*
INZ    LDAA   #%00010001 CHAR LEN=8; NO PARITY
*                          2 STOP BITS
*
INZ1   STAA   ACIAT    SAVE FOR CONTROL LOOP ACIA IN
*
       STAA   ACIAS    INZ ACIA
ENT1   LDS    SP
       JSR    PCRLF
       BRA    CONTB    SKIP TO INSURE MIKBUG : COMPAT.
INCH2  BRA    INCH1    MIKBUG 1.0 INPUT 1 CHARACTER
CONTB  LDX    #MCL2    PRINT HEADER
       JSR    PDATA1   PRINT DATA STRING
       LDX    #NMI     INIT PDN
       STX    NIO
*
* MAIN COMMAND/CONTROL LOOP
*
CONTRL EQU    *
*
* RESTORE STACK POINTER REGISTER
*
       LDS    SP       SP WAS INITIALIZED EARLIER
*
       LDAA   ACIAT    GET PROPER ACIA INIT BITS
*                      FOR USER'S TERMINAL
       STAA   ACIAS    INZ ACIA
*
       CLR    OUTSW    MAKE SURE INPUT IS ECHOED
*
       LDX    #MCLOFF  TERMINAL INIT STRING
       JSR    PDATA1   PRINT DATA STRING
*
       BSR    INCH1    READ COMMAND CHARACTER
       TAB             SAVE CHARACTER IN B
       BRA    CNTA     SKIP OVER MIKBUG 1.0 VECTOR
OUT2   BRA    OUTCH1   MIKBUG 1.0 ; OUTPUT 1 CHAR ROUTINE
CNTA   JSR    OUTS     PRINT SPACE AFTER COMMAND
*
* B REGISTER HOLDS CHARACTER INPUT BY USER
* USE JUMP TABLE TO GO TO APPROPRIATE ROUTINE.
*
       LDX    #FCTABL  X:= ADDRESS OF JUMP TABLE
NXTCHR CMPB   0,X      DOES INPUT CHAR MATCH?
       BEQ    GOODCH   YES, GOTO APROPRIATE ROUTINE
       INX             ELSE, UPDATE INDEX INTO TABLE
       INX
       INX
       CPX    #FCTBEN  END OF TABLE REACHED?
       BNE    NXTCHR   NO, TRY NEXT CHAR
       BRA    CONTRL   NO MATCH, REPROMPT USER
*
*
GOODCH LDX    1,X      GET ADDRESS FROM J.T.
       JMP    0,X      GOTO APPROPRIATE ROUTINE
*
*
* NMI ENTRY
*
NMI    STS    SP       SAVE STACK
       JSR    PCRLF
       LDAA   #'B      PRINT B
       BSR    OUT2
       JSR    OUTS
       LDAA   #2       REMOVE BREAKPOINTS
       BSR    BRKSUB
       BRA    PSTAK1
*
* SET SPEED FOR USER TTY
*
SPD    BSR    INCH2    INPUT CHAR
       CMPA   #'1
       BEQ    INZ
       LDAA   #$15
       BRA    INZ1     SET 2 STOP BITS
*
*
BADDRJ JMP    BADDR    GO BUILD ADDRESS
*
*
* RESET ALL BREAKPOINTS
*
DELBRK LDAA   #1       RESET BREAKS FLAG
BSRBRK BSR    BRKSUB   BREAK HANDLING SUBR.
       BRA    CNTRL2   RETURN TO COMMAND LEVEL
*
* RESET 1 BREAKPOINT
*
RSTBRK BSR    BADDRJ   PUTS USER ENTERED ADDRESS
*                            INTO XHI,XLO
       CLRA            RESET 1 BREAK FLAG
       BRA    BSRBRK   GO RESET 1
*
* PRINT OUT ALL NON-ZERO BREAK ADDRESSES
*
PNTBRK JSR    PCRLF    DO CR/LF
       LDAA   #2       PRINT BREAK ADDRESSES FLAGS
       BRA    BSRBRK   GO PRINT
*
* SET ONE BREAK
*
SETBRK BSR    BADDRJ   GET USER ENTERED ADDRESS (XHI,XLO)
       LDAA   #4       SET ONE BREAK FLAG
       BSR    BRKSUB   GO SET IT
       BRA    PNTBRK   PRINT ALL BREAKPOINTS
*
* GO TO REQUESTED
*
GOTO   BSR    BADDRJ   GO GET ADDRESS FROM USER
*                      XHI,XLOW HOLD ADDRESS
       LDAA   #$FF     FLAG FOR PUTTING IN BREAKS
       BSR    BRKSUB   GO PUT IN BREAKS
       TSX
       LDAA   XHI      SAVE PCH ON STACK
       STAA   5,X
       LDAA   XLOW     PUSH PCL
       STAA   6,X
       RTI             GO TO USER PRG
*
* SINGLE INSTRUCTION TRACE REQUESTED
*
NEXT   LDX    #1       # INSTRUCTIONS TO TRACE
TRACE2 CLR    BRKTRC   CLEAR FLAG INDICATING TRACE
*                      IS DUE TO BREAK
TRACE3 STX    NTRACE   SAVE # INST'S TO TRACE
*                            IS DUE TO BREAK
       LDX    SP       X : = STACK POINTER
       LDX    6,X      X : = ADDRESS OF INSTR TO BE EX
       STX    TRCADR   SAVE IN TRACE ADDRESS STORE
       LDAA   0,X      GET INSTRUCTION TO BE TRACED
       STAA   TRCINS   SAVE IN TRACE INSTRUCTION STORE
       JMP    CONTRC   GO TO CONTINUE TRACE PART OF
*
* MULTIPLE INSTRUCTION TRACE
*
TRACE  BSR    BADDRJ   GET # OF INSTRUCTIONS TO TRACE
       BRA    TRACE2   GO TRACE'M
*
* CONTINUE EXECUTION
*
CONT   INC    BRKTRC   TRACE 1 TO RESTORE SWI'S
       LDX    #1       ONE TRACE ONLY
       BRA    TRACE3
*
*
*  R COMMAND
*
* PRINT STACK CONTENTS
*
PSTAK1 JSR    PCRLF    PRINT CR LF
       LDX    #MCL3    PRINT HEADER
       JSR    PDATA1
PSTAK  BSR    PRINT    PRINT STACK
CNTRL2 JMP    CONTRL   RETURN TO COMMAND LEVEL
**********
*
* BRKSUB
*
*
* THIS ROUTINE DOES A NUMBER OF OPERATIONS HAVING
* TO DO WITH BREAKPOINTS.
*
* THE A REGISTER DETERMINES FUNCTION PERFORMED:
*
* A = -1 => BREAKS ARE PUT INTO USER'S CODE
* A =  0 => THE BREAKPOINT WHOSE ADDRESS IS IN
*           XHI, XLO IS PURGED;
*           ALL BREAKPOINTS ARE TEMPORARILY REMOVED
* A =  1 => ALL BREAKPOINTS ARE PURGED
* A =  2 => ALL BREAKPOINTS ARE PRINTED OUT
*           ALL BREAKPOINTS ARE TEMPORARILY REMOVED
* A =  3 => ALL BREAKPOINTS ARE TEMPORARILY REMOVED
* A =  4 => THE BREAK ADDRESS IN XHI, XLO IS
*           PUT INTO THE FIRST ZERO BREAKPOINT
*           POSITION; ALL BREAKS ARE TEMPORARILY REMOVED
*
**********
*
BRKSUB EQU    *
       STS    SSAVE    SAVE S SO WE CAN USE
       STAA   ASAVE    A HOLDS THE FUNCTION #
*
       LDX    #BRKADR  INIT X FOR LOOP THROUGH BREAKS
*
* START OF LOOP THROUGH BREAK ADDRESSES
*
BRKLP  LDAA   ASAVE    GET FUNCTION #
       LDS    0,X      S:=NEXT ADDRESS IN BRRKPT LIST
       BEQ    LN       IF 0, THEN NOT A VALID BREAK
*
       TST    BRKSIN   ARE BREAKS IN USER'S CODE?
       BEQ    NOBRIN   BRANCH, IF NOT
*
* BREAKS ARE IN USER'S CODE
*
       TSTA            SHOULD BREAKS BE IN?
       BMI    BKDONE   YES, RETURN TO CALLER
*
* BREAKS ARE TO BE TAKEN OUT OF USER'S
* CODE TEMPORARILY
*
BRK2   LDAA   2*NBRBPT,X GET INSTR. BELONG-
*                            ING IN USER CODE
       PSHA            PUT IT THERE
*
* OTHER LOOP ACTIONS TO BE PERFORMED EACH TIME THROUGH
* LOOP WHEN BREAK ADDRESS NOT EQUAL TO 0.
*
BKCON1 LDAA   ASAVE    WHAT FUNCTION IS TO BE DONE
       BEQ    FNDRPL   SEE IF BREAKPOINT NEEDS TO
*                            BE REPLACED
       CMPA   #1       IS BREAK ADDRESS TO BE RESET?
       BEQ    CLRBRK   YES, SET BRKADR TO 0
*
       CMPA   #2       IS BRK ADDR TO BE PRINTED?
       BEQ    PRNTBK   YES, GO PRINT ADDRESS
*
* UPDATE LOOP INDEX AND LOOP IF APPROPRIATE
*
BKCON2 INX             MAKE X POINT TO
       INX             NEXT BREAK ADDRESS
BKCON3 CPX    #BRKINS  ANY MORE BREAKS?
       BNE    BRKLP    YES,LOOP
*
* WRAP-UP PROCESSING AND EXIT
*
       CLRA            A = BREAKS IN FLAG
       TST    ASAVE    IS FUNCTION = -1?
       BPL    BKPUT    NO, SO BRKSIN = 0
       INCA            FCTN = -1 => BRKSIN:=1
BKPUT  STAA   BRKSIN   STORE APPROPRIATE FLAG
*
* RESTORE S-REG AND RETURN TO CALLER
*
BKDONE LDS    SSAVE    RESTORE USER S-REG
       RTS             RETURN
*
*
* MISCELLANEOUS ROUTINES FOR BRKSUB
*
* BREAKPOINT ADDRESS = 0 - IF FUNCTION = 4 THEN
* PUT BREAKPOINT ADDRESS IN CURRENT POSITION
* A HOLDS THE FUNCTION #, X HOLDS BREAKPOINT INDEX
*
LN     CMPA   #4       IS FUNCTION = 4
       BNE    BKCON2   IF NOT, THEN CONTINUE LOOP
*
       LDS    XHI      GET NEW BREAK ADDRESS
       STS    0,X      PUT IN CURRENT POSITION
*
       DEC    ASAVE    DO NOT PLACE ADDRESS MORE
*                      THAN ONCE-CONT TO
*                      TAKE OUT BREAKPOINTS
       BRA    BKCON2   CONTINUE LOOP
*
* BREAKS ARE NOT IN AND ADDRESS IS NON-ZERO.
* IF FUNCTION = -1 THEN SWI'S ARE TO BE PUT IN.
* A HOLDS FUNCTION NUMBER, S HOLDS ADDRESS
*
NOBRIN TSTA            IS FUNCTION = -1
       BPL    BKCON1   NO, CONTINUE
*
       DES             MAKE ADDRESS POINT TO 1 LESS
       PULA            GET USER INSTRUCTION
       STAA   2*NBRBPT,X SAVE
       LDAA   #SWI     GET SWI OP CODE
       PSHA            REPLACE USER INSTRUCTION
       BRA    BKCON2   CONTINUE LOOP
*
* FUNCTION=0 BRK ADDR NOT = 0, USER'S INSTR
* IS IN (NOT SWI).
* IF ADDRESS = XHI,XLO THEN SET ADDRESS = 0
FNDRPL LDAA   0,X      GET TOP BYTE OF ADDRESS
       CMPA   XHI      DO TOP BYTES COMPARE
       BNE    BKCON2   NO,CONTINUE LOOP
       LDAB   1,X      GET LOW BYTE OF ADDR
       CMPB   XLOW     SAME FOR LOW BYTES
       BNE    BKCON2
*
CLRBRK CLR    0,X      CLEAR OUT BREAK
       CLR    1,X      ADDRESS FIELD
       BRA    BKCON2   CONTINUE LOOP
*
*
OT2HS  JMP    OUT2HS
OT4HS  JMP    OUT4HS
*
*
* PRINT OUT BREAK ADDRESS
* FUNCTION = 2, BREAK ADDRESS NOT = 0, X = ADDRESS IN
*
PRNTBK LDS    SSAVE
       BSR    OT4HS    OUTPUT ADDRESS AND SPACE
       BRA    BKCON3   OUT4HS INCREMENTS X,
*                      SO BYPAS 2 INX'S
*
* PRINT CONTENTS OF STACK
*
PRINT  JSR    PCRLF    PRINT CR LF
       LDX    SP       PRINT OUT STACK
       INX
       BSR    OT2HS    CONDITION CODES
       BSR    OT2HS    ACC-B
       BSR    OT2HS    ACC-A
       BSR    OT4HS    X-REG
       BSR    OT4HS    P-COUNTER
       LDX    #SP
       BSR    OT4HS    STACK POINTER
       RTS


*     PUNCH DUMP
*     PUNCH FROM BEGINNING ADDRESS (BEGA) THRU ENDING
*     ADDRESS (ENDA)
*

MTAPE1 FCB    $D,$A,0,0,0,0,'S,'1,4 PUNCH FORMAT

PUNCH  EQU    *

       JSR    GETADD   GET ADDRESS
       LDAA   #$12     TURN TTY PUNCH ON
       JSR    OUTCH    OUT CHAR
*
*      PUNCH LEADER - 25 NULLS
*
       LDAB   #25      B HOLDS # NULLS TO PUNCH
PNULL  CLRA            A=0 (NULL CHAR)
       JSR    OUTCH    GO OUTPUT NULL
       DECB            DECREMENT COUNTER
       BNE    PNULL    IF NOT DONE, THEN LOOP
*
       LDX    BEGA
       STX    TW       TEMP BEGINNING ADDRESS
PUN11  LDAA   ENDA+1
       SUBA   TW+1
       LDAB   ENDA
       SBCB   TW
       BNE    PUN22
       CMPA   #16
       BCS    PUN23
PUN22  LDAA   #15
PUN23  ADDA   #4
       STAA   MCONT    FRAME COUNT THIS RECORD
       SUBA   #3
       STAA   TEMP     BYTE COUNT THIS RECORD
*       PUNCH C/R,L/F,NULLS,S,1
       LDX    #MTAPE1
       JSR    PDATA1
       CLRB            ZERO CHECKSUM
*     PUNCH FRAME COUNT
       LDX    #MCONT
       BSR    PUNT2    PUNCH 2 HEX CHAR
*     PUNCH ADDRESS
       LDX    #TW
       BSR    PUNT2
       BSR    PUNT2
*     PUNCH DATA
       LDX    TW
PUN32  BSR    PUNT2    PUNCH ONE BYTE (2 FRAMES)
       DEC    TEMP     DEC BYTE COUNT
       BNE    PUN32
       STX    TW
       COMB
       PSHB
       TSX
       BSR    PUNT2    PUNCH CHECKSUM
       PULB            RESTORE STACK
       LDX    TW
       DEX
       CPX    ENDA
       BNE    PUN11
       JSR    PCRLF
       LDX    #MEOF
       JSR    PDATA1   OUTPUT EOF
       BRA    CTRL     BRANCH TO CONTRL

*     PUNCH 2 HEX CHAR, UPDATE CHECKSUM
PUNT2  ADDB   0,X      UPDATE CHECKSUM
       JMP    OUT2H    OUTPUT TWO HEX CHARS AND RTS
*
* SWI-1 SOFTWARE INTERRUPT LEVEL 1 PROCESSING
*
SWI15  EQU    *
       STS    SP       SAVE USER'S SP
*
       LDAA   #3
       JSR    BRKSUB   GO TAKE OUT ALL THE BREAKS
*
* DECREMENT P-COUNTER
*
       TSX             X:=STACK POINTER - 1
       TST    6,X      IF LOWER BYTE = 0 => BORROW
       BNE    SWI151   BRANCH IF BORROW NOT REQ'D
       DEC    5,X      DECREMENT UPPER BYTE
SWI151 DEC    6,X      DECREMENT LOWER BYTE
*
* TEST FOR ADDRESS TRACE OR BREAK
*
       LDX    5,X      X:=P COUNTER
       CPX    TRCADR   IS SWI FOR TRACE?
       BEQ    TRCINH   YES, GO TO TRACE INT HANDLER
*
       LDAA   0,X      GET INSTRUCTION CAUSING SWI
       CMPA   #SWI     WAS IT REPLACED BY CALL TO BREAK
       BNE    BRKINH   YES, SO MUST BE A BREAK
*
* USER SWI-TRANSFER THROUGH LEVEL 2 SWI
*
       TSX             X:=STACK POINTER
       INC    6,X      UPDATE LOW BYTE OF P-COUNTER
       BNE    INCNOV   BRANCH IF NO CARRY
       INC    5,X      UPDATE HIGH BYTE IF NECESSARY
INCNOV LDX    SWI2     X:=POINTER TO LEVEL 2 SWI HANDLER
       JMP    0,X      GO TO LEVEL 2 HANDLER
*
*
*
*
* BREAK INTERRUPT HANDLER
*
BRKINH EQU    *
       JSR    PRINT    STOP AND SHOW REGS TO USER
CTRL   JMP    CONTRL   RETURN TO CONTROL LOOP
*
* TRACE INTERRUPT HANDLER
* P-COUNTER  HAS BEEN DECREMENTED TO POINT AT SWI
* TRCINS HOLDS OP CODE REPLACED BY SWI
* X HOLD ADDRESS WHERE TRACE SWI IS
*
TRCINH LDAA   TRCINS   GET OP CODE OF TRACED INSTR
       STAA   0,X      RESTORE TO USER'S CODE
*
       TST    BRKTRC   IS PROCESSING TO BE
*                           IMMEDIATELY CONTINUED?
       BEQ    NBKTRC   BRANCH IF NOT
*
* PROCESSING IS TO 'CONTINUE'
*
       CLR    BRKTRC   RESET CONTINUE FLAG
       LDAA   #$FF     FLAG TO SET BREAKS IN CODE
       JSR    BRKSUB   PUT BREAKS IN
       CLR    TRCADR   NO MORE TRACE, SO CLEAR ADDRESS
       CLR    TRCADR+1
       RTI             CONTINUE
*
* TRACE IS DUE TO N OR T TRACE COMMANDS
*
NBKTRC JSR    PRINT    PRINT STACK
       LDX    NTRACE   GET # INSTRUCTIONS TO TRACE
       DEX             DECREMENT COUNT
       STX    NTRACE   AND RESTORE
       BEQ    CTRL     BRANCH IF ALL TRACES DONE
*
* TRACE NOT DONE - TRACE NEXT INSTRUCTION
*
CONTRC LDAA   TRCINS   GET CURRENT INSTRUCTION
       STAA   BRINS    SAVE IN CASE IT'S A BRANCH
       BSR    OPCBYT   GO GET # BYTES/TYPE
       TSTA            CHECK FOR BRANCH
       BPL    CKOBRA   CHECK FOR OTHER THAN BRANCH
*
* RELATIVE BRANCH TYPE INSTRUCTION
* DETERMINE WHERE TO PUT SWI
* S- HOLDS POINTER TO USER STACK AFTER SWI
       PULA            GET CONDITION CODE
       DES             UPDATE STACK POINTER AFTER PULL
       ORAA   #%00010000 MAKE INT'S INHIBITED
       TAP             RESTORE USER'S C. CODE REG
       JMP    BRINS    GO SEE HOW RELATIVE BRANCH
*                            FARES
*
* BRANCH WAS NOGO - PUT SWI AT NEXT INSTRUCTION
*
BRNOGO LDAA   #2       A = # BYTES AFTER CURRENT INSTR
       BRA    CKOBRA   GO PUT SWI APPROPRIATELY
*
* BRANCH WAS GO, PUT SWI AT ADDRESS BEING
* JUMPED TO
*
BRGO   LDX    TRCADR   X : = TRACE ADDRESS
       LDAA   1,X      GET BRANCH OFFSET
       INX             OFFSET IS RELATIVE TO
       INX             INSTR FOLLOWING BRANCH
       BMI    BRGODC   BRANCH IF OFFSET NEGATIVE
BRG1   BSR    INCX     INCREMENT X BY AMOUNT IN
*                          A REG
BRG2   STX    TRCADR   SAVE ADDRESS OF NEXT
*                            INSTR TO STOP ON
       LDAA   0,X      GET INSTRUCTION TO BE REPLACED
       STAA   TRCINS   SAVE
       LDAA   #SWI     GET SWI OP CODE
       STAA   0,X      REPLACE INSTR WITH SWI
       LDS    SP       GET ORIGINAL STACK POINTER
       RTI             TRACE ANOTHER INSTR
*
* X NEEDS TO BE DECREMENTED (OFFSET NEGATIVE)
*
BRGODC DEX             DECREMENT ADDRESS
       INCA            INCREMENT COUNTER
       BNE    BRGODC   IF COUNTER NOT 0, BRANCH
       BRA    BRG2     IF DONE, GO RETURN TO USER PROG
*
* SUBROUTINE TO INCREMENT X BY CONTENTS OF A
*
INCX   TSTA            IS A = 0?
       BEQ    INCXR    IF SO, INC DONE
INXLP  INX             ELSE INCREMENT X
       DECA            DECREMENT COUNT
       BNE    INXLP    IF COUNT NOT YET 0, LOOP
INCXR  RTS             RETURN FROM THIS SUBROUTINE
*
* INSTRUCTION TO BE TRACED IS NOT A BRANCH
*
CKOBRA LDX    TRCADR   X : = TRACE ADDRESS
       LDAB   0,X      GET INSTR TO BE TRACED
       CMPB   #$6E     IS IT A JUMP, INDEXED?
       BEQ    JMPIDX   YES, GO SIMULATE JUMP IDXED
       CMPB   #$7E     JUMP, EXTENDED?
       BEQ    JMPEXT
       CMPB   #$AD     JSR,  INDEXED?
       BEQ    JMPIDX   (JUMP IDXED IS SAME AS
*                       TRANSFER OF CONTROL)
       CMPB   #$BD     JSR, EXTENDED?
       BEQ    JMPEXT
       CMPB   #$3B     RTI?
       BEQ    RTISIM
       CMPB   #$39     RTS?
       BEQ    RTSSIM
       CMPB   #$8D     BSR?
       BEQ    BRGO     (BRANCH PROCESSING)
*
* NOT A BRANCH, JUMP. RTI, RTS
* A REGISTER HOLDS # BYTES IN INSTRUCTION
*
       BRA    BRG1     PUT IN NEW SWI AND
*                            TRACE NEXT INSTRUCTION
*
* JUMP, JSR INDEXED SIMULATION
*
JMPIDX LDAA   1,X      A : = ADDRESS OFFSET
       TSX
       LDX    3,X      GET TARGETS X REG
       BRA    BRG1     UPDATE X, TRACE NEXT INSTR
*
* JUMP,  JSR EXTENDED
*
JMPEXT LDX    1,X      GET ADDRESS TO BE JUMPED TO
       BRA    BRG2     GO TRACE NEXT INSTR.
*
* RTI ENCOUNTERED
*
RTISIM TSX
       LDX    12,X     GET P-COUNTER FROM STACK
       BRA    BRG2     GO TRACE NEXT INSTR.
*
* RTS ENCOUNTERED
*
RTSSIM TSX
       LDX    7,X      GET RETURN P-REG FROM STACK
       BRA    BRG2     GO TRACE NEXT INSTR
*************************
*
* OPBCYT
*
* THIS ROUTINE DETERMINES THE # OF BYTES IN AN INSTRUCTION
* GIVEN ITS OP CODE.
*
* INPUT: A HOLDS THE OP CODE
*
* OUTPUT: X HOLDS THE INDEX OF TABLE ELEMENT
* B NOT RESTORED
* A HOLDS # BYTES IN INSTRUCTION
* EXCEPT FOR BRANCHES IN WHICH CASE IS NEGATIVE
*
************************
*
OPCBYT EQU    *
       TAB             B:= OP CODE
       LSRA
       LSRA
       LSRA            PUT 4 UPPER BITS OF OP CODE IN
       LSRA            LOWER 4 BITS OF A
*
       LDX    #OPBTTB  X:= ADDRESS OF TABLE
       BSR    INCX     INCREMENT X TO POINT TO CORRECT
*
       LDAA    0,X     GET TABLE ENTRY
       BNE    OPBTRT   IF NOT 0 THEN NO FURTHER
*                            PROCESSING NEEDED
*
* IF TOP 4 BITS = 8 OR C, THEN THERE ARE TWO CLASSES
* OF INSTRUCTIONS: 2 BYTE INSTRUCTIONS AND
* CE, 8C AND 8E WHICH ARE 3 BYTE INSTRUCTIONS
*
       LDAA   #2       # BYTES IN MOST OF 8# INSTRUCTIONS
       CMPB   #$8C     3 BYTE INSTRUCTION?
       BEQ    OPBT3    YES, UPDATE A
       CMPB   #$CE     3 BYTE INSTR?
       BEQ    OPBT3    YES, UPDATE A
       CMPB   #$8E     3 BYTE INSTRUCTION?
       BNE    OPBTRT   NO, RETURN
*
OPBT3  INCA            # BYTES IN INSTRUCTION:=3
*
OPBTRT RTS             RETURN TO CALLER
*
* OP CODE TO NUMBER OF BYTES CONVERSION TABLE
*
*           # BYTES  TOP 4 BITS OF OPCODE
*           -------  --------------------
*
OPBTTB EQU    *
       FCB    1        0
       FCB    1        1
       FCB    2+%10000000 2 ( MINUS=> BRANCHES )
       FCB    1        3
       FCB    1        4
       FCB    1        5
       FCB    2        6
       FCB    3        7
       FCB    0        8 # BYTES=2 EXCEPT 8C,8E
       FCB    2        9
       FCB    2        A
       FCB    3        B
       FCB    0        C # BYTES = 2 EXCEPT CE
       FCB    2        D
       FCB    2        E
       FCB    3        F
*
* CONSTANT DATA
*
MEOF   FCC    /S9030000FC/
       FCB    4
MCLOFF FCB    $13      READER OFF
MCL    FCB    $A,$D,$14,0,0,0,0,'*,4 LF,CR,PUNCH
MCL1   FCB    $D,$A,0,0,0,0,4 CR LF
MCL2   FCC    /MIKBUG 2.0/
       FCB    4
MCL3   FCC    /CC B  A   X    P    S/
       FCB    4
MCL4   FCC    /BEG ADDR ?/
       FCB    4
MCL5   FCC    /END ADDR ?/
       FCB    4
*
*
* MAXIMAL SOFTWARE IMPLEMENTATION OF THE
*    RITTER-ZETTNER STANDARDS
*
* COPYRIGHT (C) 1977 MOTOROLA INC. AND T. F. RITTER
*
*      COMMANDS FOR EXORTAPE
* C L D S :
* C - CHECK TAPE
* L - LOAD FROM TAPE TO MEMORY
* D - DUMP FROM MEMORY TO TAPE
* S - SET BAUD RATE
*
* SPEED :
* ENTER 04 08 12 16 20
*
* FILE ID :
* ENTER FOUR HEX CHARACTERS
*
* STARTSTOP PAGES:
* ENTER STARTING PAGE, TWO HEX CHARACTERS
* ENTER STOPPAGE, TWO HEX CHARACTERS
*
*
*
*         FILE SPECIFICATIONS
* ALC := UNDEFINED BIT; AUTOMATIC LEVEL CONTROL
* POST := UNDEFINED BIT; MISSING PULSE PROTECT
* START SEQUENCE := 89AFH
* CRC := CYCLIC REDUNDENCY CHECK BIT; X16+X15+X2+X0
* HEADERECORD := (32 ALC) (START SEQUENCE) (08H)
*    (16 FILE ID) (8 # OF GOOD PAGES) (8 POST)
* TRAILERECORD := (16 ALC) (START SEQUENCE)
*    (20H) (8 # OF BAD PAGES) (8 POST)
* DUMPAGERECORD := (16 ALC) (START SEQUENCE) (10H)
*    (8 PAGE #) (2048 DATA) (16 CRC) (8 POST)
* CHARECORD := (32 ALC) (START SEQUENCE) (40H)
*    (8 LENGTH) (1-256 CHARS) (16 CRC) (8 POST)
* OTHERECORD := NEITHER HEADER NOR TRAILER RECORD
* SUBFILE := (HEADERECORD) (0-N OTHERECORDS)
* FILE := (1-N SUBFILES) (TRAILERECORD)
*
*
*         DATA SPECIFICATIONS
* SYNCHRONOUS DATA; NO START OR STOP BITS
* MSB SENT FIRST (CORRECT ORDER ON SCOPE)
* VOICE MESSAGES MAY BE PRESENT BETWEEN FILES
*
*
*         AUDIO MODULATION SPECIFICATIONS
* DOUBLE-FREQUENCY RETURN-TO-BIAS MODULATION
* LOGIC ONE = FIVE ELEMENT PATTERN: 0 1 0 1 0
* LOGIC ZERO = FIVE ELEMENT PATTERN 0 1 0 0 0
* LOCAL EL CHEAPO (REALISTIC CTR-34) DOES 1200 BAUD
*    (DATA RATE EQUALS 1650 BAUD 2-STOP ASYNC)
* 0 ERROS IN 2.6 MILLION BITS RECOVERED
* FROM MEMOREX MRX2
*
*
*         AUDIO HARDWARE SPECIFICATIONS
* OUTPUT FROM PIA B2 THROUGH 11:1 VOLTAGE DIVIDER
*    (4.7K, 470) INTO MIKE JACK
* INPUT FROM SPKR JACK, THROUGH DC-RESTORING
*    CIRCUIT AND SCHMIDTT TRIGGER
*    (MC14583 PREFERRED) INTO PIA B0
*  RECOVERED PULSE PHASE MATTERS, SO USE SWITCH TO
*     SELECT PHASE -- BOTH AVAILABLE FROM MC14583
*
*BAUD RATES:        400     800    1200    1600    2000
*EQUIV ASYNC:       550    1100    1650    2200    2750
*ELEMENT (USEC):    500     250     167     125     100
*TOTCNT:             35      1B      12      0D      0B    
*PATDEL:             50      26      18      11      0D
*
*SYSTEM STORAGE
TTYCON EQU    $8008    ACIA CONTROL
TTY    EQU    $8009    TTY ACIA
TP     EQU    $8004    TAPE PORT
TACON  EQU    $8005    TAPE CONTROL
ESC    EQU    $1B      ESCAPE CHAR
*
*
*
*
*
EOT    EQU    4
*
*
*   MESSAGES
*
*
MSG1   FCC    /EXORTAPE 4.3/
       FCB    EOT
MSG2   FCC    /C L D S: /
       FCB    EOT
MSG3   FCC    /FILE ID: /
       FCB    EOT
MSG4   FCC    /STARTSTOP PAGES: /
       FCB    EOT
MSG5   FCC    /SPEED: /
       FCB    EOT
*
* PRINT LINE WITH A PRECEEDING CR/LF
*   X POINT TO STRING, STRING MUST
*   TERMINATE WITH A $4 CHARACTER.
*
PDATA  JSR    PCRLF
PDAT1P JMP    PDATA1
*
* TINS PROVIDES TAPE "IN'S" FOR MIKBUG KEYBOARD
*     CONTROL OF TAPE SYSTEM
*
*
* ENTER HERE
*
*
EXORT  BSR    EXOR     CALL TAPE ROUTINE VIA A BSR
       JMP    ENT1     RETURN TO EXEC
*
*
*
*
*
* TIN'S ERROR ROUTINE
*
ERR    LDAA   #'?      PRINT '?'
       JSR    OUTCH
* FALL INTO TINS
*
*
*
EXOR   EQU    *
TINS   LDX    #$1B26   STANDARD SPEED
       STX    TOTCNT
SOFT   EQU    *
TINSS  LDX    #MSG1    SEND PGM TITLE
TI1    BSR    PDATA
TI2A   LDX    #MSG5    SEND SPEED QUESTION
       BSR    PDATA
       JSR    BYTE     INPUT 2 HEX CHARACTERS
       CMPA   #$20     2000 BAUD?
       BNE    TIN1
       LDX    #$0B0D
       BRA    TIN5
TIN1   CMPA   #$16     1600 BAUD?
       BNE    TIN2
       LDX    #$0D11
       BRA    TIN5
TIN2   CMPA   #$12     1200 BAUD?
       BNE    TIN3
       LDX    #$1218
       BRA    TIN5
TIN3   CMPA   #$04     0400 BAUD?
       BNE    TIN4
       LDX    #$3550
       BRA    TIN5
TIN4   CMPA   #$08
       BNE    ERR      NOT A VALID SPEED
       LDX    #$1B26   800 BAUD IS NORMAL






TIN5   STX    TOTCNT
TIN8   LDX    #MSG2    SEND MODE QUESTION
TI2    BSR    PDATA    C=CHECK; L=LOAD
       JSR    INCH     D=DUMP; S= SPEED
       CMPA   #'S
       BEQ    TI2A
*
*
TIN6   STAA   T1       STORE MODE CHAR
       LDX    #MSG3    SEND FILE ID PROMPT
TI4    BSR    PDATA
       JSR    BADDR    GET FILE ID
       STX    FIDH
       JSR    PCRLF
       LDAA   T1
       CMPA   #'D      DUMP MODE?
       BNE    TIN7
       LDX    #MSG4    SEND START/STOP PROMPT
       BSR    PDAT1P
       JSR    BADDR
       STX    STARTP
       JSR    PCRLF
       JMP    MASTER
TIN7   CMPA   #'C      CHECK MODE?
       BEQ    CHECK
       CMPA   #'L      CHECK FOR LOAD
       BEQ    LOAD2
       JMP    ERR
*
* FALL INTO LOAD
LOADV  BRA    LOAD2
CHECK  LDAA   #$01     INSERT CHECK COMMAND
       BRA    C12
LOAD2  LDAA   #$E7     INSERT LOAD COMMAND
C12    STAA   CL       (STORE B INDEXED)
       CLR    CLL      NOP/ZERO DISPLACEMENT
       LDAA   #$39     INSERT RTS
       STAA   CLLL
* FALL INTO GETLOAD
*
* GETLOAD SEARCHES FOR THE DESIRED FILE,
*     THEN LOADS IT INTO RAM
*
*     RAM:  Q, R, S, H, L (SCRATCH)
*           TOTCNT, FIDH, FIDL (PERM)
*
GETLOA JSR    LSETUP   SET UP PIA
       BSR    GETFIL   SEARCH FOR CORRECT FILE
       BEQ    GET4     OUT IFF ESCAPED
GET2   BSR    STARTV   GET THE NEXT RECORD-TYPE
       BEQ    GET4     OUT IF ESCAPE
       CMPB   #$20     TRAILERECORD?
       BEQ    GET1
       CMPB   #$10     DUMPAGERECORD?
       BNE    GET2
       BSR    DUMPR    BRING IT IN!
       BEQ    GET4     OUT IFF ESCAPE
       BRA    GET2
GET1   TST    V        CHECK PAGE COUNT
       BEQ    GET4
       BMI    GET3
       LDAA   #'-      '-' FOR MISSING PAGE(S)
       BRA    GET5
GET3   LDAA   #'+      '+' FOR EXTRA PAGE(S)
GET5   JSR    OUTCH    PRINT IT!
GET4   RTS             RETURN
*
* DUMPR BRINGS IN A DUMPAGE RECORD
*
*     RAM:  H, L (SCRATCH)
*     REGS: ACCA, ACCB (SCRATCH); IX (PERM)
*     EXIT: FALLS INTO CRCK
*
DUMPR  BSR    LDV      GET PAGE NUMBER
       STAB   H        )
       CLR    L        ) LOAD IX!
       LDX    H        )
DUM1   BSR    LDV
       BEQ    G2       OUT IFF ESCAPE
       JSR    CL       CHECK, OR LOAD
       INX             STORAGE PTR
       INC    L        BYTE COUNT
       BNE    DUM1
       DEC    V        PAGE COUNT
* FALL INTO CRCK
*
* CRCK SHECKS THE CRC AND PRINT A CHAR
*
*     RAM:  Q, R, S, TOTCNT (FROM LOADBYTE)
*     REGS:  ACCA (SCRATCH, ACCB (FROM LOADBYTE)
*
CRCK   BSR    LDV      ) INPUT CRC CHARS
       BSR    LDV      )
       LDAA   R        CHECK CRC REGISTERS
       ORAA   S
       BNE    CRCK1
       LDAA   #'G      PRINT G FOR GOOD CRC
       BRA    CRCK2
CRCK1  LDAA   #'B      PRINT B FOR BAD CRC
CRCK2  JMP    TTYO1    PRINT IT!
LDV    JMP    LOADBV   GET A TAPE BYTE IN ACCB
STARTV BRA    STARTF
*
* GETFILE LOOKS FOR:
*     1)  A START SEQUENCE
*     2)  A HEADERECORD TYPE
*     3)  A FILE ID MATCH WITH FIDH, FIDL
* AND RETURNS WHEN FOUND, OR ESCAPED
*
*     REGS:  ACCA, ACCB (SCRATCH ONLY)
*
G1     LDAA   #'X      INDICATE WRONG FILE FOUND
       BSR    CRCK2    SEND CHAR TO TTY
GETFIL BSR    STARTF
       BEQ    G2       OUT IFF ESCAPE
       CMPB   #$08     HEADERECORD-TYPE?
       BNE    GETFIL   BRANCH IF NOT
       BSR    LDV      GET BYTE IN ACCB
       CMPB   FIDH     GOOD FILE ID(H)?
       BNE    G1
       BSR    LDV
       CMPB   FIDL     GOOD FILE ID(L)?
       BNE    G1
       LDAA   #'H      INDICATE HEADER FOUND
       BSR    CRCK2
       BSR    LDV
       STAB   V        STORE PAGE COUNT
G2     RTS
*
* STARTFIND LOOKS FOR THE 16-BIT START SEQUENCE 89AF
*     RETURNS WITH THE NEXT BYTE, THE RECORD TYPE,
*     IN Q AND ACCB.
*
*     RAM:  Q, R, S, TOTCNT (PERM), H (SCRATCH)
*     REGS:  ACCA, ACCB (SCRATCH ONLY)
*     EXIT:  FALLS INTO LOADBYTE, WHICH
*            FALLS INTO LOADBIT, WHICH
*            FALLS INTO CRC
*     ESCAPE:  ESC IN COMMAND PORT GETS OUT
*                (TEST DONE IN CRC)
*
STARTF CLR    H        ACCUMULATES 16 BITS
       CLR    Q
STA1   ASL    Q        SHIFT THE 16-BIT REGISTER
       ROL    H
       BSR    LOADB1
       BEQ    G2       OUT IFF ESCAPED
       LDAA   H
       LDAB   Q
       CMPA   #$89     START SEQUENCE
       BNE    STA1
       CMPB   #$AF
       BNE    STA1
STA2   CLR    R        CLEAR THE CRC REGISTER
       CLR    S
* FALL INTO LOADBYTE TO RETURN A BYTE
*
* LOADBYTE RECOVERS OF DATA IN Q AND ACCB, AND DOES CRC
*
*     RAM:  Q, R, S, TOTCNT (PERM)
*     REGS:  ACCA, ACCB (SCRATCH ONLY)
*     EXIT:  FALLS INTO LOADBIT, WHICH
*            FALLS INTO CRC
*
LOADBY LDAB   #$02     SET STOP
       STAB   Q
LOAD1  BSR    LOADB1
       BEQ    G2       OUT IFF ESCAPE
       ASL    Q        STOP INTO CARRY?
       BCC    LOAD1    BRANCH IF NO
* FALL INTO LOADBIT FOR LAST BIT
*
* LOADBIT RECOVERS ONE BIT OF DATA IN Q AND ACCB,
*     AND DOES CRC IN R AND S
*
*     RAM:  Q, R, S, TOTCNT (PERM)
*     REGS:  ACCA, ACCB (SCRATCH ONLY)
*     EXIT:  BRANCHES OR FALLS INTO CRC ROUTINE
*            DATA BIT GOES INTO Q LSB
*
LOADB1 CLRB
LOADB6 DECB
       BEQ    LOADB5
       BSR    TAIN1V   GET TAPE DATA IN CARRY
       BCS    LOADB6   WAIT FOR LOW
LOADB2 DECB
       BEQ    LOADB5
       BSR    TAIN1V   WAIT FOR HIGH
       BCC    LOADB2   )  (FRONT OF SYNC EL)
       LDAB   TOTCNT   3.5 ELS DELAY
LOADB3 DECB
       BEQ    LOADB5
       BSR    TAIN1V   )  WAIT FOR LOW
       BCS    LOADB3   )  (END OF SYNC EL)
LOADB4 DECB
       BEQ    LOADB5   DONE YET?
       BSR    TAIN1V
       BCC    LOADB4
       INC    Q        STORE A '1' BIT
LOADB5 LDAA   Q        GET DATA FOR CRC
* FALL INTO CRC1
*
*  CRC ENTERS A BIT INTO CRC REGISTERS R AND S
*     USES CRC POLYNOMIAL:  X16 + X15 + X2 + X0
*
*     ENTRY:  ACCA HOLDS NEW BIT
*     RAM:  R, S (PERM)
*     REGS:  ACCA, ACCB (SCRATCH)
*     EXIT:  ACCB = Q, Z = 1 IFF ESC
*
CRC1   RORA            LSB INTO CARRY
       RORA            CARRY INTO MSB
CRC2   ANDA   #$80     MASK MSB (DATA BIT)
       EORA   R        ENTER DATA BIT
       LDAB   S
       ASLB            SHIFT 16 BITS LEFT
       ROLA
       BCC    CRC3     IF B16 HIGH. . .
       EORA   #$80     ENTER CRC POLYNOMIAL
       EORB   #$05
CRC3   STAA   R
       STAB   S
       LDAB   Q
       JSR    TTYIN1   CHECK FOR ESCAPE
       ANDA   #$7F     MASK PARITY
       CMPA   #ESC
       RTS
TAIN1V JMP    TAIN1
*
* BYTEOUT SENDS BYTE IN ACCA TO TAPE
*
*     RAM:  R, S (CHANGED IN CRC)
*     REGS:  ACCA, ACCB (DESTROYED)
*     EXIT:  ACCA = 0, ACCB UNDEFINED
*
*     ACCA = DATA BYTE (SHIFTED)
*     ACCB = RECORDING PATTERN (ONE BIT)
*
BYTEOU PSHA            SAVE THE DATA BYTE
       BSR    CRC2     ) DO THE CRC FIRST
       PULA            RECOVER THE DATA BYTE
       SEC             SET STOP
       ROLA            DATA BIT INTO CARRY
       BRA    BY2
BY1    PULA            RECOVER FROM DONE TEST
       PSHA            SAVE SHIFTING BYTE
       BSR    CRC2
       PULA            RECOVER SHIFTING BYTE
       ASLA            DATA BIT INTO CARRY
BY2    LDAB   #$0A     RECORDING PATTERN
BY3    JSR    TAOU1    SEND ACCB TO TAPE
       PSHB            SAVE PATTERN
       LDAB   PATDEL   ELEMENT DELAY
BY4    DECB
       BNE    BY4      BRANCH IF ELEMENT NOT DONE
       PULB            RECOVER PATTERN
       ROLB            NEXT ELEMENT (DATA FROM CARRY)
       BCC    BY3      BRANCH IF PATTERN NOT DONE
       PSHA            SAVE DATA BYTE BEFORE TEST
       ASLA            TEST ACCA
       BNE    BY1      BRANCH IF BYTE NOT DONE
BY5    INS             RESTORE STACK
       RTS
*
* PREAMBLE SENDS OUT ALC BITS, AND THE START SEQUENCE,
*     THEN INITS THE CRC REGISTERS
*
*     RAM:  R, S (CHANGED)
*     REGS:  ACCA, ACCB (DESTROYED)
*     EXIT:  ACCA = 0, ACCB UNDEFINED
*
PREAMB BSR    BYTOV1   ALC BITS
       BSR    BYTOV1
       LDAA   #$89     START SEQUENCE (H)
       BSR    BYTOV1
       LDAA   #$AF     START SEQUENCE (L)
       BSR    BYTOV1
       CLR    R        ) CLEAR THE CRC REGISTERS
       CLR    S        )
       RTS
*
* HEADERECORD SENDS ALC BITS, THE START SEQUENCE,
*     HEADRECORD-TYPE, FILE ID, AND THE NUMBER OF
*     PAGES TO BE DUMPED
*
*     RAM:  FIDH, FIDL (UNMODIFIED)
*           R, S (CHANGED)
*     REGS:  ACCA, ACCB (DESTROYED)
*     EXIT:  ACCA = 0, ACCB UNDEFINED
*
HEADER BSR    BYTOV1   ALC BITS
       BSR    BYTOV1
       BSR    PREAMB   START A RECORD
       LDAA   #$08     HEADERTYPE
       BSR    BYTOV1
       LDAA   FIDH     FILE ID(H)
       BSR    BYTOV1
       LDAA   FIDL     FILE ID(L)
       BSR    BYTOV1
       LDAA   STOPPG   STOPAGE
       SUBA   STARTP   STARTPAGE
       INCA
       BSR    BYTOV1   SEND # PAGES
BYTOV1 JMP    BYTEOV   EXTRA BITS
*
* TRAILERECORD SENDS A TRAILERECORD TO TAPE
*
*     RAM:  R, S (PERM)
*     REGS:  ACCA, ABBC (DESTROYED)
*
TRAILR  BSR   PREAMB   START A RECORD
        LDAA  #$20     TRAILERECORD TYPE
        BSR   BYTOV1
        BRA   BYTOV1   EXTRA BITS
*
* DUMPAGERECORD SENDS THE START SEQUENCE, DUMPAGE-TYPE,
*     PAGE NUMBER, 2048 BITS DATA, AND THE CRC CHARACTERS
*
*     RAM:  H, R, S (PERM); L (SCRATCH)
*     REGS:  ACCA, ACCB (DESTROYED), NEW IX
*     EXIT:  ACCA = 0
*
DUMPAG BSR    PREAMB   START A RECORD
       LDAA   #$10     DUMPAGE TYPE
       BSR    BYTOV1
       LDAA   H        SEND PAGE NUMBER
       BSR    BYTOV1
       CLR    L        DO ENTIRE PAGE
       LDX    H        POINT AT THE DATA
DUMP1  LDAA   0,X
       BSR    BYTOV1   SEND DATA
       INX
       INC    L        BYTE CTR
       BNE    DUMP1
       BSR    SENCRC
       LDAA   #'D      PRINT D FOR EACH PAGE DUMPED
       BSR    TTYO1
       CLRA
       BRA    BYTOV1   EXTRA BITS
*
* SENCRC SENDS THE CRC REGISTERS TO TAPE
*
*
*     RAM:  R, S (FREED AFTER THIS); L (SCRATCH)
*     REGS:  ACCA, ACCB (DESTROYED)
*
SENCRC LDAA   S
       STAA   L        TEMPORARY CRC(L) STORAGE
       LDAA   R
       BSR    BYTOV1   SEND CRC(H)
       LDAA   L
       BRA    BYTOV1   SEND CRC(L)
*
* MASTERDUMP SENDS A COMPLETE FILE TO TAPE:
*     HEADERECORE, DUMPAGERECORDS (1-256), TRAILERECORD
*
*     RAM: STARTP, STOPPG (UNMODIFIED)
*          H, L (TEMP)
*     REGS: NEW EVERYTHING
*
MASTER BSR    DSETUP   SETUP DUMP PORT
       BSR    HEADER   SEND HEADERECORD
       LDAA   STARTP   GET STARTPAGE
       STAA   H        PRESENT PAGE
       DEC    H
MAST1  INC    H
       BSR    DUMPAG
       LDAA   TTY
       ANDA   #$7F
       CMPA   #ESC
       BEQ    MAST3
       LDAB   STOPPG   GET STOPAGE
       CMPB   H        PRESENT PAGE
       BNE    MAST1    BRANCH IF NOT DONE
MAST3  BSR    TRAILR   SEND TRAILERECORD
MAST2  RTS
SETUP  CLR    TACON    INTO DATA DIRECTION REG.
       LDAA   #$04     B2 AN OUTPUT, REST INPUTS
       STAA   TP       (ONLY B0 USED FOR INPUT)
       STAA   TACON    BACK TO DATA REGISTER
       RTS
*
*  VECTORS- IN OTHER VERSIONS OF THIS TAPE
*   INTERFACE THESE VECTORS WILL BE IMPLEMENTED
*   IN RAM TO ALLOW THE USER ACCESS TO
*   THE TAPE SYSTEM.
*
TAIN1  JMP    TAIN2    TAPE IN PORT VECTOR
TAOU1  JMP    TAOU2    TAPE OUT PORT VECTOR
LOADBV JMP    LOADBY   TAPE BYTE IN VECTOR
BYTEOV JMP    BYTEOU   TAPE BYTE OUT VECTOR
TTYIN1 JMP    TTYIN2   CONTROL IN PORT VECTOR
TTYO1  JMP    TTYO2    CONTROL OUT PORT VECTOR
LSETUP JMP    SETUP    TAPE OUT PIA INIT
DSETUP JMP    SETUP    TAPE IN PAI INIT
*
*
TAIN2  LDAA   TP       ACCA FROM TAPE
       RORA            DATA BIT IN CARRY
       RTS
TTYIN2 LDAA   TTY      ACCA FROM ACIA
       RTS
TTYO2  STAA   TTY      SEND ACCA TO ACIA
       RTS
TAOU2  STAB   TP       ACCB TO TAPE
       RTS
*
******* COPYRIGHT (C) 1977 MOTOROLA INC - AUSTIN TEXAS
*
*
*********************
*
* UNSIGNED MULTIPLY -----
*
*   THIS ROUTINE MULTIPLIES THE UNSIGNED NUMBER IN THE
*   A REGISTER WITH THE UNSIGNED NUMBER IN THE B
*   REGISTER AND PUTS THE ANSWERS IN THE CONCATENATED
*   A:B WHERE A IS THE MSB. THE ROUTINE IS
*   RE-ENTRANT AND POSITION INDEPENDENT AS WELL
*   AS BEING ROMABLE. THE X REGISTER IS DESTROYED
*   BY THE ROUTINE.
*
*   DURING EXECUTION THE STACK CONTAINS:
*   0,X  =  LOOP COUNTER
*   1,X  =  MULTIPLIER (B REG ON ENTRY)
*
*   THE ALGORITHM USED MAY NOT APPEAR THE FASTEST
*   ON PAPER BECAUSE IT ALWAYS REQUIRES 8 PASSES
*   THE THE LOOP BUT BECAUSE OF THE FACT ALL
*   CALCULATIONS CAN BE DONE IN THE REGISTERS IT
*   IS FASTER EXCEPT FOR WHEN THE MULTIPLICAND
*   IS VERY SMALL (<10). THE METHOD IS A SHIFT AND
*   ADD TECHNIQUE THAT BEGINGS WITH THE MS BIT
*   AND WORKS DOWN TO THE LS BIT.
*
*   EXECUTION TIME: (29 + ZEROES*19 + ONES*26) CYCLES
*     WHERE ZEROES AND ONES ARE THE 0'S AND 1'S IN
*     THE A-REG ON CALL.
*
*     AVERAGE EXECUTION TIME: 209 CYCLES
*
*********************
*
MUL    PSHB            PUT MULTIPLIER ON THE STACK
       LDAB   #8       PUT COUNTER ON STACK
       PSHB
       TSX             SET X TO POINT TO STACK
       CLRB            CLEAR PLACE TO START ANSWER
ML1    ASLB            SHIFT ANS 1 LEFT AND INTO A
       ROLA            SHIFT WHATS LEFT OF THE MULTIPLIER
       BCC    ML2      BRANCH IF NO ADD NEEDED
       ADDB   1,X      ADD MULTIPLIER AT THIS POSITION
       ADCA   #0       ADD CARRY TO A IF ANY
ML2    DEC    0,X      DONE?
       BNE    ML1      NOPE
       INS             YES,CLEAN UP THE STACK
       INS
       RTS
*
***********************
*
* SIGNED MULTIPLY -----
*
*     THIS ROUTINE MULTIPLIES THE TWO SIGNED NUMBERS IN
*     THE A AND B REGISTERS AND PUTS THE SIGNED
*     16 BIT ANSWER IN THE CONCATENATED A:B WHERE
*     THE A REGISTER IS THE MSB. THIS ROUTINE DESTROYS
*     THE CALLER'S X-REGISTER.
*
*     DURING EXECUTION THE STACK CONTAINS:
*     0,X  =  FLAG
*
*     THE ROUTINE IS PURE,RE-ENTRANT AND POSITION INDEPENDENT.
*
*     THE METHOD USE EVALUATES EACH ARGUMENT AND IF IT
*     IS NEGATIVE IT IS 2'S COMPLEMENTED AND THE FLAG IS
*     INCREMENTED. IF AFTER EVALUATING BOTH ARGUMENTS THE
*     FLAG IS EVEN (0 OR 2) THEN THE ANSWER WILL BE POSITIVE,
*     ELSE,THE ANSWER WILL NEED TO BE 2'S COMPLEMENTED.
*     UNSIGNED MULTIPLE ROUTINE IS USED TO MULTIPLY THE
*     CORRECTED REGISTERS
*
*    AVERAGE EXECUTIONS TIMES:
*     A-REG  B-REG
*      +      +           268 AVERAGE
*      +      -           283 AVERAGE
*      -      +           283 AVERAGE
*      -      -           286 AVERAGE
*
*
*************************
*
SMUL   DES             CARVE OUT A PLACE ON THE STACK F...
       TSX             GET POINTER TO THAT PLACE
       CLR    0,X      CLEAR FLAG
       TSTA            CHECK MULTIPLIER
       BPL    SML1     POSITIVE, NO COMP. NEEDED
       NEGA            2'S COMP. ARGUMENT
       INC    0,X      INCR FLAG
SML1   TSTB            TEST OTHER ARG
       BPL    SML2     NO COMP NEEDED
       NEGB
       INC    0,X      INCR FLAG
SML2   BSR    MUL      GO DO UNSIGNED MULTIPLY
       TSX             GET BACK PTR TO FLAG
       ROR    0,X      SEE IF FLAG IS EVEN OR ODD
       BCC    SML3     EVEN ANSWER IS OKAY 'CAUSE ITS F...
       NEGA            DBL PRECISION 2'S COMP
       NEGB
       SBCA   #0
SML3   INS             CLEANUP STACK
       RTS             RETURN TO CALLER
*
*********************
*
* POSTIVE DIVIDE -----
*
*   THIS ROUTINE DIVIDES THE 16 BIT POSITIVE DIVIDEND
*   IN THE A:B REGISTERS (A IS THE MSB) BY AN 8
*   BIT POSITIVE  DIVISOR POINTED TO BY THE X-REGISTER.
*   THE QUOTIENT IS IN B ON EXIT AND THE REMAINDER
*   IS IN THE A-REGISTER. THE X-REGISTER IS
*   DESTROYED.
*   IF DIVISION BY ZERO WAS ATTEMPTED OR THE
*   QUOTIENT WILL NOT FIT IN 8 BITS THE OVERFLOW
*   BIT IS SET ON EXIT. ALSO V IS SET IF EITHER
*   THE DIVIDEND OR THE DIVISOR IS NEGATIVE ON CALL.
*   OTHERWISE V IS CLEARED.
*
*
*   THE ROUTING IS PURE,RE-ENTRANT AND POSITION INDEPENDENT.
*
*   DURING EXECUTION THE STACK CONTAINS
*   0,X  =  LOOP COUNTER
*   1,X  =  DIVISOR
*   2,X  =  DIVIDEND MSB (ONLY USED FOR TEMP STORE)
*
*   THE METHOD USED IS NON RESTORING DIVIDE WHERE THE
*   DIVIDEND AND DIVISOR AND KNOWN TO BE POSITIVE. THIS
*   METHOD PROVED FASTEST SINCE IT CAN BE CARRIED OUT
*   ESSENTIALLY IN THE ACCUMULATORS. THE ALGORITHM TRIES
*   TO GET THE REMAINDER AS NEAR ZERO AS POSSIBLE
*   AND SOMETIMES ADDS THE DIVISOR AND SOMETIMES
*   SUBTRACTS IT DEPENDING ON WHICH SIDE OF ZERO THE
*   PARTIAL REMAINDER RESIDES AT ANY TIME. FOR MORE
*   INFO READ: 'AN ALGORITHM FOR NON RESTORING DIVISION'
*   S. SANYAL ; 'COMPUTER DESIGN' / MAY 1997.
*
*   EXECUTION TIME AVERAGE (NO OVERFLOWS): 289 CYCLES
*     THIS TIME IS RELATIVELY INDEPENDENT OF THE
*     CALLING VALUES.
*
*
*********************
*
DIV    PSHA            SAVE DIVIDEND MSB A SECOND
       LDAA   0,X      FETCH THE DIVISOR
       BMI    DIVOV2   NEGATIVE DIVISOR IS A NO-NO
       PSHA            PUSH IT
       LDAA   #8       PUSH LOOP CTR
       PSHA
       TSX             POINT X TO STACK
       LDAA   2,X      RESTORE ORIGINAL DIVIDEND MSB
       CMPA   1,X      WILL QUOTIENT OVERFLOW? (ALS D!
       BCC    DIVOVF   YES,GO SET V AND EXIT
DLOOP  ASLB            SHIFT DIVIDEND-ANSWER LEFT
       ROLA
       BCC    DL2      IS DIVIDEND MS BIT SET?
       ADDA   1,X      YES,ADD DIVISOR TO MSB
       BRA    DL3
DL2    SUBA   1,X      NO,SUB DIVISOR FROM MSB
       INCB            SET BIT IN RESULT
DL3    DEC    0,X      DONE?
       BNE    DLOOP    NO
       SEC             SHIFT A 1 IN LS BIT OF QUOTIENT
       ROLB            CASE THATS OKAY, CORRECT LATTER
       TSTA            IS REMAINDER NEGATIVE?
       BPL    DL4      NO,EVERYTHING'S OKAY
       DECB            RESET QUOTIENT LS BIT
       ADDA   1,X      ADD DIVISOR  TO GET + REMAINDER
       CLV             INSURE V IS CLEARED
DL4    INS             CLEAN UP THE STACK
       INS
       INS
       RTS             RETURN
*
DIVOVF INS             CLEAN UP STACK
       INS
DIVOV2 INS
       SEV             SET THE OVERFLOW FLAG
       RTS
*
* INTERRUPT VECTORS
*
       ORG    BASORG+$7F8
       FDB    IO
       FDB    SFEI
       FDB    POWDWN
       FDB    START
*
*
* RAM - LOCATIONS DEVOTED TO VARIABLE INFORMATION
*
*
       ORG    $A000    START OF RAM .
NBRBPT EQU    8        # OF BREAKPOINTS SUPPORTED
*
* THE FOLLOWING ARE INITIALIZED AT START
*
IOV    RMB    2        I/O INTERRUPT POINTER
BEGA   RMB    2        BEGIN ADDRESS PRINT/PUNCH
ENDA   RMB    2        END ADDRESS PRINT/PUNCH
NIO    RMB    2        NMI INTERRUPT POINTER
SP     RMB    2        USER STACK POINTER
SWI1   RMB    2        LEVEL 1 SWI VECTOR
SWI2   RMB    2        LEVEL 2 SWI VECTOR
BRINS  RMB    8        STORAGE FOR CONDITIONAL BRANCH
*                            ROUTINE
BRANEN EQU    *        END OF BRANCH ROUTINE + 1
*
* THE FOLLOWING ARE INITIALIZED TO ZERO AT START
*
*
OUTSW  RMB    1        OUTPUT SWITCH
*                       (ZERO => ECHO INPUT)
TRCADR RMB    2        TRACE ADDRESS
TRCINS RMB    1        OP CODE REPLACED BY SWI
NTRACE RMB    2        NO. OF INSTRUCTIONS TO TRACE
*
BRKADR RMB    NBRBPT*2 BREAKPOINT ADDRESS TABLE
BRKINS RMB    NBRBPT*2 OP CODES FOR BREAK REPLACEMENT
*                            (UPPER BYTE OF EACH
*                             PAIR USED ONLY)
CKSM   EQU    *        CHECKSUM
ASAVE  EQU    *        A REG SAVE
TEMP   EQU    *        CHAR COUNT(INADD)
       RMB    1
*
*
BYTECT EQU    *        BYTE COUNT
MCONT  EQU    *        TMP
       RMB    1
*
*
XHI    RMB    1        X REG HIGH (TEMP)
XLOW   RMB    1        X REG LOW
*
*
SSAVE  EQU    *        S REG SAVE
TW     EQU    *        TEMP DOUBLE BYTE
       RMB    2
*
*
BRKSIN RMB    1        1=>BREAKS ARE IN USER PROGRAM
*
BRKTRC RMB    1	       1=>P-COUNTER IS AT BREAKPOINT
*                      AND USER WANTS TO CONTINUE-
*                      ONE TRACE WILL BE DONE AND
*                      BREAKPOINT RESTORED
ENDIN0 EQU    $A080    END OF VAR'S INTZ'D to 0
*
ACIAT  RMB    1        SAVE ACIS CONTROL REG FOR
*                      CONTROL LOOP INITIALIZE
*  EXORTAPE RAM
*AUXILIARY REGISTER STORAGE
FIDH   RMB    1
FIDL   RMB    1
STARTP RMB    1
STOPPG RMB    1
TOTCNT RMB    1        WINDOW WIDTH
PATDEL RMB    1        PATTERN-ELEMENT LENGTH
CL     RMB    1        CHECK/LOAD SUB
CLL    RMB    1
CLLL   RMB    1        RTS
*TAPE TEMPORARIES
H      RMB    1        LOAD IX, ETC.
L      RMB    1
Q      RMB    1        Q HOLDS LAST BYTE RECOVERED
R      RMB    1        R,S IS CRC REGISTER
S      RMB    1
V      RMB    1        PAGE COUNT
T1     EQU    CL
*
* REST OF 128 RAM IS USED FOR STACK
*
       RMB    36
STACK  RMB    1        START OF STACK AREA
