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

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

Size optimizations in various files in the XTIDE BIOS.
Also added a new include file for generic macros (macros.inc).

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