;
;=========================
;	PIC-7SEG01
;=========================
;
;	Copyright 2007 アルゴ算法堂
;
;	7seg_ledを表示する処理
;		74ls47 と　hc138を使用
;	Clock4MHz Internal 版 
;
;	更新履歴
;	=======
;	07/10/20	Ver.1.00	最初の版(id=0x0300)
;
;	内蔵オシレータではMCLRをGPIOとして使用できない。
;
	list	 p=16f648a
	#include p16f648a.inc
	
; CONFIGRATIONS
	__config	_INTOSC_OSC_NOCLKOUT & _PWRTE_ON & _WDT_OFF & _BOREN_ON & _LVP_OFF & _MCLRE_ON & _DATA_CP_OFF & _CP_OFF


; Set User ID Memory
	__idlocs	0x0300
;
;
; constant
;#define	_DEBUG_
;#define	USECC		; 汎用のＣＣ処理を選択
;
option_val	equ	b'00010001'
	;b7		RPBU	0: pullup
	;b6		INTEDE	0:nouse	rb0/int
	;b5		T0CS	timer0 clock source 0:FOSC/4
	;b4		T0SE	nouse	timer0 clock edge
	;b3		PSA		0: prescaler to timer0
	;b2-b0	PSn		divider
	;				0:	1:2
	;				1:	1:4
	;				2:	1:8
	;				3:	1:16
	;				4:	1:32
	;				5:	1:64
	;				6:	1:128
	;				7:	1:255
;
DIGIT_SZ	equ	8	;
; IO BIT INDEX
PORTA_ADR_0	equ	0	;OUT for demultiplexer 
PORTA_ADR_1	equ	1	;OUT
PORTA_ADR_2	equ	2	;OUT
;
PORTB_SW	equ	0	;IN  for demo mode
PORTB_DATA_0	equ	4	;OUT fot segment driver
PORTB_DATA_1	equ	5	;OUT
PORTB_DATA_2	equ	6	;OUT
PORTB_DATA_3	equ	7	;OUT
;
PORTA_ADR_MASK	equ	((1<<PORTA_ADR_0)|(1<<PORTA_ADR_1)|(1<<PORTA_ADR_2))
PORTB_DATA_MASK	equ	((1<<PORTB_DATA_0)|(1<<PORTB_DATA_1)|(1<<PORTB_DATA_2)|(1<<PORTB_DATA_3))
;
; COMMON REGISTERS (NON BANKED REGISTERS)
;
	cblock	0x70
	irq_wback	; wk backup
	irq_sback	; swap backup
	irq_fsrback
	irq_pclathback
	endc
;
; bank0
;	banked works
;
	cblock	0x20
;
	temp			; temporary work for general
	temp2
;
	timer0_count
;
	ctrl
	digit_count		; digit index
	vram:DIGIT_SZ		; display data: lownible is bcd data
;
;-- demonstration vram
;
	demo_top
	demo_adr
	demo_count
;
;-- gpio bacup ----
;
	porta_back
	portb_back
; --
	endc
;
;	ctrl の　制御ビット
CTRL_INHIBIT	equ	0	; 表示禁止
CTRL_RPG	equ	1	; ゼロサプレス用作業域
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;	programs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	org	0x0
;
;***************
;	startup
;***************
startup:
	call	initialize
	goto	main
;
;
	org	0x4
;
;***************
;	intrupt
;***************
irq:
	; prologue
	movwf	irq_wback	;save wk
	swapf	STATUS,w	;save status
	movwf	irq_sback
;
	bcf	STATUS,RP0
	bcf	STATUS,RP1
	bcf	STATUS,IRP
	;
	; prologue 2
	movf	FSR,w
	movwf	irq_fsrback
	movf	PCLATH,w
	movwf	irq_pclathback
	;
	;----------------
	btfsc	INTCON,T0IF
	call	tmr0irq
	;----------------
	; epilogue 2
	;
	movf	irq_pclathback,w
	movwf	PCLATH
	movf	irq_fsrback,w
	movwf	FSR
	;
	; epilogue
	swapf	irq_sback,w	;load status
	movwf	STATUS
	swapf	irq_wback,f	;load wk
	swapf	irq_wback,w
	retfie


;;;;;;;;;;;;
;***********************************
;	initialize for standard hardware
;***********************************
initialize:
	clrf	STATUS
;
; initialize portA & portB
;
	clrw
	movwf	PORTA
	movwf	porta_back
	movlw	0xf0
	movwf	PORTB
	movwf	portb_back
