OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [src/] [sys09bug/] [sys09bug.asm] - Rev 105

Go to most recent revision | Compare with Previous | Blame | View Log

* NAM SYS09BUG12 SYSTEM09 MONITOR
 OPT l
 PAGE
*
* MONITOR PROGRAM FOR THE SOUTHWEST TECHNICAL
* PRODUCTS MP-09 CPU BOARD AS COMMENTED BY....
*
* ALLEN CLARK            WALLACE WATSON
* 2502 REGAL OAKS LANE   4815 EAST 97th AVE.
* LUTZ, FLA. 33549       TEMPLE TERRACE, FLA. 33617
* PH. 813-977-0347       PH. 813-985-1359
*
* MODIFIED TO SBUG09 VER 1.8 BY:  RANDY JARRETT
*                                 2561 NANTUCKET DR APT. E
*                                 ATLANTA, GA  30345
*                                 PH. 404-320-1043
*
* MODIFIED TO SYS09BUG VER 1.0
* FOR:     SYSTEM09 FPGA SYSTEM
* BY:      JOHN KENT
* DATE:    21ST NOVEMBER 2006
* REMOVED: DISK BOOTS
*          MEMORY TEST
* ADDED:   ADM3A VDU DRIVER
*
* MODIFIED TO SYS09BUG VER 1.1
* FOR:     SYSTEM09 FPGA SYSTEM
* BY:      JOHN KENT
* DATE:    7TH JANUARY 2007
* ADDED:   'U' USER EXTENTION COMMANDS AT $F000
*          CONDITIONAL ASSEMBLY OF FLOPPY BOOTS
*          AND REALTIME CLOCK
*
* MODIFIED TO SYS09BUG VER 1.2
* FOR:     SYSTEM09 FPGA SYSTEM
* BY:      JOHN KENT
* DATE:    21ST MAY 2007
* ADDED:   COMPACT FLASH BOOT TO FPGA VERSION
*          REMOVED PORT REDIRECTION ON PUNCH & LOAD
*
* Modified to SYS09BUG VER 1.3
* FOR:     SYSTEM09 FPGA SYSTEM
* BY:      JOHN KENT
* DATE:    8TH JAN 2008
* ADDED:   CONDITIONALS FOR SPARTAN3E STARTER BOARD
*          WITH ONLY 32K OF RAM
*
* Modified to SYS09BUG VER 1.4
* FOR:     SYSTEM09 FPGA SYSTEM
* BY:      JOHN KENT
* DATE:    3RD FEB 2008
* ADDED:   CONDITIONALS FOR XESS BOARD WITH IDE
*          SEPERATE CONDITIONAL FOR S3 STARTER AND B5-X300
*          16 BIT IDE DISK BOOT STRAP ROUTINE
*
* Modified to SYS09BUG VER 1.5
* FOR:     SYSTEM09 FPGA SYSTEM
* BY:      JOHN KENT
* DATE:    7TH SEP 2008
* ADDED:   ADDED "B3-S2+" STRING
*
* Modified to SYS09BUG VER 1.6
* FOR:     SYSTEM09 FPGA SYSTEM
* BY:      JOHN KENT
* DATE:    2ND DEC 2008
* ADDED:   ADDED HARDWARE FLOW CONTROL
*
* CHANGED: SEPARARTED OPTIONS EQUATES AND BODY INTO SEPARATE FILES
*
*       *** COMMANDS ***
*
* CONTROL A   = ALTER THE "A" ACCUMULATOR
* CONTROL B   = ALTER THE "B" ACCUMULATOR
* CONTROL C   = ALTER THE CONDITION CODE REGISTER
* CONTROL D   = ALTER THE DIRECT PAGE REGISTER
* CONTROL P   = ALTER THE PROGRAM COUNTER
* CONTROL U   = ALTER USER STACK POINTER
* CONTROL X   = ALTER "X" INDEX REGISTER
* CONTROL Y   = ALTER "Y" INDEX REGISTER
* B hhhh      = SET BREAKPOINT AT LOCATION $hhhh
* D           = 5.25" MINIFLOPPY BOOT
* E ssss-eeee = EXAMINE MEMORY
*               FROM STARTING ADDRESS ssss
*               TO ENDING ADDRESS eeee.
* G           = CONTINUE EXECUTION FROM BREAKPOINT OR SWI
* L           = LOAD TAPE
* M hhhh      = EXAMINE AND CHANGE MEMORY LOCATION hhhh
* P ssss-eeee = PUNCH TAPE, START ssss TO END eeee ADDR.
* R           = DISPLAY REGISTER CONTENTS
* S           = DISPLAY STACK FROM ssss TO $DFC0
* U           = 8" DMAF2 FLOPPY BOOT
* U           = USER EXTENSION COMMANDS AT $F000
* X           = REMOVE ALL BREAKPOINTS
*
*
***************************************************
*   SYS09BUG VARIABLE SPACE
***************************************************
*
        ORG   MONRAM
STACK   EQU   *         ; TOP OF INTERNAL STACK
NMI     RMB   2         ; USER NMI VECTOR
SWI3    RMB   2         ; SOFTWARE INTERRUPT VECTOR #3
SWI2    RMB   2         ; SOFTWARE INTERRUPT VECTOR #2
FIRQ    RMB   2         ; FAST INTERRUPT VECTOR
IRQ     RMB   2         ; INTERRUPT VECTOR
SWI     RMB   2         ; SOFTWARE INTERRUPT VECTOR
SVCVO   RMB   2         ; SUPERVISOR CALL VECTOR ORGIN
SVCVL   RMB   2         ; SUPERVISOR CALL VECTOR LIMIT
        IFD DATOPT
LRARAM  RMB  16         ; LRA ADDRESSES
        ENDIF DATOPT
CPORT   RMB   2         ; RE-VECTORABLE CONTROL PORT
ECHO    RMB   1         ; ECHO FLAG
BPTBL   RMB  24         ; BREAKPOINT TABLE BASE ADDR
        IFD  TRAOPT
NMISAV  RMB   2         ; NMI Jump Vector Backup
TRACNT  RMB   2         ; Trace Count
        ENDIF TRAOPT
        IFD VDUOPT
*
**************************************************
*   VDU8 DISPLAY DRIVER VARIABLES                                    *
**************************************************
*
**** ALWAYS KEEP COLADX AND ROWADX TOGETHER ******
COLADX  RMB   1         ; CURSOR COLUMN
ROWADX  RMB   1         ; CURSOR ROW
**************************************************
*
NEWROW  RMB   1         ; NEW ROW TEMP FOR ESCAPE
ESCFLG  RMB   1         ; ESCAPE SEQUENCE ACTIVE
        ENDIF VDUOPT
        IFD DG640OPT
*
***************************************************
*   DG640 MEMORY MAPPED DISPLAY DRIVER VARIABLES  *
***************************************************
*
***** ALWAYS KEEP THESE TWO BYTES TOGETHER *****
COLADX  RMB   1        ; CURSOR COLUMN
ROWADX  RMB   1        ; CURSOR ROW
*************************************************
CURSOR  RMB   2        ; ABSOLUTE SCREEN ADDRESS
NEWROW  RMB   1        ; NEW ROW TEMP FOR ESCAPE
ESCFLG  RMB   1        ; ESCAPE SEQUENCE ACTIVE
        ENDIF DG640OPT
*
*
***************************************************
*   START OF ROM                                  *
***************************************************
*
        ORG   MONROM
        FDB   MONITOR
        FDB   NEXTCMD
        FDB   INCH
        FDB   INCHE
        FDB   INCHEK
        FDB   OUTCH
        FDB   PDATA
        FDB   PCRLF
        FDB   PSTRNG
        FDB   LRA
*
        IFD   ADSOPT
        FDB   PCHK     ; CHECK FOR PRINTER INPUT
        FDB   PINIZ    ; INITIATE PRINTER
        FDB   POUTCH   ; OUTPUT CH. TO PRINTER
        FDB   VINIZ
        FDB   VOUTCH
        FDB   ACINIZ
        FDB   AOUTCH
        ENDIF ADSOPT
*
* MONITOR
*
* VECTOR ADDRESS STRING IS.....
* $F8A1-$F8A1-$F8A1-$F8A1-$F8A1-$FAB0-$FFFF-$FFFF
*
MONITOR LDX   #RAMVEC  ; POINT TO VECTOR ADDR. STRING
        LDY   #STACK   ; POINT TO RAM VECTOR LOCATION
        LDB   #$10     ; BYTES TO MOVE = 16
LOOPA   LDA   ,X+      ; GET VECTOR BYTE
        STA   ,Y+      ; PUT VECTORS IN RAM / $DFC0-$DFCF
        DECB           ; SUBTRACT 1 FROM NUMBER OF BYTES TO MOVE
        BNE   LOOPA    ; CONTINUE UNTIL ALL VECTORS MOVED
*
* CONTENTS     FROM         TO      FUNCTION
*  $F8A1       $FE40      $DFC0     USER-V
*  $F8A1       $FE42      $DFC2     SWI3-V
*  $F8A1       $FE44      $DFC4     SWI2-V
*  $F8A1       $FE46      $DFC6     FIRQ-V
*  $F8A1       $FE48      $DFC8     IRQ-V
*  $FAB0       $FE4A      $DFCA     SWI-V
*  $FFFF       $FE4C      $DFCC     SVC-VO
*  $FFFF       $FE4E      $DFCE     SVC-VL
*
        LDX   #ACIAS
        STX   CPORT    ; STORE ADDR. IN RAM
        LBSR  XBKPNT   ; CLEAR OUTSTANDING BREAKPOINTS
        LDB   #12      ; CLEAR 12 BYTES ON STACK
CLRSTK  CLR   ,-S
        DECB
        BNE   CLRSTK
        LEAX  MONITOR,PCR  ; SET PC TO SBUG-E ENTRY
        STX   10,S    ; ON STACK
        LDA   #$D0    ; PRESET CONDITION CODES ON STACK
        STA   ,S
        TFR   S,U
        LBSR  IOINIZ  ; INITIALIZE CONTROL PORT
        LDX   #MSG1   ; POINT TO MONITOR MESSAGE
        LBSR  PDATA   ; PRINT MSG
*
        IFD   DATOPT
        LDX   #LRARAM ; POINT TO LRA RAM STORAGE AREA
        CLRA  START   ; TOTAL AT ZERO
        LDB   #13     ; TOTAL UP ALL ACTIVE RAM MEMORY
FNDREL  TST   B,X     ; TEST FOR RAM AT NEXT LOC.
        BEQ   RELPAS  ; IF NO RAM GO TO NEXT LOC.
        ADDA  #4      ; ELSE ADD 4K TO TOTAL
        DAA           ; ADJ. TOTAL FOR DECIMAL
RELPAS  DECB          ; SUB. 1 FROM LOCS. TO TEST
        BPL   FNDREL  ; PRINT TOTAL OF RAM
        LBSR  OUT2H   ; OUTPUT HEX BYTE AS ASCII
        LDX   #MSG2   ; POINT TO MSG 'K' CR/LF + 3 NULS
        LBSR  PDATA   ; PRINT MSG
        ENDIF DATOPT
*
        IFD   TRAOPT
        LBSR  TRAINZ
        ENDIF TRAOPT
*
***** NEXTCMD *****
*
NEXTCMD LDX  #MSG3   ; POINT TO MSG ">"
        LBSR PSTRNG  ; PRINT MSG
        LBSR INCH    ; GET ONE CHAR. FROM TERMINAL
        ANDA #$7F    ; STRIP PARITY FROM CHAR.
        CMPA #$0D    ; IS IT CARRIAGE RETURN ?
        BEQ  NEXTCMD ; IF CR THEN GET ANOTHER CHAR.
        TFR  A,B     ; PUT CHAR. IN "B" ACCUM.
        CMPA #$20    ; IS IT CONTROL OR DATA CHAR ?
        BGE  PRTCMD  ; IF CMD CHAR IS DATA, PRNT IT
        LDA  #'^     ; ELSE CNTRL CHAR CMD SO...
        LBSR OUTCH   ; PRINT "^"
        TFR  B,A     ; RECALL CNTRL CMD CHAR
        ADDA #$40    ; CONVERT IT TO ASCII LETTER
PRTCMD  LBSR OUTCH   ; PRNT CMD CHAR
        LBSR OUT1S   ; PRNT SPACE
        CMPB #$60
        BLE  NXTCH0
        SUBB #$20
*
***** DO TABLE LOOKUP *****
*   FOR COMMAND FUNCTIONS
*
NXTCH0  LDX  #JMPTAB ; POINT TO JUMP TABLE
NXTCHR  CMPB ,X+     ; DOES COMMAND MATCH TABLE ENTRY ?
        BEQ  JMPCMD  ; BRANCH IF MATCH FOUND
        LEAX 2,X     ; POINT TO NEXT ENTRY IN TABLE
        CMPX #TABEND ; REACHED END OF TABLE YET ?
        BNE  NXTCHR  ; IF NOT END, CHECK NEXT ENTRY
        LDX  #MSG4   ; POINT TO MSG "WHAT?"
        LBSR PDATA   ; PRINT MSG
        BRA  NEXTCMD ; IF NO MATCH, PRMPT FOR NEW CMD
