summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/CHKDSK/CHKDISK.ASM
blob: c76be99f993715885ec7c85f7ede47a447685b9f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
TITLE	CHKDISK  - procedures that read or write to the disk
page	,132					;

	.xlist
	include chkseg.inc							;an005;bgb
	INCLUDE CHKCHNG.INC
	INCLUDE DOSSYM.INC
	INCLUDE CHKEQU.INC
	INCLUDE CHKMACRO.INC
	include pathmac.inc


CONST	SEGMENT PUBLIC PARA  'DATA'
	EXTRN	FIXMES_ARG:word
	EXTRN	BADW_ARG:word
	EXTRN	badrw_num:word,BADRW_STR:WORD,HAVFIX:byte
	EXTRN	DIRTYFAT:byte,DOFIX:byte,SECONDPASS:byte
	EXTRN	HECODE:byte,USERDIR:byte,FRAGMENT:byte
	EXTRN	ORPHEXT:byte,ALLDRV:byte,FIXMFLG:byte,DIRCHAR:byte
	EXTRN	EOFVAL:word,BADVAL:word
	extrn	fTrunc:BYTE
CONST	ENDS

DATA	SEGMENT PUBLIC PARA 'DATA'
	EXTRN	THISDPB:dword,NUL_ARG:byte
	EXTRN	NAMBUF:byte,SRFCBPT:word,FATMAP:word
	EXTRN	USERDEV:byte,HARDCH:dword,CONTCH:dword
	EXTRN	ExitStatus:Byte,Read_Write_Relative:Byte
	extrn	bytes_per_sector:word						;an005;bgb
	extrn	sec_count:word, paras_per_64k:word, secs_per_64k:word		 ;an005;bgb
	extrn	fattbl_seg:word, paras_per_fat:word		       ;an005;bgb
DATA	ENDS

CODE	SEGMENT PUBLIC PARA 'CODE'
ASSUME	CS:DG,DS:DG,ES:DG,SS:DG
	EXTRN	FCB_TO_ASCZ:NEAR
	EXTRN	EPRINT:NEAR
	EXTRN	PROMPTYN:NEAR,DIRPROC:NEAR
	EXTRN	DOCRLF:NEAR,UNPACK:NEAR,PACK:NEAR
	EXTRN	CHECKNOFMES:NEAR
public read_disk, Read_once, write_disk, Write_once				;an005;bgb
public ReadFt, seg_adj, calc_sp64k						;an005;bgb
	.list


	pathlabl chkdisk
;=========================================================================	;an005;bgb
; READ_DISK	:	This routine reads the logical sector count requested.	;an005;bgb
;			It will read a maximum of 64k in one read.  If more	;an005;bgb
;			than 64k exists it will continue looping until		;an005;bgb
;			all sectors have been read.				;an005;bgb
;										;an005;bgb
;	Inputs	:	AL - Drive letter					;an005;bgb
;			ES:BX - Segment:offset of transfer address		;an005;bgb
;			CX - Sector count					;an005;bgb
;			DX - 1st  sector					;an005;bgb
;										;an005;bgb
;	Outputs :	Logical sectors read					;an005;bgb
; LOGIC 									;an005;bgb
; ***** 									;an005;bgb
;    adjust es:bx to es:00							;an005;bgb
;    calcluate sectors-per-64k (how many sectors are there that can fit within a 64k segment?)
;    DO while there are more sectors to read than sectors-per-64k		;an005;bgb
;	set sector-count to sectors-per-64k					;an005;bgb
;	perform the disk read							;an005;bgb
;	bump the seg addr to the new addr					;an005;bgb
;	dec  the number of sectors to read by sectors-per-64k			;an005;bgb
;	bump the starting sector number by the sectors-per-64k			;an005;bgb
;    ENDDO									;an005;bgb
;    perform a disk read for less than sectors-per-64k				;an005;bgb
;=========================================================================	;an005;bgb
procedure	read_disk							;an005;bgb
	savereg <ax,bx,cx,dx,es>						;an005;bgb
	call	seg_adj 			;an000;calc new seg:off 	;an005;bgb
	call	calc_sp64k			;an000;secs/64k 		;an005;bgb
;	$DO				; do while more than 64k		;an005;bgb
$$DO1:
	    cmp     cx,secs_per_64k	    ;an000;exceed 64k			;an005;bgb
;	$LEAVE	LE			    ;an000;yes				;an005;bgb
	JLE $$EN1
	    mov     sec_count,cx	;an000;save cx				;an005;bgb
	    mov     cx,secs_per_64k	;an000;get maximum read 		;an005;bgb
	    call    read_once		;an000;read it				;an005;bgb
