IPB
ЛогинПароль:

> ПРАВИЛА РАЗДЕЛА!!!

1. Заголовок или название темы должно быть информативным
2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE]
3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора.
5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM!
6. Проверяйте программы перед тем, как выложить их на форум!!

 
 Ответить  Открыть новую тему 
> Мелодия системного динамика, Все о системном динамике
сообщение
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 69
Пол: Мужской

Репутация: -  3  +


Здравствуйте, уважаемые.

Есть задача:

Написать программу исполняющую на системном динамике песню про веселых гусей.

К сожалению, я пока не обладаю соответствующими навыками в программировании на ассемблере, но был бы очень признателен людям, которые откликнулись бы на эту тему и написали все что знаю о системном динамике, как к нему обращаться и работать. Как завершение этой темы, общими усилиями, хотелось бы написать процедуру биликанья динамика, т. е. в соответствии от введенной цифры он биликал бы соответствующую ноту. Вот.

Заранее благодарен тем, кто откликнется.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Для начала - одна нота:
.8086
.model tiny
locals

; Темп (в ударах в минуту)
tempo equ 120

; Таблица соответствия номеров полутонов обозначениям нот
; (в буквенной нотации), S - диез
C equ 0 ;"до"
D equ 2 ;"ре"
E equ 4 ;"ми"
F equ 5 ;"фа"
G equ 7 ;"соль"
A equ 9 ;"ля"
B equ 11 ;"си"
S equ 1 ;#

;---------------------------------------------------------------
; play - воспроизведение ноты
; note = номер полутона
; octave = номер октавы
; len = длительность для размера 4/4 и заданного темпа

play macro note,octave,len
mov ax,octave shl 8 + note ;начинаем играть ноту
call play_note
mov cx,4370/(tempo*len) ;задержка
call delay
call stop_note ;выключаем динамик
endm

.code
.startup
;воспроизведение ноты "ля" первой октавы
play A,3,4

;выход
mov ax,4C00h
int 21h

;---------------------------------------------------------------
; play_note - начинает воспроизведение ноты
; вход:
; al = номер полутона внутри октавы (0..11)
; ah = номер октавы (3 = первая фортепианная)
; выход:
; нет

play_note proc
mov cl,ah ;cl = номер октавы
cbw ;ax = номер полутона * 2
shl ax,1
lea bx,notes ;bx = @notes[номер полутона]
add bx,ax
mov al,0B6h ;загрузка упраляющего слова таймера
out 43h,al ;(меандер на 3-м канале)
mov ax,[bx] ;ax = notes[номер полутона] * 2^номер октавы
shr ax,cl
out 42h,al ;загрузка коэффициента деления в 3-й канал таймера
mov al,ah
out 42h,al
in al,61h ;включение динамика
or al,3
out 61h,al
ret
endp

;---------------------------------------------------------------
; stop_note - выключает динамик
; вход:
; нет
; выход:
; нет

stop_note proc
in al,61h
and al,not 1
out 61h,al
ret
endp

;---------------------------------------------------------------
; delay - задержка
; вход:
; cx = длительность задержки в 1/18 с (точнее - в 65536/1193180 с)
; выход:
; нет

delay proc
xor ax,ax
mov es,ax
@@1:
mov ax,es:[46Ch]
@@2:
hlt
cmp ax,es:[46Ch]
je @@2
loop @@1
ret
endp

.const

; notes - таблица коэффициентов деления для октавы 0 (контроктавы)
; Коэффициенты деления для более высоких октав получаются
; путём умножения значений из таблицы на 2^(номер октавы)

notes:
dw 36488 ;C
dw 34445 ;C#
dw 32511 ;D
dw 30673 ;D#
dw 28960 ;E
dw 27328 ;F
dw 25804 ;F#
dw 24350 ;G
dw 22981 ;G#
dw 21694 ;A
dw 20473 ;A#
dw 19325 ;B

end


Добавлено через 12 мин.
http://podgoretsky.com/ftp/Docs/Asm/AsmBradly/8/8-2.html
http://www.cyberguru.ru/programming/assemb...mers-sound.html


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Пионер
**

Группа: Пользователи
Сообщений: 69
Пол: Мужской

Репутация: -  3  +


Отлично, пойду разбираться с кодом, спасибо за наводку.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Пионер
**

Группа: Пользователи
Сообщений: 69
Пол: Мужской

Репутация: -  3  +


М
КМА, следи за тем, что печатаешь. Я исправил.. Лопарь



Я тута помучился чуть-чуть, и вообщем сделал такую прикольную вещь. По возможности оставил комментарии, мало ли кому понадобиться. Только она играет "Веселую овечку Мери".


TITLE mary
;=================
;= сегмент стека =
;=================
mary_stack SEGMENT PARA STACK 'stack'
db 64 dup('stack')
mary_stack ENDS
;==================
;= сегмент данных =
;==================
mary_data SEGMENT PARA PUBLIC 'data'
; время задержки
mary_time dw 6 dup (25), 50
dw 2 dup (25, 25), 50, 25, 25, 50
dw 12 dup (25), 100
; цельная нота, это 100 (1 сек), половинная 50, 25 это четверть, и т. д.
;++++++++++++++++++++++
; мелодия мери
mary_freq dw 330, 294, 262, 293, 3 dup(330) ; 1-2 такт
dw 3 dup(294), 330, 2 dup(392) ; 3-4 такт
dw 330, 294, 262, 294, 4 dup (330) ; 5-6 такт
dw 2 dup (294), 330, 294, 262, 0FFFFh ; 7-8 такт
; нота соответствуют частотам
; до 130,8
; диез 138,6
; ре 146,8
; ми 164,8
; диез 155,6
; фа 174,8
; соль 196
; диез 185
; ля 220
; диез 207,7
; си 246,9
; ----------
; до 261
; диез 277,2
; ре 293,7
; диез 311,1
; ми 329,6
; фа 349,2
; диез 370
; соль 392
; диез 415
; ля 440
; диез 464,2
; cи 493,9
mary_data ENDS
;================
;= сегмент кода =
;================
mary_code SEGMENT PARA PUBLIC 'code'

mary proc far
assume CS: mary_code, DS: mary_data, SS: mary_stack
push DS
xor ax, ax ; обнуляем ax
push ax ; DS:0000 по нему будем выходить в ОС

mov ax, mary_data ; явно определим сегмент данных
mov DS, ax
; подготовим все для проигрыша звука, т. е.
lea si, mary_freq ; загрузим в si массив мелодии
call play ; запускаем процедуру play
ret
mary endp

; Процедра play проигрывает мелодию
; в регистре si должен находиться адрес массива мелодии
play proc near
push ax ; cохраняем регистры
push di
push si
push bp
@freq:
mov di, [si] ; загружаем в di следующую ноту
cmp di, 0FFFFh ; сравниваем, не конец ли? (0FFFFh признак окончания)
je @end_play ; если конец, то заканчиваем проигрывать
; если нет, то воспроизведем звук
mov bx, mary_time+bp
call sound ; вызвав процедуру sound
add si, 2 ; ставим указатель на следующую ноту
add bp, 2 ; и соответственно на следующий такт
jmp @freq ; прыгаем на следующий проигрыш ноты

@end_play:
pop bp ; восстанавливаем регистры
pop si
pop di
pop ax
ret
play endp

; процедура sound проигрывает звук
; в di соответствущая нота
; в bx задержка
sound proc near
push ax ; сохраним регистры
push bx
push cs
push dx
push di

mov al, 0BCh
out 43h, al ; запишем в al значение таймера
mov dx, 14h ; делитель времени
mov ax, 4F33h ; 1331000 делить на частоту
div di
out 42h, al ; младший байт счетчика таймера
mov al, ah
out 42h, al
in al, 61h
mov ah, al
or al, 3 ; включаем динамики
out 61h, al
@waits: ; делаем задержку
mov cx, 10000 ; в 10 милисекунд
loop $
dec bx ; пока не кончиться bx
jnz @waits ; будем выводить звук
mov al, ah
out 61h, al ; восстанавливаем порт в начальное состояник

pop di ; восстановим регистры
pop dx
pop cx
pop bx
pop ax
ret
sound endp
mary_code ENDS
END mary


 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.10.2020 12:09
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name