;ALARM415.ASM 12DEC02 - COPYRIGHT JOHN BECKER - EPE INTRUDER ALARM

;PIC16F877-4, 3.2768MHz, WDT OFF, POR ON, XTAL XS

;Config register bits
; CP1 CP0 DBG NIL WRT CPD LVP BOR CP1 CP0 POR WDT OS1 OS0
;  1   1   1   1   1   1   0   0   1   1   0   0   0   1
;N.B. Logic 1/0 do NOT necessarily mean that the function is On/Off
;respectively - refer to PIC '87 data sheet.

#DEFINE PAGE0   BCF $03,5
#DEFINE PAGE1   BSF $03,5

	List P = PIC16F877, R=DEC; 
        __CONFIG   h'3F31'

INDF:    .EQU $00  ;page 0, 1, 2, 3
OPTION:  .EQU $01  ;page 1, 3
PCL:     .EQU $02  ;page 0, 1, 2, 3
STATUS:  .EQU $03  ;page 0, 1, 2, 3
FSR:     .EQU $04  ;page 0, 1, 2, 3

PORTA:   .EQU $05  ;page 0
TRISA:   .EQU $05  ;page 1
PORTB:   .EQU $06  ;page 0, 2
TRISB:   .EQU $06  ;page 1, 3
PORTC:   .EQU $07  ;page 0
TRISC:   .EQU $07  ;page 1
PORTD:   .EQU $08  ;page 0
TRISD:   .EQU $08  ;page 1
PORTE:   .EQU $09  ;page 0
TRISE:   .EQU $09  ;page 1

PCLATH:  .EQU $0A  ;page 0, 1, 2, 3
INTCON:  .EQU $0B  ;page 0, 1, 2, 3

EEDATA:  .EQU $0C  ;page 2
EECON1:  .EQU $0C  ;page 3
         
PIR2:    .EQU $0D  ;page 0
EEADR:   .EQU $0D  ;page 2
EECON2:  .EQU $0D  ;page 3

ADCON1:  .EQU $1F  ;page 1

SLOWIT:   .EQU $20        ; pause counter
CLKCNT:   .EQU $21
CLKSEC:   .EQU $22
CLKMIN:   .EQU $23
CLKHRS:   .EQU $24
LOOP:     .EQU $25
LOOPA:    .EQU $26 
RSLINE:   .EQU $27
STORE:    .EQU $28 
STORE1:   .EQU $29 
STORE2:   .EQU $2A
STORE3:   .EQU $2B
ZONESVAL: .EQU $2C     ; current val of zones status
ALARMSTATUS: .EQU $2D  ; controls the following:
                       ; bit 0 buzzer
                       ; bit 1 strobe
                       ; bit 2 bell
                       ; bit 3 -
                       ; bit 4 Panic flag
                       ; bit 5 passive entry zone (just turns on buzzer when entered)
                       ; bit 6 power interrupt flag
                       ; bit 7 alarm on flag

SWITCH1:   .EQU $2E   ; multiplex val for rows
SWVAL:     .EQU $2F   ; input val from RB0-RB3
COL:       .EQU $30   ; column counter (inc in decimal)
ROW:       .EQU $31   ; row counter (inc as matrix val)
ROWNUM:    .EQU $32   ; row counter (inc in decimal)
ALARMZONE: .EQU $33   ; holds status of which zone triggered
KEYPRESS:  .EQU $34   ; value of key pressed keypad1
PIN0:      .EQU $35   ; 1st pin number val FIRST KEYPAD
PIN1:      .EQU $36   ; 2nd pin number val
PIN2:      .EQU $37   ; 3rd pin number val
PIN3:      .EQU $38   ; 4th pin number val

EXITTIME:  .EQU $39   ; entry/exit delay
EXITZONE:  .EQU $3A   ; entry/exit zone
INCLZONE:  .EQU $3B   ; zones to be included in monitoring

BELLTIME      .EQU $3C   ; bell on time value in BCD mins
FLASH:        .EQU $3D   ; flag for flashing buzzer LED when zone incorrectly open during alarm setting
ZONENORMAL:   .EQU $3E  ; normal zone logic
ENGINEERSET:  .EQU $3F ; flag to indicate if ENGINEER has been called
PREVALARMZONE .EQU $40 ; previous alarm condition register
ENTRYDELAY:   .EQU $41 ; counter for entry/exit delay
PIN4:         .EQU $42   ; 1st pin number val FOR 2ND KEYPAD
PIN5:         .EQU $43   ; 2nd pin number val
PIN6:         .EQU $44   ; 3rd pin number val
PIN7:         .EQU $45   ; 4th pin number val
KEYPRESS2:    .EQU $46   ; value of key pressed keypad2
ENTRYTIME2:   .EQU $47   ; entry time for keypad2
ENTRYDELAY2:  .EQU $48   ; counter for keypad2 entry delay
CLKCNT2:      .EQU $49
STORED        .EQU $4A   ; temp store for keypad2

COUNT0  .EQU    0x50            ;lsb
COUNT1  .EQU    0x51
COUNT2  .EQU    0x52            ;msb
DIGIT1  .EQU    0x53            ;lsd
DIGIT2  .EQU    0x54
BITCNT  .EQU    0x5B
DIGCNT  .EQU    0x5C
STOREX: .EQU $60
STOREY: .EQU $61

          ; locations up to $7F are available

             ;************************************************************
             ;           Bit Definitions
             ;************************************************************

W:      .EQU 0
F:      .EQU 1
C:      .EQU 0
DC:     .EQU 1 
Z:      .EQU 2

RP0:    .EQU 5           ;STATUS reg
RP1:    .EQU 6           ;STATUS reg
GIE:    .EQU 7           ;INTCON reg

RD:     .EQU 0  ;EECON1 reg eeprom read enable flag
WR:     .EQU 1  ;EECON1 reg eeprom write initiate flag
WREN:   .EQU 2  ;EECON1 reg eeprom write enable flag

EEPGD:  .EQU 7           ;EECON1 reg 
EEIF:   .EQU 4           ;PIR2 reg 

BUZZER: .EQU 0
STROBE: .EQU 1
BELL:   .EQU 2
PANIC:  .EQU 4
RBIF:   .EQU 0

;............. DATA EEPROM USE

                ; 0-3  PIN CODE
                ; 4    ZONES EXCLUDED
                ; 5    ENTRY/EXIT ZONE
                ; 6    ENTRY/EXIT DELAY
                ; 7    ZONES INTRUDED (AlarmZone)
                ; 8    ALARM ON/OFF & BELL, BUZZER, STROBE STATUS (AlarmStatus)
                ; 9    BELL ON TIME (MAX 15 MINS)
                ; 10   NORMAL ZONE STATUS
                ; 11-14 2ND PIN CODE
                ; 15   ENTRY DELAY VIA KEYPAD2

        .ORG $0004      ;Interrupt vector address
        GOTO GIEOFF     ;Jump to interrupt routine on interrupt
        .ORG $0005      ;Start of program memory

GIEOFF: BCF INTCON,GIE  ;turn off global interrupts
        BTFSC INTCON,GIE
        goto GIEOFF
        goto START

TABLCD: addwf PCL,F     ;LCD initialisation table
        retlw %00110011 ;initialise lcd - first byte
        retlw %00110011 ;2nd byte (repeat of first)
        retlw %00110010 ;set for 4-bit operation
        retlw %00101100 ;set for 2 lines
        retlw %00000110 ;set entry mode to increment each address
        retlw %00001100 ;set display on, cursor off, blink off
        retlw %00000001 ;clear display
        retlw %00000010 ;return home, cursor & RAM to zero
                        ;end inititalisation table

ALLOFF: addwf PCL,F
        retlw 'A'
        retlw 'L'
        retlw 'L'
        retlw ' '
        retlw 'O'
        retlw 'F'
        retlw 'F'
        retlw ' '

MESSAGON: addwf PCL,F
        retlw 'A'
        retlw 'L'
        retlw 'A'
        retlw 'R'
        retlw 'M'
        retlw ' '
        retlw 'O'
        retlw 'N'
        retlw ' '

MESSAG2: addwf PCL,F
        retlw ' '
        retlw ' '
        retlw 'E'
        retlw 'N'
        retlw 'T'
        retlw 'R'
        retlw 'Y'
        retlw ' '

CHKVAL: addwf PCL,F
        retlw %01011001 ;59 secs max
        retlw %01011001 ;59 mins max
        retlw %00100011 ;23 hours max

VALUE:  ADDWF PCL,F       ;lookup table for key allocation
        retlw '1'
        retlw '2'
        retlw '3'
        retlw 'A'
        retlw '4'
        retlw '5'
        retlw '6'
        retlw 'B'
        retlw '7'
        retlw '8'
        retlw '9'
        retlw 'C'
        retlw '-'
        retlw '0'
        retlw 'E'
        retlw 'D'

BITVALUE: ADDWF PCL,F       ;lookup table for decimal to bit conversion
        retlw 0
        retlw 1
        retlw 2
        retlw 4
        retlw 8
        retlw 16
        retlw 32
        retlw 64
        retlw 128