;
; data directions
;
	bsf	STATUS,RP0
	movlw	b'00100000'
			; b0: 0 GPIO Output adr_0
			; b1: 0 GPIO Output adr_1
			; b2: 0 GPIO Output adr_2
			; b3: 0 GPIO Output 
			; b4: 0 GPIO Output 
			; b5: 1 MCLR
			; b6: 0 GPIO Output 
			; b7: 0 GPIO Output 
	movwf	TRISA
	movlw	b'00000001'
			; b0: 0 GPIO Output
			; b1: 0 GPIO Output
			; b2: 0 GPIO Output
			; b3: 0 GPIO Output
			; b4: 0 GPIO Output data_0
			; b5: 0 GPIO Output data_1
			; b6: 0 GPIO Output data_2
			; b7: 0 GPIO Output data_3
	movwf	TRISB
	bcf	STATUS,RP0
;
; option_reg
;
	bsf	STATUS,RP0
	movlw	option_val
	movwf	OPTION_REG
	bcf	STATUS,RP0
;
; ccp nouse (default)
;
; comparator(not used)
;
	movlw	0x07		; com off
	movwf	CMCON
;
; vref nouse (default)
; timer1(not used) default
; timer2(not used) default
;
; usart(not used)
;
; timer0(use)
;
	clrf	TMR0
; interupt
	clrf	INTCON
	bsf	INTCON,T0IE
	return
;
;*********************
;	main routine
;*********************

main:
;
	clrf	timer0_count
	clrf	ctrl
	clrf	digit_count
	clrf	demo_top		; demo first flag clear
	call	vramClr
;
	clrf	TMR0
;
	bsf	INTCON,GIE		; global irq
;
	btfss	PORTB,PORTB_SW
	goto	main_loop2
;
main_loop1:
	call	vramSetDemo
	call	demoWait
	goto	main_loop1
;
main_loop2:
	call	CountDemo
	call	demoWait
	goto	main_loop2
;
;-------/ demoWait /---------
;
;	デモの待ち時間処理
;
demoWait:
	movf	timer0_count,w
	btfsc	STATUS,Z
	goto	demoWait		; 0以外を待つ
demoWait_2:
	movf	timer0_count,w
	btfss	STATUS,Z
	goto	demoWait_2		; 0を待つ
	return
;
;-------------------
; timer0 irq routine
;-------------------
tmr0irq:
	bcf	INTCON,T0IF
	incf	timer0_count,f
;
	btfss	ctrl,CTRL_INHIBIT
	call	vramDisp2
	return

;
;-------------------
; vramFunction
;-------------------
;
;
;----------/ vramDisp1 /----------
;
;	単純表示処理
;
;	表示手順は次の通り
;	bSf 	ctrl,CTRL_INHIBIT
;	clrf	digit_count
;	データをvramにセット
;	bcf	ctrl,CTRL_INHIBIT
;
vramDisp1:
;
	decf	digit_count,f
	movlw	7
	andwf	digit_count,f
	; 表示を消す
	movlw	PORTB_DATA_MASK
	iorwf	portb_back,w
	movwf	PORTB
	; 桁指定
	movlw	~PORTA_ADR_MASK
	andwf	porta_back,w
	iorwf	digit_count,w
	movwf	porta_back
	movwf	PORTA
	; 内容出力
	movlw	~PORTB_DATA_MASK
	andwf	portb_back,f
	movf	digit_count,w
	sublw	7
	addlw	vram
	movwf	FSR
	swapf	INDF,w
	iorwf	portb_back,w
	movwf	portb_back
	movwf	PORTB
;
	return
;
;
;----------/ vramDisp2 /----------
;
;	ゼロサプレスデータ表示処理
;
;	表示手順は次の通り
;	bSf 	ctrl,CTRL_INHIBIT
;	clrf	digit_count
;	データをvramにセット
;	bcf	ctrl,CTRL_INHIBIT
;
vramDisp2:
;
	decf	digit_count,f
	movlw	7
	andwf	digit_count,f
	; 桁によるリップルグランド処理
	movf	digit_count,w
	btfsc	STATUS,Z
	bcf	ctrl,CTRL_RPG	; 最下位桁はリップルグランドなし
	sublw	7
	btfsc	STATUS,Z
	bsf	ctrl,CTRL_RPG	; 最上位桁はリップルグランド強制セット
	; 表示を消す
	movlw	PORTB_DATA_MASK
	iorwf	portb_back,w
	movwf	PORTB
	; 桁指定
	movlw	~PORTA_ADR_MASK
	andwf	porta_back,w
	iorwf	digit_count,w
	movwf	porta_back
	movwf	PORTA
	; 内容出力
	movlw	~PORTB_DATA_MASK
	andwf	portb_back,f
	movf	digit_count,w
	sublw	7
	addlw	vram
	movwf	FSR
	swapf	INDF,w
	; リップルグランド処理
	btfss	ctrl,CTRL_RPG
	goto	vramDisp2_norpg	; no rpg flag 
	movf	INDF,f
	btfss	STATUS,Z
	bcf	ctrl,CTRL_RPG	; data valid -> no rpg
	btfsc	ctrl,CTRL_RPG
	movlw	PORTB_DATA_MASK	; blank data
