Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

847 lines
42 KiB

  1. ;/*
  2. ; * Microsoft Confidential
  3. ; * Copyright (C) Microsoft Corporation 1988 - 1991
  4. ; * All Rights Reserved.
  5. ; */
  6. ;************************************************************
  7. ;**
  8. ;** NAME: Support for HP PCL printers added to GRAPHICS.
  9. ;**
  10. ;** DESCRIPTION: I added code to the procedures PRINT_BW_PRT and FILL_BUFFER
  11. ;** to handle the support of HP PCL printers. I used the algorithm
  12. ;** below for PRINT_BW_PRT.
  13. ;**
  14. ;** if data_type = data_row
  15. ;** if cur_scan_lne_length = 0 goto next_coordinates
  16. ;** for i:=1 to box_h
  17. ;** call new_prt_line
  18. ;** save regs.
  19. ;** save cur_row & cur_column
  20. ;** for j:=1 to cur_scan_lne_lenght/nb_boxes_per_prt_buf
  21. ;** (+1 if remainder)
  22. ;** call fill_buffer
  23. ;** call print_buffer
  24. ;** end_for
  25. ;** call end_prt_line
  26. ;** restore cur_column & cur_row
  27. ;** restore regs.
  28. ;** end_for
  29. ;** restore regs.
  30. ;** next_coordinates: if rotate_sw = on
  31. ;** inc cur_column
  32. ;** else
  33. ;** inc cur_row
  34. ;** endif
  35. ;** else
  36. ;** .
  37. ;** .
  38. ;** .
  39. ;** call end_prt_line ; Print CR & LF
  40. ;** .
  41. ;** .
  42. ;** .
  43. ;** endif
  44. ;**
  45. ;** DOCUMENTATION NOTES: This version of GRBWPRT.ASM differs from the previous
  46. ;** version only in terms of documentation.
  47. ;**
  48. ;**
  49. ;************************************************************
  50. PAGE ,132 ;AN000;
  51. TITLE DOS GRAPHICS Command - Black and White printing modules
  52. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
  53. ;; DOS - GRAPHICS Command
  54. ;;
  55. ;; ;AN000;
  56. ;; File Name: GRBWPRT.ASM ;AN000;
  57. ;; ---------- ;AN000;
  58. ;; ;AN000;
  59. ;; Description: ;AN000;
  60. ;; ------------ ;AN000;
  61. ;; This file contains the code for printing a GRAPHICS screen on a ;AN000;
  62. ;; BLACK and WHITE printer. ;AN000;
  63. ;; ;AN000;
  64. ;; Documentation Reference: ;AN000;
  65. ;; ------------------------ ;AN000;
  66. ;; OASIS High Level Design ;AN000;
  67. ;; OASIS GRAPHICS I1 Overview ;AN000;
  68. ;; ;AN000;
  69. ;; Procedures Contained in This File: ;AN000;
  70. ;; ---------------------------------- ;AN000;
  71. ;; ;AN000;
  72. ;; PRINT_BW_APA ;AN000;
  73. ;; FILL_BUFFER ;AN000;
  74. ;; INT2PAT ;AN000;
  75. ;; PAT2BOX ;AN000;
  76. ;; ;AN000;
  77. ;; ;AN000;
  78. ;; Include Files Required: ;AN000;
  79. ;; ----------------------- ;AN000;
  80. ;; GRCTRL.EXT - Externals for print screen control ;AN000;
  81. ;; GRCTRL.STR - Structures and equates for print screen control ;AN000;
  82. ;; GRPATTRN.STR - Structures for the printer patterns. ;AN000;
  83. ;; ;AN000;
  84. ;; GRSHAR.STR - Shared Data Area Structure ;AN000;
  85. ;; ;AN000;
  86. ;; STRUC.INC - Macros for using structured assembly language ;AN000;
  87. ;; ;AN000;
  88. ;; ;AN000;
  89. ;; External Procedure References: ;AN000;
  90. ;; ------------------------------ ;AN000;
  91. ;; FROM FILE GRCTRL.ASM: ;AN000;
  92. ;; PRT_SCR - Main module for printing the screen. ;AN000;
  93. ;; TO FILE GRCOMMON.ASM ;AN000;
  94. ;; Common modules - tools for printing a screen. ;AN000;
  95. ;; ;AN000;
  96. ;; Linkage Instructions: ;AN000;
  97. ;; -------------------- ;AN000;
  98. ;; This file is included by GRCTRL.ASM ;AN000;
  99. ;; ;AN000;
  100. ;; Change History: ;AN000;
  101. ;; --------------- ;AN000;
  102. ;; ;AN000;
  103. ;; ;AN000;
  104. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
  105. PAGE ;AN000;
  106. CODE SEGMENT PUBLIC 'CODE' ;AN000;
  107. ASSUME CS:CODE,DS:CODE ;AN000;
  108. ;AN000;
  109. PUBLIC PRINT_BW_APA ;AN000;
  110. PUBLIC LEN_OF_BW_MODULES ;AN000;
  111. ;AN000;
  112. .XLIST ;AN000;
  113. INCLUDE GRCTRL.STR ; Stuctures needed ;AN000;
  114. INCLUDE GRSHAR.STR ; for both set of print modules ;AN000;
  115. INCLUDE GRPATTRN.STR ; ;AN000;
  116. INCLUDE GRCTRL.EXT ; Externals from PRT_SCR control module ;AN000;
  117. INCLUDE STRUC.INC ; ;AN000;
  118. ;AN000;
  119. PUBLIC PRINT_BW_APA ; Black and white modules, ;AN000;
  120. .LIST ;AN000;
  121. ;===============================================================================;AN000;
  122. ; ;AN000;
  123. ; PRINT_BW_APA : PRINT A GRAPHIC MODE SCREEN ON A BLACK AND WHITE PRINTER ;AN000;
  124. ; ;AN000;
  125. ;-------------------------------------------------------------------------------;AN000;
  126. ; ;AN000;
  127. ; INPUT: BP = Offset of the shared data area ;AN000;
  128. ; XLT_TAB = Color translation table ;AN000;
  129. ; BIOS_INT_5H = Pointer to BIOS int 5h ;AN000;
  130. ; ;AN000;
  131. ; OUTPUT: PRINTER ;AN000;
  132. ; ;AN000;
  133. ;-------------------------------------------------------------------------------;AN000;
  134. ; ;AN000;
  135. ; DESCRIPTION: This procedure maps each pixel of the screen to a box ;AN000;
  136. ; of dots on the printer. The box size depends on the screen resolution ;AN000;
  137. ; and the number of bytes per printer line. It is chosen in order to ;AN000;
  138. ; respect the screen ratio and is documented in each printer profile. ;AN000;
  139. ; ;AN000;
  140. ; For efficiency and space considerations, the print buffer does not ;AN000;
  141. ; hold a full print line. Bytes representing pixels are printed as soon ;AN000;
  142. ; as they are ready to be printed. However, the print buffer is wide ;AN000;
  143. ; enough to hold complete boxes. ;AN000;
  144. ; ;AN000;
  145. ; The order for reading pixels off the screen is driven by the ;AN000;
  146. ; order bytes are expected by the printer. To print the screen in its ;AN000;
  147. ; original orientation we must begin reading it from the top left corner ;AN000;
  148. ; and send the pixels line by line; to print it sideways, reading will ;AN000;
  149. ; start from the bottom left corner and a "LINE" will now be a vertical ;AN000;
  150. ; screen column read from bottom to top. ;AN000;
  151. ; ;AN000;
  152. ; There is more to it however, the printer head is printing a ;AN000;
  153. ; vertical column of 8 dots at a time and each pixel read is mapped to ;AN000;
  154. ; a box of dots that is less than 8 dots high (e.g., 2 cols x 1 row) ;AN000;
  155. ; therefore, many boxes must be stored in the bytes sent to the printer. ;AN000;
  156. ; ;AN000;
  157. ; These boxes represent pixels that are one above each other on the ;AN000;
  158. ; screen. We must read enough pixels on one column of the screen to use ;AN000;
  159. ; all 8 bits of the vertical printer head (e.g., if the box size is 2x1 ;AN000;
  160. ; then 8 pixels must be read and 2 bytes of the print buffer will be ;AN000;
  161. ; filled). ;AN000;
  162. ; ;AN000;
  163. ; The PRINT BUFFER for any box size will be 8 bits high by "BOX ;AN000;
  164. ; WIDTH" bits wide. ;AN000;
  165. ; ;AN000;
  166. ; After the buffer is filled, it is printed and the next "column" ;AN000;
  167. ; of 8 pixels is read. Therefore, the screen is read "line by line" ;AN000;
  168. ; where a line is 8 pixels high for a 2x1 box (4 pixels high for a 3x2 ;AN000;
  169. ; box). ONE SUCH LINE IS CALLED A SCAN LINE. ;AN000;
  170. ; ;AN000;
  171. PAGE ;AN000;
  172. ; ;AN000;
  173. ; A 350X200 screen mapping to a 3x2 box is read in the following order: ;AN000;
  174. ; ;AN000;
  175. ; SCREEN: ;AN000;
  176. ; ;AN000;
  177. ; column column . . . column ;AN000;
  178. ; no. 0 no. 1 no. 349 ;AN000;
  179. ; ����������������������������������������ͻ ;AN000;
  180. ; scan �1(0,0) 5(0,1) 1397(0,349)� ;AN000;
  181. ; line �2(1,0) 6(1,1) . . . . . . . 1398(1,349)� ;AN000;
  182. ; no. 1 �3(2,0) 7(2,1) 1399(2,349)� ;AN000;
  183. ; �4(3,0) 8(3,1) 1400(3,349)� ;AN000;
  184. ; � � ;AN000;
  185. ; scan �1401(4,0) 1405(4,1) � LEGEND: n(X,Y) ;AN000;
  186. ; line �1402(5,0) etc, � ;AN000;
  187. ; no. 2 �1403(6,0) . . . . . � n = READ RANK ;AN000;
  188. ; �1404(7,0) � X = ROW NUMBER ;AN000;
  189. ; � . � Y = COLUMN NUMBER ;AN000;
  190. ; etc, � . � ;AN000;
  191. ; � . 70000(199,349)� ;AN000;
  192. ; ����������������������������������������ͼ ;AN000;
  193. ; ;AN000;
  194. ; ;AN000;
  195. ; LOGIC : ;AN000;
  196. ; ;AN000;
  197. ; Initialize printer and local variables. ;AN000;
  198. ; CALL LOC_MODE_PRT_INFO ; Get printer info related to current mode. ;AN000;
  199. ; CALL GET_SCREEN_INFO ; Get info. about how to read the screen ;AN000;
  200. ; CALL SETUP_PRT ; Set up the printer (Line spacing, etc) ;AN000;
  201. ; ;AN000;
  202. ; FOR each scan line on the screen (NB_SCAN_LINES) ;AN000;
  203. ; (Note: One scan line maps to one print line) ;AN000;
  204. ; BEGIN ;AN000;
  205. ; CALL DET_CUR_SCAN_LNE_LENGTH ; Determine length in pels of the current ;AN000;
  206. ; ; scan line. ;AN000;
  207. ; IF CUR_SCAN_LNE_LENGTH NE 0 THEN ;AN000;
  208. ; CALL NEW_PRT_LINE ; Initialize a new printer line ;AN000;
  209. ; DO CUR_SCAN_LNE_LENGTH times ; For each column ;AN000;
  210. ; BEGIN ;AN000;
  211. ; CALL FILL_BUFFER ; Read top-down enough pels to fill the buffer ;AN000;
  212. ; CALL PRINT_BUFFER ; Print the buffer ;AN000;
  213. ; IF printing sideways THEN INC CUR_ROW ; Get coordinates of next ;AN000;
  214. ; ELSE INC CUR_COLUMN ; "column" (vertical chunk of ;AN000;
  215. ; END (for each column) ; a scan line). ;AN000;
  216. ; PRINT_BYTE CR ; Print a CR and a LF ;AN000;
  217. ; PRINT_BYTE LF ;AN000;
  218. ; ; Get coordinates of next scan line: ;AN000;
  219. ; IF printing sideways THEN ;AN000;
  220. ; ADD CUR_COLUMN,NB_BOXES_PER_PRT_BUF ;AN000;
  221. ; MOV CUR_ROW,SCREEN_HEIGHT - 1 ;AN000;
  222. ; ELSE ;AN000;
  223. ; ADD CUR_ROW,NB_BOXES_PER_PRT_BUF ;AN000;
  224. ; MOV CUR_COLUMN,0 ;AN000;
  225. ; END (for each scan line) ;AN000;
  226. ; ;AN000;
  227. PRINT_BW_APA PROC NEAR ;AN000;
  228. PUSH AX ;AN000;
  229. PUSH BX ;AN000;
  230. PUSH CX ;AN000;
  231. ;AN000;
  232. ;-------------------------------------------------------------------------------;AN000;
  233. ; ;AN000;
  234. ; INITIALIZATION: ;AN000;
  235. ; ;AN000;
  236. ; 1) Locate and extract printer DISPLAYMODE information from ;AN000;
  237. ; the shared data area, calculate the number of boxes fitting ;AN000;
  238. ; in the printer buffer. ;AN000;
  239. ; 2) Determine where to start reading the screen: ;AN000;
  240. ; If printing sideways, start in LOW LEFT corner. ;AN000;
  241. ; If normal printing, start in TOP LEFT corner. ;AN000;
  242. ; Determine the maximum length for a scan line: ;AN000;
  243. ; If printing sideways, it is the height of the screen. ;AN000;
  244. ; For normal printing, it is the width of the screen. ;AN000;
  245. ; Determine the number of scan lines on the screen. ;AN000;
  246. ; 3) Set up the Printer for printing Graphics. ;AN000;
  247. ; ;AN000;
  248. ;-------------------------------------------------------------------------------;AN000;
  249. CALL LOC_MODE_PRT_INFO ; Get printer info related to curr. mode;AN000;
  250. ; ;AN000;
  251. ;-------Test if DISPLAYMODE info record was found: ;AN000;
  252. .IF <ERROR_CODE EQ DISPLAYMODE_INFO_NOT_FOUND> ;AN000;
  253. .THEN ;AN000;
  254. MOV ERROR_CODE,UNABLE_TO_PRINT ; IF no record found, ;AN000;
  255. JMP PRINT_BW_APA_END ; then, return error code ;AN000;
  256. .ENDIF ; and quit procedure ;AN000;
  257. ; ;AN000;
  258. ;-------Get the box size from the DISPLAYMODE info record: ;AN000;
  259. MOV BX,CUR_MODE_PTR ; BX := Offset current DISPLAYMODE info.;AN000;
  260. MOV AH,[BX].BOX_WIDTH ; Take local copy of the box size. ;AN000;
  261. MOV BOX_W,AH ; in BOX_W and BOX_H ;AN000;
  262. MOV AL,[BX].BOX_HEIGHT ;AN000;
  263. MOV BOX_H,AL ;AN000;
  264. ; ;AN000;
  265. ;-------Verify if the box size obtained from DISPLAYMODE info. is valid ;AN000;
  266. .IF <ZERO AL> OR ; IF height of the box is 0 ;AN000;
  267. .IF <ZERO AH> ; OR width of the box is 0 ;AN000;
  268. .THEN ; THEN we can't print: ;AN000;
  269. MOV ERROR_CODE,UNABLE_TO_PRINT ; return error code ;AN000;
  270. JMP PRINT_BW_APA_END ; and quit ;AN000;
  271. .ENDIF ;AN000;
  272. ; ;AN000;
  273. ;-------Get the Print Orientation from the DISPLAYMODE info record ;AN000;
  274. .IF <[BX].PRINT_OPTIONS EQ ROTATE>; If printing sideways ;AN000;
  275. .THEN ; then: ;AN000;
  276. MOV ROTATE_SW,ON ; Rotate switch := "ON" ;AN000;
  277. .ENDIF ;AN000;
  278. ;AN000;
  279. ; ;AN000;
  280. ;-------Initialize print variables and the printer: ;AN000;
  281. CALL GET_SCREEN_INFO ; Get info. about how to read the screen;AN000;
  282. CALL SETUP_PRT ; Set up the printer (Line spacing, etc);AN000;
  283. .IF <BIT ERROR_CODE NZ PRINTER_ERROR> ;AN000;
  284. .THEN ; A printer error occurred: quit ;AN000;
  285. JMP PRINT_BW_APA_END ; ;AN000;
  286. .ENDIF ;AN000;
  287. MOV CX,NB_SCAN_LINES ;AN000;
  288. ; \/ ~~mda(001) -----------------------------------------------------------------------
  289. ; Added the following modification to support printers with
  290. ; vertical print heads, such as HP PCL printers.
  291. ;
  292. ; ; .IF <DS:[BP].DATA_TYPE EQ DATA_ROW>
  293. CMP DS:[BP].DATA_TYPE,DATA_ROW ;
  294. JNE GOTO_ITS_DATA_COLUMN ;
  295. ;-------------------------------------------------------------------------------
  296. ;
  297. ; FOR EACH SCAN LINE ON THE SCREEN, WHICH REALLY IS JUST ONE LINE:
  298. ;
  299. ;-------------------------------------------------------------------------------
  300. PRINT_1_LINE_OF_BOXES: ;
  301. CALL DET_CUR_SCAN_LNE_LENGTH ; Determine how many non-blanks on line
  302. CMP CUR_SCAN_LNE_LENGTH,0 ; .IF <CUR_SCAN_LNE_LENGTH NE 0>
  303. JE GOTO_NEXT_COORDINATES ; If line is not empty then,
  304. ;
  305. PUSH CX ; Save scan line counter
  306. XOR CH,CH ; Clear register
  307. MOV CL,BOX_H ; CX is the # of times we need to read
  308. ; a line to print complete boxes.
  309. MOV DS:[BP].ROW_TO_EXTRACT,CL ; Determines what row to extract
  310. DEC DS:[BP].ROW_TO_EXTRACT ; zero based
  311. READ_LINE: ;
  312. CALL NEW_PRT_LINE ; Send escape sequence to the printer
  313. .IF <BIT ERROR_CODE NZ PRINTER_ERROR> ; for starting a new line.
  314. .THEN ; If a printer error occurred:
  315. POP CX ; Restore counter for how many times we
  316. JMP PRINT_BW_APA_END; need to read line and quit!
  317. .ENDIF ;
  318. PUSH DX ;
  319. PUSH CX ; Save counter for how many times we
  320. ; need to read line.
  321. PUSH CUR_ROW ; Save coordinates where start reading
  322. PUSH CUR_COLUMN ; line.
  323. MOV AX,CUR_SCAN_LNE_LENGTH ; DX:AX = counter for how many pixels need to
  324. CWD ; be read per line
  325. XOR BH,BH ;
  326. MOV BL,NB_BOXES_PER_PRT_BUF ;
  327. DIV BX ;
  328. .IF <DX NE 0> ; So don't lose data when
  329. INC AX ; have a remainder.
  330. .ENDIF ;
  331. MOV CX,AX ; loop CX times to read all
  332. ; pixels on scan line.
  333. JMP SHORT PRINT_1_LINE ; Jumps were out of range
  334. GOTO_NEXT_COORDINATES: ;
  335. JMP SHORT NEXT_COORDINATES ;
  336. GOTO_PRINT_1_LINE_OF_BOXES: ;
  337. JMP PRINT_1_LINE_OF_BOXES ;
  338. GOTO_ITS_DATA_COLUMN: ;
  339. JMP SHORT ITS_DATA_COLUMN ;
  340. PRINT_1_LINE: ;
  341. CALL FILL_BUFFER ; Read enough pixels to fill the buffer
  342. ; convert each to a printer box,
  343. ; extract a row from each box,
  344. ; store it in the print buffer
  345. CALL PRINT_BUFFER ; Print it
  346. .IF <BIT ERROR_CODE NZ PRINTER_ERROR> ;
  347. .THEN ; A printer error occurred:
  348. POP CUR_COLUMN ;
  349. POP CUR_ROW ;
  350. POP CX ; Restore counter for how many pixels
  351. ; needed to read per line
  352. POP DX ;
  353. POP CX ; Save scan line counter
  354. JMP PRINT_BW_APA_END ; and quit
  355. .ENDIF ;
  356. LOOP PRINT_1_LINE ; Continue reading, converting, extracting
  357. ; storing and printing.
  358. CALL END_PRT_LINE ; Send escape sequence to the printer
  359. .IF <BIT ERROR_CODE NZ PRINTER_ERROR> ; for ending a line.
  360. .THEN ; If a printer error occurred:
  361. POP CUR_COLUMN ;
  362. POP CUR_ROW ;
  363. POP CX ; Restore counter for how many times we
  364. ; needed to read per line
  365. POP DX ;
  366. POP CX ; Save scan line counter
  367. JMP PRINT_BW_APA_END; need to read line and quit!
  368. .ENDIF ;
  369. DEC DS:[BP].ROW_TO_EXTRACT ; Extract next row. Note:zero based
  370. POP CUR_COLUMN ; Restore coordinates of beginning
  371. POP CUR_ROW ; of "scan" line.
  372. POP CX ; Restore counter for how many times we
  373. ; needed to read per line
  374. POP DX ;
  375. LOOP READ_LINE ; Read the line again so we can extract
  376. ; the other rows out of the printer boxes
  377. POP CX ; Save scan line counter
  378. NEXT_COORDINATES: ; End of, if line is not empty
  379. .IF <CUR_SCAN_LNE_LENGTH EQ 0> ;
  380. CALL NEW_PRT_LINE ; Send esc. seq. to printer
  381. .ENDIF ;
  382. .IF <ROTATE_SW EQ ON> ; Get coordinates of next "scan" line
  383. .THEN ;
  384. INC CUR_COLUMN ;
  385. .ELSE ;
  386. INC CUR_ROW ;
  387. .ENDIF ;
  388. DEC CX ; Loop was out of range. Read another
  389. CMP CX,0 ; "scan" line and print the corresponding
  390. JNE GOTO_PRINT_1_LINE_OF_BOXES; printer boxes.
  391. JMP SHORT DONE_WITH_PRINTING ;
  392. ITS_DATA_COLUMN: ; .ELSE
  393. ; /\ ~~mda(001) -----------------------------------------------------------------------
  394. ;-------------------------------------------------------------------------------;AN000;
  395. ; ;AN000;
  396. ; FOR EACH SCAN LINE ON THE SCREEN: ;AN000;
  397. ; ;AN000;
  398. ;-------------------------------------------------------------------------------;AN000;
  399. PRINT_1_SCAN_LINE: ;AN000;
  400. CALL DET_CUR_SCAN_LNE_LENGTH ; Determine how many non-blanks on line ;AN000;
  401. .IF <CUR_SCAN_LNE_LENGTH NE 0> ; If line is not empty ;AN000;
  402. .THEN ; then, ;AN000;
  403. CALL NEW_PRT_LINE ; Send escape sequence to the printer ;AN000;
  404. .IF <BIT ERROR_CODE NZ PRINTER_ERROR> ; for starting a new line.;AN000;
  405. .THEN ; If a printer error occurred: ;AN000;
  406. JMP SHORT PRINT_BW_APA_END ; Quit ! ;AN000;
  407. .ENDIF ;AN000;
  408. ;AN000;
  409. PUSH CX ; Save scan line counter ;AN000;
  410. MOV CX,CUR_SCAN_LNE_LENGTH ;AN000;
  411. ;-------------------------------------------------------------------------------;AN000;
  412. ; ;AN000;
  413. ; FOR each column on the current scan line (up to the last non-blank): ;AN000;
  414. ; ;AN000;
  415. ;-------------------------------------------------------------------------------;AN000;
  416. PRINT_1_SCAN_COLUMN: ;AN000;
  417. CALL FILL_BUFFER ; Read all pixels on this column, ;AN000;
  418. ; convert each to a printer box, ;AN000;
  419. ; store boxes in the print buffer ;AN000;
  420. ; (a buffer contains one "column";AN000;
  421. ; of pixels). ;AN000;
  422. CALL PRINT_BUFFER ; Print the buffer. ;AN000;
  423. .IF <BIT ERROR_CODE NZ PRINTER_ERROR> ;AN000;
  424. .THEN ; A printer error occurred: ;AN000;
  425. POP CX ; Restore scan line counter and quit ;AN000;
  426. JMP SHORT PRINT_BW_APA_END ; ;AN000;
  427. .ENDIF ;AN000;
  428. ;AN000;
  429. ;AN000;
  430. ;-------Get coordinates of next "column": ;AN000;
  431. .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
  432. .THEN ; ;AN000;
  433. DEC CUR_ROW ; then, get row above on screen ;AN000;
  434. .ELSE ; ;AN000;
  435. INC CUR_COLUMN ; else, get column next right ;AN000;
  436. .ENDIF ; ;AN000;
  437. ;AN000;
  438. LOOP PRINT_1_SCAN_COLUMN ; Print next column ;AN000;
  439. ;AN000;
  440. POP CX ; Restore scan line counter ;AN000;
  441. .ENDIF ; Endif line is not empty ;AN000;
  442. ;-------------------------------------------------------------------------------;AN000;
  443. ; ;AN000;
  444. ; Print a carriage return and a line feed: ;AN000;
  445. ; ;AN000;
  446. ;-------------------------------------------------------------------------------;AN000;
  447. ; \/ ~~mda(001) -----------------------------------------------------------------------
  448. ; Commented out the following and replaced it with the procedure
  449. ; END_PRT_LINE because this procedure takes care of this as well
  450. ; as sending the esc. seq. that comes after the keyword DATA.
  451. ;
  452. ; MOV AL,CR ;AN000;
  453. ; CALL PRINT_BYTE ; Send CR ;AN000;
  454. ; JC PRINT_BW_APA_END ; If printer error, leave;AN000;
  455. ; MOV AL,LF ; ;AN000;
  456. ; CALL PRINT_BYTE ; Send LF ;AN000;
  457. ; JC PRINT_BW_APA_END ; If printer error, leave;AN000;
  458. ; ;
  459. CALL END_PRT_LINE ; Send escape sequence to the printer ;AN000;
  460. .IF <BIT ERROR_CODE NZ PRINTER_ERROR> ; for ending a line, and for ;AN000;
  461. ; doing a CR and LF.
  462. .THEN ; If a printer error occurred: ;AN000;
  463. JMP SHORT PRINT_BW_APA_END ; Quit ! ;AN000;
  464. .ENDIF ; ;AN000;
  465. ; /\ ~~mda(001) -----------------------------------------------------------------------
  466. JMP SHORT GET_NEXT_SCAN_LINE ;~~mda(001) Used this to replace a
  467. GOTO_PRINT_1_SCAN_LINE: ; loop that was out or range.
  468. JMP PRINT_1_SCAN_LINE ;
  469. GET_NEXT_SCAN_LINE: ;
  470. ;-------------------------------------------------------------------------------;AN000;
  471. ; ;AN000;
  472. ; Get coordinates of next scan line: ;AN000;
  473. ; ;AN000;
  474. ;-------------------------------------------------------------------------------;AN000;
  475. .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
  476. .THEN ; then: ;AN000;
  477. MOV AL,NB_BOXES_PER_PRT_BUF ; AX := Numbers of pels read on row ;AN000;
  478. CBW ; ;AN000;
  479. ADD CUR_COLUMN,AX ; CUR_COLUMN + Number of pels read ;AN000;
  480. MOV AX,SCREEN_HEIGHT ; CUR_ROW := SCREEN_HEIGHT - 1;AN000;
  481. DEC AX ; ;AN000;
  482. MOV CUR_ROW,AX ; ;AN000;
  483. .ELSE ; else, printing NOT rotated: ;AN000;
  484. MOV AL,NB_BOXES_PER_PRT_BUF ; AX := Number of pels read on colum;AN000;
  485. CBW ; ;AN000;
  486. ADD CUR_ROW,AX ; CUR_ROW + Number of pels read;AN000;
  487. MOV CUR_COLUMN,0 ; CUR_COLUMN := 0 ;AN000;
  488. .ENDIF ; ;AN000;
  489. ;; LOOP PRINT_1_SCAN_LINE ;~~mda(001) Commented it out cause loop is ;AN000;
  490. ; out of range.
  491. DEC CX ;~~mda(001) Used this instead of the LOOP
  492. OR CX,CX
  493. JNZ GOTO_PRINT_1_SCAN_LINE ;
  494. DONE_WITH_PRINTING: ;~~mda(001) Label for endif. ;AN000;
  495. ;-------------------------------------------------------------------------------;AN000;
  496. ; ;AN000;
  497. ; Restore the printer. ;AN000;
  498. ; ;AN000;
  499. ;-------------------------------------------------------------------------------;AN000;
  500. CALL RESTORE_PRT ;AN000;
  501. PRINT_BW_APA_END: ;AN000;
  502. POP CX ;AN000;
  503. POP BX ;AN000;
  504. POP AX ;AN000;
  505. RET ;AN000;
  506. PRINT_BW_APA ENDP ;AN000;
  507. PAGE ;AN000;
  508. ;===============================================================================;AN000;
  509. ; ;AN000;
  510. ; FILL_BUFFER : READS ENOUGH PIXELS TO FILL UP THE PRINT BUFFER. ;AN000;
  511. ; THESE PIXELS ARE MAPPED TO A PRINTER DOT BOX. ;AN000;
  512. ; ;AN000;
  513. ;-------------------------------------------------------------------------------;AN000;
  514. ; ;AN000;
  515. ; INPUT: CUR_COLUMN, ;AN000;
  516. ; CUR_ROW = Coordinates of the first pixel to be read ;AN000;
  517. ; BOXES_PER_PRT_BUF = Number of boxes fitting in the print ;AN000;
  518. ; buffer ;AN000;
  519. ; XLT_TAB = Color translation table ;AN000;
  520. ; ;AN000;
  521. ; OUTPUT: PRT_BUF = PRINT BUFFER ;AN000;
  522. ; ;AN000;
  523. ;-------------------------------------------------------------------------------;AN000;
  524. ; ;AN000;
  525. ; DESCRIPTION: ;AN000;
  526. ; ;AN000;
  527. ; 1) Pixels are read one by one vertically from top to bottom in ;AN000;
  528. ; the current column of the screen scan line. ;AN000;
  529. ; NOTE: What is called here a 'column' can actually be a line ;AN000;
  530. ; on the physical display. ;AN000;
  531. ; 2) Each pixel is mapped to a printer dot box. ;AN000;
  532. ; 3) Each Dot box is stored in the printer buffer. ;AN000;
  533. ; 4) The coordinates in input are those of the "top" pixel ;AN000;
  534. ; and restored when leaving this procedure. ;AN000;
  535. ; ;AN000;
  536. ; ;AN000;
  537. ; LOGIC: ;AN000;
  538. ; ;AN000;
  539. ; Save coordinates of the current "column" (slice of a screen scan line) ;AN000;
  540. ; DO for BOXES_PER_PRT_BUF (8 / BOX_H) ;AN000;
  541. ; BEGIN ;AN000;
  542. ; CALL READ_DOT ; Read a pixel, get index in XLT_TAB ;AN000;
  543. ; Get pixel intensity from XLT_TAB ;AN000;
  544. ; CALL INT2PAT ; Locate pattern corresponding to int. ;AN000;
  545. ; CALL PAT2BOX ; Extract box from pattern ;AN000;
  546. ; CALL STORE_BOX ; Store the box in the printer buffer ;AN000;
  547. ; ; Get coordinates of next pixel below: ;AN000;
  548. ; IF printing is sideways THEN INC CUR_COLUMN ;AN000;
  549. ; ELSE INC CUR_ROW ;AN000;
  550. ; END ;AN000;
  551. ; Restore initial coordinates. ;AN000;
  552. ; ;AN000;
  553. FILL_BUFFER PROC NEAR ;AN000;
  554. PUSH AX ;AN000;
  555. PUSH BX ;AN000;
  556. PUSH CX ;AN000;
  557. PUSH SI ;AN000;
  558. PUSH DI ;AN000;
  559. ;AN000;
  560. ;-------------------------------------------------------------------------------;AN000;
  561. ; ;AN000;
  562. ; Save initial coordinates: ;AN000;
  563. ; ;AN000;
  564. ;-------------------------------------------------------------------------------;AN000;
  565. ;\/ ~~mda(001) -----------------------------------------------------------------------
  566. ; If DATA_TYPE is equal to DATA_ROW then we have a horizontal
  567. ; print head so we SHOULDN'T save CUR_ROW and CUR_COLUMN because
  568. ; we are moving down the "scan" line from left to right a little
  569. ; at a time, that is we don't finish reading the scan line until
  570. ; we have made repeated calls to this procedure. Remember since
  571. ; we're dealing with horizontal print heads one scan line is
  572. ; really just one line.
  573. ; ;
  574. .IF <DS:[BP].DATA_TYPE NE DATA_ROW> ;
  575. ;
  576. PUSH CUR_ROW ;
  577. PUSH CUR_COLUMN ;
  578. .ENDIF ;
  579. ;/\ ~~mda(001) -----------------------------------------------------------------------
  580. ;-------Clear the print buffer: ;AN000;
  581. XOR BX,BX ; For each byte in the PRT_BUF: ;AN000;
  582. CLEAR_PRT_BUF: ;AN000;
  583. MOV PRT_BUF[BX],0 ; Initialize byte to blanks ;AN000;
  584. INC BX ; Get next byte ;AN000;
  585. CMP BL,BOX_W ; All bytes cleared ? ;AN000;
  586. JL CLEAR_PRT_BUF ; No, clear next one. ;AN000;
  587. ;AN000;
  588. MOV BX,OFFSET XLT_TAB ; BX := Offset of XLT_TAB ;AN000;
  589. ;AN000;
  590. ;-------Fill the print buffer with one box for each pixel read: ;AN000;
  591. XOR CX,CX ; CL := Number of pixels to read ;AN000;
  592. MOV CL,NB_BOXES_PER_PRT_BUF ;AN000;
  593. ;-------------------------------------------------------------------------------;AN000;
  594. ; ;AN000;
  595. ; For each pixel within the current column of the scan line: ;AN000;
  596. ; ;AN000;
  597. ;-------------------------------------------------------------------------------;AN000;
  598. READ_AND_STORE_1_PIXEL: ;AN000;
  599. CALL READ_DOT ; AL := Index into translation table ;AN000;
  600. XLAT XLT_TAB ; AL := Intensity ;AN000;
  601. CALL INT2PAT ; SI := Offset of matching Pattern ;AN000;
  602. CALL PAT2BOX ; Extract CUR_BOX from the pattern. ;AN000;
  603. MOV SI,OFFSET CUR_BOX ; Store it in the PRT_BUF ;AN000;
  604. CALL STORE_BOX ;AN000;
  605. ;AN000;
  606. ;-------Get coordinates of next pixel: ;AN000;
  607. ;\/ ~~mda(001) -----------------------------------------------------------------------
  608. ; If DATA_TYPE is DATA_ROW then we have a horizontal print head
  609. ; so we need to read the next pixel on the scan line. Remember
  610. ; since we're dealing with horizontal print heads one scan line
  611. ; is really just one line. For every pixel read we need to store
  612. ; one row of the corresponding box in the print buffer.
  613. ;
  614. .IF <DS:[BP].DATA_TYPE EQ DATA_ROW> ;
  615. .IF <ROTATE_SW EQ ON> ; If printing sideways
  616. .THEN ;
  617. DEC CUR_ROW ; then, decrement row number
  618. .ELSE ;
  619. INC CUR_COLUMN ; else, increment column number
  620. .ENDIF ;
  621. .ELSE ;
  622. ;/\ ~~mda(001) -----------------------------------------------------------------------
  623. .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000;
  624. .THEN ; ;AN000;
  625. INC CUR_COLUMN ; then, increment column number ;AN000;
  626. .ELSE ; ;AN000;
  627. INC CUR_ROW ; else, increment row number ;AN000;
  628. .ENDIF ; ;AN000;
  629. .ENDIF ; ~~mda(001) Close IF stmt.
  630. LOOP READ_AND_STORE_1_PIXEL ;AN000;
  631. ;AN000;
  632. ;-------------------------------------------------------------------------------;AN000;
  633. ; ;AN000;
  634. ; Restore initial coordinates: ;AN000;
  635. ; ;AN000;
  636. ;-------------------------------------------------------------------------------;AN000;
  637. ;\/ ~~mda(001) -----------------------------------------------------------------------
  638. ; If DATA_TYPE = DATA_ROW then we don't restore initial coordinates.
  639. ;
  640. .IF <DS:[BP].DATA_TYPE NE DATA_ROW> ;
  641. POP CUR_COLUMN ;
  642. POP CUR_ROW ;
  643. .ENDIF ;
  644. ;/\ ~~mda(001) -----------------------------------------------------------------------
  645. ;AN000;
  646. POP DI ;AN000;
  647. POP SI ;AN000;
  648. POP CX ;AN000;
  649. POP BX ;AN000;
  650. POP AX ;AN000;
  651. RET ;AN000;
  652. FILL_BUFFER ENDP ;AN000;
  653. PAGE ;AN000;
  654. ;===============================================================================;AN000;
  655. ; ;AN000;
  656. ; INT2PAT : MAP AN INTENSITY TO A PATTERN. ;AN000;
  657. ; ;AN000;
  658. ;-------------------------------------------------------------------------------;AN000;
  659. ; ;AN000;
  660. ; INPUT: AL = GREY INTENSITY (0 - 63 = BLACK to WHITE) ;AN000;
  661. ; BOX_W = Number of columns in a box ;AN000;
  662. ; CUR_MODE_PTR = Offset of current DISPLAYMODE info record ;AN000;
  663. ; ;AN000;
  664. ; OUTPUT: SI = OFFSET OF THE PATTERN MATCHING THE INTENSITY ;AN000;
  665. ; ;AN000;
  666. ;-------------------------------------------------------------------------------;AN000;
  667. ; ;AN000;
  668. ; DESCRIPTION: Performs a sequential search in the table of patterns ;AN000;
  669. ; until the proper pattern is found. ;AN000;
  670. ; ;AN000;
  671. ; ;AN000;
  672. ; SI = 0 ; FOUND = FALSE ;AN000;
  673. ; DO UNTIL FOUND = TRUE ;AN000;
  674. ; BEGIN ;AN000;
  675. ; IF AL <= Maximum intensity of the current pattern in the table ;AN000;
  676. ; THEN ;AN000;
  677. ; FOUND = TRUE ;AN000;
  678. ; ELSE ;AN000;
  679. ; SI = SI + (BOX_W * 2) ;AN000;
  680. ; END ;AN000;
  681. ; ;AN000;
  682. INT2PAT PROC NEAR ;AN000;
  683. PUSH AX ;AN000;
  684. PUSH BX ;AN000;
  685. PUSH DX ;AN000;
  686. ;AN000;
  687. ;-------Calculate the size in bytes of one pattern STRUCTURE: (see GRPATTRN.STR);AN000;
  688. MOV DL,BOX_W ; DX := Number of columns in the box ;AN000;
  689. XOR DH,DH ;AN000;
  690. SHL DL,1 ; (DX * 2) = Number of columns in the pattern ;AN000;
  691. INC DL ; DL := Size in bytes of one pattern ;AN000;
  692. ; (includes intensity field) ;AN000;
  693. MOV BX,CUR_MODE_PTR ; BX := Offset of current mode ;AN000;
  694. ; SI := Offset of the first pattern ;AN000;
  695. MOV SI,[BX].PATTERN_TAB_PTR ;AN000;
  696. ADD SI,BP ;AN000;
  697. ;AN000;
  698. COMPARE_INTENSITY: ;AN000;
  699. CMP AL,[SI] ; Within the range of this pattern ? ;AN000;
  700. JLE FOUND_PATTERN ; Yes, use this pattern. ;AN000;
  701. ; No, look at next pattern: ;AN000;
  702. ADD SI,DX ; SI := SI + Number columns in pattern) ;AN000;
  703. JMP SHORT COMPARE_INTENSITY ;AN000;
  704. ;AN000;
  705. FOUND_PATTERN: ;AN000;
  706. ;AN000;
  707. POP DX ;AN000;
  708. POP BX ;AN000;
  709. POP AX ;AN000;
  710. RET ;AN000;
  711. ;AN000;
  712. INT2PAT ENDP ;AN000;
  713. PAGE ;AN000;
  714. ;===============================================================================;AN000;
  715. ; ;AN000;
  716. ; PAT2BOX : SELECT AND EXTRACT THE PROPER BOX FROM THE PATTERN ACCORDING ;AN000;
  717. ; TO THE COORDINATES OF THE PIXEL. ;AN000;
  718. ; ;AN000;
  719. ;-------------------------------------------------------------------------------;AN000;
  720. ; ;AN000;
  721. ; INPUT: SI = OFFSET OF CURRENT PATTERN ;AN000;
  722. ; CUR_COLUMN, ;AN000;
  723. ; CUR_ROW = COORDINATES OF THE CURRENT PIXEL ;AN000;
  724. ; ;AN000;
  725. ; OUTPUT: CUR_BOX = PORTION OF THE PATTERN TO BE PRINTED ;AN000;
  726. ; ;AN000;
  727. ;-------------------------------------------------------------------------------;AN000;
  728. ; ;AN000;
  729. ; DESCRIPTION: If the pixel is on even-even coordinates, then the ;AN000;
  730. ; top-left box of the pattern is extracted. ;AN000;
  731. ; If its Even-odd --> extract the top-right box. ;AN000;
  732. ; Odd-even --> low-left box, and Odd-odd --> low-right box. ;AN000;
  733. ; ;AN000;
  734. PAGE ;AN000;
  735. ; For example., (with a 3x2 box): ;AN000;
  736. ; ;AN000;
  737. ; PATTERN (over 6 bytes): ;AN000;
  738. ; ;AN000;
  739. ; ;AN000;
  740. ; byte1 byte2 byte3 byte4 byte5 byte6 ;AN000;
  741. ; ;AN000;
  742. ; 0 0 0 0 0 0 ;AN000;
  743. ; 0 0 0 0 0 0 ;AN000;
  744. ; 0 0 0 0 0 0 ;AN000;
  745. ; 0 0 0 0 0 0 ;AN000;
  746. ; even-even --> dot1 dot2 dot3 | dot1 dot2 dot3 <-- even-odd ;AN000;
  747. ; (row-column) dot4 dot5 dot6 | dot4 dot5 dot6 box ;AN000;
  748. ; box. ------------------------------------------------ ;AN000;
  749. ; odd-even --> dot1 dot2 dot3 | dot1 dot2 dot3 <-- odd-odd ;AN000;
  750. ; box dot4 dot5 dot6 | dot4 dot5 dot6 box ;AN000;
  751. ; ;AN000;
  752. ; ;AN000;
  753. ; The selected box is then stored as follow: ;AN000;
  754. ; ;AN000;
  755. ; CUR_BOX: ;AN000;
  756. ; byte1 byte2 byte3 ;AN000;
  757. ; MSB ------> 0 0 0 ;AN000;
  758. ; (bit7) 0 0 0 ;AN000;
  759. ; 0 0 0 ;AN000;
  760. ; 0 0 0 ;AN000;
  761. ; 0 0 0 ;AN000;
  762. ; 0 0 0 ;AN000;
  763. ; dot1 dot2 dot3 <-- box ;AN000;
  764. ; LSB ------>dot4 dot5 dot6 ;AN000;
  765. ; ;AN000;
  766. ; LOGIC: ;AN000;
  767. ; IF CUR_ROW is odd ;AN000;
  768. ; THEN SI := SI + BOX_W ; Access right portion of pattern ;AN000;
  769. ; Build a bit mask in BL of BOX_H bits, right justified. ;AN000;
  770. ; FOR each column in the box (BOX_W) ;AN000;
  771. ; Get the pattern column in AL ;AN000;
  772. ; IF CUR_COLUMN is even ;AN000;
  773. ; THEN ;AN000;
  774. ; Move down the column of the top box. ;AN000;
  775. ; AND BL,AL ; BL <-- Column of the desired box ;AN000;
  776. ; ;AN000;
  777. ; ;AN000;
  778. PAT2BOX PROC NEAR ;AN000;
  779. PUSH AX ;AN000;
  780. PUSH BX ;AN000;
  781. PUSH CX ;AN000;
  782. PUSH SI ;AN000;
  783. ;AN000;
  784. ; SI := Offset of current pattern ;AN000;
  785. INC SI ; Skip the MAX INTENSITY field ;AN000;
  786. ;-------------------------------------------------------------------------------;AN000;
  787. ; ;AN000;
  788. ; Set SI to either the left or right set of 2 boxes in the pattern: ;AN000;
  789. ; ;AN000;
  790. ;-------------------------------------------------------------------------------;AN000;
  791. TEST CUR_ROW,1 ; Odd row ? ;AN000;
  792. JZ EXTRACT_BOX ; No, access left portion of pattern ;AN000;
  793. MOV AL,BOX_W ; ;AN000;
  794. CBW ; ;AN000;
  795. ADD SI,AX ; Yes, access right portion of pattern;AN000;
  796. ;AN000;
  797. ;-------------------------------------------------------------------------------;AN000;
  798. ; ;AN000;
  799. ; Extract the box: ;AN000;
  800. ; ;AN000;
  801. ;-------------------------------------------------------------------------------;AN000;
  802. EXTRACT_BOX: ;AN000;
  803. ;-------Build a bit mask that will be used to keep only BOX_H bits ;AN000;
  804. ;-------of the bytes where CUR_BOX is stored. ;AN000;
  805. XOR AH,AH ; AH := Box column bit mask ;AN000;
  806. MOV AL,BOX_H ; For each row of the box: ;AN000;
  807. INIT_MASK: ; ;AN000;
  808. SHL AH,1 ; ;AN000;
  809. OR AH,1 ; Insert one bit in the mask. ;AN000;
  810. DEC AL ; ;AN000;
  811. CMP AL,0 ; ;AN000;
  812. JG INIT_MASK ;AN000;
  813. ;AN000;
  814. XOR BX,BX ; BL := Column number within the box ;AN000;
  815. ; ;AN000;
  816. ;-------For each column of the box: ;AN000;
  817. EXTRACT_1_BOX_COLUMN: ;AN000;
  818. MOV AL,[SI] ; AL := Current column of pattern ;AN000;
  819. TEST CUR_COLUMN,1 ; If the pixel is on ODD column ;AN000;
  820. JNZ BOTTOM_BOX ; Then, need bottom box portion ;AN000;
  821. MOV CL,BOX_H ; Else, need top box portion ;AN000;
  822. TOP_BOX: ; Need top box: ;AN000;
  823. SHR AL,CL ; Shift top box over bottom box ;AN000;
  824. BOTTOM_BOX: ; The box we want is now at bottom ;AN000;
  825. AND AL,AH ; Keep only bits from the box ;AN000;
  826. MOV CUR_BOX[BX],AL ; Store this box column ;AN000;
  827. INC SI ; Access next column of the pattern ;AN000;
  828. INC BX ; One more column stored. ;AN000;
  829. CMP BL,BOX_W ; All stored ? ;AN000;
  830. JL EXTRACT_1_BOX_COLUMN ; No, continue ;AN000;
  831. ;AN000;
  832. POP SI ;AN000;
  833. POP CX ;AN000;
  834. POP BX ;AN000;
  835. POP AX ;AN000;
  836. RET ;AN000;
  837. PAT2BOX ENDP ;AN000;
  838. INCLUDE GRCOMMON.ASM ;AN000;
  839. LEN_OF_BW_MODULES EQU $-PRINT_BW_APA ;AN000;
  840. CODE ENDS ;AN000;
  841. END ;AN000;
  842.