Full Version : Compact Flash & Hardisk Library (BASCOM)
avr >>BASIC & OTHER AVR LANGUAGES >>Compact Flash & Hardisk Library (BASCOM)


Admin3- 04-17-2006
AVR-DOS (BASCOM)

Driver-Library for CompactFlash-Card and Hard Disk: CF_HD.Lib / CF_HD.LBX

CODE

;Driver-Library for CompactFlash-Card and Hard Disk:
;FILE:CF_HD.Lib
.equ Ata_Reg_data = 0
.equ Ata_Reg_error = 1
.equ Ata_Reg_features = 1
.equ Ata_Reg_sectorcnt = 2
.equ Ata_Reg_sectornum = 3
.equ Ata_Reg_cyl_l = 4
.equ Ata_Reg_cyl_h = 5
.equ Ata_Reg_device_head = 6
.equ Ata_Reg_status = 7
.equ Ata_Reg_cmd = 7


; ATA Commands
.equ ATA_Cmd_Identify = &HEC
.equ ATA_Cmd_Write_Sec = &H30
.equ ATA_Cmd_Read_Sec = &H20
.equ ATA_Cmd_Recalibrate = &H10
.equ ATA_Drive0 = &HE0

; Register Usage
; r20: Timer - low byte
; r21: Timer - High Byte
; r22: Data Byte / ATA-command
; r23: ATA-register-address (Control-port setting)
; r24: Temporary
; r25: Error-code

;------------------------------------------------------------------------------
[_DriveGetIdentity]
$EXTERNAL _Drive_Write_Reg, _DriveClearErrorBytes
; Read Identity Info from the Drive
_DriveGetIdentity:
  rcall _Drive_Check_Command          ; check ready for new command
  brcs _DriveGetIdentity9             ; Error?
  ldi r23, Ata_Reg_device_head
  ldi r22, Ata_Drive0
  rcall _Drive_Write_Reg
  ldi r22, ATA_Cmd_Identify           ; Command for Drive identity
  rcall _Drive_Write_CommandReg       ; send to Drive
  rjmp _Drive_Read_Sector_LBASet      ; Read Info to SRAM (mit return)
_DriveGetIdentity9:
  ret
[End]



[_Drive_Check_Ready]
$EXTERNAL _DriveClearErrorBytes
_Drive_Check_Command:
  rcall _Drive_Check_Busy
  brcc _Drive_Check_Command0
*  cpi r25, cpErrDriveError
  brne _Drive_Check_EndError9
_Drive_Check_Command0:
  rcall _Drive_Check_LoadTimer
_Drive_Check_Command1:
  rcall _Drive_Set_RegAddrStatus      ; not necessary in every loop but increases loop time
  rcall _Drive_Read
  andi r22, &H50
  cpi r22, &H50
  breq _Drive_Check_OK
  rcall _Drive_Check_us10
  subi r20, 1                         ; decr. Timer by 1
  sbci r21, 0
  brne _Drive_Check_Command1
*  ldi r25 , cpErrDriveTimeOutCommand
  rjmp _Drive_Check_EndError9

_Drive_Check_Data:
  rcall _Drive_Check_Busy
  brcs _Drive_Check_EndError9
  rcall _Drive_Check_LoadTimer
_Drive_Check_Data1:
  rcall _Drive_Set_RegAddrStatus      ; set status register address
  rcall _Drive_Read
  andi r22, &H58
  cpi r22, &H58
  breq _Drive_Check_OK
  rcall _Drive_Check_us10
  subi r20, 1                         ; decr. Timer by 1
  sbci r21, 0
  brne _Drive_Check_Data1
*  ldi r25 , cpErrDriveTimeOutData
  rjmp _Drive_Check_EndError9
_Drive_Check_OK:
  clr r25                             ; additional if use from outside
  clc
  ret

_Drive_Check_Busy:
  rcall _DriveClearErrorBytes
  rcall _Drive_Check_LoadTimer
_Drive_Check_Busy1:
  rcall _Drive_Set_RegAddrStatus      ; Set Status Address register
  rcall _Drive_Read                   ; read status register
;   andi r22, &H81                      ; Busy(7) and Error(0)-Bit
;   cpi r22, &H80                       ; Busy?
;   brne _Drive_CHECK_Busy2
  sbrs r22, 7                           ; Busy
  rjmp _Drive_Check_Busy2
  rcall _Drive_Check_us10
  subi r20, 1                         ; decr. timer by 1
  sbci r21, 0
  brne _Drive_Check_Busy1
*  ldi r25 , cpErrDriveTimeOutBusy
  rjmp _Drive_Check_EndError9

