Hi Martin Eric,

on Tue 02-11-1999 19:06 Martin-Eric Racine wrote:
>>
----- snip ----- re: porting PLEP to mint
>
>Actually, I do.  

Ok then, I'm not sure exactly how well you are familiar with PLIP
hardware signalling, so I'll give a first outline of both PLIP and
PLEP details further below (for comparison), and then you can come
back with questions on any details you want clarified.


>Certain people on the MiNT list expressed concern that the
>regular PLIP protocol *might* cause damage to either end's
>Centronics hardware, if/when a collision occurs.
>
>Is your enhanced PLEP protocol immune to this?

No protocol can ensure completely against a hardware 'collision',
the best way to protect against such problems is by hardware mods,
as described in my docs on how to build a PLIP/PLEP adaptor instead
of just modified cable.

A collision of this kind can only occur when both sides think that
they may send at the same time, so the basic assumption is that the
protocol has already failed somehow.

Of course, it could happen more normally in a really bad protocol,
that does not return the port to input state after each byte transfer.
PLEP does return to that state at all times when it is not waiting for
the other end to read its output data, and the first response to a
write collision is always to set the port for input.  Also, PLEP has
a better capability to detect write collisions, due to the different
usage of Strobe and Busy signals.


>> There isn't, although some words categorically belong to one or the
>> other of these classes.  It is a bit like german declinations, in
>> that you mostly have to learn the classifications by rote.
>
>Declinations are easy enough and there are clear rules about
>which word is masculine, feminine or neutral in German.

No, those are genders, whereas I think there are six declinations in
german, or possibly more.  It was a long time since I went to school,
and german grammar was not a subject I enjoyed...


>Finnish has even more intricate declinations (17 cases), but not
>masculine/feminine per se.  The context indicates wether a person
>is male or female and everything else is neutral (exception: when
>talking about a specificaly male/female animal or person, then we
>add a special feminine ending).

Yes, I have heard about that, and also that they 'stack' suffixes
to a much greater extent than we do in swedish (max three levels).
But I have no real knowledge of finnish myself.


>> In fact even english has some remaining vestiges of such grammar,
>> although most of it disappeared many centuries ago, so it mostly
>> applies only to ancient words and expressions.
>
>Irregular verbs in English all have Saxon and Norse origins;
>quite germanic sounding too.

Small wonder, as the Saxons settled parts of britain long before
the Romans left.  They made some kind of deal to defend the coasts
against other german tribes.  English has some very mixed origins.


----- snip ----- re: slang and loanwords in Sweden VS Finland
>
>Funny you mention this:  
>
>my boss was saying that, to him, nynorsk is the only scandinavian
>language he understands fluently, because it sounds like the old
>swedish dialect he was taught as a child; modern swedish uses too
>many English, German and Danish words, in his opinion.

I suppose it does add a strong foreign flavour to modern speech, but
it is still better than the opposite approach, practiced by Iceland.
They invent new words based on ancient ones for *ALL* modern stuff.
I have no idea what ancient norse words they use to describe ICs
and transistors etc...  Seems a bit silly to me to be honest.


>> (eg: 'garage')  The use of french '' is no longer considered
>> necessary, and a normal 'e' will be accepted as equally
>> correct, although many still use '' anyway.
>
>Well, garage never had any  in French anyhow... ;-)

I do know that. I guess I should have separated those two statements.
I mentioned 'garage' because there is such a *huge* difference between
the pronounciation it should have if swedish rules were applied, and
the french/english pronounciation that we too use.


>> Well, if you already 'had no trouble figuring out what people said'
>> then I think that this course may be below your current level, and
>> you would waste a lot of time rehearsing stuff you already know.
>
>Nej! Jag inte tallar svenska.  I just manage to extrapolate
>because of the obvious resemblances with French and German.
>As long as one knows how to pronounce the scandinavian vowels,
>many words are easily figured out.

That is true.  The real problem for most englishmen and americans is
that they almost never can master the scandinavian sounds.  Even if
they do learn to recognize the differencies they can seldom manage
to pronounce them correctly.


