;=================================================================
;
; Homebrew CamBase Control Program
;  
; (C) Copyright 2006 All Reserved Yasuo Ogane
;
;=================================================================

	INCLUDE	"P16F876.INC"	

 	__config   _CP_OFF & _WDT_OFF & _PWRTE_OFF & _HS_OSC & _DEBUG_OFF & _BODEN_OFF & _LVP_OFF

;*********************************
;  Define Variables to Registers
;*********************************

BUFFER	EQU	20H ; received character
TEMP	EQU	21H ; temp data 

GR0		EQU	22H	; 
GR1		EQU	23H	; 
GR2		EQU	24H	; 

CMD		EQU	25H	; 
NUM		EQU	26H	; 
IDX0	EQU	27H	;
BREG	EQU	28H 	;

STNO	EQU	29H	;

POS_P	EQU	2AH	;  0 <= POS_P <= 127 
POS_T	EQU	2BH	;  0 <= POS_T <= 127 

FF		EQU 2CH ;

WREG	EQU 70H;
SREG	EQU 71H;
LREG	EQU 72H;

;****************************************
; Vector Table
;****************************************

; Power Reset
	ORG		0x000		
	GOTO	INIT
; Interrupts
	ORG		0x004
	GOTO	ISR

;****************************************
; Main Entry Point
;****************************************

	ORG	0x008
INIT           
;
; Port B
;  Output : 7  6  5  4  3  2  1  0
;  Input  :
;  Usage  : 
;    7 : LED
;    1 : Servo Pulse (Tilt)
;    0 : Servo Pulse (Pan)
; 
	BSF		STATUS,RP0	; Set Page 1
	movlw	0x00	
	movwf	TRISB	; Set Port B
;
; Port C
;  Output :    6  5    
;  Input  : 7        4  3  2  1  0
;  Usage  : 
;    7 : RX
;    6 : TX
;    2 : Station Number
;    1 : Station Number
;    0 : Station Number
;  
	MOVLW	09FH	
	MOVWF	TRISC	; Set Port C
;
; USART
;  Mode : Async
;  Transmit : Enable
;  Baud Rate Generator : High
;  Baud Rate : 38400BPS
;
	MOVLW	024H	
	MOVWF	TXSTA	; Set TX mode
;	MOVLW	00fH	; 19200BPS
	MOVLW	020H	; 38400BPS
	MOVWF	SPBRG	
 	BCF		STATUS,RP0	; Set Page 0
	MOVLW	090H	
	MOVWF	RCSTA	; Set RX mode
; 
; Timer 0 ( 8 + 8 bit )
;  Fosc = 20MHz
;  Fosc / 4 = 5MHz ( 0.2us )
;  ( Necceary Fosc Clock Count ) = 10 ms / 0.2us 
;                                = 50000
;  ( Timer Count ) = 50000 / Prescale
;                  = 50000 / 256 
;                  = 195 = 0xC3 
;  ( Timer0 Initial Count ) = 0xFF - 0xC3
;                           = 0x3C
;
	BSF		STATUS,RP0	; Set Page 1
	MOVLW	087H
	MOVWF	OPTION_REG
	BCF		STATUS,RP0	; Set Page 0
	MOVLW	03CH ; Initialize Timer 0
	MOVWF	TMR0
	CLRF	FF ; Reset Flip Flop
;
; Timer 1 ( 16 + 3 bit )
;  Fosc = 20MHz
;  Fosc / 4 = 5MHz ( 0.2us )
;  ( Necceary Fosc Clock Count ) = 1.5 ms / 0.2us 
;                                = 7500
;  ( Timer Count ) = 7500 / Prescale
;                  = 7500 / 8 
;                  = 937 = 0x03A9 
;  ( Timer1 Initial Count ) = 0
;  ( Timer High Reg ) = 0
;  ( Timer Low Reg )  = 0
;  ( CCP Register setting ) = 0x03A9
;  ( CCP High Reg ) = 0x03
;  ( CCP Low Reg )  = 0xA9
;
;   PW    TMR1               CCPRx
; ------- ----------------- ---------
;  0.9ms    553 (937 - 384)  0x0229
;  1.0ms    617 (937 - 320)  0x0269  (min) 
;  1.5ms    937              0x03A9  (nutral) 
;  2.0ms   1257 (937 + 320)  0x04E9  (max)
;  2.1ms   1321 (937 + 384)  0x0529
;           
;  0.2us x 8 = 1.6us / 1 count
;  Count p-p = 640 
;  Command p-p = 128
;  Rate ~ Count p-p / Command p-p = 5
;
#define	POS_MIN_H	0x02
#define	POS_MIN_L	0x69
#define POS_RATE	.5
#define POS_HOME	.63

