PDA

Просмотр полной версии : Попиксельный скролл на Асме



helcril
15.12.2009, 14:29
Доброго времени суток, камрады!

Намедни решил поразминать свой изрядно отупевший мозг. :v2_wacko:
Инструментом для этого выбрал старый добрый Спектрум, а именно программирование на асме для Спектрума. :v2_thumb:

Вдохновившись книжкой "Как написать игру на ассемблере" и разобравшись с парой примеров из сего интересного опуса, задумал написать программку-скроллер.
Т.к. код (читай алгоритм) , предложенный в книге, моему скудному уму не поддался, то решил написать все с чистого листа (пока используя приемы из этой книги).

И вроде бы все получилось... Но!
Заковыка в том, что текст-то мой скроллится, но как только он "проезжает" один экран - ряды пикселов изображения постепенно начинают исчезать.

В общем, прошу прощения за столь длинное предисловие, теперь - к делу. Вопросы знатокам (или не очень знатокам) таковы:
1. Как избежать этого безвозвратного сдвига нужных пикселов (я так полагаю, что исчезают они из-за моего совершенно беспредельного их двиганья по памяти)?:v2_conf2:
2. Куда они собственно деваются? Т.е. продолжают ли они существовать где-то в памяти во время выполнения моего быдлокода?:v2_conf2:

В приложении образ TRD и листинг программы...
Заранее спасибо за ответ!:v2_clapp:

ЗЫ: Слезно прошу изъясняться так, как будто рассказываете что-то дебилу. Желательно с примерами и, как говорится "на пальцах" :v2_biggr: так как человек я скорее гуманитарного склада, и для меня многие элементарные вещи неочевидны! :v2_blush:
ЗЗЫ: Компилятор - ASAM, Эмулятор - Spectaculator.

GM BIT
15.12.2009, 15:07
Усли надо чтоб просто уползало добавляем в основной цикл AND A

loop push hl ; save address

ld b,8 ; set counter = 8 pixel rows
scrl1 push bc
push hl

AND A ;что бы слева выехал пустой пиксель!!!!!!!!!!!!!!!!!!

ld b,32 ; set counter = string lenght
scrl2 rr (hl) ; shift data in memory
inc l ; next symbol
djnz scrl2

pop hl ; recover hl

inc h ; next pixel row
pop bc ; recover counter
djnz scrl1

pop hl ; recover address
call pause
jp loop



А если нужна ротация строки, то добавляем пару команд

loop push hl ; save address

ld b,8 ; set counter = 8 pixel rows
scrl1 push bc
push hl

AND A

ld b,32 ; set counter = string lenght
scrl2 rr (hl) ; shift data in memory
inc l ; next symbol
djnz scrl2

pop hl ; recover hl

jr nc,$+4 ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
set 7,(hl) ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

inc h ; next pixel row
pop bc ; recover counter
djnz scrl1

pop hl ; recover address
call pause
jp loop

эти две команды для того, что если справа есть точка и она заехала за экран то она появляется слева
Ну что то вроде того

helcril
16.12.2009, 08:41
Про "AND A" я вроде все понял. И да, строчка "уезжает" как положено.
Но хочется, чтобы строчка эта крутилась и крутилась. :v2_smile:
Попробовал добавить предложенные вами строчки в программу - заработало!!!
Поясните, пожалуйста, что это за "$+4" и "set 7,(hl)"? ну всмысле логику работы данного участка кода.
Спасибо за помощь!:v2_clapp:

GM BIT
16.12.2009, 09:17
jr nc,$+4 - проверяем флаг переноса (или заехала ли правая точка за экран), если его нет то перепрыгиваем следующую команду иначе ставим точку слева в строке командой set 7,(hl)

helcril
17.12.2009, 02:33
И снова спасибо, но вот что такое "$+4"? И как это связано с "заездом за экран"? :v2_conf2:
Еще вопрос: в вашем треде "Пишем на ассемблере под эмулятором" был пример скролла. Так вот там использовался какой-то интересный шрифт. Как это получилось?
Кстати предложенная вами связка "спектакулятор+кримсон+асам" очень понравилась, довольно удобно. :v2_thumb:

psb
17.12.2009, 03:22
что такое "$+4"?
$ - значит адрес текущей инструкции, т.е.

label:
jr nc,$+4 ;2 байта
set 7,(hl) ;2 байта
label2:

это означает, что если CY сброшен, то пропустить set 7,(hl).
т.е. $ будет равен label, а $+4=label2.

например, jr $ зациклит программу.

GM BIT
17.12.2009, 04:32
Так вот там использовался какой-то интересный шрифт. Как это получилось?
Там взят стандартный шрифт из ПЗУ смещен на один пиксель и наложенный на него же:

not_end ld l,a
ld h,0
add hl,hl
add hl,hl
add hl,hl
ld de,#3c00
add hl,de ;находим символ в ПЗУ
ld de,buff
ld b,8 ;цикл перебрасывает 8 байт символа из ПЗУ в buff
loop2 ld a,(hl) ;берем байт из ПЗУ !!!!!!!!!!!!!!!!!!!!!!
rrca ;сдвигаем вправо на один пиксель !!!!!!!!!!!!!!!!!!!!!!!!!!!!
or (hl) ;совмещаем наложением сдвинутый и нет !!!!!!!!!!!!!!!!!!!!!!!!!!!!
ld (de),a ;кладем получившийся результат !!!!!!!!!!!!!!!!!
inc l
inc de
djnz loop2
ret

helcril
17.12.2009, 08:07
Спасибо всем за помощь!
А вообще, может посоветуете какие-нибудь книжки (кроме уже упомянутой мной "Как написать игру на Ассемблере") по Ассемблеру Z-80 для начинающих? Интересует именно "развлекательная" тематика, т.е. какие-нибудь подобные "скроллеры", примитивные демки, игрушки...

jerri
17.12.2009, 09:31
нууу почитай ZX Ревю и всякое здесь (http://trd.speccy.cz/book.htm)