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