From:	CSBVAX::MRGATE!info-vax-RELAY@KL.SRI.COM@SMTP 11-FEB-1988 20:17
To:	ARISIA::EVERHART
Subj:	Macget/Macput for VMS


Received: from XX.LCS.MIT.EDU by KL.SRI.COM with TCP; Mon 1 Feb 88 10:42:37-PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 1 Feb 88 13:34-EST
Received: from JASPER.Palladian.COM (JASPER.Palladian.COM) by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 78510; 1 Feb 88 13:23
:59-EST
Received: from BANFF.Palladian.COM by JASPER.Palladian.COM via CHAOS with CHAOS-MAIL id 18132; Mon 1-Feb-88 13:12:18 EST
Date: Mon, 1 Feb 88 13:11 EST
From: Jeffrey Del Papa <dp@JASPER.Palladian.COM>
Subject: Macget/Macput for VMS
To: lui@locus.ucla.edu
cc: info-vax@kl.sri.com
In-Reply-To: <10891@shemp.UCLA.EDU>
Message-ID: <880201131155.4.DP@BANFF.Palladian.COM>

    Date: 28 Jan 88 19:58:38 GMT
    From: lui@locus.ucla.edu

    Does anyone have a version of Macget/Macput for VAX/VMS? We do have a C
    compilier on our systems, so I could port the UNIX versions (what needs to
    be changed?). I used to be a systems programmer for UNIX, but I'm not all
    that familiar with VAX/VMS C.


	    Stephen Lui
	    UCLA Department of Computer Science and

	    System Manager
	    Hughes Aircraft Company
	    Radar Systems Group

    Physical Address:
	    Centinela Ave. & Teale St.
	    Culver City, CA.
	    (213) 305-2085

    Mailing Address:
	    Hughes Aircraft Company
	    M/S RC R49 2563
	    P.O. Box 92426
	    Los Angeles, CA
	    90009-2426

	    ARPA:  lui@cs.ucla.edu
	    UUCP:  ...!{cepu,ihnp4,trwspp,ucbvax}!ucla-cs!lui

-------- begin maclib.c
#include stdio
#include ssdef
#include iodef
#include ttdef
#include "style.h"

long g_TTYStatus[2];
FILE *g_LogFile = NULL;
short g_channel;
int   g_FlushOutput = FALSE;
int   g_TerminalInitialized = FALSE;
int   g_PrintBytes = FALSE;
int   g_PrintCount = 0;

GetTTYChannel ()
{
    register int status;
    struct vaxstring
    {
        short length;
        char  type;
        char  class;
        char  *string;
    } ttyname;
    int timedout();
 
    ttyname.type   = 14;
    ttyname.class  = 1;
    ttyname.length = 2;
    ttyname.string = "TT";
 
    status = SYS$ASSIGN (&ttyname, &g_channel, NULL, NULL);
    if (status ISNT SS$_NORMAL)
        fatal ("Unable to assign terminal (error code %d).\n", status);
}
 
SetTTYModes ()
{
    register int status;
    long data[2];
    char iosb[4];

    status = SYS$QIOW (NULL, g_channel, IO$_SENSEMODE, &iosb,
                       NULL, NULL, &data, sizeof (data), 0, 0, 0, 0);
    if (status ISNT SS$_NORMAL)
	printf ("Error in terminal write.\n");
    g_TTYStatus[0] = data[0];
    g_TTYStatus[1] = data[1];
    data[1] |= (TT$M_PASSALL|TT$M_EIGHTBIT);
    data[1] &= ~(TT$M_TTSYNC|TT$M_WRAP);
    status = SYS$QIOW (NULL, g_channel, IO$_SETMODE, &iosb,
                       NULL, NULL, &data, sizeof (data), 0, 0, 0, 0);
    if (status ISNT SS$_NORMAL)
	printf ("Error in terminal write.\n");
    g_TerminalInitialized = TRUE;
}

ResetTTYModes ()
{
    register int status;
    char iosb[4];

    if (g_TerminalInitialized)
    {
	status = SYS$QIOW (NULL, g_channel, IO$_SETMODE, &iosb,
                           NULL, NULL, &g_TTYStatus, sizeof (g_TTYStatus), 0, 0, 0, 0);
	if (status ISNT SS$_NORMAL)
	    printf ("Error in terminal write.\n");
    }
}

int ReadTTYChar ()
{
    register int status;
    char inputchar;
    char iosb[4];
 
    status = SYS$QIOW (NULL, g_channel, IO$_TTYREADALL|IO$M_NOECHO, &iosb,
                       NULL, NULL, &inputchar, 1, 0, 0, 0, 0);
    if (status ISNT SS$_NORMAL)
        log ("Error in terminal read.\n");

    if (g_PrintBytes)
    {
	log ("(%02x)", (int)(inputchar & 0xFF));
	if (((++g_PrintCount) & 0xF) IS 0)
	    log ("\n");
    }
    return ((int)(inputchar & 0xFF));
}

