home *** CD-ROM | disk | FTP | other *** search
- Unit grafdump;
-
- Interface
-
- Uses
- dos, graph;
-
- Procedure hardcopy(inverse: boolean;
- gmode, gdevice: integer);
-
- { MGA, CGA, Herc, EGA, VGA Graphics screen dump routine
- for EPSON compatible printers. Turbo Pascal, v4 or better
-
- Any non black screen pixel (in first page) is printed. }
-
-
- Implementation
-
- Procedure hardcopy(inverse: boolean;
- gmode, gdevice: integer);
-
- { Inverse true produces an inverse image.
- Gmode and gdevice are the arguments returned from Turbo's
- InitGraph procedure.
-
- Dot spacing (mode) and multiples of each byte across the page
- are manipulated to give the 'best' aspect ratio on the print.
-
- Mode: 1 = Double-Density 120 dpi, 2 = High-Speed D-D 120 dpi
- 3 = Quad-Density 240 dpi, 4 = 80 dpi
- 5 = 72 dpi, 6 = 90 dpi
- 0 = 60 dpi.
-
- Pre-FX series of EPSON printers should only use Mode 1.
-
- This routine uses mode 2 for VGAHi (ymaxglbl=479) and CGACn
- (xmaxglb=319), - mode 6 for all other gmodes.
- CGACn print is 1/2 page and crude, rest are full page
-
- Nb. Uses ReadMode 1 for EGA & VGA to cmp black with all bit planes.
-
- Reference : "Programmers guide to PC & PS/2 Video System"
- R Wilton, MicroSoft Press, 1987
- Graft: Gordon Findlay, Christchurch School of Medicine
- (gordon%chmeds.ac.nz@cunyvm.cuny.edu)
- Mac McLennan, Forest Research Institute
- Christchurch, New Zealand
- }
-
- Const
- esc = 27;
- lptportnum = 1; { Defaults to LPT1. 2 = LPT2 }
-
- Var
- regs: registers;
- boff: integer;
- mode, pbyte, sb, i, j, n1, n2: byte;
- pwide, grafbase, ymaxglb, xmaxglb: word;
-
-
- Function nextpbyte(x, y: word): byte;
-
-
- Begin
- Case gdevice Of
- cga:
- If (gmode = cgahi) Then
- pbyte := mem[grafbase: (y shr 1) * 80 + (y And
- 1) * $2000 + (x shr 3)]
- Else
- Begin
- pbyte := 0;
- i := 0;
- boff := (y shr 1) * 80 + (y And 1) * $2000 + (x shr 2);
- Repeat
- sb := mem[grafbase: boff + i];
- j := 0;
- Repeat
- pbyte := pbyte shl 1;
- If ((sb And $c0) > 0) Then
- inc(pbyte);
- sb := sb shl 2;
- inc(j);
- Until (j > 3);
- inc(i);
- Until (i > 1);
- End;
-
- vga, ega, ega64, egamono:
- pbyte := Not mem[grafbase: (y * 80 + (x shr 3))];
-
- hercmono:
- pbyte := mem[grafbase: (y And
- 3)shl 13 + 90 * (y shr 2) + (x shr 3)];
-
- Else
- pbyte := 0 { should never happen }
- End;
-
- If inverse Then
- nextpbyte := Not pbyte
- Else
- nextpbyte := pbyte;
- End;
-
-
- Procedure sendbyte(pb: byte);
- { Send one byte to the printer }
-
- Begin
- regs.ah := 0;
- regs.al := pb;
- regs.dx := pred(lptportnum);
- intr($17, regs);
- End; { SendByte }
-
-
- Procedure dumpgraf;
-
- Var
- xi, yi: integer; { Pixel coordinates }
-
-
- Procedure printaline;
-
- Begin
- { Select 8-Pin graphics print mode for each line }
- sendbyte(esc);
- sendbyte(ord('*'));
- sendbyte(mode);
- sendbyte(n1);
- sendbyte(n2); { dots on line }
-
- { Get the next print line off the screen, bottom of screen
- is the lh side of the paper. Each byte is 8 pixels in the
- X coordinate and 1 in the Y, and is printed twice to improve
- aspect ratio (except where ymaxglb = 199 - printed 3x). }
-
- yi := ymaxglb;
- Repeat
- pbyte := nextpbyte(xi, yi); { Each byte is 1 pixel (Y axis)}
- sendbyte(pbyte);
- sendbyte(pbyte);
- If (ymaxglb < 200) Then
- sendbyte(pbyte);
- dec(yi);
- Until (yi < 0);
- sendbyte(10); { Send LF }
- End;
-
-
- Begin
- xi := 0;
- Repeat
- printaline; { Each printed line is 8 pixels deep (X axis) }
- inc(xi, 8);
- Until (xi > xmaxglb);
- sendbyte(13);
- sendbyte(12); { Send CR & FF }
- End; { DumpGraf }
-
-
- Function checkprt: boolean;
- { Check Printer connected, online and has paper, If not then BEEP }
-
- Begin
- regs.ax := $200;
- regs.dx := pred(lptportnum);
- intr($17, regs);
- regs.ah := regs.ah xor $80;
- regs.ah := regs.ah And $A9;
- If (regs.ah <> 0) Then
- Begin
- writeln(#7,#7);
- checkprt := false;
- End
- Else
- checkprt := true;
- End;
-
-
- Begin { HardCopy }
- If Not checkprt Then
- exit; { and beep }
- Case gdevice Of
- cga:
- Begin
- grafbase := $B800;
- ymaxglb := 199;
- If (gmode = cgahi) Then
- xmaxglb := 639
- Else
- xmaxglb := 319;
- End;
- ega, ega64, egamono:
- Begin
- grafbase := $A000;
- xmaxglb := 639;
- ymaxglb := 349;
- portw[$3CE] := $805; { Set ReadMode = 1 - all bit planes cmpd.}
- { Defaults assumed:- Color Don't Care register = $0F }
- { - Color Compare register = $00 }
- End;
- vga:
- Begin
- grafbase := $A000;
- xmaxglb := 639;
- portw[$3CE] := $805;
- Case gmode Of
- vgalo:
- ymaxglb := 199;
- vgamed:
- ymaxglb := 349;
- vgahi:
- ymaxglb := 479;
- End;
- End;
- hercmono:
- Begin
- grafbase := $B000;
- xmaxglb := 719;
- ymaxglb := 347
- End;
- Else
- exit
- End;
-
- sendbyte(esc); { Select 24/216-inch line spacing }
- sendbyte(ord('3'));
- sendbyte(24);
-
- If ((xmaxglb < 320) Or (ymaxglb = 479)) Then
- mode := 2
- Else
- mode := 6;
- pwide := ymaxglb + 1;
- If (ymaxglb < 200) Then
- pwide := pwide * 3
- Else
- pwide := pwide shl 1;
- n1 := lo(pwide); { Determine 2 byte control code for }
- n2 := hi(pwide); { the number of dots per print line }
-
- dumpgraf;
-
- If (gdevice In [vga, ega, ega64, egamono]) Then
- portw[$3CE] := 5;
-
- sendbyte(esc);
- sendbyte(2); { Reset to 1/6-inch line spacing }
- End; { HardCopy }
-
-
- End.
-