| 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] |