; Timer 1 ( 10ms * 2 )
	CLRF	TMR1H ; Initialize Timer 1  
	CLRF	TMR1L ; 
	MOVLW	030H ; Prescale 1:8
	MOVWF	T1CON

; CCP1 for Pan
	; Set Pan Nutral Position
	MOVLW	POS_HOME 
	MOVWF	POS_P
	; Init CCP1 
	MOVLW	0AH ; Compare mode, Interrupt raised by CCP1
	MOVWF	CCP1CON
	MOVLW	0FFH ; Set CCP1 Compare Value ( Dummy )
	MOVWF	CCPR1H 
	MOVWF	CCPR1L 

; CCP2 for Tilt
	; Set Pan Nutral Position
	MOVLW	POS_HOME 
	MOVWF	POS_T
	; Init CCP2
	MOVLW	0AH ; Compare mode, Interrupt raised by CCP2
	MOVWF	CCP2CON
	MOVLW	0FFH ; Set CCP2 Compare Value ( Dummy )
	MOVWF	CCPR2H   
	MOVWF	CCPR2L  
;
; Enable Interrupts
;
	BSF		STATUS,RP0	; Set Page 1
	BCF		PIE1,TMR1IE ; Disable Timer1 Interrupt
	BSF		PIE1,CCP1IE ; Enable CCP1 Interrupt 
	BSF		PIE2,CCP2IE ; Enable CCP2 Interrupt 
	BSF		INTCON,T0IE ; Enable Timer 0 Interrupt 
	BSF		INTCON,PEIE
	BSF		INTCON,GIE
 	BCF		STATUS,RP0	; Set Page 0
;
; Get Station Number
;
	MOVF	PORTC,W
	XORLW	0FH
	ANDLW	07H
	MOVWF	STNO
;
; LED off
; Both Servo Output Low
;
	CLRF	BREG
	BSF		BREG,7
	MOVF	BREG,W
	MOVWF	PORTB
;
; Main Loop
;
MAINLP
	; Wait for USART receive flag
	BTFSS	PIR1,RCIF
	GOTO	MAINLP
	; check frame error
	BTFSC	RCSTA,FERR	
	GOTO	FRAME_ERR
	; check overrun error
	BTFSC	RCSTA,OERR	
	GOTO	OVER_ERR
	; get receved data
	MOVF	RCREG,W			
	MOVWF	BUFFER
	GOTO	CHK_CMD
;
; Process Frame Error
;
FRAME_ERR
	MOVF	RCREG,W		; dummy input & reset FERR
	BTFSS	RCSTA,OERR	; check more error
	GOTO	MAINLP
;
; Process Overrun Error
;
OVER_ERR
	BCF		RCSTA,CREN	; reset OERR
	BSF		RCSTA,CREN
	GOTO	MAINLP
;
; Command Characters
;
#define	CMD_TILT	'T'
#define	CMD_PAN		'P'
#define	CMD_LON		'E'
#define	CMD_LOFF	'D'
#define	CMD_STAT	'S'
#define	CMD_INQ		'Q'
#define	CMD_HOME	'H'
;
; check if command character
;
CHK_CMD
	MOVF	BUFFER,W
	SUBLW	CMD_TILT
	BTFSC	STATUS,Z
	GOTO	COMMAND
	MOVF	BUFFER,W
	SUBLW	CMD_PAN
	BTFSC	STATUS,Z
	GOTO	COMMAND
	MOVF	BUFFER,W
	SUBLW	CMD_HOME
	BTFSC	STATUS,Z
	GOTO	COMMAND
	MOVF	BUFFER,W
	SUBLW	CMD_HOME
	BTFSC	STATUS,Z
	GOTO	COMMAND
	MOVF	BUFFER,W
	SUBLW	CMD_LON
	BTFSC	STATUS,Z
	GOTO	COMMAND
	MOVF	BUFFER,W
	SUBLW	CMD_LOFF
	BTFSC	STATUS,Z
	GOTO	COMMAND
	MOVF	BUFFER,W
	SUBLW	CMD_STAT
	BTFSC	STATUS,Z
	GOTO	COMMAND
	MOVF	BUFFER,W
	SUBLW	CMD_INQ
	BTFSC	STATUS,Z
	GOTO	COMMAND
;
; check if P or T commnd's operand 
;
	MOVF	BUFFER,W
	SUBLW	'0'
	BTFSC	STATUS,Z
	GOTO	NUMBER
	MOVF	BUFFER,W
	SUBLW	'1'
	BTFSC	STATUS,Z
	GOTO	NUMBER
	MOVF	BUFFER,W
	SUBLW	'2'
	BTFSC	STATUS,Z
	GOTO	NUMBER
	MOVF	BUFFER,W
	SUBLW	'3'
	BTFSC	STATUS,Z
	GOTO	NUMBER
	MOVF	BUFFER,W
	SUBLW	'4'
	BTFSC	STATUS,Z
	GOTO	NUMBER
	MOVF	BUFFER,W
	SUBLW	'5'
	BTFSC	STATUS,Z
	GOTO	NUMBER
	MOVF	BUFFER,W
	SUBLW	'6'
	BTFSC	STATUS,Z
	GOTO	NUMBER
	MOVF	BUFFER,W
	SUBLW	'7'
	BTFSC	STATUS,Z
	GOTO	NUMBER
	MOVF	BUFFER,W
	SUBLW	'8'
	BTFSC	STATUS,Z
	GOTO	NUMBER
	MOVF	BUFFER,W
	SUBLW	'9'
	BTFSC	STATUS,Z
	GOTO	NUMBER
;
; check if end of line
;
	MOVF	BUFFER,W
	SUBLW	0DH
	BTFSC	STATUS,Z
	GOTO	END_OF_LINE
;
; Process Invalid character
;
INV_CHAR
	MOVLW	'?'
	CALL	TX
	CALL	CRLF
	GOTO	MAINLP
;
; Keep Command Character in work
;
COMMAND	
	MOVF	BUFFER,W
	MOVWF	CMD
	CLRF	NUM
	GOTO	MAINLP
;
; Calcurate Numeric Operand
;
NUMBER
	MOVLW	.10
	MOVWF	IDX0
	CLRW
N1
	ADDWF	NUM,W
	DECFSZ	IDX0,F
	GOTO	N1
	MOVWF	NUM
	MOVLW	30H
	SUBWF	BUFFER,W
	ADDWF	NUM,F
	GOTO	MAINLP
;
; Excecute Command
;
END_OF_LINE
	MOVF	CMD,W
	SUBLW	CMD_TILT
	BTFSC	STATUS,Z
	GOTO	DO_TILT
	MOVF	CMD,W
	SUBLW	CMD_PAN
	BTFSC	STATUS,Z
	GOTO	DO_PAN
	MOVF	CMD,W
	SUBLW	CMD_HOME
	BTFSC	STATUS,Z
	GOTO	DO_HOME
	MOVF	CMD,W
	SUBLW	CMD_LON
	BTFSC	STATUS,Z
	GOTO	DO_LON
	MOVF	CMD,W
	SUBLW	CMD_LOFF
	BTFSC	STATUS,Z
	GOTO	DO_LOFF
	MOVF	CMD,W
	SUBLW	CMD_STAT
	BTFSC	STATUS,Z
	GOTO	DO_STAT
	MOVF	CMD,W
	SUBLW	CMD_INQ
	BTFSC	STATUS,Z
	GOTO	DO_INQ
	GOTO	MAINLP
;
; Execute Tilt Command
;
DO_TILT
	; NUM -> POS_T (8 bit: 0 - 127)
	MOVF	NUM,W
	MOVWF	POS_T
	GOTO	MAINLP
;
; Execute Pan Command
;
DO_PAN
	; NUM -> POS_P (8 bit: 0 - 127)
	MOVF	NUM,W
	MOVWF	POS_P 
	GOTO	MAINLP
;
; Execute Home Command
;
DO_HOME
	MOVLW	POS_HOME
	MOVWF	POS_P 
	MOVWF	POS_T 
	GOTO	MAINLP
;
; Execute Light On Command
;
DO_LON
	BCF		BREG,7
	GOTO	MAINLP
;
; Execute Light Off Command
;
DO_LOFF
	BSF		BREG,7
	GOTO	MAINLP
;
; Execute Status Command
;
DO_STAT
	MOVF	STNO,W
	CALL	B2C
	MOVF	GR1,W
	CALL	TX
	MOVF	GR0,W
	CALL	TX
	MOVLW	' '
	CALL	TX
	MOVF	POS_P,W
	CALL	B2C
	MOVF	GR2,W
	CALL	TX
	MOVF	GR1,W
	CALL	TX
	MOVF	GR0,W
	CALL	TX
	MOVLW	' '
	CALL	TX
	MOVF	POS_T,W
	CALL	B2C
	MOVF	GR2,W
	CALL	TX
	MOVF	GR1,W
	CALL	TX
	MOVF	GR0,W
	CALL	TX
	CALL	CRLF
	GOTO	MAINLP
;
; Execute Inquire Command
;
DO_INQ
	MOVLW	'H'
	CALL	TX
	MOVLW	'o'
	CALL	TX
	MOVLW	'm'
	CALL	TX
	MOVLW	'e'
	CALL	TX
	MOVLW	'b'
	CALL	TX
	MOVLW	'r'
	CALL	TX
	MOVLW	'e'
	CALL	TX
	MOVLW	'w'
	CALL	TX
	CALL	CRLF
	GOTO	MAINLP

;****************************************
; Interrupt Service Routine
;****************************************

ISR
;
; Save Registers
;
	MOVWF	WREG ; save Wreg
	SWAPF	STATUS,W
	CLRF	STATUS
	MOVWF	SREG
	MOVF	PCLATH,W ; save PClath
	MOVWF	LREG
	CLRF	PCLATH
;
; Process Timer 0 Interrupt
;
TIMER0
	BTFSS	INTCON,T0IF ; If int <> Timer0 then goto CCP1
	GOTO	CCP1
	; Timer 0 service
	BCF		INTCON,T0IF
	MOVLW	03CH
	MOVWF	TMR0 ; Initialize Timer 0 
	MOVLW	0FFH ; XOR Flip Flop
	XORWF	FF,F
	BTFSC	STATUS,Z ; If FF==0 then goto CCP1
	GOTO	CCP1
	; POS_P * POS_RATE  -> ( mul3b, mul3a )
	MOVF	POS_P,W
	MOVWF	mul1a
	MOVLW	POS_RATE
	MOVWF	mul2a
	CALL 	mul816
	; ( mul3b, mul3a ) + (min value) ->  ( CCPR1H, CCPR1L )
	MOVF	mul3b,W
	MOVWF	ad1b  
	MOVF	mul3a,W
	MOVWF	ad1a
	MOVLW	POS_MIN_H
	MOVWF	ad2b
	MOVLW	POS_MIN_L	
	MOVWF	ad2a
	CALL	add16
	MOVF	ad1b,W
	MOVWF	CCPR1H
	MOVF	ad1a,W
	MOVWF	CCPR1L
	; POS_T * POS_RATE  -> ( mul3b, mul3a )
	MOVF	POS_T,W
	MOVWF	mul1a
	MOVLW	POS_RATE
	MOVWF	mul2a
	CALL 	mul816
	; ( mul3b, mul3a ) + (min value) ->  ( CCPR2H, CCPR2L )
	MOVF	mul3b,W
	MOVWF	ad1b  
	MOVF	mul3a,W
	MOVWF	ad1a
	MOVLW	POS_MIN_H
	MOVWF	ad2b
	MOVLW	POS_MIN_L	
	MOVWF	ad2a
	CALL	add16
	MOVF	ad1b,W
	MOVWF	CCPR2H
	MOVF	ad1a,W
	MOVWF	CCPR2L
	; Reset Timer1 value
	CLRF	TMR1H 
	CLRF	TMR1L 
	; Both Servo Output High 
	BSF		BREG,0 ; Pan
	BSF		BREG,1 ; Tilt
	MOVF	BREG,W
	MOVWF	PORTB
	; Start Timer 1
	BSF		T1CON,TMR1ON 
;
; Process CCP1 Interrupt
;
CCP1
	BTFSS	PIR1,CCP1IF ; If int <> CCP1 then goto CCP2
	GOTO	CCP2
	; CCP1 service
	BCF		PIR1,CCP1IF ; Clear CCP1 Interrupt Flag
	; Pan Servo Output Low 
	BCF		BREG,0
	MOVF	BREG,W
	MOVWF	PORTB
;
; Process CCP2 Interrupt
;
CCP2
	BTFSS	PIR2,CCP2IF ; If int <> CCP1 then goto OTHER
	GOTO	OTHER
	; CCP2 service
	BCF		PIR2,CCP2IF ; Clear CCP2 Interrupt Flag
	; Tilt Servo Output Low 
	BCF		BREG,1
	MOVF	BREG,W
	MOVWF	PORTB
;
; Process Other Interrupt
;
OTHER
	; Reset all other interrupt flags
	BCF		INTCON,RBIF
	BCF		INTCON,INTF
;
; Stop Timer 1
;
STOPTMR1
	; If both Puls Low then Stop Timer 1
	BTFSC	BREG,0
	GOTO	ENDIFTMR1	
	BTFSC	BREG,1
	GOTO	ENDIFTMR1
	BCF		T1CON,TMR1ON ; Stop Timer 1 
ENDIFTMR1	
;
; Restore Registers
;
	MOVF	LREG,W
	MOVWF	PCLATH
	SWAPF	SREG,W
	MOVWF	STATUS
	SWAPF	WREG
	SWAPF	WREG,W ; recover Wreg

	RETFIE


;****************************************
; Sub Routine
;****************************************

;-----------------------------------
; Subroutine TX
;   Send a character to serial port
;
; input 
;   Weg : char to send
; output
;   none
;
TX
	MOVWF	TEMP
	BSF		STATUS,RP0
TXBUSY
	BTFSS	TXSTA,TRMT
	GOTO	TXBUSY
	BCF		STATUS,RP0
	MOVF	TEMP,W
	MOVWF	TXREG
	RETURN

CRLF
	MOVLW	0DH
	CALL	TX
	MOVLW	0AH
	CALL	TX
	RETURN

;-------------------------------------
; binary number to character
;
; Input
;   Wreg : binary number
; Output
;   GR0 :   1 degit
;   GR1 :  10 degit
;   GR2 : 100 degit
B2C
	MOVWF	TEMP
	clrf	GR0
	clrf	GR1
	clrf	GR2

	; if w < 100 then goto B2C_10
	MOVF	TEMP,W
	SUBLW	.99
	BTFSC	STATUS,C
	GOTO	B2C_10	
	; w / 100 -> GR2
	; w % 100 -> TEMP
	movf	TEMP,W
	movwf	div1a
	movlw	.100
	movwf	div2a
	call	div8
	movf	div3a,W
	movwf	GR2
	movf	div4a,W
	movwf	TEMP	

B2C_10
	; if w < 10 then goto B2C_1
	MOVF	TEMP,W
	SUBLW	.9
	BTFSC	STATUS,C
	GOTO	B2C_1	

	; w % 100 (=TEMP) -> div1a
	movf	TEMP,W
	movwf	div1a
	; (w % 100) / 10 -> GR1
	movlw	.10
	movwf	div2a
	call	div8	
	movf	div3a,W
	movwf	GR1
	movf	div4a,W
	movwf	TEMP

B2C_1
	; (w % 100) % 10 -> GR0
	movf	TEMP,W
	movwf	GR0

	movlw	30H
	addwf	GR0,F
	addwf	GR1,F
	addwf	GR2,F

	RETURN

;---------------------------------------------------------------------

mul816		;８×８ビット＝１６ビットの乗算
			;mul1a×mul2a＝mul3b（上位）mul3a（下位）
			;mul1a に被乗数、mul2a に乗数を代入し、mul816 をコールする
			;実行後、被乗数、乗数とも保存
			;ルーチン名 : mul816

;---------------------　mul816 での使用変数

mul1a		equ	40h		;被乗数
mul2a		equ	41h		;乗数
mul3b		equ	42h		;結果（上位）
mul3a		equ	43h		;結果（下位）
lc			equ	44h		;ループ用

;使用変数の xxh には適切なアドレスを記入してご使用下さい。

;--------------------　使用例

;		movlw	d'255'		;定数を w に代入
;		movwf	mul1a		;w から mul1a にセット（被乗数）
;		movlw	d'255'		;定数を w に代入
;		movwf	mul2a		;w から mul2a にセット（乗数）
;		call	mul816		;呼ぶ

;--------------------  mul816 の主ルーチン
 

					;乗数を答え下位（ワーク）にコピーする
		movf	mul2a,0		;mul2a を w にコピー
		movwf	mul3a		;w から mul3a にコピー
		clrf	mul3b		;答用変数、上位をクリアしておく

		movlw	8
		movwf	lc		;lc に 8 を代入
mul611
		bcf	3,0		;キャリフラグのクリア
		btfss	mul3a,0		;最下位ビットが 0 なら mul612 へ飛ぶ
		goto	mul612
		movf	mul1a,0		;mul1a（下位） を w にコピー
		addwf	mul3b,1		;答え（下位）に加える（キャリフラグが次のシフトに必要）

mul612
		rrf	mul3b,1		;答えを１ビット右に送る（被乗数を倍する）
		rrf	mul3a,1		;　～ 下位

		decfsz	lc,1		;ビット数分の繰り返し
		goto	mul611

		return

;---------------------------------------------------------------------

add16	;１６＋１６＝１６ビットの加算
		;ad1b(上位),ad1a(下位) と ad2b,ad2a に二つの引き数を
		;セットして呼ぶ
		;結果は ad1b,ad1a （左項）に加算された形で得られる。
		;ad2b,ad2a は変化しない。

;------------------------------  add16 での使用変数

ad1b		equ	45h	;引き数１／答え(上位)
ad1a		equ	46h	;引き数１／答え(下位)
ad2b		equ	47h	;引き数２(上位)
ad2a		equ	48h	;引き数２(下位)

;使用変数の xxh には適切なアドレスを記入してご使用下さい。

;------------------------------

		movf	ad2a,0
		addwf	ad1a,1
		btfsc	3h,0
		incf	ad1b,1
		movf	ad2b,0
		addwf	ad1b,1

		return

;---------------------------------------------------------------------

div8			;８ビットの割り算ルーチン

;--------------------	div8 での使用変数

div1a		equ	49h		;割られる数　（終了時には０になって戻る）
div2a		equ	4ah		;割る数       (変化せず戻る）
div3a		equ	4bh		;答え　　　　（答えが返る）
div4a		equ	4ch		;余り　　　　（余りが返る、内部ワークにも使用）
divl1		equ	4dh		;内部ループ用
divl2		equ	4eh		;内部ループ用
d8err		equ	4fh		;割る数が０であった場合に１をセットして戻る

;使用変数の xxh には適切なアドレスを記入してご使用下さい。

;--------------------	使用例

;		movlw	0ffh		;割られる数    255
;		movwf	div1a
;		movlw	07h		;割る数        7
;		movwf	div2a
;		call	div8		;答えは div3a 、余りは div4a に返る

;--------------------	主ルーチン

		movlw	8
		movwf	divl1
		movf	div2a,0		;割る数をコピー
		movwf	div4a
di801
		rlf	div4a,1		;左シフトする
		btfsc	3h,0		;割る数の上位ビット位置を探す
		goto	di802
		decfsz	divl1,1
		goto	di801
		movlw	1
		movwf	d8err		;割る数が０である、エラー
		return
di802
		clrf	div3a		;答えをクリアしておく
		clrf	div4a		;ワークをクリアしておく
		movlw	8
		movwf	divl2
		movf	divl1,0
		subwf	divl2,1		;残り、実ループの回数
di803
		bcf	3h,0		;キャリフラグを０に
		rlf	div1a,1
		rlf	div4a,1
		decfsz	divl1,1
		goto	di803		;割られる数を初期位置までシフトしておく
di804
		movf	div2a,0
		subwf	div4a,0
		btfss	3h,0
		goto	di805		;引くことが不可能（上位が小さい）なら di805 へ
		movf	div2a,0
		subwf	div4a,1
		bsf	3h,0		;キャリフラグを１に
		goto	di806
di805
		bcf	3h,0		;キャリフラグを０に
di806
		rlf	div3a,1		;キャリフラグの内容を答えにシフトしてゆく
		movf	divl2,1
		btfsc	3h,2
		goto	di807		;最下位まで処理したなら終了

		decf	divl2,1		;ビット位置を１つ下げる（右へ）
		bcf	3h,0		;キャリフラグを０に
		rlf	div1a,1		;ワークへ１ビット左シフト
		rlf	div4a,1
		goto	di804
di807
		clrf	d8err		;正常終了
		return


	END

                

