2021-09-08 12:17 — asano
カテゴリー:
このところCOSMAC関係が続いておりますが、今回をもって一旦終わる予定です。
ソフトウェアUARTも動いたことですし今更感もあるのですが、せっかく準備したUSARTも動かしてみました。
当初8251を考えていましたが、せっかく他がCMOSなのでそれに合わせるためと、クロックを5MHzにしてしまったので分周しなくても使えるという理由からμPD71051Cを使うことにしました。
シリアルクロックの生成は安直に19.6608MHzのEXO-3を選びました。これは源発の19.6608MHzの他に1/21~1/28の内の一つを出力できます。1/27が153.6kHzでちょうど×16モードでの9600bpsに相当します。分周比の設定を変えれば4800bps, 19200bps, 38400bpsも出せます。×64モードの使える8251系なら1200bps, 2400bpsもできるので、ボーレートジェネレータとしては便利で使いやすいデバイスですね。製造中止なのが残念です。
さて80系バスのペリフェラルをCOSMACに接続するにはメモリマップトI/Oとしてつなぐ方法とINP
/OUT
命令でアクセスする方法があります。
前者は広大なアドレス空間が使えますが、逆に言えばその分搭載可能なメモリが減ってしまいます。
後者ならメモリ空間は減りませんが、I/Oに使えるアドレスは1~7の7つしかありません。
EMILY Boardならメモリ空間は余っているので前者でもよいのですが、ここではCOSMACらしいということで敢えて後者の方式を試してみることにしました。
COSMACのI/Oはちょっと変わっています。一般的なプロセッサの場合CPU⇔I/O間でデータ転送するわけですが、COSMACの場合はメモリ⇔I/O間で行なわれCPUはアドレスこそ出力するもののデータにはあまり関わりません。
- I/Oライト時にはメモリリードとI/Oライトが同時に実行され、メモリのデータが出力されCPUはデータには一切関知しません。
- I/Oリード時にはメモリライトとI/Oリードが同時に実行され、データは一応CPUにも読み込まれて
D
レジスタにもセットされますが、メモリにも必ず書き込まれます。
それではμPD71051Cのピンをどう接続したか具体的に見ていきます。
- D0~D7 ⇔ BUS0~BUS7
0がLSBなのは共通なのでこれは問題ないですね。 - CLK ⇐ CLOCK
8251/μPD71051CのCLKはバスタイミングと非同期でよいので必要によって分周したり他のクロックを使ってもOKです。 - CS ⇐ !(N1 & !N2)
ポートアドレスが2,3の時のみアクセスさせます。未使用だった74HC139の半分を使っています。 - C/D ⇐ N0
ポートアドレス2でデータ、3でコントロール・ステータスレジスタにアクセスさせます。 - RD ⇐ MWR
一瞬間違いかと思うかもしれませんが、上記のようにメモリライトとI/Oリードが同時なのでこれでOKです。 - WR ⇐ MRD
逆も同様です。 - RESET プルダウン
インバータが余っていなかったのでプルダウンで済ませてしまいました。ソフトウェアで初期化してやれば問題なさそうです。F8の時もそうでした。
最後に初期化と1文字入力の部分のソフトウェアを載せておきます。
(1) 5/ 700 : INIT:
(1) 6/ 700 : E2 SEX SP ; Use (SP) as temporary area
(1) 7/ 701 : F8 00 LDI 00H
(1) 8/ 703 : 52 STR SP
(1) 9/ 704 : 63 OUT USARTC
(1) 10/ 705 : 22 DEC SP
(1) 11/ 706 : F8 00 LDI 00H
(1) 12/ 708 : 52 STR SP
(1) 13/ 709 : 63 OUT USARTC
(1) 14/ 70A : 22 DEC SP
(1) 15/ 70B : F8 00 LDI 00H
(1) 16/ 70D : 52 STR SP
(1) 17/ 70E : 63 OUT USARTC
(1) 18/ 70F : 22 DEC SP
(1) 19/ 710 : F8 40 LDI 40H ; Reset
(1) 20/ 712 : 52 STR SP
(1) 21/ 713 : 63 OUT USARTC
(1) 22/ 714 : 22 DEC SP
(1) 23/ 715 :
(1) 24/ 715 : F8 4E LDI 4EH
(1) 25/ 717 : 52 STR SP
(1) 26/ 718 : 63 OUT USARTC
(1) 27/ 719 : 22 DEC SP
(1) 28/ 71A : F8 37 LDI 37H
(1) 29/ 71C : 52 STR SP
(1) 30/ 71D : 63 OUT USARTC
(1) 31/ 71E : 22 DEC SP
(1) 32/ 71F :
(1) 33/ 71F : D5 SEP RETN
(1) 34/ 720 :
(1) 35/ 720 : CONIN:
(1) 36/ 720 : E2 SEX SP
(1) 37/ 721 : CIN0:
(1) 38/ 721 : 6B INP USARTC
(1) 39/ 722 : FA 02 ANI 02H
(1) 40/ 724 : 32 21 BZ CIN0
(1) 41/ 726 : 6A INP USARTD
(1) 42/ 727 : A8 PLO 8
(1) 43/ 728 :
(1) 44/ 728 : D5 SEP RETN
初期化のINIT:
はソフトウェアリセットをかけてモード・コマンドを書き込んでいるだけです。
一点注意すべきはメモリをちょっと乱暴な方法で使っている点です。前述のようにポートの入出力にメモリがどうしても必要なのですが、現在Universal Monitorはコンソールドライバのファイル内でRAM上のエリアを確保する方法を用意していません。仕方ないのでスタックトップを勝手に使ってしまっているのでSTR SP
とOUT
の間で割り込みが発生してスタックに何か書き込まれると正常に動作しません。現状では割り込みを使わない前提でこうしていますが、割り込みを必要とする場合はSP
を他のレジスタにコピーしてSP
を1減らすなどの対応が必要になります。
1文字入力のCONIN:
でも同様にスタックトップを使っていますが、こちらはINP
命令でメモリはダミー(D
レジスタの値を利用しているため)です。このまま割り込みを使っても問題はないはずです。
コメントを追加