借り初めのひみつきち

仮ブログです。

WASMで自作PCエミュレーター Part4

自作エミュレーターVGA に(一部)対応しました!

github.com

今までは UART 経由で端末エミュレーターに接続していました。
DOS やその上で動く多くのソフトウェアは標準入出力という概念があるので、今まではこの方法が簡単に実装できてうまく動いていました。
しかし、世の中には VRAM を直接操作してテキスト表示したり、グラフィックスを扱うソフトもたくさんあります。
また、使っていた端末エミュレーターにも色々と不満が出てきていたので置き換えたいと考えていました。
そんなわけで VGA の実装をはじめたのでした。

V・G・A!

VGA を実装するにあたって問題がひとつありました。このエミュレーターMMIO に対応していません。
要するに VRAM にメモリアクセスしたことを検知して画面を更新することができません。

UART は IO 命令を契機に画面更新ができましたが、それができなくなりました。
画面のレンダリングはとても重い作業なので毎フレーム再描画するわけにもいきません。
解決策としては一定間隔で VRAM 領域をスキャンして変更があった場合に再描画するようにしました。
徹夜で調整した結果、まぁまぁのパフォーマンスが出てるようです。

モード 3 とモード 13 のみ実装しています。モード 12 は VGA = 640x480 を象徴するメジャーな画面モードのひとつではありますが、 MMIO がないと実現不可能なのでおそらく未来永劫実装しません。

PS/2 と JS のキーボード処理の闇

端末エミュレーターを廃止したのでキーボード入力もきちんと実装する必要が出てきました。
JavaScript ではキーイベントで結構細かいところまでキー入力の値が取れるのですが、そこは闇だらけでした。
環境によって取れる値が異なったり、別のキーに対して同じキーコードが割り当てられていたりします。
さらに、英語配列を基準にキーコードを決めてるようで、日本語モードだと記号の対応がぐちゃぐちゃでした。
完全に PS/2 キーボードをエミュレーションしようとすると記号キーの対応が死んでしまうので、 ASCII コードが取れるところは文字が入力したいと判断して ASCII コードを優先するようにしました。

TL; DR

これらの改修でゲームなんかもそれなりに動くようになりました。

f:id:neriring16:20190715001621p:plain

f:id:neriring16:20190715000906p:plain

f:id:neriring16:20190715001010p:plain

f:id:neriring16:20190715001050p:plain