PDA

Просмотр полной версии : Игрушка Columns для УКНЦ



BlaireCas
09.07.2023, 18:07
Кажется никто давно не писал игр для нашей замечательной машинки УКНЦ.
А давайте напишем хотя-бы что-то? Хотя-бы тетрис? :) Так-сказать "потрясем ассемблером!" :)

Оригинал это Sega Genesis - Columns.
Вроде для УКНЦ ничего похожего не видел.

Падают разные шарики и прочее и надо чтобы совпало больше 3-х цветов по вертикали/горизонтали/диагонали. Затем они уничтожаются, фигурки в стакане падают вниз и вообщем все повторяется.

https://i.imgur.com/cJEZJ59.png

Арт нагло украден с zx-art. Спасибо автору, вроде подписал его ник внизу.
Процедура распаковки бэкграунда от Manwe за что ему вместе с IvanQ тоже спасибо.

Для старта - нажать "Пробел". Ну а дальше "вправо-влево-вверх-вниз".
Для RGB <-> GRB - нажать K1
Для так-сказать "улучшенных тайлов" - нажать К2 :)
K3 - включает или выключает увеличение уровня по набору определенных очков (если отключить - фигурки не начнут увеличивать скорость и можно будет играть на первом уровне пока не надоест)

Исходные коды: https://github.com/blairecas/column
.sav-ка находится там в /release

Диск с автозагрузкой: 79217

BlaireCas
10.07.2023, 14:21
Поулучшал что можно. Добавил всякие там объяснения кнопок, вывод очков, уровень. Чутка тайлы подправил.
Сейчас стало более-менее законченное.

Hunta
10.07.2023, 14:42
Сунулся в первое попавшееся место. В чём преимущество такого варианта


PPSEN: mov #PPMSG, R0 ; array address
mov #5, R1 ; bytes to send+1 (sending from @#PP_MSG)
br 1$
2$: movb (R0)+, @#176676
1$: tstb @#176674 ; test if we are ready to send
bpl 1$ ; cycle if >= 0 (not set last bit in byte)
sob R1, 2$
return

перед таким


PPSEN: mov #PPMSG, R0 ; array address
mov #4, R1 ; bytes to send (sending from @#PP_MSG)
1$:
tstb @#176674 ; test if we are ready to send
bpl 1$ ; cycle if >= 0 (not set last bit in byte)

movb (R0)+, @#176676

sob R1, 1$

return

??

BlaireCas
10.07.2023, 14:51
В чём преимущество такого варианта
Выполнится последний раз tstb в первом случае. Тут я не знаю насколько это критично проверить по окончании данный регистр. Где-то очень давно взял этот кусок кода для пересылки данных в ПП и зачем-то там было сделано именно с тестом регистра "до" и "после".

Hunta
10.07.2023, 14:54
Выполнится последний раз tstb в первом случае.
Это обычный вариант - засылка по готовности. И обычно проверяется ПЕРЕД пересылкой, а после, если всё закончилось - тупо оставляем до следующего раза (немного ускоряем программу, немного делаем меньше код). Насколько я помню от времён программирования на УК-НЦ - никаких проблем не должно быть.

Так же (делаем меньше код)


; can palka go left?
CanGoLeft:
; check min X
mov PalkaX, R1
beq 90$
; check stakan
mov PalkaY, R2
add #47., R2
asr R2
bic #^B111, R2 ; palka Y to stakan line addr
add R1, R2
dec R2
tstb Stakan(R2)
bne 90$
sec
return
90$: clc
return

обычно реализуют как


; can palka go left?
CanGoLeft:
; check min X
mov PalkaX, R1
beq 90$
; check stakan
mov PalkaY, R2
add #47., R2
asr R2
bic #^B111, R2 ; palka Y to stakan line addr
add R1, R2
dec R2
tstb Stakan(R2)
BEQ 100$
90$:
TST (PC)+
100$:
SEC
RETURN

BlaireCas
10.07.2023, 15:12
Так же (делаем меньше код)
Да там в коде вагон с тележкой неоптимальщины/раздутия размеров и т.д.

