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