Почитай просто руководство к Alasm. Получишь примерное представление о возможностях современных (и не только) компиляторов.
Вид для печати
В этой процедуре если и оптимизировать то оптимизировать по занимаемому месту под "генерилку".
В самой процедуре прорисовки можно только если добавить сохранение стёка по другому. :v2_wink2:
вывзов экранрефрешэра:
ld (refresh1+1),sp
jp refresh ;рефреш экрана
refresh1 ld sp,#3131
ret
refresh ld sp,#c014
pop hl,de,bc,af
exx: exa
pop hl,de,bc,af
.... ну и так далее только в конце
jp refresh1
Проблема только в том что под одну экранстраницу будут передёргивания (луч перегонит рефрешер экрана).
Неуверен что процедура генератора стала короче, но понятней немного должна стать :v2_wink2:
По поводу сдвига советую пересмотреть тогда сам внутренний экран таким образом чтобы "передвигать" по оси y или x можно было путём увеличения указателя на экран на ширину или 1 байт. Идеальный вариант сделать ширину строки 32байта, тогда сдвиг вправо будет просто инкремент указателя на 1, влево соответственно декремент а вниз или вверх на 256.
(inc/dec l - по оси x, inc/dec h - по оси y)
но тогда надо при выводе либо следить за стёком чтобы неулетел за границу 256байт либо использовать ld a,(hl): ld (de),a: inc l: inc e
Кстати, кидать данные через стек можно и с использованием прерываний. Я подсмотрел у Медноногова в исходниках Черного Ворона.
Вот тут мои исходники http://zx.pk.ru/showpost.php?p=32815&postcount=60
Мое замечание по слову "номеров". Скорость уже увеличится, если эти номера заменить реальным адресом тайла. Я так делал в Вере. Хотя сначала хранил именно номера, по которым потом высчитывался адрес - а это опять ведь тормоз... Хотя у меня тайлов было 512 и номера были двубайтовыми, потому замена их на адреса никак не сказалась на длине карты.
А кто помнит в чём там трюк с восстановлением данных при вызове прерывания? Ведь графика по-любому затрется адресом возврата при поступлении прерывания... Если только каждый блок перед выводом где-то отмечать, а в обработчике прерывания заново переписывать из резервного хранилища...
если данные забираются через стек допустим в DE, то когда будет переход по im2 первым делом на то место куда впечатался адрес возврата пишут то что в DE
Код:на прерваниях вот такая конструкция
ex (sp),hl ;сохраняем содержимое HL и забираем адрес возврата
ld (im_jmp0),hl ;сохраняем его для возврата из прерывания
pop hl ;восстанавливаем содержимое HL
ld (im_sp0),sp ;сохраняем содержимое стека для возврата
push bc ;восстанавливаем поврежденную графику
;все процедуры вывода спрайтов и графики
;оптимизированы для сохраниния данных таким способом
ld sp,im_stek ;дальше работаем в стеке прерывания
push hl,de,bc,af ;сохраняем основной набор регистров
;если потребуется сохранить остальные (требуется при
;проигрывании музыки), то их можно сохранить тут
call im_proc
pop af,bc,de,hl ;восстанавливаем регистры
ld sp,$ ;стек
im_sp0 equ $-2
ei ;статус прерываний
jp $ ;возвращаемся по раннее сохраненному адресу
im_jmp0 equ $-2
для спрайтов можно придумать похожее или например вотКод:а на прерываниях например вот такая процедура вывода BG
ld hl,-6
add hl,sp
ld (tile_sp0),hl
ld hl,draw_buf
ld de,#4058
draw_bbuf1
xor a
draw_bbuf0
or (hl)
call nz,draw_tile
inc l
jp nz,draw_bbuf0
inc h
inc e
ld a,d
add a,8
ld d,a
cp #58
jp c,draw_bbuf1
ret
draw_tile
push hl,de
dec a
jp nz,draw_modded
ld (hl),a
;restore background
ld bc,back_tls-draw_buf
add hl,bc
ld c,l
ld l,(hl)
ld b,e
ld e,c
ld h,font_c/256
ld a,(hl)
ld (bc),a
ld h,font_d/2048
draw_tile0
add hl,hl
add hl,hl
add hl,hl
ld c,(hl)
inc l
ld b,(hl)
inc l
ld sp,hl
ex de,hl
dup 3
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
edup
ld (hl),c
inc h
ld (hl),b
ld sp,$
tile_sp0 equ $-2
pop de,hl
xor a
ret
самое главное это контролировать во время отрисовки регистр в котором забираешь спрайтКод:ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld (draw_sp0),sp
ld sp,hl
dup 8
ld a,(de)
or c
xor b
ld (de),a
inc de
pop bc
edup
Отличная игра получилась! А расскажи, как выбирал эти адреса и выводил на экран? Использовал буфер или напрямую? Как я понял, 512 тайлов 2*16 занимают 16КБ. Располагал их в #8000 или в #c000? Где хранилась карта?
Тут обсуждают по большей части вывод тайла, но имхо не хватат обсуждения полного цикла с выборкой из карты. Ибо все "быстрые" способы могут разбиться об накладные расходы на переключение sp. Нужен комплексный разбор.
зы. Ничего что я на ты?
- - - Добавлено - - -
Спасибо за примеры!
Решил пока вопрос восстановления данных отодвинуть на второй план. Сейчас думаю как побыстрее вывести фон на экран. Задача усложняется выводом со смещением. Возможно ли вывести тайловый экран со смещением по горизонтали на несколько пикселей хотя бы за 100 Килотактов (Кт)? Интересует полный цикл от выборки из карты до вывода на экран. У меня пока получается порядка 150Кт при размере тайла 3*16Б и средней заполненности экрана от 1 до 4-х одинаковых тайлов подряд. Графику читаю стеком, на экран вывожу по (hl)
«змейкой». Если делаю чтение и запись стеком, то получается дольше из-за накладных расходов на переключение sp, плюс не хватает регистров. Но теоретически предел метода (sp)=>(hl) (pop rp; ld (hl),r;inc l = 5+7+4=16t/Б) больше чем (sp)=>(sp) (pop rp; push rp = 5 + 5.5 = 11.5t/Б).