PDA

Просмотр полной версии : Пишу шедевр для «Вектора 06Ц»



Страницы : [1] 2

metamorpho
20.06.2020, 20:12
Привет всем!!

Моя цель - написать шедевр для «Вектора 06Ц» :)
Конечно при поддержке знатоков «Вектора».
Так вот здесь я буду задавать разные «глупые» вопросы - так что просьба к тем кто знает подскажите начинающему (в детстве у меня был "Вектор", ассемблер знаю только в общих чертах, в последние годы программирую на бейсике AppGameKit - есть несколько завершённых мной игр для Windows). Сейчас исследую Лебедева А.З. «Секреты Вектора» и «Код BoulderDash»

Для начала вот такие вопросы интересуют:
1. Посоветуйте какой ассемблер сейчас можно использовать чтобы написать игру для «Вектора» ?
На каком эмуляторе лучше всего тестировать результаты ?
2. Есть ли программы преобразования графики с PC в данные для вставки в ассемблер ?
3. Есть ли музыкальный редактор использующий ВИ53 и выдающий данные которые можно вставить в код игры и есть ли код который мог бы запускать эту мелодию ?
4. Аппаратным вертикальным скроллингом экрана можно сдвигать только сразу все (8000-FFFF) плоскости экрана или можно сдвигать их по отдельности ?
5. Как на ассемблере запретить использование плоскости экрана (на Бейсике «Вектора» команда Screen 2,n) и использовать эту память для кода игры ?
6. Какой архиватор данных эффективнее всего использовать в игре ?
7. Есть ли код который проигрывает мелодию для чипа AY ?

------------------------------------------------------------------------------------
Прошло 2 месяца
-------------------------------------------------------------------------------------



2 месяца и 4 дня.
Ну вот и пройден путь - моя цель достигнута - завершено написание моего первого "шедевра" для Вектора.
Спасибо всем кто так или иначе помогал мне написать эту игру.
Без ваших советов и информации я бы ещё наверное долго разбирался что к чему и писал код.
Было интересно осваивать ассемблер - в чём-то он конечно сложный, но несомненно очень гибкий и
мощный, по сути на нём можно сделать очень много невероятных програмных ходов - всё ограничивается
только техническими характеристиками компьютера и "высотой полёта" самого программиста :)
После такой практики написания игры заметил появилось некое "ассемблерное мышление", так что даже
когда программируешь на Бейсике, но мыслишь уже командами ассемблера :)
А также привычка повсюду экономить на количестве и на тактах команд :)

Что было сделано:
- написан конвертер графики с компьютера на Вектор06Ц (формат для вставки в ассемблер)
- написан редактор уровней, который выдаёт данные для вставки в ассемблер
- сделана графика для проекта
- написан свой вариант плеера для проигрывания музыки на ВИ53

Игру писал используя текстовый редактор "NotePad" и "Pretty 8080 Assembler" (спасибо за него svofski).

Некоторые технические моменты игры:
- используется аппаратный вертикальный скроллинг
- используется 8 цветов (3-и плоскости)
- музыка воспроизводится на ВИ53 (то что есть в любом стандартном Векторе)
В игре остались некоторые баги, но существенно на качество игрового процесса они не влияют.

Ассемблерный поход и Битва за байты.
Поскольку это мой первый проект на ассемблере, то я особо и не задумывался о том сколько памяти осталось
и поэтому большую часть кода писал не задумываясь об оптимизации и хитрых алгоритмах.
В результате под конец проекта возникли сложности с памятью - её стало нехватать.
Нехватало примерно 2200 байт. Пришлось бороться за каждые возможные байты.
В итоге пришлось отказаться от использования некоторой графики и придумывать способ сжатия
картинки на заставку, а также изменить на менее ресурсоёмкий способ хранения уровней.
Также изменить некоторый код - придумав более сокращённую версию алгоритма.
В этом есть какая-то штука, когда в стеснёных условиях памяти Вектора ты борешься за каждый байт и
делаешь некий "подвиг" в своих глазах :)

Музыка и эксперименты.
Самой сложной частью проекта для меня оказалась музыка.
Как известно на Вектор-06Ц для ВИ53 нет никакого (нормального) редактора для написания музыки.
Поэтому желая быстро получить музыку я попробовал сделать конвертор музыки из midi формата на свой
формат написанного мной плеера. Конвертер написал, но с midi форматом не всё просто. Автоматическая
конвертация это только пол дела. Ещё нужно учесть много моментов, которые на автоматике сложно
сделать. В итоге перекинулся на другую идею.
Второй идеей было переложить готовые ноты на формат моего плеера. Поначитавшись информации про
нотный стан, бемоли, диезы и другие интересности решил написать свой простенький музыкальный
редактор. Была написана рабочая версия, на которой вполне можно писать музыку. Найдя подходящую
нотную мелодию я начал писать её в своём редакторе, но довольно скоро столкнулся с проблемой
синхронизации 3-х каналов. На нотном стане частенько встречаются ноты и паузы с различной
длительностью, а в редакторе это не было предусмотрено. Нужно было писать более серьёзную версию с
визуальной синхронизацией по длительности звучания. И идея с нотным редактором была оставлена.

Далее был эксперимент с рандомным написанием музыки (это уже от отчаяния) :)
Было написано несколько вариантов кода, но ничего из этого не нравилось.

Далее в результате поисков решения этой задачи пришла идея использовать не точный образ midi
формата, а лишь нотный массив, несущий в себе некий музыкальный мотив.
Поэтому я вновь вернулся к конвертеру и переделал его для этой цели.
После конвертации подходящих мелодий остаётся очень немного, но всё же это лучше чем ничего.
Из двух таких массивов+ручная доработка удалось склеить более менее вариант мелодии для игры.
Вообщем нужен качественный музыкальный редактор для ВИ53 - если будет вдохновение напишу :)

В целом приобретён интересный опыт и какое-то необычное особое чувство когда программируешь на
первый свой компьютер из своего детства. Сейчас зная различные подводные камни создания игры на Вектор,
уже понятно с чего начать и как расставлять приоритеты в различных задачах.
Есть желание создать ещё некоторые игровые проекты для Вектора - теперь уже с более лучшим
пониманием некоторых ограничений и преимуществ платформы.

Итак вот мой первый шедевр для Вектора-06Ц игра "Binorum" - логическая с 9-ю уровнями.
Если кто-то захочет поблагодарить монетой пишите :)
Игру можно свободно скачать ниже прилагается (rom)
или же сразу поиграть здесь http://sensi.org/scalar/ware/910/



https://youtu.be/q2wLNbjbguE

https://1.bp.blogspot.com/-1ZPxg2ONgb0/X0QE5KwQMaI/AAAAAAAABXQ/-leqWo2MAnoSd3dh9jjqzyedwWYA0XJeACLcBGAsYHQ/s640/Bino.png

https://1.bp.blogspot.com/-In1OnOtX_io/X0QPqWO9jHI/AAAAAAAABXc/1C0FR31G1qEKfl_9kJpxbZ4_jmplTEWIACLcBGAsYHQ/s765/qas1.png

https://1.bp.blogspot.com/-ydRKsSgrcqM/X0QPqQarwcI/AAAAAAAABXg/4cKo4b_e4lkinAU-SoCOHI24QGqrll9_gCLcBGAsYHQ/s765/qas2.png

KTSerg
20.06.2020, 21:26
...
4. Аппаратным вертикальным скроллингом экрана можно сдвигать только сразу все (8000-FFFF) плоскости экрана или можно сдвигать их по отдельности ?
Аппаратный скроллинг "сдвигает" все области сразу. Инфа в них не сдвигается, "сдвигается" только отображение на экране.

5. Как на ассемблере запретить использование плоскости экрана (на Бейсике «Вектора» команда Screen 2,n) и использовать эту память для кода игры ?
...
"Запрет" происходит при помощи программирования палитры. При использовании графики 256*256 точек: 4 области формируют палитру из 16 цветов (это комбинации из точек расположенных в одинаковых координатах на всех плоскостях экрана).
Если какой-то элемент игры должен быть 16-ти цветным, то для его отображения нужно будет записать информацию во все 4 экранные плоскости. Если элемент - 8-ми цветный, то только в три плоскости. Соответственно 4-ёх цветный - расположен в двух экранных плоскостях. И элемент содержащий только два цвета - потребует занесения данных только в одну экранную плоскость.
Это позволяет разнести "фон" и "персонажей" по разным экранным плоскостям, правда с потерей количества цветов которые можно будет использовать. Но при этом отпадает необходимость программно "накладывать" изображение персонажа на изображение фона.

Есть много материала на эту тему. Например "Vector-User" http://www.sensi.org/scalar/ware/572/
В выпуске №3 техническое описание экранной области.


есть несколько завершённых мной игр для Windows
А ссылочки?

metamorpho
20.06.2020, 22:00
KTSerg, спасибо за информацию.

Вот одна из последних моих игр (там можно и другие мои игры посмотреть)
https://www.youtube.com/watch?v=H7oV74kGTms

KTSerg
21.06.2020, 08:52
...
5. Как на ассемблере запретить использование плоскости экрана (на Бейсике «Вектора» команда Screen 2,n) и использовать эту память для кода игры ?
...
Есть ещё "финт" с использованием КвазиДиска.
Экранная область может использоваться полностью (32КБ), при этом программа может занимать ещё 5 раз по 32КБ ;)
32КБ - в ОЗУ самого Вектора, и ещё в 4-ёх банках КвазиДиска по 32Кб в каждом.
Правда для меня это только теория, поскольку сам этой "фишки" не применял.

metamorpho
21.06.2020, 08:56
По поводу использования плоскостей экрана в "Vector-User" написано: «Управление режимами дисплея и управление заданием цвета фона рабочей и нерабочей области экрана осуществляется через порт 02-PB (0...3) и переключатель режимов, что позволяет:
- установить объём памяти дисплея (объём экранного ОЗУ) равным 8, 16, 24 и 32 Кбайт, изменяя содержимое таблицы цветов, т.е. отобразить информацию соответственно из одной, двух, трёх, четырёх плоскостей экранного ОЗУ.»

Я не совсем понял как «изменяя содержимое таблицы цветов» можно «установить объём памяти дисплея».
Есть предположение что нужно установить цвет плоскости равным цвету фона, тогда информация в плоскости не будет видна, правильно ли я понял ?


Ещё любопытно как ivagor, смог увеличить скорость работы Болдера (Болдер++) ? Что было оптимизировано ?

KTSerg
21.06.2020, 10:17
...
Я не совсем понял как «изменяя содержимое таблицы цветов» можно «установить объём памяти дисплея».
Есть предположение что нужно установить цвет плоскости равным цвету фона, тогда информация в плоскости не будет видна, правильно ли я понял ?
...
Да принцип именно такой.
В "секретах Лебедева" в таблице цветности подробно комментировано какой цвет предназначен для каких экранных плоскостей.
Грубо говоря, если мы используем первую плоскость для персонажа и вторую для картинки заднего плана, а остальные плоскости для программы, то:
программируем цвет №1 (соответствующий плоскости персонажа), и другой цвет №2 - для картинки заднего плана, остальные (для начала) цвета это фоновый цвет (где нет изображения).
Что получим: пока положение персонажа не совпадает с картинкой заднего плана - всё ОК.
Как только персонаж набежал на картинку заднего плана, то в этом месте пиксели уже имеют цвет №3 (1 + 2) - у нас это фон, значит вместо персонажа получим "тень" - цвет фона.
Если нам нужно что-бы персонаж был виден на фоне заднего плана, то цвет №3 программируем как цвет №1.
Если нам нужно, что-бы персонаж "забегал" за изображение на заднем плане, то цвет №3 должен совпадать с цветом №2.

Ну и в таком плане палитра подбирается для комбинации изображения для всех плоскостей.

Надеюсь я ничего не напутал, если накосячил с объяснением пусть знающие поправят.

svofski
21.06.2020, 13:46
3. Есть ли музыкальный редактор использующий ВИ53 и выдающий данные которые можно вставить в код игры и есть ли код который мог бы запускать эту мелодию ?
В теме «Биперная музыка (https://zx-pk.ru/threads/28132-bipernaya-muzyka-na-vektore-06ts.html)» можно найти много интересного. Я при этом не уверен, что там есть простой вариант плеера с таймером, который можно было бы повесить на 50Гц. Пример биперного двухканального музона есть даже в виде рыбы (https://svofski.github.io/pretty-8080-assembler/?arkmus), но это подходит наверное только для заставки, или таблицы рекордов. Писать музыкальный редактор для ВИ53 сейчас вряд ли кто-то станет, но SegaBoy получал отличные результаты (https://zx-pk.ru/threads/29077-igraem-melodii-na-vi53.html) конверсией MIDI, а уж MIDI сделать можно много из чего. ivagor переносил Апогеевский плеер на Вектор, послушать можно тут (http://sensi.org/scalar/ware/899/) (запускается прямо в картотеке).


6. Какой архиватор данных эффективнее всего использовать в игре ?
Тема «Сжатие данных (https://zx-pk.ru/threads/29679-szhatie-dannykh.html)».


7. Есть ли код который проигрывает мелодию для чипа AY ?
Я пользовался плеером st_play, в коротом написано Автор порта: Тарасов М.Н.(Mick),2008 в демке 8-bit Snail. Я пользовался им просто как монолитным черным ящиком. Собрал, приклеил, вызвал. Не знаю откуда он у меня взялся, но попробую собрать из хлебных крошек, если никто раньше не найдет первоисточник.

- - - Добавлено - - -


2. Есть ли программы преобразования графики с PC в данные для вставки в ассемблер ?
Я всегда писал свои по случаю, потому что графика для Вектора всегда подразумевает какие-то особенности -- сколько слоев, размеры, как именно выводить и так далее.

metamorpho
21.06.2020, 14:01
svofski, спасибо за информацию !! Буду исследовать.

dbk
21.06.2020, 14:06
svofski, спасибо за информацию !! Буду исследовать.
Если у вас что-то получится, я постараюсь вас отблагодарить.

metamorpho
21.06.2020, 14:19
dbk, спасибо, это мотивирует ещё больше.

dbk
21.06.2020, 14:32
1. Посоветуйте какой ассемблер сейчас можно использовать чтобы написать игру для «Вектора» ?
Кроссассемблер Telemark Cross Assembler (http://old-dos.ru/index.php?page=files&mode=files&do=show&id=1385) или как мне советовали ермолаевский Monitor «HIGH»+EDASM (http://sensi.org/scalar/ware/727/), Pretty 8080 Assembler (https://svofski.github.io/pretty-8080-assembler/) Вячеслава

На каком эмуляторе лучше всего тестировать результаты ?
Откинув эмуляторы для ДОС (https://drive.google.com/drive/folders/1D5StWsZN28Sm89Bz8zbarzDaYtQmLZ7N), существуют три эмулятора Вектор-06Ц: Virtual Vector (https://cloud.mail.ru/public/5uyc/2pkicQPoZ) (заточен именно под Вектор и его клоны, более ресурсоёмок, автор Игорь Титарь доступен), Emu80 (https://zx-pk.ru/threads/27488-emu80-v-4.html) или тут (https://github.com/vpyk/emu80v4) от Вячеслава Пыхонина (автор доступен, но я заметил проблему с эмуляцией к примеру журналов Байт, всё никак не соберусь автору эмулятора написать), универсальный эмулятор Башкирия (http://bashkiria-2m.narod.ru/index/files/0-11) включает в себя поддержку Вектора.
А ну еще есть некий emulator3000 (http://www.emulator3000.org/rus-e3.htm) , им я не пользовался, ничего сказать про его работу не могу.


2. Есть ли программы преобразования графики с PC в данные для вставки в ассемблер ?
В исходниках порта River Raid для Вектора (https://github.com/svofski/incursiondelrio/releases/tag/release-one), Вячеслав на Питоне писал что-то такое, ну или я что-то напутал.

А по-остальному вопросы уже вне моей компетенции, увы. Но сдается мне, что не зная ассемблера и не выкурив мануал того же Черезова (http://sensi.org/scalar/ware/632/) с Лебедевым (я тут по-соседству на неделе выложил правленный исходник Секретов Вектора (https://zx-pk.ru/threads/29144-programmirovanie-na-assemblere.html?p=1068795&viewfull=1#post1068795)), у вас шедевр получится только через пару лет ((((

svofski
21.06.2020, 15:17
В исходниках порта River Raid для Вектора, Вячеслав на Питоне писал что-то такое, ну или я что-то напутал.
В River Raid генерация кода спрайтов, это конверсией графики не назовешь, хотя сама по себе идея может пригодиться. Чуть более универсальный пример, где именно битмап преобразуется в db, есть в bbstro: https://github.com/svofski/bazis-bbstro (png2db.py).

Что до эмуляторов -- я понимаю, что для многих если нету gui, то это как бы и не эмулятор вообще, но все же есть еще v06x (https://github.com/svofski/vector06sdl/releases), у которого есть несколько присущих только ему особенностей. Хотя, если запускать ради отладчика, я бы сам воспользовался VV или emu (про отладчик в emu80 я пока ничего не знаю).

ivagor
21.06.2020, 15:34
заметил проблему с эмуляцией к примеру журналов Байт
Какие именно проблемы и с каким номером байта? Попробовал несколько, пока проблем не заметил.

dbk
21.06.2020, 16:20
Какие именно проблемы и с каким номером байта? Попробовал несколько, пока проблем не заметил.

При запуске к примеру номеров 21-26 без автозапуска версия emu80qt у меня выдает вот такое, с автозапуском (Alt+F3) проблемы такой не наблюдается. Система win10x64 , NVidia 740Ti

https://i112.fastpic.ru/big/2020/0621/cb/7caabd33371693b427fb856f365aa8cb.jpg (https://fastpic.ru/view/112/2020/0621/7caabd33371693b427fb856f365aa8cb.jpg.html)
Ну и так же при запуске этой версии на видеокарте mobile intel 965 Express chipset вместо изображения загрузочного экрана Вектора у меня просто чёрный экран, не qt версия даже меню не выдает (иконок-кнопок управления не показывает), просто экран запущенного эмулятора (пустой квадрат) и всё. Из минусов - нет раскладки клавиатуры, приходилось запускать Тест устройств (http://sensi.org/scalar/ware/621/) -> тест клавиатуры -> тыкать на кнопки и выписывать на бумажку все управляющие клавиши. Что есть "умная клавиатура", я так и не понял ) Зато дебаггер более похож на стандартный Turbo Debugger от Borland Pascal, чего не скажешь про Virtual vector, ну и в последнем меня выбешивает постоянно скрывающееся меню ))) Зато в Virtual vector есть настройка клавиатуры с таблицей соотвествий клавиш, где хотя бы можно было выписать набор управляющих клавиш на бумажку и уже оперировать переписанными данными.

Как писал выше, emu80 менее ресурсоемок, через минут 15-30 запущенного VV на 2х ядерном ноуте, оно так начинает педалить, что приходится прибивать задачу и перезапускать.
Зато опять же, более наворочен в плане настроек.

- - - Добавлено - - -


В River Raid генерация кода спрайтов, это конверсией графики не назовешь, хотя сама по себе идея может пригодиться. Чуть более универсальный пример, где именно битмап преобразуется в db, есть в bbstro: https://github.com/svofski/bazis-bbstro (png2db.py).

Вот-вот-вот, с языка сняли. Там именно есть "тулза" по конвертации png в db, а я всё вспомнить не мог, где я такое видел )


Что до эмуляторов -- я понимаю, что для многих если нету gui, то это как бы и не эмулятор вообще, но все же есть еще v06x (https://github.com/svofski/vector06sdl/releases), у которого есть несколько присущих только ему особенностей. Хотя, если запускать ради отладчика, я бы сам воспользовался VV или emu (про отладчик в emu80 я пока ничего не знаю).
Пока не приходилось пользоваться.

ivagor
21.06.2020, 16:48
С байтом в emu80 при запуске из загрузчика проблема связана с ВВ55. Байт при старте не задает режим системной ВВ55, и он (режим) должен был бы остаться от загрузчика. Там он почти всегда 88 и очень немного 8A, т.е. в подавляющем большинстве случаев все должно было бы быть нормально, но мы видим, что проблема стабильно воспроизводится каждый раз. Есть предположение, что в emu80 ресет влияет и на ВВ55, хотя для вектора это неправильно. Если верить даташиту, при ресете ВВ55 все порты программируются на ввод, при этом не получается запрограммировать палитру и изменить режим экрана, что и наблюдается в emu80. Надо бы посмотреть исходник emu80, но у меня скачан старый, без вектора, и ленюсь качать новый.

dbk
21.06.2020, 16:51
С байтом в emu80 при запуске из загрузчика проблема связана с ВВ55.
Я отписался автору о найденной проблеме.

metamorpho
21.06.2020, 17:17
Да уж столько много информации разной нужно освоить, но зачастую там много воды не нужной мне. Хотелось конечно конкретики в некоторых моментах, но не всегда она есть, но ничего прорвёмся :)

Первая проба пера на ассемблере будет такая - код игры в пределах 32 Кб + использование всех четырёх видео-плоскостей.

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

На данный момент выбор пал на "Pretty 8080 Assembler" - тестировал только приведённые там примеры различных рыб - всё легко и изящно - сделал BIN получил ROM запустил в эмуляторе VV. Есть ли у "Pretty 8080 Assembler" какие-либо неудобные ограничения или подводные камни которые нужно будет учесть ?

ivagor
21.06.2020, 17:20
Возможно в описании механизма мои предположения не полностью подтвердятся, но проблема точно в ВВ55. Если в байте добавить задание режима ВВ55, то все становится нормально. И наоборот, если взять другую программу, которая не задает режим ВВ55 (например exolon), то там тоже будут проблемы.

dbk
21.06.2020, 17:42
Да уж столько много информации разной нужно освоить, но зачастую там много воды не нужной мне. Хотелось конечно конкретики в некоторых моментах, но не всегда она есть, но ничего прорвёмся :)
Первая проба пера на ассемблере будет такая - код игры в пределах 32 Кб + использование всех четырёх видео-плоскостей.


Эмммм... вы для начала вывели бы квадратик на экран и прикрутили бы к нему управление ) кстати, вот тут (http://sensi.org/scalar/ware/892/) и тут (http://sensi.org/scalar/ware/893/) лежит что-то полезное для геймдева. Так же позволю себе рекомендовать вообще наработки (http://sensi.org/scalar/author/277/) данного автора (https://zx-pk.ru/members/6976-ppc.html).

Он по-моему присутствует на данном форуме (https://zx-pk.ru/members/6976-ppc.html), правда давно его не видел.

metamorpho
21.06.2020, 17:59
dbk, спасибо за полезные ссылки.

svofski
21.06.2020, 19:24
Есть ли у "Pretty 8080 Assembler" какие-либо неудобные ограничения или подводные камни которые нужно будет учесть ?
Не всем нравится работать в браузере и трудно разбить программу на несколько частей. Я в таких случаях пользуюсь оффлайновой версией, а саму сборку организую в Makefile. Мне так удобней, но я за это не агитирую.

Синтаксис TASM и Pretty в основном совместим, так что можно отрабатывать мелкие части в Прекрасном, а потом их объединять в уже TASM-ом.



На современном движке на котором я программирую (AppGameKit) нужно каждый раз заново создавать весь игровой экран, а на Векторе как я понял этого делать не нужно - т.е. если спрайт статичный, то достаточно один раз вывести его в видео-плоскость и дальше Вектор сам по прерыванию будет это выводить - правильно ли я понял ?
На экране будет показано то, что лежит в видеопамяти. Прерывания синхронны с ходом луча, но к отображению информации они прямого отношения не имеют. Cтатичная картинка просто будет стоять и не меняться.

Рисовать целиком игровое поле в теневую плоскость и потом копировать -- для этого нет ни памяти, ни быстродействия. Просто очистить экран константой занимает больше 1/50 секунды. Если спрайт без фона и без наложения, достаточно просто затереть предыдущий кадр и нарисовать текущий. Вектор позволяет хитрым выбором палитры сделать так, чтобы наложение спрайтов на фон было "аппаратным". При этом, разумеется, уменьшается количество доступных цветов.

svofski
21.06.2020, 22:22
Не прошло и 11 лет, как я собрал волю в кулак, сгреб из помойки в сотни файлов минимум нужного и сделал маленькую компактную репку с сорцами 8-битной улитки:

https://github.com/svofski/8-bit-snail

Из потенциально интересного такого, что можно было бы еще где-то употребить, тут есть player.asm, который играет pt2 файлы на ay. Мне стыдно, но я не знаю, чья это работа. В заголовке там коментарии от рекомпилятора z80. Вообще для демки я пользовался файлом player.bin, но тут все же прошелся по меткам и сделал ассемблируемый листинг. Не стоит думать, что его можно перенести на другие адреса -- там остались абсолютные адреса в изобилии. Но их не так и много, может быть есть смысл доделать эту работу до конца.

dbk
21.06.2020, 22:58
Кстати, касаемо игродева: помогите вспомнить демку, по-моему от SES, с персонажами из Monkey Island, Гайбрашем Тапервудом и обезьянками. Ну и технодемку с Чипом тоже можно посмотреть как устроена. Если топик-стартер действительно начнет что-то писать, то данные технодемки, на мой взгляд, будут хорошим ориентиром к чему нужно стремиться, ну и что может платформа Вектора. Эх, очень жаль, что SES отошел от дел, очень жаль.

Pyk
21.06.2020, 23:46
Есть предположение, что в emu80 ресет влияет и на ВВ55, хотя для вектора это неправильно
Именно так, моя недоработка. Постараюсь исправить в следующий версии, которую планирую выпустить, наконец, ориентировочно в первой половине июля.


Ну и так же при запуске этой версии на видеокарте mobile intel 965 Express chipset вместо изображения загрузочного экрана Вектора у меня просто чёрный экран, не qt версия даже меню не выдает (иконок-кнопок управления не показывает), просто экран запущенного эмулятора (пустой квадрат) и всё.
Ну, меню в не-qt-версии действительно отсутствует, все управление через горячие клавиши и диалоги (Alt-F12 для начала, там есть подсказки). Другое дело, что черного экрана вообще-то не должно быть, тем более в обоих версиях сразу. К тому же, что я на 965 чипсете успешно запускал его. Напиши в ЛС или на e-mail конфигурацию системы - попробуем разобраться.


Что есть "умная клавиатура", я так и не понял
В двух словах это означает, что нет жестко определенного соответствия клавиш, и для ввода большинства символов можно просто их набирать на клавиатуре ПК как обычно, в том числе переключая раскладки - эмулятор сам перетранслирует в нужную клавишу и добавит Shift где надо. Естественно, работает это не везде и не всегда, но в большинстве случаев очень удобно.

metamorpho
22.06.2020, 08:50
svofski, спасибо за ссылочку на player.asm

Прочитал книжку "Ассемблер-редактор" (от "Вектора" у меня ещё осталась).
В целом понятно что и как, но некоторые моменты конечно напрягают (всякие флаги нуля и др.).
Да ассемблер по сравнению с Бейсиком конечно жесть в плане удобства, но зато скорость.

На Бейсике даёшь команду вывод спрайта и указал X,Y и всё.
На ассемблере стало понятно, что при сдвиге спрайта влево или вправо на экране нужно будет учесть байтовую структуру экрана и всё делать самому.
Я так понял что налету такой сдвиг спрайта лучше не делать т.к. это будет тормозить процесс.
А также на лету сделать горизонтальное отражение спрайта (для экономии памяти) тоже не вариант.
Интересно с каким шагом (+1 +2 +4 +8) идёт сдвиг влево(вправо) в Болдере например.

Так и не нашёл то что мне нужно в отношении картинок, а именно
программы преобразования графики с PC в данные (типа .db с7h,0bh) для вставки в ассемблер ?
Поэтому решил написать такую програмку сам.

KTSerg
22.06.2020, 09:39
...
Прочитал книжку "Ассемблер-редактор" (от "Вектора" у меня ещё осталась).
В целом понятно что и как, но некоторые моменты конечно напрягают (всякие флаги нуля и др.).
Да ассемблер по сравнению с Бейсиком конечно жесть в плане удобства, но зато скорость.
...
Если Ассемблер вызывает сомнения, может имеет смысл начать с использования какой-то среды разработки или хотя-бы готовых комплектов драйверов.
И ассемблера будет меньше и появится представление об особенностях Вектора.
Благо ссылок уже накидали.
А когда будет результат, можно будет пробовать заменить какие-то функции/подпрограммы своими вариантами.

metamorpho
22.06.2020, 10:26
KTSerg, ну не настолько всё плохо :)
Да и на Векторе нет ничего другого для написания шедевра - только Ассемблер, только хардкор :)

KTSerg
22.06.2020, 10:40
KTSerg, ну не настолько всё плохо :)
Да и на Векторе нет ничего другого для написания шедевра - только Ассемблер, только хардкор :)
Не аксиома, с моей точки зрения.
В любом случае, игрушка - это кроме алгоритмов обработки сценария, ещё и набор подпрограмм выполняющих разные рутинные задачи (обработки клавы, вывод на экран, звук, и пр.).
Так почему, бы не воспользоваться уже готовыми подпрограммами (из наборов драйверов или средств разработки), которые уже написаны, отлажены... тем более созданных именно для облегчения процесса создания больших и сложных (а так-же не очень больших, и не очень сложных) программ.

metamorpho
22.06.2020, 11:49
Я имел ввиду что "Бейсик" и известные "Драйверы устройств" для Вектора достаточно медленные по графике.
А готовый полезный код я конечно буду заимствовать и использовать.
Начать хочу с того что написал Лебедев А.З. в своих "секретах по Вектору + исходники Болдера", в принципе там основное необходимое написано (на мой взгляд).

svofski
22.06.2020, 11:55
Так и не нашёл то что мне нужно в отношении картинок, а именно
программы преобразования графики с PC в данные (типа .db с7h,0bh) для вставки в ассемблер ?
Поэтому решил написать такую програмку сам
Как у меня это происходит: все начинается с написания процедуры вывода картинки, в процессе приходит понимание того, как должны быть устроены данные, чтобы именно эта процедура была проще и быстрее, и уже когда она готова, остается только написать конвертер и подсунуть данные.

metamorpho
22.06.2020, 19:44
Подскажите где найти информацию по горячим клавишам "Pretty 8080 Assembler" ?

svofski
22.06.2020, 20:27
Подскажите где найти информацию по горячим клавишам "Pretty 8080 Assembler" ?

Редактор называется ace, вот вроде его хелп:
https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts

Ничего специального я не добавлял, хотя было бы прикольно сделать перейти по адресу, а не по номеру строки, например.

metamorpho
25.06.2020, 10:16
Возник вопрос. В разных описаниях графического режима Вектора написано что одновременно на экране могут отображаться только 16 цветов из 256 цветовой палитры.

Но есть программы которые отображают вот этот спектр цветов.
http://sensi.org/scalar/ware/770/
http://sensi.org/scalar/ware/768/

За счёт чего это происходит ?
И можно ли в игре использовать больше 16 цветов одновременно ?

svofski
25.06.2020, 11:29
Это мультиколор, или растровые эффекты. Для них процессору приходится выводить код цвета в регистр $0c синхронно с ходом луча. Для наших целей можно считать, что out 0c выводит цвет прямо в ЦАП. Если на экране черный фон и мы делаем mvi a, $ff \ out $0c в момент, когда луч находится посередине 1-й строки, мы увидим переход с черного на белый несмотря на то, что в видеопамяти по прежнему все нули.

В игре это использовать сложно, потому что это делается процессором, а единственная точка синхронизации -- это кадровое прерывание. Оттуда можно только считать такты. Будет либо колоссальная потеря времени в цикле задержки, либо код должен быть написан так, что все его ветвления занимают одно и то же время, либо на собственно работу программы останется время только от непосредственно после последнего мультиколорного out до следующего прерывания. Сложно, но можно. Можно представить себе игру, в которой обработка требуется минимальная, код разбит на маленькие корутины, которые гарантировано успевают исполниться в нижней половине экрана, а большая часть экрана при этом занята каким-то мультиколорным эффектом.

На самом деле есть еще способ синхронизации, примененный в Exolon (но не для мультиколора) — поскольку таймер считает синхронно с процессором, его можно использовать для определения положения луча на экране. Пока я ни разу не видел, чтобы это было применено для растровых эффектов и боюсь, что может быть не получится попасть ровно в нужное место просто потому, что одна только инструкция in - это 12 тактов и точность определения таким образом получается +/- полстроки.

ivagor
25.06.2020, 12:11
Пока я ни разу не видел, чтобы это было применено для растровых эффектов и боюсь, что может быть не получится попасть ровно в нужное место просто потому, что одна только инструкция in - это 12 тактов и точность определения таким образом получается +/- полстроки.
Вариант, как это можно было бы использовать для растрового эффекта. Читаем (заранее, иначе не получится) значение из таймера, находим разность с нужным моментом. Разбиваем ее (разность) условно на 2 части: грубая подстройка (ее компенсируем циклом) и точная подстройка - как вариант ее можно сделать по таблице задержки (nop nop ... nop) индекс перехода в которую определять по той самой "части точной подстройки". Но это все малопригодная для игр штука, и еще не надо забывать про тонкие светлые полосы, сопровождающие на реале запись в РУ2 в активной части растра.
Имхо при ориентации на многоцветную графику самый простой вариант движка - использовать вывод с дискретностью тайлов 8x8 точек. Как это выглядит в простейшем случае, без масок, можно увидеть на примере HUDSONовских игр (http://www.sensi.org/scalar/author/41/) портированных с msx (только не надо учитывать jet set в этом списке, там все иначе). В векторовских версиях можно было нарисовать гораздо более цветную (это даже я делал) и красивую (а вот это я не умею) графику. Если скорость не так важна (на экране сравнительно мало движущихся объектов), то можно при выводе "спрайтовых тайлов" использовать маску, как в Chip and Dale (http://www.sensi.org/scalar/ware/393/).

- - - Добавлено - - -

Robotz (https://zx-pk.ru/threads/19922-robotz!-releases.html?p=535343&viewfull=1#post535343) уже рекомендовали, но начинать с них знакомство с программированием для вектора наверное все же несколько сложновато, но может я ошибаюсь.

metamorpho
25.06.2020, 12:21
svofski, ivagor спасибо!!

Ещё вопрос такой - скорость аппаратного вертикального скролинга будет одинаковый и при режиме 256х256 и при режиме 512х256 точек ?

svofski
25.06.2020, 12:28
Скроллинг будет одинаковый.

А для Вектора уже есть Space Invaders?

ivagor
25.06.2020, 12:41
А для Вектора уже есть Space Invaders?
Ужас (http://www.sensi.org/scalar/ware/89/), Пиф-паф (http://www.sensi.org/scalar/ware/77/), может еще что забыл.

svofski
25.06.2020, 13:14
О, а Пиф-паф то — огого!

metamorpho
26.06.2020, 14:23
прогресс написания шедевра на сегодняшний день:

- написал программу перевода графики с PC в формат .db 0,1,2,3,.... для вставки в ассемблер
- написал код вывода спрайта на экран (программировать на ассемблере это полный "хардкор",
но в тоже время это оказалось весьма интересно :) )

Сейчас пишу редактор уровней, чтобы также выдавал текстовый файл в формате .db 0,1,2,3,.... для вставки в ассемблер

svofski
26.06.2020, 18:42
Круто!

btw, когда данных чуть больше, чем пара строчек db, но еще не настолько много, что все, решено, пишем сборку из кусочков итд.. я пользуюсь db64



echo "sprite: db64 $(base64 -w0 sprite.bin)" >> masterpiece.asm


Это может быть выглядит странно, зато компактней, чем прорва db

metamorpho
26.06.2020, 19:11
svofski, спасибо!!

А какой объём информации можно загрузить в "Pretty 8080 Assembler" ?

svofski
26.06.2020, 20:03
А какой объём информации можно загрузить в "Pretty 8080 Assembler" ?
Никаких искусственных ограничений нет, но на выходе точно никак не может получиться больше 64К.

ivagor
27.06.2020, 10:02
Кажется я не видел картинок с результатами программирования РУ2 в активной области с мониторов/телевизиров с прямыми цветами. Есть шанс, что там будут темные полосы, но не уверен.

ivagor
27.06.2020, 10:15
KTSerg, большое спасибо! Про цвет полос писал уже давно и интересно было увидеть. То, что отстают - со светлыми аналогично.

svofski
27.06.2020, 10:51
Синий шибко мощный, старший бит все собой забивает. Надфилем его :)

ivagor
27.06.2020, 11:04
Если посмотреть на крайний правый столбец, который д.б. черным, то там все равно синеватость, т.е. дело не в старшем бите или по крайней мере не только в старшем бите.
И до меня только сейчас дошло, что "полосы РУ2" на обоих картинках темные. Т.е. получается это зависит от "прямизны" устройства отображения (плохая формулировка, надо бы ее уточнить и развернуть).

svofski
27.06.2020, 11:09
Не. Та синеватость это просто LCD так показывает черный. А между уровням 1 и 2 синего скачок совершенно непропорциональный. При этом белый выглядит норм. Странно.

ivagor
27.06.2020, 11:21
По картинке clrspace мне сложно судить про "линейность цапа" (по clrs256 проще). У меня вызывают вопросы почти отсутствие зеленого в голубом столбце и мало красного в фиолетовом/пурпурном столбце, да и серый столбец тоже своеобразный. Это все про вторую картинку, которая не инверсная.

metamorpho
02.07.2020, 19:07
прогресс написания шедевра на сегодняшний день (шаг 2):

- написал (адаптировал свой) редактор уровней, чтобы также выдавал текстовый файл в формате .db 0,1,2,3,.... для вставки в ассемблер
- написал код вывода уровня на экран + анимация объектов


https://youtu.be/-ai1EYPJsd8

Программировать на ассемблере становится всё интересней, каждая новая задача это отличная головоломка :)

Следующим шагом будет: опрос клавиатуры и движение главного героя по уровню

metamorpho
07.07.2020, 15:38
Сделал опрос клавиатуры и движение игрока влево-вправо (см. видео)

Спрайты у меня 24х24 точек, в итоге экран 10х10 элементов - это не совсем стандартно, но в 24х24 точки можно уместить более детальную графику, чем в 16х16. Но в этом решении есть свои трудности при реализации следующего шага.
Хочу сделать игру с аппаратным вертикальным скроллингом, в связи с этим
столкнулся с выбором - есть такие вот варианты:
1. Если сохранить 24х24 точки и 16 цветов, то нужно писать хитрую программу которая будет выводить только часть (выбранную треть высотой 8 точек) спрайта (это для вертикального скроллинга). Поскольку спрайт (24х24) точки х10 (элементов) = 240х240 точек, поэтому остаются края со всех сторон по 8 точек.

2. Можно изменить графику и сделать 16х16 точек и сохранить 16 цветов, тогда программа вертикального скроллинга будет попроще (наверное), но есть подозрение что если делать вывод спрайтов для вертикального скроллинга высотой 16 точек, то это будет заметнее чем высотой 8 точек.

3. Есть ещё вариант оставить 8 цветов, а одну плоскость сделать "ширмой", которая будет прикрывать вывод строки спрайтов (высотой 16 точек) для вертикального скроллинга и в итоге скроллинг смотреться будет более качественно (наверное), но это потеря 8 цветов для игры.

Может у кого есть идеи или советы, пишите :)

Следующий шаг в разработке: движение главного героя по уровню вверх-вниз с помощью аппаратного вертикального скроллинга.


https://www.youtube.com/watch?v=VYO5TWW943c&feature=youtu.be

jerri
07.07.2020, 20:48
metamorpho, а зачем выводить сразу весь тайл?
выводи попиксельно с прокруткой

KTSerg
10.07.2020, 08:01
Сделал опрос клавиатуры и движение игрока влево-вправо ...
А скорость передвижения влево-вправо как-то синхронизирована с прерываниями?

metamorpho
10.07.2020, 08:24
metamorpho, а зачем выводить сразу весь тайл?
выводи попиксельно с прокруткой

Скорость игры будет выше, поскольку количество выполняемых команд будет меньше, т.к. вывод целого спрайта не требует дополнительных вычисления как при выводе части спрайта (это я ориентируюсь на основании своего кода)


А скорость передвижения влево-вправо как-то синхронизирована с прерываниями?

Нет. А что даст такая синхронизация ? И как это сделать ?

jerri
10.07.2020, 08:40
Скорость игры будет выше, поскольку количество выполняемых команд будет меньше, т.к. вывод целого спрайта не требует дополнительных вычисления как при выводе части спрайта (это я ориентируюсь на основании своего кода)


ну значит надо что-то поменять
просто плавное движение экрана смотрится более приятным чем грубое потайловое.

вот например

https://youtu.be/Jz3EFWsvoBs?t=45




Нет. А что даст такая синхронизация ? И как это сделать ?
плавность отображения

KTSerg
10.07.2020, 08:58
...
Нет. А что даст такая синхронизация ? И как это сделать ?
С моей субъективной точки зрения, синхронизация перемещения с прерыванием может дать равномерность скорости перемещения персонажа по экрану.
Мне кажется, что вертикальный скролинг лучше задавать в прерываниях, т.к. изменение регистра скролинга в другое время может привести к появлению артефактов на экране.
Значит скорость вертикального перемещения будет зависеть от прерываний. Нужно на практике посмотреть какое соотношение смещения по вертикали за сколько циклов прерывания для данной игры наиболее оптимально. А если к этому привязать ещё и отрисовку смещения персонажа по горизонтали, то игроком восприниматься это будет более гармонично. Иначе получится, что по горизонтали персонаж бегает с одной скоростью, а по вертикали с другой.
Как делается синхронизация... ну например:
В прерывании организуем счетчик, который уменьшается от некоторого значения до нуля, при достижении нуля, присваивает значение "1" некоторой переменной (это "флаг", указывающий основному циклу программы, что пора отрисовывать перемещение), и значение счетчика снова восстанавливается для очередного цикла.
А основной цикл кроме всего прочего проверяет значение "флаг"а, а когда он становится равным "1", сначала сбрасывает его в "0", а потом отрисовывает перемещения персонажа (при наличии смещения по горизонтали), и элементы лабиринта для компенсации скролинга (при наличии смещения по вертикали).
Не знаю на сколько понятно я выразил свою мысль.

metamorpho
10.07.2020, 13:57
jerri, KTSerg - спасибо за идеи и советы!!

Аппаратный вертикальный скроллинг у меня прописан именно в программе обработки прерываний.
А горизонтального скроллинга в этой игре не будет.
Если движение влево и вправо будет сильно различаться по скорости от движения вверх и вниз, тогда воспользуюсь идеей синхронизации вертикального и горизонтального движения.

metamorpho
15.07.2020, 22:55
Сделал движение главного героя по уровню вверх-вниз с помощью аппаратного вертикального скроллинга. Результат оказался не таким что ожидал, но всё же это результат.

Следующий шаг в разработке:
- возможно поэксперементирую с другими вариантами вертикального скроллинга
- оптимизация (укорение) кода


https://youtu.be/ThltwegPfBY

KTSerg
16.07.2020, 06:23
Сделал движение главного героя по уровню вверх-вниз с помощью аппаратного вертикального скроллинга. Результат оказался не таким что ожидал, но всё же это результат.
...
Это иллюзия, или сначала программа выводит элементы лабиринта, а потом происходит аппаратный скролинг ?
А если сначала сдвигать, а потом выводить лабиринт на экран?

b2m
16.07.2020, 10:00
А если сначала сдвигать, а потом выводить лабиринт на экран?
А без разницы. Будет такой-же эффект, но с другой стороны экрана. Нужно оставлять пустое место, выводить и сдвигать попиксельно (по одной линии).

KTSerg
16.07.2020, 10:36
А без разницы. Будет такой-же эффект, но с другой стороны экрана. Нужно оставлять пустое место, выводить и сдвигать попиксельно (по одной линии).
Да это понятно.
Просто из практического интереса, как это будет выглядеть.
Хотя скорее всего текущий вариант более приемлим, т.к. в сторону движения лабиринт выезжает уже готовый, а мерцание лабиринта происходит за спиной. Хотя сейчас снова посмотреть видео (присмотреться к артефактам) не получается, а утром нормально показывало.

metamorpho
16.07.2020, 10:44
А без разницы. Будет такой-же эффект, но с другой стороны экрана. Нужно оставлять пустое место, выводить и сдвигать попиксельно (по одной линии).

Попиксельно медленно получается. На видео аппаратный вертикальный скроллинг сдвигается на 4 пикселя когда происходит обработка прерывания.

KTSerg
16.07.2020, 12:12
Попиксельно медленно получается. На видео аппаратный вертикальный скроллинг сдвигается на 4 пикселя когда происходит обработка прерывания.
Напомни, сколько цветов сейчас используется, для элементов лабиринта (я стены имею в виду) ?

metamorpho
16.07.2020, 12:19
Напомни, сколько цветов сейчас используется, для элементов лабиринта (я стены имею в виду) ?

Сейчас используются все 16 цветов, т.к. все спрайты выводятся в 4 плоскости.

KTSerg
16.07.2020, 12:32
Сейчас используются все 16 цветов, т.к. все спрайты выводятся в 4 плоскости.
Но в спрайтах ведь не используется вся палитра, или все спрайты содержат более 8 цветов?
Я о том, что можно ведь оптимизировать по скорости, и сделать отдельные алгоритмы вывода, для персонажа, стен, и не знаю как их назвать - собираемые элементы...
Тогда вывод будет быстрее, а если спрайты стен содержат не более 8 цветов, то сделать "ширму" сверху и снизу для зоны скролинга.

metamorpho
16.07.2020, 12:50
Но в спрайтах ведь не используется вся палитра, или все спрайты содержат более 8 цветов?
Я о том, что можно ведь оптимизировать по скорости, и сделать отдельные алгоритмы вывода, для персонажа, стен, и не знаю как их назвать - собираемые элементы...
Тогда вывод будет быстрее, а если спрайты стен содержат не более 8 цветов, то сделать "ширму" сверху и снизу для зоны скролинга.


KTSerg, спасибо за совет!! У меня такие же идеи насчёт оптимизации по скорости.
Это (я так думаю) хороший вариант - написать для разных спрайтов разные подпрограммы их вывода в зависимости от количества используемых в них цветов.

Про "ширму":
- не хочется терять 8 цветов, т.к. в планах сделать игрушку такую же цветастую как PUTUP
- даже если делать "ширму" то при аппаратном вертикальном скроллинге сдвигаются все 4-и плоскости, включая "ширму". И выходит мне нужно будет и спрайты нарисовать и "ширму" обновить. Похоже разница в скорости будет небольшой. Хотя тут есть зависимость от количества цветов используемых в стенах.

KTSerg
16.07.2020, 13:06
...
Про "ширму":
- не хочется терять 8 цветов, т.к. в планах сделать игрушку такую же цветастую как PUTUP
- даже если делать "ширму" то при аппаратном вертикальном скроллинге сдвигаются все 4-и плоскости, включая "ширму". И выходит мне нужно будет и спрайты нарисовать и "ширму" обновить. Похоже разница в скорости будет небольшой. Хотя тут есть зависимость от количества цветов используемых в стенах.
"Ширма" это всего одна экранная плоскость, заполнять её стеком значением FFFFh, или удалять, занося стеком 0000h (два PUSH H - вот четыре строки одной колонки уже готовы, дольше адрес стека менять), это быстрее, чем все плоскости, да ещё плюс сопутствующая логика выбора спрайта, хотя это и мизер должен быть.
Хотя надо посчитать, может стеком "ширму" формировать и не выгодно, по времени.

Improver
16.07.2020, 13:23
metamorpho, KTSerg, посмотрел я видео, мне кажется, движения вверх-вниз вполне хорошо выглядят, не хуже, чем в других играх на Вектор, или на той же денди (оно же NES). И решение делать прорисовку в противоположной движению стороне экрана тоже верное, туда обычно никто не смотрит, нет смысла как-то ухудшать шедевр. :) Извиняюсь за своё некомпетентное в плане игрописания мнение...

svofski
16.07.2020, 14:06
В этом вся суть аппаратного скроллинга. Его очень трудно применить на практике с выгодой. Приходится жертвовать очень много чем.

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

Если этого не делать в каждом кадре, то это не такая уж большая проблема. Можно просто выделить например один из 8 кадров на разные задачи, которые не требуют немедленного исполнения.

metamorpho
16.07.2020, 15:55
Improver, спасибо !!
Но всегда хочется сделать ещё лучше :)


....Чтобы не было мельтешни на краях экрана, надо подтирать низ сразу после прерывания, задолго до того, как эта область будет просканирована лучем. А верх незадолго до перывания, чтобы он был чистым сразу после прерывания.
Если этого не делать в каждом кадре, то это не такая уж большая проблема. Можно просто выделить например один из 8 кадров на разные задачи, которые не требуют немедленного исполнения.

svofski, возможно я не совсем понял эту мысль. Но у меня нет двойного затирания (вверху и внизу) как такового, поскольку например
при движении главного героя вверх происходит скроллинг экрана вниз
при этом внизу рисуется то что перемещается вверх экрана
т.е. у меня лишь один раз рисуется новая часть при этом затирая сразу ненужную старую.

svofski
16.07.2020, 16:22
svofski, возможно я не совсем понял эту мысль. Но у меня нет двойного затирания (вверху и внизу) как такового, поскольку например
при движении главного героя вверх происходит скроллинг экрана вниз
при этом внизу рисуется то что перемещается вверх экрана
т.е. у меня лишь один раз рисуется новая часть при этом затирая сразу ненужную старую.

От направления прокрутки зависит временной интервал, в который можно рисовать новую часть лабиринта без мельтешения.

Если скролл вверх, внизу надо нарисовать новое. Это можно сделать в интервал от прерывания до начала сканирования лучом обновляемой области.

Если скролл вниз, вверху надо нарисовать новое. Это можно сделать или до того, как луч дошел до первой отображаемой строки, или между тем, как луч уже отрисовал верхнюю часть экрана и случилось прерывание.

Life Pro Tip: вывод разных цветов в регистр бордюра дает возможность увидеть наглядно сколько именно времени от кадра занимают разные процедуры.

KTSerg
16.07.2020, 19:16
...
- даже если делать "ширму" то при аппаратном вертикальном скроллинге сдвигаются все 4-и плоскости, включая "ширму". И выходит мне нужно будет и спрайты нарисовать и "ширму" обновить. Похоже разница в скорости будет небольшой. Хотя тут есть зависимость от количества цветов используемых в стенах.
Не агитации ради, а токма спортивного интересу из.
Прикинул алгоритм "ширмы".
Формирование "ширмы" в 4 строки и на всю ширину экрана занимает 2048 тактов, или около 0.68 мсек.
Это один проход. Для удаления "ширмы" и установки её на новое место в два раза дольше.
"Луч" за это время успевает отобразить на экране порядка 20-ти строк (если я в расчетах не ошибся).

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

metamorpho
16.07.2020, 19:54
svofski, спасибо за советы, но для меня подобные манёвры кода пока непонятны - это уже похоже высший пилотаж.
Я непонимаю как это реализовать в коде.

KTSerg, я решил поэксперементировать с "ширмой", о результатах сообщу.

KTSerg
17.07.2020, 07:24
Осмелюсь показать свою идею по заполнению ширмы.
Сразу скажу, я этим ни когда не пользовался и не протестировал.
Не призываю это использовать, просто как пример, может на какие мысли подтолкнёт.


сохранение указателя стека
lxi h,0000h
dad sp
shld sohr_sp

подготовка регистров.
HL должна читать адрес шиирмы, который где-то вычисляется и хранится в памяти
lhld adr_shirm - в HL загрузить адрес верхней строки "ширмы" из памяти.
lxi d,$0100 - в DE загрузить смещение для перехода к следующей колонке "ширмы".
lxi b,$ffff - в BC загружаем "ширму" или $0000 для её снятия.
mvi a,$20 - счетчик количества колонок ширмы, если пользоваться циклом

shirm_scr:
sphl - адрес ширмы в указатель стека
push b - две строки ширмы
push b - две строки ширмы
dad d - переход на следующую колонку ширмы

dcr a - счетчик циклов для ширмы
jnz shirm_scr - на повтор цикла

восстановление указателя стека
lhld sohr_sp
sphl

если циклом не пользоваться, а просто повторить 32 раза 4 команды загрузки ширмы, то её заполнение ускоряется на 30%.


- - - Добавлено - - -



KTSerg, я решил поэксперементировать с "ширмой", о результатах сообщу.
metamorpho, это глобальные изменения и самих спрайтов и алгоритмов их вывода... я много раз косячил, просто начиная вносить глобальные изменения в программы, не создав сначала копию уже рабочего проекта...

metamorpho
17.07.2020, 08:09
Отключил одну плоскость. Сделал "ширму". Смотрится более ровно чем в исходном варианте, но попрежнему мельтишит.
Дальше хочу попробовать уменьшить вывод прибавки графики до 4-х строк (сейчас 8 строк) при скроллинге, выглядеть должно получше.
Если и это не даст приемлемый вид отображения, то возможно буду пробовать применить советы svofski.


https://www.youtube.com/watch?v=0tROsp5qeh8

- - - Добавлено - - -


metamorpho, это глобальные изменения и самих спрайтов и алгоритмов их вывода... я много раз косячил, просто начиная вносить глобальные изменения в программы, не создав сначала копию уже рабочего проекта...

KTSerg, спасибо за совет. Да я тоже это проходил :) Стараюсь почаще сохранять варианты кода.

