GitHub - neri/vpc: A PC Emulator implemented by WebAssembly
はりぼてOS
前回投稿時点では 起動画面が出るところまでの動作でそれ以降の動作は不安定になってましたが、その後の改良で現在ではほとんどのアプリが動くようになりました。
マウスも「Pointer Lock API」というものを使ってかなり理想に近い動作をするようになりました。タッチパネルの動作をどうするかが現在の課題です。
また、どうもmmlplayer のタイマーがうまく動いていないらしく途中で再生が止まってしまう不具合を確認しています。
最も近い隣人
画像を拡大縮小するアルゴリズムはいくつかあって多くのアルゴリズムは近くのピクセルの値と演算して補完しますが、「Nearest Neighbor」というのは直訳すると「最も近い隣人」になり、最も近い場所にあるピクセルをそのまま描画するというかっこいい名前とは裏腹に最も単純なアルゴリズムです。
ピクセルアートを整数倍表示するときはこの「Nearest Neighbor」を使うとボケのない綺麗な描画できます。
しかし整数倍にできなかったり風景写真やアウトラインフォントなどの描画は「Nearest Neighbor」を使うとガクガクしてしまうので、設定画面で切り替えできるようにしました。
iOS端末では「Nearest Neighbor」は常時オフにした方が全体的に良好な描画結果になるようです。
デバッグ機能、Step Over、Break on MBR
もともとCPUはステップ実行できるようになっていて、実行中にレジスタの値を読み書きできるように設計されていましたが、デバッガといえるほどの機能が充実していませんでした。
そこで、インターフェースを改良していろんなコマンドを実行できるようにしました。
現在、MS-DOS 付属の debug コマンドのコマンドに近いインターフェースを実装しています。
アセンブル機能はありませんが、メモリのダンプ、逆アセンブル、レジスタの参照と編集、ステップ実行などのデバッグ機能が利用できます。
実行中に「DevTool」にある「Step」ボタンを押すか、「ICEBP」という隠し命令 (オペコード 0xF1) を実行するとデバッグモードになります。
また、新たに Step Over (ptrace) 機能も実装しました。
これは次に実行する命令が CALL 命令や INT 命令だった場合に「次の次の命令」にブレークポイントを設定し、それ以外の命令の場合は通常のステップ実行する機能で、デバッグ時に関数の中身まで関心がない場合にステップを省略することができます。
この機能はハードウェアブレークポイントで実装しています。ハードウェアブレークポイントが設定されると CPU 実行時に CS:EIP の値を監視するので実行速度が1〜2割程度低下しますが、有効になるのはデバッグの一時的な実行時だけでソフトウェアブレークポイントよりメリットが多いので採用しました。
さらに「Break on MBR」という機能も実装しました。
この機能を有効にすると起動時に MBR にジャンプした瞬間にデバッグモードになって OS の起動をデバッグできるようになります。