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

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

Changes to XTIDE Universal BIOS:

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