;
;
;
;       11/12/81
;
;       edited 6/8/82 by W. DuBois
;
;
;
;
;
;
;
;
;MACSBUG  IDNT  1,32 KDM MACSBUG (03/25/81)
;  SEQUENTIAL FILE FORMAT
;  DATE: 10/29/81 WPF
;******************************************************************
;                                                                *
;       THESE MACROS ARE USED TO FORCE THE STRUCTURED RESIDENT  *
;       ASSEMBLER TO GENERATE THE SAME CODE THAT THE CROSS        *
;       ASSEMBLER PRODUCED. THE OBJECT BEING TO GET THE SOURCE  *
;       IN A CONDITION THAT IT GENERATES EXACTLY WHAT WAS RELEASED  *
;       AS MACSBUG 1.3.                                         *
;       NOTE: UPON RELEASING ANY NEW VERSIONS, THE OPTIMIZATION  *
;       CAN INSTANTLY BE "RE-AQUIRED" BY A SIMPLE CHANGE TO THESE       *
;       MACROS...CHANGE ADDA TO ADD, AND SUBA TO SUB.           *
;                                                                *
;       ALSO NOTE THAT EACH MODIFICATION TO THE SOURCE FOR      *
;       PURPOSES OF COMPATABILITY ARE MARKED BY THE CHARS.      *OPT*  *
;       (FUTURE ASSEMBLIES CAN BE OPTIMIZED BY REMOVING THESE   *
;       CHANGES AND MODIFYING THE TWO MACROS).
;******************************************************************
         PAGE
;**********************************************************************
; C O P Y R I G H T E D 1 9 8 1 B Y     M O T O R O L A ,       I N C . *
;**********************************************************************
;**********************************************************************
;       MACSBUG 1.32 CORRECTS THE FOLLOWING:                            *
;                                                                       *
;       When the BREAK key was pressed at baud rates less than  *
;       9600 and greater than 150, the firmware would enter an  *
;       infinite loop printing :*:*:*:*:*:*:* etc.                      *
;       The time spent in an existing delay loop, (INITACIA), was       *
;       increased to prevent the problem.                               *
;                                                                       *
;       NOTE: This modification was made with a minimum amount    *
;               of object code changes to allow patches to MACSbug 1.31 *
;               firmware.                                                *
;                                                                       *
  PAGE
ROM     EQU $20000     ;START OF ROM (USED AS OFFSET)
;                                                       6/8/82 START
;ACIA1   EQU $3FF01      ;TERMINAL
;ACIA2   EQU $3FF21      ;HOST ACIA ADDRESS
;                                                       6/8/82 END
;
;  THE FOLLOWING NOT CURRENTLY USED - JLH
;
;  DS.L 1       ;RESTART STACK
;  DS.L 1       ;RESTART VECTOR
;  DS.L 1       ;BUSS ERROR
;  DS.L 1       ;ILL ADDRESS
;  DS.L 1       ;ILL INSTRUCTION
;  DS.L 1       ;DIVIDE BY ZERO
;  DS.L 1       ;CHECK TRAP
;  DS.L 1       ;TRAP V
;  DS.L 1       ;PRIVLIDGE VIOLATION
;  DS.L 1       ;TRACE 
;  DS.L 1       ;1010 LINE EMULATION
;  DS.L 1       ;1010 LINE EMULATION
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;-NOT USED
;  DS.L 1       ;
;  DS.L 1       ;
;  DS.L 1       ;
;  DS.L 1       ;
;  DS.L 1       ;
;  DS.L 1       ;
;  DS.L 1       ;
;  DS.L 1       ;ABORT BUTTON
;  DS.L 1       ;TRAP  0
;  DS.L 1       ;TRAP  1
;  DS.L 1       ;TRAP  2
;  DS.L 1       ;TRAP  3
;  DS.L 1       ;TRAP  4
;  DS.L 1       ;TRAP  5
;  DS.L 1       ;TRAP  6
;  DS.L 1       ;TRAP  7
;  DS.L 1       ;TRAP  8
;  DS.L 1       ;TRAP  9
;  DS.L 1       ;TRAP 10
;  DS.L 1       ;TRAP 11
;  DS.L 1       ;TRAP 12
;  DS.L 1       ;TRAP 13
;  DS.L 1       ;TRAP 14
;  DS.L 1       ;TRAP 15
         PAGE
;*********************************************************************
;       NOTE THE OFFSET DIRECTIVE IS BEING...
;       "USED TO DEFINE A TABLE OF OFFSETS VIA THE DEFINE STORAGE (DS)
;       DIRECTIVE WITHOUT PASSING THESE STORAGE DEFINITIONS ON TO THE   *
;        LINKAGE EDITOR, IN EFFECT CREATING (A) DUMMY SECTION..."       *
;       (SEE THE "RESIDENT STRUCTURED ASSEMBLER REF MANUAL... 3.2.4").  *
;**********************************************************************
REGPC   EQU $400        ;USERS PROGRAM COUNTER
REGSR   EQU $404        ;USERS CONDITION CODES
REGS    EQU $408        ;4BYTES*3SECTIONS*8REG(OR MEM)
REGA7   EQU REGS+60     ;WHERE A7 REG IS
REGUS   EQU $448        ;USER STACK
OFFSET  EQU $44C        ;ASSUMED OFFSET
FORMAT  EQU $450        ;TRACE DISPLAY FORMATS
ADALL   EQU $474        ;SPECIAL FORMAT FLAGS
WINDOWS  EQU $478       ;WINDOW PARAMETERS
LOOPR1  EQU $4B8        ;LOW RANGE FOR LOOP CMD
LOOPR2  EQU $4BC        ;HIGH RANGE
BPADD   EQU $4C0        ;BREAKPOINT ADDRESSES
BPTILL  EQU $4E0        ;TEMPORARY BREAKPOINT
BPCNT   EQU $4E4        ;BREAKPOINT COUNTS
BPDATA  EQU $508        ;HOLD USER WORDS REPLACED BY TRAP IN SET BP
SAVETRAP EQU $51A       ;HOLDS USER'S TRAP7 VECTOR (WE USE FOR BP)
NULLPADS EQU $51E       ;CHARACTER NULL PADS
CRPADS  EQU $520        ;CARRIAGE RETURN NULL PADS
SBIT    EQU $522        ;STOP BITS (ACIA PROGRAM)
OUTTO   EQU $524        ;HOLDS ADDRESS OF OUTPUT ROUTINE
INFROM  EQU $528        ;HOLDS ADDRESS OF INPUT ROUTINE
ALTACIA1 EQU $52C       ;ALTERNATE ACIA PORT#1
ALTACIA2 EQU $530       ;ALTERNATE ACIA PORT#2
INPORT1  EQU $534       ;INPUT ROUTINE ADDRESS
OUTPORT1 EQU $538       ;ADDRESS FOR OUPUT ROUTINE
INPORT2  EQU $53C       ;ADDRESS FOR INPUT ROUTINE
OUTPORT2 EQU $540       ;FOR OUTPURT ROUTINE
INPORT3  EQU $544       ;THIS MIGHT BE FOR TAPE
OUTPORT3 EQU $548       ;THIS MIGHT BE FOR PRINTER
TRACECNT EQU $54C       ;TRACE COUNTER
TRACEON  EQU $550       ;FLAG FOR TRACE ON
RUN     EQU $552        ;1=SAVE USER REGISTERS 0=NOT
BPSTATUS EQU $554       ;1=PB ARE IN  0=ARE OUT OF MEMORY
SCREEN1  EQU $556       ;PRINT THIS BEFORE TRACE DISPLAY
SCREEN2  EQU $55A       ;PRINT THIS AFTER
BASE    EQU $55E        ;WORK VARIABLE
SIGN    EQU $560
VECTOR  EQU $562        ;WORK VARIABLE
TEMP    EQU $564        ;WORK SPACE
WORK1   EQU $568        ;WORK SPACE
WORK2   EQU $56C        ;WORK SPACE
STRSYM  EQU $570        ;START OF SYMBOL TABLE
ENDSYM  EQU $574        ;END OF SYMBOL TABLE
CMDTABLE EQU $578       ;START OF COMMAND TABLE
BUFFER  EQU $57C        ;WORKING STORAGE BUFFER
;
SYSTACK  EQU $6B8       ;START OF STACK (GOES DOWN)
;                                                       6/8/82 START
COMM1   EQU $06BB
CON1    EQU $06BA
COMM2   EQU $06BD
CON2    EQU $06BC
;                                                       6/8/82 END
         PAGE
;
;       INITIALIZATION ROUTINE
;
; BY CONVENTION THIS "PROM" IS ADDRESSED AT $000000 UPON RESTART.
; WHEN A) THE ADDRESS FOR THE STACK POINTER (LOCATED AT $000000), AND
;       B) THE ADDRESS FOR RESTART      (LOCATED AT $000004), HAVE
; BEEN EXTRACTED, THE NORMAL ADDRESSING MODE RESUMES AND THIS "PROM"
; WILL BE ADDRESSED AT $20000.
;
;
;
ZERO    DATA.L  0               ;USED AS A LABEL FOR A "BRA" IN SOURCE
                                ;STACK ADDRESS (FOR RESTART)
        DATA.L ROM+8            ;ADDRESS FOR RESTART.
;
;
START   MOVE.W #$2700,SR        ;MASK OFF INTERRUPTS
;                                                               6/8/82 START
        MOVE.L #$00030F00,A0    ;GENERAL IO INITIALIZATION
        MOVE.B #$17,$07(A0)     ;KYBD CTRL, 600 BAUD, 8 BIT WD
        MOVE.B #$0B,$05(A0)     ;KYBD CMD, NO PARITY, NO INTS
        MOVE.B #$3E,$27(A0)     ;DCOM0 CTRL, 9600 BAUD, 7 BIT
        MOVE.B #$AB,$25(A0)     ;DCOM0 COMMAND
        MOVE.B #$3E,$47(A0)     ;DCOM1 CTRL, 9600 BAUD, 7 BIT
        MOVE.B #$AB,$45(A0)     ;CMD
        MOVE.B #$00,$7F(A0)     ;VIA PORT A
        MOVE.B #$00,$61(A0)     ;VIA PORT B
        MOVE.B #$80,$67(A0)     ;DATA DIRECTION A INWARDS
        MOVE.B #$37,$65(A0)     ;DATA DIRECTION B INWARDS
        MOVE.B #$10,$77(A0)     ;FREE RUN SHIFT REGISTER, COUNTER
        MOVE.B #$FF,$75(A0)     ;SYMMETRICAL WAVE SHAPE
        MOVE.B #$A0,$71(A0)     ;FAIRLY LOW INITIAL FREQUENCY
        TST.B $C1(A0)           ;TURN OFF POSSIBLE OMNINET INT
        MOVE.B $01(A0),D0       ;CLEAR KYBD DATA BUFFER
        MOVE.B $21(A0),D0       ;CLEAR DCOM0 PORT
        MOVE.B $41(A0),D0       ;CLEAR DCOM1 PORT
;                                                               6/8/82 END
;
;
        SUBA.L A0,A0            ;CLEAR A0...ADDRESS POINTERS
        MOVE.L #ROM+ABORTE-ZERO,D1      ;ABORT ERROR
INIT0   MOVE.L D1,(A0)+         ;INITIALIZE VECTOR
        CMPA.L #$400,A0         ;SEE IF DONE
        BMI.S INIT0
;                         SET UP SOME INDIVIDUAL VECTORS
        MOVE.L #ROM+TRACE-ZERO,$24.W
        MOVE.L #ROM+ABORTB-ZERO,$7C.W   ;ABORT BUTTON
        MOVE.L #ROM+TRAP15-ZERO,$BC.W   ;FOR USER I/O
;
        MOVE.L #REGPC,A0        ;START OF WORK RAM (PAST REGISTERS)
        MOVE.L #(SYSTACK-REGPC)/2,D0    ;WORDS TO ZERO
INIT    CLR.W (A0)+
        SUBQ.L #1,D0    ;
        BNE.S INIT
;
        MOVE.L #SYSTACK,A7      ;SET UP SUPER STACK
;                                                               6/8/82 START
        MOVE.W #$3EAB,CON1.W
        MOVE.W #$3EAB,CON2.W
;                                                               6/8/82 END
        MOVE.L #$20002000,REGSR.W       ;DEFAULT STATUS REGISTER
        MOVE.L #$7FFE,REGA7.W   ;SUPERVISOR STACK
        MOVE.L #$7F00,REGUS.W   ;MORE STACK
        MOVE.L #SYSTACK+2,STRSYM.W      ;INITIALIZE SYMBOL TABLE POINTERS
        MOVE.L #SYSTACK+2,ENDSYM.W
        MOVE.L #ROM+SYSCMDS-ZERO,CMDTABLE.W     ;POINTER TO COMMAND TABLE
        MOVE.L #ROM+OUT1CR0-ZERO,OUTPORT1.W     ;INITIALIZE I/O ROUTINES
        MOVE.L #ROM+OUTPUT20-ZERO,OUTPORT2.W
        MOVE.L #ROM+OUT1CR0-ZERO,OUTPORT3.W     ;(PORT 3 SAME AS PORT 1)
        MOVE.L #ROM+PORTIN10-ZERO,INPORT1.W
        MOVE.L #ROM+PORTIN20-ZERO,INPORT2.W
        MOVE.L #ROM+PORTIN10-ZERO,INPORT3.W
        MOVE.L #'----',ADALL.W  ;INITIALIZE THE TRACE DISPALY
        MOVE.W #$0302,FORMAT.W  ;PC & SR
        MOVE.W #$0404,FORMAT+18.W       ;SS US
        BRA.S INIT3
INIT2   MOVE.L #$1FFFF,D0       ;DELAY LOOP
INIT21  SUBQ.L #1,D0
        BNE.S INIT21
INIT3   BSR FIXBUF
        MOVE.W #$0D0A,(A6)+     ;GET A FRESH LINE        
        MOVE.L #'MACS',(A6)+
        MOVE.L #'BUG ',(A6)+    ;MACSBUG 2.0
        MOVE.L #'2.0',(A6)+     ;*6/8/82*
MSG     BSR OUT1CR      ;GO PRINT MESSAGE AND ENTER MACSBUG
;
;
;       ***MACSBUG***  ENTRY    ;POINT
;
MACSBUG MOVE.W #$2700,SR        ;MASK OFF INTERRUPTS
        MOVE.L #SYSTACK,A7      ;RESTORE SYSTEM STACK
        BSR SWAPOUT     ;GET BP OUT OF USER MEMORY
        CLR.L BPTILL.W  ;GET RID OF 'TILL' BREAKPOINT
        CLR.L OUTTO.W   ;INITIALIZE I/O TO DEFAULT
        CLR.L INFROM.W  ;INITIALIZE I/O TO DEFAULT
        CLR.L WORK2.W   ;NO ECHO
        BSR FIXBUF      ;A5&A6=#BUFFER
        TST.W TRACEON.W ;SEE IF IN TRACE MODE
        BEQ.S MACSBUG1  ;*
        MOVE.B #':',(A6)+       ;Trace mode prompt = :*
MACSBUG1 MOVE.B #'*',(A6)+      ;Normal prompt = *
        BSR OUTPUT      ;GO PRINT IT
        BSR FIXBUF      ;GET READY FOR INPUT
        CLR.L (A6)      ;CLEAR PART OF THE BUFFER
        BSR PORTIN1     ;GET A COMMAND
MACSBUG2 MOVE.B #' ',(A6)       ;BLANK OUT END+1
        CLR.L D7        ;DO NOT PRINT WHAT IF ERROR
;
;  DECODE A COMMAND
;
DECODE0  CMPA.L A6,A5   ;SEE IF ANYTHING ENTERED
        BMI.S DECODE1
        TST.W TRACEON.W ;SEE IF IN TRACE MODE
        BEQ.S MACSBUG
        MOVE.L #'T 1 ',(A6)+    ;PHONY UP COMMAND
        BRA.S MACSBUG2
DECODE1  CMPA.L A6,A5   ;SEE IF AT END OF BUFFER
        BHI WHAT        ;GO TO 'WHAT' IF CONFUSED
        MOVE.B (A5),D0  ;GRAB FIRST CHARACTER
        BEQ.S DECODE11  ;IGNORE NULLS
        CMPI.B #'*',D0  ;SEND LINE COMMAND
        BNE.S DECODE10
        ADDA.L #1,A5    ;GET PAST PHOENY PROMPT
        BSR OUTPUT2     ;SEND LINE+CR
        BRA.S MACSBUG   ;REENTER COMMAND MODE
DECODE10 CMPI.B #$20,D0 ;IGNORE LEADING SPACES
        BNE.S DECODE2   ;WHERE TO GO IF NOT A SPACE
DECODE11 ADDA.L #1,A5   ;BUMP START OF BUFFER
        BRA.S DECODE1   ;TRY NEXT CHARACTER
;
DECODE2  MOVE.B (A5),D1 ;GET 2 LETTERS OF COMMAND
        LSL.W #8,D1     ;MAKE ROOM FOR NEXT CHAR
        MOVE.B 1(A5),D1 ;GET NEXT CHAR
;                                                       6/8/82 START
        MOVE.L CMDTABLE.W,A0      ;START OF COMMAND TABLE
;                                                       6/8/82 END
DECODE4  MOVE.W (A0)+,D0        ;GET 2 LETTERS FROM TABLE
        MOVE.L (A0)+,D7 ;GET ROUTINE VECTOR
        CMPI.W #$FFFF,D0        ;SEE IF END OF TABLE
        BEQ     WHAT    ;
        CMPI.B #'*',D0  ;SEE IF DONT CARE CHARACTER
        BNE.S DECODE5
        MOVE.B D1,D0    ;DEFAULT
        BRA.S DECODE3
DECODE5  CMPI.B #'@',D0 ;SEE IF MUST-BE-NUMBER
        BNE.S DECODE3
        MOVE.B D1,D0    ;GET THE ALLEGED DIGIT
        CMPI.B #'0',D0  ;SEE IF LESS THAN ZERO
        BMI.S DECODE4
        CMPI.B #'8',D0  ;SEE IF GT NINE
        BPL.S DECODE4
DECODE3  CMP.W D1,D0    ;? CMD=INPUT ?
        BNE.S DECODE4
        CLR.W TRACEON.W ;TURN OFF TRACE MODE
        MOVE.L D7,-(A7) ;SET UP TO GO TO CMD
RETURN  RTS
;
WHAT    BSR FIXBUF      ;PRINT OUT 'WHAT'
        CLR.L TRACEON.W ;MAKE SURE TRACE IS OFF
        MOVE.L #'WHAT',(A6)+
        MOVE.L #$3F0D0A00,(A6)+ ;'?'+CR+LF+EOT
        BSR OUTPUT
        BRA MACSBUG
        PAGE
;
;  SYSTEM COMMAND TABLE
;
;
SYSCMDS DATA.W 'DM'     ;DISPLAY MEMORY (SAME AS PRINT)
        DATA.L ROM+PRINT-ZERO
        DATA.W 'SM'     ;SET MEMORY
        DATA.L ROM+SMCMD-ZERO
        DATA.W 'D@'     ;SET OR PRINT A DATA REGISTER
        DATA.L ROM+SETD-ZERO
        DATA.W 'A7'     ;SET A7 REG (SPECIAL)
        DATA.L ROM+SETA7-ZERO
        DATA.W 'A@'     ;SET OR PRINT AN ADDRESS REGISTER
        DATA.L ROM+SETA-ZERO
        DATA.W 'SR'     ;SET STATUS REGISTER
        DATA.L ROM+SETSR-ZERO
        DATA.W 'PC'     ;SET PROGRAM COUNTER
        DATA.L ROM+SETPC-ZERO
        DATA.W 'US'     ;SET USER STACK
        DATA.L ROM+SETUS-ZERO
        DATA.W 'SS'     ;SET SUPERVISOR STACK
        DATA.L ROM+SETSS-ZERO
        DATA.W 'BR'     ;SET BREAKPOINT
        DATA.L ROM+BCMD-ZERO
        DATA.W 'W@'     ;DEFINE A WINDOW
        DATA.L ROM+SETW-ZERO
        DATA.W 'M@'     ;SET MEMORY THROUGH WINDOW
        DATA.L ROM+SETMW-ZERO
        DATA.W 'OF'     ;SET OFFSET
        DATA.L ROM+SETO-ZERO
        DATA.W 'A:'     ;SEQUENCE THROUGH A CLASS
        DATA.L ROM+SEQCLSA-ZERO
        DATA.W 'D:'     ;SEQUENCE THROUGH A CLASS
        DATA.L ROM+SEQCLSD-ZERO
        DATA.W 'A '     ;PRINT CLASS
        DATA.L ROM+PNTCLSA-ZERO
        DATA.W 'D '     ;PRINT CLASS
        DATA.L ROM+PNTCLSD-ZERO
        DATA.W 'TD'     ;SET AND PRINT TRACE DISPLAY
        DATA.L ROM+RCMD-ZERO
        DATA.W 'CV'     ;NUMBER CONVERSION
        DATA.L ROM+NUMCON0-ZERO
        DATA.W 'CA'     ;CALL AN ALIEN ROUTINE (BSR)
        DATA.L ROM+USERCALL-ZERO
        DATA.W 'G*'     ;GO COMMAND
        DATA.L ROM+GOCMD-ZERO
        DATA.W 'RE'     ;READ (DOWNLOAD) COMMAND
        DATA.L ROM+READ-ZERO
        DATA.W 'VE'     ;VERIFY COMMAND
        DATA.L ROM+VERIFY-ZERO
        DATA.W 'P2'     ;ENTER TRANSPARENT MODE
        DATA.L ROM+P2CMD-ZERO
        DATA.W 'SY'     ;SYMBOLICS
        DATA.L ROM+SYCMD-ZERO
        DATA.W 'TE'     ;TERMINAL NULL CONTROL
        DATA.L ROM+SPCMD-ZERO
        DATA.W 'T*'     ;TRACE COMMAND
        DATA.L ROM+TCMD-ZERO
        DATA.W 'FO'     ;FORMAT (HOW TO PROGRAM ACIA)
        DATA.L ROM+FOCMD-ZERO
        DATA.W 'CR'     ;CR PADD COMMAND
        DATA.L ROM+CRCMD-ZERO
        DATA.W 'NU'     ;NULL PADD COMMAND
        DATA.L ROM+NUCMD-ZERO
        DATA.W 'PU'     ;PUNCH COMMAND
        DATA.L ROM+PUNCH-ZERO
        DATA.W 'OP'     ;OPEN MEMORY
        DATA.L ROM+OPENCMD-ZERO
;
        DATA.W $FFFF    ;END OF LIST
          PAGE
;       ***PRINT***  PRINT (CORE DUMP) MACSBUG ENTRY POINT
;       FORMAT:  PRINT[S] ADDRESS COUNT
;       OR      PRINT ADDRESS ADDRESS
;       IF SECOND PARAMETER IS LESS THAN STARTING ADDRESS
;       THEN IT IS ASSUMED TO BE A COUNT-ELSE ENDING ADD.
;       IF 'S' USED IN COMMAND THEN IT WILL PRINT 16 LINES
;       AND PROMPT-ENTER CR FOR 16 MORE LINES ETC OR
;       ANY MACSBUG COMMAND.
;
PRINT   BSR SCANPORT    ;WHERE TO SEND OUTPUT
        MOVEQ.L #-1,D6  ;HOW MANY PER PAGE
        MOVEQ.L #2,D0   ;INDEX PAST COMMAND
        MOVE.B #' ',(A6)        ;LANK OUT LAST LETTER
PRINT1  MOVE.B 0(A5,D0),D1      ;GET COMMAND LETTER
        CMPI.B #' ',D1          ;SEE IF SPACE
        BEQ.S PRINT5    ;NOT 'PRINTS'
        CMPI.B #'S',D1  ;SEE IF LETTER S
        BEQ.S PRINT4
        ADDQ.L #1,D0    ;CHECK NEXT CHAR
        BRA.S PRINT1
PRINT4  MOVEQ.L #16,D6  ;DO 16 LINES AT A TIME
        MOVE.L INPORT1.W,INFROM.W       ;MUST BE CONSOLE WITH THIS OPTION
        MOVE.L OUTPORT1.W,OUTTO.W
PRINT5  MOVE.L #0,A3    ;DEFAULT ZERO  START & END ADDRESS
        MOVE.L #0,A4
        MOVE.L #ROM+PUTADR-ZERO,A0      ;WHERE TO GO IF NO PARAMETERS
        BSR GRABNUM     ;GET NUMBER
        MOVE.L D0,A3
        MOVE.L D0,A4    ;DEFAULT IS END
        BSR GRABNUM
        CMP.L A3,D0     ;SEE IF GREATER
        BHI.S PRINT2
        ADD.L A3,D0     ;END=START+COUNT-1
        SUBQ.L #1,D0    ;BACK OFF ONE
        MOVE.L D0,A4
        BRA.S PUTADR
PRINT2  MOVE.L D0,A4    ;ENDING ADDRESS=INPUT
        MOVE.L A3,D0    ;GET READY FOR AND
        ANDI.L #$00FFFFF0,D0     ;ROUND FOR EVEN DISPLAY
        MOVE.L D0,A3    ;ROUNDED START ADDRESS
; START A NEW 'DUMP' LINE
PUTADR  BSR FIXBUF      ;SET UP OUTPUT BUFFER
        MOVE.L A3,D0    ;CURRENT LINE ADDRESS
        BSR PNT6HX      ;PRINT THE ADDRESS
        MOVE.W #$2020,(A6)+     ;PRINT 2 SPACES
        MOVE.L A3,A0    ;A0 IS SCANNING ADDRESS
        MOVE.W #$10,D3  ;SET UP COUNTER FOR LOOP
NXTBP   MOVE.B (A0)+,D0 ;GET BYTE TO PRINT
        BSR PNT2HX      ;PRINT IT
        MOVE.B #$20,(A6)+       ;SPACE BETWEEN EACH HEX
        SUBQ.L #1,D3    ;LOOP TILL D3 IS ZERO
        BNE.S NXTBP
        MOVE.W #$2020,(A6)+     ;MOVE A COUPLE OF SPACES
        MOVE.L A3,A0    ;RELOAD SCANNER FOR ASCII PRINTS
        MOVE.W #$10,D3  ;RELOAD COUNTER
NXTCHR  MOVE.B (A0)+,D0 ;GRAB BYTE
        CMPI.B #$20,D0  ;SEE IF IT IS CONTROL CHAR
        BLE.S NOTCHR    ;WHERE TO GO IF LESS THAN SPACE
        CMPI.B #'Z',D0  ;IF .LE. Z THEN PRINT
        BLE.S PUTCHR
        CMPI.B #$61,D0  ;FILTER OUT $5B TO $60
        BLT.S NOTCHR
        CMPI.B #$7A,D0  ;SEE IF ABOVE LITTLE Z
        BLE.S PUTCHR
NOTCHR  MOVE.B #$2E,D0  ;CHANGE UNPRINTABLE TO PERIOD
PUTCHR  MOVE.B D0,(A6)+ ;MOVE PRINT CHAR TO PRINT BUFFER
        SUBQ.L #1,D3    ;LOOP AROUND FOR NEXT CHAR
        BNE.S NXTCHR
        BSR OUT1CR      ;AT END OF LINE...PRINT IT
        ADDA.L #$10,A3  ;UPDATE STARTING ADDRESS OF NEXT ADDRESS
        CMPA.L A4,A3    ;DOES NEW LINE START PAST END ADDR
        BGT MACSBUG     ;DONE WITH PRINTING
        SUBQ.L #1,D6    ;KNOCK DOWN COUNTER
        BNE.S PUTADR    ;DO ANOTHER LINE
        BSR FIXBUF      ;SET UP FOR PROMPT
        MOVE.B #'*',(A6)+       ;PROMPT SAME AS MACSBUG
        BSR OUTPUT      ;PRINT IT
        BSR FIXBUF      ;RESET BUFFER
        BSR PORTIN1     ;TAKE IN INPUT
        CMPA.L A6,A5    ;SEE IF ANYTHING ENTERED
        BNE MACSBUG2    ;GO DECODE A COMMAND
        MOVE.B #16,D6   ;DO ANOTHER 16 LINES
        BRA PUTADR
        PAGE
;
;       ***SM***        SET MEMORY
;       FORMAT: SM ADDRESS HEX HEX,HEX,'ASCII'  ETC.
;       COMMAS OR SPACES BETWEEN FIELDS
;       FIELDS ARE SIZE ADJUSTED (STORES UP TO 4 BYTES)
;       ASCII ENCLOSED IN SINGLE QUOTES-ANY LENGTH
;
SMCMD   MOVE.L #ROM+SYNTAX-ZERO,A0      ;IF NO PARAMETERS
        BSR GRABNUM     ;GET PARAMETER
        MOVE.L D0,A1    ;A1=START (OPEN) ADDRESS
SETM1   MOVE.L #ROM+MACSBUG-ZERO,A0     ;IF NO PARAMTER
        BSR FINDNP
        MOVE.L A5,A4    ;SAVE ADDRESS OF PARAMTER
        MOVE.B (A5),D0  ;CHECK OUT NEXT CHARACTER
        CMPI.B #$27,D0  ;SEE IF IT IS QUOTE MARK
        BEQ.S SETM5     ;SPECIAL ROUTINE
        CMPI.B #'N',D0  ;SEE IF NEXT LINE FEATURE
        BEQ SETM7
        BSR GETNUMA     ;GET THE DATA
        MOVE.L A1,A3    ;ADDRESS
        MOVE.L A5,D1    ;COMPUTE BYTES OF DATA
        SUB.L A4,D1     ;LEN=END-START
        ASR.L #1,D1     ;BYTES=CHAR/2
        BCC.S SETM3     ;TAKE CARE OF ODD CHARACTER
        ADDQ.L #1,D1    ;WHOLE NUMBER OF BYTES
SETM3   MOVE.L D1,D2    ;D1 SCANS DOWN
        SUBQ.L #1,D2    ;KNOCK IT DOWN TO INDEX
        MOVE.B D0,0(A3,D2)      ;INDEXED BECAUSE BACKWARD
        MOVE.B 0(A3,D2),D3      ;REREAD TO CHECK IF STORED OK
        CMP.B D0,D3     ;ARE SAME?
        BEQ.S SETM4
SETME   BRA ERROR       ;DIDN'T STORE RIGHT!!
SETM4   ASR.L #8,D0     ;SHIFT ONE BYTE
        ADDA.L #1,A1    ;BUMP ADDRESS
        SUBQ.L #1,D1
        BNE.S SETM3
        BRA.S SETM1     ;GO DO NEXT DATA
;  DATA IN IN ASCII STRING
SETM5   ADDA.L #1,A5    ;GET PAST QUOTE MARK
SETM6   CMPA.L A6,A5    ;SEE IF END OF BUFFER
        BGE MACSBUG
        MOVE.B (A5)+,D0 ;GRAB CHARACTER
        CMPI.B #$27,D0  ;SEE IF QUOTE MARK
        BEQ.S SETM1     ;IF SO-END OF STRING
        MOVE.B D0,(A1)  ;SAVE DATA
        MOVE.B (A1)+,D1 ;REREAD FOR CHECK
        CMP.B D1,D0     ;SEE IF SAME
        BNE.S SETME     ;NOT EQUAL=ERROR
        BRA.S SETM6     ;DO ANOTHER
;
SETM7   BSR FIXBUF      ;DISPLAY CURRENT ADDRESS
        MOVE.L A1,D0    ;
        BSR PNT8HX      ;PUT ADDRESS IN BUFFER
        MOVE.L #' ? ',(A6)+     ;PROMPT
        BSR OUTPUT      ;DUMP BUFFER WITH NO LF CR
        BSR FIXBUF      ;GET READY FOR INPUT
        MOVE.B #' ',(A5)+       ;ADVANCE IN BUFFER
        MOVE.L A5,A6    ;BECAUSE OF SNAFU IN FINDNP
        BSR PORTIN1     ;INPUT FROM CONSOLE
        MOVE.B -(A5),D0 ;JUST BACK UP IN BUFFER
        CMPA.L A6,A5
        BEQ MACSBUG
        BRA SETM1       ;DO DECODE IT
        PAGE
;
;       ***OPEN***  EXAMINE/CHANGE MEMORY
;
;
OPENCMD  MOVE.L #ROM+ERROR2-ZERO,A0     ;WHERE TO GO IF NO ADDRESS
        BSR GRABNUM     ;GET ADDRESS
        MOVE.L D0,A4    ;SAVE ADDRESS HERE
OPEN10  BSR FIXBUF      ;PRINT ADDRESS & CONTENT
        MOVE.L A4,D0    ;CURRENT ADDRESS
        BSR PNT6HX
        MOVE.B #' ',(A6)+       ;SPACE
        MOVE.B (A4),D0  ;GRAB CONTENT
        BSR PNT2HX      ;PRINT IT
        MOVE.B #' ',(A6)+       ;SPACE
        MOVE.B #'?',(A6)+       ;PROMPT
        BSR  OUTPUT     ;OUTPUT THE BUFFER
;
; TAKE IN NEW CONTENT OR COMMAND
        BSR FIXBUF
        BSR PORTIN1     ;GET LINE FROM USER
        CMPA.L A5,A6    ;SEE IF NULL LINE
        BEQ OPEN50      ;GO TO NEXT LOCATION    
        MOVE.B (A5),D0  ;SEE IF '.' END OF COMMAND
        CMPI.B #'.',D0
        BEQ MACSBUG     ;END ROUTINE
        MOVE.B (A4),D0  ;DEFAULT VALUE
        BSR GETNUMA     ;GET NEW CONTENT
;               PATCH 12/13/79 TO FORCE WRITE
        NOP             ;CMP.B D0,(A4)  SEE IF CHANGE NEEDED
        NOP             ;BEQ.S OPEN30
        MOVE.B D0,(A4)  ;SAVE NEW DATA
        CMP.B (A4),D0   ;SEE IF CHANGE MADE
        BEQ.S OPEN30
        BSR FIXBUF      ;GET READY FOR ERROR MESSAGE
        MOVE.L #'NO C',(A6)+
        MOVE.L #'HANG',(A6)+    ;.
        MOVE.L #'E ',(A6)+
        BSR OUT1CR
        BRA.S OPEN10    ;STAY AT SAME LOCATION
;
; NOW FIGURE OUT UP/DOWN/SAME  ADDRESS
;
OPEN30  CMPA.L A6,A5    ;SEE IF AT BEGINNING OF BUFFER
        BEQ.S OPEN50
        MOVE.B -(A6),D0
        CMPI.B #'.',D0  ;SEE IF CLOSE MODE
        BEQ     MACSBUG
        CMPI.B #'^',D0  ;GOING UP ALTERNATE CHAR
        BEQ.S OPEN60
        CMPI.B #'=',D0  ;SEE IF STAYING THE SAME
        BEQ.S OPEN10
OPEN50  ADDA.L #1,A4    ;GO LOW-TO-HIGH
        BRA     OPEN10
OPEN60  SUBA    #1,A4   ;GO HIGH-TO-LOW
        BRA     OPEN10
        PAGE 
;
; ***READ*** AND ***VERIFY**    'S' RECORDS
;
VERIFY  MOVE.L #'V ',WORK1.W    ;MARK THE MODE
        BRA.S CHKCHKS   ;GO CHECK CHECKSUM OPTION
;
READ    CLR.L WORK1.W   ;READ MODE
CHKCHKS  CLR.L TEMP.W   ;NORMALLY CHECK CHECKSUM
        CLR.L WORK2.W   ;ECHO
        BSR SCANPORT    ;SET UP OUTPUT P1,P2,P3 ETC                     
; SEE IF CHECKSUM -C OPTION AND =SEND THIS OPTION
READ01  CMPA.L A6,A5    ;SEE IF AT END OF BUFFER
        BEQ.S READ0
        MOVE.B (A5)+,D0 ;GET A CHARACTER
READ03  CMPI.B #'=',D0  ;SEE IF EQUAL SIGN
        BNE.S READ02
        BSR OUTPUT2     ;SEND REST OF LINE TO PORT
        BRA.S READ0
READ02  CMPI.B #'X',D0  ;SEE IF ECHO
        BNE.S READ021
        MOVE.L #-1,WORK2.W      ;SET ECHO
        BRA.S READ01
READ021  CMPI.B #'-',D0 ;SEE IF MINUS SIGN
        BNE.S READ01
        CMPA.L A6,A5    ;SEE IF AT END OF BUFFER
        BEQ.S READ0
        MOVE.B (A5)+,D0 ;GRAB SECOND CHARACTER
        CMPI.B #'C',D0  ;SEE IF LETTER C AS IN  -C
        BNE.S READ03
        MOVE.W #'CC',TEMP.W     ;MARK AS IGNORE CHECKSUM
        BRA.S READ01
;
READ0   BSR FIXBUF      ;START OF INPUT BUFFER
        BSR PORTIN2     ;GET A RECORD FROM PORT
        CLR.L D4        ;FIRST TIME THROUGH JUST CHECK STUFF
READ00  MOVE.L A5,A3    ;SAVE START ADDRESS OF BUFFER
        MOVE.L A6,A4
        MOVE.B (A3)+,D0 ;PULL FIRST CHARACTER
        CMPI.B #'S',D0  ;SEE IF IT IS AN S
        BEQ READ1
        BRA.S READ0     ;GO GET ANOTHER BUFFER
READ1   MOVE.B (A3)+,D0 ;PULL RECORD TYPE
        CMPI.B #'0',D0  ;'S0'???
        BEQ.S READ0     ;JUST IGNORE
        CMPI.B #'1',D0  ;S1 ??? (2 BYTE ADDRES-DATA RECORD)
        BEQ READS1
        CMPI.B #'2',D0  ;S2 ???  (3 BYTE ADDRESS)
        BEQ READS2
        CMPI.B #'8',D0  ;S8 ??? (3 BYTE ADD-END OF FILE)
        BEQ READS8
        CMPI.B #'9',D0  ;S9 ??? /2 BYTE ADD-END OF FILE)
        BEQ READS9
        BRA.S READ0     ;IGNORE WEIRD LINE
READS1  MOVEQ.L #4,D6   ;CHARACTERS IN ADDRESS
READ2   CLR.L D5        ;D5 HOLDS THE CHECKSUM
        MOVEQ.L #2,D2   ;GET THE 2 CHARACTER BYTE COUNT
        BSR READHEX
        MOVE.L D0,D3    ;D3 HOLDS BYTE COUNT
        ADD.B D0,D5     ;ADD TO CHECKSUM
        MOVE.L A3,A1    ;SAVE ADDRESS FOR A WHILE
        MOVE.L D6,D7    ;CHAR IN ADDRESS
        DIVU #2,D7      ;BYTES IN ADDRESS
READ4X  MOVEQ.L #2,D2   ;READ ONE BYTE
        BSR READHEX     ;OF THE ADDRESS
        ADD.B D0,D5     ;CHECKSUM
        SUBQ.L #1,D7
        BNE.S READ4X
        MOVE.L A1,A3    ;RESTORE ADDRESS
        MOVE.L D6,D7    ;SET UP TO ADJUST BYTE COUNT
        ADDQ.L #2,D7    ;ADD IN CHECK SUM & ADDRESS
        DIVU #2,D7      ;CHANGE CHARACTERS TO BYTES
        SUB.W D7,D3     ;ADJUST BYTE COUNT
        MOVE.L D6,D2    ;SET CHARACTERS IN ADDRESS
        BSR READHEX     ;GET THE ADDRESS INTO D0
        MOVE.L D0,A0    ;SAVE ADDRESS IN A0
        ADDA.L OFFSET.W,A0        ;ADD IN OFFSET
        CLR.L D6        ;ZERO=MATCHED OK
READ3   MOVEQ.L #2,D2   ;SET UP TO GET BYTE OF DATA
        BSR READHEX
        TST.B WORK1.W   ;SEE IF VERIFY MODE
        BEQ.S READ301
        MOVE.B (A0)+,D1 ;GET MEMORY
        CMP.B D1,D0     ;SEE IF SAME
        BEQ.S READ31
        MOVE.B #'P',D6  ;MARK FOR PRINT
        BRA.S READ33
READ31  MOVE.L A3,A2    ;TRY TO BLANK OUT OK STUFF
        SUBA.L #2,A2    ;BACK UP 2
        MOVE.B #' ',(A2)+
        MOVE.B #' ',(A2)+
        BRA.S READ33
READ301  ADD.B D0,D5    ;CHECKSUM
        TST.L D4        ;ZERO=JUST TESTING (PASS 1)
        BEQ.S READ33
        MOVE.B D0,(A0)+ ;SAVE THE TAPE DATA
READ33  SUBQ.L #1,D3    ;GO DOWN BYTE COUNT
        BNE.S READ3
        TST.B WORK1.W   ;SEE IF IN VERIFY MODE
        BEQ.S READ34
        TST.B D6        ;SEE IF PRINT IS NEEDED
        BEQ READ0
        MOVE.L OUTPORT1.W,OUTTO.W       ;SET UP FOR CONSOLE
        MOVE.B #' ',(A2)+       ;BLANK OUT CHECKSUM
        MOVE.B #' ',(A2)+       ;BLANK OUT CHECKSUM
        BSR OUT1CR0     ;GO  PRINT IT
        BRA READ0
READ34  TST.L D4        ;NONZERO=END SECOND PASS
        BNE READ0
        MOVEQ.L #1,D4   ;FLAG NOW AS PASS2
        TST.B TEMP.W    ;SEE IF CHKSUM IGNORED
        BNE READ00      ;START SECOND PASS
        MOVEQ.L #2,D2   ;GET CHECKSUM
        BSR READHEX
        NOT.B D0        ;REVERSE IT
        CMP.B D5,D0     ;SEE IF SAME AS CHECKSUM
        BEQ READ00      ;START SECOND PASS
        MOVE.L #' CHK',(A6)+    ;ERROR TYPE
        MOVE.L #'SUM=',(A6)+
        MOVE.B D5,D0    ;D5=COMPUTED CHKSUM
        NOT.B D0        ;REVERSE IT
        BSR PNT2HX      ;PUT WHAT CHKSUM SHOULD BE
        BSR OUT1CR0
        BRA READ0
READS2  MOVEQ.L #6,D6   ;CHARACTERS IN ADDRESS
        BRA READ2
READS8  MOVEQ.L #6,D2   ;6 CHAR IN ADDRESS
READ8   ADDA.L #2,A3    ;GET PAST BYTE COUNT
        BSR READHEX     ;GET ADDRESS
        MOVE.L D0,REGPC.W       ;SAVE IT IN THE USER PREG
        BRA MACSBUG     ;END OF ROUTINE?
READS9  MOVEQ.L #4,D2   ;4 CHAR IN ADDRESS
        BRA.S READ8
