	list	P=PIC12F629
	include  "P12F629.INC"

	__CONFIG _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT

#define egyes b'00010000' ; középső 1-es pont - GP4-es láb
#define kettes b'00000001' ; egyik kettes átló - GP0-ás láb
#define kettesb b'00000100' ; másik kettes átló - GP2-es láb
#define kettesc b'00000010' ; középső kettes vonal - GP1-es láb
#define harmas (egyes  | kettes)
#define harmasb (egyes | kettesb)
#define negyes (kettes | kettesb)
#define otos (kettes | kettes | egyes)
#define hatos (kettes | kettesb | kettesc)
#define hetes (kettes | kettesb | kettesc | egyes)
#define hangsz b'00100000' ; hangszóró a GP5-re kötve
#define hangszb d'5'

ck	equ	20h			
delay1  equ 21h
delay2  equ 22h
delay3  equ 23h
szam_0  equ 24h
kikapcsolo equ 25h
on_count equ 26h
periodusido equ 27h
timer equ 28h


PROG CODE 0
	goto	start
start:
	bsf		STATUS, RP0	
	call	3ffh		
	movwf	OSCCAL		
	movlw	b'00001000'
	movwf	TRISIO
	movlw	b'00000000'
	movwf	OPTION_REG
	movlw	b'00001000'	
	movwf	IOC
	bcf		STATUS, RP0	;
	clrf	GPIO
	movlw	b'00000111'
	movwf	CMCON		
	movlw	b'00001000'	;
	movwf	INTCON		;

	movlw b'11001000'
	movwf OPTION_REG

 	btfsc STATUS,3 ; 0 a harmadik bit?
 	goto poweronreset ; ha bekapcsolás vol6t , akkor a reset rutinhoz ugrik


 	btfsc kikapcsolo,0 ; 0 a kikapcsoló alsó bit?
 	goto kikapcs ; ha bit 1-es, akkor kikapcsol

 	call delay100ms  ; késleltetés a nyomógomp pergésének kiküszöbölésére
 	bsf kikapcsolo,0 ; ha a következő pár sorban jel érkezik a nyomógombtól, akkor kikapcsolás

 	movfw  TMR0  ; timer olvasása a véletlenszám generálásához
 	movwf  timer ;az elsőnek olvasott valódi véletlenszám tárolása

	call  villogtat_1 ; LED-ek villogtatása, csak a játék kredvéért :) + késleltetés + hang
	clrf  kikapcsolo  ; innentől a gombnyomás nem vált ki kikapcsolást
	call  villogtat_1 ; LED-ek villogtatása, csak a játék kredvéért :) + késleltetés + hang

	movfw  timer  ; előkészítés a véletlenszám osztásához
	call osztas ; osztási maradék a szam_0 változóban
	movfw szam_0 ; w-ban (0...11)
	call  szamok ; konvertálás (egyes-hatos)
	movwf GPIO ; a tárolt érték kijelzése, vagyis a LED-ek állapotának beállítása
  
	movlw d'6' ; várakozás
	movwf ck ; enyiszer fut le a ciklus
	call delay20s ; késleltetés
	decfsz ck,1 ; ck csökkentlése 0-ig
	goto $-2 ; visszaugrás 2 sort, ha még nem nulla

	goto kikapcs ; elég hosszú idő telt el, kikapcsolás
;*********************************************
beep_1:

	; hang előállítási rutin
 	movlw d'200' ; 200 ciklusos lesz
 	movwf delay1
