このページではJavaScriptを使用しています。
Home > マイコン実用例 > 電子サイコロ > プログラム内容(その2)
プログラム内容(その2)

サイコロを2つ動かすプログラムです。アドレス8600からプログラムが始まっています。左側からアドレス、マシン語プログラム、アセンプラプログラムの順番で書かれています。

プログラムは、ざっと次の動作をしています。

  • スイッチ1,2を監視。それぞれのLEDに対応させます。
  • スイッチがONで乱数発生、サイコロ目のデータに変換して出力
  • もう1度ONでサイコロを乱数で回転させます。

フラグ類をスイッチ1と2で分けて持ち、それぞれテーブルの先頭をサブルーチンに渡すようにしています。

・プログラムの説明
                        ;**************************
                        ;    サイコロプログラム   *
                        ;      	(その2)        *
                        ;                         *
                        ;**************************
                                                
                        ;---------- ワーキングテーブル
   E000                 RREGL 	EQU 0E000H	;RANDOM REG L
   E001                 RREGH	EQU 0E001H	;RANDOM REG H

   E010                 SW1FLG	EQU 0E010H	;スイッチ1が押されると1
   E011                 SK1STS	EQU 0E011H	;サイコロ1の状態 (回転→1,停止→0)
   E012                 SK1PO	EQU 0E012H	;サイコロ1の出力ポート

   E020                 SW2FLG	EQU 0E020H	;スイッチ2
   E021                 SK2STS 	EQU 0E021H	;サイコロ2       〃
   E022                 SK2PO	EQU 0E022H	;
                        ;---------- I/O テーブル
   0004                 PA 	EQU 04H		;スイッチの入力ポート
   0005                 PB	EQU 05H		;サイコロ1のLED出力ポート
   0006                 PC	EQU 06H		;サイコロ2の  :
   0007                 MODE	EQU 07H		;入出力モードの設定ポート
                        
                        
   8600                 	ORG 8600H	;プログラム開始アドレス
                        
                        ;------ イニシャライズ -------------
   8600   3E 90         PINIT:	LD A,90H	;--- I/O ポートモードセット
   8602   D3 07         	OUT (MODE),A	;PA=IN,PB=OUT,PC=OUT
   8604   3E 01         	LD A,1		;--- ワーキングテーブルイニシャライズ
   8606   32 11 E0      	LD (SK1STS),A	;回転ステータスをセット(ランダム点灯)
   8609   32 21 E0      	LD (SK2STS),A	;
   860C   3E 00         	LD A,0		;
   860E   32 10 E0      	LD (SW1FLG),A	;スイッチOFFをセット
   8611   32 20 E0      	LD (SW2FLG),A	;
   8614   3E 05         	LD A,PB		;出力ポートをメモリにセットしておく
   8616   32 12 E0      	LD (SK1PO),A	;
   8619   3E 06         	LD A,PC		;
   861B   32 22 E0      	LD (SK2PO),A	;
                        
                        ;========== サイコロ メイン ===========
                        
   861E   CD 98 86      MAIN:	CALL TIM	;チャタリング防止の待ち時間
   8621   CD 61 86      	CALL INPTA	;データをポートから入力
   8624   CB 72         	BIT 6,D		;データのBIT6を調べる
   8626   21 10 E0      	LD HL,SW1FLG	;  サイコロ1テーブルをセット
   8629   D5            	PUSH DE		;
   862A   28 02         	JR Z,SW1ON	;
   862C   36 01         	LD (HL),1	;1なら(スイッチ1が押されたら)SW1FLGを1にする
   862E   CC 6B 86      SW1ON:	CALL Z,SKSTP	;0なら 停止サブルーチンへ
   8631   D1            SW2CHK:	POP DE	
   8632   CB 7A         	BIT 7,D		;入力データのBIT7を調べる
   8634   21 20 E0      	LD HL,SW2FLG	;  サイコロ1テーブルをセット
   8637   28 02         	JR Z,SW2ON	;
   8639   36 01         	LD (HL),1	;1なら(スイッチ2が押されたら)SW2FLGを1にする
   863B   CC 6B 86      SW2ON:	CALL Z,SKSTP	;0なら 停止サブルーチンへ
                        
   863E   3A 11 E0      KORO:	LD A,(SK1STS)	;----サイコロ1のフラグチェック
   8641   FE 00         	CP 0
   8643   CA 4E 86      	JP Z,KORO2	;1→LEDランダム点灯,0→サイコロ2へ
   8646   CD A1 86      	CALL RDM	;乱数ルーチン(1~6)
   8649   CD 87 86      	CALL KOROME	;サイコロデータに変換
   864C   D3 05         	OUT (PB),A	;サイコロデータをポートBへOUT
   864E   3A 21 E0      KORO2:	LD A,(SK2STS)	;----サイコロ2のフラグチェック
   8651   FE 00         	CP 0
   8653   CA 1E 86      	JP Z,MAIN	;1→LEDランダム点灯,0→MAINへ
   8656   CD A1 86      	CALL RDM	;乱数ルーチン(1~6)
   8659   CD 87 86      	CALL KOROME	;サイコロデータに変換
   865C   D3 06         	OUT (PC),A	;サイコロデータをポートCへOUT
   865E   C3 1E 86      	JP MAIN
                        
                        ;==================== サブルーチン====================================
                        ;--------データ入力--------------------------------------------
   8661   DB 04         INPTA:	IN A,(PA)	;ポートAのデータをAレジスタに読み込む
   8663   57            	LD D,A
   8664   DB 04         	IN A,(PA)	;正確なデータをとる為2度読みをする
   8666   BA            	CP D		;最初に読み込んだデータと比較する
   8667   C2 61 86      	JP NZ,INPTA	;違っていたら再チェック
   866A   C9            	RET
                        
                        ;-------スイッチONからOFFになったときサイコロ止める-----------
   866B   7E            SKSTP:	LD A,(HL)	;スイッチフラグ(SWFLG)を調べる
   866C   FE 00         	CP 0		;
   866E   C8            	RET Z		;0ならリターン(スイッチ押されてない)
   866F   36 00         	LD (HL),0	;SWFLGをクリア
   8671   23            	INC HL		;
   8672   7E            	LD A,(HL)	;サイコロの状態フラグ(SKSTS)を調べる
   8673   FE 00         	CP 0            ;
   8675   36 01         	LD (HL),1	;0ならSKSTSを1 (回転)にしてリターン
   8677   C8            	RET Z           ;
   8678   36 00         	LD (HL),0	;1ならSKSTSを0にする
   867A   23            	INC HL		;
   867B   E5            	PUSH HL		;ポートの入っているアドレスをセーブ
   867C   CD A1 86      	CALL RDM	;ランダムデータルーチン
   867F   CD 87 86      	CALL KOROME	;サイコロ変換ルーチン
   8682   E1            	POP HL		;
   8683   4E            	LD C,(HL)	;
   8684   ED 79         	OUT (C),A	;指定のポートに出力
   8686   C9            	RET
                        
                        ;---------- データをサイコロに変換 ----------
                        ;数字をAにセットしてコールする
   8687   21 91 86      KOROME:	LD HL,SKTABL
   868A   3D            LOOP:	DEC A
   868B   23            	INC HL
   868C   C2 8A 86      	JP NZ,LOOP
   868F   7E            	LD A,(HL)
   8690   C9            	RET
                        
   8691                 SKTABL
   8691   00 08 41 49   	DB 00H,08H,41H,49H,55H,5DH,77H	 ;--サイコロデータ --
   8695   55 5D 77      
                        
                        ;---------- タイマールーチン ----------
   8698   21 00 10      TIM:	LD HL,1000H
   869B   2B            TLP:	DEC HL
   869C   7C            	LD A,H
   869D   B5            	OR L
   869E   C8            	RET Z
   869F   18 FA         	JR TLP
                        	
                        ;---------- 乱数 ----------------------
   86A1   CD B4 86      RDM:	CALL RDMGEN	;乱数発生ルーチン
   86A4   3A 01 E0      	LD A,(RREGH)
   86A7   E6 07         	AND 7		;下3ビットをとる	
   86A9   FE 07         	CP 7		;7,0をはねる
   86AB   CA A1 86      	JP Z,RDM
   86AE   FE 00         	CP 0
   86B0   CA A1 86      	JP Z,RDM
   86B3   C9            	RET
                        
                        ;----------  RANDOM GENERATOR ----------
   86B4   3A 01 E0      RDMGEN:	LD A,(RREGH)	;以下、乱数発生ルーチン
   86B7   A7            	AND A		;(M系列)
   86B8   28 1D         	JR Z,INITLD
   86BA   67            	LD H,A
   86BB   CB 07         	RLC A		;5ビット左シフト
   86BD   CB 07         	RLC A
   86BF   CB 07         	RLC A
   86C1   CB 07         	RLC A
   86C3   CB 07         	RLC A
   86C5   AC            	XOR H		;ビット2と7のXORをとる
   86C6   E6 80         	AND 80H		;
   86C8   F5            	PUSH AF
   86C9   3A 00 E0      	LD A,(RREGL)	;
   86CC   17            	RLA		;ビット7→キャリーへ
   86CD   7C            	LD A,H
   86CE   17            	RLA		;データシフト キャリー→ビット0
   86CF   32 01 E0      	LD (RREGH),A
   86D2   F1            	POP AF
   86D3   32 00 E0      	LD (RREGL),A	;次の入力をビット7に保存
   86D6   C9            	RET
                        
   86D7   3E FF         INITLD:	LD A,0FFH
   86D9   32 01 E0      	LD (RREGH),A
   86DC   18 D6         	JR RDMGEN
                        
   86DE                 	END