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

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

Changes:

  • Minor optimizations to the JR-IDE/ISA code.
  • Some cleanups (the MemoryMappedIDE folder and Bootmenu_SwapDrives.txt were deleted).
File size: 8.1 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
23    .wSectorsInBlock        resb    2   ; 0, Block size in sectors
24    .bSectorsLeft           resb    1   ; 2, Sectors left to transfer
25    .bSectorsDone           resb    1   ; 3, Number of sectors xferred
26                            resb    3   ; 4, 5, 6
27                            resb    1   ; 7, IDEPACK.bDeviceControl
28    .fpDPT                  resb    4   ; 8, Far pointer to DPT
29endstruc
30
31
32; Section containing code
33SECTION .text
34
35;--------------------------------------------------------------------
36; JrIdeTransfer_StartWithCommandInAL
37;   Parameters:
38;       AL:     IDE command that was used to start the transfer
39;               (all PIO read and write commands including Identify Device)
40;       ES:SI:  Ptr to normalized data buffer
41;       DS:DI:  Ptr to DPT (in RAMVARS segment)
42;       SS:BP:  Ptr to IDEPACK
43;   Returns:
44;       AH:     INT 13h Error Code
45;       CX:     Number of successfully transferred sectors
46;       CF:     Cleared if success, Set if error
47;   Corrupts registers:
48;       AL, BX, DX, SI, ES
49;--------------------------------------------------------------------
50ALIGN JUMP_ALIGN
51JrIdeTransfer_StartWithCommandInAL:
52    push    cs  ; We push CS here (segment of SAW) and later pop it to DS (reads) or ES (writes)
53
54    ; Initialize PIOVARS
55    xor     cx, cx
56    mov     [bp+MEMPIOVARS.bSectorsDone], cl
57    mov     cl, [bp+IDEPACK.bSectorCount]
58    mov     [bp+MEMPIOVARS.bSectorsLeft], cl
59    mov     cl, [di+DPT_ATA.bBlockSize]
60    mov     [bp+MEMPIOVARS.wSectorsInBlock], cx
61    mov     [bp+MEMPIOVARS.fpDPT], di
62    mov     [bp+MEMPIOVARS.fpDPT+2], ds
63
64    ; Are we reading or writing?
65    test    al, 16  ; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
66    jnz     SHORT WriteToSectorAccessWindow
67    cmp     al, COMMAND_WRITE_MULTIPLE
68    je      SHORT WriteToSectorAccessWindow
69    ; Fall to ReadFromSectorAccessWindow
70
71;--------------------------------------------------------------------
72; ReadFromSectorAccessWindow
73;   Parameters:
74;       Stack:  Segment part of ptr to Sector Access Window
75;       ES:SI:  Normalized ptr to buffer to receive data
76;       SS:BP:  Ptr to MEMPIOVARS
77;   Returns:
78;       DS:DI:  Ptr to DPT (in RAMVARS segment)
79;       AH:     BIOS Error code
80;       CX:     Number of successfully transferred sectors
81;       CF:     0 if transfer successful
82;               1 if any error
83;   Corrupts registers:
84;       AL, BX, DX, SI, ES
85;--------------------------------------------------------------------
86ReadFromSectorAccessWindow:
87    pop     ds      ; CS -> DS
88    mov     di, si  ; ES:DI = destination
89    mov     si, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET   ; DS:SI = source
90
91    call    WaitUntilReadyToTransferNextBlock
92    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
93
94    mov     cx, [bp+MEMPIOVARS.wSectorsInBlock]
95    cmp     [bp+MEMPIOVARS.bSectorsLeft], cl
96    jbe     SHORT .ReadLastBlockFromDrive
97
98ALIGN JUMP_ALIGN
99.ReadNextBlockFromDrive:
100    call    ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
101    call    WaitUntilReadyToTransferNextBlock
102    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
103
104    ; Increment number of successfully read sectors
105    mov     cx, [bp+MEMPIOVARS.wSectorsInBlock]
106    add     [bp+MEMPIOVARS.bSectorsDone], cl
107    sub     [bp+MEMPIOVARS.bSectorsLeft], cl
108    ja      SHORT .ReadNextBlockFromDrive
109
110ALIGN JUMP_ALIGN
111.ReadLastBlockFromDrive:
112    mov     cl, [bp+MEMPIOVARS.bSectorsLeft]
113    call    ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
114
115    ; Check for errors in last block
116CheckErrorsAfterTransferringLastMemoryMappedBlock:
117    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
118    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
119    call    IdeWait_PollStatusFlagInBLwithTimeoutInBH
120
121    ; Return number of successfully transferred sectors
122ReturnWithMemoryIOtransferErrorInAH:
123    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
124%ifdef USE_386
125    movzx   cx, [bp+MEMPIOVARS.bSectorsDone]
126%else
127    mov     ch, 0
128    mov     cl, [bp+MEMPIOVARS.bSectorsDone]
129%endif
130    ret
131
132
133;--------------------------------------------------------------------
134; WriteToSectorAccessWindow
135;   Parameters:
136;       Stack:  Segment part of ptr to Sector Access Window
137;       ES:SI:  Normalized ptr to buffer containing data
138;       SS:BP:  Ptr to MEMPIOVARS
139;   Returns:
140;       DS:DI:  Ptr to DPT (in RAMVARS segment)
141;       AH:     BIOS Error code
142;       CX:     Number of successfully transferred sectors
143;       CF:     0 if transfer successful
144;               1 if any error
145;   Corrupts registers:
146;       AL, BX, DX, SI, ES
147;--------------------------------------------------------------------
148ALIGN JUMP_ALIGN
149WriteToSectorAccessWindow:
150    push    es
151    pop     ds
152    pop     es  ; CS -> ES
153    mov     di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
154
155    ; Always poll when writing first block (IRQs are generated for following blocks)
156    call    WaitUntilReadyToTransferNextBlock
157    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
158
159    mov     cx, [bp+MEMPIOVARS.wSectorsInBlock]
160    cmp     [bp+MEMPIOVARS.bSectorsLeft], cl
161    jbe     SHORT .WriteLastBlockToDrive
162
163ALIGN JUMP_ALIGN
164.WriteNextBlockToDrive:
165    call    WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
166    call    WaitUntilReadyToTransferNextBlock
167    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
168
169    ; Increment number of successfully written WORDs
170    mov     cx, [bp+MEMPIOVARS.wSectorsInBlock]
171    add     [bp+MEMPIOVARS.bSectorsDone], cl
172    sub     [bp+MEMPIOVARS.bSectorsLeft], cl
173    ja      SHORT .WriteNextBlockToDrive
174
175ALIGN JUMP_ALIGN
176.WriteLastBlockToDrive:
177    mov     cl, [bp+MEMPIOVARS.bSectorsLeft]
178    ePUSH_T bx, CheckErrorsAfterTransferringLastMemoryMappedBlock
179    ; Fall to WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
180
181;--------------------------------------------------------------------
182; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
183;   Parameters:
184;       CX:     Number of sectors in block
185;       DS:SI:  Normalized ptr to source buffer
186;       ES:DI:  Ptr to Sector Access Window
187;   Returns:
188;       CX, DX: Zero
189;       SI:     Updated
190;   Corrupts registers:
191;       BX
192;--------------------------------------------------------------------
193ALIGN JUMP_ALIGN
194WriteSingleBlockFromDSSIToSectorAccessWindowInESDI:
195    mov     bx, di
196    mov     dx, cx
197    xor     cl, cl
198ALIGN JUMP_ALIGN
199.WriteBlock:
200    mov     ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
201    rep movsw
202    mov     di, bx  ; Reset for next sector
203    dec     dx
204    jnz     SHORT .WriteBlock
205    ret
206
207
208;--------------------------------------------------------------------
209; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
210;   Parameters:
211;       CX      Number of sectors in block
212;       ES:DI:  Normalized ptr to buffer to receive data (destination)
213;       DS:SI:  Ptr to Sector Access Window (source)
214;   Returns:
215;       CX, DX: Zero
216;       DI:     Updated
217;   Corrupts registers:
218;       BX
219;--------------------------------------------------------------------
220ALIGN JUMP_ALIGN
221ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
222    mov     bx, si
223    mov     dx, cx
224    xor     cl, cl
225ALIGN JUMP_ALIGN
226.ReadBlock:
227    mov     ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
228    rep movsw
229    mov     si, bx  ; Reset for next sector
230    dec     dx
231    jnz     SHORT .ReadBlock
232    ret
233
234
235;--------------------------------------------------------------------
236; WaitUntilReadyToTransferNextBlock
237;   Parameters:
238;       SS:BP:  Ptr to MEMPIOVARS
239;   Returns:
240;       AH:     INT 13h Error Code
241;       CF:     Cleared if success, Set if error
242;   Corrupts registers:
243;       AL, BX, CX, DX
244;--------------------------------------------------------------------
245ALIGN JUMP_ALIGN
246WaitUntilReadyToTransferNextBlock:
247    push    ds
248    push    di
249    lds     di, [bp+MEMPIOVARS.fpDPT]   ; DPT now in DS:DI
250    call    IdeWait_IRQorDRQ            ; Always polls
251    pop     di
252    pop     ds
253    ret
254
255
256%if JRIDE_SECTOR_ACCESS_WINDOW_SIZE <> 512
257    %error "JRIDE_SECTOR_ACCESS_WINDOW_SIZE is no longer equal to 512. JrIdeTransfer.asm needs changes."
258%endif
Note: See TracBrowser for help on using the repository browser.