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

Last change on this file since 596 was 596, checked in by krille_n_, 6 years ago

Changes:

  • Made changes to HotkeyBar.asm to give the Boot Menu and Hotkey Bar a more consistent look. It will probably seem a bit strange at first to people used to the classic theme.
  • Added the missing parts of USE_NEC_V that should have been committed with the rest in r593.
  • Removed DEFINES_ALL_FEATURES from the BIOS makefile. It didn't work anymore and never really made sense anyway. Added all the official builds to 'make unused' instead which actually uncovered some unused code in the Tiny build.
  • XTIDECFG will no longer load color themes from unrecognized versions of the BIOS.
  • Other fixes in comments and some minor optimizations.
File size: 9.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-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:   ; Unused entrypoint OK
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:     ; Unused entrypoint OK
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:    ; Unused entrypoint OK
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%ifdef USE_386
203    jnz     IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
204%else
205    jz      SHORT .PollStatusFlagInsteadOfWaitIrq
206    jmp     IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
207.PollStatusFlagInsteadOfWaitIrq:
208%endif
209%endif ; MODULE_IRQ
210    jmp     IdeWait_PollStatusFlagInBLwithTimeoutInBH
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
229IdeCommand_SelectDrive:
230    ; We use different timeout value when detecting drives.
231    ; This prevents unnecessary long delays when drive is not present.
232    mov     cx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
233    cmp     WORD [RAMVARS.wDrvDetectSignature], RAMVARS_DRV_DETECT_SIGNATURE
234    eCMOVE  ch, TIMEOUT_SELECT_DRIVE_DURING_DRIVE_DETECTION
235
236    ; Select Master or Slave Drive
237    mov     al, [bp+IDEPACK.bDrvAndHead]
238    OUTPUT_AL_TO_IDE_REGISTER   DRIVE_AND_HEAD_SELECT_REGISTER
239    mov     bx, cx
240    call    IdeWait_PollStatusFlagInBLwithTimeoutInBH
241
242    ; Ignore errors from IDE Error Register (set by previous command)
243    cmp     ah, RET_HD_TIMEOUT
244    je      SHORT .FailedToSelectDrive
245    xor     ax, ax                  ; Always success unless timeout
246    ret
247.FailedToSelectDrive:
248    stc
249    ret
250
251
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
266OutputSectorCountAndAddress:
267    OUTPUT_AL_TO_IDE_REGISTER   SECTOR_COUNT_REGISTER
268
269    mov     al, ah
270    OUTPUT_AL_TO_IDE_REGISTER   LBA_LOW_REGISTER
271
272    mov     al, cl
273    OUTPUT_AL_TO_IDE_REGISTER   LBA_MIDDLE_REGISTER
274
275    mov     al, ch
276    OUTPUT_AL_TO_IDE_REGISTER   LBA_HIGH_REGISTER
277    ret
Note: See TracBrowser for help on using the repository browser.