OK - Here are some bits and pieces from code which runs nicely on an 'F88 @ 16 MHz:

* * * *

DEFINE OSC 16
DEFINE HSER_BAUD 250000
DEFINE HSER_CLROERR 1

* * * *
This next routine is called on a gosub from my main housekeeping loop:
* * * *

checkdmx:

counter = 1 'just a dummy variable
pulsin target,0,counter 'here I'm looking for the break signal

if counter = 0 then
idleflag = 1 'either no dmx, or break was too long to count
return
endif


if counter < 40 then checkdmx 'watching for 'break
'if you get here, an active low pulse was detected, but it was too short.
'probably just part of the datastream. So go back and look again.

'otherwise, a valid break was found and it's time to read the start code

RCREG = dummy 'clear out any garbage which may be in the USART
RCREG = dummy
SPBRG = 0
TXSTA.2 = 0 'brgh = 0
TXSTA.4 = 0
RCSTA.7 = 1
RCSTA.6 = 0 'setting 8 bit receive mode, no parity, etc
RCSTA.4 = 0 'check the datasheet to see what all these bits do
RCSTA.4 = 1 'now, the USART is on and ready to receive

while RCIF = 0:wend 'hover here after break, before start code

startcode = RCREG 'This is the first byte received after the break

if startcode <> 0 then 'do your own stuff here on a non-zero code

aminus = address1 - 1 'address1 is my target address

for x = 1 to aminus 'set up a loop to count almost to the address
while RCIF = 0:WEND 'sit here until a byte is received
dummy = RCREG 'stash the byte somewhere unimportant
next x

hserin [newlevel1] 'This is your target channel data

RCSTA.7 = 0 'turn off the USART

return