Джерри попросил процедурку вычисления адреса в экране.
Суть следующая:
есть DE - адрес в экране
C - количество пиксельных линий которые надо пропустить вниз
Надо сделать п/п, которая получит в DE адрес новой пиксельной линии
Что получилось:
Код:
ld a,d 4 берём уже имеющееся смещение по пикселям вниз
and %00000111 7 маскируем
add a,c 4 добавляем к смещению, т.к. можем перейти через треть или з/м
ld c,a 4 сохранили полученное значение
and %00111000 7 выделили часть, отвечающую за положение внутри трети экрана
rlca 4 смещаем её в старшие биты
rlca 4
add a,e 4 добавляем к младшему адресу
ld e,a 4 сохраняем
sbc a,a 4 если у нас появился CY, значит надо будет делать переход в другую треть
and %01000000 7 заполнили флагом переноса шестой бит аккумулятора
add a,c 4 добавили значения по третям из исходных данных
and %11000000 7 выделили
rrca 4 смещаем в 4-5 бит для адреса экрана
rrca 4 обращаю внимание что полученные трети никуда не сохраняем!
rrca 4
xor c 4 нам надо ещё младшие 3 бита, адрес пиксельной линии
and %11111000 7 по хитрому без промежуточного регистра выделяем её
xor c 4 получили в аккумуляторе
ld b,a 4 спрятали
ld a,d 4 из регистра D забираем треть и сам адрес
and %11111000 4 маскируем их
add a,b 4 добавляем спрятанное значение, младшие 3 бита учтены вначале
ld d,a 4 готово!
итого 111 тактов. Кто короче? :-)
---------- Post added at 10:20 ---------- Previous post was at 09:53 ----------
Ещё один перл.
Пересчёт из атрибутной области в адресную.
Там фактически надо переместить биты из младших 0-1 в более старшие 3-4, плюс сохранить адрес. Универсальность процедуры в применимости и по отношению к теневому (#c000-#daff) экрану.
Код:
ld a,h ; 4
; and %00000011 ; 7 0 - так и хочется замаскировать эти биты, но эта операция не нужна,
add a,a ; 4 8 - т.к. старшие биты уйдут по дальнейшей маске %00011111, а
add a,a ; 4 12 - младшие биты забиты нулями по add a,a
add a,a ; 4 16
xor h ; 4 20
and %00011111 ; 7 27 - сохраним нужные биты и обнулим ненужные 0-2
xor h ; 4 31 - вытащили исходный адрес расположения
ld h,a ; 4 35
итого 35 тактов :-) кто быстрее?