summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/GRAPHICS/GRBWPRT.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/GRAPHICS/GRBWPRT.ASM')
-rw-r--r--v4.0/src/CMD/GRAPHICS/GRBWPRT.ASM631
1 files changed, 631 insertions, 0 deletions
diff --git a/v4.0/src/CMD/GRAPHICS/GRBWPRT.ASM b/v4.0/src/CMD/GRAPHICS/GRBWPRT.ASM
new file mode 100644
index 0000000..7b09ffd
--- /dev/null
+++ b/v4.0/src/CMD/GRAPHICS/GRBWPRT.ASM
@@ -0,0 +1,631 @@
1 PAGE ,132 ;AN000;
2 TITLE DOS GRAPHICS Command - Black and White printing modules
3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
4;; DOS - GRAPHICS Command
5;; (c) Copyright 1988 Microsoft
6;; ;AN000;
7;; File Name: GRBWPRT.ASM ;AN000;
8;; ---------- ;AN000;
9;; ;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;
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_BW_APA ;AN000;
24;; FILL_BUFFER ;AN000;
25;; INT2PAT ;AN000;
26;; PAT2BOX ;AN000;
27;; ;AN000;
28;; ;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;
34;; ;AN000;
35;; GRSHAR.STR - Shared Data Area Structure ;AN000;
36;; ;AN000;
37;; STRUC.INC - Macros for using structured assembly language ;AN000;
38;; ;AN000;
39;; ;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;
46;; ;AN000;
47;; Linkage Instructions: ;AN000;
48;; -------------------- ;AN000;
49;; This file is included by GRCTRL.ASM ;AN000;
50;; ;AN000;
51;; Change History: ;AN000;
52;; --------------- ;AN000;
53;; ;AN000;
54;; ;AN000;
55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
56PAGE ;AN000;
57CODE SEGMENT PUBLIC 'CODE' ;AN000;
58 ASSUME CS:CODE,DS:CODE ;AN000;
59 ;AN000;
60 PUBLIC PRINT_BW_APA ;AN000;
61 PUBLIC LEN_OF_BW_MODULES ;AN000;
62 ;AN000;
63.XLIST ;AN000;
64INCLUDE GRCTRL.STR ; Stuctures needed ;AN000;
65INCLUDE GRSHAR.STR ; for both set of print modules ;AN000;
66INCLUDE GRPATTRN.STR ; ;AN000;
67INCLUDE GRCTRL.EXT ; Externals from PRT_SCR control module ;AN000;
68INCLUDE STRUC.INC ; ;AN000;
69 ;AN000;
70 PUBLIC PRINT_BW_APA ; Black and white modules, ;AN000;
71.LIST ;AN000;
72;===============================================================================;AN000;
73; ;AN000;
74; PRINT_BW_APA : PRINT A GRAPHIC MODE SCREEN ON A BLACK AND WHITE PRINTER ;AN000;
75; ;AN000;
76;-------------------------------------------------------------------------------;AN000;
77; ;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;
81; ;AN000;
82; OUTPUT: PRINTER ;AN000;
83; ;AN000;
84;-------------------------------------------------------------------------------;AN000;
85; ;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;
90; ;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;
95; ;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;
102; ;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;
107; ;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;
112; filled). ;AN000;
113; ;AN000;
114; The PRINT BUFFER for any box size will be 8 bits high by "BOX ;AN000;
115; WIDTH" bits wide. ;AN000;
116; ;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;
121; ;AN000;
122PAGE ;AN000;
123; ;AN000;
124; A 350X200 screen mapping to a 3x2 box is read in the following order: ;AN000;
125; ;AN000;
126; SCREEN: ;AN000;
127; ;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;
135; º º ;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;
141; etc, º . º ;AN000;
142; º . 70000(199,349)º ;AN000;
143; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ;AN000;
144; ;AN000;
145; ;AN000;
146; LOGIC : ;AN000;
147; ;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;
152; ;AN000;
153; FOR each scan line on the screen (NB_SCAN_LINES) ;AN000;
154; (Note: One scan line maps to one print line) ;AN000;
155; BEGIN ;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;
161; BEGIN ;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;
173; ELSE ;AN000;
174; ADD CUR_ROW,NB_BOXES_PER_PRT_BUF ;AN000;
175; MOV CUR_COLUMN,0 ;AN000;
176; END (for each scan line) ;AN000;
177; ;AN000;
178PRINT_BW_APA PROC NEAR ;AN000;
179 PUSH AX ;AN000;
180 PUSH BX ;AN000;
181 PUSH CX ;AN000;
182 ;AN000;
183;-------------------------------------------------------------------------------;AN000;
184; ;AN000;
185; INITIALIZATION: ;AN000;
186; ;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;
198; ;AN000;
199;-------------------------------------------------------------------------------;AN000;
200 CALL LOC_MODE_PRT_INFO ; Get printer info related to curr. mode;AN000;
201; ;AN000;
202;-------Test if DISPLAYMODE info record was found: ;AN000;
203 .IF <ERROR_CODE EQ DISPLAYMODE_INFO_NOT_FOUND> ;AN000;
204 .THEN ;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;
208; ;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;
214 MOV BOX_H,AL ;AN000;
215; ;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;
222 .ENDIF ;AN000;
223; ;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;
228 .ENDIF ;AN000;
229 ;AN000;
230; ;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;
237 .ENDIF ;AN000;
238 ;AN000;
239 MOV CX,NB_SCAN_LINES ;AN000;
240;-------------------------------------------------------------------------------;AN000;
241; ;AN000;
242; FOR EACH SCAN LINE ON THE SCREEN: ;AN000;
243; ;AN000;
244;-------------------------------------------------------------------------------;AN000;
245PRINT_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;
253 .ENDIF ;AN000;
254 ;AN000;
255 PUSH CX ; Save scan line counter ;AN000;
256 MOV CX,CUR_SCAN_LNE_LENGTH ;AN000;
257;-------------------------------------------------------------------------------;AN000;
258; ;AN000;
259; FOR each column on the current scan line (up to the last non-blank): ;AN000;
260; ;AN000;
261;-------------------------------------------------------------------------------;AN000;
262PRINT_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;
273 .ENDIF ;AN000;
274 ;AN000;
275 ;AN000;
276;-------Get coordinates of next "column": ;AN000;
277 .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
278 .THEN ; ;AN000;
279 DEC CUR_ROW ; then, get row above on screen ;AN000;
280 .ELSE ; ;AN000;
281 INC CUR_COLUMN ; else, get column next right ;AN000;
282 .ENDIF ; ;AN000;
283 ;AN000;
284 LOOP PRINT_1_SCAN_COLUMN ; Print next column ;AN000;
285 ;AN000;
286 POP CX ; Restore scan line counter ;AN000;
287.ENDIF ; Endif line is not empty ;AN000;
288;-------------------------------------------------------------------------------;AN000;
289; ;AN000;
290; Print a carriage return and a line feed: ;AN000;
291; ;AN000;
292;-------------------------------------------------------------------------------;AN000;
293 MOV AL,CR ;AN000;
294 CALL PRINT_BYTE ; Send CR ;AN000;
295 JC PRINT_BW_APA_END ; If printer error, leave ;AN000;
296 MOV AL,LF ;AN000;
297 CALL PRINT_BYTE ; Send LF ;AN000;
298 JC PRINT_BW_APA_END ; If printer error, leave ;AN000;
299;-------------------------------------------------------------------------------;AN000;
300; ;AN000;
301; Get coordinates of next scan line: ;AN000;
302; ;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;
307 CBW ; ;AN000;
308 ADD CUR_COLUMN,AX ; CUR_COLUMN + Number of pels read ;AN000;
309 MOV AX,SCREEN_HEIGHT ; CUR_ROW := SCREEN_HEIGHT - 1 ;AN000;
310 DEC AX ; ;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;
314 CBW ; ;AN000;
315 ADD CUR_ROW,AX ; CUR_ROW + Number of pels read ;AN000;
316 MOV CUR_COLUMN,0 ; CUR_COLUMN := 0 ;AN000;
317 .ENDIF ; ;AN000;
318 LOOP PRINT_1_SCAN_LINE ; ;AN000;
319 ;AN000;
320;-------------------------------------------------------------------------------;AN000;
321; ;AN000;
322; Restore the printer. ;AN000;
323; ;AN000;
324;-------------------------------------------------------------------------------;AN000;
325 CALL RESTORE_PRT ;AN000;
326PRINT_BW_APA_END: ;AN000;
327 POP CX ;AN000;
328 POP BX ;AN000;
329 POP AX ;AN000;
330 RET ;AN000;
331PRINT_BW_APA ENDP ;AN000;
332PAGE ;AN000;
333;===============================================================================;AN000;
334; ;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;
337; ;AN000;
338;-------------------------------------------------------------------------------;AN000;
339; ;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;
343; buffer ;AN000;
344; XLT_TAB = Color translation table ;AN000;
345; ;AN000;
346; OUTPUT: PRT_BUF = PRINT BUFFER ;AN000;
347; ;AN000;
348;-------------------------------------------------------------------------------;AN000;
349; ;AN000;
350; DESCRIPTION: ;AN000;
351; ;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;
360; ;AN000;
361; ;AN000;
362; LOGIC: ;AN000;
363; ;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;
366; BEGIN ;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;
375; END ;AN000;
376; Restore initial coordinates. ;AN000;
377; ;AN000;
378FILL_BUFFER PROC NEAR ;AN000;
379 PUSH AX ;AN000;
380 PUSH BX ;AN000;
381 PUSH CX ;AN000;
382 PUSH SI ;AN000;
383 PUSH DI ;AN000;
384 ;AN000;
385;-------------------------------------------------------------------------------;AN000;
386; ;AN000;
387; Save initial coordinates: ;AN000;
388; ;AN000;
389;-------------------------------------------------------------------------------;AN000;
390 PUSH CUR_ROW ;AN000;
391 PUSH CUR_COLUMN ;AN000;
392 ;AN000;
393;-------Clear the print buffer: ;AN000;
394 XOR BX,BX ; For each byte in the PRT_BUF: ;AN000;
395CLEAR_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;
400 ;AN000;
401 MOV BX,OFFSET XLT_TAB ; BX := Offset of XLT_TAB ;AN000;
402 ;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;
407; ;AN000;
408; For each pixel within the current column of the scan line: ;AN000;
409; ;AN000;
410;-------------------------------------------------------------------------------;AN000;
411READ_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;
418 ;AN000;
419;-------Get coordinates of next pixel: ;AN000;
420 .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
421 .THEN ; ;AN000;
422 INC CUR_COLUMN ; then, increment column number ;AN000;
423 .ELSE ; ;AN000;
424 INC CUR_ROW ; else, increment row number ;AN000;
425 .ENDIF ; ;AN000;
426 LOOP READ_AND_STORE_1_PIXEL ;AN000;
427 ;AN000;
428;-------------------------------------------------------------------------------;AN000;
429; ;AN000;
430; Restore initial coordinates: ;AN000;
431; ;AN000;
432;-------------------------------------------------------------------------------;AN000;
433 POP CUR_COLUMN ;AN000;
434 POP CUR_ROW ;AN000;
435 ;AN000;
436 POP DI ;AN000;
437 POP SI ;AN000;
438 POP CX ;AN000;
439 POP BX ;AN000;
440 POP AX ;AN000;
441 RET ;AN000;
442FILL_BUFFER ENDP ;AN000;
443PAGE ;AN000;
444;===============================================================================;AN000;
445; ;AN000;
446; INT2PAT : MAP AN INTENSITY TO A PATTERN. ;AN000;
447; ;AN000;
448;-------------------------------------------------------------------------------;AN000;
449; ;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;
453; ;AN000;
454; OUTPUT: SI = OFFSET OF THE PATTERN MATCHING THE INTENSITY ;AN000;
455; ;AN000;
456;-------------------------------------------------------------------------------;AN000;
457; ;AN000;
458; DESCRIPTION: Performs a sequential search in the table of patterns ;AN000;
459; until the proper pattern is found. ;AN000;
460; ;AN000;
461; ;AN000;
462; SI = 0 ; FOUND = FALSE ;AN000;
463; DO UNTIL FOUND = TRUE ;AN000;
464; BEGIN ;AN000;
465; IF AL <= Maximum intensity of the current pattern in the table ;AN000;
466; THEN ;AN000;
467; FOUND = TRUE ;AN000;
468; ELSE ;AN000;
469; SI = SI + (BOX_W * 2) ;AN000;
470; END ;AN000;
471; ;AN000;
472INT2PAT PROC NEAR ;AN000;
473 PUSH AX ;AN000;
474 PUSH BX ;AN000;
475 PUSH DX ;AN000;
476 ;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;
479 XOR DH,DH ;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;
486 ADD SI,BP ;AN000;
487 ;AN000;
488COMPARE_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;
494 ;AN000;
495FOUND_PATTERN: ;AN000;
496 ;AN000;
497 POP DX ;AN000;
498 POP BX ;AN000;
499 POP AX ;AN000;
500 RET ;AN000;
501 ;AN000;
502INT2PAT ENDP ;AN000;
503PAGE ;AN000;
504;===============================================================================;AN000;
505; ;AN000;
506; PAT2BOX : SELECT AND EXTRACT THE PROPER BOX FROM THE PATTERN ACCORDING ;AN000;
507; TO THE COORDINATES OF THE PIXEL. ;AN000;
508; ;AN000;
509;-------------------------------------------------------------------------------;AN000;
510; ;AN000;
511; INPUT: SI = OFFSET OF CURRENT PATTERN ;AN000;
512; CUR_COLUMN, ;AN000;
513; CUR_ROW = COORDINATES OF THE CURRENT PIXEL ;AN000;
514; ;AN000;
515; OUTPUT: CUR_BOX = PORTION OF THE PATTERN TO BE PRINTED ;AN000;
516; ;AN000;
517;-------------------------------------------------------------------------------;AN000;
518; ;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;
523; ;AN000;
524PAGE ;AN000;
525; For example., (with a 3x2 box): ;AN000;
526; ;AN000;
527; PATTERN (over 6 bytes): ;AN000;
528; ;AN000;
529; ;AN000;
530; byte1 byte2 byte3 byte4 byte5 byte6 ;AN000;
531; ;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;
541; ;AN000;
542; ;AN000;
543; The selected box is then stored as follow: ;AN000;
544; ;AN000;
545; CUR_BOX: ;AN000;
546; byte1 byte2 byte3 ;AN000;
547; MSB ------> 0 0 0 ;AN000;
548; (bit7) 0 0 0 ;AN000;
549; 0 0 0 ;AN000;
550; 0 0 0 ;AN000;
551; 0 0 0 ;AN000;
552; 0 0 0 ;AN000;
553; dot1 dot2 dot3 <-- box ;AN000;
554; LSB ------>dot4 dot5 dot6 ;AN000;
555; ;AN000;
556; LOGIC: ;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;
563; THEN ;AN000;
564; Move down the column of the top box. ;AN000;
565; AND BL,AL ; BL <-- Column of the desired box ;AN000;
566; ;AN000;
567; ;AN000;
568PAT2BOX PROC NEAR ;AN000;
569 PUSH AX ;AN000;
570 PUSH BX ;AN000;
571 PUSH CX ;AN000;
572 PUSH SI ;AN000;
573 ;AN000;
574 ; SI := Offset of current pattern ;AN000;
575 INC SI ; Skip the MAX INTENSITY field ;AN000;
576;-------------------------------------------------------------------------------;AN000;
577; ;AN000;
578; Set SI to either the left or right set of 2 boxes in the pattern: ;AN000;
579; ;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;
584 CBW ; ;AN000;
585 ADD SI,AX ; Yes, access right portion of pattern;AN000;
586 ;AN000;
587;-------------------------------------------------------------------------------;AN000;
588; ;AN000;
589; Extract the box: ;AN000;
590; ;AN000;
591;-------------------------------------------------------------------------------;AN000;
592EXTRACT_BOX: ;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;
597INIT_MASK: ; ;AN000;
598 SHL AH,1 ; ;AN000;
599 OR AH,1 ; Insert one bit in the mask. ;AN000;
600 DEC AL ; ;AN000;
601 CMP AL,0 ; ;AN000;
602 JG INIT_MASK ;AN000;
603 ;AN000;
604 XOR BX,BX ; BL := Column number within the box ;AN000;
605; ;AN000;
606;-------For each column of the box: ;AN000;
607EXTRACT_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;
612TOP_BOX: ; Need top box: ;AN000;
613 SHR AL,CL ; Shift top box over bottom box ;AN000;
614BOTTOM_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;
621 ;AN000;
622 POP SI ;AN000;
623 POP CX ;AN000;
624 POP BX ;AN000;
625 POP AX ;AN000;
626 RET ;AN000;
627PAT2BOX ENDP ;AN000;
628INCLUDE GRCOMMON.ASM ;AN000;
629LEN_OF_BW_MODULES EQU $-PRINT_BW_APA ;AN000;
630CODE ENDS ;AN000;
631 END ;AN000;