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

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

Changes to XTIDE Universal BIOS:

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