Салют, друзья! 💥
Некоторое время подумываю о создании новой платформы для демосцены. До вчерашнего дня я только размышлял об её особенностях, возможностях, продумывал заголовок (опциональный, но с кучей настроек), некоторые технические нюансы (организацию API, структуру памяти). И вот, наконец, вчера открыл Visual Studio, создал проект и написал немного кода🙂
💻 Ни для кого не секрет, что помимо аппаратных платформ существуют и искусственно созданные: PICO-8, TIC-80, недавно появившаяся MicroW8 и др.
Каждая платформа имеет ограничения: по разрешению экрана, набору цветов, возможностям воспроизведения звука, производительности, наконец. Ограничения — неотъемлемая часть демосцены. Однако даже мощнейший современный компьютер с видеокартой RTX 4090 тоже имеет ограничения, но конечно, другого уровня, нежели ретрокомпьютеры. Вместе с тем, смотреть 64K или 4K intro на шейдерах не менее интересно, чем демо/интро под ZX Spectrum, написанные на чистом ассемблере Z80, или интро под TIC-80 на Lua. Во всём есть свои фишки, своя романтика и свои челленджи.
Поскольку я любитель Newskool-платформ, ассемблера и Sizecoding'а, моя платформа ориентирована на полноцветный hi-res, максимальную скорость и нативный код x86 под Windows. А ещё я люблю многопоточность, и именно она легла с основу новой платформы.
👉 Минутка рекламы в тему: обязательно подписывайтесь на мой канал и чат о параллельном и асинхронном программировании, GPGPU и оптимизации.
Каковы особенности моей платформы?
🔹 Нативный исполняемый код x86. Интро пишется под процессор Intel IA-32 / AMD x86. Никакого байт-кода, никакого Lua, JavaScript, Python или GLSL. Только ассемблер, только хардкор!😁 И никаких тормозных DOSBox'ов, код запускается внутри процесса среды исполнения под Windows. Помимо всего прочего, вам доступны все прелести современных процессоров: 32-битная адресация, SIMD (вплоть до AVX-512) и прочие наборы инструкций. Возможно, позже будет поддержка 64-битного кода, но я не обещаю.
🔹 Опциональный заголовок. Да, это почти как COM-файл под DOS. Вам не нужно тратить драгоценные байты (десятки и сотни) на ненужную информацию о вашем интро. Заголовок, если он нужен, будет иметь разную длину в зависимости от тех данных, которые вы хотите там разместить.Вы даже можете спрятать заголовок в имя файла. Так что, под новую платформу вполне возможно создавать даже 32 или 64-байтные интро.
🔹 Среда исполнения с унифицированным API. Проблема DOS в том, что на работу вашего intro влияет множество внешних факторов, которые сложно (а иногда и невозможно) контролировать. Начиная от загруженных драйверов и резидентных программ, заканчивая особенностями реализации DOS и BIOS (в т.ч. различные номера видеорежимов VESA на каждой системе, разное состояние Unreal Mode и поддержки SSE). Кому-то наверняка это даже нравится, но лично я считаю это излишним неудобством. Если ваше аппаратное обеспечение не соответствует каким-то требованиям intro, среда исполненияPara\\e/ Para||elix выдаст соответствующее сообщение, в DOS же, скорее всего, система просто зависнет, либо intro будет глючить.
Некоторое время подумываю о создании новой платформы для демосцены. До вчерашнего дня я только размышлял об её особенностях, возможностях, продумывал заголовок (опциональный, но с кучей настроек), некоторые технические нюансы (организацию API, структуру памяти). И вот, наконец, вчера открыл Visual Studio, создал проект и написал немного кода
Каждая платформа имеет ограничения: по разрешению экрана, набору цветов, возможностям воспроизведения звука, производительности, наконец. Ограничения — неотъемлемая часть демосцены. Однако даже мощнейший современный компьютер с видеокартой RTX 4090 тоже имеет ограничения, но конечно, другого уровня, нежели ретрокомпьютеры. Вместе с тем, смотреть 64K или 4K intro на шейдерах не менее интересно, чем демо/интро под ZX Spectrum, написанные на чистом ассемблере Z80, или интро под TIC-80 на Lua. Во всём есть свои фишки, своя романтика и свои челленджи.
Поскольку я любитель Newskool-платформ, ассемблера и Sizecoding'а, моя платформа ориентирована на полноцветный hi-res, максимальную скорость и нативный код x86 под Windows. А ещё я люблю многопоточность, и именно она легла с основу новой платформы.
Каковы особенности моей платформы?
🔹 Нативный исполняемый код x86. Интро пишется под процессор Intel IA-32 / AMD x86. Никакого байт-кода, никакого Lua, JavaScript, Python или GLSL. Только ассемблер, только хардкор!
🔹 Опциональный заголовок. Да, это почти как COM-файл под DOS. Вам не нужно тратить драгоценные байты (десятки и сотни) на ненужную информацию о вашем интро. Заголовок, если он нужен, будет иметь разную длину в зависимости от тех данных, которые вы хотите там разместить.
🔹 Среда исполнения с унифицированным API. Проблема DOS в том, что на работу вашего intro влияет множество внешних факторов, которые сложно (а иногда и невозможно) контролировать. Начиная от загруженных драйверов и резидентных программ, заканчивая особенностями реализации DOS и BIOS (в т.ч. различные номера видеорежимов VESA на каждой системе, разное состояние Unreal Mode и поддержки SSE). Кому-то наверняка это даже нравится, но лично я считаю это излишним неудобством. Если ваше аппаратное обеспечение не соответствует каким-то требованиям intro, среда исполнения
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
🔹 Разнообразие видеорежимов, режимов воспроизведения звука. Вы можете установить практически любое разрешение экрана с нужной вам цветностью (даже аппаратно неподдерживаемое — в этом случае картинка будет натягиваться на стандартное разрешение). Генерация звука может осуществляться в отдельной callback-функции и выдавать как семплы в стиле bytebeat, так и использовать MIDI.
🔹 Вам доступно до 512 МБ1 ГБ оперативной памяти. Кроме того, память программы (код и данные) выровнена по границе 16 МБ, как и видеопамять, которая организована в виде массива идущих друг за другом пикселей (при этом каждая строка может быть дополнительно выровнена при необходимости).
🔹 Вишенка на торте: МНОГОПОТОЧНОСТЬ!!! Да, друзья, вы можете вызывать API-функции среды исполнения, которые в многопоточном режиме будут вызывать вашу callback-функцию отрисовки строк или даже отдельных пикселей (или групп пикселей по 2, 4, 8, 16, 32 или 64 шт для использования SIMD). Вы можете запросить вызов и любых других функций в многопоточном режиме, делать многопоточные циклы и пр. Разумеется, будут и барьеры и прочие средства синхронизации.
🔹 Различные мелочи вроде возможности остановить или перемотать intro, запустить с нужной секунды (удобно для отладки), завершить через нужное время (удобно для показа на пати зацикленных intro), замедлить/ускорить, воспроизвести задом наперёд (разумеется, для использования этих фишек intro должно быть специальным образом организовано). Расширенный функционал среды исполнения включается и отключается в конфиг-файле, который можно распространять вместе с правилами участия в компо (например, на нашем пати запрещено записывать заголовки в имена файлов, вызывать GDI-функции для рисования фигур, использовать более 64 Мб памяти и т.д.).
⚡️ Сейчас пишется самая-самая первая версия. Так сказать, MVP (минимально жизнеспособный продукт). Многого в ней не будет. Но в ней точно будет многопоточность и точно не будет заголовков исполняемых файлов intro. Я буду счастлив, если успею сделать её к Lovebyte Party 2023 (к февралю). К сожалению, дел всегда много, особенно под Новый Год, так что работать над платформой каждый день (и тем более по много часов) я не смогу. Но я буду стараться выделять на работу над платформой хоть какое-то время. И буду безмерно рад, если вы станете следить за ходом работы и поддерживать меня идеями, советами и реакциями 😉
🔹 Вам доступно до 512 МБ
🔹 Вишенка на торте: МНОГОПОТОЧНОСТЬ!!! Да, друзья, вы можете вызывать API-функции среды исполнения, которые в многопоточном режиме будут вызывать вашу callback-функцию отрисовки строк или даже отдельных пикселей (или групп пикселей по 2, 4, 8, 16, 32 или 64 шт для использования SIMD). Вы можете запросить вызов и любых других функций в многопоточном режиме, делать многопоточные циклы и пр. Разумеется, будут и барьеры и прочие средства синхронизации.
🔹 Различные мелочи вроде возможности остановить или перемотать intro, запустить с нужной секунды (удобно для отладки), завершить через нужное время (удобно для показа на пати зацикленных intro), замедлить/ускорить, воспроизвести задом наперёд (разумеется, для использования этих фишек intro должно быть специальным образом организовано). Расширенный функционал среды исполнения включается и отключается в конфиг-файле, который можно распространять вместе с правилами участия в компо (например, на нашем пати запрещено записывать заголовки в имена файлов, вызывать GDI-функции для рисования фигур, использовать более 64 Мб памяти и т.д.).
Please open Telegram to view this post
VIEW IN TELEGRAM
Продолжаю думать над организацией памяти.
Примерный Memory Map 32-битного процесса в Windows:
Хочу сделать так, чтобы интра начиналась с фиксированного адреса.
Скорее всего, это будет адрес
Если брать резерв доступной интре памяти в 1 ГБ для (включая сам код), то следующий свободный блок начнётся с адреса
Буферы под звук и пр. могут начинаться с любого адреса — это не шибко важно.
Теперь расскажу, зачем под API нужно аж 64-80 мегабайт. При старте интры регистр
В расширенной версии API с диапазоном в почти 256 адресов (позволяющей создавать соответственно около 256 функций) потребуется 80 МБ, т.к. 4-х цифр уже не хватит, нужно 5. Само собой, тут будет много пустых областей, которые не будут расходовать память. Ну и 1 ГБ + 256 МБ я выделять сразу не буду, достаточно только зарезервировать адресное пространство.
Примерный Memory Map 32-битного процесса в Windows:
0x00000000 - 0x0000FFFF
(64K) — резервная область (область нулевых указателей).0x00010000 - 0x7FFDFFFF
(почти 2 ГБ) — память, доступная процессу, включая DLL-ки в верхней части этой области.0x7FFE0000 - 0x7FFFFFFF
(128K) — системная область вперемешку с юзерской.0x80000000 - 0xBFFFFFFF
/ почти 0xFFFFFFFF
(1-2 ГБ) — память, доступная юзеру (соответственно в режиме PAE для 32-битной системы и в 64-битной системе), в 32-битной системе без PAE (или с отключенным битом 4G в PE недоступна).Хочу сделать так, чтобы интра начиналась с фиксированного адреса.
Скорее всего, это будет адрес
0x10000000
(256 МБ от начала), потому что мне нужно от 64 до 80 МБ на API (ниже объясню почему) + память для самой среды запуска + адрес красивый и удобный :))Если брать резерв доступной интре памяти в 1 ГБ для (включая сам код), то следующий свободный блок начнётся с адреса
0x50000000
. Здесь, собственно, может начинаться видеопамять. Даже при 8K-разрешении 8192*8192*32 bpp на это нужно не более 256 МБ, т.е. на 0x60000000
всё закончится. Под DLL-ки оставшегося пространства хватит с лихвой.Буферы под звук и пр. могут начинаться с любого адреса — это не шибко важно.
Теперь расскажу, зачем под API нужно аж 64-80 мегабайт. При старте интры регистр
ebp
будет указывать на область API-адресов: непосредственно по адресу ebp
будет находиться 2-байтный jmp short
(или 5-байтный jmp near
, а пока думаю как лучше сделать, тут есть некоторые нюансы) на обработчик API, который выполняет функцию по её номеру в регистре ah
, т.е. вызов API потребует всего 2 байта (call ebp
), не считая загрузки номера в ah
. По адресам [ebp-N]
(N = -128...0, кроме 2-5 номеров) будут находиться 4-байтные адреса обработчиков API-функций. Чтобы все адреса были корректными, они должны содержать разные (неповторяющиеся) сочетания из 4-х цифр (к примеру, в 8 числах 1,1,1,1,2,1,1,3
у нас 5 валидных адресов: 0x01010101
, 0x02010101
, 0x01020101
, 0x01010201
, 0x03010102
). Для 128 таких комбинаций диапазон адресов будет около 64 МБ. И такая организация позволит делать вызовы API-функций 3-мя байтами (call dword [ebp-N]
) :)В расширенной версии API с диапазоном в почти 256 адресов (позволяющей создавать соответственно около 256 функций) потребуется 80 МБ, т.к. 4-х цифр уже не хватит, нужно 5. Само собой, тут будет много пустых областей, которые не будут расходовать память. Ну и 1 ГБ + 256 МБ я выделять сразу не буду, достаточно только зарезервировать адресное пространство.
❤1