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

Last change on this file since 536 was 536, checked in by krille_n_@…, 11 years ago

Changes:

  • Added support for the Silicon Valley Computer ADP50L controller (and possibly other IDE controllers from SVC using memory mapped I/O). Please note that this has not been tested in any way since I don't have any of these cards myself (make backups before trying this on drives with important data). Also, *if* it works, make sure it works reliably (stress test the disk system). Some things you should know: 1) Autodetection for this controller has not been added to XTIDECFG, you need to manually select the "SVC ADP50L" controller (and possibly change the BIOS segment address if not using the default of C800h). 2) The memory mapped I/O window is inside the ROM address space of the controller. The XTIDE Universal BIOS currently do not support this so that means you need to use another ROM (for example, an XTIDE or XTCF card or the BOOT ROM of a NIC). This presents another problem, the original ADP50L BIOS needs to be disabled somehow to avoid conflicts. Either pull the ROM chip or disable the BIOS by removing jumper J3. Note, I have no idea if any of this will actually work. It's basically a shot in the dark.
File size: 8.7 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
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;--------------------------------------------------------------------
[150]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
[507]82    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_DRDY)
83    call    IdeWait_PollStatusFlagInBLwithTimeoutInBH
[150]84.SkipLongWaitSinceDriveIsNotPrimaryMaster:
85
86    ; Create IDEPACK without INTPACK
87    push    bp
88    call    Idepack_FakeToSSBP
89
[493]90%ifdef MODULE_8BIT_IDE_ADVANCED
[480]91    ; Enable 8-bit PIO mode for 8-bit ATA and XT-CF
92    push    si
93    call    AH9h_Enable8bitModeForDevice8bitAta
[473]94    xor     al, al                      ; XTCF_8BIT_PIO_MODE
[480]95    call    AH9h_SetModeFromALtoXTCF
[443]96    pop     si
[493]97%endif ; MODULE_8BIT_IDE_ADVANCED
[437]98
[150]99    ; Prepare to output Identify Device command
100    mov     dl, 1                       ; Sector count (required by IdeTransfer.asm)
101    mov     al, COMMAND_IDENTIFY_DEVICE
[411]102    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
[150]103    call    Idepack_StoreNonExtParametersAndIssueCommandFromAL
104
105    ; Clean stack and return
[439]106.FailedToSet8bitMode:
[443]107    lea     sp, [bp+SIZE_OF_IDEPACK_WITHOUT_INTPACK]    ; This assumes BP hasn't changed between Idepack_FakeToSSBP and here
[150]108    pop     bp
109    ret
110
111
112;--------------------------------------------------------------------
113; IdeCommand_OutputWithParameters
114;   Parameters:
115;       BH:     System timer ticks for timeout
116;       BL:     IDE Status Register bit to poll after command
117;       ES:SI:  Ptr to buffer (for data transfer commands)
118;       DS:DI:  Ptr to DPT (in RAMVARS segment)
119;       SS:BP:  Ptr to IDEPACK
120;   Returns:
121;       AH:     INT 13h Error Code
[249]122;       CX:     Number of successfully transferred sectors (for transfer commands)
[150]123;       CF:     Cleared if success, Set if error
124;   Corrupts registers:
[249]125;       AL, BX, (CX), DX, (ES:SI for data transfer commands)
[150]126;--------------------------------------------------------------------
127ALIGN JUMP_ALIGN
[400]128IdeCommand_OutputWithParameters:
[158]129    push    bx                      ; Store status register bits to poll
[150]130
131    ; Select Master or Slave drive and output head number or LBA28 top bits
[400]132    call    IdeCommand_SelectDrive
[150]133    jc      SHORT .DriveNotReady
134
135    ; Output Device Control Byte to enable or disable interrupts
136    mov     al, [bp+IDEPACK.bDeviceControl]
[400]137%ifdef MODULE_IRQ
[158]138    test    al, FLG_DEVCONTROL_nIEN ; Interrupts disabled?
[152]139    jnz     SHORT .DoNotSetInterruptInServiceFlag
[158]140
141    ; Clear Task Flag and set Interrupt In-Service Flag
142    or      BYTE [di+DPT.bFlagsHigh], FLGH_DPT_INTERRUPT_IN_SERVICE
[152]143    push    ds
[158]144    LOAD_BDA_SEGMENT_TO ds, dx, !   ; Also zero DX
145    mov     [BDA.bHDTaskFlg], dl
[152]146    pop     ds
147.DoNotSetInterruptInServiceFlag:
[266]148%endif
[267]149    OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER     DEVICE_CONTROL_REGISTER_out
[150]150
151    ; Output Feature Number
152    mov     al, [bp+IDEPACK.bFeatures]
[267]153    OUTPUT_AL_TO_IDE_REGISTER   FEATURES_REGISTER_out
[150]154
155    ; Output Sector Address High (only used by LBA48)
[285]156%ifdef MODULE_EBIOS
[294]157    eMOVZX  ax, [bp+IDEPACK.bLbaLowExt]     ; Zero sector count
[150]158    mov     cx, [bp+IDEPACK.wLbaMiddleAndHighExt]
[400]159    call    OutputSectorCountAndAddress
[285]160%endif
[150]161
162    ; Output Sector Address Low
163    mov     ax, [bp+IDEPACK.wSectorCountAndLbaLow]
164    mov     cx, [bp+IDEPACK.wLbaMiddleAndHigh]
[400]165    call    OutputSectorCountAndAddress
[150]166
167    ; Output command
168    mov     al, [bp+IDEPACK.bCommand]
[267]169    OUTPUT_AL_TO_IDE_REGISTER   COMMAND_REGISTER_out
[150]170
171    ; Wait until command completed
[400]172    pop     bx                              ; Pop status and timeout for polling
173    cmp     bl, FLG_STATUS_DRQ              ; Data transfer started?
174    jne     SHORT .WaitUntilNonTransferCommandCompletes
[493]175%ifdef MODULE_8BIT_IDE_ADVANCED
[480]176    cmp     BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_MEMMAP
[536]177    jae     SHORT JrIdeTransfer_StartWithCommandInAL    ; DEVICE_8BIT_XTCF_MEMMAP, DEVICE_8BIT_JRIDE_ISA or DEVICE_8BIT_ADP50L
[480]178%endif
[474]179    jmp     IdeTransfer_StartWithCommandInAL
[400]180
181.WaitUntilNonTransferCommandCompletes:
182%ifdef MODULE_IRQ
[150]183    test    BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
[400]184    jz      SHORT .PollStatusFlagInsteadOfWaitIrq
185    jmp     IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
186.PollStatusFlagInsteadOfWaitIrq:
187%endif
188    jmp     IdeWait_PollStatusFlagInBLwithTimeoutInBH
[150]189
190.DriveNotReady:
191    pop     bx                          ; Clean stack
192    ret
193
194
195;--------------------------------------------------------------------
196; IdeCommand_SelectDrive
197;   Parameters:
198;       DS:DI:  Ptr to DPT (in RAMVARS segment)
199;       SS:BP:  Ptr to IDEPACK
200;   Returns:
201;       AH:     INT 13h Error Code
202;       CF:     Cleared if success, Set if error
203;   Corrupts registers:
204;       AL, BX, CX, DX
205;--------------------------------------------------------------------
206ALIGN JUMP_ALIGN
[400]207IdeCommand_SelectDrive:
[444]208    ; We use different timeout value when detecting drives.
209    ; This prevents unnecessary long delays when drive is not present.
[473]210    mov     cx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
[444]211    cmp     WORD [RAMVARS.wDrvDetectSignature], RAMVARS_DRV_DETECT_SIGNATURE
[473]212    eCMOVE  ch, TIMEOUT_SELECT_DRIVE_DURING_DRIVE_DETECTION
[408]213
[150]214    ; Select Master or Slave Drive
215    mov     al, [bp+IDEPACK.bDrvAndHead]
[267]216    OUTPUT_AL_TO_IDE_REGISTER   DRIVE_AND_HEAD_SELECT_REGISTER
[473]217    mov     bx, cx
[400]218    call    IdeWait_PollStatusFlagInBLwithTimeoutInBH
[150]219
[281]220    ; Ignore errors from IDE Error Register (set by previous command)
[285]221    cmp     ah, RET_HD_TIMEOUT
222    je      SHORT .FailedToSelectDrive
223    xor     ax, ax                  ; Always success unless timeout
224    ret
225.FailedToSelectDrive:
[281]226    stc
[279]227    ret
[150]228
[279]229
[150]230;--------------------------------------------------------------------
231; OutputSectorCountAndAddress
232;   Parameters:
233;       AH:     LBA low bits (Sector Number)
234;       AL:     Sector Count
235;       CL:     LBA middle bits (Cylinder Number low)
236;       CH:     LBA high bits (Cylinder Number high)
237;       DS:DI:  Ptr to DPT (in RAMVARS segment)
238;   Returns:
239;       Nothing
240;   Corrupts registers:
241;       AL, BX, DX
242;--------------------------------------------------------------------
243ALIGN JUMP_ALIGN
[400]244OutputSectorCountAndAddress:
[267]245    OUTPUT_AL_TO_IDE_REGISTER   SECTOR_COUNT_REGISTER
[150]246
247    mov     al, ah
[267]248    OUTPUT_AL_TO_IDE_REGISTER   LBA_LOW_REGISTER
[150]249
250    mov     al, cl
[267]251    OUTPUT_AL_TO_IDE_REGISTER   LBA_MIDDLE_REGISTER
[150]252
253    mov     al, ch
[473]254    OUTPUT_AL_TO_IDE_REGISTER   LBA_HIGH_REGISTER
255    ret
Note: See TracBrowser for help on using the repository browser.