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

Last change on this file since 158 was 158, checked in by aitotat, 13 years ago

Changes to XTIDE Universal BIOS:

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