;/* ; * Microsoft Confidential ; * Copyright (C) Microsoft Corporation 1988 - 1991 ; * All Rights Reserved. ; */ ;************************************************************ ;** ;** ;** NAME: Support for HP PCL printers added to GRAPHICS. ;** ;** DESCRIPTION: I fixed a MS bug. MS did not initialize the variable ;** ROTATE_SW. Consequently, if you do a non-rotate after doing ;** a rotate, the picture would be printed incorrectly as a ;** rotated picture. Note this bug was in Q.01.01 and fixed for ;** Q.01.02. ;** ;** NOTES: The following bug was fixed for the pre-release version ;** Q.01.02. ;** ;** BUG (mda004) ;** ------------ ;** ;** NAME: After GRAPHICS prints a rotated picture it will print pictures ;** which are not supposed to be rotated as rotated junk. ;** ;** FILES AFFECTED: GRCTRL.ASM ;** ;** CAUSE: MicroSoft was failing to initialize the variable ROTATE_SW to ;** OFF. Consequently, if you printed a picture whose corresponding ;** printbox did NOT specify a rotate after printing a picture whose ;** corresponding printbox did specify a rotate, the picture would ;** print as rotated junk. ;** ;** FIX: Initialize the variable ROTATE_SW to OFF right before going into ;** the print procedure Print_Color or Print_BW_APA. ;** ;** DOCUMENTATION NOTES: This version of GRCTRL.ASM differs from the previous ;** version only in terms of documentation. ;** ;** ;************************************************************ PAGE ,132 TITLE DOS GRAPHICS Command - Print screen Control module ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; DOS - GRAPHICS Command ;; ;; ;; File Name: GRCTRL.ASM ;; ---------- ;; ;; Description: ;; ------------ ;; This file contains the code for the Print Screen control module. ;; ;; Documentation Reference: ;; ------------------------ ;; OASIS High Level Design ;; OASIS GRAPHICS I1 Overview ;; ;; Procedures Contained in This File: ;; ---------------------------------- ;; PRT_SCR ;; DET_HW_CONFIG ;; DET_MODE_STATE ;; GET_MODE_ATTR ;; SET_UP_XLT_TAB ;; SET_CGA_XLT_TAB ;; CGA_COL2RGB ;; RGB2XLT_TAB ;; SET_EGA_XLT_TAB ;; EGA_COL2RGB ;; SET_MODE_F_XLT_TAB ;; SET_MODE_13H_XLT_TAB ;; SET_ROUNDUP_XLT_TAB ;; SET_BACKG_IN_XLT_TAB ;; RGB2BAND ;; RGB2INT ;; ;; ;; Include Files Required: ;; ----------------------- ;; GRINST.EXT - Externals for GRINST.ASM ;; ;; ;; External Procedure References: ;; ------------------------------ ;; FROM FILE GRINST.ASM: ;; GRAPHICS_INSTALL - Main module for installation. ;; ;; Linkage Instructions: ;; -------------------- ;; Refer to GRAPHICS.ASM ;; ;; Change History: ;; --------------- ;; M001 NSM 1/30/91 New var to store the old int 10 handler ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CODE SEGMENT PUBLIC 'CODE' ASSUME CS:CODE,DS:CODE .XLIST INCLUDE GRINT2FH.EXT INCLUDE GRBWPRT.EXT INCLUDE GRCOLPRT.EXT INCLUDE GRSHAR.STR INCLUDE GRPATTRN.STR INCLUDE GRPATTRN.EXT INCLUDE STRUC.INC .LIST PRT_SCR PROC NEAR JMP PRT_SCR_BEGIN PAGE ;=============================================================================== ; ; GRAPHICS INTERRUPT DRIVER'S DATA: ; ;=============================================================================== .xlist PUBLIC PRT_SCR,ERROR_CODE,XLT_TAB,MODE_TYPE PUBLIC CUR_MODE_PTR,CUR_MODE,NB_COLORS,SCREEN_HEIGHT,SCREEN_WIDTH PUBLIC CUR_PAGE,CUR_COLUMN,CUR_ROW,NB_SCAN_LINES,SCAN_LINE_MAX_LENGTH PUBLIC CUR_SCAN_LNE_LENGTH PUBLIC PRT_BUF,NB_BOXES_PER_PRT_BUF,CUR_BOX,BOX_H,BOX_W PUBLIC PRINT_SCREEN_ALLOWED,RGB PUBLIC BIOS_INT_5H PUBLIC OLD_INT_10H ; /* M001 */ PUBLIC ROTATE_SW PUBLIC DET_HW_CONFIG PUBLIC NB_CHAR_COLUMNS PUBLIC RGB2INT PUBLIC RGB2BAND .list INCLUDE GRCTRL.STR ;------------------------------------------------------------------------------- ; ; ENTRY POINT TO BIOS HARDWARE INTERRUPT 5 HANDLER ; ;------------------------------------------------------------------------------- BIOS_INT_5H DW ? ; Pointer to BIOS int 5h DW ? ;/* M001 BEGIN */ -------------------------------------------------------------- ; ; ENTRY POINT TO BIOS HARDWARE INTERRUPT 10 HANDLER ; ;------------------------------------------------------------------------------- OLD_INT_10H DW ? ; Pointer to BIOS int 10h DW ? ; /* M001 END */ ;------------------------------------------------------------------------------- ; ; PRINT SCREEN ERROR CODE (Used at print screen time, see GRCTRL.STR for ; error codes allowed) ; ;------------------------------------------------------------------------------- ERROR_CODE DB 0 ; ERROR CODE 0 = NO ERROR ;------------------------------------------------------------------------------- ; ; SCREEN PIXEL: INTERNAL REPRESENTATION ; ;------------------------------------------------------------------------------- RGB PIXEL_STR < , , > ; PIXEL := RED, GREEN, BLUE Values ;------------------------------------------------------------------------------- ; ; COLOR TRANSLATION TABLE: ; ; This table is used to translate the color numbers returned by ; Interrupt 10H Read Dot and Read Character calls into print ; information. The table consists of 256 entries, one byte each, ; indexed by color number. ; In the case of black and white printing, the table ; entries are grey scale intensities from 0 to 63. In the case ; of color printing each table entry contains a "band mask" indicating ; which color print bands are required to generate the required color. ; The band masks are simply bit masks where each bit corresponds to one ; of the printer bands. ; ; The table is set up at the beginning of the print screen processing, ; before any data is read from the screen. From then on, translating ; from screen information into print information is done quickly by ; accessing this table. Not all 256 entries are initialized for each ; screen print. The number of entries used is equal to the number ; of colors available concurrently with the given display mode. ;------------------------------------------------------------------------------- XLT_TAB DB 256 DUP(32) ; COLOR TRANSLATION TABLE ; This table is used to translate the Color Dot ; or Byte Attribute to a Band Mask for color ; printing or to a Grey Intensity for Mono- ; chrome printing. ;------------------------------------------------------------------------------- ; ; CURRENT VIDEO MODE ATTRIBUTES ; ;------------------------------------------------------------------------------- MODE_TYPE DB ? ; Mode types (bit mask) APA or TXT CUR_MODE_PTR DW ? ; DISPLAYMODE INFO RECORD for the current ; mode (defined in the shared data area). CUR_MODE DB ? ; Current video mode number NB_COLORS DW ? ; Number of colors supported by this mode SCREEN_HEIGHT DW ? ; Number of rows on the screen (chars or pixels) SCREEN_WIDTH DW ? ; Number of columns on the screen (chars/pixels) ; (for text modes is equal to NB_CHAR_COLUMNS) NB_CHAR_COLUMNS DB ? ; Number of columns on the screen if in txt mode CUR_PAGE DB ? ; Active page number ROTATE_SW DB ? ; Switch: if "ON" then, must print sideways ;------------------------------------------------------------------------------- ; ; ACTIVE SCREEN ATTRIBUTES ; ;------------------------------------------------------------------------------- CUR_COLUMN DW ? ; Current pixel/char column number CUR_ROW DW ? ; Current pixel/char row number NB_SCAN_LINES DW ? ; Number of screen scan lines SCAN_LINE_MAX_LENGTH DW ? ; Maximum number of dots/chars per scan line CUR_SCAN_LNE_LENGTH DW ? ; Length in pels/chars of the current scan line ;------------------------------------------------------------------------------- ; ; PRINTER VARIABLES ; ;------------------------------------------------------------------------------- PRT_BUF DB ?,?,?,? ; PRINT BUFFER NB_BOXES_PER_PRT_BUF DB ? ; Number of boxes fitting in the print buffer CUR_BOX DB ?,?,?,? ; BOX = PRINTER REPRESENTATION OF 1 PIXEL BOX_H DB ? ; HEIGHT OF THE BOX BOX_W DB ? ; WIDTH OF THE BOX ;------------------------------------------------------------------------------- ; ; CONTROL VARIABLES: ; ; This data is used to communicate between the Installation Modules ; and the Resident Print Screen Modules. ;------------------------------------------------------------------------------- PRINT_SCREEN_ALLOWED DB YES; Used to avoid print screens ; while the GRAPHICS installation ; (or re-install) is in progress ; Set by GRAPHICS_INSTALL module. PAGE ;=============================================================================== ; ; INTERRUPT 5 DRIVER'S CODE: ; ;------------------------------------------------------------------------------- ;=============================================================================== ; ; PRT_SCR : PRINT THE ACTIVE SCREEN ; ;------------------------------------------------------------------------------- ; ; INPUT: SHARED_DATA_AREA_PTR = Offset of the data area used for ; passing data between the ; Installation process and the Print ; Screen process. ; PRINT_SCREEN_ALLOWED = Switch. Set to "No" if currently ; installing GRAPHICS.COM ; ; NOTE: These 2 variables are declared within ; PRT_SCR but initialized by the ; Installation process GRAPHICS_INIT ; OUTPUT: PRINTER ; ; CALLED BY: INTERRUPT 5 ; ; ;------------------------------------------------------------------------------- ; ; DESCRIPTION: ; ; PRINT THE ACTIVE SCREEN for all TEXT and All Points Addressable (APA) ; display modes available with either a MONO, CGA, EGA, or VGA video ; adapter on a Black and White or Color printer. ; ; INITIALIZATION: ; ; Each pixel or character on the screen has a color attribute. These ; colors must be translated into different internal representations: ; ; For printing in colors, each color is translated to a BAND MASK. ; The Band Mask indicates how to obtain this color on the printer. ; ; For printing in Black and White, each color is translated to a ; GREY INTENSITY number between 0 (black) and 63 (white). ; ; The BAND MASK or the GREY INTENSITIES are found in the COLOR ; TRANSLATION TABLE. This table is initialized before calling any of ; the print screen modules. ; ; PRINT SCREEN TIME: ; ; When a pixel or character is read off the screen by one of the print ; screen modules, its color is used as an index into the translation ; table. ; ; ; LOGIC: ; ; IF SCREEN_PRINTS_ALLOWED=NO ; Block print screens until Installation ; THEN IRET ; Process (or re-install!) is finished. ; ELSE ; ; CALL DET_HW_CONFIG ; Determine hardware configuration ; CALL DET_MODE_STATE ; Determine video mode and active page ; CALL GET_MODE_ATTR ; Get video attributes (TXT or APA, etc) ; ; IF MODE_TYPE = TXT AND Number of colors = 0 ; THEN Invoke BIOS INTERRUPT 5 ; ELSE ; IF PRINTER_TYPE = BLACK_WHITE ; THEN ; IF MODE_TYPE = TXT ; THEN Invoke BIOS INTERRUPT 5 ; ELSE ; Mode is APA ; CALL SET_UP_XLT_TAB ; Set up the color translation table ; CALL PRINT_BW_APA ; Print the active screen on a B&W printer ; ELSE ; Color printer attached ; CALL SET_UP_XLT_TAB ; Set up the color translation table ; CALL PRINT_COLOR ; Print the active screen on a Color prt. ; IRET ; PRT_SCR_BEGIN: PUSH AX ; Save Registers PUSH BX ; PUSH CX ; PUSH DX ; PUSH SI ; PUSH DI ; PUSH BP ; PUSH DS ; PUSH ES ; ; CLD ; Clear direction flag PUSH CS ; DS := CS POP DS ;------------------------------------------------------------------------------- ; Verify if we are allowed to print (not allowed if currently installing ; GRAPHICS or printing a screen): ;------------------------------------------------------------------------------- CMP PRINT_SCREEN_ALLOWED,NO ; IF not allowed to print JE PRT_SCR_RETURN ; THEN quit ; ELSE print the screen: ;------------------------------------------------------------------------------- ; INITIALIZATION: ;------------------------------------------------------------------------------- PRT_SCR_INIT: ; Disable print screen while MOV PRINT_SCREEN_ALLOWED,NO ; we are printing the current ; screen. MOV BP,SHARED_DATA_AREA_PTR ; BP := Offset Shared Data Area MOV ERROR_CODE,NO_ERROR ; No error so far. CALL DET_HW_CONFIG ; Determine the type of display adapter CALL DET_MODE_STATE ; Init CUR_PAGE, CUR_MODE CALL GET_MODE_ATTR ; Determine if APA or TXT, nb. of colors, ; and screen dimensions in pels or characters. ; ; Test the error code returned by GET_MODE_ATTR: ; TEST ERROR_CODE,MODE_NOT_SUPPORTED ;If mode not supported then, JNZ DO_BEEP ; let BIOS give it a try. ;------------------------------------------------------------------------------ ; Check the printer type: ;------------------------------------------------------------------------------ .IF ; Is a black and white printer .THEN ; attached ? ;------------------------------------------------------------------------------ ; A Black and White printer is attached ;------------------------------------------------------------------------------ CMP MODE_TYPE,TXT ; Is the screen in text mode ? JNE INVOKE_PRINT_ROUTINE ; No, call GRAPHICS B&W routine JMP SHORT EXIT_TO_BIOS ; Yes, give control to BIOS INTERRUPT 5 .ELSE ;------------------------------------------------------------------------------ ; A Color printer is attached ;------------------------------------------------------------------------------ CMP NB_COLORS,0 ; Is the screen in a Monochrome JNE INVOKE_PRINT_ROUTINE TEST MODE_TYPE,TXT ; text mode ? JNZ INVOKE_PRINT_ROUTINE JMP SHORT EXIT_TO_BIOS ; Yes, let BIOS INTERRUPT 5 handle it ; No, we handle it. .ENDIF ; ENDIF black and white or color printer ;------------------------------------------------------------------------------- ; ; Call the print routine (which is either PRINT_COLOR or PRINT_BW_APA) ; ;------------------------------------------------------------------------------- INVOKE_PRINT_ROUTINE: CALL SET_UP_XLT_TAB ; Set up the color translation table ; \/ ~~mda(004) ---------------------------------------------------------------- ; The following fixes a MS bug. MS was failing to initialize ; the variable ROTATE_SW to off. Consequently, if you printed a ; picture whose corresponding printbox did NOT specify a rotate ; after printing a picture whose corresponding printbox did ; specify a rotate, the picture would print rotated. MOV ROTATE_SW,OFF ; Set printing to standard unless otherwise ; set to rotate via PRINT_OPTIONS. ; /\ ~~mda(004) ---------------------------------------------------------------- CALL PRINT_MODULE_START ; Call the print modules that were ; made resident at Install time. MOV PRINT_SCREEN_ALLOWED,YES; Enable PrtScr for next calls ;----------------------------------------------------------------------------- ; Test the error code returned by either PRINT_COLOR or PRT_BW_APA ;----------------------------------------------------------------------------- TEST ERROR_CODE,UNABLE_TO_PRINT ; If unable to print the screen JNZ SHORT EXIT_TO_BIOS ; then, let BIOS give it a try PRT_SCR_RETURN: ; Restore registers POP ES ; POP DS ; POP BP ; POP DI ; POP SI ; POP DX ; POP CX ; POP BX ; POP AX ; ; IRET ; Return control to interrupted ; process ; give a beep for modes not supported by graphics DO_BEEP: mov ah,2 ; console output mov dx,7 ; ^G - beep for modes not supported int 21h EXIT_TO_BIOS: ; Restore registers POP ES ; POP DS ; POP BP ; POP DI ; POP SI ; POP DX ; POP CX ; POP BX ; POP AX ; CLI ; Disable interrupts MOV CS:PRINT_SCREEN_ALLOWED,YES ; Enable PrtScr for next calls JMP DWORD PTR CS:BIOS_INT_5H ; Exit to BIOS INTERRUPT 5 PRT_SCR ENDP ;=============================================================================== ; ; PRT_SCR MODULES: ; ;------------------------------------------------------------------------------- PAGE ;=============================================================================== ; ; DET_HW_CONFIG : DETERMINE WHAT TYPE OF VIDEO HARDWARE IS PRESENT ; ;------------------------------------------------------------------------------- ; ; INPUT: BP = Offset of the shared data area ; ; OUTPUT: HARDWARE_CONFIG is updated in the shared data area ; ; CALLED BY: PRT_SCR ; ; EXTERNAL CALLS: BIOS INT 10H ; ;------------------------------------------------------------------------------- ; ; LOGIC: ; Issue BIOS INT10H Get Display Configuration Code (AX=1A00H) ; IF AL = 1AH THEN /* VGA (PS/2 OR BRECON-B) */ ; /* BL = active DCC */ ; /* BH = alternate DCC */ ; /* Display Code: */ ; /* 1 - Mono Adapter */ ; /* 2 - CGA */ ; /* 4 - EGA with Mono Display */ ; /* 5 - EGA with Color Display */ ; /* 7 - PS/2 Mod 50,60,80 OR BRECON-B with Mono Display */ ; /* 8 - PS/2 Mod 50,60,80 OR BRECON-B with Color Display */ ; /* B - PS/2 Mod 30 with Mono Display */ ; /* C - PS/2 Mod 30 with Color Display */ ; IF AL = 1AH THEN /* Call is supported */ ; Set HARDWARE_CONFIG byte based on DCC returned in DL ; ELSE ; Issue INT 10H EGA Info (AH=12H BL=10H) ; IF BL <> 10H THEN /* EGA */ ; Set EGA bit in HARDWARE_CONFIG ; ELSE /* CGA or */ ; Issue INT 10H PC CONVERTIBLE Physical display description param. ; request. (AH=15H) ; IF ES:[DI] = 5140H ; THEN ; Set PC_CONVERTIBLE bit in HARDWARE_CONFIG ; ELSE ; Set OLD_ADAPTER bit in HARDWARE_CONFIG ; ENDIF ; ENDIF ; ENDIF ; RETURN ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DET_HW_CONFIG PROC NEAR ;------------------------------------------------------------------------------- ; ; Try to read display combination code (PS/2 call): ; ;------------------------------------------------------------------------------- MOV AX,READ_CONFIG_CALL INT 10H ; Call video BIOS .IF ; If call is supported .THEN ;------------------------------------------------------------------------------- ; ; Call is supported, PS/2 BIOS is present (Model 39,50,60,80 or BRECON-B card), ; Determine what is the primary video adapter: ; ;------------------------------------------------------------------------------- .SELECT .WHEN OR ; MONO or .WHEN ; CGA MOV DS:[BP].HARDWARE_CONFIG,OLD_ADAPTER .WHEN OR ; EGA with Mono or .WHEN ; EGA with Color MOV DS:[BP].HARDWARE_CONFIG,EGA .WHEN OR ; BRECON-B with Mono or .WHEN ; BRECON-B with Color MOV DS:[BP].HARDWARE_CONFIG,ROUNDUP .WHEN OR ; PS/2 Model 30 with Mono or .WHEN ; PS/2 Model 30 with Color MOV DS:[BP].HARDWARE_CONFIG,PALACE .ENDSELECT ;------------------------------------------------------------------------------- ; ; PS/2 call is not supported, try the EGA info call: ; ;------------------------------------------------------------------------------- .ELSE MOV AH,ALT_SELECT_CALL ; Request Alternate select's MOV BL,EGA_INFO_CALL ; "return EGA information call" INT 10H ; Call video BIOS .IF ; If a memory value is returned .THEN ; then, there is an EGA MOV DS:[BP].HARDWARE_CONFIG,EGA .ELSE ; else, call is not supported: ;------------------------------------------------------------------------------- ; ; EGA call is not supported, try the PC CONVERTIBLE display description call: ; ;------------------------------------------------------------------------------- MOV AH,DISP_DESC_CALL INT 10H ; Call BIOS, ES:DI :=Offset of parms .IF ; If LCD display type, .THEN ; set LCD bit in Shared Data area MOV DS:[BP].HARDWARE_CONFIG,PC_CONVERTIBLE .ELSE ; else, we have an old adapter. MOV DS:[BP].HARDWARE_CONFIG,OLD_ADAPTER ; (either MONO or CGA) .ENDIF ; Display type is LCD .ENDIF ; EGA BIOS is present .ENDIF ; PS/2 BIOS is present RET DET_HW_CONFIG ENDP PAGE ;======================================================================= ; ; DET_MODE_STATE : Determine the current video mode and the active page. ; ;----------------------------------------------------------------------- ; ; INPUT: HARDWARE_CONFIG = Type of video hardware attached ; ; OUTPUT: CUR_MODE = Video mode number (0-13H) ; CUR_PAGE = Video page number (0-8) ; NB_CHAR_COLUMNS = Number of columns if in a text mode. ; ; ; CALLED BY: PRT_SCR ; ; ;------------------------------------------------------------------------------- ; ; DESCRIPTION: Use the BIOS interface to ; obtain the current mode and active page. ; ; LOGIC: ; ; Call BIOS INTERRUPT 10H: "Return current video state" (AH = 0fh) ; DET_MODE_STATE PROC NEAR PUSH AX PUSH BX MOV AH,GET_STATE_CALL INT 10H ; CALL BIOS MOV CUR_MODE,AL MOV NB_CHAR_COLUMNS,AH MOV CUR_PAGE,BH POP BX POP AX RET DET_MODE_STATE ENDP PAGE ;======================================================================= ; ; GET_MODE_ATTR: Obtain attributes of current video mode. ; ;----------------------------------------------------------------------- ; ; INPUT: CUR_MODE = Current video mode (1 BYTE) ; ; OUTPUT: MODE_TYPE = Video mode type (TXT or APA) ; NB_COLORS = Maximum number of colors (0-256) (0=B&W) ; ERROR_CODE = Error code if error occurred. ; SCREEN_HEIGHT= Number of rows (in pixels if APA or char if TEXT) ; SCREEN_WIDTH = Number of columns (in pixels/char) ; ; CALLED BY: PRT_SCR ; ; ;----------------------------------------------------------------------- ; ; DESCRIPTION: Scan the 2 local video mode attribute tables until the ; current mode is located. Return the attributes. ; For APA modes SCREEN_HEIGHT and SCREEN_WIDTH are in pixels, ; for TEXT modes they are in characters. ; ; ; LOGIC: ; ; Scan the APA_ATTR_TABLE ; IF FOUND ; MODE_TYPE := APA ; NB_COLORS := mode.MAX_COLORS ; SCREEN_HEIGHT := mode.NB_L ; SCREEN_WIDTH := mode.NB_C ; ELSE ; Scan the TXT_ATTR_TABLE ; When FOUND ; MODE_TYPE := TXT ; NB_COLORS := mode.NUM_COLORS ; SCREEN_WIDTH := NB_CHAR_COLUMNS ; SCREEN_HEIGHT := Byte in ROM BIOS at 40:84 ; ;----------------------------------------------------------------------- GET_MODE_ATTR PROC NEAR JMP SHORT GET_MODE_ATTR_BEGIN ;----------------------------------------------------------------------- ; ; LOCAL DATA ; ;----------------------------------------------------------------------- APA_ATTR STRUC ; ATTRIBUTES FOR APA MODES: APA_MODE DB ? ; Mode number NB_C DW ? ; Number of columns NB_L DW ? ; Number of lines MAX_COLORS DW ? ; Maximum number of colors available (0=B&W) APA_ATTR ENDS TXT_ATTR STRUC ; ATTRIBUTES FOR TXT MODES: TXT_MODE DB ? ; Mode number NUM_COLORS DB ? ; Number of colors TXT_ATTR ENDS ;----------------------------------------------------------------------- ; ; APA MODE ATTRIBUTES: ; ;----------------------------------------------------------------------- NB_APA_MODES DW 10 APA_ATTR_TABLE LABEL WORD MODE04 APA_ATTR < 4,320,200, 4> MODE05 APA_ATTR < 5,320,200, 4> MODE06 APA_ATTR < 6,640,200, 2> MODE0D APA_ATTR <0DH,320,200, 16> MODE0E APA_ATTR <0EH,640,200, 16> MODE0F APA_ATTR <0FH,640,350, 4> MODE10H APA_ATTR <10H,640,350, 16> MODE11H APA_ATTR <11H,640,480, 2> MODE12H APA_ATTR <12H,640,480, 16> MODE13H APA_ATTR <13H,320,200,256> ;----------------------------------------------------------------------- ; ; TXT MODE ATTRIBUTES: ; ;----------------------------------------------------------------------- NB_TXT_MODES DW 5 TXT_ATTR_TABLE LABEL WORD MODE00 TXT_ATTR < 0, 16> MODE01 TXT_ATTR < 1, 16> MODE02 TXT_ATTR < 2, 16> MODE03 TXT_ATTR < 3, 16> MODE07 TXT_ATTR < 7, 0> ;----------------------------------------------------------------------- ; ; BEGIN OF GET_MODE_ATTR ; ;----------------------------------------------------------------------- GET_MODE_ATTR_BEGIN: PUSH AX PUSH BX PUSH CX PUSH DX MOV DL,CUR_MODE ; DL = CURRENT MODE ; ; Scan the APA_ATTR_TABLE ; MOV CX,NB_APA_MODES ; CS <-- Number of APA modes MOV BX,OFFSET APA_ATTR_TABLE; BX <-- Offset of APA mode table SCAN_APA: CMP DL,[BX].APA_MODE ; IF mode found JE SHORT ITS_APA ; THEN get its attributes ADD BX,SIZE APA_ATTR LOOP SCAN_APA ; ELSE keep scanning JMP SHORT SCAN_TXT_INIT ; NOT in this table: scan txt modes ITS_APA: MOV MODE_TYPE,APA ; MODE = APA MOV AX,[BX].MAX_COLORS MOV NB_COLORS,AX ; Get number of colors MOV AX,[BX].NB_L MOV SCREEN_HEIGHT,AX ; Get number of lines MOV AX,[BX].NB_C MOV SCREEN_WIDTH,AX ; Get number of columns JMP SHORT GET_MODE_ATTR_END ; ; Scan the TXT_ATTR_TABLE ; SCAN_TXT_INIT: MOV CX,NB_TXT_MODES ; CX <-- Number of TXT modes MOV BX,OFFSET TXT_ATTR_TABLE; BX <-- Offset of TXT mode table SCAN_TXT: CMP DL,[BX].TXT_MODE ; IF mode found JE SHORT ITS_TXT ; THEN get its attributes ADD BX,SIZE TXT_ATTR LOOP SCAN_TXT ; ELSE keep scanning ITS_TXT: MOV MODE_TYPE,TXT ; MODE = TXT MOV AL,[BX].NUM_COLORS CBW MOV NB_COLORS,AX ; Get number of colors MOV AL,NB_CHAR_COLUMNS ; Get number of columns CBW MOV SCREEN_WIDTH,AX .IF ; If an old adapter is there .THEN ; The number of lines is 25 MOV SCREEN_HEIGHT,25 .ELSE MOV AX,BIOS_SEG ; Get number of rows MOV ES,AX ; from BIOS Data Area MOV BX,NB_ROWS_OFFSET ; at 0040:0084 MOV AL,ES:[BX] CBW INC AX MOV SCREEN_HEIGHT,AX .ENDIF JMP SHORT GET_MODE_ATTR_END ; ; The current mode was not found in any of the tables ; MOV ERROR_CODE,MODE_NOT_SUPPORTED GET_MODE_ATTR_END: POP AX POP BX POP CX POP DX RET GET_MODE_ATTR ENDP PAGE ;======================================================================= ; ; SET_UP_XLT_TABLE : SET UP A COLOR MAPPING FOR EACH COLOR AVAILABLE ; WITH THE CURRENT MODE ; ;----------------------------------------------------------------------- ; ; INPUT: CUR_MODE = Current video mode. ; HARDWARE_CONFIG = Type of display adapter. ; PRINTER_TYPE = Type of printer attached (Color or B&W) ; XLT_TAB = Color translation table. ; CUR_PAGE = Active page number ; BP = Offset of the shared data area ; ; ; OUTPUT: XLT_TAB IS UPDATED ; ; CALLED BY: PRT_SCR ; ;----------------------------------------------------------------------- ; ; DESCRIPTION: The table is updated to hold a mapping for each color ; available in the current video mode either TEXT or APA. ; ; For example, if the current mode supports 16 colors then the first ; sixteen bytes of the table will hold the corresponding Color printer ; or Black and White printer mappings for these colors. ; ; ; LOGIC: ; ; IF HARDWARE_CONFIG = CGA OR HARDWARE_CONFIG = PC_CONVERTIBLE ; THEN ; CALL SET_CGA_XLT_TAB ; ; ELSE IF HARDWARE_CONFIG = EGA ; THEN ; CALL SET_EGA_XLT_TAB ; ; ELSE IF CUR_MODE = 0FH ; THEN ; CALL SET_MODE_F_XLT_TAB ; ; ELSE IF CUR_MODE = 19 ; THEN ; CALL SET_MODE_13H_XLT_TAB ; ; ELSE ; CALL SET_ROUNDUP_XLT_TAB ; ; CALL SET_BACKG_IN_XLT_TAB ; Update the background in the translation table ; SET_UP_XLT_TAB PROC NEAR ;------------------------------------------------------------------------------- ; For old display modes: set up translation table as for a Color Graphics Adapt. ; Either 4 or 16 colors are set up depending if the mode is an APA or text mode. ; ; NOTE: SET_UP_XLT_TAB cannot be invoked if the display adater is a Monochrome ; display adater. (When a Mono. adapter is attached, a jump is made to ; the ROM BIOS for printing the screen, and no translation table is set). ;------------------------------------------------------------------------------- .IF OR ; IF it is a CGA .IF ; or a PC convertible .THEN ; THEN set up CGA colors CALL SET_CGA_XLT_TAB ; .ELSEIF ; ELSEIF it is an EGA CALL SET_EGA_XLT_TAB ; set up EGA colors. .ELSEIF ; ELSEIF we are in mode 15 CALL SET_MODE_F_XLT_TAB ; set up its 4 shades ;------------------------------------------------------------------------------- ; A PS/2 system is attached: (we either have a PALACE [Model 30] or a ROUNDUP) ;------------------------------------------------------------------------------- .ELSEIF ; ELSEIF current mode is 13h CALL SET_MODE_13H_XLT_TAB ; set up 256 colors .ELSEIF ; ELSEIF PS/2 Model 30(MCGA) CALL SET_CGA_XLT_TAB ; handle it like a CGA .ELSE ; ELSE we have a ROUNDUP ;------------------------------------------------------------------------------- ; A PS/2 model 50, 60 or 80 or an ADA 'B' card is attached (in 16 color mode): ;------------------------------------------------------------------------------- CALL SET_ROUNDUP_XLT_TAB ; set up 16 colors .ENDIF ;------------------------------------------------------------------------------- ; Finish setting up the translation table: ;------------------------------------------------------------------------------- CALL SET_BACKG_IN_XLT_TAB ; Update the background in the translation table ; according to the command line switch setting ; (i.e.,/R /B) RET SET_UP_XLT_TAB ENDP PAGE ;=============================================================================== ; ; SET_BACKG_IN_XLT_TAB : ADJUST THE MAPPING FOR THE BACKGROUND COLOR IN THE ; XLT_TAB ACCORDING TO PRINTER TYPE AND /R /B. ; ; ;------------------------------------------------------------------------------- ; ; INPUT: BP = Offset of shared data area (SWITCHES) ; XLT_TAB = The color translation table. ; ; OUTPUT: XLT_TAB IS UPDATED ; ;------------------------------------------------------------------------------- ; ; DESCRIPTION: If there is a black and white printer and /R is NOT specified ; then the background color should not be printed and it is replaced in the ; translation table by the Intensity for white (will print nothing). ; ; If a color printer is attached and /B is not specified then the background ; color is replaced by the Print Band mask for white. ; ; LOGIC: ; IF (a black and white printer is attached) AND (/R is OFF) ; THEN ; MOV XLT_TAB, WHITE_INT ; Store white in translation table ; ELSE (a color printer is attached) ; IF (/B is ON) ; THEN ; RGB.R := MAX_INT ; RGB.G := MAX_INT ; RGB.B := MAX_INT ; CALL RGB2BAND ; Convert RGB for white to a Band Mask ; MOV XLT_TAB,AL ; Store the band mask in the xlt table ; ; ;------------------------------------------------------------------------------- SET_BACKG_IN_XLT_TAB PROC NEAR ;------------------------------------------------------------------------------- ; ; Test if a black and white printer is attached. ; ;------------------------------------------------------------------------------- .IF AND ; IF black and white .IF ; printer and not /R .THEN ; then, map background MOV XLT_TAB,WHITE_INT ; to white. ;------------------------------------------------------------------------------- ; ; A Color printer is attached: ; ;------------------------------------------------------------------------------- .ELSEIF AND ; else, if color printer .IF ; and /B if OFF .THEN ; ; Store a null band mask MOV XLT_TAB,0 ; the translation table. .ENDIF RET SET_BACKG_IN_XLT_TAB ENDP PAGE ;======================================================================= ; ; SET_EGA_XLT_TAB : SET UP COLOR TRANSLATION TABLE FOR ENHANCED GRAPHIC ; ADAPTER ; ;----------------------------------------------------------------------- ; ; INPUT: XLT_TAB = Color translation table. ; PRINTER_TYPE = Type of printer attached (Color or B&W) ; SWITCHES = GRAPHICS command line parameters. ; ; OUTPUT: XLT_TAB IS UPDATED ; ; CALLED BY: SET_UP_XLT_TABLE ; ;----------------------------------------------------------------------- ; ; NOTES: With the EGA, "VIDEO BIOS READ DOT call" returns an index into ; the 16 EGA palette registers. ; ; These registers contain the actual colors stored as rgbRGB components ; (see EGA_COL2RGB for details) for mode hex 10. Under mode hex E these ; registers contain the actual colors as I0RGB components (see CGA_COL2RGB ; for details). ; ; These registers can be Revised by the user but, are 'WRITE ONLY'. ; However, it is possible to define a SAVE AREA where BIOS will maintain ; a copy of the palette registers. ; ; This area is called the "DYNAMIC SAVE AREA" and is defined via the ; BIOS EGA SAVE_PTR AREA. Whenever the palette registers are changed by ; the user, BIOS updates the EGA_SAVE_AREA. ; ; The 16 palette registers are the first 16 bytes of the DYNAMIC SAVE AREA. ; ; This program takes advantage of this feature and consults the EGA DYNAMIC ; SAVE AREA in order to obtain the colors used in the active screen. ; ; ; DESCRIPTION: Obtain each color available with an EGA by reading its ; palette register in the EGA_SAVE_AREA: ; ; Calculate the mapping for this color, either a BAND_MASK or a ; GREY INTENSITY and store it in the color translation table. ; ; ; LOGIC: ; ; Obtain the DYNAMIC EGA SAVE AREA offset from the BIOS SAVE_PTR_AREA. ; ; If current mode is either 4,5 or 6 ; Then, ; CALL SET_CGA_XLT_TAB ; Get the background color by reading palette register number 0 ; Else, ; For each register number (0 to 15): ; Get the register contents (rgbRGB values) from the EGA SAVE AREA ; CALL EGA_COL2RGB ; Obtain the Red, Green, Blue values ; CALL RGB2XLT_TAB ; Obtain a Band Mask or a Grey Intensity ; ; and store the result in the XLT_TAB ; SET_EGA_XLT_TAB PROC NEAR PUSH AX ; Save the registers used PUSH BX PUSH CX PUSH DX PUSH DI ;------------------------------------------------------------------------------- ; ; Obtain the pointer to the DYNAMIC SAVE AREA from the SAVE AREA POINTER TABLE: ; ;------------------------------------------------------------------------------- EGA_SAVE_PTR EQU 4A8H ; EGA BIOS pointer to table of ; pointer to save areas. XOR AX,AX ; ES segment := paragraph 0 MOV ES,AX LES BX,ES:DWORD PTR EGA_SAVE_PTR ; ES:BX := Pointer to ptr table LES BX,ES:[BX]+4 ; ES:BX := Pointer to dynamic save area ; (NOTE: It is the second pointer in ; the table) ;------------------------------------------------------------------------------- ; ; Set up one entry in the translation table for each color available. ; ;------------------------------------------------------------------------------- .IF OR ; If the current mode is an old CGA .IF OR ; GRAPHICS mode: .IF .THEN ;------------------------------------------------------------------------------- ; Current mode is either mode 4, 5 or 6; ; Store each color of the old CGA All Points Addressable mode: ;------------------------------------------------------------------------------- CALL SET_CGA_XLT_TAB ; Set up colors in the translation ; table, NOTE: The background color ; will not be set properly since the ; EGA BIOS does not update memory ; location 40:66 with the value ; of the background color as CGA ; does. ;------Adjust the background color in the translation table: ;------The background color is obtained from the EGA DYNAMIC SAVE AREA ;------ES:BX = Address of the EGA DYNAMIC SAVE AREA ;------NOTE : For CGA compatible modes EGA BIOS stores the color in the ;------DYNAMIC SAVE AREA as a I0RGB value. XOR DI,DI ; DI:=register number = index in XLT_TAB MOV AL,ES:[BX][DI] ; AL:=Palette register 0 = Back. color MOV AH,AL ; Convert I0RGB to IRGB (CGA color) AND AL,111B ; Isolate RGB bits AND AH,10000B ; Isolate I bit SHR AH,1 ; Move I bit from position 5 to 4 OR AL,AH ; Get IRGB byte. CALL CGA_COL2RGB ; Convert IRGB to R,G,B values CALL RGB2XLT_TAB ; Convert RGB to an entry in XLT_TAB .ELSE ; ELSE, we have an EGA graphics mode: ;------------------------------------------------------------------------------- ; The current mode is a either a text mode or one of the EGA enhanced mode; ; Store in the translation table each color available (these modes have 16 col.) ;------------------------------------------------------------------------------- MOV CX,16 ; CX := Number of palette registers ; to read XOR DI,DI ; DI := Palette register number ; and index in the translation table STORE_1_EGA_COLOR: MOV AL,ES:[BX][DI] ; AL := Palette register .IF OR ; If mode E (hex) OR mode D (hex) .IF ; the colors are .THEN ; stored as I0CGA colors MOV AH,AL ; Convert I0RGB to IRGB (CGA color) AND AL,111B ; Isolate RGB bits AND AH,10000B ; Isolate I bit SHR AH,1 ; Move I bit from position 5 to 4 OR AL,AH ; Get IRGB byte. CALL CGA_COL2RGB ; Convert IRGB to R,G,B values .ELSE ; Else, they are stored as (rgbRGB); CALL EGA_COL2RGB ; Convert register to R,G,B values .ENDIF CALL RGB2XLT_TAB ; Convert RGB to an entry in XLT_TAB INC DI ; Get next palette register number LOOP STORE_1_EGA_COLOR .ENDIF ; ENDIF 4 colors or 16 colors POP DI ; Restore the registers POP DX POP CX POP BX POP AX RET SET_EGA_XLT_TAB ENDP PAGE ;======================================================================= ; ; SET_CGA_XLT_TAB : SET UP COLOR TRANSLATION TABLE FOR COLOR GRAPHIC ; ADAPTER ; ;----------------------------------------------------------------------- ; ; INPUT: XLT_TAB = Color translation table. ; PRINTER_TYPE = Type of printer attached (Color or B&W) ; SWITCHES = GRAPHICS command line parameters. ; ; OUTPUT: XLT_TAB IS UPDATED ; ; CALLED BY: SET_UP_XLT_TABLE ; ;----------------------------------------------------------------------- ; ; NOTES: With the CGA, the "VIDEO BIOS READ DOT call" returns a number ; from 0 to 3. A dot of value 0 is of the background color. ; ; The actual value of the background color is stored in BIOS VIDEO ; DISPLAY DATA AREA as a PIIRGB value (see CGA_COL2RGB for details) and ; can be any of 16 colors. ; ; A dot of value 1,2, or 3 represents any of 2 specific colors depending ; on the current color palette. ; ; The palette number is obtained from the BIOS VIDEO DISPLAY DATA AREA ; (It is the "P" bit or bit number 5) ; ; The dot values 1,2,3 expressed in binary actually represent the RG ; (Red, Green) components of the color. ; ; The palette number represents the B (Blue) component therefore, when ; the palette number is appended to the color number we obtain the RGB ; components for that color. ; ; (E.G., COLOR = 010 ; COLOR # 2 ; PALETTE= 0 ; PALETTE # 0 ; ; IRGB = 0100 ; Intensity = 0 Ä¿ ; ; Red = 1 ÃÄÄÄ> color = Red ; ; Green = 0 ³ ; ; Blue = 0 ÄÙ ; ; ; DESCRIPTION: ; ; For each color available with a CGA: ; Calculate the color mapping, either a BAND_MASK or a GREY ; INTENSITY and store it in the color translation table. ; ; LOGIC: ; ; ; Obtain the background color from VIDEO BIOS DATA AREA ; ; and the paletter number ; ; ; Store the Background color: ; CALL CGA_COL2RGB ; Convert IRGB components to RGB values ; CALL RGB2XLT_TAB ; Convert RGB to an entry in the translation ; ; table ; ; Store all other colors: ; FOR IRG := 1 TO 3 ; Obtain the color number ; Append palette number (B) to IRG ; CALL CGA_COL2RGB ; Convert color to RGB values ; CALL RGB2XLT_TAB ; Convert RGB to an entry in the translation ; ; table ; SET_CGA_XLT_TAB PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DI PUSH ES .IF OR .IF ;=============================================================================== ; ; THE CURRENT MODE IS MODE 4 OR 5 ; ;------------------------------------------------------------------------------- .THEN ;------------------------------------------------------------------------------- ; Read the CRT palette from the BIOS ROM to obtain the background color and ; the current palette number; store the palette number in BL ;------------------------------------------------------------------------------- ROM_BIOS_SEG EQU 40H ; CGA BIOS SEGMENT CRT_PALETTE_OFF EQU 66H ; BIOS Current palette setting P_BIT_MASK EQU 100000B ; bit 5 = Current palette I_BIT_MASK EQU 1000B ; bit 4 = Intensity bit R_BIT_MASK EQU 100B ; bit 2 = Red bit G_BIT_MASK EQU 10B ; bit 1 = Green bit B_BIT_MASK EQU 1B ; bit 0 = Blue bit MOV AX,ROM_BIOS_SEG ; ES := ROM BIOS SEGMENT PUSH AX POP ES MOV AL,ES:CRT_PALETTE_OFF; AL := CRT Palette (00PIIRGB) MOV BL,P_BIT_MASK ; LOW NIBBLE = BACKGROUND COLOR AND BL,AL ; BL := Palette number MOV CL,5 SHR BL,CL XOR DI,DI ; DI := Index in the XLT_TAB ;------------------------------------------------------------------------------- ; Store the background color, (obtained from low 4 bits of the byte at 40:66) ;------------------------------------------------------------------------------- CALL CGA_COL2RGB ; Convert color (in AL) to R, G, B values CALL RGB2XLT_TAB ; Convert RGB to an entry in XLT_TAB ;------------------------------------------------------------------------------- ; Store the 3 foreground colors for mode 4 and 5 ;------------------------------------------------------------------------------- MOV CX,3 ; For each color, but the background: STORE_1_CGA_MODE4_COLOR: INC DI ; Increment index in the translation table MOV AX,DI ; AL := IRG SHL AL,1 OR AL,BL ; AL := IRGB CALL CGA_COL2RGB ; Convert color (in AL) to R, G, B values CALL RGB2XLT_TAB ; Convert RGB to an entry in XLT_TAB LOOP STORE_1_CGA_MODE4_COLOR .ELSEIF ;=============================================================================== ; ; THE CURRENT MODE IS MODE 6 ; ;------------------------------------------------------------------------------- .THEN ;------------------------------------------------------------------------------- ; Store background color for mode 6 (mode 6 is a 2 colors, APA mode) ; Background is stored as BLACK ;------------------------------------------------------------------------------- XOR DI,DI ; DI := Index of color in translation table MOV RGB.R,BLACK_INT ; Foreground color is white MOV RGB.G,BLACK_INT ; RGB := RGB of white MOV RGB.B,BLACK_INT ; CALL RGB2XLT_TAB ; Convert RGB to an entry in XLT_TAB ;------------------------------------------------------------------------------- ; Store foreground color for mode 6 (mode 6 is a 2 colors, APA mode) ;------------------------------------------------------------------------------- INC DI ; DI := Index of color in translation table MOV RGB.R,WHITE_INT ; Background color is BLACK MOV RGB.G,WHITE_INT ; RGB := RGB of BLACK MOV RGB.B,WHITE_INT ; CALL RGB2XLT_TAB ; Convert RGB to an entry in XLT_TAB .ELSE ;=============================================================================== ; ; THE CURRENT MODE IS A TEXT MODE: ; ;------------------------------------------------------------------------------- XOR DI,DI ; DI := Index in the translation table MOV CX,16 ; For each of the 16 colors: STORE_1_CGA_TEXT_COLOR: MOV AX,DI ; AL := IRGB CALL CGA_COL2RGB ; Convert color (in AL) to R, G, B values CALL RGB2XLT_TAB ; Convert RGB to an entry in XLT_TAB INC DI ; Increment index in the translation table LOOP STORE_1_CGA_TEXT_COLOR .ENDIF ; POP ES POP DI POP CX POP BX POP AX RET SET_CGA_XLT_TAB ENDP PAGE ;=============================================================================== ; ; RGB2XLT_TAB: CONVERT R,G,B VALUES TO EITHER A BAND MASK OR AN INTENSITY ; STORE THE RESULT IN THE TRANSLATION TABLE ; ;------------------------------------------------------------------------------- ; ; INPUT: DI = Index in the translation table ; RGB = Red Green Blue values of the color to be stored. ; ; OUTPUT: XLT_TAB is updated ; ;------------------------------------------------------------------------------- ; DESCRIPTION: Convert the RGB values to either a Band mask or an intensity ; depending on the printer type; store the result in the translation table. ; ; LOGIC: ; IF PRINTER_TYPE = COLOR ; THEN ; CALL RGB2BAND ; Obtain a Band Mask ; ELSE ; Printer is Monochrome ; CALL RGB2INT ; Obtain a Grey Intensity ; Store the result in the XLT_TAB ; RGB2XLT_TAB PROC NEAR .IF ; Color printer ? .THEN ;-------A color printer is attached: CALL RGB2BAND ; Yes, convert RGB to color band (in AL) .ELSE ;-------A black and white printer is attached: CALL RGB2INT ; No, RGB to an intensity in AL .ENDIF ;-------Store the result MOV XLT_TAB[DI],AL RET RGB2XLT_TAB ENDP PAGE ;=============================================================================== ; ; CGA_COL2RGB : CONVERT A COLOR FROM THE CGA TO RED GREEN BLUE VALUES ; ;------------------------------------------------------------------------------- ; ; INPUT: AL = 0000IRGB ONE BYTE WHERE BIT: ; ; I = Intensity bit ; R = Red component ; G = Green component ; B = Blue component ; ; ; OUTPUT: RGB.R = RED component (0-63) ; RGB.G = GREEN component (0-63) ; RGB.B = BLUE component (0-63) ; ; CALLED BY: SET_UP_CGA_XLT_TABLE ; ;----------------------------------------------------------------------- ; ; DESCRIPTION: If either the RED, GREEN, or BLUE bit is on (in an IRGB ; byte) then, the corresponding color gun on the display is firing 2/3 ; of its capacity, giving a color intensity of "2/3". ; ; If the INTENSITY bit is on, then 1/3 is added to EACH color. ; ; (E.G., IRGB R G B ; BLACK = 00000000 ( 0, 0, 0) ; WHITE = 00001111 (3/3, 3/3, 3/3) ; RED = 00000100 (2/3, 0, 0) ; HIGH INT. RED = 00001100 (3/3, 1/3, 1/3) ; ; Since we want an intensity from 0 to 63, ; "2/3" of RED means: ; 2/3 * 63 = 42 ; ; ; LOGIC: ; Get the intensity. ; Get the red component ; Get the green component ; Get the blue component ; CGA_COL2RGB PROC NEAR ;----------------------------------------------------------------------- ; ; Init the R,G,B values: ; ;----------------------------------------------------------------------- MOV RGB.R,0 MOV RGB.G,0 MOV RGB.B,0 ;----------------------------------------------------------------------- ; ; Test the Intensity bit: ; ;----------------------------------------------------------------------- .IF ; IF, I is on .THEN ADD RGB.R,ONE_THIRD ; Then, add one third to each ADD RGB.G,ONE_THIRD ; color. ADD RGB.B,ONE_THIRD .ENDIF ;----------------------------------------------------------------------- ; ; Test the RGB bits: ; ;----------------------------------------------------------------------- .IF ; If, Red is on .THEN ADD RGB.R,TWO_THIRD ; then, add two third RED .ENDIF .IF ; If, Green is on .THEN ADD RGB.G,TWO_THIRD ; then, add two third GREEN .ENDIF .IF ; If, Blue is on .THEN ADD RGB.B,TWO_THIRD ; then, add two third BLUE .ENDIF RET CGA_COL2RGB ENDP PAGE ;======================================================================= ; ; SET_MODE_F_XLT_TAB: SET UP COLOR TRANSLATION TABLE FOR MONOCHROME ; MODE "F" ; ;----------------------------------------------------------------------- ; ; INPUT: XLT_TAB = Color translation table. ; PRINTER_TYPE = Type of printer attached (Color or B&W) ; SWITCHES = GRAPHICS command line parameters. ; ; OUTPUT: XLT_TAB IS UPDATED ; ; CALLED BY: SET_UP_XLT_TABLE ; ;------------------------------------------------------------------------------- ; ; NOTES: In mode F the "VIDEO BIOS READ DOT call" returns a byte where ; bit 1 and 3 represent the value of plane 1 and 3. ; The following colors are available using this mode: ; ; plane 2: plane 0: color: ; 0 0 black ; 0 1 white ; 1 0 blinking white ; 1 1 high-intensity white ; ; ; DESCRIPTION: A local table holds the Red, Green, Blue values for each of ; the 4 Mono colors available in Mode Fh. ; Each color is stored as either a Grey intensity if printing in Monochrome ; or as a Band Mask if printing in color. ; Black is stored as black. ; White is stored as a light gray ; High-intensity white and blinking white are stored as white. ; ; ; LOGIC: ; FOR EACH "COLOR" AVAILABLE WITH MODE F ; GET ITS R,G,B VALUES ; CALL RGB2XLT_TAB ; Convert RGB to an entry in the translation ; ; table ; SET_MODE_F_XLT_TAB PROC NEAR PUSH AX PUSH SI PUSH DI JMP SHORT SET_MODE_F_BEGIN ;------------------------------------------------------------------------------- ; ; TABLE OF R,G,B VALUES WE ASSIGN TO THE 4 COLORS AVAILABLE IN MODE F: ; ;------------------------------------------------------------------------------- MODE_F_RGB LABEL BYTE DB BLACK_INT,BLACK_INT,BLACK_INT ; Black is mapped to black. DB TWO_THIRD,TWO_THIRD,TWO_THIRD ; White --> light grey DB WHITE_INT,WHITE_INT,WHITE_INT ; Blinking --> white DB WHITE_INT,WHITE_INT,WHITE_INT ; High-int. White --> white ;------------------------------------------------------------------------------- ; ; STORE THE COLORS AVAILABLE WITH MODE F ; ;------------------------------------------------------------------------------- SET_MODE_F_BEGIN: MOV SI,OFFSET MODE_F_RGB ; SI <-- Offset of RGB table XOR DI,DI ; DI <-- Index into translation table ;-------For each color available in mode F: STORE_1_MODE_F_COLOR: MOV AL,[SI] ; Get the Red component MOV RGB.R,AL MOV AL,[SI]+1 ; Get the Green component MOV RGB.G,AL MOV AL,[SI]+2 ; Get the Blue component MOV RGB.B,AL ;-------Convert pixel to either a Color band or an Intensity: CALL RGB2XLT_TAB ; Convert and store in the xlt table ADD SI,3 ; Get next R,G,B values INC DI ; One more color has been stored CMP DI,NB_COLORS ; All stored ? JL STORE_1_MODE_F_COLOR POP DI POP SI POP AX RET SET_MODE_F_XLT_TAB ENDP PAGE ;======================================================================= ; ; SET_MODE_13H_XLT_TAB: SET UP COLOR TRANSLATION TABLE FOR PALACE VIDEO ; ADAPTER IN MODE 13H ; ;----------------------------------------------------------------------- ; ; INPUT: XLT_TAB = Color translation table. ; PRINTER_TYPE = Type of printer attached (Color or B&W) ; SWITCHES = GRAPHICS command line parameters. ; ; OUTPUT: XLT_TAB IS UPDATED ; ; CALLED BY: SET_UP_XLT_TABLE ; ;----------------------------------------------------------------------- ; ; NOTES: With the PALACE the "VIDEO BIOS READ DOT call" returns a direct ; index to the 256 COLOR REGISTERS. ; ; These COLORS REGISTERS hold the R,G,B (Red, Green, Blue) values for ; each of the 256 colors available at the same time on the screen. ; Color register number 0 holds the background color. ; ; DESCRIPTION: Store a color mapping for each color register. ; If the REVERSE_SW is off, exchange white and black. ; ; LOGIC: ; ; For each color (0 to 255) ; Read the color register ; get the RGB values for this color num. ; Store the result in the XLT_TAB ; SET_MODE_13H_XLT_TAB PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX PUSH DI MOV NB_COLORS_TO_READ,256 ; Read 256 color registers ;------------------------------------------------------------------------------- ; ; Store in the translation table each color available for mode 13h: ; ;------------------------------------------------------------------------------- XOR DI,DI ; DI := Palette register number ; and index in the translation table STORE_1_M13H_COLOR: MOV BX,DI ; BX := Color register to be read MOV AX,GET_C_REG_CALL ; AX := BIOS Get color register call INT 10H ; Call BIOS MOV RGB.R,DH ; Get Red value MOV RGB.G,CH ; Get Green value MOV RGB.B,CL ; Get Blue value CALL RGB2XLT_TAB ; Convert RGB to an entry in XLT_TAB INC DI ; Get next palette register number CMP DI,NB_COLORS_TO_READ ; All colors stored ? JL STORE_1_M13H_COLOR ; No, get next one POP DI POP DX POP CX POP BX POP AX RET NB_COLORS_TO_READ DW ? ; Number of colors registers to read with a PS/2 SET_MODE_13H_XLT_TAB ENDP PAGE ;=============================================================================== ; ; SET_ROUNDUP_XLT_TAB: SET UP COLOR TRANSLATION TABLE FOR ROUNDUP VIDEO ; ADAPTER ; ;------------------------------------------------------------------------------- ; ; INPUT: XLT_TAB = Color translation table. ; PRINTER_TYPE = Type of printer attached (Color or B&W) ; SWITCHES = GRAPHICS command line parameters. ; ; OUTPUT: XLT_TAB IS UPDATED ; ; CALLED BY: SET_UP_XLT_TABLE ; ;------------------------------------------------------------------------------- ; ; NOTES: With the ROUNDUP the "VIDEO BIOS READ DOT call" returns an ; index into the 16 PALETTE REGISTERS. ; ; Each palette register holds an index into the current "color page" ; within the 256 COLOR REGISTERS. ; ; These "color pages" represent all the colors from WHICH TO CHOOSE the ; screen colors for an active page; 16 colors can be displayed at the ; same time on the screen. ; ; There are 2 paging modes: either 64 color pages or 16 color pages: ; ; In 64 color mode, there are 4 color pages available (the 256 palette ; registers are partitioned in 4 blocks of 64 colors). ; ; The 16 screen colors for the active page are selected from these 64 ; color registers. ; ; This scheme allows for quickly changing the contents of the screen by ; changing the active page. ; ; The COLOR REGISTERS contains the color information stored as RGB (Red, ; Green, Blue) components. There is one byte for each of these 3 ; components. The value for each component ranges from 0 to 63 (where ; 0 = color not present). ; ; ; DESCRIPTION: Determine the paging mode and the active color page. ; For each color available with the current mode, get the palette ; register and then, read the corresponding color register in order to ; obtain its RGB components. ; ; For mode 11h, 2 colors only are available. These colors are obtained from ; palette register 0 (background) and 7 (foreground color). The contents ; of these 2 palette registers is also used as an index within the color ; registers. ; ; If printing is Monochrome, map the RGB to a Grey Intensity. ; If printing is in colors, map the RGB to a Band Mask. ; Store the result in the translation table ; ; LOGIC: ; ; Read color page state (BIOS INT 10H - AL = 1AH) ; ; If mode 4,5 or 6 ; Then ; CALL SET_CGA_XLT_TAB ; Adjust the background color. ; else ; If mode 11h ; then ; For PALETTE_INDEX := 0 to 15 ; IF PAGE_MODE = PAGE_64_REGISTERS ; THEN ; Read the palette register number "PALETTE_INDEX" ; COLOR_INDEX := Palette register contents ; COLOR_INDEX := (CUR_PAGE_NUM * 64) + COLOR_INDEX ; Read color register number "COLOR_INDEX" ; Obtain R,G,B values. ; CALL RGB2XLT_TAB ; Convert RGB to an entry in XLT_TAB ; ; ELSE IF PAGE_MODE = PAGE_16_REGISTERS ; COLOR_INDEX := (CUR_PAGE_NUM * 16) + PALETTE_INDEX ; Read color register number "COLOR_INDEX" ; CALL RGB2XLT_TAB ; Convert RGB to an entry in XLT_TAB ; ; SET_ROUNDUP_XLT_TAB PROC NEAR PAGING_MODE_64 EQU 0 PUSH AX PUSH BX PUSH CX PUSH DI ;------------------------------------------------------------------------------- ; Obtain the color page state ;------------------------------------------------------------------------------- MOV AX,PAGE_STATE_CALL ; Call BIOS INT 10H ; BL := Paging mode ; BH := Current page ;------------------------------------------------------------------------------- ; Check the video mode: ;------------------------------------------------------------------------------- .SELECT .WHEN OR ; If the current mode is an old CGA .WHEN OR ; mode: .WHEN ; ;------------------------------------------------------------------------------- ; ; Old CGA graphics mode (mode 4, 5 or 6) ; ;------------------------------------------------------------------------------- ;------------------------------------------------------------------------------- ; Store colors of the old CGA modes: ;------------------------------------------------------------------------------- CALL SET_CGA_XLT_TAB ; Set up colors in the translation ; table, NOTE: The background color ; will not be set properly since the ; PS/2 BIOS does not update memory ; location 40:66 with the value ; of the background color as CGA ; does for modes 4 and 5. However ; 40:66 holds the current palette ; selected. ;------------------------------------------------------------------------------- ; Adjust the background color for modes 4,5 or 6 ;------------------------------------------------------------------------------- MOV PAL_REGISTER_NB,0 ; Read the palette register number 0 CALL GET_PALETTE_RGB ; this register points to the color ; register that contains the RGB ; values of the BACKGROUND color. MOV DI,0 ; DI := Index in the translation table CALL RGB2XLT_TAB ; Store mapping in the translation table .WHEN ;------------------------------------------------------------------------------- ; ; Mode 11h (2 colors out of 256,000 colors) ; ;------------------------------------------------------------------------------- ;------------------------------------------------------------------------------- ; Get the background color: ;------------------------------------------------------------------------------- MOV PAL_REGISTER_NB,0 ; Read the palette register number 0 CALL GET_PALETTE_RGB ; Get the RGB values for this color MOV DI,0 ; DI := Index in translation table CALL RGB2XLT_TAB ; Store mapping in the translation table ;------------------------------------------------------------------------------- ; Get the foreground color: ;------------------------------------------------------------------------------- MOV PAL_REGISTER_NB,7 ; Read the palette register for the ; FOREGROUND color (palette register 7) CALL GET_PALETTE_RGB ; Get the RGB values for this color MOV DI,1 ; DI := Index in translation table CALL RGB2XLT_TAB ; Store mapping in the translation table .OTHERWISE ;------------------------------------------------------------------------------- ; ; The current mode is a 16 color mode ; ;------------------------------------------------------------------------------- XOR DI,DI ; DI := Index in translation table MOV CX,16 ; 16 colors to read and store MOV PAL_REGISTER_NB,0 ; Palette register to read STORE_1_PS2_COLOR: CALL GET_PALETTE_RGB ; Get the RGB values for this color ; ;-------Convert the RGB values to band mask or intensity and store in XLT_TAB: CALL RGB2XLT_TAB ; Store mapping in the translation table INC DI ; Get next palette register number INC PAL_REGISTER_NB ; LOOP STORE_1_PS2_COLOR ; Read it. .ENDSELECT POP DI POP CX POP BX POP AX RET PAL_REGISTER_NB DB ? ; Number of the palette register to read SET_ROUNDUP_XLT_TAB ENDP PAGE ;=============================================================================== ; ; GET_PALETTE_RGB: ON THE PS/2 MODEL 50, 60 AND 80, GET THE RGB VALUES FOR A ; PALETTE REGISTER BY READING THE CORRESPONDING COLOR REGISTER ; ;------------------------------------------------------------------------------- ; ; INPUT: PAL_REGISTER_NB = Palette register number ; BH = Current page number ; BL = Current paging mode ; ; OUTPUT: RGB.R = The RGB values obtained from the color register ; RGB.G corresponding to the palette register specified ; RGB.B ; ; CALLED BY: SET_ROUNDUP_XLT_TAB ; ;------------------------------------------------------------------------------- GET_PALETTE_RGB PROC PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI MOV AL,BH ; SI := Current page number CBW ; MOV SI,AX ; ;------------------------------------------------------------------------------- ; ; Calculte the absolute number of the first Color Register for the current page: ; (calculated in SI) ; ;------------------------------------------------------------------------------- .IF ; If mode is 64 Color page .THEN ; then MOV CL,6 ; SI := Current page num * 64 SHL SI,CL ; .ELSE ; else, Mode is 16 Color page MOV CL,4 ; SI := Current page num * 16 SHL SI,CL ; .ENDIF ; ;-------Read the PALETTE REGISTER MOV BL,PAL_REGISTER_NB ; BL := Palette register to be read MOV AX,GET_P_REG_CALL ; Read palette register call INT 10H ; Call BIOS, ; BH := Color register index ; WITHIN the current page and is ; either (0-15) or (0-63) ; NOTE: SI = Absolute index (0-255) to ; the first color register of the ; current page and is a multiple of ; either 16 or 64 MOV BL,BH ; BX := Index within current color page XOR BH,BH ; ; ;-------Read the Color register: OR BX,SI ; BX := Index of Color register to read MOV AX,GET_C_REG_CALL ; Read the color register INT 10H ; Call BIOS, MOV RGB.R,DH ; DH := Red value read MOV RGB.G,CH ; CH := Green value read MOV RGB.B,CL ; CL := Blue value read POP SI POP DX POP CX POP BX POP AX RET GET_PALETTE_RGB ENDP PAGE ;======================================================================= ; ; EGA_COL2RGB : CONVERT A COLOR FROM THE EGA TO RED GREEN BLUE VALUES ; ;----------------------------------------------------------------------- ; ; INPUT: AL = 00rgbRGB ONE BYTE WHERE BIT: ; ; r = 1/3 of Red component ; g = 1/3 of Green component ; b = 1/3 of Blue component ; R = 2/3 of Red component ; G = 2/3 of Green component ; B = 3/3 of Blue component ; ; ; OUTPUT: RGB.R = RED component (0-63) ; RGB.G = GREEN component (0-63) ; RGB.B = BLUE component (0-63) ; ; CALLED BY: SET_UP_EGA_XLT_TABLE ; ;----------------------------------------------------------------------- ; ; DESCRIPTION: Sums up the values for each color component. ; "2/3 of RED" means that the red gun in the display attached to the EGA ; is firing at 2/3 of full intensity. ; ; Since the color intensities range from 0 to 63, "1/3" means an ; intensity of: ; 1/3 * 63 = 21 ; ; LOGIC: ; ; Get the red component ; Get the green component ; Get the blue component ; EGA_COL2RGB PROC NEAR ; ;-------Get the RED component (bit 5 and 2) ; ;-------Check bit 2 MOV RGB.R,0 TEST AL,100B ; "R" is on ? JZ CHECK_BIT_5 ; No, check "r" ADD RGB.R,TWO_THIRD ; Yes, add 2/3 RED CHECK_BIT_5: TEST AL,100000B ; "r" is on ? JZ CHECK_BIT_1 ; No, check Green ADD RGB.R,ONE_THIRD ; Yes, add 1/3 RED ; ;-------Get the GREEN component (bit 4 and 1) ; CHECK_BIT_1: MOV RGB.G,0 TEST AL,10B ; "G" is on ? JZ CHECK_BIT_4 ; No, check "g" ADD RGB.G,TWO_THIRD ; Yes, add 2/3 GREEN CHECK_BIT_4: TEST AL,10000B ; "g" is on ? JZ CHECK_BIT_0 ; No, check for Blue ADD RGB.G,ONE_THIRD ; Yes, add 1/3 GREEN ; ;-------Get the BLUE component (bit 3 and 0) ; CHECK_BIT_0: MOV RGB.B,0 TEST AL,1B ; "B" is on ? JZ CHECK_BIT_3 ; No, check "b" ADD RGB.B,TWO_THIRD ; Yes, add 2/3 BLUE CHECK_BIT_3: TEST AL,1000B ; "b" is on ? JZ EGA_COL2RGB_RETURN ; No, return ADD RGB.B,ONE_THIRD ; Yes, add 1/3 BLUE EGA_COL2RGB_RETURN: RET EGA_COL2RGB ENDP PAGE ;=============================================================================== ; ; RGB2INT : MAP RED GREEN BLUE VALUES TO AN INTENSITY. ; ;------------------------------------------------------------------------------- ; ; INPUT: RGB.R = A RED value (0-63) ; RGB.G = A GREEN value (0-63) ; RGB.B = A BLUE value (0-63) ; DARKADJUST_VALUE= THE DARKNESS VALUE (In shared data area). ; SWITCHES = Command line switches ; ; OUTPUT: AL = THE INTENSITY (0-63) NOTE: 0 = BLACK ; 63 = BRIGHT WHITE ; ; WARNING: AH IS LOST ; ;------------------------------------------------------------------------------- ; ; DESCRIPTION: When the RGB values for a pixel are at their maximum ; value, what we obtain is a bright white pixel on the screen; this is ; the brightest color achievable and therefore, its intensity is 63. ; ; When no color gun is firing on the display: RGB values are 0,0,0 this ; is no color at all and therefore maps to intensity 0. ; ; For intermediate colors, experimentation has shown that the eye will ; see blue as darker than red and red as darker than green. ; ; On a grey rainbow from 0 - 10 where 0 is black and 10 is white: ; ; Blue corresponds to a grey of intensity 1 ; Red corresponds to a grey of intensity 3 ; Green corresponds to a grey of intensity 6 ; ; Therefore, if we mix all 3 colors we obtain a grey of ; intensity 1 + 3 + 6 = 10 (i.e.,white). ; ; ; LOGIC: ; ; Calculate the intensity ; ; AL = (.6 * G) + (.3 * R) + (.1 * B) ; ; Adjust Darkness ; ; AL = AL + DARKADJUST_VALUE ; RGB2INT PROC NEAR PUSH BX PUSH CX PUSH DX XOR AX,AX ; AL := Current component intensity XOR BX,BX ; BX is used for calculations XOR DX,DX ; DL := Running sum for grey intensity ;-------Process /R (Reverse black and white) .IF ; IF reverse is OFF .THEN ; THEN REVERSE BLACK AND WHITE: ;-------Test if the color is BLACK .IF AND ; If black .IF AND ; .IF ; .THEN ; then, replace it with white MOV AL,WHITE_INT JMP SHORT RGB2INT_END .ELSEIF AND ; else if, high-intensity white .IF AND ; .IF ; .THEN ; then, replace it with black MOV AL,BLACK_INT JMP SHORT RGB2INT_END .ELSEIF AND ; else if, white .IF AND ; .IF ; .THEN ; then, replace it with black MOV AL,BLACK_INT JMP SHORT RGB2INT_END .ENDIF .ENDIF ;-------Calculate Green component MOV AL,RGB.G ; AL := Green component MOV BH,6 ; MUL BH ; AX := Green * 6 MOV BH,10 ; DIV BH ; AL := (GREEN * 6) / 10 ADD DL,AL ; DL := Cumulative intensity MOV CH,AH ; CH := Cumulative remainder ;-------Calculate Red component MOV AL,RGB.R ; AL := Red component MOV BH,3 ; MUL BH ; AX := Red * 3 MOV BH,10 ; DIV BH ; AL := (RED * 3) / 10 ADD DL,AL ; DL := Cumulative intensity ADD CH,AH ; CH := Cumulative remainder ;-------Calculate Blue component MOV AL,RGB.B ; AX := Blue component XOR AH,AH ; DIV BH ; AL := BLUE / 10 ADD DL,AL ; DL := Cumulative intensity ADD CH,AH ; CH := Cumulative remainder ;-------Adjust intensity with cumulative remainder XOR AX,AX MOV AL,CH ; AX := Cumulative remainder MOV BH,10 ; BH := 10 DIV BH ; AL := Total remainder / 10 ADD DL,AL ; DL := Cumulative intensity .IF ; If remainder > 4 .THEN ; Then, add 1 INC DL ; to the intensity .ENDIF ;-------Adjust darkness ADD DL,DS:[BP].DARKADJUST_VALUE ;-------Return result MOV AL,DL ; AL := sum of R,G,B intensities RGB2INT_END: POP DX POP CX POP BX RET RGB2INT ENDP PAGE ;============================================================================== ; ; RGB2BAND: MAP RED GREEN BLUE VALUES TO A "SELECT COLOR BAND" MASK FOR ; THE COLOR PRINTER. ; ;------------------------------------------------------------------------------ ; ; INPUT: RGB.R = A RED value (0-63) ; RGB.G = A GREEN value (0-63) ; RGB.B = A BLUE value (0-63) ; BP = Offset of the Shared Data Area. ; ; OUTPUT: AL = The Band Mask, one byte where: ; ; bit 0 = Color Band 1 is needed ; bit 1 = Color Band 2 is needed ; bit 2 = Color Band 3 is needed ; bit 3 = Color Band 4 is needed ; ; ; CALLED BY: SET_CGA_XLT_TAB ; SET_EGA_XLT_TAB ; SET_ROUNDUP_XLT_TAB ; SET_MODE_13H_XLT_TAB ; SET_MODE_F_XLT_TAB ; ;------------------------------------------------------------------------------ ; ; NOTES: The RGB values in input describe a color from the screen. ; Up to 256K different colors can be described with these RGB values. ; ; On the color printer, the print ribbon is composed of 4 color bands, ; each of a different color. By overlapping these 4 bands when ; printing, more colors can be obtained. However, the number of colors ; that can be achieved by overlapping print bands is very limited (4 or ; 8 colors). ; ; THIS MODULE SELECT THE PRINTER COLOR THAT IS THE CLOSEST TO THE ; DESIRED SCREEN COLOR. ; ; The Band Mask specifies which color bands have to be overlapped to ; obtain a color on the printer. ; ; ; DESCRIPTION: Go through the list of printer colors in the SHARED DATA ; AREA, for each of these colors, compare its RGB values with those in ; input. ; Get the BAND_MASK of the closest printer color. ; ; LOGIC: ; ; Locate the printer colors info structure in the shared data area: ; COLORPRINT_PTR := BP + COLORPRINT_PTR ; ; Get the number of printer colors from the COLORPRINT info in the Shared ; data area: ; Number of colors := COLORPRINT_PTR.NUM_PRT_COLOR ; ; CURRENT_COLOR_PTR : First record in the COLORPRINT info structure ; BEST_CHOICE := CURRENT_RECORD_PTR.BAND_MASK ; MIN_DIFF := Maximum positive value ; ; FOR each printer color: ; CUR_DIFF := 0 ; (* Calculate the geometric distance between the RGB values from the *) ; (* input and those of the printer color. *) ; Red difference := (R - CURRENT_COLOR_PTR.RED) ; Red difference := Red difference * Red difference ; CUR_DIFF := CUR_DIFF + Red difference ; ; Green difference := (G - CURRENT_COLOR_PTR.GREEN) ; Green difference := Green difference * Green difference ; CUR_DIFF := CUR_DIFF + Green difference ; ; Blue difference := (B - CURRENT_COLOR_PTR.BLUE) ; Blue difference := Blue difference * Blue difference ; CUR_DIFF := CUR_DIFF + Blue difference ; ; IF CUR_DIFF < MIN_DIFF ; THEN BEGIN ; MIN_DIFF := CUR_DIFF ; BEST_CHOICE := printer color.BAND_MASK ; END ; ; CURRENT_COLOR_PTR := Offset of next color ; END (For each printer color) ; ; Return BEST_CHOICE ; ; RGB2BAND PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX ;-------Process /R (Reverse black and white) .IF ; IF reverse is OFF .THEN ; THEN REVERSE BLACK AND WHITE: ;------------------------------------------------------------------------------ ; ; REVERSE BLACK AND WHITE: ; ;------------------------------------------------------------------------------ ;-------Test if the color is BLACK .IF AND ; If black .IF AND ; .IF ; .THEN ; then, replace it with the MOV BEST_CHOICE,0 ; band mask for white JMP RGB2BAND_END ; return this band mask .ELSEIF AND ; else if, high-intensity white .IF AND ; .IF ; .THEN ; then, replace it with the MOV RGB.R,BLACK_INT ; RGB values of black MOV RGB.G,BLACK_INT MOV RGB.B,BLACK_INT .ELSEIF AND ; else if, white .IF AND ; .IF ; .THEN ; then, replace it with the MOV RGB.R,BLACK_INT ; RGB values of black MOV RGB.G,BLACK_INT MOV RGB.B,BLACK_INT .ENDIF .ENDIF ;------------------------------------------------------------------------------ ; ; CALCULATE THE GEOMETRIC DISTANCE BETWEEN THE COLORS OF THE PIXEL AND THOSE OF ; THE PRINTER: ; ;------------------------------------------------------------------------------ MOV BX,DS:[BP].COLORPRINT_PTR ; BX := OFFSET of COLORPRINT ADD BX,BP MOV MIN_DIFF,7FFFh ; No match yet, minimum diff. ; is maximum POSITIVE value. XOR CX,CX MOV CL,DS:[BP].NUM_PRT_COLOR ; CX := Number of print colors INSPECT_1_PRINT_COLOR: MOV CUR_DIFF,0 ; Current difference := 0 ;------------------------------------------------------------------------------ ; Calculate the Red difference: ;------------------------------------------------------------------------------ MOV AL,RGB.R SUB AL,[BX].RED ;-------Elevate at the power of two MOV DL,AL ; DX := Red difference IMUL DL ; AX := Red diff. square ADD CUR_DIFF,AX ; CURR_DIF + Red diff. ;------------------------------------------------------------------------------ ; Calculate the Green difference: ;------------------------------------------------------------------------------ MOV AL,RGB.G SUB AL,[BX].GREEN ;-------Elevate at the power of two MOV DL,AL ; DX := Red difference IMUL DL ; AX := Red diff. square ADD CUR_DIFF,AX ; CURR_DIF + Green diff. ;------------------------------------------------------------------------------ ; Calculate the Blue difference: ;------------------------------------------------------------------------------ MOV AL,RGB.B SUB AL,[BX].BLUE ;-------Elevate at the power of two MOV DL,AL ; DX := Red difference IMUL DL ; AX := Red diff. square ADD CUR_DIFF,AX ; CURR_DIF + Blue diff. ;------------------------------------------------------------------------------ ; Check how close is this print color to the screen color: ;------------------------------------------------------------------------------ MOV AX,CUR_DIFF ; If this color is better than what we .IF ; had before. .THEN ; MOV MIN_DIFF,AX ; then, new minimum distance; MOV AL,[BX].SELECT_MASK ; get its band mask. MOV BEST_CHOICE,AL ; .ENDIF ; ;------------------------------------------------------------------------------ ; Get offset of next COLORPRINT info record: ;------------------------------------------------------------------------------ ADD BX,SIZE COLORPRINT_STR LOOP INSPECT_1_PRINT_COLOR ;------------------------------------------------------------------------------ ; BEST_CHOICE contains the print color with the closest RGB values ;------------------------------------------------------------------------------ RGB2BAND_END: POP DX POP CX POP BX POP AX MOV AL,BEST_CHOICE RET BEST_CHOICE DB ? MIN_DIFF DW ? CUR_DIFF DW ? RGB2BAND ENDP CODE ENDS END