  ;  *** COMPILED WITH SX/B VERSION 1.51.03  09/21/2006 ***
                                 ;' ========================================================================= 
                                 ;'
                                 ;'   File...... DhoganDecoder-1uffakind-11A.SXB
                                 ;'   Purpose... Decode 8 bit detector signal and light some leds
                                 ;'   Author.... Zoot
                                 ;'   E-mail.... craig@1uffakind.com
                                 ;'   Started... 20 jan 2012
                                 ;'   Updated... 24 jan 2012
                                 ;'   Version... 11A
                                 ;' 
                                 ;' ========================================================================= 
                                 ;'
                                 ;' -------------------------------------------------------------------------
                                 ;' Program Description 
                                 ;' ------------------------------------------------------------------------- 
                                 ;' Decodes an 8 bit pulse train on the detector pin and lights appropriate
                                 ;' leds depending on received message
                                 ;' message is a start bit followed by 8 bits:
                                 ;' start bit = ~7200us
                                 ;' one bit   = ~2400us
                                 ;' zero bit  = ~1200us
                                 ;' rest      = ~2400us ???
                                 ;' frame     = ~36200us ??? but max has to be more like 45600us which would allow for startbit + $FF

                                 ;' ------------------------------------------------------------------------- 
                                 ;' Conditional Compilation Symbols 
                                 ;' ------------------------------------------------------------------------- 

                                 ;' comment out line below for message that is MSB first
                                 ;' uncommment line below (remove just the FIRST ') for message that is LSB first 
                                 ;' to LSB first message

                                 ;''{$DEFINE MESSAGE_LSB_FIRST}


                                 ;' ------------------------------------------------------------------------- 
                                 ;' Device Settings 
                                 ;' ------------------------------------------------------------------------- 

DEVICE          SX28, OSCHS1, TURBO, STACKX, OPTIONX, BOROFF ;DEVICE          SX28, OSCHS1, TURBO, STACKX, OPTIONX, BOROFF

  ; DEFINE SYSTEM VARIABLES
__RAM         EQU  $00
RBC           EQU  $06
RBC_LSB       EQU  $06
RBC_MSB       EQU  $07
__PARAM1      EQU  $08
__PARAM2      EQU  $09
__PARAM3      EQU  $0A
__PARAM4      EQU  $0B
__PARAM5      EQU  $0C
__PARAMCNT    EQU  $0C
__WPARAM12    EQU  $08
__WPARAM12_LSB EQU  $08
__WPARAM12_MSB EQU  $09
__WPARAM23    EQU  $09
__WPARAM23_LSB EQU  $09
__WPARAM23_MSB EQU  $0A
__WPARAM34    EQU  $0A
__WPARAM34_LSB EQU  $0A
__WPARAM34_MSB EQU  $0B
__TRISA       EQU  $FA
TRIS_A        EQU  $FA
__TRISB       EQU  $FB
TRIS_B        EQU  $FB
__TRISC       EQU  $FC
TRIS_C        EQU  $FC
__INTPARAMFSR EQU  $F5
__REMAINDER   EQU  $08
__WREMAINDER  EQU  $08
__WREMAINDER_LSB EQU  $08
__WREMAINDER_MSB EQU  $09

; Define ShiftIn & ShiftOut Constants
LSBFIRST      EQU  0
MSBFIRST      EQU  1
MSBPRE        EQU  0
LSBPRE        EQU  1
MSBPOST       EQU  2
LSBPOST       EQU  3


 LIST Q=2                        ;IRC_CAL         IRC_4MHZ
IRC_CAL         IRC_4MHZ        
 LIST Q=-2                      

FREQ 4000000                     ;FREQ            4_000_000 
__FREQMHZ     EQU  4

ID "DHdec11A"                    ;ID              "DHdec11A" 


                                 ;' ------------------------------------------------------------------------- 
                                 ;' IO Pins 
                                 ;' ------------------------------------------------------------------------- 

UnusedRA0     EQU  RA.0          ;UnusedRA0 PIN RA.0 INPUT PULLUP ' always pull up unused input pins, or make them outputs

UnusedRA1     EQU  RA.1          ;UnusedRA1 PIN RA.1 INPUT PULLUP

UnusedRA2     EQU  RA.2          ;UnusedRA2 PIN RA.2 INPUT PULLUP


SignalDetect  EQU  RA.3          ;SignalDetect    PIN 	RA.3 INPUT