WriteTTYChar (ch)
char ch;
{
    register int status;
    char inputchar;
    char iosb[4];

    if (g_PrintBytes)
    {
	log ("[%02x]", (int) (ch & 0xFF));
	if (((++g_PrintCount) & 0xF) IS 0)
	    log ("\n");
    }
    status = SYS$QIOW (NULL, g_channel, IO$_WRITEVBLK|IO$M_NOFORMAT, &iosb,
                       NULL, NULL, &ch, 1, 0, 0, 0, 0);
    if (status ISNT SS$_NORMAL)
        log ("Error in terminal write.\n");
}

OpenLogFile (name)
char *name;
{
    g_LogFile = fopen (name, "w");
    if (g_LogFile IS NULL)
	fatal ("Unable to open '%s' for writing.\n", name);
}

CloseLogFile ()
{
    if (g_LogFile ISNT NULL)
    {
	fprintf (g_LogFile, "Log ending.\n");
        fclose (g_LogFile);
    }
}

fatal (format, arg)
char *format;
char *arg;
{
    fprintf (stderr, format, arg);
    if (g_LogFile ISNT NULL)
    {
        fprintf (g_LogFile, format, arg);
	if (g_FlushOutput)
	    fflush (g_LogFile);
    }
    CleanUp (TRUE);
}

message (format, arg)
char *format;
char *arg;
{
    fprintf (stdout, format, arg);
    if (g_LogFile ISNT NULL)
    {
        fprintf (g_LogFile, format, arg);
	if (g_FlushOutput)
	    fflush (g_LogFile);
    }
}

log (format, arg)
char *format;
char *arg;
{
    if (g_LogFile ISNT NULL)
    {
        fprintf (g_LogFile, format, arg);
	if (g_FlushOutput)
	    fflush (g_LogFile);
    }
}
-------- end maclib.c
-------- begin style.h
#define IS      ==
#define ISNT    !=
#define AND     &&
#define OR      ||
-------- end.style.h
-------- begin xmodem.h
/* Mac time of 00:00:00 GMT, Jan 1, 1970 */
#define TIMEDIFF 0x7c25b080

#define RECORDBYTES 132
#define DATABYTES 128
#define NAMEBYTES 63

#define RETRIES 10
#define ACKTIMO 10

#define SOHTIMO 10
#define LINTIMO 20
#define CHRTIMO 2

#define MAXRECNO 0xff
#define BYTEMASK 0xff

#define TMO -1
#define DUP '\000'
#define SOH '\001'
#define EOT '\004'
#define ACK '\006'
#define NAK '\025'
#define CAN '\030'
#define EEF '\032'
#define ESC '\033'

#define H_NLENOFF 1
#define H_NAMEOFF 2
/* 65 <-> 80 is the FInfo structure */
#define H_TYPEOFF 65
#define H_AUTHOFF 69

#define H_LOCKOFF 81
#define H_DLENOFF 83
#define H_RLENOFF 87
#define H_CTIMOFF 91
#define H_MTIMOFF 95

/*******************************************************************************
** The following macros make timed code easier to write.  The macros should
** be used in the following way:
**
**	BEGIN_TIMED_SECTION (timeout_time)
**	    <the normal code to execute in a timed manner>
**	    <this CANNOT include a break, continue, or return>
**	ON_TIMEOUT
**	    <the code to execute when timeout occurs>
**          <this CAN include a break, continue, or return>
**	END_TIMED_SECTION
**
*******************************************************************************/

#include setjmp
jmp_buf g_TimeOutBuffer;

#define BEGIN_TIMED_SECTION(time)       if (!setjmp(g_TimeOutBuffer)) { alarm (time);
#define ON_TIMEOUT			alarm (0); } else {
#define END_TIMED_SECTION		}
---------- end xmodem.h
---------- begin macqms.c
/*
     This filter converts MacPaint files into Quic files for printing
     on an QMS-1200 or -800 laser printer.  It was written by Van
     Jacobson of Lawrence Berkeley Laboratory (van@lbl-csam.arpa,
     ...!ucbvax!lbl-csam!van) and is in the public domain.  It was
     loosely based on macimp.c by Winkler@harvard which was in turn
     based on MACimp for Tops-20 by Ed Pattermann, Stanford.

     Usage:
       macqms [-l] [-x<xpos>] [-y<ypos>] [-m<mag>] [-n<ipp>[,<ipr>]] [file ...]

     '-l' prints in "landscape" orientation (default is "portrait"
     orientation).  <xpos> and <ypos> are the position of the upper
     left corner of the bitmap.  They are given in inches and default
     to 0.41 and 0.70 (which will center a 576x720 image at mag 4).
     <mag> is a magnification for the bitmap and can be any integer
     >0.  The default is 4.  Magnifications larger than 4 may result in
     bizarre images.  `-n<ipp>' prints <ipp> images-per-page.  The files
     are printed `m' across by `n/m' down. "m" can be specified (e.g.,
     "-n4,2") or it can be defaulted.  The default is the largest number
     of images that will fit the current magnification & orientation.

     Send enhancements and bug reports to van@lbl-csam.

     History:      
	21 August 1984  VJ - created. 
*/

