§ Тайминги
Сегодня я хочу просто рассказать о том, как можно довольно легко и без проблем сделать вывод экрана спектрума на VGA монитор. Да, я как бы, говорю что легко, и без проблем, но это лишь потому, что я уже много раз делал этот видеовывод, да и сам он по себе простой.Самая большая проблема заключается в другом. Тайминги, которые совершенно не совместимы между VGA 25 Мгц и телевизионным сигналом, который генерировал спектрум. Возьмем за основу самое стандартное разрешение VGA 640 x 480, и его тайминги.
| HORIZ VERT | ZX HORIZ VERT Задний порожек | 48 33 | 48 48 Видимая область | 640 480 | 256 192 Передний порожек | 16 10 | 48 56 Синхронизация | 96 2 | 96 16 ИТОГО | 800 525 | 448 312Итого, 800 пиксель-клоков на одну строку и 525 строк, 60 кадров в секунду. Красиво и быстро. А теперь, очень интересный момент. Надо сделать 50 кадров. Вот этот момент полон печали и тоски. Мало того, что надо сделать 50 кадров в секунду, так еще надо другие тайминги. Частота видеопроцессора у спектрума 7 Мгц.
В таблице у спектрума немного не так все работает. На самом деле, там 48 и 48 пиксельклока отведены для рисования бордера, а не порожеков, которые у VGA равны черному цвету, так что можно считать что общая область рисования картинки равна 352 пикселей и 96 это синхронизация. Высота картинки тоже составляет 296 пикселей. Это очень сильно много, так что вместить ничего не получится на VGA, чтобы было нормально, потому часть бордера придется скрыть. Например, слева и справа будет по 32 пикселя, а не по 48. А сверху и снизу, кстати говоря, 48 пикселей получится сделать (снизу все равно будет не 56).
Так что как бы я ни старался, уложить точно экран у меня не выйдет. Но ладно, я тогда буду просто пытаться делать максимально приблизительно и на 60 Гц вместо 50 Гц, что даст увеличение на 6/5 скорости работы процессора (+20%) чтобы четко и точно успевать бегать за лучом.
§ Видеоадаптер VGA
В любом случае, что бы там ни было, и как бы там ни было, надо сделать видеоадаптер, который будет выдавать стандартную картинку на VGA. Минимальный видеоадаптер будет выглядеть, в целом, вот так.// verilator lint_off WIDTH module video ( input clock, output reg [3:0] r, output reg [3:0] g, output reg [3:0] b, output hs, output vs ); // --------------------------------------------------------------------- // Тайминги для горизонтальной|вертикальной развертки (640x400) parameter hz_visible = 640, vt_visible = 480, hz_front = 16, vt_front = 10, hz_sync = 96, vt_sync = 2, hz_back = 48, vt_back = 33, hz_whole = 800, vt_whole = 525; // --------------------------------------------------------------------- assign hs = x < (hz_back + hz_visible + hz_front); // NEG. assign vs = y >= (vt_back + vt_visible + vt_front); // POS. // --------------------------------------------------------------------- wire xmax = (x == hz_whole - 1); wire ymax = (y == vt_whole - 1); reg [10:0] x = 0; reg [10:0] y = 0; // --------------------------------------------------------------------- // Вывод видеосигнала always @(posedge clock) begin {r, g, b} <= 12'h000; // Кадровая развертка x <= xmax ? 0 : x + 1; y <= xmax ? (ymax ? 0 : y + 1) : y; // Вывод окна видеоадаптера if (x >= hz_back && x < hz_visible + hz_back && y >= vt_back && y < vt_visible + vt_back) begin {r, g, b} <= 12'hFFF; end end endmodule