LedPort       EQU  RB            ;LedPort     PIN RB ' used for setting all 4 leds at once

LedFirstPin   EQU  1             ;LedFirstPin CON 1 ' first pin index number of set of 4 for leds

LedPortMask   EQU  %1111<<LedFirstPin^$FF ;LedPortMask CON %1111 << LedFirstPin ^ $FF ' mask for LED pins for setting all at once


UnusedRB0     EQU  RB.0          ;UnusedRB0 PIN RB.0 INPUT PULLUP


Lock          EQU  LedPort.1     ;Lock		PIN	LedPort.1 OUTPUT

Unlock        EQU  LedPort.2     ;Unlock		PIN	LedPort.2 OUTPUT

Trunk         EQU  LedPort.3     ;Trunk		PIN	LedPort.3 OUTPUT

Panic         EQU  LedPort.4     ;Panic		PIN	LedPort.4 OUTPUT


UnusedRB5     EQU  RB.5          ;UnusedRB5 PIN RB.5 INPUT PULLUP

UnusedRB6     EQU  RB.6          ;UnusedRB6 PIN RB.6 INPUT PULLUP

UnusedRB7     EQU  RB.7          ;UnusedRB7 PIN RB.7 INPUT PULLUP


UnusedRC      EQU  RC            ;UnusedRC PIN RC INPUT PULLUP


                                 ;' ------------------------------------------------------------------------- 
                                 ;' Constants 
                                 ;' -------------------------------------------------------------------------

                                 ;' Output Constants

LEDON         EQU  1             ;LEDON  CON 1 ' change this to 0 if you use "active low" LEDs, i.e., cathode to pin

LEDOFF        EQU  0             ;LEDOFF CON 0 ' change this to 1 if you use "active low" LEDs, i.e., cathode to pin


                                 ;' Pulsetrain Constants

                                 ;'PULSESTATE      CON  0 ' set to 0 if you are measuring LOW pulses; set to 1 if you measuring HIGH pulse; yours are LOW, I believe

STARTBIT      EQU  7200          ;STARTBIT      CON 7200 ' in microseconds -- presuming that your measurements of these is correct!

ONEBIT        EQU  2400          ;ONEBIT        CON 2400 ' in microseconds -- but if not, just edit them to match reality

ZEROBIT       EQU  1200          ;ZEROBIT       CON 1200 ' in microseconds


ERRORMARGIN   EQU  15            ;ERRORMARGIN   CON 15   ' margin of error for a good pulse, in percent -- adjust if need be

                                 ;                       ' your margin for the 1.2-1.3ms zero pulse is about 9.2 percent



                                 ;' Computed Constants - no need to edit these, they are derived from the values above

PULSERESOLUTION  EQU  10         ;PULSERESOLUTION CON 10 ' pulsewidth measurement units, DO NOT CHANGE


PULSINRESHALF  EQU  (PULSERESOLUTION+1)/2 ;PULSINRESHALF  CON (PULSERESOLUTION+1)/2 ' used for rounding


ERRMARGDIV    EQU  (100+(ERRORMARGIN/2))/ERRORMARGIN ;ERRMARGDIV    CON (100+(ERRORMARGIN/2))/ERRORMARGIN

ERRMARGHALF   EQU  (ERRMARGDIV+1)/2 ;ERRMARGHALF   CON (ERRMARGDIV+1)/2 ' used for rounding


STARTBITACT   EQU  (STARTBIT+PULSINRESHALF)/PULSERESOLUTION ;STARTBITACT   CON (STARTBIT+PULSINRESHALF)/PULSERESOLUTION ' actual pulsewidths in PULSERESOLUTION units

ONEBITACT     EQU  (ONEBIT+PULSINRESHALF)/PULSERESOLUTION ;ONEBITACT     CON (ONEBIT+PULSINRESHALF)/PULSERESOLUTION

ZEROBITACT    EQU  (ZEROBIT+PULSINRESHALF)/PULSERESOLUTION ;ZEROBITACT    CON (ZEROBIT+PULSINRESHALF)/PULSERESOLUTION


STARTBITMAX   EQU  STARTBITACT+((STARTBITACT+ERRMARGHALF)/ERRMARGDIV) ;STARTBITMAX   CON STARTBITACT+((STARTBITACT+ERRMARGHALF)/ERRMARGDIV) ' these are mins/maxes that allow for the percent margin of error