Hunta
10.07.2023, 15:21
Да там в коде вагон с тележкой неоптимальщины/раздутия размеров и т.д
Ну так не надо так делать. 200 гигов памяти на PDP-11 не встретишь.

Alex_K
10.07.2023, 15:39
Сунулся в первое попавшееся место. В чём преимущество такого варианта
Всё правильно сделано. Канал К2 работает так: первые два байта это адрес блока параметров. Третий байт должен быть обязательно ненулевым. А вот по приходу четвёртого байта п/п обработки прерываний его не считывает, а только ставит флаг вызова в диспетчере процессов. Уже когда выполнится процесс драйвера канала К2, то он считает этот четвёртый байт. Со стороны ЦП установится флаг готовности, что свидетельствует о том, что запрос выполнен.
Если же мы решили работать в режиме прерываний, то тогда заносятся четыре байта, в конце готовность не проверяется, устанавливается флаг разрешения прерывания. Как только прерывание произошло, то запрос выполнен.

Hunta
10.07.2023, 15:48
Всё правильно сделано.


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

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

Alex_K
10.07.2023, 15:51
Ох уж эти современные программисты и куски "волшебного кода". Ок, делаем дальше, не понимая почему.
Так предложите правильный вариант. Ваш вариант с циклом из четырёх байт и отсутствием проверки готовности в конце я считаю неправильным.

Hunta
10.07.2023, 15:58
Так предложите правильный вариант.
Я совсем не про то.

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


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

Alex_K
10.07.2023, 16:06
В силу описанного выше - я не могу сказать - правильный он или нет - надо смотреть взаимодествие между ЦП и ПП. Вполне возможно, что в некоторых местах будет правильным, в некоторых - нет. Но разбираться за автора во всех таких "волшебных" местах - я считаю неправильным.
Взаимодействие при запуске своего кода в ПП: надо подать три запроса - выделить память (код 1), записать из памяти ЦП в память ПП (код 020), запустить п/п в памяти ПП (код 030). Если запросы с кодами 020 и 030 можно гнать сплошным потоком. То на запрос с кодом 1 надо дождаться ответа, произошла ли ошибка при выделении памяти, и если всё нормально, то адрес выделенного блока в ОЗУ ПП.

Hunta
10.07.2023, 16:12
Взаимодействие при запуске своего кода в ПП
Если посмотреть код рядом с этой процедурой, то можно понять, что, как я и писал ранее:

в некоторых местах будет правильным, в некоторых - нет
Так что мнение

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

BlaireCas
10.07.2023, 16:19
Да там можно вариант Хунты использовать, никаких проверок на выделение памяти в ПП нету. Также нет никакого выхода в РТ-11.
Не выделит полсотни байт в ПП - ну облом (да, там столько мало запрашивается и думается случай скорей нереальный что в ПП нет немножко свободной памяти).

Alex_K
10.07.2023, 16:26
Если посмотреть код рядом с этой процедурой, то можно понять, что, как я и писал ранее:
Сама процедура PPSEN написана правильно. А вот рядом с ней к PPRUN у меня тоже есть претензии.

то же в общем случае - неправильно
Вы считаете моё мнение неправильным, я ваше. Ну что ж, на том и разойдёмся.

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


Да там можно вариант Хунты использовать, никаких проверок на выделение памяти в ПП нету.
Используйте. Он вполне пройдёт, если не будет ошибок с выделением памяти. А если будет ошибка, то в PPAPP останется ноль и вы закачаете по нулевому адресу в ОЗУ ПП.
А так как у вас всё равно проверку на выделение памяти не производится, то и сработает.

Hunta
10.07.2023, 16:37
Вы считаете моё мнение неправильным, я ваше. Ну что ж, на том и разойдёмся.
Ок, поскольку я не специалист по УК-НЦ - пошёл-ка я отсюда. Колдуйте дальше. Без меня.

BlaireCas
10.07.2023, 16:41
И вообще господа, я сам знаю что код у меня такой что лучше его не смотреть. (всякие явно бросающиеся в глаза вещи в циклы не завернуты, где-то вообще на регистрах можно было вместо переменных в памяти, логику лучше можно сделать, какие-то флаговые переменные для которых хватает байта выделены как word и т.д.).
Но так уж понаписал как понаписал. Сейчас всё это причесывать не буду. Но в будущем постараюсь что-то учесть и написание кода улучшать :) (я надеюсь на это).

