1 ; * * * * * * * * * * * * START OF SPECIFICATIONS * * * * * * * * * * * * * * *
3 ; MODULE NAME: MSGSERV.SAL
5 ; DESCRIPTIVE NAME: Message Services SALUT file
7 ; FUNCTION: This module incorporates all the messages services and
8 ; is called upon at build time to INCLUDE the code requested
9 ; by a utility. Code is requested using the macro MSG_SERVICES.
11 ; ENTRY POINT: Since this a collection of subroutines, entry point is at
12 ; requested procedure.
14 ; INPUT: Since this a collection of subroutines, input is dependent on function
17 ; EXIT-NORMAL: In all cases, CARRY FLAG = 0
19 ; EXIT-ERROR: In all cases, CARRY FLAG = 1
21 ; INTERNAL REFERENCES: (list of included subroutines)
28 ; EXTERNAL REFERENCES: None
30 ; NOTES: At build time, some modules must be included. These are only included
31 ; once using assembler switches. Other logic is included at the request
34 ; COMR and COMT are assembler switches to conditionally assemble code
35 ; for RESIDENT COMMAND.COM and TRANSIENT COMMAND.COM to reduce resident
36 ; storage and multiple EQUates.
38 ; REVISION HISTORY: Created MAY 1987
40 ; Label: DOS - - Message Retriever
41 ; (c) Copyright 1988 Microsoft
44 ; * * * * * * * * * * * * END OF SPECIFICATIONS * * * * * * * * * * * * * * * *
47 ; $SALUT $M (2,5,22,62) ;;AN000;; Set SALUT formatting
49 IF $M_STRUC
;;AN000;; IF we haven't included the structures yet THEN
50 $M_STRUC
= FALSE
;;AN000;; Let the assembler know that we have
51 ;;AN000;; and include them
54 SUBTTL DOS
- Message Retriever
- MSGSTR
.INC Module
55 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
57 ;; STRUCTURE: $M_SUBLIST_STRUC
59 ;; Replacable parameters are described by a sublist structure
61 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
63 $M_SUBLIST_STRUC
STRUC ;;AN000;;
65 $M_S_SIZE
DB 11 ;;AN000;; SUBLIST size (PTR to next SUBLIST)
66 $M_S_RESV
DB 0 ;;AN000;; RESERVED
67 $M_S_VALUE
DD ?
;;AN000;; Time, Date or PTR to data item
68 $M_S_ID
DB ?
;;AN000;; n of %n
69 $M_S_FLAG
DB ?
;;AN000;; Data-type flags
70 $M_S_MAXW
DB ?
;;AN000;; Maximum field width
71 $M_S_MINW
DB ?
;;AN000;; Minimum field width
72 $M_S_PAD
DB ?
;;AN000;; Character for Pad field
74 $M_SUBLIST_STRUC ENDS
;;AN000;;
76 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
78 ;; STRUCTURE: $M_CLASS_ID
80 ;; Each class will be defined by this structure.
82 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
84 $M_CLASS_ID
STRUC ;;AN000;;
86 $M_CLS_ID
DB -1 ;;AN000;; Class identifer
87 $M_COMMAND_VER
DW EXPECTED_VERSION
;;AN003;; COMMAND.COM version check
88 $M_NUM_CLS_MSG
DB 0 ;;AN000;; Total number of message in class
92 $M_CLASS_ID_SZ EQU TYPE $M_CLASS_ID
;;AN000;;
94 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
96 ;; STRUCTURE: $M_ID_STRUC
98 ;; Each message will be defined by this structure.
100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
102 $M_ID
STRUC ;;AN000;;
104 $M_NUM
DW -1 ;;AN000;; Message Number
105 $M_TXT_PTR
DW ?
;;AN000;; Pointer to message text
108 ;;AN000;; Status Flag Values:
109 $M_ID_SZ EQU TYPE $M_ID
;;AN000;;
111 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
113 ;; STRUCTURE: $M_RES_ADDRS
115 ;; Resident data area definition of variables
117 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
119 $M_RES_ADDRS
STRUC ;;AN000;;
121 $M_EXT_ERR_ADDRS
DD 0 ;;AN000;; Allow pointers to THREE Extended error locations
122 $M_EXT_FILE
DD 0 ;;AN001;;
123 $M_EXT_COMMAND
DD 0 ;;AN000;;
124 $M_EXT_TERM
DD -1 ;;AN000;;
125 $M_PARSE_COMMAND
DD 0 ;;AN000;;
126 $M_PARSE_ADDRS
DD 0 ;;AN000;; Allow pointers to TWO Parse error locations
127 $M_PARSE_TERM
DD -1 ;;AN000;;
128 $M_CRIT_ADDRS
DD 0 ;;AN000;; Allow pointers to TWO Critical error locations
129 $M_CRIT_COMMAND
DD 0 ;;AN000;;
130 $M_CRIT_TERM
DD -1 ;;AN000;;
131 $M_DISK_PROC_ADDR
DD -1 ;;AN004;; Address of READ_DISK_PROC
132 $M_CLASS_ADDRS
DD $M_NUM_CLS
DUP(0) ;;AN000;; Allow pointers to specified classes
133 $M_CLS_TERM
DD -1 ;;AN000;;
134 $M_DBCS_VEC
DD 0 ;;AN000;; Save DBCS vector
135 $M_HANDLE
DW ?
;;AN000;;
136 $M_SIZE
DB 0 ;;AN000;;
137 $M_CRLF
DB 0DH,0AH ;;AN004;; CR LF message
138 $M_CLASS
DB ?
;;AN004;; Saved class
139 $M_RETURN_ADDR
DW ?
;;AN000;;
140 $M_MSG_NUM
DW $M_NULL
;;AN000;;
141 $M_DIVISOR
DW 10 ;;AN000;; Default = 10 (must be a WORD for division)
142 $M_TEMP_BUF
DB $M_TEMP_BUF_SZ
DUP("$") ;;AN000;; Temporary buffer
143 $M_BUF_TERM
DB "$" ;;AN000;;
145 $M_RES_ADDRS ENDS
;;AN000;;
147 $M_RES_ADDRS_SZ EQU TYPE $M_RES_ADDRS
;;AN000;;
149 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
151 ;; STRUCTURE: $M_COUNTRY_INFO
153 ;; Important fields of the Get Country Information call
155 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
157 $M_COUNTRY_INFO
STRUC ;;AN000;; Expected Country infomation
159 $M_HEADER
DB $M_RES_ADDRS_SZ
-$M_TEMP_BUF_SZ
-1 DUP(?
) ;;AN000;; Go past first part of struc
160 $M_DATE_FORMAT
DW ?
;;AN000;; <------- Date Format
161 $M_CURR_SEPARA
DB 5 DUP(?
) ;;AN000;;
162 $M_THOU_SEPARA
DB ?
,0 ;;AN000;; <------- Thou Separator
163 $M_DECI_SEPARA
DB ?
,0 ;;AN000;; <------- Decimal Separator
164 $M_DATE_SEPARA
DB ?
,0 ;;AN000;; <------- Date Separator
165 $M_TIME_SEPARA
DB ?
,0 ;;AN000;; <------- Time Separator
166 $M_CURR_FORMAT
DB ?
;;AN000;;
167 $M_SIG_DIGS_CU
DB ?
;;AN000;;
168 $M_TIME_FORMAT
DB ?
;;AN000;; <------- Time Format
170 $M_COUNTRY_INFO ENDS
;;AN000;;
171 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
173 ELSE ;;AN000;; ELSE if we have already included the STRUCTURES
175 ; $SALUT $M (2,5,13,62) ;;AN000;; Set SALUT formatting for code section
177 IF MSGDATA
;;AN000;; IF this is a request to include the data area
178 MSGDATA
= FALSE
;;AN000;; Let the assembler know not to include it again
179 ;;AN000;; and include it
181 SUBTTL DOS
- Message Retriever
- MSGRES
.TAB Module
182 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
184 ;; DATA NAME: $M_RES_TABLE
186 ;; REFERENCE LABEL: $M_RT
188 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
190 IF COMR
;;AN000;; Since COMMAND.COM includes this twice
191 $M_RT EQU $M_RT2
;;AN000;; we must redefine the label so no
192 $M_RT2
LABEL BYTE ;;AN000;; assembly errors occur
193 $M_ALTLABEL
= TRUE
;;AN000;; Flag that label was changed
195 $M_RT
LABEL BYTE ;;AN000;;
197 $M_RES_ADDRS
<> ;;AN000;; Resident addresses
199 include COPYRIGH
.INC ;;AN001;; Include Copyright 1988 Microsoft
201 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
202 ENDIF
;;AN000;; END of include of Data table
205 IF NOT $M_MSGDATA_ONLY
;;AN000;; IF this was a request for only the data table THEN
206 ;; don't include any more code
207 ;;AN000;; Figure out what other code to include
208 IF DISK_PROC
;;AN003;; Is the request to include the READ_DISK code
209 IF COMR
;;AN003;; (Only Resident COMMAND.COM should ask for it)
210 $M_RT EQU $M_RT2
;;AN003;;
212 DISK_PROC
= FALSE
;;AN003;; Yes, THEN include it and reset flag
214 SUBTTL DOS
- Message Retriever
- DISK_PROC Module
215 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
217 ;; PROC NAME: DISK_PROC
219 ;; FUNCTION: Used in COMMAND.COM if we need to access the Parse or Extended
220 ;; errors from disk\diskette
221 ;; INPUTS: AX has the message number
222 ;; DX has the message class
223 ;; AND ... the COMMAND.COM Variable RESGROUP:COMSPEC is
224 ;; assumed to be set!!
226 ;; OUTPUTS: ES:DI points to message length (BYTE) followed by text
229 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
231 PUBLIC READ_DISK_PROC
;;
233 READ_DISK_PROC PROC
FAR ;;AN003;;
235 PUSH AX ;;AN003;; Save everything
242 MOV BP,AX ;;AN003;; Save message number
243 MOV AX,DOS_EXTENDED_OPEN
;;AN003;; Set INT 21 function
244 LEA SI,RESGROUP
:COMSPEC
;;AN003;; Get addressibilty to COMMAND.COM
247 MOV DI,-1 ;;AN003;; No extended attribute list
248 MOV BX,NO_CRIT_OPEN
;;AN003;; Don't generate critical error
249 MOV DX,NOT_EX_FAIL_EX_OPEN
;;AN003;; Open Flag
250 INT 21H
;;AN003;; Open the file
251 POP DI ;;AN003;; Retreive LSEEK pointer
253 ; $IF NC,LONG ;;AN003;; No,
257 PUSH DI ;;AN003;; Save LSEEK pointer
258 MOV BX,AX ;;AN003;; Set handle in BX
259 MOV AX,DOS_LSEEK_FILE
;;AN003;; LSEEK to the errors
260 XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM
262 INT 21H
;;AN003;; LSEEK the file
263 POP DX ;;AN003;; Retreive LSEEK pointer
265 ; $IF NC ;;AN003;; No,
267 INC CX ;;AN003;; Set flag to first pass
270 PUSH DX ;;AN003;; Save LSEEK pointer
271 PUSH CX ;;AN003;; Save first pass flag
272 PUSH AX ;;AN003;; Save number of messages (if set yet)
273 XOR SI,SI ;;AN003;; Reset buffer index
274 MOV AH,DOS_READ_BYTE
;;AN003;; Read
275 MOV CX,$M_TEMP_BUF_SZ
;;AN003;; the first part of the header
276 LEA DX,$M_RT
.$M_TEMP_BUF
;;AN003;; into the temp buffer
277 INT 21H
;;AN003;; Read it
284 XOR CX,CX ;;AN003;; Set flag to second pass
285 XOR AH,AH ;;AN003;; Get number of messages in class
286 MOV AL,DS:[DI].$M_NUM_CLS_MSG
;;AN003;;
287 MOV SI,$M_CLASS_ID_SZ
;;AN003;; Initialize index
288 CMP DS:[DI].$M_COMMAND_VER
,EXPECTED_VERSION
;;AN003;; Is this the right version of COMMAND.COM?
292 ; $IF Z ;;AN003;; Yes,
296 CMP BP,WORD PTR $M_RT
.$M_TEMP_BUF
[SI] ;;AN003;; Is this the message I'm looking for?
297 ; $EXITIF Z ;;AN003;; Yes, (ZF=1)
299 CLC ;;AN003;; Reset carry, exit search
300 ; $ORELSE ;;AN003;; No, (ZF=0)
303 ADD SI,$M_ID_SZ
;;AN003;; Increment index
304 ADD DX,$M_ID_SZ
;;AN003;; Add offset of first header
305 DEC AX ;;AN003;; Decrement # of messages left
306 ; $LEAVE Z ;;AN003;; Have we exhausted all messages?
308 CMP SI,$M_TEMP_BUF_SZ
-1 ;;AN003;; No, Have we exhausted the buffer?
309 ; $ENDLOOP A ;;AN003;; No, Check next message (ZF=1)
312 STC ;;AN003;; Yes, (ZF=0) set error (ZF=0)
315 ; $ELSE ;;AN003;; No,
318 XOR CX,CX ;;AN003;; Set Zero flag to exit READ Loop
319 STC ;;AN003;; Set Carry
322 ; $ENDDO Z ;;AN003;; Get next buffer full if needed
325 ; $IF NC ;;AN003;; No,
327 MOV AX,DOS_LSEEK_FILE
;;AN003;; Prepare to LSEEK to the specific message
328 XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM
329 ADD DX,$M_CLASS_ID_SZ
;;AN003;; Add offset of first header
330 ADD DX,WORD PTR $M_RT
.$M_TEMP_BUF
[SI]+2 ;;AN003;; Add offset from msg structure
331 INT 21H
;;AN003;; LSEEK the file
332 MOV AH,DOS_READ_BYTE
;;AN003;; Read
333 MOV CX,$M_TEMP_BUF_SZ
;;AN003;; the message
334 LEA DX,$M_RT
.$M_TEMP_BUF
;;AN003;; into the temp buffer
335 INT 21H
;;AN003;; Read it
336 MOV DI,DX ;;AN003;; into the temp buffer
337 PUSH DS ;;AN003;; into the temp buffer
338 POP ES ;;AN003;; into the temp buffer
343 PUSHF ;;AN003;; Close file handle
344 MOV AH,DOS_CLOSE_FILE
;;AN003;; Close file handle
347 ; $ENDIF ;;AN003;; Yes there was an error,
355 ;;AN003;; abort everything
358 READ_DISK_PROC ENDP
;;AN003;;
359 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
360 ENDIF
;;AN003;; END of include for DISK_PROC
363 IF SETSTDIO
;;AN000;; Is the request to include the code for SETSTDIO
364 SETSTDIO
= FALSE
;;AN000;; Yes, THEN include it and reset flag
366 SUBTTL DOS
- Message Retriever
- SETSTDIO Module
367 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
369 ;; PROC NAME: SETSTDIO
377 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
380 SETSTDINON PROC
FAR ;AN001;
382 SETSTDINON PROC
NEAR ;AN001;
384 PUSH AX ;AN002; Save changed regs
387 MOV AX,DOS_IOCTL_GET_INFO
;AN001; Get info using IOCTL
392 OR DH,$M_CRIT_ERR_MASK
;AN001; Turn on bit
393 MOV AX,DOS_IOCTL_SET_INFO
;AN001; Set info using IOCTL
395 POP DX ;AN002; Restore Regs
401 SETSTDINON ENDP
;AN001;
404 SETSTDINOFF PROC
FAR ;AN001;
406 SETSTDINOFF PROC
NEAR ;AN001;
409 PUSH AX ;AN002; Save changed regs
412 MOV AX,DOS_IOCTL_GET_INFO
;AN001; Get info using IOCTL
417 AND DH,NOT $M_CRIT_ERR_MASK
;AN001; Turn off bit
418 MOV AX,DOS_IOCTL_SET_INFO
;AN001; Set info using IOCTL
420 POP DX ;AN002; Restore Regs
426 SETSTDINOFF ENDP
;AN001;
429 SETSTDOUTON PROC
FAR ;AN001;
431 SETSTDOUTON PROC
NEAR ;AN001;
434 PUSH AX ;AN002; Save changed regs
437 MOV AX,DOS_IOCTL_GET_INFO
;AN001; Get info using IOCTL
438 MOV BX,STDOUT
;AN001;
442 OR DH,$M_CRIT_ERR_MASK
;AN001; Turn on bit
443 MOV AX,DOS_IOCTL_SET_INFO
;AN001; Set info using IOCTL
445 POP DX ;AN002; Restore Regs
451 SETSTDOUTON ENDP
;AN001;
454 SETSTDOUTOFF PROC
FAR ;AN001;
456 SETSTDOUTOFF PROC
NEAR
459 PUSH AX ;AN002; Save changed regs
462 MOV AX,DOS_IOCTL_GET_INFO
;AN001; Get info using IOCTL
463 MOV BX,STDOUT
;AN001;
467 AND DH,NOT $M_CRIT_ERR_MASK
;AN001; Turn off bit
468 MOV AX,DOS_IOCTL_SET_INFO
;AN001; Set info using IOCTL
470 POP DX ;AN002; Restore Regs
476 SETSTDOUTOFF ENDP
;AN001;
477 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
478 ENDIF
;;AN000;; END of include for SETSTDIO
480 IF LOADmsg
;;AN000;; Is the request to include the code for SYSLOADMSG ?
482 $M_RT EQU $M_RT2
;;AN000;;
484 LOADmsg
= FALSE
;;AN000;; Yes, THEN include it and reset flag
486 SUBTTL DOS
- Message Retriever
- LOADMSG
.ASM Module
487 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
489 ;; PROC NAME: SYSLOADMSG
497 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
500 SYSLOADMSG PROC
FAR ;;AN000;;
502 SYSLOADMSG PROC
NEAR ;;AN000;;
509 XOR CX,CX ;;AN000; Reset to zero
512 MOV AX,DOS_GET_EXT_PARSE_ADD
;;AN000;; 2FH Interface
513 MOV DL,DOS_GET_EXTENDED
;;AN000;; Where are the Extended errors in COMMAND.COM
514 INT 2FH
;;AN000;; Private interface
515 MOV WORD PTR $M_RT
.$M_EXT_COMMAND
+2,ES ;;AN000;; Move into first avaliable table location
516 MOV WORD PTR $M_RT
.$M_EXT_COMMAND
,DI ;;AN000;;
518 MOV AX,DOS_GET_EXT_PARSE_ADD
;;AN000;; 2FH Interface
519 MOV DL,DOS_GET_PARSE
;;AN000;; Where are the Parse errors in COMMAND.COM
520 INT 2FH
;;AN000;; Private interface
521 MOV WORD PTR $M_RT
.$M_PARSE_COMMAND
+2,ES ;;AN000;; Move into first avaliable table location
522 MOV WORD PTR $M_RT
.$M_PARSE_COMMAND
,DI ;;AN000;;
524 MOV AX,DOS_GET_EXT_PARSE_ADD
;;AN000;; 2FH Interface
525 MOV DL,DOS_GET_CRITICAL
;;AN000;; Where are the Critical errors in COMMAND.COM
526 INT 2FH
;;AN000;; Private interface
527 MOV WORD PTR $M_RT
.$M_CRIT_COMMAND
+2,ES ;;AN000;; Move into first avaliable table location
528 MOV WORD PTR $M_RT
.$M_CRIT_COMMAND
,DI ;;AN000;;
530 MOV AX,DOS_GET_EXT_PARSE_ADD
;;AN001;; 2FH Interface
531 MOV DL,DOS_GET_FILE
;;AN001;; Where are the FILE dependant in IFSFUNC.EXE
532 INT 2FH
;;AN001;; Private interface
533 MOV WORD PTR $M_RT
.$M_EXT_FILE
+2,ES ;;AN001;; Move into first avaliable table location
534 MOV WORD PTR $M_RT
.$M_EXT_FILE
,DI ;;AN001;;
536 IF COMR
;; ** Special case for RESIDENT COMMAND.COM
538 IFNDEF READ_DISK_INFO
;;AN003;;
539 Extrn READ_DISK_PROC
:Far ;;AN003;;
544 CALL FAR PTR $M_MSGSERV_1
;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors)
546 CALL $M_MSGSERV_1
;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors)
548 MOV WORD PTR $M_RT
.$M_EXT_ERR_ADDRS
+2,ES ;;AN000;; Move into first avaliable table location
549 MOV WORD PTR $M_RT
.$M_EXT_ERR_ADDRS
,DI ;;AN000;;
550 MOV WORD PTR $M_RT
.$M_CRIT_ADDRS
+2,ES ;;AN000;; Move into first avaliable table location
551 MOV WORD PTR $M_RT
.$M_CRIT_ADDRS
,DI ;;AN000;;
554 CALL FAR PTR $M_MSGSERV_2
;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors)
556 CALL $M_MSGSERV_2
;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors)
558 MOV WORD PTR $M_RT
.$M_PARSE_ADDRS
+2,ES ;;AN000;; Move into first avaliable table location
559 MOV WORD PTR $M_RT
.$M_PARSE_ADDRS
,DI ;;AN000;;
562 MOV AX,DOS_GET_EXT_PARSE_ADD
;;AN001;; 2FH Interface
563 MOV DL,DOS_GET_ADDR
;;AN001;; Where is the READ_DISK_PROC in COMMAND.COM
564 INT 2FH
;;AN001;; Private interface
565 MOV WORD PTR $M_RT
.$M_DISK_PROC_ADDR
+2,ES ;;AN001;; Move into first avaliable table location
566 MOV WORD PTR $M_RT
.$M_DISK_PROC_ADDR
,DI ;;AN001;;
568 $M_BUILD_PTRS %$M_NUM_CLS
;;AN000;; Build all utility classes
570 CALL $M_GET_DBCS_VEC
;;AN000;; Save the DBCS vector
572 IF NOT NOCHECKSTDIN
;;AN000;; IF EOF check is not to be suppressed
573 CALL $M_CHECKSTDIN
;;AN000;; Set EOF CHECK
576 IF NOT NOCHECKSTDOUT
;;AN000;; IF Disk Full check is not to be suppressed
577 CALL $M_CHECKSTDOUT
;;AN000;; Set Disk Full CHECK
580 IF NOVERCHECKmsg
;;AN000;; IF version check is to be supressed
581 CLC ;;AN000;; Make sure carry is clear
584 CALL $M_VERSION_CHECK
;;AN000;; Check Version
587 ; $IF NC ;;AN000;; No.
589 IF NOT NOVERCHECKmsg
;;AN000;; IF version check was not supressed
590 POP CX ;;AN000;; Reset stack
592 POP DI ;;AN000;; Restore REGS
597 ; $ELSE ;;AN000;; Yes,
600 IF NOVERCHECKmsg
;;AN000;; IF version check is to be supressed
602 STC ;;AN000;; Reset carry flag
603 ELSE ;;AN000;; IF version check is to be supressed
605 STC ;;AN000;; Reset carry flag
606 ENDIF
;;AN000;; IF version check is to be supressed
611 SYSLOADMSG ENDP
;;AN000;;
612 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
614 SUBTTL DOS
- Message Retriever
- $M_VERSION_CHECK Proc
615 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
617 ;; Proc Name: $M_GET_DBCS_VEC
619 ;; Function: Get the DBCS vector and save it for later use
627 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
629 $M_GET_DBCS_VEC PROC
NEAR ;;AN000;;
631 PUSH AX ;;AN000;; Save character to check
634 MOV AX,DOS_GET_DBCS_INFO
;;AN000;; DOS function to get DBSC environment
635 INT 21H
;;AN000;; Get environment pointer
636 PUSH DS ;;AN000;; Get environment pointer
637 POP ES ;;AN000;; Get environment pointer
638 POP DS ;;AN000;; Get environment pointer
641 MOV WORD PTR $M_RT
.$M_DBCS_VEC
,SI ;;AN000;; Save DBCS Vector
642 MOV WORD PTR $M_RT
.$M_DBCS_VEC
+2,ES ;;AN000;;
646 POP AX ;;AN000;; Retrieve character to check
649 $M_GET_DBCS_VEC ENDP
;;
651 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
652 IF NOCHECKSTDIN
;AN001; Are we suppose to include the code for Checking EOF ?
653 ELSE ;AN001; Yes, THEN include it
655 SUBTTL DOS
- Message Retriever
- $M_CHECKSTDIN Proc
656 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
658 ;; Proc Name: $M_CHECKSTDIN
668 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
670 $M_CHECKSTDIN PROC
NEAR ;AN001;
672 MOV AX,DOS_IOCTL_GET_INFO
;AN001; Get info using IOCTL
677 OR DH,$M_CRIT_ERR_MASK
;AN001; Turn on bit
678 MOV AX,DOS_IOCTL_SET_INFO
;AN001; Set info using IOCTL
683 $M_CHECKSTDIN ENDP
;AN001;
685 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
686 ENDIF
;AN001; END of include for EOF Check
687 IF NOCHECKSTDOUT
;AN001; Are we suppose to include the code for Checking Disk Full?
688 ELSE ;AN001; Yes, THEN include it
690 SUBTTL DOS
- Message Retriever
- $M_CHECKSTDOUT Proc
691 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
693 ;; Proc Name: $M_CHECKSTDOUT
703 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
705 $M_CHECKSTDOUT PROC
NEAR ;AN001;
707 MOV AX,DOS_IOCTL_GET_INFO
;AN001; Get info using IOCTL
708 MOV BX,STDOUT
;AN001;
712 OR DH,$M_CRIT_ERR_MASK
;AN001; Turn on bit
713 MOV AX,DOS_IOCTL_SET_INFO
;AN001; Set info using IOCTL
718 $M_CHECKSTDOUT ENDP
;AN001;
720 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
721 ENDIF
;AN001; END of include for Disk Full Check
722 IF NOVERCHECKmsg
;;AN000;; Are we suppose to include the code for DOS version check?
723 ELSE ;;AN000;; Yes, THEN include it
725 SUBTTL DOS
- Message Retriever
- $M_VERSION_CHECK Proc
726 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
728 ;; Proc Name: $M_VERSION_CHECK
730 ;; Function: Determine if DOS version is within allowable limits
734 ;; Outputs: CARRY_FLAG = 1 if Incorrect DOS version
735 ;; Registers set for SYSDISPMSG
736 ;; CARRY_FLAG = 0 if Correct DOS version
740 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
742 $M_VERSION_CHECK PROC
NEAR ;;AN000;;
744 MOV AH,DOS_GET_VERSION
;;AN000;; Check that version matches VERSIONA.INC
747 CMP AX,EXPECTED_VERSION
;;AN000;; IF DOS_MAJOR is correct
750 CLC ;;AN000;; Clear the carry flag
751 ; $ELSE ;;AN000;; ELSE
754 IF NOT COMR
;; ** Special case for RESIDENT COMMAND.COM
755 CMP AX,LOWEST_4CH_VERSION
;;AN000;; Does this version support AH = 4CH
756 ; $IF B ;;AN000;; No,
758 MOV BX,NO_HANDLE
;;AN000;; No handle (version doesn't support)
759 ; $ELSE ;;AN000;; Yes,
762 MOV BX,STDERR
;;AN000;; Standard Error
766 MOV BX,NO_HANDLE
;;AN000;; No handle
768 MOV AX,1 ;;AN000;; Set message # 1
769 MOV CX,NO_REPLACE
;;AN000;; No replacable parms
770 MOV DL,NO_INPUT
;;AN000;; No input
771 MOV DH,UTILITY_MSG_CLASS
;;AN000;; Utility class message
772 STC ;;AN000;; Set Carry Flag
778 $M_VERSION_CHECK ENDP
;;
780 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
781 ENDIF
;;AN000;; END of include for DOS version check
782 ENDIF
;;AN000;; END of include for SYSLOADMSG
784 IF GETmsg
;;AN000;; Is the request to include the code for SYSGETMSG ?
786 $M_RT EQU $M_RT2
;;AN000;;
788 GETmsg
= FALSE
;;AN000;; Yes, THEN include it and reset flag
790 SUBTTL DOS
- Message Retriever
- GETMSG
.ASM Module
791 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
793 ;; Proc Name: SYSGETMSG
795 ;; Function: The GET service returns the segment, offset and size of the
796 ;; message text to the caller based on a message number.
797 ;; The GET function will not display the message thus assumes
798 ;; caller will handle replaceable parameters.
805 ;; Call $M_GET_MSG_ADDRESS
806 ;; IF MSG_NUM exists THEN
807 ;; Set DS:SI = MSG_TXT_PTR + 1
813 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
816 SYSGETMSG PROC
FAR ;;AN000;;
818 SYSGETMSG PROC
NEAR ;;AN000;;
821 ;; Save registers needed later
823 PUSH AX ;;AN000;; Save changed regs
829 CALL FAR PTR $M_GET_MSG_ADDRESS
;;AN000;; Scan thru classes to find message
831 CALL $M_GET_MSG_ADDRESS
;;AN000;; Scan thru classes to find message
832 ENDIF
;;AN000;; Return message in ES:DI
833 ; $IF NC ;;AN000;; Message found?
835 CMP DH,UTILITY_MSG_CLASS
840 POP DS ;;AN000;; Return message in DS:SI
844 IF FARmsg
;;AN000;; Yes,
846 POP DS ;;AN000;; Return message in DS:SI
848 PUSH CS ;;AN000;; Return message in DS:SI
853 MOV SI,DI ;;AN000;; Return message in DS:SI
857 POP BP ;;AN000;; Restore changed regs
865 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
866 IF $M_SUBS
;;AN000;; Include the common subroutines if they haven't yet
867 $M_SUBS
= FALSE
;;AN000;; No, then include and reset the flag
868 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
870 ;; PROC NAME: $M_GET_MSG_ADDRESS
872 ;; FUNCTION: To scan thru classes to return pointer to the message header
873 ;; INPUTS: Access to $M_RES_ADDRESSES
874 ;; OUPUTS: IF CX = 0 THEN Message was not found
875 ;; IF CX > 1 THEN ES:DI points to the specified message
876 ;; REGS CHANGED: ES,DI,CX
878 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
881 $M_GET_MSG_ADDRESS PROC
FAR ;;AN000;;
883 $M_GET_MSG_ADDRESS PROC
NEAR ;;AN000;;
888 XOR SI,SI ;;AN000;; Use SI as an index
889 XOR CX,CX ;;AN000;; Use CX as an size
892 CMP DH,UTILITY_MSG_CLASS
;;AN000;; Were utility messages requested?
893 ; $IF E ;;AN000;; Yes,
896 LES DI,DWORD PTR $M_RT
.$M_CLASS_ADDRS
[SI] ;;AN000;; Get address of class
899 MOV DI,WORD PTR $M_RT
.$M_CLASS_ADDRS
[SI] ;;AN000;; Get address of class
902 ; $ELSE ;;AN000;; No,
905 TEST DH,PARSE_ERR_CLASS
;;AN000;; Were parse errors requested?
906 ; $IF NE ;;AN000;; Yes,
908 LES DI,DWORD PTR $M_RT
.$M_PARSE_COMMAND
[SI] ;;AN000;; Get address of class
910 ; $ELSE ;;AN000;; No, extended errors were specified
913 CMP AX,$M_CRIT_LO
;;AN000;; Is this a critical error?
914 ; $IF AE,AND ;;AN000;;
916 CMP AX,$M_CRIT_HI
;;AN000;;
917 ; $IF BE ;;AN000;; Yes,
919 LES DI,DWORD PTR $M_RT
.$M_CRIT_ADDRS
[SI] ;;AN000;; Get address of class
924 LES DI,DWORD PTR $M_RT
.$M_EXT_ERR_ADDRS
[SI] ;;AN000;; Get address of class
933 CMP BX,$M_TERMINATING_FLAG
;;AN000;; Are we finished all classes?
934 ; $IF E ;;AN000;; Yes,
936 CMP DH,UTILITY_MSG_CLASS
;;AN000;; Was it a UTILITY class?
937 ; $IF E ;;AN000;; Yes,
939 STC ;;AN000;; Set the carry flag
940 ; $ELSE ;;AN000;; No,
943 MOV $M_RT
.$M_MSG_NUM
,AX ;;AN000;; Save message number
944 MOV AX,$M_SPECIAL_MSG_NUM
;;AN000;; Set special message number
945 MOV BP,$M_ONE_REPLACE
;;AN000;; Set one replace in message
946 XOR SI,SI ;;AN000;; Reset the SI index to start again
948 ; $ENDIF ;;AN000;; No,
953 CMP BX,$M_CLASS_NOT_EXIST
;;AN000;; Does this class exist?
954 ; $IF NE ;;AN001;; Yes,
956 CALL $M_FIND_SPECIFIED_MSG
;;AN000;; Try to find the message
959 ADD SI,$M_ADDR_SZ_FAR
;;AN000;; Get next class
965 OR CX,CX ;;AN000;; Was the message found?
966 ; $ENDDO NZ,LONG ;;AN000;;
972 PUSHF ;;AN006;; Save the flag state
973 CMP DH,EXT_ERR_CLASS
;;AN006;; Was an extended error requested?
974 ; $IF E ;;AN006;; Yes,
976 PUSH DX ;;AN006;; Save all needed registers
983 MOV AX,IFSFUNC_INSTALL_CHECK
;;AN006;; Check if IFSFUNC is installed
985 CMP AL,IFSFUNC_INSTALLED
;;AN006;; Is it installed?
986 POP AX ;;AN006;; Restore msg number
987 ; $IF E ;;AN006;; Yes,
989 MOV BX,AX ;;AN006;; BX is the extended error number
990 MOV AX,IFS_GET_ERR_TEXT
;;AN006;; AX is the muliplex number
991 INT 2FH
;;AN006;; Call IFSFUNC
992 ; $ELSE ;;AN006;; No,
995 STC ;;AN006;; Carry conditon
999 ; $IF C ;;AN006;; Was there an update?
1001 POP DI ;;AN006;; No,
1002 POP ES ;;AN006;; Restore old pointer
1004 ; $ELSE ;;AN006;; Yes
1007 ADD SP,6 ;;AN006;; Throw away old pointer
1008 CALL $M_SET_LEN_IN_CX
;;AN006;; Get the length of the ASCIIZ string
1011 POP BP ;;AN006;; Restore other Regs
1015 $M_POPF
;;AN006;; Restore the flag state
1019 RET ;;AN000;; Return ES:DI pointing to the message
1021 $M_GET_MSG_ADDRESS ENDP
;;
1023 $M_SET_LEN_IN_CX PROC
NEAR ;;
1025 PUSH DI ;;AN006;; Save position
1027 MOV CX,-1 ;;AN006;; Set CX for decrements
1028 XOR AL,AL ;;AN006;; Prepare compare register
1029 REPNE SCASB ;;AN006;; Scan for zero
1030 NOT CX ;;AN006;; Change decrement into number
1031 DEC CX ;;AN006;; Don't include the zero
1033 POP DI ;;AN006;; Restore position
1036 $M_SET_LEN_IN_CX ENDP
;;
1038 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1040 ;; PROC NAME: $M_FIND_SPECIFIED_MSG
1042 ;; FUNCTION: To scan thru message headers until message is found
1043 ;; INPUTS: ES:DI points to beginning of msg headers
1044 ;; CX contains the number of messages in class
1045 ;; DH contains the message class
1046 ;; OUPUTS: IF CX = 0 THEN Message was not found
1047 ;; IF CX > 1 THEN ES:DI points to header of specified message
1049 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1051 $M_FIND_SPECIFIED_MSG PROC
NEAR ;;AN000;;
1053 CMP BX,1 ;;AN004;; Do we have an address to CALL?
1054 ; $IF E,AND ;;AN004;; Yes,
1056 CMP WORD PTR $M_RT
.$M_DISK_PROC_ADDR
,-1 ;;AN004;; Do we have an address to CALL?
1057 ; $IF NE ;;AN004;; Yes,
1059 CMP AX,$M_SPECIAL_MSG_NUM
;;AN004;; Are we displaying a default Ext Err?
1060 ; $IF E ;;AN004;; . . . and . . .
1062 PUSH AX ;;AN004;; Reset the special message number
1063 MOV AX,$M_RT
.$M_MSG_NUM
;;AN004;; Get the old message number
1064 CALL DWORD PTR $M_RT
.$M_DISK_PROC_ADDR
;;AN004;; Call the READ_DISK_PROC to get error text
1065 POP AX ;;AN004;; Reset the special message number
1066 ; $ELSE ;;AN004;; Get the old message number
1069 CALL DWORD PTR $M_RT
.$M_DISK_PROC_ADDR
;;AN004;; Call the READ_DISK_PROC to get error text
1070 ; $ENDIF ;;AN004;; Get the old message number
1075 XOR CX,CX ;;AN002;; CX = 0 will allow us to
1076 CMP DH,UTILITY_MSG_CLASS
;;AN001;;
1079 MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG
;;AN001;; Get number of messages in class
1084 CMP BYTE PTR ES:[DI].$M_CLASS_ID
,DH ;;AN002;; Check if class still exists at
1086 CMP BYTE PTR CS:[DI].$M_CLASS_ID
,DH ;;AN002;; Check if class still exists at
1088 ; $IF E ;;AN002;; pointer (hopefully)
1091 MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG
;;AN000;; Get number of messages in class
1093 MOV CL,BYTE PTR CS:[DI].$M_NUM_CLS_MSG
;;AN000;; Get number of messages in class
1095 ; $ENDIF ;;AN002;; go on to the next class
1099 ADD DI,$M_CLASS_ID_SZ
;;AN000;; Point past the class header
1100 STC ;;AN004;; Flag that we haven't found anything yet
1104 ; $IF C ;;AN004;; Have we found anything yet?
1106 CLC ;;AN004;; No, reset carry
1109 OR CX,CX ;;AN000;; Do we have any to check?
1110 ; $LEAVE Z ;;AN000;; No, return with CX = 0
1112 CMP DH,UTILITY_MSG_CLASS
;;AN001;;
1115 CMP AX,WORD PTR ES:[DI].$M_NUM
;;AN001;; Is this the message requested?
1120 CMP AX,WORD PTR ES:[DI].$M_NUM
;;AN000;; Is this the message requested?
1122 CMP AX,WORD PTR CS:[DI].$M_NUM
;;AN000;; Is this the message requested?
1126 ; $EXITIF E ;;AN000;;
1131 DEC CX ;;AN000;; No, well do we have more to check?
1132 ; $LEAVE Z ;;AN000;; No, return with CX = 0
1134 ADD DI,$M_ID_SZ
;;AN000;; Yes, skip past msg header
1135 ; $ENDLOOP ;;AN000;;
1139 ; $ENDSRCH ;;AN000;; Check next message
1141 ; $IF NC ;;AN000;; Did we find the message?
1143 CMP DH,UTILITY_MSG_CLASS
;;AN001;; Yes, is it a utility message?
1150 POP ES ;;AN000;; Return ES:DI pointing to the message
1154 ADD DI,WORD PTR ES:[DI].$M_TXT_PTR
;;AN000;; Prepare ES:DI pointing to the message
1159 ;; Yes, great we can return with CX > 0
1161 ; $IF NC ;;AN000;; Did we find the message?
1164 MOV CL,BYTE PTR ES:[DI] ;;AN000;; Move size into CX
1165 INC DI ;;AN000;; Increment past length
1169 MOV $M_RT
.$M_SIZE
,$M_NULL
;;AN004;; Reset variable
1170 RET ;;AN000;; Return
1172 $M_FIND_SPECIFIED_MSG ENDP
;;AN000;;
1174 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1175 ENDIF
;;AN000;; END of include of common subroutines
1176 ENDIF
;;AN000;; END of include of SYSGETMSG
1178 IF DISPLAYmsg
;;AN000;; Is the request to include the code for SYSGETMSG ?
1180 $M_RT EQU $M_RT2
;;AN000;;
1182 DISPLAYmsg
= FALSE
;;AN000;; Yes, THEN include it and reset flag
1184 SUBTTL DOS
- Message Retriever
- DISPMSG
.ASM Module
1185 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1187 ;; Proc Name: SYSDISPMSG
1189 ;; Function: The DISPLAY service will output a defined message to a handle
1190 ;; requested by the caller. It also provides function to display
1191 ;; messages when handles are not applicable (ie. DOS function calls
1192 ;; 00h to 0Ah) Replaceable parameters are allowed and are
1193 ;; defined previous to entry.
1195 ;; It is assumes that a PRELOAD function has already determined
1196 ;; the addressibilty internally to the message retriever services.
1202 ;; Save registers needed later
1203 ;; Get address of the message requested
1204 ;; IF Message number exists THEN
1205 ;; IF replacable parameters were specified THEN
1206 ;; Display message with replacable parms
1208 ;; Display string without replacable parms
1210 ;; IF character input was requested THEN
1211 ;; Wait for character input
1219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1222 SYSDISPMSG PROC
FAR ;;AN000;;
1224 SYSDISPMSG PROC
NEAR ;;AN000;;
1227 ;; Save registers and values needed later
1229 PUSH AX ;;AN000;; Save changed REGs
1233 PUSH DI ;;AN000;; Save pointer to input buffer (offset)
1234 PUSH ES ;;AN000;; Save pointer to input buffer (segment)
1235 PUSH DX ;;AN000;; Save Input/Class request
1237 MOV BP,CX ;;AN000;; Use BP to hold replace count
1238 MOV WORD PTR $M_RT
.$M_HANDLE
,BX ;;AN000;; Save handle
1239 MOV BYTE PTR $M_RT
.$M_CLASS
,DH ;;AN004;; Save class
1241 ;; Get address of the message requested
1244 CALL FAR PTR $M_GET_MSG_ADDRESS
;;AN000;; Scan thru classes to find message
1246 CALL $M_GET_MSG_ADDRESS
;;AN000;; Scan thru classes to find message
1248 OR CX,CX ;;AN000;; Was message found?
1249 ; $IF NZ ;;AN000;; YES, Message address in ES:DI
1252 ;; Test if replacable parameters were specified
1254 OR BP,BP ;;AN000;; Were replacable parameters requested
1258 ;; Display string without replacable parms
1260 CALL $M_DISPLAY_STRING
;;AN000;; No, great . . . Display message
1264 IF $M_REPLACE
;;AN000;;
1266 ;; Display message with replacable parms
1268 CALL $M_DISPLAY_MESSAGE
;;AN000;; Display the message with substitutions
1275 POP DX ;;AN000;; Get Input/Class request
1277 CALL $M_ADD_CRLF
;;AN004;; Check if we need to add the CR LF chars.
1279 POP ES ;;AN000;; Get location of input buffer (if specified)
1282 ;; Test if character input was requested
1284 IF INPUTmsg
;;AN000;;
1285 OR DL,DL ;;AN000;; Was Wait-For-Input requested?
1288 CALL $M_WAIT_FOR_INPUT
;;AN000;;
1296 STC ;;AN000;; Reset carry flag
1299 ; $ELSE ;;AN000;; No,
1302 POP ES ;;AN000;; Get pointer to input buffer (segment)
1303 POP DI ;;AN000;; Get base pointer to first sublist (offset)
1304 POP DX ;;AN000;; Get base pointer to first sublist (segment)
1305 STC ;;AN000;; Set carry flag
1309 ; $IF NC ;;AN000;; Was there an error?
1311 POP BP ;;AN000;; No,
1314 IF INPUTmsg
;;AN000;;
1319 ; $ELSE ;;AN000;; Yes,
1322 ADD SP,8 ;;AN000;; Eliminate from stack
1327 RET ;;AN000;; Return
1329 SYSDISPMSG ENDP
;;AN000;;
1331 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1334 ;; PROC NAME: $M_DISPLAY_STRING
1336 ;; FUNCTION: Will display or write string
1337 ;; INPUTS: ES:DI points to beginning of message
1338 ;; CX contains the length of string to write (if applicable)
1340 ;; REGS Revised: None
1342 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1344 $M_DISPLAY_STRING PROC
NEAR ;;AN000;;
1350 MOV BX,$M_RT
.$M_HANDLE
;;AN000;; Retrieve handle
1352 IF COMR
;; ** Special case for RESIDENT COMMAND.COM
1353 CALL $M_DISPLAY_$_STRING
;;AN000;; No, display $ terminated string
1355 CMP BX,$M_NO_HANDLE
;;AN000;; Was there a handle specified?
1358 CALL $M_DISPLAY_$_STRING
;;AN000;; No, display $ terminated string
1362 CALL $M_DISPLAY_H_STRING
;;AN000;; Yes, display string to handle
1366 ; $IF C ;;AN000;; Was there an error?
1368 MOV AH,DOS_GET_EXT_ERROR
;;AN000;; Yes,
1369 MOV BX,DOS_GET_EXT_ERROR_BX
;;AN000;; Get extended error
1371 XOR AH,AH ;;AN000;; Clear AH
1372 ADD SP,6 ;;AN000;; Clean up stack
1373 STC ;;AN000;; Flag that there was an error
1374 ; $ELSE ;;AN000;; No,
1377 CMP BX,$M_NO_HANDLE
;;AN000;; Was there a handle specified?
1380 CMP AX,CX ;AN001; Was it ALL written?
1381 ; $IF NE ;AN001; No,
1383 CALL $M_GET_EXT_ERR_39
;AN001; Set Extended error
1384 ADD SP,6 ;AN001; Clean up stack
1385 STC ;AN001; Flag that there was an error
1393 ; $IF NC ;;AN000;; Was there ANY error?
1395 POP DX ;;AN000;; Restore regs
1400 RET ;;AN000;; Return
1402 $M_DISPLAY_STRING ENDP
;;AN000;;
1404 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1406 ;; PROC NAME: $M_DISPLAY_$_STRING
1408 ;; FUNCTION: Will display a $ terminated string
1409 ;; INPUTS: ES:DI points to beginning of message text (not the length)
1413 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1415 $M_DISPLAY_$_STRING PROC
NEAR ;;AN000;;
1419 POP DS ;;AN000;; Set DS to segment of message text
1421 CMP CX,$M_SINGLE_CHAR
;;AN000;; Is this a single character?
1422 ; $IF E ;;AN000;; Yes,
1424 MOV AH,DOS_DISP_CHAR
;;AN000;; DOS Function to display CHARACTER
1425 MOV DL,BYTE PTR ES:[DI] ;;AN000;; Get the character
1426 INT 21H
;;AN000;; Write character
1427 POP DS ;;AN000;; Set DS to segment of message text
1428 MOV AL,DL ;;AN000;; Get the character in AL
1429 CALL $M_IS_IT_DBCS
;;AN000;; Is this the first byte of a DB character
1432 POP DS ;;AN000;; Set DS to segment of message text
1433 ; $IF C ;;AN000;; Yes,
1435 MOV DL,BYTE PTR ES:[DI]+1 ;;AN000;; Get the next character
1436 INT 21H
;;AN000;; Write character
1437 CLC ;;AN000;; Clear the DBCS indicator
1440 ; $ELSE ;;AN000;; No,
1444 MOV AH,DOS_DISP_CHAR
;;AN000;; DOS Function to display CHARACTER
1447 OR CX,CX ;;AN002;; Are there any left to display?
1448 ; $LEAVE Z ;;AN002;; Yes,
1450 MOV DL,BYTE PTR ES:[DI] ;;AN002;; Get the character
1451 INT 21H
;;AN002;; Display the character
1452 INC DI ;;AN002;; Set pointer to next character
1453 DEC CX ;;AN002;; Count this character
1454 ; $ENDDO Z ;;AN002;; No,
1461 CLC ;;AN000;; Char functions used don't return carry as error
1465 $M_DISPLAY_$_STRING ENDP
;;AN000;;
1468 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1470 ;; PROC NAME: $M_DISPLAY_H_STRING
1472 ;; FUNCTION: Will display a string to a specified handle
1473 ;; INPUTS: ES:DI points to beginning of message
1474 ;; CX contains the number of bytes to write
1475 ;; BX contains the handle to write to
1479 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1481 $M_DISPLAY_H_STRING PROC
NEAR ;;AN000;;
1483 XOR AX,AX ;;AN002;; Set number of bytes written to 0
1484 OR CX,CX ;;AN002;; For performance, don't write if not necessary
1485 ; $IF NZ ;;AN002;; Any chars to write?
1487 PUSH DS ;;AN000;; Yes,
1489 POP DS ;;AN000;; Set DS to segment of message text
1490 MOV AH,DOS_WRITE_HANDLE
;;AN000;; DOS function to write to a handle
1491 MOV DX,DI ;;AN000;; Pointer to data to write
1492 CMP CX,$M_SINGLE_CHAR
;;AN000;; Is this a single character?
1493 ; $IF E ;;AN000;; Yes,
1495 INT 21H
;;AN000;; Write character
1496 POP DS ;;AN000;; Set DS to segment of message text
1498 MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get the character
1499 CALL $M_IS_IT_DBCS
;;AN000;; Is this the first byte of a DB character
1500 POP AX ;;AN000;; Set DS to segment of message text
1503 POP DS ;;AN000;; Set DS to segment of message text
1504 ; $IF C ;;AN000;; Yes,
1506 CLC ;;AN000;; Clear the DBCS indicator
1507 MOV AH,DOS_WRITE_HANDLE
;;AN000;; DOS function to write to a handle
1508 INC DX ;;AN000;; Point to next character
1509 INT 21H
;;AN000;; Write character
1512 ; $ELSE ;;AN000;; No,
1515 INT 21H
;;AN000;; Write String at DS:SI to handle
1524 $M_DISPLAY_H_STRING ENDP
;;AN000;;
1526 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1528 ;; PROC NAME: $M_GET_EXT_ERR_39
1530 ;; FUNCTION: Will set registers for extended error #39
1532 ;; OUPUTS: AX,BX,CX set
1535 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1537 $M_GET_EXT_ERR_39 PROC
NEAR ;AN001;
1539 MOV AX,EXT_ERR_39
;AN001; Set AX=39
1540 MOV BX,(ERROR_CLASS_39
SHR 8) + ACTION_39
;AN001; Set BH=1 BL=4
1541 MOV CH,LOCUS_39
;AN001; Set CH=1
1545 $M_GET_EXT_ERR_39 ENDP
;AN001;
1547 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1550 ;; PROC NAME: $M_ADD_CRLF
1552 ;; FUNCTION: Will decide whether to display a CRLF
1553 ;; INPUTS: DX contains the Input/Class requested
1555 ;; REGS Revised: CX,ES,DI
1557 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1559 $M_ADD_CRLF PROC
NEAR ;;AN004;;
1561 CMP DH,UTILITY_MSG_CLASS
;;AN004;; Is it a utility message?
1562 ; $IF NE ;;AN004;; No,
1564 TEST DH,$M_NO_CRLF_MASK
;;AN004;; Are we to supress the CR LF?
1565 ; $IF Z ;;AN004;; No,
1568 POP ES ;;AN004;; Set ES to data segment
1569 LEA DI,$M_RT
.$M_CRLF
;;AN004;; Point at CRLF message
1570 MOV CX,$M_CRLF_SIZE
;;AN004;; Set the message size
1571 CALL $M_DISPLAY_STRING
;;AN004;; Display the CRLF
1576 RET ;;AN004;; Return
1578 $M_ADD_CRLF ENDP
;;AN004;;
1580 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1582 ;; PROC NAME: $M_IS_IT_DBCS
1584 ;; FUNCTION: Will decide whether character is Single or Double Byte
1585 ;; INPUTS: AL contains the byte to be checked
1586 ;; OUPUTS: Carry flag = 0 if byte is NOT in DBCS range
1587 ;; Carry flag = 1 if byte IS in DBCS range
1588 ;; REGS USED: All restored
1590 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1592 $M_IS_IT_DBCS PROC
NEAR ;;AN000;;
1594 PUSH ES ;;AN000;; Save Extra segment register
1595 PUSH DI ;;AN000;; Save SI register
1597 LES DI,$M_RT
.$M_DBCS_VEC
;;AN000;;
1598 OR DI,DI ;;AN000;; Was the DBCS vector set?
1603 CMP WORD PTR ES:[DI],$M_DBCS_TERM
;;AN000;; Is this the terminating flag?
1605 ; $LEAVE E ;;AN000;;
1608 CMP AL,BYTE PTR ES:[DI] ;;AN000;; Does the character fall in the DBCS range?
1609 ; $IF AE,AND ;;AN000;;
1611 CMP AL,BYTE PTR ES:[DI]+1 ;;AN000;; Does the character fall in the DBCS range?
1615 ; $ENDIF ;;AN000;; Set carry flag
1617 INC DI ;;AN000;; No,
1618 INC DI ;;AN000;; Go to next vector
1626 POP ES ;;AN000;; Restore SI register
1627 RET ;;AN000;; Return
1629 $M_IS_IT_DBCS ENDP
;;AN000;;
1631 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1633 ;; PROC NAME: $M_CONVERT2ASC
1635 ;; FUNCTION: Convert a binary number to a ASCII string
1636 ;; INPUTS: DX:AX contains the number to be converted
1637 ;; $M_RT_DIVISOR contains the divisor
1638 ;; OUPUTS: CX contains the number of characters
1639 ;; Top of stack --> Last character
1641 ;; Bot of stack --> First character
1644 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1646 $M_CONVERT2ASC PROC
NEAR ;;AN000;;
1648 POP [$M_RT
.$M_RETURN_ADDR
] ;;AN000;; Save Return Address
1649 XOR BX,BX ;;AN000;; Use BP as a swapping register
1651 XCHG BX,AX ;;AN000;; Initialize - Low Word in BP
1652 XCHG AX,DX ;;AN000;; - High Word in AX
1653 ; $DO ;;AN000;; DO UNTIL Low Word becomes zero
1655 DIV $M_RT
.$M_DIVISOR
;;AN000;; Divide High Word by divisor
1656 XCHG BX,AX ;;AN000;; Setup to divide Low Word using remainder
1657 ;; and save reduced High Word in BP
1658 DIV $M_RT
.$M_DIVISOR
;;AN000;; Divide Low Word by divisor
1659 CMP DX,9 ;;AN000;; Make a digit of the remainder
1660 ; $IF A ;;AN000;; IF 10 to 15,
1662 ADD DL,55 ;;AN000;; Make A to F ASCII
1663 ; $ELSE ;;AN000;; IF 0 to 9,
1666 ADD DL,'0' ;;AN000;; Make 0 to 9 ASCII
1669 PUSH DX ;;AN000;; Save the digit on the stack
1670 INC CX ;;AN000;; Count that digit
1671 OR AX,AX ;;AN000;; Are we done?
1672 ; $LEAVE Z,AND ;;AN000;;
1674 OR BX,BX ;;AN000;; AX and BX must be ZERO!!
1675 ; $LEAVE Z ;;AN000;; No,
1679 CMP CX,$M_FIRST_THOU
;;AN000;; Are we at the first thousands mark
1680 ; $IF E ;;AN000;; Yes,
1682 CMP $M_SL
.$M_S_PAD
,$M_COMMA
;;AN000;; Is the pad character a comma?
1683 ; $IF E ;;AN000;; Yes,
1685 PUSH WORD PTR $M_RT
.$M_THOU_SEPARA
;;AN000;; Insert a thousand separator
1689 ; $ELSE ;;AN000;; No,
1692 CMP CX,$M_SECOND_THOU
;;AN000;; Are we at the first thousands mark
1693 ; $IF E ;;AN000;; Yes,
1695 CMP $M_SL
.$M_S_PAD
,$M_COMMA
;;AN000;; Is the pad character a comma?
1696 ; $IF E ;;AN000;; Yes,
1698 PUSH WORD PTR $M_RT
.$M_THOU_SEPARA
;;AN000;; Insert a thousand separator
1702 ; $ELSE ;;AN000;; No,
1705 CMP CX,$M_THIRD_THOU
;;AN000;; Are we at the first thousands mark
1706 ; $IF E ;;AN000;; Yes,
1708 CMP $M_SL
.$M_S_PAD
,$M_COMMA
;;AN000;; Is the pad character a comma?
1709 ; $IF E ;;AN000;; Yes,
1711 PUSH WORD PTR $M_RT
.$M_THOU_SEPARA
;;AN000;; Insert a thousand separator
1722 XCHG AX,BX ;;AN000;; Setup to divide the reduced High Word
1723 ;;AN000;; and Revised Low Word
1724 XOR DX,DX ;;AN000;; Reset remainder
1725 ; $ENDDO ;;AN000;; NEXT
1729 XOR DX,DX ;;AN000;; Reset remainder
1730 XOR AX,AX ;;AN000;; Reset remainder
1731 PUSH [$M_RT
.$M_RETURN_ADDR
] ;;AN000;; Restore Return Address
1732 RET ;;AN000;; Return
1734 $M_CONVERT2ASC ENDP
;;AN000;;
1736 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1738 ;; PROC NAME: $M_DISPLAY_MESSAGE
1740 ;; FUNCTION: Will display or write entire message (with replacable parameters)
1741 ;; INPUTS: ES:DI points to beginning of message
1742 ;; DS:SI points to first sublist structure in chain
1743 ;; BX contains the handle to write to (if applicable)
1744 ;; CX contains the length of string to write (before substitutions)
1745 ;; BP contains the count of replacables
1750 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1752 $M_DISPLAY_MESSAGE PROC
NEAR ;;AN000;;
1754 ; $DO ;;AN000;; Note: DS:SI -> message
1756 XOR DX,DX ;;AN000;; Set size = 0
1757 OR CX,CX ;;AN000;; Are we finished the message yet?
1758 ; $IF NZ ;;AN000;; No,
1760 MOV AH,"%" ;;AN000;; Prepare to scan for %
1763 ; $DO ;;AN000;; Scan through string until %
1765 CMP BYTE PTR ES:[DI],AH ;;AN000;; Is this character NOT a %
1766 ; $LEAVE E,AND ;;AN000;; No,
1768 CMP BYTE PTR ES:[DI+1],AH ;;AN000;; Is the next character also a %
1769 ; $LEAVE NE,AND ;;AN000;; No,
1771 CMP AL,AH ;;AN000;; Was the character before a %
1772 ; $LEAVE NE ;;AN000;; No, GREAT found it
1775 MOV AL,BYTE PTR ES:[DI] ;;AN004;; Yes, (to any of the above)
1776 CALL $M_IS_IT_DBCS
;;AN004;; Is this character the first part of a DBCS?
1777 ; $IF C ;;AN004;; Yes,
1779 INC DI ;;AN004;; Increment past second part
1782 INC DI ;;AN000;; Next character in string
1783 INC DX ;;AN000;; Size = Size + 1
1784 DEC CX ;;AN000;; Decrement total size
1785 ; $ENDDO Z ;;AN000;; Exit scan if we're at the end of the line
1791 PUSH SI ;;AN000;; Save beginning of sublists
1792 XCHG CX,DX ;;AN000;; Get size of message to display (tot sz in DX)
1793 OR BP,BP ;;AN000;; Do we have any replacables to do?
1794 ; $IF NZ ;;AN000;; Yes,
1796 DEC BP ;;AN000;; Decrement number of replacables
1798 ;; Search through sublists to find applicable one
1800 CMP $M_RT
.$M_MSG_NUM
,$M_NULL
;;AN000;; Is this an Extended/Parse case
1801 ; $IF E ;;AN000;; No,
1805 MOV AL,$M_SL
.$M_S_ID
;;AN000;; Get ID byte
1806 ADD AL,30H
;;AN000;; Convert to ASCII
1807 CMP AL,BYTE PTR ES:[DI]+1 ;;AN000;; Is this the right sublist?
1808 ; $EXITIF E ;;AN000;;
1810 ; $ORELSE ;;AN000;; No,
1813 CMP AL,$M_SPECIAL_CASE
;;AN000;; Does this sublist have ID = 0
1814 ; $LEAVE E,AND ;;AN000;; Yes,
1816 OR DX,DX ;;AN000;; Are we at the end of the message?
1817 ; $LEAVE Z ;;AN000;; No,
1820 ADD SI,WORD PTR $M_SL
.$M_S_SIZE
;;AN000;; Next SUBLIST
1821 ; $ENDLOOP ;;AN000;; Yes,
1824 CMP $M_RT
.$M_CLASS
,UTILITY_MSG_CLASS
;;AN004;; Is it a utility message?
1825 ; $IF E ;;AN004;; Yes,
1827 INC DX ;;AN000;; Remember to display CR,LF
1828 INC DX ;;AN000;; at the end of the message
1829 DEC CX ;;AN000;; Adjust message length
1831 DEC DI ;;AN000;; Adjust ending address of message
1833 ; $ELSE ;;AN004;; No,
1836 MOV DX,-1 ;;AN004;; Set special case
1839 ; $ENDSRCH ;;AN000;;
1846 ;; Prepare and display this part of message
1848 PUSH DI ;;AN000;; Save pointer to replace number
1849 SUB DI,CX ;;AN000;; Determine beginning of string
1850 CALL $M_DISPLAY_STRING
;;AN000;; Display string until % (or end)
1851 POP DI ;;AN000;; Get back pointer to replace number
1852 POP CX ;;AN000;; Clean up stack in case error
1853 ; $LEAVE C,LONG ;;AN000;; Fail if carry was set
1859 ;; Save and reset pointer registers
1861 MOV CX,DX ;;AN000;; Get the size of the rest of the message
1862 CMP $M_SL
.$M_S_ID
,$M_SPECIAL_CASE
-30H
;;AN000;; Is this the %0 case?
1863 ; $IF NE ;;AN000;; No,
1865 OR CX,CX ;;AN000;; Are we finished the whole message?
1866 ; $IF NZ ;;AN000;; No,
1868 DEC CX ;;AN000;; Decrement total size (%)
1869 DEC CX ;;AN000;; Decrement total size (#)
1870 INC DI ;;AN000;; Go past %
1871 INC DI ;;AN000;; Go past replace number
1872 ; $ELSE ;;AN000;; Yes, (Note this will not leave because INC)
1875 POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs
1876 ; $ENDIF ;;AN000;; Yes, Note this will not leave because INC
1881 OR CX,CX ;;AN000;; Are we finished the whole message?
1882 ; $IF Z ;;AN004;; No,
1884 POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs
1885 ; $ELSE ;;AN000;; No,
1888 CMP CX,-1 ;;AN004;; Are we at the end of the message?
1889 ; $IF Z ;;AN004;; No,
1894 OR DI,DI ;;AN004;; Turn ZF off
1897 ; $ENDIF ;;AN000;; Note this will not leave because INC
1899 ; $LEAVE Z ;;AN000;;
1901 PUSH BP ;;AN000;; Save the replace count
1902 PUSH DI ;;AN000;; Save location to complete message
1904 PUSH CX ;;AN000;; Save size of the rest of the message
1905 XOR CX,CX ;;AN000;; Reset CX used for character count
1907 ;; Determine what action is required on parameter
1909 CMP $M_RT
.$M_MSG_NUM
,$M_NULL
;;AN000;; Is this an Extended/Parse case
1913 IF CHARmsg
;;AN000;; Was Char specified?
1914 TEST BYTE PTR $M_SL
.$M_S_FLAG
,NOT Char_Type
AND $M_TYPE_MASK
;;AN000;;
1918 ;; Character type requested
1920 LES DI,DWORD PTR $M_SL
.$M_S_VALUE
;;AN000;; Load pointer to replacing parameter
1921 CALL $M_CHAR_REPLACE
;;AN000;;
1922 ; $ELSE ;;AN000;; Get the rest of the message to display
1926 IF NUMmsg
;;AN000;; Was Nnmeric type specified?
1927 TEST BYTE PTR $M_SL
.$M_S_FLAG
,NOT Sgn_Bin_Type
AND $M_TYPE_MASK
;;AN000;;
1928 ; $IF Z,OR ;;AN000;;
1930 TEST BYTE PTR $M_SL
.$M_S_FLAG
,NOT Unsgn_Bin_Type
AND $M_TYPE_MASK
;;AN000;;
1931 ; $IF Z,OR ;;AN000;;
1933 TEST BYTE PTR $M_SL
.$M_S_FLAG
,NOT Bin_Hex_Type
AND $M_TYPE_MASK
;;AN000;;
1938 ;; Numeric type requested
1940 LES DI,DWORD PTR $M_SL
.$M_S_VALUE
;;AN000;; Load pointer to replacing parameter
1941 CALL $M_BIN2ASC_REPLACE
;;AN000;;
1942 ; $ELSE ;;AN000;; Get the rest of the message to display
1946 IF DATEmsg
;;AN000;; Was date specified?
1947 TEST BYTE PTR $M_SL
.$M_S_FLAG
,NOT Date_Type
AND $M_TYPE_MASK
;;AN000;;
1951 ;; Date type requested
1953 CALL $M_DATE_REPLACE
;;AN000;;
1954 ; $ELSE ;;AN000;; Get the rest of the message to display
1958 IF TIMEmsg
;;AN000;; Was time (12 hour format) specified?
1960 ;; Time type requested (Default if we have not matched until here)
1962 CALL $M_TIME_REPLACE
;;AN000;;
1965 IF DATEmsg
;;AN000;;
1973 IF CHARmsg
;;AN000;;
1978 IF $M_REPLACE
;;AN000;;
1979 ;; With the replace information of the Stack, display the replaceable field
1981 CALL $M_DISPLAY_REPLACE
;;AN000;; Display the replace
1983 ;; None of the above - Extended/Parse replace
1988 CALL $M_EXT_PAR_REPLACE
;;AN000;;
1993 ;; We must go back and complete the message after the replacable parameter if there is any left
1995 ; $IF NC ;;AN000;; IF there was an error displaying then EXIT
1997 POP CX ;;AN000;; Get size of the rest of the message
1998 POP ES ;;AN000;; Get address of the rest of the message
2000 POP BP ;;AN000;; Get replacment count
2001 POP SI ;;AN000;; ELSE get address of first sublist structure
2005 ADD SP,10 ;;AN000;; Clean up stack if error
2009 CMP $M_RT
.$M_MSG_NUM
,$M_NULL
;;AN000;; Is this an Extended/Parse case
2010 ; $ENDDO NE,OR ;;AN000;;
2012 ; $ENDDO C,LONG ;;AN000;; Go back and display the rest of the message
2018 ;; IF there was an error displaying then EXIT
2019 MOV $M_RT
.$M_MSG_NUM
,0 ;;AN000;; Reset message number to null
2020 RET ;;AN000;; Return
2022 $M_DISPLAY_MESSAGE ENDP
;;AN000;;
2024 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2026 ;; PROC NAME: $M_EXT_PAR_REPLACE
2034 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2036 $M_EXT_PAR_REPLACE PROC
NEAR ;;AN000;;
2038 XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH)
2039 MOV AX,$M_RT
.$M_MSG_NUM
;;AN000;; Prepare for get binary value (LOW)
2040 MOV $M_RT
.$M_DIVISOR
,$M_BASE10
;;AN000;; Set default divisor
2042 CALL $M_CONVERT2ASC
;;AN000;;
2046 POP AX ;;AN000;; Get character in register
2047 MOV BYTE PTR $M_RT
.$M_TEMP_BUF
[BX],AL ;;AN000;; Move char into the buffer
2048 INC BX ;;AN000;; Increase buffer count
2049 CMP BX,$M_TEMP_BUF_SZ
;;AN000;; Is buffer full?
2050 ; $IF E ;;AN000;; Yes,
2052 CALL $M_FLUSH_BUF
;;AN000;; Flush the buffer
2055 DEC CL ;;AN000;; Have we completed replace?
2056 ; $ENDDO Z ;;AN000;;
2059 MOV AX,$M_CR_LF
;;AN000;; Move char into the buffer
2060 MOV WORD PTR $M_RT
.$M_TEMP_BUF
[BX],AX ;;AN000;; Move char into the buffer
2061 INC BX ;;AN000;; Increase buffer count
2062 INC BX ;;AN000;; Increase buffer count
2063 CALL $M_FLUSH_BUF
;;AN000;; Flush the buffer
2066 $M_EXT_PAR_REPLACE ENDP
;;AN000;;
2068 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2070 IF $M_SUBS
;;AN000;; Include the common subroutines if they haven't yet
2071 $M_SUBS
= FALSE
;;AN000;; No, then include and reset the flag
2072 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2074 ;; PROC NAME: $M_GET_MSG_ADDRESS
2076 ;; FUNCTION: To scan thru classes to return pointer to the message header
2077 ;; INPUTS: Access to $M_RES_ADDRESSES
2078 ;; OUPUTS: IF CX = 0 THEN Message was not found
2079 ;; IF CX > 1 THEN DS:SI points to the specified message
2080 ;; REGS CHANGED: ES,DI,CX,DS,SI
2082 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2085 $M_GET_MSG_ADDRESS PROC
FAR ;;AN000;;
2087 $M_GET_MSG_ADDRESS PROC
NEAR ;;AN000;;
2092 XOR SI,SI ;;AN000;; Use SI as an index
2093 XOR CX,CX ;;AN000;; Use CX as an size
2096 CMP DH,UTILITY_MSG_CLASS
;;AN000;; Were utility messages requested?
2097 ; $IF E ;;AN000;; Yes,
2100 LES DI,DWORD PTR $M_RT
.$M_CLASS_ADDRS
[SI] ;;AN000;; Get address of class
2103 MOV DI,WORD PTR $M_RT
.$M_CLASS_ADDRS
[SI] ;;AN000;; Get address of class
2106 ; $ELSE ;;AN000;; No,
2109 TEST DH,PARSE_ERR_CLASS
;;AN000;; Were parse errors requested?
2110 ; $IF NE ;;AN000;; Yes,
2112 LES DI,DWORD PTR $M_RT
.$M_PARSE_COMMAND
[SI] ;;AN000;; Get address of class
2114 ; $ELSE ;;AN000;; No, extended errors were specified
2117 CMP AX,$M_CRIT_LO
;;AN000;; Is this a critical error?
2118 ; $IF AE,AND ;;AN000;;
2120 CMP AX,$M_CRIT_HI
;;AN000;;
2121 ; $IF BE ;;AN000;; Yes,
2123 LES DI,DWORD PTR $M_RT
.$M_CRIT_ADDRS
[SI] ;;AN000;; Get address of class
2128 LES DI,DWORD PTR $M_RT
.$M_EXT_ERR_ADDRS
[SI] ;;AN000;; Get address of class
2137 CMP BX,$M_TERMINATING_FLAG
;;AN000;; Are we finished all classes?
2138 ; $IF E ;;AN000;; Yes,
2140 CMP DH,UTILITY_MSG_CLASS
;;AN000;; Was it a UTILITY class?
2141 ; $IF E ;;AN000;; Yes,
2143 STC ;;AN000;; Set the carry flag
2144 ; $ELSE ;;AN000;; No,
2147 MOV $M_RT
.$M_MSG_NUM
,AX ;;AN000;; Save message number
2148 MOV AX,$M_SPECIAL_MSG_NUM
;;AN000;; Set special message number
2149 MOV BP,$M_ONE_REPLACE
;;AN000;; Set one replace in message
2150 XOR SI,SI ;;AN000;; Reset the SI index to start again
2152 ; $ENDIF ;;AN000;; No,
2157 CMP BX,$M_CLASS_NOT_EXIST
;;AN000;; Does this class exist?
2158 ; $IF NE ;;AN001;; Yes,
2160 CALL $M_FIND_SPECIFIED_MSG
;;AN000;; Try to find the message
2163 ADD SI,$M_ADDR_SZ_FAR
;;AN000;; Get next class
2167 ; $LEAVE C ;;AN000;;
2169 OR CX,CX ;;AN000;; Was the message found?
2170 ; $ENDDO NZ,LONG ;;AN000;;
2176 PUSHF ;;AN006;; Save the flag state
2177 CMP DH,EXT_ERR_CLASS
;;AN006;; Was an extended error requested?
2178 ; $IF E ;;AN006;; Yes,
2180 PUSH DX ;;AN006;; Save all needed registers
2187 MOV AX,IFSFUNC_INSTALL_CHECK
;;AN006;; Check if IFSFUNC is installed
2189 CMP AL,IFSFUNC_INSTALLED
;;AN006;; Is it installed?
2190 POP AX ;;AN006;; Restore msg number
2191 ; $IF E ;;AN006;; Yes,
2193 MOV BX,AX ;;AN006;; BX is the extended error number
2194 MOV AX,IFS_GET_ERR_TEXT
;;AN006;; AX is the muliplex number
2195 INT 2FH
;;AN006;; Call IFSFUNC
2196 ; $ELSE ;;AN006;; No,
2199 STC ;;AN006;; Carry conditon
2203 ; $IF C ;;AN006;; Was there an update?
2205 POP DI ;;AN006;; No,
2206 POP ES ;;AN006;; Restore old pointer
2208 ; $ELSE ;;AN006;; Yes
2211 ADD SP,6 ;;AN006;; Throw away old pointer
2212 CALL $M_SET_LEN_IN_CX
;;AN006;; Get the length of the ASCIIZ string
2215 POP BP ;;AN006;; Restore other Regs
2219 $M_POPF
;;AN006;; Restore the flag state
2223 RET ;;AN000;; Return ES:DI pointing to the message
2225 $M_GET_MSG_ADDRESS ENDP
;;
2227 $M_SET_LEN_IN_CX PROC
NEAR ;;
2229 PUSH DI ;;AN006;; Save position
2231 MOV CX,-1 ;;AN006;; Set CX for decrements
2232 XOR AL,AL ;;AN006;; Prepare compare register
2233 REPNE SCASB ;;AN006;; Scan for zero
2234 NOT CX ;;AN006;; Change decrement into number
2235 DEC CX ;;AN006;; Don't include the zero
2237 POP DI ;;AN006;; Restore position
2240 $M_SET_LEN_IN_CX ENDP
;;
2242 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2244 ;; PROC NAME: $M_FIND_SPECIFIED_MSG
2246 ;; FUNCTION: To scan thru message headers until message is found
2247 ;; INPUTS: ES:DI points to beginning of msg headers
2248 ;; CX contains the number of messages in class
2249 ;; DH contains the message class
2250 ;; OUPUTS: IF CX = 0 THEN Message was not found
2251 ;; IF CX > 1 THEN ES:DI points to header of specified message
2253 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2255 $M_FIND_SPECIFIED_MSG PROC
NEAR ;;AN000;;
2257 CMP BX,1 ;;AN004;; Do we have an address to CALL?
2258 ; $IF E,AND ;;AN004;; Yes,
2260 CMP WORD PTR $M_RT
.$M_DISK_PROC_ADDR
,-1 ;;AN004;; Do we have an address to CALL?
2261 ; $IF NE ;;AN004;; Yes,
2263 CMP AX,$M_SPECIAL_MSG_NUM
;;AN004;; Are we displaying a default Ext Err?
2264 ; $IF E ;;AN004;; . . . and . . .
2266 PUSH AX ;;AN004;; Reset the special message number
2267 MOV AX,$M_RT
.$M_MSG_NUM
;;AN004;; Get the old message number
2268 CALL DWORD PTR $M_RT
.$M_DISK_PROC_ADDR
;;AN004;; Call the READ_DISK_PROC to get error text
2269 POP AX ;;AN004;; Reset the special message number
2270 ; $ELSE ;;AN004;; Get the old message number
2273 CALL DWORD PTR $M_RT
.$M_DISK_PROC_ADDR
;;AN004;; Call the READ_DISK_PROC to get error text
2274 ; $ENDIF ;;AN004;; Get the old message number
2279 XOR CX,CX ;;AN002;; CX = 0 will allow us to
2280 CMP DH,UTILITY_MSG_CLASS
;;AN001;;
2283 MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG
;;AN001;; Get number of messages in class
2288 CMP BYTE PTR ES:[DI].$M_CLASS_ID
,DH ;;AN002;; Check if class still exists at
2290 CMP BYTE PTR CS:[DI].$M_CLASS_ID
,DH ;;AN002;; Check if class still exists at
2292 ; $IF E ;;AN002;; pointer (hopefully)
2295 MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG
;;AN000;; Get number of messages in class
2297 MOV CL,BYTE PTR CS:[DI].$M_NUM_CLS_MSG
;;AN000;; Get number of messages in class
2299 ; $ENDIF ;;AN002;; go on to the next class
2303 ADD DI,$M_CLASS_ID_SZ
;;AN000;; Point past the class header
2304 STC ;;AN004;; Flag that we haven't found anything yet
2308 ; $IF C ;;AN004;; Have we found anything yet?
2310 CLC ;;AN004;; No, reset carry
2313 OR CX,CX ;;AN000;; Do we have any to check?
2314 ; $LEAVE Z ;;AN000;; No, return with CX = 0
2316 CMP DH,UTILITY_MSG_CLASS
;;AN001;;
2319 CMP AX,WORD PTR ES:[DI].$M_NUM
;;AN001;; Is this the message requested?
2324 CMP AX,WORD PTR ES:[DI].$M_NUM
;;AN000;; Is this the message requested?
2326 CMP AX,WORD PTR CS:[DI].$M_NUM
;;AN000;; Is this the message requested?
2330 ; $EXITIF E ;;AN000;;
2335 DEC CX ;;AN000;; No, well do we have more to check?
2336 ; $LEAVE Z ;;AN000;; No, return with CX = 0
2338 ADD DI,$M_ID_SZ
;;AN000;; Yes, skip past msg header
2339 ; $ENDLOOP ;;AN000;;
2343 ; $ENDSRCH ;;AN000;; Check next message
2345 ; $IF NC ;;AN000;; Did we find the message?
2347 CMP DH,UTILITY_MSG_CLASS
;;AN001;; Yes, is it a utility message?
2354 POP ES ;;AN000;; Return ES:DI pointing to the message
2358 ADD DI,WORD PTR ES:[DI].$M_TXT_PTR
;;AN000;; Prepare ES:DI pointing to the message
2363 ;; Yes, great we can return with CX > 0
2365 ; $IF NC ;;AN000;; Did we find the message?
2368 MOV CL,BYTE PTR ES:[DI] ;;AN000;; Move size into CX
2369 INC DI ;;AN000;; Increment past length
2373 MOV $M_RT
.$M_SIZE
,$M_NULL
;;AN004;; Reset variable
2374 RET ;;AN000;; Return
2376 $M_FIND_SPECIFIED_MSG ENDP
;;AN000;;
2378 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2379 ENDIF
;;AN000;; END of include of common subroutines
2381 IF $M_REPLACE
;;AN000;; Is the request to include the code for replaceable parms
2382 $M_REPLACE
= FALSE
;;AN000;; Tell the assembler we did
2384 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2385 $M_DISPLAY_REPLACE PROC
NEAR ;;AN000;;
2387 XOR BX,BX ;;AN000;; Use BX for buffer count
2389 CMP $M_SL
.$M_S_ID
,$M_SPECIAL_CASE
-30H
;;AN000;; Is this the special case (convert to ASCII)
2390 ; $IF E ;;AN000;; Yes,
2392 MOV WORD PTR $M_RT
.$M_TEMP_BUF
[BX],$M_SPACE_HYP
;;AN000;; Move in a " -"
2393 INC BX ;;AN000;; Increment count
2394 INC BX ;;AN000;; Increment count
2395 MOV BYTE PTR $M_RT
.$M_TEMP_BUF
[BX],$M_SPACE
;;AN000;; Move in a " "
2396 INC BX ;;AN000;; Increment count
2397 CALL $M_FLUSH_BUF
;;AN000;; Write out " - " to prepare for special case
2398 ; $ENDIF ;;AN000;; If it fails we will catch it later
2402 POP BP ;;AN000;; Remember the return address
2403 XOR BX,BX ;;AN000;; Use BX for buffer count
2404 XOR DX,DX ;;AN000;; Use DX for count of parms taken off the stack
2406 MOV $M_RT
.$M_SIZE
,CL ;;AN000;; Save size to later clear stack
2407 MOV AL,BYTE PTR $M_SL
.$M_S_MINW
;;AN000;; Get the minimum width
2409 CMP AL,CL ;;AN000;; Do we need pad chars added?
2410 ; $IF A ;;AN000;; Yes,
2412 SUB AL,CL ;;AN000;; Calculate how many pad chars are needed.
2413 MOV DH,AL ;;AN000;; Save the number of pad characters
2414 TEST BYTE PTR $M_SL
.$M_S_FLAG
,Right_Align
;;AN000;; Was replaceable parm to be right aligned?
2415 ; $IF NZ ;;AN000;; Yes,
2417 ; $DO ;;AN000;; Begin filling buffer with pad chars
2419 MOV AL,BYTE PTR $M_SL
.$M_S_PAD
;;AN000;;
2420 MOV BYTE PTR $M_RT
.$M_TEMP_BUF
[BX],AL ;;AN000;; Move in a pad char
2422 CMP BX,$M_TEMP_BUF_SZ
;;AN000;; Is buffer full?
2423 ; $IF E ;;AN000;; Yes,
2425 CALL $M_FLUSH_BUF
;;AN000;; Flush the buffer
2428 DEC DH ;;AN000;; Have we filled with enough pad chars?
2429 ; $ENDDO Z ;;AN000;; No, next pad character
2433 ; $ENDIF ;;AN000;; Yes,
2436 CMP BYTE PTR $M_SL
.$M_S_MAXW
,$M_UNLIM_W
;;AN000;; Is maximum width unlimited?
2439 CMP BYTE PTR $M_SL
.$M_S_MAXW
,CL ;;AN000;; Will we exceed maximum width?
2440 ; $IF B ;;AN000;; Yes,
2442 SUB CL,BYTE PTR $M_SL
.$M_S_MAXW
;;AN000;; Calculate how many extra chars
2443 MOV DL,CL ;;AN000;; Remember how many chars to pop off
2444 MOV CL,BYTE PTR $M_SL
.$M_S_MAXW
;;AN000;; Set new string length
2452 ; $DO ;;AN000;; Begin filling buffer with string
2454 TEST BYTE PTR $M_SL
.$M_S_FLAG
,NOT Char_Type
AND $M_TYPE_MASK
;;AN000;;
2455 ; $IF Z,AND ;;AN000;;
2457 TEST $M_SL
.$M_S_FLAG
,Char_field_ASCIIZ
AND $M_SIZE_MASK
; Is this replace a ASCIIZ string?
2458 ; $IF NZ ;;AN000;; Yes,
2460 MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get first character from string
2461 INC DI ;;AN000;; Next character in string
2462 ; $ELSE ;;AN000;; No,
2465 POP AX ;;AN000;; Get character in register
2468 MOV BYTE PTR $M_RT
.$M_TEMP_BUF
[BX],AL ;;AN000;; Move char into the buffer
2469 INC BX ;;AN000;; Increase buffer count
2470 CMP BX,$M_TEMP_BUF_SZ
;;AN000;; Is buffer full?
2471 ; $IF E ;;AN000;; Yes,
2473 CALL $M_FLUSH_BUF
;;AN000;; Flush the buffer
2476 DEC CL ;;AN000;; Have we completed replace?
2477 ; $ENDDO Z ;;AN000;; Test again
2482 TEST BYTE PTR $M_SL
.$M_S_FLAG
,Right_Align
;;AN000;; Was replaceable parm to be left aligned?
2483 ; $IF Z ;;AN000;; Yes,
2485 OR DH,DH ;;AN000;; Do we need pad chars added?
2486 ; $IF NZ ;;AN000;; Yes,
2488 ; $DO ;;AN000;; Begin filling buffer with pad chars
2490 MOV AL,BYTE PTR $M_SL
.$M_S_PAD
;;AN000;;
2491 MOV BYTE PTR $M_RT
.$M_TEMP_BUF
[BX],AL ;;AN000;; Move in a pad char
2493 CMP BX,$M_TEMP_BUF_SZ
;;AN000;; Is buffer full?
2494 ; $IF E ;;AN000;; Yes,
2496 CALL $M_FLUSH_BUF
;;AN000;; Flush the buffer
2499 DEC DH ;;AN000;; Have we filled with enough pad chars?
2500 ; $ENDDO Z ;;AN000;; Test again
2507 TEST BYTE PTR $M_SL
.$M_S_FLAG
,NOT Char_Type
AND $M_TYPE_MASK
;;AN000;;
2508 ; $IF Z,AND ;;AN000;;
2510 TEST $M_SL
.$M_S_FLAG
,Char_field_ASCIIZ
AND $M_SIZE_MASK
;;AN000;; Is this replace a ASCIIZ string?
2511 ; $IF NZ ;;AN000;; Yes,
2521 POP [$M_RT
.$M_RETURN_ADDR
] ;;AN000;; Clean Up stack using spare variable
2522 DEC DL ;;AN000;; Are we done?
2523 ; $ENDDO Z ;;AN000;;
2529 CALL $M_FLUSH_BUF
;;AN000;; Flush the buffer for the final time
2530 PUSH BP ;;AN000;; Restore the return address
2534 $M_DISPLAY_REPLACE ENDP
;;AN000;;
2536 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2538 ;; PROC NAME: $M_FLUSH_BUFFER
2540 ;; FUNCTION: Display the contents of the temporary buffer
2541 ;; INPUTS: DI contains the number of bytes to display
2542 ;; OUTPUTS: BX reset to zero
2546 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2548 $M_FLUSH_BUF PROC
NEAR ;;AN000;;
2550 PUSH CX ;;AN000;; Save changed regs
2553 PUSH DS ;;AN000;; Set ES pointing to buffer
2556 MOV CX,BX ;;AN000;; Set number of bytes to display
2557 XOR BX,BX ;;AN000;; Reset buffer counter
2558 LEA DI,$M_RT
.$M_TEMP_BUF
;;AN000;; Reset buffer location pointer
2559 CALL $M_DISPLAY_STRING
;;AN000;; Display the buffer
2561 ; $IF NC ;;AN000;; Error?
2563 POP DI ;;AN000;; No, Restore changed regs
2566 ; $ELSE ;;AN000;; Yes,
2569 ADD SP,6 ;;AN000;; Fix stack
2571 ; $ENDIF ;;AN000;; Error?
2574 RET ;;AN000;; Return
2576 $M_FLUSH_BUF ENDP
;;AN000;;
2579 IF CHARmsg
;;AN000;; Is the request to include the code for CHAR replace?
2580 $M_REPLACE
= TRUE
;;AN000;; Yes, THEN include it and flag that we will need common
2581 $M_CHAR_ONLY
= TRUE
;;AN000;; replacement code later
2582 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2584 ;; PROC NAME: $M_CHAR_REPLACE
2586 ;; FUNCTION: Will prepare a single char or ASCIIZ string for replace
2587 ;; INPUTS: DS:SI points at corresponding SUBLIST
2588 ;; ES:DI contains the VALUE from SUBLIST
2589 ;; OUTPUTS: CX contains number of characters on stack
2590 ;; Top of stack --> Last character
2592 ;; Bot of stack --> First character
2594 ;; OTHER REGS Revised: AX
2596 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2598 $M_CHAR_REPLACE PROC
NEAR ;;AN000;;
2600 POP BP ;;AN000;; Save return address
2601 TEST $M_SL
.$M_S_FLAG
,NOT Char_Field_Char
AND $M_SIZE_MASK
;;AN000;; Was Character specified?
2602 ; $IF Z ;;AN000;; Yes,
2604 MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get the character
2605 PUSH AX ;;AN000;; Put it on the stack
2606 INC CX ;;AN000;; Increase the count
2607 CALL $M_IS_IT_DBCS
;;AN000;; Is this the first byte of a DB character
2608 ; $IF C ;;AN000;; Yes,
2610 MOV AL,BYTE PTR ES:[DI]+1 ;;AN000;; Get the next character
2611 PUSH AX ;;AN000;; Put it on the stack
2612 CLC ;;AN000;; Clear the carry
2615 ; $ELSE ;;AN000;; No, it was an ASCIIZ string
2620 MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get the character
2621 OR AL,AL ;;AN000;; Is it the NULL?
2622 ; $LEAVE Z ;;AN000;; No,
2624 INC DI ;;AN000;; Next character
2625 INC CX ;;AN000;; Increment the count
2626 ; $ENDDO ;;AN000;; Yes,
2629 SUB DI,CX ;;AN000;; Set SI at the beginning of the string
2633 PUSH BP ;;AN000;; Restore return address
2634 RET ;;AN000;; Return
2636 $M_CHAR_REPLACE ENDP
;;AN000;;
2638 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2639 ENDIF
;;AN000;; END of include of CHAR replace code
2641 IF NUMmsg
;;AN000;; Is the request to include the code for NUM replace?
2642 $M_REPLACE
= TRUE
;;AN000;; Yes, THEN include it and flag that we will need common
2643 $M_CHAR_ONLY
= FALSE
;;AN000;; replacement code later
2644 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2646 ;; PROC NAME: $M_BIN2ASC_REPLACE
2648 ;; FUNCTION: Convert a signed or unsigned binary number to an ASCII string
2649 ;; and prepare to display
2650 ;; INPUTS: DS:SI points at corresponding SUBLIST
2651 ;; ES:DI contains the VALUE from SUBLIST
2652 ;; OUTPUTS: CX contains number of characters on stack
2653 ;; Top of stack --> Last character
2655 ;; Bot of stack --> First character
2656 ;; OTHER REGS Revised: BX,DX,AX
2658 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2660 $M_BIN2ASC_REPLACE PROC
NEAR ;;AN000;;
2662 POP BP ;;AN000;; Save return address
2664 XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH)
2665 XOR AX,AX ;;AN000;; Prepare for get binary value (LOW)
2666 MOV $M_RT
.$M_DIVISOR
,$M_BASE16
;;AN000;; Set default divisor
2667 XOR BX,BX ;;AN000;; Use BP as the NEG flag (if applicable)
2669 TEST $M_SL
.$M_S_FLAG
,NOT $M_BYTE
AND $M_SIZE_MASK
;;AN000;; Was BYTE specified?
2672 MOV AL, BYTE PTR ES:[DI] ;;AN000;; Setup byte in AL
2673 TEST $M_SL
.$M_S_FLAG
,NOT Sgn_Bin_Type
AND $M_TYPE_MASK
;;AN000;; Was Signed binary specified?
2676 TEST AL,10000000b ;;AN000;; Is this number negative?
2677 ; $IF NZ ;;AN000;; Yes,
2679 INC BX ;;AN000;; Remember that it was negative
2680 AND AL,01111111b ;;AN000;; Make it positive
2683 MOV $M_RT
.$M_DIVISOR
,$M_BASE10
;;AN000;;
2686 TEST $M_SL
.$M_S_FLAG
,NOT Unsgn_Bin_Type
AND $M_TYPE_MASK
;;AN000;; Was Signed binary specified?
2689 MOV $M_RT
.$M_DIVISOR
,$M_BASE10
;;AN000;;
2696 TEST $M_SL
.$M_S_FLAG
,NOT $M_WORD
AND $M_SIZE_MASK
;;AN000;; Was WORD specified?
2699 MOV AX, WORD PTR ES:[DI] ;;AN000;; Setup byte in AL
2700 TEST $M_SL
.$M_S_FLAG
,NOT Sgn_Bin_Type
AND $M_TYPE_MASK
;; AN000;; Was Signed binary specified?
2703 TEST AH,10000000b ;;AN000;; Is this number negative?
2704 ; $IF NZ ;;AN000;; Yes,
2706 INC BX ;;AN000;; Remember that it was negative
2707 AND AH,01111111b ;;AN000;; Make it positive
2710 MOV $M_RT
.$M_DIVISOR
,$M_BASE10
;;AN000;;
2713 TEST $M_SL
.$M_S_FLAG
,NOT Unsgn_Bin_Type
AND $M_TYPE_MASK
;;AN000;; Was Signed binary specified?
2716 MOV $M_RT
.$M_DIVISOR
,$M_BASE10
;;AN000;;
2723 MOV AX, WORD PTR ES:[DI] ;;AN000;; Setup Double word in DX:AX
2724 MOV DX, WORD PTR ES:[DI]+2 ;;AN000;;
2725 TEST $M_SL
.$M_S_FLAG
,NOT Sgn_Bin_Type
AND $M_TYPE_MASK
;;AN000;; Was Signed binary specified?
2728 TEST DH,10000000b ;;AN000;; Is this number negative?
2729 ; $IF NZ ;;AN000;; Yes,
2731 INC BX ;;AN000;; Remember that it was negative
2732 AND DH,01111111b ;;AN000;; Make it positive
2735 MOV $M_RT
.$M_DIVISOR
,$M_BASE10
;;AN000;;
2738 TEST $M_SL
.$M_S_FLAG
,NOT Unsgn_Bin_Type
AND $M_TYPE_MASK
;;AN000;; Was Signed binary specified?
2741 MOV $M_RT
.$M_DIVISOR
,$M_BASE10
;;AN000;;
2750 CALL $M_CONVERT2ASC
;;AN000;; Convert to ASCII string
2753 ; $IF NZ ;;AN000;; Was number negative?
2755 XOR DX,DX ;;AN000;; Yes,
2756 MOV DL,$M_NEG_SIGN
;;AN000;; Put "-" on the stack with the number
2758 ; $ENDIF ;;AN000;; No,
2762 PUSH BP ;;AN000;; Restore return address
2763 RET ;;AN000;; Return
2765 $M_BIN2ASC_REPLACE ENDP
;;AN000;;
2767 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2768 ENDIF
;;AN000;; END of include of NUM replace code
2770 IF DATEmsg
;;AN000;; Is the request to include the code for DATE replace?
2771 $M_REPLACE
= TRUE
;;AN000;; Yes, THEN include it and flag that we will need common
2772 $M_CHAR_ONLY
= FALSE
;;AN000;; replacement code later
2773 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2775 ;; PROC NAME: $M_DATE_REPLACE
2777 ;; FUNCTION: Convert a date to a decimal ASCII string using current
2778 ;; country format and prepare to display
2779 ;; INPUTS: DS:SI points at corresponding SUBLIST
2780 ;; ES:DI points at VALUE from SUBLIST
2781 ;; OUTPUTS: CX contains number of characters on stack
2782 ;; Top of stack --> Last character
2784 ;; Bot of stack --> First character
2785 ;; OTHER REGS Revised: DX, AX
2787 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2789 $M_DATE_REPLACE PROC
NEAR ;;AN000;;
2791 POP BP ;;AN000;; Save return address
2792 MOV $M_RT
.$M_DIVISOR
,$M_BASE10
;;AN000;; Set default divisor
2793 CALL $M_GET_DATE
;;AN000;; Set date format/separator in $M_RT
2795 XOR DX,DX ;;AN000;; Reset DX value
2796 XOR AX,AX ;;AN000;; Reset AX value
2797 CMP WORD PTR $M_RT
.$M_DATE_FORMAT
,0 ;;AN000;; USA Date Format
2798 ; $IF E ;;AN000;; Beginning from end: (saved on the stack)
2800 CALL $M_YEAR
;;AN000;; Get Year
2801 CALL $M_CONVERTDATE
;;AN000;; Convert it to an ASCII string
2802 PUSH WORD PTR $M_RT
.$M_DATE_SEPARA
;;AN000;;
2803 INC CX ;;AN000;; Increment count
2804 XOR AX,AX ;;AN000;; Reset AX value
2805 MOV AL,BYTE PTR $M_SL
.$M_S_VALUE
+3 ;;AN000;; Get Day
2806 CALL $M_CONVERTDATE
;;AN000;; Convert it to an ASCII string
2807 PUSH WORD PTR $M_RT
.$M_DATE_SEPARA
;;AN000;;
2808 INC CX ;;AN000;; Increment count
2809 MOV AL,BYTE PTR $M_SL
.$M_S_VALUE
+2 ;;AN000;; Get Month
2810 CALL $M_CONVERTDATE
;;AN000;; Convert it to an ASCII string
2814 CMP WORD PTR $M_RT
.$M_DATE_FORMAT
,1 ;;AN000;; EUROPE Date Format
2815 ; $IF E ;;AN000;; Beginning from end: (saved on the stack)
2817 CALL $M_YEAR
;;AN000;; Get Year
2818 CALL $M_CONVERTDATE
;;AN000;; Convert it to an ASCII string
2819 PUSH WORD PTR $M_RT
.$M_DATE_SEPARA
;;AN000;;
2821 XOR AX,AX ;;AN000;; Reset AX
2822 MOV AL,BYTE PTR $M_SL
.$M_S_VALUE
+2 ;;AN000;; Get Month
2823 CALL $M_CONVERTDATE
;;AN000;; Convert it to an ASCII string
2824 PUSH WORD PTR $M_RT
.$M_DATE_SEPARA
;;AN000;;
2826 MOV AL,BYTE PTR $M_SL
.$M_S_VALUE
+3 ;;AN000;; Get Day
2827 CALL $M_CONVERTDATE
;;AN000;; Convert it to an ASCII string
2831 CMP WORD PTR $M_RT
.$M_DATE_FORMAT
,2 ;;AN000;; JAPAN Date Format
2832 ; $IF E ;;AN000;; Beginning from end: (saved on the stack)
2834 MOV AL,BYTE PTR $M_SL
.$M_S_VALUE
+3 ;;AN000;; Get Day
2835 CALL $M_CONVERTDATE
;;AN000;; Convert it to an ASCII string
2836 PUSH WORD PTR $M_RT
.$M_DATE_SEPARA
;;AN000;;
2838 MOV AL,BYTE PTR $M_SL
.$M_S_VALUE
+2 ;;AN000;; Get Month
2839 CALL $M_CONVERTDATE
;;AN000;; Convert it to an ASCII string
2840 PUSH WORD PTR $M_RT
.$M_DATE_SEPARA
;;AN000;;
2842 CALL $M_YEAR
;;AN000;; Get Year
2843 CALL $M_CONVERTDATE
;;AN000;; Convert it to an ASCII string
2847 PUSH BP ;;AN000;; Restore return address
2848 RET ;;AN000;; Return
2850 $M_DATE_REPLACE ENDP
;;AN000;;
2852 $M_GET_DATE PROC
NEAR ;;AN000;;
2853 MOV AH,DOS_GET_COUNTRY
;;AN000;; Call DOS for country dependant info
2854 MOV AL,0 ;;AN000;; Get current country info
2855 LEA DX,$M_RT
.$M_TEMP_BUF
;;AN000;; Set up addressibility to buffer
2857 ; $IF C ;;AN000;; No,
2859 MOV WORD PTR $M_RT
.$M_DATE_FORMAT
,$M_DEF_DATE_FORM
;;AN000;; Set default date format (BH)
2860 MOV BYTE PTR $M_RT
.$M_DATE_SEPARA
,$M_DEF_DATE_SEP
;;AN000;; Set default date separator (BL)
2864 $M_GET_DATE ENDP
;;AN000;;
2866 $M_YEAR PROC
NEAR ;;AN000;;
2867 MOV AX,WORD PTR $M_SL
.$M_S_VALUE
;;AN000;; Get Year
2868 TEST $M_SL
.$M_S_FLAG
,Date_MDY_4
AND $M_DATE_MASK
;;AN000;; Was Month/Day/Year (2 Digits) specified?
2871 CMP AX,$M_MAX_2_YEAR
;;AN000;; Get Year
2874 MOV AX,$M_MAX_2_YEAR
;;AN000;;
2880 $M_YEAR ENDP
;;AN000;;
2882 $M_CONVERTDATE PROC
NEAR ;;AN000;;
2883 POP WORD PTR $M_RT
.$M_TEMP_BUF
;;AN000;; Save return address
2884 MOV $M_RT
.$M_SIZE
,CL ;;AN000;; Save the size before conversion
2885 CALL $M_CONVERT2ASC
;;AN000;; Convert it to an ASCII string
2886 DEC CX ;;AN000;; Test if size only grew by 1
2887 CMP CL,$M_RT
.$M_SIZE
;;AN000;; Did size only grow by one
2888 ; $IF E ;;AN000;; Yes,
2890 MOV AX,$M_TIMEDATE_PAD
;;AN000;; Get a pad character (0)
2891 PUSH AX ;;AN000;; Save it
2892 INC CX ;;AN000;; Count it
2895 INC CX ;;AN000;; Restore CX
2896 PUSH WORD PTR $M_RT
.$M_TEMP_BUF
;;AN000;; Save return address
2898 $M_CONVERTDATE ENDP
;;AN000;;
2900 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2901 ENDIF
;;AN000;; END of include of DATE replace code
2903 IF TIMEmsg
;;AN000;; Is the request to include the code for TIME replace?
2904 $M_REPLACE
= TRUE
;;AN000;; Yes, THEN include it and flag that we will need common
2905 $M_CHAR_ONLY
= FALSE
;;AN000;; replacement code later
2906 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2908 ;; PROC NAME: $M_TIME_REPLACE
2910 ;; FUNCTION: Convert a time to a decimal ASCII string
2911 ;; and prepare to display
2912 ;; INPUTS: DS:SI points at corresponding SUBLIST
2913 ;; ES:DI points at VALUE from SUBLIST
2914 ;; OUTPUTS: CX contains number of characters on stack
2915 ;; Top of stack --> Last character
2917 ;; Bot of stack --> First character
2918 ;; REGS USED: BP,CX,AX
2920 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2922 $M_TIME_REPLACE PROC
NEAR ;;AN000;;
2924 POP BP ;;AN000;; Save return address
2925 MOV $M_RT
.$M_DIVISOR
,$M_BASE10
;;AN000;; Set default divisor
2926 CALL $M_GET_TIME
;;AN000;; All O.K.?
2927 TEST $M_SL
.$M_S_FLAG
,Time_Cty_Type
AND $M_TIME_MASK
;;AN000;; Is this a request for current country info?
2928 ; $IF NZ ;;AN000;; Yes,
2930 CMP BYTE PTR $M_RT
.$M_TIME_FORMAT
,0 ;;AN000;; Is the current country format 12 Hour?
2931 ; $IF E ;;AN000;; Yes,
2933 MOV AL,BYTE PTR $M_SL
.$M_S_VALUE
;;AN000;; Get Hours
2934 CMP AL,12 ;;AN000;; Is hour 12 or less?
2935 ; $IF L,OR ;;AN000;; or
2937 CMP AL,23 ;;AN000;; Is hour 24 or greater?
2938 ; $IF G ;;AN000;; Yes,
2941 MOV AL,$M_AM
;;AN000;;
2942 PUSH AX ;;AN000;; Push an "a" to represent AM.
2944 ; $ELSE ;;AN000;; No,
2947 MOV AL,$M_PM
;;AN000;;
2948 PUSH AX ;;AN000;; Push an "p" to represent PM.
2959 TEST $M_SL
.$M_S_FLAG
,Time_HHMMSSHH_Cty
AND $M_SIZE_MASK
;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified?
2962 MOV AL,BYTE PTR $M_SL
.$M_S_VALUE
+3 ;;AN000;; Get Hundreds
2963 CALL $M_CONVERTTIME
;;AN000;;
2964 PUSH WORD PTR $M_RT
.$M_DECI_SEPARA
;;AN000;;
2968 TEST $M_SL
.$M_S_FLAG
,Time_HHMMSSHH_Cty
AND $M_SIZE_MASK
;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified?
2969 ; $IF NZ,OR ;;AN000;;
2971 TEST $M_SL
.$M_S_FLAG
,Time_HHMMSS_Cty
AND $M_SIZE_MASK
;;AN000;; Was Hour/Min/Sec (12 Hour) specified?
2975 MOV AL,BYTE PTR $M_SL
.$M_S_VALUE
+2 ;;AN000;; Get Seconds
2976 CALL $M_CONVERTTIME
;;AN000;;
2977 PUSH WORD PTR $M_RT
.$M_TIME_SEPARA
;;AN000;;
2981 ;; Do Hour/Min (12 Hour)
2982 MOV AL,BYTE PTR $M_SL
.$M_S_VALUE
+1 ;;AN000;; Get Minutes
2983 CALL $M_CONVERTTIME
;;AN000;;
2984 PUSH WORD PTR $M_RT
.$M_TIME_SEPARA
;;AN000;;
2987 MOV AL,BYTE PTR $M_SL
.$M_S_VALUE
;;AN000;; Get Hours
2988 TEST $M_SL
.$M_S_FLAG
,Time_Cty_Type
AND $M_TIME_MASK
;;AN000;; Is this a request for current country info?
2989 ; $IF NZ ;;AN000;; Yes,
2991 CMP BYTE PTR $M_RT
.$M_TIME_FORMAT
,0 ;;AN000;; Is the current country format 12 Hour?
2992 ; $IF E ;;AN000;; Yes,
2994 CMP AL,13 ;;AN000;; Is hour less than 12?
2995 ; $IF GE ;;AN000;; Yes,
2997 SUB AL,12 ;;AN000;; Set to a 12 hour value
3000 CMP AL,0 ;;AN000;; Is hour less than 12?
3001 ; $IF E ;;AN000;; Yes,
3003 MOV AL,12 ;;AN000;; Set to a 12 hour value
3010 CALL $M_CONVERT2ASC
;;AN000;; Convert it to ASCII
3012 PUSH BP ;;AN000;; Restore return address
3013 RET ;;AN000;; Return
3015 $M_TIME_REPLACE ENDP
;;AN000;;
3017 $M_GET_TIME PROC
NEAR ;;AN000;;
3018 MOV AH,DOS_GET_COUNTRY
;;AN000;; Call DOS for country dependant info
3019 MOV AL,0 ;;AN000;; Get current country info
3020 LEA DX,$M_RT
.$M_TEMP_BUF
;;AN000;; Set up addressibility to buffer
3022 ; $IF C ;;AN000;; No,
3024 MOV WORD PTR $M_RT
.$M_TIME_FORMAT
,$M_DEF_TIME_FORM
;;AN000;; Set default time format (BH)
3025 MOV BYTE PTR $M_RT
.$M_TIME_SEPARA
,$M_DEF_TIME_SEP
;;AN000;; Set default time separator (BL)
3026 MOV BYTE PTR $M_RT
.$M_DECI_SEPARA
,$M_DEF_DECI_SEP
;;AN000;; Set default time separator (BL)
3030 $M_GET_TIME ENDP
;;AN000;;
3032 $M_CONVERTTIME PROC
NEAR ;;AN000;;
3033 POP WORD PTR $M_RT
.$M_TEMP_BUF
;;AN000;; Save return address
3034 MOV $M_RT
.$M_SIZE
,CL ;;AN000;; Save the size before conversion
3035 CALL $M_CONVERT2ASC
;;AN000;; Convert it to an ASCII string
3036 DEC CX ;;AN000;; Test if size only grew by 1
3037 CMP CL,$M_RT
.$M_SIZE
;;AN000;; Did size only grow by one
3038 ; $IF E ;;AN000;; Yes,
3040 MOV AX,$M_TIMEDATE_PAD
;;AN000;; Get a pad character (0)
3041 PUSH AX ;;AN000;; Save it
3042 INC CX ;;AN000;; Count it
3045 INC CX ;;AN000;; Restore CX
3046 PUSH WORD PTR $M_RT
.$M_TEMP_BUF
;;AN000;; Save return address
3048 $M_CONVERTTIME ENDP
;;AN000;;
3050 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3051 ENDIF
;;AN000;; END of include of TIME replace
3052 ENDIF
;;AN000;; END of include of Replacement common code
3054 IF INPUTmsg
;;AN000;; Is the request to include the code for NUM replace?
3055 INPUTmsg
= FALSE
;;AN000;; Yes, THEN include it and reset the flag
3056 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3058 ;; PROC NAME: $M_WAIT_FOR_INPUT
3060 ;; FUNCTION: To accept keyed input and return extended key value
3062 ;; INPUTS: DL contains the DOS function requested for input
3063 ;; OUPUTS: AX contains the extended key value that was read
3066 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3068 $M_WAIT_FOR_INPUT PROC
NEAR ;;AN000;;
3070 PUSH CX ;;AN000;; Save CX
3071 PUSH DX ;;AN000;; Save DX
3072 PUSH DS ;;AN000;; Save Data segment
3074 CMP DL,DOS_CLR_KEYB_BUF_MASK
;;AN001;; Are we to clear the keyboard buffer?
3075 ; $IF A ;;AN001;; Yes,
3077 MOV AL,DL ;;AN001;; Mov function into AL
3078 AND AL,LOW_NIB_MASK
;;AN001;; Mask out the C in high nibble
3079 MOV AH,DOS_CLR_KEYB_BUF
;;AN001;; Set input function
3080 ; $ELSE ;;AN001;; No,
3083 MOV AH,DL ;;AN000;; Put DOS function in AH
3086 PUSH ES ;;AN000;; Get output buffer segment
3088 MOV DX,DI ;;AN000;; Get output buffer offset in case needed
3089 INT 21H
;;AN000;; Get keyboard input
3092 CMP DL,DOS_BUF_KEYB_INP
;;AN000;;
3094 ; $IF NE ;;AN000;; If character input
3096 CALL $M_IS_IT_DBCS
;;AN000;; Is this character DBCS?
3099 MOV CL,AL ;;AN000;; Save first character
3100 MOV AH,DL ;;AN001;; Get back function
3101 INT 21H
;;AN000;; Get keyboard input
3102 MOV AH,CL ;;AN000;; Retreive first character AX = xxxx
3103 CLC ;;AN000;; Clear carry condition
3107 MOV AH,0 ;;AN000;; AX = 00xx where xx is SBCS
3121 STC ;;AN000;; Reset carry flag
3124 RET ;;AN000;; Return
3126 $M_WAIT_FOR_INPUT ENDP
;;AN000;;
3128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3129 ENDIF
;;AN000;; END of include of Wait for Input
3130 ENDIF
;;AN000;; END of include of SYSDISPMSG
3131 ENDIF
;;AN000;; END of include of MSG_DATA_ONLY
3132 ENDIF
;;AN000;; END of include of Structure only