;---- pn15 generator
;---- 疑似ランダム系列ジェネレータ・ファームウェア
;---- by K.I	since 040513


;	LIST	P=PIC12F629
;	INCLUDE	P12F629.INC
	LIST	P=PIC12F675
	INCLUDE	P12F675.INC

	__CONFIG _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT

; CPD		: data memory Code Protect [ON,OFF]
; CP		: flash program memory Code Protect [ALL,HALF,UPPER_256,OFF]
; BODEN		: BrownOut reset ENable [ON,OFF]
; MCLRE		: MCLR Enable [ON,OFF]
; PWRTE		: PoWeR up Timer Enable (72ms) [ON,OFF]
; WDT		: Watch Dog Timer [ON,OFF]
; LP OSC		; Low Power OSC
; XT OSC		; XT OSC (normal speed)
; HS OSC		: High Speed mode OSC
; EC OSC		: RC mode OSC
; INTRC_OSC	; Intenal RC OSC [CLKOUT,NOCLKOUT]
; EXTRC_OSC	; External RC OSC [CLKOUT,NOCLKOUT]

	__IDLOCS H'0100'	;V1.00

;--------------------------------
BOD	EQU	0		;PCON-Brown Outreset Detect
;--------------------------------
TXD	EQU	0		;GP0, O, 送信データ
IN0	EQU	1		;GP1, I, bit0
IN1	EQU	2		;GP2, I, bit1
TXEN	EQU	3		;GP3, I, /送信イネーブル
IN2	EQU	4		;GP4, I, bit2
IN3	EQU	5		;GP5, I, bit3
;--------------------------------
TXFLAG	EQU	0		;Tx flag
;--------------------------------

GPIODIR	EQU	B'00111110'	;GPIO入出力設定
GPIOINI	EQU	B'00001000'	;GPIO InitValue
OPT_INI	EQU	B'00000000'	;OPTION Init
WPU_INI	EQU	B'00000000'	;WPU Init
CMP_INI	EQU	B'00000111'	;CMP Init
AD0_INI	EQU	B'00000000'	;ADCON0 Init
ANS_INI	EQU	B'00000000'	;ANSEL Init

PRELOAD	EQU	-208/4		;TMR0 preload (208us)


TXDATA	EQU	B'1111111111111111'
STAGE	EQU	B'0111111111111111'
TAP	EQU	B'0110000000000000'

;--------------------------------

	CBLOCK	H'20'

	W_TEMP			;Wレジスタ退避用
	STATUS_TEMP		;STATUSレジスタ退避用

	TXDATAL			;送信データ L
	TXDATAH			;送信データ H
	TAPL			;タップ L
	TAPH			;タップ H
	MASKL			;タップでマスクしたTxData L
	MASKH			;タップでマスクしたTxData H

	TXMODE			;Tx mode
	LINE			;汎用baffer

	TABLEINDEX		;TABLE index
	WAIT_CN			;WAIT counter
	WAIT_CN2			;WAIT counter2

	GPIOX			;GPIO初期設定値

	ENDC

;--------------------------------------------------------
	ORG	0		;リセット・ベクタ
;--------------------------------------------------------
	goto	SETUPPORTS	;ポートの初期設定

;--------------------------------------------------------
	ORG	4		; interrupt vector location
;--------------------------------------------------------
	movwf   W_TEMP		; Wレジスタの退避
	movf	STATUS,W		; STATUSレジスタも
	movwf	STATUS_TEMP	; 退避する

	BTFSC	INTCON,T0IF	; T0割り込みならば
	CALL	T0WAKEUP		; T0WAKEUP処理へ

	BTFSC	INTCON,GPIF	; GP割り込みならば
	CALL	GPWAKEUP		; GPWAKEUP処理へ

	movf    STATUS_TEMP,w	; 退避していたSTATUSレジスタの内容を
	movwf	STATUS		; 回復させる
	swapf   W_TEMP,f
	swapf   W_TEMP,w		; Wレジスタも回復させて
	retfie			; インタラプト処理終了→GIE再設定される

;--------------------------------------------------------
	DT	"pn15 generator 040518 by K.I"	;<-- **** Version ****
;--------------------------------------------------------
; Timer0割込み処理→送信フラグを立てるだけ
;--------------------------------------------------------
T0WAKEUP
	BCF	INTCON,T0IF	;T0割込みフラグをクリアしておく

	BSF	TXMODE,TXFLAG

	movlw	PRELOAD
	addwf	TMR0,f

	return

;--------------------------------------------------------
; GP変化割込み→なにもしない(SLEEPから抜けるだけ)
;--------------------------------------------------------
GPWAKEUP
	BCF	INTCON,GPIF	;GP割込みフラグをクリアしておく
	return

;--------------------------------------------------------
; 入出力ポートの初期設定を行う
;--------------------------------------------------------
SETUPPORTS

	call    0x3FF		; calibration値は3FF番地にRETLWで記録済みとする
	bsf     STATUS,RP0	; set file register bank to 1 
	movwf   OSCCAL		; update register with factory cal value 

	MOVLW	OPT_INI		;WAKE-UP,PULL-UP,1:16 WDT PRESCALER
	MOVWF	OPTION_REG

	MOVLW	GPIODIR		;Set I/O direction
	MOVWF	TRISIO
	MOVLW	WPU_INI
	MOVWF	WPU
;	BSF	PCON,BOD
	MOVLW	ANS_INI		;Init Analog Input Select
	MOVWF	ANSEL		;(12F675 only)

	BCF	STATUS,RP0	;select bank0

	MOVF	GPIO,W
	MOVWF	GPIOX

	MOVLW	GPIOINI		;Init I/O data
	MOVWF	GPIO
	MOVLW	CMP_INI		;Init CMP data (CMP off)
	MOVWF	CMCON
	MOVLW	AD0_INI		;Init A/D control
	MOVWF	ADCON0		;(12F675 only)

	movlw	PRELOAD
	movwf	TMR0
	movlw	Low(TAP)
	movwf	TAPL
	movlw	TAP>>8
	movwf	TAPH
	CLRF	TXMODE

; ---- 割込み許可 ----------------

	BSF	STATUS,RP0	;select bank1
	BSF	IOC,3		;GP3の変化によるインタラプト設定
	BCF	STATUS,RP0	;select bank0
	BSF	INTCON,GPIE	;GPレジスタ変化によるインタラプト許可
	BSF	INTCON,T0IE	;Timer0 overflowによるインタラプト許可
	BSF	INTCON,GIE	;グローバルインタラプト許可

; ---- メインループ ----------------
LOOP
	BTFSS	TXMODE,TXFLAG	;Tx flag が'H'ならば、送信
	GOTO	TXSKIP

	CALL	SEND_PN
	BCF	TXMODE,TXFLAG	;Tx flag をクリア
TXSKIP
	BTFSS	GPIO,TXEN	;TXENが'L'ならばLOOP
	GOTO	LOOP

; ---- スリープ ----------------

	BCF	TXMODE,TXFLAG	;Tx flag をクリア
	BCF	GPIO,TXD		;TxD をクリア
	BSF	INTCON,GPIE	;GPレジスタ変化によるインタラプト許可

	SLEEP			;スリープ状態へ
	BCF	INTCON,GPIE	;GP割込み禁止
	GOTO	LOOP		;メインループへ

;--------------------------------------------------------
; PN符号計算→TXDATAとTAPから、次のPN符号を求める
;  計算したPN符号の0ビット目の値を送信する
;--------------------------------------------------------
SEND_PN

;---- TAPで、TXDATAをマスクする ----------------

	MOVLW	Low(STAGE)
	ANDWF	TXDATAL,F
	MOVF	TXDATAL,W
	ANDWF	TAPL,W
	MOVWF	MASKL

	MOVLW	STAGE>>8
	ANDWF	TXDATAH,F
	MOVF	TXDATAH,W
	ANDWF	TAPH,W
	MOVWF	MASKH

;---- マスクされたTXDATAの全てのビットのEx-ORをとる --------

	CLRC
	CLRF	LINE

	RRF	MASKH	;---- 上位8ビット
	SKPNC
	INCF	LINE
	RRF	MASKH
	SKPNC
	INCF	LINE
	RRF	MASKH
	SKPNC
	INCF	LINE
	RRF	MASKH
	SKPNC
	INCF	LINE
	RRF	MASKH
	SKPNC
	INCF	LINE
	RRF	MASKH
	SKPNC
	INCF	LINE
	RRF	MASKH
	SKPNC
	INCF	LINE
	RRF	MASKH
	SKPNC
	INCF	LINE

	RRF	MASKL	;---- 下位8ビット
	SKPNC
	INCF	LINE
	RRF	MASKL
	SKPNC
	INCF	LINE
	RRF	MASKL
	SKPNC
	INCF	LINE
	RRF	MASKL
	SKPNC
	INCF	LINE
	RRF	MASKL
	SKPNC
	INCF	LINE
	RRF	MASKL
	SKPNC
	INCF	LINE
	RRF	MASKL
	SKPNC
	INCF	LINE
	RRF	MASKL
	SKPNC
	INCF	LINE	;---- Ex-ORの結果をLINEに入れる
	
;---- TXDATAを左にシフトして、Bit0に Ex-ORの結果をセットする

	RLF	TXDATAL
	RLF	TXDATAH
	BTFSC	LINE,0
	GOTO	TX1
TX0
	BCF	TXDATAL,0
	RETLW	0
TX1
	BSF	TXDATAL,0	;---- NRZIなので
	CALL	XOR_TX		;---- DATA1の場合のみ反転
	RETLW	1

;--------------------------------------------------------
; NRZIの1ビット送信ルーチン
;--------------------------------------------------------
XOR_TX
				;NRZIで送信するために
	MOVLW	1		;GP0を反転させる
	XORWF	GPIO,F

	RETLW	0

;--------------------------------------------------------
	ORG	0x3FF
;--------------------------------------------------------
	RETLW	0xA0		;キャリブレーションデータ


	END