📄 flash.a11
字号:
STAA FCmdA+FOffset ;
BSR FUnlock ;Send unlock sequence again
TBA ;A <- Sector address
BSR FSector ;Select sector to erase
LDX #FOffset ;Assume even sector
BITA #$01 ;Odd sector ?
BEQ Main2 ; No
LDX #FOffset+$4000 ; Yes, set address for odd sector
Main2 LDAA #FCmdSEra ;Sector erase command
STAA 0,X ;Send to sector base address
Main3 LDAA #EraseAck ;Acknowledge erase request
Main4 BSR CharOut ;
Main$$ BRA Main ;Issue sector prompt again
;---------------------------------------
GetHexD$$ BRA GetHexD ;Help for GETHEXD call
CharOut$ BRA CharOut ;Help for CHAROUT call
Msg$ BRA Msg ;Help for MSG call
;---------------------------------------
; Erase entire FLASH array
;
; Entire device erase procedure:
; 1. Write unlock sequence:
; Value <FUnlkV1> written to address <FUnlkA1>
; Value <FUnlkV2> written to address <FUnlkA2>
; These writes must occur with FA15=FA16=0
; 2. Write generic erase-enable command:
; Value <FCmdErase> written to address <FCmdA>
; 3. Write unlock sequence again (same as step 1).
; 4. Write "erase device" command:
; Value <FCmdCEra> written to address <FCmdA>
;
; Note: Verification of erasure is not performed.
Main5 BSR FUnlock ;Send unlock sequence
LDAA #FCmdErase ;Erase command prebyte
STAA FCmdA+FOffset ;
BSR FUnlock ;Send unlock sequence again
LDAA #FCmdCEra ;Erase entire device command
STAA FCmdA+FOffset ;
BRA Main3 ;Echo "!" & issue sector prompt again
; Prompt for load address offset
Main6 BSR Msg ;Send offset prompt
DB CR,LF,'Ofs:',NUL
BSR GetNum$ ;Get offset (4-digit hex)
BCS Main7 ;Use default offset if <ESC> rec'd
STX @Offset ;Save offset entered
; Send prompt to start sending S-records
; Jump to S-record read & program routine
Main7 BSR Msg$ ;Transmit S-record send prompt
DB CR,LF,'Send!',CR,LF,NUL
BRA Program$ ;Start S-record read & program routine
;*******************************************************************************
;Subroutine: CharIn
;Function: Read next available character from SCI receive queue
; Waits for character to be received before returning
; Ignores characters with SCI error bits set
;
; A <- Character received from SCI (MSB stripped)
;
;Stack usage: 3 bytes (including BSR/JSR)
;Destroyed: Nothing
;*******************************************************************************
CharIn PSHB ;Save B
CharIn1 LDAB SCSR ;Get SCI status
BITB #RDRF. ;Data ready ?
BEQ CharIn1 ; No, wait
LDAA SCDR ;Get character received
BITB #NF.+FE. ;Any errors ?
BNE CharIn ; Yes, discard data
ANDA #$7F ;Strip MSbit
PULB ;Recover B
RTS ;Exit
;*******************************************************************************
;Subroutine: CharOut
;Function: Transmit character via SCI transmitter
; Waits for TDRE before sending character
;
; A -> Character to send via SCI
;
;Stack usage: 3 bytes (including BSR/JSR)
;Destroyed: Nothing
;*******************************************************************************
CharOut PSHA ;Save character to send
CharOut1 LDAA SCSR ;Check SCI status
BITA #TDRE. ;Transmit data register clear ?
BEQ CharOut1 ; No, wait
PULA ;Recover character
STAA SCDR ;Transmit
RTS ;Exit
;*******************************************************************************
;Subroutine: FUnlock
;Function: Send array write unlock sequence to FLASH
;
; Write <FUnlkV1> to <FUnlkA1> ($AA to $5555)
; Write <FUnlkV2> to <FUnlkA2> ($55 to $2AAA)
;
; Values specified above are device addresses. The value
; <FOffset> is added to these addresses to account for the
; FLASH ROM's position in the HC11 memory map.
;
;Stack usage: 6 bytes (including BSR/JSR)
;Destroyed: A
;*******************************************************************************
FUnlock CLRA ;A16=A15=0 for unlock commands
BSR FSector ;
LDAA #FUnlkV1 ;1st unlock write cycle
STAA FOffset+FUnlkA1 ;
LDAA #FUnlkV2 ;2nd unlock write cycle
STAA FOffset+FUnlkA2 ;
RTS ;Exit
;*******************************************************************************
;Subroutine: FSector
;Function: Set FLASH A15 & A16 lines to requested sector address
;
; A -> Sector # (bits 1-2 relevant; all others ignored)
;
; This implementation assumes that the 128Kx8 FLASH ROM
; device is mapped such that a 32K page exists in the HC11
; address space at any given time. Device address bits A15
; (FA15) and A16 (FA16) are driven by HC11 output ports.
; This routine accepts a FLASH sector number (0-7, specifying
; a 16K segment of the device) and uses the upper two bits
; of this value (bits 1 & 2) to drive the appropriate HC11
; output pins which in turn bank in the appropriate 32K
; FLASH memory block into the HC11 address space.
;
; Since the least significant bit (bit 0) of the sector number
; is not relevant to the bank switching scheme, it is ignored.
;
;Stack usage: 4 bytes (including BSR/JSR)
;Destroyed: Nothing
;*******************************************************************************
FSector PSHX ;Save X
LDX #IOBase ;Point to I/O register base address
BCLR FA15_,X,FA15.+FA16. ;Assume sector 0
BITA #$02 ;A15 = 1 ?
BEQ FSector1 ; No: FA15 = 0
BSET FA15_,X,FA15. ; Yes: FA15 = 1
FSector1 BITA #$04 ;A16 = 1 ?
BEQ FSector2 ; No: FA16 = 0
BSET FA16_,X,FA16. ; Yes: FA16 = 1
FSector2 PULX ;Restore X
RTS ;Exit
;---------------------------------------
Program$ BRA Program ;Help for PROGRAM branch
Main$ BRA Main$$ ;Help for MAIN branch
;---------------------------------------
;*******************************************************************************
;Subroutine: GetHexD
;Function: Get single char from SCI, interpret as hex digit
;
; A <- Actual character received (converted to uppercase)
; B <- Integer value of digit received (0-15)
; Carry set on exit if digit was not valid hex
;
;Note: Character read is NOT echoed back
;
;Stack usage: 5 bytes (including BSR/JSR)
;Destroyed: Nothing
;*******************************************************************************
GetHexD BSR CharIn ;Get character from SCI
CMPA #'a' ;Lowercase?
BLO GetHexD1 ; No
CMPA #'z' ;Lowercase?
BHI GetHexD1 ; No
SUBA #'a'-'A' ;Subtract lowercase offset
GetHexD1 TAB ;B <- Character received
SUBB #'0' ;Subtract ASCII digit offset
BLO GetHexDER ; Exit if not valid digit
CMPB #10 ;Digit = 0..9 ?
BLO GetHexDOK ; Yes, exit now
SUBB #'A'-'0'-10 ;Subtract alpha offset
BLO GetHexDER ; Exit if underflow (invalid digit)
CMPB #10 ;Valid digit ?
BLO GetHexDER ; No, exit
CMPB #15 ;Valid digit ?
BHI GetHexDER ; No, exit
GetHexDOK CLC ;Standard exit - no error
RTS ;
GetHexDER SEC ;Error exit
RTS ;
;*******************************************************************************
;Subroutine: GetHexB
;Function: Get 2-digit (byte) hex # from SCI
;
; A <- Last character received from SCI
; B <- Integer representation of value received
;
;Note: Character(s) read are NOT echoed back
;
;Stack usage: 7 bytes (including BSR/JSR)
;Destroyed: Nothing
;*******************************************************************************
GetHexB BSR GetHexD ;Get Most Significant Digit (MSD)
BCS GetHexBX ;Exit if error
LSLB ;Move digit into MSD position
LSLB ;
LSLB ;
LSLB ;
STAB @NumBuf ;Save for later
BSR GetHexD ;Get Least Significant Digit (LSD)
BCS GetHexBX ;Exit if error
ADDB @NumBuf ;Add MSD*16 + LSD
STAB @NumBuf ;Save result
ADDB @Checksum ;Add value to checksum
STAB @Checksum ;
LDAB @NumBuf ;Recover converted value
CLC ;No errors
GetHexBX RTS ;Exit
;---------------------------------------
FUnlock$ BRA FUnlock ;Help for FUNLOCK call
FSector$ BRA FSector ;Help for FSECTOR call
;---------------------------------------
;-------------------------------------------------------------------------------
; S-record read & programming routine
;
; S-record format reference:
;
; S10898184D61726BBC <CR>
; ^^^-^---^-------^- ^---
; ||| | | | |____ End-of-line character, usually $0D.
; ||| | | |_______ 1's compliment 8-bit checksum (modulo 2^8)
; ||| | | Checksum based on 8-bit integer value of all
; ||| | | 2-char pairs, NOT including "S" and rectype.
; ||| | |_______________ Data field: (length-3) 2-char ASCII HEX pairs
; ||| |___________________ Address field: base location to write data.
; |||_____________________ Length field: # of 2-char pairs including
; || address field & checksum but not "S" lead-in
; || or record type.
; ||______________________ Record type: 0=Header, 1=Data, 9=End.
; |_______________________ Lead-in character, uppercase "S" = $53
Program LDAA #PromptChr ;Transmit prompt character
Program1 BSR CharOut ;
CLR Checksum ;Reset checksum counter
; Wait for starting "S"
Program2 BSR GetHexD ;Get character (this does UC conversion)
CMPA #SRecLead ;S-record lead-in ?
BEQ Program3 ; Yes, get record type
CMPA #ESC ;Escape ?
BNE Program2 ; No, resume scan for leading "S"
BRA Main$ ;Abort: Restart everything
; Get record type
Program3 BSR GetHexD ;Get record type code
BCS ProgramE ;Abort if error
STAB @RecType ;Save record type
; Get record length field
;
; Note: Record length specified in a S-record includes the 2 bytes
; for address plus 1 byte for checksum. A "null" S-record (no data
; field) will have a specified length of 03. The read and program
; loops expect length to be expressed in terms of the size of the data
; field only, plus 1. Subtracting 2 from the length specified in the
; S-record will provide the proper length count for the read & program
; routines.
BSR GetHexB ;Get record length
BCS ProgramE ;Abort if error
SUBB #2 ;Subtract 2 bytes for address
BLS ProgramE ;Error if record length <= 0
STAB @Length ;Save record length
; Get address field
BSR GetHexB ;Get address MSB
BCS ProgramE ;Abort if error
STAB @Address ;Save address MSB
BSR GetHexB ;Get address LSB
BCS ProgramE ;Abort if error
STAB @Address+1 ;Save address LSB
; Get data field, save in buffer
LDX #SBuffer ;Reset save pointer
LDY @Length ;Save length count in X
Program4 DEC Length ;Decrement length counter
BEQ Program5 ;If Length = 0, data field read complete
BSR GetHexB ;Get data byte
BCS ProgramE ;Abort if error
STAB 0,X ;Save in buffer
INX ;Point to next location
BRA Program4 ;Get next data byte
; Get & verify checksum field
Program5 STY @Length ;Restore length count
Program6 BSR GetHexB ;Get checksum
BCS ProgramE ;Abort if error
LDAA @Checksum ;Get checksum accumulation
COMA ;Should be $FF, inversion should set Z
BEQ ProgramF ;If valid, program FLASH with data
; Bad record - send error prompt & restart
ProgramE LDAA #BadRecChr ;Transmit "bad record" character
Program1$ BRA Program1 ;Restart S-record loader
; Set-up for FLASH programming operation
ProgramF LDAA @RecType ;Get S-record type code
CMPA #1 ;Type 1 data record ?
BNE Program ; No, ignore it
LDD @Offset ;Get user-specified offset
ADDD @Address ;Add to S-record addr, ignore overflow
XGDX ;X <- Programming base address
LDY #SBuffer ;Y <- S-record data base address
; Program/verify FLASH with S-record data
;
; Programming algorithm for a Am29F010 FLASH device:
;
; 1. Write unlock sequence:
; Value <FUnlkV1> written to address <FUnlkA1>
; Value <FUnlkV2> written to address <FUnlkA2>
; These writes must occur with FA15=FA16=0
; 2. Write "program byte" command:
; Value <FCmdPgm> written to address <FCmdA>
; 3. Write desired value to desired address
; (<FSector> routine used to set address bits FA15 & FA16 properly)
; 4. Wait for delay/verification - see below
ProgramF1 DEC Length ;Decrement length counter
BEQ Program ;Done w/record if length count at 0
BSR FUnlock$ ;Send unlock sequence
LDAA #FCmdPgm ;Send program command
STAA FOffset+FCmdA ;
LDAA @Sector ;Set sector address (A15 & A16)
BSR FSector$ ;
LDAA 0,Y ;Get S-record data
STAA 0,X ;Write to FLASH
TAB ;Copy byte written to B
; FLASH programming delay/verification procedure:
;
; 1. Read value from address just programmed
; 2. IF bit 7 of value read = bit 7 of value programmed THEN
; Programming complete, value written properly
; 3. IF bit 5 of value read = 0 THEN
; Write not complete, repeat starting at step 1
; 4. IF bit 7 of value read = bit 7 of value programmed THEN
; Programming complete, value written properly
; 5. Value not written properly (verify error) if read bit 5 = 1
; (indicating write cycle complete) and bit 7 read/data mismatch.
;
; This procedure is identical to the recommended procedure for data
; write verification as published in the Am29F010 data sheet.
ProgramF2 TBA ;Get S-record data
ANDA #$80 ;Mask all except bit 7
EORA 0,X ;DATA bit 7 = FLASH bit 7 ?
BPL ProgramF3 ; Yes, byte written OK
BITA #$20 ;FLASH bit 5 = 0 ?
BEQ ProgramF2 ; Yes, write not complete
EORB 0,X ;Bit 7 data = Bit 7 FLASH ?
BMI ProgramF4 ; No, write error
ProgramF3 INX ;Point to next FLASH address
INY ;Point to next S-record byte
BRA ProgramF1 ;Resume programming
; FLASH programming error
ProgramF4 LDAA #PgmErrChr ;Transmit programming error character
BRA Program1$ ;Resume S-record scan
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -