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
|