URL
https://opencores.org/ocsvn/ffr16/ffr16/trunk
Subversion Repositories ffr16
[/] [ffr16/] [branches/] [APERT/] [sources/] [hau/] [240603KN/] [cfreader.psm] - Rev 5
Go to most recent revision | Compare with Previous | Blame | View Log
;--===========================================================================--
;--
;-- CF SECTOR READER
;--
;-- - SEPTEMBER 2002
;-- - APERT - UPV / EHU. - BASQUE COUNTRY UNIVERSITY
;-- - DISTRIBUTED UNDER GPL LICENSE
;--
;-- Design units : FAT FILE LOADER
;--
;-- File name : cfreader.psm
;--
;-- Purpose : READ RAW SECTORS FROM CF
;--
;-- Library : -
;--
;-- Languaje : ASSEMBLER FOR XILINX PICOBLAZE
;--
;-- Compiler : KCPSM ASSEMBLER V1.10
;--
;-- Debugger : PSM DEBUG V1.00
;--===========================================================================--
;-------------------------------------------------------------------------------
;-- Revision list
;-- Version Author Date Changes
;--
;-- 260902 Armando Astarloa 27 September 2002 -
;-- 241002 Armando Astarloa 27 October 2002 Reset on error
;-- 031202 Armando Astarloa 27 December 2002 Load LBA information from data bus
;-- 120103 Armando Astarloa 12 January 2003 Quit status check when words reading
;-- 290103 Armando Astarloa 29 January 2003 Reset function. Reset after error
;-- 050503 Armando Astarloa 02 May 2003 Allow not all bytes of the sector read.
;-- do_reset_and_retry state
;-- 160503 Armando Astarloa 15 May 2003 Complete sector reading
;-- 170603 Armando Astarloa 17 June 2003 Bug in words per sector read
;-- 230603 Armando Astarloa 24 June 2003 Quit soft reset (KCPSM v.1002 has reset)
;--
;-------------------------------------------------------------------------------
;-- Description : DUMMY CF SECTORS READ
;-------------------------------------------------------------------------------
;--
;-- CONSTANT DEFINITIONS
;--
CONSTANT DELAY1,03
; 50 MHZ DELAY1 => T(clk_i) => fastloop=DELAY1*T*2= 120ns sF=1 => delay= sF*fastloop
; 50 MHZ DELAY1=03 => T=20NS => fastloop=3*20*2= 120ns sF=1 => delay= 120ns
CONSTANT IDENTIFY_COMMAND,EC
CONSTANT WRITE_SECTOR_COMMAND,30
CONSTANT READ_SECTOR_COMMAND,20
CONSTANT WRITE_SEC_FEATURE,00
CONSTANT SOFT_RESET,04
;--
;-- RAM REGISTERS
;--
;
; s0
; s1
; s2
; s3 -> WISHBONE CONTROL
; s4 -> REGISTERS STACK
; s5 -> MY_STATUS
; D3 = ERROR
; D2 = DATA TRANSFER ALLOWED (0 NOT / 1 YES)
; D1 = COMMAND ALLOWED (NOT BUSY) (0 NOT / 1 YES)
; D0 = SECTOR AVAILABLE (0 NOT / 1 YES)
CONSTANT SECTOR_AVAILABLE,01
CONSTANT COMMAND_ALLOWED,02
CONSTANT DATA_TRANSFER_ALLOWED,04
CONSTANT ERROR_MY_STATUS,08
; s6 -> WORDS_READ
; s7 -> LBA_7_0
; s8 -> LBA_15_8
; s9 -> LBA_23_16
; sA -> LD_LBA_27_24
; sB -> data[7:0] in ide
; sC -> data[15:8] in ide
; sD -> data[7:0] out ide
; sE -> data[15:8] out ide
; sF -> acummulator
;
;--
;-- OUTPUT PORTS
;--
;--
;-- IDE INTERFACE PORTS - OUTPUTS
;--
CONSTANT DATA_IDE_OUT_7_0,00
CONSTANT DATA_IDE_OUT_15_8,01
CONSTANT IDE_CONTROL_OUT,02
; D7 =
; D6 =
; D5 =
; D4 =
; D3 =
; D2 =
; D1 = NIOWR
; D0 = NIORD
CONSTANT NIOWR,FD
CONSTANT NIORD,FE
CONSTANT IDE_ADDRESS_OUT,03
; D7 =
; D6 =
; D5 =
; D4 = NCE1
; D3 = NCE0
; D2 = A2
; D1 = A1
; D0 = A0
;
; WRITE IDE REGISTERS
;
; NCE1/NCE0/ A2/ A1/ A0
CONSTANT CONTROL,0E ; 000 0 1 1 1 0
CONSTANT DATA,10 ; 000 1 0 0 0 0
CONSTANT FEATURE,11 ; 000 1 0 0 0 1
CONSTANT SECTOR_COUNT,12; 000 1 0 0 1 0
CONSTANT LBA_7_0,13 ; 000 1 0 0 1 1
CONSTANT LBA_15_8,14 ; 000 1 0 1 0 0
CONSTANT LBA_23_16,15 ; 000 1 0 1 0 1
CONSTANT LD_LBA_27_24,16; 000 1 0 1 1 0
CONSTANT COMMAND,17 ; 000 1 0 1 1 1
CONSTANT CF_OFF,18 ; 000 1 1 0 0 0
;
; READ IDE REGISTERS
; NCE1/NCE0/ A2/ A1/ A0
CONSTANT A_STATUS,0E ; 000 0 1 1 1 0
CONSTANT STATUS,17 ; 000 1 0 1 1 1
;--
;-- WISHBONE INTERFACE PORTS - OUTPUTS
;--
CONSTANT DATA_WB_OUT_7_0,04
CONSTANT DATA_WB_OUT_15_8,05
CONSTANT CONTROL_WB_OUT,06
; D7 =
; D6 =
; D5 =
; D4 =
; D3 =
; D2 =
; D1 = TAG0_WORD_AVAILABLE
; D0 = ACK_CF_READER
CONSTANT ACK_CF_READER,01
CONSTANT TAG0_WORD_AVAILABLE,02
;--
;-- BUS CONTROL SIGNALS
;--
CONSTANT CONTROL_OUT,07
; D7 =
; D6 =
; D5 =
; D4 =
; D3 =
; D2 = ERROR
; D1 = WB_BUS_WRITE_ENABLE
; D0 = IDE_BUS_WRITE_ENABLE
CONSTANT IDE_BUS_WRITE_ENABLE,01
CONSTANT WB_BUS_WRITE_ENABLE,02
CONSTANT ERROR,04
;--
;-- INPUT PORTS
;--
;--
;-- IDE INTERFACE PORTS - INPUTS
;--
CONSTANT DATA_IDE_IN_7_0,00
CONSTANT DATA_IDE_IN_15_8,01
;--
;-- WISHBONE INTERFACE PORTS - INPUTS
;--
CONSTANT CONTROL_WB_IN,02
; D7 =
; D6 =
; D5 =
; D4 = WB_A0
; D3 = -
; D2 = W_WE
; D1 = TAG1_WORD_REQUEST
; D0 = STROBE_CF_READER
;
; STROBE_CF_READER = 1 & W_WE=1 & WB_A0 = 0
CONSTANT WRITE_LBA_15_0,05
; STROBE_CF_READER = 1 & W_WE=1 & WB_A0 = 1
CONSTANT WRITE_LBA_27_16,15
CONSTANT STROBE_CF_READER_AND_RD,01
CONSTANT TAG1_WORD_REQUEST,02
CONSTANT W_WE,04
;--
;-- WISHBONE INTERFACE PORTS - INPUTS
;--
CONSTANT DATA_WB_IN_7_0,03
CONSTANT DATA_WB_IN_15_8,04
;--
;-- REGISTERS INITIALIZATION
;--
initialization:
;
; BUS CONTROL : WRITE NOT ENABLE
;
LOAD sF,00
OUTPUT sF,CONTROL_OUT
;
; WISHBONE BUS INITIALIZATION
;
LOAD sF,00
OUTPUT sF,DATA_WB_OUT_7_0
OUTPUT sF,DATA_WB_OUT_15_8
OUTPUT sF,CONTROL_WB_OUT
;
; IDE BUS INITIALIZATION
;
LOAD sF,00
OUTPUT sF,DATA_IDE_OUT_7_0
OUTPUT sF,DATA_IDE_OUT_15_8
LOAD sF,18
OUTPUT sF,IDE_ADDRESS_OUT
LOAD sF,FF
OUTPUT sF,IDE_CONTROL_OUT
;
; WAIT FOR 210NS*31 (RESET DELAY)
;
LOAD s5,00
LOAD s6,00
LOAD sF,FF
CALL wait_loop
CALL soft_reset
LOAD sF,FF
CALL wait_loop
LOAD sF,FF
CALL wait_loop
LOAD sF,FF
CALL wait_loop
main:
;
; CHECK WISHBONE BUS
;
; wait state for stb_i deassertion
;LOAD sF,01
;CALL wait_loop
AND sF,sF
AND sF,sF
AND sF,sF
AND sF,sF
INPUT s3,CONTROL_WB_IN
;
; CHECK STROBE & READ
;
LOAD sF,s3
SUB sF,WRITE_LBA_15_0
JUMP Z,store_lba_15_0
LOAD sF,s3
SUB sF,WRITE_LBA_27_16
JUMP Z,store_lba_27_16
LOAD sF,s3
SUB sF,STROBE_CF_READER_AND_RD
JUMP Z,put_data_in_wb_bus
;
; IF NOT READ REQUEST MAINTAIN SIGNAL
;
LOAD sF,00
OUTPUT sF,CONTROL_OUT
OUTPUT sF,CONTROL_WB_OUT
JUMP main
store_lba_15_0:
; DATA_WB_IN_7_0 -> s7 LBA_7_0
INPUT s7,DATA_WB_IN_7_0
; DATA_WB_IN_15_8 -> s8 LBA_15_8
INPUT s8,DATA_WB_IN_15_8
; SECTOR AVAILABLE / COMMAND AVAILABLE -> 0
LOAD sF,00
AND s5,sF
JUMP wishbone_ack
store_lba_27_16:
; DATA_WB_IN_7_0 -> s9 LBA_23_16
INPUT s9,DATA_WB_IN_7_0
; DATA_WB_IN_15_8 -> s10 LD_LBA_27_24
INPUT sA,DATA_WB_IN_15_8
; SECTOR AVAILABLE -> 0
; antes 020503 LOAD sF,FE
LOAD sF,00
AND s5,sF
JUMP wishbone_ack
do_reset_and_retry:
CALL soft_reset
LOAD s5,00
put_data_in_wb_bus:
CALL read_word_from_cf
; check for error
LOAD sF,s5
AND sF,ERROR_MY_STATUS
JUMP NZ,do_reset_and_retry
OUTPUT sB,DATA_WB_OUT_7_0
OUTPUT sC,DATA_WB_OUT_15_8
;
; ENABLE WB ENABLE
;
LOAD sF,WB_BUS_WRITE_ENABLE
OUTPUT sF,CONTROL_OUT
wishbone_ack:
;
; WISHBONE ACK
;
LOAD sF,ACK_CF_READER
OUTPUT sF,CONTROL_WB_OUT
; null - wait state
;
AND sF,sF
AND sF,sF
AND sF,sF
AND sF,sF
; WISHBONE MASTER MUST CHECK ACK SIGNAL
; IN THE RISING EDGE OF THE CLOCK AND DEASSERT
; STROBE SIGNAL. SLAVE AUTOMATICALLY DEASSERT ACK
;
LOAD sF,00
OUTPUT sF,CONTROL_WB_OUT
;OUTPUT sF,CONTROL_OUT
JUMP main
wait_loop:
;
; SOFTWARE DELAY LOOP
; TAKES SLOW LOOP VALUE FROM sF
;
; TWO CYCLES PER INSTRUCTION
;
; SLOW LOOP 3 INSTRUCTIONS * sF
; FAST LOOP 2 INSTRUCTIONS * DELAY1
; 50 MHZ DELAY1=0A => T=20NS => fl=3*20*2= 120ns sF=1 => delay= 120ns
LOAD s1,sF
slow_loop:
LOAD s0,DELAY1
fast_loop:
SUB s0,01
JUMP NZ,fast_loop
SUB s1,01
JUMP NZ,slow_loop
RETURN
write_ide_register:
;
; TAKE ADDRESS FROM SF REGISTER AND IT'S PUT INTO THE PORT
;
OUTPUT sF,IDE_ADDRESS_OUT
;
; DATA OUT IDE
;
OUTPUT sD,DATA_IDE_OUT_7_0
OUTPUT sE,DATA_IDE_OUT_15_8
;
; DATA OUT BUS ENABLE
;
LOAD sF,IDE_BUS_WRITE_ENABLE
OUTPUT sF,CONTROL_OUT
;
; WAIT FOR 70 NS (MIN)
; (120ns/50Mhz)
LOAD sF,01
CALL wait_loop
;
; WRITE STROBE ON
;
LOAD sF,NIOWR
OUTPUT sF,IDE_CONTROL_OUT
;
; WAIT FOR 165NS (MIN)
; (240ns/50Mhz)
; 020503
LOAD sF,02
CALL wait_loop
;
; WRITE STROBE OFF
;
LOAD sF,FF
OUTPUT sF,IDE_CONTROL_OUT
;
; WAIT FOR 20NS (MIN)
; (410ns/50Mhz)
; 020503
;LOAD sF,01
;CALL wait_loop
;
; CE AND ADRESSES OFF
;
LOAD sF,CF_OFF
OUTPUT sF,IDE_ADDRESS_OUT
;
; WAIT FOR 30NS (MIN) (if delay of the two previos inst>30ns this is not necessary)
; (put again 020503)
LOAD sF,01
CALL wait_loop
;
; DATA OUT BUS DISABLE
;
LOAD sF,00
OUTPUT sF,CONTROL_OUT
;
; (put again 020503)
LOAD sF,02
CALL wait_loop
RETURN
read_ide_register:
;
; TAKE ADDRESS FROM SF REGISTER AND IT'S PUT INTO THE PORT
;
OUTPUT sF,IDE_ADDRESS_OUT
;
; WAIT FOR 70 NS (MIN)
;
LOAD sF,01
CALL wait_loop
;
; READ STROBE ON
; reset control_out (140503)
LOAD sF,00
OUTPUT sF,CONTROL_OUT
LOAD sF,NIORD
OUTPUT sF,IDE_CONTROL_OUT
;
; WAIT FOR 165NS (MIN)
;
LOAD sF,02
CALL wait_loop
;
; TAKE DE DATA FROM IDE BUS
;
INPUT sB,DATA_IDE_IN_7_0
INPUT sC,DATA_IDE_IN_15_8
;
; READ STROBE OFF
;
LOAD sF,FF
OUTPUT sF,IDE_CONTROL_OUT
;
; WAIT FOR 20NS (MIN)
;
;LOAD sF,01
;CALL wait_loop
;
; CE AND ADRESSES OFF
;
LOAD sF,CF_OFF
OUTPUT sF,IDE_ADDRESS_OUT
;
; WAIT FOR 20NS (MIN)
; (120ns/50mhz)
;LOAD sF,01
;CALL wait_loop
RETURN
read_sector:
;
; WRITE ATA COMMANDS TO THE CF
;
;
; IDE FEATURE REGISTER
;
LOAD sD,WRITE_SEC_FEATURE
LOAD sF,FEATURE
CALL write_ide_register
;
; IDE SECTOR COUNT REGISTER
;
LOAD sD,01
LOAD sF,SECTOR_COUNT
CALL write_ide_register
;
; IDE LBA_7_0
;
LOAD sD,s7
LOAD sF,LBA_7_0
CALL write_ide_register
;
; IDE LBA_15_8
;
LOAD sD,s8
LOAD sF,LBA_15_8
CALL write_ide_register
;
; IDE LBA_23_16
;
LOAD sD,s9
LOAD sF,LBA_23_16
CALL write_ide_register
;
; IDE LD_LBA_27_24
;
; LBA_27_42 OR WITH 1110
; BIT7 : 1
; BIT6 : LBA=1
; BIT5 : 1
; BIT4 : DRV=0
;
;
LOAD sF,sA
OR sF,E0
LOAD sD,sF
LOAD sF,LD_LBA_27_24
CALL write_ide_register
;
; IDE READ SECTOR COMMAND
;
LOAD sD,READ_SECTOR_COMMAND
LOAD sF,COMMAND
CALL write_ide_register
;
; PUT SECTOR ALLOWED FLAG INTO MY_STATUS
;
; 290103 Added data available check
retry_status_check:
CALL cf_status_check
LOAD sF,s5
AND sF,ERROR_MY_STATUS
RETURN NZ
LOAD sF,DATA_TRANSFER_ALLOWED
AND sF,s5
; LOOPS UNTIL SECTOR DATA IS AVAILABLE
JUMP Z,retry_status_check
LOAD sF,SECTOR_AVAILABLE
OR s5,sF
;
; RESET WORDS READ REGISTER
;
LOAD s6,FF
RETURN
read_word_from_cf:
;
; CHECK IF THE SECTOR IS AVAILABLE
;
LOAD sF,SECTOR_AVAILABLE
AND sF,s5
;
; IF SECTOR_AVAILABLE=0 JUMP TO READ_NEW_SECTOR
;
CALL Z,read_new_sector
; check for error
LOAD sF,s5
AND sF,ERROR_MY_STATUS
RETURN NZ
;retry_status_check:
;CALL cf_status_check
;
; CHECK IF DATA IS AVAILABLE
;
; 120103 - changed . When there is sector
; available in the cf ram buffer it is not
; necessary to check neither bsy or drq
; only read words with the correct timing paramenters
;
;LOAD sF,DATA_TRANSFER_ALLOWED
;AND sF,s5
; LOOPS UNTIL SECTOR DATA IS AVAILABLE
;JUMP Z,retry_status_check
; end 120103
;
; IF 256 WORD READ -> SECTOR AVAILABLE=0
;
CALL read_word
AND s6,s6
JUMP Z,reset_word_READ
;
; DECREMENT NUMBER OF WORDS READ
;
SUB s6,01
RETURN
reset_word_READ:
;
; IF 256 WORD READ -> SECTOR AVAILABLE=0
;
;ADD s7,01
LOAD s6,FF
LOAD sF,FE
AND s5,sF
RETURN
read_word:
;
; READ WORDS FROM IDE DATA REGISTERS
;
LOAD sF,DATA
CALL read_ide_register
;
; DATA ARE IN sB , sC
;
; DATA AVAILABLE SIGNAL IS STORED
LOAD sF,TAG0_WORD_AVAILABLE
OUTPUT sF,CONTROL_WB_OUT
RETURN
dummy_word_read:
CALL read_word
SUB s6,01
read_new_sector:
CALL cf_status_check
LOAD sF,s5
AND sF,DATA_TRANSFER_ALLOWED
;loops until previous non READ words are READ
JUMP NZ,dummy_word_read
LOAD sF,s5
AND sF,ERROR_MY_STATUS
RETURN NZ
LOAD sF,s5
AND sF,COMMAND_ALLOWED
; loops until commands are allowed
LOAD s6,FF
JUMP Z,read_new_sector
JUMP read_sector
cf_status_check:
;
; CF STATUS REGISTER READ
;
LOAD sF,STATUS
CALL read_ide_register
;
; ERROR
;
; BSY/DRDY/DWF/DSC/DRQ/CORR/0/ERR
; MASK 0 0 0 0 0 0 0 1
; ERR-ST X X X X X X X 1
; AND 0 0 0 0 0 0 0 1
LOAD sF,01
AND sF,sB
JUMP NZ,put_error_code
;
; DATA REQUEST MASK (READY=1 : BUSY=0 : DRQ=1)
;
; BSY/DRDY/DWF/DSC/DRQ/CORR/0/ERR
; MASK 1 1 0 0 1 0 0 1
; DRQ-ST 0 1 X X 1 X X 0
; AND 0 1 0 0 1 0 0 0
LOAD sF,C9
AND sF,sB
SUB sF,48
JUMP Z,put_data_request_allowed
;
; COMMAND ALLOWED MASK (READY=1 : BUSY=0)
;
; BSY/DRDY/DWF/DSC/DRQ/CORR/0/ERR
; MASK 1 1 0 0 0 0 0 1
; CMD-ST 0 1 X X 0 X X 0
; AND 0 1 0 0 0 0 0 0
LOAD sF,C1
AND sF,sB
SUB sF,40
JUMP Z,put_command_allowed
;
; ELSE DATA_TRANSFER_ALLOWED & COMMAND_ALLOWED => 0
;
;JUMP put_error_code
; REVISAR ???
;AND s5,01
RETURN
put_error_code:
;
; ERROR SIGNAL
;
; PUT ERROR CODE
;
LOAD sF,04
OUTPUT sF,CONTROL_OUT
CALL soft_reset
LOAD s5,ERROR_MY_STATUS
RETURN
;JUMP initialization (STACK OVERFLOW???)
soft_reset:
LOAD sD,SOFT_RESET
LOAD sF,CONTROL
CALL write_ide_register
LOAD sF,FF
CALL wait_loop
LOAD sF,FF
CALL wait_loop
LOAD sF,FF
CALL wait_loop
LOAD sF,FF
CALL wait_loop
LOAD sD,00
LOAD sF,CONTROL
CALL write_ide_register
RETURN
put_data_request_allowed:
;
; DRQ ALLOW -> MY STATUS REGISTER
;
AND s5,FD
LOAD sF,DATA_TRANSFER_ALLOWED
OR s5,sF
RETURN
put_command_allowed:
;
; DRQ ALLOW -> MY STATUS REGISTER
;
AND s5,FB
LOAD sF,COMMAND_ALLOWED
OR s5,sF
RETURN
ADDRESS FF
interrupt:
RETURNI ENABLE
Go to most recent revision | Compare with Previous | Blame | View Log