summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/MACRO.ASM
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--v4.0/src/DOS/MACRO.ASM445
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
2TITLE MACRO - Pathname and macro related internal routines
3NAME 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;
85include dosseg.asm
86
87CODE SEGMENT BYTE PUBLIC 'CODE'
88 ASSUME SS:DOSGroup,CS:DOSGroup
89
90.xcref
91INCLUDE DOSSYM.INC
92INCLUDE DEVSYM.INC
93.cref
94.list
95.sall
96
97Installed = 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
114BREAK <$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
143ASSUME DS:NOTHING,ES:NOTHING
144
145 CMP AL,7 ; set in_use ? ;AN000;
146 JNZ chk08 ; no ;AN000;
147srinuse: ;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;
159resetdrv: ;AN000;
160 AND [SI.curdir_flags],NOT curdir_inuse ; reset in_use ;AN000;
161 JMP SHORT okdone ; ;AN000;
162baddrv: ;AN000;
163 MOV AX,error_invalid_drive ; error ;AN000;
164 JMP SHORT ASS_ERR ; ;AN000;
165chk08: ;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
177okdone:
178 transfer SYS_RET_OK
179
180ASS_ERR:
181 transfer SYS_RET_ERR
182 ENDIF
183
184EndProc $AssignOper
185
186Break <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
194Procedure FIND_DPB,NEAR
195 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
196 LDS SI,[DPBHEAD]
197DPB_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
205NO_DPB:
206 STC
207 return
208EndProc FIND_DPB
209
210Break <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
218Procedure 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
245PRET:
246 POP SI
247 POP DS
248 POP AX
249RET_OK: return
250EndProc InitCDS
251
252Break <$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
270Procedure $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
282UserGet:
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
292ASSUME DS:DOSGROUP
293 MOV SI,OFFSET DOSGroup:MyName ; point source to user string
294UserMove:
295ASSUME DS:NOTHING
296 MOV CX,15
297 REP MOVSB ; blam.
298 XOR AX,AX ; 16th byte is 0
299 STOSB
300UserBye:
301 transfer sys_ret_ok ; no errors here
302
303UserSet:
304ASSUME 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
314UserPrint:
315 ASSUME ES:NOTHING
316IF NOT Installed
317 transfer PRINTER_GETSET_STRING
318ELSE
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
326OKPA:
327 transfer SYS_RET_OK
328ENDIF
329
330EndProc $UserOper
331
332Break <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
343Procedure 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
355EndProc GetVisDrv
356
357Break <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
370Procedure 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
376GetMap:
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
392Not_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
397GetBerr:
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
401GetBerr2:
402 MOV AL,error_invalid_drive ;AN000;;IFS. invalid FAT drive
403notfat: ;AN000;
404 MOV [DrvErr],AL ;AN000;;IFS. save this for IOCTL
405 mov [EXTERR_LOCUS],errLOC_UNK
406 STC
407GetBye: RestoreReg <SI,DS> ; restore world
408 return
409EndProc GetThisDrv
410
411Break <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
425Procedure 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
431GetCDS:
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!
442EndProc GetCDSFromDrv
443
444CODE ends
445END