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

Subversion Repositories System09

[/] [System09/] [branches/] [mkfiles_rev1/] [src/] [sys09bug/] [sys09bug.asm] - Rev 95

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
* 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        DECREMENT 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 
        BVS  ALTUD 
        STX  8,U 
ALTUD   RTS ;
* 
* ALTER "Y" INDEX REGISTER 
* 
ALTRY   BSR  PRTIY   PRINT MSG " IY = " 
        BSR  JOUT1S   OUTPUT SPACE 
        BSR  JIN1ADR 
        BVS  ALTYD 
        STX  6,U     $F8F0 
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 #$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 #$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 
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 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. 
        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 
        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  #$11   SET 8 DATA, 2 STOP AN 0 PARITY 
        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  STAA   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 ?
        LBEQ   BACKSP
        CMPA   #$1B      ESCAPE SEQUENCE?
        LBEQ   SETESC
        CMPA   #$1A      CTRL Z - Clear Screen
        LBEQ   CLRSCR
        CMPA   #$16      CTRL ^ - Home
        LBEQ   HOME
        CMPA   #$D       CTRL M - RETURN?
        LBEQ   CRETN
        CMPA   #$0C      CTRL L - CHAR RIGHT
        LBEQ   CHRIGHT
        CMPA   #$0B      CTRL K - MOVE UP ONE LINE
        LBEQ   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?
        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 ?
        LBEQ   RETESC    Yes, Ignore
        DECB             No, Decrement ROW
        LBRA   NEWCUR    POSITION CURSOR
*
*********************************** BACK SPACE
*
BACKSP  LDA    COLADX
        BEQ    RETESC      RETURN
        DECA
        LBRA   POSCOL    POSITION CURSOR
*
*********************************** CURSOR RIGHT
*
CHRIGHT LDA    COLADX
        INCA
        CMPA   #LINLEN
        LBEQ   RETESC
        LBRA   POSCOL
*
*********************************** CURSOR RIGHT
*
HOME    LDD    #0        HOME - POSITION TOP OF SCREEN
        LBRA    NEWCUR
*
***************************************************
*                 ESCAPE HANDLERS                 *
***************************************************
*
ESCAPE  LDAB   ESCFLG    GET FLAG
        CMPB   #'=       SETTING CURSOR?
        BEQ    ESCCUR    BRANCH IF SO
        CMPA   #'Y       CLEAR TO END OF SCREEN?
        LBEQ   ESCCLS
        CMPA   #'T       CLEAR TO END OF LINE?
        BEQ   ESCCLL
        CMPA   #'=       STARTING CURSOR SET?
        BNE    CLRESC    BRANCH IF NOT
*
***************************** START ESCAPE SEQUENCE
*
SETESC  STAA   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
        STAA   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  LDAB   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
        STAA   0,X       DISPLAY CHARACTER
        LBSR   NEWCOL    UPDATE COLUMN
*
** DISPLAY CURSOR AND RETURN
RETURN  LDX    CURSOR    AND DISPLAY IT
        LDB    ,X
        ORAB   #$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, Ignore
        DECB             No, Decrement ROW
        LBRA   NEWCUR    POSITION CURSOR


*********************************** BACK SPACE

BACKSP  LDA    COLADX
        BEQ    RETESC      RETURN
        DECA
        LBRA   POSCOL    POSITION CURSOR

*********************************** CURSOR RIGHT

CHRIGHT LDA    COLADX
        INCA
        CMPA   #LINLEN
        BEQ   RETESC
        LBRA   POSCOL

***************************************************
*                 ESCAPE HANDLERS                 *
***************************************************

ESCAPE  LDAB   ESCFLG    GET FLAG
        CMPB   #'=       SETTING CURSOR?
        BEQ    ESCCUR    BRANCH IF SO
        CMPA   #'Y       CLEAR TO END OF SCREEN?
        LBEQ   ESCCLS
        CMPA   #'T       CLEAR TO END OF LINE?
        BEQ   ESCCLL
        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  STAA   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
        STAA  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  LDAB  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
        LDAB  ROWADX
        CMPB  #NUMLIN-1
        BEQ   ESCCLL
*
** SCROLL SCREEN DOWN FROM CURSOR
*
        LDX   #SCREEN+SCNLEN-LINLEN
ESCIN0  LDAA  0,-X
        STAA  LINLEN,X
        LDA   SCNLEN,X
        STA   SCNLEN+LINLEN,X
        CPX   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
        LDAA  LINLEN,X  MOVE TWO BYTES
        STAA  0,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  LDAA  #$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
        STAB PADATA
RESTLP  INCB DELAY FOR RESET
        BNE RESTLP
        STAA PADATA ACCA=DIRMSK
*
** INITALIZE PORT B (DATA PORT)
        LDAA #$2A
        STAA PBCTRL
        LDD #$FF2E ACCA=$FF ACCB =%00101110
        STD PBDATA PBDREG   PBCTRL
*
** SELECT 66 LINES/PAGE
        LDAA #$1B
        BSR POUTCH
        LDAA #'C
        BSR POUTCH
        LDAA #66
        PULS B
*************************************
*
** OUTPUT A CHARACTER TO THE PRINTER
*
*************************************
POUTCH  PSHS B
        LDAB PBDATA CLEAR INTERRUPT BIT
*
** WAIT TILL NOT BUSY
BUSYLP  LDAB PADATA
        BITB #PERROR
        BEQ PEXIT
        TSTB
        BMI BUSYLP
*
** NOW OUTPUT CHARACTER
        STAA 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.4 FOR ' 
      IFD S3EOPT
      FCC 'S3E '
      ENDIF S3EOPT
      IFD B5XOPT
      FCC 'B5-X300 '
      ENDIF B5XOPT
      IFD S3SOPT
      FCC 'S3STARTER '
      ENDIF S3SOPT
      IFD ADSOPT
      FCC 'ADS6809 '
      ENDIF ADSOPT
      IFD SWTOPT`
      FCC 'SWTPC '
      ENDIF SWTOPT
      IFD XESOPT`
      FCC  'XESS '
      ENDIF XESOPT
      FCC ' - '
      FCB 4 
MSG2  FCB 'K,$D,$A,$00,$00,$00,$04 K, * CR/LF + 3 NULS 
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  #$F 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  $C,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.