From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/GRAPHICS/GRCOLPRT.ASM | 1122 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1122 insertions(+) create mode 100644 v4.0/src/CMD/GRAPHICS/GRCOLPRT.ASM (limited to 'v4.0/src/CMD/GRAPHICS/GRCOLPRT.ASM') diff --git a/v4.0/src/CMD/GRAPHICS/GRCOLPRT.ASM b/v4.0/src/CMD/GRAPHICS/GRCOLPRT.ASM new file mode 100644 index 0000000..0c1d0a2 --- /dev/null +++ b/v4.0/src/CMD/GRAPHICS/GRCOLPRT.ASM @@ -0,0 +1,1122 @@ + PAGE ,132 ;AN000; + TITLE DOS GRAPHICS Command - Color printing modules +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; +;; DOS - GRAPHICS Command +;; (c) Copyright 1988 Microsoft +;; ;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 ;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 ;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 OR ; IF height of the box is 0 ;AN000; + .IF ; 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 ; 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 ;AN000; + .THEN ; A printer error occurred: ;AN000; + POP CX ; Restore the line counter ;AN000; + JMP 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 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 ;If needs this band to print the color ;AN000; + .THEN ; of this character ;AN000; + .IF ; 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 ;AN000; + .THEN ; A printer error occurred: quit ;AN000; + JMP 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 ; 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 ; 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 ;AN000; + .THEN ; A printer error occurred: ;AN000; + POP CX ; Restore the line counter and ;AN000; + JMP 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 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 ; 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 ; 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 ; 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 ; 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 ; 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 ;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 ; 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; -- cgit v1.2.3