READHEX  CLR.L D0       ;READ HEX FROM BUFFER
RHEX1   MOVE.B (A3)+,D1 ;GRAB ASCII
        CMPI.B #$30,D1  ;SEE IF LESS THAN ZERO
        BLT RHEX3       ;
        CMPI.B #$39,D1  ;SEE IF GT 9
        BLE RHEX2
        SUBQ.B #7,D1    ;NORMALIZE $A TO 10
        CMPI.B #$40,D1  ;SEE IF TOO LARGE
        BLT RHEX2       ;
RHEX3   MOVE.L #' NOT',(A6)+    ;'NOT HEX=X?'  MESSAGE
        MOVE.L #' HEX',(A6)+
        MOVE.B #'=',(A6)+
        MOVE.B -(A3),(A6)+      ;BAD CHARACTER
        BSR OUT1CR
        MOVE.L (A7)+,D0 ;POP STACK (NO RETURN FROM ROUTINE)
        BRA READ0       ;GO TRY NEXT RECORD
RHEX2   ANDI.B #$F,D1
        ASL.L #4,D0     ;SHIFT PRIOR RESULT
        OR.B D1,D0      ;INCLUDE NEX HEX CHARACTER
        SUBQ.L #1,D2    ;LOOP AROUND
        BNE.S RHEX1
        RTS
        PAGE
;
;       ***PUNCH***  PUNCH 'S' RECORDS
;       FORMAT:  PU ADDRESS  ADDRESS OR COUNT
;
;
PUNCH   BRA MACSBUG
;PUNCH   BSR SCANPORT    ;SEE WHERE TO SEND OUTPUT
;       MOVE.L #ROM+ERROR2-ZERO,A0      ;WHERE TO GO IF NO PARAMTERS
;       BSR GRABNUM     ;GET NUMBER ELSE ERROR
;       MOVE.L D0,A3    ;SAVE IT
;       BSR FINDNP      ;SEARCH FOR END ADDRESS
;       BSR GETNUMR     ;GET THE NUMBER
;       MOVE.L D0,A4    ;SAVE IT
;       CMPA.L A3,A4    ;SEE IF COUNT OR ABSOLUTE
;       BHI.S PUNCH1
;       ADDA.L A3,A4    ;IT WAS COUNT
;       SUBA.L #1,A4    ;MOVE IT DOWN
;PUNCH1
;       MOVE.L #ROM+PUNCH5-ZERO,A0      ;WHERE TO GO IF NO HEADER
;       BSR FINDNP      ;LOOK FOR HEADER
;PUNCH5  MOVE.L A5,A0    ;START OF BUFFER
;       MOVE.L A6,D5    ;END OF TEXT+1
;       BSR FIXBUF      ;A5,A6=#BUFFER
;       MOVEQ.L #2,D6   ;THE BYTE COUNT
;       CLR.L D4        ;CLEAR THE CHECKSUM
;       MOVE.L #'S0??',(A6)+    ;START OF S RECORD
;       MOVE.L #'0000',(A6)+    ;DUMMY ADDRESS
;MORES0  CMPA.L D5,A0    ;SEE IF AT END OF TEXT
;       BGE.S ENDS0     ;WHERE TO GO WHEN ALL CHARACTERS USED
;       ADDQ.L #1,D6    ;ANOTHER BYTE
;       MOVE.B (A0)+,D0 ;GET ANOTHER BYTE OF TEXT
;       ADD.L D0,D4     ;FOR CHECKSUM
;       BSR PNT2HX      ;PUT IT IN BUFFER
;       BRA.S MORES0
;ENDS0   BSR PNTSREC     ;GO PRINT THE 'S' RECORD
;       MOVE A3,A2      ;A2 WILL SCAN BETWEEN A3-A4
;
; DO ANOTHER    ;'S' RECORD
;
;MORESP  BSR FIXBUF      ;A5,A6=#BUFFER
;       CLR.L D4        ;CLEAR CHECKSUM REGISTER
;       MOVE.L A3,D0    ;READY TO PRINT ADDRESS
;       SUB.L OFFSET.W,D0
;       MOVE.L A3,D1    ;GET READY TO AND ADDRESS
;       MOVEQ.L #$10,D3 ;MAXIMUM BYTES ON S REC LINE
;       ADD.L D3,D1     ;INSURE END OF LINE ADDRESS IS MAX
;       ANDI.L #$FF0000,D1       ;SEE IF 3 BYTE ADDRESS
;       BNE S2REC       ;WHERE TO GO IF 3 BYTES NEEDED
;       MOVE.L #'S1??',(A6)+    ;PUSH
;       MOVE A3,D0      ;SET UP TO PRINT 2 BYTE ADDRESS
;       SUB.L OFFSET.W,D0
;       BSR PNT4HX      ;PRINT 4 HEX CHAR ADDRESS
;       MOVEQ.L #2,D6   ;BYTE COUNT
;       MOVE.W A3,D0    ;FIX UP CHECKSUM
;       SUB.L OFFSET.W,D0
;       ADD.B D0,D4     ;LOW BYTE
;       ASR #8,D0       ;SHIFT IT OVER
;       ADD.B D0,D4     ;HIGH BYTE OF ADDRESS
;       BRA PNCA3       ;GO PUNCH A LINE
;S2REC   MOVE.L #'S2??',(A6)+    ;PUSH
;       BSR PNT6HX      ;PRINT 6 HEX CHAR ADDRESS
;       MOVEQ.L #3,D6   ;BYTE COUNT
;       MOVE.L A3,D0    ;FIX UP CHECKSUM
;       SUB.L OFFSET.W,D0
;       ADD.B D0,D4     ;LOW BYTE
;       ASR #8,D0       ;SHIFT IT OVER
;       ADD.B D0,D4     ;MIDDLE BYTE
;       SWAP D0 ;SET UP FOR HIGH BYTE
;       ADD.B D0,D4     ;ADD HIGH BYTE
;PNCA3   CMPA.L A4,A3    ;SEE IF AT ENDING ADDRESS
; END OF FILE
;       BLE A3OUT       ;WHERE TO GO IF BELOW OR AT END ADDRESS
;       BSR PNTSRECX    ;END IT BY PRINTING LAST RECORD
;       BSR FIXBUF      ;A5,A6=#BUFFER
;       MOVE.L #'S9??',(A6)+    ;MOVE TO PRINT BUFFER
;       MOVE.L #'0000',(A6)+    ;MOVE '0000' TO PRIT BUFFER
;       MOVEQ.L #2,D6   ;BYTE COUNT
;       BSR PNTSREC     ;PRINT 'S9' END-OF-FILE RECORD
;       BRA MACSBUG     ;REENTER MACSBUG
;A3OUT   MOVE.B (A3)+,D0 ;GRAB THE BYTE FROM MEMORY
;       ADD.W D0,D4     ;ADD TO CHECKSUM
;       ADDQ.W #1,D6    ;BUMP THE BYTE COUNT
;       ADDA.L #1,A1    ;ADD TO COUNT OF BYTES PROCESSED
;       BSR PNT2HX      ;PUT THE HEX IN THE PRINT BUFFER
;       SUBQ.L #1,D3    ;COUNT DOWN CHAR TO GO IN LINE
;       BNE.S PNCA3
;       BSR PNTSREC     ;END OF LINE-PUNCH IT
;       BRA MORESP      ;GO FIX UP NEXT LINE
;
; FIX UP & PRINT THE 'S' RECORD/LINE
;
PNTSRECX CMPA.W #$0000,A1       ;SEE IF ANY CHAR MOVED
        BNE.S PNTSREC   ;IF SO GO PRINT IT
        RTS             ;IF NOT JUST RETURN
PNTSREC  ADDQ #1,D6     ;ONE MORE BYTE (CHECKSUM)
        ADD.W D6,D4     ;ADD BYTE COUNT TO CHECKSUM
        NOT.B D4        ;COMPLIMENT THE CHECKSUM
        MOVE.L D4,D0    ;READY FOR PRINT-HEX
        BSR PNT2HX      ;PUT CHECKSUM IN RECORD
        MOVE.L A6,D7    ;SAVE FOR THE MOMENT
        MOVE.L A5,A6    ;START OF BUFFER
        ADDA.L #2,A6    ;BYPASS RECORD TYPE (4 CHAR)
        MOVE.B D6,D0    ;SET UP BYTE COUNT FOR PNTHEX ROUTINE
        BSR PNT2HX      ;PUT THE BYTE COUNT IN THE PRINT BUFFER
        MOVE.L D7,A6    ;RESTORE REAL END OF BUFFER
        BSR OUT1CR      ;DO THE ACTUAL DISPLAY/PUNCH 
        SUBA.L A1,A1    ;CLEAR COUNTER OF BYTES PROCESSED
        RTS
         PAGE
;
;       ***TE***        SPEED COMMAND
;
SPCMD   MOVE.B 2(A5),D6 ;SAVE ACIA #
SPCMD2  MOVE.L #ROM+SYNTAX-ZERO,A0      ;WHERE TO GO IF NO PARAMTERS
        BSR GRABNUMA    ;GET SPEED
        CMPI.W #$110,D0 ;BAUD=110??
        BNE.S SPCMD3
        MOVE.B #0,D0    ;CHARACTER NULLS
        MOVE.B #0,D1    ;CR NULLS
        BRA.S SPCMD8
SPCMD3  CMPI.W #$300,D0 ;BAUD=300??
        BNE.S SPCMD4
        MOVE.B #0,D0
        MOVE.B #4,D1
        BRA.S SPCMD8
SPCMD4  CMPI.W #$1200,D0        ;BAUD=1200??
        BNE.S SPCMD5
        MOVE.B #3,D0
        MOVE.B #$17,D1
        BRA.S SPCMD8
SPCMD5  CMPI.W #$2400,D0        ;BAUD=2400??
        BNE WHAT
        MOVEQ.L #$7,D0
        MOVEQ.L #$2F,D1
SPCMD8  CMPI.B #'2',D6  ;SEE IF PORT1 ONLY
        BEQ.S SPCMD9
        MOVE.B D0,NULLPADS.W    ;SET CHAR NULLS
        MOVE.B D1,CRPADS.W      ;SET CR NULLS
SPCMD9  CMPI.B #'1',D6  ;SEE IF PORT2 ONLY
        BEQ INIT2
        MOVE.B D0,NULLPADS+1.W  ;SET CHAR NULLS
        MOVE.B D1,CRPADS+1.W    ;SET CR NULLS
        BRA INIT2
        PAGE
;
;       COMMANDS TO SET TERMINAL SPEEDS
;
;                                                       6/8/82 START
FOCMD   MOVE.L #CON1,A1 ;INDEX FOR ACIA CONTROL STUFF
;                                                       6/8/82 END
        BRA.S PADCMD
NUCMD   MOVE.L #NULLPADS,A1     ;INDEX FOR NULL PAD STUFF
        BRA.S PADCMD
;
CRCMD   MOVE.L #CRPADS,A1       ;CARRIAGE RETURN PADS
;
PADCMD  MOVE.W (A5),D7  ;SAVE TEST 'NU' OR 'CR'
        MOVE.B 2(A5),D6 ;SAVE POSSIBLE ACIA #1 OR 2
        MOVE.L A6,D5    ;SEE IF ':' USED
        SUB.L A5,D5     ;COMPUTE OFFSET
        MOVE.B #':',D0  ;COMPARE WITH SLASH
PADCMD0  CMP.B 0(A5,D5),D0      ;SEE IF BUFFER=/
        BEQ.S PADCMD1
        SUBQ.L #1,D5    ;LOOP AROUND
        BNE.S PADCMD0
PADCMD1  MOVE.L #ROM+PNTPAD-ZERO,A0
        BSR GRABNUMA    ;GET NEXT PARAMETER IF ANY
PADCMD11 CMPI.B #'2',D6 ;SEE IF SETING PORT1
        BEQ.S PADCMD2
        MOVE.B D0,(A1)  ;SAVE PARAMETER
PADCMD2  CMPI.B #'1',D6 ;SEE IF SETING PORT2
        BEQ.S PADCMD3
        MOVE.B D0,1(A1)
;
;       PATCHED *08/14/80*
PADCMD3  BRA PATCH3     ;CALL INITACIA AND RE-ENTER MACSBUG
;
PNTPAD  BSR FIXBUF      ;SET UP TO PRINT
        CMPI.B #'1',D6  ;SEE IF ANY PARTICUALR NUMBER USED
        BEQ.S PNTPAD2
        CMPI.B #'2',D6
        BEQ.S PNTPAD2
        MOVE.B (A1),D0  ;SEE IF THE TWO ARE THE SAME
        CMP.B 1(A1),D0
        BNE.S PNTPAD2
        MOVE.W D7,(A6)+ ;'NU' OR 'CR'
        MOVE.B #'=',(A6)+       ;SET UP TO PRINT 1 NUMBER
        BSR PNT2HX
        BRA.S PNTPAD4
PNTPAD2  CMPI.B #'2',D6 ;SEE IF PORT1
        BEQ.S PNTPAD3
        MOVE.W D7,(A6)+ ;'NU' OR 'CR'
        MOVE.W #'1=',(A6)+
        MOVE.B (A1),D0  ;GET VALUE TO PRINT
        BSR PNT2HX
        MOVE.W #' ',(A6)+               ;SPACES
PNTPAD3  CMPI.B #'1',D6 ;SEE IF PORT2 ONLY
        BEQ.S PNTPAD4
        MOVE.W D7,(A6)+ ;SET IN 'NU' OR 'CR'
        MOVE.W #'2=',(A6)+
        MOVE.B 1(A1),D0 ;GET PAD VALUE
        BSR PNT2HX
PNTPAD4  BSR OUTPUT     ;GO PRINT IT
        BSR FIXBUF
        TST.B D5        ;SEE IF ':' USED
        BEQ MSG
        BSR PORTIN1     ;GO GET INPUT
        CMPA.L A6,A5    ;SEE IF ANYTHING INPUT
        BEQ MACSBUG
        BSR GETNUMA     ;GO GET PARAMETER
        BRA PADCMD11    ;GO DECODE IT
        PAGE
;
;       PRINT & INPUT REGISTER ROUTINES
;
SETD    MOVE.L #REGS,A4 ;START OF REGISTERS
        BRA.S SETR
SETA    MOVE.L #REGS+32,A4      ;OFFSET IN REGISTER TABLE
        BRA.S SETR
SETPC   MOVE.L #REGPC,A4        ;WHERE PC IS
        BRA.S SETR0
SETSR   MOVE.L #REGSR,A4        ;WHERE SR IS
        BRA.S SETR0
SETA7   MOVE.L REGSR.W,D1 ;GET CONDITION CODES
        ANDI #$2000,D1    ;CHECK SUPERVISOR BIT
        BEQ.S SETUS
SETSS   MOVE.L #REGA7,A4        ;WHERE SUPERVISOR STACK IS
        BRA.S SETR0
SETUS   MOVE.L #REGUS,A4        ;USER STACK
        BRA.S SETR0
SETO    MOVE.L #OFFSET,A4       ;WHERE OFFSET IS
        BRA.S SETR0
;
;  ROUTINE TO ENTER DATA FOR A SINGLE REGISTER
;       A5-A6 ARE COMMAND BUFFER
;       D0 HAS REGISTER DIGIT A4 HAS CLASS OFFSET
SETR    BSR GETHEX      ;GET REG NUMBER
        LSL.L #2,D0     ;SHIFT LEFT...MULT BY 4
        ADDA.L D0,A4    ;A4 NOW HAS EXACT ADDRESS
SETR0   ADDA.L #2,A5    ;NOW FIND PARAMETERS
        MOVE.B #':',D0  ;SEE IF SLASH IN COMMAND
        BSR.S SCAN
        BEQ.S SETR5
;SEE IF ANY PARAMER (HEX)
SETR3   MOVE.L #ROM+SETR4-ZERO,A0       ;WHERE TO GO IF NO PARAMETERS
        BSR FINDNP      ;GO FIND NEXT PARAMETER
SETR6   CLR.L D0        ;DEFAULT VALUE IS ZERO
SETR7   BSR GETNUMA     ;GO GET VALUE
        BSR.S CHECKSR   ;SEE IF SR OVERFLOW
        MOVE.L D0,(A4)  ;SAVE NEW VALUE
        BRA MACSBUG
;JUST PRINT IT
SETR4   BSR.S PRINTR    ;FIX UP TO PRINT
        BRA MSG ;GO PRINT MESSAGE-GO TO MACSBUG
SETR5   BSR.S PRINTR    ;FIX UP TO PRINT
        MOVE.B #' ',(A6)+       ;SPACE
        MOVE.B #'?',(A6)+       ;PROMPT
        MOVE.B #' ',(A6)+       ;SPACE
        BSR OUTPUT      ;PRINT IT
        BSR.S GETINPUT  ;GO FILL INPUT BUFFER
        MOVE.L (A4),D0  ;DEFAULT VALUE
        BRA.S SETR7
; SEE IF;CHARACTER IS IN BUFFER
SCAN    MOVE.L A5,A0    ;A0 IS WORKING SCANNER
SCAN2   CMPA.L A6,A0    ;SEE IF AT END OF BUFFER
        BHI.S RETURN5
        CMP.B (A0),D0   ;LOOK AT CHARACTER
        BEQ.S RETURN5
        ADDA.L #1,A0    ;GET PAST CHARACTER
        BRA.S SCAN2
RETURN5  RTS
        PAGE
; ROUTINE TO SET UP TO PRINT REG
PRINTR  BSR FIXBUF
        ADDA.L #2,A6    ;GET PAST REG NAME
        MOVE.B #'=',(A6)+       ;PUT IN EQUAL SIGN
        MOVE.L (A4),D0  ;GET VALUE
        CMPA.L #REGSR,A4        ;SEE IF THIS IS CONDITION CODES
        BNE.S PRINTR2
        BSR PNT4HX      ;JUST PRINT WORD
        RTS
PRINTR2  BSR PNT8HX     ;PRINT THE VALUE
        RTS
;  TAKE IN INPUT ETC
GETINPUT BSR FIXBUF     ;SET UP BUFFER POINTERS
        BSR PORTIN1
        RTS
CHECKSR  CMPA.W #REGSR,A4       ;SEE IF STATUS REG
        BNE RETURN      ;
        CMPI.L #$FFFF,D0 ;SEE IF OVERFLOW
        BLE RETURN      ;RETURN IF OK
        BRA ERROR       ;OVERFLOW ON SR REG
        PAGE
;
;       PRINT ALL REGISTERS IN A CLASS (A OR D)
;
PNTCLSD MOVE.B #'D',D7  ;CLASS=DATA
        MOVE.L #REGS,A3 ;OFFSET
        BSR.S PNTCLS
        BRA MACSBUG
PNTCLSA MOVE.B #'A',D7  ;CLASS=ADDRESS
        MOVE.L #REGS+32,A3      ;OFFSET
        BSR.S PNTCLS
        BRA MACSBUG
PNTCLS  BSR FIXBUF
        CLR.L D6        ;REGISTER COUNTER
PNTCLS1 BSR.S PNTREG    ;PRINT THE REGISTER
        CMPI.B #4,D6    ;DISPLAY AFTER 3&7
        BNE.S PNTCLS2
        BSR OUT1CR
        BSR FIXBUF
        BRA.S PNTCLS1   ;DO SOME MORE
PNTCLS2 CMPI.B #8,D6    ;AT END?
        BNE.S PNTCLS1
        BSR OUT1CR      ;PRINT IT
        RTS                      
;
;       SUBROUTINE TO   ;PRINT REGISTER X#=12345678.
PNTREG  MOVE.B D7,(A6)+ ;CLASS
        MOVE.B D6,D0    ;REG#
        BSR PUTHEX
        MOVE.B #'=',(A6)+       ;EQUAL SIGN
        MOVE.L D6,D0    ;COMPUTE ADDRESS OF REG
        LSL.L #2,D0     ;MULT BY FOUR
        ADD.L A3,D0     ;ADD IN OFFSET
        MOVE.L D0,A4    ;SET UP TO GET DEFFERED
        CMPA.L #REGA7,A4        ;SEE IF REG A7
        BNE.S PNTREG1
        MOVE.L REGSR.W,D0 ;GET STATUS REGISTER
        ANDI.W #$2000,D0 ;CHECK SUPERVISOR BIT
        BNE PNTREG1
        MOVE.L #REGUS,A4        ;TAKE ADDRESS OF USER STACK
PNTREG1 MOVE.L (A4),D0  ;GET REG CONTENT
        BSR PNT8HX      ;PUT IN BUFFER
        MOVE.B #' ',(A6)+               ;SPACE
        ADDQ.L #1,D6    ;BUMP REG#
        RTS
        PAGE
;
;       SEQUENCE THROUGH A CLASS
;       PRINT & INPUT ALL REG BY CLASS
;
SEQCLSD MOVE.B #'D',D7  ;CLASS=DATA
        MOVE.L #REGS,A3 ;OFFSET
        BRA.S SEQCLS
SEQCLSA MOVE.B #'A',D7  ;CLASS=ADDRESS
        MOVE.L #REGS+32,A3      ;OFFSET
        BRA.S SEQCLS
SEQCLSB MOVE.B #'B',D7  ;CLASS=BREAKPOINTS
        MOVE.L #BPADD,A3        ;OFFSET
SEQCLS  CLR D6          ;REG WE ARE DOING
SEQCLS1 BSR FIXBUF      ;START A NEW LINE
        BSR.S PNTREG
        MOVE.W #'? ',(A6)+              ;PROMPT
        BSR OUTPUT      ;PRINT IT
        BSR GETINPUT
        MOVE.L (A4),D0  ;DEFAULT VALUE
        BSR GETNUMA
        BSR CHECKSR     ;SEE IF SR OVERFLOW
        MOVE.L D0,(A4)  ;SAVE NEW VALUE
        CMPI.B #8,D6    ;AT END??
        BNE.S SEQCLS1
        BRA MACSBUG     ;END OF ROUTINE
         PAGE