Alex_K
10.07.2023, 16:57
всякие явно бросающиеся в глаза вещи в циклы не завернуты
Развёрнутый цикл выполняется быстрее, место правда кушает. Но тест копирования памяти это показал.

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

какие-то флаговые переменные для которых хватает байта выделены как word и т.д.).
Запись в байт в 1801ВМ2 медленней проходит, а память ПП так вообще. Но если скорость не играет роль, то можно и в отдельных битиках хранить в слове.

Alex_K
10.07.2023, 19:15
Используйте. Он вполне пройдёт, если не будет ошибок с выделением памяти. А если будет ошибка, то в PPAPP останется ноль и вы закачаете по нулевому адресу в ОЗУ ПП.
А так как у вас всё равно проверку на выделение памяти не производится, то и сработает.
Посмотрел реализацию запроса блока памяти в ПЗУ. Обязательно надо ждать ответа. В блоке в слове со смещением 6 передаётся размер блока в словах при запросе памяти. А при передаче данных в ПП там находится адрес передаваемого блока в ЦП. Т.е. если вы не будете ждать и сформируете новый блок для передачи в ПП (код 020), то перед установкой бита готовности ваш адрес ЦП затрётся размером выделенного блока.
Так что не сработает, если даже ошибок не будет. Так что обязательно ждать готовности канала К2 после передачи данных.

Titus
11.07.2023, 01:37
Вроде для УКНЦ ничего похожего не видел.

Спасибо за игрушку, понравилась!

Динамично, приятно, быстро, красиво.

Хотелось бы, чтобы не так рано переключалась игра на быструю скорость)

BlaireCas
12.07.2023, 07:19
Хотелось бы, чтобы не так рано переключалась игра на быструю скорость)
Даже не предполагалось что кто-то будет реально играть :)
Сделал несколько больше очки переключения уровня (и соответственно скорости): 500., 1000., 1500., 2000., 3000., 4000., 6000.

Titus
12.07.2023, 11:36
Даже не предполагалось что кто-то будет реально играть
Сделал несколько больше очки переключения уровня (и соответственно скорости): 500., 1000., 1500., 2000., 3000., 4000., 6000.

На мой взгляд, сильно увеличивать скорость вообще не надо.
Чуть увеличил разок и все.
Люди обычно играют, чтобы расслабиться, переключиться.
А тут раз, и вдруг все быстрее пошло)

BlaireCas
12.07.2023, 14:38
На мой взгляд, сильно увеличивать скорость вообще не надо.
Надо будет подумать сделать там выбор навроде "Уровень вкл/выкл".

BlaireCas
13.07.2023, 00:47
Сунулся в первое попавшееся место. В чём преимущество такого варианта
Код:


PPSEN: mov #PPMSG, R0 ; array address
mov #5, R1 ; bytes to send+1 (sending from @#PP_MSG)
br 1$
2$: movb (R0)+, @#176676
1$: tstb @#176674 ; test if we are ready to send
bpl 1$ ; cycle if >= 0 (not set last bit in byte)
sob R1, 2$
return



Хунта наверное не посмотрит. Но ведь... Чорт подъери:

https://i.imgur.com/j6G8sDP.png

Не то чтобы я спорил с Alex_K и откуда-то взял нечто другое. Но вон в журнале тоже как-бы "а и нафиг нам tstb лишнее, проживем и без него". Даже без "первого" tstb (вдруг как-раз без первого-то можно).

Флеймово было, но я останусь верен старому коду с двумя tstb уж фиг с ним.

Hunta
13.07.2023, 08:28
Даже без "первого" tstb (вдруг как-раз без первого-то можно).
Здесь другой подход - всегда дожидаемся готовности после засылка байта. Он похож на мой первый вариант, просто проверка готовности ПОСЛЕ засылки байта. То есть на выходе из процедуры - мы дождались окончания пересылки. В этом случае соблюдается

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

