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

Last change on this file since 415 was 414, checked in by aitotat@…, 13 years ago

Changes to XTIDE Universal BIOS:

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