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

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

Changes to XTIDE Universal BIOS:

  • Some minor optimizations.
  • Boot menu now displays JR-IDE/ISA bus type (M8).
  • Drive detection now displays ROM segment as JR-IDE/ISA Device address.
File size: 7.6 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%ifdef MODULE_EBIOS
132    eMOVZX  ax, BYTE [bp+IDEPACK.bLbaLowExt]    ; Zero sector count
133    mov     cx, [bp+IDEPACK.wLbaMiddleAndHighExt]
134    call    IDEDEVICE%+OutputSectorCountAndAddress
135%endif
136
137    ; Output Sector Address Low
138    mov     ax, [bp+IDEPACK.wSectorCountAndLbaLow]
139    mov     cx, [bp+IDEPACK.wLbaMiddleAndHigh]
140    call    IDEDEVICE%+OutputSectorCountAndAddress
141
142    ; Output command
143    mov     al, [bp+IDEPACK.bCommand]
144    OUTPUT_AL_TO_IDE_REGISTER   COMMAND_REGISTER_out
145
146    ; Wait until command completed
147    pop     bx                      ; Pop status and timeout for polling
148    cmp     bl, FLG_STATUS_DRQ      ; Data transfer started?
149    je      SHORT IDEDEVICE%+Transfer_StartWithCommandInAL
150    test    BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
151    jz      SHORT .WaitForIrqOrRdy
152    jmp     IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
153
154ALIGN JUMP_ALIGN
155.WaitForIrqOrRdy:
156    jmp     IDEDEVICE%+Wait_IRQorStatusFlagInBLwithTimeoutInBH
157
158.DriveNotReady:
159    pop     bx                          ; Clean stack
160    ret
161
162
163;--------------------------------------------------------------------
164; IdeCommand_SelectDrive
165;   Parameters:
166;       DS:DI:  Ptr to DPT (in RAMVARS segment)
167;       SS:BP:  Ptr to IDEPACK
168;   Returns:
169;       AH:     INT 13h Error Code
170;       CF:     Cleared if success, Set if error
171;   Corrupts registers:
172;       AL, BX, CX, DX
173;--------------------------------------------------------------------
174ALIGN JUMP_ALIGN
175IDEDEVICE%+Command_SelectDrive:
176    ; Wait until neither Master or Slave Drive is busy.
177    ; I don't think this wait is necessary.
178    ;mov        bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_BSY, FLG_STATUS_BSY)
179    ;cmp        BYTE [bp+IDEPACK.bCommand], COMMAND_IDENTIFY_DEVICE
180    ;eCMOVE bh, TIMEOUT_IDENTIFY_DEVICE
181    ;call   IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
182
183    ; Select Master or Slave Drive
184    mov     al, [bp+IDEPACK.bDrvAndHead]
185    OUTPUT_AL_TO_IDE_REGISTER   DRIVE_AND_HEAD_SELECT_REGISTER
186    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
187    cmp     BYTE [bp+IDEPACK.bCommand], COMMAND_IDENTIFY_DEVICE
188    eCMOVE  bh, TIMEOUT_IDENTIFY_DEVICE
189    call    IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
190
191    ; Ignore errors from IDE Error Register (set by previous command)
192    cmp     ah, RET_HD_TIMEOUT
193    je      SHORT .FailedToSelectDrive
194    xor     ax, ax                  ; Always success unless timeout
195    ret
196.FailedToSelectDrive:
197    stc
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.