summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/APPEND/APPEND.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/APPEND/APPEND.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/APPEND/APPEND.ASM')
-rw-r--r--v4.0/src/CMD/APPEND/APPEND.ASM3462
1 files changed, 3462 insertions, 0 deletions
diff --git a/v4.0/src/CMD/APPEND/APPEND.ASM b/v4.0/src/CMD/APPEND/APPEND.ASM
new file mode 100644
index 0000000..5ca2b70
--- /dev/null
+++ b/v4.0/src/CMD/APPEND/APPEND.ASM
@@ -0,0 +1,3462 @@
1page 60,120
2;
3.sall
4title APPEND
5include sysmsg.inc
6msg_utilname<APPEND>
7;-----------------------------------------------------------------------------
8;
9; Title: APPEND
10;
11; Author: G. G. A. Network version
12; B. A. F.` DOS changes
13;
14; Syntax: From the DOS command line:
15;
16; APPEND [d:]path[[;[d:]path]...]
17; - Used to specify the directories to be
18; searched after the working directory.
19;
20; APPEND ;
21; - Used to release all appended directories.
22;
23; APPEND
24; - Used to show appended directories.
25;
26; First time only:
27;
28; APPEND [[d:]path | | /X | /E | /X /E]
29; - [d:]path Normal support and Set path
30; - Normal support
31; - /X Extended support, SEARCH, FIND and EXEC
32; - /E Use DOS Environment for path(s)
33;
34; Revision History:
35; @@01 07/11/86 Fix hang in TopView start PTM P00000??
36; @@02 07/28/86 Fix APPEND size problem PTM P0000045
37; @@03 07/29/86 Fix APPEND status with /E problem PTM P00000??
38; @@04 07/30/86 Fix second APPEND hang PTM P0000053
39; @@05 08/13/86 Fix parameter error PTM P0000125
40; @@06 08/20/86 Fix APPEND xxx fails in TopView PTM P0000217
41; @@07 08/21/86 Resurrect APPEND version message PTM P0000252
42; @@08 08/21/86 APPEND=path first time hangs PTM P0000254
43; @@09 08/22/86 APPEND gets wrong path under nested COMMAND PTM P0000276
44; @@10 08/28/86 Change message for @@05 PTM P0000291
45; @@11 09/10/86 Support message profile and make
46; msg length variable. R.G. PTM P0000479
47; @@12 09/25/86 Allow second external append call. (RG) PTM P0000515
48; @@13 09/30/86 APPEND gets wrong path under nested COMMAND PTM P0000600
49; Again. Fix in COMMAND now, so remove @@09 changes
50; @@14 10/01/86 Lower case drive in path files PTM P0000600
51; @@15 10/06/86 Include "," and "=" in skip leading of
52; argument area parsing. PTM P0000677
53; @@16 10/06/86 Fix not using full APPEND path PTM P0000794
54; @@17 12/03/86 When searching for "APPEND=" string in
55; environment, make sure delimiter precedes.(RG) PTM P0000893
56;
57;-------------------------------------------------------------------
58;
59; AN000 3.30 changes, GGA 6/87 new code. P000
60; AN001 Support DRIVE and PATH modes D043
61; AN002 Add truename function P1276
62; AN003 Add extended handle open function D250
63; AN005
64; AN006 Add DBCS support
65; AN007 Release Environmental Vector space P2666
66; AN008 Allow equal symbol with append - APPEND=A:/1; P2901
67; AN009 Release Environmental Vector on only the P3333
68; first invocation of APPEND
69; AN010 display invalid parm from command line P3908
70;
71;
72;-----------------------------------------------------------------------------
73;Date Rev Comments
74;-----------------------------------------------------------------------------
75;06-02-86 0.0 Begin conversion to PC/DOS version
76;06-20-86 0.0 End conversion to PC/DOS version
77;
78page
79
80cseg segment public para 'CODE'
81 assume cs:cseg
82 assume ds:nothing,es:nothing
83
84;-----------------------------------------------------------------------------
85; Equates
86;-----------------------------------------------------------------------------
87
88.xlist
89;include fsi.lib
90NETSYSUTIL EQU 0C2H ; SYSTEM UTILITIES
91NETENQ EQU 07H ; ENQ RESOURCE
92NETDEQ EQU 08H ; DEQ RESOURCE
93;include task.lib
94TCBR_APPEND EQU 001H ; APPEND ACTIVE
95;include DOS.lib
96DOSSERVER EQU 5DH ; SERVER OPERATION
97DOSSETERROR EQU 0AH ; SET EXTENDED ERROR
98;include server.lib
99DPL STRUC
100DPL_AX DW 0 ;AX REG
101DPL_BX DW 0 ;BX REG
102DPL_CX DW 0 ;CX REG
103DPL_DX DW 0 ;DX REG
104DPL_SI DW 0 ;SI REG
105DPL_DI DW 0 ;DI REG
106DPL_DS DW 0 ;DS REG
107DPL_ES DW 0 ;ES REG
108DPL_XID DW 0 ;RESERVED
109DPL_UID DW 0 ;SERVER USER ID
110DPL_PID DW 0 ;REDIRECTOR PROCESS ID
111DPL ENDS
112include sysmac.lib
113include versiona.inc
114include appendp.inc ; parseing stuff for append ;AN004;
115.list
116; extrn end_address:near ; end of stay resident stuff
117
118; extrn bad_append_msg:byte ; messages
119; extrn path_error_msg:byte
120; extrn parm_error_msg:byte
121; extrn path_parm_error_msg:byte
122; extrn no_append_msg:byte ; @@05
123; extrn append_assign_msg:byte
124; extrn append_TV_msg:byte ; @@01
125; extrn bad_DOS_msg:byte
126; extrn second_APPEND_msg:byte ; @@04
127
128; extrn len_bad_append_msg:word ;@@11
129; extrn len_path_error_msg:word ;@@11
130; extrn len_parm_error_msg:word ;@@11
131; extrn len_path_parm_error_msg:word ;@@11
132; extrn len_no_append_msg:word ;@@11
133; extrn len_append_assign_msg:word ;@@11
134; extrn len_append_TV_msg:word ;@@11
135; extrn len_bad_DOS_msg:word ;@@11
136; extrn len_second_APPEND_msg:word ;@@11
137
138; Environmental Vector
139
140PSP_Env equ 2ch ;Environmental vector segment in PSP ;an007; dms;
141
142; Interrupts
143
144DOS_function equ 21h ; DOS function call interrupt
145int_function equ 2fh ; DOS internal function interrupt, used
146 ; to verify APPEND presence
147termpgm equ 20h ; @@05
148resident equ 27h
149
150; Function calls
151
152get_vector equ 3521h ; DOS function call to get INT 21 vector
153set_vector equ 2521h ; DOS function call to set INT 21 vector
154get_intfcn equ 352fh ; DOS function call to get INT 2f vector
155set_intfcn equ 252fh ; DOS function call to set INT 2f vector
156get_version equ 30h ; DOS function call to get DOS version number
157get_DTA equ 2fh ; DOS function get DTA
158set_DTA equ 1ah ; DOS function set DTA
159get_crit_err equ 3524h ; DOS function call to get INT 24 vector
160set_crit_err equ 2524h ; DOS function call to set INT 24 vector
161get_PSP equ 62h ; DOS function call to get PSP address
162Free_Alloc_Mem equ 49h ; DOS function call to free alloc. mem. ;an007; dms;
163
164print_string equ 09h ; DOS function call to get print a string
165ctrl_break equ 33h ; DOS function call to get/set ctrl-break
166
167awrite equ 40h ; write function
168get_dir equ 47h ; get current dir
169change_dir equ 3bh ; change dir
170get_disk equ 19h ; get current disk
171change_disk equ 0eh ; change disk
172term_stay equ 31h ; terminate a process and stay resident
173term_proc equ 4ch ; terminate a process
174
175redir_flag equ 0000000000001000B ; redir flag for net installation check
176
177; DOS INT 2f function for APPEND presence
178
179append_2f equ 0b7h ; int 2f function code for append
180applic_2f equ 0aeh ; int 2f function code for applications
181COMMAND_2f equ -1 ; int 2f subfunction code for COMMAND call
182append_inst equ 0ffh ; flag means append is there
183
184; INT 2f sub-function codes ;AN000;
185
186are_you_there equ 0 ; function code for presence check
187old_dir_ptr equ 1 ; means APPEND 1.0 is trying to run
188get_app_version equ 2 ; fun code for get ver request
189tv_vector equ 3 ; fun code for set TV vector
190dir_ptr equ 4 ; function code to return dirlist ptr
191get_state equ 6 ; function code to return append ;AN001;
192 ; state ;AN001;
193set_state equ 7 ; function code to set append ;AN001;
194 ; state ;AN001;
195
196DOS_version equ 10h ; function call to get DOS version
197true_name equ 11h ; one-shot truename fcn for ASCIIZ ops ;AN002;
198
199; DOS INT 21 function calls that APPEND traps
200
201FCB_opn equ 0fh
202file_sz equ 23h
203handle_opn equ 3dh
204dat_tim equ 57h
205FCB_sch1 equ 11h
206handle_fnd1 equ 4eh
207exec_proc equ 4bh
208ext_handle_opn equ 6ch ;AN003;
209
210break macro ; this is a dummy break macro so PDB.INC
211 endm ; won't blow up in the build
212
213; define some things for PDB (PSP) ;AN002;
214 ;AN002;
215include pdb.inc ;AN002;
216 ;AN002;
217true_name_flag equ 01h ; flag for true name function ;AN002;
218eo_create equ 00f0h ; mask to check extended opens for create ;AN003;
219
220; Error codes that don't mean stop looking
221
222FCB_failed equ 0ffh ; FCB open failed
223FCB_file_not_found equ 2 ; file not found on FCB open
224handle_file_not_found equ 2 ; file not found on handle open
225handle_path_not_found equ 3 ; path not found on handle open
226FCB_no_more_files equ 18 ; no more matching files
227handle_no_more_files equ 18 ; no more matching files
228
229; Equates for TOPVIEW barrier
230TV_TRUE equ -1 ; this was changed from TRUE ;AN000;
231 ; because 3.30 parser uses TRUE ;AN000;
232false equ 0 ;
233
234; Message equates
235
236tab_char equ 9
237cr equ 13
238lf equ 10
239beep equ 7
240STDOUT equ 0001h ; standard output file
241STDERR equ 0002h ; standard error file
242null equ 0
243
244page
245
246;-----------------------------------------------------------------------------
247; Resident data area
248;-----------------------------------------------------------------------------
249
250version_loc: ; version number
251 db major_version,minor_version
252; dw message_list ; pointer to message table
253
254 even
255vector_offset dw 0 ; save pointer to old int 21 here
256vector_segment dw 0
257crit_vector_offset dw 0 ; save pointer to old int 24 here
258crit_vector_segment dw 0
259intfcn_offset dw 0 ; save pointer to old int 2f here
260intfcn_segment dw 0
261dirlst_offset dw 0 ; save pointer to dir list here
262dirlst_segment dw 0
263tv_vec_off dw 0 ; save TV vector here
264tv_vec_seg dw 0
265
266pars_off dd cseg: SysParse ; save pointer to parser here
267;pars_off dw offset SysParse ; save pointer to parser here
268;pars_seg dw 0
269
270app_dirs_seg dw 0 ; save ES here during FCB
271
272FCB_ptr dd 0 ; save pointer to FCB here
273handle_ptr dd 0 ; save pointer to ASCIIZ string here
274
275stack_offset dw 0
276stack_segment dw 0 ; Calling process stack
277
278incoming_AX dw 0 ; AX saved at entry to interrupt handler
279incoming_CX dw 0 ; CX saved at entry to interrupt handler
280; must be together
281incoming_BX dw 0 ; BX saved at entry to interrupt handler
282incoming_ES dw 0 ; ES saved at entry to interrupt handler
283; must be together
284ax_after_21 dw 0 ; AX saved after call to real INT 21
285; temp_DS_save dw 0 ; DS saved during stack ops
286temp_CS_save dw 0 ; CS saved during stack ops (set_return_flags)
287temp_IP_save dw 0 ; IP saved during stack ops (set_return_flags)
288FCB_drive_id db 0 ; save the drive id for FCB opens here
289
290;------------------------
291; DBCS stuff here ;AN006;
292 ;AN006;
293DBCSEV_OFF DW 0 ; OFFSET OF DBCS EV ;AN006;
294DBCSEV_SEG DW 0 ; SEGMENT OF DBCS EV ;AN006;
295 ;AN006;
296;DEFAULT DBCS ENVIRONMENTAL VECTOR ;AN006;
297EVEV DB 00H,00H ;AN006;
298 DB 00H,00H ;AN006;
299 DB 00H,00H ;AN006;
300 ;AN006;
301dbcs_fb dw 0 ; offset of DBCS first byte chars found
302;------------------------
303
304initial_pass dw 0 ; flag used to indicate inital APPEND ;AN007;
305
306incoming_DX dw 0 ; used for saves for extended open ;AN003;
307incoming_SI dw 0 ; used for saves for extended open ;AN003;
308incoming_DI dw 0 ; used for saves for extended open ;AN003;
309incoming_DS dw 0 ; used for saves for extended open ;AN003;
310true_name_count dw 0 ; used to save number of chars in true_name dir ;AN003;
311
312int_save_ip dw 0 ; save registers here during critical
313int_save_cs dw 0 ; error handler stack ops
314
315work_disk db "?:\" ; user's working disk
316work_dir db 64 dup(" ") ; user's working dir
317app_disk db "?:\" ; user's working disk
318app_dir db 64 dup(" ") ; user's append disk's working dir
319ctrl_break_state db 0 ; save the old ctrl-break state here
320
321end_search db 0 ; end search flag
322try_dir db 128 dup (0) ; try this dir
323fname db 15 dup (0) ; 8.3 filename stripped from original
324 ; ASCIIZ string
325app_dirs_ptr dw 0 ; pointer to appended dir to try
326
327set_name db "SET " ; SET command
328; must be together
329setappend_name db "SET " ; SET command
330append_id db "APPEND=" ; display from here for user
331; must be together
332app_dirs db ";"
333 db 128 dup (0) ; area for storing appended dirs
334 db 0 ; just to insure that the last dir is null terminated
335semicolon db ";",0 ; null list
336
337; Flags / barriers added for TopView
338
339tv_flag db 0 ; flag to indicate re-entr from TopView
340
341parse_flag db 0 ; flag used by APPEND parsing
342
343FCB_ext_err db 0 ; flag used to indicate that FCB
344 ; open failed and ext err was done
345crit_err_flag db 0 ; flag used to indicate that a critical
346 ; error happened
347ext_err_flag db 0 ; flag used to indicate that ext err
348 ; must be set 0 = don't set, 1 = do set
349in_middle db 0 ; flag used to tell if we made it to
350 ; middle of string before finding a space
351equal_found db 0 ; multiple = check
352;crit_sect_flag db 0 ; critical section flag
353
354stack_area dw 99 dup(0) ; stack area for append
355append_stack dw 0
356
357net_config dw 0 ; flag word for what (if any) network
358 ; config we are running under
359 ; as long as this word is zero, a clear determination
360 ; has not been made about the configuration
361
362 even
363ext_err_dpl DPL <> ; reserve a DPL for get/set extended error code
364
365
366save_ext_err DPL <> ; reserve a DPL for first extended
367 ; error code
368
369;------------------------------------------------------------------- ;AN001;
370; ;AN001;
371; mode_flags This status word is used to control the various ;AN001;
372; APPEND functions and modes. ;AN001;
373; ;AN001;
374;------------------------------------------------------------------- ;AN001;
375mode_flags dw Path_mode + Drive_mode + Enabled ;AN001;
376 ; mode control flags ;AN001;
377 ; initially - path, drive and ;AN001;
378 ; enabled ;AN001;
379
380; equates for mode_flags follow: ;AN001;
381
382X_mode equ 8000h ; in /X mode
383E_mode equ 4000h ; in /E mode
384Path_mode equ 2000h ; PATH in string OK ;AN001;
385Drive_mode equ 1000h ; DRIVE in string OK ;AN001;
386Enabled equ 0001h ; APPEND enabled ;AN001;
387
388;-------------------------------------------------------------------
389
390cmd_name@ dd ? ; internal name string
391
392expected_error dw ? ; error to do append scan
393expected_ext_error dw ? ; error to do append scan
394
395cmd_env dw ? ; pointer to COMMANDs environment
396cmd_buf dw ? ; CMDBUF offset (in SS)
397
398incoming_DTA dd ? ; user's DTA (on EXEC)
399exec_DTA db 21+1+2+2+2+2+13 dup(0) ; find DTA for exec emulation
400
401old_syntax db 0 ; using network syntax
402
403res_append db 0 ; resident append call ; @@05
404
405abort_sp dw ? ; sp to restore on errors ; @@05
406
407crlf label byte
408 db CR,LF
409crlf_len equ $ - crlf
410
411;******************************************************************* ;an010;bgb
412; parser message display area ;an010;bgb
413;******************************************************************* ;an010;bgb
414inv_parm db 0bh ;length ;an010;bgb
415 db 0 ;reserved ;an010;bgb
416si_off dw 0 ;put offset of command line here ;an010;bgb
417si_seg dw 0 ;put segment of command line here ;an010;bgb
418 db 0 ;use percent zero ;an010;bgb
419 db Left_Align+Char_Field_ASCIIZ ;type of data ;an010;bgb
420 db 128 ;max width ;an010;bgb
421 db 1 ;min width ;an010;bgb
422 db ' ' ;pad char ;an010;bgb
423
424;-------------------------------------------------------------------
425;
426; resident message area
427;
428;-------------------------------------------------------------------
429
430MSG_SERVICES <MSGDATA>
431MSG_SERVICES <DISPLAYmsg,CHARmsg> ;an010;bgb
432MSG_SERVICES <APPEND.CLA,APPEND.CL1,APPEND.CTL>
433
434.xlist
435;-----------------------------------------------------------------------------
436; macros
437;-----------------------------------------------------------------------------
438
439;-----------------------------
440; save and restore register macros
441save_regs macro
442 push bx
443 push cx
444 push dx
445
446 push di
447 push si
448 push ds
449 push es
450 endm
451
452restore_regs macro
453 pop es
454 pop ds
455 pop si
456 pop di
457
458 pop dx
459 pop cx
460 pop bx
461 endm
462
463;-----------------------------
464; this macro is used instead of the normal POPF instruction to help
465; prevent a 286 bug from occurring
466popff macro
467 local myret
468 jmp $+3
469myret label near
470 iret
471 push cs
472 call myret
473 endm
474
475;----------------------------- ; @@12
476; check character ; @@12
477; ; @@12
478chkchar macro char ; @@12
479 lodsb ; @@12
480 and al,0dfh ; @@12
481 cmp al,char ; @@12
482 jne ccn_ret ; @@12
483 endm ; @@12
484.list
485
486page
487;-----------------------------------------------------------------------------
488; resident routine - control transferred here on INT 21
489; check to see if this call has a function code we are interested in
490;-----------------------------------------------------------------------------
491
492
493tv_entry:
494 pushf ; @@01
495 jmp check_fcb_open ; @@01
496
497interrupt_hook:
498resident_routine:
499 pushf ; save the user's flags (old stack)
500
501 cmp tv_flag,TV_TRUE ; see if in TV ;AN000;
502 je use_old ; yes, old_vect
503
504check_fcb_open: ; @@01
505
506;------------------------------------------------------------------- ;AN001;
507; first, check to see if APPEND disabled, if so, skip everything ;AN001;
508; and go to real INT 21 handler ;AN001;
509;------------------------------------------------------------------- ;AN001;
510 test mode_flags,Enabled ; APPEND disabled? ;AN001;
511 jz real_jump ; yes, skip all other checks ;AN001;
512
513 cmp ah,FCB_opn ; FCB open?
514 jump E,FCB_open ; yes, do the APPEND
515
516 cmp ah,handle_opn ; handle open?
517 jump E,handle_open ; yes, do the APPEND
518
519 cmp ah,ext_handle_opn ; extended handle open? ;AN003;
520 jump E,ext_handle_open ; yes, do the APPEND ;AN003;
521 ;AN003;
522 cmp ah,file_sz ; file size?
523 jump E,FCB_open ; yes, do the APPEND
524
525
526 test mode_flags,X_mode ; /X mode not selected
527 jz real_jump
528
529 cmp ah,FCB_sch1 ; search?
530 jump E,FCB_search1 ; yes, do the APPEND
531
532 cmp ah,handle_fnd1 ; find?
533 jump E,handle_find1 ; yes, do the APPEND
534
535 cmp tv_flag,TV_TRUE ; cant do in TopView ;AN000;
536 je skip_exec
537 cmp ax,exec_proc*256+0 ; EXEC?
538 jump E,exec_pgm ; yes, do the APPEND
539skip_exec:
540 cmp ax,exec_proc*256+3 ; EXEC?
541 jump E,exec_pgm ; yes, do the APPEND
542
543 page
544;-----------------------------------------------------------------------------
545; By here, we know that the call was not one we are interested in,
546; pass through to old INT 21.
547; Since this is done with a jmp, control will pass back to original caller
548; after DOS is finished.
549;-----------------------------------------------------------------------------
550
551real_jump:
552 cmp tv_flag,TV_TRUE ; see if called by TV ;AN000;
553 jne use_old ; yes, use old vect
554
555 popff ; restore user's flags
556 jmp dword ptr tv_vec_off ; pass through to TV
557
558use_old:
559 popff ; restore user's flags (old stack)
560 jmp dword ptr Vector_Offset ; jump to old INT 21
561
562page
563;-----------------------------------------------------------------------------
564; FCB_search1 - this routine handles FCB search first calls
565;-----------------------------------------------------------------------------
566
567FCB_search1:
568 mov expected_ext_error,fcb_no_more_files
569 jmp short FCB_openx1
570
571;-----------------------------------------------------------------------------
572; FCB_open - this routine handles FCB open calls
573;-----------------------------------------------------------------------------
574
575FCB_open:
576 mov expected_ext_error,fcb_file_not_found
577FCB_openx1:
578 call check_config ; check the config flags
579 call crit_sect_set ; set critical section flag
580
581 call tv_barrier
582
583 mov incoming_AX,ax ; save user's AX
584 mov word ptr FCB_ptr+0,dx ; save FCB pointer
585 mov word ptr FCB_ptr+2,ds
586
587 popff ; restore user's flags
588 call int_21 ; try the open
589
590 cli
591 mov AX_after_21,ax ; save AX as it came back from INT
592 pushf ; save flags from operation
593 cmp al,FCB_failed ; open failed ?
594 je check_error ; yes, lets check extended error
595 jmp set_return_flags ; no, fix the stack, then ret to caller
596
597check_error:
598 call get_ext_err_code ; get the extended error code
599 mov FCB_ext_err,1 ; set FCB ext error
600 call save_first_ext_err ; save first extended error code
601 mov ax,ext_err_dpl.DPL_AX ; get error in ax
602 cmp ax,expected_ext_error ; file not found?
603 je FCB_openx2 ; yes, lets look around for file
604 lea dx,save_ext_err ;
605 call set_ext_err_code ; set the extended error code
606 jmp set_return_flags ; no, fix the stack, then return
607
608FCB_openx2:
609
610; set up APPEND's stack
611
612 popff ; get rid of the flags from the
613 ; real operation
614; mov temp_DS_save,ds ; Save DS reg
615 mov stack_segment,ss ; Save it
616 mov stack_offset,sp ; Save it
617 mov ax,cs ; Get current segment
618 mov ss,ax ; and point stack seg here
619 lea sp,append_stack ; set up new stack
620
621 save_regs ; save registers
622
623 push cs ; establish addressability
624 pop ds
625
626 call ctrl_break_set ; set ctrl-break handler
627 call crit_err_set ; set crit err handler
628
629 mov ext_err_flag,1 ; flag for setting critical error
630
631; fix FCB drive spec
632
633 les bx,dword ptr FCB_ptr ; ES:BX points to FCB
634 mov ah,ES:byte ptr [bx] ; get FCB drive spec
635 cmp ah,-1 ; extended FCB?
636 jne not_ext_FCB1
637 add bx,1+5+1 ; point to real drive letter
638 mov ah,ES:byte ptr [bx] ; get FCB drive spec
639
640not_ext_FCB1:
641 mov FCB_drive_id,ah ; save it for later
642 mov ES:byte ptr [bx],0 ; zero the drive field out to
643 ; use default drive
644
645 mov ah,get_disk ; get disk
646 call int_21 ; call DOS INT 21 handler
647
648 add al,"A" ; make it a character
649 mov work_disk,al ; save it
650
651 mov ah,get_dir ; get directory
652 xor dx,dx ; default drive
653 lea si,work_dir ; save area
654 call int_21 ; call DOS INT 21 handler
655
656 call address_path ; get address of path
657 cmp es: byte ptr [di],";" ; is the append list null?
658 jump E,null_list ; exit append
659 mov app_dirs_seg,es ; save app dirs segment
660 mov si,di ; source
661
662try_another1:
663 lea di,try_dir ; destination
664 call get_app_dir ; copy dir to try into try_dir
665 mov app_dirs_ptr,si ; save updated pointer
666
667
668;-----------------------------
669try_app_dir1:
670 mov app_disk,0 ; zero for current dir
671 cmp try_dir+1,":" ; see if we have a drive
672 jne no_drive ; char should be a colon
673
674; yes, there was a drive specified, must do the change disk function call
675
676 mov ah,change_disk ; change disk
677 mov dl,try_dir ; get the char representation of the drive
678 mov app_disk,dl ; save it away for later use
679 call cap_dl
680 sub dl,"A" ; convert from char to drive spec
681 call int_21 ; call DOS INT 21 handler
682; jc check_end_dir_list ; there was an error, see if there is
683 ; another to try
684
685 cmp crit_err_flag,0 ; did we experience a critical error
686 jne set_err_code ; yes, fake a file_not_found
687
688no_drive:
689 mov ah,get_dir ; get directory
690 xor dx,dx ; default drive
691 lea si,app_dir ; save area
692 call int_21 ; call DOS INT 21 handler
693
694; check to see if there was a critical error
695
696 cmp crit_err_flag,0 ; did we experience a critical error
697 je cd_worked ; no, the cd worked
698 jmp short set_err_code
699
700save_regs_and_set:
701 pushf ; save everything again
702 save_regs
703 push cs ; re-establish addressability
704 pop ds ; ds = cs
705
706set_err_code:
707 xor ah,ah ; make ax look like open failed
708 mov al,FCB_failed
709 mov ax_after_21,ax ; save it away so we can restore it below
710
711 jmp no_more_to_try
712
713cd_worked:
714 lea dx,try_dir ; point dx to dir to try
715 mov ah,change_dir ; change dir to appended directory
716 call int_21 ; call DOS INT 21 handler
717
718; try the open in this dir
719
720 restore_regs ; make regs look like when user
721 mov ax,incoming_AX ; called us
722
723 call int_21 ; call DOS INT 21 handler
724 mov ax_after_21,ax ; save AX
725 cmp crit_err_flag,0 ; did we get critical error?
726 jne save_regs_and_set ; yes, fake a file_not_found
727 cmp al,FCB_failed ; did open work?
728 jne open_ok
729 call get_ext_err_code ; get the extended error code
730
731open_ok:
732 pushf ; save everything again
733 save_regs
734
735 push cs ; re-establish addressability
736 pop ds ; ds = cs
737
738; restore user's working disk and restore the dir on the appended drive
739
740 mov ah,change_disk ; change disk back to our original
741 mov dl,work_disk
742 call cap_dl
743 sub dl,"A" ; convert from char to drive spec
744 call int_21 ; call DOS INT 21 handler
745
746 mov ah,change_dir ; change dir
747 lea dx,app_disk ; save area (this time include drive)
748 call int_21 ; call DOS INT 21 handler
749
750; this is for ..\dirname ptr
751
752 mov ah,change_dir ; change dir
753 lea dx,work_disk ; save area (this time include drive)
754 call int_21 ; call DOS INT 21 handler
755
756 mov ax,ax_after_21 ; restore AX
757 cmp al,FCB_failed ; did open work?
758 jne FCB_open_worked
759 mov ax,ext_err_dpl.DPL_AX
760 cmp ax,expected_ext_error
761 jne no_more_to_try ; not file not found
762
763check_end_dir_list:
764 mov es,app_dirs_seg ; restore es
765 mov si,app_dirs_ptr
766 cmp si,null ; should we try again?
767 je no_more_to_try ; no
768 jmp try_another1 ; yes
769
770FCB_open_worked:
771 mov byte ptr ext_err_flag,0 ; the open worked, no need to set ext err code
772 jmp short set_disk
773
774no_more_to_try:
775; restore user's working disk and dir
776
777; The following code up to label "null_list" which
778; restores the user's drive and path was moved in front
779; of the code to restore the drive spec in FCB.
780;
781 mov ah,change_disk ; change disk
782 mov dl,work_disk
783 call cap_dl
784 sub dl,"A" ; convert from char to drive spec
785 call int_21 ; call DOS INT 21 handler
786
787 mov ah,change_dir ; change dir
788 lea dx,work_disk ; save area (this time include drive)
789 call int_21 ; call DOS INT 21 handler
790
791null_list:
792 mov ah,FCB_drive_id ; get FCB drive spec
793; cmp ah,0 ; did they ask for default drive?
794; je fix_drive_spec ; yes, leave it alone
795 jmp short fix_drive_spec
796
797set_disk: ; set drive number in FCB
798 mov ah,work_disk ; no, give them the found drive spec
799 sub ah,"A"-1 ; convert from char to drive spec
800
801; ah has proper drive spec to put into FCB, do it
802
803fix_drive_spec:
804 les bx,dword ptr FCB_ptr ; ES:BX points to FCB
805 cmp ES:byte ptr[bx],-1 ; extended FCB
806 jne not_ext_FCB2 ; put in the proper drive spec
807 add bx,1+5+1 ; point to real drive letter
808
809not_ext_FCB2:
810 mov ES:byte ptr [bx],ah
811
812
813 call ctrl_break_restore
814 call crit_err_restore
815
816; find out if there is a need to set the extended error code
817
818 cmp ext_err_flag,0 ; do we need to set the extended error code?
819 je no_ext_err ; no, finish up
820 lea dx,ext_err_dpl
821 cmp FCB_ext_err,0
822 je handle_ext_err
823 lea dx,save_ext_err
824
825handle_ext_err:
826 call set_ext_err_code ; yes, go set the ext error info
827
828; all done with append, clean things back up for the user
829
830no_ext_err:
831 restore_regs ; restore registers
832
833 jmp reset_stack ; fix stack, ret to caller
834page
835
836;-----------------------------------------------------------------------------
837; handle_find - APPEND handle find function
838;-----------------------------------------------------------------------------
839
840handle_find1:
841 mov incoming_CX,cx ; save user's CX
842 mov expected_error,handle_no_more_files
843; mov expected_ext_error,handle_no_more_files
844 jmp short handle_openx
845
846;-----------------------------------------------------------------------------
847; exec_pgm - APPEND exec program function
848;-----------------------------------------------------------------------------
849
850exec_pgm:
851 mov incoming_BX,bx ; save user's ES:BX
852 mov incoming_ES,es
853 mov expected_error,handle_file_not_found
854; mov expected_ext_error,handle_no_more_files
855 jmp short handle_openx
856
857;----------------------------------------------------------------------------- ;AN003;
858; ext_handle_open - APPEND extended handle open function ;AN003;
859;----------------------------------------------------------------------------- ;AN003;
860ext_handle_open: ;AN003;
861 test dx,eo_create ; does this call specify create? ;AN003;
862 jz no_eo_create ; no, we can continue ;AN003;
863 ;AN003;
864 jmp real_jump ; yes, do nothing but pass on to real ;AN003;
865 ; INT 21 handler ;AN003;
866 ;AN003;
867; getting here means the caller did not specify the create option ;AN003;
868 ;AN003;
869no_eo_create: ;AN003;
870 ;AN003;
871 mov incoming_BX,bx ; save user's registers ;AN003;
872 mov incoming_CX,cx ; extended open sure does use a lot ;AN003;
873 mov incoming_DX,dx ; of registers ;AN003;
874 mov incoming_SI,si ;AN003;
875 mov incoming_DI,di ;AN003;
876 mov incoming_ES,es ;AN003;
877 mov incoming_DS,ds ;AN003;
878 ;AN003;
879 mov expected_error,handle_file_not_found ;AN003;
880 jmp short handle_openx ; for now ... ;AN003;
881 ;AN003;
882;-----------------------------------------------------------------------------
883; handle_open - APPEND handle open function
884;-----------------------------------------------------------------------------
885
886handle_open:
887 mov expected_error,handle_file_not_found
888; mov expected_ext_error,handle_file_not_found
889
890handle_openx:
891 call check_config ; check the config flags
892 call crit_sect_set ; set critical section flag
893
894 call tv_barrier ; no op on exec
895
896 mov incoming_AX,ax ; save user's AX
897 mov word ptr handle_ptr+0,dx ; save path pointer
898 mov word ptr handle_ptr+2,ds
899
900 popff ; restore user's flags
901 call int_21 ; try the open
902
903 cli
904 mov AX_after_21,ax ; save AX as it came back from INT
905 pushf ; save flags from operation
906
907; find out if we had an error, and if so was it the one we were
908; looking for
909
910 jc what_happened ; yes, lets find out what happened
911 mov incoming_AX,-1 ; insure no exec done later
912 jmp set_return_flags ; no, fix the stack, then ret to caller
913 ; this means that the real call worked,
914 ; APPEND does not need to do anything
915
916what_happened:
917; cmp ax,handle_path_not_found ; normal errors
918; je handle_search ; yes, look for the file
919 cmp ax,expected_error ; was the error file not found?
920 je handle_search ; yes, look for the file
921 jmp set_return_flags ; no, fix the stack, then ret to caller
922
923
924handle_search:
925 call get_ext_err_code ; get the extended error code information
926
927; set up APPEND's stack
928 popff ; get rid of the flags from the
929 ; real operation
930; mov temp_DS_save,ds ; Save DS reg
931 mov stack_segment,ss ; Save it
932 mov stack_offset,sp ; Save it
933 mov ax,cs ; Get current segment
934 mov ss,ax ; and point stack seg here
935 lea sp,append_stack ; set up new stack
936
937 save_regs ; save registers
938 pushf ;
939 push cs ; establish addressability
940 pop ds
941
942 call crit_err_set
943
944 call ctrl_break_set
945
946; all done with the prep stuff, let's get down to business
947
948;------------------------------------------------------------------- ;AN001;
949; ;AN001;
950; before doing anything else, check DRIVE and PATH modes ;AN001;
951; ;AN001;
952;------------------------------------------------------------------- ;AN001;
953; ;AN001;
954
955 pushf ; save flags ;AN001;
956 push ax ; save AX ;AN001;
957 ;AN001;
958 cmp incoming_AX,exec_proc*256 ; is this call an exec?
959 je drive_and_path_ok
960
961
962;-------------------------------------------------------------------
963; Set up ES:SI to point to incoming string
964;-------------------------------------------------------------------
965
966 cmp incoming_AX,ext_handle_opn*256+0 ;is this call an ext open? ;AN003;
967 jne no_eo13 ;AN003;
968 mov si,incoming_SI ; DS:SI points to original name for ex open ;AN003;
969 mov es,incoming_DS ; but this code wants ES:SI to point to it ;AN003;
970 lea di,fname ; DS:DI points to fname area ;AN003;
971 jmp eo_skip3 ; skip the old stuff ;AN003;
972 ;AN003;
973no_eo13: ;AN003;
974 les si,dword ptr handle_ptr ; ES:SI points to original handle
975 lea di,fname ; DS:DI points to fname area
976eo_skip3:
977;-------------------------------------------------------------------
978
979 test mode_flags,Drive_mode ; Drive_mode enabled?
980 jnz check_path_mode ; yes, go check path mode
981
982 call check_for_drive ; no, find out if there is a drive
983 ; specified
984 cmp ax,0 ; was there a drive letter?
985 je check_path_mode ; no, go check path mode
986
987;-------------------------------------------------------------------
988; getting here means that Drive_mode is disabled and that a drive letter
989; was found. This means we give up on this APPEND operation
990
991 jmp drive_or_path_conflict
992
993
994check_path_mode:
995 test mode_flags,Path_mode ; Path_mode enabled?
996 jnz drive_and_path_ok ; yes, go do the APPEND function
997
998 call check_for_path ; no, find out if there is a path
999 ; specified
1000
1001 cmp ax,0 ; was there a path?
1002 jne drive_or_path_conflict ; no, go do the APPEND function
1003
1004
1005 call check_for_drive ; no, find out if there is a drive
1006 ; specified
1007 cmp ax,0 ; was there a drive letter?
1008 je drive_and_path_ok ; no, everything is OK
1009 ; yes, fall through and exit w/error
1010
1011;------------------------------------------------------------------- ;AN001;
1012; getting here means that Drive_mode is disabled and that a drive ;AN001;
1013; letter was found. This means we give up on this APPEND operatio ;AN001; n
1014
1015drive_or_path_conflict:
1016
1017 pop ax ; clean up stack
1018 popff
1019
1020; restore_regs ; restore some regs ;AN002;
1021; pop ax
1022
1023 mov ext_err_flag,1 ; we need to set extended error info
1024 mov ax,expected_error ; make ax look like we got file not found
1025 mov ax_after_21,ax ; save it away so we can restore it below
1026 popff ; get flags from stack
1027 stc ; set the carry flag
1028 pushf ; put 'em back
1029
1030 jmp no_more_to_try2
1031
1032
1033drive_and_path_ok: ;AN001;
1034 pop ax ; restore AX ;AN001;
1035 popff ; restore flags ;AN001;
1036 ;AN001;
1037;------------------------------------------------------------------- ;AN001;
1038; end of code to check DRIVE and PATH modes ;AN001;
1039;------------------------------------------------------------------- ;AN001;
1040
1041 cmp incoming_AX,ext_handle_opn*256+0 ;is this call an ext open? ;AN003;
1042 jne no_eo1 ;AN003;
1043 mov si,incoming_SI ; DS:SI points to original name for ex open ;AN003;
1044 mov es,incoming_DS ; but this code wants ES:SI to point to it ;AN003;
1045 lea di,fname ; DS:DI points to fname area ;AN003;
1046 jmp eo_skip1 ; skip the old stuff ;AN003;
1047 ;AN003;
1048no_eo1: ;AN003;
1049 les si,dword ptr handle_ptr ; ES:SI points to original handle
1050 lea di,fname ; DS:DI points to fname area
1051eo_skip1: ;AN003;
1052 call get_fname ; strip just the 8.3 filename from
1053 ; the original ASCIIZ string
1054 call address_path ; address the path
1055 cmp es: byte ptr [di],";" ; is append list null ?
1056 jump E,no_more_to_try2 ; exit append
1057 popff ;
1058 mov si,di ; pointer to list of appended directories
1059 pushf ; push flags onto stack just for the
1060 ; popff below
1061
1062try_another2:
1063 popff
1064 lea di,try_dir ; buffer to be filled with dir name
1065 ; to try
1066 push cx ; save CX
1067 call get_app_dir ; this routine will return with a dir
1068 ; to try in try_dir
1069 mov true_name_count,cx ; save number of chars for later us ;AN003;
1070 pop cx
1071 mov app_dirs_ptr,si ; save updated pointer
1072
1073
1074;-----------------------------
1075try_app_dir2:
1076
1077 call append_fname ; glue the filename onto the end of the dir to try
1078
1079
1080; we now have an ASCIIZ string that includes the original 8.3 filename
1081; and one of the appended dir paths
1082
1083 mov ax,incoming_AX
1084 mov cx,incoming_CX
1085 lea dx,try_dir ; point to new ASCIIZ string
1086
1087 cmp incoming_AX,ext_handle_opn*256+0 ; extended open? ;AN003;
1088 jne not_eo1 ;AN003;
1089 ;AN003;
1090; this is an extended open call ;AN003;
1091 ;AN003;
1092 save_regs ;AN003;
1093 ;AN003;
1094 mov si,dx ; ext open wants DS:SI -> filename ;AN003;
1095 push cs ;AN003;
1096 pop ds ;AN003;
1097 ;AN003;
1098 mov ax,incoming_AX ; function code ;AN003;
1099 mov bx,incoming_BX ; mode word ;AN003;
1100 mov cx,incoming_CX ; attributes ;AN003;
1101 mov dx,incoming_DX ; flags ;AN003;
1102 mov es,incoming_ES ; ES:DI parm_list pointer ;AN003;
1103 mov di,incoming_DI ;AN003;
1104 ;AN003;
1105 call int_21 ; try the extended open ;AN003;
1106 ;AN003;
1107 restore_regs ;AN003;
1108 pushf ; save flags ;AN003;
1109; mov es,incoming_ES ; restore es as it was ;AN003;
1110 jmp not_exec2 ; go find out what happened ;AN003;
1111 ;AN003;
1112 ;AN003;
1113not_eo1: ;AN003;
1114 cmp incoming_AX,exec_proc*256+0 ; exec pgm call
1115 jne not_exec1
1116
1117; this is an exec call ;AN003;
1118
1119 push es
1120 push bx
1121 mov ah,get_DTA
1122 call int_21
1123 mov word ptr incoming_DTA+0,bx ; save callers DTA
1124 mov word ptr incoming_DTA+2,es
1125 pop bx
1126 pop es
1127 push ds
1128 push dx
1129 mov ah,set_DTA
1130 lea dx,exec_DTA ; set for fake exec search
1131 push cs
1132 pop ds
1133 call int_21
1134 pop dx
1135 pop ds
1136 mov ah,handle_fnd1 ; precess search by finds
1137 mov expected_error,handle_no_more_files
1138
1139not_exec1:
1140
1141 push es ; save append's ES
1142 push bx ; save append's BX
1143 mov es,incoming_ES ; must restore ES before doing the call ; fix for P37, GGA 9/10/87
1144 mov bx,incoming_BX ; must resatore user's ES:BX
1145
1146 call int_21 ; try the open
1147
1148 pop bx ; restore append's BX
1149 pop es ; restore append's es
1150 pushf ; save flags
1151 cmp incoming_AX,exec_proc*256+0 ; exec pgm call
1152 jne not_exec2
1153 push ds
1154 push dx
1155 push ax
1156 mov ah,set_DTA
1157 mov dx,word ptr incoming_DTA+0 ; restore callers DTA
1158 mov ds,word ptr incoming_DTA+2
1159 call int_21
1160 pop ax
1161 pop dx
1162 pop ds
1163not_exec2:
1164 popff
1165 pushf
1166 jnc found_it_remote ; all done
1167
1168 cmp crit_err_flag,0 ; process critical errors
1169 jne check_crit_err
1170
1171 cmp ax,handle_path_not_found ; normal errors
1172 je should_we_look_more
1173
1174 cmp ax,expected_error ; was the error we found file not found?
1175 je should_we_look_more ; yes, look some more
1176 jmp no_more_to_try2 ; no, any other error, we pack it in
1177
1178should_we_look_more:
1179 mov si,app_dirs_ptr ; yes, see if we should look more
1180 cmp si,null ; should we try again?
1181 je no_more_to_tryx
1182 jmp try_another2 ; yes
1183no_more_to_tryx:
1184 jmp no_more_to_try2
1185
1186check_crit_err:
1187 mov ext_err_flag,1 ; we need to set extended error info
1188 mov ax,expected_error ; make ax look like we got file not found
1189 mov ax_after_21,ax ; save it away so we can restore it below
1190 popff ; get clags from stack
1191 stc ; set the carry flag
1192 pushf ; put 'em back
1193
1194 jmp no_more_to_try2
1195
1196found_it_remote: ; come here only if the file was found in
1197 ; an appended directory
1198 mov ax_after_21,ax ; save AX
1199
1200
1201; ;AN002;
1202; Find out if this process has the true_name flag set in thier PSP. ;AN002;
1203; At this point, DS:DX points to the true name of the found file ;AN002;
1204; ;AN002;
1205 ;AN002;
1206 push ax ; save some regs ;AN002;
1207 save_regs
1208 ;AN002;
1209 mov ah,get_PSP ; function code for get PSP operation ;AN002;
1210 call int_21 ; get the PSP, segment returned in BX ;AN002;
1211 mov es,bx ; need to use it as a segment ;AN002;
1212 mov di,PDB_Append ; get pointer to APPEND flag in PDB ;AN002;
1213 ;AN002;
1214 mov ax,es:[di] ; get APPEND flag into AX ;AN002;
1215 test ax,true_name_flag ; is true name flag armed? ;AN002;
1216 jz no_true_name ; no, don't copy true name ;AN002;
1217 ;AN002;
1218 sub ax,true_name_flag ; clear true name flag ;AN002;
1219 mov es:[di],ax ; save it in PSP ;AN002;
1220 ;AN002;
1221 mov di,word ptr handle_ptr+0 ; get user's buffer pointer ES:DI ;AN002;
1222 mov es,word ptr handle_ptr+2 ;AN002;
1223
1224; find out if this is a handle find or an open or an exec
1225
1226 cmp incoming_AX,exec_proc*256+0 ; exec?
1227 je no_true_name ; yes, do nothing with true name
1228 ;AN002;
1229 cmp incoming_AX,handle_fnd1*256+0 ; handle find?
1230 jne not_hf ; no, go do the easy stuff
1231 ;AN002;
1232; function we are doing is a handle find, must get part of true_name
1233; string from append path, part from DTA. Messy!
1234
1235 lea si,try_dir ; buffer that has last APPEND path tried
1236
1237 mov cx,true_name_count ; get number of chars in true_name dir ;AN002;
1238
1239copy_true_name_loop2:
1240 mov ah,ds:[si] ; get byte of append dir path ;AN002;
1241 mov es:[di],ah ; copy it to user's buffer ;AN002;
1242 inc si ; in this loop, the null is not copied ;AN002;
1243 inc di ;AN002;
1244 loop copy_true_name_loop2 ;AN002;
1245
1246; put in the "\"
1247
1248 mov ah,"\" ; get a \
1249 mov es:[di],ah ; copy it
1250 inc di ; increment pointer
1251
1252; we have copied the first part of the string, now get the real filename
1253; from the DTA
1254
1255 push es
1256 push bx
1257
1258 mov ah,get_DTA
1259 call int_21
1260 push es
1261 pop ds
1262 mov si,bx
1263
1264 pop bx
1265 pop es
1266
1267copy_true_name_loop3:
1268 mov ah,ds:[si+30] ; get byte of actual filename ;AN002;
1269 mov es:[di],ah ; copy it to user's buffer ;AN002;
1270 cmp ah,null ; is it a null? ;AN002;
1271 je true_name_copied ; yes, all done ;AN002;
1272 inc si ; in this loop the null is copied ;AN002;
1273 inc di ;AN002;
1274 jmp copy_true_name_loop3 ;AN002;
1275
1276not_hf:
1277 mov si,dx ; make DS:SI point to true name
1278
1279copy_true_name_loop: ;AN002;
1280 mov ah,ds:[si] ; get byte of true name ;AN002;
1281 mov es:[di],ah ; copy it to user's buffer ;AN002;
1282 cmp ah,null ; is it a null? ;AN002;
1283 je true_name_copied ; yes, all done ;AN002;
1284 inc si ;AN002;
1285 inc di ;AN002;
1286 jmp copy_true_name_loop ;AN002;
1287 ;AN002;
1288true_name_copied: ;AN002;
1289 ;AN002;
1290no_true_name: ;AN002;
1291 restore_regs ; restore some regs ;AN002;
1292 pop ax
1293 ;AN002;
1294 ;AN002;
1295no_more_to_try2:
1296
1297 call ctrl_break_restore ; restore normal control break address
1298 call crit_err_restore ; restore normal critical error address
1299
1300; find out if there is a need to set the extended error code
1301
1302 cmp ext_err_flag,0 ; do we need to set the extended error code?
1303 je no_ext_err2 ; no, finish up
1304 lea dx,ext_err_dpl
1305 call set_ext_err_code ; yes, go set the ext error info
1306
1307; reset flags, and pack it in
1308
1309no_ext_err2:
1310 popff
1311 restore_regs ; restore registers
1312 pushf ; put the real flags on the stack
1313
1314 jmp reset_stack ; fix stack, ret to caller
1315
1316page
1317;-------------------------------------------------------------------
1318;
1319; support routines for drive and path mode checking
1320;
1321;
1322;-------------------------------------------------------------------
1323
1324
1325check_for_drive: ; input: ES:SI -> original string
1326 ; output: AX = 0 no drive present
1327 ; output: AX = -1 drive present
1328
1329 xor ax,ax ; assume no drive letter present
1330
1331 cmp es: byte ptr [si+1],':' ; is the second char a ":"?
1332 jne exit_check_for_drive ; no, skip setting the flag
1333
1334 mov ax,-1 ; yes, set the flag
1335
1336exit_check_for_drive:
1337
1338 ret
1339
1340;-------------------------------------------------------------------
1341
1342check_for_path: ; input: ES:SI -> original string
1343 ; output: AX = 0 no path present
1344 ; output: AX = -1 path present
1345
1346 push si ; save pointer
1347
1348 xor ax,ax ; assume no path present
1349
1350
1351; walk the string and look for "/", or "\". Any of these mean that a
1352; path is present
1353
1354walk_handle_string:
1355
1356 push ax ;AN006;
1357 mov al,es: byte ptr [si] ; is this a dbcs char? ;AN006;
1358 call Chk_DBCS ;AN006;
1359 pop ax ;AN006;
1360 ;AN006;
1361 jnc no_dbcs1 ; no, keep looking ;AN006;
1362
1363 add si,2 ; yes, skip it and the next char ;AN006;
1364 jmp walk_handle_string ; the next char could be a "\", but ;AN006;
1365 ; would not mean a path was found ;AN006;
1366 ;AN006;
1367no_dbcs1: ;AN006;
1368 cmp es: byte ptr [si],"\" ; is the char a "\"?
1369 je found_path ; yes, set flag and return
1370 cmp es: byte ptr [si],"/" ; is the char a "/"?
1371 je found_path ; yes, set flag and return
1372 cmp es: byte ptr [si],0 ; is the char a null
1373 je exit_check_for_path ; yes, got to the end of the
1374 ; handle string
1375
1376 inc si ; point to next char
1377 jmp walk_handle_string ; and look again
1378
1379found_path:
1380 mov ax,-1 ; yes, set the flag
1381
1382exit_check_for_path:
1383 pop si ; restore si
1384 ret
1385
1386page
1387;-----------------------------------------------------------------------------
1388; Entry point for interrupt 2f handler
1389;-----------------------------------------------------------------------------
1390
1391intfcn_hook:
1392 cmp ah,append_2f ; is this function call for append?
1393;;;;;; je do_appends ; @@12
1394 jne ih_10 ; @@12
1395 jmp do_appends ; @@12
1396ih_10: ; @@12
1397 cmp ah,applic_2f ; is this function call for applications
1398 je do_applic
1399 jmp pass_it_on
1400
1401do_applic:
1402 cmp dx,-1 ; not COMMAND call
1403 jump NE,pass_it_on
1404 cmp al,0 ; match name request
1405 jne ck01
1406
1407 mov cmd_buf,bx ; save CMDBUF offset
1408 call check_cmd_name
1409 jne no_internal1
1410 mov al,append_inst ; inidicate I want this command
1411no_internal1:
1412 iret
1413
1414ck01:
1415 cmp al,1 ; match name request
1416 jne ck02
1417
1418; save pointer to parser
1419
1420 mov word ptr pars_off+0,di ; ES:DI points to COMMAND.COM's parser
1421 mov word ptr pars_off+2,es ; save it for later
1422
1423 mov cmd_env,bx ; save env pointer address
1424 call check_cmd_name
1425 jne no_internal2
1426 call COMMAND_begin ; process internal command
1427no_internal2:
1428 iret
1429
1430ck02:
1431; cmp al,2 ; set COMMAND active ; @@13; @@09
1432; jne ck03 ; @@13; @@09
1433; mov cmd_active,1 ; @@13; @@09
1434; iret ; @@13; @@09
1435ck03: ; @@13; @@09
1436; cmp al,3 ; set COMMAND in active ; @@13; @@09
1437; jne ck04 ; @@13; @@09
1438; mov cmd_active,0 ; @@13; @@09
1439; iret ; @@13; @@09
1440ck04: ; @@13; @@09
1441 jmp pass_it_on
1442
1443;*******************************************************************************
1444; The following old code is commented out. @@12
1445;*******************************************************************************
1446;check_cmd_name: ; see if internal APPEND
1447; push es
1448; push cs
1449; pop es
1450; push di
1451; push cx
1452; push si
1453; cmp ds:byte ptr[si],6 ; length must match
1454; jne skip_comp
1455; comp append_id,6,[si+1] ; see if APPEND is command
1456;skip_comp:
1457; pop si
1458; pop cx
1459; pop di
1460; pop es
1461; ret
1462;*********************************************************************
1463check_cmd_name: ; See if APPEND @@12
1464 push ax ; @@12
1465 push si ; @@12
1466 push cx ; @@12
1467 push di ; @@12
1468 push es ; @@12
1469 mov si,cmd_buf ; DS:SI -> cmd buf ended with cr @@12
1470 add si,2 ; 1st 2 bytes garbage @@12
1471 ; @@12
1472ccn_skip_leading: ; @@12
1473 lodsb ; skip leading stuff @@12
1474
1475 call Chk_DBCS ; find out if this is DBCS ;AN006;
1476 jnc no_dbcs2 ; no, keep looking ;AN006;
1477 lodsb ; yes, skip it and the next byte ;AN006;
1478 jmp ccn_skip_leading ; the second byte will be skipper when ;AN006;
1479 ; we go back through ;AN006;
1480
1481no_dbcs2: ;AN006;
1482 cmp al," " ; blank @@12
1483 je ccn_skip_leading ; @@12
1484 cmp al,tab_char ; tab @@12
1485 je ccn_skip_leading ; @@12
1486 cmp al,"," ; comma @@12
1487 je ccn_skip_leading ; @@12
1488 cmp al,"=" ; equal @@12
1489 je ccn_skip_leading ; @@12
1490 cmp al,";" ; semi-colon @@12
1491 je ccn_skip_leading ; @@12
1492 cmp al,"\" ; back slash @@12
1493 je ccn_skip_leading ; @@12
1494 cmp al,cr ; bad ret for early terminate @@12
1495 jne ccn_02 ; @@12
1496 cmp al,0 ; reset z for no match @@12
1497 jmp ccn_ret ; @@12
1498ccn_02: ; @@12
1499 mov di,si ; di -> beginning of possible @@12
1500 dec di ; "APPEND " string @@12
1501 lodsb ; @@12
1502 cmp al,":" ; @@12
1503 jne ccn_cont ; @@12
1504 mov di,si ; @@12
1505 lodsb ; @@12
1506ccn_cont: ; @@12
1507 call Chk_DBCS ;AN006;
1508 jnc no_dbcs3 ; no, carry on ;AN006;
1509 add si,2 ; yes, skip it and the next byte ;AN006;
1510 jmp ccn_20 ;AN006;
1511 ;AN006;
1512no_dbcs3: ;AN006;
1513 cmp al,"\" ; move di up upon "\" @@12
1514 jne ccn_20 ; @@12
1515 mov di,si ; @@12
1516ccn_10: ; @@12
1517 lodsb ; @@12
1518 jmp ccn_cont ; @@12
1519ccn_20: ; @@12
1520 cmp al," " ; look for separator @@12
1521 je ccn_30 ; if found, then have command @@12
1522 cmp al,"=" ; @@12
1523 je ccn_30 ; @@12
1524 cmp al,cr ; @@12
1525 je ccn_30 ; @@12
1526 cmp al,tab_char ; @@12
1527 je ccn_30 ; @@12
1528 cmp al,"," ; @@12
1529 je ccn_30 ; @@12
1530 cmp al,";" ; @@12
1531 jne ccn_10 ; @@12
1532
1533ccn_30: ; @@12
1534 sub si,di ; @@12
1535 cmp si,7 ; @@12
1536 jne ccn_ret ; no match @@12
1537 ; @@12
1538 mov si,di ; @@12
1539 chkchar "A" ; look for "APPEND" string @@12
1540 chkchar "P" ; @@12
1541 chkchar "P" ; @@12
1542 chkchar "E" ; @@12
1543 chkchar "N" ; @@12
1544 chkchar "D" ; @@12
1545 ; exit with z set for match @@12
1546ccn_ret: ; @@12
1547 pop es ; @@12
1548 pop di ; @@12
1549 pop cx ; @@12
1550 pop si ; @@12
1551 pop ax ; @@12
1552 ret ; @@12
1553
1554page
1555;------------------------------------------------------------------- ;AN000;
1556; ;AN000;
1557; do_appends ;AN000;
1558; ;AN000;
1559; This is the INT 2F handler for the APPEND ;AN000;
1560; subfunction ;AN000;
1561; ;AN000;
1562; New functions added for 3.30: ;AN000;
1563; ;AN000;
1564; ;AN000;
1565; ;AN000;
1566; Get /X status ;AN000;
1567; ;AN000;
1568; Input: AX = B706 ;AN000;
1569; ;AN000;
1570; Output: BX = 0000 /X not active ;AN000;
1571; = 0001 /X active ;AN000;
1572; ;AN000;
1573; ;AN000;
1574; ;AN000;
1575; Set /X status ;AN000;
1576; ;AN000;
1577; Input: AX = B707 ;AN000;
1578; ;AN000;
1579; BX = 0000 turn /X off ;AN000;
1580; BX = 0001 turn /X on (active) ;AN000;
1581; ;AN000;
1582;------------------------------------------------------------------- ;AN000;
1583;
1584do_appends:
1585 cmp al,are_you_there ; is the function request for presence?
1586 jne ck1
1587
1588 mov al,-1 ; set flag to indicate we are here
1589 iret ; return to user
1590
1591ck1:
1592 cmp al,dir_ptr ; is the function request for pointer?
1593 jne ck2
1594
1595 les di,dword ptr dirlst_offset ; return dirlist pointer to caller
1596 iret
1597
1598ck2:
1599 cmp al,get_app_version ; is the function request for version?
1600 jne ck3 ; no, check for next function
1601
1602 mov ax,-1 ; yes, set NOT NETWORK version
1603 iret
1604
1605ck3:
1606 cmp al,tv_vector ; is the function request for TV vector?
1607 jne ck4 ; no, check for old dir ptr
1608
1609 mov tv_vec_seg,es ; yes, save the TV vector
1610 mov tv_vec_off,di
1611
1612 push cs ; set ES:DI to tv ent pnt
1613 pop es ;
1614 lea di,tv_entry
1615
1616 xor byte ptr tv_flag,TV_TRUE ; set flag ;AN000;
1617 iret
1618
1619ck4: ;
1620 cmp al,old_dir_ptr ; is it the old dir ptr
1621 jne ck5 ; no, pass it on
1622
1623 push ds
1624 push cs
1625 pop ds
1626
1627 call sysloadmsg ;AN000;
1628 ;AN000;
1629 mov ax,1 ; message number ;AN000;
1630 mov bx,STDERR ; handle ;AN000;
1631 xor cx,cx ; sub count ;AN000;
1632 xor dl,dl ; no input ;AN000;
1633 mov dh,-1 ; message class ;AN000;
1634 call sysdispmsg ;AN000;
1635
1636 pop ds
1637 mov al,1
1638 call terminate ; exit to DOS ; @@05
1639
1640ck5: ;
1641 cmp al,DOS_version ; is it the new version check
1642 jne ck6 ; no, pass it on
1643
1644 mov ax,mode_flags ; set mode bits
1645 xor bx,bx ; destroy registers
1646 xor cx,cx
1647 mov dl,byte ptr version_loc ; major version num
1648 mov dh,byte ptr version_loc+1 ; minor version num
1649 iret
1650
1651ck6: ;AN000;
1652 cmp al,get_state ; is it get state call? ;AN001;
1653 jne ck7 ; no, look some more ;AN000;
1654 ;AN000;
1655 mov bx,mode_flags ; get mode bits ;AN000;
1656 iret ; return to user ;AN000;
1657 ;AN000;
1658ck7: ;AN000;
1659 cmp al,set_state ; is it set state call? ;AN001;
1660 jne ck8 ; no, look some more ;AN000;
1661 ;AN000;
1662 mov mode_flags,bx ; save the new state ;AN001;
1663 iret ;AN000;
1664 ;AN000;
1665ck8: ;AN000;
1666
1667 cmp al,true_name ; is it the set true name function? ;AN002;
1668 jne ck9 ; no, look some more ;AN002;
1669 ;AN002;
1670 push ax ; save some regs ;AN002;
1671 push bx ;AN002;
1672 push es ;AN002;
1673 push di ;AN002;
1674 ;AN002;
1675 ;AN002;
1676; get the PSP and then get the APPEND flags byte
1677
1678 mov ah,get_PSP ; function code to get PSP address ;AN002;
1679 call int_21 ; get the PSP address ;AN002;
1680 mov es,bx ; need to use it as a segment ;AN002;
1681 mov di,PDB_Append ; get pointer to APPEND flag in PDB ;AN002;
1682 ;AN002;
1683; is the flag already set?
1684
1685 mov ax,es:[di] ; get APPEND flag into AX ;AN002;
1686 test ax,true_name_flag ; is it set? ;AN002;
1687 jnz no_set_true_name ; yes, do nothing ;AN002;
1688 ;AN002;
1689; set the true_name flag
1690
1691set_true_name: ;AN002;
1692 add ax,true_name_flag ; set true name flag ;AN002;
1693 mov es:[di],ax ; save in PSP ;AN002;
1694 ;AN002;
1695no_set_true_name:
1696 pop di ; restore some regs ;AN002;
1697 pop es ;AN002;
1698 pop bx ;AN002;
1699 pop ax ;AN002;
1700 ;AN002;
1701 iret ; return ;AN002;
1702 ;AN002;
1703ck9: ;AN002;
1704
1705;-------------------------------------------------------------------
1706; fill in additional 2F functions here
1707;-------------------------------------------------------------------
1708
1709pass_it_on: ; the function call (ah) was not for append
1710 jmp dword ptr intfcn_Offset ; jump to old INT 2f
1711
1712page
1713;-----------------------------------------------------------------------------
1714; Entry point for interrupt 24 handler
1715;-----------------------------------------------------------------------------
1716
1717crit_err_handler:
1718
1719 mov crit_err_flag,0ffh ; set critical error flag
1720 mov al,3 ; fail int 21h
1721 iret
1722
1723page
1724;-----------------------------------------------------------------------------
1725; miscellaneous routines
1726;-----------------------------------------------------------------------------
1727;-----------------------------------------------------------------------------
1728; tv_barrier
1729;-----------------------------------------------------------------------------
1730
1731tv_barrier:
1732
1733 cmp tv_flag,TV_TRUE ; in Topview ;AN000;
1734 jne no_barrier
1735
1736 push ax
1737 mov ax,2002h ; wait on DOS barrier
1738 int 2Ah
1739 pop ax
1740no_barrier:
1741 ret
1742
1743;-----------------------------
1744; check_config - this routine is called by both the FCB and handle open
1745; code. I checks the net_config flag to see if it is zero, if so it
1746; does an installation check. If it is non-zero, nothing is done.
1747
1748check_config:
1749
1750 push ax ; save a few registers
1751 push bx
1752
1753; examine the config flag to see if we already know what config we have
1754
1755 cmp net_config,0
1756 jne do_not_look ; we know config already
1757
1758; the flag word has not been set before, go find out what config we have
1759
1760 mov ax,0b800h ; installation code function code
1761 int 2fh ; do the installation check
1762
1763 mov net_config,bx ; save flag word for later
1764
1765do_not_look:
1766 pop bx ;restore regs and leave
1767 pop ax
1768 ret
1769
1770;*( Chk_DBCS ) *************************************************************
1771;* *
1772;* Function: Check if a specified byte is in ranges of the DBCS lead bytes*
1773;* Attention: If your code is resident, comment out the lines marked *
1774;* ;** . *
1775;* *
1776;* Input: *
1777;* AL = Code to be examined *
1778;* *
1779;* *
1780;* Output: *
1781;* If CF is on then a lead byte of DBCS *
1782;* *
1783;* Register: *
1784;* FL is used for the output, others are unchanged. *
1785;* *
1786;***************************************************************************
1787Chk_DBCS PROC
1788 PUSH DS
1789 PUSH SI
1790; CMP CS:DBCSEV_SEG,0 ; ALREADY SET ? ;**
1791; JNE DBCS00 ;**
1792 MOV SI,OFFSET EVEV ; SET DEFAULT OFFSET ;**
1793 PUSH CS ;**
1794 POP DS ; SET DEFAULT SEGMENT ;**
1795 PUSH AX
1796 MOV AX,6300H ; GET DBCS EV CALL
1797 INT 21H
1798 MOV CS:DBCSEV_OFF,SI ;**
1799 MOV CS:DBCSEV_SEG,DS ;**
1800 POP AX
1801DBCS00:
1802 MOV SI,CS:DBCSEV_OFF ;**
1803 MOV DS,CS:DBCSEV_SEG ;**
1804DBCS_LOOP:
1805 CMP WORD PTR [SI],0
1806 JE NON_DBCS
1807 CMP AL,[SI]
1808 JB DBCS01
1809 CMP AL,[SI+1]
1810 JA DBCS01
1811 STC
1812 JMP DBCS_EXIT
1813DBCS01:
1814 ADD SI,2
1815 JMP DBCS_LOOP
1816NON_DBCS:
1817 CLC
1818DBCS_EXIT:
1819 POP SI
1820 POP DS
1821 RET
1822Chk_DBCS ENDP
1823
1824
1825;-----------------------------
1826; append_fname - glues the fname onto the end of the dir to try
1827
1828append_fname:
1829 push es
1830 push ds
1831 pop es
1832 lea di,try_dir ; destination, sort of (dir name)
1833 lea si,fname ; source (filename)
1834
1835; find the end of the dir name
1836
1837 mov dbcs_fb,-1 ; set flag for no dbcs first byte chars ;AN006;
1838
1839walk_dir_name:
1840 mov al,byte ptr [di] ; get a char from dir name
1841 cmp al,null ; are we at the end?
1842 je end_of_dir ; yes, add on the fname
1843
1844 call Chk_DBCS ; char is in al ;AN006;
1845 jnc no_dbcs4 ; no, keep looking ;AN006;
1846 mov dbcs_fb,di ; save offset ;AN006;
1847 inc di ; skip second byte
1848
1849no_dbcs4:
1850 inc di ; no, keep stepping
1851 jmp walk_dir_name
1852
1853; now it is time to append the filename
1854
1855end_of_dir:
1856 mov al,byte ptr [di-1] ; get last char of dir name
1857 cmp al,"\" ; is it a dir seperator?
1858 jne check_next_dir_sep ; no, check the next dir sep char ;AN006;
1859 ;AN006;
1860 sub di,2 ; yes, must find out if real dir sep ;AN006;
1861 ; or DBCS second byte ;AN006;
1862 cmp dbcs_fb,di ; is the char before our dir sep a DBCS ;AN006;
1863 ; first byte? ;AN006;
1864 jne no_dbcs4a ; no, must check for the next dir sep ;AN006;
1865 ; yes, this means we must put in a dir sep ;AN006;
1866 add di,2 ; restore di ;AN006;
1867 jmp put_in_dir_sep ; put int the dir sep char ;AN006;
1868 ;AN006;
1869no_dbcs4a: ;AN006;
1870 add di,1 ; restore di, then check next dir sep ;AN006;
1871
1872check_next_dir_sep:
1873 cmp al,"/" ; is it the other dir seperator?
1874 je add_fname ; yes, no need to add one
1875put_in_dir_sep: ;AN006;
1876 mov al,"\" ; get dir seperator
1877 stosb ; add to end of dir
1878
1879add_fname:
1880 lodsb ; get a char from fname
1881 stosb ; copy the char
1882 cmp al,null ; are we at the and of the filename?
1883 je eo_name ; yes, all done!
1884 jmp add_fname
1885
1886
1887
1888
1889
1890
1891
1892eo_name:
1893 pop es
1894 ret
1895
1896
1897;-----------------------------
1898; get_fname strips out the 8.3 filename from the original ASCIIZ string
1899;
1900; INPUT: ES:SI points to original string
1901; DS:DI points to area for filename
1902
1903get_fname:
1904
1905 mov bx,si ; save the pointer
1906 mov dbcs_fb,-1 ; set the dbcs flag off ;AN006;
1907
1908gfn1:
1909 mov ah,ES:byte ptr [si] ; get a char from the source
1910 cmp ah,null ; is it a null?
1911 je got_the_end ; yes, we found the end
1912
1913 call chk_dbcs ; is this char a DBCS first byte? ;AN006;
1914 jnc no_dbcs5 ; no, carry on
1915 mov dbcs_fb,si ; yes, save pointer
1916 inc si ; skip second byte
1917
1918no_dbcs5:
1919 inc si ; no, point to next char
1920 jmp gfn1 ; loop till end found
1921
1922got_the_end:
1923 mov ah,ES:byte ptr [si] ; get a char
1924 cmp ah,"/" ; did we find a /
1925 je went_too_far ; yes, we found the start
1926 cmp ah,"\" ; did we find a \
1927 je found_bslash ; yes, we found the start ;AN006;
1928 cmp ah,":" ; did we find a :
1929 je went_too_far ; yes, we found the start
1930 cmp si,bx ; are we back to the original start?
1931 je got_the_beg ; yes, we found the start of the fname
1932 dec si ; step back a char, then look some more
1933 jmp got_the_end
1934
1935found_bslash: ; found a backslash, must figure out if ;AN006;
1936 ; is second byte of DBCS ;AN006;
1937 dec si ; point to next char ;AN006;
1938 cmp si,dbcs_fb ; do they match?
1939 jne no_dbcs5a ; no, fix up si and carry on ;AN006;
1940 dec si ; skip dbcs byte and loop some more ;AN006;
1941 jmp got_the_end ;AN006;
1942
1943no_dbcs5a: ;AN006;
1944 inc si ; went too far by one extra ;AN006;
1945 ;AN006;
1946went_too_far:
1947 inc si ; went one char too far back
1948
1949; ES:SI now points to the beginning of the filename
1950
1951got_the_beg:
1952 mov ah,ES:byte ptr [si] ; get a char from the source
1953 mov byte ptr [di],ah ; copy to dest
1954 cmp ah,null ; did we just copy the end?
1955 je done_with_fname ; yes, all done
1956 inc si ; no, get the next char
1957 inc di
1958 cmp di,offset app_dirs_ptr ; make sure we dont try to copy past the
1959 je done_with_fname ; area
1960 jmp got_the_beg
1961
1962done_with_fname:
1963 ret
1964
1965;-----------------------------
1966; this code executed to return to caller after APPEND's stack has been
1967; initialized
1968
1969reset_stack:
1970
1971; reset the stack ;AN002;
1972
1973 popff ; restore flags from real open
1974 mov ss,Stack_Segment ; Get original stack segment
1975 mov sp,Stack_Offset ; Get original stack pointer
1976 pushf ; put the flags on the old stack
1977
1978
1979;-----------------------------
1980; before jumping to this routine, SS:SP must point to the caller's stack,
1981; and the flags from the real INT 21 operation must have been pushed
1982
1983set_return_flags:
1984
1985; must be sure to clear the true_name flag before leaving ;AN002;
1986 ;AN002;
1987 push ax ; save some regs ;AN002;
1988 push bx ;AN002;
1989 push es ;AN002;
1990 push di ;AN002;
1991 ;AN002;
1992 mov ah,get_PSP ; function code for get PSP operation ;AN002;
1993 call int_21 ; get the PSP, segment returned in BX ;AN002;
1994 mov es,bx ; need to use it as a segment ;AN002;
1995 mov di,PDB_Append ; get pointer to APPEND flag in PDB ;AN002;
1996 ;AN002;
1997 mov ax,es:[di] ; get APPEND flag into AX ;AN002;
1998 test ax,true_name_flag ; is true name flag armed? ;AN002;
1999 jz reset_stack2 ; no, don't copy true name ;AN002;
2000 ;AN002;
2001 sub ax,true_name_flag ; clear true name flag ;AN002;
2002 mov es:[di],ax ; save it in PSP ;AN002;
2003 ;AN002;
2004 ;AN002;
2005reset_stack2: ;AN002;
2006 ;AN002;
2007 pop di ; restore ;AN002;
2008 pop es ;AN002;
2009 pop bx ;AN002;
2010 pop ax ;AN002;
2011 ;AN002;
2012 cmp tv_flag,TV_TRUE ;AN000;
2013 jne tv_flag_not_set
2014
2015 mov ax,2003h ; clear open barrier
2016 int 2Ah
2017
2018
2019; pop down to the old flags on the user's stack
2020
2021tv_flag_not_set:
2022
2023 cmp incoming_AX,exec_proc*256+0 ; need to do exec
2024 jne not_exec3
2025 popff ; discard bad flags
2026 mov ax,incoming_AX ; set exec parms
2027
2028 push ds ; save DS, this must be done ;an005;
2029 ; to pervent DS from being trashed on return to caller ;an005;
2030
2031 push cs
2032 pop ds
2033 lea dx,try_dir
2034 mov bx,incoming_BX
2035 mov es,incoming_ES
2036 call int_21 ; issue the exec
2037
2038 pop ds ; restore DS ; an005;
2039
2040 pushf
2041
2042not_exec3:
2043 popff ; get flags from real int 21 (old stack)
2044 pop temp_IP_save ; save IP, CS
2045 pop temp_CS_save
2046 lahf ; save flags in AH
2047 popff ; pop old flags off stack
2048 sahf ; replace old with new
2049
2050; push the new flags onto the stack, then fix CS and IP on stack
2051
2052 pushf ; push new flags onto stack
2053 push temp_CS_save ; restore IP, CS
2054 push temp_IP_save
2055 mov ax,AX_after_21 ; Set AX as it was after open
2056
2057 call crit_sect_reset ; clear the critical section flag
2058 iret ; return to the calling routine
2059
2060
2061;-----------------------------
2062; This routine is used to extract an appended dir from the dir list
2063; On entry, DS:DI points to an area for the appended dir
2064; and ES:SI points to the source string
2065
2066get_app_dir:
2067
2068 xor cx,cx ; keep a count of chars in cx ;AN003;
2069copy_dir:
2070 mov ah,es:byte ptr [si] ; get the char, and copy it into dest
2071 cmp ah,null ; find a null?
2072 je no_more_dirs ; yes, inform caller that this is the last one
2073
2074 cmp ah,";" ; check to see if we are at the end of a dir
2075 je update_pointer ; yes,
2076
2077 mov byte ptr [di],ah ; if not null or semi-colon, then copy it
2078 inc si ; increment both pointers
2079 inc di
2080 inc cx ; count of chars ;AN003;
2081 jmp copy_dir ; do it some more
2082
2083update_pointer:
2084 inc si ; point to next char
2085 mov ah,es:byte ptr [si] ; get char ; @@16
2086 cmp ah,null ; did we reach the end of the dir list?
2087 je no_more_dirs ;
2088
2089 cmp ah,";" ; is is a semi-colon
2090 je update_pointer
2091 jmp all_done
2092
2093
2094no_more_dirs:
2095 xor si,si ; set end search flag
2096
2097all_done:
2098 mov byte ptr [di],null ; null terminate destination
2099 ret ; return to caller
2100
2101;-----------------------------
2102; set ctrl-break check off
2103; first, save the old state so we can restore it later,
2104; then turn ctrl-break checking off
2105
2106ctrl_break_set:
2107
2108 mov ah,ctrl_break ; function code for ctrl-break check
2109 xor al,al ; 0 = get current state
2110 call int_21 ; call DOS INT 21 handler
2111
2112 mov ctrl_break_state,dl ; save the old ctrl-break state
2113
2114 mov ah,ctrl_break ; function code for ctrl-break check
2115 mov al,01 ; set current state
2116 xor dl,dl ; 0 = off
2117 call int_21 ; call DOS INT 21 handler
2118 ret
2119
2120
2121;-----------------------------
2122; restore ctrl-break checking flag to the way it was
2123ctrl_break_restore:
2124 mov ah,ctrl_break ; function code for ctrl-break check
2125 mov al,01 ; set current state
2126 mov dl,ctrl_break_state ; get the way is was before we messed with it
2127 call int_21 ; call DOS INT 21 handler
2128 ret
2129
2130;-----------------------------
2131; restore ctrl-break checking flag to the way it was
2132ctrl_break_rest:
2133 mov ah,ctrl_break ; function code for ctrl-break check
2134 mov al,01 ; set current state
2135 mov dl,ctrl_break_state ; get the way is was before we messed with it
2136 call int_21
2137 ret
2138
2139;-----------------------------
2140;
2141crit_err_set:
2142 mov crit_err_flag,0 ; clear the critical error flag
2143
2144 mov ax,get_crit_err ; Get INT 24h vector
2145 call int_21 ; call DOS INT 21 handler
2146
2147 mov crit_vector_offset,bx ; Save it
2148 mov ax,es ; es hase segment for resident code
2149 mov crit_vector_segment,ax
2150
2151 lea dx,crit_err_handler ; DS:DX = New INT 21h vector
2152 mov ax,set_crit_err ; function code for setting critical error vector
2153 call int_21 ; call DOS INT 21 handler
2154 ret ; go back to the caller
2155
2156
2157;-----------------------------
2158;
2159crit_err_restore:
2160 push ds ; save ds for this function
2161 mov ax,set_crit_err ; function code for setting critical error vector
2162 mov dx,crit_vector_offset ; get old int 24 offset
2163 mov ds,crit_vector_segment ; get old int 24 segment
2164 call int_21 ; call INT 21
2165 pop ds
2166 ret
2167
2168;-----------------------------
2169; crit_sect_set - issues an enque request to the server to protect
2170; against reentry. This request is issued only if the network is started,
2171; and then, only for RCV, MSG, and SRV configurations
2172crit_sect_set:
2173 push ax
2174 push bx
2175 push di
2176 push es
2177
2178 mov ax,net_config ; check the server config flag
2179 cmp ax,0 ; is it zero?
2180 je dont_set_crit_sect ; yes, skip it
2181
2182 cmp ax,redir_flag ; is it a redir?
2183 je dont_set_crit_sect ; yes, skip it
2184 ; otherwise, issue the request
2185
2186; the config flag was not zero or redir, so set crit section
2187
2188 mov ah,NETSYSUTIL
2189 mov al,NETENQ
2190 mov bx,TCBR_APPEND
2191 int 2Ah
2192
2193dont_set_crit_sect: ; because of the config we don't want
2194 pop es ; to set critical section
2195 pop di
2196 pop bx
2197 pop ax
2198 ret
2199
2200;-----------------------------
2201;
2202crit_sect_reset:
2203 push ax
2204 push bx
2205
2206 mov ax,net_config ; check the server config flag
2207 cmp ax,0 ; is it zero?
2208 je not_set ; yes, skip it
2209
2210 cmp ax,redir_flag ; is it a redir?
2211 je not_set ; yes, skip it
2212
2213 mov ah,NETSYSUTIL ; turn critical section off
2214 mov al,NETDEQ
2215 mov bx,TCBR_APPEND
2216 int 2Ah
2217
2218not_set:
2219 pop bx
2220 pop ax
2221 ret
2222
2223
2224;-----------------------------
2225; save_first_ext_err - this routine is used to save the extended
2226; error info after the first FCB open.
2227save_first_ext_err:
2228
2229 push ax
2230
2231 mov ax,ext_err_dpl.DPL_AX ; copy all registers
2232 mov save_ext_err.DPL_AX,ax
2233 mov ax,ext_err_dpl.DPL_BX
2234 mov save_ext_err.DPL_BX,ax
2235 mov ax,ext_err_dpl.DPL_CX
2236 mov save_ext_err.DPL_CX,ax
2237 mov ax,ext_err_dpl.DPL_DX
2238 mov save_ext_err.DPL_DX,ax
2239 mov ax,ext_err_dpl.DPL_SI
2240 mov save_ext_err.DPL_SI,ax
2241 mov ax,ext_err_dpl.DPL_DI
2242 mov save_ext_err.DPL_DI,ax
2243 mov ax,ext_err_dpl.DPL_DS
2244 mov save_ext_err.DPL_DS,ax
2245 mov ax,ext_err_dpl.DPL_ES
2246 mov save_ext_err.DPL_ES,ax
2247
2248 pop ax
2249 ret
2250
2251;-----------------------------
2252; get_ext_err_code - this routine is used to get the extended error
2253; info for the error that cause append to start its search
2254
2255get_ext_err_code:
2256 push ax ; save register that are changed by this
2257 push bx ; DOS function
2258 push cx
2259 push di
2260 push si
2261 push es
2262 push ds
2263
2264; get the extended error information
2265
2266 mov ah,59h ; function code for get extended error
2267 xor bx,bx ; version number
2268 call int_21 ; get the extended error
2269
2270; save it away in a DPL for set_ext_error_code
2271; all fields in the DPL will be filled in except the last three,
2272; which will be left at zero
2273
2274 mov ext_err_dpl.DPL_AX,ax
2275 mov ext_err_dpl.DPL_BX,bx
2276 mov ext_err_dpl.DPL_CX,cx
2277 mov ext_err_dpl.DPL_DX,dx
2278 mov ext_err_dpl.DPL_SI,si
2279 mov ext_err_dpl.DPL_DI,di
2280 mov ext_err_dpl.DPL_DS,ds
2281 mov ext_err_dpl.DPL_ES,es
2282
2283
2284; restore regs and return
2285
2286 pop ds
2287 pop es ; restore registers
2288 pop si
2289 pop di
2290 pop cx
2291 pop bx
2292 pop ax
2293 ret
2294
2295;-----------------------------
2296; set_ext_err_code - this routine is used to get the extended error
2297; info for the error that cause append to start its search
2298; CS:DX points to return list
2299set_ext_err_code:
2300 push ax ; save register that are changed by this
2301 push ds ; DOS function
2302
2303; get the extended error information
2304
2305 mov ah,DOSSERVER ; function code for DOSSERVER call
2306 mov al,DOSSETERROR ; sub-function code for set extended error
2307 push cs
2308 pop ds
2309 call int_21 ; set the extended error
2310
2311; restore regs and return
2312
2313 pop ds ; restore registers
2314 pop ax
2315 ret
2316page
2317;-----------------------------
2318; This routine is used to initiate DOS calls from within the APPEND interrupt
2319; handlers. An INT instruction can not be used because it would cause APPEND
2320; to be re-entered.
2321;
2322; SS, SP saved incase call is EXEC which blows them away
2323int_21: ;
2324 cmp tv_flag,TV_TRUE ; see if being re-entered ;AN000;
2325 jne use_old_vec ; yes, pass through to DOS
2326
2327 pushf ; to comp for iret pops
2328 call dword ptr tv_vec_off ; Call INT 21h
2329 ret ;
2330
2331use_old_vec:
2332 cmp vector_segment,0 ; not installed yet
2333 je use_int
2334
2335 pushf ; to comp for iret pops
2336 call dword ptr vector_offset ; Call INT 21h
2337 ret ;
2338
2339use_int:
2340 int DOS_function
2341 ret
2342page
2343;-----------------------------
2344; This routine is used to locate the current APPEND path string
2345; result to ES:DI
2346
2347address_path:
2348address_status: ; @@13
2349 test mode_flags,E_mode
2350 jnz get_env_mode
2351
2352address_pathx:
2353 mov ax,append_2f*256+dir_ptr ; get from buffer
2354 int int_function
2355 clc
2356 ret
2357
2358get_env_mode: ; get from environment
2359; cmp cmd_active,0 ; different logic ; @@13; @@09
2360; jne use_cmd_env ; if in COMMAND ; @@13; @@09
2361 push bx
2362 mov ah,get_PSP
2363 call int_21 ; get the PSP
2364 mov es,bx
2365 mov bx,002ch ; address environment
2366 mov ax,es:word ptr[bx]
2367 mov es,ax
2368 pop bx
2369 cmp ax,0 ; PSP pointer is set
2370 je address_pathx ; @@13
2371use_cmd_env: ; @@13
2372; cmp cmd_env,0 ; have not set my pointer yet
2373; je address_pathx ; @@13
2374; mov es,cmd_env ; @@13
2375env_mode1:
2376 mov di,0 ; start at start
2377 cmp es:byte ptr[di],0 ; no environment
2378 je no_appendeq
2379find_append:
2380 cmp es:word ptr[di],0 ; at environment end
2381 je no_appendeq
2382 push di
2383 push si
2384 push cx
2385 push ds
2386 push cs
2387 pop ds
2388 comp ,6+1,append_id ; string = "APPEND="
2389 pop ds
2390 pop cx
2391 pop si
2392 pop di
2393 je at_appendeq
2394 inc di
2395 jmp find_append
2396at_appendeq: ; must insure this is @@17
2397 cmp di,0 ; genuine "APPEND=" string @@17
2398 je at_appendeq_genuine ; if start of environ ok @@17
2399 dec di ; else check that 0 @@17
2400 cmp es:byte ptr[di],0 ; precedes string @@17
2401 je at_appendeq_10 ; jmp if ok @@17
2402 add di,8 ; else cont.search after @@17
2403 jmp find_append ; "=" @@17
2404at_appendeq_10: ; @@17
2405 inc di ; @@17
2406at_appendeq_genuine: ; @@17
2407 add di,6+1 ; skip APPEND=
2408 cmp es:byte ptr[di],0 ; null value
2409 je no_appendeq ; treat as not found
2410 cmp es:byte ptr[di]," "
2411 je no_appendeq
2412 cmp es:byte ptr[di],";"
2413 je no_appendeq
2414 clc ; set ok
2415 ret
2416
2417no_appendeq: ; not found, use default
2418 lea di,semicolon ; null list
2419 push cs
2420 pop es
2421 stc ; set error
2422 ret
2423
2424;----------------------------- ; @@03
2425; This routine is used to locate the current APPEND path string ; @@03
2426; result to ES:DI. Used by APPEND status. ; @@03
2427
2428;address_status: ; @@13; @@03
2429; test mode_flags,E_mode ; @@13; @@03
2430; jump Z,address_pathx ; @@13; @@03
2431; jmp use_cmd_env ; @@13; @@03
2432
2433cap_dl: ; convert dl to uppercase
2434 cmp dl,"a" ; find out if we have a lower case; @@14
2435 jb cap_dlx ; char ; @@14
2436 cmp dl,"z" ; @@14
2437 ja cap_dlx ; @@14
2438 sub dl,"a"-"A" ; convert char to upper case ; @@14
2439cap_dlx:
2440 ret
2441
2442; end_address: ; this is the end of the TSR stuff ;AN002;
2443
2444page
2445;-----------------------------------------------------------------------------
2446; Main routine. Used to determine if APPEND has been loaded
2447; before. If not, load resident portion of APPEND. Then handle setting
2448; or displaying appended directory list.
2449;-----------------------------------------------------------------------------
2450
2451main_begin: ; DOS entry point
2452
2453 mov ax,seg mystack ; set up stack
2454 mov ss,ax
2455 lea sp,mystack
2456
2457 cld
2458
2459 mov res_append,0 ; set external copy ; @@05
2460
2461 push cs ; make DS point to CS
2462 pop ds
2463
2464 push cs ; make ES point to CS
2465 pop es
2466
2467
2468; find out if append has been loaded ; @@04
2469 ; @@04
2470 mov ah,append_2f ; int 2f function code for append ; @@04
2471 mov al,are_you_there ; function code to ask if append ; @@04
2472 ; has been loaded ; @@04
2473 int int_function ; @@04
2474 ; @@04
2475 cmp al,append_inst ; is append there? ; @@04
2476 jne not_there_yet ; no ; @@04
2477
2478 mov dx,0 ; set for network version ; @@07
2479 mov ah,append_2f ; int 2F function code for append ; @@07
2480 mov al,DOS_version ; function code for get version ; @@07
2481 int int_function ; @@07
2482 cmp dx,word ptr version_loc ; does the version match? ; @@07
2483 jne bad_append_ver ; no, cough up an error messsage ; @@07
2484
2485
2486 call sysloadmsg ;AN000;
2487 ;AN000;
2488 mov ax,9 ; message number ;AN000;
2489 mov bx,STDERR ; handle ;AN000;
2490 xor cx,cx ; sub count ;AN000;
2491 xor dl,dl ; no input ;AN000;
2492 mov dh,-1 ; message class ;AN000;
2493 call sysdispmsg ;AN000;
2494; mov cx,len_second_APPEND_msg; length of string ;AN000; ; @@04
2495; lea dx,second_APPEND_msg ; second load message ;AN000; ; @@04
2496; call print_STDERR ; display error message ;AN000; ; @@04
2497; lea dx,crlf ; carriage return, line feed ; @@04
2498; mov cx,crlf_len ; length of string ; @@04
2499; call print_STDERR ; @@04
2500 ; @@04
2501 mov al,0fch ; second load ; @@05
2502 call terminate ; exit to DOS ; @@05
2503
2504bad_append_ver: ; append version mismatch ; @@07
2505 call sysloadmsg ;AN000;
2506 ;AN000;
2507 mov ax,1 ; message number ;AN000;
2508 mov bx,STDERR ; handle ;AN000;
2509 xor cx,cx ; sub count ;AN000;
2510 xor dl,dl ; no input ;AN000;
2511 mov dh,-1 ; message class ;AN000;
2512 call sysdispmsg ;AN000;
2513; mov cx,len_bad_append_msg ;AN000; ; @@07
2514; lea dx,bad_append_msg ; bad app message ;AN000; ; @@07
2515; call print_STDERR ;AN000; ; @@07
2516; lea dx,crlf ; carriage return, line feed ; @@07
2517; mov cx,crlf_len ; length of string ; @@07
2518; call print_STDERR ; @@07
2519 mov ax,0feh ; bad APPEND version ; @@05
2520 call terminate ; exit to DOS ; @@05
2521
2522not_there_yet: ; @@04
2523
2524 mov cs:initial_pass,-1 ; set a flag for initial pass ;AN007;
2525 call do_command ; do actual APPEND
2526
2527 mov bx,4 ; close all standard files
2528do_closes:
2529 mov ah,3eh ; close file handle
2530 call int_21
2531 dec bx
2532 jns do_closes
2533
2534 call set_vectors ; set append vectors on success ; @@05
2535
2536 call Release_Environment ; release the environmental vector space ;an007; dms;
2537
2538 lea dx,end_address+15 ; normal end
2539 mov cl,4 ; calc end address in paragraphs
2540 shr dx,cl
2541 mov ah,get_PSP ; calc space from PSP to my code ; @@02
2542 call int_21 ; @@02
2543 mov ax,cs ; @@02
2544 sub ax,bx ; @@02
2545 add dx,ax ; calc length to keep ; @@02
2546 mov al,0 ; exit with no error
2547 mov ah,term_stay
2548 call int_21
2549
2550page
2551
2552COMMAND_begin: ; COMMAND entry point
2553 save_regs
2554 mov word ptr cmd_name@+0,si ; save internal command buffer @
2555 mov word ptr cmd_name@+2,ds
2556 cld
2557
2558 mov abort_sp,sp ; save sp for aborts ; @@05
2559 mov res_append,1 ; set resident copy ; @@05
2560 call do_command ; do actual APPEND
2561abort_exit: ; exit to abort append ; @@05
2562 mov sp,abort_sp ; @@05
2563
2564 push es
2565 push di
2566 les di,cmd_name@
2567 mov es:byte ptr[di],0 ; set no command now
2568 pop di
2569 pop es
2570
2571 cmp ax,0 ; error
2572 jne no_E_mode
2573 test mode_flags,E_mode ; no /E processing
2574 jz no_E_mode
2575
2576 mov ax,append_2f*256+dir_ptr; int 2f function code for append
2577 int int_function
2578 push es
2579 pop ds
2580 mov si,di
2581
2582; mov ah,get_PSP ; set new command
2583; call int_21
2584 mov bx,ss
2585 mov es,bx
2586 mov bx,cmd_buf ; command line iput buffer
2587 inc bx ; skip max length
2588 mov es:byte ptr[bx],3+1+6+1
2589 mov di,bx ; address command line buffer
2590 inc di ; skip current length
2591 push ds
2592 push si
2593 push cs
2594 pop ds
2595 move ,3+1+6+1,setappend_name ; set in "SET APPEND="
2596 pop si
2597 pop ds
2598 cmp ds:byte ptr[si],";" ; null list is special case
2599 jne copy_path
2600 mov al," "
2601 stosb
2602 inc es:byte ptr[bx]
2603 jmp short copy_path_done
2604copy_path:
2605 lodsb
2606 cmp al,0
2607 je copy_path_done
2608 stosb
2609 inc es:byte ptr[bx]
2610 jmp copy_path
2611copy_path_done:
2612 mov es:byte ptr[di],cr ; set end delimiter
2613
2614 les di,cmd_name@
2615 mov al,3 ; SET length
2616 stosb
2617 push cs ; @@06
2618 pop ds ; @@06
2619 move ,8,set_name ; set up "SET" command
2620
2621 mov ax,0 ; set to do SET
2622no_E_mode:
2623
2624 restore_regs
2625 ret
2626
2627page
2628
2629do_command: ; APPEND process
2630
2631; set ctrl-break check off
2632; first, save the old state so we can restore it later,
2633; then turn ctrl-break checking off
2634
2635 mov ah,ctrl_break ; function code for ctrl-break check
2636 xor al,al ; 0 = get current state
2637 call int_21
2638
2639 mov ctrl_break_state,dl ; save the old ctrl-break state
2640
2641 mov ah,ctrl_break ; function code for ctrl-break check
2642 mov al,01 ; set current state
2643 xor dl,dl ; 0 = off
2644 call int_21
2645
2646; find out if append has been loaded
2647
2648 mov ah,append_2f ; int 2f function code for append
2649 mov al,are_you_there ; function code to ask if append
2650 ; has been loaded
2651 int int_function
2652
2653 cmp al,append_inst ; is append there?
2654 jne not_already_there ; yes, don't try to put it
2655 jmp already_there ; yes, don't try to put it
2656 ; there again
2657
2658; get DOS version and decide if it is in the allowed range for
2659; APPEND
2660
2661not_already_there:
2662 mov ah,get_version ; lets find out if we should do it
2663 call int_21 ; try the open
2664 cmp ax,expected_version ; compare with DOS version
2665 jne bad_DOS
2666
2667 jmp check_assign ; valid range
2668 ; lets see if assign has been loaded
2669
2670; Break it to the user that he's trying to do an APPEND with
2671; the wrong DOS version
2672
2673bad_DOS:
2674 cmp al,01 ; DOS 1x or below has no handle fcns ; fixed P134 9/10/87 - gga
2675 ja use_STDERR
2676; lea dx,bad_DOS_msg ; bad DOS message ;AN000;
2677; mov ah,print_string ;AN000;
2678; call int_21 ;AN000;
2679 call sysloadmsg ;AN000;
2680 ;AN000;
2681 mov ax,8 ; message number ;AN000;
2682 mov bx,NO_HANDLE ; no handle ;AN000;
2683 xor cx,cx ; sub count ;AN000;
2684 xor dl,dl ; no input ;AN000;
2685 mov dh,-1 ; message class ;AN000;
2686 call sysdispmsg ;AN000;
2687
2688
2689 call ctrl_break_rest
2690 int termpgm ; return to DOS ; @@05
2691
2692use_STDERR:
2693 ;AN000;
2694 call sysloadmsg ;AN000;
2695 ;AN000;
2696 mov ax,8 ; message number ;AN000;
2697 mov bx,STDERR ; handle ;AN000;
2698 xor cx,cx ; sub count ;AN000;
2699 xor dl,dl ; no input ;AN000;
2700 mov dh,-1 ; message class ;AN000;
2701 call sysdispmsg ;AN000;
2702
2703; mov cx,len_bad_DOS_msg ; length of string ;AN000;
2704; lea dx,bad_DOS_msg ; bad DOS message ;AN000;
2705; call print_STDERR ; display error message ;AN000;
2706
2707 call ctrl_break_rest
2708 mov al,0ffh ; bad DOS version ; @@05
2709 call terminate ; exit to DOS ; @@05
2710
2711check_assign:
2712 mov ax,0600h
2713 int 2fh
2714 or al,al
2715 jnz assign_there
2716 jmp check_TopView ; ASSIGN has not been loaded, ; @@01
2717
2718; ASSIGN has been loaded before APPEND, bad news!
2719
2720assign_there:
2721 call sysloadmsg ;AN000;
2722 ;AN000;
2723 mov ax,6 ; message number ;AN000;
2724 mov bx,STDERR ; handle ;AN000;
2725 xor cx,cx ; sub count ;AN000;
2726 xor dl,dl ; no input ;AN000;
2727 mov dh,-1 ; message class ;AN000;
2728 call sysdispmsg ;AN000;
2729
2730; mov cx,len_append_assign_msg; length of string
2731; lea dx,append_assign_msg
2732; call print_STDERR ; display error message
2733 jmp conflict_exit ; @@01
2734 ; @@01
2735check_Topview: ; @@01
2736 mov bx,0 ; incase not there ; @@01
2737 mov ax,10h*256+34 ; TopView version check ; @@01
2738 int 15h ; @@01
2739 cmp bx,0 ; @@01
2740 jnz TopView_there ; @@01
2741 jmp replace_vector ; TopView has not been loaded, ; @@01
2742 ; @@01
2743; TopView has been loaded before APPEND, bad news! ; @@01
2744 ; @@01
2745TopView_there: ; @@01
2746; mov cx,len_append_TV_msg ; length of string ; @@01
2747; lea dx,append_TV_msg ; @@01
2748; call print_STDERR ; display error message ; @@01
2749 call sysloadmsg ;AN000;
2750 ;AN000;
2751 mov ax,7 ; message number ;AN000;
2752 mov bx,STDERR ; handle ;AN000;
2753 xor cx,cx ; sub count ;AN000;
2754 xor dl,dl ; no input ;AN000;
2755 mov dh,-1 ; message class ;AN000;
2756 call sysdispmsg ;AN000;
2757
2758 ; @@01
2759conflict_exit: ; @@01
2760 call ctrl_break_rest
2761 mov al,0fdh ; @@05
2762 call terminate ; exit to DOS ; @@05
2763
2764; get pointer to dir list, on return ES:DI points to buffer
2765
2766already_there:
2767
2768; This code has been moved to main_begin ; @@07
2769; ; @@07
2770; make sure the right version of APPEND has been loaded ; @@07
2771;
2772
2773; mov dx,0 ; set for network version ; @@07
2774; mov ah,append_2f ; int 2F function code for append ; @@07
2775; mov al,DOS_version ; function code for get version ; @@07
2776; int int_function ; @@07
2777; cmp dx,word ptr version_loc ; does the version match? ; @@07
2778; jump NE,bad_append_ver ; no, cough up an error messsage ; @@07
2779
2780process_args: ; process all arguments
2781
2782;-------------------------------------------------------------------
2783 mov si,0081h ; DS:SI points to argument area
2784 mov cs:byte ptr e_switch+9,0 ; turn /E switch off
2785
2786process_argsx: ; process all arguments
2787;
2788
2789
2790; make sure that the /PATH and /X switches are re-enabled, and
2791; various flags are cleared
2792
2793 mov ah,"/"
2794 mov cs:byte ptr x_switch+9,ah ; re-enable /X switch
2795 mov cs:byte ptr path_switch+9,ah ; re-enable /PATH switch
2796 mov cs:byte ptr x_result.$P_Type,0 ; clear flag
2797 mov cs:byte ptr path_result.$P_Type,0 ; clear flag
2798 mov cs:byte ptr dirs_result.$P_Type,0 ; clear flag
2799 mov cs:parse_flag,0 ; clear parse flag
2800
2801; set up things to call PARSER
2802
2803 push cs ; make sure ES points to segment where
2804 pop es ; parm block info is
2805 lea di,cs:p_block2 ; ES:DI points to parm block, for secondary parsing
2806
2807
2808 xor cx,cx ; ordinal value, must start as 0
2809 xor dx,dx ; must be 0
2810
2811 call Scan_For_Equal ; yes - let's see if we have "=" symbol ;an008; dms;
2812 ; parse past it if we do
2813
2814get_pars_info:
2815 call dword ptr pars_off ; call to COMMAND.COM's parser
2816
2817 cmp ax,-1 ; end of line?
2818 jne not_end_of_line ; no, carry on
2819 jmp end_of_line_reached ; yes, go figure out what we got
2820
2821not_end_of_line:
2822
2823 cmp ax,0 ; no, find out if there an error
2824 je not_parse_error ; no, carry on
2825 jmp parse_error ; yes, go display the error message
2826
2827; got here without any errors, set the proper bits in mode_flags
2828
2829not_parse_error:
2830 mov cs: parse_flag,0ffh ; set parse flag
2831
2832
2833check_e:
2834 cmp e_result.$P_Type,3 ; was there a /E in this pass?
2835 jne check_x ; no, look for an X
2836
2837 mov byte ptr e_switch+9,0 ; turn this off so we don't allow another
2838 mov e_result.$P_Type,0 ; clear this so we don't get fooled later
2839
2840 or mode_flags,E_mode ; set E mode on
2841
2842 jmp get_pars_info ; go get another argument
2843
2844check_x:
2845 cmp x_result.$P_Type,3 ; was there a /X on this pass? list index
2846 je set_x ; yes, and it was /X w/o ON or OFF
2847
2848 cmp x_result.$P_Type,2 ; was there a /X on this pass? list index
2849 jne check_path
2850
2851 mov byte ptr x_switch+9,0 ; turn this off so we don't allow another
2852 mov x_result.$P_Type,0 ; clear this so we don't get fooled later
2853
2854 cmp x_result.$P_Item_Tag,1 ; was /X or /X:ON specified?
2855 je set_x ; yes, set X mode on
2856 and mode_flags,NOT x_mode ; no, clear it
2857 jmp get_pars_info
2858
2859set_x:
2860 or mode_flags,x_mode
2861 jmp get_pars_info
2862
2863check_path:
2864 cmp path_result.$P_Type,2 ; was there a /path on this pass? list index
2865 jne check_dirs
2866
2867 xor ah,ah ; turn this off so we don't allow
2868 mov byte ptr path_switch+9,ah ; another
2869 mov path_result.$P_Type,0 ; clear this so we don't get fooled later
2870
2871
2872 cmp path_result.$P_Item_Tag,1 ; was /PATH:ON specified?
2873 je set_path ; yes, set PATH mode
2874 and mode_flags,NOT path_mode ; no, clear it
2875 jmp get_pars_info
2876
2877set_path:
2878 or mode_flags,path_mode ; set PATH mode on
2879 jmp get_pars_info
2880
2881; find out if dirs specified
2882
2883check_dirs:
2884 cmp dirs_result.$P_Type,3 ; was a simple string returned?
2885 je check_dirs2 ; yes, carry on
2886 jmp get_pars_info ; no, all done for now
2887
2888; set up stuff to do the dirs copy
2889
2890check_dirs2:
2891 push es
2892 push ds
2893 push si
2894 push di
2895
2896 lds si,dword ptr dirs_result.$P_Picked_Val ; get pointer to dirs string
2897 mov dirs_result.$P_Type,0 ; clear this so we don't get fooled later
2898
2899 mov di,0 ; set incase int 2f not installed ; @@08
2900 mov es,di ; @@08
2901 mov ax,append_2f*256+dir_ptr ; es:di -> internal result area ; @@08
2902 int int_function ; @@08
2903 mov ax,es ; see if active yet ; @@08
2904 or ax,di ; @@08
2905 jnz copy_dirs_loop ; ok, do the copy ; @@08
2906 push cs ; not active, set myself ; @@08
2907 pop es ; @@08
2908 lea di,app_dirs ; @@08
2909
2910copy_dirs_loop:
2911 movs es: byte ptr[di],ds:[si]; copy char
2912
2913 cmp byte ptr ds:[si-1],0 ; is char a null
2914 je done_copy_dirs
2915
2916 jmp copy_dirs_loop
2917
2918done_copy_dirs:
2919
2920 pop di
2921 pop si
2922 pop ds
2923 pop es
2924
2925 jmp get_pars_info ; no error yet, loop till done
2926
2927end_of_line_reached:
2928 mov old_syntax,0 ; process old format operands
2929
2930 cmp cs:initial_pass,-1 ; is this the first APPEND ;AN006;
2931 je first_one ; yes, clear flag and exit ;AN006;
2932
2933 cmp cs:parse_flag,0 ; if this flag is off, means null command line
2934 ; was nothing on the command line
2935 je display_dirs ; go display the dirs
2936
2937first_one: ;AN006;
2938 mov cs:initial_pass,0 ; clear first pass flag ;AN006;
2939
2940done_for_now:
2941normal_exit:
2942 call ctrl_break_rest ; reset control break checking
2943 mov ax,0 ; set string
2944 ret ; exit to COMMAND
2945
2946
2947parse_error:
2948 push ax ;save parser error code ;an010;bgb
2949 call sysloadmsg ;AN000;
2950 pop ax ;restore parser error coed ;an010;bgb
2951 call do_parse_err ;an010;bgb
2952 jmp bad_parmx ; display message and get out
2953
2954;-------------------------------------------------------------------
2955
2956; mov si,0081h ; point si to argument area
2957; mov bx,ss
2958; mov ds,bx
2959;
2960;process_argsx: ; process all arguments
2961; mov di,0 ; set incase int 2f not installed ; @@08
2962; mov es,di ; @@08
2963; mov ax,append_2f*256+dir_ptr ; es:di -> internal result area ; @@08
2964; int int_function ; @@08
2965; mov ax,es ; see if active yet ; @@08
2966; or ax,di ; @@08
2967; jnz have_ptr ; @@08
2968; push cs ; not active, set myself ; @@08
2969; pop es ; @@08
2970; lea di,app_dirs ; @@08
2971;have_ptr: ; @@08
2972;
2973;; step through the DOS command line argument area, and copy the new dir
2974;; list to the proper place in APPEND. This requires some parsing for
2975;; spaces, tabs chars, equal signs, as well as conversion to upper case
2976;
2977; cmp byte ptr[si],"=" ; APPEND=path is OK syntax
2978; jne skip_leading
2979; inc si
2980;skip_leading: ; skip leading spaces
2981; lodsb
2982; cmp al," "
2983; je skip_leading
2984; cmp al,tab_char
2985; je skip_leading
2986; cmp al,"," ; @@15
2987; je skip_leading ; @@15
2988; cmp al,"=" ; @@15
2989; je skip_leading ; @@15
2990; cmp al,cr ; did we have command line arguments?
2991; jump E,display_dirs ; no, display the dirs currently appended
2992; cmp al,"/" ; is it a parm starter? ; @@05
2993; jump E,bad_path_parm ; yes, it's an error ; @@05
2994; dec si
2995;
2996;copy_args:
2997; lodsb ; get char from command line area
2998; cmp al,cr ; are we at the end?
2999; jump E,found_end ; yes, display the currently appended dirs
3000; cmp al," " ; is it a space?
3001; je found_space ; yes, at end
3002; cmp al,tab_char ; is it a tab?
3003; je found_space ; yes, treat it like a space
3004; cmp al,"/" ; is it a parm starter?
3005; je bad_path_parm ; yes, it's an error ; @@05
3006; cmp al,"a" ; find out if we have a lower case char
3007; jb copy_char ; @@14
3008; cmp al,"z"
3009; ja copy_char ; @@14
3010; sub al,"a"-"A" ; convert char to upper case ; @@14
3011;
3012;copy_char:
3013; mov in_middle,-1 ; say that we made it to the middle
3014; stosb ; no, copy char into resident storage area
3015; jmp copy_args ; do it some more
3016;
3017;found_space:
3018; cmp in_middle,0 ; set the space flag then go through
3019; jump E,copy_args ; loop some more
3020;
3021;found_end:
3022; cmp in_middle,0 ; if I found the end of string but not
3023; jump E,display_dirs ; in the middle, go display some dirs
3024;
3025; mov es:byte ptr [di],0 ; null terminate the string
3026; mov in_middle,0
3027; cmp al,cr
3028; je past_trailing
3029;
3030;skip_trailing: ; skip end spaces
3031; lodsb
3032; cmp al," "
3033; je skip_trailing
3034; cmp al,tab_char
3035; je skip_trailing
3036; cmp al,"/" ; path and parm not together ; @@05
3037; je bad_path_parm ; @@05
3038; cmp al,cr ; only white space allowed at end
3039; jne bad_path
3040;past_trailing:
3041;
3042; cmp old_syntax,0 ; go back to normal mode
3043; je normal_exit
3044; jmp exit_append2
3045;normal_exit:
3046; call ctrl_break_rest ; reset control break checking
3047; mov ax,0 ; set string
3048; ret ; exit to COMMAND
3049
3050bad_path: ; bad paath operand
3051; mov cx,len_path_error_msg ; length of string
3052; lea dx,path_error_msg
3053 call sysloadmsg ;AN000;
3054 ;AN000;
3055 mov ax,3 ; message number ;AN000;
3056 mov bx,STDERR ; handle ;AN000;
3057 xor cx,cx ; sub count ;AN000;
3058 xor dl,dl ; no input ;AN000;
3059 mov dh,-1 ; message class ;AN000;
3060;gga call sysdispmsg ;AN000;
3061
3062 jmp short bad_parmx
3063
3064bad_path_parm: ; bad parameter ; @@05
3065; mov cx,len_path_parm_error_msg ; length of string ; @@05
3066; lea dx,path_parm_error_msg ; @@05
3067 call sysloadmsg ;AN000;
3068 mov ax,3 ; message number ;AN000;
3069 mov bx,STDERR ; standard error ;AN000;
3070 xor cx,cx ; sub count ;AN000;
3071 xor dl,dl ; no input ;AN000;
3072 mov dh,-1 ; message class ;AN000;
3073 jmp short bad_parmx ; @@05
3074bad_parm: ; bad parameter
3075; mov cx,len_parm_error_msg ; length of string
3076; lea dx,parm_error_msg
3077 call sysloadmsg ;AN000;
3078 ;AN000;
3079 mov ax,3 ; message number ;AN000;
3080 mov bx,STDERR ; standard error ;AN000;
3081 xor cx,cx ; sub count ;AN000;
3082 xor dl,dl ; no input ;AN000;
3083 mov dh,-1 ; message class ;AN000;
3084
3085bad_parmx: ; bad parameter
3086 push ds
3087 push cs
3088 pop ds
3089; call print_STDERR ; display error message
3090 lea si,inv_parm ; point to msg parm ;an010;bgb
3091 call sysdispmsg ;AN000;
3092 pop ds
3093 call ctrl_break_rest
3094 mov al,1 ; @@05
3095 call terminate ; exit to DOS ; @@05
3096
3097; This code has been moved to main_begin ; @@07
3098;bad_append_ver: ; append version mismatch ; @@07
3099; push ds ; @@07
3100; push cs ; @@07
3101; pop ds ; @@07
3102; mov cx,len_bad_append_msg ; @@07
3103; lea dx,bad_append_msg ; bad app message ; @@07
3104; call print_STDERR ; @@07
3105; lea dx,crlf ; carriage return, line feed ; @@07
3106; mov cx,crlf_len ; length of string ; @@07
3107; call print_STDERR ; @@07
3108; pop ds ; @@07
3109; call ctrl_break_rest ; @@07
3110; mov ax,0feh ; bad APPEND version ; @@05
3111; call terminate ; exit to DOS ; @@05
3112
3113; Display currently appended directories
3114
3115display_dirs:
3116 call address_status ; get working path ; @@03
3117 push ds
3118 push es
3119 pop ds
3120
3121 cmp es:byte ptr[di],";" ; no append now
3122 je no_dirs_appended
3123
3124; count the chars in the dir list, cx will hold the count
3125
3126 mov si,di
3127 sub si,6+1 ; move pointer to APPEND
3128 mov dx,si ; save pointer to string
3129 xor cx,cx
3130
3131scanit:
3132 lodsb ; get character
3133 cmp al,null ; are we at end?
3134 je print_it ; yes, print it
3135 inc cx ; look at the next character
3136 jmp scanit ; loop till we find the end
3137
3138print_it:
3139 call print_STDOUT ; display appended dirs
3140 push cs
3141 pop ds
3142 lea dx,crlf ; carriage return, line feed
3143 mov cx,crlf_len ; length of string
3144 call print_STDOUT
3145 pop ds
3146
3147exit_append:
3148 cmp old_syntax,0 ; process old format operands
3149 je exit_append2
3150 mov si,0081h ; set up rescan
3151 mov ah,get_PSP
3152 call int_21
3153 mov ds,bx
3154 jmp process_argsx
3155
3156exit_append2:
3157 mov old_syntax,0 ; after first time this must be off
3158 call ctrl_break_rest ; reset control break checking
3159 mov ax,-1 ; no action
3160 ret ; exit to COMMAND
3161
3162no_dirs_appended:
3163 push cs
3164 pop ds
3165
3166 call sysloadmsg ;AN000;
3167 ;AN000;
3168 mov ax,5 ; message number ;AN000;
3169 mov bx,STDERR ; handle ;AN000;
3170 xor cx,cx ; sub count ;AN000;
3171 xor dl,dl ; no input ;AN000;
3172 mov dh,-1 ; message class ;AN000;
3173 call sysdispmsg ;AN000;
3174
3175; lea dx,no_append_msg ; no dirs message ;AN000;
3176; mov cx,len_no_append_msg ; length of string ;AN000;
3177; call print_STDOUT ;AN000;
3178 pop ds
3179 jmp exit_append2 ; APPEND = = fix ;GGA
3180
3181page
3182;-------------------------------------------------------------------
3183; Getting here means that APPEND has not been loaded yet. Get the
3184; old vector, save it, and point the vector to the new routine.
3185;-------------------------------------------------------------------
3186
3187replace_vector:
3188
3189 push ds
3190 mov si,0081h ; point si to argument area
3191 mov ah,get_PSP
3192 call int_21
3193 mov ds,bx
3194
3195; Process /X and /E parameters
3196
3197skip_leading2: ; skip leading spaces
3198; lodsb
3199; cmp al," "
3200; je skip_leading2
3201; cmp al,tab_char
3202; je skip_leading2
3203; cmp al,cr ; at end
3204; jump E,parms_done
3205; cmp al,"/"
3206; jne set_old_syntax
3207
3208found_slash:
3209; lodsb
3210; cmp al,"e"
3211; je slash_E
3212; cmp al,"E"
3213; je slash_E
3214; cmp al,"x"
3215; je slash_X
3216; cmp al,"X"
3217; je slash_X
3218bad_parmy:
3219; pop ds
3220; jmp bad_parm
3221bad_path_parmy:
3222; pop ds
3223; jmp bad_path_parm
3224
3225slash_X:
3226; test mode_flags,X_mode ; no duplicates allowed
3227; jnz bad_parmy
3228; or mode_flags,X_mode
3229; jmp short slashx
3230
3231slash_E:
3232; test mode_flags,E_mode ; no duplicates allowed
3233; jnz bad_parmy
3234; or mode_flags,E_mode
3235slashx:
3236; jmp skip_leading2 ; loop some more
3237set_old_syntax:
3238;; test mode_flags,0 ; no /? switches on old mode
3239;; jne bad_path_parmy
3240 mov old_syntax,1
3241parms_done:
3242 pop ds
3243 jmp exit_append
3244page
3245
3246set_vectors: ; set append hooks ; @@05
3247 push es
3248
3249; Get INT 2f vector. Save to call older 2f handlers
3250
3251 mov ax,get_intfcn ; Get INT 2fh vector
3252 call int_21
3253 mov intfcn_offset,bx ; Save it
3254 mov intfcn_segment,es
3255
3256; get int 21 vector
3257
3258 mov ax,get_vector ; Get INT 21h vector
3259 call int_21
3260 mov vector_offset,bx ; Save it
3261 mov vector_segment,es
3262 pop es
3263
3264 push ds ; @@08
3265 push cs ; @@08
3266 pop ds ; @@08
3267 lea dx,intfcn_hook ; DS:DX = New INT 2fh vector
3268 mov ax,set_intfcn ; Hook the interrupt
3269 call int_21
3270
3271 lea dx,interrupt_hook ; DS:DX = New INT 21h vector
3272 mov ax,set_vector ; Hook the interrupt
3273 call int_21
3274
3275 mov dirlst_segment,cs ; save the address of the dirlist
3276 lea dx,app_dirs
3277 mov dirlst_offset,dx
3278 pop ds ; @@08
3279
3280 ret ; @@05
3281
3282terminate: ; terminate to dos or return ; @@05
3283 cmp res_append,0 ; @@05
3284 jne is_res ; @@05
3285 call Release_Environment ; release environmental vector ;ac009; dms;
3286 mov ah,term_proc ; return to DOS on first time ; @@05
3287 call int_21 ; @@05
3288is_res: ; @@05
3289 mov ax,-1 ; set abort requested ; @@05
3290 jmp abort_exit ; must go back to COMMAND ; @@05
3291
3292
3293print_STDOUT:
3294 mov bx,STDOUT ; Standard output device handle
3295 mov ah,awrite ; function code for write
3296 call int_21
3297 ret
3298
3299print_STDERR:
3300 mov bx,STDERR ; Standard output device handle
3301 mov ah,awrite
3302 call int_21
3303 ret
3304
3305Release_Environment: ;an007; dms;
3306
3307 push ax ;save regs ;an007; dms;
3308 push bx ; ;an007; dms;
3309 push es ; ;an007; dms;
3310 mov ah,Get_PSP ; get the PSP segment ;an007; dms;
3311 call int_21 ; invoke INT 21h ;an007; dms;
3312 mov es,bx ; BX contains PSP segment - put in ES ;an007; dms;
3313 mov bx,word ptr es:[PSP_Env]; get segment of environmental vector ;an007; dms;
3314 mov es,bx ; place segment in ES for Free Memory ;an007; dms;
3315 mov ah,Free_Alloc_Mem ; Free Allocated Memory ;an007; dms;
3316 int 21h ; invoke INT 21h ;an007; dms;
3317 pop es ; restore regs ;an007; dms;
3318 pop bx ; ;an007; dms;
3319 pop ax ; ;an007; dms;
3320
3321 ret ; return to caller ;an007; dms;
3322
3323;=========================================================================
3324; Scan_For_Equal : This routine scans the command line from the
3325; beginning until it encounters anything other
3326; than the equal, tab, or space characters.
3327; Register SI is sent back to the caller pointing
3328; to the character that does not meet the match
3329; criteria.
3330;
3331; Inputs : DS:SI - pointer to next parm
3332;
3333; Outputs : SI - adjusted to byte not matching the following:
3334; "="
3335; " "
3336; TAB
3337;
3338; Author : DS
3339; Date : 1/27/88
3340; Version : DOS 3.4
3341;=========================================================================
3342
3343Scan_For_Equal:
3344
3345 push ax ; save regs ;an008; dms;
3346 push cx ; ;an008; dms;
3347
3348 xor cx,cx ; clear cx ;an008; dms;
3349 mov cl,byte ptr ds:[80h] ; get length of command line ;an008; dms;
3350
3351Scan_For_Equal_Loop:
3352
3353 cmp cx,0 ; at end? ;an008; dms;
3354 jbe Scan_For_Equal_Exit ; exit loop ;an008; dms;
3355 mov al,byte ptr ds:[si] ; get 1st. character ;an008; dms;
3356 call Chk_DBCS ; DBCS lead byte? ;an008; dms;
3357 jnc Scan_For_Equal_No_DBCS ; no ;an008; dms;
3358 cmp byte ptr ds:[si],81h ; blank lead byte ;an008; dms;
3359 jne Scan_For_Equal_Exit ; exit with adjusted SI ;an008; dms;
3360 cmp byte ptr ds:[si+1],40h ; DBCS blank ;an008; dms;
3361 jne Scan_For_Equal_Exit ; exit with adjusted SI ;an008; dms;
3362
3363 add si,2 ; yes - DBCS lead byte ;an008; dms;
3364 sub dx,2 ; decrease counter ;an008; dms;
3365 jmp Scan_For_Equal_Loop
3366
3367Scan_For_Equal_No_DBCS:
3368
3369 cmp al,"=" ; = found? ;an008; dms;
3370 je Scan_For_Equal_Next ; next character ;an008; dms;
3371 cmp al,20h ; space? ;an008; dms;
3372 je Scan_For_Equal_Next ; next character ;an008; dms;
3373 cmp al,09h ; tab? ;an008; dms;
3374 je Scan_For_Equal_Next ; next character ;an008; dms;
3375 jmp Scan_For_Equal_Exit ; exit with adjusted SI ;an008; dms;
3376
3377Scan_For_Equal_Next:
3378
3379 inc si ; adjust ptr ;an008; dms;
3380 dec cx ; decrease counter ;an008; dms;
3381 jmp Scan_For_Equal_Loop ; continue loop ;an008; dms;
3382
3383Scan_For_Equal_Exit:
3384
3385 pop cx ; ;an008; dms;
3386 pop ax ; ;an008; dms;
3387
3388 ret ; return to caller ;an008; dms;
3389
3390
3391
3392;========================================================================= ;an010;bgb
3393; do_parse_err : This routine sets up for the display of a parse ;an010;bgb
3394; error, and displays the offending parameter. ;an010;bgb
3395; ;an010;bgb
3396; Inputs : DS:SI - points just past offending parm in command line ;an010;bgb
3397; ;an010;bgb
3398; Outputs : si_off- parm for msg ret. ;an010;bgb
3399; si_seg- parm for msg ret. ;an010;bgb
3400; command line - hex zero at end of offending parm ;an010;bgb
3401; ;an010;bgb
3402; Date : 3/29/88 ;an010;bgb
3403; Version : DOS 4.0 (wow!) ;an010;bgb
3404;========================================================================= ;an010;bgb
3405do_parse_err PROC ;an010;bgb
3406;;;;;;;;mov ax,3 ;removed- parser handles this ;an010;bgb
3407 mov bx,STDERR ; handle ;an010;bgb
3408;;;;;;;;xor cx,cx ; sub count ;an010;bgb
3409 mov cx,1 ;display invalid parm ;an010;bgb
3410 xor dl,dl ; no input ;an010;bgb
3411 mov dh,02 ; message class of parse error ;an010;bgb
3412;;;;;;;;mov cs:si_off,81h ;initialize pointer ;an010;bgb
3413 ;an010;bgb
3414 dec si ;point to last byte of invalid parm ;an010;bgb
3415public decsi ;an010;bgb
3416decsi: cmp byte ptr [si],' ' ;are we pointing to a space? ;an010;bgb
3417; $IF E,OR ;if so, we dont want to do that ;an010;bgb
3418 JE $$LL1
3419 cmp byte ptr [si],0dh ;are we pointing to CR? ;an010;bgb
3420; $IF E ;if so, we dont want to do that ;an010;bgb
3421 JNE $$IF1
3422$$LL1:
3423 dec si ;find the last byte of parm ;an010;bgb
3424 jmp decsi ;an010;bgb
3425; $ENDIF ;an010;bgb
3426$$IF1:
3427 mov byte ptr [si+1],00 ;zero terminate display string ;an010;bgb
3428nextsi: ;an010;bgb
3429public nextsi ;an010;bgb
3430 dec si ;look at previous char ;an010;bgb
3431 cmp byte ptr [si],' ' ;find parm separator ;an010;bgb
3432 jnz nextsi ;loop until begin of parm found ;an010;bgb
3433 ;an010;bgb
3434 mov cs:si_off,si ;mov si into display parms ;an010;bgb
3435 mov cs:si_seg,ds ;initialize pointer ;an010;bgb
3436 ret ; return to caller ;an010;bgb
3437do_parse_err ENDP ;an010;bgb
3438
3439
3440;-------------------------------------------------------------------
3441;
3442;-------------------------------------------------------------------
3443
3444MSG_SERVICES <LOADmsg>
3445MSG_SERVICES <APPEND.CLB,APPEND.CL2,APPEND.CTL>
3446
3447end_address: ; this is the end of the TSR stuff ;AN004;
3448
3449include parse.asm ; include the parser code
3450include msgdcl.inc
3451
3452cseg ends
3453sseg segment para stack 'STACK'
3454 assume ss:sseg
3455 dw 512 dup(0)
3456mystack dw 0
3457sseg ends
3458
3459
3460
3461 end main_begin
3462 \ No newline at end of file