JMPCMD  JSR  [,X]    ; JUMP TO COMMAND ROUTINE
        BRA  NEXTCMD ; PROMPT FOR NEW COMMAND
*
* "G" GO OR CONTINUE
*
GO      TFR  U,S
RTI     RTI
*
***** "M" MEMORY EXAMINE AND CHANGE *****
*
MEMCHG  LBSR IN1ADR  ; INPUT ADDRESS
        BVS  CHRTN   ; IF NOT HEX, RETURN
        TFR  X,Y     ; SAVE ADDR IN "Y"
MEMC2   LDX  #MSG5   ; POINT TO MSG " - "
        LBSR PSTRNG  ; PRINT MSG
        TFR  Y,X     ; FETCH ADDRESS
        LBSR OUT4H   ; PRINT ADDR IN HEX
        LBSR OUT1S   ; OUTPUT SPACE
        LDA  ,Y      ; GET CONTENTS OF CURRENT ADDR.
        LBSR OUT2H   ; OUTPUT CONTENTS IN ASCII
        LBSR OUT1S   ; OUTPUT SPACE
        LBSR BYTE    ; LOOP WAITING FOR OPERATOR INPUT
        BVC  CHANGE  ; IF VALID HEX GO CHANGE MEM. LOC.
        CMPA #8      ; IS IT A BACKSPACE (CNTRL H)?
        BEQ  MEMC2   ; PROMPT OPERATOR AGAIN
        CMPA #$18    ; IS IT A CANCEL (CNTRL X)?
        BEQ  MEMC2   ; PROMPT OPERATOR AGAIN
        CMPA #'^     ; IS IT AN UP ARROW?
        BEQ  BACK    ; DISPLAY PREVIOUS BYTE
        CMPA #$D     ; IS IT A CR?
        BNE  FORWRD  ; DISPLAY NEXT BYTE
CHRTN   RTS          ; EXIT ROUTINE
*
*
CHANGE  STA  ,Y      ; CHANGE BYTE IN MEMORY
        CMPA ,Y      ; DID MEMORY BYTE CHANGE?
        BEQ  FORWRD  ; $F972
        LBSR OUT1S   ; OUTPUT SPACE
        LDA  #'?     ; LOAD QUESTION MARK
        LBSR OUTCH   ; PRINT IT
FORWRD  LEAY 1,Y     ; POINT TO NEXT HIGHER MEM LOCATION
        BRA  MEMC2   ; PRINT LOCATION & CONTENTS
BACK    LEAY -1,Y    ; POINT TO LAST MEM LOCATION
        BRA  MEMC2   ; PRINT LOCATION & CONTENTS
*
* "S" DISPLAY STACK
* HEX-ASCII DISPLAY OF CURRENT STACK CONTENTS FROM
** CURRENT STACK POINTER TO INTERNAL STACK LIMIT.
*
DISSTK  LBSR PRTSP   ; PRINT CURRENT STACK POINTER
        TFR  U,Y
        LDX  #STACK  ; LOAD INTERNAL STACK AS UPPER LIMIT
        LEAX -1,X    ; POINT TO CURRENT STACK
        BRA  MDUMP1  ; ENTER MEMORY DUMP OF STACK CONTENTS
*
* "E" DUMP MEMORY FOR EXAMINE IN HEX AND ASCII
* AFTER CALLING 'IN2ADR' LOWER ADDRESS IN Y-REG.
*                        UPPER ADDRESS IN X-REG.
* IF HEX ADDRESSES ARE INVALID (V)=1.
*
MEMDUMP LBSR IN2ADR  ; INPUT ADDRESS BOUNDRIES
        BVS  EDPRTN  ; NEW COMMAND IF ILLEGAL HEX
MDUMP1  PSHS Y       ; COMPARE LOWER TO UPPER BOUNDS
        CMPX ,S++    ; LOWER BOUNDS > UPPER BOUNDS?
        BCC  AJDUMP  ; IF NOT, DUMP HEX AND ASCII
EDPRTN  RTS          ;
*
* ADJUST LOWER AND UPPER ADDRESS LIMITS
* TO EVEN 16 BYTE BOUNDRIES.
*
* IF LOWER ADDR = $4532
* LOWER BOUNDS WILL BE ADJUSTED TO = $4530.
*
* IF UPPER ADDR = $4567
* UPPER BOUNDS WILL BE ADJUSTED TO = $4570.
*
* ENTER WITH LOWER ADDRESS IN X-REG.
*           -UPPER ADDRESS ON TOP OF STACK.
*
AJDUMP  TFR  X,D     ; GET UPPER ADDR IN D-REG
        ADDD #$10    ; ADD 16 TO UPPER ADDRESS
        ANDB #$F0    ; MASK TO EVEN 16 BYTE BOUNDRY
        PSHS A,B     ; SAVE ON STACK AS UPPER DUMP LIMIT
        TFR  Y,D     ; $F9A5 GET LOWER ADDRESS IN D-REG
        ANDB #$F0    ; MASK TO EVEN 16 BYTE BOUNDRY
        TFR  D,X     ; PUT IN X-REG AS LOWER DUMP LIMIT
NXTLIN  CMPX ,S      ; COMPARE LOWER TO UPPER LIMIT
        BEQ  SKPDMP  ; IF EQUAL SKIP HEX-ASCII DUMP
        LBSR INCHEK  ; CHECK FOR INPUT FROM KEYBOARD
        BEQ  EDUMP
SKPDMP  LEAS 2,S     ; READJUST STACK IF NOT DUMPING
        RTS          ;
*
* PRINT 16 HEX BYTES FOLLOWED BY 16 ASCII CHARACTERS
* FOR EACH LINE THROUGHOUT ADDRESS LIMITS.
*
EDUMP   PSHS X       ; PUSH LOWER ADDR LIMIT ON STACK
        LDX  #MSG5   ; POINT TO MSG " - "
        LBSR PSTRNG  ; PRINT MSG
        LDX  ,S      ; LOAD LOWER ADDR FROM TOP OF STACK
        LBSR OUT4H   ; PRINT THE ADDRESS
        LBSR OUT2S   ; 2 SPACES
        LDB  #$10    ; LOAD COUNT OF 16 BYTES TO DUMP
ELOOP   LDA  ,X+     ; GET FROM MEMORY HEX BYTE TO PRINT
        LBSR OUT2H   ; OUTPUT HEX BYTE AS ASCII
        LBSR OUT1S   ; OUTPUT SPACE
        DECB         ; $F9D1 DECREMENT BYTE COUNT
        BNE  ELOOP   ; CONTINUE TIL 16 HEX BYTES PRINTED
*
* PRINT 16 ASCII CHARACTERS
* IF NOT PRINTABLE OR NOT VALID
* ASCII PRINT A PERIOD (.)
        LBSR OUT2S   ; 2 SPACES
        LDX  ,S++    ; GET LOW LIMIT FRM STACK - ADJ STACK
        LDB  #$10    ; SET ASCII CHAR TO PRINT = 16
EDPASC  LDA  ,X+     ; GET CHARACTER FROM MEMORY
        CMPA #$20    ; IF LESS THAN $20, NON-PRINTABLE?
        BCS  PERIOD  ; IF SO, PRINT PERIOD INSTEAD
        CMPA #$7E    ; IS IT VALID ASCII?
        BLS  PRASC   ; IF SO PRINT IT
PERIOD  LDA  #'.     ; LOAD A PERIOD (.)
PRASC   LBSR OUTCH   ; PRINT ASCII CHARACTER
        DECB         ; DECREMENT COUNT
        BNE  EDPASC
        BRA  NXTLIN
*
***** "B" SET BREAKPOINT *****
*
BRKPNT  LBSR IN1ADR  ; GET BREAKPOINT ADDRESS
        BVS  EXITBP  ; EXIT IF INVALID HEX ADDR.
        CMPX #STACK  ; ADDRESS ILLEGAL IF >=$DFC0
        BCC  BPERR   ; IF ERROR PRINT (?), EXIT
        PSHS X       ; $FA82 PUSH BP ADDRESS ON STACK
        LDX  #$FFFF  ; LOAD DUMMY ADDR TO TEST BP TABLE
        BSR BPTEST   ; TEST BP TABLE FOR FREE SPACE
        PULS X       ; POP BP ADDRESS FROM STACK
        BEQ  BPERR   ; (Z) SET, OUT OF BP TABLE SPACE
        LDA  ,X      ; GET DATA AT BREAKPOINT ADDRESS
        CMPA #$3F    ; IS IT A SWI?
        BEQ  BPERR   ; IF SWI ALREADY, INDICATE ERROR
        STA  ,Y+     ; SAVE DATA BYTE IN BP TABLE
        STX  ,Y      ; SAVE BP ADDRESS IN BP TABLE
        LDA  #$3F    ; LOAD A SWI ($3F)
        STA  ,X      ; SAVE SWI AT BREAKPOINT ADDRESS
EXITBP  RTS ;
*
*  INDICATE ERROR SETTING BREAKPOINT
*
BPERR   LBSR OUT1S   ; OUTPUT SPACE
        LDA  #'?     ; LOAD (?), INDICATE BREAKPOINT ERROR
        LBRA OUTCH   ; PRINT "?"
*
*** "X" CLEAR OUTSTANDING BREAKPOINTS ***
*
XBKPNT  LDY  #BPTBL  ; POINT TO BREAKPOINT TABLE
        LDB  #8      ; LOAD BREAKPOINT COUNTER
XBPLP   BSR  RPLSWI  ; REMOVE USED ENTRY IN BP TABLE
        DECB  $FAAC  ; DECREMENT BP COUNTER
        BNE  XBPLP   ; END OF BREAKPOINT TABLE?
        RTS
*
***** SWI ENTRY POINT *****
*
SWIE    TFR  S,U     ; TRANSFER STACK TO USER POINTER
        LDX  10,U    ; LOAD PC FROM STACK INTO X-REG
        LEAX -1,X    ; ADJUST ADDR DOWN 1 BYTE.
        BSR  BPTEST  ; FIND BREAKPOINT IN BP TABLE
        BEQ  REGPR   ; IF FOUND, REPLACE DATA AT BP ADDR
        STX  10,U    ; SAVE BREAKPOINT ADDR IN STACK
        BSR  RPLSWI  ; GO REPLACE SWI WITH ORIGINAL DATA
REGPR   LBSR REGSTR  ; GO PRINT REGISTERS
*
        IFD TRAOPT
        LDX #0
        STX TRACNT
        ENDIF TRAOPT
*
        LBRA NEXTCMD ; GET NEXT COMMAND
*
RPLSWI  LDX  1,Y     ; LOAD BP ADDRESS FROM BP TABLE
        CMPX #STACK  ; COMPARE TO TOP AVAILABLE USER MEMORY
        BCC  FFSTBL  ; GO RESET TABLE ENTRY TO $FF'S
        LDA  ,X      ; GET DATA FROM BP ADDRESS
        CMPA #$3F    ; IS IT SWI?
        BNE  FFSTBL  ; IF NOT, RESET TABLE ENTRY TO $FF'S
        LDA  ,Y      ; GET ORIGINAL DATA FROM BP TABLE
        STA  ,X      ; $FAD3 RESTORE DATA AT BP ADDRESS
FFSTBL  LDA  #$FF    ; LOAD $FF IN A-ACC
        STA  ,Y+     ; RESET BREAKPOINT TABLE DATA TO $FF'S
        STA  ,Y+     ; RESET BREAKPOINT TABLE ADDR TO $FF'S
        STA  ,Y+
        RTS
*
** SEARCH BREAKPOINT TABLE FOR MATCH **
*
BPTEST  LDY  #BPTBL  ; POINT TO BREAKPOINT TABLE
        LDB  #8      ; LOAD BREAKPOINT COUNTER
FNDBP   LDA  ,Y+     ; LOAD DATA BYTE
        CMPX ,Y++    ; COMPARE ADDRESS, IS IT SAME?
        BEQ  BPADJ   ; IF SO, ADJUST POINTER FOR TABLE ENTRY
        DECB         ; IF NOT, DECREMENT BREAKPOINT COUNTER
        BNE  FNDBP   ; AND LOOK FOR NEXT POSSIBLE MATCH
        RTS          ;
*
*
BPADJ   LEAY -3,Y    ; MOVE POINTER TO BEGIN OF BP ENTRY
        RTS
*
        IFD TRAOPT
