diff options
Diffstat (limited to '')
| -rw-r--r-- | v4.0/src/DOS/MACRO.ASM | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/v4.0/src/DOS/MACRO.ASM b/v4.0/src/DOS/MACRO.ASM new file mode 100644 index 0000000..dea0771 --- /dev/null +++ b/v4.0/src/DOS/MACRO.ASM | |||
| @@ -0,0 +1,445 @@ | |||
| 1 | ; SCCSID = @(#)macro.asm 1.2 85/07/11 | ||
| 2 | TITLE MACRO - Pathname and macro related internal routines | ||
| 3 | NAME MACRO | ||
| 4 | ; | ||
| 5 | ; $AssignOper written | ||
| 6 | ; FIND_DPB written | ||
| 7 | ; InitCDS written | ||
| 8 | ; $UserOper written | ||
| 9 | ; GetVisDrv written | ||
| 10 | ; GetThisDrv written | ||
| 11 | ; GetCDSFromDrv written | ||
| 12 | ; | ||
| 13 | ; Revision history: | ||
| 14 | ; | ||
| 15 | ; Created: MZ 4 April 1983 | ||
| 16 | ; MZ 18 April 1983 Make TransFCB handle extended FCBs | ||
| 17 | ; AR 2 June 1983 Define/Delete macro for NET redir. | ||
| 18 | ; MZ 3 Nov 83 Fix InitCDS to reset length to 2 | ||
| 19 | ; MZ 4 Nov 83 Fix NetAssign to use STRLEN only | ||
| 20 | ; MZ 18 Nov 83 Rewrite string processing for subtree | ||
| 21 | ; aliasing. | ||
| 22 | ; | ||
| 23 | ; MSDOS performs several types of name translation. First, we maintain for | ||
| 24 | ; each valid drive letter the text of the current directory on that drive. | ||
| 25 | ; For invalid drive letters, there is no current directory so we pretend to | ||
| 26 | ; be at the root. A current directory is either the raw local directory | ||
| 27 | ; (consisting of drive:\path) or a local network directory (consisting of | ||
| 28 | ; \\machine\path. There is a limit on the point to which a .. is allowed. | ||
| 29 | ; | ||
| 30 | ; Given a path, MSDOS will transform this into a real from-the-root path | ||
| 31 | ; without . or .. entries. Any component that is > 8.3 is truncated to | ||
| 32 | ; this and all * are expanded into ?'s. | ||
| 33 | ; | ||
| 34 | ; The second part of name translation involves subtree aliasing. A list of | ||
| 35 | ; subtree pairs is maintained by the external utility SUBST. The results of | ||
| 36 | ; the previous 'canonicalization' are then examined to see if any of the | ||
| 37 | ; subtree pairs is a prefix of the user path. If so, then this prefix is | ||
| 38 | ; replaced with the other subtree in the pair. | ||
| 39 | ; | ||
| 40 | ; A third part involves mapping this "real" path into a "physical" path. A | ||
| 41 | ; list of drive/subtree pairs are maintained by the external utility JOIN. | ||
| 42 | ; The output of the previous translation is examined to see if any of the | ||
| 43 | ; subtrees in this list are a prefix of the string. If so, then the prefix | ||
| 44 | ; is replaced by the appropriate drive letter. In this manner, we can | ||
| 45 | ; 'mount' one device under another. | ||
| 46 | ; | ||
| 47 | ; The final form of name translation involves the mapping of a user's | ||
| 48 | ; logical drive number into the internal physical drive. This is | ||
| 49 | ; accomplished by converting the drive number into letter:CON, performing | ||
| 50 | ; the above translation and then converting the character back into a drive | ||
| 51 | ; number. | ||
| 52 | ; | ||
| 53 | ; curdir_list STRUC | ||
| 54 | ; curdir_text DB DIRSTRLEN DUP (?) ; text of assignment and curdir | ||
| 55 | ; curdir_flags DW ? ; various flags | ||
| 56 | ; curdir_devptr DD ? ; local pointer to DPB or net device | ||
| 57 | ; curdir_ID DW ? ; cluster of current dir (net ID) | ||
| 58 | ; DW ? | ||
| 59 | ; curdir_end DW ? ; end of assignment | ||
| 60 | ; curdir_list ENDS | ||
| 61 | ; curdir_netID EQU DWORD PTR curdir_ID | ||
| 62 | ; ;Flag word masks | ||
| 63 | ; curdir_isnet EQU 1000000000000000B | ||
| 64 | ; curdir_inuse EQU 0100000000000000B | ||
| 65 | ; | ||
| 66 | ; There are two main entry points: TransPath and TransFCB. TransPath will | ||
| 67 | ; take a path and form the real text of the pathname with all . and .. | ||
| 68 | ; removed. TransFCB will translate an FCB into a path and then invoke | ||
| 69 | ; TransPath. | ||
| 70 | ; | ||
| 71 | ; Implementation note: CURDIR_End field points to the point in the text | ||
| 72 | ; string where the user may back up to via .. It is the location of a | ||
| 73 | ; separator character. For the root, it points at the leading /. For net | ||
| 74 | ; assignments it points at the end (nul) of the initial assignment: | ||
| 75 | ; A:/ \\foo\bar \\foo\bar\blech\bozo | ||
| 76 | ; ^ ^ ^ | ||
| 77 | ; A: -> d: /path/ path/ text | ||
| 78 | ; | ||
| 79 | ; A000 version 4.00 Jan. 1988 | ||
| 80 | |||
| 81 | .xlist | ||
| 82 | ; | ||
| 83 | ; get the appropriate segment definitions | ||
| 84 | ; | ||
| 85 | include dosseg.asm | ||
| 86 | |||
| 87 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 88 | ASSUME SS:DOSGroup,CS:DOSGroup | ||
| 89 | |||
| 90 | .xcref | ||
| 91 | INCLUDE DOSSYM.INC | ||
| 92 | INCLUDE DEVSYM.INC | ||
| 93 | .cref | ||
| 94 | .list | ||
| 95 | .sall | ||
| 96 | |||
| 97 | Installed = TRUE | ||
| 98 | |||
| 99 | I_need ThisCDS,DWORD ; pointer to CDS used | ||
| 100 | I_need CDSAddr,DWORD ; pointer to CDS table | ||
| 101 | I_need CDSCount,BYTE ; number of CDS entries | ||
| 102 | I_need CurDrv,BYTE ; current macro assignment (old | ||
| 103 | ; current drive) | ||
| 104 | I_need NUMIO,BYTE ; Number of physical drives | ||
| 105 | I_need fSharing,BYTE ; TRUE => no redirection allowed | ||
| 106 | I_need DummyCDS,80h ; buffer for dummy cds | ||
| 107 | I_need DIFFNAM,BYTE ; flag for MyName being set | ||
| 108 | I_need MYNAME,16 ; machine name | ||
| 109 | I_need MYNUM,WORD ; machine number | ||
| 110 | I_need DPBHEAD,DWORD ; beginning of DPB chain | ||
| 111 | I_need EXTERR_LOCUS,BYTE ; Extended Error Locus | ||
| 112 | I_need DrvErr,BYTE ; drive error | ||
| 113 | |||
| 114 | BREAK <$AssignOper -- Set up a Macro> | ||
| 115 | |||
| 116 | ; Inputs: | ||
| 117 | ; AL = 00 get assign mode (ReturnMode) | ||
| 118 | ; AL = 01 set assign mode (SetMode) | ||
| 119 | ; AL = 02 get attach list entry (GetAsgList) | ||
| 120 | ; AL = 03 Define Macro (attch start) | ||
| 121 | ; BL = Macro type | ||
| 122 | ; = 0 alias | ||
| 123 | ; = 1 file/device | ||
| 124 | ; = 2 drive | ||
| 125 | ; = 3 Char device -> network | ||
| 126 | ; = 4 File device -> network | ||
| 127 | ; DS:SI -> ASCIZ source name | ||
| 128 | ; ES:DI -> ASCIZ destination name | ||
| 129 | ; AL = 04 Cancel Macro | ||
| 130 | ; DS:SI -> ASCIZ source name | ||
| 131 | ; AL = 05 Modified get attach list entry | ||
| 132 | ; AL = 06 Get ifsfunc item | ||
| 133 | ; AL = 07 set in_use of a drive's CDS | ||
| 134 | ; DL = drive number, 0=default 0=A,, | ||
| 135 | ; AL = 08 reset in_use of a drive's CDS | ||
| 136 | ; DL = drive number, 0=A, 1=B,,, | ||
| 137 | ; Function: | ||
| 138 | ; Do macro stuff | ||
| 139 | ; Returns: | ||
| 140 | ; Std Xenix style error return | ||
| 141 | |||
| 142 | procedure $AssignOper,NEAR | ||
| 143 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 144 | |||
| 145 | CMP AL,7 ; set in_use ? ;AN000; | ||
| 146 | JNZ chk08 ; no ;AN000; | ||
| 147 | srinuse: ;AN000; | ||
| 148 | PUSH AX ; save al ;AN000; | ||
| 149 | MOV AL,DL ; AL= drive id ;AN000; | ||
| 150 | CALL GetCDSFromDrv ; ds:si -> cds ;AN000; | ||
| 151 | POP AX ; ;AN000; | ||
| 152 | JC baddrv ; bad drive ;AN000; | ||
| 153 | CMP WORD PTR [SI.curdir_devptr],0 ; dpb ptr =0 ? ;AN000; | ||
| 154 | JZ baddrv ; no ;AN000; | ||
| 155 | CMP AL,7 ; set ? ;AN000; | ||
| 156 | JNZ resetdrv ; no ;AN000; | ||
| 157 | OR [SI.curdir_flags],curdir_inuse ; set in_use ;AN000; | ||
| 158 | JMP SHORT okdone ; ;AN000; | ||
| 159 | resetdrv: ;AN000; | ||
| 160 | AND [SI.curdir_flags],NOT curdir_inuse ; reset in_use ;AN000; | ||
| 161 | JMP SHORT okdone ; ;AN000; | ||
| 162 | baddrv: ;AN000; | ||
| 163 | MOV AX,error_invalid_drive ; error ;AN000; | ||
| 164 | JMP SHORT ASS_ERR ; ;AN000; | ||
| 165 | chk08: ;AN000; | ||
| 166 | CMP AL,8 ; reset inuse ? ;AN000; | ||
| 167 | JZ srinuse ; yes ;AN000; | ||
| 168 | |||
| 169 | IF NOT INSTALLED | ||
| 170 | transfer NET_ASSOPER | ||
| 171 | ELSE | ||
| 172 | PUSH AX | ||
| 173 | MOV AX,(multnet SHL 8) OR 30 | ||
| 174 | INT 2FH | ||
| 175 | POP BX ; Don't zap error code in AX | ||
| 176 | JC ASS_ERR | ||
| 177 | okdone: | ||
| 178 | transfer SYS_RET_OK | ||
| 179 | |||
| 180 | ASS_ERR: | ||
| 181 | transfer SYS_RET_ERR | ||
| 182 | ENDIF | ||
| 183 | |||
| 184 | EndProc $AssignOper | ||
| 185 | |||
| 186 | Break <FIND_DPB - Find a DPB from a drive number> | ||
| 187 | |||
| 188 | ; Inputs: AL has drive number A = 0 | ||
| 189 | ; Outputs: Carry Set | ||
| 190 | ; No DPB for this drive number | ||
| 191 | ; Carry Clear | ||
| 192 | ; DS:SI points to DPB for drive | ||
| 193 | ; registers modified: DS,SI | ||
| 194 | Procedure FIND_DPB,NEAR | ||
| 195 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 196 | LDS SI,[DPBHEAD] | ||
| 197 | DPB_LOOP: | ||
| 198 | CMP SI,-1 | ||
| 199 | JZ NO_DPB | ||
| 200 | CMP AL,[SI.dpb_drive] | ||
| 201 | retz ; Carry clear | ||
| 202 | LDS SI,[SI.dpb_next_dpb] | ||
| 203 | JMP DPB_LOOP | ||
| 204 | |||
| 205 | NO_DPB: | ||
| 206 | STC | ||
| 207 | return | ||
| 208 | EndProc FIND_DPB | ||
| 209 | |||
| 210 | Break <InitCDS - set up an empty CDS> | ||
| 211 | |||
| 212 | ; Inputs: ThisCDS points to CDS | ||
| 213 | ; AL has uppercase drive letter | ||
| 214 | ; Outputs: ThisCDS is now empty | ||
| 215 | ; ES:DI point to CDS | ||
| 216 | ; Carry set if no DPB associated with drive | ||
| 217 | ; registers modified: AH,ES,DI | ||
| 218 | Procedure InitCDS,NEAR | ||
| 219 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 220 | MOV AH,':' | ||
| 221 | PUSH AX | ||
| 222 | SUB AL,"A"-1 ; A = 1 | ||
| 223 | CMP [NUMIO],AL | ||
| 224 | POP AX | ||
| 225 | LES DI,[THISCDS] | ||
| 226 | MOV ES:[DI.curdir_flags],0 ; "free" CDS | ||
| 227 | JB RET_OK ; Drive does not map a physical drive | ||
| 228 | MOV WORD PTR ES:[DI.curdir_text],AX | ||
| 229 | PUSH AX | ||
| 230 | MOV AX,"\" | ||
| 231 | MOV WORD PTR ES:[DI.curdir_text+2],AX ; NUL terminate | ||
| 232 | POP AX | ||
| 233 | OR ES:[DI.curdir_flags],curdir_inuse | ||
| 234 | MOV ES:[DI.curdir_END],2 ; MZ 3 Nov 83 | ||
| 235 | MOV ES:[DI.curdir_ID],0 | ||
| 236 | MOV ES:[DI.curdir_ID+2],0 | ||
| 237 | PUSH AX | ||
| 238 | PUSH DS | ||
| 239 | PUSH SI | ||
| 240 | SUB AL,"A" ; A = 0 | ||
| 241 | invoke FIND_DPB | ||
| 242 | JC PRET ; OOOOPPPPPSSSS!!!! | ||
| 243 | MOV WORD PTR ES:[DI.curdir_devptr],SI | ||
| 244 | MOV WORD PTR ES:[DI.curdir_devptr+2],DS | ||
| 245 | PRET: | ||
| 246 | POP SI | ||
| 247 | POP DS | ||
| 248 | POP AX | ||
| 249 | RET_OK: return | ||
| 250 | EndProc InitCDS | ||
| 251 | |||
| 252 | Break <$UserOper - get/set current user ID (for net)> | ||
| 253 | |||
| 254 | ; | ||
| 255 | ; $UserOper - retrieve or initiate a user id string. MSDOS will only | ||
| 256 | ; maintain this string and do no verifications. | ||
| 257 | ; | ||
| 258 | ; Inputs: AL has function type (0-get 1-set 2-printer-set 3-printer-get | ||
| 259 | ; 4-printer-set-flags,5-printer-get-flags) | ||
| 260 | ; DS:DX is user string pointer (calls 1,2) | ||
| 261 | ; ES:DI is user buffer (call 3) | ||
| 262 | ; BX is assign index (calls 2,3,4,5) | ||
| 263 | ; CX is user number (call 1) | ||
| 264 | ; DX is flag word (call 4) | ||
| 265 | ; Outputs: If AL = 0 then the current user string is written to DS:DX | ||
| 266 | ; and user CX is set to the user number | ||
| 267 | ; If AL = 3 then CX bytes have been put at input ES:DI | ||
| 268 | ; If AL = 5 then DX is flag word | ||
| 269 | |||
| 270 | Procedure $UserOper,NEAR | ||
| 271 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 272 | PUSH AX | ||
| 273 | SUB AL,1 ; quick dispatch on 0,1 | ||
| 274 | POP AX | ||
| 275 | JB UserGet ; return to user the string | ||
| 276 | JZ UserSet ; set the current user | ||
| 277 | CMP AL,5 ; test for 2,3,4 or 5 | ||
| 278 | JBE UserPrint ; yep | ||
| 279 | MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus | ||
| 280 | error error_Invalid_Function ; not 0,1,2,3 | ||
| 281 | |||
| 282 | UserGet: | ||
| 283 | ; Transfer MYNAME to DS:DX | ||
| 284 | ; Set Return CX to MYNUM | ||
| 285 | PUSH DS ; switch registers | ||
| 286 | POP ES | ||
| 287 | MOV DI,DX ; destination | ||
| 288 | MOV CX,[MYNUM] ; Get number | ||
| 289 | invoke get_user_stack | ||
| 290 | MOV [SI.User_CX],CX ; Set number return | ||
| 291 | Context DS ; point to DOSGroup | ||
| 292 | ASSUME DS:DOSGROUP | ||
| 293 | MOV SI,OFFSET DOSGroup:MyName ; point source to user string | ||
| 294 | UserMove: | ||
| 295 | ASSUME DS:NOTHING | ||
| 296 | MOV CX,15 | ||
| 297 | REP MOVSB ; blam. | ||
| 298 | XOR AX,AX ; 16th byte is 0 | ||
| 299 | STOSB | ||
| 300 | UserBye: | ||
| 301 | transfer sys_ret_ok ; no errors here | ||
| 302 | |||
| 303 | UserSet: | ||
| 304 | ASSUME DS:NOTHING | ||
| 305 | ; Transfer DS:DX to MYNAME | ||
| 306 | ; CX to MYNUM | ||
| 307 | MOV [MYNUM],CX | ||
| 308 | MOV SI,DX ; user space has source | ||
| 309 | Context ES | ||
| 310 | MOV DI,OFFSET DOSGroup:MyName ; point dest to user string | ||
| 311 | INC [DiffNam] ; signal change | ||
| 312 | JMP UserMove | ||
| 313 | |||
| 314 | UserPrint: | ||
| 315 | ASSUME ES:NOTHING | ||
| 316 | IF NOT Installed | ||
| 317 | transfer PRINTER_GETSET_STRING | ||
| 318 | ELSE | ||
| 319 | PUSH AX | ||
| 320 | MOV AX,(multNET SHL 8) OR 31 | ||
| 321 | INT 2FH | ||
| 322 | POP DX ; Clean stack | ||
| 323 | JNC OKPA | ||
| 324 | transfer SYS_RET_ERR | ||
| 325 | |||
| 326 | OKPA: | ||
| 327 | transfer SYS_RET_OK | ||
| 328 | ENDIF | ||
| 329 | |||
| 330 | EndProc $UserOper | ||
| 331 | |||
| 332 | Break <GetVisDrv - return visible drive> | ||
| 333 | |||
| 334 | ; | ||
| 335 | ; GetVisDrv - correctly map non-spliced inuse drives | ||
| 336 | ; | ||
| 337 | ; Inputs: AL has drive identifier (0=default) | ||
| 338 | ; Outputs: Carry Set - invalid drive/macro | ||
| 339 | ; Carry Clear - AL has physical drive (0=A) | ||
| 340 | ; ThisCDS points to CDS | ||
| 341 | ; Registers modified: AL | ||
| 342 | |||
| 343 | Procedure GetVisDrv,NEAR | ||
| 344 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 345 | CALL GetThisDrv ; get inuse drive | ||
| 346 | retc | ||
| 347 | SaveReg <DS,SI> | ||
| 348 | LDS SI,ThisCDS | ||
| 349 | TEST [SI].curdir_flags,curdir_splice | ||
| 350 | RestoreReg <SI,DS> | ||
| 351 | retz ; if not spliced, return OK | ||
| 352 | MOV [DrvErr],error_invalid_drive ;IFS. ;AN000; | ||
| 353 | STC ; signal error | ||
| 354 | return | ||
| 355 | EndProc GetVisDrv | ||
| 356 | |||
| 357 | Break <Getthisdrv - map a drive designator (0=def, 1=A...)> | ||
| 358 | |||
| 359 | ; | ||
| 360 | ; GetThisDrv - look through a set of macros and return the current drive and | ||
| 361 | ; macro pointer | ||
| 362 | ; | ||
| 363 | ; Inputs: AL has drive identifier (1=A, 0=default) | ||
| 364 | ; Outputs: | ||
| 365 | ; Carry Set - invalid drive/macro | ||
| 366 | ; Carry Clear - AL has physical drive (0=A) | ||
| 367 | ; ThisCDS points to macro | ||
| 368 | ; Registers modified: AL | ||
| 369 | |||
| 370 | Procedure GetThisDrv,NEAR | ||
| 371 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 372 | OR AL,AL ; are we using default drive? | ||
| 373 | JNZ GetMap ; no, go get the CDS pointers | ||
| 374 | MOV AL,[CurDrv] ; get the current drive | ||
| 375 | INC AL ; Counteract next instruction | ||
| 376 | GetMap: | ||
| 377 | DEC AL ; 0 = A | ||
| 378 | SaveReg <DS,SI> ; save world | ||
| 379 | mov [EXTERR_LOCUS],errLOC_Disk | ||
| 380 | TEST fSharing,-1 ; Logical or Physical? | ||
| 381 | JZ Not_SRVC ; Logical | ||
| 382 | SaveReg <AX,ES,DI> | ||
| 383 | MOV WORD PTR ThisCDS,OFFSET DOSGroup:DummyCDS | ||
| 384 | MOV WORD PTR ThisCDS+2,CS ; ThisCDS = &DummyCDS; | ||
| 385 | ADD AL,'A' | ||
| 386 | CALL InitCDS ; InitCDS(c); | ||
| 387 | TEST ES:[DI.curdir_flags],curdir_inuse ; Clears carry | ||
| 388 | RestoreReg <DI,ES,AX> | ||
| 389 | JZ GetBerr ; Not a physical drive. | ||
| 390 | JMP SHORT GetBye ; carry clear | ||
| 391 | |||
| 392 | Not_SRVC: | ||
| 393 | invoke GetCDSFromDrv | ||
| 394 | JC GetBerr2 ; Unassigned CDS -> return error already set | ||
| 395 | TEST [SI.curdir_flags],curdir_inuse ; Clears Carry | ||
| 396 | JNZ GetBye ; carry clear | ||
| 397 | GetBerr: | ||
| 398 | MOV AL,error_not_DOS_disk ;AN000;IFS. Formatted IFS drive | ||
| 399 | CMP WORD PTR [SI.curdir_devptr],0 ;AN000;IFS. dpb ptr =0 ? | ||
| 400 | JNZ notfat ;AN000;IFS. no | ||
| 401 | GetBerr2: | ||
| 402 | MOV AL,error_invalid_drive ;AN000;;IFS. invalid FAT drive | ||
| 403 | notfat: ;AN000; | ||
| 404 | MOV [DrvErr],AL ;AN000;;IFS. save this for IOCTL | ||
| 405 | mov [EXTERR_LOCUS],errLOC_UNK | ||
| 406 | STC | ||
| 407 | GetBye: RestoreReg <SI,DS> ; restore world | ||
| 408 | return | ||
| 409 | EndProc GetThisDrv | ||
| 410 | |||
| 411 | Break <GetCDSFromDrv - convert a drive number to a CDS pointer> | ||
| 412 | |||
| 413 | ; | ||
| 414 | ; GetCDSFromDrv - given a physical drive number, convert it to a CDS | ||
| 415 | ; pointer, returning an error if the drive number is greater than the | ||
| 416 | ; number of CDS's | ||
| 417 | ; | ||
| 418 | ; Inputs: AL is physical unit # A=0... | ||
| 419 | ; Outputs: Carry Set if Bad Drive | ||
| 420 | ; Carry Clear | ||
| 421 | ; DS:SI -> CDS | ||
| 422 | ; [THISCDS] = DS:SI | ||
| 423 | ; Registers modified: DS,SI | ||
| 424 | |||
| 425 | Procedure GetCDSFromDrv,NEAR | ||
| 426 | ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup | ||
| 427 | CMP AL,[CDSCount] ; is this a valid designator | ||
| 428 | JB GetCDS ; yes, go get the macro | ||
| 429 | STC ; signal error | ||
| 430 | return ; bye | ||
| 431 | GetCDS: | ||
| 432 | SaveReg <BX,AX> | ||
| 433 | LDS SI,[CDSAddr] ; get pointer to table | ||
| 434 | MOV BL,SIZE CurDir_list ; size in convenient spot | ||
| 435 | MUL BL ; get net offset | ||
| 436 | ADD SI,AX ; convert to true pointer | ||
| 437 | MOV WORD PTR [ThisCDS],SI ; store convenient offset | ||
| 438 | MOV WORD PTR [ThisCDS+2],DS ; store convenient segment | ||
| 439 | RestoreReg <AX,BX> | ||
| 440 | CLC ; no error | ||
| 441 | return ; bye! | ||
| 442 | EndProc GetCDSFromDrv | ||
| 443 | |||
| 444 | CODE ends | ||
| 445 | END | ||