ROMライタのファームウェアひとまず完成

EN29F002用ROMライタ ファームウェア

ファームウェアのソースだけあってもしょうがないんですが、共有してみます。書き込み、読み込み、チップ全消去できるのは確認済み。

ROMに対する各操作シーケンスのタイミングがイメージしやすいよう、特に構造化もせずゴリゴリ書きました。単純なコマンドで最低限の動作をするように作ってあり、あとはPC側の書き込みソフトを目的に応じて作りこむ想定です。

コーディング上ハマった点など。

  • Arduinoのピンモードを動的に切り換えて双方向データバスにしたかったが上手く行かなかった。入力と出力のピンを分け、出力はROMの出力と衝突しないよう541で制御。
  • が、最後の瞬間まで541のつもりで540(541とは出力が反転する)を使っていた…動くわけねえよ! そもそも541のつもりで540を買っていたようなので根が深い。
  • ポートレジスタで入力を受ける場合、PINXを使う。PORTXで入出力いけるってどこかで読んだ気がするけど、ダメだった。
  • 書き込みはビットを1→0にする操作しかできないので、消去(ビットをすべて1にする)してから書き込む。
  • Serial.readStringUntil(char terminator);でコマンドのやり取りをするとき、受信データに terminator で指定した文字が現れるほか、タイムアウトでも受信を打ち切ってしまうのにしばらく気付かなかった。タイムアウトの場合は受信データをバッファして繋げて…というコードを書き出すとこの関数使う意味がないような気がしたので、Serial.setTimeout(-1);として回避(引数の型が unsigned long なので無制限の待ちになってるわけではないはず)。
  • Serial.readStringUntil(char terminator);で取得した文字列の最後に terminator は含まれない。
  • PC側ソフトからシリアルポートをopenすると、Arduinoはリセットがかかる。これに気付かずミニマルなコマンド送受信の実験するのにも苦労した…。open後2秒くらい待てばいいらしい。

あとはハマったのではないですが、書き込み時のDQ7ポーリングは簡略化できそうです。Arduinoからの制御が遅いので最初にDQ7を見に行く時すでにタイムアウトしてる気がします。つまりこの時点で書き込んだデータの7bit目==DQ7なら成功だし、違うなら失敗と判断するだけでOKのような。まぁとりあえずはデータシート通りに。

次はRubyで書き込みソフトを作る…ではなく、書き込むべきデータがまだ存在しないので、Ubuntuで使えるZ80アセンブラ入手が課題です。前にやったbinutilsをクロス開発用にコンパイルする手順でいけそうですが、ちょっと大げさな感じ。お手軽なものがないか調査してみます。

アセンブラをクリアしてZ80バイナリをROMに焼けたとしても、見てください。
f:id:marlesan:20161024003823j:plain:w400
この状態ではROMの抜き差しが不自由すぎるので、ライタ回路のシールド化が必要です。半田付けヤッター!

f:id:marlesan:20161024004325j:plain:w400
シールド回路のおおまかなレイアウト。表はZIFソケット、裏はArduinoとの接続部分に邪魔されてスマートな配線は無理そうです。写真撮るときには失念していましたが、Arduinoに対するリセットボタンも必要。チャタリング解消してデジタルなエッジを作ろうとしたら、スイッチ+IC+抵抗+コンデンサを載せないと…。

この辺の作業、完全にイージーモードだと思ってましたが結構厄介そう。

一番困ってるのはこれ。
f:id:marlesan:20161024005302j:plain:w400
足が太すぎる……。ZIFソケットは問題ないですが、Z80の基板上に載せる予定のICソケットには入りません。どう対策を打ったものか…

  • 足を細いものに付け替える。
    • 足を固定している穴がスルーホールっぽい。半田除去失敗しそう。
  • Z80の基板にもZIFソケットを乗せる。
    • もう1個持ってるのでできなくはないですが、イヤすぎますね…。
  • シールド上のコネクタからZ80基板上のROMソケットにジャンパ線で接続。
    • 現状の最善策はこれくらい。でもArduinoに電源が入らないようROMとして使うときはシールド外さないといけないのが面倒。

自分で変換基板を発注してみようかな。そしたらついでに28ピンにしちゃうぞ。