]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/UTIL.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / UTIL.ASM
1 ; SCCSID = @(#)util.asm 1.1 85/04/10
2 TITLE UTIL - Handle utilities
3 NAME UTIL
4 ;
5 ; Handle related utilities for MSDOS 2.X.
6 ;
7 ; pJFNFromHandle written
8 ; SFFromHandle written
9 ; SFFromSFN written
10 ; JFNFree written
11 ; SFNFree written
12 ;
13 ; Modification history:
14 ;
15 ; Created: MZ 1 April 1983
16 ;
17
18 .xlist
19 ;
20 ; get the appropriate segment definitions
21 ;
22 include dosseg.asm
23
24 CODE SEGMENT BYTE PUBLIC 'CODE'
25 ASSUME SS:DOSGROUP,CS:DOSGROUP
26
27 .xcref
28 INCLUDE DOSSYM.INC
29 INCLUDE DEVSYM.INC
30 .cref
31 .list
32 .sall
33
34 I_need CurrentPDB,WORD ; current process data block location
35 I_need SFT_Addr,DWORD ; pointer to beginning of table
36 I_Need PROC_ID,WORD ; current process ID
37 I_Need USER_ID,WORD ; current user ID
38 if debug
39 I_need BugLev,WORD
40 I_need BugTyp,WORD
41 include bugtyp.asm
42 endif
43
44 BREAK <pJFNFromHandle - return pointer to JFN table entry>
45
46 ;
47 ; pJFNFromHandle - Given a handle, return the pointer to the JFN location
48 ; in the user's data space
49 ; Inputs: BX - Handle
50 ; Outputs: Carry Set
51 ; AX has error code
52 ; Carry reset
53 ; ES:DI point to the handle spot
54 ; Registers modified:
55 ; If no error, ES:DI, else AX,ES
56 ; NOTE:
57 ; This routine is called from $CREATE_PROCESS_DATA_BLOCK which is called
58 ; at DOSINIT time with SS NOT DOSGROUP
59 procedure pJFNFromHandle,NEAR
60 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
61 MOV ES,[CurrentPDB] ; get user process data block
62 CMP BX,ES:[PDB_JFN_Length] ; is handle greater than allocated
63 JB JFNAdd ; no, get offset
64 fmt TypAccess,LevSFN,<"$p: Illegal JFN %x\n">,<BX>
65 MOV AL,error_invalid_handle ; appropriate error
66 ReturnCarry:
67 STC ; signal error
68 return ; go back
69 JFNAdd: LES DI,ES:[PDB_JFN_Pointer] ; get pointer to beginning of table
70 ADD DI,BX ; add in offset
71 ReturnNoCarry:
72 CLC ; no holes
73 return ; bye!
74 EndProc pJFNFromHandle
75
76 BREAK <SFFromHandle - return pointer (or error) to SF entry from handle>
77
78 ;
79 ; SFFromHandle - Given a handle, get JFN and then index into SF table
80 ;
81 ; Input: BX has handle
82 ; Output: Carry Set
83 ; AX has error code
84 ; Carry Reset
85 ; ES:DI has pointer to SF entry
86 ; Registers modified: If error, AX,ES, else ES:DI
87 ; NOTE:
88 ; This routine is called from $CREATE_PROCESS_DATA_BLOCK which is called
89 ; at DOSINIT time with SS NOT DOSGROUP
90 procedure SFFromHandle,NEAR
91 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
92 CALL pJFNFromHandle ; get jfn pointer
93 retc ; return if error
94 CMP BYTE PTR ES:[DI],-1 ; unused handle
95 JNZ GetSF ; nope, suck out SF
96 fmt TypAccess,LevSFN,<"$p: Illegal SFN $x:$x\n">,<ES,DI>
97 MOV AL,error_invalid_handle ; appropriate error
98 jump ReturnCarry ; signal it
99 GetSF:
100 SaveReg <BX> ; save handle
101 MOV BL,BYTE PTR ES:[DI] ; get SFN
102 XOR BH,BH ; ignore upper half
103 CALL SFFromSFN ; get real sf spot
104 RestoreReg <BX> ; restore
105 return ; say goodbye
106 EndProc SFFromHandle
107
108 BREAK <SFFromSFN - index into SF table for SFN>
109
110 ;
111 ; SFFromSFN - index into SF tables for SFN.
112 ;
113 ; Input: BX has SF index
114 ; Output: ES:DI points to SF entry
115 ; Registers modified: ES:DI, BX only
116 ; NOTE:
117 ; This routine is called from SFFromHandle which is called
118 ; at DOSINIT time with SS NOT DOSGROUP
119 procedure SFFromSFN,NEAR
120 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
121 LES DI,[SFT_Addr] ; get pointer to beginning of table
122 ScanLoop:
123 CMP BX,ES:[DI].SFCount ; is handle in this table?
124 JB GetOffset ; yes, go grab it
125 SUB BX,ES:[DI].SFCount
126 LES DI,ES:[DI].SFLink ; get next table segment
127 CMP DI,-1 ; end of tables?
128 JNZ ScanLoop ; no, try again
129 STC ; error...
130 JMP SHORT Restore ; go restore
131 GetOffset:
132 SaveReg <AX> ; save AX
133 MOV AX,SIZE SF_Entry ; put it in a nice place
134 MUL BL ; times size
135 ADD DI,AX ; offset by size
136 RestoreReg <AX> ; get world back
137 ADD DI,SFTable ; offset into structure
138 CLC ; no holes
139 Restore:
140 return ; bye!
141 EndProc SFFromSFN
142
143 BREAK <JFNFree - return a jfn pointer if one is free>
144
145 ;
146 ; JFNFree - scan through the JFN table and return a pointer to a free slot
147 ;
148 ; Input: None.
149 ; Output: Carry Set
150 ; AX has error code, BX,ES,DI garbage
151 ; Carry Reset
152 ; BX has new handle, ES:DI is pointer to JFN slot
153 ; Registers modified: As above only.
154 procedure JFNFree,NEAR
155 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
156 XOR BX,BX ; try starting low
157 JFNScan:
158 CALL pJFNFromHandle ; get the appropriate handle
159 JC JFNNone ; no more handles
160 CMP BYTE PTR ES:[DI],-1 ; free?
161 JZ JFNFound ; yes, carry is clear
162 INC BX ; no, next handle
163 JMP JFNScan ; and try again
164 JFNNone:
165 MOV AL,error_too_many_open_files
166 JFNFound:
167 return ; bye
168 EndProc JFNFree
169
170 BREAK <SFNFree - find a free SFN>
171
172 ;
173 ; SFNFree - scan through the sf table looking for free entries
174 ; Inputs: none
175 ; Outputs: Carry Set - AX has error code, BX destroyed
176 ; Carry Clear - BX has SFN
177 ; ES:DI - pointer to SFT
178 ; SFT_ref_count is set to 1
179 ; Registers modified: none
180
181 Procedure SFNFree,NEAR
182 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
183 XOR BX,BX ; start at beginning
184 SFNFreeLoop:
185 SaveReg <BX> ; Next call zaps BX
186 CALL SFFromSFN ; get the potential handle
187 RestoreReg <BX>
188 JNC SFNCheck ; no carry, check to see if its free
189 MOV AL,error_too_many_open_files ; appropriate error
190 JMP SFNDone
191 SFNCheck:
192 CMP ES:[DI.sf_Ref_Count],0 ; free?
193 IF NOT DEBUG
194 JZ SFNGot ; yep, got return him
195 ELSE
196 JNZ NoGot
197 JMP SFNGot
198 NoGot:
199 ENDIF
200 CMP ES:[DI.sf_ref_count],sf_busy
201 JNZ SFNNext ; not marked busy...
202 fmt TypAccess,LevSFN,<"$p: SFT $x:$x($x)is busy, owner $x:$x\n">,<ES,DI,BX,ES:[DI].sf_UID,ES:[DI].sf_pid>
203 SaveReg <BX>
204 MOV BX,User_ID
205 CMP ES:[DI.sf_UID],BX
206 JNZ SFNNextP
207 MOV BX,Proc_ID
208 CMP ES:[DI.sf_PID],BX
209 JZ SFNGotP
210 SFNNextP:
211 fmt TypAccess,LevSFN,<"$p: SFT unusable\n">
212 RestoreReg <BX>
213 SFNNext:
214 INC BX ; no, try next sf number
215 JMP SFNFreeLoop ; and go until it fails
216 SFNGot:
217 SaveReg <BX>
218 SFNGotP:
219 CLC ; no error
220 fmt TypAccess,LevSFN,<"$p: SFT $x:$x($x) marked busy\n">,<ES,DI,BX>
221 MOV ES:[DI.sf_ref_count],sf_busy ; make sure that this is allocated
222 MOV BX,User_ID
223 MOV ES:[DI.sf_UID],BX
224 MOV BX,Proc_ID
225 MOV ES:[DI.sf_PID],BX
226 RestoreReg <BX>
227 SFNDone:
228 return ; bye
229 EndProc SFNFree
230
231 CODE ENDS
232 END