source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Device/IDE/JrIdeTransfer.asm @ 417

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

Changes to XTIDE Universal BIOS:

  • AT builds now relocate INT 13h stack to top of stolen conventional memory.
  • Some small fixes here and there.
File size: 8.2 KB
Line 
1; Project name  :   XTIDE Universal BIOS
2; Description   :   Memory mapped IDE Device transfer functions.
3
4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2012 by XTIDE Universal BIOS Team.
7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
12;
13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16; GNU General Public License for more details.
17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
19
20; Structure containing variables for PIO transfer functions.
21; This struct must not be larger than IDEPACK without INTPACK.
22struc MEMPIOVARS    ; Must not be larger than 9 bytes! See IDEPACK in RamVars.inc.
23    .wSectorsInBlock        resb    2   ; 0-1, Block size in sectors
24    .fpDPT                  resb    4   ; 2-5, Far pointer to DPT
25    .bSectorsLeft           resb    1   ; 6, Sectors left to transfer
26                            resb    1   ; 7, IDEPACK.bDeviceControl
27    .bSectorsDone           resb    1   ; 8, Number of sectors xferred
28endstruc
29
30
31; Section containing code
32SECTION .text
33
34;--------------------------------------------------------------------
35; JrIdeTransfer_StartWithCommandInAL
36;   Parameters:
37;       AL:     IDE command that was used to start the transfer
38;               (all PIO read and write commands including Identify Device)
39;       ES:SI:  Ptr to normalized data buffer
40;       DS:DI:  Ptr to DPT (in RAMVARS segment)
41;       SS:BP:  Ptr to IDEPACK
42;   Returns:
43;       AH:     INT 13h Error Code
44;       CX:     Number of successfully transferred sectors
45;       CF:     Cleared if success, Set if error
46;   Corrupts registers:
47;       AL, BX, DX, SI, ES
48;--------------------------------------------------------------------
49ALIGN JUMP_ALIGN
50JrIdeTransfer_StartWithCommandInAL:
51    push    cs  ; We push CS here (segment of SAW) and later pop it to DS (reads) or ES (writes)
52
53    ; Initialize PIOVARS
54    xor     cx, cx
55    mov     [bp+MEMPIOVARS.bSectorsDone], cl
56    mov     cl, [bp+IDEPACK.bSectorCount]
57    mov     [bp+MEMPIOVARS.bSectorsLeft], cl
58    mov     cl, [di+DPT_ATA.bBlockSize]
59    mov     [bp+MEMPIOVARS.wSectorsInBlock], cx
60    mov     [bp+MEMPIOVARS.fpDPT], di
61    mov     [bp+MEMPIOVARS.fpDPT+2], ds
62
63    ; Are we reading or writing?
64    test    al, 16  ; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
65    jnz     SHORT WriteToSectorAccessWindow
66    cmp     al, COMMAND_WRITE_MULTIPLE
67    je      SHORT WriteToSectorAccessWindow
68    ; Fall to ReadFromSectorAccessWindow
69
70;--------------------------------------------------------------------
71; ReadFromSectorAccessWindow
72;   Parameters:
73;       Stack:  Segment part of ptr to Sector Access Window
74;       ES:SI:  Normalized ptr to buffer to receive data
75;       SS:BP:  Ptr to MEMPIOVARS
76;   Returns:
77;       DS:DI:  Ptr to DPT (in RAMVARS segment)
78;       AH:     BIOS Error code
79;       CX:     Number of successfully transferred sectors
80;       CF:     0 if transfer successful
81;               1 if any error
82;   Corrupts registers:
83;       AL, BX, DX, SI, ES
84;--------------------------------------------------------------------
85ReadFromSectorAccessWindow:
86    pop     ds      ; CS -> DS
87    mov     di, si  ; ES:DI = destination
88    mov     si, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET   ; DS:SI = source
89
90    call    WaitUntilReadyToTransferNextBlock
91    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
92
93    mov     cx, [bp+MEMPIOVARS.wSectorsInBlock]
94    cmp     [bp+MEMPIOVARS.bSectorsLeft], cl
95    jbe     SHORT .ReadLastBlockFromDrive
96
97ALIGN JUMP_ALIGN
98.ReadNextBlockFromDrive:
99    call    ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
100    call    WaitUntilReadyToTransferNextBlock
101    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
102
103    ; Increment number of successfully read sectors
104    mov     cx, [bp+MEMPIOVARS.wSectorsInBlock]
105    add     [bp+MEMPIOVARS.bSectorsDone], cl
106    sub     [bp+MEMPIOVARS.bSectorsLeft], cl
107    ja      SHORT .ReadNextBlockFromDrive
108
109ALIGN JUMP_ALIGN
110.ReadLastBlockFromDrive:
111    mov     cl, [bp+MEMPIOVARS.bSectorsLeft]
112    call    ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
113
114    ; Check for errors in last block
115CheckErrorsAfterTransferringLastMemoryMappedBlock:
116    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
117    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_BSY)
118    call    IdeWait_PollStatusFlagInBLwithTimeoutInBH
119
120    ; Return number of successfully transferred sectors
121ReturnWithMemoryIOtransferErrorInAH:
122    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
123%ifdef USE_386
124    movzx   cx, [bp+MEMPIOVARS.bSectorsDone]
125%else
126    mov     ch, 0
127    mov     cl, [bp+MEMPIOVARS.bSectorsDone]
128%endif
129    ret
130
131
132;--------------------------------------------------------------------
133; WriteToSectorAccessWindow
134;   Parameters:
135;       Stack:  Segment part of ptr to Sector Access Window
136;       ES:SI:  Normalized ptr to buffer containing data
137;       SS:BP:  Ptr to MEMPIOVARS
138;   Returns:
139;       DS:DI:  Ptr to DPT (in RAMVARS segment)
140;       AH:     BIOS Error code
141;       CX:     Number of successfully transferred sectors
142;       CF:     0 if transfer successful
143;               1 if any error
144;   Corrupts registers:
145;       AL, BX, DX, SI, ES
146;--------------------------------------------------------------------
147ALIGN JUMP_ALIGN
148WriteToSectorAccessWindow:
149    push    es
150    pop     ds
151    pop     es  ; CS -> ES
152    mov     di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
153
154    ; Always poll when writing first block (IRQs are generated for following blocks)
155    call    WaitUntilReadyToTransferNextBlock
156    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
157
158    mov     cx, [bp+MEMPIOVARS.wSectorsInBlock]
159    cmp     [bp+MEMPIOVARS.bSectorsLeft], cl
160    jbe     SHORT .WriteLastBlockToDrive
161
162ALIGN JUMP_ALIGN
163.WriteNextBlockToDrive:
164    call    WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
165    call    WaitUntilReadyToTransferNextBlock
166    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
167
168    ; Increment number of successfully written WORDs
169    mov     cx, [bp+MEMPIOVARS.wSectorsInBlock]
170    add     [bp+MEMPIOVARS.bSectorsDone], cl
171    sub     [bp+MEMPIOVARS.bSectorsLeft], cl
172    ja      SHORT .WriteNextBlockToDrive
173
174ALIGN JUMP_ALIGN
175.WriteLastBlockToDrive:
176    mov     cl, [bp+MEMPIOVARS.bSectorsLeft]
177    ePUSH_T bx, CheckErrorsAfterTransferringLastMemoryMappedBlock
178    ; Fall to WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
179
180;--------------------------------------------------------------------
181; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
182;   Parameters:
183;       CX:     Number of sectors in block
184;       DS:SI:  Normalized ptr to source buffer
185;       ES:DI:  Ptr to Sector Access Window
186;   Returns:
187;       CX, DX: Zero
188;       SI:     Updated
189;   Corrupts registers:
190;       BX
191;--------------------------------------------------------------------
192ALIGN JUMP_ALIGN
193WriteSingleBlockFromDSSIToSectorAccessWindowInESDI:
194    mov     bx, di
195    mov     dx, cx
196    xor     cl, cl
197ALIGN JUMP_ALIGN
198.WriteBlock:
199    mov     ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
200    rep movsw
201    mov     di, bx  ; Reset for next sector
202    dec     dx
203    jnz     SHORT .WriteBlock
204    ret
205
206
207;--------------------------------------------------------------------
208; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
209;   Parameters:
210;       CX      Number of sectors in block
211;       ES:DI:  Normalized ptr to buffer to receive data (destination)
212;       DS:SI:  Ptr to Sector Access Window (source)
213;   Returns:
214;       CX, DX: Zero
215;       DI:     Updated
216;   Corrupts registers:
217;       BX
218;--------------------------------------------------------------------
219ALIGN JUMP_ALIGN
220ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
221    mov     bx, si
222    mov     dx, cx
223    xor     cl, cl
224ALIGN JUMP_ALIGN
225.ReadBlock:
226    mov     ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
227    rep movsw
228    mov     si, bx  ; Reset for next sector
229    dec     dx
230    jnz     SHORT .ReadBlock
231    ret
232
233
234;--------------------------------------------------------------------
235; WaitUntilReadyToTransferNextBlock
236;   Parameters:
237;       SS:BP:  Ptr to MEMPIOVARS
238;   Returns:
239;       AH:     INT 13h Error Code
240;       CF:     Cleared if success, Set if error
241;   Corrupts registers:
242;       AL, BX, CX, DX
243;--------------------------------------------------------------------
244ALIGN JUMP_ALIGN
245WaitUntilReadyToTransferNextBlock:
246    push    ds
247    push    di
248    lds     di, [bp+MEMPIOVARS.fpDPT]   ; DPT now in DS:DI
249    call    IdeWait_IRQorDRQ            ; Always polls
250    pop     di
251    pop     ds
252    ret
253
254
255%if JRIDE_SECTOR_ACCESS_WINDOW_SIZE <> 512
256    %error "JRIDE_SECTOR_ACCESS_WINDOW_SIZE is no longer equal to 512. JrIdeTransfer.asm needs changes."
257%endif
Note: See TracBrowser for help on using the repository browser.