KTSerg
17.07.2020, 08:32
Пока не могу посмотреть видео, гляну вечером.
Но мне кажется, что при работе с ширмой важно синхронизировать её формирование с прерыванием.
При скроллинге вверх, не должно быть проблем с мерцанием, а вот при скроллинге вниз, ширма будет перескакивать в верх экрана, и нужно успевать быстро её удалить, пока "луч" не добрался до вывода верхних строк рабочей области экрана.
Это моё субъективное мнение.

svofski
17.07.2020, 11:57
Не претендую на оптимальность, но вот как написано заполнение ширмы в River Raid: ClearBlinds и DrawBlinds
https://github.com/svofski/incursiondelrio/blob/f1a3403348ec3a31a4beb93a7b17eaaed842b148/incursion.asm#L493

Согласен с KTSerg -- ширма не освобождает от необходимости синхронизации, синхронизация так же важна, как и без нее.

Раз синхронизация все равно требуется, то может быть проще все-таки без ширмы.Но тут возникает, разумеется, проблема с такими игровыми вещами, как вывод счета, времени, жизней. А это по сути ширма.

x-code
17.07.2020, 12:12
Автор, а вот тебе источник вдохновения для будущего шедевра:


https://www.youtube.com/watch?v=mDqCEbRmdrw

metamorpho
17.07.2020, 12:30
Автор, а вот тебе источник вдохновения для будущего шедевра:

x-code, спасибо!! Именно такого рода геймплей будет мой первый пробный шедевр


KTSerg, svofski спасибо за советы,
но я явно не улавливаю тему синхронизации :)

Например вот эта мысль: "Если скролл вверх, внизу надо нарисовать новое. Это можно сделать в интервал от прерывания до начала сканирования лучом обновляемой области."

Как узнать когда начался "интервал от прерывания до начала сканирования лучом обновляемой области" ?
Может пример какой есть ?

Ещё как узнать насколько может быть долгой программа обработки прерываний ?

svofski
17.07.2020, 12:54
Тут все просто. Каждый кадр занимает ровно 59904 такта. Время исполнения каждой инструкции дано в таблице (https://github.com/svofski/vector06cc/wiki/Instruction_Timings). Дальше можно просто посчитать.

Разумеется рассчитывать весь экран -- это очень занудно. Для почти всех случаев достаточно оценочных данных и простеньких замеров. Можно в отладчике смотреть на число тактов, VV по крайней мере показывает текущий такт экрана, это очень удобно. Или можно выводить другой цвет бордюра, как я делал. Сделал какую-то тормозную процедуру, поменял бордюр с черного на красный до и с красного на черный после. Посмотрел на экран, ага, вот столько строк у меня ушло на этот спрайт, или что-то такое.

KTSerg
17.07.2020, 13:55
metamorpho, если не секрет, покажи код подпрограммы прерывания.
Что у тебя там обрабатывается?
В игре например палитру можно программировать не в прерывании а один раз при старте программы отдельной процедурой, ну и если есть необходимость специально вызывать процедуру программирования палитры.

metamorpho
17.07.2020, 14:25
Конечно не секрет :) Этот код практически без изменений я взял у Лебедева


INIT: PUSH H
PUSH B
PUSH D
PUSH PSW
LDA WRPAL ; ПРОВЕРКА РАЗРЕШЕНИЯ ЗАПИСИ ПАЛИТРЫ В
ORA A ; ОЗУ ЦВЕТОГЕНЕРАТОРА.
JZ NWRPAL
MVI A,88H
OUT 00H
LXI H,COLR15 ; ЗАПИСЬ ПАЛИТРЫ.
LXI D,100FH
INIT1: MOV A,E
OUT 02
MOV A,M
OUT 0CH
OUT 0CH
OUT 0CH
OUT 0CH
OUT 0CH
DCX H
OUT 0CH
DCR E
OUT 0CH
DCR D
OUT 0CH
JNZ INIT1
NWRPAL: MVI A,8AH ; ПРОВЕРКА НАЖАТИЯ НА ЛЮБУЮ КЛАВИШУ
OUT 00 ; МАТРИЦЫ КЛАВИАТУРЫ 8*8 (КРОМЕ УС,СС,РУС/ЛАТ).
XRA A
OUT 03
IN 2
STA STATUS
MVI A,0FEH ; ПРОВЕРКА НАЖАТИЯ НА КЛАВИШИ ИГРОВОГО РЯДА.
OUT 03
IN 02
STA KEYKOD
MVI A,88H
OUT 00
LDA BORDER ; УСТАНОВКА ЦВЕТА БОРДЮРА.
ANI 0FH
OUT 02
LDA SCROLL ; УСТАНОВКА ВЕРТИКАЛЬНОГО ПОЛОЖЕНИЯ ЭКРАНА.
OUT 03
;
; ОБРАБОТКА ВЫСОТЫ И ДЛИТЕЛЬНОСТИ ЗВУКА ПО НОМЕРУ ПАРАМЕТРА ЗВУКА.
;
LDA TON ; ВЗЯТЬ КОД ИЗ БУФЕРА НОМЕРОВ ПАРАМЕТРОВ ЗВУКА.
ORA A ; НОМЕР ПАРАМЕТРА УСТАНОВЛЕН?
JZ TSSOUN ; ЕСЛИ НЕТ - ПЕРЕЙТИ НА ПРОВЕРКУ ОТРАБОТКИ ДЛИТ.ЗВУКА.
DCR A ; УМЕНШИТЬ НОМЕР НА 1, Т.К. МАССИВ НАЧИН. С НУЛЕВОГО.
ADD A ; УМНОЖИТЬ НОМЕР ПАРАМЕТРОВ ЗВУКА НА 4, ТАК КАК
ADD A ; ПАРАМЕТРЫ ОДНОГО ЗВУКА ЗАНИМАЮТ 4 БАЙТА.
MOV E,A ; ПОДГОТОВИТЬ В "DE" СМЕЩЕНИЕ ОТ НАЧАЛА ПАРАМЕТРОВ.
MVI D,0
LXI H,BAZTON ; УСТАНОВИТЬ В "HL" АДРЕС НАЧАЛА ПАРАМЕТРОВ ЗВУКА.
DAD D ; СЛОЖЕНИЕМ С "DE" ПОЛУЧИТЬ В "HL" АДРЕС НУЖНЫХ ПАРАМ.
MVI A,0B6H ; УСТАНОВИТЬ РЕЖИМ 3 ТАЙМЕРА ДЛЯ КАНАЛА 2, ЗАПИСЬ КОЭФ-
OUT 08 ; ФИЦИЕНТА ДЕЛЕНИЯ В ДВА БАЙТА - СНАЧАЛА МЛ. ПОТОМ СТ.
MOV A,M ; ВЗЯТЬ МЛАДШИЙ БАЙТ КОЭФФ. ДЕЛЕНИЯ И
OUT 09 ; ЗАПИСАТЬ В КАНАЛ 2 ТАЙМЕРА.
INX H ; ПЕРЕДВИНУТЬ УКАЗАТЕЛЬ НА СЛЕДУЮЩИЙ БАЙТ ПАРАМЕТРОВ.
MOV A,M ; ВЗЯТЬ СТАРШИЙ БАЙТ КОЭФФ. ДЕЛЕНИЯ И
OUT 09 ; ЗАПИСАТЬ В КАНАЛ 2 ТАЙМЕРА.
INX H
MOV E,M ; ВЗЯТЬ В ПАРУ "DE" ДЛИТЕЛЬНОСТЬ ЗВУЧАНИЯ.
INX H
MOV D,M
XCHG ; И ЗАПИСАТЬ ЕЕ В
SHLD STSOUN ; СЧЕТЧИК ВРЕМЕНИ ЗВУЧАНИЯ.
XRA A ; ОБНУЛИТЬ БУФЕР НОМЕРОВ ПАРАМЕТРОВ ЗВУКА (Т.Е. ПАРА-
STA TON ; МЕТРЫ ВЗЯТЫ И ИХ НЕ НУЖНО СНОВА ОПРЕДЕЛЯТЬ).
JMP EXINIT ; ВЫЙТИ ИЗ П/П ОБРАБОТКИ СИСТЕМНОГО ПРЕРЫВАНИЯ.
;
TSSOUN: LHLD STSOUN ; ВЗЯТЬ СЧЕТЧИК ВРЕМЕНИ ЗВУЧАНИЯ И ПРОВЕРИТЬ,
MOV A,H ; РАВЕН ЛИ ОН НУЛЮ (ВРЕМЯ ЗВУЧАНИЯ КОНЧИЛОСЬ)?
ORA L
JZ OFSOUN ; ЕСЛИ КОНЧИЛОСЬ - ВЫКЛЮЧИТЬ ЗВУК!
DCX H ; УМЕНЬШИТЬ СЧЕТЧИК.
SHLD STSOUN
JMP EXINIT ; И ВЫЙТИ ИЗ П/П ПРЕРЫВАНИЯ.
OFSOUN: MVI A,0B6H ; ВЫКЛЮЧИТЬ КАНАЛ 2 ТАЙМЕРА ПУТЕМ ЗАПИСИ В РЕГ.
OUT 08 ; РЕЖИМА УПР. СЛОВА ДЛЯ ЭТОГО КАНАЛА БЕЗ ПАРАМ.
EXINIT: XRA A
STA WRPAL
POP PSW
POP D
POP B
POP H
EI
RET

KTSerg
17.07.2020, 19:41
Конечно не секрет :) Этот код практически без изменений я взял у Лебедева
...

metamorpho, запусти вот это.
К твоему прерыванию добавил ширму и измерение цвета бордюра по методике svofski, для визуализации момента, когда заканчивается обработка прерывания.
когда цвет бордюра красный - выполняется прерывание, когда прерывание заканчивается - цвет меняется на зелёный.
Пробовал ширму в 8 строк, без музыки прерывание заканчивается точно с началом вывода рабочей области экрана, если ширму расположить внизу экрана, должно быть нормально, ведь стираться она успевает, а установка ширмы внизу экрана - луч до неё не успевает добежать.
По центру экрана ширма. Мусор - визуализация скролинга.

metamorpho
17.07.2020, 22:50
KTSerg, спасибо!!
Похоже получилось - теперь мельтишения нет, скроллинг чистый :)


https://youtu.be/Tf4P3SB_fo8

KTSerg
18.07.2020, 02:56
...
Похоже получилось - теперь мельтишения нет, скроллинг чистый :)
...
Что-то не совсем понятное, рассмотреть сложно, вроде какое-то смещение есть, и не равномерность скроллинга.
А можно "rom" выложить для рассмотреть скроллинг, а то не понятно, воспроизведение видео подтормаживает, или скроллинг скачет.

metamorpho
18.07.2020, 08:46
В приложении rom

А вто как выглядит программа прерываний



INIT: PUSH H
PUSH B
PUSH D
PUSH PSW
LDA WRPAL ; ПРОВЕРКА РАЗРЕШЕНИЯ ЗАПИСИ ПАЛИТРЫ В
ORA A ; ОЗУ ЦВЕТОГЕНЕРАТОРА.
JZ NWRPAL
MVI A,88H
OUT 00H
LXI H,COLR15 ; ЗАПИСЬ ПАЛИТРЫ.
LXI D,100FH
INIT1: MOV A,E
OUT 02
MOV A,M
OUT 0CH
OUT 0CH
OUT 0CH
OUT 0CH
OUT 0CH
DCX H
OUT 0CH
DCR E
OUT 0CH
DCR D
OUT 0CH
JNZ INIT1
NWRPAL: MVI A,8AH ; ПРОВЕРКА НАЖАТИЯ НА ЛЮБУЮ КЛАВИШУ
OUT 00 ; МАТРИЦЫ КЛАВИАТУРЫ 8*8 (КРОМЕ УС,СС,РУС/ЛАТ).
XRA A
OUT 03
IN 2
STA STATUS
MVI A,0FEH ; ПРОВЕРКА НАЖАТИЯ НА КЛАВИШИ ИГРОВОГО РЯДА.
OUT 03
IN 02
STA KEYKOD
MVI A,88H
OUT 00
LDA BORDER ; УСТАНОВКА ЦВЕТА БОРДЮРА.
ANI 0FH
OUT 02
LDA SCROLL ; УСТАНОВКА ВЕРТИКАЛЬНОГО ПОЛОЖЕНИЯ ЭКРАНА.
OUT 03
;jmp EXINIT
; ОБРАБОТКА ВЫСОТЫ И ДЛИТЕЛЬНОСТИ ЗВУКА ПО НОМЕРУ ПАРАМЕТРА ЗВУКА.
;
LDA TON ; ВЗЯТЬ КОД ИЗ БУФЕРА НОМЕРОВ ПАРАМЕТРОВ ЗВУКА.
ORA A ; НОМЕР ПАРАМЕТРА УСТАНОВЛЕН?
JZ TSSOUN ; ЕСЛИ НЕТ - ПЕРЕЙТИ НА ПРОВЕРКУ ОТРАБОТКИ ДЛИТ.ЗВУКА.
DCR A ; УМЕНШИТЬ НОМЕР НА 1, Т.К. МАССИВ НАЧИН. С НУЛЕВОГО.
ADD A ; УМНОЖИТЬ НОМЕР ПАРАМЕТРОВ ЗВУКА НА 4, ТАК КАК
ADD A ; ПАРАМЕТРЫ ОДНОГО ЗВУКА ЗАНИМАЮТ 4 БАЙТА.
MOV E,A ; ПОДГОТОВИТЬ В "DE" СМЕЩЕНИЕ ОТ НАЧАЛА ПАРАМЕТРОВ.
MVI D,0
LXI H,BAZTON ; УСТАНОВИТЬ В "HL" АДРЕС НАЧАЛА ПАРАМЕТРОВ ЗВУКА.
DAD D ; СЛОЖЕНИЕМ С "DE" ПОЛУЧИТЬ В "HL" АДРЕС НУЖНЫХ ПАРАМ.
MVI A,0B6H ; УСТАНОВИТЬ РЕЖИМ 3 ТАЙМЕРА ДЛЯ КАНАЛА 2, ЗАПИСЬ КОЭФ-
OUT 08 ; ФИЦИЕНТА ДЕЛЕНИЯ В ДВА БАЙТА - СНАЧАЛА МЛ. ПОТОМ СТ.
MOV A,M ; ВЗЯТЬ МЛАДШИЙ БАЙТ КОЭФФ. ДЕЛЕНИЯ И
OUT 09 ; ЗАПИСАТЬ В КАНАЛ 2 ТАЙМЕРА.
INX H ; ПЕРЕДВИНУТЬ УКАЗАТЕЛЬ НА СЛЕДУЮЩИЙ БАЙТ ПАРАМЕТРОВ.
MOV A,M ; ВЗЯТЬ СТАРШИЙ БАЙТ КОЭФФ. ДЕЛЕНИЯ И
OUT 09 ; ЗАПИСАТЬ В КАНАЛ 2 ТАЙМЕРА.
INX H
MOV E,M ; ВЗЯТЬ В ПАРУ "DE" ДЛИТЕЛЬНОСТЬ ЗВУЧАНИЯ.
INX H
MOV D,M
XCHG ; И ЗАПИСАТЬ ЕЕ В
SHLD STSOUN ; СЧЕТЧИК ВРЕМЕНИ ЗВУЧАНИЯ.
XRA A ; ОБНУЛИТЬ БУФЕР НОМЕРОВ ПАРАМЕТРОВ ЗВУКА (Т.Е. ПАРА-
STA TON ; МЕТРЫ ВЗЯТЫ И ИХ НЕ НУЖНО СНОВА ОПРЕДЕЛЯТЬ).
JMP EXINIT ; ВЫЙТИ ИЗ П/П ОБРАБОТКИ СИСТЕМНОГО ПРЕРЫВАНИЯ.
;
TSSOUN: LHLD STSOUN ; ВЗЯТЬ СЧЕТЧИК ВРЕМЕНИ ЗВУЧАНИЯ И ПРОВЕРИТЬ,
MOV A,H ; РАВЕН ЛИ ОН НУЛЮ (ВРЕМЯ ЗВУЧАНИЯ КОНЧИЛОСЬ)?
ORA L
JZ OFSOUN ; ЕСЛИ КОНЧИЛОСЬ - ВЫКЛЮЧИТЬ ЗВУК!
DCX H ; УМЕНЬШИТЬ СЧЕТЧИК.
SHLD STSOUN
JMP EXINIT ; И ВЫЙТИ ИЗ П/П ПРЕРЫВАНИЯ.
OFSOUN: MVI A,0B6H ; ВЫКЛЮЧИТЬ КАНАЛ 2 ТАЙМЕРА ПУТЕМ ЗАПИСИ В РЕГ.
OUT 08 ; РЕЖИМА УПР. СЛОВА ДЛЯ ЭТОГО КАНАЛА БЕЗ ПАРАМ.
EXINIT: XRA A
STA WRPAL

LDA kub_napr
CPI 3 ; vverx
JZ trapinko2
CPI 4 ; vverx
JZ trapinko1
jmp trapinko3

trapinko1:
call shirm0 ; стираем ширму
lhld ashirm ;
lda scroll
inr a
mov l,a
shld ashirm ;
call shirm1 ; рисуем ширму
jmp trapinko4

trapinko2:
call shirm0wwt ;
lhld ashirm2 ;
lda scroll
adi 9
mov l,a
shld ashirm2 ;
call shirm1wwt ;
jmp trapinko4

trapinko3:
call shirm0
call shirm0wwt
trapinko4:
POP PSW
POP D
POP B
POP H
EI
RET

KTSerg
18.07.2020, 10:55
В приложении rom

Спасибо.
Ширму не нужно убирать когда персонаж стоит на месте. Пусть она будет всегда. Иначе возникает ощущение, что экран дёргается, то приподнимается, то опускается.
И странно, но проскакивают артефакты с правой стороны ширмы, при движении вверх в одном месте лабиринта, при движении вниз - в другом.

- - - Добавлено - - -

Я изменил цвет фона, что-бы было видно ширму.
Есть два глюка с ширмой.
Первый, если при движении персонажа вверх по лабиринту, непосредственно перед столкновением со стеной нажать клавишу вниз, то ширма не удаляется. Сделал пару скриншотов, с не удаленной ширмой.
И второй, видимо при переходе скроллинга через 0 ширма рисуется левее чем нужно. Это проявляется как при движении вниз, так и при движении вверх.

metamorpho
18.07.2020, 14:45
KTSerg, спасибо за отлов багов.

Вот вариант (rom) когда ширму не убирать.
Насколько я понимаю при движении вверх программа не успевает отрисовывать ширму.

KTSerg
18.07.2020, 15:40
...
Вот вариант (rom) когда ширму не убирать.
Насколько я понимаю при движении вверх программа не успевает отрисовывать ширму.
А для чего используется сразу две ширмы?
Мне кажется одной вполне должно быть достаточно.
Может если пользоваться только одной ширмой, и выводить лабиринт только под ней, то и времени будет достаточно?
И остался баг со смещением ширмы, где-то адрес начала ширмы задаётся например $80FF, а не $81FF как обычно, и для нижней ширмы аналогично. Просто ширма стала длиннее, и артефакты не выскакивают при её смещении ;)

metamorpho
18.07.2020, 15:52
А для чего используется сразу две ширмы? Мне кажется одной вполне должно быть достаточно.
Может если пользоваться только одной ширмой, и выводить лабиринт только под ней, то и времени будет достаточно?


До меня только сейчас дошло, что можно использовать только одну ширму и рисовать нужное только внизу экрана и при движении вверх и при движении вниз.
Буду изменять код. Сделаю ширму только снизу (надеюсь это решит проблему).

Ещё вопрос как сделать эффект "небольшой втряски" экрана как бы в бок ?
Что можно при этом использовать в сочетании с аппаратным вертикальным скроллингом ?

Ещё кто знает как реализован эффект искажения шахматной доски в конце вот этой демки ?

https://www.youtube.com/watch?v=7Z0dsZUAyd0

KTSerg
18.07.2020, 15:59
Для "встряски" по горизонтали, либо копировать всю память видео-ОЗУ со смещением... но быстро не получится - от артефактов не избавиться... Либо подобрать простую, но эффектную картинку скажем 4-ёх цветную... вывести её два раза со смещением в разных плоскостях экрана и переключать палитру, чтобы была видна то одна, то другая, а если совместить ещё и с вертикальным скроллингом...

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

svofski
18.07.2020, 16:17
Ещё кто знает как реализован эффект искажения шахматной доски в конце вот этой демки ?

Шашечки это все "мультиколор", так же, как и бегущие через весь экран огромные буквы. Экранный буфер для них не используется, вот пример вывода одной строки:
https://github.com/svofski/8-bit-snail/blob/master/src/8snail.asm#L2020
Подвинуть по горизонтали такое нетрудно, надо задержаться на 4 или 8 тактов. См. checker_a1, checker_a2, checker_a3: там вставлен 1 и 2 nop-а соответственно.

