page 80,132 TITLE 4.00 PRINT TRANSIENT ; $SALUT (4,25,30,41) INCLUDE pridefs.inc SaveReg MACRO reglist ;; push those registers IRP reg, PUSH reg ENDM ENDM RestoreReg MACRO reglist ;; pop those registers IRP reg, POP reg ENDM ENDM BREAK ;******************* 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 ; - 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 ;---------------------------------------- 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 ;-------------------------------------- ; 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 9 ; 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 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, ; congruant, 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 ;-------------------------------------- ; 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 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; ; $if e ; if no error in jump calculation ;AC000; JNE $$IF24 call Process_A_Switch ; ;AC000; ; $else JMP SHORT $$EN24 $$IF24: stc ; set the error flag ;AC000; ; $endif ; endif - no error in jump calculation ;AC000; $$EN24: ; $endif ; endif - name or switch ;AC000: $$EN22: ; $leave c ; leave the loop if error ocurred ;AC000; JC $$EN16 ; $enddo ; enddo ;AC000; JMP SHORT $$DO16 $$EN16: ; $if nc,long ; if no error so far ;AC000; JNC $$XL1 JMP $$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 ; $endif ; erdif - errors ;AC000; $$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 ;******************* 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; ASSUME ds:DG,es:DG 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 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 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 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 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 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 ;******************* 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 ; int 3 nop cmp [PInst],0 ; has print been installed? ; $if e ; if not ..... ;AC000; JNE $$IF81 call Set_Buffer ; ... better do it now ;AC000; ; $endif ; endif - installed ;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 ; $if ne ; if no : ;AC000; 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" ; conver to letter code stosb ; store letter code mov al,":" stosb clc ; clear error flag ;AC000; ; $else ; else - theres a drive ;AC000; JMP SHORT $$EN83 $$IF83: mov al,byte ptr [si] ; get drive letter sub al,"@" ; conver to proper code... ; $if a ; if a valid drive ;AC000; JNA $$IF85 mov dl,al ; save for later (used in DoPath) movsb ; move the drive letter movsb ; move the ":" clc ; ;AC000; ; $else ; ;AC000; JMP SHORT $$EN85 $$IF85: mov ax,(CLASS_B shl 8) + InvDrvMes ; set up error message ;AC000; stc ; set error flag ;AC000; ; $endif ; ;AC000; $$EN85: ; $endif ; endif - : ;AC000; $$EN83: ;------------------------------------ ; could have CF & message # here ;------------------------------------ ; $if nc ; if no error so far ;AC000; JC $$IF89 ;------------------------------------ ; Check for full path ;------------------------------------ mov al,[PathChar] cmp byte ptr [si],al ; does it start from the root? ; $if ne ; if not get the current path ;AC000; JE $$IF90 stosb ; store path character push si mov si,di ; buffer for current directory mov ah,Current_Dir ; get current directory int 21h ; $if c ; if an error occures ;AC000; JNC $$IF91 pop si ; clear the stack mov ax,(CLASS_B shl 8) + InvDrvMes ; set up error message ;AC000; ; $else ; else - no error so far ;AC000; JMP SHORT $$EN91 $$IF91: ; $do ; find terminating nul ;AC000; $$DO93: lodsb or al,al ; $enddo z ; ;AC000; 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 ; $if ne ; if not, add a path char ;AC000; JE $$IF95 mov al,[PathChar] stosb ; put path separator before file name ; $endif ; ;AC000; $$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; ; $endif ; ;AC000; $$EN91: ; $else ; 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 ; $if c ; ;AC000; JNC $$IF99 mov ax,(CLASS_B shl 8) + InvDrvMes ; ;AC000; ; $endif ; ;AC000; $$IF99: ; $endif ; ;AC000; $$EN90: ; $endif ; endif errors ;AC000; $$IF89: ;------------------------------------ ; could have CF & message # here ;------------------------------------ ; $if nc ; if no error so far ;AC000; JC $$IF103 mov cx,MaxFileLen ; lets 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 ; $if c ; if too long ;AC000; JNC $$IF104 mov cx,1 ; Set cx to Fall through to FNTooLong ; $endif ; ;AC000; $$IF104: ; WHILE (Length(FileName) <= MaxFileLen) ; $search ; DO copy in the file name ;AC000; $$DO106: lodsb stosb cmp al,"*" ; $if e,or ; if its ambigous - *, or...... ;AC000; JE $$LL107 cmp al,"?" ; : ; $if e ; if its ambigous - ?, .......: ;AC000; JNE $$IF107 $$LL107: mov [Ambig],1 ; ambigous filename found ; $endif ; endif - ambigous ;AC000; $$IF107: or al,al ; end of name? clc ; ;AC000; ; $exitif z ; ;AC000; JNZ $$IF106 ; $orelse ; ;AC000; JMP SHORT $$SR106 $$IF106: ; $endloop loop ; ;AC000; LOOP $$DO106 dec di ; the name was too long ! mov [NulPtr],di mov ax,(CLASS_C shl 8) + NamTMes ; ;AC000; stc ; ;AN010; ; $endsrch ; we have the full absolute name... ;AC000; $$SR106: ; $endif ; endif errors ;AC000; $$IF103: push cs ; restore ds to DG pop ds ASSUME ds:DG ;------------------------------------ ; could have CF & message # ;------------------------------------ ; $if nc,long ; ;AC000; JNC $$XL2 JMP $$IF114 $$XL2: dec di mov [NulPtr],di ; save pointer to termanting nul ;------------------------------------ ; check for an option following name ;------------------------------------ call Parse_Input ; ;AC000; cmp ax,noerror ; a parse error? ;AC000; ; $if e ; if no parse error ;AC000; JNE $$IF115 cmp [P_SYN],offset DG:C_SW_ptr ; is it the cancel switch /C ;AC000; ; $if e ; if it is ;AC000; JNE $$IF116 mov [CanFlag],1 ; set cancel flag ; $else ; else - it is not ;AC000; JMP SHORT $$EN116 $$IF116: cmp [P_SYN],offset DG:P_SW_ptr ; is it the print switch /P ;AC000; ; $if e ; if it is ;AC000; JNE $$IF118 mov [CanFlag],0 ; reset cancel flag ; $endif ; ;AC000; $$IF118: ; $endif ; ;AC000; $$EN116: ; $if e ; if /C or /P found ;AC000; JNE $$IF121 mov [ordinal],cx ; ;AC000; mov [scan_ptr],si ; ;AC000; ; $endif ; ;AC000; $$IF121: ; $endif ; ;AC000; $$IF115: ;-------------------------------------- ;------------------------------------ ; check file exists ;------------------------------------ cmp [CanFlag],1 ; are we in cancel mode ; $if e ; if cancel mode ;AC000; 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 ; $if c ; ;AC000; JNC $$IF125 cmp ax,2 ; $if ne ; Original Print Code timing jump ;AC000; JE $$IF126 ;------------------------------------ ;***** PROCESS CANCEL ERROR ;------------------------------------ ; $endif ; ;AC000; $$IF126: mov ax,(CLASS_C shl 8) + BadCanMes ; ;AC000; stc ; ;AC000; ; $endif ; ;AC000; $$IF125: ; $else long ; submit mode active ;AC000; JMP $$EN124 $$IF124: cmp [Ambig],1 ; is this an ambigous name? ; $if e,and ; if it is ambigous ;AC000; JNE $$IF130 ; do another ambigous name call GetAbsN ; get abs name into NameBuf ; $if c ; if an error occured ;AC000; JNC $$IF130 mov ax,(CLASS_C shl 8) + BadNameMes ; ;AC000; call DispMsg ; call DispMsg ;AN000; ; $else long ; there is at least 1 name ;AC000; JMP $$EN130 $$IF130: ; $do ; until all names processed ;AC000; $$DO132: ; 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; ; $if nc,and ; target drive local and ;AN010; JC $$IF133 test dx,1200H ; check if (x & 0x1000) ;AN010; ; (redirected or shared) ; $if z,and ; 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; ; $if nc ; if no errors so far ;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; ; $endif ; ;AN010; $$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; ; $if c ; if error ;AC000; JNC $$IF135 ; do error handling SaveReg mov ah,GetExtendedError int 21h mov ah,DOS_error RestoreReg stc ; ;AC000; ; $else ; ;AC000; JMP SHORT $$EN135 $$IF135: ; close file mov bx,ax ; copy handle mov ah,close int 21h ; clc ; clear error flag ;AC000; ; 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 ; $if nc,and ; if successfull, or ;AC000; JC $$IF137 cmp ax,error_queue_full ; $if ne ; if error but queue not full ;AC000; JE $$IF137 mov [QFullMes],0 ; queue is not full clc ; reset the error flag ;AC000; ; $else ; else - the queue IS full ;AC000; JMP SHORT $$EN137 $$IF137: cmp [QFullMes],1 ; has the message already been issued? ; $if ne ; if the message has not been posted ;AC000; JE $$IF139 mov [QFullMes],1 ; set the 'message posted' flag mov ax,(CLASS_B shl 8) + FullMes ; load msg # ;AC000; stc ; display the message ;AC000; ; $else JMP SHORT $$EN139 $$IF139: clc ; make sure carry clear ; $endif ; message processed ;AC000; $$EN139: ; $endif ; queue errors ;AC000; $$EN137: ; $endif ; OPENing errors ;AC000; $$EN135: ; $if c ; if error ;AC000; JNC $$IF144 call DispMsg ; display the error with this file ;AC000; ; $endif ; ;AC000; $$IF144: ; $leave c ; quit if error in displaying message ;AC000; JC $$EN132 cmp [Ambig],1 ; are we processing an ambigous name? ; $if e ; if Ambiguous ;AC000; JNE $$IF147 ; call Absn2 (will set fail if at end) call GetAbsN2 ; get another file name ; $else ; ;AC000; JMP SHORT $$EN147 $$IF147: mov ax,0 ; set fail ;AC000; stc ; ;AC000; ; $endif ; ;AC000; $$EN147: ; $enddo c,long ; end do on fail ;AC000; JC $$XL3 JMP $$DO132 $$XL3: $$EN132: cmp ax,0 ; is there a message? ;AC000; ; $if e ; if no message ;AC000; JNE $$IF151 clc ; reset fail ;AC000; ; $endif ; no message to display ;AC000; $$IF151: ; $endif ; any submission errors ;AC000; $$EN130: ; $endif ; submit or cancel ;AC000; $$EN124: ; $endif ; any errors so far ;AC000; $$IF114: ; $if c ; if error ;AC000; JNC $$IF156 call DispMsg ; display the submit error ;AC000; ; $endif ; ;AC000; $$IF156: ret ; finished submission ;AC000; Submit_File ENDP BREAK ;******************* 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 ;******************* 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 ;******************* 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 ;******************* 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 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 ;******************* 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 ;******************* 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 ;******************* 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 ;******************* 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 ;******************* 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 ;******************* 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 ;******************* 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 ;******************* 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 ;******************* 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 ;******************* 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'ER 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 ;******************* 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 ;******************* 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