
Сообщение от
AzAtom
Написал на этом паскале процедуру рисования линии и к нему на асме процедуру точки. Всего получилось заполнение экрана 192 линий по 256 точек за 12,4 сек, что соответствует 883 такта на пиксель. Сама процедура точки получилась 315 тактов, она без табличная, адрес "вычисляется" переставлением битов. Больше 500 тактов на пиксель в самом скомпилированном алгоритме линии тоже многовато, но там понятно, под переменные используются не регистры, а память.
Очень жаль, что в сообщении нет этого замечательного кода, но если использовать алгоритм Брезенхема, то результаты будут в несколько раз лучше. Судя по наброску на псевдокоде, который не очень сложно перевести на асм, большую часть переменных, необходимых для рисования линии, вполне можно распихать по регистрам. Вычислять для каждой точки адрес в памяти не потребуется, и общее быстродействие без особых усилий можно довести до 150 тактов на точку плюс тактов 500 на вычисления переменных в начале функции:
Код:
DRAW_LINE(X1,Y1,X2,Y2):
IF Y2<Y1 //рисовать линию будем с того конца, у которого Y меньше
SWAP(X1,X2)
DY = ABS(Y2-Y1)
Y1 = MIN(Y1,Y2)
IF X2<X1 //правим команды вращения маски и изменения указателя после метки INC_or_DEC
INC_or_DEC = DEC_X
ELSE
INC_or_DEC = INC_X
DX = ABS(X2-X1)
CNT = MAX(DX,DY) //количество точек которые нужно нарисовать
HL = COO_TO_ADR(X1,Y1) //вычисляем байт в котором сидит первая точка
PT = 1 SHL (X1&7) //вычисляем маску точки
ER = 0 //устанавливаем ошибку в ноль
GOTO SET_PT_1
INC_Y:
ER -= DX //корректируем ошибку
H += 1 //смещаемся по Y
IF H AND 7 //в 7 случаях из 8 можно будет нарисовать точку без дальнейшей коррекции
GOTO SET_PT_1
H -= 8 //корректируем указатель и переходим в следующую строку знакомест
L += 32
IF L AND 224
GOTO SET_PT_1
H += 8 //переходим в следующий блок из 8 строк
SET_PT_1:
(HL) |= PT //рисуем точку
IF CNT=0 //проверяем не закончилась ли линия
GOTO EXIT
CNT -= 1
IF ER>=DX //проверяем, можно ли дальше двигаться вдоль оси Y
GOTO INC_Y
INC_or_DEC: //код настроенный в начале процедуры на уменьшение или увеличение X
RRC PT or RLC PT //сдвиг маски
IF CY
INC L or DEC L //изменение указателя
ER+=DY //коррекция ошибки
IF ER>=DX //проверка не нужно ли сместиться по оси Y
GOTO INC_Y
SET_PT_2:
(HL) |= PT //рисуем точку
IF CNT=0 //проверяем не закончилась ли линия
GOTO EXIT
CNT-=1
GOTO INC_or_DEC //переходим у следующей точке
EXIT: