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

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

Changes to XTIDE Universal BIOS:

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