Почему этим должна заниматься видеокарта?
Вид для печати
Почему этим должна заниматься видеокарта?
Компрессия может понадобиться чтобы игра влезла на диск TR-DOS. Хотя спрайты займут не более 512К. На код останется не более 640 - 512 = 128К. Пока хватает памяти в этих пределах - можно и не сжимать.
Подскажите как продемонстрировать скорость/возможности видеокарты - нужен тест.
как реализована совместимость с оригинальными спеками ?
Вы имеете ввиду аппаратное подключение к краевому разъему или времянки оригинального Спектрума ?
Если аппаратно, то видеокарта планируется в слот ZX-BUS, на котором должна быть частота 14 МГц. А у оригинального Спека и ZXEvо, как тут написали, этого нет. Можно сделать дополнительный генератор 14 или 56 МГц на плате видеокарты.
Для реализации времянок оригинального Спектрума, как в LENINGRAD-2012, потребуется подача с видеокарты через ZX-BUS нового тактового сигнала на Z80. Для этого на плате предусмотрена перемычка. Если не подавать, то тактовые на Z80 будут идти с материнской платы.
Также предусмотрены вилки для подключения тумблеров или перемычек для управления следующими режимами:
1. CONTENDED MEMORY - ON/OFF
2. PORT FF - 0N/OFF
3. SCAN - ZX SPECTRUM (50 Hz) / PENTAGON-128 (48 Hz)
Можешь сделать заготовку спецификации и положить ее в первое сообщение? А то вычитывать весь тред с целью понять что оно вообще должно уметь, утомительно. Да и мысли менялись уже. Для начала тест №1:
1. Определение наличия карточки.
2. Включение дополнительного видеорежима.
3. Очистка указанным цветом (из палитры?) и отображение нулевого экрана.
4. Установка цвета бордера (из палитры?).
5. Очистка и отображение первого экрана.
6. Возвращение режима 6912.
Проверяется:
1. Отправка команд в карточку и ожидание их приема.
2. Включение и выключение видеорежима.
3. Очистка экранной памяти заданным цветом.
4. Возможность показа обоих двух экранов.
5. Возврат к режиму 6912.
6. Работа бордера.
7. Детект карточки.
Отсебятина тут:
1. Очистка цветом - это я сам придумал, но видеокарта ведь все равно должна показывать какой-то цвет на месте, где нет тайла фона и точек спрайта.
2. Возврат в 6912 - это все-таки надо. К примеру, товарищи, программирующие на реале, это сильно заценят.
3. Детект карточки. Все-таки, хорошо бы, чтобы он был.
Вопросов по реализации также хватает:
1. Как передаются команды в карточку?
2. Как пользоваться переключением экранов? Классика, 7ffd?
3. Как задавать цвет бордюра?
4. Какая палитра будет после сброса карты? (предлагается - стандартная спековская, отображенная на все цвета с повторением через 16).
5. Как узнать когда команда выполнилась и выполнилась ли она.
6. Как узнать если карточка вообще?
7. Какие видеорежимы и с какой глубиной цвета будут реализованы? Будет ли поллитра.
P.S. Есть столь же детальные задумки для еще пары тестов. Первая пока на пробу.
Для управления видеокартой «METEOR-2013», которая предназначена для ускорения графики в
ZX SPECTRUM-совместимых компьютерах, разработаны простые и эффективные команды типа PRINT, PLOT, DRAW, POKE, PAPER, INK, BORDER, похожие по назначению на соответствующие команды BASICa.
Для указания места вывода на экран используются координаты X и Y. Спрайты загружаются
в память видеокарты и не занимают места в основной памяти компьютера. Во время игры с помощью соответствующих команд видеокарты спрайты копируются по номерам в указанные координаты экрана.
Спрайты можно накладывать друг на друга с использованием прозрачного цвета фона спрайта.
В одной игре можно использовать спрайты нескольких размеров. Имеется возможность задавать границы окна для печати спрайтов. При печати части спрайтов, выходящие за границы окна, обрезаются. Поверх спрайтов можно рисовать нужным цветом точками и линиями.
Параметры новых режимов - 256х192 и 320х240 точек, 255 цветов с палитрой + «прозрачный» цвет.
Два экрана - теневой и отображаемый. Координаты (0,0) в левом верхнем углу экрана.
Палитра - 3х6 бит (как BMP 256), размещена во внутренней памяти FPGA 256 * 18 бит.
Для команд работы с видеокартой «METEOR-2013» выделены адреса 5800H-58FFH в области атрибутов стандартного экрана ZX-SPECTRUM. Команда определяется по адресу, а данные, которые записывает Z80 по этому адресу, используются как параметры для этой команды. Команды в видеокарте накапливаются в буфере для исключения ожидания Z80 при выполнении сложных команд. Видеокарта затем выполняет накопленные команды из буфера.
История оптимизации команд для работы с видеокартой:
Код:130714-05 - глобальная оптимизация команд с целью ускорения заполнения экрана спрайтами
130711-01 - убраны команды задания границ копирования части спрайтов. Добавлены команды рисования точки
130707-01 - добавлены команды управления курсором.
130630-01 - координаты курсора на экране теперь могут быть отрицательными для автоматического обрезания спрайта при выходе за границу экрана. Координата Y теперь тоже состоит из старшего и младшего байта.
130629-02 - вместо команды установки младшего байта номера спрайта с копированием спрайта добавлены команты PRINT_AUTOINC_X, PRINT_AUTOINC_Y для печати спрайта с автоинкрементом координат.
130629-01 - Уточнение имен команд
130628 - В ходе написания примера работы с видеокартой уточнены названия команд и т.п. Также удобнее по одному адресу записывать номер команды, а по другому - значение этого параметра. Потом ПЛИС сможет записывать оба байта одним словом в буфер FIFO.
130624 - добавлен адрес спрайта с номером 0
130622 - вместо HL для адресации команд и данных теперь применятеся индексная адресация с IY
130621 - предложен буфер команд в FPGA для того чтобы не нужно было ждать готовности видеокарты. Запись команд и данных по адресу в HL.
Так тоже можно. Главное, чтобы запись была подряд по указанному адресу в ОЗУ три раза подряд и с нужными значениями.
Я прикинул, что удобнее задать как у вас базовый адрес команд в IY, а для записи команд и параметров использовать индексную адресацию. Это освободит регистровую пару HL для более важных операций в игре.
Обновил систему команд для индексной адресации -- http://www.zx.pk.ru/showpost.php?p=610738&postcount=50
================================================== ==============
ПРИНЦИПЫ ПЕРЕКЛЮЧЕНИЯ ЭКРАНОВ.
В видеокарте предусмотрено два экрана - отображаемый и рабочий.
Команда выбора экрана:
LD (IY+1), NUM_SCR
LD (IY+1), число (обычно поочередно, каждое прерывание менять 1 и 2)
Бит D0 числа показывает видеокарте какой экран отображать на TV.
Бит D1 числа показывает видеокарте какой экран рабочий.
Текущее состояние нужно хранить в одной из ячеек ОЗУ. Каждое прерываение инвертировать два младших бита, сохранять новое значение и отправлять в видеокарту команду выбора экрана.
Теоретически, можно сделать установку так, что редактируется и отображается один и тот же экран. Тогда его не надо будет переключать. Чтобы для рисования изображения без мельканий с использований только одного экрана было достаточно много времени желательно изменить положение INT. Предлагается в новых режимах сигнал INT формировать в момент сразу после отображения правой нижней точки экрана. Это позволит построить новый экран пока на TV отображается кадровый BORDER.
карта клевая, только есть минус - спек получается нелепым довеском к ней, так как её вычислительных мозностей и ресурсов в принципе хватит что бы подрубить джостик и сделать денди как я понимаю
Т.е. например, чтобы установить размер спрайта по горизонтали 16 точек,
нужно сделать так:
LD (IY+1), SIZE_X
LD (IY+1), 16
А само значение константы SIZE_X какое ?
---------- Post added at 17:21 ---------- Previous post was at 17:19 ----------
Это мне такое sdcc сгенерировал с IY.
А вообще, тут уж как программер захочет, хоть через HL, хоть через IY.
---------- Post added at 17:25 ---------- Previous post was at 17:21 ----------
А длина его какая ?
Он может переполниться ?
Опытного образца пока нет, но детали для него уже выбраны и заказаны.
Блок-схема видеокарты "METEOR-2013"
http://s61.radikal.ru/i172/1306/be/12bca1b9f08at.jpg
---------- Post added at 20:21 ---------- Previous post was at 20:17 ----------
Когда интерфейс будет проработан достаточно оптимально - перепишем все команды и пронумеруем от 0 до N.
Сколько влезет в FPGA. В обычных случаях Z80 не будет успевать перегружать FPGA.Цитата:
А длина его какая ?
Он может переполниться ?
zst, по схеме:
Предлагаю поставить генератор на одной 3.3в м/с вместо 555LN1+кварц.
Сигналы /OE на м/с памяти, возможно, не нужны - при понижении WE вывод автоматически отключается, а шины у памятей отдельная и мешать другим ус-вам не будут.
vlad, в ipvc нет слоев. Слои я отдельно пробовал делать. Концепция похожая, да.
IanPo, так у тебя уже все вроде здесь IPVC - графический контроллер для ZX-BUS получилось, у zst вроде как, такая же концепция вырисовывается?
Так может получится доделать начатое?
zst раз уж решил взять CycloneII EP2C5Q208 то надеюсь, что будет возможность на будущее установить EP2C8Q208?
На мой взгляд, лучше поставить 3-ри SRAM 512K x 8бит вместо двух по 16бит, скорости и так хватит для 256 цветов, а вот возможностей в разы больше появится (вместо 3-ей SRAM возможно лучше поставить SDRAM для подкачки видео строк или использовать как буфер для различного вида видео данных).
Попробовал сделать пробные наброски схемы на EP4CE6E22 + 2-ве SRAM 512Kx8 в связке с EPM3064AT100. Пока вроде все получилось.
При разработке ReVerSE II наткнулся на эти статьи, может пригодятся:
Генерация видео сигнала "Generating NTSC composite video with an FPGA and two resistors"
Генерация аудио сигнала "PWM (Pulse Width Modulation)"
HDMI "HDMI Output"
Всё таки думаю,
что в обычной программе, спрайты будут самых разных размеров,
(т.е. по номеру спрайта уже нельзя будет вычислить, его адрес )
поэтому тут нужен просто 3-байтовый адрес спрайт-памяти.
Планируете ли выложить все фалы проекта (или некоторые части) в открытый доступ ?
А чем такой генератор лучше ? И какую лучше частоту: 14, 56, 84 или какую другую ? К какому входу FPGA лучше подключать? Вообще-то планировалось брать 14 МГц с материнской платы компьютера. Но у некоторых компьютеров ее нет на разъеме.
Только если останется 6 лишних выводов.
Пока от лишних наворотов я отказался. Цель - максимально ускорить работу копирования спрайтов в область экрана.Цитата:
На мой взгляд, лучше поставить 3-ри SRAM 512K x 8бит вместо двух по 16бит, скорости и так хватит для 256 цветов, а вот возможностей в разы больше появится (вместо 3-ей SRAM возможно лучше поставить SDRAM для подкачки видео строк или использовать как буфер для различного вида видео данных).
Хорошо бы пока сделать новый графический режим в соответствии с указанным набором команд для тех компьютеров на FPGA, где это возможно - Speccy2010 и ReVerSE. Как вы считаете - это возможно ?Цитата:
Попробовал сделать пробные наброски схемы на EP4CE6E22 + 2-ве SRAM 512Kx8 в связке с EPM3064AT100. Пока вроде все получилось.
При разработке ReVerSE II
Спасибо. Хорошо бы почитать теорию, по видеоролику догадаться трудновато. Думаю, раз есть FPGA, может предусмотреть переключаемый видеовыход, как в Speccy2010 - SCART/VGA/S-VIDEO/COMPOSITE/HDMI ? Хотя бы предусмотреть на будущее возможность подпайки через разъем дополнительных разъемов.Цитата:
наткнулся на эти статьи, может пригодятся:
Генерация видео сигнала "Generating NTSC composite video with an FPGA and two resistors"
Генерация аудио сигнала "PWM (Pulse Width Modulation)"
HDMI "HDMI Output"
Может лучше стандартизировать размер для хранения спрайтов 16 х 16 точек ? Тогда рассчитывать адрес в FPGA проще. Указанием начальной и конечной строки/столбца спрайта можно уменьшать до нужного размера. А если нужно изобразить больший объект - то составлять их из нескольких спрайтов. Лишние пикселы закрашивать прозрачным цветом.
Можно будет выложить исходники прошивки в этой теме или на GOOGLECODE.Цитата:
Планируете ли выложить все фалы проекта (или некоторые части) в открытый доступ ?
Может хранить спрайты одинаковых размеров в наборах до 256 спрайтов в наборе ? Тогда на каждый набор нужно видеокарте указывать размеры спрайта и количество спрайтов в наборе. Возможно также начальный адрес каждого набора. Тогда при копировании на экран достаточно будет указать номер набора и номер спрайта. Остальные данные по началу блока и размерам спрайта указать при загрузке.
Возможно FPGA сможет сама вычислять начала каждого спрайта по номеру набора и спрайта. Тогда нужно спроектировать достаточное количество наборов и выделить для этого соответствующие команды и параметры.
Alex Rider, если спрайты разного размера (пуля и танк, например), то надо иметь таблицу адресов начал спрайтов.
zst, генератор просто меньше по габаритам, меньше элементов. Если будет генерация от ZXBUS, то его вообще можно не ставить (на выбор юзера). 14 МГц достаточно, подавать на PLL вход Циклона(можно посмотреть в даташите или Квартусе). С помощью ФАПЧ можно получить 56 МГц или 84.
Сделай пока возможность его установки. А какой именно частоты зависит от того какие видео режимы планируешь, экспериментально можешь попробовать подобрать в MegaWizard (ALTPLL).
Должны остаться, :) иначе не будет куда развивать конфигурацию.
Наворотами это думаю назвать сложно, корки контроллера SDRAM есть. Перенос данных от спека в видео ускоритель возможно, при наличии простого DMA на счетчиках.
Все закладывать не имеет смысла, т.к. реально использоваться будет всего один видео выход. Но как базовый, я бы распаял VGA, остальное пусть подрубается в интерфейс.
Возможно, но на данных бордах есть ряд архитектурных ограничений.
Эм... А вот я не пойму ни разу. А нельзя ли разве просто сначала грузить спрайты разных размеров вперемешку, а потом выводить их по номеру (возможно, 2-хбайтному)? И не заморачиваться наборами - наборы не нужны при программировании со стороны Спектрума.
Вот это не надо совсем. Спрайты должны быть произвольного размера (ну да, с каким-то разумным верхним ограничением). Потому что железка на карточке в 100500 раз мощнее Z80, а вы хотите на Z80 переложить вот эту вот аппликацию, склеивание спрайтов из кусков. Да еще и проверку того, чтобы вышедшие за пределы экрана куски с другой стороны не поперли. Сделайте простую для программистов штуку - это сильно повысит шансы того, что кто-то что-то под нее напишет.
upd: а номер спрайта обязан быть 2-х байтным. Потому что первым делом я бы загрузил в видеокарту 256 спрайтов букв.
Не, это уже лишнее.
Вот сейчас у вас, по проекту, это нормальный классический блитер.
Копирующий спрайты размером до 255x255.
Деление же на блоки по 16x16, просто надуманный момент.
Незачем усложнять жизнь программеру и заставлять его составлять объект из неких кусков 16x16.
Вот каких размеров спрайт нужен, вот таким он и будет.
Ну и нужно сделать, чтобы можно было задавать адрес спрайта, в двух вариантах:
- по 3-ёх байтовому адресу в спрайт памяти
- по 2-ух байтовому номеру (если кодер очень хочет сэкономить)
Т.е. какой именно вариант будет удобен кодеру, такой он и и будет использовать.
---------- Post added at 22:59 ---------- Previous post was at 22:46 ----------
Верно IanPo говорит.
Согласен, нужно предоставить программисту возможность использовать спрайты разных размеров. Для этого я и предложил идею наборов. Их еще можно назвать банками, блоками и т.п. Важно то, что в банке спрайты одинакового размера. Для простоты нумерации одним байтом количество спрайтов в банке может быть от 1 до 256. Это обеспечит легкость указания спрайта одним байтом.
Например шрифт в кодировке WINDOWS-1251. Рисуем 256 символов размером 8 х 8 точек или другого размера. Это будет банк спрайтов номер 1. Чтобы изобразить текст сначал выбираем банк спрайтов номер 1 с символами. Потом уже используем однобайтный номер спрайта/ символа в банке. Мне кажется это проще, чем каждый раз указывать по два байта.
Второй банк спрайтов может содержать тайлы травы, деревьев, земли и т.п. Он уже может содержать от 1 до 256 спрайтов размером, например, 12 х 12 точек. Это будет банк спрайтов номер 2. Тогда для изображения фона нужно установить текущим банк номер 2 и уже работать с однобайтовым номером спрайта. Это тоже проще, чем каждый раз писать по два байта.
Фактически, старший байт номера спрайта - это номер банка. Банков спрайтов может быть, например, 16. Один для букв, другой для фона, третий для главного героя, четвертый - враги, пятый - пули, шестой взрывы и т.п. Каждый банк нужно описать следующими параметрами: адрес начала, размер спрайта по-горизонтали, размер спрайта по-вертикали. Не обязательно в банке рисовать все 256 спрайтов - только необходимое количество. Адрес следующего банка указывать на следующий байт после последнего байта предыдущего банка.
Таблица смещений спрайтов не обязательна ни в каком случае. В карточку я могу загрузить спрайты известным в известном мне порядке и рисовать их на экране по номеру - это удобно, исключает указательную арифметику в памяти видеокарты. Оставить прямую адресацию в видеократе стоит, да. Даже без видеокарты при выводе на экран 6912 можно обойтись без таблицы смещений спрайтов если хранить перед каждым спрайтом его размеры.
---------- Post added at 05:22 ---------- Previous post was at 05:19 ----------
Так можно, да. Фактически, номер спрайта всен равно останется 2-хбайтным, только нумерация не сквозная. А как теперь сопоставить загруженный в карточку спрайт и его номер?
Смещение для каждого спрайта указывать не надо - только адрес начала банка. Это можно сделать при загрузке спрайтов в видеокарту.На мой взгляд, удобнее хранить спрайты одинакового размера в одном банке. Это позволит видеокарточке самой рассчитывать адрес начала нужного спрайта по номеру. Для этого видеокарта возьмет адрес начала банка и прибавит к нему смещение (номер спрайта * ширина спрайта * высота спрайта). Программисту остается передать видеокарте номер банка и номер спрайта в этом банке.Цитата:
Так можно, да. Фактически, номер спрайта всен равно останется 2-хбайтным, только нумерация не сквозная. А как теперь сопоставить загруженный в карточку спрайт и его номер?
Вопрос к программистам - что представляет из себя карта уровня для игр типа R-TYPE на логическом уровне ? Достаточно ли 256 спрайтов для такой игры ? Или нужно несколько банков спрайтов по 256 ?
Да, нормальная идея.
Только, оставить выбор за кодером, какой метод использовать,
описанные вами банки или
3-ёх байтовый адрес.
Т.е. нужно реализовать в карте оба метода.
(начать с более простого)
---------- Post added at 15:11 ---------- Previous post was at 14:59 ----------
Номер спрайта, можно сделать 2 байтовым.
Но, по умолчанию, старший байт равен нулю.
Тогда, кодер может установить:
- только младший байт номера спрайта
(если 256 номеров спрайтов достаточно)
или
- младший и старший байты номера спрайта
(если 256 номеров спрайтов не достаточно)
---------- Post added at 15:15 ---------- Previous post was at 15:11 ----------
Вот, по предложенному мной простому методу,
если 256 не достаточно,
то кодер просто будет юзать 2-ух байтовый номер спрайта.
Вы согласны, что спрайты в банке должны быть одинакового размера ?
Старший байт номера спрайта - это номер банка.
Чтобы видеокарта могла найти спрайт по номеру она должна знать начало банка и размеры спрайтов в этом банке.
Если указывать при копировании трехбайтный адрес спрайта, тогда нужно будет каждый раз указывать и размер спрайта, если будут использоваться спрайты разных размеров. А при обращении по номеру банка и спрайта размер спрайтов будет читаться из параметров банка. Как их увязать между собой.
Как вариант можно не делить всю область на банки и не сохранять их параметры. Тогда нужно каждый раз при смене размера используемого спрайта задавать текущий размер и указывать адрес начала спрайтов данного размера. Тогда нет ограничений на количество банков и не надо сохранять в видеокарте их параметры.
FPGA может аппаратно умножать числа по 18 битов. Это можно использовать для вычисления смещения спрайта в банке.
Запутаться можно уже...
Давайте о банках и спрайтах еще обдумаем хорошенько. Еще нужно обдумать о поведении блиттера на границах экрана. Например, как изображать спрайт летящего справа-налево объекта ?
Да, конечно.
Верно.
Смотрите, можно проще, прям без "банков", вот так:
- установил начало области (3 байта адрес спрайт памяти)
- установил размер спрайтов области (2 байта)
- копирую спрайт по номеру спрайта (номер спрайта: 1 или 2 байта)
- ...
Т.е. всё тоже самое, что вы говорили, только понятия "банка", мы не вводим. А просто при необходимости, подаются команды установки "начала области" и "размера спрайтов области" (вместо переключения банков).
По моему так по-проще будет.
На нормальных видеоконтроллерах спрайты лежат в виде битмапа шириной 512 и не требуют никакого умножения. Тслабсу это было внедрено в мосх ещё два года назад, он понял сразу.
Вроде решили, что не стоит ограничивать полет фантазии программиста размерами спрайта 16 х 16 точек или каким-либо другим. Пусть он сам выбирает размер, например 6х8 точек для букв. А для произвольного размера нужно умножение при определении по номеру адреса начала спрайта .
В команды добавлено:
АДРЕС НАЧАЛА ОБЛАСТИ СПРАЙТОВ
LD (IY+1), SPR0_ADDR0 ; младший байт адреса
LD (IY+1), число
LD (IY+1), SPR0_ADDR1 ; средний байт адреса
LD (IY+1), число
LD (IY+1), SPR0_ADDR2 ; старший байт адреса
LD (IY+1), число
РАЗМЕР СПРАЙТОВ В ОБЛАСТИ
LD (IY+1), SIZE_X ; размер спрайта по-горизонтали (обычно 16)
LD (IY+1), число
LD (IY+1), SIZE_Y ; размер спрайта по-вертикали (обычно 16)
LD (IY+1), число
Пользователь задаёт координаты левого верхнего угла спрайта в битмапе и размер этого спрайта. Первая строка спрайта берётся по адресу base+256*Y+X. Следующая строка спрайта берётся по адресу +256. И так далее.