Q51859: How to Print Images on SCREENs 7 Through 12 to Epson Printer
Article: Q51859
Product(s): See article
Version(s): 4.00 4.00b 4.50
Operating System(s): MS-DOS
Keyword(s): ENDUSER | B_BasicCom appnote BQ0085 | mspl13_basic
Last Modified: 18-OCT-1990
The program listing below demonstrates one method of printing an EGA
or VGA SCREEN 7, 8, 9, 10, 11, or 12 image to an Epson printer (or
compatible) with graphics capability.
This information applies to Microsoft QuickBASIC versions 4.00, 4.00b,
and 4.50 for MS-DOS; to Microsoft BASIC Compiler versions 6.00 and
6.00b for MS-DOS; and to Microsoft BASIC PDS (Professional Development
System) versions 7.00 and 7.10 for MS-DOS. (Earlier versions do not
support VGA SCREEN 12.)
This article is one part of the application note titled "How to Print
BASIC Video Screens to Epson Printers." A printed copy of this
application note can be obtained by calling Microsoft Product Support
Services at (206) 637-7096. This application note can also be obtained
in separate parts in this Knowledge Base by searching for the
following words:
Epson and print and screen and QuickBASIC
If you have a printer other than an Epson, you must change the printer
control codes used in the following program for setting line spacing
and graphics mode. Control codes can be found in your printer's
manual.
The routine below for printing EGA and VGA SCREEN modes 7 through 12
is required only if you aren't running under MS-DOS version 4.00 or
later. In MS-DOS 4.00 and later, the program GRAPHICS.COM supports all
standard EGA and VGA SCREEN modes. Thus, the routine given in a
separate article (part of the same application note) for printing CGA
SCREEN modes can be used to print EGA and VGA SCREENs in MS-DOS 4.00
and later.
If you want further information about graphics memory and the various
graphics modes, please refer to the following book, which is available
in bookstores or by calling Microsoft Press at (800) 888-3303 or (206)
882-8661:
"Programmer's Guide to PC and PS/2 Video Systems," by Richard
Wilton (published by Microsoft Press, 1987)
Printing EGA or VGA Screen Modes 7 Through 12
---------------------------------------------
Because EGA and VGA memory are stored in contiguous blocks per
"plane," printing the screen to a printer can be a fairly simple
operation. The method used in the program below prints the image
sideways, which avoids the need to do any bit-shifting and uses a
simple two-dots-per-pixel shading pattern to represent different
colors.
To produce different patterns for different colors, each color plane
must be analyzed. In SCREEN modes with four video planes (7, 8, 9, and
12), each of the four different base EGA/VGA colors -- blue, green,
red, and intensity -- is represented in a separate memory bank or
plane of EGA/VGA memory. Each bit in a color plane represents a pixel
on the screen; thus, each pixel on the screen has a color attribute
depicted by four bits, one in each color plane.
Each plane is addressed for reading/writing by selecting the bank of
memory to access with an OUT instruction. This program logically OR's
the blue and red planes together and does the same with the green and
intensity planes. This effectively reduces the number of pattern
(color) combinations from 16 to 4. Therefore, some colors that appear
to be different on the screen have the same appearance on paper.
SCREEN modes 10 and 11 are almost identical, except that there are
only two color planes; thus, each pixel on the screen has a color
attribute depicted by two bits, one in each of the two color planes.
Because there are only two bits per pixel and two pins are being
fired, no OR'ing of the color planes needs to be done.
The Epson printer can fire up to eight pins per graphics byte sent.
Thus, moving from left to right, a loop that reads screen data from
the bottom of the screen upward can access eight vertical columns at a
time. This behavior coincides with the printer firing eight pins at a
time and creates eight horizontal columns on the page, turning the
printout sideways.
DECLARE SUB ScreenParams (scrn%, ScreenWidth%, ScreenLength%, NP%)
DECLARE SUB DRAWPIC (scrn%)
DECLARE SUB VGAtoEpson (scrn%, f$, flip%, border%)
' Demonstrates the use of VGAtoEpson, a subprogram that dumps
' a SCREEN 7, 8, 9, 10, 11 or 12 image to an Epson printer.
CLS : scrn% = 0
WHILE (scrn% < 7) OR (scrn% > 12)
INPUT "Enter Screen Mode: (7, 8, 9, 10, 11 or 12)"; scrn%
WEND
SCREEN scrn% : CALL DRAWPIC(scrn%) ' Draw the picture
CALL VGAtoEpson(scrn%, "LPT1", 0, 255) ' Do the VGA screen print
END
SUB DRAWPIC (scrn%) ' Draw picture on screen
CALL ScreenParams(scrn%, ScreenWidth%, ScreenLength%, NumPlanes%)
IF NumPlanes% = 2 THEN ci% = 0 ELSE ci% = 1 ' Color increment
xmax% = ScreenWidth% : ymax% = ScreenLength%
halfx% = xmax% / 2 : halfy% = ymax% / 2
x% = halfx% : c% = 1
FOR y% = ymax% TO halfy% STEP -5
deltax% = xmax% - x% : deltay% = ymax% - y%
LINE (halfx%, y%)-(x%, halfy%), c%
LINE (x%, ymax%)-(xmax%, y%), c% + ci%
LINE (halfx%, deltay%)-(x%, halfy%), c% + 2 * ci%
LINE (x%, 0)-(xmax%, deltay%), c% + 3 * ci%
LINE (halfx% + 1, y%)-(deltax%, halfy%), c% + 4 * ci%
LINE (deltax%, ymax%)-(0, y%), c% + 5 * ci%
LINE (halfx%, deltay%)-(deltax%, halfy% + 1), c% + 6 * ci%
LINE (deltax%, 0)-(0, deltay%), c% + 7 * ci%
x% = x% + (((xmax% + 1) / (ymax% + 1)) * 5)
NEXT y%
END SUB
SUB ScreenParams (scrn%, ScreenWidth%, ScreenLength%, NumPlanes%)
' Return the screen dimensions in pixels
' and the number of planes.
NumPlanes% = 4 ' Set default values for SCREEN 12
ScreenWidth% = 640 : ScreenLength% = 480
SELECT CASE scrn% ' Change values for other SCREEN modes
CASE 7
ScreenWidth% = 320 : ScreenLength% = 200
CASE 8
ScreenLength% = 200
CASE 9
ScreenLength% = 350
CASE 10
NumPlanes% = 2 : ScreenLength% = 350
CASE 11
NumPlanes% = 2
END SELECT
END SUB
SUB VGAtoEpson (scrn%, fileN$, flip%, border%) STATIC
' Sends the image on SCREEN 7, 8, 9, 10, 11 or 12
' to an Epson printer.
' Parameters:
' scrn% - SCREEN video mode of screen to print (7 through 12)
' fileN$ - Name of file or device to send image to
' flip% - Invert flag (0 = normal, not 0 = invert)
' border% - Character to use for border drawing on screens
' 9 and 10 (0 = none, 255 = solid, etc.)
OPEN fileN$ FOR BINARY AS 1 'Open the output file
WIDTH #1, 255
esc$ = CHR$(27) : crlf$ = CHR$(13) + CHR$(10)
line$ = esc$ + "A" + CHR$(8) 'Set printer to 8/72 lpi"
PUT #1, , line$
CALL ScreenParams(scrn%, ScreenWidth%, ScreenLength%, NumPlanes%)
IF ScreenLength% < 480 THEN ' Figure how many bytes to send
numbyte% = ScreenLength% * 2 + 16 ' to printer for one
maxy% = ScreenLength% - 1 ' line of graphics.
ELSE
numbyte% = 960 : maxy% = 479
END IF
DEF SEG = &HA000 'Start of EGA/VGA screen memory
BorderOffset% = (960 - numbyte%) / (2 * 8)
IF ScreenLength% < 480 THEN
' Print top line for border on screens where border will fit
line$ = SPACE$(BorderOffset%) '(for margin)
PUT #1, , line$
line$ = esc$ + "L" + MKI$(numbyte%)
line$ = line$ + STRING$(numbyte%, border%) + crlf$
PUT #1, , line$
END IF
' This loop is the horizontal byte location
colend% = (ScreenWidth% / 8) - 1
FOR col% = 0 TO colend%
' Set the printer up to receive 716 or 960 bytes
' of graphics data
IF ScreenLength% < 480 THEN
line$ = SPACE$(BorderOffset%)
PUT #1, , line$ '(for border)
END IF
line$ = esc$ + "L" + MKI$(numbyte%) '(for init)
PUT #1, , line$
IF ScreenLength% < 480 THEN
line$ = STRING$(8, border%)
PUT #1, , line$ '(for border)
END IF
'--- This loop is the vertical byte position
FOR row% = maxy% TO 0 STEP -1
' For 4 plane screens (7, 8, 9 and 12) logically OR the blue
' plane with the red plane, send that byte, then OR the green
' plane with the intensity plane and send that byte.
' For screens 10 and 11, the video planes are sent directly
' to the printer.
FOR plane% = 0 TO 1 'Plane (* 2) set
OUT &H3CE, 4 : OUT &H3CF, plane%
place& = row% 'Figure out screen memory
place& = place& * (colend% + 1) ' location to read - use
place& = place& + col% ' a long to avoid overflow.
mem% = PEEK(place&)
IF NumPlanes% = 4 THEN ' OR color planes together
OUT &H3CE, 4 : OUT &H3CF, plane% + 2
mem% = mem% OR PEEK(place&)
END IF
'--- Flip the byte if need be (inverses printed picture)
IF flip% <> 0 THEN mem% = 255 - mem%
line$ = CHR$(mem%) : PUT #1, , line$
NEXT plane%
NEXT row%
line$ = crlf$ ' Default for no border
IF ScreenLength% < 480 THEN
line$ = STRING$(8, border%) + crlf$ ' Righthand border
END IF
PUT #1, , line$
NEXT col%
IF ScreenLength% < 480 THEN '--- Print bottom line for border
line$ = SPACE$(BorderOffset%) '(for margin)
PUT #1, , line$
line$ = esc$ + "L" + MKI$(numbyte%)
line$ = line$ + STRING$(numbyte%, border%) + crlf$
PUT #1, , line$
END IF
ResetPrn$ = esc$ + "@"
PUT #1, , ResetPrn$ ' Reset printer
line$ = CHR$(12) : PUT #1, , line$ ' Send formfeed (page eject)
CLOSE 1 ' All done
END SUB
THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.
Copyright Microsoft Corporation 1986-2002.