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

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

Changes to XTIDE Universal BIOS:

  • Drive internal write cache is now disabled by default.
  • Fixed a bug where IDE Master/Slave Drive selection returned error if previous IDE command set a ABRT flag in error register.
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.bSetBlock], 1 ; Block = 1 sector
58%ifdef ASSEMBLE_SHARED_IDE_DEVICE_FUNCTIONS
59 call IdeDPT_StoreReversedAddressLinesFlagIfNecessary
60%endif
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 IDEDEVICE%+Wait_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; CX: Number of successfully transferred sectors (for transfer commands)
98; CF: Cleared if success, Set if error
99; Corrupts registers:
100; AL, BX, (CX), DX, (ES:SI for data transfer commands)
101;--------------------------------------------------------------------
102ALIGN JUMP_ALIGN
103IDEDEVICE%+Command_OutputWithParameters:
104 push bx ; Store status register bits to poll
105
106 ; Select Master or Slave drive and output head number or LBA28 top bits
107 call IDEDEVICE%+Command_SelectDrive
108 jc SHORT .DriveNotReady
109
110 ; Output Device Control Byte to enable or disable interrupts
111 mov al, [bp+IDEPACK.bDeviceControl]
112%ifdef ASSEMBLE_SHARED_IDE_DEVICE_FUNCTIONS ; JR-IDE/ISA
113 test al, FLG_DEVCONTROL_nIEN ; Interrupts disabled?
114 jnz SHORT .DoNotSetInterruptInServiceFlag
115
116 ; Clear Task Flag and set Interrupt In-Service Flag
117 or BYTE [di+DPT.bFlagsHigh], FLGH_DPT_INTERRUPT_IN_SERVICE
118 push ds
119 LOAD_BDA_SEGMENT_TO ds, dx, ! ; Also zero DX
120 mov [BDA.bHDTaskFlg], dl
121 pop ds
122.DoNotSetInterruptInServiceFlag:
123%endif
124 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
125
126 ; Output Feature Number
127 mov al, [bp+IDEPACK.bFeatures]
128 OUTPUT_AL_TO_IDE_REGISTER FEATURES_REGISTER_out
129
130 ; Output Sector Address High (only used by LBA48)
131 eMOVZX ax, BYTE [bp+IDEPACK.bLbaLowExt] ; Zero sector count
132 mov cx, [bp+IDEPACK.wLbaMiddleAndHighExt]
133 call IDEDEVICE%+OutputSectorCountAndAddress
134
135 ; Output Sector Address Low
136 mov ax, [bp+IDEPACK.wSectorCountAndLbaLow]
137 mov cx, [bp+IDEPACK.wLbaMiddleAndHigh]
138 call IDEDEVICE%+OutputSectorCountAndAddress
139
140 ; Output command
141 mov al, [bp+IDEPACK.bCommand]
142 OUTPUT_AL_TO_IDE_REGISTER COMMAND_REGISTER_out
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 IDEDEVICE%+Transfer_StartWithCommandInAL
148 test BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
149 jz SHORT .WaitForIrqOrRdy
150 jmp IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
151
152ALIGN JUMP_ALIGN
153.WaitForIrqOrRdy:
154 jmp IDEDEVICE%+Wait_IRQorStatusFlagInBLwithTimeoutInBH
155
156.DriveNotReady:
157 pop bx ; Clean stack
158 ret
159
160
161;--------------------------------------------------------------------
162; IdeCommand_SelectDrive
163; Parameters:
164; DS:DI: Ptr to DPT (in RAMVARS segment)
165; SS:BP: Ptr to IDEPACK
166; Returns:
167; AH: INT 13h Error Code
168; CF: Cleared if success, Set if error
169; Corrupts registers:
170; AL, BX, CX, DX
171;--------------------------------------------------------------------
172ALIGN JUMP_ALIGN
173IDEDEVICE%+Command_SelectDrive:
174 ; Wait until neither Master or Slave Drive is busy.
175 ; I don't think this wait is necessary.
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 IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
180
181 ; Select Master or Slave Drive
182 mov al, [bp+IDEPACK.bDrvAndHead]
183 OUTPUT_AL_TO_IDE_REGISTER DRIVE_AND_HEAD_SELECT_REGISTER
184 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
185 cmp BYTE [bp+IDEPACK.bCommand], COMMAND_IDENTIFY_DEVICE
186 eCMOVE bh, TIMEOUT_IDENTIFY_DEVICE
187 call IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
188 jc SHORT .ErrorWhenSelectingMasterOrSlave
189 ret
190
191 ; Ignore previously unsupported command (for example some SET FEATURES subcommand)
192.ErrorWhenSelectingMasterOrSlave:
193 sub ah, 1 ; Clear CF
194 jz SHORT .IgnoreABRTerror ; RET_HD_INVALID == 1
195 inc ah
196 stc ; Restore error
197.IgnoreABRTerror:
198 ret
199
200
201;--------------------------------------------------------------------
202; OutputSectorCountAndAddress
203; Parameters:
204; AH: LBA low bits (Sector Number)
205; AL: Sector Count
206; CL: LBA middle bits (Cylinder Number low)
207; CH: LBA high bits (Cylinder Number high)
208; DS:DI: Ptr to DPT (in RAMVARS segment)
209; Returns:
210; Nothing
211; Corrupts registers:
212; AL, BX, DX
213;--------------------------------------------------------------------
214ALIGN JUMP_ALIGN
215IDEDEVICE%+OutputSectorCountAndAddress:
216 OUTPUT_AL_TO_IDE_REGISTER SECTOR_COUNT_REGISTER
217
218 mov al, ah
219 OUTPUT_AL_TO_IDE_REGISTER LBA_LOW_REGISTER
220
221 mov al, cl
222 OUTPUT_AL_TO_IDE_REGISTER LBA_MIDDLE_REGISTER
223
224 mov al, ch
225 JUMP_TO_OUTPUT_AL_TO_IDE_REGISTER LBA_HIGH_REGISTER
Note: See TracBrowser for help on using the repository browser.