]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/GRAPHICS/GRCOLPRT.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / GRAPHICS / GRCOLPRT.ASM
1 PAGE ,132 ;AN000;
2 TITLE DOS GRAPHICS Command - Color printing modules
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
4 ;; DOS - GRAPHICS Command
5 ;; (c) Copyright 1988 Microsoft
6 ;; ;AN000;
7 ;; File Name: GRCOLPRT.ASM ;AN000;
8 ;; ---------- ;AN000;
9 ;; ;AN000;
10 ;; Description: ;AN000;
11 ;; ------------ ;AN000;
12 ;; This file contains the code for printing a screen (text and graphics) ;AN000;
13 ;; on a COLOR printer. ;AN000;
14 ;; ;AN000;
15 ;; Documentation Reference: ;AN000;
16 ;; ------------------------ ;AN000;
17 ;; OASIS High Level Design ;AN000;
18 ;; OASIS GRAPHICS I1 Overview ;AN000;
19 ;; ;AN000;
20 ;; Procedures Contained in This File: ;AN000;
21 ;; ---------------------------------- ;AN000;
22 ;; ;AN000;
23 ;; PRINT_COLOR ;AN000;
24 ;; SCAN_FOR_BANDS_APA ;AN000;
25 ;; SCAN_FOR_BANDS_TXT ;AN000;
26 ;; PRINT_BAND_APA ;AN000;
27 ;; PRINT_BAND_TXT ;AN000;
28 ;; SET_CURSOR ;AN000;
29 ;; SET_COLOR_BAND ;AN000;
30 ;; INIT_BLACK_BOX ;AN000;
31 ;; ;AN000;
32 ;; ;AN000;
33 ;; Include Files Required: ;AN000;
34 ;; ----------------------- ;AN000;
35 ;; ;AN000;
36 ;; GRCTRL.EXT - Externals for print screen control ;AN000;
37 ;; GRCTRL.STR - Structures and equates for print screen control ;AN000;
38 ;; GRPATTRN.STR - Structures for the printer patterns. ;AN000;
39 ;; ;AN000;
40 ;; GRSHAR.STR - Shared Data Area Structure ;AN000;
41 ;; ;AN000;
42 ;; STRUC.INC - Macros for using structured assembly language ;AN000;
43 ;; ;AN000;
44 ;; External Procedure References: ;AN000;
45 ;; ------------------------------ ;AN000;
46 ;; FROM FILE GRCTRL.ASM: ;AN000;
47 ;; PRT_SCR - Main module for printing the screen. ;AN000;
48 ;; TO FILE GRCOMMON.ASM ;AN000;
49 ;; Common modules - tools for printing a screen. ;AN000;
50 ;; ;AN000;
51 ;; Linkage Instructions: ;AN000;
52 ;; -------------------- ;AN000;
53 ;; Refer to GRAPHICS.ASM ;AN000;
54 ;; ;AN000;
55 ;; Change History: ;AN000;
56 ;; --------------- ;AN000;
57 ;; Date last updated 5/26/87. ;AN000;
58 ;; ;AN000;
59 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
60 PAGE ;AN000;
61 CODE SEGMENT PUBLIC 'CODE' ;AN000;
62 ASSUME CS:CODE,DS:CODE ;AN000;
63 ;AN000;
64 PUBLIC PRINT_MODULE_START ;; Color modules public ;AN000;
65 PUBLIC PRINT_COLOR ;; procedures ;AN000;
66 PUBLIC LEN_OF_COLOR_MODULES ;; ;AN000;
67 ;; ;AN000;
68 .XLIST ; ;AN000;
69 INCLUDE GRCTRL.STR ; Stuctures needed ;AN000;
70 INCLUDE GRSHAR.STR ; for both set of print modules ;AN000;
71 INCLUDE GRPATTRN.STR ; ;AN000;
72 ; ;AN000;
73 INCLUDE GRCTRL.EXT ; Externals from PRT_SCR control module ;AN000;
74 INCLUDE STRUC.INC ; ;AN000;
75 .LIST ; ;AN000;
76 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AN000;
77 ;; ;AN000;
78 ;; ;AN000;
79 ;; PRINT_COLOR : PRINT TEXT AND APA MODE SCREEN ON A COLOR PRINTER ;AN000;
80 ;; ;AN000;
81 ;-------------------------------------------------------------------------------;AN000;
82 ; ;AN000;
83 ; INPUT: BP = Offset of the shared data area ;AN000;
84 ; XLT_TAB = Color translation table ;AN000;
85 ; ;AN000;
86 ; OUTPUT: PRINTER ;AN000;
87 ; ;AN000;
88 ;-------------------------------------------------------------------------------;AN000;
89 ;; ;AN000;
90 ;; Description: ;AN000;
91 ;; Main control module for printing of text and graphics ;AN000;
92 ;; on color printers. ;AN000;
93 ;; ;AN000;
94 ;; Calls either the text or graphics mode routine. ;AN000;
95 ;; ;AN000;
96 ;; Called By: ;AN000;
97 ;; PRINT_SCREEN ;AN000;
98 ;; ;AN000;
99 ;; External Calls: ;AN000;
100 ;; LOC_MODE_PRT_INFO, PRINT_COLOR_APA, PRINT_COLOR_TXT ;AN000;
101 ;; ;AN000;
102 ;; Logic: ;AN000;
103 ;; IF MODE_TYPE = TXT ;AN000;
104 ;; THEN CALL PRINT_COLOR_TXT ;AN000;
105 ;; ELSE (MODE_TYPE = APA) ;AN000;
106 ;; CALL LOC_MODE_PRT_INFO ; Get DISPLAYMODE record from the SHARED AREA ;AN000;
107 ;; CALL PRINT_COLOR_APA ;AN000;
108 ;; RETURN ;AN000;
109 ;; ;AN000;
110 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
111 PRINT_MODULE_START LABEL BYTE ;AN000;
112 PRINT_COLOR PROC NEAR ;AN000;
113 JMP SHORT PRINT_COLOR_BEGIN ;AN000;
114 WHITE_BOX DB 0,0,0,0 ; Print boxes for APA mode ;AN000;
115 BLACK_BOX DB ?,?,?,? ; NOTE: 1 print box = 1 screen pixel ;AN000;
116 ; only BOX_W bytes are used out of these 2 ;AN000;
117 ; boxes. ;AN000;
118 ;AN000;
119 REQ_BAND_MASK DB ? ; Mask = "All color bands needed for the current;AN000;
120 ; print line". ;AN000;
121 ;AN000;
122 PRINT_COLOR_BEGIN: ;AN000;
123 .IF <MODE_TYPE EQ TXT> ;AN000;
124 .THEN ;AN000;
125 ;-------------------------------------------------------------------------------;AN000;
126 ; The screen is in a text mode: ;AN000;
127 ;-------------------------------------------------------------------------------;AN000;
128 CALL PRINT_COLOR_TXT ; Print a text screen on a color printer;AN000;
129 .ELSE ;AN000;
130 ;-------------------------------------------------------------------------------;AN000;
131 ; The screen is in All Points Addressable mode: ;AN000;
132 ; Locate and extract printer DISPLAYMODE information from ;AN000;
133 ; the shared data area. ;AN000;
134 ;-------------------------------------------------------------------------------;AN000;
135 CALL LOC_MODE_PRT_INFO ; Get printer info related to curr. mode;AN000;
136 ; ;AN000;
137 ;-------Test if DISPLAYMODE info record was found: ;AN000;
138 .IF <ERROR_CODE EQ DISPLAYMODE_INFO_NOT_FOUND> ;AN000;
139 .THEN ;AN000;
140 MOV ERROR_CODE,UNABLE_TO_PRINT ; IF no record found, ;AN000;
141 JMP SHORT PRINT_COLOR_END ; then, return error code ;AN000;
142 .ENDIF ; and quit procedure ;AN000;
143 ; ;AN000;
144 ;-------Get the box size from the DISPLAYMODE info record: ;AN000;
145 MOV BX,CUR_MODE_PTR ; BX := Offset current DISPLAYMODE info.;AN000;
146 MOV AH,[BX].BOX_WIDTH ; Take local copy of the box size. ;AN000;
147 MOV BOX_W,AH ; in BOX_W and BOX_H ;AN000;
148 MOV AL,[BX].BOX_HEIGHT ;AN000;
149 MOV BOX_H,AL ;AN000;
150 ; ;AN000;
151 ;-------Verify if the box size obtained from DISPLAYMODE info. is valid ;AN000;
152 .IF <ZERO AL> OR ; IF height of the box is 0 ;AN000;
153 .IF <ZERO AH> ; OR width of the box is 0 ;AN000;
154 .THEN ; THEN we can't print: ;AN000;
155 MOV ERROR_CODE,UNABLE_TO_PRINT ; return error code ;AN000;
156 JMP SHORT PRINT_COLOR_END ; and quit ;AN000;
157 .ENDIF ;AN000;
158 ; ;AN000;
159 ;-------Get the Print Orientation from the DISPLAYMODE info record ;AN000;
160 .IF <[BX].PRINT_OPTIONS EQ ROTATE>; If printing sideways ;AN000;
161 .THEN ; then: ;AN000;
162 MOV ROTATE_SW,ON ; Rotate switch := "ON" ;AN000;
163 .ENDIF ;AN000;
164 CALL PRINT_COLOR_APA ; Print APA screen on a color printer ;AN000;
165 .ENDIF ;AN000;
166 PRINT_COLOR_END: ;AN000;
167 RET ;AN000;
168 PRINT_COLOR ENDP ;AN000;
169 PAGE ;AN000;
170 ;===============================================================================;AN000;
171 ; ;AN000;
172 ; PRINT_COLOR_TXT: PRINT A TEXT MODE SCREEN ON A COLOR PRINTER ;AN000;
173 ; ;AN000;
174 ;-------------------------------------------------------------------------------;AN000;
175 ; ;AN000;
176 ; INPUT: BP = Offset of the shared data area ;AN000;
177 ; XLT_TAB = Color translation table ;AN000;
178 ; SCREEN_WIDTH = Maximum length of Screen scan line. ;AN000;
179 ; SCREEN_HEIGHT = Number of SCAN LINES on the screen ;AN000;
180 ; ;AN000;
181 ; OUTPUT: PRINTER ;AN000;
182 ; ;AN000;
183 ;-------------------------------------------------------------------------------;AN000;
184 ; ;AN000;
185 ; DESCRIPTION: The screen is read and printed line by line; character by ;AN000;
186 ; character. ;AN000;
187 ; Each line is first scanned in order to determine what colors are present on ;AN000;
188 ; it and what printer bands will be needed to approximate these colors. ;AN000;
189 ; ;AN000;
190 ; For each printer color band needed for the current line, this screen line ;AN000;
191 ; is READ AGAIN character by character; If the color of the ;AN000;
192 ; current character must use the current color band to be ;AN000;
193 ; approximated; then, the character is printed. ;AN000;
194 ; ;AN000;
195 ; ;AN000;
196 ; LOGIC : ;AN000;
197 ; ;AN000;
198 ; Save current coordinates of the cursor. ;AN000;
199 ; Initialize the cursor to the first character to be read (Top-left of screen) ;AN000;
200 ; FOR each row on the screen (SCREEN_HEIGHT) ;AN000;
201 ; BEGIN ;AN000;
202 ; CALL SCAN_FOR_BANDS_TXT(CUR_ROW,CUR_COLUMN,REQ_BAND_MASK) ;AN000;
203 ; CUR_BAND_MASK := 01H ;AN000;
204 ; IF REQ_BAND_MASK <> 0 THEN ;AN000;
205 ; DO 8 TIMES ;AN000;
206 ; IF (REQ_BAND_MASK AND CUR_BAND_MASK)=1 THEN ;AN000;
207 ; CALL PRINT_BAND_TXT(CUR_ROW,CUR_COLUMN,CUR_BAND_MASK) ;AN000;
208 ; CALL PRINT_BYTE(CARRIAGE_RETURN) ;AN000;
209 ; ENDIF ;AN000;
210 ; Shift CUR_BAND_MASK one bit left ;AN000;
211 ; ENDDO ;AN000;
212 ; CALL PRINT_BYTE(LINE_FEED) ;AN000;
213 ; ENDIF ;AN000;
214 ; CUR_COLUMN := 0 ; Get next row coordinates ;AN000;
215 ; CUR_ROW := CUR_ROW + 1 ;AN000;
216 ; END ; FOR each row on the screen ;AN000;
217 ; Restore initial coordinates of the cursor ;AN000;
218 ; ;AN000;
219 PRINT_COLOR_TXT PROC ;AN000;
220 PUSH BX ;AN000;
221 PUSH CX ;AN000;
222 PUSH DX ;AN000;
223 ; ;AN000;
224 ;-------Save coordinates of the cursor on the stack: ;AN000;
225 MOV AH,READ_CURSOR_CALL ; Read position of the cursor on the screen;AN000;
226 MOV BH,CUR_PAGE ; for the current page ;AN000;
227 INT 10H ; Call BIOS ;AN000;
228 PUSH DX ; DH := Row number, DL := Column number ;AN000;
229 ; CX := Top line and bottom line for cursor;AN000;
230 ; (not needed) ;AN000;
231 ; ;AN000;
232 ;-------Initialize the cursor to the first character to be read ;AN000;
233 MOV CUR_ROW,0 ; cursor = position (0,0) on the screen ;AN000;
234 MOV CUR_COLUMN,0 ; (top-left corner) ;AN000;
235 CALL SET_CURSOR ;AN000;
236 ;AN000;
237 MOV CX,SCREEN_HEIGHT ; CX := Number of rows on the screen ;AN000;
238 ;-------------------------------------------------------------------------------;AN000;
239 ; ;AN000;
240 ; FOR EACH ROW ON THE SCREEN: ;AN000;
241 ; ;AN000;
242 ;-------------------------------------------------------------------------------;AN000;
243 PRINT_1_TEXT_LINE: ;AN000;
244 CALL SCAN_FOR_BANDS_TXT ; REQ_BAND_MASK := Print bands needed ;AN000;
245 ; for this line ;AN000;
246 MOV DL,01H ; DL :="Current Band printed" mask ;AN000;
247 ;AN000;
248 ; NOTE: The COLORSELECT records are stored sequentially in the ;AN000;
249 ; Shared Data area. The band mask 00000001 corresponds to the first ;AN000;
250 ; record, 00000010 to the second, etc. ;AN000;
251 ; The COLORSELECT record indicates: "How to select the color band" ;AN000;
252 ; on the printer (It contains the bytes that must be sent to the printer;AN000;
253 ;AN000;
254 MOV BX,DS:[BP].COLORSELECT_PTR; BX := relative offset of COLORSELECT;AN000;
255 ADD BX,BP ; BX := absolute offset of COLORSELECT ;AN000;
256 PUSH CX ; Save row counter ;AN000;
257 MOV CX,8 ; For up to the maximum number of print ;AN000;
258 ; bands with this printer ;AN000;
259 ;-----------------------------------------------------------------------;AN000;
260 ; ;AN000;
261 ; FOR each Color Band available with the ribbon installed on the printer;AN000;
262 ; ;AN000;
263 ;-----------------------------------------------------------------------;AN000;
264 PRINT_1_COLOR_BAND_TXT: ; Do one pass of the printer head: ;AN000;
265 .IF <BIT REQ_BAND_MASK AND DL> ; IF this color band is needed ;AN000;
266 .THEN ; by any character on the line ;AN000;
267 CALL SET_COLOR_BAND ; then, select the color band ;AN000;
268 CALL PRINT_BAND_TXT ; and do one Print Pass for it. ;AN000;
269 .IF <BIT ERROR_CODE NZ PRINTER_ERROR> ;AN000;
270 .THEN ; A printer error occurred: ;AN000;
271 POP CX ; Restore the line counter ;AN000;
272 JMP PRINT_COLOR_TXT_END ; and quit. ;AN000;
273 .ENDIF ;AN000;
274 MOV AL,CR ; Print a carriage return ;AN000;
275 CALL PRINT_BYTE ;AN000;
276 .IF C ;AN000;
277 .THEN ; A printer error occurred: ;AN000;
278 POP CX ; Restore the line counter ;AN000;
279 JMP PRINT_COLOR_TXT_END ; and quit. ;AN000;
280 .ENDIF ; ENDIF printer error ;AN000;
281 .ENDIF ; ENDIF this color band is needed ;AN000;
282 SHL DL,1 ; Get next Color Band mask ;AN000;
283 ; [BX] := Next COLORSELECT record: ;AN000;
284 MOV AL,[BX].NUM_SELECT_ESC ; skip the escape bytes ;AN000;
285 XOR AH,AH ; ;AN000;
286 ADD BX,AX ; ;AN000;
287 INC BX ; skip the NUM_SELECT_ESC field ;AN000;
288 LOOP PRINT_1_COLOR_BAND_TXT ;AN000;
289 POP CX ; Restore row counter ;AN000;
290 ; ;AN000;
291 ;-----Print a line feed: ;AN000;
292 MOV AL,LF ;AN000;
293 CALL PRINT_BYTE ; Send the LF ;AN000;
294 JC PRINT_COLOR_TXT_END ; If printer error, quit ;AN000;
295 ; ;AN000;
296 ;-------Get coordinates of the first character in the next scan line: ;AN000;
297 INC CUR_ROW ; CUR_ROW + 1 ;AN000;
298 MOV CUR_COLUMN,0 ; CUR_COLUMN := 0 ;AN000;
299 ; ;AN000;
300 ;-------Point CURSOR to first character in the next scan line: ;AN000;
301 CALL SET_CURSOR ;AN000;
302 ;AN000;
303 LOOP PRINT_1_TEXT_LINE ; Print next scan line ;AN000;
304 ;AN000;
305 ; ;AN000;
306 ;-------Restore CURSOR to its original location (saved on the stack) ;AN000;
307 PRINT_COLOR_TXT_END: ;AN000;
308 POP DX ; DH := Row number, DL := Column number ;AN000;
309 MOV CL,DH ;AN000;
310 MOV CUR_ROW,CX ; CUR_ROW := Original row number ;AN000;
311 MOV CL,DL ;AN000;
312 MOV CUR_COLUMN,CX ; CUR_COLUMN := Original column number ;AN000;
313 CALL SET_CURSOR ; Set the cursor back there ;AN000;
314 ;AN000;
315 POP DX ;AN000;
316 POP CX ;AN000;
317 POP BX ;AN000;
318 RET ;AN000;
319 PRINT_COLOR_TXT ENDP ;AN000;
320 PAGE ;AN000;
321 ;===============================================================================;AN000;
322 ; ;AN000;
323 ; SCAN_FOR_BANDS_TEXT: DETERMINE WHAT PRINTER COLOR BANDS ARE NEEDED FOR ;AN000;
324 ; PRINTING THE COLORS ON THE CURRENT SCREEN LINE. ;AN000;
325 ; ;AN000;
326 ;-------------------------------------------------------------------------------;AN000;
327 ; ;AN000;
328 ; INPUT: CUR_ROW = row to start scanning ;AN000;
329 ; CUR_COLUMN = column to start scanning ;AN000;
330 ; ROTATE_SW = ON if printing is sideways ;AN000;
331 ; ;AN000;
332 ; OUTPUT: REQ_BAND_MASK ;AN000;
333 ; ;AN000;
334 ; ;AN000;
335 ; DATA STRUCTURE REFERENCED: ;AN000;
336 ; XLT_TAB = Color translation table ;AN000;
337 ; ;AN000;
338 ;-------------------------------------------------------------------------------;AN000;
339 ; ;AN000;
340 ; DESCRIPTION: Read all characters on the current line from left to right. ;AN000;
341 ; For each character, extract its band mask from the color translation table. ;AN000;
342 ; Add the band mask required for this character to the "Required Bands" mask. ;AN000;
343 ; ;AN000;
344 ; LOGIC : ;AN000;
345 ; Save current coordinates ;AN000;
346 ; DO (SCREEN_WIDTH) TIMES ;AN000;
347 ; Read a character ;AN000;
348 ; Get its Band Mask from the color translation table in AL ;AN000;
349 ; OR REQ_BAND_MASK,AL ; Add its band mask to the "Required bands" mask;AN000;
350 ; ; Get coordinates of the next character: ;AN000;
351 ; INC CUR_COLUMN ;AN000;
352 ; Restore initial coordinates ;AN000;
353 ; ;AN000;
354 SCAN_FOR_BANDS_TXT PROC NEAR ;AN000;
355 PUSH CUR_ROW ; Save coordinates ;AN000;
356 PUSH CUR_COLUMN ;AN000;
357 PUSH AX ;AN000;
358 PUSH BX ;AN000;
359 PUSH CX ;AN000;
360 ;AN000;
361 MOV REQ_BAND_MASK,0 ; No Color bands needed so far... ;AN000;
362 MOV CX,SCREEN_WIDTH ; For each character on the screen row ;AN000;
363 ;-------------------------------------------------------------------------------;AN000;
364 ; ;AN000;
365 ; FOR each character on the current scan line: ;AN000;
366 ; ;AN000;
367 ;-------------------------------------------------------------------------------;AN000;
368 SCAN_1_CHAR: ;AN000;
369 ; ;AN000;
370 ;-------Read the character at the current cursor position ;AN000;
371 CALL SET_CURSOR ; Set cursor at character to be read ;AN000;
372 MOV AH,READ_CHAR_CALL ; Read one character ;AN000;
373 MOV BH,CUR_PAGE ; at CUR_PAGE, CUR_COLUMN and CUR_ROW ;AN000;
374 INT 10H ; Call BIOS ;AN000;
375 ; AL:=Character read, AH:=Byte attribute;AN000;
376 AND AH,00001111B ; AH := Foreground color attribute ;AN000;
377 XCHG AL,AH ; AL := AH, used as index in the XLT_TAB;AN000;
378 MOV BX,OFFSET XLT_TAB ; BX := Offset of translation table ;AN000;
379 XLAT XLT_TAB ; AL = Band mask ;AN000;
380 ; ;AN000;
381 ;-------Obtain what Print bands are required to print the color of this char: ;AN000;
382 OR REQ_BAND_MASK,AL ;AN000;
383 ;AN000;
384 INC CUR_COLUMN ; Get coordinates of next character ;AN000;
385 LOOP SCAN_1_CHAR ; Scan next character ;AN000;
386 ;AN000;
387 POP CX ;AN000;
388 POP BX ;AN000;
389 POP AX ;AN000;
390 POP CUR_COLUMN ; Restore initial coordinates ;AN000;
391 POP CUR_ROW ;AN000;
392 RET ;AN000;
393 SCAN_FOR_BANDS_TXT ENDP ;AN000;
394 PAGE ;AN000;
395 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AN000;
396 ;; ;AN000;
397 ;; PRINT_BAND_TXT: PRINT ALL CHARACTERS ON THE CURRENT LINE THAT ARE THE SAME ;AN000;
398 ;; COLOR AS THE CURRENT PRINT BAND. ;AN000;
399 ;; ;AN000;
400 ;-------------------------------------------------------------------------------;AN000;
401 ; ;AN000;
402 ; INPUT: CUR_ROW, ;AN000;
403 ; CUR_COLUMN : Coordinates of the first character to be read in ;AN000;
404 ; the current scan line. ;AN000;
405 ; DL : Band mask indicating what print band to use ;AN000;
406 ; for this print pass. ;AN000;
407 ; SCAN_LINE_LENGTH: Length of the current scan line. ;AN000;
408 ; ;AN000;
409 ; OUTPUT: PRINTER ;AN000;
410 ; ;AN000;
411 ;-------------------------------------------------------------------------------;AN000;
412 ; LOGIC: ;AN000;
413 ; DO (SCAN_LINE_LENGTH) TIMES ;AN000;
414 ; CALL BIOS INT 10H Read Character - returns CHAR, COLOR_NUM ;AN000;
415 ; IF (CUR_BAND_MASK AND XLAT_TAB[COLOR_NUM])=1 ;AN000;
416 ; THEN IF Background color is same as Foreground color ;AN000;
417 ; THEN ;AN000;
418 ; CALL PRINT_BYTE(SOLID_BOX) ;AN000;
419 ; ELSE ;AN000;
420 ; CALL PRINT_BYTE(CHAR) ;AN000;
421 ; ELSE ;AN000;
422 ; CALL PRINT_BYTE(blank) ;AN000;
423 ; Get coordinates of the next character ;AN000;
424 ; ;AN000;
425 PRINT_BAND_TXT PROC ;AN000;
426 SOLID_BOX EQU 219 ; ASCII Code for printing a solid box ;AN000;
427 BLANK EQU 32 ; ASCII code for printing a space ;AN000;
428 PUSH CUR_COLUMN ; Save column number ;AN000;
429 PUSH AX ;AN000;
430 PUSH BX ;AN000;
431 PUSH CX ;AN000;
432 MOV CX,SCREEN_WIDTH ; CX := Number of character on one screen row ;AN000;
433 ;===============================================================================;AN000;
434 ; ;AN000;
435 ; FOR each character on the current row: ;AN000;
436 ; ;AN000;
437 ;===============================================================================;AN000;
438 PRINT_1_CHAR: ;AN000;
439 ; ;AN000;
440 ;-------Read the character at the current cursor position ;AN000;
441 CALL SET_CURSOR ; Set cursor at character to be read ;AN000;
442 MOV AH,READ_CHAR_CALL ; Read one character ;AN000;
443 MOV BH,CUR_PAGE ; at CUR_PAGE, CUR_COLUMN and CUR_ROW ;AN000;
444 INT 10H ; Call BIOS ;AN000;
445 ; AL:=Character read, AH:=Byte attribute;AN000;
446 MOV CUR_CHAR,AL ;AN000;
447 MOV DH,AH ; DH := Byte attribute ;AN000;
448 AND DH,11110000B ; DH := Background color ;AN000;
449 SHR DH,1 ; DH := Background color right justified;AN000;
450 SHR DH,1 ;AN000;
451 SHR DH,1 ;AN000;
452 SHR DH,1 ;AN000;
453 AND AH,00001111B ; AH := Foreground color right justified;AN000;
454 ; ;AN000;
455 ;-------Test if this character should be printed (need color of the current band;AN000;
456 MOV AL,AH ; AL:=color used as index in the XLT_TAB;AN000;
457 MOV BX,OFFSET XLT_TAB ; BX := Offset of translation table ;AN000;
458 XLAT XLT_TAB ; AL := Band mask (DL=current band mask);AN000;
459 .IF <BIT AL AND DL> ;If needs this band to print the color ;AN000;
460 .THEN ; of this character ;AN000;
461 .IF <AH EQ DH> ; then: when foreground = background ;AN000;
462 .THEN ; send a solid box ;AN000;
463 MOV AL,SOLID_BOX ; ;AN000;
464 .ELSE ; when foreground <> background ;AN000;
465 MOV AL,CUR_CHAR ; send the character ;AN000;
466 .ENDIF ; Endif foreground = background ;AN000;
467 .ELSE ; else: send a blank ;AN000;
468 MOV AL,BLANK ; ;AN000;
469 .ENDIF ; Endif color band needed ;AN000;
470 CALL PRINT_BYTE ; Print the byte ;AN000;
471 JC PRINT_BAND_TXT_END ; If printer error occurred: QUIT ;AN000;
472 INC CUR_COLUMN ; Else, Get next column; keep going ;AN000;
473 LOOP PRINT_1_CHAR ;AN000;
474 ;AN000;
475 PRINT_BAND_TXT_END: ;AN000;
476 POP CX ;AN000;
477 POP BX ;AN000;
478 POP AX ;AN000;
479 POP CUR_COLUMN ; Restore column number ;AN000;
480 RET ;AN000;
481 CUR_CHAR DB ? ;AN000;
482 PRINT_BAND_TXT ENDP ;AN000;
483 PAGE ;AN000;
484 ;===============================================================================;AN000;
485 ; ;AN000;
486 ; PRINT_COLOR_APA: PRINT AN APA MODE SCREEN ON A COLOR PRINTER ;AN000;
487 ; ;AN000;
488 ;-------------------------------------------------------------------------------;AN000;
489 ; ;AN000;
490 ; INPUT: BP = Offset of the shared data area ;AN000;
491 ; XLT_TAB = Color translation table ;AN000;
492 ; CUR_MODE_PTR = Coordinates of current DISPLAYMODE info. ;AN000;
493 ; ;AN000;
494 ; OUTPUT: PRINTER ;AN000;
495 ; ;AN000;
496 ;-------------------------------------------------------------------------------;AN000;
497 ; ;AN000;
498 ; DESCRIPTION: Each pixel on the screen is printed as a "box" of dots on the ;AN000;
499 ; printer. For a screen pixel of a given color, the best color approximation ;AN000;
500 ; is chosen among the color available on the printer. ;AN000;
501 ; ;AN000;
502 ; The printer colors are obtained by selecting a print band. A few more printer ;AN000;
503 ; color are obtained by printing twice (or more times) with different color ;AN000;
504 ; bands. ;AN000;
505 ; ;AN000;
506 ; For example, let's say we have a ribbon on the printer with a YELLOW CYAN ;AN000;
507 ; MAGENTA ribbon and we read a GREEN pixel on the screen. ;AN000;
508 ; ;AN000;
509 ; We first determine what "box" size will be used to represent this pixel. ;AN000;
510 ; Let's say it's a 3x2 box (this is obtained from the DISPLAYMODE record) ;AN000;
511 ; In all cases, we will print this pixel as a 3x2 box of printer dots. ;AN000;
512 ; That is, we will print 6 dots on the printer for one on the screen. ;AN000;
513 ; We do not use any kind of patterns (e,g,. printing only 2 dots out of 6) ;AN000;
514 ; for printing on the color printer. A screen pixel is either printed ;AN000;
515 ; as a "full" box of printer dots or not printed at all (e,g,. if it's white).;AN000;
516 ; ;AN000;
517 ; Now, from the COLORPRINT records, we know all the colors availables on the ;AN000;
518 ; printer, and what print bands must be used (or overlaid) in order to ;AN000;
519 ; obtain them. ;AN000;
520 ; ;AN000;
521 ; So, we consult these COLORPRINT records one by one comparing how close ;AN000;
522 ; the color of each of them is to our GREEN pixel. (the colors for our pixel ;AN000;
523 ; AND for the printer color are both indicated in terms of RGB values) ;AN000;
524 ; WE PICK THE CLOSEST PRINTER COLOR. ;AN000;
525 ; ;AN000;
526 ; To conclude, our GREEN pixel will be printed by first selecting the YELLOW ;AN000;
527 ; band, then sending to the printer a "box". Then, the BLUE band is selected ;AN000;
528 ; and the "box" is sent again. ;AN000;
529 ; ;AN000;
530 ; This process is carried line by line. ;AN000;
531 ; ;AN000;
532 ; For each line, we first read each pixel to see what color bands are going ;AN000;
533 ; to be needed for this line. ;AN000;
534 ; ;AN000;
535 ; Then, we loop for each band available on the printer. ;AN000;
536 ; ;AN000;
537 ; IF the current line needs the current printer band (i.e.,if any pixel on ;AN000;
538 ; the line needs this color band in order to achieve its color. ;AN000;
539 ; THEN, we select this color band (we know how to do it from the COLORSELECT ;AN000;
540 ; record in the Shared Data area) ;AN000;
541 ; AND we must read the line again; for each pixel that needs the current ;AN000;
542 ; band a "box" is sent to the printer. ;AN000;
543 ; ;AN000;
544 ; LOGIC : ;AN000;
545 ; CALL INIT_BLACK_BOX ; Initialize a print box ;AN000;
546 ; CALL GET_SCREEN_INFO ;AN000;
547 ; CALL SETUP_PRT ;AN000;
548 ; DO (NB_SCAN_LINES) TIMES ;AN000;
549 ; CALL DET_CUR_SCAN_LNE_LENGTH ;AN000;
550 ; IF CUR_SCAN_LNE_LENGTH NE 0 THEN ;AN000;
551 ; CALL SCAN_FOR_BANDS_APA(CUR_ROW,CUR_COLUMN,REQ_BAND_MASK) ;AN000;
552 ; CUR_BAND_MASK := 01H ;AN000;
553 ; IF REQ_BAND_MASK <> 0 THEN ;AN000;
554 ; DO 8 TIMES ;AN000;
555 ; IF (REQ_BAND_MASK AND CUR_BAND_MASK)=1 THEN ;AN000;
556 ; CALL NEW_PRT_LINE ;AN000;
557 ; CALL PRINT_BAND_APA(CUR_ROW,CUR_COLUMN,CUR_BAND_MASK) ;AN000;
558 ; CALL PRINT_BYTE(CARRIAGE_RETURN) ;AN000;
559 ; ENDIF ;AN000;
560 ; Shift CUR_BAND_MASK one bit left ;AN000;
561 ; ENDDO ;AN000;
562 ; ENDIF ; Should make a print pass for this color band ;AN000;
563 ; CALL PRINT_BYTE(LINE_FEED) ;AN000;
564 ; ENDIF ; Current scan line is not empty ;AN000;
565 ; IF rotated print THEN ;AN000;
566 ; CUR_COLUMN := CUR_COLUMN - BOXES_PER_PRT_BUF ;AN000;
567 ; CUR_ROW := SAVE_START_ROW ;AN000;
568 ; ELSE ;AN000;
569 ; CUR_ROW := CUR_ROW + BOXES_PER_PRT_BUF ;AN000;
570 ; CUR_COLUMN := SAVE_START_COLUMN ;AN000;
571 ; ENDIF ;AN000;
572 ; ENDDO ; Number of Scan lines ;AN000;
573 ; CALL RESTORE_PRT ;AN000;
574 ; ;AN000;
575 PRINT_COLOR_APA PROC ;AN000;
576 PUSH AX ;AN000;
577 PUSH BX ;AN000;
578 PUSH CX ;AN000;
579 PUSH DX ;AN000;
580 ;AN000;
581 ;AN000;
582 ;-------Initialize print box (A "box" represents one screen pel on the printer) ;AN000;
583 CALL INIT_BLACK_BOX ;AN000;
584 ;-------------------------------------------------------------------------------;AN000;
585 ; ;AN000;
586 ; Determine where to start reading the screen: ;AN000;
587 ; If printing sideways, start in LOW LEFT corner. ;AN000;
588 ; If normal printing, start in TOP LEFT corner. ;AN000;
589 ; Determine the maximum length for a scan line: ;AN000;
590 ; If printing sideways, it is the height of the screen. ;AN000;
591 ; For normal printing, it is the width of the screen. ;AN000;
592 ; Determine the number of scan lines on the screen. ;AN000;
593 ; ;AN000;
594 ;-------------------------------------------------------------------------------;AN000;
595 CALL GET_SCREEN_INFO ; Get info. about how to read the screen;AN000;
596 CALL SETUP_PRT ; Set up the printer (Line spacing, etc);AN000;
597 .IF <BIT ERROR_CODE NZ PRINTER_ERROR> ;AN000;
598 .THEN ; A printer error occurred: quit ;AN000;
599 JMP PRINT_COLOR_APA_END ; ;AN000;
600 .ENDIF ;AN000;
601 ;AN000;
602 MOV CX,NB_SCAN_LINES ;AN000;
603 ;---------------------------------------------------------------------------- ;AN000;
604 ; ;AN000;
605 ; FOR EACH SCAN LINE ON THE SCREEN (and each print line): ;AN000;
606 ; ;AN000;
607 ;---------------------------------------------------------------------------- ;AN000;
608 PRINT_SCAN_LINE: ;AN000;
609 CALL DET_CUR_SCAN_LNE_LENGTH ; Determine length of the scan line ;AN000;
610 .IF <CUR_SCAN_LNE_LENGTH NE 0> ; If line is not empty ;AN000;
611 .THEN ;AN000;
612 CALL SCAN_FOR_BANDS_APA ; REQ_BAND_MASK := Mask for what print;AN000;
613 ; bands are needed. ;AN000;
614 MOV DL,01H ; DL := "Current Band to be printed" ;AN000;
615 MOV BX,DS:[BP].COLORSELECT_PTR; BX := Offset of COLORSELECT record;AN000;
616 ADD BX,BP ; ("How to select the color band");AN000;
617 PUSH CX ; Save scan line counter ;AN000;
618 MOV CX,8 ; For up to the maximum number of prin;AN000;
619 ; bands with this printer ;AN000;
620 ;---------------------------------------------------------------------;AN000;
621 ; ;AN000;
622 ; FOR each Color Band needed: ;AN000;
623 ; ;AN000;
624 ;---------------------------------------------------------------------;AN000;
625 PRINT_1_COLOR_BAND_APA: ; Only if this color band is needed: ;AN000;
626 .IF <BIT REQ_BAND_MASK AND DL> ; Do one pass of the printer head ;AN000;
627 .THEN ; ;AN000;
628 CALL SET_COLOR_BAND ; Select the color band on the printer;AN000;
629 CALL NEW_PRT_LINE ; Send escape sequence to the printer ;AN000;
630 ; for starting a new graphics line ;AN000;
631 .IF <BIT ERROR_CODE NZ PRINTER_ERROR> ;AN000;
632 .THEN ; A printer error occurred: ;AN000;
633 POP CX ; Restore the line counter and ;AN000;
634 JMP PRINT_COLOR_APA_END ; return ;AN000;
635 .ENDIF ; Endif printer error occurred ;AN000;
636 ;AN000;
637 CALL PRINT_BAND_APA ; Do one Print Pass for current band ;AN000;
638 MOV AL,CR ; Print a carriage return ;AN000;
639 CALL PRINT_BYTE ;AN000;
640 .IF C ; If a printer error occurred ;AN000;
641 .THEN ;AN000;
642 POP CX ; Restore the line counter and ;AN000;
643 JMP PRINT_COLOR_APA_END ; return ;AN000;
644 .ENDIF ; End if printer error occurred ;AN000;
645 .ENDIF ; End if this color band is needed ;AN000;
646 SHL DL,1 ; Get next Color Band mask ;AN000;
647 ; Locate next COLORSELECT record: ;AN000;
648 MOV AL,[BX].NUM_SELECT_ESC; skip the escape bytes ;AN000;
649 XOR AH,AH ;AN000;
650 ADD BX,AX ;AN000;
651 INC BX ; skip the NUM_SELECT_ESC field ;AN000;
652 LOOP PRINT_1_COLOR_BAND_APA ;AN000;
653 POP CX ; Restore scan line counter ;AN000;
654 .ENDIF ; Scan line length <> 0 ;AN000;
655 ; ;AN000;
656 ;-----Print a line feed: ;AN000;
657 MOV AL,LF ;AN000;
658 CALL PRINT_BYTE ;AN000;
659 JC PRINT_COLOR_APA_END ; If a printer error occurred: quit ;AN000;
660 ; ;AN000;
661 ;-------Get coordinates of next scan line: ;AN000;
662 .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
663 .THEN ; then: ;AN000;
664 MOV AL,NB_BOXES_PER_PRT_BUF; AX := Numbers of pels read on row ;AN000;
665 CBW ; ;AN000;
666 ADD CUR_COLUMN,AX ; CUR_COLUMN + Number of pels read ;AN000;
667 MOV AX,SCREEN_HEIGHT ; CUR_ROW := SCREEN_HEIGHT - 1 ;AN000;
668 DEC AX ; ;AN000;
669 MOV CUR_ROW,AX ; ;AN000;
670 .ELSE ; else, printing NOT rotated: ;AN000;
671 MOV AL,NB_BOXES_PER_PRT_BUF ; AX := Number of pels read on column ;AN000;
672 CBW ; ;AN000;
673 ADD CUR_ROW,AX ; CUR_ROW + Number of pels read ;AN000;
674 MOV CUR_COLUMN,0 ; CUR_COLUMN := 0 ;AN000;
675 .ENDIF ; End if printing sideways ;AN000;
676 LOOP PRINT_SCAN_LINE ; ;AN000;
677 ;AN000;
678 ;-------------------------------------------------------------------------------;AN000;
679 ; ;AN000;
680 ; Restore the printer (send a Page Eject, etc.) ;AN000;
681 ; ;AN000;
682 ;-------------------------------------------------------------------------------;AN000;
683 CALL RESTORE_PRT ;AN000;
684 PRINT_COLOR_APA_END: ;AN000;
685 POP DX ;AN000;
686 POP CX ;AN000;
687 POP BX ;AN000;
688 POP AX ;AN000;
689 RET ;AN000;
690 PRINT_COLOR_APA ENDP ;AN000;
691 PAGE ;AN000;
692 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AN000;
693 ;; ;AN000;
694 ;; ;AN000;
695 ;; SCAN_FOR_BANDS_APA : DETERMINE WHAT PRINT BANDS ARE NEEDED FOR THE CURRENT ;AN000;
696 ;; PRINT PASS. ;AN000;
697 ;; ;AN000;
698 ;;------------------------------------------------------------------------------;AN000;
699 ; ;AN000;
700 ; INPUT: CUR_ROW : row to start scanning (word) ;AN000;
701 ; CUR_COLUMN : column to start scanning (word) ;AN000;
702 ; CUR_SCAN_LNE_LENGTH : length of the current scan line (word) ;AN000;
703 ; ROTATE_SW = ON if printing is sideways ;AN000;
704 ; ;AN000;
705 ; OUTPUT: REQ_BAND_MASK : band mask for required bands (byte) ;AN000;
706 ; ;AN000;
707 ;;------------------------------------------------------------------------------;AN000;
708 ;; ;AN000;
709 ;; Data Structures Referenced: ;AN000;
710 ;; Shared Data Area ;AN000;
711 ;; Print Info ;AN000;
712 ;; Color Translate Table ;AN000;
713 ;; ;AN000;
714 ;; ;AN000;
715 ;; Description: ;AN000;
716 ;; Read all the dots required for one print line to determine ;AN000;
717 ;; the print bands required. The print line corresponds to several ;AN000;
718 ;; screen rows (or columns if rotated printing). The number of ;AN000;
719 ;; rows / columns per print line is stored in NB_BOXES_PER_PRT_BUF. ;AN000;
720 ;; The band information is obtained from the Color Translate Table. ;AN000;
721 ;; ;AN000;
722 ;; Called By: ;AN000;
723 ;; PRINT_COLOR_APA ;AN000;
724 ;; ;AN000;
725 ;; External Calls: ;AN000;
726 ;; READ_DOT, BIOS INT 10H ;AN000;
727 ;; ;AN000;
728 ;; Logic: ;AN000;
729 ;; Save initial coordinates ;AN000;
730 ;; SAVE_START_COLUMN := CUR_COLUMN ;AN000;
731 ;; REQ_BAND_MASK := 00H ;AN000;
732 ;; DO (SCAN_LINE_LENGTH) TIMES ;AN000;
733 ;; Save coordinates of the "column" ;AN000;
734 ;; DO (BOXES_PER_PRT_BUF) TIMES ;AN000;
735 ;; CALL READ_DOT(IN CUR_ROW,CUR_COLUMN; OUT COLOR_NUM) ;AN000;
736 ;; REQ_BAND_MASK := REQ_BAND_MASK OR COLOR_XLAT_TAB[BX] ;AN000;
737 ;; IF rotated print THEN ;AN000;
738 ;; Increment CUR_COLUMN ;AN000;
739 ;; ELSE ;AN000;
740 ;; Increment CUR_ROW ;AN000;
741 ;; ENDIF ;AN000;
742 ;; Restore coordinates of the "column" ;AN000;
743 ;; ENDDO ;AN000;
744 ;; IF rotated print THEN ;AN000;
745 ;; Decrement CUR_ROW ;AN000;
746 ;; ELSE ;AN000;
747 ;; Increment CUR_COLUMN ;AN000;
748 ;; ENDIF ;AN000;
749 ;; ENDDO ;AN000;
750 ;; Restore initial coordinates ;AN000;
751 ;; RETURN ;AN000;
752 ;; ;AN000;
753 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
754 SCAN_FOR_BANDS_APA PROC NEAR ;AN000;
755 PUSH CUR_ROW ;AN000;
756 PUSH CUR_COLUMN ;AN000;
757 PUSH AX ;AN000;
758 PUSH BX ;AN000;
759 PUSH CX ;AN000;
760 ;AN000;
761 MOV REQ_BAND_MASK,0 ; No Color bands needed so far... ;AN000;
762 MOV BX,OFFSET XLT_TAB ; BX := Offset of translation table ;AN000;
763 MOV CX,CUR_SCAN_LNE_LENGTH ;AN000;
764 ;===============================================================================;AN000;
765 ; ;AN000;
766 ; FOR each column on the current scan line (up to the last non=blank): ;AN000;
767 ; ;AN000;
768 ;===============================================================================;AN000;
769 SCAN_1_COLUMN: ;AN000;
770 PUSH CX ; Save column counter ;AN000;
771 PUSH CUR_ROW ; Save coordinates of the "column" ;AN000;
772 PUSH CUR_COLUMN ;AN000;
773 ;-------------------------------------------------------------------------------;AN000;
774 ; ;AN000;
775 ; For each pixel within the current column of the scan line: ;AN000;
776 ; ;AN000;
777 ;-------------------------------------------------------------------------------;AN000;
778 XOR CX,CX ; CX := Number of pixels to read ;AN000;
779 MOV CL,NB_BOXES_PER_PRT_BUF ; within the current "column" ;AN000;
780 SCAN_1_PIXEL: ;AN000;
781 CALL READ_DOT ; AL := Index into translation table ;AN000;
782 XLAT XLT_TAB ; AL := Band mask ;AN000;
783 OR REQ_BAND_MASK,AL ; Add bands required for this pixel ;AN000;
784 ;AN000;
785 ;-------Get coordinates of next pixel: ;AN000;
786 .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
787 .THEN ; ;AN000;
788 INC CUR_COLUMN ; then, increment column number ;AN000;
789 .ELSE ; ;AN000;
790 INC CUR_ROW ; else, increment row number ;AN000;
791 .ENDIF ; ;AN000;
792 LOOP SCAN_1_PIXEL ;AN000;
793 POP CUR_COLUMN ; Restore coordinates of the "column" ;AN000;
794 POP CUR_ROW ; ;AN000;
795 POP CX ; Restore column counter ;AN000;
796 ;AN000;
797 ;AN000;
798 ;-------Get coordinates of next "column": ;AN000;
799 .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
800 .THEN ; ;AN000;
801 DEC CUR_ROW ; then, get row above on screen ;AN000;
802 .ELSE ; ;AN000;
803 INC CUR_COLUMN ; else, get column next right ;AN000;
804 .ENDIF ; ;AN000;
805 LOOP SCAN_1_COLUMN ;AN000;
806 ;AN000;
807 POP CX ;AN000;
808 POP BX ;AN000;
809 POP AX ;AN000;
810 POP CUR_COLUMN ;AN000;
811 POP CUR_ROW ;AN000;
812 RET ;AN000;
813 SCAN_FOR_BANDS_APA ENDP ;AN000;
814 PAGE ;AN000;
815 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AN000;
816 ;; ;AN000;
817 ;; PRINT_BAND_APA : PRINT ALL DOTS ON CURRENT LINE THAT NEED THE CURRENT BAND ;AN000;
818 ;; TO APPROXIMATE THEIR COLOR. ;AN000;
819 ;; ;AN000;
820 ;-------------------------------------------------------------------------------;AN000;
821 ; ;AN000;
822 ; INPUT: CUR_ROW, ;AN000;
823 ; CUR_COLUMN : Coordinates of the first pixel to be read in the ;AN000;
824 ; current scan line. ;AN000;
825 ; DL : Band mask indicating what print band to use ;AN000;
826 ; for this print pass. ;AN000;
827 ; CUR_SCAN_LNE_LENGTH: Length of the current scan line. ;AN000;
828 ; ROTATE_SW = ON if printing is sideways ;AN000;
829 ; ;AN000;
830 ; OUTPUT: PRINTER ;AN000;
831 ; ;AN000;
832 ;-------------------------------------------------------------------------------;AN000;
833 ;; ;AN000;
834 ;; Data Structures Referenced: ;AN000;
835 ;; Shared Data Area ;AN000;
836 ;; Print Info ;AN000;
837 ;; Color Translate Table ;AN000;
838 ;; ;AN000;
839 ;; Description: ;AN000;
840 ;; Print all dots on this print line which need the current ;AN000;
841 ;; band. The print line corresponds to several ;AN000;
842 ;; screen rows (or columns if rotated printing). The number of ;AN000;
843 ;; rows / columns per print line is stored in NB_BOXES_PER_PRT_BUF. ;AN000;
844 ;; The band information is obtained from the Color Translate Table. ;AN000;
845 ;; ;AN000;
846 ;; Called By: ;AN000;
847 ;; PRINT_COLOR_APA ;AN000;
848 ;; ;AN000;
849 ;; External Calls: ;AN000;
850 ;; READ_DOT, BIOS INT 10H, STORE_BOX, PRT_BUFFER, PRINT_BYTE ;AN000;
851 ;; ;AN000;
852 ;; Logic: ;AN000;
853 ;; SAVE_START_ROW := CUR_ROW ;AN000;
854 ;; SAVE_START_COLUMN := CUR_COLUMN ;AN000;
855 ;; ;AN000;
856 ;; CALL SET_COLOR_BAND ; Select the color for this print pass ;AN000;
857 ;; DO (SCAN_LINE_LENGTH) TIMES ;AN000;
858 ;; Save coordinates of the "column" ;AN000;
859 ;; Clear the print buffer ;AN000;
860 ;; DO (BOXES_PER_PRT_BUF) TIMES ;AN000;
861 ;; CALL READ_DOT(CUR_ROW,CUR_COLUMN,COLOR_NUM) ;AN000;
862 ;; IF (CUR_BAND_MASK AND XLAT_TAB[COLOR_NUM])=1 THEN ;AN000;
863 ;; CALL STORE_BOX(black box) ;AN000;
864 ;; ELSE ;AN000;
865 ;; CALL STORE_BOX(white box) ;AN000;
866 ;; ENDIF ;AN000;
867 ;; IF rotated print THEN ;AN000;
868 ;; Decrement CUR_COLUMN ;AN000;
869 ;; ELSE ;AN000;
870 ;; Increment CUR_ROW ;AN000;
871 ;; ENDIF ;AN000;
872 ;; ENDDO ;AN000;
873 ;; CALL PRINT_BUFFER ;AN000;
874 ;; Restore coordinates of the "column" ;AN000;
875 ;; ; Get coordinates of the next "column"; ;AN000;
876 ;; IF rotated print THEN ;AN000;
877 ;; Decrement CUR_ROW ;AN000;
878 ;; CUR_COLUMN := SAVE_START_COLUMN ;AN000;
879 ;; ELSE ;AN000;
880 ;; Increment CUR_COLUMN ;AN000;
881 ;; CUR_ROW := SAVE_START_ROW ;AN000;
882 ;; ENDIF ;AN000;
883 ;; ENDDO ;AN000;
884 ;; RETURN ;AN000;
885 ;; ;AN000;
886 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AN000;
887 PRINT_BAND_APA PROC NEAR ;AN000;
888 PUSH CUR_ROW ; Save coordinates ;AN000;
889 PUSH CUR_COLUMN ;AN000;
890 PUSH AX ;AN000;
891 PUSH BX ;AN000;
892 PUSH CX ;AN000;
893 PUSH SI ;AN000;
894 PUSH DI ;AN000;
895 ;AN000;
896 MOV BX,OFFSET XLT_TAB ; BX := Offset of translation table ;AN000;
897 MOV CX,CUR_SCAN_LNE_LENGTH ;AN000;
898 ;===============================================================================;AN000;
899 ; ;AN000;
900 ; FOR each column on the current scan line (up to the last non=blank): ;AN000;
901 ; (One "column" contains the number of pixels required to fill the Print buffer);AN000;
902 ; ;AN000;
903 ;===============================================================================;AN000;
904 PRINT_1_COLUMN: ;AN000;
905 ;-------------------------------------------------------------------------------;AN000;
906 ; ;AN000;
907 ; Clear the print buffer "PRT_BUF" ;AN000;
908 ; ;AN000;
909 ;-------------------------------------------------------------------------------;AN000;
910 XOR DI,DI ; DI := Number of bytes cleared in the buffer ;AN000;
911 XOR AX,AX ;AN000;
912 MOV AL,BOX_W ; AX := Number of bytes in the print buffer ;AN000;
913 CLEAR_BUF: ; For each byte in the PRT_BUF: ;AN000;
914 MOV PRT_BUF[DI],0 ; Initialize byte to blanks ;AN000;
915 INC DI ; One more has been cleared ;AN000;
916 CMP DI,AX ; All bytes cleared ? ;AN000;
917 JL CLEAR_BUF ; No, clear next one. ;AN000;
918 ;AN000;
919 ;-------------------------------------------------------------------------------;AN000;
920 ; ;AN000;
921 ; Fill up the print buffer "PRT_BUF" ;AN000;
922 ; ;AN000;
923 ;-------------------------------------------------------------------------------;AN000;
924 PUSH CX ; Save column counter ;AN000;
925 XOR CX,CX ; CX := Number of pixels to read ;AN000;
926 MOV CL,NB_BOXES_PER_PRT_BUF ; within the current "column" ;AN000;
927 ; of the scan line ;AN000;
928 PUSH CUR_ROW ; Save coordinates of the "column" ;AN000;
929 PUSH CUR_COLUMN ;AN000;
930 ; ;AN000;
931 ; For each pixel within the current column of the scan line: ;AN000;
932 STORE_1_PIXEL: ;AN000;
933 CALL READ_DOT ; AL := Index into translation table ;AN000;
934 XLAT XLT_TAB ; AL := Band mask ;AN000;
935 .IF <BIT AL AND DL> ; If color of the current pixel needs ;AN000;
936 .THEN ; the current printer band ;AN000;
937 MOV SI,OFFSET BLACK_BOX ; then, store a box in the ;AN000;
938 CALL STORE_BOX ; PRT_BUF ;AN000;
939 .ELSE ; ;AN000;
940 MOV SI,OFFSET WHITE_BOX ; else, store an empty box ;AN000;
941 CALL STORE_BOX ; in the PRT_BUF ;AN000;
942 .ENDIF ;AN000;
943 ; ;AN000;
944 ;-------Get coordinates of next pixel: ;AN000;
945 .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
946 .THEN ; ;AN000;
947 INC CUR_COLUMN ; then, increment column number ;AN000;
948 .ELSE ; ;AN000;
949 INC CUR_ROW ; else, increment row number ;AN000;
950 .ENDIF ; ;AN000;
951 LOOP STORE_1_PIXEL ;AN000;
952 ;AN000;
953 POP CUR_COLUMN ; Restore coordinates of the "column" ;AN000;
954 POP CUR_ROW ; ;AN000;
955 POP CX ; Restore column counter ;AN000;
956 ;-------------------------------------------------------------------------------;AN000;
957 ; ;AN000;
958 ; Print the PRT_BUF: ;AN000;
959 ; ;AN000;
960 ;-------------------------------------------------------------------------------;AN000;
961 CALL PRINT_BUFFER ;AN000;
962 .IF <BIT ERROR_CODE NZ PRINTER_ERROR> ;AN000;
963 .THEN ; A printer error occurred: QUIT ;AN000;
964 JMP SHORT PRINT_BAND_APA_END ; ;AN000;
965 .ENDIF ;AN000;
966 ;AN000;
967 ;-------------------------------------------------------------------------------;AN000;
968 ; ;AN000;
969 ; Get coordinates of next "column": ;AN000;
970 ; ;AN000;
971 ;-------------------------------------------------------------------------------;AN000;
972 .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
973 .THEN ; ;AN000;
974 DEC CUR_ROW ; then, get row above on screen ;AN000;
975 .ELSE ; ;AN000;
976 INC CUR_COLUMN ; else, get column next right ;AN000;
977 .ENDIF ; ;AN000;
978 LOOP PRINT_1_COLUMN ;AN000;
979 ;AN000;
980 PRINT_BAND_APA_END: ;AN000;
981 POP DI ;AN000;
982 POP SI ;AN000;
983 POP CX ;AN000;
984 POP BX ;AN000;
985 POP AX ;AN000;
986 POP CUR_COLUMN ; Restore initial coordinates ;AN000;
987 POP CUR_ROW ;AN000;
988 RET ;AN000;
989 PRINT_BAND_APA ENDP ;AN000;
990 PAGE ;AN000;
991 ;===============================================================================;AN000;
992 ; ;AN000;
993 ; SET_CURSOR : SET THE CURSOR TO CUR_ROW, CUR_COLUMN AND CUR_PAGE ;AN000;
994 ; ;AN000;
995 ;-------------------------------------------------------------------------------;AN000;
996 ; ;AN000;
997 ; INPUT: CUR_ROW, ;AN000;
998 ; CUR_COLUMN = Coordinates for the cursor (word) ;AN000;
999 ; CUR_PAGE = Page for which to set the cursor (byte) ;AN000;
1000 ; ;AN000;
1001 ; OUTPUT: SCREEN ;AN000;
1002 ; ;AN000;
1003 ;-------------------------------------------------------------------------------;AN000;
1004 SET_CURSOR PROC NEAR ;AN000;
1005 PUSH AX ;AN000;
1006 PUSH BX ;AN000;
1007 PUSH DX ;AN000;
1008 MOV DH,BYTE PTR CUR_ROW ;AN000;
1009 MOV DL,BYTE PTR CUR_COLUMN ;AN000;
1010 MOV BH,CUR_PAGE ;AN000;
1011 MOV AH,SET_CURSOR_CALL ; Set cursor request ;AN000;
1012 INT 10H ; Call BIOS ;AN000;
1013 POP DX ;AN000;
1014 POP BX ;AN000;
1015 POP AX ;AN000;
1016 RET ;AN000;
1017 SET_CURSOR ENDP ;AN000;
1018 PAGE ;AN000;
1019 ;===============================================================================;AN000;
1020 ; ;AN000;
1021 ; SET_COLOR_BAND : SET THE PRINTER TO THE CURRENT COLOR BAND ;AN000;
1022 ; ;AN000;
1023 ;-------------------------------------------------------------------------------;AN000;
1024 ; ;AN000;
1025 ; INPUT: BX = Offset of current COLORSELECT record in the ;AN000;
1026 ; Shared data area. ;AN000;
1027 ; DS:[BP] = Offset of shared data area ;AN000;
1028 ; ;AN000;
1029 ; OUTPUT: PRINTER ;AN000;
1030 ; ;AN000;
1031 ;-------------------------------------------------------------------------------;AN000;
1032 SET_COLOR_BAND PROC NEAR ;AN000;
1033 PUSH AX ;AN000;
1034 PUSH BX ;AN000;
1035 PUSH CX ;AN000;
1036 ;AN000;
1037 ;-------Send the escape sequence for selecting this color band to the printer: ;AN000;
1038 XOR CX,CX ;AN000;
1039 MOV CL,[BX].NUM_SELECT_ESC ; CX := Number of bytes to send ;AN000;
1040 ADD BX,OFFSET SELECT_ESC ; BX := Offset of bytes to send ;AN000;
1041 SEND_1_COLORSELECT_BYTE: ;AN000;
1042 MOV AL,[BX] ; AL := Byte to send to printer ;AN000;
1043 CALL PRINT_BYTE ; Send it ;AN000;
1044 JC SET_COLOR_BAND_END ; If printer error: return ;AN000;
1045 INC BX ; Get next byte ;AN000;
1046 LOOP SEND_1_COLORSELECT_BYTE ;AN000;
1047 ;AN000;
1048 SET_COLOR_BAND_END: ;AN000;
1049 POP CX ;AN000;
1050 POP BX ;AN000;
1051 POP AX ;AN000;
1052 RET ;AN000;
1053 SET_COLOR_BAND ENDP ;AN000;
1054 PAGE ;AN000;
1055 ;===============================================================================;AN000;
1056 ; ;AN000;
1057 ; INIT_BLACK_BOX: INIT. THE BOX FOR PRINTING APA MODE DOTS ON A COLOR PRINTER. ;AN000;
1058 ; ;AN000;
1059 ;-------------------------------------------------------------------------------;AN000;
1060 ; ;AN000;
1061 ; INPUT: BOX_W, ;AN000;
1062 ; BOX_H = Size of the print box for one pixel. ;AN000;
1063 ; ;AN000;
1064 ; OUTPUT: BLACK_BOX = A box for which all dots are on. ;AN000;
1065 ; ;AN000;
1066 ;-------------------------------------------------------------------------------;AN000;
1067 ; ;AN000;
1068 ; DESCRIPTION: Initialize the print box used to print a screen pixel. ;AN000;
1069 ; ;AN000;
1070 ; For example, ;AN000;
1071 ; with a size of 3x2 the BLACK_BOX will use 3 bytes: ;AN000;
1072 ; ;AN000;
1073 ; ;AN000;
1074 ; byte1 byte2 byte3 ;AN000;
1075 ; (column1) (column2) (column3) ;AN000;
1076 ; bit 7 -->0 0 0 ;AN000;
1077 ; 0 0 0 ;AN000;
1078 ; 0 0 0 ;AN000;
1079 ; 0 0 0 ;AN000;
1080 ; 0 0 0 ;AN000;
1081 ; 0 0 0 ;AN000;
1082 ; 1 1 1 ;AN000;
1083 ; bit 0 -->1 1 1 ;AN000;
1084 ; ;AN000;
1085 ;-------------------------------------------------------------------------------;AN000;
1086 INIT_BLACK_BOX PROC NEAR ;AN000;
1087 PUSH AX ;AN000;
1088 PUSH BX ;AN000;
1089 PUSH CX ;AN000;
1090 ;AN000;
1091 ;-------Build one box column: ;AN000;
1092 XOR CX,CX ;AN000;
1093 MOV CL,BOX_H ; CX := Height in bits of the print box ;AN000;
1094 XOR AL,AL ; AX := Bit mask for creating box column ;AN000;
1095 .REPEAT ; For height of the box: ;AN000;
1096 SHL AL,1 ; ;AN000;
1097 OR AL,1 ; Insert one bit in the box column ;AN000;
1098 .LOOP ;AN000;
1099 ;AN000;
1100 ;-------------------------------------------------------------------------------;AN000;
1101 ; ;AN000;
1102 ; AL now contains one box column. ;AN000;
1103 ; ;AN000;
1104 ;-------------------------------------------------------------------------------;AN000;
1105 ;AN000;
1106 ;-------Replicate this column over all columns of the box. ;AN000;
1107 XOR BX,BX ; BX := Index into the BOX ;AN000;
1108 INIT_1_BLACK_COLUMN: ;AN000;
1109 MOV BLACK_BOX[BX],AL; Init current column to black box column ;AN000;
1110 INC BX ; Get next column ;AN000;
1111 CMP BL,BOX_W ;AN000;
1112 JL INIT_1_BLACK_COLUMN ;AN000;
1113 ;AN000;
1114 POP CX ;AN000;
1115 POP BX ;AN000;
1116 POP AX ;AN000;
1117 RET ;AN000;
1118 INIT_BLACK_BOX ENDP ;AN000;
1119 INCLUDE GRCOMMON.ASM ;AN000;
1120 LEN_OF_COLOR_MODULES EQU $-PRINT_COLOR ;AN000;
1121 CODE ENDS ;AN000;
1122 END ;AN000;