;;; 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