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

Last change on this file since 352 was 294, checked in by krille_n_@…, 12 years ago

Commit 2/2 (BIOS):

  • Fixed a bug in AH1h_HStatus.asm.
  • Minor optimizations.
  • Fixed spelling and did some cleaning.
File size: 7.6 KB
RevLine 
[238]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
[242]10 ; TODO: The above word vars could just as well be byte vars?
11 resb 1 ; 6,
[238]12 resb 1 ; 7, IDEPACK.bDeviceControl
13 .fpDPT resb 4 ; 8, Far pointer to DPT
14endstruc
15
16
17; Section containing code
18SECTION .text
19
20;--------------------------------------------------------------------
21; MemIdeTransfer_StartWithCommandInAL
22; Parameters:
23; AL: IDE command that was used to start the transfer
24; (all PIO read and write commands including Identify Device)
25; ES:SI: Ptr to normalized data buffer
26; DS:DI: Ptr to DPT (in RAMVARS segment)
27; SS:BP: Ptr to IDEPACK
28; Returns:
29; AH: INT 13h Error Code
30; CX: Number of successfully transferred sectors
31; CF: Cleared if success, Set if error
32; Corrupts registers:
33; AL, BX, DX, SI, ES
34;--------------------------------------------------------------------
35ALIGN JUMP_ALIGN
36MemIdeTransfer_StartWithCommandInAL:
[242]37 push cs ; We push CS here (segment of SAW) and later pop it to DS (reads) or ES (writes)
38
[238]39 ; Initialize MEMPIOVARS
[242]40 xor cx, cx
41 mov [bp+MEMPIOVARS.wWordsDone], cx
42 mov ch, [bp+IDEPACK.bSectorCount]
43 mov [bp+MEMPIOVARS.wWordsLeft], cx
44 mov ch, [di+DPT_ATA.bSetBlock]
45 mov [bp+MEMPIOVARS.wWordsInBlock], cx
[238]46 mov [bp+MEMPIOVARS.fpDPT], di
47 mov [bp+MEMPIOVARS.fpDPT+2], ds
48
49 ; Are we reading or writing?
[242]50 test al, 16 ; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
51 jnz SHORT WriteToSectorAccessWindow
52 cmp al, COMMAND_WRITE_MULTIPLE
53 je SHORT WriteToSectorAccessWindow
54 ; Fall to ReadFromSectorAccessWindow
[238]55
[242]56;--------------------------------------------------------------------
57; ReadFromSectorAccessWindow
58; Parameters:
59; Stack: Segment part of ptr to Sector Access Window
60; ES:SI: Normalized ptr to buffer to receive data
61; SS:BP: Ptr to MEMPIOVARS
62; Returns:
63; DS:DI: Ptr to DPT (in RAMVARS segment)
64; AH: BIOS Error code
65; CX: Number of successfully transferred sectors
[294]66; CF: 0 if transfer successful
[242]67; 1 if any error
68; Corrupts registers:
69; AL, BX, DX, SI, ES
70;--------------------------------------------------------------------
71ReadFromSectorAccessWindow:
[267]72 pop ds ; CS -> DS
73 mov di, si ; ES:DI = destination
74 mov si, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET ; DS:SI = source
[238]75
[242]76 call WaitUntilReadyToTransferNextBlock
77 jc SHORT ReturnWithMemoryIOtransferErrorInAH
78
[267]79 mov cx, [bp+MEMPIOVARS.wWordsInBlock]
[242]80
[238]81ALIGN JUMP_ALIGN
[242]82.ReadNextBlockFromDrive:
[267]83 cmp [bp+MEMPIOVARS.wWordsLeft], cx
[242]84 jbe SHORT .ReadLastBlockFromDrive
85 call ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
86 call WaitUntilReadyToTransferNextBlock
87 jc SHORT ReturnWithMemoryIOtransferErrorInAH
[238]88
[242]89 ; Increment number of successfully read WORDs
[267]90 mov cx, [bp+MEMPIOVARS.wWordsInBlock]
91 sub [bp+MEMPIOVARS.wWordsLeft], cx
92 add [bp+MEMPIOVARS.wWordsDone], cx
[242]93 jmp SHORT .ReadNextBlockFromDrive
[238]94
[242]95ALIGN JUMP_ALIGN
96.ReadLastBlockFromDrive:
[267]97 mov ch, [bp+MEMPIOVARS.wWordsLeft+1] ; Sectors left
[242]98 call ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
99
100 ; Check for errors in last block
101CheckErrorsAfterTransferringLastMemoryMappedBlock:
102 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
103 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
104 call IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
105
106 ; Return number of successfully transferred sectors
107ReturnWithMemoryIOtransferErrorInAH:
108 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
[267]109 mov cx, [bp+MEMPIOVARS.wWordsDone]
[242]110 jc SHORT .ConvertTransferredWordsInCXtoSectors
[267]111 add cx, [bp+MEMPIOVARS.wWordsLeft] ; Never sets CF
[242]112.ConvertTransferredWordsInCXtoSectors:
113 xchg cl, ch
114 ret
115
116
[238]117;--------------------------------------------------------------------
[242]118; WriteToSectorAccessWindow
[238]119; Parameters:
[242]120; Stack: Segment part of ptr to Sector Access Window
121; ES:SI: Normalized ptr to buffer containing data
[238]122; SS:BP: Ptr to MEMPIOVARS
123; Returns:
124; DS:DI: Ptr to DPT (in RAMVARS segment)
125; AH: BIOS Error code
126; CX: Number of successfully transferred sectors
[294]127; CF: 0 if transfer successful
[238]128; 1 if any error
129; Corrupts registers:
130; AL, BX, DX, SI, ES
131;--------------------------------------------------------------------
[242]132ALIGN JUMP_ALIGN
133WriteToSectorAccessWindow:
134 push es
135 pop ds
136 pop es ; CS -> ES
137 mov di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
138
[238]139 ; Always poll when writing first block (IRQs are generated for following blocks)
140 call WaitUntilReadyToTransferNextBlock
141 jc SHORT ReturnWithMemoryIOtransferErrorInAH
142
[267]143 mov cx, [bp+MEMPIOVARS.wWordsInBlock]
[242]144
[238]145ALIGN JUMP_ALIGN
146.WriteNextBlockToDrive:
[267]147 cmp [bp+MEMPIOVARS.wWordsLeft], cx
[238]148 jbe SHORT .WriteLastBlockToDrive
149 call WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
150 call WaitUntilReadyToTransferNextBlock
151 jc SHORT ReturnWithMemoryIOtransferErrorInAH
152
153 ; Increment number of successfully written WORDs
[267]154 mov cx, [bp+MEMPIOVARS.wWordsInBlock]
155 sub [bp+MEMPIOVARS.wWordsLeft], cx
156 add [bp+MEMPIOVARS.wWordsDone], cx
[238]157 jmp SHORT .WriteNextBlockToDrive
158
159ALIGN JUMP_ALIGN
160.WriteLastBlockToDrive:
[267]161 mov ch, [bp+MEMPIOVARS.wWordsLeft+1] ; Sectors left
[266]162 ePUSH_T bx, CheckErrorsAfterTransferringLastMemoryMappedBlock
[242]163 ; Fall to WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
[238]164
165;--------------------------------------------------------------------
166; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
167; Parameters:
[242]168; CH: Number of sectors in block
[238]169; DS:SI: Normalized ptr to source buffer
170; ES:DI: Ptr to Sector Access Window
171; Returns:
172; CX, DX: Zero
173; SI: Updated
174; Corrupts registers:
[242]175; BX
[238]176;--------------------------------------------------------------------
177ALIGN JUMP_ALIGN
178WriteSingleBlockFromDSSIToSectorAccessWindowInESDI:
[242]179 mov bx, di
180 eMOVZX dx, ch
181 xor cl, cl
182ALIGN JUMP_ALIGN
183.WriteBlock:
184 mov ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
[238]185 rep movsw
[242]186 mov di, bx ; Reset for next sector
[238]187 dec dx
[242]188 jnz SHORT .WriteBlock
[238]189 ret
190
191
192;--------------------------------------------------------------------
193; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
194; Parameters:
[242]195; CH: Number of sectors in block
196; ES:DI: Normalized ptr to buffer to receive data (destination)
[238]197; DS:SI: Ptr to Sector Access Window (source)
198; Returns:
199; CX, DX: Zero
200; DI: Updated
201; Corrupts registers:
[242]202; BX
[238]203;--------------------------------------------------------------------
204ALIGN JUMP_ALIGN
205ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
[242]206 mov bx, si
207 eMOVZX dx, ch
208 xor cl, cl
209ALIGN JUMP_ALIGN
210.ReadBlock:
211 mov ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
[238]212 rep movsw
[242]213 mov si, bx ; Reset for next sector
[238]214 dec dx
[242]215 jnz SHORT .ReadBlock
[238]216 ret
217
218
219;--------------------------------------------------------------------
220; WaitUntilReadyToTransferNextBlock
221; Parameters:
222; SS:BP: Ptr to MEMPIOVARS
223; Returns:
224; AH: INT 13h Error Code
225; CF: Cleared if success, Set if error
226; Corrupts registers:
227; AL, BX, CX, DX
228;--------------------------------------------------------------------
229ALIGN JUMP_ALIGN
230WaitUntilReadyToTransferNextBlock:
231 push ds
232 push di
233 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
234 call IDEDEVICE%+Wait_IRQorDRQ ; Always polls
235 pop di
236 pop ds
237 ret
[242]238
239
240%if JRIDE_SECTOR_ACCESS_WINDOW_SIZE <> 512
241 %error "JRIDE_SECTOR_ACCESS_WINDOW_SIZE is no longer equal to 512. MemIdeTransfer.asm needs changes."
242%endif
243
Note: See TracBrowser for help on using the repository browser.