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