1 TITLE CHKDISK
- procedures that read
or write to the disk
5 include chkseg
.inc ;an005;bgb
13 CONST
SEGMENT PUBLIC PARA
'DATA'
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
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
34 CODE SEGMENT PUBLIC PARA
'CODE'
35 ASSUME
CS:DG
,DS:DG
,ES:DG
,SS:DG
36 EXTRN FCB_TO_ASCZ
: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
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
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
58 ; Outputs : Logical sectors read ;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
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
78 cmp cx,secs_per_64k
;an000;exceed 64k ;an005;bgb
79 ; $LEAVE LE ;an000;yes ;an005;bgb
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
87 add cx,paras_per_64k
; adjust transfer area ;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
95 call read_once
;an000;read it ;an005;bgb
96 restorereg
<es,dx,cx,bx,ax> ;an005;bgb
98 read_disk endp
;an005;bgb
101 ;***************************************************************************** ;an005;bgb
102 ;Routine name: Read_once ;an005;bgb
103 ;***************************************************************************** ;an005;bgb
105 ;description: Read in data using Generic IOCtl ;an005;bgb
107 ;Called Procedures: None ;an005;bgb
110 ;Change History: Created 5/13/87 MT ;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
118 ;Output: CY if error ;an005;bgb
119 ; AH = INT 25h error code ;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
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
142 Read_once endp
;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
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
156 ; Outputs : Logical sectors read ;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
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
175 cmp cx,secs_per_64k
;an000;exceed 64k ;an005;bgb
176 ; $LEAVE LE ;an000;yes ;an005;bgb
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
184 add cx,paras_per_64k
; adjust transfer area ;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
192 call write_once
;an000;read it ;an005;bgb
193 restorereg
<es,dx,cx,bx,ax> ;an013;bgb
195 write_disk endp
;an005;bgb
197 ;***************************************************************************** ;an005;bgb
198 ;Routine name: Write_once ;an005;bgb
199 ;***************************************************************************** ;an005;bgb
201 ;description: Write Data using int 26 ;an005;bgb
203 ;Called Procedures: None ;an005;bgb
206 ;Change History: Created 5/13/87 MT ;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
214 ;Output: CY if error ;an005;bgb
215 ; AH = INT 26h error code ;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
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
238 Write_once endp
; ;AN005;bgb
240 ;========================================================================= ;an005;bgb
241 ; SEG_ADJ : This routine adjusts the segment:offset to prevent ;an005;bgb
242 ; address wrap. ;an005;bgb
244 ; Inputs : bx - Offset to adjust segment with ;an005;bgb
245 ; es - Segment to be adjusted ;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
262 seg_adj endp
;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
269 ; Inputs : DPB_SECTOR_SIZE - bytes/sector ;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
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
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
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
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
317 add dx,cx ; fatstart += fatsize ;an005;bgb
318 call Read_Disk
; Read_Disk (); ;AC0;an005;bgb
321 bad_read: ret ;an005;bgb
322 EndProc ReadFt
;an005;bgb