You are here

ノウハウ・テクニック

古のマイコン開発法(その3)

カテゴリー:

その2で市販トレーニングキットと同じように使えるようになりました。

しかしまだハンドアセンブルしたバイナリを入力して実行することしかできません。何らかの高級言語を使いたいところです。そうなると16進キーパッドや7セグメントLED表示器では不足です。

というわけで......

キーボード
16進キーパッドと異なりスイッチを並べて自作するのは難しいですが、当時でもキーボードは入手できたようです。

もちろんUSBのような共通のインターフェイスがあったわけではありません。単にキースイッチが並んでいるだけで自分でマトリクスを配線しなくてはならないもの、マトリクスの配線までされているもの、エンコーダまでついているものなどがあったようです。マトリクスタイプならキーパッドの数が増えただけのようなものなのでソフトウェアの変更は容易でしょう。

ディスプレイ
表示装置そのものの製作は困難なので既製品を利用します。最も安価なのはテレビで代用する方法で、ビデオ入力が無い場合はRFモジュレータを用意してアンテナ端子から入力します。

古のマイコン開発法(その2)

カテゴリー:

その1でプログラムを実行できるようになりましたが、スイッチを操作して書き込むのは非常に手間がかかります。また電源を切れば消えてしまい、再度入力しなくてはなりません。

バッテリバックアップ
SRAMを電池でバックアップ(あるいは電源を入れっぱなしに)すれば毎回入力しなくて済むようになります。

プログラムを暴走させて壊してしまうリスクはありますが、RAMを2つ搭載して片方の書き込み信号をスイッチで切れるようにして保護する方法もあります。

キーパッド
16進キーパッドと7セグメントLED表示器を搭載すれば入力が楽になります。

これを制御するためのプログラムはスイッチ操作で入力する必要があります。必要最小限のプログラムをスイッチ操作で入力し、キーパッドが使えるようになったらそれを利用して機能を拡張していくことで効率よく入力できます。

カセットインターフェイス
カセットインターフェイスを製作すれば入力したプログラムを保存しておくことができます。

古のマイコン開発法(その1)

カテゴリー:

ちょっとTwitter(もう「X」と書かなきゃいけないのか)で話が出たので大昔のマイコン開発について書いてみることにします。

マイコン開発といってもツールに恵まれていたであろう業務でやっていたような人ではなくアマチュアの話です。

今マイコンボードを開発するというと、フラッシュメモリを内蔵したマイコンとPCを接続(接続ケーブルなどは簡単に作れるか個人でも買える程度の価格)して簡単に書き込めますし、書き込むソフトウェアの作成もコンパイラなどのツールも無償で使えるものも多く存在します。マイコンの機能はほぼチップの中で完結しているので基板もI/Oの引き出しがメインになります。

一方で1970年代から80年代の頭にかけてアマチュアがマイコンボードを作るといった場合、パソコンを持っていないからいっちょ作ってみるかというパターンが結構あったのです。

当時の本や記事を読むとこの状況を前提として書かれているものがあります。それらを元に当時の人がどうやって何もないところから作り上げていったか書いてみようと思います。

まず当時はCPU, ROM, RAM, I/Oが一つになったデバイスはほとんどありません。

ATmega164でWDTが勝手に動作した件

カテゴリー:

PLLシンセサイザ(その5)のところで「ちょっとトラブルがあった」と書きましたが、今回はそれについて書いてみようと思います。

VCOが出来たのでD/Aコンバータから電圧を与えてV-F特性を見ようと電源を入れたのですが......

何故かマイコンがリセットを繰り返してしまいD/Aを操作できません。最後にD/Aコンバータを確認したときには動作していましたし、それからソフトウェアは変更していません。ハードウェア的には電源とD/Aの出力をくらいでマイコンの動作に影響を与えるとは考えにくいのです。電源が揺れれば考えられなくはありませんが、オシロで見ても問題なさそうですしVCO基板を外しても解決していません。

以前試したときは(初期化を忘れていたのに)偶然動いていただけかもしれません。未使用割り込みベクタをreti命令を指すようにしたり、I/Oポートの初期化を見直したりしましたが効果ありません。

MC68020 / MC68030 の判別

カテゴリー:

アドレスエラー・バスエラー時の表示は、未対応のフォーマットの場合にはスタックに積まれたワードをそのまま16進ダンプするようにしたので、デコードルーチンは後回しにして判別を書くことにしました。