_Drive_Check_Busy2:
  andi r22, &H01                      ; check Error(0)-Bit
  breq  _Drive_Check_OK
*  ldi r25 , cpErrDriveError
_Drive_Check_EndError9:
; store Status and Error from drive to debug-Bytes
  push r25
  rcall _Drive_Set_RegAddrStatus
  rcall _Drive_Read
*  sts {gbDriveStatusReg}, r22
  ldi r23, Ata_Reg_error
  rcall _Drive_Set_RegAddr
  rcall _Drive_Read
*  sts {gbDriveErrorReg}, r22
  pop r25
_Drive_Check_EndError10:
*  sts {gbDriveError}, r25
  sec
  ret

_Drive_Check_LoadTimer:
  clr r20                             ; do not touch r16-r19
  clr r21                             ; load with 0 for max time = 2^16 cycles
_Drive_Check_LoadTimer9:
  ret
_Drive_Check_US10:
;   @genus(10)
*  ldi r25, ( (_XTAL * 10) / 3000000 ) ; loop needs 3
_Drive_Check_US10a:
  dec r25
  brne _Drive_Check_US10a
  ret
[END]



[_Drive_Write]
$EXTERNAL _Drive_Check_Ready
; give a pulse to WE to force Compactflash Drive to read Data
; Registeraddress (A0-A2) and Data (D0-D7) must be set
_Drive_Write:

*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Reset ATA_Port_CS0
*#ELSE
  *BASIC: Set ATA_Port_CS0
*#ENDIF

*BASIC: Reset ATA_Port_DIOW                 ;
  @genus(0.5)
*BASIC: Set ATA_Port_DIOW

*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Set ATA_Port_CS0
*#ELSE
  *BASIC: Reset ATA_Port_CS0
*#ENDIF

  ret
[END]



[_Drive_Read]
$EXTERNAL _Drive_Check_Ready
; Read Low Byte from the HardDisk (for Harddisk register)
; Register address must be set.
_Drive_Read:
*BASIC: Config ATA_Data_Low = Input

*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Input
*#ENDIF

*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Reset ATA_Port_CS0
*#ELSE
  *BASIC: Set ATA_Port_CS0
*#ENDIF

*BASIC: Reset ATA_Port_DIOR
  @genus(0.5)
*BASIC: _B3 = ATA_Data_Low_In               ; = r22
*BASIC: Set ATA_Port_DIOR

*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Set ATA_Port_CS0
*#ELSE
  *BASIC: Reset ATA_Port_CS0
*#ENDIF

*BASIC: Config ATA_Data_Low = Output

*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Output
*#ENDIF

  ret
[END]



[_Drive_Set_RegAddr]
; Set register address
; two entry-points to routine
; 1: Drive_Set_RegAddr: Register address must passed in r23
; 2: Drive_Set_RegAddrData: register address is Data
; 3. Drive_Set_RegAddrStatus: register address is Status
_Drive_Set_RegAddrStatus:
  ldi r23, ATA_Reg_Status
  rjmp _Drive_Set_RegAddr             ; set status register address
_Drive_Set_RegAddrData:
  ldi r23, Ata_Reg_data
_Drive_Set_RegAddr:
 ; Save r23 to r0, because Set, Reset uses r23 on extended I/O
  mov r0, r23
 ; DA0
  bst r0, 0
  brtc _Drive_Set_RegAddr1
*BASIC: Set ATA_Port_DA0
  rjmp _Drive_Set_RegAddr2
_Drive_Set_RegAddr1:
*BASIC: Reset ATA_Port_DA0
_Drive_Set_RegAddr2:
 ; DA1
  bst r0, 1
  brtc _Drive_Set_RegAddr3
*BASIC: Set ATA_Port_DA1
  rjmp _Drive_Set_RegAddr4
_Drive_Set_RegAddr3:
*BASIC: Reset ATA_Port_DA1
_Drive_Set_RegAddr4:
 ; DA2
  bst r0, 2
  brtc _Drive_Set_RegAddr5
*BASIC: Set ATA_Port_DA2
  rjmp _Drive_Set_RegAddr6
_Drive_Set_RegAddr5:
*BASIC: Reset ATA_Port_DA2
_Drive_Set_RegAddr6:
  ret
[End]



