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