Turbo Pascal 7.0 (программа-обработчик прерываний).
На вузовской заочке вот такой пример программы дан (в конце описание кода программы). Всё компилируется, но при запуске exe`шника в MS-DOS (эмулятор DOSBox) программа просто издаёт постоянный писк, на нажатие клавиш никак не реагирует.
Подскажите пожалуйста, что не так?
Может быть в начале программы надо прописывать что-то, связанное со значениями флагов (на ассемблере немного писал).
Не понимаю как воспринимаются компилятором строчки кода в фигурных скобках (получается фигурные скобки не всегда означают комментарии).
Буду рад уже просто литературе какой-нибудь (не могу найти), где про прерывания и резидентные программы с потоками всё расписано для чайников.
{$M $1000, 0, 0}
Program Scan_code;
Uses Crt, Dos;
Var
OldKey: Procedure;
c, c1 : Byte;
vk1 : Boolean;
{$F+}
Procedure Key; Interrupt; { Обработчик прерывания. }
Begin
c1 := c;
c := Port[$60];
if c = 1 then { Нажали ESC. }
vk1 := true; { Включен режим отображения кодов нажимаемых клавиш. }
if vk1 then
Begin
write(' kod=', c, ' ');
if c = c1 + 128 then writeln; { Отпустили клавишу. }
End;
Sound(1000);
Delay(100);
Nosound;
Inline($9C);
OldKey;
End;
{$F-}
Begin { Основная программа. }
vk1 := false; { Сначала режим отображения кодов выключен. }
GetIntVec($9, @OldKey);
SetIntVec($9, Addr(Key));
Keep(0);
End.
Программа должна обрабатывать прерывание клавиатуры и каждое нажатие на клавишу сопровождать звуком. После нажатия на клавишу ESC программа начинает дополнительно выводить коды нажатых клавиш, причём код нажатия и код отжатия различаются на 128 и выводятся в одной строке. Коды следующей нажатой клавиши – на следующей строке и т.д. Для того чтобы проверить, является ли очередное прерывание клавиатуры сигналом отпускания клавиши, используется дополнительная переменная c1, в которую сохраняется предыдущее значение, считанное с порта клавиатуры. Если они различаются на 128 – клавиша отпущена.
Перед процедурой – обработчиком прерывания включается режим “дальней модели”, после него он выключается. В конце нового обработчика вызывается стандартный обработчик, который предварительно был сохранён под именем OldKey.
DosBox и не обязан эмулировать DOS максимально точно. Попробуй на VirtualBox поставить DOS и из-под него запускать свою программу.
Как обратный слеш ввести?
Просто другие символы вводятся, но не "\".
Пытался и c помощью виртуальной клавиатуры ввести (в том числе и на кнопку справа от NumLock нажимал).
Мне это надо для захода в общую папку (находящуюся в основной ОС).
Ничего не получается, буду ещё завтра долбиться
А под этим что имеется в виду?
Через DAEMON Tools перекинул exe`шник в гостевую ОС.
Дос нашёл этот exe`шник и смог запустить его.
Но тут даже писка не наблюдается (тишина), вводить по прежнему ничего не получается после запуска exe`шника.
Во-первых, мне не нравится вот это:
Inline($9C);
OldKey; У тебя начала IRET, потом старый обработчик. Не находишь, что это нелогично? И если мне не изменяет память, 9С - это RET, а не IRET. По-моему, должна быть разница.
Во-вторых, как сказано выше, DosBox - такой себе эмулятор, и ХЗ, позволяет ли он нормально работать с портами. Используй настоящую виртуальную машину.
Я часов 40 потратил на поиск ошибки, её просто нет.
Посоветуйте пожалуйста что-то вроде VirtualBox в количестве двух штук. В VirtualBox звук вообще не выводится, драйвер нужный стоит, звук включен, там всё необходимое есть.
Всё это время пытался добиться результата в DOSBox`е. С контроллером мундохался, без delay запускал, прерывания разрешал и запрещал для одной строки, пробовал вместо процедуры указатель использовать, чисто ассемблерный код запускал, игрался с инлайнами.
Короче, надеюсь просто дело в DOSBox`е.
Короче установил полную борландовскую версию паскаля (7.01), там есть возможность компиляции в защищённом режиме. Скомпилировал программку эту и запустил экзешник, всё работает (DOSBox справился со всем этим).
Если кто-то это читает и вам надо использовать SetIntVec, то скорее всего надо компилировать в защищённом режиме.