Насколько понял, восстановление фона под спрайтами не производится, вместо этого перерисовывается весь экран (фон) целиком.
Зато не понял, почему при ширине экрана 80 байт пересылаются только 78. Или так и задумано?
Предположил, что крайний ряд является буфером скроллера, но идет же просто пересылка без сдвигов. Непонятно.
Указано, что карта лежит рядами по 78 байт. А почему так? Она еще и вверх-вниз может скроллиться в игре?
Или откуда эта цифра в 78 байт? Поподробнее о формате хранения куска карты в странице, если можно.
Начнем оптимизировать)) Первое, что сразу бросается в глаза: очень много лишних действий внутри циклов вывода строк.
Скажем, каждый раз вычисляется один и тот же адрес для IX, хотя задавать его нужно всего один раз _перед_ циклом.
Для пар IX/IY обмен с памятью жрет много + тут в цикле берем адрес из таблицы, - огромные потери, около 100 тактов на линию.
Перебрасываем 160 линий, 160х100=16000, если кусками лево-право (работают оба цикла) - уже 32000, это только приблизительно.
Убрав одно лишь задание IX внутри каждого цикла, можно выкинуть кусок кода в красной скобке. Стрелки - команды для оптимизации.
Второе: внутри каждого цикла по две команды LD BC,(nn) - очень расточительно в плане затрат времени. Выделено стрелками.
Команды LD BC/DE,(nn) и обратные - LD (nn),BC/DE - жрут на 4 такта и на байт больше памяти, чем такие же с HL,
поэтому везде, где можно, желательно для обмена с памятью использовать пару HL. Это общая рекомендация для любого кода.
Конкретно в этом примере чтение BC еще и вставлено в цикл, причем циклов два (левый и правый столбец) - теряем много тактов.
Напрашивается прямая загрузка в регистры вместо косвенной (из памяти), размещая переменные сразу в коде циклов.
Теперь посмотрим, как избавиться от таблицы переходов по цепочкам LDI, да и от шести килобайт с этими цепочками заодно.
Целых 6 кило места, которого и так вечно не хватает - слишком жирно. Есть способ скользить по коду намного проще.
Размещаем цепочки LDI с максимальной длиной строки (78) прямо в циклах, заодно убрав схему возврата (LD BC,nn:PUSH BC:RET)
и повторную загрузку после них BC из PrintMapCol, которая станет не нужна, т.к. IX будем задавать перед циклом:
dup и edup с числом - директивы для повтора строк кода между ними, могут зависеть от конкретного ассемблера.Код:dup 78 ldi edup
Процедур две (для левой и правой части), поэтому цепочек с LDI тоже будет две. 2 по 160 байт всяко лучше, чем 6 кило.
Осталось переделать обе процедуры "прыжка" в нужное нам место, и возврат по RET отпадает за ненадобностью.
Ниже новый листинг. Все исходные переменные в шапке оставил, но MapLeftPart, MapRightPart и PrintMapCol2 не используются.
Можно еще поиграть с размещением переменных из шапки в коде, но они будут вне циклов - на скорости уже не скажется.
Скрытый текст
Код:BaseScrAddr equ #c000 ;адрес экрана RightCol equ #4d ;последний столбик справа (#4d=77) MapLeftPart dw 0 ;число столбцов в левой части экрана для карты - не нужна, переделана в skip_L MapRightPart dw 0 ;число столбцов в правой части экрана для карты - не нужна, переделана в skip_R PrintMapPag db 0 ;страница памяти с которой начинается карта PrintMapCol dw 0 ;номер текущего столбика для печати PrintMapCol2 dw 0 ;количество столбцов для переноса справа - не нужна, вычисляем IX до цикла PrintMapAddr dw 0 ;текущий адрес карты MapPrintTable ;эти две переменные больше не нужны MapPrintCode ;т.к. убираем таблицу адресов и цепочки LDI ;печать готовой карты из памяти MapPrint ld a,(PrintMapPag) ;включаем нужную страницу call PageSlot2G ld hl, (PrintMapAddr) ld de, BaseScrAddr ld bc, (PrintMapCol) ;ширина левой части inc c dec c jp z,MapPrint3 ;если C=0, левую часть не рисуем. !JP вместо JR ld a,80 sub c ld (skip_R+1),a ;ширина пропуска правой части rlc c ;умножаем на 2 (LDI - 2 байта) ld ix,MapPr_L+2 ;адрес начала строки LDI'шек add ix,bc ;получаем в IX адрес прыжка ld a,160 ;кол-во строк MapPr_L jp (ix) ;начало цикла левой части dup 78 ldi ;перенос edup skip_R ld bc,0 ;в C загружена ширина пропуска, B=0 ex de,hl add hl,bc ex de,hl add hl,bc dec a jp nz,MapPr_L ;JP вместо JR, т.к. команды LDI развернуты в цикле - у JR не хватит смещения MapPrint3 ;печать (или не печать) правой части из след. страницы ld a,(PrintMapCol) cp RightCol+1 jp z,MapPrintE ;!JP вместо JR. А по уму достаточно команды RET Z ld a,(PrintMapPag) ;включаем нужную страницу inc a call PageSlot2G ld hl,(PrintMapAddr) ld de,BaseScrAddr ;или ld d,BaseScrAddr/256 (нам нужен только старший байт) ld bc,(PrintMapCol) ld e,c ld b,0 ld a,78 ;сразу отнимаем 2, зачем лишняя команда (sub 2) sub c rlca ;умножаем на 2 ld c,a ;смещение для jp (ix) ld ix,MapPr_R+2 add ix,bc ld a,80 sub l ld (skip_L+1),a ;пропуск левой части ld l,b ;b=0 ld a, 160 MapPr_R jp (ix) ;начало цикла правой части dup 78 ldi edup skip_L ld bc,0 ex de,hl add hl,bc ex de,hl add hl,bc dec a jp nz,MapPr_R ;JP вместо JR MapPrintE ; можно удалить метку и RET, если ниже MapPrint3 поставить RET Z вместо JP Z ret[свернуть]
Процедура обсчета следующей строки (do_scroll_new) остается без изменений.
Что еще добавить... код не проверялся (набивался в блокноте), возможны глюки =)) Если возникнут вопросы - задавай.
И все равно непонятна фишка с числом 78. Не запуская код и не имея представления о схеме карты. Прошу разъяснить.





Ответить с цитированием
Размещение рекламы на форуме способствует его дальнейшему развитию 

Scorpion ZS 256 Turbo+/GMX 2MB/SMUC v1.3 OP/CF-IDE 2GB/TS ARM/Covox #DD/FDD 5'25/FDD 3'5/AT Kbrd & Mouse Ctrl v2.5/Universal PS/2 Kbrd Ctrl/ZX WiFi