CPU実験室

誰も見向きもしない古いCPUをいじって動かしてみようというプロジェクトです

プログラムメモリアクセス

i8031のプログラム領域とデータ領域はアーキテクチャ的に分離していて、さらに今回の基板では物理的にRAMも別にしたので普通であればプログラムコードはデータとして扱えません。それを唯一可能にするのがmovc命令なんですが、コンパイラが吐いたアセンブラコードを見ると一見してmovcが見当たりません。それではどうやってアクセスしているのかと。

 

まずmain()の中でlcdstr()関数を呼んでいる部分です

f:id:O3I:20200310194123j:plain

コードに埋め込まれた"*** TEST ***"という文字列のアドレス#___str_0をdptrレジスタにセットしてlcdstrを呼んでいるのはいいですが、ここでミソなのは同時にbレジスタに0x80をセットしてから呼んでいるところです。

次にlcdstr()は簡単な処理なのに長大なコードに展開されています。これで半分くらいです。

f:id:O3I:20200310194144j:plain

やっと中ほどに出てくる_gptrgetルーチンがポインタ変数から値を取り出す(*str)処理の実体です。(get value for a generic pointer)

この処理はビルド時にリンクされるライブラリに含まれるようでソースコードも公開されていました。要はbレジスタにセットされたフラグを見てポインタの指す先がプログラム領域かデータ領域を判断しそれによりmovcmovxを使い分けるようです。フラグが0x80ならプログラム領域であるということでここでやっとmovcが出てきました。

f:id:O3I:20200310202512j:plain

LCD自体がもともとアクセスが低速だし、目で追える速度で更新できれば十分なのでいいですがそれにしても迂遠なコードです。アセンブラのベタ手書きだったら数行で済みそうです