   title  "4-digit Serial Nixie Clock For Leigh"
;#define Debug
;
;	The clock uses a watch tuningfork crystal that
;	clocks at 32kHz along with an RTC chip from TI.   
;	
;  Hardware Notes:
;   This application runs on a 16F87 executing at 4 MHz with the internal osc.
;   _MCLR is tied through a 10K Resistor to Vcc and PWRT is Enabled.  
;	Port B is used as a general purpose data output bus.  The data are 
;	sent out in 32-bit chunks, made up of 4 8-bit registers.  Separate
;	functions build the data block so that multiplexing is done in 
;	software as opposed to hardware.  Only two nixies' cathodes are tied
;	low at a time in this manner...  Time from the RTC comes in BCD format, so I will 
; 	be converting BCD to decimal in EEPROM this time as usual.  
;

  	LIST R=DEC, P=16F87
 	#INCLUDE "p16f87.inc"
LIST
	CLK		EQU		7;
	DAT		EQU		6;
	OE		EQU		5;	
	SCL		EQU		4;
	SDA		EQU		1;

;  Registers
CBLOCK 0x020
	;;registers!
	_w, _status, _pclath, _fsr			;  Context Register Save Values
	

	ByteA	;
	ByteB	;
	ByteC	;
	ByteD	;
;	second	;
	correct_hours;
	correct_minutes;
	minutes_high;
	minutes_low;
	minutes	;
	hours_high;
	hours_low;
	hours	;
	minutes_old;
	hours_old;
	PWM		;
			;bit 5 = spin flag
			;bit 0 = PWM hi-low state
			;bit 1 = time update flag	
	PWMOn	;
	brigntness;
	A_or_B;
	keys	;
	temp_w;
	Data_in;
	Data_out;
	i2c_count;
	serial_count;
	display_out;
	show_timer;
	which_tube;
	spinner;
	spin_timer;
	spin_timer2;
	slave;
	slave_temp;
	data_container;
	wr_address;
	re_address;
	msd_temp
	lsd_temp;

ENDC

PAGE

;Program Configuration Register 1
		__CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_CLKOUT

;Program Configuration Register 2
		__CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF

  
;  Mainline of Timer


org     0x0 	;reset vector
  	goto   	Mainline

org     0x4	;interrupt vector
	goto	Int

org 	0x10
Mainline					
	movlw	0x4F;	; Register initialization
	movwf	PWMOn;
	
	movlw   0xFF;
	movwf	ByteA;
	movwf	A_or_B;
	movwf	ByteB;
	movwf	ByteC;
	movwf	ByteD;
	
	movwf	minutes
	movwf  	hours
	movwf	data_container;
	movwf	hours_low;
	movwf	hours_high;
	movwf	minutes_low;
	movwf	minutes_high;
	movwf	Data_in;
	movwf	Data_out;	
	movwf	temp_w;
	movwf	lsd_temp;
	movwf	msd_temp;
	movwf	serial_count;
	movlw	b'01010101'
	movwf	display_out;	
	movlw	0x01;
	movwf	spinner;
	movwf	spin_timer;
	movwf	spin_timer2;
	movwf	minutes_old;
	movwf	hours_old;
	movwf	PWM;

							;Special register initialization
	clrf 	Data_in;
	clrf	Data_out;
	bsf		STATUS, RP0;
	movlw	0x11;
	movwf 	TRISB;
	movlw	0x1F;
	movwf	TRISA 			;  PORTA is input

	movlw  0x0C5			;  0x0C0 - Minimum Timer Delay	
;	movlw  	0x0C4			;  0x0C0 - Minimum Timer Delay	
;	movlw	0xC0;
	movwf  	OPTION_REG

	movlw 	0x070
	movwf	OSCCON
	clrf	STATUS			;bank 0
	CLRF 	SSPSTAT 		; SMP = 0, CKE = 0, and clear status bits
	MOVLW 	0x00 			; Set up SPI port, Master mode, CLK/16,
	MOVWF 	SSPCON 			; Data xmit on falling edge (CKE=1 & CKP=1)
	bcf		STATUS, RP0
	
	; initialize the RTC chip
	; should be like 1 or 2 writes.
	; might also set the starting 
	; time to something specific
	; so another 2 writes
setup_script
	movlw	0xF0;
	movwf	temp_w;
	call	Delay;	
	movlw	0xD0;
	movwf	slave;
	movlw	0x0C; 	;halt time
	movwf	wr_address;
	movlw	0x00;
	movwf	data_container;
	movlw	0xF0;
	movwf	temp_w;
	call 	Delay;
	call	write_a_byte;
	movlw	0x0C; 
	movwf	re_address;
	call	read_a_byte;
	movfw	Data_in;
	btfsc	Data_in, 6;
		goto	setup_script;
	nop;
	nop;
	movlw	0xD0;
	movwf	slave;
	movlw	0x02;	minutes
	movwf	re_address;
	call	read_a_byte;
	movfw	Data_in;
	movwf	correct_minutes;
	movwf	minutes_old;
	movlw	0x03;	hours
	movwf	re_address;
	call	read_a_byte;
	movfw	Data_in;
	movwf	correct_hours;		
	movwf	hours_old;
	nop;
	nop;
	movlw	0x01	;control, seconds
	movwf	re_address;	
	call	read_a_byte;
	movfw	Data_in;
	btfsc	Data_in, 7;
		goto	set_start;
	
	goto	Enable_Interrupts;
set_start	;also set time regs
	movlw	0x01;
	movwf	wr_address;
	movlw	0x00	;start oscillator, fool! seconds = 30;
	movwf	data_container;
	movlw	0x0F;
	movwf	temp_w;
	call 	Delay;
	call	write_a_byte;	
	movlw	0x03;	;hours
	movwf	wr_address;
	movlw	0x08;	
	movwf	data_container;
	movlw	0x0F;
	movwf	temp_w;
	call 	Delay;
	call	write_a_byte;
	movlw	0x02;
	movwf	wr_address;	;minutes;
	movlw	0x17;
	movwf	data_container;
	movlw	0x0F;
	movwf	temp_w;
	call 	Delay;
	call	write_a_byte;

;	goto	setup_script
Enable_Interrupts
	clrf  	TMR0			;  Start the Timer from Scratch
	movlw  	b'11100000'
  	;movlw  (1 << GIE) + (1 << T0IE)
  	movwf  INTCON			;  Enable Interrupts
Loop						;  Loop Here
	btfss	PWM,1;	;bit "1" is the display update bit 
		goto 	Skip_update;	(remember to set it in INT_PWM when PWM goes low)
	call 	download_time;
	call	load_display;
	call	display_update;
	bcf	PWM,1;		;reset update flag
	
Skip_update
	
;	movlw	0x01;
	movf	PORTA, w;
   	xorwf	keys, w;		
	andlw	0x0F		;only check the 4 button pins
	btfsc	STATUS,Z	;test, if Z=0, no buttons
		goto	Loop		;no, loop again
	xorwf	keys,f
	movlw	0xFF;		;long,short delay
;	movlw	0x04;
	movwf	temp_w;
	call	Delay
Debounce
	;movlw	0xA0
	movlw	0xFF;			
;	movlw	0x04;
	movwf	temp_w;
	call	Delay
	movf	PORTA, w;
	movwf	keys;
test_hours	
	btfsc	keys, 0		;hours 
		goto test_minutes;
	call	Hours;		
	goto	Loop;
test_minutes
	btfsc	keys, 1		;minutes
		goto test_brightness;
	call 	Minutes;
	goto	Loop;	
test_brightness
	btfsc	keys, 2		;brightness
		goto test_spinner;
	call 	Dimmer;
	goto	Loop;
test_spinner
	btfsc	keys, 3
		goto Loop;
	call	set_spinner;
	goto	Loop;

set_spinner
	incf	spinner;
	movlw	0x05;
	subwf	spinner,w; 
	btfss	STATUS, C;
		goto 	end_set
	clrf	spinner;
end_set
	return;

Hours
	; will be add one hour
	movlw	0xD0;
	movwf	slave;
	movlw	0x03;	hours
	movwf	re_address;
	call	read_a_byte;
	movfw	Data_in;
	movwf	hours;
	andlw	0xF0;
	movwf	hours_high;
;	swapf	hours_high;
	movfw	hours;
	andlw	0x0F;
	movwf	hours_low;
	incf	hours_low;	
	movfw	hours_high;
	iorwf	hours_low, w;
	movwf	hours;
	movlw	0x24;
	subwf	hours, w
	btfss	STATUS, C
		goto Hours_adv
Hours_clear
	clrf	hours_high;
	clrf	hours_low;
	goto	Hours_end;
Hours_adv		;low
	movlw	0xA;
	subwf	hours_low,w;
	btfss	STATUS, C;
		goto	Hours_end;
	swapf	hours_high;
	incf	hours_high;
	swapf	hours_high;
	movlw	0x00;
	movwf	hours_low;
