Z80-CP/M ボードをつくる

SBC6809を作って遊ぶ過程でWebを見ていたら、いろいろなものがあることがわかりました。

4IC Z80 コンピューター を作りたくなって、オレンジピコからまたポチリ(病気がこじれた)。土日には配達されるまいと思っていたら、日曜の午後に郵便が届いていたので、我慢ができず作業開始。

1) ハードウェアの製作

まず、Z80のペリフェラルを引き受けているATmega32aにプログラム(Arduinoのスケッチ)を書き込むことが必要。

Atmega32a へ書き込みは下記の通り実行。

Arduino as ISP を使ってAtmega32a にブートローダーなどを書き込む方針に決めた。TL866CSライタを使っても良いみたいだけど、ヒューズの設定の仕方など不明点があったので、とりあえずみんながやっているやり方で!(あとで、こちらのDiscussions をよく読んだら書いてあったけど)。

1a) まず、arduino as ISP を作成する。

手持ちのFreeduinoを引っ張り出してきて、でも、いろいろの実験でどうなっているか不明だったので、Atmel ICE を使ってArduino のbootloader を書き込んでArduino化する。

次にArduino IDEのExamples からArduinoISPスケッチを開いて、Freeduinoの方に、ArduinoIDEを書き込もうとしたら、シリアル経由ではうまくいかなかった。しょうがないので、ブートローダー付きのArduinoIDEスケッチの.hexファイルを生成し、AtmelICEをICSP端子につないでAtmelICEから直接書き込んだ(2度手間をやっちゃった)。

そして、ArduinoISPとなった、Freeduinoを使っての書き込みを実行。

ブレッドボードにATmega32a を刺し、適当にググって下記の配線をジャンパーワイヤーでArduinoISPとなったFreeduinoと行った。

– Connect pins 10 and 30 on IC to 5V on Arduino

– Connect pins 11 and 31 to Ground on Arduino

– Connect pin 6 on IC to pin 11 on Arduino (MOSI)

– Connect pin 7 on IC to pin 12 on Arduino (MISO)

-Connect pin 8 on IC to pin 13 on Arduino (SCK)

-Connect pin 9 on IC to pin 10 on Arduino

そのうえで、まず、ArduinoISPを使って、ATmega32のブートローダーを書き込む。そして、Arduino IDEでATmega32Aで動かすスケッチ(S221116_R100218_Z80.ino)を開いて、アップロード実行。

不安なので、ATmega32aをブレッドボードから外して、TL866CSにつないでメモリの内容を読みだしたところ、ちゃんと書き込みできてそう。ちょっと不安だけど、この先はボードを完成させてからチェックすることにする。

1b) ボードの実装。

実装するLEDは、状態を見るだけなので、全部手持ちの赤でもいいのだけど、まあ、作った人の例に色も合わせてみようといろいろな色のLEDを秋月から購入。

ついでに、EEPROM (24LC1025)を2つ使ってi2c につなぐvirtual disk もCP/Mを走らせるのには必要なので、これもまた、人の実装例を見ながらおんなじように作った。さらに、I2CバスにつけるRTCモジュールもAmazonでポチり、これもまた、こちらのLogsにある通りのことをやって、接続した。Parallel I/O の例も載っていたが、こちらの方はi2c pio expander のICを買っておいた(未実装)。

1c) 火入れ。

電源は、PCのUSBから取る。あっさり、basic が起動できることを確かめた。

2) ソフト

2a) CP/M を動かす。

CP/M は8080で動く、MS-DOSの前からあるDOSです(自分の世代より前のことなのでわかりません。。。) MS-DOSがすでに理解してもらえないような気が。

中略。

ブートさせると、basic, forth, iLoad, 等を選べるようになっているが、iLoadを選び、iDiskという、i2cのvirtual diskにディスクイメージを書き込むためのユティリティをアップロードして動かすと、プロンプトがでるので、QPM271_DiskPack.zipを解凍したところに入っている4つの.hexファイルをteratermを使ってアップロード。ついでにCPMのディスクパックに含まれているdisk1 用のTurbo Pascal のイメージも書き込む。

Turbo Pascalなんて、学部1年の情報実習以来?懐かしい!というかPascalの文法も、TruboPascalの統合環境の使い方ももう忘れてる。

リブートして、QP/Mをロードしたところ。

QP/Mのディスクにはmicrosoft basic が入っていたのでそれでi2c RTCの動作確認(QP/Mで使っているけど)

OK!

ここでCコンパイラを動かしたりしたいけど、メモリとかディスクとかちょっと不足気味?

とりあえず、mbasic で遊ぶ。

Conway’s game of Life

いろんなbasicのゲームがwebで見つかるので、いろいろ遊んでみる。

game of life は、昔F-BASIC でも作って動かしていたように思います。

動かしてみたけど、有名なグライダーを入れると、グライダーが飛んでかないでいきなり消滅。。。?

3) 今後

特に目的もなく、作ってみましたが、basic でi2cポートも叩けるみたいなので、手持ちの24bit AD変換器などのセンサーを動かして高精度データをとりつつ、でも、データの表示はASCIIキャラクターのグラフで表示。みたいなのをやって遊びたいな、なんて思っています。

 

sbc6809を作る

有隣堂にモトローラ6800伝説があったので、思わず衝動買い。(ついでにインテル8080伝説の方も・・・)こういうの私的にはぐいぐい来ます。

私は、先に書いたように、Z80と6809が載っているパソコンをいじくったことはあるのですが、アセンブラは6809しか経験がないです。今回、FMのメモリ拡張ボードなどを作ったりしてハードウェアは一番なじみのある、6809のsingle board computer を作りたくなりました。

まず、スイッチサイエンスでPCBを販売していたので、購入。

ボードを購入して、退路を断った後、部品を集めようと思いましたが、その前に、自分のジャンクボックスにEPROMやら、74LS00やら74LS138ならきっとあるはずと思って、探してみたら、今の家に引っ越した後に部品の整理ということで、古い部品をかなり捨てていたことが発覚。どれも手持ちがありませんでした。手持ちの7400などは全部HCだった。使えない!

EPROMライタも昔作った覚えがあるのですが、見つけられない。EPROMの消去は、サンハヤトの感光基板作成用の紫外線ライトがあるはずだからそれでやればいいはず。

頒布されている技術情報のpdfを見ると、非常に丁寧に部品の購入先やら型番まで表に書かれていたので、それを見ながら、全部通販でポチポチ購入。

6809は、若松通商になかったので、ebay で怪しい中国の業者に、Hitachi HD63C09や、Motorola MC68B09P の発注をした後に、オレンジピコでMC68B09Pが扱われていることに気が付き、そちらで68B09Pと、あとで楽することを考えて、EEPROMを購入。若松からは、HD63A50P, HM6264ALSP-12, Intel D27256, 74LS00, 74LS138を購入。その他必要な部品(シリアル-TTL 5V変換ケーブル、ACアダプター、ICソケット、スイッチ、抵抗、コンデンサ、水晶)は、秋月から購入。

EPROMの書き込みにライタが必要なので、amazonでTL866CSを購入。

それから、ボーレートクロックジェネレータとして使われているPIC12F1822も書き込みツールを持っていないので、オレンジピコからpickit3互換品を購入。

ポチポチしまくって数日内に全部の部品がそろいました。通販バンザイ。

オレンジピコのMC68B09PはSTmicroでした。なんか残念。やっぱり日立かモトローラでしょ!

オリンピックの女子パシュート決勝を見ながら、はんだ付け大会。部品のGNDピンのサーマル処理がちゃんとされているので、かなりはんだ付けが楽でした。素晴らしい。

pickit3を使ったpic12f1822の書き込みは、ブレッドボードを使って行いました。

EPROMは動作確認用のエコーバックプログラムのHEXファイルを書き込み。

PCにつないで、5VのACアダプターを繋ぎ電源投入すると、あっさり動きました。

 

美しいボードだ。。。