;	$LEAVE	C								;an005;bgb
	JC $$EN1
	    mov     cx,es							;an005;bgb
	    add     cx,paras_per_64k	; adjust transfer area			;an005;bgb
	    mov     es,cx							;an005;bgb
	    mov     cx,sec_count	; restore sector count			;an005;bgb
	    sub     cx,secs_per_64k	;an000;get sectors remaining		;an005;bgb
	    add     dx,secs_per_64k	;an000;adjust starting sector		;an005;bgb
;	$ENDDO									;an005;bgb
	JMP SHORT $$DO1
$$EN1:
	call	read_once	    ;an000;read it				;an005;bgb
	restorereg <es,dx,cx,bx,ax>						;an005;bgb
	ret									;an005;bgb
read_disk	endp								 ;an005;bgb
										;an005;bgb
										;an005;bgb
;*****************************************************************************	;an005;bgb
;Routine name: Read_once							;an005;bgb
;*****************************************************************************	;an005;bgb
;										;an005;bgb
;description: Read in data using Generic IOCtl					;an005;bgb
;										;an005;bgb
;Called Procedures: None							;an005;bgb
;										;an005;bgb
;										;an005;bgb
;Change History: Created	5/13/87 	MT				;an005;bgb
;										;an005;bgb
;Input: AL = Drive number (0=A) 						;an005;bgb
;	es:BX = Transfer address						;an005;bgb
;	CX = Number of sectors							;an005;bgb
;	Read_Write_Relative.Start_Sector_High = Number of sectors high		;an005;bgb
;	DX = logical sector number low						;an005;bgb
;										;an005;bgb
;Output: CY if error								;an005;bgb
;	 AH = INT 25h error code						;an005;bgb
;										;an005;bgb
;Psuedocode									;an005;bgb
;----------									;an005;bgb
;	Save registers								;an005;bgb
;	Setup structure for function call					;an005;bgb
;	Read the disk (AX=440Dh, CL = 6Fh)					;an005;bgb
;	Restore registers							;an005;bgb
;	ret									;an005;bgb
;*****************************************************************************	;an005;bgb
Procedure Read_once				;				;an005;bgb
	savereg  <ax,bx,cx,dx,si,di,bp,es,ds>	;Change it to Read relative sect;an005;bgb
	mov	Read_Write_Relative.Buffer_Offset,bx ;Get transfer buffer add	 ;an005;bgb
	mov	bx,es				;				;AN005;bgb
	mov	Read_Write_Relative.Buffer_Segment,bx ;Get segment		;an005;bgb
	mov	Read_Write_Relative.Number_Sectors,cx ;Number of sec to read	;an005;bgb
	mov	Read_Write_Relative.Start_Sector_Low,dx ;Start sector		;an005;bgb
	mov	bx,offset Read_Write_Relative	;				;an005;bgb
	mov	cx,0FFFFh			;Read relative sector		;an005;bgb
	INT	25h				;Do the read			;an005;bgb
	pop dx					;Throw away flags on stack	;an005;bgb
	restorereg <ds,es,bp,di,si,dx,cx,bx,ax> 				;an005;bgb
	return									;an005;bgb
 Read_once endp 								;an005;bgb
										;an005;bgb
										;an005;bgb
;=========================================================================	;an005;bgb
; WRITE-DISK	:	This routine reads the logical sector count requested.	;an005;bgb
;			It will read a maximum of 64k in one read.  If more	;an005;bgb
;			than 64k exists it will continue looping until		;an005;bgb
;			all sectors have been read.				;an005;bgb
;										;an005;bgb
;	Inputs	:	AL - Drive letter					;an005;bgb
;			ES:BX - Segment:offset of transfer address		;an005;bgb
;			CX - Sector count					;an005;bgb
;			DX - 1st  sector					;an005;bgb
;										;an005;bgb
;	Outputs :	Logical sectors read					;an005;bgb
; LOGIC 									;an005;bgb
; ***** 									;an005;bgb
;    adjust es:bx to es:00							;an005;bgb
;    calcluate sectors-per-64k (how many sectors are there that can fit within a 64k segment?)
;    DO while there are more sectors to read than sectors-per-64k		;an005;bgb
;	set sector-count to sectors-per-64k					;an005;bgb
;	perform the disk read							;an005;bgb
;	bump the seg addr to the new addr					;an005;bgb
;	dec  the number of sectors to read by sectors-per-64k			;an005;bgb
;	bump the starting sector number by the sectors-per-64k			;an005;bgb
;    ENDDO									;an005;bgb
;    perform a disk read for less than sectors-per-64k				;an005;bgb
;=========================================================================	;an005;bgb
procedure      write_disk							;an005;bgb
	savereg <ax,bx,cx,dx,es>						;an013;bgb
	call	seg_adj 		;an000;calc new seg:off 		;an005;bgb
