'===========================================================================
' Subject: Screen Dump to Epson Printer       Date: 12-14-02 (  :  )       
'  Author: Roger Oxford                       Code: QB,PDS                 
'  Origin: r.oxfordjr@worldnet.att.net      Packet: TEXT.ABC
'===========================================================================
REM ** PROGRAM NAME IS NEWDUMP.BAS and it was derived from MS.K.B. Q57354
'It Demonstrates the use of VGAtoEpson, a subprogram that dumps
'a SCREEN image in B & W (7,8,9,10,11 or 12) to a printer emulating an Epson.
'My IBM printer produces an image with gaps ( spaces ).
'DOES NOT REQUIRE GRAPHICS.COM FROM DOS 5!

Scrn% = 12     'YOU CAN DECLARE SCREEN MODE HERE TO TEST THE SYSTEM BUT
               'THIS ROUTINE CHAINED BEHIND YOUR GRAPHICS PATTERN
               'DOES NOT HAVE TO BE INFORMED OF THE SCREEN PARAMETERS.
SCREEN (Scrn%)
WIDTH 80, 30
PALETTE 0, 65536 * 60:
GOSUB 20000 'DRAW PICTURE ON SCREEN
LOCATE 1, 1: INPUT ""; j

'' "Name" & SAVE this part from here down to print a graphics screen by
'' using the command CHAIN "Name" after your graphics drawing is complete.
'' DERIVED FROM MS.K.B. Q57354
flip% = 0: FileN$ = "LPT1": border% = 255
GOSUB 14000: REM VGAtoEpson(Scrn%, "LPT1", 0, 255) Do the VGA screen print

SCREEN 0
REM CHAIN "your program"
SYSTEM

14000   : REM  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: REM prevents  auto line feed
 esc$ = CHR$(27): crlf$ = CHR$(13) + CHR$(10)
 line$ = esc$ + "A" + CHR$(7)    'Set printer to 8/72 lpi"
 PUT #1, , line$

 GOSUB 17000: REM 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 graphic 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
 
  line$ = CHR$(12): PUT #1, , line$' Send formfeed (page eject)
  ResetPrn$ = esc$ + "@"
  PUT #1, , ResetPrn$
  CLOSE 1           ' All MOST done
 REM END SUB
RETURN

REM **  Sub Screenparams(Scrn%,ScreenWidth%,ScreenLength%,NP%)
'THE FINDINGS OF THIS ROUTINE ARE RIGHT ON A DELL VGA MODE 1 OF 11:
'  SCREEN  1 @ 40 X 25 & 80 X 25   (639 x 199)   does not work
'  SCREEN  2 @ 80 X 25             (639 x 199)   does not work
'  SCREEN  7 @ 80 X 25             (639 x 199)
'  SCREEN  7 @ 40 X 25             (319 x 199)
'  SCREEN  8 @ 80 X 25                   (639 x 199)
'  SCREEN  9 & 10  @ 80 X 25 & 80 X 43   (639 x 349)
'  SCREEN 11 & 12 @ 80 X 30 & 80 X 60    (639 x 479)
17000 REM  Screenparams (Scrn%, ScreenWidth%, ScreenLength%, NP%)
      REM ** figure # OF TEXT RSS,COLS
      COLS = 80
      ON ERROR GOTO 17020
      LOCATE 1, COLS
      GOTO 17030
17020 IF COLS = 80 THEN LET COLS = 40: RESUME

17030 LET RSS = 60
17031 ON ERROR GOTO 17080
17036 LOCATE RSS, COLS
      GOTO 17250: REM ** IF MOUSE 6.26 OR LATER NOT AVAILABLE THEN GOTO 17250
                  REM ** VS LABLE 17200
17080 IF RSS = 60 THEN LET RSS = 50: RESUME
      IF RSS = 50 THEN LET RSS = 43: RESUME
      IF RSS = 43 THEN LET RSS = 30: RESUME
      IF RSS = 30 THEN LET RSS = 25: RESUME

17250 REM ** FIND SCREEN RESOLUTION the hard way
      LET maxx = 719: LET maxy = 1
      ON ERROR GOTO 17300
      VIEW (0, 0)-(maxx, maxy)
      GOTO 17350
17300 IF maxx = 719 THEN LET maxx = 639: RESUME
      IF maxx = 639 THEN LET maxx = 359: RESUME
      IF maxx = 359 THEN LET maxx = 319: RESUME
17350
      LET maxy = 479
      ON ERROR GOTO 17375
      VIEW (0, 0)-(maxx, maxy)
      IF Scrn% = 1 THEN LET maxx = 639: LET maxy = 199
      GOTO 17400
17375 IF maxy = 479 THEN LET maxy = 399: RESUME
      IF maxy = 399 THEN LET maxy = 349: RESUME
      IF maxy = 349 THEN LET maxy = 199: RESUME

17400 REM LET XPIX = (maxx + 1) / COLS: REM ** # X PIXLES / CHARACTER
      REM LET YPIX = (MAXY + 1) / RSS: REM ** # Y PIXLES / CHARACTER
    
17900 LET ScreenWidth% = maxx + 1: LET ScreenLength% = maxy + 1
'  SCREEN  1 @ 40 X 25 & 80 X 25   (639 x 199)  does not work
'  SCREEN  2 @ 80 X 25             (639 x 199)  does not work
'  SCREEN  7 @ 80 X 25             (639 x 199)
'  SCREEN  7 @ 40 X 25             (319 x 199)
'  SCREEN  8 @ 80 X 25                   (639 x 199)
'  SCREEN  9 & 10  @ 80 X 25 & 80 X 43   (639 x 349)
'  SCREEN 11 & 12 @ 80 X 30 & 80 X 60    (639 x 479)
Numplanes% = 4
    IF ScreenWidth% = 640 AND ScreenLength% = 479 AND RSS = 60 THEN Scrn% = 11: GOTO 17950 ' OR 12
    IF ScreenWidth% = 640 AND ScreenLength% = 479 AND RSS = 30 THEN Scrn% = 11: GOTO 17950 ' OR 12
    IF ScreenWidth% = 640 AND ScreenLength% = 350 AND RSS = 43 THEN Scrn% = 10: GOTO 17950  ' OR 9
    IF ScreenWidth% = 640 AND ScreenLength% = 350 AND RSS = 25 THEN Scrn% = 10: GOTO 17950  ' OR 9
    IF ScreenWidth% = 640 AND ScreenLength% = 200 AND RSS = 25 AND COLS = 80 THEN Scrn% = 8 ' OR 7
    IF ScreenWidth% = 320 AND ScreenLength% = 200 AND RSS = 25 AND COLS = 40 THEN Scrn% = 7
17950 IF Scrn% = 10 THEN Numplanes% = 2  'BECAUSE SCREENS 7,8,9,12
      IF Scrn% = 11 THEN Numplanes% = 2  'ARE 4 PLANES
      RETURN
 
20000
' DRAWPIC        ' Draw picture on screen
 GOSUB 17000: REM 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%
RETURN


