Вход

Просмотр полной версии : Christmas Tree Event - рисуем елочку =)



reddie
26.12.2021, 15:28
К сожалению, узнал об этом конкурсе только вчера от Manwe в этой темке https://zx-pk.ru/threads/34009-bk-bystree-vsekh.html?p=1140654&viewfull=1#post1140654
В посте Manwe ссылка на результаты (последняя колонка - размер в байтах), ссылка на сам эвент (описание): http://logiker.com/Vintage-Computing-Christmas-Challenge-2021
Спектрум, как ни странно, глубоко в эээ середине, непорядок. Решил помучать свои мозги, заранее условившись не смотреть готовые решения вообще, для любой платформы.
В правилах ничего не сказано про запреты на использование особенностей компа, поэтому код использует процедуру печати ПЗУ, а также некоторые трюки для сокращения объема:

- при запуске кода из Бейсика регистровая пара BC равняется адресу запуска. Используем, ибо нефиг
- сам адрес запуска, т.е. пара BC, указывает на массив данных для вывода строк
- в то же время, адрес кода (данных) рассчитан так, чтобы регистр C пригодился как счетчик строк, а регистр B экономит один байт при подсчете координат вывода
- вывод идет в служебный экран, это фича Спектрум-Бейсика при запуске кодов. Экономим память, убирая инициализацию основного потока (экрана)
- в условиях не сказано, что код обязан возвращать управление, поэтому для предотвращения очистки служебного экрана прога "вешается", дабы не выходить в Бейсик
- адрес запуска не совпадает с адресом загрузки блока, что тоже не является обязательным
- исходя из пункта один, корректный запуск возможен только из Бейсика. Можно просто запустить файл TRD в эмуляторе, на диске уже записан "boot" для загрузки и запуска кода

Размер моей версии - 35 байт. 14 байт данных строк "елочки" плюс 21 байт программы, это 15 команд Z80.
Однако ниже по топику char указал, как сократить программу еще на три байта, за что заслуживает почетной медали ;)
Итоговый размер (пока?) - 32 байта. Код сократился до 13 команд и занимает 18 байт, плюс те же 14 байт данных. Улучшенная версия приложена.
Конечно, конкурс довольно специфический, и является неким писькомерством, но потренировать мозги было интересно.
Версия для ПК8000 от Ivagor, 42 байта: https://zx-pk.ru/threads/8378-pk8000-soft-staryj-i-novyj.html?p=1140692&viewfull=1#post1140692 но и там есть подвижки в сторону уменьшения.

76748

76755

https://i.ibb.co/W5Y5Dh2/Christmas-Tree-screen.jpg (https://ibb.co/Kh3hNPr)

Manwe
26.12.2021, 15:48
Отличный результат!
А о конкурсе мы сами узнали в последний день – каждый из трёх участников на БК 0010 писал свою программу за один вечер.
Так-то понятно, что у 8-битного компьютера больше шансов выйти вперёд, чем у 16-битного. Поэтому меня и удивило, что БК 0010 смог обойти только C64 в этом конкурсе.

litwr
26.12.2021, 19:16
Отличный результат!
А о конкурсе мы сами узнали в последний день – каждый из трёх участников на БК 0010 писал свою программу за один вечер.
Так-то понятно, что у 8-битного компьютера больше шансов выйти вперёд, чем у 16-битного. Поэтому меня и удивило, что БК 0010 смог обойти только C64 в этом конкурсе.

Там ещё Коммодор+4 впереди, а это не 64; На самом деле, думаю там практически любая машина с 6502 могла запустить примерно тот же код, что и Коммодор 64 или +4.

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


К сожалению, узнал об этом конкурсе только вчера от Manwe в этой темке https://zx-pk.ru/threads/34009-bk-bystree-vsekh.html?p=1140654&viewfull=1#post1140654
В посте Manwe ссылка на результаты (последняя колонка - размер в байтах), ссылка на сам эвент (описание): http://logiker.com/Vintage-Computing-Christmas-Challenge-2021
Спектрум, как ни странно, глубоко в эээ середине, непорядок. Решил помучать свои мозги, заранее условившись не смотреть готовые решения вообще, для любой платформы.
В правилах ничего не сказано про запреты на использование особенностей компа, поэтому код использует процедуру печати ПЗУ, а также некоторые трюки для сокращения объема:

- при запуске кода из Бейсика регистровая пара BC равняется адресу запуска. Используем, ибо нефиг
- сам адрес запуска, т.е. пара BC, указывает на массив данных для вывода строк
- в то же время, адрес кода (данных) рассчитан так, чтобы регистр C пригодился как счетчик строк, а регистр B экономит один байт при подсчете координат вывода
- вывод идет в служебный экран, это фича Спектрум-Бейсика при запуске кодов. Экономим память, убирая инициализацию основного потока (экрана)
- в условиях не сказано, что код обязан возвращать управление, поэтому для предотвращения очистки служебного экрана прога "вешается", дабы не выходить в Бейсик
- адрес запуска не совпадает с адресом загрузки блока, что тоже не является обязательным
- исходя из пункта один, корректный запуск возможен только из Бейсика. Можно просто запустить файл TRD в эмуляторе, на диске уже записан "boot" для загрузки и запуска кода

Итоговый размер кода - 35 байт. 14 байт данных строк "елочки" плюс 21 байт программы, это 15 команд Z80. Спектрум рулит, просто нужно творчески подходить к делу.
Конечно, конкурс довольно специфический, и является неким писькомерством, но потренировать мозги было интересно.
Версия для ПК8000 от Ivagor, 42 байта: https://zx-pk.ru/threads/8378-pk8000-soft-staryj-i-novyj.html?p=1140692&viewfull=1#post1140692

76748

https://i.ibb.co/W5Y5Dh2/Christmas-Tree-screen.jpg (https://ibb.co/Kh3hNPr)

Ну и ну! Надо было спектрумистов тоже приглашать... Но это уже было бы какое-то вторжение. :)

char
26.12.2021, 22:49
достаточно RRA вместо SRA A ;)

reddie
26.12.2021, 23:20
достаточно RRA вместо SRA A
Если после RST 16 флаг переноса всегда устанавливается - то да. Настолько глубоко в дебри ПЗУ не залазил :D
Думал еще поиграться с вариантов с циклами, но вряд ли он окажется короче. Потом как-нибудь попробую.
Кстати, организатор конкурса ответил мне на почту, обещал выложить и мой вариант. Пока 35 байт это рекорд, но...
Цитируя его: программа под ДОС (MS-DOS, видимо) на данный момент весит 36 байт, но ребята работают над этим =)

char
26.12.2021, 23:30
еще можно перед print убрать одну RST 16 и в таблице все значения уменьшить на 1 ;)

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

а можно и два rst 16 убрать, 32 байта



defb -3-2,-3-2,-23-2,-17-2,-11-2,-5-2,-15-2,-11-2,-7-2,-3-2,-7-2,-5-2,-3-2,-1-2

start
dec c
jr z,$ ;stop when finished

ld a,23 ;set coords via ROM procedure
rst 16
ld a,(bc) ;line len in negative format
ld e,a
rra
sub b ;centering
print
rst 16
ld a,"*"
inc e
jr nz,print
jr start
end

reddie
26.12.2021, 23:55
еще можно перед print убрать одну RST 16
Да, команде TAB второй байт, в общем-то, пофиг, можно и звездочку вместо него скормить. И после RST 16 действительно флаг выставляется как надо.
Итого ужали еще на три байта. Что лишний раз подтверждает истинность фразы "любую программу можно сократить минимум еще на байт" =))
Но для этого нужно время и желание, а эти ресурсы не бесконечны. Хотя теперь код близок к идеалу. по-моему.

Reobne
27.12.2021, 00:56
На спектруме, вообще не нужна программа, чтобы рисовать такую ёлку. Просто надо написать одну строчку.

reddie
27.12.2021, 01:03
Вот только длина этой бейсик-программы в разы больше ассемблерной, а суть конкурса была именно в минимизации.

Reobne
27.12.2021, 01:10
Программы? Ноль байтов.
Это не программа, это команда. Составная. :)

char
27.12.2021, 02:09
кстати, если не сильно центрировать, можно и в 30 байт сделать :)



org -14*256+1+#10000

x equ 3
defb -3-x,-3-x,-23-x,-17-x,-11-x,-5-x,-15-x,-11-x,-7-x,-3-x,-7-x,-5-x,-3-x,-1-x

start
ld a,23 ;set coords via ROM procedure
rst 16

dec c
jr z,$ ;stop when finished
; ret z

ld a,(bc) ;line len in negative format
ld e,a
print
inc e
jr z,start

rra
sub b ;centering
rst 16

jr print


еще, скажем, можно подумать насчет ret z, с вызовом программы через print usr ...

reddie
27.12.2021, 13:27
если не сильно центрировать, можно и в 30 байт сделать
Да, рыл в этом направлении, но в условиях указано про центровку. Так что делал "как положено"
Считаю, что дальнейшая оптимизация, если и возможна, то за счёт игры входными данными.
Самое сложным было убедить "буржуя", что бейсик-загрузчик не даёт каких-либо преимуществ.
В том смысле, что лишь загружает и запускает код, и не содержит скрытых доп. данных.
По сути, он и не нужен, в описании чётко указано, с какого адреса запускать код.
Вся проблема лишь в несовпадении адресов загрузки и запуска, как "обычно" делается.
В принципе, подобрав адрес запуска и переместив данные в конец, можно уйти от этого, но выгоды не будет.

reddie
27.12.2021, 16:25
еще, скажем, можно подумать насчет ret z, с вызовом программы через print usr ...
Да, только вместо Print поставить оператор Pause =) Собственно, почти так и делал в процессе отладки кода, но даже не помышлял об использовании такого варианта в готовой программе, поскольку считаю это помощью со стороны Бейсика: мы как бы заменяем кусочек кода бейсик-оператором.
При отладке вызывал код конструкцией Randomize usr 61455: Pause 0 - можно так и оставить, но вход и выход в машкоды передаёт параметр через рег. пару BC, а она перед выходом равна 61440, то есть при вызове через Pause usr 61455 получится команда Pause 61440 - бесконечная пауза, по сути. Условно программа сократится ещё на байт, но почему б тогда и ещё чего-нибудь в бейсик-часть не напихать? :D