⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ata.asm

📁 DIY自己的MP3的参考价值极高的代码。含有详细的解释
💻 ASM
字号:
/* ***********************************************************************
**
**  Copyright (C) 2002  Jesper Hansen <jesperh@telia.com> and 
**			Romuald Bialy (MIS) <romek_b@o2.pl>.
**
**
**  Yampp-7/USB - low level support library
**
**
*************************************************************************
**
**   This file is part of the yampp system.
**
**  This program is free software; you can redistribute it and/or
**  modify it under the terms of the GNU General Public License
**  as published by the Free Software Foundation; either version 2
**  of the License, or (at your option) any later version.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this program; if not, write to the Free Software Foundation, 
**  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**
*************************************************************************
**
**  Revision History
**
**  when         what  who	why
**
**  2002-09-22   1.0   MIS      initial public release
**  2003-07-14   1.1   MIS      added watchdog resets to USB<->CARD functions
**  2004-01-10   1.2   MIS      fixed ATA_SetDrive function to avoid lockup if no card is present
**
*********************************************************************** */


#define __ASSEMBLER__ 1
#define __SFR_OFFSET 0
#include <avr/io.h>

#define ATA_ASM
#include "ata.h"

#define __tmp_reg__	r0
#define __zero_reg__	r1


#define USB_PIN		PIND
#define USB_TXRDY	PD3
#define USB_RXRDY	PD2
#define USB_ADDR	0x8000



.section	.text

 
;******************************************************************************* 
;*
;* ATA Interface stuff
;* 
;******************************************************************************* 
 

; 512 byte sector buffer in internal RAM

.global ata_sbuf
	.comm	ata_sbuf,512
	.comm	ata_drive,1
	
	.comm	ata_stat,1

		
;			    r24
;u08 ReadBYTE(u08 reg);
	.global	ReadBYTE
ReadBYTE:
		push	r31			; save register
		mov	r31,r24			; only high 8 bytes are needed
		ld	r24,Z			; read byte	
		pop	r31			; restore
		clr	r25			; clear high
		ret					

;				 r24		r22		
;void WriteBYTE(u08 reg, u08 dat) 
	.global WriteBYTE
WriteBYTE:

		push	r31			; save register
		mov	r31,r24			; only high 8 bytes are needed
		st	Z,r22			; write byte	
		pop	r31			; restore
		ret					



;
; r20,r24, X, Z modified
;
BufferToDisk:

		; set Z to disk
		ldi	r31,lo8(ATAPI_RepData)
		clr	r30

		; set X to ram buffer
  		ldi	r27,hi8(ata_sbuf)
 		ldi 	r26,lo8(ata_sbuf)

		clr	r20				; loop count = 256 words
btd1:
		ld	r24,X+
		st	Z,r24

		ld	r24,X+
		st	Z,r24
		
		dec	r20				; dec loop counter
		brne	btd1				; and loop until done
		ret


;
; r20,r24, X, Z modified
;

DiskToBuffer:
	
		; set X to disk
		ldi	r27,lo8(ATAPI_RepData)
		clr	r26

		; set Z to ram buffer
  		ldi 	r31,hi8(ata_sbuf)
 		ldi 	r30,lo8(ata_sbuf)



		clr	r20				; loop count = 256 words
dtb1:
		ld	r24,X
		st	Z+,r24

		ld	r24,X
		st	Z+,r24
		
		dec	r20				; dec loop counter
		brne	dtb1				; and loop until done
		ret


;
; read status register
;
;
; r24,r25,r30,r31 destroyed
;
	.global ATA_ReadStat
ATA_ReadStat:
 		ldi 	r24,lo8(ATAPI_Stat)
 		rjmp 	ReadBYTE

;
; r24,r25,r30,r31 destroyed
;
	.global ATA_WaitBusy
ATA_WaitBusy:
		rcall	ATA_ReadStat		; read status register
 		tst 	r24			; check for BUSY set
 		brlt 	ATA_WaitBusy		; set, goto check again
		ret



