• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

TashTalk: Single-Chip LocalTalk Interface

cheesestraws

Well-known member
If you want to wire this up to netatalk on a pi or similar directly, I'd recommend having a look at the following code, which may still work. This is the Linux driver for the LocalTalk PC Card. It works by decapitating the incoming LocalTalk frames and generating fake ethernet frames.


Personally, I think my first approach would be to try to do the same; adapt this algorithm to process packets, read and write them from a tap interface's file descriptor, then wire up netatalk to the tap as it if were to a localtalk card, and see what happens.
 

LaPorta

Well-known member
That’s pretty cool: any chance this could be used to create some sort of straight-up server device, almost like a NAS that legacy AppleTalk computers could attach to? Kind of like A2SERVER, but a bit more transparent?
 

dougg3

Well-known member
If you want to wire this up to netatalk on a pi or similar directly, I'd recommend having a look at the following code, which may still work. This is the Linux driver for the LocalTalk PC Card. It works by decapitating the incoming LocalTalk frames and generating fake ethernet frames.


Wow...I never saw the whole "pretends to be an ether device" stuff in the comments at the top of this driver but now I see them after you brought it up. This driver is super old by the way...looks like it was started in 1995! I'm pretty sure that those comments about Ethernet are out of date. Linux has the capability to create an actual network interface that is a LocalTalk device for a super long time (e.g. lt0 instead of eth0) and this driver uses that capability now -- one way to tell is that it calls alloc_ltalkdev. So I'm probably being slightly pedantic (hopefully not annoyingly!), but what this driver really does is: take LocalTalk frames from the Linux networking stack and send them onto the card when asked to send, and receive frames from the card and forward them onto the Linux networking stack. Not as Ethernet frames, but as LocalTalk frames.

Either way, if a driver like this was written for this project, you could use netatalk 2.x out of the box to implement a bridge between Ethernet and LocalTalk. That's the direction I ended up going because all of the stuff in the various chapters of Inside AppleTalk got pretty intimidating and netatalk did it all for me. But...I did deal with annoying kernel issues to get to that point -- nobody's been using/maintaining this stuff, there's definitely some bit rot.
 

cheesestraws

Well-known member
! I'm pretty sure that those comments about Ethernet are out of date.

Then I stand corrected. I saw header wibbling and Linux kernel foo I didn't understand, and sort of assumed the comments were right...

Sigh.

Sorry to send everyone down a rabbit hole.
 

tashtari

