     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                                  [list -]
    81          ******************       warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi]
    14                              <4> [list -]
    14                              <3> [list -]
     3                              <2> 
     4                              <2> addsection DOSSTART, align=16 PUBLIC class=DOSSTART
     5                              <2> ; (no prior section) ; DOSSTART		ENDS
     6                              <2> 
     7                              <2> addsection DOSSTARTJUMP, align=1 PUBLIC class=START
     8                              <2> ; (no prior section) ; DOSSTARTJUMP		ENDS
     9                              <2> 
    10                              <2> addsection CONSTANTS, align=2 PUBLIC class=CONST
    11                              <2> ; (no prior section) ; CONSTANTS	ENDS
    12                              <2> 
    13                              <2> addsection DATA, align=2 PUBLIC class=DATA
    14                              <2> ; (no prior section) ; DATA		ENDS
    15                              <2> 
    16                              <2> addsection TABLE, align=2 PUBLIC class=TABLE
    17                              <2> ; (no prior section) ; TABLE		ENDS
    18                              <2> 
    19                              <2> addsection DOSDATATABLE, align=2 PUBLIC class=DOSDATACODE
    20                              <2> ; (no prior section) ; DOSDATATABLE		ENDS
    21                              <2> 
    22                              <2> addsection DOSDATACODE, align=1 PUBLIC class=DOSDATACODE
    23                              <2> ; (no prior section) ; DOSDATACODE		ENDS
    24                              <2> 
    25                              <2> addsection DOSBIODATA, align=2 PUBLIC class=DOSBIODATA
    26                              <2> 
    27                              <2> addsection LAST, align=16 PUBLIC class=LAST
    28                              <2> ; (no prior section) ; LAST		ENDS
    29                              <2> 
    30                              <2> group DOSGROUP DOSSTART DOSSTARTJUMP CONSTANTS DATA TABLE DOSDATATABLE DOSDATACODE DOSBIODATA LAST
     8                              <1> 
     9                              <1> %include "dcodeseg.nas"
     1                              <2> 
     2                              <2> %ifndef DCODESEGNAS
     3                              <2> %assign DCODESEGNAS 1
     4                              <2> 
     5                              <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE
     6                              <2> ; (no prior section) ; DOSCODETABLE		ENDS
     7                              <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE
     8                              <2> ; (no prior section) ; DOSCODECODE		ENDS
     9                              <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE
    10                              <2> section BIOCODE	align=2 PUBLIC class=DOSCODE
    11                              <2> 
    12                              <2> %ifnidni DOSENTRYGROUP, DOSCODEGROUP
    13                              <2>  group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE
    14                              <2> %endif
    15                              <2> 
    16                              <2> %endif
    10                              <1> 
    11                              <1> section LAST
    12                              <1> ; (no prior section) ; LAST		ENDS
    86                                  
    87                                  [list +]
    88                                  section DOSCODECODE
    89                                  [list -]
    89          ******************       warning: out: ... for DOS Version 4.00 ... [-w+user]
    89          ******************       warning: out: BPB.INC... [-w+user]
    89          ******************       warning: out: ... CLONE version build switch on ... [-w+user]
    89          ******************       warning: out: DEVSYM.INC... [-w+user]
    96                                  ;.sall
    97                                  
    98                                  %iassign Installed TRUE
    99                                  
   100                                  	I_need	ThisCDS,DWORD		; pointer to CDS used
   101                                  	I_need	CDSAddr,DWORD		; pointer to CDS table
   102                                  	I_need	CDSCount,BYTE		; number of CDS entries
   103                                  	I_need	CurDrv,BYTE		; current macro assignment (old
   104                                  					; current drive)
   105                                  	I_need	NUMIO,BYTE		; Number of physical drives
   106                                  	I_need	fSharing,BYTE		; TRUE => no redirection allowed
   107                                  	I_need	DummyCDS,80h		; buffer for dummy cds
   108                                  	I_need	DIFFNAM,BYTE		; flag for MyName being set
   109                                  	I_need	MYNAME,16		; machine name
   110                                  	I_need	MYNUM,WORD		; machine number
   111                                  	I_need	DPBHEAD,DWORD		; beginning of DPB chain
   112                                  	I_need	EXTERR_LOCUS,BYTE	; Extended Error Locus
   113                                  	I_need	DrvErr,BYTE		; drive error
   114                                  
   115                                   assume nocheck, ss:DOSGROUP
   116                                  
   117                                  BREAK <$AssignOper -- Set up a Macro>
   118                                  
   119                                  ; Inputs:
   120                                  ;	AL = 00 get assign mode 		    (ReturnMode)
   121                                  ;	AL = 01 set assign mode 		    (SetMode)
   122                                  ;	AL = 02 get attach list entry		    (GetAsgList)
   123                                  ;	AL = 03 Define Macro (attch start)
   124                                  ;	    BL = Macro type
   125                                  ;	       = 0 alias
   126                                  ;	       = 1 file/device
   127                                  ;	       = 2 drive
   128                                  ;	       = 3 Char device -> network
   129                                  ;	       = 4 File device -> network
   130                                  ;	    DS:SI -> ASCIZ source name
   131                                  ;	    ES:DI -> ASCIZ destination name
   132                                  ;	AL = 04 Cancel Macro
   133                                  ;	    DS:SI -> ASCIZ source name
   134                                  ;	AL = 05 Modified get attach list entry
   135                                  ;	AL = 06 Get ifsfunc item
   136                                  ;	AL = 07 set in_use of a drive's CDS
   137                                  ;	     DL = drive number, 0=default  0=A,,
   138                                  ;	AL = 08 reset in_use of a drive's CDS
   139                                  ;	     DL = drive number, 0=A, 1=B,,,
   140                                  ; Function:
   141                                  ;	Do macro stuff
   142                                  ; Returns:
   143                                  ;	Std Xenix style error return
   144                                  
   145                                  	procedure   D_AssignOper,NEAR
   145          ******************       warning: proc D_AssignOper... [-w+user]
   146                                  ASSUME	DS:NOTHING,ES:NOTHING
   147                                  
   148 00000000 3C07                    	CMP	AL,7				      ; set in_use ?		;AN000;
   149 00000002 7526                    	JNZ	chk08				      ; no			;AN000;
   150                                  srinuse:									;AN000;
   151 00000004 50                      	PUSH	AX				      ; save al 		;AN000;
   152 00000005 88D0                    	MOV	AL,DL				      ; AL= drive id		;AN000;
   153 00000007 E86301                  	CALL	GetCDSFromDrv			      ; ds:si -> cds		;AN000;
   154 0000000A 58                      	POP	AX				      ; 			;AN000;
   155 0000000B 7218                    	JC	baddrv				      ; bad drive		;AN000;
   156 0000000D 837C4500                	CMP	WORD PTR [SI + curdir_devptr],0	      ; dpb ptr =0 ?		;AN000;
   157 00000011 7412                    	JZ	baddrv				      ;     no			;AN000;
   158 00000013 3C07                    	CMP	AL,7				      ; set ?			;AN000;
   159 00000015 7507                    	JNZ	resetdrv			      ; no			;AN000;
   160 00000017 814C430040              	OR	word [SI + curdir_flags],curdir_inuse	      ; set in_use		;AN000;
   161 0000001C EB19                    	JMP	SHORT okdone			      ; 			;AN000;
   162                                  resetdrv:									;AN000;
   163 0000001E 816443FFBF              	AND	word [SI + curdir_flags],~ curdir_inuse    ; reset in_use		;AN000;
   164 00000023 EB12                    	JMP	SHORT okdone			      ; 			;AN000;
   165                                  baddrv: 									;AN000;
   166 00000025 B80F00                  	MOV	AX,error_invalid_drive		      ; error			;AN000;
   167 00000028 EB10                    	JMP	SHORT ASS_ERR			      ; 			;AN000;
   168                                  chk08:										;AN000;
   169 0000002A 3C08                    	CMP	AL,8				      ; reset inuse ?		;AN000;
   170 0000002C 74D6                    	JZ	srinuse 			      ; yes			;AN000;
   171                                  
   172                                  	%IFN INSTALLED
   173                                  	transfer NET_ASSOPER
   174                                  	%ELSE
   175 0000002E 50                      	PUSH	AX
   176                                  multnet equ MultNET	; NASM port equate
   177 0000002F B81E11                  	MOV	AX,(multnet << 8) | 30
   178 00000032 CD2F                    	INT	2FH
   179 00000034 5B                      	POP	BX			; Don't zap error code in AX
   180 00000035 7203                    	JC	ASS_ERR
   181                                  okdone:
   182 00000037 E9(0000)                	transfer SYS_RET_OK
   183                                  
   184                                  ASS_ERR:
   185 0000003A E9(0000)                	transfer SYS_RET_ERR
   186                                  	%ENDIF
   187                                  
   188                                  EndProc D_AssignOper
   189                                  
   190                                  Break <FIND_DPB - Find a DPB from a drive number>
   191                                  
   192                                  ;   Inputs:	AL has drive number A = 0
   193                                  ;   Outputs:	Carry Set
   194                                  ;		    No DPB for this drive number
   195                                  ;		Carry Clear
   196                                  ;		    DS:SI points to DPB for drive
   197                                  ;   registers modified: DS,SI
   198                                  Procedure FIND_DPB,NEAR
   198          ******************       warning: proc FIND_DPB... [-w+user]
   199                                   ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGroup
   200 0000003D 36C536[0000]            	LDS	SI,[ss:DPBHEAD]
   201                                  DPB_LOOP:
   202 00000042 83FEFF                  	CMP	SI,-1
   203 00000045 740A                    	JZ	NO_DPB
   204 00000047 3A04                    	CMP	AL,[SI + dpb_drive]
   205 00000049 7501C3                  	retz				; Carry clear
   206 0000004C C57419                  	LDS	SI,[SI + dpb_next_dpb]
   207 0000004F EBF1                    	JMP	DPB_LOOP
   208                                  
   209                                  NO_DPB:
   210 00000051 F9                      	STC
   211 00000052 C3                      	return
   212                                  EndProc FIND_DPB
   213                                  
   214                                  Break <InitCDS - set up an empty CDS>
   215                                  
   216                                  ;   Inputs:	ThisCDS points to CDS
   217                                  ;		AL has uppercase drive letter
   218                                  ;   Outputs:	ThisCDS is now empty
   219                                  ;		ES:DI point to CDS
   220                                  ;		Carry set if no DPB associated with drive
   221                                  ;   registers modified: AH,ES,DI
   222                                  Procedure InitCDS,NEAR
   222          ******************       warning: proc InitCDS... [-w+user]
   223                                   ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGroup
   224 00000053 B43A                    	MOV	AH,':'
   225                                  ;	PUSH	AX
   226                                  ;	SUB	AL,"A"-1                ; A = 1
   227                                  ;	CMP	[ss:NUMIO],AL
   228                                  ;	POP	AX
   229                                  THISCDS equ ThisCDS	; NASM port label
   230 00000055 36C43E[0000]            	LES	DI,[ss:THISCDS]
   231 0000005A 26C745430000            	MOV	word [ES:DI + curdir_flags],0	; "free" CDS
   232                                  ;	JB	RET_OK			; Drive does not map a physical drive
   233 00000060 268905                  	MOV	WORD PTR [ES:DI + curdir_text],AX
   234 00000063 50                      	PUSH	AX
   235 00000064 B85C00                  	MOV	AX,"\"
   236 00000067 26894502                	MOV	WORD PTR [ES:DI + curdir_text+2],AX   ; NUL terminate
   237 0000006B 58                      	POP	AX
   238 0000006C 26814D430040            	OR	word [ES:DI + curdir_flags],curdir_inuse
   239                                  curdir_END equ curdir_end	; NASM port equate
   240 00000072 26C7454F0200            	MOV	word [ES:DI + curdir_END],2	; MZ 3 Nov 83
   241 00000078 26C745490000            	MOV	word [ES:DI + curdir_ID],0
   242 0000007E 26C7454B0000            	MOV	word [ES:DI + curdir_ID+2],0
   243 00000084 50                      	PUSH	AX
   244 00000085 1E                      	PUSH	DS
   245 00000086 56                      	PUSH	SI
   246 00000087 2C41                    	SUB	AL,"A"                  ; A = 0
   247 00000089 E8B1FF                  	invoke	FIND_DPB
   248 0000008C 7208                    	JC	PRET			; OOOOPPPPPSSSS!!!!
   249 0000008E 26897545                	MOV	WORD PTR [ES:DI + curdir_devptr],SI
   250 00000092 268C5D47                	MOV	WORD PTR [ES:DI + curdir_devptr+2],DS
   251                                  PRET:
   252 00000096 5E                      	POP	SI
   253 00000097 1F                      	POP	DS
   254                                   assume ds:nothing
   255 00000098 58                      	POP	AX
   256 00000099 C3                      RET_OK: return
   257                                  EndProc InitCDS
   258                                  
   259                                  Break <$UserOper - get/set current user ID (for net)>
   260                                  
   261                                  ;
   262                                  ;   $UserOper - retrieve or initiate a user id string.	MSDOS will only
   263                                  ;	maintain this string and do no verifications.
   264                                  ;
   265                                  ;   Inputs:	AL has function type (0-get 1-set 2-printer-set 3-printer-get
   266                                  ;				      4-printer-set-flags,5-printer-get-flags)
   267                                  ;		DS:DX is user string pointer (calls 1,2)
   268                                  ;		ES:DI is user buffer (call 3)
   269                                  ;		BX is assign index (calls 2,3,4,5)
   270                                  ;		CX is user number (call 1)
   271                                  ;		DX is flag word (call 4)
   272                                  ;   Outputs:	If AL = 0 then the current user string is written to DS:DX
   273                                  ;			and user CX is set to the user number
   274                                  ;		If AL = 3 then CX bytes have been put at input ES:DI
   275                                  ;		If AL = 5 then DX is flag word
   276                                  
   277                                  Procedure   D_UserOper,NEAR
   277          ******************       warning: proc D_UserOper... [-w+user]
   278                                   ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGroup
   279 0000009A 50                      	PUSH	AX
   280 0000009B 2C01                    	SUB	AL,1			; quick dispatch on 0,1
   281 0000009D 58                      	POP	AX
   282 0000009E 7210                    	JB	UserGet 		; return to user the string
   283 000000A0 742D                    	JZ	UserSet 		; set the current user
   284 000000A2 3C05                    	CMP	AL,5			; test for 2,3,4 or 5
   285 000000A4 763C                    	JBE	UserPrint		; yep
   286                                  errLoc_Unk equ errLOC_Unk	; NASM port equate
   287 000000A6 36C606[0000]01          	MOV	byte [ss:EXTERR_LOCUS],errLoc_Unk ; Extended Error Locus
   288                                  error_Invalid_Function equ error_invalid_function	; NASM port equate
   289 000000AC B001EB8A                	error	error_Invalid_Function	; not 0,1,2,3
   290                                  
   291                                  UserGet:
   292                                  ; Transfer MYNAME to DS:DX
   293                                  ; Set Return CX to MYNUM
   294 000000B0 1E                      	PUSH	DS			; switch registers
   295 000000B1 07                      	POP	ES
   296                                   assume es:nothing
   297 000000B2 89D7                    	MOV	DI,DX			; destination
   298 000000B4 368B0E[0000]            	MOV	CX,[ss:MYNUM]		; Get number
   299 000000B9 E8(0000)                	invoke	get_user_stack
   300                                  User_CX equ user_CX	; NASM port equate
   301 000000BC 894C04                  	MOV	[SI + User_CX],CX 	; Set number return
   302 000000BF 161F                    	Context DS			; point to DOSGroup
   303                                  ASSUME	DS:DOSGROUP
   304                                  DOSGroup equ DOSGROUP	; NASM port equate
   305                                  MyName equ MYNAME	; NASM port label
   306 000000C1 BE[0000]                	MOV	SI,OFFSET MyName wrt DOSGroup   ; point source to user string
   307                                  UserMove:
   308                                  ASSUME	DS:NOTHING
   309 000000C4 B90F00                  	MOV	CX,15
   310 000000C7 F3A4                    	REP	MOVSB			; blam.
   311 000000C9 31C0                    	XOR	AX,AX			; 16th byte is 0
   312 000000CB AA                      	STOSB
   313                                  UserBye:
   314 000000CC E9(0000)                	transfer    sys_ret_ok		; no errors here
   315                                  
   316                                  UserSet:
   317                                  ASSUME	DS:NOTHING
   318                                  ; Transfer DS:DX to MYNAME
   319                                  ; CX to MYNUM
   320 000000CF 36890E[0000]            	MOV	[ss:MYNUM],CX
   321 000000D4 89D6                    	MOV	SI,DX			; user space has source
   322 000000D6 1607                    	Context ES
   323 000000D8 BF[0000]                	MOV	DI,OFFSET MyName wrt DOSGroup   ; point dest to user string
   324                                  DiffNam equ DIFFNAM	; NASM port label
   325 000000DB 36FE06[0000]            	INC	byte [ss:DiffNam]		  ; signal change
   326 000000E0 EBE2                    	JMP	UserMove
   327                                  
   328                                  UserPrint:
   329                                  	ASSUME	ES:NOTHING
   330                                  %IFN Installed
   331                                  	transfer PRINTER_GETSET_STRING
   332                                  %ELSE
   333 000000E2 50                      	PUSH	AX
   334                                  multNET equ MultNET	; NASM port equate
   335 000000E3 B81F11                  	MOV	AX,(multNET << 8) | 31
   336 000000E6 CD2F                    	INT	2FH
   337 000000E8 5A                      	POP	DX			; Clean stack
   338 000000E9 7302                    	JNC	OKPA
   339 000000EB EBC1                    	transfer SYS_RET_ERR
   340                                  
   341                                  OKPA:
   342 000000ED EBDD                    	transfer SYS_RET_OK
   343                                  %ENDIF
   344                                  
   345                                  EndProc D_UserOper
   346                                  
   347                                  Break	<GetVisDrv - return visible drive>
   348                                  
   349                                  ;
   350                                  ;   GetVisDrv - correctly map non-spliced inuse drives
   351                                  ;
   352                                  ;   Inputs:	AL has drive identifier (0=default)
   353                                  ;   Outputs:	Carry Set - invalid drive/macro
   354                                  ;		Carry Clear - AL has physical drive (0=A)
   355                                  ;		    ThisCDS points to CDS
   356                                  ;   Registers modified: AL
   357                                  
   358                                  Procedure   GetVisDrv,NEAR
   358          ******************       warning: proc GetVisDrv... [-w+user]
   359                                   ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGroup
   360 000000EF E81A00                  	CALL	GetThisDrv		; get inuse drive
   361 000000F2 72A5                    	retc
   362 000000F4 1E56                    	SaveReg <DS,SI>
   363 000000F6 36C536[0000]            	LDS	SI,[ss:ThisCDS]
   364 000000FB F744430020              	TEST	word [SI + curdir_flags],curdir_splice
   365 00000100 5E1F                    	RestoreReg  <SI,DS>
   366 00000102 7495                    	retz				; if not spliced, return OK
   367 00000104 36C606[0000]0F          	MOV	byte [ss:DrvErr],error_invalid_drive ;IFS.				;AN000;
   368 0000010A F9                      	STC				; signal error
   369 0000010B C3                      	return
   370                                  EndProc GetVisDrv
   371                                  
   372                                  Break <Getthisdrv - map a drive designator (0=def, 1=A...)>
   373                                  
   374                                  ;
   375                                  ;   GetThisDrv - look through a set of macros and return the current drive and
   376                                  ;	macro pointer
   377                                  ;
   378                                  ;   Inputs:	AL has drive identifier (1=A, 0=default)
   379                                  ;   Outputs:
   380                                  ;		Carry Set - invalid drive/macro
   381                                  ;		Carry Clear - AL has physical drive (0=A)
   382                                  ;		   ThisCDS points to macro
   383                                  ;   Registers modified: AL
   384                                  
   385                                  Procedure   GetThisDrv,NEAR
   385          ******************       warning: proc GetThisDrv... [-w+user]
   386                                   ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGroup
   387 0000010C 08C0                    	OR	AL,AL			; are we using default drive?
   388 0000010E 7506                    	JNZ	GetMap			; no, go get the CDS pointers
   389 00000110 36A0[0000]              	MOV	AL,[ss:CurDrv]		; get the current drive
   390 00000114 FEC0                    	INC	AL			; Counteract next instruction
   391                                  GetMap:
   392 00000116 FEC8                    	DEC	AL			; 0 = A
   393 00000118 1E56                    	SaveReg <DS,SI> 		; save world
   394 0000011A 36C606[0000]02          	mov	byte [ss:EXTERR_LOCUS],errLOC_Disk
   395 00000120 36F606[0000]FF          	TEST	byte [ss:fSharing],-1		; Logical or Physical?
   396 00000126 7421                    	JZ	Not_SRVC		; Logical
   397 00000128 500657                  	SaveReg <AX,ES,DI>
   398 0000012B 36C706[0000][0000]      	MOV	WORD [ss:ThisCDS],OFFSET DummyCDS wrt DOSGroup
   399 00000132 368C16[0200]            	MOV	WORD PTR [ss:ThisCDS+2], ss	;	ThisCDS = &DummyCDS;
   400 00000137 0441                    	ADD	AL,'A'
   401 00000139 E817FF                  	CALL	InitCDS 		;	InitCDS(c);
   402 0000013C 26F745430040            	TEST	word [ES:DI + curdir_flags],curdir_inuse	; Clears carry
   403 00000142 5F0758                  	RestoreReg  <DI,ES,AX>
   404 00000145 740E                    	JZ	GetBerr 		; Not a physical drive.
   405 00000147 EB21                    	JMP	SHORT GetBye		; carry clear
   406                                  
   407                                  Not_SRVC:
   408 00000149 E82100                  	invoke	GetCDSFromDrv
   409 0000014C 720F                    	JC	GetBerr2		; Unassigned CDS -> return error already set
   410 0000014E F744430040              	TEST	word [SI + curdir_flags],curdir_inuse	; Clears Carry
   411 00000153 7515                    	JNZ	GetBye			; carry clear
   412                                  GetBerr:
   413 00000155 B01A                    	MOV	AL,error_not_DOS_disk	;AN000;IFS. Formatted IFS drive
   414 00000157 837C4500                	CMP	WORD PTR [SI + curdir_devptr],0	 ;AN000;IFS. dpb ptr =0 ?
   415 0000015B 7502                    	JNZ	notfat			;AN000;IFS. no
   416                                  GetBerr2:
   417 0000015D B00F                    	MOV	AL,error_invalid_drive	;AN000;;IFS. invalid FAT drive
   418                                  notfat: 				;AN000;
   419 0000015F 36A2[0000]              	MOV	[ss:DrvErr],AL		;AN000;;IFS. save this for IOCTL
   420                                  errLOC_UNK equ errLOC_Unk	; NASM port equate
   421 00000163 36C606[0000]01          	mov	byte [ss:EXTERR_LOCUS],errLOC_UNK
   422 00000169 F9                      	STC
   423 0000016A 5E1F                    GetBye: RestoreReg  <SI,DS>		; restore world
   424 0000016C C3                      	return
   425                                  EndProc GetThisDrv
   426                                  
   427                                  Break <GetCDSFromDrv - convert a drive number to a CDS pointer>
   428                                  
   429                                  ;
   430                                  ;   GetCDSFromDrv - given a physical drive number, convert it to a CDS
   431                                  ;	pointer, returning an error if the drive number is greater than the
   432                                  ;	number of CDS's
   433                                  ;
   434                                  ;   Inputs:	AL is physical unit # A=0...
   435                                  ;   Outputs:	Carry Set if Bad Drive
   436                                  ;		Carry Clear
   437                                  ;		    DS:SI -> CDS
   438                                  ;		    [THISCDS] = DS:SI
   439                                  ;   Registers modified: DS,SI
   440                                  
   441                                  Procedure   GetCDSFromDrv,NEAR
   441          ******************       warning: proc GetCDSFromDrv... [-w+user]
   442                                   ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGroup
   443 0000016D 363A06[0000]            	CMP	AL,[ss:CDSCount]		; is this a valid designator
   444 00000172 7202                    	JB	GetCDS			; yes, go get the macro
   445 00000174 F9                      	STC				; signal error
   446 00000175 C3                      	return				; bye
   447                                  GetCDS:
   448 00000176 5350                    	SaveReg <BX,AX>
   449 00000178 36C536[0000]            	LDS	SI,[ss:CDSAddr]		; get pointer to table
   450                                  CurDir_list_struc_size equ curdir_list_struc_size	; NASM port equate
   451 0000017D B358                    	MOV	BL,CurDir_list_struc_size	; size in convenient spot
   452 0000017F F6E3                    	MUL	BL			; get net offset
   453 00000181 01C6                    	ADD	SI,AX			; convert to true pointer
   454 00000183 368936[0000]            	MOV	WORD PTR [ss:ThisCDS],SI	; store convenient offset
   455 00000188 368C1E[0200]            	MOV	WORD PTR [ss:ThisCDS+2],DS ; store convenient segment
   456 0000018D 585B                    	RestoreReg  <AX,BX>
   457 0000018F F8                      	CLC				; no error
   458 00000190 C3                      	return				; bye!
   459                                  EndProc GetCDSFromDrv
   460                                  
   461                                  END
