16x64 Dot Matrisin Pic yoluyla sürülmesi

Başlatan onuryldz, 20 Ağustos 2018, 17:05:29

onuryldz

Arkadaşlar merhaba elimde internette ne kadar arasam da hakkında bir döküman bulamadığım bir 16x64 dot matris(Red & Green) var. Ben bu matrisi pic yoluyla sürmek istiyorum. Ama bu dot matris Hub yapısında değil köşelerinde 14 pinli bağlantı noktaları var ve galiba kendi üzerinde sürücüsü yok. Öğrendiğim kadarıyla I2C haberleşmesi ile kullanılıyor ve elimde örnek(çalışıyor) asm kodu var asm kodu takvim ve saat işlevi görüyor. Bana yardım edebilir misiniz bu konu hakkında? En azında pin yapısı hakkında bile birşey öğrenebilsem bir yerlere gelebilirim belki.
Kod 3000 satırın üzerinde bu arada
Resimler




TITLE "2 line 8x8x8 dotmaxtix display with GPS and RTC"
 LIST p=18F452
 #include "p18f452.inc"

 CONFIG OSCS = OFF, OSC=HS,PWRT = ON,BOR = OFF,WDT = OFF
 CONFIG STVR = ON, LVP = OFF, DEBUG = OFF
 CONFIG CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF,CPB = OFF,CPD = OFF
 CONFIG WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF,WRTB = OFF,WRTD = OFF,WRTC = OFF
 CONFIG EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF ,EBTRB = OFF


myram UDATA
w_temp res 1
s_temp res 1
bsr_temp res 1
scan_row res 1
count res 1
l_data res 1
count1 res 1
col_indx res 1
temp1 res 1
temp2 res 1
temp_FSR res 1
TBL_temp1 res 1
TBL_temp2 res 1 ;double chr, shifting and placing FSR
bitwise res 1
sspcount res 1
sec res 1
min res 1
hou res 1
wday res 1
day res 1
month res 1
year res 1
col res 1
type res 1
nible res 1 
ssp_data res 1
ssp_mode res 1
int_num res 1
int_num2 res 1
temp3 res 1
ready res 1
m_count res 1
w_templ res 1
s_templ res 1
bsr_templ res 1
command res 1
t_dig1 res 1
t_dig2 res 1
t_dig3 res 1
h_dig1 res 1
h_dig2 res 1
rh1 res 1
rh0 res 1
aarg0 res 1
aarg1 res 1
barg0 res 1
barg1 res 1
res4 res 1
res3 res 1
res2 res 1
res1 res 1
t_res4 res 1
t_res3 res 1
t_res2 res 1
t_res1 res 1
ircom res 1
iradd res 1
ircount res 1
intgate res 1
mode res 1
num_data res 1
sec2 res 1
tdata res 1
ram_index res 1
imin res 1
isec res 1
t_diff res 1
eaddr res 1
pclath_t res 1
temper res 1
bcd res 1
bcd10 res 1
bcd1 res 1

cntmsec res 1
cntmsec2 res 1
cntmsec3 res 1
modindx res 1
max res 1
num_tim1 res 1
ir_stat res 1
infoindx res 1
info1 res 1
info2 res 1
info3 res 1
info4 res 1
info5 res 1
info6 res 1
comma_c res 1

group1 udata 0x177
led_gps res 1



#define _Z STATUS,Z
#define _N STATUS,N
#define _C STATUS,C
#define _LSB bitwise,0
#define BCD_C PORTA,3
#define BCD_B PORTA,5
#define BCD_A PORTE,0
#define CLK PORTE,2
#define STROBE PORTA,2
#define RED PORTA,1
#define GREEN PORTE,1
#define UDN PORTC,2
#define SSP_WR ssp_mode,0
#define SHT_DATA PORTB,1
#define SHT_CLK PORTB,3
#define IR_DATA PORTB,0
#define WAIT_TEMP ssp_mode,1
#define WAIT_HUMD ssp_mode,2
#define PROCESS ssp_mode,3
#define IR_S1 ir_stat,0
#define IR_S2 ir_stat,1
#define IR_TOG ir_stat,2
#define INT0_GATE intgate,0
#define IR_CODE ir_stat,3
#define IR_INFO ir_stat,4
#define UP_RTC mode,0
#define SETUP_M mode,1
#define SLEEP_M mode,2
#define ERR mode,4
#define GPS mode,5
#define STARTUP mode,6
#define IR_WAIT mode,4
#define COLOR PORTD,4 ;SW 4
#define GPS_TYP PORTD,5 ;SW 3;0 meinbercapture 1:NMEA
#define UTC ssp_mode,7
#define LOCAL_M ssp_mode,6
#define SUN_LIGHT ssp_mode,5
#define PLUS1 ssp_mode,4

 org 0x00
 bra MAIN

;high priority interrupt routine.
 org 0x08
 bra INTR_H
;low priority interrupt routine
 org 0x18
 bra INTR_L

;************MUST BE CHECKED*********************
MONTH11 addwf PCL
 nop
 retlw 'O' ;1 
 retlw 'S' ;2
 retlw 'M' ;3
 retlw 'N' ;4
 retlw 'M' ;5
 retlw 'H' ;6
 retlw 'T' ;7
 retlw 'A' ;8
 retlw 'E' ;9
 retlw 'E' ;10
 retlw 'K' ;
 retlw 'A' 
;************MUST BE CHECKED*********************
MONTH22 addwf PCL,f
 nop
 retlw 'C' 
 retlw 'B' 
 retlw 'R' 
 retlw 'I' 
 retlw 'A' 
 retlw 'A' 
 retlw 'E' 
 retlw 'G' 
 retlw 'Y' 
 retlw 'K' 
 retlw 'A' 
 retlw 'R' 
;************MUST BE CHECKED*********************
MONTH33 addwf PCL,f
 nop
 retlw 'K' 
 retlw 'T' 
 retlw 'T' 
 retlw 'S' 
 retlw 'Y' 
 retlw 'Z' 
 retlw 'M' 
 retlw 'U' 
 retlw 'L' 
 retlw 'M' 
 retlw 'S' 
 retlw 'A' 
;************MUST BE CHECKED*********************
WDAY11 addwf PCL,f
 nop
 retlw 'P' 
 retlw 'S' 
 retlw 'C' 
 retlw 'P' 
 retlw 'C' 
 retlw 'C' 
 retlw 'P' 
;************MUST BE CHECKED*********************
WDAY22 addwf PCL,f
 nop
 retlw 'A' 
 retlw 'A' 
 retlw 'A' 
 retlw 'E' 
 retlw 'U' 
 retlw 'U' 
 retlw 'A' 
;************MUST BE CHECKED*********************
WDAY33 addwf PCL,f
 nop
 retlw 'Z' 
 retlw 'L' 
 retlw 'R' 
 retlw 'R' 
 retlw 'M' 
 retlw 'M' 
 retlw 'Z' 
;************MUST BE CHECKED*********************
WDAY44 addwf PCL,f
 nop
 retlw 'R' 
 retlw 'I' 
 retlw 'S' 
 retlw 'S' 
 retlw 'A' 
 retlw 'R' 
 retlw 'A' 
;************MUST BE CHECKED*********************
WDAY55 addwf PCL,f
 nop
 retlw 'T' 
 retlw ' ' 
 retlw 'M' 
 retlw 'M' 
 retlw ' ' 
 retlw 'T' 
 retlw 'R' 
MONTH1 btfss month,4
 bra _MO11
 movlw D'6'
 subwf month,w
_MO11 movwf temp3
 rlncf temp3,w
 rcall MONTH11
 return
MONTH2 btfss month,4
 bra _MO22
 movlw D'6'
 subwf month,w
_MO22 movwf temp3
 rlncf temp3,w
 rcall MONTH22
 return
MONTH3 btfss month,4
 bra _MO33
 movlw D'6'
 subwf month,w
_MO33 movwf temp3
 rlncf temp3,w
 rcall MONTH33
 return
WDAY1 movwf temp3
 rlncf temp3,w
 rcall WDAY11
 return
WDAY2 movwf temp3
 rlncf temp3,w
 rcall WDAY22
 return
WDAY3 movwf temp3
 rlncf temp3,w
 rcall WDAY33
 return
WDAY4 movwf temp3
 rlncf temp3,w
 rcall WDAY44
 return
WDAY5 movwf temp3
 rlncf temp3,w
 rcall WDAY55
 return

 org 0x200
MAX_T addwf PCL,f
 retlw 0x04 ;day
 retlw 0x0a ;
 retlw 0x02 ;month
 retlw 0x0a ;
 retlw 0x0a ;year
 retlw 0x0a ;
 retlw 0x03 ;hour
 retlw 0x0a ;
 retlw 0x06 ;min
 retlw 0x0a ;
 retlw 0x06 ;sec
 retlw 0x0a ;
 retlw 0x08 ;wday

TB_MO addwf PCL,f
 nop
 retlw 0x32 ;Ocak 
 retlw 0x29 ;Şubat
 retlw 0x32 ;Mart
 retlw 0x31 ;Nisan
 retlw 0x32 ;Mayis
 retlw 0x31 ;Haziran 
 retlw 0x32 ;Temmuz
 retlw 0x32 ;Agustos
 retlw 0x31 ;Eylül
 nop
 nop
 nop
 nop
 nop
 nop
 retlw 0x32 ;Ekim
 retlw 0x31 ;Kasım
 retlw 0x32 ;Aralık

TB_MO2 movff PCLATH,pclath_t
 movlw 0x02
 movwf PCLATH
 rlncf res2,w
 rcall TB_MO
 movff pclath_t,PCLATH
 return
TB_MO1 movff PCLATH,pclath_t
 movlw 0x02
 movwf PCLATH
 rlncf month,w
 rcall TB_MO
 movff pclath_t,PCLATH
 return
;SETUP MODE cursor position
; D    D  -  M  M  -  Y  Y  Y  Y
; 0    6  0c 12  18  1e  24  2a  30  36
;+41
; 41  47  4d 53  59  5f  65  6b  71  77
; H    H  :  M  M    :  S  S  T  T  C
; 0    6  b  10  16  1b  20  26  2f  35  3b
SET_T addwf PCL,f
 retlw 0x41 ;modindx is 0
 retlw 0x47 ;modindx is 1
 retlw 0x53 ;modindx is 2,month
 retlw 0x59 ;modindx is 3
 retlw 0x71 ;modindx is 4,year
 retlw 0x77 ;modindx is 5
 retlw 0x00 ;modindx is 6,hour 
 retlw 0x06 ;modindx is 7
 retlw 0x10 ;modindx is 8,min
 retlw 0x16 ;modindx is 9
 retlw 0x20 ;modindx is 10,sec
 retlw 0x26 ;modindx is 11
 retlw 0x35 ;modindx is 12,wday

SET_TA movff PCLATH,pclath_t
 movlw 0x02
 movwf PCLATH
 rlncf modindx,w
 rcall SET_T
 movff pclath_t,PCLATH
 return
MAX_TA movff PCLATH,pclath_t
 movlw 0x02
 movwf PCLATH
 rlncf modindx,w
 rcall MAX_T
 movff pclath_t,PCLATH
 return