;
;       ***BR***        SET AND PRINT BREAKPOINTS
;
BCMD    MOVE.L #ROM+BCMD7-ZERO,A0       ;WHERE TO GO IF NO PARAMETERS
BCMD0   BSR FINDNP      ;SEARCH FOR NEXT PARAMETER
        LSL.L #8,D0     ;GET 4 BYTES
        MOVE.B 2(A5),D0
        LSL.L #8,D0
        MOVE.B 3(A5),D0
        CMPI.L #'CLEA',D0        ;SEE IF PART OF CLEAR
        BNE.S BCMD02
        MOVE.B 4(A5),D0 ;GET THE 'R'
        LSL.W #8,D0
        MOVE.B 5(A5),D0 ;GET THE SPACE
        CMPI.W #'R ',D0         ;MAKE SURE ITS 'CLEAR '
        BNE.S BCMD02
        BSR FIXBP       ;GET POINTERS
BCMD01  CLR.L (A0)+     ;CLEAR THE ADDRESS TABLE
        SUBQ.L #1,D7    ;DO IT 8 TIMES
        BNE.S BCMD01
        BRA MACSBUG
BCMD02  CLR.L D0        ;DEFAULT VALUE
        BSR GETNUMR     ;PULL NUMBER
        MOVE.L #ROM+BCMD3-ZERO,A1       ;WHERE TO JUMP TO
        BSR FIXBP       ;SET UP COUNTER & ADDRESS
BCMD00  CMP.L (A0),D0   ;SEE IF ALREADY IN TABLE
        BEQ.S BCMD33    ;GO CHECK FOR COUNT
        ADDA.L #4,A2    ;BUMP OTHER POINTER
        ADDA.L #4,A0    ;BUMP MAIN POINTER
        SUBQ.L #1,D7
        BNE.S BCMD00
        TST.L D0        ;SEE IF NEGATIVE(REMOVE BP)
        BPL.S BCMD1
        CLR.L D3        ;STORE A ZERO
        NEG.L D0        ;CHANGE BACK TO POSITIVE
        MOVE.L #ROM+BCMD4-ZERO,A1
BCMD1   BSR     FIXBP   ;GET ADDRESS & POINTERS
BCMD2   JMP (A1)        ;GO TO RIGHT ROUTINE
BCMD3   TST.L (A0)      ;FIND AN EMPTY STOP
        BNE.S BCMD5
        CLR.L (A2)      ;CLEAR THE COUNT
        MOVE.L D0,(A0)  ;PUT NEW ADDRESS IN TABLE
BCMD33  MOVE.B (A5),D1  ;CHECK OUT POSSIBLE COUNT
        CMPI.B #':',D1
        BNE.S BCMD6     ;NO COUNT
        ADDA.L #1,A5    ;BUMP THE BUFFER SCANNER
        CLR.L D0        ;DEFAULT VALUE
        BSR GETNUMA     ;GO GET THE COUNT
        MOVE.L D0,(A2)  ;MOVE TO TABLE
        BRA.S BCMD6
BCMD4   CMP.L (A0),D0   ;SEE IF ALREADY IN TABLE
        BNE.S BCMD5
        CLR.L (A0)      ;CLEAR IT WHEN FOUND
        BRA.S BCMD6
BCMD5   ADDA.L #4,A0    ;BUMP TABLE POINTER
        ADDA.L #4,A2    ;BUMP POINTER TO COUNTS
        SUBQ.L #1,D7    ;LOOP AROUND
        BNE.S BCMD2
        BSR FIXBUF      ;ERROR MESSAGE
        MOVE.L #'TABL',(A6)+
        MOVE.L #'E FU',(A6)+
        MOVE.L #'LL ',(A6)+
        BRA.S BCMD77
BCMD6   MOVE.L #ROM+MACSBUG-ZERO,A0     ;WHERE TO GO IF NO MORE PARAMETERS
        BRA BCMD0
;
BCMD7   BSR FIXBUF      ;PRINT BREAKPOINTS
BCMD77  MOVE.L #'BRKP',(A6)+    ;SET UP LEADER
        MOVE.L #'TS= ',(A6)+
        BSR.S FIXBP     ;SET ADDRESS & COUNTER
        MOVE.L #BPADD,A0        ;START OF TABLE
BCMD8   MOVE.L (A0)+,D0 ;GET ADDRESS
        MOVE.L (A2)+,D6 ;GET COUNT
        TST.L D0        ;SEE IF ZERO
        BEQ.S BCMD9
        BSR PNTZHX      ;PRINT WITH ZERO SURPRESS
        TST.L D6        ;SEE IF COUNT IS ZERO
        BEQ BCMD81      ;DONT PRINT ZERO COUNT
        MOVE.L D6,D0    ;GET READY FOR PRINT
        MOVE.B #':',(A6)+
        BSR PNTZHX      ;PRINT WITH ZERO SURPRESS
BCMD81  MOVE.B #' ',(A6)+               ;SPACE
BCMD9   SUBQ.L #1,D7    ;LOOP AROUND
        BNE.S BCMD8
        BRA MSG         ;PRINT MESSAGE-GO TO MACSBUG
FIXBP   MOVE.L #BPADD,A0        ;SET UP ADDRESS & COUNTER
        MOVEQ.L #8,D7   ;COUNTER
        MOVE.L #BPCNT,A2        ;COUNTS
        RTS
         PAGE
;
;       ***W#.L***      DEFINE A WINDOW
;
SETW    MOVE.B 1(A5),D0 ;GET WINDOW NUMBER
        MOVE.B D0,D6    ;SAVE ASCII FOR A WHILE
        BSR GETHEX
        CMPI.B #7,D0    ;SEE IF ABOVE 7
        BHI SYNTAX
        MULU #8,D0      ;COMPUTE WINDOW ADDRESS
        ADDI.W #WINDOWS,D0
        MOVE.L D0,A1    ;INDEXED ADDRESS OF WINDOW
        MOVE.L A5,D7    ;SAVE FOR AWHILE
        MOVE.L #ROM+PRINTW-ZERO,A0      ;WHERE TO GO IF NO PARAMETER
        MOVE.B 2(A5),D0 ;SEE IF LEN
        CMPI.B #'.',D0
        BNE.S SETW1
        MOVE.L #ROM+SETW11-ZERO,A0      ;WHERE TO GO
SETW1   BSR FINDNP      ;SEE IF ANOTHER PARAMETER
SETW11  MOVE.L D7,A5    ;YES THERE WAS PARAMETER (OR LEN)
        CLR.L (A1)      ;CLEAR IT ALL OUT
        CLR.L 4(A1)     ;DISPLACMENT
        MOVE.B 2(A5),D0 ;SEE IF .LEN
        CMPI.B #'.',D0  ;CHECK FOR DECMAL POINT
        BNE.S SETW2
        MOVE.B 3(A5),D0 ;GET SIZE 1,2,3,4
        BSR GETHEX
        CMPI.B #4,D0    ;SEE IF >4
        BHI SYNTAX      ;ERROR IF IT IS
        MOVE.B D0,(A1)  ;SAVE SIZE
        TST.B D0        ;SEE IF IT WAS ZERO
        BEQ MACSBUG
SETW2   MOVE.L #ROM+ERROR-ZERO,A0       ;WHERE TO GO IF NO PARATMER
        BSR FINDNP      ;SET A5 TO NEXT PARAMETER
SETW22  MOVE.B (A5),D0  ;LOOK AT NEXT CHAR
        CMPI.B #'(',D0  ;SEE IF NO DISPLACMENT
        BEQ.S SETW3
        CLR.L D0        ;DEFAULT DISPLACMENT
        BSR GETNUMA
        MOVE.L D0,4(A1) ;SAVE DISPLACMENT
SETW3   MOVE.B (A5),D0  ;SEE WHAT REGISTER
        CMPI.B #'(',D0  ;SEE IF DEFERED STUFF
        BNE MACSBUG     ;IF NOT LEFT PAREN-END
        ADDA.L #1,A5    ;GET PAST '('
        MOVE.B (A5)+,D0 ;GET FIRST CHAR OF POSSIBLE REGISTER
        CMPI.B #'*',D0  ;SEE IF PC
        BNE.S SETW4
        MOVE.B D0,1(A1) ;FLAG AS PC
        BRA.S SETW6
SETW4   CMPI.B #'A',D0  ;MUST BE ADDRESS REGISTER
        BNE SYN1        ;ERROR
        MOVE.B (A5)+,D0 ;GET ADD REG NUMBER
        MOVE.B D0,1(A1) ;SAVE NUMBER (ASCII)
        BSR GETHEX      ;GET ADDRESS REG NUMBER
        CMPI.B #7,D0    ;SEE IF IN RANGE
        BHI SYN1        ;ERROR
SETW6   MOVE.B (A5)+,D0 ;CHECK NEXT BYTE OF BUFFER
        CMPI.B #',',D0  ;IF COMMA GO ON
        BEQ.S SETW9
        CMPI.B #')',D0  ;IF RIGHT PAREN ITS OK
        BEQ MACSBUG
        BRA SYN1
SETW9   MOVE.B (A5)+,D0 ;GET FIRST CHAR OF REGISTER
        CMPI.B #'A',D0  ;MUST BE 'A' OR 'D'
        BEQ.S SETW8
        CMPI.B #'D',D0
        BNE SYN1
SETW8   MOVE.B D0,2(A1) ;SAVE REG TYPE
        MOVE.B (A5)+,D0
        MOVE.B D0,3(A1) ;SAVE NUMBER
        BSR GETHEX
        CMPI.B #7,D0    ;SEE IF IN RANGE
        BHI.S SYN1
        BRA MACSBUG
;
SYN1    CLR.L (A1)      ;JUST CLEAR THE WHOLE THING
        BRA SYNTAX
        PAGE
;
;       PRINT A WINDOW AS W#    DEFINATION=ADDRESS
;
PRINTW  MOVE.B BUFFER+2.W,D5      ;SAVE POSSIBLE ':'
        BSR FIXBUF      ;A5,A6=#BUFFER
        MOVE.B #'W',(A6)+
        MOVE.B D6,(A6)+ ;NUMBER
        MOVE.B #'.',(A6)+       ;READY FOR LENGTH
        MOVE.B (A1),D0  ;GET LENGTH
        BSR PUTHEX      ;PRINT 1 HEX CHAR
        MOVE.W #' ',(A6)+
        TST.B (A1)      ;SEE IF LENGTH IS ZERO
        BNE.S PRINTW00
        MOVE.L #'????',(A6)+    ;SAY IT IS UNDEFINED
        BRA PRINTW99    ;GO PRINT IT
PRINTW00 TST.L 4(A1)    ;SEE IF ANY DISPLACMENT
        BEQ.S PRINTW1
        MOVE.L 4(A1),D0 ;GET HEX CONSTANT DISPLACMENT
        BSR PNTZHX      ;PRINT WITH SIGN AND ZERO SURPRESS
PRINTW1 MOVE.B 1(A1),D0 ;GET ADDRESS REGISTER NUMBER
        BEQ PRINTW99    ;IF ZERO-PRINT IT ETC
        MOVE.B #'(',(A6)+       ;SET UP FOR DEFFERED STUFF
        CMPI.B #'*',D0  ;SEE IF PROGRAM COUNTER
        BNE.S PRINTW3
        MOVE.B D0,(A6)+ ;JUST PUT IN '*'
        BRA.S PRINTW4
PRINTW3 MOVE.B #'A',(A6)+       ;FOR ADDRESS REG
        MOVE.B D0,(A6)+ ;FOR REG NUMBER
PRINTW4 MOVE.B 2(A1),D0 ;SEE IF INDEX REGISTER USED
        BEQ.S PRINTW8
        MOVE.B #',',(A6)+       ;COMMA
        MOVE.B D0,(A6)+ ;INDEX TYPE
        MOVE.B 3(A1),(A6)+      ;INDEX NUMBER
PRINTW8 MOVE.B #')',(A6)+       ;CLOSE PAREN
PRINTW9 BSR WINDA       ;GO GET ADDRESS INTO A0,D3
        MOVE.L D3,D0    ;GET READY FOR PRINT-HEX
        MOVE.B #'=',(A6)+       ;PUT IN EQUAL SIGN
        BSR PNTZHX      ;PRINT WITH ZERO SURPRESS
PRINTW99 BSR OUTPUT     ;GO PRINT IT
        BSR FIXBUF      ;SET UP BUFFER
        MOVE.B #' ',(A6)+
        CMPI.B #':',D5  ;SEE IF INPUT NEEDED
        BNE MSG ;
        MOVE.B #'=',(A6)+
        MOVE.B #'?',(A6)+
        MOVE.B #' ',(A6)+
        BSR OUTPUT      ;PRINT PROMPT
        BSR FIXBUF
        BSR PORTIN1     ;GO GET NEW VALUE
        CMPA.L A6,A5    ;SEE IF ANYTHING ENTERED
        BEQ MACSBUG
        BRA SETW22      ;GO DECODE INPUT
;
;       SUBROUTINE TO COMPUTE ADDRESS OF WINDOW
;       A1 POINTS TO WINDOW TABLE OF PARTICULAR WINDOW
;
WINDA   MOVE.L 4(A1),D3 ;GET DISPLACMENT
        CLR.L D0        ;SET UP FOR REGISTER COMPUTATION
        MOVE.B 1(A1),D0 ;GET REGISTER NUMBER OR *
        BEQ.S WINDA99   ;DONE IF NOTHING HERE
        CMPI.B #'*',D0  ;SEE IF PC
        BNE.S WINDA3
        ADD.L REGPC.W,D3        ;ADD IN PROGRAM COUNTER
        BRA.S WINDA6
WINDA3  MOVE.L #REGS+32,A0      ;GET BASE OF ADD REGS
        ANDI.W #$F,D0    ;SAVE ONLY BOTTOM NIBBLE
        ASL #2,D0       ;MULT BY 4
        ADD.L 0(A0,D0),D3       ;ADD IN ADDRESS REGISTER
WINDA6  MOVE.B 2(A1),D0 ;SEE WHAT INDEX LOOKS LIKE
        BEQ.S WINDA99   ;END IF NONE
        MOVE.L #REGS,A0 ;BASE FOR DATA REGS
        CMPI.B #'A',D0  ;SEE IF ADDRESS REG
        BNE.S WINDA4
        ADDA.W #32,A0   ;GET PAST DATA REG TO ADD REG
WINDA4  CLR.L D0        ;SET UP INDEX
        MOVE.B 3(A1),D0 ;INDEX NUMBER
        ANDI.W #$F,D0    ;SAVE ONLY BOTTOM NIBBLE
        ASL.W #2,D0     ;MULT BY 4
        ADD.L 0(A0,D0),D3       ;ADD IN INDEX
WINDA99 MOVE.L D3,A0    ;ALSO PUT IN ADDRESS REGISTER
        MOVE.L D3,D0    ;ALSO SET UP TO PRINT IT
        RTS             ;END OF ROUTINE
        PAGE
;
;       GET MEMORY THROUGH WINDOW
;       A0=MEMORY START (COMPUTED WITH WIND)
;       A1=POINTER TO WINDOW TABLE ENTRY
WINDM   CLR.L D1        ;USED FOR COUNTER
        CLR.L D0        ;HOLDS RESULTS
        MOVE.B (A1),D1  ;GET LENGTH 1,2,3,4
        BEQ.S WINDM9    ;ZERO LENGTH=UNDEFINED
WINDM1  ASL.L #8,D0     ;MAKE ROOM FOR NEW BYTE
        MOVE.B (A0)+,D0 ;GRAB NEW BYTE
        SUBQ.L #1,D1    ;LOOP AROUND
        BNE.S WINDM1
WINDM9  RTS
;
;
;       ***M#***        SET MEMORY THROUGH WINDOW
;
SETMW   MOVE.W (A5),D0  ;COMPUTE WINDWOW TABLE ENTRY
        ANDI.L #$F,D0    ;ASCII TO BINARY
        MULU #8,D0      ;8 BYTES PER ENTRY
        ADDI.W #WINDOWS,D0       ;ADD IN BASE
        MOVE.L D0,A1    ;USED AS MASTER INDEX
        TST.B (A1)      ;SEE IF DEFINED
        BNE.S SETMW1
        BSR FIXBUF
        MOVE.L #'NOT ',(A6)+
        MOVE.L #'DEFI',(A6)+
        MOVE.L #'NED ',(A6)+
        BRA MSG
SETMW1  MOVE.L #ROM+SETMP-ZERO,A0       ;WHERE TO GO IF NO PARAMETER
        BSR FINDNP      ;SEE IF DATA IS OUT THERE
SETMW2  BSR GETNUMA     ;GO GET DATA
        MOVE.L D0,TEMP.W        ;SAVE DATA HERE
        BSR WINDA       ;GET ADDRESS INTO A0
        MOVE.L #TEMP+4,A2       ;USED FOR INDEX
        CLR.L D0        ;USED FOR COUNT
        MOVE.B (A1),D0  ;GET LENGTH
        ADDA.L D0,A0    ;ADD LENGTH TO ADDRESS
SETMW3  MOVE.B -(A2),-(A0)      ;TRANSFER BYTE
        MOVE.B (A2),D1  ;RE-READ DATA
        CMP.B (A0),D1   ;SEE IF SAME
        BNE ERROR
        SUBQ.L #1,D0    ;LOOP AROUND
        BNE.S SETMW3
        BRA MACSBUG     ;END OF ROUTINE
;
;
SETMP   MOVE.B BUFFER+2.W,D4    ;GET POSSIBLE ':'
        BSR WINDA       ;GET EFFECTIVE ADDRESS
;
        BSR WINDM       ;GET MEMORY THROUGH WINDOW (ADDA.X TYPE TEQH.)
;
        BSR FIXBUF
        ADDA.L #2,A6    ;GET PAST 'W#'
        MOVE.B #'=',(A6)+       ;SET UP TO PRINT CONTENTS
        MOVE.B (A1),D3  ;GET LENGTH
        MOVE.L #ROM+PNT2HX-ZERO,A4      ;WHERE TO GO IF ONE BYTE
        CMPI.B #1,D3    ;SEE IF SIZE IS ONE
        BEQ.S SETMP5
        MOVE.L #ROM+PNT4HX-ZERO,A4
        CMPI.B #2,D3    ;SEE IF SIZE IS TWO
        BEQ.S SETMP5
        MOVE.L #ROM+PNT6HX-ZERO,A4
        CMPI.B #3,D3    ;SEE IF SIZE IS THREE
        BEQ.S SETMP5
        MOVE.L #ROM+PNT8HX-ZERO,A4
SETMP5  JSR (A4)        ;GO INDIRECT
        BSR OUTPUT      ;GO PRINT IT
        BSR FIXBUF      ;SET UP BUFFER
        MOVE.B #' ',(A6)+
        CMPI.B #':',D4  ;SEE IF INPUT NEEDED
        BNE MSG ;
        MOVE.B #'=',(A6)+       ;THIS IS THE PROMPT
        MOVE.B #'?',(A6)+
        MOVE.B #' ',(A6)+
        BSR OUTPUT
        BSR FIXBUF
        BSR PORTIN1     ;GO GET INPUT
        CMPA.L A6,A5    ;SEE IF ANYTHING INPUT
        BEQ MACSBUG
        BRA SETMW2      ;GO DECODE IT
        PAGE
;
;       ***SY***        SET SYMBOL TABLE VALUES ETC
;
SYCMD   BSR SCANPORT    ;SEE WHERE TO SEND OUTPUT
        MOVE.L #ROM+SYMPA-ZERO,A0       ;CHANGE WHEN PRINT AVAILABLE
        BSR FINDNP      ;POINT TO NEXT PARAMETER
        CLR.L D5        ;SET UP FOR DELETE?
        MOVE.B (A5),D0  ;SEE IF DELETE
        CMPI.B #'-',D0
        BNE.S SY0
        MOVE.B (A5)+,D5 ;FLAG AS DELETE
SY0     BSR GETSY       ;GO GET SYMBOL INTO D6,D7
        TST D6  ;SEE IF SYMBOL
        BEQ SYHEX       ;NOT SYMBOL...SEE IF HEX NUMBER
        CMPI.B #'-',D5  ;SEE IF DELETE
        BEQ SYMOUT
        CMPA.L A6,A5
        BPL.S SY00
        MOVE.B (A5)+,D0 ;SCAN FOR ':'
        CMPI.B #':',D0
        BEQ SY5
SY00    MOVE.L #ROM+SY6-ZERO,A0 ;WHERE TO GO IF NO PARAMETER (SYMBOL VALUE)
        BSR FINDNP      ;SEARCH FOR PARAMETER
        CLR.L D0        ;DEFAULT VALUE
        BSR GETNUMA
        MOVE.L D0,D5    ;SAVE IT HERE FOR AWHILE
        MOVE.L #ROM+SY4-ZERO,A0 ;WHERE TO GO IF IN TABLE
        BSR SSYMTAB     ;SEACH IN TABLE
        MOVE.L ENDSYM.W,A0        ;END OF SYMBOL TABLE
        MOVE.L D6,(A0)+ ;SAVE NEW SYMBOL
        MOVE.L D7,(A0)+
        MOVE.L D5,(A0)+ ;SAVE VALUE
        MOVE.L A0,ENDSYM.W      ;SAVE NEW END OF TABLE
        BSR SYMSRT      ;MAINTAIN IN SORTED ORDER
        BRA MACSBUG
