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

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

Changes to XTIDE Universal BIOS:

  • Integrated XT-CFv3 support by James Pearce.
  • XT-CFv2 memory mapped I/O and DMA modes are no longer supported (but PIO mode is).
File size: 9.1 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
[526]6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
[400]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)
[480]39; ES:SI: Ptr to data buffer
[400]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:
[473]51 ; Initialize MEMPIOVARS
52 xchg cx, ax ; IDE command to CL
53 xor ax, ax
54 mov [bp+MEMPIOVARS.bSectorsDone], al
[538]55 mov dh, [bp+IDEPACK.bSectorCount]
56 mov [bp+MEMPIOVARS.bSectorsLeft], dh
[473]57 mov al, [di+DPT_ATA.bBlockSize]
58 mov [bp+MEMPIOVARS.wSectorsInBlock], ax
[400]59 mov [bp+MEMPIOVARS.fpDPT], di
60 mov [bp+MEMPIOVARS.fpDPT+2], ds
61
[480]62 ; Normalize pointer
63 call IdeTransfer_NormalizePointerInESSI
[538]64%ifdef USE_AT
65 jc SHORT ReturnWithMemoryIOtransferErrorInAH
66%endif
[480]67
[473]68 ; Get far pointer to Sector Access Window
69 cmp BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_JRIDE_ISA
[545]70 mov ds, [di+DPT.wBasePort] ; Segment for JR-IDE/ISA and ADP50L
[536]71 mov di, ADP50L_SECTOR_ACCESS_WINDOW_OFFSET
[545]72 eCMOVE di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
[473]73
[400]74 ; Are we reading or writing?
[473]75.SectorAccessWindowLoadedToDSDI:
76 test cl, 16 ; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
[400]77 jnz SHORT WriteToSectorAccessWindow
[473]78 cmp cl, COMMAND_WRITE_MULTIPLE
[400]79 je SHORT WriteToSectorAccessWindow
80 ; Fall to ReadFromSectorAccessWindow
81
82;--------------------------------------------------------------------
83; ReadFromSectorAccessWindow
84; Parameters:
[473]85; DS:DI: Ptr to Sector Access Window
[400]86; ES:SI: Normalized ptr to buffer to receive data
87; SS:BP: Ptr to MEMPIOVARS
88; Returns:
89; DS:DI: Ptr to DPT (in RAMVARS segment)
90; AH: BIOS Error code
91; CX: Number of successfully transferred sectors
92; CF: 0 if transfer successful
93; 1 if any error
94; Corrupts registers:
[475]95; AL, BX, DX, SI
[400]96;--------------------------------------------------------------------
97ReadFromSectorAccessWindow:
[473]98 xchg si, di ; DS:SI = source, ES:DI = Destination
[400]99 call WaitUntilReadyToTransferNextBlock
100 jc SHORT ReturnWithMemoryIOtransferErrorInAH
101
[475]102 mov cx, [bp+MEMPIOVARS.wSectorsInBlock] ; Clears CH
[412]103 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
104 jbe SHORT .ReadLastBlockFromDrive
[400]105
106ALIGN JUMP_ALIGN
107.ReadNextBlockFromDrive:
108 call ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
109 call WaitUntilReadyToTransferNextBlock
110 jc SHORT ReturnWithMemoryIOtransferErrorInAH
111
[476]112 ; Update number of successfully read sectors and sectors left to transfer.
113 ; We cannot use SUB instruction as a comparison since it will not
114 ; work in this situation:
115 ; Before SUB we have 2 full blocks left to transfer. SUB command
116 ; then compares 2 full blocks against one full block and updates
117 ; sectors left to one full block and jumps to .ReadNextBlockFromDrive,
118 ; since we have one full block left to transfer. After it has been
119 ; transferred, there will be a wait for next block but DRQ is never
120 ; set since all is transferred! Then we get timeout error.
[400]121 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
[476]122 sub [bp+MEMPIOVARS.bSectorsLeft], cl
[412]123 add [bp+MEMPIOVARS.bSectorsDone], cl
[476]124 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
[412]125 ja SHORT .ReadNextBlockFromDrive
[400]126
127ALIGN JUMP_ALIGN
128.ReadLastBlockFromDrive:
129 mov cl, [bp+MEMPIOVARS.bSectorsLeft]
[419]130 push cx
[400]131 call ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
132
133 ; Check for errors in last block
134CheckErrorsAfterTransferringLastMemoryMappedBlock:
135 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
[417]136 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_BSY)
[400]137 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
[419]138 pop cx ; [bp+MEMPIOVARS.bSectorsLeft]
139 jc SHORT ReturnWithMemoryIOtransferErrorInAH
[400]140
[445]141 ; All sectors successfully transferred
[475]142 add cl, [bp+MEMPIOVARS.bSectorsDone] ; Never sets CF
[419]143 ret
144
[400]145 ; Return number of successfully transferred sectors
146ReturnWithMemoryIOtransferErrorInAH:
147 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
148%ifdef USE_386
[475]149 movzx cx, BYTE [bp+MEMPIOVARS.bSectorsDone]
[400]150%else
[475]151 mov ch, 0 ; Preserve CF
[400]152 mov cl, [bp+MEMPIOVARS.bSectorsDone]
153%endif
154 ret
155
156
157;--------------------------------------------------------------------
158; WriteToSectorAccessWindow
159; Parameters:
[473]160; DS:DI: Ptr to Sector Access Window
[400]161; ES:SI: Normalized ptr to buffer containing data
162; SS:BP: Ptr to MEMPIOVARS
163; Returns:
164; DS:DI: Ptr to DPT (in RAMVARS segment)
165; AH: BIOS Error code
166; CX: Number of successfully transferred sectors
167; CF: 0 if transfer successful
168; 1 if any error
169; Corrupts registers:
170; AL, BX, DX, SI, ES
171;--------------------------------------------------------------------
172ALIGN JUMP_ALIGN
173WriteToSectorAccessWindow:
174 push es
[473]175 push ds
176 pop es ; ES:DI = Sector Access Window (destination)
177 pop ds ; DS:SI = Ptr to source buffer
[400]178
179 ; Always poll when writing first block (IRQs are generated for following blocks)
180 call WaitUntilReadyToTransferNextBlock
181 jc SHORT ReturnWithMemoryIOtransferErrorInAH
182
183 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
[412]184 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
185 jbe SHORT .WriteLastBlockToDrive
[400]186
187ALIGN JUMP_ALIGN
188.WriteNextBlockToDrive:
189 call WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
190 call WaitUntilReadyToTransferNextBlock
191 jc SHORT ReturnWithMemoryIOtransferErrorInAH
192
193 ; Increment number of successfully written WORDs
194 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
[476]195 sub [bp+MEMPIOVARS.bSectorsLeft], cl
[412]196 add [bp+MEMPIOVARS.bSectorsDone], cl
[476]197 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
[412]198 ja SHORT .WriteNextBlockToDrive
[400]199
200ALIGN JUMP_ALIGN
201.WriteLastBlockToDrive:
202 mov cl, [bp+MEMPIOVARS.bSectorsLeft]
[419]203 push cx
[400]204 ePUSH_T bx, CheckErrorsAfterTransferringLastMemoryMappedBlock
205 ; Fall to WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
206
207;--------------------------------------------------------------------
208; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
209; Parameters:
210; CX: Number of sectors in block
211; DS:SI: Normalized ptr to source buffer
212; ES:DI: Ptr to Sector Access Window
213; Returns:
214; CX, DX: Zero
215; SI: Updated
216; Corrupts registers:
217; BX
218;--------------------------------------------------------------------
219ALIGN JUMP_ALIGN
220WriteSingleBlockFromDSSIToSectorAccessWindowInESDI:
221 mov bx, di
222 mov dx, cx
[536]223 xor cx, cx
[400]224ALIGN JUMP_ALIGN
[475]225.WriteNextSector:
[536]226 inc ch
[400]227 rep movsw
228 mov di, bx ; Reset for next sector
229 dec dx
[475]230 jnz SHORT .WriteNextSector
[400]231 ret
232
233
234;--------------------------------------------------------------------
235; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
236; Parameters:
[475]237; CX Number of sectors in full block or sectors in last partial block
[400]238; ES:DI: Normalized ptr to buffer to receive data (destination)
239; DS:SI: Ptr to Sector Access Window (source)
240; Returns:
241; CX, DX: Zero
242; DI: Updated
243; Corrupts registers:
244; BX
245;--------------------------------------------------------------------
246ALIGN JUMP_ALIGN
247ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
248 mov bx, si
249 mov dx, cx
[536]250 xor cx, cx
[400]251ALIGN JUMP_ALIGN
[475]252.ReadNextSector:
[536]253 inc ch
[400]254 rep movsw
255 mov si, bx ; Reset for next sector
256 dec dx
[475]257 jnz SHORT .ReadNextSector
[400]258 ret
259
260
261;--------------------------------------------------------------------
262; WaitUntilReadyToTransferNextBlock
263; Parameters:
264; SS:BP: Ptr to MEMPIOVARS
265; Returns:
266; AH: INT 13h Error Code
267; CF: Cleared if success, Set if error
268; Corrupts registers:
269; AL, BX, CX, DX
270;--------------------------------------------------------------------
271ALIGN JUMP_ALIGN
272WaitUntilReadyToTransferNextBlock:
273 push ds
274 push di
275 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
276 call IdeWait_IRQorDRQ ; Always polls
277 pop di
278 pop ds
279 ret
280
Note: See TracBrowser for help on using the repository browser.