現在地

プログラミング

SBCZ80(その後)

カテゴリー:

SBCZ80について進展がありましたので記録しておきます。

メッセージ文字化け

電源ON時にメッセージの一部が化ける現象が発生していました。

CR,LF,"Universal Monitor Z80",CR,LF,00H

上記のメッセージ(最後の00Hは文字列の終端マークです)を表示しているはずなのになぜかLFと"U"の間に変な文字が挿入され次の"U"とともに化けてしまいます。電源ONのままリセットすれば問題はありません。

次にメッセージを少し変形しました。

CR,LF,CR,LF,"Universal Monitor Z80",CR,LF,00H

やはり2文字目のLFの後に挿入されると想像していましたが、実際は4文字目のLFの後"U"の前に挿入されました。

前回はここまで書きました。

さらにLF,"U"の組み合わせに何かあるのかと次を試してみます。

SBCZ80(ソフトウェア編)

カテゴリー:

前回に引き続いてSBCZ80、今回はソフトウェア編です。

いつものようにUniversal Monitorを移植するわけですが、これまでUniversal Monitor Z80を動かしてきたMAA-1ボードとSBCZ80は実はほとんど同じです。ソフトウェアから見た違いといえばROM/RAMの容量が半分になっているくらいで、SIOのアドレスなども一致しています。

となると0FF00H~0FFFFHに配置されていたワークエリア・スタックを0BF00H~0BFFFHに移動するだけで動きそうです。これならconfig.incの変更ですみます。

8031/8032ボード(ソフトウェア編)

カテゴリー:

8031/8032ボードはいくつかアドレスを変えながらループさせてアドレスバス確認が出来たところで一応完成ということにして、Universal Monitorの移植にかかります。

ターミナルはEMILY Board経由と内蔵UARTの両方に対応することにしますが、まずは簡単そうなEMILY Board経由で一通り動かしてみることにして一通りのコマンド(D(ump), G(o), S(et), H(bank), L(oad))を実装してみました。

これもまた癖のあるアーキテクチャですね。

8088ボード(ソフトウェア編)

カテゴリー:

8088ボードのソフトウェアについて書いてみます。

動かすのはいつものようにUniversal Monitorです。

8086系は8080に似ていますし、以前(30年ほど前です)書いていたこともあるので、あまり苦もなく書けますね。フラグ変化とか細部はもちろん憶えてはいないので資料確認しながらですし、アセンブルすると使えないレジスタ指定しててエラーになったりはありますが、書いているうちにすぐに慣れていきます。

まずはコンソールドライバ、EMILY Board用のものを6502から、8251用のものを8080から移植しました。ほぼ機械的な変換で済みますが8251の初期化部分にはNOPを追加(8251はまだ配線もしていないので動作未確認)しています。

TMS9995ボード (ソフトウェア編)

カテゴリー:

TMS9995ボードUniversal Monitorの基本部分(D,G,Sコマンド)の移植ができましたので、アセンブリ言語でプログラミングしてみて感じたことを書いてみようと思います。

  • 豊富なレジスタ
    16と数が多いだけではなく基本的に対等なのでやりくりに苦労することがあまりありません。まぁ実態はメモリの一部なので直接メモリアクセスするのに比べメリットは少ない(命令長が短くなる・一部レジスタ専用の命令がある)ですが。

[UniMon] RP2A03判別 と Lコマンド追加

カテゴリー:

先日のRP2A03ボードによってRP2A03判別ルーチンの確認ができたのでここに記しておきます。

まず判別するためには両者の違いを利用することになりますが、簡単なのはRP2A03で削除されている10進演算機能の有無を使う方法です。

他にも内蔵のAudio Processing Unit(APU)などのレジスタを参照する方法も考えられなくは無いですが、RP2A03以外では何がつながっているかわからず、誤判別や思わぬ副作用の原因になるかもしれません。

それではソースコードです。

[UniMon] レジスタ命令の内側(その3)

カテゴリー:

最後となる今回は「3. メモリに退避されている内容をレジスタに戻しユーザプログラムに制御を渡す」です。

コマンドで値を変更したらその状態でユーザプログラムを実行できなくては意味がありません。

要はレジスタに値を設定して目的の番地にブランチすれば良いだけなのですが、すでに設定済みのレジスタを壊さないようにしなくてはいけないので進むにつれ制約が増えていきます。

比較的多くのプロセッサで使える手は、「スタックに積んでおいてPOP,...,POP,RET」です。ちょうど1回目の逆です。

スタックを使った割り込みに対応しているプロセッサなら大抵これが使えます。

割り込み時にはレジスタの状態を元に戻す必要があるからです。スタックが専用空間にあって自由にアクセスできないなど使えないプロセッサもありますが...

MC6800を例に見てみましょう。

[UniMon] レジスタ命令の内側(その2)

カテゴリー:

前回は「ユーザプログラムからモニタに制御が渡ったときにレジスタ内容をメモリに退避する」でしたので、今回は「2. メモリに退避されている値を表示・変更する」についてです。

レジスタ内容をメモリに退避するのはプロセッサ固有の書き方が必要でしたが、すでにメモリ上にある値を表示・変更するだけであれば特殊なプログラミングは必要ありません。とはいえレジスタの名称や個数はプロセッサ毎に異なりますからそれなりの工夫は要ります。

まず全レジスタの一覧表示は簡単です。ループとテーブルで書いてもいいのですが、レジスタ数が少ないうちは「レジスタ名を表示・メモリから値をロード・16進表示」を必要数分並べてしまっても大したことはありません。

レジスタの変更はそうはいきませんので、以下のようなテーブルを用意しました。

[UniMon] レジスタ命令の内側(その1)

カテゴリー:

MC6800に続いて6502, MC6809についてもレジスタ命令を追加しましたので、その内側について書いてみたいと思います。

さて、レジスタ命令とはレジスタの値を表示・変更する機能なわけですが、CPUがある瞬間に実行できるプログラムは1つですからユーザプログラム実行中はモニタプログラムは実行できません。モニタプログラム自身の動作にもレジスタは必要です。

ではどうするか?

モニタプログラムには次の3つの機能が必要になります。

ページ