📄 smc_dtc_debug.fsm
字号:
;===================================================================
;
; SMART MEDIA CARD
;
;===================================================================
;------------
; smc_dtc_up
;------------
;------------------------------------------------------------------
; START ADDRESS FOR read data to USB
; ST7: Give a 3 or 4 bytes address, number of pages
; 0x1632 - 0x1635 = The address, big endien (0x00E2-0x00E5)
; 0x163F = Number of pages (counter), it should be 0 on exit
; On return: Counter = 0 means no error
; Counter !=0 means ECC error on that page
;------------------------------------------------------------------
:init_command_address
; 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 MSB 0
LD LSB 15
LD DDR_PARALLEL ; PA3-0 as output, PA4 as input
LD OR_PARALLEL ; PA3=/RD, PA2=ALE, PA1=/WE, PA0=CLE
; PA4=R/B
LD MSB 15
LD MASK ; MASK = 0xFF
XOR ; A = 0
LD ADR_BUFFER01 ; clear the high byte of ADR0
; LD A ADR_BUFFER01 ; clear A as the first byte, it is always 0
;for 256mb
;----------
LD ADR_BUFFER10 ; clear low byte of ADR1
LD CMP10 ; clear low byte of CMP1
LD BUFFER_MNGT ; clear SEGment offset for using Y on ECC check
LD LSB 1
LD X ; X = 1
LD CMP11 ;flag to differentiate b/w src read or destination read
LD ADR_BUFFER11
;--------
:next_page256
;--------------
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 ADR_BUFFER01
LD MSB 0
LD LSB 0
LD ADR_BUFFER01
LD DATA_FLASH ; command Read(1), sequential read
; LD LSB 1
; LD X ; X = 1
; LD ADR_BUFFER11
;;; Output the sequential read command (0x00)
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
;--------------------------------------------------
; START ADDRESS FOR address_latch_cycle
;--------------------------------------------------
; LD A ADR_BUFFER01 ; clear A as the first byte, it is always 0,for 256mb
; LD ADR_BUFFER10 ; clear low byte of ADR1
; LD CMP10 ; clear low byte of CMP1
; LD BUFFER_MNGT ; clear SEGment offset for using Y on ECC check
:send_address
LD MSB 14
LD LSB 06
LD ADR_BUFFER00 ; buffer pointer 0 = 0x00E6
LD A DATA_BUFFER0
LD Y ; Y = number of address bytes
DECY
LD LSB 12
LD CMP01 ; CMP01 = 12, for send address toggling lines
LD LSB 14
LD DR_PARALLEL ; ALE = 1, WE = 1
; LD A ADR_BUFFER01 ; clear A as the first byte, it is always 0,for 256mb
; LD ADR_BUFFER10 ; clear low byte of ADR1
; LD CMP10 ; clear low byte of CMP1
; LD BUFFER_MNGT ; clear SEGment offset for using Y on ECC check
;for debug routine
;---------------------
;flag to differentiate between the source page read or destination page read
LD A CMP11
BSET1
JP :start_address
LD MSB 14
LD LSB 12
LD ADR_BUFFER00
:start_address
SUB16 ADR_BUFFER0 ; send address from high byte to low byte
:loop_send_address
;-----------------
; SUB16 ADR_BUFFER0 ; send address from high byte to low byte
LD A DATA_BUFFER0
LD DATA_FLASH ; Output the address bytes
LD A CMP01
LD DR_PARALLEL ; ALE = 1, WE = 0
LD LSB 14
LD DR_PARALLEL ; ALE = 1, WE = 1
SUB16 ADR_BUFFER0 ; send address from high byte to low byte
; LD A DATA_BUFFER0
DECY
JP :loop_send_address
LD MSB 0
LD LSB 10
LD DR_PARALLEL ; ALE = 0, WE = 1
;---------------------------------------------------
;For 256 MB or 2K page send 0x30 command,
;---------------------------------------------------
;send 0x30 cmd
LD MSB 3
LD LSB 0
LD DATA_FLASH
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Start to read one page
;; 1. Test the READY/BUSY line is ready
;; 2. Wait one of the buffer is free
;; 3. Read the page data
;; 4. Check the ECC
;; 5. Submit the buffer to send the page data
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:Wait_SMC_Ready
;--------------
LD A ADR_BUFFER01
LD CMP01
LD LSB 2
LD CMP00 ; CMP0 = 0x0002, will use for RD toggling
LD ADR_BUFFER00 ; buffer pointer 0 = 0x0002
;;; Reset the ECC calculation machine
; LD MSB 0 ; data_flash port = intput
LD LSB 9 ; DATA_FLASH Port driven by FCI
LD CTRL_FCI ; PARALLEL Port driven by FCI
LD MSB 2 ; ECC Mode & Reset TMP Reg
LD CTRL_FCI ; PARALLEL Port driven by FCI
:wait_ready_line
;---------------
ADDER16 ADR_BUFFER0
CP ADR_BUFFER0=>CMP0
JP :test_busy_line
; the waiting loop is timeout
STATUS STOP ERROR ; return with error
:test_busy_line
;--------------
LD A DR_PARALLEL
EXCHANGE
BCLR1
JP :wait_ready_line
:Init_Page_Reading
;----------------- ; Initialize ADR0 for read ECC
LD A ADR_BUFFER10
LD ADR_BUFFER01 ; clear high byte of pointer 0
; LD MSB 15
; LD LSB 8
; LD ADR_BUFFER00 ; ADR0 = 0x00F8, points the ECC memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Test and wait one of the buffer is full
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LD A ADR_BUFFER11
BSET2
JP :read_one_page
LD LSB 1
LD ADR_BUFFER11 ; buffer pointer 1 = 0x0100
;:wait_buffer0_full
;-----------------
; LD A BUFFER_MNGT
; BSET3
; JP :wait_buffer0_full
; JP :read_one_page
;:wait_buffer1_full
;-----------------
; LD A, BUFFER_MNGT
; BSET4
; JP :wait_buffer1_full
:read_one_page
;-------------
LD A ADR_BUFFER10
LD Y ; Clear Y
:read_256_bytes
;--------------
LD LSB 2
LD DR_PARALLEL ; RD = 0; WE = 1; ALE=CLE=0
LD LSB 10
LD DR_PARALLEL ; RD = 1; WE = 1; ALE=CLE=0
LD A DATA_FLASH ; Get the reading data byte
LD DATA_BUFFER1 ; Save it in the buffer
; LD ECC_CRC ; Load to ECC_CRC REG
; LD A ECC_CRC ; AUTO UPDATE OF Line PARITY 1
; LD A ECC_CRC ; AUTO UPDATE OF Line PARITY 2
; LD A ECC_CRC ; AUTO UPDATE OF column PARITY
ADDER16 ADR_BUFFER1
INCY
JP :read_256_bytes
LD A ADR_BUFFER11 ; The value can be 0010, 0011, 0100, 0101
BCLR1
JP :read_256_bytes
;---------------------------------------------
; Read 16 bytes of redundant area from the SMC
; They will be saved in 0xE7-0xF6
;---------------------------------------------
;:init_read_spare
LD LSB 15
LD Y ; Y = 15
LD MSB 14
LD LSB 15
LD ADR_BUFFER00 ; ADR0 = 0x00f0
; points to one byte before spare area
LD A CMP11
BSET1
JP :read_spare
LD MSB 12
LD LSB 15
LD ADR_BUFFER00 ;spare area address for second read
:read_spare
;----------
ADDER16 ADR_BUFFER0
LD LSB 2
LD DR_PARALLEL ; RD = 0; WE = 1; ALE=CLE=0
LD LSB 10
LD DR_PARALLEL ; RD = 1; WE = 1; ALE=CLE=0
LD A DATA_FLASH ; Save one byte of redundant area
LD DATA_BUFFER0
DECY
JP :read_spare
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; After the ECC check is verified. Submit the buffer read
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LD A ADR_BUFFER11 ; The value is either 0011 or 0101
BSET3
JP :Set_buffer1_full
:Set_buffer0_full
;----------------
LD LSB 0
LD CMP11
CP ALWAYS
LD MSB 0
LD LSB 15
BRANCH:next_page256
:Set_buffer1_full
;----------------
LD LSB 1
:Set_Buffer_Full
;---------------
LD CMP11
; LD BUFFER_MNGT
; LD LSB 0
; LD BUFFER_MNGT
;compare the data in two buffers
;--------------------------------
LD MSB 0
LD LSB 0
LD ADR_BUFFER00
LD ADR_BUFFER10
LD LSB 1
LD ADR_BUFFER01 ;ADR0 = 0X100
LD LSB 3
LD ADR_BUFFER11 ; ADR1 = 0X300
:read_nxt_byte
LD A DATA_BUFFER0
LD MASK
LD A DATA_BUFFER1
XOR
LD Y
DECY
JP :status_not_equal
CP ALWAYS
JP :good_data
:status_not_equal
STATUS STOP ERROR
:good_data
ADDER16 ADR_BUFFER0
ADDER16 ADR_BUFFER1
LD A ADR_BUFFER11
BCLR3
JP :read_nxt_byte
;compare spare area
;----------------------
LD A ADR_BUFFER00
LD ADR_BUFFER01
LD ADR_BUFFER11
LD MSB 13
LD ADR_BUFFER00
LD MSB 15
LD ADR_BUFFER10
:chk_nxt_spare
LD A DATA_BUFFER0
LD MASK
LD A DATA_BUFFER1
XOR
LD Y
DECY
JP :status_not_equal
:good_data_spare
ADDER16 ADR_BUFFER0
ADDER16 ADR_BUFFER1
LD A ADR_BUFFER10
LD Y
INCY
JP :chk_nxt_spare
;increment the page address and decrement the page counter
;----------------------------------------------------------
LD MSB 14
LD LSB 5
LD ADR_BUFFER00 ;0xe5 = 1st col. byte destination add
LD LSB 11
LD ADR_BUFFER10 ;0XEB = 1st col byte of source add
LD MSB 1
LD LSB 0
LD Y
LD A DATA_BUFFER0
CLC
ADDER8 Y
LD DATA_BUFFER0
LD A DATA_BUFFER1
CLC
ADDER8 Y
LD DATA_BUFFER1
SUB16 ADR_BUFFER0 ;0xe4 = 2nd col byte of destination add
SUB16 ADR_BUFFER1 ;0xea = 2nd col byte of source address
LD MSB 0
LD LSB 2
LD Y
LD A DATA_BUFFER0 ;decrement 2nd col byte by 0x02
CLC
ADDER8 Y
BCLR4
LD DATA_BUFFER0
LD A DATA_BUFFER1
CLC
ADDER8 Y
BCLR4
LD DATA_BUFFER1
JP :dec_page
ADDER16 ADR_BUFFER0 ; 1st col = 0 at page change
ADDER16 ADR_BUFFER1 ; 1st col = 0 at page change
LD A ADR_BUFFER01
LD DATA_BUFFER0
LD DATA_BUFFER1
SUB16 ADR_BUFFER0
SUB16 ADR_BUFFER0 ; 0xe3 = 1st row byte
SUB16 ADR_BUFFER1
SUB16 ADR_BUFFER1 ; 0xe3 = 1st row byte
:next_page
;------------
LD A DATA_BUFFER0
CLC
ADDER8 X
LD DATA_BUFFER0
LD A DATA_BUFFER1
CLC
ADDER8 X
LD DATA_BUFFER1
;For 256mb
:dec_page
LD A ADR_BUFFER01
LD ADR_BUFFER10
LD LSB 5
LD ADR_BUFFER11 ;reload ADR1
LD MSB 14
LD LSB 0
LD Y
LD A <Y>
CLC
SUB8 X
LD <Y> ;new
CP A=>X
LD MSB 0
LD LSB 15
BRANCH :next_page256
STATUS STOP
:all_pages_read
;--------------
; ** LD A BUFFER_MNGT ; wait for 2 buffers are free
; ** BSET3
; ** JP :all_pages_read
; ** BSET4
; ** JP :all_pages_read
; STATUS STOP ; FINISH SUCCESSFULLY!
;------------------------------------------------------------------
; START ADDRESS FOR read data FF to USB
; ST7: Give number of pages
; 0x163F = Number of pages (counter), it should be 0 on exit
; On return: Counter = 0 means no error
; Counter !=0 means ECC error on that page
;------------------------------------------------------------------
; LD MSB 0
; LD LSB 0
; LD ADR_BUFFER10 ; low byte of pointer 1
; LD ADR_BUFFER01 ; high byte of pointer 0
; LD CMP10
; LD LSB 1
; LD ADR_BUFFER11 ; ADR1 = 0x0100
; LD X ; X = 1
; LD LSB 5
; LD CMP11 ; CMP1 = 0x0500
; LD MSB 15
; LD LSB 15
; LD ADR_BUFFER00 ; ADR00 = 0x00FF
;:fill_buffer_with_FF
; LD DATA_BUFFER1
; ADDER16 ADR_BUFFER1
; CP ADR_BUFFER1<CMP1
; JP :fill_buffer_with_FF
; LD A DATA_BUFFER0
; LD Y ; load the page counter
;:FFsend_2_pages
;--------------
; DECY
; JP :FFwait_for_buffer_0
; JP :FF_finish
;:FFwait_for_buffer_0
;-----------------
; LD A BUFFER_MNGT
; BSET3
; JP :FFwait_for_buffer_0
; LD LSB 1
; LD BUFFER_MNGT ; mark buffer0 full
; LD LSB 0
; LD BUFFER_MNGT ; mark buffer0 full
; DECY
; JP :FFwait_for_buffer_1
;:FF_finish
; INCY
; LD A Y
; LD DATA_BUFFER0 ; clear the page counter
; STATUS STOP
;:FFwait_for_buffer_1
;-----------------
; LD A BUFFER_MNGT
; BSET4
; JP :FFwait_for_buffer_1
; LD LSB 2
; LD BUFFER_MNGT ; mark buffer1 full
; LD LSB 0
; LD BUFFER_MNGT ; mark buffer1 full
; JP :FFsend_2_pages
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -