diff options
Diffstat (limited to 'v4.0/src/DOS/UTIL.ASM')
| -rw-r--r-- | v4.0/src/DOS/UTIL.ASM | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/v4.0/src/DOS/UTIL.ASM b/v4.0/src/DOS/UTIL.ASM new file mode 100644 index 0000000..3c9c516 --- /dev/null +++ b/v4.0/src/DOS/UTIL.ASM | |||
| @@ -0,0 +1,232 @@ | |||
| 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 | ||