summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/CHKDSK/CHKDISK.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/CHKDSK/CHKDISK.ASM')
-rw-r--r--v4.0/src/CMD/CHKDSK/CHKDISK.ASM328
1 files changed, 328 insertions, 0 deletions
diff --git a/v4.0/src/CMD/CHKDSK/CHKDISK.ASM b/v4.0/src/CMD/CHKDSK/CHKDISK.ASM
new file mode 100644
index 0000000..c76be99
--- /dev/null
+++ b/v4.0/src/CMD/CHKDSK/CHKDISK.ASM
@@ -0,0 +1,328 @@
1TITLE CHKDISK - procedures that read or write to the disk
2page ,132 ;
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
13CONST 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
22CONST ENDS
23
24DATA 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
32DATA ENDS
33
34CODE SEGMENT PUBLIC PARA 'CODE'
35ASSUME 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
41public read_disk, Read_once, write_disk, Write_once ;an005;bgb
42public 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
72procedure 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
98read_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
129Procedure 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
170procedure 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
195write_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
225Procedure 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
238Write_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
250procedure 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
262seg_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
274procedure 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
289calc_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
311Procedure 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:
321bad_read: ret ;an005;bgb
322EndProc ReadFt ;an005;bgb
323
324
325 pathlabl chkdisk
326CODE ENDS
327 END
328 \ No newline at end of file