Системный счетчик 8254, который вырабатывает прерывание int 8h - чтобы точно все поняли о чем идет речь.
Надо по нажатию клавиши выдавать звуковой сигнал. Я это делаю через канал 2 счетчика, запрограммированного в 3 режим на нужную частоту (примерно 100Гц).
Что-то работает не так как я хочу. Не включается динамик при отладке и при запуске проги. Процедура Delay при отладке повела себя должным образом. Запускаю под виртуалкой Windows XP, компилятор TASM, отладчик тот же.
;=================
; Beep
;===================
Bdeni proc
push ax
; programming timer for channel 2
;manage string: SC RW M BCD настраиваем на чтение/запись второй канал
mov al, 10 11 011 0b
out timer_MR,al ; send to chan
mov ax,1193 ; 100 Hz
out timer_channel_2,al
mov al,ah
out timer_channel_2,al
; turning on loudspeaker
in al,loudspeaker_MR
or al,03h ; last two bytes is 1 for channel 2 and for loudspk
out loudspeaker_MR, al
; delay for not intermediate off of ldspk
call delay
; turning off loudspeaker
in al,loudspeaker_MR
add al,11111100b ; last two bytes is 1 for channel 2 and for loudspk
out loudspeaker_MR, al
pop ax
ret
Bdeni endp
;=====================
; work with channel 0
;=====================
delay proc
push ax
push bx
call ReadOL_ch0 ; read timer in channel 0
mov bx,ax ; old val to bx
Delay1:
call ReadOL_ch0
cmp bx,ax
jg CMP1
jz Delay1
jb CMP2
CMP1: ; old > new
sub bx,ax
cmp bx,loudspeaker_lngt
jae end1
jmp Delay1
CMP2: ; old < new
sub bx,ax
neg bx
cmp bx,loudspeaker_lngt
jb Delay1
end1:
pop bx
pop ax
ret
delay endp
;================================
; Read Ol of channel0
; output - ax
;=================================
ReadOL_ch0 proc
mov al, 11 00 100 0b ; rbc for reading CE channel0
out timer_MR,al
mov al, 00 00 000 0b ; manage str for read OL without interrupt ticking of timer
out timer_MR,al
xor ax,ax
in al,timer_channel_0 ; young byte
xchg ah,al ; rem young byte
in al,timer_channel_0 ; old byte
xchg al,ah ; make proper number
ret
ReadOL_ch0 endp
В нажатиях клавиш я уверен, но если что :
main:
call ClearScreen
call ReadImr
mov al,imr
call ByteToHex
lea dx,buffer
call PrintStr_bios
call BlockKeyboard
lea dx,blockmsg
call PrintStr_bios
lea dx,endl
call PrintStr_bios
waiting:
mov al,0Ah ; irr read command
out 20h,al
; nop
in al,20h ; read irr
; nop
and al,00000010b ; analizing irr. zero if there isn't any active
jz waiting
xor ax,ax
in al,60h ; get byte-code of pushing key
and al,01111111b ; get rid of first byte (press/release button)
call ByteToHex
lea dx,buffer
call PrintStr_bios
call Bdeni
cmp al,01h ; esc was pushed
je progover
call UnblockKeybooard
; pause for clear stdout
mov ah,00h
int 16h
jmp main
progover:
lea dx,endmsg
call PrintStr_bios
call UnblockKeybooard
; pause
mov ah, 00h
int 16h
ret ; return to 000h on int 20h
Байты в директивах мов разбиты для удобства чтения.