Full Version : IDE/FAT INterface to Harddrive (AVR ASM)
avr >>TECHNICAL & HARDWARE >>IDE/FAT INterface to Harddrive (AVR ASM)


AVR_Admin- 05-09-2006
IDE Harddrive Interface to 8515

QUOTE
198.95 ms for read a sector
206.79 ms for 3 ramdom sector  take 00828822 instruction

60 cector sec/sec min  60 x .5k = 30kbit sec  ramdom sector
120 sector sec/sec max 120 x 5k = 60kbit sec  ramdom sector

714 consecutive sector read/sec  357kbit ses  good for mp3 player :-)

head seek betwen non consecutive sector sector  22,60ms

mesure was taken from a seagate st946a (540mb) 2,5 laptop drive
end avr cloked at 4,00 Mhz on a stk-200 board
the code is not clock dependent rug good on 8mhz clock to
just change value of timer1 for out of delay drive respond


Link: http://vfx.freeweb.hu/avr/index.html

CODE

;*****************************************************************************
;*                         IDE DRIVER V1.1                                   *
;*                                                                           *
;*                                                                           *
;*                                                                           *
;*        Copyright(C) 1999-2000 ALPHATRONIC  BY.MARC LALONDE                *
;*****************************************************************************
;      ------------->>>>> NOTE <<<<<-------------
;
;20/10/2000 15:50  bebug hardware interface (drive not respond to command )
;20/10/2000 17:39  first working code (identify_device working )
;27/10/2000 20:53  read/write sector working +adding drive command
;27/10/2000 22:41  work well on 2 quantum drive but fail on 2 segate ??
;                  maby a bad timing ??im chek this now    
;28/10/2000 16:35  corect a part of bug that afect segate drrive now the only
;                  bug on thers drive is a pinc,7 tha is alwlas 1 ??
;29/10/2000 21:22  adding time out timer of 4 seconde if drive command crash  
;
;*****************************************************************************
;
;                                 AT90S8515Px
; SIGNAL_NAME                    ______ ______                     SIGNAL_NAME
;      .                        |      -      |                         .
;   IDE DA0  -->    (TO) PB0  --| 1        40 |--   VCC                 .
;   IDE DA1  -->    (T1) PB1  --| 2        39 |--   PA0 LCD 7   <-> IDE DD00
;   IDE DA2  -->  (AIN0) PB2  --| 3        38 |--   PA1 LCD 8   <-> IDE DD01
;   IDE SC0- -->  (AIN1) PB3  --| 4        37 |--   PA2 LCD 9   <-> IDE DD02
;   IDE SC1- -->   (SS*) PB4  --| 5        36 |--   PA3 LCD 10  <-> IDE DD03
;      .     <--  (MOSI) PB5  --| 6        35 |--   PA4 LCD 11  <-> IDE DD04
;      .     -->  (MISO) PB6  --| 7        34 |--   PA5 LCD 12  <-> IDE DD05
;      .     <--   (SCK) PB7  --| 8        33 |--   PA6 LCD 13  <-> IDE DD06
;      .     -->      RESET*  ->| 9        32 |--   PA7 LCD 14  <-> IDE DD07
;      .     -->   (RXD) PD0  --| 10       31 |--   ICP         <--     .
;      .     <--   (TXD) PD1  --| 11       30 |--   ALE         -->     .
;   IDE RD   <--  (INT0) PD2  --| 12       29 |--   OC1B        -->     .
;   IDE WD   <--  (INT1) PD3  --| 13       28 |--   PC7 (A15)   <-> IDE DD08
;   IDE RST  <--         PD4  --| 14       27 |--   PC6 LCD 4   <-> IDE DD09
;      .     <--  (OC1A) PD5  --| 15       26 |--   PC5 (A13)   <-> IDE DD10
;   LCD 5    <--   (WR*) PD6  --| 16       25 |--   PC4 (A12)   <-> IDE DD11
;   LCD 6    <--   (RD*) PD7  --| 17       24 |--   PC3 (A11)   <-> IDE DD12
;   4.0 Mhz  -->       XTAL1  ->| 18       23 |--   PC2 (A10)   <-> IDE DD13
;   4.0 Mhz  <--       XTAL2  <-| 19       22 |--   PC1 (A9)    <-> IDE DD14
;                        GND  --| 20       21 |--   PC0 (A8)    <-> IDE DD15
;                               |_____________|
;
;                                   (DIP-40)
;
;LCD IS STK-200 STANDART PINOUT
;
;command suported end useing this label
;
;ata_rst         hardware hard drive reset              just call label
;
;ata_id          perfor identify_device command         just call label
;
;ata_idle        put drive in idle state                just call label
;
;ata_sleep       put drive in sleep                     just call label
;
;lba_sel         selection lba sector to do operation   must load register
;                sector_cnt,sector,cyl_low,cyl_hi,head  before call label
;                                                                  
;ata_read_sec    read sector designed by lba_sel        must set lba_sel first
;                note: the sector content is tranfered to avr ram (block1)
;
;ata_write_sec   write sector designed by lba_sel       must set lba_sel first
;                note: the conten of ram is copied to dirve sector (block1)

;*****************************************************************************
.include "c:\atmel\inc\8515def.inc"
.include "c:\atmel\project\thinkpad\2\ata_3.asm

.cseg
.org 0

       rjmp reset
reti        ; External 0 interrupt  Vector
reti  ; External 1 interrupt  Vector
reti  ; Timer 1 Capture  Vector
reti  ; Timer1 CompareA  Vector
reti  ; Timer 1 CompareB  Vector
reti  ; Timer 1 Overflow  Vector
reti  ; Timer 0 Overflow  Vector
reti  ; SPI  Vector
reti  ; UART Receive  Vector
reti  ; UDR Empty  Vector
reti  ; UART Transmit  Vector
reti  ; Analogue Comparator  Vector

RESET:
ldi temp,low(RAMEND)
out SPL,temp        ;init Stack Pointer
ldi temp,high(RAMEND)
out SPH,temp
ldi     temp,255
out     ddrb,temp
out     ddrd,temp
sbi     portd,rd
sbi     portd,wd
       ldi     temp,0        
       out     tccr1a,temp
       ldi     temp,tck1024           ;set timer pre scaler
       out     tccr1b,temp
       ldi     temp,60
       out     ocr1ah,temp            ;set timer for 4 seconde at 4mhz
       ldi     temp,255
       out     ocr1al,temp

;*****************************************************************************
;* MAIN PROGRAM LOOP                                            *
;*****************************************************************************

main:
                 
rcall   ata_rst                ;reset of drive        
       rcall   ata_id                 ;get drive information  
       
   
;        rcall   pwd_to_ram             ;transfer password to ram
;        rcall   ata_set_pwd            ;set drive whit password  
;        rcall   ata_id                 ;verifi pwd set (bytes 160 in ram)
;        ldi     pwd_1,31               ;set passord (1 for exemple) in asci
;        rcall   pwd_to_ram             ;transfer password to ram
;        rcall   ata_unlock             ;unlock drive whit password
       
       ldi     sector_cnt,1           ;one sector to be read
       ldi     sector,1               ;logical bloc adress 1 (lba)
       ldi     cyl_low,0              ;bits 8-15  of lba
       ldi     cyl_hi,0               ;bits  16-30 of lba
       rcall   lba_sel
       rcall   ata_read_sec           ;read sector selectioned sector
       
       ldi     sector,2               ;logical bloc adress 2
       rcall   lba_sel
       rcall   ata_write_sec          ;write ram contain to selected adress
       
       ldi     sector,2  
       rcall   lba_sel                  
       rcall   ata_read_sec           ;read sector to confirm that sector
                                      ;1 is now copied in sector 2
                                               
       rcall   ata_sleep              ;drive go sleep (head park on pellow)
       
