From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/GRAPHICS/GRCTRL.ASM | 2162 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 2162 insertions(+) create mode 100644 v4.0/src/CMD/GRAPHICS/GRCTRL.ASM (limited to 'v4.0/src/CMD/GRAPHICS/GRCTRL.ASM') diff --git a/v4.0/src/CMD/GRAPHICS/GRCTRL.ASM b/v4.0/src/CMD/GRAPHICS/GRCTRL.ASM new file mode 100644 index 0000000..1deff0a --- /dev/null +++ b/v4.0/src/CMD/GRAPHICS/GRCTRL.ASM @@ -0,0 +1,2162 @@ + 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; -- cgit v1.2.3