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

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

Changes:

  • Optimizations (both for size and speed) in IdeTransfer.asm and MemIdeTransfer.asm
  • Fixed a bug where the SingleByteRead/Write functions in IdeTransfer.asm would fail on 128 sector transfers.
  • Fixed some typos and errors in general, comments etc.
File size: 7.6 KB
RevLine 
[238]1; Project name  :   XTIDE Universal BIOS
2; Description   :   Memory mapped IDE Device transfer functions.
3
4; Structure containing variables for PIO transfer functions.
5; This struct must not be larger than IDEPACK without INTPACK.
6struc MEMPIOVARS
7    .wWordsInBlock          resb    2   ; 0, Block size in WORDs
8    .wWordsLeft             resb    2   ; 2, WORDs left to transfer
9    .wWordsDone             resb    2   ; 4, Number of sectors xferred
[242]10    ; TODO: The above word vars could just as well be byte vars?
11                            resb    1   ; 6,
[238]12                            resb    1   ; 7, IDEPACK.bDeviceControl
13    .fpDPT                  resb    4   ; 8, Far pointer to DPT
14endstruc
15
16
17; Section containing code
18SECTION .text
19
20;--------------------------------------------------------------------
21; MemIdeTransfer_StartWithCommandInAL
22;   Parameters:
23;       AL:     IDE command that was used to start the transfer
24;               (all PIO read and write commands including Identify Device)
25;       ES:SI:  Ptr to normalized data buffer
26;       DS:DI:  Ptr to DPT (in RAMVARS segment)
27;       SS:BP:  Ptr to IDEPACK
28;   Returns:
29;       AH:     INT 13h Error Code
30;       CX:     Number of successfully transferred sectors
31;       CF:     Cleared if success, Set if error
32;   Corrupts registers:
33;       AL, BX, DX, SI, ES
34;--------------------------------------------------------------------
35ALIGN JUMP_ALIGN
36MemIdeTransfer_StartWithCommandInAL:
[242]37    push    cs  ; We push CS here (segment of SAW) and later pop it to DS (reads) or ES (writes)
38
[238]39    ; Initialize MEMPIOVARS
[242]40    xor     cx, cx
41    mov     [bp+MEMPIOVARS.wWordsDone], cx
42    mov     ch, [bp+IDEPACK.bSectorCount]
43    mov     [bp+MEMPIOVARS.wWordsLeft], cx
44    mov     ch, [di+DPT_ATA.bSetBlock]
45    mov     [bp+MEMPIOVARS.wWordsInBlock], cx
[238]46    mov     [bp+MEMPIOVARS.fpDPT], di
47    mov     [bp+MEMPIOVARS.fpDPT+2], ds
48
49    ; Are we reading or writing?
[242]50    test    al, 16  ; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
51    jnz     SHORT WriteToSectorAccessWindow
52    cmp     al, COMMAND_WRITE_MULTIPLE
53    je      SHORT WriteToSectorAccessWindow
54    ; Fall to ReadFromSectorAccessWindow
[238]55
[242]56;--------------------------------------------------------------------
57; ReadFromSectorAccessWindow
58;   Parameters:
59;       Stack:  Segment part of ptr to Sector Access Window
60;       ES:SI:  Normalized ptr to buffer to receive data
61;       SS:BP:  Ptr to MEMPIOVARS
62;   Returns:
63;       DS:DI:  Ptr to DPT (in RAMVARS segment)
64;       AH:     BIOS Error code
65;       CX:     Number of successfully transferred sectors
66;       CF:     0 if transfer succesfull
67;               1 if any error
68;   Corrupts registers:
69;       AL, BX, DX, SI, ES
70;--------------------------------------------------------------------
71ReadFromSectorAccessWindow:
72    pop     ds  ; CS -> DS
[238]73    mov     di, si
74    mov     si, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
75
[242]76    call    WaitUntilReadyToTransferNextBlock
77    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
78
79    mov     cx, [bp+PIOVARS.wWordsInBlock]
80
[238]81ALIGN JUMP_ALIGN
[242]82.ReadNextBlockFromDrive:
83    cmp     [bp+PIOVARS.wWordsLeft], cx
84    jbe     SHORT .ReadLastBlockFromDrive
85    call    ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
86    call    WaitUntilReadyToTransferNextBlock
87    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
[238]88
[242]89    ; Increment number of successfully read WORDs
90    mov     cx, [bp+PIOVARS.wWordsInBlock]
91    sub     [bp+PIOVARS.wWordsLeft], cx
92    add     [bp+PIOVARS.wWordsDone], cx
93    jmp     SHORT .ReadNextBlockFromDrive
[238]94
[242]95ALIGN JUMP_ALIGN
96.ReadLastBlockFromDrive:
97    mov     ch, [bp+PIOVARS.wWordsLeft+1]       ; Sectors left
98    call    ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
99
100    ; Check for errors in last block
101CheckErrorsAfterTransferringLastMemoryMappedBlock:
102    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
103    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
104    call    IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
105
106    ; Return number of successfully transferred sectors
107ReturnWithMemoryIOtransferErrorInAH:
108    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
109    mov     cx, [bp+PIOVARS.wWordsDone]
110    jc      SHORT .ConvertTransferredWordsInCXtoSectors
111    add     cx, [bp+PIOVARS.wWordsLeft]         ; Never sets CF
112.ConvertTransferredWordsInCXtoSectors:
113    xchg    cl, ch
114    ret
115
116
[238]117;--------------------------------------------------------------------
[242]118; WriteToSectorAccessWindow
[238]119;   Parameters:
[242]120;       Stack:  Segment part of ptr to Sector Access Window
121;       ES:SI:  Normalized ptr to buffer containing data
[238]122;       SS:BP:  Ptr to MEMPIOVARS
123;   Returns:
124;       DS:DI:  Ptr to DPT (in RAMVARS segment)
125;       AH:     BIOS Error code
126;       CX:     Number of successfully transferred sectors
127;       CF:     0 if transfer succesfull
128;               1 if any error
129;   Corrupts registers:
130;       AL, BX, DX, SI, ES
131;--------------------------------------------------------------------
[242]132ALIGN JUMP_ALIGN
133WriteToSectorAccessWindow:
134    push    es
135    pop     ds
136    pop     es  ; CS -> ES
137    mov     di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
138
[238]139    ; Always poll when writing first block (IRQs are generated for following blocks)
140    call    WaitUntilReadyToTransferNextBlock
141    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
142
[242]143    mov     cx, [bp+PIOVARS.wWordsInBlock]
144
[238]145ALIGN JUMP_ALIGN
146.WriteNextBlockToDrive:
147    cmp     [bp+PIOVARS.wWordsLeft], cx
148    jbe     SHORT .WriteLastBlockToDrive
149    call    WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
150    call    WaitUntilReadyToTransferNextBlock
151    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
152
153    ; Increment number of successfully written WORDs
[242]154    mov     cx, [bp+PIOVARS.wWordsInBlock]
155    sub     [bp+PIOVARS.wWordsLeft], cx
156    add     [bp+PIOVARS.wWordsDone], cx
[238]157    jmp     SHORT .WriteNextBlockToDrive
158
159ALIGN JUMP_ALIGN
160.WriteLastBlockToDrive:
[242]161    mov     ch, [bp+PIOVARS.wWordsLeft+1]       ; Sectors left
162%ifndef USE_186
163    mov     bx, CheckErrorsAfterTransferringLastMemoryMappedBlock
164    push    bx
165%else
[238]166    push    CheckErrorsAfterTransferringLastMemoryMappedBlock
167%endif
[242]168    ; Fall to WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
[238]169
170;--------------------------------------------------------------------
171; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
172;   Parameters:
[242]173;       CH:     Number of sectors in block
[238]174;       DS:SI:  Normalized ptr to source buffer
175;       ES:DI:  Ptr to Sector Access Window
176;   Returns:
177;       CX, DX: Zero
178;       SI:     Updated
179;   Corrupts registers:
[242]180;       BX
[238]181;--------------------------------------------------------------------
182ALIGN JUMP_ALIGN
183WriteSingleBlockFromDSSIToSectorAccessWindowInESDI:
[242]184    mov     bx, di
185    eMOVZX  dx, ch
186    xor     cl, cl
187ALIGN JUMP_ALIGN
188.WriteBlock:
189    mov     ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
[238]190    rep movsw
[242]191    mov     di, bx  ; Reset for next sector
[238]192    dec     dx
[242]193    jnz     SHORT .WriteBlock
[238]194    ret
195
196
197;--------------------------------------------------------------------
198; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
199;   Parameters:
[242]200;       CH:     Number of sectors in block
201;       ES:DI:  Normalized ptr to buffer to receive data (destination)
[238]202;       DS:SI:  Ptr to Sector Access Window (source)
203;   Returns:
204;       CX, DX: Zero
205;       DI:     Updated
206;   Corrupts registers:
[242]207;       BX
[238]208;--------------------------------------------------------------------
209ALIGN JUMP_ALIGN
210ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
[242]211    mov     bx, si
212    eMOVZX  dx, ch
213    xor     cl, cl
214ALIGN JUMP_ALIGN
215.ReadBlock:
216    mov     ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
[238]217    rep movsw
[242]218    mov     si, bx  ; Reset for next sector
[238]219    dec     dx
[242]220    jnz     SHORT .ReadBlock
[238]221    ret
222
223
224;--------------------------------------------------------------------
225; WaitUntilReadyToTransferNextBlock
226;   Parameters:
227;       SS:BP:  Ptr to MEMPIOVARS
228;   Returns:
229;       AH:     INT 13h Error Code
230;       CF:     Cleared if success, Set if error
231;   Corrupts registers:
232;       AL, BX, CX, DX
233;--------------------------------------------------------------------
234ALIGN JUMP_ALIGN
235WaitUntilReadyToTransferNextBlock:
236    push    ds
237    push    di
238    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
239    call    IDEDEVICE%+Wait_IRQorDRQ            ; Always polls
240    pop     di
241    pop     ds
242    ret
[242]243
244
245%if JRIDE_SECTOR_ACCESS_WINDOW_SIZE <> 512
246    %error "JRIDE_SECTOR_ACCESS_WINDOW_SIZE is no longer equal to 512. MemIdeTransfer.asm needs changes."
247%endif
248
Note: See TracBrowser for help on using the repository browser.