;
; 自動演奏  教科書 p34
;
; これがKz80の限界です。
; 実機とかなり音が違うはずです。
; kz80で演奏するときは、周波数を二万ぐらいにして、実行してください。
; プログラム中で、補正を加えることで、なんとかKZ80でも音楽を聞けるようにしてい
; ます。ちなみに KZ80の 0FFFEHには 0FEHが必ず入っています。
; あと、パソコンの速さにより、音が違います。よって、FMV450NL/S以外で実行する
; ときは、プログラムを調整してください。
;
        ORG     8000H
        ; KZ80かの判定
        LDA     0FFFEH
        CPI     0FEH
        JNZ     J2
        ; KZ80である
        ; テンポカウンターを 1/9にする
        LXI     H,19FFH/9
        SHLD    SOUND+1
        ; 音程データをいじる
        LXI     H,1FA7H ; ana a -> a7h
                        ; rar   -> 1fh
        SHLD    ST1
        SHLD    ST1+2
J2:
        ;
        MVI     A,90H
        OUT     CWR1
        OUT     CWR2
        MVI     A,04H
        OUT     PORTC1
        
MAIN:   LXI     H,MUSIC ; 音楽データ
MAIN1:  MOV     A,M     ; 音程
        CPI     0FFH
        JZ      J1
        ANA     A
        JZ      MAIN
        
ST1:    NOP
        NOP
        NOP
        NOP
        
        ; KZ80用
        JNZ     J1
        MVI     A,1
J1:
        MOV     B,A ; 音程
        ; 音長データ読みだし
        INX     H
        MOV     C,M

        ; 音を演奏する
MAIN2:  PUSH    H
        CALL    SOUND
        POP     H
        ; 音長カウンター減算
        DCR     C
        JNZ     MAIN2
        ; 次のデータへ
        INX     H
        JMP     MAIN1
        ; テンポの設定
SOUND:  LXI     H,19FFH
SOUND1: MOV     D,B             ; 音程
        ; 音程が0FFHかのチェック
        ; 休符かのチェック
        MOV     A,B
        INR     A
        JZ      SOUND2
        ; 音の発生&ウエイト
        MVI     A,0FH
        CALL    COUNT
        ; 音のOFF&ウエイト
        MOV     D,B
SOUND2: MVI     A,0EH
        CALL    COUNT
        JMP     SOUND1
        ; 音の発生＆OFF&ウエイト
COUNT:  OUT     CWR1        ; A に出力データが入る
        ;
COUNT1: DCX     H       ; テンポカウンター
        MOV     A,H
        ANA     A       ; テンポカウンターの上位が0になるまでループ
        JZ      COUNT2
        DCR     D       ; 音程カウンター減算
        JNZ     COUNT1
        RET
        ; Main2の付近までに戻る
COUNT2: POP     D   ; スタックの調整
        RET
        
PORTC1  EQU     0F2H
CWR1    EQU     0F3H
CWR2    EQU     0F7H

        ORG     8D00H
        
MUSIC:  DB      21H,4,21H,2,25H,2
        DB      2AH,2,25H,2,2AH,2
        DB      2CH,2,32H,4,32H,4
        DB      32H,8,1FH,4,1FH,2
        DB      21H,2,25H,2,2AH,2
        DB      25H,2,1FH,2,21H,16
        DB      1FH,4,1FH,2,21H,2
        DB      25H,4,25H,2,1FH,2
        DB      21H,4,21H,2,2AH,2
        DB      32H,8,2CH,4,21H,4
        DB      25H,2,2AH,2,2CH,2
        DB      2AH,2,32H,16,0FFH,4
        DB      0
        
        END
