📄 smc_dtc_format256.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 + -