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

📄 smc_dtc_format256.fsm

📁 HID-Ukey底层源码实现(st72651芯片) windows上层驱动
💻 FSM
字号:
;===================================================================
;			SMART MEDIA CARD
;===================================================================

;---------------
; smc_dtc_format
;---------------

; Check spare area
;	call send_cmd_address with CMD 0x50 & 0x00
;	call init_read_spare without any param
;		on error, goto next cluster
; Erase the cluster
;	call send_cmd_address with CMD 0x60 & 0xD0
;	call read_status without any param
;		on error, mark this cluster as bad and goto next cluster
; Write all 0's to the cluster
;	call send_cmd_00 without any param
;	call write_zero_to_all_pages with CMD 0x80 & 0x10
; Read all 0's
;	call send_cmd_address with CMD 0x00 & 0x40
;		on error, mark this cluster as bad and goto next cluster
;	call read_check_cluster without any param
;		on error, mark this cluster as bad and goto next cluster
; Erase the cluster
;	call send_cmd_address with CMD 0x60 & 0xD0
;	call read_status without any param
;		on error, mark this cluster as bad and goto next cluster

;for 256MB
;------------

:clear_cluster_pages
;-------------------

      LD	MSB 14
      LD	LSB 3
      LD	ADR_BUFFER00	; buffer pointer 0 = 0x00E3
      LD	A DATA_BUFFER0
      CLC
      ADDER8	X		; increase the page address
      LD	DATA_BUFFER0	; and save it

      LD	MSB 15
      LD	LSB 15
      LD	ADR_BUFFER00
      LD	A DATA_BUFFER0
      CLC
      SUB8	X
      LD	DATA_BUFFER0
      CP	A=>X		; check the page counter
      JP :chk_cmd

:time_to_go_home
;--------------- On this point:

      STATUS	STOP

:chk_cmd
;--------
      LD	A CMP10
      EXCHANGE			;write 2nd cmd is 0x10 and read 2nd cmd is 0x30
      BCLR2
      JP :save_page_counter

;     LD	MSB 10
;     LD	LSB 10		;branch to next read page operation
;     BRANCH :loop_read_all_pages
      JP :time_to_go_home


;entry point for read spare area and read all zeros
;---------------------------------------------------
      LD	MSB 0		;<<entry point for read and check spare
;      CP	ALWAYS
      JP :load_cmd_read_spare1

;      LD	MSB 15		;<<entry point for write
;      LD	LSB 15
;      LD	ADR_BUFFER00
;      LD	A DATA_BUFFER0	;commented because CMP00 is used below

:save_page_counter
;------------------
;      LD	CMP00
      LD	MSB 8
      LD	LSB 0
      LD	CMP11
      LD	MSB 1
      CP	ALWAYS
      JP :load_cmd_2

:load_cmd_read_spare1
      LD	LSB 0
      LD	CMP11
      LD	MSB 3
;      CP	ALWAYS		;commented for 2.1 version
      JP :load_cmd_2

      LD	MSB 6		; <<entry point for erase
      LD	LSB 0
      LD	CMP11
      LD	MSB 13

:load_cmd_2
      LD	CMP10

:send_address
      LD	MSB 0
      LD	ADR_BUFFER01	; clear the high byte of the pointer 0
      LD	LSB 1
      LD	X		; X = 1
      LD	MSB 14
      LD	LSB 6
      LD	ADR_BUFFER00	; buffer pointer 0 = 0x00E6

:save_addr_bytes
;-----------------
      LD	A DATA_BUFFER0
      SUB16	ADR_BUFFER0
      LD	Y		; Load number of addres bytes
      DECY

      LD	MSB 1		;data_flash port = output
      LD	LSB 9		;DATA_FLASH Port driven by FCI  
      LD	CTRL_FCI	;PARALLEL Port driven by FCI

      LD	A CMP11		; get the 1st command

:send_cmd
;---------
      LD	DATA_FLASH	; output the command

      LD	MSB 0
      LD	LSB 10
      LD	DR_PARALLEL	; WE = 1, CLE = 0
      LD	LSB 11
      LD	DR_PARALLEL	; WE = 1, CLE = 1
      LD	LSB 9
      LD	DR_PARALLEL	; WE = 0, CLE = 1
      LD	LSB 11
      LD	DR_PARALLEL	; WE = 1, CLE = 1
      LD	LSB 10
      LD	DR_PARALLEL	; WE = 1, CLE = 0

;      INCY
;      LD A Y
;      CP A=>X
;      JP :latch_address

;      CP ALWAYS
;      JP :end_of_second_cmd

:latch_address
;; Send two byte less if this is an erase operation
;      DECY			;added for 2 cmd send
      LD	A CMP10
      EXCHANGE
      BCLR4
      JP :Prepare_Send_Address_Bytes
      DECY			;added for 256mb
      DECY
:Prepare_Send_Address_Bytes
      LD	LSB 14
      LD	DR_PARALLEL	; WE = 1, ALE = 1