bp1:
	movlw d'80' ; ettől függ a periódusidő
	addwf szam_0,w ; és persze a számtól is, hogy többféle hangmagasság legyen
	movwf periodusido ; eltesszük a változóba az aktuális értéket
  

	swapf  delay1,w ; kiszámolunk egy másik lehetséges frekvenciát is
	andlw d'15' ; ez nem a számtól, hanem külső ciklustól függ
	iorlw d'80'
	;btfsc on:count,0
	btfsc timer,6 ; ez dönti el, hogy a két kiszámolt frekvencia közül melyik szóljon éppen


	decfsz periodusido,1 ; periódusidő várakozó ciklusa
	goto $-1
	movlw hangsz ; a hanszóró bitje a GPIO porton
	xorwf GPIO,1 ; hangszóró bit invertálása
	decfsz delay1,1 ; 0-ig fogunk számolni
	goto bp1 ; vissza a ciklus elejére

	bcf GPIO,hangszb ; a végén a hangszóró kikapcsp (biztos, ami biztos alapon :))
	retlw 0 ; visszatérés a függvényből
;********************************************
villogtat_1:

	movlw d'11' ; ez egy ennyiszer lefutó ciklus lesz
	movwf ck ; szám a cilusváltozóba

jmp1:

	; véletlenszám generálás (ez csak a villogás miatt kell)
	call sorsol ; szám: 0...11 a szam_0 változóban
	movwf szam_0 ; a dobott érték kijelzése
 	call szamok ; konvertálás a LED-ek portra kötése szerinti fotmára
	movwf GPIO ; LED-ek bekapcsolása

	;call delay100ms ; várakozás - ez volt korábban
	call beep_1 ;most hangot is adunk ki
	decfsz ck,1 ;ismétlés amíg a ciklusváltozó nullára csökken
	goto jmp1 ; vissza a ciklus elejére

	retlw 0 ; visszatérés a függvémnyből
;***************************

poweronreset:

	 ; ide ugrik, ha a program resettel kezdett (pl.: elemcsre)
	clrf on_count ;bekapcsolásszámláló nullázás
	movlw hetes ; összes LED bekapcsolás (hetest dobtam! :))
	movwf GPIO ; bekapcsoljuk a LED-eket
kikapcs:

	call delay100ms ; késleltestés a gombpergés és hasonlók miatt
	call beep_1 ; hanszóró csippantás + még késleltetés
	incf on_count,1 ;bekapcsolás számolás (valójában kikapcsolást számolunk, de mostmár mindegy)
	clrf kikapcsolo ; kikapcsoló nullázása, hiszen mindjárt kikapcsolunk
	clrf GPIO ; kimenetetk nullázása, LED-ek és a hangszóró kikapcsolása
	sleep ; alvó üzemmód, kikapcsolás a következő reset-ig
;***********************************
sorsol:

	; véletlenszám generálás
	movfw TMR0 ; a beépített TIMER értékét olvassuk véletlenszámnak
  
osztas:

	movwf szam_0
	movlw d'12' ;12-vel fogunk osztani
	bcf STATUS,C ; C-biz nullázása, megint csak biztos, ami biztos alapon :)
	subwf szam_0,w ; levonjuk az osztót
	BTFSC STATUS,C ; addig amíg sz osztandó el nem fogy
	goto osztas ; vissza a ciklus elejére, ha az osztandó még nem 0	
	; az osztási maradék a szam_0 változóba került	
;***********************************
szamok:

	; itt valósítjuk a meg a szám- LED-ek állapota konverziót
	addwf PCL,f
	retlw egyes
	retlw kettes
	retlw harmas
	retlw negyes
	retlw otos
	retlw hatos
	retlw egyes
	retlw kettesb
	retlw harmasb
	retlw negyes
	retlw otos
	retlw hatos
;********************************
delay20s:

	 ; ez az egyik késleltető ciklus, semmi mást nem csinál, csak futnak a ciklusok és közbentelik az idő
	clrf delay3
	goto d2

delay100ms:

	; 100ms késleltetés
	movlw 1
	movwf delay3
d2:
	movlw d'70'
	movwf delay2
d1:

	clrf delay1
	decfsz delay1,f
	goto $-1  

	decfsz delay2,f
	goto d1
	decfsz delay3,f
	goto d2

	retlw 0
;**********************************************

OSCVAL	CODE
OscCalVal
	retlw	0
	end

