Сначала я программирую на винтажные компьютерные группы. То, что я пишу, специально для MS-DOS, а не для windows, потому что это то, что люди запускают. Моя текущая программа предназначена для более поздних систем, а не для линии 8086, поэтому планировалось использовать IRQ 8. Это позволяет мне устанавливать частоту прерываний в двоичных значениях от 2 / секунды до 8192 / секунду (2, 4, 8, 16, так далее…)
Только, по какой-то причине, на более старых старых системах (хорошо, это звучит странно), это не работает. В эмуляции и системе 386, к которой у меня есть доступ, она работает просто отлично, но в моей системе P3 (GA-6BXC MB с процессором P3 800) она просто не работает.
Код
установка прерывания
disable();
oldrtc = getvect(0x70); //Reads the vector for IRQ 8
settvect(0x70,countdown); //Sets the vector for
outportb(0x70,0x8a);
y = inportb(0x71) & 0xf0;
outportb(0x70,0x8a);
outportb(0x71,y | _MRATE_); //Adjustable value, set for 64 interrupts per second
outportb(0x70,0x8b);
y = inportb(0x71);
outportb(0x70,0x8b);
outportb(0x71,y | 0x40);
enable();
в конце прерывания
outportb(0x70,0x0c);
inportb(0x71); //Reading the C register resets the interrupt
outportb(0xa0,0x20); //Resets the PIC (turns interrupts back on)
outportb(0x20,0x20); //There are 2 PICs on AT machines and later
При закрытии программы вниз
disable();
outportb(0x70,0x8b);
y = inportb(0x71);
outportb(0x70,0x8b);
outportb(0x71,y & 0xbf);
setvect(0x70,oldrtc);
enable();
Я не вижу в коде ничего, что могло бы вызвать проблему. Но это просто не имеет смысла. Хотя я не полностью доверяю этой информации, MSD «сообщает» IRQ 8 как RTC Counter и говорит, что он присутствует и работает просто отлично. Возможно ли, что более поздние системы переместили вектор? Все, что я нахожу, говорит о том, что IRQ 8 — это вектор 0x70, но прерывание никогда не срабатывает в моей системе Pentium III. Есть ли способ узнать, были ли изменены векторы?
Прошло долгое время с тех пор, как я сделал какой-либо код MS-DOS, и я не думаю, что когда-либо работал с этим конкретным прерыванием (я почти уверен, что вы можете просто прочитать ячейку памяти, чтобы извлечь время, а IRQ0 может быть использованным, чтобы вызвать вас с интервалом тоже, так что, может быть, это и лучше. Во всяком случае, учитывая мою ржавость, простите меня за своего рода сброс ссылок.
http://wiki.osdev.org/Real_Time_Clock В нижней части этой страницы есть кто-то, кто говорит, что у них тоже были проблемы на некоторых машинах. RBIL предполагает, что это может быть вещь BIOS: http://www.ctyme.com/intr/rb-7797.htm
Без DOS я бы просто перехватил сам IRQ0 и переназначил их все на свои собственные номера прерываний и изменил время по мере необходимости. Я сделал это несколько недавно! Я думаю, что это плохая идея для DOS, хотя это выглядит более рекомендуемым для этого: http://www.ctyme.com/intr/rb-2443.htm
В любом случае, я уверен, что это связано с BIOS:
«Примечания: Многие BIOS отключают периодическое прерывание в обработчике INT 70h, если только не происходит ожидание события (см. INT 15 / AH = 83h, INT 15 / AH = 86h). Может быть замаскировано установкой бита 0 на порт ввода-вывода A1h «