📄 ex10_1.asm
字号:
; Ex10_1.asm
;
; Software that plays Musical notes.
; Intended for use with Chapter 10 Laboratory Experiments
.xlist
include stdlib.a
includelib stdlib.lib
.list
; Hardware related equates
PPI_B equ 61h ;8255 port B address
PIT_Ch2 equ 42h ;Timer channel 2 address
PIT_CW equ 43h ;Timer control word address.
RTC textequ <es:[6ch]> ;Real Time clock writes here.
; The following macros program the 8254 timer chip to play a
; note or a rest.
Note macro frequency, duration
mov ax, frequency
mov cx, duration
call PlayNote
endm
Rest macro Duration
local RestLoop
;; Turn off the speaker.
in al, PPI_B
and al, 0FCh
out PPI_B, al
mov cx, Duration
RestLoop: call Delay18
loop RestLoop
endm
dseg segment para public 'data'
; See Delay18.asm for details about the following variables.
TimedValue word 0
RTC2 word 0
; DivisorConst is the constant that, when divided by a desired frequency
; produces the divisor constant to feed into the timer chip to produce
; a tone of the given frequency.
DivisorConst dword 1193180
dseg ends
;********************************************************
cseg segment para public 'code'
assume cs:cseg, ds:dseg
; Delay- This routine delays for approximately 1/18th second.
; See the Delay18.asm file for comments about this code.
Delay18 proc near
push ds
push es
push ax
push bx
push cx
push dx
push si
mov ax, dseg
mov es, ax
mov ds, ax
mov cx, TimedValue
mov si, es:RTC2
mov dx, PPI_B
align 4
TimeRTC: mov bx, 50
align 4
DelayLp: dec bx
jne DelayLp
cmp si, es:RTC2
loope TimeRTC
pop si
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
ret
Delay18 endp
; DelayInit- Computes the timing constant for the Delay18 routine
; by watching when the RTC code updates the RTC variable.
DelayInit proc
push es
push ax
push bx
push cx
push dx
push si
mov ax, 40h
mov es, ax
mov ax, RTC
RTCMustChange: cmp ax, RTC
je RTCMustChange
mov cx, 0
mov si, RTC
mov dx, PPI_B
align 4
TimeRTC: mov bx, 50
align 4
DelayLp: dec bx
jne DelayLp
cmp si, RTC
loope TimeRTC
neg cx ;CX counted down!
shl cx, 1 ;Increase delay time.
mov TimedValue, cx ;Save away
pop si
pop dx
pop cx
pop bx
pop ax
pop es
ret
DelayInit endp
; PlayNote- This procedure programs the 8254 timer chip to play a given
; note (frequency is passed in AX) for a given duration (passed
; in cx).
PlayNote proc
push dx
push cx
push ax
; Turn on the speaker.
in al, PPI_B
or al, 3
out PPI_B, al
; Tell the chip we want to program it with a new 16-bit divisor value.
mov al, 0B6h ;Magic value to program chip.
out PIT_CW, al
; Convert the frequency to a divisor constant.
pop cx ;Get the frequency.
mov dx, word ptr DivisorConst+2
mov ax, word ptr DivisorConst
div cx
out PIT_Ch2, al
xchg al, ah
out PIT_Ch2, al
mov ax, cx ;Restore original AX value.
pop cx ;Retrieve duration
mov dx, cx ;Save Duration.
DelayLp: call Delay18
loop DelayLp
mov cx, dx ;Restore original CX value
pop dx ;Restore original DX value.
ret
PlayNote endp
; Main program which tests out the DELAY subroutine.
Main proc
mov ax, dseg
mov ds, ax
mov es, ax
call DelayInit
; Play "Amazing Grace"
note 294, 4
note 392, 8
note 494, 2
note 392, 2
note 494, 8
note 440, 4
note 392, 8
note 330, 4
note 294, 8
rest 2
note 294, 4
note 392, 8
note 494, 2
note 392, 2
note 494, 8
note 440, 4
note 587, 16
note 494, 4
note 587, 4
note 494, 2
note 587, 2
note 494, 2
note 392, 8
note 294, 4
note 330, 4
note 392, 2
rest 2
note 392, 2
note 330, 2
note 294, 8
rest 2
note 294, 4
note 392, 8
note 494, 2
note 392, 2
note 494, 8
note 440, 4
note 392, 16
rest 1
Quit: ExitPgm ;DOS macro to quit program.
Main endp
cseg ends
sseg segment para stack 'stack'
stk dw 1024 dup (0)
sseg ends
end Main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -