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

Last change on this file since 590 was 589, checked in by Krister Nordvall, 9 years ago

Changes:

  • BIOS: Fixed a purely cosmetic bug from r542 where, in builds containing MODULE_EBIOS, the boot menu would display an incorrect drive size (0.4 kB with MODULE_STRINGS_COMPRESSED or 0.5 kB without) for old drives with no support for LBA.
  • Fixed a bug from r392 where Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent would return the ID in AL instead of AH (if DANGEROUS_DETECTION had been defined).
  • Fixed a bug from r587 in AdvAtaInit.asm that would prevent detection of QDI Vision controllers.
  • Also changed how the QDI Vision IDs are defined (removed the need for shifting) to avoid confusion. This fixed a potential bug from r587 in AdvAtaInit.asm where some IDs were not being shifted.
  • Fixed a bug in PDC20x30.asm from r587 where GetPdcIDtoAX would not return with the IDE base port in DX so DisablePdcProgrammingMode would fail.
  • Made some changes to ModuleDependency.inc and other files so that MODULE_ADVANCED_ATA now requires USE_386. Consequently it is no longer included in the regular AT-builds, only in the 386_8k-build.
  • Moved the UNROLL_SECTORS_IN_CX_TO_xWORDS macros from IDE_8bit.inc to IdeIO.inc which means it's now possible to build a BIOS without MODULE_8BIT_IDE.
  • XTIDECFG: Added a minimum DOS version check (since it needs DOS version 2+) to allow the program to quit gracefully in the unlikely scenario where someone tries to run it under DOS version 1.
  • Made some changes to Drive.asm to improve drive enumeration. The old method using GET_DOS_DRIVE_PARAMETER_BLOCK_FOR_SPECIFIC_DRIVE worked well in Windows XP but not in Windows 98 SE (in Windows or in DOS mode). The two problems were; 1) The function call would access the drives which on single floppy drive systems would cause Windows to swap between A: and B: (throwing a blue screen asking the user to insert a disk etc). 2) Only floppy drives and FAT16 drives would be available in the list of drives, no FAT32/optical/network drives.
  • Improved code in IdeControllerMenu.asm so that the default port addresses for all IDE interfaces are now restored when (re-)selecting the (same) type of IDE device.
  • Also made it impossible to select a device type unless the required module is included in the loaded BIOS.
  • The version check done when loading a BIOS now uses the FLASH_SIGNATURE definition from Version.inc. Any changes affecting RomVars now only requires updating that definition. This means that changes to RomVars must be implemented in both the BIOS and XTIDECFG before being committed to the repository.
  • Added a compatibility fix for 3Com 3C503 cards to the ROM checksumming code in Buffers.asm (Buffers_GenerateChecksum).
  • SerDrive: Made some minor changes to file names and paths to improve compatibility with case sensitive environments.
  • BIOSDRVS: Made a minor size optimization which as a side effect also makes it compatible with all DOS versions including DOS version 1.
  • Library: Renamed the WAIT_RETRACE_IF_NECESSARY_THEN macro to CALL_WAIT_FOR_RETRACE_IF_NECESSARY_THEN and made a tail-call-optimized version of it (JMP_WAIT_FOR_RETRACE_IF_NECESSARY_THEN).
  • A speed optimization to the eRCL_IM macro for 386 and higher. This change breaks emulation in the sense that the macro will fail when given a memory operand as the first parameter.
  • Other minor optimizations and fixes.
