[comp.sys.mac.programmer] Programming the SCC

woody@tybalt.caltech.edu (William Edward Woody) (06/06/89)

	I was wondering if anyone out there has programmed the serial
ports on the Macintosh to communicate at rates faster than 57,600 baud,
and would be willing to share with me examples of that code.  I wish to
try my hand at programming the serial ports at 115,200 baud (half that
of the AppleTalk rates), and I don't quite have the hang of how to
talk to the Zilog SCC yet.  If anyone out there can help be, I'd be more
than greatful.

	Thanks.

	Oh, by the way, please respond DIRECTLY to me as I don't regularly
read the net (and I'm too quick with the 'Cancel all articles' command...).


----
	Help keep the freedom of information about computers alive!  Shoot
a lawyer today.
----

---	William Edward Woody		[woody@tybalt.caltech.edu]

+-----------------------------------------------------------------------+
|=[]====================  Standard Information  ========================|
|-----------------------------------------------------------------------|
|USNAIL (work)             | DISCLAMER:                                 |
|        Mail Stop 510-202 |     The intelligent and well thought out   |
|Jet Propulsion Laboratory | comment outlined above was generated by a  |
|       Pasadena, CA 91109 | million well-trained monkeys pounding on   |
|--------------------------| my computer with overripe bananas.  The    |
|       (home)             | rest of the garbage above is my own fault. |
|       330 S. Mentor #331 |                                            |
|  Pasadena, CA 91106-3331 |          MACII>>][n&&/|\&&IBM&&...         |
+-----------------------------------------------------------------------+

nf0i+@andrew.cmu.edu (Norman William Franke, III) (06/08/89)

I would also like information on using the serial ports at speeds greater
than 57K, or more to the point, how to read data from a MacRecorder.

Norman Franke
nf0i+@andrew.cmu.edu

grue@melmac.hss.bu.oz (Frobozz) (06/13/89)

In article <YYXJcay00UoL89Vkp3@andrew.cmu.edu> nf0i+@andrew.cmu.edu (Norman William Franke, III) writes:
>I would also like information on using the serial ports at speeds greater
>than 57K, or more to the point, how to read data from a MacRecorder.
>
>Norman Franke
>nf0i+@andrew.cmu.edu


Count me in too. (esp the bit about a MacRecorder)

				Paul Dale
seeya
SNIF
Paul Dale.

Language Centre              internet     :grue@lance.hss.bu.oz{.au}
Humanities & Social Sciences JANET        :grue%lance.hss.bu.oz@uk.ac.ukc
Bond University              ARPA, bitnet :grue%lance.hss.bu.oz.au@uunet.uu.net
Australia                    UUCP         :..!uunet!munnari!lance.hss.bu.oz!grue
seeya
SNIF

mnkonar@manyjars.SRC.Honeywell.COM (Murat N. Konar) (06/15/89)

In article <347@eldritch.hss.bu.oz> grue@melmac.hss.bu.oz (Frobozz) writes:
>In article <YYXJcay00UoL89Vkp3@andrew.cmu.edu> nf0i+@andrew.cmu.edu (Norman William Franke, III) writes:
>>I would also like information on using the serial ports at speeds greater
>>than 57K, or more to the point, how to read data from a MacRecorder.
>
>Count me in too. (esp the bit about a MacRecorder)

Me three. (ha, ha.)




   
  
  
____________________________________________________________________
Have a day. :^|
Murat N. Konar        Honeywell Systems & Research Center, Camden, MN
mnkonar@SRC.honeywell.com (internet) {umn-cs,ems,bthpyd}!srcsip!mnkonar(UUCP)

mcli@joker (Maurice Ling) (06/16/89)

Hell you all,

I'm a relatively novice Mac Programmer and I would like to send and receive
simple ascii codes through the SCC port A using THINK's Lightspeed C.
I've tried many things already and the program below gives me "Pascal
argument wrong size" error.  Anyways, All I need to do is send commands
like "EX" or "BY1000" to a scanner.  I have the "inside Macintosh" Manuals,
but the examples are all in Pascal code.  Send mail if this topic has been
discussed to death.  Thanks a bunch.

----------------------------------------------------------------------------
#include <stdio.h>
#include <serialDvr.h>
#include <DeviceMgr.h>
#include <MacTypes.h>
#include <strings.h>

main()
{
	sendinfo();
}

sendinfo()
{
	int setup,stuff, err;
	long int count = 1L;
	char message;
	char *ptr;
	SerShk flags;
	
	flags.fXOn = 1;
	flags.fCTS = 1;
	
	message = 't';
	ptr = &message;
	err = RAMSDOpen(sPortA);
	printf("%d\n",err);
	if (!err)
	{
		stuff = SerHShake (-7,flags);
		setup = baud300+data8+stop10+noParity;
		printf("%d\n",SerReset(-7,setup));
		stuff = FSWrite ( -7, count, ptr);
		printf("%d\n",stuff);
		printf("%ld\n",count);
	}
	RAMSDClose(sPortA);
	printf("%d\n",err);
}
------------------------------------------------------------------------------

************************************************************************
*                                                                      *
* Optics...  The wave of the future             **      **      **     *
*                                              *  *    *  *    *  *    *
* BITNET  :  MCLI_SS@UORDBV, MCLISS@UORVM     *       *       *        *
* UUCP    :  ...rochester!uhura!mcli         **      **      **        *
* Internet:  mcli@uhura.cc.rochester.edu    ***     ***     ***        *
*                                         *****   *****   *****        *       
************************************************************************

************************************************************************
*                                                                      *
* Optics...  The wave of the future             **      **      **     *

tim@hoptoad.uucp (Tim Maroney) (06/17/89)

In article <2286@ur-cc.UUCP> mcli@joker (Maurice Ling) writes:
>I'm a relatively novice Mac Programmer and I would like to send and receive
>simple ascii codes through the SCC port A using THINK's Lightspeed C.
>I've tried many things already and the program below gives me "Pascal
>argument wrong size" error.

Sigh -- would it have been too much trouble to mention what line the
error was on?

>	SerShk flags;
>		stuff = SerHShake (-7,flags);

I take it this was the line?  Structures over four bytes are passed to
the OS by pointer in LightSpeed C.  "stuff = SerHShake(-7, &flags);"
should work.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com
Postal: 424 Tehama, SF CA 94103; Phone: (415) 495-2934

These are not my opinions, those of my ex-employers, my old schools, my
relatives, my friends, or really any rational person whatsoever.

svc@well.UUCP (Leonard Rosenthol) (06/19/89)

In article <347@eldritch.hss.bu.oz>, grue@melmac.hss.bu.oz (Frobozz) writes:
> In article <YYXJcay00UoL89Vkp3@andrew.cmu.edu> nf0i+@andrew.cmu.edu (Norman William Franke, III) writes:
> >I would also like information on using the serial ports at speeds greater
> >than 57K, or more to the point, how to read data from a MacRecorder.
> >
> >Norman Franke
> >nf0i+@andrew.cmu.edu
> 
> 
> Count me in too. (esp the bit about a MacRecorder)
> 
> 				Paul Dale
>
	What follows is some source for reading the data direct from a Mac-
Recorder that was posted to this group previously.  I did not write it, so
I take no credit and especially NO BLAME!

/* Written  6:18 pm  Nov 26, 1988 by palmer@tybalt.caltech.edu in
uxe.cso.uiuc.edu:comp.sys.mac.programmer */
Due to the large number of requests that have been posted recently, I
am posting this code which reads the MacRecorder (sampling at 22 kHz).

MacRecorder comes with no programming documentation, so this is as good
as it gets.  If anyone has anything better, I'd be very interested.

I don't know where the original code comes from, but I made modifications
which allows it to work as an oscilloscope (on an SE or earlier machine.)
The style of the original code was lousy, and I opted to maintain stylistic
unity with my additions.

The core of the program is the routines which set up the port for reading
an externally clocked data stream.  To understand these, you must read the
Zilog SCC (Serial communications controller) data sheets.  At the MacRecorder's
input rate, interrupt driven routines are infeasible, so it uses continuous
polling.  This may cause data loss if other interrupts occur.

MacRecorder also transmits its data MSB first (if you understand how an SAR
ADC works, you will understand why.)  This is the opposite of most serial
ports, and so a translation table (included) which reverse the bit order
is needed.

Here is the code:
--------------------------------------------------------------

#include	<stdio.h>
#include	<QuickDraw.h>
#define 	x1Clock		12	/* Clock mode for Scc chip */
#define 	x16Clock	76


#define LENGTH 750		/* how much to read */
#define WIDTH 512		/* how large the screen is */
int Length = LENGTH,RealLength,x;
unsigned char buffer[LENGTH];
unsigned char table[256];
int screentable[256];
#define TOPMAR 20

void Die();

unsigned char *FindMin();

extern long *zero:0;
main() 
{
	register unsigned char *pch;
	Rect r;
	long SccIn();
	
	int i;
		
	InitGraf(&thePort);
	InitFonts ();
	InitWindows ();
	InitMenus ();
	TEInit ();
	InitDialogs(&Die);
	InitCursor ();

	SccInit();
	TableInit();
	r = thePort->portBits.bounds;
	PaintRect(&r);

	r.top = TOPMAR;
	r.bottom = TOPMAR+256;

	for (i = 0 ; i < 256 ; i++)
		screentable[i] = (table[i] + TOPMAR) * thePort->portBits.rowBytes;
	do {
		PenNormal();
		RealLength = MySccIn(buffer, LENGTH);
		pch = FindMin(buffer, LENGTH - WIDTH);
		DrawCurve(pch);
		if (Button()) {
			SysBeep(3);
			Die();
		}
		PaintRect(&r);
	} while (RealLength>=LENGTH);
	SysBeep(12);
}

DrawCurve(pch)		/* works only on MacI under non-multi finder */
register unsigned char *pch;
{
	register int byte;
	register int bit;
	register int *pscreentable = screentable;
	register unsigned char *pscreen  = 
				(unsigned char *)(thePort->portBits.baseAddr);
	
	for (byte = 0 ; byte < 64 ; byte++)
		for (bit = 0x100 ; bit >>= 1 ; )
			pscreen[pscreentable[*pch++] + byte] ^= (char)bit;
}

unsigned char *FindMin(pch, cch)
unsigned char *pch;
int cch;
{
	unsigned char *pchmin = pch;
	unsigned char min = *pch;
	
if (cch < 0) SysBeep(3);
	for ( ; --cch > 0 ; )
		if (*pch++ < min) {
			pchmin = pch - 1;
			min = *pchmin;
		}
	return pchmin;
} 

char **SccRd,**SccWr,*SccRBase,*SccWBase;	/* pointer to Scc chip */
int aCtl = 2;								/* offsets */
int aData = 6;
int bCtl = 0;
int dData = 4;
SccInit() /* initializes the Scc chip for the MacRecorder Plus */
	/* for the regular MacRecorder II, replace x1Clock with x16Clock below */
{	
	SccRd = (char **)0x1D8;		
	SccWr = (char **)0x1DC;		
	SccRBase = (char *)*SccRd;	
	SccWBase = (char *)*SccWr;
	SccPoke(9,2);			/* NV only */
						/* following line is for MacRecorder Plus */
	SccPoke(4,x1Clock);	/* 2 stop bits, Async, x1 clock mode  */
	SccPoke(1,1);			/* no Rx/Tx Int, Ext Int ON (mouse) */
	SccPoke(3,193);			/* initialize receiver, 8bits */
	SccPoke(5,122);			/* 8bits/char, send break(for other hardware!), Tx enable */
	SccPoke(11,48);			/* use TRxC as receiver clock */
	SccPoke(14,1);			/* BR enable, nothing else */
	SccPoke(15,8);			/* Interrupt on CD changes (mouse), turn off CTS interrupt */
	SccPoke(64,64);			/* Reset Rx CRC */
	SccPoke(9,10);			/* initialize master interrupt and NV */
}
SccPoke(n,v)		/* accesses the modem port */
char n,v;
{
	*(SccWBase + aCtl) = n;	/* set index to register n */
	*(SccWBase + aCtl) = v;	/* write v into register n */
}
SccPeek(n)
char n;
{	
	*(SccWBase + aCtl) = n;		/* set index to register n */
	return(*(SccRBase + aCtl));	/* retrun value in register n */
}
TableInit()
{
	MakeTable(&table[0]);
	ModifyTable(&table[0]);
}
MakeTable(table)
register char *table;
{
	asm	{
			adda.w	#256,table
			move.w	#255,D0
	lp0:	move.b	D0,D1
			move.w	#07,D3
	lp1:	lsr.b	#01,D1
			roxl.b	#01,D2
			dbf		D3,@lp1
			move.b	D2,-(table)
			dbf		D0,@lp0
		}
}
#ifdef FOO   /*( this is not needed if you use unsigned chars */
ModifyTable(table)
char *table;
{
	int i;
	for (i=0;i<256;i++)
	{
		if ( table[i]>=0 ) table[i] -= 128;
		else table[i] += 128 ;
	}
}
#endif
int MySccIn(dest, count)
register char *dest;
register int count;
{
	int	iCount = count;	/* actual number of bytes received */
	register	char	*pSccRBase = SccRBase;
	while (count-- > 0 && !Button()) {
		while (0 == (pSccRBase[2] & 0x1))
			if (Button())
				return (iCount - count + 1);
		*dest++ = pSccRBase[6];
	}
	return iCount;
}

long SccIn(dest,count)
register char *dest;
register long count;
{
	register	unsigned char	*Table;		/* a lookup table */
	register	long	aCount;	/* actual number of bytes received */
	Table = &table[0];
	aCount = 0L;
	asm	{
		move.l  #0x9FFFF8,A0			; /* SccRBase   */
#ifdef FOO
		move.l	#0xEFE1FE,A1			; /* mouse button */
		clr.l	D0
	lp:	btst	#03,(A1)				; /* mouse clicked? */
		beq		@lq
#else
	}
	lp:	if (Button())
			return(aCount);
	asm {
#endif
		btst	#00,2(A0)				; /* SccRBase + aCtl */
		beq		@lp
		move.b	6(A0), D0				; /* SccRBase + aData */
		move.b	00(Table,D0), (dest)+	; /* translate in lookup table */
		addq.l	#1,aCount				; /* one more byte received */
		subq.l	#1,count
		bne		@lp
	lq:	nop
		}
	return(aCount);
}

void Die()
{
	ExitToShell();
}
----------------------------------------------------------------

		David Palmer
		palmer@tybalt.caltech.edu
		...rutgers!cit-vax!tybalt.caltech.edu!palmer
	"I was sad that I had no shirt, until I met a man with no torso"
/* End of text from uxe.cso.uiuc.edu:comp.sys.mac.programmer */

-- 
+--------------------------------------------------+
Leonard Rosenthol        |  GEnie : MACgician
Lazerware, inc.          |  MacNet: MACgician
UUCP: svc@well.UUCP      |  ALink : D0025