[_DriveReadSector]
$EXTERNAL _Drive_Set_CntLBA , _Drive_Write_Reg , _Drive_Read
$EXTERNAL _DriveClearErrorBytes
; Read Sector(s) from Drive-Drive to SRAM
; Entry with following parameters set:
; Register r21: Count of Sector(s) to transfer
; Register X: Pointer to Sectornumber (LONG)
; Register Z: SRAM-Address, where the data to transfer
_DriveReadSector:
  rcall _Drive_Check_Command
  brcs _DriveReadSector9              ; Error?
  rcall _Drive_Set_CntLBA             ; LBA-Sector to Drive
  ldi r22, ATA_Cmd_Read_Sec           ; read command
  rcall _Drive_Write_CommandReg       ; to Compactflash
_Drive_Read_Sector_LBASet:
  rcall _Drive_Check_Data
  brcs _DriveReadSector9              ; Error?
  rcall _Drive_Set_RegAddrData        ; turn register-address to data
  clr r20                             ; Counter for 256 Word to read

*#IF ATA_DataBits = 16
  ldi r21, 1                           ; Counter for 256 Word to read
*#ELSE
  ldi r21, 2                           ; Counter for 512 Bytes to read
*#ENDIF

*BASIC: Config ATA_Data_Low = Input

*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Input
*#ENDIF

*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Reset ATA_Port_CS0
*#ELSE
  *BASIC: Set ATA_Port_CS0
*#ENDIF

_Drive_Read_Sector1:
*BASIC: Reset ATA_Port_DIOR
  @genus(0.5)
*BASIC: _B3 = ATA_Data_Low_In
*  st Z+, _B3

*#IF ATA_DataBits = 16
  *BASIC: _B3 = ATA_Data_high_In
  *  st Z+, _B3
*#ENDIF

*BASIC: Set ATA_Port_DIOR
  subi r20, 1
  sbci r21, 0
  brne  _Drive_READ_SECTOR1

*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Set ATA_Port_CS0
*#ELSE
  *BASIC: Reset ATA_Port_CS0
*#ENDIF

*BASIC: Config ATA_Data_Low = Output

*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Output
*#ENDIF

  clr r25                             ; set default no error
  clc
_DriveReadSector9:
  Ret
[END]



[_DriveWriteSector]
$EXTERNAL _Drive_Set_CntLBA , _Drive_Write_Reg
$EXTERNAL _DriveClearErrorBytes
; write Sector(s) to Drive-Card
; Entry with following parameter set:
; Register r21: Count of sector(s) to transfer
; Register X: Pointer to Sectornumber (LONG)
; Register Z: SRAM-Address, at which Data to transfer starts
_DriveWriteSector:
  rcall _Drive_Check_Command
  brcs _DriveWriteSector9             ; Error?
  rcall _Drive_Set_CntLBA             ; LBA-Sector to Drive
  ldi r22, ATA_Cmd_Write_Sec          ; write command
  rcall _Drive_Write_CommandReg       ; to compactflash
_Drive_Write_Sector_LBASet:
  rcall _Drive_Check_Data
  brcs _DriveWriteSector9             ; Error?
  rcall _Drive_Set_RegAddrData        ; turn register-address to data
  clr r20                             ; &H100 or &H200 to count, Low Byte = 0

*#IF ATA_DataBits = 16
  ldi r21, 1                           ; Counter for 256 Word to read
*#ELSE
  ldi r21, 2                           ; Counter for 512 Bytes to read
*#ENDIF

*BASIC: Config ATA_Data_Low = Output

*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Output
*#ENDIF

*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Reset ATA_Port_CS0
*#ELSE
  *BASIC: Set ATA_Port_CS0
*#ENDIF

_Drive_Write_Sector1:
  ld r22, z+                          ; low byte
*BASIC: ATA_Data_Low = _B3             ; Low Byte to data port

*#IF ATA_DataBits = 16
  ld r22, Z+                          ; high byte
*BASIC: ATA_Data_high = _B3            ; High Byte to data port
*#ENDIF

*BASIC: Reset ATA_Port_DIOW
  @genus(0.5)
*BASIC: Set ATA_Port_DIOW
  subi r20, 1
  sbci r21, 0
  brne  _Drive_Write_SECTOR1          ; last Word written?

*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Set ATA_Port_CS0
*#ELSE
  *BASIC: Reset ATA_Port_CS0
*#ENDIF
  rcall _Drive_Check_Busy
;   clr r25                             ; set default no error
;   clc
_DriveWriteSector9:
  Ret
[END]



[_Drive_Write_Reg]
$EXTERNAL _Drive_Set_RegAddr , _Drive_Write
;------------------------------------------------------------------------------
; write a value to a specified register address, value is passed in r22
; two different entry points
; 1: Drive_Write_CommandReg: write value to command-register (default)
; 2: Drive_Write_Reg: Register passed in r22
_Drive_Write_CommandReg:
  ldi r23, Ata_Reg_cmd                ; Default register: Command