#include stdio
double atof();

#define	MAC_HEADER_LENGTH	512
#define	MAC_SCANLINES		720	/* number of scanlines in image */
#define	MAC_SCANLINE_BITS	576	/* number of bits in a scanline */
#define	MAC_SCANLINE_BYTES	(MAC_SCANLINE_BITS/8)

int	mag=4;			/* horiz & vert magnification in dots */
int	window=MAC_SCANLINE_BITS;	/* horiz width of image in dots */
int	initial_xpos = 410;	/* left margin position in inches*1000 */
int	initial_ypos = 700;	/* top margin position in inches*1000 */
char	orientation = 'P';	/* "portrait" orientation */
int	qms_pagewidth = 8500;	/* in inches*1000 */
int	ipp = 1;		/* 1 image per page */
int	ipr = 0;		/* default images per row */
int	images = 0;		/* number of images on current page */
int	xpos;
int	ypos;
int	xpos_incr;
int	ypos_incr;
char	usage[] =
  "usage: macqms [-l] [-m<mag>] [-x<xpos>] [-y<ypos>] [-n<ipp>] [file ...]";

main(argc,argv)
int argc;
char **argv;
{
	register int i;

	argv++; argc--;
	for ( i=0; i < argc; i++ )
		{
		if ( argv[i][0] != '-' )
			break;

		switch ( argv[i][1] )
		{
		case 'm':
			mag = atoi( &argv[i][2] );
			if ( mag <= 0 )
				mag = 1;
			break;
		case 'l':
			orientation = 'L';
			qms_pagewidth = 11000;
			break;
		case 'x':
			xpos = atof( &argv[i][2] )*1000.;
			break;
		case 'y':
			ypos = atof( &argv[i][2] )*1000.;
			break;
		case 'n':
			sscanf( &argv[i][2], "%d,%d", &ipp, &ipr );
			break;
		default:
			fprintf( stderr, usage );
			exit(1);
		}
	}
	qms_init();
	if ( i >= argc )
		/* no file arguments - send contents of stdin */
		send_one_bitmap();
	else
		for ( ; i < argc; i++ )
			{
			if ( freopen( argv[i], "r", stdin ) == NULL )
				{
				perror( argv[i] );
				exit(2);
				}
			send_one_bitmap();
			}

	/* if we have a partial page of images left over, eject it. */
	if ( images > 0 )
		qms_eject();

	qms_end();
	fflush(stdout) ; 
}


send_one_bitmap()
{
	/* set initial position & switch to plot mode */
	printf( "^IT%05d\n^IJ%05d\n^P%04d\n", xpos, ypos, window );
	throw_away_mac_header() ;
	send_bitmap_data() ;
	/* exit plot mode & update the postion for the next picture, if any */
	printf( "^G\n" );
	if ( ++images >= ipp )
		qms_eject();
	else
		{
		if ( (images % ipr) != 0 )
			xpos += xpos_incr;
		else
			{
			xpos = initial_xpos;
			ypos += ypos_incr;
			}
		}
}

qms_eject()
{
	printf("^,\n");
	xpos = initial_xpos;
	ypos = initial_ypos;
	images = 0;
}

int obytes;
int scanline;

send_bitmap_data()
{
	register int repeat_count, i;

	obytes=0;
	scanline=0;

	while ( (repeat_count = getchar()) != EOF )
		{
		repeat_count &= 0xff;
		if ( repeat_count >= 128 )
			{
			if ( repeat_count == 128 )
				continue;

			/* this is a <repeat count><data to repeat> pair.  This
			 * is almost identical to the qms compression scheme so
			 * we just reformat slightly & write it out.
			 */
			repeat_count = 257 - repeat_count;
			check_for_error( repeat_count );
			printf( "^C%03d", repeat_count );
			printhex( nextbyte() );
			}
		else 
			{
			/* this is a <count><count+1 bytes of data> sequence.
			 * We just ship out the data.
			 */
			check_for_error( ++repeat_count );
			while ( repeat_count-- > 0 )
				printhex( nextbyte() );
			}

		if ( obytes >= MAC_SCANLINE_BYTES )
			{
			putchar( '\n' );
			if ( ++scanline >= MAC_SCANLINES )
				break;
			obytes = 0;
			}
		}
}

check_for_error( bytes )
{
	/* check that the result of putting "bytes" data bytes is <= 1
	 * scan lines worth of data.
	 */
	if ( (obytes += bytes) > MAC_SCANLINE_BYTES )
		{
		/* too many bytes - assume that we dropped some & output
		 * filler for the previous scanline.
		 */
		printf( "\n^C%03d00\n", MAC_SCANLINE_BYTES + bytes - obytes );

		fprintf( stderr,
			"macqms: %d bytes on scanline %d (input byte %D)\n",
			obytes, scanline, ftell( stdin ) );

		obytes = bytes;
		scanline++;
		}
}

