Oleg N. Cher, твори! !
Вид для печати
Oleg N. Cher, твори! !
переименовать бы тему в "карточная игра" или как-то так
Ну смотри, в скорости потеряешь вдвое.
Для произвольной ширины я бы сделал иначе: перед последовательностью команд ROL поставить BR, чтобы он прыгал вперёд на нужное число слов, пропуская ненужные ROLы. Просто перед началом записываешь в младший байт по адресу команды BR число сколько ROLов надо пропустить. Самомодифицирующийся код.
Исходник и бинарник: Вложение 76771
Код:; R0 - screen address
; R1 - width in words
; R2 - height in rows
ScrollRight:
MOVB #32.,RB ; default offset
SUB R1,RB
ASL R1 ; width in bytes
MOV R1,Of1+2
NEG Of1+2
R: CLC
RB: BR Of1
2: .Repeat 32.
{
ROL (R0)+ ; scroll row
}
Of1: ADC -32.(R0)
SUB R1,R0
INC PC ; repeat twice
BR R
ADD #100,R0 ; next row
SOB R2,R
RET
; R0 - screen address
; R1 - width in words
; R2 - height in rows
ScrollLeft:
MOVB #32.,LB ; default offset
SUB R1,LB
ASL R1 ; width in bytes
MOV R1,Of2-2
SUB #2,Of2-2
L: ADD R1,R0
CLC
LB: BR Of2:
2: .Repeat 32.
{
ROR -(R0) ; scroll row
}
BCC Of2
BIS #100000,-2(R0)
Of2: INC PC ; repeat twice
BR L
ADD #100,R0 ; next row
SOB R2,L
RET
По аналогии со Спектрумом предложу еще один вариант, для БК он даже больше подойдет, как как PC такой же регистр, как и остальные:
ADD смещение,PC
как оно точно записывается в ассемблере PDP, вам лучше знать =) Зато избавимся от команд BR и команды модификации кода,
плюс при таком варианте длина прыжка не имеет ограничения, имеющегося для команды BR - можно хоть 500 команд перепрыгнуть.
К сожалению, по аналогии со Спектрумом не получится, потому что у него инструкции 8-битные, а тут 16-битные. То есть не получится прибавлять нечётные числа – они в середину команды будут указывать.
Хотя... Я же там потом ширину умножаю на 2. Надо попробовать!
Update: попробовал. Пришлось задействовать ещё один регистр. Команда ADD работает чуть дольше, чем BRanch. Размер процедуры не сократился. Так что лучше оставить с BR. Всё-таки для PDP-11 самомодифицирующийся код – часто наилучшее решение.
По идее, должен сократиться, сейчас сижу сочиняю процедуру)) хотя тут двоякая задача: максимальная скорость и размер не сильно раздувать.
И еще пара вопросов, все же PDP не моя стихия. Как понимаю, переход для SOB ограничен 128-ю байтами назад?
То бишь нас спасает только то, что работаем словами - 64 команды сдвига не влезли бы в переход. Не в конкретно данном примере, а вообще, где понадобятся 64 двухбайтовых команды.
И второе: объясните фокус с однократным повтором кода через INC PC. Каким образом это первый раз срабатывает, а на втором проходе нет.
неа, именно inc PC и только на процах, которые допускают чтение слов по нечётным адресам. Это совсем другая фича и работает по-другому.
Когда выполняется первый раз команда INC PC, то счётчик команд становится нечётным, но при этом всё равно выполняется команда, следующая за INC PC, т.к. по нечётному адресу всё равно читаются слова, которые читались бы и по чётному. А вот при втором выполнении, нечётный PC становится чётным, при этом значение счётчика команд становится +2 к значению счётчика команд после выполнения INC PC и следующая команда за INC PC пропускается и выполнение программы идёт дальше. Немного сумбурно, но всё это легко пронаблюдать в любом отладчике даже на самой БКшке. У этого метода один минус - нельзя использовать относительную адресацию для байтового доступа к памяти внутри участка, который повторно выполняется с нечётным счётчиком команд.
Не совсем так. Поскольку адреса команд могут быть только чётные, то в байте хранится смещение, которое потом удваивается процессором, т.е. переход возможен до 256 байт назад и 254 вперёд. Если я конечно правильно понял логику проца PDP-11.
- - - Добавлено - - -
Кстати, команда SOB не портит флаги?