
{$K0} {$K2} {$K12} {$K13} {$K14} {$K15}
module epson2;

{		second portion of EPSON 			      }
{	A print 'formatter' program to facilitate use of the epson    }
{	Written by Harry Eckerson on 9/18/81 and last revised 9/25/81 }
{	This program requires erl files utilmod and paslib and epson2 }
{		******** NO cpm LST device IO is used *******	      }
{	Location base of output ports = 80H ; control port = 87H     }
const
  blank = ' ';
  spec_c = '?'; {spec character in col 1 to detect spec action }
  base = 128;
  base1 = 129;
  base7 = 135;
  bell = 7;
  c_ret = 13;
  cr_lf = 10;

var
  p_fil : external text;
  f_name,
  str : external string;
  ok  : external char;
  no_c,
  code : external boolean;
  long_s : external string[255];
  count, i,
  ten_top, ten_bot, ten_page,
  top, bottom, lines_per , spaces,
  num, l_count, page_l, p_number	: external integer;
  l_feed, d_strike, number, comp, emph : external boolean;

external function keypressed : boolean;
external procedure @HLT;
external function @BDOS( func, parm : integer): integer;

procedure init_io;
var
    i : integer;
    ok_init : boolean;
begin
 write('Turn printer on, align paper and then press <cr>.');
 ok_init := yes_1(str,no_c);

(*	end;	put the end here for disks with functional LST: dev *)
 out[base7] := 0; { select daisy port }
 out[base1] := 192; { set bits 6&7 high of base1;6=strobe high;7=auto_L_off }
 
 out[base1] := 128; {leave 7 high take 6 low }
		{ this should initialize printer line #31 }
 for i := 1 to 10 do ;
	{	 delay cycle }  
 out[base1] := 192 { this goes back to 6 & 7 high }
end; {init }

procedure p_error (ok : char);
{ This procedure is not needed if LST: is used }
var
  lets : string;
  i : integer;
begin
  i := ord(ok);
  if i = 0
	then begin { delay to see if really off }
	  for i := 1 to maxint do ;
	  ok := inp[base];
	  i := ord(ok)
	end;
  if i = 0 then write('TURN ON PRINTER')
  else if i in [3,67] then write('PRINTER NOT ON LINE')
  else if i = 65 then write ('OUT OF PAPER')
  else begin
	write('Printer error # ',i,' = ');
	for i := 7 downto 0 do write(ord(tstbit(ok,i)))
     end;
  write(' <cr> or ^C ? ');
  readln(lets);
  if ord(ok) = 0 then init_io
end; { p_error }

procedure clr_line;
{ CLR_LINE should move back to the last printed line and delete it. }
begin
  write(chr(19),chr(19),chr(22))
end;

procedure p_out(let_val : integer);
var ok : char;
 i : integer;
begin
(*   i := @BDOS(5,let_val)	{ output char to printer }
	bdos call for disks with modified bios where LST: works 
	if @BDOS is used the rest of this procedure can be deleted. *)

 out[base7] := 0; { select daisy port }
 i := -32000;
 repeat 	{ input busy line; test it to see when it clears }
   ok := inp[base];
   if (ord(ok) = 0) or tstbit(ok,0) then p_error(ok);
 until tstbit(ok, 7);
 out[base] := wrd(let_val); { set data to be sent on the line }
 out[base7] := 32; 
 out[base7] := 48; {enable printer output & strobe daisy port low }
 for i := 1 to 1 do; { delay a moment } 
 out[base7] := 32; { strobe printer high and leave printer on }
end; { p_out }

procedure d_blanks( var d_line : string);
begin
  while pos( blank,d_line) = 1 do delete(d_line,1,1)
end; { d_blanks }

procedure set_page(page_l : integer);
begin
  p_out(27); { 'C' }
  p_out(67);
  p_out(page_l)
end;

function yes_1( var str : string;var zero_ch : boolean) : boolean;
var
 let : char;
 i : integer;
begin
  readln(str);
  zero_ch := length(str) = 0;
  d_blanks(str);
  yes_1 := (pos('Y',str) = 1) or (pos('y',str) = 1)
end; { yes_1 }


function convert( var line : string; tenths : boolean): integer;
var
  val : integer;
begin
  while (length(line) > 0 ) and not (line[1] in ['0'..'9','.'])
	do delete(line, 1, 1); { eliminate non numbers }
  val := 0;
  while (length(line) > 0) and (line[1] in ['0'..'9'])
   do begin
	val := val * 10 + ord(line[1]) - 48;
	delete(line,1,1)
   end; { conversion }
  if tenths
    then begin
      if pos('.',line) = 1 then delete(line,1,1);
      if (length(line) > 0) and ( line[1] in ['0'..'9'])
	then begin
		val := val * 10 + ord(line[1]) -48 ;
		delete(line, 1, 1)
	end
	else val := val * 10 { when trailing '.' }
     end;
  convert := val
end; { convert }

procedure set_epson;
begin
  { set up printer }
  p_out(27);  { 1st line spacing }
  case lines_per of
	60 : p_out(ord('2'));
	80 : p_out(ord('0'));
	103: p_out(ord('1'))
   end; { case }

  if comp then p_out(15)
	  else p_out(146);

  p_out(27);
  if emph then p_out(69) {'E'}
	  else p_out(70); { 'F' }

  p_out(27);
  if d_strike then p_out(71) {'G'}
	      else p_out(72) {'H'}
end; { set_epson }

modend.