CPUはまあまあ暖かくなります。消費電力は5V 0.15A = 0.75W でした。意外に低消費電力。モバイルバッテリーで十分動かせますね。

BASICを入れて、プログラム書いて遊びたい。本当は、このボードでCコンパイラが動くといいのですが、メモリが小さすぎて無理かな?やっぱり、同じボードで完結する環境が好きなので、インタープリターを入れていじくるのが良い。

… 勢いあまって、BASIC もEEPROMに書き込んで動かしてみた。

夜更かししてないで、はよ寝よ!

 

 

コンピューティング今昔

娘とIchigoJam を組立て、BASIC事始めしてます。

IchigoJamは、画面はビデオ端子を使います。キーボードはUSB端子がついているのですが、これはPS/2キーボード対応しているUSBキーボードをつけるための端子のようで、愛用のthinkpad キーボードはつながりませんでしたので、amazonでこれを購入し、プログラムを楽しめるようになりました。最初は、こんな単純なのつまんない、って言うかななんて思っていましたが、結構楽しんでます。

単純にBEEPコマンドを打って音を出すだけでも、盛り上がっています。素直な娘だ。。。まあ、BEEPコマンドも、音程を変えられるような仕組みになっていて工夫されているとは思いますが。

娘と一緒にBASICで遊んでいると、例によって自分の昔を思い出しちゃいました。

私とパソコンとの最初の出会いは、友達のうちにあった、MZ2000
でした。今調べると、結構高い機械だな、友達のお父さんお金持ち!と思う。毎日のように友達の家にお邪魔して、プログラム打ち込んで遊んでました。カセットテープからシステムプログラムを読み込んで立ち上がるという、今思うとかなりチャレンジングな機構を採用していましたね。いろいろなシステムが走らせられるのはいいような、カセットなので、10分程度待たないと立ち上がらなかったような、そんな記憶が。

当時、秋葉原ではMSXが出始めたタイミングだったと思います。当時の私の愛読雑誌の初歩のラジオなどでも特集が組まれていましたが、MSXは画面がMZ2000と比べたら綺麗ではなかったので、あまり興味はありませんでしたね。

次に、触れ合ったパソコンは、JR200でした。これも自分のではなくて、友達の家で、やっぱりプログラム打ち込みとかして遊んでいたと思います。この友達はファミコンも持っていたのでゼビウスとかして毎日遊んでいました。

自分はと言えば、我が家は、父が(娘の祖父)めったに子どもにモノを買い与えない人だったので、パソコンはおねだりもしなかったと思いますが、買ってもらえませんでしたね(その反動が今に出ている気もします。。。)

ようやく中学2年の時にFM77AVを買ってもらったのが自分の最初のパソコンでした。やっぱり、BASICのプログラムを打ち込んだりして遊ぶのが多かったと思いますが、XANADU、とかゲームソフトも買ってもらって、いやほど遊んでいたと思います。当時は、パソコンもいろいろいじくる余地があったので、パソコンでゲームするのが多かったとは思うんですが、何割かは、当時ソフトバンクが出していた、Oh!FM という雑誌の記事を参考に、拡張メモリボードを作成したり、AD変換器をつけてデータをとったり、Cでプログラミング(DRACO Cというちょっと風変わりな処理系を使っていた)を始めたりと、今につながることを始めたのもちょうどこのころと思います。

(当時、ソフトバンクの出版者の孫正義、という名前を見て、変な名前、って思っていた。。。)

で、高校の時は、高2あたりから大学の受験を考え始めて、あまりパソコンで遊んだ記憶がありませんが、大学に入って、教養で、プログラムの時間がありましたが、学校で使っていたのが、FM16βだったと思います(と書いて調べてみたら、時期があいませんね。FM-Rだったかも。)学校に営業しまくりの富士通ですね。授業の時間、課題に飽きてPascal でワイアーライン3Dグラフィックスを書いて遊んだり、当時はまだWebのない時代でしたが、大阪大学に進んだ高校の同級生とtalk でキーボードチャットをしたりしていたような気がします。