Hours_end		;high
	movfw	hours_high;
	iorwf	hours_low, w;
	movwf	hours;
	swapf	hours_high;
	movwf	data_container;
	movlw	0x03;	minutes
	movwf	wr_address;
	movlw	0xD0;
	movwf	slave;
	call	write_a_byte;
	return;

Minutes
	; will be add one minute
	movlw	0xD0;
	movwf	slave;
	movlw	0x02;	minutes
	movwf	re_address;
	call	read_a_byte;
	movfw	Data_in;
	movwf	minutes;
	andlw	0xF0;
	movwf	minutes_high;
	swapf	minutes_high;
	movfw	minutes;
	andlw	0x0F;
	movwf	minutes_low;
	incf	minutes_low;
	movlw	0xA;
	subwf	minutes_low, w
	btfss	STATUS, C
		goto Minutes_end
	movlw	0x00;
	movwf	minutes_low;	
	incf	minutes_high;
	movlw	0x06;
	subwf	minutes_high, w;
	btfss	STATUS, C
		goto Minutes_end
	movlw	0x00;
	movwf	minutes_high;
	movwf	minutes_low;
Minutes_end
	swapf	minutes_high;
	movfw	minutes_low;
	iorwf	minutes_high, w;	
	movwf	minutes;
	swapf	minutes_high;
	movwf	data_container;
	movlw	0x02;	minutes
	movwf	wr_address;
	movlw	0xD0;
	movwf	slave;
	call	write_a_byte;
	return;

Dimmer
	;adds 0x20 to PWM
	movfw	PWMOn;
	addlw 0x10;
	movwf	PWMOn;
	movlw	0x9F;
	subwf	PWMOn, w;
	btfss	STATUS, C	
		goto Dimmer_end;
	movlw	0x4F;
	movwf	PWMOn;
Dimmer_end
	return;

Int				;  Interrupt Handler	
	movwf  	_w			;  Save Context Registers
  	movf   	STATUS, w		;   - Assume TMR0 is the only enabled
	bcf		STATUS, RP0
	bcf		STATUS, RP1 
	movwf	_status;
	movf	PCLATH, w
	movwf	_pclath
	clrf	PCLATH
	btfsc	INTCON, TMR0IF
		goto 	TMR0_INT
	goto	INT_end;

TMR0_INT ;TMR0 Interrupt: PWM-ing in the interrupter
	btfsc PWM,0;
		goto PWM_ON;
	bsf PWM,0;
	bcf	PWM,1;
	btfss	A_or_B, 0;
		goto	B_set;
A_set
	bsf	PORTB, 3;
	bcf	PORTB, 0;
		goto	skipped;
B_set
	bcf	PORTB, 3;
	bsf	PORTB, 0;
skipped	
	movlw	6 + 6	; to be re-calculated...
	subwf PWMOn, w;
	sublw	0	;get value in timer
	movwf TMR0;
		goto PWM_Done
PWM_ON
	incf	A_or_B;			; might not need, see p283
	; now turn off the HV
	bcf	PWM,0;
	bcf	PORTB, 3;
	bcf	PORTB, 0;
	bsf	PWM,1; 	; flag to tell the register to update the time
	; set the A,B pins to toggle between tube pairs	
	movf PWMOn, w;
	sublw 6 + 6;
	sublw	0	;get value in timer
	movwf TMR0;
		goto 	PWM_Done
PWM_Done
	bcf		INTCON, TMR0IF		;  Reset the Interrupt Flag
INT_end
	movf	_pclath, w
	movwf	PCLATH
  	movf   	_status, w		;  Restore the Context Registers
  	movwf  	STATUS
  	swapf  	_w, f
  	swapf  	_w, w
	retfie	;			
		
bcd2dec			;eeprom binary to decimal hack
	banksel	EEADR;
	movwf	EEADR;
	banksel EECON1;
	bcf EECON1, EEPGD 	; EE Point
	bsf EECON1, RD 	; EE Read
	banksel EEDATA;
	movf	EEDATA, w;
	banksel	ByteA;
	return;

download_time
	movlw	0xD0;
	movwf	slave;
	movlw	0x02;	minutes
	movwf	re_address;
	call	read_a_byte;
	movfw	Data_in;
	movwf	correct_minutes;
	movlw	0x03;	hours
	movwf	re_address;
	call	read_a_byte;
	movfw	Data_in;
	movwf	correct_hours;		
	call	make_12_hr_time;	;translate to 12-hr time, then...
	;check if spinner state;
