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

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

Changes to XTIDE Universal BIOS:

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