(бухай): программируй
148 subscribers
465 photos
96 videos
3 files
65 links
Мысли, дегустация и код
Download Telegram
И это я не говорю о том, что программа на бейсике весит 28 байт, а на ассемблере - 27, а работает в сотни раз быстрее⌨️
1
This media is not supported in your browser
VIEW IN TELEGRAM
2😁1
Тут даже комментировать нечего )
🔥3
This media is not supported in your browser
VIEW IN TELEGRAM
Я победил ограничение перемещения спрайтов в Commodore. Как я говорил в статье, движение спрайта по горизонтали ограничено 256 координатами, так как регистр памяти, отвечающий за это, может принимать только значения от 0 до 255. При этом, экран то у нас целых 320 пикселя в ширину.
Для этого разработчики придумали так называемый "старший бит" - это бит (для каждого спрайта свой) в отдельном регистре, который, если принимает значение 1, позволяет перемещать спрайт за пределы 255-ой координаты0️⃣0️⃣0️⃣0️⃣0️⃣0️⃣0️⃣1️⃣
🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
Но, программируя спрайты, да и вообще любую графику на этом компьютере, можно не учесть одну небольшую деталь, и получится примерно следующее
Это происходит, потому что в старые времена телевизоры выводили картинку на экран построчно, линия за линией. И видеочип Commodore следует этим правилам.
Проблема возникает, когда нужно переместить спрайт на экране, а линия, например, уже отрисовала половину изображения. Спрайт перемещается дальше, и отрисовка второй половины изображения происходит уже в другом месте.
Примерно так
Но так как видеочип в Commodore обновляет экран 60 (или 50, в зависимости от региона) раз в секунду, то каждая новая линия спрайта будет отрисована не в том месте, где надо. Из-за этого и возникает такой эффект
Решить это можно очень просто. Надо обратиться к регистру памяти, в котором указано, какую линию экрана рисует компьютер. Спрайт можно двигать только в том случае, если видеочип уже полностью обновил экран и вернулся в нулевую строку. Делается это двумя строчками кода:
Начинаем с лейбла loop. команда lda $d012 загружает из этого регистра номер текущей линии отрисовки. А команда bne loop сравнивает номер линии с нулем. Если номер больше нуля, то проверяем заново.
Покопавшись в старых запасах, обнаружил вот такое сокровище. Правда диск не в лучшем состоянии, надеюсь, что получится его запустить
Заказал вот такую штуку для Commodore, и вроде как она ожидает меня в отделении почты.
И это очень полезная вещь. Сейчас у меня есть только кассетный магнитофон, с помощью которого я могу считывать программы на кассетах. Проблема в том, что на кассеты эти программы надо как-то записать. Для этого нужна кассетная дека или магнитофон с возможностью записи. Это все сложно и дорого.
А дисководы для дискет стоят от 8 тысяч рублей, и опять же, встает вопрос о том, как на эти дискеты записать программы.

Эта плата называется SD2IEC, и она эмулирует дисковод. В нее вставляется сд-карта с записанными программами, а Коммодор считывает их как с дискеты.

Но более подробно только вечером)
👍4
Ассемблер продолжает меня вымучивать. Сегодня я наконец разобрался, как сложить два числа. И это оказалось не так просто.
Так как архитектура Commodore 8-ми битная, то один регистр памяти может принимать значения от 0 до 255. И сложить, например, 10 и 50 не сложно. Надо воспользоваться следующими командами:
lda #10 // загружаем в регистр А значение 10
adc #50 // складываем с 60
sta result // помещаем новое значение в нужный регистр памяти.
Но что, если надо сложить числа больше 255-ти. Например, 1024 и 306.
В этом случае эти числа 16-ти битные, и каждое число занимает уже не один байт памяти, а два (16-ти битные числа могут принимать значения от 0 до 65 535).

Число 1024 в шестнадцатеричной системе - это 0400, а 306 - 0132. В памяти компьютера они занимают по два байта: 00 04 в первом случае, и 32 01 во втором.
Да, в Commodore 64 обратная запись, поэтому числа будут перевернуты.
И теперь осталось их сложить.
Вот весь код операции сложения. Казалось бы, что может быть проще. Но не на ассемблере.
Итак, первое число хранится в регистрах $fb-fc (00 40), а второе - в регистрах $fd-fe (32 01). Ради удобства я их обозвал в соответствии с назначением (low byte, то есть конец числа, и high byte, то есть начало).
В блоке init мы просто кладем в нужные регистры два слагаемых, здесь ничего интересного, и об этом я уже рассказывал.

А вот потом начинается магия.

В процессоре Commodore есть специальный регистр, который содержит разные флаги. Один из таких флагов называется Carry, и он переключается с 0 на 1, когда какое-нибудь значение после какой-либо операции перескочило 255. Этот флаг очень важен при сложении и вычитании.
Поэтому первым делом надо этот флаг очистить командой clc (clear carry).
Потом мы загружаем в регистр A вторую половину первого числа и прибавляем к ней вторую половину второго числа. Если эти два числа в сумме дают значение больше 255, то флаг carry становится равен единице, а регистр А перескакивает значение 255, обнуляется и к нулю добавляется недостающая разница, которую надо поместить в регистр результата (lda n1low, adc n2low, sta result).