;	$DO				; do while more than 64k		;an005;bgb
$$DO5:
	    cmp     cx,secs_per_64k	;an000;exceed 64k			;an005;bgb
;	$LEAVE	LE			;an000;yes				;an005;bgb
	JLE $$EN5
	    mov     sec_count,cx	;an000;save cx				;an005;bgb
	    mov     cx,secs_per_64k	;an000;get maximum read 		;an005;bgb
	    call   write_once		;an000;read it				;an005;bgb
;	$LEAVE	C								;an005;bgb
	JC $$EN5
	    mov     cx,es							;an005;bgb
	    add     cx,paras_per_64k	; adjust transfer area			;an005;bgb
	    mov     es,cx							;an005;bgb
	    mov     cx,sec_count	; restore sector count			;an005;bgb
	    sub     cx,secs_per_64k	;an000;get sectors remaining		;an005;bgb
	    add     dx,secs_per_64k	;an000;adjust starting sector		;an005;bgb
;	$ENDDO									;an005;bgb
	JMP SHORT $$DO5
$$EN5:
	call	write_once		;an000;read it				;an005;bgb
	restorereg <es,dx,cx,bx,ax>						;an013;bgb
	ret									;an005;bgb
write_disk	endp								;an005;bgb
										;an005;bgb
;*****************************************************************************	;an005;bgb
;Routine name: Write_once							;an005;bgb
;*****************************************************************************	;an005;bgb
;										;an005;bgb
;description: Write Data using int 26						;an005;bgb
;										;an005;bgb
;Called Procedures: None							;an005;bgb
;										;an005;bgb
;										;an005;bgb
;Change History: Created	5/13/87 	MT				;an005;bgb
;										;an005;bgb
;Input: AL = Drive number (0=A) 						;an005;bgb
;	DS:BX = Transfer address						;an005;bgb
;	CX = Number of sectors							;an005;bgb
;	Read_Write_Relative.Start_Sector_High = already set up			;an048;bgb
;	DX = logical sector number low						;an005;bgb
;										;an005;bgb
;Output: CY if error								;an005;bgb
;	 AH = INT 26h error code						;an005;bgb
;										;an005;bgb
;Psuedocode									;an005;bgb
;----------									;an005;bgb
;	Save registers								;an005;bgb
;	Setup structure for function call					;an005;bgb
;	Write to disk (AX=440Dh, CL = 4Fh)					;an005;bgb
;	Restore registers							;an005;bgb
;	ret									;an005;bgb
;*****************************************************************************	;an005;bgb
Procedure Write_once				 ;				;an005;bgb
    savereg <ax,bx,cx,dx,di,si,bp,es,ds>	 ;This is setup for INT 26h right;AN005;bgb
    mov  Read_Write_Relative.Buffer_Offset,bx	 ;Get transfer buffer add	;AN005;bgb
    mov  bx,es					 ;				;AN005;bgb
    mov  Read_Write_Relative.Buffer_Segment,bx	 ;Get segment			;AN005;bgb
    mov  Read_Write_Relative.Number_Sectors,cx	 ;Number of sec to write	;AN005;bgb
    mov  Read_Write_Relative.Start_Sector_Low,dx ;Start sector			;AN005;bgb
    mov  cx,0FFFFh				 ;Write relative sector 	;AN005;bgb
    lea  bx,read_write_relative 		 ;				;an005;bgb
    INT  026h					 ;Do the write			;AN005;bgb
    pop  dx					 ;flags is returned on the stack;AN005;bgb
    restorereg <ds,es,bp,si,di,dx,cx,bx,ax>	 ;				;AN005;bgb
	ret					 ;				;AN005;bgb
Write_once endp 				 ;				;AN005;bgb
										;an005;bgb
