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

Last change on this file since 500 was 493, checked in by gregli@…, 12 years ago

Separated MODULE_8BIT_IDE into the basic part used by XTIDE rev 1 and rev 2 which is PIO based, and MODULE_8BIT_IDE_ADVANCED for JRIDE and XTCF support which requires memory mapping and/or DMA. This allows for creating an 8KB image with boot menu support (but no hotkeys) for the XTIDE rev 1. Cleaned up how we reset the drive translation information, ensuring it is properly set between boot attempt on a primary and secondary drive - as a result we clean it when needed, rather than trying to always keep it clean. Also fixed translation bugs in int13h.asm where I had previously missed converting some MODULE_HOTKEYS into MODULE_DRIVEXLATE.

File size: 8.6 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : IDE Device Command functions.
3
4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2012 by XTIDE Universal BIOS Team.
7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
12;
13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16; GNU General Public License for more details.
17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
19
20; Section containing code
21SECTION .text
22
23;--------------------------------------------------------------------
24; IdeCommand_ResetMasterAndSlaveController
25; Parameters:
26; DS:DI: Ptr to DPT (in RAMVARS segment)
27; Returns:
28; AH: INT 13h Error Code
29; CF: Cleared if success, Set if error
30; Corrupts registers:
31; AL, BX, CX, DX
32;--------------------------------------------------------------------
33IdeCommand_ResetMasterAndSlaveController:
34 ; HSR0: Set_SRST
35 call AccessDPT_GetDeviceControlByteToAL
36 or al, FLG_DEVCONTROL_SRST | FLG_DEVCONTROL_nIEN ; Set Reset bit
37 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
38 mov ax, HSR0_RESET_WAIT_US
39 call Timer_DelayMicrosecondsFromAX
40
41 ; HSR1: Clear_wait
42 call AccessDPT_GetDeviceControlByteToAL
43 or al, FLG_DEVCONTROL_nIEN
44 and al, ~FLG_DEVCONTROL_SRST ; Clear reset bit
45 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
46 mov ax, HSR1_RESET_WAIT_US
47 call Timer_DelayMicrosecondsFromAX
48
49 ; HSR2: Check_status
50 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MAXIMUM, FLG_STATUS_BSY)
51 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
52
53
54;--------------------------------------------------------------------
55; IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
56; Parameters:
57; BH: Drive Select byte for Drive and Head Select Register
58; DX: Autodetected port for XT-CF
59; DS: Segment to RAMVARS
60; ES:SI: Ptr to buffer to receive 512-byte IDE Information
61; CS:BP: Ptr to IDEVARS
62; Returns:
63; AH: INT 13h Error Code
64; CF: Cleared if success, Set if error
65; Corrupts registers:
66; AL, BX, CX, DX, SI, DI, ES
67;--------------------------------------------------------------------
68IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH:
69 ; Create fake DPT to be able to use Device.asm functions
70 call FindDPT_ForNewDriveToDSDI
71 eMOVZX ax, bh
72 mov [di+DPT.wFlags], ax
73 call CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI
74 call IdeDPT_StoreDeviceTypeToDPTinDSDIfromIdevarsInCSBP
75 mov BYTE [di+DPT_ATA.bBlockSize], 1 ; Block = 1 sector
76
77 ; Wait until drive motors have reached full speed
78 cmp bp, BYTE ROMVARS.ideVars0 ; First controller?
79 jne SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
80 test bh, FLG_DRVNHEAD_DRV ; Wait already done for Master
81 jnz SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
82 call AHDh_WaitUntilDriveMotorHasReachedFullSpeed
83.SkipLongWaitSinceDriveIsNotPrimaryMaster:
84
85 ; Create IDEPACK without INTPACK
86 push bp
87 call Idepack_FakeToSSBP
88
89%ifdef MODULE_8BIT_IDE_ADVANCED
90 ; Enable 8-bit PIO mode for 8-bit ATA and XT-CF
91 push si
92 call AH9h_Enable8bitModeForDevice8bitAta
93 xor al, al ; XTCF_8BIT_PIO_MODE
94 call AH9h_SetModeFromALtoXTCF
95 pop si
96%endif ; MODULE_8BIT_IDE_ADVANCED
97
98 ; Prepare to output Identify Device command
99 mov dl, 1 ; Sector count (required by IdeTransfer.asm)
100 mov al, COMMAND_IDENTIFY_DEVICE
101 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
102 call Idepack_StoreNonExtParametersAndIssueCommandFromAL
103
104 ; Clean stack and return
105.FailedToSet8bitMode:
106 lea sp, [bp+SIZE_OF_IDEPACK_WITHOUT_INTPACK] ; This assumes BP hasn't changed between Idepack_FakeToSSBP and here
107 pop bp
108 ret
109
110
111;--------------------------------------------------------------------
112; IdeCommand_OutputWithParameters
113; Parameters:
114; BH: System timer ticks for timeout
115; BL: IDE Status Register bit to poll after command
116; ES:SI: Ptr to buffer (for data transfer commands)
117; DS:DI: Ptr to DPT (in RAMVARS segment)
118; SS:BP: Ptr to IDEPACK
119; Returns:
120; AH: INT 13h Error Code
121; CX: Number of successfully transferred sectors (for transfer commands)
122; CF: Cleared if success, Set if error
123; Corrupts registers:
124; AL, BX, (CX), DX, (ES:SI for data transfer commands)
125;--------------------------------------------------------------------
126ALIGN JUMP_ALIGN
127IdeCommand_OutputWithParameters:
128 push bx ; Store status register bits to poll
129
130 ; Select Master or Slave drive and output head number or LBA28 top bits
131 call IdeCommand_SelectDrive
132 jc SHORT .DriveNotReady
133
134 ; Output Device Control Byte to enable or disable interrupts
135 mov al, [bp+IDEPACK.bDeviceControl]
136%ifdef MODULE_IRQ
137 test al, FLG_DEVCONTROL_nIEN ; Interrupts disabled?
138 jnz SHORT .DoNotSetInterruptInServiceFlag
139
140 ; Clear Task Flag and set Interrupt In-Service Flag
141 or BYTE [di+DPT.bFlagsHigh], FLGH_DPT_INTERRUPT_IN_SERVICE
142 push ds
143 LOAD_BDA_SEGMENT_TO ds, dx, ! ; Also zero DX
144 mov [BDA.bHDTaskFlg], dl
145 pop ds
146.DoNotSetInterruptInServiceFlag:
147%endif
148 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
149
150 ; Output Feature Number
151 mov al, [bp+IDEPACK.bFeatures]
152 OUTPUT_AL_TO_IDE_REGISTER FEATURES_REGISTER_out
153
154 ; Output Sector Address High (only used by LBA48)
155%ifdef MODULE_EBIOS
156 eMOVZX ax, [bp+IDEPACK.bLbaLowExt] ; Zero sector count
157 mov cx, [bp+IDEPACK.wLbaMiddleAndHighExt]
158 call OutputSectorCountAndAddress
159%endif
160
161 ; Output Sector Address Low
162 mov ax, [bp+IDEPACK.wSectorCountAndLbaLow]
163 mov cx, [bp+IDEPACK.wLbaMiddleAndHigh]
164 call OutputSectorCountAndAddress
165
166 ; Output command
167 mov al, [bp+IDEPACK.bCommand]
168 OUTPUT_AL_TO_IDE_REGISTER COMMAND_REGISTER_out
169
170 ; Wait until command completed
171 pop bx ; Pop status and timeout for polling
172 cmp bl, FLG_STATUS_DRQ ; Data transfer started?
173 jne SHORT .WaitUntilNonTransferCommandCompletes
174%ifdef MODULE_8BIT_IDE_ADVANCED
175 cmp BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_MEMMAP
176 jae SHORT JrIdeTransfer_StartWithCommandInAL ; DEVICE_8BIT_XTCF_MEMMAP or DEVICE_8BIT_JRIDE_ISA
177%endif
178 jmp IdeTransfer_StartWithCommandInAL
179
180.WaitUntilNonTransferCommandCompletes:
181%ifdef MODULE_IRQ
182 test BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
183 jz SHORT .PollStatusFlagInsteadOfWaitIrq
184 jmp IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
185.PollStatusFlagInsteadOfWaitIrq:
186%endif
187 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
188
189.DriveNotReady:
190 pop bx ; Clean stack
191 ret
192
193
194;--------------------------------------------------------------------
195; IdeCommand_SelectDrive
196; Parameters:
197; DS:DI: Ptr to DPT (in RAMVARS segment)
198; SS:BP: Ptr to IDEPACK
199; Returns:
200; AH: INT 13h Error Code
201; CF: Cleared if success, Set if error
202; Corrupts registers:
203; AL, BX, CX, DX
204;--------------------------------------------------------------------
205ALIGN JUMP_ALIGN
206IdeCommand_SelectDrive:
207 ; We use different timeout value when detecting drives.
208 ; This prevents unnecessary long delays when drive is not present.
209 mov cx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
210 cmp WORD [RAMVARS.wDrvDetectSignature], RAMVARS_DRV_DETECT_SIGNATURE
211 eCMOVE ch, TIMEOUT_SELECT_DRIVE_DURING_DRIVE_DETECTION
212
213 ; Select Master or Slave Drive
214 mov al, [bp+IDEPACK.bDrvAndHead]
215 OUTPUT_AL_TO_IDE_REGISTER DRIVE_AND_HEAD_SELECT_REGISTER
216 mov bx, cx
217 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
218
219 ; Ignore errors from IDE Error Register (set by previous command)
220 cmp ah, RET_HD_TIMEOUT
221 je SHORT .FailedToSelectDrive
222 xor ax, ax ; Always success unless timeout
223 ret
224.FailedToSelectDrive:
225 stc
226 ret
227
228
229;--------------------------------------------------------------------
230; OutputSectorCountAndAddress
231; Parameters:
232; AH: LBA low bits (Sector Number)
233; AL: Sector Count
234; CL: LBA middle bits (Cylinder Number low)
235; CH: LBA high bits (Cylinder Number high)
236; DS:DI: Ptr to DPT (in RAMVARS segment)
237; Returns:
238; Nothing
239; Corrupts registers:
240; AL, BX, DX
241;--------------------------------------------------------------------
242ALIGN JUMP_ALIGN
243OutputSectorCountAndAddress:
244 OUTPUT_AL_TO_IDE_REGISTER SECTOR_COUNT_REGISTER
245
246 mov al, ah
247 OUTPUT_AL_TO_IDE_REGISTER LBA_LOW_REGISTER
248
249 mov al, cl
250 OUTPUT_AL_TO_IDE_REGISTER LBA_MIDDLE_REGISTER
251
252 mov al, ch
253 OUTPUT_AL_TO_IDE_REGISTER LBA_HIGH_REGISTER
254 ret
Note: See TracBrowser for help on using the repository browser.