STOP:                                          
rjmp    stop

drive_error:      

       rjmp    drive_error        ;if you land here you have a problem



CODE

;*****************************************************************************
;*                         IDE DRIVER V1.1                                   *
;*                                                                           *
;*                         final version 7/11/2000                           *
;*                                                                           *
;*        Copyright(C) 1999-2000 ALPHATRONIC  BY.MARC LALONDE                *
;*****************************************************************************
;      ------------->>>>> NOTE <<<<<-------------
;
;strobe the /DIOW and /DIOR lines. Normally these signals
;are set to 1 when not in use and to strobe the signal
;means to set the signal to 0 for at least 165ns and
;then set the signal back to 1. Also remember that the
;data and control lines must be valid for a clock cycle
;before strobing the DIOW or DIOR lines and they must be
;valid for another clock cycle after strobing DIOW/R.
;Also remember to use a clock that is slower
;than 8Mhz. If you use a clock faster than 8Mhz
;you will have to be careful with the timing requirements.
;In order to use an 8Mhz clock you need to strobe for
;2 clock cycles
;
;   Drive I/O;write strobe.
; Rising edge
;clocks data from the host data bus to
;a drive register or data port
;
;   Drive I/O read strobe.
;Falling edge
;enables data from a drive register or
;data port to host data bus.
;
; Don't use for ANY-THING  without writen permission of alphatronic .
;
;20/10/2000 15:50  bebug hardware interface (drive not respond to command )
;20/10/2000 17:39  first working code (identify_device working )
;27/10/2000 20:53  read/write sector working +adding drive command
;27/10/2000 22:41  work well on 2 quantum drive but fail on 2 segate ??
;                  maby a bad timing ??im chek this now    
;28/10/2000 16:35  corect a part of bug that afect segate drrive now the only
;                  bug on thers drive is a pinc,7 tha is alwlas 1 ??
;29/10/2000 21:22  adding time out timer of 4 seconde if drive command crash  
;07/11/200  15:00  no more knot bug (final version)
;*****************************************************************************
;
;                                 AT90S8515Px
; SIGNAL_NAME                    ______ ______                     SIGNAL_NAME
;      .                        |      -      |                         .
;   IDE DA0  -->    (TO) PB0  --| 1        40 |--   VCC                 .
;   IDE DA1  -->    (T1) PB1  --| 2        39 |--   PA0 LCD 7   <-> IDE DD00
;   IDE DA2  -->  (AIN0) PB2  --| 3        38 |--   PA1 LCD 8   <-> IDE DD01
;   IDE SC0- -->  (AIN1) PB3  --| 4        37 |--   PA2 LCD 9   <-> IDE DD02
;   IDE SC1- -->   (SS*) PB4  --| 5        36 |--   PA3 LCD 10  <-> IDE DD03
;      .     <--  (MOSI) PB5  --| 6        35 |--   PA4 LCD 11  <-> IDE DD04
;      .     -->  (MISO) PB6  --| 7        34 |--   PA5 LCD 12  <-> IDE DD05
;      .     <--   (SCK) PB7  --| 8        33 |--   PA6 LCD 13  <-> IDE DD06
;      .     -->      RESET*  ->| 9        32 |--   PA7 LCD 14  <-> IDE DD07
;      .     -->   (RXD) PD0  --| 10       31 |--   ICP         <--     .
;      .     <--   (TXD) PD1  --| 11       30 |--   ALE         -->     .
;   IDE RD   <--  (INT0) PD2  --| 12       29 |--   OC1B        -->     .
;   IDE WD   <--  (INT1) PD3  --| 13       28 |--   PC7 (A15)   <-> IDE DD08
;   IDE RST  <--         PD4  --| 14       27 |--   PC6 LCD 4   <-> IDE DD09
;      .     <--  (OC1A) PD5  --| 15       26 |--   PC5 (A13)   <-> IDE DD10
;   LCD 5    <--   (WR*) PD6  --| 16       25 |--   PC4 (A12)   <-> IDE DD11
;   LCD 6    <--   (RD*) PD7  --| 17       24 |--   PC3 (A11)   <-> IDE DD12
;   4.0 Mhz  -->       XTAL1  ->| 18       23 |--   PC2 (A10)   <-> IDE DD13
;   4.0 Mhz  <--       XTAL2  <-| 19       22 |--   PC1 (A9)    <-> IDE DD14
;                        GND  --| 20       21 |--   PC0 (A8)    <-> IDE DD15
;                               |_____________|
;
;                                   (DIP-40)
;
;LCD IS STK-200 STANDART PINOUT
;
;command suported end useing this label
;
;ata_rst         hardware hard drive reset              just call label
;
;ata_id          perfor identify_device command         just call label
;
;ata_idle        put drive in idle state                just call label
;
;ata_sleep       put drive in sleep                     just call label
;
;lba_sel         selection lba sector to do operation   must load register
;                sector_cnt,sector,cyl_low,cyl_hi,head  before call label
;                                                                  
;ata_read_sec    read sector designed by lba_sel        must set lba_sel first
;                note: the sector content is tranfered to avr ram (block1)
;
;ata_write_sec   write sector designed by lba_sel       must set lba_sel first
;                note: the conten of ram is copied to dirve sector (block1)

;
;                             |<------------ t0 ------------------------>|
;                       __________________________________________       |
;Address Valid *1 _____/                                          \________
;                      |<-t1->|<----------- t2 ----------->|<-t9->|      |
;                      |      |____________________________|<---t2i----->|_
;DIOR-/DIOW-      ____________/                            \_____________/
;                      |      |                            |      |
;                      |      |                    ________|__  ->|   |<-t8
;Write Data    *2 --------------------------------<___________>------------
;                      |      |                   |<--t3-->|  |       |
;                      |      |                          ->|t4|<-     |
;                      |      |                     _______|___ ____  |
;Read Data     *2 ---------------------------------<___________X____>------
;                    ->|t7|<- |                    |     ->|t6 |<-  | |
;                      |  | ->| tA |<-             |<-t5-->|<-t6Z-->|
;                      |  |___________________________________________|
;IOCS16-          ________/        |               |                  \____
;                                  |             ->|tRd|<-            |
;                 _________________|___________________|___________________
;IORDY            XXXXXXXXXXXXXXXXX____________________/
;                                  |<-------tB-------->|
;  *1 Device Address consists of signals CS0-, CS1- and DA2-0
;  *2 Data consists of DD0-15 (16-bit) or DD0-7 (8-bit)  
;
;
;t0       650ns
;t1       70 ns
;t2       165ns
;t3       60 ns
;t4       30 ns
;t5       50 ns
;t6       5  ns
;t7       90 ns
;t8       60 ns
;t9       20 ns

;*****************************************************************************
;.include "c:\atmel\inc\8515def.inc"