STARTBITMIN   EQU  STARTBITACT-((STARTBITACT+ERRMARGHALF)/ERRMARGDIV) ;STARTBITMIN   CON STARTBITACT-((STARTBITACT+ERRMARGHALF)/ERRMARGDIV) ' 648 - 792 = 0x288 0x0318


ONEBITMAX     EQU  ONEBITACT+((ONEBITACT+ERRMARGHALF)/ERRMARGDIV) ;ONEBITMAX     CON ONEBITACT+((ONEBITACT+ERRMARGHALF)/ERRMARGDIV)

ONEBITMIN     EQU  ONEBITACT-((ONEBITACT+ERRMARGHALF)/ERRMARGDIV) ;ONEBITMIN     CON ONEBITACT-((ONEBITACT+ERRMARGHALF)/ERRMARGDIV)


ZEROBITMAX    EQU  ZEROBITACT+((ZEROBITACT+ERRMARGHALF)/ERRMARGDIV) ;ZEROBITMAX    CON ZEROBITACT+((ZEROBITACT+ERRMARGHALF)/ERRMARGDIV)

ZEROBITMIN    EQU  ZEROBITACT-((ZEROBITACT+ERRMARGHALF)/ERRMARGDIV) ;ZEROBITMIN    CON ZEROBITACT-((ZEROBITACT+ERRMARGHALF)/ERRMARGDIV)


                                 ;' ------------------------------------------------------------------------- 
                                 ;' Variables 
                                 ;' ------------------------------------------------------------------------- 

                                 ;' $00 GLOBAL bank

tmpW1         EQU  0x0D          ;tmpW1 VAR Word    ' work variables
tmpW1_LSB     EQU  tmpW1        
tmpW1_MSB     EQU  tmpW1+1      

tmpB1         EQU  0x0F          ;tmpB1 VAR Byte


                                 ;' $10 default bank

msgBits       EQU  0x10          ;msgBits  VAR Byte ' possible message in progress bits

message       EQU  0x11          ;message  VAR Byte ' final message byte

prevMsg       EQU  0x12          ;prevMsg  VAR Byte ' previous message received

msgCount      EQU  0x13          ;msgCount VAR Byte ' number of times same message received

bitCount      EQU  0x14          ;bitCount VAR Byte ' good bits received this message

pulseDur      EQU  0x15          ;pulseDur VAR Word ' pulse duration in units of PULSERESOLUTION
pulseDur_LSB  EQU  pulseDur     
pulseDur_MSB  EQU  pulseDur+1   


frame         EQU  0x17          ;frame    VAR Byte ' currently unused


                                 ;' ========================================================================= 
RESET __PROGSTART                ;PROGRAM Start
__PROGSTART:                    
  JNB TO,@__RESTORETRIS         
  JB PD,@__POWERUP              
  CLR W                         
  MODE $09                      
  MOV !RB,W                     
  MOV FSR,W                     
  MODE $0F                      
  CJE FSR,#0,@__POWERUP         
  CJNE FSR,#$FF,@__RESTORETRIS  
__POWERUP:                      
  CLR RA                        
  CLR RB                        
  CLR RC                        
  MOV FSR,#$08                  
  SB FSR.3                      
  SETB FSR.4                    
  CLR IND                       
  IJNZ FSR,@$-3                 
  MOV FSR,#__TRISA              
  MOV IND,#255                  
  INC FSR                       
  MOV IND,W                     
  INC FSR                       
  MOV IND,W                     
__RESTORETRIS:                  
  MOV FSR,#__TRISA              
  MOV !RA,IND                   
  INC FSR                       
  MOV !RB,IND                   
  INC FSR                       
  MOV !RC,IND                   
  MODE $0F                      
  MOV FSR,#__TRISB              
  MOV W,#225                    
  MOV !RB,W                     
  MOV IND,W                     
  MODE $0E                      
  MOV W,#248                    
  MOV !RA,W                     
  MOV W,#30                     
  MOV !RB,W                     
  MOV W,#0                      
  MOV !RC,W                     
  CLR FSR                       
  JMP @Start                    
  ORG $+2  ; FOR DEBUGGER       

                                 ;' ========================================================================= 

                                 ;' -------------------------------------------------------------------------
                                 ;' Subroutine Declarations
                                 ;' -------------------------------------------------------------------------

__GET_PULSE:                     ;GET_PULSE FUNC 2                ' return a word value in PULSERESOLUTION units of PULSESTATE on SignalDetect pin
  JMP @GET_PULSE                

__PAUSE_US:                      ;PAUSE_US  SUB  2, 2 ', Word       ' pause microseconds
  JMP @PAUSE_US                 

__PAUSE_MS:                      ;PAUSE_MS  SUB  2, 2 ', Word       ' pause milliseconds
  JMP @PAUSE_MS                 


                                 ;' ------------------------------------------------------------------------- 
                                 ;' Program Code 
                                 ;' ------------------------------------------------------------------------- 
Start:                           ;Start:                   ' only runs on reset/power-up


                                 ;  ' BANK __DEFAULT

  CLRB Lock                      ;   Lock         = LEDOFF

  CLRB Unlock                    ;   Unlock	= LEDOFF

  CLRB Trunk                     ;   Trunk	= LEDOFF

  CLRB Panic                     ;   Panic	= LEDOFF


  CLR message                    ;   message = %0000_0000

  CLR prevMsg                    ;   prevMsg = %0000_0000 

  CLR bitCount                   ;   bitCount = 0

  CLR frame                      ;   frame = 0             ' this is stub that we might use for additional error checking; for now it does nothing


  MOV __PARAM1,#500 & 255        ;   PAUSE_MS 500         ' let everything settle (can't hurt)
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              



Led_Test:                        ;Led_Test:


                                 ;   ' all on
  MOV W, #LedPortMask ^ $FF      ;   \MOV W, #LedPortMask ^ $FF

  OR LedPort, W                  ;   \OR LedPort, W

  MOV __PARAM1,#500 & 255        ;   PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              

                                 ;   ' all off
  AND LedPort,#LedPortMask       ;   LedPort = LedPort & LedPortMask

  MOV __PARAM1,#500 & 255        ;   PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              

                                 ;   ' now light up each led in order for one second each, one second between

  SETB Lock                      ;   Lock = LEDON

  MOV __PARAM1,#500 & 255        ;   PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              

  CLRB Lock                      ;   Lock = LEDOFF

  MOV __PARAM1,#500 & 255        ;   PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              


  SETB Unlock                    ;   Unlock = LEDON

  MOV __PARAM1,#500 & 255        ;   PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              

  CLRB Unlock                    ;   Unlock = LEDOFF

  MOV __PARAM1,#500 & 255        ;   PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              


  SETB Trunk                     ;   Trunk = LEDON

  MOV __PARAM1,#500 & 255        ;   PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              

  CLRB Trunk                     ;   Trunk = LEDOFF

  MOV __PARAM1,#500 & 255        ;   PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              


  SETB Panic                     ;   Panic = LEDON

  MOV __PARAM1,#500 & 255        ;   PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              

  CLRB Panic                     ;   Panic = LEDOFF

  MOV __PARAM1,#500 & 255        ;   PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              



                                 ;' ------------------------------------------------------------------------- 

Main:                            ;Main:


  CLR bitCount                   ;   bitCount = 0         ' clear bit count for next message



                                 ;' ------------------------------------------------------------------------- 
Test_Start_Bit:                  ;Test_Start_Bit:

__DO_1:                          ;   DO

  CALL @__GET_PULSE              ;      pulseDur = GET_PULSE
  MOV pulseDur_LSB,__PARAM1     
  MOV pulseDur_MSB,__PARAM2     


  CJB pulseDur_MSB,#STARTBITMIN >> 8,@__ELSE_1 ;         IF pulseDur >= STARTBITMIN THEN   ' see if it's a start bit
  JNZ @$+8                      
  CJB pulseDur_LSB,#STARTBITMIN & 255,@__ELSE_1

  CJB pulseDur_MSB,#STARTBITMAX >> 8,@$+13 ;            IF pulseDur <= STARTBITMAX THEN 
  JNZ @__ELSE_2                 
  CJA pulseDur_LSB,#STARTBITMAX & 255,@__ELSE_2

  SETB Lock                      ;               lock = 1

__DO_2:                          ;               DO

  JMP @__DO_2                    ;               LOOP
__LOOP_2:                       

__ELSE_2:                        ;            ENDIF
__ENDIF_2:                      

  JMP @__ENDIF_1                 ;         ELSEIF pulseDur >= ONEBITMIN THEN   ' see if it's a start bit
__ELSE_1:                       
  CJB pulseDur_MSB,#ONEBITMIN >> 8,@__ELSE_3
  JNZ @$+8                      
  CJB pulseDur_LSB,#ONEBITMIN & 255,@__ELSE_3

  CJB pulseDur_MSB,#ONEBITMAX >> 8,@$+13 ;            IF pulseDur <= ONEBITMAX THEN 
  JNZ @__ELSE_4                 
  CJA pulseDur_LSB,#ONEBITMAX & 255,@__ELSE_4

  SETB Unlock                    ;               unlock = 1

