サイコロを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 |