D
D
DVoropaev2019-01-18 10:08:34
DOS
DVoropaev, 2019-01-18 10:08:34

Why does the program terminate incorrectly?

The task was to write a resident program for DOS that plays notes from an array (1sec for each note)
The program starts, notes are played in the background. but as soon as the notes end, DOS stops responding to anything

.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

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
jcmvbkbc, 2019-01-18
@DVoropaev

as soon as the notes end, DOS stops responding to anything

and why do you call voidwhen the notes end?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question