>For example, "inte" reminds me of the old British "ain't" and
>incidently has the same meaning, while "tallar" reminds me of
>"teller" as in "storyteller."

There are many such relationships, and in most cases this is due
to a common origin.  Actually 'teller' is identical to 'talare'
in its origins.


>> Most foreigners arriving here don't know any swedish at all,
>> and it must be them that this course is geared for.
>
>Neither do I, but then again, just listening and noting the
>similarities helps me understand.  

What I meant was that sharing an 'immersion' with lots of other
beginners might not be the best way to learn/improve your swedish.
It might be more effective to use those two weeks to mingle with
swedish people for real instead.  Sort of a personal immersion...


>Same with Russian; you wouldn't believe the number of words
>similar to French (pretty obvious) and sometimes German and
>Swedish (if you listen closely).

I know.  There has always been some traffic between Sweden and
russia, and even now there are some villages deep in russia where
Swedish is still spoken.  And the French and German influence is
of course due to the periods when those nations were dominant, a
few centuries back for France, but more recently for Germany.

Sweden too imported lots of French and German loanwords in those
periods.  (In fact our royalty too is imported from France.)


>See if you can guess this one (I assume scandinavian
>pronounciation, in this example):
>
>Ja govorju po-schvedskji.

I'm not sure about 'govorju' but I'd guess either at "I speak swedish"
or the opposite, though I doubt the latter as I do recognize some of
the negations.


Ok, so now for some PLIP/PLEP details.

Both PLIP and PLEP use the strobe signal to flag outgoing transfers
and to acknowledge read bytes.  But they do it in different ways.

Without adding overmuch complexity a single handshake line has two
ways of being used. Short pulses and steady state changes.  PLIP
only makes use of the latter once per packet, which forces it to
use identical pulses for writing bytes and for reading bytes.

That is the main reason why PLIP can't detect collisions easily,
because it can mistake incoming write pulses as read acknowledge
pulses. So both ends keep on sending, believing that the other
is actually receiving.


PLIP hardware signalling:
-------------------------
A PLIP transfer is done like this:

 1:  Sender initiates communication by a Strobe pulse
 2:  Receiver acknowledges that request by holding Strobe low
 3:  Sender checks that Busy is steadily low and pulses Strobe again
 4:  Receiver first raises Strobe level, and pulses Strobe to start transfer
 5:  Sender switches to output mode
 6:  Sender outputs an encoded data byte and pulses Strobe
 7:  Receiver reads the data and pulses strobe
 8:  Steps 6 and 7 above repeat for all encoded bytes of a datagram
 9:  After all data Sender outputs END code and pulses strobe
10:  Receiver reads the END code and pulses strobe
11:  Sender switches to input mode

It is possible to switch to input mode for each byte too, but I doubt very
much that the MiNT driver does so.

Note that the only check on signal validity occurs in step 3 above, and that
there is no way for either party to detect a collision after that.  Both will
keep on pulsing until one of them completes sending its datagram.  Also note
that all states except the four SLIP 'specials' are allowed on data lines,
so short-circuit can not be detected that way either.


PLEP hardware signalling:
-------------------------
A PLEP transfer is a lot more complex, so before I proceed with a step by
step list I need to establish some 'global' differencies.

A:  Whenever Busy drops, for long or short pulse, Strobe will be raised
    and the port will be set for input.  (This cuts off any collision.)

B:  If Busy is still low after some more processing, then this is taken
    to mean that a byte is incoming (command code or data), and that byte
    is then read and Strobe is pulsed in response.  This is called sending
    an ACK (acknowledgement).

C:  If Busy was not low as tested in "B:", then it is taken as an invitation
    to send something.  This can be a response code to ongoing traffic, a
    command to start a new transfer, or whatever.  It depends on the state.
    In many cases it will be another ACK, inviting the other end to send.

D:  Sending a low Strobe level, as seen in "B:" is called sending an ATT
    (attention) and is always accompanied by data on the output port.
    As implied by "B:" and "A:" the automatic response pulse from the
    other end causes us to raise the Strobe level and release the port,
    as soon as the other end has read the data.

It should be clear from the above that there are rich opportunities to
detect any deviation, and collisions will always be cut short if both
parties are at least 'alive'.

Also, 16 codes are reserved for special use, and will never occur in data.
Two of these, $00 and $FF, are considered error codes, and will lead to
abortion of any ongoing process.  The code $00, which is the most likely
result of collisions, is also used as the normal error code, which always
leads to both parties switching ports to input and stop signalling.  If
needed the transfer process can be restarted by an interrupt driven timer
within 50ms.  Of the other codes only some are currently used, the rest
being reserved for future needs.  (eg: PLMP)

With the above concepts clearly in mind we can start on the 'step list'

 1:  Sender sends ATT with DBEG code on port (Datagram BEGun)
 2:  Receiver sends ACK after noting DBEG request
 3:  Sender sends ACK to invite detailed response
 4:  Receiver sends ATT with DREQ code on port
 5:  Sender sends ACK after noting DREQ (Datagram REQuest)
 6:  Receiver sends ACK to invite datagram data
 7:  Semder sends ATT with encoded datagram byte on port
 8:  Receiver sends ACK after storing data
 9:  Steps 7 and 8 are repeated until datagram is complete
10:  Sender sends ATT with upper byte of CRC (encoded) on port
11:  Receiver sends ACK after storing CRC byte
12:  Sender sends ATT with lower byte of CRC (encoded) on port
13:  Receiver sends ACK after storing CRC byte
14:  Sender sends ATT with DEND code on port (Datagram END)
15:  Receiver sends ACK after noting DEND code
16:  Sender sends ACK to request detailed response from receiver
17:  Receiver sends ATT with DACK code on port (Datagram ACKnowledged)
18:  Sender sends ACK after noting transfer success

At this point the current transfer is over, and the 'ball' rests in the
hands of the late Receiver, who can now initiate a new transfer, or send
an ACK to the late Sender to let him continue if he likes.  If neither
has any more data to send, this is where the process goes idle.

But that is not all...  Far from it !

At every step along the way it is possible for either party to break the
process by sending ATT with ERRL (ERRor Low = $00) on the port, which will
then cause both ends to go idle with very little delay. It is not permitted
for a receiver of ERRL to send one of its own. (could go on forever...)

It is also possible for a Receiver to refuse accepting data at step "4:",
to send something instead, simply by sending a DBEG of its own, rather
than the DREQ that the other end wants.


Whenever a legal command is received, even in ongoing traffic, the one who
receives it should respond to it as if it had arrived in idle state, after
aborting the transfer (if any) that was in progress and if so, then that
datagram should remain in storage for a future attempt.

The same should also be done if the receiver sends any other response than
DACK after a sender has sent DEND and ACK.  PLIP is lossy, PLEP is not !

But please note that if the CRC is correct, then receiver MUST send DACK.
It should never interfere with, or test correctness of, higher protocols
such as TCP/IP etc.  That would waste the work done by TCP et al.


Whenever an illegal command is received, which is not ERRL, the receiver
should respond by sending ERRL, and then going to idle state.  Note that
many codes are only legal in their expected sequence, but illegal when
they arrive in any other circumstances.


One important code which has not been mentioned yet is DOFF (Data OFFset),
which is used as a prefix byte to any data (or CRC) byte whose encoded value
would coincide with one of the 16 'specials', then an extra offset is added
to that byte so that it can be sent without breaking the rules.

NB: this means that steps "10:" to "13:" that handled the CRC could actually
    need to transfer as many as 4 bytes for this.  But this does not matter,
    because at that time the receiver has not yet seen DEND, so he just goes
    on storing the decoded bytes and including them in the calculated CRC,
    as if they were data.  This will lead to a zero CRC when DEND arrives,
    which is ideal for simple testing.  The only drawback is the loss of
    two bytes for each datagram buffer, and I think we can live with that ;-)

Naturally the receiver should also check that received data does not exceed
max MTU+2 before DEND arrives, and if this limit is exceeded, then that is
another occasion to send ERRL and go idle.


