6809について

凍結

MC6809 は 1979年にモトローラ社が発表した MPU(CPU) で、 MC6800/6802 を発展させたものになっていました。

※ モトローラ社は現存しますが、 MPU等を扱う半導体部門は独立分社化していて フリースケール・セミコンダクタ社となっています。
※ 当時のモトローラは発表してから製品が出荷されるまでの期間が1年ほど空いていたらしい。

6809(というか680x系)のプログラミングは、レジスタ同士、メモリ同士、の演算は (ほぼ)なく、 基本的にレジスタでメモリをアクセスする演算になります。

レジスタや命令表については 6809命令表 をみてやってください。

また、

のサイトあたりに、詳しい解説があり、参考になります。


 究極の8ビットCPU 

凍結

6809は究極の8ビットと謳われていました。

  • 命令の直交行性が(8ビットCPUとしては)高い
  • 豊富なアドレッシングモード
  • ポジション・インディペンデントなプログラムが組める
    (リエントラントなプログラムが組みやすい)
    (リカーシブなルーチンが組みやすい)

というような特徴がいわれていたような覚えがあります。

究極かはどうかは別にしても当時の 8ビットCPUの中では高機能で強力な部類だったでしょう。

 6809は(綺麗な命令体系で)綺麗に書ける、と言われましたが、 8ビットCPUとしては、であって、68K には遠く及ばず、 8086 同程度かちょっと下くらいかな、というのが実際のところでしょうか。

 残念ながら主流になることはありませんでした。
 すでに 8080/Z80系 や 6800/6802系が普及していたというのもあるでしょう。 組み込み用途としてはオーバースペック気味だったのでは、とも思います。
高機能である分、トランジスタ数も結構あったようで (当時の16ビットCPU並に)、コストがかかるモノに思います。

他の8ビットCPUと同様に絶対アドレス主体で組むと pcリラティブなどのポジションインディペンデントのための命令は使いませんし、 逆にos9等で pcリラティブで行うと絶対アドレッスングの使用頻度が少なく、 使われない命令の量が他の8ビットCPUよりも多そうです。

 高スペック用途では モトローラ自身が1980年に発表した16ビットCPU の 68000 のほうが主流で、 現在でもよく使われるくらいに普及していますし。
 6809はモトローラのMPUの中でも異端児の類かな、って気もしてます。


 vs 8086

凍結

 8 ビットCPU としては、当時のパソコンユーザは Z80 とよく比較することに なりましたが、発表年やアーキテクチャのあり方をみると、 むしろ 8086/8088 (1978年発表)に近いんじゃないかな、と思います
(これは単に己がFM11ユーザーだったためにPC9801(8086)系を意識してたせいかもですが)。

 6809,8086ともにそれ以前の 8ビットCPU を拡張/高機能化していったものですが、 命令の直交性具合は結構似た感じですし、

  • 8086 は、セグメント・レジスタによる相対化
  • 6809 は、PC相対, dp(やインデックスレジスタ)相対化

でポジションインディペンデントなどが視野に入っているように思います。

 ただ64Kバイトより広いメモリをどう扱うかの部分のアプローチの違いが、 区分/ランクが分かれる結果になっています。

 8ビットCPU と 16ビットCPU の区別は、結局はメーカーの宣伝しだい、 といったところでしょうが、大雑把には

  • CPUコアにとってのメモリー空間が64Kバイト以内ならば 8ビット
  • 16ビットバスで、それ以上かつ32ビットアドレス未満であれば 16ビット

といったところでしょうか。

そして、

  • 8086 は、セグメントレジスタを用いて1Mバイトをサポートする。
  • 6809 は、それ自体には無いが、オプションで6829というMMU(バンク切り替えの高機能版とでも)
  • と組み合わせて使えば2M バイトを扱える。

といったところです。

 もちろん、データ的には連続して64Kバイト以上扱えないとしても、 余計なサブルーチン/システム・コールをしなくても 1M の空間をアクセスしたりjump/callできる 8086 のほうが扱いやすいのは確かですが(腐っても16ビット... 命令が実質32ビットアーキテクチャの68Kと比べるとケチョンケチョンかもですが、 8ビットCPUとくらべると、ね)

 個人的には 6809 と 8086 は同程度にマニアック(な命令体系)だし、 同程度に綺麗だし、 同程度に汚いCPUだよなあ、 っと思っていたのでした。
(トリッキーな選択肢が多い分09のほうが汚くなりやすいかもだけど、パズル的には楽しいとも)。


 パソコン 

凍結

1980年代のパソコン用CPUとして、日本では

  • 日立のベーシックマスターLevel3/S1シリーズ
  • 富士通のFM-7/8/11シリーズ

に搭載されていました。海外では

  • TRS-80シリーズ

等に搭載されていたようです。

 これらの OS(といういい方は微妙だけど)としては、 たいてい Microsoft社製 BASIC をカスタマイズしたものが 採用されていたようです。

別売りの OS としては、

  • FLEX (TSC社)
  • os9(Microware社)

なんかが有名なところでしょうか。

TSC社のFLEXは元は 6800 用があり、それを6809対応にしたもののようです。 (TSC社はすでにない模様)

