Article #1048

既に発行済みのブログであっても適宜修正・追加することがあります。
We may make changes and additions to blogs already published.

GameFSMの改良 (23)

posted by sakurai on December 11, 2025 #1048

対応するコードを示します。まず、前景は各色1bitカラー$(g, r, b)$で元と変わりません。

   Bit#(1) fg_g1 = !in_exp ? (in_data[2] & pack(fg_dt)) : 1'b0;
   Bit#(1) fg_r1 = !in_exp ? (in_data[1] & pack(fg_dt))
                           : ((in_data[2] | in_data[1] | in_data[0]) & pack(fg_dt));
   Bit#(1) fg_b1 = !in_exp ? (in_data[0] & pack(fg_dt)) : 1'b0;

これに4bitの背景を重ね合わせます。背景は$(g_3, g_2, g_1, g_0, r_3, r_2, r_1, r_0, b_3, b_2, b_1, b_0)$の各色4bitカラーです。ただし前稿のとおり、$g_3=r_3=b_3=0$であることからデータは省略でき、3bitずつROMに格納します。

   // 背景 GRB333(9bit)
   Bit#(3) bg_g3 = bg_data[8:6];
   Bit#(3) bg_r3 = bg_data[5:3];
   Bit#(3) bg_b3 = bg_data[2:0];

そこからスキャンのタイミングでこのように各色3bitずつ9bitを取り出します。

   // 3bit → 4bit (MSB=0 を付加)
   Bit#(4) bg_g4 = { 1'b0, bg_g3 };
   Bit#(4) bg_r4 = { 1'b0, bg_r3 };
   Bit#(4) bg_b4 = { 1'b0, bg_b3 };

次にこのようにMSBに0を詰めて各色4bitとします。

   // 背景無効領域は完全黒
   Bit#(4) pix_g4 = bg_active ? mixPx(bg_g4, fg_g1) : 4'b0000;
   Bit#(4) pix_r4 = bg_active ? mixPx(bg_r4, fg_r1) : 4'b0000;
   Bit#(4) pix_b4 = bg_active ? mixPx(bg_b4, fg_b1) : 4'b0000;

前景と背景をブレンドしてdisplay timingでレターボックス化します。以下は前景と背景の合成関数です。

// 背景4bit bg4 と 1bit 前景 fg1 を合成
// 前景の足し込み量は 4'hC 固定(強すぎれば 8〜F で調整)
function Bit#(4) mixPx(Bit#(4) bg4, Bit#(1) fg1);
   UInt#(4) ubg  = unpack(bg4);
   // fg1 が 0 のとき 0000, 1 のとき 1111
   Bit#(4) add_b = 4'hC & { fg1, fg1, fg1, fg1 };
   UInt#(4) uadd = unpack(add_b);
   UInt#(5) sum  = zeroExtend(ubg) + zeroExtend(uadd);
   UInt#(4) out4 = (sum > 15) ? 15 : truncate(sum);
   return pack(out4);
endfunction

図1048.1に完成結果を示します。実際には動画で見るより背景画像は暗くなっており、ゲームの邪魔になることはありません。

図%%.1
図1048.1 完成画面

記事タイトルはGameFSMの改良ですが、実際に背景画像や星の点滅はGraphicsFSMというグラフィックコントローラに実装しました。背景画像が結構ROMを食うため、Arty 7-35Tでは入らず、Arty 7-100Tでなければ入りませんでした。


左矢前のブログ 次のブログ右矢

Leave a Comment

Your email address will not be published.

You may use Markdown syntax. If you include an ad such as http://, it will be invalidated by our AI system.

Please enter the numbers as they are shown in the image above.