__DO_3:                          ;               DO

  JMP @__DO_3                    ;               LOOP
__LOOP_3:                       

__ELSE_4:                        ;            ENDIF
__ENDIF_4:                      

  JMP @__ENDIF_1                 ;         ELSEIF pulseDur >= ZEROBITMIN THEN   ' see if it's a start bit
__ELSE_3:                       
  CJB pulseDur_MSB,#ZEROBITMIN >> 8,@__ELSE_5
  JNZ @$+8                      
  CJB pulseDur_LSB,#ZEROBITMIN & 255,@__ELSE_5

  CJB pulseDur_MSB,#ZEROBITMAX >> 8,@$+13 ;            IF pulseDur <= ZEROBITMAX THEN 
  JNZ @__ELSE_6                 
  CJA pulseDur_LSB,#ZEROBITMAX & 255,@__ELSE_6

  SETB Trunk                     ;               trunk = 1

__DO_4:                          ;               DO

  JMP @__DO_4                    ;               LOOP
__LOOP_4:                       

__ELSE_6:                        ;            ENDIF
__ENDIF_6:                      

__ELSE_5:                        ;         ENDIF
__ENDIF_1:                      


  JMP @__DO_1                    ;   LOOP
__LOOP_1:                       



                                 ;' ------------------------------------------------------------------------- 

Get_Message_Bits:                ;Get_Message_Bits:

__DO_5:                          ;   DO WHILE bitCount < 9   ' must have 8 good bits + start bit = 9 bits for message to be considered valid
  CJAE bitCount,#9,@__LOOP_5    


  CALL @__GET_PULSE              ;      pulseDur = GET_PULSE
  MOV pulseDur_LSB,__PARAM1     
  MOV pulseDur_MSB,__PARAM2     


  CJNE bitCount,#0,@__ELSE_7     ;      IF bitCount = 0 THEN  ' start bit not received yet


  CJB pulseDur_MSB,#STARTBITMIN >> 8,@__ELSE_8 ;         IF pulseDur >= STARTBITMIN THEN   ' see if it's a start bit
  JNZ @$+8                      
  CJB pulseDur_LSB,#STARTBITMIN & 255,@__ELSE_8

  CJB pulseDur_MSB,#STARTBITMAX >> 8,@$+13 ;            IF pulseDur <= STARTBITMAX THEN 
  JNZ @__ELSE_9                 
  CJA pulseDur_LSB,#STARTBITMAX & 255,@__ELSE_9

  MOV bitCount,#1                ;               bitCount = 1                ' start bit received

  CLR msgBits                    ;               msgBits = %0000_0000        ' clear message received bits

__ELSE_9:                        ;            ENDIF
__ENDIF_9:                      

__ELSE_8:                        ;         ENDIF
__ENDIF_8:                      


  JMP @__ENDIF_7                 ;      ELSE                              ' if you got start bit, see if subsequent bits are 0, 1 or "bad" bit
__ELSE_7:                       


  CJB pulseDur_MSB,#ZEROBITMIN >> 8,@$+13 ;         IF pulseDur < ZEROBITMIN THEN  ' too small for zero
  JNZ @__ELSE_10                
  CJAE pulseDur_LSB,#ZEROBITMIN & 255,@__ELSE_10

  CLR bitCount                   ;            bitCount = 0                ' clear the bit count

  JMP @__ENDIF_10                ;         ELSEIF pulseDur > ONEBITMAX THEN  ' too big for one
__ELSE_10:                      
  CJB pulseDur_MSB,#ONEBITMAX >> 8,@__ELSE_11
  JNZ @$+8                      
  CJBE pulseDur_LSB,#ONEBITMAX & 255,@__ELSE_11

  CLR bitCount                   ;            bitCount = 0                ' clear the bit count

  JMP @__ENDIF_10                ;         ELSEIF pulseDur > ZEROBITMAX THEN  ' too big for zero, too small for one