PINCODE: ADDWF PCL,F       ; change pin code message
        retlw 'C'
        retlw 'H'
        retlw 'A'
        retlw 'N'
        retlw 'G'
        retlw 'E'
        retlw ' '
        retlw 'P'
        retlw 'I'
        retlw 'N'
        retlw ' '
        retlw 'C'
        retlw 'O'
        retlw 'D'
        retlw 'E'
        retlw ' '

PIN2MSG: ADDWF PCL,F       ; change 2ND pin code message
        retlw 'S'
        retlw 'E'
        retlw 'T'
        retlw ' '
        retlw '2'
        retlw 'N'
        retlw 'D'
        retlw ' '
        retlw 'P'
        retlw 'I'
        retlw 'N'
        retlw ' '
        retlw 'C'
        retlw 'O'
        retlw 'D'
        retlw 'E'

ENTRYTIME: ADDWF PCL,F       ; change ENTRY/EXIT time message
        retlw 'S'
        retlw 'E'
        retlw 'T'
        retlw ' '
        retlw 'I'
        retlw 'N'
        retlw '/'
        retlw 'O'
        retlw 'U'
        retlw 'T'
        retlw ' '
        retlw 'T'
        retlw 'I'
        retlw 'M'
        retlw 'E'
        retlw ' '

BELLTIMEMSG: ADDWF PCL,F       ; change ENTRY/EXIT time message
        retlw 'S'
        retlw 'E'
        retlw 'T'
        retlw ' '
        retlw 'B'
        retlw 'E'
        retlw 'L'
        retlw 'L'
        retlw ' '
        retlw 'O'
        retlw 'N'
        retlw ' '
        retlw 'T'
        retlw 'I'
        retlw 'M'
        retlw 'E'

ENTRYZONE: ADDWF PCL,F       ; set ENTRY/EXIT zone message
        retlw 'S'
        retlw 'E'
        retlw 'T'
        retlw ' '
        retlw 'I'
        retlw 'N'
        retlw '/'
        retlw 'O'
        retlw 'U'
        retlw 'T'
        retlw ' '
        retlw 'Z'
        retlw 'O'
        retlw 'N'
        retlw 'E'
        retlw ' '

MODEMSG: ADDWF PCL,F       ; mode message
        retlw 'S'
        retlw 'E'
        retlw 'L'
        retlw 'E'
        retlw 'C'
        retlw 'T'
        retlw ' '
        retlw 'M'
        retlw 'O'
        retlw 'D'
        retlw 'E'
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '
        retlw ' '

WATCHMSG: ADDWF PCL,F       ; zones to be watched message
        retlw 'S'
        retlw 'E'
        retlw 'T'
        retlw ' '
        retlw 'W'
        retlw 'A'
        retlw 'T'
        retlw 'C'
        retlw 'H'
        retlw ' '
        retlw 'Z'
        retlw 'O'
        retlw 'N'
        retlw 'E'
        retlw 'S'
        retlw ' '

OPENZONE: ADDWF PCL,F       ; zones incorrectly open when alarm is being set
        retlw 'C'
        retlw 'H'
        retlw 'E'
        retlw 'C'
        retlw 'K'
        retlw ' '
        retlw 'O'
        retlw 'P'
        retlw 'E'
        retlw 'N'
        retlw ' '
        retlw 'Z'
        retlw 'O'
        retlw 'N'
        retlw 'E'
        retlw 'S'

ZONELOGIC: ADDWF PCL,F       ; assess zone logic message (i.e normally open or normally closed)
        retlw 'A'
        retlw 'U'
        retlw 'T'
        retlw 'O'
        retlw ' '
        retlw 'Z'
        retlw 'O'
        retlw 'N'
        retlw 'E'
        retlw ' '
        retlw 'A'
        retlw 'S'
        retlw 'S'
        retlw 'E'
        retlw 'S'
        retlw 'S'

SHOWLOGIC: ADDWF PCL,F       ; assess zone logic message (i.e normally open or normally closed)
        retlw 'N'
        retlw 'O'
        retlw 'R'
        retlw 'M'
        retlw ' '
        retlw 'Z'
        retlw 'O'
        retlw 'N'
        retlw 'E'
        retlw ' '
        retlw 'L'
        retlw 'O'
        retlw 'G'
        retlw 'I'
        retlw 'C'
        retlw ' '

PASSIVEMSG: ADDWF PCL,F       ; passive alarm message
        retlw 'M'
        retlw 'O'
        retlw 'N'
        retlw 'I'
        retlw 'T'
        retlw 'O'
        retlw 'R'
        retlw ' '

START:  bcf STATUS,RP0
        bcf STATUS,RP1
        clrf PORTA
        clrf PORTB
        clrf PORTC
        clrf PORTD
        clrf PORTE
        PAGE1
        movlw %11011111     ;RB0-RB4, RB6-RB7 as input, RB5 as output
        movwf TRISB
        movlw %00001111     ;RC0-RC3 as input, RC4-RC7 as output
        movwf TRISC         
        movlw 255
        movwf TRISD         ;PORTD as input
        clrf TRISE          ;PORTE as output
        movlw %00000111     ;PORT A/E as digital
        movwf ADCON1        ;
        movlw %11000000     ;RA0-RA5 as outputs
        movwf TRISA

        movlw %00000110     ;timer 1:128 (1/25th sec)
        movwf OPTION
        PAGE0
        clrf INTCON
        call PAUSIT     ;1/5 sec delay

LCDSET: clrf LOOP       ;clr LCD set-up loop
        clrf RSLINE     ;clear RS line for instruction send
LCDST2: movf LOOP,W     ;get table address
        call TABLCD     ;get set-up instruction
        call LCDOUT     ;perform it
        incf LOOP,F     ;inc loop
        btfss LOOP,3    ;has last LCD set-up instruction now been done?
        goto LCDST2     ;no
        call PAUSIT     ;1/5 sec delay

        clrf ENGINEERSET
        bsf ALARMSTATUS,6   ; set Power interruption flag

        call KEYPAD1    ; is ENGINEER code to be entered following power-up
        movf KEYPRESS,W ; with key 'D' pressed?
        xorlw 'D'
        btfss STATUS,Z
        goto SETCLK     ; no

        clrf ALARMZONE
        clrf ALARMSTATUS
        bsf ENGINEERSET,0
        bcf ALARMSTATUS,6   ; clear Power interruption flag

        movlw %10000001 ; default set INCLZONE for zones 1 & 8
        movwf STORE1
        movlw 4
        call SETPRM

        movlw %00000001 ; default set entry/exit zone
        movwf STORE1
        movlw 5
        call SETPRM

        movlw 30        ; default set EXITTIME to 30 secs in binary
        movwf STORE1
        movlw 6
        call SETPRM

        clrf STORE1     ; default clear INTRUDED status
        movlw 7
        call SETPRM
        clrf PORTE

        clrf STORE1     ; default clear ALARMSTATUS (bell etc)
        bcf STORE1,BELL
        movlw 8
        call SETPRM

        movlw %00010101 ; default set bell switch-off time to 15 mins in BCD
        movwf STORE1
        movlw 9
        call SETPRM

        movlw %00000000 ; default set for "normal" zone status - all open
        movwf STORE1
        movlw 10
        call SETPRM

        movlw 30        ; default set ENTRYTIME to 30 secs in binary for keypad2
        movwf STORE1
        movlw 15
        call SETPRM

        call ENGINEER   ; yes, set ENGINEER entry code and reset all defaults

SETCLK: clrf CLKSEC     ;clear seconds counter
        clrf CLKMIN     ;clear minutes counter
        clrf CLKHRS     ;clear hours counter
        clrf PREVALARMZONE
        clrf ENTRYDELAY
        clrf ENTRYDELAY2

        movlw 25        ;initial basic CLKCNT val for secs timing
        movwf CLKCNT

        movlw 0         ; RECALL PIN CODE
        call PRMGET
        movwf PIN0
        movlw 1
        call PRMGET
        movwf PIN1
        movlw 2
        call PRMGET
        movwf PIN2
        movlw 3
        call PRMGET
        movwf PIN3

        movlw 4            ; RECALL INCLUDED/EXCLUDED ZONES
        call PRMGET
        movwf INCLZONE
        bsf INCLZONE,7     ; ensure bit 7 (1st PANIC zone) is always on

        movlw 5            ; RECALL ENTRY/EXIT ZONE
        call PRMGET
        movwf EXITZONE
        movlw 6            ; RECALL ENTRY/EXIT TIME
        call PRMGET
        movwf EXITTIME
        movlw 7            ; RECALL ALARMZONE STATUS
        call PRMGET
        movwf ALARMZONE
        movlw 8            ; RECALL ALARMSTATUS STATUS
        call PRMGET
        movwf ALARMSTATUS  ; and activate buzzer/strobe if needed (but not bell)
        andlw %00000011
        movwf PORTE
        movlw 9            ; RECALL BELL ON TIME
        call PRMGET
        movwf BELLTIME
        movlw 10           ; RECALL "NORMAL ZONE STATUS
        call PRMGET
        movwf ZONENORMAL

        movlw 11           ; RECALL PIN CODE 2
        call PRMGET
        movwf PIN4
        movlw 12
        call PRMGET
        movwf PIN5
        movlw 13
        call PRMGET
        movwf PIN6
        movlw 14
        call PRMGET
        movwf PIN7

        movlw 15           ; RECALL ENTRY TIME FOR KEYPAD2
        call PRMGET
        movwf ENTRYTIME2

        btfss ALARMSTATUS,7 ; is alarm on?
        goto ITSOFF
        call CHECKZONE2
        bsf ALARMSTATUS,6   ; set Power interruption flag
        goto MAIN

ITSOFF: call ALARMOFF   ; show ALARM OFF message
        btfsc ENGINEERSET,0 ; has ENGINEER been called?
        goto MAIN       ;yes

        call LCD21      ;set address for line 1 cell 1
        bsf RSLINE,4    ;set RS for data send
        movlw 'P'
        call LCDOUT
        movlw 'O'
        call LCDOUT
        movlw 'W'
        call LCDOUT
        movlw 'E'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw 'E'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        movlw 'O'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        clrf ENGINEERSET   ; clear ENGINEER flag

;............................ END OF SETUP

MAIN:   call CHECKMODE
        call PINENTRY2
        movf ENTRYDELAY2,W  ; has entry2 delay timed out?
        btfss STATUS,Z
        call CONTINUEENTRY2 ; no, continue countdown of entry2
        goto MAIN

ALARMISON: btfss ALARMSTATUS,7 ; is alarm on ?
        return            ; no
        call MONITOR      ; get current status of zones 1-8
        call CHECKZONE    ; compare current and preset zones status
        call SETBELLS
        call CLKIN
        return

PASSIVEALARM:
        call MONITOR      ; get current status of zones 1-8
        call CHECKZONE    ; compare current and preset zones status
        movf ZONESVAL,W
        btfss STATUS,Z
        goto PAS1
        bcf PORTE,BUZZER
        goto PAS2
PAS1:   bsf PORTE,BUZZER
PAS2:   call LCD21          ;set address for line 1 cell 1
        bsf RSLINE,4       ;set RS for data send
        movf ZONESVAL,W
        movwf STORE1       ; store INTRUDED status
        call SHOWZONE
        return

;******* CHECK MODE

CHECKMODE: call KEYPAD1   ; is key pressed?
        movf KEYPRESS,W
        btfsc STATUS,Z
        return            ; no, so return

CHECKM2: call WAITKEYPRESS
        movf KEYPRESS,W      ; is keypress = pin number?
        xorwf PIN0,W
        btfss STATUS,Z
        return

        call WAITKEYRELEASE
        call WAITKEYPRESS
        movf KEYPRESS,W      ; is keypress = pin number?
        xorwf PIN1,W
        btfss STATUS,Z
        return

        call WAITKEYRELEASE
        call WAITKEYPRESS
        movf KEYPRESS,W      ; is keypress = pin number?
        xorwf PIN2,W
        btfss STATUS,Z
        return

        call WAITKEYRELEASE
        call WAITKEYPRESS
        movf KEYPRESS,W      ; is keypress = pin number?
        xorwf PIN3,W
        btfss STATUS,Z
        return

        goto AMENDMODE       ; yes

;*********** AMEND MODE  **********

AMENDMODE: clrf PORTE      ; turn off bell, buzzer, strobe
        btfss ALARMSTATUS,7  ; is alarm already in alarm mode?
        goto AMEND0     ; no
        goto AMEND2     

AMEND0: call LCD1       ;set address for line 1 cell 1
        bsf RSLINE,4    ;set RS for data send
        clrf LOOP       ;clear loop
        bsf RSLINE,4    ;set RS for data send
AMEND1: movf LOOP,W     ;get table address
        call MODEMSG    ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto AMEND1     ;no
        call CLRLINE2

AMEND2: clrf ALARMSTATUS
        clrf ALARMZONE
        clrf PREVALARMZONE

        call WAITKEYRELEASE
        call WAITKEYPRESS

        movf KEYPRESS,W  ; is keypress = '0' - alarm on?
        xorlw '0'
        btfsc STATUS,Z
        goto ALARMON     ; yes, so set alarm on and exit

CHECK12: movf KEYPRESS,W ; is keypress = '-' - cancel?
        xorlw '-'
        btfsc STATUS,Z
        goto ALARMOFF    ; general return to normal off status

CHECK0: movf KEYPRESS,W  ; is keypress = '1' - change PIN code?
        xorlw '1'
        btfss STATUS,Z
        goto CHECK1
        call ENGINEER
        goto AMEND0

CHECK1: movf KEYPRESS,W  ; is keypress = '2' - change ENTRY/EXIT time?
        xorlw '2'
        btfss STATUS,Z
        goto CHECK2
        call CHANGEENTRY
        goto AMEND0

CHECK2: movf KEYPRESS,W  ; is keypress = '3' - change ENTRY/EXIT ZONE?
        xorlw '3'
        btfss STATUS,Z
        goto CHECK3
        call SETENTRY
        goto AMEND0

CHECK3: movf KEYPRESS,W  ; is keypress = '4' - select zones to monitored?
        xorlw '4'
        btfss STATUS,Z
        goto CHECK4
        call SETMONITOR
        goto AMEND0

CHECK4: movf KEYPRESS,W  ; is keypress = '5' - select bell on time (max 15 mins)
        xorlw '5'
        btfss STATUS,Z
        goto CHECK5
        call SETBELLTIME
        goto AMEND0

CHECK5: movf KEYPRESS,W  ; is keypress = '6' - assess normal zone logic
        xorlw '6'
        btfss STATUS,Z
        goto CHECK6
        call ASSESSLOGIC
        goto AMEND0

CHECK6: movf KEYPRESS,W  ; is keypress = '7' - preset normal zone logic
        xorlw '7'
        btfss STATUS,Z
        goto CHECK7
        call PRESETLOGIC
        goto AMEND0

CHECK7: movf KEYPRESS,W  ; is keypress = '8' - set 2nd pin code
        xorlw '8'
        btfss STATUS,Z
        goto CHECK8
        call PINCODE2
        goto AMEND0

CHECK8: movf KEYPRESS,W  ; is keypress = '9' - change ENTRY time for keypad2 ?
        xorlw '9'
        btfss STATUS,Z
        goto CHECK14
        call CHANGEENTRY2
        goto AMEND0

CHECK14: movf KEYPRESS,W  ; is keypress = '.' (coded 'E') - buzzer only monitor of entries
        xorlw 'E'
        btfss STATUS,Z
        goto CHECK15
        goto SETPASSIVE

CHECK15:
        goto AMEND2


; ******** PASSIVE MODE

SETPASSIVE: call LCD1  ;set LCD for line 1, cell 1
         bsf RSLINE,4   ;set LCD RS line high

        clrf LOOP       ;clear loop
SETP2:  movf LOOP,W     ;get table address
        call PASSIVEMSG ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,3    ;has last LCD letter been sent?
        goto SETP2      ;no
        movlw 'M'
        call LCDOUT
        movlw '0'
        call LCDOUT
        movlw 'D'
        call LCDOUT
        movlw 'E'
        call LCDOUT
        bsf ALARMSTATUS,5
        return

;********* CHANGE ENTRY/EXIT TIME

CHANGEENTRY: call LCD1  ;set LCD for line 1, cell 1
         bsf RSLINE,4   ;set LCD RS line high

        clrf LOOP       ;clear loop
ENT2:   movf LOOP,W     ;get table address
        call ENTRYTIME  ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto ENT2       ;no

        call CLRLINE2
        call LCD23      ;set LCD for line 2, cell 3
        bsf RSLINE,4    ;set LCD RS line high
        movlw ' '
        call LCDOUT
        movlw 'P'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        movlw 'E'
        call LCDOUT
        movlw 'V'
        call LCDOUT
        movlw ' '
        call LCDOUT
        movf EXITTIME,W
        movwf COUNT0
        call BIN2DEC

        movf DIGIT2,W
        addlw 48
        call LCDOUT
        movf DIGIT1,W
        addlw 48
        call LCDOUT

        call LCD21      ;set LCD for line 2, cell 1
        bsf RSLINE,4    ;set LCD RS line high

        call WAITKEYRELEASE
ENT3:   call WAITKEYPRESS ; get first value (tens)
        movf KEYPRESS,W ; is keypress = 12 - cancel?
        xorlw '-'
        btfsc STATUS,Z
        return          ; yes

        btfsc KEYPRESS,6 ; is it >= 'A'?
        goto ENT3        ; yes, so try again

        movf KEYPRESS,W
        andlw %00001111

        movwf COUNT1
        movwf COUNT2
        movf KEYPRESS,W
        call LCDOUT

        call WAITKEYRELEASE
ENT4:   call WAITKEYPRESS   ; get 2nd val (units)
        movf KEYPRESS,W ; is keypress = 12 - cancel?
        xorlw '-'
        btfsc STATUS,Z
        return          ; yes

        btfsc KEYPRESS,6 ; is it >= 'A'?
        goto ENT4        ; yes, so try again

        movf KEYPRESS,W
        andlw %00001111
        movwf COUNT0
        addwf COUNT1,W   ; is total = 0?
        btfsc STATUS,Z
        goto ENT4        ; yes, so try again
        movf KEYPRESS,W
        call LCDOUT

