Затея вот в чем: со времен начала Виндовса, когда M$ стала мешать людям работать с портами
напрямую, пишу я вот такую подвиндовую программку:
beep3xx.gif
Это просто настройка канала 2 таймера
8254 на извлечение звука частотой ~
440 Hz.
Приложение 16-разрядное, лезет в порты само через
IN PORT и
OUT PORT.
И я нигде не слышал, что извлечение звука из канала 2 таймера как-то вредило Венде.
Эта программулька нормально работает под Вендами 3.хх, 95, 98, Ме. А вот под ХР - уже
с переменным успехом.
У неё есть под-ДОС-овский прототип
BEEPER.ASM:
Code: Select all
SEG_A SEGMENT BYTE PUBLIC
ASSUME CS:SEG_A, DS:SEG_A
ORG 100h
BEEPER PROC FAR
START:
JMP LOC_0021
TONE_HIGH DW 4A6H;854H ;1.190.000/1000=1200Гц (делитель 3DFH)
TONE_LOW DW 4A6H;0A90H ;1.190.000/3000=440Гц (делитель)
DATA_0010 DB 01H ; пpизнак совпадения и пеpеключения
DATA_0012 DB 'BEEPER: press any key to stop & exit!',00H
BEEPER ENDP
LOC_0021:
MOV AX,0F00H; узнаем pежим
INT 10H
PUSH BX ; сохpаним стpаницу
XOR BX,BX; очистить окно
MOV CX,BX; pазмеpами:
MOV BH,07H; аттpибут
MOV DH,24; 25 стpок на
MOV DL,AH; AH столбцов
MOV AX,0600H
INT 10H
POP BX ; восстановим стpаницу
XOR DX,DX ; <- веpхний угол
MOV AX,0200H
INT 10H ; установим куpсоp
MOV BX,OFFSET DATA_0012
LOC_0020:
MOV AL,CS:[BX]
OR AL,AL
JZ LOC_0022
MOV AH,0EH; записать символ из AL
INT 10H
INC BX
JMP LOC_0020
LOC_0022:
CALL PUT_BEEP
MOV AX,0101H
INT 16H
JZ LOC_0022
; INT 20H
MOV AX,4C05H
INT 21H ;Выход с ошибкой 5
;____________________________ Генеpация звука ________________________________
PUT_BEEP PROC NEAR
PUSH AX
MOV AX,CS:TONE_HIGH ;=880Гц (делитель)
NEG CS:DATA_0010 ; пеpеключатель ?
JL LOC_0011 ; Jump if <
MOV AX,CS:TONE_LOW ;=440Гц (делитель)
JMP SHORT LOC_0011
LOC_0011:
CALL LOCK_BEEP
POP AX
RET
PUT_BEEP ENDP
;---------------------------- Вывод звука -----------------------------------
LOCK_BEEP PROC NEAR
;________________________________ Настpоим таймеp ___________________________
PUSH DX
PUSH AX ; AX - делитель сохpаним
MOV AL,0B6H; = 1011.0110b - в pегистp команд
; L+L+ L+-L--- код двоичный
; ¦ ¦ L----- 011 - pежим 3 - генеp.меандpа
; ¦ L-------- 11 - мл.байт, ст.байт
; L---------- 10 - канал 2
MOV DX,0043H
OUT DX,AL ; port 43H, 8253 wrt timr mode
JMP SHORT $+2
POP AX ; AX - делитель восстановим
;----------------------------------------------------------------------------
MOV DX,0042H
OUT DX,AL ; port 42H, 8253 timer 2 spkr
JMP SHORT $+2
MOV AL,AH
OUT DX,AL ; port 42H, 8253 timer 2 spkr
JMP SHORT $+2
;________________________________ Включение звука ____________________________
IN AL,61H ; port 61H, 8255 port B, read
JMP SHORT $+2
OR AL,03H; = 0000.0011b - установили 2 младших бита
; ¦L----- бит 0 = 1 включить таймеp(2)
; L------ бит 1 = 1 включить динамик
OUT 61H,AL; port 61H, 8255 B - spkr, etc
JMP SHORT $+2
;______________________ Фоpмиpуем задеpжку чеpез пpеpывание __________________
PUSH BX
PUSH DX
MOV BX,0004H ; задеpжка 2x 1/18 cек = 0.22 c
XOR AX,AX ; функция чтения счетчка
INT 1AH ; получим значение в [DX}
ADD BX,DX
LOC_0013:
INT 1AH ; получим значение в [DX]
CMP DX,BX
JC LOC_0013 ; Jump if not zero
POP DX
POP BX
;________________________________ Выключение звука ___________________________
IN AL,61H ; port 61H, 8255 port B, read
JMP SHORT $+2
AND AL,0FCH; = 1111.1100b - сбpосили 2 младших бита
; ¦L---- бит 0 = 0 выключить таймеp(2)
; L----- бит 1 = 0 выключить динамик
OUT 61H,AL ; port 61H, 8255 B - spkr, etc
JMP SHORT $+2
POP DX
RET
LOCK_BEEP ENDP
;-----------------------------------------------------------------------------
SEG_A ENDS
END START
Он тоже нормально работает под Вендами 3.хх, 95, 98, Ме порой и под ХР ...
Позже я написал еще один подВиндовый вариант, который использует
dll-библиотеку
portio.dll
beep98.gif
Он успешно работает под Вендами 3.хх, 95, 98, Ме и под ХР ...
Пробовал я вчера все три варианта под
Windows 7:
Самый первый вариант работает, не падает, но издает полную тишину!
Последний вариант через библиотеку
portio.dll - тоже издает полную тишину.
Я как администратор на своем ноутбуке зарегистрировал новые библиотеки
ntport.dll и
zntport.sys.
Адаптировал программу под них, программа работает, но звука таймера нет.
А вот с ДОС-овским вариантом вышло интересно!
Во-первых, он очень поганно, но звучит в ДОС-бокс. Это странно - таймер-то "железка" и звук
должен быть ровный, но кажается, что в ДОС-бокс таймер эмулируют софтверно через звуковую
карту. Звучит с подвываниями и "федингами".
Но самое потрясающее происходит при запуске ДОС-программы прямо под
Windows 7:
при запуске она молчит, а вот после её выключения
Windows 7 начинает издавать якобы
"звук таймера"!
Ощущение - как будто Венда записала звук в файл и теперь проигрывает его!
Звук прекращается при повторном запуске этой ДОС-программы.
Вот такие опыты с невинным, казалось бы, портом 2 таймера
8254 под
Windows 7.
P.S. Почитал про порты под Windows 7 какую-то неубедительную бредятину здесь:
Открытие портов ввода/вывода в Windows 7.
P.P.S. А вот здесь про работу с портами под Windows 7 расписали, пожалуй, поумнее:
ПРОГРАММИРОВАНИЕ УСТРОЙСТВ ВВОДА-ВЫВОДА
You do not have the required permissions to view the files attached to this post.