*
** TRACE from address AAAA BB bytes
*
TRACE   LBSR ALTPC1  ; SET UP NEW PC
        BVS  TREXIT  ; ADDRESS ERROR, EXIT
        LBSR OUT1S
        LBSR IN1ADR  ; Fetch Byte Count
        BVS TREXIT   ; Byte Count error, EXIT
        STX TRACNT
*
        LDX NMI      ; Save NMI Vector
        STX NMISAV
        LDX #NMIE    ; Set up NMI for Tracing
        STX NMI
        LBSR TRAINZ  ; Initialise Hardware
        BRA TRACEG   ; Start Trace
TREXIT  RTS
*
* CRA0 = 0 CA1 IRQ DISAB, CRA0 = 1 CA1 IRQ ENAB
* CRA1 = 1 CA1 Rising edge IRQ
* CRA2 = 0 TADATA = Data Direction, CRA2 = 1 TADATA = I/O Register
* CRA3 = 0 CA2 = 0 output, CRA3 = 1 CA2 = 1
* CRA4 = 1 ] CA2 = Set/Reset output
* CRA5 = 1 ]
* CRA6 = X CA2 Input Interrupt Flag
* CRA7 = X CA1 Interrupt Flag
*
* CRB0 = 0 CB1 IRQ DISAB, CRB0 = 1 CA1 IRQ ENAB
* CRB1 = 1 CB1 Rising edge IRQ
* CRB2 = 0 TBDATA = Data Direction, CRB2 = 1 TBDATA = I/O Register
* CRB3 = 0 CB2 = 0 output, CRB3 = 1 CB2 = 1
* CRB4 = 1 ] CB2 = Set/Reset output
* CRB5 = 1 ]
* CRB6 = X CB2 Input Interrupt Flag
* CRB7 = X CB1 Interrupt Flag
*
*
** TRACE NMI ENTRY POINT
*
NMIE    TFR  S,U
        LDA  #$36    ; Disable Interrupt, CA2 Low
        STA  TACTRL
        LDA  TADATA  ; Clear Interrupt flag by reading data port
*
        LBSR REGSTR  ; DUMP REGISTERS
*
        LDX  10,U    ; TEST IF NEXT INSTRUCTION IS A SWI
        LDA  ,X
        CMPA #$3F
        BEQ  TRACEX  ; EXIT ON SWI
*
        LDX  TRACNT  ; CHECK IF TRACE COUNT EXPIRED
        BEQ  TRACEX  ; YES, GO BACK TO THE MONITOR
        LEAX -1,X    ; ECREMENT TRACE COUNT
        STX  TRACNT
*
**  TRACE GO (RESUME SINGLE STEP)
*
TRACEG  TFR  U,S     ; SET UP PROGRAM STACK POINTER
        LDA  #TRADEL ; SET UP TIMER DELAY (NUMB CYCLES FOR RTI+1)
        STA  TADATA
        LDA  #$36    ; LOAD STROBE LOW
        STA  TACTRL
        LDA  TADATA  ; CLEAR INTERRUPT
        LDA  #$36    ; RELEASE RESET
        STA  TBCTRL
        LDA  #$3F    ; RELEASE LOAD, ENABLE CA1 NMI, CA1 RISING EDGE
        STA  TACTRL
        RTI          ; GO EXECUTE INSTRUCTION
*
TRACEX  LDX NMISAV   ; Restore NMI vector
        STX NMI
        LBRA NEXTCMD ; Jump back to the command loop.
*
** TRACE HARDWARE INITIALISATION
*
TRAINZ  LDA #$32     ; SELECT DDRA, CA2 LOW, NMI DISABLED
        STA TACTRL
        LDA #$3A     ; SELECT DDRB, CB2 HIGH, FIRQ DISABLED
        STA TBCTRL
        LDA #$FF     ; PORTA = OUTPUT
        STA TADATA
        LDA #$00     ; PORTB = INPUT
        STA TBDATA
        LDA #$36     ; SELECT OUTPUT REGISTER A, CA2 LOW
        STA TACTRL
        LDA #$3E     ; SELECT OUTPUT REGISTER B, CB2 HIGH
        STA TBCTRL
        RTS
*
        ENDIF TRAOPT
        IFD  MFDCOPT
*
** "U" MINI DISK BOOT
*
MINBOOT TST  CMDFDC
        CLR  DRVFDC
        LDX  #$0000
LOOP    LEAX $01,X
        CMPX #$0000
        BNE  LOOP
        LDA  #$0F
        STA  CMDFDC
        BSR  DELAY
LOOP1   LDB  CMDFDC
        BITB #$01
        BNE  LOOP1
        LDA  #$01
        STA  SECFDC
        BSR  DELAY
        LDA  #$8C
        STA  CMDFDC
        BSR  DELAY
        LDX  #$C000
        BRA  LOOP3
LOOP2   BITB #$02
        BEQ  LOOP3
        LDA  DATFDC
        STA ,X+
LOOP3   LDB  CMDFDC
        BITB #$01
        BNE  LOOP2
        BITB #$2C
        BEQ  LOOP4
        RTS
*
LOOP4   LDX  #$C000
        STX  $0A,U
        TFR  U,S
        RTI
*
DELAY   LDB  #$04
LOOP5   DECB
        BNE  LOOP5
        RTS
        ENDIF MFDCOPT
*
        IFD  DMAFOPT
*
*** "D" DISK BOOT FOR DMAF2 ***
*
DBOOT   LDA  #$DE
        STA  DRVREG
        LDA  #$FF
        STA  PRIREG  ; $FAF8
        STA  CCREG
        STA  AAAREG
        STA  BBBREG
        TST  CCREG
        LDA  #$D8
        STA  COMREG
        LBSR DLY
DBOOT0  LDA  COMREG
        BMI  DBOOT0
        LDA  #$09
        STA  COMREG
        LBSR DLY
*
DISKWT  LDA  COMREG  ; FETCH DRIVE STATUS
        BITA #1      ; TEST BUSY BIT
        BNE  DISKWT  ; LOOP UNTIL NOT BUSY
*
        BITA #$10
        BNE  DBOOT
*
        LDX  #$C000  ; LOGICAL ADDR. = $C000
        BSR LRA      ; GET 20 BIT PHYSICAL ADDR. OF LOG. ADDR.
        ORA  #$10
        STA  CCCREG
        TFR  X,D
        COMA  ;
        COMB  ;
        STD  ADDREG
        LDX  #$FEFF  ; LOAD DMA BYTE COUNT = $100
        STX  CNTREG  ; STORE IN COUNT REGISTER
        LDA  #$FF    ; LOAD THE CHANNEL REGISTER
        STA  CCREG
        LDA  #$FE    ; SET CHANNEL 0
        STA  PRIREG
        LDA  #1      ; SET SECTOR TO "1"
        STA  SECREG  ; ISSUE COMMAND
        LDA  #$8C    ; SET SINGLE SECTOR READ
        STA  COMREG  ; ISSUE COMMAND
        BSR  DLY
*
* THE FOLLOWING CODE TESTS THE STATUS OF THE
* CHANNEL CONTROL REGISTER. IF "D7" IS NOT
* ZERO THEN IT WILL LOOP WAITING FOR "D7"
* TO GO TO ZERO. IF AFTER 65,536 TRIES IT
* IS STILL A ONE THE BOOT OPERATION WILL
* BE STARTED OVER FROM THE BEGINING.
*
        CLRB         ;
DBOOT1  PSHS B       ; $FB55
        CLRB         ;
DBOOT2  TST  CCREG
        BPL  DBOOT3
        DECB  ;
        BNE  DBOOT2
        PULS B
        DECB
        BNE  DBOOT1
        BRA  DBOOT
DBOOT3  PULS B
        LDA  COMREG
        BITA #$1C
        BEQ  DBOOT4
        RTS  ;
*
*
DBOOT4  LDB  #$DE
        STB  DRVREG
        LDX  #$C000
        STX  10,U
        TFR  U,S     ; $FB7B
        RTI  ;
        ENDIF DMAFOPT
*
        IFD CF8OPT
*
* COMPACT FLASH BOOT
*
CFBOOT  BSR  WAITRDY
        LDA  #HEADLBA
        STA  CF_HEAD
        BSR  WAITRDY
        LDA  #FEAT8BIT
        STA  CF_FEATURE
        LDA  #CMDFEATURE
        STA  CF_COMAND
        BSR  WAITRDY
*
* READ SECTORS FROM CF
*
CFREAD  LDA  #$01
        STA  CF_SECCNT
        CLRA
        STA  CF_SECNUM
        STA  CF_CYLLO
        STA  CF_CYLHI
*
        LDA  #CMDREAD ; IDE READ MULTIPLE
        STA  CF_COMAND
        BSR  WAITRDY
        LDX  #$C000
*
* READ LOOP
*
RDLOOP  BSR  WAITDRQ
        LDA  CF_DATA
        STA  ,X+
        CMPX #$C200
        BNE  RDLOOP
*
        LDX  #$C000
        STX  $0A,U
        TFR  U,S
        RTI
*
* WAIT UNTIL READY
*
WAITRDY LDA  CF_STATUS
        BITA #BUSY
        BNE  WAITRDY
        LDA  CF_STATUS
        BITA #DRDY
        BEQ  WAITRDY
        RTS
*
* WAIT FOR DATA REQUEST
*
WAITDRQ LDA  CF_STATUS
        BITA #DRQ
        BEQ  WAITDRQ
        RTS
        ENDIF CF8OPT
*
        IFD IDEOPT
*
* XESS 16 BIT IDE BOOT
*
IDEBOOT LDD  #AUXRESET
        STD  CF_AUX
        LDD #AUXRSTREL
        STD CF_AUX
        LDD  #HEADLBA
        STD  CF_HEAD
        BSR  WAITRDY
*
* READ SECTORS FROM CF
*
        LDD  #$01
        STD  CF_SECCNT
        CLRB
        STD  CF_SECNUM
        STD  CF_CYLLO
        STD  CF_CYLHI
*
        LDB  #CMDREAD ; IDE READ MULTIPLE
        STD  CF_COMAND
        BSR  WAITRDY
        LDX  #$C000
*
* READ LOOP
*
RDLOOP  BSR  WAITDRQ
        LDD  CF_DATA
        STB  ,X+
        CMPX #$C100
        BNE  RDLOOP
*
        LDX  #$C000
        STX  $0A,U
        TFR  U,S
        RTI
*
* WAIT UNTIL READY
*
WAITRDY LDD  CF_STATUS
        BITB #BUSY
        BNE  WAITRDY
        LDD  CF_STATUS
        BITB #DRDY
        BEQ  WAITRDY
        RTS
*
* WAIT FOR DATA REQUEST
*
WAITDRQ LDD  CF_STATUS
        BITB #DRQ
        BEQ  WAITDRQ
        RTS
        ENDIF IDEOPT
*
        IFD RTCOPT
*
* CLOCK INTER FACE UTILITY
*
* TIME <Hours> <Minuits> <Seconds>
* If no argument is specified, the current time
* will be displayed.
*
* READ A REGISTER FROM THE COUNTER.
* The X Index rgister points to the register
* to be read. The Status Register is checked
* before and after the register is read before
* returning a value in accumulator A
*
RDCLK  TST CLKSTA
       BNE RDCLK
RDCLK1 LDA 0,X
       TST CLKSTA
       BNE RDCLK1
       RTS
*
* MAIN PROGRAM:
*
TIMSET LDX #COUNTR    ; POINT TO TIMER
      LBSR BYTE       ; READ HOURS
      BVS  SHOWTM     ; NO ARG, DISP TIME
      STA HOUR,X
      LBSR OUT1S
      LBSR BYTE       ; READ MINUITES
      BVS  SHOWTM
      STA MINUIT,X
      LBSR OUT1S
      LBSR BYTE       ; SECONDS.
      BVS SHOWTM
      STA SECOND,X
*
* DISPLAY CURRENT TIME
*
SHOWTM LBSR PCRLF
       LDX #COUNTR+HOUR
       LDB #3
SHOWLP BSR RDCLK
       LBSR OUT2H
       LDA #':
       LBSR OUTCH
       LEAX -1,X
       DECB
       BNE SHOWLP
       RTS
*
* INITIATE CLOCK.
* MASK INTERRUPTS.
*
CLKINZ CLR CINTCR     ; MASK ALL INTERRUPTS
       TST CINTSR     ; CLEAR ANY INTERRUPTS
       RTS
       ENDIF RTCOPT
       IFD DATOPT
*
***** LRA LOAD REAL ADDRESS *****
*
* THE FOLLOWING CODE LOADS THE 20-BIT
* PHYSICAL ADDRESS OF A MEMORY BYTE
* INTO THE "A" AND "X" REGISTERS. THIS
* ROUTINE IS ENTERED WITH THE LOGICAL
* ADDRESS OF A MEMORY BYTE IN THE "IX"
* REGISTER. EXIT IS MADE WITH THE HIGH-
* ORDER FOUR BITS OF THE 20-BIT PHYSICAL
* ADDRESS IN THE "A" REGISTER, AND THE
* LOW-ORDER 16-BITS OF THE 20-BIT
* PHYSICAL ADDRESS IN THE "IX" REGISTER.
* ALL OTHER REGISTERS ARE PRESERVED.
* THIS ROUTINE IS REQUIRED SINCE THE
* DMAF1 AND DMAF2 DISK CONTROLLERS MUST
* PRESENT PHYSICAL ADDRESSES ON THE
* SYSTEM BUS.
*
LRA     PSHS A,B,X,Y  ; PUSH REGISTERS ON STACK
        LDA  2,S      ; GET MSB LOGICAL ADDR FRM X REG ON STACK
        LSRA          ;
        LSRA          ; ADJ FOR INDEXED INTO
        LSRA          ; CORRESPONDING LOCATION
        LSRA          ; IN LRA TABLE
        LDY  #LRARAM  ; LOAD LRA TABLE BASE ADDRESS
        LDB  A,Y      ; GET PHYSICAL ADDR. DATA FROM LRA TABLE
        LSRB          ; ADJ. REAL ADDR. TO REFLECT EXTENDED
        LSRB          ; PHYSICAL ADDRESS.
        LSRB          ; EXTENDED MS 4-BITS ARE RETURNED
        LSRB          ; IN THE "A" ACCUMULATOR
        STB  ,S       ; MS 4 BITS IN A ACCUM. STORED ON STACK
        LDB  A,Y      ; LOAD REAL ADDRESS DATA FROM LRA TABLE
        COMB          ; COMP TO ADJ FOR PHYSICAL ADDR. IN X REG
        ASLB          ; ADJ DATA FOR RELOCATION IN X REG
        ASLB          ;
        ASLB          ; $FB97
        ASLB          ;
        LDA  2,S      ; GET MS BYTE OF LOGICAL ADDR.
        ANDA #$0F     ; MASK MS NIBBLE OF LOGICAL ADDRESS
        STA  2,S      ; SAVE IT IN X REG ON STACK
        ORB  2,S      ; SET MS BYTE IN X REG TO ADJ PHY ADDR.
*
* PLUS LS NIBBLE OF LOGICAL ADDRESS
*
        STB  2,S      ; SAVE AS LS 16 BITS OF PHY ADDR IN X REG ON STACK
        PULS A,B,X,Y,PC ; POP REGS. FROM STACK
        ENDIF DATOPT
*
* DELAY LOOP
*
DLY     PSHS B        ; SAVE CONTENTS OF "B"
        LDB  #$20     ; GET LOOP DELAY VALUE
SUB1    DECB          ; SUBTRACT ONE FROM VALUE
        BNE  SUB1     ; LOOP UNTIL ZERO
        PULS B,PC     ; RESTORE CONTENTS OF "B"
* RTS  ;
*
***** "L" LOAD MIKBUG TAPE *****
*
LOAD    JSR  ACINIZ
        LDA  #$11     ; LOAD 'DC1' CASS. READ ON CODE
        LBSR OUTCH    ; OUTPUT IT TO TERMINAL PORT
        CLR  ECHO     ; TURN OFF ECHO FLAG
LOAD1   LBSR ECHON    ; INPUT 8 BIT BYTE WITH NO ECHO
LOAD2   CMPA #'S      ; IS IT AN "S", START CHARACTER ?
        BNE  LOAD1    ; IF NOT, DISCARD AND GET NEXT CHAR.
        LBSR ECHON
        CMPA #'9      ; IS IT A "9" , END OF FILE CHAR ?
        BEQ  LOAD21   ; IF SO, EXIT LOAD
        CMPA #'1      ; IS IT A "1" , FILE LOAD CHAR ?
        BNE  LOAD2    ; IF NOT, LOOK FOR START CHAR.
        LBSR BYTE     ; INPUT BYTE COUNT
        PSHS A        ; PUSH COUNT ON STACK
        BVS  LODERR   ; (V) C-CODE SET, ILLEGAL HEX
        LBSR IN1ADR   ; INPUT LOAD ADDRESS
        BVS  LODERR   ; (V) C-CODE SET, ADDR NOT HEX
        PSHS X        ; PUSH ADDR ON STACK
        LDB  ,S+      ; LOAD MSB OF ADDR AS CHECKSUM BYTE
        ADDB ,S+      ; ADD LSB OF ADDR TO CHECKSUM
        ADDB ,S       ; ADD BYTE COUNT BYTE TO CHECKSUM
        DEC  ,S       ; $FC37 DECREMENT BYTE COUNT 2 TO BYPASS
        DEC  ,S       ; ADDRESS BYTES.
LOAD10  PSHS B        ; PUSH CHECKSUM ON STACK
        LBSR BYTE     ; INPUT DATA BYTE (2 HEX CHAR)
        PULS B        ; POP CHECKSUM FROM STACK
        BVS  LODERR   ; (V) SET, DATA BYTE NOT HEX
        PSHS A        ; PUSH DATA BYTE ON STACK
        ADDB ,S+      ; ADD DATA TO CHECKSUM, AUTO INC STACK
        DEC  ,S       ; DECREMENT BYTE COUNT 1
        BEQ  LOAD16   ; IF BYTE COUNT ZERO, TEST CHECKSUM
        STA  ,X+      ; SAVE DATA BYTE IN MEMORY
        BRA  LOAD10   ; GET NEXT DATA BYTE
LODERR  CLRB          ; ERROR CONDITION, ZERO CHECKSUM  ;
LOAD16  PULS A        ; ADJUST STACK (REMOVE BYTE COUNT)
        CMPB #$FF     ; CHECKSUM OK?
        BEQ  LOAD1    ; IF SO, LOAD NEXT LINE
        LDA  #'?      ; LOAD (?) ERROR INDICATOR
        LBSR OUTCH    ; OUTPUT IT TO TERMINAL
LOAD21  COM  ECHO     ; TURN ECHO ON
        LDA  #$13     ; $FC5F LOAD 'DC3' CASS. READ OFF CODE
        LBRA OUTCH    ; OUTPUT IT
*
***** "P" PUNCH MIKBUG TAPE *****
*
PUNCH   CLR  ,-S      ; CLEAR RESERVED BYTE ON STACK
        LBSR IN2ADR   ; GET BEGIN AND END ADDRESS
        PSHS X,Y      ; SAVE ADDRESSES ON STACK
        BVS  PUNEXT   ; (V) C-CODE SET, EXIT PUNCH
        CMPX 2,S      ; COMPARE BEGIN TO END ADDR
        BCS  PUNEXT   ; IF BEGIN GREATER THAN END, EXIT PUNCH
        LEAX 1,X      ; INCREMENT END ADDRESS
        STX  ,S       ; STORE END ADDR ON STACK
        JSR  ACINIZ
        LDA  #$12     ; LOAD 'DC2' PUNCH ON CODE
        LBSR OUTCH    ; OUTPUT IT TO TERMINAL
PUNCH2  LDD  ,S       ; LOAD END ADDR IN D-ACC
        SUBD 2,S      ; SUBTRACT BEGIN FROM END
        BEQ  PUNCH3   ; SAME, PUNCH 32 BYTES DEFAULT
        CMPD #$20     ; LESS THAN 32 BYTES?
        BLS  PUNCH4   ; PUNCH THAT MANY BYTES
PUNCH3  LDB  #$20     ; LOAD BYTE COUNT OF 32.
PUNCH4  STB  4,S      ; STORE ON STACK AS BYTE COUNT
        LDX  #MSG20   ; POINT TO MSG "S1"
        LBSR PSTRNG   ; PRINT MSG
        ADDB #3       ; ADD 3 BYTES TO BYTE COUNT
        TFR  B,A      ; GET BYTE COUNT IN A-ACC TO PUNCH
        LBSR OUT2H    ; OUTPUT BYTE COUNT
        LDX  2,S      ; LOAD BEGIN ADDRESS
        LBSR OUT4H    ; PUNCH ADDRESS
        ADDB 2,S      ; ADD ADDR MSB TO CHECKSUM
        ADDB 3,S      ; ADD ADDR LSB TO CHECKSUM
PUNCHL  ADDB ,X       ; ADD DATA BYTE TO CHECKSUM
        LDA  ,X+      ; LOAD DATA BYTE TO PUNCH
        LBSR OUT2H    ; OUTPUT DATA BYTE
        DEC  4,S      ; DECREMENT BYTE COUNT
        BNE  PUNCHL   ; NOT DONE, PUNCH NEXT BYTE
        COMB  1's     ; COMPLIMENT CHECKSUM BYTE
        TFR  B,A      ; GET IT IN A-ACC TO PUNCH
        LBSR OUT2H    ; OUTPUT CHECKSUM BYTE
        STX  2,S      ; SAVE X-REG IN STACK AS NEW PUNCH ADDR
        CMPX ,S       ; COMPARE IT TO END ADDR
        BNE  PUNCH2   ; $FCB5 PUNCH NOT DONE, CONT.
PUNEXT  LDA  #$14     ; LOAD 'DC4' PUNCH OFF CODE
        LBSR OUTCH    ; OUTPUT IT
        LEAS 5,S      ; READJUST STACK POINTER
        RTS  ;
*
* PRINT STRING PRECEEDED BY A CR & LF.
*
PSTRNG  BSR  PCRLF    ; PRINT CR/LF
        BRA  PDATA    ; PRINT STRING POINTED TO BY IX
*
* PCRLF
*
PCRLF   PSHS X        ; SAVE IX
        LDX  #MSG2+1  ; POINT TO MSG CR/LF + 3 NULS
        LBSR PDATA    ; PRINT MSG
        PULS X,PC     ; RESTORE IX & RETURN
*
* LONG BRANCHES TO COMMON ROUTINES
*
JOUT1S  LBRA OUT1S
JBYTE   LBRA BYTE
JIN1ADR LBRA IN1ADR
*
* ALTER "PC" PROGRAM COUNTER
*
ALTRPC  LBSR  PRTPC   ; $FCF5 PRINT MSG " PC = "
ALTPC1  BSR  JOUT1S   ; OUTPUT SPACE
        BSR  JIN1ADR  ; GET NEW CONTENTS FOR "PC"
        BVS  ALTPCD   ; EXIT IF INVALID HEX
        STX  10,U     ; POKE IN NEW CONTENTS
ALTPCD  RTS           ;
*
* ALTER "U" USER STACK POINTER
*
ALTRU   BSR  PRTUS    ; $FCCA PRINT MSG " US = "
        BSR  JOUT1S   ; OUTPUT SPACE
        BSR  JIN1ADR  ; GET NEW CONTENTS FOR "US"
        BVS  ALTUD    ; EXIT IF INVALID HEX
        STX  8,U      ; POKE IN NEW CONTENTS
ALTUD   RTS           ;
*
* ALTER "Y" INDEX REGISTER
*
ALTRY   BSR  PRTIY    ; PRINT MSG " IY = "
        BSR  JOUT1S   ; OUTPUT SPACE
        BSR  JIN1ADR  ; GET NEW CONTENTS FOR "IY"
        BVS  ALTYD    ; EXIT IF INVALID HEX
        STX  6,U      ; $F8F0 POKE IN NEW CONTENTS
ALTYD   RTS           ;
*
* ALTER "X" INDEX REGISTER
*
ALTRX   BSR  PRTIX    ; $FCE0 PRINT MSG " IX = "
        BSR  JOUT1S   ; OUTPUT SPACE
        BSR  JIN1ADR
        BVS  ALTXD
        STX  4,U
ALTXD   RTS ;
*
* ALTER "DP" DIRECT PAGE REGISTER
*
ALTRDP  BSR  PRTDP    ; $FCD5 PRINT MSG " DP = "
        BSR  JOUT1S   ; OUTPUT SPACE
        BSR  JBYTE    ; INPUT BYTE (2 HEX CHAR)
        BVS  ALTDPD
        STA  3,U
ALTDPD  RTS ;
*
* ALTER "B" ACCUMULATOR
*
ALTRB   BSR  PRTB     ; $FD09 PRINT MSG " B = "
        BSR  JOUT1S   ; OUTPUT SPACE
        BSR  JBYTE    ; INPUT BYTE (2 HEX CHAR)
        BVS  ALTBD
        STA  2,U
ALTBD   RTS           ; $F91C
*
* ALTER "A" ACCUMULATOR
*
ALTRA   BSR  PRTA     ; $FCFF RINT MSG " A = "
        BSR  JOUT1S   ; OUTPUT SPACE
        BSR  JBYTE    ; INPUT BYTE (2 HEX CHAR)
        BVS  ALTAD
        STA  1,U
ALTAD   RTS ;
*
* ALTER "CC" REGISTER
*
ALTRCC  BSR  PRTCC    ; $FD13 PRINT MSG " CC: "
        BSR  JOUT1S   ; OUTPUT SPACE
        BSR  JBYTE    ; INPUT BYTE (2 HEX CHAR)
        BVS  ALTCCD
        ORA  #$80     ; SETS "E" FLAG IN PRINT LIST
        STA  ,U
ALTCCD  RTS ;
*
* PDATA
*
PRINT   LBSR OUTCH
PDATA   LDA  ,X+      ; GET 1st CHAR. TO PRINT
        CMPA #4       ; IS IT EOT?
        BNE  PRINT    ; IF NOT EOT PRINT IT
        RTS  ;
*
* PRINT REGISTERS
*
PRTSP   LDX  #MSG10   ; POINT TO MSG "SP="
        BSR  PDATA    ; PRINT MSG
        TFR  U,X
JOUT4H  LBRA OUT4H
*
PRTUS   LDX  #MSG12   ; POINT TO MSG "US="
        BSR  PDATA    ; PRINT MSG
        LDX  8,U
        BRA  JOUT4H
*
PRTDP   LDX   #MSG15  ; POINT TO MSG "DP="
        BSR  PDATA    ; PRINT MSG
        LDA  3,U
JOUT2H  LBRA OUT2H    ; OUTPUT HEX BYTE AS ASCII
*
PRTIX   LDX  #MSG14   ; POINT TO MSG "IX="
        BSR  PDATA    ; PRINT MSG
        LDX  4,U      ; $FCE6
        BRA  JOUT4H
*
PRTIY   LDX  #MSG13   ; POINT TO MSG "IY="
        BSR  PDATA    ; PRINT MSG
        LDX  6,U
        BRA  JOUT4H
*
PRTPC   LDX  #MSG11   ; POINT TO MSG "PC="
        BSR  PDATA    ; PRINT MSG
        LDX  10,U
        BRA  JOUT4H
*
PRTA    LDX  #MSG16   ; POINT TO MSG "A="
        BSR  PDATA    ; PRINT MSG
        LDA  1,U
        BRA  JOUT2H   ; OUTPUT HEX BYTE AS ASCII
*
PRTB    LDX  #MSG17   ; POINT TO MSG "B="
        BSR  PDATA    ; PRINT MSG
        LDA  2,U
        BRA  JOUT2H   ; OUTPUT HEX BYTE AS ASCII
*
PRTCC   LDX  #MSG18   ; POINT TO MSG "CC:"
        BSR  PDATA    ; PRINT MSG
        LDA  ,U
        LDX  #MSG19   ; POINT TO MSG "EFHINZVC"
        LBRA BIASCI   ; OUTPUT IN BINARY/ASCII FORMAT
*
* "R" DISPLAY REGISTERS
*
REGSTR  LDX  #MSG5    ; POINT TO MSG " - "
        LBSR PSTRNG   ; PRINT MSG
        BSR  PRTSP    ; $FCBF
        BSR  PRTUS    ; $FCCA
        BSR  PRTDP    ; $FCD5
        BSR  PRTIX    ; $FCE0
        BSR  PRTIY    ; $FCEB
        LDX  #MSG5    ; POINT TO MSG " - "
        LBSR PSTRNG   ; PRINT MSG
        BSR  PRTPC    ; $FCF5
        BSR  PRTA     ; $FCFF
        BSR  PRTB     ; $FD09
        BRA  PRTCC    ; $FD13
*
* THE FOLLOWING ROUTINE LOOPS WAITING FOR THE
* OPERATOR TO INPUT TWO VALID HEX ADDRESSES.
* THE FIRST ADDRESS INPUT IS RETURNED IN "IY".
* THE SECOND IS RETURNED IN "IX". THE "V" BIT
* IN THE C-CODE REG. IS SET IF AN INVALID HEX
* ADDRESS IS INPUT.
*
IN2ADR  BSR  IN1ADR   ; GET FIRST ADDRESS
        BVS  NOTHEX   ; EXIT IF NOT VALID HEX
        TFR  X,Y      ; SAVE FIRST ADDR. IN "IY"
        LDA  #'-
        LBSR OUTCH    ; PRINT " - "
*
* THE FOLLOWING ROUTINE LOOPS WAITING FOR THE
* OPERATOR TO INPUT ONE VALID HEX ADDRESS. THE
* ADDRESS IS RETURNED IN THE "X" REGISTER.
*
IN1ADR  BSR  BYTE     ; INPUT BYTE (2 HEX CHAR)
        BVS  NOTHEX   ; EXIT IF NOT VALID HEX
        TFR  D,X
        BSR  BYTE     ; INPUT BYTE (2 HEX CHAR)
        BVS  NOTHEX
        PSHS X
        STA  1,S
        PULS X,PC
*
***** INPUT BYTE (2 HEX CHAR.) *****
*
BYTE    BSR  INHEX    ; GET HEX LEFT
        BVS  NOTHEX   ; EXIT IF NOT VALID HEX
        ASLA          ;
        ASLA          ;
        ASLA          ; SHIFT INTO LEFT NIBBLE
        ASLA          ;
        TFR  A,B      ; PUT HEXL IN "B"
        BSR  INHEX    ; GET HEX RIGHT
        BVS  NOTHEX   ; EXIT IF NOT VALID HEX
        PSHS B        ; PUSH HEXL ON STACK
        ADDA ,S+      ; ADD HEXL TO HEXR AND ADJ. STK
        RTS           ; RETURN WITH HEX L&R IN "A"
*
*
INHEX   BSR  ECHON    ; INPUT ASCII CHAR.
        CMPA #'0      ; IS IT > OR = "0" ?
        BCS  NOTHEX   ; IF LESS IT AIN'T HEX
        CMPA #'9      ; IS IT < OR = "9" ?
        BHI  INHEXA   ; IF > MAYBE IT'S ALPHA
        SUBA #$30     ; ASCII ADJ. NUMERIC
        RTS           ;
*
*
INHEXA  CMPA #'A      ; IS IT > OR = "A"
        BCS  NOTHEX   ; IF LESS IT AIN'T HEX
        CMPA #'F      ; IS IT < OR = "F" ?
        BHI  INHEXL   ; IF > IT AIN'T HEX
        SUBA #'A-10   ; ($37) ASCII ADJ. ALPHA
        RTS           ;
*
INHEXL  CMPA #'a      ; IS IT > OR = "a"
        BCS  NOTHEX   ; IF LESS IT AIN'T HEX
        CMPA #'f      ; IS IT < "f"
        BHI  NOTHEX   ; IF > IT AIN'T HEX
        SUBA #'a-10   ; ($57) ADJUST TO LOWER CASE
        RTS           ;
*
*
NOTHEX  ORCC #2       ; SET (V) FLAG IN C-CODES REGISTER
        RTS           ;
*
*
OUT4H   PSHS X        ; PUSH X-REG. ON THE STACK
        PULS A        ; POP MS BYTE OF X-REG INTO A-ACC.
        BSR  OUTHL    ; OUTPUT HEX LEFT
        PULS A        ; POP LS BYTE OF X-REG INTO A-ACC.
OUTHL   EQU *
OUT2H   PSHS A        ; SAVE IT BACK ON STACK
        LSRA          ; CONVERT UPPER HEX NIBBLE TO ASCII
        LSRA          ;
        LSRA          ;
        LSRA          ;
        BSR  XASCII   ; PRINT HEX NIBBLE AS ASCII
OUTHR   PULS A        ; CONVERT LOWER HEX NIBBLE TO ASCII
        ANDA #$0F     ; STRIP LEFT NIBBLE
XASCII  ADDA #$30     ; ASCII ADJ
        CMPA #$39     ; IS IT < OR = "9" ?
        BLE  OUTC     ; IF LESS, OUTPUT IT
        ADDA #7       ; IF > MAKE ASCII LETTER
OUTC    BRA OUTCH     ;  OUTPUT CHAR
*
* BINARY / ASCII --- THIS ROUTINE
* OUTPUTS A BYTE IN ENHANCED
* BINARY FORMAT. THE ENHANCEMENT
* IS DONE BY SUBSTITUTING ASCII
* LETTERS FOR THE ONES IN THE BYTE.
* THE ASCII ENHANCEMENT LETTERS
* ARE OBTAINED FROM THE STRING
* POINTED TO BY THE INDEX REG. "X".
*
BIASCI  PSHS A        ; SAVE "A" ON STACK
        LDB  #8       ; PRESET LOOP# TO BITS PER BYTE
OUTBA   LDA  ,X+      ; GET LETTER FROM STRING
        ASL  ,S       ; TEST BYTE FOR "1" IN B7
        BCS  PRTBA    ; IF ONE PRINT LETTER
        LDA  #'-      ; IF ZERO PRINT "-"
PRTBA   BSR  OUTCH    ; PRINT IT
        BSR  OUT1S    ; PRINT SPACE
        DECB          ; SUB 1 FROM #BITS YET TO PRINT
        BNE  OUTBA
        PULS A,PC
*
        IFD EXTOPT
*
* EXTENDED USER COMMANDS
*
USRCMD  JMP [MONEXT+EXTCMD]
        ENDIF EXTOPT
*
*
ECHON   TST  ECHO     ; IS ECHO REQUIRED ?
        BEQ  INCH     ; ECHO NOT REQ. IF CLEAR
*
* INCHE
*
* GETS CHARACTER FROM TERMINAL AND
* ECHOS SAME. THE CHARACTER IS RETURNED
* IN THE "A" ACCUMULATOR WITH THE PARITY
* BIT MASKED OFF. ALL OTHER REGISTERS
* ARE PRESERVED.
*
INCHE   BSR  INCH     ; GET CHAR FROM TERMINAL
        ANDA #$7F     ; STRIP PARITY FROM CHAR.
        BRA  OUTCH    ; ECHO CHAR TO TERMINAL
*
* INCH
*
* GET CHARACTER FROM TERMINAL. RETURN
* CHARACTER IN "A" ACCUMULATOR AND PRESERVE
* ALL OTHER REGISTERS. THE INPUT CHARACTER
* IS 8 BITS AND IS NOT ECHOED.
*
*
INCH    PSHS X        ; SAVE IX
        IFD  HFCOPT
        LDA  #$11     ; SET RTS* LOW, REQUEST FAR END TO TX
        STA  [CPORT]
        ENDIF HFCOPT
GETSTA  LDX  CPORT    ; POINT TO TERMINAL PORT
        LDA  ,X       ; FETCH PORT STATUS
        BITA #1       ; TEST READY BIT, RDRF ?
        IFD  PS2OPT
        BNE  GETST1
        LDX  #PS2KBD
        LDA  ,X
        BITA #1
        ENDIF PS2OPT
        BEQ  GETSTA   ; IF NOT RDY, THEN TRY AGAIN
GETST1  EQU  *
        IFD  HFCOPT
        LDA  #$51     ; SET RTS* HIGH, STOP FAR END FROM TXING, UNTIL NEXT INPUT
        STA  [CPORT]
        ENDIF HFCOPT
        LDA  1,X      ; FETCH CHAR
        PULS X,PC     ; RESTORE IX
*
* INCHEK
*
* CHECK FOR A CHARACTER AVAILABLE FROM
* THE TERMINAL. THE SERIAL PORT IS CHECKED
* FOR READ READY. ALL REGISTERS ARE
* PRESERVED, AND THE "Z" BIT WILL BE
* CLEAR IF A CHARACTER CAN BE READ.
*
*
INCHEK  PSHS A        ; SAVE A ACCUM
        IFD  HFCOPT
        LDA  #$11     ; SET RTS* LOW, REQUEST FAR END TO TX
        STA  [CPORT]
        ENDIF HFCOPT
        LDA  [CPORT]  ; FETCH PORT STATUS
        BITA #1       ; TEST READY BIT, RDRF ?
        IFD  PS2OPT
        BNE  INCHEK1
        LDA  PS2KBD
        BITA #1       ; TEST READY BIT< RDRF ?
        ENDIF PS2OPT
INCHEK1 PULS A,PC     ; RESTORE A ACCUM.
*
OUT2S   BSR  OUT1S    ; OUTPUT 2 SPACES
OUT1S   LDA  #$20     ; OUTPUT 1 SPACE
*
*
* OUTCH
*
* OUTPUT CHARACTER TO TERMINAL.
* THE CHAR. TO BE OUTPUT IS
* PASSED IN THE A REGISTER.
* ALL REGISTERS ARE PRESERVED.
*
OUTCH   IFD   VDUOPT
        BSR   VOUTCH
        ENDIF VDUOPT
        IFD   DG640OPT
        BSR   VOUTCH
        ENDIF DG640OPT
AOUTCH  PSHS A,X      ; SAVE A ACCUM AND IX
        LDX  CPORT    ; GET ADDR. OF TERMINAL
FETSTA  LDA  ,X       ; FETCH PORT STATUS
        BITA #2       ; TEST TDRE, OK TO XMIT ?
        BEQ  FETSTA   ; IF NOT LOOP UNTIL RDY
        BITA #8       ; CLEAR TO SEND ?
        BNE  FETSTA   ; NO, LOOP UNTIL CLEAR
        PULS A        ; GET CHAR. FOR XMIT
        STA  1,X      ; XMIT CHAR.
        PULS X,PC     ; RESTORE IX
*
* IO INITIALIZATION
*
IOINIZ  EQU  *
        IFD  VDUOPT
        BSR  VINIZ
        ENDIF VDUOPT
        IFD  DG640OPT
        BSR  VINIZ
        ENDIF DG640OPT
ACINIZ  LDX  CPORT    ; POINT TO CONTROL PORT ADDRESS
        LDA  #3       ; RESET ACIA PORT CODE
        STA  ,X       ; STORE IN CONTROL REGISTER
        LDA  #$51     ; SET 8 DATA, 2 STOP AN 0 PARITY RTS* HIGH
        STA  ,X       ; STORE IN CONTROL REGISTER
        TST  1,X      ; ANYTHING IN DATA REGISTER?
        LDA  #$FF     ; TURN ON ECHO FLAG
        STA  ECHO
        RTS
*
        IFD VDUOPT
*
***************************************************
*      VDU8 ADM3A REGISTER-MAPPED EMULATOR        *
*                                                 *
*      80 x 25 Characters
*
***************************************************
*
***************************************************
*               INITIALIZE EMULATOR               *
***************************************************
*
VINIZ   LDX  #VDU
        LDD  #0
        STD  COLADX   ; AND ROWADX
        STA  VDUCOL,X
        STB  VDUROW,X
        STB  VDUOFF,X
        STD  NEWROW   ; AND ESCFLG
        LDB  #$02
        STB  VDUATT,X
        CLR  ESCFLG
        LDA  #$1B     ; SEND ESCAPE
        BSR  VOUTCH
        LDA  #'Y      ; CLEAR TO END OF SCREEN
*
** VIDEO OUTPUT ROUTINE
*
VOUTCH  PSHS A,B,X    ; SAVE REGISTERS
        LDX  #VDU     ; POINT TO VDU REGISTERS
*
** CHECK FOR ESCAPE SEQUENCE
*
        TST  ESCFLG   ; ESCAPE ACTIVE?
        BEQ  SOROU1   ; BRANCH IF NOT
        BSR  ESCAPE   ; ELSE DO ESCAPE
        BRA  RETURN   ; AND RETURN
*
** CHECK FOR CONTROL CHARACTERS
*
SOROU1  CMPA #$20     ; CONTROL CODES?
        BHS  SOROU2
        BSR  CONTRL   ; BRANCH IF SO
        BRA  RETURN
*
** OUTPUT TEXT CHARACTER
*
SOROU2  STA  VDUCHR,X ; DISPLAY CHARACTER
        LBSR NEWCOL   ; UPDATE COLUMN
*
** DISPLAY CURSOR AND RETURN
*
RETURN  PULS A,B,X,PC ; RESTORE REGISTERS AND RETURN
*
***************************************************
*              CONTROL CODE HANDLERS              *
***************************************************
*
CONTRL  CMPA #$08     ; CTRL H - BACKSPACE ?
        BEQ  BACKSP
        CMPA #$1B     ; ESCAPE SEQUENCE?
        BEQ  SETESC
        CMPA #$1A     ; CTRL Z - Clear Screen
        LBEQ CLRSCR
        CMPA #$16     ; CTRL ^ - Home
        BEQ  HOME
        CMPA #$0D     ; CTRL M - RETURN?
        LBEQ CRETN
        CMPA #$0C     ; CTRL L - CHAR RIGHT
        BEQ  CHRIGHT
        CMPA #$0B     ; CTRL K - MOVE UP ONE LINE
        BEQ  LINEUP
        CMPA #$0A     ; CTRL J - LINE FEED
        BNE  RETESC   ; NONE OF THESE, RETURN
*
***************************************** LINE FEED
*
LINEFD  LDD  COLADX   ; GET CURRENT COLUMN AND ROW
        INCB          ; BUMP ROW
        CMPB #NUMLIN  ; SCROLL TIME?
        BNE  NEWCUR   ; POSITION CURSOR IF NOT
        LBRA SCROLL   ; ELSE SCROLL IT
*
***************************************** LINE FEED
*
LINEUP  LDD  COLADX   ; GET CURRENT COLUMN AND ROW
        TSTB          ; AT TOP OF SCREEN ?
        BEQ  RETESC   ; Yes, Ignore
        DECB          ; No, Decrement ROW
        BRA  NEWCUR   ; POSITION CURSOR
*
*********************************** BACK SPACE
*
BACKSP  LDA  COLADX
        BEQ  RETESC   ; RETURN
        DECA
        BRA  POSCOL   ; POSITION CURSOR
*
*********************************** CURSOR RIGHT
*
CHRIGHT LDA  COLADX
        INCA
        CMPA #LINLEN
        BEQ  RETESC
        BRA  POSCOL
*
*********************************** CURSOR RIGHT
*
HOME    LDD  #0       ; HOME - POSITION TOP OF SCREEN
        BRA  NEWCUR
*
***************************************************
*                 ESCAPE HANDLERS                 *
***************************************************
*
ESCAPE  LDB  ESCFLG   ; GET FLAG
        CMPB #'=      ; SETTING CURSOR?
        BEQ  ESCCUR   ; BRANCH IF SO
        CMPA #'Y      ; CLEAR TO END OF SCREEN?
        BEQ  ESCCLS
        CMPA #'T      ; CLEAR TO END OF LINE?
        BEQ  ESCCLL
        CMPA #'=      ; STARTING CURSOR SET?
        BNE  CLRESC   ; BRANCH IF NOT
*
***************************** START ESCAPE SEQUENCE
*
SETESC  STA  ESCFLG   ; ELSE START CURSORING
        RTS           ; AND RETURN
*
CLRESC  CLR  ESCFLG   ; NO OTHERS SUPPORTED
RETESC  RTS           ; SO RETURN
*
********************************* SET SCREEN CURSOR
*
ESCCUR  TST  NEWROW   ; ROW SET?
        BNE  ESCCU1   ; BRANCH IF SO
        STA  NEWROW   ; ELSE SET NEW ROW
        RTS           ; AND RETURN
*
ESCCU1  CLR  ESCFLG
        SUBA #$20     ; ADJUST COLUMN ADDRESS
        CMPA #LINLEN-1 ;CHECK FOR ACCEPTABLE COLUM
        BHI  RETESC   ; NOT OK, DO NOTHING
*
ESCCU2  LDB  NEWROW
        CLR  NEWROW
        SUBB #$20     ; ADJUST TO ROW ADDRESS
        CMPB #NUMLIN-1 ; CHECK FOR ACCEPTABLE ROW
        BHI  RETESC   ; ELSE RETURN DOING NOTHING
        BRA  NEWCUR   ; GO SET NEW CURSOR IF SO
*
****************** CLEAR FROM CURSOR TO END OF LINE
*
CLRSCR  LDD  #0       ; CLEAR FROM TOP OF SCREEN
        BSR  NEWCUR
ESCCLL  LDA  COLADX
        LDB  #$20     ; AND CLEAR CHAR
ESCCL1  STB  VDUCHR,X ; DISPLAY TEXT
        INCA
        STA  VDUCOL,X
        CMPA #LINLEN  ; UNTIL END OF LINE
        BNE  ESCCL1
        CLR  ESCFLG
        RTS
*
*********************************** CARRIAGE RETURN
*
CRETN   CLRA          ; SET COLUMN ZERO
POSCOL  LDB  ROWADX   ; GET CURRENT ROW
*
*********** GENERATE NEW CURSOR POSITION AND RETURN
*
NEWCUR  STD  COLADX   ; SAVE NEW ROW AND COLUMN
        STA  VDUCOL,X ; SET NEW COLUMN
        STB  VDUROW,X ; SET NEW ROW
        RTS           ; AND RETURN
*
********************* UPDATE CURRENT COLUMN AND ROW
*
NEWCOL  LDD  COLADX   ; GET ROW AND COLUMN
        INCA          ; BUMP COLUMN
        CMPA #LINLEN  ; ROLL?
        BNE  NEWCUR   ; BRANCH IF NOT
        CLRA          ; ELSE RESET TO ZERO
        INCB          ; AND BUMP ROW
        CMPB #NUMLIN
        BNE  NEWCUR
        DECB          ; BOTTOM ROW
        BSR  NEWCUR
*
********************************* SCROLL THE SCREEN
*
SCROLL  LDB  VDUOFF,X
        INCB
        CMPB #NUMLIN
        BLO  SCROL1
        CLRB
SCROL1  STB  VDUOFF,X
*
**************** CLEAR FROM CURSOR TO END OF SCREEN
*
ESCCLS  LDB  COLADX   ; GET CURSOR
        LDA  #$20     ; GET A SPACE
ESCCLS1 STB  COLADX
        STB  VDUCOL,X
        STA  VDUCHR,X
        INCB
        CMPB #LINLEN
        BNE  ESCCLS1
*
        LDB  ROWADX
        INCB
        CMPB #NUMLIN
        BEQ  ESCCLS2
        STB  ROWADX
        STB  VDUROW,X
        CLRB
        BRA  ESCCLS1
*
ESCCLS2 CLRB
        STB  COLADX
        STB  VDUCOL,X
        STB  ESCFLG
        RTS
        ENDIF VDUOPT
*
        IFD DG640OPT
***************************************************
*      TELEVIDEO-TYPE MEMORY-MAPPED EMULATOR      *
*                                                 *
* FOR HARD-WIRED MEMORY-MAPPED DISPLAYS USING THE *
* HIGH ORDER BIT OF EACH BYTE FOR  REVERSE  VIDEO *
* CURSORING  (SUCH  AS THE THOMAS INSTRUMENTATION *
* 16x64 BOARD).                                   *
***************************************************
*
***************************************************
*               INITIALIZE EMULATOR               *
***************************************************
*
VINIZ   LDX  #0
        STX  COLADX   ; AND ROWADX
        STX  NEWROW   ; AND ESCFLG
        LDX  #SCREEN  ; POINT TO SCREEN
        STX  CURSOR   ; SET PROGRAM CURSOR
        LDA  #$1B     ; SEND ESCAPE
        BSR  VOUTCH
        LDA  #'Y      ; CLEAR TO END OF SCREEN
*
** VIDEO OUTPUT ROUTINE
*
VOUTCH  PSHS A,B,X    ; SAVE REGISTERS
*
** CLEAR CURSOR
*
        LDX  CURSOR
        LDB  0,X
        ANDB #$7F
        STB  0,X
*
** CHECK FOR ESCAPE SEQUENCE
*
        TST  ESCFLG   ; ESCAPE ACTIVE?
        BEQ  SOROU1   ; BRANCH IF NOT
        BSR  ESCAPE   ; ELSE DO ESCAPE
        BRA  RETURN   ; AND RETURN
*
** CHECK FOR CONTROL CHARACTERS
*
SOROU1  CMPA #$20     ; CONTROL CODES?
        BHS  SOROU2
        BSR  CONTRL   ; BRANCH IF SO
        BRA  RETURN
*
** OUTPUT TEXT CHARACTER
*
SOROU2  LDX  CURSOR   ; ELSE GET CURSOR
        STA  0,X      ; DISPLAY CHARACTER
        LBSR NEWCOL   ; UPDATE COLUMN
*
** DISPLAY CURSOR AND RETURN
*
RETURN  LDX  CURSOR   ; AND DISPLAY IT
        LDB  ,X
        ORB  #$80     ; WITH REVID
        STB  ,X
        PULS A,B,X,PC ; RESTORE REGISTERS AND RETURN
*
***************************************************
*              CONTROL CODE HANDLERS              *
***************************************************
*
CONTRL  CMPA #$08     ; CTRL H - BACKSPACE ?
        LBEQ BACKSP
        CMPA #$1B     ; ESCAPE SEQUENCE?
        LBEQ SETESC
        CMPA #$D      ; CTRL M - RETURN?
        LBEQ CRETN
        CMPA #$0A     ; CTRL J - LINE FEED
        BNE  RETESC   ; NONE OF THESE, RETURN
*
***************************************** LINE FEED
*
LINEFD  LDD  COLADX   ; GET CURRENT COLUMN AND ROW
        INCB          ; BUMP ROW
        CMPB #NUMLIN  ; SCROLL TIME?
        LBNE NEWCUR   ; POSITION CURSOR IF NOT
        LBRA SCROLL   ; ELSE SCROLL IT
*
***************************************** LINE FEED
*
LINEUP  LDD  COLADX   ; GET CURRENT COLUMN AND ROW
        TSTB          ; AT TOP OF SCREEN ?
        BEQ  RETESC   ; YES, RETURN
        DECB          ; NO, DECREMENT ROW
        LBRA NEWCUR   ; POSITION CURSOR