_Drive_Write_Reg:
  rcall _Drive_Set_RegAddr
*BASIC: ATA_Data_Low = _B3
  rjmp _Drive_Write                   ; force Drive to accept register and data
[End]



[_Drive_Set_CntLBA]
$EXTERNAL _Drive_Write_Reg
; Write Sectornumber (LBA) to Drive-Card (fix for 1 sector)
; following parameter must be set:
; Register X: Pointer to sectornumber
;
_Drive_Set_CntLBA:
  ldi r22, 1                          ; 1 sector to read or write
  ldi r23, Ata_Reg_SectorCnt
  rcall _Drive_Write_Reg
  ld r22, X+                          ; load LSB of Sector number
  ldi r23, ATA_Reg_SectorNum
  rcall _Drive_Write_Reg
  ld r22, X+                          ; load 2.Byte of Sector number
  ldi r23, ATA_Reg_Cyl_l
  rcall _Drive_Write_Reg
  ld r22, X+                          ; load 3.Byte of Sector number
  ldi r23, ATA_Reg_Cyl_h
  rcall _Drive_Write_Reg
  ld r22, X+                          ; load MSB of Sector number
  ldi r23, ATA_Reg_device_head
  andi r22, &H0F                      ; only bit 0 to 3 valid for head
  ori r22, Ata_Drive0                 ; set Bit 4 to 7 (Drive 0 and LBA Mode)
  rjmp _Drive_Write_Reg
[END]



[_DriveInit]
$EXTERNAL _DriveReset, _Drive_Check_ready, _DriveCheck
$EXTERNAL _DriveClearErrorBytes
; Setup the pins needed for the Drive-Card
_DriveInit:
  rcall _DriveClearErrorBytes
 ; Data ports to LOW
*BASIC: Config ATA_Data_Low = OutPut

*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Output
*#ENDIF

*#IF ATA_Reset_ActiveLevel = 0
  *BASIC: Set ATA_Port_Reset
*#ELSE
  *BASIC: Reset ATA_Port_Reset
*#ENDIF

*#IF ATA_Reset_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_Reset = Output
*#ENDIF

*BASIC: Set ATA_Port_CS0
*#IF ATA_CS0_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_CS0 = Output
*#ENDIF

*#IF ATA_CS1_Connected = 1
*BASIC: Set ATA_Port_CS1
*#IF ATA_CS1_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_CS1 = Output
  *BASIC: Set ATA_Pin_CS1
*#ENDIF
*#ENDIF

*BASIC: Set ATA_Port_DIOR
*#IF ATA_DIOR_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_DIOR = Output
*#ENDIF

*BASIC: Set ATA_Port_DIOW
*#IF ATA_DIOW_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_DIOW = Output
*#ENDIF

*#IF ATA_DA0_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_DA0 = Output
*#ENDIF

*#IF ATA_DA1_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_DA1 = Output
*#ENDIF

*#IF ATA_DA2_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_DA2 = Output
*#ENDIF

*#IF ATA_CD1_Connected = 1
  * #IF ATA_CD1_PortInputOnly = 0
     *BASIC: Set ATA_Port_CD1
     *BASIC: Config ATA_Pin_CD1 = Input
  *#ENDIF
*#ENDIF

  ldi r24, 1                          ; wait 1 ms
  clr r25
  call _Waitms                        ; 1 ms delay
  rcall _DriveCheck
  brcc _DriveInit1
  ret                             ; Error, Drive not attached
_DriveInit1:
  rjmp _DriveReset1
[End]



[_DriveReset]
$EXTERNAL _DriveClearErrorBytes
;------------------------------------------------------------------------------
; force Drive-Card to a Hardware-reset
_DriveReset:
*#IF ATA_Reset_Connected = 1
  rcall _DriveClearErrorBytes
_DriveReset1:
  ldi r24, 42                         ; time out for spinning up: 31Sec./0.75
_DriveReset2:
  push r24
  rcall _Drive_Check_Command          ; needs appr. 0.75 Sec. if busy
  pop r24
  brcc _DriveReset3
  dec r24
  brne _DriveReset2
  sec                                 ; Error sign
  rjmp _DriveReset9

_DriveReset3:
*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Reset ATA_Port_CS0
*#ELSE
  *BASIC: Set ATA_Port_CS0
*#ENDIF

*#IF ATA_Reset_ActiveLevel = 0
  *BASIC: Reset ATA_Port_Reset