;diver            
.equ   BLOCK1            =$60        ;start address of SRAM array #1
.equ   security_status     =$160       ;security satus bit of drive
.equ   model_number        =$94        ;model number  
.equ   TCK1024             =5        ;Timer/Counter runs from CK / 1024

;ata-4 command

.equ   identify_device     =0b11101100 ;EC HEX
.equ   disabel_password    =0b11110110 ;F6
.equ   freeze_lock         =0b11110101 ;F5
.equ   set_password        =0b11110001 ;F1
.equ   unlock              =0b11110010 ;F2
.equ   erase_prepare       =0b11110011 ;F3
.equ   erase_unit          =0b11110100 ;F4
.equ   check_power_mode    =0b11100101 ;E5
.equ   device_diagnostics  =0b10010000 ;90
.equ   format_track        =0b01010000 ;50
.equ   format_unit         =0b11110111 ;F7
.equ   idel                =0b11100011 ;E3
.equ   idel_immediate      =0b11100001 ;E1
.equ   initialize_device   =0b10010001 ;91
.equ   read_sector         =0b00100000 ;20
.equ   read_long           =0b00100010 ;22
.equ   read_long_retry     =0b00100011 ;23
.equ   read_multiple       =0b11000100 ;C4
.equ   read_verify         =0b01000000 ;40
.equ   read_verity_retry   =0b01000001 ;41
.equ   recalibrate         =0b         ;1x
.equ   seek                =0b         ;7x
.equ   set_features        =0b11101111 ;EF
.equ   set_max_address     =0b11111001 ;F9
.equ   set_multiple_mode   =0b11000110 ;C6
.equ   sleep               =0b11100110 ;E6
.equ   standby             =0b11100010 ;E2
.equ   standby_immediate   =0b11100000 ;E0
.equ   write_long          =0b00110010 ;32
.equ   write_long_retry    =0b00110011 ;33
.equ   write_sectors_retry =0b00110000 ;30
.equ   write_sector        =0b00110001 ;31
.equ   write_verity        =0b00111100 ;3C        

;ata-4 register                            bit mask of register
                                           
;command block register                 n\c n\c n\c SC1- SC0- DA2 DA1 DA0
.equ   feature             =0b00010001
.equ   sector_cont         =0b00010010      
.equ   sector_number       =0b00010011
.equ   cylinder_low        =0b00010100
.equ   cylinder_high       =0b00010101
.equ   device_head         =0b00010110
.equ   command             =0b00010111 ;write
.equ   status              =0b00010111 ;read
.equ   data                =0b00010000
.equ   error               =0b00010001

;control block registers
.equ   alternate_status    =0b00010110
.equ   device control      =0b00010110

.equ   master              =0b11100000
.equ   slave               =0b10100000
.equ   user_pwd            =0b00000000
.equ   master_pwd          =0b00000001

;pin direct
.equ   rd           =   5
.equ   wd           =   4
.equ   rst          =   3

;***** Main Program Register variables

.def   chr_1        =   r2             ;pasword character 1 in  asci
.def   chr_2        =   r3
.def   chr_3        =   r4
.def   chr_4        =   r5             ;        to
.def   chr_5        =   r6
.def   chr_6        =   r7
.def   chr_7        =   r8             ;password character 7

.def   delay        =   r17
.def   Counter     = r16            ;used as character counter
.def   temp         =   r17
.def   drv_status   =   r18
.def   sector       =   r19            ;in LBA =bits 0  - 7
.def   cyl_low      =   r20            ;in LBA =bits 8  - 15
.def   cyl_hi       =   r21            ;in LBA =bits 16 - 23
.def   head         =   r22            ;in LBA =bits 23 - 30
.def   ata_command  =   r23
.def   sector_cnt   =   r24

;*****************************************************************************
;* ATA COMMAND LIST                                           *
;*****************************************************************************

.org 100  
   
ata_rst:
         
       rcall   delay4ms               ;whait voltage stab
       cbi     portd,rst              ;put drive in reset
       rcall   delay4ms               ;whait voltage stab
       sbi     portd,rst              ;put drive in working mode
       rcall   ata_stat
 
       
ata_pio:

       ldi     temp,255               ;put data bus as ouput
       out     ddra,temp
       ldi     temp,feature           ;select  registe
       out     portb,temp          
       cbi     portd,wd               ;selection pio mode
       ldi     temp,0b00000011                  
       out     porta,temp             ;select master drive
       sbi     portd,wd
       ldi     temp,sector_cont       ;select  registe
       out     portb,temp          
       cbi     portd,wd               ;write data to resister of drive
       ldi     temp,0b00000001                  
       out     porta,temp             ;pio mode = 0
       sbi     portd,wd
       ldi     temp,device_head       ;select  registe
       out     portb,temp          
       cbi     portd,wd  
       ldi     temp,master                  
       out     porta,temp             ;select master drive
       sbi     portd,wd
       ldi     temp,command           ;select register  
       out     portB,temp          
       cbi     portD,wd               ;write comend
       ldi     temp,set_features    
       out     porta,temp          
       sbi     portd,wd
       rcall   ata_stat
       ret  
         
ata_id:

       ldi     ata_command,identify_device
       rcall   set_command
       rcall   ata_stat2        
       ldi YH,high(BLOCK1)        ;init Y-pointer to start of sram
ldi YL,low(BLOCK1)
       rcall   read_buffer
       rcall   ata_stat
       ret

ata_disable_pwd:

       ldi     ata_command,disabel_password
       rcall   set_command
       rcall   ata_stat2
       ldi YH,high(BLOCK1)        ;init Y-pointer to start of sram
ldi YL,low(BLOCK1)
       rcall   write_buffer
       rcall   ata_stat
       ret
       
ata_unlock:

       ldi     ata_command,unlock
       rcall   set_command
       rcall   ata_stat2
       ldi YH,high(BLOCK1)        ;init Y-pointer to start of sram
ldi YL,low(BLOCK1)
       rcall   write_buffer
       rcall   ata_stat
       ret

ata_set_pwd:
                   
       ldi     ata_command,set_password
       rcall   set_command
       rcall   ata_stat2
       ldi YH,high(BLOCK1)        ;init Y-pointer to start of sram
ldi YL,low(BLOCK1)
       rcall   write_buffer
       rcall   ata_stat
       ret


ata_idle:

       ldi     ata_command,idel_immediate
       rcall   set_command
       rcall   ata_stat
       ret
       
ata_sleep:

       ldi     ata_command,sleep
       rcall   set_command
       rcall   ata_stat
       ret  
             
lba_sel:

       ldi     temp,255               ;put data bus as ouput
       out     ddra,temp
       ldi     temp,device_head       ;select  registe
       out     portb,temp          
       cbi     portd,wd               ;write data to resister of drive
       ldi     temp,master                  
       out     porta,temp             ;select master drive
       sbi     portd,wd
       ldi     temp,sector_cont       ;write sector count
       out     portb,temp
       cbi     portd,wd
       out     porta,sector_cnt
       sbi     portd,wd
       ldi     temp,sector_number     ;write sector no.
       out     portb,temp
       cbi     portd,wd
       out     porta,sector
       sbi     portd,wd
       ldi     temp,cylinder_low      ;write cyl_low
       out     portb,temp
       cbi     portd,wd
       out     porta,cyl_low
       sbi     portd,wd
       ldi     temp,cylinder_high     ;write cyl_hi
       out     portb,temp
       cbi     portd,wd
       out     porta,cyl_hi
       sbi     portd,wd                
       ldi     temp,command           ;select register  
       out     portB,temp
       ret
       
