あなたが現在見ているのは Raspi Zero 2W ベアメタル開発 05【MZ-80K2 Emu 編】

Raspi Zero 2W ベアメタル開発 05【MZ-80K2 Emu 編】

さて、前回から数日経ってしまいましたが、Z80のエミュレーションで、問題が発生。

Delphi で開発したソースは、メモリからオペコード(1byte)を読み込んで、事前に用意したオペコードに対応するプロシージャ名の配列から、対象となるprocedure 名を取得して、そのprocedure名からプロシージャを呼び出すためのポインタを取得してマシン語の実行というプログラムだったのですが(ややこしいですけど効率的)、なんとベアメタルでの Free Pascal では構文でエラーは出ないものの、ポインタの値が null しか戻ってこないという大ピンチに陥っていまして、ちょいとなやんでいました。

色々と調べて、トライしてやっと求めている動きになりました。

具体的には、procedure( )of object 型の配列を準備して、オペコードに対応するprocedure のポインタを設定するという方法です。

TOp という class にマシン語命令を処理するprocedure がすべて入っていて、そのインスタンスをop とした時、クラス外で準備した配列に次のようにポインタを代入します。

opcode_main[$C3] := @op.jp;

Z80 ではメインとなる命令群が256個、2バイト命令が、CB, DD,ED,FD ということで、4*256個、3バイト命令で、256*2の512個、合わせて 1792 個の命令(その中には未定義の部分もありますが)なので、ポインタを利用した呼び出しをしないと、大量のif then else if をずらーっと記述しなければいけないはめになり、かつ遅いプログラムとなってしまいます。

まぁとりあえず、解決策があって良かった。

ということで、Z80の動作もレジスタの値の変化を表示して、うまくいってるようなので、VRAMの内容を画面に書き込むモードに切り替えて実行!

とりあえず、モニタプログラムが動いて、画面にSP-1002 の表示が出ました。

しかし、めちゃくちゃ遅い! これはなんとかせねば。

コメントを残す

CAPTCHA