

	list		p=16f684		; list directive to define processor
	#include	<P16F684.inc>		; processor specific variable definitions
	
	__CONFIG    _CP_OFF & _CPD_OFF & _BOD_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF


; FIGYELEM---> az időzitések 4MHz-es órajelre vonatkoznak!!!!

;***** VARIABLE DEFINITIONS
w_temp		EQU	0x7E			; variable used for context saving
status_temp	EQU	0x7F			; variable used for context saving

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;->RANDOMhoz<-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
random					EQU	3F	; ebben keletkezik 4(2)-percenként egy-egy újabb véletlen-szám!...	
RNDshift				EQU	3E	; ...ami ebből tolódik ki a 4094-es IC(k)-be.
pulse_timer				EQU	3D	; 
time_for_30sec			EQU	3C	; kezdőérték a 30 másodperc időhöz(60-->letöltve EEPROMból)
RNDcntrL				EQU	003B; le-számláló a 30 másodperchez(indul a fenti értékről)
time_for_2min			EQU	3A	; kezdőérték a 2 perc időhöz(04-->letöltve EEPROMból)
RNDcntrH				EQU	39	; le-számláló a 2 perchez(indul a fenti értékről)
XORbyteRND				EQU	38	; ezzel kifordithatjuk/vagy nem/a "random" bájtot(vagy bitjeit) az "RNDshift" számára! (-->letöltve EEPROMból)
IORbyteRND				EQU	37	; amelyik bit ebben a bájtban =1, az ahhoz tartozó lámpa állandóan világit! (-->letöltve EEPROMból)
ANDbyteRND				EQU	36	; amelyik bit ebben a bájtban =0, az ahhoz tartozó lámpa sohasem világit! (-->letöltve EEPROMból)
cntr_gen				EQU	35	; egy újabb generál-számláló
flags					EQU 34	; különféle jelzőbitek helye

#define	pulse_for_RND	PORTA,RA5	; kimenet, a véletlenszerűen kapcsolt világitások számára küldi át a véletlen-bájtot kb.2 percenként.

#define	RANDOM_calc_method	flags,4	; 0-->calc by A.Warren, 1-->calc by N.Golovchenko.

#define ZERO	STATUS,Z
#define CARY	STATUS,C


;ĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐd
;**********************************************************************
	ORG		0x0000			; processor reset vector
	call		INIC
  	goto		main_program	; go to beginning of program

;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
	ORG		0x0004			; interrupt vector location
	movwf		w_temp			; save off current W register contents
	movf		STATUS,w		; move status register into W register
	movwf		status_temp		; save off contents of STATUS register

; isr code can go here or be located as a call subroutine elsewhere

	movf		status_temp,w		; retrieve copy of STATUS register
	movwf		STATUS			; restore pre-isr STATUS register contents
	swapf		w_temp,f
	swapf		w_temp,w		; restore pre-isr W register contents
	retfie					; return from interrupt
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
	ORG	0x0100
INIC
;
;
; Az inic során gondoskodni kell az állandók letöltéséről az EEPROMból!
; Továbbá alapértékre kell tölteni a számlálókat, és meginditani a TIMER1-et!
; A "random"-nak is itt adunk alapértéket, pl. a TIMER0 értékét beleirva!
; Majd valamelyik főprogrambeli művelet során -- amelyik nem állandó idejű távolságra van a program meginditásától...
;...(pl. ahol emberi beavatkozás kell) -- újratöltjük a "random"-ot a TIMER0-ból. Igy lesz 'valódi' álvéletlen-bájtunk a továbbiakban!
;
;
		return
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ


;ŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁ
main_program

; itt jönne a főprogram, ami bármi lehet.
; NAGYON FONTOS: a főprogramba elég sűrűn be kell ágyazni az alábbi részletet:

	banksel	INDF
		btfsc	PIR1,TMR1IF		; TIMER-1 lejárt? Átugrás, ha még nem járt le.
		call	rutin_for_TIMER1_overflow	; lejárt: meghivjuk, mert "BÁRMILYEN FŐPROGRAM-RÉSZ"-végrehajtása alatt lejárhatottt!

