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

Last change on this file since 539 was 536, checked in by krille_n_@…, 12 years ago

Changes:

  • Added support for the Silicon Valley Computer ADP50L controller (and possibly other IDE controllers from SVC using memory mapped I/O). Please note that this has not been tested in any way since I don't have any of these cards myself (make backups before trying this on drives with important data). Also, *if* it works, make sure it works reliably (stress test the disk system). Some things you should know: 1) Autodetection for this controller has not been added to XTIDECFG, you need to manually select the "SVC ADP50L" controller (and possibly change the BIOS segment address if not using the default of C800h). 2) The memory mapped I/O window is inside the ROM address space of the controller. The XTIDE Universal BIOS currently do not support this so that means you need to use another ROM (for example, an XTIDE or XTCF card or the BOOT ROM of a NIC). This presents another problem, the original ADP50L BIOS needs to be disabled somehow to avoid conflicts. Either pull the ROM chip or disable the BIOS by removing jumper J3. Note, I have no idea if any of this will actually work. It's basically a shot in the dark.
File size: 8.7 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : IDE Device Command functions.
3
4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
12;
13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16; GNU General Public License for more details.
17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
19
20; Section containing code
21SECTION .text
22
23;--------------------------------------------------------------------
24; IdeCommand_ResetMasterAndSlaveController
25; Parameters:
26; DS:DI: Ptr to DPT (in RAMVARS segment)
27; Returns:
28; AH: INT 13h Error Code
29; CF: Cleared if success, Set if error
30; Corrupts registers:
31; AL, BX, CX, DX
32;--------------------------------------------------------------------
33IdeCommand_ResetMasterAndSlaveController:
34 ; HSR0: Set_SRST
35 call AccessDPT_GetDeviceControlByteToAL
36 or al, FLG_DEVCONTROL_SRST | FLG_DEVCONTROL_nIEN ; Set Reset bit
37 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
38 mov ax, HSR0_RESET_WAIT_US
39 call Timer_DelayMicrosecondsFromAX
40
41 ; HSR1: Clear_wait
42 call AccessDPT_GetDeviceControlByteToAL
43 or al, FLG_DEVCONTROL_nIEN
44 and al, ~FLG_DEVCONTROL_SRST ; Clear reset bit
45 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
46 mov ax, HSR1_RESET_WAIT_US
47 call Timer_DelayMicrosecondsFromAX
48
49 ; HSR2: Check_status
50 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MAXIMUM, FLG_STATUS_BSY)
51 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
52
53
54;--------------------------------------------------------------------
55; IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
56; Parameters:
57; BH: Drive Select byte for Drive and Head Select Register
58; DX: Autodetected port for XT-CF
59; DS: Segment to RAMVARS
60; ES:SI: Ptr to buffer to receive 512-byte IDE Information
61; CS:BP: Ptr to IDEVARS
62; Returns:
63; AH: INT 13h Error Code
64; CF: Cleared if success, Set if error
65; Corrupts registers:
66; AL, BX, CX, DX, SI, DI, ES
67;--------------------------------------------------------------------
68IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH:
69 ; Create fake DPT to be able to use Device.asm functions
70 call FindDPT_ForNewDriveToDSDI
71 eMOVZX ax, bh
72 mov [di+DPT.wFlags], ax
73 call CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI
74 call IdeDPT_StoreDeviceTypeToDPTinDSDIfromIdevarsInCSBP
75 mov BYTE [di+DPT_ATA.bBlockSize], 1 ; Block = 1 sector
76
77 ; Wait until drive motors have reached full speed
78 cmp bp, BYTE ROMVARS.ideVars0 ; First controller?
79 jne SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
80 test bh, FLG_DRVNHEAD_DRV ; Wait already done for Master
81 jnz SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
82 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_DRDY)
83 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
84.SkipLongWaitSinceDriveIsNotPrimaryMaster:
85
86 ; Create IDEPACK without INTPACK
87 push bp
88 call Idepack_FakeToSSBP
89
90%ifdef MODULE_8BIT_IDE_ADVANCED
91 ; Enable 8-bit PIO mode for 8-bit ATA and XT-CF
92 push si
93 call AH9h_Enable8bitModeForDevice8bitAta
94 xor al, al ; XTCF_8BIT_PIO_MODE
95 call AH9h_SetModeFromALtoXTCF
96 pop si
97%endif ; MODULE_8BIT_IDE_ADVANCED
98
99 ; Prepare to output Identify Device command
100 mov dl, 1 ; Sector count (required by IdeTransfer.asm)
101 mov al, COMMAND_IDENTIFY_DEVICE
102 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
103 call Idepack_StoreNonExtParametersAndIssueCommandFromAL
104
105 ; Clean stack and return
106.FailedToSet8bitMode:
107 lea sp, [bp+SIZE_OF_IDEPACK_WITHOUT_INTPACK] ; This assumes BP hasn't changed between Idepack_FakeToSSBP and here
108 pop bp
109 ret
110
111
112;--------------------------------------------------------------------
113; IdeCommand_OutputWithParameters
114; Parameters:
115; BH: System timer ticks for timeout
116; BL: IDE Status Register bit to poll after command
117; ES:SI: Ptr to buffer (for data transfer commands)
118; DS:DI: Ptr to DPT (in RAMVARS segment)
119; SS:BP: Ptr to IDEPACK
120; Returns:
121; AH: INT 13h Error Code
122; CX: Number of successfully transferred sectors (for transfer commands)
123; CF: Cleared if success, Set if error
124; Corrupts registers:
125; AL, BX, (CX), DX, (ES:SI for data transfer commands)
126;--------------------------------------------------------------------
127ALIGN JUMP_ALIGN
128IdeCommand_OutputWithParameters:
129 push bx ; Store status register bits to poll
130
131 ; Select Master or Slave drive and output head number or LBA28 top bits
132 call IdeCommand_SelectDrive
133 jc SHORT .DriveNotReady
134
135 ; Output Device Control Byte to enable or disable interrupts
136 mov al, [bp+IDEPACK.bDeviceControl]
137%ifdef MODULE_IRQ
138 test al, FLG_DEVCONTROL_nIEN ; Interrupts disabled?
139 jnz SHORT .DoNotSetInterruptInServiceFlag
140
141 ; Clear Task Flag and set Interrupt In-Service Flag
142 or BYTE [di+DPT.bFlagsHigh], FLGH_DPT_INTERRUPT_IN_SERVICE
143 push ds
144 LOAD_BDA_SEGMENT_TO ds, dx, ! ; Also zero DX
145 mov [BDA.bHDTaskFlg], dl
146 pop ds
147.DoNotSetInterruptInServiceFlag:
148%endif
149 OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
150
151 ; Output Feature Number
152 mov al, [bp+IDEPACK.bFeatures]
153 OUTPUT_AL_TO_IDE_REGISTER FEATURES_REGISTER_out
154
155 ; Output Sector Address High (only used by LBA48)
156%ifdef MODULE_EBIOS
157 eMOVZX ax, [bp+IDEPACK.bLbaLowExt] ; Zero sector count
158 mov cx, [bp+IDEPACK.wLbaMiddleAndHighExt]
159 call OutputSectorCountAndAddress
160%endif
161
162 ; Output Sector Address Low
163 mov ax, [bp+IDEPACK.wSectorCountAndLbaLow]
164 mov cx, [bp+IDEPACK.wLbaMiddleAndHigh]
165 call OutputSectorCountAndAddress
166
167 ; Output command
168 mov al, [bp+IDEPACK.bCommand]
169 OUTPUT_AL_TO_IDE_REGISTER COMMAND_REGISTER_out
170
171 ; Wait until command completed
172 pop bx ; Pop status and timeout for polling
173 cmp bl, FLG_STATUS_DRQ ; Data transfer started?
174 jne SHORT .WaitUntilNonTransferCommandCompletes
175%ifdef MODULE_8BIT_IDE_ADVANCED
176 cmp BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_MEMMAP
177 jae SHORT JrIdeTransfer_StartWithCommandInAL ; DEVICE_8BIT_XTCF_MEMMAP, DEVICE_8BIT_JRIDE_ISA or DEVICE_8BIT_ADP50L
178%endif
179 jmp IdeTransfer_StartWithCommandInAL
180
181.WaitUntilNonTransferCommandCompletes:
182%ifdef MODULE_IRQ
183 test BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
184 jz SHORT .PollStatusFlagInsteadOfWaitIrq
185 jmp IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
186.PollStatusFlagInsteadOfWaitIrq:
187%endif
188 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
189
190.DriveNotReady:
191 pop bx ; Clean stack
192 ret
193
194
195;--------------------------------------------------------------------
196; IdeCommand_SelectDrive
197; Parameters:
198; DS:DI: Ptr to DPT (in RAMVARS segment)
199; SS:BP: Ptr to IDEPACK
200; Returns:
201; AH: INT 13h Error Code
202; CF: Cleared if success, Set if error
203; Corrupts registers:
204; AL, BX, CX, DX
205;--------------------------------------------------------------------
206ALIGN JUMP_ALIGN
207IdeCommand_SelectDrive:
208 ; We use different timeout value when detecting drives.
209 ; This prevents unnecessary long delays when drive is not present.
210 mov cx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
211 cmp WORD [RAMVARS.wDrvDetectSignature], RAMVARS_DRV_DETECT_SIGNATURE
212 eCMOVE ch, TIMEOUT_SELECT_DRIVE_DURING_DRIVE_DETECTION
213
214 ; Select Master or Slave Drive
215 mov al, [bp+IDEPACK.bDrvAndHead]
216 OUTPUT_AL_TO_IDE_REGISTER DRIVE_AND_HEAD_SELECT_REGISTER
217 mov bx, cx
218 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
219
220 ; Ignore errors from IDE Error Register (set by previous command)
221 cmp ah, RET_HD_TIMEOUT
222 je SHORT .FailedToSelectDrive
223 xor ax, ax ; Always success unless timeout
224 ret
225.FailedToSelectDrive:
226 stc
227 ret
228
229
230;--------------------------------------------------------------------
231; OutputSectorCountAndAddress
232; Parameters:
233; AH: LBA low bits (Sector Number)
234; AL: Sector Count
235; CL: LBA middle bits (Cylinder Number low)
236; CH: LBA high bits (Cylinder Number high)
237; DS:DI: Ptr to DPT (in RAMVARS segment)
238; Returns:
239; Nothing
240; Corrupts registers:
241; AL, BX, DX
242;--------------------------------------------------------------------
243ALIGN JUMP_ALIGN
244OutputSectorCountAndAddress:
245 OUTPUT_AL_TO_IDE_REGISTER SECTOR_COUNT_REGISTER
246
247 mov al, ah
248 OUTPUT_AL_TO_IDE_REGISTER LBA_LOW_REGISTER
249
250 mov al, cl
251 OUTPUT_AL_TO_IDE_REGISTER LBA_MIDDLE_REGISTER
252
253 mov al, ch
254 OUTPUT_AL_TO_IDE_REGISTER LBA_HIGH_REGISTER
255 ret
Note: See TracBrowser for help on using the repository browser.