source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm@ 158

Last change on this file since 158 was 158, checked in by Tomi Tilli, 14 years ago

Changes to XTIDE Universal BIOS:

  • Optimized few bytes.
File size: 7.3 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : IDE Device Command functions.
3
4; Section containing code
5SECTION .text
6
7;--------------------------------------------------------------------
8; IdeCommand_ResetMasterAndSlaveController
9; Parameters:
10; DS:DI: Ptr to DPT (in RAMVARS segment)
11; Returns:
12; AH: INT 13h Error Code
13; CF: Cleared if success, Set if error
14; Corrupts registers:
15; AL, BX, CX, DX
16;--------------------------------------------------------------------
17IdeCommand_ResetMasterAndSlaveController:
18 ; HSR0: Set_SRST
19 call AccessDPT_GetDeviceControlByteToAL
20 or al, FLG_DEVCONTROL_SRST | FLG_DEVCONTROL_nIEN ; Set Reset bit
21 mov dl, DEVICE_CONTROL_REGISTER_out
22 call Device_OutputALtoIdeControlBlockRegisterInDL
23 mov ax, HSR0_RESET_WAIT_US
24 call Timer_DelayMicrosecondsFromAX
25
26 ; HSR1: Clear_wait
27 call AccessDPT_GetDeviceControlByteToAL
28 or al, FLG_DEVCONTROL_nIEN
29 and al, ~FLG_DEVCONTROL_SRST ; Clear reset bit
30 mov dl, DEVICE_CONTROL_REGISTER_out
31 call Device_OutputALtoIdeControlBlockRegisterInDL
32 mov ax, HSR1_RESET_WAIT_US
33 call Timer_DelayMicrosecondsFromAX
34
35 ; HSR2: Check_status
36 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_BSY)
37 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
38
39
40;--------------------------------------------------------------------
41; IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
42; Parameters:
43; BH: Drive Select byte for Drive and Head Select Register
44; DS: Segment to RAMVARS
45; ES:SI: Ptr to buffer to receive 512-byte IDE Information
46; CS:BP: Ptr to IDEVARS
47; Returns:
48; AH: INT 13h Error Code
49; CF: Cleared if success, Set if error
50; Corrupts registers:
51; AL, BL, CX, DX, SI, DI, ES
52;--------------------------------------------------------------------
53IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH:
54 ; Create fake DPT to be able to use Device.asm functions
55 call FindDPT_ForNewDriveToDSDI
56 eMOVZX ax, bh
57 cmp BYTE [cs:bp+IDEVARS.bDevice], DEVICE_XTIDE_WITH_REVERSED_A3_AND_A0
58 eCMOVE ah, FLGH_DPT_REVERSED_A0_AND_A3
59 mov [di+DPT.wFlags], ax
60 mov [di+DPT.bIdevarsOffset], bp
61 mov BYTE [di+DPT_ATA.bSetBlock], 1 ; Block = 1 sector
62
63 ; Wait until drive motors have reached max speed
64 cmp bp, BYTE ROMVARS.ideVars0
65 jne SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
66 test al, FLG_DRVNHEAD_DRV
67 jnz SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
68 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_BSY)
69 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
70.SkipLongWaitSinceDriveIsNotPrimaryMaster:
71
72 ; Create IDEPACK without INTPACK
73 push bp
74 call Idepack_FakeToSSBP
75
76 ; Prepare to output Identify Device command
77 mov dl, 1 ; Sector count (required by IdeTransfer.asm)
78 mov al, COMMAND_IDENTIFY_DEVICE
79 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_IDENTIFY_DEVICE, FLG_STATUS_DRQ)
80 call Idepack_StoreNonExtParametersAndIssueCommandFromAL
81
82 ; Clean stack and return
83 lea sp, [bp+EXTRA_BYTES_FOR_INTPACK] ; This assumes BP hasn't changed between Idepack_FakeToSSBP and here
84 pop bp
85 ret
86
87
88;--------------------------------------------------------------------
89; IdeCommand_OutputWithParameters
90; Parameters:
91; BH: System timer ticks for timeout
92; BL: IDE Status Register bit to poll after command
93; ES:SI: Ptr to buffer (for data transfer commands)
94; DS:DI: Ptr to DPT (in RAMVARS segment)
95; SS:BP: Ptr to IDEPACK
96; Returns:
97; AH: INT 13h Error Code
98; CF: Cleared if success, Set if error
99; Corrupts registers:
100; AL, BX, CX, DX, (ES:SI for data transfer commands)
101;--------------------------------------------------------------------
102ALIGN JUMP_ALIGN
103IdeCommand_OutputWithParameters:
104 push bx ; Store status register bits to poll
105
106 ; Select Master or Slave drive and output head number or LBA28 top bits
107 call IdeCommand_SelectDrive
108 jc SHORT .DriveNotReady
109
110 ; Output Device Control Byte to enable or disable interrupts
111 mov al, [bp+IDEPACK.bDeviceControl]
112 test al, FLG_DEVCONTROL_nIEN ; Interrupts disabled?
113 jnz SHORT .DoNotSetInterruptInServiceFlag
114
115 ; Clear Task Flag and set Interrupt In-Service Flag
116 or BYTE [di+DPT.bFlagsHigh], FLGH_DPT_INTERRUPT_IN_SERVICE
117 push ds
118 LOAD_BDA_SEGMENT_TO ds, dx, ! ; Also zero DX
119 mov [BDA.bHDTaskFlg], dl
120 pop ds
121.DoNotSetInterruptInServiceFlag:
122 mov dl, DEVICE_CONTROL_REGISTER_out
123 call Device_OutputALtoIdeControlBlockRegisterInDL
124
125 ; Output Feature Number
126 mov dl, FEATURES_REGISTER_out
127 mov al, [bp+IDEPACK.bFeatures]
128 call Device_OutputALtoIdeRegisterInDL
129
130 ; Output Sector Address High (only used by LBA48)
131 mov ax, [bp+IDEPACK.wSectorCountHighAndLbaLowExt]
132 mov cx, [bp+IDEPACK.wLbaMiddleAndHighExt]
133 call OutputSectorCountAndAddress
134
135 ; Output Sector Address Low
136 mov ax, [bp+IDEPACK.wSectorCountAndLbaLow]
137 mov cx, [bp+IDEPACK.wLbaMiddleAndHigh]
138 call OutputSectorCountAndAddress
139
140 ; Output command
141 mov dl, COMMAND_REGISTER_out
142 mov al, [bp+IDEPACK.bCommand]
143 call Device_OutputALtoIdeRegisterInDL
144
145 ; Wait until command completed
146 pop bx ; Pop status and timeout for polling
147 cmp bl, FLG_STATUS_DRQ ; Data transfer started?
148 je SHORT IdeTransfer_StartWithCommandInAL
149 test BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
150 jz SHORT .WaitForIrqOrRdy
151 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
152
153ALIGN JUMP_ALIGN
154.WaitForIrqOrRdy:
155 jmp IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
156
157.DriveNotReady:
158 pop bx ; Clean stack
159ReturnSinceTimeoutWhenPollingBusy:
160 ret
161
162
163;--------------------------------------------------------------------
164; IdeCommand_SelectDrive
165; Parameters:
166; DS:DI: Ptr to DPT (in RAMVARS segment)
167; SS:BP: Ptr to IDEPACK
168; Returns:
169; AH: INT 13h Error Code
170; CF: Cleared if success, Set if error
171; Corrupts registers:
172; AL, BX, CX, DX
173;--------------------------------------------------------------------
174ALIGN JUMP_ALIGN
175IdeCommand_SelectDrive:
176 ; Wait until neither Master or Slave Drive is busy
177 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_BSY, FLG_STATUS_BSY)
178 cmp BYTE [bp+IDEPACK.bCommand], COMMAND_IDENTIFY_DEVICE
179 eCMOVE bh, TIMEOUT_IDENTIFY_DEVICE
180 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
181 jc SHORT ReturnSinceTimeoutWhenPollingBusy
182
183 ; Select Master or Slave Drive
184 mov dl, DRIVE_AND_HEAD_SELECT_REGISTER
185 mov al, [bp+IDEPACK.bDrvAndHead]
186 call Device_OutputALtoIdeRegisterInDL
187 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
188 cmp BYTE [bp+IDEPACK.bCommand], COMMAND_IDENTIFY_DEVICE
189 eCMOVE bh, TIMEOUT_IDENTIFY_DEVICE
190 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
191
192
193;--------------------------------------------------------------------
194; OutputSectorCountAndAddress
195; Parameters:
196; AH: LBA low bits (Sector Number)
197; AL: Sector Count
198; CL: LBA middle bits (Cylinder Number low)
199; CH: LBA high bits (Cylinder Number high)
200; DS:DI: Ptr to DPT (in RAMVARS segment)
201; Returns:
202; Nothing
203; Corrupts registers:
204; AL, BX, DX
205;--------------------------------------------------------------------
206ALIGN JUMP_ALIGN
207OutputSectorCountAndAddress:
208 mov dl, SECTOR_COUNT_REGISTER
209 call Device_OutputALtoIdeRegisterInDL
210
211 mov al, ah
212 mov dl, LBA_LOW_REGISTER
213 call Device_OutputALtoIdeRegisterInDL
214
215 mov al, cl
216 mov dl, LBA_MIDDLE_REGISTER
217 call Device_OutputALtoIdeRegisterInDL
218
219 mov al, ch
220 mov dl, LBA_HIGH_REGISTER
221 jmp Device_OutputALtoIdeRegisterInDL
Note: See TracBrowser for help on using the repository browser.