⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.a11

📁 该应用软件可以实现大多数单片机的仿真实验
💻 A11
📖 第 1 页 / 共 2 页
字号:
	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 + -