Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2628 lines
109 KiB

  1. ; * * * * * * * * * * * * START OF SPECIFICATIONS * * * * * * * * * * * * * * *
  2. ;
  3. ; MODULE NAME: MSGSERV.SAL
  4. ;
  5. ; DESCRIPTIVE NAME: Message Services SALUT file
  6. ;
  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.
  10. ;
  11. ; ENTRY POINT: Since this a collection of subroutines, entry point is at
  12. ; requested procedure.
  13. ;
  14. ; INPUT: Since this a collection of subroutines, input is dependent on function
  15. ; requested.
  16. ;
  17. ; EXIT-NORMAL: In all cases, CARRY FLAG = 0
  18. ;
  19. ; EXIT-ERROR: In all cases, CARRY FLAG = 1
  20. ;
  21. ; INTERNAL REFERENCES: (list of included subroutines)
  22. ;
  23. ; - SYSLOADMSG
  24. ; - SYSDISPMSG
  25. ; - SYSGETMSG
  26. ;
  27. ;
  28. ; EXTERNAL REFERENCES: None
  29. ;
  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
  32. ; of the utility.
  33. ;
  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.
  37. ;
  38. ; REVISION HISTORY: Created MAY 1987
  39. ;
  40. ; Label: DOS - - Message Retriever
  41. ; (c) Copyright 1988 Microsoft
  42. ;
  43. ;
  44. ; * * * * * * * * * * * * END OF SPECIFICATIONS * * * * * * * * * * * * * * * *
  45. ; Page
  46. $SALUT $M (2,5,22,62) ;;AN000;; Set SALUT formatting
  47. IF $M_STRUC ;;AN000;; IF we haven't included the structures yet THEN
  48. $M_STRUC = FALSE ;;AN000;; Let the assembler know that we have
  49. ;;AN000;; and include them
  50. PAGE
  51. SUBTTL DOS - Message Retriever - MSGSTR.INC Module
  52. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  53. ;;
  54. ;; STRUCTURE: $M_SUBLIST_STRUC
  55. ;;
  56. ;; Replacable parameters are described by a sublist structure
  57. ;;
  58. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  59. ;;
  60. $M_SUBLIST_STRUC STRUC ;;AN000;;
  61. ;;
  62. $M_S_SIZE DB 11 ;;AN000;; SUBLIST size (PTR to next SUBLIST)
  63. $M_S_RESV DB 0 ;;AN000;; RESERVED
  64. $M_S_VALUE DD ? ;;AN000;; Time, Date or PTR to data item
  65. $M_S_ID DB ? ;;AN000;; n of %n
  66. $M_S_FLAG DB ? ;;AN000;; Data-type flags
  67. $M_S_MAXW DB ? ;;AN000;; Maximum field width
  68. $M_S_MINW DB ? ;;AN000;; Minimum field width
  69. $M_S_PAD DB ? ;;AN000;; Character for Pad field
  70. ;;
  71. $M_SUBLIST_STRUC ENDS ;;AN000;;
  72. ;;
  73. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  74. ;;
  75. ;; STRUCTURE: $M_CLASS_ID
  76. ;;
  77. ;; Each class will be defined by this structure.
  78. ;;
  79. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  80. ;;
  81. $M_CLASS_ID STRUC ;;AN000;;
  82. ;;
  83. $M_CLS_ID DB -1 ;;AN000;; Class identifer
  84. $M_COMMAND_VER DW EXPECTED_VERSION ;;AN003;; COMMAND.COM version check
  85. $M_NUM_CLS_MSG DB 0 ;;AN000;; Total number of message in class
  86. ;;
  87. $M_CLASS_ID ENDS ;;
  88. ;;AN000;;
  89. $M_CLASS_ID_SZ EQU SIZE $M_CLASS_ID ;;AN000;;
  90. ;;
  91. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  92. ;;
  93. ;; STRUCTURE: $M_ID_STRUC
  94. ;;
  95. ;; Each message will be defined by this structure.
  96. ;;
  97. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  98. ;;
  99. $M_ID STRUC ;;AN000;;
  100. ;;
  101. $M_NUM DW -1 ;;AN000;; Message Number
  102. $M_TXT_PTR DW ? ;;AN000;; Pointer to message text
  103. ;;
  104. $M_ID ENDS ;;AN000;;
  105. ;;AN000;; Status Flag Values:
  106. $M_ID_SZ EQU SIZE $M_ID ;;AN000;;
  107. ;;
  108. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  109. ;;
  110. ;; STRUCTURE: $M_RES_ADDRS
  111. ;;
  112. ;; Resident data area definition of variables
  113. ;;
  114. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  115. ;;
  116. $M_RES_ADDRS STRUC ;;AN000;;
  117. ;;
  118. $M_EXT_ERR_ADDRS DD 0 ;;AN000;; Allow pointers to THREE Extended error locations
  119. $M_EXT_FILE DD 0 ;;AN001;;
  120. $M_EXT_COMMAND DD 0 ;;AN000;;
  121. $M_EXT_TERM DD -1 ;;AN000;;
  122. $M_PARSE_COMMAND DD 0 ;;AN000;;
  123. $M_PARSE_ADDRS DD 0 ;;AN000;; Allow pointers to TWO Parse error locations
  124. $M_PARSE_TERM DD -1 ;;AN000;;
  125. $M_CRIT_ADDRS DD 0 ;;AN000;; Allow pointers to TWO Critical error locations
  126. $M_CRIT_COMMAND DD 0 ;;AN000;;
  127. $M_CRIT_TERM DD -1 ;;AN000;;
  128. $M_DISK_PROC_ADDR DD -1 ;;AN004;; Address of READ_DISK_PROC
  129. $M_CLASS_ADDRS DD $M_NUM_CLS DUP(0) ;;AN000;; Allow pointers to specified classes
  130. $M_CLS_TERM DD -1 ;;AN000;;
  131. $M_DBCS_VEC DD 0 ;;AN000;; Save DBCS vector
  132. $M_HANDLE DW ? ;;AN000;;
  133. $M_SIZE DB 0 ;;AN000;;
  134. $M_CRLF DB 0DH,0AH ;;AN004;; CR LF message
  135. $M_CLASS DB ? ;;AN004;; Saved class
  136. $M_RETURN_ADDR DW ? ;;AN000;;
  137. $M_MSG_NUM DW $M_NULL ;;AN000;;
  138. $M_DIVISOR DW 10 ;;AN000;; Default = 10 (must be a WORD for division)
  139. $M_TEMP_BUF DB $M_TEMP_BUF_SZ DUP("$") ;;AN000;; Temporary buffer
  140. $M_BUF_TERM DB "$" ;;AN000;;
  141. $M_RES_ADDRS ENDS ;;AN000;;
  142. ;;
  143. $M_RES_ADDRS_SZ EQU SIZE $M_RES_ADDRS ;;AN000;;
  144. ;;
  145. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  146. ;;
  147. ;; STRUCTURE: $M_COUNTRY_INFO
  148. ;;
  149. ;; Important fields of the Get Country Information call
  150. ;;
  151. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  152. ;;
  153. $M_COUNTRY_INFO STRUC ;;AN000;; Expected Country infomation
  154. ;;
  155. $M_HEADER DB $M_RES_ADDRS_SZ-$M_TEMP_BUF_SZ-1 DUP(?) ;;AN000;; Go past first part of struc
  156. $M_DATE_FORMAT DW ? ;;AN000;; <------- Date Format
  157. $M_CURR_SEPARA DB 5 DUP(?) ;;AN000;;
  158. $M_THOU_SEPARA DB ?,0 ;;AN000;; <------- Thou Separator
  159. $M_DECI_SEPARA DB ?,0 ;;AN000;; <------- Decimal Separator
  160. $M_DATE_SEPARA DB ?,0 ;;AN000;; <------- Date Separator
  161. $M_TIME_SEPARA DB ?,0 ;;AN000;; <------- Time Separator
  162. $M_CURR_FORMAT DB ? ;;AN000;;
  163. $M_SIG_DIGS_CU DB ? ;;AN000;;
  164. $M_TIME_FORMAT DB ? ;;AN000;; <------- Time Format
  165. ;;
  166. $M_COUNTRY_INFO ENDS ;;AN000;;
  167. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  168. ;;
  169. ELSE ;;AN000;; ELSE if we have already included the STRUCTURES
  170. ;
  171. $SALUT $M (2,5,13,62) ;;AN000;; Set SALUT formatting for code section
  172. IF MSGDATA ;;AN000;; IF this is a request to include the data area
  173. MSGDATA = FALSE ;;AN000;; Let the assembler know not to include it again
  174. ;;AN000;; and include it
  175. PAGE
  176. SUBTTL DOS - Message Retriever - MSGRES.TAB Module
  177. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  178. ;;
  179. ;; DATA NAME: $M_RES_TABLE
  180. ;;
  181. ;; REFERENCE LABEL: $M_RT
  182. ;;
  183. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  184. ;;
  185. IF COMR ;;AN000;; Since COMMAND.COM includes this twice
  186. $M_RT EQU $M_RT2 ;;AN000;; we must redefine the label so no
  187. $M_RT2 LABEL BYTE ;;AN000;; assembly errors occur
  188. $M_ALTLABEL = TRUE ;;AN000;; Flag that label was changed
  189. ELSE ;;AN000;;
  190. $M_RT LABEL BYTE ;;AN000;;
  191. ENDIF ;;AN000;;
  192. $M_RES_ADDRS <> ;;AN000;; Resident addresses
  193. ;;
  194. include COPYRIGH.INC ;;AN001;; Include Copyright 1988 Microsoft
  195. ;;
  196. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  197. ENDIF ;;AN000;; END of include of Data table
  198. ;
  199. IF NOT $M_MSGDATA_ONLY ;;AN000;; IF this was a request for only the data table THEN
  200. ;; don't include any more code
  201. ;;AN000;; Figure out what other code to include
  202. IF DISK_PROC ;;AN003;; Is the request to include the READ_DISK code
  203. IF COMR ;;AN003;; (Only Resident COMMAND.COM should ask for it)
  204. $M_RT EQU $M_RT2 ;;AN003;;
  205. ENDIF
  206. DISK_PROC = FALSE ;;AN003;; Yes, THEN include it and reset flag
  207. PAGE
  208. SUBTTL DOS - Message Retriever - DISK_PROC Module
  209. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  210. ;;
  211. ;; PROC NAME: DISK_PROC
  212. ;;
  213. ;; FUNCTION: Used in COMMAND.COM if we need to access the Parse or Extended
  214. ;; errors from disk\diskette
  215. ;; INPUTS: AX has the message number
  216. ;; DX has the message class
  217. ;; AND ... the COMMAND.COM Variable RESGROUP:COMSPEC is
  218. ;; assumed to be set!!
  219. ;;
  220. ;; OUTPUTS: ES:DI points to message length (BYTE) followed by text
  221. ;;
  222. ;;
  223. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  224. ;;
  225. PUBLIC READ_DISK_PROC ;;
  226. ;;
  227. READ_DISK_PROC PROC FAR ;;AN003;;
  228. PUSH AX ;;AN003;; Save everything
  229. PUSH BX ;;AN003;;
  230. PUSH DX ;;AN003;;
  231. PUSH SI ;;AN003;;
  232. PUSH BP ;;AN003;;
  233. PUSH DS ;;AN003;;
  234. PUSH DI ;;AN003;;
  235. MOV BP,AX ;;AN003;; Save message number
  236. MOV AX,DOS_EXTENDED_OPEN ;;AN003;; Set INT 21 function
  237. LEA SI,RESGROUP:COMSPEC ;;AN003;; Get addressibilty to COMMAND.COM
  238. PUSH CS ;;AN003;;
  239. POP DS ;;AN003;;
  240. MOV DI,-1 ;;AN003;; No extended attribute list
  241. MOV BX,NO_CRIT_OPEN ;;AN003;; Don't generate critical error
  242. MOV DX,NOT_EX_FAIL_EX_OPEN ;;AN003;; Open Flag
  243. INT 21H ;;AN003;; Open the file
  244. POP DI ;;AN003;; Retreive LSEEK pointer
  245. ;;AN003;; Error ?
  246. $IF NC,LONG ;;AN003;; No,
  247. PUSH DI ;;AN003;; Save LSEEK pointer
  248. MOV BX,AX ;;AN003;; Set handle in BX
  249. MOV AX,DOS_LSEEK_FILE ;;AN003;; LSEEK to the errors
  250. XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM
  251. MOV DX,DI ;;AN003;;
  252. INT 21H ;;AN003;; LSEEK the file
  253. POP DX ;;AN003;; Retreive LSEEK pointer
  254. ;;AN003;; Error ?
  255. $IF NC ;;AN003;; No,
  256. INC CX ;;AN003;; Set flag to first pass
  257. $DO ;;AN003;;
  258. PUSH DX ;;AN003;; Save LSEEK pointer
  259. PUSH CX ;;AN003;; Save first pass flag
  260. PUSH AX ;;AN003;; Save number of messages (if set yet)
  261. XOR SI,SI ;;AN003;; Reset buffer index
  262. MOV AH,DOS_READ_BYTE ;;AN003;; Read
  263. MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the first part of the header
  264. LEA DX,$M_RT.$M_TEMP_BUF ;;AN003;; into the temp buffer
  265. INT 21H ;;AN003;; Read it
  266. MOV DI,DX ;;AN003;;
  267. POP AX ;;AN003;;
  268. POP CX ;;AN003;;
  269. OR CX,CX ;;AN003;;
  270. $IF NZ ;;AN003;;
  271. XOR CX,CX ;;AN003;; Set flag to second pass
  272. XOR AH,AH ;;AN003;; Get number of messages in class
  273. MOV AL,DS:[DI].$M_NUM_CLS_MSG ;;AN003;;
  274. MOV SI,$M_CLASS_ID_SZ ;;AN003;; Initialize index
  275. CMP DS:[DI].$M_COMMAND_VER,EXPECTED_VERSION ;;AN003;; Is this the right version of COMMAND.COM?
  276. $ENDIF ;;AN003;;
  277. POP DX ;;AN003;;
  278. $IF Z ;;AN003;; Yes,
  279. $SEARCH ;;AN003;;
  280. CMP BP,WORD PTR $M_RT.$M_TEMP_BUF[SI] ;;AN003;; Is this the message I'm looking for?
  281. $EXITIF Z ;;AN003;; Yes, (ZF=1)
  282. CLC ;;AN003;; Reset carry, exit search
  283. $ORELSE ;;AN003;; No, (ZF=0)
  284. ADD SI,$M_ID_SZ ;;AN003;; Increment index
  285. ADD DX,$M_ID_SZ ;;AN003;; Add offset of first header
  286. DEC AX ;;AN003;; Decrement # of messages left
  287. $LEAVE Z ;;AN003;; Have we exhausted all messages?
  288. CMP SI,$M_TEMP_BUF_SZ-1 ;;AN003;; No, Have we exhausted the buffer?
  289. $ENDLOOP A ;;AN003;; No, Check next message (ZF=1)
  290. STC ;;AN003;; Yes, (ZF=0) set error (ZF=0)
  291. $ENDSRCH ;;AN003;;
  292. $ELSE ;;AN003;; No,
  293. XOR CX,CX ;;AN003;; Set Zero flag to exit READ Loop
  294. STC ;;AN003;; Set Carry
  295. $ENDIF ;;AN003;;
  296. $ENDDO Z ;;AN003;; Get next buffer full if needed
  297. ;;AN003;; Error ?
  298. $IF NC ;;AN003;; No,
  299. MOV AX,DOS_LSEEK_FILE ;;AN003;; Prepare to LSEEK to the specific message
  300. XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM
  301. ADD DX,$M_CLASS_ID_SZ ;;AN003;; Add offset of first header
  302. ADD DX,WORD PTR $M_RT.$M_TEMP_BUF[SI]+2 ;;AN003;; Add offset from msg structure
  303. INT 21H ;;AN003;; LSEEK the file
  304. MOV AH,DOS_READ_BYTE ;;AN003;; Read
  305. MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the message
  306. LEA DX,$M_RT.$M_TEMP_BUF ;;AN003;; into the temp buffer
  307. INT 21H ;;AN003;; Read it
  308. MOV DI,DX ;;AN003;; into the temp buffer
  309. PUSH DS ;;AN003;; into the temp buffer
  310. POP ES ;;AN003;; into the temp buffer
  311. $ENDIF ;;AN003;;
  312. $ENDIF ;;AN003;;
  313. PUSHF ;;AN003;; Close file handle
  314. MOV AH,DOS_CLOSE_FILE ;;AN003;; Close file handle
  315. INT 21H ;;AN003;;
  316. $M_POPF ;;AN003;;
  317. $ENDIF ;;AN003;; Yes there was an error,
  318. POP DS ;;AN003;;
  319. POP BP ;;AN003;;
  320. POP SI ;;AN003;;
  321. POP DX ;;AN003;;
  322. POP BX ;;AN003;;
  323. POP AX ;;AN003;;
  324. ;;AN003;; abort everything
  325. RET ;;AN003;;
  326. READ_DISK_PROC ENDP ;;AN003;;
  327. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  328. ENDIF ;;AN003;; END of include for DISK_PROC
  329. ;
  330. IF SETSTDIO ;;AN000;; Is the request to include the code for SETSTDIO
  331. SETSTDIO = FALSE ;;AN000;; Yes, THEN include it and reset flag
  332. PAGE
  333. SUBTTL DOS - Message Retriever - SETSTDIO Module
  334. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  335. ;;
  336. ;; PROC NAME: SETSTDIO
  337. ;;
  338. ;; FUNCTION:
  339. ;; INPUTS:
  340. ;;
  341. ;; OUPUTS:
  342. ;;
  343. ;;
  344. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  345. ;;
  346. IF FARmsg ;AN001;
  347. SETSTDINON PROC FAR ;AN001;
  348. ELSE ;AN001;
  349. SETSTDINON PROC NEAR ;AN001;
  350. ENDIF ;AN001;
  351. PUSH AX ;AN002; Save changed regs
  352. PUSH BX ;AN002;
  353. PUSH DX ;AN002;
  354. MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL
  355. MOV BX,STDIN ;AN001;
  356. XOR DX,DX ;AN001;
  357. INT 21H ;AN001;
  358. OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit
  359. MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL
  360. INT 21H ;AN001;
  361. POP DX ;AN002; Restore Regs
  362. POP BX ;AN002;
  363. POP AX ;AN002;
  364. RET ;AN001;
  365. ;AN001;
  366. SETSTDINON ENDP ;AN001;
  367. IF FARmsg ;AN001;
  368. SETSTDINOFF PROC FAR ;AN001;
  369. ELSE ;AN001;
  370. SETSTDINOFF PROC NEAR ;AN001;
  371. ENDIF ;AN001;
  372. PUSH AX ;AN002; Save changed regs
  373. PUSH BX ;AN002;
  374. PUSH DX ;AN002;
  375. MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL
  376. MOV BX,STDIN ;AN001;
  377. XOR DX,DX ;AN001;
  378. INT 21H ;AN001;
  379. AND DH,NOT $M_CRIT_ERR_MASK ;AN001; Turn off bit
  380. MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL
  381. INT 21H ;AN001;
  382. POP DX ;AN002; Restore Regs
  383. POP BX ;AN002;
  384. POP AX ;AN002;
  385. RET ;AN001;
  386. SETSTDINOFF ENDP ;AN001;
  387. IF FARmsg ;AN001;
  388. SETSTDOUTON PROC FAR ;AN001;
  389. ELSE ;AN001;
  390. SETSTDOUTON PROC NEAR ;AN001;
  391. ENDIF ;AN001;
  392. PUSH AX ;AN002; Save changed regs
  393. PUSH BX ;AN002;
  394. PUSH DX ;AN002;
  395. MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL
  396. MOV BX,STDOUT ;AN001;
  397. XOR DX,DX ;AN001;
  398. INT 21H ;AN001;
  399. OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit
  400. MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL
  401. INT 21H ;AN001;
  402. POP DX ;AN002; Restore Regs
  403. POP BX ;AN002;
  404. POP AX ;AN002;
  405. RET ;AN001;
  406. SETSTDOUTON ENDP ;AN001;
  407. IF FARmsg ;AN001;
  408. SETSTDOUTOFF PROC FAR ;AN001;
  409. ELSE ;AN001;
  410. SETSTDOUTOFF PROC NEAR
  411. ENDIF ;AN001;
  412. PUSH AX ;AN002; Save changed regs
  413. PUSH BX ;AN002;
  414. PUSH DX ;AN002;
  415. MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL
  416. MOV BX,STDOUT ;AN001;
  417. XOR DX,DX ;AN001;
  418. INT 21H ;AN001;
  419. AND DH,NOT $M_CRIT_ERR_MASK ;AN001; Turn off bit
  420. MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL
  421. INT 21H ;AN001;
  422. POP DX ;AN002; Restore Regs
  423. POP BX ;AN002;
  424. POP AX ;AN002;
  425. RET ;AN001;
  426. SETSTDOUTOFF ENDP ;AN001;
  427. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  428. ENDIF ;;AN000;; END of include for SETSTDIO
  429. ;
  430. IF LOADmsg ;;AN000;; Is the request to include the code for SYSLOADMSG ?
  431. IF COMR ;;AN000;;
  432. $M_RT EQU $M_RT2 ;;AN000;;
  433. ENDIF
  434. LOADmsg = FALSE ;;AN000;; Yes, THEN include it and reset flag
  435. PAGE
  436. SUBTTL DOS - Message Retriever - LOADMSG.ASM Module
  437. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  438. ;;
  439. ;; PROC NAME: SYSLOADMSG
  440. ;;
  441. ;; FUNCTION:
  442. ;; INPUTS:
  443. ;;
  444. ;; OUPUTS:
  445. ;;
  446. ;;
  447. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  448. ;;
  449. IF FARmsg ;;AN000;;
  450. SYSLOADMSG PROC FAR ;;AN000;;
  451. ELSE ;;AN000;;
  452. SYSLOADMSG PROC NEAR ;;AN000;;
  453. ENDIF ;;AN000;;
  454. PUSH AX ;;AN000;
  455. PUSH BX ;;AN000;
  456. PUSH DX ;;AN000;
  457. PUSH ES ;;AN000;
  458. PUSH DI ;;AN000;
  459. XOR CX,CX ;;AN000; Reset to zero
  460. MOV ES,CX ;;AN000;
  461. XOR DI,DI ;;AN000;
  462. MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface
  463. MOV DL,DOS_GET_EXTENDED ;;AN000;; Where are the Extended errors in COMMAND.COM
  464. INT 2FH ;;AN000;; Private interface
  465. MOV WORD PTR $M_RT.$M_EXT_COMMAND+2,ES ;;AN000;; Move into first avaliable table location
  466. MOV WORD PTR $M_RT.$M_EXT_COMMAND,DI ;;AN000;;
  467. ;;
  468. MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface
  469. MOV DL,DOS_GET_PARSE ;;AN000;; Where are the Parse errors in COMMAND.COM
  470. INT 2FH ;;AN000;; Private interface
  471. MOV WORD PTR $M_RT.$M_PARSE_COMMAND+2,ES ;;AN000;; Move into first avaliable table location
  472. MOV WORD PTR $M_RT.$M_PARSE_COMMAND,DI ;;AN000;;
  473. ;;
  474. MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface
  475. MOV DL,DOS_GET_CRITICAL ;;AN000;; Where are the Critical errors in COMMAND.COM
  476. INT 2FH ;;AN000;; Private interface
  477. MOV WORD PTR $M_RT.$M_CRIT_COMMAND+2,ES ;;AN000;; Move into first avaliable table location
  478. MOV WORD PTR $M_RT.$M_CRIT_COMMAND,DI ;;AN000;;
  479. MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface
  480. MOV DL,DOS_GET_FILE ;;AN001;; Where are the FILE dependant in IFSFUNC.EXE
  481. INT 2FH ;;AN001;; Private interface
  482. MOV WORD PTR $M_RT.$M_EXT_FILE+2,ES ;;AN001;; Move into first avaliable table location
  483. MOV WORD PTR $M_RT.$M_EXT_FILE,DI ;;AN001;;
  484. IF COMR ;; ** Special case for RESIDENT COMMAND.COM
  485. IF2
  486. IFNDEF READ_DISK_INFO ;;AN003;;
  487. Extrn READ_DISK_PROC:Far ;;AN003;;
  488. ENDIF ;;AN003;;
  489. ENDIF ;;AN003;;
  490. ELSE ;;
  491. IF FARmsg ;;AN000;;
  492. CALL FAR PTR $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors)
  493. ELSE ;;AN000;;
  494. CALL $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors)
  495. ENDIF ;;AN000;;
  496. MOV WORD PTR $M_RT.$M_EXT_ERR_ADDRS+2,ES ;;AN000;; Move into first avaliable table location
  497. MOV WORD PTR $M_RT.$M_EXT_ERR_ADDRS,DI ;;AN000;;
  498. MOV WORD PTR $M_RT.$M_CRIT_ADDRS+2,ES ;;AN000;; Move into first avaliable table location
  499. MOV WORD PTR $M_RT.$M_CRIT_ADDRS,DI ;;AN000;;
  500. ;;
  501. IF FARmsg ;;AN000;;
  502. CALL FAR PTR $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors)
  503. ELSE ;;AN000;;
  504. CALL $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors)
  505. ENDIF ;;AN000;;
  506. MOV WORD PTR $M_RT.$M_PARSE_ADDRS+2,ES ;;AN000;; Move into first avaliable table location
  507. MOV WORD PTR $M_RT.$M_PARSE_ADDRS,DI ;;AN000;;
  508. ENDIF ;;
  509. ;;
  510. MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface
  511. MOV DL,DOS_GET_ADDR ;;AN001;; Where is the READ_DISK_PROC in COMMAND.COM
  512. INT 2FH ;;AN001;; Private interface
  513. MOV WORD PTR $M_RT.$M_DISK_PROC_ADDR+2,ES ;;AN001;; Move into first avaliable table location
  514. MOV WORD PTR $M_RT.$M_DISK_PROC_ADDR,DI ;;AN001;;
  515. $M_BUILD_PTRS %$M_NUM_CLS ;;AN000;; Build all utility classes
  516. ;;AN000;;
  517. CALL $M_GET_DBCS_VEC ;;AN000;; Save the DBCS vector
  518. IF NOT NOCHECKSTDIN ;;AN000;; IF EOF check is not to be suppressed
  519. CALL $M_CHECKSTDIN ;;AN000;; Set EOF CHECK
  520. ENDIF ;;AN000;;
  521. ;;AN000;;
  522. IF NOT NOCHECKSTDOUT ;;AN000;; IF Disk Full check is not to be suppressed
  523. CALL $M_CHECKSTDOUT ;;AN000;; Set Disk Full CHECK
  524. ENDIF ;;AN000;;
  525. ;;AN000;;
  526. IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed
  527. CLC ;;AN000;; Make sure carry is clear
  528. ELSE ;;AN000;; ELSE
  529. PUSH CX ;;AN000;;
  530. CALL $M_VERSION_CHECK ;;AN000;; Check Version
  531. ENDIF ;;AN000;;
  532. ;; Error ?
  533. $IF NC ;;AN000;; No.
  534. IF NOT NOVERCHECKmsg ;;AN000;; IF version check was not supressed
  535. POP CX ;;AN000;; Reset stack
  536. ENDIF ;;AN000;;
  537. POP DI ;;AN000;; Restore REGS
  538. POP ES ;;AN000;;
  539. POP DX ;;AN000;;
  540. POP BX ;;AN000;;
  541. POP AX ;;AN000;;
  542. $ELSE ;;AN000;; Yes,
  543. IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed
  544. ADD SP,10 ;;AN000;;
  545. STC ;;AN000;; Reset carry flag
  546. ELSE ;;AN000;; IF version check is to be supressed
  547. ADD SP,12 ;;AN000;;
  548. STC ;;AN000;; Reset carry flag
  549. ENDIF ;;AN000;; IF version check is to be supressed
  550. $ENDIF ;;AN000;;
  551. RET ;;AN000;;
  552. ;;
  553. SYSLOADMSG ENDP ;;AN000;;
  554. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  555. PAGE
  556. SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc
  557. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  558. ;;
  559. ;; Proc Name: $M_GET_DBCS_VEC
  560. ;;
  561. ;; Function: Get the DBCS vector and save it for later use
  562. ;;
  563. ;; Inputs: None
  564. ;;
  565. ;; Outputs: None
  566. ;;
  567. ;; Regs Changed:
  568. ;;
  569. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  570. ;;
  571. $M_GET_DBCS_VEC PROC NEAR ;;AN000;;
  572. ;;
  573. PUSH AX ;;AN000;; Save character to check
  574. PUSH SI ;;AN000;;
  575. PUSH DS ;;AN000;;
  576. MOV AX,DOS_GET_DBCS_INFO ;;AN000;; DOS function to get DBSC environment
  577. INT 21H ;;AN000;; Get environment pointer
  578. PUSH DS ;;AN000;; Get environment pointer
  579. POP ES ;;AN000;; Get environment pointer
  580. POP DS ;;AN000;; Get environment pointer
  581. $IF NC ;;AN000;;
  582. MOV WORD PTR $M_RT.$M_DBCS_VEC,SI ;;AN000;; Save DBCS Vector
  583. MOV WORD PTR $M_RT.$M_DBCS_VEC+2,ES ;;AN000;;
  584. $ENDIF ;;AN000;;
  585. POP SI ;;AN000;;
  586. POP AX ;;AN000;; Retrieve character to check
  587. RET ;;AN000;; Return
  588. ;;
  589. $M_GET_DBCS_VEC ENDP ;;
  590. ;;
  591. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  592. IF NOCHECKSTDIN ;AN001; Are we suppose to include the code for Checking EOF ?
  593. ELSE ;AN001; Yes, THEN include it
  594. PAGE
  595. SUBTTL DOS - Message Retriever - $M_CHECKSTDIN Proc
  596. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  597. ;;
  598. ;; Proc Name: $M_CHECKSTDIN
  599. ;;
  600. ;; Function:
  601. ;;
  602. ;; Inputs: None
  603. ;;
  604. ;; Outputs:
  605. ;;
  606. ;; Regs Changed:
  607. ;;
  608. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  609. ;;
  610. $M_CHECKSTDIN PROC NEAR ;AN001;
  611. MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL
  612. MOV BX,STDIN ;AN001;
  613. XOR DX,DX ;AN001;
  614. INT 21H ;AN001;
  615. OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit
  616. MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL
  617. INT 21H ;AN001;
  618. RET ;AN001;
  619. $M_CHECKSTDIN ENDP ;AN001;
  620. ;;
  621. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  622. ENDIF ;AN001; END of include for EOF Check
  623. IF NOCHECKSTDOUT ;AN001; Are we suppose to include the code for Checking Disk Full?
  624. ELSE ;AN001; Yes, THEN include it
  625. PAGE
  626. SUBTTL DOS - Message Retriever - $M_CHECKSTDOUT Proc
  627. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  628. ;;
  629. ;; Proc Name: $M_CHECKSTDOUT
  630. ;;
  631. ;; Function:
  632. ;;
  633. ;; Inputs: None
  634. ;;
  635. ;; Outputs:
  636. ;;
  637. ;; Regs Changed:
  638. ;;
  639. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  640. ;;
  641. $M_CHECKSTDOUT PROC NEAR ;AN001;
  642. MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL
  643. MOV BX,STDOUT ;AN001;
  644. XOR DX,DX ;AN001;
  645. INT 21H ;AN001;
  646. OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit
  647. MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL
  648. INT 21H ;AN001;
  649. RET ;AN001;
  650. $M_CHECKSTDOUT ENDP ;AN001;
  651. ;;
  652. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  653. ENDIF ;AN001; END of include for Disk Full Check
  654. IF NOVERCHECKmsg ;;AN000;; Are we suppose to include the code for DOS version check?
  655. ELSE ;;AN000;; Yes, THEN include it
  656. PAGE
  657. SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc
  658. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  659. ;;
  660. ;; Proc Name: $M_VERSION_CHECK
  661. ;;
  662. ;; Function: Determine if DOS version is within allowable limits
  663. ;;
  664. ;; Inputs: None
  665. ;;
  666. ;; Outputs: CARRY_FLAG = 1 if Incorrect DOS version
  667. ;; Registers set for SYSDISPMSG
  668. ;; CARRY_FLAG = 0 if Correct DOS version
  669. ;;
  670. ;; Regs Changed: AX
  671. ;;
  672. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  673. ;;
  674. $M_VERSION_CHECK PROC NEAR ;;AN000;;
  675. ;;
  676. MOV AH,DOS_GET_VERSION ;;AN000;; Check that version matches VERSIONA.INC
  677. INT 21H ;;AN000;;
  678. ;;
  679. CMP AX,EXPECTED_VERSION ;;AN000;; IF DOS_MAJOR is correct
  680. $IF E ;;AN000;;
  681. CLC ;;AN000;; Clear the carry flag
  682. $ELSE ;;AN000;; ELSE
  683. IF NOT COMR ;; ** Special case for RESIDENT COMMAND.COM
  684. CMP AX,LOWEST_4CH_VERSION ;;AN000;; Does this version support AH = 4CH
  685. $IF B ;;AN000;; No,
  686. MOV BX,NO_HANDLE ;;AN000;; No handle (version doesn't support)
  687. $ELSE ;;AN000;; Yes,
  688. MOV BX,STDERR ;;AN000;; Standard Error
  689. $ENDIF ;;AN000;;
  690. ELSE
  691. MOV BX,NO_HANDLE ;;AN000;; No handle
  692. ENDIF
  693. MOV AX,1 ;;AN000;; Set message # 1
  694. MOV CX,NO_REPLACE ;;AN000;; No replacable parms
  695. MOV DL,NO_INPUT ;;AN000;; No input
  696. MOV DH,UTILITY_MSG_CLASS ;;AN000;; Utility class message
  697. STC ;;AN000;; Set Carry Flag
  698. $ENDIF ;;AN000;;
  699. ;;
  700. RET ;;AN000;; Return
  701. ;;
  702. $M_VERSION_CHECK ENDP ;;
  703. ;;
  704. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  705. ENDIF ;;AN000;; END of include for DOS version check
  706. ENDIF ;;AN000;; END of include for SYSLOADMSG
  707. ;
  708. IF GETmsg ;;AN000;; Is the request to include the code for SYSGETMSG ?
  709. IF COMR ;;AN000;;
  710. $M_RT EQU $M_RT2 ;;AN000;;
  711. ENDIF ;;AN000;;
  712. GETmsg = FALSE ;;AN000;; Yes, THEN include it and reset flag
  713. PAGE
  714. SUBTTL DOS - Message Retriever - GETMSG.ASM Module
  715. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  716. ;;
  717. ;; Proc Name: SYSGETMSG
  718. ;;
  719. ;; Function: The GET service returns the segment, offset and size of the
  720. ;; message text to the caller based on a message number.
  721. ;; The GET function will not display the message thus assumes
  722. ;; caller will handle replaceable parameters.
  723. ;;
  724. ;; Inputs:
  725. ;;
  726. ;; Outputs:
  727. ;;
  728. ;; Psuedocode:
  729. ;; Call $M_GET_MSG_ADDRESS
  730. ;; IF MSG_NUM exists THEN
  731. ;; Set DS:SI = MSG_TXT_PTR + 1
  732. ;; CARRY_FLAG = 0
  733. ;; ELSE
  734. ;; CARRY_FLAG = 1
  735. ;; ENDIF
  736. ;;
  737. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  738. ;;
  739. IF FARmsg ;;AN000;;
  740. SYSGETMSG PROC FAR ;;AN000;;
  741. ELSE ;;AN000;;
  742. SYSGETMSG PROC NEAR ;;AN000;;
  743. ENDIF ;;AN000;;
  744. ;;
  745. ;; Save registers needed later
  746. PUSH AX ;;AN000;; Save changed regs
  747. PUSH ES ;;AN000;;
  748. PUSH DI ;;AN000;;
  749. PUSH BP ;;AN000;;
  750. ;;
  751. IF FARmsg ;;AN000;;
  752. CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message
  753. ELSE ;;AN000;;
  754. CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message
  755. ENDIF ;;AN000;; Return message in ES:DI
  756. $IF NC ;;AN000;; Message found?
  757. CMP DH,UTILITY_MSG_CLASS
  758. CLC ;;AN000;;
  759. $IF NE
  760. PUSH ES ;;AN000;;
  761. POP DS ;;AN000;; Return message in DS:SI
  762. $ELSE
  763. IF FARmsg ;;AN000;; Yes,
  764. PUSH ES ;;AN000;;
  765. POP DS ;;AN000;; Return message in DS:SI
  766. ELSE ;;AN000;;
  767. PUSH CS ;;AN000;; Return message in DS:SI
  768. POP DS ;;AN000;;
  769. ENDIF ;;AN000;;
  770. $ENDIF ;;AN000;;
  771. MOV SI,DI ;;AN000;; Return message in DS:SI
  772. $ENDIF ;;AN000;;
  773. ;;
  774. POP BP ;;AN000;; Restore changed regs
  775. POP DI ;;AN000;;
  776. POP ES ;;AN000;;
  777. POP AX ;;AN000;;
  778. ;;
  779. RET ;;AN000;; Return
  780. ;;
  781. SYSGETMSG ENDP ;;
  782. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  783. IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet
  784. $M_SUBS = FALSE ;;AN000;; No, then include and reset the flag
  785. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  786. ;;
  787. ;; PROC NAME: $M_GET_MSG_ADDRESS
  788. ;;
  789. ;; FUNCTION: To scan thru classes to return pointer to the message header
  790. ;; INPUTS: Access to $M_RES_ADDRESSES
  791. ;; OUPUTS: IF CX = 0 THEN Message was not found
  792. ;; IF CX > 1 THEN ES:DI points to the specified message
  793. ;; REGS CHANGED: ES,DI,CX
  794. ;;
  795. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  796. ;;
  797. IF FARmsg ;;AN000;;
  798. $M_GET_MSG_ADDRESS PROC FAR ;;AN000;;
  799. ELSE ;;AN000;;
  800. $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;;
  801. ENDIF ;;AN000;;
  802. ;;
  803. PUSH SI ;;AN000;;
  804. PUSH BX ;;AN000;;
  805. XOR SI,SI ;;AN000;; Use SI as an index
  806. XOR CX,CX ;;AN000;; Use CX as an size
  807. $DO ;;AN000;;
  808. CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested?
  809. $IF E ;;AN000;; Yes,
  810. IF FARmsg ;;AN000;;
  811. LES DI,DWORD PTR $M_RT.$M_CLASS_ADDRS[SI] ;;AN000;; Get address of class
  812. MOV BX,ES ;;AN000;
  813. ELSE ;;AN000;;
  814. MOV DI,WORD PTR $M_RT.$M_CLASS_ADDRS[SI] ;;AN000;; Get address of class
  815. MOV BX,DI ;;AN000;
  816. ENDIF ;;AN000;;
  817. $ELSE ;;AN000;; No,
  818. TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested?
  819. $IF NE ;;AN000;; Yes,
  820. LES DI,DWORD PTR $M_RT.$M_PARSE_COMMAND[SI] ;;AN000;; Get address of class
  821. MOV BX,ES ;;AN000;
  822. $ELSE ;;AN000;; No, extended errors were specified
  823. CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error?
  824. $IF AE,AND ;;AN000;;
  825. CMP AX,$M_CRIT_HI ;;AN000;;
  826. $IF BE ;;AN000;; Yes,
  827. LES DI,DWORD PTR $M_RT.$M_CRIT_ADDRS[SI] ;;AN000;; Get address of class
  828. MOV BX,ES ;;AN000;
  829. $ELSE ;;AN000;;
  830. LES DI,DWORD PTR $M_RT.$M_EXT_ERR_ADDRS[SI] ;;AN000;; Get address of class
  831. MOV BX,ES ;;AN000;
  832. $ENDIF ;;AN000;;
  833. $ENDIF ;;AN000;;
  834. $ENDIF ;;AN000;;
  835. ;;
  836. CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes?
  837. $IF E ;;AN000;; Yes,
  838. CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class?
  839. $IF E ;;AN000;; Yes,
  840. STC ;;AN000;; Set the carry flag
  841. $ELSE ;;AN000;; No,
  842. MOV $M_RT.$M_MSG_NUM,AX ;;AN000;; Save message number
  843. MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number
  844. MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message
  845. XOR SI,SI ;;AN000;; Reset the SI index to start again
  846. CLC ;;AN000;;
  847. $ENDIF ;;AN000;; No,
  848. $ELSE ;;AN000;;
  849. CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist?
  850. $IF NE ;;AN001;; Yes,
  851. CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message
  852. $ENDIF ;;AN000;;
  853. ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class
  854. CLC ;;AN000;;
  855. $ENDIF ;;AN000;;
  856. $LEAVE C ;;AN000;;
  857. OR CX,CX ;;AN000;; Was the message found?
  858. $ENDDO NZ,LONG ;;AN000;;
  859. PUSHF ;;AN006;; Save the flag state
  860. CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested?
  861. $IF E ;;AN006;; Yes,
  862. PUSH DX ;;AN006;; Save all needed registers
  863. PUSH BP ;;AN006;;
  864. PUSH CX ;;AN006;;
  865. PUSH ES ;;AN006;;
  866. PUSH DI ;;AN006;;
  867. PUSH AX ;;AN006;;
  868. MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed
  869. INT 2FH ;;AN006;;
  870. CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed?
  871. POP AX ;;AN006;; Restore msg number
  872. $IF E ;;AN006;; Yes,
  873. MOV BX,AX ;;AN006;; BX is the extended error number
  874. MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number
  875. INT 2FH ;;AN006;; Call IFSFUNC
  876. $ELSE ;;AN006;; No,
  877. STC ;;AN006;; Carry conditon
  878. $ENDIF ;;AN006;;
  879. $IF C ;;AN006;; Was there an update?
  880. POP DI ;;AN006;; No,
  881. POP ES ;;AN006;; Restore old pointer
  882. POP CX ;;AN006;;
  883. $ELSE ;;AN006;; Yes
  884. ADD SP,6 ;;AN006;; Throw away old pointer
  885. CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string
  886. $ENDIF ;;AN006;;
  887. POP BP ;;AN006;; Restore other Regs
  888. POP DX ;;AN006;;
  889. $ENDIF ;;AN006;;
  890. $M_POPF ;;AN006;; Restore the flag state
  891. POP BX ;;AN000;;
  892. POP SI ;;AN000;;
  893. RET ;;AN000;; Return ES:DI pointing to the message
  894. ;;
  895. $M_GET_MSG_ADDRESS ENDP ;;
  896. ;;
  897. $M_SET_LEN_IN_CX PROC NEAR ;;
  898. ;;
  899. PUSH DI ;;AN006;; Save position
  900. PUSH AX ;;AN006;;
  901. MOV CX,-1 ;;AN006;; Set CX for decrements
  902. XOR AL,AL ;;AN006;; Prepare compare register
  903. REPNE SCASB ;;AN006;; Scan for zero
  904. NOT CX ;;AN006;; Change decrement into number
  905. DEC CX ;;AN006;; Don't include the zero
  906. POP AX ;;AN006;;
  907. POP DI ;;AN006;; Restore position
  908. RET ;;AN006;;
  909. ;;
  910. $M_SET_LEN_IN_CX ENDP ;;
  911. ;;
  912. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  913. ;;
  914. ;; PROC NAME: $M_FIND_SPECIFIED_MSG
  915. ;;
  916. ;; FUNCTION: To scan thru message headers until message is found
  917. ;; INPUTS: ES:DI points to beginning of msg headers
  918. ;; CX contains the number of messages in class
  919. ;; DH contains the message class
  920. ;; OUPUTS: IF CX = 0 THEN Message was not found
  921. ;; IF CX > 1 THEN ES:DI points to header of specified message
  922. ;;
  923. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  924. ;;
  925. $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;;
  926. ;;
  927. CMP BX,1 ;;AN004;; Do we have an address to CALL?
  928. $IF E,AND ;;AN004;; Yes,
  929. CMP WORD PTR $M_RT.$M_DISK_PROC_ADDR,-1 ;;AN004;; Do we have an address to CALL?
  930. $IF NE ;;AN004;; Yes,
  931. CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err?
  932. $IF E ;;AN004;; . . . and . . .
  933. PUSH AX ;;AN004;; Reset the special message number
  934. MOV AX,$M_RT.$M_MSG_NUM ;;AN004;; Get the old message number
  935. CALL DWORD PTR $M_RT.$M_DISK_PROC_ADDR ;;AN004;; Call the READ_DISK_PROC to get error text
  936. POP AX ;;AN004;; Reset the special message number
  937. $ELSE ;;AN004;; Get the old message number
  938. CALL DWORD PTR $M_RT.$M_DISK_PROC_ADDR ;;AN004;; Call the READ_DISK_PROC to get error text
  939. $ENDIF ;;AN004;; Get the old message number
  940. $ELSE ;;AN004;;
  941. XOR CX,CX ;;AN002;; CX = 0 will allow us to
  942. CMP DH,UTILITY_MSG_CLASS ;;AN001;;
  943. $IF NE ;;AN001;;
  944. MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG ;;AN001;; Get number of messages in class
  945. $ELSE ;;AN001;;
  946. IF FARmsg ;;AN001;;
  947. CMP BYTE PTR ES:[DI].$M_CLASS_ID,DH ;;AN002;; Check if class still exists at
  948. ELSE
  949. CMP BYTE PTR CS:[DI].$M_CLASS_ID,DH ;;AN002;; Check if class still exists at
  950. ENDIF
  951. $IF E ;;AN002;; pointer (hopefully)
  952. IF FARmsg ;;AN001;;
  953. MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class
  954. ELSE
  955. MOV CL,BYTE PTR CS:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class
  956. ENDIF
  957. $ENDIF ;;AN002;; go on to the next class
  958. $ENDIF ;;AN001;;
  959. ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header
  960. STC ;;AN004;; Flag that we haven't found anything yet
  961. $ENDIF ;;AN004;;
  962. $IF C ;;AN004;; Have we found anything yet?
  963. CLC ;;AN004;; No, reset carry
  964. $SEARCH ;;AN000;;
  965. OR CX,CX ;;AN000;; Do we have any to check?
  966. $LEAVE Z ;;AN000;; No, return with CX = 0
  967. CMP DH,UTILITY_MSG_CLASS ;;AN001;;
  968. $IF NE ;;AN001;;
  969. CMP AX,WORD PTR ES:[DI].$M_NUM ;;AN001;; Is this the message requested?
  970. $ELSE ;;AN001;;
  971. IF FARmsg ;;AN001;;
  972. CMP AX,WORD PTR ES:[DI].$M_NUM ;;AN000;; Is this the message requested?
  973. ELSE
  974. CMP AX,WORD PTR CS:[DI].$M_NUM ;;AN000;; Is this the message requested?
  975. ENDIF
  976. $ENDIF
  977. $EXITIF E ;;AN000;;
  978. $ORELSE ;;AN000;
  979. DEC CX ;;AN000;; No, well do we have more to check?
  980. $LEAVE Z ;;AN000;; No, return with CX = 0
  981. ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header
  982. $ENDLOOP ;;AN000;;
  983. STC ;;AN000;;
  984. $ENDSRCH ;;AN000;; Check next message
  985. $IF NC ;;AN000;; Did we find the message?
  986. CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message?
  987. CLC ;;AN001;;
  988. $IF E ;;AN001;;
  989. IF FARmsg ;;AN001;;
  990. ELSE ;;AN000;;
  991. PUSH CS ;;AN000;;
  992. POP ES ;;AN000;; Return ES:DI pointing to the message
  993. ENDIF
  994. $ENDIF ;;AN001;;
  995. ADD DI,WORD PTR ES:[DI].$M_TXT_PTR ;;AN000;; Prepare ES:DI pointing to the message
  996. $ENDIF ;;AN004;;
  997. $ENDIF ;;AN004;;
  998. ;; Yes, great we can return with CX > 0
  999. $IF NC ;;AN000;; Did we find the message?
  1000. XOR CH,CH ;;AN000;;
  1001. MOV CL,BYTE PTR ES:[DI] ;;AN000;; Move size into CX
  1002. INC DI ;;AN000;; Increment past length
  1003. $ENDIF ;;AN004;;
  1004. MOV $M_RT.$M_SIZE,$M_NULL ;;AN004;; Reset variable
  1005. RET ;;AN000;; Return
  1006. ;;
  1007. $M_FIND_SPECIFIED_MSG ENDP ;;AN000;;
  1008. ;;
  1009. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1010. ENDIF ;;AN000;; END of include of common subroutines
  1011. ENDIF ;;AN000;; END of include of SYSGETMSG
  1012. ;
  1013. IF DISPLAYmsg ;;AN000;; Is the request to include the code for SYSGETMSG ?
  1014. IF COMR ;;AN000;;
  1015. $M_RT EQU $M_RT2 ;;AN000;;
  1016. ENDIF ;;AN000;;
  1017. DISPLAYmsg = FALSE ;;AN000;; Yes, THEN include it and reset flag
  1018. PAGE
  1019. SUBTTL DOS - Message Retriever - DISPMSG.ASM Module
  1020. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1021. ;;
  1022. ;; Proc Name: SYSDISPMSG
  1023. ;;
  1024. ;; Function: The DISPLAY service will output a defined message to a handle
  1025. ;; requested by the caller. It also provides function to display
  1026. ;; messages when handles are not applicable (ie. DOS function calls
  1027. ;; 00h to 0Ah) Replaceable parameters are allowed and are
  1028. ;; defined previous to entry.
  1029. ;;
  1030. ;; It is assumes that a PRELOAD function has already determined
  1031. ;; the addressibilty internally to the message retriever services.
  1032. ;; Inputs:
  1033. ;;
  1034. ;; Outputs:
  1035. ;;
  1036. ;; Psuedocode:
  1037. ;; Save registers needed later
  1038. ;; Get address of the message requested
  1039. ;; IF Message number exists THEN
  1040. ;; IF replacable parameters were specified THEN
  1041. ;; Display message with replacable parms
  1042. ;; ELSE
  1043. ;; Display string without replacable parms
  1044. ;; ENDIF
  1045. ;; IF character input was requested THEN
  1046. ;; Wait for character input
  1047. ;; ENDIF
  1048. ;; Clear CARRY FLAG
  1049. ;; ELSE
  1050. ;; Set CARRY FLAG
  1051. ;; ENDIF
  1052. ;; Return
  1053. ;;
  1054. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1055. ;;
  1056. IF FARmsg ;;AN000;;
  1057. SYSDISPMSG PROC FAR ;;AN000;;
  1058. ELSE ;;AN000;;
  1059. SYSDISPMSG PROC NEAR ;;AN000;;
  1060. ENDIF ;;AN000;;
  1061. ;;
  1062. ;; Save registers and values needed later
  1063. PUSH AX ;;AN000;; Save changed REGs
  1064. PUSH BX ;;AN000;;
  1065. PUSH CX ;;AN000;;
  1066. PUSH BP ;;AN000;;
  1067. PUSH DI ;;AN000;; Save pointer to input buffer (offset)
  1068. PUSH ES ;;AN000;; Save pointer to input buffer (segment)
  1069. PUSH DX ;;AN000;; Save Input/Class request
  1070. MOV BP,CX ;;AN000;; Use BP to hold replace count
  1071. MOV WORD PTR $M_RT.$M_HANDLE,BX ;;AN000;; Save handle
  1072. MOV BYTE PTR $M_RT.$M_CLASS,DH ;;AN004;; Save class
  1073. ;; Get address of the message requested
  1074. IF FARmsg ;;AN000;;
  1075. CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message
  1076. ELSE ;;AN000;;
  1077. CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message
  1078. ENDIF ;;AN000;;
  1079. OR CX,CX ;;AN000;; Was message found?
  1080. $IF NZ ;;AN000;; YES, Message address in ES:DI
  1081. ;; Test if replacable parameters were specified
  1082. OR BP,BP ;;AN000;; Were replacable parameters requested
  1083. $IF Z ;;AN000;;
  1084. ;; Display string without replacable parms
  1085. CALL $M_DISPLAY_STRING ;;AN000;; No, great . . . Display message
  1086. $ELSE ;;AN000;;
  1087. IF $M_REPLACE ;;AN000;;
  1088. ;; Display message with replacable parms
  1089. CALL $M_DISPLAY_MESSAGE ;;AN000;; Display the message with substitutions
  1090. ENDIF ;;AN000;;
  1091. $ENDIF ;;AN000;;
  1092. $IF NC
  1093. POP DX ;;AN000;; Get Input/Class request
  1094. CALL $M_ADD_CRLF ;;AN004;; Check if we need to add the CR LF chars.
  1095. POP ES ;;AN000;; Get location of input buffer (if specified)
  1096. POP DI ;;AN000;;
  1097. ;; Test if character input was requested
  1098. IF INPUTmsg ;;AN000;;
  1099. OR DL,DL ;;AN000;; Was Wait-For-Input requested?
  1100. $IF NZ ;;AN000;;
  1101. CALL $M_WAIT_FOR_INPUT ;;AN000;;
  1102. $ENDIF ;;AN000;;
  1103. ENDIF ;;AN000;;
  1104. $ELSE ;;AN000;;
  1105. ADD SP,6 ;;AN000;;
  1106. STC ;;AN000;; Reset carry flag
  1107. $ENDIF ;;AN000;;
  1108. $ELSE ;;AN000;; No,
  1109. POP ES ;;AN000;; Get pointer to input buffer (segment)
  1110. POP DI ;;AN000;; Get base pointer to first sublist (offset)
  1111. POP DX ;;AN000;; Get base pointer to first sublist (segment)
  1112. STC ;;AN000;; Set carry flag
  1113. $ENDIF ;;AN000;;
  1114. ;;
  1115. $IF NC ;;AN000;; Was there an error?
  1116. POP BP ;;AN000;; No,
  1117. POP CX ;;AN000;;
  1118. POP BX ;;AN000;;
  1119. IF INPUTmsg ;;AN000;;
  1120. ADD SP,2 ;;AN000;;
  1121. ELSE ;AN000;
  1122. POP AX ;;AN000;;
  1123. ENDIF ;;AN000;;
  1124. $ELSE ;;AN000;; Yes,
  1125. ADD SP,8 ;;AN000;; Eliminate from stack
  1126. STC ;;AN000;;
  1127. $ENDIF ;;AN000;;
  1128. ;;
  1129. RET ;;AN000;; Return
  1130. ;;
  1131. SYSDISPMSG ENDP ;;AN000;;
  1132. ;;
  1133. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1134. ;
  1135. ;;
  1136. ;; PROC NAME: $M_DISPLAY_STRING
  1137. ;;
  1138. ;; FUNCTION: Will display or write string
  1139. ;; INPUTS: ES:DI points to beginning of message
  1140. ;; CX contains the length of string to write (if applicable)
  1141. ;; OUTPUTS: None
  1142. ;; REGS Revised: None
  1143. ;;
  1144. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1145. ;;
  1146. $M_DISPLAY_STRING PROC NEAR ;;AN000;;
  1147. ;;
  1148. PUSH AX ;;AN000;;
  1149. PUSH BX ;;AN000;;
  1150. PUSH DX ;;AN000;;
  1151. ;;
  1152. MOV BX,$M_RT.$M_HANDLE ;;AN000;; Retrieve handle
  1153. ;;
  1154. IF COMR ;; ** Special case for RESIDENT COMMAND.COM
  1155. CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string
  1156. ELSE
  1157. CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified?
  1158. $IF E ;;AN000;;
  1159. CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string
  1160. $ELSE ;;AN000;;
  1161. CALL $M_DISPLAY_H_STRING ;;AN000;; Yes, display string to handle
  1162. $ENDIF ;;AN000;;
  1163. ;AN001;
  1164. $IF C ;;AN000;; Was there an error?
  1165. MOV AH,DOS_GET_EXT_ERROR ;;AN000;; Yes,
  1166. MOV BX,DOS_GET_EXT_ERROR_BX ;;AN000;; Get extended error
  1167. INT 21H ;;AN000;;
  1168. XOR AH,AH ;;AN000;; Clear AH
  1169. ADD SP,6 ;;AN000;; Clean up stack
  1170. STC ;;AN000;; Flag that there was an error
  1171. $ELSE ;;AN000;; No,
  1172. CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified?
  1173. $IF NE ;;AN000;;
  1174. CMP AX,CX ;AN001; Was it ALL written?
  1175. $IF NE ;AN001; No,
  1176. CALL $M_GET_EXT_ERR_39 ;AN001; Set Extended error
  1177. ADD SP,6 ;AN001; Clean up stack
  1178. STC ;AN001; Flag that there was an error
  1179. $ENDIF ;AN001;
  1180. $ENDIF ;AN001;
  1181. $ENDIF ;;AN000;;
  1182. ENDIF
  1183. $IF NC ;;AN000;; Was there ANY error?
  1184. POP DX ;;AN000;; Restore regs
  1185. POP BX ;;AN000;;
  1186. POP AX ;;AN000;;
  1187. $ENDIF ;;AN000;;
  1188. RET ;;AN000;; Return
  1189. ;;
  1190. $M_DISPLAY_STRING ENDP ;;AN000;;
  1191. ;;
  1192. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1193. ;;
  1194. ;; PROC NAME: $M_DISPLAY_$_STRING
  1195. ;;
  1196. ;; FUNCTION: Will display a $ terminated string
  1197. ;; INPUTS: ES:DI points to beginning of message text (not the length)
  1198. ;; OUPUTS: None
  1199. ;; REGS USED: AX,DX
  1200. ;;
  1201. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1202. ;;
  1203. $M_DISPLAY_$_STRING PROC NEAR ;;AN000;;
  1204. ;;
  1205. PUSH DS ;;AN000;;
  1206. PUSH ES ;;AN000;;
  1207. POP DS ;;AN000;; Set DS to segment of message text
  1208. IF NOT COMR
  1209. CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character?
  1210. $IF E ;;AN000;; Yes,
  1211. MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER
  1212. MOV DL,BYTE PTR ES:[DI] ;;AN000;; Get the character
  1213. INT 21H ;;AN000;; Write character
  1214. POP DS ;;AN000;; Set DS to segment of message text
  1215. MOV AL,DL ;;AN000;; Get the character in AL
  1216. CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character
  1217. PUSH DS ;;AN000;;
  1218. PUSH ES ;;AN000;;
  1219. POP DS ;;AN000;; Set DS to segment of message text
  1220. $IF C ;;AN000;; Yes,
  1221. MOV DL,BYTE PTR ES:[DI]+1 ;;AN000;; Get the next character
  1222. INT 21H ;;AN000;; Write character
  1223. CLC ;;AN000;; Clear the DBCS indicator
  1224. $ENDIF ;;AN000;;
  1225. $ELSE ;;AN000;; No,
  1226. ENDIF
  1227. MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER
  1228. $DO ;;AN002;; No,
  1229. OR CX,CX ;;AN002;; Are there any left to display?
  1230. $LEAVE Z ;;AN002;; Yes,
  1231. MOV DL,BYTE PTR ES:[DI] ;;AN002;; Get the character
  1232. INT 21H ;;AN002;; Display the character
  1233. INC DI ;;AN002;; Set pointer to next character
  1234. DEC CX ;;AN002;; Count this character
  1235. $ENDDO Z ;;AN002;; No,
  1236. IF NOT COMR
  1237. $ENDIF ;;AN000;;
  1238. ENDIF
  1239. CLC ;;AN000;; Char functions used don't return carry as error
  1240. POP DS ;;AN000;;
  1241. RET ;;AN000;;
  1242. ;;
  1243. $M_DISPLAY_$_STRING ENDP ;;AN000;;
  1244. ;;
  1245. IF NOT COMR
  1246. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1247. ;;
  1248. ;; PROC NAME: $M_DISPLAY_H_STRING
  1249. ;;
  1250. ;; FUNCTION: Will display a string to a specified handle
  1251. ;; INPUTS: ES:DI points to beginning of message
  1252. ;; CX contains the number of bytes to write
  1253. ;; BX contains the handle to write to
  1254. ;; OUPUTS: None
  1255. ;; REGS USED: AX,DX
  1256. ;;
  1257. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1258. ;;
  1259. $M_DISPLAY_H_STRING PROC NEAR ;;AN000;;
  1260. ;;
  1261. XOR AX,AX ;;AN002;; Set number of bytes written to 0
  1262. OR CX,CX ;;AN002;; For performance, don't write if not necessary
  1263. $IF NZ ;;AN002;; Any chars to write?
  1264. PUSH DS ;;AN000;; Yes,
  1265. PUSH ES ;;AN000;;
  1266. POP DS ;;AN000;; Set DS to segment of message text
  1267. MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle
  1268. MOV DX,DI ;;AN000;; Pointer to data to write
  1269. CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character?
  1270. $IF E ;;AN000;; Yes,
  1271. INT 21H ;;AN000;; Write character
  1272. POP DS ;;AN000;; Set DS to segment of message text
  1273. PUSH AX ;;AN000;;
  1274. MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get the character
  1275. CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character
  1276. POP AX ;;AN000;; Set DS to segment of message text
  1277. PUSH DS ;;AN000;;
  1278. PUSH ES ;;AN000;;
  1279. POP DS ;;AN000;; Set DS to segment of message text
  1280. $IF C ;;AN000;; Yes,
  1281. CLC ;;AN000;; Clear the DBCS indicator
  1282. MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle
  1283. INC DX ;;AN000;; Point to next character
  1284. INT 21H ;;AN000;; Write character
  1285. $ENDIF ;;AN000;;
  1286. $ELSE ;;AN000;; No,
  1287. INT 21H ;;AN000;; Write String at DS:SI to handle
  1288. $ENDIF ;;AN000;;
  1289. POP DS ;;AN000;;
  1290. $ENDIF ;;AN002;;
  1291. ;;
  1292. RET ;;AN000;;
  1293. ;;
  1294. $M_DISPLAY_H_STRING ENDP ;;AN000;;
  1295. ;;
  1296. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1297. ;;
  1298. ;; PROC NAME: $M_GET_EXT_ERR_39
  1299. ;;
  1300. ;; FUNCTION: Will set registers for extended error #39
  1301. ;; INPUTS: None
  1302. ;; OUPUTS: AX,BX,CX set
  1303. ;; REGS USED:
  1304. ;;
  1305. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1306. ;;
  1307. $M_GET_EXT_ERR_39 PROC NEAR ;AN001;
  1308. ;;
  1309. MOV AX,EXT_ERR_39 ;AN001; Set AX=39
  1310. MOV BX,(ERROR_CLASS_39 SHR 8) + ACTION_39 ;AN001; Set BH=1 BL=4
  1311. MOV CH,LOCUS_39 ;AN001; Set CH=1
  1312. ;AN001;
  1313. RET ;AN001;
  1314. ;;
  1315. $M_GET_EXT_ERR_39 ENDP ;AN001;
  1316. ;;
  1317. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1318. ENDIF
  1319. ;;
  1320. ;; PROC NAME: $M_ADD_CRLF
  1321. ;;
  1322. ;; FUNCTION: Will decide whether to display a CRLF
  1323. ;; INPUTS: DX contains the Input/Class requested
  1324. ;; OUTPUTS: None
  1325. ;; REGS Revised: CX,ES,DI
  1326. ;;
  1327. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1328. ;;
  1329. $M_ADD_CRLF PROC NEAR ;;AN004;;
  1330. ;;
  1331. CMP DH,UTILITY_MSG_CLASS ;;AN004;; Is it a utility message?
  1332. $IF NE ;;AN004;; No,
  1333. TEST DH,$M_NO_CRLF_MASK ;;AN004;; Are we to supress the CR LF?
  1334. $IF Z ;;AN004;; No,
  1335. PUSH DS ;;AN004;;
  1336. POP ES ;;AN004;; Set ES to data segment
  1337. LEA DI,$M_RT.$M_CRLF ;;AN004;; Point at CRLF message
  1338. MOV CX,$M_CRLF_SIZE ;;AN004;; Set the message size
  1339. CALL $M_DISPLAY_STRING ;;AN004;; Display the CRLF
  1340. $ENDIF ;;AN004;;
  1341. $ENDIF ;;AN004;;
  1342. RET ;;AN004;; Return
  1343. ;;
  1344. $M_ADD_CRLF ENDP ;;AN004;;
  1345. ;;
  1346. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1347. ;;
  1348. ;; PROC NAME: $M_IS_IT_DBCS
  1349. ;;
  1350. ;; FUNCTION: Will decide whether character is Single or Double Byte
  1351. ;; INPUTS: AL contains the byte to be checked
  1352. ;; OUPUTS: Carry flag = 0 if byte is NOT in DBCS range
  1353. ;; Carry flag = 1 if byte IS in DBCS range
  1354. ;; REGS USED: All restored
  1355. ;;
  1356. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1357. ;;
  1358. $M_IS_IT_DBCS PROC NEAR ;;AN000;;
  1359. ;;
  1360. PUSH ES ;;AN000;; Save Extra segment register
  1361. PUSH DI ;;AN000;; Save SI register
  1362. ;;
  1363. LES DI,$M_RT.$M_DBCS_VEC ;;AN000;;
  1364. OR DI,DI ;;AN000;; Was the DBCS vector set?
  1365. $IF NZ ;;AN000;;
  1366. $DO ;;AN000;;
  1367. CMP WORD PTR ES:[DI],$M_DBCS_TERM ;;AN000;; Is this the terminating flag?
  1368. CLC ;;AN000;;
  1369. $LEAVE E ;;AN000;;
  1370. ;; No,
  1371. CMP AL,BYTE PTR ES:[DI] ;;AN000;; Does the character fall in the DBCS range?
  1372. $IF AE,AND ;;AN000;;
  1373. CMP AL,BYTE PTR ES:[DI]+1 ;;AN000;; Does the character fall in the DBCS range?
  1374. $IF BE ;;AN000;;
  1375. STC ;;AN000;; Yes,
  1376. $ENDIF ;;AN000;; Set carry flag
  1377. INC DI ;;AN000;; No,
  1378. INC DI ;;AN000;; Go to next vector
  1379. $ENDDO ;;AN000;;
  1380. $ENDIF ;;AN000;;
  1381. POP DI ;;AN000;;
  1382. POP ES ;;AN000;; Restore SI register
  1383. RET ;;AN000;; Return
  1384. ;;
  1385. $M_IS_IT_DBCS ENDP ;;AN000;;
  1386. ;;
  1387. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1388. ;;
  1389. ;; PROC NAME: $M_CONVERT2ASC
  1390. ;;
  1391. ;; FUNCTION: Convert a binary number to a ASCII string
  1392. ;; INPUTS: DX:AX contains the number to be converted
  1393. ;; $M_RT_DIVISOR contains the divisor
  1394. ;; OUPUTS: CX contains the number of characters
  1395. ;; Top of stack --> Last character
  1396. ;; . . .
  1397. ;; Bot of stack --> First character
  1398. ;; REGS USED:
  1399. ;;
  1400. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1401. ;;
  1402. $M_CONVERT2ASC PROC NEAR ;;AN000;;
  1403. ;;
  1404. POP [$M_RT.$M_RETURN_ADDR] ;;AN000;; Save Return Address
  1405. XOR BX,BX ;;AN000;; Use BP as a swapping register
  1406. ;;
  1407. XCHG BX,AX ;;AN000;; Initialize - Low Word in BP
  1408. XCHG AX,DX ;;AN000;; - High Word in AX
  1409. $DO ;;AN000;; DO UNTIL Low Word becomes zero
  1410. DIV $M_RT.$M_DIVISOR ;;AN000;; Divide High Word by divisor
  1411. XCHG BX,AX ;;AN000;; Setup to divide Low Word using remainder
  1412. ;; and save reduced High Word in BP
  1413. DIV $M_RT.$M_DIVISOR ;;AN000;; Divide Low Word by divisor
  1414. CMP DX,9 ;;AN000;; Make a digit of the remainder
  1415. $IF A ;;AN000;; IF 10 to 15,
  1416. ADD DL,55 ;;AN000;; Make A to F ASCII
  1417. $ELSE ;;AN000;; IF 0 to 9,
  1418. ADD DL,'0' ;;AN000;; Make 0 to 9 ASCII
  1419. $ENDIF ;;AN000;;
  1420. PUSH DX ;;AN000;; Save the digit on the stack
  1421. INC CX ;;AN000;; Count that digit
  1422. OR AX,AX ;;AN000;; Are we done?
  1423. $LEAVE Z,AND ;;AN000;;
  1424. OR BX,BX ;;AN000;; AX and BX must be ZERO!!
  1425. $LEAVE Z ;;AN000;; No,
  1426. IF NOT COMR
  1427. CMP CX,$M_FIRST_THOU ;;AN000;; Are we at the first thousands mark
  1428. $IF E ;;AN000;; Yes,
  1429. CMP $M_SL.$M_S_PAD,$M_COMMA ;;AN000;; Is the pad character a comma?
  1430. $IF E ;;AN000;; Yes,
  1431. PUSH WORD PTR $M_RT.$M_THOU_SEPARA ;;AN000;; Insert a thousand separator
  1432. INC CX ;;AN000;;
  1433. $ENDIF ;;AN000;;
  1434. $ELSE ;;AN000;; No,
  1435. CMP CX,$M_SECOND_THOU ;;AN000;; Are we at the first thousands mark
  1436. $IF E ;;AN000;; Yes,
  1437. CMP $M_SL.$M_S_PAD,$M_COMMA ;;AN000;; Is the pad character a comma?
  1438. $IF E ;;AN000;; Yes,
  1439. PUSH WORD PTR $M_RT.$M_THOU_SEPARA ;;AN000;; Insert a thousand separator
  1440. INC CX ;;AN000;;
  1441. $ENDIF ;;AN000;;
  1442. $ELSE ;;AN000;; No,
  1443. CMP CX,$M_THIRD_THOU ;;AN000;; Are we at the first thousands mark
  1444. $IF E ;;AN000;; Yes,
  1445. CMP $M_SL.$M_S_PAD,$M_COMMA ;;AN000;; Is the pad character a comma?
  1446. $IF E ;;AN000;; Yes,
  1447. PUSH WORD PTR $M_RT.$M_THOU_SEPARA ;;AN000;; Insert a thousand separator
  1448. INC CX ;;AN000;;
  1449. $ENDIF ;;AN000;;
  1450. $ENDIF ;;AN000;;
  1451. $ENDIF ;;AN000;;
  1452. $ENDIF ;;AN000;;
  1453. ENDIF
  1454. XCHG AX,BX ;;AN000;; Setup to divide the reduced High Word
  1455. ;;AN000;; and Revised Low Word
  1456. XOR DX,DX ;;AN000;; Reset remainder
  1457. $ENDDO ;;AN000;; NEXT
  1458. ;;AN000;; Yes,
  1459. XOR DX,DX ;;AN000;; Reset remainder
  1460. XOR AX,AX ;;AN000;; Reset remainder
  1461. PUSH [$M_RT.$M_RETURN_ADDR] ;;AN000;; Restore Return Address
  1462. RET ;;AN000;; Return
  1463. ;;
  1464. $M_CONVERT2ASC ENDP ;;AN000;;
  1465. ;;
  1466. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1467. ;;
  1468. ;; PROC NAME: $M_DISPLAY_MESSAGE
  1469. ;;
  1470. ;; FUNCTION: Will display or write entire message (with replacable parameters)
  1471. ;; INPUTS: ES:DI points to beginning of message
  1472. ;; DS:SI points to first sublist structure in chain
  1473. ;; BX contains the handle to write to (if applicable)
  1474. ;; CX contains the length of string to write (before substitutions)
  1475. ;; BP contains the count of replacables
  1476. ;;
  1477. ;; OUTPUTS:
  1478. ;; REGS USED: All
  1479. ;;
  1480. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1481. ;;
  1482. $M_DISPLAY_MESSAGE PROC NEAR ;;AN000;;
  1483. ;;
  1484. $DO ;;AN000;; Note: DS:SI -> message
  1485. XOR DX,DX ;;AN000;; Set size = 0
  1486. OR CX,CX ;;AN000;; Are we finished the message yet?
  1487. $IF NZ ;;AN000;; No,
  1488. MOV AH,"%" ;;AN000;; Prepare to scan for %
  1489. MOV AL,0 ;;AN004;;
  1490. ;;
  1491. $DO ;;AN000;; Scan through string until %
  1492. CMP BYTE PTR ES:[DI],AH ;;AN000;; Is this character NOT a %
  1493. $LEAVE E,AND ;;AN000;; No,
  1494. CMP BYTE PTR ES:[DI+1],AH ;;AN000;; Is the next character also a %
  1495. $LEAVE NE,AND ;;AN000;; No,
  1496. CMP AL,AH ;;AN000;; Was the character before a %
  1497. $LEAVE NE ;;AN000;; No, GREAT found it
  1498. MOV AL,BYTE PTR ES:[DI] ;;AN004;; Yes, (to any of the above)
  1499. CALL $M_IS_IT_DBCS ;;AN004;; Is this character the first part of a DBCS?
  1500. $IF C ;;AN004;; Yes,
  1501. INC DI ;;AN004;; Increment past second part
  1502. $ENDIF ;;AN004;;
  1503. INC DI ;;AN000;; Next character in string
  1504. INC DX ;;AN000;; Size = Size + 1
  1505. DEC CX ;;AN000;; Decrement total size
  1506. $ENDDO Z ;;AN000;; Exit scan if we're at the end of the line
  1507. $ENDIF ;;AN000;;
  1508. ;;
  1509. PUSH SI ;;AN000;; Save beginning of sublists
  1510. XCHG CX,DX ;;AN000;; Get size of message to display (tot sz in DX)
  1511. OR BP,BP ;;AN000;; Do we have any replacables to do?
  1512. $IF NZ ;;AN000;; Yes,
  1513. DEC BP ;;AN000;; Decrement number of replacables
  1514. ;; Search through sublists to find applicable one
  1515. CMP $M_RT.$M_MSG_NUM,$M_NULL ;;AN000;; Is this an Extended/Parse case
  1516. $IF E ;;AN000;; No,
  1517. $SEARCH ;;AN000;;
  1518. MOV AL,$M_SL.$M_S_ID ;;AN000;; Get ID byte
  1519. ADD AL,30H ;;AN000;; Convert to ASCII
  1520. CMP AL,BYTE PTR ES:[DI]+1 ;;AN000;; Is this the right sublist?
  1521. $EXITIF E ;;AN000;;
  1522. $ORELSE ;;AN000;; No,
  1523. CMP AL,$M_SPECIAL_CASE ;;AN000;; Does this sublist have ID = 0
  1524. $LEAVE E,AND ;;AN000;; Yes,
  1525. OR DX,DX ;;AN000;; Are we at the end of the message?
  1526. $LEAVE Z ;;AN000;; No,
  1527. ADD SI,WORD PTR $M_SL.$M_S_SIZE ;;AN000;; Next SUBLIST
  1528. $ENDLOOP ;;AN000;; Yes,
  1529. CMP $M_RT.$M_CLASS,UTILITY_MSG_CLASS ;;AN004;; Is it a utility message?
  1530. $IF E ;;AN004;; Yes,
  1531. INC DX ;;AN000;; Remember to display CR,LF
  1532. INC DX ;;AN000;; at the end of the message
  1533. DEC CX ;;AN000;; Adjust message length
  1534. DEC CX ;;AN000;;
  1535. DEC DI ;;AN000;; Adjust ending address of message
  1536. DEC DI ;;AN000;;
  1537. $ELSE ;;AN004;; No,
  1538. MOV DX,-1 ;;AN004;; Set special case
  1539. $ENDIF ;;AN004;;
  1540. $ENDSRCH ;;AN000;;
  1541. $ENDIF ;;AN000;;
  1542. $ENDIF ;;AN000;;
  1543. ;; Prepare and display this part of message
  1544. PUSH DI ;;AN000;; Save pointer to replace number
  1545. SUB DI,CX ;;AN000;; Determine beginning of string
  1546. CALL $M_DISPLAY_STRING ;;AN000;; Display string until % (or end)
  1547. POP DI ;;AN000;; Get back pointer to replace number
  1548. POP CX ;;AN000;; Clean up stack in case error
  1549. $LEAVE C,LONG ;;AN000;; Fail if carry was set
  1550. PUSH CX ;;AN000;;
  1551. ;; Save and reset pointer registers
  1552. MOV CX,DX ;;AN000;; Get the size of the rest of the message
  1553. CMP $M_SL.$M_S_ID,$M_SPECIAL_CASE-30H ;;AN000;; Is this the %0 case?
  1554. $IF NE ;;AN000;; No,
  1555. OR CX,CX ;;AN000;; Are we finished the whole message?
  1556. $IF NZ ;;AN000;; No,
  1557. DEC CX ;;AN000;; Decrement total size (%)
  1558. DEC CX ;;AN000;; Decrement total size (#)
  1559. INC DI ;;AN000;; Go past %
  1560. INC DI ;;AN000;; Go past replace number
  1561. $ELSE ;;AN000;; Yes, (Note this will not leave because INC)
  1562. POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs
  1563. $ENDIF ;;AN000;; Yes, Note this will not leave because INC
  1564. $ELSE ;;AN000;;
  1565. OR CX,CX ;;AN000;; Are we finished the whole message?
  1566. $IF Z ;;AN004;; No,
  1567. POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs
  1568. $ELSE ;;AN000;; No,
  1569. CMP CX,-1 ;;AN004;; Are we at the end of the message?
  1570. $IF Z ;;AN004;; No,
  1571. XOR CX,CX ;;AN004;;
  1572. $ENDIF ;;AN000;;
  1573. OR DI,DI ;;AN004;; Turn ZF off
  1574. $ENDIF ;;AN000;;
  1575. $ENDIF ;;AN000;; Note this will not leave because INC
  1576. $LEAVE Z ;;AN000;;
  1577. PUSH BP ;;AN000;; Save the replace count
  1578. PUSH DI ;;AN000;; Save location to complete message
  1579. PUSH ES ;;AN000;;
  1580. PUSH CX ;;AN000;; Save size of the rest of the message
  1581. XOR CX,CX ;;AN000;; Reset CX used for character count
  1582. ;; Determine what action is required on parameter
  1583. CMP $M_RT.$M_MSG_NUM,$M_NULL ;;AN000;; Is this an Extended/Parse case
  1584. $IF E ;;AN000;;
  1585. IF CHARmsg ;;AN000;; Was Char specified?
  1586. TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Char_Type AND $M_TYPE_MASK ;;AN000;;
  1587. $IF Z ;;AN000;;
  1588. ;; Character type requested
  1589. ;;AN000;;
  1590. LES DI,DWORD PTR $M_SL.$M_S_VALUE ;;AN000;; Load pointer to replacing parameter
  1591. CALL $M_CHAR_REPLACE ;;AN000;;
  1592. $ELSE ;;AN000;; Get the rest of the message to display
  1593. ENDIF ;;AN000;;
  1594. IF NUMmsg ;;AN000;; Was Nnmeric type specified?
  1595. TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Sgn_Bin_Type AND $M_TYPE_MASK ;;AN000;;
  1596. $IF Z,OR ;;AN000;;
  1597. TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Unsgn_Bin_Type AND $M_TYPE_MASK ;;AN000;;
  1598. $IF Z,OR ;;AN000;;
  1599. TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Bin_Hex_Type AND $M_TYPE_MASK ;;AN000;;
  1600. $IF Z ;;AN000;;
  1601. ;; Numeric type requested
  1602. LES DI,DWORD PTR $M_SL.$M_S_VALUE ;;AN000;; Load pointer to replacing parameter
  1603. CALL $M_BIN2ASC_REPLACE ;;AN000;;
  1604. $ELSE ;;AN000;; Get the rest of the message to display
  1605. ENDIF ;;AN000;;
  1606. IF DATEmsg ;;AN000;; Was date specified?
  1607. TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Date_Type AND $M_TYPE_MASK ;;AN000;;
  1608. $IF E ;;AN000;;
  1609. ;; Date type requested
  1610. CALL $M_DATE_REPLACE ;;AN000;;
  1611. $ELSE ;;AN000;; Get the rest of the message to display
  1612. ENDIF ;;AN000;;
  1613. IF TIMEmsg ;;AN000;; Was time (12 hour format) specified?
  1614. ;; Time type requested (Default if we have not matched until here)
  1615. CALL $M_TIME_REPLACE ;;AN000;;
  1616. ENDIF ;;AN000;;
  1617. IF DATEmsg ;;AN000;;
  1618. $ENDIF ;;AN000;;
  1619. ENDIF ;;AN000;;
  1620. IF NUMmsg ;;AN000;;
  1621. $ENDIF ;;AN000;;
  1622. ENDIF ;;AN000;;
  1623. IF CHARmsg ;;AN000;;
  1624. $ENDIF ;;AN000;;
  1625. ENDIF ;;AN000;;
  1626. IF $M_REPLACE ;;AN000;;
  1627. ;; With the replace information of the Stack, display the replaceable field
  1628. CALL $M_DISPLAY_REPLACE ;;AN000;; Display the replace
  1629. ENDIF ;;AN000;;
  1630. ;; None of the above - Extended/Parse replace
  1631. $ELSE ;;AN000;;
  1632. IF NOT COMR
  1633. CALL $M_EXT_PAR_REPLACE ;;AN000;;
  1634. ENDIF
  1635. $ENDIF ;;AN000;;
  1636. ;; We must go back and complete the message after the replacable parameter if there is any left
  1637. $IF NC ;;AN000;; IF there was an error displaying then EXIT
  1638. POP CX ;;AN000;; Get size of the rest of the message
  1639. POP ES ;;AN000;; Get address of the rest of the message
  1640. POP DI ;;AN000;;
  1641. POP BP ;;AN000;; Get replacment count
  1642. POP SI ;;AN000;; ELSE get address of first sublist structure
  1643. $ELSE ;;AN000;;
  1644. ADD SP,10 ;;AN000;; Clean up stack if error
  1645. STC ;;AN000;;
  1646. $ENDIF ;;AN000;;
  1647. CMP $M_RT.$M_MSG_NUM,$M_NULL ;;AN000;; Is this an Extended/Parse case
  1648. $ENDDO NE,OR ;;AN000;;
  1649. $ENDDO C,LONG ;;AN000;; Go back and display the rest of the message
  1650. ;; IF there was an error displaying then EXIT
  1651. MOV $M_RT.$M_MSG_NUM,0 ;;AN000;; Reset message number to null
  1652. RET ;;AN000;; Return
  1653. ;;
  1654. $M_DISPLAY_MESSAGE ENDP ;;AN000;;
  1655. IF NOT COMR
  1656. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1657. ;;
  1658. ;; PROC NAME: $M_EXT_PAR_REPLACE
  1659. ;;
  1660. ;; FUNCTION:
  1661. ;; INPUTS:
  1662. ;; OUPUTS:
  1663. ;;
  1664. ;; REGS USED:
  1665. ;;
  1666. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1667. ;;
  1668. $M_EXT_PAR_REPLACE PROC NEAR ;;AN000;;
  1669. ;;
  1670. XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH)
  1671. MOV AX,$M_RT.$M_MSG_NUM ;;AN000;; Prepare for get binary value (LOW)
  1672. MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; Set default divisor
  1673. ;;
  1674. CALL $M_CONVERT2ASC ;;AN000;;
  1675. ;;
  1676. $DO ;;AN000;;
  1677. POP AX ;;AN000;; Get character in register
  1678. MOV BYTE PTR $M_RT.$M_TEMP_BUF[BX],AL ;;AN000;; Move char into the buffer
  1679. INC BX ;;AN000;; Increase buffer count
  1680. CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full?
  1681. $IF E ;;AN000;; Yes,
  1682. CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer
  1683. $ENDIF ;;AN000;;
  1684. DEC CL ;;AN000;; Have we completed replace?
  1685. $ENDDO Z ;;AN000;;
  1686. ;;
  1687. MOV AX,$M_CR_LF ;;AN000;; Move char into the buffer
  1688. MOV WORD PTR $M_RT.$M_TEMP_BUF[BX],AX ;;AN000;; Move char into the buffer
  1689. INC BX ;;AN000;; Increase buffer count
  1690. INC BX ;;AN000;; Increase buffer count
  1691. CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer
  1692. RET ;;AN000::
  1693. ;;
  1694. $M_EXT_PAR_REPLACE ENDP ;;AN000;;
  1695. ;;
  1696. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1697. ENDIF
  1698. IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet
  1699. $M_SUBS = FALSE ;;AN000;; No, then include and reset the flag
  1700. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1701. ;;
  1702. ;; PROC NAME: $M_GET_MSG_ADDRESS
  1703. ;;
  1704. ;; FUNCTION: To scan thru classes to return pointer to the message header
  1705. ;; INPUTS: Access to $M_RES_ADDRESSES
  1706. ;; OUPUTS: IF CX = 0 THEN Message was not found
  1707. ;; IF CX > 1 THEN DS:SI points to the specified message
  1708. ;; REGS CHANGED: ES,DI,CX,DS,SI
  1709. ;;
  1710. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1711. ;;
  1712. IF FARmsg ;;AN000;;
  1713. $M_GET_MSG_ADDRESS PROC FAR ;;AN000;;
  1714. ELSE ;;AN000;;
  1715. $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;;
  1716. ENDIF ;;AN000;;
  1717. ;;
  1718. PUSH SI ;;AN000;;
  1719. PUSH BX ;;AN000;;
  1720. XOR SI,SI ;;AN000;; Use SI as an index
  1721. XOR CX,CX ;;AN000;; Use CX as an size
  1722. $DO ;;AN000;;
  1723. CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested?
  1724. $IF E ;;AN000;; Yes,
  1725. IF FARmsg ;;AN000;;
  1726. LES DI,DWORD PTR $M_RT.$M_CLASS_ADDRS[SI] ;;AN000;; Get address of class
  1727. MOV BX,ES ;;AN000;
  1728. ELSE ;;AN000;;
  1729. MOV DI,WORD PTR $M_RT.$M_CLASS_ADDRS[SI] ;;AN000;; Get address of class
  1730. MOV BX,DI ;;AN000;
  1731. ENDIF ;;AN000;;
  1732. $ELSE ;;AN000;; No,
  1733. TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested?
  1734. $IF NE ;;AN000;; Yes,
  1735. LES DI,DWORD PTR $M_RT.$M_PARSE_COMMAND[SI] ;;AN000;; Get address of class
  1736. MOV BX,ES ;;AN000;
  1737. $ELSE ;;AN000;; No, extended errors were specified
  1738. CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error?
  1739. $IF AE,AND ;;AN000;;
  1740. CMP AX,$M_CRIT_HI ;;AN000;;
  1741. $IF BE ;;AN000;; Yes,
  1742. LES DI,DWORD PTR $M_RT.$M_CRIT_ADDRS[SI] ;;AN000;; Get address of class
  1743. MOV BX,ES ;;AN000;
  1744. $ELSE ;;AN000;;
  1745. LES DI,DWORD PTR $M_RT.$M_EXT_ERR_ADDRS[SI] ;;AN000;; Get address of class
  1746. MOV BX,ES ;;AN000;
  1747. $ENDIF ;;AN000;;
  1748. $ENDIF ;;AN000;;
  1749. $ENDIF ;;AN000;;
  1750. ;;
  1751. CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes?
  1752. $IF E ;;AN000;; Yes,
  1753. CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class?
  1754. $IF E ;;AN000;; Yes,
  1755. STC ;;AN000;; Set the carry flag
  1756. $ELSE ;;AN000;; No,
  1757. MOV $M_RT.$M_MSG_NUM,AX ;;AN000;; Save message number
  1758. MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number
  1759. MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message
  1760. XOR SI,SI ;;AN000;; Reset the SI index to start again
  1761. CLC ;;AN000;;
  1762. $ENDIF ;;AN000;; No,
  1763. $ELSE ;;AN000;;
  1764. CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist?
  1765. $IF NE ;;AN001;; Yes,
  1766. CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message
  1767. $ENDIF ;;AN000;;
  1768. ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class
  1769. CLC ;;AN000;;
  1770. $ENDIF ;;AN000;;
  1771. $LEAVE C ;;AN000;;
  1772. OR CX,CX ;;AN000;; Was the message found?
  1773. $ENDDO NZ,LONG ;;AN000;;
  1774. PUSHF ;;AN006;; Save the flag state
  1775. CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested?
  1776. $IF E ;;AN006;; Yes,
  1777. PUSH DX ;;AN006;; Save all needed registers
  1778. PUSH BP ;;AN006;;
  1779. PUSH CX ;;AN006;;
  1780. PUSH ES ;;AN006;;
  1781. PUSH DI ;;AN006;;
  1782. PUSH AX ;;AN006;;
  1783. MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed
  1784. INT 2FH ;;AN006;;
  1785. CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed?
  1786. POP AX ;;AN006;; Restore msg number
  1787. $IF E ;;AN006;; Yes,
  1788. MOV BX,AX ;;AN006;; BX is the extended error number
  1789. MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number
  1790. INT 2FH ;;AN006;; Call IFSFUNC
  1791. $ELSE ;;AN006;; No,
  1792. STC ;;AN006;; Carry conditon
  1793. $ENDIF ;;AN006;;
  1794. $IF C ;;AN006;; Was there an update?
  1795. POP DI ;;AN006;; No,
  1796. POP ES ;;AN006;; Restore old pointer
  1797. POP CX ;;AN006;;
  1798. $ELSE ;;AN006;; Yes
  1799. ADD SP,6 ;;AN006;; Throw away old pointer
  1800. CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string
  1801. $ENDIF ;;AN006;;
  1802. POP BP ;;AN006;; Restore other Regs
  1803. POP DX ;;AN006;;
  1804. $ENDIF ;;AN006;;
  1805. $M_POPF ;;AN006;; Restore the flag state
  1806. POP BX ;;AN000;;
  1807. POP SI ;;AN000;;
  1808. RET ;;AN000;; Return ES:DI pointing to the message
  1809. ;;
  1810. $M_GET_MSG_ADDRESS ENDP ;;
  1811. ;;
  1812. $M_SET_LEN_IN_CX PROC NEAR ;;
  1813. ;;
  1814. PUSH DI ;;AN006;; Save position
  1815. PUSH AX ;;AN006;;
  1816. MOV CX,-1 ;;AN006;; Set CX for decrements
  1817. XOR AL,AL ;;AN006;; Prepare compare register
  1818. REPNE SCASB ;;AN006;; Scan for zero
  1819. NOT CX ;;AN006;; Change decrement into number
  1820. DEC CX ;;AN006;; Don't include the zero
  1821. POP AX ;;AN006;;
  1822. POP DI ;;AN006;; Restore position
  1823. RET ;;AN006;;
  1824. ;;
  1825. $M_SET_LEN_IN_CX ENDP ;;
  1826. ;;
  1827. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1828. ;;
  1829. ;; PROC NAME: $M_FIND_SPECIFIED_MSG
  1830. ;;
  1831. ;; FUNCTION: To scan thru message headers until message is found
  1832. ;; INPUTS: ES:DI points to beginning of msg headers
  1833. ;; CX contains the number of messages in class
  1834. ;; DH contains the message class
  1835. ;; OUPUTS: IF CX = 0 THEN Message was not found
  1836. ;; IF CX > 1 THEN ES:DI points to header of specified message
  1837. ;;
  1838. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1839. ;;
  1840. $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;;
  1841. ;;
  1842. CMP BX,1 ;;AN004;; Do we have an address to CALL?
  1843. $IF E,AND ;;AN004;; Yes,
  1844. CMP WORD PTR $M_RT.$M_DISK_PROC_ADDR,-1 ;;AN004;; Do we have an address to CALL?
  1845. $IF NE ;;AN004;; Yes,
  1846. CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err?
  1847. $IF E ;;AN004;; . . . and . . .
  1848. PUSH AX ;;AN004;; Reset the special message number
  1849. MOV AX,$M_RT.$M_MSG_NUM ;;AN004;; Get the old message number
  1850. CALL DWORD PTR $M_RT.$M_DISK_PROC_ADDR ;;AN004;; Call the READ_DISK_PROC to get error text
  1851. POP AX ;;AN004;; Reset the special message number
  1852. $ELSE ;;AN004;; Get the old message number
  1853. CALL DWORD PTR $M_RT.$M_DISK_PROC_ADDR ;;AN004;; Call the READ_DISK_PROC to get error text
  1854. $ENDIF ;;AN004;; Get the old message number
  1855. $ELSE ;;AN004;;
  1856. XOR CX,CX ;;AN002;; CX = 0 will allow us to
  1857. CMP DH,UTILITY_MSG_CLASS ;;AN001;;
  1858. $IF NE ;;AN001;;
  1859. MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG ;;AN001;; Get number of messages in class
  1860. $ELSE ;;AN001;;
  1861. IF FARmsg ;;AN001;;
  1862. CMP BYTE PTR ES:[DI].$M_CLASS_ID,DH ;;AN002;; Check if class still exists at
  1863. ELSE
  1864. CMP BYTE PTR CS:[DI].$M_CLASS_ID,DH ;;AN002;; Check if class still exists at
  1865. ENDIF
  1866. $IF E ;;AN002;; pointer (hopefully)
  1867. IF FARmsg ;;AN001;;
  1868. MOV CL,BYTE PTR ES:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class
  1869. ELSE
  1870. MOV CL,BYTE PTR CS:[DI].$M_NUM_CLS_MSG ;;AN000;; Get number of messages in class
  1871. ENDIF
  1872. $ENDIF ;;AN002;; go on to the next class
  1873. $ENDIF ;;AN001;;
  1874. ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header
  1875. STC ;;AN004;; Flag that we haven't found anything yet
  1876. $ENDIF ;;AN004;;
  1877. $IF C ;;AN004;; Have we found anything yet?
  1878. CLC ;;AN004;; No, reset carry
  1879. $SEARCH ;;AN000;;
  1880. OR CX,CX ;;AN000;; Do we have any to check?
  1881. $LEAVE Z ;;AN000;; No, return with CX = 0
  1882. CMP DH,UTILITY_MSG_CLASS ;;AN001;;
  1883. $IF NE ;;AN001;;
  1884. CMP AX,WORD PTR ES:[DI].$M_NUM ;;AN001;; Is this the message requested?
  1885. $ELSE ;;AN001;;
  1886. IF FARmsg ;;AN001;;
  1887. CMP AX,WORD PTR ES:[DI].$M_NUM ;;AN000;; Is this the message requested?
  1888. ELSE
  1889. CMP AX,WORD PTR CS:[DI].$M_NUM ;;AN000;; Is this the message requested?
  1890. ENDIF
  1891. $ENDIF
  1892. $EXITIF E ;;AN000;;
  1893. $ORELSE ;;AN000;
  1894. DEC CX ;;AN000;; No, well do we have more to check?
  1895. $LEAVE Z ;;AN000;; No, return with CX = 0
  1896. ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header
  1897. $ENDLOOP ;;AN000;;
  1898. STC ;;AN000;;
  1899. $ENDSRCH ;;AN000;; Check next message
  1900. $IF NC ;;AN000;; Did we find the message?
  1901. CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message?
  1902. CLC ;;AN001;;
  1903. $IF E ;;AN001;;
  1904. IF FARmsg ;;AN001;;
  1905. ELSE ;;AN000;;
  1906. PUSH CS ;;AN000;;
  1907. POP ES ;;AN000;; Return ES:DI pointing to the message
  1908. ENDIF
  1909. $ENDIF ;;AN001;;
  1910. ADD DI,WORD PTR ES:[DI].$M_TXT_PTR ;;AN000;; Prepare ES:DI pointing to the message
  1911. $ENDIF ;;AN004;;
  1912. $ENDIF ;;AN004;;
  1913. ;; Yes, great we can return with CX > 0
  1914. $IF NC ;;AN000;; Did we find the message?
  1915. XOR CH,CH ;;AN000;;
  1916. MOV CL,BYTE PTR ES:[DI] ;;AN000;; Move size into CX
  1917. INC DI ;;AN000;; Increment past length
  1918. $ENDIF ;;AN004;;
  1919. MOV $M_RT.$M_SIZE,$M_NULL ;;AN004;; Reset variable
  1920. RET ;;AN000;; Return
  1921. ;;
  1922. $M_FIND_SPECIFIED_MSG ENDP ;;AN000;;
  1923. ;;
  1924. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1925. ENDIF ;;AN000;; END of include of common subroutines
  1926. ;
  1927. IF $M_REPLACE ;;AN000;; Is the request to include the code for replaceable parms
  1928. $M_REPLACE = FALSE ;;AN000;; Tell the assembler we did
  1929. ;;
  1930. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1931. $M_DISPLAY_REPLACE PROC NEAR ;;AN000;;
  1932. ;;
  1933. XOR BX,BX ;;AN000;; Use BX for buffer count
  1934. IF NOT COMR
  1935. CMP $M_SL.$M_S_ID,$M_SPECIAL_CASE-30H ;;AN000;; Is this the special case (convert to ASCII)
  1936. $IF E ;;AN000;; Yes,
  1937. MOV WORD PTR $M_RT.$M_TEMP_BUF[BX],$M_SPACE_HYP ;;AN000;; Move in a " -"
  1938. INC BX ;;AN000;; Increment count
  1939. INC BX ;;AN000;; Increment count
  1940. MOV BYTE PTR $M_RT.$M_TEMP_BUF[BX],$M_SPACE ;;AN000;; Move in a " "
  1941. INC BX ;;AN000;; Increment count
  1942. CALL $M_FLUSH_BUF ;;AN000;; Write out " - " to prepare for special case
  1943. $ENDIF ;;AN000;; If it fails we will catch it later
  1944. ENDIF
  1945. POP BP ;;AN000;; Remember the return address
  1946. XOR BX,BX ;;AN000;; Use BX for buffer count
  1947. XOR DX,DX ;;AN000;; Use DX for count of parms taken off the stack
  1948. MOV $M_RT.$M_SIZE,CL ;;AN000;; Save size to later clear stack
  1949. MOV AL,BYTE PTR $M_SL.$M_S_MINW ;;AN000;; Get the minimum width
  1950. ;;
  1951. CMP AL,CL ;;AN000;; Do we need pad chars added?
  1952. $IF A ;;AN000;; Yes,
  1953. SUB AL,CL ;;AN000;; Calculate how many pad chars are needed.
  1954. MOV DH,AL ;;AN000;; Save the number of pad characters
  1955. TEST BYTE PTR $M_SL.$M_S_FLAG,Right_Align ;;AN000;; Was replaceable parm to be right aligned?
  1956. $IF NZ ;;AN000;; Yes,
  1957. $DO ;;AN000;; Begin filling buffer with pad chars
  1958. MOV AL,BYTE PTR $M_SL.$M_S_PAD ;;AN000;;
  1959. MOV BYTE PTR $M_RT.$M_TEMP_BUF[BX],AL ;;AN000;; Move in a pad char
  1960. INC BX ;;AN000;;
  1961. CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full?
  1962. $IF E ;;AN000;; Yes,
  1963. CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer
  1964. $ENDIF ;;AN000;;
  1965. DEC DH ;;AN000;; Have we filled with enough pad chars?
  1966. $ENDDO Z ;;AN000;; No, next pad character
  1967. $ENDIF ;;AN000;;
  1968. $ENDIF ;;AN000;; Yes,
  1969. ;;
  1970. CMP BYTE PTR $M_SL.$M_S_MAXW,$M_UNLIM_W ;;AN000;; Is maximum width unlimited?
  1971. $IF NE ;;AN000;;
  1972. CMP BYTE PTR $M_SL.$M_S_MAXW,CL ;;AN000;; Will we exceed maximum width?
  1973. $IF B ;;AN000;; Yes,
  1974. SUB CL,BYTE PTR $M_SL.$M_S_MAXW ;;AN000;; Calculate how many extra chars
  1975. MOV DL,CL ;;AN000;; Remember how many chars to pop off
  1976. MOV CL,BYTE PTR $M_SL.$M_S_MAXW ;;AN000;; Set new string length
  1977. $ENDIF ;;AN000;;
  1978. $ENDIF ;;AN000;;
  1979. OR CX,CX ;;AN000;;
  1980. $IF NZ ;;AN000;;
  1981. $DO ;;AN000;; Begin filling buffer with string
  1982. TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Char_Type AND $M_TYPE_MASK ;;AN000;;
  1983. $IF Z,AND ;;AN000;;
  1984. TEST $M_SL.$M_S_FLAG,Char_field_ASCIIZ AND $M_SIZE_MASK ; Is this replace a ASCIIZ string?
  1985. $IF NZ ;;AN000;; Yes,
  1986. MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get first character from string
  1987. INC DI ;;AN000;; Next character in string
  1988. $ELSE ;;AN000;; No,
  1989. POP AX ;;AN000;; Get character in register
  1990. $ENDIF ;;AN000;;
  1991. MOV BYTE PTR $M_RT.$M_TEMP_BUF[BX],AL ;;AN000;; Move char into the buffer
  1992. INC BX ;;AN000;; Increase buffer count
  1993. CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full?
  1994. $IF E ;;AN000;; Yes,
  1995. CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer
  1996. $ENDIF ;;AN000;;
  1997. DEC CL ;;AN000;; Have we completed replace?
  1998. $ENDDO Z ;;AN000;; Test again
  1999. $ENDIF ;;AN000;;
  2000. ;;
  2001. TEST BYTE PTR $M_SL.$M_S_FLAG,Right_Align ;;AN000;; Was replaceable parm to be left aligned?
  2002. $IF Z ;;AN000;; Yes,
  2003. OR DH,DH ;;AN000;; Do we need pad chars added?
  2004. $IF NZ ;;AN000;; Yes,
  2005. $DO ;;AN000;; Begin filling buffer with pad chars
  2006. MOV AL,BYTE PTR $M_SL.$M_S_PAD ;;AN000;;
  2007. MOV BYTE PTR $M_RT.$M_TEMP_BUF[BX],AL ;;AN000;; Move in a pad char
  2008. INC BX ;;AN000;;
  2009. CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full?
  2010. $IF E ;;AN000;; Yes,
  2011. CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer
  2012. $ENDIF ;;AN000;;
  2013. DEC DH ;;AN000;; Have we filled with enough pad chars?
  2014. $ENDDO Z ;;AN000;; Test again
  2015. $ENDIF ;;AN000;;
  2016. $ENDIF ;;AN000;;
  2017. ;;
  2018. TEST BYTE PTR $M_SL.$M_S_FLAG,NOT Char_Type AND $M_TYPE_MASK ;;AN000;;
  2019. $IF Z,AND ;;AN000;;
  2020. TEST $M_SL.$M_S_FLAG,Char_field_ASCIIZ AND $M_SIZE_MASK ;;AN000;; Is this replace a ASCIIZ string?
  2021. $IF NZ ;;AN000;; Yes,
  2022. $ELSE ;;AN000;;
  2023. OR DL,DL ;;AN000;;
  2024. $IF NE ;;AN000;;
  2025. $DO ;;AN000;;
  2026. POP [$M_RT.$M_RETURN_ADDR] ;;AN000;; Clean Up stack using spare variable
  2027. DEC DL ;;AN000;; Are we done?
  2028. $ENDDO Z ;;AN000;;
  2029. $ENDIF ;;AN000;;
  2030. $ENDIF ;;AN000;;
  2031. CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer for the final time
  2032. PUSH BP ;;AN000;; Restore the return address
  2033. ;;
  2034. RET ;;AN000;;
  2035. ;;
  2036. $M_DISPLAY_REPLACE ENDP ;;AN000;;
  2037. ;;
  2038. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2039. ;;
  2040. ;; PROC NAME: $M_FLUSH_BUFFER
  2041. ;;
  2042. ;; FUNCTION: Display the contents of the temporary buffer
  2043. ;; INPUTS: DI contains the number of bytes to display
  2044. ;; OUTPUTS: BX reset to zero
  2045. ;;
  2046. ;; REGS USED:
  2047. ;;
  2048. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2049. ;;
  2050. $M_FLUSH_BUF PROC NEAR ;;AN000;;
  2051. ;;
  2052. PUSH CX ;;AN000;; Save changed regs
  2053. PUSH ES ;;AN000;;
  2054. PUSH DI ;;AN000;;
  2055. PUSH DS ;;AN000;; Set ES pointing to buffer
  2056. POP ES ;;AN000;;
  2057. ;;
  2058. MOV CX,BX ;;AN000;; Set number of bytes to display
  2059. XOR BX,BX ;;AN000;; Reset buffer counter
  2060. LEA DI,$M_RT.$M_TEMP_BUF ;;AN000;; Reset buffer location pointer
  2061. CALL $M_DISPLAY_STRING ;;AN000;; Display the buffer
  2062. ;;
  2063. $IF NC ;;AN000;; Error?
  2064. POP DI ;;AN000;; No, Restore changed regs
  2065. POP ES ;;AN000;;
  2066. POP CX ;;AN000;;
  2067. $ELSE ;;AN000;; Yes,
  2068. ADD SP,6 ;;AN000;; Fix stack
  2069. STC ;;AN000;;
  2070. $ENDIF ;;AN000;; Error?
  2071. ;;
  2072. RET ;;AN000;; Return
  2073. ;;
  2074. $M_FLUSH_BUF ENDP ;;AN000;;
  2075. ;;
  2076. ;;
  2077. IF CHARmsg ;;AN000;; Is the request to include the code for CHAR replace?
  2078. $M_REPLACE = TRUE ;;AN000;; Yes, THEN include it and flag that we will need common
  2079. $M_CHAR_ONLY = TRUE ;;AN000;; replacement code later
  2080. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2081. ;;
  2082. ;; PROC NAME: $M_CHAR_REPLACE
  2083. ;;
  2084. ;; FUNCTION: Will prepare a single char or ASCIIZ string for replace
  2085. ;; INPUTS: DS:SI points at corresponding SUBLIST
  2086. ;; ES:DI contains the VALUE from SUBLIST
  2087. ;; OUTPUTS: CX contains number of characters on stack
  2088. ;; Top of stack --> Last character
  2089. ;; . . .
  2090. ;; Bot of stack --> First character
  2091. ;;
  2092. ;; OTHER REGS Revised: AX
  2093. ;;
  2094. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2095. ;;
  2096. $M_CHAR_REPLACE PROC NEAR ;;AN000;;
  2097. ;;
  2098. POP BP ;;AN000;; Save return address
  2099. TEST $M_SL.$M_S_FLAG,NOT Char_Field_Char AND $M_SIZE_MASK ;;AN000;; Was Character specified?
  2100. $IF Z ;;AN000;; Yes,
  2101. MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get the character
  2102. PUSH AX ;;AN000;; Put it on the stack
  2103. INC CX ;;AN000;; Increase the count
  2104. CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character
  2105. $IF C ;;AN000;; Yes,
  2106. MOV AL,BYTE PTR ES:[DI]+1 ;;AN000;; Get the next character
  2107. PUSH AX ;;AN000;; Put it on the stack
  2108. CLC ;;AN000;; Clear the carry
  2109. $ENDIF ;;AN000;;
  2110. $ELSE ;;AN000;; No, it was an ASCIIZ string
  2111. $DO ;;AN000;;
  2112. MOV AL,BYTE PTR ES:[DI] ;;AN000;; Get the character
  2113. OR AL,AL ;;AN000;; Is it the NULL?
  2114. $LEAVE Z ;;AN000;; No,
  2115. INC DI ;;AN000;; Next character
  2116. INC CX ;;AN000;; Increment the count
  2117. $ENDDO ;;AN000;; Yes,
  2118. SUB DI,CX ;;AN000;; Set SI at the beginning of the string
  2119. $ENDIF ;;AN000;;
  2120. ;;AN000;;
  2121. PUSH BP ;;AN000;; Restore return address
  2122. RET ;;AN000;; Return
  2123. ;;
  2124. $M_CHAR_REPLACE ENDP ;;AN000;;
  2125. ;;
  2126. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2127. ENDIF ;;AN000;; END of include of CHAR replace code
  2128. ;
  2129. IF NUMmsg ;;AN000;; Is the request to include the code for NUM replace?
  2130. $M_REPLACE = TRUE ;;AN000;; Yes, THEN include it and flag that we will need common
  2131. $M_CHAR_ONLY = FALSE ;;AN000;; replacement code later
  2132. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2133. ;;
  2134. ;; PROC NAME: $M_BIN2ASC_REPLACE
  2135. ;;
  2136. ;; FUNCTION: Convert a signed or unsigned binary number to an ASCII string
  2137. ;; and prepare to display
  2138. ;; INPUTS: DS:SI points at corresponding SUBLIST
  2139. ;; ES:DI contains the VALUE from SUBLIST
  2140. ;; OUTPUTS: CX contains number of characters on stack
  2141. ;; Top of stack --> Last character
  2142. ;; . . .
  2143. ;; Bot of stack --> First character
  2144. ;; OTHER REGS Revised: BX,DX,AX
  2145. ;;
  2146. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2147. ;;
  2148. $M_BIN2ASC_REPLACE PROC NEAR ;;AN000;;
  2149. ;;
  2150. POP BP ;;AN000;; Save return address
  2151. ;;
  2152. XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH)
  2153. XOR AX,AX ;;AN000;; Prepare for get binary value (LOW)
  2154. MOV $M_RT.$M_DIVISOR,$M_BASE16 ;;AN000;; Set default divisor
  2155. XOR BX,BX ;;AN000;; Use BP as the NEG flag (if applicable)
  2156. IF NOT COMR
  2157. TEST $M_SL.$M_S_FLAG,NOT $M_BYTE AND $M_SIZE_MASK ;;AN000;; Was BYTE specified?
  2158. $IF Z ;;AN000;;
  2159. MOV AL, BYTE PTR ES:[DI] ;;AN000;; Setup byte in AL
  2160. TEST $M_SL.$M_S_FLAG,NOT Sgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; Was Signed binary specified?
  2161. $IF Z ;;AN000;;
  2162. TEST AL,10000000b ;;AN000;; Is this number negative?
  2163. $IF NZ ;;AN000;; Yes,
  2164. INC BX ;;AN000;; Remember that it was negative
  2165. AND AL,01111111b ;;AN000;; Make it positive
  2166. $ENDIF ;;AN000;;
  2167. MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;;
  2168. $ENDIF ;;AN000;;
  2169. TEST $M_SL.$M_S_FLAG,NOT Unsgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; Was Signed binary specified?
  2170. $IF Z ;;AN000;;
  2171. MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;;
  2172. $ENDIF ;;AN000;;
  2173. $ELSE ;;AN000;;
  2174. ENDIF
  2175. TEST $M_SL.$M_S_FLAG,NOT $M_WORD AND $M_SIZE_MASK ;;AN000;; Was WORD specified?
  2176. $IF Z ;;AN000;;
  2177. MOV AX, WORD PTR ES:[DI] ;;AN000;; Setup byte in AL
  2178. TEST $M_SL.$M_S_FLAG,NOT Sgn_Bin_Type AND $M_TYPE_MASK ;; AN000;; Was Signed binary specified?
  2179. $IF Z ;;AN000;;
  2180. TEST AH,10000000b ;;AN000;; Is this number negative?
  2181. $IF NZ ;;AN000;; Yes,
  2182. INC BX ;;AN000;; Remember that it was negative
  2183. AND AH,01111111b ;;AN000;; Make it positive
  2184. $ENDIF ;;AN000;;
  2185. MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;;
  2186. $ENDIF ;;AN000;;
  2187. TEST $M_SL.$M_S_FLAG,NOT Unsgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; Was Signed binary specified?
  2188. $IF Z ;;AN000;;
  2189. MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;;
  2190. $ENDIF ;;AN000;;
  2191. $ELSE ;;AN000;;
  2192. IF NOT COMR
  2193. MOV AX, WORD PTR ES:[DI] ;;AN000;; Setup Double word in DX:AX
  2194. MOV DX, WORD PTR ES:[DI]+2 ;;AN000;;
  2195. TEST $M_SL.$M_S_FLAG,NOT Sgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; Was Signed binary specified?
  2196. $IF Z ;;AN000;;
  2197. TEST DH,10000000b ;;AN000;; Is this number negative?
  2198. $IF NZ ;;AN000;; Yes,
  2199. INC BX ;;AN000;; Remember that it was negative
  2200. AND DH,01111111b ;;AN000;; Make it positive
  2201. $ENDIF ;;AN000;;
  2202. MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;;
  2203. $ENDIF ;;AN000;;
  2204. TEST $M_SL.$M_S_FLAG,NOT Unsgn_Bin_Type AND $M_TYPE_MASK ;;AN000;; Was Signed binary specified?
  2205. $IF Z ;;AN000;;
  2206. MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;;
  2207. $ENDIF ;;AN000;;
  2208. ENDIF
  2209. $ENDIF ;;AN000;;
  2210. $ENDIF ;;AN000;;
  2211. ;;
  2212. CALL $M_CONVERT2ASC ;;AN000;; Convert to ASCII string
  2213. IF NOT COMR
  2214. OR BX,BX ;;AN000;;
  2215. $IF NZ ;;AN000;; Was number negative?
  2216. XOR DX,DX ;;AN000;; Yes,
  2217. MOV DL,$M_NEG_SIGN ;;AN000;; Put "-" on the stack with the number
  2218. PUSH DX ;;AN000;;
  2219. $ENDIF ;;AN000;; No,
  2220. ENDIF
  2221. ;;
  2222. PUSH BP ;;AN000;; Restore return address
  2223. RET ;;AN000;; Return
  2224. ;;
  2225. $M_BIN2ASC_REPLACE ENDP ;;AN000;;
  2226. ;;
  2227. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2228. ENDIF ;;AN000;; END of include of NUM replace code
  2229. ;
  2230. IF DATEmsg ;;AN000;; Is the request to include the code for DATE replace?
  2231. $M_REPLACE = TRUE ;;AN000;; Yes, THEN include it and flag that we will need common
  2232. $M_CHAR_ONLY = FALSE ;;AN000;; replacement code later
  2233. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2234. ;;
  2235. ;; PROC NAME: $M_DATE_REPLACE
  2236. ;;
  2237. ;; FUNCTION: Convert a date to a decimal ASCII string using current
  2238. ;; country format and prepare to display
  2239. ;; INPUTS: DS:SI points at corresponding SUBLIST
  2240. ;; ES:DI points at VALUE from SUBLIST
  2241. ;; OUTPUTS: CX contains number of characters on stack
  2242. ;; Top of stack --> Last character
  2243. ;; . . .
  2244. ;; Bot of stack --> First character
  2245. ;; OTHER REGS Revised: DX, AX
  2246. ;;
  2247. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2248. ;;
  2249. $M_DATE_REPLACE PROC NEAR ;;AN000;;
  2250. ;;
  2251. POP BP ;;AN000;; Save return address
  2252. MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; Set default divisor
  2253. CALL $M_GET_DATE ;;AN000;; Set date format/separator in $M_RT
  2254. ;;AN000;; All O.K.?
  2255. XOR DX,DX ;;AN000;; Reset DX value
  2256. XOR AX,AX ;;AN000;; Reset AX value
  2257. CMP WORD PTR $M_RT.$M_DATE_FORMAT,0 ;;AN000;; USA Date Format
  2258. $IF E ;;AN000;; Beginning from end: (saved on the stack)
  2259. CALL $M_YEAR ;;AN000;; Get Year
  2260. CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string
  2261. PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;;
  2262. INC CX ;;AN000;; Increment count
  2263. XOR AX,AX ;;AN000;; Reset AX value
  2264. MOV AL,BYTE PTR $M_SL.$M_S_VALUE+3 ;;AN000;; Get Day
  2265. CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string
  2266. PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;;
  2267. INC CX ;;AN000;; Increment count
  2268. MOV AL,BYTE PTR $M_SL.$M_S_VALUE+2 ;;AN000;; Get Month
  2269. CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string
  2270. $ENDIF ;;AN000;;
  2271. ;;
  2272. CMP WORD PTR $M_RT.$M_DATE_FORMAT,1 ;;AN000;; EUROPE Date Format
  2273. $IF E ;;AN000;; Beginning from end: (saved on the stack)
  2274. CALL $M_YEAR ;;AN000;; Get Year
  2275. CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string
  2276. PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;;
  2277. INC CX ;;AN000;;
  2278. XOR AX,AX ;;AN000;; Reset AX
  2279. MOV AL,BYTE PTR $M_SL.$M_S_VALUE+2 ;;AN000;; Get Month
  2280. CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string
  2281. PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;;
  2282. INC CX ;;AN000;;
  2283. MOV AL,BYTE PTR $M_SL.$M_S_VALUE+3 ;;AN000;; Get Day
  2284. CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string
  2285. $ENDIF ;;AN000;;
  2286. ;;
  2287. CMP WORD PTR $M_RT.$M_DATE_FORMAT,2 ;;AN000;; JAPAN Date Format
  2288. $IF E ;;AN000;; Beginning from end: (saved on the stack)
  2289. MOV AL,BYTE PTR $M_SL.$M_S_VALUE+3 ;;AN000;; Get Day
  2290. CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string
  2291. PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;;
  2292. INC CX ;;AN000;;
  2293. MOV AL,BYTE PTR $M_SL.$M_S_VALUE+2 ;;AN000;; Get Month
  2294. CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string
  2295. PUSH WORD PTR $M_RT.$M_DATE_SEPARA ;;AN000;;
  2296. INC CX ;;AN000;;
  2297. CALL $M_YEAR ;;AN000;; Get Year
  2298. CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string
  2299. $ENDIF ;;AN000;;
  2300. ;;
  2301. PUSH BP ;;AN000;; Restore return address
  2302. RET ;;AN000;; Return
  2303. ;;
  2304. $M_DATE_REPLACE ENDP ;;AN000;;
  2305. ;;
  2306. $M_GET_DATE PROC NEAR ;;AN000;;
  2307. MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info
  2308. MOV AL,0 ;;AN000;; Get current country info
  2309. LEA DX,$M_RT.$M_TEMP_BUF ;;AN000;; Set up addressibility to buffer
  2310. INT 21H ;;AN000;;
  2311. $IF C ;;AN000;; No,
  2312. MOV WORD PTR $M_RT.$M_DATE_FORMAT,$M_DEF_DATE_FORM ;;AN000;; Set default date format (BH)
  2313. MOV BYTE PTR $M_RT.$M_DATE_SEPARA,$M_DEF_DATE_SEP ;;AN000;; Set default date separator (BL)
  2314. $ENDIF ;;AN000;;
  2315. RET ;;AN000;;
  2316. $M_GET_DATE ENDP ;;AN000;;
  2317. ;;
  2318. $M_YEAR PROC NEAR ;;AN000;;
  2319. MOV AX,WORD PTR $M_SL.$M_S_VALUE ;;AN000;; Get Year
  2320. TEST $M_SL.$M_S_FLAG,Date_MDY_4 AND $M_DATE_MASK ;;AN000;; Was Month/Day/Year (2 Digits) specified?
  2321. $IF Z ;;AN000;;
  2322. CMP AX,$M_MAX_2_YEAR ;;AN000;; Get Year
  2323. $IF A ;;AN000;;
  2324. MOV AX,$M_MAX_2_YEAR ;;AN000;;
  2325. $ENDIF ;;AN000;;
  2326. $ENDIF ;;AN000;;
  2327. RET ;;AN000;;
  2328. $M_YEAR ENDP ;;AN000;;
  2329. ;;
  2330. $M_CONVERTDATE PROC NEAR ;;AN000;;
  2331. POP WORD PTR $M_RT.$M_TEMP_BUF ;;AN000;; Save return address
  2332. MOV $M_RT.$M_SIZE,CL ;;AN000;; Save the size before conversion
  2333. CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string
  2334. DEC CX ;;AN000;; Test if size only grew by 1
  2335. CMP CL,$M_RT.$M_SIZE ;;AN000;; Did size only grow by one
  2336. $IF E ;;AN000;; Yes,
  2337. MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0)
  2338. PUSH AX ;;AN000;; Save it
  2339. INC CX ;;AN000;; Count it
  2340. $ENDIF ;;AN000;;
  2341. INC CX ;;AN000;; Restore CX
  2342. PUSH WORD PTR $M_RT.$M_TEMP_BUF ;;AN000;; Save return address
  2343. RET ;;AN000;;
  2344. $M_CONVERTDATE ENDP ;;AN000;;
  2345. ;;
  2346. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2347. ENDIF ;;AN000;; END of include of DATE replace code
  2348. ;
  2349. IF TIMEmsg ;;AN000;; Is the request to include the code for TIME replace?
  2350. $M_REPLACE = TRUE ;;AN000;; Yes, THEN include it and flag that we will need common
  2351. $M_CHAR_ONLY = FALSE ;;AN000;; replacement code later
  2352. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2353. ;;
  2354. ;; PROC NAME: $M_TIME_REPLACE
  2355. ;;
  2356. ;; FUNCTION: Convert a time to a decimal ASCII string
  2357. ;; and prepare to display
  2358. ;; INPUTS: DS:SI points at corresponding SUBLIST
  2359. ;; ES:DI points at VALUE from SUBLIST
  2360. ;; OUTPUTS: CX contains number of characters on stack
  2361. ;; Top of stack --> Last character
  2362. ;; . . .
  2363. ;; Bot of stack --> First character
  2364. ;; REGS USED: BP,CX,AX
  2365. ;;
  2366. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2367. ;;
  2368. $M_TIME_REPLACE PROC NEAR ;;AN000;;
  2369. ;;
  2370. POP BP ;;AN000;; Save return address
  2371. MOV $M_RT.$M_DIVISOR,$M_BASE10 ;;AN000;; Set default divisor
  2372. CALL $M_GET_TIME ;;AN000;; All O.K.?
  2373. TEST $M_SL.$M_S_FLAG,Time_Cty_Type AND $M_TIME_MASK ;;AN000;; Is this a request for current country info?
  2374. $IF NZ ;;AN000;; Yes,
  2375. CMP BYTE PTR $M_RT.$M_TIME_FORMAT,0 ;;AN000;; Is the current country format 12 Hour?
  2376. $IF E ;;AN000;; Yes,
  2377. MOV AL,BYTE PTR $M_SL.$M_S_VALUE ;;AN000;; Get Hours
  2378. CMP AL,12 ;;AN000;; Is hour 12 or less?
  2379. $IF L,OR ;;AN000;; or
  2380. CMP AL,23 ;;AN000;; Is hour 24 or greater?
  2381. $IF G ;;AN000;; Yes,
  2382. MOV AL,$M_AM ;;AN000;;
  2383. PUSH AX ;;AN000;; Push an "a" to represent AM.
  2384. INC CX ;;AN000;;
  2385. $ELSE ;;AN000;; No,
  2386. MOV AL,$M_PM ;;AN000;;
  2387. PUSH AX ;;AN000;; Push an "p" to represent PM.
  2388. INC CX ;;AN000;;
  2389. $ENDIF ;;AN000;;
  2390. $ENDIF ;;AN000;;
  2391. $ENDIF ;;AN000;;
  2392. ;;
  2393. XOR AX,AX ;;AN000;;
  2394. XOR DX,DX ;;AN000;;
  2395. TEST $M_SL.$M_S_FLAG,Time_HHMMSSHH_Cty AND $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified?
  2396. $IF NZ ;;AN000;;
  2397. MOV AL,BYTE PTR $M_SL.$M_S_VALUE+3 ;;AN000;; Get Hundreds
  2398. CALL $M_CONVERTTIME ;;AN000;;
  2399. PUSH WORD PTR $M_RT.$M_DECI_SEPARA ;;AN000;;
  2400. INC CX ;;AN000;;
  2401. $ENDIF ;;AN000;;
  2402. TEST $M_SL.$M_S_FLAG,Time_HHMMSSHH_Cty AND $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified?
  2403. $IF NZ,OR ;;AN000;;
  2404. TEST $M_SL.$M_S_FLAG,Time_HHMMSS_Cty AND $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec (12 Hour) specified?
  2405. $IF NZ ;;AN000;;
  2406. MOV AL,BYTE PTR $M_SL.$M_S_VALUE+2 ;;AN000;; Get Seconds
  2407. CALL $M_CONVERTTIME ;;AN000;;
  2408. PUSH WORD PTR $M_RT.$M_TIME_SEPARA ;;AN000;;
  2409. INC CX ;;AN000;;
  2410. $ENDIF ;;AN000;;
  2411. ;; Do Hour/Min (12 Hour)
  2412. MOV AL,BYTE PTR $M_SL.$M_S_VALUE+1 ;;AN000;; Get Minutes
  2413. CALL $M_CONVERTTIME ;;AN000;;
  2414. PUSH WORD PTR $M_RT.$M_TIME_SEPARA ;;AN000;;
  2415. INC CX ;;AN000;;
  2416. ;;
  2417. MOV AL,BYTE PTR $M_SL.$M_S_VALUE ;;AN000;; Get Hours
  2418. TEST $M_SL.$M_S_FLAG,Time_Cty_Type AND $M_TIME_MASK ;;AN000;; Is this a request for current country info?
  2419. $IF NZ ;;AN000;; Yes,
  2420. CMP BYTE PTR $M_RT.$M_TIME_FORMAT,0 ;;AN000;; Is the current country format 12 Hour?
  2421. $IF E ;;AN000;; Yes,
  2422. CMP AL,13 ;;AN000;; Is hour less than 12?
  2423. $IF GE ;;AN000;; Yes,
  2424. SUB AL,12 ;;AN000;; Set to a 12 hour value
  2425. $ENDIF ;;AN000;;
  2426. CMP AL,0 ;;AN000;; Is hour less than 12?
  2427. $IF E ;;AN000;; Yes,
  2428. MOV AL,12 ;;AN000;; Set to a 12 hour value
  2429. $ENDIF ;;AN000;;
  2430. $ENDIF ;;AN000;;
  2431. $ENDIF ;;AN000;;
  2432. CALL $M_CONVERT2ASC ;;AN000;; Convert it to ASCII
  2433. ;;
  2434. PUSH BP ;;AN000;; Restore return address
  2435. RET ;;AN000;; Return
  2436. ;;
  2437. $M_TIME_REPLACE ENDP ;;AN000;;
  2438. ;;
  2439. $M_GET_TIME PROC NEAR ;;AN000;;
  2440. MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info
  2441. MOV AL,0 ;;AN000;; Get current country info
  2442. LEA DX,$M_RT.$M_TEMP_BUF ;;AN000;; Set up addressibility to buffer
  2443. INT 21H ;;AN000;;
  2444. $IF C ;;AN000;; No,
  2445. MOV WORD PTR $M_RT.$M_TIME_FORMAT,$M_DEF_TIME_FORM ;;AN000;; Set default time format (BH)
  2446. MOV BYTE PTR $M_RT.$M_TIME_SEPARA,$M_DEF_TIME_SEP ;;AN000;; Set default time separator (BL)
  2447. MOV BYTE PTR $M_RT.$M_DECI_SEPARA,$M_DEF_DECI_SEP ;;AN000;; Set default time separator (BL)
  2448. $ENDIF ;;AN000;;
  2449. RET ;;AN000;;
  2450. $M_GET_TIME ENDP ;;AN000;;
  2451. ;;
  2452. $M_CONVERTTIME PROC NEAR ;;AN000;;
  2453. POP WORD PTR $M_RT.$M_TEMP_BUF ;;AN000;; Save return address
  2454. MOV $M_RT.$M_SIZE,CL ;;AN000;; Save the size before conversion
  2455. CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string
  2456. DEC CX ;;AN000;; Test if size only grew by 1
  2457. CMP CL,$M_RT.$M_SIZE ;;AN000;; Did size only grow by one
  2458. $IF E ;;AN000;; Yes,
  2459. MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0)
  2460. PUSH AX ;;AN000;; Save it
  2461. INC CX ;;AN000;; Count it
  2462. $ENDIF ;;AN000;;
  2463. INC CX ;;AN000;; Restore CX
  2464. PUSH WORD PTR $M_RT.$M_TEMP_BUF ;;AN000;; Save return address
  2465. RET ;;AN000;;
  2466. $M_CONVERTTIME ENDP ;;AN000;;
  2467. ;;
  2468. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2469. ENDIF ;;AN000;; END of include of TIME replace
  2470. ENDIF ;;AN000;; END of include of Replacement common code
  2471. ;
  2472. IF INPUTmsg ;;AN000;; Is the request to include the code for NUM replace?
  2473. INPUTmsg = FALSE ;;AN000;; Yes, THEN include it and reset the flag
  2474. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2475. ;;
  2476. ;; PROC NAME: $M_WAIT_FOR_INPUT
  2477. ;;
  2478. ;; FUNCTION: To accept keyed input and return extended key value
  2479. ;; in AX register
  2480. ;; INPUTS: DL contains the DOS function requested for input
  2481. ;; OUPUTS: AX contains the extended key value that was read
  2482. ;; REGS USED:
  2483. ;;
  2484. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2485. ;;
  2486. $M_WAIT_FOR_INPUT PROC NEAR ;;AN000;;
  2487. ;;
  2488. PUSH CX ;;AN000;; Save CX
  2489. PUSH DX ;;AN000;; Save DX
  2490. PUSH DS ;;AN000;; Save Data segment
  2491. ;;
  2492. CMP DL,DOS_CLR_KEYB_BUF_MASK ;;AN001;; Are we to clear the keyboard buffer?
  2493. $IF A ;;AN001;; Yes,
  2494. MOV AL,DL ;;AN001;; Mov function into AL
  2495. AND AL,LOW_NIB_MASK ;;AN001;; Mask out the C in high nibble
  2496. MOV AH,DOS_CLR_KEYB_BUF ;;AN001;; Set input function
  2497. $ELSE ;;AN001;; No,
  2498. MOV AH,DL ;;AN000;; Put DOS function in AH
  2499. $ENDIF ;;AN001;;
  2500. PUSH ES ;;AN000;; Get output buffer segment
  2501. POP DS ;;AN000;;
  2502. MOV DX,DI ;;AN000;; Get output buffer offset in case needed
  2503. INT 21H ;;AN000;; Get keyboard input
  2504. POP DS ;;AN000;;
  2505. CMP DL,DOS_BUF_KEYB_INP ;;AN000;;
  2506. CLC ;;AN000;;
  2507. $IF NE ;;AN000;; If character input
  2508. CALL $M_IS_IT_DBCS ;;AN000;; Is this character DBCS?
  2509. $IF C ;;AN000;;
  2510. MOV CL,AL ;;AN000;; Save first character
  2511. MOV AH,DL ;;AN001;; Get back function
  2512. INT 21H ;;AN000;; Get keyboard input
  2513. MOV AH,CL ;;AN000;; Retreive first character AX = xxxx
  2514. CLC ;;AN000;; Clear carry condition
  2515. $ELSE ;;AN000;;
  2516. MOV AH,0 ;;AN000;; AX = 00xx where xx is SBCS
  2517. $ENDIF ;;AN000;;
  2518. $ENDIF ;;AN000;;
  2519. ;;
  2520. $IF NC ;;AN000;;
  2521. POP DX ;;AN000;;
  2522. POP CX ;;AN000;;
  2523. $ELSE ;;AN000;;
  2524. ADD SP,4 ;;AN000;;
  2525. STC ;;AN000;; Reset carry flag
  2526. $ENDIF ;;AN000;;
  2527. RET ;;AN000;; Return
  2528. ;;
  2529. $M_WAIT_FOR_INPUT ENDP ;;AN000;;
  2530. ;;
  2531. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2532. ENDIF ;;AN000;; END of include of Wait for Input
  2533. ENDIF ;;AN000;; END of include of SYSDISPMSG
  2534. ENDIF ;;AN000;; END of include of MSG_DATA_ONLY
  2535. ENDIF ;;AN000;; END of include of Structure only
  2536.