;u08 WaitReady(void);
;
;modifies  R24, R25, Z
;
	.global ATA_WaitReady
ATA_WaitReady:
		rcall	ATA_WaitBusy		; get status register
 		sbrc 	r24,0			; skip if Error bit is clear
		rjmp	ATA_wrdy2		; else return err
		sbrs	r24,3			; test for DRQ, skip if set
		rjmp	ATA_WaitReady		; not yet, loop again	
ATA_wrdy2:
		andi	r24,1			; return 0 on OK, 1 on FAIL
		sts	ata_stat,r24		; save result
 		ret

;					r24
;void ATA_SetDrive(u08 Drive);
	.global ATA_SetDrive
ATA_SetDrive:
		andi	r24,1				; mask bit
		swap	r24

		ldi	r25,0xE0			; LBA and fixed bits for Device/Head register
		or	r24,r25				; combine
		sts	ata_drive,r24			; save in variable
		mov	r22,r24	
  		ldi 	r24,lo8(ATAPI_DRVSelect)
;		cli
 		rcall 	WriteBYTE			; write drive select value to drive
;		rcall	ATA_WaitBusy			; wait for not busy
;		sei
		ret


	.global ATA_Read
;	      r25..r22
;u08 ATA_Read( u32 lba ) 

ATA_Read:
		sts	ata_stat,__zero_reg__	; clear error flag
		ldi	r18,0x20		; read command
		ldi	r20,1			; request one sector
		rcall	ATA_Request
		tst	r24
		brne	ATA_CMD_END
		rcall	DiskToBuffer
ATA_CMD_END:	lds	r24,ata_stat		; read ata error flag
		mov	r25,r24
 		ret



	.global ATA_Write
;	       r25..r22
;u08 ATA_Write( u32 lba ) 

ATA_Write:
		sts	ata_stat,__zero_reg__	; clear error flag
		ldi	r18,0x30		; write command
		ldi	r20,1			; request one sector
		rcall	ATA_Request
		tst	r24
		brne	ATA_CMD_END
		rcall	BufferToDisk
		rjmp	ATA_CMD_END



	.global ATA_Read_USB
;		   r25..r22 		r20     	
;u08 ATA_Read_USB( u32 lba,  u08 numsectors);
;	
ATA_Read_USB:
		sts	ata_stat,__zero_reg__		; clear error flag
		ldi	r18,0x20			; read command
		rcall	ATA_Request
		tst	r24
		brne	ATA_CMD_END

		mov	r22,r20				; save count
.RTU0:
		wdr
		rcall	ATA_WaitReady
		rcall	DiskToBuffer

	; send buffer to USB

		ldi	r27,hi8(ata_sbuf)
		ldi	r26,lo8(ata_sbuf)		; X points to buffer
		ldi	r31,hi8(USB_ADDR)
		ldi	r30,lo8(USB_ADDR)		; Z points to USB
		clr	r20				; loop count = 256 words
.RTU1:
		sbic 	USB_PIN,USB_TXRDY		; while flag is set
 		rjmp 	.RTU1				; wait for bit to be cleared
		ld	r24,X+				; read from RAM
		st	Z,r24				; store to USB
.RTU2:
		sbic 	USB_PIN,USB_TXRDY		; while flag is set
 		rjmp 	.RTU2				; wait for bit to be cleared
		ld	r24,X+				; read from USB
		st	Z,r24				; store to RAM
		dec	r20				; dec loop counter
		brne	.RTU1				; and loop until done
		dec	r22				; dec sector counter
		brne	.RTU0				; and loop until done
		rjmp	ATA_CMD_END



;		    r25..r22 		r20     	
;u08 ATA_Write_USB( u32 lba,  u08 numsectors);
;	
	.global ATA_Write_USB
