PAGE 50,132
TITLE PRTSC_1 - DUMP SCREEN GRAPHICS TO PRINTER
;               PROLOG - MODULE DESCRIPTION
;This subroutine dumps the displayed screen graphics to the printer.
;It will print either 320x200 or 640x200 graphics.  The former is
;printed with the printer in 480 mode, and the latter is printed 
;with the printer in 960 mode.
;  All registers are preserved.
CRT_MODE        EQU    49H     ;offset into BIOS data area
CSEG    SEGMENT PARA PUBLIC 'CODE'
GRMASK  DB      ?
PRTSC_1 PROC    FAR
        ASSUME  CS:CSEG
        PUBLIC  PRTSC_1
        PUSH    DS
        PUSH    SI
        PUSH    AX
        PUSH    BX
        PUSH    CX
        PUSH    DX
        MOV     AX,40H
        MOV     DS,AX   ;BIOS data segment
        MOV     AL,DS:[CRT_MODE]
        TEST    AL,6
        JNZ     PR1
        JMP     PRTSC_RET
PR1     LABEL   NEAR
        MOV     CL,'K'          ;480 mode
        MOV     CS:GRMASK,0C0H  ;320X200 graphics
        CMP     AL,6
        JL      PR2
        MOV     CL,'L'          ;960 mode
        MOV     CS:GRMASK,080H  ;640X200 graphics
PR2     LABEL   NEAR
        MOV     AX,0B800H       ;screen segment
        MOV     DS,AX
        MOV     AX,0141H        ;send ESC A 8 to printer for
        MOV     BL,8            ; 8/72" linefeeds
        CALL    ESC_SEQ
ROW     LABEL   NEAR
        MOV     AH,2            ;sen ESC K (or L) n1 n2 to printer
        MOV     AL,CL
        MOV     BX,0140H        ;=320 dots
        CMP     AL,'L'
        JNZ     RO1
        SHL     BX,1            ;=640 dots
RO1     LABEL   NEAR
        CALL    ESC_SEQ
        XOR     BX,BX
        PUSH    CX
COLUMN  LABEL   NEAR
        MOV     AH,CS:GRMASK
COL1    LABEL   NEAR
        MOV     DX,8000H
        MOV     CX,4
        MOV     SI,0
COL2    LABEL   NEAR
        MOV     AL,[BX][SI]
        AND     AL,AH
        JZ      COL3
        OR      DL,DH
COL3    LABEL   NEAR
        SHR     DH,1
        MOV     AL,[BX+2000H][SI]
        AND     AL,AH
        JZ      COL4
        OR      DL,DH
COL4    LABEL   NEAR
        SHR     DH,1
        ADD     SI,50H
        LOOP    COL2
        PUSH    AX
        MOV     AL,DL
        MOV     AH,0
        XOR     DX,DX
        INT     17H
        POP     AX
        SHR     AH,1
        MOV     AL,CS:GRMASK
        TEST    AL,40H
        JZ      COL5
        SHR     AH,1
COL5    LABEL   NEAR
        OR      AH,AH
        JNZ     COL1
        INC     BX
        MOV     AL,BL
        CMP     AL,50H
        JL      COLUMN
        MOV     AX,000AH        ;linefeed to printer
        XOR     DX,DX
        INT     17H
        TEST    AH,1
        JNZ     PRTSC_RET
        MOV     AX,DS
        ADD     AX,14H
        CMP     AL,0F4H
        MOV     DS,AX
        POP     CX
        JNE     ROW
        MOV     AX,0032H        ;send ESC 2 to printer
        CALL    ESC_SEQ         ;sets printer to 6 lines/inch
PRTSC_RET       LABEL   NEAR
        POP     DX
        POP     CX
        POP     BX
        POP     AX
        POP     SI
        POP     DS
        RET
PRTSC_1 ENDP
SUBTTL SUBROUTINE TO SEND ESC SEQUENCE TO PRINTER
        PAGE
;           PROLOG - MODULE DESCRIPTION
;This subroutine sends an ascii ESC character to the printer followed by the
;character in AL.  AH specifies the number of characters to follow the first
;two (0 if none, 1, or 2).  The first of these is in BL and the second in BH.
;All registers except AX are preserved.  AH contains printer status on return.
;The routine returns immediately on a timeout error.
ESC_SEQ PROC    NEAR
        PUSH    BX
        PUSH    CX
        PUSH    DX
        MOV     CX,AX           ;Save AX
        XOR     DX,DX           ;DX=0 indicates printer 1
        MOV     AX,001BH        ;AL='ESC'
        INT     17H             ;printer_io
        TEST    AH,1            ;timeout?
        JNZ     ESC_RET
        MOV     AL,CL           ;retrieve character
        MOV     AH,0
        INT     17H
        TEST    AH,1
        JNZ     ESC_RET
E1      LABEL   NEAR
        MOV     AL,CH
        CMP     AL,0            ;anymore characters to send?
        JZ      ESC_RET         ;return if done
        MOV     AL,BL           ;get next character
        MOV     AH,0
        INT     17H
        TEST    AH,1
        JNZ     ESC_RET
        MOV     BL,BH           ;put next character in BL
        DEC     CH
        JMP     E1              ;do until all characters sent
ESC_RET LABEL   NEAR
        POP     DX
        POP     CX
        POP     BX
        RET
ESC_SEQ ENDP
CSEG    ENDS
        END
