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

Last change on this file since 499 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
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
[376]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.
[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;--------------------------------------------------------------------
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;--------------------------------------------------------------------
[400]33IdeCommand_ResetMasterAndSlaveController:
[150]34 ; HSR0: Set_SRST
35 call AccessDPT_GetDeviceControlByteToAL
36 or al, FLG_DEVCONTROL_SRST | FLG_DEVCONTROL_nIEN ; Set Reset bit
[267]37 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
[150]38 mov ax, HSR0_RESET_WAIT_US
[155]39 call Timer_DelayMicrosecondsFromAX
[150]40
41 ; HSR1: Clear_wait
42 call AccessDPT_GetDeviceControlByteToAL
43 or al, FLG_DEVCONTROL_nIEN
44 and al, ~FLG_DEVCONTROL_SRST ; Clear reset bit
[267]45 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
[150]46 mov ax, HSR1_RESET_WAIT_US
[155]47 call Timer_DelayMicrosecondsFromAX
[150]48
49 ; HSR2: Check_status
[432]50 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MAXIMUM, FLG_STATUS_BSY)
[400]51 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
[150]52
53
54;--------------------------------------------------------------------
55; IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
56; Parameters:
57; BH: Drive Select byte for Drive and Head Select Register
[473]58; DX: Autodetected port for XT-CF
[150]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:
[443]66; AL, BX, CX, DX, SI, DI, ES
[150]67;--------------------------------------------------------------------
[400]68IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH:
[150]69 ; Create fake DPT to be able to use Device.asm functions
70 call FindDPT_ForNewDriveToDSDI
[158]71 eMOVZX ax, bh
[150]72 mov [di+DPT.wFlags], ax
[473]73 call CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI
74 call IdeDPT_StoreDeviceTypeToDPTinDSDIfromIdevarsInCSBP
[365]75 mov BYTE [di+DPT_ATA.bBlockSize], 1 ; Block = 1 sector
[150]76
[443]77 ; Wait until drive motors have reached full speed
[473]78 cmp bp, BYTE ROMVARS.ideVars0 ; First controller?
[150]79 jne SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
[473]80 test bh, FLG_DRVNHEAD_DRV ; Wait already done for Master
[150]81 jnz SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
[445]82 call AHDh_WaitUntilDriveMotorHasReachedFullSpeed
[150]83.SkipLongWaitSinceDriveIsNotPrimaryMaster:
84
85 ; Create IDEPACK without INTPACK
86 push bp
87 call Idepack_FakeToSSBP
88
[493]89%ifdef MODULE_8BIT_IDE_ADVANCED
[480]90 ; Enable 8-bit PIO mode for 8-bit ATA and XT-CF
91 push si
92 call AH9h_Enable8bitModeForDevice8bitAta
[473]93 xor al, al ; XTCF_8BIT_PIO_MODE
[480]94 call AH9h_SetModeFromALtoXTCF
[443]95 pop si
[493]96%endif ; MODULE_8BIT_IDE_ADVANCED
[437]97
[150]98 ; Prepare to output Identify Device command
99 mov dl, 1 ; Sector count (required by IdeTransfer.asm)
100 mov al, COMMAND_IDENTIFY_DEVICE
[411]101 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
[150]102 call Idepack_StoreNonExtParametersAndIssueCommandFromAL
103
104 ; Clean stack and return
[439]105.FailedToSet8bitMode:
[443]106 lea sp, [bp+SIZE_OF_IDEPACK_WITHOUT_INTPACK] ; This assumes BP hasn't changed between Idepack_FakeToSSBP and here
[150]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
[249]121; CX: Number of successfully transferred sectors (for transfer commands)
[150]122; CF: Cleared if success, Set if error
123; Corrupts registers:
[249]124; AL, BX, (CX), DX, (ES:SI for data transfer commands)
[150]125;--------------------------------------------------------------------
126ALIGN JUMP_ALIGN
[400]127IdeCommand_OutputWithParameters:
[158]128 push bx ; Store status register bits to poll
[150]129
130 ; Select Master or Slave drive and output head number or LBA28 top bits
[400]131 call IdeCommand_SelectDrive
[150]132 jc SHORT .DriveNotReady
133
134 ; Output Device Control Byte to enable or disable interrupts
135 mov al, [bp+IDEPACK.bDeviceControl]
[400]136%ifdef MODULE_IRQ
[158]137 test al, FLG_DEVCONTROL_nIEN ; Interrupts disabled?
[152]138 jnz SHORT .DoNotSetInterruptInServiceFlag
[158]139
140 ; Clear Task Flag and set Interrupt In-Service Flag
141 or BYTE [di+DPT.bFlagsHigh], FLGH_DPT_INTERRUPT_IN_SERVICE
[152]142 push ds
[158]143 LOAD_BDA_SEGMENT_TO ds, dx, ! ; Also zero DX
144 mov [BDA.bHDTaskFlg], dl
[152]145 pop ds
146.DoNotSetInterruptInServiceFlag:
[266]147%endif
[267]148 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
[150]149
150 ; Output Feature Number
151 mov al, [bp+IDEPACK.bFeatures]
[267]152 OUTPUT_AL_TO_IDE_REGISTER FEATURES_REGISTER_out
[150]153
154 ; Output Sector Address High (only used by LBA48)
[285]155%ifdef MODULE_EBIOS
[294]156 eMOVZX ax, [bp+IDEPACK.bLbaLowExt] ; Zero sector count
[150]157 mov cx, [bp+IDEPACK.wLbaMiddleAndHighExt]
[400]158 call OutputSectorCountAndAddress
[285]159%endif
[150]160
161 ; Output Sector Address Low
162 mov ax, [bp+IDEPACK.wSectorCountAndLbaLow]
163 mov cx, [bp+IDEPACK.wLbaMiddleAndHigh]
[400]164 call OutputSectorCountAndAddress
[150]165
166 ; Output command
167 mov al, [bp+IDEPACK.bCommand]
[267]168 OUTPUT_AL_TO_IDE_REGISTER COMMAND_REGISTER_out
[150]169
170 ; Wait until command completed
[400]171 pop bx ; Pop status and timeout for polling
172 cmp bl, FLG_STATUS_DRQ ; Data transfer started?
173 jne SHORT .WaitUntilNonTransferCommandCompletes
[493]174%ifdef MODULE_8BIT_IDE_ADVANCED
[480]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
[474]178 jmp IdeTransfer_StartWithCommandInAL
[400]179
180.WaitUntilNonTransferCommandCompletes:
181%ifdef MODULE_IRQ
[150]182 test BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
[400]183 jz SHORT .PollStatusFlagInsteadOfWaitIrq
184 jmp IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
185.PollStatusFlagInsteadOfWaitIrq:
186%endif
187 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
[150]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
[400]206IdeCommand_SelectDrive:
[444]207 ; We use different timeout value when detecting drives.
208 ; This prevents unnecessary long delays when drive is not present.
[473]209 mov cx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
[444]210 cmp WORD [RAMVARS.wDrvDetectSignature], RAMVARS_DRV_DETECT_SIGNATURE
[473]211 eCMOVE ch, TIMEOUT_SELECT_DRIVE_DURING_DRIVE_DETECTION
[408]212
[150]213 ; Select Master or Slave Drive
214 mov al, [bp+IDEPACK.bDrvAndHead]
[267]215 OUTPUT_AL_TO_IDE_REGISTER DRIVE_AND_HEAD_SELECT_REGISTER
[473]216 mov bx, cx
[400]217 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
[150]218
[281]219 ; Ignore errors from IDE Error Register (set by previous command)
[285]220 cmp ah, RET_HD_TIMEOUT
221 je SHORT .FailedToSelectDrive
222 xor ax, ax ; Always success unless timeout
223 ret
224.FailedToSelectDrive:
[281]225 stc
[279]226 ret
[150]227
[279]228
[150]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
[400]243OutputSectorCountAndAddress:
[267]244 OUTPUT_AL_TO_IDE_REGISTER SECTOR_COUNT_REGISTER
[150]245
246 mov al, ah
[267]247 OUTPUT_AL_TO_IDE_REGISTER LBA_LOW_REGISTER
[150]248
249 mov al, cl
[267]250 OUTPUT_AL_TO_IDE_REGISTER LBA_MIDDLE_REGISTER
[150]251
252 mov al, ch
[473]253 OUTPUT_AL_TO_IDE_REGISTER LBA_HIGH_REGISTER
254 ret
Note: See TracBrowser for help on using the repository browser.