PIC Whisperer
Not as Ethernet frames, but as LocalTalk frames.
That makes a lot of sense given what I was reading from that source code. As far as I can tell, though, the tap interface assumes Ethernet and I don't think this can be changed, so making a LocalTalk device would involve either changing the tap driver or writing a new LocalTalk kernel driver, neither of which I'm anxious to do. An interesting proposition would be to bridge to EtherTalk Phase 1 and thus not have to worry about cheating and breaking routing to come up with the network number (if anyone wants Phase 2, they can use tashtalkd to bridge to LToUDP and further bridge it using https://github.com/sfiera/multitalk) but I'm struggling to find any documentation at all on EtherTalk Phase 1; all I get are passing mentions of it as being old and busted and Phase 2 being the new hotness.
 

tashtari

PIC Whisperer
The more I think about this, the more I just want to leave tashtalkd as a bridge between the TashTalk device and LToUDP. The only thing I'd really want to extend it to is a tapped lt0 device, and I don't think there's a way to do that without mucking about in the kernel. I say "the kernel" like there's only one, but as @cheesestraws has pointed out, there's reason to want to do this on NetBSD, because it's got a maintained netatalk 2.x package...
 

tashtari

PIC Whisperer
On the Pi Hat; which Pi UART would you like the PIC to connect to?
Also, on the Pi Hat, where do you want the PIC's CTS to go on the Pi's header pins?
So, the pins that I have everything connected to on my breadboarded mess of a prototype are:

PIC Pin RPi 3 Pin SN65HVD08 Pin -------------------- ------------- ------------- 01 Supply 01 3v3 Power 08 Vcc 02 RA5/LocalTalk Out 04 D 03 RA4/Driver Enable 03 DE 04 RA3/LocalTalk In 01 R 05 RA2/UART CTS 36 GPIO16/CTS 06 RA1/UART RX 08 GPIO14/TXD 07 RA0/UART TX 10 GPIO15/RXD 08 Ground 06 Ground 05 GND

Pins are per https://pinout.xyz/pinout/uart, and please do double-check me. I use the PL001 UART on the RPi 3 because it supports RTS/CTS. It's my understanding that the RPi 4 has a bunch more UARTs than its predecessors, which only have the PL001 "good" UART and the mini-UART that's pinned to the system clock and lacks features (one of which is RTS/CTS). On the RPi 3, I had to apply a device tree file that switched the Bluetooth device to use the mini-UART instead of the PL001 UART that it uses by default. I don't know if the board would have to change for use with the RPi 4.

My prototype uses the SN65HVD08 as its driver/receiver chip; you can of course use whatever RS422/485 driver chip you want, but be sure to experimentally verify that its receiver outputs a logic '1' for an idle, undriven bus. Another chip from TI that I tried (the SN75C1168) seemed to indicate in its spec sheet that it would, but instead outputted an indecisive signal.

On that subject, actually, I'm curious: are you thinking to put an 8-pin mini-DIN on this so that the user can plug in a LocalTalk or PhoneNet dongle as they prefer, or directly mount a pair of 3-pin mini-DINs or 6P4C connectors and use your own isolation transformer? My prototype uses a broken-open PhoneNet dongle and actually had to use a pair of SN65HVD08s, one as driver and one as receiver, because the hybrid transformer in the dongle expects separate lines for transmit and receive (because that's what it gets from the SCC) - but you should only have to use one SN65HVD08 if you're using your own isolation transformer because the bus is inherently half-duplex. I just know nothing about isolation transformers and didn't feel confident selecting a part myself in order to do that.
 

bdurbrow

Well-known member
I was putting on a mini-din 8 connector; with pads for both a right-angle and vertical connector depending on which one the user wanted to install. I was going to have that driven by an ISL83490IBZ; but it seems to be out of stock now... so I'll have to put pads down for an alternate chip.
 

NJRoadfan

Well-known member
netatalk can handle any AppleTalk routing via its atalkd component. There is no reason to reinvent the wheel. I don't think the Linux kernel support for AppleTalk supports Phase 1 packets, so thats the reasoning for any oddities dealing with LocalTalk PC cards.
 

tashtari

PIC Whisperer
The synchronization pulse is clearly designed around the "missing clock" detection feature of the SCC.
the SCC can detect that it has lost a clock faster than it can detect that it has gained one.
Update on this, I implemented the sync pulse and updated the repo. As near as I can tell from scope traces, the SCC turns the driver on for 1.5 bit times and then keeps it off for 4.5 bit times before starting the actual transmission, so that's the behavior I sought to duplicate. It seemingly varies a lot how the receiver IC translates this into logic levels, but that doesn't matter; unlike the SCC, my firmware considers any inversion on the line to be a signal it's in use, it doesn't need to get and lose a clock...
 

tashtari

PIC Whisperer
netatalk can handle any AppleTalk routing via its atalkd component. There is no reason to reinvent the wheel. I don't think the Linux kernel support for AppleTalk supports Phase 1 packets, so thats the reasoning for any oddities dealing with LocalTalk PC cards.
Agree, I'm definitely not looking to write a whole new AppleTalk router, it's just a still-unanswered question in my mind what the right thing to do is to get the data captured by my chip into atalkd. Maybe what I ought to be doing is investigating what it would take to get atalkd to support LToUDP...
 

tashtari

PIC Whisperer
For speed, I modified the code so it starts counting down the inter-dialog gap from the last time there was activity, instead of when the host began transmitting a frame - this should considerably improve the latency of ENQ-ACK sequences between machines on different sides of the chip.

This has not, however, changed the fact that TashTalk - or at least my prototype setup - seems to be a better transmitter than receiver. I've been using copies of a 400 KB file between an emulated server and a real (LC II) client to test speed, and copies to the LC II (where the chip is mostly transmitting) are more than double the speed of copies to Mini vMac (where the chip is mostly receiving). In the latter case, there are many pauses of a discernible length in the activity during the copy, on the order of a quarter of a second, but in the former case there are almost none. Not yet sure what to ascribe this to. Frames are not arriving with bad CRCs on the host end, and that includes RTS/CTS, so it's not like things are getting garbled on the line...

I'll definitely be interested to see if anyone else has similar experiences, once more people have working setups. Anything I can do to make this happen faster? Anyone want to take a stab at breadboarding this and want some help? I aim to please. =)
 

sfiera

Well-known member
Have you tried getting two of your adapters talking so that you get a look at the transmitting and receiving ends at the same time?

I’d like to give it a go, or at least do some more work on multitalk to the point where it’s useful to you. I don’t remember exactly how well I was doing at bridging Phase 1/Phase 2. I think I had an EtherTalk Quadra talking to a LocalTalk Mini vMac Plus, but things fell down going through the Quadra’s AppleTalk bridge to a real Plus on the other side. As far as I understand, EtherTalk implies Phase 2; LocalTalk can be either, and something went wrong going 1 → 2 → 1.

Aside from the PIC12F1840, I assume I’d need some sort of programmer for the chip? I definitely have a spare Pi 0W lying around.
 

tashtari

PIC Whisperer
Have you tried getting two of your adapters talking so that you get a look at the transmitting and receiving ends at the same time?
I haven't yet. This is a good idea, I just need to come up with a setup where I can put it through its paces.
or at least do some more work on multitalk to the point where it’s useful to you. I don’t remember exactly how well I was doing at bridging Phase 1/Phase 2. I think I had an EtherTalk Quadra talking to a LocalTalk Mini vMac Plus, but things fell down going through the Quadra’s AppleTalk bridge to a real Plus on the other side. As far as I understand, EtherTalk implies Phase 2; LocalTalk can be either, and something went wrong going 1 → 2 → 1.
I'm trying to walk the line where I neither implement an AppleTalk router from scratch nor run anything that breaks an AppleTalk router, and I'm still not sure how best to do this. EtherTalk Phase 1 does exist, I know that much, because even though I can't find any documentation on it, it is mentioned in several places. I could be wrong, but I think LocalTalk is inherently Phase 1 because a LocalTalk network can't contain more than 253 nodes. If I'm right about both of those things, bridging LocalTalk to EtherTalk Phase 1 could be an appealing idea, because Netatalk's atalkd supports EtherTalk Phase 1 and OS support for Ethernet is obviously strong, and nothing would be involved that would break routing.

Looking more closely at the introduction to the second edition of Inside AppleTalk, it mentions that Phase 2 was developed shortly after the first edition was published. It seems that, in typical Apple fashion, the old was swiftly disposed of and anyone still interested in it was asked to forget it ever existed. I found a copy of what I believe to be the first edition on ebay; maybe that will provide some answers on the subject of Phase 1 when it shows up.
Aside from the PIC12F1840, I assume I’d need some sort of programmer for the chip? I definitely have a spare Pi 0W lying around.
You would, yeah. It's my understanding that some multifunctional programmers like the TL866 can program it, or alternately you can get a PICkit 3 off ebay for peanuts since they're previous-generation. It's also worth noting that Microchip's sampling program is (in my experience) exceedingly generous, so you may not have to pay for the chip itself at all.
 

NJRoadfan

Well-known member
The first edition of Inside AppleTalk (or a draft of it) is out there somewhere in PDF. I recall coming across it at one point. The bigger issue is that almost nothing still in use today talks Phase 1, including the Linux kernel drivers for AppleTalk. One place to look for LocalTalk to Ethernet bridging ideas is the AppleTalk bridge in GSport. It injects LocalTalk LLAP packets from the emulated Apple IIgs into a PCap interface. I know Peter Neubauer had to do some creative workarounds dealing with Phase 2.

The AppleTalk Bridge Code:

The connection to the emulated SSC can be found in the main source tree at:

scc_llap.h/.c (glue interface between emulated SCC and bridge)
scc.h/.c (impliments actual SCC emulation)

FWIW, this bridge works with netatalk being the seed router. I have tested this code extensively with GSport and the IIgs GS/OS AppleTalk stack and it works very well.
 
Top