:Send_Address_Bytes
;------------------
      LD	A DATA_BUFFER0
      SUB16	ADR_BUFFER0
      LD	DATA_FLASH	; Send the address byte
      LD	LSB 12
      LD	DR_PARALLEL	; WE = 0, ALE = 1
      LD	LSB 14
      LD	DR_PARALLEL	; WE = 1, ALE = 1
:Next_Address_Byte
;-----------------
      DECY
      JP :Send_Address_Bytes

      LD	LSB 10
      LD	DR_PARALLEL	; WE = 1, CLE = 0, ALE = 0, RD = 1
      
      LD	A CMP10		;if it is a write cmd
      EXCHANGE
      BCLR2
      JP :chk_first_cmd

:send_nxt_read_cmd
;------------------
      LD	A CMP10
      CP	ALWAYS
      JP :send_cmd2

:end_of_second_cmd
;------------------
      STATUS STOP

:chk_first_cmd
;--------------
      LD	A CMP11
      EXCHANGE
      BCLR4
      JP :end_of_second_cmd
      
:write_all_zeros
;---------------
      LD	MSB 4
      LD	LSB 0
      LD	CMP00		; CMP0 = 0x0840; CMP10 is the 2nd CMD

      LD	MSB 0
      LD	ADR_BUFFER00	; buffer pointer 0 = 0x0000
      LD	ADR_BUFFER11

      LD	LSB 8
      LD	CMP01

:loop_write_zeros
      LD	LSB 0
      LD	DATA_FLASH
      LD	LSB 8
      LD	DR_PARALLEL	; WE = 0
      LD	LSB 10
      LD	DR_PARALLEL	; WE = 1
      ADDER16	ADR_BUFFER0
      CP	ADR_BUFFER0<CMP0
      JP :loop_write_zeros

;      SUB16 ADR_BUFFER0
;      LD ADR_BUFFER00		;point to 0xe0
      
;      LD A DATA_BUFFER0
;      LD DATA_BUFFER0
;      LD CMP00
     
:send_write_erase_cmd
      LD	A CMP10		; get the 2nd CMD
				;<<entry for erase second
:send_cmd2
;-----------
;      LD Y			;save to chk the cmd
      LD	DATA_FLASH
      LD	MSB 0
      LD	LSB 11
      LD	DR_PARALLEL	; WE = 1, CLE = 1
      LD	LSB 9
      LD	DR_PARALLEL	; WE = 0, CLE = 1
      LD	LSB 11
      LD	DR_PARALLEL	; WE = 1, CLE = 1
      LD	LSB 10
      LD	DR_PARALLEL	; WE = 1, CLE = 0

      LD A CMP10
      EXCHANGE
      BSET2			;if it was the 2nd read cmd,then stop
      JP :status_stop

      LD	A Y 
      EXCHANGE
      BCLR4
      JP :end_of_cmd

:wait_write_erase_busy
;---------------------
      LD	A DR_PARALLEL
      EXCHANGE
      BCLR1
      JP :wait_write_erase_busy

      LD	MSB 7
      LD	LSB 0
      LD	Y
;      CP	ALWAYS
      JP :send_cmd2

:end_of_cmd
;------------
      LD	MSB 0		;data_flash port = input
      LD	LSB 9		;DATA_FLASH Port driven by FCI  
      LD	CTRL_FCI	;PARALLEL Port driven by FCI

      LD	LSB 2
      LD	DR_PARALLEL
      LD	LSB 10
      LD	DR_PARALLEL
      LD	A DATA_FLASH	; read the status
      BCLR1			; check the status bit,changed
      JP :erase_write_pass

:cluster_read_write_error
;------------------------
;      NOP
      STATUS	STOP ERROR

:erase_write_pass
;---------------- 
      LD	A CMP10
      EXCHANGE
      BCLR4			;if erase cmd then 2nd cmd is 0xd0
      LD	A ADR_BUFFER11	; ADR_BUFFER11 = 0x00
      BRANCH	:clear_cluster_pages

:status_stop
;--------------
      STATUS STOP

;:cluster_read_write_error
;------------------------
;      NOP
;      STATUS	STOP ERROR

;:erase_write_pass
;---------------- 
;      LD	A CMP10
;      EXCHANGE
;      BCLR4			;if erase cmd then 2nd cmd is 0xd0
;      LD	A ADR_BUFFER01	; ADR_BUFFER01 = 0x00
;      BRANCH	:clear_cluster_pages

;:status_stop
;--------------
;      STATUS STOP

;--------------------------------------------------------
;	START ADDRESS FOR read and check all 0's
;--------------------------------------------------------
:read_check_cluster
;------------------
      LD	MSB 0		;data_flash port = input
      LD	LSB 9		;DATA_FLASH Port driven by FCI  
      LD	CTRL_FCI	;PARALLEL Port driven by FCI
      LD	LSB 2
      LD	CMP11
      LD	LSB 8
      LD	CMP01
      LD	MSB 4
      LD	LSB 0		;CMP1 = 0x840
      LD	CMP00