;
;       DELETE A SYMBOL FROM TABLE
;
SYMOUT  MOVE.L STRSYM.W,A0        ;START OF TABLE
SYMOUT1 CMPA.L ENDSYM.W,A0      ;CHECK END OF TABLE
        BEQ NOTFOUND
        CMP.L (A0),D6   ;CHECK 1ST 4 BYTES
        BNE.S SYMOUT2
        CMP.L 4(A0),D7  ;CHECK 2ND 4 BYTES
        BEQ.S SYMOUT3
SYMOUT2 ADDA.L #12,A0   ;BUMP POINTER
        BRA.S SYMOUT1
SYMOUT3 MOVE.L ENDSYM.W,D0      ;BACK UP END OF TABLE
        SUBI.L #12,D0
        MOVE.L D0,ENDSYM.W      ;SAVE IT
SYMOUT4 MOVE.L 12(A0),(A0)      ;CATIPILLIAR BACK
        MOVE.L 16(A0),4(A0)
        MOVE.L 20(A0),8(A0)
        ADDA.L #12,A0   ;BUMP POINTER
        CMPA.L D0,A0
        BLT.S SYMOUT4
        BRA MACSBUG     ;DONE
;
SY4     MOVE.L D5,-(A1) ;PUT VALUE IN EXISTING ENTRY
        BRA MACSBUG
;
;       SY hex ?        SEE IF USER IS ASKING FOR SYMBOL FROM HEX VALUE
;
SYHEX   MOVE.L #BUFFER,A5       ;RESTORE FIRST PART
        BSR FINDNP      ;NOW POINT TO POSSIBLE hex VALUE
        BSR GETNUMA     ;GET A VALUE OR ERROR OUT
        BSR SNUMTAB     ;SEARCH TABLE FOR VALUE
        BRA SY61        ;GO PRINT IT
;
;       ':'     PRINT AND QUE FOR INPUT
SY5     MOVE.L #ROM+SY51-ZERO,A0
        BSR SSYMTAB     ;SEARCH SYMBOL TABLE
NOTFOUND BSR FIXBUF     ;
        MOVE.L #'NOT ',(A6)+
        MOVE.L #'FOUN',(A6)+
        MOVE.W #'D ',(A6)+
        BRA MSG
SY51    BSR SYP ;PRINT THE SYMBOL
        BSR FIXBUF      ;SET UP FOR PROMPT
        MOVE.W #' ?',(A6)+              ;PRINT PROMPT
        BSR OUTPUT
        BSR FIXBUF      ;SET UP FOR INPUT
        BSR PORTIN1     ;TAKE IN INPUT
        CMPA.L A6,A5    ;SEE IF ANYTHING ENTERED
        BEQ MACSBUG
SY58    CLR.L D0        ;GO GET THE NUMBER
        BSR GETNUMA
        MOVE.L D0,-(A1) ;SAVE NEW DATA
        BRA MACSBUG
;
;       IF YOU CAN FIND IT-PRINT IT
SY6     MOVE.L #ROM+SY61-ZERO,A0        ;IF FOUND GO HERE
        BSR SSYMTAB     ;SEARCH SYMBOL TABLE
        BSR FIXBUF      ;PUT IT BACK OUT
        MOVE.L D6,(A6)+
        MOVE.L D7,(A6)+
        MOVE.W #' ',(A6)+               ;PUT IN SOME SPACES
        BSR GETNUMA     ;GET A NUMBER OUT OF IT
        BSR SNUMTAB     ;SEARCH FOR NUMBER IN TABLE
SY61    BSR.S SYP       ;PRINT IT
        BSR FIXBUF      ;TERMINATE LINE
        BRA MSG
;
SYP     BSR FIXBUF      ;PRINT THE SYMBOL & VALUE
        MOVE.L D6,(A6)+ ;PUT SYMBOL IN BUFFER
        MOVE.L D7,(A6)+
        MOVE.B #'=',(A6)+
        BSR PNTZHX      ;PUT IN VALUE
        MOVE.B #$20,D0  ;SPACE
SYP0    CMP.B (A5),D0   ;CHECK FOR LEADING SPACE
        BNE.S SYP1
        ADDA.L #1,A5    ;GET PAST IT
        BRA.S SYP0
SYP1    BSR OUTPUT
        RTS
;
;       SEARCH SYMBOL TABLE FOR A SYMBOL
;       D6 & D7 HAVE SYMBOL     RETURNS VALUE IN D0
;
SSYMTAB MOVE.L STRSYM.W,A1      ;START OF TABLE
SSYMTAB1 CMPA.L ENDSYM.W,A1     ;SEE IF AT END
        BLT.S SSYMTAB2
        RTS                     ;NOT IN TABLE
SSYMTAB2 MOVE.L (A1)+,D1        ;READ FROM TABLE
        MOVE.L (A1)+,D2
        MOVE.L (A1)+,D0
        CMP.L D6,D1     ;SEE IF IT MATCHES
        BNE.S SSYMTAB1
        CMP.L D7,D2
        BNE.S SSYMTAB1
        JMP (A0)        ;WHERE TO GO IF FOUND IN TABLE
;
;       SEARCH THE SYMBOL TABLE FOR A VALUE
;       VALUE IN D0     RETURNS D6 & D7 = SYMBOL OR
;       8 ASCII DIGITS OF HEX VALUE IF NOT FOUND
;
SNUMTAB MOVEM.L D0-D2/A1/A6,-(A7)       ;SAVE SOME WORKING REGISTERS
        MOVE.L STRSYM.W,A1      ;START OF TABLE
SNUMTAB0 CMPA.L ENDSYM.W,A1     ;SEE IF AT END OF TABLE
        BLT.S SNUMTAB1  ;WHERE TO GO IF NOT END
        MOVE.L #WORK1,A6        ;FIX UP SMALL BUFFER
        BSR PNT8HX      ;PUT IN 8 CHARACTERS OF HEX
        MOVE.L WORK1.W,D6       ;READ ASCII INTO RETURN PLACE
        MOVE.L WORK2.W,D7
        BRA.S SNUMTAB9
SNUMTAB1 MOVE.L (A1)+,D6        ;SYMBOL NAME
        MOVE.L (A1)+,D7 ;MORE NAME
        MOVE.L (A1)+,D2 ;SYMBOL VALUE
        CMP.L D2,D0     ;SEE IF SAME VALUE
        BNE.S SNUMTAB0  ;GO DO SOME MORE
        BSR NORM1       ;LEFT JUSTIFY NAME
SNUMTAB9 MOVEM.L (A7)+,D0-D2/A1/A6      ;RESTORE REGISTERS
        RTS
;
;       PRINT THE WHOLE SYMBOL TABLE
;
;       (SORT IT FIRST)
;
SYMPA   BSR SYMSRT      ;SORT THE TABLE AGAIN
        MOVE.L STRSYM.W,A0      ;START OF TABLE
SYMPA1  MOVEQ.L #3,D5   ;COUNTER
        BSR FIXBUF
SYMPA2  CMPA.L ENDSYM.W,A0        ;AT END OF TABLE
        BGE MSG
        MOVE.L (A0)+,D6 ;GET SYMBOL
        MOVE.L (A0)+,D7
        BSR NORM1       ;RIGHT JUSTIFY
        MOVE.L D6,(A6)+ ;PUT IN PRINT BUFFER
        MOVE.L D7,(A6)+
        MOVE.W #' ',(A6)+               ;SPACE
        MOVE.L (A0)+,D0 ;GET VALUE
        BSR PNT8HX      ;PRINT IT
        MOVE.L #' ',(A6)+               ;SPACES
        SUBQ.L #1,D5    ;LOOP
        BNE.S SYMPA2
        BSR OUT1CR      ;PRINT BUFFER
        BRA.S SYMPA1
;
;       SORT THE SYMBOL TABLE
;
SYMSRT  MOVE.L STRSYM.W,A0      ;START OF TABLE
SYMSRT0 CMPA.L ENDSYM.W,A0      ;SEE IF AT END
        BLT.S SYMSRT1
        RTS             ;END OF SORT    
SYMSRT1 MOVE.L A0,A1    ;POINT TO NEXT ENTRY
SYMSRT2 ADDA.L #12,A1
        CMPA.L ENDSYM.W,A1      ;SEE IF AT END
        BLT SYMSRT3
        ADDA.L #12,A0   ;BUMP TOP POINTER
        BRA.S SYMSRT0
SYMSRT3 MOVE.L (A0),D6  ;GET TOP SYMBOL
        MOVE.L 4(A0),D7
        BSR NORM1       ;RIGHT JUSTIFY
        MOVE.L D6,D1
        MOVE.L D7,D2
        MOVE.L (A1),D6  ;2ND SYMBOL
        MOVE.L 4(A1),D7
        BSR.S NORM1     ;RIGHT JUSTIFY
        CMP.L D6,D1     ;COMPARE
        BLT.S SYMSRT2
        BGT.S SYMSRT4
        CMP.L D7,D2     ;CHECK LEAST SIGNIFICANT
        BLT.S SYMSRT2
SYMSRT4 MOVE.L (A0),D0  ;EXCHANGE
        MOVE.L 4(A0),D1
        MOVE.L 8(A0),D2
        MOVE.L (A1),(A0)
        MOVE.L 4(A1),4(A0)
        MOVE.L 8(A1),8(A0)
        MOVE.L D0,(A1)
        MOVE.L D1,4(A1)
        MOVE.L D2,8(A1)
        BRA.S SYMSRT2
;
;       NORMALIZE SYMBOL IN D6,D7
;       SYMBOLS ARE RIGHT JUSTIFIED IN THE TABLE
;       THIS LEFT JUSTIFIES THEM IN THE REGISTER PAIR
;
NORM1   CMPI.L #'    ',D6               ;SEE IF ALL SPACES
        BNE NORM0       ;
        CMPI.L #'    ',D7
        BEQ RETURN
NORM0   MOVE.L D6,D0    ;RIGHT JUSTIFY SYMBOL
        SWAP D0
        LSR.W #8,D0     ;SEE IF LEADING SPACE
        CMPI.B #$20,D0
        BEQ.S NORM2
        RTS
NORM2   MOVE.L D7,VECTOR.W
        LSL.L #8,D6
        MOVE.B VECTOR.W,D6
        LSL.L #8,D7
        MOVE.B #$20,D7  ;TRAILING BLANK
        BRA.S NORM1
        PAGE 
;
;
;       ***CALL***      CALL TO USER ADDRESS
;
USERCALL BSR WHATNUM    ;GO GET ADDRESS OR PRINT WHAT
        MOVE.L D0,A0    ;PUT ADDRESS IN ADDRESS REG
        JSR (A0)        ;GO TO USER ADDRESS
        BRA MACSBUG     ;USER RETUNS HERE-REENTER MACSBUG
        PAGE
;
;       ***TD***        SET TRACE DISPLAY FORMAT
;
RCMD    CLR.L D7        ;FLAG FO ANY DONE?
        ADDA.L #2,A5    ;GET PAST 'TD'
R1      CMPA.L A6,A5    ;SEE IF AT END OF BUFFER
        BLE.S R11
        TST.L D7        ;SEE IF ANY DONE
        BNE.S R10
        BSR TDISPLY     ;JUST LETTER R ENTERED MEANS DISPLAY
R10     BRA MACSBUG
R11     MOVE.B (A5)+,D0 ;GET 1ST CHAR
        CMPI.B #' ',D0          ;IGNORE SPACES
        BEQ.S R1
        CMPI.B #',',D0  ;IGNORE COMMAS
        BEQ.S R1
        ASL.W #8,D0     ;SHIFT LEFT ONE BYTE
        MOVE.B (A5)+,D0 ;PICK UP 2ND LETTER
        CMPI.W #'AL',D0 ;SEE IF COMMAND 'AL'(L)
        BNE.S R2
        MOVE.L #'----',ADALL.W  ;SPECIAL FORMATS
        MOVE.W #$302,FORMAT.W   ;PC & SR        
        MOVE.W #$4040,FORMAT+18.W       ;SS & US
        BRA MACSBUG
R2      CMPI.W #'CL',D0 ;SEE IF COMMAND 'CL'(EAR)
        BNE.S R3
        CLR.L ADALL.W   ;SPECIAL FORMATS
        CLR.L D0
        MOVEQ.L #36,D2  ;SET ALL OFF
        BRA REGALL
R3      MOVE.L #ROM+REGNAMES-ZERO,A0    ;REGISTER NAMES TABLE
        MOVE.L #FORMAT,A1       ;FORMAT-(LENGTH) TABLE
R4      MOVE.W (A0)+,D1 ;GET REG NAME
        CMPI.W #'??',D1 ;SEE IF AT END OF TABLE
        BNE.S R43
        BSR FIXBUF      ;SET UP FOR ERROR MESSAGE
        MOVE.L #'WHAT',(A6)+
        MOVE.L #' IS ',(A6)+
        MOVE.W D0,(A6)+
        MOVE.B #'?',(A6)+
        BRA MSG ;GO PRINT BUFFER 
;       TEST SOME SPECIAL CASES
;                THIS 'L.' IMPLIES BOARDER BETWEEN TRACE DISPLAYS
R43     CMPI.W #'L.',D0 ;IMPLIES LINE
        BNE.S R45
        MOVE.B (A5)+,ADALL+2.W  ;THIS IS WHAT BOARD WILL BE
        BRA R61
R45     CMPI.W #'D.',D0 ;IMPLIES ALL DATA REGISTERS
        BNE.S R46
        MOVE.L #ADALL,A1        ;GET ADDRESS OF FORMAT THING
        BRA.S R51
R46     CMPI.W #'A.',D0 ;IMPLIES ALL ADDRESS REGISTERS
        BNE.S R47
        MOVE.L #ADALL+1,A1      ;GET ADDRESS OF FORMAT THING
        BRA.S R51
R47     CMP.W D1,D0     ;SEE IF NAME IS SAME
        BEQ.S R5
        ADDA.L #1,A1    ;BUMP FORMAT TABLE
        BRA.S R4
R5      MOVE.B #4,(A1)  ;DEFAULT TO 4 BYTES
        ADDQ.L #1,D7    ;FLAG AS REG DEF MODE
        MOVE.B (A5)+,D0 ;SEE IF DECIMAL POINT
        CMPI.B #'.',D0
        BNE R1
R51     MOVE.B (A5)+,D0 ;GET FORMAT NUMBER
        CMPI.B #'Z',D0  ;SEE IF ZERO SURPRESS
        BEQ.S R6
        CMPI.B #'R',D0  ;SEE IF RELATIVE
        BEQ.S R6
        CMPI.B #'D',D0  ;SEE IF DECIMAL
        BEQ.S R6
        CMPI.B #'S',D0  ;SEE IF SYMBOLIC
        BEQ.S R6
        BSR GETHEX
        CMPI.B #4,D0
        BLE.S R6
        MOVEQ.L #2,D0   ;ERROR NUMBER 2 SIZE TOO LARGE
        BGT ERROR
;
R6      MOVE.B D0,(A1)  ;SAVE FORMAT
R61     MOVEQ.L #1,D7   ;SOMETHING DEFINED
        BRA R1  ;GO DO NEXT ONE
REGALL  MOVE.L #FORMAT,A0       ;SET UP SCANNER
REGALL2 MOVE.B D0,(A0)+
        SUBQ.L #1,D2
        BNE.S REGALL2
        BRA MACSBUG
REGNAMES DATA.L 'PCSR'  ;TABLE OF NAMES OF REGISTERS
        DATA.L 'D0D1'
        DATA.L 'D2D3'
        DATA.L 'D4D5'
        DATA.L 'D6D7'
        DATA.L 'A0A1'
        DATA.L 'A2A3'
        DATA.L 'A4A5'
        DATA.L 'A6A7'
        DATA.L 'USSS'
        DATA.L 'W0M0'
        DATA.L 'W1M1'
        DATA.L 'W2M2'
        DATA.L 'W3M3'
        DATA.L 'W4M4'
        DATA.L 'W5M5'
        DATA.L 'W6M6'
        DATA.L 'W7M7'
        DATA.W '??'
        PAGE
;
;       PRINT TRACE DISPLAY SUBROUTINE
;
TDISPLY BSR FIXBUF      ;PRINT PRELUDE
        MOVE.L SCREEN1.W,(A6)+
        BSR OUTPUT
        MOVE.L #FORMAT,A3       ;FORMAT BYTES
        MOVE.L #ROM+REGNAMES-ZERO,A4    ;REGISTER NAMES
        MOVE.L #REGPC,A2        ;REGISTER DATA
TD0     BSR FIXBUF      ;SUT UP I/O BUFFER
TD1     MOVE.L A6,D0    ;CALCUATE BUFFER LENGTH
        SUB.L A5,D0     ;SEE IF FULL
        CMPI.W #64,D0   ;BUFFER FULL IF 64 CHAR?
        BLE.S TD2
        BSR OUT1CR      ;PRINT FULL BUFFER
        BRA.S TD0
TD2     MOVE.W (A4)+,D0 ;GET REG NAME
        MOVE.B (A3)+,D1 ;GET FORMAT
        MOVE.L (A2)+,D7 ;GET REG CONTENT
        CMPI.W #'??',D0 ;SEE IF AT END OF REGS
        BNE.S TD4
        CMPA.L A6,A5    ;AT END SEE IF PRINT NEEDED
        BEQ.S TD21
        BSR OUT1CR      ;PRINT BUFFER
TD21    TST.B ADALL.W   ;SEE IF D REGS NEED PRINTING
        BEQ.S TD25
        MOVE.B #'D',D7  ;CLASS=DATA
        MOVE.L #REGS,A3 ;OFFSET
        BSR PNTCLS      ;GO PRINT THE BLOCK
TD25    TST.B ADALL+1.W ;SEE IF A REGS NEED PRINTING
        BEQ.S TD26
        MOVE.B  #'A',D7 ;CLASS=ADDRESS
        MOVE.L #REGS+32,A3      ;OFFSET
        BSR PNTCLS      ;GO PRINT THE BLOCK
TD26    MOVE.B ADALL+2.W,D0     ;CHECK FOR BOARDER
        BEQ.S TD3
        CMPI.B #'0',D0  ;ZERO=NO BOARDER
        BEQ.S TD3
        BSR FIXBUF
        MOVEQ.L #64,D1  ;LOOP COUNTER
TD27    MOVE.B D0,(A6)+ ;FILL BUFFER WITH BOARDER
        SUBQ.L #1,D1
        BNE.S TD27
        BSR OUT1CR      ;PRINT BOARDER
TD3     BSR FIXBUF      ;PRINT END STUFF FOR SCREEN CONTROL
        MOVE.L SCREEN2.W,(A6)+
        BSR OUTPUT
        RTS             ;RETURN FOR MORE WORK
TD4     CMPI.B #0,D1    ;SEE IF ZERO FORMAT
        BEQ.S TD1       ;JUST SKIP IT
        MOVE.W D0,D2    ;PRINT REG NAME IN BUFFER
        ASR.W #8,D0     ;MOVE IT OVER
        MOVE.B D0,D3    ;SAVE REGISTER TYPE A,D,W,M ETC
        MOVE.B D0,(A6)+ ;SAVE FIRST LETTER
        MOVE.B D2,(A6)+ ;SAVE NEXT LETTER
        MOVE.B #'=',(A6)+       ;EQUAL SIGN
        CMPI.W #'A7',D2 ;SEE IF IRREGULAR STACK STUFF
        BNE.S T44
        MOVE.L REGSR.W,D0       ;GET STATUS
        ANDI.W #$2000,D0 ;CHECK SUPERVISOR
        BNE.S T448      ;IS SUPER
        MOVE.L REGUS.W,D0       ;IS NOT SUPER
        BRA.S T449
T44     CMPI.W #'SS',D2 ;SUPER STACK IS SPECIAL
        BNE.S T448
        MOVE.L REGA7.W,D0       ;GET A7
        BRA.S T449
T448    MOVE.L D7,D0    ;REGISTER VALUE
        CMPI.B #'W',D3  ;SEE IF IT IS A WINDOW
        BEQ.S TDW1
        CMPI.B #'M',D3  ;SEE IF MEMORY
        BNE.S T449
TDW1    MOVE.L D1,D6    ;SAVE FORMAT
        MOVE.B D3,D7    ;SAVE CLASS 'M' OR 'W'
        ANDI.L #$F,D2    ;COMPUTE MEMORY WINDOW TABLE
        MULU #8,D2      ;FROM REGISTER NUMBER
        ADDI.W #WINDOWS,D2
        MOVE.L D2,A1    ;POINTS TO TABLE ENTRY-6BYTES
        TST.B (A1)      ;SEE IF DEFINED
        BNE.S TDW2
        SUBA.L #4,A6    ;BACK UP        .M0=    4 SPOTS
        BRA TD9 ;PUT BACK IN SPACE
TDW2    BSR WINDA       ;GET ADDRESS INTO D3,D0,A0
        CMPI.B #'W',D7  ;IF WINDOW-PRINT ADDRESS
        BEQ.S TDW9
        BSR WINDM       ;GET CONTENT INTO DO
TDW9    MOVE.L D6,D1    ;RESTORE FORMAT
T449    CMPI.B #1,D1    ;SEE IF #1 FORMAT
        BNE.S TD5
T44A    BSR PNT2HX
        BRA.S TD9
TD5     CMPI.B #2,D1    ;SEE IF #2 FORMAT
        BNE.S TD6
TD51    BSR PNT4HX
        BRA.S TD9
TD6     CMPI.B #3,D1    ;SEE IF #3 FORMAT
        BNE.S TD7
TD61    BSR PNT6HX
        BRA.S TD9
TD7     CMPI.B #'Z',D1  ;SEE IF ZERO SURPRESS
        BNE.S TD71
        BSR PNTZHX      ;PRINT WITH ZERO SURPRESS
        BRA.S TD9
TD71    CMPI.B #'R',D1  ;SEE IF RELATIVE
        BNE.S TD72
        SUB.L OFFSET.W,D0 ;ADJUST VIA OFFSET
        BSR PNTZHX
        MOVE.B #'R',(A6)+       ;MARK AS RELATIVE
        BRA.S TD9
TD72    CMPI.B #'D',D1  ;SEE IF DECIMAL
        BNE.S TD73
        BSR HEX2DEC     ;GO PRINT DECIMAL
        BRA.S TD9
TD73    CMPI.B #'S',D1  ;SEE IF SYMBOLIC
        BEQ.S TDSYMB
TD8     CMPI.W #'SR',D2 ;SEE IF STATUS REGISTER
        BEQ.S TD51
        CMPI.W #'PC',D2 ;SEE IF PROGRAM COUNTER
        BEQ.S TD61
        CMPI.B #'1',D1  ;SEE IF ASCII 1
        BEQ.S T44A
        CMPI.B #'2',D1
        BEQ.S TD51
        CMPI.B #'3',D1
        BEQ.S TD61
        BSR PNT8HX
TD9     MOVE.B #' ',(A6)+       ;SPACE BETWEEN REGS
        BRA TD1
;
;       SYMBOLIC FORMAT D0 HAS VALUE...
;       SEARCH SYMBOL TABLE FOR VALUE
;       IF FOUND RETURN NAME IN D6,D7
;       IF NOT FOUND RETURN 8 HEX CHAR (VALUE) IN D6-D7
TDSYMB  BSR SNUMTAB     ;GET NAME INTO D6-D7
        MOVE.B #0,(A6)  ;NULL OUT CURRENT POSITION
        MOVE.L A6,D0    ;MAKE SURE A6 IS EVEN
        ADDQ.L #1,D0
        ANDI.B #$FE,D0   ;TURN OFF LOWEST BIT
        MOVE.L D0,A6
        MOVE.L D6,(A6)+ ;SAVE NAME OR HEX VALUE
        MOVE.L D7,(A6)+ ;LOWER PART
        BRA.S TD9
        PAGE
;
;       SAVE ALL REGISTERS ROUTINE-JMP (TEMP) BACK
;
SAVE    MOVE.L A7,REGA7.W       ;FREE UP FOR WORK
        MOVE.L #REGA7,A7        ;WHERE TO START STORING
        MOVEM.L D0-D7/A0-A6,-(A7)       ;SAVE REGISTERS
        MOVE.L #SYSTACK,A7      ;SET UP REAL MACSBUG STACK
        MOVE.L REGA7.W,A0       ;GET OLD SS
        MOVE.W (A0)+,REGSR+2.W  ;GET SR
        MOVE.L (A0)+,REGPC.W    ;GET PC
        MOVE.L A0,REGA7.W       ;WHERE STACK REALLY POINTS
        MOVE.L USP,A1           ;GET USERS STACK POINTER
        MOVE.L A1,REGUS.W       ;SAVE IT FOR DISPLAY ETC
        MOVE.L REGPC.W,D0       ;GET PROGRAM COUNTER
        CLR.L D1                ;FORM RETURN ADDRESS
        MOVE.W TEMP.W,D1        ;GET ADDRESS
        ADDI.L #ROM,D1           ;ADD IN START OF ROM
        MOVE.L D1,-(A7)         ;PUT ON STACK
        CLR.W RUN.W             ;USERS REGISTERS ON SAVE (DONT OVERWRITE)
        RTS                     ;RETURN TO SENDER
;
;
;       UNSAVE ALL REGISTERS-JMP (TEMP) BACK
;
UNSAVE  MOVE.L REGUS.W,A1       ;RESTORE USER'S STACK
        MOVE.L A1,USP
        MOVE.L #REGS,A7 ;RESTORE REGISTERS
        MOVEM.L (A7)+,D0-D7/A0-A6
        MOVE.L REGA7.W,A7       ;FIX UP SS
        MOVE.L REGPC.W,-(A7)    ;PUSH PROGRAM COUNTER
        MOVE.W REGSR+2.W,-(A7)  ;STATUS REGISTER
        MOVE.W TEMP.W,-(A7)     ;PUSH ON STACK RETURN ADDRESS
        MOVE.W #2,-(A7) ;ROM STARTS AT 20000
        MOVE.W #1,RUN.W ;USER STARTING TO RUN (SAVE HIS REG)
        RTS             ;GO BACK TO CALLER
        PAGE
;
;       ***TRACE***     TRACE ENTRY POINT
;
TRACE   MOVE.W #$2700,SR        ;MASK OFF INTERRUPTS
        MOVE.W #TRACE00-ZERO,TEMP.W     ;SET UP TO COME BACK FROM SAVE
        BRA.S SAVE      ;SAVE ALL REGISTERS
TRACE00 CLR.L D6        ;WHEN D6>0 MUST PRINT COUNTED BP
        BSR FIXBP       ;CHECK FOR BREAKPOINT
        MOVEQ.L #9,D7   ;8TH BP IS 'UNTILL' FEATURE
        MOVE.L REGPC.W,D1
TRACE01 CMP.L (A0),D1   ;SEE IF PC MATCHES ADDRESS IN TABLE
        BNE.S TRACE08
        MOVEQ.L #-1,D6  ;MUST PRINT
        MOVE.L (A2),D0  ;GET COUNT
        BEQ.S TRACE02
        SUBQ.L #1,D0    ;COUNT DOWN
        MOVE.L D0,(A2)  ;SAVE IT
        BNE.S OKTD
TRACE02 CLR.L TRACECNT.W        ;STOP AFTER PRINT
        BRA.S OKTD
TRACE08 ADDA.L #4,A0    ;BUMP TABLE POINTER
        ADDA.L #2,A2    ;BUMP COUNT TABLE POINTER
        SUBQ.L #1,D7    ;LOOP AROUND
        BNE.S TRACE01
        MOVE.L TRACECNT.W,D0    ;EXAMIN THE TRACE COUNTER
        BEQ.S OKTD      ;WAS ALREADY ZERO-PRINT DISPLAY
        SUBQ.L #1,D0    ;SUBTRACT 1
        MOVE.L D0,TRACECNT.W    ;SAVE NEW VALUE
        TST.B D6        ;SEE IF MUST PRINT
        BNE.S OKTD      ;NONZERO=MUST PRINT
        TST.L D0        ;CHECK TRACE COUNTER
        BEQ.S OKTD      ;COUNT=ZERO...PRINT IT
        BPL.S TRACE0    ;NEGATIVE=SPECIAL CASE
; END UP HERE AFTER BREAKPOINTING ONE
; INSTRUCTION-PUT BP BACK IN AND CONTINUE TO RUN
        MOVE.L REGSR.W,D0       ;TURN TRACE MODE OFF
        ANDI.L #$7FFF7FFF,D0
        MOVE.L D0,REGSR.W       ;SAVE IT
        CLR.L TRACECNT.W
        BSR SWAPIN      ;PUT BP BACK INTO USER'S MEMORY
        BRA UNSTACK     ;CONTINUE TO RUN
TRACE0  MOVE.L REGPC.W,D0       ;CHECK WHERE WE ARE
        CMP.L LOOPR1.W,D0       ;IS BELOW LOOP RANGE?
        BLT.S OKTD
        TST.L LOOPR2.W          ;SEE IF OTHER IS ZERO
        BEQ.S OKTD
        CMP.L LOOPR2.W,D0       ;IS ABOVE RANGE?
        BLE.S NOTD
OKTD    BSR TDISPLY     ;GO PRINT TRACE DISPLAY
        TST.L TRACECNT.W        ;CHK THE COUNTER
        BEQ MACSBUG     ;STOP WHEN ZERO
NOTD    BRA UNTRACE     ;CONTINUE WITH TRACE
        PAGE
;
;       ***T*** TRACE COMMAND
;
;
TCMD    MOVE.L #ROM+TRACE1-ZERO,A0      ;IF NO PARAMTERS
        MOVE.W #-1,TRACEON.W    ;SET FLAG FOR TRACE ON
        BSR FINDNP      ;FIND NEXT PARAMETER
        LSL.L #8,D0     ;GET ALL 4 CHARAC
        MOVE.B 2(A5),D0
        LSL.L #8,D0
        MOVE.B 3(A5),D0
        CMPI.L #'TILL',D0
        BNE.S TCMD1
        MOVE.B 4(A5),D0 ;SEE IF FOLLOWED BY A SPACE
        CMPI.B #' ',D0
        BEQ.S TCMD5
TCMD1   MOVEQ.L #1,D0   ;DEFAULT VALUE
        BSR GETNUMA     ;FIND NUMBER OF INST TO TRACE
        MOVE.L D0,TRACECNT.W
        BRA.S UNTRACE
TCMD5   BSR WHATNUM     ;GET NUMBER ELSE PRINT WHAT
        MOVE.L D0,BPTILL.W      ;9TH BP
        MOVE.L #$FFFF,TRACECNT.W        ;SET FOR A VERY LONG TIME
        BRA.S UNTRACE
TRACE1  MOVE.L #1,TRACECNT.W
UNTRACE BSR SWAPSOME    ;SWAP IN MOST BREAKPOINTS
        MOVE.L REGSR.W,D0       ;SET UP TRACE BIT!
        ORI.W #$8000,D0
        MOVE.L D0,REGSR.W
UNSTACK MOVE.W #UNSTACK2-ZERO,TEMP.W    ;WHERE TO RETURN
        BRA UNSAVE      ;RESTORE ALL REGISTERS
UNSTACK2 MOVE.L A0,A0   ;DELAY SOME
        RTE             ;GO BACK TO THE USER
;
        PAGE
;
;       ***GO***        RUN PROGRAM (NOT TRACE)
;
GOCMD   MOVE.L #ROM+GOCMD1-ZERO,A0      ;WHERE TO GO IF NO PARAMERS
        BSR FINDNP
        LSL.L #8,D0     ;GET ALL FOUR CHARACTERS
        MOVE.B 2(A5),D0
        LSL.L #8,D0
        MOVE.B 3(A5),D0
        CMPI.L #'TILL',D0
        BNE.S GOCMD0
        MOVE.B 4(A5),D0 ;SEE IF FOLLOWED BY SPACE
        CMPI.B #' ',D0
        BNE.S GOCMD0
GOUNTIL BSR WHATNUM     ;GET NUMBER ELSE PRINT WHAT
        MOVE.L D0,BPTILL.W      ;9TH BREAKPOINT
        BRA.S GOCMD1    ;NORMAL STARTUP
GOCMD0  CLR.L D0        ;DEFAULT ADDRESS
        BSR GETNUMR
        MOVE.L D0,REGPC.W
GOCMD1  MOVE.L #$FFFFFFFF,TRACECNT.W    ;FLAG THE COUNTER AS SPECIAL
        BRA.S UNTRACE   ;TRACE ONE GO GET PAST POSSIBLE BREAKPOINT
;
SWAPSOME BSR SWAPOUT    ;MAKE SURE THEY ARE ALL OUT
        MOVE.L #ROM+SWAPSOM1-ZERO,A6    ;ROUTINE FOR IT
        BRA.S SWAPINK
;
SWAPIN  BSR SWAPOUT     ;MAKE SURE THEY ARE ALL OUT
        MOVE.L #ROM+SWAPIN1-ZERO,A6     ;ROUTINE FOR IT
SWAPINK MOVE.L $BC.W,D0 ;SEE WHAT VECTOR
        CMPI.L #ROM+CHKBP-ZERO,D0       ;DONT OVERWRITE WITH THIS
        BEQ.S SWAPBP
        MOVE.L $BC.W,SAVETRAP.W ;SAVE USERS TRAP ADDRESS
        MOVE.L #ROM+CHKBP-ZERO,$BC.W    ;PUT IN OUR BREAKPOINT VECTOR
        BRA.S SWAPBP
SWAPOUT TST.W BPSTATUS.W        ;SEE IF ALREADY OUT
        BEQ.S SWAPEND   ;BPSTATUS=0 IF OUT
        MOVE.L SAVETRAP.W,$BC.W ;PUT USERS VECTOR BACK IN RAM
        MOVE.L #ROM+SWAPOUT1-ZERO,A6
SWAPBP  BSR FIXBP       ;GET POINTERS ETC.
        MOVEQ.L #9,D7   ;DO 9 BP
        MOVE.L #BPDATA,A3       ;CONTENT TABLE
SWAP1   MOVE.L (A0),A4  ;GET POSSIBLE ADDDRESS
        CMPA.L #0,A4    ;TEST A4
        BEQ.S SWAP99    ;ZERO MEANS NO BP DEFINED
        JMP (A6)        ;GO TO RIGHT ROUTINE
SWAPSOM1 CMPA.L REGPC.W,A4      ;SEE IF AT CURRENT ADDRESS
        BEQ SWAP99
SWAPIN1 MOVE.W (A4),(A3)        ;USER'S PROGRAM GOES INTO TABLE
        MOVE.W #$4E4F,(A4)      ;PUT BREAKPOINT IN (TRAP 15)
        MOVE.W #1,BPSTATUS.W    ;FLAG AS BP IN
        BRA.S SWAP99
SWAPOUT1 MOVE.W (A3),(A4)       ;PUT CONTENTS BACK INTO PROGRAM
        CLR.W BPSTATUS.W        ;FLAG AS BREAKPOINTS OUT
SWAP99  ADDA.L #4,A0    ;BUMP ADDRESS TABLE POINTER
        ADDA.L #2,A3    ;BUMP CONTENT TABLE POINTER
        SUBQ.L #1,D7
        BNE.S SWAP1
SWAPEND RTS
        PAGE
;
;       BREAKPOINT TEST
;       USER HIT A TRAP 7....
;       SEE IF IT MATCHES ANY BREAKPOINT
;
CHKBP   MOVE.W #$2700,SR        ;MASK OF INT.
        MOVE.W #CHKBP00-ZERO,TEMP.W     ;WHERE TO GO AFTER SAVE
        BRA SAVE        ;SAVE ALL REGISTERS
CHKBP00 BSR FIXBP       ;GET POINTER TO ADDRESS/COUNTES
        MOVEQ.L #9,D7   ;8TH PB IS 'UNITLL' FEATURE
        MOVE.L REGPC.W,D0       ;GET PROGRAM COUNTER TO COMPARE
        SUBQ.L #2,D0    ;BACKUP TO ADDRESS OF TRAP
CHKBP1  CMP.L (A0),D0   ;SEE IF WE ARE THERE
        BEQ.S CHKBP2
        ADDA.L #4,A0    ;BUMP BOTH POINTERS
        ADDA.L #4,A2
        SUBQ.L #1,D7
        BNE.S CHKBP1
; IS NOT A BREAKPOINT
        MOVE.W #CHKBP5-ZERO,TEMP.W      ;WHERE TO RETURN
        BRA UNSAVE
CHKBP5  MOVE.L SAVETRAP.W,-(A7) ;GO TO WHERE USER WANTS TO GO
        RTS
; IS BREAKPOINT...CHECK COUNT
CHKBP2  MOVE.L (A2),D0  ;GET COUNT
        BEQ.S CHKBP3
        SUBQ.L #1,D0    ;DECREMENT
        MOVE.L D0,(A2)  ;PUT COUNT AWAY
        BEQ.S CHKBP3
        BSR CHKBP4
        BRA GOCMD1      ;KEEP GOING
CHKBP3  BSR CHKBP4      ;COUNT IS ZERO
        BRA MACSBUG     ;COMMAND LINE
CHKBP4  BSR SWAPOUT     ;TAKE BP OUT OF MEMORY
        MOVE.L REGPC.W,D0       ;ADJUST THE PROGRAM COUNTER
        SUBQ.L #2,D0    ;MOVE IT BACK TO POINT AT BP ADDRESS
        MOVE.L D0,REGPC.W       ;SAVE IT
        BSR TDISPLY     ;PRINT TRACE DISPLAY
        RTS
        PAGE
;
;       HANDLE THE ABORT BUTTON
;
ABORTB  TST.W RUN.W     ;SEE IF USER WAS RUNNING
        BEQ MACSBUG     ;
        MOVE.W #ABORTB0-ZERO,TEMP.W     ;WHERE TO GO AFTER SAVE
        BRA SAVE        ;PUT ALL REG AWAY
ABORTB0 BSR TDISPLY
        BRA MACSBUG
;
;       OTHER TRAP AND EXCEPTION VECTORS INITIALIZED TO HERE
;
ABORTE  TST.W RUN.W     ;SEE IF USER WAS RUNNING
        BEQ ABORTE0
        MOVE.W #ABORTE0-ZERO,TEMP.W     ;WHERE TO GO AFTER SAVE
        BRA SAVE
ABORTE0 BSR FIXBUF      ;SEND MESAGE
        MOVE.L #'TRAP',(A6)+
        MOVE.L #' ERR',(A6)+
        MOVE.L #'OR ',(A6)+
        BRA MSG
;
;       THIS BRANCH INSERTED TO MATCH THE RELEASED 1.3 CODE
;
        BRA     ZERO    ;(SIMILAR TO "ADDA" IN PURPOSE).
;
        PAGE
;
;       PRINT HEX ROUTINES
;
;
; PRINT 8 HEX CHARACTERS
;
PNT8HX  SWAP D0         ;FLIP REG HALVES
        BSR PNT4HX      ;DO TOP WORD
        SWAP D0 ;NOW DO LOWER WORD
        BRA PNT4HX
; PRINT 6 HEX CHARACTERS
PNT6HX  SWAP D0 ;FLIP REGISTER HALVES
        BSR PNT2HX
        SWAP D0 ;FLIP BACK REG HALVES
; PRINT 4 HEX CHARACTERS IN D0.W
PNT4HX  MOVE.W D0,D1    ;SAVE IN TEMP
;
;******************************************************************OPT*
;                                                               *OPT*
;       NOTE ROXR AND ROR WERE REVERSED IN CROSS ASSEMBLER...   *OPT*
;       THE SOURCE      ;HERE IS SWITCHED TO MATCH OBJECT CODE IN 1.3 *OPT*
;
        ROXR.W #8,D0    ;GET BITS 15-8 INTO LOWER BYTE.         *OPT*
        BSR PNT2HX      ;PRINT IT
        MOVE.W D1,D0    ;PULL IT BACK
; PRINT 2 HEX CHARACTERS IN D0.B
PNT2HX  MOVE.W D0,D2    ;SAVE IN TEMP REG
        ROR.W #4,D0     ;FORM UPPER NIBBLE                      *OPT*
;
;******************************************************************OPT*
;
        BSR PUTHEX      ;PUT ASCII INTO PRINT BUFFER
        MOVE.W D2,D0    ;GET BACK FROM TEMP
; CONVERT D0.NIBBLE TO HEX & PUT IT IN PRINT BUFFER
;
PUTHEX  ANDI.B #$0F,D0   ;SAVE LOWER NIBBLE
        ORI.B #$30,D0    ;CONVERT TO ASCII
        CMPI.B #$39,D0  ;SEE IF IT IS>9
        BLE SAVHEX
        ADDQ #7,D0      ;ADD TO MAKE 10=>A
SAVHEX  MOVE.B D0,(A6)+ ;PUT IT IN PRINT BUFFER
        RTS
        PAGE
;
;
;       PRINT HEX (ZERO SURPRESS)
;
PNTZHX  CLR.L D4        ;IS ZERO WHEN SURPRESSING
        MOVE.L D0,D1    ;SAVE IN TEMP
        BEQ.S PNTZ81    ;IF ZERO
        BPL.S PNTZ0
        NEG.L D1        ;CHANGE TO POSITIVE VALUE
        MOVE.B #'-',(A6)+       ;PUT SIGN INTO BUFFER
PNTZ0   MOVEQ.L #8,D2   ;8 POSSIBLE CHARACTERS
PNTZ1   MOVE.L D1,D0    ;UNSAVE IT
        MOVE.L D2,D3    ;COUNT DOWN FROM HERE
        SUBQ.L #1,D3    ;BACK OFF ONE
        BEQ.S PNTZ4     ;IF NO ROTATE SKIP THIS
PNTZ2   ASR.L #4,D0     ;ROTATE LRIGHT
        ANDI.L #$FFFFFFF,D0      ;CLEAR TOP NIBBLE
        SUBQ.L #1,D3
        BNE.S PNTZ2
PNTZ4   ANDI.B #$F,D0    ;SAVE ONLY NIBBLE
        BNE.S PNTZ3
        TST.B D4        ;SEE IF STILL SURPRESSING
        BEQ.S PNTZ8
PNTZ3   BSR.S PUTHEX    ;PUT A HEX CHAR IN BUFFER
        MOVE.B D0,D4    ;MARK AS NON-SURPRESSING MODE
PNTZ8   SUBQ.L #1,D2    ;DO ANOTHER CHAR
        BNE.S PNTZ1
        TST.B D4        ;SEE IF ANYTHING PRINTED
        BNE.S PNTZ9
PNTZ81  MOVE.B #'0',(A6)+       ;MOVE AT LEAST ONE ZERO
PNTZ9   RTS
        PAGE
