サイコロを2つ動かすプログラムです。アドレス8600からプログラムが始まっています。左側からアドレス、マシン語プログラム、アセンプラプログラムの順番で書かれています。
プログラムは、ざっと次の動作をしています。
フラグ類をスイッチ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
|