совершенно нету связи с поправкой
Если бы разворачивание цикла ничего не меняло, ты бы не поправлял мои 32-8*256 на свои 32-7*256.
разворачивание цикла ничего не меняет
какой смысл в оптимизации вообще, если не упарываться всерьёз? 8)

расстояние в таблице (для всего экрана) от первого нужного байта до последнего 16 байт
с заворачиванием или обрезкой по низу — еще плюс один байт, с обрезкой по верху — еще плюс 8
в твоём случае +7 байт на обработку перехода с обратным jr и больше без него (дубль хвоста)
еще больше с проверкой обрезки, еще больше с заворачиванием
Во-первых, мы пока ещё цикл не разворачивали.
Во-вторых, у меня некоторое недоумение. Уточни пожалуйста, сколько точно байт понадобится для таблицы во втором из твоих вариантов кода.
«Чуть помедленнее» — это jr + ld a,h: add 7: ld h,a + jr = 5+15+12 = 32 такта на каждой трети. 3*32т=96т. Ты сейчас всерьёз упарываешься из-за меньше чем 100 тактов?

И что означает «не факт ещё, что в сумме короче»?
статистически «общая» — всё же чуть помедленнее, и не факт еще, что в сумме короче
зато нужен лишний код для перехода сегмента, сопоставимый по размеру с таблицей

и да, чтоб не нужно было выполнять лишний inc, прибавлять следует 32-7*256
Ну т.е. общая скорость та же, что и во втором твоём решении.
Спасибо за напоминание, что у нас свободен DE! Но таблица не нужна совсем:
ld de,-8*256+32
add hl,de
bit 0,h : jr nz,.newthird
; 10+11+8+7 = 36t
Вариант без таблиц, но с разбросанными по памяти одиночными байтами, 55 тактов:

    ld b,c
    add hl,bc
    ld b,h
    ld a,(bc)
    ld h,a


Вариант с байтами, собранными рядом в мини-табличку, 57 тактов:

    ld de,$XX20
    add hl,de
    exd
    ld l,d
    ld h,(hl)

(регистр c здесь освободился под счётчик и -4 такта префикса учтены в сумме)
Ачо размер? Умеренный, как по мне, плюс еще и генерить очень быстро, где-то даже динамически будет выгодно. Развороту djnz перпендикулярно и не мешает, наоборот — даже чуть проще и быстрее станет после него.
Ты конечно знатный извращенец. Действительно, с таблицами такого размера спрайты на полэкрана для тебя и правда фантастичны. На каждом ряде знакомест вместо 67 тактов у тебя выходит 4+11+7+7+8+10 = 47 тактов. 24*20т = 480т (на самом деле, меньше, из-за обработки хвоста). Я бы не стал так делать. Разворот DJNZ даст намного больше скорости и займёт намного меньше памяти.

Но я рад любым идеям, потому что, как ты знаешь сам, приходит день и всё это обязательно пригождается, м.б. в каком-то другом виде.
А если так? ;)

        ...

_main1: inc h
_main2: ...
        djnz _main1
        ld b,c        ; c = $20
        add hl,bc
        ld h,(hl)     ; таблицы кусками по 256 байт @ ... $6700, $6800, $6F00, $7000, $7700 ...
        ld b,8
        dec xl        ; счётчик символьных строк вместо занятого c
        jp nz,_main2
        exa           ; zf сохранён на повторный приход сюда
        ld b,a        ; длина хвоста и флаги после and7 при первом входе
        jp nz,_main2  ; если ненулевой хвост и не повторно сюда попали

_end:   ld sp,0
        ret        


Это адаптация из опытов по быстрой отрисовке отрезка (где sp вместо bc применяется) — где-то рядом уже как-то упоминал. Хотя для реальных небольших спрайтов (а не фантастичных на полэкрана) разница по скорости незаметна. Более весомая выгода подобных таблиц на практике — бесплатный вертикальный wrap или clip (перенаправлением в ПЗУ) для окна из 1-3 сегментов.
  • avatar VBI
  • 0
Однозначно круто!
Ты у нас сейчас главный мультиколорщик, давай, делись!
Следующий шаг — постоянный по тактам down_hl без таблиц :)
Кроме того, RST7 предложил ещё один подход к реализации DOWN_HL, разбивающий счётчик строк в спрайте на два и в итоге ускоряющий DOWN_HL ещё в 2 раза. Это решение показано в только что добавленном приложении к статье.
Нам повезло получить комментарий по этому поводу от RST7:

«Я думаю, что регистр С надо использовать не для сохранения старшего байта, а в качестве счетчика до перехода на .nextchar. Т.е. в .nextchar будет

LD C,0xF8

a в основном цикле

INC H
INC C
JR Z,.nextchar

Ну и преинит

LD A,H
OR 0xF8
LD C,A

Оно, конечно, ухудшит вариант nextchar на 18 тактов, т.е. суммарно 21*18=378 тактов, но зато 168*7=1176 тактов выиграет на основном переходе.»
  • avatar sq
  • 0
Как же мы скучали!)