#ifndef _ope_inc_ #define _ope_inc_ messg "include 'ope.inc'" LIST ; Title : Numeric operation ; By : komi ; Last update : 2007.02.28 ; Version : 0.40 NOLIST ;---------------------------------------------------------------------------- ; 解説 ;---------------------------------------------------------------------------- ; ; ■代入 ; ・1byte型 ; move_U1W u1 u1 ← Wreg Wregからの代入 ; move_S1W s1 s1 ← Wreg ; move_U1V1 u1, v u1 ← v 値を直接代入 ; move_S1V1 s1, v s1 ← v ; move_U1U1 u1, u1 u1 ← u1 変数からの代入 ; move_S1S1 s1, s1 s1 ← s1 ; ・2byte型 ; move_U2W u2 u2 ← Wreg Wregからの代入, 上位にはゼロ ; move_S2W s2 s2 ← Wreg ; move_U2V2 u2, v u2 ← 値 値を直接代入 ; move_S2V2 s2, v s2 ← 値 ; move_U2U2 u2, u2 u2 ← u2 変数からの代入 ; move_S2S2 s2, s2 s2 ← s2 ; ;---------------------------------------------------------------------------- ; ; ■足し算 ; ・2byte型 ; add_U2U2 u2A, u2B u2A = u2A + u2B ; ;---------------------------------------------------------------------------- ; ; ■引き算 ; ・2byte型 ; sub_U2U2 u2A, u2B u2A = u2A - U2B ; ;---------------------------------------------------------------------------- ; ; ■掛け算 ; ・U2_Multi_U1U1 MACRO result, var1, var2 ; U2:result 結果が入る ; U1:var1 掛けられる数 ; U1:var2 掛ける数 ; ・U2_Multi_U1U1_fast MACRO result, var1, var2 ; U2:result 結果が入る ; U1:var1 掛けられる数 ; U1:var2 掛ける数、破壊されます ; <*>ループを展開することで高速化しています. ; ;---------------------------------------------------------------------------- ; ; ■シフト ; ・1byte型 ; lshift_U1V1 u1, v u1 <<= v ; rshift_U1V1 u1, v u1 >>= v ; lshift_S1V1 s1, v s1 <<= v ; rshift_S1V1 s1, v s1 >>= v (*)算術シフト ; ;---------------------------------------------------------------------------- ; ; ■比較 ; ・比較演算子の種類 ; _Equal_ == ; _IsNot_ != ; _IsLargerThan_ > ; _IsSmallerThan_ < ; _IsOrMore_ >= ; _IsOrLess_ <= ; ・書き方 ; if (A == B) goto C; C言語風 ; if_U1U1_goto A, _IsEqualTo_, B, C 本マクロの場合 ; ; ・書き方 ; if (A == B) { 処理A } C言語風 ; else if (A < B) { 処理B } ; else { 処理C } ; if_U1U1 A, _IsEqualTo_, B ; 処理A ; else_if_U1U1 A, _IsSmallerThan_, B ; 処理B ; else_ ; 処理C ; end_if ; ; ジャンプ先が同ページ内の場合 ; if_U1V1_goto A, 10, labelA ; ジャンプ先が他ページの場合 ; if_U1V1_lgoto A, 10, labelB ; #define _IsEqualTo_ 0 ; == #define _IsNotEqualTo_ 1 ; != #define _IsLargerThan_ 2 ; > #define _IsSmallerThan_ 3 ; < #define _IsOrMore_ 4 ; >= #define _IsOrLess_ 5 ; <= #define _AND_ 6 ; & #define _OR_ 7 ; | #define _XOR_ 8 ; ^ variable _IfCount0 = 0 variable _IfCount1 = 0 ;---------------------------------------------------------------------------- ; ; ;---------------------------------------------------------------------------- ;------------------------------------------------------------------ ; 一時エリア U_OPE UDATA OPE_TEMP0 res 1 OPE_TEMP1 res 1 ;------------------------------------------------------------------ ;---------------------------------------------------------------------------- ; 代入 ;------------------------------------------------------------------ ; Wreg ← U1 move_WU1 MACRO var banksel var MOVF var, W ENDM ;------------------------------------------------------------------ ; Wreg ← V1 move_WV1 MACRO value MOVLW value ENDM ;------------------------------------------------------------------ ; u1 ← Wreg ; s1 ← Wreg move_U1W MACRO var banksel var MOVWF var ENDM #define move_S1W mave_U1W ;------------------------------------------------------------------ ; u1 ← unsigned 1byte data move_U1V1 MACRO var, value NOLIST if (value < D'0' || value > D'255') messg "The value is outside the range.(OPE.INC)" endif if (value != D'0') LIST banksel var MOVLW value MOVWF var NOLIST else LIST banksel var CLRF var NOLIST endif LIST ENDM ;------------------------------------------------------------------ ; s1 ← signed 1byte data move_S1V1 MACRO var, value NOLIST if (value < -D'128' || value > D'127') messg "The value is outside the range.(OPE.INC)" endif if (value != D'0') LIST banksel var MOVLW value MOVWF var NOLIST else LIST banksel var CLRF var NOLIST endif LIST ENDM ;------------------------------------------------------------------ ; u1 ← u1 ; s1 ← s1 move_U1U1 MACRO var1, var2 banksel var2 MOVF var2, w banksel var1 MOVWF var1 ENDM #define move_S1S1 move_U1U1 ;------------------------------------------------------------------ ; u2 ← Wreg ; s2 ← Wreg move_U2W MACRO var banksel var MOVWF var CLRF (var+1) ENDM #define move_S2W move_U2W ;------------------------------------------------------------------ ; u2 ← unsigned 2byte data move_U2V2 MACRO var, value if (value < D'0' | value > D'65535') messg "The value is outside the range.(OPE.INC)" endif banksel var if (value != D'0') MOVLW low value MOVWF var MOVLW high value MOVWF (var+1) else CLRF var CLRF (var+1) endif ENDM ;------------------------------------------------------------------ ; s2 ← signed 2byte data move_S2V2 MACRO var, value if (value < -D'32768' || value > D'32767') messg "The value is outside the range.(OPE.INC)" endif banksel var if (value != D'0') MOVLW low value MOVWF var MOVLW high value MOVWF (var+1) else CLRF var CLRF (var+1) endif ENDM ;------------------------------------------------------------------ ; u2 ← u2 ; s2 ← s2 move_U2U2 MACRO var1, var2 banksel var2 MOVF var2, w banksel var1 MOVWF var1 banksel var2 MOVF (var2+1), w banksel var1 MOVWF (var1+1) ENDM #define move_S2S2 move_U2U2 ;------------------------------------------------------------------ ;---------------------------------------------------------------------------- ; 論理演算 ;------------------------------------------------------------------ ; U1 = U1 & Wreg and_U1W MACRO varU1 banksel varU1 ANDWF varU1, F ENDM ;------------------------------------------------------------------ ; U1 = U1 & V1 and_U1V1 MACRO varU1, value MOVLW value and_U1W varU1 ENDM ;------------------------------------------------------------------ ; U1 = U1 | Wreg or_U1W MACRO varU1 banksel varU1 IORWF varU1, F ENDM ;------------------------------------------------------------------ ; U1 = U1 | V1 or_U1V1 MACRO varU1, value MOVLW value or_U1W varU1 ENDM ;------------------------------------------------------------------ ;---------------------------------------------------------------------------- ; 足し算 ;------------------------------------------------------------------ ; U1 = U1 + Wreg add_U1W MACRO varU1 banksel varU1 ADDWF varU1, F ENDM ;------------------------------------------------------------------ ; U1 = U1 + V1 add_U1V1 MACRO varU1, value MOVLW value add_U1W varU1 ENDM ;------------------------------------------------------------------ ; U1 = U1 + U1 add_U1U1 MACRO var1, var2 banksel var2 MOVF var2, W banksel var1 ADDWF var1, F ENDM ;------------------------------------------------------------------ ; U2 = U2 + U2 add_U2U2 MACRO var1, var2 banksel var2 MOVF var2, W banksel var1 ADDWF var1, F banksel var2 MOVF (var2+1), W BTFSC STATUS, C INCF (var2+1), W banksel data1 ADDWF (var1+1), F ENDM ;------------------------------------------------------------------ ; U2 = U2 + W add_U2W MACRO var banksel var ADDWF var, F BTFSC STATUS, C INCF (var+1), F ENDM ;------------------------------------------------------------------ ;---------------------------------------------------------------------------- ; 引き算 ;------------------------------------------------------------------ ; U1 = U1 - Wreg sub_U1W MACRO varU1 banksel varU1 SUBWF varU1, F ENDM ;------------------------------------------------------------------ ; U1 = U1 - V1 sub_U1V1 MACRO varU1, value MOVLW value sub_U1W varU1 ENDM ;------------------------------------------------------------------ ; U2 = U2 - U2 sub_U2U2 MACRO var1, var2 banksel var2 MOVF var2, W banksel var1 SUBWF var1, F banksel var2 MOVF (var2+1), W BTFSS STATUS, C INCF (var2+1), W banksel data1 SUBWF (var1+1), F ENDM ;------------------------------------------------------------------ ;---------------------------------------------------------------------------- ; 掛け算 ;------------------------------------------------------------------ ; u2 = u1 * u1 ; OPE_TEMP0 is temporary. ; result = var1 * var2 U2_Multi_U1U1 MACRO result, var1, var2 local Multi_loop banksel result CLRF result CLRF (result+1) banksel var2 MOVF var2, W banksel OPE_TEMP1 MOVWF OPE_TEMP1 banksel OPE_TEMP0 MOVLW D'8' MOVWF OPE_TEMP0 BCF STATUS, C banksel var1 MOVF var1, W Multi_loop banksel OPE_TEMP1 RRF OPE_TEMP1, F banksel result BTFSC STATUS, C ADDWF (result+1), F RRF (result+1), F RRF result, F banksel OPE_TEMP0 DECFSZ OPE_TEMP0, F GOTO Multi_loop ENDM ;------------------------------------------------------------------ ; u2 = u1 * u1 ; Var2 is destroyed. ; result = var1 * var2 U2_Multi_U1U1_fast MACRO result, var1, var2 local i=0; banksel result CLRF result CLRF (result+1) BCF STATUS, C banksel var1 MOVF var1, W while (D'8' > i) banksel var2 RRF var2, F banksel result BTFSC STATUS, C ADDWF (result+1), F RRF (result+1), F RRF result, F i++ endw ENDM ;------------------------------------------------------------------ ;---------------------------------------------------------------------------- ; シフト ;------------------------------------------------------------------ ; u1 <<= n ; s1 <<= n lshift_U1 MACRO var, n local i=0 banksel var while (n > i) BCF STATUS, C RLF var, F i++ endw ENDM #define lshift_S2 lshift_U2 ;------------------------------------------------------------------ ; u1 >>= n rshift_U1 MACRO var, n local i=0 banksel var while (n > i) BCF STATUS, C RRF var, F i++ endw ENDM ;------------------------------------------------------------------ ; u2 >>= n rshift_U2 MACRO var, n local i=0 banksel var while (n > i) BCF STATUS, C RRF (var+1), F RRF var, F i++ endw ENDM ;------------------------------------------------------------------ ; s1 >>= n rshift_S1 MACRO var, n local i=0 banksel var while (n > i) BCF STATUS, C BTFSC var, D'7' BSF STATUS, C RRF var, F i++ endw ENDM ;------------------------------------------------------------------ ;---------------------------------------------------------------------------- ; 比較 ;------------------------------------------------------------------ ; if (U1 ope U1) lgoto if_U1U1_lgoto MACRO var1, ope, var2, label1 pagesel label1 if_U1U1_goto var1, ope, var2, label1 ENDM ;------------------------------------------------------------------ ; if (U1 ope U1) goto if_U1U1_goto MACRO var1, ope, var2, label1 NOLIST if (ope == _IsEqualTo_) LIST banksel var2 MOVF var2, W banksel var1 XORWF var1, W BTFSC STATUS, Z NOLIST endif if (ope == _IsNotEqualTo_) LIST banksel var2 MOVF var2, W banksel var1 XORWF var1, W BTFSS STATUS, Z NOLIST endif if (ope == _IsLargerThan_) LIST banksel var1 MOVF var1, W banksel var2 SUBWF var2, W BTFSS STATUS, C NOLIST endif if (ope == _IsSmallerThan_) LIST banksel var2 MOVF var2, W banksel var1 SUBWF var1, W BTFSS STATUS, C NOLIST endif if (ope == _IsOrMore_) LIST banksel var2 MOVF var2, W banksel var1 SUBWF var1, W BTFSC STATUS, C NOLIST endif if (ope == _IsOrLess_) LIST banksel var1 MOVF var1, W banksel var2 SUBWF var2, W BTFSC STATUS, C NOLIST endif if (ope == _AND_) LIST banksel var1 MOVF var1, W banksel var2 ANDWF var2, W BTFSS STATUS, Z NOLIST endif if (ope == _OR_) LIST banksel var1 MOVF var1, W banksel var2 IORWF var2, W BTFSS STATUS, Z NOLIST endif if (ope == _XOR_) LIST banksel var1 MOVF var1, W banksel var2 XORWF var2, W BTFSS STATUS, Z NOLIST endif LIST GOTO label1 ENDM ;------------------------------------------------------------------ ; if (U1 ope U1) else endif if_U1U1_core MACRO var1, ope, var2 NOLIST if (ope == _IsEqualTo_) LIST banksel var2 MOVF var2, W banksel var1 XORWF var1, W BTFSS STATUS, Z NOLIST endif if (ope == _IsNotEqualTo_) LIST banksel var2 MOVF var2, W banksel var1 XORWF var1, W BTFSC STATUS, Z NOLIST endif if (ope == _IsLargerThan_) LIST banksel var1 MOVF var1, W banksel var2 SUBWF var2, W BTFSC STATUS, C NOLIST endif if (ope == _IsSmallerThan_) LIST banksel var2 MOVF var2, W banksel var1 SUBWF var1, W BTFSC STATUS, C NOLIST endif if (ope == _IsOrMore_) LIST banksel var2 MOVF var2, W banksel var1 SUBWF var1, W BTFSS STATUS, C NOLIST endif if (ope == _IsOrLess_) LIST banksel var1 MOVF var1, W banksel var2 SUBWF var2, W BTFSS STATUS, C NOLIST endif if (ope == _AND_) LIST banksel var1 MOVF var1, W banksel var2 ANDWF var2, W BTFSC STATUS, Z NOLIST endif if (ope == _OR_) LIST banksel var1 MOVF var1, W banksel var2 IORWF var2, W BTFSC STATUS, Z NOLIST endif if (ope == _XOR_) LIST banksel var1 MOVF var1, W banksel var2 XORWF var2, W BTFSC STATUS, Z NOLIST endif LIST ENDM if_U1U1 MACRO var1, ope, var2 NOLIST _IfCount0++ _IfCount1++ variable _IfCount2_#v(_IfCount0) = 0 _IfKaisou#v(_IfCount1) = _IfCount0 LIST if_U1U1_core var1, ope, var2 GOTO iflabel_#v(_IfCount0)_#v(_IfCount2_#v(_IfCount0)) ENDM else_if_U1U1 MACRO var1, ope, var2 NOLIST local temp = _IfKaisou#v(_IfCount1) LIST GOTO endif_#v(temp) iflabel_#v(temp)_#v(_IfCount2_#v(temp)): NOLIST _IfCount2_#v(temp)++ LIST if_U1U1_core var1, ope, var2 GOTO iflabel_#v(temp)_#v(_IfCount2_#v(temp)) ENDM else_ MACRO NOLIST local temp = _IfKaisou#v(_IfCount1) LIST GOTO endif_#v(temp) iflabel_#v(temp)_#v(_IfCount2_#v(temp)): NOLIST _IfCount2_#v(temp)++ LIST ENDM end_if MACRO NOLIST local temp = _IfKaisou#v(_IfCount1) LIST iflabel_#v(temp)_#v(_IfCount2_#v(temp)): endif_#v(temp): NOLIST _IfCount1-- LIST ENDM ;------------------------------------------------------------------ ; if (U1 ope V1) lgoto if_U1V1_lgoto MACRO var, ope, value, label1 pagesel label1 if_U1V1_goto var, ope, value, label1 ENDM ;------------------------------------------------------------------ ; if (U1 ope V1) goto if_U1V1_goto MACRO var, ope, value, label1 NOLIST if (ope == _IsEqualTo_) LIST MOVLW value banksel var XORWF var, W BTFSC STATUS, Z NOLIST endif if (ope == _IsNotEqualTo_) LIST MOVLW value banksel var XORWF var, W BTFSS STATUS, Z NOLIST endif if (ope == _IsLargerThan_) LIST banksel var MOVF var, W SUBLW value BTFSS STATUS, C NOLIST endif if (ope == _IsSmallerThan_) LIST MOVLW value banksel var SUBWF var, W BTFSS STATUS, C NOLIST endif if (ope == _IsOrMore_) LIST MOVLW value banksel var SUBWF var, W BTFSC STATUS, C NOLIST endif if (ope == _IsOrLess_) LIST banksel var MOVF var, W SUBLW value BTFSC STATUS, C NOLIST endif if (ope == _AND_) LIST banksel var MOVF var, W ANDLW value BTFSS STATUS, Z NOLIST endif if (ope == _OR_) LIST banksel var MOVF var, W IORLW value BTFSS STATUS, Z NOLIST endif if (ope == _XOR_) LIST banksel var MOVF var, W XORLW value BTFSS STATUS, Z NOLIST endif LIST GOTO label1 ENDM ;------------------------------------------------------------------ ; if (U1 ope V1) else if if_U1V1_core MACRO var, ope, value NOLIST if (ope == _IsEqualTo_) LIST MOVLW value banksel var XORWF var, W BTFSS STATUS, Z NOLIST endif if (ope == _IsNotEqualTo_) LIST MOVLW value banksel var XORWF var, W BTFSC STATUS, Z NOLIST endif if (ope == _IsLargerThan_) LIST banksel var MOVF var, W SUBLW value BTFSC STATUS, C NOLIST endif if (ope == _IsSmallerThan_) LIST MOVLW value banksel var SUBWF var, W BTFSC STATUS, C NOLIST endif if (ope == _IsOrMore_) LIST MOVLW value banksel var SUBWF var, W BTFSS STATUS, C NOLIST endif if (ope == _IsOrLess_) LIST banksel var MOVF var, W SUBLW value BTFSS STATUS, C NOLIST endif if (ope == _AND_) LIST banksel var MOVF var, W ANDLW value BTFSC STATUS, Z NOLIST endif if (ope == _OR_) LIST banksel var MOVF var, W IORLW value BTFSC STATUS, Z NOLIST endif if (ope == _XOR_) LIST banksel var MOVF var, W XORLW value BTFSC STATUS, Z NOLIST endif LIST ENDM if_U1V1 MACRO var1, ope, var2 NOLIST _IfCount0++ _IfCount1++ variable _IfCount2_#v(_IfCount0) = 0 _IfKaisou#v(_IfCount1) = _IfCount0 LIST if_U1V1_core var1, ope, var2 GOTO iflabel_#v(_IfCount0)_#v(_IfCount2_#v(_IfCount0)) ENDM else_if_U1V1 MACRO var1, ope, var2 NOLIST local temp = _IfKaisou#v(_IfCount1) LIST GOTO endif_#v(temp) iflabel_#v(temp)_#v(_IfCount2_#v(temp)): NOLIST _IfCount2_#v(temp)++ LIST if_U1V1_core var1, ope, var2 GOTO iflabel_#v(temp)_#v(_IfCount2_#v(temp)) ENDM ;------------------------------------------------------------------ ;---------------------------------------------------------------------------- ; その他 ;------------------------------------------------------------------ ; even parity ; var1 は破壊されます ; Z = 偶数パリティ parity_U1 MACRO var1 banksel var1 SWAPF var1, W XORWF var1, F RRF var1, W XORWF var1, F RRF var1, W RLF var1, F XORWF var1, W ANDLW B'00111110' ENDM ;------------------------------------------------------------------ ; swap U1, Wreg swap_U1W MACRO var1 banksel var1 XORWF var1, F XORWF var1, W XORWF var1, F ENDM ;------------------------------------------------------------------ ; swap U1, U1 swap_U1U1 MACRO var1, var2 banksel var1 XORWF var1, F XORWF var1, W XORWF var1, F banksel var2 MOVWF var2 ENDM ;------------------------------------------------------------------ ; U1++ inc_U1 MACRO varU1 banksel varU1 INCF varU1, F ENDM ;------------------------------------------------------------------ ; U2++ inc_U2 MACRO varU2 banksel varU2 INCFSZ varU2, F GOTO $+2 INCF (varU2+1), F ENDM ;------------------------------------------------------------------ ; U1-- dec_U1 MACRO varU1 banksel varU1 DECF varU1, F ENDM ;------------------------------------------------------------------ ; U2-- dec_U2 MACRO varU2 banksel varU2 DECF varU2, F INCFSZ varU2, W GOTO $+2 DECF (varU2+1), F ENDM ;------------------------------------------------------------------ ; if (A <= U1 && U1 <= B) goto if_between_V1U1V1_goto MACRO val1, var, val2, label banksel var MOVF var, W ADDLW (D'255'-val2) ADDLW (val2-val1+1) BTFSC STATUS, C GOTO label ENDM ;------------------------------------------------------------------ ; if (A <= U1 && U1 <= B) else endif if0_between_V1U1V1 MACRO number, val1, var, val2 banksel var MOVF var, W ADDLW (D'255'-val2) ADDLW (val2-val1+1) BTFSS STATUS, C GOTO endif_#v(number) ENDM if0e_between_V1U1V1 MACRO number, val1, var, val2 banksel var MOVF var, W ADDLW (D'255'-val2) ADDLW (val2-val1+1) BTFSS STATUS, C GOTO else_#v(number) ENDM ;------------------------------------------------------------------ ; if !(A <= U1 && U1 <= B) goto if_not_between_V1U1V1_goto MACRO val1, var, val2, label banksel var MOVF var, W ADDLW (D'255'-val2) ADDLW (val2-val1+1) BTFSS STATUS, C GOTO label ENDM ;------------------------------------------------------------------ ; if !(A <= U1 && U1 <= B) else endif if0_not_between_V1U1V1 MACRO number, val1, var, val2, label banksel var MOVF var, W ADDLW (D'255'-val2) ADDLW (val2-val1+1) BTFSS STATUS, C GOTO endif_v#(number) ENDM if0e_not_between_V1U1V1 MACRO number, val1, var, val2, label banksel var MOVF var, W ADDLW (D'255'-val2) ADDLW (val2-val1+1) BTFSS STATUS, C GOTO else_v#(number) ENDM ;------------------------------------------------------------------ ;---------------------------------------------------------------------------- LIST #endif