2025-04-27 07:49:33 -04:00

1128 lines
51 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;/*
; * 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;