ENT5:   call WAITKEYRELEASE
        call WAITKEYPRESS
        movf KEYPRESS,W
        xorlw 'D'        ; is key = 15? - completion code number
        btfsc STATUS,Z
        goto ENT6        ; yes

        movf KEYPRESS,W
        xorlw '-'        ; is key = 12? - error in number so start again
        btfss STATUS,Z
        goto ENT5        ; no
        goto CHANGEENTRY ; yes

ENT6:   call WAITKEYRELEASE
        bcf STATUS,C
        rlf COUNT1,F     ; convert decimal to binary
        rlf COUNT1,F
        rlf COUNT1,W
        addwf COUNT2,W
        addwf COUNT2,W
        addwf COUNT0,W
        movwf EXITTIME
        movf EXITTIME,W
        movwf STORE1
        movlw 6
        call SETPRM
        call STORIT
        return

;********* MONITOR ZONES   *********

MONITOR: swapf PORTC,W   ; get RC0-RC3, store it as MS nibble
         andlw %11110000
         movwf ZONESVAL
         movf PORTD,W    ; get RD0-RD3, store it as LS nibble
         andlw %00001111
         iorwf ZONESVAL,F
         return

; ********* compare current and preset zones status

CHECKZONE: movf ENTRYDELAY2,W  ; has entry2 delay timed out?
        btfss STATUS,Z
        call CONTINUEENTRY2 ; no, continue countdown       

        movf ZONESVAL,W    ; get current zones val
        xorwf ZONENORMAL,W ; XOR with normal zones status
        btfss STATUS,Z     ; has a zone status been changed?
        goto ZCH2          ; yes
        movf ALARMZONE,W   ; have any zones been triggered?
        btfsc STATUS,Z     ;
        return             ; no

ZCH2:   movwf ZONESVAL     ; yes
        andwf INCLZONE,W   ; is it a required zone?
        btfsc STATUS,Z
        return             ; no

        movwf ZONESVAL
        btfsc ALARMSTATUS,5 ; yes, is alarm in passive status (just sets buzzer)?
        return              ; yes

        iorwf ALARMZONE,W  ; no, OR answer with previous zones triggered value
        movwf ALARMZONE

        btfsc ALARMSTATUS,STROBE  ; has alarm already been triggered?
        goto ZONEB          ; yes

        movf ALARMZONE,W
        andwf EXITZONE,W   ; has entry zone been triggered?
        btfsc STATUS,Z
        goto ZONEB         ; no

        movf ENTRYDELAY,W   ; yes, has entry delay timed out?
        btfsc STATUS,Z
        goto ZONEB         ; yes

        bsf ALARMSTATUS,BUZZER ; no so continue countdown
        call CONTINUEENTRY ;

        call LCD21          ;set address for line 1 cell 1
        bsf RSLINE,4       ;set RS for data send
        movlw 'E'
        call LCDOUT
        movlw 'N'
        call LCDOUT
        movlw 'T'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        movlw 'Y'
        call LCDOUT
        return

ZONEB:  movf ALARMZONE,W
        xorwf PREVALARMZONE,W  ; is it same as previous alarm zone setting?
        btfsc STATUS,Z
        return               ; yes

        movf ALARMZONE,W
        movwf PREVALARMZONE

        movwf STORE1       ; store INTRUDED status
        movlw 7
        call SETPRM

CHECKZONE2:                ; called also from power up entry
        call LCD1          ;set address for line 1 cell 1
        bsf RSLINE,4       ;set RS for data send
        movf ALARMZONE,W
        movwf STORE1       ; store INTRUDED status
        call SHOWZONE

        clrf LOOP       ;clear loop
        bsf RSLINE,4    ;set RS for data send
        btfss ALARMSTATUS,PANIC
        goto LCDMS3     ; ...... TRIG
        movlw 'P'
        call LCDOUT

LCDMS3: movf LOOP,W     ;get table address
        call MESSAG2    ;get ENTERED message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,3    ;has last LCD letter been sent?
        goto LCDMS3     ;no

TRIG:   btfss ALARMSTATUS,STROBE    ; has alarm already been triggered?
        bsf ALARMSTATUS,BELL        ; no, so trigger bell
        bsf ALARMSTATUS,BUZZER
        bsf ALARMSTATUS,STROBE

        movf ALARMSTATUS,W          ; store ALARMSTATUS (but with bell off) to eeprom
        movwf STORE1
        bcf STORE1,BELL
        movlw 8
        call SETPRM
        return

; ****** SETS BELL BUZZER STROBE with ALARMSTATUS value

SETBELLS: movf ALARMSTATUS,W
        andlw %00000111
        movwf PORTE
        return

;********* CLOCK UPDATING

CLKIN:  btfss ALARMSTATUS,STROBE  ; clock only used if strobe active
        return                    ; allowing elapsed time since first zone triggered to be shown
        btfss INTCON,2            ; has timer rollover occurred?
        return                    ; no

        BCF INTCON,2     ; yes, clear timer flag
        decfsz CLKCNT,F  ; increment clock routine. Is it = 0?
        return           ; no

CLKADD: movlw 25         ; reset start value of CLKCNT
        movwf CLKCNT

SECCLK: movlw CLKSEC
        movwf FSR
        movlw 3
        movwf LOOPA

ADDCLK: incf INDF,F     ;inc units
        movlw 6
        addwf INDF,W    ;if 6 is added is there a digit carry?
        btfss STATUS,DC
        goto CHK15      ;no
        movwf INDF      ;yes
        movlw 160
        addwf INDF,W    ;if 160 is added is there a carry
        btfss STATUS,C  ;(adding 160 checks if tens of units = 6)
        goto CHK15      ;no
        clrf INDF       ;yes
        incf FSR,F
        decfsz LOOPA,F
        goto ADDCLK

CHK15:  movf CLKMIN,W         ; has bell been on for set number of mins?
        xorwf BELLTIME,W      ; mins in BCD (max 20)
        btfsc STATUS,Z
        bcf ALARMSTATUS,BELL

CLKSHW: call LCD21      ;set address for line 1 cell 9
        bsf RSLINE,4    ;set RS for data send
        movf CLKHRS,W   ;get hrs
        call LCDFRM     ;format and send it
        movlw ':'       ;insert colon
        call LCDOUT
        movf CLKMIN,W   ;get mins
        call LCDFRM
        movlw '.'       ;insert colon
        call LCDOUT
        movf CLKSEC,W   ;get secs
        call LCDFRM
        btfss ALARMSTATUS,6 ; has there been a power interruption?
        return          ;no

        movlw ' '       ; yes
        call LCDOUT
        movlw 'P'
        call LCDOUT
        movlw 'S'
        call LCDOUT
        movlw 'U'
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw 'E'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        return

;..........GET KEYPAD 1 VAL ROUTINE........

KEYPAD1: clrf KEYPRESS
         btfss INTCON,RBIF    ; has Panic been pushed
         goto KP2             ; no
         call PANICSET

KP2:     btfsc ALARMSTATUS,7  ; is alarm on?
         call ALARMISON       ; yes
         btfsc ALARMSTATUS,5  ; is alarm on?
         call  PASSIVEALARM   ; yes

;         goto KEYPAD2

         movlw %00001111
         movwf PORTC
         movwf STORE
         nop              ;pause to allow PORTC to stabilise
         comf PORTB,W     ;get & invert PORTB
         andlw %00001111  ;isolate bits 0-3
         btfsc STATUS,Z   ;is result NOT zero (keys pressed)?
         return           ;no, so return to main prog

         movlw %10000000  ;yes, a key is pressed so get it
         movwf SWITCH1    ;initial val for RC4-7
         movlw 3          ;initial val for COL
         movwf COL
         clrf ROW         ;initial val for ROW

GETIT:   comf SWITCH1,W   ;get and invert val for PORTC
         iorwf STORE,W
         movwf PORTC      ;output to PORTC
         nop              ;pause to allow PORTC to stabilise
         comf PORTB,W     ;get and invert val from PORTB
         andlw 15         ;isolate bits 0-3
         btfss STATUS,Z   ;is it zero?
         goto GET2        ;no, so goto analysis routine
         decf COL,F       ;dec col val
         bcf STATUS,C     ;clear carry flag
         rrf SWITCH1,F    ;divide RC7-4 val by 2
         movf SWITCH1,W   ;
         andlw %11110000
         btfss STATUS,C   ;is it zero?
         goto GETIT       ;no, so continue loop
         return           ;yes, so return to main program

GET2:    movwf SWVAL      ;store PORTB val
         clrf ROW         ;clear row count
         clrf ROWNUM      ;clear row number count

GET3:    rrf SWVAL,F      ;rotate right PORTB store val
         btfsc STATUS,C   ;is carry flag set?
         goto SUMIT       ;yes so key pressed, go & finish answer
         movlw 4
         addwf ROW,F      ;add matrix val to ROW count
         incf ROWNUM,F    ;inc row number count
         btfss ROWNUM,2
         goto GET3

SUMIT:   movf ROW,W       ;sum up results to single answer
         addwf COL,W      ;add ROW to COL (total of 0-15)
         call VALUE
         movwf KEYPRESS   ; store result into KEYPRESS
         call DEBOUNCE
         return           ;return to main program

;********* SET ENGINEER'S PIN CODE

ENGINEER: call LCD1       ;set LCD for line 1, cell 1
         bsf RSLINE,4     ;set LCD RS line high

        clrf LOOP       ;clear loop
ENG2:   movf LOOP,W     ;get table address
        call PINCODE    ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto ENG2       ;no

        call CLRLINE2
        call LCD21      ;set LCD for line 2, cell 1
        bsf RSLINE,4    ;set LCD RS line high

        movlw PIN0
        movwf FSR
        clrf LOOP

ENG3:   call WAITKEYRELEASE
        call WAITKEYPRESS

        movf KEYPRESS,W
        xorlw '-'        ; is key = 12? - error in number so start again
        btfss STATUS,Z   ; ... c
        goto ENG4        ; ... ENGINEER
        movf LOOP,W      ; is LOOP = 0?
        btfss STATUS,Z
        goto ENGINEER    ; no, so clear and continue
        return           ; yes, so exit

ENG4:   movf KEYPRESS,W  ; is val greater than 11?
        xorlw 'E'        ; is it = 14?
        btfsc STATUS,Z
        goto ENG3        ; yes, so try again
        movf KEYPRESS,W  ; is val greater than 11?
        xorlw 'D'        ; is it = 15?
        btfsc STATUS,Z
        goto ENG3        ; yes, so try again

        movf KEYPRESS,W
        movwf INDF       ; no, store it into PINx and eeprom
        movwf STORE1     ; and send to LCD
        movf LOOP,W
        call SETPRM
        movf KEYPRESS,W
        call LCDOUT
        incf FSR,F
        incf LOOP,F
        btfss LOOP,2
        goto ENG3

ENG7:   call WAITKEYRELEASE
        call WAITKEYPRESS
        movf KEYPRESS,W
        xorlw 'D'        ; is key = 16? - completion code number
        btfsc STATUS,Z
        goto ENG8        ; yes

        movf KEYPRESS,W
        xorlw '-'        ; is key = 12? - error in number so start again
        btfss STATUS,Z
        goto ENG7        ; no
        goto ENGINEER

ENG8:   call STORIT
        call WAITKEYRELEASE
        return

; ******* WRITE DATA TO EEPROM ROUTINE modified for PIC16F87x devices ********
          ;according to data sheet DS30292A page 43

                        ;This routine is entered with W holding
                        ;the eeprom byte address at which data
                        ;is to be stored. The data to be stored
                        ;is held in STORE1.
SETPRM: bsf STATUS,RP1  ;set for Page 2
        bcf STATUS,RP0
        movwf EEADR     ;copy W into EEADR to set eeprom address
        bcf STATUS,RP1  ;set for Page 0
        movf STORE1,W   ;get data value from STORE1 and hold in W
        bsf STATUS,RP1  ;set for Page 2
        movwf EEDATA    ;copy W into eeprom data byte register
        bsf STATUS,RP0  ;set for page 3
        bcf EECON1,EEPGD ;point to Data memory
        bsf EECON1,WREN ;enable write flag

MANUAL: movlw $55       ;these lines cause the action required by
        movwf EECON2    ;by the eeprom to store the data in EEDATA
        movlw $AA       ;at the address held by EEADR.
        movwf EECON2
        bsf EECON1,WR   ;set the ``perform write'' flag
        bcf STATUS,RP1  ;set for Page 0
        bcf STATUS,RP0

CHKWRT: btfss PIR2,EEIF ;wait until bit 4 of PIR2 is set
        goto CHKWRT
        bcf PIR2,EEIF   ;clear bit 4 of PIR2
        return


;******** READ DATA FROM EEPROM ROUTINE modified for PIC16F87x devices ****
;         according to data sheet DS30292A page 43

                        ;This routine is entered with W holding
                        ;the eeprom byte address to be read.
PRMGET: bsf STATUS,RP1  ;set for Page 2
        bcf STATUS,RP0
        movwf EEADR     ;copy W into EEADR to set eeprom address
        bsf STATUS,RP0  ;set for Page 3
        bcf EECON1,EEPGD ;point to data memory
        bsf EECON1,RD   ;enable read flag
        bcf STATUS,RP0  ;set for Page 2 
        movf EEDATA,W   ;read eeprom data now in EEDATA into W
        bcf STATUS,RP1  ;set for Page 0
        return

;******** LCD ROUTINES **********

LCD1:   movlw %10000000
        goto LCDLIN
LCD5:   movlw %10000100
        goto LCDLIN
LCD21:  movlw %11000000
        goto LCDLIN
LCD23:  movlw %11000011

LCDLIN: BCF RSLINE,4

LCDOUT: movwf STORE
        movlw 50
        movwf LOOPA
DELAY:  decfsz LOOPA,F
        goto DELAY
        call SENDIT
SENDIT: swapf STORE,F
        movf STORE,W
        andlw 15
        iorwf RSLINE,W
        movwf PORTA
        BSF PORTA,5
        BCF PORTA,5
        RETURN

LCDFRM: movwf STORE2    ;split & format decimal byte for LCD
        swapf STORE2,W  ;get tens nibble
        andlw 15
        iorlw 48        ;ASCII convert it
        call LCDOUT     ;send it
        movf STORE2,W   ;get units
        andlw 15
        iorlw 48        ;ASCII convert it
	call LCDOUT
	return

;.............

PAUSIT: movlw 10
        movwf SLOWIT
        BCF INTCON,2
PAUSE:  btfss INTCON,2
        goto PAUSE
        BCF INTCON,2
        decfsz SLOWIT,F
        goto PAUSE
        return

DEBOUNCE: bsf PORTE,0      ; briefly sound buzzer
        clrf SLOWIT
DBX:    decfsz SLOWIT,F
        goto DBX
DBA:    decfsz SLOWIT,F
        goto DBA
DBB:    decfsz SLOWIT,F
        goto DBB
DBC:    decfsz SLOWIT,F
        goto DBC
DBD:    decfsz SLOWIT,F
        goto DBD

        btfss PORTE,1      ; has alarm been triggered?
        bcf PORTE,0        ; no, so turn off buzzer
        return

;.............

ALARMOFF: clrf PORTE
        call CLRLINE1
        call LCD1     ;set address for line 1 cell 1
        bsf RSLINE,4    ;set RS for data send
        clrf LOOP       ;clear loop
        bsf RSLINE,4    ;set RS for data send
ALOFF2: movf LOOP,W     ;get table address
        call ALLOFF     ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,3    ;has last LCD letter been sent?
        goto ALOFF2     ;no
        call CLRLINE2
        call PAUSIT
        clrf ALARMZONE
        clrf ALARMSTATUS
        clrf PREVALARMZONE
        clrf ENTRYDELAY
        clrf ZONESVAL
        clrf CLKSEC
        clrf CLKMIN
        clrf CLKHRS

        clrf STORE1       ; reset ALARMZONE status to eeprom
        movlw 7
        call SETPRM
        clrf STORE1       ; reset ALARMSTATUS status to eeprom
        movlw 8
        call SETPRM
        return

;******** SET ALARM INTO ACTIVE MODE ********

ALARMON: bsf PORTE,BUZZER ; turn on buzzer
        call MONITOR      ; get zones status
        comf EXITZONE,W   ; invert exit zone 
        andwf ZONESVAL,W  ; AND inverted exit zone with zones status to exclude exit zone setting
        movwf STOREX      ; store it into STOREX (new variable that needs equating at start)
        comf EXITZONE,W   ; invert exit zone 
        andwf ZONENORMAL,W ; AND it with ZONENORMAL to exclude its setting
        xorwf STOREX,W    ; compare current zones value with normal zones status, but ignoring entry zone
        btfsc STATUS,Z    ; is a zone incorrectly open?
        goto ALON1        ; no
        movwf STORE3      ; yes, set value for show zones at SETAL

        call KEYPAD1    ; check if abort being called
        movf KEYPRESS,W ; is there a keypress?
        btfsc STATUS,Z
        goto SETAL      ; no

        movf KEYPRESS,W ; yes
        xorlw '-'       ; is key = 12 - abort?
        btfsc STATUS,Z
        goto ALARMOFF   ; yes

SETAL:  call LCD1       ;set address for line 1 cell 1
        bsf RSLINE,4    ;set RS for data send
        clrf LOOP       ;clear loop
        bsf RSLINE,4    ;set RS for data send
ALON0:  movf LOOP,W     ;get table address
        call OPENZONE   ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto ALON0      ;no

        call LCD21      ; set LCD for line 2, cell 1
        bsf RSLINE,4    ; set LCD RS line high
        movf STORE3,W   ; yes, so show zones
        movwf STORE1
        call SHOWZONE
        incf FLASH,F    ; beep buzzer and flash its LED
        bcf PORTE,0
        btfss FLASH,0
        bsf PORTE,0
        call PAUSIT
        goto ALARMON

ALON1:  call CLRLINE1
        call LCD1       ;set address for line 1 cell 1
        bsf RSLINE,4    ;set RS for data send
        clrf LOOP       ;clear loop
        bsf RSLINE,4    ;set RS for data send
ALON2:  movf LOOP,W     ;get table address
        call MESSAGON   ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,3    ;has last LCD letter been sent?
        goto ALON2      ;no
        clrf ALARMZONE
        clrf PREVALARMZONE
        call CLRLINE2
        goto DELAYEXIT

;............