Alex_K
13.07.2023, 10:50
Не то чтобы я спорил с Alex_K и откуда-то взял нечто другое. Но вон в журнале тоже как-бы "а и нафиг нам tstb лишнее, проживем и без него". Даже без "первого" tstb (вдруг как-раз без первого-то можно).
А вы обратили внимание, что там только две команды - передача в ОЗУ ПП (код 020) и запуск в ОЗУ ПП (код 030). Отсутствует команда выделения блока памяти в ОЗУ ПП (код 1). Здесь естественно сработает, т.к. функции 020 и 030 не меняют ваш блок параметров. А функция 1 после исполнения передаёт в ваш блок параметров результат операции.

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


но ценой то, что в общем (весь) код будет работать немного медленней. В целом я бы реализовал два вариант процедур - одну на код 1 (можно по этой схеме), вторую - по моему варианту - на все другие коды, где можно не ждать после последнего байта
Да уж, задержка будет ужасной. И выигрыш в задержке будет только при запуске кода по команде 030. В случае передачи команды 020 и не ожидания установки бита готовности придётся ждать его перед командой 030. Вот собственно и весь выигрыш. А так ожидание ещё может уйти на синхронизацию с запуском кода в ПП, если кодам в ЦП и ПП надо взаимодействовать между собой.

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

Ещё столовую ложку дёгтя в бочку мёда. По поводу последовательной подачи команд 020 и 030. Всё сработает и с циклом на четыре, если адрес запуска в ПП будет равен адресу загрузки. А вот если не равны, то вы в блоке параметров пропишите уже новый адрес, а в ПП ещё не успел обработаться запрос 020. Тогда загрузка в ПП начнётся уже с нового адреса.
Я писал несколько программ, которые оставались резидентами в ПП, так у меня получалось, что адрес запуска не был равен адресу загрузки. В младших адресах был резидент, а в более старших осуществлялась инициализация и уменьшение занимаемого блока памяти под объём резидента.

BlaireCas
13.07.2023, 11:37
Отсутствует команда выделения блока памяти в ОЗУ ПП (код 1)
Ну кто-ж его теперь знает. Это ведь бумажный журнал. Сократили, закомментировали тремя точками остальной код. Однако по таким вот журналам и учились. Я уже забыл откуда взял изначальный код с двумя tstb, откуда-то (да да тупая копипаста). Похоже не из этого журнала. В каком-то другом видимо было.

Alex_K
13.07.2023, 11:45
Ну кто-ж его теперь знает. Это ведь бумажный журнал. Сократили, закомментировали тремя точками остальной код. Однако по таким вот журналам и учились. Я уже забыл откуда взял изначальный код с двумя tstb, откуда-то (да да тупая копипаста). Похоже не из этого журнала. В каком-то другом видимо было.
А чего тут знать-то? Блок параметров под меткой Z имеет адрес загрузки 30000. Тем более выделяют два блока, один на загрузку, другой на запуск. Никакой экономии памяти!!!

Titus
13.07.2023, 11:46
Сделал несколько больше очки переключения уровня (и соответственно скорости): 500., 1000., 1500., 2000., 3000., 4000., 6000.
В новой версии у меня на эмуляторе в нижней части экрана (под игровым полем) мусор.

Alex_K
13.07.2023, 11:51
Я уже забыл откуда взял изначальный код с двумя tstb, откуда-то (да да тупая копипаста). Похоже не из этого журнала. В каком-то другом видимо было.
Когда я начинал программировать в ПП, у меня не было соответствующей документации "Работа с внешними устройствами". Код запуска в ПП я брал из программы ZWUK.SAV. Она там уже была со счётчиком пять, т.е. такая как надо.

BlaireCas
13.07.2023, 11:56
в нижней части экрана (под игровым полем) мусор.
Логично, я убрал сколько-то слов с таблицы строк экрана которая идет ниже 288. строки. По-идее на реальном УКНЦ ниже 288. строк он не нарисует, а у тебя эмулятор видимо "дальше пошел" :)
Я запускаю когда emustudio - нажимаю shift-del, ctrl-del, ctrl-del (даже запомнил) и становится вроде как УКНЦ без сканлайнов.

