TL;DR: как считать количество тактов между двумя прерываниями, чтобы определить скорость процессора?
Захотелось мне в программе определять скорость процессора, так, каприз, не критично, просто чуть удобнее было бы. Добрые люди подсказали, коллега @Uzix пример кода показал. Но, я же самый умный, я пример толком смотреть не стал, начал сразу сам что-то накручивать. Пример, конечно, понадобился позже, не такой я гений, чтобы сразу всё написать сходу, но, к моему удивлению, скорее, для проверки и сверки данных. Теория там понятна, заводим IM 2 и считаем количество тактов, которое успеваем сделать между двумя прерываниями. Эксперименты у меня с Sizif-512, ничего другого в наличии нет.
И вот когда дошло дело до сравнения моего (работающего, к моему немалому удивлению) прототипа с примером, увидел я много ключевых различий. Хотелось бы прояснить, то ли я что-то упускаю, то ли для моего упрощённого случая все эти тонкости не важны.
Итак, вид на проблему с моей колокольни. Когда мы увеличиваем частоту процессора и делаем свой обработчик прерываний самое главное не сделать его слишком коротким/быстрым. «ULA» или кто-там-вместо держит /INT 32 «настоящих» такта, согласно ТОЙ САМОЙ КНИГЕ. Получается, когда процессор начинает работать быстрее, его 32 такта в какой-то момент оказываются быстрее 32-х тактов ULA. И тут мы входим в ту же реку дважды. В смысле, обработчик вызывается ещё раз для того же самого прерывания. Понятно, проблема тоже не проблема, делаем обработчик прерывания достаточно долгим и… Всё работает. Важный момент: IM 2 у меня нигде больше не используется и, практически, после одного прерывания отключается. Ну, такая особенность у меня, не нужно мне это, кроме как для измерения скорости, поэтому неразумно длинный обработчик меня не смущает.
Вопрос №0: я правильно понял проблему? А то, может я вообще не то решал и ловил тёмную кошку прямо под фонарём, так сказать
Дальше я начал смотреть на пример, экспериментировать с кодом и обнаружил две вещи, которые поставили меня в тупик. Моих знаний недостаточно для понимания почему происходит подземный стук и, как говорил почтальон Печкин, хотелось бы повысить уровень собственной образованности
Вопрос №1: теоретически рассчитанные задержки на практике можно сократить раза в четыре (подтверждено экспериментально. на Sizif). Раза в два, я бы ещё понял, но в четыре? Есть где-то авторитетный источник, где описаноожидаемоеобщепринятое поведение «ULA» и Z80 при повышении частоты? Я явно где-то ошибся в расчётах.
Вопрос №2: в примере Евгения и некоторых других, которые я видел, авторы предпочитают добавлять задержку NOP’ами или какими другими «прямолинейными» инструкциями. Я не долго думая сделал цикл и разницы не заметил. Там могут быть какие-то, мне не важные, побочные эффекты и отсутствие цикла принципиально или нет? И итеративно длина обработчика у Евгения подбирается, чтобы остановиться на наименьшем замедлении, которое достаточно, так? Но, всё же, почему не сделать через цикл с параметром…
P.S. как я понял, на Next таких проблем нет, там эмулируемая ULA подстраивает длительность импульса /INT под частоту. Пример, который я сделал и который на Sizif на 14МГц ухитряется вызвать обработчик несколько раз за прерывание, на Next всегда и на любой частоте вызывает обработчик только один раз. Ну, эта информация практически нам тут бесполезна, там на Next и API есть для получения текущей частоты, да и «живого» Next я вряд ли когда увижу.