DELAYEXIT:
        movf EXITTIME,W
        movwf CLKSEC

        bsf PORTE,BUZZER ; set buzzer on
        movf CLKSEC,W
        movwf COUNT0
        call BIN2DEC

        call LCD21      ;set address for line 2 cell 1
        bsf RSLINE,4    ;set RS for data send
        movlw 'I'
        call LCDOUT
        movlw 'N'
        call LCDOUT
        movlw ' '
        call LCDOUT

        movf digit2,W
        addlw 48
        call LCDOUT
        movf digit1,W
        addlw 48
        call LCDOUT

        movlw ' '
        call LCDOUT
        movlw 'S'
        call LCDOUT
        movlw 'E'
        call LCDOUT
        movlw 'C'
        call LCDOUT
        movlw 'S'
        call LCDOUT

        movlw 25         ; reset start value of CLKCNT
        movwf CLKCNT     ; 23 used because of DEBOUNCE call in KEYPAD1 routine

        bcf INTCON,2     ; yes, clear timer flag
EXIT2:  btfss INTCON,2   ; has timer rollover occurred?
        goto EXIT2       ; no
        bcf INTCON,2     ; yes, clear timer flag

        call KEYPAD1     ; is abort being called?
        movf KEYPRESS,W
        xorlw '-'
        btfsc STATUS,Z
        goto ALARMOFF    ; yes

        bsf PORTE,BUZZER ; keep buzzer on
        decfsz CLKCNT,F  ; increment clock routine. Is it = 0?
        goto EXIT2       ; no

        movlw 25         ; reset start value of CLKCNT
        movwf CLKCNT     ; 23 used because of DEBOUNCE call in KEYPAD1 routine
        decf CLKSEC,F    ; inc secs count
        movf CLKSEC,W
        movwf count0
        clrf COUNT1
        clrf COUNT2
        call BIN2DEC

        call LCD23      ;set address for line 2 cell 1
        bsf RSLINE,4    ;set RS for data send
        movf CLKSEC,W

        movf digit2,W
        addlw 48
        call LCDOUT
        movf digit1,W
        addlw 48
        call LCDOUT

        movf CLKSEC,W    ; is it equal to EXITTIME?
        btfss STATUS,Z
        goto EXIT2       ; no

        bcf PORTE,BUZZER
        call CLRLINE2
        clrf CLKSEC
        clrf CLKMIN
        clrf CLKHRS
        clrf STORE1       ; reset ALARMZONE status to eeprom
        movlw 7
        call SETPRM
        movlw %10000000   ; bit 7 = alarm on flag
        movwf ALARMSTATUS
        movwf STORE1      ; reset ALARMSTATUS status to eeprom
        movlw 8
        call SETPRM
        movf EXITTIME,W
        movwf ENTRYDELAY
        movlw 25         ; reset start value of CLKCNT
        movwf CLKCNT     ;
        bcf PORTB,5      ; turn off keypad2 entry enable
        return

;*********** binary to decimal modified from Peter Hemsley's code

bin2dec: clrf    digit1
	clrf	digit2

        movlw   8               ;8 bits to do
	movwf	bitcnt

bitlp   rlf     count0,F        ;Shift msb into carry
	movlw	digit1
	movwf	fsr		;Pointer to digits
        movlw   2               ;2 digits to do
	movwf	digcnt
adjlp   rlf     indf,F          ;Shift digit 1 bit left
        movlw 10
        subwf INDF, W
	skpnc
	movwf	indf

        incf    fsr,F           ;Next digit
        decfsz  digcnt,F
	goto	adjlp
        decfsz  bitcnt,F        ;Next bit
	goto	bitlp
	return

;********* SET ENTRY/EXIT ZONE

SETENTRY: call LCD1       ;set LCD for line 1, cell 1
         bsf RSLINE,4     ;set LCD RS line high

        clrf LOOP       ;clear loop
EXT2:   movf LOOP,W     ;get table address
        call ENTRYZONE  ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto EXT2       ;no
        movf EXITZONE,W
        movwf STORE3

        call CLRLINE2

EXT2A:  call LCD21      ;set LCD for line 2, cell 1
        bsf RSLINE,4    ;set LCD RS line high
        movf STORE3,W
        movwf STORE1
        call SHOWZONE
        movlw ' '
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw 'M'
        call LCDOUT
        movlw 'A'
        call LCDOUT
        movlw 'X'
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw '6'
        call LCDOUT

        call WAITKEYRELEASE
EXT3:   call WAITKEYPRESS

        movf KEYPRESS,W ; is keypress = 12 - cancel?
        xorlw '-'
        btfsc STATUS,Z
        return          ; yes

        movf KEYPRESS,W
        xorlw 'D'        ; is key = 15? - completion code number
        btfsc STATUS,Z
        goto EXT5        ; yes

        btfsc KEYPRESS,6   ; is val >= 'A'?
        goto EXT3

        movf KEYPRESS,W
        addlw 201       ; is val greater than 7?
        btfsc STATUS,C
        goto EXT3        ; yes, so try again

        movf KEYPRESS,W
        andlw %00001111
        btfsc STATUS,Z   ; is val = 0?
        goto EXT3        ; yes, so try again
        call BITVALUE
        movwf STORE3
        goto EXT2A

EXT5:   movf STORE3,W    ; store entry/exit zone
        movwf EXITZONE
        movwf STORE1
        movlw 5
        call SETPRM

        movf EXITZONE,W
        iorwf INCLZONE,F ; set INCLZONE to include entry/exit zone
        movf INCLZONE,W  ; store new val for INCLZONE
        movwf STORE1
        movlw 4
        call SETPRM
        call STORIT
        return

;********** SET ZONES TO BE MONITORED

SETMONITOR: call LCD1   ;set LCD for line 1, cell 1
         bsf RSLINE,4   ;set LCD RS line high

        clrf LOOP       ;clear loop
MON2:   movf LOOP,W     ;get table address
        call WATCHMSG   ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto MON2       ;no

        movf INCLZONE,W
        movwf STORE3    ; temp store INTRUDED status
        call CLRLINE2

WATCH2: call LCD21      ;set address for line 2 cell 1
        bsf RSLINE,4    ;set RS for data send
        movf STORE3,W
        movwf STORE1    ; store INTRUDED status
        call SHOWZONE

MON2A:  call WAITKEYRELEASE
MON3:   call WAITKEYPRESS

        movf KEYPRESS,W ; is keypress = 12 - cancel?
        xorlw '-'
        btfsc STATUS,Z
        return          ; yes

        movf KEYPRESS,W
        xorlw 'D'        ; is key = 15? - completion code number
        btfsc STATUS,Z
        goto MON7        ; yes

        btfsc KEYPRESS,6   ; is val >= 'A'?
        goto MON3

        movf KEYPRESS,W
        addlw 200       ; is val greater than 8?
        btfsc STATUS,C
        goto MON3        ; yes, so try again

        movf KEYPRESS,W
        andlw %00001111
        btfsc STATUS,Z
        goto MON2A

        call BITVALUE
        movwf STORE1
        movwf STORE2

        movf STORE3,W        ; toggle existing bit into STORE
        addwf STORE1,W
        andwf STORE1,F

        comf STORE2,W      ; invert value
        andwf STORE3,W   ; AND to clear existing bit

        iorwf STORE1,W
        iorwf EXITZONE,W  ; ensure that entry/exit zone is always set
        movwf STORE3
        bsf STORE3,7
        goto WATCH2

MON7:   movf STORE3,W
        movwf INCLZONE
        movwf STORE1
        movlw 4
        call SETPRM
        call STORIT
        return

;..............

STORIT: movlw ' '
        call LCDOUT
        movlw 'S'
        call LCDOUT
        movlw 'T'
        call LCDOUT
        movlw 'O'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        movlw 'E'
        call LCDOUT
        movlw 'D'
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw ' '
        call LCDOUT

        call PAUSIT
        call PAUSIT

        call LCD1        ;set LCD for line 1, cell 1
        bsf RSLINE,4     ;set LCD RS line high
        clrf LOOP       ;
STOR2:  movf LOOP,W     ;
        movlw ' '       ;clear cell
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto STOR2      ;no
        call CLRLINE2
        return

;...........

WAITKEYRELEASE:
WKR2:   call KEYPAD1         ; wait till key released
        movf KEYPRESS,W
        btfss STATUS,Z
        goto WKR2   
        return

WAITKEYPRESS:
WKP2:   call KEYPAD1         ; wait till key pressed
        movf KEYPRESS,W
        btfsc STATUS,Z
        goto WKP2
        return

SHOWZONE: movlw '1'
        movwf LOOP
        movlw %00000001
        movwf COUNT0
SHOW2:  movf COUNT0,W
        andwf STORE1,W
        movlw '-'
        btfss STATUS,Z
        movf LOOP,W
        call LCDOUT
        incf LOOP,F
        bcf STATUS,C
        rlf COUNT0,F
        btfss STATUS,C
        goto SHOW2
        return

SHOWZONE2: movlw %00000001
        movwf COUNT0
SHOW3:  movf COUNT0,W
        andwf STORE1,W
        movlw 'o'
        btfss STATUS,Z
        movlw 'C'
        call LCDOUT
        bcf STATUS,C
        rlf COUNT0,F
        btfss STATUS,C
        goto SHOW3
        return

;********* CHANGE BELL ON TIME

