; * * * * * * * * * * * * 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 $M_NUM_CLS_MSG DB 0 ;;AN000;; Total number of message in class ;; $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 XOR AH,AH ;;AN003;; Get number of messages in class MOV AL,DS:[DI].$M_NUM_CLS_MSG ;;AN003;; 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;; ;; 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 MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG ;;AN001;; Get number of messages in class ; $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;; MOV CL,BYTE PTR ES:[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 ;;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 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;; ;; 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 MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG ;;AN001;; Get number of messages in class ; $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;; MOV CL,BYTE PTR ES:[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 ;;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 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