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

Last change on this file since 157 was 157, checked in by krille_n_@…, 14 years ago

Changes to the XTIDE Universal BIOS:

  • Size optimizations in IdeTransfer.asm and IdeCommand.asm (saved 12 bytes).
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 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 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 lea sp, [bp+SIZE_OF_FAKE_IDEPACK] ; This assumes BP hasn't changed between Idepack_FakeToSSBP and here
85 pop bp
86 ret
87
88
89;--------------------------------------------------------------------
90; IdeCommand_OutputWithParameters
91; Parameters:
92; BH: System timer ticks for timeout
93; BL: IDE Status Register bit to poll after command
94; ES:SI: Ptr to buffer (for data transfer commands)
95; DS:DI: Ptr to DPT (in RAMVARS segment)
96; SS:BP: Ptr to IDEPACK
97; Returns:
98; AH: INT 13h Error Code
99; CF: Cleared if success, Set if error
100; Corrupts registers:
101; AL, BX, CX, DX, (ES:SI for data transfer commands)
102;--------------------------------------------------------------------
103ALIGN JUMP_ALIGN
104IdeCommand_OutputWithParameters:
105 push bx ; Store status register bits to poll
106
107 ; Select Master or Slave drive and output head number or LBA28 top bits
108 call IdeCommand_SelectDrive
109 jc SHORT .DriveNotReady
110
111 ; Output Device Control Byte to enable or disable interrupts
112 mov dl, DEVICE_CONTROL_REGISTER_out
113 mov al, [bp+IDEPACK.bDeviceControl]
114 test al, FLG_DEVCONTROL_nIEN
115 jnz SHORT .DoNotSetInterruptInServiceFlag
116 or WORD [di+DPT.wFlags], FLG_DPT_INTERRUPT_IN_SERVICE
117 push ds
118 LOAD_BDA_SEGMENT_TO ds, cx, ! ; Also zero CX
119 mov [BDA.bHDTaskFlg], al
120 pop ds
121.DoNotSetInterruptInServiceFlag:
122 call Device_OutputALtoIdeControlBlockRegisterInDL
123
124 ; Output Feature Number
125 mov dl, FEATURES_REGISTER_out
126 mov al, [bp+IDEPACK.bFeatures]
127 call Device_OutputALtoIdeRegisterInDL
128
129 ; Output Sector Address High (only used by LBA48)
130 mov ax, [bp+IDEPACK.wSectorCountHighAndLbaLowExt]
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 Device_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 .StartDataTransfer
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
155ALIGN JUMP_ALIGN
156.StartDataTransfer:
157 jmp IdeTransfer_StartWithCommandInAL
158
159.DriveNotReady:
160 pop bx ; Clean stack
161ReturnSinceTimeoutWhenPollingBusy:
162 ret
163
164
165;--------------------------------------------------------------------
166; IdeCommand_SelectDrive
167; Parameters:
168; DS:DI: Ptr to DPT (in RAMVARS segment)
169; SS:BP: Ptr to IDEPACK
170; Returns:
171; AH: INT 13h Error Code
172; CF: Cleared if success, Set if error
173; Corrupts registers:
174; AL, BX, CX, DX
175;--------------------------------------------------------------------
176ALIGN JUMP_ALIGN
177IdeCommand_SelectDrive:
178 ; Wait until neither Master or Slave Drive is busy
179 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_BSY, FLG_STATUS_BSY)
180 cmp BYTE [bp+IDEPACK.bCommand], COMMAND_IDENTIFY_DEVICE
181 eCMOVE bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_IDENTIFY_DEVICE, FLG_STATUS_BSY)
182 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
183 jc SHORT ReturnSinceTimeoutWhenPollingBusy
184
185 ; Select Master or Slave Drive
186 mov dl, DRIVE_AND_HEAD_SELECT_REGISTER
187 mov al, [bp+IDEPACK.bDrvAndHead]
188 call Device_OutputALtoIdeRegisterInDL
189 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
190 cmp BYTE [bp+IDEPACK.bCommand], COMMAND_IDENTIFY_DEVICE
191 eCMOVE bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_IDENTIFY_DEVICE, FLG_STATUS_DRDY)
192 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
193
194
195;--------------------------------------------------------------------
196; OutputSectorCountAndAddress
197; Parameters:
198; AH: LBA low bits (Sector Number)
199; AL: Sector Count
200; CL: LBA middle bits (Cylinder Number low)
201; CH: LBA high bits (Cylinder Number high)
202; DS:DI: Ptr to DPT (in RAMVARS segment)
203; Returns:
204; Nothing
205; Corrupts registers:
206; AL, BX, DX
207;--------------------------------------------------------------------
208ALIGN JUMP_ALIGN
209OutputSectorCountAndAddress:
210 mov dl, SECTOR_COUNT_REGISTER
211 call Device_OutputALtoIdeRegisterInDL
212
213 mov al, ah
214 mov dl, LBA_LOW_REGISTER
215 call Device_OutputALtoIdeRegisterInDL
216
217 mov al, cl
218 mov dl, LBA_MIDDLE_REGISTER
219 call Device_OutputALtoIdeRegisterInDL
220
221 mov al, ch
222 mov dl, LBA_HIGH_REGISTER
223 jmp Device_OutputALtoIdeRegisterInDL
Note: See TracBrowser for help on using the repository browser.