Spinner_zero
	movlw	0x04;
	subwf	spinner,w;
	btfsc	STATUS, C;
		goto	spin_12_hour;
	movlw	0x03;
	subwf	spinner,w;
	btfsc	STATUS, C;
		goto	spin_1_hour;
	movlw	0x02;
	subwf	spinner,w;
	btfsc	STATUS, C;
		goto	spin_10_minute;
	movlw	0x01;
	subwf	spinner,w;
	btfsc	STATUS, C;
		goto	spin_1_minute;
	movlw	0x00;
	subwf	spinner,w;
	btfsc	STATUS, C;
		goto	HM_hi_low;
	goto	HM_hi_low;
spin_1_minute
	movfw	correct_minutes;
	xorwf	minutes_old,w;	;minutes changed?
	btfss	STATUS, Z;		;skip if didn't change
		bsf		PWM,5;	;spin_flag		
	goto	spin_spin_sugar
spin_10_minute
	movfw	correct_minutes;
	xorwf	minutes_old,w;
	iorlw	0x0F;
	xorlw	0x0F;	
	btfss	STATUS, Z;
		bsf		PWM,5;
	goto	spin_spin_sugar
spin_1_hour
	movfw	correct_hours;
	xorwf	hours_old,w;
	btfss	STATUS, Z;
		bsf		PWM, 5;
	goto spin_spin_sugar
spin_12_hour
	movfw	correct_hours;
	xorwf	hours_old,w;
	iorlw	0x0F;
	xorlw	0x0F;
	btfss	STATUS, Z;
		bsf		PWM, 5;
spin_spin_sugar
	btfss	PWM, 5;		;if flag not set, skip
		goto	HM_hi_low;
	incf	spin_timer;
	movlw	0x0A;
	xorwf	spin_timer,w;
	btfss	STATUS, Z;
		goto	download_time_end;
	clrf	spin_timer;
	incf	spin_timer2;
	movlw	0x29;
	subwf	spin_timer2,w; 
	btfsc	STATUS, C;
		goto	HM_hi_low;
	movlw	0x1F;
	subwf	spin_timer2,w;
	btfsc	STATUS, C;
		goto	min_low;
	movlw	0x15;
	subwf	spin_timer2,w;
	btfsc	STATUS, C;
		goto	min_high;
	movlw	0x0B;
	subwf	spin_timer2,w;
	btfsc	STATUS, C;
		goto	hour_low;
	goto	hour_high;
hour_high	
	incf	hours_high	
	movlw	0x0A;
	subwf	hours_high, w;
	btfss	STATUS, C;
		goto	hour_low
	movlw	0x00;
	movwf	hours_high;
hour_low
	incf	hours_low;
	movlw	0x0A;	
	subwf	hours_low, w;
	btfss	STATUS, C;
		goto	min_high;
	movlw	0x00;
	movwf	hours_low;
min_high
	incf	minutes_high;
	movlw	0x0A;
	subwf	minutes_high, w;
	btfss	STATUS, C;
		goto 	min_low;
	movlw	0x00;
	movwf	minutes_high;
min_low
	incf	minutes_low;		
	movlw	0x0A;
	subwf	minutes_low, w;
	btfss	STATUS, C;
		goto	assemble_time;
	movlw	0x00;
	movwf	minutes_low;
assemble_time
	movfw	minutes_high;
	swapf	minutes_high,w;
	iorwf	minutes_low,w;
	movwf	minutes;
	movfw	hours_high;	
	swapf	hours_high,w;
	iorwf	hours_low,w;
	movwf	hours;
	goto	download_time_end;

HM_hi_low
	bcf		PWM, 5;
	clrf	spin_timer2;
	clrf	spin_timer;
	movfw	correct_minutes;
	andlw	0xF0;
	movwf	minutes_high;
	swapf	minutes_high;
	movfw	correct_minutes;
	andlw	0x0F;
	movwf	minutes_low;	
	movfw	correct_hours
	andlw	0xF0;
	movwf	hours_high;
	swapf 	hours_high;
	movfw	correct_hours;
	andlw	0x0F;
	movwf	hours_low;	
	movfw	correct_minutes;
	movwf	minutes_old;
	movfw	correct_hours;
	movwf	hours_old;
	goto	assemble_time;
download_time_end;			
	return;
	
make_12_hr_time
		movlw	0x23
	subwf	correct_hours, w;
	btfss	STATUS, C;
		goto 	check_10
	movlw	0x11
	movwf	correct_hours;
	goto	make_end
