;*****ustawianie nazw zmiennych i stalych**** 
;
;   XC = 3.2768 MHz
;      4
;  --------- = 819200 instrukcji/sekunde
;  3.2768MHz
;
; prescaler = 128
; 819200 / 128 = 6400 = 256 * 25
; TIMER0 ma pojemnosc do 256 wiec musi sie przepelnic 25 razy zeby tyknela 1 sekunda.
;
; Converting code to 628A:
; To add to the needed config bit changes. 
; The GPR’s start at 0x20. 
; Turn the Comparator module off with <movlw 0x07> <movwf CMCON>. 
; Adjustment of basic 84 code to 628/a code is easy-peasy.  


;LIST   P=16F84A   ;rodzaj mikrokontrolera
LIST   P=16F628A  
include "p16F628A.inc"
__CONFIG _CP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _BODEN_OFF & _LVP_OFF

radix   hex         ;domyslny system zapisu liczb
;__config 0x3ff1     ;wdt off, XT osc

;STATUS   equ   03h ;Adres rejestru statusu
;TRISA   equ   85h ;Adres konfiguracji portu A
;PORTA   equ 05h ;Adres portu A
;TRISB   equ 86h ;Adres konfiguracji portu B
;PORTB   equ 06h ;Adres portu B
TIMER   equ   01h ;Adres Timera 0
;GIE      equ   07h ;Bity konfiguracyjne....
;T0IE   equ   05h 
;T0IF   equ 02h
;INTCON   equ 0Bh

; TABELA ZE ZMIENNYMI PROGRAMOWYMI: 

cblock 0x20
COUNT1   ;Dwie petle opoznienia
TEMP     ;zmienna tymczasowa
G_1      ;zmienna z czasem GG:MM:SS
G_2      
M_1      
M_2      
S_1      
S_2      
COUNT2   
tick   
COUNT3   
endc


org      0x00      ;wyznaczam oryginalny poczatek programu
goto   Cdalszy

org      0x04      ;poczatek kodu przerwania
   movwf TEMP      ;kopiuje w do tempa /na wszelki wypadek ;p/

   decfsz COUNT2,1   ;jesli bit = 1 to zmniejsza COUNT2 o 1:
   goto koniec2   ;jesli count2 != 0 ide do konca
               ;jesli count == 0 kontynuuje i...
   movlw   tick   ;ustawiam tick spowrotem na 4
   movwf   COUNT2

   incf S_2,1      ;...zwiekszamy ilosc sekund o 1   

   ;clrf TIMER      ;czyszcze timer 00000000

   koniec2
   bcf INTCON,T0IF
   movf TEMP,w      ;kopiuje TEMPA do w /przywracam w/
retfie            ;koniec kodu przerwania

Cdalszy
;****ustawienia portow****
movlw 0x07 
movwf CMCON
bsf      STATUS,5   ;Wchodze na Bank1
movlw   b'00000'      ;Wpisuje 00000 do TRISA,
movwf   TRISA       ;i ustawiam caly portA jako output
movlw   b'11000000' ;Wpisuje 00111111 do TRISB 
movwf   TRISB       ;i ustawiam portB jako 6xOutput i 2xInput
bcf      STATUS,5    ;Wchodze na Bank0

;****ustawiena prescalera****
movlw   b'11010110'      ;Bit   opis   00000110 - prescaler=128
option               ;0   Prescaler Value
                  ;1   Prescaler Value
                  ;2   Prescaler Value
                  ;3   Prescaler Assignment (0=tmr0, 1=watchdog timer)
                  ;4   tmr0 external edge clock select (0=rising, 1=falling)
                  ;5   tmr0 clock source (0=internal instruction cycle, 1=external) 
                  ;6   Interrupt edge select (0=falling, 1=rising)
                  ;7   Port B Pullup Enable (0=enabled, 1=disabled)
bsf INTCON,GIE
bsf INTCON,T0IE
clrf TIMER

clrf COUNT1

movlw   tick    ;wpisuje 25 do conut2
movwf   COUNT2

;***********************************************START PROGRAMU
Start
   call licz
   call sprawdz_przycisk_min
   call sprawdz_przycisk_godz

   call    L1_akt   ; lampa 1 aktywna Hh:mm:ss
   movf   G_1,w   ; wpisuje G_1 do W
   movwf   PORTA   ; wpisuje W na port A
   call    Delay

   call    L2_akt   ; lampa 2 aktywna Hh:mm:ss
   movf   G_2,w   ; wpisuje G_2 do W
   movwf   PORTA   ; wpisuje W na port A
   call    Delay

   call    L3_akt   ; lampa 3 aktywna Hh:mm:ss
   movf   M_1,w   ; wpisuje M_1 do W
   movwf   PORTA   ; wpisuje W na port A
   call    Delay

   call    L4_akt   ; lampa 4 aktywna Hh:mm:ss
   movf   M_2,w   ; wpisuje M_2 do W
   movwf   PORTA   ; wpisuje W na port A
   call    Delay

   call    L5_akt   ; lampa 5 aktywna Hh:mm:ss
   movf   S_1,w   ; wpisuje S_1 do W
   movwf   PORTA   ; wpisuje W na port A
   call    Delay

   call    L6_akt   ; lampa 6 aktywna Hh:mm:ss
   movf   S_2,w   ; wpisuje S_2 do W
   movwf   PORTA   ; wpisuje W na port A
   call    Delay

goto Start

