home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
BEEHIVE
/
UTILITYS
/
PUDD.ARC
/
PUDD-04.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-08-11
|
15KB
|
422 lines
{**************************************************************************
Print is the procedure used to print the screen to a dot matrix
printer. It is commented more extensively to help you modify it
for your own printer. It will run without modification on an MX-80
Concepts:
Each dot on the screen is repesented by a bit. There are
8 bits in a byte. Each horizontal row has 640 dots which
means 80 bytes. The procedure GetLine will return a 80 byte
array from the specified horizontal row. Since the Epson
printer uses 8 vertical dots for each graphic line, the
procedure uses groups of 8 rows to form each line for the
printer. In pascal, this means I have used an array of
array. That is each screen line is an 80 byte array and
each printer line is an array of 8 screen lines.
Once a group of screen lines is built a group of 8 bytes
arranged vertically, are taken off. This grouping is better
thought of as an 8x8 bit array. At this point each byte
represents a horizontal series of 8 dots. The printer has
a vertical set of wires to print 8 dots and must have the
information passed as a byte representing 8 dots in a vertical
series. For this reason the 8x8 array must be turned 90 degrees.
The initial group of 8 bytes is the var TempBlock. As TempBlock
is passed into PrintHead it is turned 90 degrees. At this point
PrintHead has info that is all ready for the printer. It would
make sense to say
for i := 1 to 8
write(lst,PrintHead[i]);
except Turbo thinks of PrintHead[i] as a number and therefore will
send ascii digits to the printer which will represent a number.
Remember (ascii 8) <> 8 in hex or decimal or anything else. To
get this information in a raw form to the printer it must be done
like
for i := 1 to 8
write(lst,chr(PrintHead[i]);
After 80 PrintHeads are done, the entire NextLine has been printed.
At that point a new NextLine is created. Since there are 240 screen
lines and 8 screen line in each NextLine, the loop printing NextLine
will repeat 30 times.
The only other thing worth mentioning is that the Epson needs this
info preceeded by a command which tells it to print a graphic
row and exactly how long that row will be. I have also added some
blanks ahead of each line to center the picture.
I almost forgot, ReadByte is used to look into a byte. It returns
a charactor string of 0's and 1's which directly represent the
byte in question. This is slower than creating an assembly
language routine to do the same thing but a lot easier to
use. With ReadByte you can analize bits using regular pascal
string procedures.
******************************************************************************}
procedure print1;
type EpsonLine = array[1..8] of ScanLine; {............ 8 horiz rows to print }
var i,j :integer;
y :integer;
block,column,offset,rowset,rowsingle :integer;
command :string[5]; {........a command to send to the printer }
NextLine :EpsonLine; {.........the printer line, an array of array }
PrintHead :array[1..8] of byte; { a 8x8 or byte by byte block of points }
TempBlock :array[1..8] of byte;
readout :Blist;
response :char; {.......used to dump out of procedure/ }
begin
command := #27 + #65 + #8; {.................................set line height }
writeln(lst,command);
y := 239;
rowset := 0;
repeat
rowset := rowset + 1; {...................rows are groups of 8 pixel rows}
{ there are 30 rows starting at y := 239 }
offset := 1;
{...........................what follows is the part that builds the NextLine }
for i := 1 to 8 do
begin
GetLine(y,ByteList);
NextLine[i] := ByteList;
y := y - 1;
end; {......NextLine is ready }
command := #27 + #76 + #32 + #3; {.................set graphic mode }
write(lst,command);
{......................................................center the picture }
for i := 1 to 160 do {.......................by sending 160 blank dots }
begin
write(lst,chr(0));
end;
{.................................what follows will print one entire NextLine }
for block := 1 to 80 do {........... 80 horz blocks of 8 dots in each row }
begin
for rowsingle := 1 to 8 do {....................build an 8x8 bit array }
begin
TempBlock[rowsingle] := NextLine[rowsingle,offset];
end;
offset := offset + 1;
{.........what follows will turn the TempBlock 1/4 turn into PrintHead }
for i := 1 to 8 do
PrintHead[i] := 0; {............................initialize printhead }
for i := 1 to 8 do
begin
ReadByte(TempBlock[i],readout); {...................look into a byte }
for j := 1 to 8 do
begin
if copy(readout,j,1) = '1' then {.......... if any bits are set }
SetBitB(8-i,PrintHead[j]); { then set corresponding bits }
end;
end; {.........................now printhead has 8 bytes to print }
{.....................................................sending to printer }
for j := 8 downto 1 do
begin
write(lst,chr(PrintHead[j]));
end;
end; {...........................................horizontal block loop}
writeln(lst); {.............................bumps paper up for next line }
delay(300); {....delay needed to pick up keypressed }
{..the software will still run faster than the printer despite delay }
until (rowset = 30) or (keypressed);
{......................row loop, another NextLine bites the ink }
{..............................................while loop to dump out }
writeln(lst);
headline; {.......restores the menu screen }
command := #27 + #65 + #9; {..........you should always put your toys back }
writeln(lst,command); { the way you found them ! }
{...ie: restore printer to default line height }
end; {................................................................print }
{*****************************************************************************
* print2 will take print to an Epson MX-80 or similar. The printout will *
* be about 8.89" x 6.67". The aspect ratio is corrected by using every *
* 3rd dot 4 times and all other dots 3 times. This shows up as a slight *
* bumpyness in diagnal lines. The short line width is much less than the *
* long line width. *
*****************************************************************************}
procedure print2;
var i,j :integer;
printcycle :integer;
point :integer;
screenrow :integer;
screenlist :ScanLine;
printline :array[1..800] of byte absolute $20E3;
command :string[4];
begin
command := #27 + #65 + #8; {.................................set line height }
writeln(lst,command);
printcycle := 0;
repeat
printcycle := printcycle + 1;
point := 1;
for screenrow := 0 to 239 do
begin
GetLine(screenrow,screenlist);
if screenrow mod 3 = 0 then
begin
for i := 1 to 4 do
begin
printline[point] := screenlist[printcycle];
point := point + 1;
end;
end
else
begin
for i := 1 to 3 do
begin
printline[point] := screenlist[printcycle];
point := point + 1;
end
end;
end; {screenrow}
command := #27 + #76 + #32 + #3; {.................set graphic mode }
write(lst,command);
for i := 1 to 800 do
begin
write(lst,chr(Printline[i]));
end;
writeln(lst);
delay(180);
until (printcycle = 80) or (keypressed);
command := #12; {.....put paper to top of form }
write(lst,command);
command := #27 + #65 + #12; {.....reset the line height to default }
write(lst,command);
end;
{*****************************************************************************
* print3 will take print to an Epson MX-80 or similar. The printout will *
* be centered on 8.5 x 11 paper and will form a 7.5 x 10 image. With this *
* size each dot is a 1/32" x 1/64" rectangle. The width of the dots comes *
* from the fact that each row is printed twice with a 1/72" offset. *
* The 7.5" dimension is derived from using each 4th dot 3 times and all *
* other dots 4 times. This is done in the screenrow mod 4 statement. *
* The printout takes so long that is is assumed the operator has gone *
* to get a beer from the fridge or some such thing. For this reason the *
* bell is rung when the print is finally done. *
*****************************************************************************}
procedure print3;
var i,j :integer;
printcycle :integer;
point :integer;
screenrow :integer;
screenlist :ScanLine;
printline :array[1..900] of byte absolute $20E3;
command :string[4];
begin
command := #27 + #65 + #8; {.................................set line height }
writeln(lst,command);
for i := 1 to 2 do {.....center on the long dimension }
writeln(lst);
printcycle := 0;
repeat
printcycle := printcycle + 1;
point := 1;
for screenrow := 0 to 239 do
begin
GetLine(screenrow,screenlist);
if screenrow mod 4 = 0 then
begin
for i := 1 to 3 do
begin
printline[point] := screenlist[printcycle];
point := point + 1;
end;
end
else
begin
for i := 1 to 4 do
begin
printline[point] := screenlist[printcycle];
point := point + 1;
end
end;
end; {screenrow}
write(lst,' '); {.......center on the short dimension }
command := #27 + #76 + #132 + #3; {.................set graphic mode }
write(lst,command);
for i := 1 to 900 do
begin
write(lst,chr(Printline[i]));
end;
command := #27 + #65 + #1; {...........set line height to 1/72" }
write(lst,command); {...........move up}
writeln(lst);
write(lst,' '); {.......center on the short dimension }
command := #27 + #76 + #132 + #3; {.................set graphic mode }
write(lst,command);
for i := 1 to 900 do {.....rewrite the same line over again }
begin
write(lst,chr(Printline[i]));
end;
command := #27 + #65 + #8; {..........................set line height }
write(lst,command);
writeln(lst);
delay(180); {......this is needed to catch the keypressed }
until (printcycle = 80) or (keypressed);
command := #12; {.....put paper to top of form }
write(lst,command);
command := #27 + #65 + #12; {.....reset the line height to default }
write(lst,command);
command := #7; {......#7 rings the bell }
for i := 1 to 5 do
write(lst,command);
end;
procedure print;
var response :char;
begin
clrscr;
gotoXY(0,10);
writeln(' Please select print style..... ');
writeln;
writeln(' 1) Small, horizontal with 17% aspect ratio error');
writeln;
writeln(' 2) Large, vertical with correct aspect ratio');
writeln;
writeln(' 3) Large, vertical. Exactly 8.5" x 10" centered');
writeln(' on the page. Correct aspect ratio and');
writeln(' fractional representation.');
repeat
read(kbd,response);
until (response = '1') or (response = '2') or (response = '3');
clrscr;
gotoXY(10,10);
write('Make sure printer is on-line');
gotoXY(10,12);
write('to cancel print press and hold any key........');
case response of
'1': print1;
'2': print2;
'3': print3;
end; {......case }
HeadLine;
end;
{****************************************************************************}
{* Display will display a section of text from the stated file *}
{****************************************************************************}
procedure Display(var fileName:textfile;section:integer);
var line :string[80];
i,j :integer;
temp :string[2];
found :boolean;
quit :boolean;
begin
clrscr;
found := false;
quit := false;
reset(filename);
repeat
if EOF(filename) then
begin
gotoXY(24,12);
write('Section requested not found !');
write(^G);
delay(2000);
found := true;
quit := true;
end
else
begin
Readln(filename,line);
if copy(line,1,7) = 'Section' then
begin
temp := copy(line,9,3);
val(temp,i,j);
delete(line,1,10);
if section = i then
found := true
end;
end;
until found;
i := 0;
if not(quit) then
begin
if section <> 0 then
writeln(line);
repeat
repeat
i := i + 1;
if not(EOF(filename)) then
readln(filename,line);
if not(copy(line,1,7) = 'Section') then
writeln(line);
if i = 22 then
begin
gotoXY(14,24);
write('-------------- press key to continue ---------------');
repeat until keypressed;
gotoXY(1,24);
clreol;
i := 0;
end;
until (copy(line,1,7) = 'Section') or EOF(filename);
until (copy(line,1,7) = 'Section') or EOF(filename);
if section <> 0 then
begin
gotoXY(14,24);
write('-------------- press key to continue ---------------');
repeat until keypressed;
gotoXY(1,24);
clreol;
end;
end;
end; {....................................display }
{****************************************************************************}
{* Help will use the doc file for on-line help. To work the doc file must *}
{* be a normal text file with each catagory starting "Section nn" *}
{****************************************************************************}
procedure Help;
var DocFile :textfile;
i,j :integer;
line :string[81];
sectionNum :integer;
temp :string[2];
begin {.........help }
if Exist('PUDD.DOC') then
begin
assign(DocFile,'PUDD.DOC');
reset(DocFile);
repeat
clrscr;
Display(DocFile,0);
gotoXY(1,24);
write(' Enter the section number of your choice......');
read(temp);
sectionNum := 0;
val(temp,SectionNum,i);
if SectionNum <> 0 then
Display(DocFile,SectionNum);
until sectionNum = 0;
end
else
begin
clrscr;
gotoXY(24,12);
write('file PUDD.DOC not found !');
write(^G);
delay(2000);
end;
end;