check_10
	movlw	0x22
	subwf	correct_hours, w;
	btfss	STATUS, C;
		goto 	check_9
	movlw	0x10;
	movwf	correct_hours;	
	goto	make_end;
check_9	
	movlw	0x21
	subwf	correct_hours,w;
	btfss	STATUS, C;
		goto	check_8
	movlw	0x09;
	movwf	correct_hours;
	goto	make_end;
check_8
	movlw	0x20;
	subwf	correct_hours, w;
	btfss	STATUS, C;
		goto	check_12;
	movlw	0x08;
	movwf	correct_hours;
	goto	make_end;
check_12	
	movfw	correct_hours;
	xorlw	0x00;
	btfss	STATUS, Z
		goto	over_13;
	movlw	0x12;
	movwf	correct_hours;
	goto	make_end
over_13
	movlw	0x013;
	subwf	correct_hours,w;
	btfss	STATUS, C;
		goto	make_end;
	movfw	correct_hours;
	andlw	0x0F;
	movwf	correct_hours;
	decf	correct_hours;
	decf	correct_hours;
make_end
	return;

load_display

AorB											;;LOAD DISPLAY		
	btfsc	A_or_B,0;							;;LOAD DISPLAY
		goto group_A							;;LOAD DISPLAY
group_B		;2,4								;;LOAD DISPLAY
	swapf	hours,w;
	andlw	0x0F;
	movwf	msd_temp;
	swapf 	minutes, w;
	andlw	0x0F;
	movwf	lsd_temp;
;		goto	lookup;
	btfsc	PWM, 5;		;Spinner Flag
		goto	lookup;
	movfw	msd_temp;
	xorlw	0x00;
	btfss	STATUS, Z;	;high bit zero?
		goto	lookup;
	movlw	0x14		;yep.  0x14 is a location to "zero" in eeprom no matter what 
	movwf	msd_temp;
		goto	lookup
group_A		;1,3
	movfw	hours;
	andlw	0x0F;
	movwf	msd_temp;
	movfw	minutes;
	andlw	0x0F;
	movwf	lsd_temp;
		goto	lookup;
lookup
	;check if overflow first
;	movlw	0x0A;
;	subwf	lsd_temp,w;
;	btfss	STATUS, C;	if overflow, skip
;		goto check_msd
;	movlw	0x09;			;error code "9"
;	movwf	lsd_temp;
;check_msd
;	movlw	0x0A;
;	subwf	msd_temp,w;
;	btfss	STATUS, C;	if overflow, skip
;		goto look_it_up
;	movlw	0x09;			;error code "9"
;	movwf	msd_temp;
look_it_up	
	movfw	lsd_temp;
		call 	bcd2dec;
	movwf	ByteD;
	movfw	lsd_temp;
	addlw	10;
		call 	bcd2dec;
	movwf	ByteC;
	movfw	msd_temp;
	addlw	20;
		call 	bcd2dec;
	movwf	ByteB;
	movfw	msd_temp;
	addlw	30;
		call 	bcd2dec;
	movwf	ByteA;
		return;

Delay						;delays by amount in w
	movf 	temp_w, w			; subroutine, not goto!	
Delay_loop	
	decfsz	temp_w,f
	goto	Delay_loop
	return


org 0x0300

send_start		;i2c start condition, no error	
	movlw	0x00;	;setup the all-output state
	bsf		STATUS, RP0;
	movwf	TRISB;
	bcf		STATUS, RP0;
	bsf		PORTB, SDA;
	bsf		PORTB, SCL;
	nop;
	nop;
	nop;
	bcf		PORTB, SDA;		;sda hi to low while clock high
	nop;
	nop;
	nop;
	bcf		PORTB, SCL;		;start clock train!
;	banksel	Data_in;
	return;

send_stop		;12c stop condigion, no error
	bcf		PORTB, SDA;
	nop;
	nop;
	nop;
	bsf		PORTB, SCL;		;Clock High
	nop;
	nop;
	nop;
	bsf		PORTB, SDA;		;Sda goes low to high while clock hi
	nop;					;necessary?
	return;

send_a_bit		;i2c send a bit (only one bit, though)
				;have to shift left or right by hand before single bit xmit
	movlw	0x00;	setup all output state
	bsf		STATUS, RP0
	movwf	TRISB;
	bcf		STATUS, RP0
	btfss	Data_out, 7;	
		goto send_zero;
	bsf		PORTB, SDA;		;send "1"
	nop;
	goto 	clk1;