- - - Добавлено - - -


Либо на картинке должен быть повторяющийся арнамент, который в сочетании с вертикальным скроллингом (определённого шага) даёт эффект горизонтального смещения картинки. Такие эксперименты тут на форуме выкладывали в демо-эффектах вроде.
Это было у Manwe в рассказе про демки на БК-0011, примерно вот тут: https://youtu.be/jlMS5s0ImM4?t=934

metamorpho
18.07.2020, 16:43
Код исправил (rom прилагается), теперь всё ровно идёт :)

KTSerg, svofski спасибо за идеи и ссылки !!

Ещё вопрос, можно ли на Векторе вызвать на бордюре разноцветные рандомные тонкие линии ?

KTSerg
18.07.2020, 16:50
...
Это было у Manwe в рассказе про демки на БК-0011, примерно вот тут: https://youtu.be/jlMS5s0ImM4?t=934
Не знаю как на счет БК-0011, но у меня на компе есть несколько rom-ов для Вектора под названием "HVSCROL", и исходники к ним (подозреваю, что с этого сайта загружено). В исходниках есть строка ";Иван Городецкий 29.05.2018" ;)
В них горизонтально-вертикальный скроллинг повторяющегося арнамента :)

svofski
18.07.2020, 23:03
Не знаю как на счет БК-0011, но у меня на компе есть несколько rom-ов для Вектора под названием "HVSCROL", и исходники к ним (подозреваю, что с этого сайта загружено). В исходниках есть строка ";Иван Городецкий 29.05.2018"
Отсюда и дальше:
https://zx-pk.ru/threads/21907-demo-effekty-dlya-vektora.html?p=965666&viewfull=1#post965666

- - - Добавлено - - -


Ещё вопрос, можно ли на Векторе вызвать на бордюре разноцветные рандомные тонкие линии ?
Сколько угодно.

svofski
19.07.2020, 09:57
Посмотрел "Ширма бинго" (хорошее название, если не для игры то для рок-группы). Синхронизация ширмы работает. Но вредный глаз отказывается не видеть, что анимированные спрайты появляются резко только когда их клетка становится видна целиком.

metamorpho
19.07.2020, 20:12
Посмотрел "Но вредный глаз отказывается не видеть, что анимированные спрайты появляются резко только когда их клетка становится видна целиком.

svofski, спасибо за отлавливание багов!!
Исправленная версия в приложении. В этой версии снова добавил верхнюю ширму, чтобы скрыть "неполную" часть строки уровня, поскольку движущиеся объекты там не обновляются, но на экране видно что они есть. Плюс визуально уровнял экран, кажется так лучше смотрится. Верхнюю ширма теперь рисуется нормально, т.к. (в ходе экспериментов) теперь её прорисовка идёт 1,5 раза (1 раз полностью, и тут же второй раз, но только первые 7 столбиков там где глючила она - в итоге не понял почему но всё получилось).

Возникла проблема - начал подбирать палитру для игры и столкнулся с неким несоответствием (или возможно я чего-то не понял.
Вот программа
http://sensi.org/scalar/ware/770/
В этой программе отображение цветов кажется несоответствует векторовским цветам по факту.
Например у меня белый цвет в палитре , не такой белый как в той программе. И жёлтый там уж очень насыщенный.
В чём может быть причина ?

Ещё может кто знает (или готовый код есть) как сделать то что сделали в программе "Тест устройств".
Там на бордюре отразили 15 цветов палитры.

KTSerg
19.07.2020, 20:40
...
Возникла проблема - начал подбирать палитру для игры и столкнулся с неким несоответствием (или возможно я чего-то не понял.
Вот программа
http://sensi.org/scalar/ware/770/
В этой программе отображение цветов кажется несоответствует векторовским цветам по факту.
Например у меня белый цвет в палитре , не такой белый как в той программе. И жёлтый там уж очень насыщенный.
В чём может быть причина ?

Ещё может кто знает (или готовый код есть) как сделать то что сделали в программе "Тест устройств".
Там на бордюре отразили 15 цветов палитры.
А чем не устраивает белый FF и желтый 3F ? (эти значения занесены в палитру и сделан скриншот).

По поводу цветных полос на бордюре... я ведь выкладывал твоё прерывание в котором изменением цвета бордюра обозначался конец выполнения подпрограммы... Попробуй добавлять задержки и снова менять цвет бордюра... получишь цветные полосы... но это съест все ресурсы процессора. Т.к. с отображением последней строки на экране начнётся новое прерывание.

metamorpho
19.07.2020, 21:15
Я нашёл причину расхождения цвета.
Оказалось на "Pretty 8080 Assembler" и на эмуляторе "VV" RGB цвета палитр различаются. Это странно. По идее должно быть одинаково.

Например на "VV" белый R=255 G=255 B=255 соответственно он выглядит чисто белым.
А на "Pretty 8080 Assembler" белый R=224 G=224 B=192 соответственно он выглядит мутно белым.

svofski
20.07.2020, 00:06
У синего младшего бита нет и в схеме ЦАП-а это никак не компенсируется. Значения резисторов для двух бит синего такие же, как и для старших бит зеленого и красного. Поэтому максимальное значение синего эквивалентно 6, а не 7, что и дает желтушку. На практике ее трудно заметить на 256-цветной таблице, но она все же бывает заметна на ч/б: http://sensi.org/scalar/ware/881/ В жизни все не так страшно, а на фотке из картотеки по-моему весьма экстремальный результат. Своими глазами я такого насыщенного желтого на месте 255 не видел.

224 в моих эмуляторах по похожей причине, я беру три бита цвета и сдвигаю их в старшие разряды, не додумывая младших. 111 -> 11100000 = 224.

ivagor
20.07.2020, 05:37
Вопрос с оттенками в палитре уже обсуждался, финальная часть начинается примерно здесь (https://zx-pk.ru/threads/19774-vektor-06ts-emulyatsiya-tsvetovoj-palitry.html?p=540169&viewfull=1#post540169). Если коротко, то я запомнил так: в большинстве случаев при подключении к цветному ТВ FF будет белый, но в некоторых менее распространенных случаях - желтоватый.

KTSerg
20.07.2020, 05:45
У синего младшего бита нет и в схеме ЦАП-а это никак не компенсируется. ...
Значит белый, хотя и не очень яркий должен быть 255-9=246=$F6 или по другому $06+$30+$C0=$F6 ?

metamorpho
20.07.2020, 09:05
С палитрой понятно. В принципе эти особенности не приносят каких-либо существенных изменений в разработку проекта.
Так что идём дальше. Следующий шаг: внедрение препятствий, ловушек и противников.
Но перед этим сделаю ускорение программы вывода спрайта - перейду на использование стека для этого.

svofski
20.07.2020, 12:08
Вопрос с оттенками в палитре уже обсуждался, финальная часть начинается примерно здесь (https://zx-pk.ru/threads/19774-vektor-06ts-emulyatsiya-tsvetovoj-palitry.html?p=540169&viewfull=1#post540169). Если коротко, то я запомнил так: в большинстве случаев при подключении к цветному ТВ FF будет белый, но в некоторых менее распространенных случаях - желтоватый.

Занятно. Вроде получается, что при аналоговой инверсии желтого быть не должно, а при цифровой должно. Но в жизни это как-то не совсем так.

metamorpho
20.07.2020, 16:20
Исследуя исходники Лебедева, а именно его способ вывода спрайта, заметил что он
вначале подпрограммы вывода спрайта запрещает прерывания, а в конце снова их разрешает.
Чем грозит запрет прерываний в основном цикле игры ?

svofski
20.07.2020, 17:06
Это зависит от основного цикла игры. Если он синхронный с разверткой и укладывается целиком во время одного кадра, то ничем, потому что прерывание не случится когда его не ждут. Если стек используется как канонический стек, а не как ухищрение для быстрой пересылки памяти, то тоже практически ничем - прерывание обработается и исполнение продолжится где прервалось. Плохо, если синхронности нет, прерывания разрешены, а стек используется для пересылки данных. Тогда может возникнуть незапланированная ситуация.

metamorpho
20.07.2020, 19:06
Настроил палитру на 8 цветов (три плоскости).
Подправил графику.
Пытался сделать вывод спрайта через стек - при этом начинает глючить верхняя ширма и ещё на экране появляется немного мусора.
Решил делать оптимизацию без использования стека - разворачиваю циклы и убираю лишнее.
Уже переделал одну подпрограмму вывода пустого спрайта - работает без мусора на экране, хотя по сути тоже самое что и со стеком пробовал писать. Не понимаю почему со стеком не получается.


https://www.youtube.com/watch?v=5eQX5lPlnm4

KTSerg
20.07.2020, 19:13
... Не понимаю почему со стеком не получается.

А при выводе спрайта с помощью стека, точно прерывания запрещал перед выводом спрайта и разрешал после вывода?

metamorpho
20.07.2020, 19:25
А при выводе спрайта с помощью стека, точно прерывания запрещал перед выводом спрайта и разрешал после вывода?

Да

jerri
20.07.2020, 19:53
metamorpho, а давай попробуем без запретов прерываний методом Медногова


как ты выводишь графику?

metamorpho
20.07.2020, 20:06
Вот вывод графики через стек пробовал - в целом работет но есть артефакты на экране



; универсальный вывод трети спрайта для затирания пустого места

SpriteC8zerowww:

PUSH H
PUSH D
PUSH B
PUSH PSW

MOV A,H ; сохраняем начало столбик X плоскость (1) куда выводим графику
STA pozic_xP1
ADI 20H ; вычисляем следующую плоскость (2) начальный столбец
STA pozic_xP2 ; сохраняем
ADI 20H ; вычисляем следующую плоскость (3) начальный столбец
STA pozic_xP3 ; сохраняем
MOV D,L
;=======================
LXI H,0 ; ВЫВОД "ПУСТОГО" СПРАЙТА. (СДЕЛАН ОТДЕЛЬНО ПО
DAD SP ; БЫСТРОМУ АЛГОРИТМУ ДЛЯ ПОВЫШЕНИЯ БЫСТРОДЕЙСТВИЯ).
SHLD BUFSP
DI
LXI B,00h

LDA pozic_xP1
MOV H,A ; установка первого столбца X плоскость (1) куда выводим графику
MOV L,D
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B

LDA pozic_xP2
MOV H,A ; установка первого столбца X плоскость (1) куда выводим графику
MOV L,D
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B

LDA pozic_xP3
MOV H,A ; установка первого столбца X плоскость (1) куда выводим графику
MOV L,D
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B

LHLD BUFSP
SPHL
EI
POP PSW
POP B
POP D
POP H

RET


А что это за метод Медногова ?

jerri
20.07.2020, 21:40
Вот вывод графики через стек пробовал - в целом работет но есть артефакты на экране



; универсальный вывод трети спрайта для затирания пустого места

SpriteC8zerowww:

PUSH H
PUSH D
PUSH B
PUSH PSW

MOV A,H ; сохраняем начало столбик X плоскость (1) куда выводим графику
STA pozic_xP1
ADI 20H ; вычисляем следующую плоскость (2) начальный столбец
STA pozic_xP2 ; сохраняем
ADI 20H ; вычисляем следующую плоскость (3) начальный столбец
STA pozic_xP3 ; сохраняем
MOV D,L
;=======================
LXI H,0 ; ВЫВОД "ПУСТОГО" СПРАЙТА. (СДЕЛАН ОТДЕЛЬНО ПО
DAD SP ; БЫСТРОМУ АЛГОРИТМУ ДЛЯ ПОВЫШЕНИЯ БЫСТРОДЕЙСТВИЯ).
SHLD BUFSP
DI
LXI B,00h

LDA pozic_xP1
MOV H,A ; установка первого столбца X плоскость (1) куда выводим графику
MOV L,D
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B

LDA pozic_xP2
MOV H,A ; установка первого столбца X плоскость (1) куда выводим графику
MOV L,D
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B

LDA pozic_xP3
MOV H,A ; установка первого столбца X плоскость (1) куда выводим графику
MOV L,D
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B
INR H
SPHL
PUSH B
PUSH B
PUSH B
PUSH B

LHLD BUFSP
SPHL
EI
POP PSW
POP B
POP D
POP H

RET


А что это за метод Медногова ?

это у тебя не вывод спрайта, это у тебя стирание спрайта.

метод Медноногова состоит в том чтобы контролировать регистровую пару содержащую данные и контролировать стек на прерываниях.

прерывание выглядит так
надеюсь ты умеешь код Z80




ISR
di
ex (sp),hl ;забираем в hl адрес возврата
ld (isr_jmp),hl ;сохраняем его для выхода
pop hl ;восстанавливаем hl
;здесь надо сохранить стек
ld (isr_stek),sp ;это для Z80 у тебя будет чуть по другому
;--------------------------
push bc ;ВСЕГДА используем BC для рисования спрайтов и прочих элементов
;восстанавливаем данные на стеке
;скорее всего рисовать через стек на экране не будет очень хорошей идеей.

ld sp,isr_own_stek
push hl,de,bc,af

;дальше прерываем

pop af,bc,de,hl
ld sp,$
isr_stek equ $-2
ei
jp $
isr_jmp equ $-2



при рисовании спрайта всегда использовать BC

например


;hl адрес спрайта
;de адрес на экране

;первую пару забираем вот такой комбинацией
ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld sp,hl
ex de,hl

ld (hl),c
inc l
ld (hl),b
inc l
pop bc

etc

svofski
20.07.2020, 21:55
Я попробовал по быстрому вставить в рыбу с гиббоном, у меня рисуется черный прямоугольник. По тексту я тоже навскидку ничего особенного не вижу. Видимо причина артефактов где-то еще.

ivagor
21.07.2020, 06:18
Быстрый вывод спрайтов - это хорошо, но я бы в первую очередь попробовал уменьшить моргания спрайта. Код я не видел, но могу предположить, что при движении спрайт сначала стирается полностью, потом полностью рисуется на новом месте. Если наложение спрайтов не планируется (или этот случай можно отрабатывать отдельно), то лучше стирать только там, где спрайта уже нет (или не будет), а там где он будет - не стирать, а сразу выводить.
Второй момент - у меня по видео создалось впечатление, что спрайты выводятся по плоскостям (сначала одна, потом вторая и т.д.). Так быстрее, но ввиду невозможности сделать двойную буферизацию я бы лучше сделал вывод сразу в три плоскости, это намного уменьшит вероятность заметности этапов прорисовки. Как примерно можно сделать:
1. Запрещаем прерывания (метод Медноногова тут не поможет, регистров не хватает), сохраняем стек.
2. Формируем в BC, DE и HL адреса трех плоскостей.
3. Выводим примерно так (8 точек с 8 цветами): pop psw\ dcx sp\ stax b\ dcr c\ pop psw\ dcx sp\ stax d\ dcr e\ pop psw\ dcx sp\ mov m,a\ dcr l
Это не самый быстрый вариант в принципе, но самый быстрый с "почти одновременным" выводом в три плоскости.
4. Возвращаем стек, разрешаем прерывания.

Если фоновая музыка с AY или ВИ53 не планируется, то в запрете прерываний проблем нет.

KTSerg
21.07.2020, 07:34
Мне кажется, что если спрайты часто выводятся не полностью, а частями по 8 строк (например), то и хранить их можно в соответствующем (оптимизированном) виде.
А при выводе спрайта на экран использовать стек не для переноса на экран, а для чтения спрайта. Тогда переносить указатель стека не нужно, а пересчитывать значение пары HL значительно проще и быстрее (DAD D), задал смещение на новую плоскость и получил один поток переноса в 72 байта (8 строк, 3 плоскости, 3 столбца) в 3 захода... ведь переход с последней плоскости на первую в новый столбец тоже можно смещением задать...

metamorpho
21.07.2020, 08:38
jerri, svofski, ivagor, KTSerg спасибо за советы, тесты и исследования !!

У меня спрайты выводятся по плоскостям, сначала в первую, потом вторую и третью.
Вод код вывода спрайта, который я использую (сейчас тоже самое, но развернул циклы)



;Вывод квадратика 24x24 точки в три плоскости для статичных объектов
;
SpriteC3:
PUSH H
PUSH D
PUSH B
MOV A,H ; сохраняем начало столбик X плоскость (1) куда выводим графику
STA pozic_xP1
ADI 20H ; вычисляем следующую плоскость (2) начальный столбец
STA pozic_xP2 ; сохраняем
ADI 20H ; вычисляем следующую плоскость (3) начальный столбец
STA pozic_xP3 ; сохраняем

MOV A,L ; сохраняем начало строки Y куда выводим графику
STA pozic_y

MVI B,3 ;в регистр "B" - счетчик столбиков X
Kvadr1:MVI C,24 ;в регистр "C" - счетчик строк Y
Kvadr2: LDAX D ; загружаем акумулятор А содержимым графики
MOV M,A ; выводим в экран по адресу "HL" байт графики
DCR L ; ; куда выводить "HL=HL+1" строка Y +1
INX D ; DE=DE+1 увеличиваем адрес откуда брать графику
DCR C ; -1 все 24 байт строки вывели ?
JNZ Kvadr2 ;если столбик не вывели полностью то продолжаем
; переключаем на следующий столбик-адрес вывода графики
INR H
LDA pozic_y
MOV L,A ; установка Y начала строки
DCR B ; -1 все 3 столбика X вывели ?
JNZ Kvadr1 ;если столбики не вывели полностью то продолжаем

;============== вывод в плоскость 2
LDA pozic_xP2
MOV H,A ; установка первого столбца X плоскость (2) куда выводим графику

MVI B,3 ;в регистр "B" - счетчик столбиков X
Kvadr11:MVI C,24 ;в регистр "C" - счетчик строк Y
Kvadr22: LDAX D ; загружаем акумулятор А содержимым графики
MOV M,A ; выводим в экран по адресу "HL" байт графики
DCR L ; ; куда выводить "HL=HL+1" строка Y +1
INX D ; DE=DE+1 увеличиваем адрес откуда брать графику
DCR C ; -1 все 24 байт строки вывели ?
JNZ Kvadr22 ;если столбик не вывели полностью то продолжаем
; переключаем на следующий столбик-адрес вывода графики
INR H
LDA pozic_y
MOV L,A ; установка Y начала строки
DCR B ; -1 все 3 столбика X вывели ?
JNZ Kvadr11 ;если столбики не вывели полностью то продолжаем

;============== вывод в плоскость 3
LDA pozic_xP3
MOV H,A ; установка первого столбца X плоскость (2) куда выводим графику

MVI B,3 ;в регистр "B" - счетчик столбиков X
Kvadr111:MVI C,24 ;в регистр "C" - счетчик строк Y
Kvadr222: LDAX D ; загружаем акумулятор А содержимым графики
MOV M,A ; выводим в экран по адресу "HL" байт графики
DCR L ; ; куда выводить "HL=HL+1" строка Y +1
INX D ; DE=DE+1 увеличиваем адрес откуда брать графику
DCR C ; -1 все 24 байт строки вывели ?
JNZ Kvadr222 ;если столбик не вывели полностью то продолжаем
; переключаем на следующий столбик-адрес вывода графики
INR H
LDA pozic_y
MOV L,A ; установка Y начала строки
DCR B ; -1 все 3 столбика X вывели ?
JNZ Kvadr111 ;если столбики не вывели полностью то продолжаем

POP B
POP D
POP H
RET ;иначе - выйти из п/п вывода квадратиков


В движении спрайты у меня не стираются полностью, на старый спрайт накладывается новый со смещением затирая старый.

ivagor, да спрайты я тоже заметил немного моргают. Вывод сразу в три плоскости очень оригинально сделан, попробую воплотить идею, если это уменьшит моргание и не снизит сильно скорость, то будет здорово.

Фоновой музыки не планирую, но звуки будут. А звукам не помешает запрет прерываний ?

ivagor
21.07.2020, 11:13
В движении спрайты у меня не стираются полностью, на старый спрайт накладывается новый со смещением затирая старый.
Меня смущает, что помаргивает даже когда стоит на месте, в принципе не должно быть так заметно.
В chipndale все выводится тайлами 8x8 из буфера и там я особо не замечал морганий/миганий, хотя там вывод по плоскостям. Если выводить по плоскостям 24x24 точки, то вероятность увидеть моргание или артефакты плоскостной прорисовки гораздо больше. Т.е. еще один компромиссный вариант (без стека и "одновременного трехплоскостного" вывода) - рисовать по тайлам 8x8.


А звукам не помешает запрет прерываний ?
Если звук запускается и глушится в прерывании - то помешает.

svofski
21.07.2020, 11:31
Перемежение плоскостей по методу ivagor-a делает вывод спрайтов нечувствительным к положению луча на момент отрисовки, это по-моему самый робастный способ. Альтернатива -- это синхронизация с ходом луча, но в игре где много спрайтов это тяжело делать. Снимаю плащ КО.

Мы все очень впечатлились почином metamorpho и бросились критиковать и чинить микропроблемы, может быть преждевременно. Когда игра будет почти готова, и так будет очевидно где надо экономить и чинить, а где нет смысла тратить силы попусту. Пока по-моему все очень круто. metamorpho, спасибо, что не маринуешь прогресс! ;) Смотреть очень интересно.

ivagor
21.07.2020, 11:40
;Вывод квадратика 24x24 точки в три плоскости для статичных объектов
Все же процедура только для статичных или и для подвижных объектов (ГГ)?


Когда игра будет почти готова, и так будет очевидно где надо экономить и чинить, а где нет смысла тратить силы попусту.
Не обязательно все сразу чинить, но желательно сразу определить проблемные места и прикинуть методы их решения или хотя бы понять, можно ли в принципе починить. Графика в игрушке мне нравится, однозначный респект, но вот помаргивания (лично для меня) сильно портят впечатление. Слишком много я видел векторовских игрушек, в которых даже при нормальной графике спрайты моргали и мигали.

svofski
21.07.2020, 11:52
Тут главное стараться делать так, чтобы в случае положения проекта в долгий ящик, было бы понятно с какой стороны к нему подойти. Конечно, к немигающим спрайтам возвращаться приятно.

metamorpho
21.07.2020, 14:40
ivagor, svofski, KTSerg и всем другим спасибо за советы, идеи и поддержку !!


Все же процедура только для статичных или и для подвижных объектов (ГГ)?

У меня три разных подпрограммы вывода спрайтов.
1-я рисует те спрайты, которые не движуться (3 столбика по 24 байта)
2-я рисует те спрайты, которые движуться (4 столбика по 24 байта)
3-я рисует по частям (3 столбика по 8 байтов) спрайты (верхнюю, среднюю и нижнюю часть), которые выходят из под ширмы (высотой 8 точек) при вертикальном скроллинге

Реализовал вариант вывода спрайта "сразу в три плоскости" со стеком.
Пришлось переписывать формат сохраняемого файла моего
конвертора графики с РС на формат .db 1,2,3 для вставки в ассемблер.
Но это того стоило, это отличная идея от ivagor - оно реально НЕМОРГАЕТ !!!!
В приложении (rom) - смотреть только без движения т.к. реализовал только одну
подпрограмму когда спрайты не движуться.

Согласен что лучше с основополагающими моментами (такие как вывод спрайта) сразу определиться
и по возможности довести их до почти идеального состояния, ведь пишу шедевр не меньше :)
По сути основополагающие моменты это как каркас на который потом можно уже что-то прикрутить или открутить.

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

Мне нужно будет в заставке выводить музыку - для этого когда мы находимся в заставке игры можно в программе прерываний включить обработку мелодии, а когда находимся в игре обработку музыки можно отключить из программы прерываний - правильно ли я понимаю ?

Также мне нужно будет выводить звуковые эффекты.
Я так понял есть два варианта:
- первый сделать это через программу обработки прерываний
- второй сделать это в основном цикле программы

Какой вариант предпочтительней ? Какие плюсы и минусы этих вариантов ?

Я так понял звук можно формировать через порт 01, а также через ВИ53.
Какие преимущества и недостатки есть у этих способов ?

KTSerg
21.07.2020, 15:31
Нужно ещё уточнить один момент...
В прерываниях не должно быть вызова подпрограмм, которые выводят на экран спрайты.
В прерывании должна быть только работа с ширмой и программирование скроллинга (про опрос клавы и музыке пока речь не идёт, говорим о графике).

С моей (субъективной) точки зрения, основной цикл программы и прерывание должны взаимодействовать следующим образом:
Основной цикл программы крутится, можно даже ждать прерывания, парой ei, hlt.
Сразу после прерывания проверяем состояние клавы.
Если движения нет, то обрабатываем меняющиеся объекты (сверху вниз, убегая от луча).
Если есть движение по вертикали, то ещё и выводим под ширмой новые элементы лабиринта, после чего присваиваем некой переменной значение, что стены готовы. И уходим на ожидание прерывания.
В прерывании проверяем значение переменной, которая говорит, что стены готовы, переставляем ширму и присваиваем новое значение для скроллинга (не забывая сбросить значение переменной, что стены готовы).

С моей точки зрения, в таком случае, артефактов должно быть минимум. Особенно если ещё и оптимизировать вывод спрайтов подвижных объектов.

ivagor
21.07.2020, 16:20
Как я понял в последнем текущем варианте "одновременный" вывод используется только для неподвижных спрайтов и ГГ стоя на месте теперь не моргает. При движении по вертикали не моргает, предположительно из-за фактической синхронизации с разверткой и убеганием от луча. А вот при движении по горизонтали артефакты заметны. Ну и кирпичи портятся при движении по вертикали.
Если двигаться будет только ГГ, то можно просто привязать его вывод к развертке (до луча или после) и делать это самым быстрым способом не обращая внимания на порядок вывода байтов. Но если планируются и другие движущиеся объекты, то все они от луча явно не убегут и надо переходить на "одновременный" или почти одновременный вывод в три плоскости. Из почти одновременных один вариант я упоминал - выводить фрагментами 8x8 точек (8 байт одной плоскости, потом второй и третьей). Еще один вариант - выводить построчно, три байта одной плоскости, потом второй и третьей. Причем этот вывод удобнее и быстрее сделать змейкой:
Первая строка: первая плоскость направо, вторая налево, третья направо
Вторая строка: третья плоскость налево, вторая направо, первая налево
Т.е. две строки образуют "элементарную единицу" вывода. Справедливости ради - любой вывод будет быстрее змейкой, не только построчный. Плюс "почти одновременных" вариантов - там можно или метод Медноногова использовать или просто не использовать стек и в обоих этих случаях отказаться от запрета прерываний.

Насчет звука - если использовать ВИ53 в режиме 3 и стартовать/глушить звуки по прерываниям, то легко получить одинаковую длительность звуков и минимальную загрузку процессора. Но звуки будут сравнительно простые.

jerri
21.07.2020, 22:25
metamorpho, метод Медноногова позволяет выводить спрайты без запрета прерываний. Он для этого и делался.
поэтому я его тебе и рекомендую.

metamorpho
21.07.2020, 23:30
На данный момент определился что не буду использовать стек совместно с DI, т.к. это приводит к глюкам с ширмой, а также может помешать реализации звуков через программу обработки прерывания.

Написал свой вариант вывода спрайта по методу ivagor "сразу в 3 плоскости" без использования стека и без DI.
В приложении (rom).
Результат вроде неплохой. Очень редко появляется моргание.
По моим подсчётам (если я правильно подсчитал) уступает варианту со стеком на 20 тактов по выводу одной строки.
Вот код вывода одной строки


DCR L
LDA pozic_xP1
MOV H,A ; адрес плоскости 1
LDAX D
MOV M,A
INX D
DAD B ; адрес плоскости 2
LDAX D
MOV M,A
INX D
DAD B ; адрес плоскости 3
LDAX D
MOV M,A
INX D

ivagor
22.07.2020, 06:00
В Binorium_7 морганий не вижу, может они и есть, но получается очень редкие, с этим вполне можно жить.
Есть возможность небольшого ускорения за счет перехода к змейке по плоскостям. Условно делим картинку на блоки 8x2 точки
1. Вывод первых 8 точек как сейчас, только добавляем lxi b,8192
2. Вывод вторых 8 точек в обратном направлении по плоскостям, добавляем lxi b,-8192
lda+mov убираем. lxi - 12 тактов и 3 байта; lda+mov - 24 такта и 4 байта, т.е. выигрыш 12 тактов и 1 байт на каждых 8 точках.

Вариант одновременного вывода со стеком можно разогнать до скорости "обычного" вывода со стеком, если интерливить спрайты по 2 штуки, т.е. хранить их с шагом в 2 байта и вставлять в промежуток другой спрайт. При этом можно будет избавиться от трех dcx sp на 8 точек, т.е. -24 такта. Это просто для полноты картины, не агитирую за этот вариант, т.к. тут надо прерывания запрещать.

KTSerg
22.07.2020, 07:04
Для того чтобы понять, где можно использовать стек, а где не желательно, нужно визуализировать работу со спрайтами как предлагал svofski. Перед началом подпрограммы менять цвет фона, по окончании - восстанавливать. Например при работе с ширмой делать фон белым, при отрисовке персонажа - красным, стен - зеленым, монеты - желтым. При внесении изменений в алгоритмы, будет сразу видно, быстрее спрайт выводится - полоса стала уже, или стало медленнее.

- - - Добавлено - - -

По поводу Binorium_7.
При старте персонаж из стены выскакивает?
А что происходит при перезапуске программы (БЛК+СБР) ? Или это только в эмуляторе emu (не успел остальные проверить) что-то с палитрой странное?

ivagor
22.07.2020, 09:31
В Binorium_7 есть небольшая шероховатость - при скролле вверх виден паразитный штрих справа вверху.

KTSerg
22.07.2020, 10:02
В Binorium_7 есть небольшая шероховатость - при скролле вверх виден паразитный штрих справа вверху.
Мне вот ещё интересен один момент...
На сколько я понимаю, сейчас используется две ширмы, одна вверху и одна внизу... не будем обращать внимание на то, что это по сути одна сплошная ширма...
Мне вот, что интересно, при смещении, сначала удаляются обе ширмы, а потом они обе восстанавливаются уже на новом месте... (это ведь лишние затраты ресурсов).
Или всё-таки удаляется только одна, а потом с другой стороны выставляется новая? (что экономит затраты на ширму в два раза)

ivagor
22.07.2020, 10:22
Подробно операции с ширмой не смотрел, но кое-что там меня смутило. Совершенно точно надо объединить стирание ширмы в старой позиции и рисование ее в новой. dad d для перехода к соседнему столбцу не нужен, меняем на inr h. Теперь есть две регистровые пары, в одну заносим 0000 для стирания, в другую - FFFF для рисования. И подряд 8 push (половина - B и половина - D). Грубо это будет (8*16+8)*32=4352 такта.

jerri
22.07.2020, 10:58
ivagor, а сколько тактов всего во фрейме?

ivagor
22.07.2020, 11:00
312*192=59904 такта/фрейм

jerri
22.07.2020, 11:28
312*192=59904 такта/фрейм

обеъктов немного, скорости должно хватать.

svofski
22.07.2020, 12:09
Если ширма -- это просто черная рамка, то достаточно перерисовать столько строк, на сколько прокрутка. Правда в этом случае целесообразность ширмы под вопросом, зачем она? Но если там будет HUD с жизнями, уровнем, счетом итд, это будет не просто стереть две строки. Весь HUD придется перерисовывать целиком каждый раз.

KTSerg
22.07.2020, 12:15
В Binorium_7 есть небольшая шероховатость - при скролле вверх виден паразитный штрих справа вверху.
Есть ещё одна мысля по поводу ширмы...
Левый верхний угол мельтешит, из-за того, что не хватает времени стереть ширму и снова нарисовать до подхода луча к верхнему левому углу рабочей области экрана...
А если сначала выставить ширму на новом месте, а потом удалять старую ширму... то мельтешить не должно. ;)

ivagor
22.07.2020, 12:21
целесообразность ширмы под вопросом, зачем она?
Без ширмы можно "гладко" без видимого заворота при скролле вывести только 1 или 2 строки (смотря как выводить и сколько цветов 8 или 16). С ширмой намного удобнее и проще, но, конечно, цветов в 2 раза меньше.


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

S_V_B
22.07.2020, 12:32
Зачем выводить объекты которые не двигаются каждый фрэйм?
Если у вас фрэйм 50Гц... можно выводить чет-нечет- и не каких морганий не будет.

- - - Добавлено - - -

Может я не правильно выразился... у вас есть список отображения (связанный с обратным ходом луча), не включайте туда даже активные объекты если не было приращений.
Если по таймеру.. то можно разделить этот список на чет и не чет... в два раза меньше выводить.. на глаз не заметно.

metamorpho
22.07.2020, 15:48
Если ширма -- это просто черная рамка, то достаточно перерисовать столько строк, на сколько прокрутка. Правда в этом случае целесообразность ширмы под вопросом, зачем она? Но если там будет HUD с жизнями, уровнем, счетом итд, это будет не просто стереть две строки. Весь HUD придется перерисовывать целиком каждый раз.

Вверху и внизу экрана есть по 8 строк, которые появились из-за выбора размера спрайта 24х24 в итоге экран 240х240.
Ширма нужна для скрытия внизу рисования частей спрайтов при вертикальном скроллинге (они мельтешат).
Вверху ширма просто закрывает торчащую треть спрайта, т.к. в этой трети не отображается анимация движущихся элементов.
Сдвиг экрана при вертикальном скроллинге происходит так:
внизу экрана рисуется строка 8 точек и происходит скроллинг на 8 точек
итак три раза т.е. 8 х 3 =24 т.е. высота одного блока уровня

На данный момент задумка такая:
Жизни и уровни будут показываться только на статичном экране при потере жизни и при прохождении уровня.
Счёта в игре не будет, т.к. цель игры собрать все монетки, а вот сколько осталось собрать монеток
будет отражаться во время игры но пока точно не знаю как и где.

Сейчас код ширмы такой:

; это в программе обработки прерываний
;=================== ширма вверху
call shirm0 ; стираем ширму
lhld ashirm
lda scroll
adi 1
mov l,a
shld ashirm
call shirm1 ; рисуем ширму
call shirmbon ; дополнительно ещё раз рисуем первые семь столбиков чтобы убрать глюки слева вверху
;======================================= ширма снизу
call shirm0wwt ; стираем ширму
lhld ashirm2 ;
lda scroll
adi 9
mov l,a
shld ashirm2 ;
call shirm1wwt ; рисуем ширму
;=======================================

;================ Это подпрограммы

; стираем ширму
shirm0: lxi h,0
shld shirmx+1
jmp shirm
;
shirm1: lxi h,0FFFFh
shld shirmx+1
; jmp shirm
;
shirm: lxi h,0
dad sp ; HL=HL+SP
shld s_sp ; сохраняем значение стека
;
lhld ashirm ; в HL помещаем адрес куда выводить на экран
lxi d,0100h ; 256
shirmx: lxi b,0
mvi a,31
;
shirmc: sphl ; перенос из HL в SP 8
push b ; запись в экран 16
push b
push b
push b
dad d ; HL=HL+DE(256) переход на следующий столбик 12
dcr a ; 8
jnz shirmc ; 12

lhld s_sp ; возвращаем значение стека
sphl
ret

;===================================
shirm0wwt: lxi h,0
shld shirmxwwt+1
jmp shirmwwt
;
shirm1wwt: lxi h,0FFFFh
shld shirmxwwt+1
;jmp shirmwwt
;
shirmwwt: lxi h,0
dad sp
shld s_sp
;
lhld ashirm2
lxi d,0100h
shirmxwwt: lxi b,0
mvi a,31 ;32
;
shirmcwwt: sphl
push b
push b
push b
push b
dad d
dcr a
jnz shirmcwwt
;
lhld s_sp
sphl
;
ret
;================================================= =====
shirmbon:
lxi h,0
dad sp ; HL=HL+SP
shld s_sp ; сохраняем значение стека
;
lhld ashirm ; в HL помещаем адрес куда выводить на экран
lxi d,0100h ; 256
shirmxbon: lxi b,0ffffh
mvi a,7
;
shirmcbon: sphl ; перенос из HL в SP
push b ; запись в экран
push b
push b
push b
dad d ; HL=HL+DE(256) переход на следующий столбик
dcr a
jnz shirmcbon

lhld s_sp ; возвращаем значение стека
sphl
ret


- - - Добавлено - - -


Есть возможность небольшого ускорения за счет перехода к змейке по плоскостям. Условно делим картинку на блоки 8x2 точки
1. Вывод первых 8 точек как сейчас, только добавляем lxi b,8192
2. Вывод вторых 8 точек в обратном направлении по плоскостям, добавляем lxi b,-8192
lda+mov убираем. lxi - 12 тактов и 3 байта; lda+mov - 24 такта и 4 байта, т.е. выигрыш 12 тактов и 1 байт на каждых 8 точках.


ivagor, никак не пойму как реализовать эту "змейку", можно небольшой пример кода....

ivagor
22.07.2020, 15:59
небольшой пример кода
;вывод блока 8x2
;первые 8 точек в блоке 8x2
lxi b,8192
ldax d\ mov m,a\ inx d\ dad b
ldax d\ mov m,a\ inx d\ dad b
ldax d\ mov m,a\ inx d\ dcr l
;вторые 8 точек в блоке 8x2
lxi b,-8192
ldax d\ mov m,a\ inx d\ dad b
ldax d\ mov m,a\ inx d\ dad b
ldax d\ mov m,a\ inx d\ dcr l
При необходимости можно немножко разменивать "одновременность" на скорость за счет (как уже писал) вывода нескольких байт в одной плоскости перед ее сменой. Это очевидно связано с тем, что inr/dcr быстрее dad.

S_V_B
22.07.2020, 18:55
"Ё,,,,,,,,,,"...или мы не про компьютер говорим? Пусть меня все бьют палками....бейте дальше.. я помочь хотел..простите.

metamorpho
22.07.2020, 19:58
Исправил появление главного героя "из стены".
Исправил глюк с палитрой, который был в предыдущей версии.
Переписал рисование ширмы с учётом некоторых предложенных здесь идей.
Ширма рисуется быстрее и вроде без глюков.
Ниже (rom) для тестов :)