File size: 9.5 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-2013 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; Used to be:
36; call AccessDPT_GetDeviceControlByteToAL
37; or al, FLG_DEVCONTROL_SRST | FLG_DEVCONTROL_nIEN ; Set Reset bit
38; Is now:
39 mov al, FLG_DEVCONTROL_SRST | FLG_DEVCONTROL_nIEN
40; ---
41 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
42 mov ax, HSR0_RESET_WAIT_US
43 call Timer_DelayMicrosecondsFromAX
44
45 ; HSR1: Clear_wait
46; Used to be:
47; call AccessDPT_GetDeviceControlByteToAL
48; or al, FLG_DEVCONTROL_nIEN
49; and al, ~FLG_DEVCONTROL_SRST ; Clear reset bit
50; Is now:
51 mov al, FLG_DEVCONTROL_nIEN
52; ---
53 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
54 mov ax, HSR1_RESET_WAIT_US
55 call Timer_DelayMicrosecondsFromAX
56
57 ; HSR2: Check_status
58 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MAXIMUM, FLG_STATUS_BSY)
59 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
60
61; *FIXME* AccessDPT_GetDeviceControlByteToAL currently always returns with
62; AL cleared (0) or with only bit 1 set (FLG_DEVCONTROL_nIEN = 2).
63; The commented away instructions above sets FLG_DEVCONTROL_nIEN anyway
64; making the call to AccessDPT_GetDeviceControlByteToAL redundant.
65; I have left this code as is since I don't know if it's a mistake
66; (from all the way back to r150) or if it's coded this way in anticipation
67; of some future changes to AccessDPT_GetDeviceControlByteToAL.
68
69;--------------------------------------------------------------------
70; IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
71; Parameters:
72; BH: Drive Select byte for Drive and Head Select Register
73; DX: Autodetected port for XT-CF
74; DS: Segment to RAMVARS
75; ES:SI: Ptr to buffer to receive 512-byte IDE Information
76; CS:BP: Ptr to IDEVARS
77; Returns:
78; AH: INT 13h Error Code
79; CF: Cleared if success, Set if error
80; Corrupts registers:
81; AL, BX, CX, DX, SI, DI, ES
82;--------------------------------------------------------------------
83IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH:
84 ; Create fake DPT to be able to use Device.asm functions
85 call FindDPT_ForNewDriveToDSDI
86 eMOVZX ax, bh
87 mov [di+DPT.wFlags], ax
88 call CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI
89 call IdeDPT_StoreDeviceTypeToDPTinDSDIfromIdevarsInCSBP
90 mov BYTE [di+DPT_ATA.bBlockSize], 1 ; Block = 1 sector
91
92 ; Wait until drive motors have reached full speed
93 cmp bp, BYTE ROMVARS.ideVars0 ; First controller?
94 jne SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
95 test bh, FLG_DRVNHEAD_DRV ; Wait already done for Master
96 jnz SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
97 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_BSY)
98 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
99.SkipLongWaitSinceDriveIsNotPrimaryMaster:
100
101 ; Create IDEPACK without INTPACK
102 push bp
103 call Idepack_FakeToSSBP
104
105%ifdef MODULE_8BIT_IDE
106 push si
107
108 ; Enable 8-bit PIO for DEVICE_8BIT_ATA (no need to verify device type here)
109 call AH9h_Enable8bitModeForDevice8bitAta
110
111 ; Set XT-CF mode. No need to check here if device is XT-CF or not.
112%ifdef MODULE_8BIT_IDE_ADVANCED
113 call AH1Eh_GetCurrentXTCFmodeToAX ; Reads from DPT_ATA.bDevice that we just stored
114 call AH9h_SetModeFromALtoXTCF ; Enables/disables 8-bit mode when necessary
115%endif ; MODULE_8BIT_IDE_ADVANCED
116 pop si
117%endif ; MODULE_8BIT_IDE
118
119 ; Prepare to output Identify Device command
120 mov dl, 1 ; Sector count (required by IdeTransfer.asm)
121 mov al, COMMAND_IDENTIFY_DEVICE
122 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
123 call Idepack_StoreNonExtParametersAndIssueCommandFromAL
124
125 ; Clean stack and return
126 lea sp, [bp+SIZE_OF_IDEPACK_WITHOUT_INTPACK] ; This assumes BP hasn't changed between Idepack_FakeToSSBP and here
127 pop bp
128 ret
129
130
131;--------------------------------------------------------------------
132; IdeCommand_OutputWithParameters
133; Parameters:
134; BH: System timer ticks for timeout
135; BL: IDE Status Register bit to poll after command
136; ES:SI: Ptr to buffer (for data transfer commands)
137; DS:DI: Ptr to DPT (in RAMVARS segment)
138; SS:BP: Ptr to IDEPACK
139; Returns:
140; AH: INT 13h Error Code
141; CX: Number of successfully transferred sectors (for transfer commands)
142; CF: Cleared if success, Set if error
143; Corrupts registers:
144; AL, BX, (CX), DX, (ES:SI for data transfer commands)
145;--------------------------------------------------------------------
146ALIGN JUMP_ALIGN
147IdeCommand_OutputWithParameters:
148 push bx ; Store status register bits to poll
149
150 ; Select Master or Slave drive and output head number or LBA28 top bits
151 call IdeCommand_SelectDrive
152 jc SHORT .DriveNotReady
153
154 ; Output Device Control Byte to enable or disable interrupts
155 mov al, [bp+IDEPACK.bDeviceControl]
156%ifdef MODULE_IRQ
157 test al, FLG_DEVCONTROL_nIEN ; Interrupts disabled?
158 jnz SHORT .DoNotSetInterruptInServiceFlag
159
160 ; Clear Task Flag and set Interrupt In-Service Flag
161 push ds
162 LOAD_BDA_SEGMENT_TO ds, dx
163 mov BYTE [BDA.bHDTaskFlg], 1 ; Will be adjusted to zero later
164 pop ds
165.DoNotSetInterruptInServiceFlag:
166%endif
167 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
168
169 ; Output Feature Number
170 mov al, [bp+IDEPACK.bFeatures]
171 OUTPUT_AL_TO_IDE_REGISTER FEATURES_REGISTER_out
172
173 ; Output Sector Address High (only used by LBA48)
174%ifdef MODULE_EBIOS
175 eMOVZX ax, [bp+IDEPACK.bLbaLowExt] ; Zero sector count
176 mov cx, [bp+IDEPACK.wLbaMiddleAndHighExt]
177 call OutputSectorCountAndAddress
178%endif
179
180 ; Output Sector Address Low
181 mov ax, [bp+IDEPACK.wSectorCountAndLbaLow]
182 mov cx, [bp+IDEPACK.wLbaMiddleAndHigh]
183 call OutputSectorCountAndAddress
184
185 ; Output command
186 mov al, [bp+IDEPACK.bCommand]
187 OUTPUT_AL_TO_IDE_REGISTER COMMAND_REGISTER_out
188
189 ; Wait until command completed
190 pop bx ; Pop status and timeout for polling
191 cmp bl, FLG_STATUS_DRQ ; Data transfer started?
192 jne SHORT .WaitUntilNonTransferCommandCompletes
193%ifdef MODULE_8BIT_IDE_ADVANCED
194 cmp BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_JRIDE_ISA
195 jae SHORT JrIdeTransfer_StartWithCommandInAL ; DEVICE_8BIT_JRIDE_ISA or DEVICE_8BIT_ADP50L
196%endif
197 jmp IdeTransfer_StartWithCommandInAL
198
199.WaitUntilNonTransferCommandCompletes:
200%ifdef MODULE_IRQ
201 test BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
202 jz SHORT .PollStatusFlagInsteadOfWaitIrq
203 jmp IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
204.PollStatusFlagInsteadOfWaitIrq:
205%endif
206 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
207
208.DriveNotReady:
209 pop bx ; Clean stack
210 ret
211
212
213;--------------------------------------------------------------------
214; IdeCommand_SelectDrive
215; Parameters:
216; DS:DI: Ptr to DPT (in RAMVARS segment)
217; SS:BP: Ptr to IDEPACK
218; Returns:
219; AH: INT 13h Error Code
220; CF: Cleared if success, Set if error
221; Corrupts registers:
222; AL, BX, CX, DX
223;--------------------------------------------------------------------
224ALIGN JUMP_ALIGN
225IdeCommand_SelectDrive:
226 ; We use different timeout value when detecting drives.
227 ; This prevents unnecessary long delays when drive is not present.
228 mov cx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
229 cmp WORD [RAMVARS.wDrvDetectSignature], RAMVARS_DRV_DETECT_SIGNATURE
230 eCMOVE ch, TIMEOUT_SELECT_DRIVE_DURING_DRIVE_DETECTION
231
232 ; Select Master or Slave Drive
233 mov al, [bp+IDEPACK.bDrvAndHead]
234 OUTPUT_AL_TO_IDE_REGISTER DRIVE_AND_HEAD_SELECT_REGISTER
235 mov bx, cx
236 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
237
238 ; Ignore errors from IDE Error Register (set by previous command)
239 cmp ah, RET_HD_TIMEOUT
240 je SHORT .FailedToSelectDrive
241 xor ax, ax ; Always success unless timeout
242 ret
243.FailedToSelectDrive:
244 stc
245 ret
246
247
248;--------------------------------------------------------------------
249; OutputSectorCountAndAddress
250; Parameters:
251; AH: LBA low bits (Sector Number)
252; AL: Sector Count
253; CL: LBA middle bits (Cylinder Number low)
254; CH: LBA high bits (Cylinder Number high)
255; DS:DI: Ptr to DPT (in RAMVARS segment)
256; Returns:
257; Nothing
258; Corrupts registers:
259; AL, BX, DX
260;--------------------------------------------------------------------
261ALIGN JUMP_ALIGN
262OutputSectorCountAndAddress:
263 OUTPUT_AL_TO_IDE_REGISTER SECTOR_COUNT_REGISTER
264
265 mov al, ah
266 OUTPUT_AL_TO_IDE_REGISTER LBA_LOW_REGISTER
267
268 mov al, cl
269 OUTPUT_AL_TO_IDE_REGISTER LBA_MIDDLE_REGISTER
270
271 mov al, ch
272 OUTPUT_AL_TO_IDE_REGISTER LBA_HIGH_REGISTER
273 ret
Note: See TracBrowser for help on using the repository browser.