{$line+,$symtab-,$linesize:131,$pagesize:65}
program sideways(input,output,infile);

{COPYRIGHT @ 1983
      Jim Holtman
      35 Dogwood Trail
      Randolph, NJ 07869
      (201) 361-3396}

{This program will print the `infile' sideways on an EPSON MX-80 Printer.
 It makes use of the characters in the PC's ROM for the graphics mode of
 the CRT. The characters in the file are `looked up' and then the graphics
 mode of the printer is used for output.}

{ The DEBUG statements will output on the CRT the current line being printed.
  The line will appear vertically. }

type
    vstr = super array[0..*] of char;
    CHAR_PER_LINE = 0..2000;		{Maximum input line size}

const
    EOF = chr(26);			{TEXT EOF character}
    EOL = chr(13);
    TAB = chr(9);			{expand TABs}
    IGNORE = [chr(0)..chr(8),chr(10)..chr(#1f),chr(#80)..chr(#FF)];
    MAX_LINES = 48;			{Lines/Page}
    SPACES_PER_LINE = 2;		{2/72th inch space between lines}
    SPACES_PER_LETTER = 8;		{DOT size of characters}

var
    lptr : array[1..MAX_LINES] of ^vstr; {input lines}
    inbuf : array[CHAR_PER_LINE] of char;
    linesize : CHAR_PER_LINE;
    indx : 0..MAX_LINES;
    line : 0..MAX_LINES+1;
    infile : file of char;
    printer : text;
    col : CHAR_PER_LINE;
    pchar : integer;
    ichar : 0..7;
    max : CHAR_PER_LINE;
    rom : ads of array[0..32000] of char;

value
  {NOTE!!!!
     The following declarations define the segment and offset values
     for the characters in the PC version of the ROM. For the XT, check
     the TECH MANUAL for the correct values.}

    rom.s := #F000; {address of the CRT character generation}
    rom.r := #FA6E; {matrix in the ROM -- for non-XT versions of PC}

begin
    assign(printer,'lpt1:');            {open the printer}
    rewrite(printer);
    reset(infile);
    repeat
	max := 0;
	linesize := 0;
	line := 1;
	while (line <= MAX_LINES) do begin
	    if infile^ = EOL then begin {check for End-of-Line}
		new(lptr[line],linesize+1);  {allocate string storage}
		movel(adr inbuf[0],adr lptr[line]^[0],wrd(linesize+1)); {save}
		if linesize > max then max := linesize;
		linesize := 0;
		line := line+1;
		get(infile);
		writeln(output,'<<');   {--DEBUG--}
		cycle;
	    end;
	    if infile^ = EOF then break;
	    if not(infile^ in IGNORE) then begin
		if infile^ = TAB then
		    repeat		{Expand TABs}
			linesize := linesize+1;
			inbuf[linesize] := ' ';
		    until (linesize mod 8) = 0
		else begin
		    linesize := linesize+1;
		    inbuf[linesize] := infile^;
		end;
		write(output,infile^);	{--DEBUG--}
	    end;
	    get(infile);
	end;
	writeln(output,'line=',line,' max=',max);  {--DEBUG--}
	if infile^ <> EOF then line := MAX_LINES
	else line := line-1;
	for col := 1 to max do begin	{Output collected lines}
	    write(printer,chr(27)*'A'*chr(SPACES_PER_LETTER)*chr(27)*'K',
		     chr((line*(8+SPACES_PER_LINE)) mod 256),
		     chr((line*(8+SPACES_PER_LINE)) div 256));
	    for indx := line downto 1 do begin	{Scan next column}
		{if column pointer is larger than string, output BLANK}
		if col > upper(lptr[indx]^) then pchar := ord(' ')
		else pchar := ord(lptr[indx]^[col]);
		write(output,chr(pchar));  {--DEBUG--}
		pchar := pchar*8;
		for ichar := 7 downto 0 do {Pickup character, a line at a time}
		    write(printer,rom^[pchar+ichar]); {from ROM}
		for ichar := 1 to SPACES_PER_LINE do write(printer,chr(0));
	    end;
	    writeln(printer);
	    writeln(output);		{--DEBUG--}
	end;
	for indx := 1 to line do dispose(lptr[indx]);  {Free up space on HEAP}
	page(printer);
    until infile^ = EOF;
end.