;
vramDisp2_norpg:
	iorwf	portb_back,w
	movwf	portb_back
	movwf	PORTB
;
	return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	メイン側の処理
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;-------/ vramClr /----------
;
;	値を0にする
;
vramClr:
	bsf 	ctrl,CTRL_INHIBIT
	clrf	digit_count
;
	movlw	vram
	movwf	FSR
	movlw	8
	movwf	temp
vramClr_loop:
	clrf	INDF
	incf	FSR,f
	decfsz	temp,f
	goto	vramClr_loop
;
	bcf	ctrl,CTRL_INHIBIT
	return

;
;----------/ vramSetDbg1 /-------------
;
;	デバッグ用の表示1
;	現在は未使用
;
;	set debug value to registor
;
vramSetDbg1:
	bsf 	ctrl,CTRL_INHIBIT
	clrf	digit_count
;
	movlw	0x01
	movwf	vram+0
	movlw	0x02
	movwf	vram+1
	movlw	0x03
	movwf	vram+2
	movlw	0x04
	movwf	vram+3
	movlw	0x05
	movwf	vram+4
	movlw	0x06
	movwf	vram+5
	movlw	0x07
	movwf	vram+6
	movlw	0x08
	movwf	vram+7
;
	bcf	ctrl,CTRL_INHIBIT
	return

;-------/ vramSetDemo /---------
;
;	シフトしながらの表示処理
;
;	in	demotop: vram top adr
;
vramSetDemo:
;
	bsf 	ctrl,CTRL_INHIBIT
	clrf	digit_count
;
	movf	demo_top,w
	movwf	demo_adr
	movlw	DIGIT_SZ
	movwf	demo_count
	movlw	vram
	movwf	FSR
vramSetDemo_loop:
	movf	demo_adr,w
	call	ReadRom
	movwf	INDF
	incf	demo_adr,f
	incf	FSR,f
;
	decfsz	demo_count,f
	goto	vramSetDemo_loop
;
	bcf	ctrl,CTRL_INHIBIT
;
	incf	demo_top,f
	movlw	eeprom_bot-eeprom_top-8
	subwf	demo_top,w
	btfsc	STATUS,C
	clrf	demo_top
	return

;-------/ CountDemo /---------
;
;	カウントアップのデモ
;
CountDemo:
	bsf 	ctrl,CTRL_INHIBIT
	clrf	digit_count
	call	CountUp
	bcf	ctrl,CTRL_INHIBIT
	return
;
;------/ CountUp /---------
;
;	カウントアップ本体
;
CountUp:
	movlw	vram+DIGIT_SZ-1
	movwf	FSR
	movlw	DIGIT_SZ
	movwf	demo_count
CountUp_loop:
	incf	INDF,f
	movlw	0x0a
	subwf	INDF,w
	btfss	STATUS,C
	return
	clrf	INDF
	decf	FSR,f
	decfsz	demo_count,f
	goto	CountUp_loop
	return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; EEPROM ACCESS
;;
;-------/ ReadRom /--------
;
;	in:	w romadr
;	out	w value
ReadRom
	bsf	STATUS,RP0
	movwf	EEADR
	bsf	EECON1,RD
	movf	EEDATA,w
	bcf	STATUS,RP0
	return

;=========================
;	EEPROM SECTION
;=========================
;
;	256 bytes
;	action data
;
;
	org		0x2100
eeprom_top:
	de		0x00		; display test data
	de		0x00
	de		0x00
	de		0x00
	de		0x00
	de		0x00
	de		0x00
	de		0x00
	de		0x01
	de		0x02
	de		0x03
	de		0x04
	de		0x05
	de		0x06
	de		0x07
	de		0x08
	de		0x09
	de		0x00		; display test data
	de		0x00
	de		0x00
	de		0x00
	de		0x00
	de		0x00
	de		0x00
	de		0x00
eeprom_bot:
;
;
	end