send_zero
	bcf		PORTB, SDA;		;send "0"
	nop;
	nop;
	nop;
clk1
	bsf		PORTB, SCL;		;toggle clock
	nop;
	nop;
	nop;
	nop;
	bcf		PORTB, SCL;		;
	return;

send_byte		;i2c send byte command (shifts so send_a_bit works)
				;assumes Data_out already loaded
	movlw	0x08			;8 bits
	movwf	i2c_count;		
sender		;loop part
		call 	send_a_bit;
	rlf		Data_out;
	decfsz	i2c_count;
		goto	sender
	; one more clock for the ack
	;
	call	get_a_bit;
	return;

get_a_bit		;i2c receive a bit
				;have to shift left or right after single bit reception
	bsf		STATUS, RP0
	bsf		TRISB, SDA;		;Force SDA input
	bsf		PORTB, SDA;		;input
	bcf		STATUS, RP0
	bcf		Data_in, 0		;set to zero as an assumption
	nop;
	bsf		PORTB, SCL;		;clock hi	
	nop;
	nop;
	btfsc	PORTB, SDA;
	bsf		Data_in, 0;		;oh- I guess it was a "1"
	nop;
	bcf		PORTB, SCL;		;clear clock
	return;

receive_byte	;i2c recieve byte command (shifts so get_a_bit works)
	movlw	0x08;
	movwf	i2c_count;
receiver	;loop part
	rlf		Data_in;		
		call get_a_bit
	decfsz	i2c_count;
		goto	receiver;
	bsf		PORTB, SDA;
	bsf		Data_out,7;
	call	send_a_bit;		;nack
	
	return;

write_a_byte	;i2c routine to write a byte to the addres "wr_address"
				;assuming the data is stored in "data_container," and the slave address 
				;is in "slave"
	movfw	slave;
	movwf	Data_out;
	call	send_start;
	nop;
	nop;
	call	send_byte;	;send slave address first (with r/w = "1" bit set)
	movfw	wr_address;
	movwf	Data_out;
	nop;
	nop;
	call	send_byte;
	movfw	data_container;
	movwf	Data_out;
	nop;
	nop;
	call	send_byte;
	nop;
	nop;
	call	send_stop;
	return;

read_a_byte		;i2c routine to read a byte from address "re_address"
				;assuming the data goes into "Data_in," and the slave
				;address lives in "slave."
	movfw	slave;
	movwf	Data_out;
	call	send_start;
	nop;
	nop;
	call	send_byte;	;send slave address first (with r/w = "0" bit set)
	movfw	re_address;
	movwf	Data_out;
	nop;
	nop;
	call	send_byte;	send read_address;
	nop;
	nop;
	call	send_start;
	movfw	slave; 
	iorlw	0x01;	;set r/w high
	movwf	Data_out;
	nop;
	nop;
	call	send_byte; 	send slave again;
	nop;
	nop;
	call	receive_byte;
	nop;
	nop;
	call 	send_stop;
	return
		
org 0x0400

display_update
	bsf	PORTB, OE;		;disable device

	movf	ByteD, w
	movwf	display_out;
	call register_director;
	movf	ByteC, w
	movwf	display_out;
	call register_director;
	movf	ByteB, w
	movwf	display_out;
	call register_director;
	movf	ByteA, w
	movwf	display_out;
	call register_director;
	;done updating the values in HV5122
	bcf	PORTB, OE;  	;enable device
	return;	
	
register_director
	movlw	0x08;
	movwf	serial_count;
ones_zeros
	btfsc	display_out, 0;	lowest bit set
		goto one_out;
zero_out
	bsf		PORTB,CLK;  ;clock
	bsf		PORTB,DAT; (just the data bit);data	
	movlw	0x0F;
	movwf	temp_w;
	call	Delay;
	rrf 	display_out,f;
	goto 	serial_loop
one_out
	bsf		PORTB,CLK;
	bcf		PORTB,DAT;
	movlw	0x0F;
	movwf	temp_w;
	call	Delay;
	rrf 	display_out,f;
serial_loop	
	bcf		PORTB,CLK;	
	movlw	0x0F;
	movwf	temp_w;
	call	Delay;
	decfsz	serial_count;
		goto ones_zeros;	
	return;
	
org	0x02100		;EEProm data with pattern of digits in HV5122 
	de	0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
  	de	0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   	de	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20
   	de	0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00 
	de	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	de	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00;
	;;	0	  1		2	  3		4	  5		6	  7		8	  9
end
