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

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

Changes to XTIDE Universal BIOS:

  • Makefile now builds small (8k) and large versions.
  • Completely untested support for JR-IDE/ISA.
File size: 7.7 KB
Line 
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
10                            resb    1   ; 6, 
11                            resb    1   ; 7, IDEPACK.bDeviceControl
12    .fpDPT                  resb    4   ; 8, Far pointer to DPT
13endstruc
14
15
16; Section containing code
17SECTION .text
18
19;--------------------------------------------------------------------
20; MemIdeTransfer_StartWithCommandInAL
21;   Parameters:
22;       AL:     IDE command that was used to start the transfer
23;               (all PIO read and write commands including Identify Device)
24;       ES:SI:  Ptr to normalized data buffer
25;       DS:DI:  Ptr to DPT (in RAMVARS segment)
26;       SS:BP:  Ptr to IDEPACK
27;   Returns:
28;       AH:     INT 13h Error Code
29;       CX:     Number of successfully transferred sectors
30;       CF:     Cleared if success, Set if error
31;   Corrupts registers:
32;       AL, BX, DX, SI, ES
33;--------------------------------------------------------------------
34ALIGN JUMP_ALIGN
35MemIdeTransfer_StartWithCommandInAL:
36    ; Initialize MEMPIOVARS
37    xchg    cx, ax                              ; IDE command to CL
38    xor     al, al
39    mov     ah, [bp+IDEPACK.bSectorCount]
40    mov     [bp+MEMPIOVARS.wWordsLeft], ax
41    cbw
42    mov     [bp+MEMPIOVARS.wWordsDone], ax      ; Zero
43    mov     ah, [di+DPT_ATA.bSetBlock]
44    mov     [bp+MEMPIOVARS.wWordsInBlock], ax
45    mov     [bp+MEMPIOVARS.fpDPT], di
46    mov     [bp+MEMPIOVARS.fpDPT+2], ds
47
48    ; Are we reading or writing?
49    test    cl, 16  ; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
50    jnz     SHORT .PrepareToWriteDataFromESSI
51    cmp     cl, COMMAND_WRITE_MULTIPLE
52    je      SHORT .PrepareToWriteDataFromESSI
53
54    ; Prepare to read data to ES:DI
55    mov     di, si
56    push    cs
57    pop     ds
58    mov     si, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
59    jmp     SHORT ReadFromSectorAccessWindowInDSSItoESDI
60
61ALIGN JUMP_ALIGN
62.PrepareToWriteDataFromESSI:
63    push    es
64    pop     ds
65    push    cs
66    pop     es
67    mov     di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
68    ; Fall to WriteToSectorAccessWindowInESDIfromDSSI
69
70
71;--------------------------------------------------------------------
72; WriteToSectorAccessWindowInESDIfromDSSI
73;   Parameters:
74;       DS:SI:  Normalized ptr to buffer containing data
75;       ES:DI:  Ptr to Sector Access Window
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 succesfull
82;               1 if any error
83;   Corrupts registers:
84;       AL, BX, DX, SI, ES
85;--------------------------------------------------------------------
86WriteToSectorAccessWindowInESDIfromDSSI:
87    ; Always poll when writing first block (IRQs are generated for following blocks)
88    call    WaitUntilReadyToTransferNextBlock
89    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
90
91ALIGN JUMP_ALIGN
92.WriteNextBlockToDrive:
93    mov     cx, [bp+PIOVARS.wWordsInBlock]
94    cmp     [bp+PIOVARS.wWordsLeft], cx
95    jbe     SHORT .WriteLastBlockToDrive
96    eMOVZX  dx, ch                              ; DX = Sectors in block
97    call    WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
98    call    WaitUntilReadyToTransferNextBlock
99    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
100
101    ; Increment number of successfully written WORDs
102    mov     ax, [bp+PIOVARS.wWordsInBlock]
103    sub     [bp+PIOVARS.wWordsLeft], ax
104    add     [bp+PIOVARS.wWordsDone], ax
105    jmp     SHORT .WriteNextBlockToDrive
106
107ALIGN JUMP_ALIGN
108.WriteLastBlockToDrive:
109    eMOVZX  dx, BYTE [bp+PIOVARS.wWordsLeft+1]  ; Sectors left
110%ifdef USE_186
111    push    CheckErrorsAfterTransferringLastMemoryMappedBlock
112    jmp     WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
113%else
114    call    WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
115    jmp     SHORT CheckErrorsAfterTransferringLastMemoryMappedBlock
116%endif
117
118
119;--------------------------------------------------------------------
120; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
121;   Parameters:
122;       DX:     Number of sectors in block
123;       DS:SI:  Normalized ptr to source buffer
124;       ES:DI:  Ptr to Sector Access Window
125;   Returns:
126;       CX, DX: Zero
127;       SI:     Updated
128;   Corrupts registers:
129;       Nothing
130;--------------------------------------------------------------------
131ALIGN JUMP_ALIGN
132WriteSingleBlockFromDSSIToSectorAccessWindowInESDI:
133    mov     cx, JRIDE_SECTOR_ACCESS_WINDOW_SIZE / 2
134    rep movsw
135    sub     di, JRIDE_SECTOR_ACCESS_WINDOW_SIZE ; Reset for next sector
136    dec     dx
137    jnz     SHORT WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
138    ret
139
140
141;--------------------------------------------------------------------
142; ReadFromSectorAccessWindowInDSSItoESDI
143;   Parameters:
144;       ES:DI:  Normalized ptr to buffer to recieve data
145;       DS:SI:  Ptr to Sector Access Window
146;       SS:BP:  Ptr to MEMPIOVARS
147;   Returns:
148;       DS:DI:  Ptr to DPT (in RAMVARS segment)
149;       AH:     BIOS Error code
150;       CX:     Number of successfully transferred sectors
151;       CF:     0 if transfer succesfull
152;               1 if any error
153;   Corrupts registers:
154;       AL, BX, DX, SI, ES
155;--------------------------------------------------------------------
156ALIGN JUMP_ALIGN
157ReadFromSectorAccessWindowInDSSItoESDI:
158    call    WaitUntilReadyToTransferNextBlock
159    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
160
161ALIGN JUMP_ALIGN
162.ReadNextBlockFromDrive:
163    mov     cx, [bp+PIOVARS.wWordsInBlock]
164    cmp     [bp+PIOVARS.wWordsLeft], cx
165    jbe     SHORT .ReadLastBlockFromDrive
166    eMOVZX  dx, ch                              ; DX = Sectors in block
167    call    ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
168    call    WaitUntilReadyToTransferNextBlock
169    jc      SHORT ReturnWithMemoryIOtransferErrorInAH
170
171    ; Increment number of successfully read WORDs
172    mov     ax, [bp+PIOVARS.wWordsInBlock]
173    sub     [bp+PIOVARS.wWordsLeft], ax
174    add     [bp+PIOVARS.wWordsDone], ax
175    jmp     SHORT .ReadNextBlockFromDrive
176
177ALIGN JUMP_ALIGN
178.ReadLastBlockFromDrive:
179    eMOVZX  dx, BYTE [bp+PIOVARS.wWordsLeft+1]  ; Sectors left
180    call    ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
181
182    ; Check for errors in last block
183CheckErrorsAfterTransferringLastMemoryMappedBlock:
184    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
185    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
186    call    IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
187
188    ; Return number of successfully read sectors
189ReturnWithMemoryIOtransferErrorInAH:
190    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
191    mov     cx, [bp+PIOVARS.wWordsDone]
192    jc      SHORT .ConvertTransferredWordsInCXtoSectors
193    add     cx, [bp+PIOVARS.wWordsLeft]         ; Never sets CF
194.ConvertTransferredWordsInCXtoSectors:
195    xchg    cl, ch
196    ret
197
198
199;--------------------------------------------------------------------
200; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
201;   Parameters:
202;       DX:     Number of sectors in block
203;       ES:DI:  Normalized ptr to buffer to recieve data (destination)
204;       DS:SI:  Ptr to Sector Access Window (source)
205;   Returns:
206;       CX, DX: Zero
207;       DI:     Updated
208;   Corrupts registers:
209;       Nothing
210;--------------------------------------------------------------------
211ALIGN JUMP_ALIGN
212ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
213    mov     cx, JRIDE_SECTOR_ACCESS_WINDOW_SIZE / 2
214    rep movsw
215    sub     si, JRIDE_SECTOR_ACCESS_WINDOW_SIZE ; Reset for next sector
216    dec     dx
217    jnz     SHORT ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
218    ret
219
220
221;--------------------------------------------------------------------
222; WaitUntilReadyToTransferNextBlock
223;   Parameters:
224;       SS:BP:  Ptr to MEMPIOVARS
225;   Returns:
226;       AH:     INT 13h Error Code
227;       CF:     Cleared if success, Set if error
228;   Corrupts registers:
229;       AL, BX, CX, DX
230;--------------------------------------------------------------------
231ALIGN JUMP_ALIGN
232WaitUntilReadyToTransferNextBlock:
233    push    ds
234    push    di
235    lds     di, [bp+MEMPIOVARS.fpDPT]           ; DPT now in DS:DI
236    call    IDEDEVICE%+Wait_IRQorDRQ            ; Always polls
237    pop     di
238    pop     ds
239    ret
Note: See TracBrowser for help on using the repository browser.