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

Last change on this file since 395 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.