*
*********************************** BACK SPACE
*
BACKSP  LDA  COLADX    ; GET CURRENT COLUMN AND ROW
        BEQ  RETESC    ; IF AT TOP LEFT CORNER RETURN
        DECA           ; OTHERWISE BACK STEP ONE CHARACTER
        LBRA POSCOL    ; POSITION CURSOR
*
*********************************** CURSOR RIGHT
*
CHRIGHT LDA  COLADX    ; GET CURRENT COLUMN AND ROW
        INCA           ; MOVE RIGHT ONE CHARACTER
        CMPA #LINLEN   ; ARE WE AT THE END OF THE LINE ?
        BEQ  RETESC    ; YES, RETURN
        LBRA POSCOL    ; NO, POSITION CURSOR
*
***************************************************
*                 ESCAPE HANDLERS                 *
***************************************************
*
ESCAPE  LDB  ESCFLG   ; ARE WE IN AN ESCAPE SEQUENCE ?
        CMPB #'=      ; ARE WE SETTING CURSOR?
        BEQ  ESCCUR   ; YES BRANCH TO SET CURSOR
        CMPA #'Y      ; CLEAR TO END OF SCREEN?
        LBEQ ESCCLS   ; YES, CLEAR SCREEN
        CMPA #'T      ; CLEAR TO END OF LINE?
        BEQ  ESCCLL   ; YES, CLEAR LINE
        CMPA #'E      ; INSERT LINE?
        BEQ  ESCINL
        CMPA #'R      ; DELETE LINE?
        BEQ  ESCDLL
        CMPA #'=      ; STARTING CURSOR SET?
        BNE  CLRESC   ; BRANCH IF NOT
*
***************************** START ESCAPE SEQUENCE
*
SETESC  STA  ESCFLG   ; ELSE START CURSORING
        RTS           ; AND RETURN
*
CLRESC  CLR  ESCFLG   ; NO OTHERS SUPPORTED
RETESC  RTS           ;  SO RETURN
*
********************************* SET SCREEN CURSOR
*
ESCCUR  TST  NEWROW   ; ROW SET?
        BNE  ESCCU1   ; BRANCH IF SO
        STA  NEWROW   ; ELSE SET NEW ROW
        RTS           ;  AND RETURN
*
ESCCU1  CLR  ESCFLG
        SUBA #$20      ; ADJUST COLUMN ADDRESS
        CMPA #LINLEN-1 ; CHECK FOR ACCEPTABLE COLUM
        BHI  RETESC    ; NOT OK, DO NOTHING
*
ESCCU2  LDB  NEWROW
        CLR  NEWROW
        SUBB #$20      ; ADJUST TO ROW ADDRESS
        CMPB #NUMLIN-1 ; CHECK FOR ACCEPTABLE ROW
        BHI  RETESC    ; ELSE RETURN DOING NOTHING
        BRA  NEWCUR    ; GO SET NEW CURSOR IF SO
*
*************************** DELETE LINE FROM SCREEN
*
ESCDLL  BSR  CRETN     ; GO COL. ZERO
        LDB  ROWADX
        CMPB #NUMLIN-1
        BEQ  SCROL3
        BRA  SCROL1    ; AND DELETE THIS LINE
*
*************************** INSERT LINE INTO SCREEN
*
ESCINL  BSR  CRETN     ; GO TO COL. ZERO
        LDB  ROWADX
        CMPB #NUMLIN-1
        BEQ  ESCCLL
*
** SCROLL SCREEN DOWN FROM CURSOR
*
        LDX  #SCREEN+SCNLEN-LINLEN
ESCIN0  LDA  ,-X
        STA  LINLEN,X
        LDA  SCNLEN,X
        STA  SCNLEN+LINLEN,X
        CMPX CURSOR
        BNE  ESCIN0
*
****************** CLEAR FROM CURSOR TO END OF LINE
*
ESCCLL  LDA  COLADX    ; GET CURRENT COLUMN
        LDX  CURSOR    ; GET CURSOR
        LDB  #$20      ; AND CLEAR CHAR
ESCLL1  STB  SCNLEN,X  ; CLEAR ATTRIBUTE
        STB  ,X+       ; CLEAR TEXT
        INCA
        CMPA #LINLEN   ; UNTIL END OF LINE
        BNE  ESCLL1
        CLR  ESCFLG
        RTS
*
*********************************** CARRIAGE RETURN
*
CRETN   CLRA           ; SET COLUMN ZERO
POSCOL  LDB  ROWADX    ; GET CURRENT ROW
*
*********** GENERATE NEW CURSOR POSITION AND RETURN
*
NEWCUR  STD  COLADX    ; SAVE NEW ROW AND COLUMN
        LDA  #LINLEN   ; ELSE ADD A LINE
        MUL            ; LINLEN * ROWADX
        ADDB COLADX
        ADCA #0
        ADDD #SCREEN   ; ADD SCREEN BASE.
        STD  CURSOR    ; SAVE NEW CURSOR
        TFR  D,X       ; GET CURSOR IN X
        RTS            ; AND RETURN
*
********************* UPDATE CURRENT COLUMN AND ROW
*
NEWCOL  LDD  COLADX    ; GET ROW AND COLUMN
        INCA           ; BUMP COLUMN
        CMPA #LINLEN   ; ROLL?
        BNE  NEWCUR    ; BRANCH IF NOT
        CLRA           ; ELSE RESET TO ZERO
        INCB           ; AND BUMP ROW
        CMPB #NUMLIN
        BNE  NEWCUR
        DECB           ; BOTTOM ROW
        BSR  NEWCUR
*
********************************* SCROLL THE SCREEN
*
SCROLL  LDX  #SCREEN   ; POINT TO SCREEN
SCROL1  LDA  SCNLEN+LINLEN,X
        STA  SCNLEN,X
        LDA  LINLEN,X  ; MOVE TWO BYTES
        STA  ,X+       ; UP ONE LINE
        CMPX #SCREEN+SCNLEN-LINLEN
        BNE  SCROL1    ; LOOP UNTIL DONE
        BRA  SCROL3
*
**************** CLEAR FROM CURSOR TO END OF SCREEN
*
ESCCLS  LDX   CURSOR   ; GET CURSOR
SCROL3  LDA   #$20     ; GET A SPACE
SCROL2  STA   SCNLEN,X ; CLEAR ATTRIBUTES
        STA   ,X+      ; AND TEXT
        CMPX  #SCREEN+SCNLEN
        BNE   SCROL2   ; UNTIL DONE
        CLR   ESCFLG
        RTS
        ENDIF DG640OPT
*
        IFD PRTOPT
*************************************
*
** PRINTER DRIVER ROUTINES
*
*************************************
*
** PINIZ - INITIATE PRINTER PORT
*
PINIZ   PSHS B
        LDD #DIRMSK*256+$04 ; ACCA=DIRMSK ACCB=$04
        STD PADATA     ; SET DDR AND SELECT DATA
*
** RESET PRINTER
*
        LDB  #PRESET
        STB  PADATA
RESTLP  INCB           ; DELAY FOR RESET
        BNE  RESTLP
        STA  PADATA    ; ACCA=DIRMSK
*
** INITALIZE PORT B (DATA PORT)
*
        LDA  #$2A
        STA  PBCTRL
        LDD  #$FF2E    ; ACCA=$FF ACCB =%00101110
        STD  PBDATA    ; PBDREG   PBCTRL
*
** SELECT 66 LINES/PAGE
*
        LDA  #$1B
        BSR  POUTCH
        LDA  #'C
        BSR  POUTCH
        LDA  #66
        PULS B
*************************************
*
** OUTPUT A CHARACTER TO THE PRINTER
*
*************************************
POUTCH  PSHS B
        LDB  PBDATA    ; CLEAR INTERRUPT BIT
*
** WAIT TILL NOT BUSY
*
BUSYLP  LDB  PADATA
        BITB #PERROR
        BEQ  PEXIT
        TSTB
        BMI  BUSYLP
*
** NOW OUTPUT CHARACTER
*
        STA  PBDATA
PEXIT   PULS B,PC
*************************************
*
** PCHK TEST IFD PRINTER READY
*
*************************************
PCHK    TST  PBCTRL    ; TEST STATE OF CRB7
        RTS            ; SET ON ACKNOWLEDGE
        ENDIF PRTOPT
*************************************
*
* MONITOR KEYBOARD COMMAND JUMP TABLE
*
*************************************
*
JMPTAB  EQU *
        FCB 1 " ^A "
        FDB ALTRA
        FCB 2 " ^B "
        FDB ALTRB
        FCB 3 " ^C "
        FDB ALTRCC
        FCB 4 " ^D "
        FDB ALTRDP
        FCB $10 " ^P "
        FDB ALTRPC
        FCB $15 " ^U "
        FDB ALTRU
        FCB $18 " ^X "
        FDB ALTRX
        FCB $19 " ^Y "
        FDB ALTRY
*
        FCC 'B'
        FDB BRKPNT
        FCC 'E'
        FDB MEMDUMP
        FCC 'G'
        FDB GO
        FCC 'L'
        FDB LOAD
        FCC 'P'
        FDB PUNCH
        FCC 'M'
        FDB MEMCHG
        FCC 'R'
        FDB REGSTR
        FCC 'S'
        FDB DISSTK
        FCC 'X'
        FDB XBKPNT
        IFD MFDCOPT
        FCC 'D'        ; *** SWTPC USES 'U' FOR MINIBOOT
        FDB MINBOOT
        ENDIF MFDCOPT
        IFD CF8OPT
        FCC 'D'        ; *** FPGA 8 BIT USES 'D' FOR CFBOOT
        FDB CFBOOT
        ENDIF CF8OPT
        IFD IDEOPT
        FCC 'D'        ; *** XESS FPGA 16 BIT IDE USES 'D' FOR IDEBOOT
        FDB IDEBOOT
        ENDIF IDEOPT
        IFD DMAFOPT
        FCC 'U'        ; *** SWTPC USES 'D' FOR DMAF2 BOOT
        FDB DBOOT
        ENDIF DMAFOPT
        IFD EXTOPT
        FCC 'U'        ; *** IF FPGA, 'U' IS FOR USER
        FDB USRCMD
        ENDIF EXTOPT
        IFD RTCOPT
        FCC 'T'
        FDB TIMSET
        ENDIF RTCOPT
        IFD TRAOPT
        FCC "T"
        FDB TRACE
        ENDIF TRAOPT
*
TABEND  EQU *
*
* ** 6809 VECTOR ADDRESSES **
*
* FOLLOWING ARE THE ADDRESSES OF THE VECTOR ROUTINES
* FOR THE 6809 PROCESSOR. DURING INITIALIZATION THEY
* ARE RELOCATED TO RAM FROM $DFC0 TO $DFCF. THEY ARE
* RELOCATED TO RAM SO THAT THE USER MAY REVECTOR TO
* HIS OWN ROUTINES IF HE SO DESIRES.
*
*
RAMVEC  FDB SWIE       ; USER-V
        FDB RTI        ; SWI3-V
        FDB RTI        ; SWI2-V
        FDB RTI        ; FIRQ-V
        FDB RTI        ; IRQ-V
        FDB SWIE       ; SWI-V
        FDB $FFFF      ; SVC-VO
        FDB $FFFF      ; SVC-VL
*
* PRINTABLE MESSAGE STRINGS
*
MSG1    FCB  $D,$A,$0,$0,$0 * 0, CR/LF, 0
        FCC  'SYS09BUG 1.6 FOR '
        IFD  SWTOPT`
        FCC  'SWTPC '
        ENDIF SWTOPT
        IFD  ADSOPT
        FCC  'ADS6809 '
        ENDIF ADSOPT
        IFD  B3SOPT
        FCC  'B3-S2+ '
        ENDIF B3SOPT
        IFD  B5XOPT
        FCC  'B5-X300 '
        ENDIF B5XOPT
        IFD  S3SOPT
        FCC  'S3STARTER '
        ENDIF S3SOPT
        IFD  S3EOPT
        FCC  'S3E '
        ENDIF S3EOPT
        IFD  XESOPT`
        FCC  'XESS '
        ENDIF XESOPT
        FCC ' - '
        FCB 4
MSG2    FCB 'K,$0D,$0A,$00,$00,$00,$04 ; K,<CR>,<LF>,3 NULS,<EOT>
MSG3    FCC '>'
        FCB 4
MSG4    FCC 'WHAT?'
        FCB 4
MSG5    FCC ' - '
        FCB 4'
MSG10   FCC '  SP='
        FCB 4
MSG11   FCC '  PC='
        FCB 4
MSG12   FCC '  US='
        FCB 4
MSG13   FCC '  IY='
        FCB 4
MSG14   FCC '  IX='
        FCB 4
MSG15   FCC '  DP='
        FCB 4
MSG16   FCC '  A='
        FCB 4
MSG17   FCC '  B='
        FCB 4
MSG18   FCC '  CC: '
        FCB 4
