Задачей было написать резидентную программу для DOS, которая проигрывает ноты из массива (1сек на каждую ноту)
Программа запускается, в фоне проигрываются ноты. но как только ноты заканчиваются, DOS перестает на что либо реагировать
.model tiny
.code
org 100h
.386
start:jmp load
ppresenceflag dw 1260h
old dd 0
outSound dw ?
la dw 2711
;массив частот соответсвующих нотам
notes dw 1B8h, 1BEh, 1EDh, 20BH, 22AH,24BH, 26EH, 293H,2BAH, 2E3H,310H,33EH,370H
counter db 18
i dw 0
isItFirst db 1
;процедура, проигрывающая звук
bip proc
pusha
mov al,0b6H;управляющтй бит
out 43H,al
mov ax,outSound;частота
out 42H,al;младшая
mov al,ah
out 42H,al;старшая
in al,61H
mov ah,al
or al,3
out 61H,al
popa
ret
bip endp
;процедура задержки
void proc
pusha
and al,11111100b
out 61h,al
mov cx,04h
mov dx,93e0h
mov ah,86h
int 15h
popa
ret
void endp
handler:
handler proc
pushf ; создание в стеке структуры для IRET
call cs:old ; вызов старого обработчика прерываний
push ds ; сохранение модифицируемых регистров
push es
push ax
push bx
push cx
push dx
push di
push cs
pop ds
;для отсчета минтуы используется счетчик counter
;тк прерывание срабатывает 18 раз в секнуду
;смена звучащей ноты изменяется только тогда когда
;counter становится равным 0
dec counter
cmp counter,0
jne met1
;воспроизведениие ноты
;и смена ноты на следующуюю
mov bx,i
mov ax,notes[bx]
mov outSound, ax
call bip
add i,2
mov counter,18
cmp i, 24
jle met1
add i,2
call void
;выход из обработчика прерывания
met1:
pop di
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
iret
handler endp
end_handler:
;не резидентная часть программы
;получаем адрес обработчика прерывания
load:mov ax, 351Ch
int 21h
cmp bx,ppresenceflag; флаг присутствия, если программа
; уже есть в памяти повтораная запись не будет производиться
jne exit
;сохранение контекста старого обработчика прерывания
mov word ptr old, bx
mov word ptr old+2,es
mov ax,251Ch
mov dx,offset handler; получаем адрес метки handler
int 21h
mov ax,3100h
mov dx,(end_handler-start+10Fh)/16; получение размера
;обработчика прерывания в параграфах
int 21h
;выход из программы с сохранением нового обработчика прерывания
exit:
mov ax,3100h
int 21h
ret
end start