编写汇编程序,使PC嗡鸣器按乐谱发声

来源:互联网 发布:淘宝卖家店铺头像图片 编辑:程序博客网 时间:2024/04/28 12:09

              DATA  SEGMENT
    MUS_FREQ  DW        330,392,330,294,330,392,330,294,330
              DW        330,392,330,294,262,294,330,392,294
              DW        262,262,220,196,196,220,262,294,330,262
              DW        -1
    MUS_TIME  DW        3 DUP (5000),2500,2500,5000,2500,2500,10000
              DW        2 DUP (5000,5000,2500,2500),10000
              DW        3 DUP (5000,2500,2500),10000
        DATA  ENDS
        STCK  SEGMENT
         STK  DB        200  DUP(?)
         TOP  EQU       LENGTH  STK
        STCK  ENDS

        CODE  SEGMENT
              ASSUME    DS:DATA, SS:STCK, CS:CODE
      START:  MOV       AX,DATA
              MOV       DS,AX
              MOV       AX,STCK
              MOV       SS,AX
              MOV       AX,TOP
              MOV       SP,AX
              LEA       SI, MUS_FREQ
                  ;SI?频率表首地址
              LEA       BP,DS: MUS_TIME
                  ;BP?音长表首地址
      FREG1:  MOV       DI,[SI]
                  ;当前音符的频率?DI
              CMP       DI,-1
                  ;判断是否是结束符号
              JE        END_MUS1
                  ;结束符,转到END_MUS1
              MOV       BX,DS:[BP]
                  ;当前音符的音长?BX
              CALL      GENSOUND
                  ;调用发声子程序
              ADD       SI,2
              ADD       BP,2
                  ;SI和BP分别指向下一个音
                  ;符的频率和音长
              JMP       FREG1
                  ;转到FREG1,继续发声
    GENSOUND  PROC      NEAR
              PUSH      AX
              PUSH      BX
              PUSH      CX
              PUSH      DX
              PUSH      DI
              MOV       AL,0B6H
              OUT       43H,AL      ;设置8253方式3
              MOV       DX,12H
              MOV       AX,3280H
              DIV       DI          ;计算计数初值
              OUT       42H,AL
              MOV       AL,AH
              OUT       42H,AL      ;向定时器2写入计数值
              IN        AL,61H
              MOV       AH,AL
              OR        AL,3
              OUT       61H,AL
       ;使PB0和PB1输出1,其余PB口不变
       ;启动发声
      WAIT1:  MOV       CX,22480
     DELAY1:  LOOP      DELAY1
              DEC       BX
              JNZ       WAIT1       ;延时,控制音长
              MOV       AL,AH
              OUT       61H,AL
        ;PB0=PB1=0,关定时器和扬声器
              POP       DI
              POP       DX
              POP       CX
              POP       BX
              POP       AX
              RET
    GENSOUND  ENDP
   END_MUS1:  NOP
              MOV       AH,4CH
              INT       21H
                 ;程序结束
        CODE  ENDS
              END       START