[net.sources.mac] ATPrint - A {RS232 - Mac - ATalk - LW} spooler program

ahi@duvan.UUCP (02/08/86)

: This is a shar archive.  Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
echo 'Extracting README'
sed 's/^X//' > README << '+ END-OF-FILE README'
XThis directory/shar-file contains ATPrint, a 
X{RS232 -> Mac -> AppleTalk -> LaserWriter} spool program. 
X
XA program running on an Mac that takes characters from the 
XRS232 (modem) port and prints them over AppleTalk to an LaserWriter
Xas raw PostScript files. In other words it lets you SHARE the LW 
Xbetween the timesharing computer and your Macs.
X
XSe the beginning of atprint.c for more info.
X
XFiles are:
XREADME		This file
Xatprint.c	The main program
Xatprint.h	Headers...
Xatprint.rc	Definitions for Rmaker.
XMakefile	Food for Make
Xrs.s		The ram serial driver glue routines...
X
XRemember to add the SuMacC-programs to the search path before typing "make"...
X
XTo run the program also needs the SERD resource Include it with ResEdit
Xor REdit. As a way of avoiding development frustration the program first looks
Xfor the file SERD on the current floppy and loads the SERD resource from that.
X
X
X
+ END-OF-FILE README
chmod 'u=rw,g=rw,o=r' 'README'
echo '	-rw-rw-r--  1 ahi           889 Feb  7 15:45 README        (as sent)'
echo -n '	'
/bin/ls -l README
echo 'Extracting atprint.c'
sed 's/^X//' > atprint.c << '+ END-OF-FILE atprint.c'
X /* 				
X  atprint === {RS232 -> Mac -> AppleTalk -> LaserWriter} spool program. V86.1b
X
X	January 86. May be copied but not sold. (Written in SuMacC)
X
X	A program running on an Mac that takes characters from the 
X	RS232 (modem) port and prints them over AppleTalk to an LaserWriter
X	as raw PostScript files. In other words it lets you SHARE the LW 
X	between the timesharing computer and your Macs.
X
X	It tries somewhat to behave as the LW itself in serial mode.  No
X	intelligence except Xon/Xoff. The file is considered ended by either
X	a CTRL-D (as on the LW) or if no chars arrive it waits 30 secs
X	then sends a XON and waits 15 more seconds then assumes end of job.
X
X	ATPrint was designed to be usable as a printer spooler running on a 
X	dedicated Mac, ie it starts up that way, listening in 
X	9600 baud and waiting to print everything. Thus you can have it as a
X	startup application on your boot disk. (For the moment we use a 
X	dedicated 128k-mac w/o keyboard&mouse. But we have tested using only 
X	a naked spare 128k Mac board, an external power supply and an external
X	disk drive as a standalone print-spool-device)
X
X	ATPrint can also be used more temporarily as it has a primitive(!)
X	terminal emulator to allow you to log in to the remote host thru the
X	RS232-connection and initiate a print command with a special dialog
X	box. 
X	
X  	It also allows you to dump a PS file on the mac-disk to the LW.
X	(a la the PSDUMP (or Downloading) program from Apple's LW disk)
X	
X	Remember that "Choose Printer" must have been done before...
X
X	Notice that the PostScript program that is sent to ATPrint must do 
X	somewhat more initializations than in the normal case. This is of 
X	course due to the fact that we are coexsiting with the Macs and the 
X	definitions in the LaserPrep file. For example you have to do
X	"initmatrix" in order not to get everything mirrored. 
X	This is of course no problem if you use a more complex application like
X	TeX with dvi2ps. The recently posted lpscript doesn't to this though.
X
X	ATPrint has been tested with the "laser" program by Matti Rendahl
X	at my dept (also posted on USENET). Laser converts ordinary text files
X	like lpscript. The laser command for use in the "Send Command" dialog
X	is "laser -l file" (REMEBER to shut off echo and turn off prompt)
X	from other terminals use "laser -lttyxx file" when
X	you don't have a dedicated Mac. 
X
X--------------------------
X
X	The code could be cleaner. I do not have very much time for
X	programming nowadays so I wanted to get it working as fast
X	as possible...	(it was only thanks to Xmas holiday that I could 
X	do anything at all). Also more should be in resources but I don't 
X	like the idea of putting numbers on everything. I want symbolic 
X	references that are defined ONCE! A preprocessor that produced a 
X	.h-file and a resource file could maybe do the trick!
X	
X	Parts of the code are from the first version of MacKermit 
X	by Stephen Engel.
X
X	One thing I had to to was to move a more recent version of 
X	RAMSD{open&close} (of course in Motorola syntax...) 
X	to SuMacC as the distributed version of these
X	routines was too old. As I was lazy, both routines have 3 dummy
X	args, instead of the correct 1.
X
X	Things could be added to the program, among them:
X	o	Compression of various sorts for hex strings and maybe 
X		everything. To speed up downloading.
X	o	Real text printing mode.
X	o	Better terminal emulation :-)
X	o	It could say "Starting print job" etc using MacinTalk (just to
X		make everyone crazy within hearing range) Or play a 
X		tune everytime a file is printed. 
X	o 	More interaction with LW, eg notice "Printer Out of Paper"
X		etc. (how do I do that?)
X	o	More communication with RS232, to inform dowloading program
X		of printing progress.
X	o 	I have one experienced the LW crashing when downloading 
X		TeX output converted by dvi2ps. Maybe the LW gets memory 
X		overflow or something else. I would like to know what
X		the problem is.		
X
X	MacXL: For some reason something seems to get out of phase (XON/XOFF?!)
X	after about two pages of PostScript when ATPrint is running
X	on a MacXL. The XL is of course slower, but XON/XOFF seems to
X	work fine in terminal emulation. Strange! Anyone knows why?
X
X---------------
X Anders Hillbo, NADA (= CS Dept), Royal Inst. of Technology, Stockholm, Sweden
X		EAN: ahi@cs.kth.sunet
X		ARPA: anders_hillbo_nada%qzcom.mailnet@mit-multics
X		USENET: seismo!enea!ttds!ahi
X
X*/
X#include "atprint.h"
X#define FileMenu 0
X#define   aboutItem 1
X#define   psprintItem 2
X#define   textprintItem 3
X#define   selecItem 4
X#define   quitItem 5
X#define EditMenu 1
X#define CommandMenu 2
X#define   connItem 1
X#define   cmdItem 2
X#define   b1200Item 3
X#define   b9600Item 4
X#define	  debugItem 5
X
X#define NIL 0
X#define iPrDevCtl 7
X#define iPrIOCtl 5
X#define lPrReset 0x00010000	/* DocOpen */
X#define PageOpen 0x00040000
X#define lPrPageEnd 0x00020000	/* PageClose */
X#define DocClose 0x00050000
X#define ShowBuf 0	/* Text stream (ps show call) */
X#define StdBuf 1	/* Raw dump of postscript */
X
X#define TOPMARGIN 10	    /* Terminal display constants */
X#define BOTTOMMARGIN 286
X#define LEFTMARGIN 12
X#define RIGHTMARGIN 480
X#define LINEHEIGHT 12
X#define CHARWIDTH 6
X
Xint
X
X	topmargin=TOPMARGIN,	/* Edges of adjustable window */
X	bottommargin=BOTTOMMARGIN,
X	textstyle=0,
X	overrun=FALSE,
X	conned=0,
X	debug,
X	numinbuffer;	    /* Number of read in characters waiting to be
X			       printed */
XRgnHandle dumptr;	    /* Dummy ptr to satisfy scrollbits */
XPoint p;
XRect scrollrect;
Xint config1200, config9600;
Xchar text[255];
X
X/* main --- Initialize windows, communications, and wait for menu selection */
Xmain()
X{
X
X    int     err,
X            code;
X    struct QDVar    QDVar;
X    int     ccount;
X
X    QD = &QDVar;
X
X    InitGraf (&thePort);
X    InitFonts ();
X    InitWindows ();
X    SetupMenus ();
X    TEInit();
X    InitDialogs ((ProcPtr) NULL);
X    SetCursor (&QD -> arrow);
X    theWindow = NewWindow (&wRecord, (Rect *) wirect, "ATPrint", VIS,
X	    documentProc, (WindowPtr) - 1, 1, 0);
X    SetPort (theWindow);
X    theWindow -> txFont = 4;	/* Monaco font with non-proportional spacing */
X    theWindow -> txSize = 9;
X    PenSize (1, 1);
X    FlushEvents (everyEvent, 0);
X    err = GetVol (volname, &volnum);
X    if (err)
X	printerr ("Bad volume name: ", err);
X
X    config1200 = 94 + 16384 + 8192 + 3072;
X    config9600 = 10 + 16384 + 8192 + 3072;
X /* baud, 1 stop bit, no par, 8 bits (9600=10, 1200=94) */
X
X    SetupIO ();
X    dumptr = NewRgn ();
X    SetRect (&scrollrect, 0, 0, 500, 390);
X    SetPort (theWindow);
X    MoveTo (0, LINEHEIGHT);
X    debug = 0;
X    text[0]=(char)0;
X    CheckItem (myMenus[CommandMenu], debugItem, debug);
X    DisableItem (myMenus[FileMenu], textprintItem);
X    DisableItem (myMenus[FileMenu], selecItem);
X/*    DisableItem (myMenus[CommandMenu], cmdItem); */
X
X/* Main loop:  look for events, ignore unless its a menu selection
X *              If it is call DoCommand to do the dispatching */
X
X    for (;;) {
X	SystemTask ();
X	SerGetBuf (innum, &ccount);
X	if (ccount > 0) {
X	    if (conned)
X		DoTermOutput (ccount);
X	    else
X		(void) DoPrinting (ccount);
X	}
X	GetNextEvent (everyEvent, &myEvent);
X	switch (myEvent.what) {
X	    case autoKey: 
X	    case keyDown: 
X		if (conned) {
X		    int     i;
X		    char    c;
X		    c = (char) myEvent.message & 0x7f;
X		    if (myEvent.modifiers & cmdKey)
X			c &= 0x1f;
X		    switch (c) {
X			case 0x08: 
X			    c = 0x7f;
X			    break;/* BS -> DEL */
X		    }
X		    i = 1;
X		    FSWrite (outnum, &i, &c);
X		}
X		break;
X	    case mouseDown: 
X		code = FindWindow (&myEvent.where, &whichWindow);
X		switch (code) {
X		    case inMenuBar: 
X			DoCommand (MenuSelect (&myEvent.where));
X			break;
X		}		/* switch */
X	}			/* switch */
X    }				/* for */
X}
X
X
X/* SetupIO --- Initialize the RS232 connection. */
XSetupIO()
X{
X  int err;
X			   /* Set up IO drivers */
X    innum=OpenDriver(".AIn");
X    outnum=OpenDriver(".AOut");
X/*    asm(".word 0xa9ff"); /* Go into MacsBug */
X    err=OpenResFile ("SERD");
X/*    if (err==-1) printerr("Couldn't open res file: ", err); */
X    err=_RAMSDOpen(1,1,1); /* Specially hacked RamSDopen for SuMacC */
X    if (err) fatal("Can't open ramdriver: ", err);
X    controlparam.serConfig=config9600;
X    CheckItem (myMenus[CommandMenu], b9600Item, TRUE);
X    err=Control(innum,8,&controlparam);
X    if (err) fatal("Can't open idriver: ",err);
X    err=Control(outnum,8,&controlparam);	
X    if (err) fatal ("Can't open odriver: ",err);
X
X  /* Replace driver buffer with larger one */
X    controlparam.serInBuff.serBPtr=mybuff;
X    controlparam.serInBuff.serBLen=(short)MYBUFSIZE;
X    err=Control(innum,9,&controlparam);
X    if (err) printerr("Trouble making io buffer:",err);
X  /* Specify handshake options */
X    controlparam.serShk.fXOn=(char)TRUE;
X    controlparam.serShk.fCTS=(char)FALSE;
X    controlparam.serShk.xOn=(char) 17;
X    controlparam.serShk.xOff=(char) 19;
X    controlparam.serShk.errs=(char)FALSE;
X    controlparam.serShk.evts=(char)FALSE;
X    controlparam.serShk.fInX=(char)TRUE;
X    err=Control(outnum,10,&controlparam);
X    if (err) printerr("Trouble with handshake: ",err);
X}
X
X
X/* SetupMenus --- Install command menus. */
X
XSetupMenus()
X{
X	int i;
X 	char fnamcnv[13];
X
X
X	InitMenus();
X	myMenus[0]=NewMenu(filemenu,"File");
X	AppendMenu(myMenus[0], "About ATPrint...");
X	AppendMenu(myMenus[0], "Print PS file");
X	AppendMenu(myMenus[0], "Print Text File");
X	AppendMenu(myMenus[0], "Print Selection");
X	AppendMenu(myMenus[0], "Quit");
X	myMenus[1]=NewMenu(modemenu,"Edit");
X	AppendMenu(myMenus[1],"Undo");
X	AppendMenu(myMenus[1],"(-");
X	AppendMenu(myMenus[1],"Cut");
X	AppendMenu(myMenus[1],"Copy");
X	AppendMenu(myMenus[1],"Paste");
X	AppendMenu(myMenus[1],"Clear");
X	myMenus[2]=NewMenu(optionmenu,"Command");
X	AppendMenu(myMenus[2],"Connected");
X	AppendMenu(myMenus[2],"Send Command");
X	AppendMenu(myMenus[2],"1200");
X	AppendMenu(myMenus[2],"9600");
X	AppendMenu(myMenus[2],"Debug");
X	for (i=0;i<numMenu;i++)
X		InsertMenu(myMenus[i],0);
X	DrawMenuBar();
X}
X
X
X/* DoCommand --- Menu dispatcher */
X
XDoCommand(mResult)
Xint mResult;
X{
X	int theMenu=mResult>>16, theItem=(mResult &0xffff);
X
X	if (mResult !=0) {
X	  switch(theMenu) {
X	    case filemenu: 
X	      switch (theItem) {
X		case aboutItem:
X		  Alert (3, NULL);
X		  break;
X		case psprintItem:
X		  printfile (TRUE);
X		  break;
X		case textprintItem:
X		  printfile (FALSE);
X		  break;
X		case selecItem:
X		  break;
X		case quitItem:
X		  _RAMSDClose(1,1,1); /* Specially hacked for SuMacC */
X		  ExitToShell();
X		  break;
X	      };
X	      break;
X	    case modemenu:
X	      /* Dispatch to the correct routines */
X	      switch(theItem) {
X  		default:
X		  break;
X 	      };
X	      break;
X	    case optionmenu:
X	      switch(theItem) {
X		case connItem:
X		  conned = !conned;
X		  CheckItem(myMenus[2],connItem,conned);
X		  break;
X		case cmdItem: {
X		  char cmd[255]; int goon=1; char *xx; int count; 
X		  int ticks;
X
X		  while (goon>0) {
X		    goon=gettext(cmd); if (goon==0) break;
X		    SendCmd (cmd);
X		    /* Wait 45 secs for chars to arrive */
X		    screenstring ("* Waiting for chars from RS232, click mouse to interrupt\r\n");
X		    SerGetBuf (innum, &count); ticks = TickCount();
X		    while (count==0) {
X		      SystemTask();
X		      if (checkuser()) break;
X		      SerGetBuf (innum, &count);
X		      if ((TickCount()-ticks) > 60*45) break;		      
X		    }
X		    if (debug) count=0;
X		    if (count>0) while(DoPrinting (count));
X			 /* while just empty ^D's */
X		  } 
X
X		  break;
X	        }
X		case b1200Item: {
X		  SerReset (innum, config1200); 
X		  SerReset (outnum, config1200); 
X		  CheckItem (myMenus[2], b1200Item, TRUE);
X		  CheckItem (myMenus[2], b9600Item, FALSE);
X		  break;
X		}
X		case b9600Item: {
X		  SerReset (innum, config9600); 
X		  SerReset (outnum, config9600); 
X		  CheckItem (myMenus[2], b1200Item, FALSE);
X		  CheckItem (myMenus[2], b9600Item, TRUE);
X		  break;
X		}
X		case debugItem: {
X		  debug = !debug;
X		  CheckItem (myMenus[CommandMenu], debugItem, debug);
X		  break;
X		}
X	      };
X	      break;
X	  };
X	};
X	HiliteMenu(0);
X}
X
X/* DoTermOutput --- Handle screen output of chars from host. */
XDoTermOutput(count)
Xint count;
X{
X  char c; int i;
X
X  SetPort (theWindow);
X  while (count>0) {
X    if (count==1) { i=1; FSRead (innum, &i, &c); screenchar (c); }
X    else {
X      for(;count>1;count--) { 
X	i=1; 
X        FSRead (innum, &i, &c);
X	screenchar (c); 
X      }
X    }
X    SerGetBuf(innum, &count);
X  }
X}
X
X#define PBUFSIZ 1024
X#define CtrlD 4
X#define CtrlQ 17
X#define CtrlJ 10
X#define PrintAsPS StdBuf /* The strange Apple name for it... */
Xchar pbuf[PBUFSIZ+1]; int dummy;
Xint pbufc;
X
X/* PrintCtoLW --- Send a char to LaserWriter. Buffers it in pbuf first */
XPrintCtoLW (c)
Xchar c;
X{
X/*  if (c==CtrlJ) return; /* LW doesn't like LF's from ATalk */
X  if ((c==CtrlD) && (pbufc>0)) {
X    PrCtlCall(iPrIOCtl, (long)pbuf, pbufc, PrintAsPS); 
X    if (debug) { pbuf[pbufc]=(char)0; screenstring (pbuf);}
X    pbufc=0; 
X  }
X  else {
X    pbuf[pbufc++]=c;
X    if (pbufc==PBUFSIZ) { 
X      PrCtlCall(iPrIOCtl, (long)pbuf, pbufc, PrintAsPS); 
X      if(debug) { pbuf[pbufc]=(char)0; screenstring (pbuf);}
X      pbufc=0; 
X    }
X  }
X}
X
X/* DoPrinting --- Print all chars from RS232 line on AppleTalk LW */
Xint DoPrinting(count)
Xint count;
X{
X  char c; int i; 
X  long tick1; long ptype;
X
X  pbufc=0;
X  /* Ignore excess Ctrl-D's */
X  i=1; FSRead (innum, &i, &c); c &=0x7f;
X  if (c==CtrlD) return(1);
X  else PrintCtoLW (c); 
X  SerGetBuf(innum, &count); 
X
X  PrClose();
X  PrDrvrOpen(); 
X  screenstring ("**Starting print job**\r\n");
X  PrCtlCall(iPrDevCtl, lPrReset, 0, 0);
X  if (debug) screenstring("---");
X  while (TRUE) {
X    if (checkuser()) break;
X    if (count==1) { i=1; FSRead (innum, &i, &c); c &=0x7f; PrintCtoLW (c); }
X    else if (count>0){
X      for(;count>1;count--) { 
X	i=1; FSRead (innum, &i, &c); c &=0x7f;
X	PrintCtoLW (c); if (c==CtrlD) break; 
X      }
X    }
X    if (c==CtrlD) break;
X    SerGetBuf(innum, &count); tick1=TickCount();
X    /* Wait for 30 Secs for more chars */
X    while (count==0) {
X      SystemTask();
X      SerGetBuf(innum, &count); 
X      if ( (TickCount()-tick1) > 60*30 ) break;
X    }
X    /* Before giving up, try Xoff and wait 15 secs, in case anything hung */
X    if (count==0) {
X      i=1; c=CtrlQ; FSWrite(outnum, &i, &c);  
X      Delay (60*15, &i); 
X      SerGetBuf(innum, &count); 
X    }
X    if (count==0) { PrintCtoLW(CtrlD); screenstring("**Timeout\r\n"); break; }
X  }
X  screenstring ("**Ending print job**\r\n");
X/*  PrCtlCall(iPrDevCtl, lPrPageEnd, 0, 0);  */
X  PrDrvrClose();
X}
X
X/* checkuser --- Test if user has interupted */
Xint checkuser()
X{
X  SystemTask();
X  GetNextEvent(everyEvent, &myEvent);
X  if (myEvent.what==mouseDown) return (1); else return(0);
X}
X
X/* printfile --- Ask for a file and dump as PostScript to LW */
Xprintfile(ps)
Xint ps;
X{
X  int refnum,ok=0; char name[100]; char buff[512]; long count,ptype;
X
X  if (ps) ptype=StdBuf; else ptype=ShowBuf;
X  refnum=open_file(name);
X  if (refnum!=NULL) {
X    PrClose();
X    PrDrvrOpen(); 
X    PrCtlCall(iPrDevCtl, lPrReset, 0, 0);
X    while (ok!=eoFErr){
X      count=512;
X      ok=FSRead(refnum, &count, (long)buff);
X      if (count>0) {
X        screenchar('*');
X        PrCtlCall(iPrIOCtl, (long)buff, count, ptype);
X      }
X    }
X    PrCtlCall(iPrDevCtl, lPrPageEnd, 0, 0); 
X    PrDrvrClose();
X    FSClose (refnum);
X  }
X}
X
X
X#define cmdBtn	OK
X#define cmdquitBtn Cancel
X#define quitBtn 3
X#define cmdText 6
X
Xint gettext(str)
Xchar str[];
X{
X  DialogPtr d; int itemHit; Handle item; int type, i; Rect r; 
X
X  d = GetNewDialog (1, 0L, (char *)-1);
X  GetDItem (d, cmdText, &type, &item, &r);
X  if (strlen (text)>0) { SetIText (item, text); SelIText (d, cmdText, 0, 400);}
X  ModalDialog (0L, &itemHit);
X  if (itemHit==quitBtn) { DisposDialog (d); return (0); }
X  for (i=0;i<255;i++) text[i]=(char)0;
X  GetIText (item, text); /* This one returns a c-string i SuMacc ? */
X  if (debug) {
X    for (i=1;i<text[0];i++) screenchar (text[i]); screenstring ("\r\n");}
X  if (debug) screenstring (text);
X  strcpy (str, text);
X  if (strlen (str)>0) strcat (str, "\r");
X  if (debug) screenstring (str);
X  DisposDialog (d);
X  if (itemHit==cmdBtn) return (1); else return (-1);
X}
X
XSendCmd (cmd)
Xchar *cmd;
X{
X  int count;
X  count=strlen(cmd);
X  if (count>0) FSWrite (outnum, &count, cmd);
X}
X
X/*
X*  Printerr ---
X*	Display error message and number in standard error box
X*/
X
Xprinterr(str,err)
Xchar *str;
Xint err;
X{
X	int i;
X	char error[10];
X
X	if (err) /* Err=0 signals message only */
X	{
X		/* Make sure string will be null terminated */
X		for(i=0;i<10;error[i++]='\0');
X
X		NumToString(err,error);  /* Convert err number */
X		ParamText(str,error,"",""); /* Insert strings into error box */
X	}
X	else
X		ParamText(str,"","","");
X	StopAlert(1,(ProcPtr) NULL);
X
X}
X
X
X/*
X*   Fatal ---
X*	Printerr, close file, and exit to shell.
X*/
X
Xfatal(str,err)
Xchar *str;
Xint err;
X{
X	printerr(str,err);
X	ExitToShell();
X}
X
X/*
X*   Printnum ---
X*	Print out number as an ascii string.
X*/
X
Xprintnum(num)
Xint num;
X{
X	int i;
X	char numstr[10];
X
X	/* Make sure string will be null terminated. */
X
X	for(i=0;i<10;numstr[i++]='\0');
X	NumToString(num,numstr);
X	DrawString(numstr);
X
X}
X
X
X/*
X*	open_file  --- used to open the file for reading
X*	   returns value of refNum if successful, NULL if not
X*	   returns file name in fNamePtr if successful, NULL if not
X*/
X
Xint open_file (fNamePtr)	/*returns refNum if file opened, NULL if not*/
Xchar fNamePtr[];
X{
X	SFReply reply;
X	Point where;
X	int i, err=0, length, refNum;
X
X	/*position of dialog box*/
X	SetPt (&where,30,30);
X
X	/*initializes fNamePtr to NULLs for safety*/
X	for (i=0; i<64; i++)
X		reply.fName[i] = NULL;
X
X	/*handles user interface*/
X	SFGetFile (&where, NULL, NULL, -1, NULL, NULL, &reply);
X
X	/*
X	*	convert Pascal string to C string --
X	*	remove leading number and add a trailing NULL
X	*/
X	length = reply.fName[0];
X	for (i=0; i< length; i++)
X		fNamePtr[i] = reply.fName[i + 1];
X	fNamePtr[i] = NULL;
X
X	for (i=0; i< length; i++)
X		reply.fName[i] = reply.fName[i + 1];
X	reply.fName[i] = NULL;
X
X	if (reply.good)		/*user did not press Cancel Button*/
X		{
X		err = FSOpen (reply.fName, (int) reply.vRefNum, &refNum);
X		if(err)
X			printerr("Bad SFgetopen",err);
X	}
X
X	else			/*user did press Cancel Button*/
X		{
X		refNum = NULL;
X		fNamePtr[0] = NULL;
X		}
X	
X	return (refNum);
X}
X
X/* screenchar --- Place a char on the screen (window) */
Xscreenchar(chr)
Xchar chr;
X{
X  chr &= 0x7f;
X  if (chr==0x0d)
X    carriage_return(); 
X  else if (chr==0x0a)
X    line_feed();
X  else if (chr==0x08)
X    back_space();
X  else if (chr==0x09)
X    tab();
X  else if (chr==0x20)
X    space();
X  else {
X    GetPen (&p);
X    if(p.h>RIGHTMARGIN)
X      {
X	overrun=FALSE;
X	carriage_return();
X	line_feed();
X	overrun=TRUE;
X      }
X    DrawChar(chr);
X  }
X}
X
X/* screenstring --- Print a string on the scren */
Xscreenstring (s)
Xchar *s;
X{
X  while(*s) screenchar (*s++);
X}
X
Xline_feed()
X{
X	if(!overrun)
X	{
X		GetPen(&p);
X		if(p.v>=bottommargin)
X		{
X			ScrollRect((Rect *)&scrollrect,0,-LINEHEIGHT,dumptr);
X			EraseRgn(dumptr);
X		}
X		else
X			MoveTo(p.h,p.v+LINEHEIGHT);
X	}
X	else
X		overrun=FALSE;
X}
X
Xcarriage_return()
X{
X	GetPen(&p);
X	MoveTo(LEFTMARGIN,p.v);
X}
X
Xback_space()
X{
X	GetPen( &p);
X	if (p.h-CHARWIDTH>0)
X		Move(-CHARWIDTH,0);
X	else
X		carriage_return();
X}
X
Xspace()
X{
X	/* Regular quickdraw space does not cover previous characters */
X	Point p; short currect[4];
X
X	GetPen(&p);
X	currect[0]=p.v-LINEHEIGHT+3;
X	currect[1]=p.h;
X	currect[2]=p.v+3;
X	currect[3]=p.h+CHARWIDTH;
X	EraseRect((Rect*) currect);
X	Move(CHARWIDTH,0);
X
X}
X
Xtab()
X{
X	int index; Point p;
X
X	GetPen(&p);
X
X	index=p.h/CHARWIDTH;
X	index=((index+8)/8);
X	index=index*8*CHARWIDTH;
X	MoveTo(index,p.v);
X}
+ END-OF-FILE atprint.c
chmod 'u=rw,g=rw,o=r' 'atprint.c'
echo '	-rw-rw-r--  1 ahi         19527 Feb  7 15:41 atprint.c        (as sent)'
echo -n '	'
/bin/ls -l atprint.c
echo 'Extracting atprint.h'
sed 's/^X//' > atprint.h << '+ END-OF-FILE atprint.h'
X/* atprint.h - Definitions for ATPrint spooler program	*/
X
X#include <stdio.h>     		/* Standard io definitions */
X#include "mac/quickdraw.h"	/* Macintosh C interface */
X#include "mac/osintf.h"
X#include "mac/toolintf.h"
X#include "mac/packintf.h"
X#include "mac/libmac.h"
X
X/* Symbol Definitions */
X
X#define TRUE        -1      /* Boolean constants */
X#define FALSE       0
X
X#define	numMenu	    3	    /* Number of menus in program */
X#define filemenu    256     /* Reference numbers for menus */
X#define modemenu    257
X#define optionmenu  255
X#define VIS         1       /* Sets window visisble */
X#define MYBUFSIZE   2048
X#define BUFSIZE	    1024
X/* #define noErr	    0       /* Macintosh error codes */
X#define eoFErr      (-39)
X#define TOPMARGIN 10	    /* Terminal display constants */
X#define BOTTOMMARGIN 286
X#define LEFTMARGIN 12
X#define RIGHTMARGIN 480
X#define CHARWIDTH 6
X
X
X/* Macro Definitions */
X
X/* Global Variables */
X
Xint	innum,		    /* Input driver refnum */
X	outnum,		    /* Output driver refnum */
X
X		            /* Mode of data transmission */
X        image=FALSE ,       /* 8-bit transmission */
X	volnum,
X    	debug=FALSE;
X
Xchar    volname[256],       /* Current volume name */
X        filnam[80],            /* Current file name */
X	mybuff[MYBUFSIZE];  /* Serial drivers new buffer */
X
XMenuHandle myMenus[numMenu];
XEventRecord myEvent;
XWindowPtr theWindow, whichWindow;
XWindowRecord wRecord;
X			     /* Rectangles */
Xshort wirect[]={40,5,335,505}, /* window in global */
X	inrect[]  = { 0, 0, 390, 500}; /* and local coords */
X
XCSParam  controlparam;      /* To change serial driver params OpParamType */
X
Xshort config;  		       /* Current Serial driver configuration */
X
+ END-OF-FILE atprint.h
chmod 'u=rw,g=r,o=r' 'atprint.h'
echo '	-rw-r--r--  1 ahi          1688 Jan  5 20:18 atprint.h        (as sent)'
echo -n '	'
/bin/ls -l atprint.h
echo 'Extracting atprint.rc'
sed 's/^X//' > atprint.rc << '+ END-OF-FILE atprint.rc'
X*
X* File atprint.rc
X*
X* This file contains the resources for rmaker for the atprint program
X
X* Specify output file of executable code
X
Xatprint.rsrc
X
X* 
XType DLOG
X  ,1
X 40 20 330 500
XVisible 1 NoGoAway 0
X  5
XSend command
X
XType ALRT
X,1
X90 50 180 400
X2
X5555
X
XType ALRT
X,3
X30 30 300 480
X4
XCCCC
X
X* Error box
XType DITL
X,2
X2
XBtnItem Enabled
X65 20 85 60
XOK
X
XStatText Disabled
X65 80 85 400
XError: ^0  ^1
X
X* About
XType DITL
X,4
X6
XBtnItem Enabled
X230 230 260 290
XOK
X
XBtnItem Disabled
X400 400 400 400
XCancel
X
XStatText Disabled
X10 10 40 450
XATPrint {RS232 -> Mac -> AppleTalk -> LaserWriter} spool program. V86.1b   
X
XStatText Disabled
X50 10 90 450
XPrints all characters from RS232 on a LaserWriter over AppleTalk (no interpretation, i e only PostScript files work).
X
XStatText Disabled
X90 10 120 450
XMay be copied but not sold.
X
XStatText Disabled
X120 10 150 450
Xseismo!enea!ttds!ahi --- Anders Hillbo, Royal Inst of Technology, Stockholm
X
X* Send Command
XType DITL
X ,5
X6
X* 1
XBtnItem Enabled
X250 30 270 140
XSend command
X
X* 2
XBtnItem Enabled
X250 150 270 380
XSend command & Quit
X
X* 3
XBtnItem Enabled
X250 390 270 440
XQuit
X
X* 4
XStatText Disabled
X30 30 120 470
XThis lets you send a print command to the remote host. We wait 45 secs for anything to happen (chars to arrive from RS232) before we give up. 
X
X* 5
XStatText Disabled
X100 30 200 470
XREMEMBER that the remote host must have the echo turned off and that it should not prompt again after the command... (on unix in CSH do "stty -echo" and "set prompt=")
X
X* 6
XEditText Disabled
X220 30 240 460
X
X
X* Compiled program code
X
XType CODE
X  b.out,0
X
X
+ END-OF-FILE atprint.rc
chmod 'u=rw,g=r,o=r' 'atprint.rc'
echo '	-rw-r--r--  1 ahi          1576 Jan 27 18:47 atprint.rc        (as sent)'
echo -n '	'
/bin/ls -l atprint.rc
echo 'Extracting Makefile'
sed 's/^X//' > Makefile << '+ END-OF-FILE Makefile'
X.SUFFIXES:  .b .c .s
X
XOBJECTS = atprint.b rs.b
X
X.c.b:
X	cc68  -c $<
X.s.b:
X	cc68  -c $<
X
Xatprint.rsrc:  atprint.rc b.out 
X	rmaker atprint.rc
X
Xb.out: atprint.b rs.b
X	cc68 -z -m ${OBJECTS}
X
Xshar:	
X	shar README atprint.c atprint.h atprint.rc Makefile rs.s naked-mac-spec > atprint.shar
+ END-OF-FILE Makefile
chmod 'u=rw,g=r,o=r' 'Makefile'
echo '	-rw-r--r--  1 ahi           281 Jan 27 19:48 Makefile        (as sent)'
echo -n '	'
/bin/ls -l Makefile
echo 'Extracting rs.s'
sed 's/^X//' > rs.s << '+ END-OF-FILE rs.s'
X| RAMSDOpen & RAMSDClose routines for opening the SERD RAM serial driver
X| resource. For use with SuMacC. 1986-01-05 20:01:26
X| I translated this from "Motorola" syntax into Unix syntax, but I 
X| was in a hurry and didn't want to learn the parameter mechanism. Thus both
X| routines have 3 dummy args and always use PortA (modem).
X
X	.text
X	.globl _RAMSDOpen, _RAMSDClose
XIOQElSize=50
XIOFileName=18
XIORefNum=24
XIODrvNum=22
XIOPermssn=27
XRSDHndl=0x28a
X|||	OSErr RamSDOpen(whichPort) | Originally but here _RAMSDopen(0,0,0)
X_RAMSDOpen:
X	link	a6,#-IOQElSize
X	moveml	#0x3030,sp@-	|	movem.l	d2-d3/a2-a3,-(sp)|save regs !!!
X	movl	#0x14,d0		|offset to AIn DCE handle
X|
X|
X|
X| Always do a-port...
X	movl	0x11c,a0		|get Unit table base address
X	movl	a0@(0,d0:w),d0		|get the DCE
X	beq	AsyncOK			|no open
X	movl	d0,a0			|DCE handle
X	movl	a0@,d0			|get and test pointer
X	beq	AsyncOK			|driver purged
X	movl	d0,a0			|copy pointer
X	tstb	a0@(7)			|check DCtlQueue+1 for new version
X	bne	AsyncOK			|yes, go open it
X	movl	RSDHndl,d0		|get resource handle
X	bgt	RamSDIn			| there already
X	movl	#2,D1			|id for XL
X	movl	0x2ae,a0		|get address of Rom base
X	movw	a0@(8),d0		|get version word
X	cmpb	#0xff,d0		|XL?
X	beq	2$			|yes
X	lsrw	#8,d0			|check high byte
X	bne	AsyncOK			|new Mac, ok
X	movl	#1,d1			|id for old Mac
X2$:
X	subw	#4,sp
X	movl	serd,sp@-		|open SERD resourc
X	movw	d1,sp@-			|push id number
X	.word	0xa9a0			|GetResource
X	movl	sp@,d3			|check return
X	bne	4$			|got it
X	addw	#4,sp			|fix stack
X	movw	0xa60,d0		|pass on resource error
X	bne	3$			|skip if there was one
X	movl	#-192,d0		|else set to resource not found
X3$:
X	bra	RamSDExit		|and quit
X4$:
X	.word	0xa992			|DetachResource
X	movl	d3,a0			|get handle
X	bset	#7,a0@			|lock it in memory
X	movl	a0,RSDHndl		|and save for later incarnations
XRamSDIn:
X	movl	RSDHndl,a3		|get handle to driver
X	movl	a3@,a3			|dereference
X	movl	#-23,d0			|assume openErr
X	cmpl	#0x53455244,a3@(4)	|must be SERD resource
X	bne	RamSDExit
X	movb	#0,d1	|A-port	|whichPort
X	btst	d1,RSDHndl		|installed already?
X	bne	AsyncOK			|yes
X	bsr	ClsPorts		|close the ROM ports
X	bset	d1,RSDHndl		|mark as installed
X	movl	#1,d0			|call install routine
X	jsr	a3@			|by calling through entry
X
XAsyncOK:
X	movl	#1,d2			|set up d2 for looping
X	lea	a6@(-IOQElSize),a0	|get ptr to param block
X	lea	drvANames,a1		|start with port A
X|	tstb	a6@(8)			|check whichPort
X|	beq	5$			|skip if A
X|	lea	drvBNames,a1		|get port B names
X5$:
X	movl	a1,a0@(IOFileName)	|set ptr to name
X	clrw	a0@(IODrvNum)
X	clrb	a0@(IOPermssn)		|open for read/write
X	.word	0xa000			|Open
X
X
X
X
X
X
X
X
X
X	bne	RamSDExit		|exit on error
X	movl	#0,d1			|zero out high bits
X	movb	a1@+,d1 		|length of string
X	addw	d1,a1			|skip to next name
X	dbra	d2,5$			|loop
X	movl	#0,d0			|no error
XRamSDExit:
X	extl	d0			|sign extend
X	moveml  sp@+,#0x0c0c	|	movem.l	sp@+,d2-d3/a2-a3	|restore regs
X	unlk	a6
X	rts
X
X|
X|	RamSDClose(whichPort)
X|
X
X_RAMSDClose:
X	link	a6,#-IOQElSize		|space for pb
X	moveml 	#0x3030,sp@-		| movem.l d2-d3/a2-a3,-(sp) |save regs
X	movb	#0,d1			|A-port whichPort
X	bsr	ClsPorts		|close the ports
X	movl	RSDHndl,d0		|get handle
X	ble	RamSDExit		|exit if not there
X	andl	0x31a,d0		|MaskBC
X	movl	d0,a0			|move to a0
X	movl	a0@,a0			|dereference
X	cmpl	#0x53455244,a0@(4)	|must be SERD
X	bne	RamSDExit		|else quit
X	bclr	d1,RSDHndl		|mark as not installed
X	movl	#0,d0			|call driver to remove
X	jsr	a0@
X	tstb	RSDHndl			|is it used by anyone?
X	bne	RamSDExit		|yes, quit
X	movl	RSDHndl,d0		|no, get handle
X	movl	d0,a0			|copy to a0
X	.word	0xa023			|DisposeHandle
X	movl	#-1,d0			|set handle to -1
X	movl	d0,RSDHndl		|to make it invalid
X	bra	RamSDExit		|and quit
X
XClsPorts:
X	movl	#-6,d0			|serial A input refnum
X	tstb	d1			|whichPort
X	beq	6$			|skip if A
X	movl	#-8,d0			|serial B input refnum
X6$:
X	lea	a6@(-IOQElSize),a0	|ptr to pb record
X	movw	d0,a0@(IORefNum)	|set up refnum
X	.word	0xa001			|Close
X	subw	#1,a0@(IORefNum)	|refnum of output driver
X	.word	0xa001			|Close also
X	rts
X
XdrvANames:
X	.byte	4
X	.ascii	".AIn"
X	.byte	5
X	.ascii	".AOut"
X.even
XdrvBNames:
X	.byte 4
X	.ascii	".BIn"
X	.byte 5
X	.ascii	".BOut"
X
X.even
Xserd:
X	.ascii "SERD"
+ END-OF-FILE rs.s
chmod 'u=rw,g=rw,o=r' 'rs.s'
echo '	-rw-rw-r--  1 ahi          4060 Jan  5 20:02 rs.s        (as sent)'
echo -n '	'
/bin/ls -l rs.s
echo 'Extracting naked-mac-spec'
sed 's/^X//' > naked-mac-spec << '+ END-OF-FILE naked-mac-spec'
XThis gives some hints when connecting a naked-mac logic board to an
Xexternal power supply./Ragge Sundblad, NADA, KTH, Stockholm
X
XYou can find a connector on the logic-card wich connects the logic-card with
Xthe analog card. This is a spec how you can connect the power-supply you
Xwant. For example, you can use a multibus-power-supply if you've got
Xa multibus-machine (like sun) and want to get the power out of it.
XIf you want, you can connect a speaker to the card so you can hear it booting.
X
X
XNo pin!  Speaker (you can even take this signal in the speaker-connector
X     |     |      in the back of the card)
X     V     V
X  o  .  o  o  o  o  o  o  o  o  o <-Normally battery
X           |    +5  0 -12 0 +12 +5
X          _/|       |
X         |_ |       |
X           \|       |
X           |________|
X
+ END-OF-FILE naked-mac-spec
chmod 'u=rw,g=rw,o=r' 'naked-mac-spec'
echo '	-rw-rw-r--  1 ahi           802 Jan 27 21:50 naked-mac-spec        (as sent)'
echo -n '	'
/bin/ls -l naked-mac-spec
exit 0