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

Last change on this file since 493 was 493, checked in by gregli@…, 11 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.