8253定时计数器演奏音乐

  1 ; 8253定时计数器演奏音乐
  2 
  3 ; 8253定时计数器T2输出用于音频驱动  演奏《一闪一闪亮晶晶》
  4 
  5 ; (A9)CS    -- (B8)300
  6 ; (A12)Φ   -- (A11)1A  ;输入4.9152MHz
  7 ; (A9)CLK2  -- (A11)1QD ;输出307.2KHz
  8 ; (A9)GATE2 -- (A10)+5V
  9 ; (A9)OUT2  -- 上板喇叭
 10 
 11 CS8253  EQU 0303H       ;8253端口地址
 12 TCON2   EQU 0302H       ;8253的通道2端口地址
 13 TCON1   EQU 0301H       ;8253的通道1端口地址
 14 TCON0   EQU 0300H       ;8253的通道0端口地址
 15 
 16 data segment
 17   state DB 3
 18 ;音符数据
 19 TFREQ   DW 264,264,396,396,440,440,396   ; 1 1 5 5 6 6 5
 20         DW 352,352,330,330,297,297,264   ; 4 4 3 3 2 2 1
 21         DW 396,396,352,352,330,330,297   ; 5 5 4 4 3 3 2
 22         DW 396,396,352,352,330,330,297   ; 5 5 4 4 3 3 2
 23         DW 264,264,396,396,440,440,396   ; 1 1 5 5 6 6 5
 24         DW 352,352,330,330,297,297,264,0 ; 4 4 3 3 2 2 1
 25 
 26 ;节拍数据
 27 TDLY    DW 6000,6000,6000,6000,6000,6000,12000
 28         DW 6000,6000,6000,6000,6000,6000,12000
 29         DW 6000,6000,6000,6000,6000,6000,12000
 30         DW 6000,6000,6000,6000,6000,6000,12000
 31         DW 6000,6000,6000,6000,6000,6000,12000
 32         DW 6000,6000,6000,6000,6000,6000,12000
 33 
 34 data ends
 35 
 36 CODE    SEGMENT
 37         ASSUME CS:CODE, ds:data
 38 
 39 START:  mov ax, data
 40         mov ds, ax
 41         
 42 restart:
 43         MOV SI,OFFSET TFREQ
 44         MOV BX,OFFSET TDLY
 45         
 46 FREQ:   MOV DI,[SI]
 47         CMP DI,0
 48         ;JE START
 49         je next
 50         
 51         CALL SOUND
 52         ADD SI, 2        ;转到下一个音符
 53         ADD BX, 2        ;转到下一个节拍
 54         JMP FREQ
 55 
 56 SOUND:  MOV DX,CS8253   ;8253初始化
 57         MOV AL,0B6H
 58         OUT DX,AL
 59         MOV DX,2
 60         MOV AX,307      ;307.2KHz
 61         DIV DI
 62         MOV DX,TCON2
 63         OUT DX,AL
 64         MOV AL,AH
 65         OUT DX,AL
 66 
 67         MOV AX,[BX]
 68 
 69         
 70 SLOOP:  MOV CX,0018H    ;延时子程序
 71         LOOP $
 72 
 73         DEC AX
 74         JNZ SLOOP
 75         RET
 76         
 77    next:;mov cx, word ptr [state]
 78         mov dl, state
 79         dec dl
 80         mov state, dl
 81         
 82         cmp dl, 0
 83         je stop
 84         jmp restart
 85         
 86    stop:mov ah, 4ch
 87         int 21h
 88 
 89 CODE    ENDS
 90         END START
 91 
 92 ******************************************************
 93 
 94 ; 8253定时计数器演奏音乐
 95 
 96 ; 8253定时计数器T2输出用于音频驱动  演奏《一闪一闪亮晶晶》
 97 
 98 ; (A9)CS    -- (B8)300
 99 ; (A12)Φ   -- (A11)1A  ;输入4.9152MHz
100 ; (A9)CLK2  -- (A11)1QD ;输出307.2KHz
101 ; (A9)GATE2 -- (A10)+5V
102 ; (A9)OUT2  -- 上板喇叭
103 
104 data segment
105   state DB 3
106 ;音符数据
107 TFREQ   DW 264,264,396,396,440,440,396   ; 1 1 5 5 6 6 5
108         DW 352,352,330,330,297,297,264   ; 4 4 3 3 2 2 1
109         DW 396,396,352,352,330,330,297   ; 5 5 4 4 3 3 2
110         DW 396,396,352,352,330,330,297   ; 5 5 4 4 3 3 2
111         DW 264,264,396,396,440,440,396   ; 1 1 5 5 6 6 5
112         DW 352,352,330,330,297,297,264,0 ; 4 4 3 3 2 2 1
113 
114 ;节拍数据
115 TDLY    DW 6000,6000,6000,6000,6000,6000,12000
116         DW 6000,6000,6000,6000,6000,6000,12000
117         DW 6000,6000,6000,6000,6000,6000,12000
118         DW 6000,6000,6000,6000,6000,6000,12000
119         DW 6000,6000,6000,6000,6000,6000,12000
120         DW 6000,6000,6000,6000,6000,6000,12000
121 
122 data ends
123 
124 CODE    SEGMENT
125 ASSUME CS:CODE, ds:data
126 
127 START:  mov ax, data
128         mov ds, ax
129 
130 restart:
131         MOV SI,OFFSET TFREQ ;置地址指针
132         MOV BX,OFFSET TDLY
133 
134 FREQ:   MOV DI,[SI]  ;寄存器间接寻址
135         CMP DI,0     ;0是音符表的终止标志
136         je next      ;如果DI=0 表明已经结束一次播放 跳转到next
137 
138         CALL SOUND   ;段内间接调用子程序sound
139         
140         ADD SI, 2        ;转到下一个音符
141         ADD BX, 2        ;转到下一个节拍
142         JMP FREQ         ;处理发声当前这个音符
143 
144 SOUND:  MOV DX, 303H
145         MOV AL,10110110B
146         OUT DX,AL     ;8253初始化 送控制字
147         
148         MOV DX,2   ;进行的是字运算
149         MOV AX,307    ;307.2KHz
150         DIV DI     ;(dx:ax)/di 结果存到ax
151         
152         MOV DX, 302H  ;端口2
153         OUT DX,AL  ;计算计数初值
154         MOV AL,AH  ;分高低8位写计数初值
155         OUT DX,AL
156 
157         MOV AX,[BX] ;取节拍数字
158 
159 
160 SLOOP:  MOV CX,0018H    ;延时子程序
161         LOOP $   ;执行一条loop指令需要17个时钟周期
162 
163         DEC AX  ;控制节拍数
164         JNZ SLOOP
165         RET
166 
167    next:
168         mov dl, state  ;取内存中的state的值
169         dec dl         ;自减
170         mov state, dl  ;更新state
171 
172         cmp dl, 0
173         je stop       ;若dl=0 表明循环次数已够 转去执行stop
174         jmp restart   ;否则转去执行restart
175 
176    stop:mov ah, 4ch   ;返回DOS结束
177         int 21h
178 
179 CODE    ENDS
180         END START
原文地址:https://www.cnblogs.com/yspworld/p/6440982.html