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

Last change on this file since 594 was 592, checked in by Krister Nordvall, 6 years ago

Changes:

  • The problem with NASM in the previous revision (r591) has been fixed.
  • The colors used by the boot menu and hotkey bar can now be customized by selecting one of a number of pre-defined color themes. Suggestions for additional themes are more than welcome!
  • Large builds are now 10 KB. Small builds are still 8 KB with the exception of the Tiny build which is now 4 KB. In other words, builds are now as small as possible to make it easier to combine them with other BIOSes.
  • Added code to the library to improve drive error handling. XTIDECFG can now handle "Drive Not Ready" errors.
  • Fixed a couple of potential bugs in AtaID.asm (AtaID_GetMaxPioModeToAXandMinCycleTimeToCX); 1) ATA1.bPioMode was treated as a WORD variable. 2) ATA2.bPIOSupp was assumed to be non-zero which would result in PIO mode 3 being returned if the assumption was wrong.
  • Made the same changes in the equivalent function used by BIOSDRVS (DisplayPioModeInformationUsingAtaInfoFromDSBX in AtaInfo.asm).
  • Fixed a bug from r587 in PDC20x30.asm in PDC20x30_GetMaxPioModeToALandMinPioCycleTimeToBX.
  • Fixed a bug from r523 in XTIDECFG where Auto Configure would only set the IRQ on one IDE interface on AT-builds.
  • XTIDECFG will now restore the default settings for the "Serial port virtual device" when reselecting it in the list of device types. This makes it behave consistently for all device types.
  • The eAAM macro is now used regardless if USE_UNDOC_INTEL is defined or not because it is apparently supported on all processors including the NEC V20/V30 CPUs.
  • Renamed the EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS define to EXCLUDE_FROM_XUB.
  • Added a define to exclude unused library code from BIOSDRVS (EXCLUDE_FROM_BIOSDRVS). This makes it a lot smaller than in previous revisions.
  • All unnecessary CLD-instructions are now under a new define 'CLD_NEEDED' which is only enabled for the BIOS. It is disabled for XTIDECFG and BIOSDRVS but can be enabled if needed by adding this define to the respective makefile. This change was made because these unnecessary instructions are wasteful and should never be needed. In fact, they only serve to hide bugs (in other peoples code) which I strongly believe should be avoided. I recommend people making their own BIOSes from source to not use this define as it's extremely unlikely to be needed.
  • Updated the copyright info in SerDrive and changed an URL to point to the new site.
  • Updated the copyright info and version number in BIOSDRVS.
  • Updated the copyright info in XTIDECFG.
  • Optimizations in general.
File size: 9.5 KB
RevLine 
[150]1; Project name : XTIDE Universal BIOS
2; Description : IDE Device Command functions.
3
[376]4;
[445]5; XTIDE Universal BIOS and Associated Tools
[526]6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
[376]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.
[445]12;
[376]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.
[445]17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
[376]19
[150]20; Section containing code
21SECTION .text
22
23;--------------------------------------------------------------------
[507]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
[589]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; ---
[507]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
[589]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; ---
[507]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
[589]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.
[507]68
69;--------------------------------------------------------------------
[150]70; IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
71; Parameters:
72; BH: Drive Select byte for Drive and Head Select Register
[473]73; DX: Autodetected port for XT-CF
[150]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:
[443]81; AL, BX, CX, DX, SI, DI, ES
[150]82;--------------------------------------------------------------------
[400]83IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH:
[150]84 ; Create fake DPT to be able to use Device.asm functions
85 call FindDPT_ForNewDriveToDSDI
[158]86 eMOVZX ax, bh
[150]87 mov [di+DPT.wFlags], ax
[473]88 call CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI
89 call IdeDPT_StoreDeviceTypeToDPTinDSDIfromIdevarsInCSBP
[365]90 mov BYTE [di+DPT_ATA.bBlockSize], 1 ; Block = 1 sector
[150]91
[443]92 ; Wait until drive motors have reached full speed
[473]93 cmp bp, BYTE ROMVARS.ideVars0 ; First controller?
[150]94 jne SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
[473]95 test bh, FLG_DRVNHEAD_DRV ; Wait already done for Master
[150]96 jnz SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
[545]97 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_BSY)
[507]98 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
[150]99.SkipLongWaitSinceDriveIsNotPrimaryMaster:
100
101 ; Create IDEPACK without INTPACK
102 push bp
103 call Idepack_FakeToSSBP
104
[545]105%ifdef MODULE_8BIT_IDE
[480]106 push si
[584]107
108 ; Enable 8-bit PIO for DEVICE_8BIT_ATA (no need to verify device type here)
[480]109 call AH9h_Enable8bitModeForDevice8bitAta
[584]110
111 ; Set XT-CF mode. No need to check here if device is XT-CF or not.
[545]112%ifdef MODULE_8BIT_IDE_ADVANCED
[584]113 call AH1Eh_GetCurrentXTCFmodeToAX ; Reads from DPT_ATA.bDevice that we just stored
114 call AH9h_SetModeFromALtoXTCF ; Enables/disables 8-bit mode when necessary
[545]115%endif ; MODULE_8BIT_IDE_ADVANCED
[443]116 pop si
[545]117%endif ; MODULE_8BIT_IDE
[437]118
[150]119 ; Prepare to output Identify Device command
120 mov dl, 1 ; Sector count (required by IdeTransfer.asm)
121 mov al, COMMAND_IDENTIFY_DEVICE
[411]122 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
[150]123 call Idepack_StoreNonExtParametersAndIssueCommandFromAL
124
125 ; Clean stack and return
[443]126 lea sp, [bp+SIZE_OF_IDEPACK_WITHOUT_INTPACK] ; This assumes BP hasn't changed between Idepack_FakeToSSBP and here
[150]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
[249]141; CX: Number of successfully transferred sectors (for transfer commands)
[150]142; CF: Cleared if success, Set if error
143; Corrupts registers:
[249]144; AL, BX, (CX), DX, (ES:SI for data transfer commands)
[150]145;--------------------------------------------------------------------
146ALIGN JUMP_ALIGN
[400]147IdeCommand_OutputWithParameters:
[158]148 push bx ; Store status register bits to poll
[150]149
150 ; Select Master or Slave drive and output head number or LBA28 top bits
[400]151 call IdeCommand_SelectDrive
[150]152 jc SHORT .DriveNotReady
153
154 ; Output Device Control Byte to enable or disable interrupts
155 mov al, [bp+IDEPACK.bDeviceControl]
[400]156%ifdef MODULE_IRQ
[158]157 test al, FLG_DEVCONTROL_nIEN ; Interrupts disabled?
[152]158 jnz SHORT .DoNotSetInterruptInServiceFlag
[158]159
160 ; Clear Task Flag and set Interrupt In-Service Flag
[152]161 push ds
[540]162 LOAD_BDA_SEGMENT_TO ds, dx
163 mov BYTE [BDA.bHDTaskFlg], 1 ; Will be adjusted to zero later
[152]164 pop ds
165.DoNotSetInterruptInServiceFlag:
[266]166%endif
[267]167 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
[150]168
169 ; Output Feature Number
170 mov al, [bp+IDEPACK.bFeatures]
[267]171 OUTPUT_AL_TO_IDE_REGISTER FEATURES_REGISTER_out
[150]172
173 ; Output Sector Address High (only used by LBA48)
[285]174%ifdef MODULE_EBIOS
[294]175 eMOVZX ax, [bp+IDEPACK.bLbaLowExt] ; Zero sector count
[150]176 mov cx, [bp+IDEPACK.wLbaMiddleAndHighExt]
[400]177 call OutputSectorCountAndAddress
[285]178%endif
[150]179
180 ; Output Sector Address Low
181 mov ax, [bp+IDEPACK.wSectorCountAndLbaLow]
182 mov cx, [bp+IDEPACK.wLbaMiddleAndHigh]
[400]183 call OutputSectorCountAndAddress
[150]184
185 ; Output command
186 mov al, [bp+IDEPACK.bCommand]
[267]187 OUTPUT_AL_TO_IDE_REGISTER COMMAND_REGISTER_out
[150]188
189 ; Wait until command completed
[400]190 pop bx ; Pop status and timeout for polling
191 cmp bl, FLG_STATUS_DRQ ; Data transfer started?
192 jne SHORT .WaitUntilNonTransferCommandCompletes
[493]193%ifdef MODULE_8BIT_IDE_ADVANCED
[545]194 cmp BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_JRIDE_ISA
195 jae SHORT JrIdeTransfer_StartWithCommandInAL ; DEVICE_8BIT_JRIDE_ISA or DEVICE_8BIT_ADP50L
[480]196%endif
[474]197 jmp IdeTransfer_StartWithCommandInAL
[400]198
199.WaitUntilNonTransferCommandCompletes:
200%ifdef MODULE_IRQ
[150]201 test BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
[592]202%ifdef USE_386
203 jnz IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
204%else
[400]205 jz SHORT .PollStatusFlagInsteadOfWaitIrq
206 jmp IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
207.PollStatusFlagInsteadOfWaitIrq:
208%endif
[592]209%endif ; MODULE_IRQ
[400]210 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
[150]211
212.DriveNotReady:
213 pop bx ; Clean stack
214 ret
215
216
217;--------------------------------------------------------------------
218; IdeCommand_SelectDrive
219; Parameters:
220; DS:DI: Ptr to DPT (in RAMVARS segment)
221; SS:BP: Ptr to IDEPACK
222; Returns:
223; AH: INT 13h Error Code
224; CF: Cleared if success, Set if error
225; Corrupts registers:
226; AL, BX, CX, DX
227;--------------------------------------------------------------------
228ALIGN JUMP_ALIGN
[400]229IdeCommand_SelectDrive:
[444]230 ; We use different timeout value when detecting drives.
231 ; This prevents unnecessary long delays when drive is not present.
[473]232 mov cx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
[444]233 cmp WORD [RAMVARS.wDrvDetectSignature], RAMVARS_DRV_DETECT_SIGNATURE
[473]234 eCMOVE ch, TIMEOUT_SELECT_DRIVE_DURING_DRIVE_DETECTION
[408]235
[150]236 ; Select Master or Slave Drive
237 mov al, [bp+IDEPACK.bDrvAndHead]
[267]238 OUTPUT_AL_TO_IDE_REGISTER DRIVE_AND_HEAD_SELECT_REGISTER
[473]239 mov bx, cx
[400]240 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
[150]241
[281]242 ; Ignore errors from IDE Error Register (set by previous command)
[285]243 cmp ah, RET_HD_TIMEOUT
244 je SHORT .FailedToSelectDrive
245 xor ax, ax ; Always success unless timeout
246 ret
247.FailedToSelectDrive:
[281]248 stc
[279]249 ret
[150]250
[279]251
[150]252;--------------------------------------------------------------------
253; OutputSectorCountAndAddress
254; Parameters:
255; AH: LBA low bits (Sector Number)
256; AL: Sector Count
257; CL: LBA middle bits (Cylinder Number low)
258; CH: LBA high bits (Cylinder Number high)
259; DS:DI: Ptr to DPT (in RAMVARS segment)
260; Returns:
261; Nothing
262; Corrupts registers:
263; AL, BX, DX
264;--------------------------------------------------------------------
265ALIGN JUMP_ALIGN
[400]266OutputSectorCountAndAddress:
[267]267 OUTPUT_AL_TO_IDE_REGISTER SECTOR_COUNT_REGISTER
[150]268
269 mov al, ah
[267]270 OUTPUT_AL_TO_IDE_REGISTER LBA_LOW_REGISTER
[150]271
272 mov al, cl
[267]273 OUTPUT_AL_TO_IDE_REGISTER LBA_MIDDLE_REGISTER
[150]274
275 mov al, ch
[473]276 OUTPUT_AL_TO_IDE_REGISTER LBA_HIGH_REGISTER
277 ret
Note: See TracBrowser for help on using the repository browser.