Well, I am off and running on getting my version of
the code up to speed:
https://github.com/go4retro/tcpser
Man, some of this code is rough. I have learned a lot about writing C code in the last
decade+.
Anyway, while I work on adding the appropriate functionality into the codebase, I find
myself ruminating on why there were so many parity options in serial communications.
I understand the need for parity per se, given link quality and such. But, why the need
for Odd, Even, Mark, Space. Is there some reason why different parity options work better
in certain situations?
Also, for those wanting to help with some code:
int detect_parity(modem_config *cfg)
{
int parity, eobits;
int charA, charT, charCR;
charA = cfg->pchars[0];
charT = cfg->pchars[1];
charCR = cfg->pchars[2];
parity = (charA & 0x80) >> 7;
parity |= (charT & 0x80) >> 6;
parity |= (charCR & 0x80) >> 5;
eobits = gen_parity(charA & 0x7f);
eobits |= gen_parity(charT & 0x7f) << 1;
eobits |= gen_parity(charCR & 0x7f) << 2;
if (parity == eobits)
return 2;
if (parity && (parity ^ eobits) == (parity | eobits))
return 1;
return parity & 0x3;
}
#define gen_parity(v) (((((v) * 0x0101010101010101ULL) & 0x8040201008040201ULL) %
0x1FF) & 1)
Fozztexx (Chris Osborn) authored this little slice of code, and it uses the AT<cr>
to determine parity of the form:
space == 0
odd == 1
even == 2
mark == 3
I'm trying to sort the code out in my head, which will happen, but takes time. The
issue I see with it is the use of the CR as the third char to check.
Hayes S registers always allows the redefinition of the CR character, via S3. As such,
there's no guarantee line termination = CR, (yes, it's valid for the first AT
command, but not after, so if the user does a 8N1 ATS3=15<cr> and then switches to
7E1, the emulator will not handle well. I agree the likelihood is almost nil someone does
this, but tcpser is supposed to be very pedantic on such matters.
Thus, anyone have a way to discern parity using only the 'A' and 'T' ? I
guess I might be able to still use the terminator, since I know what it is ahead of time,
but not sure if the above code works on the principle that the 3 ASCII values have unique
traits that would not hold true for other values.
(Without having gone through the code presented in full detail, but thinking from root
premises.)
ASCII A = 0x41 --> 2 bits on
ASCII T = 0x54 --> 3 bits on
Thus A and T would produce different parity values, and presented with an instance of each
character it should be possible to discern all 4 potential parity encodings (S/O/E/M
derived from the 4 combinations possible from observing the parity bit from the two
character instances 00/10/01/11 (if I have parity policy in the right order)).
So it wouldn't seem like the CR would be necessary for the task.
If one assumes ASCII encoding for the A & T it seems to me the code could be simpler -
e.g. why calculate parity for known characters; but perhaps the writer had something more
in mind than I'm aware or thinking of.