tashtalk/firmware/one-chip.asm

3108 lines
95 KiB
NASM

;;; 80 characters wide please ;;;;;;;;;;;;;;;;;;;;;;;;;; 8-space tabs please ;;;
;
;;;
;;;;; TashTalk: Single-Chip UART-LocalTalk Interface
;;;
;
;;; Connections ;;;
;;; ;;;
; .--------. ;
; Supply -|01 \/ 08|- Ground ;
; LocalTalk <--> RA5 -|02 07|- RA0/TX ---> UART TX ;
; Driver Enable <--- RA4 -|03 06|- RA1/RX <--- UART RX ;
; !MCLR ---> RA3 -|04 05|- RA2 ---> UART CTS ;
; '--------' ;
;;; ;;;
;;; Assembler Directives ;;;
list P=PIC12F1840, F=INHX32, ST=OFF, MM=OFF, R=DEC, X=ON
#include P12F1840.inc
errorlevel -302 ;Suppress "register not in bank 0" messages
errorlevel -224 ;Suppress TRIS instruction not recommended msgs
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
;_FOSC_INTOSC Internal oscillator, I/O on RA5
;_WDTE_OFF Watchdog timer disabled
;_PWRTE_ON Keep in reset for 64 ms on start
;_MCLRE_ON RA3/!MCLR is !MCLR
;_CP_OFF Code protection off
;_CPD_OFF Data memory protection off
;_BOREN_OFF Brownout reset off
;_CLKOUTEN_OFF CLKOUT disabled, I/O on RA4
;_IESO_OFF Internal/External switch not needed
;_FCMEN_OFF Fail-safe clock monitor not needed
__config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _LVP_OFF
;_WRT_OFF Write protection off
;_PLLEN_ON 4x PLL on
;_STVREN_ON Stack over/underflow causes reset
;_LVP_OFF High-voltage on Vpp to program
;;; Macros ;;;
DELAY macro value ;Delay 3*W cycles, set W to 0
movlw value
decfsz WREG,F
bra $-1
endm
DNOP macro
bra $+1
endm
;;; Constants ;;;
;FLAGS:
LR_FRM equ 7 ;Set when received frame registers have changed
LR_CROK equ 6 ;Set when CRC of last frame passed
CTS_PLS equ 5 ;Set when a CTS frame should trigger a send from queue
TMPFLAG equ 4 ;Used as temporary storage in transmitter
;FEATURES:
CALCCRC equ 7 ;Set if transmitter should calculate CRC itself
CHKCRC equ 6 ;Set if receiver should check CRC and signal bad CRCs
;;; Variable Storage ;;;
cblock 0x70 ;Bank-common registers
FLAGS ;You've got to have flags
LR_BUF ;Receiver buffer
LR_BUF2 ;Receiver buffer
LR_CCRC1 ;Receiver CRC register
LR_CCRC2 ; "
LR_STATE ;Receiver state pointer
UR_LEN ;Current length of UART receiver queue
GBACKOFF ;Global backoff mask
LBACKOFF ;Local backoff mask
COL_HIST ;Collision history for last 8 transmissions
DEF_HIST ;Deferral history for last 8 transmissions
ATTEMPTS ;Number of attempts at this transmission
FEATURES ;Feature flags
D2
D1
D0
endc
cblock 0xD0 ;Upper end of bank 1 registers
NODEBM0 ;Node ID bitmap
NODEBM1 ; "
NODEBM2 ; "
NODEBM3 ; "
NODEBM4 ; "
NODEBM5 ; "
NODEBM6 ; "
NODEBM7 ; "
NODEBM8 ; "
NODEBM9 ; "
NODEBM10 ; "
NODEBM11 ; "
NODEBM12 ; "
NODEBM13 ; "
NODEBM14 ; "
NODEBM15 ; "
NODEBM16 ; "
NODEBM17 ; "
NODEBM18 ; "
NODEBM19 ; "
NODEBM20 ; "
NODEBM21 ; "
NODEBM22 ; "
NODEBM23 ; "
NODEBM24 ; "
NODEBM25 ; "
NODEBM26 ; "
NODEBM27 ; "
NODEBM28 ; "
NODEBM29 ; "
NODEBM30 ; "
NODEBM31 ; "
endc
cblock 0x120 ;Bank 2 registers
FSR1L_TM ;Temp registers when using FSR1 to modify the node ID
INDF1_TM ; bitmap
LT_CRC1 ;Running CRC value calculated by SendByte/SendFromQueue
LT_CRC2 ; "
LT_CRCX ;Temp variable used when calculating CRC
LT_LENH ;Number of bytes to be read from queue by SendFromQueue
LT_LENL ; "
LT_BUF ;Buffer used to hold the byte being sent over LocalTalk
LT_BUF2 ;Temporary buffer
LT_ONES ;Count of consecutive ones sent by LT transmitter
UR_DEST ;First five bytes of frame loaded for transmission
UR_SRC ; "
UR_TYPE ; "
UR_4TH ; "
UR_5TH ; "
endc
cblock 0x16B ;Upper end of bank 2 registers
LR_DEST ;First five bytes of last received frame
LR_SRC ; "
LR_TYPE ; "
LR_CRC1 ; "
LR_CRC2 ; "
endc
;Linear Memory:
;0x2000-0x207F - UART receiver queue
;0x2080-0x209F - Node ID bitmap
;0x20A0-0x20AE - Bank 2 registers
;0x20AF-0x20EA - Unused
;0x20EB-0x20EF - Upper end of bank 2 registers
;;; Vectors ;;;
org 0x0 ;Reset vector
bra Init
org 0x4 ;Interrupt vector
;;; Interrupt Handler ;;;
Interrupt
movlp high LtReceiver ;02
btfsc INTCON,IOCIF ;03
goto LtReceiver ;04(-05)
movlb 0
btfsc PIR1,RCIF
bra RxInterrupt
retfie
RxInterrupt
movlb 3 ;Get the received byte
movf RCREG,W ; "
movwi FSR0++ ;Push it onto the queue
bcf FSR0L,7 ;Wrap the queue around
incf UR_LEN,F ;Increment the queue length
movlw B'00000100' ;If the UART receiver queue length >= 64,
movlb 2 ; deassert CTS so the host stops sending us
btfsc UR_LEN,6 ; data
iorwf LATA,F ; "
movlb 31 ;Store the changed UART receiver push point
movf FSR0L,W ; back in its shadow register so it stays the
movwf FSR0L_SHAD ; same when we return from interrupt
retfie
;;; Mainline ;;;
Init
banksel OSCCON ;32 MHz (w/PLL) high-freq internal oscillator
movlw B'11110000'
movwf OSCCON
banksel OSCSTAT ;Spin until PLL is ready and instruction clock
btfss OSCSTAT,PLLR ; gears up to 8 MHz
bra $-1
banksel IOCAN ;RA5 sets IOCAN[IOCAF5] on pos/neg edge
movlw B'00100000'
movwf IOCAN
movwf IOCAP
banksel RCSTA ;UART async mode, 1 MHz, but receiver not
movlw B'01001000' ; enabled just yet
movwf BAUDCON
clrf SPBRGH
movlw 7
movwf SPBRGL
movlw B'00100110'
movwf TXSTA
movlw B'10000000'
movwf RCSTA
banksel OPTION_REG ;Timer0 uses instruction clock
movlw B'11011111'
movwf OPTION_REG
banksel T1CON ;Timer1 ticks with instruction clock
movlw B'00000001'
movwf T1CON
banksel T2CON ;Timer2 has 1:16 prescaler, 1:10 postscaler, it
movlw B'01001010' ; interrupts after 20 * (PR2 + 1) microseconds
movwf T2CON
banksel ANSELA ;All pins digital, not analog
clrf ANSELA
banksel LATA ;Drivers off, CTS asserted
movlw B'00001011'
movwf LATA
banksel TRISA ;TX, RA4,2 outputs, RX, RA5,3 inputs
movlw B'00101010'
movwf TRISA
movlw 0x20 ;Set FSRs to point permanently to linear memory
movwf FSR0H
movwf FSR1H
movlw 0x80 ;Zero out node ID bitmap (0x2080-0x209F) so we
movwf FSR1L ; don't respond to random IDs before the host
movlw 0 ; gets a chance to initialize us
ZeroNID movwi FSR1++
btfss FSR1L,5
bra ZeroNID
clrf UR_LEN ;Set up UART receiver queue (0x2000-0x207F),
clrf FSR0L ; for which FSRs are push (FSR0) and pop (FSR1)
clrf FSR1L ; pointers
clrf FEATURES ;All optional features off to start
clrf LR_CCRC1 ;Receiver CRC registers cleared to ones to
decf LR_CCRC1,F ; start, we don't have time to do this when we
clrf LR_CCRC2 ; jump into the code
decf LR_CCRC2,F
banksel PIE1 ;UART Rx and IOC interrupts on, interrupt
movlw B'00100000' ; subsystem on
movwf PIE1
movlw B'11001000'
movwf INTCON
banksel RCSTA ;Enable receiver now that interrupt is on
bsf RCSTA,CREN
bra PrepForNextFrame
;entered with BSR = 2
AwaitFeatures
call CheckLtReceiver ;Check for and deal with receiver activity
movf UR_LEN,W ;If there isn't yet a byte in the UART receiver
addlw -1 ; queue, loop around again
btfss STATUS,C ; "
bra AwaitFeatures ; "
movwf UR_LEN ;Decrement the UART receiver queue size by 1
movlw B'11111011' ;If the pop off the queue dropped the length
btfss UR_LEN,6 ; below 64, assert CTS so the host sends us
andwf LATA,F ; data again
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf FEATURES ;Store this byte into the features bitmap
bra AwaitCommand ;Return to await next command
;entered with BSR = 2
AwaitNodeId
call CheckLtReceiver ;Check for and deal with receiver activity
movf UR_LEN,W ;If there aren't yet 32 bytes in the UART
addlw -32 ; receiver queue, loop around again
btfss STATUS,C ; "
bra AwaitNodeId ; "
movwf UR_LEN ;Decrement the UART receiver queue size by 32
movlw B'11111011' ;If the pop off the queue dropped the length
btfss UR_LEN,6 ; below 64, assert CTS so the host sends us
andwf LATA,F ; data again
movlb 1 ;Switch to bank 1 where the node ID bitmap is
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM0 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM1 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM2 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM3 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM4 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM5 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM6 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM7 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM8 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM9 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM10 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM11 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM12 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM13 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM14 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM15 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM16 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM17 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM18 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM19 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM20 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM21 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM22 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM23 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM24 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM25 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM26 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM27 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM28 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM29 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM30 ;Store this byte into the node ID bitmap
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf NODEBM31 ;Store this byte into the node ID bitmap
;fall through
;entered with BSR = ?
AwaitCommand
movlb 2
call CheckLtReceiver ;Check for and deal with receiver activity
movf UR_LEN,F ;If there's no data in the UART receiver queue,
btfsc STATUS,Z ; loop around again
bra AwaitCommand ; "
decf UR_LEN,F ;Decrement the UART receiver queue size
movlw B'11111011' ;If the pop off the queue dropped the length
btfss UR_LEN,6 ; below 64, assert CTS so the host sends us
andwf LATA,F ; data again
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
addlw -1 ;If it's one, that's the command byte for
btfsc STATUS,Z ; sending a frame, so go wait for the first
bra AwaitDest ; byte of that frame (the destination)
addlw -1 ;If it's two, that's the command byte for
btfsc STATUS,Z ; setting the node ID bitmap, so go wait for
bra AwaitNodeId ; that data
addlw -1 ;If it's three, that's the command byte for
btfsc STATUS,Z ; setting the features bitmap, so go wait for
bra AwaitFeatures ; that data
bra AwaitCommand ;All other commands are considered no-ops
;entered with BSR = ?
PrepForNextFrame
movlw -3 ;If there have been more than two collisions
btfsc COL_HIST,7 ; during the last eight transmissions, left-
addlw 1 ; shift a one (up to a maximum of four) into
btfsc COL_HIST,6 ; the global backoff mask and clear the
addlw 1 ; collision history
btfsc COL_HIST,5 ; "
addlw 1 ; "
btfsc COL_HIST,4 ; "
addlw 1 ; "
btfsc COL_HIST,3 ; "
addlw 1 ; "
btfsc COL_HIST,2 ; "
addlw 1 ; "
btfsc COL_HIST,1 ; "
addlw 1 ; "
btfsc COL_HIST,0 ; "
addlw 1 ; "
bsf STATUS,C ; "
btfss WREG,7 ; "
rlf GBACKOFF,F ; "
bcf GBACKOFF,4 ; "
btfss WREG,7 ; "
clrf COL_HIST ; "
movlw -2 ;If there have been fewer than two deferrals
btfsc DEF_HIST,7 ; during the last eight transmissions, right-
addlw 1 ; shift the global backoff mask and fill the
btfsc DEF_HIST,6 ; deferral history
addlw 1 ; "
btfsc DEF_HIST,5 ; "
addlw 1 ; "
btfsc DEF_HIST,4 ; "
addlw 1 ; "
btfsc DEF_HIST,3 ; "
addlw 1 ; "
btfsc DEF_HIST,2 ; "
addlw 1 ; "
btfsc DEF_HIST,1 ; "
addlw 1 ; "
btfsc DEF_HIST,0 ; "
addlw 1 ; "
btfsc WREG,7 ; "
lsrf GBACKOFF,F ; "
btfsc WREG,7 ; "
clrf DEF_HIST ; "
btfsc WREG,7 ; "
decf DEF_HIST,F ; "
lslf COL_HIST,F ;Progress the collision and deferral history
lslf DEF_HIST,F ; logs to make space for what happens this time
movf GBACKOFF,W ;Copy the global backoff mask into the local
movwf LBACKOFF ; backoff mask
movlw 32 ;Set attempts counter to 32
movwf ATTEMPTS ; "
bra AwaitCommand ;We're set for the next frame, wait for it
;entered with BSR = 2
AwaitDest
call CheckLtReceiver ;Check for and deal with receiver activity
movf UR_LEN,F ;If there's no data in the UART receiver queue,
btfsc STATUS,Z ; loop around again
bra AwaitDest ; "
decf UR_LEN,F ;Decrement the UART receiver queue size
movlw B'11111011' ;If the pop off the queue dropped the length
btfss UR_LEN,6 ; below 64, assert CTS so the host sends us
andwf LATA,F ; data again
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf UR_DEST ;Save this byte as the loaded frame destination
;fall through
;entered with BSR = 2
AwaitSrc
call CheckLtReceiver ;Check for and deal with receiver activity
movf UR_LEN,F ;If there's no data in the UART receiver queue,
btfsc STATUS,Z ; loop around again
bra AwaitSrc ; "
decf UR_LEN,F ;Decrement the UART receiver queue size
movlw B'11111011' ;If the pop off the queue dropped the length
btfss UR_LEN,6 ; below 64, assert CTS so the host sends us
andwf LATA,F ; data again
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf UR_SRC ;Save this byte as the loaded frame source
;fall through
;entered with BSR = 2
AwaitType
call CheckLtReceiver ;Check for and deal with receiver activity
movf UR_LEN,F ;If there's no data in the UART receiver queue,
btfsc STATUS,Z ; loop around again
bra AwaitType ; "
decf UR_LEN,F ;Decrement the UART receiver queue size
movlw B'11111011' ;If the pop off the queue dropped the length
btfss UR_LEN,6 ; below 64, assert CTS so the host sends us
andwf LATA,F ; data again
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf UR_TYPE ;Save this byte as the loaded frame type
;fall through
;entered with BSR = 2
Await4th
call CheckLtReceiver ;Check for and deal with receiver activity
movf UR_LEN,F ;If there's no data in the UART receiver queue,
btfsc STATUS,Z ; loop around again
bra Await4th ; "
decf UR_LEN,F ;Decrement the UART receiver queue size
movlw B'11111011' ;If the pop off the queue dropped the length
btfss UR_LEN,6 ; below 64, assert CTS so the host sends us
andwf LATA,F ; data again
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf UR_4TH ;Save this byte as the loaded frame 4th byte
;fall through
;entered with BSR = 2
Await5th
call CheckLtReceiver ;Check for and deal with receiver activity
movf UR_LEN,F ;If there's no data in the UART receiver queue,
btfsc STATUS,Z ; loop around again
bra Await5th ; "
decf UR_LEN,F ;Decrement the UART receiver queue size
movlw B'11111011' ;If the pop off the queue dropped the length
btfss UR_LEN,6 ; below 64, assert CTS so the host sends us
andwf LATA,F ; data again
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf UR_5TH ;Save this byte as the loaded frame 5th byte
bra WaitToSendCtrl ;Prepare to send as soon as possible
;entered with BSR = ?
TryAgain
decf ATTEMPTS,F ;Decrement the attempts counter; if it's hit
btfsc STATUS,Z ; zero, give up trying to transmit this frame
bra GiveUp ; and if necessary drain the frame payload
call SetTimer2 ;Set Timer2 using the local backoff mask
;fall through
;entered with BSR = ?
WaitToSendCtrl
bsf INTCON,GIE ;Reenable interrupts in case they were disabled
movlb 0 ;If Timer2 has been stopped, it means a frame
btfsc T2CON,TMR2ON ; came in while we were waiting; handle it and
bra WTSC1 ; defer and retry
call DealWithFrame ; "
bra Deferred ; "
WTSC1 bcf INTCON,GIE ;Disable interrupts before checking Timer2
btfss PIR1,TMR2IF ;Unless Timer2 has interrupted, loop around
bra WaitToSendCtrl ; again
movlb 2 ;If the loaded frame is a control frame, just
btfss UR_TYPE,7 ; go ahead and send it and then prepare for the
bra WTSC2 ; next frame
call SendControlFrame; "
bra PrepForNextFrame; "
WTSC2 call SendRts ;If it's a data frame, send an RTS frame first
movlb 0 ;Set Timer2 to interrupt after 200us, the
movlw 9 ; maximum interframe gap
movwf PR2 ; "
bsf T2CON,TMR2ON ;Activate Timer2
clrf TMR2 ;Reset Timer2
bcf PIR1,TMR2IF ;Clear the Timer2 interrupt flag
movlb 2 ;If frame's destination is broadcast (0xFF)
incf UR_DEST,W ; then we want to wait for 200us of silence
movlb 0 ; before sending; otherwise we want to wait for
btfsc STATUS,Z ; a CTS frame and 200us is our timeout
bra WaitForSilence ; "
bra WaitForCts ; "
;entered with BSR = ?
GiveUp
movlb 2
btfsc UR_TYPE,7 ;If loaded frame is a control frame, we already
bra PrepForNextFrame; have it in full
movf UR_4TH,W ;If loaded frame is a data frame, we need to
andlw B'00000011' ; extract the length from the 4th and 5th bytes
movwf LT_LENH ; and drain that many characters from the UART
movf UR_5TH,W ; receiver queue (even if it doesn't already
movwf LT_LENL ; contain all of them)
GiveUp1 movlw -1 ;Decrement the length counter; if it was
addwf LT_LENL,F ; already zero, we're done
addwfc LT_LENH,F ; "
btfss STATUS,C ; "
bra PrepForNextFrame; "
GiveUp2 call CheckLtReceiver ;Check for and deal with receiver activity
movf UR_LEN,F ;If there's no data in the UART receiver queue,
btfsc STATUS,Z ; loop around again
bra GiveUp2 ; "
decf UR_LEN,F ;Decrement the UART receiver queue size
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movlw B'11111011' ;If the pop off the queue dropped the length
btfss UR_LEN,6 ; below 64, assert CTS so the host sends us
andwf LATA,F ; data again
bra GiveUp1 ;Go back to decrement counter again
;entered with BSR = 2
Deferred
bsf DEF_HIST,0 ;We had to defer, so note that in deferral log
bsf LBACKOFF,0 ;Expand local backoff mask if it's zero
bra TryAgain ;And retry
;entered with BSR = ?
Collided
bsf COL_HIST,0 ;We collided, so note that in collision log
lslf LBACKOFF,F ;Expand local backoff mask by one bit, up to a
bsf LBACKOFF,0 ; maximum of 0b1111
bcf LBACKOFF,4 ; "
bra TryAgain ;And retry
;entered with BSR = 0
WaitForSilence
bsf INTCON,GIE ;Reenable interrupts in case they were disabled
btfsc T2CON,TMR2ON ;If Timer2 has been stopped, it means a frame
bra WFS1 ; came in while we were waiting; handle it and
call DealWithFrame ; consider this a collision and retry
bra Collided ; "
WFS1 bcf INTCON,GIE ;Disable interrupts before checking Timer2
btfss PIR1,TMR2IF ;Unless Timer2 has interrupted, loop around
bra WaitForSilence ; again
call SendDataFrame ;If Timer2 has interrupted, send our broadcast
bra PrepForNextFrame; frame and return to await next frame
;entered with BSR = 0
WaitForCts
bsf FLAGS,CTS_PLS ;Raise the flag that we want a CTS frame
btfsc T2CON,TMR2ON ;If Timer2 has been stopped, it means a frame
bra WFC1 ; came in while we were waiting; handle it
call DealWithFrame ; "
btfss FLAGS,CTS_PLS ;If the flag has been cleared, data's been sent
bra PrepForNextFrame; and we can return to await a new frame;
bcf FLAGS,CTS_PLS ; otherwise consider it a collision and retry
bra Collided ; "
WFC1 btfss PIR1,TMR2IF ;Unless Timer2 has interrupted, loop around
bra WaitForCts ; again
bcf FLAGS,CTS_PLS ;Our RTS must have collided, send it again
bra Collided ; "
;;; LocalTalk Transmitter Subprograms ;;;
SetTimer2
movlb 0 ;XORing together the bytes of Timer1 is a cheap
movf TMR1L,W ; but reasonable way to get a 'random' number;
xorwf TMR1H,W ; AND it with the local backoff mask to get our
andwf LBACKOFF,W ; backoff value in multiples of 100us
addlw 4 ;Add 400us to this for minimum interdialog gap
movwf PR2 ;Multiply the value in WREG by 5, because
lslf WREG,W ; Timer2 will interrupt after 20us times the
lslf WREG,W ; value in PR2
addwf PR2,F ; "
decf PR2,F ; "
bsf T2CON,TMR2ON ;Activate Timer2
clrf TMR2 ;Reset Timer2
bcf PIR1,TMR2IF ;Clear the Timer2 interrupt flag
return
CheckLtReceiver
btfsc FLAGS,LR_FRM ;If there's been a change in incoming frame
call DealWithFrame ; regs, deal with the frame
movlb 0 ;If Timer2 has been stopped, it means there was
btfss T2CON,TMR2ON ; activity on LocalTalk bus and we need to
call SetTimer2 ; reset and restart Timer2
movlb 2 ;Callers will have had BSR set to 2
return
DealWithFrame
movlb 2
btfss FLAGS,LR_FRM ;If the incoming frame regs haven't changed,
return ; we have nothing to do here
bcf FLAGS,LR_FRM ;This is so we know if regs changed under us
btfss FLAGS,LR_CROK ;If the frame's CRC check failed, the frame is
return ; invalid, ignore it
btfss LR_TYPE,7 ;If the frame is not a control frame, there's
return ; nothing to do; host handles data frames
movf FSR1L,W ;Using the node ID bitmap, check whether this
movwf FSR1L_TM ; packet's destination is one we represent,
movf LR_DEST,W ; and if it's not, we don't respond to it
movwf FSR1L ; "
movlw B'00000001' ; "
btfsc FSR1L,1 ; "
movlw B'00000100' ; "
btfsc FSR1L,0 ; "
lslf WREG,W ; "
btfsc FSR1L,2 ; "
swapf WREG,W ; "
lsrf FSR1L,F ; "
lsrf FSR1L,F ; "
lsrf FSR1L,F ; "
bsf FSR1L,7 ; "
andwf INDF1,W ; "
movwf INDF1_TM ; "
movf FSR1L_TM,W ; "
movwf FSR1L ; "
movf INDF1_TM,F ; "
btfsc STATUS,Z ; "
return ; "
bcf INTCON,GIE ;Disable interrupts so frame vars don't change
btfsc FLAGS,LR_FRM ;If this flag is set, regs changed under us so
bra DealWiR ; we can't act, reenable interrupts and return
movf LR_TYPE,W ;If the frame type is 0x81 (ENQ), jump into
addlw -0x81 ; sending an ACK frame and return from there
btfsc STATUS,Z ; "
bra SendAck ; "
addlw -3 ;If the frame type is 0x84 (RTS), jump into
btfsc STATUS,Z ; sending a CTS frame and return from there
bra SendCts ; "
addlw -1 ;If the frame type is anything but 0x85 (CTS),
btfss STATUS,Z ; reenable interrupts and return, the frame is
bra DealWiR ; not something we know how to act on
btfss FLAGS,CTS_PLS ;If we weren't expecting a CTS, reenable
bra DealWiR ; interrupts and return
movf LR_SRC,W ;If the source of the incoming frame doesn't
xorwf UR_DEST,W ; match the destination of the loaded outgoing
btfss STATUS,Z ; frame, this frame is not for the sender,
bra DealWiR ; so reenable interrupts and return
movf LR_DEST,W ;If the destination of the incoming frame
xorwf UR_SRC,W ; doesn't match the source of the loaded
btfss STATUS,Z ; outgoing frame, this frame is not for the
bra DealWiR ; sender, so reenable interrupts and return
bcf FLAGS,CTS_PLS ;Clear the flag so caller knows we sent frame
bra SendDataFrame ;Jump into sending frame and return from there
DealWiR bsf INTCON,GIE ;Reenable interrupts
return
SendControlFrame
movlb 2
bcf INTCON,GIE ;Disable interrupts
call SendSyncPreamble;XX-25 Sync pulse because frame starts a dialog
movf UR_DEST,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
movf UR_SRC,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
movf UR_TYPE,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
movf UR_4TH,W ;26
btfsc FEATURES,CALCCRC;27
comf LT_CRC1,W ;28
movwf LT_BUF ;29
comf LT_CRC2,W ;30
movwf LT_BUF2 ;31
call SendByte ;32-25
movf UR_5TH,W ;26
btfsc FEATURES,CALCCRC;27
movf LT_BUF2,W ;28
movwf LT_BUF ;29
DNOP ;30-31
call SendByte ;32-25
DNOP ;26-27
DNOP ;28-29
DNOP ;30-31
call SendPostamble ;32-XX
movlb 7 ;Clear the inevitable IOC interrupt that came
bcf IOCAF,IOCAF5 ; in while (and because) we were transmitting
movlb 2 ; before reenabling interrupts
bsf INTCON,GIE ;Reenable interrupts
return
SendDataFrame
movlb 2
bcf INTCON,GIE ;Disable interrupts
call SendPreamble ;XX-25
movf UR_DEST,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
movf UR_SRC,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
movf UR_TYPE,W ;26
movwf LT_BUF ;27
nop ;28
bsf FLAGS,TMPFLAG ;29 If frame length is 2, we need to overwrite
btfss FEATURES,CALCCRC;30 the CRC bytes with our calculated CRC; if
bcf FLAGS,TMPFLAG ;31 the feature is off, never do this
call SendByte ;32-25
movf UR_4TH,W ;26
movwf LT_BUF ;27
andlw B'00000011' ;28
movwf LT_LENH ;29
btfss STATUS,Z ;30 If high byte of length is not zero, length
bcf FLAGS,TMPFLAG ;31 of frame is not 2
call SendByte ;32-25
movf UR_5TH,W ;26
movwf LT_BUF ;27
movwf LT_LENL ;28
xorlw 2 ;29 If low byte of length is not 2, length of
btfss STATUS,Z ;30 frame is not 2
bcf FLAGS,TMPFLAG ;31 "
call SendByte ;32-25
comf LT_CRC1,W ;26 If length of frame is 2, overstrike the
btfsc FLAGS,TMPFLAG ;27 first byte to send with the first byte of
movwf INDF1 ;28 the CRC and store the second for later
comf LT_CRC2,W ;29 use; this takes care of the fact that we
btfsc FLAGS,TMPFLAG ;30 won't have time to do it later
movwf LT_BUF2 ;31 "
call SendFromQueue ;32-25 (Branches into SendPostamble)
movlb 7 ;Clear the inevitable IOC interrupt that came
bcf IOCAF,IOCAF5 ; in while (and because) we were transmitting
movlb 2 ; before reenabling interrupts
bsf INTCON,GIE ;Reenable interrupts
return
SendRts
movlb 2
bcf INTCON,GIE ;Disable interrupts
call SendSyncPreamble;XX-25 Sync pulse because frame starts a dialog
movf UR_DEST,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
movf UR_SRC,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
movlw 0x84 ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
comf LT_CRC1,W ;26
movwf LT_BUF ;27
comf LT_CRC2,W ;28
movwf LT_BUF2 ;29
DNOP ;30-31
call SendByte ;32-25
movf LT_BUF2,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
DNOP ;26-27
DNOP ;28-29
DNOP ;30-31
call SendPostamble ;32-XX
movlb 7 ;Clear the inevitable IOC interrupt that came
bcf IOCAF,IOCAF5 ; in while (and because) we were transmitting
movlb 2 ; before reenabling interrupts
bsf INTCON,GIE ;Reenable interrupts
return
SendAck
movlb 2
bcf INTCON,GIE ;Disable interrupts
call SendPreamble ;XX-25
movf LR_DEST,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
movf LR_DEST,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
movlw 0x82 ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
comf LT_CRC1,W ;26
movwf LT_BUF ;27
comf LT_CRC2,W ;28
movwf LT_BUF2 ;29
DNOP ;30-31
call SendByte ;32-25
movf LT_BUF2,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
DNOP ;26-27
DNOP ;28-29
DNOP ;30-31
call SendPostamble ;32-XX
movlb 7 ;Clear the inevitable IOC interrupt that came
bcf IOCAF,IOCAF5 ; in while (and because) we were transmitting
movlb 2 ; before reenabling interrupts
bsf INTCON,GIE ;Reenable interrupts
return
SendCts
movlb 2
bcf INTCON,GIE ;Disable interrupts
call SendPreamble ;XX-25
movf LR_SRC,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
movf LR_DEST,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
movlw 0x85 ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
comf LT_CRC1,W ;26
movwf LT_BUF ;27
comf LT_CRC2,W ;28
movwf LT_BUF2 ;29
DNOP ;30-31
call SendByte ;32-25
movf LT_BUF2,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
call SendByte ;32-25
DNOP ;26-27
DNOP ;28-29
DNOP ;30-31
call SendPostamble ;32-XX
movlb 7 ;Clear the inevitable IOC interrupt that came
bcf IOCAF,IOCAF5 ; in while (and because) we were transmitting
movlb 2 ; before reenabling interrupts
bsf INTCON,GIE ;Reenable interrupts
return
;All subs below assume that they're being called with BSR in bank 2
SendSyncPreamble
bcf LATA,5 ;32 Make sure LT pin is ready to output a 0
movlw B'00001010' ;33 Get ready to drive LT pin
bsf LATA,4 ;34 Switch transceiver to drive mode
tris 5 ;00 Drive a 0 on LT pin
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
DELAY 7 ;15-00
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00101010' ;15 Get ready to tristate LT pin
tris 5 ;16 Tristate LT pin
bcf LATA,4 ;17 Switch transceiver to receive mode
DELAY 6 ;18-00
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
DELAY 7 ;15-00
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
DELAY 7 ;15-00
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
DELAY 7 ;15-00
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
DELAY 4 ;15-26
nop ;27
;fall through
SendPreamble
movlw B'01111110' ;28 Load flag byte into the buffer for later
movwf LT_BUF ;29 "
movlw 4 ;30 Set the counter to send four pre-flag ones
movwf LT_ONES ;31 "
bcf LATA,5 ;32 Make sure LT pin is ready to output a 0
movlw B'00001010' ;33 Get ready to drive LT pin
bsf LATA,4 ;34 Switch transceiver to drive mode
tris 5 ;00 Drive a 0 on LT pin
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
bra SendPr1 ;15-16 Join the pre-flag ones loop in progress
SendPr2 DNOP ;33-34
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
clrf LT_CRC1 ;15 Reset the running CRC registers to all
decf LT_CRC1,F ;16 ones; we're going to end up doing this
SendPr1 clrf LT_CRC2 ;17 repeatedly, but it doesn't matter
decf LT_CRC2,F ;18 "
DELAY 3 ;19-27
nop ;28
movlw B'00100000' ;29 Load pattern for inverting LocalTalk pin
decfsz LT_ONES,F ;30 Decrement pre-ones counter and loop if it
bra SendPr2 ;31(-32) is not yet zero
movlw 24 ;32 Rotate buffer 24 times and we'll send three
movwf LT_ONES ;33 flag bytes
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
SendPr3 xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss LT_BUF,0 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lsrf LT_BUF,F ;18 Rotate the buffer
btfsc STATUS,C ;19 "
bsf LT_BUF,7 ;20 "
decfsz LT_ONES,F ;21 Decrement the loop counter; if it's not 0
bra SendPr4 ;22(-23) yet, skip the next two lines
incf LT_ONES,F ;23 Reset ones counter to be ready for SendByte
return ;24-25
SendPr4 DELAY 2 ;24-29
DNOP ;30-31
movlw B'00100000' ;32 Load pattern for inverting LocalTalk pin
bra SendPr3 ;33-34
SendByte
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss LT_BUF,0 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss LT_BUF,0 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
movf LT_BUF,W ;24 Update LT_CRC1 with the byte being sent;
xorwf LT_CRC1,W ;25 note that we don't movlp back to 0 because
movwf LT_CRCX ;26 we don't have time; this only works
movlp high CrcLut1 ;27 because CrcLut1 is below the page boundary
callw ;28-31 "
xorwf LT_CRC2,W ;32 "
movwf LT_CRC1 ;33 "
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss LT_BUF,1 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss LT_BUF,1 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
movf LT_CRCX,W ;24 Update LT_CRC2 with the byte being sent
movlp high CrcLut2 ;25 "
callw ;26-29 "
movlp 0 ;30 "
movwf LT_CRC2 ;31 "
DNOP ;32-33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss LT_BUF,2 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss LT_BUF,2 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
DELAY 3 ;24-32
nop ;33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss LT_BUF,3 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss LT_BUF,3 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
DELAY 3 ;24-32
nop ;33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss LT_BUF,4 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss LT_BUF,4 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
DELAY 3 ;24-32
nop ;33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss LT_BUF,5 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss LT_BUF,5 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
DELAY 3 ;24-32
nop ;33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss LT_BUF,6 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss LT_BUF,6 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
DELAY 3 ;24-32
nop ;33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss LT_BUF,7 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss LT_BUF,7 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
return ;24-25
SendFromQueue
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss INDF1,0 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss INDF1,0 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
movlw -1 ;24 Decrement the send length by one to start
addwf LT_LENL,F ;25 with because this decrement method only
addwfc LT_LENH,F ;26 signals if the register is already zero
DELAY 2 ;27-32
nop ;33
SendFrL movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss INDF1,1 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss INDF1,1 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
movf INDF1,W ;24 Update LT_CRC1 with the byte being sent;
xorwf LT_CRC1,W ;25 note that we don't movlp back to 0 because
movwf LT_CRCX ;26 we don't have time; this only works
movlp high CrcLut1 ;27 because CrcLut1 is below the page boundary
callw ;28-31 "
xorwf LT_CRC2,W ;32 "
movwf LT_CRC1 ;33 "
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss INDF1,2 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss INDF1,2 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
movf LT_CRCX,W ;24 Update LT_CRC2 with the byte being sent
movlp high CrcLut2 ;25 "
callw ;26-29 "
movlp 0 ;30 "
movwf LT_CRC2 ;31 "
DNOP ;32-33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss INDF1,3 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss INDF1,3 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
bsf FLAGS,TMPFLAG ;24 If frame length is 2, we need to overwrite
btfss FEATURES,CALCCRC;25 the CRC bytes with our calculated CRC; if
bcf FLAGS,TMPFLAG ;26 the feature is off, never do this
movf LT_LENH,W ;27 If the upper byte of the remaining byte
btfss STATUS,Z ;28 counter is not zero, remaining byte
bcf FLAGS,TMPFLAG ;29 counter is not 2
movf LT_LENL,W ;30 If the lower byte of the remaining byte
xorlw 2 ;31 counter is not 2, remaining byte counter
btfss STATUS,Z ;32 is not 2; we will use this flag later
bcf FLAGS,TMPFLAG ;33 "
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss INDF1,4 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss INDF1,4 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
moviw FSR1++ ;24 Advance the receiver queue pop pointer
bcf FSR1L,7 ;25 "
comf LT_CRC1,W ;26 If the remaining byte counter is at 2, set
btfsc FLAGS,TMPFLAG ;27 the next byte to be sent to the first byte
movwf INDF1 ;28 of the CRC and store the second byte of
comf LT_CRC2,W ;29 the CRC to be sent later (when the
btfsc FLAGS,TMPFLAG ;30 remaining byte counter is at 1)
movwf LT_BUF2 ;31 "
decf FSR1L,F ;32 Regress the receiver queue pop pointer
bcf FSR1L,7 ;33 "
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss INDF1,5 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss INDF1,5 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
bsf FLAGS,TMPFLAG ;24 If frame length is 2, we need to overwrite
btfss FEATURES,CALCCRC;25 the CRC bytes with our calculated CRC; if
bcf FLAGS,TMPFLAG ;26 the feature is off, never do this
movf LT_LENH,W ;27 If the upper byte of the remaining byte
btfss STATUS,Z ;28 counter is not zero, remaining byte
bcf FLAGS,TMPFLAG ;29 counter is not 1
movf LT_LENL,W ;30 If the lower byte of the remaining byte
xorlw 1 ;31 counter is not 1, remaining byte counter
btfss STATUS,Z ;32 is not 1; we will use this flag later
bcf FLAGS,TMPFLAG ;33 "
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss INDF1,6 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss INDF1,6 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
moviw FSR1++ ;24 Advance the receiver queue pop pointer
bcf FSR1L,7 ;25 "
movf LT_BUF2,W ;26 If the remaining byte counter is at 1, set
btfsc FLAGS,TMPFLAG ;27 the next byte to be sent to the second
movwf INDF1 ;28 byte of the CRC that we saved earlier
decf FSR1L,F ;29 Regress the receiver queue pop pointer
bcf FSR1L,7 ;30 "
DNOP ;31-32
nop ;33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss INDF1,7 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss INDF1,7 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
moviw FSR1++ ;24 Advance the receiver queue pop pointer
bcf FSR1L,7 ;25 "
decf UR_LEN,F ;26 Decrement the receiver queue length
nop ;27
movlw -1 ;28 Decrement the send length; if it was
addwf LT_LENL,F ;29 already zero, this was our last byte and
addwfc LT_LENH,F ;30 carry will not be set
btfss STATUS,C ;31 If this was our last byte, jump into
bra SendPostamble ;32(-33) sending the postamble
nop ;33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss INDF1,0 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lslf LT_ONES,F ;18 Increment the consecutive ones counter if
btfss INDF1,0 ;19 this bit is a one, otherwise reset it
clrf LT_ONES ;20 "
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
movlw B'11111011' ;24 If the pop off the queue dropped the length
btfss UR_LEN,6 ;25 below 64, assert CTS so the host sends us
andwf LATA,F ;26 data again
DNOP ;27-28
DNOP ;29-30
nop ;31
bra SendFrL ;32-33
SendPostamble
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
nop ;15
movlw B'00100000' ;16 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;17 Invert LocalTalk pin to signal a zero
movlw B'10111111' ;18 Load the rest of the flag byte into buffer
movwf LT_BUF ;19 "
movlw 20 ;20 Shift this buffer 20 times (shifting in
movwf LT_ONES ;21 ones) and we'll send a flag and 13 ones
DELAY 3 ;22-30
nop ;31
SendPoL DNOP ;32-33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
movlw B'00100000' ;15 Load pattern for inverting LocalTalk pin
btfss LT_BUF,0 ;16 Unless this bit is a one...
xorwf LATA,F ;17 ...Invert LocalTalk pin to signal a zero
lsrf LT_BUF,F ;18 Rotate a 1 into the buffer
bsf LT_BUF,7 ;19 "
DELAY 3 ;20-28
decfsz LT_ONES,F ;29 Decrement the loop counter; if it's not 0
bra SendPoL ;30(-31) yet, loop to send the next bit
btfsc LATA,5 ;31 If the bus is currently driven to 1, we
bra SendPoZ ;32(-33) need to drive it to 0 before ending
movlw B'00101010' ;33 Get ready to tristate LT pin
tris 5 ;34 Tristate LT pin
bcf LATA,4 ;00 Switch transceiver to receive mode
return ;End transmission
SendPoZ nop ;34
bcf LATA,5 ;00 Drive bus to 0
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
DELAY 6 ;15-32
movlw B'00101010' ;33 Get ready to tristate LT pin
tris 5 ;34 Tristate LT pin
bcf LATA,4 ;00 Switch transceiver to receive mode
return ;End transmission
SendByteStuff
DELAY 3 ;25-33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
nop ;15
movlw B'00100000' ;16 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;17 Invert LocalTalk pin for our stuffed zero
clrf LT_ONES ;18 Reset the ones counter
bsf LT_ONES,0 ;19 "
nop ;20
nop ;21
return ;22-23
SendDoUartSvc
movlb 0 ;03 Check if there is a byte waiting from the
btfss PIR1,RCIF ;04 UART; if there isn't, check if we need to
bra SendDoUartCts ;05(-06) set CTS instead
movlb 3 ;06 Get the received byte
movf RCREG,W ;07 "
movlb 2 ;08 "
movwi FSR0++ ;09 Push it onto the queue
bcf FSR0L,7 ;10 Wrap the queue around
incf UR_LEN,F ;11 Increment the queue length
nop ;12
return ;13-14
SendDoUartCts
movlb 2 ;07 If the UART receiver queue length >= 64,
movlw B'00000100' ;08 deassert CTS so the host stops sending us
btfsc UR_LEN,6 ;09 data
iorwf LATA,F ;10 "
DNOP ;11-12
return ;13-14
;;; CRC Lookup Tables ;;;
org 0x600
CrcLut1
dt 0x00,0x89,0x12,0x9B,0x24,0xAD,0x36,0xBF
dt 0x48,0xC1,0x5A,0xD3,0x6C,0xE5,0x7E,0xF7
dt 0x81,0x08,0x93,0x1A,0xA5,0x2C,0xB7,0x3E
dt 0xC9,0x40,0xDB,0x52,0xED,0x64,0xFF,0x76
dt 0x02,0x8B,0x10,0x99,0x26,0xAF,0x34,0xBD
dt 0x4A,0xC3,0x58,0xD1,0x6E,0xE7,0x7C,0xF5
dt 0x83,0x0A,0x91,0x18,0xA7,0x2E,0xB5,0x3C
dt 0xCB,0x42,0xD9,0x50,0xEF,0x66,0xFD,0x74
dt 0x04,0x8D,0x16,0x9F,0x20,0xA9,0x32,0xBB
dt 0x4C,0xC5,0x5E,0xD7,0x68,0xE1,0x7A,0xF3
dt 0x85,0x0C,0x97,0x1E,0xA1,0x28,0xB3,0x3A
dt 0xCD,0x44,0xDF,0x56,0xE9,0x60,0xFB,0x72
dt 0x06,0x8F,0x14,0x9D,0x22,0xAB,0x30,0xB9
dt 0x4E,0xC7,0x5C,0xD5,0x6A,0xE3,0x78,0xF1
dt 0x87,0x0E,0x95,0x1C,0xA3,0x2A,0xB1,0x38
dt 0xCF,0x46,0xDD,0x54,0xEB,0x62,0xF9,0x70
dt 0x08,0x81,0x1A,0x93,0x2C,0xA5,0x3E,0xB7
dt 0x40,0xC9,0x52,0xDB,0x64,0xED,0x76,0xFF
dt 0x89,0x00,0x9B,0x12,0xAD,0x24,0xBF,0x36
dt 0xC1,0x48,0xD3,0x5A,0xE5,0x6C,0xF7,0x7E
dt 0x0A,0x83,0x18,0x91,0x2E,0xA7,0x3C,0xB5
dt 0x42,0xCB,0x50,0xD9,0x66,0xEF,0x74,0xFD
dt 0x8B,0x02,0x99,0x10,0xAF,0x26,0xBD,0x34
dt 0xC3,0x4A,0xD1,0x58,0xE7,0x6E,0xF5,0x7C
dt 0x0C,0x85,0x1E,0x97,0x28,0xA1,0x3A,0xB3
dt 0x44,0xCD,0x56,0xDF,0x60,0xE9,0x72,0xFB
dt 0x8D,0x04,0x9F,0x16,0xA9,0x20,0xBB,0x32
dt 0xC5,0x4C,0xD7,0x5E,0xE1,0x68,0xF3,0x7A
dt 0x0E,0x87,0x1C,0x95,0x2A,0xA3,0x38,0xB1
dt 0x46,0xCF,0x54,0xDD,0x62,0xEB,0x70,0xF9
dt 0x8F,0x06,0x9D,0x14,0xAB,0x22,0xB9,0x30
dt 0xC7,0x4E,0xD5,0x5C,0xE3,0x6A,0xF1,0x78
org 0x700
CrcLut2
dt 0x00,0x11,0x23,0x32,0x46,0x57,0x65,0x74
dt 0x8C,0x9D,0xAF,0xBE,0xCA,0xDB,0xE9,0xF8
dt 0x10,0x01,0x33,0x22,0x56,0x47,0x75,0x64
dt 0x9C,0x8D,0xBF,0xAE,0xDA,0xCB,0xF9,0xE8
dt 0x21,0x30,0x02,0x13,0x67,0x76,0x44,0x55
dt 0xAD,0xBC,0x8E,0x9F,0xEB,0xFA,0xC8,0xD9
dt 0x31,0x20,0x12,0x03,0x77,0x66,0x54,0x45
dt 0xBD,0xAC,0x9E,0x8F,0xFB,0xEA,0xD8,0xC9
dt 0x42,0x53,0x61,0x70,0x04,0x15,0x27,0x36
dt 0xCE,0xDF,0xED,0xFC,0x88,0x99,0xAB,0xBA
dt 0x52,0x43,0x71,0x60,0x14,0x05,0x37,0x26
dt 0xDE,0xCF,0xFD,0xEC,0x98,0x89,0xBB,0xAA
dt 0x63,0x72,0x40,0x51,0x25,0x34,0x06,0x17
dt 0xEF,0xFE,0xCC,0xDD,0xA9,0xB8,0x8A,0x9B
dt 0x73,0x62,0x50,0x41,0x35,0x24,0x16,0x07
dt 0xFF,0xEE,0xDC,0xCD,0xB9,0xA8,0x9A,0x8B
dt 0x84,0x95,0xA7,0xB6,0xC2,0xD3,0xE1,0xF0
dt 0x08,0x19,0x2B,0x3A,0x4E,0x5F,0x6D,0x7C
dt 0x94,0x85,0xB7,0xA6,0xD2,0xC3,0xF1,0xE0
dt 0x18,0x09,0x3B,0x2A,0x5E,0x4F,0x7D,0x6C
dt 0xA5,0xB4,0x86,0x97,0xE3,0xF2,0xC0,0xD1
dt 0x29,0x38,0x0A,0x1B,0x6F,0x7E,0x4C,0x5D
dt 0xB5,0xA4,0x96,0x87,0xF3,0xE2,0xD0,0xC1
dt 0x39,0x28,0x1A,0x0B,0x7F,0x6E,0x5C,0x4D
dt 0xC6,0xD7,0xE5,0xF4,0x80,0x91,0xA3,0xB2
dt 0x4A,0x5B,0x69,0x78,0x0C,0x1D,0x2F,0x3E
dt 0xD6,0xC7,0xF5,0xE4,0x90,0x81,0xB3,0xA2
dt 0x5A,0x4B,0x79,0x68,0x1C,0x0D,0x3F,0x2E
dt 0xE7,0xF6,0xC4,0xD5,0xA1,0xB0,0x82,0x93
dt 0x6B,0x7A,0x48,0x59,0x2D,0x3C,0x0E,0x1F
dt 0xF7,0xE6,0xD4,0xC5,0xB1,0xA0,0x92,0x83
dt 0x7B,0x6A,0x58,0x49,0x3D,0x2C,0x1E,0x0F
;;; LocalTalk Receiver Code ;;;
; _________________
;|________________| |
;
;|''''|''''|''''|''''|''''|''''|''''|''''|''''|
;0 5 10 15 20 25 30 35 40 45
; \________________/
; Time period when we should be checking for a clock-inversion
org 0x800
OutNothingSkip
movlw B'00001111' ;16 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;17 deassert CTS so the host stops sending us
movwf PORTA ;18 data
movlb 7 ;19 "
bra OutCheckInv ;20-21
LtReceiver
movlb 7 ;06 Ready to detect inversion
bcf IOCAF,IOCAF5 ;07 "
clrf LR_STATE ;08 Reset receiver state
movlw 0xEB ;09 Don't need pop pointer here, so point FSR1
movwf FSR1L ;10 to LocalTalk receiver frame registers
nop ;11
;fall through
OutNothing
movlb 0 ;12 Check if there is a byte waiting from the
btfss PIR1,RCIF ;13 UART; if there isn't, skip the rest of
bra OutNothingSkip ;14(-15) this
movlb 3 ;15 Get the received byte
movf RCREG,W ;16 "
movlb 7 ;17 "
movwi FSR0++ ;18 Push it onto the queue
bcf FSR0L,7 ;19 Wrap the queue around
incf UR_LEN,F ;20 Increment the queue length
nop ;21
;fall through
OutCheckInv
bsf STATUS,C ;22 If the IOC flag was set while the preceding
btfsc IOCAF,IOCAF5 ;23 code was running, this bit is a 0; in
bcf STATUS,C ;24 either case, copy it into the carry bit
bcf IOCAF,IOCAF5 ;25 Clear the IOC flag so we can look for clock
btfsc IOCAF,IOCAF5 ;26 Check if the line has inverted, indicating
bra OutReceive ;27 a clock
btfsc IOCAF,IOCAF5 ;28 "
bra OutReceive ;29 "
btfsc IOCAF,IOCAF5 ;30 "
bra OutReceive ;31 "
btfsc IOCAF,IOCAF5 ;32 "
bra OutReceive ;33 "
btfsc IOCAF,IOCAF5 ;34 "
bra OutReceive ;35 "
btfsc IOCAF,IOCAF5 ;36 "
bra OutReceive ;37 "
btfsc IOCAF,IOCAF5 ;38 "
bra OutReceive ;39 "
btfsc IOCAF,IOCAF5 ;40 "
bra OutReceive ;41 "
btfsc IOCAF,IOCAF5 ;42 "
bra OutReceive ;43 "
bra OutLostClock ;By this point, we must assume we've lost clock
EmpNothingSkip
movlw B'00001111' ;16 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;17 deassert CTS so the host stops sending us
movwf PORTA ;18 data
movlb 7 ;19 "
bra EmpCheckInv ;20-21
OutFlag
EmpFlag
EmpNothing
movlb 0 ;12 Check if there is a byte waiting from the
btfss PIR1,RCIF ;13 UART; if there isn't, skip the rest of
bra EmpNothingSkip ;14(-15) this
movlb 3 ;15 Get the received byte
movf RCREG,W ;16 "
movlb 7 ;17 "
movwi FSR0++ ;18 Push it onto the queue
bcf FSR0L,7 ;19 Wrap the queue around
incf UR_LEN,F ;20 Increment the queue length
nop ;21
;fall through
EmpCheckInv
bsf STATUS,C ;22 If the IOC flag was set while the preceding
btfsc IOCAF,IOCAF5 ;23 code was running, this bit is a 0; in
bcf STATUS,C ;24 either case, copy it into the carry bit
bcf IOCAF,IOCAF5 ;25 Clear the IOC flag so we can look for clock
btfsc IOCAF,IOCAF5 ;26 Check if the line has inverted, indicating
bra EmpReceive ;27 a clock
btfsc IOCAF,IOCAF5 ;28 "
bra EmpReceive ;29 "
btfsc IOCAF,IOCAF5 ;30 "
bra EmpReceive ;31 "
btfsc IOCAF,IOCAF5 ;32 "
bra EmpReceive ;33 "
btfsc IOCAF,IOCAF5 ;34 "
bra EmpReceive ;35 "
btfsc IOCAF,IOCAF5 ;36 "
bra EmpReceive ;37 "
btfsc IOCAF,IOCAF5 ;38 "
bra EmpReceive ;39 "
btfsc IOCAF,IOCAF5 ;40 "
bra EmpReceive ;41 "
btfsc IOCAF,IOCAF5 ;42 "
bra EmpReceive ;43 "
bra EmpLostClock ;By this point, we must assume we've lost clock
InNothingSkip
movlw B'00001111' ;16 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;17 deassert CTS so the host stops sending us
movwf PORTA ;18 data
movlb 7 ;19 "
bra InCheckInv ;20-21
InNothing
movlb 0 ;12 Check if there is a byte waiting from the
btfss PIR1,RCIF ;13 UART; if there isn't, skip the rest of
bra InNothingSkip ;14(-15) this
movlb 3 ;15 Get the received byte
movf RCREG,W ;16 "
movlb 7 ;17 "
movwi FSR0++ ;18 Push it onto the queue
bcf FSR0L,7 ;19 Wrap the queue around
incf UR_LEN,F ;20 Increment the queue length
nop ;21
;fall through
InCheckInv
bsf STATUS,C ;22 If the IOC flag was set while the preceding
btfsc IOCAF,IOCAF5 ;23 code was running, this bit is a 0; in
bcf STATUS,C ;24 either case, copy it into the carry bit
bcf IOCAF,IOCAF5 ;25 Clear the IOC flag so we can look for clock
btfsc IOCAF,IOCAF5 ;26 Check if the line has inverted, indicating
bra InReceive ;27 a clock
btfsc IOCAF,IOCAF5 ;28 "
bra InReceive ;29 "
btfsc IOCAF,IOCAF5 ;30 "
bra InReceive ;31 "
btfsc IOCAF,IOCAF5 ;32 "
bra InReceive ;33 "
btfsc IOCAF,IOCAF5 ;34 "
bra InReceive ;35 "
btfsc IOCAF,IOCAF5 ;36 "
bra InReceive ;37 "
btfsc IOCAF,IOCAF5 ;38 "
bra InReceive ;39 "
btfsc IOCAF,IOCAF5 ;40 "
bra InReceive ;41 "
btfsc IOCAF,IOCAF5 ;42 "
bra InReceive ;43 "
bra InLostClock ;By this point, we must assume we've lost clock
InSecond
movf LR_BUF2,W ;12 Update the CRC with the last byte received
xorwf LR_CCRC1,W ;13 "
movlp high CrcLut1 ;14 "
callw ;15-18 "
movwf D0 ;19 "
bra InCheckInv ;20-21
InFourth
movf LR_BUF2,W ;12 Update the CRC with the last byte received
movwi FSR1++ ;13 "
xorwf LR_CCRC1,W ;14 "
movwf D1 ;15 "
movf D0,W ;16 "
xorwf LR_CCRC2,W ;17 "
movwf LR_CCRC1 ;18 "
nop ;19
bra InCheckInv ;20-21
InSixth
movf D1,W ;12 Update the CRC with the last byte received
movlp high CrcLut2 ;13 "
callw ;14-17 "
movwf LR_CCRC2 ;18 "
nop ;19
bra InCheckInv ;20-21
OutReceive
bcf IOCAF,IOCAF5 ;00 Ready to detect inversion
movlp high OutFSA ;01 Point PCLATH to the out-of-frame FSA for 0
btfsc STATUS,C ;02 Increment to the FSA for 1 if we got a 1
incf PCLATH,F ;03 "
movf LR_STATE,W ;04 Jump to the state pointed to by STATE
movwf PCL ;05-06 "
EmpReceive
bcf IOCAF,IOCAF5 ;00 Ready to detect inversion
movlp high EmpFSA ;01 Point PCLATH to the empty-frame FSA for 0
btfsc STATUS,C ;02 Increment to the FSA for 1 if we got a 1
incf PCLATH,F ;03 "
movf LR_STATE,W ;04 Jump to the state pointed to by STATE
movwf PCL ;05-06 "
InReceive
bcf IOCAF,IOCAF5 ;00 Ready to detect inversion
movlp high InFSA ;01 Point PCLATH to the in-frame FSA for 0
btfsc STATUS,C ;02 Increment to the FSA for 1 if we got a 1
incf PCLATH,F ;03 "
movf LR_STATE,W ;04 Jump to the state pointed to by STATE
movwf PCL ;05-06 "
InFlag
bsf FLAGS,LR_CROK ;12 If the whole frame and a correct CRC have
movf LR_CCRC1,W ;13 been fed through the CRC calculator, the
xorlw 0xB8 ;14 registers should be 0xB8 and 0xF0; set
btfss STATUS,Z ;15 flag if this is the case and clear it
bcf FLAGS,LR_CROK ;16 otherwise
movf LR_CCRC2,W ;17 "
xorlw 0xF0 ;18 "
btfss STATUS,Z ;19 "
bcf FLAGS,LR_CROK ;20 "
movlw 0xFC ;21 Compute the correct status to send - if the
btfss FLAGS,LR_CROK ;22 CRC is wrong and CRC checking is enabled,
btfss FEATURES,CHKCRC ;23 this should be 0xFC (frame check failed),
movlw 0xFD ;24 otherwise it should be 0xFD (frame done)
movlb 3 ;25 Transmit a zero, which is an escape
clrf TXREG ;26 character
movwf TXREG ;27 Send the byte computed above
movlb 7 ;28 "
bsf FLAGS,LR_FRM ;29 Raise the flag that frame regs have changed
InFlag2 bcf IOCAF,IOCAF5 ;Ready to detect inversion
movlb 0 ;00 Check if there is a byte waiting from the
bcf STATUS,C ;01 UART
btfsc PIR1,RCIF ;02 "
bsf STATUS,C ;03 "
movlb 3 ;04 If there is a byte waiting from the UART,
btfsc STATUS,C ;05 push it onto the queue
movf RCREG,W ;06 "
movlb 0 ;07 "
btfsc STATUS,C ;08 "
movwi FSR0++ ;09 "
bcf FSR0L,7 ;10 Wrap the queue around
btfsc STATUS,C ;11 If there was a byte waiting from the UART,
incf UR_LEN,F ;12 increment the queue length
movlw B'00001111' ;13 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;14 deassert CTS so the host stops sending us
movwf PORTA ;15 data
bcf STATUS,C ;16 Check if there is a byte waiting from the
btfsc PIR1,RCIF ;17 UART
bsf STATUS,C ;18 "
movlb 3 ;19 If there is a byte waiting from the UART,
btfsc STATUS,C ;20 push it onto the queue
movf RCREG,W ;21 "
movlb 0 ;22 "
btfsc STATUS,C ;23 "
movwi FSR0++ ;24 "
bcf FSR0L,7 ;25 Wrap the queue around
btfsc STATUS,C ;26 If there was a byte waiting from the UART,
incf UR_LEN,F ;27 increment the queue length
movlw B'00001111' ;28 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;29 deassert CTS so the host stops sending us
movwf PORTA ;30 data
bcf STATUS,C ;31 Check if there is a byte waiting from the
btfsc PIR1,RCIF ;32 UART
bsf STATUS,C ;33 "
movlb 3 ;34 If there is a byte waiting from the UART,
btfsc STATUS,C ;35 push it onto the queue
movf RCREG,W ;36 "
movlb 0 ;37 "
btfsc STATUS,C ;38 "
movwi FSR0++ ;39 "
bcf FSR0L,7 ;40 Wrap the queue around
btfsc STATUS,C ;41 If there was a byte waiting from the UART,
incf UR_LEN,F ;42 increment the queue length
movlw B'00001111' ;43 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;44 deassert CTS so the host stops sending us
movwf PORTA ;45 data
movlb 7 ;If there's been an inversion in the elapsed
btfsc IOCAF,IOCAF5 ; ~1.25 bit times, the line is not yet idle and
bra InFlag2 ; we should try again
bra FinishUp ;Else, proceed to finish the receive
EmpByte
InByte
movf LR_BUF,W ;12 Save received byte into second buffer so it
movwf LR_BUF2 ;13 can be CRC'd and copied into the frame regs
btfss STATUS,Z ;14 If the received byte is not a zero, just
bra InByte2 ;15(-16) transmit it as-is
movlb 3 ;16 If the received byte is a zero, transmit
clrf TXREG ;17 escape sequence 0x00 0xFF
decf TXREG,F ;18 "
movlb 7 ;19 "
bra InCheckInv ;20-21
InByte2 movlb 3 ;17 Transmit the received byte on the UART
movwf TXREG ;18 "
movlb 7 ;19 "
bra InCheckInv ;20-21
OutFErr
EmpFErr
InFErr
bcf IOCAF,IOCAF5 ;Ready to detect inversion
movlb 0 ;00 Check if there is a byte waiting from the
bcf STATUS,C ;01 UART
btfsc PIR1,RCIF ;02 "
bsf STATUS,C ;03 "
movlb 3 ;04 If there is a byte waiting from the UART,
btfsc STATUS,C ;05 push it onto the queue
movf RCREG,W ;06 "
movlb 0 ;07 "
btfsc STATUS,C ;08 "
movwi FSR0++ ;09 "
bcf FSR0L,7 ;10 Wrap the queue around
btfsc STATUS,C ;11 If there was a byte waiting from the UART,
incf UR_LEN,F ;12 increment the queue length
movlw B'00001111' ;13 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;14 deassert CTS so the host stops sending us
movwf PORTA ;15 data
bcf STATUS,C ;16 Check if there is a byte waiting from the
btfsc PIR1,RCIF ;17 UART
bsf STATUS,C ;18 "
movlb 3 ;19 If there is a byte waiting from the UART,
btfsc STATUS,C ;20 push it onto the queue
movf RCREG,W ;21 "
movlb 0 ;22 "
btfsc STATUS,C ;23 "
movwi FSR0++ ;24 "
bcf FSR0L,7 ;25 Wrap the queue around
btfsc STATUS,C ;26 If there was a byte waiting from the UART,
incf UR_LEN,F ;27 increment the queue length
movlw B'00001111' ;28 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;29 deassert CTS so the host stops sending us
movwf PORTA ;30 data
bcf STATUS,C ;31 Check if there is a byte waiting from the
btfsc PIR1,RCIF ;32 UART
bsf STATUS,C ;33 "
movlb 3 ;34 If there is a byte waiting from the UART,
btfsc STATUS,C ;35 push it onto the queue
movf RCREG,W ;36 "
movlb 0 ;37 "
btfsc STATUS,C ;38 "
movwi FSR0++ ;39 "
bcf FSR0L,7 ;40 Wrap the queue around
btfsc STATUS,C ;41 If there was a byte waiting from the UART,
incf UR_LEN,F ;42 increment the queue length
movlw B'00001111' ;43 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;44 deassert CTS so the host stops sending us
movwf PORTA ;45 data
movlb 7 ;If there's been an inversion in the elapsed
btfsc IOCAF,IOCAF5 ; ~1.25 bit times, the line is not yet idle and
bra OutFErr ; we should try again
movlb 3 ;Transmit a zero, which is an escape character
clrf TXREG ; "
movlw 0xFE ;Transmit 0xFE, which signifies 'Frame Error'
movwf TXREG ; "
;fall through
OutLostClock
EmpLostClock
FinishUp
movlb 0 ;If the frame regs changed, deactivate Timer2
btfss FLAGS,LR_FRM ; and clear its interrupt flag so anything that
bra Finish2 ; was waiting for it knows that a frame was
bcf T2CON,TMR2ON ; received while waiting
bcf PIR1,TMR2IF ; "
Finish2 clrf LR_CCRC1 ;Clear receiver CRC registers to ones since we
decf LR_CCRC1,F ; don't have time to do this when we jump into
clrf LR_CCRC2 ; the receiver
decf LR_CCRC2,F ; "
movf FSR0L,W ;Store the changed UART receiver push point
movlb 31 ; back in its shadow register so it stays the
movwf FSR0L_SHAD ; same when we return from interrupt
retfie
InLostClock
movlb 0 ;Wait until the UART transmitter is ready for
btfss PIR1,TXIF ; a byte
bra $-1 ; "
movlb 3 ;Transmit a zero, which is an escape character
clrf TXREG ; "
movlb 0 ;Wait until the UART transmitter is ready for
btfss PIR1,TXIF ; another byte
bra $-1 ; "
movlb 3 ;Transmit 0xFA, which signifies 'Frame Aborted'
movlw 0xFA ; "
movwf TXREG ; "
bra FinishUp
;;; LocalTalk Receiver State Machines ;;;
OutFSA org 0xA00
Oswait0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c0r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c1r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c2r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c3r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c4r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c5r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c6r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c7r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c0r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c1r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c2r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c3r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c4r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c5r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c6r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c7r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c0r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c1r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c2r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c3r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c4r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c5r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c6r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c7r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c0r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c1r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c2r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c3r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c4r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c5r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c6r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c7r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c0r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c1r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c2r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c3r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c4r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c5r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c6r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c7r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os5c0r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os5c1r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os5c2r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os5c3r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os5c4r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os5c5r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os5c6r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os5c7r0 bcf LR_BUF,0 ;07
movlw low Os0c1r0 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os6c7r0 bcf LR_BUF,7 ;07
movlw low Os0c0r0 ;08
movwf LR_STATE ;09
goto OutFlag ;10-11
org 0xB00
Oswait1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c0r1 bsf LR_BUF,0 ;07
movlw low Os1c1r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c1r1 bsf LR_BUF,1 ;07
movlw low Os1c2r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c2r1 bsf LR_BUF,2 ;07
movlw low Os1c3r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c3r1 bsf LR_BUF,3 ;07
movlw low Os1c4r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c4r1 bsf LR_BUF,4 ;07
movlw low Os1c5r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c5r1 bsf LR_BUF,5 ;07
movlw low Os1c6r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c6r1 bsf LR_BUF,6 ;07
movlw low Os1c7r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os0c7r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os1c0r1 bsf LR_BUF,0 ;07
movlw low Os2c1r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c1r1 bsf LR_BUF,1 ;07
movlw low Os2c2r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c2r1 bsf LR_BUF,2 ;07
movlw low Os2c3r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c3r1 bsf LR_BUF,3 ;07
movlw low Os2c4r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c4r1 bsf LR_BUF,4 ;07
movlw low Os2c5r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c5r1 bsf LR_BUF,5 ;07
movlw low Os2c6r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c6r1 bsf LR_BUF,6 ;07
movlw low Os2c7r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os1c7r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os2c0r1 bsf LR_BUF,0 ;07
movlw low Os3c1r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c1r1 bsf LR_BUF,1 ;07
movlw low Os3c2r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c2r1 bsf LR_BUF,2 ;07
movlw low Os3c3r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c3r1 bsf LR_BUF,3 ;07
movlw low Os3c4r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c4r1 bsf LR_BUF,4 ;07
movlw low Os3c5r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c5r1 bsf LR_BUF,5 ;07
movlw low Os3c6r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c6r1 bsf LR_BUF,6 ;07
movlw low Os3c7r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os2c7r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os3c0r1 bsf LR_BUF,0 ;07
movlw low Os4c1r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c1r1 bsf LR_BUF,1 ;07
movlw low Os4c2r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c2r1 bsf LR_BUF,2 ;07
movlw low Os4c3r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c3r1 bsf LR_BUF,3 ;07
movlw low Os4c4r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c4r1 bsf LR_BUF,4 ;07
movlw low Os4c5r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c5r1 bsf LR_BUF,5 ;07
movlw low Os4c6r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c6r1 bsf LR_BUF,6 ;07
movlw low Os4c7r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os3c7r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os4c0r1 bsf LR_BUF,0 ;07
movlw low Os5c1r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c1r1 bsf LR_BUF,1 ;07
movlw low Os5c2r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c2r1 bsf LR_BUF,2 ;07
movlw low Os5c3r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c3r1 bsf LR_BUF,3 ;07
movlw low Os5c4r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c4r1 bsf LR_BUF,4 ;07
movlw low Os5c5r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c5r1 bsf LR_BUF,5 ;07
movlw low Os5c6r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c6r1 bsf LR_BUF,6 ;07
movlw low Os5c7r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os4c7r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os5c0r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os5c1r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os5c2r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os5c3r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os5c4r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os5c5r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os5c6r1 bsf LR_BUF,6 ;07
movlw low Os6c7r1 ;08
movwf LR_STATE ;09
goto OutNothing ;10-11
Os5c7r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
Os6c7r1 nop ;07
movlw low Oswait1 ;08
movwf LR_STATE ;09
goto OutFErr ;10-11
EmpFSA org 0xC00
Eswait0 bcf LR_BUF,0 ;07
movlw low Es0c1r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c0r0 bcf LR_BUF,0 ;07
movlw low Es0c1r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c1r0 bcf LR_BUF,1 ;07
movlw low Es0c2r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c2r0 bcf LR_BUF,2 ;07
movlw low Es0c3r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c3r0 bcf LR_BUF,3 ;07
movlw low Es0c4r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c4r0 bcf LR_BUF,4 ;07
movlw low Es0c5r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c5r0 bcf LR_BUF,5 ;07
movlw low Es0c6r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c6r0 bcf LR_BUF,6 ;07
movlw low Es0c7r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c7r0 bcf LR_BUF,7 ;07
movlw low Es0c0r0 ;08
movwf LR_STATE ;09
goto EmpByte ;10-11
Es1c0r0 bcf LR_BUF,0 ;07
movlw low Es0c1r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c1r0 bcf LR_BUF,1 ;07
movlw low Es0c2r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c2r0 bcf LR_BUF,2 ;07
movlw low Es0c3r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c3r0 bcf LR_BUF,3 ;07
movlw low Es0c4r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c4r0 bcf LR_BUF,4 ;07
movlw low Es0c5r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c5r0 bcf LR_BUF,5 ;07
movlw low Es0c6r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c6r0 bcf LR_BUF,6 ;07
movlw low Es0c7r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c7r0 bcf LR_BUF,7 ;07
movlw low Es0c0r0 ;08
movwf LR_STATE ;09
goto EmpByte ;10-11
Es2c0r0 bcf LR_BUF,0 ;07
movlw low Es0c1r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c1r0 bcf LR_BUF,1 ;07
movlw low Es0c2r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c2r0 bcf LR_BUF,2 ;07
movlw low Es0c3r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c3r0 bcf LR_BUF,3 ;07
movlw low Es0c4r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c4r0 bcf LR_BUF,4 ;07
movlw low Es0c5r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c5r0 bcf LR_BUF,5 ;07
movlw low Es0c6r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c6r0 bcf LR_BUF,6 ;07
movlw low Es0c7r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c7r0 bcf LR_BUF,7 ;07
movlw low Es0c0r0 ;08
movwf LR_STATE ;09
goto EmpByte ;10-11
Es3c0r0 bcf LR_BUF,0 ;07
movlw low Es0c1r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c1r0 bcf LR_BUF,1 ;07
movlw low Es0c2r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c2r0 bcf LR_BUF,2 ;07
movlw low Es0c3r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c3r0 bcf LR_BUF,3 ;07
movlw low Es0c4r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c4r0 bcf LR_BUF,4 ;07
movlw low Es0c5r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c5r0 bcf LR_BUF,5 ;07
movlw low Es0c6r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c6r0 bcf LR_BUF,6 ;07
movlw low Es0c7r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c7r0 bcf LR_BUF,7 ;07
movlw low Es0c0r0 ;08
movwf LR_STATE ;09
goto EmpByte ;10-11
Es4c0r0 bcf LR_BUF,0 ;07
movlw low Es0c1r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c1r0 bcf LR_BUF,1 ;07
movlw low Es0c2r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c2r0 bcf LR_BUF,2 ;07
movlw low Es0c3r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c3r0 bcf LR_BUF,3 ;07
movlw low Es0c4r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c4r0 bcf LR_BUF,4 ;07
movlw low Es0c5r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c5r0 bcf LR_BUF,5 ;07
movlw low Es0c6r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c6r0 bcf LR_BUF,6 ;07
movlw low Es0c7r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c7r0 bcf LR_BUF,7 ;07
movlw low Es0c0r0 ;08
movwf LR_STATE ;09
goto EmpByte ;10-11
Es5c0r0 nop ;07
movlw low Es0c0r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es5c1r0 nop ;07
movlw low Es0c1r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es5c2r0 nop ;07
movlw low Es0c2r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es5c3r0 nop ;07
movlw low Es0c3r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es5c4r0 nop ;07
movlw low Es0c4r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es5c5r0 nop ;07
movlw low Es0c5r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es5c6r0 nop ;07
movlw low Es0c6r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es5c7r0 nop ;07
movlw low Es0c7r0 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es6c7r0 bcf LR_BUF,7 ;07
movlw low Es0c0r0 ;08
movwf LR_STATE ;09
goto EmpFlag ;10-11
org 0xD00
Eswait1 nop ;07
movlw low Eswait1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c0r1 bsf LR_BUF,0 ;07
movlw low Es1c1r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c1r1 bsf LR_BUF,1 ;07
movlw low Es1c2r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c2r1 bsf LR_BUF,2 ;07
movlw low Es1c3r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c3r1 bsf LR_BUF,3 ;07
movlw low Es1c4r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c4r1 bsf LR_BUF,4 ;07
movlw low Es1c5r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c5r1 bsf LR_BUF,5 ;07
movlw low Es1c6r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c6r1 bsf LR_BUF,6 ;07
movlw low Es1c7r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es0c7r1 bsf LR_BUF,7 ;07
movlw low Es1c0r1 ;08
movwf LR_STATE ;09
goto EmpByte ;10-11
Es1c0r1 bsf LR_BUF,0 ;07
movlw low Es2c1r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c1r1 bsf LR_BUF,1 ;07
movlw low Es2c2r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c2r1 bsf LR_BUF,2 ;07
movlw low Es2c3r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c3r1 bsf LR_BUF,3 ;07
movlw low Es2c4r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c4r1 bsf LR_BUF,4 ;07
movlw low Es2c5r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c5r1 bsf LR_BUF,5 ;07
movlw low Es2c6r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c6r1 bsf LR_BUF,6 ;07
movlw low Es2c7r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es1c7r1 bsf LR_BUF,7 ;07
movlw low Es2c0r1 ;08
movwf LR_STATE ;09
goto EmpByte ;10-11
Es2c0r1 bsf LR_BUF,0 ;07
movlw low Es3c1r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c1r1 bsf LR_BUF,1 ;07
movlw low Es3c2r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c2r1 bsf LR_BUF,2 ;07
movlw low Es3c3r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c3r1 bsf LR_BUF,3 ;07
movlw low Es3c4r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c4r1 bsf LR_BUF,4 ;07
movlw low Es3c5r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c5r1 bsf LR_BUF,5 ;07
movlw low Es3c6r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c6r1 bsf LR_BUF,6 ;07
movlw low Es3c7r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es2c7r1 bsf LR_BUF,7 ;07
movlw low Es3c0r1 ;08
movwf LR_STATE ;09
goto EmpByte ;10-11
Es3c0r1 bsf LR_BUF,0 ;07
movlw low Es4c1r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c1r1 bsf LR_BUF,1 ;07
movlw low Es4c2r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c2r1 bsf LR_BUF,2 ;07
movlw low Es4c3r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c3r1 bsf LR_BUF,3 ;07
movlw low Es4c4r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c4r1 bsf LR_BUF,4 ;07
movlw low Es4c5r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c5r1 bsf LR_BUF,5 ;07
movlw low Es4c6r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c6r1 bsf LR_BUF,6 ;07
movlw low Es4c7r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es3c7r1 bsf LR_BUF,7 ;07
movlw low Es4c0r1 ;08
movwf LR_STATE ;09
goto EmpByte ;10-11
Es4c0r1 bsf LR_BUF,0 ;07
movlw low Es5c1r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c1r1 bsf LR_BUF,1 ;07
movlw low Es5c2r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c2r1 bsf LR_BUF,2 ;07
movlw low Es5c3r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c3r1 bsf LR_BUF,3 ;07
movlw low Es5c4r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c4r1 bsf LR_BUF,4 ;07
movlw low Es5c5r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c5r1 bsf LR_BUF,5 ;07
movlw low Es5c6r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c6r1 bsf LR_BUF,6 ;07
movlw low Es5c7r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es4c7r1 bsf LR_BUF,7 ;07
movlw low Es5c0r1 ;08
movwf LR_STATE ;09
goto EmpByte ;10-11
Es5c0r1 nop ;07
movlw low Eswait1 ;08
movwf LR_STATE ;09
goto EmpFErr ;10-11
Es5c1r1 nop ;07
movlw low Eswait1 ;08
movwf LR_STATE ;09
goto EmpFErr ;10-11
Es5c2r1 nop ;07
movlw low Eswait1 ;08
movwf LR_STATE ;09
goto EmpFErr ;10-11
Es5c3r1 nop ;07
movlw low Eswait1 ;08
movwf LR_STATE ;09
goto EmpFErr ;10-11
Es5c4r1 nop ;07
movlw low Eswait1 ;08
movwf LR_STATE ;09
goto EmpFErr ;10-11
Es5c5r1 nop ;07
movlw low Eswait1 ;08
movwf LR_STATE ;09
goto EmpFErr ;10-11
Es5c6r1 bsf LR_BUF,6 ;07
movlw low Es6c7r1 ;08
movwf LR_STATE ;09
goto EmpNothing ;10-11
Es5c7r1 nop ;07
movlw low Eswait1 ;08
movwf LR_STATE ;09
goto EmpFErr ;10-11
Es6c7r1 nop ;07
movlw low Eswait1 ;08
movwf LR_STATE ;09
goto EmpFErr ;10-11
InFSA org 0xE00
Iswait0 bcf LR_BUF,0 ;07
movlw low Is0c1r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is0c0r0 bcf LR_BUF,0 ;07
movlw low Is0c1r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is0c1r0 bcf LR_BUF,1 ;07
movlw low Is0c2r0 ;08
movwf LR_STATE ;09
goto InSecond ;10-11
Is0c2r0 bcf LR_BUF,2 ;07
movlw low Is0c3r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is0c3r0 bcf LR_BUF,3 ;07
movlw low Is0c4r0 ;08
movwf LR_STATE ;09
goto InFourth ;10-11
Is0c4r0 bcf LR_BUF,4 ;07
movlw low Is0c5r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is0c5r0 bcf LR_BUF,5 ;07
movlw low Is0c6r0 ;08
movwf LR_STATE ;09
goto InSixth ;10-11
Is0c6r0 bcf LR_BUF,6 ;07
movlw low Is0c7r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is0c7r0 bcf LR_BUF,7 ;07
movlw low Is0c0r0 ;08
movwf LR_STATE ;09
goto InByte ;10-11
Is1c0r0 bcf LR_BUF,0 ;07
movlw low Is0c1r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is1c1r0 bcf LR_BUF,1 ;07
movlw low Is0c2r0 ;08
movwf LR_STATE ;09
goto InSecond ;10-11
Is1c2r0 bcf LR_BUF,2 ;07
movlw low Is0c3r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is1c3r0 bcf LR_BUF,3 ;07
movlw low Is0c4r0 ;08
movwf LR_STATE ;09
goto InFourth ;10-11
Is1c4r0 bcf LR_BUF,4 ;07
movlw low Is0c5r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is1c5r0 bcf LR_BUF,5 ;07
movlw low Is0c6r0 ;08
movwf LR_STATE ;09
goto InSixth ;10-11
Is1c6r0 bcf LR_BUF,6 ;07
movlw low Is0c7r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is1c7r0 bcf LR_BUF,7 ;07
movlw low Is0c0r0 ;08
movwf LR_STATE ;09
goto InByte ;10-11
Is2c0r0 bcf LR_BUF,0 ;07
movlw low Is0c1r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is2c1r0 bcf LR_BUF,1 ;07
movlw low Is0c2r0 ;08
movwf LR_STATE ;09
goto InSecond ;10-11
Is2c2r0 bcf LR_BUF,2 ;07
movlw low Is0c3r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is2c3r0 bcf LR_BUF,3 ;07
movlw low Is0c4r0 ;08
movwf LR_STATE ;09
goto InFourth ;10-11
Is2c4r0 bcf LR_BUF,4 ;07
movlw low Is0c5r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is2c5r0 bcf LR_BUF,5 ;07
movlw low Is0c6r0 ;08
movwf LR_STATE ;09
goto InSixth ;10-11
Is2c6r0 bcf LR_BUF,6 ;07
movlw low Is0c7r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is2c7r0 bcf LR_BUF,7 ;07
movlw low Is0c0r0 ;08
movwf LR_STATE ;09
goto InByte ;10-11
Is3c0r0 bcf LR_BUF,0 ;07
movlw low Is0c1r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is3c1r0 bcf LR_BUF,1 ;07
movlw low Is0c2r0 ;08
movwf LR_STATE ;09
goto InSecond ;10-11
Is3c2r0 bcf LR_BUF,2 ;07
movlw low Is0c3r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is3c3r0 bcf LR_BUF,3 ;07
movlw low Is0c4r0 ;08
movwf LR_STATE ;09
goto InFourth ;10-11
Is3c4r0 bcf LR_BUF,4 ;07
movlw low Is0c5r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is3c5r0 bcf LR_BUF,5 ;07
movlw low Is0c6r0 ;08
movwf LR_STATE ;09
goto InSixth ;10-11
Is3c6r0 bcf LR_BUF,6 ;07
movlw low Is0c7r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is3c7r0 bcf LR_BUF,7 ;07
movlw low Is0c0r0 ;08
movwf LR_STATE ;09
goto InByte ;10-11
Is4c0r0 bcf LR_BUF,0 ;07
movlw low Is0c1r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is4c1r0 bcf LR_BUF,1 ;07
movlw low Is0c2r0 ;08
movwf LR_STATE ;09
goto InSecond ;10-11
Is4c2r0 bcf LR_BUF,2 ;07
movlw low Is0c3r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is4c3r0 bcf LR_BUF,3 ;07
movlw low Is0c4r0 ;08
movwf LR_STATE ;09
goto InFourth ;10-11
Is4c4r0 bcf LR_BUF,4 ;07
movlw low Is0c5r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is4c5r0 bcf LR_BUF,5 ;07
movlw low Is0c6r0 ;08
movwf LR_STATE ;09
goto InSixth ;10-11
Is4c6r0 bcf LR_BUF,6 ;07
movlw low Is0c7r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is4c7r0 bcf LR_BUF,7 ;07
movlw low Is0c0r0 ;08
movwf LR_STATE ;09
goto InByte ;10-11
Is5c0r0 nop ;07
movlw low Is0c0r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is5c1r0 nop ;07
movlw low Is0c1r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is5c2r0 nop ;07
movlw low Is0c2r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is5c3r0 nop ;07
movlw low Is0c3r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is5c4r0 nop ;07
movlw low Is0c4r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is5c5r0 nop ;07
movlw low Is0c5r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is5c6r0 nop ;07
movlw low Is0c6r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is5c7r0 nop ;07
movlw low Is0c7r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is6c7r0 bcf LR_BUF,7 ;07
movlw low Iswait0 ;08
movwf LR_STATE ;09
goto InFlag ;10-11
org 0xF00
Iswait1 nop ;07
movlw low Iswait1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is0c0r1 bsf LR_BUF,0 ;07
movlw low Is1c1r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is0c1r1 bsf LR_BUF,1 ;07
movlw low Is1c2r1 ;08
movwf LR_STATE ;09
goto InSecond ;10-11
Is0c2r1 bsf LR_BUF,2 ;07
movlw low Is1c3r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is0c3r1 bsf LR_BUF,3 ;07
movlw low Is1c4r1 ;08
movwf LR_STATE ;09
goto InFourth ;10-11
Is0c4r1 bsf LR_BUF,4 ;07
movlw low Is1c5r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is0c5r1 bsf LR_BUF,5 ;07
movlw low Is1c6r1 ;08
movwf LR_STATE ;09
goto InSixth ;10-11
Is0c6r1 bsf LR_BUF,6 ;07
movlw low Is1c7r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is0c7r1 bsf LR_BUF,7 ;07
movlw low Is1c0r1 ;08
movwf LR_STATE ;09
goto InByte ;10-11
Is1c0r1 bsf LR_BUF,0 ;07
movlw low Is2c1r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is1c1r1 bsf LR_BUF,1 ;07
movlw low Is2c2r1 ;08
movwf LR_STATE ;09
goto InSecond ;10-11
Is1c2r1 bsf LR_BUF,2 ;07
movlw low Is2c3r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is1c3r1 bsf LR_BUF,3 ;07
movlw low Is2c4r1 ;08
movwf LR_STATE ;09
goto InFourth ;10-11
Is1c4r1 bsf LR_BUF,4 ;07
movlw low Is2c5r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is1c5r1 bsf LR_BUF,5 ;07
movlw low Is2c6r1 ;08
movwf LR_STATE ;09
goto InSixth ;10-11
Is1c6r1 bsf LR_BUF,6 ;07
movlw low Is2c7r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is1c7r1 bsf LR_BUF,7 ;07
movlw low Is2c0r1 ;08
movwf LR_STATE ;09
goto InByte ;10-11
Is2c0r1 bsf LR_BUF,0 ;07
movlw low Is3c1r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is2c1r1 bsf LR_BUF,1 ;07
movlw low Is3c2r1 ;08
movwf LR_STATE ;09
goto InSecond ;10-11
Is2c2r1 bsf LR_BUF,2 ;07
movlw low Is3c3r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is2c3r1 bsf LR_BUF,3 ;07
movlw low Is3c4r1 ;08
movwf LR_STATE ;09
goto InFourth ;10-11
Is2c4r1 bsf LR_BUF,4 ;07
movlw low Is3c5r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is2c5r1 bsf LR_BUF,5 ;07
movlw low Is3c6r1 ;08
movwf LR_STATE ;09
goto InSixth ;10-11
Is2c6r1 bsf LR_BUF,6 ;07
movlw low Is3c7r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is2c7r1 bsf LR_BUF,7 ;07
movlw low Is3c0r1 ;08
movwf LR_STATE ;09
goto InByte ;10-11
Is3c0r1 bsf LR_BUF,0 ;07
movlw low Is4c1r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is3c1r1 bsf LR_BUF,1 ;07
movlw low Is4c2r1 ;08
movwf LR_STATE ;09
goto InSecond ;10-11
Is3c2r1 bsf LR_BUF,2 ;07
movlw low Is4c3r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is3c3r1 bsf LR_BUF,3 ;07
movlw low Is4c4r1 ;08
movwf LR_STATE ;09
goto InFourth ;10-11
Is3c4r1 bsf LR_BUF,4 ;07
movlw low Is4c5r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is3c5r1 bsf LR_BUF,5 ;07
movlw low Is4c6r1 ;08
movwf LR_STATE ;09
goto InSixth ;10-11
Is3c6r1 bsf LR_BUF,6 ;07
movlw low Is4c7r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is3c7r1 bsf LR_BUF,7 ;07
movlw low Is4c0r1 ;08
movwf LR_STATE ;09
goto InByte ;10-11
Is4c0r1 bsf LR_BUF,0 ;07
movlw low Is5c1r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is4c1r1 bsf LR_BUF,1 ;07
movlw low Is5c2r1 ;08
movwf LR_STATE ;09
goto InSecond ;10-11
Is4c2r1 bsf LR_BUF,2 ;07
movlw low Is5c3r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is4c3r1 bsf LR_BUF,3 ;07
movlw low Is5c4r1 ;08
movwf LR_STATE ;09
goto InFourth ;10-11
Is4c4r1 bsf LR_BUF,4 ;07
movlw low Is5c5r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is4c5r1 bsf LR_BUF,5 ;07
movlw low Is5c6r1 ;08
movwf LR_STATE ;09
goto InSixth ;10-11
Is4c6r1 bsf LR_BUF,6 ;07
movlw low Is5c7r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is4c7r1 bsf LR_BUF,7 ;07
movlw low Is5c0r1 ;08
movwf LR_STATE ;09
goto InByte ;10-11
Is5c0r1 nop ;07
movlw low Iswait1 ;08
movwf LR_STATE ;09
goto InFErr ;10-11
Is5c1r1 nop ;07
movlw low Iswait1 ;08
movwf LR_STATE ;09
goto InFErr ;10-11
Is5c2r1 nop ;07
movlw low Iswait1 ;08
movwf LR_STATE ;09
goto InFErr ;10-11
Is5c3r1 nop ;07
movlw low Iswait1 ;08
movwf LR_STATE ;09
goto InFErr ;10-11
Is5c4r1 nop ;07
movlw low Iswait1 ;08
movwf LR_STATE ;09
goto InFErr ;10-11
Is5c5r1 nop ;07
movlw low Iswait1 ;08
movwf LR_STATE ;09
goto InFErr ;10-11
Is5c6r1 bsf LR_BUF,6 ;07
movlw low Is6c7r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
Is5c7r1 nop ;07
movlw low Iswait1 ;08
movwf LR_STATE ;09
goto InFErr ;10-11
Is6c7r1 nop ;07
movlw low Iswait1 ;08
movwf LR_STATE ;09
goto InFErr ;10-11
;;; End of Program ;;;
end