ata_read_sec:
             
       cbi     portD,wd               ;write comend
       ldi     temp,read_sector      
       out     porta,temp      
       sbi     portd,wd
       rcall   ata_stat2
       ldi     YH,high(BLOCK1)        ;init Y-pointer to start of sram
       ldi     YL,low(BLOCK1)  
       rcall   read_buffer
       rcall   ata_stat
       ret            
     
ata_write_sec:
             
       cbi     portD,wd               ;write comend
       ldi     temp,write_sector      
       out     porta,temp      
       sbi     portd,wd
       rcall   ata_stat2
       ldi     YH,high(BLOCK1)        ;init Y-pointer to start of sram
       ldi     YL,low(BLOCK1)  
       rcall   write_buffer
       rcall   ata_stat
       ret  
           
pwd_to_ram:

       ldi     YH,high(BLOCK1)        ;init Y-pointer to start of sram
       ldi     YL,low(BLOCK1)  
       ldi     temp,user_pwd          ;chose betwen user or master pwd  
       st      Y+,temp                        
       st      y+,chr_1               ;write pasword in ram (7 chr asci)
       st      y+,chr_2
       st      y+,chr_3
       st      y+,chr_4
       st      y+,chr_5
       st      y+,chr_6
       st      y+,chr_7
       ldi     counter,247
fill:        
       ldi     temp,0                 ;fill the rest or ram of 0
       st      y+,temp
       dec     counter                ;conter  - 1
       brne    fill
       ret
                   
;*****************************************************************************
;* IDE ROUTINE                                        *
;*****************************************************************************
     
ata_stat2:
   
       ldi     temp,0                 ;clear timer conter  
       out     tcnt1h,temp
       out     tcnt1l,temp
       ldi     temp,255               ;clear interup flag just in case
       out     tifr,temp    
r_stat2:
       in      temp,tifr
       sbrc    temp,6                 ;if drive is still in error after  
       rjmp    drive_error            ;4 sec falg set en go drive error
 ldi     temp,0
 out     porta,temp
 out     ddra,temp
ldi     temp,status            ;read status regist for see if error
       out     portB,temp
       cbi     portD,rd               ;strobe read pin
       rcall   delay100us             ;let drive time to respond
       in      drv_status,pina        ;store status  in registe drv_status
       nop                            ;small delay
       sbi     portD,rd               ;rising edge of read pin
       sbrs    drv_status,7           ;drive busy   (bsy)
       sbrc    drv_status,0           ;drive error  (err)          
       rjmp    r_stat2
drq:    
       in      temp,tifr              ;if drive is still in error after
       sbrc    temp,6                 ;4 sec falg set en go drive error
       rjmp    drive_error
       sbrc    drv_status,3           ;loop until drive set drq bit
       ret
       cbi     portd,rd
       rcall   delay40us
       in      drv_status,pina
       nop
       sbi     portd,rd
       rjmp    drq
       
ata_stat:
 
       ldi     temp,0                 ;clear timer conter
       out     tcnt1h,temp
       out     tcnt1l,temp
       ldi     temp,255               ;clear interup flag just in case
       out     tifr,temp    
r_stat:
       in      temp,tifr              ;if drive is still in error after
       sbrc    temp,6                 ;4 sec falg set en go drive error
       rjmp    drive_error
 ldi     temp,0
 out     porta,temp
 out     ddra,temp
ldi     temp,status            ;read status regist for see if error
       out     portB,temp
       cbi     portD,rd               ;strobe read pin
       rcall   delay100us             ;let drive time to respond
       in      drv_status,pina        ;store status  in registe drv_status  
       nop                            ;small delay
       sbi     portD,rd               ;rising edge of read pin
       sbrs    drv_status,7           ;drive busy   (bsy)
       sbrc    drv_status,0           ;drive error  (err)          
       rjmp    r_stat  
       sbrs    drv_status,6           ;device redy  (drdy)
       rjmp    r_stat
       ret      
       
     
set_command:

       ldi     temp,255               ;put data bus as ouput
       out     ddra,temp
       ldi     temp,device_head       ;select  registe
       out     portb,temp          
       cbi     portd,wd               ;write data to resister of drive
       ldi     temp,master                  
       out     porta,temp             ;select master drive
       sbi     portd,wd
       ldi     temp,command           ;select register  
       out     portB,temp          
       cbi     portD,wd               ;write comend      
       out     porta,ata_command          
       sbi     portd,wd
       ret  

read_buffer:

       ldi     temp,0                 ;put portA as a input
       out     ddra,temp
       out     ddrc,temp
       ldi     temp,0                 ;clear bit in portA
       out     portA,temp
       out     portc,temp
       ldi     counter,250            ;buffer size (fifo) first 250 bytes
   
       ldi     temp,data              ;select data registe on port d
       out     portB,temp              
lp3:
       sbi     portb,5                ;set pinb,5 hi for test
       sbi     ddrb,5
       cbi     portD,rd    
       nop
       in      temp,pina
       st      Y+,temp
       in      temp,pinc
       st      Y+,temp;      
       nop            
       sbi     portd,rd
       dec     counter                ;conter  - 1
       brne    lp3
       ldi     counter,6
     
last6:
       cbi     portb,5                ;clr pinb,5 hi for test
       cbi     ddrb,5                 ;read last 128 bytes of ram
       cbi     portD,rd               ;but dont in ram to prevent  
       nop                            ;stak pointer coruption
       sbi     portD,rd
       dec     counter
       brne    last6
       ret
     
write_buffer:

       ldi     temp,255               ;put portA as a ouput
       out     ddra,temp
       out     ddrc,temp
       ldi     temp,0                 ;clear bit in portA
       out     portA,temp
       out     portc,temp
       ldi     counter,250            ;buffer size (fifo) first 250 bytes
   
       ldi     temp,data              ;select data registe on port d  
       out     portB,temp  
                 
lp4:
       cbi     portd,wd
       nop
       ld      temp,y+
       out     porta,temp
       ld      temp,y+
       out     portc,temp      
       nop            
       sbi     portd,wd
       dec     counter                  ;buffer  - 1
       brne    lp4
       ldi     counter,6
     
last6_2:
                                      ;read last 128 bytes of ram
       cbi     portD,wd               ;but dont in ram to prevent  
       nop                            ;stak pointer coruption
       sbi     portD,wd
       dec     counter
       brne    last6_2
       ret      

;****************************************************************************
;* 3 different delay routines used by  IDE                             *
;****************************************************************************
Delay40us:
ldi  r21,$40
Loop3: dec  r21
brne  loop3
ret
Delay100us:
ldi  r21,$88
Loop: dec  r21
brne  loop
ret
Delay4ms:
ldi  r22,$1c
Loop1: ldi  r21,$00
Loop2: dec  r21
brne  loop2
dec  r22
brne  loop1
ret    
     


AVR_Admin- 05-09-2006
CODE


