;--------------------------------------------------------------------- ; ゆっくり世代交代するスローライフゲーム ; ; 2008.03.04 T.Nakamura (c) ; ; (1). RA4(入力) :IRセンサ ; (2). RB0〜7 :行データ ; (3). RA0〜2 :列カウンタ(3-8デコーダ TC74HC238AP) ; (4). RA3 :3-8デコーダ TC74HC238AP ENABLE ;--------------------------------------------------------------------- ; ;--------------------------------------------------------------------- ; デバイス定義 ;--------------------------------------------------------------------- LIST P=PIC16F648A INCLUDE "P16F648A.INC" __CONFIG _CP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC & _LVP_OFF ERRORLEVEL -302 ;アセンブル時のバンク警告メッセージ抑制 ;--------------------------------------------------------------------- ; 変数レジスタの定義(BANK0) ;--------------------------------------------------------------------- DSPBUF EQU 020H ; 表示バッファ 32バイト(20H〜3FH) PRVGENE EQU 040H ; 前世代 8バイト(40H〜47H) NOWGENE EQU 048H ; 現世代 8バイト(48H〜4FH) NXTGENE EQU 050H ; 次世代 8バイト(50H〜57H) IRBUF EQU 058H ; IRセンサバッファ 8バイト(58H〜5FH) ; BKUPW EQU 060H ; Wレジ待避用 BKUPS EQU 061H ; STATUSレジ待避用 BKUPFR EQU 062H ; FSRレジ待避用 BKUPPCL EQU 063H ; PCLHレジ待避用 DUTYCNT EQU 064H ; LED ON時間をカウントするデューティカウンタ CNT1 EQU 065H ; ウェイトカウンタ CNT2 EQU 066H ; 〃 CNT EQU 067H ; カウンタ ROWCNT EQU 068H ; カウンタ LINCNT EQU 069H ; カウンタ LEDBUF EQU 06AH ; LEDバッファ BRIGHT EQU 06BH ; 輝度 WK1 EQU 06CH ; 作業用 WK2 EQU 06DH ; 作業用 FLAG EQU 06EH ; FLAG[0] 前世代のセル状態:1:存在、0:無し ; FLAG[1] 現世代のセル状態:1:存在、0:無し DSPPOS EQU 06FH ; 表示位置 WKBRT EQU 070H ; 輝度(割り込み処理で使用) CNT3 EQU 071H ; CNT4 EQU 072H ; TARGET EQU 073H LIFECNT EQU 074H TMP EQU 075H GENENO EQU 076H ; 世代カウンタ LIFENO EQU 077H ; 生きているセル数 BORN EQU 078H ; 次世代で生まれるセル数 DEATH EQU 079H ; 次世代で死滅するセル数 FIXCNT EQU 07AH ; 固定状態検出カウンタ BRIGHT2 EQU 07BH ; 輝度 PRVLIFE EQU 07CH ; 前回のライフ数 IRCNT EQU 07DH ; 赤外線センサのチェックカウンタ IRBUFF EQU 07EH ; 赤外線センサのバッファ ;--------------------------------------------------------------------- ; マクロ定義 ;--------------------------------------------------------------------- BANK0 MACRO BCF STATUS,RP0 ;BANK0に切り替える ENDM BANK1 MACRO BSF STATUS,RP0 ;BANK1に切り替える ENDM ;--------------------------------------------------------------------- ; リセットベクタ ;--------------------------------------------------------------------- ORG 00H ; リセット時の飛び込み先 RESET GOTO START ; ; ORG 04H ; 割り込み時の飛び込み先 ;--------------------------------------------------------------------- ; 割り込み処理でダイナミック表示を行う。 ; 約9.765KHzの割り込みで表示バッファの値を判定し、順次ポート出力する。 ;--------------------------------------------------------------------- INTRUPT ;レジスタ待避 MOVWF BKUPW ;バックアップ(Wレジ) SWAPF STATUS,W ;バックアップ(STATUSレジ) MOVWF BKUPS MOVF FSR,W ;バックアップ(FSRレジ) MOVWF BKUPFR ; BCF INTCON,T0IF ;割り込みフラグリセット ; ; 表示バッファの内容を1列分(1行)出力 ; 4バイトで1列分 ; ROWCNT:列 ; LINCNT:行 ; ; ROWCNTをアドレス変換(4倍し、DSPBUFを加算) MOVF ROWCNT,W ; MOVWF FSR ; FSR にセット BCF STATUS,C ; キャリーをクリア RLF FSR,F ; 左にbit shift2回で元の4倍 RLF FSR,F ; MOVLW DSPBUF ; 表示バッファアドレスを加算 ADDWF FSR,F ; CLRF LINCNT CLRF LEDBUF MOVF DUTYCNT,W CALL BRTTBL MOVWF WKBRT LINELP MOVF INDF,W ; 対象セルの指定輝度を取り出す BTFSC LINCNT,0 ; 奇数/偶数判断 SWAPF INDF,W ; 奇数ならニブルスワップで取り出し直し ANDLW H'0F' ; 3ビットだけ取り出す BTFSC STATUS,Z ; 0なら点灯しないので次のセル確認 GOTO NEXTCELL SUBWF WKBRT,W ; 指定輝度 < 現在の輝度 なら OFF BTFSC STATUS,C GOTO NEXTCELL CELLON MOVF LINCNT,W CALL DECBIT IORWF LEDBUF,F ; LEDBUFの当該bitをON ; NEXTCELL BTFSC LINCNT,0 ; 奇数/偶数判断 INCF FSR,F ; 奇数なら次のセルアドレスへインクリメント INCF LINCNT,F BTFSS LINCNT,3 ; 3ビット目が1なら8になったのでループ終わり GOTO LINELP ; CLRF PORTA ; 3-8デコーダをDISABLE(3bit目) MOVF LEDBUF,W MOVWF PORTB ; LEDバッファの内容を出力 MOVF ROWCNT,W IORLW B'00001000' ; 3ビット目(3-8デコーダENABLE) MOVWF PORTA ; ROWカウンタを出力 ; INCF DUTYCNT,F MOVLW D'16' SUBWF DUTYCNT,W BTFSS STATUS,Z ; DUTYCNT==16なら次の列の処理 GOTO RSTREG ; CLRF DUTYCNT ; 次の列のためにクリア INCF ROWCNT,F ; 次の列のためにROWカウンタアップ BTFSC ROWCNT,3 ; ROWCNT==8 なら0に戻す CLRF ROWCNT ; ;レジスタ復元 RSTREG MOVF BKUPFR,W ;復元(FSRレジ) MOVWF FSR SWAPF BKUPS,W ;復元(STATUSレジ) MOVWF STATUS SWAPF BKUPW,F ;復元(Wレジ) SWAPF BKUPW,W ; RETFIE ;割り込みから復帰 BRTTBL CLRF PCLATH ; ADDWF PCL,F RETLW D'0' ;0 RETLW D'1' ;1 RETLW D'2' ;2 RETLW D'3' ;3 RETLW D'4' ;4 RETLW D'5' ;5 RETLW D'6' ;6 RETLW D'7' ;7 RETLW D'8' ;8 RETLW D'9' ;9 RETLW D'9' ;10 RETLW D'10' ;11 RETLW D'10' ;12 RETLW D'11' ;13 RETLW D'11' ;14 RETLW D'11' ;15 ;--------------------------------------------------------------------- ; 初期化 ;--------------------------------------------------------------------- START BCF INTCON,GIE ;全割込み禁止 BANK1 MOVLW B'11110000' MOVWF TRISA ;ポートAはBIT0-3を出力、4-7を入力端子 CLRF TRISB ;ポートBは全て出力端子 ;割り込みタイマーセット ; MOVLW H'80' ;プリスケーラを1:2にする MOVLW H'88' ;プリスケーラを使わない MOVWF OPTION_REG ;約1Kヘルツで割り込みが入るはず BANK0 ;clock10MHz -> 2.5Mcycle ;2.5Mcycle/256=9,765Hz(=102.4usec毎) MOVLW 0x07 ; MOVWF CMCON ;コンパレータモードOFF ; ; CLRF PORTA CLRF PORTB CLRF DUTYCNT CLRF ROWCNT CALL CLRDPBUF ; BCF FLAG,4 ; 動作モードゆっくり ; ;--------------------------------------------------------------------- ; メイン処理 ;--------------------------------------------------------------------- BCF FLAG,3 ; IR受信フラグ ; BSF INTCON,T0IE ; タイマ0割り込みイネーブル BSF INTCON,GIE ;割り込み許可 ; ; CALL CLRDPBUF ;表示バッファクリア CALL CLRPRV ; 前世代クリア CALL LIFEPTRN ; 初期パターン MAINLOOP BCF FLAG,2 ; 次の世代で終了フラグ CLRF GENENO ; 世代カウンタクリア CLRF FIXCNT ; 繰り返しを検出するカウンタ CLRF PRVLIFE ; 前世代のライフ数 ; GENELOOP CLRF BRIGHT MOVLW D'12' ; 12段階で輝度を変化 MOVWF CNT3 BRTLOOP ; 輝度のアップダウンループ CALL SETBRT CALL WAIT02S BTFSC FLAG,3 ; もしIR割り込みを受信したら新世界 GOTO NEWWORLD DECFSZ CNT3,F GOTO BRTLOOP ; BTFSC FLAG,2 ; 次の世代で終了フラグ GOTO SLEEPWLD ; CALL WAIT05S ; 1世代の表示時間 BTFSC FLAG,3 ; もしIR割り込みを受信したら新世界 GOTO NEWWORLD ; MOVF LIFENO,W MOVWF PRVLIFE ; 前回のLIFE数を保存 CALL CHKGENE ; 新世代のデータ作成 CALL CPYGENE ; 世代テーブルをコピー INCF GENENO,F ; 1世代進んだ ; MOVF LIFENO,F BTFSC STATUS,Z ; 生きているセルが0になった GOTO FINNEXT ; 新世界創世 ; MOVF BORN,F BTFSS STATUS,Z ; 生まれたセルが0 GOTO CHKLIMGEN MOVF DEATH,F BTFSS STATUS,Z ; 死んだセルが0 GOTO CHKLIMGEN ; FINNEXT BSF FLAG,2 ; 次の世代で終了 CALL CLRNOW ; 現世代を0にしてフェイドアウト GOTO GENELOOP ; CHKLIMGEN MOVF PRVLIFE,W ; SUBWF LIFENO,W ; 前世代のライフ数と比較 BTFSS STATUS,Z GOTO CHKLIMIT ; 変化があるのでLIMITチェック ; INCF FIXCNT,F ; 変化がなく同じLIFE数で振動状態の可能性あり。 MOVLW D'10' SUBWF FIXCNT,W BTFSS STATUS,Z GOTO GENELOOP GOTO FINNEXT ; 次の世代で終了 ; CHKLIMIT ; LIFE数の異なる振動で終了しないケースもあるので最大256世代まで MOVF GENENO,F ; 0なら256世代目 BTFSS STATUS,Z GOTO GENELOOP ; まだLIMITになっていない。 GOTO FINNEXT ; 次の世代で終了 ; SLEEPWLD CALL CHKIRHEAD ; IR受信確認 BTFSS FLAG,3 ; GOTO SLEEPWLD ; NEWWORLD BCF FLAG,4 ; スローライフモード MOVF GENENO,F ; 1世代経つ前に再度IR受信したらファストライフ BTFSC STATUS,Z BSF FLAG,4 ; ファストライフモード ; ; 新世界の初期世代設定 BCF FLAG,3 ; IR受信フラグクリア CALL CLRDPBUF ; 表示バッファクリア ; CALL CLRPRV ; 前世代クリア CALL SETSEED ; 新世界の初期世代作成 GOTO MAINLOOP ; ;--------------------------------------------------------------------- ; 起動時の世代(LiFE文字) ;--------------------------------------------------------------------- LIFEPTRN MOVLW B'11110000' MOVWF NOWGENE MOVLW B'10000111' MOVWF NOWGENE+1 MOVLW B'00000000' MOVWF NOWGENE+2 MOVLW B'01111100' MOVWF NOWGENE+3 MOVLW B'00010100' MOVWF NOWGENE+4 MOVLW B'00000000' MOVWF NOWGENE+5 MOVLW B'11111000' MOVWF NOWGENE+6 MOVLW B'10101000' MOVWF NOWGENE+7 RETURN ; ;--------------------------------------------------------------------- ; 初期世代をランダムに設定 ;--------------------------------------------------------------------- SETSEED MOVF TMR0,W XORWF STATUS,W MOVWF WK1 MOVLW D'8' MOVWF CNT3 MOVLW NOWGENE MOVWF FSR SETSEED1 RLF WK1,F RLF WK1,F RLF WK1,F MOVF WK1,W XORWF TMR0,W MOVWF WK1 MOVWF INDF INCF FSR,F DECFSZ CNT3,F GOTO SETSEED1 RETURN ; ;--------------------------------------------------------------------- ; 表示用バッファクリア ;--------------------------------------------------------------------- CLRDPBUF MOVLW D'32' MOVWF CNT ; 64バイト分のクリア MOVLW DSPBUF ; W ← DSPBUFの先頭アドレス MOVWF FSR ; FSR にアドレスをセット CLRDPBUF2 CLRF INDF ;(FSR)クリア INCF FSR,F ; DECFSZ CNT,F ; GOTO CLRDPBUF2 RETURN ; ;--------------------------------------------------------------------- ; 現世代クリア ;--------------------------------------------------------------------- CLRNOW CLRF NOWGENE CLRF NOWGENE+1 CLRF NOWGENE+2 CLRF NOWGENE+3 CLRF NOWGENE+4 CLRF NOWGENE+5 CLRF NOWGENE+6 CLRF NOWGENE+7 RETURN ; ;--------------------------------------------------------------------- ; 前世代クリア ;--------------------------------------------------------------------- CLRPRV CLRF PRVGENE CLRF PRVGENE+1 CLRF PRVGENE+2 CLRF PRVGENE+3 CLRF PRVGENE+4 CLRF PRVGENE+5 CLRF PRVGENE+6 CLRF PRVGENE+7 RETURN ; ;--------------------------------------------------------------------- ; 次世代クリア ;--------------------------------------------------------------------- CLRNEXT CLRF NXTGENE CLRF NXTGENE+1 CLRF NXTGENE+2 CLRF NXTGENE+3 CLRF NXTGENE+4 CLRF NXTGENE+5 CLRF NXTGENE+6 CLRF NXTGENE+7 RETURN ; ;--------------------------------------------------------------------- ; Wレジ値をビット位置にデコード ;--------------------------------------------------------------------- DECBIT CLRF PCLATH ADDWF PCL,F DECBIT1 RETLW B'00000001' ;0 RETLW B'00000010' ;1 RETLW B'00000100' ;2 RETLW B'00001000' ;3 RETLW B'00010000' ;4 RETLW B'00100000' ;5 RETLW B'01000000' ;6 RETLW B'10000000' ;7 ; ;--------------------------------------------------------------------- ; 次の世代チェック ;--------------------------------------------------------------------- CHKGENE CALL CLRNEXT ; 次世代テーブルクリア CLRF TARGET ; 0番目のセルから調べる CLRF LIFENO ; 次世代に生きているセル数カウンタ CLRF BORN ; 次世代に生まれる数 CLRF DEATH ; 次世代に死ぬ数 CHKGENE1 CALL CNTLIFE MOVF TARGET,W CALL CHKCELL ; セルが死んでいればZ=1 BTFSS STATUS,Z GOTO ACTCELL ; セルは生きている DEADCELL ; 死んでいるセル MOVF LIFECNT,W SUBLW D'3' BTFSS STATUS,Z ; 周りに3つの生きているセルがあるか? GOTO CHKGENE2 ; 周りに3つの生きているセルがある MOVF TARGET,W CALL SETCELL ; 次の世代で生まれる INCF LIFENO,F INCF BORN,F GOTO CHKGENE2 ; ACTCELL ; 生きているセル BTFSS LIFECNT,1 ; 周りに2つか3つの生きているセルがあるか? GOTO NXTDEATH ; 周りに3つの生きているセルがある MOVF TARGET,W CALL SETCELL ; 次の世代でも生き残る INCF LIFENO,F GOTO CHKGENE2 ; NXTDEATH INCF DEATH,F CHKGENE2 INCF TARGET,F MOVLW D'64' SUBWF TARGET,W BTFSS STATUS,Z GOTO CHKGENE1 RETURN ; ;--------------------------------------------------------------------- ; 現世代の状態を表示バッファにコピー ;--------------------------------------------------------------------- CPYDISP MOVLW D'64' MOVWF CNT CLRF DSPPOS CPYDISP1 MOVF DSPPOS,W CALL CHKCELL BTFSC STATUS,Z ; Z=1なら死んでいるセル GOTO CPYDISP2 ; MOVLW D'11' ; 輝度11を設定 GOTO CPYDISP3 CPYDISP2 MOVLW D'0' ; 輝度0を設定 CPYDISP3 CALL SETDSP ; INCF DSPPOS,F DECFSZ CNT,F GOTO CPYDISP1 RETURN ; ;--------------------------------------------------------------------- ; 前世代と現世代セルの状態を調べ、輝度を設定する。 ; CALLされる都度、輝度をup(生まれるセル)/down(死滅するセル)する。 ; 輝度はBRIGHTで管理。最初はBRIGHT=0。 ;--------------------------------------------------------------------- SETBRT MOVLW D'12' SUBWF BRIGHT,W BTFSC STATUS,Z ; もし12になったら11に戻す DECF BRIGHT,F ; MOVF BRIGHT,W SUBLW D'11' MOVWF BRIGHT2 ; 7-BRIGHT ダウン方向の輝度 MOVLW D'64' ; 64セル分設定する MOVWF CNT CLRF DSPPOS SETBRT1 BCF FLAG,0 BCF FLAG,1 MOVF DSPPOS,W MOVWF WK1 ; ANDLW H'07' ; Wの下位3bitを取り出し、ビット位置確定 MOVWF WK2 ; ビット位置 BCF STATUS,C ; Carry bitをクリア RLF WK1,F ; 左にbit shift(2倍) SWAPF WK1,W ; ニブルスワップで1/16して、元の1/8 ANDLW H'0F' ; Wの下位4bitを取り出し、バイト位置確定 MOVWF WK1 ; 一時保管 ADDLW PRVGENE ; 前世代の先頭アドレスを加算 MOVWF FSR ; FSR にアドレスをセット MOVF WK2,W CALL DECBIT ; デコードしたビットの位置がWで返される MOVWF TMP ; 一時保管 ANDWF INDF,W ; 座標が0ならZフラグが1で返る BTFSS STATUS,Z BSF FLAG,0 ; 前世代は生存(1) ; MOVF WK1,W ADDLW NOWGENE ; 現世代の先頭アドレス加算 MOVWF FSR MOVF TMP,W ; デコード済みのビット位置 ANDWF INDF,W ; 座標が0ならZフラグが1で返る BTFSS STATUS,Z BSF FLAG,1 ; 現世代は生存(1) ; ; 輝度の設定 ; BTFSC FLAG,0 ; '00' 前世代、現世代共に死 GOTO SETBRT11 BTFSC FLAG,1 GOTO SETBRT11 MOVLW D'0' CALL SETDSP GOTO SETBRT3 ; 次のセル ; SETBRT11 BTFSS FLAG,0 ; '11' 前世代、現世代共に生存 GOTO SETBRT01 BTFSS FLAG,1 GOTO SETBRT01 MOVLW D'7' CALL SETDSP GOTO SETBRT3 ; 次のセル ; SETBRT01 BTFSS FLAG,0 ; '01' 死←生への変化 GOTO SETBRT10 ; 次のタイプ MOVF BRIGHT2,W CALL SETDSP ; W座標の輝度を下げる GOTO SETBRT3 ; SETBRT10 ; 生←死への変化 MOVF BRIGHT,W CALL SETDSP ; W座標の輝度を上げる ; SETBRT3 INCF DSPPOS,F DECFSZ CNT,F GOTO SETBRT1 INCF BRIGHT,F RETURN ; ;--------------------------------------------------------------------- ; グラデーションパターンの設定 ;--------------------------------------------------------------------- GRADATION MOVLW D'64' MOVWF CNT CLRF DSPPOS CLRF BRIGHT GRAD1 MOVF BRIGHT,W CALL SETDSP INCF BRIGHT,F INCF DSPPOS,F DECFSZ CNT,F GOTO GRAD1 RETURN ; ;--------------------------------------------------------------------- ; 表示バッファへの設定 ; DSPPOS で指示された座標に輝度データ(W)の値を設定する ; DSPPOS は破壊されない ;--------------------------------------------------------------------- SETDSP MOVWF WK1 ; 輝度情報を待避 BCF STATUS,C ; キャリーをクリア RRF DSPPOS,W ; 座標値を1/2してアドレスを求める ADDLW DSPBUF MOVWF FSR ; FSR にセット ; MOVF INDF,W BTFSC DSPPOS,0 ; 奇数/偶数判断 GOTO SETDSP2 ; ; ANDLW H'70' ANDLW H'F0' MOVWF WK2 MOVF WK1,W ANDLW H'0F' ; ANDLW H'07' GOTO SETDSP3 SETDSP2 ANDLW H'0F' ; ANDLW H'07' MOVWF WK2 SWAPF WK1,W ANDLW H'F0' ; ANDLW H'70' SETDSP3 IORWF WK2,W MOVWF INDF ;(FSR) ← 輝度 RETURN ; ;--------------------------------------------------------------------- ; NOWGENEセルの指定座標の周りを調べる ; 現世代の座標(TARGETで指示された)の周りのフラグを数える ; 結果(0〜8のいずれか)はWに入れて返る ; @AB ; C■D ; EFG ; 7 6 5 4 3 2 1 0 ; +-----------------------+ ; 0 | 7 6 5 4 3 2 1 0| ; 1 |15 14 13 12 11 10 9 8| ; 2 |23 22 21 20 19 18 17 16| ; 3 |31 30 29 28 27 26 25 24| ; 4 |39 38 37 36 35 34 33 32| ; 5 |47 46 45 44 43 42 41 40| ; 6 |55 54 53 52 51 50 49 48| ; 7 |63 62 61 60 59 58 57 56| ; +-----------------------+ ;--------------------------------------------------------------------- CNTLIFE: CLRF LIFECNT ; LIFEカウンタクリア MOVF TARGET,W ; ;@の確認 SUBLW D'7' BTFSC STATUS,C ;7以下なら@ABスキップ GOTO CNTLIFE4 ; MOVLW H'07' ; i%8==7 のときもスキップ ANDWF TARGET,W ; 下位ビットが7ならi%8==7 SUBLW D'7' BTFSC STATUS,Z GOTO CNTLIFE2 ; MOVLW D'7' ; W=TARGET-7 SUBWF TARGET,W ; CALL CHKCELL ; LIFEがないとZは1 BTFSS STATUS,Z INCF LIFECNT,F ; CNTLIFE2 ;Aの確認 MOVLW D'8' ; W=TARGET-8 SUBWF TARGET,W ; CALL CHKCELL ; LIFEがないとZは1 BTFSS STATUS,Z INCF LIFECNT,F ; CNTLIFE3 ;Bの確認 MOVLW H'07' ANDWF TARGET,W ; 上位ビットをマスクして0ならi%8==0 BTFSC STATUS,Z GOTO CNTLIFE4 ; MOVLW D'9' ; W=TARGET-9 SUBWF TARGET,W ; CALL CHKCELL ; LIFEがないとZは1 BTFSS STATUS,Z INCF LIFECNT,F ; CNTLIFE4 ;Cの確認 MOVLW H'07' ; i%8==7 のときはスキップ ANDWF TARGET,W ; 下位ビットが7ならi%8==7 SUBLW D'7' BTFSC STATUS,Z GOTO CNTLIFE5 ; INCF TARGET,W ; W=TARGET+1 CALL CHKCELL ; LIFEがないとZは1 BTFSS STATUS,Z INCF LIFECNT,F ; CNTLIFE5 ;Dの確認 MOVLW H'07' ANDWF TARGET,W ; 上位ビットをマスクして0ならi%8==0 BTFSC STATUS,Z GOTO CNTLIFE6 ; DECF TARGET,W ; W=TARGET-1 CALL CHKCELL ; LIFEがないとZは1 BTFSS STATUS,Z INCF LIFECNT,F ; CNTLIFE6 ;Eの確認 MOVF TARGET,W SUBLW D'55' BTFSS STATUS,C ;55以上ならEFGスキップ RETURN ; MOVLW H'07' ; i%8==7 のときはスキップ ANDWF TARGET,W ; 下位ビットが7ならi%8==7 SUBLW D'7' BTFSC STATUS,Z GOTO CNTLIFE7 ; MOVLW D'9' ADDWF TARGET,W ; W=TARGET+9 CALL CHKCELL ; LIFEがないとZは1 BTFSS STATUS,Z INCF LIFECNT,F ; CNTLIFE7 ;Fの確認 MOVLW D'8' ADDWF TARGET,W ; W=TARGET+8 CALL CHKCELL ; LIFEがないとZは1 BTFSS STATUS,Z INCF LIFECNT,F ; CNTLIFE8 ;Gの確認 MOVLW H'07' ANDWF TARGET,W ; 上位ビットをマスクして0ならi%8==0 BTFSC STATUS,Z RETURN ; MOVLW D'7' ADDWF TARGET,W ; W=TARGET+7 CALL CHKCELL ; LIFEがないとZは1 BTFSS STATUS,Z INCF LIFECNT,F ; RETURN ; ;--------------------------------------------------------------------- ; NOWGENEセルの状態を調べる ; 現世代の座標(Wで指示された)のビットを確認する。 ; 結果はWとZフラグで返る ;--------------------------------------------------------------------- CHKCELL: ; 座標が何バイト目か確認 ; 8で割った商がバイト位置になる。 MOVWF WK1 ; ANDLW H'07' ; Wの下位3bitを取り出し、ビット位置確定 MOVWF WK2 ; ビット位置 BCF STATUS,C ; Carry bitをクリア RLF WK1,F ; 左にbit shift(2倍) SWAPF WK1,W ; ニブルスワップで1/16して、元の1/8 ANDLW H'0F' ; Wの下位4bitを取り出し、バイト位置確定 ADDLW NOWGENE ; 次世代の先頭アドレスを加算 MOVWF FSR ; FSR にアドレスをセット ; MOVF WK2,W CALL DECBIT ; デコードしたビットの位置がWで返される ANDWF INDF,W ; 座標が0ならZフラグが1で返る RETURN ; ;--------------------------------------------------------------------- ; NXTGENEセルへの設定 ; Wで指示された座標のビットを次世代テーブルにセットする。 ; ; NXTGENE ; 7 6 5 4 3 2 1 0 ; +-----------------------+ ; 0 | 7 6 5 4 3 2 1 0| ; 1 |15 14 13 12 11 10 9 8| ; 2 |23 22 21 20 19 18 17 16| ; 3 |31 30 29 28 27 26 25 24| ; 4 |39 38 37 36 35 34 33 32| ; 5 |47 46 45 44 43 42 41 40| ; 6 |55 54 53 52 51 50 49 48| ; 7 |63 62 61 60 59 58 57 56| ; +-----------------------+ ; ;--------------------------------------------------------------------- SETCELL: ; 座標が何バイト目か確認 ; 8で割った商がバイト位置になる。 MOVWF WK1 ; ANDLW H'07' ; Wの下位3bitを取り出し、ビット位置確定 MOVWF WK2 ; ビット位置 BCF STATUS,C ; Carry bitをクリア RLF WK1,F ; 左にbit shift(2倍) SWAPF WK1,W ; ニブルスワップで1/16して、元の1/8 ANDLW H'0F' ; Wの下位4bitを取り出し、バイト位置確定 ADDLW NXTGENE ; 次世代の先頭アドレスを加算 MOVWF FSR ; FSR にアドレスをセット ; MOVF WK2,W CALL DECBIT ; デコードしたビットの位置がWで返される IORWF INDF,F ; (FSR) 番地とBUFF1のORでセット RETURN ; ;--------------------------------------------------------------------- ; 世代のコピー(NXTGENE,NOWGENE→NOWGENE,PRVGENE) ;--------------------------------------------------------------------- CPYGENE: MOVLW D'16' MOVWF CNT3 MOVLW NOWGENE ; 現世代の先頭アドレス MOVWF WK1 MOVLW PRVGENE ; 前世代の先頭アドレス MOVWF WK2 CPYGENE1 MOVF WK1,W MOVWF FSR ; FSR にアドレスをセット ; MOVF INDF,W ; 次世代の8セル分を待避 MOVWF TMP ; ; MOVF WK2,W MOVWF FSR ; FSR にアドレスをセット MOVF TMP,W MOVWF INDF ; 次世代の8セル分をコピー ; INCF WK1,F INCF WK2,F DECFSZ CNT3,F GOTO CPYGENE1 ; ;次世代セルのクリア CLRF NXTGENE ; 次世代の先頭アドレス CLRF NXTGENE+1 CLRF NXTGENE+2 CLRF NXTGENE+3 CLRF NXTGENE+4 CLRF NXTGENE+5 CLRF NXTGENE+6 CLRF NXTGENE+7 RETURN ; ;--------------------------------------------------------------------- ; IRセンサ確認 ; リーダ部を読み取る。正しく読み取れたらFLAG[3]をHIGHにして戻る。 ; (注)正しくリーダ部が読めている訳ではない。 ;--------------------------------------------------------------------- CHKIRHEAD BCF FLAG,3 ; IR受信フラグクリア BTFSC PORTA,4 ; IR受信確認 RETURN ; まだ未受信 ; ; 次にIRがHIGHになったら、1.6msec毎にIRセンサの状態を確認し、バッファに溜める ; BTFSS PORTA,4 ; IR受信確認 GOTO $-1 ; HIGHになるまで待つ MOVLW D'3' ; 3回確認(約5msecかかる) MOVWF IRCNT CLRF IRBUFF ; バッファクリア CHKIRLP CALL WAIT2MS ; 1.6msec待ち BCF STATUS,C ; キャリーフラグクリア BTFSC PORTA,4 ; IR受信確認 BSF STATUS,C ; HIGHならキャリーセット RLF IRBUFF,F ; IRバッファシフト(キャリーがシフトされる) DECFSZ IRCNT,F ; 3回確認 GOTO CHKIRLP ; MOVLW B'00000110' ; リーダの終了パターンとマッチング SUBWF IRBUFF,W ; Zフラグが1なら受信成功 BTFSS STATUS,Z RETURN BSF FLAG,3 ; 受信フラグセット ; MOVLW D'80' ; 連続して読まないように約120msecウエイト MOVWF IRCNT CHKIRLP2 CALL WAIT2MS ; 1.6msec待ち DECFSZ IRCNT,F ; GOTO CHKIRLP2 RETURN ; ;--------------------------------------------------------------------- ; Waitルーチン(注)割り込みがあるので時間通りにならない ;--------------------------------------------------------------------- WAIT1MS ;約0.4msec MOVLW D'1' BTFSS FLAG,4 ; 動作モード (0:ゆっくり、1:速い) MOVLW D'250' MOVWF CNT1 W1MSLP NOP DECFSZ CNT1,F GOTO W1MSLP GOTO $+1 RETURN ; WAIT05S ;0.5秒(500msec) MOVLW D'249' MOVWF CNT2 W05SLP CALL CHKIRHEAD ; IR受信確認 BTFSC FLAG,3 ; 受信していたら即リターン RETURN CALL WAIT1MS DECFSZ CNT2,F GOTO W05SLP NOP RETURN ; WAIT02S ;0.05秒(50msec) MOVLW D'100' MOVWF CNT2 W02SLP CALL CHKIRHEAD ; IR受信確認 BTFSC FLAG,3 ; 受信していたら即リターン RETURN ; CALL WAIT1MS DECFSZ CNT2,F GOTO W02SLP NOP RETURN ; WAIT2MS ; 1.6msec(IR受信用ウェイト) MOVLW D'160' MOVWF CNT1 W2MS GOTO $+1 GOTO $+1 GOTO $+1 NOP DECFSZ CNT1,F GOTO W2MS RETURN ;--------------------------------------------------------------------- END ;--------------------------------------------------------------------- ; 終わり ;---------------------------------------------------------------------