__ELSE_11:                      
  CJB pulseDur_MSB,#ZEROBITMAX >> 8,@__ELSE_12
  JNZ @$+8                      
  CJBE pulseDur_LSB,#ZEROBITMAX & 255,@__ELSE_12

  CJB pulseDur_MSB,#ONEBITMIN >> 8,@$+13 ;            IF pulseDur < ONEBITMIN THEN  
  JNZ @__ELSE_13                
  CJAE pulseDur_LSB,#ONEBITMIN & 255,@__ELSE_13

  CLR bitCount                   ;               bitCount = 0                ' clear the bit count

__ELSE_13:                       ;            ENDIF
__ENDIF_13:                     

__ELSE_12:                       ;         ENDIF
__ENDIF_10:                     


  CJE bitCount,#0,@__ELSE_14     ;         IF bitCount <> 0 THEN           ' only do the bit if it's good


                                 ;'{$IFDEF MESSAGE_LSB_FIRST}
                                
                                 ;              msgBits = msgBits >> 1 '  shift existing bits (presumes message is LSB first)
                                 ;              IF pulseDur >= ONEBITMIN THEN ' if 1 bit, set it; if 0, it's already 0
                                 ;                msgBits.7 = 1 ' set MSB to 1
                                 ;              ENDIF
                                
                                 ;'{$ELSE}
                                 ;            ' default is MSB first unless MESSAGE_LSB_FIRST is defined
  MOV __PARAM1,msgBits           ;            msgBits = msgBits << 1          '  shift existing bits (presumes message is MSB first)
  CLC                           
  RL __PARAM1                   
  MOV msgBits,__PARAM1          

  CJB pulseDur_MSB,#ONEBITMIN >> 8,@__ELSE_15 ;            IF pulseDur >= ONEBITMIN THEN   ' if 1 bit, set it; if 0, it's already 0
  JNZ @$+8                      
  CJB pulseDur_LSB,#ONEBITMIN & 255,@__ELSE_15

  SETB msgBits.0                 ;               msgBits.0 = 1 ' set LSB to 1

__ELSE_15:                       ;            ENDIF
__ENDIF_15:                     


                                 ;'{$ENDIF}

  INC bitCount                   ;            INC bitCount ' increment bit count   


__ELSE_14:                       ;         ENDIF
__ENDIF_14:                     


__ENDIF_7:                       ;       ENDIF


  JMP @__DO_5                    ;   LOOP
__LOOP_5:                       


                                 ;' ------------------------------------------------------------------------- 
Message_Done:                    ;Message_Done:


  MOV prevMsg,message            ;   prevMsg = message    ' save last message received

  MOV message,msgBits            ;   message = msgBits    ' save current message


  CJNE message,#%1001_1111,@__ELSE_16 ;   IF     message = %1001_1111 THEN ' edit what led(s) you want on and off for each message


  SETB Lock                      ;          lock   = LEDON

  CLRB Unlock                    ;          Unlock = LEDOFF

  CLRB Trunk                     ;          trunk  = LEDOFF

  CLRB Panic                     ;          panic  = LEDOFF


  JMP @__ENDIF_16                ;   ELSEIF message = %1010_1111 THEN
__ELSE_16:                      
  CJNE message,#%1010_1111,@__ELSE_17


  CLRB Lock                      ;          lock   = LEDOFF

  SETB Unlock                    ;          Unlock = LEDON

  CLRB Trunk                     ;          trunk  = LEDOFF

  CLRB Panic                     ;          panic  = LEDOFF


  JMP @__ENDIF_16                ;   ELSEIF message = %1011_0111 THEN
__ELSE_17:                      
  CJNE message,#%1011_0111,@__ELSE_18


  CLRB Lock                      ;          lock   = LEDOFF

  CLRB Unlock                    ;          Unlock = LEDOFF

  SETB Trunk                     ;          trunk  = LEDON

  CLRB Panic                     ;          panic  = LEDOFF


  JMP @__ENDIF_16                ;   ELSEIF message = %1011_1011 THEN
__ELSE_18:                      
  CJNE message,#%1011_1011,@__ELSE_19


  CLRB Lock                      ;          lock   = LEDOFF

  CLRB Unlock                    ;          Unlock = LEDOFF

  CLRB Trunk                     ;          trunk  = LEDOFF

  SETB Panic                     ;          panic  = LEDON


                                 ;  ' add more elseifs here if you want them for other messages

  JMP @__ENDIF_16                ;   ELSE