;      LD	MSB 15
;      LD	LSB 15
;      LD	ADR_BUFFER00

;      LD	DATA_BUFFER0
;      LD	Y
;      DECY

:loop_read_all_pages
;-------------------
      LD	A ADR_BUFFER01
      LD	ADR_BUFFER00
      LD	ADR_BUFFER11	; ADR0 = 0x0000

:wait_read_page
      LD	A DR_PARALLEL
      EXCHANGE
      BCLR1
      JP :wait_read_page

:loop_read_page
;--------------
      LD	A CMP11
      LD	DR_PARALLEL	; RD = 0
      LD	LSB 10
      LD	DR_PARALLEL	; RD = 1
      LD	A DATA_FLASH
      CP	A=>X
      JP :cluster_read_write_error
      ADDER16	ADR_BUFFER0
      CP	ADR_BUFFER0<CMP0
      JP :loop_read_page
;      DECY
;      CP	ALWAYS
      LD	A ADR_BUFFER11	;to be changed
      BRANCH :clear_cluster_pages

;:stop_or_error
;-------------
;      STATUS STOP

;---------------------------------------------------------------
;		START ADDRESS FOR read_spare & check_spare
; redundant area is read to address of 1F0-1FF
;------------------------------------------------------------------------------------------------
; 1F0 | 1F1 | 1F2 | 1F3 | 1F4 | 1F5 | 1F6 | 1F7 | 1F8 | 1F9 | 1FA | 1FB | 1FC | 1FD | 1FE | 1FF |
;    Reserved Field     | DAT | BLK |  Address1 |   ECC Field-2   |  Address2 |   ECC Field-1   |
;------------------------------------------------------------------------------------------------
:init_read_spare
;---------------
      LD	MSB 15
      LD	LSB 0
      LD	Y		; Y = 0xF0
      LD	MSB 2
      LD	BUFFER_MNGT	; segment offset = 1, going to use <Y> for reading spare area
      EXCHANGE
      LD	CMP00		; CMP00 = 0x02, used for toggling bit for reading

;      LD	MSB 0		; data_flash port = intput   
      LD	LSB 9		; DATA_FLASH Port driven by FCI 
      LD	CTRL_FCI	; PARALLEL Port driven by FCI 

:test_busy_line
;--------------
      LD	A DR_PARALLEL
      EXCHANGE
      BCLR1
      JP :test_busy_line

; read_spare
;-----------
:read_spare
      LD	A CMP00
      LD	DR_PARALLEL	; RD = 0
      LD	LSB 10
      LD	DR_PARALLEL	; RD = 1

      LD	A DATA_FLASH	; load DATA_FLASH
      LD	<Y>
      INCY
      JP :read_spare

;------------------------------------------
; check Block_Status has no more than one 0
;------------------------------------------
      LD	A ADR_BUFFER01
      LD	CMP01
      LD	A X
      LD	ADR_BUFFER11
      LD	CMP00		; CMP0 = 0x0001
      LD	LSB 8		; Y = 0x08; points to a pattern array as following
      LD	Y		; { ~0x00, ~0x01, ~0x02, ~0x04, ~0x08, ~0x10, ~0x20, ~0x40, ~0x80 }
      LD	MSB 15
      LD	LSB 5
      LD	ADR_BUFFER10	; pointer 1 = 0x01F5, points to Block_Status of the redundant area

:check_Block_Status
;------------------
      LD	A DATA_BUFFER1
      LD	X
      LD	A <Y>
      CP	A<X
      JP :check_Block_Status_next
      LD	X
      LD	A DATA_BUFFER1
      CP	A=>X			; we found one match on the array
      JP :good_Block_Status
:check_Block_Status_next
;-----------------------
      DECY
      JP :check_Block_Status

:cluster_error
;-------------
      STATUS	STOP ERROR

:good_Block_Status
;-----------------
      LD	A ADR_BUFFER11
      LD	X		; X = 1
      ADDER16	ADR_BUFFER1	; buffer pointer 1 = 0x01F6
      LD	A DATA_BUFFER1	; high byte of Address1
      LD	ADR_BUFFER01
      ADDER16	ADR_BUFFER1
      LD	A DATA_BUFFER1
      LD	ADR_BUFFER00	; ADR_BUFFER0 = Address1-Field
      CP	ADR_BUFFER0<CMP0; check with 0x0001, it may be a CIS
				; if it is a CIS, claim it as error and return
      JP :cluster_error
      LD	MSB 15
      LD	LSB 11
      LD	ADR_BUFFER10	; skip the ECC Field-2

      LD	A DATA_BUFFER1
      LD	CMP01
      ADDER16	ADR_BUFFER1
      LD	A DATA_BUFFER1
      LD	CMP00		; CMP0 = Address2-Field
      CP	ADR_BUFFER0<CMP0
      JP :cluster_error
      SUB16	ADR_BUFFER0
      CP	ADR_BUFFER0=>CMP0
      JP :cluster_error

      STATUS	STOP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -