8080A I2C EEPROM 読み込み

連休は結局8080Aのマイコンボードをいじって終わってしまった。娘は学校の宿題を済ました(らしい)のに、なんてこった!

でも、8080のアセンブラ記述もだいぶ慣れたので、ま、いっか。EEPROM のダンプができるところまで来たので、記録しておこう。

ichigojam でEEPROMにセーブしてあったデータを1ページ(128bytes)ごとダンプしたところ。

I2Cの読み取り手順に問題があるようで、最初の読み取った1バイトは多分ダミーで、そのままではいけないけど修正をしてない。この問題はRTCの読み込みをした時点で気が付くべきだったが、節穴でした。

8080Aボードのモニターも、先にアップロードしたものは、outコマンドでちゃんと書き込みができていないので、それもバグ。一応直したつもりだけど、まだテストしていない。

アセンブラはこれまでは、zasm のオンラインコンパイラーを使っていたけど、今日ubuntuでzasm を動かして、スクリプトでアセンブルとintel hexファイルの整形を一発でやるようにワークフローを変えてみた。まあまあ快適。

I2CインターフェースICへ与えるクロックが低すぎる問題は、pic12F1822で8251へ与えるボーレートクロックと4MHzを同時に生成するようにしようと思っているが、これもまだテストしていない。

いろいろと半端だなあ。

例によってバグがいろいろ入っているであろうプログラムリストを恥ずかしいけど下に置いておく。

i2ctest_8080_lst (2)

(5/8) pic12F1822 で生成するボーレートクロックを309kHz (19200bps)にし、OSC/4 = 8MHz も出力するようにした。8MHz はI2C インターフェースのCLKとして入力してみたが、動かない。何がいけないのだろう。。。とりあえず、元の2MHz に戻して、プログラムをいろいろいじくってみた。I2C のダミー読み取りは汚いやり方ですが、直してみた。まあ、いいかな。

(5/8終わり)

8080A I2C RTC読み出し動く

8080Aマイコンボードの開発環境が落ち着いたので、I2C接続のRTCを読み出すプログラムを書いて遊びました。I2C接続のRTCは、DS3231のモジュールがアマゾンの通販で安く売ってますので、それを使ってます。レジスタを読み出してHEXで表示するだけでOKなので、ラクチン。

前にmicrosoft basic でテストしていた内容を下敷きに、アセンブラでRTCの読み出し表示プログラム(要は時計)を実装しました。

テスト中。いい感じ。

こちらに、作成したプログラムを貼っておきます。

i2ctest_8080_lst

I2Cの初期化がうまくいかない(?)ことがたまにあり、これはbasicで試していた時もそうだったのですが、なぜかよくわかっていません(多分STOPコンディションなど半端な状態のまま、終わったりした影響が次に実行するときに出るんだと思う)。

ま、後でよく考えよう。

RTCの読み出しと表示を合わせて3ms程度で終わります。basic と比べるとやっぱり圧倒的に速い。ロジアナでデータとアドレスのバスを観測すると、一つずつ命令を実行している様子が楽しめて、可愛らしく感じるものがあります。ビットもえー、って感じ?

I2Cのクロックは63kHz程度になってます。マニュアルによると、PCF8584に12MHz クロックを入れたときに90kHzになる設定にしているのですが、8080Aなので、実際に入れているのは、2MHz クロックなんだけど、何となく動いている。どないやねん(これが初期化に失敗する理由?)。設定値を変更して遊ぼう。

(追記)設定を変えて試そうとしてみたら、設定を間違えていることに気づき、直したら全く動かない。いろいろやってみたけど、間違った設置値でしか動かせてない。やっぱりちゃんとしたクロックを送ってあげないとダメなのかな?(追記終わり)

最初はおっかなびっくりアセンブラを書いていましたが、パターンに慣れてくると、気軽に手が動くようになってきた。生成される機械語もアセンブラだと短いし、結構楽しくなってきました。

smallc は変数の受け渡しがいまだによくわからなくって勉強中。smallcでめちゃくちゃ冗長なコードが生成されるのを見てしまうと、やっぱり遊ぶのには、アセンブラの方がいいかも、と思える。

次は、I2C接続のeepromの読み書きをしてみようと思っているところです。

8080 モニタープログラム

intel 8080A 搭載のマイコンボードですが、非常にゆっくりとではありますが、ちょこちょこ遊んでいます。microsoft basic で搭載したI2Cポートをたたいて、RTCを動かせることは確認したのですが、やはり機械語で読み取りをしたいな、ということで、このマイコンボードでのアセンブラやCのプログラミング環境を整えることにしました、(ら、はまってかなり時間が経ってしまった・・・)。

ハードウェアは、こんな感じで、

256kbit SRAMを、8000H-FFFFH, 256kbit EEPROM を0000H-7FFFH に配置しています。IOは0C0H に8251を、0E0HにPCF8574 (I2C interface)を配置しています。あとで、CP/Mを動かそうと思っているのですが、下位のROMをRAMに変更できないといけないんですが、どうやるかはこれから考えるところ。

(写真は、上に書いたもののどれも写ってない!)

CP/Mの開発環境を使うことを念頭に、下記のようなプログラム開発フローを作ろうと考えました。

1) こちらで紹介されているCP/M エミュレーターで、最初のテストを行う。

2) 開発環境は、CP/Mのツールを使う。(smallc など)

3) コンパイル等は、windowsで行い、エミュレーターでテストする。

4) コンパイルは、CP/M のバイナリーを生成するのと同時に、CP/Mと互換のBDOSをROMに書いた8080ボードでも動くようにバイナリーを生成し、Intel Hexをtera term でボードに送り込んで動かす。

このとき、4)のCP/M 互換のBDOSを8080CPUボードで動かすのは、こちらの8085モニターを8080で動くように変更してやることにしました。これは、8080のアセンブラ、逆アセンブラが付いていますので、8080のアセンブラを覚えていない私にとってはちょうどいい感じなので、これで。

このモニタープログラムを8080で動くようにするには、シリアル通信を受信割り込みをかけてやっているので、それをRST7の割り込みで行うように変更するだけでOKなんですが、元のプログラムですと、タイミング悪く受信割り込みがかかると、シリアル受信バッファーのインデックスがずれてしまう問題があったので、修正をしました。

また、私のボードは、割り込みがかかると、必ずRST7に飛んでしまう仕様になっているので、割り込み先をユーザープログラムで乗っ取ることができるようにするために、一旦RAMのアドレスに飛んで、そちらから割り込みハンドラー(シリアルデータ受信ルーチン)にJMPするようにしました。

それから、もとのモニタープログラムでは、Intel Hexのロードはできるようにはなっていませんので、モニタープログラムのsmallcのソースを変更して、load コマンドでIntel Hexの読み込みができるようにしました。

さらに、I2Cインターフェースのチェックなどに便利?と、モニターにIOポートの読み書きコマンド(out, inp) を実装しました。これを実装するときに、Z80と8080の違いを勉強したんですが、8080は、IO関係の命令でレジスタ間接アドレッシングができないので、ROMに命令を置くと、読み書きするIOアドレスが変えられないとわかって、ちょっと不便だな、と思いました。相対ジャンプ命令もないし・・・

プログラム開発環境整備を試行錯誤しつつ、モニタープログラムを書きつつ、デバッグしつつ、で結構時間がかかってしまいましたが一応動くようになりました。

ROMに書き込むプログラムのアセンブルは、zasm オンラインアセンブラーでやっています。8080の命令以外を使っていないかチェックできるし、8080の二モニックに対応しているし、Intel Hexを吐けるしで、結構便利。

ということで、一応できたので、ここにモニターのアセンブラコードをおいておきます。っと思ったんだけど、添付の仕方がわからん・・・

MON80_ASM

これでいいかな?

これはIntel Hexをロードしているところ。チェックサムは一応見ていて、おかしな行が出てきたらアボートし、メモリのどこをいじくったかわかるようにしてます。XON/XOFFのフロー制御は一応うまく動いているようで、エラーは出ませんけど(処理に無駄が多く、速度が200bytes/secぐらいしか出ませんが!)。

 

これは、IO input, output を試しているところ。

 

8080A動いた

8080Aのボードで苦心していましたが、動きました。

8251のシリアル通信で、ロジアナで見る限り、初期化がしっかりなされているのにも関わらず、8251のステータスがずっと0、って困っていました。回路図を何度見ても間違いはなく、でも思ったような動きをしていないことも事実、という時には、やっぱり現物の配線を確認すべし、ってことで、8251周りの配線をテスターで確認していきました。まず、GNDは4番につながっているので、OK、じゃあ26番のVCCは?ってことで調べると、導通がありません。あれー?ということで、その時、はたと、EEPROMのVPPに配線していたVCCを、EEPROM対応をするためにVPPとA14とを入れ替え、VCCからの配線をパターンカットしていることに気が付きました。8251のVCCをここのVPPのところから引っ張っていたために、配線修正した瞬間8251に正しく電源電圧がかからなくなっていたということが判明。