INTR_H movwf w_temp
 movff STATUS,s_temp
 movff BSR,bsr_temp
 btfsc PIR1,SSPIF
 call SSP_INT
 btfsc PIR1,TMR1IF
 rcall INT_TMR1
 btfsc INTCON,INT0IF
 rcall INT_INT0
 btfsc PIR1,RCIF
 call RXFUNC

 movff bsr_temp,BSR
 movf w_temp,w
 movff s_temp,STATUS 
 retfie

INTR_L movwf w_templ
 movff STATUS,s_templ
 movff BSR,bsr_templ
 btfsc INTCON,TMR0IF
 rcall INT_TMR0
 btfsc INTCON3,INT1IF
 rcall INT_INT1
 btfsc PIR1,ADIF
 call INT_ADC
 movff bsr_templ,BSR
 movf w_templ,w
 movff s_templ,STATUS 
 retfie

INT_TMR1 
;889+889=1778usn (22Ba),, 0x10000-0x22ba=dd46 for 1778usn
 movlw 0xdd
 movwf TMR1H
 movlw 0x46
 movwf TMR1L
;a0->S1 bit, a1->S2 bit, a2->T bit
;a3->ADDRESS1,a4->ADDRESS2,a5->ADDRESS3,a6->ADDRESS4,a7->ADDRESS5,
 movlw 0xa0
 cpfseq ircount
 bra _NIRA0
;ircount is oxa0 so it means getting first start bit S1
 btfss IR_DATA 
 bsf IR_S1 ;if IR_DATA=0
 incf ircount,f
 bra _ENDTMR1
_NIRA0 movlw 0xa1
 cpfseq ircount
 bra _NIRA1
;ircount is oxa1 so it means getting second start bit S2
 btfss IR_DATA 
 bsf IR_S2 ;if IR_DATA=0
 incf ircount,f
 bra _ENDTMR1
_NIRA1 movlw 0xa2
 cpfseq ircount
 bra _NIRA2
;ircount is 0xa2 so it means getting toggle bit TOG
 btfss IR_DATA 
 bsf IR_TOG ;if IR_DATA=0
 incf ircount,f
 bra _ENDTMR1
_NIRA2 movlw 0xa8
 cpfslt ircount
 bra _NIRADDR
;Address information
 bcf _C
 btfss IR_DATA
 bsf _C
 rlcf iradd,f
 incf ircount,f
 bra _ENDTMR1
_NIRADDR 
;IR Code Information
 bcf _C
 btfss IR_DATA
 bsf _C
 rlcf ircom,f
 incf ircount,f
;a8->D1,a9->D2,aa->D3,ab->D4,ac->D5,ad->D6,
 movlw 0xae
 cpfseq ircount
 bra _ENDTMR1
;ircount is 0xae so it means IR data has been recevied completely 

 btfss IR_S1
 bra _ENDTMR2
 btfss IR_S2
 bra _ENDTMR2
 
 lfsr FSR2,0x170
 btfsc IR_TOG
 bsf iradd,7
 btfsc IR_S1
 bsf iradd,6
 btfsc IR_S2
 bsf iradd,5

 movff iradd,POSTINC2
 movff ircom,POSTINC2
 bsf IR_CODE ;IR CODE detected
 rcall IRCOMMD
 
_ENDTMR2 bcf T1CON,TMR1ON ;Timer1 OFF
 bsf IR_WAIT
 clrf num_tim1
 bra _ENDTMR1

_ENDTMR1 bcf PIR1,TMR1IF
 return

;****************************************************************
;Vestel Remote control RC-5 protocol
;IR Command has been Received
IRCOMMD movlw 0x0c
 cpfseq ircom
 bra _IRN0C
;Turn off / Turn on 
 btg SLEEP_M
 bra _ENDCOMD
_IRN0C movlw 0x35
 cpfseq ircom
 bra _IRN35
;OK button so set or quit SETUP_M mode
 btfss SETUP_M
 bra _NSETMODE
;setup mode quiting
 movlw 0xfe
 movwf ircom ;0xFE is QUIT MODE
 return
_NSETMODE movlw 0xfd ;0xFD is ENTERING SETUP MODE
 movwf ircom
 bsf SETUP_M
 return ;clear SETUP_M
;Direction
_IRN35 movlw 0x16
 cpfseq ircom
 bra _IRN16
;Right (0x16)
 incf modindx,f
 movlw D'13'
 cpfseq modindx
 bra _ENDCOMD
 clrf modindx
 bra _ENDCOMD
_IRN16 movlw 0x15
 cpfseq ircom
 bra _IRN15
;Left (0x15)
 movf modindx,w
 btfss _Z
 bra _NMOD0
;modindx is 0
 movlw D'12'
 movwf modindx
 bra _ENDCOMD
_NMOD0 decf modindx,f
 bra _ENDCOMD
_IRN15 movlw 0x14
 cpfseq ircom
 bra _IRN14
;Up (0x15)
 clrf modindx
 bra _ENDCOMD
_IRN14 movlw 0x13
 cpfseq ircom
 bra _IRN13
;Down (0x13)
 movlw D'06'
 movwf modindx
 bra _ENDCOMD
_IRN13 return

_ENDCOMD bcf IR_CODE
 return

;*************************************************************
INT_INT0 btfsc GPS
 bra _ENDINT0
 btfss INT0_GATE
 bra _ENDINT0

;Ir Start has been dedected
 bcf INTCON,INT0IE ;INT0 Disable
 bcf INT0_GATE
;so start timer1 for 445usn for first Start bit (S1)
 movlw 0xF7 ;10000-f74f=8b1*0,2 (20MHz)=445usn
 movwf TMR1H
 movlw 0x4f
 movwf TMR1L
 movlw B'00000001'
 movwf T1CON ;Timer1 is ON
 bcf PIR1,TMR1IF
 bsf PIE1,TMR1IE
 bsf IPR1,TMR1IP
 clrf ircom
 clrf iradd
 bcf IR_S1
 bcf IR_S2
 bcf IR_TOG
;a0->S1 bit, a1->S2 bit, a2->T bit
;a3->ADDRESS1,a4->ADDRESS2,a5->ADDRESS3,a6->ADDRESS4,a7->ADDRESS5,
 movlw 0xa0 
 movwf ircount
_ENDINT0 bcf INTCON,INT0IF
 return

INT_INT1 
 btfss WAIT_TEMP
 bra _NW_TEMP
;temperature data is ready
 call SHT_TEMP2
 bra _ENDINT1
_NW_TEMP btfss WAIT_HUMD
 bra _ENDINT1
;humudity data is ready
 call SHT_HUMD2
 bra _ENDINT1

_ENDINT1 bcf INTCON,INT1IF
 return 

SEND_ACK1 bcf TRISB,1
 bsf SHT_DATA
 nop
 bsf SHT_CLK
 nop
 bcf SHT_CLK
 return

SEND_ACK bcf TRISB,1
 bcf SHT_DATA
 nop
 bsf SHT_CLK
 nop
 bcf SHT_CLK
 return

READ_SHT bsf TRISB,1
 clrf command
 movlw 0x08
 movwf m_count
_READ1 bcf _C
 bsf SHT_CLK
 btfsc SHT_DATA
 bsf _C
 rlcf command,f
 bcf SHT_CLK
 decfsz m_count,f
 bra _READ1
 return
;*********************************************************
;input modindx
FLASH btfss SETUP_M
 return
 movf int_num,w
 bz _FLASH1
 return
;SETUP MODE and int_num is zero
_FLASH1 movf int_num2,w
 bnz _FLASH2
;int_num2 is zero
 btfsc IR_INFO
 bra _FL_INFO
 movf modindx,w
 call SET_TA
 movwf temp1
 movwf temp2
 movlw 0x07
 andwf temp2,f
;for example modindx is 0; W is 41; temp1 is 41, temp2 is 1,temp_FSR is 108
 lfsr FSR0,0x170
 movlw 0xf8
 andwf temp1,f
 rrncf temp1,f
 rrncf temp1,f
 rrncf temp1,w
 addwf FSR0L,f
 movff FSR0L,temp_FSR ;save FSRL
 movlw 0x00
 cpfseq temp2
 bra _FLAN0
;temp2 is 0
 movlw B'11111000'
 movwf POSTINC0
 return
_FLAN0 movlw 0x01
 cpfseq temp2
 bra _FLAN1
;temp2 is 1
 movlw B'01111100'
 movwf POSTINC0
 return
_FLAN1 movlw 0x02
 cpfseq temp2
 bra _FLAN2
;temp2 is 2
 movlw B'00111110'
 movwf POSTINC0
 return
_FLAN2 movlw 0x03
 cpfseq temp2
 bra _FLAN3
;temp2 is 3
 movlw B'00011111'
 movwf POSTINC0
 return
_FLAN3 movlw 0x04
 cpfseq temp2
 bra _FLAN4
;temp2 is 4
 movlw B'00001111'
 movwf POSTINC0
 movlw B'10000000'
 movwf POSTINC0
 return
_FLAN4 movlw 0x05
 cpfseq temp2
 bra _FLAN5
;temp2 is 5
 movlw B'00000111'
 movwf POSTINC0
 movlw B'11000000'
 movwf POSTINC0
 return
_FLAN5 movlw 0x06
 cpfseq temp2
 bra _FLAN6
;temp2 is 6
 movlw B'00000011'
 movwf POSTINC0
 movlw B'11100000'
 movwf POSTINC0
 return
_FLAN6 
;temp2 is 7
 movlw B'00000001'
 movwf POSTINC0
 movlw B'11110000'
 movwf POSTINC0
 return
_FL_INFO movf infoindx,w
 bnz _FLN00
;infoindx is 0 so it is info1 and at 00
 lfsr FSR0,0x170
 movlw B'11111000'
 movwf POSTINC0
 return
_FLN00 movlw 0x01
 cpfseq infoindx
 bra _FLN01
;infoindx is 1 so it is info2 and at 06
 lfsr FSR0,0x170
 movlw B'00000011'
 movwf POSTINC0
 movlw B'11100000'
 movwf POSTINC0
 return
_FLN01 movlw 0x02
 cpfseq infoindx
 bra _FLN02
;infoindx is 2 so it is info3 and at 0c
 lfsr FSR0,0x171
 movlw B'00001111'
 movwf POSTINC0
 movlw B'10000000'
 movwf POSTINC0
 return
_FLN02 movlw 0x03
 cpfseq infoindx
 bra _FLN03
;infoindx is 3 so it is info4 and at 12
 lfsr FSR0,0x172
 movlw B'00111110'
 movwf POSTINC0
 return
_FLN03 movlw 0x04
 cpfseq infoindx
 bra _FLN04
;infoindx is 4 so it is info5 and at 18
 lfsr FSR0,0x173
 movlw B'11111000'
 movwf POSTINC0
 return
_FLN04 
;infoindx is 5 so it is info6 and at 1e
 lfsr FSR0,0x173
 movlw B'00000011'
 movwf POSTINC0
 movlw B'11100000'
 movwf POSTINC0
 return

_FLASH2
;intnum is 0 but int_num2 is not. so check int_num2 is 60 or not
 movlw D'60'
 cpfseq int_num2
 return ;not 60
;yes it is 60 so clear FLASH Line
 lfsr FSR0,0x170
_FLASH3 clrf INDF0
 incf FSR0L,f ;clear from 170-17f
 btfss FSR0L,7 
 bra _FLASH3
 return 
;*********************************************************
;TMR0 interrupt routine
INT_TMR0 btfss RCSTA,OERR
 bra _NOERR
;overrun error has accured
 clrf RCSTA
 movlw 0x90
 movwf RCSTA
_NOERR rcall FLASH
 btfss IR_WAIT
 bra _NOTWAIT
 incf num_tim1,f
 movf num_tim1,w
 bnz _NOTWAIT
 bcf IR_WAIT
 bcf INTCON,INT0IF
 bcf INTCON2,INTEDG0
 bsf INTCON,INT0IE
 bsf INT0_GATE
 bcf INTCON2,INTEDG0 ;INT0 Falling Edge
_NOTWAIT incf int_num,f
 btfss int_num,2
 goto _INT1
 clrf int_num
 incf int_num2,f
 movlw D'153'
 cpfseq int_num2
 bra _INT1
 clrf int_num2
 btfsc SETUP_M
 bra _INT1
;testing GPS
 movlw 0x01
 movwf BSR
 clrf led_gps
 clrf BSR
 lfsr FSR0,0x177
 clrf INDF0
 btfss GPS
 bra _GPSNP ;GPS is not present
;GPS is present
 incf sec2,f
 movlw 0x03
 cpfseq sec2
 bra _INT1
;GPS has gone
 bcf GPS
_GPSNP incf sec,w
 daw
 movwf sec
 movlw 0x01
 movwf BSR
 movlw 0x01
 movwf led_gps
 clrf BSR
 call SECOND
 movlw 0x60
 cpfseq sec
 bra _INT1
;start reading date from DS1307
; clrf sec
 clrf sspcount
 bcf SSP_WR 
 movlw 0x07
 movwf ssp_data
 bsf SSPCON2,SEN
 lfsr FSR2,0x08f
 bra _END_TMR0
_INT1 rcall SCAN
 bsf UDN ;UDN off
 bsf STROBE
 bcf STROBE
 bcf BCD_C
 bcf BCD_B
 bcf BCD_A
 btfsc scan_row,0
 bsf BCD_A
 btfsc scan_row,1
 bsf BCD_B
 btfsc scan_row,2
 bsf BCD_C
 btfss SLEEP_M
 bcf UDN ;UDN on
 incf scan_row,f
 btfsc scan_row,3
 clrf scan_row

_END_TMR0 bcf INTCON,TMR0IF
 return
;*******************************************************
;MEMORY 
;1.LINE :08h....0fh scan_row is 0
; :18h....1fh scan_row is 1
; :78h....7fh scan_row is 7 
;2.LINE :00h....07h scan_row is 0
; :10h....17h scan_row is 1
; :70h....77h scan_row is 7
;COLOM NUMBERs
;1.LINE :40...7f
;2.LINE :00...3f 
SCAN 
 movlw 0x10
 movwf count1
 mulwf scan_row
 movff PRODL,FSR1L
 movlw 0x01
 movwf FSR1H
_SCAN1 movf POSTINC1,w
 movwf l_data
 rcall SER_P
 decfsz count1,f
 bra _SCAN1
;scan complated
 return

SER_P
 bra SER_PR ;only red

 movlw 0x10 
 CPFSGT count1 ;count1 >10
 bra SER_P2 ;GREEN
 movlw 0x18 
 CPFSGT count1
 bra SER_PR ;RED
;Yellow
 movlw 0x08
 movwf count
_SERP1 bcf CLK
 bcf RED
 bcf GREEN
 rlcf l_data,f
 btfsc _C
 bsf RED
 btfsc _C
 bsf GREEN
 bsf CLK
 decfsz count,f
 bra _SERP1
 return

SER_PR movlw 0x08
 movwf count
_SERPR bcf CLK
 bcf RED
 bcf GREEN
 rlcf l_data,f
 btfsc _C
 bsf RED
 bsf CLK
 decfsz count,f
 bra _SERPR
 return

SER_P2 movlw 0x08
 movwf count
_SERP2 bcf CLK
 bcf RED
 bcf GREEN
 rlcf l_data,f
 btfsc _C
 bsf GREEN
 bsf CLK
 decfsz count,f
 bra _SERP2
 return

SSP_INT
;testing Stop Condition
_COUNA btfss SSPSTAT,P
 bra _SSPNP
;Stop has been detected
 movlw 0x03
 movwf ready
 bra _ENDSSP 

;testing end of ssp data
_SSPNP movf ssp_data,w
 bnz _NEODATA
 bsf SSPCON2,PEN
; movlw 0x03
; movwf ready 
 bra _ENDSSP
_NEODATA btfss SSP_WR ;WR Mode?
 bra SSP_READ
;Writing mode
;sspcount 1: Start, 2:D0, 3:00, 4:sec, 5:min, 6:hour, 7:wday, 8:day, 10:month, 11:year, 12:control 
 incf sspcount,f
 movlw 0x01
 cpfseq sspcount
 bra SSPN01W
 movlw 0xD0
 movwf SSPBUF
 bra _ENDSSP
SSPN01W movlw 0x02
 cpfseq sspcount
 bra SSPN02W
 clrf SSPBUF
 bra _ENDSSP
SSPN02W movf POSTINC2,w ;7:sec
 movwf SSPBUF
 decf ssp_data,f
 bra _ENDSSP 

SSP_READ movlw 0x02
 cpfseq sspcount
 bra SSPN002
 movlw 0xf2
 movwf sspcount
 bra _CONTSSP
SSPN002 movlw 0xF3
 cpfseq sspcount
 bra _CONTSSP
 movlw 0x02
 movwf sspcount
_CONTSSP incf sspcount,f
 
;Reading mode
;sspcount 1: Start, 2:D0, 3:00, 4:D1, 5:sec, 6:min, 7:hour, 8:wday, 9:day, 10:month, 11:year, 12:control 
 movlw 0x01
 cpfseq sspcount
 bra SSPN01
 movlw 0xD0
 movwf SSPBUF
 bra _ENDSSP
SSPN01 movlw 0x02
 cpfseq sspcount
 bra SSPN02
 clrf SSPBUF
 bra _ENDSSP
SSPN02 movlw 0xF3
 cpfseq sspcount
 bra SSPNF3
 bsf SSPCON2,RSEN
 bra _ENDSSP

SSPNF3 movlw 0x03
 cpfseq sspcount
 bra SSPN03
 movlw 0xD1
 movwf SSPBUF
 bra _ENDSSP
SSPN03 btfss SSPSTAT,BF ;buffer full?
 bra B_FREE
;Buffer full
; movff ssp_data,POSTINC2
 movf SSPBUF,w
 movwf POSTINC2
 decfsz ssp_data,f
 bra _SSPDN0
;ssp_data is 0 so ACK=1
 bsf SSPCON2,ACKDT
 bsf SSPCON2,ACKEN
 bra _ENDSSP
_SSPDN0
;ssp_data is not 0 so ACK=0
 bcf SSPCON2,ACKDT
 bsf SSPCON2,ACKEN
 bra _ENDSSP
B_FREE bsf SSPCON2,RCEN
 bra _ENDSSP
 
_ENDSSP 
 bcf PIR1,SSPIF
 return
;************READ EEPROM***********************
;INPUT addr
;OUTPUT W (Eprom data)
RD_EE movff eaddr,EEADR
 bcf EECON1,EEPGD
 bcf EECON1,CFGS
 bsf EECON1,RD
 movf EEDATA,w
 return

;**********************************************
;INPUT W:first address of data series
;OUTPUT :fill eyear, emonth,eday,ehour,et_diff
;eyear-res1,emonth-res2,eday-res3,ehour-res4,et_diff-t_res1
ETIME movwf eaddr
 rcall RD_EE
 movwf res1 ;eyear
 incf eaddr,f
 rcall RD_EE
 movwf res2 ;emonth
 incf eaddr,f
 rcall RD_EE
 movwf res3 ;eday
 incf eaddr,f
 rcall RD_EE
 movwf res4 ;ehour
 incf eaddr,f
 rcall RD_EE
 movwf t_res1 ;et_diff
 return 

;it is assumed that it is local time
ADJ_L bcf STARTUP
 call F_WDAY
 bcf INTCON,GIEH
 bcf INTCON,GIEL
;if SUNLIGHT SAVING is active calculate
; otherwise LOCAL time = UTC +2 +PLUS1
 btfsc SUN_LIGHT
 bra _SUN_ACTV
;SUN LIGHT SAVING OFF
 movlw 0x02
 movwf t_diff
 btfsc PLUS1
 incf t_diff,f
 return
_SUN_ACTV clrf count
_ADJ1 movlw 0x05
 mulwf count
 movf PRODL,w
 movwf temp3
 call ETIME 
;if(year==eyear) check month and so on
;if(year>eyear) set t_diff
;if(year<eyear) return
 movf year,w
 cpfseq res1 ;eyear
 bra _YNEQ 
;year==eyear, compare emonth and month
 movf month,w
 cpfseq res2
 bra _MNEQ
;mount==emonth
 movf day,w
 cpfseq res3
 bra _DNEQ
;day==eday(res3)
 movf hou,w
 cpfseq res4
 bra _HNEQ 
;hou==ehour(res4)
 bra SET_DI

_HNEQ movf hou,w
 cpfslt res4
 bra _ADJ2
;hou>ehour
 bra SET_DI

_DNEQ movf day,w
 cpfslt res3
 bra _ADJ2
;day>eday(res3)
 bra SET_DI

_MNEQ movf month,w
 cpfslt res2
 bra _ADJ2
;mount>emount(res2)
 bra SET_DI

_YNEQ movf year,w
 cpfslt res1 
 bra _ADJ2 ;year<eyear (RETURN)
;eyear(res1) is little than year year>eyear
SET_DI movff t_res1,t_diff
 incf count,f
 decf imin,f ;for refresh display
 bra _ADJ1

_ADJ2 bsf INTCON,GIEH
 bsf INTCON,GIEL
 return

;**********************************************************
;A/D Conversiton
;**********************************************************
ADC_C movlw B'00000001' ;Fosc/2, chn:0,ADON
 movwf ADCON0
 bcf PIR1,ADIF
 bsf PIE1,ADIE
 bcf IPR1,ADIP ;A/D Low Priority interrupt
 bsf ADCON0,GO_DONE
 return

;Anolog Digital convertion is done
;VDD is assumed 5.12V
;if 1024 bit represent 5.12V then 10mv will be 2 bit
INT_ADC movf ADRESL,w
 movwf temper
; movlw 0x04
; addwf temper ;compansate diff from 5.12 - 4.90V
 bcf _C
 rrcf temper,f ; divide by 2
 bcf PIR1,ADIF
 bcf PIE1,ADIE ;Disable A/D Interrupt
 return
;BCD convertion
;input W
_BCD movwf bcd
 clrf bcd10
 clrf bcd1
 movlw 0x0a
_SUBAG subwf bcd,f
 btfss STATUS,C
 bra _BCD2
 incf bcd10,f
 bra _SUBAG
_BCD2 addwf bcd,w
 movwf bcd1
 return

MAIN call INIT

 bcf UDN
 bcf STROBE 
 clrf scan_row
 rcall CLR_MAP
 clrf ready
 clrf ram_index
 movlw B'10010000' ;SPEN, CREN
 movwf RCSTA 
 movlw D'23'
 btfsc GPS_TYP ;if 1; NMEA,, 
 movlw D'60'
 movwf num_data
 clrf m_count
 bcf WAIT_TEMP
 bcf WAIT_HUMD
 bcf PROCESS
 bsf STARTUP
 bcf UP_RTC
 bcf SLEEP_M
 bcf SETUP_M
 bcf GPS
 clrf sec2
 movlw 0xff
 movwf imin
 movwf isec
 clrf t_diff
;Setting up INT0 for dedection of IR codes
;sony device first start 2.4msn
 bcf INTCON2,INTEDG0
 bsf INTCON,INT0IE
 bsf INT0_GATE
 bcf INTCON2,INTEDG0 ;INT0 Falling Edge
 bcf IR_WAIT
 bcf IR_CODE
 bcf IR_INFO
 clrf info1
 clrf info2
 clrf info3
 clrf info4
 clrf info5
 clrf info6

 movlw 0x55
 movwf sec
 movlw 0x04
 movwf min
 movlw 0x16
 movwf hou
 movlw 0x01
 movwf wday
 movlw 0x01
 movwf day
 movlw 0x11
 movwf month
 movlw 0x13
 movwf year

;DIP switches
 bcf LOCAL_M
 bcf UTC
 bcf SUN_LIGHT
 bcf PLUS1
 movf PORTD,w
 andlw B'11000000'
 movwf info1
 movlw 0x00
 cpfseq info1
 bra _SWN0
;PORTD7:6 switches is 00
;UTC MODE
 bsf UTC
 goto _END_SW
_SWN0 movlw B'01000000'
 cpfseq info1
 bra _SWN01
;PORT7:6 switches is 01 
;LOCAL MODE,SUNLIGHT SAVING ON
 bsf LOCAL_M
 bsf SUN_LIGHT
 bra _END_SW
_SWN01 movlw B'10000000'
 cpfseq info1
 bra _SWN10
;PORTD7:6 switches is 10
;LOCAL MODE,SUNLIGHT SAVING OFF,UTC+2
 bsf LOCAL_M
 bra _END_SW
_SWN10 movlw B'11000000'
 cpfseq info1
 bra _END_SW
;LOCAL MODE,SUNLIGHT SAVING OFF,UTC+3
 bsf LOCAL_M
 bsf PLUS1
;if LOCAL is active calculate time diffirence
_END_SW 
; btfsc LOCAL_M
; call ADJ_L
;WRITING RTC
; bsf UP_RTC
; bsf SSP_WR
; bcf INT0_GATE 
; clrf sspcount
; movlw 0x08
; movwf ssp_data
; bsf SSPCON2,SEN
; lfsr FSR2,0x08f
; clrf ready

;_WRLOOP nop
; bra _WRLOOP


 rcall CLR_MAP
 bcf INTCON,GIEL
 call STU_MAP
 clrf ready
 bsf INTCON,GIEL

M_LOOP2 btfss UP_RTC
 bra _NUPRTC
;UP_RTC has been set, it means RTC is going to set by GPS
 movlw 0x03
 cpfseq ready
 bra M_LOOP2 ;UP_RTC is set;ready not 3
;ready is 3 and UP_RTC is set
 clrf ready
 bcf UP_RTC
 clrf RCSTA
 movlw B'10010000' ;SPEN, CREN
 movwf RCSTA 
 bcf PIR1,RCIF
 bsf PIE1,RCIE
 bra M_LOOP2
_NUPRTC movlw 0x45
 cpfseq sec
 bra _SECN45
 bsf PROCESS
 call ADC_C
_SECN45 movlw 0x01
 cpfseq ready
 bra _RN01
;ready is 1 when data is taken from GPS Receiver
 clrf ready
 movf imin,w
 cpfseq min
 bra _NMINSAME
;min=imin so write only second
 bcf INTCON,GIEL
 bcf INTCON,GIEL
 call SECOND
 bsf INTCON,GIEL
 bsf INTCON,GIEH
 bra M_LOOP2 
_NMINSAME movff min,imin
 btfsc STARTUP
 rcall ADJ_L
 rcall CLR_MAP
 bcf INTCON,GIEL
 call STU_MAP
 clrf ready
 bsf INTCON,GIEL
 bra M_LOOP2 
;check SETUP MODE
_RN01 btfsc SETUP_M
 bra _SETMODE
 movlw 0x03
 cpfseq ready
 bra M_LOOP2 

 rcall CLR_MAP
 bcf INTCON,GIEL
 call STU_MAP
 clrf ready
 bsf INTCON,GIEL

 bra M_LOOP2

_SETMODE btfss IR_CODE
 bra _SETMODE
 movlw 0x12
 cpfseq ircom
 bra _IRN12
;ircode is INFO
 btfss IR_INFO
 bra _IRINFO0
;IR_INFO is HIGH so it means still in INFO MODE
 bcf IR_CODE
 bcf IR_INFO
 bcf INTCON,GIEL
 rcall CLR_MAP
 call STU_MAP2
 clrf ready
 bsf INTCON,GIEL
 bra _SETMODE

;IR_INFO is LOW so Entering INFO MODE
_IRINFO0 bsf IR_INFO
 rcall INFO1
 bra _ILLEGAL
 
_IRN12 movlw 0xfe
 cpfseq ircom
 bra _IRNFE
;ircom is 0xfe QUIT SETUP MODE
 bcf SETUP_M
 bcf IR_CODE
;WRITING RTC
 bsf SSP_WR
 bcf INT0_GATE 
 clrf sspcount
 movlw 0x08
 movwf ssp_data
 bsf SSPCON2,SEN
 lfsr FSR2,0x08f
 clrf ready
 bra _RN01

_IRNFE movlw 0xfd
 cpfseq ircom
 bra _IRNFD
;ircom is 0xfd Setup mode initiate
 clrf modindx
 bcf INTCON,GIEL
 rcall DISASM
 call CLR_MAP
 call STU_MAP2 ;setup screen
 bsf INTCON,GIEL
 bra _ILLEGAL
_IRNFD movlw 0x0d
 cpfseq ircom
 bra _IRN0D
;ircom is 0x0d (MUTE) it means quit from setup mode without saving
 bcf SETUP_M
 movlw 0x59
 movwf sec
 bcf IR_CODE
 bra M_LOOP2
;check that ircom is a numeric
_IRN0D movlw 0x0a
 cpfslt ircom
 bra _MENU
;numeric, to find max value for each  modindx
 btfss IR_INFO
 bra _IRNINFO
;numeric value but it is in INFO MODE
 lfsr FSR0,0x0d1 ;info1
 movf infoindx,w
 addwf FSR0L,f
 movff ircom,POSTINC0
 incf infoindx,f
 bcf INTCON,GIEL
 rcall CLR_2LIN ;cleaning second line
 rcall STU_2LIN ;filling second line
 bsf INTCON,GIEL
 bra _ILLEGAL
_IRNINFO movf modindx,w
 call MAX_TA
 movwf max
 cpfslt ircom
 bra _ILLEGAL
;ircom is smaller than max
 lfsr FSR0,0x200
 movf modindx,w
 addwf FSR0L,f
 movff ircom,INDF0
 incf modindx,f
 movlw D'13'
 cpfseq modindx
 bra _IRNF01
 clrf modindx
_IRNF01 bcf INTCON,GIEL
 rcall ASM_TIME
 call CLR_MAP
 call STU_MAP2 ;setup screen
 bsf INTCON,GIEL
 bra _ILLEGAL

_MENU bra _ILLEGAL

_ILLEGAL bcf IR_CODE
 bra _SETMODE
;******************************************************
INFO1 bcf INTCON,GIEL
 rcall CLR_2LIN ;cleaning second line
 rcall STU_2LIN ;filling second line
 bsf INTCON,GIEL
 clrf infoindx
 return
;*************************************** 
;Clearing second line 
CLR_2LIN lfsr FSR0,0x100
_INFO11 btfsc FSR0L,3
 bra _INFO12
 clrf POSTINC0 ;Delete and Inc FSR0
 btfss FSR0L,7 ;is 180?
 bra _INFO11
 return
_INFO12 movlw 0x08
 addwf FSR0L,f
 bra _INFO11
;****************************************
STU_2LIN
;N  N  N  N  N  N
;0  6  0c  12  18  1e
 movlw 0x00
 movwf col_indx
 movff info1,l_data
 rcall STU_DIG
 movlw 0x06
 movwf col_indx
 movff info2,l_data
 rcall STU_DIG
 movlw 0x0c
 movwf col_indx
 movff info3,l_data
 rcall STU_DIG
 movlw 0x12
 movwf col_indx
 movff info4,l_data
 rcall STU_DIG
 movlw 0x18
 movwf col_indx
 movff info5,l_data
 rcall STU_DIG
 movlw 0x1e
 movwf col_indx
 movff info6,l_data
 rcall STU_DIG
 return
;*******************************************************
;Asemble time and date information from RAM
ASM_TIME clrf day
 clrf month
 clrf year
 clrf hou
 clrf min
 clrf sec
 clrf wday
 lfsr FSR0,0x200
 movff POSTINC0,day
 swapf day,f
 movf POSTINC0,w
 addwf day,f
;month
 movff POSTINC0,month
 swapf month,f
 movf POSTINC0,w
 addwf month,f
;year
 movff POSTINC0,year
 swapf year,f
 movf POSTINC0,w
 addwf year,f
;hour
 movff POSTINC0,hou
 swapf hou,f
 movf POSTINC0,w
 addwf hou,f
;minute
 movff POSTINC0,min
 swapf min,f
 movf POSTINC0,w
 addwf min,f
;second
 movff POSTINC0,sec
 swapf sec,f
 movf POSTINC0,w
 addwf sec,f
;wday
 movff POSTINC0,wday
 return

;*******************************************************
;Store time and date information in RAM (starting from 0x200) 
DISASM lfsr FSR0,0x200
;day(0x200-0x201)
 swapf day,w
 andlw 0x0f
 movwf POSTINC0
 movf day,w
 andlw 0x0f
 movwf POSTINC0
;month(0x202-0x203)
 swapf month,w
 andlw 0x0f
 movwf POSTINC0
 movf month,w
 andlw 0x0f
 movwf POSTINC0
;year(0x204-0x205)
 swapf year,w
 andlw 0x0f
 movwf POSTINC0
 movf year,w
 andlw 0x0f
 movwf POSTINC0
;hour(0x206-0x207)
 swapf hou,w
 andlw 0x0f
 movwf POSTINC0
 movf hou,w
 andlw 0x0f
 movwf POSTINC0
;minute(0x208-0x209)
 swapf min,w
 andlw 0x0f
 movwf POSTINC0
 movf min,w
 andlw 0x0f
 movwf POSTINC0
;second(0x210-0x211)
 swapf sec,w
 andlw 0x0f
 movwf POSTINC0
 movf sec,w
 andlw 0x0f
 movwf POSTINC0
;wday(0x212)
 movf wday,w
 andlw 0x0f
 movwf POSTINC0
 return

CLR_MAP lfsr FSR0,0x100
_CL1 clrf POSTINC0 ;Delete and Inc FSR0
 btfss FSR0H,1 ;is 200?
 bra _CL1
 return

_STU2 movf temp2,w
 addwf INDF0,f
 return
_STU1 movlw 0x07
 andwf col_indx,w
 movwf temp1
 movff TABLAT,temp2
 movf temp1,w
 btfsc _Z
 bra _STU2
;temp1 is not zero so it means shifting
_STU3 bcf _C
 rrcf temp2,f
 decfsz temp1,f
 goto _STU3

 movf temp2,w
 addwf INDF0,f
 movlw 0x07
 andwf col_indx,w
 movwf temp1
 movlw 0x03
 cpfsgt temp1
 return ;col_indx <=3,,, 0,1,2,3

_STUNLT4 incf FSR0L,f
 movlw 0x04
 cpfseq temp1
 bra _STUN4
;temp1 is 4
 btfsc TABLAT,3
 bsf INDF0,7
 bra _STUNEXT
_STUN4 
 movlw 0x05
 cpfseq temp1
 bra _STUN5
;temp1 is 5
 btfsc TABLAT,3
 bsf INDF0,6
 btfsc TABLAT,4
 bsf INDF0,7
 bra _STUNEXT
_STUN5
 movlw 0x06
 cpfseq temp1
 bra _STUN6
;temp1 is 6
 btfsc TABLAT,3
 bsf INDF0,5
 btfsc TABLAT,4
 bsf INDF0,6
 btfsc TABLAT,5
 bsf INDF0,7
 bra _STUNEXT
_STUN6
;temp1 is 7
 btfsc TABLAT,3
 bsf INDF0,4
 btfsc TABLAT,4
 bsf INDF0,5
 btfsc TABLAT,5
 bsf INDF0,6
 btfsc TABLAT,6
 bsf INDF0,7
 bra _STUNEXT

_STUNEXT decf FSR0L,f
 return

STU_MAP
;2.ROW XX:XX:XX  XXC
; H    H  :  M  M    :  S  S  T  T  C
; 0    6  b  10  16  1b  20  26  2f  35  3b
 movlw 0x00
 movwf col_indx
 swapf hou,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0x06
 movwf col_indx
 movf hou,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0x0b
 movwf col_indx
 movlw ':'
 movwf l_data
 rcall STU_ASC

 movlw 0x10
 movwf col_indx
 swapf min,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0x16
 movwf col_indx
 movf min,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0x1b
 movwf col_indx
 movlw ':'
 movwf l_data
 rcall STU_ASC

 rcall SECOND

;temper has temperature value in hex
;convert it to BCD
 movf temper,w
 call _BCD

 movlw 0x2f
 movwf col_indx
 movf bcd10,w
 movwf l_data
 rcall STU_DIG


 movlw 0x35
 movwf col_indx
 movf bcd1,w
 movwf l_data
 rcall STU_DIG

 movlw 0x3b
 movwf col_indx
 movlw '!'
 movwf l_data
 rcall STU_ASC

;1.ROW
;XX XXX XXXXX
; X    X    X    X    X      X    X    X    X    X
; 0    6    0e  14  1a    23  29  2f  35  3b
;+40h
; 40  46    4e  54  5a  63    69  6f  75    7b
 movlw 0x40
 movwf col_indx
 swapf day,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0x46
 movwf col_indx
 movlw 0x0f
 andwf day,w
 movwf l_data
 rcall STU_DIG

 movlw 0x4e
 movwf col_indx
 movf month,w
 call MONTH1
 movwf l_data
 rcall STU_ASC

 movlw 0x54
 movwf col_indx
 movf month,w
 call MONTH2
 movwf l_data
 rcall STU_ASC

 movlw 0x5a
 movwf col_indx
 movf month,w
 call MONTH3
 movwf l_data
 rcall STU_ASC

; btfsc GPS_TYP
; bra _NMEA_1 ;NMEA Modea
 movlw 0x63
 movwf col_indx
 movf wday,w
 call WDAY1
 movwf l_data
 rcall STU_ASC

 movlw 0x69
 movwf col_indx
 movf wday,w
 call WDAY2
 movwf l_data
 rcall STU_ASC

 movlw 0x6f
 movwf col_indx
 movf wday,w
 call WDAY3
 movwf l_data
 rcall STU_ASC

 movlw 0x75
 movwf col_indx
 movf wday,w
 call WDAY4
 movwf l_data
 rcall STU_ASC

 movlw 0x7b
 movwf col_indx
 movf wday,w
 call WDAY5
 movwf l_data
 rcall STU_ASC

 return 

SECOND
;clearing previous

 lfsr FSR2,0x104
_SEC2 clrf POSTINC2
 movlw B'00011111'
 andwf POSTINC2

 movlw 0x0e
 addwf FSR2L,f
 btfss FSR2L,7 ;if it is 1000xxxx?
 bnc _SEC2 ;yes reached

 
_SEC1 movlw 0x20
 movwf col_indx
 swapf sec,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0x26
 movwf col_indx
 movlw 0x0f
 andwf sec,w 
 movwf l_data
 rcall STU_DIG
 return

 bra _NOT_NMEA

_NMEA_1
;2 for 20XX
 movlw 0x66
 movwf col_indx
 movlw 0x02
 movwf l_data
 rcall STU_DIG 
;0 for 20XX
 movlw 0x6c
 movwf col_indx
 clrf l_data
 rcall STU_DIG

 movlw 0x72
 movwf col_indx
 swapf year,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0x78
 movwf col_indx
 movlw 0x0f
 andwf year,w
 movwf l_data
 rcall STU_DIG

 return

;1-2.ROWs (double)
;XX XX : XX XX
;XX XX : XX XX XX
;Y  Y  :  Y    Y    X    X
;0  0b  18  1e  29  35  3b
;9  14  1a  27  32  39  3f
;+C0
;c0 cb  d8  de  e9  f5    fb
;c9 d4  da  e7
_NOT_NMEA movlw 0xc0
 movwf col_indx
 swapf hou,w
 andlw 0x0f
 movwf l_data
 rcall STU_DBL

 movlw 0xcb
 movwf col_indx
 movlw 0x0f
 andwf hou,w
 movwf l_data
 rcall STU_DBL
;Point
 movlw B'11100000'
 lfsr FSR0,0x133
 movwf POSTINC0
 lfsr FSR0,0x153
 movwf POSTINC0
 lfsr FSR0,0x173
 movwf POSTINC0
 lfsr FSR0,0x17b
 movwf POSTINC0
 lfsr FSR0,0x19b
 movwf POSTINC0
 lfsr FSR0,0x1bb
 movwf POSTINC0


 movlw 0xde
 movwf col_indx
 swapf min,w
 andlw 0x0f
 movwf l_data
 rcall STU_DBL

 movlw 0xe9
 movwf col_indx
 movlw 0x0f
 andwf min,w
 movwf l_data
 rcall STU_DBL

;SECOND1 movlw 0xb5
 movwf col_indx
 swapf sec,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0xbb
 movwf col_indx
 movlw 0x0f
 andwf sec,w 
 movwf l_data
 rcall STU_DIG
 return

;INPUT l_data-> Numeric
STU_DBL movf l_data,w
 mullw 0x20
 movff PRODL,TBLPTRL
 clrf TBLPTRU
 movlw 0x1a
 addwf PRODH,w
 movwf TBLPTRH

STU_DBL1 movff col_indx,temp1
 lfsr FSR0,0x100
 movlw 0xf8
 andwf temp1,f
 rrncf temp1,f
 rrncf temp1,f
 rrncf temp1,w
 addwf FSR0L,f
 movff FSR0L,temp_FSR ;save FSRL 
;Double Character first row
 rcall DB_CH_ROW
;Double Character second row
 movlw 0x08
 subwf temp_FSR,f
 rcall DB_CH_ROW
 return

DB_CH_ROW clrf count
STU_DBL2 movff temp_FSR,FSR0L
 movf count,w
 mullw 0x20
 movf PRODL,w
 addwf FSR0L,f
 TBLRD*+
 movff TABLAT,TBL_temp1
 TBLRD*+
 movff TABLAT,TBL_temp2
 rcall _SHIFT
 incf count,f
 btfss count,3
 bra STU_DBL2
 return 

;INPUT l_data->ASCI 
STU_ASC movlw 0x20
 subwf l_data,w
 mullw 0x08
 movff PRODL,TBLPTRL
 movf PRODH,w
 addlw 0x18
 movwf TBLPTRH
 clrf TBLPTRU
 bra STU_CMN

STU_DIG movf l_data,w
 mullw 0x08
 movf PRODL,w 
 addlw 0x80
 movwf TBLPTRL
 clrf TBLPTRU
 movlw 0x18
 movwf TBLPTRH

STU_CMN movff col_indx,temp1
 lfsr FSR0,0x100
 movlw 0xf8
 andwf temp1,f
 rrncf temp1,f
 rrncf temp1,f
 rrncf temp1,w
 addwf FSR0L,f
 movff FSR0L,temp_FSR ;save FSRL 

 clrf count
_STUM1 movff temp_FSR,FSR0L
 movf count,w
 mullw 0x10
 movf PRODL,w
 addwf FSR0L,f
 TBLRD*+
 rcall _STU1
 incf count,f
 btfss count,3
 bra _STUM1
 return

;*****************************************************
;SHIFT for double character
;Main function is _SHIFT
_SHFT1 movf TBL_temp1,w
 addwf POSTINC0,f
 movf TBL_temp2,w
 addwf POSTINC0,f
 return
_SHIFT movlw 0x07
 andwf col_indx,w
 movwf temp1
; movff TABLAT,temp2
 movf temp1,w
 btfsc _Z
 bra _SHFT1
;temp1 is not zero so it means shifting
 bcf _LSB
 btfsc TBL_temp2,6
 bsf _LSB ;will be used at 7th shift
_SHFT3 bcf _C
 rrcf TBL_temp1,f
 rrcf TBL_temp2,f
 decfsz temp1,f
 goto _SHFT3

 movf TBL_temp1,w
 addwf POSTINC0,f
 movff TBL_temp2,POSTINC0
 movlw 0x07
 andwf col_indx,w
 xorlw 0x07
 bz _7TH 
 return
_7TH btfss _LSB
 return
 bsf POSTINC0,7
 return

;SECOND
 lfsr FSR2,0x116
;_SEC1 movlw 0xf8
 andwf POSTINC2
 clrf POSTINC2
 movlw 0x1e
 addwf FSR2L,f
; bnc _SEC1
; goto SECOND1
 return
