6800と6809の互換性 [6809]
今回は製作記事ではなくて、インストラクションセットの話
あらためて言うまでもないが、6809は6800とオブジェクトレベルでは互換性はない。が、全くの別物というわけではない。あくまで6800、正確には6801を拡張/変更したものであり、両方に存在する命令の多くはマシンコードも同じである。
残念ながら、全てが同一でないし、6800から削られた命令の中にはなくては困るものもあり、またその代替となる新規命令も当然のように元とはマシンコードがことなるため、同一オブジェクトで6800、6809両方で動作させる事は不可能に近い。
6800にたいしての6809の変更点であるが、
CPUはメモリ上にあるデータを処理していくという事を基本として、その部分の強化に重点が置かれていると思う。
そのためにインデックスレジスタYとユーザスタックポインタを追加し、アドレッシングモードの大幅な拡張が行われている。
それに対して特定のレジスタに特化した命令(コンディションコードのセット/リセット等)、レジスタ間の命令(TAB,TBA等)は削除されている。
CPU(レジスタ)-メモリ間の転送と処理(演算等)を柔軟に行えるように強化変更されている。
では、6800に対してどういう変更が行われているのであろうか?
実際には6801に対して変更されているので、6801に対してみてみる。
どのCPUでもそうだがマシンコードは適当に割り振られているわけではなく、特定のビットに命令の種類等が割り振られている。
8080ならb7b6の上位2bitが転送、演算、分岐等の命令の種類を示し、続くb5b4b3の3bitがディスティネーション、b2b1b0の3bitがソースのような感じにだいたいなっている。
もちろん、分岐命令ではソース/ディスティネーションのところは別の意味となる。
6800はどうか?大雑把に言うと
最上位ビットが1、マシンコードで$8x以降に関しては
上記の表より、例えばマシンコードが
10100110(=$A6)はLDAAのインデックスアドレッシングであり、インデックスアドレッシングは2バイト目がオフセットなので、オフセットが5の場合はアセンブルリスト風に書けば
となる。
上位4bitが0000~0111に関しては
主にオペランドをとらないInherentとRelativeアドレッシングをとる分岐命令が存在するが、
b5b4が10,11となる$6x,$7xは、IndexedおよびExtendedアドレッシングのシフト、ローテート命令が並んでいる。
それ以外では$2xの行が条件ブランチ命令、$0x,1x,3x,4x,5xはInherentアドレッシングの命令が、下位4bitを命令種別としてわりときれいに並んでいる。
6800から削られた命令は$0x,$1xの行にあるので、この2行からごっそり削り取られ、新規命令が追加された形になる。
追加された命令にはDirectアドレッシングをとるものがあり、Directアドレッシングのマシンコードは上の表よりb5b4が01なので$1xに割り振られた、
のかと思いきや、なぜか$0xの行に並んでいる。
その影響で元から存在するNOP命令のマシンコードが$01から$22に変更されている。
それ以外では継承されている命令のマシンコードに変更はないようである。$00~$7Fに関しては。
後半($80~)で変更があるのは$xEと$xFの2列。
$8E,$9E,$AE,$BEがLDS,$9F,$AF,$BFがSTSとスタックポインタに関する命令だったのが
LDXとSTXに変更。LDX,STXは$Bx~$Fxの$xE,$xFの列にあったのでずらした感じになる。
かわりに$Bx~$FxのE,F列にスタックポインタ命令が入っているので入れ替わったようになっているが、実際に入ったのはユーザスタックポインタに関する命令LDU,STUであり、システムスタックポインタのPage2の$Bx~$Fxの$xE,$xF列に移動している。
Page2命令はプリフィクスコード$10がつくので、システムスタックポインタへのロードストアは
命令長、実行時間ともに長くなる。
あらたに追加されたインデックスレジスタYに関する命令群もPage2に存在する。
マシンコードもインデックスレジスタXに関するLDX,STX,CMPXと同じ配置なのでプリフィクスコード$10がつけばY、つかなければXに対する命令となる。
Page3も存在し(プリフィクスコード$11)、SWI命令はPage2がSWI2、Page3がSWI3となる。
Page3にはそれ以外にスタックポインタの比較命令が存在する。
コードマップを見る限り、アドレッシングモードは6800からあいかわらずの
Inherent,Immidiate,Direct,Indexed,Extenedの5つしかない。
マニュアルを見てもまとめられた命令表にはその5つしかなく、命令表を見比べただけでは6800との差はあまりない。
では6809ではアドレッシングモードが大幅に拡張されているが、どうなっているのであろうか?
追加されたアドレッシングモードは
全てインデックスレジスタを介したアドレッシングモードである。
したがってインデックスアドレッシングを拡張する形で追加されている。
6800のインデックスアドレッシングは第2バイトがオフセット値となるが、6809では第2バイトがポストバイトコードとなり、このポストバイトコードによって数あるインデックスアドレッシングモードから具体的なアドレッシングモードが決まる。
このうち上位4bitが0の場合がゼロ・オフセット・インデックスで6800の
インデックスアドレッシングとほぼ同じものであるが、符号付なのでオフセットは-8~+7となる。
6800、6809ともに存在する命令でインデックスアドレッシングを使い、オフセットを0~7の範囲に留めておくとマシンコードは同一となるので、上記で示した
LDA #5,X
という命令は6809でも同一のマシンコードとなる。
命令表を見比べた限りでは6800/1と6809の違いはあまりなく、6800 -> 6801 -> 6809と順当に進化していっているような印象で、同一命令の大部分はマシンコードも同じなため、共通の命令だけを使っていれば共有オブジェクトコードができるのでは?という錯覚に私などは陥ってしまう。
実際にはマシンコードマップが一部変更されているので完全上位互換とはいかないが
アセンブリ言語レベルでは小変更でアセンブルし直せばすむレベルにはなっている。
6809の真骨頂は拡張された部分にあるのだが。
ほぼ文字だけの長文にお付き合いいただき、ありがとうございました。
あらためて言うまでもないが、6809は6800とオブジェクトレベルでは互換性はない。が、全くの別物というわけではない。あくまで6800、正確には6801を拡張/変更したものであり、両方に存在する命令の多くはマシンコードも同じである。
残念ながら、全てが同一でないし、6800から削られた命令の中にはなくては困るものもあり、またその代替となる新規命令も当然のように元とはマシンコードがことなるため、同一オブジェクトで6800、6809両方で動作させる事は不可能に近い。
6800にたいしての6809の変更点であるが、
CPUはメモリ上にあるデータを処理していくという事を基本として、その部分の強化に重点が置かれていると思う。
そのためにインデックスレジスタYとユーザスタックポインタを追加し、アドレッシングモードの大幅な拡張が行われている。
それに対して特定のレジスタに特化した命令(コンディションコードのセット/リセット等)、レジスタ間の命令(TAB,TBA等)は削除されている。
CPU(レジスタ)-メモリ間の転送と処理(演算等)を柔軟に行えるように強化変更されている。
では、6800に対してどういう変更が行われているのであろうか?
実際には6801に対して変更されているので、6801に対してみてみる。
どのCPUでもそうだがマシンコードは適当に割り振られているわけではなく、特定のビットに命令の種類等が割り振られている。
8080ならb7b6の上位2bitが転送、演算、分岐等の命令の種類を示し、続くb5b4b3の3bitがディスティネーション、b2b1b0の3bitがソースのような感じにだいたいなっている。
もちろん、分岐命令ではソース/ディスティネーションのところは別の意味となる。
6800はどうか?大雑把に言うと
最上位ビットが1、マシンコードで$8x以降に関しては
b7 | b6 | 対象レジスタ |
---|---|---|
1 | 0 | AccA |
1 | 1 | AccB |
b5 | b4 | アドレッシングモード |
---|---|---|
0 | 0 | Immidiate |
0 | 1 | Direct |
1 | 0 | Indexed |
1 | 1 | Extended |
b3 | b2 | b1 | b0 | 命令種別 |
---|---|---|---|---|
0 | 0 | 0 | 0 | SUB |
0 | 0 | 0 | 1 | CMP |
0 | 0 | 1 | 0 | SBC |
0 | 0 | 1 | 1 | SUBD(6801),ADDD(6801) |
0 | 1 | 0 | 0 | AND |
0 | 1 | 0 | 1 | BIT |
0 | 1 | 1 | 0 | LDA |
0 | 1 | 1 | 1 | STA |
1 | 0 | 0 | 0 | EOR |
1 | 0 | 0 | 1 | ADC |
1 | 0 | 1 | 0 | ORA |
1 | 0 | 1 | 1 | ADD |
1 | 1 | 0 | 0 | CMP,LDD(6801) |
1 | 1 | 0 | 1 | JSR(BBSR),STD(6801) |
1 | 1 | 1 | 0 | LDS,LDX |
1 | 1 | 1 | 1 | STS,STX |
上記の表より、例えばマシンコードが
10100110(=$A6)はLDAAのインデックスアドレッシングであり、インデックスアドレッシングは2バイト目がオフセットなので、オフセットが5の場合はアセンブルリスト風に書けば
A6 | 05 | LDAA | #5,X |
となる。
上位4bitが0000~0111に関しては
主にオペランドをとらないInherentとRelativeアドレッシングをとる分岐命令が存在するが、
b5b4が10,11となる$6x,$7xは、IndexedおよびExtendedアドレッシングのシフト、ローテート命令が並んでいる。
それ以外では$2xの行が条件ブランチ命令、$0x,1x,3x,4x,5xはInherentアドレッシングの命令が、下位4bitを命令種別としてわりときれいに並んでいる。
6800から削られた命令は$0x,$1xの行にあるので、この2行からごっそり削り取られ、新規命令が追加された形になる。
追加された命令にはDirectアドレッシングをとるものがあり、Directアドレッシングのマシンコードは上の表よりb5b4が01なので$1xに割り振られた、
のかと思いきや、なぜか$0xの行に並んでいる。
その影響で元から存在するNOP命令のマシンコードが$01から$22に変更されている。
それ以外では継承されている命令のマシンコードに変更はないようである。$00~$7Fに関しては。
後半($80~)で変更があるのは$xEと$xFの2列。
$8E,$9E,$AE,$BEがLDS,$9F,$AF,$BFがSTSとスタックポインタに関する命令だったのが
LDXとSTXに変更。LDX,STXは$Bx~$Fxの$xE,$xFの列にあったのでずらした感じになる。
かわりに$Bx~$FxのE,F列にスタックポインタ命令が入っているので入れ替わったようになっているが、実際に入ったのはユーザスタックポインタに関する命令LDU,STUであり、システムスタックポインタのPage2の$Bx~$Fxの$xE,$xF列に移動している。
Page2命令はプリフィクスコード$10がつくので、システムスタックポインタへのロードストアは
命令長、実行時間ともに長くなる。
あらたに追加されたインデックスレジスタYに関する命令群もPage2に存在する。
マシンコードもインデックスレジスタXに関するLDX,STX,CMPXと同じ配置なのでプリフィクスコード$10がつけばY、つかなければXに対する命令となる。
Page3も存在し(プリフィクスコード$11)、SWI命令はPage2がSWI2、Page3がSWI3となる。
Page3にはそれ以外にスタックポインタの比較命令が存在する。
コードマップを見る限り、アドレッシングモードは6800からあいかわらずの
Inherent,Immidiate,Direct,Indexed,Extenedの5つしかない。
マニュアルを見てもまとめられた命令表にはその5つしかなく、命令表を見比べただけでは6800との差はあまりない。
では6809ではアドレッシングモードが大幅に拡張されているが、どうなっているのであろうか?
追加されたアドレッシングモードは
- ゼロ・オフセット・インデックス(6800のインデックスアドレッシングとほぼ同等)
- コンスタント・オフセット・インデックス
- アキュムレータ・オフセット・インデックス
- オート・インクリメント/デクリメント・インデックス
- インデックス・インダイレクト
全てインデックスレジスタを介したアドレッシングモードである。
したがってインデックスアドレッシングを拡張する形で追加されている。
6800のインデックスアドレッシングは第2バイトがオフセット値となるが、6809では第2バイトがポストバイトコードとなり、このポストバイトコードによって数あるインデックスアドレッシングモードから具体的なアドレッシングモードが決まる。
このうち上位4bitが0の場合がゼロ・オフセット・インデックスで6800の
インデックスアドレッシングとほぼ同じものであるが、符号付なのでオフセットは-8~+7となる。
6800、6809ともに存在する命令でインデックスアドレッシングを使い、オフセットを0~7の範囲に留めておくとマシンコードは同一となるので、上記で示した
LDA #5,X
という命令は6809でも同一のマシンコードとなる。
命令表を見比べた限りでは6800/1と6809の違いはあまりなく、6800 -> 6801 -> 6809と順当に進化していっているような印象で、同一命令の大部分はマシンコードも同じなため、共通の命令だけを使っていれば共有オブジェクトコードができるのでは?という錯覚に私などは陥ってしまう。
実際にはマシンコードマップが一部変更されているので完全上位互換とはいかないが
アセンブリ言語レベルでは小変更でアセンブルし直せばすむレベルにはなっている。
6809の真骨頂は拡張された部分にあるのだが。
ほぼ文字だけの長文にお付き合いいただき、ありがとうございました。
コメント 0