So, it turns out you can write back to the Activator to change the heights it's looking for. Although it seems only the demo program may be doing it, no idea if the released device supports this (especially seeing as it looks up if light bounces at a certain angle or not, it'd require either tilting the sensors or having a bunch of them for each height).

Warning: the stuff below is mostly a wild guess from examining code, I need confirmation from people who can test on a real Activator

When idling (i.e. when not accessing the Activator), TH and DATA0 should be outputs, and they should be high and low, respectively. The rest of the pins should be inputs (in other words, ctrl port = $41, data port = $40). I have no idea what kicks the Activator into compatibility mode (i.e. pretending to be a controller), but I guess it kicks in if this doesn't happen for a while.

The Activator loves to change the directions of the pins (sometimes it drives them, sometimes it doesn't). The "driven/not driven" stuff below is a wild guess on my end and could be entirely wrong, especially since I don't know what it does in compatibility mode.

To read the Activator state:

Write $00 to data port

Wait a while (code does 28 dummy DBF iterations)

Read data port, check that it's $04

Write $01 to data port and wait until bit 1 = 1

Read data port, bits 5-2 are L3-L0

Write $00 to data port and wait until bit 1 = 0

Read data port, bits 5-2 are L7-L4

Write $01 to data port and wait until bit 1 = 1

Read data port, bits 5-2 are H3-H0

Write $00 to data port and wait until bit 1 = 0

Read data port, bits 5-2 are H7-H4

Write $40 to data port

To send a command to the Activator:

Write $00 to data port

Wait a while (code does 28 dummy DBF iterations)

Read data port, check that it's $04

Write $7D to ctrl port and wait a couple of NOP

Write $01 to data port and wait until bit 1 = 1

Read data port, check that it's $01

Write (command<<2) to data port and wait until bit 1 = 0

Write $40 to data port and wait a couple of NOP

Write $41 to ctrl port

This is what made me suspect that TR/TL/DATA3/DATA2 are not driven and the value caused by pull up/down instead: otherwise the only way the Mega Drive could signal a write is by causing a bus fight. It seems that the difference between starting a read and starting a write is whether they get driven low before DATA0 gets toggled again.

No idea what values can be written, but it seems 0-7 change the heights the Activator looks for (in steps of 2 inches, according to the demo program). It's possible the fourth bit isn't used at all.

EDIT: thinking about it further, since there's a significant delay needed after you do the initial $00 write, I wonder if that's what the Activator uses to determine whether to go into compatibility mode or not (i.e. Activator packet would start if TH and DATA0 are held low for long enough, while reading a controller would not try to drive low DATA0). In which case the initial "not driven" values in those charts are wrong :​P (again, I really need tests on the real thing to know for sure)