VGA controller その後

昨夜作りかけたディスプレイコントローラだが、ちょこちょこっとデバッグして、画面が映るようになった。しかし、VGA の解像度に充分な容量のメモリは (DRAM が動かない限り) ないので、いまのところ適当なパターンを作る回路が仕込んであり、スイッチでそれを切り替えて遊べる、みたいな感じ。
で、テキスト VRAM みたいなのがあって、文字を表示できたらいいかなー、と思ったので、現状のパターン発生回路の出力にテキストをスーパーインポーズできるような仕掛けを作ることにした。フォントを作っちゃえばあとはなんとかなるだろ、と思うのだが、甘いかな。とりあえず、テキストに簡単な属性がつけられるといいなー、と思って、本棚から何年ぶりかで「PC-9800シリーズ テクニカルデータブック」を引っ張り出してみた。テキストVRAMの属性ビットのところをみると、
– R
– G
– B
– VL (Vertical Line)
– UL (Under Line)
– RV (Reverse)
– BL (Blink)
– ST_ (Secret)
だそうだ。Secret は実装しなくてもいいか。UL は 4 pixel 右にずれる仕様で、つまり、VL と合わせると罫線としても使えるようになっている。いまさらだけど、98 かっこいいな!
で、XC3S700AN の Block RAM は 20 個ある、というのを前提に仕様を整理してみることにする。
CG (Character Generator) に必要なメモリは、1文字 8×16 で 16bytes. カタカナだけの 8bit コードを全部サポートすると、4kB 必要になるが、ASCII だけの 7bit コードなら、2kB だから、BlockRAM ひとつにちょうど収まる (こう考えてみると、CG というのはけっこう大きな ROM が必要で、ましてや漢字をサポートするというのは、16×16 だとしても 32bytes/character なわけで、ひと昔前ならば一大事業だと思う)。
VRAM のほうは、1文字 8bit で、80×25 でちょうど 2kB. これだと 640×400 しか使い切れない (NEC の気持ちがわかった気がするぞ!)。キャラクタの高さを 16 ドットにすると、80×30 まで入るわけで、これだと 2400bytes 必要であり、352バイトはみ出してしまうが、さすがにこれだけのために BlockRAM をもうひとつ使うのはなんかもったいないので、attribute を 4bit に圧縮して、BlockRAM の後半をこれに使うことにした。RGB + UL でいいかな。
VRAM のアドレッシングは、VGA コントローラから現在の X 座標と Y 座標の値が出てくるので、X (8 pixels/character) は下の 3 bit を切り捨てて、Y (16 pixels / character) は下の 4bit を切り捨ててやれば、キャラクタ座標になるわけだ。しかし、ここからアドレスに変換するところが実に問題で、80 を掛ける、というのはけっこうしんどい。そこで、text + attribute で、一行あたり 120 bytes だから、128bytes / line を割り当てることにした。こうすると、4kB のメモリには 32 行分乗ることになり、30行の画面には充分である。結局のところ、アドレス計算は、
assign TEXT_A[11:0] = {VGA_Y[9:4], VGA_X[9:3]};
みたいな感じでできる。Attribute のほうは、2 桁分が 1 バイトで読めてくるので、そこはちょっと工夫が必要だが、たいしたことはない。
CG は、アドレスの上位 7 ビットが文字コードで、下位 4 ビットが Y 軸。
これが終わったら、とりあえず文字の表示とかが FPGA 単体でできるようになるわけなので、学生の教育用に UART と Ethernet の MAC くらいは作りたいが、Ethernet MAC は大変そうだなあ。

コメントを残す