*#ELSE
  *BASIC: Set ATA_Port_Reset
*#ENDIF

  ldi r24, 10                         ; wait 10 ms
  clr r25
  call _Waitms                       ; 1 ms delay

*#IF ATA_Reset_ActiveLevel = 0
  *BASIC: Set ATA_Port_Reset
*#ELSE
  *BASIC: Reset ATA_Port_Reset
*#ENDIF

*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Set ATA_Port_CS0
*#ELSE
  *BASIC: Reset ATA_Port_CS0
*#ENDIF

*  ldi r24 , lByte(waitms_afterReset)  ;
*  ldi r25 , hByte(waitms_afterReset)  ;
  call _Waitms
  rcall _Drive_Check_Command
  brcs _DriveReset9
; recalibrate set LBA Address to 0
  clr r16
  clr r17
  clr r18
  clr r19
  rcall _Drive_Set_CntLBA

  ldi r22, ATA_Cmd_Recalibrate        ; recalibrate command

  rcall _Drive_Write_CommandReg       ;

  ldi r24, 200                        ; 100 msec delay
  clr r25
  call _Waitms

  rcall _Drive_Check_Command
  brcs _DriveReset9
*#ELSE
_DriveReset1:
*#ENDIF
  clr r25                             ; set default no error
  clc

_DriveReset9:
  ret
[End]



[_DriveCheck]
$EXTERNAL _DriveClearErrorBytes, _Drive_Check_Ready
;------------------------------------------------------------------------------
; Checks, whether Drive is plugged in: Pin CD1 is LOW
; if OK r24 = 1; otherwise 0
_DriveCheck:
  rcall _DriveClearErrorBytes
*#IF ATA_CD1_Connected = 1
; next Basic statement affects XL and XH, but have no impact here
*BASIC: _temp1 = ATA_Pin_CD1
  sbrs _temp1, 0
  rjmp _DriveCheck1
*  ldi r25, cpErrDriveNotPresent
  rjmp _Drive_Check_EndError10
*#ENDIF
_DriveCheck1:
  clr r25
  clc
  ret
[END]


[_DriveClearErrorBytes]
_DriveClearErrorBytes:
  clr r24
*  sts {gbDriveError}, r24
*  sts {gbDriveStatusReg}, r24
*  sts {gbDriveErrorReg}, r24
  ret
[end]

;========================================

;Driver-Library for CompactFlash-Card and Hard Disk:
;FILE: CF_HD.LBX

Comment = Compiled LIB file, no comment included

.equ Ata_Reg_data = 0
.equ Ata_Reg_error = 1
.equ Ata_Reg_features = 1
.equ Ata_Reg_sectorcnt = 2
.equ Ata_Reg_sectornum = 3
.equ Ata_Reg_cyl_l = 4
.equ Ata_Reg_cyl_h = 5
.equ Ata_Reg_device_head = 6
.equ Ata_Reg_status = 7
.equ Ata_Reg_cmd = 7
.equ ATA_Cmd_Identify = &HEC
.equ ATA_Cmd_Write_Sec = &H30
.equ ATA_Cmd_Read_Sec = &H20
.equ ATA_Cmd_Recalibrate = &H10
.equ ATA_Drive0 = &HE0
[_DriveGetIdentity]
$EXTERNAL _Drive_Write_Reg, _DriveClearErrorBytes
_DriveGetIdentity:
  rcall _Drive_Check_Command
  brcs _DriveGetIdentity9
.OBJ E076
.OBJ EE60
  rcall _Drive_Write_Reg
.OBJ EE6C
  rcall _Drive_Write_CommandReg
  rjmp _Drive_Read_Sector_LBASet
_DriveGetIdentity9:
.OBJ 9508
[End]
[_Drive_Check_Ready]
$EXTERNAL _DriveClearErrorBytes
_Drive_Check_Command:
  rcall _Drive_Check_Busy
  brcc _Drive_Check_Command0
*  cpi r25, cpErrDriveError
  brne _Drive_Check_EndError9
_Drive_Check_Command0:
  rcall _Drive_Check_LoadTimer
_Drive_Check_Command1:
  rcall _Drive_Set_RegAddrStatus
  rcall _Drive_Read
.OBJ 7560
.OBJ 3560
  breq _Drive_Check_OK
  rcall _Drive_Check_us10
.OBJ 5041
.OBJ 4050
  brne _Drive_Check_Command1
*  ldi r25 , cpErrDriveTimeOutCommand
  rjmp _Drive_Check_EndError9
_Drive_Check_Data:
  rcall _Drive_Check_Busy
  brcs _Drive_Check_EndError9
  rcall _Drive_Check_LoadTimer
