19 |
GameFSMの改良 (5) |
いろいろと試した結果、copyAreaがstaticに32回呼ばれ(関連関数だと60回以上)、それが状態爆発を起こしていることが分かってきました。数年前に開発した時は同じソースで、bsvコンパイルが1時間もかかっていましたが、PCを最新のマシンに更新したのとbscもアップデートされ、現在は16分程度になっています。それでも時間がかかるのは前記の問題のようです。
これもChatGPT5に相談したところ、メインのStmtからcopyAreaのStmtを32回呼ぶと巨大なステートマシンのスケジューリングが必要になり時間がかかるとのことで、copyArea等の画面操作関数を書き換え、画面アクセスする関数(blitEngine())に統合します。さらにその関数をautoFSM化して常に動作させておき、メインからは適宜コマンドを発行するだけにします。
まず、blitEngine()が動作するコマンド種別を定義します。
typedef UInt#(8) U8;
typedef enum { BLIT_COPY, BLIT_OR, BLIT_ERASE, BLIT_ANDN }
BlitOp deriving (Bits, Eq);
typedef struct {
BlitOp op;
U8 sx; U8 sy; // ソース(prom)のx, yアドレス
U8 dx; U8 dy; // デスト(vram)のx, yアドレス
U8 w; U8 h; // 図形の幅と高さ
} Blit deriving (Bits, Eq);