summaryrefslogtreecommitdiff
path: root/v4.0/src/BIOS/MSVOLID.INC
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/BIOS/MSVOLID.INC')
-rw-r--r--v4.0/src/BIOS/MSVOLID.INC297
1 files changed, 297 insertions, 0 deletions
diff --git a/v4.0/src/BIOS/MSVOLID.INC b/v4.0/src/BIOS/MSVOLID.INC
new file mode 100644
index 0000000..d1a9588
--- /dev/null
+++ b/v4.0/src/BIOS/MSVOLID.INC
@@ -0,0 +1,297 @@
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
25vid_size equ 12
26
27 PATHSTART 001,VOLID ;3.30
28
29;
30; null volume id
31;
32
33nul_vid db "NO NAME ",0
34
35;
36; data scratch area used to hold volume ids
37;
38
39tmp_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
59Set_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
72setvret: ; SET Volume RETurn
73 clc ; no error, clear carry flag
74 pop ax ; restore registers
75 pop dx
76 ret
77SetErr:
78 pop dx ; pop stack but don't overwrite AX
79 pop dx ; restore DX
80 ret
81
82
83
84root_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
104read_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
133next_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
151fvid_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
158ent_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
164NotFound:
165 XOR SI,SI
166 jmp short fvid_ret
167
168found_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
185fvid_ret:
186 pop ax
187 clc
188RVIDRet:
189 pop BX ; restore register
190 pop CX
191 pop DX
192 pop ES
193 ret
194no_vid:
195 pop cx ; clean stack of outer loop counter
196 jmp NotFound ; not found
197ReadVIDErr:
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
211transfer_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
236check_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
247check_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
265FAT_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
272OkRet1: 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
286init_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