Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1128 lines
51 KiB

;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1988 - 1991
; * All Rights Reserved.
; */
PAGE ,132 ;AN000;
TITLE DOS GRAPHICS Command - Color printing modules
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
;; DOS - GRAPHICS Command
;;
;; ;AN000;
;; File Name: GRCOLPRT.ASM ;AN000;
;; ---------- ;AN000;
;; ;AN000;
;; Description: ;AN000;
;; ------------ ;AN000;
;; This file contains the code for printing a screen (text and graphics) ;AN000;
;; on a COLOR printer. ;AN000;
;; ;AN000;
;; Documentation Reference: ;AN000;
;; ------------------------ ;AN000;
;; OASIS High Level Design ;AN000;
;; OASIS GRAPHICS I1 Overview ;AN000;
;; ;AN000;
;; Procedures Contained in This File: ;AN000;
;; ---------------------------------- ;AN000;
;; ;AN000;
;; PRINT_COLOR ;AN000;
;; SCAN_FOR_BANDS_APA ;AN000;
;; SCAN_FOR_BANDS_TXT ;AN000;
;; PRINT_BAND_APA ;AN000;
;; PRINT_BAND_TXT ;AN000;
;; SET_CURSOR ;AN000;
;; SET_COLOR_BAND ;AN000;
;; INIT_BLACK_BOX ;AN000;
;; ;AN000;
;; ;AN000;
;; Include Files Required: ;AN000;
;; ----------------------- ;AN000;
;; ;AN000;
;; GRCTRL.EXT - Externals for print screen control ;AN000;
;; GRCTRL.STR - Structures and equates for print screen control ;AN000;
;; GRPATTRN.STR - Structures for the printer patterns. ;AN000;
;; ;AN000;
;; GRSHAR.STR - Shared Data Area Structure ;AN000;
;; ;AN000;
;; STRUC.INC - Macros for using structured assembly language ;AN000;
;; ;AN000;
;; External Procedure References: ;AN000;
;; ------------------------------ ;AN000;
;; FROM FILE GRCTRL.ASM: ;AN000;
;; PRT_SCR - Main module for printing the screen. ;AN000;
;; TO FILE GRCOMMON.ASM ;AN000;
;; Common modules - tools for printing a screen. ;AN000;
;; ;AN000;
;; Linkage Instructions: ;AN000;
;; -------------------- ;AN000;
;; Refer to GRAPHICS.ASM ;AN000;
;; ;AN000;
;; Change History: ;AN000;
;; --------------- ;AN000;
;; Date last updated 5/26/87. ;AN000;
;; ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
PAGE ;AN000;
CODE SEGMENT PUBLIC 'CODE' ;AN000;
ASSUME CS:CODE,DS:CODE ;AN000;
;AN000;
PUBLIC PRINT_MODULE_START ;; Color modules public ;AN000;
PUBLIC PRINT_COLOR ;; procedures ;AN000;
PUBLIC LEN_OF_COLOR_MODULES ;; ;AN000;
;; ;AN000;
.XLIST ; ;AN000;
INCLUDE GRCTRL.STR ; Stuctures needed ;AN000;
INCLUDE GRSHAR.STR ; for both set of print modules ;AN000;
INCLUDE GRPATTRN.STR ; ;AN000;
; ;AN000;
INCLUDE GRCTRL.EXT ; Externals from PRT_SCR control module ;AN000;
INCLUDE STRUC.INC ; ;AN000;
.LIST ; ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AN000;
;; ;AN000;
;; ;AN000;
;; PRINT_COLOR : PRINT TEXT AND APA MODE SCREEN ON A COLOR PRINTER ;AN000;
;; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; INPUT: BP = Offset of the shared data area ;AN000;
; XLT_TAB = Color translation table ;AN000;
; ;AN000;
; OUTPUT: PRINTER ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
;; ;AN000;
;; Description: ;AN000;
;; Main control module for printing of text and graphics ;AN000;
;; on color printers. ;AN000;
;; ;AN000;
;; Calls either the text or graphics mode routine. ;AN000;
;; ;AN000;
;; Called By: ;AN000;
;; PRINT_SCREEN ;AN000;
;; ;AN000;
;; External Calls: ;AN000;
;; LOC_MODE_PRT_INFO, PRINT_COLOR_APA, PRINT_COLOR_TXT ;AN000;
;; ;AN000;
;; Logic: ;AN000;
;; IF MODE_TYPE = TXT ;AN000;
;; THEN CALL PRINT_COLOR_TXT ;AN000;
;; ELSE (MODE_TYPE = APA) ;AN000;
;; CALL LOC_MODE_PRT_INFO ; Get DISPLAYMODE record from the SHARED AREA ;AN000;
;; CALL PRINT_COLOR_APA ;AN000;
;; RETURN ;AN000;
;; ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
PRINT_MODULE_START LABEL BYTE ;AN000;
PRINT_COLOR PROC NEAR ;AN000;
JMP SHORT PRINT_COLOR_BEGIN ;AN000;
WHITE_BOX DB 0,0,0,0 ; Print boxes for APA mode ;AN000;
BLACK_BOX DB ?,?,?,? ; NOTE: 1 print box = 1 screen pixel ;AN000;
; only BOX_W bytes are used out of these 2 ;AN000;
; boxes. ;AN000;
;AN000;
REQ_BAND_MASK DB ? ; Mask = "All color bands needed for the current;AN000;
; print line". ;AN000;
;AN000;
PRINT_COLOR_BEGIN: ;AN000;
.IF <MODE_TYPE EQ TXT> ;AN000;
.THEN ;AN000;
;-------------------------------------------------------------------------------;AN000;
; The screen is in a text mode: ;AN000;
;-------------------------------------------------------------------------------;AN000;
CALL PRINT_COLOR_TXT ; Print a text screen on a color printer;AN000;
.ELSE ;AN000;
;-------------------------------------------------------------------------------;AN000;
; The screen is in All Points Addressable mode: ;AN000;
; Locate and extract printer DISPLAYMODE information from ;AN000;
; the shared data area. ;AN000;
;-------------------------------------------------------------------------------;AN000;
CALL LOC_MODE_PRT_INFO ; Get printer info related to curr. mode;AN000;
; ;AN000;
;-------Test if DISPLAYMODE info record was found: ;AN000;
.IF <ERROR_CODE EQ DISPLAYMODE_INFO_NOT_FOUND> ;AN000;
.THEN ;AN000;
MOV ERROR_CODE,UNABLE_TO_PRINT ; IF no record found, ;AN000;
JMP SHORT PRINT_COLOR_END ; then, return error code ;AN000;
.ENDIF ; and quit procedure ;AN000;
; ;AN000;
;-------Get the box size from the DISPLAYMODE info record: ;AN000;
MOV BX,CUR_MODE_PTR ; BX := Offset current DISPLAYMODE info.;AN000;
MOV AH,[BX].BOX_WIDTH ; Take local copy of the box size. ;AN000;
MOV BOX_W,AH ; in BOX_W and BOX_H ;AN000;
MOV AL,[BX].BOX_HEIGHT ;AN000;
MOV BOX_H,AL ;AN000;
; ;AN000;
;-------Verify if the box size obtained from DISPLAYMODE info. is valid ;AN000;
.IF <ZERO AL> OR ; IF height of the box is 0 ;AN000;
.IF <ZERO AH> ; OR width of the box is 0 ;AN000;
.THEN ; THEN we can't print: ;AN000;
MOV ERROR_CODE,UNABLE_TO_PRINT ; return error code ;AN000;
JMP SHORT PRINT_COLOR_END ; and quit ;AN000;
.ENDIF ;AN000;
; ;AN000;
;-------Get the Print Orientation from the DISPLAYMODE info record ;AN000;
.IF <[BX].PRINT_OPTIONS EQ ROTATE>; If printing sideways ;AN000;
.THEN ; then: ;AN000;
MOV ROTATE_SW,ON ; Rotate switch := "ON" ;AN000;
.ENDIF ;AN000;
CALL PRINT_COLOR_APA ; Print APA screen on a color printer ;AN000;
.ENDIF ;AN000;
PRINT_COLOR_END: ;AN000;
RET ;AN000;
PRINT_COLOR ENDP ;AN000;
PAGE ;AN000;
;===============================================================================;AN000;
; ;AN000;
; PRINT_COLOR_TXT: PRINT A TEXT MODE SCREEN ON A COLOR PRINTER ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; INPUT: BP = Offset of the shared data area ;AN000;
; XLT_TAB = Color translation table ;AN000;
; SCREEN_WIDTH = Maximum length of Screen scan line. ;AN000;
; SCREEN_HEIGHT = Number of SCAN LINES on the screen ;AN000;
; ;AN000;
; OUTPUT: PRINTER ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; DESCRIPTION: The screen is read and printed line by line; character by ;AN000;
; character. ;AN000;
; Each line is first scanned in order to determine what colors are present on ;AN000;
; it and what printer bands will be needed to approximate these colors. ;AN000;
; ;AN000;
; For each printer color band needed for the current line, this screen line ;AN000;
; is READ AGAIN character by character; If the color of the ;AN000;
; current character must use the current color band to be ;AN000;
; approximated; then, the character is printed. ;AN000;
; ;AN000;
; ;AN000;
; LOGIC : ;AN000;
; ;AN000;
; Save current coordinates of the cursor. ;AN000;
; Initialize the cursor to the first character to be read (Top-left of screen) ;AN000;
; FOR each row on the screen (SCREEN_HEIGHT) ;AN000;
; BEGIN ;AN000;
; CALL SCAN_FOR_BANDS_TXT(CUR_ROW,CUR_COLUMN,REQ_BAND_MASK) ;AN000;
; CUR_BAND_MASK := 01H ;AN000;
; IF REQ_BAND_MASK <> 0 THEN ;AN000;
; DO 8 TIMES ;AN000;
; IF (REQ_BAND_MASK AND CUR_BAND_MASK)=1 THEN ;AN000;
; CALL PRINT_BAND_TXT(CUR_ROW,CUR_COLUMN,CUR_BAND_MASK) ;AN000;
; CALL PRINT_BYTE(CARRIAGE_RETURN) ;AN000;
; ENDIF ;AN000;
; Shift CUR_BAND_MASK one bit left ;AN000;
; ENDDO ;AN000;
; CALL PRINT_BYTE(LINE_FEED) ;AN000;
; ENDIF ;AN000;
; CUR_COLUMN := 0 ; Get next row coordinates ;AN000;
; CUR_ROW := CUR_ROW + 1 ;AN000;
; END ; FOR each row on the screen ;AN000;
; Restore initial coordinates of the cursor ;AN000;
; ;AN000;
PRINT_COLOR_TXT PROC ;AN000;
PUSH BX ;AN000;
PUSH CX ;AN000;
PUSH DX ;AN000;
; ;AN000;
;-------Save coordinates of the cursor on the stack: ;AN000;
MOV AH,READ_CURSOR_CALL ; Read position of the cursor on the screen;AN000;
MOV BH,CUR_PAGE ; for the current page ;AN000;
INT 10H ; Call BIOS ;AN000;
PUSH DX ; DH := Row number, DL := Column number ;AN000;
; CX := Top line and bottom line for cursor;AN000;
; (not needed) ;AN000;
; ;AN000;
;-------Initialize the cursor to the first character to be read ;AN000;
MOV CUR_ROW,0 ; cursor = position (0,0) on the screen ;AN000;
MOV CUR_COLUMN,0 ; (top-left corner) ;AN000;
CALL SET_CURSOR ;AN000;
;AN000;
MOV CX,SCREEN_HEIGHT ; CX := Number of rows on the screen ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; FOR EACH ROW ON THE SCREEN: ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
PRINT_1_TEXT_LINE: ;AN000;
CALL SCAN_FOR_BANDS_TXT ; REQ_BAND_MASK := Print bands needed ;AN000;
; for this line ;AN000;
MOV DL,01H ; DL :="Current Band printed" mask ;AN000;
;AN000;
; NOTE: The COLORSELECT records are stored sequentially in the ;AN000;
; Shared Data area. The band mask 00000001 corresponds to the first ;AN000;
; record, 00000010 to the second, etc. ;AN000;
; The COLORSELECT record indicates: "How to select the color band" ;AN000;
; on the printer (It contains the bytes that must be sent to the printer;AN000;
;AN000;
MOV BX,DS:[BP].COLORSELECT_PTR; BX := relative offset of COLORSELECT;AN000;
ADD BX,BP ; BX := absolute offset of COLORSELECT ;AN000;
PUSH CX ; Save row counter ;AN000;
MOV CX,8 ; For up to the maximum number of print ;AN000;
; bands with this printer ;AN000;
;-----------------------------------------------------------------------;AN000;
; ;AN000;
; FOR each Color Band available with the ribbon installed on the printer;AN000;
; ;AN000;
;-----------------------------------------------------------------------;AN000;
PRINT_1_COLOR_BAND_TXT: ; Do one pass of the printer head: ;AN000;
.IF <BIT REQ_BAND_MASK AND DL> ; IF this color band is needed ;AN000;
.THEN ; by any character on the line ;AN000;
CALL SET_COLOR_BAND ; then, select the color band ;AN000;
CALL PRINT_BAND_TXT ; and do one Print Pass for it. ;AN000;
.IF <BIT ERROR_CODE NZ PRINTER_ERROR> ;AN000;
.THEN ; A printer error occurred: ;AN000;
POP CX ; Restore the line counter ;AN000;
JMP SHORT PRINT_COLOR_TXT_END ; and quit. ;AN000;
.ENDIF ;AN000;
MOV AL,CR ; Print a carriage return ;AN000;
CALL PRINT_BYTE ;AN000;
.IF C ;AN000;
.THEN ; A printer error occurred: ;AN000;
POP CX ; Restore the line counter ;AN000;
JMP SHORT PRINT_COLOR_TXT_END ; and quit. ;AN000;
.ENDIF ; ENDIF printer error ;AN000;
.ENDIF ; ENDIF this color band is needed ;AN000;
SHL DL,1 ; Get next Color Band mask ;AN000;
; [BX] := Next COLORSELECT record: ;AN000;
MOV AL,[BX].NUM_SELECT_ESC ; skip the escape bytes ;AN000;
XOR AH,AH ; ;AN000;
ADD BX,AX ; ;AN000;
INC BX ; skip the NUM_SELECT_ESC field ;AN000;
LOOP PRINT_1_COLOR_BAND_TXT ;AN000;
POP CX ; Restore row counter ;AN000;
; ;AN000;
;-----Print a line feed: ;AN000;
MOV AL,LF ;AN000;
CALL PRINT_BYTE ; Send the LF ;AN000;
JC PRINT_COLOR_TXT_END ; If printer error, quit ;AN000;
; ;AN000;
;-------Get coordinates of the first character in the next scan line: ;AN000;
INC CUR_ROW ; CUR_ROW + 1 ;AN000;
MOV CUR_COLUMN,0 ; CUR_COLUMN := 0 ;AN000;
; ;AN000;
;-------Point CURSOR to first character in the next scan line: ;AN000;
CALL SET_CURSOR ;AN000;
;AN000;
LOOP PRINT_1_TEXT_LINE ; Print next scan line ;AN000;
;AN000;
; ;AN000;
;-------Restore CURSOR to its original location (saved on the stack) ;AN000;
PRINT_COLOR_TXT_END: ;AN000;
POP DX ; DH := Row number, DL := Column number ;AN000;
MOV CL,DH ;AN000;
MOV CUR_ROW,CX ; CUR_ROW := Original row number ;AN000;
MOV CL,DL ;AN000;
MOV CUR_COLUMN,CX ; CUR_COLUMN := Original column number ;AN000;
CALL SET_CURSOR ; Set the cursor back there ;AN000;
;AN000;
POP DX ;AN000;
POP CX ;AN000;
POP BX ;AN000;
RET ;AN000;
PRINT_COLOR_TXT ENDP ;AN000;
PAGE ;AN000;
;===============================================================================;AN000;
; ;AN000;
; SCAN_FOR_BANDS_TEXT: DETERMINE WHAT PRINTER COLOR BANDS ARE NEEDED FOR ;AN000;
; PRINTING THE COLORS ON THE CURRENT SCREEN LINE. ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; INPUT: CUR_ROW = row to start scanning ;AN000;
; CUR_COLUMN = column to start scanning ;AN000;
; ROTATE_SW = ON if printing is sideways ;AN000;
; ;AN000;
; OUTPUT: REQ_BAND_MASK ;AN000;
; ;AN000;
; ;AN000;
; DATA STRUCTURE REFERENCED: ;AN000;
; XLT_TAB = Color translation table ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; DESCRIPTION: Read all characters on the current line from left to right. ;AN000;
; For each character, extract its band mask from the color translation table. ;AN000;
; Add the band mask required for this character to the "Required Bands" mask. ;AN000;
; ;AN000;
; LOGIC : ;AN000;
; Save current coordinates ;AN000;
; DO (SCREEN_WIDTH) TIMES ;AN000;
; Read a character ;AN000;
; Get its Band Mask from the color translation table in AL ;AN000;
; OR REQ_BAND_MASK,AL ; Add its band mask to the "Required bands" mask;AN000;
; ; Get coordinates of the next character: ;AN000;
; INC CUR_COLUMN ;AN000;
; Restore initial coordinates ;AN000;
; ;AN000;
SCAN_FOR_BANDS_TXT PROC NEAR ;AN000;
PUSH CUR_ROW ; Save coordinates ;AN000;
PUSH CUR_COLUMN ;AN000;
PUSH AX ;AN000;
PUSH BX ;AN000;
PUSH CX ;AN000;
;AN000;
MOV REQ_BAND_MASK,0 ; No Color bands needed so far... ;AN000;
MOV CX,SCREEN_WIDTH ; For each character on the screen row ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; FOR each character on the current scan line: ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
SCAN_1_CHAR: ;AN000;
; ;AN000;
;-------Read the character at the current cursor position ;AN000;
CALL SET_CURSOR ; Set cursor at character to be read ;AN000;
MOV AH,READ_CHAR_CALL ; Read one character ;AN000;
MOV BH,CUR_PAGE ; at CUR_PAGE, CUR_COLUMN and CUR_ROW ;AN000;
INT 10H ; Call BIOS ;AN000;
; AL:=Character read, AH:=Byte attribute;AN000;
AND AH,00001111B ; AH := Foreground color attribute ;AN000;
XCHG AL,AH ; AL := AH, used as index in the XLT_TAB;AN000;
MOV BX,OFFSET XLT_TAB ; BX := Offset of translation table ;AN000;
XLAT XLT_TAB ; AL = Band mask ;AN000;
; ;AN000;
;-------Obtain what Print bands are required to print the color of this char: ;AN000;
OR REQ_BAND_MASK,AL ;AN000;
;AN000;
INC CUR_COLUMN ; Get coordinates of next character ;AN000;
LOOP SCAN_1_CHAR ; Scan next character ;AN000;
;AN000;
POP CX ;AN000;
POP BX ;AN000;
POP AX ;AN000;
POP CUR_COLUMN ; Restore initial coordinates ;AN000;
POP CUR_ROW ;AN000;
RET ;AN000;
SCAN_FOR_BANDS_TXT ENDP ;AN000;
PAGE ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AN000;
;; ;AN000;
;; PRINT_BAND_TXT: PRINT ALL CHARACTERS ON THE CURRENT LINE THAT ARE THE SAME ;AN000;
;; COLOR AS THE CURRENT PRINT BAND. ;AN000;
;; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; INPUT: CUR_ROW, ;AN000;
; CUR_COLUMN : Coordinates of the first character to be read in ;AN000;
; the current scan line. ;AN000;
; DL : Band mask indicating what print band to use ;AN000;
; for this print pass. ;AN000;
; SCAN_LINE_LENGTH: Length of the current scan line. ;AN000;
; ;AN000;
; OUTPUT: PRINTER ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; LOGIC: ;AN000;
; DO (SCAN_LINE_LENGTH) TIMES ;AN000;
; CALL BIOS INT 10H Read Character - returns CHAR, COLOR_NUM ;AN000;
; IF (CUR_BAND_MASK AND XLAT_TAB[COLOR_NUM])=1 ;AN000;
; THEN IF Background color is same as Foreground color ;AN000;
; THEN ;AN000;
; CALL PRINT_BYTE(SOLID_BOX) ;AN000;
; ELSE ;AN000;
; CALL PRINT_BYTE(CHAR) ;AN000;
; ELSE ;AN000;
; CALL PRINT_BYTE(blank) ;AN000;
; Get coordinates of the next character ;AN000;
; ;AN000;
PRINT_BAND_TXT PROC ;AN000;
SOLID_BOX EQU 219 ; ASCII Code for printing a solid box ;AN000;
BLANK EQU 32 ; ASCII code for printing a space ;AN000;
PUSH CUR_COLUMN ; Save column number ;AN000;
PUSH AX ;AN000;
PUSH BX ;AN000;
PUSH CX ;AN000;
MOV CX,SCREEN_WIDTH ; CX := Number of character on one screen row ;AN000;
;===============================================================================;AN000;
; ;AN000;
; FOR each character on the current row: ;AN000;
; ;AN000;
;===============================================================================;AN000;
PRINT_1_CHAR: ;AN000;
; ;AN000;
;-------Read the character at the current cursor position ;AN000;
CALL SET_CURSOR ; Set cursor at character to be read ;AN000;
MOV AH,READ_CHAR_CALL ; Read one character ;AN000;
MOV BH,CUR_PAGE ; at CUR_PAGE, CUR_COLUMN and CUR_ROW ;AN000;
INT 10H ; Call BIOS ;AN000;
; AL:=Character read, AH:=Byte attribute;AN000;
MOV CUR_CHAR,AL ;AN000;
MOV DH,AH ; DH := Byte attribute ;AN000;
AND DH,11110000B ; DH := Background color ;AN000;
SHR DH,1 ; DH := Background color right justified;AN000;
SHR DH,1 ;AN000;
SHR DH,1 ;AN000;
SHR DH,1 ;AN000;
AND AH,00001111B ; AH := Foreground color right justified;AN000;
; ;AN000;
;-------Test if this character should be printed (need color of the current band;AN000;
MOV AL,AH ; AL:=color used as index in the XLT_TAB;AN000;
MOV BX,OFFSET XLT_TAB ; BX := Offset of translation table ;AN000;
XLAT XLT_TAB ; AL := Band mask (DL=current band mask);AN000;
.IF <BIT AL AND DL> ;If needs this band to print the color ;AN000;
.THEN ; of this character ;AN000;
.IF <AH EQ DH> ; then: when foreground = background ;AN000;
.THEN ; send a solid box ;AN000;
MOV AL,SOLID_BOX ; ;AN000;
.ELSE ; when foreground <> background ;AN000;
MOV AL,CUR_CHAR ; send the character ;AN000;
.ENDIF ; Endif foreground = background ;AN000;
.ELSE ; else: send a blank ;AN000;
MOV AL,BLANK ; ;AN000;
.ENDIF ; Endif color band needed ;AN000;
CALL PRINT_BYTE ; Print the byte ;AN000;
JC PRINT_BAND_TXT_END ; If printer error occurred: QUIT ;AN000;
INC CUR_COLUMN ; Else, Get next column; keep going ;AN000;
LOOP PRINT_1_CHAR ;AN000;
;AN000;
PRINT_BAND_TXT_END: ;AN000;
POP CX ;AN000;
POP BX ;AN000;
POP AX ;AN000;
POP CUR_COLUMN ; Restore column number ;AN000;
RET ;AN000;
CUR_CHAR DB ? ;AN000;
PRINT_BAND_TXT ENDP ;AN000;
PAGE ;AN000;
;===============================================================================;AN000;
; ;AN000;
; PRINT_COLOR_APA: PRINT AN APA MODE SCREEN ON A COLOR PRINTER ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; INPUT: BP = Offset of the shared data area ;AN000;
; XLT_TAB = Color translation table ;AN000;
; CUR_MODE_PTR = Coordinates of current DISPLAYMODE info. ;AN000;
; ;AN000;
; OUTPUT: PRINTER ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; DESCRIPTION: Each pixel on the screen is printed as a "box" of dots on the ;AN000;
; printer. For a screen pixel of a given color, the best color approximation ;AN000;
; is chosen among the color available on the printer. ;AN000;
; ;AN000;
; The printer colors are obtained by selecting a print band. A few more printer ;AN000;
; color are obtained by printing twice (or more times) with different color ;AN000;
; bands. ;AN000;
; ;AN000;
; For example, let's say we have a ribbon on the printer with a YELLOW CYAN ;AN000;
; MAGENTA ribbon and we read a GREEN pixel on the screen. ;AN000;
; ;AN000;
; We first determine what "box" size will be used to represent this pixel. ;AN000;
; Let's say it's a 3x2 box (this is obtained from the DISPLAYMODE record) ;AN000;
; In all cases, we will print this pixel as a 3x2 box of printer dots. ;AN000;
; That is, we will print 6 dots on the printer for one on the screen. ;AN000;
; We do not use any kind of patterns (e,g,. printing only 2 dots out of 6) ;AN000;
; for printing on the color printer. A screen pixel is either printed ;AN000;
; as a "full" box of printer dots or not printed at all (e,g,. if it's white).;AN000;
; ;AN000;
; Now, from the COLORPRINT records, we know all the colors availables on the ;AN000;
; printer, and what print bands must be used (or overlaid) in order to ;AN000;
; obtain them. ;AN000;
; ;AN000;
; So, we consult these COLORPRINT records one by one comparing how close ;AN000;
; the color of each of them is to our GREEN pixel. (the colors for our pixel ;AN000;
; AND for the printer color are both indicated in terms of RGB values) ;AN000;
; WE PICK THE CLOSEST PRINTER COLOR. ;AN000;
; ;AN000;
; To conclude, our GREEN pixel will be printed by first selecting the YELLOW ;AN000;
; band, then sending to the printer a "box". Then, the BLUE band is selected ;AN000;
; and the "box" is sent again. ;AN000;
; ;AN000;
; This process is carried line by line. ;AN000;
; ;AN000;
; For each line, we first read each pixel to see what color bands are going ;AN000;
; to be needed for this line. ;AN000;
; ;AN000;
; Then, we loop for each band available on the printer. ;AN000;
; ;AN000;
; IF the current line needs the current printer band (i.e.,if any pixel on ;AN000;
; the line needs this color band in order to achieve its color. ;AN000;
; THEN, we select this color band (we know how to do it from the COLORSELECT ;AN000;
; record in the Shared Data area) ;AN000;
; AND we must read the line again; for each pixel that needs the current ;AN000;
; band a "box" is sent to the printer. ;AN000;
; ;AN000;
; LOGIC : ;AN000;
; CALL INIT_BLACK_BOX ; Initialize a print box ;AN000;
; CALL GET_SCREEN_INFO ;AN000;
; CALL SETUP_PRT ;AN000;
; DO (NB_SCAN_LINES) TIMES ;AN000;
; CALL DET_CUR_SCAN_LNE_LENGTH ;AN000;
; IF CUR_SCAN_LNE_LENGTH NE 0 THEN ;AN000;
; CALL SCAN_FOR_BANDS_APA(CUR_ROW,CUR_COLUMN,REQ_BAND_MASK) ;AN000;
; CUR_BAND_MASK := 01H ;AN000;
; IF REQ_BAND_MASK <> 0 THEN ;AN000;
; DO 8 TIMES ;AN000;
; IF (REQ_BAND_MASK AND CUR_BAND_MASK)=1 THEN ;AN000;
; CALL NEW_PRT_LINE ;AN000;
; CALL PRINT_BAND_APA(CUR_ROW,CUR_COLUMN,CUR_BAND_MASK) ;AN000;
; CALL PRINT_BYTE(CARRIAGE_RETURN) ;AN000;
; ENDIF ;AN000;
; Shift CUR_BAND_MASK one bit left ;AN000;
; ENDDO ;AN000;
; ENDIF ; Should make a print pass for this color band ;AN000;
; CALL PRINT_BYTE(LINE_FEED) ;AN000;
; ENDIF ; Current scan line is not empty ;AN000;
; IF rotated print THEN ;AN000;
; CUR_COLUMN := CUR_COLUMN - BOXES_PER_PRT_BUF ;AN000;
; CUR_ROW := SAVE_START_ROW ;AN000;
; ELSE ;AN000;
; CUR_ROW := CUR_ROW + BOXES_PER_PRT_BUF ;AN000;
; CUR_COLUMN := SAVE_START_COLUMN ;AN000;
; ENDIF ;AN000;
; ENDDO ; Number of Scan lines ;AN000;
; CALL RESTORE_PRT ;AN000;
; ;AN000;
PRINT_COLOR_APA PROC ;AN000;
PUSH AX ;AN000;
PUSH BX ;AN000;
PUSH CX ;AN000;
PUSH DX ;AN000;
;AN000;
;AN000;
;-------Initialize print box (A "box" represents one screen pel on the printer) ;AN000;
CALL INIT_BLACK_BOX ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; Determine where to start reading the screen: ;AN000;
; If printing sideways, start in LOW LEFT corner. ;AN000;
; If normal printing, start in TOP LEFT corner. ;AN000;
; Determine the maximum length for a scan line: ;AN000;
; If printing sideways, it is the height of the screen. ;AN000;
; For normal printing, it is the width of the screen. ;AN000;
; Determine the number of scan lines on the screen. ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
CALL GET_SCREEN_INFO ; Get info. about how to read the screen;AN000;
CALL SETUP_PRT ; Set up the printer (Line spacing, etc);AN000;
.IF <BIT ERROR_CODE NZ PRINTER_ERROR> ;AN000;
.THEN ; A printer error occurred: quit ;AN000;
JMP SHORT PRINT_COLOR_APA_END ; ;AN000;
.ENDIF ;AN000;
;AN000;
MOV CX,NB_SCAN_LINES ;AN000;
;---------------------------------------------------------------------------- ;AN000;
; ;AN000;
; FOR EACH SCAN LINE ON THE SCREEN (and each print line): ;AN000;
; ;AN000;
;---------------------------------------------------------------------------- ;AN000;
PRINT_SCAN_LINE: ;AN000;
CALL DET_CUR_SCAN_LNE_LENGTH ; Determine length of the scan line ;AN000;
.IF <CUR_SCAN_LNE_LENGTH NE 0> ; If line is not empty ;AN000;
.THEN ;AN000;
CALL SCAN_FOR_BANDS_APA ; REQ_BAND_MASK := Mask for what print;AN000;
; bands are needed. ;AN000;
MOV DL,01H ; DL := "Current Band to be printed" ;AN000;
MOV BX,DS:[BP].COLORSELECT_PTR; BX := Offset of COLORSELECT record;AN000;
ADD BX,BP ; ("How to select the color band");AN000;
PUSH CX ; Save scan line counter ;AN000;
MOV CX,8 ; For up to the maximum number of prin;AN000;
; bands with this printer ;AN000;
;---------------------------------------------------------------------;AN000;
; ;AN000;
; FOR each Color Band needed: ;AN000;
; ;AN000;
;---------------------------------------------------------------------;AN000;
PRINT_1_COLOR_BAND_APA: ; Only if this color band is needed: ;AN000;
.IF <BIT REQ_BAND_MASK AND DL> ; Do one pass of the printer head ;AN000;
.THEN ; ;AN000;
CALL SET_COLOR_BAND ; Select the color band on the printer;AN000;
CALL NEW_PRT_LINE ; Send escape sequence to the printer ;AN000;
; for starting a new graphics line ;AN000;
.IF <BIT ERROR_CODE NZ PRINTER_ERROR> ;AN000;
.THEN ; A printer error occurred: ;AN000;
POP CX ; Restore the line counter and ;AN000;
JMP SHORT PRINT_COLOR_APA_END ; return ;AN000;
.ENDIF ; Endif printer error occurred ;AN000;
;AN000;
CALL PRINT_BAND_APA ; Do one Print Pass for current band ;AN000;
MOV AL,CR ; Print a carriage return ;AN000;
CALL PRINT_BYTE ;AN000;
.IF C ; If a printer error occurred ;AN000;
.THEN ;AN000;
POP CX ; Restore the line counter and ;AN000;
JMP SHORT PRINT_COLOR_APA_END ; return ;AN000;
.ENDIF ; End if printer error occurred ;AN000;
.ENDIF ; End if this color band is needed ;AN000;
SHL DL,1 ; Get next Color Band mask ;AN000;
; Locate next COLORSELECT record: ;AN000;
MOV AL,[BX].NUM_SELECT_ESC; skip the escape bytes ;AN000;
XOR AH,AH ;AN000;
ADD BX,AX ;AN000;
INC BX ; skip the NUM_SELECT_ESC field ;AN000;
LOOP PRINT_1_COLOR_BAND_APA ;AN000;
POP CX ; Restore scan line counter ;AN000;
.ENDIF ; Scan line length <> 0 ;AN000;
; ;AN000;
;-----Print a line feed: ;AN000;
MOV AL,LF ;AN000;
CALL PRINT_BYTE ;AN000;
JC PRINT_COLOR_APA_END ; If a printer error occurred: quit ;AN000;
; ;AN000;
;-------Get coordinates of next scan line: ;AN000;
.IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
.THEN ; then: ;AN000;
MOV AL,NB_BOXES_PER_PRT_BUF; AX := Numbers of pels read on row ;AN000;
CBW ; ;AN000;
ADD CUR_COLUMN,AX ; CUR_COLUMN + Number of pels read ;AN000;
MOV AX,SCREEN_HEIGHT ; CUR_ROW := SCREEN_HEIGHT - 1 ;AN000;
DEC AX ; ;AN000;
MOV CUR_ROW,AX ; ;AN000;
.ELSE ; else, printing NOT rotated: ;AN000;
MOV AL,NB_BOXES_PER_PRT_BUF ; AX := Number of pels read on column ;AN000;
CBW ; ;AN000;
ADD CUR_ROW,AX ; CUR_ROW + Number of pels read ;AN000;
MOV CUR_COLUMN,0 ; CUR_COLUMN := 0 ;AN000;
.ENDIF ; End if printing sideways ;AN000;
LOOP PRINT_SCAN_LINE ; ;AN000;
;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; Restore the printer (send a Page Eject, etc.) ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
CALL RESTORE_PRT ;AN000;
PRINT_COLOR_APA_END: ;AN000;
POP DX ;AN000;
POP CX ;AN000;
POP BX ;AN000;
POP AX ;AN000;
RET ;AN000;
PRINT_COLOR_APA ENDP ;AN000;
PAGE ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AN000;
;; ;AN000;
;; ;AN000;
;; SCAN_FOR_BANDS_APA : DETERMINE WHAT PRINT BANDS ARE NEEDED FOR THE CURRENT ;AN000;
;; PRINT PASS. ;AN000;
;; ;AN000;
;;------------------------------------------------------------------------------;AN000;
; ;AN000;
; INPUT: CUR_ROW : row to start scanning (word) ;AN000;
; CUR_COLUMN : column to start scanning (word) ;AN000;
; CUR_SCAN_LNE_LENGTH : length of the current scan line (word) ;AN000;
; ROTATE_SW = ON if printing is sideways ;AN000;
; ;AN000;
; OUTPUT: REQ_BAND_MASK : band mask for required bands (byte) ;AN000;
; ;AN000;
;;------------------------------------------------------------------------------;AN000;
;; ;AN000;
;; Data Structures Referenced: ;AN000;
;; Shared Data Area ;AN000;
;; Print Info ;AN000;
;; Color Translate Table ;AN000;
;; ;AN000;
;; ;AN000;
;; Description: ;AN000;
;; Read all the dots required for one print line to determine ;AN000;
;; the print bands required. The print line corresponds to several ;AN000;
;; screen rows (or columns if rotated printing). The number of ;AN000;
;; rows / columns per print line is stored in NB_BOXES_PER_PRT_BUF. ;AN000;
;; The band information is obtained from the Color Translate Table. ;AN000;
;; ;AN000;
;; Called By: ;AN000;
;; PRINT_COLOR_APA ;AN000;
;; ;AN000;
;; External Calls: ;AN000;
;; READ_DOT, BIOS INT 10H ;AN000;
;; ;AN000;
;; Logic: ;AN000;
;; Save initial coordinates ;AN000;
;; SAVE_START_COLUMN := CUR_COLUMN ;AN000;
;; REQ_BAND_MASK := 00H ;AN000;
;; DO (SCAN_LINE_LENGTH) TIMES ;AN000;
;; Save coordinates of the "column" ;AN000;
;; DO (BOXES_PER_PRT_BUF) TIMES ;AN000;
;; CALL READ_DOT(IN CUR_ROW,CUR_COLUMN; OUT COLOR_NUM) ;AN000;
;; REQ_BAND_MASK := REQ_BAND_MASK OR COLOR_XLAT_TAB[BX] ;AN000;
;; IF rotated print THEN ;AN000;
;; Increment CUR_COLUMN ;AN000;
;; ELSE ;AN000;
;; Increment CUR_ROW ;AN000;
;; ENDIF ;AN000;
;; Restore coordinates of the "column" ;AN000;
;; ENDDO ;AN000;
;; IF rotated print THEN ;AN000;
;; Decrement CUR_ROW ;AN000;
;; ELSE ;AN000;
;; Increment CUR_COLUMN ;AN000;
;; ENDIF ;AN000;
;; ENDDO ;AN000;
;; Restore initial coordinates ;AN000;
;; RETURN ;AN000;
;; ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
SCAN_FOR_BANDS_APA PROC NEAR ;AN000;
PUSH CUR_ROW ;AN000;
PUSH CUR_COLUMN ;AN000;
PUSH AX ;AN000;
PUSH BX ;AN000;
PUSH CX ;AN000;
;AN000;
MOV REQ_BAND_MASK,0 ; No Color bands needed so far... ;AN000;
MOV BX,OFFSET XLT_TAB ; BX := Offset of translation table ;AN000;
MOV CX,CUR_SCAN_LNE_LENGTH ;AN000;
;===============================================================================;AN000;
; ;AN000;
; FOR each column on the current scan line (up to the last non=blank): ;AN000;
; ;AN000;
;===============================================================================;AN000;
SCAN_1_COLUMN: ;AN000;
PUSH CX ; Save column counter ;AN000;
PUSH CUR_ROW ; Save coordinates of the "column" ;AN000;
PUSH CUR_COLUMN ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; For each pixel within the current column of the scan line: ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
XOR CX,CX ; CX := Number of pixels to read ;AN000;
MOV CL,NB_BOXES_PER_PRT_BUF ; within the current "column" ;AN000;
SCAN_1_PIXEL: ;AN000;
CALL READ_DOT ; AL := Index into translation table ;AN000;
XLAT XLT_TAB ; AL := Band mask ;AN000;
OR REQ_BAND_MASK,AL ; Add bands required for this pixel ;AN000;
;AN000;
;-------Get coordinates of next pixel: ;AN000;
.IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
.THEN ; ;AN000;
INC CUR_COLUMN ; then, increment column number ;AN000;
.ELSE ; ;AN000;
INC CUR_ROW ; else, increment row number ;AN000;
.ENDIF ; ;AN000;
LOOP SCAN_1_PIXEL ;AN000;
POP CUR_COLUMN ; Restore coordinates of the "column" ;AN000;
POP CUR_ROW ; ;AN000;
POP CX ; Restore column counter ;AN000;
;AN000;
;AN000;
;-------Get coordinates of next "column": ;AN000;
.IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
.THEN ; ;AN000;
DEC CUR_ROW ; then, get row above on screen ;AN000;
.ELSE ; ;AN000;
INC CUR_COLUMN ; else, get column next right ;AN000;
.ENDIF ; ;AN000;
LOOP SCAN_1_COLUMN ;AN000;
;AN000;
POP CX ;AN000;
POP BX ;AN000;
POP AX ;AN000;
POP CUR_COLUMN ;AN000;
POP CUR_ROW ;AN000;
RET ;AN000;
SCAN_FOR_BANDS_APA ENDP ;AN000;
PAGE ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AN000;
;; ;AN000;
;; PRINT_BAND_APA : PRINT ALL DOTS ON CURRENT LINE THAT NEED THE CURRENT BAND ;AN000;
;; TO APPROXIMATE THEIR COLOR. ;AN000;
;; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; INPUT: CUR_ROW, ;AN000;
; CUR_COLUMN : Coordinates of the first pixel to be read in the ;AN000;
; current scan line. ;AN000;
; DL : Band mask indicating what print band to use ;AN000;
; for this print pass. ;AN000;
; CUR_SCAN_LNE_LENGTH: Length of the current scan line. ;AN000;
; ROTATE_SW = ON if printing is sideways ;AN000;
; ;AN000;
; OUTPUT: PRINTER ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
;; ;AN000;
;; Data Structures Referenced: ;AN000;
;; Shared Data Area ;AN000;
;; Print Info ;AN000;
;; Color Translate Table ;AN000;
;; ;AN000;
;; Description: ;AN000;
;; Print all dots on this print line which need the current ;AN000;
;; band. The print line corresponds to several ;AN000;
;; screen rows (or columns if rotated printing). The number of ;AN000;
;; rows / columns per print line is stored in NB_BOXES_PER_PRT_BUF. ;AN000;
;; The band information is obtained from the Color Translate Table. ;AN000;
;; ;AN000;
;; Called By: ;AN000;
;; PRINT_COLOR_APA ;AN000;
;; ;AN000;
;; External Calls: ;AN000;
;; READ_DOT, BIOS INT 10H, STORE_BOX, PRT_BUFFER, PRINT_BYTE ;AN000;
;; ;AN000;
;; Logic: ;AN000;
;; SAVE_START_ROW := CUR_ROW ;AN000;
;; SAVE_START_COLUMN := CUR_COLUMN ;AN000;
;; ;AN000;
;; CALL SET_COLOR_BAND ; Select the color for this print pass ;AN000;
;; DO (SCAN_LINE_LENGTH) TIMES ;AN000;
;; Save coordinates of the "column" ;AN000;
;; Clear the print buffer ;AN000;
;; DO (BOXES_PER_PRT_BUF) TIMES ;AN000;
;; CALL READ_DOT(CUR_ROW,CUR_COLUMN,COLOR_NUM) ;AN000;
;; IF (CUR_BAND_MASK AND XLAT_TAB[COLOR_NUM])=1 THEN ;AN000;
;; CALL STORE_BOX(black box) ;AN000;
;; ELSE ;AN000;
;; CALL STORE_BOX(white box) ;AN000;
;; ENDIF ;AN000;
;; IF rotated print THEN ;AN000;
;; Decrement CUR_COLUMN ;AN000;
;; ELSE ;AN000;
;; Increment CUR_ROW ;AN000;
;; ENDIF ;AN000;
;; ENDDO ;AN000;
;; CALL PRINT_BUFFER ;AN000;
;; Restore coordinates of the "column" ;AN000;
;; ; Get coordinates of the next "column"; ;AN000;
;; IF rotated print THEN ;AN000;
;; Decrement CUR_ROW ;AN000;
;; CUR_COLUMN := SAVE_START_COLUMN ;AN000;
;; ELSE ;AN000;
;; Increment CUR_COLUMN ;AN000;
;; CUR_ROW := SAVE_START_ROW ;AN000;
;; ENDIF ;AN000;
;; ENDDO ;AN000;
;; RETURN ;AN000;
;; ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AN000;
PRINT_BAND_APA PROC NEAR ;AN000;
PUSH CUR_ROW ; Save coordinates ;AN000;
PUSH CUR_COLUMN ;AN000;
PUSH AX ;AN000;
PUSH BX ;AN000;
PUSH CX ;AN000;
PUSH SI ;AN000;
PUSH DI ;AN000;
;AN000;
MOV BX,OFFSET XLT_TAB ; BX := Offset of translation table ;AN000;
MOV CX,CUR_SCAN_LNE_LENGTH ;AN000;
;===============================================================================;AN000;
; ;AN000;
; FOR each column on the current scan line (up to the last non=blank): ;AN000;
; (One "column" contains the number of pixels required to fill the Print buffer);AN000;
; ;AN000;
;===============================================================================;AN000;
PRINT_1_COLUMN: ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; Clear the print buffer "PRT_BUF" ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
XOR DI,DI ; DI := Number of bytes cleared in the buffer ;AN000;
XOR AX,AX ;AN000;
MOV AL,BOX_W ; AX := Number of bytes in the print buffer ;AN000;
CLEAR_BUF: ; For each byte in the PRT_BUF: ;AN000;
MOV PRT_BUF[DI],0 ; Initialize byte to blanks ;AN000;
INC DI ; One more has been cleared ;AN000;
CMP DI,AX ; All bytes cleared ? ;AN000;
JL CLEAR_BUF ; No, clear next one. ;AN000;
;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; Fill up the print buffer "PRT_BUF" ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
PUSH CX ; Save column counter ;AN000;
XOR CX,CX ; CX := Number of pixels to read ;AN000;
MOV CL,NB_BOXES_PER_PRT_BUF ; within the current "column" ;AN000;
; of the scan line ;AN000;
PUSH CUR_ROW ; Save coordinates of the "column" ;AN000;
PUSH CUR_COLUMN ;AN000;
; ;AN000;
; For each pixel within the current column of the scan line: ;AN000;
STORE_1_PIXEL: ;AN000;
CALL READ_DOT ; AL := Index into translation table ;AN000;
XLAT XLT_TAB ; AL := Band mask ;AN000;
.IF <BIT AL AND DL> ; If color of the current pixel needs ;AN000;
.THEN ; the current printer band ;AN000;
MOV SI,OFFSET BLACK_BOX ; then, store a box in the ;AN000;
CALL STORE_BOX ; PRT_BUF ;AN000;
.ELSE ; ;AN000;
MOV SI,OFFSET WHITE_BOX ; else, store an empty box ;AN000;
CALL STORE_BOX ; in the PRT_BUF ;AN000;
.ENDIF ;AN000;
; ;AN000;
;-------Get coordinates of next pixel: ;AN000;
.IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
.THEN ; ;AN000;
INC CUR_COLUMN ; then, increment column number ;AN000;
.ELSE ; ;AN000;
INC CUR_ROW ; else, increment row number ;AN000;
.ENDIF ; ;AN000;
LOOP STORE_1_PIXEL ;AN000;
;AN000;
POP CUR_COLUMN ; Restore coordinates of the "column" ;AN000;
POP CUR_ROW ; ;AN000;
POP CX ; Restore column counter ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; Print the PRT_BUF: ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
CALL PRINT_BUFFER ;AN000;
.IF <BIT ERROR_CODE NZ PRINTER_ERROR> ;AN000;
.THEN ; A printer error occurred: QUIT ;AN000;
JMP SHORT PRINT_BAND_APA_END ; ;AN000;
.ENDIF ;AN000;
;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; Get coordinates of next "column": ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
.IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
.THEN ; ;AN000;
DEC CUR_ROW ; then, get row above on screen ;AN000;
.ELSE ; ;AN000;
INC CUR_COLUMN ; else, get column next right ;AN000;
.ENDIF ; ;AN000;
LOOP PRINT_1_COLUMN ;AN000;
;AN000;
PRINT_BAND_APA_END: ;AN000;
POP DI ;AN000;
POP SI ;AN000;
POP CX ;AN000;
POP BX ;AN000;
POP AX ;AN000;
POP CUR_COLUMN ; Restore initial coordinates ;AN000;
POP CUR_ROW ;AN000;
RET ;AN000;
PRINT_BAND_APA ENDP ;AN000;
PAGE ;AN000;
;===============================================================================;AN000;
; ;AN000;
; SET_CURSOR : SET THE CURSOR TO CUR_ROW, CUR_COLUMN AND CUR_PAGE ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; INPUT: CUR_ROW, ;AN000;
; CUR_COLUMN = Coordinates for the cursor (word) ;AN000;
; CUR_PAGE = Page for which to set the cursor (byte) ;AN000;
; ;AN000;
; OUTPUT: SCREEN ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
SET_CURSOR PROC NEAR ;AN000;
PUSH AX ;AN000;
PUSH BX ;AN000;
PUSH DX ;AN000;
MOV DH,BYTE PTR CUR_ROW ;AN000;
MOV DL,BYTE PTR CUR_COLUMN ;AN000;
MOV BH,CUR_PAGE ;AN000;
MOV AH,SET_CURSOR_CALL ; Set cursor request ;AN000;
INT 10H ; Call BIOS ;AN000;
POP DX ;AN000;
POP BX ;AN000;
POP AX ;AN000;
RET ;AN000;
SET_CURSOR ENDP ;AN000;
PAGE ;AN000;
;===============================================================================;AN000;
; ;AN000;
; SET_COLOR_BAND : SET THE PRINTER TO THE CURRENT COLOR BAND ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; INPUT: BX = Offset of current COLORSELECT record in the ;AN000;
; Shared data area. ;AN000;
; DS:[BP] = Offset of shared data area ;AN000;
; ;AN000;
; OUTPUT: PRINTER ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
SET_COLOR_BAND PROC NEAR ;AN000;
PUSH AX ;AN000;
PUSH BX ;AN000;
PUSH CX ;AN000;
;AN000;
;-------Send the escape sequence for selecting this color band to the printer: ;AN000;
XOR CX,CX ;AN000;
MOV CL,[BX].NUM_SELECT_ESC ; CX := Number of bytes to send ;AN000;
ADD BX,OFFSET SELECT_ESC ; BX := Offset of bytes to send ;AN000;
SEND_1_COLORSELECT_BYTE: ;AN000;
MOV AL,[BX] ; AL := Byte to send to printer ;AN000;
CALL PRINT_BYTE ; Send it ;AN000;
JC SET_COLOR_BAND_END ; If printer error: return ;AN000;
INC BX ; Get next byte ;AN000;
LOOP SEND_1_COLORSELECT_BYTE ;AN000;
;AN000;
SET_COLOR_BAND_END: ;AN000;
POP CX ;AN000;
POP BX ;AN000;
POP AX ;AN000;
RET ;AN000;
SET_COLOR_BAND ENDP ;AN000;
PAGE ;AN000;
;===============================================================================;AN000;
; ;AN000;
; INIT_BLACK_BOX: INIT. THE BOX FOR PRINTING APA MODE DOTS ON A COLOR PRINTER. ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; INPUT: BOX_W, ;AN000;
; BOX_H = Size of the print box for one pixel. ;AN000;
; ;AN000;
; OUTPUT: BLACK_BOX = A box for which all dots are on. ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; DESCRIPTION: Initialize the print box used to print a screen pixel. ;AN000;
; ;AN000;
; For example, ;AN000;
; with a size of 3x2 the BLACK_BOX will use 3 bytes: ;AN000;
; ;AN000;
; ;AN000;
; byte1 byte2 byte3 ;AN000;
; (column1) (column2) (column3) ;AN000;
; bit 7 -->0 0 0 ;AN000;
; 0 0 0 ;AN000;
; 0 0 0 ;AN000;
; 0 0 0 ;AN000;
; 0 0 0 ;AN000;
; 0 0 0 ;AN000;
; 1 1 1 ;AN000;
; bit 0 -->1 1 1 ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
INIT_BLACK_BOX PROC NEAR ;AN000;
PUSH AX ;AN000;
PUSH BX ;AN000;
PUSH CX ;AN000;
;AN000;
;-------Build one box column: ;AN000;
XOR CX,CX ;AN000;
MOV CL,BOX_H ; CX := Height in bits of the print box ;AN000;
XOR AL,AL ; AX := Bit mask for creating box column ;AN000;
.REPEAT ; For height of the box: ;AN000;
SHL AL,1 ; ;AN000;
OR AL,1 ; Insert one bit in the box column ;AN000;
.LOOP ;AN000;
;AN000;
;-------------------------------------------------------------------------------;AN000;
; ;AN000;
; AL now contains one box column. ;AN000;
; ;AN000;
;-------------------------------------------------------------------------------;AN000;
;AN000;
;-------Replicate this column over all columns of the box. ;AN000;
XOR BX,BX ; BX := Index into the BOX ;AN000;
INIT_1_BLACK_COLUMN: ;AN000;
MOV BLACK_BOX[BX],AL; Init current column to black box column ;AN000;
INC BX ; Get next column ;AN000;
CMP BL,BOX_W ;AN000;
JL INIT_1_BLACK_COLUMN ;AN000;
;AN000;
POP CX ;AN000;
POP BX ;AN000;
POP AX ;AN000;
RET ;AN000;
INIT_BLACK_BOX ENDP ;AN000;
INCLUDE GRCOMMON.ASM ;AN000;
LEN_OF_COLOR_MODULES EQU $-PRINT_COLOR ;AN000;
CODE ENDS ;AN000;
END ;AN000;