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
|
;-------------------------------------------------------------------------
;
; File: msvolid.asm
; This file contains the volume_id subroutines and data structures.
;
; Routines in this file are:
; Set_Volume_ID - main routine, calls other routines.
; read_volume_id - read the volume ID and tells if it has
; been changed.
; Transfer_volume_id - copy the volume ID from TMP to special
; drive.
; Check_Volume_ID - compare volume ID in TMP area with one
; expected for drive.
; Fat_Check - see of the fatID has changed in the
; specified drive.
; Init_Vid_loop - set up for VID scan or move
;
;
;-------------------------------------------------------------------------
;
; length of the volume id
;
vid_size equ 12
PATHSTART 001,VOLID ;3.30
;
; null volume id
;
nul_vid db "NO NAME ",0
;
; data scratch area used to hold volume ids
;
tmp_vid db "NO NAME ",0
PATHEND 001,VOLID ;3.30
;
; Set_Volume_ID
; If drive has changeline support, read in and set the volume_ID
; and the last FAT_ID byte. If no change line support then do nothing.
;
; On entry:
; DS:DI points to the BDS for this disk.
; AH contains media byte
;
; On Exit:
; Carry clear:
; Successful call
; Carry set
; Error and AX has error code
;
Set_Volume_ID:
PUBLIC SET_VOLUME_ID ;3.30
push dx ; save registers
push ax
CALL HasChange ; does drive have changeline support?
jz setvret ; no, get out
push di
call read_volume_ID ; read the volume ID
pop di
jc SetErr ; if error go to error routine
call transfer_volume_ID ; copy the volume id to special drive
call ResetChanged ; restore value of change line
setvret: ; SET Volume RETurn
clc ; no error, clear carry flag
pop ax ; restore registers
pop dx
ret
SetErr:
pop dx ; pop stack but don't overwrite AX
pop dx ; restore DX
ret
root_sec DW ? ;Root sector #
;
; read_volume_id read the volume ID and tells if it has been changed.
;
; On entry:
; DS:DI points to current BDS for drive.
; On Exit:
; Carry Clear
; SI = 1 No change
; SI = 0 ?
; SI = -1 Change
;
; Carry Set:
; Error and AX has error code.
;
read_volume_id:
push ES ; preserve registers
push DX
push CX
push BX
push AX
push DS ; Preserve Current BDS
push DI
push cs ; get ES segment correct
pop es
push cs ; get DS segment correct
pop ds
mov di,offset tmp_vid
mov si,offset nul_vid
mov cx,vid_size
rep movsb ; initialize tmp_vid to null vi_id
pop DI ; Restore Current BDS
pop DS
mov al,byte ptr ds:[di].cFAT ; # of fats
mov cx,word ptr ds:[di].csecfat ; sectors / fat
mul cl ; size taken by fats
add ax,word ptr ds:[di].ressec ; add on reserved sectors
; AX is now sector # (0 based)
mov cs:[root_sec],ax ; set initial value
mov ax,[di].cDir ; # root dir entries
mov cl,4 ; 16 entries/sector
shr ax,cl ; divide by 16
mov cx,ax ; cx is # of sectors to scan
next_sec:
push cx ; save outer loop counter
mov ax,cs:[root_sec] ; get sector #
mov cx,word ptr ds:[di].seclim ; sectors / track
xor DX,DX
div cx
; set up registers for call to read_sector
inc DX ; dx= sectors into track, ax= track count from 0
mov cl,dl ; sector to read
xor DX,DX
div word ptr ds:[di].hdlim ; # heads on this disc
mov dh,dl ; Head number
mov ch,al ; Track #
call read_sector ; get first sector of the root directory,
; ES:BX -> BOOT
jc ReadVIDErr ; error on read
mov cx,16 ; # of dir entries in a block of root
mov al,08h ; volume label bit
fvid_loop:
cmp byte ptr es:[bx],0 ; End of dir?
jz no_vid ; yes, no vol id
cmp byte ptr es:[bx],0E5h ; empty entry?
jz ent_loop ; yes, skip
test es:[bx+11],al ; is volume label bit set in fcb?
jnz found_vid ; jmp yes
ent_loop:
ADD BX,32 ;MJB003 ADD LENGTH OF DIRECTORY ENTRY ;3.30
loop fvid_loop
pop cx ; outer loop
inc cs:[root_sec] ; next sector
loop next_sec ; continue
NotFound:
XOR SI,SI
jmp short fvid_ret
found_vid:
pop cx ; clean stack of outer loop counter
mov si,bx ; point to volume_id
push ds ; preserve currnet BDS
push di
push es ; es:si points to volume id.
pop ds ; source segment
push cs
pop es ; destination segment
mov di,offset tmp_vid ; dest of volume_id
mov cx,vid_size -1 ; length of string minus NUL
rep movsb ; mov volume label to tmp_vid
xor al,al
stosb ; Null terminate
XOR SI,SI
pop DI ; restore current BDS
pop DS
fvid_ret:
pop ax
clc
RVIDRet:
pop BX ; restore register
pop CX
pop DX
pop ES
ret
no_vid:
pop cx ; clean stack of outer loop counter
jmp NotFound ; not found
ReadVIDErr:
pop SI
pop SI
jmp RVIDRet
;
; Transfer_volume_id - copy the volume ID from TMP to special drive
;
; Inputs: DS:DI nas current BDS
; Outputs: BDS for drive has volume ID from TMP
;
transfer_volume_ID:
push DS ; preserve current BDS
push DI
push ES
push SI
push CX
call init_vid_loop
cld
rep MOVSB ; transfer
pop CX
pop SI
pop ES
pop DI ; restore current BDS
pop DS
ret
;
; Check_Volume_ID - compare volume ID in TMP area with one expected for
; drive
;
; Inputs: DS:DI has current BDS for drive
; Outputs: SI = 0 if compare succeeds
; SI = -1 if compare fails.
check_volume_id:
push DS ; preserve current BDS for drive
push DI
push ES
push CX
call init_vid_loop
cld
repz cmpsb ; are the 2 volume_ids the same?
mov si,0 ; assume unknown
jz check_vid_ret ; carry clear if jump taken
mov si,-1 ; failure
check_vid_ret:
pop CX
pop ES
pop DI ; restore current BDS
pop DS
ret
;
; Fat_Check - see of the fatID has changed in the specified drive.
; - uses the FAT ID obtained from the boot sector.
;
; Inputs: MedByt is expected FAT ID
; DS:DI points to current BDS
; Output: Carry Clear
; SI = -1 if fat ID different,
; SI = 0 otherwise
; No other registers changed.
FAT_CHECK:
push AX
xor SI, SI ; say FAT ID's are same.
mov AL, cs:MedByt
cmp AL, byte ptr [DI].Mediad ; compare it with the BDS medbyte
jz OKRET1 ; carry clear
dec SI
OkRet1: clc
pop AX
ret
;
; Init_Vid_loop - set up for VID scan or move
;
; Inputs: DS:DI pionts to BDS for the drive
; Outputs: DS:SI points to tmp_vid
; ES:DI points to vid for drive
; CX has size for VID compare
;
init_vid_loop:
push ax
push ds
pop es
push cs
pop ds
mov si,offset tmp_vid ; source
add di,volid
mov cx,vid_size
pop ax
ret
|