Titus
13.07.2023, 12:12
По-идее на реальном УКНЦ ниже 288. строк он не нарисует, а у тебя эмулятор видимо "дальше пошел"
Я запускаю когда emustudio - нажимаю shift-del, ctrl-del, ctrl-del (даже запомнил) и становится вроде как УКНЦ без сканлайнов.

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

BlaireCas
13.07.2023, 13:03
Но есть одна хитрая версия игры LAND
Ну честно сказать вот не знаю стоит-ли делать таблицу строк больше чем 288. юзабельных строк. На реальной машинке ведь не будет ну никак больше чем 288. А то что под ними пририсовывает - ну как-бы .. даже не знаю. Я могу зациклить их на начало, но это тоже вот ну зачем?
(и кстати да, твой эмулятор вполне пользуется спросом и нужен)

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

Alex_K
13.07.2023, 13:46
одна хитрая версия игры LAND,
Эта игра LAND перетащена с ДВК с КГД. Там 286 строк. Плюс ещё верхняя информационная строка на УКНЦ - плюс 12 строк. Итого 298. Но реальная машина показывает только 288.

BlaireCas
13.07.2023, 23:50
сильно увеличивать скорость вообще не надо
Добавил в меню "Вкл/Выкл" увеличения уровня и соответственно скорости. Дефолтно включен естественно. (К3 нажать, работает только в "стартовом меню").
Заодно чтобы подбодрить обновил в стартовом посте скриншот на EmuStudio. :) А мусор под экраном вычищать не буду уж извините.

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

Titus
14.07.2023, 11:12
Эта игра LAND перетащена с ДВК с КГД. Там 286 строк. Плюс ещё верхняя информационная строка на УКНЦ - плюс 12 строк. Итого 298. Но реальная машина показывает только 288.
Я знаю, сколько на реальной машине строк, тем более, что я реверсил чипы от УКНЦ)

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

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


А мусор под экраном вычищать не буду уж извините
Пффф. А чего там его вычищать-то? Его просто не надо делать. Практически ни в одной программе и игре на УКНЦ на моем эмуляторе там нет мусора, а у тебя есть)

BlaireCas
14.07.2023, 11:22
Его просто не надо делать.
Он там не делается специально. Но ладно, вот ну припер к стенке :) Хорошо забью туда пустые строки.
Но тогда вопрос - сколько дополнительных строк выводит EmuStudio?

UPD: можно не отвечать, пофиксил зациклив пустой строкой. проапдейтил первый пост, сейчас на EmuStudio вроде как окей :)

Alex_K
14.07.2023, 11:32
Он там не делается специально. Но ладно, вот ну припер к стенке Хорошо забью туда пустые строки.
Но тогда вопрос - сколько дополнительных строк выводит EmuStudio?
Ну если так хочется, то после 288 строк достаточно одну двухсловную запись, первое слово будет указывать на адрес пустой видеостроки, а адрес следующего элемента равен самому себе.

BlaireCas
14.07.2023, 14:02
Ну если так хочется, то после 288 строк достаточно одну двухсловную запись
У меня была идея вывести туда некую надпись мол EmuStudio Rulez! (а еще и скроллер можно было засунуть с рекламой BIL corp или прочими древними вещами) Но подумав решил не страдать ерундой :) Да конечно в цикле сделал на пустой адрес.

И вот кстати тоже момент. Как определить запущено на эмуляторе и на каком из наших двоих? Ну вроде пока эмуляцию бага реального ВМ2 не сделали, то-есть определить можно по этому. Далее как различить UKNCBTL или EmuStudio - ну вроде Никита недоделал момент когда VRAM банки в ПП отображаются на ПЗУ. То-есть он сделал, но чтение оттуда будет читать из VRAM (а в реальности читает из ПЗУ). Вот уж не знаю зачем определять где запущена программа, но .. вдруг захочется.

reddie
14.07.2023, 17:52
Отличная игрушка получается! Кто бы там что ни писал выше про кривой код - это профессиональные критики, а не игроки. Обычный пользователь не полезет в дебри кода косяки искать =)) Поэтому результат оцениваю строго положительно.