I think this is near complete now, except for some needed 'numbers'.
As normal (for me that is) these are given in DevPac syntax:
;----------------------------------------------------------------------------
cp_ERRL		= $00	;ix F  eq AF	;ERRor Lo, request refused
cp_ERRH		= $FF	;ix E  eq AE	;ERRor Hi, spurious error
cp_DREQ		= $FE	;ix D  eq AD	;Data REQuest from receiver
cp_DBEG		= $FD	;ix C  eq AC	;Data BEGun from sender
cp_DEND		= $FC	;ix B  eq AB	;Data END from sender
cp_DOFF		= $FB	;ix A  eq AA	;Data OFFset from sender
cp_DACK		= $FA	;ix 9  eq A9	;Data ACKnowledge from receiver
cp_res0		= $F9	;ix 8  eq A8
cp_sel8		= $F8	;ix 7  eq A7	;gated select 8 (DBEG for unit 8)
cp_sel7		= $F7	;ix 6  eq A6	;gated select 7 (DBEG for unit 7)
cp_sel6		= $F6	;ix 5  eq A5	;gated select 6 (DBEG for unit 6)
cp_sel5		= $F5	;ix 4  eq A4	;gated select 5 (DBEG for unit 5)
cp_sel4		= $F4	;ix 3  eq A3	;gated select 4 (DBEG for unit 4)
cp_sel3		= $F3	;ix 2  eq A2	;gated select 3 (DBEG for unit 3)
cp_sel2		= $F2	;ix 1  eq A1	;gated select 2 (DBEG for unit 2)
cp_sel1		= $F1	;ix 0  eq A0	;gated select 1 (DBEG for unit 1)
;-------
cp_offset	= $80			;encoded char offset for cp_DOFF
cp_base		= $A0			;decoded char equivalent to cp_sel0 when encoded
cp_DOFF_dec	= $FF&(cp_base-cp_sel1-cp_offset)
cp_DOFF_enc	= $FF&(cp_sel1+cp_offset)
;----------------------------------------------------------------------------

This may not be entirely clear, so let me clarify the use a bit.

The code cp_ERRH is not intended to be used ever.  It it purposely blocked,
as it represents the least reliable signal state.  (pull-up condition)

The codes cp_sel1 through cp_sel8 are not used at all by PLEP, but are in
preparation for a coming protocol, with multiple units  connected. (PLMP)
My aim is to keep that as close as possible to PLEP, although it remains
to be seen to what extent that will be possible. (Hardware dependent.)

All data is sent with some offset, which is normally (cp_sel1-cp_base), and
given these definitions that is $51.  This means that if data bytes in the
range $A0-$AF were to be encoded this way, then they would result in values
that coincide with the 'specials' cp_sel1 through cp_ERRL.

To avoid that, those values use the cp_DOFF prefix byte followed with the
encoded byte offset additionally by cp_offset, which is $80.

This means that (for example) a data byte of $A3 would be sent as the two
bytes $FB and $74.  But only the pure data before encoding is included in
the CRC calculation.  No command bytes or offsets are involved in that.

The CRC calculation is a perfectly normal 16bit CRC of 8bit data stream,
so you may already have nice routines for that.  Otherwise you may use the
same one I designed for it.  (Preferably crediting the source.  ;-)

It is given below as a DevPac macro, which should be entered with a byte
to be included in the CRC in d0, and the CRC value itself in d1.  The
result is garbage in d0 and the new CRC value in d1.  This just happened
to fit my needs best, but it is easily changed.

Some people insist on table-driven code for CRC, but to be quite honest
I fail to see how much can be gained, either in space or in speed, over
the 10 instructions (of 20 bytes total), achieved by this macro.

;-------------------------------------
pl_crc	MACRO
;-------------------------------------
	rol.w	#8,d1
	eor.b	d0,d1
	move.b	d1,d0
	lsr.b	#4,d0
	eor.b	d0,d1
	move.b	d1,d0
	lsl.w	#7,d0
	eor.b	d1,d0
	lsl.w	#5,d0
	eor.w	d0,d1
	ENDM
;-------------------------------------

Ok, that's all for now then.