SETBELLTIME: call LCD1  ;set LCD for line 1, cell 1
         bsf RSLINE,4   ;set LCD RS line high

        clrf LOOP       ;clear loop
BEL2:   movf LOOP,W     ;get table address
        call BELLTIMEMSG  ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto BEL2       ;no

        call CLRLINE2
        call LCD21      ;set LCD for line 2, cell 1
        bsf RSLINE,4    ;set LCD RS line high
        movlw '?'
        call LCDOUT
        movlw '?'
        call LCDOUT
        movlw ' '
        call LCDOUT
        movlw 'P'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        movlw 'E'
        call LCDOUT
        movlw 'V'
        call LCDOUT
        movlw ' '
        call LCDOUT

        movf BELLTIME,W
        call LCDFRM

        movlw ' '
        call LCDOUT
        movlw 'M'
        call LCDOUT
        movlw 'A'
        call LCDOUT
        movlw 'X'
        call LCDOUT
        movlw '2'
        call LCDOUT
        movlw '0'
        call LCDOUT

        call LCD21      ;set LCD for line 2, cell 1
        bsf RSLINE,4    ;set LCD RS line high

        call WAITKEYRELEASE
BEL3:   call WAITKEYPRESS ; get first value (tens)
        movf KEYPRESS,W   ; is keypress = 12 - cancel?
        xorlw '-'
        btfsc STATUS,Z
        return            ; yes

        btfsc KEYPRESS,6   ; is val >= 'A'?
        goto BEL3

        movf KEYPRESS,W
        addlw 205       ; is val greater than 2?
        btfsc STATUS,C
        goto BEL3        ; yes, so try again
        movf KEYPRESS,W
        andlw %00001111

        movwf COUNT1
        iorlw 48
        call LCDOUT

        call WAITKEYRELEASE
BEL4:   call WAITKEYPRESS  ; get 2nd val (units)
        movf KEYPRESS,W    ; is keypress = 12 - cancel?
        xorlw '-'
        btfsc STATUS,Z
        return             ; yes

        btfsc KEYPRESS,6   ; is val >= 'A'?
        goto BEL4

        movf KEYPRESS,W
        addlw 198       ; is val greater than 9?
        btfsc STATUS,C
        goto BEL4        ; yes, so try again
        movf KEYPRESS,W
        andlw %00001111
        movwf COUNT0

        btfss COUNT1,1   ; is COUNT1 (tens) = 2?
        goto BEL4A       ; no
        clrf COUNT0      ; yes, so clear units

BEL4A:  movf COUNT0,W    ; is total value =  0?
        iorwf COUNT1,W
        btfsc STATUS,Z
        goto BEL4        ; yes

        movf COUNT0,W    ; no
        iorlw 48
        call LCDOUT

BEL5:   call WAITKEYRELEASE
        call WAITKEYPRESS
        movf KEYPRESS,W
        xorlw 'D'        ; is key = 15? - completion code number
        btfsc STATUS,Z
        goto BEL6        ; yes

        movf KEYPRESS,W
        xorlw '-'        ; is key = 12? - error in number so start again
        btfss STATUS,Z
        goto BEL5        ; no
        goto SETBELLTIME ; yes

BEL6:   swapf COUNT1,W
        iorwf COUNT0,W
        movwf BELLTIME
        movwf STORE1
        movlw 9
        call SETPRM
        call STORIT
        call WAITKEYRELEASE
        return

;............

CLRLINE1: call LCD1     ;set address for line 1 cell 1
        bsf RSLINE,4    ;set RS for data send
        clrf LOOP       ;
CLRL1:  movf LOOP,W     ;
        movlw ' '       ;clear cell
        call LCDOUT     ;
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto CLRL1      ;no
        return

CLRLINE2: call LCD21    ;set address for line 2 cell 1
        bsf RSLINE,4    ;set RS for data send
        clrf LOOP       ;
CLRL2:  movf LOOP,W     ;
        movlw ' '       ;clear cell
        call LCDOUT     ;
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto CLRL2      ;no
        return

;..............

CONTINUEENTRY: bcf INTCON,2 ; yes, clear timer flag
ENTRY2: btfss INTCON,2   ; has timer rollover occurred?
        goto ENTRY2      ; no
        bcf INTCON,2     ; yes, clear timer flag
        decfsz CLKCNT,F  ; no, decrement clock routine. Is it = 0?
        return
        movlw 25         ; reset start value of CLKCNT
        movwf CLKCNT     ; 23 used because of DEBOUNCE call in KEYPAD1 routine
        decf ENTRYDELAY,F  ; dec secs count
        return

;.............

; **** ASSESS ZONE LOGIC

ASSESSLOGIC: call LCD1       ;set LCD for line 1, cell 1
         bsf RSLINE,4     ;set LCD RS line high

        clrf LOOP       ;clear loop
ASL1:   movf LOOP,W     ;get table address
        call ZONELOGIC  ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto ASL1       ;no
        call CLRLINE2

ASL2: ;  movf PORTD,W
        call MONITOR
        movf ZONESVAL,W
        movwf STORE3

        call LCD21      ;set LCD for line 2, cell 1
        bsf RSLINE,4    ;set LCD RS line high
        movf STORE3,W
        movwf STORE1
        call SHOWZONE2

        call KEYPAD1
        movf KEYPRESS,W ; is keypress = 12 - cancel?
        xorlw '-'
        btfsc STATUS,Z
        return          ; yes

        movf KEYPRESS,W
        xorlw 'D'        ; is key = 15? - completion code number
        btfss STATUS,Z
        goto ASL2        ; no

        movf STORE3,W    ; store normal zone status
        movwf ZONENORMAL
        movwf STORE1
        movlw 10
        call SETPRM
        call STORIT
        return

; **** SHOW PRESET ZONE LOGIC

PRESETLOGIC: call LCD1  ;set LCD for line 1, cell 1
         bsf RSLINE,4   ;set LCD RS line high

        clrf LOOP       ;clear loop
SHL1:   movf LOOP,W     ;get table address
        call SHOWLOGIC  ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto SHL1       ;no
        call CLRLINE2

        call LCD21      ;set LCD for line 2, cell 1
        bsf RSLINE,4    ;set LCD RS line high
        movf ZONENORMAL,W
        movwf STORE1
        call SHOWZONE2
        call WAITKEYRELEASE

SHL2:   call KEYPAD1
        movf KEYPRESS,W ; is keypress = 12 - cancel?
        xorlw '-'
        btfss STATUS,Z
        goto SHL2
        return          ; yes

;******** BEYOND THIS POINT ITS ALL FOR KEYPAD 2 ASSOCIATED ROUTINES

;********* SET 2ND PIN CODE - via keypad 1

PINCODE2: call LCD1       ;set LCD for line 1, cell 1
         bsf RSLINE,4     ;set LCD RS line high

        clrf LOOP       ;clear loop
PINC2:  movf LOOP,W     ;get table address
        call PIN2MSG    ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto PINC2       ;no

        call CLRLINE2
        call LCD21      ;set LCD for line 2, cell 1
        bsf RSLINE,4    ;set LCD RS line high

        movlw PIN4
        movwf FSR
        clrf LOOP

PINC3:  call WAITKEYRELEASE
        call WAITKEYPRESS

        movf KEYPRESS,W
        xorlw '-'        ; is key = 12? - error in number so start again
        btfss STATUS,Z   ;
        goto PINC3A      ;
        movf LOOP,W      ; is LOOP = 0?
        btfss STATUS,Z
        goto PINCODE2    ; no, so clear and continue
        return           ; yes, so exit

PINC3A: movf KEYPRESS,W  ; is val greater than 11?
        xorlw 'D'        ; is it = 14?
        btfsc STATUS,Z
        goto PINC3       ; yes, so try again
        movf KEYPRESS,W  ; is val greater than 11?
        xorlw 'E'        ; is it = 15?
        btfsc STATUS,Z
        goto PINC3       ; yes, so try again

        movf KEYPRESS,W
        movwf INDF       ; no, store it into PINx and eeprom
        movwf STORE1     ; and send to LCD
        movf LOOP,W
        addlw 11
        call SETPRM
        movf KEYPRESS,W
        call LCDOUT
        incf FSR,F
        incf LOOP,F
        btfss LOOP,2
        goto PINC3

PINC4:  call WAITKEYRELEASE
        call WAITKEYPRESS
        movf KEYPRESS,W
        xorlw 'D'        ; is key = 16? - completion code number
        btfsc STATUS,Z
        goto PINC5       ; yes

        movf KEYPRESS,W
        xorlw '-'        ; is key = 12? - error in number so start again
        btfss STATUS,Z
        goto PINC4       ; no
        goto PINCODE2

PINC5:  call STORIT
        call WAITKEYRELEASE
        return

;******* CHECK PIN CODE2 ENTRY