; Igy némi kis szórással körülbelül pl.2 percenként sor kerülhet a lámpa-váltásra. De a pontatlanság csak fokozza a véletlenszerűséget!
; Ha mégis pontosan 2 percenként akarjuk a váltást, akkor használni kell a TIMER-1 megszakitását, és onnan kell meghivni az alábbi rutint.

;ŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁŁ



;rndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrnd
; -RANDOM-LAMP --- A VÉLETLEN-LÁMPAKAPCSOLGATÓ szubrutin--> ---RANDOM-LAMP----RANDOM-LAMP--
;rndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrnd
rutin_for_TIMER1_overflow
	banksel	INDF
		nop
;OVERFLOW--oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
		bcf		T1CON,TMR1ON	; először leállitjuk.
		movlw	d'244'			; ~0,5 sec @ 4MHz ==> 499,72msec KIMÉRVE!
		sublw	00				; mert felfelé számol.
		movwf	TMR1H
		clrf	TMR1L
		bsf		T1CON,TMR1ON	; újra meginditjuk.
		bcf		PIR1,TMR1IF		; IR-flag törölve.
		decfsz	RNDcntrL,f		; LSB-számláló csökkentése, és lejárt? Átugrás, ha lejárt.
		return				; nem járt még le!
		movfw	time_for_30sec	; ~0,5 perc @ 4MHz ==> 29,98sec KIMÉRVE!
		movwf	RNDcntrL		; újratöltjük az LSB-számlálót!
		decfsz	RNDcntrH,f		; MSB-számláló csökkentése is, és lejárt? Átugrás, ha lejárt.
		return				; nem járt még le!
		movfw	time_for_2min	; ~2 perc @ 4MHz ==> 119,9sec KIMÉRVE!
		movwf	RNDcntrH		; újratöltjük az MSB-számlálót is!
		goto	make_RND_byte_and_transfer	; majd ekkor átküldünk egy újabb lámpa-kapcsolgató VÉLETLEN bitmintát!!!! RETURN majd onnan!
;OVERFLOW--oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
;
;____________________________________________________________________________________________________
make_RND_byte_and_transfer;---------------
		nop			
;............................először is képezünk egy újabb RND-bájtot:...
		btfss	RANDOM_calc_method				; átugrás, ha Golov kell.
		call	calc_newRNDbyte_byWARREN
		btfsc	RANDOM_calc_method				; átugrás, ha Waren kellett.
		call	calc_newRNDbyte_byGOLOVCHENKO
		nop
;=====================================================================================================
byte_transfer_to_4094IC_inRND
;............................azután ezt az RND-bájtot átküldjük a lámpa-kapcsolgató áramkörnek(4094IC):
		movlw	08
		movwf	cntr_gen
lupSHFT	rlf		RNDshift,f		; a 7. bittel kezdjük a küldést!
		btfss	CARY
		goto	bit_00			; egy 0-bit kiküldés/beirás teljes ideje: 4,015 msec! Kimérve.
		goto	bit_11			; egy 1-bit kiküldés/beirás teljes ideje: 4,016 msec! Kimérve.
;................................
bit_00;..........................==>3,5 msec
		movlw	d'250'
		movwf	pulse_timer	
		bsf		pulse_for_RND	; indul a 3,5 msec-os HI-impulzus!--->250*14us=3500usec! Kimérve.
loop_00	goto	$+1				; 2
		goto	$+1				; 4
		goto	$+1				; 6
		goto	$+1				; 8
		goto	$+1				; 10
		nop						; 11
		decfsz	pulse_timer,f	; 12
		goto	loop_00			; 14
		bcf		pulse_for_RND	; végetér a 3,5 msec-os HI-impulzus!
		goto	after_0_pause_to_next_bit
bit_11;..........................==>1 msec
		movlw	d'250'
		movwf	pulse_timer	
		bsf		pulse_for_RND	; indul az 1 msec-os HI-impulzus!--->250*4us=1000usec! Kimérve.
loop_11	nop						; 1 usec
		decfsz	pulse_timer,f	; 2
		goto	loop_11			; 4
		bcf		pulse_for_RND	; végetér az 1 msec-os HI-impulzus!
		goto	after_1_pause_to_next_bit
;................................
after_0_pause_to_next_bit;.......
		movlw	d'125'			; --->125*4us=500usec ======>3500+500=4000usec.
		movwf	pulse_timer	
