2 TITLE DOS GRAPHICS Command
- Black
and White printing modules
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
4 ;; DOS - GRAPHICS Command
5 ;; (c) Copyright 1988 Microsoft
7 ;; File Name: GRBWPRT.ASM ;AN000;
10 ;; Description: ;AN000;
11 ;; ------------ ;AN000;
12 ;; This file contains the code for printing a GRAPHICS screen on a ;AN000;
13 ;; BLACK and WHITE printer. ;AN000;
15 ;; Documentation Reference: ;AN000;
16 ;; ------------------------ ;AN000;
17 ;; OASIS High Level Design ;AN000;
18 ;; OASIS GRAPHICS I1 Overview ;AN000;
20 ;; Procedures Contained in This File: ;AN000;
21 ;; ---------------------------------- ;AN000;
23 ;; PRINT_BW_APA ;AN000;
24 ;; FILL_BUFFER ;AN000;
29 ;; Include Files Required: ;AN000;
30 ;; ----------------------- ;AN000;
31 ;; GRCTRL.EXT - Externals for print screen control ;AN000;
32 ;; GRCTRL.STR - Structures and equates for print screen control ;AN000;
33 ;; GRPATTRN.STR - Structures for the printer patterns. ;AN000;
35 ;; GRSHAR.STR - Shared Data Area Structure ;AN000;
37 ;; STRUC.INC - Macros for using structured assembly language ;AN000;
40 ;; External Procedure References: ;AN000;
41 ;; ------------------------------ ;AN000;
42 ;; FROM FILE GRCTRL.ASM: ;AN000;
43 ;; PRT_SCR - Main module for printing the screen. ;AN000;
44 ;; TO FILE GRCOMMON.ASM ;AN000;
45 ;; Common modules - tools for printing a screen. ;AN000;
47 ;; Linkage Instructions: ;AN000;
48 ;; -------------------- ;AN000;
49 ;; This file is included by GRCTRL.ASM ;AN000;
51 ;; Change History: ;AN000;
52 ;; --------------- ;AN000;
55 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
57 CODE SEGMENT PUBLIC 'CODE' ;AN000;
58 ASSUME
CS:CODE,DS:CODE ;AN000;
60 PUBLIC PRINT_BW_APA
;AN000;
61 PUBLIC LEN_OF_BW_MODULES
;AN000;
64 INCLUDE GRCTRL
.STR ; Stuctures needed ;AN000;
65 INCLUDE GRSHAR
.STR ; for both set of print modules ;AN000;
66 INCLUDE GRPATTRN
.STR ; ;AN000;
67 INCLUDE GRCTRL
.EXT
; Externals from PRT_SCR control module ;AN000;
68 INCLUDE STRUC.INC ; ;AN000;
70 PUBLIC PRINT_BW_APA
; Black and white modules, ;AN000;
72 ;===============================================================================;AN000;
74 ; PRINT_BW_APA : PRINT A GRAPHIC MODE SCREEN ON A BLACK AND WHITE PRINTER ;AN000;
76 ;-------------------------------------------------------------------------------;AN000;
78 ; INPUT: BP = Offset of the shared data area ;AN000;
79 ; XLT_TAB = Color translation table ;AN000;
80 ; BIOS_INT_5H = Pointer to BIOS int 5h ;AN000;
82 ; OUTPUT: PRINTER ;AN000;
84 ;-------------------------------------------------------------------------------;AN000;
86 ; DESCRIPTION: This procedure maps each pixel of the screen to a box ;AN000;
87 ; of dots on the printer. The box size depends on the screen resolution ;AN000;
88 ; and the number of bytes per printer line. It is chosen in order to ;AN000;
89 ; respect the screen ratio and is documented in each printer profile. ;AN000;
91 ; For efficiency and space considerations, the print buffer does not ;AN000;
92 ; hold a full print line. Bytes representing pixels are printed as soon ;AN000;
93 ; as they are ready to be printed. However, the print buffer is wide ;AN000;
94 ; enough to hold complete boxes. ;AN000;
96 ; The order for reading pixels off the screen is driven by the ;AN000;
97 ; order bytes are expected by the printer. To print the screen in its ;AN000;
98 ; original orientation we must begin reading it from the top left corner ;AN000;
99 ; and send the pixels line by line; to print it sideways, reading will ;AN000;
100 ; start from the bottom left corner and a "LINE" will now be a vertical ;AN000;
101 ; screen column read from bottom to top. ;AN000;
103 ; There is more to it however, the printer head is printing a ;AN000;
104 ; vertical column of 8 dots at a time and each pixel read is mapped to ;AN000;
105 ; a box of dots that is less than 8 dots high (e.g., 2 cols x 1 row) ;AN000;
106 ; therefore, many boxes must be stored in the bytes sent to the printer. ;AN000;
108 ; These boxes represent pixels that are one above each other on the ;AN000;
109 ; screen. We must read enough pixels on one column of the screen to use ;AN000;
110 ; all 8 bits of the vertical printer head (e.g., if the box size is 2x1 ;AN000;
111 ; then 8 pixels must be read and 2 bytes of the print buffer will be ;AN000;
114 ; The PRINT BUFFER for any box size will be 8 bits high by "BOX ;AN000;
115 ; WIDTH" bits wide. ;AN000;
117 ; After the buffer is filled, it is printed and the next "column" ;AN000;
118 ; of 8 pixels is read. Therefore, the screen is read "line by line" ;AN000;
119 ; where a line is 8 pixels high for a 2x1 box (4 pixels high for a 3x2 ;AN000;
120 ; box). ONE SUCH LINE IS CALLED A SCAN LINE. ;AN000;
124 ; A 350X200 screen mapping to a 3x2 box is read in the following order: ;AN000;
128 ; column column . . . column ;AN000;
129 ; no. 0 no. 1 no. 349 ;AN000;
130 ; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ;AN000;
131 ; scan º1(0,0) 5(0,1) 1397(0,349)º ;AN000;
132 ; line º2(1,0) 6(1,1) . . . . . . . 1398(1,349)º ;AN000;
133 ; no. 1 º3(2,0) 7(2,1) 1399(2,349)º ;AN000;
134 ; º4(3,0) 8(3,1) 1400(3,349)º ;AN000;
136 ; scan º1401(4,0) 1405(4,1) º LEGEND: n(X,Y) ;AN000;
137 ; line º1402(5,0) etc, º ;AN000;
138 ; no. 2 º1403(6,0) . . . . . º n = READ RANK ;AN000;
139 ; º1404(7,0) º X = ROW NUMBER ;AN000;
140 ; º . º Y = COLUMN NUMBER ;AN000;
142 ; º . 70000(199,349)º ;AN000;
143 ; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ;AN000;
148 ; Initialize printer and local variables. ;AN000;
149 ; CALL LOC_MODE_PRT_INFO ; Get printer info related to current mode. ;AN000;
150 ; CALL GET_SCREEN_INFO ; Get info. about how to read the screen ;AN000;
151 ; CALL SETUP_PRT ; Set up the printer (Line spacing, etc) ;AN000;
153 ; FOR each scan line on the screen (NB_SCAN_LINES) ;AN000;
154 ; (Note: One scan line maps to one print line) ;AN000;
156 ; CALL DET_CUR_SCAN_LNE_LENGTH ; Determine length in pels of the current ;AN000;
157 ; ; scan line. ;AN000;
158 ; IF CUR_SCAN_LNE_LENGTH NE 0 THEN ;AN000;
159 ; CALL NEW_PRT_LINE ; Initialize a new printer line ;AN000;
160 ; DO CUR_SCAN_LNE_LENGTH times ; For each column ;AN000;
162 ; CALL FILL_BUFFER ; Read top-down enough pels to fill the buffer ;AN000;
163 ; CALL PRINT_BUFFER ; Print the buffer ;AN000;
164 ; IF printing sideways THEN INC CUR_ROW ; Get coordinates of next ;AN000;
165 ; ELSE INC CUR_COLUMN ; "column" (vertical chunk of ;AN000;
166 ; END (for each column) ; a scan line). ;AN000;
167 ; PRINT_BYTE CR ; Print a CR and a LF ;AN000;
168 ; PRINT_BYTE LF ;AN000;
169 ; ; Get coordinates of next scan line: ;AN000;
170 ; IF printing sideways THEN ;AN000;
171 ; ADD CUR_COLUMN,NB_BOXES_PER_PRT_BUF ;AN000;
172 ; MOV CUR_ROW,SCREEN_HEIGHT - 1 ;AN000;
174 ; ADD CUR_ROW,NB_BOXES_PER_PRT_BUF ;AN000;
175 ; MOV CUR_COLUMN,0 ;AN000;
176 ; END (for each scan line) ;AN000;
178 PRINT_BW_APA PROC
NEAR ;AN000;
183 ;-------------------------------------------------------------------------------;AN000;
185 ; INITIALIZATION: ;AN000;
187 ; 1) Locate and extract printer DISPLAYMODE information from ;AN000;
188 ; the shared data area, calculate the number of boxes fitting ;AN000;
189 ; in the printer buffer. ;AN000;
190 ; 2) Determine where to start reading the screen: ;AN000;
191 ; If printing sideways, start in LOW LEFT corner. ;AN000;
192 ; If normal printing, start in TOP LEFT corner. ;AN000;
193 ; Determine the maximum length for a scan line: ;AN000;
194 ; If printing sideways, it is the height of the screen. ;AN000;
195 ; For normal printing, it is the width of the screen. ;AN000;
196 ; Determine the number of scan lines on the screen. ;AN000;
197 ; 3) Set up the Printer for printing Graphics. ;AN000;
199 ;-------------------------------------------------------------------------------;AN000;
200 CALL LOC_MODE_PRT_INFO
; Get printer info related to curr. mode;AN000;
202 ;-------Test if DISPLAYMODE info record was found: ;AN000;
203 .IF <ERROR_CODE
EQ DISPLAYMODE_INFO_NOT_FOUND
> ;AN000;
205 MOV ERROR_CODE
,UNABLE_TO_PRINT
; IF no record found, ;AN000;
206 JMP PRINT_BW_APA_END
; then, return error code ;AN000;
207 .ENDIF
; and quit procedure ;AN000;
209 ;-------Get the box size from the DISPLAYMODE info record: ;AN000;
210 MOV BX,CUR_MODE_PTR
; BX := Offset current DISPLAYMODE info.;AN000;
211 MOV AH,[BX].BOX_WIDTH
; Take local copy of the box size. ;AN000;
212 MOV BOX_W
,AH ; in BOX_W and BOX_H ;AN000;
213 MOV AL,[BX].BOX_HEIGHT
;AN000;
216 ;-------Verify if the box size obtained from DISPLAYMODE info. is valid ;AN000;
217 .IF <ZERO
AL> OR ; IF height of the box is 0 ;AN000;
218 .IF <ZERO
AH> ; OR width of the box is 0 ;AN000;
219 .THEN
; THEN we can't print: ;AN000;
220 MOV ERROR_CODE
,UNABLE_TO_PRINT
; return error code ;AN000;
221 JMP PRINT_BW_APA_END
; and quit ;AN000;
224 ;-------Get the Print Orientation from the DISPLAYMODE info record ;AN000;
225 .IF <[BX].PRINT_OPTIONS
EQ ROTATE
>; If printing sideways ;AN000;
226 .THEN
; then: ;AN000;
227 MOV ROTATE_SW
,ON ; Rotate switch := "ON" ;AN000;
231 ;-------Initialize print variables and the printer: ;AN000;
232 CALL GET_SCREEN_INFO
; Get info. about how to read the screen;AN000;
233 CALL SETUP_PRT
; Set up the printer (Line spacing, etc);AN000;
234 .IF <BIT ERROR_CODE NZ PRINTER_ERROR
> ;AN000;
235 .THEN
; A printer error occurred: quit ;AN000;
236 JMP PRINT_BW_APA_END
; ;AN000;
239 MOV CX,NB_SCAN_LINES
;AN000;
240 ;-------------------------------------------------------------------------------;AN000;
242 ; FOR EACH SCAN LINE ON THE SCREEN: ;AN000;
244 ;-------------------------------------------------------------------------------;AN000;
245 PRINT_1_SCAN_LINE: ;AN000;
246 CALL DET_CUR_SCAN_LNE_LENGTH
; Determine how many non-blanks on line ;AN000;
247 .IF <CUR_SCAN_LNE_LENGTH NE
0> ; If line is not empty ;AN000;
248 .THEN
; then, ;AN000;
249 CALL NEW_PRT_LINE
; Send escape sequence to the printer ;AN000;
250 .IF <BIT ERROR_CODE NZ PRINTER_ERROR
> ; for starting a new line. ;AN000;
251 .THEN
; If a printer error occurred: ;AN000;
252 JMP PRINT_BW_APA_END
; Quit ! ;AN000;
255 PUSH CX ; Save scan line counter ;AN000;
256 MOV CX,CUR_SCAN_LNE_LENGTH
;AN000;
257 ;-------------------------------------------------------------------------------;AN000;
259 ; FOR each column on the current scan line (up to the last non-blank): ;AN000;
261 ;-------------------------------------------------------------------------------;AN000;
262 PRINT_1_SCAN_COLUMN: ;AN000;
263 CALL FILL_BUFFER
; Read all pixels on this column, ;AN000;
264 ; convert each to a printer box, ;AN000;
265 ; store boxes in the print buffer ;AN000;
266 ; (a buffer contains one "column" ;AN000;
267 ; of pixels). ;AN000;
268 CALL PRINT_BUFFER
; Print the buffer. ;AN000;
269 .IF <BIT ERROR_CODE NZ PRINTER_ERROR
> ;AN000;
270 .THEN
; A printer error occurred: ;AN000;
271 POP CX ; Restore scan line counter and quit ;AN000;
272 JMP PRINT_BW_APA_END
; ;AN000;
276 ;-------Get coordinates of next "column": ;AN000;
277 .IF <ROTATE_SW
EQ ON> ; If printing sideways ;AN000;
279 DEC CUR_ROW
; then, get row above on screen ;AN000;
281 INC CUR_COLUMN
; else, get column next right ;AN000;
284 LOOP PRINT_1_SCAN_COLUMN
; Print next column ;AN000;
286 POP CX ; Restore scan line counter ;AN000;
287 .ENDIF
; Endif line is not empty ;AN000;
288 ;-------------------------------------------------------------------------------;AN000;
290 ; Print a carriage return and a line feed: ;AN000;
292 ;-------------------------------------------------------------------------------;AN000;
294 CALL PRINT_BYTE
; Send CR ;AN000;
295 JC PRINT_BW_APA_END
; If printer error, leave ;AN000;
297 CALL PRINT_BYTE
; Send LF ;AN000;
298 JC PRINT_BW_APA_END
; If printer error, leave ;AN000;
299 ;-------------------------------------------------------------------------------;AN000;
301 ; Get coordinates of next scan line: ;AN000;
303 ;-------------------------------------------------------------------------------;AN000;
304 .IF <ROTATE_SW
EQ ON> ; If printing sideways ;AN000;
305 .THEN
; then: ;AN000;
306 MOV AL,NB_BOXES_PER_PRT_BUF
; AX := Numbers of pels read on row ;AN000;
308 ADD CUR_COLUMN
,AX ; CUR_COLUMN + Number of pels read ;AN000;
309 MOV AX,SCREEN_HEIGHT
; CUR_ROW := SCREEN_HEIGHT - 1 ;AN000;
311 MOV CUR_ROW
,AX ; ;AN000;
312 .ELSE ; else, printing NOT rotated: ;AN000;
313 MOV AL,NB_BOXES_PER_PRT_BUF
; AX := Number of pels read on colum;AN000;
315 ADD CUR_ROW
,AX ; CUR_ROW + Number of pels read ;AN000;
316 MOV CUR_COLUMN
,0 ; CUR_COLUMN := 0 ;AN000;
318 LOOP PRINT_1_SCAN_LINE
; ;AN000;
320 ;-------------------------------------------------------------------------------;AN000;
322 ; Restore the printer. ;AN000;
324 ;-------------------------------------------------------------------------------;AN000;
325 CALL RESTORE_PRT
;AN000;
326 PRINT_BW_APA_END: ;AN000;
331 PRINT_BW_APA ENDP
;AN000;
333 ;===============================================================================;AN000;
335 ; FILL_BUFFER : READS ENOUGH PIXELS TO FILL UP THE PRINT BUFFER. ;AN000;
336 ; THESE PIXELS ARE MAPPED TO A PRINTER DOT BOX. ;AN000;
338 ;-------------------------------------------------------------------------------;AN000;
340 ; INPUT: CUR_COLUMN, ;AN000;
341 ; CUR_ROW = Coordinates of the first pixel to be read ;AN000;
342 ; BOXES_PER_PRT_BUF = Number of boxes fitting in the print ;AN000;
344 ; XLT_TAB = Color translation table ;AN000;
346 ; OUTPUT: PRT_BUF = PRINT BUFFER ;AN000;
348 ;-------------------------------------------------------------------------------;AN000;
350 ; DESCRIPTION: ;AN000;
352 ; 1) Pixels are read one by one vertically from top to bottom in ;AN000;
353 ; the current column of the screen scan line. ;AN000;
354 ; NOTE: What is called here a 'column' can actually be a line ;AN000;
355 ; on the physical display. ;AN000;
356 ; 2) Each pixel is mapped to a printer dot box. ;AN000;
357 ; 3) Each Dot box is stored in the printer buffer. ;AN000;
358 ; 4) The coordinates in input are those of the "top" pixel ;AN000;
359 ; and restored when leaving this procedure. ;AN000;
364 ; Save coordinates of the current "column" (slice of a screen scan line) ;AN000;
365 ; DO for BOXES_PER_PRT_BUF (8 / BOX_H) ;AN000;
367 ; CALL READ_DOT ; Read a pixel, get index in XLT_TAB ;AN000;
368 ; Get pixel intensity from XLT_TAB ;AN000;
369 ; CALL INT2PAT ; Locate pattern corresponding to int. ;AN000;
370 ; CALL PAT2BOX ; Extract box from pattern ;AN000;
371 ; CALL STORE_BOX ; Store the box in the printer buffer ;AN000;
372 ; ; Get coordinates of next pixel below: ;AN000;
373 ; IF printing is sideways THEN INC CUR_COLUMN ;AN000;
374 ; ELSE INC CUR_ROW ;AN000;
376 ; Restore initial coordinates. ;AN000;
378 FILL_BUFFER PROC
NEAR ;AN000;
385 ;-------------------------------------------------------------------------------;AN000;
387 ; Save initial coordinates: ;AN000;
389 ;-------------------------------------------------------------------------------;AN000;
391 PUSH CUR_COLUMN
;AN000;
393 ;-------Clear the print buffer: ;AN000;
394 XOR BX,BX ; For each byte in the PRT_BUF: ;AN000;
395 CLEAR_PRT_BUF: ;AN000;
396 MOV PRT_BUF
[BX],0 ; Initialize byte to blanks ;AN000;
397 INC BX ; Get next byte ;AN000;
398 CMP BL,BOX_W
; All bytes cleared ? ;AN000;
399 JL CLEAR_PRT_BUF
; No, clear next one. ;AN000;
401 MOV BX,OFFSET XLT_TAB
; BX := Offset of XLT_TAB ;AN000;
403 ;-------Fill the print buffer with one box for each pixel read: ;AN000;
404 XOR CX,CX ; CL := Number of pixels to read ;AN000;
405 MOV CL,NB_BOXES_PER_PRT_BUF
;AN000;
406 ;-------------------------------------------------------------------------------;AN000;
408 ; For each pixel within the current column of the scan line: ;AN000;
410 ;-------------------------------------------------------------------------------;AN000;
411 READ_AND_STORE_1_PIXEL: ;AN000;
412 CALL READ_DOT
; AL := Index into translation table ;AN000;
413 XLAT XLT_TAB
; AL := Intensity ;AN000;
414 CALL INT2PAT
; SI := Offset of matching Pattern ;AN000;
415 CALL PAT2BOX
; Extract CUR_BOX from the pattern. ;AN000;
416 MOV SI,OFFSET CUR_BOX
; Store it in the PRT_BUF ;AN000;
417 CALL STORE_BOX
;AN000;
419 ;-------Get coordinates of next pixel: ;AN000;
420 .IF <ROTATE_SW
EQ ON> ; If printing sideways ;AN000;
422 INC CUR_COLUMN
; then, increment column number ;AN000;
424 INC CUR_ROW
; else, increment row number ;AN000;
426 LOOP READ_AND_STORE_1_PIXEL
;AN000;
428 ;-------------------------------------------------------------------------------;AN000;
430 ; Restore initial coordinates: ;AN000;
432 ;-------------------------------------------------------------------------------;AN000;
433 POP CUR_COLUMN
;AN000;
442 FILL_BUFFER ENDP
;AN000;
444 ;===============================================================================;AN000;
446 ; INT2PAT : MAP AN INTENSITY TO A PATTERN. ;AN000;
448 ;-------------------------------------------------------------------------------;AN000;
450 ; INPUT: AL = GREY INTENSITY (0 - 63 = BLACK to WHITE) ;AN000;
451 ; BOX_W = Number of columns in a box ;AN000;
452 ; CUR_MODE_PTR = Offset of current DISPLAYMODE info record ;AN000;
454 ; OUTPUT: SI = OFFSET OF THE PATTERN MATCHING THE INTENSITY ;AN000;
456 ;-------------------------------------------------------------------------------;AN000;
458 ; DESCRIPTION: Performs a sequential search in the table of patterns ;AN000;
459 ; until the proper pattern is found. ;AN000;
462 ; SI = 0 ; FOUND = FALSE ;AN000;
463 ; DO UNTIL FOUND = TRUE ;AN000;
465 ; IF AL <= Maximum intensity of the current pattern in the table ;AN000;
467 ; FOUND = TRUE ;AN000;
469 ; SI = SI + (BOX_W * 2) ;AN000;
472 INT2PAT PROC
NEAR ;AN000;
477 ;-------Calculate the size in bytes of one pattern STRUCTURE: (see GRPATTRN.STR);AN000;
478 MOV DL,BOX_W
; DX := Number of columns in the box ;AN000;
480 SHL DL,1 ; (DX * 2) = Number of columns in the pattern ;AN000;
481 INC DL ; DL := Size in bytes of one pattern ;AN000;
482 ; (includes intensity field) ;AN000;
483 MOV BX,CUR_MODE_PTR
; BX := Offset of current mode ;AN000;
484 ; SI := Offset of the first pattern ;AN000;
485 MOV SI,[BX].PATTERN_TAB_PTR
;AN000;
488 COMPARE_INTENSITY: ;AN000;
489 CMP AL,[SI] ; Within the range of this pattern ? ;AN000;
490 JLE FOUND_PATTERN
; Yes, use this pattern. ;AN000;
491 ; No, look at next pattern: ;AN000;
492 ADD SI,DX ; SI := SI + Number columns in pattern) ;AN000;
493 JMP SHORT COMPARE_INTENSITY
;AN000;
495 FOUND_PATTERN: ;AN000;
504 ;===============================================================================;AN000;
506 ; PAT2BOX : SELECT AND EXTRACT THE PROPER BOX FROM THE PATTERN ACCORDING ;AN000;
507 ; TO THE COORDINATES OF THE PIXEL. ;AN000;
509 ;-------------------------------------------------------------------------------;AN000;
511 ; INPUT: SI = OFFSET OF CURRENT PATTERN ;AN000;
512 ; CUR_COLUMN, ;AN000;
513 ; CUR_ROW = COORDINATES OF THE CURRENT PIXEL ;AN000;
515 ; OUTPUT: CUR_BOX = PORTION OF THE PATTERN TO BE PRINTED ;AN000;
517 ;-------------------------------------------------------------------------------;AN000;
519 ; DESCRIPTION: If the pixel is on even-even coordinates, then the ;AN000;
520 ; top-left box of the pattern is extracted. ;AN000;
521 ; If its Even-odd --> extract the top-right box. ;AN000;
522 ; Odd-even --> low-left box, and Odd-odd --> low-right box. ;AN000;
525 ; For example., (with a 3x2 box): ;AN000;
527 ; PATTERN (over 6 bytes): ;AN000;
530 ; byte1 byte2 byte3 byte4 byte5 byte6 ;AN000;
532 ; 0 0 0 0 0 0 ;AN000;
533 ; 0 0 0 0 0 0 ;AN000;
534 ; 0 0 0 0 0 0 ;AN000;
535 ; 0 0 0 0 0 0 ;AN000;
536 ; even-even --> dot1 dot2 dot3 | dot1 dot2 dot3 <-- even-odd ;AN000;
537 ; (row-column) dot4 dot5 dot6 | dot4 dot5 dot6 box ;AN000;
538 ; box. ------------------------------------------------ ;AN000;
539 ; odd-even --> dot1 dot2 dot3 | dot1 dot2 dot3 <-- odd-odd ;AN000;
540 ; box dot4 dot5 dot6 | dot4 dot5 dot6 box ;AN000;
543 ; The selected box is then stored as follow: ;AN000;
546 ; byte1 byte2 byte3 ;AN000;
547 ; MSB ------> 0 0 0 ;AN000;
548 ; (bit7) 0 0 0 ;AN000;
553 ; dot1 dot2 dot3 <-- box ;AN000;
554 ; LSB ------>dot4 dot5 dot6 ;AN000;
557 ; IF CUR_ROW is odd ;AN000;
558 ; THEN SI := SI + BOX_W ; Access right portion of pattern ;AN000;
559 ; Build a bit mask in BL of BOX_H bits, right justified. ;AN000;
560 ; FOR each column in the box (BOX_W) ;AN000;
561 ; Get the pattern column in AL ;AN000;
562 ; IF CUR_COLUMN is even ;AN000;
564 ; Move down the column of the top box. ;AN000;
565 ; AND BL,AL ; BL <-- Column of the desired box ;AN000;
568 PAT2BOX PROC
NEAR ;AN000;
574 ; SI := Offset of current pattern ;AN000;
575 INC SI ; Skip the MAX INTENSITY field ;AN000;
576 ;-------------------------------------------------------------------------------;AN000;
578 ; Set SI to either the left or right set of 2 boxes in the pattern: ;AN000;
580 ;-------------------------------------------------------------------------------;AN000;
581 TEST CUR_ROW
,1 ; Odd row ? ;AN000;
582 JZ EXTRACT_BOX
; No, access left portion of pattern ;AN000;
583 MOV AL,BOX_W
; ;AN000;
585 ADD SI,AX ; Yes, access right portion of pattern;AN000;
587 ;-------------------------------------------------------------------------------;AN000;
589 ; Extract the box: ;AN000;
591 ;-------------------------------------------------------------------------------;AN000;
593 ;-------Build a bit mask that will be used to keep only BOX_H bits ;AN000;
594 ;-------of the bytes where CUR_BOX is stored. ;AN000;
595 XOR AH,AH ; AH := Box column bit mask ;AN000;
596 MOV AL,BOX_H
; For each row of the box: ;AN000;
599 OR AH,1 ; Insert one bit in the mask. ;AN000;
604 XOR BX,BX ; BL := Column number within the box ;AN000;
606 ;-------For each column of the box: ;AN000;
607 EXTRACT_1_BOX_COLUMN: ;AN000;
608 MOV AL,[SI] ; AL := Current column of pattern ;AN000;
609 TEST CUR_COLUMN
,1 ; If the pixel is on ODD column ;AN000;
610 JNZ BOTTOM_BOX
; Then, need bottom box portion ;AN000;
611 MOV CL,BOX_H
; Else, need top box portion ;AN000;
612 TOP_BOX: ; Need top box: ;AN000;
613 SHR AL,CL ; Shift top box over bottom box ;AN000;
614 BOTTOM_BOX: ; The box we want is now at bottom ;AN000;
615 AND AL,AH ; Keep only bits from the box ;AN000;
616 MOV CUR_BOX
[BX],AL ; Store this box column ;AN000;
617 INC SI ; Access next column of the pattern ;AN000;
618 INC BX ; One more column stored. ;AN000;
619 CMP BL,BOX_W
; All stored ? ;AN000;
620 JL EXTRACT_1_BOX_COLUMN
; No, continue ;AN000;
628 INCLUDE GRCOMMON
.ASM
;AN000;
629 LEN_OF_BW_MODULES EQU
$-PRINT_BW_APA
;AN000;