ATA_Write_USB:
		sts	ata_stat,__zero_reg__		; clear error flag
		ldi	r18,0x30			; write command
		rcall	ATA_Request
		tst	r24
		brne	ATA_CMD_END

		cli
		mov	r22,r20				; save count
.LJ0:
		rcall	ATA_WaitReady
		wdr
	
		ldi	r31,lo8(ATAPI_RepData)		; Z points to CF card data register
		clr	r30
		ldi	r27,hi8(USB_ADDR)
		ldi	r26,lo8(USB_ADDR)		; X points to USB
		clr	r20				; loop count = 256 words
.LJ1:
		sbic 	USB_PIN,USB_RXRDY		; while flag is set
 		rjmp 	.LJ1				; wait for bit to be cleared
		ld	r24,X				; read from USB
		st	Z,r24				; store to CARD
.LJ2:
		sbic 	USB_PIN,USB_RXRDY		; while flag is set
 		rjmp 	.LJ2				; wait for bit to be cleared
		ld	r24,X				; read from USB
		st	Z,r24				; store to CARD

		dec	r20				; dec loop counter
		brne	.LJ1				; and loop until done

		dec	r22				; dec sector counter
		brne	.LJ0				; and loop until done
		sei
		rjmp	ATA_CMD_END

;****************************************

;	head cyl sect
;	 8   16   8
	 

;r22   		sect = (u16) ( lba & 0x000000ffL );	
;   			lba = lba >> 8;
;r24/r23   	cyl = (u16) ( lba & 0x0000ffff );
;   			lba = lba >> 16;
;r25   		head = ( (u16) ( lba & 0x0fL ) ) | 0x40;
	


;			      r25..r22     r20		r18
;u08 ATA_Request_Sectors_LBA( u32 lba, u08 numsectors, u08 command);
	
	.global ATA_Request
ATA_Request:	
	
		mov	r19,r22				; save sector (low LBA) value
		mov	r21,r24				; save LBA 23:16
		
		andi	r25,0x0f			; mask high LBA (LBA 27:24) 
		lds	r22,ata_drive			; get drive
		or 	r22,r25				; combine	

 		rcall	ATA_WaitBusy
		
  		ldi 	r24,lo8(ATAPI_DRVSelect)
 		rcall 	WriteBYTE			; write drive select value
 
 	; wait for !BUSY and DRDY
.L927:
		rcall	ATA_WaitBusy
		sbrs	r24,6				; skip if DRDY is set
		rjmp	.L927
		
  		mov 	r22,r20
 		ldi 	r24,lo8(ATA_SectorCount)	; nSectors
 		rcall 	WriteBYTE

 		mov 	r22,r19				; get saved value
		ldi 	r24,lo8(ATA_Sector)		; Start Sector (LBA 7:0)
		rcall 	WriteBYTE

		mov 	r22,r23			
		ldi 	r24,lo8(ATAPI_CountLSB)		; LSB of track (LBA 15:8)
		rcall 	WriteBYTE

  		mov 	r22,r21				; get saved value	
 		ldi 	r24,lo8(ATAPI_CountMSB)		; MSB of track (LBA 23:16)
 		rcall 	WriteBYTE
 
 		mov 	r22,r18
 		ldi 	r24,lo8(ATAPI_Cmd)		; Send the command
 		rcall 	WriteBYTE

		nop
		nop
		nop
		nop

	; dummy read of Alternate Status register
 		ldi 	r24,lo8(ATAPI_AltStat)
 		rcall 	ReadBYTE

		rjmp	ATA_WaitReady			; check and return result





;
;u08 ATA_Identify(void)
	.global ATA_Identify
ATA_Identify:	
		clr	r25
		clr	r24
		movw	r22,r24
		movw	r20,r24
		ldi	r18,0xEC
		rcall	ATA_Request	
		tst	r24
		brne	id_err
		rcall	DiskToBuffer
id_err:		lds	r24,ata_stat		; read ata error flag
		clr	r25
 		ret

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -