]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/BIOS/MSVOLID.INC

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / BIOS / MSVOLID.INC
1 ;-------------------------------------------------------------------------
2 ;
3 ; File: msvolid.asm
4 ; This file contains the volume_id subroutines and data structures.
5 ;
6 ; Routines in this file are:
7 ; Set_Volume_ID - main routine, calls other routines.
8 ; read_volume_id - read the volume ID and tells if it has
9 ; been changed.
10 ; Transfer_volume_id - copy the volume ID from TMP to special
11 ; drive.
12 ; Check_Volume_ID - compare volume ID in TMP area with one
13 ; expected for drive.
14 ; Fat_Check - see of the fatID has changed in the
15 ; specified drive.
16 ; Init_Vid_loop - set up for VID scan or move
17 ;
18 ;
19 ;-------------------------------------------------------------------------
20
21 ;
22 ; length of the volume id
23 ;
24
25 vid_size equ 12
26
27 PATHSTART 001,VOLID ;3.30
28
29 ;
30 ; null volume id
31 ;
32
33 nul_vid db "NO NAME ",0
34
35 ;
36 ; data scratch area used to hold volume ids
37 ;
38
39 tmp_vid db "NO NAME ",0
40
41 PATHEND 001,VOLID ;3.30
42
43 ;
44 ; Set_Volume_ID
45 ; If drive has changeline support, read in and set the volume_ID
46 ; and the last FAT_ID byte. If no change line support then do nothing.
47 ;
48 ; On entry:
49 ; DS:DI points to the BDS for this disk.
50 ; AH contains media byte
51 ;
52 ; On Exit:
53 ; Carry clear:
54 ; Successful call
55 ; Carry set
56 ; Error and AX has error code
57 ;
58
59 Set_Volume_ID:
60 PUBLIC SET_VOLUME_ID ;3.30
61 push dx ; save registers
62 push ax
63 CALL HasChange ; does drive have changeline support?
64 jz setvret ; no, get out
65 push di
66 call read_volume_ID ; read the volume ID
67 pop di
68 jc SetErr ; if error go to error routine
69 call transfer_volume_ID ; copy the volume id to special drive
70 call ResetChanged ; restore value of change line
71
72 setvret: ; SET Volume RETurn
73 clc ; no error, clear carry flag
74 pop ax ; restore registers
75 pop dx
76 ret
77 SetErr:
78 pop dx ; pop stack but don't overwrite AX
79 pop dx ; restore DX
80 ret
81
82
83
84 root_sec DW ? ;Root sector #
85
86
87
88
89 ;
90 ; read_volume_id read the volume ID and tells if it has been changed.
91 ;
92 ; On entry:
93 ; DS:DI points to current BDS for drive.
94 ; On Exit:
95 ; Carry Clear
96 ; SI = 1 No change
97 ; SI = 0 ?
98 ; SI = -1 Change
99 ;
100 ; Carry Set:
101 ; Error and AX has error code.
102 ;
103
104 read_volume_id:
105 push ES ; preserve registers
106 push DX
107 push CX
108 push BX
109 push AX
110 push DS ; Preserve Current BDS
111 push DI
112 push cs ; get ES segment correct
113 pop es
114 push cs ; get DS segment correct
115 pop ds
116 mov di,offset tmp_vid
117 mov si,offset nul_vid
118 mov cx,vid_size
119 rep movsb ; initialize tmp_vid to null vi_id
120
121 pop DI ; Restore Current BDS
122 pop DS
123 mov al,byte ptr ds:[di].cFAT ; # of fats
124 mov cx,word ptr ds:[di].csecfat ; sectors / fat
125 mul cl ; size taken by fats
126 add ax,word ptr ds:[di].ressec ; add on reserved sectors
127 ; AX is now sector # (0 based)
128 mov cs:[root_sec],ax ; set initial value
129 mov ax,[di].cDir ; # root dir entries
130 mov cl,4 ; 16 entries/sector
131 shr ax,cl ; divide by 16
132 mov cx,ax ; cx is # of sectors to scan
133 next_sec:
134 push cx ; save outer loop counter
135 mov ax,cs:[root_sec] ; get sector #
136 mov cx,word ptr ds:[di].seclim ; sectors / track
137 xor DX,DX
138 div cx
139 ; set up registers for call to read_sector
140 inc DX ; dx= sectors into track, ax= track count from 0
141 mov cl,dl ; sector to read
142 xor DX,DX
143 div word ptr ds:[di].hdlim ; # heads on this disc
144 mov dh,dl ; Head number
145 mov ch,al ; Track #
146 call read_sector ; get first sector of the root directory,
147 ; ES:BX -> BOOT
148 jc ReadVIDErr ; error on read
149 mov cx,16 ; # of dir entries in a block of root
150 mov al,08h ; volume label bit
151 fvid_loop:
152 cmp byte ptr es:[bx],0 ; End of dir?
153 jz no_vid ; yes, no vol id
154 cmp byte ptr es:[bx],0E5h ; empty entry?
155 jz ent_loop ; yes, skip
156 test es:[bx+11],al ; is volume label bit set in fcb?
157 jnz found_vid ; jmp yes
158 ent_loop:
159 ADD BX,32 ;MJB003 ADD LENGTH OF DIRECTORY ENTRY ;3.30
160 loop fvid_loop
161 pop cx ; outer loop
162 inc cs:[root_sec] ; next sector
163 loop next_sec ; continue
164 NotFound:
165 XOR SI,SI
166 jmp short fvid_ret
167
168 found_vid:
169 pop cx ; clean stack of outer loop counter
170 mov si,bx ; point to volume_id
171 push ds ; preserve currnet BDS
172 push di
173 push es ; es:si points to volume id.
174 pop ds ; source segment
175 push cs
176 pop es ; destination segment
177 mov di,offset tmp_vid ; dest of volume_id
178 mov cx,vid_size -1 ; length of string minus NUL
179 rep movsb ; mov volume label to tmp_vid
180 xor al,al
181 stosb ; Null terminate
182 XOR SI,SI
183 pop DI ; restore current BDS
184 pop DS
185 fvid_ret:
186 pop ax
187 clc
188 RVIDRet:
189 pop BX ; restore register
190 pop CX
191 pop DX
192 pop ES
193 ret
194 no_vid:
195 pop cx ; clean stack of outer loop counter
196 jmp NotFound ; not found
197 ReadVIDErr:
198 pop SI
199 pop SI
200 jmp RVIDRet
201
202
203
204 ;
205 ; Transfer_volume_id - copy the volume ID from TMP to special drive
206 ;
207 ; Inputs: DS:DI nas current BDS
208 ; Outputs: BDS for drive has volume ID from TMP
209 ;
210
211 transfer_volume_ID:
212 push DS ; preserve current BDS
213 push DI
214 push ES
215 push SI
216 push CX
217 call init_vid_loop
218 cld
219 rep MOVSB ; transfer
220 pop CX
221 pop SI
222 pop ES
223 pop DI ; restore current BDS
224 pop DS
225 ret
226
227
228 ;
229 ; Check_Volume_ID - compare volume ID in TMP area with one expected for
230 ; drive
231 ;
232 ; Inputs: DS:DI has current BDS for drive
233 ; Outputs: SI = 0 if compare succeeds
234 ; SI = -1 if compare fails.
235
236 check_volume_id:
237 push DS ; preserve current BDS for drive
238 push DI
239 push ES
240 push CX
241 call init_vid_loop
242 cld
243 repz cmpsb ; are the 2 volume_ids the same?
244 mov si,0 ; assume unknown
245 jz check_vid_ret ; carry clear if jump taken
246 mov si,-1 ; failure
247 check_vid_ret:
248 pop CX
249 pop ES
250 pop DI ; restore current BDS
251 pop DS
252 ret
253
254 ;
255 ; Fat_Check - see of the fatID has changed in the specified drive.
256 ; - uses the FAT ID obtained from the boot sector.
257 ;
258 ; Inputs: MedByt is expected FAT ID
259 ; DS:DI points to current BDS
260 ; Output: Carry Clear
261 ; SI = -1 if fat ID different,
262 ; SI = 0 otherwise
263 ; No other registers changed.
264
265 FAT_CHECK:
266 push AX
267 xor SI, SI ; say FAT ID's are same.
268 mov AL, cs:MedByt
269 cmp AL, byte ptr [DI].Mediad ; compare it with the BDS medbyte
270 jz OKRET1 ; carry clear
271 dec SI
272 OkRet1: clc
273 pop AX
274 ret
275
276
277 ;
278 ; Init_Vid_loop - set up for VID scan or move
279 ;
280 ; Inputs: DS:DI pionts to BDS for the drive
281 ; Outputs: DS:SI points to tmp_vid
282 ; ES:DI points to vid for drive
283 ; CX has size for VID compare
284 ;
285
286 init_vid_loop:
287 push ax
288 push ds
289 pop es
290 push cs
291 pop ds
292 mov si,offset tmp_vid ; source
293 add di,volid
294 mov cx,vid_size
295 pop ax
296 ret
297