URL
https://opencores.org/ocsvn/System09/System09/trunk
Subversion Repositories System09
[/] [System09/] [rev_86/] [src/] [dump/] [dump_cf8.asm] - Rev 220
Go to most recent revision | Compare with Previous | Blame | View Log
*
* Sector Dump Utility
* For Compact Flash Driver
* for the 6809
* Configured in 8 bit mode
*
* John Kent
* 21 May 2007
*
* Register Equates
*
CF_BASE EQU $E040
CF_DATA EQU CF_BASE+0
CF_ERROR EQU CF_BASE+1 ; read error
CF_FEATURE EQU CF_BASE+1 ; write feature
CF_SECCNT EQU CF_BASE+2
CF_SECNUM EQU CF_BASE+3
CF_CYLLO EQU CF_BASE+4
CF_CYLHI EQU CF_BASE+5
CF_HEAD EQU CF_BASE+6
CF_STATUS EQU CF_BASE+7 ; read status
CF_COMAND EQU CF_BASE+7 ; write command
*
* Command Equates
*
CMDREAD EQU $20 ; Read Single sector
CMDWRITE EQU $30 ; Write Single sector
CMDFEATURE EQU $EF
FEAT8BIT EQU $01 ; enable 8 bit transfers
HEADLBA EQU $E0
*
* Status bit equates
*
BUSY EQU $80
DRDY EQU $40
DRQ EQU $08
ERR EQU $01
*
* Start of Program
*
ORG $0100
START LBRA START1
*
* DATA STORAGE
*
SECNUM FCB $00,$00,$00
CPORT FDB $E000
ECHO FCB $FF
*
* SECTOR BUFFER
*
SECBUF RMB 512
*
* PROGRAM STACK
*
RMB 64
STACK EQU *
*
* Initialization
*
START1 LDS #STACK
*
* Clear sector buffer
*
LDX #SECBUF
LDY #512
ZEROLP CLR ,X+
LEAY -1,Y
BNE ZEROLP
*
* INITIALIZE CF CARD FOR 8 BIT LBA MODE
*
JSR WAITRDY
LDA #HEADLBA
STA CF_HEAD
JSR WAITRDY
LDA #FEAT8BIT
STA CF_FEATURE
LDA #CMDFEATURE
STA CF_COMAND
JSR WAITRDY
*
* DISPLAY TITTLE BANNER
*
LDX #TTLMSG
JSR PDATA
*
* COMMAND LOOP
* R - READ
* W - WRITE
* N - NEXT
* P - PREV
* M - MODIFY
* Q - QUIT
*
CMDLP LDX #CMDMSG
JSR PDATA
JSR ECHON
CMPA #'R'
BEQ READ
CMPA #'N'
BEQ NEXT
CMPA #'P'
BEQ PREV
CMPA #'W'
LBEQ WRITE
CMPA #'M'
BEQ MODIFY
CMPA #'Q'
BEQ QUIT
LDX #WOTMSG
JSR PSTRNG
BRA CMDLP
*
* QUIT
*
QUIT JMP [$F800]
*
* MODIFY SECTOR
*
MODIFY JSR MEMCHG
BRA CMDLP
*
* NEXT SECTOR (READ)
* INCREMENT SECTOR NUMBER
* WRAPS AROUND TO ZERO ON $FFFFFF
*
NEXT LDX SECNUM+1
LEAX 1,X
STX SECNUM+1
BNE READS
INC SECNUM
BRA READS
*
* PREVIOUS SECTOR (READ)
* DECREMENT SECTOR NUMBER
* DON'T DECREMENT PAST $000000
*
PREV LDX SECNUM+1
BNE PREV1
TST SECNUM
BEQ READS
DEC SECNUM
PREV1 LEAX -1,X
STX SECNUM+1
BRA READS
*
* READ SECTORS FROM CF
*
READ LDX #SECPMT
JSR PSTRNG
JSR IN6HEX
BVS RDEXIT
STB SECNUM
STX SECNUM+1
*
READS LDA #$01
STA CF_SECCNT
LDA SECNUM+2
STA CF_SECNUM
LDA SECNUM+1
STA CF_CYLLO
LDA SECNUM+0
STA CF_CYLHI
*
LDA #CMDREAD ; IDE READ MULTIPLE
STA CF_COMAND
JSR WAITRDY
*
LDX #SECBUF
LDY #512
*
* READ LOOP
*
RDLOOP JSR WAITDRQ
LDA CF_DATA
STA ,X+
LEAY -1,Y
BNE RDLOOP
*
JSR WAITRDY
JSR MEMDUMP
RDEXIT JMP CMDLP
*
* WRITE SECTOR TO CF
*
WRITE LDX #SECPMT
JSR PSTRNG
JSR IN6HEX
BVS WREXIT
STB SECNUM
STX SECNUM+1
*
LDA #$01
STA CF_SECCNT
LDA SECNUM+2
STA CF_SECNUM
LDA SECNUM+1
STA CF_CYLLO
LDA SECNUM+0
STA CF_CYLHI
*
LDA #CMDWRITE; IDE WRITE MULTIPLE
STA CF_COMAND
JSR WAITRDY
*
LDX #SECBUF
LDY #512
*
* WRITE LOOP
*
WRLOOP JSR WAITDRQ
LDA ,X+
STA CF_DATA
LEAY -1,Y
BNE WRLOOP
*
JSR WAITRDY
WREXIT JMP CMDLP
*
* 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
*
* DUMP SECTOR IN MEMORY
*
MEMDUMP LDX #SECMSG
JSR PSTRNG
LDA SECNUM
JSR OUT2H
LDX SECNUM+1
JSR OUT4H
JSR PCRLF
LDY #$0000
LEAX #$1FF,Y
*
* 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 SECBUF,X GET FROM MEMORY HEX BYTE TO PRINT
LEAX 1,X
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 SECBUF,X GET CHARACTER FROM MEMORY
LEAX 1,X
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
*
*
***** "M" MEMORY EXAMINE AND CHANGE *****
*
* RESTRICT ADDRESSING RANGE TO 512 BYTES ($000 - $1FF)
*
MEMCHG LDX #MEMMSG
JSR PSTRNG
LBSR IN3HEX INPUT ADDRESS
BVS CHRTN IF NOT HEX, RETURN
CMPX #$0200
BHS CHRTN
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 SECBUF,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 SECBUF,Y CHANGE BYTE IN MEMORY
CMPA SECBUF,Y DID MEMORY BYTE CHANGE?
BEQ FORWRD $F972
LBSR OUT1S OUTPUT SPACE
LDA #'? LOAD QUESTION MARK
LBSR OUTCH PRINT IT
FORWRD CMPY #$01FF
BEQ MEMC2
LEAY 1,Y POINT TO NEXT HIGHER MEM LOCATION
BRA MEMC2 PRINT LOCATION & CONTENTS
BACK CMPY #$0000
BEQ MEMC2
LEAY -1,Y POINT TO LAST MEM LOCATION
BRA MEMC2 PRINT LOCATION & CONTENTS
*
* THE FOLLOWING ROUTINE LOOPS WAITING FOR THE
* OPERATOR TO INPUT ONE VALID HEX ADDRESS. THE
* ADDRESS IS RETURNED IN THE "X" REGISTER.
*
* IN6HEX - MS BYTE IN ACCB
* LS WORD IN X REG
*
IN6HEX LEAS -3,S
BSR BYTE
BVS NOTHEX
STA 0,S
BSR BYTE
BVS NOTHEX
STA 1,S
BSR BYTE
BVS NOTHEX
STA 2,S
CLRA
PULS B,X,PC
*
* INPUT 3 HEX DIGITS
* RESULT RETURNED IN X
*
IN3HEX BSR INHEX INPUT HEX (1 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
*
* 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
BSR PDATA PRINT MSG
PULS X,PC RESTORE IX
PRINT BSR OUTCH
*
* PDATA
*
PDATA LDA ,X+ GET 1st CHAR. TO PRINT
CMPA #4 IS IT EOT?
BNE PRINT IF NOT EOT PRINT IT
RTS ;
*
*
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 ?
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 ?
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 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
*
*
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
*
* MESSAGE STRINGS
*
TTLMSG FCB $0A,$0D
FCC "COMPACT FLASH SECTOR READ/WRITE UTILITY"
FCB $04
CMDMSG FCB $0A,$0D
FCC "(R) READ SECTOR"
FCB $0A,$0D
FCC "(W) WRITE SECTOR"
FCB $0A,$0D
FCC "(N) NEXT SECTOR"
FCB $0A,$0D
FCC "(P) PREV SECTOR"
FCB $0A,$0D
FCC "(M) MODIFY SECTOR"
FCB $0A,$0D
FCC "(Q) QUIT"
FCB $0A,$0D
FCC ": "
FCB $04
SECPMT FCC "SECTOR NUMBER (6 HEX) : "
FCB $04
SECMSG FCC "SECTOR NUMBER - $"
FCB $04
MEMMSG FCB $0D,$0A
FCC "MEMORY ADDRESS (3 HEX): "
FCB $04
MSG5 FCC " - "
FCB $04
MSG2 FCB $00,$00,$0A,$0D,$00,$00,$00,$04
WOTMSG FCC "What ?"
FCB $0D,$0A,$04
*
END START
Go to most recent revision | Compare with Previous | Blame | View Log