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