нажатия клавиши должна выделять всю XMS память в системе (подробнее про XMS тут https://frolov-lib.ru/books/bsp.old/v33/ch11.htm)
Программа отрабатывает в эмуляторе DOSBox, в виртуалке DOS 6.22 через Virtual Box, но вот из под Qemu программа запускается, писать в клавиатуру можно, но когда нажимаешь нужную клавишу происходит зависание системы и вывод символа 'Ш' в правом верхнем углу.
Знаю, что нельзя вызывать прерывания внутри нового обработчика, но как тогда быть, подскажите что не так?
.model tiny
.code
ORG 100h
main:
jmp Init
;Ниже идет, собственно, код обработчика прерывания 09h
New_09h proc far
push ax ;сохраняем регистры
push dx
push ds
push es
mov ax,cs
mov ds,ax
mov es,ax
in al,60H ;читать ключ
cmp al,1Eh ;Если нажата клавиша 'A'
je do_pop ;да, активизировать popup
pop es ;нет, восстанавливаем регистры
pop ds
pop dx
pop ax ;и уходим на исходный обработчик
jmp cs:[Old_09h]
do_pop: ;код отработки нажатия клавиши 'A'
in al,61H ;взять значениe порта управления клавиатурой
mov ah,al ;сохранить его
or al,80h ;установить бит разрешения для клавиатуры
out 61H,al ;и вывести его в управляющий порт
xchg ah,al ;извлечь исходное значение порта
out 61H,al ;и записать его обратно
mov al,20H ;послать сигнал "конец прерывания"
out 20H,al ;контроллеру прерываний 8259
sti
mov dx,sizeMem ;перемещаем максимальное значение XMS памяти
mov ah,09h ;выделяем всю XMS память
call dword ptr HMMEntry
cli
pushf
call dword ptr cs:[Old_09h]
pop es ;восстанавливаем регистры
pop ds
pop dx
pop ax
iret ;возврат из обработчика прерываний
New_09h endp
HMMEntry DD ?
Old_09h DD 0 ;определение ячейки памяти для хранения адреса системного обработчика
sizeMem DW 0 ;переменная для хранения максимального значения XMS памяти (Кб)
;Со следующей метки нашей программы уже не будет в памяти
Init:
;Установим наш обработчик (New_09h
mov ax,3509h
int 21h mov word ptr Old_09h,bx
mov word ptr Old_09h+2,es
;запись стартового обработчика в вектор прерываний
mov ax,2509h
mov dx,offset New_09h
int 21h
;выводим сообщение о загрузке резидента в память
mov ah,09h
mov dx,offset InitMsg
int 21h
;получаем адрес управляющей функции драйвера
mov ax,4310h
int 2Fh mov word ptr HMMEntry,bx
mov word ptr HMMEntry+2,es
;определяем размер свободной расширенной памяти
mov ah,08h
xor bx,bx
call dword ptr HMMEntry
mov sizeMem,dx
;возврат в DOS, оставшись резидентным
mov dx,offset Init
int 27h
InitMsg DB "Resident installed in memory",13,10,"$"
end main
Можно попробовать потестировать на реальном железе
Обсуждают сегодня