	 page   80,132
	TITLE 4.00 PRINT  TRANSIENT

;/*
; *                      Microsoft Confidential
; *                      Copyright (C) Microsoft Corporation 1991
; *                      All Rights Reserved.
; */

;                       $SALUT (4,25,30,41)
			INCLUDE pridefs.inc

SaveReg                 MACRO reglist   ;; push those registers
IRP                     reg,<reglist>
			PUSH reg
ENDM
ENDM

RestoreReg              MACRO reglist   ;; pop those registers
IRP                     reg,<reglist>
			POP  reg
ENDM
ENDM

BREAK                   <Transient Portion>
;******************* START OF SPECIFICATIONS ***********************************
;
; MODULE NAME:          PRINT_T.SAL
;
; DESCRIPTIVE NAME:     TRANSIENT  -  Print Initialization and Instalation
;                       Routine.   DOS PRINT program for background printing
;                       of   text files to the list device - Transient Portion.
;
;  FUNCTION:    - Call the DOS PARSE Service Routines to process the command
;                 line. Search for valid input:
;                        - filenames (may be more than one
;                        - switches: /D:device
;                                    /B:buffsize  512 to 16k - 512 default
;                                    /Q:quesiz      4 to 32  -  10 default
;                                    /S:timeslice   1 to 255 -   8 default
;                                    /U:busytick    1 to 255 -   1 default
;                                    /M:maxtick     1 to 255 -   2 default
;                                    /T    terminate
;                                    /C    cancel
;                                    /P    print
;                                    /?    print out help message
;               - Install the resident component if not already installed
;               - Submit files for printing to the resident component
;
;  INPUT:       Parameter string from command line in the PSP
;
;  OUTPUT:      All parameters specified are updated. Files are submitted to
;               the resident component for printing.
;
;  REGISTERS USED: T.B.D.
;  (NOT RESTORED)
;
;  LINKAGE:     LINK - TRANSIENT
;
;  NORMAL       -
;  EXIT:
;
;  ERROR        -
;  EXIT:
;
;  EXTERNAL     -
;  REFERENCES:
;
;  CHANGE       03/11/87 - Major restructureing of TRANSIENT - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START  TRANSIENT
;
;       If pdb_environ != 0
;               deallocate memory
;       endif
;       call SYSLOADMSG
;       if no error (if there is - SYSLOADMSG is already set to
;                               display it - ie DOS ver error
;               if not installed
;                       call Load_R_Msg
;                       if no error
;                               get all interupt values
;                       else
;                               load error message #
;                               set error flag
;                       endif
;               else
;                       if PSPRINT conflict
;                               load error message #
;                               set error flag
;                       endif
;               endif
;       endif
;       if no error and
;       get and set INT 24 handler
;       update path character
;       Set up for Parse_Input call
;       Do
;       Leave if end of command line
;       Leave if error flag set
;               call parse_input
;               if carry set
;                       set up for Invalid_parm message
;               endif
;       Leave if error flag set
;               update Parse_C_B
;               if file_name
;                       call Submit_Name
;               endif
;               if switch
;                       Do_case switch
;                               Bgncase_/D
;                                       if valid value and not installed
;                                               move device name to LISTNAME
;                                               reset carry
;                                       else
;                                               set carry
;                                       endif
;                               Endcase_/D
;                               Bgncase_/B
;                                       if valid value and not installed
;                                               update BLKSIZ
;                                               reset carry
;                                       else
;                                               set carry
;                                       endif
;                               Endcase_/B
;                               Bgncase_/Q
;                                       if valid value and not installed
;                                               update BLKSIZ
;                                               reset carry
;                                       else
;                                               set carry
;                                       endif
;                               Endcase_/Q
;                               Bgncase_/S
;                                       if valid value and not installed
;                                               update TIMESLICE, SLICECNT
;                                               reset carry
;                                       else
;                                               set carry
;                                       endif
;                               Endcase_/S
;                               Bgncase_/U
;                                       if valid value and not installed
;                                               update BUSYTICK
;                                               reset carry
;                                       else
;                                               set carry
;                                       endif
;                               Endcase_/U
;                               Bgncase_/M
;                                       if valid value and not installed
;                                               update MAXTICK
;                                               reset carry
;                                       else
;                                               set carry
;                                       endif
;                               Endcase_/M
;                               Bgncase_/T
;                                       if installed
;                                               set up for cancel
;                                               call IntWhileBusy
;                                       endif
;                                       call Set_Buffer
;                                       reset carry
;                               Endcase_/T
;                               Bgncase_/C
;                                       if installed
;                                               set CanFlag
;                                       else
;                                               call Set_Buffer
;                                       endif
;                                       reset carry
;                               Endcase_/C
;                               Bgncase_/P
;                                       if installed
;                                               reset CanFlag
;                                       else
;                                               call Set_Buffer
;                                       endif
;                                       reset carry
;                               Endcase_/P
;                       end_case
;                       if carry set
;                               set up for Invalid_parm message
;                       endif
;               endif
;       enddo
;       if no error
;               if not installed
;                       call Set_Buffer
;               else
;                       get queue pointer
;                       check for off line
;                       display queue
;               endif
;       else
;               call DispMsg  (display the fatal error)
;       endif
;
;       return
;
;       END  TRANSIENT
;
;==================== END - PSEUDOCODE =========================================

CodeR                   Segment public para

			extrn SliceCnt:BYTE, BusyTick:BYTE, MaxTick:BYTE, TimeSlice:BYTE
			extrn EndRes:WORD, BlkSiz:WORD, QueueLen:BYTE, PChar:BYTE
			extrn ListName:BYTE, FileQueue:BYTE, EndQueue:WORD, Buffer:WORD
			extrn EndPtr:WORD, NxtChr:WORD, MoveTrans:FAR, TO_DOS:FAR

			extrn MESBAS:WORD, R_MES_BUFF:WORD

CodeR                   EndS


			BREAK <Transient Data>

;----------------------------------------
; Transient data
;----------------------------------------

DATA                    SEGMENT public BYTE



			public namebuf

			ORG  0

SWITCHAR                DB   ?
PathChar                db   "\"

SubPack                 db   0          ; Level
			dd   ?          ; pointer to filename

;--- Ints used by print. These ints are loaded here before the
; resident is installed, just in case an error before print
; is installed cases it to be never installed and the ints
; have to be restored.

i28vec                  dd   ?          ; SOFTINT
i2fvec                  dd   ?          ; COMINT
i05vec                  dd   ?
i13vec                  dd   ?
i14vec                  dd   ?
i15vec                  dd   ?
i17vec                  dd   ?
i1cvec                  dd   ?          ; INTLOC

;--- Temp stack for use durint int 23 and 24 processing
			db   278 + 80H dup (?) ; 278 == IBM's ROM requirements
intStk                  dw   ?


;--- Print installed flag:
; 0 = Not installed yet: process only configuration parameters
;       during the command line parse
; 1 = Partially installed: process only print commands AND flag
;       configuration parameters as errors AND finish by executing
;       the keep process
; 2 = Already installed: process only print commands AND flag
;       configuration parameters as errors
PInst                   db   0          ; defaults to not installed
CanFlag                 db   0          ; cancel mode flag (0= no cancel)
Ambig                   db   ?          ; =1 if a filename is ambigous
DevSpec                 db   0          ; =1 a device was specified with the
					;  /d option, do not prompt
QFullMes                db   0          ; =1 queue full message issued already
HARDCH                  DD   ?          ;Pointer to real INT 24 handler

TokBuf                  DB   (MaxFileLen+16) dup(?) ; token buffer for input

NulPtr                  dw   ?          ; pointer to the nul in NameBuf
FNamPtr                 dw   ?          ; pointer to name portion of file name
NameBuf                 db   (MaxFileLen+16) dup(?) ; full name buffer for file
					;  plus room for ambigous expansion

whichmsg                dw   (CLASS_C shl 8)+FstMes ; initial message for
					;               file queue loop

SearchBuf               find_buf <>     ; search buffer

appbuf                  db      64  dup (0)
nxtdir                  dw      0
appseg                  dw      0
datseg                  dw      0
triedappend             db      0
dsklet                  db      0

semicolon               equ     ';'
endofline                       equ     0

					;--------------------------------------
					; PARSE Equates
					;--------------------------------------

EOL                     equ  -1         ; Indicator for End-Of-Line
NOERROR                 equ  0          ; Return Indicator for No Errors

DEVICE                  equ  0          ; device
BUFFSIZ                 equ  1          ; buffsiz
QUESIZ                  equ  2          ; quesiz
TIME                    equ  3          ; timeslice
BUSYT                   equ  4          ; busytick
MAXT                    equ  5          ; maxtick
TERM                    equ  6          ; Terminate
CANC                    equ  7          ; Cancel
PRINT                   equ  8          ; Print

file_spec               equ  5          ; Parse Type for file spec found

					;--------------------------------------
					; PARSE Control Block
					;--------------------------------------

ORDINAL                 DW   0          ; Current Parse ordinal value
SCAN_PTR                DW   81h        ; Current Parse location Pointer
MSG_PTR                 DW   81h        ; Last Parse location Pointer

					;--------------------------------------
					;  STRUCTURE TO DEFINE ADDITIONAL
					;       COMMAND LINE PARAMETERS
					;--------------------------------------
PARMS                   LABEL WORD
			DW   OFFSET DG:PARMSX ; POINTER TO PARMS STRUCTURE
			DB   0          ; NO DELIMITER LIST FOLLOWS

					;--------------------------------------
					;  STRUCTURE TO DEFINE SYNTAX
					;--------------------------------------
PARMSX                  LABEL BYTE
			DB   0,1        ; A POSITIONAL PARAMETER IS VALID
			DW   OFFSET DG:POS1 ; POINTER TO POSITIONAL DEFINITION
			DB   10         ; THERE ARE 9 TYPES OF SWITCHES
			DW   OFFSET DG:SW1 ; POINTER TO THE /D:device SWITCH DEFINITION AREA
			DW   OFFSET DG:SW2 ; POINTER TO THE /B:buffsiz SWITCH DEFINITION AREA
			DW   OFFSET DG:SW3 ; POINTER TO THE /Q:quesiz SWITCH DEFINITION AREA
			DW   OFFSET DG:SW4 ; POINTER TO THE /S:timeslice SWITCH DEFINITION AREA
			DW   OFFSET DG:SW5 ; POINTER TO THE /U:busytick SWITCH DEFINITION AREA
			DW   OFFSET DG:SW6 ; POINTER TO THE /M:maxval SWITCH DEFINITION AREA
			DW   OFFSET DG:SW7 ; POINTER TO THE /T  TERMINATE SWITCH DEFINITION AREA
			DW   OFFSET DG:SW8 ; POINTER TO THE /C CANCEL SWITCH DEFINITION AREA
			DW   OFFSET DG:SW9 ; POINTER TO THE /P PRINT SWITCH DEFINITION AREA
			DW   OFFSET DG:SW10 ; POINTER TO /? PRINT SWITCH DEFINITION AREA
			DW   0          ; THERE ARE NO KEYWORDS IN PRINT SYNTAX

					;--------------------------------------
					;
					; NOTE: Do NOT change the layout or size
					;       of the following entries:
					;        --- SW1 through SW9  ---
					;       Their size and position are used
					;       to calculate an index for a
					;       DO_CASE (jump table). This is
					;       possible ONLY if the size of all
					;       9 entries are exactly the same,
					;       congruent, and in this exact
					;       order. Any changes here MUST be
					;       matched in the Process_A_Switch
					;       PROC.
					;
					;       The following formula is used:
					;
					;       Index = (offset P_SYN - offset
					;               SW1) / SW_SIZE
					;
					;--------------------------------------


					;--------------------------------------
					;  STRUCTURE TO DEFINE THE POSITIONAL
					;           PARAMETER (File Name)
					;--------------------------------------
POS1                    LABEL WORD
			DW   0203H      ; OPTIONAL, REPEATABLE FILE SPEC
			DW   0001H      ; CAPS BY FILE TABLE
			DW   OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
			DW   OFFSET DG:NOVALS ; NO VALUES LIST REQUIRED
			DB   0          ; NO KEYWORDS

					;--------------------------------------
					; STRUCTURE TO DEFINE /D:device SWITCH
					;--------------------------------------
SW1                     LABEL WORD
			DW   2001H      ; MUST BE PRINT OUTPUT DEVICE
					; (optional simple string)
			DW   1h         ; Caps by file table
			DW   OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
			DW   OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY
			DB   1          ; ONE SWITCH IN FOLLOWING LIST
SW_PTR                  DB   "/D",0     ; /D: INDICATES DEVICE SPECIFIED

SW_SIZE                 equ  $ - SW1
					;--------------------------------------
					; STRUCTURE TO DEFINE /B:buffsiz SWITCH
					;--------------------------------------
SW2                     LABEL WORD
			DW   8001H      ; MUST BE NUMERIC (optional)
			DW   0          ; NO FUNCTION FLAGS
			DW   OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
			DW   OFFSET DG:VALUE_BUF ; NEED VALUE LIST FOR buffsiz
			DB   1          ; ONE SWITCH IN FOLLOWING LIST
B_SWITCH                DB   "/B",0     ; /B: INDICATES buffsiz REQUESTED

					;--------------------------------------
					; STRUCTURE TO DEFINE /Q:quesiz SWITCH
					;--------------------------------------
SW3                     LABEL WORD
			DW   8001H      ; MUST BE NUMERIC (optional)
			DW   0          ; NO FUNCTION FLAGS
			DW   OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
			DW   OFFSET DG:VALUE_QUE ; NEED VALUE LIST FOR quesiz
			DB   1          ; ONE SWITCH IN FOLLOWING LIST
Q_SWITCH                DB   "/Q",0     ; /Q: INDICATES quesiz REQUESTED

					;--------------------------------------
					; STRUCTURE TO DEFINE /S:timeslice SWITCH
					;--------------------------------------
SW4                     LABEL WORD
			DW   8001H      ; MUST BE NUMERIC (optional)
			DW   0          ; NO FUNCTION FLAGS
			DW   OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
			DW   OFFSET DG:VALUE_TIME ; NEED VALUE LIST FOR timeslice
			DB   1          ; ONE SWITCH IN FOLLOWING LIST
S_SWITCH                DB   "/S",0     ; /S: INDICATES timeslice REQUESTED

					;--------------------------------------
					; STRUCTURE TO DEFINE /U:busytick SWITCH
					;--------------------------------------
SW5                     LABEL WORD
			DW   8001H      ; MUST BE NUMERIC (optional)
			DW   0          ; NO FUNCTION FLAGS
			DW   OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
			DW   OFFSET DG:VALUE_BUSY ; NEED VALUE LIST FOR busytick
			DB   1          ; ONE SWITCH IN FOLLOWING LIST
U_SWITCH                DB   "/U",0     ; /U: INDICATES busytick REQUESTED

					;--------------------------------------
					; STRUCTURE TO DEFINE /M:maxtick SWITCH
					;--------------------------------------
SW6                     LABEL WORD
			DW   8001H      ; MUST BE NUMERIC (optional)
			DW   0          ; NO FUNCTION FLAGS
			DW   OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
			DW   OFFSET DG:VALUE_MAXT ; NEED VALUE LIST FOR maxtick
			DB   1          ; ONE SWITCH IN FOLLOWING LIST
M_SWITCH                DB   "/M",0     ; /M: INDICATES maxtick REQUESTED

					;--------------------------------------
					;  STRUCTURE TO DEFINE /T Terminate SWITCH
					;--------------------------------------
SW7                     LABEL WORD
			DW   8001H      ; SWITCH ONLY
					; (optional simple string)
			DW   0          ; NO FUNCTION FLAGS
			DW   OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
			DW   OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY
			DB   1          ; ONE SWITCH IN FOLLOWING LIST
			DB   "/T",0     ; /T: INDICATES Terminate REQUESTED

					;--------------------------------------
					;  STRUCTURE TO DEFINE /C Cancel SWITCH
					;--------------------------------------
SW8                     LABEL WORD
			DW   8003H      ; SWITCH ONLY
					; (optional, repeatable simple string)
			DW   0          ; NO FUNCTION FLAGS
			DW   OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
			DW   OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY
			DB   1          ; ONE SWITCH IN FOLLOWING LIST
C_SW_ptr                DB   "/C",0     ; /C: INDICATES Cancel REQUESTED

					;--------------------------------------
					;  STRUCTURE TO DEFINE /P Print SWITCH
					;--------------------------------------
SW9                     LABEL WORD
			DW   8003H      ; SWITCH ONLY
					; (optional, repeatable simple string)
			DW   0          ; NO FUNCTION FLAGS
			DW   OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
			DW   OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY
			DB   1          ; ONE SWITCH IN FOLLOWING LIST
P_SW_ptr                DB   "/P",0     ; /P: INDICATES Print REQUESTED


					;--------------------------------------
					;  STRUCTURE TO DEFINE /? Print SWITCH
					;--------------------------------------
SW10                    LABEL WORD
			DW   0
			DW   0          ; NO FUNCTION FLAGS
			DW   OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
			DW   OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY
			DB   1          ; ONE SWITCH IN FOLLOWING LIST
?_SW_ptr                DB   "/?",0     ; /?: INDICATES HELP REQUESTED


					;--------------------------------------
					;  VALUE LIST FOR FILE NAMES
					;--------------------------------------
NOVALS                  LABEL WORD
			DB   0          ; NO VALUES

					;--------------------------------------
					;  VALUE LIST DEFINITION FOR buffsiz
					;--------------------------------------
VALUE_BUF               LABEL BYTE
			DB   1          ; ONE VALUE ALLOWED
			DB   1          ; ONLY ONE RANGE
			DB   BUFFSIZ    ; IDENTIFY IT AS buffsiz
					; USER CAN SPECIFY /+512 THROUGH /+16K
			DD   MinBufferLen,MaxBufferLen

					;--------------------------------------
					;  VALUE LIST DEFINITION FOR quesiz
					;--------------------------------------
VALUE_QUE               LABEL BYTE
			DB   1          ; ONE VALUE ALLOWED
			DB   1          ; ONLY ONE RANGE
			DB   QUESIZ     ; IDENTIFY IT AS quesiz
					; USER CAN SPECIFY /+4 THROUGH /+32
			DD   MinQueueLen,MaxQueueLen

					;--------------------------------------
					;  VALUE LIST DEFINITION FOR timeslice
					;--------------------------------------
VALUE_TIME              LABEL BYTE
			DB   1          ; ONE VALUE ALLOWED
			DB   1          ; ONLY ONE RANGE
			DB   TIME       ; IDENTIFY IT AS timeslice
					; USER CAN SPECIFY /+1 THROUGH /+255
			DD   MinTimeSlice,MaxTimeSlice

					;--------------------------------------
					;  VALUE LIST DEFINITION FOR busytick
					;--------------------------------------
VALUE_BUSY              LABEL BYTE
			DB   1          ; ONE VALUE ALLOWED
			DB   1          ; ONLY ONE RANGE
			DB   BUSYT      ; IDENTIFY IT AS busytick
					; USER CAN SPECIFY /+1 THROUGH /+255
			DD   MinBusyTick,MaxBusyTick

					;--------------------------------------
					;  VALUE LIST DEFINITION FOR maxtick
					;--------------------------------------
VALUE_MAXT              LABEL BYTE
			DB   1          ; ONE VALUE ALLOWED
			DB   1          ; ONLY ONE RANGE
			DB   MAXT       ; IDENTIFY IT AS maxtick
					; USER CAN SPECIFY /+1 THROUGH /+255
			DD   MinMaxTick,MaxMaxTick

					;--------------------------------------
					;  RETURN BUFFER FOR PARSE INFORMATION
					;--------------------------------------
PARSE_BUFF              LABEL BYTE
P_TYPE                  DB   ?          ; TYPE RETURNED
P_ITEM_TAG              DB   ?          ; SPACE FOR ITEM TAG
P_SYN                   DW   ?          ; POINTER TO LIST ENTRY
P_PTR_L                 DW   ?          ; SPACE FOR POINTER / VALUE - LOW
P_PTR_H                 DW   ?          ; SPACE FOR POINTER / VALUE - HIGH

					;----------------------------------------
					; SUBLIST for Message call
					;----------------------------------------

SUBLIST                 LABEL WORD

			DB   sub_size   ; size of sublist
			DB   0          ; reserved
insert_ptr_off          DW   0          ; pointer to insert - offset
insert_ptr_seg          DW   DG         ; pointer to insert - segment
insert_num              DB   0          ; number of insert
			DB   Char_Field_ASCIIZ ; data type flag - ASCII Z string
			DB   MaxFileLen ; maximum field size
			DB   1          ; minimum field size
			DB   " "        ; pad character

sub_size                equ  $ - SUBLIST ; size of sublist


OPEN_FILE               label dword

			dw   offset DG:NameBuf ; name pointer offset
open_seg                dw   ?          ; name pointer segment

DATA                    ENDS

			BREAK <Transient Code>

Code                    Segment public para
Code                    EndS

Code                    Segment public para

			public TransRet,TransSize,GoDispMsg

			extrn SYSLOADMSG:NEAR, SYSGETMSG:NEAR, SYSDISPMSG:NEAR
			extrn SYSPARSE:NEAR

			ASSUME CS:DG,DS:nothing,ES:nothing,SS:Stack

;  $SALUT (4,4,9,41)


TRANSIENT:
					;-------------------------------------
					; Install Print
					;-------------------------------------

   cld
   mov  ax,ds:[pdb_environ]
   or   ax,ax

;  $if  nz                              ; if pdb_environ != 0                  ;AC000;
   JZ $$IF1

       push es                          ; deallocate memory
       mov  es,ax
       mov  ah,dealloc
       int  21h
       pop  es

;  $endif                               ;                                      ;AC000;
$$IF1:

   call SYSLOADMSG                      ; Initialize the Message Service code  ;AN000;

;  $if  c                               ; if error                             ;AC000;
   JNC $$IF3

       mov  ah,dh                       ; set up class for DispMsg

;  $else                                ; else - no error - keep going
   JMP SHORT $$EN3
$$IF3:

       push cs
       pop  ax
       mov  ds,ax
       mov  es,ax

       ASSUME DS:DG,ES:DG
					; NOTE: es must ALWAYS point to DG

       mov  ax,0100h                    ; Ask if already installed
       int  ComInt
       or   al,al

;      $if  z                           ; if not installed                     ;AC000;
       JNZ $$IF5

	   call Load_R_Msg              ;                                      ;AC000;

;          $if  nc                      ; if no error                          ;AC000;
	   JC $$IF6

	       call Save_Vectors        ;                                      ;AC000;

;          $endif                       ; endif - NB: - If carry IS set,       ;AC000;
$$IF6:
					; Load_R_Msg will have loaded the
					; error message #

;      $else                            ;  else - we are installed             ;AC000;
       JMP SHORT $$EN5
$$IF5:

	   cmp  al,1

;          $if  z                       ; if PSPRINT conflict                  ;AC000;
	   JNZ $$IF9

	       mov  ax,(CLASS_B shl 8) + CONFLICTMES ; load error message #    ;AC000;

	       stc                      ; set the error flag                   ;AC000;

;          $else                        ;                                      ;AC000;
	   JMP SHORT $$EN9
$$IF9:

	       mov  [PInst],2           ; remember print already installed
					;          and that we only do one pass
	       mov  al," "              ; invalidate install switches          ;AN005;
	       mov  SW_PTR,al           ; /D                                   ;AN005;
	       mov  B_SWITCH,al         ; /B                                   ;AN005;
	       mov  Q_SWITCH,al         ; /Q                                   ;AN005;
	       mov  S_SWITCH,al         ; /S                                   ;AN005;
	       mov  U_SWITCH,al         ; /U                                   ;AN005;
	       mov  M_SWITCH,al         ; /M                                   ;AN005;
	       clc                      ; reset the error flag                 ;AC000;

;          $endif                       ;                                      ;AC000;
$$EN9:
;      $endif                           ;                                      ;AC000;
$$EN5:
;  $endif                               ;                                      ;AC000;
$$EN3:

;  $if  nc,and                          ; if no errors so far and..............;AC000;
   JC $$IF14

   call GetHInt                         ; save current int 24 vector
   call SetInts                         ; set int 23 and 24 vectors
   mov  ax,CHAR_OPER shl 8
   int  21h
   mov  [SWITCHAR],dl                   ; Get user switch character
   cmp  dl,"-"

;  $if  e                               ; if "-"                               ;AC000;
   JNE $$IF14
       mov  [PathChar],"/"              ; alternate path character
;  $endif                               ;                                      ;AC000;
$$IF14:

					; Set up for Parse_Input call

;  $do                                  ; Do_until end of command line         ;AC000;
$$DO16:

;  $leave c                             ;  quit if an error occured            ;AC000;
   JC $$EN16

       call parse_input                 ;                                      ;AC000;

       mov  [ordinal],cx                ;  update Parse_C_B                    ;AC000;
       mov  [scan_ptr],si               ;                                      ;AC000;

       cmp  al,EOL                      ;  are we at the end?                  ;AC000;

;  $leave e                             ; leave if end of line                 ;AC000;
   JE $$EN16

       cmp  al,noerror                  ;                                      ;AC000;

;      $if  ne                          ;  if error                            ;AC000;
       JE $$IF19

	   mov  ah,Parse_error          ;   set class to Parse error           ;AC000;


	   stc                          ;    set the error flag                ;AC000;

;      $endif                           ;  endif                               ;AC000;
$$IF19:

;  $leave c                             ; leave the loop if error ocurred      ;AC000;
   JC $$EN16

       cmp  [p_type],File_Spec          ;  is it a file spec?                  ;AC000;

;      $if  e                           ;  if it is a file spec                ;AC000;
       JNE $$IF22

	   call Submit_File             ;                                      ;AC000;

;      $else                            ;  else - we must now have a           ;AC000;
       JMP SHORT $$EN22
$$IF22:
					;       valid switch!


					;  Do_case switch

	   push cs                      ;   set up for CASE                    ;AC000;
	   pop  ds                      ;                                      ;AC000;
	   mov  ax,[p_syn]              ;                                      ;AC000;
	   sub  ax,OFFSET DG:SW_PTR     ;                                      ;AC000;
	   mov  dl,SW_SIZE              ;                                      ;AC000;
	   div  dl                      ;                                      ;AC000;
	   cmp  ah,noerror              ;                                      ;AC000;
	   mov  di,ax                   ;                                      ;AC000;
	   mov  ax,(CLASS_B shl 8) + invparm ; set message in case of error    ;AC000;

	   JNE $$IF24
	   call Process_A_Switch        ;                                      ;AC000;
	   JMP SHORT $$EN24
$$IF24:
	   stc                          ; set the error flag                   ;AC000;

$$EN24:

$$EN22:
	   JC $$EN16

;  $enddo                               ; enddo                                ;AC000;
   JMP SHORT $$DO16
$$EN16:

   JNC $$XL1
   JMP short $$IF30
$$XL1:

       cmp  [PInst],0                   ; is print already installed?

;      $if  e                           ; if not installed                     ;AC000;
       JNE $$IF31

	   call Set_Buffer              ; NOTE from now on the TRANSIENT could ;AC000;
					; be in a SEGMENT that is different
					; than the one set up by the loader!
					; *** MOV xx,DG will no longer work ***
					; (use PUSH CS , POP xx instead)

;      $endif                           ; endif  - installed                   ;AC000;
$$IF31:

					; Grab the pointer to the queue and
					;  lock it down.  Remember that since
					;  there are threads in the background,
					;  we may get a busy return.  We sit
					;  here in a spin loop until we can
					;  actually lock the queue.

       mov  ax,0104h                    ; get status
       call IntWhileBusy                ; on return DS:SI points to queue

       ASSUME DS:nothing
					;------------------------------------
					;    check for off-line
					;------------------------------------

       cmp  dx,ErrCnt1                  ; check count

;      $if  ae                          ; if count too high                    ;AC000;
       JNAE $$IF33

	   mov  ax,(CLASS_B shl 8) + CntMes ; printer might be off-line        ;AC000;
	   call DispMsg                 ;                                      ;AC000;

;      $endif                           ; endif - count Too high               ;AC000;
$$IF33:

;                                       ;------------------------------------
;                                       ;    display current queue
;                                       ;        ds:si points to print queue
;                                       ;        ds:di must point to display
;                                       ;                         buffer
;                                       ; xNameTrans will copy the name into
;                                       ;   the name buffer.  It will do
;                                       ;   any name truncation if needed
;                                       ;   (including any DBSC characters)
;                                       ;
;                                       ;------------------------------------
;      mov  di,offset dg:NameBuf        ;                                      ;AN009;
;      mov  ax,(xNameTrans SHL 8)       ; check for name translation           ;AN009;
;      int  21h                         ; get real path and name               ;AN009;

;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx
       call copy_to_arg_buf
;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx

       mov  ax,[whichmsg]               ;                                      ;AN000;
       mov  [whichmsg],(CLASS_C shl 8) + SecMes ; set up in queue msg          ;AC000;
       cmp  byte ptr ds:[si],0          ; is the queue empty?

;      $if  ne                          ; if queue not empty                   ;AC000;
       JE $$IF35

;          $do                          ;                                      ;AC000;
$$DO36:

	       push ds
	       call DispMsg             ;                                      ;AC000;
	       pop  ds
	       add  si,MaxFileLen       ; point to next entry in queue

;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx
	       call copy_to_arg_buf
;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx

;               mov  di,offset dg:NameBuf ;                                     ;AN009;
;               mov  ax,(xNameTrans SHL 8) ; check for name translation         ;AN009;
;               int  21h                 ; get real path and name               ;AN009;
	       mov  ax,[whichmsg]       ;                                      ;AC009;
	       cmp  byte ptr ds:[si],0  ; end of queue?

;          $enddo e                     ;                                      ;AC000;
	   JNE $$DO36

;      $else                            ; else - queue is empty                ;AC000;
       JMP SHORT $$EN35
$$IF35:

	   mov  ax,(CLASS_B shl 8) + NoFils ;                                  ;AC000;
	   call DispMsg                 ;                                      ;AC000;

;      $endif                           ; endif - queue not empty              ;AC000;
$$EN35:

					;------------------------------------
					;    exit transient
					;------------------------------------

       mov  ax,0105H                    ; unlock the print queue
       call IntWhileBusy                ; on return DS:SI points to queue
       cmp  [PInst],1                   ; are we partially installed ?

;      $if  e                           ; if so...  complete the process       ;AC000;
       JNE $$IF40

	   mov  ax,CodeR                ; close Std Devices
	   mov  ds,ax

	   ASSUME DS:CodeR

	   xor  bx,bx
	   mov  cx,5                    ; StdIN,StdOUT,StdERR,StdAUX,StdPRN

;          $do                          ; Close STD handles before keep process;AC000;
$$DO41:

	       mov  ah,CLOSE
	       int  21h
	       inc  bx

;          $enddo loop                  ;                                      ;AC000;
	   LOOP $$DO41


	   mov  dx,[ENDRES]             ; install print...
	   mov  ax,KEEP_PROCESS shl 8   ; Exit code 0

;      $else                            ; else -                               ;AC000;
       JMP SHORT $$EN40
$$IF40:

	   mov  ax,(EXIT shl 8)         ; quit with no error

;      $endif                           ; endif -                              ;AC000;
$$EN40:

;  $else                                ; else - a fatal error occured         ;AC000;
   JMP SHORT $$EN30
$$IF30:
       call DispMsg                     ; display the error message            ;AC000;
       mov  ax,(EXIT shl 8)             ; quit with error
$$EN30:
       int      21h                             ; either EXIT or KEEP_PROCESS

   push es
   xor  ax,ax
   push ax

   foo  proc    far
   ret                                  ; Must use this method, version may be < 2.00
   foo  endp

   BREAK <Process_A_Switch>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:     Process_A_Switch
;
;  FUNCTION: This routine is a DO Case that processes all valid switched for
;            PRINT.
;
;  INPUT:    Jump table offset calculated in the main routine.
;
;  OUTPUT:   Proper processing for the switch
;
;  REGISTERS USED: T.B.D.
;  (NOT RESTORED)
;
;  LINKAGE:     Call from: TRANSIENT
;
;  NORMAL       -
;  EXIT:
;
;  ERROR        -
;  EXIT:
;
;  EXTERNAL     Call to:   DispMsg        Parse_Input       GetAbsN
;  REFERENCES:             IntWhileBusy   GetAbsN2
;
;  CHANGE       04/01/87 - make SWITCH processing a PROC - FJG
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;        START Process_A_Switch
;        END Process_A_Switch
;
;******************** END   - PSEUDOCODE ***************************************

   Process_A_Switch PROC NEAR

   shl  di,1                            ;                                      ;AC000;

   jmp  cs:JMPTABLE[di]                 ;                                      ;AC000;

JMPTABLE LABEL WORD                     ;                                      ;AC000;

   DW   CASE_D                          ;                                      ;AN000;
   DW   CASE_B                          ;                                      ;AN000;
   DW   CASE_Q                          ;                                      ;AN000;
   DW   CASE_S                          ;                                      ;AN000;
   DW   CASE_U                          ;                                      ;AN000;
   DW   CASE_M                          ;                                      ;AN000;
   DW   CASE_T                          ;                                      ;AN000;
   DW   CASE_C                          ;                                      ;AN000;
   DW   CASE_P                          ;                                      ;AN000;
   DW   CASE_?

   ASSUME ds:DG,es:DG

CASE_?:
	mov     ax, MSG_OPTIONS_FIRST   ; starting msg nbr
	mov     bx, stdout              ; output handle
	mov     cx, 0                   ; no substitutions
	mov     dh, CLASS_Util          ; message class
	mov     dl, 0                   ; no input wanted
	mov     si, 0                   ; substitution ptr
@@:
	call    SYSDISPMSG
	cmp     ax, MSG_OPTIONS_LAST    ; last msg?
	je      @F                      ;  done if so
	inc     ax                      ; else bump msg nbr
	jmp     short @B                ;  and go do it
@@:

	   mov  ah,EXIT                 ; quit with error
	   xor  al, al
	   int  21h

CASE_D:                                 ; Bgncase_/D                           ;AN000;

   cmp  [PInst],0                       ;                                      ;AC000;

;  $if  e,and                           ;  if not installed                    ;AC000;
   JNE $$IF47

					;   move device name to LISTNAME
   mov  bp,[P_PTR_L]                    ;                                      ;AC000;
   mov  di,bp                           ;  save start address                  ;AC000;
   mov  ax,[P_PTR_H]                    ;                                      ;AC000;
   mov  es,ax                           ;

   ASSUME es:nothing

   xor  al,al                           ; find the length of input name        ;AN000;
   mov  cx,9                            ; it can not be longer than 8 + :      ;AN000;

   ASSUME es:DG                         ; this is a bogus assume to keep the
					;      assembler happy
   repne scas NameBuf                   ; (use NameBuf to tell assembler its   ;AN000;
					; a byte search)
   ASSUME es:nothing                    ; this puts it back right

   dec  di                              ; back up to first null                ;AN000;
   mov  ax,di                           ; pointer to end                       ;AN000;
   sub  ax,bp                           ; subtract start pointer               ;AN000;
   mov  cx,ax                           ; difference is the length             ;AN000;
   or   cx,cx                           ; is it non zero?                      ;AN000;

;  $if  ne                              ; if we have a name                    ;AN000;
   JE $$IF47

       mov  si,di                       ; set DS:SI up to source (Parse Buffer);AN000;
       mov  ax,es                       ; set ES:DI up to LISTNAME (in CodeR)  ;AN000;
       mov  ds,ax                       ;                                      ;AN000;
       mov  ax,CodeR                    ;
       mov  es,ax                       ;

       ASSUME DS:nothing,ES:CodeR

       mov  WORD PTR [LISTNAME],2020h   ; Nul out default
       mov  [LISTNAME+2]," "            ;
       mov  di,OFFSET CodeR:LISTNAME    ;
       dec  si                          ; back up to last character            ;AN004;
       cmp  BYTE PTR [si],':'           ; is there a ':' at the end of the name?

;      $if  e                           ; if it is                             ;AC000;
       JNE $$IF48
	   dec  cx                      ; Chuck the trailing ':'
;      $endif                           ;                                      ;AC000;
$$IF48:

       cmp  cx,8                        ; is the name still longer than 8?

;      $if  a                           ; if it is                             ;AC000;
       JNA $$IF50
	   mov  cx,8                    ; Limit to 8 chars for device
;      $endif                           ;                                      ;AC000;
$$IF50:

       mov  si,bp                       ;                                      ;AC000;
       rep  movsb                       ; move the device name into LISTNAME                                     ;AC000;
       mov  si,bp                       ;
       mov  [DevSpec],1                 ; remember that a device was specified
       clc                              ;   reset carry                        ;AC000;

;  $else                                ;  else                                ;AC000;
   JMP SHORT $$EN47
$$IF47:

       stc                              ;   set carry                          ;AC000;

;  $endif                               ;  endif                               ;AC000;
$$EN47:

   push cs                              ;
   pop  cx                              ;
   mov  ds,cx                           ;
   mov  es,cx                           ;
   mov  al," "                          ; invalidate this switch               ;AN005;
   mov  SW_PTR,al                       ; /D                                   ;AN005;


   JMP  CASE_END                        ; Endcase_/D                           ;AN000;

CASE_B:                                 ; Bgncase_/B                           ;AN000;

   ASSUME ds:DG,es:DG

   cmp  [PInst],0                       ;

;  $if  e                               ;  if not installed                    ;AC000;
   JNE $$IF54

       mov  ax,[P_PTR_L]                ;   get the value                      ;AC000;
       push ds                          ;   update BLKSIZ
       mov  dx,CodeR                    ;
       mov  ds,dx                       ;

       ASSUME DS:CodeR

       mov  [BLKSIZ],ax                 ;
       pop  ds                          ;

       ASSUME DS:DG

       clc                              ;   reset carry                        ;AC000;

;  $else                                ;  else                                ;AC000;
   JMP SHORT $$EN54
$$IF54:

       stc                              ;   set carry                          ;AC000;

;  $endif                               ;  endif                               ;AC000;
$$EN54:

   mov  al," "                          ; invalidate this switch               ;AN005;
   mov  B_SWITCH,al                     ; /B                                   ;AN005;

   JMP  CASE_END                        ; Endcase_/B                           ;AN000;

CASE_Q:                                 ; Bgncase_/Q                           ;AN000;

   cmp  [PInst],0                       ;

;  $if  e                               ;  if not installed                    ;AC000;
   JNE $$IF57

       mov  ax,[P_PTR_L]                ;   get the value                      ;AC000;
       push ds                          ;   update BLKSIZ
       mov  dx,CodeR                    ;
       mov  ds,dx                       ;

       ASSUME DS:CodeR

       mov  [QueueLen],al               ;
       pop  ds                          ;

       ASSUME DS:DG

       clc                              ;   reset carry                        ;AC000;

;  $else                                ;  else                                ;AC000;
   JMP SHORT $$EN57
$$IF57:

       stc                              ;   set carry                          ;AC000;

;  $endif                               ;  endif                               ;AC000;
$$EN57:

   mov  al," "                          ; invalidate this switch               ;AN005;
   mov  Q_SWITCH,al                     ; /Q                                   ;AN005;

   JMP  CASE_END                        ; Endcase_/Q                           ;AN000;

CASE_S:                                 ; Bgncase_/S                           ;AN000;

   cmp  [PInst],0                       ;

;  $if  e                               ;  if not installed                    ;AC000;
   JNE $$IF60

       mov  ax,[P_PTR_L]                ;   get the value                      ;AC000;
       push ds                          ;   update TIMESLICE, SLICECNT
       mov  dx,CodeR                    ;
       mov  ds,dx                       ;

       ASSUME ds:CodeR

       mov  [TIMESLICE],al              ;
       mov  [SLICECNT],al               ;
       pop  ds                          ;

       ASSUME ds:DG

       clc                              ;   reset carry                        ;AC000;

;  $else                                ;  else                                ;AC000;
   JMP SHORT $$EN60
$$IF60:

       stc                              ;   set carry                          ;AC000;

;  $endif                               ;  endif                               ;AC000;
$$EN60:

   mov  al," "                          ; invalidate this switch               ;AN005;
   mov  S_SWITCH,al                     ; /S                                   ;AN005;

   JMP  short CASE_END                  ; Endcase_/S                           ;AN000;

CASE_U:                                 ; Bgncase_/U                           ;AN000;

   cmp  [PInst],0                       ;

;  $if  e                               ;  if not installed                    ;AC000;
   JNE $$IF63

       mov  ax,[P_PTR_L]                ;   get the value                      ;AC000;
       push ds                          ;   update BUSYTICK
       mov  dx,CodeR                    ;
       mov  ds,dx                       ;

       ASSUME ds:CodeR

       mov  [BUSYTICK],al               ;
       pop  ds                          ;

       ASSUME ds:DG

       clc                              ;   reset carry                        ;AC000;

;  $else                                ;  else                                ;AC000;
   JMP SHORT $$EN63
$$IF63:

       stc                              ;   set carry                          ;AC000;

;  $endif                               ;  endif                               ;AC000;
$$EN63:

   mov  al," "                          ; invalidate this switch               ;AN005;
   mov  U_SWITCH,al                     ; /U                                   ;AN005;

   JMP  short CASE_END                  ; Endcase_/U                           ;AN000;

CASE_M:                                 ; Bgncase_/M                           ;AN000;

   cmp  [PInst],0                       ;

;  $if  e                               ;  if not installed                    ;AC000;
   JNE $$IF66

       mov  ax,[P_PTR_L]                ;   get the value                      ;AC000;
       push ds                          ;   update MAXTICK
       mov  dx,CodeR                    ;
       mov  ds,dx                       ;

       ASSUME ds:CodeR

       mov  [MAXTICK],al                ;
       pop  ds                          ;

       ASSUME ds:DG

       clc                              ;   reset carry                        ;AC000;

;  $else                                ;  else                                ;AC000;
   JMP SHORT $$EN66
$$IF66:

       stc                              ;   set carry                          ;AC000;

;  $endif                               ;  endif                               ;AC000;
$$EN66:

   mov  al," "                          ; invalidate this switch               ;AN005;
   mov  M_SWITCH,al                     ; /M                                   ;AN005;

   JMP  short CASE_END                  ; Endcase_/M                           ;AN000;

CASE_T:                                 ; Bgncase_/T                           ;AN000;

   push si                              ;   save parse pointer

   cmp  [PInst],0                       ;  has print been installed?

;  $if  e                               ;  if not installed                    ;AC000;
   JNE $$IF69

       call Set_Buffer                  ;  do it now                           ;AC000;

;  $endif                               ;  endif                               ;AC000;
$$IF69:
					;   set up for cancel
   mov  ax,0103H                        ;   cancel command

   call IntWhileBusy                    ;

   pop  si                              ;   restore parse pointer

   clc                                  ;  reset carry                         ;AC000;

   JMP  short CASE_END                  ; Endcase_/T                           ;AN000;

CASE_C:                                 ; Bgncase_/C                           ;AN000;

   cmp  [PInst],0                       ;  has print been installed?

;  $if  ne                              ;  if installed                        ;AC000;
   JE $$IF71

       mov  [CanFlag],1                 ;   set CanFlag

;  $else                                ;  else                                ;AC000;
   JMP SHORT $$EN71
$$IF71:

       call Set_Buffer                  ;                                      ;AC000;

;  $endif                               ;  endif                               ;AC000;
$$EN71:

   clc                                  ;  reset carry                         ;AC000;

   JMP  short CASE_END                  ; Endcase_/C                           ;AN000;

CASE_P:                                 ; Bgncase_/P                           ;AN000;

   cmp  [PInst],0                       ;  has print been installed?

;  $if  ne                              ;  if installed                        ;AC000;
   JE $$IF74

       mov  [CanFlag],0                 ;   reset CanFlag

;  $else                                ;  else                                ;AC000;
   JMP SHORT $$EN74
$$IF74:

       call Set_Buffer                  ;                                      ;AC000;

;  $endif                               ;  endif                               ;AC000;
$$EN74:

   clc                                  ;  reset carry                         ;AC000;

					; Endcase_/P

CASE_END:                               ; End_case                             ;AN000;

;  $if  c                               ; if carry set                         ;AC000;
   JNC $$IF77

       mov  ax,(Parse_error shl 8) + INVPARM ; set up for Invalid_parm message ;AN000:

       cmp  [PInst],0                   ;  has print been installed?

;      $if  ne                          ;  if installed                        ;AN005;
       JE $$IF78

	   call DispMsg                 ;  display the message and keep going  ;AN005;

;      $endif                           ;  endif                               ;AN005;
$$IF78:

;  $endif                               ; endif                                ;AC000;
$$IF77:

   ret

   Process_A_Switch ENDP

   BREAK <Submit_File>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        Submit_File -  PRINT TRANSIENT to Resident Interface Routine
;
;  FUNCTION:    Resolved ambiguous file names (containing ? and *) and submits
;               the file to the Resident component of PRINT for printing.
;
;  INPUT:       File name in Parse buffer
;
;  OUTPUT:      None.
;
;  NOTE:        This code is primarily old code, but it has been completely
;               restructured and SALUTed.
;
;  REGISTERS USED: T.B.D.
;  (NOT RESTORED)
;
;  LINKAGE:     Call from: TRANSIENT
;
;  NORMAL       -
;  EXIT:
;
;  ERROR        -
;  EXIT:
;
;  EXTERNAL     Call to:   DispMsg        Parse_Input       GetAbsN
;  REFERENCES:             IntWhileBusy   GetAbsN2
;
;  CHANGE       04/01/87 - change PaFile to Submit_File   - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;        START
;        .
;        .
;        .
;        .
;        .
;
; INPUT: CanFlag and Ambig set appropriately
;
;       if CanFlag
;               set up cancel
;               call IntWhileBusy
;               if error
;                       process the error
;               endif
;       else
;               if Ambig and
;
;               call getabsn
;
;               if error
;                       load error message
;                       call DispMsg
;               else
;                       do (until not Ambig)
;                               call open_file
;                               if error
;                                       do error handling
;                               else
;                                       close file
;                                       submit packet
;                                       if error
;                                               set up message
;                                       endif
;                               endif
;                               if error
;                                       call Dispmsg
;                               endif
;                       leave if error
;                               if Ambig
;                                       call Absn2 (will set fail if at end)
;                               else
;                                       set fail
;                               endif
;                       enddo on fail
;                       if no message
;                               reset fail
;                       endif
;               endif
;       endif
;       .
;       .
;       .
;       if error message
;               call DispMsg
;       endif
;
;       ret
;
;       END
;
;******************** END   - PSEUDOCODE ***************************************

   Submit_File PROC NEAR

   ASSUME ds:DG,es:DG

   nop                                  ; for production - uncomment this line and comment the next
   nop

   cmp  [PInst],0                       ; has print been installed?
   JNE $$IF81

   call Set_Buffer                      ; if not, better do it now                     ;AC000;

$$IF81:
   cld                                  ; just in case...
   mov  [Ambig],0                       ; assume not an ambigous file
					;------------------------------------
					;    Check for drive specifier
					;------------------------------------
   mov  si,P_PTR_L                      ;                                      ;AC000;
   mov  ax,P_PTR_H                      ;                                      ;AC000;
   mov  ds,ax

   ASSUME ds:nothing

   mov  di,offset dg:NameBuf            ; buffer for full file name
   cmp  byte ptr [si+1],":"             ; check if there is a drive designator
   je   $$if83

   mov  ah,Get_Default_Drive            ; get it...
   int  21h
   mov  dl,al                           ; save for later (used in DoPath)
   inc  dl                              ; adjust to proper code (A=1,B=2,...)
   add  al,"A"                          ; convert to letter code
   stosb                                ; store letter code
   mov  al,":"
   stosb
   clc                                  ; clear error flag                     ;AC000;
   jmp  short  $$en83

$$IF83:
   mov  al,byte ptr [si]                ; get drive letter
   sub  al,"@"                          ; conver to proper code...
   jna  $$if85                          ; if not a valid drive, go fix

   mov  dl,al                           ; save for later (used in DoPath)
   movsb                                ; move the drive letter
   movsb                                ; move the ":"
   clc                                  ;                                      ;AC000;
   jmp  short  $$en85

$$IF85:
   mov  ax,(CLASS_B shl 8) + InvDrvMes ; set up error message          ;AC000;
   stc                                  ; set error flag                       ;AC000;

$$EN85:
$$EN83:
					;------------------------------------
					; could have CF & message # here
					;------------------------------------
   jc  $$if89
					;------------------------------------
					;    Check for full path
					;------------------------------------
   mov  al,[PathChar]
   cmp  byte ptr [si],al                ; does it start from the root?
   je   $$if90
					; if not get the current path          ;AC000;
   stosb                                ; store path character
   push si
   mov  si,di                           ; buffer for current directory
   mov  ah,Current_Dir                  ; get current directory
   int  21h
   jnc  $$if91

   pop  si                              ; clear the stack
   mov  ax,(CLASS_B shl 8) + InvDrvMes ; set up error message      ;AC000;
   jmp  short  $$en91

$$IF91:
$$DO93:
					; find terminating nul                 ;AC000;
   lodsb
   or   al,al
   jnz  $$do93

   dec  si                              ; adjust to point to nul
   mov  ax,di                           ; save pointer to beg. of path
   mov  di,si                           ; here is were the file name goes
   pop  si                              ; points to file name
   cmp  ax,di                           ; if equal then file is in the root
   je   $$if95
					; if not, add a path char              ;AC000;
   mov  al,[PathChar]
   stosb                                ; put path separator before file name

$$IF95:
					;------------------------------------
					;    Check for valid drive.
					;------------------------------------
					; Done by getting current dir of
					; the drive in question (already in
					; DL) into NameBuf. If no error the
					; valid drive and we throw away the
					; current dir stuf by overwriting it
					; with the filename.

   clc                                  ; reset error flag                     ;AC000;

$$EN91:
					; else - it starts from the root       ;AC000;
   jmp  short  $$en90

$$IF90:
					; DL has drive number (from DrvFound)
   push si
   mov  si,di                           ; buffer for current directory
   mov  ah,Current_Dir                  ; get current directory
   int  21h
   pop  si
   jnc  $$if99

   mov  ax,(CLASS_B shl 8) + InvDrvMes ;                               ;AC000;

$$IF99:
$$EN90:
$$IF89:
					;------------------------------------
					; could have CF & message # here
					;------------------------------------
   jc  $$if103

   mov  cx,MaxFileLen                   ; let's not overflow file name buffer
   mov  ax,di                           ; CX := MaxFileLen -
					;       long(&NameBuf - &PtrLastchar)
   sub  ax,offset dg:NameBuf            ; size of the filename so far
   sub  cx,ax                           ; size left for the filename
   jnc  $$if104

   mov  cx,1                            ; Set cx to fall through to FNTooLong

$$IF104:
					; WHILE (Length(FileName) <= MaxFileLen)
					;       DO copy in the file name       ;AC000;
$$DO106:
   lodsb
   stosb
   cmp  al,"*"
					; if it's ambigous - *, or......       ;AC000;
   je  $$ll107

   cmp  al,"?"                          ;                              :
					; if it's ambigous - ?, .......:       ;AC000;
   jne  $$if107

$$LL107:
   mov  [Ambig],1                       ;       ambigous filename found

$$IF107:
   or   al,al                           ;       end of name?
   clc                                  ;                                      ;AC000;
   jnz  $$if106

   jmp  short  $$sr106

$$IF106:
   loop  $$do106

   dec  di                              ; the name was too long !
   mov  [NulPtr],di
   mov  ax,(CLASS_C shl 8) + NamTMes    ;                                      ;AC000;
   stc                                  ;                                      ;AN010;
					; we have the full absolute name...    ;AC000;
$$SR106:
$$IF103:
   push cs                              ; restore ds to DG
   pop  ds

   ASSUME ds:DG
					;------------------------------------
					; could have CF & message #
					;------------------------------------
   jnc  $$xl2
   jmp  $$if114

$$XL2:
   dec  di
   mov  [NulPtr],di                     ; save pointer to terminating nul
					;------------------------------------
					;    check for an option following name
					;------------------------------------
   call Parse_Input                     ;                                      ;AC000;
   cmp  ax,noerror                      ;  a parse error?                      ;AC000;
   jne  $$if115

   cmp  [P_SYN],offset DG:C_SW_ptr      ;  is it the cancel switch /C       ;AC000;
   jne  $$if116

   mov  [CanFlag],1                     ; set cancel flag
   jmp  short  $$en116

$$IF116:
   cmp  [P_SYN],offset DG:P_SW_ptr      ;  is it the print switch /P    ;AC000;
   jne  $$if118

   mov  [CanFlag],0                     ; reset cancel flag

$$IF118:
$$EN116:
					; if /C or /P found                    ;AC000;
   jne  $$if121

   mov  [ordinal],cx                    ;                                      ;AC000;
   mov  [scan_ptr],si                   ;                                      ;AC000;

$$IF121:
$$IF115:
					;------------------------------------
					;    check file exists
					;------------------------------------
   cmp  [CanFlag],1                     ; are we in cancel mode
   jne  $$if124
					;------------------------------------
					;     Issue a cancel command
					;------------------------------------
					; NOTE: ds:dx MUST point to NameFuf !!!
					; set up cancel
   mov  dx,offset dg:NameBuf            ; filename
   mov  ax,0102H
   call IntWhileBusy
   jnc  $$if125

   cmp  ax,2
					; Original Print Code timing jump      ;AC000;
   je   $$if126
					;------------------------------------
					;***** PROCESS CANCEL ERROR
					;------------------------------------
$$IF126:
   mov  ax,(CLASS_C shl 8) + BadCanMes ;                               ;AC000;
   stc                                  ;                                      ;AC000;

$$IF125:
					; submit mode active                   ;AC000;
   jmp  $$en124

$$IF124:
   cmp  [Ambig],1                       ; is this an ambiguous name?
   jne  $$if130

					; do another ambiguous name
   call GetAbsN                         ; get abs name into NameBuf
; M00 - I commented out the next 4 statements
;   jnc  $$if130
;   mov  ax,(CLASS_C shl 8) + BadNameMes ;                             ;AC000;
;   call DispMsg                                ; call DispMsg                         ;AN000;
					; there is at least 1 name             ;AC000;
;   jmp  $$en130

$$IF130:
$$DO132:
					; do until all names processed         ;AC000;
					; Check if this is a local drive -
					;    If it is, convert the filename
					;    to its physical name.

   lea  si,NameBuf                      ; DS:SI = NameBuf containing name      ;AN010;
   mov  bl,ds:[si]                      ; get DRIVE ID                         ;AN010;
   sub  bl,40h                          ; convert to a number                  ;AN010;
					; IOCtl call to see if target drive is local
   mov  ax,(IOCTL SHL 8) + 9 ;AN010;
   int  21h                             ; IOCtl + dev_local  <4409>            ;AN010;
					; target drive local and               ;AN010;
   jc   $$if133

   test dx,1200H                        ; check if (x & 0x1000)                ;AN010;
					;      (redirected or shared)
					; if RC indicates NO network drive     ;AN010;
   jnz  $$if133
					; Translate the file name into an
					; absolute path name - note that
					; from this point on only SERVER DOS
					; calls will work with this name!

   lea  di,TokBuf                       ; DS:DI = output buffer                ;AN010;
   mov  ax,(xNameTrans SHL 8)           ; check for name translation     ;AN010;
   int  21h                             ; get real path and name               ;AN010;
   jc   $$if133

   xchg di,si                           ; switch source and destination        ;AN010;
   mov  cx,((MaxFileLen+16)/2)          ; move Max buffer              ;AN010;
   cld                                  ;AN010;
   rep  movsw                           ; move name back into NameBuf          ;AN010;

; Reset FnamPtr to the last \ + 1 in NameBuf, which may well have changed
; if the absolute pathname being substituted for *.* is a partial pathname
; which includes directories, e.g.  e:\print\print_t.asm becomes c:\dos500\
; cmd\print\print_t.asm, because e: was subst'd for c:\dos500\cmd
   mov  cl, PathChar
back: dec  di
   cmp  byte ptr [di], cl
   jne  back
   inc  di
   mov  FnamPtr, di

; Looking for new file, so reset APPEND flag.
   mov  triedappend, 0

$$IF133:
					; set up to open file
   xor  cx,cx                           ; zero attribute type                  ;AC000;
   mov  di,cx                           ;                                      ;AC001;
   dec  di                              ; no list supplied                     ;AC001;
   mov  dx,(ignore_cp shl 8) + (failopen shl 4) + openit ;     ;AC001;
   mov  open_seg,es                     ; segment fix up for OPEN_FILE         ;AC000;
   lds  si,OPEN_FILE                    ;                                      ;AC001;
   mov  bx,open_mode                    ; set open mode                        ;AC000;
   mov  ah,ExtOpen                      ; open for reading exist.              ;AN010;
   mov  al,ds:[si]                      ; recover drive ID                     ;AN010;
   call TO_DOS                          ; make a SERVER DOS call               ;AC010;

; Start Fix  M00
   jc   s1                              ; if open failed, search APPENDed dirs
   jmp  $$if135

s1:
   cmp  triedappend, 1                 ;   but only if we haven't, yet
   jne  s2
   jmp   exterr

s2:
   push  ds
   push  es
   cld

; set the DTA space we will be using
   cmp  ambig, 1
   je   noset                           ; if ambig is set, dta was already set
   mov  ah, 01ah
   mov  dx, OFFSET dg:SearchBuf
   int  21h

; see if APPEND is installed
noset:
   mov  ax, 0b700h
   int  2fh
   or   al, al
   jnz  s3
   jmp  nopath                          ; append not installed
   ; Don't just give up here -- try to open the file again so the
   ; GetExtendedError call gets the right value.

; get the current disk
s3:
   mov  ah, 19h
   int  21h
   add  al, 'A'
   mov  dsklet, al

; get the pointer to the APPEND directory string
   mov  ax, 0b704h
   int  2fh
   mov  nxtdir, di
   mov  ax, es
   mov  appseg, ax

top:
   mov          si, nxtdir                      ; do FIRST while DS-> data !
   push ds                                      ; put ds on stack.  es will retrieve unless error
   mov ax, appseg
   mov  ds, ax
   mov  al, semicolon                           ; terminator char is ';'
   call string_len                              ; returns length in CX
   or   cx, cx                                  ; if ';' didn't work, try 0
   jne  cntnue
   mov  al, endofline
   call string_len
   or   cx, cx                          ; string empty, no more dirs to try ?
   jnz  cntnue

   pop  ds    ;restore data segment saved on stack 
   stc                                  ; if we got to here, nothing was found
   jmp  short nopath

; save location of the next directory in the path
cntnue:
   mov  ax, cx
   add  ax, si
; We need to do the following check to make sure we stop looking for APPENDed
; directories as soon as the APPEND string ends in a null.
   mov   di, ax
   cmp   byte ptr [di], endofline
   je    empty_string
   inc   ax

empty_string:
   pop  es                                      ; get data segment
   mov  es:nxtdir,  ax

; now copy the directory into appbuf
   mov  di,  OFFSET es:appbuf
   cmp  byte ptr ds:[si + 1], ':'               ; is drive specified ?
   je   skipdl                                  ;  then skip adding drive letter
   mov  al, es:dsklet
   stosb
   mov  al, ':'
   stosb

skipdl:
   rep  movsb
   cmp  byte ptr es:[di - 1], '\'
   je   ns                                      ; no slash - don't add slash
   mov  byte ptr es:[di], '\'
   inc  di

;
; add the file name to the path being constructed in appbuf
;
; N.b., this should NOT be the name pointed to by p_ptr_h:p_ptr_l, since
; ParseInput has been called to advance this to the next command-line
; argument past the filename we are currently processing.  Instead, we want
; the filename pointed to by fnamptr.
;
ns:
;   mov  ax, es:p_ptr_h

   mov   ax, es
   mov  ds, ax

;   mov  si, p_ptr_l
   mov   si, fnamptr

   mov  al, endofline                           ; Endofline equ 0
   call string_len
   rep  movsb

; see if we can "find" the file
   mov  ah, 4eh
   xor  cx, cx
   mov  dx, OFFSET ds:appbuf
   int  21h
   jc   clearout

; findfirst succeeded, so copy the full pathname into NameBuf
   mov  si,  OFFSET ds:appbuf
   mov  di,  OFFSET ds:NameBuf
   call string_len
   rep  movsb                                   ; get correct directory first

   mov  si,  OFFSET dg:SearchBuf
   add  si,  1eh                                ; get filename from DTA

reverse:
   cmp  byte ptr es:[di], '\'
   je   catenate
   dec  di
   jmp  short  reverse

catenate:
   inc  di
   mov  es:FNamPtr, di                          ; save for Copy_Name
   call string_len
   inc  cx                                      ; copy the null byte, too
   rep  movsb
   jmp  short  nopath

; zero out buffer
clearout:
   mov  di,  OFFSET ds:appbuf
   xor  al, al
   mov  cx, 64
   rep  stosb
   jmp  top

nopath:
   pop  es
   pop  ds
   mov  triedappend, 1
   jmp  $$if133
; End Fix M00

exterr:                                 ; do error handling
   SaveReg <SI,DI,BP,ES,DS>
   mov  ah,GetExtendedError
   int  21h
   mov  ah,DOS_error
   RestoreReg <DS,ES,BP,DI,SI>
   stc                                  ;                                      ;AC000;
   jmp  short  $$en135

$$IF135:
; make sure the file name does not designate a device
   SaveReg <SI,DI,BP,ES,DS,AX,BX,DX>
   mov  bx,  ax                         ; bx = file handle
   mov  ax,  GetDevInfo                 ; 4400H
   int  21h
   and  dx,  IsDevice?                  ; bit 7 set ?
   pushf
					; close file
;M000
; Bx already contains the handle. This gives an invalid handle and so
;the file never gets closed and this leads to sharing violations on other
;operations on this file. Also, Print soon runs out of handles.
;M000;   mov  bx,ax                           ; copy handle

   mov  ah,close
   int  21h                             ;

   popf
   RestoreReg <DX,BX,AX,DS,ES,BP,DI,SI>
   jz Continue

   mov  AX, (CLASS_B shl 8) + ACCESS_DENIED
   stc
   jmp  short $$en135

Continue:
   clc
					; submit packet
   mov  dx,offset dg:NameBuf            ;
   mov  word ptr [SubPack+1],dx         ; store pointer to name in
   mov  word ptr [SubPack+3],ds         ;  submit packet
   mov  dx,offset dg:SubPack            ; DS:DX address of packet
   mov  ax,0101H                        ; submit a file to resident
   call IntWhileBusy
   jc   $$if137

   cmp  ax,error_queue_full
   je   $$if137

   mov  [QFullMes],0                    ; queue is not full
   clc                                  ; reset the error flag                 ;AC000;
   jmp short $$en137

$$IF137:
   cmp  [QFullMes],1                    ; has the message already been issued?
   je   $$if139
					; if the message has not been posted   ;AC000;
   mov  [QFullMes],1                    ; set the 'message posted' flag
   mov  ax,(CLASS_B shl 8) + FullMes    ; load msg #  ;AC000;
   stc                                  ; display the message                  ;AC000;
   jmp short $$en139

$$IF139:
    clc                                 ; make sure carry clear
					; message processed                    ;AC000;
$$EN139:
					; queue errors                         ;AC000;
$$EN137:
					; OPENing errors                       ;AC000;
$$EN135:
   jnc $$if144

   call DispMsg                         ; display the error with this file     ;AC000;

$$IF144:
					; quit if error in displaying message  ;AC000;
   jc $$en132

   cmp  [Ambig],1                       ; are we processing an ambigous name?
   jne  $$if147
					; call Absn2 (will set fail if at end)
   call GetAbsN2                        ; get another file name
   jmp short $$en147

$$IF147:
   mov  ax,0                            ; set fail                             ;AC000;
   stc                                  ;                                      ;AC000;

$$EN147:
   jc  $$xl3
   jmp $$do132

$$XL3:
$$EN132:
   cmp  ax,0                            ; is there a message?                  ;AC000;
   jne  $$if151
					; if no message                        ;AC000;
   clc                                  ; reset fail                           ;AC000;
					; no message to display                ;AC000;
$$IF151:
					; any submission errors                ;AC000;
$$EN130:
					; submit or cancel                     ;AC000;
$$EN124:
					; any errors so far                    ;AC000;
$$IF114:
   jnc $$if156

   call DispMsg                         ; display the submit error             ;AC000;
$$IF156:
GetOut: ret                                  ; finished submission                  ;AC000;

   Submit_File ENDP



;***************************************************************************
; string_len expects ds:si to point to the desired string, and al to contain
; the desired terminator character
;***************************************************************************
string_len      proc    near

; save es:di because we  trash them
	push    es
	push    di

; set es:di = ds:si
	push    ds
	pop     es
	mov     di, si

; find the terminator character somewhere in the first 64 bytes of the string
	mov     cx, 64                  ; pathname can't be longer anyhow
	repne   scasb
	jne     finis

; set CX equal to string length
	sub     cx, 64
	neg     cx
	dec     cx                      ; don't count the ';' in the length

finis:  pop     di
	pop     es
	ret

string_len      endp



   BREAK <Set_Buffer>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        Set_Buffer  -  PRINT Build Resident Buffer routine.
;
;  FUNCTION:    Calculate the buffer size required by the resident component and
;               move the transient portion accordingly
;
;  NOTE:        This code is primarily old code, but it has been partly
;               restructured in order to SALUT it.
;
;  INPUT:       None.
;
;  OUTPUT:      Resident Buffer established, and TRANSIENT moved accordingly.
;
;  REGISTERS USED: T.B.D.
;  (NOT RESTORED)
;
;  LINKAGE:     Called from: TRANSIENT
;
;  NORMAL       -
;  EXIT:
;
;  ERROR        -
;  EXIT:
;
;  EXTERNAL     Calls to:  DispMsg,  Parse_Input
;  REFERENCES:
;
;  CHANGE       03/11/87 - Change SETBUF to Set_Buffer   - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;        START
;        END
;
;******************** END   - PSEUDOCODE ***************************************

   Set_Buffer PROC NEAR

   push cs
   pop  ds
   assume ds:DG
   mov  dl,[PathChar]                   ; transfer PathChar (in PRINT_T)
   mov  ax,CodeR
   mov  es,ax
   assume es:CodeR
   mov  [PChar],dl                      ; to PChar (in PRINT_R)


					;------------------------------------
					;    check device
					;------------------------------------

   cmp  [DevSpec],1                     ; was it already specified?

;  $if  ne,and                          ; if not specified ...........         ;AC000;
   JE $$IF158

   lea  di,TokBuf                       ; ES:DI point to TokBuf      :         ;AC000;
   mov  [TokBuf],9                      ; max of 9 chars             :
   mov  [TokBuf+1],0                    ; assume zero in             :

   push es                              ;                                      ;AC000;
   mov  ax,ds                           ;                                      ;AC000;
   mov  es,ax                           ;                                      ;AC000;

   assume es:DG                         ;                                      ;AC000;

   mov  ax,(CLASS_D shl 8) + prompt     ; DispMsg treats 'prompt' as :         ;AC000;
					;       a special case       :
   call DispMsg                         ;                            :         ;AC000;

   mov  ax,(CLASS_B shl 8) + NEXT_LINE  ; advance to next line after :         ;AC000;
					;       "buffered input" call:
   call DispMsg                         ;                            :         ;AC000;

   pop  es                              ;                                      ;AC000;

   assume es:CodeR

   mov  cl,[TokBuf+1]                   ; check how many read in     :
   or   cl,cl                           ;                            :

;  $if  nz                              ; if a CR was typed..........:         ;AC000;
   JZ $$IF158

       xor  ch,ch
       mov  si,offset dg:TokBuf+2
       mov  di,offset CodeR:ListName
       push si
       mov  dx,si                       ; get ready to capitalize              ;AN007;
       add  si,cx
       mov  byte ptr [si],0             ; turn it into an ascii z string       ;AN007;
       mov  ax,(GetExtCntry SHL 8) + Cap_ASCIIZ ; let DOS capitalize the string ;AN007;
       INT  21h                         ; call DOS to do it                   ;AN007;
       dec  si
       cmp  byte ptr [si],':'

;      $if  e                           ; if a :                               ;AC000;
       JNE $$IF159
	   dec  cx                      ; get rid of trailing ':'
;      $endif                           ; endif - a :                          ;AC000;
$$IF159:

       cmp  cx,8                        ; is it greater than 8 ?               ;AN000;

;      $if  a                           ; if greater - force it to 8.:         ;AC000;
       JNA $$IF161

	   mov  cx,8                    ;                                      ;AN000;

;      $endif                           ;                                      ;AC000;
$$IF161:

       pop  si

       rep  movsb                       ;                                      ;AC000;

;  $endif                               ;                                      ;AC000;
$$IF158:
					;------------------------------------
					;    queue size
					;------------------------------------
   push es
   pop  ds

   ASSUME ds:CodeR

   mov  ax,MaxFileLen                   ; maximum length of a file name
   mul  [QueueLen]                      ; AX = result
   add  ax,offset CodeR:FileQueue
   mov  [EndQueue],ax                   ; save pointer to last nul
   inc  ax
   mov  [buffer],ax                     ; beggining of buffer

					;------------------------------------
					;--- buffer size
					;------------------------------------

   add  ax,[BlkSiz]
   mov  [ENDPTR],AX                     ; Set end of buffer pointer
   mov  [NXTCHR],AX                     ; Buffer empty
   add  ax,100h                         ; allow for header
   add  ax,16                           ; Convert to para
   shr  ax,1
   shr  ax,1
   shr  ax,1
   shr  ax,1
   mov  [EndRes],ax                     ; Add size of buffer to term res size

					; Now JUMP into PRINT_R - the resident
   jmp  MoveTrans                       ;   code to initialize the buffer space

TransRet:                               ; after moving the transient we come
					;  here.
   sti                                  ; Ints were off during initialization
   push cs                              ; CAUTION !!!! from here on in DG is
   pop  ax                              ;  not the ASSEMBLED DG - its bogus -
   mov  ds,ax                           ;  after the move! Only PUSH/POP will
   mov  es,ax                           ;  work.
   mov  WORD PTR [insert_ptr_seg],ax    ; fix up segment in SUBLIST for msgs!  ;AC002;
   mov  WORD PTR [P_PTR_H],ax           ; fix up segment for PARSE             ;AC002;

   ASSUME ds:DG,es:DG


   call SYSLOADMSG                      ; RE-Initialize the Message Services   ;AN016;
					;  - WARNING!!! the Message retriver
					;    keeps track of offset and SEGMENT
					;    for extended and parse errors
					;    EVEN THOUGH WE ARE NEAR!!!  since
					;    the location could now have been
					;    moved - it must now be reset

					;------------------------------------
					;   normalize int handlers for new location of dg
					;------------------------------------

   mov  ax,(SET_INTERRUPT_VECTOR shl 8) or 23h
   mov  dx,OFFSET DG:INT_23
   int  21h
   mov  ax,(SET_INTERRUPT_VECTOR shl 8) or 24h
   mov  dx,OFFSET DG:INT_24
   int  21h

   mov  [PInst],1                       ; remember we just installed resident part

   ret                                  ; finished                             ;AC000;

   Set_Buffer ENDP

   BREAK <copy_to_arg_buf>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:     copy_to_arg_buf
;
;  FUNCTION: Copies the names of the files in the print queue into NameBuf
;               - one name copied per invocation
;
;  INPUT:
;
;  OUTPUT:
;
;
;  REGISTERS USED: T.B.D.
;
;  LINKAGE:     Called from:
;
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START copy_to_arg_buf
;
;       ret
;
;       END copy_to_arg_buf
;
;******************** END   - PSEUDOCODE ***************************************

   copy_to_arg_buf PROC NEAR

   push di
   push si
   push ax                              ; must preserve AX (could be message #);AN000;
   mov  di,offset dg:NameBuf

;  $do                                  ;                                      ;AC000;
$$DO164:

       lodsb
       or   al,al

;  $leave z                             ;                                      ;AC000;
   JZ $$EN164

       stosb

;  $enddo                               ;                                      ;AC000;
   JMP SHORT $$DO164
$$EN164:

   stosb
   pop  ax                              ; must preserve AX (could be message #);AN000;
   pop  si
   pop  di

   ret

   copy_to_arg_buf ENDP

   BREAK <IntWhileBusy>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        IntWhileBusy
;
;  FUNCTION:
;
;  INPUT:
;
;  OUTPUT:
;
;
;  REGISTERS USED: T.B.D.
;
;  LINKAGE:     Called from:
;
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START IntWhileBusy
;
;       ret
;
;       END IntWhileBusy
;
;******************** END   - PSEUDOCODE ***************************************

   IntWhileBusy PROC NEAR

;  $search complex                      ;                                      ;AC000;
   JMP SHORT $$SS167
$$DO167:

       pop  ax

;  $strtsrch                            ;                                      ;AC000;
$$SS167:

       push ax
       int  ComInt

;  $exitif nc                           ;                                      ;AC000;
   JC $$IF167

       add  sp,2                        ; clear off AX and clear carry

;  $orelse                              ;                                      ;AC000;
   JMP SHORT $$SR167
$$IF167:

       cmp  ax,error_busy

;  $leave nz                            ;                                      ;AC000;
   JNZ $$EN167

;  $endloop                             ;                                      ;AC000;
   JMP SHORT $$DO167
$$EN167:

       add  sp,2                        ; clear off AX
       stc                              ;                                      ;AC000;

;  $endsrch                             ;                                      ;AC000;
$$SR167:

   ret

   IntWhileBusy ENDP

   BREAK <GetAbsN>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        GetAbsN
;
;  FUNCTION:    Return first absolute name from ambigous name
;
;  INPUT:       NameBuf has the ambigous File Name
;
;  OUTPUT:      Carry Set if no files match
;               else NameBuf has the absolute name
;
;  REGISTERS USED: T.B.D.
;
;  LINKAGE:     Called from:
;
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START GetAbsN
;
;       ret
;
;       END GetAbsN
;
;******************** END   - PSEUDOCODE ***************************************

   GetAbsN PROC NEAR

public GetAbsN

   ASSUME ds:DG,es:DG

   mov  ah,Set_DMA                      ; buffer for ffirst / fnext
   mov  dx,offset dg:SearchBuf
   int  21h
					;------------------------------------
					;    look for a match
					;------------------------------------
   mov  dx,offset dg:NameBuf
   mov  cx,0                            ; no attributes
   mov  ah,Find_First
   int  21h

;  $if  nc                              ; if no error                          ;AC000;
   JC $$IF174

					;------------------------------------
					;    Place new name in NameBuf
					;------------------------------------
       mov  si,[NulPtr]
       std                              ; scan back

;      $do                              ;                                      ;AC000;
$$DO175:

	   lodsb
	   cmp  al,PathChar

;      $enddo e                         ;                                      ;AC000;
       JNE $$DO175

       cld                              ; just in case...
       inc  si
       inc  si
       mov  [FnamPtr],si
       call CopyName
       clc                              ;                                      ;AC000;

;  $endif                               ; endif -no error                      ;AC000;
$$IF174:

   ret

   GetAbsN ENDP

   BREAK <GetAbsN2>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        GetAbsN2
;
;  FUNCTION:    Return next absolute name from ambigous
;
;  INPUT:
;
;  OUTPUT:
;
;  REGISTERS USED: T.B.D.
;
;  LINKAGE:     Called from:
;
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START GetAbsN2
;
;       ret
;
;       END GetAbsN2
;
;******************** END   - PSEUDOCODE ***************************************

   GetAbsN2 PROC NEAR

   mov  ah,Set_DMA                      ; buffer for ffirst / fnext
   mov  dx,offset dg:SearchBuf
   int  21h
   mov  ah,Find_Next
   int  21h

;  $if  nc                              ; if no error                          ;AC000;
   JC $$IF178

       call CopyName                    ; we found one
       clc                              ;                                      ;AC000;

;  $endif                               ; endif - no error                     ;AC000;
$$IF178:

   mov  ax,0                            ; signal no message available

   ret                                  ; return

   GetAbsN2 ENDP

   BREAK <CopyName>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        CopyName
;
;  FUNCTION:    Copy name from search buf to NameBuf
;
;  INPUT:
;
;  OUTPUT:
;
;  REGISTERS USED: T.B.D.
;
;  LINKAGE:     Called from:
;
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START CopyName
;
;       ret
;
;       END CopyName
;
;******************** END   - PSEUDOCODE ***************************************

   CopyName PROC NEAR

   mov  di,[FNamPtr]
   mov  si,offset dg:SearchBuf.find_buf_pname
   cld

;  $do                                  ; until null is found                  ;AC000;
$$DO180:

       lodsb                            ; move the name
       stosb
       or   al,al                       ; nul found?

;  $enddo e                             ;                                      ;AC000;
   JNE $$DO180

   ret

   CopyName ENDP

   BREAK <Save_Vectors>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:         Save_Vectors
;
;  FUNCTION:     save int vectors in case of error
;
;  INPUT:
;
;  OUTPUT:
;
;  REGISTERS USED: T.B.D.
;
;  LINKAGE:     Called from:
;
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START Save_Vectors
;
;       ret
;
;       END Save_Vectors
;
;******************** END   - PSEUDOCODE ***************************************

   Save_Vectors PROC NEAR

   mov  ax,(get_interrupt_vector shl 8) or SOFTINT ; (SOFTINT)
   int  21h

   ASSUME es:nothing

   mov  word ptr [i28vec+2],es
   mov  word ptr [i28vec],bx

   mov  ax,(get_interrupt_vector shl 8) or COMINT ; (COMINT)
   int  21h
   mov  word ptr [i2fvec+2],es
   mov  word ptr [i2fvec],bx

   mov  ax,(get_interrupt_vector shl 8) or 13h
   int  21h
   mov  word ptr [i13vec+2],es
   mov  word ptr [i13vec],bx

   mov  ax,(get_interrupt_vector shl 8) or 15h
   int  21h
   mov  word ptr [i15vec+2],es
   mov  word ptr [i15vec],bx

   mov  ax,(get_interrupt_vector shl 8) or 17h
   int  21h
   mov  word ptr [i17vec+2],es
   mov  word ptr [i17vec],bx

   mov  ax,(get_interrupt_vector shl 8) or 14h
   int  21h
   mov  word ptr [i14vec+2],es
   mov  word ptr [i14vec],bx

   mov  ax,(get_interrupt_vector shl 8) or 05h
   int  21h
   mov  word ptr [i05vec+2],es
   mov  word ptr [i05vec],bx

   mov  ax,(get_interrupt_vector shl 8) or INTLOC ; (INTLOC)
   int  21h
   mov  word ptr [i1cvec+2],es
   mov  word ptr [i1cvec],bx

   push cs
   pop  es

   ASSUME es:DG

   Save_Vectors ENDP

   BREAK <GetHInt>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        GetHInt
;
;  FUNCTION:    Install PRINT Interupt Handler routines
;
;  INPUT:
;
;  OUTPUT:
;
;  REGISTERS USED: T.B.D.
;
;  LINKAGE:     Called from: TRANSIENT,
;
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START GetHInt
;
;       ret
;
;       END GetHInt
;
;******************** END   - PSEUDOCODE ***************************************

   GetHInt PROC NEAR

   ASSUME ds:DG,es:DG

   push es
   mov  ax,(GET_INTERRUPT_VECTOR shl 8) OR 24h
   int  21h

   ASSUME es:nothing

   mov  WORD PTR [HARDCH],bx
   mov  WORD PTR [HARDCH+2],es
   pop  es

   ASSUME es:DG

   ret

   GetHInt ENDP

   BREAK <SetInts>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        SetInts
;
;  FUNCTION:    Install PRINT Interupt Handler routines
;
;  INPUT:
;
;  OUTPUT:
;
;  REGISTERS USED: T.B.D.
;  (NOT RESTORED)
;
;  LINKAGE:     Called from: TRANSIENT,
;
;  NORMAL
;  EXIT:
;
;  ERROR
;  EXIT:
;
;  EXTERNAL
;  REFERENCES:
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START SetInts
;
;       ret
;
;       END SetInts
;
;******************** END   - PSEUDOCODE ***************************************

   SetInts PROC NEAR

   ASSUME ds:DG,es:DG

   mov  AX,(SET_INTERRUPT_VECTOR shl 8) OR 23h
   mov  DX,OFFSET DG:INT_23
   int  21h

   mov  ax,(SET_INTERRUPT_VECTOR shl 8) OR 24h
   mov  dx,OFFSET DG:INT_24
   int  21h

   ret

   SetInts ENDP

   BREAK <Int_24>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        Int_24
;
;  FUNCTION:    INT 24 handler
;
;  INPUT:
;
;  OUTPUT:
;
;  NOTE:        This is coded as a PROC but is never called
;
;  REGISTERS USED: T.B.D.
;  (NOT RESTORED)
;
;  LINKAGE:     INTerupt 24
;
;  NORMAL
;  EXIT:
;
;  ERROR
;  EXIT:
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START Int_24
;
;       ret
;
;       END Int_24
;
;******************** END   - PSEUDOCODE ***************************************


INT_24_RETADDR DW OFFSET DG:INT_24_BACK

in_int_23 db 0                          ; reentrancy flag


   INT_24 PROC FAR

   ASSUME ds:nothing,es:nothing,ss:nothing

   pushf
   push cs
   push [INT_24_RETADDR]
   push WORD PTR [HARDCH+2]
   push WORD PTR [HARDCH]

   ret

   INT_24 ENDP

   BREAK <INT_24_BACK>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        INT_24_BACK
;
;  FUNCTION:    INT 24 post processor
;
;  INPUT:
;
;  OUTPUT:
;
;  NOTE:        This is NOT a PROC
;
;  REGISTERS USED: T.B.D.
;  (NOT RESTORED)
;
;  LINKAGE:     INTerupt 24
;
;  NORMAL
;  EXIT:
;
;  ERROR
;  EXIT:
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START INT_24_BACK
;
;       ret
;
;       END INT_24_BACK
;
;******************** END   - PSEUDOCODE ***************************************

INT_24_BACK:

   cmp  al,2                            ; Abort?

;  $if  z                               ; if abort                             ;AC000;
   JNZ $$IF182

       inc  [in_int_23]                 ; no int 23's allowed
       push cs
       pop  ds

       ASSUME ds:DG

       push cs
       pop  ss

       ASSUME ss:DG

       mov  sp, offset dg:intStk        ; setup local int stack
       cmp  [PInst],2

;      $if  ne                          ; if not installed                     ;AC000;
       JE $$IF183

	   call Restore_ints

;      $endif                           ; endif - not installed                ;AC000;
$$IF183:

       mov  ah,EXIT
       mov  al,0FFH
       int  21h

;  $endif                               ; endif - abort
$$IF182:

   IRET

   BREAK <Int_23>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        Int_23
;
;  FUNCTION:    INT 23 handler
;
;  INPUT:
;
;  OUTPUT:
;
;  NOTE:        This is NOT a PROC
;
;  REGISTERS USED: T.B.D.
;  (NOT RESTORED)
;
;  LINKAGE:     INTerupt 23
;
;  NORMAL
;  EXIT:
;
;  ERROR
;  EXIT:
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START Int_23
;
;       ret
;
;       END Int_23
;
;******************** END   - PSEUDOCODE ***************************************

INT_23:

   ASSUME ds:nothing,es:nothing,ss:nothing

   cmp  [in_int_23],0                   ; check for a re-entrant call

;  $if  e                               ; If its OK                            ;AC000;
   JNE $$IF186

       inc  [in_int_23]                 ; make sure no more int 23's
       push cs
       pop  ds

       ASSUME ds:DG

       push cs
       pop  ss

       ASSUME ss:DG

       mov  sp, offset dg:intStk        ; setup local int stack
       cmp  [PInst],2

;      $if  ne                          ; if not installed - undo              ;AC000;
       JE $$IF187

	   call Restore_ints            ;                                      ;AC000;

;      $else                            ; else - dont undo                     ;AC000;
       JMP SHORT $$EN187
$$IF187:

	   mov  ax,0105H
	   call IntWhileBusy            ; unlock print queue (just in case)

;      $endif                           ; endif - undo                         ;AC000;
$$EN187:

       mov  ah,EXIT
       mov  al,0FFH
       int  21h

;  $endif                               ; endif - its OK                       ;AC000;
$$IF186:

   iret                                 ;

   BREAK <Restore_ints>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        Restore_ints
;
;  FUNCTION:    Restore all ints used by print to original values
;
;  INPUT:
;
;  OUTPUT:
;
;  REGISTERS USED: T.B.D.
;  (NOT RESTORED)
;
;  LINKAGE:     Called from: TRANSIENT,
;
;  NORMAL
;  EXIT:
;
;  ERROR
;  EXIT:
;
;  EXTERNAL
;  REFERENCES:
;
;  CHANGE       05/20/87 - Header added       - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START Restore_ints
;
;       ret
;
;       END Restore_ints
;
;******************** END   - PSEUDOCODE ***************************************

   Restore_ints PROC NEAR

   ASSUME ds:DG,es:nothing,ss:DG

   cli
   mov  ax,(set_interrupt_vector shl 8) or SOFTINT ; (SOFTINT)
   push ds
   lds  dx,[i28vec]
   int  21h
   pop  ds

   mov  ax,(set_interrupt_vector shl 8) or COMINT ; (COMINT)
   push ds
   lds  dx,[i2fvec]
   int  21h
   pop  ds

   mov  ax,(set_interrupt_vector shl 8) or 13h
   push ds
   lds  dx,[i13vec]
   int  21h
   pop  ds

   mov  ax,(set_interrupt_vector shl 8) or 15h
   push ds
   lds  dx,[i15vec]
   int  21h
   pop  ds

   mov  ax,(set_interrupt_vector shl 8) or 17h
   push ds
   lds  dx,[i17vec]
   int  21h
   pop  ds

   mov  ax,(set_interrupt_vector shl 8) or 14h
   push ds
   lds  dx,[i14vec]
   int  21h
   pop  ds

   mov  ax,(set_interrupt_vector shl 8) or 05h
   push ds
   lds  dx,[i05vec]
   int  21h
   pop  ds

   mov  ax,(set_interrupt_vector shl 8) or INTLOC ; (INTLOC)
   push ds
   lds  dx,[i1cvec]
   int  21h
   pop  ds
   sti

   ret

   Restore_ints ENDP


   BREAK <Parse_Input>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        Parse_Input  -  PRINT Command Line Parser
;
;  FUNCTION:    Call the DOS PARSE Service Routines to process the command
;               line. Search for valid input:
;                        - filenames (may be more than one)
;                        - switches: /D:device
;                                    /B:buffsize  512 to 16k - 512 default
;                                    /Q:quesiz      4 to 32  -  10 default
;                                    /S:timeslice   1 to 255 -   8 default
;                                    /U:busytick    1 to 255 -   1 default
;                                    /M:maxtick     1 to 255 -   2 default
;                                    /T    terminate
;                                    /C    cancel
;                                    /P    print
;
;  INPUT:       Current Parse parameters in the Parse_C_B
;                     [ORDINAL]  -  CURRENT ORDINAL VALUE
;                     [SCAN_PTR] -  CURRENT SCAN POINT
;                                -  DS:[SCAN_PTR] - Pionter to Parse string
;               ES:DI - Pointer to PARMS block
;
;  OUTPUT:      PARSE_BUFF filled in:
;
;                    P_TYPE       - TYPE RETURNED
;                    P_ITEM_TAG   - SPACE FOR ITEM TAG
;                    P_SYN        - POINTER TO LIST ENTRY
;                    P_PTR_L      - SPACE FOR POINTER / VALUE - LOW
;                    P_PTR_H      - SPACE FOR POINTER / VALUE - HIGH
;
;  REGISTERS USED: T.B.D.
;  (NOT RESTORED)
;
;  LINKAGE:     Called from: TRANSIENT, Set_Buffer and Submit_File
;
;  NORMAL       CF = 0
;  EXIT:
;
;  ERROR        CF = 1 If user enters:
;  EXIT:                   - any invalid parameter or switch
;                          - an invalid value for a valid switch
;               AX = Parse error number
;
;  EXTERNAL     - System parse service routines
;  REFERENCES:
;
;  CHANGE       03/11/87 - First release      - F. G.
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;        START
;        END
;
;******************** END   - PSEUDOCODE ***************************************

   Parse_Input PROC NEAR

Syntax_Error equ 9                      ; Parse syntax error
Parse_EOL equ 0FFh                      ; Parse End Of Line
					;--------------------------------------
					;  Load appropriate registers
					;     from the Parse_Control_Block
					;--------------------------------------
   ASSUME ds:DG,es:DG,ss:nothing

   mov  cx,[ORDINAL]                    ; CURRENT ORDINAL VALUE                ;AN000;
   mov  si,[SCAN_PTR]                   ; CURRENT SCAN POINT                   ;AN000;
   mov  [MSG_PTR],si                    ; Save start in case of error          ;AN000;
   lea  di,PARMS                        ;                                      ;AN000;
   mov  dx,0                            ; RESERVED                             ;AN000;
   push ds                              ;                                      ;AN000;
   mov  ax,CodeR                        ;                                      ;AN000;
   sub  ax,10h                          ; back up 100h to start of psp         ;AN000;
   mov  ds,ax                           ; DS:SI  = command string in PSP       ;AN000;

					;--------------------------------------
   ASSUME ds:nothing                    ;  Call the Parse service routines
					;--------------------------------------

					; CX    - Ordinal value
					; DX    - zero (reserved)
					; DS:SI - Pionter to Parse string
					; ES:DI - Pointer to PARMS block

   call SYSPARSE                        ; PARSE IT!                            ;AN000;

   pop  ds                              ;                                      ;AN000;

   ASSUME ds:DG

   cmp  ax,NOERROR                      ; no errors?                           ;AN000;

;  $if  e                               ; if no errors                         ;AN000;
   JNE $$IF191

       clc                              ; WE'RE DONE                           ;AN000;

;  $else                                ; else - there was an error            ;AN000;
   JMP SHORT $$EN191
$$IF191:

       cmp  al,Parse_EOL                ; error FFh  ?                         ;AN000;

;      $if  ne                          ; if not EOL                           ;AN000;
       JE $$IF193

	   cmp  al,Syntax_Error         ; error 1 to 9 ?                       ;AN000;

;          $if  a                       ; if parse error                       ;AN000;
	   JNA $$IF194

	       mov  al,Syntax_Error     ; Parse syntax error

;          $endif                       ; endif errors                         ;AN000;
$$IF194:

	   lea  bx,Parse_Ret_Code
	   xlat cs:[bx]

;      $endif                           ; endif errors                         ;AN000;
$$IF193:

       stc                              ; SET ERROR FLAG                       ;AN000;

;  $endif                               ; endif - no error                     ;AN000;
$$EN191:

   ret                                  ; NORMAL RETURN TO CALLER              ;AN000;

Parse_Ret_Code label byte

   db   0                               ; Ret Code 0 -                         ;AC003;
   db   9                               ; Ret Code 1 - Too many parameters     ;AC003;
   db   9                               ; Ret Code 2 - Required parameter msg  ;AC003;
   db   3                               ; Ret Code 3 - Invalid switch          ;AC003;
   db   9                               ; Ret Code 4 - Invalid keyword         ;AC003;
   db   9                               ; Ret Code 5 - (reserved)              ;AC003;
   db   6                               ; Ret Code 6 - Parm val out of range   ;AC003;
   db   9                               ; Ret Code 7 - Parameter val not allow ;AC003;
   db   9                               ; Ret Code 8 - Parm format not correct ;AC003;
   db   9                               ; Ret Code 9 - Invalid Parameter       ;AC003;

   Parse_Input ENDP



   BREAK <DispMsg>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        DispMsg  -  PRINT Display Transient Message Routine
;
;  FUNCTION:    Display the transient messages for PRINT
;
;  INPUT:       Al = message number
;               Ah = class  - 0 - Message Service class
;                             1 - DOS extended error
;                             2 - Parse error
;                             A - PRINT_R message
;                             B - PRINT_T message
;                             C - PRINT_T message with insert
;                                                       DS:SI = sublist
;                             D - PRINT_T message with input buffer where:
;                                                       ES:DI = input buffer
;  OUTPUT:      - Messages output to Output Device
;
;  REGISTERS USED:  CX DX
;  (NOT RESTORED)
;
;  LINKAGE:     Call from  PRINT_R, TRANSIENT
;
;  NORMAL       -
;  EXIT:
;
;  ERROR        -
;  EXIT:
;
;  CHANGE       03/11/87 - First release      - F. G.
;  LOG:         09/28/87 - move back to tranient - make 'NEAR'
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;       START DispMsg
;
;       point to SUBLIST
;       reset response  (DL)
;       set class to utility (DH)
;       reset insert  (CX)
;       set output handle (BX)
;       if CLASS requires insert
;               load insert required
;       endif
;       if CLASS requires response
;               flush keystroke buffer
;               load response required (Dir CON in no echo)
;       endif
;       if CLASS is not Utility
;               set CLASS
;       endif
;       call SysDispMsg to display message
;       if error
;               set class to DOS_error
;               set error flag
;       endif
;
;       ret
;
;       END DispMsg
;
;******************** END   - PSEUDOCODE ***************************************

   DispMsg PROC NEAR

   ASSUME CS:DG,DS:nothing,ES:nothing,SS:nothing

   push ds                              ;                                      ;AN000;
   push si                              ;                                      ;AN000;
   push cs                              ; called before and after relocation   ;AC002;
   pop  ds                              ;  - don't use DG                      ;AC002;

   ASSUME CS:DG,DS:DG,ES:nothing,SS:nothing

   lea  si,SUBLIST                      ; point to sublist                     ;AN000;
   xor  dx,dx                           ; reset response  (DL)                 ;AN000;
   dec  dh                              ;                                      ;AN000;
   xor  cx,cx                           ; reset insert  (CX)                   ;AN000;
   mov  bx,STDOUT                       ; set output handle (BX)               ;AC014;

   cmp  ah,CLASS_C                      ; is it CLASS C                        ;AN000;

;  $if  e,or                            ; CLASS C requires insert              ;AC012;
   JE $$LL198

   cmp  ah,DOS_Error                    ; is it a DOS error?                   ;AN012;

;  $if  e                               ; DOS requires insert                  ;AN012;
   JNE $$IF198
$$LL198:

       mov  cx,offset DG:NameBuf        ; set up insert pointer to NameBuf     ;AN005;
       mov  insert_ptr_off,cx           ;                                      ;AN005;
       push cs                          ;                                      ;AN005;
       pop  [insert_ptr_seg]            ;                                      ;AN005;
       cmp  ah,CLASS_C                  ;                                      ;AC012;
;      $if  e,and                       ;                                      ;AC012;
       JNE $$IF199
       cmp  al,BadNameMes               ;                                      ;AN010;
;      $if  b                           ;                                      ;AN010;
       JNB $$IF199
	   mov  [insert_num],1          ;                                      ;AN005;
;      $else                            ;                                      ;AN010;
       JMP SHORT $$EN199
$$IF199:
	   mov  [insert_num],0          ;                                      ;AN010;
;      $endif                           ;                                      ;AN010;
$$EN199:
       mov  cx,1                        ; 1 parameter to replace               ;AN005;

;  $endif                               ;                                      ;AN000;
$$IF198:

   cmp  ah,CLASS_D                      ; is it CLASS D                        ;AN000;

;  $if  e                               ; CLASS D requires response            ;AN000;
   JNE $$IF203

					; flush keystroke buffer?
       mov  dl,buffered_input           ; load response required (INT 21h 0A)  ;AN000;

;  $endif                               ;                                      ;AN000;
$$IF203:

   cmp  ah,Parse_error

;  $if  be                              ; if Parse or DOS error
   JNBE $$IF205

       mov  dh,ah
       mov  bx,STDERR                   ; set output handle (BX)               ;AN014;

;  $endif                               ;
$$IF205:

;  $if  e                               ; if it is a parse error - show them
   JNE $$IF207
					; what is wrong
       mov  cx,[MSG_PTR]                ;  set up sublist offset               ;AN005;
       mov  [insert_ptr_off],cx         ;                                      ;AN005;
       mov  cx,CodeR                    ;  set up sublist segment (PSP)        ;AN005;
       sub  cx,10h                      ;                                      ;AN005;
       mov  [insert_ptr_seg],cx         ;                                      ;AN005;
       push si                          ;  save current pointer                ;AN005;
       push ds                          ;                                      ;AN005;
       mov  si,[SCAN_PTR]               ; point to end of bad parm             ;AN005;
       mov  ds,cx                       ;                                      ;AN005;
       mov  BYTE PTR ds:[si],0          ; terminate the parameter              ;AN005;
       pop  ds                          ;   restore current pointer            ;AN005;
       pop  si                          ;                                      ;AN005;
       mov  [insert_num],0              ;                                      ;AN005;
       mov  cx,1                        ; 1 parameter to replace               ;AN005;

;  $endif
$$IF207:

   xor  ah,ah                           ;                                      ;AN000;

   call SysDispMsg                      ; to display message                   ;AN002;

;  $if  c                               ; error ..................             ;AN000;
   JNC $$IF209

       mov  ah,DOS_error                ; load error exit code                 ;AN000;
       stc                              ; indicate failure                     ;AN000;

;  $endif                               ;                                      ;AN000;
$$IF209:

   pop  si                              ;                                      ;AN000;
   pop  ds                              ;                                      ;AN000;

   ret                                  ;                                      ;AN000;

   DispMsg ENDP

   GoDispMsg PROC FAR

   call DispMsg                         ; This allows long calls form CODER    ;AN000;

   ret                                  ;                                      ;AN000;

   GoDispMsg ENDP

   BREAK <Load_R_Msg>
;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:        Load_R_Msg  -  PRINT Load  Resident Message Routine
;
;  FUNCTION:    Load the PRINT resident messages into their
;               current message buffer.  Note that PRINT 'pumps' the
;               error text out as part of the data stream.  For this reason
;               the message service code is NOT used to display RESIDENT messages.
;
;  INPUT:       Messages in PRINT_RM, and Message Retriver code in PRINT_TM.
;
;  OUTPUT:      Resident messages loaded into the resident message buffer
;               and Message Sevices code initalized
;
;  NOTE:        Messages ERRO through ERR12, ERRMEST through AllCan, FATMES
;               BADDDRVM, GOODMES and BADMES are used in place - whereever
;               the Message retriever points to them. BADDRVM is moved directly behind
;               FATMES.
;
;  REGISTERS USED:  DS:SI - points to message text
;  (NOT RESTORED)  (   AX - message # - not destroyed)
;                  (   DH - Class - not destroyed)
;
;  LINKAGE:     Call from TRANSIENT
;
;  NORMAL       CF = 0
;  EXIT:
;
;  ERROR        CF = 1
;  EXIT:        AX = error number
;
;  CHANGE       03/11/87 - First release      - F. G.
;  LOG:         09/28/87 - P1175 - all resident messages must be moved
;
;******************* END OF SPECIFICATIONS *************************************
;******************** START - PSEUDOCODE ***************************************
;
;        START
;        END
;
;******************** END   - PSEUDOCODE ***************************************

   Load_R_Msg PROC NEAR

					;--------------------------------------
					; Load the Resident Messages
					;--------------------------------------
   mov  ax,CodeR                        ;                                      ;AN000;
   mov  es,ax                           ;                                      ;AN000;

   ASSUME DS:nothing,ES:CodeR

   lea  di,R_MES_BUFF                   ; set destination to resident buffer   ;AN000;
   mov  bx,OFFSET CodeR:MESBAS          ; use BX as an index to MESBAS (CodeR) ;AN000;

					;--------------------------------------
					; Move messages ERR0 thru ERR12
					;--------------------------------------

   mov  ax,ERR0                         ; message # 19 to start                ;AN000;
   mov  dx,(DOS_error shl 8)            ; Class is DOS error                   ;AN000;

;  $do                                  ;                                      ;AN000;
$$DO211:

       call MoveMes                     ; LOAD the message                     ;AN000;
;  $leave c                             ; leave loop if ERROR                  ;AN000;
   JC $$EN211
       mov  byte ptr es:[di],DOLLAR     ; append a delimiter
       inc  di                          ; move to next message                 ;AN000;
       inc  al                          ; advance message #                    ;AN000;
       cmp  al,ERR12                    ; are we past ERR12 ?                  ;AN000;

;  $enddo a                             ; if not, do it again                  ;AN000;
   JNA $$DO211
$$EN211:

;  $if  nc                              ; if no ERROR                          ;AN000;
   JC $$IF214
					;--------------------------------------
					; Do rocessing for ERRMEST through
					;      BADDRVM
					;--------------------------------------

       mov  ax, errmest                 ; message # 3 to start                 ;AN000;
       mov  dx,(CLASS_Util shl 8)       ; Class is Utility                     ;AN000;

;      $do                              ; now we are past ERR12                ;AN000;
$$DO215:

	   call MoveMes                 ; LOAD the message                     ;AC002;
;      $leave c                         ; leave loop if ERROR                  ;AC002;
       JC $$EN215
	   inc  al                      ; advance message #                    ;AC002;
	   cmp  al,BADDRVM              ; are we past BADDRVM                  ;AC002;

;      $enddo a                         ;                                      ;AN000;
       JNA $$DO215
$$EN215:

;  $endif                               ; endif - no error                     ;AN000;
$$IF214:

   push cs                              ;                                      ;AN000;
   pop  es                              ;                                      ;AN000;
   push cs                              ;                                      ;AN000;
   pop  ds                              ;                                      ;AN000;

   ASSUME DS:DG,ES:DG

   ret                                  ;                                      ;AN000;

   Load_R_Msg ENDP
					;--------------------------------------
					; Move the Messages into their
					;       final resting place
					;--------------------------------------
MoveMes PROC NEAR

   mov  es:[bx],di                      ; save the pointer to this message     ;AN000;
   call SYSGETMSG                       ; line up the pointer on the message   ;AN000;
;  $if  nc                              ; if no error                          ;AN000;
   JC $$IF219
					; all being well --- WE NOW HAVE---
					; DS:SI - aimed at the message file
					; ES:DI - aimed at the Resident Buffer
					; CX        - # of characters
       cld                              ; go ahead                             ;AN000;
       rep  movsb                       ; and copy it!                         ;AN000;
       inc  bx                          ; set up for next pointer              ;AN000;
       inc  bx                          ;                                      ;AN000;

;  $endif                               ; endif - no error                     ;AN000;
$$IF219:

   ret                                  ;                                      ;AN000;

   MoveMes ENDP


CODE ENDS


STACK SEGMENT STACK

   dw   100 dup(0)

TransSize LABEL BYTE                    ; end of transient
					;  only because code is para algned
STACK ENDS

   END  Transient

