Просмотр полной версии : Как быстро скроллить память на 2 пиксела?
Alex Rider
06.11.2013, 20:11
А знает кто-нибудь быстрый способ поскроллить строчку на экране на 2 пиксела в одном цикле перебора байтов? Ну, вернее, есть ли способ быстрее, чем 2 раза подряд на 1 пиксел?
А знает кто-нибудь быстрый способ поскроллить строчку на экране на 2 пиксела в одном цикле перебора байтов? Ну, вернее, есть ли способ быстрее, чем 2 раза подряд на 1 пиксел?
хмм
ну можно так
xor a
ex af,af
dup 31
ld a,(hl)
ex af,af'
rra
rr (hl)
rra
rr (hl)
inc l
edup
ex af,af'
rra
rr (hl)
rra
rr (hl)
либо вариант с табличками но сильно сомневаюсь что будет быстрее
Alex Rider
06.11.2013, 21:47
либо вариант с табличками но сильно сомневаюсь что будет быстрее
А что за вариант с табличками? У меня есть смутное подозрение, что скроллить придется не непрерывный кусок памяти, при этом границы "разрыва" не постоянны, так что вариант с dup-edup может либо не прокатить, либо обернуться геморроем с самомодифицирующимся кодом.
Так определись, чего именно скролить... потом уже процедуру придумывай.
ну можно так
Это точно работает?
Я делал так:
dup NN
rl (hl)
ex af,af'
rl (hl)
ex af,af'
dec l
edup
А что за вариант с табличками? У меня есть смутное подозрение, что скроллить придется не непрерывный кусок памяти, при этом границы "разрыва" не постоянны, так что вариант с dup-edup может либо не прокатить, либо обернуться геморроем с самомодифицирующимся кодом.
с табличками это примерно так
ld bc,head_table
dup nn
ld a,(de)
ldi
ld l,a
ld h,b
ld h,(hl)
edup
по алгоритму
данный скроллер позволяет скроллить на расстояние от 1 до 6 бит без изменения программы
и соответственно таблицы занимают от (2+1)*256 до (64+1)*256
как это работает:
у нас есть так называемая head_table где прописаны адреса таблиц скролла откуда мы уже берем сдвинутые данные для следующего байта.
генератор головной таблицы
ld hl,head_table
ld de,roll_table
ht0
ld a,l
and #03 ;размерность таблицы 2 бита (сдвиг на 2)
add a,d
ld (hl),a
inc l
jr nz,ht0
генератор таблиц скролла
ld hl,roll_table
ld bc,#0400 ;размерность таблицы (2 бита *2 значения)
rt0
push bc
rt1
ld b,2 ; на сколько битов скролл
ld a,c
ld (hl),l
rt2
rra
rr (hl)
djnz rt2
inc l
jr nz,rt1
inc h
pop bc
inc c
djnz rt0
Alex Rider
07.11.2013, 18:08
dup NN
rl (hl)
ex af,af'
rl (hl)
ex af,af'
dec l
edup
Надо больше спать по ночам, а не писать :( Идея использовать второй аккумулятор крутилась в голове, но как я мог не додуматься до такой простой реализации? Спасибо!
introspec
07.11.2013, 18:54
Идея использовать второй аккумулятор крутилась в голове, но как я мог не додуматься до такой простой реализации?Можно и с одним аккумулятором:
dup NN
rl (hl)
rla
rl (hl)
rra
dec l
edup
Hacker Grey
16.12.2013, 15:35
Сразу скажу - такты не считал.
Но попробуй - может так быстрее будет ?
pop hl
rr h
rr l
ex af,af'
rr h
rr l
ex af,af'
push hl
dec sp
dec sp
(или INC sp - смотрю куда крутить ну и RR или RL)
introspec
16.12.2013, 20:18
Сразу скажу - такты не считал.
Но попробуй - может так быстрее будет ?
Решение alone или моё - 42 такта на байт. У jerri чуть быстрее - 38 тактов на байт + таблица. Новое предложенное решение - 72 такта на 2 байта (36 тактов на байт), т.е. новый рекорд по скорости, причём без дополнительных затрат по памяти :)
Alex Rider
16.12.2013, 20:49
Круто, спасибо! Но переделывать уже поздно :) Во-превых, заоптимизил остальное, что мешало во фрейм уложиться. Во-вторых, сузил область скролла. В третьих, отправил готовое на сборку уже :) Буду иметь в виду сей фокус.
pop hl
rr h
rr l
ex af,af'
rr h
rr l
ex af,af'
push hl
dec sp
dec sp
pop hl
rr h
rr l
ex af,af'
rr h
rr l
ex af,af'
ld (nn),hl
же :)
Потестил, с ADC не получается :(
Но, можно так:
LD C,(HL) ; 7
RL C ; 8
RLA ; 4
RL C ; 8
RRA ; 4
LD (HL),C ; 7
38 тактов на байт, без таблицы.
denpopov
27.05.2014, 07:42
некий слоупочный скроллер вышел, 44(или 48?)такта на байт.
нутром чую, что можно оптимизировать, но быстрее не выйдет.
А чего его дергает то? :rolleyes:
Ой, чё за жесть внутри? :v2_dizzy_facepalm:
denpopov
27.05.2014, 08:16
А чего его дергает то?
ничо не дергает вроде.
Ой, чё за жесть внутри?
киде?
denpopov, а чем тебе идеи предложенные ранее не понравились?
denpopov
27.05.2014, 10:31
denpopov, а чем тебе идеи предложенные ранее не понравились?
просто давно видел тему, возникла идея. Теперь выходит, что скроллить можно на 2-7 точек.
вот только как выводить букву - это вопрос
introspec
27.05.2014, 11:12
38 тактов на байт, без таблицы.А почему 4 такта DEC L не посчитал? :)
Просто как вариант. В лоб, без таблиц и стека.
Скролл на 3 бита(пикселя)
46 тактов на байт.
LD C,$F8
....
LD A,(HL)
RLCA
RLCA
RLCA
LD E,A
XOR D
AND C
XOR D
LD (HL),A
DEC L
LD A,(HL)
RLCA
RLCA
RLCA
LD D,A
XOR E
AND C
XOR E
LD (HL),A
DEC L
LD HL,$401f
LD BC,$8f8
loop
LD A,(HL)
RLCA
RLCA
RLCA
LD D,A
AND C
LD (HL),A
DEC L
DUP 15
LD A,(HL)
RLCA
RLCA
RLCA
LD E,A
XOR D
AND C
XOR D
LD (HL),A
DEC L
LD A,(HL)
RLCA
RLCA
RLCA
LD D,A
XOR E
AND C
XOR E
LD (HL),A
DEC L
EDUP
LD A,(HL)
RLCA
RLCA
RLCA
LD E,A
XOR D
AND C
XOR D
LD (HL),A
LD DE,256+31
ADD HL,DE
DEC B
JP NZ,loop
denpopov
27.05.2014, 16:29
Скролл на 3 бита(пикселя)
а значение D?
Скролл на 3 бита(пикселя)
46 тактов на байт.
RLD: DEC L
+
RR (HL):INC L
=
41 такт на байт.
pop hl
rr h
rr l
ex af,af'
rr h
rr l
ex af,af'
ld (nn),hl
же :)
Это 33 такта на байт (кстати, перепутаны местами h и l).
А почему не 32 такта на байт:
POP HL 10
POP DE 10
RR L 8
RR H 8
RR E 8
RR D 8
EX AF,AF' 4
RR L 8
RR H 8
RR E 8
RR D 8
EX AF,AF' 4
LD (nn),HL 16
LD (nn),DE 20
Или даже 31.6 такта на байт:
POP HL 10
POP DE 10
POP BC 10
RR L 8
RR H 8
RR E 8
RR D 8
RR C 8
RR B 8
EX AF,AF' 4
RR L 8
RR H 8
RR E 8
RR D 8
RR C 8
RR B 8
EX AF,AF' 4
LD (nn),HL 16
LD (nn),DE 20
LD (nn),BC 20
Теоретически, на практике не проверял.
Сдвиг на 3 бита самый медленный :( Уж лучше таблицами.
---------- Post added at 07:32 ---------- Previous post was at 07:26 ----------
Titus, Ради спортивного интереса буду раз если поковыряешь моё творчество
http://zx-pk.ru/showthread.php?t=23544
Может есть идеи как оптимизировать?
Сдвиг на 3 бита самый медленный :( Уж лучше таблицами.
У меня на два же)
---------- Post added at 05:37 ---------- Previous post was at 05:33 ----------
Titus, Ради спортивного интереса буду раз если поковыряешь моё творчество
http://zx-pk.ru/showthread.php?t=23544
У тебя много ограничений.
Стек не используешь, а это золотое дно в ускорении.
Таблиц тоже используешь по минимуму, хотя памяти у тебя 128Кб.
Titus, это версия без таблиц. К сожалению оказалось менее универсальной и более тормозной для разно размерных спрайтов, если в неё внедрять изменение длины спрайта "на лету". Использовать стек, я думал.. но выходило тормознее.
Сейчас уже, в текущей версии кода, я всё переделал под таблицы и стек. По скорости одинаково вышло.
Просто основной приём, сдвига на 3 интересный получился за счет уже сдвинутого на 1 копирования в буфер скролирования :)
Дальше применяем RLD или RRD и получаем сдвиг на 3 более быстрый чем делать RL (HL). Жаль, что RLD/RRD не работают в регистрах.
Сейчас уже, в текущей версии кода, я всё переделал под таблицы и стек. По скорости одинаково вышло.
Чего ж ковырять то, что уже устарело) Надо ковырять актуальное)
Titus, в актуальном баланс между размером и скоростью главное. Была бы возможность строить мегакод для спрайтов в локации... но её нет.
Barmaley_m
09.04.2015, 22:57
Или даже 31.6 такта на байт:
POP HL 10
POP DE 10
POP BC 10
RR L 8
RR H 8
RR E 8
RR D 8
RR C 8
RR B 8
EX AF,AF' 4
RR L 8
RR H 8
RR E 8
RR D 8
RR C 8
RR B 8
EX AF,AF' 4
LD (nn),HL 16
LD (nn),DE 20
LD (nn),BC 20
Можно еще задействовать альтернативные регистры (EXX). И тогда может оправдять себя переставление SP (LD SP,nn) и запись в память через PUSH.
В пределе имеем (при неограниченном кол-ве регистров):
2x RL r - 16 тактов на байт
1x PUSH rp, 1xPOP rp на каждые 2 байта, 21/2=10.5 тактов на байт
поэтому любой алгоритм такого типа не сможет сделать быстрее, чем 26,5 тактов на байт. Это без учета установок SP, без учета EXX.
Но даже и с такой оптимистической скоростью, если скроллить одну треть экрана - то это будет более 54272 тактов. За один фрейм больше, чем 1/3 экрана, не проскроллишь.
Поэтому я думаю, что в реальных играх и демах нужно использовать трюки, создавать иллюзию скролла, а не сам скролл. Типа как в Sea Dragon тайловая графика.
Можно еще задействовать альтернативные регистры (EXX). И тогда может оправдять себя переставление SP (LD SP,nn) и запись в память через PUSH.
Нет, не оправдает. Попробуй напиши и рассчитай, сколько получится тактов.
Barmaley_m
10.04.2015, 16:21
Нет, не оправдает. Попробуй напиши и рассчитай, сколько получится тактов.
Пишем (скролл влево):
LD SP,nn ;10
POP HL ;10
POP DE ;10
POP BC ;10
RL H ;8
RL L ;8
RL D ;8
RL E ;8
RL B ;8
RL C ;8
EXX ;4
POP HL;10
POP DE ;10
POP BC ;10
RL H ;8
RL L ;8
RL D ;8
RL E ;8
RL B ;8
RL C ;8
EXX ;4
EX AF,AF' ;4
RL H ;8
RL L ;8
RL D ;8
RL E ;8
RL B ;8
RL C ;8
EXX ;4
RL H ;8
RL L ;8
RL D ;8
RL E ;8
RL B ;8
RL C ;8
EX AF,AF' ;4
PUSH BC ;11
PUSH DE ;11
PUSH HL ;11
EXX ;4
PUSH BC ;11
PUSH DE ;11
PUSH HL ;11
Этот фрагмент обрабатывает 12 байт. Растактовка:
На POP - 6*10 = 60 тактов
На PUSH - 6*11 = 66 тактов
На LD SP - 10 тактов
На EXX - 4*4 = 16 тактов
На EX AF,AF' - 2*4 = 8 тактов
На RL - 12*2*8 = 192 такта
Всего 352 такта
На каждый байт - 29 + 1/3 тактов в среднем.
Хоть 4 команды EXX сжирают 16 тактов, а одна LD SP - 10 тактов - то кажется, что без EXX будет быстрее. Однако, если делать блоками по 6 байт без EXX - то будет:
POP - 3*10 = 30
PUSH - 3*11 = 33
LD SP - 10
EX AF,AF' - 8
RL - 6*2*8 = 96
Всего - 177
На каждый байт - 29.5 тактов в среднем. Чуть больше.
Причина в том, что при обработке блоками по 12 байт встречается в 2 раза меньше команд EX AF,AF' в среднем. То есть с EXX потеря 6 тактов на EXX, однако выигрыш 8 тактов на EX AF,AF'. В конечном счете выигрыш в 2 такта.
Barmaley_m, круто)
Делай, пожалуйста, демы)
Barmaley_m, не работает. вся строка на 3 не сдвигается.
У меня как-то так получилось:
58 тактов / байт
LD HL,#401F
DUP 32 ; SCROLL 3
LD C,(HL)
RL C
EX AF,AF'
RL C
EX AF,AF'
RLA
RL C
RRA
LD (HL),C
DEC L
EDUP
Стековый вариант 57,5 тактов на байт :)
Если использовать прямую адресацию LD HL,(nn) / LD (nn),HL — получим 56 тактов на байт.
LD (STACK+1),SP
LD HL,#401E
DUP 16 ; SCROLL 3
LD SP,HL
DEC L
DEC L
POP DE
RL D
EX AF,AF'
RL D
EX AF,AF'
RLA
RL D
RRA
RL E
EX AF,AF'
RL E
EX AF,AF'
RLA
RL E
RRA
PUSH DE
EDUP
STACK:
LD SP,#0000
Если пишем стеком LD HL,(nn) / PUSH HL немного быстрее будет — 53,5 такта на байт.
ADR=#401E
LD (STACK+1),SP
LD SP,#4020
DUP 16 ; SCROLL 3
LD HL,(ADR)
RL H
EX AF,AF'
RL H
EX AF,AF'
RLA
RL H
RRA
RL L
EX AF,AF'
RL L
EX AF,AF'
RLA
RL L
RRA
PUSH HL
ADR=ADR-2
EDUP
STACK
LD SP,#0000
Вариант без EX AF,AF', по скорости одинаково.
ADR=#401E
LD (STACK+1),SP
LD SP,#4020
DUP 16 ; SCROLL 3
LD HL,(ADR)
RL H
RLA
RL H
RLA
RL H
RRA
RRA
RL L
RLA
RL L
RLA
RL L
RRA
RRA
PUSH HL
ADR=ADR-2
EDUP
STACK
LD SP,#0000
Если на 3 надо первым проходом rld вторым rr обратно. Хотя все это не актуальные извраты имхо.
Этот пример тут был уже, тоже нерабочий.
Этот пример тут был уже, тоже нерабочий.
Разве может Alone дать нерабочий пример)
Бармалей написал пример скроллинга на 2, а не на 3.
Разве может Alone дать нерабочий пример)
Бармалей написал пример скроллинга на 2, а не на 3.
У меня он чё-та не заработал. Как им строку сдвинуть в 32 байта на 3 точки влево? :)
Там ошибка, вот правильно:
37 тактов байт.
DUP 32 ; SCROLL 3
RLD
RR (HL)
DEC L
EDUP
Barmaley_m
11.04.2015, 22:45
У меня он чё-та не заработал.
Не понял, что не заработало, где ошибки?
Как им строку сдвинуть в 32 байта на 3 точки влево? :)
Тема о сдвиге на 2 точки. Мой код свигает на 2.
То, что 32 не делится на 12, означает, что надо двигать две группы по 12 и потом еще одну группу из 8 байт. Получить на базе моего кода сдвиг укороченной группы из 8 байт - задача несложная. Ее я оставил в качестве домашнего задания тем, кому это интересно.
Ну и вообще уже не раз было сказано, что, даже если сдвигать всю информацию чисто на регистрах, 8 тактов на сдвиг одного байта на один бит - это слишком много. Фреймового скролла на 2 пиксела на полный экран не получится. Почитайте все тему разработки Sea Dragon. Там было рассмотрено много разных вариантов, в итоге от "честного" скролла отказались в пользу тайловой графики.
То есть это правильно, а у алона ошибка? Мда...
Сам проверь.. DEL L после RR надо и всё.
RLD: DEC L
+
RR (HL):INC L
=
41 такт на байт.
---------- Post added at 11:49 ---------- Previous post was at 11:45 ----------
Не понял, что не заработало, где ошибки?
Вроде как читать стеком POP xx и записывать PUSH xx подходит для сдвига вправо RR x. Для сдвига влево читать с конца нужно, POP не годится, т.к. увеличивает SP на 2.
krt17, видимо значит мой вариант c RLD не рабочий... :)
krt17, Ага, я уже протестировал. Ну сами по себе команды RRD/RLD не особо удобные. Наверное можно придумать чтобы одним проходом сдвигалось на 3, но в ущерб скорости :)
Вспомнил еще один прикольный метод на 40 за байт
dec e, вообще-то)
---------- Post added at 14:27 ---------- Previous post was at 14:11 ----------
krt17, тебе тоже надо демы писать)
krt17, с таблицами всё прозрачно. Надо родить скролл влево на 3 точки в один проход с помощью команды RLD :)
Все мои демы на бумажке в тетрадке,а зачастую и просто в голове;), дальше не интересно.
Не уподобляйся мне, воплощай в реал)
Прикинул со стеком и табличкой в раскладке получается 36, но это уж совсем кощунство.
Выкладывай для всех свое кощунство)
По итогу 38 с табличкой на 3*8*#100 по скорости победитель, если я опять ничего не пропустил.
Пропустил) как на счет записи результата из А в регистры?
Да тут вообще полный крах и позор. Стирать не буду пусть останется как клеймо. Но 38 это я про другую говорил
ld a,(de)
ld l,a
ldd
dec h
ld h,(hl)
Это было написано еще до рома, все четко, вариант с ldd так сказать.
В начале темы jerry выкладывал сходную:
ld bc,head_table
dup nn
ld a,(de)
ldi
ld l,a
ld h,b
ld h,(hl)
edup
Судя по тому что никто не исправил, никто и не вникал как работает.
Суть и так понятна, но, видимо, действительно никто не вникал)
Barmaley_m
12.04.2015, 21:14
Вроде как читать стеком POP xx и записывать PUSH xx подходит для сдвига вправо RR x. Для сдвига влево читать с конца нужно, POP не годится, т.к. увеличивает SP на 2.
Какая разница, если в начале каждого блока стоит команда LD SP? Главное - что PUSH и POP читают и записывают в непрерывный блок памяти. Поэтому в этом месте моего кода ошибок нет.
Да похоже, но помечена примерно и не работает. ldi нужно после ld l,a. А так вообще отлично и табличка меньше. Судя по тому что никто не исправил, никто и не вникал как работает.
ну и сдвигает она вправо. :)
Alex Rider
14.04.2015, 02:09
Блин, вашу бы фантазию тогда, когда Heart Megademo писалась! Про скролл на 3 пикселя я вообще тогда не думал, казалось, что там и во фрейм для одной строчки не уложишься :)
очередной буржуйский эксперимент (на 48к)
http://savepic.su/6311284.png
при нажатии любой клавиши - бежит быстрее
FF нужен, для наших уже давно пройденный этап, движок на примитивном пушере не писал только ААА
ААА - расшифровывается легко.
А что такое FF? 255? Или может Final Fantasy?
А что такое FF?
LD BC,#40FF
LD E,#04
L8045: LD A,R
IN A,(C)
CP E
JP NZ,L8045
А почему порт FF адресуют шестнадцатибитно 40FF? В этом есть смысл?
SoftFelix
29.10.2015, 00:18
очередной буржуйский эксперимент (на 48к)
А сложно из этого SNA сделать SCL или TRD? Хотелось бы потестить на КАЕ с его портом #FF.
А почему порт FF адресуют шестнадцатибитно 40FF? В этом есть смысл?
"The address of the port being accessed is placed on the data bus. If this is in the range 0x4000 to 0x7fff, the ULA treats this as an attempted access to contended memory and therefore introduces a delay"
http://www.worldofspectrum.org/faq/reference/48kreference.htm#IOContention
NEO SPECTRUMAN
29.10.2015, 00:37
Кстати какой смысл в LD A,R? Может он есть?
может для выравнивания по тактам? :v2_conf2:
не так много способов получить 9 тактовую задержку
только зачем тогда ничему не кратный 35 тактный цикл :v2_happy:
Охохо, trdos нужен, сорри
попробуй сохранить блок ->32768,32768
Как насчет того, чтоб не сдвигать на 2 бита, а иметь четыре варианта знакогенератора (уже сдвинутый фонт на 0, 2, 4 и 6 бит) и каждый раз выводить с использование очередного варианта фонта?
Как насчет того, чтоб не сдвигать на 2 бита, а иметь четыре варианта знакогенератора (уже сдвинутый фонт на 0, 2, 4 и 6 бит) и каждый раз выводить с использование очередного варианта фонта?
Так и делают)
http://savepic.su/6307760.png
вариант мультиколорного движка.
заточен под фирменный 48к,(ГГ двигается сам)
Powered by vBulletin® Version 4.2.5 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot