]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/CHKDSK/CHKDISK.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / CHKDSK / CHKDISK.ASM
1 TITLE CHKDISK - procedures that read or write to the disk
2 page ,132 ;\ f
3
4 .xlist
5 include chkseg.inc ;an005;bgb
6 INCLUDE CHKCHNG.INC
7 INCLUDE DOSSYM.INC
8 INCLUDE CHKEQU.INC
9 INCLUDE CHKMACRO.INC
10 include pathmac.inc
11
12
13 CONST SEGMENT PUBLIC PARA 'DATA'
14 EXTRN FIXMES_ARG:word
15 EXTRN BADW_ARG:word
16 EXTRN badrw_num:word,BADRW_STR:WORD,HAVFIX:byte
17 EXTRN DIRTYFAT:byte,DOFIX:byte,SECONDPASS:byte
18 EXTRN HECODE:byte,USERDIR:byte,FRAGMENT:byte
19 EXTRN ORPHEXT:byte,ALLDRV:byte,FIXMFLG:byte,DIRCHAR:byte
20 EXTRN EOFVAL:word,BADVAL:word
21 extrn fTrunc:BYTE
22 CONST ENDS
23
24 DATA SEGMENT PUBLIC PARA 'DATA'
25 EXTRN THISDPB:dword,NUL_ARG:byte
26 EXTRN NAMBUF:byte,SRFCBPT:word,FATMAP:word
27 EXTRN USERDEV:byte,HARDCH:dword,CONTCH:dword
28 EXTRN ExitStatus:Byte,Read_Write_Relative:Byte
29 extrn bytes_per_sector:word ;an005;bgb
30 extrn sec_count:word, paras_per_64k:word, secs_per_64k:word ;an005;bgb
31 extrn fattbl_seg:word, paras_per_fat:word ;an005;bgb
32 DATA ENDS
33
34 CODE SEGMENT PUBLIC PARA 'CODE'
35 ASSUME CS:DG,DS:DG,ES:DG,SS:DG
36 EXTRN FCB_TO_ASCZ:NEAR
37 EXTRN EPRINT:NEAR
38 EXTRN PROMPTYN:NEAR,DIRPROC:NEAR
39 EXTRN DOCRLF:NEAR,UNPACK:NEAR,PACK:NEAR
40 EXTRN CHECKNOFMES:NEAR
41 public read_disk, Read_once, write_disk, Write_once ;an005;bgb
42 public ReadFt, seg_adj, calc_sp64k ;an005;bgb
43 .list
44
45
46 pathlabl chkdisk
47 ;========================================================================= ;an005;bgb
48 ; READ_DISK : This routine reads the logical sector count requested. ;an005;bgb
49 ; It will read a maximum of 64k in one read. If more ;an005;bgb
50 ; than 64k exists it will continue looping until ;an005;bgb
51 ; all sectors have been read. ;an005;bgb
52 ; ;an005;bgb
53 ; Inputs : AL - Drive letter ;an005;bgb
54 ; ES:BX - Segment:offset of transfer address ;an005;bgb
55 ; CX - Sector count ;an005;bgb
56 ; DX - 1st sector ;an005;bgb
57 ; ;an005;bgb
58 ; Outputs : Logical sectors read ;an005;bgb
59 ; LOGIC ;an005;bgb
60 ; ***** ;an005;bgb
61 ; adjust es:bx to es:00 ;an005;bgb
62 ; calcluate sectors-per-64k (how many sectors are there that can fit within a 64k segment?)
63 ; DO while there are more sectors to read than sectors-per-64k ;an005;bgb
64 ; set sector-count to sectors-per-64k ;an005;bgb
65 ; perform the disk read ;an005;bgb
66 ; bump the seg addr to the new addr ;an005;bgb
67 ; dec the number of sectors to read by sectors-per-64k ;an005;bgb
68 ; bump the starting sector number by the sectors-per-64k ;an005;bgb
69 ; ENDDO ;an005;bgb
70 ; perform a disk read for less than sectors-per-64k ;an005;bgb
71 ;========================================================================= ;an005;bgb
72 procedure read_disk ;an005;bgb
73 savereg <ax,bx,cx,dx,es> ;an005;bgb
74 call seg_adj ;an000;calc new seg:off ;an005;bgb
75 call calc_sp64k ;an000;secs/64k ;an005;bgb
76 ; $DO ; do while more than 64k ;an005;bgb
77 $$DO1:
78 cmp cx,secs_per_64k ;an000;exceed 64k ;an005;bgb
79 ; $LEAVE LE ;an000;yes ;an005;bgb
80 JLE $$EN1
81 mov sec_count,cx ;an000;save cx ;an005;bgb
82 mov cx,secs_per_64k ;an000;get maximum read ;an005;bgb
83 call read_once ;an000;read it ;an005;bgb
84 ; $LEAVE C ;an005;bgb
85 JC $$EN1
86 mov cx,es ;an005;bgb
87 add cx,paras_per_64k ; adjust transfer area ;an005;bgb
88 mov es,cx ;an005;bgb
89 mov cx,sec_count ; restore sector count ;an005;bgb
90 sub cx,secs_per_64k ;an000;get sectors remaining ;an005;bgb
91 add dx,secs_per_64k ;an000;adjust starting sector ;an005;bgb
92 ; $ENDDO ;an005;bgb
93 JMP SHORT $$DO1
94 $$EN1:
95 call read_once ;an000;read it ;an005;bgb
96 restorereg <es,dx,cx,bx,ax> ;an005;bgb
97 ret ;an005;bgb
98 read_disk endp ;an005;bgb
99 ;an005;bgb
100 ;an005;bgb
101 ;***************************************************************************** ;an005;bgb
102 ;Routine name: Read_once ;an005;bgb
103 ;***************************************************************************** ;an005;bgb
104 ; ;an005;bgb
105 ;description: Read in data using Generic IOCtl ;an005;bgb
106 ; ;an005;bgb
107 ;Called Procedures: None ;an005;bgb
108 ; ;an005;bgb
109 ; ;an005;bgb
110 ;Change History: Created 5/13/87 MT ;an005;bgb
111 ; ;an005;bgb
112 ;Input: AL = Drive number (0=A) ;an005;bgb
113 ; es:BX = Transfer address ;an005;bgb
114 ; CX = Number of sectors ;an005;bgb
115 ; Read_Write_Relative.Start_Sector_High = Number of sectors high ;an005;bgb
116 ; DX = logical sector number low ;an005;bgb
117 ; ;an005;bgb
118 ;Output: CY if error ;an005;bgb
119 ; AH = INT 25h error code ;an005;bgb
120 ; ;an005;bgb
121 ;Psuedocode ;an005;bgb
122 ;---------- ;an005;bgb
123 ; Save registers ;an005;bgb
124 ; Setup structure for function call ;an005;bgb
125 ; Read the disk (AX=440Dh, CL = 6Fh) ;an005;bgb
126 ; Restore registers ;an005;bgb
127 ; ret ;an005;bgb
128 ;***************************************************************************** ;an005;bgb
129 Procedure Read_once ; ;an005;bgb
130 savereg <ax,bx,cx,dx,si,di,bp,es,ds> ;Change it to Read relative sect;an005;bgb
131 mov Read_Write_Relative.Buffer_Offset,bx ;Get transfer buffer add ;an005;bgb
132 mov bx,es ; ;AN005;bgb
133 mov Read_Write_Relative.Buffer_Segment,bx ;Get segment ;an005;bgb
134 mov Read_Write_Relative.Number_Sectors,cx ;Number of sec to read ;an005;bgb
135 mov Read_Write_Relative.Start_Sector_Low,dx ;Start sector ;an005;bgb
136 mov bx,offset Read_Write_Relative ; ;an005;bgb
137 mov cx,0FFFFh ;Read relative sector ;an005;bgb
138 INT 25h ;Do the read ;an005;bgb
139 pop dx ;Throw away flags on stack ;an005;bgb
140 restorereg <ds,es,bp,di,si,dx,cx,bx,ax> ;an005;bgb
141 return ;an005;bgb
142 Read_once endp ;an005;bgb
143 ;an005;bgb
144 ;an005;bgb
145 ;========================================================================= ;an005;bgb
146 ; WRITE-DISK : This routine reads the logical sector count requested. ;an005;bgb
147 ; It will read a maximum of 64k in one read. If more ;an005;bgb
148 ; than 64k exists it will continue looping until ;an005;bgb
149 ; all sectors have been read. ;an005;bgb
150 ; ;an005;bgb
151 ; Inputs : AL - Drive letter ;an005;bgb
152 ; ES:BX - Segment:offset of transfer address ;an005;bgb
153 ; CX - Sector count ;an005;bgb
154 ; DX - 1st sector ;an005;bgb
155 ; ;an005;bgb
156 ; Outputs : Logical sectors read ;an005;bgb
157 ; LOGIC ;an005;bgb
158 ; ***** ;an005;bgb
159 ; adjust es:bx to es:00 ;an005;bgb
160 ; calcluate sectors-per-64k (how many sectors are there that can fit within a 64k segment?)
161 ; DO while there are more sectors to read than sectors-per-64k ;an005;bgb
162 ; set sector-count to sectors-per-64k ;an005;bgb
163 ; perform the disk read ;an005;bgb
164 ; bump the seg addr to the new addr ;an005;bgb
165 ; dec the number of sectors to read by sectors-per-64k ;an005;bgb
166 ; bump the starting sector number by the sectors-per-64k ;an005;bgb
167 ; ENDDO ;an005;bgb
168 ; perform a disk read for less than sectors-per-64k ;an005;bgb
169 ;========================================================================= ;an005;bgb
170 procedure write_disk ;an005;bgb
171 savereg <ax,bx,cx,dx,es> ;an013;bgb
172 call seg_adj ;an000;calc new seg:off ;an005;bgb
173 ; $DO ; do while more than 64k ;an005;bgb
174 $$DO5:
175 cmp cx,secs_per_64k ;an000;exceed 64k ;an005;bgb
176 ; $LEAVE LE ;an000;yes ;an005;bgb
177 JLE $$EN5
178 mov sec_count,cx ;an000;save cx ;an005;bgb
179 mov cx,secs_per_64k ;an000;get maximum read ;an005;bgb
180 call write_once ;an000;read it ;an005;bgb
181 ; $LEAVE C ;an005;bgb
182 JC $$EN5
183 mov cx,es ;an005;bgb
184 add cx,paras_per_64k ; adjust transfer area ;an005;bgb
185 mov es,cx ;an005;bgb
186 mov cx,sec_count ; restore sector count ;an005;bgb
187 sub cx,secs_per_64k ;an000;get sectors remaining ;an005;bgb
188 add dx,secs_per_64k ;an000;adjust starting sector ;an005;bgb
189 ; $ENDDO ;an005;bgb
190 JMP SHORT $$DO5
191 $$EN5:
192 call write_once ;an000;read it ;an005;bgb
193 restorereg <es,dx,cx,bx,ax> ;an013;bgb
194 ret ;an005;bgb
195 write_disk endp ;an005;bgb
196 ;an005;bgb
197 ;***************************************************************************** ;an005;bgb
198 ;Routine name: Write_once ;an005;bgb
199 ;***************************************************************************** ;an005;bgb
200 ; ;an005;bgb
201 ;description: Write Data using int 26 ;an005;bgb
202 ; ;an005;bgb
203 ;Called Procedures: None ;an005;bgb
204 ; ;an005;bgb
205 ; ;an005;bgb
206 ;Change History: Created 5/13/87 MT ;an005;bgb
207 ; ;an005;bgb
208 ;Input: AL = Drive number (0=A) ;an005;bgb
209 ; DS:BX = Transfer address ;an005;bgb
210 ; CX = Number of sectors ;an005;bgb
211 ; Read_Write_Relative.Start_Sector_High = already set up ;an048;bgb
212 ; DX = logical sector number low ;an005;bgb
213 ; ;an005;bgb
214 ;Output: CY if error ;an005;bgb
215 ; AH = INT 26h error code ;an005;bgb
216 ; ;an005;bgb
217 ;Psuedocode ;an005;bgb
218 ;---------- ;an005;bgb
219 ; Save registers ;an005;bgb
220 ; Setup structure for function call ;an005;bgb
221 ; Write to disk (AX=440Dh, CL = 4Fh) ;an005;bgb
222 ; Restore registers ;an005;bgb
223 ; ret ;an005;bgb
224 ;***************************************************************************** ;an005;bgb
225 Procedure Write_once ; ;an005;bgb
226 savereg <ax,bx,cx,dx,di,si,bp,es,ds> ;This is setup for INT 26h right;AN005;bgb
227 mov Read_Write_Relative.Buffer_Offset,bx ;Get transfer buffer add ;AN005;bgb
228 mov bx,es ; ;AN005;bgb
229 mov Read_Write_Relative.Buffer_Segment,bx ;Get segment ;AN005;bgb
230 mov Read_Write_Relative.Number_Sectors,cx ;Number of sec to write ;AN005;bgb
231 mov Read_Write_Relative.Start_Sector_Low,dx ;Start sector ;AN005;bgb
232 mov cx,0FFFFh ;Write relative sector ;AN005;bgb
233 lea bx,read_write_relative ; ;an005;bgb
234 INT 026h ;Do the write ;AN005;bgb
235 pop dx ;flags is returned on the stack;AN005;bgb
236 restorereg <ds,es,bp,si,di,dx,cx,bx,ax> ; ;AN005;bgb
237 ret ; ;AN005;bgb
238 Write_once endp ; ;AN005;bgb
239 ;an005;bgb
240 ;========================================================================= ;an005;bgb
241 ; SEG_ADJ : This routine adjusts the segment:offset to prevent ;an005;bgb
242 ; address wrap. ;an005;bgb
243 ; ;an005;bgb
244 ; Inputs : bx - Offset to adjust segment with ;an005;bgb
245 ; es - Segment to be adjusted ;an005;bgb
246 ; ;an005;bgb
247 ; Outputs : bx - New offset ;an005;bgb
248 ; es - Adjusted segment ;an005;bgb
249 ;========================================================================= ;an005;bgb
250 procedure seg_adj ;an005;bgb
251 savereg <ax,cx,dx> ;an005;bgb
252 mov ax,bx ;an000;get offset ;an005;bgb
253 mov bx,0010h ;divide by 16 ;an005;bgb
254 xor dx,dx ;an000;clear dx ;an005;bgb
255 div bx ;an000;get para count ;an022;bgb
256 mov bx,es ;an000;get seg ;an005;bgb
257 add bx,ax ;an000;adjust for paras ;an005;bgb
258 mov es,bx ;an000;save new seg ;an005;bgb
259 mov bx,dx ;an000;new offset ;an005;bgb
260 restorereg <dx,cx,ax> ;an005;bgb
261 ret ;an005;bgb
262 seg_adj endp ;an005;bgb
263 ;an005;bgb
264 ;an005;bgb
265 ;========================================================================= ;an005;bgb
266 ; CALC_SP64K : This routine calculates how many sectors, for this ;an005;bgb
267 ; particular media, will fit into 64k. ;an005;bgb
268 ; ;an005;bgb
269 ; Inputs : DPB_SECTOR_SIZE - bytes/sector ;an005;bgb
270 ; ;an005;bgb
271 ; Outputs : SECS_PER_64K - Sectors / 64k ;an005;bgb
272 ; PARAS_PER_64K - paragraphs per 64k ;an005;bgb
273 ;========================================================================= ;an005;bgb
274 procedure calc_sp64k ;an005;bgb
275 savereg <ax,bx,cx,dx> ;an005;bgb
276 mov ax,0ffffh ;an000;64k ;an005;bgb
277 mov bx,bytes_per_sector ;an000;get bytes/sector ;an005;bgb
278 xor dx,dx ;an000;clear dx ;an005;bgb
279 div bx ;an000;sector count ;an022;bgb;bgb
280 mov secs_per_64k,ax ;an000;save sector count ;an005;bgb
281 mov ax,bytes_per_sector ;an000;get bytes/sector ;an005;bgb
282 mov bx,010h ; divide by paras ;an005;bgb
283 xor dx,dx ;an000;clear dx ;an005;bgb
284 div bx ; paras per sector ;an022;bgb;bgb
285 mul secs_per_64k ; times sectors ;an005;bgb
286 mov paras_per_64k,ax ; = paras per 64k ;an005;bgb
287 restorereg <dx,cx,bx,ax> ;an000;restore dx ;an005;bgb
288 ret ;an000; ;an005;bgb
289 calc_sp64k endp ;an000; ;an005;bgb
290 ;an005;bgb
291 ;an005;bgb
292 Break <ReadFT - read in the entire fat> ;an005;bgb
293 ;****************************************************************************** ;an005;bgb
294 ; ReadFt - attempt to read in the fat. If there are errors, step to ;an005;bgb
295 ; successive fats until no more. ;an005;bgb
296 ; ;an005;bgb
297 ; Inputs: none. ;an005;bgb
298 ; Outputs: Fats are read until one succeeds. ;an005;bgb
299 ; Carry set indicates no Fat could be read. ;an005;bgb
300 ; Registers modified: all ;an005;bgb
301 ; LOGIC ;an005;bgb
302 ; ***** ;an005;bgb
303 ; DO for each of the fats on the disk: ;an005;bgb
304 ; read - all the sectors in the fat ;an005;bgb
305 ; increase the starting sector by the number of sectors in each fat ;an005;bgb
306 ; ;an005;bgb
307 ; LARGE FAT SUPPORT - the big change here is in read disk. since the fat must ;an005;bgb
308 ; be within the first 32M, then the starting sector number of 65535 is ok, ;an005;bgb
309 ; as is a larger number of sectors to read/write. ;an005;bgb
310 ;****************************************************************************** ;an005;bgb
311 Procedure ReadFt,NEAR ;an005;bgb
312 clc ;Clear CY so we will loop ;an005;bgb
313 mov Read_Write_Relative.Start_Sector_High,0 ; ;an005;bgb
314 call Read_Disk ; Read_Disk (); ;AC0;an005;bgb
315 ; $IF C
316 JNC $$IF9
317 add dx,cx ; fatstart += fatsize ;an005;bgb
318 call Read_Disk ; Read_Disk (); ;AC0;an005;bgb
319 ; $ENDIF
320 $$IF9:
321 bad_read: ret ;an005;bgb
322 EndProc ReadFt ;an005;bgb
323
324
325 pathlabl chkdisk
326 CODE ENDS
327 END
328 \1a