throw_away_mac_header()
{
     short bytenum ;

     for ( bytenum = 0 ; bytenum < MAC_HEADER_LENGTH ; bytenum ++ ) 
           nextbyte() ;
}

nextbyte()
{
	int byte;

	if ( (byte = getchar()) == EOF ) 
		{
		fprintf( stderr,
			"macqms: unexpected EOF reading macpaint file.\n" );
		exit(1);
		}
	return (byte);
}

static char hex_tab[] = {	'0', '1', '2', '3', '4', '5', '6', '7',
				'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

printhex( byte )
int byte;
{
	/* print a byte as 2 hex digits.  N.B.- the qms currently requires
	 * that the digits be in *upper case* so we can't use printf.
	 */
	putchar( hex_tab[(byte>>4) & 0xf]);
	putchar( hex_tab[byte & 0xf]);
}

qms_init()
{
	/* switch to quic mode & make sure the qms 
	 * is set up the way we expect.
	 */
	if (freopen("qms.bit","w",stdout) == NULL) perror("unable to open bit data file");
	printf( "\n^PY^-\n^ISYNTAX00000\n^F^-\n" );
	/* set the portrait/landscape orientation */
	printf( "^IO%c\n", orientation );
	/*  set the magnification */
	printf( "^IP%02d%02d\n", mag, mag );
	/* set the postioning stuff needed for multiple images per page */
	xpos = initial_xpos;
	ypos = initial_ypos;
	ypos_incr = (mag * MAC_SCANLINES * 10) / 3; /* inches per image  */
	xpos_incr = (mag * MAC_SCANLINE_BITS * 10) / 3;
	if ( ipr <= 0 )
		ipr = (qms_pagewidth - xpos) / xpos_incr;
}

qms_end()
{
	/* exit quic mode */
	printf( "^-^PN^-\n" );
}
------------ end macqms.c
------------ befin macqms.pas
Program MacQMS;
{* By Eric Lavitsky 12/03/84. Based on Macimp by Ed Patterman, Stanford  *}
{* and macqms by Van Jacobson, Lawrence Berkely Laboratory. This program *}
{* will take a Macintosh Bitmap file and convert it into a Quic file for *}
{* the QMS 1200 laser printer.						 *}

{* Edit History
   Edit	   Who      When     What
   ----	   ---	  --------  ---------------------------------------------
    01	   EL	  03-Dec-84  Initial version
    02	   EL	  18-Dec-84  Added standalone/document capability

*}
    include 'pas:pascmd.pas';
    include 'pas:jsys.pas';

const
	Mac_Header_Length = 512;    {* Macpaint header length in bytes *}
	Mac_Scanlines = 720;	    {* Vertical resolution of Mac screen *}
	Mac_Scanline_Bits = 576;   {* Horizontal resolution of Mac screen *}
	Mac_Scanline_Bytes = 72; 

type
	byte = 0..377B;

var
	mag:integer;	            {* horiz & vert magnification in dots *}
	window:integer;		    {* horiz width of image in dots *}
	initial_xpos:integer;	    {* left margin position in inches*1000 *}
	initial_ypos:integer;	    {* top margin position in inches*1000 *}
	orientation:char;           {* orientation of image on paper *}
	ortbl:table;		    {* COMND storage for orientation command *}
	qms_page_width:integer;	    {* in inches*1000 *}
	ipp:integer;		    {* images per page *}
	ipr:integer;		    {* images per row *}
	images:integer;		    {* number of images on current page *}
	copies:integer;		    {* number of copies to be printed *}
	xpos,ypos:integer;
	xpos_incr:integer;
	ypos_incr:integer;
	document_type:char;         {* document type *}
	doctbl:table;		    {* COMND storage for document command *}
	yntbl:table;		    {* more COMND storage *}

	{* various counting variables *}
	i,j,k,l,n:integer;
	bytes:integer;

	{* storage for Qformat *}
	high,num,max,digit : integer;
	str : packed array[1..10] of char;
	lett : char;

	{* file definitions *}
	infilename: packed array [1..80] of char;
	outfilename: packed array [1..80] of char;
	inlength:integer;
	Qms_file: file of char;
	Mac_file: file of byte;
	databyte: byte;
	opcode:integer;
	
function exp(i,j : integer) : integer;
var k,l : integer;
begin 
    l := i; 
    for k := 1 to j do 
	l := l * i;
    exp := l;
end;

procedure Qformat(num,high:integer);
begin
    for k := 1 to 10 do
	str[k] := ' ';
    k := 0;
    max := exp(10,high-2);
    while (max >= 1) do
	begin
	    digit := num div max;
	    lett := chr(ord('0') + ord(digit));
	    k := k + 1;
	    str[k] := lett;
	    num := num - (num div max ) * max;
	    max := max div 10;
	end;
end;
    
procedure init_params;
{* set defaults for Qms settings and build keyword tables for COMND *}
begin
    qms_page_width := 8500;
    orientation := 'P';
    mag := 4;
    ipp := 1;
    ipr := 0;
    initial_xpos := 410;
    initial_ypos := 700;
    copies := 1;
    images := 0;
    window := Mac_Scanline_Bits;
    ortbl := tbmak(2);
    tbadd(ortbl,0,'L ',0);
    tbadd(ortbl,1,'P ',0);
    doctbl := tbmak(2);
    tbadd(doctbl,0,'Document',0);
    tbadd(doctbl,1,'Standalone',0);
    yntbl := tbmak(2);
    tbadd(yntbl,0,'No',0);
    tbadd(yntbl,1,'Yes',0);
end; {* init_params *}

procedure qms_init;
{* write out the initial parameters to put the Qms into bitmap mode *}
 begin
    writeln(Qms_file,'');
    if (document_type = 'S') then
	writeln(Qms_file,'^PY^-');
    writeln(Qms_file,'^ISYNTAX0000');
    writeln(Qms_file,'^F^-');
    writeln(Qms_file,'^IO',orientation:1);
    writeln(Qms_file,'^IP0',mag:1,'0',mag:1);
    xpos := initial_xpos;
    ypos := initial_ypos;
    ypos_incr := trunc(((mag * Mac_Scanlines) * 10) / 3);
    xpos_incr := trunc(((mag * Mac_Scanline_Bits) * 10) / 3);
    if (ipr <= 0)
	then ipr := trunc((qms_page_width - xpos) / xpos_incr);
 end; {* qms_init *}

procedure qms_eject;
  begin
      if (document_type = 'S') then
	  begin
	      Qformat(copies,4);	    {* must give it page copy *}
	      writeln(Qms_file,'^DC',str:4);   {* count before form feed *} 
	  end;
      writeln(Qms_file,'^,');
     xpos := initial_xpos;
     ypos := initial_ypos;
     images := 0;
  end; {* qms_eject *}

procedure qms_end;
{* write the final parameters to reset the Qms *}
  begin
      if (document_type = 'S') then
	  writeln(Qms_file,'^-^PN^-');
      writeln(Qms_file,'');
  end; {* qms_end *}

procedure throw_away_mac_header;
{* the Macpaint header is not needed, so read it and ignore it *}
begin
    for i := 1 to Mac_Header_Length do 
	read(Mac_file,databyte) ;
end;

procedure out_bitmap_data;
{* here the Mac image is actually processed *}
begin {* out_bitmap_data *}
   write(tty,'Processing file ',infilename:inlength);
   for i := 1 to Mac_Scanlines do
       begin
	   while bytes < Mac_Scanline_Bytes do
	       begin
		  read(Mac_file,opcode);
		  if opcode > 127 then	    {* <count byte> <data byte> *}
		      begin
			  opcode := 256-opcode+1;
			  Qformat(opcode,3);
			  write(Qms_file,'^C',str:3);
			  read(Mac_file,databyte);
			  write(Qms_file,databyte:2:h);
		      end {* if opcode *}
		  else	  {* <count byte> <count+1 data bytes> *}
		      begin
			  opcode := opcode + 1;
			  for l := 1 to opcode do
			      begin
				  read(Mac_file,databyte);
				  write(Qms_file,databyte:2:h);
			      end;
		     end;
		     bytes := bytes + opcode;
	       end; {* while *}

	   if (bytes > Mac_Scanline_Bytes) then
	       begin
		   writeln(tty,' [FAILED]');
		   writeln(tty,'Input file is not a Mac bitmap file');
		   close(Mac_file);
		   jsys(haltf);
	       end; {* if bytes > Mac_Scanline_Bytes *}

	   bytes := 0;
	   writeln(Qms_file,'');
       end; {* for i:= 1 to Mac_Scanlines *}
   writeln(tty,' [OK]');
end; {* out_bitmap_data *}

procedure out_one_bitmap;
{* write out positioning commands and bitmap to output file *}
  begin
      if (document_type = 'S') then
	  begin
	      Qformat(xpos,5);
	      writeln(Qms_file,'^IT',str:5);
	      Qformat(ypos,5);
	      writeln(Qms_file,'^IJ',str:5);
	  end;
      Qformat(window,4);
      write(Qms_file,'^P',str:4);
      throw_away_mac_header;
      out_bitmap_data;
      writeln(Qms_file,'^G');
      images := images + 1;
      if (images >= ipp)
	  then qms_eject
	  else if ((images mod ipr) <> 0) 
	      then xpos := xpos + xpos_incr
	      else begin
		       xpos := initial_xpos;
		       ypos := ypos + ypos_incr;
		   end;
  end;

begin {* Main Program *}
    init_params;
1:
    writeln(tty,'MacQMS - A Mac Bitmap File to QMS Conversion Program');
    cmini('Mac Filename to be Converted > ');
    cmhlp('Name of Mac file ');
    cmifi(Mac_file);
    inlength := cmatom(infilename);
    cmcfm;
    cmini('Output filename > ');
    cmhlp('Enter local filename ');
    gjgen(400000000000B); gjext('LG1200');
    cmfil(Qms_file);
    i := cmatom(outfilename);
    cmcfm;
    cmini('Image Type > ');
    cmhlp('Document or Standalone ');
    cmdef('Standalone ');
    k := cmkey(doctbl);
    cmcfm;
    case k of
	0: document_type := 'D';
	1: document_type := 'S';
    end;
    cmini('Enter magnification desired > ');
    cmhlp('Magnification level, from 1 to 4 ');
    cmdef('4 ');
    mag := cmnum; cmcfm;
    if (document_type = 'S') then 
	begin
	    cmini('Change default positioning parameters? ');
	    cmhlp('Yes or No ');
	    cmdef('No ');
	    k := cmkey(yntbl);
	    cmcfm;
	    if (k = 1) then
		begin
		    cmini('Number of copies > ');
		    cmdef('1 ');
		    copies := cmnum; cmcfm;
		    cmini('Orientation > ');
		    cmhlp('L for landscape, P for portrait ');
		    cmdef('P ');
		    j := cmkey(ortbl);
		    cmcfm;
		    case j of
			0: orientation := 'L';
			1: orientation := 'P';
		    end;
		    cmini('Images per page > ');
		    cmhlp('Decimal number between 1 and 9999 ');
		    cmdef('1 ');
		    ipp := cmnum; cmcfm;
		    cmini('Images per row > ');
		    cmhlp('Decimal number ');
		    cmdef('0 ');
		    ipr := cmnum; cmcfm;
		    cmini('X-position > ');
		    cmhlp('Left margin in inches * 1000 ');
		    cmdef('410');
		    initial_xpos := cmnum; cmcfm;
		    cmini('Y-position > ');
		    cmhlp('Top margin in inches * 1000 ');
		    cmdef('700');
		    initial_ypos := cmnum; cmcfm;
		end;
	    end;
    rewrite(Qms_file,outfilename);
    qms_init; {* write out header information *}
    for n := 1 to ipp do
	begin
	    reset(Mac_file,infilename,'/B:08');
	    out_one_bitmap;
	    close(Mac_file);
	end;
    if (images > 0)
	then qms_eject;
    qms_end;
    close(Qms_file);
    jsys(haltf);
    goto 1;
end. {* MactoQMS *}
-------------- end macqms.pas
------------- begin macqms.doc











                                    MACQMS

                           A Macintosh To QMS Bitmap
                              Conversion Facility


















                               By: Eric Lavitsky
                               26 December 1984
                 Center For Computer and Information Services
                              Rutgers University
                            Piscataway, New Jersey
Introduction                                                             Page 1


1. Introduction

1.1. Overview

The  Program  is  written  in  Rutgers  Pascal  and  was  inspired and based on
MACIMP.PAS from Ed Pattermann at Stanford  and  MACQMS.C  by  Van  Jacobsen  at
Lawrence  Berkely Laboratory. The latter version would not work at our site, so
I set out to write one in Pascal which  could  also  be  transported  to  other
sites/Pascals.

After a general understanding of the MacPaint and QUIC formats is accquired, it
would be a fairly trivial project to insert Macintosh pictures  into  your  own
documents  for printing on the QMS. The Macintosh image could also be converted
for output on various other devices. The appendices at the end of this document
may  give  you some insights. I would also recommend looking through the source
code to see  how  the  conversion  is  done.  If  these  don't  provide  enough
information,  I  have  found  the  QMS  programmers' manual to be an invaluable
resource in my efforts.

My thanks to Charles Mcgrew for his undying enthusiasm and contributions.

1.2. System Requirements

What you will need:

   - Macintosh computer with or without external disk drive
   - MacTerminal V1.1 or MacKermit
   - Modem or hardwired line to the DEC-20
   - The MODEM or Kermit program on the DEC-20
   - A Mac disk with MacPaint images on it (MacPaint is not needed)
Transferring files to the host computer                                  Page 2


2. Transferring files to the host computer

2.1. Modem and MacTerminal 1.1

2.1.1. Macintosh Settings

Boot up Macterminal V1.1 on a Macintosh that is  connected  by  a  modem  or  a
hardwired line to the DEC-20.

Make sure the following settings exist on MacTerminal:

            Terminal:

                    VT100
                    ANSI

            Compatibility:

                    Baud Rate: set to your line or modem speed
                    Parity: None
                    Bits Per Character: 8
                    Connection: Modem
                    Handshaking: Xon/Xoff
                    Connection Port: Set to where your modem/line is connected

            File-Transfer:

                    XMODEM

                Delays shouldn't be needed. If you think you are retransmitting
                a  lot  of  packets  because  of  noisy lines try fudging these
                yourself.

2.1.2. Transferring the file to the DEC-20

Log on to the DEC-20

On the 20 run the MODEM program:

            @MODEM.EXE

Modem will respond with:

            MODEM>

All 8 bits of every byte in a MacPaint image are significant and therefore must
be  sent to the 20. Normally, the 20 only receives 7 bit bytes. MODEM, however,
will let you transfer 8 bit bytes as well.

            MODEM>RB filename

RB stands for RECEIVE BINARY, which will make sure the 20 receives all  8  bits
Transferring files to the host computer                                  Page 3


of every MacPaint byte.

On  the Macintosh, select Send File from the FILE Menu. The Mac will prompt you
with the filenames on the current disk in the drive. If you want to send a file
from  another disk, select eject and insert the disk of your preference. Select
the file you desire and then choose send (which will appear in the menu next to
the  filename  you select). Of course, if you have two disk drives, you can put
the desired disk for the transfer in the second  drive  and  select  the  Drive
option  when  it asks you for the filename to transfer. You can then select the
file from the other drive. The Mac will then  prompt  you  for  disk  swaps  if
necessary and transfer the file.

When  the transfer is complete, it will return you to MacTerminal, connected to
the 20 and running MODEM. You May now exit MODEM or  repeat  the  procedure  to
transfer more files:

            MODEM>D

(D  is  for  disconnect - Do *NOT* type 'e' or 'exit', or you will get yourself
hung!)

2.2. Kermit

Kermit will also let you transfer full 8 bit bytes to the 20.

2.2.1. Macintosh Settings

Pull down "Mode", select "Controls".

                Set baud rate (for the current version, you have  to  set  some
                OTHER  speed  and  then set it to what you want, due to a funny
                bug that sets the  line  speed  to  1200  no  matter  what  the
                indicator shows.)

                    Bits Sent: 8
                    Stop Bits: 1
                    Parity: None
                    Xon/Xoff Flow: Yes

then click "exit".

2.2.2. Transferring Files To The DEC-20

Pull down "Mode" again and select "Connect".  Start up kermit on the DEC-20:

            @KERMIT.EXE

The 20 will respond with:

            TOPS-20 KERMIT version 4.2(253)

            KERMIT-20>
Transferring files to the host computer                                  Page 4


To send a MacPaint file:

            KERMIT-20>SET FILE BYTESIZE 8

            KERMIT-20>RECEIVE or RECEIVE filename

Return  to  MacKermit.   Now pull down "Mode" once again and select "Transmit".
The host will call the file whatever it is you call the local file (you have no
choice.)
Running MACQMS                                                           Page 5


3. Running MACQMS

The MacPaint image has now been transferred to the 20. You can now go ahead and
convert it to a format suitable  for  printing  on  the  QMS  Lasergrafix  1200
printer.  You  can convert it to be printed as a seperate document (standalone)
or to be inserted in a document (document).

3.1. Converting Images For Standalone Printing

Suppose we called the picture file 'MAC-PICTURE.PIC'.  To  convert  it  to  QMS
format, run MACQMS on the 20:

            @MACQMS.EXE

MACQMS will prompt you for several things:

            MacQMS - A Mac Bitmap File to QMS Conversion Program
            Mac Filename to be Converted > MAC-PICTURE.PIC.1 
            Output filename > MAC-PICTURE.LG1200.1 
            Image Type > STANDALONE
            Enter magnification desired > 4
            Change default positioning parameters? No
            Processing file MAC-PICTURE.PIC.1 [OK]


Normally  you  will  respond  with  'No' to the prompt 'Change default printing
parameters? ' This will produce a  full  page,  1  image  reproduction  of  the
original  mac  picture in portrait mode (vertically oriented on the page). What
happens if you respond with 'Yes' at this prompt? ...

            MacQMS - A Mac Bitmap File to QMS Conversion Program
            Mac Filename to be Converted > MAC-PICTURE.PIC.1 
            Output filename > MAC-PICTURE.LG1200.1 
            Image Type > STANDALONE 
            Change default positioning parameters? Yes
            Enter magnification desired > 4 
            Number of copies > 1 
            Orientation > P 
            Images per page > 1 
            Images per row > 0 
            X-position > 410 
            Y-position > 700 
            Processing file MAC-PICTURE.PIC.1 [OK]


You may enter a value for any of these parameters or enter a carriage return to
use  the  default  value.  The settings shown here are the default values which
will print a full page image as described above. You may type a  question  mark
at any of the prompts for more help.

'[OK]' indicates that the file has been fully processed by MacQms.  If an error
ocurs, you will get the following message instead of the '[OK]' message:
Running MACQMS                                                           Page 6


            [FAILED] File Is Not A Macintosh Bitmap File

If this happens, there are two possible reasons:

   1. The file is really not a Mac bitmap file

   2. The file was not correctly sent to or received by  the  20  -  check
      your communication settings and try uploading the file again.

3.2. The Parameters

3.2.1. Magnification

This parameter can be any integer from 1 to 4. A magnification of 4 in Portrait
mode will yield a full page image. You may experiment with  this  parameter  in
combination  with  the other format parameters to yield the results you desire.
The default is 4.

3.2.2. Copies

This will add a command at the end of the QUIC file telling the QMS  to  repeat
the same pass on a new page. The default is 1.

3.2.3. Orientation

This  will tell the QMS what orientation to print the page. 'P' is for portrait
mode, which is a vertical orientation. 'L' is for landscape mode,  which  is  a
horizontal orientation. The default is P.

3.2.4. Images Per Page

This parameter controls the number of images printed on each page.  If there is
no room to print the image on the page, it will force a page eject and print it
on  the  next  page.  You  should be carefull when you use this setting. If the
magnification is too large and you are printing multiple images  per  row,  you
may get funny results. The default is 1 image per page. More than one image per
page will result in multiple processing of the file (you will see  the  message
'Processing  File  ...'  etc.  once for each of the number of images per page.)
There should be a more efficient way to do this, i.e. - reposition  and  repeat
the  pass. If anyone comes up with the code to do this, feel free to send it to
me and I will add it in!

3.2.5. Images Per Row

This parameter controls the number of images to be printed across on the  page.
If  you  are  printing two images on a page and specify two images per row, the
images will be printed next to each other, rather than one below the other. See
the  section on images per page for some special considerations you should take
into account when using this option. The default is 0 (which is effectively the
same as 1).
Running MACQMS                                                           Page 7


3.2.6. X-Position

This will specify the position from the left side of the page at which to start
printing the image. The value is input in inches * 1000. That is to say, if you
wanted  to start printing .41 inches from the left margin, you would enter 410,
which is the default.

3.2.7. Y-Position

This will specify the position from the top of  the  page  at  which  to  start
printing the image. The value is input in inches * 1000. That is to say, if you
wanted to start printing .71 inches from the left margin, you would eneter 710,
which is the default.

3.3. Printing the picture

You  now  will  have  a file in your directory called MAC-PICTURE.LG1200.1 This
file is suitable for printing on the QMS laser printer:

            @PRINT MAC-PICTURE.LG1200.1 /UNIT:3 or /SITE:QMS

Be sure the toner level in the QMS isn't  low  before  printing  any  pictures.
Also, please refill the QMS with toner after printing several pictures.

3.4. Converting For Use In A Seperate Document

Suppose  you  wanted  to  put  the  picture  into  a text document.  Specifying
'document' to the prompt image type will produce an image  without  positioning
commnands  suitable  for  insertion  in a text document. It is assumed that the
correct positioning will be done from within the text document. For information
on how to use a picture from within SCRIBE, see the next section.

            MacQMS - A Mac Bitmap File to QMS Conversion Program
            Mac Filename to be Converted > MAC-PICTURE.PIC.1
            Output filename > MAC-PICTURE.LG1200.1 
            Image Type > DOCUMENT 
            Enter magnification desired > 2 
            Processing file MAC-PICTURE.PIC.1 [OK]

3.5. Using A Macintosh Picture In Scribe

If  you  want  to  use  the bitmap image from within a scribe document you must
first run MACQMS on the file and specify 'document' as the image type. In  your
SCRIBE source file, include the following where you want the image to appear:

            @picture(size=4.25in,nonscaleablelaser=foo.mss)

Where  'foo.mss'  is  the  name  of  the converted bitmap file.  The size tells
SCRIBE how much space to allow for the picture within the  text.  To  determine
what size you should use, use the following table:
Running MACQMS                                                           Page 8


            MACQMS Magnification                      SCRIBE Size

                    4                                     8.50 in
                    3                                     6.40 in
                    2                                     4.25 in
                    1                                     2.20 in

These  are  only  suggestions,  you  may  get  better results by using slightly
different values.

Mail any bug reports, comments to LAVITSKY@RUTGERS
MacPaint File Format                                                     Page 9


I. MacPaint File Format

The first 512 bytes of the file are the header. The first four  bytes  comprise
the  version  number, followed by 38 * 8 = 304 bytes of patterns. The remaining
204 bytes are reserved for future expansion.  If the version  number  is  zero,
the  patterns are ignored. Hence, programs that wish to create files to be read
into MacPaint can just write out 512 bytes of zero as the header.

Following the header are 720 compressed scanlines of data which  form  the  576
wide  by 720 tall bitmap. The bitmap is compressed as follows: Any run of three
or more equal bytes is compressed into a count byte and  a  single  data  byte.
Runs of unequal bytes are passed on literally, preceeded also by a count byte.

          <count byte> <data byte>

                    count = -1..-127 ==> replicate byte 2..128 times

          <count byte> <n data bytes>

                    count = 0..127 ==> copy 1..128 times uncompressed

                    count = -128 ignored for backward compatibility
--------------- end macqms.doc

<dp>


-------

