📄 smc_dtc_mapzone.fsm
字号:
;===================================================================
;
; SMART MEDIA CARD
;
;===================================================================
;----------------
; SMC_DTC_MapZone
;----------------
:init_command_address
;------------------------------------------------------------------------
; START ADDRESS FOR make the map zone
; INPUT:
; 0xE2-0xE5 is the address of the 1st cluster to be scanned
; 0xE6: = 3 for 3 bytes address; = 4 for 4 bytes address
; 0xD0-0xD1 is the start address of the lookup table
; 0xD2-0xD3 is the end address of the loopup table
;------------------------------------------------------------------------
LD MSB 0
LD LSB 15
LD DDR_PARALLEL
LD OR_PARALLEL
LD MSB 15
LD MASK
XOR
LD BUFFER_MNGT ; Clear segment offset
LD ADR_BUFFER01
LD ADR_BUFFER10
LD CMP10
LD LSB 1
LD ADR_BUFFER11 ; buffer pointer 1 = 0x0100
LD LSB 5
LD CMP11 ; CMP1 = 0x0500
;-------------------------
; Output the command 0x50
;-------------------------
:start_read_spare_area
LD MSB 1 ;data_flash port = output
LD LSB 9 ;DATA_FLASH Port driven by FCI
LD CTRL_FCI ;PARALLEL Port driven by FCI
:pre_wait_card_ready
;---------------
LD A DR_PARALLEL
EXCHANGE
BCLR1 ; test busy line
JP :pre_wait_card_ready
LD MSB 5
LD LSB 0
LD DATA_FLASH ; command Read(3)
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
;------------------------------------
; Output the 3 or 4 bytes of address
;------------------------------------
LD MSB 0
LD LSB 1
LD X ; X = 1
LD MSB 14
LD LSB 6
LD ADR_BUFFER00 ; buffer pointer 0 = 0x00E6
LD A DATA_BUFFER0 ; load the number of address bytes
LD Y
DECY
LD A ADR_BUFFER01 ; A = 0
:loop_send_address
;-----------------
SUB16 ADR_BUFFER0 ; send address from high byte to low byte
LD DATA_FLASH
LD MSB 0
LD LSB 14
LD DR_PARALLEL ; ALE = 1, WE = 1
LD LSB 12
LD DR_PARALLEL ; ALE = 1, WE = 0
LD LSB 14
LD DR_PARALLEL ; ALE = 1, WE = 1
LD A DATA_BUFFER0
DECY
JP :loop_send_address
LD MSB 0
LD LSB 10
LD DR_PARALLEL ; ALE = 0, WE = 1
;LD MSB 0 ; data_flash port = intput
LD LSB 9 ; DATA_FLASH Port driven by FCI
LD CTRL_FCI ; PARALLEL Port driven by FCI
;---------------------
; Read the spare area
;---------------------
:init_read_spare
LD LSB 2
LD CMP00 ; CMP00 = 0x02 for toggling RD line
LD LSB 15
LD Y ; Y = 15
LD MSB 14
LD LSB 07
LD ADR_BUFFER00 ; ADR0 = 0x00E7, points to spare area
LD CMP01 ; save this address for later use
:wait_card_ready
;---------------
LD A DR_PARALLEL
EXCHANGE
BCLR1 ; test busy line
JP :wait_card_ready
; 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 DATA_BUFFER0
ADDER16 ADR_BUFFER0
DECY
JP :read_spare
;-------------------------------
; Check the spare area is valid
;-------------------------------
LD A CMP01
LD Y ; Y = 0x00E7, points to spare area
LD A <Y> ; load 1st byte of reserved area
XOR
CP A=>X ; X = 1
JP :spare_area_check_FF
INCY
LD A <Y> ; load 2nd byte of reserved area
XOR
CP A=>X
JP :spare_area_check_FF
INCY
LD A <Y> ; load 3rd byte of reserved area
XOR
CP A=>X
JP :spare_area_check_FF
INCY
LD A <Y> ; load 4th byte of reserved area
XOR
CP A=>X
JP :spare_area_check_FF
INCY
LD A <Y> ; load data status byte
XOR
CP A=>X
JP :spare_area_check_FF
INCY
LD A <Y> ; load block status byte
INCY
XOR
:spare_area_check_FF
;-----------------
SEC
CP A=>X
JP :spare_area_address_error
LD A <Y> ; load high byte of block address 1
LD ADR_BUFFER01
INCY
LD A <Y> ; load low byte of block address 1
LD ADR_BUFFER00
LD X ; X = low byte of block address 1
INCY
INCY ; skip 1st byte of ECC2
INCY ; skip 2nd byte of ECC2
INCY ; skip 3rd byte of ECC2
LD A <Y> ; load high byte of block address 2
LD CMP01
INCY
LD A <Y> ; load low byte of block address 2
LD CMP00
CP ADR_BUFFER0<CMP0
JP :spare_area_error
CLC
SUB8 X ; CMP00 - ADR_BUFFER00
CP CARRY
JP :spare_area_error
LD A ADR_BUFFER01
LD X
LD A CMP01
SUB8 X
:spare_area_address_error
;------------------------
CP CARRY
JP :spare_area_error
;---------------------
; check the parity bit
;---------------------
SEC
LD A ADR_BUFFER00
XOR
LD A ADR_BUFFER01
XOR
CP CARRY
JP :got_a_good_address
:spare_area_error
;----------------
LD MSB 0
LD LSB 1
LD X ; X = 1
EXCHANGE ; A = 0x10
LD DATA_BUFFER1
ADDER16 ADR_BUFFER1
LD MSB 0
LD DATA_BUFFER1 ; save as 0x1000, this is an invalid cluster
ADDER16 ADR_BUFFER1
CP ALWAYS
JP :increase_cluster_address
:got_logical_address
;-------------------
LD A ADR_BUFFER01 ; high byte of the address
EXCHANGE
BCLR1 ; bit12 of the address must be 1
JP :spare_area_error
EXCHANGE
CP ALWAYS
JP :save_logical_address
:got_a_good_address
;------------------
LD MSB 0
LD LSB 1
LD X ; X = 0x01
LD A ADR_BUFFER00
XOR
CP A=>X
JP :got_logical_address
LD A ADR_BUFFER01
XOR
CP A=>X
JP :got_logical_address
:got_free_cluster
;----------------
;*LD MSB 14
;*LD LSB 7 ; A = 0xE7, will be 0x73 after shift right
LD A MASK
:save_logical_address
;--------------------
LD DATA_BUFFER1 ; save the high byte of the address
ADDER16 ADR_BUFFER1
LD A ADR_BUFFER00
BCLR1 ; clear the parity bit
LD DATA_BUFFER1 ; save the low byte of the address
ADDER16 ADR_BUFFER1
:increase_cluster_address
;------------------------
LD A MASK
LD ADR_BUFFER00
XOR
LD ADR_BUFFER01 ; ADR0 = 0x00FF, points to cluster size
LD A DATA_BUFFER0
LD X ; X = the size of the cluster
CLC
LD MSB 14
LD LSB 5
LD Y ; Y = 0xE5, points to the cluster address
LD A <Y>
ADDER8 X
LD <Y> ; byte 0 of the address
DECY ; Y = 0xE4
LD A ADR_BUFFER01
LD X ; clear X
LD A <Y>
ADDER8 X ; byte 1 of the address
LD <Y>
DECY ; Y = 0xE3
LD A <Y>
ADDER8 X
LD <Y> ; byte 2 of the address
:check_next_cluster
;------------------
LD MSB 0
LD LSB 15
CP ADR_BUFFER1<CMP1
BRANCH :start_read_spare_area
:no_more_clusters
NOP
NOP
NOP
STATUS STOP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -