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

Last change on this file since 372 was 365, checked in by aitotat@…, 13 years ago

Changes to XTIDE Universal BIOS:

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