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

📄 ide.s

📁 Frank s MP3 Player Source Files
💻 S
📖 第 1 页 / 共 3 页
字号:
;* to is passed in the param1 parameter, as defined in the header of this file.
;* The data byte to be written is passed in param2.
;* 
;* The front of this routine has a chunk of bit manipulation code to translate the
;* param1 address bit allocation to the IDE pins on ports B & F.
;*
;* This routine does the following on the IDE bus:  (all times are minimums)
;*
;* Write the 5-bit address (with read, write, reset all high)
;* Wait 50 ns
;* Set /WR low
;* Wait 290 ns
;*	  While waiting, set the low byte port to be an output
;*	  While waiting, write param2 to the low 8 bits of the IDE bus
;* Set /WR high
;* Wait 20 ns
;* Set the low byte port to be inputs
;* return
;*
;* Accepts: Address in param1, byte to write in param2
;* Returns: Nothing
;* Uses:	temp, flags. 
;*
;**********************************************************************************

IDE_write8:
		; put A0-2 on port b, and cs0, cs1 on port f
		in		temp,PORTB
		bst		param1,3						
		bld		temp,5							; param1:3 -> temp:5  (A0)
		bst		param1,4
		bld		temp,6							; param1:4 -> temp:6  (A1)
		bst		param1,5
		bld		temp,7							; param1:5 -> temp:7  (A2)
		out		PORTB,temp						; write A0-2 onto the IDE bus
		lds		temp,PORTF
		bst		param1,6
		bld		temp,2							; param1:6 -> temp:2  (/CS1)
		bst		param1,7
		bld		temp,3							; param1:7 -> temp:3  (/CS0)
		sts		PORTF,temp						; write /CS0, /CS1 onto the IDE bus

		; make /WR low
		lds		temp,PORTF
		cbr		temp,2							; clear bit 1, the /WR line
		sts		PORTF,temp						; and write it to the IDE bus

		out		IDEDATAL,param2					; write data byte onto IDE bus port
		ldi		temp,255
		out		IDEDATAL_DDR,temp				; low byte direction set for output
		nop
		nop
		nop
		nop										; finish waiting the 290 ns

		; make /WR high
		lds		temp,PORTF
		sbr		temp,2							; set bit 1, the /WR line
		sts		PORTF,temp						; and write it to the IDE bus

		ldi		temp,0
		out		IDEDATAL_DDR,temp				; low byte direction set for input
		ret
		


;**********************************************************************************
;*
;* IDE_read16_C
;*
;* C-callable version of IDE_Read16 below.
;*
;* u16 IDE_read16_C (u08 idereg);
;*
;* Address of IDE register to read from is passed in via r24. Result is returned
;* via r25:r24
;*
;**********************************************************************************
IDE_read16_C:
    push    param1
    push    param2

    mov     param1,r24
    rcall   IDE_read16
    mov     r24,param1                          ; low byte return
    mov     r25,param2                          ; high byte return

    pop     param2
    pop     param1
    ret






;**********************************************************************************
;*
;* IDE_read16
;* Read an 16 bit value from the IDE interface
;*
;* This routine reads a 16-bit word from the IDE interface. The 5 bit "address" to be read
;* from is passed in the param1 parameter, as defined in the header of this file.
;* The low byte read from the drive is returned in param1; the high byte in param2.
;*
;* The start of this routine contains a chunk of bit manipulation code to convert the
;* param1 address bit allocation into bit mappings for ports B & F.
;*
;* This routine does the following on the IDE bus:  (all times are minimums)
;*
;* Write the 5-bit address (with read, write, reset all high)
;* Wait 50 ns
;* Set /RD low
;* Wait 125 ns
;* Read the 2 bytes (low and high) from the IDE bus
;* Set /RD high
;* return
;*
;* Accepts: Address in param1
;* Returns: Low byte read in param1; high byte in param2
;* Uses:	flags. 
;*
;**********************************************************************************

IDE_read16:
		push	temp
		
; Test code only - wait until BSY bit in status register is clear and RDY bit is set.
;		push	param1							; preserve the original IDE address
IDE_read16_test:
;		ldi		param1,IDERD_ST
;		rcall	IDE_read8						; read status register
;		sbrc	param1,IDEST_BSY_BIT			; skip forward if BSY bit clear
;		rjmp	IDE_read16_test3				; repeat if BSY bit set (drive is busy)
;		sbrs	param1,IDEST_RDY_BIT			; skip forward if RDY bit set
;		rjmp	IDE_read16_test3				; repeat if RDY bit clear (drive is not ready)
;		sbrs	param1,IDEST_COR_BIT
;		rjmp	IDE_read16_test2				; jump forward if correctable error bit clear
;		ldi		param1,'Z'
;		call	UART_TxCharWait 
;		ldi		param1,'C'
;		call	UART_TxCharWait 
;		ldi		param1,'O'
;		call	UART_TxCharWait			
;		ldi		param1,'R'
;		call	UART_TxCharWait					; print debug message if correctable error bit set
IDE_read16_test2:				
;		pop		param1
; end of test code		

		; put A0-2 on port b, and cs0, cs1 on port f
		in		temp,PORTB
		bst		param1,3						
		bld		temp,5							; param1:3 -> temp:5  (A0)
		bst		param1,4
		bld		temp,6							; param1:4 -> temp:6  (A1)
		bst		param1,5
		bld		temp,7							; param1:5 -> temp:7  (A2)
		out		PORTB,temp						; write A0-2 onto the IDE bus
		lds		temp,PORTF
		bst		param1,6
		bld		temp,2							; param1:6 -> temp:2  (/CS1)
		bst		param1,7
		bld		temp,3							; param1:7 -> temp:3  (/CS0)
		sts		PORTF,temp						; write /CS0, /CS1 onto the IDE bus

		; make /RD low
		lds		temp,PORTF
		cbr		temp,16							; clear bit 4, the /RD line
		sts		PORTF,temp						; and write it to the IDE bus

		nop
		nop										; wait a bit (125 ns)
		in		param1,IDEDATAL_PIN				; read the low 8 bits of the IDE bus
		in		param2,IDEDATAH_PIN				; read the high 8 bits of the IDE bus

		; make /RD high again
		lds		temp,PORTF
		sbr		temp,16							; set bit 4, the /RD line
		sts		PORTF,temp						; and write it to the IDE bus

		pop		temp
		ret

; test code - busy bit or ready could result in endless loop. So print debug info if busy bit set or ready bit clear
IDE_read16_test3:
		call	UART_PutHexWait					; print value of status register
		ldi		param1,' '
		call	UART_TxCharWait 
		ldi		param1,'I'
		call	UART_TxCharWait 
		ldi		param1,'D'
		call	UART_TxCharWait 
		ldi		param1,'E'
		call	UART_TxCharWait 
		ldi		param1,'r'
		call	UART_TxCharWait 
		ldi		param1,'1'
		call	UART_TxCharWait 
		ldi		param1,'6'
		call	UART_TxCharWait 
		ldi		param1,'\r'
		call	UART_TxCharWait 
		ldi		param1,'\n'						; followed by a short message
		call	UART_TxCharWait
		rjmp	IDE_read16_test					; then loop back to check busy bit again
; end of test code segment		
		


;**********************************************************************************
;*
;* IDE_AutoPD
;* Enables automatic power-down on the drive
;*
;* This routine issues a command to the drive to enable automatic power-down
;* mode. This mode greatly reduces power consumption, heat dissipation, and noise
;* of the drive when it is not being accessed. It functions as follows:
;*
;* This routine does the following on the IDE bus:  (all times are minimums)
;*
;* Wait for drive to not be busy (BSY=0 in status register) 
;* Write a 13 to the SECTOR COUNT register
;* Wait for drive to set RDY
;* Write the command $E2 - Standby Mode, Automatic Power Down to the drive
;* return
;*
;*
;* Accepts: nothing
;* Returns: nothing
;* Uses:	flags. 
;*			zeros r1
;*
;**********************************************************************************

IDE_AutoPD:
		push	temp
		push	param1
		push	param2

IDE_AutoPDAA:
; wait for drive to clear busy flag
		ldi		temp,IDERD_ST
		mov		param1,temp
		rcall	IDE_read8						; read status register
		sbrc	param1,IDEST_BSY_BIT			; skip forward if BSY bit clear
		rjmp	IDE_AutoPDAA					; repeat if BSY bit set (drive is busy)
		
; make sure drive has ready (RDY) bit set 
		sbrs	param1,IDEST_RDY_BIT			; skip forward if RDY bit set
		rjmp	IDE_AutoPDAA					; repeat if RDY bit clear (drive is not ready)
		
; write 13 to sector count register
		ldi		temp,IDEWR_SC
		mov		param1,temp						; sector count register address in param1
		ldi		temp,13
		mov		param2,temp						; 13 in param2
		rcall	IDE_write8						; write 13 to SECTOR COUNT register
		
; wait for drive to set ready flag
IDEAPD: ldi		temp,IDERD_ST
		mov		param1,temp
		rcall	IDE_read8						; read status register
		sbrs	param1,IDEST_RDY_BIT			; skip forward if DRDY bit set
		rjmp	IDEAPD							; repeat if DRDY bit clear		
		
; write command $E2 to the drive & return
		ldi		temp,IDEWR_CMD
		mov		param1,temp						; param1: command register address
		ldi		temp,0xe2
		mov		param2,temp						; param2: $e2
		rcall	IDE_write8						; write command to drive
		
		clr		r1								; zero r1 (for the C compiler)
		pop		param2
		pop		param1
		pop		temp							
		ret
		
		




;**********************************************************************************
;*
;* IDE_Standby
;* Tells the drive to immediately go into standby mode
;*
;* This routine does the following on the IDE bus:  (all times are minimums)
;*
;* Wait for drive to not be busy (BSY=0 in status register) 
;* Make sure drive is ready
;* Write the command $E0 - Standby Immediate, to the drive
;* return
;*
;*
;* Accepts: nothing
;* Returns: nothing
;* Uses:	flags. 
;*			zeros r1
;*
;**********************************************************************************

IDE_Standby:
		push	temp
		push	param1
		push	param2

IDE_StandbyAA:
; wait for drive to clear busy flag
		ldi		temp,IDERD_ST
		mov		param1,temp
		rcall	IDE_read8						; read status register
		sbrc	param1,IDEST_BSY_BIT			; skip forward if BSY bit clear
		rjmp	IDE_StandbyAA					; repeat if BSY bit set (drive is busy)
		
; make sure drive has ready (RDY) bit set 
		sbrs	param1,IDEST_RDY_BIT			; skip forward if RDY bit set
		rjmp	IDE_StandbyAA					; repeat if RDY bit clear (drive is not ready)
		
; write command $E0 to the drive & return
		ldi		temp,IDEWR_CMD
		mov		param1,temp						; param1: command register address
		ldi		temp,0xe0
		mov		param2,temp						; param2: $e0
		rcall	IDE_write8						; write command to drive
		
		clr		r1								; zero r1 (for the C compiler)
		pop		param2
		pop		param1
		pop		temp
		ret
		
		



;**********************************************************************************
;*
;* SeekSectorC

⌨️ 快捷键说明

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