; * * * * * * * * * * * * START OF SPECIFICATIONS * * * * * * * * * * * * * * * ; ; MODULE NAME: MSGSERV.SAL ; ; DESCRIPTIVE NAME: Message Services SALUT file ; ; FUNCTION: This module incorporates all the messages services and ; is called upon at build time to INCLUDE the code requested ; by a utility. Code is requested using the macro MSG_SERVICES. ; ; ENTRY POINT: Since this a collection of subroutines, entry point is at ; requested procedure. ; ; INPUT: Since this a collection of subroutines, input is dependent on function ; requested. ; ; EXIT-NORMAL: In all cases, CARRY FLAG = 0 ; ; EXIT-ERROR: In all cases, CARRY FLAG = 1 ; ; INTERNAL REFERENCES: (list of included subroutines) ; ; - SYSLOADMSG ; - SYSDISPMSG ; - SYSGETMSG ; ; ; EXTERNAL REFERENCES: None ; ; NOTES: At build time, some modules must be included. These are only included ; once using assembler switches. Other logic is included at the request ; of the utility. ; ; COMR and COMT are assembler switches to conditionally assemble code ; for RESIDENT COMMAND.COM and TRANSIENT COMMAND.COM to reduce resident ; storage and multiple EQUates. ; ; REVISION HISTORY: Created MAY 1987 ; ; Label: DOS - - Message Retriever ; (c) Copyright 1988 Microsoft ; ; ; * * * * * * * * * * * * END OF SPECIFICATIONS * * * * * * * * * * * * * * * * ; Page ; ; Revision History ; ================ ; ; M007 SR 08/24/90 Fixed bug #1818 -- changed ; $M_DISPLAY_H_STRING to properly ; handle Ctrl-Z being passed ; ; M013 SR 9/12/90 Make SETSTDIO flag false so that all ; these routines are no longer assembled. ; ; M016 SR 10/14/90 Bug #3380. Changed SYSLOADMSG so that ; CR-LF string also gets reinitialized ; on every cycle. ; ; M020 SR 10/26/90 Bug #3380 again. Initialize $M_DIVISOR ; & $_MSG_NUM also in SYSLOADMSG. ; ; $SALUT $M (2,5,22,62) ;;AN000;; Set SALUT formatting IF $M_STRUC ;;AN000;; IF we haven't included the structures yet THEN $M_STRUC = FALSE ;;AN000;; Let the assembler know that we have ;;AN000;; and include them PAGE SUBTTL DOS - Message Retriever - MSGSTR.INC Module ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; STRUCTURE: $M_SUBLIST_STRUC ;; ;; Replacable parameters are described by a sublist structure ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_SUBLIST_STRUC STRUC ;;AN000;; ;; $M_S_SIZE DB 11 ;;AN000;; SUBLIST size (PTR to next SUBLIST) $M_S_RESV DB 0 ;;AN000;; RESERVED $M_S_VALUE DD ? ;;AN000;; Time, Date or PTR to data item $M_S_ID DB ? ;;AN000;; n of %n $M_S_FLAG DB ? ;;AN000;; Data-type flags $M_S_MAXW DB ? ;;AN000;; Maximum field width $M_S_MINW DB ? ;;AN000;; Minimum field width $M_S_PAD DB ? ;;AN000;; Character for Pad field ;; $M_SUBLIST_STRUC ENDS ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; STRUCTURE: $M_CLASS_ID ;; ;; Each class will be defined by this structure. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_CLASS_ID STRUC ;;AN000;; ;; $M_CLS_ID DB -1 ;;AN000;; Class identifer $M_COMMAND_VER DW EXPECTED_VERSION ;;AN003;; COMMAND.COM version check ifdef BILINGUAL $M_NUM_CLS_MSG DW 0 ;;AN000;; Total number of message in class else $M_NUM_CLS_MSG DB 0 ;;AN000;; Total number of message in class endif ;; $M_CLASS_ID ENDS ;; ;;AN000;; $M_CLASS_ID_SZ EQU SIZE $M_CLASS_ID ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; STRUCTURE: $M_ID_STRUC ;; ;; Each message will be defined by this structure. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_ID STRUC ;;AN000;; ;; $M_NUM DW -1 ;;AN000;; Message Number $M_TXT_PTR DW ? ;;AN000;; Pointer to message text ;; $M_ID ENDS ;;AN000;; ;;AN000;; Status Flag Values: $M_ID_SZ EQU SIZE $M_ID ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; STRUCTURE: $M_RES_ADDRS ;; ;; Resident data area definition of variables ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_RES_ADDRS STRUC ;;AN000;; ;; $M_EXT_ERR_ADDRS DD 0 ;;AN000;; Allow pointers to THREE Extended error locations $M_EXT_FILE DD 0 ;;AN001;; $M_EXT_COMMAND DD 0 ;;AN000;; $M_EXT_TERM DD -1 ;;AN000;; $M_PARSE_COMMAND DD 0 ;;AN000;; $M_PARSE_ADDRS DD 0 ;;AN000;; Allow pointers to TWO Parse error locations $M_PARSE_TERM DD -1 ;;AN000;; $M_CRIT_ADDRS DD 0 ;;AN000;; Allow pointers to TWO Critical error locations $M_CRIT_COMMAND DD 0 ;;AN000;; $M_CRIT_TERM DD -1 ;;AN000;; $M_DISK_PROC_ADDR DD -1 ;;AN004;; Address of READ_DISK_PROC $M_CLASS_ADDRS DD $M_NUM_CLS DUP(0) ;;AN000;; Allow pointers to specified classes $M_CLS_TERM DD -1 ;;AN000;; $M_DBCS_VEC DD 0 ;;AN000;; Save DBCS vector $M_HANDLE DW ? ;;AN000;; $M_SIZE DB 0 ;;AN000;; $M_CRLF DB 0DH,0AH ;;AN004;; CR LF message $M_CLASS DB ? ;;AN004;; Saved class $M_RETURN_ADDR DW ? ;;AN000;; $M_MSG_NUM DW $M_NULL ;;AN000;; $M_DIVISOR DW 10 ;;AN000;; Default = 10 (must be a WORD for division) $M_TEMP_BUF DB $M_TEMP_BUF_SZ DUP("$") ;;AN000;; Temporary buffer $M_BUF_TERM DB "$" ;;AN000;; $M_RES_ADDRS ENDS ;;AN000;; ;; $M_RES_ADDRS_SZ EQU SIZE $M_RES_ADDRS ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; STRUCTURE: $M_COUNTRY_INFO ;; ;; Important fields of the Get Country Information call ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_COUNTRY_INFO STRUC ;;AN000;; Expected Country infomation ;; $M_HEADER DB $M_RES_ADDRS_SZ-$M_TEMP_BUF_SZ-1 DUP(?) ;;AN000;; Go past first part of struc $M_DATE_FORMAT DW ? ;;AN000;; <------- Date Format $M_CURR_SEPARA DB 5 DUP(?) ;;AN000;; $M_THOU_SEPARA DB ?,0 ;;AN000;; <------- Thou Separator $M_DECI_SEPARA DB ?,0 ;;AN000;; <------- Decimal Separator $M_DATE_SEPARA DB ?,0 ;;AN000;; <------- Date Separator $M_TIME_SEPARA DB ?,0 ;;AN000;; <------- Time Separator $M_CURR_FORMAT DB ? ;;AN000;; $M_SIG_DIGS_CU DB ? ;;AN000;; $M_TIME_FORMAT DB ? ;;AN000;; <------- Time Format ;; $M_COUNTRY_INFO ENDS ;;AN000;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ELSE ;;AN000;; ELSE if we have already included the STRUCTURES ; ; $SALUT $M (2,5,13,62) ;;AN000;; Set SALUT formatting for code section IF MSGDATA ;;AN000;; IF this is a request to include the data area MSGDATA = FALSE ;;AN000;; Let the assembler know not to include it again ;;AN000;; and include it PAGE SUBTTL DOS - Message Retriever - MSGRES.TAB Module ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; DATA NAME: $M_RES_TABLE ;; ;; REFERENCE LABEL: $M_RT ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; IF COMR ;;AN000;; Since COMMAND.COM includes this twice $M_RT EQU $M_RT2 ;;AN000;; we must redefine the label so no $M_RT2 LABEL BYTE ;;AN000;; assembly errors occur $M_ALTLABEL = TRUE ;;AN000;; Flag that label was changed ELSE ;;AN000;; $M_RT LABEL BYTE ;;AN000;; ENDIF ;;AN000;; $M_RES_ADDRS <> ;;AN000;; Resident addresses ;; include COPYRIGH.INC ;;AN001;; Include Copyright 1988 Microsoft ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;;AN000;; END of include of Data table ; IF NOT $M_MSGDATA_ONLY ;;AN000;; IF this was a request for only the data table THEN ;; don't include any more code ;;AN000;; Figure out what other code to include IF DISK_PROC ;;AN003;; Is the request to include the READ_DISK code IF COMR ;;AN003;; (Only Resident COMMAND.COM should ask for it) $M_RT EQU $M_RT2 ;;AN003;; ENDIF DISK_PROC = FALSE ;;AN003;; Yes, THEN include it and reset flag PAGE SUBTTL DOS - Message Retriever - DISK_PROC Module ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: DISK_PROC ;; ;; FUNCTION: Used in COMMAND.COM if we need to access the Parse or Extended ;; errors from disk\diskette ;; INPUTS: AX has the message number ;; DX has the message class ;; AND ... the COMMAND.COM Variable RESGROUP:COMSPEC is ;; assumed to be set!! ;; ;; OUTPUTS: ES:DI points to message length (BYTE) followed by text ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PUBLIC READ_DISK_PROC ;; ;; READ_DISK_PROC PROC FAR ;;AN003;; PUSH AX ;;AN003;; Save everything PUSH BX ;;AN003;; PUSH DX ;;AN003;; PUSH SI ;;AN003;; PUSH BP ;;AN003;; PUSH DS ;;AN003;; PUSH DI ;;AN003;; MOV BP,AX ;;AN003;; Save message number MOV AX,DOS_EXTENDED_OPEN ;;AN003;; Set INT 21 function LEA SI,RESGROUP:COMSPEC ;;AN003;; Get addressibilty to COMMAND.COM PUSH CS ;;AN003;; POP DS ;;AN003;; MOV DI,-1 ;;AN003;; No extended attribute list MOV BX,NO_CRIT_OPEN ;;AN003;; Don't generate critical error MOV DX,NOT_EX_FAIL_EX_OPEN ;;AN003;; Open Flag INT 21H ;;AN003;; Open the file POP DI ;;AN003;; Retreive LSEEK pointer ;;AN003;; Error ? ; $IF NC,LONG ;;AN003;; No, JNC $MXL1 JMP $MIF1 $MXL1: PUSH DI ;;AN003;; Save LSEEK pointer MOV BX,AX ;;AN003;; Set handle in BX MOV AX,DOS_LSEEK_FILE ;;AN003;; LSEEK to the errors XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM MOV DX,DI ;;AN003;; INT 21H ;;AN003;; LSEEK the file POP DX ;;AN003;; Retreive LSEEK pointer ;;AN003;; Error ? ; $IF NC ;;AN003;; No, JC $MIF2 INC CX ;;AN003;; Set flag to first pass ; $DO ;;AN003;; $MDO3: PUSH DX ;;AN003;; Save LSEEK pointer PUSH CX ;;AN003;; Save first pass flag PUSH AX ;;AN003;; Save number of messages (if set yet) XOR SI,SI ;;AN003;; Reset buffer index MOV AH,DOS_READ_BYTE ;;AN003;; Read MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the first part of the header LEA DX,$M_RT.$M_TEMP_BUF ;;AN003;; into the temp buffer INT 21H ;;AN003;; Read it MOV DI,DX ;;AN003;; POP AX ;;AN003;; POP CX ;;AN003;; OR CX,CX ;;AN003;; ; $IF NZ ;;AN003;; JZ $MIF4 XOR CX,CX ;;AN003;; Set flag to second pass ifdef BILINGUAL MOV AX,DS:[DI].$M_NUM_CLS_MSG ;;AN003;; else XOR AH,AH ;;AN003;; Get number of messages in class MOV AL,DS:[DI].$M_NUM_CLS_MSG ;;AN003;; endif MOV SI,$M_CLASS_ID_SZ ;;AN003;; Initialize index CMP DS:[DI].$M_COMMAND_VER,EXPECTED_VERSION ;;AN003;; Is this the right version of COMMAND.COM? ; $ENDIF ;;AN003;; $MIF4: POP DX ;;AN003;; ; $IF Z ;;AN003;; Yes, JNZ $MIF6 ; $SEARCH ;;AN003;; $MDO7: CMP BP,WORD PTR $M_RT.$M_TEMP_BUF[SI] ;;AN003;; Is this the message I'm looking for? ; $EXITIF Z ;;AN003;; Yes, (ZF=1) JNZ $MIF7 CLC ;;AN003;; Reset carry, exit search ; $ORELSE ;;AN003;; No, (ZF=0) JMP SHORT $MSR7 $MIF7: ADD SI,$M_ID_SZ ;;AN003;; Increment index ADD DX,$M_ID_SZ ;;AN003;; Add offset of first header DEC AX ;;AN003;; Decrement # of messages left ; $LEAVE Z ;;AN003;; Have we exhausted all messages? JZ $MEN7 CMP SI,$M_TEMP_BUF_SZ-1 ;;AN003;; No, Have we exhausted the buffer? ; $ENDLOOP A ;;AN003;; No, Check next message (ZF=1) JNA $MDO7 $MEN7: STC ;;AN003;; Yes, (ZF=0) set error (ZF=0) ; $ENDSRCH ;;AN003;; $MSR7: ; $ELSE ;;AN003;; No, JMP SHORT $MEN6 $MIF6: XOR CX,CX ;;AN003;; Set Zero flag to exit READ Loop STC ;;AN003;; Set Carry ; $ENDIF ;;AN003;; $MEN6: ; $ENDDO Z ;;AN003;; Get next buffer full if needed JNZ $MDO3 ;;AN003;; Error ? ; $IF NC ;;AN003;; No, JC $MIF16 MOV AX,DOS_LSEEK_FILE ;;AN003;; Prepare to LSEEK to the specific message XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM ADD DX,$M_CLASS_ID_SZ ;;AN003;; Add offset of first header ADD DX,WORD PTR $M_RT.$M_TEMP_BUF[SI]+2 ;;AN003;; Add offset from msg structure INT 21H ;;AN003;; LSEEK the file MOV AH,DOS_READ_BYTE ;;AN003;; Read MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the message LEA DX,$M_RT.$M_TEMP_BUF ;;AN003;; into the temp buffer INT 21H ;;AN003;; Read it MOV DI,DX ;;AN003;; into the temp buffer PUSH DS ;;AN003;; into the temp buffer POP ES ;;AN003;; into the temp buffer ; $ENDIF ;;AN003;; $MIF16: ; $ENDIF ;;AN003;; $MIF2: PUSHF ;;AN003;; Close file handle MOV AH,DOS_CLOSE_FILE ;;AN003;; Close file handle INT 21H ;;AN003;; $M_POPF ;;AN003;; ; $ENDIF ;;AN003;; Yes there was an error, $MIF1: POP DS ;;AN003;; POP BP ;;AN003;; POP SI ;;AN003;; POP DX ;;AN003;; POP BX ;;AN003;; POP AX ;;AN003;; ;;AN003;; abort everything RET ;;AN003;; READ_DISK_PROC ENDP ;;AN003;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;;AN003;; END of include for DISK_PROC ; SETSTDIO = FALSE ; M013 IF SETSTDIO ;;AN000;; Is the request to include the code for SETSTDIO SETSTDIO = FALSE ;;AN000;; Yes, THEN include it and reset flag PAGE SUBTTL DOS - Message Retriever - SETSTDIO Module ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: SETSTDIO ;; ;; FUNCTION: ;; INPUTS: ;; ;; OUPUTS: ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; IF FARmsg ;AN001; SETSTDINON PROC FAR ;AN001; ELSE ;AN001; SETSTDINON PROC NEAR ;AN001; ENDIF ;AN001; PUSH AX ;AN002; Save changed regs PUSH BX ;AN002; PUSH DX ;AN002; MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL MOV BX,STDIN ;AN001; XOR DX,DX ;AN001; INT 21H ;AN001; OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL INT 21H ;AN001; POP DX ;AN002; Restore Regs POP BX ;AN002; POP AX ;AN002; RET ;AN001; ;AN001; SETSTDINON ENDP ;AN001; IF FARmsg ;AN001; SETSTDINOFF PROC FAR ;AN001; ELSE ;AN001; SETSTDINOFF PROC NEAR ;AN001; ENDIF ;AN001; PUSH AX ;AN002; Save changed regs PUSH BX ;AN002; PUSH DX ;AN002; MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL MOV BX,STDIN ;AN001; XOR DX,DX ;AN001; INT 21H ;AN001; AND DH,NOT $M_CRIT_ERR_MASK ;AN001; Turn off bit MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL INT 21H ;AN001; POP DX ;AN002; Restore Regs POP BX ;AN002; POP AX ;AN002; RET ;AN001; SETSTDINOFF ENDP ;AN001; IF FARmsg ;AN001; SETSTDOUTON PROC FAR ;AN001; ELSE ;AN001; SETSTDOUTON PROC NEAR ;AN001; ENDIF ;AN001; PUSH AX ;AN002; Save changed regs PUSH BX ;AN002; PUSH DX ;AN002; MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL MOV BX,STDOUT ;AN001; XOR DX,DX ;AN001; INT 21H ;AN001; OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL INT 21H ;AN001; POP DX ;AN002; Restore Regs POP BX ;AN002; POP AX ;AN002; RET ;AN001; SETSTDOUTON ENDP ;AN001; IF FARmsg ;AN001; SETSTDOUTOFF PROC FAR ;AN001; ELSE ;AN001; SETSTDOUTOFF PROC NEAR ENDIF ;AN001; PUSH AX ;AN002; Save changed regs PUSH BX ;AN002; PUSH DX ;AN002; MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL MOV BX,STDOUT ;AN001; XOR DX,DX ;AN001; INT 21H ;AN001; AND DH,NOT $M_CRIT_ERR_MASK ;AN001; Turn off bit MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL INT 21H ;AN001; POP DX ;AN002; Restore Regs POP BX ;AN002; POP AX ;AN002; RET ;AN001; SETSTDOUTOFF ENDP ;AN001; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;;AN000;; END of include for SETSTDIO ; IF LOADmsg ;;AN000;; Is the request to include the code for SYSLOADMSG ? IF COMR ;;AN000;; $M_RT EQU $M_RT2 ;;AN000;; ENDIF LOADmsg = FALSE ;;AN000;; Yes, THEN include it and reset flag PAGE SUBTTL DOS - Message Retriever - LOADMSG.ASM Module ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: SYSLOADMSG ;; ;; FUNCTION: ;; INPUTS: ;; ;; OUPUTS: ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; IF FARmsg ;;AN000;; SYSLOADMSG PROC FAR ;;AN000;; ELSE ;;AN000;; SYSLOADMSG PROC NEAR ;;AN000;; ENDIF ;;AN000;; PUSH AX ;;AN000; PUSH BX ;;AN000; PUSH DX ;;AN000; PUSH ES ;;AN000; PUSH DI ;;AN000; XOR CX,CX ;;AN000; Reset to zero MOV ES,CX ;;AN000; XOR DI,DI ;;AN000; MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface MOV DL,DOS_GET_EXTENDED ;;AN000;; Where are the Extended errors in COMMAND.COM INT 2FH ;;AN000;; Private interface MOV WORD PTR $M_RT.$M_EXT_COMMAND+2,ES ;;AN000;; Move into first avaliable table location MOV WORD PTR $M_RT.$M_EXT_COMMAND,DI ;;AN000;; ;; MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface MOV DL,DOS_GET_PARSE ;;AN000;; Where are the Parse errors in COMMAND.COM INT 2FH ;;AN000;; Private interface MOV WORD PTR $M_RT.$M_PARSE_COMMAND+2,ES ;;AN000;; Move into first avaliable table location MOV WORD PTR $M_RT.$M_PARSE_COMMAND,DI ;;AN000;; ;; MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface MOV DL,DOS_GET_CRITICAL ;;AN000;; Where are the Critical errors in COMMAND.COM INT 2FH ;;AN000;; Private interface MOV WORD PTR $M_RT.$M_CRIT_COMMAND+2,ES ;;AN000;; Move into first avaliable table location MOV WORD PTR $M_RT.$M_CRIT_COMMAND,DI ;;AN000;; MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface MOV DL,DOS_GET_FILE ;;AN001;; Where are the FILE dependant in IFSFUNC.EXE INT 2FH ;;AN001;; Private interface MOV WORD PTR $M_RT.$M_EXT_FILE+2,ES ;;AN001;; Move into first avaliable table location MOV WORD PTR $M_RT.$M_EXT_FILE,DI ;;AN001;; IF COMR ;; ** Special case for RESIDENT COMMAND.COM IF2 IFNDEF READ_DISK_INFO ;;AN003;; Extrn READ_DISK_PROC:Far ;;AN003;; ENDIF ;;AN003;; ENDIF ;;AN003;; ELSE ;; IF FARmsg ;;AN000;; CALL FAR PTR $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) ELSE ;;AN000;; CALL $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) ENDIF ;;AN000;; MOV WORD PTR $M_RT.$M_EXT_ERR_ADDRS+2,ES ;;AN000;; Move into first avaliable table location MOV WORD PTR $M_RT.$M_EXT_ERR_ADDRS,DI ;;AN000;; MOV WORD PTR $M_RT.$M_CRIT_ADDRS+2,ES ;;AN000;; Move into first avaliable table location MOV WORD PTR $M_RT.$M_CRIT_ADDRS,DI ;;AN000;; ;; IF FARmsg ;;AN000;; CALL FAR PTR $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) ELSE ;;AN000;; CALL $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) ENDIF ;;AN000;; MOV WORD PTR $M_RT.$M_PARSE_ADDRS+2,ES ;;AN000;; Move into first avaliable table location MOV WORD PTR $M_RT.$M_PARSE_ADDRS,DI ;;AN000;; ENDIF ;; ;; MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface MOV DL,DOS_GET_ADDR ;;AN001;; Where is the READ_DISK_PROC in COMMAND.COM INT 2FH ;;AN001;; Private interface MOV WORD PTR $M_RT.$M_DISK_PROC_ADDR+2,ES ;;AN001;; Move into first avaliable table location MOV WORD PTR $M_RT.$M_DISK_PROC_ADDR,DI ;;AN001;; ;M016; M020 ; Reinitialize the CR-LF string. Also, reinit the buffer terminator just to ;be safe. Initialize $M_MSG_NUM and $M_DIVISOR also. ; mov word ptr $M_RT.$M_CRLF,0a0dh ; Reinit CR-LF ;M016 mov byte ptr $M_RT.$M_BUF_TERM,'$' ; Reinit buffer end;M016 mov word ptr $M_RT.$M_MSG_NUM,$M_NULL ; M020 mov word ptr $M_RT.$M_DIVISOR,$M_BASE10 ; M020 $M_BUILD_PTRS %$M_NUM_CLS ;;AN000;; Build all utility classes ;;AN000;; CALL $M_GET_DBCS_VEC ;;AN000;; Save the DBCS vector IF NOT NOCHECKSTDIN ;;AN000;; IF EOF check is not to be suppressed CALL $M_CHECKSTDIN ;;AN000;; Set EOF CHECK ENDIF ;;AN000;; ;;AN000;; IF NOT NOCHECKSTDOUT ;;AN000;; IF Disk Full check is not to be suppressed CALL $M_CHECKSTDOUT ;;AN000;; Set Disk Full CHECK ENDIF ;;AN000;; ;;AN000;; IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed CLC ;;AN000;; Make sure carry is clear ELSE ;;AN000;; ELSE PUSH CX ;;AN000;; CALL $M_VERSION_CHECK ;;AN000;; Check Version ENDIF ;;AN000;; ;; Error ? ; $IF NC ;;AN000;; No. JC $MIF20 IF NOT NOVERCHECKmsg ;;AN000;; IF version check was not supressed POP CX ;;AN000;; Reset stack ENDIF ;;AN000;; POP DI ;;AN000;; Restore REGS POP ES ;;AN000;; POP DX ;;AN000;; POP BX ;;AN000;; POP AX ;;AN000;; ; $ELSE ;;AN000;; Yes, JMP SHORT $MEN20 $MIF20: IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed ADD SP,10 ;;AN000;; STC ;;AN000;; Reset carry flag ELSE ;;AN000;; IF version check is to be supressed ADD SP,12 ;;AN000;; STC ;;AN000;; Reset carry flag ENDIF ;;AN000;; IF version check is to be supressed ; $ENDIF ;;AN000;; $MEN20: RET ;;AN000;; ;; SYSLOADMSG ENDP ;;AN000;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PAGE SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Proc Name: $M_GET_DBCS_VEC ;; ;; Function: Get the DBCS vector and save it for later use ;; ;; Inputs: None ;; ;; Outputs: None ;; ;; Regs Changed: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_GET_DBCS_VEC PROC NEAR ;;AN000;; ;; PUSH AX ;;AN000;; Save character to check PUSH SI ;;AN000;; PUSH DS ;;AN000;; MOV AX,DOS_GET_DBCS_INFO ;;AN000;; DOS function to get DBSC environment INT 21H ;;AN000;; Get environment pointer PUSH DS ;;AN000;; Get environment pointer POP ES ;;AN000;; Get environment pointer POP DS ;;AN000;; Get environment pointer ; $IF NC ;;AN000;; JC $MIF23 MOV WORD PTR $M_RT.$M_DBCS_VEC,SI ;;AN000;; Save DBCS Vector MOV WORD PTR $M_RT.$M_DBCS_VEC+2,ES ;;AN000;; ; $ENDIF ;;AN000;; $MIF23: POP SI ;;AN000;; POP AX ;;AN000;; Retrieve character to check RET ;;AN000;; Return ;; $M_GET_DBCS_VEC ENDP ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IF NOCHECKSTDIN ;AN001; Are we suppose to include the code for Checking EOF ? ELSE ;AN001; Yes, THEN include it PAGE SUBTTL DOS - Message Retriever - $M_CHECKSTDIN Proc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Proc Name: $M_CHECKSTDIN ;; ;; Function: ;; ;; Inputs: None ;; ;; Outputs: ;; ;; Regs Changed: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_CHECKSTDIN PROC NEAR ;AN001; MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL MOV BX,STDIN ;AN001; XOR DX,DX ;AN001; INT 21H ;AN001; AND DH,1 ;clear top 7 bits OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL INT 21H ;AN001; RET ;AN001; $M_CHECKSTDIN ENDP ;AN001; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;AN001; END of include for EOF Check IF NOCHECKSTDOUT ;AN001; Are we suppose to include the code for Checking Disk Full? ELSE ;AN001; Yes, THEN include it PAGE SUBTTL DOS - Message Retriever - $M_CHECKSTDOUT Proc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Proc Name: $M_CHECKSTDOUT ;; ;; Function: ;; ;; Inputs: None ;; ;; Outputs: ;; ;; Regs Changed: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_CHECKSTDOUT PROC NEAR ;AN001; MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL MOV BX,STDOUT ;AN001; XOR DX,DX ;AN001; INT 21H ;AN001; OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL INT 21H ;AN001; RET ;AN001; $M_CHECKSTDOUT ENDP ;AN001; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;AN001; END of include for Disk Full Check IF NOVERCHECKmsg ;;AN000;; Are we suppose to include the code for DOS version check? ELSE ;;AN000;; Yes, THEN include it PAGE SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Proc Name: $M_VERSION_CHECK ;; ;; Function: Determine if DOS version is within allowable limits ;; ;; Inputs: None ;; ;; Outputs: CARRY_FLAG = 1 if Incorrect DOS version ;; Registers set for SYSDISPMSG ;; CARRY_FLAG = 0 if Correct DOS version ;; ;; Regs Changed: AX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_VERSION_CHECK PROC NEAR ;;AN000;; ;; MOV AH,DOS_GET_VERSION ;;AN000;; Check that version matches VERSIONA.INC INT 21H ;;AN000;; ;; CMP AX,EXPECTED_VERSION ;;AN000;; IF DOS_MAJOR is correct ; $IF E ;;AN000;; JNE $MIF25 CLC ;;AN000;; Clear the carry flag ; $ELSE ;;AN000;; ELSE JMP SHORT $MEN25 $MIF25: IF NOT COMR ;; ** Special case for RESIDENT COMMAND.COM CMP AX,LOWEST_4CH_VERSION ;;AN000;; Does this version support AH = 4CH ; $IF B ;;AN000;; No, JNB $MIF27 MOV BX,NO_HANDLE ;;AN000;; No handle (version doesn't support) ; $ELSE ;;AN000;; Yes, JMP SHORT $MEN27 $MIF27: MOV BX,STDERR ;;AN000;; Standard Error ; $ENDIF ;;AN000;; $MEN27: ELSE MOV BX,NO_HANDLE ;;AN000;; No handle ENDIF MOV AX,1 ;;AN000;; Set message # 1 MOV CX,NO_REPLACE ;;AN000;; No replacable parms MOV DL,NO_INPUT ;;AN000;; No input MOV DH,UTILITY_MSG_CLASS ;;AN000;; Utility class message STC ;;AN000;; Set Carry Flag ; $ENDIF ;;AN000;; $MEN25: ;; RET ;;AN000;; Return ;; $M_VERSION_CHECK ENDP ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;;AN000;; END of include for DOS version check ENDIF ;;AN000;; END of include for SYSLOADMSG ; IF GETmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? IF COMR ;;AN000;; $M_RT EQU $M_RT2 ;;AN000;; ENDIF ;;AN000;; GETmsg = FALSE ;;AN000;; Yes, THEN include it and reset flag PAGE SUBTTL DOS - Message Retriever - GETMSG.ASM Module ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Proc Name: SYSGETMSG ;; ;; Function: The GET service returns the segment, offset and size of the ;; message text to the caller based on a message number. ;; The GET function will not display the message thus assumes ;; caller will handle replaceable parameters. ;; ;; Inputs: ;; ;; Outputs: ;; ;; Psuedocode: ;; Call $M_GET_MSG_ADDRESS ;; IF MSG_NUM exists THEN ;; Set DS:SI = MSG_TXT_PTR + 1 ;; CARRY_FLAG = 0 ;; ELSE ;; CARRY_FLAG = 1 ;; ENDIF ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; IF FARmsg ;;AN000;; SYSGETMSG PROC FAR ;;AN000;; ELSE ;;AN000;; SYSGETMSG PROC NEAR ;;AN000;; ENDIF ;;AN000;; ;; ;; Save registers needed later PUSH AX ;;AN000;; Save changed regs PUSH ES ;;AN000;; PUSH DI ;;AN000;; PUSH BP ;;AN000;; ;; IF FARmsg ;;AN000;; CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message ELSE ;;AN000;; CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message ENDIF ;;AN000;; Return message in ES:DI ; $IF NC ;;AN000;; Message found? JC $MIF31 CMP DH,UTILITY_MSG_CLASS CLC ;;AN000;; ; $IF NE JE $MIF32 PUSH ES ;;AN000;; POP DS ;;AN000;; Return message in DS:SI ; $ELSE JMP SHORT $MEN32 $MIF32: IF FARmsg ;;AN000;; Yes, PUSH ES ;;AN000;; POP DS ;;AN000;; Return message in DS:SI ELSE ;;AN000;; PUSH CS ;;AN000;; Return message in DS:SI POP DS ;;AN000;; ENDIF ;;AN000;; ; $ENDIF ;;AN000;; $MEN32: MOV SI,DI ;;AN000;; Return message in DS:SI ; $ENDIF ;;AN000;; $MIF31: ;; POP BP ;;AN000;; Restore changed regs POP DI ;;AN000;; POP ES ;;AN000;; POP AX ;;AN000;; ;; RET ;;AN000;; Return ;; SYSGETMSG ENDP ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet $M_SUBS = FALSE ;;AN000;; No, then include and reset the flag ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_GET_MSG_ADDRESS ;; ;; FUNCTION: To scan thru classes to return pointer to the message header ;; INPUTS: Access to $M_RES_ADDRESSES ;; OUPUTS: IF CX = 0 THEN Message was not found ;; IF CX > 1 THEN ES:DI points to the specified message ;; REGS CHANGED: ES,DI,CX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; IF FARmsg ;;AN000;; $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; ELSE ;;AN000;; $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; ENDIF ;;AN000;; ;; PUSH SI ;;AN000;; PUSH BX ;;AN000;; XOR SI,SI ;;AN000;; Use SI as an index XOR CX,CX ;;AN000;; Use CX as an size ; $DO ;;AN000;; $MDO36: CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? ; $IF E ;;AN000;; Yes, JNE $MIF37 IF FARmsg ;;AN000;; LES DI,DWORD PTR $M_RT.$M_CLASS_ADDRS[SI] ;;AN000;; Get address of class MOV BX,ES ;;AN000; ELSE ;;AN000;; MOV DI,WORD PTR $M_RT.$M_CLASS_ADDRS[SI] ;;AN000;; Get address of class MOV BX,DI ;;AN000; ENDIF ;;AN000;; ; $ELSE ;;AN000;; No, JMP SHORT $MEN37 $MIF37: TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? ; $IF NE ;;AN000;; Yes, JE $MIF39 LES DI,DWORD PTR $M_RT.$M_PARSE_COMMAND[SI] ;;AN000;; Get address of class MOV BX,ES ;;AN000; ; $ELSE ;;AN000;; No, extended errors were specified JMP SHORT $MEN39 $MIF39: CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? ; $IF AE,AND ;;AN000;; JNAE $MIF41 CMP AX,$M_CRIT_HI ;;AN000;; ; $IF BE ;;AN000;; Yes, JNBE $MIF41 LES DI,DWORD PTR $M_RT.$M_CRIT_ADDRS[SI] ;;AN000;; Get address of class MOV BX,ES ;;AN000; ; $ELSE ;;AN000;; JMP SHORT $MEN41 $MIF41: LES DI,DWORD PTR $M_RT.$M_EXT_ERR_ADDRS[SI] ;;AN000;; Get address of class MOV BX,ES ;;AN000; ; $ENDIF ;;AN000;; $MEN41: ; $ENDIF ;;AN000;; $MEN39: ; $ENDIF ;;AN000;; $MEN37: ;; CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? ; $IF E ;;AN000;; Yes, JNE $MIF46 CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? ; $IF E ;;AN000;; Yes, JNE $MIF47 STC ;;AN000;; Set the carry flag ; $ELSE ;;AN000;; No, JMP SHORT $MEN47 $MIF47: MOV $M_RT.$M_MSG_NUM,AX ;;AN000;; Save message number MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message XOR SI,SI ;;AN000;; Reset the SI index to start again CLC ;;AN000;; ; $ENDIF ;;AN000;; No, $MEN47: ; $ELSE ;;AN000;; JMP SHORT $MEN46 $MIF46: CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? ; $IF NE ;;AN001;; Yes, JE $MIF51 CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message ; $ENDIF ;;AN000;; $MIF51: ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class CLC ;;AN000;; ; $ENDIF ;;AN000;; $MEN46: ; $LEAVE C ;;AN000;; JC $MEN36 OR CX,CX ;;AN000;; Was the message found? ; $ENDDO NZ,LONG ;;AN000;; JNZ $MXL2 JMP $MDO36 $MXL2: $MEN36: PUSHF ;;AN006;; Save the flag state CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? ; $IF E ;;AN006;; Yes, JNE $MIF56 PUSH DX ;;AN006;; Save all needed registers PUSH BP ;;AN006;; PUSH CX ;;AN006;; PUSH ES ;;AN006;; PUSH DI ;;AN006;; PUSH AX ;;AN006;; MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed INT 2FH ;;AN006;; CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? POP AX ;;AN006;; Restore msg number ; $IF E ;;AN006;; Yes, JNE $MIF57 MOV BX,AX ;;AN006;; BX is the extended error number MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number INT 2FH ;;AN006;; Call IFSFUNC ; $ELSE ;;AN006;; No, JMP SHORT $MEN57 $MIF57: STC ;;AN006;; Carry conditon ; $ENDIF ;;AN006;; $MEN57: ; $IF C ;;AN006;; Was there an update? JNC $MIF60 POP DI ;;AN006;; No, POP ES ;;AN006;; Restore old pointer POP CX ;;AN006;; ; $ELSE ;;AN006;; Yes JMP SHORT $MEN60 $MIF60: ADD SP,6 ;;AN006;; Throw away old pointer CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string ; $ENDIF ;;AN006;; $MEN60: POP BP ;;AN006;; Restore other Regs POP DX ;;AN006;; ; $ENDIF ;;AN006;; $MIF56: $M_POPF ;;AN006;; Restore the flag state POP BX ;;AN000;; POP SI ;;AN000;; RET ;;AN000;; Return ES:DI pointing to the message ;; $M_GET_MSG_ADDRESS ENDP ;; ;; $M_SET_LEN_IN_CX PROC NEAR ;; ;; PUSH DI ;;AN006;; Save position PUSH AX ;;AN006;; MOV CX,-1 ;;AN006;; Set CX for decrements XOR AL,AL ;;AN006;; Prepare compare register REPNE SCASB ;;AN006;; Scan for zero NOT CX ;;AN006;; Change decrement into number DEC CX ;;AN006;; Don't include the zero POP AX ;;AN006;; POP DI ;;AN006;; Restore position RET ;;AN006;; ;; $M_SET_LEN_IN_CX ENDP ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_FIND_SPECIFIED_MSG ;; ;; FUNCTION: To scan thru message headers until message is found ;; INPUTS: ES:DI points to beginning of msg headers ;; CX contains the number of messages in class ;; DH contains the message class ;; OUPUTS: IF CX = 0 THEN Message was not found ;; IF CX > 1 THEN ES:DI points to header of specified message ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; ;; ifdef BILINGUAL push ax ; save ax push ax push bx mov ax,4f01h ; get code page xor bx,bx int 2fh ifdef JAPAN cmp bx,932 endif ifdef KOREA cmp bx,949 endif ifdef TAIWAN cmp bx,950 endif ifdef PRC cmp bx,936 endif pop bx pop ax jz MFSM_03 ; if DBCS code page cmp ax,$M_SPECIAL_MSG_NUM jz MFSM_03 cmp dh,EXT_ERR_CLASS jz MFSM_01 cmp dh,PARSE_ERR_CLASS jz MFSM_02 add ax,UTILITY_MSG_ADJ jmp short MFSM_03 MFSM_01: add ax,EXT_MSG_ADJ jmp short MFSM_03 MFSM_02: add ax,PARSE_MSG_ADJ MFSM_03: endif CMP BX,1 ;;AN004;; Do we have an address to CALL? ; $IF E,AND ;;AN004;; Yes, JNE $MIF64 CMP WORD PTR $M_RT.$M_DISK_PROC_ADDR,-1 ;;AN004;; Do we have an address to CALL? ; $IF NE ;;AN004;; Yes, JE $MIF64 CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? ; $IF E ;;AN004;; . . . and . . . JNE $MIF65 PUSH AX ;;AN004;; Reset the special message number MOV AX,$M_RT.$M_MSG_NUM ;;AN004;; Get the old message number CALL DWORD PTR $M_RT.$M_DISK_PROC_ADDR ;;AN004;; Call the READ_DISK_PROC to get error text POP AX ;;AN004;; Reset the special message number ; $ELSE ;;AN004;; Get the old message number JMP SHORT $MEN65 $MIF65: CALL DWORD PTR $M_RT.$M_DISK_PROC_ADDR ;;AN004;; Call the READ_DISK_PROC to get error text ; $ENDIF ;;AN004;; Get the old message number $MEN65: ; $ELSE ;;AN004;; JMP SHORT $MEN64 $MIF64: XOR CX,CX ;;AN002;; CX = 0 will allow us to CMP DH,UTILITY_MSG_CLASS ;;AN001;; ; $IF NE ;;AN001;; JE $MIF69 ifdef BILINGUAL MOV CX,WORD PTR ES:[DI].$M_NUM_CLS_MSG ;;AN001;; Get number of messages in class else MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG ;;AN001;; Get number of messages in class endif ; $ELSE ;;AN001;; JMP SHORT $MEN69 $MIF69: IF FARmsg ;;AN001;; CMP BYTE PTR ES:[DI].$M_CLASS_ID,DH ;;AN002;; Check if class still exists at ELSE CMP BYTE PTR CS:[DI].$M_CLASS_ID,DH ;;AN002;; Check if class still exists at ENDIF ; $IF E ;;AN002;; pointer (hopefully) JNE $MIF71 IF FARmsg ;;AN001;; ifdef BILINGUAL MOV CX,WORD PTR ES:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class else MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class endif ELSE ifdef BILINGUAL MOV CX,WORD PTR CS:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class else MOV CL,BYTE PTR CS:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class endif ENDIF ; $ENDIF ;;AN002;; go on to the next class $MIF71: ; $ENDIF ;;AN001;; $MEN69: ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header STC ;;AN004;; Flag that we haven't found anything yet ; $ENDIF ;;AN004;; $MEN64: ; $IF C ;;AN004;; Have we found anything yet? JNC $MIF75 CLC ;;AN004;; No, reset carry ; $SEARCH ;;AN000;; $MDO76: OR CX,CX ;;AN000;; Do we have any to check? ; $LEAVE Z ;;AN000;; No, return with CX = 0 JZ $MEN76 CMP DH,UTILITY_MSG_CLASS ;;AN001;; ; $IF NE ;;AN001;; JE $MIF78 CMP AX,WORD PTR ES:[DI].$M_NUM ;;AN001;; Is this the message requested? ; $ELSE ;;AN001;; JMP SHORT $MEN78 $MIF78: IF FARmsg ;;AN001;; CMP AX,WORD PTR ES:[DI].$M_NUM ;;AN000;; Is this the message requested? ELSE CMP AX,WORD PTR CS:[DI].$M_NUM ;;AN000;; Is this the message requested? ENDIF ; $ENDIF $MEN78: ; $EXITIF E ;;AN000;; JNE $MIF76 ; $ORELSE ;;AN000; JMP SHORT $MSR76 $MIF76: DEC CX ;;AN000;; No, well do we have more to check? ; $LEAVE Z ;;AN000;; No, return with CX = 0 JZ $MEN76 ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header ; $ENDLOOP ;;AN000;; JMP SHORT $MDO76 $MEN76: STC ;;AN000;; ; $ENDSRCH ;;AN000;; Check next message $MSR76: ; $IF NC ;;AN000;; Did we find the message? JC $MIF86 CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? CLC ;;AN001;; ; $IF E ;;AN001;; JNE $MIF87 IF FARmsg ;;AN001;; ELSE ;;AN000;; PUSH CS ;;AN000;; POP ES ;;AN000;; Return ES:DI pointing to the message ENDIF ; $ENDIF ;;AN001;; $MIF87: ADD DI,WORD PTR ES:[DI].$M_TXT_PTR ;;AN000;; Prepare ES:DI pointing to the message ; $ENDIF ;;AN004;; $MIF86: ; $ENDIF ;;AN004;; $MIF75: ;; Yes, great we can return with CX > 0 ; $IF NC ;;AN000;; Did we find the message? JC $MIF91 XOR CH,CH ;;AN000;; MOV CL,BYTE PTR ES:[DI] ;;AN000;; Move size into CX INC DI ;;AN000;; Increment past length ; $ENDIF ;;AN004;; $MIF91: MOV $M_RT.$M_SIZE,$M_NULL ;;AN004;; Reset variable ifdef BILINGUAL pop ax endif RET ;;AN000;; Return ;; $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;;AN000;; END of include of common subroutines ENDIF ;;AN000;; END of include of SYSGETMSG ; IF DISPLAYmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? IF COMR ;;AN000;; $M_RT EQU $M_RT2 ;;AN000;; ENDIF ;;AN000;; DISPLAYmsg = FALSE ;;AN000;; Yes, THEN include it and reset flag PAGE SUBTTL DOS - Message Retriever - DISPMSG.ASM Module ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Proc Name: SYSDISPMSG ;; ;; Function: The DISPLAY service will output a defined message to a handle ;; requested by the caller. It also provides function to display ;; messages when handles are not applicable (ie. DOS function calls ;; 00h to 0Ah) Replaceable parameters are allowed and are ;; defined previous to entry. ;; ;; It is assumes that a PRELOAD function has already determined ;; the addressibilty internally to the message retriever services. ;; Inputs: ;; ;; Outputs: ;; ;; Psuedocode: ;; Save registers needed later ;; Get address of the message requested ;; IF Message number exists THEN ;; IF replacable parameters were specified THEN ;; Display message with replacable parms ;; ELSE ;; Display string without replacable parms ;; ENDIF ;; IF character input was requested THEN ;; Wait for character input ;; ENDIF ;; Clear CARRY FLAG ;; ELSE ;; Set CARRY FLAG ;; ENDIF ;; Return ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; IF FARmsg ;;AN000;; SYSDISPMSG PROC FAR ;;AN000;; ELSE ;;AN000;; SYSDISPMSG PROC NEAR ;;AN000;; ENDIF ;;AN000;; ;; ;; Save registers and values needed later PUSH AX ;;AN000;; Save changed REGs PUSH BX ;;AN000;; PUSH CX ;;AN000;; PUSH BP ;;AN000;; PUSH DI ;;AN000;; Save pointer to input buffer (offset) PUSH ES ;;AN000;; Save pointer to input buffer (segment) PUSH DX ;;AN000;; Save Input/Class request MOV BP,CX ;;AN000;; Use BP to hold replace count MOV WORD PTR $M_RT.$M_HANDLE,BX ;;AN000;; Save handle MOV BYTE PTR $M_RT.$M_CLASS,DH ;;AN004;; Save class ;; Get address of the message requested IF FARmsg ;;AN000;; CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message ELSE ;;AN000;; CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message ENDIF ;;AN000;; OR CX,CX ;;AN000;; Was message found? ; $IF NZ ;;AN000;; YES, Message address in ES:DI JZ $MIF93 ;; Test if replacable parameters were specified OR BP,BP ;;AN000;; Were replacable parameters requested ; $IF Z ;;AN000;; JNZ $MIF94 ;; Display string without replacable parms CALL $M_DISPLAY_STRING ;;AN000;; No, great . . . Display message ; $ELSE ;;AN000;; JMP SHORT $MEN94 $MIF94: IF $M_REPLACE ;;AN000;; ;; Display message with replacable parms CALL $M_DISPLAY_MESSAGE ;;AN000;; Display the message with substitutions ENDIF ;;AN000;; ; $ENDIF ;;AN000;; $MEN94: ; $IF NC JC $MIF97 POP DX ;;AN000;; Get Input/Class request CALL $M_ADD_CRLF ;;AN004;; Check if we need to add the CR LF chars. POP ES ;;AN000;; Get location of input buffer (if specified) POP DI ;;AN000;; ;; Test if character input was requested IF INPUTmsg ;;AN000;; OR DL,DL ;;AN000;; Was Wait-For-Input requested? ; $IF NZ ;;AN000;; JZ $MIF98 CALL $M_WAIT_FOR_INPUT ;;AN000;; ; $ENDIF ;;AN000;; $MIF98: ENDIF ;;AN000;; ; $ELSE ;;AN000;; JMP SHORT $MEN97 $MIF97: ADD SP,6 ;;AN000;; STC ;;AN000;; Reset carry flag ; $ENDIF ;;AN000;; $MEN97: ; $ELSE ;;AN000;; No, JMP SHORT $MEN93 $MIF93: POP ES ;;AN000;; Get pointer to input buffer (segment) POP DI ;;AN000;; Get base pointer to first sublist (offset) POP DX ;;AN000;; Get base pointer to first sublist (segment) STC ;;AN000;; Set carry flag ; $ENDIF ;;AN000;; $MEN93: ;; ; $IF NC ;;AN000;; Was there an error? JC $MIF104 POP BP ;;AN000;; No, POP CX ;;AN000;; POP BX ;;AN000;; IF INPUTmsg ;;AN000;; ADD SP,2 ;;AN000;; ELSE ;AN000; POP AX ;;AN000;; ENDIF ;;AN000;; ; $ELSE ;;AN000;; Yes, JMP SHORT $MEN104 $MIF104: ADD SP,8 ;;AN000;; Eliminate from stack STC ;;AN000;; ; $ENDIF ;;AN000;; $MEN104: ;; RET ;;AN000;; Return ;; SYSDISPMSG ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;; ;; PROC NAME: $M_DISPLAY_STRING ;; ;; FUNCTION: Will display or write string ;; INPUTS: ES:DI points to beginning of message ;; CX contains the length of string to write (if applicable) ;; OUTPUTS: None ;; REGS Revised: None ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_DISPLAY_STRING PROC NEAR ;;AN000;; ;; PUSH AX ;;AN000;; PUSH BX ;;AN000;; PUSH DX ;;AN000;; ;; MOV BX,$M_RT.$M_HANDLE ;;AN000;; Retrieve handle ;; IF COMR ;; ** Special case for RESIDENT COMMAND.COM CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string ELSE CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? ; $IF E ;;AN000;; JNE $MIF107 CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string ; $ELSE ;;AN000;; JMP SHORT $MEN107 $MIF107: CALL $M_DISPLAY_H_STRING ;;AN000;; Yes, display string to handle ; $ENDIF ;;AN000;; $MEN107: ;AN001; ; $IF C ;;AN000;; Was there an error? JNC $MIF110 MOV AH,DOS_GET_EXT_ERROR ;;AN000;; Yes, MOV BX,DOS_GET_EXT_ERROR_BX ;;AN000;; Get extended error INT 21H ;;AN000;; XOR AH,AH ;;AN000;; Clear AH ADD SP,6 ;;AN000;; Clean up stack STC ;;AN000;; Flag that there was an error ; $ELSE ;;AN000;; No, JMP SHORT $MEN110 $MIF110: CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? ; $IF NE ;;AN000;; JE $MIF112 CMP AX,CX ;AN001; Was it ALL written? ; $IF NE ;AN001; No, JE $MIF113 CALL $M_GET_EXT_ERR_39 ;AN001; Set Extended error ADD SP,6 ;AN001; Clean up stack STC ;AN001; Flag that there was an error ; $ENDIF ;AN001; $MIF113: ; $ENDIF ;AN001; $MIF112: ; $ENDIF ;;AN000;; $MEN110: ENDIF ; $IF NC ;;AN000;; Was there ANY error? JC $MIF117 POP DX ;;AN000;; Restore regs POP BX ;;AN000;; POP AX ;;AN000;; ; $ENDIF ;;AN000;; $MIF117: RET ;;AN000;; Return ;; $M_DISPLAY_STRING ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_DISPLAY_$_STRING ;; ;; FUNCTION: Will display a $ terminated string ;; INPUTS: ES:DI points to beginning of message text (not the length) ;; OUPUTS: None ;; REGS USED: AX,DX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_DISPLAY_$_STRING PROC NEAR ;;AN000;; ;; PUSH DS ;;AN000;; PUSH ES ;;AN000;; POP DS ;;AN000;; Set DS to segment of message text IF NOT COMR CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? ; $IF E ;;AN000;; Yes, JNE $MIF119 MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER MOV DL,BYTE PTR ES:[DI] ;;AN000;; Get the character INT 21H ;;AN000;; Write character POP DS ;;AN000;; Set DS to segment of message text MOV AL,DL ;;AN000;; Get the character in AL CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character PUSH DS ;;AN000;; PUSH ES ;;AN000;; POP DS ;;AN000;; Set DS to segment of message text ; $IF C ;;AN000;; Yes, JNC $MIF120 MOV DL,BYTE PTR ES:[DI]+1 ;;AN000;; Get the next character INT 21H ;;AN000;; Write character CLC ;;AN000;; Clear the DBCS indicator ; $ENDIF ;;AN000;; $MIF120: ; $ELSE ;;AN000;; No, JMP SHORT $MEN119 $MIF119: ENDIF MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER ; $DO ;;AN002;; No, $MDO123: OR CX,CX ;;AN002;; Are there any left to display? ; $LEAVE Z ;;AN002;; Yes, JZ $MEN123 MOV DL,BYTE PTR ES:[DI] ;;AN002;; Get the character INT 21H ;;AN002;; Display the character INC DI ;;AN002;; Set pointer to next character DEC CX ;;AN002;; Count this character ; $ENDDO Z ;;AN002;; No, JNZ $MDO123 $MEN123: IF NOT COMR ; $ENDIF ;;AN000;; $MEN119: ENDIF CLC ;;AN000;; Char functions used don't return carry as error POP DS ;;AN000;; RET ;;AN000;; ;; $M_DISPLAY_$_STRING ENDP ;;AN000;; ;; IF NOT COMR ; ;Scan_ctrlZ : This routine looks through the string to be printed and ;truncates it at the Ctrl-Z if any present. ; ; ENTRY: ds:dx = String to be displayed ; cx = number of chars to be displayed ; ; EXIT: cx = number of chars to be displayed ; Scan_CtrlZ proc near push di push ax push es push bx mov di,dx push ds pop es ;es:di points at string mov bx,cx ;save current count mov al,1ah cld repne scasb ;find first Ctrl-Z jnz noCtrlZ ;no CtrlZ found in string sub bx,cx dec bx ;bx = new count to display noCtrlZ: mov cx,bx ;cx = actual display count pop bx pop es pop ax pop di ret Scan_CtrlZ endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_DISPLAY_H_STRING ;; ;; FUNCTION: Will display a string to a specified handle ;; INPUTS: ES:DI points to beginning of message ;; CX contains the number of bytes to write ;; BX contains the handle to write to ;; OUPUTS: None ;; REGS USED: AX,DX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_DISPLAY_H_STRING PROC NEAR ;;AN000;; ;; XOR AX,AX ;;AN002;; Set number of bytes written to 0 OR CX,CX ;;AN002;; For performance, don't write if not necessary ; $IF NZ ;;AN002;; Any chars to write? JZ $MIF127 PUSH DS ;;AN000;; Yes, PUSH ES ;;AN000;; POP DS ;;AN000;; Set DS to segment of message text MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle MOV DX,DI ;;AN000;; Pointer to data to write CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? ; $IF E ;;AN000;; Yes, JNE $MIF128 INT 21H ;;AN000;; Write character POP DS ;;AN000;; Set DS to segment of message text PUSH AX ;;AN000;; MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get the character CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character POP AX ;;AN000;; Set DS to segment of message text PUSH DS ;;AN000;; PUSH ES ;;AN000;; POP DS ;;AN000;; Set DS to segment of message text ; $IF C ;;AN000;; Yes, JNC $MIF129 CLC ;;AN000;; Clear the DBCS indicator MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle INC DX ;;AN000;; Point to next character INT 21H ;;AN000;; Write character ; $ENDIF ;;AN000;; $MIF129: ;SR; ; If the single char happened to be a Ctrl-Z, the dos write would return ;0 chars written making the caller think there was an error writing. To ;avoid this, we check if the single char was a Ctrl-Z and if so, return that ;the char was written, thus fooling the caller. ; pushf ;save flags cmp byte ptr es:[di],1ah ;is char a Ctrl-Z? jnz @f ;no, continue mov ax,cx ;yes, fake as if it was written @@: $M_Popf ;restore flags ; $ELSE ;;AN000;; No, JMP SHORT $MEN128 $MIF128: ;SR; ; Prescan the string looking for Ctrl-Z. We terminate the message the moment ;we hit a Ctrl-Z. cx will contain the number of characters to be printed. ; push bp ; M007 push cx call scan_ctrlZ ;cx = count without Ctrl-Z mov bp,cx ;store no ^Z count in bp ;M007 pop cx ;get old count back ;M007 INT 21H ;;AN000;; Write String at DS:SI to handle jnc chk_count ;no error, adjust return count jmp short m_cnt_ok ;error, return with carry set;M007 ;M007 ; If we are writing to con and there is a Ctrl-Z in the string, the ;return count will be much less and if this returns to the caller we can get ;spurious error messages. We check here if the count returned is same as ;original count or same as the count if we stop at Ctrl-Z. In the second ;case, we fake it as if all bytes have been written. If the return count ;does not match either count, then we had some other disk error (such as ;insufficient disk space) and we pass it through ; chk_count: cmp cx,ax ;have all bytes been written?;M007 je m_cnt_ok ;there was an error writing ;M007 cmp bp,ax ;count = Ctrl-Z count? ;M007 clc ;no error either way ;M007 jne m_cnt_ok ;no, pass it through ;M007 mov ax,cx ;return old count ;M007 m_cnt_ok: ; M007 pop bp ; M007 ; $ENDIF ;;AN000;; $MEN128: POP DS ;;AN000;; ; $ENDIF ;;AN002;; $MIF127: ;; RET ;;AN000;; ;; $M_DISPLAY_H_STRING ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_GET_EXT_ERR_39 ;; ;; FUNCTION: Will set registers for extended error #39 ;; INPUTS: None ;; OUPUTS: AX,BX,CX set ;; REGS USED: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_GET_EXT_ERR_39 PROC NEAR ;AN001; ;; MOV AX,EXT_ERR_39 ;AN001; Set AX=39 MOV BX,(ERROR_CLASS_39 SHR 8) + ACTION_39 ;AN001; Set BH=1 BL=4 MOV CH,LOCUS_39 ;AN001; Set CH=1 ;AN001; RET ;AN001; ;; $M_GET_EXT_ERR_39 ENDP ;AN001; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;; ;; PROC NAME: $M_ADD_CRLF ;; ;; FUNCTION: Will decide whether to display a CRLF ;; INPUTS: DX contains the Input/Class requested ;; OUTPUTS: None ;; REGS Revised: CX,ES,DI ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_ADD_CRLF PROC NEAR ;;AN004;; ;; CMP DH,UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? ; $IF NE ;;AN004;; No, JE $MIF134 TEST DH,$M_NO_CRLF_MASK ;;AN004;; Are we to supress the CR LF? ; $IF Z ;;AN004;; No, JNZ $MIF135 PUSH DS ;;AN004;; POP ES ;;AN004;; Set ES to data segment LEA DI,$M_RT.$M_CRLF ;;AN004;; Point at CRLF message MOV CX,$M_CRLF_SIZE ;;AN004;; Set the message size CALL $M_DISPLAY_STRING ;;AN004;; Display the CRLF ; $ENDIF ;;AN004;; $MIF135: ; $ENDIF ;;AN004;; $MIF134: RET ;;AN004;; Return ;; $M_ADD_CRLF ENDP ;;AN004;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_IS_IT_DBCS ;; ;; FUNCTION: Will decide whether character is Single or Double Byte ;; INPUTS: AL contains the byte to be checked ;; OUPUTS: Carry flag = 0 if byte is NOT in DBCS range ;; Carry flag = 1 if byte IS in DBCS range ;; REGS USED: All restored ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_IS_IT_DBCS PROC NEAR ;;AN000;; ;; PUSH ES ;;AN000;; Save Extra segment register PUSH DI ;;AN000;; Save SI register ;; LES DI,$M_RT.$M_DBCS_VEC ;;AN000;; OR DI,DI ;;AN000;; Was the DBCS vector set? ; $IF NZ ;;AN000;; JZ $MIF138 ; $DO ;;AN000;; $MDO139: CMP WORD PTR ES:[DI],$M_DBCS_TERM ;;AN000;; Is this the terminating flag? CLC ;;AN000;; ; $LEAVE E ;;AN000;; JE $MEN139 ;; No, CMP AL,BYTE PTR ES:[DI] ;;AN000;; Does the character fall in the DBCS range? ; $IF AE,AND ;;AN000;; JNAE $MIF141 CMP AL,BYTE PTR ES:[DI]+1 ;;AN000;; Does the character fall in the DBCS range? ; $IF BE ;;AN000;; JNBE $MIF141 STC ;;AN000;; Yes, ; $ENDIF ;;AN000;; Set carry flag $MIF141: INC DI ;;AN000;; No, INC DI ;;AN000;; Go to next vector ; $ENDDO ;;AN000;; JMP SHORT $MDO139 $MEN139: ; $ENDIF ;;AN000;; $MIF138: POP DI ;;AN000;; POP ES ;;AN000;; Restore SI register RET ;;AN000;; Return ;; $M_IS_IT_DBCS ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_CONVERT2ASC ;; ;; FUNCTION: Convert a binary number to a ASCII string ;; INPUTS: DX:AX contains the number to be converted ;; $M_RT_DIVISOR contains the divisor ;; OUPUTS: CX contains the number of characters ;; Top of stack --> Last character ;; . . . ;; Bot of stack --> First character ;; REGS USED: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_CONVERT2ASC PROC NEAR ;;AN000;; ;; POP [$M_RT.$M_RETURN_ADDR] ;;AN000;; Save Return Address XOR BX,BX ;;AN000;; Use BP as a swapping register ;; XCHG BX,AX ;;AN000;; Initialize - Low Word in BP XCHG AX,DX ;;AN000;; - High Word in AX ; $DO ;;AN000;; DO UNTIL Low Word becomes zero $MDO145: DIV $M_RT.$M_DIVISOR ;;AN000;; Divide High Word by divisor XCHG BX,AX ;;AN000;; Setup to divide Low Word using remainder ;; and save reduced High Word in BP DIV $M_RT.$M_DIVISOR ;;AN000;; Divide Low Word by divisor CMP DX,9 ;;AN000;; Make a digit of the remainder ; $IF A ;;AN000;; IF 10 to 15, JNA $MIF146 ADD DL,55 ;;AN000;; Make A to F ASCII ; $ELSE ;;AN000;; IF 0 to 9, JMP SHORT $MEN146 $MIF146: ADD DL,'0' ;;AN000;; Make 0 to 9 ASCII ; $ENDIF ;;AN000;; $MEN146: PUSH DX ;;AN000;; Save the digit on the stack INC CX ;;AN000;; Count that digit OR AX,AX ;;AN000;; Are we done? ; $LEAVE Z,AND ;;AN000;; JNZ $MLL149 OR BX,BX ;;AN000;; AX and BX must be ZERO!! ; $LEAVE Z ;;AN000;; No, JZ $MEN145 $MLL149: IF NOT COMR CMP CX,$M_FIRST_THOU ;;AN000;; Are we at the first thousands mark ; $IF E ;;AN000;; Yes, JNE $MIF150 CMP $M_SL.$M_S_PAD,$M_COMMA ;;AN000;; Is the pad character a comma? ; $IF E ;;AN000;; Yes, JNE $MIF151 PUSH WORD PTR $M_RT.$M_THOU_SEPARA ;;AN000;; Insert a thousand separator INC CX ;;AN000;; ; $ENDIF ;;AN000;; $MIF151: ; $ELSE ;;AN000;; No, JMP SHORT $MEN150 $MIF150: CMP CX,$M_SECOND_THOU ;;AN000;; Are we at the first thousands mark ; $IF E ;;AN000;; Yes, JNE $MIF154 CMP $M_SL.$M_S_PAD,$M_COMMA ;;AN000;; Is the pad character a comma? ; $IF E ;;AN000;; Yes, JNE $MIF155 PUSH WORD PTR $M_RT.$M_THOU_SEPARA ;;AN000;; Insert a thousand separator INC CX ;;AN000;; ; $ENDIF ;;AN000;; $MIF155: ; $ELSE ;;AN000;; No, JMP SHORT $MEN154 $MIF154: CMP CX,$M_THIRD_THOU ;;AN000;; Are we at the first thousands mark ; $IF E ;;AN000;; Yes, JNE $MIF158 CMP $M_SL.$M_S_PAD,$M_COMMA ;;AN000;; Is the pad character a comma? ; $IF E ;;AN000;; Yes, JNE $MIF159 PUSH WORD PTR $M_RT.$M_THOU_SEPARA ;;AN000;; Insert a thousand separator INC CX ;;AN000;; ; $ENDIF ;;AN000;; $MIF159: ; $ENDIF ;;AN000;; $MIF158: ; $ENDIF ;;AN000;; $MEN154: ; $ENDIF ;;AN000;; $MEN150: ENDIF XCHG AX,BX ;;AN000;; Setup to divide the reduced High Word ;;AN000;; and Revised Low Word XOR DX,DX ;;AN000;; Reset remainder ; $ENDDO ;;AN000;; NEXT JMP SHORT $MDO145 $MEN145: ;;AN000;; Yes, XOR DX,DX ;;AN000;; Reset remainder XOR AX,AX ;;AN000;; Reset remainder PUSH [$M_RT.$M_RETURN_ADDR] ;;AN000;; Restore Return Address RET ;;AN000;; Return ;; $M_CONVERT2ASC ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_DISPLAY_MESSAGE ;; ;; FUNCTION: Will display or write entire message (with replacable parameters) ;; INPUTS: ES:DI points to beginning of message ;; DS:SI points to first sublist structure in chain ;; BX contains the handle to write to (if applicable) ;; CX contains the length of string to write (before substitutions) ;; BP contains the count of replacables ;; ;; OUTPUTS: ;; REGS USED: All ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_DISPLAY_MESSAGE PROC NEAR ;;AN000;; ;; ; $DO ;;AN000;; Note: DS:SI -> message $MDO165: XOR DX,DX ;;AN000;; Set size = 0 OR CX,CX ;;AN000;; Are we finished the message yet? ; $IF NZ ;;AN000;; No, JZ $MIF166 MOV AH,"%" ;;AN000;; Prepare to scan for % MOV AL,0 ;;AN004;; ;; ; $DO ;;AN000;; Scan through string until % $MDO167: CMP BYTE PTR ES:[DI],AH ;;AN000;; Is this character NOT a % ; $LEAVE E,AND ;;AN000;; No, JNE $MLL168 CMP BYTE PTR ES:[DI+1],AH ;;AN000;; Is the next character also a % ; $LEAVE NE,AND ;;AN000;; No, JE $MLL168 CMP AL,AH ;;AN000;; Was the character before a % ; $LEAVE NE ;;AN000;; No, GREAT found it JNE $MEN167 $MLL168: MOV AL,BYTE PTR ES:[DI] ;;AN004;; Yes, (to any of the above) CALL $M_IS_IT_DBCS ;;AN004;; Is this character the first part of a DBCS? ; $IF C ;;AN004;; Yes, JNC $MIF169 INC DI ;;AN004;; Increment past second part ; $ENDIF ;;AN004;; $MIF169: INC DI ;;AN000;; Next character in string INC DX ;;AN000;; Size = Size + 1 DEC CX ;;AN000;; Decrement total size ; $ENDDO Z ;;AN000;; Exit scan if we're at the end of the line JNZ $MDO167 $MEN167: ; $ENDIF ;;AN000;; $MIF166: ;; PUSH SI ;;AN000;; Save beginning of sublists XCHG CX,DX ;;AN000;; Get size of message to display (tot sz in DX) OR BP,BP ;;AN000;; Do we have any replacables to do? ; $IF NZ ;;AN000;; Yes, JZ $MIF173 DEC BP ;;AN000;; Decrement number of replacables ;; Search through sublists to find applicable one CMP $M_RT.$M_MSG_NUM,$M_NULL ;;AN000;; Is this an Extended/Parse case ; $IF E ;;AN000;; No, JNE $MIF174 ; $SEARCH ;;AN000;; $MDO175: MOV AL,$M_SL.$M_S_ID ;;AN000;; Get ID byte ADD AL,30H ;;AN000;; Convert to ASCII CMP AL,BYTE PTR ES:[DI]+1 ;;AN000;; Is this the right sublist? ; $EXITIF E ;;AN000;; JNE $MIF175 ; $ORELSE ;;AN000;; No, JMP SHORT $MSR175 $MIF175: CMP AL,$M_SPECIAL_CASE ;;AN000;; Does this sublist have ID = 0 ; $LEAVE E,AND ;;AN000;; Yes, JNE $MLL178 OR DX,DX ;;AN000;; Are we at the end of the message? ; $LEAVE Z ;;AN000;; No, JZ $MEN175 $MLL178: ADD SI,WORD PTR $M_SL.$M_S_SIZE ;;AN000;; Next SUBLIST ; $ENDLOOP ;;AN000;; Yes, JMP SHORT $MDO175 $MEN175: CMP $M_RT.$M_CLASS,UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? ; $IF E ;;AN004;; Yes, JNE $MIF180 INC DX ;;AN000;; Remember to display CR,LF INC DX ;;AN000;; at the end of the message DEC CX ;;AN000;; Adjust message length DEC CX ;;AN000;; DEC DI ;;AN000;; Adjust ending address of message DEC DI ;;AN000;; ; $ELSE ;;AN004;; No, JMP SHORT $MEN180 $MIF180: MOV DX,-1 ;;AN004;; Set special case ; $ENDIF ;;AN004;; $MEN180: ; $ENDSRCH ;;AN000;; $MSR175: ; $ENDIF ;;AN000;; $MIF174: ; $ENDIF ;;AN000;; $MIF173: ;; Prepare and display this part of message PUSH DI ;;AN000;; Save pointer to replace number SUB DI,CX ;;AN000;; Determine beginning of string CALL $M_DISPLAY_STRING ;;AN000;; Display string until % (or end) POP DI ;;AN000;; Get back pointer to replace number POP CX ;;AN000;; Clean up stack in case error ; $LEAVE C,LONG ;;AN000;; Fail if carry was set JNC $MXL3 JMP $MEN165 $MXL3: PUSH CX ;;AN000;; ;; Save and reset pointer registers MOV CX,DX ;;AN000;; Get the size of the rest of the message CMP $M_SL.$M_S_ID,$M_SPECIAL_CASE-30H ;;AN000;; Is this the %0 case? ; $IF NE ;;AN000;; No, JE $MIF187 OR CX,CX ;;AN000;; Are we finished the whole message? ; $IF NZ ;;AN000;; No, JZ $MIF188 DEC CX ;;AN000;; Decrement total size (%) DEC CX ;;AN000;; Decrement total size (#) INC DI ;;AN000;; Go past % INC DI ;;AN000;; Go past replace number ; $ELSE ;;AN000;; Yes, (Note this will not leave because INC) JMP SHORT $MEN188 $MIF188: POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs ; $ENDIF ;;AN000;; Yes, Note this will not leave because INC $MEN188: ; $ELSE ;;AN000;; JMP SHORT $MEN187 $MIF187: OR CX,CX ;;AN000;; Are we finished the whole message? ; $IF Z ;;AN004;; No, JNZ $MIF192 POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs ; $ELSE ;;AN000;; No, JMP SHORT $MEN192 $MIF192: CMP CX,-1 ;;AN004;; Are we at the end of the message? ; $IF Z ;;AN004;; No, JNZ $MIF194 XOR CX,CX ;;AN004;; ; $ENDIF ;;AN000;; $MIF194: OR DI,DI ;;AN004;; Turn ZF off ; $ENDIF ;;AN000;; $MEN192: ; $ENDIF ;;AN000;; Note this will not leave because INC $MEN187: ; $LEAVE Z ;;AN000;; JZ $MEN165 PUSH BP ;;AN000;; Save the replace count PUSH DI ;;AN000;; Save location to complete message PUSH ES ;;AN000;; PUSH CX ;;AN000;; Save size of the rest of the message XOR CX,CX ;;AN000;; Reset CX used for character count ;; Determine what action is required on parameter CMP $M_RT.$M_MSG_NUM,$M_NULL ;;AN000;; Is this an Extended/Parse case ; $IF E ;;AN000;; JNE $MIF199 IF CHARmsg ;;AN000;; Was Char specified? TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Char_Type AND $M_TYPE_MASK ;;AN000;; ; $IF Z ;;AN000;; JNZ $MIF200 ;; Character type requested ;;AN000;; LES DI,DWORD PTR $M_SL.$M_S_VALUE ;;AN000;; Load pointer to replacing parameter CALL $M_CHAR_REPLACE ;;AN000;; ; $ELSE ;;AN000;; Get the rest of the message to display JMP SHORT $MEN200 $MIF200: ENDIF ;;AN000;; IF NUMmsg ;;AN000;; Was Nnmeric type specified? TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Sgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; ; $IF Z,OR ;;AN000;; JZ $MLL202 TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Unsgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; ; $IF Z,OR ;;AN000;; JZ $MLL202 TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Bin_Hex_Type AND $M_TYPE_MASK ;;AN000;; ; $IF Z ;;AN000;; JNZ $MIF202 $MLL202: ;; Numeric type requested LES DI,DWORD PTR $M_SL.$M_S_VALUE ;;AN000;; Load pointer to replacing parameter CALL $M_BIN2ASC_REPLACE ;;AN000;; ; $ELSE ;;AN000;; Get the rest of the message to display JMP SHORT $MEN202 $MIF202: ENDIF ;;AN000;; IF DATEmsg ;;AN000;; Was date specified? TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Date_Type AND $M_TYPE_MASK ;;AN000;; ; $IF E ;;AN000;; JNE $MIF204 ;; Date type requested CALL $M_DATE_REPLACE ;;AN000;; ; $ELSE ;;AN000;; Get the rest of the message to display JMP SHORT $MEN204 $MIF204: ENDIF ;;AN000;; IF TIMEmsg ;;AN000;; Was time (12 hour format) specified? ;; Time type requested (Default if we have not matched until here) CALL $M_TIME_REPLACE ;;AN000;; ENDIF ;;AN000;; IF DATEmsg ;;AN000;; ; $ENDIF ;;AN000;; $MEN204: ENDIF ;;AN000;; IF NUMmsg ;;AN000;; ; $ENDIF ;;AN000;; $MEN202: ENDIF ;;AN000;; IF CHARmsg ;;AN000;; ; $ENDIF ;;AN000;; $MEN200: ENDIF ;;AN000;; IF $M_REPLACE ;;AN000;; ;; With the replace information of the Stack, display the replaceable field CALL $M_DISPLAY_REPLACE ;;AN000;; Display the replace ENDIF ;;AN000;; ;; None of the above - Extended/Parse replace ; $ELSE ;;AN000;; JMP SHORT $MEN199 $MIF199: IF NOT COMR CALL $M_EXT_PAR_REPLACE ;;AN000;; ENDIF ; $ENDIF ;;AN000;; $MEN199: ;; We must go back and complete the message after the replacable parameter if there is any left ; $IF NC ;;AN000;; IF there was an error displaying then EXIT JC $MIF211 POP CX ;;AN000;; Get size of the rest of the message POP ES ;;AN000;; Get address of the rest of the message POP DI ;;AN000;; POP BP ;;AN000;; Get replacment count POP SI ;;AN000;; ELSE get address of first sublist structure ; $ELSE ;;AN000;; JMP SHORT $MEN211 $MIF211: ADD SP,10 ;;AN000;; Clean up stack if error STC ;;AN000;; ; $ENDIF ;;AN000;; $MEN211: CMP $M_RT.$M_MSG_NUM,$M_NULL ;;AN000;; Is this an Extended/Parse case ; $ENDDO NE,OR ;;AN000;; JNE $MLL214 ; $ENDDO C,LONG ;;AN000;; Go back and display the rest of the message JC $MXL4 JMP $MDO165 $MXL4: $MLL214: $MEN165: ;; IF there was an error displaying then EXIT MOV $M_RT.$M_MSG_NUM,0 ;;AN000;; Reset message number to null RET ;;AN000;; Return ;; $M_DISPLAY_MESSAGE ENDP ;;AN000;; IF NOT COMR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_EXT_PAR_REPLACE ;; ;; FUNCTION: ;; INPUTS: ;; OUPUTS: ;; ;; REGS USED: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_EXT_PAR_REPLACE PROC NEAR ;;AN000;; ;; XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) MOV AX,$M_RT.$M_MSG_NUM ;;AN000;; Prepare for get binary value (LOW) MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; Set default divisor ;; CALL $M_CONVERT2ASC ;;AN000;; ;; ; $DO ;;AN000;; $MDO215: POP AX ;;AN000;; Get character in register MOV BYTE PTR $M_RT.$M_TEMP_BUF[BX],AL ;;AN000;; Move char into the buffer INC BX ;;AN000;; Increase buffer count CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? ; $IF E ;;AN000;; Yes, JNE $MIF216 CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer ; $ENDIF ;;AN000;; $MIF216: DEC CL ;;AN000;; Have we completed replace? ; $ENDDO Z ;;AN000;; JNZ $MDO215 ;; MOV AX,$M_CR_LF ;;AN000;; Move char into the buffer MOV WORD PTR $M_RT.$M_TEMP_BUF[BX],AX ;;AN000;; Move char into the buffer INC BX ;;AN000;; Increase buffer count INC BX ;;AN000;; Increase buffer count CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer RET ;;AN000:: ;; $M_EXT_PAR_REPLACE ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet $M_SUBS = FALSE ;;AN000;; No, then include and reset the flag ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_GET_MSG_ADDRESS ;; ;; FUNCTION: To scan thru classes to return pointer to the message header ;; INPUTS: Access to $M_RES_ADDRESSES ;; OUPUTS: IF CX = 0 THEN Message was not found ;; IF CX > 1 THEN DS:SI points to the specified message ;; REGS CHANGED: ES,DI,CX,DS,SI ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; IF FARmsg ;;AN000;; $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; ELSE ;;AN000;; $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; ENDIF ;;AN000;; ;; PUSH SI ;;AN000;; PUSH BX ;;AN000;; XOR SI,SI ;;AN000;; Use SI as an index XOR CX,CX ;;AN000;; Use CX as an size ; $DO ;;AN000;; $MDO219: CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? ; $IF E ;;AN000;; Yes, JNE $MIF220 IF FARmsg ;;AN000;; LES DI,DWORD PTR $M_RT.$M_CLASS_ADDRS[SI] ;;AN000;; Get address of class MOV BX,ES ;;AN000; ELSE ;;AN000;; MOV DI,WORD PTR $M_RT.$M_CLASS_ADDRS[SI] ;;AN000;; Get address of class MOV BX,DI ;;AN000; ENDIF ;;AN000;; ; $ELSE ;;AN000;; No, JMP SHORT $MEN220 $MIF220: TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? ; $IF NE ;;AN000;; Yes, JE $MIF222 LES DI,DWORD PTR $M_RT.$M_PARSE_COMMAND[SI] ;;AN000;; Get address of class MOV BX,ES ;;AN000; ; $ELSE ;;AN000;; No, extended errors were specified JMP SHORT $MEN222 $MIF222: CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? ; $IF AE,AND ;;AN000;; JNAE $MIF224 CMP AX,$M_CRIT_HI ;;AN000;; ; $IF BE ;;AN000;; Yes, JNBE $MIF224 LES DI,DWORD PTR $M_RT.$M_CRIT_ADDRS[SI] ;;AN000;; Get address of class MOV BX,ES ;;AN000; ; $ELSE ;;AN000;; JMP SHORT $MEN224 $MIF224: LES DI,DWORD PTR $M_RT.$M_EXT_ERR_ADDRS[SI] ;;AN000;; Get address of class MOV BX,ES ;;AN000; ; $ENDIF ;;AN000;; $MEN224: ; $ENDIF ;;AN000;; $MEN222: ; $ENDIF ;;AN000;; $MEN220: ;; CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? ; $IF E ;;AN000;; Yes, JNE $MIF229 CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? ; $IF E ;;AN000;; Yes, JNE $MIF230 STC ;;AN000;; Set the carry flag ; $ELSE ;;AN000;; No, JMP SHORT $MEN230 $MIF230: MOV $M_RT.$M_MSG_NUM,AX ;;AN000;; Save message number MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message XOR SI,SI ;;AN000;; Reset the SI index to start again CLC ;;AN000;; ; $ENDIF ;;AN000;; No, $MEN230: ; $ELSE ;;AN000;; JMP SHORT $MEN229 $MIF229: CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? ; $IF NE ;;AN001;; Yes, JE $MIF234 CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message ; $ENDIF ;;AN000;; $MIF234: ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class CLC ;;AN000;; ; $ENDIF ;;AN000;; $MEN229: ; $LEAVE C ;;AN000;; JC $MEN219 OR CX,CX ;;AN000;; Was the message found? ; $ENDDO NZ,LONG ;;AN000;; JNZ $MXL5 JMP $MDO219 $MXL5: $MEN219: PUSHF ;;AN006;; Save the flag state CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? ; $IF E ;;AN006;; Yes, JNE $MIF239 PUSH DX ;;AN006;; Save all needed registers PUSH BP ;;AN006;; PUSH CX ;;AN006;; PUSH ES ;;AN006;; PUSH DI ;;AN006;; PUSH AX ;;AN006;; MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed INT 2FH ;;AN006;; CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? POP AX ;;AN006;; Restore msg number ; $IF E ;;AN006;; Yes, JNE $MIF240 MOV BX,AX ;;AN006;; BX is the extended error number MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number INT 2FH ;;AN006;; Call IFSFUNC ; $ELSE ;;AN006;; No, JMP SHORT $MEN240 $MIF240: STC ;;AN006;; Carry conditon ; $ENDIF ;;AN006;; $MEN240: ; $IF C ;;AN006;; Was there an update? JNC $MIF243 POP DI ;;AN006;; No, POP ES ;;AN006;; Restore old pointer POP CX ;;AN006;; ; $ELSE ;;AN006;; Yes JMP SHORT $MEN243 $MIF243: ADD SP,6 ;;AN006;; Throw away old pointer CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string ; $ENDIF ;;AN006;; $MEN243: POP BP ;;AN006;; Restore other Regs POP DX ;;AN006;; ; $ENDIF ;;AN006;; $MIF239: $M_POPF ;;AN006;; Restore the flag state POP BX ;;AN000;; POP SI ;;AN000;; RET ;;AN000;; Return ES:DI pointing to the message ;; $M_GET_MSG_ADDRESS ENDP ;; ;; $M_SET_LEN_IN_CX PROC NEAR ;; ;; PUSH DI ;;AN006;; Save position PUSH AX ;;AN006;; MOV CX,-1 ;;AN006;; Set CX for decrements XOR AL,AL ;;AN006;; Prepare compare register REPNE SCASB ;;AN006;; Scan for zero NOT CX ;;AN006;; Change decrement into number DEC CX ;;AN006;; Don't include the zero POP AX ;;AN006;; POP DI ;;AN006;; Restore position RET ;;AN006;; ;; $M_SET_LEN_IN_CX ENDP ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_FIND_SPECIFIED_MSG ;; ;; FUNCTION: To scan thru message headers until message is found ;; INPUTS: ES:DI points to beginning of msg headers ;; CX contains the number of messages in class ;; DH contains the message class ;; OUPUTS: IF CX = 0 THEN Message was not found ;; IF CX > 1 THEN ES:DI points to header of specified message ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; ;; ifdef BILINGUAL push ax ; save ax push ax push bx mov ax,4f01h ; get code page xor bx,bx int 2fh ifdef JAPAN cmp bx,932 endif ifdef KOREA cmp bx,949 endif ifdef TAIWAN cmp bx,950 endif ifdef PRC cmp bx,936 endif pop bx pop ax jz MFSM_13 ; if DBCS code page cmp ax,$M_SPECIAL_MSG_NUM jz MFSM_13 cmp dh,EXT_ERR_CLASS jz MFSM_11 cmp dh,PARSE_ERR_CLASS jz MFSM_12 add ax,UTILITY_MSG_ADJ jmp short MFSM_13 MFSM_11: add ax,EXT_MSG_ADJ jmp short MFSM_13 MFSM_12: add ax,PARSE_MSG_ADJ MFSM_13: endif CMP BX,1 ;;AN004;; Do we have an address to CALL? ; $IF E,AND ;;AN004;; Yes, JNE $MIF247 CMP WORD PTR $M_RT.$M_DISK_PROC_ADDR,-1 ;;AN004;; Do we have an address to CALL? ; $IF NE ;;AN004;; Yes, JE $MIF247 CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? ; $IF E ;;AN004;; . . . and . . . JNE $MIF248 PUSH AX ;;AN004;; Reset the special message number MOV AX,$M_RT.$M_MSG_NUM ;;AN004;; Get the old message number CALL DWORD PTR $M_RT.$M_DISK_PROC_ADDR ;;AN004;; Call the READ_DISK_PROC to get error text POP AX ;;AN004;; Reset the special message number ; $ELSE ;;AN004;; Get the old message number JMP SHORT $MEN248 $MIF248: CALL DWORD PTR $M_RT.$M_DISK_PROC_ADDR ;;AN004;; Call the READ_DISK_PROC to get error text ; $ENDIF ;;AN004;; Get the old message number $MEN248: ; $ELSE ;;AN004;; JMP SHORT $MEN247 $MIF247: XOR CX,CX ;;AN002;; CX = 0 will allow us to CMP DH,UTILITY_MSG_CLASS ;;AN001;; ; $IF NE ;;AN001;; JE $MIF252 ifdef BILINGUAL MOV CX,WORD PTR ES:[DI].$M_NUM_CLS_MSG ;;AN001;; Get number of messages in class else MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG ;;AN001;; Get number of messages in class endif ; $ELSE ;;AN001;; JMP SHORT $MEN252 $MIF252: IF FARmsg ;;AN001;; CMP BYTE PTR ES:[DI].$M_CLASS_ID,DH ;;AN002;; Check if class still exists at ELSE CMP BYTE PTR CS:[DI].$M_CLASS_ID,DH ;;AN002;; Check if class still exists at ENDIF ; $IF E ;;AN002;; pointer (hopefully) JNE $MIF254 IF FARmsg ;;AN001;; ifdef BILINGUAL MOV CX,WORD PTR ES:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class else MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class endif ELSE ifdef BILINGUAL MOV CX,WORD PTR CS:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class else MOV CL,BYTE PTR CS:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class endif ENDIF ; $ENDIF ;;AN002;; go on to the next class $MIF254: ; $ENDIF ;;AN001;; $MEN252: ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header STC ;;AN004;; Flag that we haven't found anything yet ; $ENDIF ;;AN004;; $MEN247: ; $IF C ;;AN004;; Have we found anything yet? JNC $MIF258 CLC ;;AN004;; No, reset carry ; $SEARCH ;;AN000;; $MDO259: OR CX,CX ;;AN000;; Do we have any to check? ; $LEAVE Z ;;AN000;; No, return with CX = 0 JZ $MEN259 CMP DH,UTILITY_MSG_CLASS ;;AN001;; ; $IF NE ;;AN001;; JE $MIF261 CMP AX,WORD PTR ES:[DI].$M_NUM ;;AN001;; Is this the message requested? ; $ELSE ;;AN001;; JMP SHORT $MEN261 $MIF261: IF FARmsg ;;AN001;; CMP AX,WORD PTR ES:[DI].$M_NUM ;;AN000;; Is this the message requested? ELSE CMP AX,WORD PTR CS:[DI].$M_NUM ;;AN000;; Is this the message requested? ENDIF ; $ENDIF $MEN261: ; $EXITIF E ;;AN000;; JNE $MIF259 ; $ORELSE ;;AN000; JMP SHORT $MSR259 $MIF259: DEC CX ;;AN000;; No, well do we have more to check? ; $LEAVE Z ;;AN000;; No, return with CX = 0 JZ $MEN259 ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header ; $ENDLOOP ;;AN000;; JMP SHORT $MDO259 $MEN259: STC ;;AN000;; ; $ENDSRCH ;;AN000;; Check next message $MSR259: ; $IF NC ;;AN000;; Did we find the message? JC $MIF269 CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? CLC ;;AN001;; ; $IF E ;;AN001;; JNE $MIF270 IF FARmsg ;;AN001;; ELSE ;;AN000;; PUSH CS ;;AN000;; POP ES ;;AN000;; Return ES:DI pointing to the message ENDIF ; $ENDIF ;;AN001;; $MIF270: ADD DI,WORD PTR ES:[DI].$M_TXT_PTR ;;AN000;; Prepare ES:DI pointing to the message ; $ENDIF ;;AN004;; $MIF269: ; $ENDIF ;;AN004;; $MIF258: ;; Yes, great we can return with CX > 0 ; $IF NC ;;AN000;; Did we find the message? JC $MIF274 XOR CH,CH ;;AN000;; MOV CL,BYTE PTR ES:[DI] ;;AN000;; Move size into CX INC DI ;;AN000;; Increment past length ; $ENDIF ;;AN004;; $MIF274: MOV $M_RT.$M_SIZE,$M_NULL ;;AN004;; Reset variable ifdef BILINGUAL pop ax endif RET ;;AN000;; Return ;; $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;;AN000;; END of include of common subroutines ; IF $M_REPLACE ;;AN000;; Is the request to include the code for replaceable parms $M_REPLACE = FALSE ;;AN000;; Tell the assembler we did ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $M_DISPLAY_REPLACE PROC NEAR ;;AN000;; ;; XOR BX,BX ;;AN000;; Use BX for buffer count IF NOT COMR CMP $M_SL.$M_S_ID,$M_SPECIAL_CASE-30H ;;AN000;; Is this the special case (convert to ASCII) ; $IF E ;;AN000;; Yes, JNE $MIF276 MOV WORD PTR $M_RT.$M_TEMP_BUF[BX],$M_SPACE_HYP ;;AN000;; Move in a " -" INC BX ;;AN000;; Increment count INC BX ;;AN000;; Increment count MOV BYTE PTR $M_RT.$M_TEMP_BUF[BX],$M_SPACE ;;AN000;; Move in a " " INC BX ;;AN000;; Increment count CALL $M_FLUSH_BUF ;;AN000;; Write out " - " to prepare for special case ; $ENDIF ;;AN000;; If it fails we will catch it later $MIF276: ENDIF POP BP ;;AN000;; Remember the return address XOR BX,BX ;;AN000;; Use BX for buffer count XOR DX,DX ;;AN000;; Use DX for count of parms taken off the stack MOV $M_RT.$M_SIZE,CL ;;AN000;; Save size to later clear stack MOV AL,BYTE PTR $M_SL.$M_S_MINW ;;AN000;; Get the minimum width ;; CMP AL,CL ;;AN000;; Do we need pad chars added? ; $IF A ;;AN000;; Yes, JNA $MIF278 SUB AL,CL ;;AN000;; Calculate how many pad chars are needed. MOV DH,AL ;;AN000;; Save the number of pad characters TEST BYTE PTR $M_SL.$M_S_FLAG,Right_Align ;;AN000;; Was replaceable parm to be right aligned? ; $IF NZ ;;AN000;; Yes, JZ $MIF279 ; $DO ;;AN000;; Begin filling buffer with pad chars $MDO280: MOV AL,BYTE PTR $M_SL.$M_S_PAD ;;AN000;; MOV BYTE PTR $M_RT.$M_TEMP_BUF[BX],AL ;;AN000;; Move in a pad char INC BX ;;AN000;; CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? ; $IF E ;;AN000;; Yes, JNE $MIF281 CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer ; $ENDIF ;;AN000;; $MIF281: DEC DH ;;AN000;; Have we filled with enough pad chars? ; $ENDDO Z ;;AN000;; No, next pad character JNZ $MDO280 ; $ENDIF ;;AN000;; $MIF279: ; $ENDIF ;;AN000;; Yes, $MIF278: ;; CMP BYTE PTR $M_SL.$M_S_MAXW,$M_UNLIM_W ;;AN000;; Is maximum width unlimited? ; $IF NE ;;AN000;; JE $MIF286 CMP BYTE PTR $M_SL.$M_S_MAXW,CL ;;AN000;; Will we exceed maximum width? ; $IF B ;;AN000;; Yes, JNB $MIF287 SUB CL,BYTE PTR $M_SL.$M_S_MAXW ;;AN000;; Calculate how many extra chars MOV DL,CL ;;AN000;; Remember how many chars to pop off MOV CL,BYTE PTR $M_SL.$M_S_MAXW ;;AN000;; Set new string length ; $ENDIF ;;AN000;; $MIF287: ; $ENDIF ;;AN000;; $MIF286: OR CX,CX ;;AN000;; ; $IF NZ ;;AN000;; JZ $MIF290 ; $DO ;;AN000;; Begin filling buffer with string $MDO291: TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Char_Type AND $M_TYPE_MASK ;;AN000;; ; $IF Z,AND ;;AN000;; JNZ $MIF292 TEST $M_SL.$M_S_FLAG,Char_field_ASCIIZ AND $M_SIZE_MASK ; Is this replace a ASCIIZ string? ; $IF NZ ;;AN000;; Yes, JZ $MIF292 MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get first character from string INC DI ;;AN000;; Next character in string ; $ELSE ;;AN000;; No, JMP SHORT $MEN292 $MIF292: POP AX ;;AN000;; Get character in register ; $ENDIF ;;AN000;; $MEN292: MOV BYTE PTR $M_RT.$M_TEMP_BUF[BX],AL ;;AN000;; Move char into the buffer INC BX ;;AN000;; Increase buffer count CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? ; $IF E ;;AN000;; Yes, JNE $MIF295 CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer ; $ENDIF ;;AN000;; $MIF295: DEC CL ;;AN000;; Have we completed replace? ; $ENDDO Z ;;AN000;; Test again JNZ $MDO291 ; $ENDIF ;;AN000;; $MIF290: ;; TEST BYTE PTR $M_SL.$M_S_FLAG,Right_Align ;;AN000;; Was replaceable parm to be left aligned? ; $IF Z ;;AN000;; Yes, JNZ $MIF299 OR DH,DH ;;AN000;; Do we need pad chars added? ; $IF NZ ;;AN000;; Yes, JZ $MIF300 ; $DO ;;AN000;; Begin filling buffer with pad chars $MDO301: MOV AL,BYTE PTR $M_SL.$M_S_PAD ;;AN000;; MOV BYTE PTR $M_RT.$M_TEMP_BUF[BX],AL ;;AN000;; Move in a pad char INC BX ;;AN000;; CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? ; $IF E ;;AN000;; Yes, JNE $MIF302 CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer ; $ENDIF ;;AN000;; $MIF302: DEC DH ;;AN000;; Have we filled with enough pad chars? ; $ENDDO Z ;;AN000;; Test again JNZ $MDO301 ; $ENDIF ;;AN000;; $MIF300: ; $ENDIF ;;AN000;; $MIF299: ;; TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Char_Type AND $M_TYPE_MASK ;;AN000;; ; $IF Z,AND ;;AN000;; JNZ $MIF307 TEST $M_SL.$M_S_FLAG,Char_field_ASCIIZ AND $M_SIZE_MASK ;;AN000;; Is this replace a ASCIIZ string? ; $IF NZ ;;AN000;; Yes, JZ $MIF307 ; $ELSE ;;AN000;; JMP SHORT $MEN307 $MIF307: OR DL,DL ;;AN000;; ; $IF NE ;;AN000;; JE $MIF309 ; $DO ;;AN000;; $MDO310: POP [$M_RT.$M_RETURN_ADDR] ;;AN000;; Clean Up stack using spare variable DEC DL ;;AN000;; Are we done? ; $ENDDO Z ;;AN000;; JNZ $MDO310 ; $ENDIF ;;AN000;; $MIF309: ; $ENDIF ;;AN000;; $MEN307: CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer for the final time PUSH BP ;;AN000;; Restore the return address ;; RET ;;AN000;; ;; $M_DISPLAY_REPLACE ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_FLUSH_BUFFER ;; ;; FUNCTION: Display the contents of the temporary buffer ;; INPUTS: DI contains the number of bytes to display ;; OUTPUTS: BX reset to zero ;; ;; REGS USED: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_FLUSH_BUF PROC NEAR ;;AN000;; ;; PUSH CX ;;AN000;; Save changed regs PUSH ES ;;AN000;; PUSH DI ;;AN000;; PUSH DS ;;AN000;; Set ES pointing to buffer POP ES ;;AN000;; ;; MOV CX,BX ;;AN000;; Set number of bytes to display XOR BX,BX ;;AN000;; Reset buffer counter LEA DI,$M_RT.$M_TEMP_BUF ;;AN000;; Reset buffer location pointer CALL $M_DISPLAY_STRING ;;AN000;; Display the buffer ;; ; $IF NC ;;AN000;; Error? JC $MIF314 POP DI ;;AN000;; No, Restore changed regs POP ES ;;AN000;; POP CX ;;AN000;; ; $ELSE ;;AN000;; Yes, JMP SHORT $MEN314 $MIF314: ADD SP,6 ;;AN000;; Fix stack STC ;;AN000;; ; $ENDIF ;;AN000;; Error? $MEN314: ;; RET ;;AN000;; Return ;; $M_FLUSH_BUF ENDP ;;AN000;; ;; ;; IF CHARmsg ;;AN000;; Is the request to include the code for CHAR replace? $M_REPLACE = TRUE ;;AN000;; Yes, THEN include it and flag that we will need common $M_CHAR_ONLY = TRUE ;;AN000;; replacement code later ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_CHAR_REPLACE ;; ;; FUNCTION: Will prepare a single char or ASCIIZ string for replace ;; INPUTS: DS:SI points at corresponding SUBLIST ;; ES:DI contains the VALUE from SUBLIST ;; OUTPUTS: CX contains number of characters on stack ;; Top of stack --> Last character ;; . . . ;; Bot of stack --> First character ;; ;; OTHER REGS Revised: AX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_CHAR_REPLACE PROC NEAR ;;AN000;; ;; POP BP ;;AN000;; Save return address TEST $M_SL.$M_S_FLAG,NOT Char_Field_Char AND $M_SIZE_MASK ;;AN000;; Was Character specified? ; $IF Z ;;AN000;; Yes, JNZ $MIF317 MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get the character PUSH AX ;;AN000;; Put it on the stack INC CX ;;AN000;; Increase the count CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character ; $IF C ;;AN000;; Yes, JNC $MIF318 MOV AL,BYTE PTR ES:[DI]+1 ;;AN000;; Get the next character PUSH AX ;;AN000;; Put it on the stack CLC ;;AN000;; Clear the carry ; $ENDIF ;;AN000;; $MIF318: ; $ELSE ;;AN000;; No, it was an ASCIIZ string JMP SHORT $MEN317 $MIF317: ; $DO ;;AN000;; $MDO321: MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get the character OR AL,AL ;;AN000;; Is it the NULL? ; $LEAVE Z ;;AN000;; No, JZ $MEN321 INC DI ;;AN000;; Next character INC CX ;;AN000;; Increment the count ; $ENDDO ;;AN000;; Yes, JMP SHORT $MDO321 $MEN321: SUB DI,CX ;;AN000;; Set SI at the beginning of the string ; $ENDIF ;;AN000;; $MEN317: ;;AN000;; PUSH BP ;;AN000;; Restore return address RET ;;AN000;; Return ;; $M_CHAR_REPLACE ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;;AN000;; END of include of CHAR replace code ; IF NUMmsg ;;AN000;; Is the request to include the code for NUM replace? $M_REPLACE = TRUE ;;AN000;; Yes, THEN include it and flag that we will need common $M_CHAR_ONLY = FALSE ;;AN000;; replacement code later ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_BIN2ASC_REPLACE ;; ;; FUNCTION: Convert a signed or unsigned binary number to an ASCII string ;; and prepare to display ;; INPUTS: DS:SI points at corresponding SUBLIST ;; ES:DI contains the VALUE from SUBLIST ;; OUTPUTS: CX contains number of characters on stack ;; Top of stack --> Last character ;; . . . ;; Bot of stack --> First character ;; OTHER REGS Revised: BX,DX,AX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_BIN2ASC_REPLACE PROC NEAR ;;AN000;; ;; POP BP ;;AN000;; Save return address ;; XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) XOR AX,AX ;;AN000;; Prepare for get binary value (LOW) MOV $M_RT.$M_DIVISOR,$M_BASE16 ;;AN000;; Set default divisor XOR BX,BX ;;AN000;; Use BP as the NEG flag (if applicable) IF NOT COMR TEST $M_SL.$M_S_FLAG,NOT $M_BYTE AND $M_SIZE_MASK ;;AN000;; Was BYTE specified? ; $IF Z ;;AN000;; JNZ $MIF325 MOV AL, BYTE PTR ES:[DI] ;;AN000;; Setup byte in AL TEST $M_SL.$M_S_FLAG,NOT Sgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; Was Signed binary specified? ; $IF Z ;;AN000;; JNZ $MIF326 TEST AL,10000000b ;;AN000;; Is this number negative? ; $IF NZ ;;AN000;; Yes, JZ $MIF327 INC BX ;;AN000;; Remember that it was negative AND AL,01111111b ;;AN000;; Make it positive ; $ENDIF ;;AN000;; $MIF327: MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; ; $ENDIF ;;AN000;; $MIF326: TEST $M_SL.$M_S_FLAG,NOT Unsgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; Was Signed binary specified? ; $IF Z ;;AN000;; JNZ $MIF330 MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; ; $ENDIF ;;AN000;; $MIF330: ; $ELSE ;;AN000;; JMP SHORT $MEN325 $MIF325: ENDIF TEST $M_SL.$M_S_FLAG,NOT $M_WORD AND $M_SIZE_MASK ;;AN000;; Was WORD specified? ; $IF Z ;;AN000;; JNZ $MIF333 MOV AX, WORD PTR ES:[DI] ;;AN000;; Setup byte in AL TEST $M_SL.$M_S_FLAG,NOT Sgn_Bin_Type AND $M_TYPE_MASK ;; AN000;; Was Signed binary specified? ; $IF Z ;;AN000;; JNZ $MIF334 TEST AH,10000000b ;;AN000;; Is this number negative? ; $IF NZ ;;AN000;; Yes, JZ $MIF335 INC BX ;;AN000;; Remember that it was negative AND AH,01111111b ;;AN000;; Make it positive ; $ENDIF ;;AN000;; $MIF335: MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; ; $ENDIF ;;AN000;; $MIF334: TEST $M_SL.$M_S_FLAG,NOT Unsgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; Was Signed binary specified? ; $IF Z ;;AN000;; JNZ $MIF338 MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; ; $ENDIF ;;AN000;; $MIF338: ; $ELSE ;;AN000;; JMP SHORT $MEN333 $MIF333: IF NOT COMR MOV AX, WORD PTR ES:[DI] ;;AN000;; Setup Double word in DX:AX MOV DX, WORD PTR ES:[DI]+2 ;;AN000;; TEST $M_SL.$M_S_FLAG,NOT Sgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; Was Signed binary specified? ; $IF Z ;;AN000;; JNZ $MIF341 TEST DH,10000000b ;;AN000;; Is this number negative? ; $IF NZ ;;AN000;; Yes, JZ $MIF342 INC BX ;;AN000;; Remember that it was negative AND DH,01111111b ;;AN000;; Make it positive ; $ENDIF ;;AN000;; $MIF342: MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; ; $ENDIF ;;AN000;; $MIF341: TEST $M_SL.$M_S_FLAG,NOT Unsgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; Was Signed binary specified? ; $IF Z ;;AN000;; JNZ $MIF345 MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; ; $ENDIF ;;AN000;; $MIF345: ENDIF ; $ENDIF ;;AN000;; $MEN333: ; $ENDIF ;;AN000;; $MEN325: ;; CALL $M_CONVERT2ASC ;;AN000;; Convert to ASCII string IF NOT COMR OR BX,BX ;;AN000;; ; $IF NZ ;;AN000;; Was number negative? JZ $MIF349 XOR DX,DX ;;AN000;; Yes, MOV DL,$M_NEG_SIGN ;;AN000;; Put "-" on the stack with the number PUSH DX ;;AN000;; ; $ENDIF ;;AN000;; No, $MIF349: ENDIF ;; PUSH BP ;;AN000;; Restore return address RET ;;AN000;; Return ;; $M_BIN2ASC_REPLACE ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;;AN000;; END of include of NUM replace code ; IF DATEmsg ;;AN000;; Is the request to include the code for DATE replace? $M_REPLACE = TRUE ;;AN000;; Yes, THEN include it and flag that we will need common $M_CHAR_ONLY = FALSE ;;AN000;; replacement code later ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_DATE_REPLACE ;; ;; FUNCTION: Convert a date to a decimal ASCII string using current ;; country format and prepare to display ;; INPUTS: DS:SI points at corresponding SUBLIST ;; ES:DI points at VALUE from SUBLIST ;; OUTPUTS: CX contains number of characters on stack ;; Top of stack --> Last character ;; . . . ;; Bot of stack --> First character ;; OTHER REGS Revised: DX, AX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_DATE_REPLACE PROC NEAR ;;AN000;; ;; POP BP ;;AN000;; Save return address MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; Set default divisor CALL $M_GET_DATE ;;AN000;; Set date format/separator in $M_RT ;;AN000;; All O.K.? XOR DX,DX ;;AN000;; Reset DX value XOR AX,AX ;;AN000;; Reset AX value CMP WORD PTR $M_RT.$M_DATE_FORMAT,0 ;;AN000;; USA Date Format ; $IF E ;;AN000;; Beginning from end: (saved on the stack) JNE $MIF351 CALL $M_YEAR ;;AN000;; Get Year CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;; INC CX ;;AN000;; Increment count XOR AX,AX ;;AN000;; Reset AX value MOV AL,BYTE PTR $M_SL.$M_S_VALUE+3 ;;AN000;; Get Day CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;; INC CX ;;AN000;; Increment count MOV AL,BYTE PTR $M_SL.$M_S_VALUE+2 ;;AN000;; Get Month CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string ; $ENDIF ;;AN000;; $MIF351: ;; CMP WORD PTR $M_RT.$M_DATE_FORMAT,1 ;;AN000;; EUROPE Date Format ; $IF E ;;AN000;; Beginning from end: (saved on the stack) JNE $MIF353 CALL $M_YEAR ;;AN000;; Get Year CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;; INC CX ;;AN000;; XOR AX,AX ;;AN000;; Reset AX MOV AL,BYTE PTR $M_SL.$M_S_VALUE+2 ;;AN000;; Get Month CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;; INC CX ;;AN000;; MOV AL,BYTE PTR $M_SL.$M_S_VALUE+3 ;;AN000;; Get Day CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string ; $ENDIF ;;AN000;; $MIF353: ;; CMP WORD PTR $M_RT.$M_DATE_FORMAT,2 ;;AN000;; JAPAN Date Format ; $IF E ;;AN000;; Beginning from end: (saved on the stack) JNE $MIF355 MOV AL,BYTE PTR $M_SL.$M_S_VALUE+3 ;;AN000;; Get Day CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;; INC CX ;;AN000;; MOV AL,BYTE PTR $M_SL.$M_S_VALUE+2 ;;AN000;; Get Month CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;; INC CX ;;AN000;; CALL $M_YEAR ;;AN000;; Get Year CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string ; $ENDIF ;;AN000;; $MIF355: ;; PUSH BP ;;AN000;; Restore return address RET ;;AN000;; Return ;; $M_DATE_REPLACE ENDP ;;AN000;; ;; $M_GET_DATE PROC NEAR ;;AN000;; MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info MOV AL,0 ;;AN000;; Get current country info LEA DX,$M_RT.$M_TEMP_BUF ;;AN000;; Set up addressibility to buffer INT 21H ;;AN000;; ; $IF C ;;AN000;; No, JNC $MIF357 MOV WORD PTR $M_RT.$M_DATE_FORMAT,$M_DEF_DATE_FORM ;;AN000;; Set default date format (BH) MOV BYTE PTR $M_RT.$M_DATE_SEPARA,$M_DEF_DATE_SEP ;;AN000;; Set default date separator (BL) ; $ENDIF ;;AN000;; $MIF357: RET ;;AN000;; $M_GET_DATE ENDP ;;AN000;; ;; $M_YEAR PROC NEAR ;;AN000;; MOV AX,WORD PTR $M_SL.$M_S_VALUE ;;AN000;; Get Year TEST $M_SL.$M_S_FLAG,Date_MDY_4 AND $M_DATE_MASK ;;AN000;; Was Month/Day/Year (2 Digits) specified? ; $IF Z ;;AN000;; JNZ $MIF359 CMP AX,$M_MAX_2_YEAR ;;AN000;; Get Year ; $IF A ;;AN000;; JNA $MIF360 MOV AX,$M_MAX_2_YEAR ;;AN000;; ; $ENDIF ;;AN000;; $MIF360: ; $ENDIF ;;AN000;; $MIF359: RET ;;AN000;; $M_YEAR ENDP ;;AN000;; ;; $M_CONVERTDATE PROC NEAR ;;AN000;; POP WORD PTR $M_RT.$M_TEMP_BUF ;;AN000;; Save return address MOV $M_RT.$M_SIZE,CL ;;AN000;; Save the size before conversion CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string DEC CX ;;AN000;; Test if size only grew by 1 CMP CL,$M_RT.$M_SIZE ;;AN000;; Did size only grow by one ; $IF E ;;AN000;; Yes, JNE $MIF363 MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) PUSH AX ;;AN000;; Save it INC CX ;;AN000;; Count it ; $ENDIF ;;AN000;; $MIF363: INC CX ;;AN000;; Restore CX PUSH WORD PTR $M_RT.$M_TEMP_BUF ;;AN000;; Save return address RET ;;AN000;; $M_CONVERTDATE ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;;AN000;; END of include of DATE replace code ; IF TIMEmsg ;;AN000;; Is the request to include the code for TIME replace? $M_REPLACE = TRUE ;;AN000;; Yes, THEN include it and flag that we will need common $M_CHAR_ONLY = FALSE ;;AN000;; replacement code later ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_TIME_REPLACE ;; ;; FUNCTION: Convert a time to a decimal ASCII string ;; and prepare to display ;; INPUTS: DS:SI points at corresponding SUBLIST ;; ES:DI points at VALUE from SUBLIST ;; OUTPUTS: CX contains number of characters on stack ;; Top of stack --> Last character ;; . . . ;; Bot of stack --> First character ;; REGS USED: BP,CX,AX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_TIME_REPLACE PROC NEAR ;;AN000;; ;; POP BP ;;AN000;; Save return address MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; Set default divisor CALL $M_GET_TIME ;;AN000;; All O.K.? TEST $M_SL.$M_S_FLAG,Time_Cty_Type AND $M_TIME_MASK ;;AN000;; Is this a request for current country info? ; $IF NZ ;;AN000;; Yes, JZ $MIF365 CMP BYTE PTR $M_RT.$M_TIME_FORMAT,0 ;;AN000;; Is the current country format 12 Hour? ; $IF E ;;AN000;; Yes, JNE $MIF366 MOV AL,BYTE PTR $M_SL.$M_S_VALUE ;;AN000;; Get Hours CMP AL,12 ;;AN000;; Is hour 12 or less? ; $IF L,OR ;;AN000;; or JL $MLL367 CMP AL,23 ;;AN000;; Is hour 24 or greater? ; $IF G ;;AN000;; Yes, JNG $MIF367 $MLL367: MOV AL,$M_AM ;;AN000;; PUSH AX ;;AN000;; Push an "a" to represent AM. INC CX ;;AN000;; ; $ELSE ;;AN000;; No, JMP SHORT $MEN367 $MIF367: MOV AL,$M_PM ;;AN000;; PUSH AX ;;AN000;; Push an "p" to represent PM. INC CX ;;AN000;; ; $ENDIF ;;AN000;; $MEN367: ; $ENDIF ;;AN000;; $MIF366: ; $ENDIF ;;AN000;; $MIF365: ;; XOR AX,AX ;;AN000;; XOR DX,DX ;;AN000;; TEST $M_SL.$M_S_FLAG,Time_HHMMSSHH_Cty AND $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? ; $IF NZ ;;AN000;; JZ $MIF372 MOV AL,BYTE PTR $M_SL.$M_S_VALUE+3 ;;AN000;; Get Hundreds CALL $M_CONVERTTIME ;;AN000;; PUSH WORD PTR $M_RT.$M_DECI_SEPARA ;;AN000;; INC CX ;;AN000;; ; $ENDIF ;;AN000;; $MIF372: TEST $M_SL.$M_S_FLAG,Time_HHMMSSHH_Cty AND $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? ; $IF NZ,OR ;;AN000;; JNZ $MLL374 TEST $M_SL.$M_S_FLAG,Time_HHMMSS_Cty AND $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec (12 Hour) specified? ; $IF NZ ;;AN000;; JZ $MIF374 $MLL374: MOV AL,BYTE PTR $M_SL.$M_S_VALUE+2 ;;AN000;; Get Seconds CALL $M_CONVERTTIME ;;AN000;; PUSH WORD PTR $M_RT.$M_TIME_SEPARA ;;AN000;; INC CX ;;AN000;; ; $ENDIF ;;AN000;; $MIF374: ;; Do Hour/Min (12 Hour) MOV AL,BYTE PTR $M_SL.$M_S_VALUE+1 ;;AN000;; Get Minutes CALL $M_CONVERTTIME ;;AN000;; PUSH WORD PTR $M_RT.$M_TIME_SEPARA ;;AN000;; INC CX ;;AN000;; ;; MOV AL,BYTE PTR $M_SL.$M_S_VALUE ;;AN000;; Get Hours TEST $M_SL.$M_S_FLAG,Time_Cty_Type AND $M_TIME_MASK ;;AN000;; Is this a request for current country info? ; $IF NZ ;;AN000;; Yes, JZ $MIF376 CMP BYTE PTR $M_RT.$M_TIME_FORMAT,0 ;;AN000;; Is the current country format 12 Hour? ; $IF E ;;AN000;; Yes, JNE $MIF377 CMP AL,13 ;;AN000;; Is hour less than 12? ; $IF GE ;;AN000;; Yes, JNGE $MIF378 SUB AL,12 ;;AN000;; Set to a 12 hour value ; $ENDIF ;;AN000;; $MIF378: CMP AL,0 ;;AN000;; Is hour less than 12? ; $IF E ;;AN000;; Yes, JNE $MIF380 MOV AL,12 ;;AN000;; Set to a 12 hour value ; $ENDIF ;;AN000;; $MIF380: ; $ENDIF ;;AN000;; $MIF377: ; $ENDIF ;;AN000;; $MIF376: CALL $M_CONVERT2ASC ;;AN000;; Convert it to ASCII ;; PUSH BP ;;AN000;; Restore return address RET ;;AN000;; Return ;; $M_TIME_REPLACE ENDP ;;AN000;; ;; $M_GET_TIME PROC NEAR ;;AN000;; MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info MOV AL,0 ;;AN000;; Get current country info LEA DX,$M_RT.$M_TEMP_BUF ;;AN000;; Set up addressibility to buffer INT 21H ;;AN000;; ; $IF C ;;AN000;; No, JNC $MIF384 MOV WORD PTR $M_RT.$M_TIME_FORMAT,$M_DEF_TIME_FORM ;;AN000;; Set default time format (BH) MOV BYTE PTR $M_RT.$M_TIME_SEPARA,$M_DEF_TIME_SEP ;;AN000;; Set default time separator (BL) MOV BYTE PTR $M_RT.$M_DECI_SEPARA,$M_DEF_DECI_SEP ;;AN000;; Set default time separator (BL) ; $ENDIF ;;AN000;; $MIF384: RET ;;AN000;; $M_GET_TIME ENDP ;;AN000;; ;; $M_CONVERTTIME PROC NEAR ;;AN000;; POP WORD PTR $M_RT.$M_TEMP_BUF ;;AN000;; Save return address MOV $M_RT.$M_SIZE,CL ;;AN000;; Save the size before conversion CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string DEC CX ;;AN000;; Test if size only grew by 1 CMP CL,$M_RT.$M_SIZE ;;AN000;; Did size only grow by one ; $IF E ;;AN000;; Yes, JNE $MIF386 MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) PUSH AX ;;AN000;; Save it INC CX ;;AN000;; Count it ; $ENDIF ;;AN000;; $MIF386: INC CX ;;AN000;; Restore CX PUSH WORD PTR $M_RT.$M_TEMP_BUF ;;AN000;; Save return address RET ;;AN000;; $M_CONVERTTIME ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;;AN000;; END of include of TIME replace ENDIF ;;AN000;; END of include of Replacement common code ; IF INPUTmsg ;;AN000;; Is the request to include the code for NUM replace? INPUTmsg = FALSE ;;AN000;; Yes, THEN include it and reset the flag ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROC NAME: $M_WAIT_FOR_INPUT ;; ;; FUNCTION: To accept keyed input and return extended key value ;; in AX register ;; INPUTS: DL contains the DOS function requested for input ;; OUPUTS: AX contains the extended key value that was read ;; REGS USED: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $M_WAIT_FOR_INPUT PROC NEAR ;;AN000;; ;; PUSH CX ;;AN000;; Save CX PUSH DX ;;AN000;; Save DX PUSH DS ;;AN000;; Save Data segment ;; CMP DL,DOS_CLR_KEYB_BUF_MASK ;;AN001;; Are we to clear the keyboard buffer? ; $IF A ;;AN001;; Yes, JNA $MIF388 MOV AL,DL ;;AN001;; Mov function into AL AND AL,LOW_NIB_MASK ;;AN001;; Mask out the C in high nibble MOV AH,DOS_CLR_KEYB_BUF ;;AN001;; Set input function ; $ELSE ;;AN001;; No, JMP SHORT $MEN388 $MIF388: MOV AH,DL ;;AN000;; Put DOS function in AH ; $ENDIF ;;AN001;; $MEN388: PUSH ES ;;AN000;; Get output buffer segment POP DS ;;AN000;; MOV DX,DI ;;AN000;; Get output buffer offset in case needed INT 21H ;;AN000;; Get keyboard input POP DS ;;AN000;; CMP DL,DOS_BUF_KEYB_INP ;;AN000;; CLC ;;AN000;; ; $IF NE ;;AN000;; If character input JE $MIF391 CALL $M_IS_IT_DBCS ;;AN000;; Is this character DBCS? ; $IF C ;;AN000;; JNC $MIF392 MOV CL,AL ;;AN000;; Save first character MOV AH,DL ;;AN001;; Get back function INT 21H ;;AN000;; Get keyboard input MOV AH,CL ;;AN000;; Retreive first character AX = xxxx CLC ;;AN000;; Clear carry condition ; $ELSE ;;AN000;; JMP SHORT $MEN392 $MIF392: MOV AH,0 ;;AN000;; AX = 00xx where xx is SBCS ; $ENDIF ;;AN000;; $MEN392: ; $ENDIF ;;AN000;; $MIF391: ;; ; $IF NC ;;AN000;; JC $MIF396 POP DX ;;AN000;; POP CX ;;AN000;; ; $ELSE ;;AN000;; JMP SHORT $MEN396 $MIF396: ADD SP,4 ;;AN000;; STC ;;AN000;; Reset carry flag ; $ENDIF ;;AN000;; $MEN396: RET ;;AN000;; Return ;; $M_WAIT_FOR_INPUT ENDP ;;AN000;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ENDIF ;;AN000;; END of include of Wait for Input ENDIF ;;AN000;; END of include of SYSDISPMSG ENDIF ;;AN000;; END of include of MSG_DATA_ONLY ENDIF ;;AN000;; END of include of Structure only