Цитата:
Сообщение от
апро
Может я что то недопонимаю, но насколько я понял из книг по ассемблеру, прерывание начинает обрабатывться после команды IM 2,
Команда IM 2 не начинает обработку прерывания, она задает режим обработки прерывания.
Цитата:
а закончится обработка должна командой RET.
Обработка прерывания также может завершиться командой RETI или RETN. А может вообще не заканчиваться, можно на прерываниях построить и главный программный цикл, но так делают редко.
Цитата:
После команды IM 2 обработчик начинает считать такты в своих мудрёных счётчиках, и если результат счёта соответствует расчётному то программа работает , а если нет то доходит до команды RST 0.
Нет никаких счетчиков в обработчике прерываний, здесь, по крайней мере. Счетчики есть в основной программе. Вот например цепочка INC E в листинге - кусок такого счетчика.
Цитата:
Но я не врублюсь , что заставляет программу доходить до какого то места и неожиданно начинать с другого.
Прерывание и заставляет. По сигналу INT делается подтверждение прерывания, и переход на обработчик прерывания (команды перехода НЕТ, это делается аппаратно, но есть адрес перехода, для режима IM 2 на спеке он хранится в памяти по адресу: (старший байт=регистру I, младший=$FF). А обработчик прерывания уже меняет адрес возврата, обходя этим команду RST 0.
Цитата:
А в моём реальном клоне программа отрабатывает до RST 0 в обоих местах, и не бросает выполняться на пол пути. В чём фокус?
Фокус в нестабильном времени кадра между прерываниями. Из-за вайтовых задержек программа не может точно вычислить время кадра в тактах, и прерывание должно произойти позже расчетного момента перед командой RST 0. То есть RST 0 отрабатывает, и идет сброс.
Цитата:
Я могу предположить, что в отмеченных местах на картинке приходит следующий сигнал INT и каким то чудом прерывает выполнение программы в нескольких тактах от команды RST 0. Но я нигде не читал про такую фишку. Везде описаны прерывания только по команде IM.
Вы неправильно представляете работу системы прерываний. По команде IM задается _режим_обработки_прерывани , а не происходит само прерывание. Сам прерывание происходит по приходу сигнала INT. Этот сигнал приходит со строгой периодичностью, с длиной периода, равной времени кадра между прерываниями (69888 тактов на фирменных 48 к, но с другой длиной на других машинах. Проблема в том, что точно вычислить эту длину на некоторых машинах программно можно, а на некоторых - нельзя (или можно, но используя другие приемы, не такие, как в данной программе)).
Цитата:
И тут назревает следующий вопрос. Если поцессор бросает выпонять программу в этих местах, то откуда начинает дальше? Могу предположить с адреса на вершине стёка.
Во время прихода сигнала прерывания на стек кладется адрес возврата - место, на котором программа была прервана. Команда RET в обработчике прерывания делает переход на это место, считывая его адрес со стека. НО - можно программно в обработчике прерывания изменить этот адрес перехода. В данной программе он просто пропускается на стеке ($FEFE INC SP:INC SP), а переход происходит на следующий адрес, хранящийся на стеке (EI: RET). EI (разрешение прерываний) нужно, т.к. при переходе в обработчик прерывания запрещаются аппаратно.