[comp.sys.mac.programmer] LSC and DDP

pete@mck-csc.UUCP (Peter Gaston) (01/11/90)

I would like to use a DDP level socket in some code I'm writing.  For
this I need to do a DDP socket listener.  Does anyone have any hints
on doing this from LSC?  I have working samples in MPW, but I'd like
to keep everything in LSC for ease of maintenence.

For example, How is ReadRest called?  What about multifinder (i.e. if
the listener is called at a bad time, A5 may be incorrect...)?

Any help would be appreciated.  Thanks.

Peter Gaston

tim@hoptoad.uucp (Tim Maroney) (01/12/90)

In article <338@mck-csc.UUCP> pete@mck-csc.UUCP (Peter Gaston) writes:
>I would like to use a DDP level socket in some code I'm writing.  For
>this I need to do a DDP socket listener.  Does anyone have any hints
>on doing this from LSC?  I have working samples in MPW, but I'd like
>to keep everything in LSC for ease of maintenence.
>
>For example, How is ReadRest called?  What about multifinder (i.e. if
>the listener is called at a bad time, A5 may be incorrect...)?

I've written several, though all in MPW Assembler and Lisa Assembler.
Unfortunately, the interface is very badly designed, so you can't
write it in anything but assembly language (in-line assembler in THINK C).

The MPW Assembler samples ought to work just about as well in THINK C
in-line assembler; most assemblers are pretty similar.  However,
if it involves any of MPW's fancy data structure definitions or
structured macros, you may have to do a significant amount of conversion.

I do have a few hints; make sure you know that section of the
documentation backwards and forwards before you start, be prepared to
crash your machine repeatedly, work on an isolated network with a Mac
dedicated to Peek attached, and put DC.W $A9FF breakpoints in your code
to watch what's happening whenever things don't seem to be making
sense.  Notice that because of the timing involved, these breakpoints
will prevent the code from working if you call ReadRest or ReadPacket
after the breakpoint, and may very well crash your machine outright if
you try to continue normal execution.  Such is the price of success.

As for A5, there's not really any choice.  You have to stash it in code
relative space before you start, then use that when you're called from
the DDP driver.  That is, you have to use a DC.L .  This is nasty and
possibly incompatible with future systems, but I've been asking Apple
for an alternative for years and there still isn't one.

ReadRest is called by offset from a4, i.e.,

	jsr	2(a4)

The arguments are in A3 (buffer address) and D3 (buffer size), as
documented.  You should keep a queue of pre-allocated buffers, dequeue
the header when you get a packet, and use that buffer to read in the
packet, then enqueue the buffer onto a reception queue.  (Or put it
back on the free queue if things fail).

Be sure you always call ReadRest.  Be sure to check error returns from
ReadPacket and ReadRest by using the Z bit directly; don't do your own
tests on D3, it's not always correct.  For instance, to call ReadPacket
and test for error,

	jsr	(a4)
	bne.s	error

DON'T do this:

	jsr	(a4)
	tst.w	d3
	bne.s	error

You will get puzzling crashes if you do.  Sometimes d3 is zero even
though there was an error.

Hope this helps.  Socket listeners and protocol handlers are weird and
frustrating, but it feels so good when you can stop working on them.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"In science it often happens that scientists say, 'You know that's a
 really good argument; my position is mistaken,' and then they actually
 change their minds and you never hear that old view from them again.
 They really do it.  It doesn't happen as often as it should, because
 scientists are human and change is sometimes painful.  But it happens
 every day.  I cannot recall the last time something like that happened
 in politics or religion." -- Carl Sagan, 1987 CSICOP keynote address