📄 ide.s
字号:
;***************************************************************************
;*
;* Title: IDE Interface Routines
;* Version: 2.1
;* Last updated: 14 April 2004
;* Target: ATMEGA128
;*
;*
;* DESCRIPTION:
;* This file contains routines for communicating with the IDE interface.
;*
;*
;* Hardware Connections:
;* PA0-7: Bidirectional. IDE data bus D0-D7
;* PC0-7: Bidirectional. IDE data bus D8-D15
;* PB4 : Output. front-panel LED (low for on)
;* PB5-7: Output. IDE address lines A0-A2
;* PD7 : Output. IDE reset line (active low)
;* PF2 : Output. IDE chip select 1 (CS1: IDE pin 38, CS1FX-)
;* PF3 : Output. IDE chip select 0 (CS2: IDE pin 37, CS3FX-)
;* PF4 : Output. IDE read strobe (IDE pin 25, active low)
;* PF1 : Output. IDE write strobe (IDE pin 23, active low)
;* PF5 : Output. LCD backlight (high for on)
;*
;* Note that the combination of A0, A1, A2, CS1, CS2 is treated as effectively
;* a single 5-bit address, and will be handled in this fashion in this software.
;* This is an important point; although there are .equ statements to assist
;* changing these routines to run on different port numbers & bits, this software
;* assumes a single 5-bit address on a port; not separate address, CS0 & CS1 signals
;* across multiple ports.
;*
;* Note: the above is not true any longer. With the Mega128 PCB those five signals
;* are split across 2 ports (B&F). With the strong desire to keep the parameter-passing
;* bit allocation (described below) unchanged, the three routines read8, write8
;* and read16 have some bit manipulation code at their beginnings to perform the
;* appropriate translation.
;*
;* All accesses to the IDE bus involving an address must be passed in to the
;* appropriate function using the following param1 bit allocation:
;*
;* bit 7: /CS0 (CS1FX-)
;* bit 6: /CS1 (CS3FX-)
;* bit 5: A2
;* bit 4: A1
;* bit 3: A0
;* bit 2 - 0 : 111 (bits are high)
;*
;* Accesses to the drive are performed using PIO Mode 1 transfers.
;*
;* Stack parameter passing: push high byte first
;* pop low byte first
;*
;***************************************************************************
/* Make the routines in this file available to other files */
.global IDE_init
.global IDE_read8
.global IDE_read8_C
.global IDE_write8
.global IDE_Write8_C
.global IDE_read16
.global IDE_read16_C
.global IDE_AutoPD
.global SeekSector
.global SeekSectorC
.global PrintDriveData
.global IDE_Standby
/* Here are the definitions we need, both in included files and defined right here */
#include "frankmp3.h"
#include "frankasm.h"
; The following are physical port connections on the AVR
#define IDEDATAL 0x1B /* Low data byte is PortA */
#define IDEDATAL_DDR 0x1A /* data direction register */
#define IDEDATAL_PIN 0x19 /* pins read register */
#define IDEDATAH 0x15 /* High data byte is port C */
#define IDEDATAH_DDR 0x14 /* data direction register */
#define IDEDATAH_PIN 0x13 /* pins read register */
#define PORTB 0x18 /* in/out offset address for PORT B */
#define DDRB 0x17 /* in/out offset address for DDR B */
#define PORTF 0x62 /* data space address for PORT F */
#define DDRF 0x61 /* data space address for DDR F */
#define PORTD 0x12 /* in/out offset address for Port D */
#define DDRD 0x11 /* in/out offset address for DDRD */
/* Define any SRAM space we need */
.comm SEEKSECT_ST, 1 ; state variable for SeekSector
.text
;**********************************************************************************
;*
;* IDE_init
;* Initialize the IDE interface, plus any IDE routines that need it.
;*
;* This routine initializes the IDE interface. It sets the appropriate
;* AVR ports to be input or outputs as required. The 16-bit IDE bidirectional data
;* is initially configured as an input.
;*
;* This routine also resets the IDE interface by setting the reset pin low
;* for a minimum of 300ns, then releases reset. This ensures the attached drive
;* is properly reset.
;*
;* It also:
;* Sets SeekSector initial state to InitSeek
;*
;*
;* Accepts: Nothing
;* Returns: Nothing
;* Uses: flags. Clears r1 (for the C compiler)
;*
;**********************************************************************************
IDE_init:
push temp
push temp2
ldi temp,0x3e
sts PORTF,temp ; RD, WR, CS0, CS1, LCD_backlight all high
ldi temp,0x3e
sts DDRF,temp ; make rd, wr, cs0, cs1, backlight pins outputs
cbi PORTD,7 ; set IDE reset line low
sbi DDRD,7 ; make the IDE reset line an output
ldi temp,0xe0
out PORTB,temp ; make A2-0 high and the LED pin low (ie LED on)
ldi temp,0xf0
out DDRB,temp ; and make the A2-0 pins and the LED pin outputs
ldi temp,0
out IDEDATAL_DDR,temp ; low ide data direction byte set for input
out IDEDATAH_DDR,temp ; high ide data direction byte set for input
ldi temp2,0
IDE_init3:
ldi temp,0
IDE_init1:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop ; a nice long reset pulse
dec temp
brne IDE_init1
dec temp2
brne IDE_init3
sbi PORTD,7 ; take drive out of reset - make IDE reset high
ldi temp2,0
IDE_init4:
ldi temp,0
IDE_init2:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop ; wait a little after reset
dec temp
brne IDE_init2
dec temp2
brne IDE_init4
; Set the initial state of SeekSector to InitSeek
ldi ZL,lo8(SEEKSECT_ST)
ldi ZH,hi8(SEEKSECT_ST) ; point Z to SeekSector state variable
ldi temp,SeekSect_ISS
st Z,temp ; make initial state to be InitSeek
clr r1 ; zero r1 (for the C compiler)
pop temp2
pop temp
ret
;**********************************************************************************
;*
;* IDE_read8_C
;* C callable version of IDE_Read8 below.
;*
;**********************************************************************************
IDE_read8_C:
push param1
mov param1,r24 ; IDE address to read passed by C compiler in r24
rcall IDE_read8
mov r24,param1 ; put byte read from drive into r24 for C compiler
pop param1
ret
;**********************************************************************************
;*
;* IDE_read8
;* Read an 8 bit value from the IDE interface
;*
;* This routine reads a byte 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 byte read from the drive is returned in param1.
;*
;* A bunch of bit manipulations are done up-front to translate the param1 bit
;* allocation to the port b and f control pins.
;*
;* 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 290 ns
;* Read the low 8 bits of the IDE bus
;* Set /RD high
;* return
;*
;* Accepts: Address in param1
;* Returns: Byte read in param1
;* Uses: flags.
;*
;**********************************************************************************
IDE_read8:
push temp
; 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
nop
nop
nop ; wait the 290 ns
in param1,IDEDATAL_PIN ; read the low 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
;**********************************************************************************
;*
;* IDE_Write8_C
;* C callable version of IDE_write8 below.
;*
;* function prototype: void IDE_Write8_C (u08 ideaddress, u08 data);
;*
;**********************************************************************************
IDE_Write8_C:
push temp
push param1
push param2
mov param1,r24 ; IDE address to write passed by C compiler in r24
mov param2,r22 ; data to write passed by C compiler in r22
rcall IDE_write8
pop param2
pop param1
pop temp
ret
;**********************************************************************************
;*
;* IDE_Write8
;* Writes an 8 bit value to the IDE interface
;*
;* This routine writes a byte to the IDE interface. The 5 bit "address" to be written
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -