summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/ASSIGN/ASSGMAIN.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/ASSIGN/ASSGMAIN.ASM')
-rw-r--r--v4.0/src/CMD/ASSIGN/ASSGMAIN.ASM1771
1 files changed, 1771 insertions, 0 deletions
diff --git a/v4.0/src/CMD/ASSIGN/ASSGMAIN.ASM b/v4.0/src/CMD/ASSIGN/ASSGMAIN.ASM
new file mode 100644
index 0000000..5561366
--- /dev/null
+++ b/v4.0/src/CMD/ASSIGN/ASSGMAIN.ASM
@@ -0,0 +1,1771 @@
1
2
3 PAGE 90,132 ;
4 TITLE ASSGMAIN.SAL - ASSIGN MAIN PROGRAM
5;****************** START OF SPECIFICATIONS *****************************
6; MODULE NAME: ASSGMAIN.SAL
7;
8; DESCRIPTIVE NAME: Reassigns drive specifications.
9;
10;FUNCTION: This program reassigns the specified drives to a new drive
11; identifier.
12;
13; ENTRY POINT: ENTRY_POINT
14;
15; INPUT:
16;
17; ASSIGN [DRIVE] [DELIMITER] [DRIVE] [SW]
18; where DRIVE = optional colon
19; where DELIMITER = +;=TAB LF SPACE
20; where SW = /STATUS or /STA
21;
22; where:
23; /STATUS - reports back to the user
24; the currently changed
25; drive assignments and the
26; new assignment drive
27;
28; Note:
29; If a drive value has not been
30; ASSIGN will report back nothing.
31;
32; UTILITY FUNCTION:
33; Instructs DOS to route disk I/O
34; for one drive into disk I/O to another
35; drive. eg.
36; a=c sets a: to c:
37;
38; EXIT-NORMAL: Assigned drives or reassigned drives
39;
40; EXIT-ERROR: Any one of the possible parse errors
41;
42; INTERNAL REFERENCES:
43; ROUTINES: SYSPARSE:near (INCLUDEd in PARSE.SAL)
44; SYSLOADMSG
45; SYSDISPMSG
46;
47;
48; EXTERNAL REFERENCES:
49; ROUTINES: none
50;
51; NOTES:
52; This module should be processed with the SALUT preprocessor
53; with the re-alignment not requested, as:
54;
55; SALUT ASSPARM,NUL;
56;
57; To assemble these modules, the sequential
58; ordering of segments may be used.
59;
60; For LINK instructions, refer to the PROLOG of the main module,
61; ASSIGN.SAL
62;
63; REVISION HISTORY: AN000 - Version 4.00: PARSER, System Message Handler,
64; Status report
65;
66; COPYRIGHT: "Microsoft DOS ASSIGN Utility"
67; "Version 4.00 (C)Copyright 1988 Microsoft"
68; "Licensed Material - Program Property of Microsoft"
69;
70;
71; AN000 -> New Code
72;
73; AN001 -> PTM P3954 Release the environmental vector and close
74; all handles.
75;
76; AN002 -> PTM P3918 Parse error messages must conform to spec.
77; All parse error messages should display
78; the offending parameters.
79;
80;
81;****************** END OF SPECIFICATIONS *****************************
82
83;*********************************************
84;* *
85;* UTILITY NAME: ASSIGN.COM *
86;* *
87;* SOURCE FILE NAME: ASSIGN.SAL *
88;* *
89;* STATUS: ASSIGN utility *
90;* PC-DOS Version 3.40 *
91;* *
92;* SYNTAX (Command line) *
93;* *
94;* ASSIGN [DRIVE] [DELIMITER] [DRIVE] [SW] *
95;* where DRIVE = optional colon *
96;* where DELIMITER = +;=TAB LF SPACE *
97;* where SW = /STATUS or /STA *
98;* *
99;* where: *
100;* /STATUS - reports back to the user *
101;* the currently changed *
102;* drive assignments and the *
103;* new assignment drive *
104;* Note: *
105;* If a drive value has not been *
106;* ASSIGN will report back nothing. *
107;* *
108;* UTILITY FUNCTION: *
109;* Instructs DOS to route disk I/O *
110;* for one drive into disk I/O to another *
111;* drive. eg. *
112;* a=c sets a: to c: *
113;*********************************************
114
115page
116DEBUG = 0
117
118.xlist
119 INCLUDE SYSMSG.INC ;AN000;
120 INCLUDE SYSVAR.INC
121 INCLUDE CURDIR.INC
122 INCLUDE MULT.INC
123 INCLUDE PDB.INC
124
125MSG_UTILNAME <ASSIGN>
126
127.list
128
129; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
130 BREAK <MACRO DEFINITIONS>
131BREAK MACRO subtitle
132.XLIST
133 SUBTTL subtitle
134.LIST
135 PAGE
136 ENDM
137.xcref break
138; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
139CallOperRange macro low,high,routine ;;NS-macro to call subroutines
140?call = low ;;NS-in the given call range
141 ;;NS-starting call value = low #
142rept (high-low)+1 ;;NS-calculate the entry point
143 CallOper ?call,routine ;;NS-into the table then execute
144 ?call = ?call + 1 ;;NS-increment call value to next
145endm
146 endm
147; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
148CallOper macro call,routine ;;NS-macro that calls a single
149 ;;NS-subroutine that is used in
150 ;;NS-the above macro loop CallOperange
151 ORG (SysTab-ASSIGN_BASE)+(call*2) ;;NS-Calculate entry point into
152 DW OFFSET CODE:routine ;;NS-code where SysTab is the
153 ENDM ;;NS-entry point to the tables
154 ;;NS-ASSIGN_BASE is at 0:0000
155 ;;NS-the (call*2) is calculated
156 ;;NS-to take into account two bytes
157 ;;NS-and final OFFSET statement points
158 ;;NS-code to be executed at the given
159 ;;NS-label
160; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
161; $SALUT (0,36,40,48)
162MyINT21 macro ;;NS-macro used to save
163 pushf ;;NS-the flags to maintain
164 call system ;;NS-DOS environment
165 endm
166; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
167SaveReg MACRO reglist ;; push those registers
168IRP reg,<reglist>
169 ?stackdepth = ?stackdepth + 1
170 PUSH reg
171ENDM
172ENDM
173.xcref SaveReg
174; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
175RestoreReg MACRO reglist ;; pop those registers
176IRP reg,<reglist>
177 ?stackdepth = ?stackdepth - 1
178 POP reg
179ENDM
180ENDM
181.xcref RestoreReg
182
183; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
184; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
185; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
186page
187 BREAK <DOS FUNCTIONS, AND OTHER EQUATES>
188; $SALUT (0,23,28,41)
189; DOS FUNCTIONS USED
190; (DEC) (HEX)
191NO_ERROR equ 0 ;return code zero from the parser
192 ;********** CNS *****************
193;Std_Con_String_Output EQU 9 ; 9
194PSP_Env equ 2ch ;Environmental vector segment in PSP ;an001; dms;
195Get_PSP equ 62h ; DOS function call to get PSP address ;an001; dms;
196Handle_Close equ 3eh ;close handle ;an001; dms;
197
198Set_Default_Drive EQU 14 ; E
199Get_Default_Drive EQU 25 ; 19
200Set_Interrupt_Vector EQU 37 ; 25
201Get_Version EQU 48 ; 30
202Keep_Process EQU 49 ; 31
203Get_Interrupt_Vector EQU 53 ; 35
204Get_Drive_Freespace EQU 54 ; 36
205Exit EQU 76 ; 4C
206Dealloc EQU 73 ; 49
207Get_In_Vars EQU 82 ; 52
208Get_Set_Media_ID equ 69h ; 69h
209
210IOCTL_READ_BLOCK EQU 4404H ;READ FROM BLOCK DEVICE
211IOCTL_WRITE_BLOCK EQU 4405H ;WRITE TO A BLOCK DEVICE
212IOCTL_BLOCK_CHANGE EQU 4408H ;BLOCK DEVICE CHANGEABLE
213IOCTL_BLOCK_REMOTE EQU 4409H ;BLOCK DEVICE REMOTE
214
215; VECTORS REFERENCED
216PGM_TERM EQU 20H
217DOS_CALL EQU 21H
218CTL_BREAK EQU 23H
219CRIT_ERR EQU 24H
220ABS_DISK_READ EQU 25H
221ABS_DISK_WRITE EQU 26H
222stay equ 27h ;NS stay interrupt value
223int_IBM EQU 2AH ;critical section maintenance
224MULTIPLEXOR EQU 2FH ;MULTIPLEXOR INTERRUPT VECTOR NUMBER
225
226; CONSTANTS USED ACROSS THE MULTIPLEXOR INTERFACE
227MPLEX_ID EQU 06H ;ID OF ASSIGN IN MPLEX CHAIN
228MPLEX_R_U_THERE EQU 0 ;MPLEX FUNCTION: ARE YOU THERE?
229MPLEX_GET_SEG EQU 1 ;MPLEX FUNCTION: GET SEG OF INSTALLED ASSIGN
230MPLEX_INSTALLED EQU 0FFH ;"I AM HERE" RETURN VALUE
231
232; OTHER EQUATES
233cr equ 0dh ;CARRIAGE RETURN
234LF EQU 0AH ;LINE FEED
235f_Interrupt EQU 0000001000000000B ;NS - mask used for interrupt
236 ;NS value
237 BREAK <ENTRY POINT FOR CODE, EXTRNS>
238; $SALUT (4,15,21,41)
239
240code segment para public ;NS code all in one segment
241assume cs:code
242 ; one segment
243
244page
245
246ASSIGN_BASE: ;NS- starting point of loaded file
247 org 100h
248
249ENTRY_POINT:
250 jmp INITIALIZATION ;JUMP TO INITIALIZATION
251; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
252 BREAK <TABLES AND LOCAL WORKAREAS>
253drives db 1,2,3,4,5,6,7,8,9 ;drive values used in comparison
254 db 10,11,12,13,14,15,16,17,18,19 ;against default or found drive
255 db 20,21,22,23,24,25,26
256default_drive db ?
257drive_save db ? ; saved drive byte
258drive_address dw ? ; location (from DS) of drive byte
259drive_save2 db ? ; second saved drive byte
260;******************************************************************************
261;******************************************************************************
262
263system dd ?
264int25_vec dd ? ;NS - Hooks for the Int 2f handler preparation
265int26_vec dd ? ;NS - Hooks for the Int 2f handler preparation
266int2F_vec dd ? ;NS - Area to be hooked in and remain resident
267user_ret dd ? ; ???????????????????????????????????????
268saveIntF dw ? ; ???????????????????????????????????????
269I21_Func db ? ; Save area for INT21 function requested -->RW
270
271
272; $SALUT (4,9,23,41)
273 EVEN
274SysTab label word ;NS-Beginning of the call,subroutine table
275 CallOper 00h,DoReset
276 CallOperRange 01h,0Ch,DoNothing ; done ????????????????????????
277 CallOper 0Dh,DoReset ; done ????????????????????????
278 CallOper 0Eh,DoSetDefault
279 CallOperRange 0Fh,17h,DoFCB ; done ????????????????????????
280 CallOper 18h,DoReset ; done ????????????????????????
281 CallOper 19h,DoGetDefault ; ????????????????????????
282 CallOperRange 1Ah,1Bh,DoReset ; done ????????????????????????
283 CallOper 1Ch,DoDL ; done ????????????????????????
284 CallOperRange 1Dh,20h,DoReset ; done ????????????????????????
285 CallOperRange 21h,24h,DoFCB ; done ????????????????????????
286 CallOperRange 25h,26h,DoReset ; done ????????????????????????
287 CallOperRange 27h,28h,DoFCB ; done ????????????????????????
288 CallOperRange 29h,31h,DoReset ; done ????????????????????????
289 CallOper 32h,DoDL ; done ????????????????????????
290 CallOperRange 33h,35h,DoReset ; done ????????????????????????
291 CallOper 36h,DoDL ; done ????????????????????????
292 CallOperRange 37h,38h,DoReset ; done ????????????????????????
293 CallOperRange 39h,3Dh,DoAscii ; done ????????????????????????
294 CallOperRange 3Eh,40h,DoReset ; done ????????????????????????
295 CallOper 41h,DoAscii ; done ????????????????????????
296 CallOper 42h,DoReset ; done ????????????????????????
297 CallOper 43h,DoAscii ; done ????????????????????????
298 CallOper 44h,DoIOCTL ; done ????????????????????????
299 CallOperRange 45h,46h,DoReset ; done ????????????????????????
300 CallOper 47h,DoDL ; done ????????????????????????
301 CallOperRange 48h,4Ah,DoReset ; done ????????????????????????
302 CallOper 4Bh,DoExec ; done ????????????????????????
303 CallOperRange 4Ch,4Dh,DoReset ; done ????????????????????????
304 CallOper 4Eh,DoAscii ; done ????????????????????????
305 CallOperRange 4Fh,55h,DoReset ; done ????????????????????????
306 CallOper 56h,DoRename ; done ????????????????????????
307 CallOperRange 57h,59h,DoReset ; done ????????????????????????
308 CallOperRange 5Ah,5Bh,DoAscii ; done ????????????????????????
309 CallOperRange 5Ch,5Fh,DoReset ; done ????????????????????????
310 CallOper 60h,DoTranslate ; done ????????????????????????
311 CallOperRange 61h,63h,DoReset ; done ????????????????????????
312 CallOperRange 64h,69h,DoSetGetMedia ;done ????????????????????????
313 CallOperRange 6ah,6bh,DoNothing ;done ????????????????????????
314 CallOper 6ch,DoAscii_DS_SI ;done ?????????????????????????
315 ; ????????????????????????
316page
317; $SALUT (4,5,11,36)
318MAXCLL EQU 6CH ; High bound of table
319
320 org (systab-ASSIGN_BASE) + (2 * (MAXCLL + 1)) ;NS - Beginning of code starts at
321 ;NS - Beginning of table + 128 bytes
322 BREAK <ASSIGN INTERRUPT HANDLER>
323ASSIGN_HANDLER:
324 mov SaveIntf,f_interrupt ;NS- Move in the mask into a saved area
325 SaveReg <AX,BX> ;NS- ??????????????????????????????????
326 cmp ah,MAXCLL ; Do a high bound check on the call
327 ; so we don't index past the end of
328 ja DoNothing ; the table on a bogus call
329
330 mov al,ah ;NS- Call must be in the 0 - 63h range
331 cbw ;NS- zero out the high byte now
332 ;NS- AX has 0 & call number
333 shl ax,1 ;NS- Double the value in AX
334 mov bx,ax ;NS- Move the value into BX to
335 jmp systab[bx] ;NS- access the call number & subroutine
336 ;NS- bx bytes into the tbl
337;***********************************************************************************
338
339EnterAssign: ;NS- make sure system intact by doing
340 call LeaveAllAssign ;NS- error recovery check
341
342 push ax ;NS- before making code
343 mov ax,8000h + critAssign ;NS- non- reentrant if unable
344 INT INT_IBM ;(2AH) NS- to screen out successfully
345
346 POP AX ;NS- LeaveAllAssign will be executed
347 RET ;return NS- and the critical section will be reset
348;************************************************************************************
349LeaveAssign: ;NS- restore re-entrancy to
350 push ax ;NS- the code after & only
351 mov ax,8100h + critAssign ;NS- after this call has been
352 INT INT_IBM ;(2AH) NS- made or the error recovery
353
354 POP AX ;NS- call has been made
355 RET ;return NS-
356
357;************************************************************************************
358LeaveAllAssign: ;NS- Error recovery call
359 push ax ;NS- to restore the Assigns
360 mov ax,8908h ;NS- critical section
361 int INT_IBM ;(2AH) NS- if ASSIGN has encountered
362
363 pop ax ;NS- a problem on entrance or departure
364 RET ;return NS-
365;************************************************************************************
366;
367; Reset the exclusion flag ;NS- Reset to Assign
368; ;NS- critical section state
369DoReset: ;NS-
370 call LeaveAllAssign ;NS-
371 ;NS-
372;****************************************************************************************
373;
374; The system call needed no special processing. Go do it directly.
375;
376DoNothing: ;NS-System registers and flags still
377 RestoreReg <bx,ax> ;NS-intact it has not been clobbered
378 jmp system ;NS-by ASSIGN code
379
380page
381;************************************************************************************
382;
383; Munge the drive byte in an FCB pointed to by DS:DX.
384; "MUNGE" ? (Webster will turn over in his gravy...)
385;
386DoFCB:
387 mov bx,dx ; indexable pointer
388 mov al,[bx] ; get drive
389 cmp al,0ffh ; extended fcb?
390 jnz DoMapDrive ; no
391
392 add bx,7 ; yes, advance past it
393 mov al,[bx] ; get read drive byte
394DoMapDrive:
395 or al,al ; default drive?
396; $IF Z ;YES
397 JNZ $$IF1
398 mov al,default_drive ; get default drive
399;
400; DS:BX points to the drive byte being munged. AL is the old value. Save
401; it away.
402;
403; $ENDIF ;AC000;
404$$IF1:
405 ;SaveFCB:
406 call EnterAssign ; NS-Enter Assign's critical section
407
408 mov drive_save,al ; NS-save the drive assignment
409 call mapdrv1 ; NS-now let's map it to the
410
411 mov [bx],al ; NS-numeric drive associated in
412 ; NS-in drive range 1 to 26
413;******************************************************************************
414; The FCB has been converted. Now let's POP off the user's info and do the
415; system call. Note that we are no longer reentrant!
416;
417 mov drive_address,bx ; NS- location of drive value
418 RestoreReg <BX,AX> ; get back original registers
419 pop word ptr user_ret ; restore his IP
420 pop word ptr user_ret+2 ; restore his CS
421 call GotoCLI ; NS- Clear out old interrupts
422 ; NS- before an IRET is issued
423 ; NS- update the current
424 call system ; flags saved => this is a system call
425
426 pushf ; NS- re-adjust the stack
427 call RestInt ; NS- and setup the environment
428
429 SaveReg <ax,bx> ; NS- with drive and the drive address
430 mov bx,drive_address ; NS- before leaving the Assign critical
431 mov al,drive_save ; NS- section
432 mov [bx],al
433 RestoreReg <bx,ax>
434 push word ptr user_ret+2 ; push back user's cs
435 push word ptr user_ret ; push back user's ip
436 Call LeaveAssign
437
438 iret ; back to user
439
440page
441;************************************************************************************
442;
443; Munge the user's ASCIZ string at DS:DX.
444;
445DoAscii:
446 mov bx,dx ; point to area
447 cmp byte ptr [bx+1],':' ; drive letter present?
448 jnz DoNothing ; nope, ignore this
449;
450; There is a drive leter present. Grab it and convert it
451;
452 mov al,[bx] ; get drive letter
453 call EnterAssign ; NS- Re-enter ASSIGN crit section
454
455 mov drive_save,al ; remember previous contents
456 call maplet ; convert to real drive letter
457
458 mov [bx],al ; place in new drive letter
459 mov drive_address,bx
460 RestoreReg <BX,AX> ; get back original registers
461 pop word ptr user_ret ; restore his IP
462 pop word ptr user_ret+2 ; restore his CS
463 call GotoCLI ; clean up stack
464
465 call system ; flags saved => this is a system call
466
467 pushf ; save all drive info
468 call RestInt ; NS- clean up environment before
469
470 SaveReg <ax,bx> ; NS- returning to the user's environment
471 mov bx,drive_address ; NS- to ask on the next ASSIGN entrance
472 mov al,drive_save
473 mov [bx],al
474 RestoreReg <bx,ax>
475 push word ptr user_ret+2 ; push back user's cs
476 push word ptr user_ret ; push back user's ip
477 Call LeaveAssign ; NS- exit ASSIGN crit. section
478
479 iret ; back to user
480
481
482;************************************************************************************
483;
484; Munge the user's ASCIZ string at DS:SI.
485;
486DoAscii_DS_SI:
487 mov bx,si ; point to area
488 cmp byte ptr [bx+1],':' ; drive letter present?
489; $if ne ; drive letter not present
490 JE $$IF3
491 jmp DoNothing ; nope, ignore this
492; $endif ;
493$$IF3:
494;
495; There is a drive leter present. Grab it and convert it
496;
497 mov al,[bx] ; get drive letter
498 call EnterAssign ; NS- Re-enter ASSIGN crit section
499
500 mov drive_save,al ; remember previous contents
501 call maplet ; convert to real drive letter
502
503 mov [bx],al ; place in new drive letter
504 mov drive_address,bx
505 RestoreReg <BX,AX> ; get back original registers
506 pop word ptr user_ret ; restore his IP
507 pop word ptr user_ret+2 ; restore his CS
508 call GotoCLI ; clean up stack
509
510 call system ; flags saved => this is a system call
511
512 pushf ; save all drive info
513 call RestInt ; NS- clean up environment before
514
515 SaveReg <ax,bx> ; NS- returning to the user's environment
516 mov bx,drive_address ; NS- to ask on the next ASSIGN entrance
517 mov al,drive_save
518 mov [bx],al
519 RestoreReg <bx,ax>
520 push word ptr user_ret+2 ; push back user's cs
521 push word ptr user_ret ; push back user's ip
522 Call LeaveAssign ; NS- exit ASSIGN crit. section
523
524 iret ; back to user
525
526page
527;************************************************************************************
528
529;
530; DoDL - the drive to map is in DL.
531;
532DoDL:
533 or dl,dl ; NS- check for drive mapping
534; $IF Z ;AC000;;USE DEFAULT DRIVE
535 JNZ $$IF5
536
537DNJ1:
538 jmp DoNothing ; NS- default drive was requested
539 ; NS- thus no mapping needed
540; $ENDIF ;AC000;
541$$IF5:
542 mov al,dl ; NS- not default case so no need doctor
543 call EnterAssign ; NS- so enter ASSIGN crit. section again
544
545 mov drive_save,al ; preserve old drive
546 call mapdrv1
547
548 mov dl,al ; drive is mapped
549 RestoreReg <BX,AX> ; get back registers
550 mov I21_Func,ah ; Save requested function call -->RW
551 pop word ptr user_ret ; restore his IP
552 pop word ptr user_ret+2 ; restore his CS
553 call GotoCLI
554
555 call system ; flags saved => this is a system call
556
557 pushf ;
558 call RestInt
559
560 cmp I21_Func,GET_DRIVE_FREESPACE ;(36h) If call returns info in DX, -->RW
561 ; NS- DL in both cases Func 36
562 ; NS- Func 1Ch are both used for
563 ; NS- drive input we don't want to
564 ; NS- the old drives so they should not
565 ; restored as the old value - use ASSIGN's
566 je Dont_Restore_DL ;AC000;;THEN DO CHANGE IT
567
568 cmp I21_Func,1ch ; If call returns info in DX, -->RW
569 ;(NOTE 1CH IS NOT DEFINED IN SYSCALL.INC. EK)
570 je Dont_Restore_DL ;AC000;;THEN DO CHANGE IT
571
572 mov dl,drive_save ; restore his dl
573 ;DONT_RESTORE_DL:
574Dont_Restore_DL:
575
576 push word ptr user_ret+2 ; push back user's cs
577 push word ptr user_ret ; push back user's ip
578 Call LeaveAssign
579
580 iret ; back to user
581;************************************************************************************
582
583; Map the IOCTL drives in BX ; NS- this section handles
584 ; NS- INT21 calls to get drive info
585DoIOCTL:
586 RestoreReg <BX,AX>
587 SaveReg <AX,BX>
588 cmp ax,IOCTL_READ_BLOCK ;(4404h) IOCTL read string from block dev
589 jz DoMapBX ;AC000;
590 ; jz DoMapBX
591 cmp ax,IOCTL_WRITE_BLOCK ;(4405h) IOCTL write string from block dev
592 jz DoMapBX ;AC000;
593 ; jz DoMapBX
594 cmp ax,IOCTL_BLOCK_CHANGE ;(4408h) IOCTL is removable
595 jz DoMapBX ;AC000;
596 ; jz DoMapBX
597 cmp ax,IOCTL_BLOCK_REMOTE ;(4409h) IOCTL block dev redir (network)
598 jnz DNJ2 ;AC000;;NORMAL CALL
599 ;DoMapBX:
600DoMapBX:
601
602 or bx,bx ; NS- drive letter associated in BL
603 jz DNJ2
604
605 mov al,bl ; not the default case
606 call EnterAssign
607
608 mov drive_save,al ; remember drive
609 call mapdrv1 ; NS- time to map drive to new assoc.
610
611 mov bl,al ; drive is mapped
612 RestoreReg <AX,AX> ; get back registers (throw away BX)
613 pop word ptr user_ret ; restore his IP
614 pop word ptr user_ret+2 ; restore his CS
615 call GotoCLI
616
617 call system ; flags saved => this is a system call
618
619 pushf
620 call RestInt
621
622 mov bl,drive_save ; restore his dl
623 push word ptr user_ret+2 ; push back user's cs
624 push word ptr user_ret ; push back user's ip
625 Call LeaveAssign
626
627 iret ; back to user
628
629DNJ2:
630
631 jmp DoNothing
632
633DoSetGetMedia:
634 RestoreReg <BX,AX> ;an000; dms;restore regs
635 SaveReg <AX,BX> ;an000; dms;save regs
636 cmp ah,Get_Set_Media_ID ;an000; dms;trap on get/set media id
637; $if z ;an000; dms;found
638 JNZ $$IF7
639 or bl,bl ;an000; dms;drive letter entered
640; $if nz ;an000; dms;yes
641 JZ $$IF8
642 mov al,bl ; not the default case
643 call EnterAssign
644
645 mov drive_save,al ; remember drive
646 call mapdrv1 ; NS- time to map drive to new assoc.
647
648 mov bl,al ; drive is mapped
649 RestoreReg <AX,AX> ; get back registers (throw away BX)
650 pop word ptr user_ret ; restore his IP
651 pop word ptr user_ret+2 ; restore his CS
652 call GotoCLI
653
654 call system ; flags saved => this is a system call
655
656 pushf
657 call RestInt
658
659 mov bl,drive_save ; restore his dl
660 push word ptr user_ret+2 ; push back user's cs
661 push word ptr user_ret ; push back user's ip
662 Call LeaveAssign
663; $else ;an000; dms;not valid function 69h
664 JMP SHORT $$EN8
665$$IF8:
666 jmp DoNothing ;an000; dms;pass to interrupt
667; $endif ;an000; dms;
668$$EN8:
669; $else ;an000; dms;
670 JMP SHORT $$EN7
671$$IF7:
672 jmp DoNothing ;an000; dms;pass to interrupt
673; $endif ;an000; dms;
674$$EN7:
675
676 iret ; back to user
677page
678;************************************************************************************
679;
680; Map the drive letter and forget about it. EXEC never returns.
681;
682DoExec:
683 RestoreReg <BX,AX>
684 SaveReg <AX,BX>
685 or al,al
686; $IF Z ;AC000;;IS LOAD GO, NOT USE NORMAL STUFF
687 JNZ $$IF13
688
689 mov bx,dx ; point to area
690DoOnce:
691 cmp byte ptr [bx+1],':' ; drive letter present?
692; $IF Z ;AC000;;YES
693 JNZ $$IF14
694;
695; There is a drive leter present. Grab it and convert it
696;
697 mov al,[bx] ; get drive letter
698 call maplet ; convert to real drive letter
699
700 mov [bx],al ; place in new drive letter
701; $ENDIF ;AC000;
702$$IF14:
703DNJ3:
704 jmp DoNothing ; restore and go on!
705
706; $ENDIF
707$$IF13:
708 ;DAJ:
709 jmp DoAscii
710
711;************************************************************************************
712;
713; Map the drive letter at DS:SI. We need to un-map it at the end.
714;
715DoTranslate:
716 mov bx,SI ; point to area
717 cmp byte ptr [bx+1],':' ; drive letter present?
718 jnz DNJ3 ; nope, ignore this
719;
720; There is a drive leter present. Grab it and convert it
721;
722 mov al,[bx] ; get drive letter
723 call EnterAssign
724
725 mov drive_save,al ; remember previous contents
726 call maplet ; convert to real drive letter
727
728 mov [bx],al ; place in new drive letter
729 mov drive_address,bx
730 RestoreReg <BX,AX> ; get back original registers
731 pop word ptr user_ret ; restore his IP
732 pop word ptr user_ret+2 ; restore his CS
733 call GotoCLI
734
735 call system ; flags saved => this is a system call
736
737 pushf
738 call RestInt
739
740 SaveReg <ax,bx>
741 mov bx,drive_address
742 mov al,drive_save
743 mov [bx],al
744 RestoreReg <bx,ax>
745 push word ptr user_ret+2 ; push back user's cs
746 push word ptr user_ret ; push back user's ip
747 Call LeaveAssign
748
749 iret ; back to user
750
751page
752;************************************************************************************
753;
754; Munge the user's ASCIZ string at DS:DX and es:di
755;
756DoRename:
757 mov bx,dx ; point to area
758 mov ax,[bx]
759 call EnterAssign
760
761 mov drive_save,al
762 mov drive_address,bx
763 cmp ah,':' ; drive letter present?
764; $IF Z ;AC000;
765 JNZ $$IF17
766
767 call maplet ; convert to real drive letter
768
769 mov [bx],al ; place in new drive letter
770; $ENDIF ;AC000;
771$$IF17:
772 ;DoES:
773 mov ax,es:[di] ;NS- Get the 2nd drive from the command linepSOP
774 mov drive_save2,al ;NS- Save possible drive
775 cmp ah,':' ;NS- exclude if no colon present
776; $IF Z ;AC000;
777 JNZ $$IF19
778
779 call maplet ;NS- go convert letter to actual drive #
780
781 mov es:[di],al ;NS- new drive value
782; $ENDIF ;AC000;
783$$IF19:
784 ;DoIt:
785 RestoreReg <BX,AX> ; get back original registers
786 pop word ptr user_ret ; restore his IP
787 pop word ptr user_ret+2 ; restore his CS
788 call GotoCLI
789
790 call system ; flags saved => this is a system call
791
792 pushf
793 call RestInt
794
795 SaveReg <ax,bx>
796 mov al,drive_save2 ; NS- get the second drive update
797 mov es:[di],al ; NS- on the command line
798 mov bx,drive_address ;
799 mov al,drive_save ;
800 mov [bx],al ;
801 RestoreReg <bx,ax> ;
802 push word ptr user_ret+2 ; push back user's cs
803 push word ptr user_ret ; push back user's ip
804 Call LeaveAssign
805
806 iret ; back to user
807
808;************************************************************************************
809;
810; DoGetDefault - return our idea of the current drive...
811;
812DoGetDefault:
813 call Assign_Check
814
815; $IF Z ;AC000;
816 JNZ $$IF21
817 ;DNJ4:
818 jmp DoNothing
819
820; $ENDIF ;AC000;
821$$IF21:
822 RestoreReg <BX,AX>
823 mov al,default_drive
824 dec al
825 iret
826
827page
828;************************************************************************************
829;
830; DoSetDefault - try to set to the mapped current drive. If we can do it,
831; then OK, else oops!
832;
833DoSetDefault:
834 RestoreReg <BX,AX>
835 mov al,dl ; get new drive
836 inc al ; convert it to 1-based
837 call EnterAssign
838
839 mov drive_save,al ; remember what we're doing
840 call mapdrv1 ; convert drive
841
842 dec al ; convert back to 0-based
843 mov dl,al ; stick back in correct register
844 mov drive_save2,al ; remember more of what we're doing
845 MyInt21 ; try the set
846
847 push ax ; save return info from set
848 mov ah,Get_Default_Drive ;(29h)
849 MyInt21
850
851 mov dl,drive_save
852 dec dl ; Restore users original value
853 cmp al,drive_save2 ; Did the set work?
854; $IF Z ;AC000;;YES!
855 JNZ $$IF23
856
857 mov al,drive_save
858 mov default_drive,al ; Set ours too, it's valid!
859; $ENDIF ;AC000;
860$$IF23:
861 ;BadDrive:
862 pop ax ; Set return info
863 call LeaveAssign
864
865 iret
866
867;************************************************************************************
868;
869; Maintain the CLI state upon the next IRET. Flags for the IRET are on the
870; stack just under the return address. This means saving the current state
871; of the int flag and then turning off the saved version.
872;
873GotoCLI:
874 push ax
875 push bp
876 mov bp,sp
877; bp ax ret f
878 mov ax,[bp + 2 + 2 + 2]
879 and SaveIntf,ax ; save those interrupts
880 and word ptr [bp + 2 + 2 + 2],not f_interrupt
881 pop bp
882 pop ax
883 ret
884;
885;************************************************************************************
886; Restore he saved interrupt flag for the user. His flags are on the stack
887; just above the RET.
888;
889RestInt:
890 push ax
891 push bp
892 mov bp,sp
893 mov ax,SaveIntf
894; bp ax ret f
895 or [bp + 2 + 2 + 2],ax
896 pop bp
897 pop ax
898 ret
899
900;************************************************************************************
901mapdrv0: ;a = 0 , b = 1
902 inc al
903; $IF NZ ;AC000;
904 JZ $$IF25
905
906 call mapdrv1
907
908; $ENDIF ;AC000;
909$$IF25:
910 ;Wrap0:
911 dec al
912 ret
913
914;************************************************************************************
915mapdrv1:
916 cmp al,26
917; $IF NA ;AC000;
918 JA $$IF27
919
920 cmp al,0 ; check for default
921; $IF Z ;AC000;
922 JNZ $$IF28
923
924 mov al,default_drive
925 mov drive_save,al
926; $ENDIF ;AC000;
927$$IF28:
928
929 push bx ;a = 1, b = 2
930 push cx
931 mov ch,ah
932 cbw
933 mov bx,offset drives-1
934 add bx,ax
935 mov al,cs:[bx]
936 mov ah,ch
937 pop cx
938 pop bx
939; $ENDIF ;AC000;
940$$IF27:
941 ret
942
943;************************************************************************************
944maplet:
945 cmp al,'A'
946 jb LetDone
947
948 cmp al,'Z'
949 jbe DoMapLet
950
951 cmp al,'a'
952 jb LetDone
953
954 cmp al,'z'
955 ja LetDone
956
957DoMapLet:
958 or al,20h
959 sub al,"a"-1
960 call mapdrv1
961
962 add al,40h
963LetDone:
964 ret
965
966page
967;************************************************************************************
968int25:
969 call mapdrv0
970
971 jmp int25_vec
972
973int26:
974 call mapdrv0
975
976 jmp int26_vec
977
978int2F:
979 CMP AH,mplex_id ;(06h) is this our multiplex?
980; $IF NE ;AC000;;NO
981 JE $$IF31
982
983 jmp int2F_vec ; No, Chain to next guy
984
985; $ENDIF ;AC000;
986$$IF31:
987 ;MINE:
988 CMP AL,mplex_get_seg ;(01h)
989 ;0 AND 1 ARE THE ONLY ALLOWED FUNCTIONS
990; $IF NA ;AC000;;IF NOT SOME OTHER NUMBER,
991 JA $$IF33
992; $IF E ;AC000;;IF FUNCTION REQUEST IS 01
993 JNE $$IF34
994 ;RETURN THE SEGID IN ES
995 PUSH CS
996 POP ES ; Call 1 gets our segment in ES
997; $ENDIF ;AC000;
998$$IF34:
999 ;QUER:
1000 MOV AL,MPLEX_INSTALLED ;(0FFh) I AM here
1001; $ENDIF
1002$$IF33:
1003 ;RESERVED_RET:
1004 IRET
1005
1006;************************************************************************************
1007assign_check:
1008 push si
1009 push ax
1010 push cx
1011 xor ax,ax
1012 mov si,ax
1013 mov cx,26
1014; $SEARCH ;AC000;
1015$$DO37:
1016 ;scn:
1017 mov al,drives[si]
1018 INC SI
1019 cmp ax,si
1020; $EXITIF NZ,NUL ;AC000;
1021 JNZ $$SR37
1022
1023; $ENDLOOP LOOP ;AC000;
1024 LOOP $$DO37
1025
1026 xor ax,ax ; reset z flag
1027; $ENDSRCH ;AC000;
1028$$SR37:
1029 ;scndone:
1030 pop cx
1031 pop ax
1032 pop si
1033 ret
1034
1035prog_size = ($-ASSIGN_BASE+15)/16
1036
1037page
1038;************************************************************************************
1039; TRANSIENT CODE
1040;************************************************************************************
1041;*********************************************
1042;* *
1043;* Subroutine name: Initialization *
1044;* *
1045;* Purpose: Process the command line. *
1046;* If there are no errors update *
1047;* the drive table according to *
1048;* the drive assignments, terminate *
1049;* and stay resident. If status switch *
1050;* set and the drive values have been *
1051;* altered display drive is set to *
1052;* 2nd drive. *
1053;* *
1054;* Input: Command line (described in header) *
1055;* *
1056;* Output: Table will be updated and resident*
1057;* code will be hooked in. *
1058;* *
1059;* Normal Exit: Valid drives, sufficient *
1060;* memory. *
1061;* Error Conditions: *
1062;* Incorrect DOS Version *
1063;* Invalid Parameter *
1064;* Invalid switch *
1065;*Externals: *
1066;* PROCESS_PATH *
1067;* REPORT_STATUS *
1068;* EXIT_PROG *
1069;* *
1070;*********************************************
1071; *****************************************
1072; * INITIALIZATION *
1073; *****************************************
1074; * *
1075; * CALL SYSLOADMSG *
1076; * Do DOS Versinon Check *
1077; * CALL SYSDISPMSG *
1078; * IF <> X.X then *
1079; * Display message *
1080; * Message number 1 *
1081; * (001 - Incorrect DOS Version) *
1082; * exit *
1083; * .ENDIF *
1084; * Continue *
1085; * *
1086; * Establish address of the *
1087; * PDB environment *
1088; * (Process Data Block ) *
1089; * .IF NO SPACE free de-allocate (49)*
1090; * memory at the environment *
1091; * address *
1092; * .ENDIF *
1093; *****************************************
1094;*******************************************************************************
1095
1096
1097 BREAK <INITIALIZATION - NOT STAY RESIDENT>
1098
1099 EXTRN SYSPARSE:NEAR ;AN000;
1100
1101ODDX equ 01H ;AN000;
1102EVENX equ 00H ;AN000;
1103PAD_CHAR equ ' ' ;AN000;
1104SEMICOLON equ ';' ;AN000;
1105SPACE equ ' ' ;AN000;
1106EQUAL equ '=' ;AN000;
1107PLUS equ '+' ;AN000;
1108good_parse_finish equ 0ffffh ;an000;
1109;******************************************************************************
1110STATUS_ONLY db 0 ;AN000;
1111STRING_CTR db 0 ;AN000;
1112STATUS_FLAG db 0 ;AN000;
1113ERR_CODE db 0 ;AN000;
1114POS_FLAG db 'n' ;AN000;
1115PARMS_AVAIL db 'n' ;AN000;
1116PAR_RETC dw 0 ;AN000; used for the return code
1117DRV_X db 0 ;AN000; from the parser
1118save_dr_tbl_ptr dw ? ;an000;drive table pointer
1119curr_es_seg dw ?
1120Parm_Ptr1 dw ? ;an002;ptr to parse parm
1121Parm_Ptr2 dw ? ;an002;ptr to parse parm
1122
1123inv dd ?
1124STring dd ? ;AN000;string holder
1125
1126
1127INCLUDE ASSGPARM.INC ;AN000;
1128INCLUDE ASSGMSG.INC ;AN000;
1129
1130
1131assume cs:code, ds:code, ss:code, es:code
1132
1133INITIALIZATION:
1134
1135 push ax ;an000; save ax
1136 mov ax,ds ;an000; get the current ds
1137 mov SEG_1,ax ;an000; set sublist table
1138 mov SEG_2,ax ;an000; set sublist table
1139 pop ax ;an000; restore ax
1140
1141 call SYSLOADMSG ;AN000; ;does DOS version check
1142; $IF C ;AN000;
1143 JNC $$IF41
1144 ;remainder of info given
1145 call SYSDISPMSG ;AN000; ;by the msg retriever
1146 ;message and exit
1147
1148 call EXIT_PROG ;AC000; ;(4CH) Terminate function
1149
1150; $ENDIF
1151$$IF41:
1152
1153
1154page
1155;************************************* CNS ************************************
1156; *****************************************
1157; * INITIALIZATION *
1158; *****************************************
1159; * *
1160; * Make internal DOS function call (52h)*
1161; * to process the data block *
1162; * information after mem is available *
1163; ******************************************
1164;************************************* CNS ************************************
1165 ;OKDOS:
1166 mov ax,ds:[pdb_environ] ;get your Process Data Block Address
1167 or ax,ax ;check to see if space available
1168; $IF NZ ;AC000;
1169 JZ $$IF43
1170 ; jz nofree
1171 push es ; save code segment value
1172 mov es,ax ; de-allocate memory
1173 mov ah,dealloc ;(49H)
1174 int DOS_CALL
1175
1176 pop es ;restore code segment value
1177
1178; $ENDIF ;ACx00;
1179$$IF43:
1180 ;nofree:
1181
1182 push es ;an000; save es
1183 mov ah,Get_In_Vars ;(52H)
1184 int DOS_CALL
1185
1186 mov Word ptr inv,bx
1187 mov Word ptr inv+2,es
1188 pop es ;an000; restore es
1189
1190;******************************************************************************
1191;
1192; *****************************************
1193; * Establish addressability *
1194; * to command line parms (DS:SI) *
1195; * Establish addressability to PARM *
1196; * control block (ES:DI) *
1197; * *
1198; *****************************************
1199;*******************************************************************************
1200 ;parser es & ds now points at the command line
1201 cld ;clear the directional flag
1202 ;decrement mode - maintanis pointer without
1203 ;advancement
1204
1205 mov di,offset ASS_PARMS ;AC000; ;set index to the location of your PARAMETER
1206 ;PARSER control block
1207 mov si,81h ;AC000; ;set index to the beginning of the commandline
1208 ;at 81h to the first 128 bytes
1209page
1210;******************************************************************************
1211;* PROCESS PATH
1212;******************************************************************************
1213;*********************************************
1214;* *
1215;* Subroutine : Process_path *
1216;* Function : Process command line. *
1217;* Repeat searching for drive *
1218;* spec. If valid update *
1219;* drive table. *
1220;* *
1221;* Normal exit: End of line *
1222;* Parse error *
1223;* *
1224;* Abort exit: Invalid drive *
1225;* *
1226;*********************************************
1227; *****************************************
1228; * *
1229; * WHILE PAR_RETC eq NO_ERROR (0) *
1230; * CALL SYSPARSE *
1231; * Case: *
1232; * .IF (POSITIONAL) *
1233; * Result is positional & Ctr even *
1234; * INC CTR *
1235; * CHECK_STRING *
1236; * .IF the string is valid *
1237; * valid drive *
1238; * calculate table drv posit. *
1239; * based on the ascii value *
1240; * .ELSE *
1241; * *
1242; * PARSE ERROR *
1243; * .ENDIF *
1244; * Result is positional & CTR odd *
1245; * save the ascii_value *
1246; * Check the String *
1247; * .IF the string is valid *
1248; * valid drive *
1249; * update the drive table *
1250; * .ELSE *
1251; * *
1252; * PARSE ERROR *
1253; * .ENDIF *
1254; * .ENDIF *
1255; * INC CTR *
1256; *****************************************
1257
1258;******************************************************************************
1259 xor cx,cx ;an000; set cx to 0 for parse
1260 xor dx,dx ;an000; set dx to 0 for parse
1261
1262 mov Parm_Ptr1,si ;an002; dms;ptr to 1st. parm
1263 mov Parm_Ptr2,si ;an002; dms;ptr to 1st. parm
1264 call SYSPARSE ;AN000; dms;priming parse
1265 mov par_retc,ax ;AN000; dms;set flag
1266
1267; $DO
1268$$DO45:
1269 CMP ax,no_error ;AN000;Is compare the return
1270; $LEAVE NE ;AN000;code 0 no error keep
1271 JNE $$EN45
1272 ;AN000;parsing
1273 call CHK_PARSER ;AN000;
1274
1275 mov Parm_Ptr2,si ;an002; dms;ptr to 1st. parm
1276 call SYSPARSE ;AN000;go parse the command line
1277 mov par_retc,ax ;AN000; dms;set flag
1278 ;AN000;restore the parm return code
1279
1280; $ENDDO ;AN000;
1281 JMP SHORT $$DO45
1282$$EN45:
1283
1284 cmp ax,good_parse_finish ;an000; dms;see if a parse error
1285; $if ne ;an000; dms;if a parse error
1286 JE $$IF48
1287 push ax ;an002; dms save ax
1288 mov ax,Parm_Ptr2 ;an002; dms;get original parm ptr
1289 mov Parm_Ptr1,ax ;an002; dms;place in variable
1290 pop ax ;an002; dms;restore ax
1291 call PARSE_ERR ;an000; dms;display error & exit
1292; $endif ;an000; dms;
1293$$IF48:
1294
1295 cmp PARMS_AVAIL,'y' ;AN000;
1296; $IF E ;AN000; If there are parms available
1297 JNE $$IF50
1298 cmp ax,0 ;AN000; see if the return code was no error
1299; $IF G ;AN000; if greater than 0
1300 JNG $$IF51
1301 mov ax,parse10
1302 call PARSE_ERR ;AN000; you got a parser error
1303 ;AN000; so report & exit
1304; $ENDIF ;AN000; you also get an error
1305$$IF51:
1306
1307 xor ax,ax ;AN000;
1308 mov al,String_ctr ;AN000;
1309 mov bx,0002h
1310 div bl ;AN000;
1311
1312 cmp ah,EVENX
1313; $IF NE ;AN000; if the drives did not pair off
1314 JE $$IF53
1315 mov ax,parse10
1316 call PARSE_ERR
1317; $ENDIF ;AN000;
1318$$IF53:
1319
1320 cmp POS_FLAG,'n' ;AN000;has a drive been specified
1321; $IF E,AND ;AN000;and has a switch also been
1322 JNE $$IF55
1323 cmp STATUS_FLAG,1 ;AN000;specified if so hook in code
1324; $IF E ;AN000;and then report status
1325 JNE $$IF55
1326 mov STATUS_ONLY,1 ;AN000;set flag specifing user input full
1327; $ENDIF ;AN000;command line
1328$$IF55:
1329 ;AN000; hook in the code
1330; $ENDIF ;AN000;
1331$$IF50:
1332
1333page
1334
1335 cmp STATUS_ONLY,0 ;AN000;
1336; $IF E ;AN000;
1337 JNE $$IF58
1338
1339 call Get_Vectors ;get current vectors ;an001; dms;
1340 call Set_Vectors ;set new vectors ;an001; dms;
1341
1342; $ELSE ;AN000;END of HOOK-IN
1343 JMP SHORT $$EN58
1344$$IF58:
1345
1346 call REPORT_STATUS ;AN000;
1347 call EXIT_PROG ;AN000;
1348
1349; $ENDIF
1350$$EN58:
1351page
1352;*********************************** CNS ***************************************
1353 RELOAD_CURDIR PROC NEAR
1354
1355;*****************************************************************************
1356;
1357; We have an interesting problem here. What if the user is assigning away
1358; his current drive? Here's the solution:
1359;
1360; o We get the current drive here.
1361; o We reload the mapping table.
1362; o We set the current drive.
1363;
1364 MOV AH,Get_Default_Drive ;(19H)
1365 INT DOS_CALL
1366
1367 PUSH AX ; save away the table
1368
1369 MOV AX,(MPLEX_ID SHL 8)+MPLEX_GET_SEG ;(0601H) Get the SEG of the installed ASSIGN
1370 INT MULTIPLEXOR ;(2FH) in ES
1371
1372 mov si,offset drives ;move in the new drive table
1373 mov di,si
1374 mov cx,26 ; move a-z
1375 CLI
1376 rep movsb ;
1377 STI
1378
1379 POP DX ; restore the old current drive
1380 MOV AH,Set_Default_Drive ;(0EH)
1381 INT DOS_CALL
1382
1383 call EXIT_PROG ;go_home:
1384
1385 INT PGM_TERM ;(20H) Exit SHOULD not return, but be safe
1386
1387 ret
1388
1389 RELOAD_CURDIR ENDP
1390;*********************************** CNS ***************************************
1391;Input: Parser control block
1392;Output: Result Parser control block
1393;Register usage: AX,BX,CX,DX,ES,DS,SI,DI
1394;
1395;
1396;*********************************** CNS ***************************************
1397
1398 CHK_PARSER PROC NEAR
1399
1400 xor cx,cx ;an000; clear out cx
1401 xor ax,ax ;AN000; clear out ax
1402 mov al,String_ctr ;AN000; grab current assign ctr
1403 mov bx,0002h ;an000; set bx to 2
1404 div bl ;AN000; divide so we get rem.
1405 cmp RES_TYPE,2 ;an000; check for 1st drive
1406; $IF E,AND ;AN000; drive letter?
1407 JNE $$IF61
1408 cmp ah,EVENX ;AN000; and no remainder?
1409; $IF E ;AN000;
1410 JNE $$IF61
1411 inc STRING_CTR ;AN000; increment counter
1412 mov PARMS_AVAIL,'y' ;AN000; signal parms entered
1413 push ax ;AN000; save ax
1414 mov al,res_itag ;AN000; grab parm entered
1415 mov drv_x,al ;AN000; save it for later use
1416 call drvchk ;AC000; check for valid drive
1417 cbw ;AC000; convert drive byte found to a word
1418 mov bx,offset drives-1 ;AC000; get the drive table
1419 add bx,ax ;AC000; get the drive address
1420 mov save_dr_tbl_ptr,bx ;an000; save the drive table pointer
1421 pop ax ;an000; restore ax
1422; $ENDIF ;AN000;
1423$$IF61:
1424
1425 cmp RES_TYPE,2 ;AN000; check for 2nd drive
1426; $IF E,AND ;AN000; drive entered?
1427 JNE $$IF63
1428 cmp ah,EVENX ;AN000; and not first?
1429; $IF NE ;AN000;
1430 JE $$IF63
1431 inc STRING_CTR ;AN000; increment counter
1432 mov PARMS_AVAIL,'y' ;AN000; signal parms entered
1433 push ax ;AN000; save ax
1434 mov al,res_itag ;AN000; grab parm entered
1435 mov drv_x,al ;AN000; save it for later use
1436 call drvchk ;AC000; if so see if it was valid
1437 mov bx,save_dr_tbl_ptr ;an000; set bx to drive table
1438 mov [bx],al ;AC000; if valid update the table
1439 mov POS_FLAG,'y' ;AN000; yes you have valid positionals
1440 pop ax ;an000; restore ax
1441 mov Parm_Ptr1,si ;an002; dms;ptr to 1st. parm
1442; $ENDIF ;AN000;
1443$$IF63:
1444
1445 cmp RES_SYN,0 ;AN000; See if a switch was specified
1446; $IF NE ;AN000; If so,
1447 JE $$IF65
1448 mov STATUS_flag,1 ;AN000; set the status flag on
1449 mov PARMS_AVAIL,'y' ;AN000; and report that a valid parameter
1450 mov byte ptr SW_Syn1,20h ;an000; remove switch from list
1451 mov byte ptr SW_Syn2,20h ;an000; remove switch from list
1452 mov Parm_Ptr1,si ;an002; dms;ptr to 1st. parm
1453; $ENDIF ;AN000; was on the command line
1454$$IF65:
1455
1456 ret ;AN000;
1457
1458
1459 CHK_PARSER ENDP
1460
1461page
1462;*********************************** CNS ***************************************
1463;
1464; check drive validity
1465;
1466drvchk:
1467
1468 sub al,"A" ; NS- error checking
1469; $IF NB ;AN000; ;if alphabetic,
1470 JB $$IF67
1471
1472 push es
1473 push bx
1474 push ax
1475
1476 les bx,inv
1477 cmp al,es:[bx].sysi_ncds ;AN000; ;NS- check in case current directory
1478; $IF NAE ;AN000; ;NS- has been altered
1479 JAE $$IF68
1480
1481
1482 les bx,es:[bx].sysi_cds
1483 push bx
1484 mov bl,size curdir_list
1485 mul bl
1486 pop bx
1487 add bx,ax
1488 test es:[bx].curdir_flags,curdir_inuse
1489; $IF NZ ;AC000;
1490 JZ $$IF69
1491
1492 pop ax
1493 pop bx
1494 pop es
1495 inc al
1496
1497 ret
1498
1499; $ENDIF ;AC000; curdir in use?
1500$$IF69:
1501; $ENDIF ;AC000; curdir been altered?
1502$$IF68:
1503; $ENDIF ;AC000; alphabetic?
1504$$IF67:
1505
1506 mov ax,parse10 ;AN000; Invalid parameter
1507 call PARSE_ERR ;an000; display the error & end
1508
1509;******************************* CNS *******************************************
1510;Purpose: Print the mapping status of the drive table.
1511;Input : Drive table
1512;Registers affected: BX,CX,DX,AX
1513;
1514;Output : Display of all drive values stored not equal to their sequential
1515; storage address
1516;
1517;******************************* CNS *******************************************
1518REPORT_STATUS PROC NEAR
1519
1520 push es ;an000; save es
1521 push es ;an000; swap es with
1522 pop ax ;an000; ax
1523 mov curr_es_seg,ax ;an000; save es in curr_es_seg
1524
1525 mov ax,0601h ;an000; our int 2fh
1526 int 2fh ;an000; returns segment of drive vector
1527 assume es:nothing ;an000; tell the linker
1528
1529 mov cl,01 ;AN000; ;initialize the counter
1530 ;AN000; advance to next drive
1531 mov bx,offset drives ;AN000; load drive table
1532; $DO
1533$$DO73:
1534 cmp cl,26 ;AN000; see if we scanned all drives
1535
1536; $LEAVE A ;AN000; exit loop if we have
1537 JA $$EN73
1538
1539 cmp cl,es:[bx] ;AN000; ;compare the table value
1540 ;to the table contents
1541; $IF NE ;AN000;
1542 JE $$IF75
1543 push bx ;an000; save bx - we stomp it
1544 push cx ;an000; save cx - we stomp it
1545 mov al,es:[bx] ;AN000; get the table contents to convert
1546 push es ;an000; save es for print
1547 mov bx,curr_es_seg ;an000; get the current segment
1548 mov es,bx ;an000; get the segment into es
1549 assume es:code ;an000; tell linker it is code
1550
1551 add cl,40H ;AN000; convert to ascii representation
1552 add al,40h ;an000; convert to ascii
1553 mov OLD_DRV,cl ;AN000; place in parms for printing
1554 mov NEW_DRV,al ;AN000; by message retriever
1555
1556 mov ax,0002h ;an000; message #2
1557 mov bx,stdout ;an000; print to standard out
1558 mov cx,0002h ;an000; two replaceable parms
1559 mov si,offset sublist1 ;an000; offset of sublist
1560 mov di,0000h ;an000; no buffer for user input
1561 mov dl,no_input ;AN000; no user input to mes. ret.
1562 mov dh,utility_msg_class ;an000; utility messages only
1563
1564 call SYSDISPMSG ;AN000; ;go to message retriever
1565 pop es ;an000; restore es
1566 assume es:nothing ;an000; tell the linker
1567 pop cx ;an000; restore cx
1568 pop bx ;an000; restore bx
1569
1570; $ENDIF ;AN000;
1571$$IF75:
1572
1573 inc bx ;an000; next drive in vector
1574 inc cl ;AN000; next letter to address
1575
1576; $ENDDO ;AN000;
1577 JMP SHORT $$DO73
1578$$EN73:
1579 pop es ;an000; restore es
1580 assume es:code ;an000; tell the linker
1581
1582 ret ;AN000;
1583
1584REPORT_STATUS ENDP
1585page
1586;******************************* CNS *******************************************
1587; Purpose: Exit program
1588; Input : Error code AL
1589; Output : Error code AL
1590;
1591;******************************* CNS *******************************************
1592EXIT_PROG PROC NEAR
1593
1594
1595
1596 mov ah,EXIT ;AC000;(4ch) RETURN TO DOS WITH ERRORLEVEL
1597 int DOS_CALL ;AC000;
1598
1599
1600 ret ;AC000;
1601
1602EXIT_PROG ENDP
1603;******************************* CNS *******************************************
1604
1605;=========================================================================
1606; PARSE_ERR : This routine prints out the applicable parse
1607; error that is returned in AX by SYSPARSE.
1608;
1609; Inputs : AX - Parse error number to be printed
1610; Outputs : Applicable parse error
1611;=========================================================================
1612
1613
1614PARSE_ERR proc near ;an000; dms;report an error
1615
1616 push ax ;an000;save ax
1617 mov byte ptr ds:[si],0 ;an002;null terminate string
1618 mov dx,Parm_Ptr1 ;an002;move ptr to sublist
1619 mov Parse_Sub_Off,dx ;an002;
1620 mov Parse_Sub_Seg,ds ;an002;
1621
1622 mov bx,STDERR ;an000;print to standard out
1623 mov cx,1 ;an002;1 replaceable parm
1624 mov si,offset Parse_Sublist ;an002;sublist for replaceable parm
1625 mov dl,NO_INPUT ;AN000;no input to message retriever
1626 mov dh,PARSE_ERR_CLASS ;AN000;display parse errors
1627 call SYSDISPMSG ;AN000;display error
1628
1629 pop ax ;AN000;restore errcode
1630 call EXIT_PROG ;AN000;exit ASSIGN due to error
1631
1632
1633PARSE_ERR endp ;an000; dms;
1634
1635Release_Environment proc near ;an001; dms;
1636
1637 push ax ;save regs ;an001; dms;
1638 push bx ; ;an001; dms;
1639 push es ; ;an001; dms;
1640 mov ah,Get_PSP ; get the PSP segment ;an001; dms;
1641 int 21h ; invoke INT 21h ;an001; dms;
1642 mov es,bx ; BX contains PSP segment - put in ES ;an001; dms;
1643 mov bx,word ptr es:[PSP_Env]; get segment of environmental vector ;an001; dms;
1644 mov es,bx ; place segment in ES for Free Memory ;an001; dms;
1645 mov ah,Dealloc ; Free Allocated Memory ;an001; dms;
1646 int 21h ; invoke INT 21h ;an001; dms;
1647 pop es ; restore regs ;an001; dms;
1648 pop bx ; ;an001; dms;
1649 pop ax ; ;an001; dms;
1650
1651 ret ; return to caller ;an001; dms;
1652
1653Release_Environment endp
1654
1655Close_Handles proc near ;close handles 0-4 ;an001; dms;
1656
1657 push bx ;save regs ;an001; dms;
1658 mov bx,4 ;close all standard files ;an001; dms;
1659
1660Close_Handle_Loop:
1661
1662 mov ah,Handle_Close ;close file handle ;an001; dms;
1663 int 21h ; ;an001; dms;
1664 dec bx ;next handle ;an001; dms;
1665 jns Close_Handle_Loop ;continue ;an001; dms;
1666
1667 pop bx ;restore regs ;an001; dms;
1668 ret ; ;an001; dms;
1669
1670Close_Handles endp ; ;an001; dms;
1671
1672Get_Vectors proc near ;get original vectors ;an001; dms;
1673
1674 mov ax,(GET_INTERRUPT_VECTOR SHL 8)+ABS_DISK_READ ;(3525h) get the int 25 vector
1675 int DOS_CALL
1676
1677 mov word ptr [int25_vec],bx
1678 mov word ptr [int25_vec+2],es
1679
1680 mov ax,(GET_INTERRUPT_VECTOR SHL 8)+ABS_DISK_WRITE ;(3526H) get the int 26 vector
1681 int DOS_CALL
1682
1683 mov word ptr [int26_vec],bx
1684 mov word ptr [int26_vec+2],es
1685
1686 mov ax,(GET_INTERRUPT_VECTOR SHL 8)+MULTIPLEXOR ;(352FH) get the int 2F vector
1687 int DOS_CALL
1688
1689 mov word ptr [int2F_vec],bx
1690 mov word ptr [int2F_vec+2],es
1691
1692 mov ax,(Get_Interrupt_Vector SHL 8)+DOS_CALL ;(3521H)
1693 int DOS_CALL
1694
1695 mov word ptr cs:[system],bx
1696 mov word ptr cs:[system+2],es
1697
1698 MOV AX,(MPLEX_ID SHL 8)+MPLEX_R_U_THERE ;(0600H) See if we are in system already
1699 INT MULTIPLEXOR ;(2FH)
1700
1701 OR AL,AL
1702; $IF NZ ;AC000; NOT INSTALLED
1703 JZ $$IF78
1704
1705 call RELOAD_CURDIR ;AC000;
1706
1707; $ENDIF
1708$$IF78:
1709
1710 ret ; ;an001; dms;
1711
1712Get_Vectors endp ; ;an001; dms;
1713
1714
1715Set_Vectors proc near ;set to new vectors ;an001; dms;
1716
1717 mov ah,Get_Default_Drive ;(19H)
1718 int DOS_CALL
1719
1720 inc al
1721 mov [default_drive],al ;NS- add one to the value to get the
1722 call mapdrv1 ;NS- actual drive value before mapping
1723
1724 dec al ;NS- dec one to setup for select function
1725 mov dl,al ;select its replacement
1726 mov ah,Set_Default_Drive ;(0EH)
1727 int DOS_CALL
1728 ;NS- Set up hooks
1729 mov dx,offset int25 ;set int 25 vector
1730 mov ax,(SET_INTERRUPT_VECTOR SHL 8) + ABS_DISK_READ ;(2525H)
1731 int DOS_CALL
1732 ;NS- setup new seg
1733 mov dx,offset int26 ;set int 26 vector
1734 mov ax,(SET_INTERRUPT_VECTOR SHL 8) + ABS_DISK_WRITE ;(2526H)
1735 int DOS_CALL
1736 ;NS- Hook in resident portion
1737 mov dx,offset int2F ;set int 2F vector
1738 mov ax,(SET_INTERRUPT_VECTOR SHL 8) + MULTIPLEXOR ;(252FH)
1739 int DOS_CALL
1740
1741 mov dx,offset ASSIGN_HANDLER ;set the system int vector
1742 mov ax,(SET_INTERRUPT_VECTOR SHL 8) + DOS_CALL ;(2521H)
1743 int DOS_CALL
1744
1745 call Close_Handles ;close handles 0-4 ;an001; dms;
1746 call Release_Environment ;release the environmental vector ;an001; dms;
1747
1748 mov dx,prog_size ;end but stay resident
1749 mov ah,KEEP_PROCESS ;(31h) NS- ASSIGN loaded in mem
1750 int DOS_CALL
1751
1752 ret ; ;an001; dms;
1753
1754Set_Vectors endp ; ;an001; dms;
1755
1756
1757
1758.xlist
1759MSG_SERVICES <MSGDATA>
1760msg_services <NEARmsg>
1761msg_services <LOADmsg>
1762msg_services <DISPLAYmsg,CHARmsg>
1763msg_services <assign.cla,assign.cl1>
1764msg_services <assign.cl2>
1765.list
1766
1767include msgdcl.inc
1768
1769code ends
1770 end ENTRY_POINT
1771 \ No newline at end of file