;****stale fragmenty programu****
;zapalanie 1..6 lampy
L1_akt
   movlw b'00000001'
   movwf PORTB
return

L2_akt
   movlw b'00000010'
   movwf PORTB
return

L3_akt
   movlw b'00000100'
   movwf PORTB
return

L4_akt
   movlw b'00001000'
   movwf PORTB
return

L5_akt
   movlw b'00010000'
   movwf PORTB
return

L6_akt
   movlw b'00100000'
   movwf PORTB
return

;opoznienie
Delay
   clrwdt
   Loop1   decfsz   COUNT1,1   ; petla 255x
         goto   Loop1
return

Delay2
   clrwdt
   Loop2   decfsz   COUNT1,1   ; petla 255x255
         goto    Loop2
         decfsz   COUNT3,1
         goto   Loop2
return

;ustawianie godziny
sprawdz_przycisk_min
   BTFSS PORTB,6      ;sprawdz przycisk minut
   goto sprawdz_end   ;jesli nie wcisniety to koncz
   call Delay2         ;jesli wcisniety to czekaj chwile
   BTFSS PORTB,6      ;i jesli dalej wcisniety to zwiekszam minuty o +1
   goto sprawdz_end
   incf M_2,1

   btfss M_2,3      ;jesli  M_2 != 8 to
   goto sprawdz_end; idzie do konca
   btfss M_2,1      ; a jesli jest 8 to sprawdzam czy nie 10 :-)
   goto sprawdz_end; jesli nie to ide do konca
   goto min_2      ; jesli tak to zeruje minuty i dodaje +1 do dziesiatek minut

   sprawdz_end
return

sprawdz_przycisk_godz
   BTFSS PORTB,7      ;sprawdz przycisk minut
   goto sprawdz2_end   ;jesli nie wcisniety to koncz
   call Delay2         ;jesli wcisniety to czekaj chwile
   BTFSS PORTB,7      ;i jesli dalej wcisniety to zwiekszam minuty o +1
   goto sprawdz2_end
   incf G_2,1

   btfss G_1,1         ;jesli G_1 != 2 to
   goto cd            ;idzie do konca
   btfss G_2,2         ;jesli G_2 != 4 to
   goto cd   ;idzie do konca albo resetuje godzine
   clrf G_1
   clrf G_2

   cd

   btfss G_2,3         ;jesli  G_2 != 8 to
   goto sprawdz2_end   ;idzie do konca
   btfss G_2,1         ;a jesli jest 8 to sprawdzam czy nie 10 :-)
   goto sprawdz2_end   ;jesli nie to ide do konca
   incf G_1,1         ;jesli tak to dziesiatki godzin +1, 
   clrf G_2         ;czyszcze jednostki godzin
                  ;i robie test na 24:00:00...
   sprawdz2_end
return

;liczenie godziny...
licz
   btfss S_2,3      ;jesli  S_2 != 8 to
   goto koniec      ;idzie do konca
   btfss S_2,1      ;a jesli jest 8 to sprawdzam czy nie 10 :-)
   goto koniec      ;jesli nie to ide do konca
   goto dziesiatki   ;jesli tak to zeruje sekundy i dodaje +1 do dziesiatek sekund

   dziesiatki
   incf S_1,1   ; zwiekszam dziesiatki sekund o +1
   clrf S_2;

   btfss S_1,2 ; jesli S_1 != 4 to
   goto koniec ; idz do konca
   btfss S_1,1   ; a jesli nie to sprawdza czy nie 6 przypadkiem
   goto koniec ; jak nie to koniec
   goto min_1  ; jak tak to skok do labela min_1

   min_1
   clrf S_1   ; czyszcze S_1
   incf M_2,1 ; jednosci minut +1

   btfss M_2,3      ;jesli  M_2 != 8 to
   goto koniec      ; idzie do konca
   btfss M_2,1      ; a jesli jest 8 to sprawdzam czy nie 10 :-)
   goto koniec      ; jesli nie to ide do konca
   goto min_2      ; jesli tak to zeruje minuty i dodaje +1 do dziesiatek minut
   
   min_2
   clrf M_2   ;czyszcze M_2
   incf M_1,1 ; dziesiatki minut +1

   btfss M_1,2 ; jesli M_1 != 4 to
   goto koniec ; idz do konca
   btfss M_1,1   ; a jesli nie to sprawdza czy nie 6 przypadkiem
   goto koniec ; jak nie to koniec
   goto godz_1 ; jak tak to skok do labela godz_1

   godz_1
   clrf M_1   ;czyszcze M_1
   incf G_2,1 ; +1 do godzin

   btfss G_1,1    ; jesli godzina != 2x:xx:xx
   goto kontyn      ; idz do kontynuuj
   btfss G_2,2      ; albo sprawdz czy nie 24:xx:xx
   goto kontyn      ; jesli nie to kontynuuj
   goto resetuj   ; jesli tak to resetuj

   resetuj
   clrf G_1   ;czyszcze G_1
   clrf G_2   ;i G_2
   goto koniec   

   kontyn
   btfss G_2,3      ;jesli  G_2 != 8 to
   goto koniec      ; idzie do konca
   btfss G_2,1      ; a jesli jest 8 to sprawdzam czy nie 10 :-)
   goto koniec      ; jesli nie to ide do konca
   goto godz_2      ; jesli tak to zeruje jednostki i dodaje +1 do dziesiatek godzin

   godz_2
   clrf G_2   ;czyszcze G_2
   incf G_1,1
   koniec
return

end