;*********************************************************
;*
;*      FIND NEXT PARAMETER IN COMMAND LINE
;*      ENTRY: (A5) POINTS TO CURRENT LOCATION IN LINE
;*      (A0) IS WHERE TO JUMP TO IF NO PARAMTERS FOUND
;*      RTS IF PARAMETER IF FOUND (A5) POINT TO IT
;*
;*********************************************************
;
FINDNP  CLR.L D1        ;0=SEARCH FOR DELIMITER
FINDNP1 CMPA.L A6,A5    ;SEE IF AT END OF BUFFER
        BEQ.S FINDNP2
        MOVE.B (A5),D0  ;GET CMMD LNE CHAR
        CMPI.B #$20,D0  ;IS IT SPACE
        BEQ.S FINDNP3
        CMPI.B #',',D0  ;IF IS COMMA
        BEQ.S FINDNP3
        CMPI.B #$3B,D0  ;SEMICOLEN?
        BNE.S FINDNP4
FINDNP2 JMP (A0)        ;NO PARAMETER-JUST OPTIONS?
FINDNP3 MOVEQ.L #-1,D1  ;MARK-SEARCH FOR NON SPACE
        BRA.S FINDNP5
FINDNP4 TST.B D1        ;SEE WHAT MODE
        BEQ.S FINDNP5
        ASL.W #8,D0     ;READY TO HOLD FIRST 2 CHAR
        MOVE.B 1(A5),D0 ;GET NEXT BYTE
        RTS             ;FOUND SOMETHING FOR REAL
FINDNP5 ADDA.L #1,A5    ;BUMP FOR NEXT CHAR
        BRA.S FINDNP1   ;GET NEXT ETC.
        PAGE
;
;       ***GETNUM***    GET A HEX NUMBER FROM THE BUFFER
;       BUFFER STARTS AT (A5)
;
GRABNUMA BSR.S FINDNP   ;FIND NEXT PARAMETER
        CLR.L D7        ;NORMAL ERROR
        BRA.S GETNUMA   ;ONE ABSOLUE PARAMETER
WHATNUM MOVE.L #WHAT-ZERO,D7    ;WHAT RESPONSE
        MOVE.L #ROM+ERROR-ZERO,A0       ;IF NO PARAMTER
GRABNUM BSR.S FINDNP    ;SCAN FOR NEXT PARAMTER
        CLR.L D7        ;SET FOR NORMAL PARAMETER
GETNUMR MOVE.L OFFSET.W,WORK2.W   ;SAVE OFFSET
        BSR.S GETNUMA   ;GET ABSOLUTE NUMBER
        MOVE.L D0,WORK1.W       ;SAVE IT FOR A MOMENT
        MOVE.B (A5),D0  ;SEE IF COMMA
        CMPI.B #',',D0
        BEQ.S GETNUMR3  ;HAS SECOND PARAMETER
        MOVE.L WORK1.W,D0       ;RESTORE
        ADD.L WORK2.W,D0        ;ADD IN DEFAULT OFFSET
        RTS
GETNUMR3 CLR.L D0       ;DEFAULT OFFSET
        ADDA.L #1,A5    ;GET PAST COMMA
        BSR.S GETNUMA   ;GET PARAMETER
        ADD.L WORK1.W,D0        ;ADD IN MAIN PART
        RTS
GETNUMA MOVE.W #16,BASE.W       ;SET BASE TO HEX
; FORM SYMBOL-CHECK     ;TABLE
GETNUMS MOVEM.L D0-D2/D6-D7/A1,-(A7)    ;FREE UP SOME ROOM
        BSR GETSY       ;GET SYMBOL INTO D6,D7
        TST D6  ;D6=NULL IF NOT A SYMBOL
        BEQ.S GETNUM0
;       SEARCH SYMBOL TABLE
        MOVE.L STRSYM.W,A1      ;START OF TABLE
GN5     CMPA.L ENDSYM.W,A1      ;SEE IF AT END
        BEQ.S GETNUM0
        BPL.S GETNUM0
        CMP.L (A1),D6   ;CHECK FIRST 4 LETTERS
        BNE.S GN6
        CMP.L 4(A1),D7  ;SECOND 4 BYTES
        BNE.S GN6
        ADDA.L D1,A5    ;BUMP TO END OF STUFF
;
        MOVE.L 8(A1),TEMP.L     ;FORCE LONG BACKWARD REF.
;
;
        MOVEM.L (A7)+,D0-D2/D6-D7/A1    ;RESTORE EVERYTHING
        MOVE.L TEMP.W,D0        ;GET VALUE
        TST.W SIGN.W    ;0=POSITIVE ELSE=MINUS THE VALUE
        BEQ RETURN
        NEG.L D0        ;MAKE IS MINUS
        RTS
GN6     ADDA.L #12,A1   ;PUMP POINTER
        BRA.S GN5
;       ITS NOT A SYMBOL-DECODE AS NUMBER
GETNUM0 MOVEM.L (A7)+,D0-D2/D6-D7/A1    ;RESTORE
GETNUM1 MOVE.L D0,D3    ;TRANSFER DEFAULT VALUE
        CLR.B SIGN.W    ;SET SIGN TO PLUS
        CLR.W TEMP.W    ;FLAG FOR CHARACTER HIT
        CLR.L D0
        CLR.L D1        ;WHERE TO PUT RESULTS
NXTNUM  CMPA.L A6,A5    ;SEE IF AT END OF BUFFER
        BEQ EXITGN
        MOVE.B (A5)+,D0 ;GRAB CHARACTER
        CMPI.B #$20,D0  ;CHECK FOR SPACE
        BNE.S GETNUM3
        TST.W TEMP.W    ;SEE IF ANYTHING ENTERED
        BEQ.S NXTNUM    ;IF NOT SCAN NEXT CHAR
GETNUM2 MOVE.B -(A5),D2 ;BACK UP TO POINT AT SPACE
        BRA EXITGN      ;IF SO-END
GETNUM3 CMPI.B #$27,D0  ;SEE IF SINGLE QUOTE
        BEQ GETNUMST    ;GET NUM STRING
        CMPI.B #$3B,D0
        BEQ.S GETNUM2   ;WHERE TO GO IF SEMICOLEN
        CMPI.B #',',D0  ;SEE IF COMMA
        BEQ.S GETNUM2
        CMPI.B #'/',D0  ;SEE IF SLASH
        BEQ.S GETNUM2
        CMPI.B #'^',D0  ;SEE IF UP ARROW
        BEQ.S GETNUM2
        CMPI.B #':',D0  ;SEE IF COLEN
        BEQ.S GETNUM2
        CMPI.B #'=',D0  ;SEE IF EQUAL SIGN
        BEQ.S GETNUM2
        CMPI.B #'(',D0  ;SEE IF LEFT PAREN
        BEQ.S GETNUM2
        CMPI.B #'R',D0  ;FOR RELATIVE
        BEQ EXITREL
        CMPI.B #'-',D0  ;SEE IF NEG SIGN
        BNE.S GETNUM4
        TST.W TEMP.W    ;SEE IF ANY CHARACTERS BEFORE?
        BNE     ERROR1
        MOVE.B #$FF,SIGN.W      ;SET FLAG AS NEGATIVE
        BRA.S NXTNUM
GETNUM4 CMPI.B #'&',D0  ;SEE IF FLAGGED AS DECIMAL
        BNE.S GETNUM41
        TST.W TEMP.W    ;SEE IF ANYTHING DECODED
        BNE ERROR1
        MOVE.W #10,BASE.W       ;BASE IS DECIMAL
;
        BRA NXTNUM      ;FORCE LONG, (SIMILAR TO "ADDA" MACRO).
;
GETNUM41 CMPI.B #'$',D0 ;SEE IF FLAGGED AS HEX
        BNE.S GETNUM5
        TST.W TEMP.W    ;SEE IF ANYTHING DECODED
        BNE.S ERROR1
        MOVE.W #16,BASE.W       ;BASE IS 16
        BRA NXTNUM
GETNUM5 BSR GETHEX      ;RETURNS WITH D0=BINARY
        CMP.W BASE.W,D0 ;IS INPUT LARGER THAN BASE
        BHI.S ERROR1
        MOVE.W #-1,TEMP.W       ;FLAG AS SOMETHING READ
        MOVE.L D1,D2    ;GET READY TO MULTIPLY D1*BASE
        SWAP D1
        MULU BASE.W,D1  ;TOP PART
        SWAP D1
        TST.W D1        ;CHECK FOR OVERFLOW
        BNE.S ERROR1    ;VALUE IS TOO LARGE
        MULU BASE.W,D2  ;NOW WORK ON LOW WORD
        ADD.L D2,D1     ;PUT IT BACK TOGETHER
        BVS.S ERROR1    ;OVERFLOW?
        ADD.L D0,D1     ;ADD IN NEW STUFF
        BVS.S ERROR1    ;ON OVERFLOW
        CLR.L D3        ;WIPE OUT DEFAULT VALUE
        BRA NXTNUM
GETNUMST TST.L D1       ;IF SOMETHING IS BEFORE THIS ERROR OUT
        BNE SYNTAX
        MOVEQ.L #5,D2   ;COUNTER
GETNUMS1 MOVE.B (A5)+,D0        ;LOAD CHARACTER
        CMPI.B #$27,D0  ;SEE IF SINGLE QUOTE
        BEQ GETNUM2     ;WHERE TO GO IF END
        LSL.L #8,D1     ;MAKE ROOM FOR NEW CHARACTER
        MOVE.B D0,D1    ;NEW BYTE
        CLR.L D3        ;WIPE   OUT DEFAULT VALUE
        CMPA.L A6,A5    ;SEE IF AT END OF BUFFER
        BEQ.S EXITGN    ;WHERE TO GO IF END OF BUFFER
        SUBQ.L #1,D2
        BNE.S GETNUMS1
        BRA SYNTAX      ;NO CLOSING QUOTE OR TOO LONG
EXITGN  MOVE.L D1,D0    ;SET UP RESULT FOR RETURN
        TST.B SIGN.W    ;SEE IF NEG
        BEQ.S RTS5
        NEG.L D0        ;CHANGE TO NEGATIVE NUMBER
RTS5    ADD.L D3,D0     ;ADD IN OLD DEFAULT VALUE
        RTS             ;END OF GETNUM-NORMAL RETURN
ERROR1  BRA ERROR       ;INDIRECT ERROR STUFF
;
;       EXIT RELATIVE
EXITREL CLR.L WORK2.W   ;CLEAR RELATIVE OFFSET
        TST.B SIGN.W
        BEQ.S EXITR2
        NEG.L D1        ;CHANGE TO NEGATIVE
EXITR2  MOVE.L D1,D0    ;RETURNS D0
        ADD.L OFFSET.W,D0
        RTS
        PAGE
;
;       ***GETHEX***    GET HEX (BINARY VALUE FROM ASCII)
;       D0.B HAS ASCII CHAR     RETURNS $0-$F BINARY OR $FF ON ERROR
;
GETHEX  ANDI.L #$FF,D0    ;STRIP OFF ALL BUT BYTE
        CMPI.B #$30,D0  ;IS IT LESS THAN ZERO
        BLT.S ERROR2
        CMPI.B #$39,D0  ;IS IT GREATER THAN 9
        BGT.S GTHX2
GTHX1   ANDI.L #$F,D0    ;SAVE ONLY LAST NIBBLE  HIGH 28 BITS OFF
        RTS
GTHX2   CMPI.B #$41,D0  ;IS IT LESS THAN 'A'
        BLT.S ERRDIG
        CMPI.B #$46,D0  ;IS IT GT 'F'
        BGT.S ERRDIG
        SUBQ.B #7,D0    ;MAKE IT SMALLER A=10
        BRA.S GTHX1
ERRDIG  CMPI.W #WHAT-ZERO,D7    ;SEE IF WHAT RESPONSE
        BEQ.S ERROR
        BSR FIXBUF      ;PRINT NOT A HEX DIGIT
        MOVE.B D0,(A6)+ ;PUT IN OFFENDING CHAR
        MOVE.B #' ',(A6)+       ;SPACE
        MOVE.L #'IS N',(A6)+
        MOVE.L #'OT A',(A6)+
        MOVE.L #' HEX',(A6)+
        MOVE.L #' DIG',(A6)+
        MOVE.W #'IT',(A6)+
        BRA MSG ;GO PRINT IT AND ENTER MACSBUG
ERROR2  MOVEQ.L #1,D0   ;ERROR NUMBER 1
ERROR   BSR FIXBUF      ;PRINT 'ERROR'
        CMPI.W #WHAT-ZERO,D7    ;SEE IF 'WHAT' RESPONSE
        BNE.S ERR1
        MOVE.L #'WHAT',(A6)+
        BRA.S ERR2
ERR1    MOVE.L #'ERRO',(A6)+
        MOVE.W #'R ',(A6)+
ERR2    BRA MSG ;PRINT MESSAGE-ENTER MACSBUG
;
;
SYNTAX  BSR FIXBUF      ;PRINT 'SYNTAX ERROR'
        MOVE.L #'SYNT',(A6)+
        MOVE.L #'AX E',(A6)+
        MOVE.L #'RROR',(A6)+
        BRA MSG         ;GO PRINT IT
        PAGE
;
;       ***#?***        NUMBER CONVERSTIONS
;
NUMCON0 MOVE.W #10,BASE.W       ;DECIMAL TO HEX
        MOVE.L #ROM+SYNTAX-ZERO,A0      ;IF NO PARAMETERS
        BSR FINDNP      ;POINT TO NEXT PARAMETER
        CLR.L D0        ;DEFAULT         
        MOVE.W #10,BASE.W       ;DEFAULT BASE
        BSR GETNUMS     ;GET NUMBER (MIGHT BE SYMBOLIC)
        MOVE.L D0,D7    ;SAVE IT FOR AWHILE
        MOVE.B (A5)+,D1 ;SEE IF COMMA
        CMPI.B #',',D1
        BNE.S NUMCON00
        CLR.L D0        ;DEFAULT OFFSET
        BSR GETNUMS     ;GET ANOTHER NUMBER
        ADD.L D0,D7
NUMCON00 BSR FIXBUF     ;SET UP FOR PRINT
        TST.L D7        ;SEE IF NEGATIVE
        BPL.S NUMCON1
        MOVE.B #'$',(A6)+
;
;       PATCHED *08/14/80*
        BSR PATCH2      ;MOVE D7>D0 THEN BSR PNT8HX
;
        MOVE.B #'=',(A6)+
NUMCON1 MOVE.L D7,D0    ;RESTORE
        BPL.S NUMCON2
        MOVE.B #'-',(A6)+
        NEG.L D0
NUMCON2 MOVE.B #'$',(A6)+
        BSR PNTZHX
        MOVE.B #'=',(A6)+       ;NOW PRINT DECIMAL VALUE
        MOVE.L D7,D0
        BPL.S NUMCON3
        MOVE.B #'-',(A6)+
        NEG.L D0
NUMCON3 MOVE.B #'&',(A6)+
        BSR HEX2DEC     ;PUT VALUE IN BUFFER
        BRA MSG ;GO PRINT IT
        PAGE
;
;       FORM SYMBOL FROM INPUT BUFFER
;       RTS WITH SYMBOL IN D6,D7
;       OR D6,D7=NULL IF NOT A SYMBOL
;
GETSY   MOVE.L #'    ',D7 ;BLANK FILL
        MOVE.L D7,D6    ;D6,D7 HOLD SYMBOL
        CLR.W SIGN.W    ;0=POSITIVE     ELSE=NEGATIVE
        CLR.L D1        ;USED AS INDEX
GETSY0  MOVE.B 0(A5,D1),D0      ;GET A CHAR FROM INPUT BUFFER
        CMPI.B #',',D0  ;SEE IF COMMA
        BEQ.S GETSY4
        CMPI.B #' ',D0  ;SEE IF SPACE
        BEQ.S GETSY4
        CMPI.B #':',D0  ;SEE IF COLEN
        BEQ.S GETSY4
        CMPI.B #'.',D0  ;SEE IF POINT
        BEQ.S GETSY3
        CMPI.B #'-',D0  ;SEE IF SIGN
        BEQ.S GETSY5
        CMPI.B #'A',D0  ;SEE IF LESS THAN LETTER
        BLT.S GETSY2
        CMPI.B #'Z',D0  ;SEE IF GREATER THAN LETTER
        BLE.S GETSY3
GETSY2  TST.W D1        ;SEE IF 1ST CHAR
        BEQ NOTSYM      ;NOT 'A'-'Z' OR '.' PRINT SYMBOL FROM HEX
        CMPI.B #'$',D0  ;ALLOW '$' IF NOT 1ST CHAR
        BEQ.S GETSY3
        CMPI.B #'0',D0  ;ALLOW DIGIT IF NOT 1ST
        BLT NOTSYM
        CMPI.B #'9',D0
        BGT NOTSYM
GETSY3  MOVE.L D6,VECTOR.W      ;CHECK TOP BYTE
        MOVE.B VECTOR.W,D2      ;SEE IF SPACE
        CMPI.B #' ',D2
        BNE.S NOTSYM
        MOVE.L D7,VECTOR.W      ;GET TOP BYTE OF D7...
        LSL.L #8,D6     ;...INTO LOW BYTE OF D6
        MOVE.B VECTOR.W,D6
        LSL.L #8,D7
        MOVE.B D0,D7    ;SAVE NEW LETTER
GETSY1  ADDQ.W #1,D1    ;BUMP INDEX
        BRA.S GETSY0
GETSY4  BSR NORM1       ;LEFT JUSTIFY IT
        RTS             ;RETURN TO SENDER
GETSY5  TST D1  ;SEE IF FIRST   COME HERE WHEN '-'
        BNE.S NOTSYM
        MOVE.W #-1,SIGN.W
        BRA.S GETSY1
NOTSYM  CLR.L D6        ;IS NOT A SYMBOL
        CLR.L D7
        RTS             ;RETURN TO SENDER
        PAGE
;
;       CONVERT BINARY TO DECIMAL       REG D0 PUT IN (A6) BUFFER AS ASCII
;
HEX2DEC MOVE.L D0,D7    ;SAVE IT HERE
        BPL.S HX2DC
        NEG.L D7        ;CHANGE TO POSITIVE
        MOVE.B #'-',(A6)+       ;PUT IN NEG SIGN
HX2DC   CLR.W TEMP.W    ;FOR ZERO SURPRESS
        MOVEQ.L #10,D6  ;COUNTER
HX2DC0  MOVEQ.L #1,D2   ;VALUE TO SUB
        MOVE.L D6,D1    ;COUNTER
        SUBQ.L #1,D1    ;ADJUST - FORM POWER OF TEN
        BEQ.S HX2DC2    ;IF POWER IS ZERO
HX2DC1  MOVE.W D2,D3    ;D3=LOWER WORD
        MULU #10,D3
        SWAP D2 ;D2=UPPER WORD
        MULU #10,D2
        SWAP D3 ;ADD UPPER TO UPPER
        ADD.W D3,D2
        SWAP D2 ;PUT UPPER IN UPPER
        SWAP D3 ;PUT LOWER IN LOWER
        MOVE.W D3,D2    ;D2=UPPER & LOWER
        SUBQ.L #1,D1
        BNE.S HX2DC1
HX2DC2  CLR.L D0        ;HOLDS SUB AMT
HX2DC22 CMP.L D2,D7
        BLT.S HX2DC3    ;IF NO MORE SUB POSSIBLE
        ADDQ.L #1,D0    ;BUMP SUBS
        SUB.L D2,D7     ;COUNT DOWN BY POWERS OF TEN
        BRA.S HX2DC22   ;DO MORE
HX2DC3  TST.B D0        ;ANY VALUE?
        BNE.S HX2DC4
        TST.W TEMP.W    ;ZERO SURPRESS
        BEQ.S HX2DC5
HX2DC4  ADDI.B #$30,D0   ;BINARY TO ASCII
        MOVE.B D0,(A6)+ ;PUT IN BUFFER
        MOVE.B D0,TEMP.W        ;MARK AS NON ZERO SURPRESS
HX2DC5  SUBQ.L #1,D6    ;NEXT POWER
        BNE.S HX2DC0
        TST.W TEMP.W    ;SEE IF ANYTHING PRINTED
        BEQ.S HX2DC6
        RTS             ;JUST END ROUTINE
HX2DC6  MOVE.B #'0',(A6)+       ;PRINT AT LEST A ZERO
        RTS             ;END OF ROUTINE
        PAGE
;
;       SEND LINE TO PORT1 WITH CR/LF
;
OUT1CR  TST.L OUTTO.W   ;SEE IF ALTERNATE ADDRESS
        BEQ.S OUT1CRX
        MOVE.L OUTTO.W,-(A7)    ;PUSH ON STACK
        RTS     ;GO DO IT
OUT1CRX MOVE.L OUTPORT1.W,-(A7) ;GO TO I/O ADDRESS
        RTS             ;(THIS NORMALLY GOES TO OUT1CR0)
;
OUT1CR0 BSR OUTPUT      ;SEND LINE
CRLF    BSR FIXBUF
        MOVE.W #$D0A,(A6)+      ;PUT CR LF AT END OF BUFFER
;       
;       OUTPUT BUFFER TO PORT1
; 
OUTPUT  MOVEM.L D0-D3/A0-A1,-(A7)       ;GET SOME WORKING ROOM
        CLR.L D3        ;NO OFFSET INTO NULL CHARACTERS
OUTP1   BSR GETACIA1    ;GET.ACIA ADDRESS INTO A0
        BRA OUTP2
;
;       SEND LINE TO PORT2 WITH CR
;
OUTPUT2 TST.L OUTTO.W   ;SEE IF ALTERNATE ADDRESS
        BEQ.S OUTPUT2X
        MOVE.L OUTTO.W,-(A7)    ;PUSH ON STACK
        RTS             ;GO DO IT
OUTPUT2X MOVE.L OUTPORT2.W,-(A7)        ;GO TO IO ROUTINE
        RTS             ;(THIS NORMALLY GOES TO OUTPUT20)
