Опять я в ступоре, на этот раз более глубоком
В общем, имеется двухбайтное число (счётчик) в 2-х соседних регистрах. Необходимо сделать процедуру его уменьшения/увеличения на 1/10/100 (в зависимости от состояния 3-х флагов) таким образом, чтобы оно не выходило за произвольные нижнюю и верхнюю границы.
Если более подробно, то один флаг (Т) отвечает за направление счёта, два других (А и Б) за величину счёта (100 если А=Б=0; 1 если Б=1; и 10 если А=1_и_Б=0). Хотелось бы решить задачу в общем виде, т.е. чтобы пороги МАКС и МИН можно было задать любые (МАКС>МИН).
Сейчас это сделано только для инкремента/декремента на единицу, да и то коряво: перед соотв. действием текущее значение счётчика побайтно сравнивается с порогом. Например, если верхний порог МАКС равен $ABCD, то инкремент будет выглядеть
Код: Выделить всё
clr zeroreg;
ldi onesreg, 1;
...
cpi count_H, 0xAB; сравниваем старший байт с порогом
brlo PC+3; если меньше, то сразу переходим к вычислению
cpi count_L, 0xCD; сравниваем младший байт с порогом
brsh PC+3; если больше или равно, то пропускаем вычисление
add count_L, onesreg; инкремент младшего байта на единицу
adc count_H, zeroreg; прибавляем значение флага переноса к старшему байту
...
Самое простое было зациклить это на соотв. число циклов (1/10/100), однако время выполнения в таком случае может достигать 1000 тактов, что недопустимо.
Наверняка можно как-то компактно дополнить этот код.
Например, прибавляем 1. Проверяем флаг Б, если Б=0 то прибавляем ещё 9. Проверяем флаг А, если А=0 то прибавляем ещё 90. Но вот как проверить то, что после прибавления не будет превышен порог (при прибавлении чисел больше 1)? С учётом возможных ошибочных переходов $FFFF -> $0000 для порогов, близких к $FFFF.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]