[comp.sys.mac] *$*$*$*$*$ The Mac Serial Ports!!!!!!

sprouse@cory.Berkeley.EDU (Steven T. Sprouse) (09/26/87)

I have been trying, withouth success, to open the !@$##@$ Mac
Serial ports. I think I have the driver and port open, but characters
are not being acknowleged by my modem. (I wrote a dumb terminal
program')  If anyone could send me the source to a dumb terminal
program I would appreciate it.
			Thank you very much,
					Steven T. Sprouse

singer@endor.harvard.edu (Andrew Singer) (09/28/87)

Here is some code. This is mine, and THINK does not provide any support or 
guarantee the quality, but I'll help you with it if you have problems.

		--Rich

UNIT ModemIO;
{This unit will read and write ASCII strings using the modem port.}

INTERFACE
{exported variables}

	CONST
 {names of the ROM serial driver for the modem port}
		ModemIn = '.AIn';
		ModemOut = '.AOut';

{other handy constants}
		Cr = 13;	{ASCII code of CR}
		Lf = 10;			{ASCII code of LF}
		XOnChar = $11;
		XOffChar = $13;

		ModemInputRefNum = -6;
		ModemOutputRefNum = -7;

{data input lengths for various instruments}
		HP3478 = 13;
		HP5386 = 19;
		HP5316 = 21;
		HP5328 = 17;
		HP3455 = 15;
		Nic1170 = 65;

{functions to converse with the modem port}
	FUNCTION InitModemPort : OSErr;					{initialize the port}
	FUNCTION Configure (Settings : Integer) : OSErr;	{configure the port}
	FUNCTION XMitBuf (buf : Ptr;
									len : Integer) : OSErr; 				{send any buffer}
	FUNCTION XMitChar (c : Char) : OSErr; 			{send a character}
	FUNCTION XMitString (str : Str255) : OSErr;	{send a string}
	FUNCTION XMitCRLF : OSErr;						{sends a CRLF}

	FUNCTION XMitLine (str : Str255) : OSErr;		{send a string followed by CRLF}

	FUNCTION RecvBuf (buf : Ptr;
									len : LongInt) : OSErr;				{get a buffer}

	FUNCTION RecvChar (VAR c : Char) : OSErr;	{get a single character}

	FUNCTION RecvFixedString (VAR Str : Str255;
									len : Integer) : OSErr;				{get a string of known length}

	FUNCTION RecvString (VAR str : Str255) : OSErr;	{get a string of unknown length}

	PROCEDURE Wait (ticks : LongInt);				{delay for the number specified in 60ths of a sec}

	PROCEDURE GetLineFeed (refNum : Integer;		{Read all chars in the input buffer, up to and including}
									VAR s : Str255);					{the first linefeed.}

	FUNCTION XMitInt (i : Integer) : OSErr;			{Send an integer in binary form -- useful for control chars}
	FUNCTION XMitLong (l : LongInt) : OSErr;		{Send a LongInt in binary form}

IMPLEMENTATION

	PROCEDURE GetLineFeed;

		VAR
			charsIn, count, Base : LongInt;
			err : OSErr;
			index : Integer;
	BEGIN
		index := 1;
		s := ' ';
		err := SerGetBuf(RefNum, count);
		charsIn := 1;
		Base := Ord4(@s);

		WHILE (count > 0) AND (s[index] <> chr(10)) DO
			BEGIN
				err := SerGetBuf(RefNum, count);
				IF count > 0 THEN
					BEGIN
						err := FSRead(RefNum, charsIn, Pointer(Base + Index));
						IF err = noErr THEN
							index := index + 1;
					END;
			END;

		s[0] := chr(Index - 1);
	END;

	FUNCTION InitModemPort;
		VAR
			err : OSErr;
			HandShake : SerShk;
			boge : Integer;

	BEGIN
		err := OpenDriver(ModemIn, boge);
		err := OpenDriver(ModemOut, boge);

		WITH Handshake DO
			BEGIN
				fXOn := 0;
				fCTS := 0;
				errs := 0;
				evts := 0;
				fInX := 0;
			END;
		err := SerHShake(ModemInputRefNum, HandShake);
		err := SerHShake(ModemOutputRefNum, HandShake);

		InitModemPort := err;
	END;

	FUNCTION Configure;
		VAR
			err : OSErr;

	BEGIN
		err := SerReset(ModemInputRefNum, Settings);
		err := SerReset(ModemOutputRefNum, Settings);
		Configure := Err;
	END;

	FUNCTION XMitBuf;
		VAR
			count : LongInt;

	BEGIN
		count := len;
		XMitBuf := FSWrite(ModemOutputRefNum, count, Buf);
	END;

	FUNCTION XMitChar;
		VAR
			chars : PACKED ARRAY[0..1] OF Char;

	BEGIN
		chars[0] := c;
		XMitChar := XMitBuf(@chars, 1);
	END;

	FUNCTION XMitString;
		VAR
			count : LongInt;
	BEGIN
		count := length(str);
		XMitString := FSWrite(ModemOutputRefNum, count, Pointer(ord4(@Str) + 1));
	END;

	FUNCTION XMitCRLF;
		VAR
			chars : Integer;
			count : LongInt;
			err : OSErr;

	BEGIN
		chars := $0D0A;
		count := 2;
		err := FSWrite(ModemOutputRefNum, count, @chars);				{send "chars", all two bytes of it}
		XMitCRLF := err;
	END;

	FUNCTION XMitInt;
	BEGIN
		xMitInt := XMitBuf(@i, 2);
	END;

	FUNCTION XMitLong;
	BEGIN
		XmitLong := XMitBuf(@l, 4);
	END;

	FUNCTION XMitLine;
		VAR
			count : LongInt;
	BEGIN
		count := length(str);
		XMitLine := FSWrite(ModemOutputRefNum, count, Pointer(ord4(@Str) + 1));
		xMitLine := XMitCRLF;
	END;

	FUNCTION RecvBuf;
	BEGIN
		RecvBuf := FSRead(ModemInputRefNum, len, buf);
	END;

	FUNCTION RecvChar;
		VAR
			chars : PACKED ARRAY[0..1] OF char;
			count : LongInt;

	BEGIN
		count := 1;
		RecvChar := FSRead(ModemInputRefNum, count, @chars);
		c := chars[0];
	END;

	FUNCTION RecvFixedString;
		VAR
			count : LongInt;

	BEGIN
		count := len;
		RecvFixedString := FSRead(ModemInputRefNum, count, Pointer(ord4(@str) + 1));
		str[0] := chr(LoWord(count));
	END;

	FUNCTION RecvString;
		VAR
			len : LongInt;
			err : OSErr;

	BEGIN
		err := SerGetBuf(ModemInputRefNum, len);
		RecvString := FSRead(ModemInputRefNum, len, Pointer(ord4(@str) + 1));
		str[0] := chr(LoWord(len));
	END;

	PROCEDURE Wait;
		VAR
			time : LongInt;

	BEGIN
		Time := TickCount;
		WHILE (tickCount - time) < ticks DO
			;
	END;
END.
**The opinions stated herein are my own opinions and do not necessarily
represent the policies or opinions of my employer (THINK Technologies, Inc).

Richard M. Siegel
Customer Support Representative
THINK Technologies, Inc.

Uucp: {decvax, ucbvax, sun}!harvard!endor!singer
Internet/Arpanet: singer@harvard.harvard.edu

No one writes programs that work right the first time. If they did,
I'd be out of a job.