- - - Добавлено - - -

Вот новый код рисования ширмы в программе обработки прерываний:


lda kub_napr ; узнаём направление главного героя 3-вверх 4-вниз
;если вертикального движения нет то ширму не рисуем и не стираем

cpi 3 ; движение вверх скрол вниз
jnz ruft12
;=======затриаем_сверху=4 строки + снизу рисуем 8 строк
; стираем ширму сверху
lxi b,0
lxi h,0
dad sp ; HL=HL+SP
shld s_sp ; сохраняем значение стека
lda scroll
sui 7
mov l,a
mvi h,0e0h
mvi a,32
shirmczz: sphl ; перенос из HL в SP 8
push b ; запись в экран 16
push b ; запись в экран 16
inr h
dcr a ; 8
jnz shirmczz ; 12

; рисуем снизу
lxi b,0FFFFh
lda scroll
adi 9
mov l,a
mvi h,0e1h
mvi a,31
shirmc2r: sphl ; перенос из HL в SP 8
push b ; запись в экран 16
push b ; запись в экран 16
push b ; запись в экран 16
push b ; запись в экран 16
inr h
dcr a ; 8
jnz shirmc2r ; 12

lhld s_sp ; возвращаем значение стека
sphl
jmp ruft14


ruft12:
cpi 4 ; движение вниз скрол вверх затриаем снизу строку 08 + сверху рисуем 8 строк
jnz ruft14 ;иначе ничего не делаем
;=======затриаем_сверху=4 строки + снизу рисуем 8 строк
; стираем ширму снизу
lxi b,0
lxi h,0
dad sp ; HL=HL+SP
shld s_sp ; сохраняем значение стека
lda scroll
adi 13
mov l,a
mvi h,0e0h
mvi a,32
shirmc44: sphl ; перенос из HL в SP 8
push b ; запись в экран 16
push b ; запись в экран 16
inr h
dcr a ; 8
jnz shirmc44 ; 12

; рисуем сверху
lxi b,0FFFFh
lda scroll
adi 1
mov l,a
mvi h,0e1h
mvi a,31
shirmc2r44: sphl ; перенос из HL в SP 8
push b ; запись в экран 16
push b ; запись в экран 16
push b ; запись в экран 16
push b ; запись в экран 16
inr h
dcr a ; 8
jnz shirmc2r44 ; 12

lhld s_sp ; возвращаем значение стека
sphl
;===================================

ruft14:

ivagor
22.07.2020, 20:02
Паразитного штриха при скролле теперь нет, морганий не заметно, это все здорово. Только при старте нижняя строка рисуется испорченной (похоже на проблему с инициализацией ширмы, но это я пальцем в небо, внутрь не смотрел). И KTSerg вроде уже упоминал, что рестарт для игрушки является проблемой. Не то чтобы это было критично, но по возможности лучше попробовать обеспечить и нормальную реакцию на ресет.

jerri
22.07.2020, 20:46
metamorpho,почему не используешь модифицирующийся код?



shld s_sp ; сохраняем значение стека

ld sp,$
s_sp equ-2

metamorpho
22.07.2020, 21:10
metamorpho,почему не используешь модифицирующийся код?

jerri, я пока не знаю что это такое и в чём преимущество этого.
Я ведь только пару-тройку недель вникаю в ассемблер.
Насколько я понимаю ld это же команда не из ассемблера для КР580ВМ80А ?


Только при старте нижняя строка рисуется испорченной (похоже на проблему с инициализацией ширмы, но это я пальцем в небо, внутрь не смотрел). И KTSerg вроде уже упоминал, что рестарт для игрушки является проблемой. Не то чтобы это было критично, но по возможности лучше попробовать обеспечить и нормальную реакцию на ресет.

Нижнюю строку исправил. А вот с рестартом пока не пойму где проблема.

jerri
22.07.2020, 21:17
jerri, я пока не знаю что это такое и в чём преимущество этого.
Я ведь только пару-тройку недель вникаю в ассемблер.
Насколько я понимаю ld это же команда не из ассемблера для КР580ВМ80А ?


Да это ассемблер Z80
это команда инициализации стека

для i80

LXI sp,$
и ставишь метку переменный на данные вносимые в SP

грубо говоря

#8003 lxi hl,#0000
#8006 lhld #800a
#8009 lxi sp,#0000

просто я не очень люблю систему команд i80 - она не очень наглядная.

грубо говоря переменная s_sp используется в одном месте и хранит определенное значение - стек при отрисовке ширмы
экономия 5 байтов

metamorpho
22.07.2020, 21:53
Исправил глюк с нижней строкой при старте.
Баг рестарта тоже исправлен.
Ниже свежий (rom) для тестов :)

S_V_B
23.07.2020, 08:52
metamorpho, по человечески.. завидую :) Столько откликов и рац. предложений.... было бы у меня с LastMission на УКНЦ.. такое .. давно бы дописал.., а так... одни снобские ФЕ...

jerri
23.07.2020, 10:27
metamorpho, по человечески.. завидую :) Столько откликов и рац. предложений.... было бы у меня с LastMission на УКНЦ.. такое .. давно бы дописал.., а так... одни снобские ФЕ...

Ты зря так, тебе и Манве подсказывал и еще там ктото
просто основной контингент форума далеко от PDP-11 и ничего машиннозависимого подсказать не сможет.

metamorpho
23.07.2020, 11:43
metamorpho, по человечески.. завидую :) Столько откликов и рац. предложений.... было бы у меня с LastMission на УКНЦ.. такое .. давно бы дописал.., а так... одни снобские ФЕ...

Если что на Вектор-06Ц можно ещё много чего интересного сделать (насколько я понял) используя его разные технические возможности.
Так что Вектор-06Ц "ждёт" новых шедевров :)

KTSerg
23.07.2020, 17:01
metamorpho, дошло до меня наконец, почему при переходе скроллинга через 00, смещается ширма...
Всё просто. Если указатель ширмы например $E100 - это вторая колонка экрана, но самая левая из используемых при формировании лабиринта. То при формировании ширмы происходит уменьшение адреса указателя стека, и получаем адрес $E0FF, $E0FE - а это самая левая колонка экрана, и левее лабиринта.

Если ограничить высоту ширмы 4-мя строками, то можно избавиться от смещения с помощью коррекции указателя ширмы.
Это модифицированная функция формирования ширмы:


lxi h,0 ;\
dad sp ; сохраняем указатель стека
shld w_sp+1 ;/
;
lhld ashirm ; положение ширмы
mov a,l ;\
ora a ;/ проверим на переход ширмы через 00
jnz shirmx ; если не 00 - коррекции положения ширмы не требуется
inr h ; при переходе ширмы через 00 - смещаем ширмц вправо
shirmx: lxi b,0 ; ставим или удаляем ширму
mvi a,30 ; длина ширмы по горизонтали
;
shirmc: sphl ; адрес секции ширмы в стек
push b ;\
push b ;/ удаляем или ставим 4 строки ширмы
inr h ; переходим к лседующей колонке ширмы
dcr a ; сколько колонок осталось
jnz shirmc ; пока не все колонки ширмы
;
w_sp: lxi sp,0 ;/ восстанавливаем указатель стека
;
ret

metamorpho
23.07.2020, 20:37
KTSerg, спасибо за код и за старания выявить проблему. Теперь DCR "глюк" :)

KTSerg
24.07.2020, 06:41
KTSerg, спасибо за код и за старания выявить проблему.
Самому интересно. :)

Теперь DCR "глюк" :)
А вот это я не понял... наверное ещё не проснулся...

- - - Добавлено - - -

Во вложении функции работы с ширмой, по 4 строки, для устранения смещения, при переходе скроллинга через 00.

metamorpho
24.07.2020, 08:05
А вот это я не понял... наверное ещё не проснулся...

DCR "глюк" это "глюк"="глюк"-1 на один "глюк" стало меньше :)

ivagor
24.07.2020, 08:42
по 4 строки
Может я что-то пропустил, но сдвиг ширмы может быть с любым шагом кратным степени двойки - при этом после прохождения 256 строк снова придем к той строке, с которой начали. Ограничивающий фактор - уложиться во временной промежуток от прерывания до активной области отображения, с учетом этого максимальный шаг сдвига - 8 строк при использовании push (8 push, 4 рисуют и 4 стирают).

KTSerg
24.07.2020, 09:01
DCR "глюк" это "глюк"="глюк"-1 на один "глюк" стало меньше
Ясно.


Может я что-то пропустил, но сдвиг ширмы может быть с любым шагом кратным степени двойки - при этом после прохождения 256 строк снова придем к той строке, с которой начали. Ограничивающий фактор - уложиться во временной промежуток от прерывания до активной области отображения, с учетом этого максимальный шаг сдвига - 8 строк при использовании push (8 push, 4 рисуют и 4 стирают).
В данном случае используется сплошная ширма высотой 16 строк, по 8 строк вверху и внизу экрана.
За одно прерывание происходит скроллинг 4 строки.
Соответственно, (с моей точки зрения) не имеет смысла перерисовывать по 8 строк ширмы. Достаточно с одной стороны удалить 4 строки, с другой добавить к ширме 4 строки. В связи с этим и "оптимизация", сокращающая работу с ширмой в 3-4 раза. И это в каждом прерывании при наличии перемещения по вертикали. А при отсутствии перемещения по вертикали, чего вообще тратить ресурсы на перерисовку ширмы...

metamorpho
27.07.2020, 17:31
Написал код для движущихся по уровню объектов (просчитываются все движущиеся по уровню объекты, даже если их нет на экране).
Скорость сразу приуныла. Придётся придумывать более скоростной вариант.


https://youtu.be/YiQsZ4qYmqE

ivagor
27.07.2020, 18:06
Красивая графика, впечатляет.

jerri
27.07.2020, 19:18
Написал код для движущихся по уровню объектов (просчитываются все движущиеся по уровню объекты, даже если их нет на экране).
Скорость сразу приуныла. Придётся придумывать более скоростной вариант.


https://youtu.be/YiQsZ4qYmqE

1. сократи количество обьектов на уровне и сделай их умнее.
2. перепиши процедуру отрисовки. должен был быть резерв по ускорению.
3. привяжи движение обьектов к прерываниям.

KTSerg
28.07.2020, 06:18
Ндас... при отсутствии возможности остановиться, пока не добежишь до стены, количество "помех" может оказаться критичным.

metamorpho
28.07.2020, 16:52
Красивая графика, впечатляет.

Спасибо!! Графику в основном - ищу подходящие готовые образы и - перекрашиваю цвета (под свои 8 цветов), сокращаю цветовую палитру (под 8 цветов), преобразую размер (очень трудно уместить в 24 точки что-либо не потеряв качество), дорисовываю некоторые элементы, делаю дополнительные кадры анимации и др.


1. сократи количество обьектов на уровне и сделай их умнее.
2. перепиши процедуру отрисовки. должен был быть резерв по ускорению.
3. привяжи движение обьектов к прерываниям.

Спасибо за советы !
Привязать движение к прерываниям - это несколько рискованно, т.к. в прерывании уже достаточно много чего, а если добавить ещё немного то начнуться глюки недорисовки. А если потом ещё нужно будет увеличить объём программы в прерываниях то это каждый раз это риск получить глюки, и придётся возвращаться и переписывать всё снова без использования прерываний - вот такие "страхи" есть.


Ндас... при отсутствии возможности остановиться, пока не добежишь до стены, количество "помех" может оказаться критичным.

Это всего лишь тестовый вариант.

----
На данный момент переписал программу обработки всех движущихся объектов.
Скорость вернулась.
Но столкнулся с новой проблемой - выход объектов за границу экрана.
Поскольку на Векторе нельзя рисовать за границей экрана, возникает проблема с тем чтобы сделать так, чтобы уходя с экрана спрайт исчезал плавно, а не резко. Сейчас придумываю как это сделать.

KTSerg
28.07.2020, 18:41
...
Но столкнулся с новой проблемой - выход объектов за границу экрана.
Поскольку на Векторе нельзя рисовать за границей экрана, возникает проблема с тем чтобы сделать так, чтобы уходя с экрана спрайт исчезал плавно, а не резко. Сейчас придумываю как это сделать.
Ширмы в 16 строк уже мало :)
Либо увеличивать ширму, либо для пограничных "строк" лабиринта использовать специализированные (адаптированные) подпрограммы вывода спрайта.

Судя по видео, уходят с экрана они как-раз плавно, а вот появляются рывком - сразу целиком.
А раз уходят плавно, значит и появляться могут так-же. Просто вывод нужно начинать на позицию раньше.

Или я не правильно проблему понял?

jerri
28.07.2020, 19:42
Спасибо за советы !
Привязать движение к прерываниям - это несколько рискованно, т.к. в прерывании уже достаточно много чего, а если добавить ещё немного то начнуться глюки недорисовки. А если потом ещё нужно будет увеличить объём программы в прерываниях то это каждый раз это риск получить глюки, и придётся возвращаться и переписывать всё снова без использования прерываний - вот такие "страхи" есть.


ты не совсем верно понимаешь концепт

на прерываниях у тебя обработка объектов
в процессе обработки создаешь массив выводимых обьектов
в 2 списка

в основном теле только отрисовка
ты берешь по очереди один из списков и рисуешь по нему объекты

пока обьектов мало - скорость отрисовки высокая
когда их много - скорость отрисовки падает, но скорость изменения ситуации остается прежней.

как то так.



Это всего лишь тестовый вариант.

----
На данный момент переписал программу обработки всех движущихся объектов.
Скорость вернулась.
Но столкнулся с новой проблемой - выход объектов за границу экрана.
Поскольку на Векторе нельзя рисовать за границей экрана, возникает проблема с тем чтобы сделать так, чтобы уходя с экрана спрайт исчезал плавно, а не резко. Сейчас придумываю как это сделать.

у тебя размер шторки должен быть равен или больше высоты спрайта.
тогда проверяешь выход спрайта за пределы экрана и рисуешь его только если он уходит совсем за шторку

выложи последний билд

metamorpho
29.07.2020, 14:35
Судя по видео, уходят с экрана они как-раз плавно, а вот появляются рывком - сразу целиком. А раз уходят плавно, значит и появляться могут так-же. Просто вывод нужно начинать на позицию раньше.Или я не правильно проблему понял?

Например вверх плавно уходят они за ширму и в итоге появляются с нижней стороны экрана, т.к. ширма=16 строк а спрайт 24 строки + подпрограмма вывода спрайта не контролирует Y, т.е. если Y=0ffh то inr y будет 00h и т.д. В итоге образуется мусор на экране и при скроллинге это ещё больше ухудшается.


ты не совсем верно понимаешь концепт
на прерываниях у тебя обработка объектов...в процессе обработки создаешь массив выводимых обьектов
в 2 списка....в основном теле только отрисовка....ты берешь по очереди один из списков и рисуешь по нему объекты........у тебя размер шторки должен быть равен или больше высоты спрайта.
.....выложи последний билд


Если программа обработки прерывания слишком длинная, то разве это не повлияет на отрисовку спрайтов в основном цикле программы ? Какой предел общего количества тактов команд, который можно без последствий для основного цикла программы, внедрить в программу обработки прерываний ?

Если делать "ширму" высотой равной высоте спрайта, то это потеря двух строк, т.е. вместо 10 станет 8.
На мой взгляд не очень хороший вариант, т.к. даже сейчас когда 10 строк уровня по горизонтали, всё равно чувствуется некоторая теснота в них. Поэтому увеличить ширму это конечно вариант, но к нему прибегну только если другие варианты не помогут.

Билд выложу позже, как только определюсь каким способом буду достигать решение этой проблемы, а сейчас только эксперименты разные.

ivagor
29.07.2020, 14:48
Если делать "ширму" высотой равной высоте спрайта, то это потеря двух строк, т.е. вместо 10 станет 8.
Ширму надо сделать не менее высоты спрайта, т.е. >=24. При этом ширма получится высотой 40 строк изображения, 216 останется для отображения, а это 9 строк спрайтов/тайлов.

- - - Добавлено - - -

Кстати, эти размышления наводят на мысль, что теоретически можно увеличить высоту спрайта до 25 строк, но это приведет к ряду неудоств.

metamorpho
29.07.2020, 14:50
Ширму надо сделать не менее высоты спрайта, т.е. >=24. При этом ширма получится высотой 40 строк изображения, 216 останется для отображения, а это 9 строк спрайтов/тайлов.

9 это уже лучше :)

Сейчас есть труднореализуемая идея - написать подпрограмму вывода спрайта, которая учитывает смещение спрайта по Y и рисует только то что есть на экране (до ширмы) + нужно отслеживать когда происходит вертикальный скроллинг чтобы контролировать какую часть спрайта снова нужно рисовать.

ivagor
29.07.2020, 15:02
написать подпрограмму вывода спрайта, которая учитывает смещение спрайта по Y и рисует только то что есть на экране (до ширмы)
Самый простой и очевидный вариант - перейти на построчное рисование. Для досрочного прерывания процедуры (когда строк <24) просто ставим команду перехода вместо команд рисования первой "лишней" строки. После перехода сразу восстанавливаем испорченные команды.

KTSerg
29.07.2020, 15:34
И алгоритма вывода спрайта видимо нужно как минимум два: один для вывода спрайта снизу-вверх, второй сверху-вниз.
Т.к. в верхней части экрана может быть видена только нижняя часть спрайта. А в нижней части экрана нужна только верхняя часть спрайта.
Если пользоваться универсальным алгоритмом вывода спрайта, то потребуются дополнительные расчеты для каждого объекта, чтобы вычислить на сколько он "спрятался", и какое смещение (в спрайте) нужно для начала его вывода.
Можно конечно не париться, и придумать какую-то таблицу с координатами, размерами, смещениями. И пересчитывать её при каждом: скроллинге, перемещении.
Тогда для вывода спрайта достаточно будет из таблицы брать кол-во видимых строк в спрайте, смещения, и проч...

Да, и действительно, если выводить только видимую часть спрайта, то алгоритм построчного вывода проще прервать после вывода нужного кол-ва строк спрайта.

jerri
29.07.2020, 19:23
Ширму надо сделать не менее высоты спрайта, т.е. >=24. При этом ширма получится высотой 40 строк изображения, 216 останется для отображения, а это 9 строк спрайтов/тайлов.


почему 40? 24 достаточно - 12 наверху и 12 внизу.

- - - Добавлено - - -


И алгоритма вывода спрайта видимо нужно как минимум два: один для вывода спрайта снизу-вверх, второй сверху-вниз.
Т.к. в верхней части экрана может быть видена только нижняя часть спрайта. А в нижней части экрана нужна только верхняя часть спрайта.
Если пользоваться универсальным алгоритмом вывода спрайта, то потребуются дополнительные расчеты для каждого объекта, чтобы вычислить на сколько он "спрятался", и какое смещение (в спрайте) нужно для начала его вывода.
Можно конечно не париться, и придумать какую-то таблицу с координатами, размерами, смещениями. И пересчитывать её при каждом: скроллинге, перемещении.
Тогда для вывода спрайта достаточно будет из таблицы брать кол-во видимых строк в спрайте, смещения, и проч...

Да, и действительно, если выводить только видимую часть спрайта, то алгоритм построчного вывода проще прервать после вывода нужного кол-ва строк спрайта.

просто скипать лишние строчки.

а в случае рисования за ширмой вообще не обращать внимания на урезание.


- - - Добавлено - - -



Если программа обработки прерывания слишком длинная, то разве это не повлияет на отрисовку спрайтов в основном цикле программы ? Какой предел общего количества тактов команд, который можно без последствий для основного цикла программы, внедрить в программу обработки прерываний ?



https://www.youtube.com/watch?v=F7-XnSAu3Uk&t=44s
вот здесь обработка обьектов отдельно освежение фона отдельно.




Если делать "ширму" высотой равной высоте спрайта, то это потеря двух строк, т.е. вместо 10 станет 8.
На мой взгляд не очень хороший вариант, т.к. даже сейчас когда 10 строк уровня по горизонтали, всё равно чувствуется некоторая теснота в них. Поэтому увеличить ширму это конечно вариант, но к нему прибегну только если другие варианты не помогут..

высота 10 элементов = 240 точек
256-24 = 232 точки - просто сверху и снизу по 4 линии тайла не будут видны.

ivagor
29.07.2020, 19:45
почему 40? 24 достаточно - 12 наверху и 12 внизу.
Чтобы было только 24 придется при сдвиге экрана не только пририсовывать несколько строк к ширме с одной стороны и стирать столько же с другой, но еще и в условном центре ширмы делать эту операцию. Можно сказать, что вместо одной ширмы в 40 строк будет 2 по 12. И целиком объект 24x24 под такой составной ширмой не нарисуешь, смысл ее мне не понятен.

jerri
29.07.2020, 19:58
Чтобы было только 24 придется при сдвиге экрана не только пририсовывать несколько строк к ширме с одной стороны и стирать столько же с другой, но еще и в условном центре ширмы делать эту операцию. Можно сказать, что вместо одной ширмы в 40 строк будет 2 по 12. И целиком объект 24x24 под такой составной ширмой не нарисуешь, смысл ее мне не понятен.

в смысле? ты неправильно смотришь.

у тебя есть ширма высотой 24

у тебя есть столбец экрана высотой 256
просто рисуешь ширму с -12 до +12 от первой строки.

и также спрайты врагов надо рисовать в этом же периоде -12 до 243
тогда ширма будет из скрывать.

ivagor
30.07.2020, 05:50
В итоге вся разница в том, что в моем варианте будут видны только 9 полных строк, а в твоем еще и "частичные" строки.

KTSerg
30.07.2020, 07:42
Или уменьшить размер ячейки лабиринта по вертикали до 22-ух или 20-ти строк.
Даже при высоте 22 строки, это на экране 10 строк лабиринта в высоту, и 36 строк ширмы. Достаточно, чтобы полностью спрятать уходящие за предел экрана элементы, без необходимости резать вывод спрайтов.

- - - Добавлено - - -

А сколько строк спрайта лабиринта прячется под ширмой, при подготовке для скроллинга, 8 строк ?
Получается, 22 строки - уходящий за ширму элемент, плюс 8 строк - с другой стороны для подготовки лабиринта... между ними зазор 6 строк...
Если не будет ситуации, когда два элемента уходят за пределы экрана одновременно в одной колонке лабиринта, то артефактов быть не должно. А с другой стороны, даже если они за ширмой что-то друг с другом сделают... этого-же ни кто не увидит :)

jerri
30.07.2020, 10:59
В итоге вся разница в том, что в моем варианте будут видны только 9 полных строк, а в твоем еще и "частичные" строки.

Ну да. Я о чем и говорю. главное это ширма и возможность скрываться за ней врагов. то что некоторые строки будет видно частично - только плюс
на экране технически может отображаться до 11 разных строк - просто верхняя и нижняя всего по 8 линий.

metamorpho
31.07.2020, 20:41
Обошёлся пока без дополнительного удлинения ширмы.
Написал две специальные дополнительные подпрограммы вывода спрайта (построчно) при его достижении верхней и нижней границы экрана.
Иногда бывает появляется артефакт, пока не понял почему.
В тестовом уровне обрабатывается 4-е летающих объекта (не считая главного героя, огонька и монет).
При этом скорость снизилась, но не критично (на мой взгляд).
Возможно можно будет что-то ускорить засчёт оптимизации.
Ниже (rom) для тестов :)

jerri
31.07.2020, 21:44
Обошёлся пока без дополнительного удлинения ширмы.
Написал две специальные дополнительные подпрограммы вывода спрайта (построчно) при его достижении верхней и нижней границы экрана.
Иногда бывает появляется артефакт, пока не понял почему.
В тестовом уровне обрабатывается 4-е летающих объекта (не считая главного героя, огонька и монет).
При этом скорость снизилась, но не критично (на мой взгляд).
Возможно можно будет что-то ускорить засчёт оптимизации.
Ниже (rom) для тестов :)


ага красиво

рисовать шторку через стек - дорого по тактам
надо по другому

у тебя спрайты какого размера?

переход от битплана к битплану очень дорого

надо змейкой - слева направо битплан 1, справа налево битплан 2, слева направо битплан 3, потом вниз
потом наоборот

- - - Добавлено - - -

почему враги визуально подвисают при движении героя?

- - - Добавлено - - -

ivagor, можешь вот это на векторский перевести?
73194

и например обьяснить как этим правильно пользоваться

ivagor
01.08.2020, 06:07
ivagor, можешь вот это на векторский перевести?
Как понимаю, речь опять про способ/метод Медноногова. PPC уже переводил на векторовский, надо вспомнить выкладывал ли он исходник, но обсуждение точно можно найти в ветке Robotz (https://zx-pk.ru/threads/19922-robotz!-releases.html), она не такая уж большая.

KTSerg
01.08.2020, 07:39
ivagor, можешь вот это на векторский перевести?
73194
и например обьяснить как этим правильно пользоваться
Сколько смотрю на этот алгоритм, не могу понять, как можно восстановить испорченные стеком данные.
С моей точки зрения, сделать это на 100% - это не возможно.

Пример.
Есть на экране картинка. Я с помощью стека вношу в неё изменения.
Только-что полностью закончил вывод спрайта, и собираюсь восстановить указатель стека, который в данный момент указывает на фоновую картинку под выведенным спрайтом... И тут пришло оно... прерывание... Адрес возврата из прерывания пишется в стек, т.е. прямо на мою фоновую картинку, о содержимом затёртого стеком ни кто, ни как знать вообще не может...
Подпрограмма "восстановления" в прерывании загоняет за место двух затёртых байт фоновой картинки содержимое пары ВС (если я правильно понял), и вот на фоновой картинке под спрайтом появляется артефакт...
А если я только занёс в ВС данные для спрайта, но не выполнил PUSH BC... и произошло прерывание, то оно сделает это за меня, испортив два предыдущих байта в спрайте?
Выход только один, в своих подпрограммах вывода спрайта, постоянно запрещать и разрешать прерывания... а будет ли при этом выигрыш от использования стека, вот в чём вопрос ?

jerri
01.08.2020, 07:47
Сколько смотрю на этот алгоритм, не могу понять, как можно восстановить испорченные стеком данные.
С моей точки зрения, сделать это на 100% - это не возможно.

Пример.
Есть на экране картинка. Я с помощью стека вношу в неё изменения.
Только-что полностью закончил вывод спрайта, и собираюсь восстановить указатель стека, который в данный момент указывает на фоновую картинку под выведенным спрайтом... И тут пришло оно... прерывание... Адрес возврата из прерывания пишется в стек, т.е. прямо на мою фоновую картинку, о содержимом затёртого стеком ни кто, ни как знать вообще не может...
Подпрограмма "восстановления" в прерывании загоняет за место двух затёртых байт фоновой картинки содержимое пары ВС (если я правильно понял), и вот на фоновой картинке под спрайтом появляется артефакт...
А если я только занёс в ВС данные для спрайта, но не выполнил PUSH BC... и произошло прерывание, то оно сделает это за меня, испортив два предыдущих байта в спрайте?
Выход только в своих программах постоянно запрещать и разрешать прерывания... а вудет ли при этом выигрыш от использования стека, вот в чём вопрос ?Ну над этим алгоритмом работал один из гениев программирования спектрума.

Задача этого набора процедур не дать сдохнуть данным спрайтов выводимых через стек при включенных прерывания.

Для этого нужна другая процедура рисования спрайтов. Более быстрая. С прокачкой данных через стек.

Стек не на экране. Стек на спрайтах.

KTSerg
01.08.2020, 07:54
...
Для этого нужна другая процедура рисования спрайтов. Более быстрая. С прокачкой данных через стек.

Стек не на экране. Стек на спрайтах.
Вот с этим согласен.
Если стек на спрайте, а не на экране. Есть вероятность корректной работы алгоритма.
Для этого как минимум нужно разрешить прерывание только после установки стека на спрайт и чтения первых байт спрайта. А перед переходом на другой спрайт запрещать.
Иначе спрайтам - кирдык.
Можно конечно выкрутиться, и подогнать, что-бы все спрайты начинались и заканчивались одинаково... тады...

jerri
01.08.2020, 07:56
Вот с этим согласен.
Если стек на спрайте, а не на экране. Есть вероятность корректной работы алгоритма.
Для этого как минимум нужно разрешить прерывание только после установки стека на спрайт и чтения первых байт спрайта.Прерывания разрешены всегда.
Просто сначала заряжаешь основной регистр под графику, потом уже стек.

KTSerg
01.08.2020, 08:10
...
и например обьяснить как этим правильно пользоваться.
Ну вот похоже и сформировались рекомендации:
1. Пара ВС ни где в программе больше не используется, кроме подпрограммы вывода спрайта.
2. Стек при выводе спрайта используется на чтение данных из спрайта.
3. Все спрайты должны иметь два первых и два последних байта одинаковыми. Например подпрограмма вывода спрайта может первую пару байт читать в холостую, без вывода на экран, и так-же по завершении вывода спрайта, считать из спрайта ещё пару байт (для очистки ВС).

Дополняйте, что ещё ?

ivagor
01.08.2020, 08:39
1. Пара ВС ни где в программе больше не используется, кроме подпрограммы вывода спрайта.
Пара BC в подпрограмме вывода спрайта используется только для чтения графики спрайта. Остальная программа может быть какой угодно.

3. Все спрайты должны иметь два первых и два последних байта одинаковыми.
Это не нужно. Решение классика - первые два байта читаем обычно, без стека. Для вектора, если графики много и она в квазе, придется читать все стеком и на этот случай (в ветке robotz) jerri предложил делать промежуток в 2 байта между спрайтами.

KTSerg
01.08.2020, 08:54
Пара BC в подпрограмме вывода спрайта используется только для чтения графики спрайта. Остальная программа может быть какой угодно.
Просто если ВС будет использоваться помимо подпрограммы вывода спрайта, то неизбежно, "буферные" байты между спрайтами будут менять значение. Это конечно не критично, для того они и предусмотрены.


Это не нужно. Решение классика - первые два байта читаем обычно, без стека. Для вектора, если графики много и она в квазе, придется читать все стеком и на этот случай (в ветке robotz) jerri предложил делать промежуток в 2 байта между спрайтами.
Ну "промежуток в 2 байта между спрайтами" и то, что я написал "первые2 и последние 2 одинаковые во всех спрайтах", в принципе одно и то-же.

ivagor
01.08.2020, 09:05
Просто если ВС будет использоваться помимо подпрограммы вывода спрайта, то неизбежно, "буферные" байты между спрайтами будут менять значение. Это конечно не критично, для того они и предусмотрены.
На время работы процедуры вывода спрайтов активен специальный(отдельный) обработчик прерываний.

jerri
01.08.2020, 10:27
На время работы процедуры вывода спрайтов активен специальный(отдельный) обработчик прерываний.Это лишнее
Все манипуляции происходят в стеке
Заменяя адрес возврата из прерывания содержимым bc

ivagor
01.08.2020, 10:59
Заменяя адрес возврата из прерывания содержимым bc
Да, критичного ничего не произойдет, но в принципе можно придумать что-нибудь очень вычурное и специфическое, где это не подойдет.

metamorpho
01.08.2020, 15:07
рисовать шторку через стек - дорого по тактам надо по другому

например ?


у тебя спрайты какого размера?

24х24 точки


переход от битплана к битплану очень дорого
надо змейкой - слева направо битплан 1, справа налево битплан 2, слева направо битплан 3, потом вниз
потом наоборот

что такое битплан ?
я не смог написать вариант змейкой чтобы он был быстрее моего.
Можно полный пример вывода спрайта по этому варианту ?


почему враги визуально подвисают при движении героя?

Так написан алгоритм взаимодействия вертикального скроллинга и отображения уровня (при вертикальном сдвиге на 24 точки - уровень (10х10 элементов экрана - обновляется лишь 1 раз),
чтобы переделывать это нужно придумавать новое взаимодействие и писать всё заново, но в этот проект это не входит. Цель этого проекта сделать игру на более-менее хорошем уровне - и получить опыт, узнав разные подводные камни при создании игры на Вектор. Если же всё доводить до идеала, то можно надолго зависнуть на одном проекте и никогда его не сделать. А у меня цель выпустить игру уже осенью этого года :)
К тому же можно объяснить это супер-способностью главного героя. Когда он делает супер-рывок по вертикали, то остальное как бы замедляет своё движение :)


ivagor, можешь вот это на векторский перевести?
73194
и например обьяснить как этим правильно пользоваться

Я многие моменты не полностью понимаю, так что чтобы понять это нужем конкретный алгоритм с коментариями :)

jerri
01.08.2020, 15:26
Я многие моменты не полностью понимаю, так что чтобы понять это нужем конкретный алгоритм с коментариями :)

Ну оно должно идти в комплекте с процедурой рисования спрайта.
У тебя же спрайты просто рисуются? Так?
А удаляешь лишнее как?

metamorpho
01.08.2020, 15:36
А удаляешь лишнее как?

Удаляю лишнее в чём ?

jerri
01.08.2020, 15:38
Удаляю лишнее в чём ?Ну вот у тебя нарисован спрайт героя.
И ты героя двигаешь. Как ты стираешь след от героя?
Мне прост влом разбирать программу

metamorpho
01.08.2020, 15:42
Ну вот у тебя нарисован спрайт героя.
И ты героя двигаешь. Как ты стираешь след от героя?
Мне прост влом разбирать программу

Поверх старого спрайта печатаю новый со сдвигом - получается одновременно и движение и затирание следа.

jerri
01.08.2020, 15:55
Поверх старого спрайта печатаю новый со сдвигом - получается одновременно и движение и затирание следа.То есть герой меньше чем 24х24

metamorpho
01.08.2020, 16:00
То есть герой меньше чем 24х24

Нет, герой 24х24. Когда например идёт сдвиг влево то у меня есть готовые спрайты 32х24 в котором идёт сдвиг влево и анимация заодно.
А когда герой стоит на месте то печатается спрайт 24х24. При сдвиге вверх тоже печатается 24х24 т.к. в спрайте снизу и сверху есть запас чёрных-нулевых линий.

jerri
01.08.2020, 16:07
Нет, герой 24х24. Когда например идёт сдвиг влево то у меня есть готовые спрайты 32х24 в котором идёт сдвиг влево и анимация заодно.
А когда герой стоит на месте то печатается спрайт 24х24. При сдвиге вверх тоже печатается 24х24 т.к. в спрайте снизу и сверху есть запас чёрных-нулевых линий.Ага у тебя есть спрайты 32*24 и спрайты 24*24

jerri
01.08.2020, 21:15
metamorpho, забавный глюк
если уперется в стену вверх или вниз и зачать соостветсвенно вверх или вниз то враги дрожат на месте

- - - Добавлено - - -

вот тебе архив с комментариями
3 файла

interrupt.a80 правильные прерывания для работы с программой отрисовки спрайтов


;процедура обработки прерывания с восстановлением поврежденных данных
;при доступе к стеку
;регистровая пара для доступа к стеку BC
im_routine
di
;сохраняем HL и забираем адрес возврата из прерывания
ex (sp),hl
;сохраняем его
ld (im_ret),hl
;забираем HL
pop hl
;сохраняем его чтобы не потерять при манипуляциях с SP
ld (im_hl),hl
;сохраняем флаги
push af
;вычисляем корректный адрес стека программы
ld hl,2
add hl,sp
;сохраняем стек программы
ld (im_sp),hl
pop af
;восстановлением поврежденые данные регистром BC
push bc

;задаем стек прерывания
ld sp,im_stek
;сохраняем все регистры кроме HL
push af,bc,de
;-----------------------------
;ISR
;здесь прерывание
;-----------------------------
;восстанавливаем регистры
pop de,bc,af
;восстанавливаем HL
ld hl,#2121
im_hl equ $-2
;восстанавливаем стек
ld sp,#3131
im_sp equ $-2
ei
;возвращаемся из обработки прерывания
jp #c3c3
im_ret equ $-2

sprite.a80 две подпрограммы быстрого вывода через стек
но тебе надо будет поменять формат спрайтов
сначала вся линия для одного плана, потом для другого, потом для третьего.
это значительно ускорит вывод.

