source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HPIO.asm @ 34

Last change on this file since 34 was 28, checked in by aitotat, 14 years ago
  • v1.1.1 broke booting from foreign drives, it is now fixed.
  • Improved error handling a bit.
  • Longer DRQ and IRQ timeouts to minimize write timouts with some (bad) CF cards.
  • Default boot menu drive should now be properly selected.
File size: 9.6 KB
Line 
1; File name     :   HPIO.asm
2; Project name  :   IDE BIOS
3; Created date  :   14.12.2007
4; Last update   :   1.8.2010
5; Author        :   Tomi Tilli
6; Description   :   PIO transfer functions.
7
8; Structure containing variables for PIO transfer functions
9struc PIOVARS
10    .fnXfer         resb    2   ; Offset to transfer function
11    .wBlockSize     resb    2   ; Block size in WORDs
12    .wWordsLeft     resb    2   ; Number of WORDs left to transfer
13                                ; (full sectors, can be partial block)
14endstruc
15
16
17; Section containing code
18SECTION .text
19
20;--------------------------------------------------------------------
21; Normalizes far pointer to that offset overflows won't happen
22; when transferring data using PIO.
23;
24; HPIO_NORMALIZE_PTR
25;   Parameters:
26;       %1:%2:      Far pointer to normalize
27;       %3:         Scratch register
28;       %4:         Scratch register
29;   Returns:
30;       %1:%2:      Normalized far pointer
31;   Corrupts registers:
32;       %3, %4
33;--------------------------------------------------------------------
34%macro HPIO_NORMALIZE_PTR 4
35    mov     %4, %2              ; Copy offset to scratch reg
36    and     %2, BYTE 0Fh        ; Clear offset bits 15...4
37    eSHR_IM %4, 4               ; Divide offset by 16
38    mov     %3, %1              ; Copy segment to scratch reg
39    add     %3, %4              ; Add shifted offset to segment
40    mov     %1, %3              ; Set normalized segment
41%endmacro
42
43
44;--------------------------------------------------------------------
45; Reads sectors from hard disk using PIO transfer mode.
46;
47; HPIO_ReadBlock
48;   Parameters:
49;       AL:     Number of sectors to read (1...255)
50;       ES:BX:  Pointer to buffer to recieve data
51;       DS:DI:  Ptr to Disk Parameter Table
52;   Returns:
53;       AH:     BIOS Error code
54;       CF:     0 if transfer succesfull
55;               1 if any error
56;   Corrupts registers:
57;       AL, BX, CX, DX
58;--------------------------------------------------------------------
59ALIGN JUMP_ALIGN
60HPIO_ReadBlock:
61    push    es
62
63    ; Create PIOVARS to stack
64    eENTER  PIOVARS_size, 0
65    sub     bp, BYTE PIOVARS_size           ; SS:BP now points to PIOVARS
66    push    si
67    mov     si, g_rgfnPioRead               ; Offset to read function lookup
68    call    HPIO_InitializePIOVARS          ; Store word count and block size
69    pop     si
70
71    ; Start to read data
72    xchg    bx, di                          ; DS:BX points DPT, ES:DI points buffer
73    mov     dx, [RAMVARS.wIdeBase]          ; Load IDE Base Port address
74    call    HPIO_ReadFromDrive
75
76    ; Destroy stack frame
77    rcl     al, 1                           ; CF to AL bit 0
78    add     bp, BYTE PIOVARS_size
79    eLEAVE
80    rcr     al, 1                           ; Restore CF
81    mov     di, bx                          ; Restore DI
82    pop     es
83    ret
84
85
86;--------------------------------------------------------------------
87; Initializes PIOVARS members.
88;
89; HPIO_InitializePIOVARS
90;   Parameters:
91;       AL:     Number of sectors to transfer (1...255)
92;       SI:     Offset to transfer function lookup table
93;       DS:DI:  Ptr to Disk Parameter Table
94;       ES:BX:  Ptr to source or destination data buffer
95;       SS:BP:  Ptr to PIOVARS
96;   Returns:
97;       ES:BX:  Normalized pointer to data buffer
98;   Corrupts registers:
99;       AX, CX
100;--------------------------------------------------------------------
101ALIGN JUMP_ALIGN
102HPIO_InitializePIOVARS:
103    ; Store number of WORDs to transfer
104    mov     ah, al                              ; Number of WORDs to transfer...
105    xor     al, al                              ; ...to AX
106    mov     [bp+PIOVARS.wWordsLeft], ax         ; Store WORD count
107
108    ; Store block size in WORDs
109    mov     ah, [di+DPT.bSetBlock]              ; AX = block size in WORDs
110    mov     [bp+PIOVARS.wBlockSize], ax         ; Store block size
111
112    ; Get transfer function based on bus type
113    xchg    ax, bx                              ; Backup BX
114    eMOVZX  bx, BYTE [di+DPT.bIdeOff]           ; CS:BX now points to IDEVARS
115    mov     bl, BYTE [cs:bx+IDEVARS.bBusType]   ; Load bus type to BX
116    mov     bx, [cs:bx+si]                      ; Load offset to transfer function
117    mov     [bp+PIOVARS.fnXfer], bx             ; Store offset to transfer function
118    xchg    bx, ax
119    ; Fall to HPIO_NormalizePtr
120
121;--------------------------------------------------------------------
122; Initializes PIOVARS members.
123;
124; HPIO_InitializePIOVARS
125;   Parameters:
126;       ES:BX:  Ptr to source or destination data buffer
127;   Returns:
128;       ES:BX:  Normalized pointer to data buffer
129;   Corrupts registers:
130;       AX, CX
131;--------------------------------------------------------------------
132;ALIGN JUMP_ALIGN
133HPIO_NormalizeDataPointer:
134    HPIO_NORMALIZE_PTR  es, bx, ax, cx
135    ret
136
137
138;--------------------------------------------------------------------
139; Reads blocks using PIO transfers.
140;
141; HPIO_ReadFromDrive
142;   Parameters:
143;       DX:     IDE Data port address
144;       DS:BX:  Ptr to DPT (in RAMVARS segment)
145;       ES:DI:  Normalized ptr to buffer to recieve data
146;       SS:BP:  Ptr to PIOVARS
147;   Returns:
148;       AH:     BIOS Error code
149;       CF:     0 if transfer succesfull
150;               1 if any error
151;   Corrupts registers:
152;       AL, CX, DX, DI
153;--------------------------------------------------------------------
154ALIGN JUMP_ALIGN
155HPIO_ReadFromDrive:
156    cld                                 ; INS to increment DI
157ALIGN JUMP_ALIGN
158.BlockLoop:
159    call    HStatus_WaitIrqOrDrq        ; Wait until ready to transfer
160    jc      SHORT .RetError             ; Return if error (code in AH)
161    mov     cx, [bp+PIOVARS.wBlockSize] ; Load block size
162    sub     [bp+PIOVARS.wWordsLeft], cx ; Transferring last (possibly partial) block?
163    jbe     SHORT .XferLastBlock        ;  If so, jump to transfer
164    call    [bp+PIOVARS.fnXfer]         ; Transfer full block
165    jmp     SHORT .BlockLoop            ; Loop while blocks left
166ALIGN JUMP_ALIGN
167.XferLastBlock:
168    add     cx, [bp+PIOVARS.wWordsLeft] ; CX to partial block size
169    call    [bp+PIOVARS.fnXfer]         ; Transfer possibly partial block
170    jmp     HStatus_WaitBsyDefTime      ; Check for errors
171.RetError:
172    ret
173
174
175;--------------------------------------------------------------------
176; Writes sectors to hard disk using PIO transfer mode.
177;
178; HPIO_WriteBlock
179;   Parameters:
180;       AL:     Number of sectors to write (1...255)
181;       ES:BX:  Pointer to buffer containing data
182;       DS:DI:  Ptr to Disk Parameter Table
183;   Returns:
184;       AH:     BIOS Error code
185;       CF:     0 if transfer successfull
186;               1 if any error
187;   Corrupts registers:
188;       AL, BX, CX, DX
189;--------------------------------------------------------------------
190ALIGN JUMP_ALIGN
191HPIO_WriteBlock:
192    push    es
193    push    si
194
195    ; Create PIOVARS to stack
196    eENTER  PIOVARS_size, 0
197    sub     bp, BYTE PIOVARS_size           ; SS:BP now points to PIOVARS
198    mov     si, g_rgfnPioWrite              ; Offset to write function lookup
199    call    HPIO_InitializePIOVARS          ; Store word count and block size
200
201    ; Prepare pointers and start transfer
202    mov     si, bx                          ; ES:SI now points source buffer
203    mov     bx, di                          ; DS:BX now points DPT
204    call    HPIO_WriteToDrive
205
206    ; Destroy stack frame
207    rcl     al, 1                           ; CF to AL bit 0
208    add     bp, BYTE PIOVARS_size
209    eLEAVE
210    rcr     al, 1                           ; Restore CF
211    pop     si
212    pop     es
213    ret
214
215;--------------------------------------------------------------------
216; Writes blocks using PIO transfers.
217;
218; HPIO_WriteToDrive
219;   Parameters:
220;       DS:BX:  Ptr to DPT (in RAMVARS segment)
221;       ES:SI:  Normalized ptr to buffer containing data
222;       SS:BP:  Ptr to PIOVARS
223;   Returns:
224;       AH:     BIOS Error code
225;       CF:     0 if transfer succesfull
226;               1 if any error
227;   Corrupts registers:
228;       AL, CX, DX, SI
229;--------------------------------------------------------------------
230ALIGN JUMP_ALIGN
231HPIO_WriteToDrive:
232    cld                                     ; OUTS to increment SI
233    call    HStatus_WaitDrqDefTime          ; Always poll DRQ for first block, get status reg to DX
234    jc      SHORT .RetError                 ; Return if error (code in AH)
235    sub     dx, BYTE REGR_IDE_ST            ; DX to Data Port address
236ALIGN JUMP_ALIGN
237.BlockLoop:
238    mov     cx, [bp+PIOVARS.wBlockSize]     ; Load block size
239    sub     [bp+PIOVARS.wWordsLeft], cx     ; Transferring last (possibly partial) block?
240    jbe     SHORT .XferLastBlock            ;  If so, jump to transfer
241    call    [bp+PIOVARS.fnXfer]             ; Transfer full block
242    call    HStatus_WaitIrqOrDrq            ; Wait until ready to transfer
243    jnc     SHORT .BlockLoop                ; If no error, loop while blocks left
244.RetError:
245    ret
246ALIGN JUMP_ALIGN
247.XferLastBlock:
248    add     cx, [bp+PIOVARS.wWordsLeft]     ; CX to partial block size
249    call    [bp+PIOVARS.fnXfer]             ; Transfer possibly partial block
250    jmp     HStatus_WaitIrqOrRdy            ; Check for errors
251
252
253;--------------------------------------------------------------------
254; Bus specific transfer functions and lookup table.
255;
256; HPIO_DualByteRead     Dual port 8-bit XTIDE PIO read transfer
257; HPIO_WordRead         Normal 16-bit IDE PIO read transfer
258; HPIO_DualByteWrite    Dual port 8-bit XTIDE PIO write transfer
259; HPIO_WordWrite        Normal 16-bit IDE PIO write transfer
260;   Parameters:
261;       CX:     Block size in WORDs
262;       DX:     IDE Data port address
263;       ES:DI:  Normalized ptr to buffer to recieve data (read only)
264;       ES:SI:  Normalized ptr to buffer containing data (write only)
265;   Returns:
266;       Nothing
267;   Corrupts registers:
268;       AX, CX
269;--------------------------------------------------------------------
270ALIGN JUMP_ALIGN
271HPIO_DualByteRead:
272    eREP_DUAL_BYTE_PORT_INSW
273    ret
274ALIGN JUMP_ALIGN
275HPIO_WordRead:
276    rep
277    db      6Dh         ; INSW
278    ret
279ALIGN JUMP_ALIGN
280HPIO_DWordRead:
281    shr     cx, 1       ; WORD count to DWORD count
282    rep
283    db      66h         ; Override operand size to 32-bit
284    db      6Dh         ; INSW/INSD
285    ret
286ALIGN JUMP_ALIGN
287HPIO_SingleByteRead:
288    eREP_SINGLE_BYTE_PORT_INSW
289    ret
290
291ALIGN JUMP_ALIGN
292HPIO_DualByteWrite:
293    eREP_DUAL_BYTE_PORT_OUTSW
294    ret
295ALIGN JUMP_ALIGN
296HPIO_WordWrite:
297    eSEG    es          ; Source is ES segment
298    rep
299    db      6Fh         ; OUTSW
300    ret
301ALIGN JUMP_ALIGN
302HPIO_DWordWrite:
303    shr     cx, 1       ; WORD count to DWORD count
304    eSEG    es          ; Source is ES segment
305    rep
306    db      66h         ; Override operand size to 32-bit
307    db      6Fh         ; OUTSW/OUTSD
308    ret
309ALIGN JUMP_ALIGN
310HPIO_SingleByteWrite:
311    eREP_SINGLE_BYTE_PORT_OUTSW
312    ret
313
314ALIGN WORD_ALIGN
315g_rgfnPioRead:
316    dw      HPIO_DualByteRead       ; 8-bit dual port reads
317    dw      HPIO_WordRead           ; 16-bit reads
318    dw      HPIO_DWordRead          ; 32-bit reads
319    dw      HPIO_SingleByteRead     ; 8-bit single port reads
320g_rgfnPioWrite:
321    dw      HPIO_DualByteWrite      ; 8-bit dual port writes
322    dw      HPIO_WordWrite          ; 16-bit writes
323    dw      HPIO_DWordWrite         ; 32-bit writes
324    dw      HPIO_SingleByteWrite    ; 8-bit single port writes
Note: See TracBrowser for help on using the repository browser.