そして、3年生で専門に上がって、出会ったのが、学科の計算機室にあったSunMicrosystems のSPARCstation2。共用の計算機室のSun3と比べたら圧倒的に速かった(今思うと、めちゃ遅いですが)。それに、SPARCstationのピザボックスのような形状がめっちゃカッコよかった!

当時、Webの始まりで、MOSAICで見られるホームページをつくったり、emacs, gccなどのgnuの環境をコンパイルして整備したり、朝から晩までかなり時間を無駄に浪費していました。おかげで単位が足りず卒業がやばかった。。。のも今ではいい思い出(?)です。学部3年生の時には、家ではEPSONのPC386Pっていう、遅めの98互換機(貧乏学生だったので)で、MSDOS上でLaTeXやグラフ描画ソフトのNgraphを使ってレポートを仕上げていましたが、やっぱり学科の計算機室に入り浸って、unix で遊んでいる方が多かったですね。

その後、修士時代にlinuxと出会い・・・と続いていきますが、今思うと、激動の時代だったなと思います。

娘はこれからどのような計算機との触れ合いをしていくのだろう?と楽しみです。私も、昔を振り返るのはこれくらいにして、もう少し最新のコンピューティングに触れ合うようにしよう、と思いました。

 

lpc1114 で短めなパルスをつくる。

Raspberry Pi に乗っけられるlpc1114のボードで相変わらず遊んでいます。

どれくらい短いパルスをこれで生成できるのか実験してみました。PWMを使うのが常識的とは思いますが、ここでは、Ticker で0.1秒程度に1回割り込みをかけて、下のルーチンでいくつかの異なったやり方でGPIOをトグルして、オシロスコープで生成したパルスを観察しました。

void pulse () {
// 常識的
 LPC_GPIO0->DATA |= 0x0000080; // dp28 set 1
 LPC_GPIO0->DATA &=~0x0000080; // dp28 set 0

 // faster?
 int n,n0,n1;
 n=LPC_GPIO0->DATA;
 n0= n|0x80;
 n1= n&(~0x80);
 LPC_GPIO0->DATA =n0;
 LPC_GPIO0->DATA =n1;

// 他のポートに影響を与える
 LPC_GPIO0->DATA = 0x80; // dp28 set 1 (affect other pin)
 LPC_GPIO0->DATA = 0x0 ; // dp28 set 0
}

結果

  1. 常識的な、ORしてANDしてbit を上げ下げするもの: 104ns
  2. ポートのデータを読んでおいて、OR, ANDしたものを用意しておいてから、順次書き込む。: 42ns
  3. 他のポートのことは無視して、定数を書き込む: 62ns

というわけで、一番短くて42ns のパルスが作れることがわかりました。ちっちゃなマイコンなのにすごいね。

PWMを使ってパルスを作るのもやってみましたが、こちらは644ns より短いパルスにならないので論外(ペリフェラルのマニュアル読んでないので、何でか分かってないけど)。

… あとで調べたら、mbedのpwm ではプリスケーラーが30に設定されているために、パルスが短くならないとわかった。

実験ではpin dp18のpwm を使っていた(TMR16B1)ので、これに対応しているレジスタを調整して、パルスを出してみる。

# prescaler 0
TMR16B1->PR=0
# MR3: PWM period maximum 16bit value (一番間隔を長くする)
TMR16B1->MR3=65535
# MR0: PWM duty cycle 16 bit
# この値になったときにパルスが立つので、一番大きな値にすると短いパルスとなる。
TMR16B1->MR0=65535

pin 番号とTMRの関係は、pwmout_api.c とかPinNames.hをみて調べた。

mbedを使わずに直接やってもいいけど、とりあえず実験なので、PwmOut でpwm を使うようにした後にレジスタを書き換えるという乱暴な方法を取りました。まあ、動いているからよい。

結果

20.8ns=(1/48M)のパルスを1.37ms (=65536/48M)間隔で出力することができました。めでたしめでたし。オシロで観察していると、プローブへのGNDラインの引き方でパルスの反射がとってもぐらぐら動くので面白いです。

とりあえず、あとのために、pwm ポートと設定レジスタの対応を下記にまとめる。

  • dp1 P0_8 PWM_1 LPC_TMR16B0 MR0
  • dp2 P0_9 PWM_2 LPC_TMR16B0 MR1
  • dp18 P1_9 PWM_3 LPC_TMR16B1 MR0
  • dp24 P0_1 PWM_5 LPC_TMR32B0 MR2

mbed lpc1114 i2c でハマる。

年末年始と、久々に電子ネタやろうと思って、ネットサーフィンしてたんですが、

RPi1114FDH Raspberry Pi 電源制御モジュール

が面白いな、って思ったので、購入して手持ちのRaspberry pi につけて遊んでいたんですが、苦労させられたので、備忘録としてメモしておきます。

これは、「Raspberry Pi電源制御」というお題目のモジュールなので、Raspberry Pi のためのものという感じもしますが、私にとっては、Raspberry Pi にのっけられるマイコンモジュールと思って買ってみました。

Raspberry Pi の上に載せられる大きさの小さな基板には、lpc1114という結構高機能だけど、ミニマルなマイコンが搭載されていて、Raspberry Piからコマンド一発でプログラムを書き込み出来るし、i2c が接続されているし、シリアルも接続されているし、LEDもついている、ということで、まさにRaspberry Pi が母艦のarduinoみたいな使い方ができる評価ボードと思います。

lpc1114 をプログラミングするには、mbed がとっても手っ取り早い、ということで早速、モジュールの添付プログラムをダウンロードしてきて、コンパイルと、lpc1114に書き込みができることを確かめたのち、i2cを使ったRaspberry Pi(RPi)との通信を実験してみると、RPi からlpc1114へのマルチバイト送信はできるのだけど、lpc1114からRPi へのマルチバイト送信がどうやってもできない。サポートサイトには、デジタルポートの読み込みができる例が記載されているけど、できないし。一体どうやって実行したんだろ?って感じです。

これは、lpc1114 mbed 側のi2cサポートと、RPi側のi2cサポートの内容のミスマッチでできないって感じ。少なくともPython,やシェルコマンドでは回避法が見つからない。丸1日程度Webを調べまくったけどダメなので、とりあえずあきらめ?

下記は、2方向の通信に使えるPythonやmbed プログラムの書き方まとめ。
1. slave (mbed) -> master (raspberry pi)方向
slave: write(buf,number_of_bytes)
master: read_byte(addr)
slaveからの2byte 目以降の読み出しはできない(master が読み出しをしないので)
2byte 以上読み込みの場合は, raspberry pi 側でread_word_data()などでできそうな気がするが、その場合は、mbed側で一度Write Addressed が立って、そっちの処理をした後にRead Addressed がかかるにも関わらずmbed側がRPi 側が期待したような形でデータを送りかえさないので、failしちゃう。
2. master (raspberry pi) -> slave (mbed) 方向
master:  write_block_data(addr,cmd,array of bytes)
slave: read(buf,number_of_max_bytes)で読める。
3. その他
また、書き込み、読み出しのコマンドの間はRPi 側で少し時間をあける(0.035sec程度?)必要がある。これより短いインターバルだと、IOErrorが出た。mbed slave側は、とにかくstateを見て、レスポンスするようなプログラムを書く。
チラシの裏状態だけど、解決してないからしょうがない。
1バイトの読み出しはできるので、プログラムが書けないことはないけど、非同期シリアルで通信した方が楽かも。うーん。
ロジアナで波形を観察したり、他のi2cデバイスをRPiにつないで動作を確認したところ、どうも主な問題はmbed slave側にあるような気がするので、1/3 朝起きた後、lpc1114のドキュメントをみていろいろ試してみたけど、あまり進歩せず。mbed のクラスライブラリを使うやり方では打開は無理っぽくて、lpc1114のi2cコントローラーを直接いじるプログラムに変えれば打開できるかもしれないけど、ちょっと荷が重い。