diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/GRAPHICS/GRCOMMON.ASM | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/CMD/GRAPHICS/GRCOMMON.ASM')
| -rw-r--r-- | v4.0/src/CMD/GRAPHICS/GRCOMMON.ASM | 858 |
1 files changed, 858 insertions, 0 deletions
diff --git a/v4.0/src/CMD/GRAPHICS/GRCOMMON.ASM b/v4.0/src/CMD/GRAPHICS/GRCOMMON.ASM new file mode 100644 index 0000000..56d1b08 --- /dev/null +++ b/v4.0/src/CMD/GRAPHICS/GRCOMMON.ASM | |||
| @@ -0,0 +1,858 @@ | |||
| 1 | PAGE ,132 ;AN000; | ||
| 2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 3 | ;; DOS - GRAPHICS Command | ||
| 4 | ;; (c) Copyright 1988 Microsoft | ||
| 5 | ;; ;AN000; | ||
| 6 | ;; File Name: GRCOMMON.ASM ;AN000; | ||
| 7 | ;; ---------- ;AN000; | ||
| 8 | ;; ;AN000; | ||
| 9 | ;; Description: ;AN000; | ||
| 10 | ;; ------------ ;AN000; | ||
| 11 | ;; ;AN000; | ||
| 12 | ;; This file contains the modules common to the Print Screen ;AN000; | ||
| 13 | ;; process of GRAPHICS.COM. ;AN000; | ||
| 14 | ;; This file is included by both set of Print modules. ;AN000; | ||
| 15 | ;; ;AN000; | ||
| 16 | ;; This file MUST BE COMPILED WITH EACH SET OF MODULES since, ;AN000; | ||
| 17 | ;; one set is relocated in memory at installation time; all ;AN000; | ||
| 18 | ;; references to the common procedures must be resolved from ;AN000; | ||
| 19 | ;; within each set of print modules. ;AN000; | ||
| 20 | ;; ;AN000; | ||
| 21 | ;; The set of common modules is relocated in memory along with ;AN000; | ||
| 22 | ;; the selected set of print modules. ;AN000; | ||
| 23 | ;; ;AN000; | ||
| 24 | ;; Documentation Reference: ;AN000; | ||
| 25 | ;; ------------------------ ;AN000; | ||
| 26 | ;; OASIS High Level Design ;AN000; | ||
| 27 | ;; OASIS GRAPHICS I1 Overview ;AN000; | ||
| 28 | ;; ;AN000; | ||
| 29 | ;; Procedures Contained in This File: ;AN000; | ||
| 30 | ;; ---------------------------------- ;AN000; | ||
| 31 | ;; READ_DOT ;AN000; | ||
| 32 | ;; LOC_MODE_PRT_INFO ;AN000; | ||
| 33 | ;; STORE_BOX ;AN000; | ||
| 34 | ;; PRINT_BUFFER ;AN000; | ||
| 35 | ;; GET_SCREEN_INFO ;AN000; | ||
| 36 | ;; SETUP_PRT ;AN000; | ||
| 37 | ;; RESTORE_PRT ;AN000; | ||
| 38 | ;; NEW_PRT_LINE ;AN000; | ||
| 39 | ;; PRINT_BYTE ;AN000; | ||
| 40 | ;; DET_CUR_SCAN_LNE_LENGTH ;AN000; | ||
| 41 | ;; ;AN000; | ||
| 42 | ;; Include Files Required: ;AN000; | ||
| 43 | ;; ----------------------- ;AN000; | ||
| 44 | ;; none ;AN000; | ||
| 45 | ;; ;AN000; | ||
| 46 | ;; External Procedure References: ;AN000; | ||
| 47 | ;; ------------------------------ ;AN000; | ||
| 48 | ;; FROM FILE GRCTRL.ASM: ;AN000; | ||
| 49 | ;; PRT_SCR - Main module for printing the screen. ;AN000; | ||
| 50 | ;; FROM FILE GRBWPRT.ASM: ;AN000; | ||
| 51 | ;; PRT_BW_APA - Main module for printing on BW printer. ;AN000; | ||
| 52 | ;; FROM FILE GRCOLPRT.ASM: ;AN000; | ||
| 53 | ;; PRINT_COLOR - Main module for printing on COLOR printer. ;AN000; | ||
| 54 | ;; ;AN000; | ||
| 55 | ;; Linkage Instructions: ;AN000; | ||
| 56 | ;; -------------------- ;AN000; | ||
| 57 | ;; ;AN000; | ||
| 58 | ;; This file is included by both GRBWPRT.ASM and GRCOLPRT.ASM and is ;AN000; | ||
| 59 | ;; compiled with each of them. However, only one copy is made resident. ;AN000; | ||
| 60 | ;; ;AN000; | ||
| 61 | ;; Change History: ;AN000; | ||
| 62 | ;; --------------- ;AN000; | ||
| 63 | ;; ;AN000; | ||
| 64 | ;; ;AN000; | ||
| 65 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 66 | ;AN000; | ||
| 67 | PAGE ;AN000; | ||
| 68 | ;===============================================================================;AN000; | ||
| 69 | ; ;AN000; | ||
| 70 | ; LOC_MODE_PRT_INFO: LOCATE DISPLAYMODE PRINTER INFO. FOR THE CURRENT ;AN000; | ||
| 71 | ; MODE ;AN000; | ||
| 72 | ; ;AN000; | ||
| 73 | ;-------------------------------------------------------------------------------;AN000; | ||
| 74 | ; ;AN000; | ||
| 75 | ; INPUT: BP = Offset of the shared data area ;AN000; | ||
| 76 | ; CUR_MODE = Current video mode ;AN000; | ||
| 77 | ; ;AN000; | ||
| 78 | ; OUTPUT: CUR_MODE_PTR = Absolute Offset of the ;AN000; | ||
| 79 | ; current DISPLAYMODE INFO record. ;AN000; | ||
| 80 | ; ;AN000; | ||
| 81 | ; ERROR_CODE = DISPLAYMODE_INFO_NOT_FOUND if not found. ;AN000; | ||
| 82 | ; ;AN000; | ||
| 83 | ; CALLED BY: PRINT_COLOR ;AN000; | ||
| 84 | ; PRINT_BW_APA ;AN000; | ||
| 85 | ; ;AN000; | ||
| 86 | ; ;AN000; | ||
| 87 | ;-------------------------------------------------------------------------------;AN000; | ||
| 88 | ; ;AN000; | ||
| 89 | ; DESCRIPTION: DISPLAYMODE_PTR is pointing to the first DISPLAYMODE ;AN000; | ||
| 90 | ; INFO record within the Shared Data Area. ;AN000; | ||
| 91 | ; ;AN000; | ||
| 92 | ; This (chained) list of DISPLAYMODE records is scanned until the record ;AN000; | ||
| 93 | ; for the current mode is found. ;AN000; | ||
| 94 | ; ;AN000; | ||
| 95 | ; Note: All pointers in the DISPLAYMODE records are relative to the beginning ;AN000; | ||
| 96 | ; of the shared data area. Therefore, we must add the offset of the ;AN000; | ||
| 97 | ; shared data area (in BP) in order to access the data these pointers ;AN000; | ||
| 98 | ; are referencing. ;AN000; | ||
| 99 | ; ;AN000; | ||
| 100 | ; The CUR_MODE_PTR is relative to the segment and references the ;AN000; | ||
| 101 | ; DISPLAYMODE record for the video mode currently set at print screen ;AN000; | ||
| 102 | ; time. ;AN000; | ||
| 103 | ; ;AN000; | ||
| 104 | ; LOGIC: ;AN000; | ||
| 105 | ; ;AN000; | ||
| 106 | ; FOUND := FALSE ;AN000; | ||
| 107 | ; DO UNTIL FOUND OR END_OF_LIST ;AN000; | ||
| 108 | ; Get a display mode information record ;AN000; | ||
| 109 | ; IF record.DISP_MODE = CUR_MODE ;AN000; | ||
| 110 | ; THEN FOUND := TRUE ;AN000; | ||
| 111 | ; ELSE ;AN000; | ||
| 112 | ; CUR_MODE_PTR := record.NEXT_DISP_MODE ;AN000; | ||
| 113 | ; ;AN000; | ||
| 114 | ; ;AN000; | ||
| 115 | ;AN000; | ||
| 116 | LOC_MODE_PRT_INFO PROC NEAR ;AN000; | ||
| 117 | PUSH BX ;AN000; | ||
| 118 | PUSH CX ;AN000; | ||
| 119 | PUSH DX ;AN000; | ||
| 120 | PUSH SI ;AN000; | ||
| 121 | ;AN000; | ||
| 122 | MOV BX,DS:[BP].DISPLAYMODE_PTR ; [BX] := Current DISPLAYMODE ;AN000; | ||
| 123 | ADD BX,BP ; record ;AN000; | ||
| 124 | MOV DL,CUR_MODE ; DL := Current mode ;AN000; | ||
| 125 | ;AN000; | ||
| 126 | SCAN_1_DISPLAYMODE_RECORD: ;AN000; | ||
| 127 | MOV SI,[BX].DISP_MODE_LIST_PTR ; [SI] : First mode covered ;AN000; | ||
| 128 | ADD SI,BP ; by this DISPLAYMODE record ;AN000; | ||
| 129 | MOV CL,[BX].NUM_DISP_MODE ; Scan each mode in the list ;AN000; | ||
| 130 | XOR CH,CH ;AN000; | ||
| 131 | SCAN_LIST_OF_MODES: ;AN000; | ||
| 132 | CMP CS:[SI],DL ; FOUND ? ;AN000; | ||
| 133 | JE FOUND ;AN000; | ||
| 134 | INC SI ; NO, get next mode in ;AN000; | ||
| 135 | LOOP SCAN_LIST_OF_MODES ; DISPLAYMODE record ;AN000; | ||
| 136 | ;AN000; | ||
| 137 | CMP [BX].NEXT_DISP_MODE,-1 ; END OF DISPLAYMODE LIST ? ;AN000; | ||
| 138 | JE NOT_FOUND ; Yes, this mode not supported ;AN000; | ||
| 139 | NEXT_RECORD: ; No, ;AN000; | ||
| 140 | MOV BX,[BX].NEXT_DISP_MODE ; [BX] := Next record ;AN000; | ||
| 141 | ADD BX,BP ; ;AN000; | ||
| 142 | JMP SHORT SCAN_1_DISPLAYMODE_RECORD ;AN000; | ||
| 143 | ;AN000; | ||
| 144 | FOUND: ; Found: ;AN000; | ||
| 145 | MOV CUR_MODE_PTR,BX ; Update pointer to current ;AN000; | ||
| 146 | JMP SHORT LOC_MODE_PRT_INFO_END ; DISPLAYMODE record. ;AN000; | ||
| 147 | ;AN000; | ||
| 148 | NOT_FOUND: ; Not found: ;AN000; | ||
| 149 | MOV ERROR_CODE,DISPLAYMODE_INFO_NOT_FOUND ; Return error condition ;AN000; | ||
| 150 | ;AN000; | ||
| 151 | LOC_MODE_PRT_INFO_END: ;AN000; | ||
| 152 | POP SI ;AN000; | ||
| 153 | POP DX ;AN000; | ||
| 154 | POP CX ;AN000; | ||
| 155 | POP BX ;AN000; | ||
| 156 | RET ;AN000; | ||
| 157 | LOC_MODE_PRT_INFO ENDP ;AN000; | ||
| 158 | PAGE ;AN000; | ||
| 159 | ;===============================================================================;AN000; | ||
| 160 | ; ;AN000; | ||
| 161 | ; STORE_BOX : STORE ONE BOX IN THE PRINT BUFFER. ;AN000; | ||
| 162 | ; ;AN000; | ||
| 163 | ;-------------------------------------------------------------------------------;AN000; | ||
| 164 | ; ;AN000; | ||
| 165 | ; INPUT: SI = OFFSET OF THE BOX TO BE PRINTED ;AN000; | ||
| 166 | ; BOX_W = BOX WIDTH IN BITS ;AN000; | ||
| 167 | ; BOX_H = BOX HEIGHT IN BITS ;AN000; | ||
| 168 | ; ;AN000; | ||
| 169 | ; OUTPUT: PRT_BUF = THE PRINT BUFFER ;AN000; | ||
| 170 | ; ;AN000; | ||
| 171 | ;-------------------------------------------------------------------------------;AN000; | ||
| 172 | ; ;AN000; | ||
| 173 | ; DESCRIPTION: The print buffer is first shifted left in order to make ;AN000; | ||
| 174 | ; room for the new box (Note: the MSB's are lost; they are assumed to ;AN000; | ||
| 175 | ; have been printed), then the box is inserted in the low-order bits of ;AN000; | ||
| 176 | ; the printer buffer. ;AN000; | ||
| 177 | ; ;AN000; | ||
| 178 | PAGE ;AN000; | ||
| 179 | ; EXAMPLE ;AN000; | ||
| 180 | ; ------- ;AN000; | ||
| 181 | ; BEFORE: AFTER: ;AN000; | ||
| 182 | ; ;AN000; | ||
| 183 | ; BOX: 0 0 0 ;AN000; | ||
| 184 | ; 0 0 0 ;AN000; | ||
| 185 | ; 0 0 0 ;AN000; | ||
| 186 | ; 0 0 0 ;AN000; | ||
| 187 | ; 0 0 0 ;AN000; | ||
| 188 | ; 0 0 0 ;AN000; | ||
| 189 | ; b1 b2 b3 ;AN000; | ||
| 190 | ; b4 b5 b6 ;AN000; | ||
| 191 | ; ;AN000; | ||
| 192 | ; PRT_BUF: byte1 byte2 byte3 PRT_BUF: byte1 byte2 byte3 ;AN000; | ||
| 193 | ; 0 1 0 1 1 1 ;AN000; | ||
| 194 | ; 1 0 1 1 1 1 ;AN000; | ||
| 195 | ; 1 1 1 1 1 1 ;AN000; | ||
| 196 | ; 1 1 1 1 1 1 ;AN000; | ||
| 197 | ; 1 1 1 1 1 1 ;AN000; | ||
| 198 | ; 1 1 1 1 1 1 ;AN000; | ||
| 199 | ; 1 1 1 b1 b2 b3 ;AN000; | ||
| 200 | ; LSB --> 1 1 1 b4 b5 b6 ;AN000; | ||
| 201 | ; ;AN000; | ||
| 202 | ; ;AN000; | ||
| 203 | ; LOGIC: ;AN000; | ||
| 204 | ; ;AN000; | ||
| 205 | ; FOR each byte of the buffer (BOX_W) ;AN000; | ||
| 206 | ; BEGIN ;AN000; | ||
| 207 | ; Make room for the box to be inserted ;AN000; | ||
| 208 | ; Insert the box ;AN000; | ||
| 209 | ; END ;AN000; | ||
| 210 | ; ;AN000; | ||
| 211 | STORE_BOX PROC NEAR ;AN000; | ||
| 212 | PUSH BX ;AN000; | ||
| 213 | PUSH CX ;AN000; | ||
| 214 | PUSH DI ;AN000; | ||
| 215 | ;AN000; | ||
| 216 | MOV DI,OFFSET PRT_BUF ; DI := Offset of the Print buffer ;AN000; | ||
| 217 | XOR BX,BX ; BX := Byte index number ;AN000; | ||
| 218 | ;AN000; | ||
| 219 | MOV CL,BOX_H ; CL := Number of BITS to be shifted ;AN000; | ||
| 220 | ; FOR each column (byte) of the box to be stored in the buffer: ;AN000; | ||
| 221 | STORE_1_BYTE: ;AN000; | ||
| 222 | SHL BYTE PTR [BX][DI],CL ; Make room for the bits to be inserted ;AN000; | ||
| 223 | MOV CH,[BX][SI] ; CH := column of the box to be inserted;AN000; | ||
| 224 | OR [BX][DI],CH ; Insert the box column in the buffer ;AN000; | ||
| 225 | INC BL ; Get next column (byte) of the box ;AN000; | ||
| 226 | CMP BL,BOX_W ; All columns (bytes) of box stored ? ;AN000; | ||
| 227 | JL STORE_1_BYTE ; No, store next one. ;AN000; | ||
| 228 | ;AN000; | ||
| 229 | STORE_BOX_END: ;AN000; | ||
| 230 | POP DI ;AN000; | ||
| 231 | POP CX ;AN000; | ||
| 232 | POP BX ;AN000; | ||
| 233 | RET ;AN000; | ||
| 234 | STORE_BOX ENDP ;AN000; | ||
| 235 | PAGE ;AN000; | ||
| 236 | ;===============================================================================;AN000; | ||
| 237 | ; ;AN000; | ||
| 238 | ; PRINT_BUFFER : PRINT THE BUFFER ;AN000; | ||
| 239 | ; ;AN000; | ||
| 240 | ;-------------------------------------------------------------------------------;AN000; | ||
| 241 | ; ;AN000; | ||
| 242 | ; INPUT: PRT_BUF = BYTES TO BE PRINTED ;AN000; | ||
| 243 | ; BOW_W = BOX WIDTH ;AN000; | ||
| 244 | ; ;AN000; | ||
| 245 | ; OUTPUT: PRINTER ;AN000; | ||
| 246 | ; ;AN000; | ||
| 247 | ;-------------------------------------------------------------------------------;AN000; | ||
| 248 | ; ;AN000; | ||
| 249 | ; DESCRIPTION: Prints BOX_W bytes. ;AN000; | ||
| 250 | ; ;AN000; | ||
| 251 | ; LOGIC: ;AN000; | ||
| 252 | ; ;AN000; | ||
| 253 | ; DO for each column in one pattern ;AN000; | ||
| 254 | ; BEGIN ;AN000; | ||
| 255 | ; Print one byte from the buffer ;AN000; | ||
| 256 | ; END ;AN000; | ||
| 257 | ; ;AN000; | ||
| 258 | PRINT_BUFFER PROC NEAR ;AN000; | ||
| 259 | PUSH AX ;AN000; | ||
| 260 | PUSH BX ;AN000; | ||
| 261 | PUSH CX ;AN000; | ||
| 262 | ;AN000; | ||
| 263 | MOV BX,OFFSET PRT_BUF ;AN000; | ||
| 264 | XOR CX,CX ;AN000; | ||
| 265 | MOV CL,BOX_W ;AN000; | ||
| 266 | PRINT_1_BUF_COLUMN: ;AN000; | ||
| 267 | MOV AL,[BX] ; Print one byte ;AN000; | ||
| 268 | CALL PRINT_BYTE ;AN000; | ||
| 269 | JC PRINT_BUFFER_END; If printer error, quit the loop ;AN000; | ||
| 270 | INC BX ; Get next byte ;AN000; | ||
| 271 | LOOP PRINT_1_BUF_COLUMN ;AN000; | ||
| 272 | PRINT_BUFFER_END: ;AN000; | ||
| 273 | POP CX ;AN000; | ||
| 274 | POP BX ;AN000; | ||
| 275 | POP AX ;AN000; | ||
| 276 | RET ;AN000; | ||
| 277 | PRINT_BUFFER ENDP ;AN000; | ||
| 278 | PAGE ;AN000; | ||
| 279 | ;===============================================================================;AN000; | ||
| 280 | ; ;AN000; | ||
| 281 | ; GET_SCREEN_INFO : GET INFORMATION ABOUT HOW TO READ THE SCREEN. ;AN000; | ||
| 282 | ; ;AN000; | ||
| 283 | ;-------------------------------------------------------------------------------;AN000; | ||
| 284 | ; ;AN000; | ||
| 285 | ; INPUT: SCREEN_HEIGHT = Number of pixel rows on the screen ;AN000; | ||
| 286 | ; SCREEN_WIDTH = Number of pixel columns on screen ;AN000; | ||
| 287 | ; CUR_MODE_PTR = Offset of the current DISPLAYMODE info rec. ;AN000; | ||
| 288 | ; ;AN000; | ||
| 289 | ; OUTPUT: PRINTER ;AN000; | ||
| 290 | ; SCAN_LINE_MAX_LENGTH = Maximum length of Screen scan line. ;AN000; | ||
| 291 | ; NB_SCAN_LINES = Number of SCAN LINES on the screen ;AN000; | ||
| 292 | ; CUR_ROW,CUR_COLUMN = Coordinates of the first pixel to be ;AN000; | ||
| 293 | ; read on the screen ;AN000; | ||
| 294 | ; NB_BOXES_PER_PRT_BUF = Number of boxes fitting in the Print ;AN000; | ||
| 295 | ; buffer ;AN000; | ||
| 296 | ; ;AN000; | ||
| 297 | ; CALLED BY: PRINT_COLOR ;AN000; | ||
| 298 | ; PRT_BW_APA ;AN000; | ||
| 299 | ; ;AN000; | ||
| 300 | ;-------------------------------------------------------------------------------;AN000; | ||
| 301 | ; ;AN000; | ||
| 302 | ; DESCRIPTION: ;AN000; | ||
| 303 | ; ;AN000; | ||
| 304 | ; 1) Determine where to start reading the screen. ;AN000; | ||
| 305 | ; For non-rotated printing, it should start with the top-left ;AN000; | ||
| 306 | ; corner pixel. ;AN000; | ||
| 307 | ; For rotated printing, it should start with the low-left corner ;AN000; | ||
| 308 | ; pixel. ;AN000; | ||
| 309 | ; ;AN000; | ||
| 310 | ; 2) Determine the length of a scan line. ;AN000; | ||
| 311 | ; For non-rotated printing, it is the WIDTH of the screen. ;AN000; | ||
| 312 | ; For rotated printing, it is the HEIGHT of the screen. ;AN000; | ||
| 313 | ; ;AN000; | ||
| 314 | ; 3) Determine the number of scan lines on the screen. ;AN000; | ||
| 315 | ; For non-rotated printing, it is the HEIGHT of the screen divided ;AN000; | ||
| 316 | ; by the number of boxes fitting in the print buffer. ;AN000; | ||
| 317 | ; For rotated printing, it is the WIDTH of the screen divided by ;AN000; | ||
| 318 | ; the number of boxes fitting in the print buffer. ;AN000; | ||
| 319 | ; ;AN000; | ||
| 320 | ; LOGIC: ;AN000; | ||
| 321 | ; ;AN000; | ||
| 322 | ; CUR_COLUMN := 0 ;AN000; | ||
| 323 | ; IF printing is sideways ;AN000; | ||
| 324 | ; THEN ;AN000; | ||
| 325 | ; CUR_ROW := SCREEN_HEIGHT - 1 ; Low-left pixel ;AN000; | ||
| 326 | ; SCAN_LINE_MAX_LENGTH := SCREEN_HEIGHT ;AN000; | ||
| 327 | ; NB_SCAN_LINES := SCREEN_WIDTH / NB_BOXES_PER_PRT_BUF ;AN000; | ||
| 328 | ; ELSE ;AN000; | ||
| 329 | ; CUR_ROW := 0 ; Top-left pixel ;AN000; | ||
| 330 | ; SCAN_LINE_MAX_LENGTH := SCREEN_WIDTH ;AN000; | ||
| 331 | ; NB_SCAN_LINES := SCREEN_HEIGHT / NB_BOXES_PER_PRT_BUF ;AN000; | ||
| 332 | ; ;AN000; | ||
| 333 | ; ;AN000; | ||
| 334 | GET_SCREEN_INFO PROC NEAR ;AN000; | ||
| 335 | PUSH AX ;AN000; | ||
| 336 | PUSH BX ; Used for DIV ;AN000; | ||
| 337 | PUSH DX ; Used for DIV ;AN000; | ||
| 338 | ;AN000; | ||
| 339 | MOV BX,CUR_MODE_PTR ; BX := Offset DISPLAYMODE info record ;AN000; | ||
| 340 | ;-------------------------------------------------------------------------------;AN000; | ||
| 341 | ; ;AN000; | ||
| 342 | ; Calculate how many printer boxes fit in the print buffer: ;AN000; | ||
| 343 | ; ;AN000; | ||
| 344 | ;-------------------------------------------------------------------------------;AN000; | ||
| 345 | MOV AX,8 ; Num := 8 bits / Box heigth ;AN000; | ||
| 346 | MOV DL,[BX].BOX_HEIGHT ;AN000; | ||
| 347 | DIV DL ;AN000; | ||
| 348 | MOV NB_BOXES_PER_PRT_BUF,AL ;AN000; | ||
| 349 | ;-------------------------------------------------------------------------------;AN000; | ||
| 350 | ; ;AN000; | ||
| 351 | ; Determine where to start reading the screen: ;AN000; | ||
| 352 | ; ;AN000; | ||
| 353 | ;-------------------------------------------------------------------------------;AN000; | ||
| 354 | MOV CUR_COLUMN,0 ; Reading always start from left of scr ;AN000; | ||
| 355 | .IF <[BX].PRINT_OPTIONS EQ ROTATE> ;AN000; | ||
| 356 | .THEN ;AN000; | ||
| 357 | ;-------------------------------------------------------------------------------;AN000; | ||
| 358 | ; ;AN000; | ||
| 359 | ; Printing is sideways; screen must be read starting in low-left corner. ;AN000; | ||
| 360 | ; ;AN000; | ||
| 361 | ;-------------------------------------------------------------------------------;AN000; | ||
| 362 | MOV AX,SCREEN_HEIGHT ;AN000; | ||
| 363 | MOV SCAN_LINE_MAX_LENGTH,AX ; Scan line length := screen height ;AN000; | ||
| 364 | DEC AX ;AN000; | ||
| 365 | MOV CUR_ROW,AX ; First row := screen height - 1 ;AN000; | ||
| 366 | ;AN000; | ||
| 367 | ;-------Calculate the number of scan lines: ;AN000; | ||
| 368 | MOV AX,SCREEN_WIDTH ; DX AX = Screen width ;AN000; | ||
| 369 | CWD ; ;AN000; | ||
| 370 | XOR BX,BX ; BX = Number of boxes per print buf ;AN000; | ||
| 371 | MOV BL,NB_BOXES_PER_PRT_BUF ; ;AN000; | ||
| 372 | DIV BX ; Screen width / number boxes per buff ;AN000; | ||
| 373 | MOV NB_SCAN_LINES,AX ; Number of scan lines := result ;AN000; | ||
| 374 | .ELSE ;AN000; | ||
| 375 | ;-------------------------------------------------------------------------------;AN000; | ||
| 376 | ; ;AN000; | ||
| 377 | ; Printing is not sideways; screen must be read starting in top-left corner ;AN000; | ||
| 378 | ; ;AN000; | ||
| 379 | ;-------------------------------------------------------------------------------;AN000; | ||
| 380 | MOV AX,SCREEN_WIDTH ;AN000; | ||
| 381 | MOV SCAN_LINE_MAX_LENGTH,AX ; Scan line length := screen width ;AN000; | ||
| 382 | MOV CUR_ROW,0 ; First row := 0 ;AN000; | ||
| 383 | ;AN000; | ||
| 384 | ;-------Calculate the number of scan lines: ;AN000; | ||
| 385 | MOV AX,SCREEN_HEIGHT ; DX AX = Screen height ;AN000; | ||
| 386 | CWD ; ;AN000; | ||
| 387 | XOR BX,BX ; BX = Number of boxes per print buff ;AN000; | ||
| 388 | MOV BL,NB_BOXES_PER_PRT_BUF ; ;AN000; | ||
| 389 | DIV BX ; Screen height/number boxes per buff. ;AN000; | ||
| 390 | MOV NB_SCAN_LINES,AX ; Number of scan lines := result ;AN000; | ||
| 391 | .ENDIF ;AN000; | ||
| 392 | POP DX ;AN000; | ||
| 393 | POP BX ;AN000; | ||
| 394 | POP AX ;AN000; | ||
| 395 | RET ;AN000; | ||
| 396 | GET_SCREEN_INFO ENDP ;AN000; | ||
| 397 | PAGE ;AN000; | ||
| 398 | ;===============================================================================;AN000; | ||
| 399 | ; ;AN000; | ||
| 400 | ; DET_CUR_SCAN_LNE_LENGTH : Determine where is the last non-blank "scan line ;AN000; | ||
| 401 | ; column" on the current scan line. ;AN000; | ||
| 402 | ; ;AN000; | ||
| 403 | ;-------------------------------------------------------------------------------;AN000; | ||
| 404 | ; ;AN000; | ||
| 405 | ; INPUT: CUR_ROW, ;AN000; | ||
| 406 | ; CUR_COLUMN = Coordinates of the top pixel of the current ;AN000; | ||
| 407 | ; scan line. ;AN000; | ||
| 408 | ; XLT_TAB = Color translation table ;AN000; | ||
| 409 | ; ;AN000; | ||
| 410 | ; OUTPUT: CUR_SCAN_LNE_LENGTH = Number of "columns" of pixels from the ;AN000; | ||
| 411 | ; beginning of the scan line up to ;AN000; | ||
| 412 | ; the last non-blank pixel. ;AN000; | ||
| 413 | ; ;AN000; | ||
| 414 | ; DATA SCREEN_WIDTH, ;AN000; | ||
| 415 | ; REFERENCED: SCREEN_HEIGHT = Dimensions of the screen in pels ;AN000; | ||
| 416 | ; SCAN_LINE_MAX_LENGTH= Maximum length of the scan line ;AN000; | ||
| 417 | ; ROTATE_SW = ON if printing is sideways ;AN000; | ||
| 418 | ; ;AN000; | ||
| 419 | ;-------------------------------------------------------------------------------;AN000; | ||
| 420 | ; ;AN000; | ||
| 421 | ; DESCRIPTION: Determine where is the last non-blank "column" by reading ;AN000; | ||
| 422 | ; the scan line backwards, one column at a time. ;AN000; | ||
| 423 | ; ;AN000; | ||
| 424 | ; ;AN000; | ||
| 425 | ; LOGIC: ;AN000; | ||
| 426 | ; ;AN000; | ||
| 427 | ; ; Obtain coordinates for the top pixel of the last column on the current ;AN000; | ||
| 428 | ; ; scan line: ;AN000; | ||
| 429 | ; IF printing is sideways ;AN000; | ||
| 430 | ; THEN ;AN000; | ||
| 431 | ; CUR_ROW := 0 ;AN000; | ||
| 432 | ; ELSE ;AN000; | ||
| 433 | ; CUR_COLUMN := SCREEN_WIDTH - 1 ;AN000; | ||
| 434 | ; ;AN000; | ||
| 435 | ; CUR_SCAN_LNE_LENGTH := SCAN_LINE_MAX_LENGTH ;AN000; | ||
| 436 | ; ; Read a column of pixels on the scan line until a non-blank is found: ;AN000; | ||
| 437 | ; For each column on the screen ;AN000; | ||
| 438 | ; CALL FILL_BUFF ;AN000; | ||
| 439 | ; ; Check if PRT_BUF is empty ;AN000; | ||
| 440 | ; IF buffer is empty ;AN000; | ||
| 441 | ; THEN DEC CUR_SCAN_LNE_LENGTH ;AN000; | ||
| 442 | ; ; Get next column ;AN000; | ||
| 443 | ; IF printing sideways THEN DEC CUR_ROW ;AN000; | ||
| 444 | ; ELSE DEC CUR_COLUMN ;AN000; | ||
| 445 | ; ELSE quit the loop ;AN000; | ||
| 446 | ; ;AN000; | ||
| 447 | DET_CUR_SCAN_LNE_LENGTH PROC NEAR ;AN000; | ||
| 448 | PUSH AX ;AN000; | ||
| 449 | PUSH BX ;AN000; | ||
| 450 | PUSH CX ;AN000; | ||
| 451 | PUSH DX ;AN000; | ||
| 452 | PUSH SI ;AN000; | ||
| 453 | PUSH DI ;AN000; | ||
| 454 | PUSH CUR_COLUMN ;AN000; | ||
| 455 | PUSH CUR_ROW ;AN000; | ||
| 456 | ;AN000; | ||
| 457 | MOV BX,OFFSET XLT_TAB ; BX := Offset of XLT_TAB ;AN000; | ||
| 458 | ;-------------------------------------------------------------------------------;AN000; | ||
| 459 | ; ;AN000; | ||
| 460 | ; Obtain coordinates of the top pixel for the last column of the current ;AN000; | ||
| 461 | ; scan line: ;AN000; | ||
| 462 | ; ;AN000; | ||
| 463 | ;-------------------------------------------------------------------------------;AN000; | ||
| 464 | .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000; | ||
| 465 | .THEN ; then, ;AN000; | ||
| 466 | MOV CUR_ROW,0 ; CUR_ROW := 0 ;AN000; | ||
| 467 | .ELSE ; else, ;AN000; | ||
| 468 | MOV CX,SCREEN_WIDTH ; CUR_COLUMN := SCREEN_WIDTH - 1 ;AN000; | ||
| 469 | DEC CX ; ;AN000; | ||
| 470 | MOV CUR_COLUMN,CX ; ;AN000; | ||
| 471 | .ENDIF ;AN000; | ||
| 472 | ;-------------------------------------------------------------------------------;AN000; | ||
| 473 | ; ;AN000; | ||
| 474 | ; Read the scan line backwards "column" by "column" until a non-blank is found: ;AN000; | ||
| 475 | ; ;AN000; | ||
| 476 | ;-------------------------------------------------------------------------------;AN000; | ||
| 477 | MOV CX,SCAN_LINE_MAX_LENGTH ; CX := current length ;AN000; | ||
| 478 | ; ;AN000; | ||
| 479 | ;-------For each "column" ;AN000; | ||
| 480 | CHECK_1_COLUMN: ;AN000; | ||
| 481 | MOV SI,CUR_ROW ; Save coordinates of the column ;AN000; | ||
| 482 | MOV DI,CUR_COLUMN ; in SI, DI ;AN000; | ||
| 483 | XOR DL,DL ; DL := Number of pixels verified in ;AN000; | ||
| 484 | ; one "column" ;AN000; | ||
| 485 | ; ;AN000; | ||
| 486 | ;-------For each pixel within that "column" ;AN000; | ||
| 487 | CHECK_1_PIXEL: ;AN000; | ||
| 488 | CALL READ_DOT ; AL := Index into translation table ;AN000; | ||
| 489 | XLAT XLT_TAB ; AL := Band mask or Intensity ;AN000; | ||
| 490 | ;AN000; | ||
| 491 | ;-------Check if pixel will map to an empty box: ;AN000; | ||
| 492 | .IF <DS:[BP].PRINTER_TYPE EQ BLACK_WHITE> ; If BLACK AND WHITE printer ;AN000; | ||
| 493 | .THEN ; then, check for intensity of white ;AN000; | ||
| 494 | CMP AL,WHITE_INT ; If curent pixel not blank ;AN000; | ||
| 495 | JNE DET_LENGTH_END ; THEN, LEAVE THE LOOP ;AN000; | ||
| 496 | .ELSE ; else, COLOR printer ;AN000; | ||
| 497 | OR AL,AL ; IF Band mask not blank ;AN000; | ||
| 498 | JNZ DET_LENGTH_END ; THEN, LEAVE THE LOOP ;AN000; | ||
| 499 | .ENDIF ;AN000; | ||
| 500 | ;AN000; | ||
| 501 | ;-------All pixels so far on this "column" are blank, get next pixel: ;AN000; | ||
| 502 | .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000; | ||
| 503 | .THEN ; ;AN000; | ||
| 504 | INC CUR_COLUMN ; then, increment column number ;AN000; | ||
| 505 | .ELSE ; ;AN000; | ||
| 506 | INC CUR_ROW ; else, increment row number ;AN000; | ||
| 507 | .ENDIF ; ;AN000; | ||
| 508 | INC DL ; One more pixel checked ;AN000; | ||
| 509 | CMP DL,NB_BOXES_PER_PRT_BUF ; All pixels for that column done ? ;AN000; | ||
| 510 | JL CHECK_1_PIXEL ; No, check next one. ;AN000; | ||
| 511 | ;AN000; | ||
| 512 | ;-------Nothing to print for this column, get next column ;AN000; | ||
| 513 | .IF <ROTATE_SW EQ ON> ; If printing sideways ;AN000; | ||
| 514 | .THEN ; then, ;AN000; | ||
| 515 | MOV CUR_COLUMN,DI ; Restore column number ;AN000; | ||
| 516 | INC CUR_ROW ; Get next row ;AN000; | ||
| 517 | .ELSE ; else, ;AN000; | ||
| 518 | MOV CUR_ROW,SI ; Restore row number ;AN000; | ||
| 519 | DEC CUR_COLUMN ; Get next column ;AN000; | ||
| 520 | .ENDIF ; ;AN000; | ||
| 521 | LOOP CHECK_1_COLUMN ; CX (length) := CX - 1 ;AN000; | ||
| 522 | ;AN000; | ||
| 523 | DET_LENGTH_END: ;AN000; | ||
| 524 | MOV CUR_SCAN_LNE_LENGTH,CX ; Get current length ;AN000; | ||
| 525 | ;AN000; | ||
| 526 | POP CUR_ROW ;AN000; | ||
| 527 | POP CUR_COLUMN ;AN000; | ||
| 528 | POP DI ;AN000; | ||
| 529 | POP SI ;AN000; | ||
| 530 | POP DX ;AN000; | ||
| 531 | POP CX ;AN000; | ||
| 532 | POP BX ;AN000; | ||
| 533 | POP AX ;AN000; | ||
| 534 | RET ;AN000; | ||
| 535 | DET_CUR_SCAN_LNE_LENGTH ENDP ;AN000; | ||
| 536 | PAGE ;AN000; | ||
| 537 | ;===============================================================================;AN000; | ||
| 538 | ; ;AN000; | ||
| 539 | ; SETUP_PRT : SET UP THE PRINTER FOR PRINTING IN GRAPHIC MODE ;AN000; | ||
| 540 | ; ;AN000; | ||
| 541 | ;-------------------------------------------------------------------------------;AN000; | ||
| 542 | ; ;AN000; | ||
| 543 | ; INPUT: CUR_MODE_PTR = Offset of the DISPLAYMODE information ;AN000; | ||
| 544 | ; record for the current mode ;AN000; | ||
| 545 | ; ;AN000; | ||
| 546 | ; OUTPUT: PRINTER ;AN000; | ||
| 547 | ; ;AN000; | ||
| 548 | ; CALLED BY: PRINT_COLOR ;AN000; | ||
| 549 | ; PRT_BW_APA ;AN000; | ||
| 550 | ; ;AN000; | ||
| 551 | ;-------------------------------------------------------------------------------;AN000; | ||
| 552 | ; ;AN000; | ||
| 553 | ; DESCRIPTION: Extract the SETUP escape sequence from the DISPLAYMODE ;AN000; | ||
| 554 | ; information record; Send this escape sequence to the printer. ;AN000; | ||
| 555 | ; ;AN000; | ||
| 556 | ; LOGIC: ;AN000; | ||
| 557 | ; ;AN000; | ||
| 558 | ; Number of bytes to print := CUR_MODE_PTR.NUM_SETUP_ESC ;AN000; | ||
| 559 | ; ;AN000; | ||
| 560 | ; Get the escape sequence: ;AN000; | ||
| 561 | ; SI := CUR_MODE_PTR.SETUP_ESC_PTR ;AN000; | ||
| 562 | ; ;AN000; | ||
| 563 | ; FOR each byte to be printed ;AN000; | ||
| 564 | ; PRINT_BYTE [SI] ; Send the byte to the printer ;AN000; | ||
| 565 | ; INC SI ; Get the next byte ;AN000; | ||
| 566 | ; ;AN000; | ||
| 567 | SETUP_PRT PROC NEAR ;AN000; | ||
| 568 | PUSH AX ;AN000; | ||
| 569 | PUSH BX ;AN000; | ||
| 570 | PUSH CX ;AN000; | ||
| 571 | ;AN000; | ||
| 572 | MOV BX,CUR_MODE_PTR ; BX := Displaymode info record. ;AN000; | ||
| 573 | ;AN000; | ||
| 574 | XOR CX,CX ; CX := Number of bytes to print ;AN000; | ||
| 575 | MOV CL,[BX].NUM_SETUP_ESC ; ;AN000; | ||
| 576 | .IF <CL G 0> ; If there is at least one ;AN000; | ||
| 577 | .THEN ; byte to be printed: ;AN000; | ||
| 578 | MOV BX,[BX].SETUP_ESC_PTR ; BX := Offset sequence to send ;AN000; | ||
| 579 | ADD BX,BP ;AN000; | ||
| 580 | ;AN000; | ||
| 581 | SEND_1_SETUP_BYTE: ;AN000; | ||
| 582 | MOV AL,[BX] ; AL := byte to print ;AN000; | ||
| 583 | CALL PRINT_BYTE ; Send it to the printer ;AN000; | ||
| 584 | JC SETUP_PRT_END ; If printer error, quit the loop ;AN000; | ||
| 585 | INC BX ; Get next byte ;AN000; | ||
| 586 | LOOP SEND_1_SETUP_BYTE ;AN000; | ||
| 587 | .ENDIF ;AN000; | ||
| 588 | SETUP_PRT_END: ;AN000; | ||
| 589 | POP CX ;AN000; | ||
| 590 | POP BX ;AN000; | ||
| 591 | POP AX ;AN000; | ||
| 592 | RET ;AN000; | ||
| 593 | SETUP_PRT ENDP ;AN000; | ||
| 594 | PAGE ;AN000; | ||
| 595 | ;===============================================================================;AN000; | ||
| 596 | ; ;AN000; | ||
| 597 | ; RESTORE_PRT : RESTORE THE PRINTER TO ITS INITIAL STATUS ;AN000; | ||
| 598 | ; ;AN000; | ||
| 599 | ;-------------------------------------------------------------------------------;AN000; | ||
| 600 | ; ;AN000; | ||
| 601 | ; INPUT: CUR_MODE_PTR = Offset of the DISPLAYMODE information ;AN000; | ||
| 602 | ; record for the current mode ;AN000; | ||
| 603 | ; ;AN000; | ||
| 604 | ; OUTPUT: PRINTER ;AN000; | ||
| 605 | ; ;AN000; | ||
| 606 | ; CALLED BY: PRINT_COLOR ;AN000; | ||
| 607 | ; PRT_BW_APA ;AN000; | ||
| 608 | ;-------------------------------------------------------------------------------;AN000; | ||
| 609 | ; ;AN000; | ||
| 610 | ; DESCRIPTION: Extract the RESTORE escape sequence from the DISPLAYMODE ;AN000; | ||
| 611 | ; information record; Send this escape sequence to the printer. ;AN000; | ||
| 612 | ; ;AN000; | ||
| 613 | ; LOGIC: ;AN000; | ||
| 614 | ; ;AN000; | ||
| 615 | ; Number of bytes to print := CUR_MODE_PTR.NUM_RESTORE_ESC ;AN000; | ||
| 616 | ; ;AN000; | ||
| 617 | ; Get the escape sequence: ;AN000; | ||
| 618 | ; SI := CUR_MODE_PTR.RESTORE_ESC_PTR ;AN000; | ||
| 619 | ; FOR each byte to be printed ;AN000; | ||
| 620 | ; PRINT_BYTE [SI] ; Send the byte to the printer ;AN000; | ||
| 621 | ; INC SI ; Get the next byte ;AN000; | ||
| 622 | ; ;AN000; | ||
| 623 | RESTORE_PRT PROC NEAR ;AN000; | ||
| 624 | PUSH AX ;AN000; | ||
| 625 | PUSH BX ;AN000; | ||
| 626 | PUSH CX ;AN000; | ||
| 627 | ;AN000; | ||
| 628 | MOV BX,CUR_MODE_PTR ; BX := Displaymode info record. ;AN000; | ||
| 629 | ;AN000; | ||
| 630 | XOR CX,CX ; CX := Number of bytes to print ;AN000; | ||
| 631 | MOV CL,[BX].NUM_RESTORE_ESC ;AN000; | ||
| 632 | .IF <CL G 0> ; If there is at least one ;AN000; | ||
| 633 | .THEN ; byte to be printed: ;AN000; | ||
| 634 | MOV BX,[BX].RESTORE_ESC_PTR ; BX := Offset sequence to send ;AN000; | ||
| 635 | ADD BX,BP ;AN000; | ||
| 636 | ;AN000; | ||
| 637 | SEND_1_RESTORE_BYTE: ;AN000; | ||
| 638 | MOV AL,[BX] ; AL := byte to print ;AN000; | ||
| 639 | CALL PRINT_BYTE ; Send it to the printer ;AN000; | ||
| 640 | JC RESTORE_PRT_END ; If printer error, quit the loop ;AN000; | ||
| 641 | INC BX ; Get next byte ;AN000; | ||
| 642 | LOOP SEND_1_RESTORE_BYTE ;AN000; | ||
| 643 | .ENDIF ;AN000; | ||
| 644 | RESTORE_PRT_END: ;AN000; | ||
| 645 | POP CX ;AN000; | ||
| 646 | POP BX ;AN000; | ||
| 647 | POP AX ;AN000; | ||
| 648 | RET ;AN000; | ||
| 649 | RESTORE_PRT ENDP ;AN000; | ||
| 650 | PAGE ;AN000; | ||
| 651 | ;===============================================================================;AN000; | ||
| 652 | ; ;AN000; | ||
| 653 | ; NEW_PRT_LINE : INITIALIZE THE PRINTER FOR A GRAPHIC LINE ;AN000; | ||
| 654 | ; ;AN000; | ||
| 655 | ;-------------------------------------------------------------------------------;AN000; | ||
| 656 | ; ;AN000; | ||
| 657 | ; INPUT: CUR_MODE_PTR = Offset of the DISPLAYMODE information ;AN000; | ||
| 658 | ; record for the current mode ;AN000; | ||
| 659 | ; CUR_SCAN_LNE_LENGTH = Number of bytes to send to the printer. ;AN000; | ||
| 660 | ; ;AN000; | ||
| 661 | ; OUTPUT: PRINTER ;AN000; | ||
| 662 | ; ;AN000; | ||
| 663 | ; CALLED BY: PRINT_BAND ;AN000; | ||
| 664 | ; PRT_BW_APA ;AN000; | ||
| 665 | ; ;AN000; | ||
| 666 | ;-------------------------------------------------------------------------------;AN000; | ||
| 667 | ; ;AN000; | ||
| 668 | ; DESCRIPTION: Extract the GRAPHICS escape sequence from the DISPLAYMODE ;AN000; | ||
| 669 | ; information record; Send this escape sequence to the printer. ;AN000; | ||
| 670 | ; Then, send the number of bytes that will follow. ;AN000; | ||
| 671 | ; ;AN000; | ||
| 672 | ; LOGIC: ;AN000; | ||
| 673 | ; ;AN000; | ||
| 674 | ; Number of bytes to print := CUR_MODE_PTR.NUM_GRAPHICS_ESC ;AN000; | ||
| 675 | ; ;AN000; | ||
| 676 | ; Get the escape sequence: ;AN000; | ||
| 677 | ; Set up the 2 bytes containing the number of bytes to send in this sequence. ;AN000; | ||
| 678 | ; SI := CUR_MODE_PTR.GRAPHICS_ESC_PTR ;AN000; | ||
| 679 | ; ;AN000; | ||
| 680 | ; FOR each byte to be printed ;AN000; | ||
| 681 | ; PRINT_BYTE [SI] ; Send the byte to the printer ;AN000; | ||
| 682 | ; INC SI ; Get the next byte ;AN000; | ||
| 683 | ; ;AN000; | ||
| 684 | ; Send the byte count ;AN000; | ||
| 685 | ; ;AN000; | ||
| 686 | ;AN000; | ||
| 687 | NEW_PRT_LINE PROC NEAR ;AN000; | ||
| 688 | PUSH AX ;AN000; | ||
| 689 | PUSH BX ;AN000; | ||
| 690 | PUSH CX ;AN000; | ||
| 691 | PUSH DX ;AN000; | ||
| 692 | PUSH DI ;AN000; | ||
| 693 | ;AN000; | ||
| 694 | MOV BX,CUR_MODE_PTR ; BX := Displaymode info record. ;AN000; | ||
| 695 | ;AN000; | ||
| 696 | ;-------------------------------------------------------------------------------;AN000; | ||
| 697 | ; Set up the 2 bytes containing the number of bytes to send in the GRAPHICS seq.;AN000; | ||
| 698 | ; NOTE: number of bytes to send is "CUR_SCAN_LNE_LENGTH * BOX_W" ;AN000; | ||
| 699 | ;-------------------------------------------------------------------------------;AN000; | ||
| 700 | MOV AL,BOX_W ; cur_scan_lne_length * ;AN000; | ||
| 701 | CBW ; printer box width = nb bytes to send;AN000; | ||
| 702 | MUL CUR_SCAN_LNE_LENGTH ; (result in DX AX) ;AN000; | ||
| 703 | ; ;AN000; | ||
| 704 | ;-------AX := Number of bytes to print ;AN000; | ||
| 705 | MOV DI,[BX].LOW_BYT_COUNT_PTR; DI := Offset of LOW byte of ;AN000; | ||
| 706 | ADD DI,BP ; byte count ;AN000; | ||
| 707 | MOV [DI],AL ; Store low byte ;AN000; | ||
| 708 | MOV DI,[BX].HGH_BYT_COUNT_PTR; DI := Offset of HIGH byte of ;AN000; | ||
| 709 | ADD DI,BP ; byte count ;AN000; | ||
| 710 | MOV [DI],AH ; Store high byte ;AN000; | ||
| 711 | ;AN000; | ||
| 712 | ;-------------------------------------------------------------------------------;AN000; | ||
| 713 | ; Send the GRAPHICS escape sequence to the printer: ;AN000; | ||
| 714 | ;-------------------------------------------------------------------------------;AN000; | ||
| 715 | XOR CX,CX ; CX := Length of the escape seq;AN000; | ||
| 716 | MOV CL,[BX].NUM_GRAPHICS_ESC ;AN000; | ||
| 717 | MOV BX,[BX].GRAPHICS_ESC_PTR ; BX := Offset sequence to send ;AN000; | ||
| 718 | ADD BX,BP ;AN000; | ||
| 719 | ;AN000; | ||
| 720 | SEND_1_GRAPHICS_BYTE: ;AN000; | ||
| 721 | MOV AL,[BX] ; AL := byte to print ;AN000; | ||
| 722 | CALL PRINT_BYTE ; Send it to the printer ;AN000; | ||
| 723 | JC NEW_PRT_LINE_ENDP ; If printer error, quit the loop ;AN000; | ||
| 724 | INC BX ; Get next byte ;AN000; | ||
| 725 | LOOP SEND_1_GRAPHICS_BYTE ;AN000; | ||
| 726 | ;AN000; | ||
| 727 | NEW_PRT_LINE_ENDP: ;AN000; | ||
| 728 | POP DI ;AN000; | ||
| 729 | POP DX ;AN000; | ||
| 730 | POP CX ;AN000; | ||
| 731 | POP BX ;AN000; | ||
| 732 | POP AX ;AN000; | ||
| 733 | RET ;AN000; | ||
| 734 | NEW_PRT_LINE ENDP ;AN000; | ||
| 735 | PAGE ;AN000; | ||
| 736 | ;===============================================================================;AN000; | ||
| 737 | ; ;AN000; | ||
| 738 | ; PRINT_BYTE : SEND A BYTE TO THE PRINTER AT LPT1 ;AN000; | ||
| 739 | ; ;AN000; | ||
| 740 | ;-------------------------------------------------------------------------------;AN000; | ||
| 741 | ; ;AN000; | ||
| 742 | ; INPUT: AL = Byte to be printed ;AN000; | ||
| 743 | ; ;AN000; | ||
| 744 | ; OUTPUT: PRINTER ;AN000; | ||
| 745 | ; ERROR_CODE = PRINTER_ERROR if an error is detected. ;AN000; | ||
| 746 | ; Carry flag is set in case of error. ;AN000; | ||
| 747 | ; ;AN000; | ||
| 748 | ;-------------------------------------------------------------------------------;AN000; | ||
| 749 | PRINT_BYTE PROC NEAR ;AN000; | ||
| 750 | PUSH AX ;AN000; | ||
| 751 | PUSH DX ;AN000; | ||
| 752 | ;AN000; | ||
| 753 | MOV DX,0000 ; PRINTER NUMBER ;AN000; | ||
| 754 | MOV AH,00 ; REQUEST PRINT ;AN000; | ||
| 755 | INT 17H ; CALL BIOS : SEND THE CHARACTER ;AN000; | ||
| 756 | ;AN000; | ||
| 757 | AND AH,00101001B ; Test error code returned in AH for ;AN000; | ||
| 758 | ; "Out of paper", "I/O error" and "Time-out". ;AN000; | ||
| 759 | JNZ PRINT_BYTE_ERROR; Set the error code if error ;AN000; | ||
| 760 | JMP SHORT PRINT_BYTE_END ; else, return normally ;AN000; | ||
| 761 | PRINT_BYTE_ERROR: ;AN000; | ||
| 762 | MOV ERROR_CODE,PRINTER_ERROR ;AN000; | ||
| 763 | STC ; Set the carry flag to indicate ERROR ;AN000; | ||
| 764 | PRINT_BYTE_END: ;AN000; | ||
| 765 | POP DX ;AN000; | ||
| 766 | POP AX ;AN000; | ||
| 767 | RET ;AN000; | ||
| 768 | PRINT_BYTE ENDP ;AN000; | ||
| 769 | PAGE ;AN000; | ||
| 770 | ;===============================================================================;AN000; | ||
| 771 | ; ;AN000; | ||
| 772 | ; READ_DOT: READ A PIXEL - RETURN A COLOR TRANSLATION TABLE INDEX ;AN000; | ||
| 773 | ; ;AN000; | ||
| 774 | ;-------------------------------------------------------------------------------;AN000; | ||
| 775 | ; ;AN000; | ||
| 776 | ; INPUT: CUR_MODE = Current video mode. ;AN000; | ||
| 777 | ; CUR_ROW, ;AN000; | ||
| 778 | ; CUR_COLUMN = Coordinates of the pixel to be read. ;AN000; | ||
| 779 | ; CUR_PAGE = Active page number ;AN000; | ||
| 780 | ; ;AN000; | ||
| 781 | ; OUTPUT: AL = Index into COLOR TRANSLATION TABLE. ;AN000; | ||
| 782 | ; ;AN000; | ||
| 783 | ; DEPENDENCIES : COLOR TRANSLATION TABLE entries must be bytes ;AN000; | ||
| 784 | ; ;AN000; | ||
| 785 | ; ;AN000; | ||
| 786 | ;-------------------------------------------------------------------------------;AN000; | ||
| 787 | ; ;AN000; | ||
| 788 | ; DESCRIPTION: Use VIDEO BIOS INTERRUPT 10H "READ DOT CALL". ;AN000; | ||
| 789 | ; ;AN000; | ||
| 790 | ; Depending on the video hardware, the dot returned by BIOS has ;AN000; | ||
| 791 | ; different meanings. ;AN000; | ||
| 792 | ; With an EGA it is an index into the Palette registers, ;AN000; | ||
| 793 | ; With a CGA it is a number from 0 to 3, mapping to a specific color ;AN000; | ||
| 794 | ; depending on the background color and the color palette currently ;AN000; | ||
| 795 | ; selected. ;AN000; | ||
| 796 | ; ;AN000; | ||
| 797 | ; The Color Translation table has been set up to hold the correct color ;AN000; | ||
| 798 | ; mapping for any "dot" in any mode. Therefore, the dot number returned ;AN000; | ||
| 799 | ; by INT 10H can be used with any mode as a direct index within that ;AN000; | ||
| 800 | ; table. ;AN000; | ||
| 801 | ; ;AN000; | ||
| 802 | ; With APA Monochrome mode 0FH there are 4 different dots: white, ;AN000; | ||
| 803 | ; blinking white, high-intensity white, and black. ;AN000; | ||
| 804 | ; ;AN000; | ||
| 805 | ; For mode 0FH, the dot returned by interrupt 10 "read dot" call is a byte ;AN000; | ||
| 806 | ; where only bits 0 and 2 are significant. These 2 bits must be appended ;AN000; | ||
| 807 | ; together in order to obtain a binary number (from 0 to 3) that will be used ;AN000; | ||
| 808 | ; as an index in the Color Translation table. ;AN000; | ||
| 809 | ; ;AN000; | ||
| 810 | ; For mode 11H, the dot is either 0 (for background color) or 7 (for the ;AN000; | ||
| 811 | ; foreground color) only the LSB is returned. That is, we return either ;AN000; | ||
| 812 | ; 0 or 1. ;AN000; | ||
| 813 | ; ;AN000; | ||
| 814 | ; LOGIC: ;AN000; | ||
| 815 | ; ;AN000; | ||
| 816 | ; Call VIDEO BIOS "READ DOT" ;AN000; | ||
| 817 | ; IF CUR_MODE = 0FH ;AN000; | ||
| 818 | ; THEN ;AN000; | ||
| 819 | ; Append bits 1 and 3. ;AN000; | ||
| 820 | ; IF CUR_MODE = 11H ;AN000; | ||
| 821 | ; THEN ;AN000; | ||
| 822 | ; Wipe out bits 1 and 2. ;AN000; | ||
| 823 | ; ;AN000; | ||
| 824 | READ_DOT PROC NEAR ;AN000; | ||
| 825 | PUSH BX ; Save registers ;AN000; | ||
| 826 | PUSH CX ;AN000; | ||
| 827 | PUSH DX ;AN000; | ||
| 828 | ;AN000; | ||
| 829 | MOV BH,CUR_PAGE ;AN000; | ||
| 830 | MOV DX,CUR_ROW ;AN000; | ||
| 831 | MOV CX,CUR_COLUMN ;AN000; | ||
| 832 | MOV AH,READ_DOT_CALL ;AN000; | ||
| 833 | INT 10H ; Call BIOS: AL <-- Dot read ;AN000; | ||
| 834 | ;AN000; | ||
| 835 | CMP CUR_MODE,0FH ; Is it Mode 0fH ? ;AN000; | ||
| 836 | JNE MODE_11H? ; No, look for mode 11h. ;AN000; | ||
| 837 | ;-------Mode 0Fh is the current mode: ;AN000; | ||
| 838 | ;-------Convert bits 2 and 0 into a 2 bit number: ;AN000; | ||
| 839 | MOV BL,AL ; BL := AL = "Pixel read" ;AN000; | ||
| 840 | AND BL,00000100B ; Wipe off all bits but bit 2 in BL ;AN000; | ||
| 841 | AND AL,00000001B ; Wipe off all bits but bit 0 in AL ;AN000; | ||
| 842 | SHR BL,1 ; Move bit 2 to bit 1 in BL ;AN000; | ||
| 843 | OR AL,BL ; Append bit 1 and bit 0 ;AN000; | ||
| 844 | JMP SHORT READ_DOT_END ; Quit. ;AN000; | ||
| 845 | ;AN000; | ||
| 846 | MODE_11H?: ;AN000; | ||
| 847 | CMP CUR_MODE,11H ; Is it Mode 0fH ? ;AN000; | ||
| 848 | JNE READ_DOT_END ; No, quit ;AN000; | ||
| 849 | ;AN000; | ||
| 850 | ;-------Mode 11H is the current mode: ;AN000; | ||
| 851 | AND AL,00000001B ; Keep only the Least significant bit ;AN000; | ||
| 852 | ;AN000; | ||
| 853 | READ_DOT_END: ;AN000; | ||
| 854 | POP DX ; Restore registers ;AN000; | ||
| 855 | POP CX ;AN000; | ||
| 856 | POP BX ;AN000; | ||
| 857 | RET ;AN000; | ||
| 858 | READ_DOT ENDP ;AN000; | ||