lui@CS.UCLA.EDU (01/29/88)
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!luirikitake@wadalab.t.u-tokyo.JUNET (rikitake) (02/01/88)
In article <10891@shemp.UCLA.EDU>, lui@CS.UCLA.EDU writes: > be changed?). I used to be a systems programmer for UNIX, but I'm not all > that familiar with VAX/VMS C. The main difference you see when you try to implement file transfer programs from UNIX is the system calls. Usually, you use SYS$QIOW system call to get access to the serial driver. -- Kenji -- Kenji Rikitake / Studying instrumentation physics in Univ. of. Tokyo. Please DO NOT REPLY to my junet address from abroad: Please reply to KENJI@DCTWCS.DAS.NET or ...!Sun!DCTWCS.DAS.NET!Kenji. Also TWICS BeeLINE operation staff. Office +81 3 351 5977
dp@JASPER.Palladian.COM (Jeffrey Del Papa) (02/02/88)
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>
-------