Лисья Нора

Оглавление


§ Код адаптера

Используется 64Кб памяти и 1Кб палитры.
/**
* Общий экран 320 на 200, 256 цветов
*/
module vga
(
input clock,
output reg [3:0] r,
output reg [3:0] g,
output reg [3:0] b,
output hs,
output vs,
output vb, // =1 VBlank
output reg [15:0] a, // Запрос данных
input [ 7:0] i, // Цвет точки
output reg [ 7:0] c, // Запрос цвета
input [15:0] p // Палитра
);
// -----------------------------------------------------------------------------
// Тайминги для горизонтальной и вертикальной развертки
parameter
// Visible Front Sync Back Whole
hzv = 640, hzf = 16, hzs = 96, hzb = 48, hzw = 800,
vtv = 400, vtf = 12, vts = 2, vtb = 35, vtw = 449;
// -----------------------------------------------------------------------------
assign hs = x < (hzb + hzv + hzf);
assign vs = y < (vtb + vtv + vtf);
assign vb = x == xmax && y == ymax;
// -----------------------------------------------------------------------------
reg [ 9:0] x = 0;
reg [ 9:0] y = 0;
wire [ 9:0] X = x - hzb;
wire [ 9:0] Y = y - vtb;
// -----------------------------------------------------------------------------
wire xmax = (x == hzw - 1);
wire ymax = (y == vtw - 1);
wire show = x >= hzb && x < hzb + hzv && y >= vtb && y < vtb + vtv;
// -----------------------------------------------------------------------------
always @(posedge clock) begin
 
// Кадровая развертка
x <= xmax ? 0 : x + 1;
y <= xmax ? (ymax ? 0 : y + 1) : y;
 
// Каждые 2Т присылается новый цвет из палитры
if (show) begin
 
if (x[0]) begin a <= Y[8:1]*320 + X[9:1]; {r, g, b} <= p; end
else begin c <= i; end
 
end else {r,g,b} <= 12'h000;
 
end
endmodule

§ TOP-модуль

wire [15:0] a, p;
wire [ 7:0] i, c;
 
vga VGA
(
.clock (clock_25),
.r (VGA_R),
.g (VGA_G),
.b (VGA_B),
.hs (VGA_HS),
.vs (VGA_VS),
.a (a),
.i (i),
.c (c),
.p (p),
);
 
m1 M1(.clock(~clock_25), .a(c), .q(p));
m64 M2(.clock(~clock_25), .a(a), .q(i));

§ Утилита создания палитры

Берется некоторое PNG изображение 24-бит размером 1 на 256 пикселей и пропускается сквозь этот скрипт.
<?php
 
$im = imagecreatefrompng($argv[1]);
 
$m = [
"WIDTH=16;",
"DEPTH=256;",
"ADDRESS_RADIX=HEX;",
"DATA_RADIX=HEX;",
"CONTENT BEGIN",
];
 
for ($y = 0; $y < 256; $y++)
{
$c = imagecolorat($im, 0, $y);
$r = ($c >> 16) & 255;
$g = ($c >> 8) & 255;
$b = ($c >> 0) & 255;
$o = ($r>>4)*256 + ($g>>4)*16 + ($b>>4);
$m[] = sprintf(" %02X: %04X;", $y, $o);
}
 
$m[] = "END;";
 
file_put_contents($argv[2], join("\n", $m));

§ Утилита создания 256-цветного образа

Для этого потребуется PNG картинка размером 320 на 200, 256 цветов.
<?php
 
$im = imagecreatefrompng($argv[1]);
 
function mifhead($a, $b)
{
return [
"WIDTH=$a;",
"DEPTH=$b;",
"ADDRESS_RADIX=HEX;",
"DATA_RADIX=HEX;",
"CONTENT BEGIN",
];
}
 
// -----------------------------------------------------------------------------
// Читаем и пишем палитру
$m = mifhead(16,256);
for ($i = 0; $i < 256; $i++)
{
$c = imagecolorsforindex($im, $i);
$r = $c['red'];
$g = $c['green'];
$b = $c['blue'];
$o = ($r>>4)*256 + ($g>>4)*16 + ($b>>4);
$m[] = sprintf(" %02X: %04X;", $i, $o);
}
$m[] = "END;";
file_put_contents($argv[2], join("\n", $m));
 
// -----------------------------------------------------------------------------
// Читаем пиксели и пишем пиксели
$m = mifhead(8,65536);
for ($y = 0; $y < 200; $y++)
for ($x = 0; $x < 320; $x++) {
$m[] = sprintf(" %04X: %02X;", $x + $y*320, imagecolorat($im, $x, $y));
}
$m[] = " [FA00..FFFF]: 00;";
$m[] = "END;";
file_put_contents($argv[3], join("\n", $m));