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