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

Last change on this file since 239 was 238, checked in by aitotat@…, 13 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.