__ELSE_19:                      


                                 ;          ' below is "anything else" lighting of the LEDs
                                 ;          ' this could help debug if you get messages, but they don't correspond 
                                 ;          ' to what you want. of course, a message of %00000000 would result in all LEDs off, but still could be helpful

                                 ;          ' if no other matches, this will display the low nib then the high nib of "message", one second each

                                 ;          ' first "blink" all LEDs once to announce the low nibble:
  MOV W, #LedPortMask ^ $FF      ;          \MOV W, #LedPortMask ^ $FF

  OR LedPort, W                  ;          \OR LedPort, W

  MOV __PARAM1,#500 & 255        ;          PAUSE_MS 500   ' pause .5 second
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              

                                 ;          ' all off
  AND LedPort,#LedPortMask       ;          LedPort = LedPort & LedPortMask

  MOV __PARAM1,#300 & 255        ;          PAUSE_MS 300
  MOV __PARAM2,#300 >> 8        
  CALL @__PAUSE_MS              


  MOV W,message                  ;          tmpB1 = message & $0F ' low nib first
  AND W,#$0F                    
  MOV tmpB1,W                   

  MOV __PARAM1,tmpB1             ;          tmpB1 = tmpB1 << LedFirstPin
  CLC                           
  RL __PARAM1                   
  MOV tmpB1,__PARAM1            

  AND LedPort,#LedPortMask       ;          LedPort = LedPort & LedPortMask

  OR LedPort,tmpB1               ;          LedPort = LedPort | tmpB1

  MOV __PARAM1,#2000 & 255       ;          PAUSE_MS 2000   ' pause two seconds
  MOV __PARAM2,#2000 >> 8       
  CALL @__PAUSE_MS              


                                 ;          ' all off
  AND LedPort,#LedPortMask       ;          LedPort = LedPort & LedPortMask

  MOV __PARAM1,#500 & 255        ;          PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              


                                 ;          ' now "blink" all LEDs twice to announce the low nibble:
  MOV W, #LedPortMask ^ $FF      ;          \MOV W, #LedPortMask ^ $FF

  OR LedPort, W                  ;          \OR LedPort, W

  MOV __PARAM1,#500 & 255        ;          PAUSE_MS 500   ' pause .5 second
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              

  AND LedPort,#LedPortMask       ;          LedPort = LedPort & LedPortMask

  MOV __PARAM1,#300 & 255        ;          PAUSE_MS 300
  MOV __PARAM2,#300 >> 8        
  CALL @__PAUSE_MS              

  MOV W, #LedPortMask ^ $FF      ;          \MOV W, #LedPortMask ^ $FF

  OR LedPort, W                  ;          \OR LedPort, W

  MOV __PARAM1,#500 & 255        ;          PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              

                                 ;          ' all off
  AND LedPort,#LedPortMask       ;          LedPort = LedPort & LedPortMask

  MOV __PARAM1,#300 & 255        ;          PAUSE_MS 300
  MOV __PARAM2,#300 >> 8        
  CALL @__PAUSE_MS              


  MOV W,message                  ;          tmpB1 = message & $F0 ' high nib
  AND W,#$F0                    
  MOV tmpB1,W                   

  SWAP tmpB1                     ;          SWAP tmpB1

  MOV __PARAM1,tmpB1             ;          tmpB1 = tmpB1 << LedFirstPin
  CLC                           
  RL __PARAM1                   
  MOV tmpB1,__PARAM1            

  AND LedPort,#LedPortMask       ;          LedPort = LedPort & LedPortMask

  OR LedPort,tmpB1               ;          LedPort = LedPort | tmpB1

  MOV __PARAM1,#2000 & 255       ;          PAUSE_MS 2000   ' pause two seconds
  MOV __PARAM2,#2000 >> 8       
  CALL @__PAUSE_MS              


  AND LedPort,#LedPortMask       ;          LedPort = LedPort & LedPortMask  ' and turn off all LEDs

  MOV __PARAM1,#500 & 255        ;          PAUSE_MS 500
  MOV __PARAM2,#500 >> 8        
  CALL @__PAUSE_MS              


__ENDIF_16:                      ;   ENDIF


                                 ;  ' no pauses for regularly handled messages lighting LEDs -- they will "stay" lit until another message comes in


                                 ;' ------------------------------------------------------------------------- 
