Leaked source code of windows server 2003
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.

1054 lines
46 KiB

  1. ;/*
  2. ; * Microsoft Confidential
  3. ; * Copyright (C) Microsoft Corporation 1988 - 1991
  4. ; * All Rights Reserved.
  5. ; */
  6. ;************************************************************
  7. ;**
  8. ;**
  9. ;** NAME: Support for HP PCL printers added to GRAPHICS.
  10. ;**
  11. ;** DESCRIPTION: I changed the default printer type from GRAPHICS to HPDEFAULT
  12. ;** because we have a section in the profile under 'HPDEFAULT' that
  13. ;** will satisfactorily handle all of our printers. I also changed
  14. ;** the number of bytes for the printer type from 9 to 16 because
  15. ;** of the RUGGEDWRITERWIDE.
  16. ;**
  17. ;** DOCUMENTATION NOTES: This version of GRINST.ASM differs from the previous
  18. ;** version only in terms of documentation.
  19. ;**
  20. ;**
  21. ;************************************************************
  22. PAGE ,132
  23. TITLE DOS - GRAPHICS Command - Installation Modules
  24. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  25. ;; DOS - GRAPHICS Command
  26. ;;
  27. ;;
  28. ;; File Name: GRINST.ASM
  29. ;; ----------
  30. ;;
  31. ;; Description:
  32. ;; ------------
  33. ;; This file contains the installation modules for the
  34. ;; GRAPHICS command.
  35. ;;
  36. ;; GRAPHICS_INSTALL is the main module.
  37. ;;
  38. ;; GRAPHICS_INSTALL calls modules in GRLOAD.ASM to load
  39. ;; the GRAPHICS profile and GRPARMS.ASM to parse the command line.
  40. ;;
  41. ;;
  42. ;; Documentation Reference:
  43. ;; ------------------------
  44. ;; OASIS High Level Design
  45. ;; OASIS GRAPHICS I1 Overview
  46. ;; DOS 3.3 Message Retriever Interface Supplement.
  47. ;; TUPPER I0 Document - PARSER HIGH LEVEL DESIGN REVIEW
  48. ;;
  49. ;; Procedures Contained in This File:
  50. ;; ----------------------------------
  51. ;; GRAPHICS_INSTALL - Main installation module
  52. ;; CHAIN_INTERRUPTS - Chain interrupts 5, 2F, EGA Save Pointers
  53. ;; COPY_PRINT_MODULES - Throw away one set of print modules
  54. ;;
  55. ;;
  56. ;; Include Files Required:
  57. ;; -----------------------
  58. ;; GRLOAD.EXT - Externals for profile load
  59. ;; GRLOAD2.EXT - Externals for profile load
  60. ;; GRCTRL.EXT - Externals for print screen control
  61. ;; GRPRINT.EXT - Externals for print modules
  62. ;; GRCPSD.EXT - Externals for COPY_SHARED_DATA module
  63. ;; GRPARMS.EXT - External for GRAPHICS command line parsing
  64. ;; GRPARSE.EXT - External for DOS parser
  65. ;; GRBWPRT.EXT - Externals for Black and white printing modules
  66. ;; GRCOLPRT.EXT - Externals for color printing modules
  67. ;; GRINT2FH.EXT - Externals for Interrupt 2Fh driver.
  68. ;;
  69. ;; GRMSG.EQU - Equates for the GRAPHICS error messages
  70. ;; SYSMSG.INC - DOS message retriever
  71. ;;
  72. ;; GRSHAR.STR - Shared Data Area Structure
  73. ;;
  74. ;; STRUC.INC - Macros for using structured assembly language
  75. ;;
  76. ;; External Procedure References:
  77. ;; ------------------------------
  78. ;; FROM FILE GRLOAD.ASM:
  79. ;; LOAD_PROFILE - Main module for profile loading
  80. ;; SYSPARSE - DOS system parser
  81. ;; SYSDISPMSG - DOS message retriever
  82. ;;
  83. ;; Linkage Instructions:
  84. ;; --------------------
  85. ;; Refer to GRAPHICS.ASM
  86. ;;
  87. ;; Change History:
  88. ;; ---------------
  89. ;; M001 NSM 1/30/91 Install our int 10 handler also along with
  90. ;; int 2f and int 5 handlers to take care of alt
  91. ;; prt-sc select calls made by ANSI.SYS
  92. ;;
  93. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  94. ;;
  95. CODE SEGMENT PUBLIC 'CODE' ;;
  96. ASSUME CS:CODE,DS:CODE ;;
  97. ;;
  98. .XLIST ;;
  99. INCLUDE GRSHAR.STR ;; Include the Shared data area structure
  100. INCLUDE SYSMSG.INC ;; Include DOS message retriever
  101. INCLUDE STRUC.INC ;; Include macros - Structured Assembler
  102. INCLUDE GRLOAD.EXT ;; Bring in external declarations
  103. INCLUDE GRLOAD2.EXT ;;
  104. INCLUDE GRLOAD3.EXT ;;
  105. INCLUDE GRCTRL.EXT ;;
  106. INCLUDE GRBWPRT.EXT ;;
  107. INCLUDE GRCOLPRT.EXT ;;
  108. INCLUDE GRCPSD.EXT ;;
  109. INCLUDE GRINT2FH.EXT ;;
  110. INCLUDE GRCTRL.EXT ;;
  111. INCLUDE GRPARSE.EXT ;;
  112. INCLUDE GRPARMS.EXT ;;
  113. INCLUDE GRMSG.EQU ;;
  114. ;;
  115. MSG_UTILNAME <GRAPHICS> ;; Identify ourself to Message retriever.
  116. ;; Include messages
  117. MSG_SERVICES <MSGDATA> ;;
  118. MSG_SERVICES <LOADmsg,DISPLAYmsg,CHARmsg,NUMmsg> ;;
  119. MSG_SERVICES <GRAPHICS.CL1,GRAPHICS.CL2,GRAPHICS.CLA,GRAPHICS.CLB,GRAPHICS.CLC>
  120. .LIST ;;
  121. ;;
  122. PUBLIC GRAPHICS_INSTALL ;;
  123. PUBLIC CHAIN_INTERRUPTS
  124. PUBLIC TEMP_SHARED_DATA_PTR ;;
  125. PUBLIC PRINTER_TYPE_PARM ;;
  126. PUBLIC PRINTER_TYPE_LENGTH ;;
  127. PUBLIC PROFILE_PATH ;;
  128. PUBLIC PRINTBOX_ID_PTR ;;
  129. PUBLIC PRINTBOX_ID_LENGTH ;;
  130. PUBLIC DEFAULT_BOX ;;
  131. PUBLIC LCD_BOX ;;
  132. PUBLIC NB_FREE_BYTES ;;
  133. PUBLIC SYSDISPMSG ;;
  134. PUBLIC DISP_ERROR ;;
  135. PUBLIC INSTALLED ;;
  136. PUBLIC ERROR_DEVICE ;;
  137. PUBLIC STDERR ;;
  138. PUBLIC STDOUT ;;
  139. PUBLIC RESIDENT_SHARED_DATA_SIZE ;;
  140. ;;
  141. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  142. ;;
  143. ;; Install Variables
  144. ;;
  145. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  146. ;;
  147. NO EQU 0 ;;
  148. YES EQU 1 ;;
  149. INSTALLED DB NO ;; YES if GRAPHICS already installed
  150. ;;
  151. ;;
  152. BYTES_AVAIL_PSP_OFF EQU 6 ;; Word number 6 of the PSP is the
  153. ;; number of bytes available in the
  154. ;; current segment
  155. ;;
  156. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  157. ;;
  158. ;; GRLOAD (PROFILE LOADING) INPUT PARMS:
  159. ;;
  160. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  161. ;\/ ~~mda ----------------------------------------------------------------------------
  162. ; Changed the default printer type from GRAPHICS to HPDEFAULT,
  163. ; which really isn't a printer type. In the GRAPHICS.PRO
  164. ; file there is a section that starts 'PRINTER HPDEFAULT'
  165. ; that has all the necessary parms to support all HP printers
  166. ; satisfactorily. Also changed the number of bytes for the
  167. ; printer type from 9 to 16 because of the RUGGEDWRITERWIDE.
  168. ;
  169. ; MD 6/4/90 - this is a backwards compatibility problem. Changed default
  170. ; back to Graphics
  171. PRINTER_TYPE_PARM DB "GRAPHICS",9 DUP(0) ; Printer type
  172. ;; (default=Graphics)
  173. ;/\ ~~mda -----------------------------------------------------------------------------
  174. PRINTER_TYPE_LENGTH DB 17 ;; Printer type maximum length of ASCIIZ
  175. PROFILE_PATH DB 128 DUP(0) ;; Profile name with full path
  176. ;; (Max size for ASCIIZ is 128)
  177. PRINTBOX_ID_PTR DW DEFAULT_BOX ;; Offset of ASCIIZ string containing
  178. DEFAULT_BOX DB "STD",14 DUP(0); the printbox id. (DEFAULT = STD)
  179. LCD_BOX DB "LCD",14 DUP(0); ASCIIZ string for the LCD printboxID
  180. PRINTBOX_ID_LENGTH DB 17 ;; Max. length for the printbox id.
  181. ;; ASCIIZ string
  182. NB_FREE_BYTES DW ? ;; Number of bytes available in our
  183. ;; resident segment
  184. RESIDENT_SHARED_DATA_SIZE DW ? ;; Size in bytes of the RESIDENT Shared
  185. ;; data area (if GRAPHICS already
  186. ;; installed).
  187. END_OF_RESIDENT_CODE DW ? ;; Offset of the end of the code that
  188. ;; has to be made resident.
  189. TEMP_SHARED_DATA_PTR DW ? ;; Offset of the temporary Shared area
  190. ;;
  191. ERROR_DEVICE DW STDERR ;; Device DISP_ERROR will output
  192. ;; messages to (STDERR or STDOUT)
  193. PAGE
  194. ;===============================================================================
  195. ;
  196. ; GRAPHICS_INSTALL : INSTALL GRAPHICS.COM
  197. ;
  198. ;-------------------------------------------------------------------------------
  199. ;
  200. ; INPUT: Command line parameters
  201. ; GRAPHICS profile - A file describing printer characteristics and
  202. ; attributes.
  203. ;
  204. ; OUTPUT: If first time invoked:
  205. ; INT 5 VECTOR and INT 2FH VECTOR are replaced; only the required
  206. ; code for printing the screen is made resident.
  207. ; else,
  208. ; The resident code is updated to reflect changes in printing
  209. ; options.
  210. ;
  211. ;-------------------------------------------------------------------------------
  212. ;;
  213. ;; DESCRIPTION:
  214. ;;
  215. ;; This module intalls GRAPHICS code and data.
  216. ;;
  217. ;; An INT 2FH driver is also installed.
  218. ;;
  219. ;; If this driver is already present then, we assume GRAPHICS was installed
  220. ;; and do not install it again but, simply update the resident code.
  221. ;;
  222. ;; The resident code contains ONLY the code and data needed for Printing
  223. ;; the screen. The code needed is determined according to the command line
  224. ;; parameters and the information extracted from the printer profile.
  225. ;;
  226. ;; The printer profile is parsed according to the current hardware setting
  227. ;; and also to the command line options. The information extracted from
  228. ;; the profile is stored in a Data area shared between the installation
  229. ;; process and the Print Screen process.
  230. ;;
  231. ;; A temporary Shared Data Area is FIRST built at the end of the .COM file
  232. ;; Before building it, we verify that there is
  233. ;; enough memory left in the current segment. If not, the installation
  234. ;; process is aborted.
  235. ;;
  236. ;; This temporary Data area when completed will be copied over the
  237. ;; installation code. Therefore, the file comprising GRAPHICS must be
  238. ;; linked in a specific order with the installation modules being last.
  239. ;;
  240. ;; These modules will be overwritten by the Shared Data area and the EGA
  241. ;; dynamic save area before we exit and stay resident.
  242. ;;
  243. ;; The end of the resident code is the end of the Shared Data area, anything
  244. ;; else beyond that is not made resident.
  245. ;;
  246. ;; The pointer to the resident Shared Data area is declared within the
  247. ;; Interrupt 2Fh driver. This pointer is initialized by the installation
  248. ;; process and points to the shared data area at Print Screen time.
  249. ;;
  250. ;; Depending on the type of printer attached (i.e., Black and white or Color)
  251. ;; only one set of modules is made resident during the installation.
  252. ;;
  253. ;; The set of print modules required is copied over the previous one at
  254. ;; location "PRINT_MODULE_START". This location is declared within
  255. ;; GRCOLPRT which must be linked before GRBWPRT
  256. ;;
  257. ;; When copying one of the 2 sets of print modules we reserve enough space
  258. ;; for the larger of them. Therefore, if GRAPHICS is already installed but
  259. ;; is reinvoked with a different printer type which needs a bigger set of
  260. ;; modules: this new set of modules is simply recopied over the existing
  261. ;; one in the resident code.
  262. ;;
  263. ;; The Shared Data area is copied rigth after the set of modules that we keep
  264. ;; that is, over the unused set of modules.
  265. ;;
  266. ;;
  267. ;-------------------------------------------------------------------------------
  268. ;;
  269. ;; Register Conventions:
  270. ;; BP - points to start of Temp Shared Data (Transiant code)
  271. ;;
  272. ;; Called By:
  273. ;; Entry point for GRAPHICS command processing.
  274. ;;
  275. ;; External Calls:
  276. ;; INT 2FH, LOAD_MESSAGES, LOAD_PROFILE, PARSE_PARMS
  277. ;; CHAIN_INTERRUPTS, COPY_SHARED_DATA, DISPLAY_MESSAGE
  278. ;; COPY_PRINT_MODULES
  279. ;;
  280. ;-------------------------------------------------------------------------------
  281. ;;
  282. ;; LOGIC:
  283. ;; Load the message retriever
  284. ;; IF carry flag is set (incorrect DOS version) THEN
  285. ;; Issue message (COMMON1)
  286. ;; Exit
  287. ;; ENDIF
  288. ;;
  289. ;; Get number of bytes available in the segment from PSP (word 6)
  290. ;; /* This is needed since we construct a temporary Shared data area at the
  291. ;; of the .COM file */
  292. ;;
  293. ;; /* Build Shared Data in temporary area */
  294. ;; END_OF_RESIDENT_CODE := (end of .COM file)
  295. ;; NB_FREE_BYTES := Number of bytes availables
  296. ;;
  297. ;; CALL PARSE_PARMS
  298. ;; IF error THEN /* PARSE_PARMS will issue messages */
  299. ;; Exit
  300. ;; ENDIF
  301. ;;
  302. ;; CALL LOAD_PROFILE
  303. ;; IF profile errors THEN
  304. ;; Exit /* LOAD_PROFILE will issue messages */
  305. ;; ENDIF
  306. ;;
  307. ;; Issue INT 2FH Install Check call (AX=AC00H)
  308. ;; /* INT 2FH returns ES:[DI] pointing to the shared data area */
  309. ;; IF already installed THEN
  310. ;; THEN
  311. ;; Move NO to PRINT_SCREEN_ALLOWED in resident Shared Data
  312. ;; SHARED_DATA_AREA_PTR := DI
  313. ;; ELSE
  314. ;; MOV PRINT_SCREEN_ALLOWED,NO
  315. ;; CALL CHAIN_INTERRUPTS /* Install INT 5 and INT 2FH vectors */
  316. ;; ES := Our segment
  317. ;; ENDIF
  318. ;; /* Keep only Print Black and White or Print Color: */
  319. ;; CALL COPY_PRINT_MODULES
  320. ;; /* COPY_SHARED_DATA will terminate & stay resident */
  321. ;; Set up registers for copy & terminate call
  322. ;; /* reserve enough memory to handle any printer in the profile*/
  323. ;; jump to COPY_SHARED_DATA module
  324. ;; ELSE
  325. ;; /* Shared Data has been built in place */
  326. ;; move YES to PRINT_SCREEN_ALLOWED
  327. ;; Return to DOS
  328. ;; ENDIF
  329. ;;
  330. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  331. GRAPHICS_INSTALL PROC NEAR ;
  332. ;-------------------------------------------------------------------------------
  333. ; Load the error messages
  334. ;-------------------------------------------------------------------------------
  335. CALL SYSLOADMSG ; Load messages
  336. .IF C ; If error when loading messages
  337. .THEN ; then,
  338. MOV CX,0 ; CX := No substitution in message
  339. MOV AX,1 ; AX := msg nb. for "Invalid DOS version"
  340. CALL DISP_ERROR ; Display error message
  341. JMP ERROR_EXIT ; and quit
  342. .ENDIF
  343. ;-------------------------------------------------------------------------------
  344. ; Get offset of where to build the TEMPORARY Shared Data area (always built)
  345. ;-------------------------------------------------------------------------------
  346. MOV BP,OFFSET LIMIT ; Build it at the end of this .COM file
  347. ; (LIMIT = the offset of the last byte
  348. ; of the last .OBJ file linked with
  349. ; GRAPHICS)
  350. MOV TEMP_SHARED_DATA_PTR,BP ;
  351. ;-------------------------------------------------------------------------------
  352. ; Determine if GRAPHICS is already installed; get the resident segment value
  353. ;-------------------------------------------------------------------------------
  354. MOV AH,PRT_SCR_2FH_NUMBER ; Call INT 2FH (the Multiplex interrupt)
  355. XOR AL,AL ; for Print Screen handler
  356. INT 2FH ;
  357. .IF <AH EQ 0FFH> ; IF already installed
  358. .THEN ; then,
  359. ;----------------------------------------------------------------------------
  360. ; GRAPHICS is already installed: Get pointer to the EXISTING Shared Data area
  361. ;----------------------------------------------------------------------------
  362. MOV INSTALLED,YES ; Say it's installed
  363. MOV AX,ES ; Get the segment and offset of the
  364. MOV SHARED_DATA_AREA_PTR,DI; resident Shared Data area.
  365. MOV RESIDENT_CODE_SEG,AX ; (returned in ES:DI)
  366. MOV AX,ES:[DI].SD_TOTAL_SIZE ; CX := Size of the existing Shared area
  367. MOV MAX_BLOCK_END, AX
  368. ; Disable print screen because we will
  369. MOV ES:PRINT_SCREEN_ALLOWED,NO ; be updating the resident code.
  370. .ELSE ; ELSE, not installed:
  371. ;------------------------------------------------------------------------
  372. ; GRAPHICS is NOT installed: RESIDENT shared data area is in OUR segment
  373. ;------------------------------------------------------------------------
  374. PUSH CS ; The Shared Data area will be in our
  375. POP RESIDENT_CODE_SEG ; segment.
  376. .ENDIF
  377. ;-------------------------------------------------------------------------------
  378. ; Determine in AX how many bytes are available for building the TEMPORARY SHARED
  379. ; DATA AREA:
  380. ;-------------------------------------------------------------------------------
  381. ; MOV AX,ES:BYTES_AVAIL_PSP_OFF;AX := Number of bytes availables in
  382. ; the current segment (as indicated in PSP)
  383. ;M000; mov ax,0FFFFh ; Assume available to top of seg
  384. ;M000;
  385. ;Check for amount of memory that is free without assuming 64K. This causes
  386. ;crashes if it is loaded into UMBs.
  387. ;
  388. push cx
  389. mov ax,offset Limit
  390. add ax,15
  391. mov cl,4
  392. shr ax,cl ;round up to nearest para
  393. mov cx,es ;get our PSP seg
  394. add ax,cx ;end of load image
  395. sub ax,es:[2] ;es:[2] = top of our memory block
  396. neg ax ;ax = # of paras free
  397. test ax,0f000h ;greater than 64K bytes?
  398. jz lt64K ;no
  399. mov ax,0ffffh ;stop at 64K
  400. jmp short gotfree
  401. lt64K:
  402. mov cl,4
  403. shl ax,cl ;ax = # of bytes free above us
  404. gotfree:
  405. pop cx
  406. ;
  407. ;M000; End changes;
  408. ;
  409. ;;; .IF <AX B <OFFSET LIMIT>> ; If there is no bytes available past
  410. ;;; .THEN ; the end of our .COM file
  411. ;;; XOR AX,AX ; then, AX := 0 bytes available
  412. ;;; .ELSE ;
  413. ;;; SUB AX,OFFSET LIMIT ; else, AX := Number of FREE bytes
  414. ;;; .ENDIF ; in this segment
  415. ;---AX = Number of bytes in our segment available for building the Temp Shared
  416. ;---data area.
  417. ;---IF ALREADY INSTALLED: Get the size of the existing Shared data area.
  418. ;---Since the temporary shared data area will be copied over the resident
  419. ;---shared data area, we do not want to build it any bigger than the one
  420. ;---it will overwrite. Therefore we do not give to LOAD_PROFILE more space
  421. ;---than the size of the existing Shared data area.
  422. .IF <INSTALLED EQ YES> ; If already installed then,
  423. .THEN
  424. PUSH CS:RESIDENT_CODE_SEG ; ES:[DI] := Resident Shared data area
  425. POP ES ;
  426. MOV DI,SHARED_DATA_AREA_PTR ;
  427. MOV CX,ES:[DI].SD_TOTAL_SIZE ; CX := Size of the existing Shared area
  428. MOV RESIDENT_SHARED_DATA_SIZE,CX ; Save size for LOAD_PROFILE
  429. .IF <AX A CX> ; If AX > size of existing SDA
  430. MOV AX,CX ; then, AX := Size of existing Shared area
  431. .ENDIF ;
  432. .ENDIF
  433. ; NB_FREE_BYTES := Number of bytes
  434. MOV NB_FREE_BYTES,AX ; available for
  435. ; building the TEMPORARY shared area
  436. ;-------------------------------------------------------------------------------
  437. ; Parse the command line parameters
  438. ;-------------------------------------------------------------------------------
  439. MOV BYTE PTR CS:[BP].SWITCHES,0 ; Init. the command line switches
  440. PUSH CS ; Set ES to segment containing the PSP
  441. POP ES
  442. CALL PARSE_PARMS ; Set switches in the Temp. Shared Area
  443. .IF C ; If error when parsing the command
  444. .THEN ; line then, EXIT
  445. JMP ERROR_EXIT
  446. .ENDIF
  447. ;-------------------------------------------------------------------------------
  448. ; Parse the printer profile - Build the temporary Shared data area
  449. ;-------------------------------------------------------------------------------
  450. CALL LOAD_PROFILE ; Builds profile info in Temporary Shared
  451. ; Data
  452. .IF C ; If error when loading the profile
  453. .THEN ; then, EXIT
  454. JMP ERROR_EXIT
  455. .ENDIF
  456. ;-------------------------------------------------------------------------------
  457. ; Check if /B was specified with a BLACK and WHITE printer:(invalid combination)
  458. ;-------------------------------------------------------------------------------
  459. .IF <CS:[BP].PRINTER_TYPE EQ BLACK_WHITE> AND
  460. .IF <BIT CS:[BP].SWITCHES NZ BACKGROUND_SW>
  461. .THEN
  462. MOV AX,INVALID_B_SWITCH ; Error := /B invalid with B&W prt.
  463. MOV CX,0 ; No substitution
  464. CALL DISP_ERROR ; Display error message
  465. JMP SHORT ERROR_EXIT ; and quit
  466. .ENDIF
  467. ;-------------------------------------------------------------------------------
  468. ;
  469. ; RELOCATE THE TEMPORARY SHARED DATA AREA AND THE SET OF REQUIRED PRINT MODULES
  470. ;
  471. ; (Discard the set of print modules not needed with the printer attached and
  472. ; discard all the code not used at print screen time).
  473. ;
  474. ; If GRAPHICS is already installed then, we copy the
  475. ; Shared Data area and the print modules over the previous ones installed in
  476. ; resident memory.
  477. ;
  478. ; If we are installed for the first time then, we copy those over the
  479. ; installation modules before we exit and stay resident.
  480. ;
  481. ; A temporaty Shared Data area is always created even if a resident one
  482. ; already exist (it is then, copied over), a set of print modules is recopied
  483. ; only if needed.
  484. ;
  485. ; NOTE: END_OF_RESIDENT_CODE points to the first location over which code
  486. ; may be relocated. After data or code is relocated, END_OF_RESIDENT_CODE
  487. ; is updated and points to the next available location for copying code
  488. ; that will stay resident.
  489. ;-------------------------------------------------------------------------------
  490. ;-------------------------------------------------------------------------------
  491. ; Initialize the pointer to the next available location for resident code:
  492. ;-------------------------------------------------------------------------------
  493. .IF <INSTALLED EQ NO> ; If not installed
  494. .THEN ; then,
  495. MOV END_OF_RESIDENT_CODE,OFFSET PRINT_MODULE_START
  496. .ENDIF ; we make everything up to the print
  497. ; modules resident code.
  498. ;-------------------------------------------------------------------------------
  499. ; Keep only the set of print modules that is needed:
  500. ;-------------------------------------------------------------------------------
  501. CALL COPY_PRINT_MODULES ; Updates END_OF_RESIDENT_CODE
  502. ;-------------------------------------------------------------------------------
  503. ; Replace the interrupt vectors and install the EGA dynamic area (if needed)
  504. ;-------------------------------------------------------------------------------
  505. .IF <INSTALLED EQ NO> ; If not already installed
  506. .THEN ; then,
  507. ;------Release evironment vector ;AN002;
  508. CALL RELEASE_ENVIRONMENT ; release unneeded environment vector ;AN002;
  509. ;------Replace the interrupt vectors
  510. MOV PRINT_SCREEN_ALLOWED,NO ; Disable Print Screen
  511. CALL CHAIN_INTERRUPTS ; Replace the interrupt vectors
  512. ; (END_OF_RESIDENT_CODE is updated)
  513. CALL DET_HW_CONFIG ; Find what display adapter we got
  514. .IF <CS:[BP].HARDWARE_CONFIG EQ EGA>;If EGA is present
  515. .THEN ; then,
  516. CALL INST_EGA_SAVE_AREA ; Install the EGA dynamic save area
  517. .ENDIF ; (END_OF_RESIDENT_CODE is updated)
  518. ;------Calculate the size of the resident code
  519. MOV DX,END_OF_RESIDENT_CODE ; DX := End of resident code
  520. ADD DX,CS:[BP].SD_TOTAL_SIZE; Add size of Shared Data area
  521. MOV CL,4 ;
  522. SHR DX,CL ; convert to paragraphs
  523. INC DX ; and add 1
  524. ;------Set AX to DOS exit function call - (COPY_SHARED_DATA will exit to DOS)
  525. MOV AH,31H ; Function call to terminate but stay
  526. XOR AL,AL ; resident
  527. .ELSE
  528. MOV AH,4CH ; Function call to terminate
  529. XOR AL,AL ; (EXIT to calling process)
  530. .ENDIF
  531. ;-------------------------------------------------------------------------------
  532. ; Copy the temporary shared data area in the resident code
  533. ;-------------------------------------------------------------------------------
  534. MOV CX,CS:[BP].SD_TOTAL_SIZE; CX := MOVSB count for COPY_SHARED_DATA
  535. MOV SI,BP ; DS:SI := Temporary Shared data area
  536. PUSH RESIDENT_CODE_SEG ; ES:DI := Resident Shared data area:
  537. POP ES ;
  538. .IF <INSTALLED EQ NO> ; If not installed
  539. .THEN ; then,
  540. MOV DI,END_OF_RESIDENT_CODE; DI := End of resident code
  541. MOV BP,DI ; BP := New resident Shared data area
  542. MOV SHARED_DATA_AREA_PTR,DI; Update pointer to resident Shar. area
  543. .ELSE ; else,
  544. MOV DI,SHARED_DATA_AREA_PTR ; DI := Existing Shared data area
  545. MOV BP,DI ; BP = DI:= Existing Shared data area
  546. .ENDIF
  547. JMP COPY_SHARED_DATA ; Jump to proc that copies area in new
  548. ; part of memory and exits to DOS
  549. ERROR_EXIT:
  550. .IF <INSTALLED EQ YES> ; If we are already installed, re-enable
  551. MOV ES,RESIDENT_CODE_SEG ; print screens
  552. MOV ES:PRINT_SCREEN_ALLOWED,YES
  553. .ENDIF ;
  554. ;
  555. MOV AH,4CH ; Function call to terminate
  556. MOV AL,1 ; (EXIT to calling process)
  557. INT 21H
  558. GRAPHICS_INSTALL ENDP
  559. PAGE
  560. ;===============================================================================
  561. ;
  562. ; INST_EGA_SAVE_AREA : INSTALL A DYNAMIC SAVE AREA FOR THE EGA PALETTE REGISTERS
  563. ;
  564. ;-------------------------------------------------------------------------------
  565. ;
  566. ; INPUT: DS = Data segment for our code
  567. ; END_OF_RESIDENT_CODE = Offset of the end of the resident code
  568. ;
  569. ; OUTPUT: END_OF_RESIDENT_CODE is updated to point to the end of the code
  570. ; that will stay resident.
  571. ; SAVE_AREA_PTR in BIOS segment is updated.
  572. ;
  573. ;-------------------------------------------------------------------------------
  574. ;;
  575. ;; Data Structures Referenced:
  576. ;; Shared Data Area
  577. ;;
  578. ;; Description:
  579. ;; ************* The EGA Dynamic Save Area will be built over top
  580. ;; ** NOTE ** of the profile loading modules (file GRLOAD.ASM)
  581. ;; ************* to avoid having to relocate this area just before
  582. ;; terminating. This is safe since the maximum memory used is
  583. ;; 288 bytes and the profile loading modules are MUCH larger than
  584. ;; this. So GRLOAD.ASM MUST be linked before GRINST.ASM and after
  585. ;; GRPRINT.ASM.
  586. ;;
  587. ;; BIOS will update the dynamic save area whenener it's aware the palette
  588. ;; registers have been updated.
  589. ;;
  590. ;; BIOS 4A8H BIOS SAVE EGA DYNAMIC
  591. ;; POINTER: POINTER TABLE SAVE AREA
  592. ;; ��������Ŀ ������������Ŀ (16 first bytes are the 16
  593. ;; � *���������������>� � EGA palette registers)
  594. ;; ���������� ������������Ĵ �����������Ŀ
  595. ;; � *���������������>�����������Ĵ
  596. ;; ������������Ĵ �����������Ĵ
  597. ;; � � �����������Ĵ
  598. ;; ������������Ĵ .
  599. ;; � � .
  600. ;; ������������Ĵ . 256 bytes
  601. ;; � � .
  602. ;; ������������Ĵ .
  603. ;; � � �����������Ĵ
  604. ;; ������������Ĵ �����������Ĵ
  605. ;; � � �����������Ĵ
  606. ;; ������������Ĵ �����������Ĵ
  607. ;; � � �����������Ĵ
  608. ;; �������������� �������������
  609. ;;
  610. ;; Called By:
  611. ;; GRAPHICS_INSTALL
  612. ;;
  613. ;; External Calls:
  614. ;;
  615. ;; Logic:
  616. ;; IF EGA Dynamic Save Area NOT established THEN
  617. ;; /* Required since default table is in ROM */
  618. ;; IF Save Table is in ROM
  619. ;; Replicate all the Save Area Table in resident RAM just before
  620. ;; the Shared Data Area
  621. ;; ENDIF
  622. ;; Allocate 256 bytes for EGA Dynamic Save Area just before the
  623. ;; Shared Data Area
  624. ;; Update END_OF_RESIDENT_CODE
  625. ;; ENDIF
  626. ;; RETURN
  627. ;;
  628. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  629. ;;
  630. BIOS_SAVE_PTR EQU 4A8H ;; Offset of the BIOS Save Ptr area
  631. SAVE_AREA_LEN EQU 8*4 ;; There are 8 pointers in the Save area
  632. EGA_DYNAMIC_LEN EQU 256 ;; Length of the EGA dynamic save area
  633. ; Standard default colours for the Enhanced Graphics Adapter: (rgbRGB values)
  634. ; The following table is necessary in order to initialize the EGA DYNAMIC
  635. ; SAVE AREA when creating it.
  636. EGA_DEFAULT_COLORS DB 00h ;; Black
  637. DB 01h ;; Blue
  638. DB 02h ;; Green
  639. DB 03h ;; Cyan
  640. DB 04h ;; Red
  641. DB 05h ;; Magenta
  642. DB 14h ;; Brown
  643. DB 07h ;; White
  644. DB 38h ;; Dark Grey
  645. DB 39h ;; Light Blue
  646. DB 3Ah ;; Light Green
  647. DB 3Bh ;; Light Cyan
  648. DB 3Ch ;; Light Red
  649. DB 3Dh ;; Light Magenta
  650. DB 3Eh ;; Yellow
  651. DB 3Fh ;; Bright white
  652. DB 00h ;; OVERSCAN register
  653. INST_EGA_SAVE_AREA PROC NEAR
  654. PUSH AX
  655. PUSH CX
  656. PUSH DX
  657. PUSH SI
  658. PUSH DI
  659. PUSH ES
  660. ;-------------------------------------------------------------------------------
  661. ; Get the BIOS save pointer table
  662. ;-------------------------------------------------------------------------------
  663. XOR AX,AX ; ES := segment 0
  664. MOV ES,AX
  665. LES SI,ES:DWORD PTR BIOS_SAVE_PTR ; ES:[SI] =Current BIOS save table
  666. .IF <<WORD PTR ES:[SI]+4> EQ 0> AND ; IF the dynamic save are pointer is
  667. .IF <<WORD PTR ES:[SI]+6> EQ 0> ; null then, it's not defined
  668. .THEN ; and we have to define it:
  669. ;---------------------------------------------------------------------------
  670. ; The Dynamic EGA save area is NOT DEFINED:
  671. ;---------------------------------------------------------------------------
  672. MOV BYTE PTR ES:[SI]+4,0FFH ; Try to write a byte in the table
  673. PUSH AX ; (PUSH AX, POP AX used to create a
  674. POP AX ; small delay)
  675. .IF <<WORD PTR ES:[SI]+4> NE 0FFH>;If we can't read our byte back then,
  676. .THEN ; the Save Ptrs table is in ROM
  677. ;------------------------------------------------------------------------
  678. ; The Save pointer table is in ROM;
  679. ; Copy the BIOS save pointer table from ROM to within our .COM file
  680. ;------------------------------------------------------------------------
  681. PUSH ES ; DS:SI := Offset of BIOS save ptrs table
  682. POP DS ;
  683. PUSH CS ; ES:DI := The next available location
  684. POP ES ; for installing resident code
  685. MOV DI,CS:END_OF_RESIDENT_CODE ; within our .COM file
  686. MOV CS:OUR_SAVE_TAB_OFF,DI ;
  687. MOV CX,SAVE_AREA_LEN ; CX := Length of the table to copy
  688. REP MOVSB ; Replicate the Save Table
  689. PUSH CS
  690. POP DS ; Reestablish our data segment
  691. ;------------------------------------------------------------------------
  692. ; Adjust END_OF_RESIDENT_CODE to the next offset available for copying
  693. ; resident code and data.
  694. ;------------------------------------------------------------------------
  695. ADD END_OF_RESIDENT_CODE,SAVE_AREA_LEN
  696. ;------------------------------------------------------------------------
  697. ; Set the pointer in OUR Save ptr table to our EGA dynamic save area
  698. ; which we create right after the Save pointer table.
  699. ;------------------------------------------------------------------------
  700. MOV DI,OUR_SAVE_TAB_OFF ; DS:[DI] := Our BIOS save ptr tab
  701. MOV AX,END_OF_RESIDENT_CODE; Store its offset
  702. MOV DS:[DI]+4,AX ;
  703. MOV WORD PTR DS:[DI]+6,DS ; Store its segment
  704. ;------------------------------------------------------------------------
  705. ; Initialize our DYNAMIC SAVE AREA with the 16 standard EGA colors
  706. ;------------------------------------------------------------------------
  707. LEA SI,EGA_DEFAULT_COLORS ; DS:[SI] := EGA 16 Default colors
  708. MOV DI,END_OF_RESIDENT_CODE ; ES:[DI] := DYNAMIC SAVE AREA
  709. MOV CX,17 ; CX := Number of colors
  710. REP MOVSB ; Initialize the Dynamic save area
  711. ;------------------------------------------------------------------------
  712. ; Set the BIOS Save Pointer to our table of Save pointers:
  713. ;------------------------------------------------------------------------
  714. CLI
  715. XOR AX,AX ; ES:BIOS_SAVE_PTR := Our save table:
  716. MOV ES,AX
  717. MOV AX,OUR_SAVE_TAB_OFF
  718. MOV ES:BIOS_SAVE_PTR,AX
  719. MOV ES:BIOS_SAVE_PTR+2,DS
  720. STI
  721. .ELSE ; ELSE save pointer table is in RAM
  722. ;------------------------------------------------------------------------
  723. ; ELSE, the BIOS save pointer table is in RAM:
  724. ;------------------------------------------------------------------------
  725. ;------------------------------------------------------------------------
  726. ; Set the pointer in THEIR Save ptr table to OUR EGA dynamic save area
  727. ;------------------------------------------------------------------------
  728. MOV WORD PTR ES:[SI]+6,DS ; ES:[SI] = The existing table in RAM
  729. MOV AX,END_OF_RESIDENT_CODE
  730. MOV ES:[SI]+4,AX
  731. .ENDIF ; ENDIF save pointer table is in ROM
  732. ;-----------------------------------------------------------------------------
  733. ; Adjust END_OF_RESIDENT_CODE to the next offset available for copying
  734. ; resident code and data.
  735. ;-----------------------------------------------------------------------------
  736. ADD END_OF_RESIDENT_CODE,EGA_DYNAMIC_LEN
  737. .ENDIF
  738. POP ES
  739. POP DI
  740. POP SI
  741. POP DX
  742. POP CX
  743. POP AX
  744. RET
  745. OUR_SAVE_TAB_OFF DW ?
  746. INST_EGA_SAVE_AREA ENDP
  747. PAGE
  748. ;===============================================================================
  749. ;
  750. ; CHAIN_INTERRUPTS : INSTALL INT 5 ,INT 10 AND INT 2FH VECTORS
  751. ;
  752. ;-------------------------------------------------------------------------------
  753. ;
  754. ; INPUT: DS = Data segment for our code
  755. ; END_OF_RESIDENT_CODE = Offset of the end of the resident code
  756. ;
  757. ; OUTPUT: OLD_INT_2FH (within INT_2FH_DRIVER)
  758. ; BIOS_INT_5H (within PRT_SCR module)
  759. ; OLD_INT_10H
  760. ; END_OF_RESIDENT_CODE is updated to point to the end of the code
  761. ; that will stay resident.
  762. ; SAVE_AREA_PTR in BIOS segment is updated if an EGA adapter is found
  763. ;
  764. ;-------------------------------------------------------------------------------
  765. ;;
  766. ;; Data Structures Referenced:
  767. ;; Shared Data Area
  768. ;;
  769. ;; Description:
  770. ;; Install Interrupts 5 ,10 and 2FH. The old vectors are saved.
  771. ;;
  772. ;; Called By:
  773. ;; GRAPHICS_INSTALL
  774. ;;
  775. ;; External Calls:
  776. ;; DOS INT 21H Replace vector AH=25h
  777. ;; DOS INT 21H Get vector AH=35h
  778. ;;
  779. ;; Logic:
  780. ;; Save interrupt 5 vector in BIOS_INT_5H
  781. ;; Point interrupt 5 to PRT_SCR module
  782. ;; Save interrupt 2FH vector in BIOS_INT_2FH
  783. ;; Point interrupt 2FH to INT_2FH_DRIVER module
  784. ;; Save interrupt 10h vector in OLD_INT_10h
  785. ;; point interrupt 10h to INT_10H_DRIVER
  786. ;; RETURN
  787. ;;
  788. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  789. ;;
  790. CHAIN_INTERRUPTS PROC NEAR ;;
  791. PUSH ES
  792. PUSH BX
  793. ;-------------------------------------------------------------------------------
  794. ; Replace INTERRUPT 5 vector
  795. ;-------------------------------------------------------------------------------
  796. MOV AX,3505H ; Get vector for int 5 request
  797. INT 21H ; Call DOS
  798. MOV CS:BIOS_INT_5H,BX ; Save the old vector
  799. MOV CS:BIOS_INT_5H+2,ES
  800. MOV DX,OFFSET PRT_SCR ; DS:DX := Offset of our Print Screen
  801. MOV AX,2505H ; Replace vector for int 5 request
  802. INT 21H ; Call DOS
  803. ;-------------------------------------------------------------------------------
  804. ; Replace INTERRUPT 2FH vector
  805. ;-------------------------------------------------------------------------------
  806. MOV AX,352FH ; Get vector for int 2FH request
  807. INT 21H ; Call DOS
  808. MOV WORD PTR OLD_INT_2FH,BX ; Save the old vector
  809. MOV WORD PTR OLD_INT_2FH+2,ES
  810. MOV DX,OFFSET INT_2FH_DRIVER; DS:DX := Offset of our 2FH handler
  811. MOV AX,252FH ; Replace vector for int 2FH request
  812. INT 21H ; Call DOS
  813. ; /* M001 BEGIN */
  814. ;------------------------------------------------------------------------------
  815. ; Replace INTERRUPT 10 vector
  816. ;------------------------------------------------------------------------------
  817. MOV AX,3510H ; Get vector for int10h request
  818. INT 21H ; Call DOS
  819. MOV WORD PTR OLD_INT_10H,BX ; Save the old vector
  820. MOV WORD PTR OLD_INT_10H+2,ES
  821. MOV DX,OFFSET INT_10H_DRIVER; DS:DX := Offset of our 2FH handler
  822. MOV AX,2510H ; Replace vector for int10H request
  823. INT 21H ; Call DOS
  824. ; /* M001 END */
  825. POP BX
  826. POP ES
  827. RET
  828. CHAIN_INTERRUPTS ENDP
  829. ;===============================================================================
  830. ;
  831. ; COPY_PRINT_MODULES: COPY THE SET OF PRINT MODULES NEEDED OVER THE PREVIOUS ONE
  832. ;
  833. ;-------------------------------------------------------------------------------
  834. ;
  835. ; INPUT: BP = Offset of the temporary Shared Data area
  836. ; END_OF_RESIDENT_CODE = Location of the set of COLOR modules
  837. ; (if first time installed)
  838. ; CS:[BP].PRINTER_TYPE = Printer type NEEDED
  839. ; RESIDENT_CODE_SEG = Segment containing the resident code
  840. ;
  841. ; OUTPUT: END_OF_RESIDENT_CODE = End of the print modules IS UPDATED
  842. ; (If first time installed)
  843. ;
  844. ;-------------------------------------------------------------------------------
  845. ;;
  846. ;; Data Structures Referenced:
  847. ;; Control Variables
  848. ;; Shared Data Area
  849. ;;
  850. ;; Description:
  851. ;; This module trashes one set of print modules (Color or Black & White)
  852. ;; depending on the type of printer attached. Since the Shared Data
  853. ;; (resident version) will reside immediately after the print modules,
  854. ;; END_OF_RESIDENT_CODE will be set by this modules.
  855. ;;
  856. ;; The set of COLOR modules is already at the rigth located when installing
  857. ;; GRAPHICS for the first time. This is true since, the color modules are
  858. ;; linked before the black and white modules.
  859. ;;
  860. ;; Therefore, if we are installing GRAPHICS for the first time and we need
  861. ;; the color modules then, we do not need to relocate any print modules.
  862. ;;
  863. ;; When installing GRAPHICS again we first check what is the resident set,
  864. ;; we recopy a new set only if needed.
  865. ;;
  866. ;; Called By:
  867. ;; GRAPHICS_INSTALL
  868. ;;
  869. ;; Logic:
  870. ;; IF color printer THEN
  871. ;; SI := Offset of BW_PRINT_MODULES
  872. ;; ELSE
  873. ;; SI := Offset of COLOR_PRINT_MODULES
  874. ;; ENDIF
  875. ;; REP MOVSB ; Copy the set of modules
  876. ;; END_OF_RESIDENT_CODE := end of the set of modules
  877. ;; RETURN
  878. ;;
  879. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  880. COPY_PRINT_MODULES PROC NEAR
  881. PUSH AX
  882. PUSH BX
  883. PUSH CX
  884. PUSH SI
  885. PUSH DI
  886. PUSH ES
  887. ;-------------------------------------------------------------------------------
  888. ; Determine if we need to relocate the set of print modules, if so, set the
  889. ; source address (DS:SI), the destination address (ES:DI) and the number of
  890. ; bytes to copy (CX).
  891. ;-------------------------------------------------------------------------------
  892. PUSH CS:RESIDENT_CODE_SEG ; ES := Segment containing the resident
  893. POP ES ; code (Where to copy modules)
  894. MOV DI,OFFSET PRINT_MODULE_START ; ES:[DI] := Resident print modules
  895. .IF <INSTALLED EQ NO> ; IF not installed
  896. .THEN ; THEN,
  897. ; We relocate the print modules
  898. ; at the end of the resident code:
  899. ; (this is where the color set is)
  900. .IF <CS:[BP].PRINTER_TYPE EQ BLACK_WHITE> ; IF we don't want the color set
  901. .THEN ; THEN,
  902. MOV NEED_NEW_PRINT_MODULES,YES ; Say we need new modules
  903. MOV SI,OFFSET PRINT_BW_APA ; DS:[SI] := Black and white modules
  904. MOV CX,LEN_OF_BW_MODULES ; CX := Length of B&W modules
  905. .ENDIF ;
  906. .ELSE ; ELSE, (We are already installed)
  907. MOV BX,SHARED_DATA_AREA_PTR ; BX := Offset of Shared Data area
  908. MOV AL,ES:[BX].PRINTER_TYPE ; AL := Type of the resident set
  909. .IF <AL NE CS:[BP].PRINTER_TYPE> ; IF resident set is not the one
  910. .THEN ; we need THEN,
  911. MOV NEED_NEW_PRINT_MODULES,YES ; Say we need a new set.
  912. .IF <CS:[BP].PRINTER_TYPE EQ COLOR>; IF its color we need then,
  913. MOV SI,OFFSET PRINT_COLOR ; DS:[SI] := Color set
  914. MOV CX,LEN_OF_COLOR_MODULES ; CX := Length of color mod.
  915. .ELSE ; ELSE
  916. MOV SI,OFFSET PRINT_BW_APA ; DS:[SI] := B&W set
  917. MOV CX,LEN_OF_BW_MODULES ; CX := Length of B&W mod.
  918. .ENDIF ; ENDIF we need the color set
  919. .ENDIF ; ENDIF we need a new set
  920. .ENDIF ; ENDIF we are not installed
  921. ;-------------------------------------------------------------------------------
  922. ; If needed: Copy the required set of print modules
  923. ;-------------------------------------------------------------------------------
  924. .IF <NEED_NEW_PRINT_MODULES EQ YES>
  925. .THEN
  926. CLD ; Clear the direction flag
  927. REP MOVSB ; Copy the set of print modules
  928. .ENDIF ; ENDIF needs to copy the print modules
  929. ;-------------------------------------------------------------------------------
  930. ; Set END_OF_RESIDENT_CODE pointer to the end of the print modules:
  931. ; (Reserve enough space to store the larger set of modules on a
  932. ; subsequent install)
  933. ;-------------------------------------------------------------------------------
  934. .IF <INSTALLED EQ NO> ; IF first time installed
  935. .THEN ; THEN,
  936. MOV CX,LEN_OF_COLOR_MODULES ; Adjust END_OF_RESIDENT_CODE to
  937. .IF <CX G LEN_OF_BW_MODULES> ; contains the larger set of modules.
  938. .THEN ;
  939. ADD END_OF_RESIDENT_CODE,LEN_OF_COLOR_MODULES
  940. .ELSE
  941. ADD END_OF_RESIDENT_CODE,LEN_OF_BW_MODULES
  942. .ENDIF ;
  943. .ENDIF
  944. POP ES
  945. POP DI
  946. POP SI
  947. POP CX
  948. POP BX
  949. POP AX
  950. RET
  951. NEED_NEW_PRINT_MODULES DB NO ; True if print modules needed must be
  952. ; copied over the other set of print
  953. ; modules
  954. COPY_PRINT_MODULES ENDP
  955. ;AN002;
  956. PAGE ;AN002;
  957. ;===============================================================================;AN002;
  958. ; ;AN002;
  959. ; PROCEDURE_NAME: RELEASE_ENVIRONMENT ;AN002;
  960. ; ;AN002;
  961. ; INPUT: None. ;AN002;
  962. ; ;AN002;
  963. ; OUTPUT: Environment vector released. ;AN002;
  964. ; ;AN002;
  965. ;-------------------------------------------------------------------------------;AN002;
  966. RELEASE_ENVIRONMENT PROC NEAR ;AN002;
  967. PUSH AX ; save regs ;AN002;
  968. PUSH BX ;AN002;
  969. PUSH ES ;AN002;
  970. MOV AH,62H ; function for get the PSP segment ;AN002;
  971. INT 21H ; invoke INT 21h ;AN002;
  972. MOV ES,BX ; BX contains PSP segment - put in ES ;AN002;
  973. MOV BX,WORD PTR ES:[2CH] ; get segment of environmental vector ;AN002;
  974. MOV ES,BX ; place segment in ES for Free Memory ;AN002;
  975. MOV AH,49H ; Free Allocated Memory function call ;AN002;
  976. INT 21H ; invoke INT 21h ;AN002;
  977. POP ES ; restore regs ;AN002;
  978. POP BX ;AN002;
  979. POP AX ;AN002;
  980. RET ;AN002;
  981. RELEASE_ENVIRONMENT ENDP ;AN002;
  982. PAGE
  983. ;===============================================================================
  984. ;
  985. ; PROCEDURE_NAME: DISP_ERROR
  986. ;
  987. ; INPUT: AX := GRAPHICS message number (documented in GRMSG.EQU)
  988. ; CX := Number of substitutions (Needed by SYSDISPMSG)
  989. ; DS:[SI] := Substitution list (needed only if CX <> 0)
  990. ;
  991. ; OUTPUT: Error message is displayed on STANDARD ERROR OUTPUT (STDERR)
  992. ;
  993. ;-------------------------------------------------------------------------------
  994. DISP_ERROR PROC NEAR
  995. PUSH BX
  996. PUSH DI
  997. PUSH SI
  998. PUSH BP
  999. MOV BX,ERROR_DEVICE ; Issue message to standard error
  1000. XOR DL,DL ; No input
  1001. MOV DH,UTILITY_MSG_CLASS;It's one of our messages
  1002. CALL SYSDISPMSG ; display error message
  1003. POP BP
  1004. POP SI
  1005. POP DI
  1006. POP BX
  1007. RET
  1008. DISP_ERROR ENDP
  1009. include msgdcl.inc
  1010. CODE ENDS
  1011. END
  1012.