вектор использует систему битпланов при формировании цвета точки
вот здесь на примере идентичной системы Commodore Amiga (http://sblive.narod.ru/ZX-Spectrum/AMIGAHardware/CHAPTER3.htm) более менее рассказано




;вывод спрайта в системе битпланов Вектор 06
;ширина спрайта -24
;на входе
;bc адрес спрайта
;de aдрес на экране
;E-Y D-X
;A высота спрайта/2

drop24
ld hl,0
add hl,sp
ld (sprite_sp0),hl
ld h,b
ld l,c
ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld sp,hl
;задаем Y в L
ld l,e
;задаем высоту спрайта в E
ld e,a
;задаем X в A
ld a,d
;переход между битпланами
ld d,#20
drop240
ld h,a
;рисуем на первом плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
;переход на второй битплан
add a,d

ld h,a
;рисуем на втором плане
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на третий битплан
add a,d

ld h,a
;рисуем на третьем плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
;возвращаемся на первый план
sub #40
;переходим на следующую строку
inc l

;повторяем цикл рисования
;
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на второй битплан
add a,d

ld h,a
;рисуем на втором плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
;переход на третий битплан
add a,d

ld h,a
;рисуем на третьем плане
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
;выбираем следующую пару байтов для цикла рисования
pop bc

;возвращаемся на первый план
sub #40
;переходим на следующую строку
inc l
;проверяем на завершение цикла
dec e
jp nz,drop240
sprite_sp
ld sp,#3131
sprite_sp0 equ $-2
ret

;ширина спрайта -32
;на входе
;bc адрес спрайта
;de aдрес на экране
;E-Y D-X
;A высота спрайта/2

drop32
ld hl,0
add hl,sp
ld (sprite_sp0),hl
ld h,b
ld l,c
ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld sp,hl
;задаем Y в L
ld l,e
;задаем высоту спрайта в E
ld e,a
;задаем X в A
ld a,d
;переход между битпланами
ld d,#20
drop320
ld h,a
;рисуем на первом плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на второй битплан
add a,d

ld h,a
;рисуем на втором плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на третий битплан
add a,d

ld h,a
;рисуем на третьем плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;возвращаемся на первый план
sub #40
;переходим на следующую строку
inc l

;повторяем цикл рисования
;
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на второй битплан
add a,d

ld h,a
;рисуем на втором плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на третий битплан
add a,d

ld h,a
;рисуем на третьем плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
;выбираем следующую пару байтов для цикла рисования
pop bc

;возвращаемся на первый план
sub #40
;переходим на следующую строку
inc l
;проверяем на завершение цикла
dec e
jp nz,drop320
jp sprite_sp

И небольшая таблица в EXCEL
с памяткой по переводу команд из z80 в i8080 и назад.
чтобы понять как это работает

73199

KTSerg
01.08.2020, 22:40
Я тут собрал "болванку" по образцу этой программы.
Спрайты 24х24 на 3 плоскости, на экране 10х10 ячеек игрового поля, ширма 16 строк.
Вывод спрайтов с использованием стека на чтение.
Прерывания, те, которые тут обсуждаются, для данного метода вывода спрайтов.

В итоге получается, что при перемещениях персонажа по горизонтали, и отрисовка ещё 5-ти подвижных объектов спокойно укладывается между прерываниями, т.е. требуется менее 20мс.
А вот при перемещении по вертикали, из-за подготовки поля под ширмой, до прерывания можно обработать только 4-е подвижных объекта, и совсем без запаса.

jerri
01.08.2020, 23:09
KTSerg, ты как поле готовишь?
Мой метод спрайтов посмотрел?

KTSerg
02.08.2020, 05:18
KTSerg, ты как поле готовишь?
Мой метод спрайтов посмотрел?
Это то, что под спойлером, начинается с ";вывод спрайта в системе битпланов Вектор 06" ?
Нет пока не смотрел. Сейчас гляну.
Мнемоника там не привычная, на первый взгляд от Z80.

jerri
02.08.2020, 05:28
Это то, что под спойлером, начинается с ";вывод спрайта в системе битпланов Вектор 06" ?
Нет пока не смотрел. Сейчас гляну.
Мнемоника там не привычная, на первый взгляд от Z80.Ну да. От z80

KTSerg
02.08.2020, 06:33
KTSerg, ты как поле готовишь?
Мой метод спрайтов посмотрел?
jerri, примерно да. Только у меня алгоритм значительно длиннее, и не построчно, а по две строки.
Т.е. две строки в одной колонке, потом две во второй, в третьей. Потом переход на след. план. По две строки справа налево. Переход на след. план. Снова по две строки в право. И так дважды.
За счет более длинного и развёрнутого алгоритма, по тактам, мой не значительно быстрее. Видимо за счет меньшего количества проверок на конц цикла. Т.к. у тебя на 4 строки дважды проверка на повтор, а у меня один раз.
Поскольку у тебя, переход между планами и проверка циклов компактнее, чем у меня.
Спасибо за идею.
И подозреваю, что у моего метода "по две строки" выше вероятность появлению мельтешения (мерцания).

- - - Добавлено - - -

jerri, в алгоритме рисования спрайта, есть для меня один не понятный момент.
При переходе на след строку (в средине алгоритма):


ld (hl),c
;возвращаемся на первый план
sub #40
;переходим на следующую строку
inc l
;повторяем цикл рисования
ld (hl),b

Уменьшение аккумулятора на 40 - это я понимаю, переход не след строку "inc l" - тоже.
А как происходит перевод регистра H - на начало?
Не пропущено "mov h,a" ?

ivagor
02.08.2020, 06:48
Не пропущено "mov h,a" ?
Да, команда пропущена.
Можно ускорить переход между плоскостями, если перейти на змейки по плоскостям и в пространстве. В варианте jerri переходы между плоскостями (при добавлении mov h,a) займут 80 тактов на две строки. Если первую строку выводить слева-направо и в одну сторону по плоскостям, а вторую справа-налево и в другую сторону по плоскостям, то переходы можно ужать до 56 тактов на две строки.

jerri
02.08.2020, 06:55
jerri, примерно да. Только у меня алгоритм значительно длиннее, и не построчно, а по две строки.
Т.е. две строки в одной колонке, потом две во второй, в третьей. Потом переход на след. план. По две строки справа налево. Переход на след. план. Снова по две строки в право. И так дважды.
За счет более длинного и развёрнутого алгоритма, по тактам, мой не значительно быстрее. Видимо за счет меньшего количества проверок на конц цикла. Т.к. у тебя на 4 строки дважды проверка на повтор, а у меня один раз.
Поскольку у тебя, переход между планами и проверка циклов компактнее, чем у меня.
Спасибо за идею.
И подозреваю, что у моего метода "по две строки" выше вероятность появлению мельтешения (мерцания).

- - - Добавлено - - -

jerri, в алгоритме рисования спрайта, есть для меня один не понятный момент.
При переходе на след строку (в средине алгоритма):


ld (hl),c
;возвращаемся на первый план
sub #40
;переходим на следующую строку
inc l
;повторяем цикл рисования
ld (hl),b

Уменьшение аккумулятора на 40 - это я понимаю, переход не след строку "inc l" - тоже.
А как происходит перевод регистра H - на начало?
Не пропущено "mov h,a" ?

Ага пропущено.

Как вариант конечно можно и по 2 строки по высоте выводить, это ещё ускорит алгоритм, но увеличит вероятность мерцания цвета.

Насколько головоломным станет формат спрайта?

Сейчас спрайт выводится построчно.

С другой стороны если снизить минимальную частоту до 25 фпс это будет не важно.

KTSerg
02.08.2020, 06:57
jerri, переделал переход между планами по твоему, спрайт выводится ещё быстрее.
Судя по таймингу, стало с запасом хватать на вывод 4-ёх подвижных объектов при перемещении во вертикали, хотя раньше запаса совсем не было.

ivagor
02.08.2020, 07:12
стало с запасом хватать на вывод 4-ёх подвижных объектов при перемещении во вертикали
Даже если учесть шторку на мой взгляд слишком осторожная оценка. По моей прикидке в кадр укладываются 7 объектов 32*24 (это движение по горизонтали, без шторки, зато спрайты крупнее). Ну и я учитываю только рисование, без обработки управляющих воздействий и взаимодействия объектов.

jerri
02.08.2020, 07:31
Даже если учесть шторку на мой взгляд слишком осторожная оценка. По моей прикидке в кадр укладываются 7 объектов 32*24 (это движение по горизонтали, без шторки, зато спрайты крупнее). Ну и я учитываю только рисование, без обработки управляющих воздействий и взаимодействия объектов.На шторке в текущем виде слишком много пересчетов на позицию.
Можно раскатать подобным образом и получить что то вроде 400 тактов на линию

KTSerg
02.08.2020, 07:53
Даже если учесть шторку на мой взгляд слишком осторожная оценка. По моей прикидке в кадр укладываются 7 объектов 32*24 (это движение по горизонтали, без шторки, зато спрайты крупнее). Ну и я учитываю только рисование, без обработки управляющих воздействий и взаимодействия объектов.
Я понимаю, что у меня не всё круто оптимизировано... но у меня, при движении по горизонтали, 6 объектов (плюс персонаж) не входит между прерываниями. И это, как упомянуто, ещё без обработки взаимодействия.

Вот выложу тестилку быстродействия вывода спрайтов. Зелёные полосы на бордюре, это время отрисовки спрайта. 10 узких полос, это вывод заполнения под ширмой.
Поскольку за одно прерывание скроллинг 4 строки, то и вывод спрайтов оптимизирован под вывод 4-ёх строк за цикл. Заполнение под ширмой тоже 4 строки за раз.

ivagor
02.08.2020, 07:57
Не смотрел шторку/ширму у metamorpho, но ничего быстрее push+...+push+inr h+sphl представить не могу. Для 4 строк будет по 1536 тактов на рисование и столько же на стирание. Это для 32 колонок, для 30 понятно меньше.

- - - Добавлено - - -


Заполнение под ширмой тоже 4 строки за раз.
Рисование под ширмой я не считал. Я бы рисовал под "высокой" ширмой сразу всю строку, а потом сдвигал уже без рисования.

KTSerg
02.08.2020, 08:43
Не смотрел шторку/ширму у metamorpho, но ничего быстрее push+...+push+inr h+sphl представить не могу. ...
Поскольку перенос ширмы всегда в прерываниях, при изменении значения скроллинга, то ширма формируется стековыми операциями записи. На моём примере, это синий цвет бордюра.


Рисование под ширмой я не считал. Я бы рисовал под "высокой" ширмой сразу всю строку, а потом сдвигал уже без рисования.
Формирование поля в 4 строки под ширмой, для равномерности использования ресурсов. Если выводить под ширмой полностью весь спрайт, да ещё на всю ширину экрана, то как минимум одно из 6 прерываний, будет занято, и перемещение подвижных объектов будет с характерным дёрганием - не будет плавным.
Мне кажется. Я не пробовал.

ivagor
02.08.2020, 08:57
Я надеюсь, что торможение из за вывода строки объектов будет не особо заметно на фоне сдвига при движении по вертикали.

jerri
02.08.2020, 09:08
Я надеюсь, что торможение из за вывода строки объектов будет не особо заметно на фоне сдвига при движении по вертикали.Значит надо выводить постепенно.
4 линии очистил - 4 линии вывел

ivagor
02.08.2020, 09:16
Если с учетом "постоянной составляющей" на вывод 10 частичных объектов высотой по 4 строки, то в кадре остается время на 5 "полных" объектов.

jerri
02.08.2020, 09:25
Не смотрел шторку/ширму у metamorpho, но ничего быстрее push+...+push+inr h+sphl представить не могу. Для 4 строк будет по 1536 тактов на рисование и столько же на стирание. Это для 32 колонок, для 30 понятно меньше.


Что-то много. Обычное раскатанное
Mov m,a
Inr h
Даст 1440 тактов без проблемы с выходом из страницы.

ivagor
02.08.2020, 09:32
Mov m,a
Inr h
Даст 1440 тактов
На векторе mov m,a - 8 тактов, inr h - 8 тактов, поэтому быстрее push для вектора ничего нет.

jerri
02.08.2020, 09:59
На векторе mov m,a - 8 тактов, inr h - 8 тактов, поэтому быстрее push для вектора ничего нет.В мануале 5 и 7 тактов.
А где растактовка под вектор?

ivagor
02.08.2020, 10:18
Векторовские растактовки например здесь (http://www.sensi.org/scalar/ware/572/), 15й номер, страница 63 файла. Там есть опечатки (CALL, может еще что). svofski делал исправленную версию, но я не помню, где она.

- - - Добавлено - - -

Прикинул push+push+inr+sphl против mov m,a+inr при прозрачном доступе проца к озу - все равно c push быстрее, 960 тактов против 1440.

jerri
02.08.2020, 10:47
Векторовские растактовки например здесь (http://www.sensi.org/scalar/ware/572/), 15й номер, страница 63 файла. Там есть опечатки (CALL, может еще что). svofski делал исправленную версию, но я не помню, где она.

- - - Добавлено - - -

Прикинул push+push+inr+sphl против mov m,a+inr при прозрачном доступе проца к озу - все равно c push быстрее, 960 тактов против 1440.Кстати почему такое торможение для регистра?
Я понимаю для памяти.

ivagor
02.08.2020, 10:54
Доступ проца к памяти один раз в 4 такта. Циклы соответсвенно округляются вверх (3->4; 4->4; 5->8)

svofski
02.08.2020, 12:17
Векторовские растактовки например здесь, 15й номер, страница 63 файла. Там есть опечатки (CALL, может еще что). svofski делал исправленную версию, но я не помню, где она.
Наверное ты про эти.
https://github.com/svofski/vector06cc/wiki/Instruction_Timings
Я не помню про исправления, но это все давно было. В любом случае тут на них смотреть проще, чем в 15-м номере на 63-й странице файла.

- - - Добавлено - - -


Кстати почему такое торможение для регистра?
Это у z80 регистр-регистр работает за 4 попсовых такта, а у 8080 там все брутальные 5.

KTSerg
02.08.2020, 16:41
Наверное ты про эти.
https://github.com/svofski/vector06cc/wiki/Instruction_Timings
...
Довольно странно, что у CALL и вокруг него, округление не до ближайшего кратного 4-ём, а значительно больше.
Но это так, если вдруг потребуется такты экономить, сразу будет видно, что там на самом деле.

ivagor
02.08.2020, 16:54
CALL без тормозов по циклам:5+3+3+3+3=17. С векторовскими тормозами:8+4+4+4+4=24. Никаких неожиданностей. Векторовским программистам повезло, что у 06Ц такие простые и понятные тормоза. Лучше бы без них, но уж если тормоза есть, то пусть хотя бы простые и понятные.

metamorpho
02.08.2020, 19:52
Написал код для объектов движущихся по горизонтали.
Вот (rom) для тестов :)
На уровне сейчас 4 движущихся объекта (не считая монет, огня и героя).
Столкновение объектов ещё не настроено - поэтому есть некоторые глюки.

jerri
02.08.2020, 19:52
CALL без тормозов по циклам:5+3+3+3+3=17. С векторовскими тормозами:8+4+4+4+4=24. Никаких неожиданностей. Векторовским программистам повезло, что у 06Ц такие простые и понятные тормоза. Лучше бы без них, но уж если тормоза есть, то пусть хотя бы простые и понятные.

На z80 call 10 тактов.

KTSerg
02.08.2020, 19:54
CALL без тормозов по циклам:5+3+3+3+3=17. С векторовскими тормозами:8+4+4+4+4=24. Никаких неожиданностей. Векторовским программистам повезло, что у 06Ц такие простые и понятные тормоза. Лучше бы без них, но уж если тормоза есть, то пусть хотя бы простые и понятные.
Нашел у себя старые таблицы, которые переписывал из умных книжек ещё в 90-ых.
Возможно ошибся, но там было написано, что CALL выполняется за 3 машинных цикла, а не за 5.
А вот вызов подпрограммы по условию C<cond>, при его соблюдении, действительно за 5 машинных циклов, как и условный переход J<cond>.

Ну и нафлудили... :v2_down:

jerri
02.08.2020, 20:01
Написал код для объектов движущихся по горизонтали.
Вот (rom) для тестов :)
На уровне сейчас 4 движущихся объекта (не считая монет, огня и героя).
Столкновение объектов ещё не настроено - поэтому есть некоторые глюки.

если упираешься в стену вверх вниз и нажимаешь в направлении стены все зависает.

чего не сменишь формат спрайтов и процедуру рисования?
будет значительно быстрее.

- - - Добавлено - - -


Векторовские растактовки например здесь (http://www.sensi.org/scalar/ware/572/), 15й номер, страница 63 файла. Там есть опечатки (CALL, может еще что). svofski делал исправленную версию, но я не помню, где она.

- - - Добавлено - - -

Прикинул push+push+inr+sphl против mov m,a+inr при прозрачном доступе проца к озу - все равно c push быстрее, 960 тактов против 1440.

а ты dec+jp учитываешь?

SegaBoy
02.08.2020, 20:05
На z80 call 10 тактов.
10 это если условие перехода не выполняется, а если выполняется или вызов безусловный, то те же 17 тактов как и у 8080

jerri
02.08.2020, 20:14
10 это если условие перехода не выполняется, а если выполняется или вызов безусловный, то те же 17 тактов как и у 8080

Это да, но таких суровых тормозов все равно нет.

ivagor
02.08.2020, 20:18
там было написано, что CALL выполняется за 3 машинных цикла, а не за 5.
3 цикла - чтение трех байт команды; потом 2 цикла - заталкивание адреса возврата в стек, итого 5 циклов.


а ты dec+jp учитываешь?
Если речь про организацию цикла, то нет, т.к. я рассматривал полностью развернутый вариант.

KTSerg
02.08.2020, 20:29
если упираешься в стену вверх вниз и нажимаешь в направлении стены все зависает.
...
jerri, я чёт не смог такое повторить. Зависает если с объектом помехой столкнулся, но об этом предупредили, что событие не обрабатывается.

metamorpho, а сколько спрайтов с фазами движения для каждого объекта?
Я насчитал по 7 вариантов?

- - - Добавлено - - -


3 цикла - чтение трех байт команды; потом 2 цикла - заталкивание адреса возврата в стек, итого 5 циклов.
...
Ясно, значит 3 цикла, это как раз для C<cond>, при не соблюдении условия, когда подпрограмма не вызывается.

metamorpho
02.08.2020, 20:41
если упираешься в стену вверх вниз и нажимаешь в направлении стены все зависает.

Спасибо за отлов бага!! Буду исправлять.


чего не сменишь формат спрайтов и процедуру рисования?
будет значительно быстрее.

Нужно попробовать. Если действительно намного быстрее моего варианта, то попробую изменить формат спрайта и код своих подпрограмм.
KTSerg, а ты можешь выложить код вывода спрайта, который ты написал по методу jerri.
Я сравню его с моим по тактам.


metamorpho, а сколько спрайтов с фазами движения для каждого объекта? Я насчитал по 7 вариантов?

Например медуза имеет направление вправо и влево. Смещение идёт на 2 пикселя.
4 кадра 32х24 вправо и 4 кадра 32х2 4 влево.
Для плавности нужно будет 8 кадров, но пока и на 4-х кадрах неплохая плавность.

jerri
02.08.2020, 21:02
jerri, я чёт не смог такое повторить. Зависает если с объектом помехой столкнулся, но об этом предупредили, что событие не обрабатывается.

я смотрел в EMU
запускаешь Binorum_13
нажимаешь ВЛЕВО
нажимаешь и держишь ВНИЗ
наслаждаешься

KTSerg
02.08.2020, 22:12
я смотрел в EMU
запускаешь Binorum_13
нажимаешь ВЛЕВО
нажимаешь и держишь ВНИЗ
наслаждаешься
Ах это. Это не зависание, это замирание - суперспособность ;) при движении героя по вертикали :)

- - - Добавлено - - -


...
Например медуза имеет направление вправо и влево. Смещение идёт на 2 пикселя.
4 кадра 32х24 вправо и 4 кадра 32х2 4 влево.
Для плавности нужно будет 8 кадров, но пока и на 4-х кадрах неплохая плавность.
я уже сообразил, что 4, а не 7.

- - - Добавлено - - -


... KTSerg, а ты можешь выложить код вывода спрайта, который ты написал по методу jerri.
Я сравню его с моим по тактам. ...
Там у меня жуткий формат спрайта, и склонность к мерцанию. А скорость из-за развёрнутости алгоритма, практически 4 строки один цикл. И плюс экономия на переходах между планами, т.к. за один заход заполняется две строки, только потом переход на следующий план. Из-за этого мерцание, т.к. изменению подвергается слишком большая площадь спрайта.
Так-что, можно сказать не юзабельный вариант вывода спрайта.

- - - Добавлено - - -

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

А - для первого плана, D - для второго, E - для третьего.
Тогда заполнение спрайта:
mov h,a ; первый план
pop b
mov m,c
mov h,d ; второй план
mov m,b
pop b
mov h,e ; третий план
mov m,c
inr l ; след. строка
mov m,b
pop b
mov h,d ; второй план
mov m,c
mov h,a ; первый план
mov m,b
inr l ; след. строка
pop b
mov m,c
...
и т.д.
если развернуть, чтобы циклы не проверять, т.к. свободных переменных нет, то ... надо проверить...

jerri
02.08.2020, 22:19
Там у меня жуткий формат спрайта, и склонность к мерцанию. А скорость из-за развёрнутости алгоритма, практически 4 строки один цикл. И плюс экономия на переходах между планами, т.к. за один заход заполняется две строки, только потом переход на следующий план. Из-за этого мерцание, т.к. изменению подвергается слишком большая площадь спрайта.
Так-что, можно сказать не юзабельный вариант вывода спрайта.


зато быстрый и эффективный

рисовать спрайты надо также как идет луч
горизонтально
вертикально - всегда будет теаринг.

кстати если сделать асинхронное освежение, то мерцания может и не быть.



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

А - для первого плана, D - для второго, E - для третьего.
Тогда заполнение спрайта:
mov h,a ; первый план
pop b
mov m,c
mov h,d ; второй план
mov m,b
pop b
mov h,e ; третий план
mov m,c
inr l ; след. строка
mov m,b
pop b
mov h,d ; второй план
mov m,c
mov h,a ; первый план
mov m,b
inr l ; след. строка
pop b
mov m,c
...
и т.д.
если развернуть, чтобы циклы не проверять, т.к. свободных переменных нет, то ... надо проверить...

только при переходе к следующему ряду надо все сразу прибавлять.
плюс 3 inr

metamorpho
02.08.2020, 23:27
Перевёл пример кода (с Z80 на Векторовский ассемблер) вывода спрайта от Jerri.
Сравнил по тактам (если я всё правильно посчитал конечно) свой вариант вывода спрайта и вариант от Jerri.
На вывод 9-и байт + возврат на начальную плоскость + переход на следующую строку
мой вариант тратит 384 такта
вариант от Jerri 224 такта
разница 160 тактов

Итого на вывод спрайта 24х24 точки (учитавая только чистый вывод 9 байтов + возврат на 1-ю плоскость + переход на следующую строку)
мой вариант тратит 3072 такта
вариант от Jerri 1792 такта
разница 1280 тактов

1280 тактов похоже это неплохой рывок по скорости.

Но правильно ли я понял (из слов KTSerg) что вариант от Jerri будет мерцать ?

KTSerg
03.08.2020, 05:33
...
Но правильно ли я понял (из слов KTSerg) что вариант от Jerri будет мерцать ?
Нет, я говорил о своей модификации этого метода.
Моя версия склонна к мерцанию, и именно моя версия на практике не юзабельна.
Быстрая версия алгоритма, но не юзабельная.

ivagor
03.08.2020, 06:15
вариант от Jerri 224 такта
Имхо правильнее все же считать для вывода "блока" из двух строк, я насчитал 464 такта (для ширины 24 точки). Можно немного ускорить (https://zx-pk.ru/threads/31954-pishu-shedevr-dlya-%C2%ABvektora-06ts%C2%BB.html?p=1075016&viewfull=1#post1075016) переходы между плоскостями, будет 440 тактов. Ну и можно развернуть, тогда не только убираем команды цикла, но и еще чуть ускоряем переходы между плоскостями, должно получится 412 тактов на две строки, но скорее всего понадобится отдельная процедура для частичного вывода спрайтов.

metamorpho
03.08.2020, 09:21
Пытаюсь вникнуть как работает этот метод.
Похоже я несовсем правильно понял,
но насколько я понял подпрограмма рисования спрайта (от Jerri)
связана с программой обработки прерываний, в которую каким то образом должен быть
внедрён следующий код (это с моим переводом на Векторовский формат ассемблера):


;процедура обработки прерывания с восстановлением поврежденных данных
;при доступе к стеку
;регистровая пара для доступа к стеку BC
im_routine
di ; di
;сохраняем HL и забираем адрес возврата из прерывания
xthl ; ex (sp),hl
;сохраняем его
shld im_ret ; ld (im_ret),hl
;забираем HL
pop h ; pop hl
;сохраняем его чтобы не потерять при манипуляциях с SP
shld im_hl ; ld (im_hl),hl
;сохраняем флаги
push psw ; push af
;вычисляем корректный адрес стека программы
lxi h,2 ; ld hl,2
dad sp ; add hl,sp
;сохраняем стек программы
shld im_sp ; ld (im_sp),hl
pop psw ; pop af
;восстановлением поврежденые данные регистром BC
push b ; push bc

;задаем стек прерывания
lxi sp,im_stek ; ld sp,im_stek
;сохраняем все регистры кроме HL
push psw ; push af,bc,de
push b
push d
;-----------------------------
;ISR
;здесь прерывание
;-----------------------------
;восстанавливаем регистры
pop d ; pop de,bc,af
pop b
pop psw
;восстанавливаем HL
lxi h,2121h ; ld hl,#2121

im_hl: equ $-2
;восстанавливаем стек
lxi sp,3131h ; ld sp,#3131
im_sp: equ $-2
ei ;ei
;возвращаемся из обработки прерывания
jmp 0c3c3h ; jp #c3c3
im_ret: equ $-2


В этом коде мне не понятны следующие моменты:
- разве правильно во время прерывания сделать запрет командой DI ?
- что такое ISR ?
- что имеется ввиду в строке ";здесь прерывание" какое прерывание ?
- lxi sp,3131h ;
im_sp: equ $-2 ; !!!???? разве здесь не споткнётся программа, зачем данные стоят между командами кода - ведь это транслируются в код каких-то команд ?
ei
- jmp 0c3c3h ; jp #c3c3 ; почему выход не по RET, а скачок в экранную память ?
- как и куда внедрить этот код ?

ivagor
03.08.2020, 09:28
- разве правильно во время прерывания сделать запрет командой DI ?
Это лишняя команда, т.к. процессор запрещает прерывание при начале его обработки.

- - - Добавлено - - -


im_sp: equ $-2
Дело вкуса, я в таких случаях делаю
im_sp: lxi sp,3131h
А обращение будет
shld im_sp+1

KTSerg
03.08.2020, 09:32
Пытаюсь вникнуть как работает этот метод.
Похоже я несовсем правильно понял,
но насколько я понял подпрограмма рисования спрайта (от Jerri)
связана с программой обработки прерываний, в которую каким то образом должен быть
внедрён следующий код (это с моим переводом на Векторовский формат ассемблера):
...

Указанный алгоритм обработки прерывания просто позволяет не портить данные в стеке, на тот случай если с помощью стека организован вывод спрайтов и при этом прерывания не запрещаются.

2121 и 3131 - это просто от фанаря, т.к. в начале алгоритма они всегда заменятся на конкретные значения.
Т.к. состояние стека восстанавливается после перехода к подпрограмме прерывания, то выход из прерываний по JMP значение которого было вытянуто из стека при его восстановлении.
ISR - это место где пользователь вставляет свою обработку прерывания.
Т.к. приведённый алгоритм, это только обёртка (восстанавливающая стек) для настоящей подпрограммы прерывания.

Скинь мне в личку свой е-майл. Кину тебе исходник своей тестилки вывода спрайтов. Там этот алгоритм прерывания реализован.

ivagor
03.08.2020, 09:40
2121 и 3131 - это просто от фанаря
Если быть занудным, то не совсем - это повторение кода команды, чтобы чуть лучше сжималось, но это конечно совсем микроскопическая мелочь. Сам в модифицируемых командах как правило пишу начальный аргумент 0.

metamorpho
03.08.2020, 10:06
ivagor, KTSerg спасибо!!
Код становится яснее :)

KTSerg почту скинул см. личку

- - - Добавлено - - -

Ёще хотел уточнить такой вопрос:

допустим
Время ПР - это время выполнения программы обработки прерываний
Время ОП - это время выполнения основной программы

Тогда если "время ПР" увеличивается, то уделяемое процессором (между прерываниями) "время ОП" уменьшается ?

KTSerg
03.08.2020, 10:40
...
Ёще хотел уточнить такой вопрос:

допустим
Время ПР - это время выполнения программы обработки прерываний
Время ОП - это время выполнения основной программы

Тогда если "время ПР" увеличивается, то уделяемое процессором (между прерываниями) "время ОП" уменьшается ?

А куда деваться, конечно уменьшается.
Тут наверное удобнее себе представить временнУю шкалу, которая показывает время выполнения ОП.
Если прерывания отключены, то просто всё время выполняется ОП.
Если прерывания включаем, то каждые 20мсек, происходит прерывание, которое отвлекает ресурсы процессора от выполнения ОП на обработку ПР.
Можно представить себе жуткий случай, когда ПР на столько перегружено задачами, что на его обработку требуется время близкое к 20мсек... Тогда ОП будут доставаться только крохи от ресурсов процессора, между тем как одно ПР закончилось, и началось другое.

Есть одна очевидная ситуация. Пока выполняется прерывание, новое не произойдёт, т.к. оно аппаратно запрещено. Если прерывание перегружено и выполняется более 20мсек, то это приведёт к потерям (пропускам) прерываний. Типа должно уже начаться новое и сделать что-то очень важное, но предыдущее ещё не закончилось... что-то важное не будет сделано...

metamorpho
03.08.2020, 10:53
Если это так, тогда справедливо к тактам программы вывода спрайта (по методу Jerri) прибавить такты (время) затраченные на обработку-восстановление стека (по методу Jerri) в прерывании ?
Но как правильно это можно посчитать ?
Это к тому чтобы точно понять насколько вариант от Jerri быстрее.

jerri
03.08.2020, 11:53
Пытаюсь вникнуть как работает этот метод.
Похоже я несовсем правильно понял,
но насколько я понял подпрограмма рисования спрайта (от Jerri)
связана с программой обработки прерываний, в которую каким то образом должен быть
внедрён следующий код (это с моим переводом на Векторовский формат ассемблера):


;процедура обработки прерывания с восстановлением поврежденных данных
;при доступе к стеку
;регистровая пара для доступа к стеку BC
im_routine
di ; di
;сохраняем HL и забираем адрес возврата из прерывания
xthl ; ex (sp),hl
;сохраняем его
shld im_ret ; ld (im_ret),hl
;забираем HL
pop h ; pop hl
;сохраняем его чтобы не потерять при манипуляциях с SP
shld im_hl ; ld (im_hl),hl
;сохраняем флаги
push psw ; push af
;вычисляем корректный адрес стека программы
lxi h,2 ; ld hl,2
dad sp ; add hl,sp
;сохраняем стек программы
shld im_sp ; ld (im_sp),hl
pop psw ; pop af
;восстановлением поврежденые данные регистром BC
push b ; push bc

;задаем стек прерывания
lxi sp,im_stek ; ld sp,im_stek
;сохраняем все регистры кроме HL
push psw ; push af,bc,de
push b
push d
;-----------------------------
;ISR
;здесь прерывание
;-----------------------------
;восстанавливаем регистры
pop d ; pop de,bc,af
pop b
pop psw
;восстанавливаем HL
lxi h,2121h ; ld hl,#2121

im_hl: equ $-2
;восстанавливаем стек
lxi sp,3131h ; ld sp,#3131
im_sp: equ $-2
ei ;ei
;возвращаемся из обработки прерывания
jmp 0c3c3h ; jp #c3c3
im_ret: equ $-2


В этом коде мне не понятны следующие моменты:

- разве правильно во время прерывания сделать запрет командой DI ?

возможно не нужно, не знаю как Вектор обрабатывает прерывания



- что такое ISR ?


interrupt sub routine

обработка прерывания



- что имеется ввиду в строке ";здесь прерывание" какое прерывание ?


имеется ввиду "здесь обрабатываем прерывание"




- lxi sp,3131h ;
im_sp: equ $-2 ; !!!???? разве здесь не споткнётся программа, зачем данные стоят между командами кода - ведь это транслируются в код каких-то команд ?

нет, потому что метка указывает на данные заносимые в регистр стека



ei
- jmp 0c3c3h ; jp #c3c3 ; почему выход не по RET, а скачок в экранную память ?
im_ret equ $-2


это не скачок в экранную память, здесь подставляется адрес возврата

и происходит прыжок на продолжение выполнения кода



- как и куда внедрить этот код ?

это процедура обработки прерывания.

- - - Добавлено - - -


Если это так, тогда справедливо к тактам программы вывода спрайта (по методу Jerri) прибавить такты (время) затраченные на обработку-восстановление стека (по методу Jerri) в прерывании ?
Но как правильно это можно посчитать ?
Это к тому чтобы точно понять насколько вариант от Jerri быстрее.

кстати вот тебе визуализация того о чем я говорю все время.

https://zx-pk.ru/attachment.php?attachmentid=73206&d=1596444430

шторка высотой 24 скрывает спрайты уходящие вверх и вниз.
и часть лабиринта.

справа ты видишь вариант 1 = мой вариант хранения спрайта - линейный по 3м битпланам
вариант 2 более быстрый по отрисовке но более геморойный в хранении спрайта.

и также нацарапана вероятность появления марцания.

но если ее посмотреть наложив на весь растр - она ничтожна.
луч должен в строго определенное время быть в определенном месте.
как то так.


73206

ivagor
03.08.2020, 11:54
не знаю как Вектор обрабатывает прерывания
Дело не в векторе, и 8080 и z80 запрещают прерывания в начале их обработки. В случае z80 есть специфика с nmi, но и там до retn или ei прерывания тоже будут запрещены.

jerri
03.08.2020, 12:20
Дело не в векторе, и 8080 и z80 запрещают прерывания в начале их обработки. В случае z80 есть специфика с nmi, но и там до retn или ei прерывания тоже будут запрещены.Не знаю, в свое время я ориентировался на крупных производителей ПО, в ранних программах прерывания запрещались при обработке прерывания и разрешались при при завершении. Возможно были нюансы

metamorpho
03.08.2020, 12:43
Jerri, спасибо за подробные объяснения!!
Я всё больше понимаю что к чему в ассемблере.
Отдельное спасибо за визуализацию !!

Метод вывода спрайта, который ты предлагаешь очень хорош.
И я уже близок к тому чтобы перейти на более быстрый вывод спрайта, но мне нужно точно понять насколько твой вариант быстрее того что я сейчас использую.
Но я не могу понять как правильно подсчитать.
Вот твоя программа вывода спрайта состоит по сути из двух частей:
1-я это вывод спрайта
2-я это программа, которая встроена в обработку прерываний.
Одно без другого не будет работать.
Так вот вопрос как подсчитать сколько времени отнимает 2-я часть программы у процессора ?
По сути это время нужно будет прибавить к 1-й части и только тогда будет видна полная картина сколько времени (тактов) уходит на отрисовку одного полного спрайта используя твой метод.

KTSerg
03.08.2020, 13:00
...
Но я не могу понять как правильно подсчитать.
Вот твоя программа вывода спрайта состоит по сути из двух частей:
1-я это вывод спрайта
2-я это программа, которая встроена в обработку прерываний.
Одно без другого не будет работать.
Так вот вопрос как подсчитать сколько времени отнимает 2-я часть программы у процессора ?
По сути это время нужно будет прибавить к 1-й части и только тогда будет видна полная картина сколько времени (тактов) уходит на отрисовку одного полного спрайта используя твой метод.

Быстрее - медленнее, больше - меньше...
Всё в мире относительно...
" Три волосины на голове, это много или мало? А три волосины в тарелке с супом, это много или мало? "

Если выводить на экран один спрайт в день, то влияние "лишних" команд в прерывании (спасающих стек от повреждения), на показатель оптимальности подпрограммы вывода спрайта, конечно будет значительным.
А вот если основная программа только и занимается, что выводит на экран спрайты, то думаю издержки увеличения длительности прерывания (спасением стека) будут ничтожны по сравнению с выигрышем полученным от применения стека в процедуре вывода спрайта.
Причём при этом ещё бонусом получаем не отключаемые (в основной программе) прерывания, а значит возможность программирования в прерываниях музыки.

- - - Добавлено - - -

Как оценить выигрыш во времени...
Слепить специальную, очень маленькую программу, которая в основном цикле, только и делает, что без остановки в цикле выводит на экран значение счетчика - сколько спрайтов выведено на экран.
Т.е. постоянно выводит на экран 4 спрайта - значение регистровой пары, после вывода увеличивать значение на 4 и снова выводить... и так в цикле.

Сделать два варианта программы. Первый вывод спрайта без использования стека. Второй по обсуждаемой методике, с соответствующим алгоритмом вывода спрайта и обработки прерывания.

И сравнить за какое время счетчики переполнятся.
В каком варианте переполнились быстрее, и на сколько быстрее.

ivagor
03.08.2020, 13:03
В emu и emu80 можно просто поставить бряки в начало интересующего фрагмента программы и в конец и эмулятор напишет, сколько прошло тактов.

jerri
03.08.2020, 13:17
Jerri, спасибо за подробные объяснения!!
Я всё больше понимаю что к чему в ассемблере.
Отдельное спасибо за визуализацию !!

Метод вывода спрайта, который ты предлагаешь очень хорош.
И я уже близок к тому чтобы перейти на более быстрый вывод спрайта, но мне нужно точно понять насколько твой вариант быстрее того что я сейчас использую.
Но я не могу понять как правильно подсчитать.
Вот твоя программа вывода спрайта состоит по сути из двух частей:
1-я это вывод спрайта
2-я это программа, которая встроена в обработку прерываний.
Одно без другого не будет работать.
Так вот вопрос как подсчитать сколько времени отнимает 2-я часть программы у процессора ?
По сути это время нужно будет прибавить к 1-й части и только тогда будет видна полная картина сколько времени (тактов) уходит на отрисовку одного полного спрайта используя твой метод.Итак давай сначала.
Твоя программа обработки прерывания

4 push. Сохранение регистров.
4 pop. Восстановление регистров
Ei
Ret

+ Компактно
- нельзя использовать рисование спрайтов через стек.



Моя программа при сохранении раза в 2-3 дольше.
Остальное идентично.

-чуть больше
+Спрайты рисуем очень быстро через стек

Скорость рисования спрайтов моей программой ты оценивал на 30-40 процентов быстрее
Те вместо 3х спрайтов ты нарисуешь 4
И при этом ещё и музыка играет.


И кстати поле в визуализации заявлено до 11*10

metamorpho
03.08.2020, 18:04
Как считаете правильно ли такое вычисление ?

КР580ВМ80А - каждая команда выполняется за 1…5 машинных циклов, каждый из которых состоит из 3…5 тактов.
Минимальное время выполнения простых регистровых команд 4 такта.
Таким образом максимальная производительность процессора оценивается в 625 тысяч оп/c.

Частота прерываний 50 Гц
50 раз в секунду процессор прерывает выполнение основной программы
и выполняет программу обработки прерываний и ресурсы-такты процессора отнимаются от выполнения ОСНОВНОЙ программы.

Та часть программы (Jerri) которая восстанавливает стек в программе прерываний использует каждое прерывание 284 такта.
Значит 50х284 такта=14200 тактов в 1 секунду отнимает 2-я часть программы (которая в прерываниях восстанавливает стек)

Например допустим за 1 секунду 15 раз (по 4 спрайта за раз) основная программа рисует спрайты.
15 раз х 4 спрайта = 60 раз/с идёт исполнение программы вывода спрайта на экран

Полный вывод одного спрайта:
Обычная программа вывода спрайта = 7520 такта (развёрнутый цикл)
1-я часть программы вывода спрайта Jerri = 5564 такта (развёрнутый цикл)
Разница 1956 тактов за один раз
1956 х 60 раз = 117 360 такта - 14200 тактов (использует 2-я часть программы от Jerri)=103160 такта экономия за секунду

- - - Добавлено - - -

Начал внедрение метода Jerri в проект.
Оформил прерывание и вроде работает всё нормально, но при скроллинге выдаёт неправильную работу
вывода спрайтов по 8 строк которые печатаются - см. (rom)
Ничего не изменял кроме программы прерывания.
Почему могла возникнуть эта проблема ?
Вот код программы прерывания.



;================================== обработка прерываний
INIT:
xthl ; обмен HL SP
shld im_ret+1 ; сохраним адрес возврата из прерываний
pop h
shld im_hl+1 ; сохраним значение HL при выходе из прерываний
push psw
lxi h,2 ;\ вычисляем указатель стека
dad sp ;/
shld im_sp+1 ; сохраним указатель стека
pop psw
push b ; восстановим данные испорченные стеком

lxi sp,im_stek ; временный указатель стека для прерываний
push PSW
push b
push d

;============================== мои задачи
;PUSH H
;PUSH B
;PUSH D
;PUSH PSW

LDA WRPAL ; ПРОВЕРКА РАЗРЕШЕНИЯ ЗАПИСИ ПАЛИТРЫ В
ORA A ; ОЗУ ЦВЕТОГЕНЕРАТОРА.
JZ NWRPAL
MVI A,88H
OUT 00H
feutral: LXI H,COLR15 ; ЗАПИСЬ ПАЛИТРЫ.
LXI D,100FH
INIT1: MOV A,E
OUT 02
MOV A,M
OUT 0CH
OUT 0CH
OUT 0CH
OUT 0CH
OUT 0CH
DCX H
OUT 0CH
DCR E
OUT 0CH
DCR D
OUT 0CH
JNZ INIT1
NWRPAL: MVI A,8AH ; ПРОВЕРКА НАЖАТИЯ НА ЛЮБУЮ КЛАВИШУ
OUT 00 ; МАТРИЦЫ КЛАВИАТУРЫ 8*8 (КРОМЕ УС,СС,РУС/ЛАТ).
XRA A
OUT 03
IN 2
STA STATUS
MVI A,0FEH ; ПРОВЕРКА НАЖАТИЯ НА КЛАВИШИ ИГРОВОГО РЯДА.
OUT 03
IN 02
STA KEYKOD
MVI A,88H
OUT 00
LDA BORDER ; УСТАНОВКА ЦВЕТА БОРДЮРА.
ANI 0FH
OUT 02
LDA SCROLL ; УСТАНОВКА ВЕРТИКАЛЬНОГО ПОЛОЖЕНИЯ ЭКРАНА.
OUT 03
;============================================
;jmp EXINIT
; ОБРАБОТКА ВЫСОТЫ И ДЛИТЕЛЬНОСТИ ЗВУКА ПО НОМЕРУ ПАРАМЕТРА ЗВУКА.
;
LDA TON ; ВЗЯТЬ КОД ИЗ БУФЕРА НОМЕРОВ ПАРАМЕТРОВ ЗВУКА.
ORA A ; НОМЕР ПАРАМЕТРА УСТАНОВЛЕН?
JZ TSSOUN ; ЕСЛИ НЕТ - ПЕРЕЙТИ НА ПРОВЕРКУ ОТРАБОТКИ ДЛИТ.ЗВУКА.
DCR A ; УМЕНШИТЬ НОМЕР НА 1, Т.К. МАССИВ НАЧИН. С НУЛЕВОГО.
ADD A ; УМНОЖИТЬ НОМЕР ПАРАМЕТРОВ ЗВУКА НА 4, ТАК КАК
ADD A ; ПАРАМЕТРЫ ОДНОГО ЗВУКА ЗАНИМАЮТ 4 БАЙТА.
MOV E,A ; ПОДГОТОВИТЬ В "DE" СМЕЩЕНИЕ ОТ НАЧАЛА ПАРАМЕТРОВ.
MVI D,0
LXI H,BAZTON ; УСТАНОВИТЬ В "HL" АДРЕС НАЧАЛА ПАРАМЕТРОВ ЗВУКА.
DAD D ; СЛОЖЕНИЕМ С "DE" ПОЛУЧИТЬ В "HL" АДРЕС НУЖНЫХ ПАРАМ.
MVI A,0B6H ; УСТАНОВИТЬ РЕЖИМ 3 ТАЙМЕРА ДЛЯ КАНАЛА 2, ЗАПИСЬ КОЭФ-
OUT 08 ; ФИЦИЕНТА ДЕЛЕНИЯ В ДВА БАЙТА - СНАЧАЛА МЛ. ПОТОМ СТ.
MOV A,M ; ВЗЯТЬ МЛАДШИЙ БАЙТ КОЭФФ. ДЕЛЕНИЯ И
OUT 09 ; ЗАПИСАТЬ В КАНАЛ 2 ТАЙМЕРА.
INX H ; ПЕРЕДВИНУТЬ УКАЗАТЕЛЬ НА СЛЕДУЮЩИЙ БАЙТ ПАРАМЕТРОВ.
MOV A,M ; ВЗЯТЬ СТАРШИЙ БАЙТ КОЭФФ. ДЕЛЕНИЯ И
OUT 09 ; ЗАПИСАТЬ В КАНАЛ 2 ТАЙМЕРА.
INX H
MOV E,M ; ВЗЯТЬ В ПАРУ "DE" ДЛИТЕЛЬНОСТЬ ЗВУЧАНИЯ.
INX H
MOV D,M
XCHG ; И ЗАПИСАТЬ ЕЕ В
SHLD STSOUN ; СЧЕТЧИК ВРЕМЕНИ ЗВУЧАНИЯ.
XRA A ; ОБНУЛИТЬ БУФЕР НОМЕРОВ ПАРАМЕТРОВ ЗВУКА (Т.Е. ПАРА-
STA TON ; МЕТРЫ ВЗЯТЫ И ИХ НЕ НУЖНО СНОВА ОПРЕДЕЛЯТЬ).
JMP EXINIT ; ВЫЙТИ ИЗ П/П ОБРАБОТКИ СИСТЕМНОГО ПРЕРЫВАНИЯ.
;
TSSOUN: LHLD STSOUN ; ВЗЯТЬ СЧЕТЧИК ВРЕМЕНИ ЗВУЧАНИЯ И ПРОВЕРИТЬ,
MOV A,H ; РАВЕН ЛИ ОН НУЛЮ (ВРЕМЯ ЗВУЧАНИЯ КОНЧИЛОСЬ)?
ORA L
JZ OFSOUN ; ЕСЛИ КОНЧИЛОСЬ - ВЫКЛЮЧИТЬ ЗВУК!
DCX H ; УМЕНЬШИТЬ СЧЕТЧИК.
SHLD STSOUN
JMP EXINIT ; И ВЫЙТИ ИЗ П/П ПРЕРЫВАНИЯ.
OFSOUN: MVI A,0B6H ; ВЫКЛЮЧИТЬ КАНАЛ 2 ТАЙМЕРА ПУТЕМ ЗАПИСИ В РЕГ.
OUT 08 ; РЕЖИМА УПР. СЛОВА ДЛЯ ЭТОГО КАНАЛА БЕЗ ПАРАМ.
EXINIT: XRA A
STA WRPAL

;================================================= =

lda kub_napr
cpi 3 ; движение вверх скрол вниз
jnz ruft12
;=======затриаем_сверху=4 строки + снизу рисуем 8 строк
; стираем ширму сверху
lxi b,0
lxi h,0
dad sp ; HL=HL+SP
shld s_sp ; сохраняем значение стека
lda scroll
sui 7
mov l,a
mvi h,0e0h
mvi a,32
shirmczz: sphl ; перенос из HL в SP 8
push b ; запись в экран 16
push b ; запись в экран 16
inr h
dcr a ; 8
jnz shirmczz ; 12

; рисуем снизу
lxi b,0FFFFh
lda scroll
adi 9
mov l,a
mvi h,0e1h
mvi a,31
shirmc2r: sphl ; перенос из HL в SP 8
push b ; запись в экран 16
push b ; запись в экран 16
push b ; запись в экран 16
push b ; запись в экран 16
inr h
dcr a ; 8
jnz shirmc2r ; 12

lhld s_sp ; возвращаем значение стека
sphl
jmp ruft14


ruft12:
cpi 4 ; движение вниз скрол вверх затриаем снизу строку 08 + сверху рисуем 8 строк
jnz ruft14 ;иначе ничего не делаем
;=======затриаем_сверху=4 строки + снизу рисуем 8 строк
; стираем ширму снизу
lxi b,0
lxi h,0
dad sp ; HL=HL+SP
shld s_sp ; сохраняем значение стека
lda scroll
adi 13
mov l,a
mvi h,0e0h
mvi a,32
shirmc44: sphl ; перенос из HL в SP 8
push b ; запись в экран 16
push b ; запись в экран 16
inr h
dcr a ; 8
jnz shirmc44 ; 12

; рисуем сверху
lxi b,0FFFFh
lda scroll
adi 1
mov l,a
mvi h,0e1h
mvi a,31
shirmc2r44: sphl ; перенос из HL в SP 8
push b ; запись в экран 16
push b ; запись в экран 16
push b ; запись в экран 16
push b ; запись в экран 16
inr h
dcr a ; 8
jnz shirmc2r44 ; 12

lhld s_sp ; возвращаем значение стека
sphl
;===================================

ruft14:
; выход из прерываний
pop d
pop b
pop psw
im_hl: lxi h,$2121
im_sp: lxi sp,$3131
ei
im_ret: jmp $c3c3