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
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.