前の10件 | -
6809でオリジナルモニタ(2) [6809]
前回は6801用モニタをニーモニック変換等でとりあえず動くようにしたが、その状態では起動はするがまともには動作しない。
1.変更点はモニタコマンドとしては以下の3つ。
(1)Rコマンド
レジスタ表示/編集コマンドは6809で追加されたレジスタも表示/編集できるように修正。
(2)Bコマンド
ブレークポイントコマンド、というよりブレーク後の動作はレジスタ追加にともないスタックが違うので対応。
(3)Gコマンド
実行コマンドはブレークポイントと関連があり、レジスタを全プッシュしてRTIでユーザプログラムへ分岐させているのでブレーク動作と同様に修正。
RTIはIRQとFIRQを判別するためCCRのEビットをチェックする。CCRをスタックにプッシュする前にEビットをたてておく。
2.その他変更点
USB-シリアル変換等に使っているPICは10ms間隔で短パルスをだしていて、6809ボードはそれをFIRQに受けている。したがってFIIRQをシステムタイマとして使用。実際の処理は他のタイマ対応ボードと同様に、内部カウンタをカウントアップするだけ。
FIRQを使用するにはコンディションコードレジスタのFビットをクリア。
3.簡単なテストプログラム。
各レジスタの値を変更して終了するだけのプログラムを作成。
Lで読み込んでGで実行し、モニタ復帰時に表示されるユーザプログラム終了時レジスタの値がセットした値と一致するか?
一致しているのでだいたい動作している模様。
その他、6809らしくプログラムを書き換えようかと思ったが、元々の6800用から6801用変更時にもそのままにしている部分も多く、面倒くさいのでとりあえずおいといて気が向いたら変更していこうかと思う。
一応、C言語でいうところのmemcpyとかstrcpyみたいな内部ルーチンがあって、そういうブロック転送的なところにはX以外にYレジスタを使うよう変更してみた。
1.変更点はモニタコマンドとしては以下の3つ。
(1)Rコマンド
レジスタ表示/編集コマンドは6809で追加されたレジスタも表示/編集できるように修正。
(2)Bコマンド
ブレークポイントコマンド、というよりブレーク後の動作はレジスタ追加にともないスタックが違うので対応。
(3)Gコマンド
実行コマンドはブレークポイントと関連があり、レジスタを全プッシュしてRTIでユーザプログラムへ分岐させているのでブレーク動作と同様に修正。
RTIはIRQとFIRQを判別するためCCRのEビットをチェックする。CCRをスタックにプッシュする前にEビットをたてておく。
2.その他変更点
USB-シリアル変換等に使っているPICは10ms間隔で短パルスをだしていて、6809ボードはそれをFIRQに受けている。したがってFIIRQをシステムタイマとして使用。実際の処理は他のタイマ対応ボードと同様に、内部カウンタをカウントアップするだけ。
FIRQを使用するにはコンディションコードレジスタのFビットをクリア。
3.簡単なテストプログラム。
各レジスタの値を変更して終了するだけのプログラムを作成。
Lで読み込んでGで実行し、モニタ復帰時に表示されるユーザプログラム終了時レジスタの値がセットした値と一致するか?
一致しているのでだいたい動作している模様。
その他、6809らしくプログラムを書き換えようかと思ったが、元々の6800用から6801用変更時にもそのままにしている部分も多く、面倒くさいのでとりあえずおいといて気が向いたら変更していこうかと思う。
一応、C言語でいうところのmemcpyとかstrcpyみたいな内部ルーチンがあって、そういうブロック転送的なところにはX以外にYレジスタを使うよう変更してみた。
6809でオリジナルモニタ(1) [6809]
色々手を出して全てが中途半端になってしまっているが、今回は6809。
前回の6800と6809の話の続きでもある。
新しく6809ボード。
ACIA(MC6850)とUSB-COM変換のPICといういつもの構成。6802ボードのCPUを6809に変えただけでもある。
ここでは初見ながら既にリビジョンがC(苦笑)。新しくと言いながらも製作したのは約1年前だし色々ポカやって、実はこれもジャンパ飛ばしていてリビジョンDに進むのが決定している。
まずはオリジナルモニタを移植。
MC6802ボード用につくったモニタをベースにMC6801(HD6303)向けに修正したので、今度はMC6801のモニタをMC6809用に修正。
6303用モニタがベースなので、まずは内蔵ペリフェラル関係のものをごっそり削る。
かわりにACIA関係をMC6802モニタからコピー。
追加された割込(FIRQ,SWI2,SW#)を念のため実装。ただしRTIするだけ。
メモリマップはほぼ変更なし。
この状態でとりあえずアセンブルしてみる。
そしてエラーを修正していく。
(1)スタック関連
まず、6809になって大きく変わったのがスタック関係。
ユーザスタックポインタが追加されただけでなく、命令も大きく変わっている。
6800はpsha,pshb,pula,pulbと、個々のレジスタ(アキュムレータ)に対して個々の命令を割り当てている。インデックスレジスタに対するモノがないのが、個人的に感じる6800の一番の問題点。これは6801になって追加されている。
6809はシステムスタックポインタ、ユーザスタックポインタに対してそれぞれpshs,puls,pshu,puluとなっている。
どのレジスタを退避/復帰するかはオペランドで指定する。これは
pshs a,b,x,y
とまとめて指定できるのは非常に便利。
したがってスタックに関する命令は全て変更。
(2)コンディションコードレジスタ関連
コンディションコード関係は6800/1ではビット毎に個別のセット/リセット命令があったが、6809ではORとANDで一括でセット/リセット。ニーモニックはORCC、ANDCC。
つまり、OR,ANDの論理演算命令がアキュムレータに対してだけでなく、コンディションコードレジスタにまで拡張されているという解釈。ただしイミディエイトアドレッシングしか使えない。
割込マスクのセット/リセットはシステム関係をやらない限りあまり使う事はないが、キャリーのセット/リセットぐらいはよく使うので要変更。
(3)インデックスレジスタのインクリメント/デクリメント
6809ではなくなっている。
INX,DEXは特定レジスタ向けの特定命令だったという解釈なのだろうか?アキュムレータに対するINC,DECはなくなったわけではない。
INC,DECは簡潔で便利なんだが、
LEAX 1,X
に変更。
まぁ+3したいときは
LEAX 3,X
とできるのでこれも便利といえば便利。
(4)ニーモニック変更
6800/1 →6809変更に伴う命令の変更は以上だが、
大量にでたアセンブルエラーは
本来6800/1、6809どちらにもある命令なのだがニーモニック表記が変更されている。
LDAA等は確かにくどいとは思うが、同じ命令で大半はマシンコードも同じ、さらにCPU別になっているとはいえソースも共有されている同じモトローラのアセンブラなんだから通してくれても良いと思う。
以上、もろもろ修正しただけでとりあえず動くことは動く。
レジスタ増えてスタックが変わってしまっているので、ブレークポイントコマンドなんかはたぶんおかしくなるだろうが。
では次に6809固有の命令を使って修正していき、モニタを完成させたい。
前回の6800と6809の話の続きでもある。
新しく6809ボード。
ACIA(MC6850)とUSB-COM変換のPICといういつもの構成。6802ボードのCPUを6809に変えただけでもある。
ここでは初見ながら既にリビジョンがC(苦笑)。新しくと言いながらも製作したのは約1年前だし色々ポカやって、実はこれもジャンパ飛ばしていてリビジョンDに進むのが決定している。
まずはオリジナルモニタを移植。
MC6802ボード用につくったモニタをベースにMC6801(HD6303)向けに修正したので、今度はMC6801のモニタをMC6809用に修正。
6303用モニタがベースなので、まずは内蔵ペリフェラル関係のものをごっそり削る。
かわりにACIA関係をMC6802モニタからコピー。
追加された割込(FIRQ,SWI2,SW#)を念のため実装。ただしRTIするだけ。
メモリマップはほぼ変更なし。
この状態でとりあえずアセンブルしてみる。
そしてエラーを修正していく。
(1)スタック関連
まず、6809になって大きく変わったのがスタック関係。
ユーザスタックポインタが追加されただけでなく、命令も大きく変わっている。
6800はpsha,pshb,pula,pulbと、個々のレジスタ(アキュムレータ)に対して個々の命令を割り当てている。インデックスレジスタに対するモノがないのが、個人的に感じる6800の一番の問題点。これは6801になって追加されている。
6809はシステムスタックポインタ、ユーザスタックポインタに対してそれぞれpshs,puls,pshu,puluとなっている。
どのレジスタを退避/復帰するかはオペランドで指定する。これは
pshs a,b,x,y
とまとめて指定できるのは非常に便利。
したがってスタックに関する命令は全て変更。
変更前 | 変更後 |
---|---|
PSHA | PSHS A |
PSHB | PSHS B |
PULA | PULS A |
PULB | PULS B |
PSHX | PSHS X |
PULX | PULS X |
(2)コンディションコードレジスタ関連
コンディションコード関係は6800/1ではビット毎に個別のセット/リセット命令があったが、6809ではORとANDで一括でセット/リセット。ニーモニックはORCC、ANDCC。
つまり、OR,ANDの論理演算命令がアキュムレータに対してだけでなく、コンディションコードレジスタにまで拡張されているという解釈。ただしイミディエイトアドレッシングしか使えない。
割込マスクのセット/リセットはシステム関係をやらない限りあまり使う事はないが、キャリーのセット/リセットぐらいはよく使うので要変更。
変更前 | 変更後 |
---|---|
SEI | ORCC #$10 |
CLI | ANDCC #$EF |
SEC | ORCC #$01 |
CLC | ANDCC #$FE |
(3)インデックスレジスタのインクリメント/デクリメント
6809ではなくなっている。
INX,DEXは特定レジスタ向けの特定命令だったという解釈なのだろうか?アキュムレータに対するINC,DECはなくなったわけではない。
INC,DECは簡潔で便利なんだが、
LEAX 1,X
に変更。
まぁ+3したいときは
LEAX 3,X
とできるのでこれも便利といえば便利。
変更前 | 変更後 |
---|---|
INX | LEAX #1,X |
DEX | LEAX #-1,X |
(4)ニーモニック変更
6800/1 →6809変更に伴う命令の変更は以上だが、
大量にでたアセンブルエラーは
LDAA | LDAB | STAA | STAA |
本来6800/1、6809どちらにもある命令なのだがニーモニック表記が変更されている。
LDAA等は確かにくどいとは思うが、同じ命令で大半はマシンコードも同じ、さらにCPU別になっているとはいえソースも共有されている同じモトローラのアセンブラなんだから通してくれても良いと思う。
変更前 | 変更後 |
---|---|
LDAA | LDA |
LDAB | LDB |
STAA | STA |
STAB | STB |
以上、もろもろ修正しただけでとりあえず動くことは動く。
レジスタ増えてスタックが変わってしまっているので、ブレークポイントコマンドなんかはたぶんおかしくなるだろうが。
では次に6809固有の命令を使って修正していき、モニタを完成させたい。
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の真骨頂は拡張された部分にあるのだが。
ほぼ文字だけの長文にお付き合いいただき、ありがとうございました。
7SEG表示 & 16進キーボード(ワンボードマイコン風) [6303]
I/O関連の続き。
その先に接続するものとして、7SEG LEDと16進キーボードを用意。
初期のワンボードマイコンの雰囲気を楽しむ。
制作したボードがこれ
7SEGが8桁と5×5のキーボード。TK-80風。
私が持っているのはTK-85なので、0~9,A~F以外のコマンドキー(?)はTK-85を参考に割り付け。
他にもキー(ボタン)がついているのは、このボードは一応8279に接続するのを前提としているため。SHIFTとかCTRLとかは8279の機能。
8255Aと共通で使えるようにするため、PPIボードで使っている34Pのコネクタにしてpinも割り振ったが、全く同じようには使えない。8255Aがビット単位で入出力を指定できればほぼいけたのだが。
今回は8255Aに接続。使ったボードがこれ
前々回で紹介したPPI2個のボードとは別で1個のもの。設計自体は2個のものよりずっと前に終わっていたのだが、ポカをやらかして作り直して後になってしまった。
ちなみにPPI2個ボードでも同じソフトが動くことは確認済み。
8279ならスキャン操作は勝手にやってくれるのだが、8255Aではそういうわけにはいかないのでタイマの使えるボードとしてHD6303のものを用意。
タイマの使えるボード用のモニタは、システムタイマとして10ms間隔のタイマを入れている。実際にはカウンタ変数をカウントアップしているだけなのでが、ちょっと前にユーザ割り込みルーチンが用意されていれば、それを呼び出すように変更している。
USB-COM変換に使っているPICには10ms間隔でタイマ出力させているが、実際に使っているのは独立した割り込み入力がある8085ボードだけ。
Z80ボードはモード2割り込みを使っているので、/INT端子に入れても使えない。
MC6802はACIAをチェックして、ACIAが割り込みだしていなかったらタイマ割り込みで良いんだろうけど、そこまでやっていない。
HD6303ボードで10msのシステムタイマ割り込みを使ってダイナミック点灯をやってみたが、見事にちらつく(苦笑)。
10ms点灯して70ms消灯しているから、まぁそうなるか。
HD603X/Yはタイマをもう1本持っているので、それで2msタイマを生成。2msだとちらつきなし。
ただ2msだとどうしてもキーはチャタリング拾うので2回読みにする。10msだと拾わないけど。
接続はこんな感じ。
本当は右端2桁も表示されているのだが、静止画だとダイナミック点灯は全部写らない。
今までは基本ソフト製作がメインだったのでROM書き換えては差し替えとやっていた都合上、メモリボードを前面にだしていたが、今は作成したソフトをロードするだけなのでCPUボードを前に。
とりあえずだが、
左4桁にアドレス表示、右2桁にそのアドレス内データ表示。
INC/DECキーで表示アドレス変更。
16進キーで数値入力してEnterキーでメモリ内容変更。
ADDRESS SETキーでアドレス変更。
ここまではやってみた。
いずれは昔のワンボードのように動作するようにしてみたいと思う。
その先に接続するものとして、7SEG LEDと16進キーボードを用意。
初期のワンボードマイコンの雰囲気を楽しむ。
制作したボードがこれ
7SEGが8桁と5×5のキーボード。TK-80風。
私が持っているのはTK-85なので、0~9,A~F以外のコマンドキー(?)はTK-85を参考に割り付け。
他にもキー(ボタン)がついているのは、このボードは一応8279に接続するのを前提としているため。SHIFTとかCTRLとかは8279の機能。
8255Aと共通で使えるようにするため、PPIボードで使っている34Pのコネクタにしてpinも割り振ったが、全く同じようには使えない。8255Aがビット単位で入出力を指定できればほぼいけたのだが。
今回は8255Aに接続。使ったボードがこれ
前々回で紹介したPPI2個のボードとは別で1個のもの。設計自体は2個のものよりずっと前に終わっていたのだが、ポカをやらかして作り直して後になってしまった。
ちなみにPPI2個ボードでも同じソフトが動くことは確認済み。
8279ならスキャン操作は勝手にやってくれるのだが、8255Aではそういうわけにはいかないのでタイマの使えるボードとしてHD6303のものを用意。
タイマの使えるボード用のモニタは、システムタイマとして10ms間隔のタイマを入れている。実際にはカウンタ変数をカウントアップしているだけなのでが、ちょっと前にユーザ割り込みルーチンが用意されていれば、それを呼び出すように変更している。
USB-COM変換に使っているPICには10ms間隔でタイマ出力させているが、実際に使っているのは独立した割り込み入力がある8085ボードだけ。
Z80ボードはモード2割り込みを使っているので、/INT端子に入れても使えない。
MC6802はACIAをチェックして、ACIAが割り込みだしていなかったらタイマ割り込みで良いんだろうけど、そこまでやっていない。
HD6303ボードで10msのシステムタイマ割り込みを使ってダイナミック点灯をやってみたが、見事にちらつく(苦笑)。
10ms点灯して70ms消灯しているから、まぁそうなるか。
HD603X/Yはタイマをもう1本持っているので、それで2msタイマを生成。2msだとちらつきなし。
ただ2msだとどうしてもキーはチャタリング拾うので2回読みにする。10msだと拾わないけど。
接続はこんな感じ。
本当は右端2桁も表示されているのだが、静止画だとダイナミック点灯は全部写らない。
今までは基本ソフト製作がメインだったのでROM書き換えては差し替えとやっていた都合上、メモリボードを前面にだしていたが、今は作成したソフトをロードするだけなのでCPUボードを前に。
とりあえずだが、
左4桁にアドレス表示、右2桁にそのアドレス内データ表示。
INC/DECキーで表示アドレス変更。
16進キーで数値入力してEnterキーでメモリ内容変更。
ADDRESS SETキーでアドレス変更。
ここまではやってみた。
いずれは昔のワンボードのように動作するようにしてみたいと思う。
6801/6301でオリジナルモニタ [6801]
オリジナルモニタシリーズ、今度はMC6801系です。
MC6800版はMC6802ボードで確認してだいたい動作しているのでベースにします。
とりあえずCPU依存な部分を除いてそのまま流用。
ただし今後各種I/Oを動作させるために、ユーザ設定の割り込みルーチンを使えるように変更。
今まではROM内固定ルーチンのみだったが、RAM上にユーザ割り込みベクタエリアを確保し、各割り込み毎にユーザベクタをチェックし、設定されていればそのルーチンを呼び出すように変更。
通信部分はACIAから内蔵SCIへ。
モトローラと日立セカンドソースの6801(3)と、その日立のCMOS版であるHD6301(3)R/Sと、さらに強化版のHD6301(3)X/Yとでソースを共有することにする。
HD6301X/Yは内蔵I/Oが増えて、その分ZEROページの占有領域が増えているがHD6301R/Sに単純に追加されているので、共通部分は機能もメモリマップも同じ。追加されたのはタイマがもう1本とポート。モニタがその追加部分を使うことはないので、占有ZRAMが増えても問題なし。
一部変更があるが、設定用のレジスタでアドレスは同じ。ブート直後にそれぞれにあわせて設定するだけなので、これも問題なし。さすがにバイナリ共通とまではいかないが、ちょっと編集してアセンブルし直しでいける。
まずはMC6801で確認。このボードで。
多少リビジョンが上がっているが初期から使っているボードで、以前にも書いたと思うがNMOS版の6801(3)では動かないので、日立のHD6303で確認。
動作OKなのでソースをMC6801向けにカスタマイズ。
基本的には16bi処理をDレジスタ用命令に書き換えるだけ。
インデックスレジスタ退避/復帰もスタックで、と思ったが今回はパス。
これも動作OKなので、次はHD6303X/Y。このボードで。
以前のボードから変更していて、外部I/Oを使用できるようにしている。68系のCPUボードはI/Oの上位8bitを設定できるようにして、80系と同じ256バイトメモリ空間を占有する。
これも初期化部分を少し変更するだけで問題なく動く。
これでタイマが使えるボードで基本となるモニタが動作するようになったので、I/Oボードを色々試すことができそう。
ただし、MC6801ボードはシングルボード化してしまってバスを出すようにしていないので、作成したI/OボードのテストはHD6303ボードメインかな?
MC6800版はMC6802ボードで確認してだいたい動作しているのでベースにします。
とりあえずCPU依存な部分を除いてそのまま流用。
ただし今後各種I/Oを動作させるために、ユーザ設定の割り込みルーチンを使えるように変更。
今まではROM内固定ルーチンのみだったが、RAM上にユーザ割り込みベクタエリアを確保し、各割り込み毎にユーザベクタをチェックし、設定されていればそのルーチンを呼び出すように変更。
通信部分はACIAから内蔵SCIへ。
モトローラと日立セカンドソースの6801(3)と、その日立のCMOS版であるHD6301(3)R/Sと、さらに強化版のHD6301(3)X/Yとでソースを共有することにする。
HD6301X/Yは内蔵I/Oが増えて、その分ZEROページの占有領域が増えているがHD6301R/Sに単純に追加されているので、共通部分は機能もメモリマップも同じ。追加されたのはタイマがもう1本とポート。モニタがその追加部分を使うことはないので、占有ZRAMが増えても問題なし。
一部変更があるが、設定用のレジスタでアドレスは同じ。ブート直後にそれぞれにあわせて設定するだけなので、これも問題なし。さすがにバイナリ共通とまではいかないが、ちょっと編集してアセンブルし直しでいける。
まずはMC6801で確認。このボードで。
多少リビジョンが上がっているが初期から使っているボードで、以前にも書いたと思うがNMOS版の6801(3)では動かないので、日立のHD6303で確認。
動作OKなのでソースをMC6801向けにカスタマイズ。
基本的には16bi処理をDレジスタ用命令に書き換えるだけ。
インデックスレジスタ退避/復帰もスタックで、と思ったが今回はパス。
これも動作OKなので、次はHD6303X/Y。このボードで。
以前のボードから変更していて、外部I/Oを使用できるようにしている。68系のCPUボードはI/Oの上位8bitを設定できるようにして、80系と同じ256バイトメモリ空間を占有する。
これも初期化部分を少し変更するだけで問題なく動く。
これでタイマが使えるボードで基本となるモニタが動作するようになったので、I/Oボードを色々試すことができそう。
ただし、MC6801ボードはシングルボード化してしまってバスを出すようにしていないので、作成したI/OボードのテストはHD6303ボードメインかな?
PPI(8255A)ボード [8bitマイコン]
昨日に続いてパラレルポート。
80系の8255Aというパラレルインテーフェース。
非常にシンプルな石で昔の定番で68系のマイコンシステムであってもよく使われていたが、3組の8bitポートがあり、A、BポートがIN,OUTどちらかにしか設定できず、Cポートのみ上位、下位4bit単位でIN,OUTを切り替えられる、まさしくパラレルポートが難点ではあったか?
今、この手のものはGPIO(General Purpos I/O)という言い方をしてbit単位で使う、つまりbit毎にIN/OUTを指定できるのが普通なのでその辺が使いにくいところではある。
PIAボードと同様にPPIを2個搭載。I/Oコネクタは、PPIが8bitポート3組なので34Pのモノを使用。
このコネクタ、昔Oh!PCという雑誌で連載されていたPC工作入門(だったかな?)の8255インターフェースボードにピン配置を合わせている。
違いは「PC工作入門」の方は±12Vを出しているが、こっちのボードはないのでN.C.
では、昨日に続いてMC6802ボードでテスト。
これまた露出を落としてもわかりにくいが一応動作はOK。ボードが4枚立っているが、昨日のPIAボードが刺さったまま。アドレスが違うので影響なし。
続いて80系CPUで確認。
と思ったら8085ボードが動かない(苦笑)。シリアルでエコーバックするだけの簡単なテストプログラムは動くので、どうやらモニタのようだが、去年8085の記事をあげてからそういえば少し手を入れたような…?
もう1年近く前の事なので何をどういじったのか覚えてない。
やはりGit等でバージョン管理するべきかな?
気を取り直してZ80ボードで確認。
これも光っているのかいないのか、全然わからない写真になってしまっているが一応動作OK。
今後I/Oを試して遊ぶにはタイマは必要になってくるので、タイマ使える8085ボードの方が都合いいのだが…
MC6802ボードもタイマ使えないので、I/Oで遊ぶには別のボードかな?
80系の8255Aというパラレルインテーフェース。
非常にシンプルな石で昔の定番で68系のマイコンシステムであってもよく使われていたが、3組の8bitポートがあり、A、BポートがIN,OUTどちらかにしか設定できず、Cポートのみ上位、下位4bit単位でIN,OUTを切り替えられる、まさしくパラレルポートが難点ではあったか?
今、この手のものはGPIO(General Purpos I/O)という言い方をしてbit単位で使う、つまりbit毎にIN/OUTを指定できるのが普通なのでその辺が使いにくいところではある。
PIAボードと同様にPPIを2個搭載。I/Oコネクタは、PPIが8bitポート3組なので34Pのモノを使用。
このコネクタ、昔Oh!PCという雑誌で連載されていたPC工作入門(だったかな?)の8255インターフェースボードにピン配置を合わせている。
違いは「PC工作入門」の方は±12Vを出しているが、こっちのボードはないのでN.C.
では、昨日に続いてMC6802ボードでテスト。
これまた露出を落としてもわかりにくいが一応動作はOK。ボードが4枚立っているが、昨日のPIAボードが刺さったまま。アドレスが違うので影響なし。
続いて80系CPUで確認。
と思ったら8085ボードが動かない(苦笑)。シリアルでエコーバックするだけの簡単なテストプログラムは動くので、どうやらモニタのようだが、去年8085の記事をあげてからそういえば少し手を入れたような…?
もう1年近く前の事なので何をどういじったのか覚えてない。
やはりGit等でバージョン管理するべきかな?
気を取り直してZ80ボードで確認。
これも光っているのかいないのか、全然わからない写真になってしまっているが一応動作OK。
今後I/Oを試して遊ぶにはタイマは必要になってくるので、タイマ使える8085ボードの方が都合いいのだが…
MC6802ボードもタイマ使えないので、I/Oで遊ぶには別のボードかな?
PIA(MC6821)ボード [8bitマイコン]
今まではほぼCPUのみを動かしてきたので周辺の話。
CPUをスタンドアローンのマイコンとして動かすために、コンソールとしてシリアルは必然的に使ってきたので、今回はパラレルポート。
まずは68系のMC6821。
10×7cmの基板にMC6821を2個。日立製のHD46821のBバージョン。
パターン配線の都合で向きをそろえていないので実装は要注意。
それぞれ26Pでポート出し。
MC6821は8bitポートが2組。それぞれに2bit補助の補助ポート。
各ポート毎に割り込みをだせるようになっているのでジャンパで設定できるようにした。
下4個のLEDとスイッチはMC6821のCA1(2)、CB1(2)確認用。
とりあえずテスト用のボードも作成。
この程度のものはどうせ1枚しか必要としないし、ユニバーサル基板で手配線で組んでもいいのだけど、最近はこの程度のものでも億劫になってきたので(苦笑)
コネクタは26PがPIA(MC6821)用、34PがPPI(8255A)用。
PIAからPAが出力でLED8個、PBが入力でスイッチ。
PPIの場合はさらにPCも出力でLED8個。
テストはMC6802の基板で。
バスは80系と68系で共有できるようにしてはいるが、E信号は80系のCPUボードからは
出すようにしていないので、80系CPUボードからは使えない。
簡単なテストプログラムを組んで、前回の68系モニタからロードして実行。
電源用LEDみたいにスモークモールドのLEDでないので、指向性が強くわかりにくいので露出を落としてみたがそれでもわかりにくいか…
さて、具体的にどう使うかは別の話だが、だいぶ先の話でもあるかな?
CPUをスタンドアローンのマイコンとして動かすために、コンソールとしてシリアルは必然的に使ってきたので、今回はパラレルポート。
まずは68系のMC6821。
10×7cmの基板にMC6821を2個。日立製のHD46821のBバージョン。
パターン配線の都合で向きをそろえていないので実装は要注意。
それぞれ26Pでポート出し。
MC6821は8bitポートが2組。それぞれに2bit補助の補助ポート。
各ポート毎に割り込みをだせるようになっているのでジャンパで設定できるようにした。
下4個のLEDとスイッチはMC6821のCA1(2)、CB1(2)確認用。
とりあえずテスト用のボードも作成。
この程度のものはどうせ1枚しか必要としないし、ユニバーサル基板で手配線で組んでもいいのだけど、最近はこの程度のものでも億劫になってきたので(苦笑)
コネクタは26PがPIA(MC6821)用、34PがPPI(8255A)用。
PIAからPAが出力でLED8個、PBが入力でスイッチ。
PPIの場合はさらにPCも出力でLED8個。
テストはMC6802の基板で。
バスは80系と68系で共有できるようにしてはいるが、E信号は80系のCPUボードからは
出すようにしていないので、80系CPUボードからは使えない。
簡単なテストプログラムを組んで、前回の68系モニタからロードして実行。
電源用LEDみたいにスモークモールドのLEDでないので、指向性が強くわかりにくいので露出を落としてみたがそれでもわかりにくいか…
さて、具体的にどう使うかは別の話だが、だいぶ先の話でもあるかな?
MC6802でオリジナルモニタ [6802]
本業で多忙になってしまったとはいえ、1年近く放置してしまった(苦笑)
何をやっていたのか、どこまでやったのかもわからなくなっていたので
放置期間も長くなってしまったが、とりあえず復活です。
さて
Z80でオリジナルモニタを作成しましたが、そのMC6800版です。
一応動作画面です。
そのうちソフト、ハード共ソース等をGitHubにあげようかと思ってます。
いつになるかはわかりませんが。
コマンドが共通というだけなんですが、MC6802基板も新しくなっています。
放置前に既に更新していたんですがね(苦笑)
MC68B00、HD63B50とともにBバージョン。日立のはCMOS版。
3MHzクロックを与えているので0.75MHz動作です。
メモリ基板も追加でもう1枚実装しました。
テストを繰り返すとROMを何度も抜き差ししてピンを曲げてしまうので
ROM用はZIFソケットにしました。
スペースの関係もあって小型のものですが、レバーが少し堅いです。
色々動作確認をしていて、日立のHD46802だけは動作しませんでした。
本家モトローラのもの、AMIのもの、富士通のMB8870,8871は問題ないのですが、
HD46802はロット違い2種、4個ほど試しましたがどれもNG。
AC特性かDC特性でも違うのかな?
市場上が本家モトローラ
その下が日立のものですが動きませんでした。
その下が独自の拡張がされている富士通のもの
一番下がAMI製。わりと珍しいかな?
とりあえず軽く復活ということで。
ネタは色々あるのですが
何をやっていたのか、どこまでやったのかもわからなくなっていたので
放置期間も長くなってしまったが、とりあえず復活です。
さて
Z80でオリジナルモニタを作成しましたが、そのMC6800版です。
一応動作画面です。
そのうちソフト、ハード共ソース等をGitHubにあげようかと思ってます。
いつになるかはわかりませんが。
コマンドが共通というだけなんですが、MC6802基板も新しくなっています。
放置前に既に更新していたんですがね(苦笑)
MC68B00、HD63B50とともにBバージョン。日立のはCMOS版。
3MHzクロックを与えているので0.75MHz動作です。
メモリ基板も追加でもう1枚実装しました。
テストを繰り返すとROMを何度も抜き差ししてピンを曲げてしまうので
ROM用はZIFソケットにしました。
スペースの関係もあって小型のものですが、レバーが少し堅いです。
色々動作確認をしていて、日立のHD46802だけは動作しませんでした。
本家モトローラのもの、AMIのもの、富士通のMB8870,8871は問題ないのですが、
HD46802はロット違い2種、4個ほど試しましたがどれもNG。
AC特性かDC特性でも違うのかな?
市場上が本家モトローラ
その下が日立のものですが動きませんでした。
その下が独自の拡張がされている富士通のもの
一番下がAMI製。わりと珍しいかな?
とりあえず軽く復活ということで。
ネタは色々あるのですが
モトローラフリーアセンブラをWIndowsで [8bitマイコン]
68系の開発にモトローラのフリーアセンブラを使用しているが、これはMS-DOS時代のソフト(いや元々はunix系だったのかな?)で今のWindowsでは直接は動かない。ただこのアセンブラはソースも公開されているのでリコンパイルしてWindowsで動くようにしてみる。
さて、ソースは確かAMIGA版のやつがソース付だったと思ったが、今現在AMIGAは動作出来る状態にない。ネットであさるとGithubで難なく見つかった。
https://github.com/JimInCA/motorola-6800-assembler
ただし、公開者が色々手を入れてるみたいで完全なオリジナルではない。
Linuxでmakeできるようになっているが、このソースを利用してWindowsで動くようにしてみる。
(1)Windows Subsystem for Linux
これはLinuxだからそのまんま。
すっぴんのWindows Subsystem for Linuxはgccもmakeも入ってないのでインストールする必要があるが、makeするだけ。
当然だがWindowsのコマンドプロンプトから実行できるわけではない。
(2)コマンドプロンプトからmake
コマンドプロンプト、あるいはPowerShellからmakeできるか?
まずはVisual C++。
makefileをVisualC向けに書き直してみたがでエラー。
gnu系のmakeとnmakeでは書式が違ったかな?
bcc32(C++Builder)でmakeしてもだめ。Borlandのmakeはnmakeと同じだったような気もする。
もう何年(十何年)?もmakefileなんか書いてないし、すっかり忘れているのでこれ以上追求するのはやめ。
(3)C++ Builder
次に(Vsual Studioでもできるが)C++Builderの統合開発環境。
C++Builderを起動し、新規作成→その他→コンソールアプリケーションでプロジェクトを作る。
ターゲットフレームワークなし。
ソースの種類はC、マルチスレッドとプロジェクトソースの指定のチェックをはずす。
プロジェクトグループとグループ所属の空のプロジェクトが作成される。
プロジェクトグループ名はオリジナルのあわせてmotoasmとでもし、プロジェクトはas0(6800用アセンブラ)と変更しておく。
プロジェクトも一つ同時に作られるがプロジェクト名を
プロジェクトのあるフォルダにアセンブラソースを全部コピー。
プロジェクトas0に対して「プロジェクトに追加」でソースを追加。
ソースはdo*.c、table*.cが各CPUの個別ソースでそれ以外は共通。
なのでプロジェクトas0(6800向アセンブラ)ならdo0.c、table0.cとそれ以外を全部追加。
念のためヘッダファイルもプロジェクトに追加。
プロジェクト新規作成時にできたデフォルトのソースとヘッダは削除。
同様にプロジェクトグループに対してプロジェクト(as1,as4,as5,as9,as11)を新規追加していく。
そしてそれぞれのプロジェクトにソース(do*.c,table*.cだけ各個でそれ以外は全部同じものを指定)を追加していく。
それが終了したら全てのプロジェクトをビルド。as0,as1,as4,as5,as9,as11が一気にビルドされる。
ビルドするとヘッダファイル"unistd.h"がないとエラーがでる。
"unistd.h"はunix系依存のヘッダファイル
エラーがでるinclude行をコメントアウトしてリビルドをかけると警告はでるがエラーもなく成功する。
警告はopen,close,read,write,create,lseek。
今は使わない古い関数ですね。
fopen等に変更すればいいはずだが、ソースを色々いじる必要があるので"io.h"で代用。これで警告もなくなる。
今までのソース等いくつかアセンブルさせてみたが問題なくアセンブルできているもよう。
まぁ全てのCPU版を試したわけではないが、とりあえず問題なさそう。
あとは今使ってるROMライタにあわせて、IntelHexをはけるようにできれば…
さて、ソースは確かAMIGA版のやつがソース付だったと思ったが、今現在AMIGAは動作出来る状態にない。ネットであさるとGithubで難なく見つかった。
https://github.com/JimInCA/motorola-6800-assembler
ただし、公開者が色々手を入れてるみたいで完全なオリジナルではない。
Linuxでmakeできるようになっているが、このソースを利用してWindowsで動くようにしてみる。
(1)Windows Subsystem for Linux
これはLinuxだからそのまんま。
すっぴんのWindows Subsystem for Linuxはgccもmakeも入ってないのでインストールする必要があるが、makeするだけ。
当然だがWindowsのコマンドプロンプトから実行できるわけではない。
(2)コマンドプロンプトからmake
コマンドプロンプト、あるいはPowerShellからmakeできるか?
まずはVisual C++。
makefileをVisualC向けに書き直してみたがでエラー。
gnu系のmakeとnmakeでは書式が違ったかな?
bcc32(C++Builder)でmakeしてもだめ。Borlandのmakeはnmakeと同じだったような気もする。
もう何年(十何年)?もmakefileなんか書いてないし、すっかり忘れているのでこれ以上追求するのはやめ。
(3)C++ Builder
次に(Vsual Studioでもできるが)C++Builderの統合開発環境。
C++Builderを起動し、新規作成→その他→コンソールアプリケーションでプロジェクトを作る。
ターゲットフレームワークなし。
ソースの種類はC、マルチスレッドとプロジェクトソースの指定のチェックをはずす。
プロジェクトグループとグループ所属の空のプロジェクトが作成される。
プロジェクトグループ名はオリジナルのあわせてmotoasmとでもし、プロジェクトはas0(6800用アセンブラ)と変更しておく。
プロジェクトも一つ同時に作られるがプロジェクト名を
プロジェクトのあるフォルダにアセンブラソースを全部コピー。
プロジェクトas0に対して「プロジェクトに追加」でソースを追加。
ソースはdo*.c、table*.cが各CPUの個別ソースでそれ以外は共通。
なのでプロジェクトas0(6800向アセンブラ)ならdo0.c、table0.cとそれ以外を全部追加。
念のためヘッダファイルもプロジェクトに追加。
プロジェクト新規作成時にできたデフォルトのソースとヘッダは削除。
同様にプロジェクトグループに対してプロジェクト(as1,as4,as5,as9,as11)を新規追加していく。
そしてそれぞれのプロジェクトにソース(do*.c,table*.cだけ各個でそれ以外は全部同じものを指定)を追加していく。
それが終了したら全てのプロジェクトをビルド。as0,as1,as4,as5,as9,as11が一気にビルドされる。
ビルドするとヘッダファイル"unistd.h"がないとエラーがでる。
"unistd.h"はunix系依存のヘッダファイル
エラーがでるinclude行をコメントアウトしてリビルドをかけると警告はでるがエラーもなく成功する。
警告はopen,close,read,write,create,lseek。
今は使わない古い関数ですね。
fopen等に変更すればいいはずだが、ソースを色々いじる必要があるので"io.h"で代用。これで警告もなくなる。
今までのソース等いくつかアセンブルさせてみたが問題なくアセンブルできているもよう。
まぁ全てのCPU版を試したわけではないが、とりあえず問題なさそう。
あとは今使ってるROMライタにあわせて、IntelHexをはけるようにできれば…
マイコン制御PIC [8bitマイコン]
今回はPICの話。
ちょっと長いし文章だけなんですみません。
今までのCPUボードには全てPICを載せている。
主にクロック、RESET生成とUSB-シリアル変換に使っている。
元々の動機はUSB-シリアル変換。
今時のPCにはCOMポートがついていない。
この手の遊びをしている人の多くは、市販のUSB-シリアル変換基板と使っているが個人的にはどうもスマートではない。
変換チップをボードに搭載してしまうのも手だが、最近の変換チップは多機能多ピンのものばかりで、ピンのピッチも細かくて手半田はかなり厳しい。以前はフロー制御線を省略した少ピンでピンピッチも比較的広いチップも手に入ったんだけどね。
で、目を付けたのがPIC16F1454。DIP14Pinだから個人でも扱いやすく、小さくあまりスペースを取らない。5V動作というところも古いマイコンの周辺として使うのに都合が良い。なにより安い。
あと、外付けの水晶発振子を必要としない。USBは通信クロックにそれなりの精度を要求するので、ほとんどのUSBマイコンはUSBを使う場合は外部に水晶発振子を必要とするが、これは内部発振でUSBを可能としている珍しいチップ。
ただし、USBが使えるだけあって安定はしているのだろうけど、発信周波数は12MHzぴったりというわけでもなさそうだ。
少ピンとはいえピンはあまるので、7×10cmの小さな基板上のパーツ点数を減らすべく他にも機能を割り当てた。
ファームウェアはUSBのCDCクラスとなるように組む必要があるが、統合開発環境MPLABのプラグインMCC(MPLAB Code Configurator)を使えば自動生成してくる。多少システムにあわせてカスタマイズする必要もあるが。
ではこのマイコン制御チップであるPICの機能であるが
(1)USB-シリアル変換
一番メインとなる部分。
USBのファームは一から作るとなるとかなり面倒だがMCCのおかげでかなり楽ちん。
シリアル側もMCCで生成。これらに限らず内蔵ペリフェラルは全てMCCで。
ドライバと呼ばれる部分を生成するだけなので、もちろん一方で受信したら他方へ送信というメイン処理は自分で書かなくてはいけない。
(2)CPUクロック生成
CPUにクロックを供給。
このPICはシステムクロックを出力する機能があり、システムクロックを1/2**n分周を出力してくれる。
USB機能を使うとシステムクロックは48MHzになるので、生成クロックは
48,24,12,6,3MHz
となる。
Z80だとBバージョンで6MHz。Aだと3MHzにするしかない。
8085だと6MHz入力で3MHz動作。
68系は4分周されるので、6MHz入力で1.5MHzとなりAバージョン。
6809や6303ならCバージョンを使うと12MHz入力で3MHz動作が可能となる。
ただ先にも書いたが発信周波数は正確ではないようで、6MHz生成しているつもりが6.4MHzでていたりする。一方でほぼ6MHzでる場合もあり、これは個体差なのかロット差なのかまだ何ともいえない。
周波数的にいまいち使いにくいが水晶発振子(器)の節約になる。
(3)ボーレートクロック生成
マイコン側8251、6850等のシリアルチップ向けにボーレートクロックを出力。
通常9600bps想定で、その16倍となる153.6Kbpsを出力。6801の場合は8倍の76.8Kbps。
ボーレートの許容誤差は一般的に5%と言われているが、16倍クロック入力の場合だいたい1/16で6.25%。
このボーレートもPICのシステムクロックから生成しているわけで、CPUクロック生成6MHzのつもりが6.4MHzになっているとすると、6.67%のずれで許容範囲外なのだが、PIC内部のシリアルボーレートも、同じPICシステムクロックから生成しているので、ぴったしあって問題なし。あくまで9600からずれているというだけ。
(4)リセット信号生成
パワーオン時とリセット入力ピンがLowになった時に、リセット出力ピンをLowに。
リセット入力ピンがHighになってから約120msリセットを持続。
自分が知る限り一番長いRESETを要求しているのは68000で100ms。
少し余裕を見て120msにしている。
リセットは単純でありながら奥が深く昔からトラブルが多い。
アナログ的要素が強いからでもあるが、マイコンでON-OFFしてやるのが単純で簡単。
マイコンのファームウェアで制御しているわけだからある意味複雑とも言えるが。
リセット入力は使用しているポートがプルアップ付なのでスイッチをつなげるだけ。
(5)タイマ出力
10msでワンショットパルスを出すようにしている。定周期タイマとして使えるように。
10ms経過で単純にソフトでONしてOFFしているだけなので、ひょっとしたらパルスが短すぎて認識できないCPUがあるかもしれないが。
8085ボードではRST7.5に入れて定周期タイマとして使えるようにしている。今のところ問題なく動作している。
8085にあわせて通常LowでHiアクティブ。
その他CPU用では論理を逆にしているが、使っているボードは今のところない。
(6)オプション選択
余ったピンを使って動作選択できるようにしていて、今のところボーレート切替。
リセット中にチェックしてHiで9600、Lowで19200に切り替えるようにしているが、現状使っていないので動作確認はできていない。
とまぁこんな感じに機能を盛り込んだので、Z80ボードなんかはICはこれとZ80CPU,SIOの3チップ構成で済んでいる。
問題点
まだ残っている問題点として、
例えばPCでteratermを端末に利用するとしよう。マイコンボード側のボーレートが9600だからCOMポートの設定も9600にしたとしても、USBの通信速度が9600bpsになるわけではない。USB機器がCDCクラスだからCOMポートの振りをしているだけで、ハードはUSBであり12Mbpsで通信されてしまう。たぶんデータ長とかはソフト的なプロトコルだから意味があるだろうし、ハードフロー制御を使ったらそのようにエミュレーションするからこれも意味があるが、通信速度は無視される。ちなみにPIC側のファームでUSB CDCクラスの通信速度を設定する項目はない。
これはどうなるかというと、たとえばマイコン側のモニタでHEXファイルをロードしようとした時、teratermなんかでファイル転送するとPCからUSB経由でPICへは12Mbpsで転送されてしまい、PIC内部でバッファオーバフローを起こす。
この辺、市販のUSB-シリアル変換基板、あるいはチップはよくできている。
しかたがないのでteratermの設定でファイル転送時、文字間に1msのwaitを入れるようにしている。
ちょっと長いし文章だけなんですみません。
今までのCPUボードには全てPICを載せている。
主にクロック、RESET生成とUSB-シリアル変換に使っている。
元々の動機はUSB-シリアル変換。
今時のPCにはCOMポートがついていない。
この手の遊びをしている人の多くは、市販のUSB-シリアル変換基板と使っているが個人的にはどうもスマートではない。
変換チップをボードに搭載してしまうのも手だが、最近の変換チップは多機能多ピンのものばかりで、ピンのピッチも細かくて手半田はかなり厳しい。以前はフロー制御線を省略した少ピンでピンピッチも比較的広いチップも手に入ったんだけどね。
で、目を付けたのがPIC16F1454。DIP14Pinだから個人でも扱いやすく、小さくあまりスペースを取らない。5V動作というところも古いマイコンの周辺として使うのに都合が良い。なにより安い。
あと、外付けの水晶発振子を必要としない。USBは通信クロックにそれなりの精度を要求するので、ほとんどのUSBマイコンはUSBを使う場合は外部に水晶発振子を必要とするが、これは内部発振でUSBを可能としている珍しいチップ。
ただし、USBが使えるだけあって安定はしているのだろうけど、発信周波数は12MHzぴったりというわけでもなさそうだ。
少ピンとはいえピンはあまるので、7×10cmの小さな基板上のパーツ点数を減らすべく他にも機能を割り当てた。
ファームウェアはUSBのCDCクラスとなるように組む必要があるが、統合開発環境MPLABのプラグインMCC(MPLAB Code Configurator)を使えば自動生成してくる。多少システムにあわせてカスタマイズする必要もあるが。
ではこのマイコン制御チップであるPICの機能であるが
(1)USB-シリアル変換
一番メインとなる部分。
USBのファームは一から作るとなるとかなり面倒だがMCCのおかげでかなり楽ちん。
シリアル側もMCCで生成。これらに限らず内蔵ペリフェラルは全てMCCで。
ドライバと呼ばれる部分を生成するだけなので、もちろん一方で受信したら他方へ送信というメイン処理は自分で書かなくてはいけない。
(2)CPUクロック生成
CPUにクロックを供給。
このPICはシステムクロックを出力する機能があり、システムクロックを1/2**n分周を出力してくれる。
USB機能を使うとシステムクロックは48MHzになるので、生成クロックは
48,24,12,6,3MHz
となる。
Z80だとBバージョンで6MHz。Aだと3MHzにするしかない。
8085だと6MHz入力で3MHz動作。
68系は4分周されるので、6MHz入力で1.5MHzとなりAバージョン。
6809や6303ならCバージョンを使うと12MHz入力で3MHz動作が可能となる。
ただ先にも書いたが発信周波数は正確ではないようで、6MHz生成しているつもりが6.4MHzでていたりする。一方でほぼ6MHzでる場合もあり、これは個体差なのかロット差なのかまだ何ともいえない。
周波数的にいまいち使いにくいが水晶発振子(器)の節約になる。
(3)ボーレートクロック生成
マイコン側8251、6850等のシリアルチップ向けにボーレートクロックを出力。
通常9600bps想定で、その16倍となる153.6Kbpsを出力。6801の場合は8倍の76.8Kbps。
ボーレートの許容誤差は一般的に5%と言われているが、16倍クロック入力の場合だいたい1/16で6.25%。
このボーレートもPICのシステムクロックから生成しているわけで、CPUクロック生成6MHzのつもりが6.4MHzになっているとすると、6.67%のずれで許容範囲外なのだが、PIC内部のシリアルボーレートも、同じPICシステムクロックから生成しているので、ぴったしあって問題なし。あくまで9600からずれているというだけ。
(4)リセット信号生成
パワーオン時とリセット入力ピンがLowになった時に、リセット出力ピンをLowに。
リセット入力ピンがHighになってから約120msリセットを持続。
自分が知る限り一番長いRESETを要求しているのは68000で100ms。
少し余裕を見て120msにしている。
リセットは単純でありながら奥が深く昔からトラブルが多い。
アナログ的要素が強いからでもあるが、マイコンでON-OFFしてやるのが単純で簡単。
マイコンのファームウェアで制御しているわけだからある意味複雑とも言えるが。
リセット入力は使用しているポートがプルアップ付なのでスイッチをつなげるだけ。
(5)タイマ出力
10msでワンショットパルスを出すようにしている。定周期タイマとして使えるように。
10ms経過で単純にソフトでONしてOFFしているだけなので、ひょっとしたらパルスが短すぎて認識できないCPUがあるかもしれないが。
8085ボードではRST7.5に入れて定周期タイマとして使えるようにしている。今のところ問題なく動作している。
8085にあわせて通常LowでHiアクティブ。
その他CPU用では論理を逆にしているが、使っているボードは今のところない。
(6)オプション選択
余ったピンを使って動作選択できるようにしていて、今のところボーレート切替。
リセット中にチェックしてHiで9600、Lowで19200に切り替えるようにしているが、現状使っていないので動作確認はできていない。
とまぁこんな感じに機能を盛り込んだので、Z80ボードなんかはICはこれとZ80CPU,SIOの3チップ構成で済んでいる。
問題点
まだ残っている問題点として、
例えばPCでteratermを端末に利用するとしよう。マイコンボード側のボーレートが9600だからCOMポートの設定も9600にしたとしても、USBの通信速度が9600bpsになるわけではない。USB機器がCDCクラスだからCOMポートの振りをしているだけで、ハードはUSBであり12Mbpsで通信されてしまう。たぶんデータ長とかはソフト的なプロトコルだから意味があるだろうし、ハードフロー制御を使ったらそのようにエミュレーションするからこれも意味があるが、通信速度は無視される。ちなみにPIC側のファームでUSB CDCクラスの通信速度を設定する項目はない。
これはどうなるかというと、たとえばマイコン側のモニタでHEXファイルをロードしようとした時、teratermなんかでファイル転送するとPCからUSB経由でPICへは12Mbpsで転送されてしまい、PIC内部でバッファオーバフローを起こす。
この辺、市販のUSB-シリアル変換基板、あるいはチップはよくできている。
しかたがないのでteratermの設定でファイル転送時、文字間に1msのwaitを入れるようにしている。
前の10件 | -