配線なおしたら、シリアルの入力文字をエコーバックするプログラム動きました。OK!

 

上にCPUボード、NEC のuPD8080A, uPB8238, uPB8224と電源周りが乗っています。intel の8080A も入手してあるので、uPD8080Aとの違いもチェックできるぞ!(興奮)

消費電流は5V 0.476A クロックジェネレーターがCPUとバスコントローラー以上に熱い!

RESETを8251に接続するために、白いジャンパ線を這わしてるのがいまいち。ロジアナを繋いでCPUボードの動作チェックしていたのでピンヘッダを無理やり上にはんだ付けしました。

下側は、8251とEEPROM関係、アドレスデコーダ、裏側にSRAMが張り付いています。I2C bus controller のPCF8584Pはまだ実装してません。

あーでもよかった。

早く、I2C関係の配線をしてCP/Mが動くようにしたいなあ。

Z80-MBCでCP/Mは動いているけど、ATmega32Aでブートローダーや周辺インターフェースをやらせているというのが私の美意識といまいち合わないので、普通のEPROMとSRAMで構成したシステムでCP/Mを動かしてみたいのです。

でもその前にボードを作り直したいな。まさかこれ程パッチ当てする羽目になるとは思ってなかった。

それよかパラレルI/FでSDメモリを読み書きできる方が良かったかな?なんて妄想が膨らみます… 結局またパッチだらけの基板を作っていつまでたっても完成しなさそう。

(4/26 追記)

vintagechipsさんの ところのマイクロソフトBASIC も動きました。

アークピットのアセンブラを持っていなかったので、こちらのオンラインアセンブラを利用して8251のアドレスだけ変更(00C0-00C1H)して、アセンブル。8080の命令範囲でアセンブルするとエラーが出ましたが、8080命令で動くように変更してあるので、z80命令を許可するオプションでアセンブルしてROMに焼きました。

PRINT INP(&HC0)

とかして、I/O ポート入力もできてそうなことを確かめたので、I2Cインターフェース関係はとりあえずこれでテストする予定(モニターを一緒に焼こうと思ったけど時間がないのでとりあえず)。

(4/26 追記おわり)

(4/28 追記)

I2Cのテストをしたら、動かなかったが、I2Cバスインターフェースがselect されていないことがわかったので、はんだ付けを疑い、LS138のところのはんだ付け不良を修正して、basic でI2Cバスに接続したRTCの読み込みができました。OK

機械語でI2Cを読み書きするプログラムは6809については作ってみたけど、8080は全くど素人なので、まだまだこれから。

(4/28 追記終わり)

8080A まだ動かないけど。

8080Aまだ動いてないけど、少しずつ前進しているのでその記録。

1) フリーランを試す。

CPUボードが悪いのかメモリボードが悪いのかさっぱりわからなかったので、まず、メモリーボードを外して、CPUボードをブレッドボードを使ってデータバスを全部pulldownし、NOPを実行するように配線して電源ON.

⇒ アドレスがインクリメントしていることを確認。ということで、メモリーボードがおかしいということがわかった。

2) メモリーボードのチェック。

arduino mega2560 を持っていたので、これで、メモリーチェックをする冶具を作成。

メモリーの読み書きをしてみるとEEPROM 28C256の配線がまちがえている(27256と全く同じ結線ではない)ことに気が付いた。パッチワークをして修正したが、まだおかしい。 EEPROMを外して読み書きをしてみると、SRAMが選択されないアドレスでも読み書きができた。⇒SRAMのCS-が常に0になっていることに気が付いた。フラットパッケージのSRAMのはんだ付けが十分でなかったためと分かり、修正。ROMとRAMが冶具で正しく読み書きできることを確かめた。

3) まだ8251でのシリアル通信ができてない。

IO周りの回路が正しくアドレスデコードできてないかな?割り込みを使わない送信で送れていないから。

ロジアナをつないで、読み書きの様子を調べた(4/23)

アドレスのデコードは問題なし。RESETのタイミングがCPUより後になっていることが分かったので、CPUのRESET信号をBUSの空きピン(12)に持ってきて、8251につないだところ、リセットのタイミングがCPUと同じになった。次のボードは、CPUボードでリセットを制御して、RESET信号をほかのボードに分配するように変更したい。

しかし、相変わらず8251のstatusで TXRDYのビットが0のままだ。端子をチェックしたがCTSも0だしなぜだかわからない。。。(4/23ここまで)