Для SOB - нет.
Вид для печати
Я проверил, тот же размер получается.
- - - Добавлено - - -Код:; R0 - screen address
; R1 - width in bytes
; R2 - height in rows
ScrollRight:
MOV #64.,R3 ; default offset
SUB R1,R3
MOV R1,Of1+2
NEG Of1+2
R: CLC
ADD R3,PC
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
Не портит.
Переход возможен на 255 слов назад
Мудрено =) Догадывался о такой механике, но стоило прояснить для себя. А на регистр SP это тоже распространяется или нет? Или он всегда изменяется на 2 командами INC/DEC?
Если же нет, то что происходит при работе с нечетным стеком? Трап, как и в остальных подобных ситуациях?
Не, у SOB переходы только назад, но вот описание команды не сходится с этим:
А теперь смотрим описание команд процессора:
https://i.ibb.co/M58p3xj/SOB-jump.jpg
число nn - это 6 бит, 64 варианта. Значит, максимальное значение - минус 128. Поэтому максимум можно обработать 63 двухбайтовых команды (учитывая +2 байта к PC от SOB)
Так же распространяется. INC/DEC меняет на единицу, а инкрементные/декрементные адресации - всегда на 2, независимо от того, словная или байтовая команда. Для PC это тоже так, см. например адресации 27, 37.
На 1801ВМ1 всё работает как ни в чём не бывало, так же как и с чётным стеком. (имеется в виду, что производятся стандартные операции помещения в стек/извлечения из стека). Байтовая операция доступа к памяти с относительной адресацией, где индексируемый регистр - стек и его значение нечётно, даёт доступ к нечётному байту, т.е. MOVB (SP),R0, если SP=0775 выдаст в R0 содержимое байта из ячейки 0775
если текущей считается сама команда SOB, то даже 124., т.к. 77R01 - это переход команды на саму себя.
Однако выполнение этой команды на 1801ВМ1 равнозначно команде DEC R при этом флаги-признаки вообще не меняются, т.к. выполняется уменьшение на 1 содержимого регистра и, если он не равен 0, то переход по смещению 0 - на адрес, следующий за командой SOB, если равен 0, то прекращение ветвления и переход на адрес, следующий за командой SOB.
Хорошо, а команды типа CALL (JSR) и RET (RTI) будут корректно работать с нечетным стеком?
А если поставить команду SOB PC,nn? Тут вопрос даже не в нулевом смещении, а в изменении PC самой командой.
Неа, у меня сократилось аж на 16 байт =) Правда, тоже задействовал один дополнительный регистр, зато ощутимый выигрыш по объему.
Заработало с первого раза без багов, хотя в асме БК я вообще нубас =) Настрочил в блокнотике, скомпилил - ура, работает.
В плане быстродействия где-то одинаково за счет того, что внутри цикла (основного) нет адресаций через память.
А если задействовать еще один регистр под хранение числа #100, то и перед SOB можно убрать выборку из памяти, а размер будет тот же.
Кстати, команда CLC не нужна, т.к. ADD reg,PC в любом случае обнулит флаг переноса.
Вложение 76773
Вложил оба варианта: первоначальный от Manwe и свой. Внутри исходники + готовый код. Ниже под спойлером текст исходника, если кому лень загружать файл.
Скроллится кусочек вверху экрана, время около 18 сек, можно перезапустить командой S монитора. Удобно запускать прямо в эмуляторе.
Развернул команды скролла, т.к. компилер BKTurbo8 не понимает этой конструкции с копиями. Как в нем задать повтор куска кода?
Скрытый текст
Код:.LA 1000
MOV #1000,R5
SCRL: MOV #40000,R0
MOV #30,R1
MOV #100,R2
CALL ScrollRight
SOB R5,SCRL
HALT
; R0 - screen address
; R1 - width in words
; R2 - height in rows
ScrollRight:
ASL R1
NEG R1
ADD #100,R1 ;R1=64-(width*2)
ROLL: MOV R0,R3 ;save scr addr
ROLL1: ADD R1,PC
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+
ROL (R0)+ ; scroll row
ROL (R0)+
ROL (R0)+
ROL (R0)+
MOV R3,R0 ; restore scr addr
ADC (R0) ; shift from last word to 1st
INC PC
BR ROLL1
ADD #100,R0
SOB R2,ROLL
RET
.END
[свернуть]
да, CLC осталась от прошлого варианта без ADD, можно смело убирать