_Drive_Check_Data1:
  rcall _Drive_Set_RegAddrStatus
  rcall _Drive_Read
.OBJ 7568
.OBJ 3568
  breq _Drive_Check_OK
  rcall _Drive_Check_us10
.OBJ 5041
.OBJ 4050
  brne _Drive_Check_Data1
*  ldi r25 , cpErrDriveTimeOutData
  rjmp _Drive_Check_EndError9
_Drive_Check_OK:
.OBJ 2799
.OBJ 9488
.OBJ 9508
_Drive_Check_Busy:
  rcall _DriveClearErrorBytes
  rcall _Drive_Check_LoadTimer
_Drive_Check_Busy1:
  rcall _Drive_Set_RegAddrStatus
  rcall _Drive_Read
.OBJ FF67
  rjmp _Drive_Check_Busy2
  rcall _Drive_Check_us10
.OBJ 5041
.OBJ 4050
  brne _Drive_Check_Busy1
*  ldi r25 , cpErrDriveTimeOutBusy
  rjmp _Drive_Check_EndError9
_Drive_Check_Busy2:
.OBJ 7061
  breq  _Drive_Check_OK
*  ldi r25 , cpErrDriveError
_Drive_Check_EndError9:
.OBJ 939F
  rcall _Drive_Set_RegAddrStatus
  rcall _Drive_Read
*  sts {gbDriveStatusReg}, r22
.OBJ E071
  rcall _Drive_Set_RegAddr
  rcall _Drive_Read
*  sts {gbDriveErrorReg}, r22
.OBJ 919F
_Drive_Check_EndError10:
*  sts {gbDriveError}, r25
.OBJ 9408
.OBJ 9508
_Drive_Check_LoadTimer:
.OBJ 2744
.OBJ 2755
_Drive_Check_LoadTimer9:
.OBJ 9508
_Drive_Check_US10:
*  ldi r25, ( (_XTAL * 10) / 3000000 )
_Drive_Check_US10a:
.OBJ 959A
  brne _Drive_Check_US10a
.OBJ 9508
[END]
[_Drive_Write]
$EXTERNAL _Drive_Check_Ready
_Drive_Write:
*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Reset ATA_Port_CS0
*#ELSE
  *BASIC: Set ATA_Port_CS0
*#ENDIF
*BASIC: Reset ATA_Port_DIOW
  @genus(0.5)
*BASIC: Set ATA_Port_DIOW
*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Set ATA_Port_CS0
*#ELSE
  *BASIC: Reset ATA_Port_CS0
*#ENDIF
.OBJ 9508
[END]
[_Drive_Read]
$EXTERNAL _Drive_Check_Ready
_Drive_Read:
*BASIC: Config ATA_Data_Low = Input
*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Input
*#ENDIF
*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Reset ATA_Port_CS0
*#ELSE
  *BASIC: Set ATA_Port_CS0
*#ENDIF
*BASIC: Reset ATA_Port_DIOR
  @genus(0.5)
*BASIC: _B3 = ATA_Data_Low_In
*BASIC: Set ATA_Port_DIOR
*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Set ATA_Port_CS0
*#ELSE
  *BASIC: Reset ATA_Port_CS0
*#ENDIF
*BASIC: Config ATA_Data_Low = Output
*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Output
*#ENDIF
.OBJ 9508
[END]
[_Drive_Set_RegAddr]
_Drive_Set_RegAddrStatus:
.OBJ E077
  rjmp _Drive_Set_RegAddr
_Drive_Set_RegAddrData:
.OBJ E070
_Drive_Set_RegAddr:
.OBJ 2E07
.OBJ FA00
  brtc _Drive_Set_RegAddr1
*BASIC: Set ATA_Port_DA0
  rjmp _Drive_Set_RegAddr2
_Drive_Set_RegAddr1:
*BASIC: Reset ATA_Port_DA0
_Drive_Set_RegAddr2:
.OBJ FA01
  brtc _Drive_Set_RegAddr3
*BASIC: Set ATA_Port_DA1
  rjmp _Drive_Set_RegAddr4
_Drive_Set_RegAddr3:
*BASIC: Reset ATA_Port_DA1
_Drive_Set_RegAddr4:
.OBJ FA02
  brtc _Drive_Set_RegAddr5
*BASIC: Set ATA_Port_DA2
  rjmp _Drive_Set_RegAddr6