;
OUTPUT20 BSR OUTPUT21
        BSR FIXBUF
        MOVE.B #$D,(A6)+        ;PUT CR AT END OF BUFFER
;
;       OUTPUT BUFFER TO PORT2 
;
OUTPUT21 MOVEM.L D0-D3/A0-A1,-(A7)
        MOVEQ.L #1,D3   ;SIGNAL FOR PORT2
        BSR GETACIA2    ;RETURNS ADDRESS IN A0  
;
;       SEND BUFFER TO PORT
;
OUTP2   CMPA.L A6,A5    ;SEE IF AT OR BEYOUND END OF LINE
        BMI.S OUTP3
        MOVEM.L (A7)+,D0-D3/A0-A1       ;RESTORE REGISTERS
        RTS             ;END OF ROUTINE
OUTP3   MOVE.B (A5)+,D0 ;GRAB BYTE TO OUTPUT
        BSR.S OUTCH1    ;GO PRINT IT
        BRA.S OUTP2     ;GO DO ANOTHER
;
;       SEND CHARACTER IN D0.B TO PORT1 
;       THROUGH .ACIA ADDRESSED BY (A0)
;       D3=0 FOR PORT1  D3=1 FOR PORT2
;       PUTS IN NULL PADDING AS NEEDED
;
OUTCH1  BSR OUTCH       ;GO PRINT "D0"
        TST.B D0        ;SEE IF NULL
        BEQ.S OUTCHRTS  ;JUST END IF NULL
        CLR.L D2        ;CLEAR UPPER BYTES OF NULL LOOP COUNTER
        MOVE.L #NULLPADS,A1     ;FORM ADDRESS OF PADS
        ADDA.L D3,A1    ;D3=0 FOR PORT1 1=PORT2
        MOVE.B (A1),D2  ;DEFAULT NULL PADS
        CMPI.B #$D,D0   ;SEE IF CR
        BNE.S OUTCH2
        MOVE.L #CRPADS,A1       ;FORM ADDRESS OF CR PADS
        ADDA.L D3,A1    ;D3=0 FOR PORT1 1=PORT2
        MOVE.B (A1),D2  ;NULLS AFTER CR
OUTCH2  TST.L D2        ;SEE IF ANY PADDS TO BE SEND
        BEQ.S OUTCHRTS  ;0=NONE
        CLR.L D0        ;0=NULL CHAR TO BE SEND
OUTCH3  BSR OUTCH       ;SEND A NULL
        SUBQ.L #1,D2    ;LOOP AROUND
        BNE.S OUTCH3
OUTCHRTS RTS            ;END OF OUTCH ROUTINE
;
;       SEND CHARACTER IN D0.B TO .ACIA IN (A0) (NO NULL PADS)
;
;                                                       6/8/82 START
;OUTCH  BSR CHKBRK              ;CHECK FOR BREAK
OUTCH   MOVE.B $23(A0),D1       ;GET STATUS
        BTST #4,D1              ;TRANSMIT REG EMPTY
        BEQ.S OUTCH             ;NOT YET
        MOVE.B D0,$21(A0)       ;SEND CHARACTER
;       BSR CTLW                ;IGNORE CONTROL-W FOR NOW
        RTS                     ;CHARACTER SENT
;
;       CHECK FOR BREAK (JUST RETURNS: 6/8/82)
;
CHKBRK  RTS
;
;CHKBRK  MOVE.B $23(A0),D1 ;READ STATUS
;       BTST #1,D1      ;SEE IF BREAK
;       BNE BREAK
;       RTS
;                                                       6/8/82 END
        PAGE
;
;       CHECK FOR CONTROL W
;
;CTLW   MOVE.B $23(A0),D1  ;READ STATUS
;       BTST #3,D1
;       BEQ.S CTLW9        ;JUST RETURN
;       MOVE.B $21(A0),D0  ;READ CHARACTER
;       CMPI.B #$17,D0     ;SEE IF CTL W
;       BNE.S CTLW9
;CTLWH  BSR.S CHKBRK       ;CHECK FOR BREAK
;       MOVE.B $23(A0),D1  ;READ STATUS
;       BTST #3,D1         ;SEE IF SENT
;       BEQ.S CTLWH
;CTLW9  RTS                ;RETURN
;
;
;       WHAT DO YOU DO WHEN THE BREAK IS PRESSED
;
;                                                       6/8/82 START
;BREAK   BSR GETACIA1      ;INITIALIZE BOTH PORTS
;       MOVE.B $21(A0),D0 ;CLEAR FRAMING ERROR
;       CLR.L D0
;       MOVE.W #$100,D0
;WAIT    SUBQ #1,D0
;       BNE.S WAIT
;       BSR FIXBUF
;       MOVE.L #$0D0D0A0A,(A6)+
;       MOVE.L #$2A425245,(A6)+ ; "*BRE
;       MOVE.L #$414B2A20,(A6)+ ;      AK*"
;       MOVE.L #$0D0D0A0A,(A6)+
;       BSR.S INITACIA    ;INITIALIZE BOTH PORTS
;       BSR GETACIA1      ;RETURNS ADDRESS IN A0
;       MOVE.B $23(A0),D0 ;CHECK IF BREAK
;       BTST #1,D0
;       BNE.S BREAK
;                                                       6/8/82 END
;       BRA MSG         ;PRINT MESSAGE AND REENTER MACSBUG
;
;       INITIALIZE BOTH ACIAs
;
;                                                       6/8/82 START
INITACIA MOVEM.L D0/A0,-(A7)    ;FREE UP SOME WORKING REGISTERS
        BSR GETACIA1            ;MOVE ADDRESS INTO A0
        MOVE.B D0,$23(A0)       ;MASTER RESET
        MOVE.B COMM1.W,$25(A0)  ;COMMAND
        MOVE.B CON1.W,$27(A0)   ;CONTROL
        BSR GETACIA2            ;MOVE ADDRESS INTO A0
        MOVE.B D0,$23(A0)       ;MASTER RESET
        MOVE.B COMM2.W,$25(A0)  ;COMMAND
        MOVE.B CON2.W,$27(A0)   ;CONTROL
        MOVE.W #$200,D0         ;WAIT DELAY
INITAC3 DBRA D0,INITAC3         ;LOOP AROUND
        MOVEM.L (A7)+,A0/D0     ;RESTORE REGISTERS
        RTS
;                                                       6/8/82 END
;
;       INPUT A LINE FROM PORT1
;
PORTIN1 TST.L INFROM.W  ;SEE IF ALTERNAT ADDRESS
        BEQ.S PORTIN1X
        MOVE.L INFROM.W,-(A7)   ;PUSH ON STACK
        RTS             ;GO DO IT
PORTIN1X MOVE.L INPORT1.W,-(A7) ;GO TO IO ROUTINE
        RTS             ;(THIS NORMALLY GOES TO PORTIN10)
;
PORTIN10 MOVEM.L        D0-D4/A0-A2,-(A7)       ;FREE UP SOME WORK REGISTERS
        CLR.L D3        ;FLAG AS PORT1
        BSR GETACIA1    ;MOVE ADDRESS INTO A0
READBUF BSR INCHNE      ;GO GET SOME DATA       (NO ECHO)
        TST.B D0        ;CHECK FOR NULLS
        BEQ.S READBUF
RB1     MOVE.W D0,D4    ;SAVE FOR A WHILE
        BSR OUTCH1      ;ECHO WHAT IS IN D0
        MOVE.W D4,D0    ;RESTORE IT
        CMPI.B #$0A,D0  ;SEE IF LINE FEED
        BEQ.S READBUF   ;DONT PUT IT IN BUFFER
        CMPI.B #$18,D0  ;SEE IF CTL X=CANCEL LINE
        BNE.S RB2
        MOVE.B #'\',D0  ;SENT A SLASH
        BSR OUTCH1
        MOVE.B #$0D,D0  ;SEND A CARRIAGE RETURN
        BSR OUTCH1
        MOVE.B #$0A,D0  ;SEND LINE FEED
        BSR OUTCH1
        MOVE.L A5,A6    ;START BUFFER OVER AGAIN
        BRA.S READBUF
;                                               6/8/82 START
RB2     CMPI.B #$08,D0   ;SEE IF CTL H=BACKSPACE
        BNE.S RB4
RB3     MOVE.B #$20,D0  ;SEND A SPACE
        BSR OUTCH1
        CMPA.L A5,A6    ;START OF BUFFER?
        BEQ.S READBUF   ;YES, SO RETURN
        MOVE.B #$08,D0  ;SEND ANOTHER BS
        BSR OUTCH1
        SUBQ #1,A6
        BRA READBUF     ;DON'T PUT IN BUFFER
;                                               6/8/82 END
RB4     CMPI.B #$04,D0  ;SEE IF CTL D (REPRINT)
        BNE.S RB5
        MOVEQ.L #$0D,D0 ;PRINT CR
        BSR OUTCH1
        MOVEQ.L #$0A,D0 ;PRINT LF
        BSR OUTCH1
        MOVE.L A5,-(A7) ;SAVE ON STACK FOR A MOMENT
RB45    BSR OUTPUT      ;GO PRINT BUFFER
        MOVE.L (A7)+,A5 ;GET BACK FROM STACK
        BRA READBUF
RB5     CMPI.B #$0D,D0  ;SEE IF AT END OF LINE
        BNE.S RB6
        MOVE.B #$0A,D0  ;GIVE LF
        BSR OUTCH1
        MOVEM.L (A7)+,D0-D4/A0-A2       ;PULL FROM STACK
        RTS             ;RETURN TO CALLER
RB6     MOVE.B D0,(A6)+ ;SAVE DATA INTO BUFFER
        BRA READBUF
;
;       INPUT CHARACTER FROM PORT1
;       ACIA ADDRESS IN (A0)
;
INCH    BSR INCHNE      ;INPUT CHARACTER
        BSR OUTCH1      ;ECHO TO CONSOLE
        RTS
;       INCH (NO ECHO)
;                                               6/8/82 START
INCHNE  MOVE.B $23(A0),D1  ;GET STATUS
        BTST #3,D1        ;INBOUND CHARACTER
        BEQ.S INCHNE
;       BSR CHKBRK        ;WAS IT A BREAK
        MOVE.B $21(A0),D0 ;GET CHAR
        ANDI.B #$7F,D0     ;GET RID OF PARITY BIT
        CMPI.B #$60,D0     ;CHANGE LOWER CASE TO UPPER CASE
        BLE.S INCHNE0
        CMPI.B #$7A,D0
        BGT INCHNE0
        BCLR #5,D0
INCHNE0 RTS
;                                               6/8/82 END
;
;       INPUT A LINE FROM PORT2 (ACIA2)
;
PORTIN2 TST.L INFROM.W  ;SEE IF ALTERNATE ADDRESS
        BEQ.S PORTIN2X
        MOVE.L INFROM.W,-(A7)
        RTS             ;GO DO IT
PORTIN2X MOVE.L INPORT2.W,-(A7) ;GO TO IO ROUTINE
        RTS             ;(THIS NORMALLY GOES TO PORTIN20)
;
PORTIN20 MOVEM.L D1-D3/A0-A3,-(A7)      ;SAVE WORKING REGISTERS
        BSR GETACIA2    ;MOVE ADDRESS INTO A0   
        MOVE.L A0,A3    ;USE ADDRESS IN A3
        BSR GETACIA1    ;MOVE ADDRESS INTO A0
;                                               6/8/82 START
POR2IN2 CMPA.L A0,A3    ;SEE IF THE SAME PORT ADDRESS
        BEQ.S PORTIN21    ;IGNORE BREAKS ETC
        BSR CHKBRK      ;CHECK FOR BREAKS ETC
        MOVE.B $23(A0),D1 ;SEE IF CHARACTER SENT
        BTST #3,D1
        BEQ.S PORTIN21  ;NONE SENT
        MOVE.B $21(A0),D1 ;READ WHAT WAS SENT
        ANDI.B #$7F,D1   ;GET RID OF PARITY BIT
        CMPI.B #1,D1    ;SEE IF CTL A
        BNE.S PORTIN21  ;
        BSR FIXBUF      ;
        MOVE.L #$2A41424F,(A6)+ ;"*ABO
        MOVE.L #$52542A20,(A6)+ ;     RT *"
        BRA MSG
PORTIN21 MOVE.B $23(A3),D1 ;READ STATUS OF PORT2
        BTST #3,D1      ;SEE IF CHARACTER SENT
        BEQ.S POR2IN2   ;LOOP AROUND
        MOVE.B $21(A3),D1 ;READ CHARACTER SENT
        ANDI.B #$7F,D1   ;DROP PARITY BIT
        TST.W WORK2.W   ;SEE IF ECHO ON
        BEQ.S PORTIN25
        MOVE.B D1,$21(A0) ;SEND TO DATA SIDE
;                                               6/8/82 END
PORTIN25 CMPI.B #$D,D1  ;SEE IF END OF LINE
        BNE.S PORTIN22
        MOVEM.L (A7)+,D1-D3/A0-A3       ;RESTORE THE REGISTERS
        RTS
PORTIN22 BRA PATCH1     ;******GO TO PATCH AREA*****
        NOP
        MOVE.B D1,(A6)+ ;SAVE CHAR IN BUFFER
        BRA.S POR2IN2   ;GO DO ANOTHER
;
;       TRANSPARENT MODE
;
P2CMD   MOVEQ.L #1,D7   ;DEFAULT IS CNTL 'A'
        MOVE.L #ROM+P2CMD0-ZERO,A0
        BSR FINDNP      ;FIND NEXT PARAMETER
        MOVE.B (A5),D7  ;QUIT CHARACTER
P2CMD0  BSR GETACIA1    ;ADDRESS FOR PORT1 INTO A0
        BSR FIXBUF      ;SET UP FOR MESSAGE
        MOVE.W #$0D0A,(A6)+
        MOVE.L #'*TRA',(A6)+
        MOVE.L #'NSPA',(A6)+
        MOVE.L #'RENT',(A6)+
        MOVE.W #'* ',(A6)+
        MOVE.L #'EXIT',(A6)+
        MOVE.W #'=$',(A6)+
        MOVE.L D7,D0    ;EXIT CHARACTER
        BSR PNT2HX      ;PRINT 2 HEX CHARACTERS
        MOVE.W #$0D0A,(A6)+
        BSR OUT1CR      ;GO PRINT BUFFER WITH CRLF
;
;                                                       6/8/82 START
        MOVE.B COMM1.W,D0
        MOVE.B #$FD,$21(A0) ;SEND "TURN OFF SPECIAL CHAR"
P2CMD1  MOVE.B $23(A0),D0 ;READ STATUS
        BTST #3,D0
        BNE.S P2CMD3
        MOVE.B 3(A0),D0 ;KEYBOARD INPUT?
        BTST #3,D0
        BEQ INCHNE2
        ;BSR KEYIN
P2CMD3  MOVE.B $21(A0),D0 ;LISTEN IN
        ANDI.B #$7F,D0   ;NO PARITY BIT
        CMP.B D0,D7     ;SEE IF QUIT CHAR
        BEQ.S UNTRANS   ;EXIT TRANSPARENT MODE
        BSR.S OUTCH4    ;TRANSMIT NORMAL STUFF
INCHNE2 MOVE.B $43(A0),D1 ;GET STATUS
        BTST #3,D1      ;INBOUND CHAR?
        BEQ.S P2CMD1
        MOVE.B $41(A0),D0 ;GET CHAR
        ANDI.B #$7F,D0   ;NO PARITY BIT
        BSR OUTCH
        BRA.S P2CMD1    ;LOOP TO INBOUND CHAR
UNTRANS BSR INITACIA
        BSR.S FIXBUF
        MOVE.L #$0D0A,(A6)+
        MOVE.L #$2A4D6163,(A6)+ ;"*MAC
        MOVE.L #$73627567,(A6)+ ;     SBUG
        MOVE.L #$2A20,(A6)+     ;          *"
        BSR.S GETACIA2
        MOVE.B #$18,$21(A0)     ;SEND CTRL-X TO HOST
        BRA MSG
OUTCH4  MOVE.B $43(A0),D1 ;GET STATUS
        BTST #4,D1      ;TRANS REG READY?
        BEQ.S OUTCH4
        MOVE.B D0,$41(A0) ;SEND CHAR
        RTS
;                                                       6/8/82 END
;       
;       GET ADDRESS OF ACIA1 PORT1 CONSOLE INTO A0
;
GETACIA1 MOVE.L ALTACIA1.W,A0   ;GET ALTERNATE ACIA ADDRESS
        BNE.S RET
        MOVE.L #$030F00,A0      ;USE DEFAULT
RET     RTS
;
;       GET ADDRESS OF ACIA2 PORT2 HOST INTO A0
;
GETACIA2 MOVE.L ALTACIA2.W,A0   ;ALTERNATE
        BNE.S RET
        MOVE.L #$030F20,A0      ;USE DEFAULT
        RTS
;                                                       6/8/82 END
;       FIX THE BUFFER A5 & A6 SET TO START OF BUFFER QUE
;
FIXBUF  MOVE.L #BUFFER,A5
        MOVE.L A5,A6
        RTS
        PAGE
;
;       SCAN COMMAND LINE FOR PORT NUMBER
;       PU2     RE1     ;SY3    PR2 etc.
;
SCANPORT MOVE.L A5,A4   ;LOAD UP A TEMP SCANNER
        CLR.L INFROM.W  ;DEFAULT IS WHATEVER IS CALLED
        CLR.L OUTTO.W
SCANP1  CMPA.L A6,A4    ;SEE IF AT END OF BUFFER
        BMI.S SCANP3
SCANP2  RTS
SCANP3  MOVE.B (A4)+,D0 ;GET A CHARACTER
        CMPI.B #' ',D0  ;SEE IF IT IS A SPACE
        BEQ.S SCANP2
        CMPI.B #'1',D0  ;SEE IF PORT 1 OVERRIDE
        BNE.S SCANP4
        MOVE.L INPORT1.W,INFROM.W
        MOVE.L OUTPORT1.W,OUTTO.W
        RTS
SCANP4  CMPI.B #'2',D0  ;SEE IF PORT 2 OVERRIDE
        BNE.S SCANP5
        MOVE.L INPORT2.W,INFROM.W
        MOVE.L OUTPORT2.W,OUTTO.W
        RTS
SCANP5  CMPI.B #'3',D0  ;SEE IF PORT3 OVERRIDE
        BNE.S SCANP1
        MOVE.L INPORT3.W,INFROM.W
        MOVE.L OUTPORT3.W,OUTTO.W
        RTS
                PAGE
;
;       ***TRAP 15*** USER CALLS THE IO ROUTINES
;
TRAP15  MOVE.L 2(A7),A0 ;GET USERS PC
        MOVE.W (A0)+,D0 ;GET PARAMETER
        MOVE.L A0,2(A7) ;NEW PROGRAM COUNTER
        MOVE.L A0,REGPC.W       ;ALSO IN TD
;
        TST.W D0        ;SEE IF ZERO
        BNE.S UIO1
        BSR SWAPOUT     ;TAKE BREAKPOINTS OUT
        BSR TDISPLY
        BRA MACSBUG     ;PUT USER IN MACSBUG
;
UIO1    CMPI.W #1,D0    ;SEE WHAT FLAVOR ETC.
        BNE.S UIO2
        BSR PORTIN1X    ;TAKE IN LINE FROM CONSOLE
        BRA.S UIO9
UIO2    CMPI.W #2,D0
        BNE.S UIO3
        BSR OUT1CRX     ;SEND LINE TO CONSOLE WITH CRLF
        BRA.S UIO9
UIO3    CMPI.W #3,D0
        BNE.S UIO4
        BSR PORTIN2X    ;TAKE IN LINE FROM PORT 2
        BRA.S UIO9
UIO4    CMPI.W #4,D0
        BNE.S UIO7
        BSR OUTPUT2X    ;SEND LINE TO CONSOLE WITH CRLF
        BRA.S UIO9
UIO7    CMPI.W #7,D0    ;ADDED 12/13/79.....
        BNE ERROR
        BSR OUTPUT      ;SEND LINE TO CONSOLE WITH NO CRLF
;                PATCHED 12/13/79
UIO9    MOVE.L REGS.W,D0        ;RESTORE D0
        MOVE.L REGS+32.W,A0     ;RESTORE A0
        RTE             ;RETURN TO USER
        PAGE
;***********************************************************************
;                                                               *
;       PATCH AREA *
;       1) IGNORE DEL CHARACTER HEX($7F) FROM PORT2 INPUT       *10/11/79*
;                                                               *
;       2) DISPLAY CORRECT DATA FROM THE DATA CONVERT ROUTINE.  *08/14/80*
;                                                               *
;       3) MOVE STOP BITS TO ACIA AT END OF "FO" COMMAND.       *08/14/80*
;                                                               *
;***********************************************************************
;
PATCH1  CMPI.B #$20,D1  ;SEE IF CTL CHAR
        BLT POR2IN2
        CMPI.B #$7F,D1  ;SEE IF GREATER OR EQUAL TO DEL
        BGE POR2IN2
        MOVE.B D1,(A6)+ ;SAVE CHARACTER
        BRA POR2IN2     ;READ ANOTHER
;
PATCH2  MOVE.L  D7,D0   ;MOVE RESULT TO D0
        BRA     PNT8HX  ;GO SET UP 8 HEX CHARS... (STACK IS SET FOR RTS)
;
PATCH3  BSR     INITACIA        ;GO INIT ACIA
        BRA     MACSBUG ;AND RE-ENTER MACSBUG.
        PAGE
;
; FILL ANY REMAINING MEMORY WITH HIGH VALUES
;

        END START