loop_0p	nop						; 1 usec
		decfsz	pulse_timer,f	; 2
		goto	loop_0p			; 4
		goto	next_bit
after_1_pause_to_next_bit;.......
		movlw	d'250'			; --->250*12us=3000usec ======>1000+3000=4000usec.
		movwf	pulse_timer	
loop_1p	goto	$+1				; 2
		goto	$+1				; 4
		goto	$+1				; 6
		goto	$+1				; 8
		nop						; 9
		decfsz	pulse_timer,f	; 10
		goto	loop_1p			; 12
		goto	next_bit
;................................
next_bit;........................	
		decfsz	cntr_gen,f
		goto	lupSHFT
		return

;=====================================================================================================
;WARREN--wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
calc_newRNDbyte_byWARREN
		rlf		random,w	; RANDOM 7.bitje a CARRYbe megy...
		rlf		random,w	; ...most pedig onnan a "W" 0.bitjébe jön be jobbról---> ez az igazi forgatás!!
		btfsc	random,4
		xorlw	01
		btfsc	random,5
		xorlw	01
		btfsc	random,3
		xorlw	01
		movwf	random		; ...MEGVAN!!
		xorwf	XORbyteRND,w; kiforditom(vagy nem) az egyes(összes) biteket, hogy még cifrább legyen!
		iorwf	IORbyteRND,w; amelyik bit =1 az "IORbyteRND"-ben, az a lámpa mindig ég!
		andwf	ANDbyteRND,w; amelyik bit =0 az "ANDbyteRND"-ben, az a lámpa sosem ég!
		xorlw	00ff		; és még kiforditom, hogy bit=1 esetén égjen a lámpa, ehhez pedig LO-szintet kell irni a 4094-es IC-be!!			
		movwf	RNDshift	; és ide letesszük a sifteléshez.
		return
;WARREN--wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
;
;GOLOVCHENKO--gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
calc_newRNDbyte_byGOLOVCHENKO
		bcf		CARY							; from: Robert LaBudde and Nikolai Golovchenko
		rlf     random,f						; ALAPBÓL: Rnew = Rold * 221 + 53, aholis: 221 = 256 - 32 - 4 + 1
		swapf   random,w						; VÉGÜL: Rnew = Rold * (-35) + 53
		andlw   00e0
		rrf     random,f
		addwf   random,w
		addwf   random,w
		addwf   random,w
		sublw   35
		movwf   random		; ...MEGVAN!!
		iorwf	IORbyteRND,w; amelyik bit =1 az "IORbyteRND"-ben, az a lámpa mindig ég!
		andwf	ANDbyteRND,w; amelyik bit =0 az "ANDbyteRND"-ben, az a lámpa sosem ég!
		xorlw	00ff		; és még kiforditom, hogy bit=1 esetén égjen a lámpa, ehhez pedig LO-szintet kell irni a 4094-es IC-be!!			
		movwf	RNDshift	; és ide letesszük a sifteléshez.
		return			
;GOLOVCHENKO--gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
;
;rndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrnd
; -RANDOM-LAMP --------- A VÉLETLEN-LÁMPAKAPCSOLGATÓ szubrutin-->VÉGE --------- RANDOM-LAMP
;rndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrndrnd




	ORG	0x2100	; data EEPROM location
;
;
;
timer_constants_forRND	ORG	0x214C
	DE	d'060',	d'004'	; CV77-->0,5-perces és CV78-->2-perces időzitési állandók a VÉLETLEN-VILÁGITÁS-hoz!!

bit_alternation_bytes	ORG	0x214E
	DE	0xA5		; CV79: a bit-kiforditó(vagy nem) bájt! Ha =00, akkor egyetlen bitet sem fordit! Ha =FF, akkor minden bitet kifordit!
	DE	0x00		; CV80: a bit-bekapcsoló(vagy nem) bájt! Amelyik bit =1, az ahhoz tartozó véletlen-lámpa állandóan világit!
	DE	0xFF		; CV81: a bit-kikapcsoló(vagy nem) bájt! Amelyik bit =0, az ahhoz tartozó véletlen-lámpa sohasem világit!



	END                       ; directive 'end of program'