PINENTRY2: call KEYPAD2   ; is key pressed?
        movf KEYPRESS2,W
        btfsc STATUS,Z
        return            ; no, so return

        movf KEYPRESS2,W      ; is keypress = pin number?
        xorwf PIN4,W
        btfss STATUS,Z
        goto CLOSE2

        call WAITKEYRELEASE2
        call WAITKEYPRESS2
        movf KEYPRESS2,W      ; is keypress = pin number?
        xorwf PIN5,W
        btfss STATUS,Z
        goto CLOSE2

        call WAITKEYRELEASE2
        call WAITKEYPRESS2
        movf KEYPRESS2,W      ; is keypress = pin number?
        xorwf PIN6,W
        btfss STATUS,Z
        goto CLOSE2

        call WAITKEYRELEASE2
        call WAITKEYPRESS2
        movf KEYPRESS2,W      ; is keypress = pin number?
        xorwf PIN7,W
        btfss STATUS,Z
        goto CLOSE2
        bsf PORTB,5          ; yes, so activate PORTB output RB5
        call WAITKEYRELEASE2
        movf ENTRYTIME2,W
        movwf ENTRYDELAY2
        movlw 25         ; reset start value of CLKCNT2
        movwf CLKCNT2
        return

CLOSE2: bcf PORTB,5          ; no, so clear PORTB output RB5
        return

;..........GET KEYPAD 2 VAL ROUTINE........

KEYPAD2: clrf KEYPRESS2
         movlw %00001111
         movwf PORTC
         movwf STORE
         nop              ;pause to allow PORTC to stabilise
;         comf PORTB,W     ;get & invert PORTB
         comf PORTD,W     ;get & invert PORTD
         movwf STORED
         swapf STORED,W   ; take bits 4-7
         andlw %00001111  ;isolate bits 0-3
         btfsc STATUS,Z   ;is result NOT zero (keys pressed)?
         return           ;no, so return to main prog

         movlw %10000000  ;yes, a key is pressed so get it
         movwf SWITCH1    ;initial val for RC4-7
         movlw 3          ;initial val for COL
         movwf COL
         clrf ROW         ;initial val for ROW

GETIT2:  comf SWITCH1,W   ;get and invert val for PORTC
         iorwf STORE,W
         movwf PORTC      ;output to PORTC
         nop              ;pause to allow PORTC to stabilise
;         comf PORTB,W     ;get and invert val from PORTB
         comf PORTD,W     ;get and invert val from PORTD
         movwf STORED
         swapf STORED,W   ; take bits 4-7
         andlw 15         ;isolate bits 0-3
         btfss STATUS,Z   ;is it zero?
         goto GET22       ;no, so goto analysis routine
         decf COL,F       ;dec col val
         bcf STATUS,C     ;clear carry flag
         rrf SWITCH1,F    ;divide RC7-4 val by 2
         movf SWITCH1,W   ;
         andlw %11110000
         btfss STATUS,C   ;is it zero?
         goto GETIT2      ;no, so continue loop
         return           ;yes, so return to main program

GET22:   movwf SWVAL      ;store PORTB val
         clrf ROW         ;clear row count
         clrf ROWNUM      ;clear row number count

GET23:   rrf SWVAL,F      ;rotate right PORTB store val
         btfsc STATUS,C   ;is carry flag set?
         goto SUMIT2      ;yes so key pressed, go & finish answer
         movlw 4
         addwf ROW,F      ;add matrix val to ROW count
         incf ROWNUM,F    ;inc row number count
         btfss ROWNUM,2
         goto GET23

SUMIT2:  movf ROW,W       ;sum up results to single answer
         addwf COL,W      ;add ROW to COL (total of 0-15)
         call VALUE
         movwf KEYPRESS2  ; store result into KEYPRESS
;         movwf KEYPRESS   ; store result into KEYPRESS
         call DEBOUNCE
         return           ;return to main program

WAITKEYRELEASE2:
WKR22:  call KEYPAD2         ; wait till key released
        movf KEYPRESS2,W
        btfss STATUS,Z
        goto WKR22
        return

WAITKEYPRESS2:
WKP22:  call KEYPAD2         ; wait till key pressed
        movf KEYPRESS2,W
        btfsc STATUS,Z
        goto WKP22
        return

;********* CHANGE ENTRY/EXIT TIME FOR KEYPAD 2

CHANGEENTRY2: call LCD1  ;set LCD for line 1, cell 1
         bsf RSLINE,4   ;set LCD RS line high

        clrf LOOP       ;clear loop
ENT22:  movf LOOP,W     ;get table address
        call ENTRYTIME  ;get message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,4    ;has last LCD letter been sent?
        goto ENT22       ;no

        call LCD5       ;set LCD for line 1, cell 5
        bsf RSLINE,4    ;set LCD RS line high
        movlw 'E'
        call LCDOUT
        movlw 'N'
        call LCDOUT
        movlw 'T'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        movlw 'Y'
        call LCDOUT
        movlw '2'
        call LCDOUT

        call CLRLINE2
        call LCD23      ;set LCD for line 2, cell 3
        bsf RSLINE,4    ;set LCD RS line high
        movlw ' '
        call LCDOUT
        movlw 'P'
        call LCDOUT
        movlw 'R'
        call LCDOUT
        movlw 'E'
        call LCDOUT
        movlw 'V'
        call LCDOUT
        movlw ' '
        call LCDOUT
        movf ENTRYTIME2,W
        movwf COUNT0
        call BIN2DEC

        movf DIGIT2,W
        addlw 48
        call LCDOUT
        movf DIGIT1,W
        addlw 48
        call LCDOUT

        call LCD21      ;set LCD for line 2, cell 1
        bsf RSLINE,4    ;set LCD RS line high

        call WAITKEYRELEASE
ENT23:  call WAITKEYPRESS ; get first value (tens)
        movf KEYPRESS,W ; is keypress = 12 - cancel?
        xorlw '-'
        btfsc STATUS,Z
        return          ; yes

        btfsc KEYPRESS,6 ; is it >= 'A'?
        goto ENT23        ; yes, so try again

        movf KEYPRESS,W
        andlw %00001111
        movwf COUNT1
        movwf COUNT2
        movf KEYPRESS,W
        call LCDOUT

        call WAITKEYRELEASE
ENT24:  call WAITKEYPRESS   ; get 2nd val (units)
        movf KEYPRESS,W ; is keypress = 12 - cancel?
        xorlw '-'
        btfsc STATUS,Z
        return          ; yes

        btfsc KEYPRESS,6 ; is it >= 'A'?
        goto ENT24        ; yes, so try again

        movf KEYPRESS,W
        andlw %00001111
        movwf COUNT0
        addwf COUNT1,W   ; is total = 0?
        btfsc STATUS,Z
        goto ENT24       ; yes, so try again

        movf KEYPRESS,W
        call LCDOUT

ENT25:  call WAITKEYRELEASE
        call WAITKEYPRESS
        movf KEYPRESS,W
        xorlw 'D'        ; is key = 15? - completion code number
        btfsc STATUS,Z
        goto ENT26       ; yes

        movf KEYPRESS,W
        xorlw '-'        ; is key = 12? - error in number so start again
        btfss STATUS,Z
        goto ENT25        ; no
        goto CHANGEENTRY2 ; yes

ENT26:  call WAITKEYRELEASE
        bcf STATUS,C
        rlf COUNT1,F     ; convert decimal to binary
        rlf COUNT1,F
        rlf COUNT1,W
        addwf COUNT2,W
        addwf COUNT2,W
        addwf COUNT0,W
        movwf ENTRYTIME2
        movf ENTRYTIME2,W
        movwf STORE1
        movlw 15
        call SETPRM
        call STORIT
        return

CONTINUEENTRY2: bcf INTCON,2 ; yes, clear timer flag
ENTRY22: btfss INTCON,2      ; has timer rollover occurred?
        goto ENTRY22         ; no
        bcf INTCON,2         ; yes, clear timer flag
        decfsz CLKCNT2,F     ; no, decrement clock routine. Is it = 0?
        return
        movlw 25             ; reset start value of CLKCNT
        movwf CLKCNT2
        decfsz ENTRYDELAY2,F ; dec secs count
        return
        bcf PORTB,5          ; clear entry 2 enable
        return

;........... PANIC ZONE .........

PANICSET: btfsc PORTB,PANIC    ; has RB4 called Panic interrupt ( = 0)?
        goto PSET2             ; no

        bsf ALARMSTATUS,PANIC  ; yes
        bsf ALARMSTATUS,7      ;
        bsf ALARMSTATUS,BELL   ; trigger bell etc
        bsf ALARMSTATUS,BUZZER
        bsf ALARMSTATUS,STROBE
        movlw %00000111
        movwf PORTE

        call LCD1              ;set address for line 1 cell 1
        bsf RSLINE,4           ;set RS for data send
        movf ZONESVAL,W
        movwf STORE1       ; store INTRUDED status
        call SHOWZONE
        movlw 'P'
        call LCDOUT

        clrf LOOP       ;clear loop
        bsf RSLINE,4    ;set RS for data send
PSET3:  movf LOOP,W     ;get table address
        call MESSAG2    ;get ENTRY message letter
        call LCDOUT     ;show it
        incf LOOP,F     ;inc loop
        btfss LOOP,3    ;has last LCD letter been sent?
        goto PSET3      ;no

        call CLRLINE2
        call CLKSHW
        clrf CLKSEC
        clrf CLKMIN
        clrf CLKHRS

        movf ALARMSTATUS,W          ; store ALARMSTATUS (but with bell off) to eeprom
        movwf STORE1
        bcf STORE1,BELL
        movlw 8
        call SETPRM

PSET2:  bcf INTCON,RBIF      ; clear RBIF flag
        return

        .END