まずMC68020以上であることの判別は容易(MC68010の判別(補足)参照)なのですが、MC68020からMC68030で追加された命令はありません。というかあるにはあるのですがMMU関係の命令なのでMC68020+MC68851(PMMU)でも実行できてしまいます。細かな動作の違いはあるかもしれませんが...

Z8000セグメントモード対応(その3)

カテゴリー:

前回までで従来の機能がセグメントモードで動作するようになりましたが、セグメントモードで動作するなら当然D(ump)などのコマンドでもセグメントが指定できなくてはなりません。

この辺りは8086のセグメントやTLCS-90のバンクを移植する形で対応しました。

表記はZ8000らしく<<SEG>>OFFSET形式も考えましたが、長くなるので8086同様SEG:OFFSET形式としています。

コマンドのパラメータ以外に対応が必要なのはR(egister)コマンドにおけるSSPとPCです。

  1. SSPH, SSPL, PCH, PCLのように16ビットずつ別のレジスタ名をつける
  2. 32レジスタとして扱う
  3. 16ビットずつに分けるが「:」で区切ってレジスタとしては1つとして扱う

などの方法が考えられます。

1.は勝手に名前を付けることになることと、2回に分けて設定するのは面倒です。

Z8000セグメントモード対応(その2)

カテゴリー:

前回枠組みができたので実際に変更していきます。

直接アドレスやJR, CALRなどの相対アドレスはアセンブラが良きに計らってくれるので書き直す必要はありません。

問題はレジスタ間接(インデックスなども含む)です。これは単純に書き換えられない上に、アドレスレジスタが隣り合う2つのレジスタをペアにする関係でレジスタの割り当てを大きく変更する必要がありました。幸いレジスタ数に余裕があったためレジスタ番号の書き換え程度で済んでいますが、不足する場合はメモリに退避するなど変更規模が大きくなってしまいます。

今回は大きく3つのパターンで対応しました。

単純に32ビットレジスタへ置き換え

レジスタ間接のまま32ビット化するのが一番手っ取り早いのですが、レジスタをペアで使用するので多用するとレジスタが足りなくなる恐れがあります。

これはどこを指すかわからない場合に使用しました。具体的にはSTROUTルーチンへの引数と各コマンドでの対象メモリへのアクセスです。

Z8000セグメントモード対応(その1)

カテゴリー:

Z8001を動かすで非セグメントモードで動くことがわかりました。動作する石も複数確保できましたので、本来のセグメントモードで動かすことにします。

Z8000ファミリにはセグメントモードでも動作するZ8001(とZ8003)と非セグメントモード専用のZ8002(とZ8004)があります。両者はリセット時のPC, PSWの初期値を格納する形式が異なる上にアドレスが重なるので同一バイナリで両方に対応することはできません。

どちらの形式で読んでも辻褄の合う値を設定することは不可能ではありませんがメモリマップの制約が大きくなります。

Z8001(とZ8003)はセグメントモードでも非セグメントモードでも動作させることができます。これは同一バイナリで両対応するのは可能ですが、ほぼすべてのルーチンを2つ持つようなことになってしまいます。

結局3種類のバイナリを作ることになります。

アドレスエラー・バスエラー (その4)

カテゴリー:

アドレスエラー・バスエラーについて今度こそ終わりにするつもりです。

MC68040

MC68040からは大きな方向転換があったように感じます。

複雑度は増しているはずなのにスタックに積まれる情報は減っているのです。前にもMC68010の判別(補足)に書きましたが、命令の再開を諦めて頭からやり直す方針のようです。

まずはアドレスエラーの場合です。

アドレスエラー・バスエラー (その3)

3回目は残りですが書ききれるかなぁ。さらに1回増えてしまうかもしれません。

ここからは自分の手で動かしたことはないのでマニュアルを元にざっくり書いていきます。

MC68020 / MC68030

この両者はソフトウェアから見た例外処理はほぼ共通のようなのでまとめて書きます。

これらではエラー発生時の状況によってスタックに積まれる情報量に違いがあるようです。キリの悪いところで発生すると保存しないといけない項目が増えるということなのかな。

どちらが使われたかはSP+6の上位4ビットでわかります。

この4ビットでどのフォーマットかはわかりますが、それが何ワードなのかは書かれていません。
Universal MonitorではこれまでMC68010までの対応だったので0000なら4ワード、それ以外なら29ワードとしていました。それをMC68020以降で実行するとスタックがおかしなことになります。今回MC68010, MC68020, MC68030, MC68040, MC68060, SCC68070で使われているフォーマットとその長さをテーブルにして引くようにしました。

まずは少ない場合から。

Pages