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

Last change on this file since 365 was 365, checked in by aitotat@…, 12 years ago

Changes to XTIDE Universal BIOS:

  • Errors from AH=9h are stored to DPTs again.
  • XT build fits in 8k again.
File size: 7.7 KB
RevLine 
[150]1; Project name  :   XTIDE Universal BIOS
2; Description   :   IDE Device Command functions.
3
4; Section containing code
5SECTION .text
6
7;--------------------------------------------------------------------
8; IdeCommand_ResetMasterAndSlaveController
9;   Parameters:
10;       DS:DI:  Ptr to DPT (in RAMVARS segment)
11;   Returns:
12;       AH:     INT 13h Error Code
13;       CF:     Cleared if success, Set if error
14;   Corrupts registers:
15;       AL, BX, CX, DX
16;--------------------------------------------------------------------
[238]17IDEDEVICE%+Command_ResetMasterAndSlaveController:
[150]18    ; HSR0: Set_SRST
19    call    AccessDPT_GetDeviceControlByteToAL
20    or      al, FLG_DEVCONTROL_SRST | FLG_DEVCONTROL_nIEN   ; Set Reset bit
[267]21    OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER     DEVICE_CONTROL_REGISTER_out
[150]22    mov     ax, HSR0_RESET_WAIT_US
[155]23    call    Timer_DelayMicrosecondsFromAX
[150]24
25    ; HSR1: Clear_wait
26    call    AccessDPT_GetDeviceControlByteToAL
27    or      al, FLG_DEVCONTROL_nIEN
28    and     al, ~FLG_DEVCONTROL_SRST                        ; Clear reset bit
[267]29    OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER     DEVICE_CONTROL_REGISTER_out
[150]30    mov     ax, HSR1_RESET_WAIT_US
[155]31    call    Timer_DelayMicrosecondsFromAX
[150]32
33    ; HSR2: Check_status
34    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_BSY)
[238]35    jmp     IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
[150]36
37
38;--------------------------------------------------------------------
39; IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
40;   Parameters:
41;       BH:     Drive Select byte for Drive and Head Select Register
42;       DS:     Segment to RAMVARS
43;       ES:SI:  Ptr to buffer to receive 512-byte IDE Information
44;       CS:BP:  Ptr to IDEVARS
45;   Returns:
46;       AH:     INT 13h Error Code
47;       CF:     Cleared if success, Set if error
48;   Corrupts registers:
49;       AL, BL, CX, DX, SI, DI, ES
50;--------------------------------------------------------------------
[238]51IDEDEVICE%+Command_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH:
[150]52    ; Create fake DPT to be able to use Device.asm functions
53    call    FindDPT_ForNewDriveToDSDI
[158]54    eMOVZX  ax, bh
[150]55    mov     [di+DPT.wFlags], ax
56    mov     [di+DPT.bIdevarsOffset], bp
[365]57    mov     BYTE [di+DPT_ATA.bBlockSize], 1 ; Block = 1 sector
[363]58%ifdef MODULE_ADVANCED_ATA
59    call    IdeDPT_StoreDeviceTypeFromIdevarsInCSBPtoDPTinDSDI
60%endif
[266]61%ifdef ASSEMBLE_SHARED_IDE_DEVICE_FUNCTIONS
[160]62    call    IdeDPT_StoreReversedAddressLinesFlagIfNecessary
[266]63%endif
[150]64
65    ; Wait until drive motors have reached max speed
66    cmp     bp, BYTE ROMVARS.ideVars0
67    jne     SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
[158]68    test    al, FLG_DRVNHEAD_DRV
[150]69    jnz     SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
70    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_BSY)
[238]71    call    IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
[150]72.SkipLongWaitSinceDriveIsNotPrimaryMaster:
73
74    ; Create IDEPACK without INTPACK
75    push    bp
76    call    Idepack_FakeToSSBP
77
78    ; Prepare to output Identify Device command
79    mov     dl, 1                       ; Sector count (required by IdeTransfer.asm)
80    mov     al, COMMAND_IDENTIFY_DEVICE
81    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_IDENTIFY_DEVICE, FLG_STATUS_DRQ)
82    call    Idepack_StoreNonExtParametersAndIssueCommandFromAL
83
84    ; Clean stack and return
[158]85    lea     sp, [bp+EXTRA_BYTES_FOR_INTPACK]    ; This assumes BP hasn't changed between Idepack_FakeToSSBP and here
[150]86    pop     bp
87    ret
88
89
90;--------------------------------------------------------------------
91; IdeCommand_OutputWithParameters
92;   Parameters:
93;       BH:     System timer ticks for timeout
94;       BL:     IDE Status Register bit to poll after command
95;       ES:SI:  Ptr to buffer (for data transfer commands)
96;       DS:DI:  Ptr to DPT (in RAMVARS segment)
97;       SS:BP:  Ptr to IDEPACK
98;   Returns:
99;       AH:     INT 13h Error Code
[249]100;       CX:     Number of successfully transferred sectors (for transfer commands)
[150]101;       CF:     Cleared if success, Set if error
102;   Corrupts registers:
[249]103;       AL, BX, (CX), DX, (ES:SI for data transfer commands)
[150]104;--------------------------------------------------------------------
105ALIGN JUMP_ALIGN
[238]106IDEDEVICE%+Command_OutputWithParameters:
[158]107    push    bx                      ; Store status register bits to poll
[150]108
109    ; Select Master or Slave drive and output head number or LBA28 top bits
[238]110    call    IDEDEVICE%+Command_SelectDrive
[150]111    jc      SHORT .DriveNotReady
112
113    ; Output Device Control Byte to enable or disable interrupts
114    mov     al, [bp+IDEPACK.bDeviceControl]
[266]115%ifdef ASSEMBLE_SHARED_IDE_DEVICE_FUNCTIONS ; JR-IDE/ISA
[158]116    test    al, FLG_DEVCONTROL_nIEN ; Interrupts disabled?
[152]117    jnz     SHORT .DoNotSetInterruptInServiceFlag
[158]118
119    ; Clear Task Flag and set Interrupt In-Service Flag
120    or      BYTE [di+DPT.bFlagsHigh], FLGH_DPT_INTERRUPT_IN_SERVICE
[152]121    push    ds
[158]122    LOAD_BDA_SEGMENT_TO ds, dx, !   ; Also zero DX
123    mov     [BDA.bHDTaskFlg], dl
[152]124    pop     ds
125.DoNotSetInterruptInServiceFlag:
[266]126%endif
[267]127    OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER     DEVICE_CONTROL_REGISTER_out
[150]128
129    ; Output Feature Number
130    mov     al, [bp+IDEPACK.bFeatures]
[267]131    OUTPUT_AL_TO_IDE_REGISTER   FEATURES_REGISTER_out
[150]132
133    ; Output Sector Address High (only used by LBA48)
[285]134%ifdef MODULE_EBIOS
[294]135    eMOVZX  ax, [bp+IDEPACK.bLbaLowExt]     ; Zero sector count
[150]136    mov     cx, [bp+IDEPACK.wLbaMiddleAndHighExt]
[266]137    call    IDEDEVICE%+OutputSectorCountAndAddress
[285]138%endif
[150]139
140    ; Output Sector Address Low
141    mov     ax, [bp+IDEPACK.wSectorCountAndLbaLow]
142    mov     cx, [bp+IDEPACK.wLbaMiddleAndHigh]
[266]143    call    IDEDEVICE%+OutputSectorCountAndAddress
[150]144
145    ; Output command
146    mov     al, [bp+IDEPACK.bCommand]
[267]147    OUTPUT_AL_TO_IDE_REGISTER   COMMAND_REGISTER_out
[150]148
149    ; Wait until command completed
[158]150    pop     bx                      ; Pop status and timeout for polling
151    cmp     bl, FLG_STATUS_DRQ      ; Data transfer started?
[238]152    je      SHORT IDEDEVICE%+Transfer_StartWithCommandInAL
[150]153    test    BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
154    jz      SHORT .WaitForIrqOrRdy
[238]155    jmp     IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
[150]156
157ALIGN JUMP_ALIGN
158.WaitForIrqOrRdy:
[238]159    jmp     IDEDEVICE%+Wait_IRQorStatusFlagInBLwithTimeoutInBH
[150]160
161.DriveNotReady:
162    pop     bx                          ; Clean stack
163    ret
164
165
166;--------------------------------------------------------------------
167; IdeCommand_SelectDrive
168;   Parameters:
169;       DS:DI:  Ptr to DPT (in RAMVARS segment)
170;       SS:BP:  Ptr to IDEPACK
171;   Returns:
172;       AH:     INT 13h Error Code
173;       CF:     Cleared if success, Set if error
174;   Corrupts registers:
175;       AL, BX, CX, DX
176;--------------------------------------------------------------------
177ALIGN JUMP_ALIGN
[238]178IDEDEVICE%+Command_SelectDrive:
[279]179    ; Wait until neither Master or Slave Drive is busy.
180    ; I don't think this wait is necessary.
181    ;mov        bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_BSY, FLG_STATUS_BSY)
182    ;cmp        BYTE [bp+IDEPACK.bCommand], COMMAND_IDENTIFY_DEVICE
183    ;eCMOVE bh, TIMEOUT_IDENTIFY_DEVICE
184    ;call   IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
[150]185
186    ; Select Master or Slave Drive
187    mov     al, [bp+IDEPACK.bDrvAndHead]
[267]188    OUTPUT_AL_TO_IDE_REGISTER   DRIVE_AND_HEAD_SELECT_REGISTER
[150]189    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
190    cmp     BYTE [bp+IDEPACK.bCommand], COMMAND_IDENTIFY_DEVICE
[158]191    eCMOVE  bh, TIMEOUT_IDENTIFY_DEVICE
[279]192    call    IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
[150]193
[281]194    ; Ignore errors from IDE Error Register (set by previous command)
[285]195    cmp     ah, RET_HD_TIMEOUT
196    je      SHORT .FailedToSelectDrive
197    xor     ax, ax                  ; Always success unless timeout
198    ret
199.FailedToSelectDrive:
[281]200    stc
[279]201    ret
[150]202
[279]203
[150]204;--------------------------------------------------------------------
205; OutputSectorCountAndAddress
206;   Parameters:
207;       AH:     LBA low bits (Sector Number)
208;       AL:     Sector Count
209;       CL:     LBA middle bits (Cylinder Number low)
210;       CH:     LBA high bits (Cylinder Number high)
211;       DS:DI:  Ptr to DPT (in RAMVARS segment)
212;   Returns:
213;       Nothing
214;   Corrupts registers:
215;       AL, BX, DX
216;--------------------------------------------------------------------
217ALIGN JUMP_ALIGN
[266]218IDEDEVICE%+OutputSectorCountAndAddress:
[267]219    OUTPUT_AL_TO_IDE_REGISTER   SECTOR_COUNT_REGISTER
[150]220
221    mov     al, ah
[267]222    OUTPUT_AL_TO_IDE_REGISTER   LBA_LOW_REGISTER
[150]223
224    mov     al, cl
[267]225    OUTPUT_AL_TO_IDE_REGISTER   LBA_MIDDLE_REGISTER
[150]226
227    mov     al, ch
[267]228    JUMP_TO_OUTPUT_AL_TO_IDE_REGISTER   LBA_HIGH_REGISTER
Note: See TracBrowser for help on using the repository browser.