source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Device/MemoryMappedIDE/MemIdeTransfer.asm @ 376

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

WIDE checkin... Added copyright and license information to sorce files, as per the GPL instructions for usage.

File size: 8.3 KB
RevLine 
[238]1; Project name  :   XTIDE Universal BIOS
2; Description   :   Memory mapped IDE Device transfer functions.
3
[376]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
[238]20; Structure containing variables for PIO transfer functions.
21; This struct must not be larger than IDEPACK without INTPACK.
22struc MEMPIOVARS
23    .wWordsInBlock          resb    2   ; 0, Block size in WORDs
24    .wWordsLeft             resb    2   ; 2, WORDs left to transfer
25    .wWordsDone             resb    2   ; 4, Number of sectors xferred
[242]26    ; TODO: The above word vars could just as well be byte vars?
27                            resb    1   ; 6,
[238]28                            resb    1   ; 7, IDEPACK.bDeviceControl
29    .fpDPT                  resb    4   ; 8, Far pointer to DPT
30endstruc
31
32
33; Section containing code
34SECTION .text
35
36;--------------------------------------------------------------------
37; MemIdeTransfer_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
52MemIdeTransfer_StartWithCommandInAL:
[242]53    push    cs  ; We push CS here (segment of SAW) and later pop it to DS (reads) or ES (writes)
54
[238]55    ; Initialize MEMPIOVARS
[242]56    xor     cx, cx
57    mov     [bp+MEMPIOVARS.wWordsDone], cx
58    mov     ch, [bp+IDEPACK.bSectorCount]
59    mov     [bp+MEMPIOVARS.wWordsLeft], cx
[365]60    mov     ch, [di+DPT_ATA.bBlockSize]
[242]61    mov     [bp+MEMPIOVARS.wWordsInBlock], cx
[238]62    mov     [bp+MEMPIOVARS.fpDPT], di
63    mov     [bp+MEMPIOVARS.fpDPT+2], ds
64
65    ; Are we reading or writing?
[242]66    test    al, 16  ; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
67    jnz     SHORT WriteToSectorAccessWindow
68    cmp     al, COMMAND_WRITE_MULTIPLE
69    je      SHORT WriteToSectorAccessWindow
70    ; Fall to ReadFromSectorAccessWindow
[238]71
[242]72;--------------------------------------------------------------------
73; ReadFromSectorAccessWindow
74;   Parameters:
75;       Stack:  Segment part of ptr to Sector Access Window
76;       ES:SI:  Normalized ptr to buffer to receive data
77;       SS:BP:  Ptr to MEMPIOVARS
78;   Returns:
79;       DS:DI:  Ptr to DPT (in RAMVARS segment)
80;       AH:     BIOS Error code
81;       CX:     Number of successfully transferred sectors
[294]82;       CF:     0 if transfer successful
[242]83;               1 if any error
84;   Corrupts registers:
85;       AL, BX, DX, SI, ES
86;--------------------------------------------------------------------
87ReadFromSectorAccessWindow:
[267]88    pop     ds      ; CS -> DS
89    mov     di, si  ; ES:DI = destination
90    mov     si, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET   ; DS:SI = source
[238]91
[242]92    call    WaitUntilReadyToTransferNextBlock
93    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
94
[267]95    mov     cx, [bp+MEMPIOVARS.wWordsInBlock]
[242]96
[238]97ALIGN JUMP_ALIGN
[242]98.ReadNextBlockFromDrive:
[267]99    cmp     [bp+MEMPIOVARS.wWordsLeft], cx
[242]100    jbe     SHORT .ReadLastBlockFromDrive
101    call    ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
102    call    WaitUntilReadyToTransferNextBlock
103    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
[238]104
[242]105    ; Increment number of successfully read WORDs
[267]106    mov     cx, [bp+MEMPIOVARS.wWordsInBlock]
107    sub     [bp+MEMPIOVARS.wWordsLeft], cx
108    add     [bp+MEMPIOVARS.wWordsDone], cx
[242]109    jmp     SHORT .ReadNextBlockFromDrive
[238]110
[242]111ALIGN JUMP_ALIGN
112.ReadLastBlockFromDrive:
[267]113    mov     ch, [bp+MEMPIOVARS.wWordsLeft+1]    ; Sectors left
[242]114    call    ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
115
116    ; Check for errors in last block
117CheckErrorsAfterTransferringLastMemoryMappedBlock:
118    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
119    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
120    call    IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
121
122    ; Return number of successfully transferred sectors
123ReturnWithMemoryIOtransferErrorInAH:
124    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
[267]125    mov     cx, [bp+MEMPIOVARS.wWordsDone]
[242]126    jc      SHORT .ConvertTransferredWordsInCXtoSectors
[267]127    add     cx, [bp+MEMPIOVARS.wWordsLeft]      ; Never sets CF
[242]128.ConvertTransferredWordsInCXtoSectors:
129    xchg    cl, ch
130    ret
131
132
[238]133;--------------------------------------------------------------------
[242]134; WriteToSectorAccessWindow
[238]135;   Parameters:
[242]136;       Stack:  Segment part of ptr to Sector Access Window
137;       ES:SI:  Normalized ptr to buffer containing data
[238]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
[294]143;       CF:     0 if transfer successful
[238]144;               1 if any error
145;   Corrupts registers:
146;       AL, BX, DX, SI, ES
147;--------------------------------------------------------------------
[242]148ALIGN JUMP_ALIGN
149WriteToSectorAccessWindow:
150    push    es
151    pop     ds
152    pop     es  ; CS -> ES
153    mov     di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
154
[238]155    ; Always poll when writing first block (IRQs are generated for following blocks)
156    call    WaitUntilReadyToTransferNextBlock
157    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
158
[267]159    mov     cx, [bp+MEMPIOVARS.wWordsInBlock]
[242]160
[238]161ALIGN JUMP_ALIGN
162.WriteNextBlockToDrive:
[267]163    cmp     [bp+MEMPIOVARS.wWordsLeft], cx
[238]164    jbe     SHORT .WriteLastBlockToDrive
165    call    WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
166    call    WaitUntilReadyToTransferNextBlock
167    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
168
169    ; Increment number of successfully written WORDs
[267]170    mov     cx, [bp+MEMPIOVARS.wWordsInBlock]
171    sub     [bp+MEMPIOVARS.wWordsLeft], cx
172    add     [bp+MEMPIOVARS.wWordsDone], cx
[238]173    jmp     SHORT .WriteNextBlockToDrive
174
175ALIGN JUMP_ALIGN
176.WriteLastBlockToDrive:
[267]177    mov     ch, [bp+MEMPIOVARS.wWordsLeft+1]        ; Sectors left
[266]178    ePUSH_T bx, CheckErrorsAfterTransferringLastMemoryMappedBlock
[242]179    ; Fall to WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
[238]180
181;--------------------------------------------------------------------
182; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
183;   Parameters:
[242]184;       CH:     Number of sectors in block
[238]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:
[242]191;       BX
[238]192;--------------------------------------------------------------------
193ALIGN JUMP_ALIGN
194WriteSingleBlockFromDSSIToSectorAccessWindowInESDI:
[242]195    mov     bx, di
196    eMOVZX  dx, ch
197    xor     cl, cl
198ALIGN JUMP_ALIGN
199.WriteBlock:
200    mov     ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
[238]201    rep movsw
[242]202    mov     di, bx  ; Reset for next sector
[238]203    dec     dx
[242]204    jnz     SHORT .WriteBlock
[238]205    ret
206
207
208;--------------------------------------------------------------------
209; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
210;   Parameters:
[242]211;       CH:     Number of sectors in block
212;       ES:DI:  Normalized ptr to buffer to receive data (destination)
[238]213;       DS:SI:  Ptr to Sector Access Window (source)
214;   Returns:
215;       CX, DX: Zero
216;       DI:     Updated
217;   Corrupts registers:
[242]218;       BX
[238]219;--------------------------------------------------------------------
220ALIGN JUMP_ALIGN
221ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
[242]222    mov     bx, si
223    eMOVZX  dx, ch
224    xor     cl, cl
225ALIGN JUMP_ALIGN
226.ReadBlock:
227    mov     ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
[238]228    rep movsw
[242]229    mov     si, bx  ; Reset for next sector
[238]230    dec     dx
[242]231    jnz     SHORT .ReadBlock
[238]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    IDEDEVICE%+Wait_IRQorDRQ            ; Always polls
251    pop     di
252    pop     ds
253    ret
[242]254
255
256%if JRIDE_SECTOR_ACCESS_WINDOW_SIZE <> 512
257    %error "JRIDE_SECTOR_ACCESS_WINDOW_SIZE is no longer equal to 512. MemIdeTransfer.asm needs changes."
258%endif
259
Note: See TracBrowser for help on using the repository browser.