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

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

Changes to all parts of the project:

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