OS9 は、Microware社が 6809専用に作られたもので、64Kバイトのメモリで使う L1、 MMRやMMU(6829)を付加したシステムで用いる L2 の2系統がありました。 OS9は後に 68K用が作られ、 さらに386,SH,PowerPC等(一旦os9000と名前を変えるが現在はos9)に発展しました (が、Microware社は買収されて RadiSys社の一部門になった模様)。

 ソフトは 8080/Z80 系の比べると断然に少なかったようです。 (FM7系はそこそこ多かったようにも思いますが、PC88に比べると弱いですし、 OS9用のソフトとなるとCP/Mに比べるとぜんぜんありませんでした)


 フラグ変化 

凍結

 6809でのプログラミング(というか昔のモトローラCPU全般?)の特徴として、 インテルCPU に比べフラグ変化が多い、ってのがあります。

 これは、ロード、ストア命令でも、フラグ変化がおこり、このため わざわざ比較命令を用いなくても、0チェックや大小判定がすぐ行える、 というメリットがあります。

 反面、見た目の命令の役割はダミーでフラグ変化のためだけに使用されたり、 もちろんレジスタ,フラグ両方意味ある動きのために用いられたりで、 プログラマの読む手間/管理の手間が、 そうでないCPUにくらべ結構大きくなります。

 とくに6809の場合、短縮形の演算命令と、 汎用的な命令とでキャリーフラグの扱いが違うため、 考えずに(バイト数を減らそうと)命令の置き換えをすると バグってしまう場合があります。

adda #1c変更incac不変
deca #1c変更decac不変
cmpa #0c変更tstac不変
lda #0c不変clrac=0
eora #$FFc不変comac=1

 clr(a|b) や com(a|b) なんかは a,bを壊してよい状況なら cフラグのオン/オフをする命令として慣用的に用いられていました。

 その他、lea では

  • leax,leay では zフラグが変化するが
  • leau,leas ではフラグ変化しない

で、うっかり uレジスタをデクリメントのループカウンタに用いて 無限ループに陥る場合があったりしました。

 フラグの存命期間が精精 2,3行とかならばマシですが、 5行10行と遡ったり、ルーチンコール前から存在していたりすると、 かなり追っかけたり把握したりするのは骨が折れます。
フラグのために平行に動く別のシーケンス/空間が存在する感じです。
(正直なとこ、初めて6809から8086に移ったとき、気持ちが楽になったのを覚えています^^;)


 効率を求めると綺麗どころか酷く汚く・・・

凍結

8 ビットCPUにしては 6809 は命令の直交性があるほうのようなので、 綺麗に書こうとすれば6502(や Z80)なんかよりかは、 楽に綺麗にプログラムが書けます。

が、1バイトでも短く、1クロックでも速く、などと考えはじめると途端に、 不可解な書き方をしてしまい、他のCPUよりもずっと可読性の悪い プログラムになっていたのでは、と思います。

 上記のフラグの件や

  • y==0 比較するのに cmpy #0 (4バイト) の代わりに sty -2,s (3バイト)
  • y=s[0] とするのに ldy ,s (3バイト) でなく leay [,s] (2バイト)
  • 1バイトスキップにbrn, 2バイトスキップに cmpx#

等、半ば慣用表現と化しているものもあり、見た目にあれ?となる表現が増えたりします。

 また、テーブルはなるべく8ビットのpcrで届くよう配置を試みますし、 jump/callも8ビットオフセットですむように配置を試みたりするでしょう。

スタックにローカル変数とる場合も、利用頻度の高いものが 5ビットオフセット範囲 になるように変数の並びを気にかけたりします。

 どの CPU でも凝りだすと大なり小なり汚くなるし、慣用表現もいろいろありますが、 なまじ凝ったモードがなくて選択肢がなく、一意に命令が使われるCPU(8086とか)のほうが 相対的に気が楽に作業できてるように思います。


 pshs/puls/pshu/pulu

凍結

6809のアセンブラ命令は、 sex (Sign EXtend)命令とかの名前で話題になることがありますが、 pshs,puls,pshu,pulu なんかは命名失敗の見本じゃないでしょうか。
(非英語圏の人間限定なのかもだけど)

push,pull の略でpsh,pul、それに s|u レジスタ名がついたものですが、 似た字面が並んでいるため、pshs(puls)と間違って puls(pshs)と書いても、なかなか気づきにくいのでした。

しかも動作が真逆なため暴走しやすい... デバッガが今の世のように当たり前に使えたら多少違うかもだけど、 ソースを追っかけていて何度通過しても気づけないことも。

字数は仕方ないにしても、せめて他のアセンブラのようにpopなら pshs,pops,pshu,popu で多少なりとも視認しやすかったのに...

モトローラの中の人が気をつけてネーミングしてくれてたら発生しなかったバグ なのにぃ、てもんです。
(6800からの流れや当時の開発環境の制約もあるだろうけど)

  • 似たものを似た名前にしたほうが綺麗

という感覚がどこかあるものですが、真逆の動作をするモノに 関しては、むしろ、

  • 見た目/字面を変えて違うことを認識しやすくすることが大事

ということを強く教えられました(反面教師だなあ、で)。

open/close とか, begin/end等 プログラムやり始めた当初は書いてて字数がそろわないことに どこか不細工みたいに感じた時もあったけれど、 慣れると真逆な操作のペアはバランスをくづしているほうが 安心するようになってました。 (というか揃えてる命名があると誰かミスってないか気になる)

なんで、C/C++等で set/get 系関数を字面だけでなく引数まで 同じにするのは勘弁してほしい (まあ先頭が違うからそんな読み間違えることはなさそうだけれど).