_Drive_Set_RegAddr5:
*BASIC: Reset ATA_Port_DA2
_Drive_Set_RegAddr6:
.OBJ 9508
[End]
[_DriveReadSector]
$EXTERNAL _Drive_Set_CntLBA , _Drive_Write_Reg , _Drive_Read
$EXTERNAL _DriveClearErrorBytes
_DriveReadSector:
  rcall _Drive_Check_Command
  brcs _DriveReadSector9
  rcall _Drive_Set_CntLBA
.OBJ E260
  rcall _Drive_Write_CommandReg
_Drive_Read_Sector_LBASet:
  rcall _Drive_Check_Data
  brcs _DriveReadSector9
  rcall _Drive_Set_RegAddrData
.OBJ 2744
*#IF ATA_DataBits = 16
.OBJ E051
*#ELSE
.OBJ E052
*#ENDIF
*BASIC: Config ATA_Data_Low = Input
*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Input
*#ENDIF
*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Reset ATA_Port_CS0
*#ELSE
  *BASIC: Set ATA_Port_CS0
*#ENDIF
_Drive_Read_Sector1:
*BASIC: Reset ATA_Port_DIOR
  @genus(0.5)
*BASIC: _B3 = ATA_Data_Low_In
*  st Z+, _B3
*#IF ATA_DataBits = 16
  *BASIC: _B3 = ATA_Data_high_In
  *  st Z+, _B3
*#ENDIF
*BASIC: Set ATA_Port_DIOR
.OBJ 5041
.OBJ 4050
  brne  _Drive_READ_SECTOR1
*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Set ATA_Port_CS0
*#ELSE
  *BASIC: Reset ATA_Port_CS0
*#ENDIF
*BASIC: Config ATA_Data_Low = Output
*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Output
*#ENDIF
.OBJ 2799
.OBJ 9488
_DriveReadSector9:
.OBJ 9508
[END]
[_DriveWriteSector]
$EXTERNAL _Drive_Set_CntLBA , _Drive_Write_Reg
$EXTERNAL _DriveClearErrorBytes
_DriveWriteSector:
  rcall _Drive_Check_Command
  brcs _DriveWriteSector9
  rcall _Drive_Set_CntLBA
.OBJ E360
  rcall _Drive_Write_CommandReg
_Drive_Write_Sector_LBASet:
  rcall _Drive_Check_Data
  brcs _DriveWriteSector9
  rcall _Drive_Set_RegAddrData
.OBJ 2744
*#IF ATA_DataBits = 16
.OBJ E051
*#ELSE
.OBJ E052
*#ENDIF
*BASIC: Config ATA_Data_Low = Output
*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Output
*#ENDIF
*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Reset ATA_Port_CS0
*#ELSE
  *BASIC: Set ATA_Port_CS0
*#ENDIF
_Drive_Write_Sector1:
.OBJ 9161
*BASIC: ATA_Data_Low = _B3
*#IF ATA_DataBits = 16
.OBJ 9161
*BASIC: ATA_Data_high = _B3
*#ENDIF
*BASIC: Reset ATA_Port_DIOW
  @genus(0.5)
*BASIC: Set ATA_Port_DIOW
.OBJ 5041
.OBJ 4050
  brne  _Drive_Write_SECTOR1
*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Set ATA_Port_CS0
*#ELSE
  *BASIC: Reset ATA_Port_CS0
*#ENDIF
  rcall _Drive_Check_Busy
_DriveWriteSector9:
.OBJ 9508
[END]
[_Drive_Write_Reg]
$EXTERNAL _Drive_Set_RegAddr , _Drive_Write
_Drive_Write_CommandReg:
.OBJ E077
_Drive_Write_Reg:
  rcall _Drive_Set_RegAddr
*BASIC: ATA_Data_Low = _B3
  rjmp _Drive_Write
[End]
[_Drive_Set_CntLBA]
$EXTERNAL _Drive_Write_Reg
_Drive_Set_CntLBA:
.OBJ E061
.OBJ E072
  rcall _Drive_Write_Reg
.OBJ 916D
.OBJ E073
  rcall _Drive_Write_Reg
.OBJ 916D
.OBJ E074
  rcall _Drive_Write_Reg
.OBJ 916D
.OBJ E075
  rcall _Drive_Write_Reg
.OBJ 916D
.OBJ E076
.OBJ 706F
.OBJ 6E60
  rjmp _Drive_Write_Reg
[END]
[_DriveInit]
$EXTERNAL _DriveReset, _Drive_Check_ready, _DriveCheck
$EXTERNAL _DriveClearErrorBytes
_DriveInit:
  rcall _DriveClearErrorBytes
*BASIC: Config ATA_Data_Low = OutPut
*#IF ATA_DataBits = 16
  *BASIC: Config ATA_Data_High = Output
*#ENDIF
*#IF ATA_Reset_ActiveLevel = 0
  *BASIC: Set ATA_Port_Reset
*#ELSE
  *BASIC: Reset ATA_Port_Reset
*#ENDIF
*#IF ATA_Reset_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_Reset = Output
*#ENDIF
*BASIC: Set ATA_Port_CS0
*#IF ATA_CS0_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_CS0 = Output
*#ENDIF
*#IF ATA_CS1_Connected = 1
*BASIC: Set ATA_Port_CS1
*#IF ATA_CS1_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_CS1 = Output
  *BASIC: Set ATA_Pin_CS1
*#ENDIF
*#ENDIF
*BASIC: Set ATA_Port_DIOR
*#IF ATA_DIOR_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_DIOR = Output
*#ENDIF
*BASIC: Set ATA_Port_DIOW
*#IF ATA_DIOW_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_DIOW = Output
*#ENDIF
*#IF ATA_DA0_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_DA0 = Output
*#ENDIF
*#IF ATA_DA1_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_DA1 = Output
*#ENDIF
*#IF ATA_DA2_PortOnlyOutput = 0
  *BASIC: Config ATA_Pin_DA2 = Output
*#ENDIF
*#IF ATA_CD1_Connected = 1
  * #IF ATA_CD1_PortInputOnly = 0
     *BASIC: Set ATA_Port_CD1
     *BASIC: Config ATA_Pin_CD1 = Input
  *#ENDIF
*#ENDIF
.OBJ E081
.OBJ 2799
  call _Waitms
  rcall _DriveCheck
  brcc _DriveInit1
.OBJ 9508
_DriveInit1:
  rjmp _DriveReset1
[End]
[_DriveReset]
$EXTERNAL _DriveClearErrorBytes
_DriveReset:
*#IF ATA_Reset_Connected = 1
  rcall _DriveClearErrorBytes
_DriveReset1:
.OBJ E28A
_DriveReset2:
.OBJ 938F
  rcall _Drive_Check_Command
.OBJ 918F
  brcc _DriveReset3
.OBJ 958A
  brne _DriveReset2
.OBJ 9408
  rjmp _DriveReset9
_DriveReset3:
*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Reset ATA_Port_CS0
*#ELSE
  *BASIC: Set ATA_Port_CS0
*#ENDIF
*#IF ATA_Reset_ActiveLevel = 0
  *BASIC: Reset ATA_Port_Reset
*#ELSE
  *BASIC: Set ATA_Port_Reset
*#ENDIF
.OBJ E08A
.OBJ 2799
  call _Waitms
*#IF ATA_Reset_ActiveLevel = 0
  *BASIC: Set ATA_Port_Reset
*#ELSE
  *BASIC: Reset ATA_Port_Reset
*#ENDIF
*#IF ATA_CS0_ActiveLevel = 0
  *BASIC: Set ATA_Port_CS0
*#ELSE
  *BASIC: Reset ATA_Port_CS0
*#ENDIF
*  ldi r24 , lByte(waitms_afterReset)
*  ldi r25 , hByte(waitms_afterReset)
  call _Waitms
  rcall _Drive_Check_Command
  brcs _DriveReset9
.OBJ 2700
.OBJ 2711
.OBJ 2722
.OBJ 2733
  rcall _Drive_Set_CntLBA
.OBJ E160
  rcall _Drive_Write_CommandReg
.OBJ EC88
.OBJ 2799
  call _Waitms
  rcall _Drive_Check_Command
  brcs _DriveReset9
*#ELSE
_DriveReset1:
*#ENDIF
.OBJ 2799
.OBJ 9488
_DriveReset9:
.OBJ 9508
[End]
[_DriveCheck]
$EXTERNAL _DriveClearErrorBytes, _Drive_Check_Ready
_DriveCheck:
  rcall _DriveClearErrorBytes
*#IF ATA_CD1_Connected = 1
*BASIC: _temp1 = ATA_Pin_CD1
.OBJ FF80
  rjmp _DriveCheck1
*  ldi r25, cpErrDriveNotPresent
  rjmp _Drive_Check_EndError10
*#ENDIF
_DriveCheck1:
.OBJ 2799
.OBJ 9488
.OBJ 9508
[END]
[_DriveClearErrorBytes]
_DriveClearErrorBytes:
.OBJ 2788
*  sts {gbDriveError}, r24
*  sts {gbDriveStatusReg}, r24
*  sts {gbDriveErrorReg}, r24
.OBJ 9508
[end]








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