AVRASM ver. 1.30  C:\Atmel\project\thinkpad\2\main.asm Wed Nov 08 13:47:27 2000


       ;*****************************************************************************
       ;*                         IDE DRIVER V1.1                                   *
       ;*                                                                           *
       ;*                                                                           *
       ;*                                                                           *
       ;*        Copyright(C) 1999-2000 ALPHATRONIC  BY.MARC LALONDE                *
       ;*****************************************************************************
       ;      ------------->>>>> NOTE <<<<<-------------
       ;
       ;20/10/2000 15:50  bebug hardware interface (drive not respond to command )
       ;20/10/2000 17:39  first working code (identify_device working )
       ;27/10/2000 20:53  read/write sector working +adding drive command
       ;27/10/2000 22:41  work well on 2 quantum drive but fail on 2 segate ??
       ;                  maby a bad timing ??im chek this now    
       ;28/10/2000 16:35  corect a part of bug that afect segate drrive now the only
       ;                  bug on thers drive is a pinc,7 tha is alwlas 1 ??
       ;29/10/2000 21:22  adding time out timer of 4 seconde if drive command crash  
       ;
       ;*****************************************************************************
       ;
       ;                                 AT90S8515Px
       ; SIGNAL_NAME                    ______ ______                     SIGNAL_NAME
       ;      .                        |      -      |                         .
       ;   IDE DA0  -->    (TO) PB0  --| 1        40 |--   VCC                 .
       ;   IDE DA1  -->    (T1) PB1  --| 2        39 |--   PA0 LCD 7   <-> IDE DD00
       ;   IDE DA2  -->  (AIN0) PB2  --| 3        38 |--   PA1 LCD 8   <-> IDE DD01
       ;   IDE SC0- -->  (AIN1) PB3  --| 4        37 |--   PA2 LCD 9   <-> IDE DD02
       ;   IDE SC1- -->   (SS*) PB4  --| 5        36 |--   PA3 LCD 10  <-> IDE DD03
       ;      .     <--  (MOSI) PB5  --| 6        35 |--   PA4 LCD 11  <-> IDE DD04
       ;      .     -->  (MISO) PB6  --| 7        34 |--   PA5 LCD 12  <-> IDE DD05
       ;      .     <--   (SCK) PB7  --| 8        33 |--   PA6 LCD 13  <-> IDE DD06
       ;      .     -->      RESET*  ->| 9        32 |--   PA7 LCD 14  <-> IDE DD07
       ;      .     -->   (RXD) PD0  --| 10       31 |--   ICP         <--     .
       ;      .     <--   (TXD) PD1  --| 11       30 |--   ALE         -->     .
       ;   IDE RD   <--  (INT0) PD2  --| 12       29 |--   OC1B        -->     .
       ;   IDE WD   <--  (INT1) PD3  --| 13       28 |--   PC7 (A15)   <-> IDE DD08
       ;   IDE RST  <--         PD4  --| 14       27 |--   PC6 LCD 4   <-> IDE DD09
       ;      .     <--  (OC1A) PD5  --| 15       26 |--   PC5 (A13)   <-> IDE DD10
       ;   LCD 5    <--   (WR*) PD6  --| 16       25 |--   PC4 (A12)   <-> IDE DD11
       ;   LCD 6    <--   (RD*) PD7  --| 17       24 |--   PC3 (A11)   <-> IDE DD12
       ;   4.0 Mhz  -->       XTAL1  ->| 18       23 |--   PC2 (A10)   <-> IDE DD13
       ;   4.0 Mhz  <--       XTAL2  <-| 19       22 |--   PC1 (A9)    <-> IDE DD14
       ;                        GND  --| 20       21 |--   PC0 (A8)    <-> IDE DD15
       ;                               |_____________|
       ;
       ;                                   (DIP-40)
       ;
       ;LCD IS STK-200 STANDART PINOUT
       ;
       ;command suported end useing this label
       ;
       ;ata_rst         hardware hard drive reset              just call label
       ;
       ;ata_id          perfor identify_device command         just call label
       ;
       ;ata_idle        put drive in idle state                just call label
       ;
       ;ata_sleep       put drive in sleep                     just call label
       ;
       ;lba_sel         selection lba sector to do operation   must load register
       ;                sector_cnt,sector,cyl_low,cyl_hi,head  before call label
       ;                                                                  
       ;ata_read_sec    read sector designed by lba_sel        must set lba_sel first
       ;                note: the sector content is tranfered to avr ram (block1)
       ;
       ;ata_write_sec   write sector designed by lba_sel       must set lba_sel first
       ;                note: the conten of ram is copied to dirve sector (block1)
       
       ;*****************************************************************************
         .include "c:\atmel\inc\8515def.inc"
       ;***************************************************************************
       ;* A P P L I C A T I O N   N O T E   F O R   T H E   A V R   F A M I L Y
       ;*
       ;* Number  :AVR000
       ;* File Name  :"8515def.inc"
       ;* Title  :Register/Bit Definitions for the AT90S8515
       ;* Date                 :99.01.28
       ;* Version              :1.30
       ;* Support telephone :+47 72 88 43 88 (ATMEL Norway)
       ;* Support fax  :+47 72 88 43 99 (ATMEL Norway)
       ;* Support E-mail :avr@atmel.com
       ;* Target MCU  :AT90S8515
       ;*
       ;* DESCRIPTION
       ;* When including this file in the assembly program file, all I/O register
       ;* names and I/O register bit names appearing in the data book can be used.
       ;* In addition, the six registers forming the three data pointers X, Y and
       ;* Z have been assigned names XL - ZH. Highest RAM address for Internal
       ;* SRAM is also defined
       ;*
       ;* The Register names are represented by their hexadecimal address.
       ;*
       ;* The Register Bit names are represented by their bit number (0-7).
       ;*
       ;* Please observe the difference in using the bit names with instructions
       ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc"
       ;* (skip if bit in register set/cleared). The following example illustrates
       ;* this:
       ;*
       ;* in r16,PORTB ;read PORTB latch
       ;* sbr r16,(1<<PB6)+(1<<PB5);set PB6 and PB5 (use masks, not bit#)
       ;* out  PORTB,r16 ;output to PORTB
       ;*
       ;* in r16,TIFR ;read the Timer Interrupt Flag Register
       ;* sbrc r16,TOV0 ;test the overflow flag (use bit#)
       ;* rjmp TOV0_is_set ;jump if set
       ;* ...   ;otherwise do something else
       ;***************************************************************************
       
       ;***** Specify Device
         .device AT90S8515
       
       ;***** I/O Register Definitions
         .equ SREG =$3f
         .equ SPH =$3e
         .equ SPL =$3d
         .equ GIMSK =$3b
         .equ GIFR =$3a
         .equ TIMSK =$39
         .equ TIFR =$38
         .equ MCUCR =$35
       
         .equ TCCR0 =$33
         .equ TCNT0 =$32
         .equ OCR0 =$31
       
         .equ TCCR1A =$2f
         .equ TCCR1B =$2e
         .equ TCNT1H =$2d
         .equ TCNT1L =$2c
         .equ OCR1AH =$2b
         .equ OCR1AL =$2a
         .equ OCR1BH =$29
         .equ OCR1BL =$28
         .equ ICR1H =$25
         .equ ICR1L =$24
       
         .equ WDTCR =$21
         .equ EEARH =$1f
         .equ EEARL =$1e
         .equ EEDR =$1d
         .equ EECR =$1c
       
         .equ PORTA =$1b
         .equ DDRA =$1a
         .equ PINA =$19
         .equ PORTB =$18
         .equ DDRB =$17
         .equ PINB =$16
         .equ PORTC =$15
         .equ DDRC =$14
         .equ PINC =$13
         .equ PORTD =$12
         .equ DDRD =$11
         .equ PIND =$10
       
         .equ SPDR =$0f
         .equ SPSR =$0e
         .equ SPCR =$0d
         .equ UDR =$0c
         .equ USR =$0b
         .equ UCR =$0a
         .equ UBRR =$09
         .equ ACSR =$08
       
       
       ;***** Bit Definitions
         .equ INT1 =7
         .equ INT0 =6
       
         .equ INTF1 =7
         .equ INTF0 =6
       
         .equ TOIE1 =7
         .equ OCIE1A =6
         .equ OCIE1B =5
         .equ TICIE1 =3
         .equ TOIE0 =1
       
         .equ TOV1 =7
         .equ OCF1A =6
         .equ OCF1B =5
         .equ ICF1 =3
         .equ TOV0 =1
       
         .equ SRE =7
         .equ SRW =6
         .equ SE =5
         .equ SM =4
         .equ ISC11 =3
         .equ ISC10 =2
         .equ ISC01 =1
         .equ ISC00 =0
       
         .equ CS02 =2
         .equ CS01 =1
         .equ CS00 =0
       
         .equ COM1A1 =7
         .equ COM1A0 =6
         .equ COM1B1 =5
         .equ COM1B0 =4
         .equ PWM11 =1
         .equ PWM10 =0
       
         .equ ICNC1 =7
         .equ ICES1 =6
         .equ CTC1 =3
         .equ CS12 =2
         .equ CS11 =1
         .equ CS10 =0
       
         .equ WDDE =4
         .equ WDE =3
         .equ WDP2 =2
         .equ WDP1 =1
         .equ WDP0 =0
       
         .equ EEMWE =2
         .equ EEWE =1
         .equ EERE =0
       
         .equ PA7 =7
         .equ PA6 =6
         .equ PA5 =5
         .equ PA4 =4
         .equ PA3 =3
         .equ PA2 =2
         .equ PA1 =1
         .equ PA0 =0
       
         .equ DDA7 =7
         .equ DDA6 =6
         .equ DDA5 =5
         .equ DDA4 =4
         .equ DDA3 =3
         .equ DDA2 =2
         .equ DDA1 =1
         .equ DDA0 =0
       
         .equ PINA7 =7
         .equ PINA6 =6
         .equ PINA5 =5
         .equ PINA4 =4
         .equ PINA3 =3
         .equ PINA2 =2
         .equ PINA1 =1
         .equ PINA0 =0
       
         .equ PB7 =7
         .equ PB6 =6
         .equ PB5 =5
         .equ PB4 =4
         .equ PB3 =3
         .equ PB2 =2
         .equ PB1 =1
         .equ PB0 =0
       
         .equ DDB7 =7
         .equ DDB6 =6
         .equ DDB5 =5
         .equ DDB4 =4
         .equ DDB3 =3
         .equ DDB2 =2
         .equ DDB1 =1
         .equ DDB0 =0
       
         .equ PINB7 =7
         .equ PINB6 =6
         .equ PINB5 =5
         .equ PINB4 =4
         .equ PINB3 =3
         .equ PINB2 =2
         .equ PINB1 =1
         .equ PINB0 =0
       
         .equ PC7 =7
         .equ PC6 =6
         .equ PC5 =5
         .equ PC4 =4
         .equ PC3 =3
         .equ PC2 =2
         .equ PC1 =1
         .equ PC0 =0
       
         .equ DDC7 =7
         .equ DDC6 =6
         .equ DDC5 =5
         .equ DDC4 =4
         .equ DDC3 =3
         .equ DDC2 =2
         .equ DDC1 =1
         .equ DDC0 =0
       
         .equ PINC7 =7
         .equ PINC6 =6
         .equ PINC5 =5
         .equ PINC4 =4
         .equ PINC3 =3
         .equ PINC2 =2
         .equ PINC1 =1
         .equ PINC0 =0
       
         .equ PD7 =7
         .equ PD6 =6
         .equ PD5 =5
         .equ PD4 =4
         .equ PD3 =3
         .equ PD2 =2
         .equ PD1 =1
         .equ PD0 =0
       
         .equ DDD7 =7
         .equ DDD6 =6
         .equ DDD5 =5
         .equ DDD4 =4
         .equ DDD3 =3
         .equ DDD2 =2
         .equ DDD1 =1
         .equ DDD0 =0
       
         .equ PIND7 =7
         .equ PIND6 =6
         .equ PIND5 =5
         .equ PIND4 =4
         .equ PIND3 =3
         .equ PIND2 =2
         .equ PIND1 =1
         .equ PIND0 =0
       
         .equ SPIE =7
         .equ SPE =6
         .equ DORD =5
         .equ MSTR =4
         .equ CPOL =3
         .equ CPHA =2
         .equ SPR1 =1
         .equ SPR0 =0
       
         .equ SPIF =7
         .equ WCOL =6
       
         .equ RXC =7
         .equ TXC =6
         .equ UDRE =5
         .equ FE =4
         .equ OR =3
       
         .equ RXCIE =7
         .equ TXCIE =6
         .equ UDRIE =5
         .equ RXEN =4
         .equ TXEN =3
         .equ CHR9 =2
         .equ RXB8 =1
         .equ TXB8 =0
       
         .equ ACD =7
         .equ ACO =5
         .equ ACI =4
         .equ ACIE =3
         .equ ACIC =2
         .equ ACIS1 =1
         .equ ACIS0 =0
       
         .def XL =r26
         .def XH =r27
         .def YL =r28
         .def YH =r29
         .def ZL =r30
         .def ZH =r31
       
         .equ  RAMEND  =$25F;Last On-Chip SRAM Location
         .equ XRAMEND =$FFFF
         .equ E2END =$1FF
         .equ FLASHEND=$FFF
       
       
         .equ INT0addr=$001;External Interrupt0 Vector Address
         .equ INT1addr=$002;External Interrupt1 Vector Address
         .equ ICP1addr=$003;Input Capture1 Interrupt Vector Address
         .equ OC1Aaddr=$004;Output Compare1A Interrupt Vector Address
         .equ OC1Baddr=$005;Output Compare1B Interrupt Vector Address
         .equ OVF1addr=$006;Overflow1 Interrupt Vector Address
         .equ OVF0addr=$007;Overflow0 Interrupt Vector Address
         .equ SPIaddr =$008;SPI Interrupt Vector Address
         .equ URXCaddr=$009;UART Receive Complete Interrupt Vector Address
         .equ UDREaddr=$00a;UART Data Register Empty Interrupt Vector Address
         .equ UTXCaddr=$00b;UART Transmit Complete Interrupt Vector Address
         .equ ACIaddr =$00c;Analog Comparator Interrupt Vector Address
         .include "c:\atmel\project\thinkpad\2\ata_3.asm
       ;*****************************************************************************
       ;*                         IDE DRIVER V1.1                                   *
       ;*                                                                           *
       ;*                                                                           *
       ;*                                                                           *
       ;*        Copyright(C) 1999-2000 ALPHATRONIC  BY.MARC LALONDE                *
       ;*****************************************************************************
       ;      ------------->>>>> NOTE <<<<<-------------
       ;
       ;strobe the /DIOW and /DIOR lines. Normally these signals
       ;are set to 1 when not in use and to strobe the signal
       ;means to set the signal to 0 for at least 165ns and
       ;then set the signal back to 1. Also remember that the
       ;data and control lines must be valid for a clock cycle
       ;before strobing the DIOW or DIOR lines and they must be
       ;valid for another clock cycle after strobing DIOW/R.
       ;Also remember to use a clock that is slower
       ;than 8Mhz. If you use a clock faster than 8Mhz
       ;you will have to be careful with the timing requirements.
       ;In order to use an 8Mhz clock you need to strobe for
       ;2 clock cycles
       ;
       ;   Drive I/O;write strobe.
       ; Rising edge
       ;clocks data from the host data bus to
       ;a drive register or data port
       ;
       ;   Drive I/O read strobe.
       ;Falling edge
       ;enables data from a drive register or
       ;data port to host data bus.
       ;
       ; Don't use for ANY-THING  without writen permission of alphatronic .
       ;
       ;20/10/2000 15:50  bebug hardware interface (drive not respond to command )
       ;20/10/2000 17:39  first working code (identify_device working )
       ;27/10/2000 20:53  read/write sector working +adding drive command
       ;27/10/2000 22:41  work well on 2 quantum drive but fail on 2 segate ??
       ;                  maby a bad timing ??im chek this now    
       ;28/10/2000 16:35  corect a part of bug that afect segate drrive now the only
       ;                  bug on thers drive is a pinc,7 tha is alwlas 1 ??
       ;29/10/2000 21:22  adding time out timer of 4 seconde if drive command crash  
       ;
       ;*****************************************************************************
       ;
       ;                                 AT90S8515Px
       ; SIGNAL_NAME                    ______ ______                     SIGNAL_NAME
       ;      .                        |      -      |                         .
       ;   IDE DA0  -->    (TO) PB0  --| 1        40 |--   VCC                 .
       ;   IDE DA1  -->    (T1) PB1  --| 2        39 |--   PA0 LCD 7   <-> IDE DD00
       ;   IDE DA2  -->  (AIN0) PB2  --| 3        38 |--   PA1 LCD 8   <-> IDE DD01
       ;   IDE SC0- -->  (AIN1) PB3  --| 4        37 |--   PA2 LCD 9   <-> IDE DD02
       ;   IDE SC1- -->   (SS*) PB4  --| 5        36 |--   PA3 LCD 10  <-> IDE DD03
       ;      .     <--  (MOSI) PB5  --| 6        35 |--   PA4 LCD 11  <-> IDE DD04
       ;      .     -->  (MISO) PB6  --| 7        34 |--   PA5 LCD 12  <-> IDE DD05
       ;      .     <--   (SCK) PB7  --| 8        33 |--   PA6 LCD 13  <-> IDE DD06
       ;      .     -->      RESET*  ->| 9        32 |--   PA7 LCD 14  <-> IDE DD07
       ;      .     -->   (RXD) PD0  --| 10       31 |--   ICP         <--     .
       ;      .     <--   (TXD) PD1  --| 11       30 |--   ALE         -->     .
       ;   IDE RD   <--  (INT0) PD2  --| 12       29 |--   OC1B        -->     .
       ;   IDE WD   <--  (INT1) PD3  --| 13       28 |--   PC7 (A15)   <-> IDE DD08
       ;   IDE RST  <--         PD4  --| 14       27 |--   PC6 LCD 4   <-> IDE DD09
       ;      .     <--  (OC1A) PD5  --| 15       26 |--   PC5 (A13)   <-> IDE DD10
       ;   LCD 5    <--   (WR*) PD6  --| 16       25 |--   PC4 (A12)   <-> IDE DD11
       ;   LCD 6    <--   (RD*) PD7  --| 17       24 |--   PC3 (A11)   <-> IDE DD12
       ;   4.0 Mhz  -->       XTAL1  ->| 18       23 |--   PC2 (A10)   <-> IDE DD13
       ;   4.0 Mhz  <--       XTAL2  <-| 19       22 |--   PC1 (A9)    <-> IDE DD14
       ;                        GND  --| 20       21 |--   PC0 (A8)    <-> IDE DD15
       ;                               |_____________|
       ;
       ;                                   (DIP-40)
       ;
       ;LCD IS STK-200 STANDART PINOUT
       ;
       ;command suported end useing this label
       ;
       ;ata_rst         hardware hard drive reset              just call label
       ;
       ;ata_id          perfor identify_device command         just call label
       ;
       ;ata_idle        put drive in idle state                just call label
       ;
       ;ata_sleep       put drive in sleep                     just call label
       ;
       ;lba_sel         selection lba sector to do operation   must load register
       ;                sector_cnt,sector,cyl_low,cyl_hi,head  before call label
       ;                                                                  
       ;ata_read_sec    read sector designed by lba_sel        must set lba_sel first
       ;                note: the sector content is tranfered to avr ram (block1)
       ;
       ;ata_write_sec   write sector designed by lba_sel       must set lba_sel first
       ;                note: the conten of ram is copied to dirve sector (block1)
       
       ;
       ;                             |<------------ t0 ------------------------>|
       ;                       __________________________________________       |
       ;Address Valid *1 _____/                                          \________
       ;                      |<-t1->|<----------- t2 ----------->|<-t9->|      |
       ;                      |      |____________________________|<---t2i----->|_
       ;DIOR-/DIOW-      ____________/                            \_____________/
       ;                      |      |                            |      |
       ;                      |      |                    ________|__  ->|   |<-t8
       ;Write Data    *2 --------------------------------<___________>------------
       ;                      |      |                   |<--t3-->|  |       |
       ;                      |      |                          ->|t4|<-     |
       ;                      |      |                     _______|___ ____  |
       ;Read Data     *2 ---------------------------------<___________X____>------
       ;                    ->|t7|<- |                    |     ->|t6 |<-  | |
       ;                      |  | ->| tA |<-             |<-t5-->|<-t6Z-->|
       ;                      |  |___________________________________________|
       ;IOCS16-          ________/        |               |                  \____
       ;                                  |             ->|tRd|<-            |
       ;                 _________________|___________________|___________________
       ;IORDY            XXXXXXXXXXXXXXXXX____________________/
       ;                                  |<-------tB-------->|
       ;  *1 Device Address consists of signals CS0-, CS1- and DA2-0
       ;  *2 Data consists of DD0-15 (16-bit) or DD0-7 (8-bit)  
       ;
       ;
       ;t0       650ns
       ;t1       70 ns
       ;t2       165ns
       ;t3       60 ns
       ;t4       30 ns
       ;t5       50 ns
       ;t6       5  ns
       ;t7       90 ns
       ;t8       60 ns
       ;t9       20 ns
       
       ;*****************************************************************************
       ;.include "c:\atmel\inc\8515def.inc"
       
       ;diver            
         .equ   BLOCK1            =$60         ;start address of SRAM array #1
         .equ   security_status     =$160        ;security satus bit of drive
         .equ   model_number        =$94         ;model number  
         .equ   TCK1024             =5         ;Timer/Counter runs from CK / 1024
       
       ;ata-4 command
       
         .equ   identify_device     =0b11101100  ;EC HEX
         .equ   disabel_password    =0b11110110  ;F6
         .equ   freeze_lock         =0b11110101  ;F5
         .equ   set_password        =0b11110001  ;F1
         .equ   unlock              =0b11110010  ;F2
         .equ   erase_prepare       =0b11110011  ;F3
         .equ   erase_unit          =0b11110100  ;F4
         .equ   check_power_mode    =0b11100101  ;E5
         .equ   device_diagnostics  =0b10010000  ;90
         .equ   format_track        =0b01010000  ;50
         .equ   format_unit         =0b11110111  ;F7
         .equ   idel                =0b11100011  ;E3
         .equ   idel_immediate      =0b11100001  ;E1
         .equ   initialize_device   =0b10010001  ;91
         .equ   read_sector         =0b00100000  ;20
         .equ   read_long           =0b00100010  ;22
         .equ   read_long_retry     =0b00100011  ;23
         .equ   read_multiple       =0b11000100  ;C4
         .equ   read_verify         =0b01000000  ;40
         .equ   read_verity_retry   =0b01000001  ;41
         .equ   recalibrate         =0b          ;1x
         .equ   seek                =0b          ;7x
         .equ   set_features        =0b11101111  ;EF
         .equ   set_max_address     =0b11111001  ;F9
         .equ   set_multiple_mode   =0b11000110  ;C6
         .equ   sleep               =0b11100110  ;E6
         .equ   standby             =0b11100010  ;E2
         .equ   standby_immediate   =0b11100000  ;E0
         .equ   write_long          =0b00110010  ;32
         .equ   write_long_retry    =0b00110011  ;33
         .equ   write_sectors_retry =0b00110000  ;30
         .equ   write_sector        =0b00110001  ;31
         .equ   write_verity        =0b00111100  ;3C        
       
       ;ata-4 register                            bit mask of register
                                                   
       ;command block register                 n\c n\c n\c SC1- SC0- DA2 DA1 DA0
         .equ   feature             =0b00010001
         .equ   sector_cont         =0b00010010      
         .equ   sector_number       =0b00010011
         .equ   cylinder_low        =0b00010100
         .equ   cylinder_high       =0b00010101
         .equ   device_head         =0b00010110
         .equ   command             =0b00010111  ;write
         .equ   status              =0b00010111  ;read
         .equ   data                =0b00010000
         .equ   error               =0b00010001
       
       ;control block registers
         .equ   alternate_status    =0b00010110
         .equ   device control      =0b00010110
       
         .equ   master              =0b11100000
         .equ   slave               =0b10100000
         .equ   user_pwd            =0b00000000
         .equ   master_pwd          =0b00000001
         
       ;pin direct
         .equ   rd           =   5
         .equ   wd           =   4
         .equ   rst          =   3
       
       ;***** Main Program Register variables
       
         .def   chr_1        =   r2              ;pasword character 1 in  asci
         .def   chr_2        =   r3
         .def   chr_3        =   r4
         .def   chr_4        =   r5              ;        to
         .def   chr_5        =   r6
         .def   chr_6        =   r7
         .def   chr_7        =   r8              ;password character 7
       
         .def   delay        =   r17
         .def   Counter     = r16             ;used as character counter
         .def   temp         =   r17
         .def   drv_status   =   r18
         .def   sector       =   r19             ;in LBA =bits 0  - 7
         .def   cyl_low      =   r20             ;in LBA =bits 8  - 15
         .def   cyl_hi       =   r21             ;in LBA =bits 16 - 23
         .def   head         =   r22             ;in LBA =bits 23 - 30
         .def   ata_command  =   r23
         .def   sector_cnt   =   r24
       
       ;*****************************************************************************
       ;* ATA COMMAND LIST                                           *
       ;*****************************************************************************
       
         .org 100  
           
         ata_rst:
                 
000064 d10e              rcall   delay4ms                ;whait voltage stab
000065 9893              cbi     portd,rst               ;put drive in reset
000066 d10c              rcall   delay4ms                ;whait voltage stab
000067 9a93              sbi     portd,rst               ;put drive in working mode
000068 d0a8              rcall   ata_stat
         
               
         ata_pio:
       
000069 ef1f              ldi     temp,255                ;put data bus as ouput
00006a bb1a              out     ddra,temp
00006b e111              ldi     temp,feature            ;select  registe
00006c bb18              out     portb,temp          
00006d 9894              cbi     portd,wd                ;selection pio mode
00006e e013              ldi     temp,0b00000011                  
00006f bb1b              out     porta,temp              ;select master drive
000070 9a94              sbi     portd,wd
000071 e112              ldi     temp,sector_cont        ;select  registe
000072 bb18              out     portb,temp          
000073 9894              cbi     portd,wd                ;write data to resister of drive
000074 e011              ldi     temp,0b00000001                  
000075 bb1b              out     porta,temp              ;pio mode = 0
000076 9a94              sbi     portd,wd
000077 e116              ldi     temp,device_head        ;select  registe
000078 bb18              out     portb,temp          
000079 9894              cbi     portd,wd  
00007a ee10              ldi     temp,master                  
00007b bb1b              out     porta,temp              ;select master drive
00007c 9a94              sbi     portd,wd
00007d e117              ldi     temp,command            ;select register  
00007e bb18              out     portB,temp          
00007f 9894              cbi     portD,wd                ;write comend
000080 ee1f              ldi     temp,set_features    
000081 bb1b              out     porta,temp          
000082 9a94              sbi     portd,wd
000083 d08d              rcall   ata_stat
000084 9508              ret  
                   
         ata_id:
       
000085 ee7c              ldi     ata_command,identify_device
000086 d0a2              rcall   set_command
000087 d069              rcall   ata_stat2        
000088 e0d0              ldi YH,high(BLOCK1)         ;init Y-pointer to start of sram
000089 e6c0       ldi YL,low(BLOCK1)
00008a d0ac              rcall   read_buffer
00008b d085              rcall   ata_stat
00008c 9508              ret
       
         ata_disable_pwd:
       
00008d ef76              ldi     ata_command,disabel_password
00008e d09a              rcall   set_command
00008f d061              rcall   ata_stat2
000090 e0d0              ldi YH,high(BLOCK1)         ;init Y-pointer to start of sram
000091 e6c0       ldi YL,low(BLOCK1)
000092 d0be              rcall   write_buffer
000093 d07d              rcall   ata_stat
000094 9508              ret
               
         ata_unlock:
       
000095 ef72              ldi     ata_command,unlock
000096 d092              rcall   set_command
000097 d059              rcall   ata_stat2
000098 e0d0              ldi YH,high(BLOCK1)         ;init Y-pointer to start of sram
000099 e6c0       ldi YL,low(BLOCK1)
00009a d0b6              rcall   write_buffer
00009b d075              rcall   ata_stat
00009c 9508              ret
         
         ata_set_pwd:
                           
00009d ef71              ldi     ata_command,set_password
00009e d08a              rcall   set_command
00009f d051              rcall   ata_stat2
0000a0 e0d0              ldi YH,high(BLOCK1)         ;init Y-pointer to start of sram
0000a1 e6c0       ldi YL,low(BLOCK1)
0000a2 d0ae              rcall   write_buffer
0000a3 d06d              rcall   ata_stat
0000a4 9508              ret
       
       
         ata_idle:
       
0000a5 ee71              ldi     ata_command,idel_immediate
0000a6 d082 &

Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.