windows-nt/Source/XPSP1/NT/base/mvdm/dos/v86/inc/msgserv.asm

3372 lines
121 KiB
NASM
Raw Permalink Normal View History

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