;**************************************************
;SETUP SCREEN
STU_MAP2
;2.ROW XX:XX:XX  XXC
; H    H  :  M  M    :  S  S  T  T  C
; 0    6  b  10  16  1b  20  26  2f  35  3b

 movlw 0x00
 movwf col_indx
 swapf hou,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0x06
 movwf col_indx
 movf hou,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0x0b
 movwf col_indx
 movlw ':'
 movwf l_data
 rcall STU_ASC

 movlw 0x10
 movwf col_indx
 swapf min,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0x16
 movwf col_indx
 movf min,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG

 movlw 0x1b
 movwf col_indx
 movlw ':'
 movwf l_data
 rcall STU_ASC

 rcall SECOND

;temper has temperature value in hex
;convert it to BCD
 movf temper,w
 call _BCD

 btfss SETUP_M
 bra _STUMAP23
;SETUP MODE
 movlw 0x35
 movwf col_indx
 movff wday,l_data
 rcall STU_DIG
 bra _STUMAP22
;NORMAL MODE 
_STUMAP23 movlw 0x2f
 movwf col_indx
 movf bcd10,w
 movwf l_data
 rcall STU_DIG

 movlw 0x35
 movwf col_indx
 movf bcd1,w
 movwf l_data
 rcall STU_DIG

 movlw 0x3b
 movwf col_indx
 movlw '!'
 movwf l_data
 rcall STU_ASC
_STUMAP22
;1.ROW
; 40  46    4e  54  5a  63    69  6f  75    7b
;DD-MM-YYYY
; D    D  -  M  M  -  Y  Y  Y  Y
; 0    6  0c 12  18  1e  24  2a  30  36
;+41
; 41  47  4d 53  59  5f  65  6b  71  77
 movlw 0x41
 movwf col_indx
 swapf day,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG
 movlw 0x47
 movwf col_indx
 movlw 0x0f
 andwf day,w
 movwf l_data
 rcall STU_DIG

 movlw 0x4d
 movwf col_indx
 movlw '-'
 movwf l_data
 rcall STU_ASC

 movlw 0x53
 movwf col_indx
 swapf month,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG
 movlw 0x59
 movwf col_indx
 movlw 0x0f
 andwf month,w
 movwf l_data
 rcall STU_DIG

 movlw 0x5f
 movwf col_indx
 movlw '-'
 movwf l_data
 rcall STU_ASC

 movlw 0x65
 movwf col_indx
 movlw 0x02
 movwf l_data
 rcall STU_DIG
 movlw 0x6b
 movwf col_indx
 clrf l_data
 rcall STU_DIG
 movlw 0x71
 movwf col_indx
 swapf year,w
 andlw 0x0f
 movwf l_data
 rcall STU_DIG
 movlw 0x77
 movwf col_indx
 movlw 0x0f
 andwf year,w
 movwf l_data
 rcall STU_DIG

 return


;SHT11 Humudity Reading
SHT_HUMD rcall SHT_RES
 movlw 0x05
 movwf command
 rcall WRITE
;Getting ACK, 1 clock pulse for ACK
 bsf TRISB,1 ;RB0 input
 bsf SHT_CLK
 bcf SHT_CLK
 nop
 nop
;waiting SHT for humudity data will be ready
 bsf WAIT_HUMD
 bcf INTCON3,INT1IF
 bcf INTCON2,INTEDG1
 bcf INTCON3,INT1IP ;Ext INT1 low priority
 bsf INTCON3,INT1IE
 return

SHT_HUMD2 bcf INTCON3,INT1IE ;Disable INT0
 bcf WAIT_HUMD
 call READ_SHT
 movff command,rh1
 call SEND_ACK
 call READ_SHT
 movff command,rh0
 call SEND_ACK1
;Calculate Humudity
;367*RH 16F*RH
;-20468 -4FF4
;-RH*RH/64 -RH*RH/64
 movlw 0x01
 movwf aarg1
 movlw 0x6f
 movwf aarg0
 movff rh1,barg1
 movff rh0,barg0
 call MUL16x16
;save RH*367
 movff res4,t_res4
 movff res3,t_res3
 movff res2,t_res2
 movff res1,t_res1
;subract 4ff4 from t_res
 movlw 0xf4
 subwf t_res1,f
 movlw 0x4f
 subwfb t_res2,f
 movlw 0x00
 subwfb t_res3,f
;RH*RH/64
 movff rh1,aarg1
 movff rh0,aarg0
 movff rh1,barg1
 movff rh0,barg0
 call MUL16x16
 movlw 0x06
 movwf m_count
_HUMD2 bcf _C
 rrcf res4,f
 rrcf res3,f
 rrcf res2,f
 rrcf res1,f
 decfsz m_count,f
 bra _HUMD2
;subtract RH*RH/64 from t_res
 movf res1,w
 subwf t_res1,f
 movf res2,w
 subwfb t_res2,f
 movf res3,w
 subwfb t_res3,f
;t_res * 13 /128  (/10)
 movlw 0x07
 movwf m_count
_HUMD3 bcf _C
 rrcf t_res4,f
 rrcf t_res3,f
 rrcf t_res2,f
 rrcf t_res1,f
 decfsz m_count,f
 bra _HUMD3
 movff t_res1,aarg0
 movff t_res2,aarg1
 clrf barg1
 movlw D'13'
 movwf barg0
 call MUL16x16
 movff res1,aarg0
 movff res2,aarg1
 clrf t_res3
 movlw 0x01
 cpfseq res3
 bra _SML65
 movlw 0x04
 movwf t_res3
;40000 %40 = 9c40
 movlw 0x40
 subwf aarg0,f
 movlw 0x9c
 subwfb aarg1,f
_SML65 call B16_BCD
 movff res4,h_dig1
 movf t_res3,w
 addwf h_dig1
 movff res3,h_dig2
 return

;SHT11 Temperature Reading
SHT_TEMP rcall SHT_RES
 movlw 0x03
 movwf command ;Reading Temperature
 rcall WRITE
;Getting ACK, 1 clock pulse for ACK
 bsf TRISB,1 ;RB0 input
 bsf SHT_CLK
 bcf SHT_CLK
 nop
 nop
;waiting SHT for temperature data will be ready
 bsf WAIT_TEMP
; bcf INTCON,INT0IF
 bcf INTCON3,INT1IF
; bcf INTCON2,INTEDG0
 bcf INTCON2,INTEDG1
 bcf INTCON3,INT1IP ;Ext INT1 low priority
; bsf INTCON,INT0IE
 bsf INTCON3,INT1IE
 return

;_TEMP1 btfsc SHT_DATA
; bra _TEMP1
; btfsc SHT_DATA
; bra _TEMP1

SHT_TEMP2 bcf INTCON3,INT1IE ;Disable INT1
 bcf WAIT_TEMP
 call READ_SHT
 movff command,aarg1
 call SEND_ACK
 call READ_SHT
 movff command,aarg0
 call SEND_ACK1
 
;Calculate Temperature
 movlw 0xA0
 subwf aarg0,f
 movlw 0x0f
 subwfb aarg1,f
 call B16_BCD
 movff res3,t_dig1
 movff res2,t_dig2
 movff aarg1,t_dig3 
 return

WRITE movlw 0x08
 movwf m_count
_WRITE1 bcf SHT_CLK
 bcf SHT_DATA
 rlcf command,f
 btfsc _C
 bsf SHT_DATA
 nop
 bsf SHT_CLK
 decfsz m_count,f
 bra _WRITE1
 bcf SHT_CLK
 return

SHT_RES bcf TRISB,1
 bsf SHT_DATA
 bcf SHT_CLK
 movlw D'12'
 movwf m_count
SHT_R1 bsf SHT_CLK
 nop
 nop
 bcf SHT_CLK
 decfsz m_count,f
 bra SHT_R1
;Tranmission start
 bsf SHT_CLK
 nop
 bcf SHT_DATA
 nop
 bcf SHT_CLK
 nop
 bsf SHT_CLK
 nop
 bsf SHT_DATA
 nop
 bcf SHT_CLK
 nop
 bcf SHT_DATA
 return

;*********************LOCAL TIME ADDING************************
;hou+=t_diff
L_CONT
 movf t_diff,w
 addwf hou,w
 daw
 movwf hou
 movlw 0x23
 cpfsgt hou
 return
;next day
 incf wday,f
 btfss wday,3
 bra _WDN8
;weekday is 8 so make it 1
 movlw 0x01
 movwf wday
 subwf hou,f
_WDN8 movlw 0x24
 subwf hou,f
 incf day,w
;test it whether day is 0x0a,0x1a or 0x2a
 daw
 movwf day
;check month for last day of it
 call TB_MO1
 movwf temp3 ;temp3 has the last day of current month
;check month whether 2 or not
 movlw 0x02
 cpfseq month
 bra _NMO2
;month is 2 (February) so check it for 29 (every 4 years 08,12,16,20..)
;if 1x - > 10+x
 movf year,w
 andlw 0xf0
 movwf res1 ;1 for 1x,, 2 for 2x 
 swapf res1
 movlw 0x0a
 mulwf res1
 movff PRODL,res1
 movf year,w
 andlw 0x0f
 addwf res1,w ;W has the year data in hex
 andlw 0x03
 bnz _NMO2
;leap year so max is 30
 movlw 0x30
 movwf temp3
_NMO2 movf temp3,w
 cpfseq day
 return
;Next mounth
 movlw 0x01
 movwf day
 incf month,w
 daw
 movwf month
 movlw 0x13
 cpfseq month
 return
;next year
 movlw 0x01
 movwf month
 incf year,w
 daw
 movwf year
 return 

;*************************************************************
;All received data from USART will be stored in RAM between
; 200
;Data Formats:
;              D:DD.MM.YY;T:2;U:HH.MM.SS;
;      0123456789012345678901234
;      0123456789ABCDEF012345678
;    90h            A0
;*************************************************************
RXFUNC btfsc UP_RTC
 bra _ENDRX2
 lfsr FSR2,0x200
 movff ram_index,FSR2L
 movff RCREG,INDF2
 rcall CHECK_DATA
 incf ram_index,f
_ENDRX bcf PIR1,RCIF
 return
_ENDRX2 movf RCREG,w
 bcf PIR1,RCIF
 return

CHECK_DATA
 btfsc GPS_TYP
 bra _NMEA
;MEINBERCAPTURE MODE
 movlw 0x00
 cpfseq ram_index
 bra _N00
 movlw 'D'
 cpfseq INDF2
 bra FAULT
 return
_N00 movlw 0x01
 cpfseq ram_index
 bra _N01
 movlw ':'
 cpfseq INDF2
 bra FAULT
 return
_N01 decfsz num_data,f
 return
;now received 23 character from GPS
 bcf ERR
 lfsr FSR2,0x202
 call _RXH
 movwf day
 call _RXL
 addwf day,f
 incf FSR2L,f
 call _RXH
 movwf month
 call _RXL
 addwf month,f
 incf FSR2L,f
 call _RXH
 movwf year
 call _RXL
 addwf year,f

 lfsr FSR2,0x20d
 call _RXL
 movwf wday

 lfsr FSR2,0x211
 call _RXH
 movwf hou
 call _RXL
 addwf hou,f
 incf FSR2L,f
 call _RXH
 movwf min
 call _RXL
 addwf min,f
 incf FSR2L,f
 call _RXH
 movwf sec
 call _RXL
 addwf sec,f
 bra _CHKD1
;NMEA MODE
_NMEA movlw 0x00
 cpfseq ram_index
 bra _NNM00
 movlw 'G'
 cpfseq INDF2
 bra FAULT
 return
_NNM00 movlw 0x01
 cpfseq ram_index
 bra _NNM01
 movlw 'P'
 cpfseq INDF2
 bra FAULT
 return
_NNM01 movlw 0x02
 cpfseq ram_index
 bra _NNM02
 movlw 'R'
 cpfseq INDF2
 bra FAULT
 return
_NNM02 movlw 0x03
 cpfseq ram_index
 bra _NNM03
 movlw 'M'
 cpfseq INDF2
 bra FAULT
 return
_NNM03 movlw 0x04
 cpfseq ram_index
 bra _NNM04
 movlw 'C'
 cpfseq INDF2
 bra FAULT
 return
_NNM04 movlw 0x05
 cpfseq ram_index
 bra _NNM05
 movlw ','
 cpfseq INDF2
 bra FAULT
 return
_NNM05 decfsz num_data,f
 return
;now received 60 character from GPS
 bcf ERR

;finding date information;
;count 9 comma from first data
 clrf comma_c
 lfsr FSR2,0x204
_COM_NEXT movlw ','
 cpfseq INDF2
 bra _NCOM9
;comma
 incf comma_c,f
 movlw 0x09
 cpfseq comma_c
 bra _NCOM9
;comma is 9 now get date
;data valid
 incf FSR2L,f
 bra _VALID
_NCOM9 incf FSR2L,f
 movlw 0x39
 cpfseq FSR2L
 bra _COM_NEXT
;FSR2 is 0x239 but still could not been counted 9 comma,so it is error
 bcf ERR
 bra FAULT

_VALID rcall _RXH
 movwf day
 rcall _RXL
 addwf day,f
 rcall _RXH
 movwf month
 rcall _RXL
 addwf month,f
 rcall _RXH
 movwf year
 rcall _RXL
 addwf year,f

 lfsr FSR2,0x206
 rcall _RXH
 movwf hou
 rcall _RXL
 addwf hou,f
 rcall _RXH
 movwf min
 rcall _RXL
 addwf min,f
 rcall _RXH
 movwf sec
 rcall _RXL
 addwf sec,f
;data has been taken from GPS,
; test it whether it is corrupted(ERR set) or valid
_CHKD1 btfsc ERR
 bra FAULT
 bsf GPS
 clrf sec2
 movlw 0x01
 movwf ready
 btfsc UTC
 bra _NSTRTUP ;if UTC
 rcall L_CONT ;if LOCAL
;if NMEA Check weekday on every 00:00:00
 btfss GPS_TYP ;0:Meinberg, 1:NMEA
 bra _CHKLOC
 movf hou,w
 bnz _CHKLOC
 movf min,w
 bnz _CHKLOC
 movf sec,w
 bnz _CHKLOC 
 call F_WDAY
;Check Local Time every on 
;when month is 3 and hour is 3:00:00
;or when month is 10 and time is 4:00:00
_CHKLOC movlw 0x03
 cpfseq month
 bra _MN03
;month is 3 now check time for 3:00:00
 movlw 0x03
 cpfseq hou
 bra _NSTRTUP
;hour is 3
 movf min,w
 bnz _NSTRTUP
;min is 00
 movf sec,w
 btfsc _Z 
 bsf STARTUP
 bra _NSTRTUP
;month is not 3 so check it for 10 and 4:00:00
_MN03 movlw 0x10
 cpfseq month
 bra _NSTRTUP
;month is 10
 movlw 0x04
 cpfseq hou
 bra _NSTRTUP
;hou is 4
 movf min,w
 bnz _NSTRTUP
;min is 00
 movf sec,w
 btfsc _Z
 bsf STARTUP
;no startup 
;Set RTC on every day (17:00:00)
_NSTRTUP
 movlw 0x17
 cpfseq hou
 bra FAULT
 movlw 0x00
 cpfseq min
 bra FAULT
 movlw 0x00
 cpfseq sec
 bra FAULT
;17:00:00 wait for RTC
 bcf PIE1,RCIE
 bsf UP_RTC
 bsf SSP_WR
 clrf sspcount
 movlw 0x08
 movwf ssp_data
 bsf SSPCON2,SEN
 lfsr FSR2,0x08f
 clrf ready 

FAULT movlw 0xff
 movwf ram_index
 movlw D'23'
 btfsc GPS_TYP ;if 1; NMEA,, 
 movlw D'60'
 movwf num_data
 return

_RXL movff POSTINC2,tdata
;if tdata=<30 or tdata>=39 then ERR
 movlw 0x2f
 cpfsgt tdata
 bsf ERR
 movlw 0x40
 cpfslt tdata
 bsf ERR
 movlw 0x30
 subwf tdata,w
 return

_RXH movff POSTINC2,tdata
;if tdata=<30 or tdata>=39 then ERR
 movlw 0x2f
 cpfsgt tdata
 bsf ERR
 movlw 0x40
 cpfslt tdata
 bsf ERR
 movlw 0x30
 subwf tdata,f
 swapf tdata,w
 return
;Finding WEEKDAY OF DATE
;***********************************************
;res1=day,res2=month,res3=year
;for 09-10-2013 res1=09;res2=10;res3=13;wday=3 (wednesday)
F_WDAY movlw 0x09
 movwf res1
 movlw 0x10
 movwf res2
 movlw 0x13
 movwf res3
 movlw 0x03
 movwf wday
;check that res3=?year
; res2=?month
; res1=?day
_FWNEXT movf res3,w
 cpfseq year ;year is equal?
 bra _FWDAY1
;year is equal res3
 movf res2,w
 cpfseq month
 bra _FWDAY1
;month is equal res2
 movf res1,w
 cpfseq day
 bra _FWDAY1
 return ;year=res3,month=res2,day=res1
;increment day and test
_FWDAY1 incf wday,f
 btfss wday,3
 bra _FWDAY2
;weekday is 8 so make it 1
 movlw 0x01
 movwf wday
_FWDAY2 incf res1,w
 daw
 movwf res1
;check month for last day of it
 call TB_MO2
 movwf temp3 ;temp3 has the last day of current month
;check month whether 2 or not
 movlw 0x02
 cpfseq res2
 bra _FWNMO2
;month is 2 (February) so check it for 29 (every 4 years 08,12,16,20..)
;if 1x - > 10+x
 movf res3,w
 andlw 0xf0
 movwf h_dig1 ;1 for 1x,, 2 for 2x 
 swapf h_dig1,f
 movlw 0x0a
 mulwf h_dig1
 movff PRODL,h_dig1
 movf res3,w
 andlw 0x0f
 addwf h_dig1,w ;W has the year data in hex
 andlw 0x03
 bnz _FWNMO2
;leap year so max is 30
 movlw 0x30
 movwf temp3
_FWNMO2 movf temp3,w
 cpfseq res1
 bra _FWNEXT ;da++;wday++; check again
;Next mounth
 movlw 0x01
 movwf res1
 incf res2,w
 daw
 movwf res2
 movlw 0x13
 cpfseq res2
 bra _FWNEXT ;month++;wday++; check again
;next year
 movlw 0x01
 movwf res2
 incf res3,w
 daw
 movwf res3
 btfsc res3,6
 return
 bra _FWNEXT ;da++;wday++; check again 


INIT movlw B'00000001'
 movwf LATA
 movlw B'00000001'
 movwf LATB
 movlw B'10011000'
 movwf LATC
 movlw B'11110000'
 movwf LATD ;PORT7:4 are inputs for DIP SWITCH
 clrf LATE
 movlw B'10001110' ;AN0 Analog Input
 movwf ADCON1
 bsf RCON,IPEN ;INT priority enable
 movlw B'00000001'
 movwf TRISA
 movlw B'00000001'
 movwf TRISB
 movlw B'10011000'
 movwf TRISC ;SDA,SCL;Tx,RX
 movlw 0xf0
 movwf TRISD
 clrf TRISE
 clrf PIE1
 clrf PIR1
 clrf IPR1
 clrf IPR2
 bsf PIE1,RCIE
 bsf IPR1,RCIP ;RX High priority
 bsf PIE1,SSPIE
 bsf IPR1,SSPIP ;SSP high priority
 movlw D'49'
 movwf SSPADD
 bsf SSPSTAT,7
; bsf SSPSTAT,6
 movlw B'00101000' ;I2C, Master mode,
 movwf SSPCON1

; movlw B'00000100' ;ASYNC, high speed
 movlw B'00000000'
 movwf TXSTA
; movlw D'129' ;9600 baud rate
 movlw D'64' ;4800 baud rate
 movwf SPBRG
 movlw B'11100000' ;GIEH,GIEL,TMR0IE
 movwf INTCON
 bsf INTCON,INT0IE ;RB0 Interrupt Enable
 bcf INTCON2,TMR0IP ;TMR0 low priority interrupt
 movlw B'11000100'
 movwf T0CON
 return

;**********************************************
;16 bit  X 16 bit multiple
;INPUT : aarg1:aarg0
; barg1:barg0
;    X__________________
; res4:res1
;**********************************************
MUL16x16 clrf    res4
 clrf res3
 clrf    res2
 movlw 0x80
 movwf res1 
nextbit
 rrcf aarg1,f
 rrcf aarg0,f
 btfss _C
 goto nobit_l
 movf barg0,w
 addwf res2,f

 movf barg1, w
 btfsc _C
 incfsz barg1, w 
 addwf res3, f 
 btfsc _C
 incf res4, f
 bcf _C
 
nobit_l 
 btfss aarg0, 7
 goto nobit_h
 movf barg0,w
 addwf res3,f
 movf barg1, w
 btfsc _C
 incfsz barg1, w
 addwf res4, f 

nobit_h
 rrcf res4,f
 rrcf res3,f
 rrcf res2,f
 rrcf res1,f

 btfss _C
 goto nextbit
 return

;*************************************************
;16 bit (2 byte) BCD convertion 
;INPUT aarg1:aarg0
;OUTPUT res4,res3,res2,aarg1,aarg0
;*************************************************
B16_BCD 
 rrcf aarg1,W ;Divide by 1000 
 rrcf WREG,1            ;Start with divide by 1024 
 andlw B'00111111'    ; 
 movwf res3            ;Result to res3 
 mullw .24                ;Correction factor = 24 (1024-1000) 
 movlw B'00000011'  ;Calculate /1024 remainder 
 andwf aarg1,1        ; 
 movf PRODL,W        ;Add correction factor 
 addwf aarg0,1          ;to remainder 
 movf PRODH,W        ;(maximum possible value is 2535) 
 addwfc aarg1,1        ; 
Do11Bit: 
 movlw low .1000      ; 
 subwf aarg0,1          ;Subtract 1000 
 movlw high .1000    ; 
 subwfb aarg1,1        ; 
 bnc Fix1000            ;Abort if negative 
 incf res3,1            ;Still positive, increment thousands 
 movlw low .1000      ; 
 subwf aarg0,1          ;Subtract 1000 
 movlw high .1000    ; 
 subwfb aarg1,1        ; 
 bnc Fix1000            ;Abort if negative 
 incf res3,1            ;Still positive, increment thousands 
 bra End1000            ;Done 
Fix1000: 
 movlw low .1000      ;Negative, add 1000 
 addwf aarg0,1          ; 
 movlw high .1000    ; 
 addwfc aarg1,1        ; 
End1000: 
 rlcf aarg0,W            ;Divide remainder by 100 
 rlcf aarg1,W            ;Start with divide by 128 
 andlw B'00000111'    ; 
 movwf res2            ;Result to res2 
 mullw .28                ;Correction factor = 28 (128-100) 
 bcf aarg0,7              ;Calculate /128 remainder 
 movf PRODL,W        ;Add correction factor to remainder 
 addwf aarg0,1          ;(maximum possible value is 299) 
 bnc Less256            ;No carry, ramainder < 256 
 movlw -.200            ;Remainder >=256 
 addwf aarg0,1          ;Subtract 200 
 incf res2,1            ;Increment hundreds twice 
 incf res2,1            ; 
 bra End100              ;Done 
Less256: 
 movlw .100            ; 
 subwf aarg0,1          ;Subtract 100 
 bnc Fix100              ;Abort if negative 
 incf res2,1            ;Still positive, increment hundreds 
 subwf aarg0,f          ;Subtract 100 
 bnc Fix100              ;Abort if negative 
 infsnz res2,1          ;Positive, incr. hundreds, skip next 
Fix100:  
 addwf aarg0,1        ;Negative, add 100 
End100: 
 movf res3,W          ;Now we have: TT:H:OO 
 mullw .205            ;res3*1000 + res2*100 + aarg0*1 
 movlw .32              ;Split res3 to two digits 
 mulwf PRODH          ;Multiply by 0.1 
 movf PRODH,W        ;(205/256 * 32/256) 
 movwf res4        ;Result to res4 
 mullw .10              ;Multiply by 10 
 movf PRODL,W        ;Subtract from original res3 
 subwf res3,1        ;Remainder is res3 
 movf aarg0,W        ;Split aarg0 to two digits 
 mullw .205            ; 
 movlw .32              ;Multiply by 0.1 
 mulwf PRODH          ;(205/256 * 32/256) 
 movf PRODH,W        ; 
 movwf aarg1          ;Result to aarg1 
 mullw .10              ;Multiply by 10 
 movf PRODL,W        ;Subtract from original aarg0 
 subwf aarg0,1          ;Remainder is aarg0 
 return                    ;Done 


;(W-1)*3+7 microsecond delay for 4 MHz
NMICRO movwf cntmsec
NMICRO1 decfsz cntmsec,f
 bra NMICRO1
 return

NMSEC bcf INTCON,GIEH
 bcf INTCON,GIEL
 movwf cntmsec
_NMSEC3 movlw 0x07
 movwf cntmsec3
_NMSEC2 movlw 0xed
 movwf cntmsec2
_NMSEC1 
 decfsz cntmsec2,f
 bra _NMSEC1
 decfsz cntmsec3,f
 bra _NMSEC2
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
 decfsz cntmsec,f
 bra _NMSEC3
 bcf INTCON,T0IF
 bsf INTCON,GIEL
 bsf INTCON,GIEH
 return

chset1 code_pack 0x1800
;Space
 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
;C(!)
 db 0xC0,0xC0,0x38,0x40,0x40,0x40,0x38,0x00
;"
 db 0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00
;#
 db 0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00
;$
 db 0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00
;%
 db 0xC0,0xC8,0x10,0x20,0x40,0x98,0x18,0x00
;&
 db 0x60,0x90,0xA0,0x40,0xA8,0x90,0x68,0x00
;'
 db 0x60,0x20,0x40,0x00,0x00,0x00,0x00,0x00
;(
 db 0x10,0x20,0x40,0x40,0x40,0x20,0x10,0x00
;)
 db 0x40,0x20,0x10,0x10,0x10,0x20,0x40,0x00
;*
 db 0x00,0x20,0xA8,0x70,0xA8,0x20,0x00,0x00
;+
 db 0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00
;,
 db 0x00,0x00,0x00,0x00,0x60,0x20,0x40,0x00
;-
 db 0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00
;.
 db 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00
;/
 db 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00
;0
 db 0x70,0x88,0x98,0xA8,0xC8,0x88,0x70,0x00
;1
 db 0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00
;2
 db 0x70,0x88,0x08,0x10,0x20,0x40,0xF8,0x00
;3
 db 0xF8,0x10,0x20,0x10,0x08,0x88,0x70,0x00
;4
 db 0x10,0x30,0x50,0x90,0xF8,0x10,0x10,0x00
;5
 db 0xF8,0x80,0xF0,0x08,0x08,0x88,0x70,0x00
;6
 db 0x30,0x40,0x80,0xF0,0x88,0x88,0x70,0x00
;7
 db 0xF8,0x08,0x10,0x20,0x40,0x40,0x40,0x00
;8
 db 0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00
;9
 db 0x70,0x88,0x88,0x78,0x08,0x10,0x60,0x00
;:
 db 0x00,0x60,0x60,0x00,0x60,0x60,0x00,0x00
;;
 db 0x00,0x60,0x60,0x00,0x60,0x20,0x40,0x00
;<
 db 0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00
;=
 db 0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00
;>
 db 0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00
;?
 db 0x70,0x88,0x08,0x10,0x20,0x00,0x20,0x00
;@
 db 0x70,0x88,0x08,0x68,0xA8,0xA8,0x70,0x00
;A
 db 0x70,0x88,0x88,0x88,0xF8,0x88,0x88,0x00
;B
 db 0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x00
;C
 db 0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00
;D
 db 0xE0,0x90,0x88,0x88,0x88,0x90,0xE0,0x00
;E
 db 0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00
;F
 db 0xF8,0x80,0x80,0xF0,0x80,0x80,0x80,0x00
;G
 db 0x70,0x88,0x80,0xB8,0x88,0x88,0x78,0x00
;H
 db 0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00
;I
 db 0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00
;J
 db 0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x00
;K
 db 0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00
;L
 db 0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00
;M
 db 0x88,0xD8,0xA8,0xA8,0x88,0x88,0x88,0x00
;N
 db 0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00
;O
 db 0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00
;P
 db 0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x00
;Q
 db 0x70,0x88,0x88,0x88,0xA8,0x90,0x68,0x00
;R
 db 0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88,0x00
;S
 db 0x78,0x80,0x80,0x70,0x08,0x08,0xF0,0x00
;T
 db 0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x00
;U
 db 0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00
;V
 db 0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00
;W
 db 0x88,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00
;X
 db 0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00
;Y
 db 0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x00
;Z
 db 0xF8,0x08,0x10,0x20,0x40,0x80,0xF8,0x00

chset2 code_pack 0x1a00
;LCD Font Maker
;Verdana 14 Normal
;0
 db 0x3F,0x00,0x7F,0x80,0xE1,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0
 db 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE1,0xC0,0x7F,0x80,0x3F,0x00,0x00,0x00
;1
 db 0x0C,0x00,0x1C,0x00,0x3C,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00
 db 0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x7F,0x80,0x7F,0x80,0x00,0x00
;2
 db 0x3E,0x00,0x7F,0x00,0x63,0x80,0x41,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x03,0x00
 db 0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0xFF,0x80,0xFF,0x80,0x00,0x00
;3

 db 0x3F,0x00,0x7F,0x80,0x41,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x01,0x80,0x0F,0x00
 db 0x0F,0x80,0x01,0xC0,0x00,0xC0,0x00,0xC0,0x41,0xC0,0x7F,0x80,0x3F,0x00,0x00,0x00
;4
 db 0x03,0x00,0x07,0x00,0x0F,0x00,0x1F,0x00,0x3B,0x00,0x73,0x00,0xE3,0x00,0xC3,0x00
 db 0xC3,0x00,0xFF,0xC0,0xFF,0xC0,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00
;5
 db 0xFF,0x80,0xFF,0x80,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xFF,0x00,0xFF,0x80,0x01,0xC0
 db 0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x81,0xC0,0xFF,0x80,0x7F,0x00,0x00,0x00
;6
 db 0x1F,0x80,0x3F,0x80,0x70,0x00,0xE0,0x00,0xC0,0x00,0xC0,0x00,0xDF,0x00,0xFF,0x80
 db 0xE1,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE1,0xC0,0x7F,0x80,0x3F,0x00,0x00,0x00
;7
 db 0xFF,0xC0,0xFF,0xC0,0x00,0xC0,0x00,0xC0,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00
 db 0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x00,0x00
;8
 db 0x3F,0x00,0x7F,0x80,0xE1,0xC0,0xC0,0xC0,0xC0,0xC0,0xE1,0xC0,0x7F,0x80,0x3F,0x00
 db 0x61,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE1,0xC0,0x7F,0x80,0x3F,0x00,0x00,0x00
;9
 db 0x3F,0x00,0x7F,0x80,0xE1,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xE1,0xC0,0xFF,0xC0
 db 0x7E,0xC0,0x00,0xC0,0x00,0xC0,0x01,0x80,0x03,0x00,0x7E,0x00,0x7C,0x00,0x00,0x00

eeprom code_pack 0xf00000
 de 0x11,0x10,0x29,0x04,0x02
 de 0x12,0x03,0x25,0x03,0x03 ;year-month-day-min-diff
 de 0x12,0x10,0x28,0x04,0x02
 de 0x13,0x03,0x31,0x03,0x03 ;year-month-day-min-diff
 de 0x13,0x10,0x27,0x04,0x02
 de 0x14,0x03,0x30,0x03,0x03 ;year-month-day-min-diff
 de 0x14,0x10,0x26,0x04,0x02
 de 0x15,0x03,0x29,0x03,0x03 ;year-month-day-min-diff
 de 0x15,0x10,0x25,0x04,0x02
 de 0x16,0x03,0x27,0x03,0x03 ;year-month-day-min-diff
 de 0x16,0x10,0x30,0x04,0x02
 de 0x17,0x03,0x26,0x03,0x03 ;year-month-day-min-diff
 de 0x17,0x10,0x29,0x04,0x02
 de 0x18,0x03,0x25,0x03,0x03 ;year-month-day-min-diff
 de 0x18,0x10,0x28,0x04,0x02
 de 0x19,0x03,0x31,0x03,0x03 ;year-month-day-min-diff
 de 0x19,0x10,0x27,0x04,0x02
 de 0x20,0x03,0x29,0x03,0x03 ;year-month-day-min-diff
 de 0x20,0x10,0x25,0x04,0x02
 de 0x21,0x03,0x28,0x03,0x03 ;year-month-day-min-diff
 de 0x21,0x10,0x31,0x04,0x02
 de 0x22,0x03,0x27,0x03,0x03 ;year-month-day-min-diff
 de 0x22,0x10,0x30,0x04,0x02
 
 END