URL
https://opencores.org/ocsvn/System09/System09/trunk
Subversion Repositories System09
[/] [System09/] [trunk/] [src/] [sys09bug/] [sys09bug.asm] - Rev 120
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
* 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
* 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
* BY: JOHN KENT
* DATE: 8TH JAN 2008
* ADDED: CONDITIONALS FOR SPARTAN3E STARTER BOARD
* WITH ONLY 32K OF RAM
*
* Modified to SYS09BUG VER 1.4
* 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
* BY: JOHN KENT
* DATE: 7TH SEP 2008
* ADDED: ADDED "B3-S2+" STRING
*
* Modified to SYS09BUG VER 1.6
* BY: JOHN KENT
* DATE: 2ND DEC 2008
* ADDED: ADDED HARDWARE FLOW CONTROL
*
* CHANGED: SEPARARTED OPTIONS EQUATES AND BODY INTO SEPARATE FILES
*
* Modified to SYS09BUG VER 1.7
* BY: JOHN KENT
* DATE: 16TH OCT 2010
* ADDED: "DE2-70" STRING
*
* *** 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.7 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
IFD DE270OPT
FCC 'DE2-70'
ENDIF DE270OPT
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