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

Last change on this file since 621 was 601, checked in by Krister Nordvall, 5 years ago

Changes:

  • Building the BIOS now works again.
  • Added a new IDE device type/transfer mode for use only with XT-IDE rev 2+ (or Chuck(G)-modded rev 1) cards installed in any of the following machines: Olivetti M24, AT&T PC6300, Xerox 6060 and Logabax Persona 1600. This new transfer mode is slightly faster than the regular XT-IDE rev 1 device type and requires that the card is configured for High Speed mode (or, in case of the card being a rev 1 card, has the Chuck(G) mod done). The new device type is called "XTIDE rev 2 (Olivetti M24)" in XTIDECFG.
  • Made some minor improvements to the library code that handles 'Drive Not Ready' errors in XTIDECFG.
  • Optimizations.
File size: 9.0 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
[601]102 mov dx, [bp+MEMPIOVARS.wSectorsInBlock] ; Clears DH
103 cmp [bp+MEMPIOVARS.bSectorsLeft], dl
[412]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.
[601]121 mov dx, [bp+MEMPIOVARS.wSectorsInBlock]
122 sub [bp+MEMPIOVARS.bSectorsLeft], dl
123 add [bp+MEMPIOVARS.bSectorsDone], dl
124 cmp [bp+MEMPIOVARS.bSectorsLeft], dl
[412]125 ja SHORT .ReadNextBlockFromDrive
[400]126
127ALIGN JUMP_ALIGN
128.ReadLastBlockFromDrive:
[601]129 mov dl, [bp+MEMPIOVARS.bSectorsLeft]
130 push dx
[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
[592]149 movzx cx, [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
[601]183 mov dx, [bp+MEMPIOVARS.wSectorsInBlock]
184 cmp [bp+MEMPIOVARS.bSectorsLeft], dl
[412]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
[601]194 mov dx, [bp+MEMPIOVARS.wSectorsInBlock]
195 sub [bp+MEMPIOVARS.bSectorsLeft], dl
196 add [bp+MEMPIOVARS.bSectorsDone], dl
197 cmp [bp+MEMPIOVARS.bSectorsLeft], dl
[412]198 ja SHORT .WriteNextBlockToDrive
[400]199
200ALIGN JUMP_ALIGN
201.WriteLastBlockToDrive:
[601]202 mov dl, [bp+MEMPIOVARS.bSectorsLeft]
203 push dx
[400]204 ePUSH_T bx, CheckErrorsAfterTransferringLastMemoryMappedBlock
205 ; Fall to WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
206
207;--------------------------------------------------------------------
208; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
209; Parameters:
[601]210; DX: Number of sectors in block
[400]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
[536]222 xor cx, cx
[400]223ALIGN JUMP_ALIGN
[475]224.WriteNextSector:
[536]225 inc ch
[400]226 rep movsw
227 mov di, bx ; Reset for next sector
228 dec dx
[475]229 jnz SHORT .WriteNextSector
[400]230 ret
231
232
233;--------------------------------------------------------------------
234; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
235; Parameters:
[601]236; DX: Number of sectors in block
237; ES:DI: Normalized ptr to destination buffer
238; DS:SI: Ptr to Sector Access Window
[400]239; Returns:
240; CX, DX: Zero
241; DI: Updated
242; Corrupts registers:
243; BX
244;--------------------------------------------------------------------
245ALIGN JUMP_ALIGN
246ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
247 mov bx, si
[536]248 xor cx, cx
[400]249ALIGN JUMP_ALIGN
[475]250.ReadNextSector:
[536]251 inc ch
[400]252 rep movsw
253 mov si, bx ; Reset for next sector
254 dec dx
[475]255 jnz SHORT .ReadNextSector
[400]256 ret
257
258
259;--------------------------------------------------------------------
260; WaitUntilReadyToTransferNextBlock
261; Parameters:
262; SS:BP: Ptr to MEMPIOVARS
263; Returns:
264; AH: INT 13h Error Code
265; CF: Cleared if success, Set if error
266; Corrupts registers:
267; AL, BX, CX, DX
268;--------------------------------------------------------------------
269ALIGN JUMP_ALIGN
270WaitUntilReadyToTransferNextBlock:
271 push ds
272 push di
273 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
274 call IdeWait_IRQorDRQ ; Always polls
275 pop di
276 pop ds
277 ret
278
Note: See TracBrowser for help on using the repository browser.