MSG19   FCC 'EFHINZVC'
MSG20   FCC 'S1'
        FCB 4
        IFD DATOPT
*
* POWER UP/ RESET/ NMI ENTRY POINT
*
        ORG $FF00
*
*
START   LDX  #IC11    ; POINT TO DAT RAM IC11
        LDA  #$0F     ; GET COMPLIMENT OF ZERO
*
*
* INITIALIZE DAT RAM --- LOADS $F-$0 IN LOCATIONS $0-$F
* OF DAT RAM, THUS STORING COMPLEMENT OF MSB OF ADDRESS
* IN THE DAT RAM. THE COMPLEMENT IS REQUIRED BECAUSE THE
* OUTPUT OF IC11, A 74S189, IS THE INVERSE OF THE DATA
* STORED IN IT.
*
*
DATLP   STA  ,X+       ; STORE & POINT TO NEXT RAM LOCATION
        DECA           ; GET COMP. VALUE FOR NEXT LOCATION
        BNE  DATLP     ; ALL 16 LOCATIONS INITIALIZED ?
*
* NOTE: IX NOW CONTAINS $0000, DAT RAM IS NO LONGER
*       ADDRESSED, AND LOGICAL ADDRESSES NOW EQUAL
*       PHYSICAL ADDRESSES.
*
        LDA  #$F0
        STA  ,X        ; STORE $F0 AT $FFFF
        LDX  #$D0A0    ; ASSUME RAM TO BE AT $D000-$DFFF
        LDY  #TSTPAT   ; LOAD TEST DATA PATTERN INTO "Y"
TSTRAM  LDU  ,X        ; SAVE DATA FROM TEST LOCATION
        STY  ,X        ; STORE TEST PATTERN AT $D0A0
        CMPY ,X        ; IS THERE RAM AT THIS LOCATION ?
        BEQ  CNVADR    ; IF MATCH THERE'S RAM, SO SKIP
        LEAX -$1000,X  ; ELSE POINT 4K LOWER
        CMPX #$F0A0    ; DECREMENTED PAST ZER0 YET ?
        BNE  TSTRAM    ; IF NOT CONTINUE TESTING FOR RAM
        BRA  START     ; ELSE START ALL OVER AGAIN
*
*
* THE FOLLOWING CODE STORES THE COMPLEMENT OF
* THE MS CHARACTER OF THE FOUR CHARACTER HEX
* ADDRESS OF THE FIRST 4K BLOCK OF RAM LOCATED
* BY THE ROUTINE "TSTRAM" INTO THE DAT RAM. IT
* IS STORED IN RAM IN THE LOCATION THAT IS
* ADDRESSED WHEN THE PROCESSOR ADDRESS IS $D---,
* THUS IF THE FIRST 4K BLOCK OF RAM IS FOUND
* WHEN TESTING LOCATION $70A0, MEANING THERE
* IS NO RAM PHYSICALLY ADDRESSED IN THE RANGE
* $8000-$DFFF, THEN THE COMPLEMENT OF THE
* "7" IN THE $70A0 WILL BE STORED IN
* THE DAT RAM. THUS WHEN THE PROCESSOR OUTPUTS
* AN ADDRESS OF $D---, THE DAT RAM WILL RESPOND
* BY RECOMPLEMENTING THE "7" AND OUTPUTTING THE
* 7 ONTO THE A12-A15 ADDRESS LINES. THUS THE
* RAM THAT IS PHYSICALLY ADDRESSED AT $7---
* WILL RESPOND AND APPEAR TO THE 6809 THAT IT
* IS AT $D--- SINCE THAT IS THE ADDRESS THE
* 6809 WILL BE OUTPUTING WHEN THAT 4K BLOCK
* OF RAM RESPONDS.
*
*
CNVADR  STU  ,X        ; RESTORE DATA AT TEST LOCATION
        TFR  X,D       ; PUT ADDR. OF PRESENT 4K BLOCK IN D
        COMA           ; COMPLEMENT MSB OF THAT ADDRESS
        LSRA           ; PUT MS 4 BITS OF ADDRESS IN
        LSRA           ; LOCATION D0-D3 TO ALLOW STORING
        LSRA           ; IT IN THE DYNAMIC ADDRESS
        LSRA           ; TRANSLATION RAM.
        STA  $FFFD     ; STORE XLATION FACTOR IN DAT "D"
*
        LDS  #STACK    ; INITIALIZE STACK POINTER
*
*
* THE FOLLOWING CHECKS TO FIND THE REAL PHYSICAL ADDRESSES
* OF ALL 4K BLKS OF RAM IN THE SYSTEM. WHEN EACH 4K BLK
* OF RAM IS LOCATED, THE COMPLEMENT OF IT'S REAL ADDRESS
* IS THEN STORED IN A "LOGICAL" TO "REAL" ADDRESS XLATION
* TABLE THAT IS BUILT FROM $DFD0 TO $DFDF. FOR EXAMPLE IF
* THE SYSTEM HAS RAM THAT IS PHYSICALLY LOCATED (WIRED TO
* RESPOND) AT THE HEX LOCATIONS $0--- THRU $F---....
*
*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
* 4K 4K 4K 4K 4K 4K 4K 4K -- 4K 4K 4K 4K -- -- --
*
* ....FOR A TOTAL OF 48K OF RAM, THEN THE TRANSLATION TABLE
* CREATED FROM $DFD0 TO $DFDF WILL CONSIST OF THE FOLLOWING....
*
*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
* 0F 0E 0D 0C 0B 0A 09 08 06 05 00 00 04 03 F1 F0
*
*
* HERE WE SEE THE LOGICAL ADDRESSES OF MEMORY FROM $0000-$7FFF
* HAVE NOT BEEN SELECTED FOR RELOCATION SO THAT THEIR PHYSICAL
* ADDRESS WILL = THEIR LOGICAL ADDRESS; HOWEVER, THE 4K BLOCK
* PHYSICALLY AT $9000 WILL HAVE ITS ADDRESS TRANSLATED SO THAT
* IT WILL LOGICALLY RESPOND AT $8000. LIKEWISE $A,$B, AND $C000
* WILL BE TRANSLATED TO RESPOND TO $9000,$C000, AND $D000
* RESPECTIVELY. THE USER SYSTEM WILL LOGICALLY APPEAR TO HAVE
* MEMORY ADDRESSED AS FOLLOWS....
*
*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
* 4K 4K 4K 4K 4K 4K 4K 4K 4K 4K -- -- 4K 4K -- --
*
*
        LDY  #LRARAM   ; POINT TO LOGICAL/REAL ADDR. TABLE
        STA  13,Y      ; STORE $D--- XLATION FACTOR AT $DFDD
        CLR  14,Y      ; CLEAR $DFDE
        LDA  #$F0      ; DESTINED FOR IC8 AN MEM EXPANSION ?
        STA  15,Y      ; STORE AT $DFDF
        LDA  #$0C      ; PRESET NUMBER OF BYTES TO CLEAR
CLRLRT  CLR  A,Y       ; CLEAR $DFDC THRU $DFD0
        DECA           ; SUB. 1 FROM BYTES LEFT TO CLEAR
        BPL  CLRLRT    ; CONTINUE IF NOT DONE CLEARING
FNDRAM  LEAX -$1000,X  ; POINT TO NEXT LOWER 4K OF RAM
        CMPX #$F0A0    ; TEST FOR DECREMENT PAST ZERO
        BEQ  FINTAB    ; SKIP IF FINISHED
        LDU  ,X        ; SAVE DATA AT CURRENT TEST LOCATION
        LDY  #TSTPAT   ; LOAD TEST DATA PATTERN INTO Y REG.
        STY  ,X        ; STORE TEST PATT. INTO RAM TEST LOC.
        CMPY ,X        ; VERIFY RAM AT TEST LOCATION
        BNE  FNDRAM    ; IF NO RAM GO LOOK 4K LOWER
        STU  ,X        ; ELSE RESTORE DATA TO TEST LOCATION
        LDY  #LRARAM   ; POINT TO LOGICAL/REAL ADDR. TABLE
        TFR  X,D       ; PUT ADDR. OF PRESENT 4K BLOCK IN D
        LSRA           ; PUT MS 4 BITS OF ADDR. IN LOC. D0-D3
        LSRA           ; TO ALLOW STORING IT IN THE DAT RAM.
        LSRA
        LSRA
        TFR  A,B       ; SAVE OFFSET INTO LRARAM TABLE
        EORA #$0F      ; INVERT MSB OF ADDR. OF CURRENT 4K BLK
        STA  B,Y       ; SAVE TRANSLATION FACTOR IN LRARAM TABLE
        BRA  FNDRAM    ; GO TRANSLATE ADDR. OF NEXT 4K BLK
FINTAB  LDA  #$F1      ; DESTINED FOR IC8 AND MEM EXPANSION ?
        LDY  #LRARAM   ; POINT TO LRARAM TABLE
        STA  14,Y      ; STORE $F1 AT $DFCE
*
* THE FOLLOWING CHECKS TO SEE IF THERE IS A 4K BLK OF
* RAM LOCATED AT $C000-$CFFF. IF NONE THERE IT LOCATES
* THE NEXT LOWER 4K BLK AN XLATES ITS ADDR SO IT
* LOGICALLY RESPONDS TO THE ADDRESS $C---.
*
*
        LDA  #$0C      ; PRESET NUMBER HEX "C"
FINDC   LDB  A,Y       ; GET ENTRY FROM LRARAM TABLE
        BNE  FOUNDC    ; BRANCH IF RAM THIS PHYSICAL ADDR.
        DECA           ; ELSE POINT 4K LOWER
        BPL  FINDC     ; GO TRY AGAIN
        BRA  XFERTF
FOUNDC  CLR  A,Y       ; CLR XLATION FACTOR OF 4K BLOCK FOUND
        STB  $0C,Y     ; GIVE IT XLATION FACTOR MOVING IT TO $C---
*
* THE FOLLOWING CODE ADJUSTS THE TRANSLATION
* FACTORS SUCH THAT ALL REMAINING RAM WILL
* RESPOND TO A CONTIGUOUS BLOCK OF LOGICAL
* ADDRESSES FROM $0000 AND UP....
*
        CLRA           ; START AT ZERO
        TFR  Y,X       ; START POINTER "X" START OF "LRARAM" TABLE.
COMPRS  LDB  A,Y       ; GET ENTRY FROM "LRARAM" TABLE
        BEQ  PNTNXT    ; IF IT'S ZER0 SKIP
        CLR  A,Y       ; ELSE ERASE FROM TABLE
        STB  ,X+       ; AND ENTER ABOVE LAST ENTRY- BUMP
PNTNXT  INCA           ; GET OFFSET TO NEXT ENTRY
        CMPA #$0C      ; LAST ENTRY YET ?
        BLT  COMPRS
*
* THE FOLLOWING CODE TRANSFER THE TRANSLATION
* FACTORS FROM THE LRARAM TABLE TO IC11 ON
* THE MP-09 CPU CARD.
*
XFERTF  LDX  #IC11     ; POINT TO DAT RAM IC11
        LDB  #$10      ; GET NO. OF BYTES TO MOVE
FETCH   LDA  ,Y+       ; GET BYTE AND POINT TO NEXT
        STA  ,X+       ; POKE XLATION FACTOR IN IC11
        DECB           ; SUB 1 FROM BYTES TO MOVE
        BNE  FETCH     ; CONTINUE UNTIL 16 MOVED
*
        ELSE
LRA     RTS
START   LDS  #STACK    ; INITIALIZE STACK POINTER
        CLRB
        ENDIF DATOPT
*
        COMB           ; SET "B" NON-ZERO
        STB  ECHO      ; TURN ON ECHO FLAG
        LBRA MONITOR   ; INITIALIZATION IS COMPLETE
*
** INTERRUPT JUMP VECTORS
*
V1      JMP  [STACK]
V2      JMP  [SWI2]
V3      JMP  [FIRQ]
V4      JMP  [IRQ]
V5      JMP  [SWI]
*
* SWI3 ENTRY POINT
*
SWI3E   TFR  S,U
        LDX  10,U      *$FFC8
        LDB  ,X+
        STX  10,U
        CLRA
        ASLB
        ROLA
        LDX  SVCVO
        CMPX #$FFFF
        BEQ  SWI3Z
        LEAX D,X
        CMPX SVCVL
        BHI  SWI3Z
        PSHS X
        LDD  ,U
        LDX  4,U
        JMP  [,S++]
SWI3Z   PULU A,B,X,CC,DP
        LDU  2,U
        JMP  [SWI3]
*
* 6809 VECTORS
*
        ORG $FFF0
        FDB V1    USER-V
        FDB SWI3E SWI3-V
        FDB V2    SWI2-V
        FDB V3    FIRQ-V
        FDB V4    IRQ-V
        FDB V5    SWI-V
        FDB V1    NMI-V
        FDB START RESTART-V
        END START

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.