Message_Count:                   ;Message_Count:

  JMP @Done                      ;   GOTO Done                    ' COMMENT OUT THIS LINE if you want LEDs and message to reset 

                                 ;                                ' when the same message is received over and over for about 8-10 seconds

  CJNE message,prevMsg,@__ELSE_20 ;   IF message = prevMsg THEN

  INC msgCount                   ;     INC msgCount                 ' 20 = ~1 second of same message repeating

  CJBE msgCount,#200,@__ELSE_21  ;     IF msgCount > 200 THEN       ' so this will TURN OFF all the LEDs after 8-10 seconds of the SAME message being received

  CLR message                    ;         message = %0000_0000

  MOV prevMsg,#%1111_1111        ;         prevMsg = %1111_1111

  AND LedPort,#LedPortMask       ;         LedPort = LedPort & LedPortMask

  CLR msgCount                   ;         msgCount = 0

__ELSE_21:                       ;     ENDIF
__ENDIF_21:                     

  JMP @__ENDIF_20                ;   ELSE
__ELSE_20:                      

  CLR msgCount                   ;     msgCount = 0

__ENDIF_20:                      ;   ENDIF



                                 ;' ------------------------------------------------------------------------- 
Done:                            ;   Done:


  JMP @Main                      ;     GOTO Main



                                 ;' -------------------------------------------------------------------------
                                 ;' SUBROUTINES AND FUNCTIONS
                                 ;' -------------------------------------------------------------------------

GET_PULSE:                       ;FUNC GET_PULSE

  MOV FSR,#__TRISA               ;  PULSIN  SignalDetect, 0, tmpW1 ', 1 ', PULSINRES = 10us units
  MODE $0F                      
  SETB IND.3                    
  MOV !RA,IND                   
  BANK $00                      
  CLR tmpW1_LSB                 
  CLR tmpW1_MSB                 
  MOV __PARAM4,#5               
  DJNZ __PARAM4,@$              
  NOP                           
  NOP                           
  NOP                           
  SUB tmpW1_LSB,#1              
  SUBB tmpW1_MSB,/C             
  MOV W,tmpW1_LSB               
  OR W,tmpW1_MSB                
  JZ @$+50                      
  JNB SignalDetect,@$-17        
  CLR tmpW1_LSB                 
  CLR tmpW1_MSB                 
  MOV __PARAM4,#5               
  DJNZ __PARAM4,@$              
  NOP                           
  NOP                           
  NOP                           
  SUB tmpW1_LSB,#1              
  SUBB tmpW1_MSB,/C             
  MOV W,tmpW1_LSB               
  OR W,tmpW1_MSB                
  JZ @$+28                      
  JB SignalDetect,@$-17         
  MOV tmpW1_LSB,#1              
  CLR tmpW1_MSB                 
  MOV __PARAM4,#5               
  DJNZ __PARAM4,@$              
  NOP                           
  NOP                           
  NOP                           
  INC tmpW1_LSB                 
  ADDB tmpW1_MSB,Z              
  MOV W,tmpW1_LSB               
  OR W,tmpW1_MSB                
  JZ @$+6                       
  JNB SignalDetect,@$-16        

  MOV __PARAM1,tmpW1_LSB         ;  RETURN tmpW1
  MOV __PARAM2,tmpW1_MSB        
  RETP                          

                                 ;  ENDFUNC



PAUSE_US:                        ;SUB PAUSE_US

                                 ;'  tmpW1 = __WPARAM12
  MOV __PARAM1,__WPARAM12_LSB    ;  PAUSEUS __WPARAM12
  MOV __PARAM2,__WPARAM12_MSB   
  CLC                           
  RR __PARAM2                   
  RR __PARAM1                   
  MOV W,__PARAM1                
  OR W,__PARAM2                 
  JZ @$+13                      
  INC __PARAM2                  
  NOP                           
  NOP                           
  NOP                           
  DJNZ __PARAM1,@$-3            
  DJNZ __PARAM2,@$-6            

  RETP                           ;  ENDSUB


PAUSE_MS:                        ;SUB PAUSE_MS

                                 ;'  tmpW1 = __WPARAM12
  MOV __PARAM1,__WPARAM12_LSB    ;  PAUSE __WPARAM12
  OR W,__WPARAM12_MSB           
  JZ @$+21                      
  MOV W,++__WPARAM12_MSB        
  MOV __PARAM2,W                
  MOV __PARAM3,#4               
  MOV __PARAM4,#28              
  DJNZ __PARAM4,@$              
  DJNZ __PARAM3,@$-3            
  DJNZ __PARAM1,@$-10           
  DJNZ __PARAM2,@$-13           

  RETP                           ;  ENDSUB



                                 ;' -------------------------------------------------------------------------
                                 ;' DATA
                                 ;' -------------------------------------------------------------------------
                                 ;'

