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

Last change on this file since 229 was 218, checked in by aitotat@…, 13 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.