summaryrefslogtreecommitdiff
path: root/v2.0/source/ROM.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/ROM.ASM')
-rw-r--r--v2.0/source/ROM.ASM530
1 files changed, 530 insertions, 0 deletions
diff --git a/v2.0/source/ROM.ASM b/v2.0/source/ROM.ASM
new file mode 100644
index 0000000..f668986
--- /dev/null
+++ b/v2.0/source/ROM.ASM
@@ -0,0 +1,530 @@
1;
2; Disk utilities of MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10.XLIST
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17TITLE ROM - miscellaneous routines
18NAME ROM
19
20 i_need CLUSNUM,WORD
21 i_need NEXTADD,WORD
22 i_need LASTPOS,WORD
23 i_need SECCLUSPOS,BYTE
24 i_need FATBYT,WORD
25 i_need RECPOS,4
26 i_need THISFCB,DWORD
27 i_need TRANS,BYTE
28 i_need BYTCNT1,WORD
29 i_need CURBUF,DWORD
30 i_need BYTSECPOS,WORD
31 i_need DMAADD,WORD
32 i_need SECPOS,WORD
33 i_need VALSEC,WORD
34
35 procedure GET_random_record,NEAR
36 entry GETRRPOS1
37 MOV CX,1
38 entry GetRRPos
39 MOV DI,DX
40 CMP BYTE PTR [DI],-1
41 JNZ NORMFCB1
42 ADD DI,7
43NORMFCB1:
44 MOV AX,WORD PTR [DI.fcb_RR]
45 MOV DX,WORD PTR [DI.fcb_RR+2]
46 return
47GET_random_record ENDP
48
49SUBTTL FNDCLUS -- Skip over allocation units
50PAGE
51 procedure FNDCLUS,NEAR
52ASSUME DS:DOSGROUP,ES:NOTHING
53
54; Inputs:
55; CX = No. of clusters to skip
56; ES:BP = Base of drive parameters
57; [THISFCB] point to FCB
58; Outputs:
59; BX = Last cluster skipped to
60; CX = No. of clusters remaining (0 unless EOF)
61; DX = Position of last cluster
62; DI destroyed. No other registers affected.
63
64 PUSH ES
65 LES DI,[THISFCB]
66 MOV BX,ES:[DI.fcb_LSTCLUS] ; fcb_lstclus is packed with dir clus
67 AND BX,0FFFh ; get rid of dir nibble
68 MOV DX,ES:[DI.fcb_CLUSPOS]
69 OR BX,BX
70 JZ NOCLUS
71 SUB CX,DX
72 JNB FINDIT
73 ADD CX,DX
74 XOR DX,DX
75 MOV BX,ES:[DI.fcb_FIRCLUS]
76FINDIT:
77 POP ES
78 JCXZ RET10
79entry SKPCLP
80 invoke UNPACK
81 CMP DI,0FF8H
82 JAE RET10
83 XCHG BX,DI
84 INC DX
85 LOOP SKPCLP
86RET10: return
87
88NOCLUS:
89 POP ES
90 INC CX
91 DEC DX
92 return
93FNDCLUS ENDP
94
95SUBTTL BUFSEC -- BUFFER A SECTOR AND SET UP A TRANSFER
96PAGE
97 procedure BUFSEC,NEAR
98ASSUME DS:DOSGROUP,ES:NOTHING
99
100; Inputs:
101; AH = priority of buffer
102; AL = 0 if buffer must be read, 1 if no pre-read needed
103; ES:BP = Base of drive parameters
104; [CLUSNUM] = Physical cluster number
105; [SECCLUSPOS] = Sector position of transfer within cluster
106; [BYTCNT1] = Size of transfer
107; Function:
108; Insure specified sector is in buffer, flushing buffer before
109; read if necessary.
110; Outputs:
111; ES:DI = Pointer to buffer
112; SI = Pointer to transfer address
113; CX = Number of bytes
114; [NEXTADD] updated
115; [TRANS] set to indicate a transfer will occur
116
117 MOV DX,[CLUSNUM]
118 MOV BL,[SECCLUSPOS]
119 CALL FIGREC
120 invoke GETBUFFR
121 MOV BYTE PTR [TRANS],1 ; A transfer is taking place
122 MOV SI,[NEXTADD]
123 MOV DI,SI
124 MOV CX,[BYTCNT1]
125 ADD DI,CX
126 MOV [NEXTADD],DI
127 LES DI,[CURBUF]
128 ADD DI,BUFINSIZ ; Point to buffer
129 ADD DI,[BYTSECPOS]
130 return
131BUFSEC ENDP
132
133SUBTTL BUFRD, BUFWRT -- PERFORM BUFFERED READ AND WRITE
134PAGE
135 procedure BUFRD,NEAR
136ASSUME DS:DOSGROUP,ES:NOTHING
137
138; Do a partial sector read via one of the system buffers
139; ES:BP Points to DPB
140
141 PUSH ES
142 MOV AX,LBRPRI SHL 8 ; Assume last byte read
143 CALL BUFSEC
144 MOV BX,ES
145 MOV ES,[DMAADD+2]
146 MOV DS,BX
147ASSUME DS:NOTHING
148 XCHG DI,SI
149 SHR CX,1
150 JNC EVENRD
151 MOVSB
152EVENRD:
153 REP MOVSW
154 POP ES
155 LDS DI,[CURBUF]
156 LEA BX,[DI.BufInSiz]
157 SUB SI,BX ; Position in buffer
158 invoke PLACEBUF
159 CMP SI,ES:[BP.dpb_sector_size]
160 JB RBUFPLACED
161 invoke PLACEHEAD
162RBUFPLACED:
163 PUSH SS
164 POP DS
165 return
166BUFRD ENDP
167
168 procedure BUFWRT,NEAR
169ASSUME DS:DOSGROUP,ES:NOTHING
170
171; Do a partial sector write via one of the system buffers
172; ES:BP Points to DPB
173
174 MOV AX,[SECPOS]
175 INC AX ; Set for next sector
176 MOV [SECPOS],AX
177 CMP AX,[VALSEC] ; Has sector been written before?
178 MOV AL,1
179 JA NOREAD ; Skip preread if SECPOS>VALSEC
180 XOR AL,AL
181NOREAD:
182 PUSH ES
183 CALL BUFSEC
184 MOV DS,[DMAADD+2]
185ASSUME DS:NOTHING
186 SHR CX,1
187 JNC EVENWRT
188 MOVSB
189EVENWRT:
190 REP MOVSW
191 POP ES
192 LDS BX,[CURBUF]
193 MOV BYTE PTR [BX.BUFDIRTY],1
194 LEA SI,[BX.BufInSiz]
195 SUB DI,SI ; Position in buffer
196 MOV SI,DI
197 MOV DI,BX
198 invoke PLACEBUF
199 CMP SI,ES:[BP.dpb_sector_size]
200 JB WBUFPLACED
201 invoke PLACEHEAD
202WBUFPLACED:
203 PUSH SS
204 POP DS
205 return
206BUFWRT ENDP
207
208SUBTTL NEXTSEC -- Compute next sector to read or write
209PAGE
210 procedure NEXTSEC,NEAR
211ASSUME DS:DOSGROUP,ES:NOTHING
212
213; Compute the next sector to read or write
214; ES:BP Points to DPB
215
216 TEST BYTE PTR [TRANS],-1
217 JZ CLRET
218 MOV AL,[SECCLUSPOS]
219 INC AL
220 CMP AL,ES:[BP.dpb_cluster_mask]
221 JBE SAVPOS
222 MOV BX,[CLUSNUM]
223 CMP BX,0FF8H
224 JAE NONEXT
225 invoke UNPACK
226 MOV [CLUSNUM],DI
227 INC [LASTPOS]
228 MOV AL,0
229SAVPOS:
230 MOV [SECCLUSPOS],AL
231CLRET:
232 CLC
233 return
234NONEXT:
235 STC
236 return
237NEXTSEC ENDP
238
239SUBTTL OPTIMIZE -- DO A USER DISK REQUEST WELL
240PAGE
241 procedure OPTIMIZE,NEAR
242ASSUME DS:DOSGROUP,ES:NOTHING
243
244; Inputs:
245; BX = Physical cluster
246; CX = No. of records
247; DL = sector within cluster
248; ES:BP = Base of drives parameters
249; [NEXTADD] = transfer address
250; Outputs:
251; AX = No. of records remaining
252; BX = Transfer address
253; CX = No. or records to be transferred
254; DX = Physical sector address
255; DI = Next cluster
256; [CLUSNUM] = Last cluster accessed
257; [NEXTADD] updated
258; ES:BP unchanged. Note that segment of transfer not set.
259
260 PUSH DX
261 PUSH BX
262 MOV AL,ES:[BP.dpb_cluster_mask]
263 INC AL ; Number of sectors per cluster
264 MOV AH,AL
265 SUB AL,DL ; AL = Number of sectors left in first cluster
266 MOV DX,CX
267 MOV CX,0
268OPTCLUS:
269; AL has number of sectors available in current cluster
270; AH has number of sectors available in next cluster
271; BX has current physical cluster
272; CX has number of sequential sectors found so far
273; DX has number of sectors left to transfer
274; ES:BP Points to DPB
275; ES:SI has FAT pointer
276 invoke UNPACK
277 ADD CL,AL
278 ADC CH,0
279 CMP CX,DX
280 JAE BLKDON
281 MOV AL,AH
282 INC BX
283 CMP DI,BX
284 JZ OPTCLUS
285 DEC BX
286FINCLUS:
287 MOV [CLUSNUM],BX ; Last cluster accessed
288 SUB DX,CX ; Number of sectors still needed
289 PUSH DX
290 MOV AX,CX
291 MUL ES:[BP.dpb_sector_size] ; Number of sectors times sector size
292 MOV SI,[NEXTADD]
293 ADD AX,SI ; Adjust by size of transfer
294 MOV [NEXTADD],AX
295 POP AX ; Number of sectors still needed
296 POP DX ; Starting cluster
297 SUB BX,DX ; Number of new clusters accessed
298 ADD [LASTPOS],BX
299 POP BX ; BL = sector postion within cluster
300 invoke FIGREC
301 MOV BX,SI
302 return
303BLKDON:
304 SUB CX,DX ; Number of sectors in cluster we don't want
305 SUB AH,CL ; Number of sectors in cluster we accepted
306 DEC AH ; Adjust to mean position within cluster
307 MOV [SECCLUSPOS],AH
308 MOV CX,DX ; Anyway, make the total equal to the request
309 JMP SHORT FINCLUS
310OPTIMIZE ENDP
311
312SUBTTL FIGREC -- Figure sector in allocation unit
313PAGE
314 procedure FIGREC,NEAR
315ASSUME DS:NOTHING,ES:NOTHING
316
317; Inputs:
318; DX = Physical cluster number
319; BL = Sector postion within cluster
320; ES:BP = Base of drive parameters
321; Outputs:
322; DX = physical sector number
323; No other registers affected.
324
325 PUSH CX
326 MOV CL,ES:[BP.dpb_cluster_shift]
327 DEC DX
328 DEC DX
329 SHL DX,CL
330 OR DL,BL
331 ADD DX,ES:[BP.dpb_first_sector]
332 POP CX
333 return
334FIGREC ENDP
335
336SUBTTL GETREC -- Figure record in file from fcb
337PAGE
338 procedure GETREC,NEAR
339ASSUME DS:NOTHING,ES:NOTHING
340
341; Inputs:
342; DS:DX point to FCB
343; Outputs:
344; CX = 1
345; DX:AX = Record number determined by fcb_EXTENT and fcb_NR fields
346; DS:DI point to FCB
347; No other registers affected.
348
349 MOV DI,DX
350 CMP BYTE PTR [DI],-1 ; Check for extended FCB
351 JNZ NORMFCB2
352 ADD DI,7
353NORMFCB2:
354 MOV CX,1
355 MOV AL,[DI.fcb_NR]
356 MOV DX,[DI.fcb_EXTENT]
357 SHL AL,1
358 SHR DX,1
359 RCR AL,1
360 MOV AH,DL
361 MOV DL,DH
362 MOV DH,0
363 return
364GETREC ENDP
365
366SUBTTL ALLOCATE -- Assign disk space
367PAGE
368 procedure ALLOCATE,NEAR
369ASSUME DS:DOSGROUP,ES:NOTHING
370
371; Inputs:
372; BX = Last cluster of file (0 if null file)
373; CX = No. of clusters to allocate
374; DX = Position of cluster BX
375; ES:BP = Base of drive parameters
376; [THISFCB] = Points to FCB
377; Outputs:
378; IF insufficient space
379; THEN
380; Carry set
381; CX = max. no. of records that could be added to file
382; ELSE
383; Carry clear
384; BX = First cluster allocated
385; FAT is fully updated including dirty bit
386; fcb_FIRCLUS field of FCB set if file was null
387; SI,BP unchanged. All other registers destroyed.
388
389 PUSH BX ; save the fat byte
390 XOR BX,BX
391 invoke UNPACK
392 MOV [FATBYT],DI
393 POP BX
394
395 PUSH DX
396 PUSH CX
397 PUSH BX
398 MOV AX,BX
399CLUSALLOC:
400 MOV DX,BX
401FINDFRE:
402 INC BX
403 CMP BX,ES:[BP.dpb_max_cluster]
404 JLE TRYOUT
405 CMP AX,1
406 JG TRYIN
407 POP BX
408 MOV DX,0FFFH
409 invoke RELBLKS
410 POP AX ; No. of clusters requested
411 SUB AX,CX ; AX=No. of clusters allocated
412 POP DX
413 invoke RESTFATBYT
414 INC DX ; Position of first cluster allocated
415 ADD AX,DX ; AX=max no. of cluster in file
416 MOV DL,ES:[BP.dpb_cluster_mask]
417 MOV DH,0
418 INC DX ; DX=records/cluster
419 MUL DX ; AX=max no. of records in file
420 MOV CX,AX
421 SUB CX,WORD PTR [RECPOS] ; CX=max no. of records that could be written
422 JA MAXREC
423 XOR CX,CX ; If CX was negative, zero it
424MAXREC:
425 STC
426 return
427
428TRYOUT:
429 invoke UNPACK
430 JZ HAVFRE
431TRYIN:
432 DEC AX
433 JLE FINDFRE
434 XCHG AX,BX
435 invoke UNPACK
436 JZ HAVFRE
437 XCHG AX,BX
438 JMP SHORT FINDFRE
439HAVFRE:
440 XCHG BX,DX
441 MOV AX,DX
442 invoke PACK
443 MOV BX,AX
444 LOOP CLUSALLOC
445 MOV DX,0FFFH
446 invoke PACK
447 POP BX
448 POP CX ; Don't need this stuff since we're successful
449 POP DX
450 invoke UNPACK
451 invoke RESTFATBYT
452 XCHG BX,DI
453 OR DI,DI
454 retnz
455 PUSH ES
456 LES DI,[THISFCB]
457 AND BX,0FFFh
458 MOV ES:[DI.fcb_FIRCLUS],BX
459 AND ES:[DI.fcb_LSTCLUS],0F000h ; clear out old lstclus
460 OR ES:[DI.fcb_LSTCLUS],BX ; or the new guy in...
461 POP ES
462 return
463ALLOCATE ENDP
464
465 procedure RESTFATBYT,NEAR
466ASSUME DS:DOSGROUP,ES:NOTHING
467
468 PUSH BX
469 PUSH DX
470 PUSH DI
471 XOR BX,BX
472 MOV DX,[FATBYT]
473 invoke PACK
474 POP DI
475 POP DX
476 POP BX
477 return
478RESTFATBYT ENDP
479
480SUBTTL RELEASE -- DEASSIGN DISK SPACE
481PAGE
482 procedure RELEASE,NEAR
483ASSUME DS:DOSGROUP,ES:NOTHING
484
485; Inputs:
486; BX = Cluster in file
487; ES:BP = Base of drive parameters
488; Function:
489; Frees cluster chain starting with [BX]
490; AX,BX,DX,DI all destroyed. Other registers unchanged.
491
492 XOR DX,DX
493entry RELBLKS
494; Enter here with DX=0FFFH to put an end-of-file mark
495; in the first cluster and free the rest in the chain.
496 invoke UNPACK
497 retz
498 MOV AX,DI
499 invoke PACK
500 CMP AX,0FF8H
501 MOV BX,AX
502 JB RELEASE
503RET12: return
504RELEASE ENDP
505
506SUBTTL GETEOF -- Find the end of a file
507PAGE
508 procedure GETEOF,NEAR
509ASSUME DS:DOSGROUP,ES:NOTHING
510
511; Inputs:
512; ES:BP Points to DPB
513; BX = Cluster in a file
514; DS = CS
515; Outputs:
516; BX = Last cluster in the file
517; DI destroyed. No other registers affected.
518
519 invoke UNPACK
520 CMP DI,0FF8H
521 JAE RET12
522 MOV BX,DI
523 JMP SHORT GETEOF
524GETEOF ENDP
525
526do_ext
527
528CODE ENDS
529 END
530