;=========================================================================	;an005;bgb
; SEG_ADJ	:	This routine adjusts the segment:offset to prevent	;an005;bgb
;			address wrap.						;an005;bgb
;										;an005;bgb
;	Inputs	:	bx - Offset to adjust segment with			;an005;bgb
;			es - Segment to be adjusted				;an005;bgb
;										;an005;bgb
;	Outputs :	bx - New offset 					;an005;bgb
;			es - Adjusted segment					;an005;bgb
;=========================================================================	;an005;bgb
procedure	seg_adj 							;an005;bgb
	savereg <ax,cx,dx>							;an005;bgb
	mov	ax,bx				;an000;get offset		;an005;bgb
	mov	bx,0010h			;divide by 16			;an005;bgb
	xor	dx,dx				;an000;clear dx 		;an005;bgb
	div	bx				;an000;get para count	    ;an022;bgb
	mov	bx,es				;an000;get seg			;an005;bgb
	add	bx,ax				;an000;adjust for paras 	;an005;bgb
	mov	es,bx				;an000;save new seg		;an005;bgb
	mov	bx,dx				;an000;new offset		;an005;bgb
	restorereg <dx,cx,ax>							;an005;bgb
	ret									;an005;bgb
seg_adj 	endp								;an005;bgb
										;an005;bgb
										;an005;bgb
;=========================================================================	;an005;bgb
; CALC_SP64K	:	This routine calculates how many sectors, for this	;an005;bgb
;			particular media, will fit into 64k.			;an005;bgb
;										;an005;bgb
;	Inputs	:	DPB_SECTOR_SIZE - bytes/sector				;an005;bgb
;										;an005;bgb
;	Outputs :	SECS_PER_64K	- Sectors / 64k 			;an005;bgb
;			PARAS_PER_64K	- paragraphs per 64k			;an005;bgb
;=========================================================================	;an005;bgb
procedure	calc_sp64k							;an005;bgb
	savereg <ax,bx,cx,dx>							;an005;bgb
	mov	ax,0ffffh			;an000;64k			;an005;bgb
	mov	bx,bytes_per_sector		;an000;get bytes/sector 	;an005;bgb
	xor	dx,dx				;an000;clear dx 		;an005;bgb
	div	bx				;an000;sector count	    ;an022;bgb;bgb
	mov	secs_per_64k,ax 		;an000;save sector count	;an005;bgb
	mov	ax,bytes_per_sector		;an000;get bytes/sector 	;an005;bgb
	mov	bx,010h 			; divide by paras		;an005;bgb
	xor	dx,dx				;an000;clear dx 		;an005;bgb
	div	bx				; paras per sector	    ;an022;bgb;bgb
	mul	secs_per_64k			; times sectors 		;an005;bgb
	mov	paras_per_64k,ax		; = paras per 64k		;an005;bgb
	restorereg <dx,cx,bx,ax>		;an000;restore dx		;an005;bgb
	ret					;an000; 			;an005;bgb
calc_sp64k	endp				;an000; 			;an005;bgb
										;an005;bgb
										;an005;bgb
	Break	<ReadFT - read in the entire fat>				;an005;bgb
;****************************************************************************** ;an005;bgb
;   ReadFt - attempt to read in the fat.  If there are errors, step to		;an005;bgb
;   successive fats until no more.						;an005;bgb
;										;an005;bgb
;   Inputs:	none.								;an005;bgb
;   Outputs:	Fats are read until one succeeds.				;an005;bgb
;		Carry set indicates no Fat could be read.			;an005;bgb
;   Registers modified: all							;an005;bgb
; LOGIC 									;an005;bgb
; ***** 									;an005;bgb
;  DO for each of the fats on the disk: 					;an005;bgb
;     read - all the sectors in the fat 					;an005;bgb
;     increase the starting sector by the number of sectors in each fat 	;an005;bgb
;										;an005;bgb
; LARGE FAT SUPPORT - the big change here is in read disk.  since the fat must	;an005;bgb
;     be within the first 32M, then the starting sector number of 65535 is ok,	;an005;bgb
;     as is a larger number of sectors to read/write.				;an005;bgb
;****************************************************************************** ;an005;bgb
Procedure ReadFt,NEAR								;an005;bgb
    clc 				;Clear CY so we will loop		    ;an005;bgb
    mov     Read_Write_Relative.Start_Sector_High,0 ;			;an005;bgb
    call    Read_Disk			;	Read_Disk ();		    ;AC0;an005;bgb
;   $IF     C
    JNC $$IF9
	add	dx,cx			;	fatstart += fatsize		;an005;bgb
	call	Read_Disk		;	Read_Disk ();		    ;AC0;an005;bgb
;   $ENDIF
$$IF9:
bad_read: ret									;an005;bgb
EndProc ReadFt									;an005;bgb


	pathlabl chkdisk
CODE	ENDS
	END