カテゴリー別アーカイブ: MC6802

6800FLEX Basic と ASCIIART

Lambda-2022 マシンで FLEX 2.0 が動くようになりました。6800 / 6809 用 DOS である FLEX はマイコン DOS としては比較的初期の製品になりますが、アセンブラをはじめ各種言語が利用できて便利です。

「DOS」といっても物理フロッピーディスクならびにドライブをいまさら使う必要は感じられないので、シリアルサーバ Apple2pi のコードを改変して FLEX ディスクドライブをエミュレートしました。Apple ProDOS が 1 ブロック 512 バイトなのに対して FLEX は 1 セクタ 256 バイトが読み書きの最小単位であるため、Apple2pi のディスクエミュレーションコードの該当部分を変更します。FLEX のセクタ数とトラック数はディスク TOC に書かれたパラメータに応じて可変となるので、その処理も追加しました。6800 用クライアントコードは 6502 クライアントコード(a2pi.s)を参考にして新規に書きました。

FLEX ブートディスクイメージの作り方については Old68fun 様のページの情報が大変参考になりました。

FLEXシステムの作成方法(その3)・・・6800FLEXの場合

さて DOS が起動するとまず BASIC を使いたいところです。最初の手習いは当然、ASCIIART.BAS です。FLEX Basic で ASCIIART 画面をきれいに出力するには FLEX の TTYSET コマンドを使って 80 桁改行、ページャなしに設定する必要があります。

1 MHz 6802 / Flex 2.0 Basic:05:05.37

同じ 1 MHz 6800(6802)で動く Altair680 Basic と比較すると若干高速であることに気が付きます。

1 MHz 6802 / Altair68 Basic:07:35

同一プロセッサ、同一クロック数でこの処理速度の違いは?思って調べると、FLEX Basic はどうも浮動小数点の精度が低めなようです。試しに 10 進での有効桁数を確認しました。

1.00001 が表現できて 1.000001 が表現できないということは10進数有効桁数は7未満です。FLEX Basic マニュアルには「10 進 6 桁精度 (“six decimal digit accuracy”)」と記載されています [1]。

2^16 < 10^5 <  2^17  < 2^19 < 10^6 < 2^20

という比較が成り立つので、FLEX Basic 浮動小数点数の仮数部は 17-19 ビットの範囲のいずれかであるようです。例の「ケチビット」を勘定に入れると仮数部は 16-18 ビットで表現可能でしょう。また指数部については検証を怠りましたがマニュアルによると +/-38(10進)ですから 2 進換算で 7 ビット、これに加えて符号 1 ビットが必要となります。

FLEX Basic はおそらく 24 ビット精度の浮動小数点を使用していると推測されます。Aitair680 Basic その他初期 MS Basic は多くの場合 40 ビットまたは 32 ビット浮動小数点です。24 ビット浮動小数点の FLEX Basic で ASCIIART を実行した場合、計算量が少ない分速くなると言えそうです。

[補注]よく数えたら仮数部が 16-18 ビット、指数部(指数符号を含むオフセット表現)が 8 ビット、符号が 1 ビットとなり全体では最低でも 25 ビット必要になります。8 ビットマシンにしては半端なビット幅なので何か計算違いしている可能性があります。

参照

  • 1. TSC Basic Users Manual, 1979, Technical System Consultants, Inc.

Λ-1/Lambda-2022 の拡張(9)カセットインターフェイス

マイコンシステム Λ-1 は外部記憶装置としてカセットテープレコーダを使います。データ保存にテープレコーダを利用する手法は特に珍しいものではなく、1980 年前後の 8 ビットパソコンでは標準的な記録方式でした。コモドール 8 ビットマシン(PET/CBM/VIC/C64)や MZ-80 のようにデジタル信号専用インターフェイスのカセットデッキもあったようですが、多くは普通の音楽録再用デッキ(ラジカセ含む)の入出力端子に接続することを前提とした設計でした。Λ-1 も市販のカセットデッキを外付けする仕組みです。

カセットデッキ回路は音声信号処理を目的とするので 15 kHz 以上の成分の録音・再生は保証されません。接続方式によっては出力の位相が反転する可能性もあります。これらの条件に適した信号を変調・復調できるインターフェイス回路が必要です。

出力信号のソースは PIA の出力ポートなので 5Vp-p の矩形波です。パルス幅の違いでビット値 0 と 1 を表し、0 が 1400us、1 が 700us のパルス幅となります。なお実際には 1 ビットのデータあたり 1 周期分を出力するのでビット値 0 の出力に 2800us、ビット値 1 の出力に 1400us を要します。

「マイコン手づくり塾」記載の回路を参考にインターフェイスを組みました。回路図は次のとおりです。

PIA に接続する他の回路、つまりキーボード入力ポートや K68-VDG の垂直同期信号入力ポートなどもこの回路図に含まれます。図の中央付近がテープレコーダ録音再生のための変復調回路ですが、面白いのはカセットテープから再生された音声信号をパルス幅測定に適した波形に加工する復調回路です。入力音声信号をクランプ回路でクリップしたあとでコンパレータを通して矩形波に整形するのですが、Λ-1 の設計ではコンパレータとしてオーディオレベルメータ用 IC の三洋 LB1405 を使います。レベルメータ LED を見ながら入力レベルを調節できます。

Lambda-2022 筐体に組み込んだ回路基板は次の画像のとおりです(筐体奥のユニバーサル基板)。

筐体背面パネルにカセットデッキ入出力用の端子を追加しました。次の画像のとおりです。

“DOUT” “DIN” “RMT” というラベルのある部分がカセットデッキ用端子です。通常はポータブルテープレコーダに接続するための 3.5mm/2.5mm 端子(ラベルよりも右側の部分)があれば十分ですが、左側に RCA 端子による入出力も追加してあります。今回はコンポ型のカセットデッキを使うのでこの RCA 端子を使って接続します。ステレオデッキの L チャンネルのみ使用します。

カセットデッキは SONY のエントリレベルモデルを中古で入手しました。今となっては 3 ヘッドの中堅機あたりでも中古価格は大差ないのでしょうが[注 1]、メカや回路がシンプルな方がメンテナンスが容易になり、またデータ信号波形に余計な色がつかなくて良いのではと考えました。当然ドルビー NR は無効にして録音します。

カセットデッキを使うのは久しぶりです。メンテを済ませてから手持ちの新旧テープを聴くなどしばらく寄り道をした後、デッキの録音レベルを調節しながらセーブ・ロードのテストを繰り返しました。ところがエラーがなかなか解消されません。

どうしたものかと書籍「マイコン手づくり塾」を読み返すと、カセットインターフェイス製作の章ではなく別のページの読者 Q&A コラムの中でトラブルシューティングとして説明されていたのが、回路図中 R5 の両端に 0.1uF 程度のスピードアップコンデンサを追加するという手法です。これが効果的だったようで、インターフェイスからデッキへの出力信号が正確なパルス幅を含む波形になりました。

それでもまだロード時にエラーが出るので、今度はデータ入力側にオシロスコープを繋いで設定を詰めていきました。最終的にまあまあ安定したと思われる設定での波形が下図のものです(CH1: デッキからのオーディオ出力信号、CH2: 復調後のデジタル信号波形)。

念のため録音後 24 時間ほどおいて再度テストしましたが同様にパスしました[注 2]。

当時オシロは高価な機器だったため、専門家以外が簡単に使えるものではありませんでした。こういったアナログ絡みの回路をオシロの助けなしに上手く動作させるには長時間のカットアンドトライが必要になったはずです。Λ-1 のカセットインターフェイス回路に LED レベルメータが組み込まれているのも、調整作業が少しでも簡単になるようにという配慮があってのことと思われます。

注:

1. eBay を覗いたらそんな事はありませんでした。3 ヘッドデッキはエントリレベルデッキに比べて少なくとも 3〜4 倍の値付けです。

2. セーブ・ロードの対象はダンプの前半 32 バイトのみなので、後半 32 バイトが変化していても問題はありません。

Λ-1/Lambda-2022 の拡張(8)パラレルインターフェイスキーボードの作成

「マイコン手づくり塾」で Λ-1 に接続して使用するキーボードは ALPS AKB-3420 というパラレルインターフェイス仕様の機種です。7 ビット ASCII コードと Strobe 信号を送出します。

ALPS AKB-3420 はとうの昔に廃番になっており、それどころか現在ではパラレルインターフェイスキーボードというカテゴリ全体が、オークションサイトで探してもたまに見かける程度という希少品種です。

さいわい昨今はキーボード自作部品やツールキットが潤沢に供給されています。自作キーボードの手法でパラレルインターフェイスキーボードを作成しようと思います。

自作キーボードと言いながら、既製品を改造して近道しておりますが…

パラレルインターフェイスキーボードの構成

自作キーボードのファームウェアといえば qmk が定番ですが、qmk ではコンピュータとのインターフェイスとしてサポートされるのは USB のみです。Λ-1 および Chick-Bug モニタで使うキーボードは PIA に接続するパラレルインターフェイスが必要になるので、qmk をそのまま使用することは残念ながら不可能です。

かといってファームウェアをいちから書くのは結構な仕事です。どうしたものかと考えながら qmk_firmware ドキュメントを眺めていたら i2c 経由でパラレルインターフェイスを追加できるかも、と思いつきました。qmk_firmware にはキーマクロ用の C 言語インターフェイスがあるので、キー押し下げイベントに応じて ASCII コードをパラレルポートへ送信する処理が追加できそうです。この方向で試してみます。

また、今回は MCU として Raspberry Pi pico を使います。そもそもパラレル出力などという風変わりなことを試すのに、その上 qmk 標準から外れた RPi pico を使うのでいろいろ予想外の困難が出るかもしれません。段階的に確かめながら作っていくことにします。

RPi pico 版 qmk_firmware のビルドとインストール

Mac Parallels VM の上に Ubuntu 20.04 を新規インストールして専用開発環境を構築します。ホスト Mac 側から VSCode Remote Development で接続して編集、ビルドを行います。

おおよそ次のステップで新しい Ubuntu VM 上に環境を作りました。

  1. Raspberry Pi pico 公式ドキュメントなどを参考に SDK とサンプルコードをセットアップします。サンプルコード pico-examples の blink プログラム(L チカ)が動くところまで確認しておきます(参考)。
  2. qmk 公式ドキュメントを参考に qmk_firmware 環境をセットアップします。
  3. qmk new-keyboard コマンドで新しいキーボードを定義します。mcu として RP2040 を指定します(参考)。

注:2022 年 11 月現在で qmk_firmware の RP2040 対応コードは master ブランチにマージ済みなので、ブランチの切り替えは不要です。

テスト用に作るキーボードはワンキーでも標準的なフルキーでもいいのですが、ともかくキーアサイン定義を RPi pico GPIO に即して書き換えます。GPIO ピン名として “GPnn” という書き方ができます。

キーボードの設定にあたって主に書き換えるのは次のファイルです(キーボード名を ‘lambda2022a’ とした場合)。

  • keyboards/lambda2022a/info.json
  • keyboards/lambda2022a/keymaps/default/keymap.c
  • keyboards/lambda2022a/config.h

この時点で簡単なキー入力テストを行います。実際につなぐのは 1 キー分のスイッチなのでブレッドボード配線で十分です。キーマトリクスの 1 交点を選んでスイッチを GPIO ピンに配線し(1 キーなのでダイオードは不要)、スイッチ押し下げのテストを行います。

使い回しの部品ばかりでリードがよじれていますが動作には問題ありません

下の画面では主に ‘c’ キー交点にスイッチを配線して入力テストを行なっています。途中でブレッドボードの GPIO 配線を差し替えて他のキーに対応する交点にスイッチを組み替えた状態でもテストしています。qmk_firmware を使うとチャタリング回避の調整が不要になるのでその点は安定して使えます(画面中 ‘c’ や ‘b’ が何度も連続して表示されるのはそれだけキーを押したからで、チャタリングではありません)。

せっかくなので C 言語のサンプルキーマクロも動かしました。特定のキーコードの押し下げイベントに対応してカスタム出力が可能であることを確認しました。

GPIO Expander パラレル出力

ここで qmk のほうはいったん置き、GPIO Expander PCF8574 モジュールを RPi pico の i2c ピンにつないでパラレルポートのテストを行います。最も単純な接続方式として PCF8574 を RPi の i2c ピンに直接接続し、電源も RPi 3V3 出力に接続します。こうすると GPIO Expander の出力は RPi pico 動作電圧と同じ 3.3V レベルになります。

デフォルトの i2c SDA/SCL ピン(pin6 と pin7)を使い、pico-examples/i2c/lcd_1602_i2c/ をお手本にして PCF8574 へ 8 ビットデータを出力しました。オシロを見ながら書き込みデータを変えてみると任意の信号を出力できそうなので、ASCII コード(AKB-3420 の仕様に従い負論理 [注 1])を b0-b6 に書いてから b7 ストローブ信号を立ち下げる動作をさせます。これを Λ-1 の PIA に入力します。

上の画像は Λ-1 モニタプログラムのキーボード入力ソースを ACIA シリアルから PIA パラレルインターフェイスキーボードに切り替えた後で文字 ’Q’ を 1.6 秒間隔で受信している状態です。

これで、RPi pico + PCF8574 から 3.3V 出力の ASCII データを送信できることがわかりました。当初は信号が減衰してデータエラーが出る可能性を考慮して I2C 回線に 3.3V – 5V レベルシフタを挟むことも検討しましたが、3.3V レベルのままで 60cm 長のフラットケーブルを介して PIA 入力に信号が届くようなのでレベルシフタは割愛します。

RPi pico + PCF8574 でパラレル出力実験

qmk C マクロでパラレル出力ドライバを書く

前節の実験は pico-examples のサンプルコードを流用して書いたものですが、これを qmk 環境に移植します。

前述の qmk 設定に加え i2c 関連機能を有効にするために、次の各ファイルを変更します。qmk 公式ドキュメントの「Raspberry Pi RP2040」および「I2C Master Driver」のページを参考にしました。

  • keyboards/lambda2022a/halconf.h
  • keyboards/lambda2022a/mcuconf.h
  • keyboards/lambda2022a/rules.mk

qmk_firmware には i2c 制御のライブラリが用意されているはずですが、RP2040 ターゲットのビルドを行ったところライブラリのリンクや i2c の初期化がなかなかうまく行きません。ソースツリーの keyboards/ 以下にある他のキーボード用の i2c コードも参照しましたが、RP2040+OLED の組み合わせによる作例ばかりで i2c バス直接制御の使用例はないようです。

この i2c バス直接制御のための設定方法がわからず数日間悩みましたが、結局 rules.mk ファイルに次の 1 行を追加することで RP2040 ビルドでの i2c 関連のリンク、初期化ともほぼ自動的に行われるようです。

OLED_ENABLE = yes

前節と同じブレッドボード上のワンキー構成キーボードを使って、’q’ キーを押すと Λ-1 のパラレルキーボードインターフェイスに ASCII コード ‘Q’ が送られることを確認しました。同時に USB ポートへも ‘q’ キーの押し下げイベントが送信されています。

最後に、qmk のキーコード(KC_xx)とモディファイアキー状態 get_mods() から ASCII コードへの変換を行います。AKB-3420 相当のパラレル出力データとして必要なのは 7 ビット ASCII コードなのでチェックすべきキーコードの数も限られ、比較的シンプルな変換処理になります。

以上でコントローラの設定とプログラムはあらかたできました。次に物理的なキーボードの選定について検討します。

キーレイアウトと機種の選定

Λ-1 で使用された ALPS AKB-3420 の写真を見ると全キーが長方形に収まっておりなかなか端正なデザインです。今で言う 68 キー配列に近いものがあります。そこで既存の 68 キー配列キーボードをベースにしてパラレルインターフェイスキーボードを作ろうと思います。

(AKB-3420 画像出典:Deskthority WIKI)

最初は基板を起こして AKB-3420 のレイアウトを再現しようと思ったのですが、現代のキーキャップで構成するには若干無理があるため断念しました。パラメトリックキーキャップ設計ツールに習熟すればあるいは可能かもしれません。

当面は一般的な 68 キー配列の市販キーボードのケースや基板を流用します。AKB-3420 は ISO 配列ですが、個人的な好みにより ANSI 配列に変更します。AKB-3420 の最大の特徴は右側 2 列のリレジェンダブルキーキャップなのでここはなるべく再現したいところですが、現代の 68 キー配列ではこの部分は 1 列しかありません。ただ、Λ-1 ではこのエリアを多用しないので 1 列のままでもしのげるのではないかと思います(ATN キー、LF キー、ESC キーが最低限必要。LF、ESC はスペースバー横に配置しても可。ATN キーはマトリクスではなく直接配線が必要)。

68 キー配列ではカーソルキーが右端列の下端にはみ出しますがこれはそのまま残します。といっても Λ-1 / Chick-Bug ではカーソルキーはほぼ無用ですので、将来の拡張用といった位置付けになります。

既製品キーボードから流用するのはケース、スイッチプレートとマトリクス配線です。もともと基板に実装されていた MCU などは配線から除外します。今回 MCU として使用する RPi pico、PCF8574 などを足し合わせると既製品ケースには収まりきらないようなので当面はマトリクス配線をケース外に引っ張り出して結線します。いずれにしてもケースは再設計が必要なようです。

組み立てとテスト

既製品キーボードのマトリクスを調べたところ 15×5 でした。RPi pico ではマトリクスに GPIO ピンを 20 個割り当ててもまだ 6 個余るので、そこへ i2c を結線します。キーボード右上端のキーはパターンカットしてマトリクスから除外し、PIA の CA1(NMI 入力) に接続してプルアップ抵抗も付けます。これが Chick-Bug の Atn キーとして機能します。

この既製品キーボードをベースにしたテスト構成では、RPi pico と PCF8574 はブレッドボードに組んだまま使用しています。改造したキーボード基板から多数の線が出ていますが、この状態で実運用予定の構成と同じ配線になっています。

以前に作成したシリアルコンソールと独立して、パラレルインターフェイスキーボードと K68-VDG によるコンソールが動くようになりました。

***

以上で、パラレルインターフェイス方式の ASCII 出力キーボードを作成しました。ところで、よく考えたらこれは Apple II Plus にそのままつながりそうです。今後折を見て、キーレイアウトをカスタマイズしてテストしようと思います。

  1. AKB-3420 単体での出力は正論理ですが、Λ-1 では AKB-3420 にバッファ回路が追加されその部分でインバータを使用しているため Λ-1 への入力信号は負論理となります。

Λ-1/Lambda-2022 の拡張(7)K68-VDG の接続

Λ-1 システムの目玉機能のひとつは MC6847 VDG を使用したディスプレイインターフェイスです。なにしろカラーモニタディスプレイは当時の市販マイコン(今で言うパソコン)のアイデンティティで、標準的な自作ボードマイコンとは一線を画する機能でした。これさえあればビデオゲームが作れる!まあそう簡単に行くものではなかったのですが、表現力という点でカラーディスプレイは飛躍的な差が付くデバイスでした。

そんな MC6847 VDG ですが Λ-1 でサポートされるのは 32×16 テキストモードだけです。このモードでは VRAM は 512 バイトしか必要としませんし、同じメモリ量で使えるセミグラフィックモードでは 64×32 のまがりなりにもカラーグラフィックスが出力できたのです。グラフィックスといってもテキストモードに間借りして 2×2 ボックスパターンキャラクタを表示させるものですが、8 色カラー出力が可能でした。

当時はメモリのコスト面を考慮するとこのような低解像度の画面設定がベストだったわけですが、現在では大容量 SRAM がたやすく手に入ります。MC6847 がサポートする 8KB VRAM を最大限に使いたいところです。

ここまで考えると Kuni-Net 様設計の K68-VDG が選択肢に入ってきます。K68-VDG は今回作っている Λ-1 マシン(Lambda-2022)で採用した SBC-Bus に対応していますし、MC6847 の各種モードをサポートして VRAM は 8KB x 4 プレーンが利用できます。またビデオ出力が高画質であることも K68-VDG の利点です。

K68-VDG を Λ-1(Lambda-2022)で使うには VRAM アドレスと VDG 設定レジスタ(LS573 8 ビットラッチ)のアドレスを K68-VDG のオリジナル設計から変更する必要があります。

デバイス旧アドレス新アドレス
VRAM$A000-$BFFF$C000-$DFFF
VDG CTL$81xx$F048

このアドレスに沿って動作するためには K68-VDG のデコード回路に手を入れる必要があります。次のように設定します(元回路は K68-VDG リポジトリのこちらを参照)。

  • VRAM アドレス変更:SBC Bus ピン 35 に $C000-$DFFF デコード信号(VRAM#)が出るようにする(I/O 基板で実装済み)
  • VDG CTL アドレス変更:SBC Bus ピン 37 に VRAMCTL# が出るようにする(I/O 基板で実装済み)。また、K68-VDG の LS02(U5)のピン5, 6 と A8 の間の配線をカットし、代わりに A3 を U5 ピン 5, 6 に接続する
  • K68-VDG のアドレスデコーダ(U10、LS138)は実装しない

K68-VDG 基板上の実作業としては U3 のピン 5, 6 部分のみパターンカットとジャンパが必要になります(トレースの都合上 U9 へ A8 を再配線する必要があります)。それから、現在 NC となっている MC6847 の FS#(ピン 37)を I/O 基板上の PIA0 PA7に接続します。これはバスを介さずに行います。

このように若干手を入れる必要がありますが、MC6847 の VRAM をフル実装した K68-VDG の機能が簡単に利用できるのは大きな利点です。これも SBC-Bus を基盤として SBC ユーザの皆様の設計が標準化されているおかげです。

Chick-Bug の再改造

これでハードウェア的には K68-VDG を Lambda-2022 に接続できましたが、Chick-Bug モニタプログラムは現状ではシリアルコンソール専用に改造されています。これを VDG/シリアル両対応に再改造します。方針としては次のようになります。

  1. 以前シリアル用に書き換えたルーチン(disp1c, kbread, etc.)を一旦オリジナルコードに戻す。
  2. シリアル対応版ルーチンを別名(disp1csr、ineee)に変えて移動する。
  3. Chick-Bug ワークエリアに入出力ルーチンスイッチ変数 eeesw を設ける。bit7 … シリアル出力オンオフ、bit6 … VDG 出力オンオフ、bit0 … シリアル入力 (1) / パラレルキーボード入力(0) 切り替え、という設定にする。デフォルトは 0xc1
  4. disp1c ルーチンで eeesw bit7, bit6 をみて、それに応じて出力ルーチンの呼び出しをオンオフする
  5. kbread ルーチンで eeesw bit0 をみて、それに応じて入力ルーチンを切り替える

下の画像に示すように、シリアルコンソールと並行して VDG テキスト画面が表示されました。FS# を監視して VRAM への書き込みを同期することにより、画面のちらつきを抑えることが可能です。ただし FS# 同期、シリアルポートとの並行出力、ソフトウェアスクロールなど処理が増えるため描画速度は低下します。必要に応じて eeesw の設定を変えれば出力先を限定してある程度高速化できます。

Lambda-2022 の実装

現時点で Lambda-2022 内部の実装状況は次の画像のとおりです。

ついに SBC-Bus スロットがいっぱいになってしまいました。画像奥(筐体前面側)から

  1. DMA カード
  2. CPU/SRAM カード
  3. VDG カード
  4. I/O カード

が装着されています。フル装着時の負荷に備えて、このケースにはスイッチング電源を装備してあります。また SBC-Bus の +5V 供給ラインだけでは心もとないのでフロントパネルと I/O 端子には別のケーブルで電源を供給しています。筐体裏側にはビデオコネクタパネルおよびシリアルコネクタパネルを追加してあります。

Λ-1/Lambda-2022 の拡張(6)Chick-Bug 拡張

Chick-Bug の標準機能がだいたい動くようになりました(カセットテープのロード/セーブは未検証)。予想通りフロントパネルの DMA スイッチ類はほとんど使わなくなってきましたがそこは気にせず、Chick-Bug へ次の機能を追加します。

  • S19 読み込み
  • メモリダンプ
  • MB8861 命令の書き換え

S19 ストリームの読み込み

SBC68 シリーズを使ってわかったことですが、シリアルコンソールが近代的なコンピュータに接続されている場合、ユーザプログラムをロードするには S19 ファイルの内容をコンソール画面にコピペする方法が最も手軽です。この機能、つまり MikBug の L コマンドを Chick-Bug に追加します。

基本的なコードは SBC68 版 MikBug とほぼ同じです。コマンド名には ‘O’ を割り当てます(’L’ はカセットテープロードコマンドですでに使用されているため)。ロードが終わったら待機モードに戻ります(他の Chick-Bug コマンドと同じ終わり方)。

ちなみに元祖 MikBug の L コマンドはテレタイプ端末の紙テープリーダを前提としていたようです。’L’ コマンドをテレタイプ端末のキーボードから入力した後、入力ラインをテープリーダに切り替えてテープを走らせ、内容を読み込みます。すると S19 データストリームが 110 baud でテープリーダからコンピュータへ送られるという仕組みです。一度でいいのでこの紙テープ読み込みを SBC シリーズや Λ-1 でやってみたいですね。

メモリダンプ

Chick-Bug 標準機能の M コマンドは 1 バイトずつの表示・確認となり操作が若干煩雑です。ダンププログラムは 64 バイト単位で表示するので操作が楽になります。「マイコン手づくり塾」の Chick-Bug 開発編にユーザプログラムとして掲載されているものを Chick-Bug 自体に組み込んでしまいます。コマンド名は ‘D’ とします。

***

これらのコマンドを追加することでモニタ内各ルーチンのエントリアドレスが変わってしまいます。今までに作成した、モニタサービスルーチンを使ったユーザプログラムは変更が必要になりますが、そもそも Lambda-2022 ではオリジナル Λ-1 から ROM アドレス自体が変わっているので今回の変更の影響は相対的に小さいものです。

MB8870 命令の書き換え

「マイコン手づくり塾」ではモトローラ MC6802 互換の各種チップを総合的に比較検討した結果、富士通 MB8870 が採用されました。MB8870 の最大の特徴は独自命令が追加されていることです。富士通製 MPU では MC6800 互換の MB8861 の頃から同じ独自命令群が採用されていました。Chick-Bug プログラムの中でもこれらの独自命令が使用されているのですが使用箇所はそれほど多くなく、多少の工夫で置き換えられます。MB8870 と MC6802 はピン互換ですから、MB8870 独自命令がなくなるよう書き換えてしまえば MC6802 チップを Lambda-2022 に装着できます。

以下、MB8870 の独自命令と使用箇所をそれぞれについて検討します。

ADX 命令

6 箇所使われており、そのうち 4 箇所は ADX #$03 という固定値加算で、加算値も小さいので inx を 3 行並べるだけで置き換えられます。

もう一つは ADX #$1F となっています。inx を 31 個も並べるというのも不格好でどうしたものかと思っていたところ、前後をよく読むとこの行での X レジスタの値は不変です。次のように書き換えられます。

変更前:
            ldx #ccrm
            stx xopnd1
            adx #$1f
            stx xopnd2


変更後:
            ldx #ccrm
            stx xopnd1
            ldx #ccrm+$1f
            stx xopnd2

最後の一つは変数へ加算しているため、A/B アキュムレータを使った 2 バイト加算に展開せざるを得ません。前後に A/B アキュムレータの退避・復帰を含むためステップ数が増えます。逆に言うと、これが MB8870 ADX 命令の真価を発揮するケースになります。

変更前:
lf          ldx cpoint
            adx #$20
            stx cpoint

変更後:
lf          psha
            pshb
            ldaa cpoint
            ldab cpoint+1
            addb #$20
            adca #0
            staa cpoint
            stab cpoint+1
            pulb
            pula

NIM、OIM 命令

それぞれ一箇所しか使われていません。どちらもカセットインターフェイス出力処理の中です。

bitout   psha
            pshb
            ldx #pdrb1
nim1    nim $fe00     [8]
            decb             [2]
            bne nim1      [4]
            pulb
oim1    oim $0100    [8]
            decb             [2]
            bne oim1      [4]
            pula
            rts

ここでは PIA の DRB レジスタの PB0(カセットデータ出力)のオフとオンを行い、オーディオ出力を一瞬トグルする効果を求めています。周期は bitout ルーチン呼び出し元で指定する AccB の値で決まります。次のように設定されています。

soutlp  lsra
            bcs markot
            ldab #$64
            bsr bitout
            bra nxtbit
markot ldab #$32
            bsr bitout
nxtbit   dec bitctr
            bne soutlp

つまり出力 ‘1’ の半周期分のループは $32 カウント(50)、出力 ‘0’ の半周期分のループは $64 カウント(100)です。具体的な半周期長はループ処理の命令サイクル数で決まりますが、命令サイクル計算に必要なデータは MB8861 命令シートに書いてあります(「マイコン手づくり塾」に掲載されています)。簡単のためループ外の命令サイクルを除外して計算すると出力 ‘1’ の半周期は 14us x $32 = 700us、出力 ’0’ の半周期は 14us x $64 = 1400us となります。

同等の処理を MC6800 命令で再現するには次のように nim、oim を書き換えます。

bitout   psha
            pshb
            ldx #pdrb1
            ldaa 0,X
            anda #$fe
            staa 0,X
nim1    nop               [2]
            nop               [2]
            nop               [2]
            nop               [2]
            decb             [2]
            bne nim1      [4]
            ldaa 0,X
            oraa #$01
            staa 0,X
            pulb
oim1    nop               [2]
            nop               [2]
            nop               [2]
            nop               [2]
            decb             [2]
            bne oim1      [4]
            pula
            rts

nim ないし oim 命令 1 個の代わりに nop を 4 個挿入することでループ内の合計サイクル数が一致するので、タイミングも同じになります。

以上で MB8870 独自命令使用部分をすべて書き換えることができました。一箇所を除いていずれも独自命令を使用する必然性があまりない処理であったように思えます。特にカセットインターフェイス出力の部分は nim/oim を使用するのであればそもそも AccA を退避する必要はありません。書き換え後のように PIA レジスタ操作に AccA を使うのであれば事前退避が必要になるので、ここはもともと MC6802 互換で書かれていたという可能性も考えられます。

注:

現時点ではまだカセットインターフェイス回路を作っておらず、PIA ポートが未接続のまま放置されています。せっかくなので SAVE コマンド出力信号を実測しました。最初に MB8870 拡張命令を使った処理の場合の出力波形です(D0 チャネル)。

たしかにマーク半周期 ~720us、スペース半周期 ~1410us となっています。

次が MC6802 命令で書き換えた後の SAVE 出力波形です。

こちらもマーク半周期 ~700us、スペース半周期 ~1490us とおよそ一致します。どうもデューティ比が正確に 50% ではないようで、ループ外の命令サイクルの影響だと思われます。

Λ-1/Lambda-2022 の拡張(5)Chick-Bug 移植

オリジナル Chick-Bug は Λ-1 に接続されたパラレルインターフェイスのキーボードと VDG ディスプレイをコンソールとして使用しますが、今回作成する Lambda-2022 システムではコンソールとして ACIA シリアル回線を追加しています。またメモリマップも変更がありますので、これらに対応するため Chick-Bug を次のように変更します。

ワークエリア:オリジナル Chick-Bug ではスタックを含むワークエリアが $F700-$F7FF に設定されていました。他の用途と干渉しない RAM 領域 $A600-$A6FF に変更します。

PIA アドレス:オリジナル Chick-Bug の PIA アドレス $EE00..$EE03 を今回作成した I/O ボードの PIA0 アドレス $F008..$F00B に変更します。

VDG アドレス:オリジナル Chick-Bug の VRAM アドレス $F000-$F1FF を $C000-$C1FF に変更します。またシステム初期化時に VDG コントロールレジスタ($F048)に適切な値を設定します。

ACIA 初期化:SBC68 版 MikBug 同様に ACIA を初期化します。システムリセットルーチン restp 内で ACIA 初期化ルーチンを呼び出します。

PIA、ACIA の接続状況は次のようになります。

Desc.DEVI/O RegisterOrig Addr.New Addr.
K/b asciiPIA0PA0-6pdra1$ee00:b0-6$f008
6847 vsyncPIA0PA7pdra1$ee00:bit7$f008
k/b strobePIA0CA1pcra1$ee01:bit7$f009
k/b ATN NMIPIA0CA2pcra1$ee01:bit6$f009
tape mtrPIA0PB1pdrb1$ee02:bit1$f00A
tape outPIA0PB0pdrb1$ee02:bit0$f00A
tape inPIA0PB7pdrb1$ee02:bit7$f00A
tape inPIA0CB1pcrb1$ee03:bit7$f00B
SerialACIACSaciacs$f028
SerialACIADAaciada$f029

Chick-Bug はプロンプト呼び出しのためにハードウェア割り込みスイッチを使いますが、これは元設計通り PIA0 CA2 へ接続します。当面は、前回 PIA のテストに使用したブレッドボード回路をそのまま流用します。

シリアルコンソール対応

冒頭に述べたように、オリジナル Λ-1 のコンソールに加えて ACIA シリアルコンソールをサポートしようと思います。将来的には VDG/パラレルキーボードとシリアル入出力を切り替えるようにしますが、当面はシリアル入出力のみ対応するコードを書きます。次の要領で 機能を変更します。

入力:オリジナル Chick-Bug では PIA0 PA ポートと CA1 に接続されたパラレルインターフェイスキーボードから入力を読み取っていました。これをシリアル入力に置き替えます。

  1. kbread ルーチンの処理をシリアル入力処理に置き換える。
  2. シリアル入力処理は SBC シリーズ版 MicBug の ineee ルーチンを参考にして記述する。

出力:オリジナル Chick-Bug では文字出力は VDG のテキスト画面へ送られますが、シリアルコンソールに同等の内容を出力できるようにします。VDG への文字出力はおもに disp1c で行われますが、画面クリアやスクロールなどの処理で VDG 直接操作があり、これらすべてをシリアルコンソール対応処理に変更します。次のように改造します。

  1. Chick-bug の中で VDG VRAM 操作に関連するルーチン(cpoint、vramt1 を直接使用する処理)を特定する。
  2. 該当する下記のルーチンをシリアル出力(outeee)対応に書き換える。
clear1, chmark, clrhm1, lf, crlf, bs, disp1c, scrolu

初期化の部分を除くと Chick-Bug モニタの他の部分から表示のために呼び出されるのは disp1c だけのようです。将来的に VDG/シリアル出力を切り替える場合は、disp1c 内で切り替え判定をすれば十分です。

シリアルコンソールの処理では HOME、CLEAR などのエスケープコードを使用します。

改変後の Chick-Bug ソース内のアドレス配置は次のとおりです。

$a600-$a66b   :システムワークエリア
$a6ff                :スタックトップ
$f080-$fa74      : Chick-Bug コード

***

以上の要領で移植作業を進めます。Chick-Bug はもともと Λ-1 ハードウェア用に書かれたモニタプログラムなのでこれを改変することを「移植」と言うのも少し変ですが、ともかく上記の方針に沿って書き換えます。

Chick-Bug 動作確認

書き換えた Chick-Bug はシリアルコンソール上での対話ができるようになっています。各コマンドの動作画面は次のとおりです。

‘M’ コマンドはメモリ内容の表示と書き換えです。

’G’ はユーザプログラム実行、’B’ はブレークポイントの設定/確認/解除です。

カセットテープインターフェイスコマンドの確認

カセットテープのロード/セーブ機能の確認はカセットレコーダインターフェイス回路を作ってから行います。

VDG 上の動作画面

本来の出力である VDG 画面はまだ確認できません。今後 VDG 回路を追加したときに確認します。

なお今回使用する予定の K68-VDG では 6847 の反転文字と通常文字を区別しているので、Chick-Bug が印字する通常の ASCII 文字($20-$5F)は後半のみ反転します。VDG 出力時に表示コードを適宜変換する必要があります。

今後の計画

全部できるかどうかわからない予定を再度並べてみます。

  • K68-VDG の接続
  • カセットテープレコーダ回路の作成とテスト
  • パラレルインターフェイスキーボードの作成

Λ-1/Lambda-2022 の拡張(4)新 CPU カードと I/O カードの製作・テスト

注文の基板が到着しました。さっそく 2 枚のカードを製作します。

新 CPU カードの製作とテスト

旧 CPU カードと同じ要領で部品を組み付けます(今回も配線ミスがありジャンパが必要になりました)。最初に CPU カードのみテストします。まず SRAMSEL ピンをプルアップして CPU カード単体で SRAM を常時有効にします。その後、旧 CPU カードと入れ替える形でバススロットに装着します。この時点で Lambda-2022 システムには 64KB フル RAM を実装した新 CPU カードと DMA カードが接続されています。

$0000-$7FFF の 32KB SRAM をテストするために次のプログラムをフロントパネルから入力、実行します。

***
* memtest $0000-$7fff
***
*
* set val to write 


val     equ $55   ; test val
erradr  equ $8100  ; address where test failed
mstart  equ $0000  ; mem test start addr
mend    equ $8000  ; mem test end addr + 1
*
        org mend
start   ldx #mstart-1
        stx erradr  ; if (erradr)=mstart-1, test succeeded; otherwize test failed
        inx
        ldaa #val
loop    staa 0,X
        cmpa 0,X
        beq ok
        stx erradr
        bra endl  ; test failed, end prog
ok      inx
        cpx #mend
        bne loop
endl    bra endl
*
        end

val を $55, $aa, $00, $ff の 4 種に変えてテストします。

$8000-$FFFF の 32KB SRAM のテストプログラムもほぼ同様で、テスト対象領域とテストプログラム領域、およびワークエリアのアドレス値を変更します。

val を $5a, $a5, $0f, $f0f の 4 種に変えてテストします。

動作上ちょっと面白い点として、2 つ目のテストプログラム($8000-$FFFF の SRAM メモリテスト)はリセットベクタ $FFFE-$FFFF まで書き換えてしまいます。ROM のない初期構成の Λ-1 ではいったんプログラムが開始してしまえばリセットベクタは不要になるのでこれでも問題なく動作します。ちなみにここまで Λ-1 用に書いたどのプログラムもスタックポインタの初期化を行っていません。割り込み処理やサブルーチン呼び出しがない場合はスタックポインタの設定も不要です。

メモリテストはやりだすときりがありませんが、以上で 64KB 分の SRAM テスト完了ということにします。SRAMSEL のプルアップを取り除いて CPU カードを再装着します。

I/O カードの製作

I/O カードを製作するには GAL20V8B のプログラミングが必要になります。といっても必要なのは静的なデコーダロジックですから、回路図に書いた論理式をソースファイル(*.PLD)に書き写すだけです。

GAL のデザインツール WINCUPL を使用するには比較的古い OS が必要になります。このために温存してある Win7 VM を引っ張り出して WINCUPL を起動しました。はじめは JED ファイルが生成されずまごつきましたが、どうも PLD ファイルの Device フィールドを無視して WINCUPL のメニューからデバイスを選んでやると正しくコンパイルされるようです。しばらく使っていなかったので手順を忘れていました[1] [2]。JED ファイルを生成したら、TL866 ROM ライタを使って EPROM と同じ要領でプログラムします。

PIC のプログラムも必要です。SBC シリーズ用にクロック生成のための HEX ファイルが用意されているので、これを書き込みます。今回は 38400bps 設定にしました。

I/O + ROM カード(PIA は未装着)

I/O カードも基板設計時の回路に諸々不具合がありパターンカットとジャンパ線で修正しました。修正点は以下のとおりです。

  • 28C64 の WE# を NC から +5V プルアップに変更
  • PIC クロック出力をピン 2 からピン 5 に変更
  • PIA、ACIA の R/W# ピン接続先をバス WR# からバス R/W# に変更

最後の修正はもしかしたら不要だったかもしれません。

新システムハードウェアのテスト

以上で拡張 Λ-1 システムのハードウェア基本部分ができましたが、ROM にはまだなんのプログラムも書き込まれていません。数回前の投稿でソースを準備した Chick-Bug の移植を始めてもいいのですが、まずは MikBug を書き込んでみます。SBC6800 版の MikBug ソース内の ACIA、ワークエリア、コード開始位置のアドレス定義を書き換えて再アセンブルすると Λ-1 で動きます。冒頭付近数行のアドレス値を書き換えるだけです。

*	ADDRESS
ACIACS	EQU	$f028
ACIADA	EQU	$f029
VAR	EQU	  $a600
*
*	OPT	MEMORY
	ORG	$f100

これらのアドレス値は下記のメモリマップにもとづいています。G コマンドの設定アドレスは $a648/$a649 となります。

MikBug の L コマンドを使って S19 データを流し込み、Hello World プログラムを実行しました。シリアルコンソールと L コマンドがこんなに有り難く感じたことはありません。フロントパネルスイッチをパチパチと操作して 1 バイトずつ入力する作業に比べると数段楽です。まあ、そのパチパチ操作のために Λ-1 を作ったのですから本末転倒する感想ではありますが、シリアルコンソールとモニタ ROM が動いた時点でフロントパネル DMA の必要性が失われてしまうのは事実です。

MikBug のコンソールが動いたので ACIA はテスト済みとみなします。次に PIA について 2 つのテストを行います。

PA / PB ポート:L チカ

PIA0 に MC6821 PIA をセットします。PIA0 のレジスタにはアドレス $f008-$f00b でアクセスできますので、全ポートを出力に設定した上で適当なループタイマを挟んで PortA と PortB の両方に $00 と $ff を交互に書き込みます。20 回繰り返したらプログラムを終了します。

「L チカ」と称する以上は適当なドライブ回路を PIA ポートに接続して LED を点滅させるのが筋ですが、面倒なので PIA ポート出力をロジアナで直接測定します。下の画面では D0 が PA0、D4 が PB0 に接続されており残りのチャネルは未接続です。

想定通り PA/PB 出力が 20 回点滅しています。(L チカプログラムはこちら

CA1 ポート:NMI 割り込み

この I/O ボードの PIA0/PIA1 の IRQA ピン(38)は 6802 NMI 割り込み(プルアップ済み)に接続されています。CA レジスタの以下のビットを書き込み・読み出しすることで IRQA を通じて割り込みを発生できます。

bit0 = 1:CA1 による割り込みを有効にします。割り込み信号に反応して IRQA ピンが立ち下がります。
bit1 = 0:CA1 割り込み信号を立ち下がりタイプに設定します。
bit7:読み出し値が 1 の場合、CA1 入力による割り込みが発生しています。PA レジスタを読み出すと値はクリアされます。

CA1 ピンに次の割り込みボタンを付けます。

MikBug の NMI 割り込みハンドラは NIO が示すアドレスへジャンプします。NIO は Lambda-2022 版 MikBug の場合 $a606-$a607 です。

画面下端近くのメッセージ行 “INTERRUPT VIA PIA0 CA” が割り込みハンドラによるものです。(割り込みハンドラプログラムのソースはこちら

***

これらのテストで I/O ハードウェアは問題なしとみなすことにします。次回は Chick-Bug の移植に移ります。

注:

  1. スクリーンショットの PLD コードにあるように Device: gal20v8a; とすると動くようです。
  2. この GAL 書き込みを終えてから code-cupl という VSCode 拡張機能を見つけました。code-cupl の ReadMe によるとコマンドライン用 cupl.exe は Windows 10 上でも動作するようです。ただし ReadMe にかかれている比較的複雑なコマンドラインオプションやライブラリファイルが必須で、さらに exe ファイルの互換モードを設定する必要もあります。

Λ-1/Lambda-2022 の拡張(3)I/O カードの設計

この I/O カードは新規設計となります。次の I/O デバイスおよびメモリを接続します。

  • PIA x 2
  • ACIA x 1
  • 4KB ROM
  • VRAM (デコードのみ)
  • VRAM コントロールレジスタ(デコードのみ)

ACIA は PC とのシリアル通信に使用します。PIA は 1 つに付き PA/PB 2 バイトのポートがあるので 2 個の PIA で合計 4 バイト分 = 32 ポートが使えます。これ以外に割り込み可能ポート CA1/2、CB1/2 が 2 セットで合計 8 ポートあります。PIA には次のようなデバイスを接続できます(全部作成するとは限りません)。かっこ内は(Px ポート数 + Cx ポート数)です。

  • フルキーボード(7+2)
  • カセットインターフェイス(3 + 1)
  • VDG 垂直同期割り込み(0 + 1)
  • 16 進キー/LED コンソール(9 + 0)

I/O カードのもう一つの重要な機能はアドレスデコード回路で、カード上のデバイスに加えて SRAM、VRAM 関連のデコードも行います。詳細を検討するために、まずメモリマップを再掲します。

次のアドレスをデコードする必要があります。

デバイス開始アドレス終了アドレス使用バイト数
VRAM$C000$DFFF8192
PIA0$F008$F00B4 + 4 ghosts
PIA1$F010$F0134 + 4 ghosts
ACIA$F028$F0292 + 6 ghosts
VDGCTL$F048$F0481 + 7 ghosts
ROM$f080$FFFF3968

細かい変更として、前稿掲載のマップに比べて PIA、ACIA 等 I/O デバイスのアドレスが若干移動しています。これは PIA 等のチップで使用できる CS ピンの組み合わせが限定されるためです。変更はあるものの A3-A15 は重複がないようにデコードされるので、I/O 領域内に 8 バイトブロック単位で適切に割り当てられます。

上の表に示した I/O、ROM、VRAM 領域をアクセスしている間は、SRAM イネーブルを無効にします。このイネーブル信号が SRAMSEL で、バス 33 ピンへ出します。同様にして VRAM 領域アクセス時は VRAM#(バス 35 ピン)、VRAM コントロールレジスタアクセス時は VRAMCTL#(バス 37 ピン)をアサートするようにします。IO デバイス(PIA0、PIA1、ACIA)についても同様のイネーブル信号を生成します。これらのアドレスデコードは VMA 有効時のみイネーブルとなるようにします。

多数のアドレス線とイネーブル信号が交錯するので、GAL デバイスを使って一括デコードすることにしました。次の回路図になります。

このカードでは 600mil 幅の IC を多数使う上、I/O ピンヘッダも多いので 95mm x 75mm 基板にギリギリ収まるサイズでした。もしかしたら基板サイズを多少延長したほうが良かったかもしれません(95mm x 95mm など)。

ここまでで新 CPU カードと I/O カードを設計したので、PCB 製造を発注します。基板が到着したら作業を再開します。

Λ-1/Lambda-2022 の拡張(2)MB8870 CPU カード再設計

Chick-Bug モニタのソースコードを読んで仕様とハードウェア処理の概要を把握したので、これに応じて CPU カードを作り直そうと思います。次の方針で設計します。

  • RAM 60KB、ROM+I/O 4KB のメモリ構成
  • VDG VRAM 8KB の追加に対応

最初にメモリマップを考えます。

Lambda-2022 拡張メモリマップ

次の要領で割り当てています。

  1. CPU カードには 32KB SRAM チップを二個使って 64KB 全域に RAM を割り当てる
  2. ROM、VRAM、I/O のアクセス時には SRAM セレクトを無効化する

ROM、VRAM、I/O のアドレスデコードは I/O カード設計時に詳細を決めます。1、2 の方針を元に再設計した CPU カードの回路は次のようになります。

この回路は Lambda-2022 CPU Rev. 2 となります。Rev. 1 からの変更点は以下の通りです。

  • 2 個めの 71256 SRAM を追加($0000-$7FFF)
  • MPU 内蔵 RAM を無効化
  • SRAM は SRAMSEL 信号有効時のみアクセスされるようにする
  • SRAMSEL 信号は I/O カード上でデコードされたものを利用する(バス 33 ピンに接続)

SRAMSEL 信号をカードをまたいで使用するため、SBC Bus のデコード信号部分を改変して再割り当てすることにしました。上記回路図中の SBC Bus はこのあたりがオリジナル版とは異なってきています。

次回は I/O カードを設計します。

Λ-1/Lambda-2022 の拡張(1)Chick-Bug 解析と計画

以前の投稿で書籍「マイコン手づくり塾」の前半およそ三分の一の内容を実装するマシンを製作しました。フロントパネル DMA で 6802 コンピュータのメインメモリを直接読み書きするという目標を達成できたのでこの段階で終了しようかとも思いましたが、せっかくなのでもう少し Λ-1 の機能拡張を試みます。

***

「マイコン手づくり塾」の後半はカラーディスプレイインターフェイスとシステムモニタプログラムの製作が山場となります。フルキーボードやカセットインターフェイスも追加され、仕上げとして Tiny BASIC を移植すると当時のいわゆる「マイコン」市販品、今で言うパソコンと同レベルのシステムが構築されて自作派にとって大きな目標達成となります。

当時の状況ではこれは大事業でした。大半のユーザは既製品のマイコンシステムが手元になかったので、各種の機材や開発環境がない状態でシステムを作り上げる必要がありました。たとえばアセンブラ処理系がない初期段階ではプログラムをハンドアセンブルで仕上げる必要があります。また外部記憶装置を得るためにまずカセットインターフェイスのハードウェアを作ります。その後 ROM ライタ回路を作り、ROM 書き込み用コードを書くとようやくモニタ ROM が作成できるのでした[1]。

「マイコン手づくり塾」単行本の内容は雑誌掲載時と若干順序が入れ替わっているのですが、この単行本に準拠すると後半部は VDG 回路 > キーボード回路 > カセットインターフェイス > ROM ライタ > Chick-Bug モニタ ROM の順番で製作が進行します。当時の開発環境事情に照らし合わせるとこの制作順しかほぼ方法がなく、壮大なブートストラップ手順と言うほかありません[2]。

しかし現代の開発環境があれば上記のような制約は問題になりません。モダン OS 上で高速なクロスアセンブラやディスアセンブラが使え、豊富なプラグイン機能が揃ったエディタもあります。ROM ライタもかつてとは比較にならないほど安価に入手できます。

今回はこれらの利点を最大限に利用して、興味のある部分だけをピックアップした上で次の手順で Λ-1 の機能拡張を進めていきたいと思います。

  1. 「マイコン手づくり塾」掲載の Chick-Bug ソースコードを入力する
  2. CPU ボードを 64KB RAM 構成で再設計する
  3. I/O + ROM カードを設計する
  4. Chick-Bug の入出力を SBC シリーズ同様の 9600 kbps シリアルに対応する

その後、余力に応じて次の機能追加を検討します。

  • VDG 製作
  • フルキーボード製作
  • カセットインターフェイス製作
  • 16 進キー + 7 セグコンソール製作

ここまで機能拡張してしまうと当初の製作動機であったフロントパネル DMA はほぼ無用の長物となってしまうのですが、これはシステムの進歩段階の違いのようなもので仕方ありません。たとえば PDP-11 の後期モデルや Altair のターンキーモデルでも、フロントパネルの入出力デバイスは撤廃されています。

Chick-Bug ソースコードの入力と解析

どこまでやるのかもわからない製作計画を延々と練ってきましたが、まずは Chick-Bug モニタのソースコードを入力して内容を読んでみることにします。

Chick−Bug ソースリストは書籍「マイコン手づくり塾」巻末に二段組 9 ページにわたって掲載されています。オリジナルのモニタ ROM アドレスは $F800-$FFFF の 2KB です。その直前 $F700 台にワークエリアが定義されており、つまり $F700 台 は RAM が想定されています。

後で説明するように今回作成するシステムでは ROM/RAM および I/O のアドレスを変更するのでこのままでは動作しませんが、とりあえずオリジナルソースをそのまま入力します。入力したコードを眺めて気がついた Chick-Bug の特徴は以下の点です。

  • 富士通 MB8861/8870 の拡張命令 NIM、OIM、ADX が使われている
  • コンソール出力に VDG テキストモードを使用(VRAM 512B)
  • PIA A ポートに接続されたキーボードから入力を取得
  • PIA B ポートに接続されたカセットテープレコーダでロード、セーブを行う(出力:PB0、入力:CB1)
  • 割り込みスイッチをPIA CA2 経由で NMI に接続し、NMI 割り込みでモニタコマンドプロンプトへ移動

MB8870 の拡張命令が使用されている場所は限られるので MC6800 互換コードに書き換えるのもあまり大変ではなさそうですが、当面は手持ちの MB8870 を Λ-1 に装着して使用することにします。ただしこれらの MB8870(MB8861)拡張命令は私が普段使用している as0 アセンブラではサポートされていませんので、アセンブル済みバイナリ列を fcb 疑似命令を使ってソース内に埋め込んでおきます。

キーボードと VDG からなるコンソールのためのサービスルーチンは全体の 30% ぐらいの分量を占めます。当面はこのコンソールの代わりに、SBC シリーズを参考にしてシリアル入出力のサービスルーチンを追加します。キーボードや VDG ディスプレイアダプタといったハードウェアはいつ作成するか決めていないので、入出力デバイスはフックを使って切り替えられるように改変しようと思います。

カセットテープレコーダインターフェイス周りのコードは全体の 20% 程度です。インターフェイス回路自体は PIA の外側に接続されるものなので、ひとまず対応 PIA ポートのみ作成してインターフェイス回路は後回しにします。

ソースコード中、ワークエリアや I/O を参照する一部の行でアドレスをラベルでなく 16 進値で直接指定している部分があったので、それらはラベル表記に書き換えておきました。将来ワークエリアを移動する時に作業が簡単になります。

***

ところでこの「マイコン手づくり塾」掲載のソースリストは pass2 処理のアセンブルリストであることに気づきました。左側オブジェクトコード中の一部のブランチ先アドレスが解決されておらず “00.” 表記となっています。またラベルの参照元アドレスがラベル行の下に挿入されており、それら参照元アドレスがリストされている行はソースコード部分が空欄となっています。いわばアセンブル作業の中間データがそのまま挿入された状態になっており、このあたりは当時のアセンブラ処理系固有の作法なのかもしれませんが、バイナリレベルでの照合が若干難しくなります。

入力したソースを as0 コマンドでアセンブルし、エラーなくオブジェクト(S19)が生成されることを確認しました。アセンブルリストもおおむね書籍掲載の内容と一致することが確認できました。このソースを元に Lambda-2022(いま作っている Λ-1 変種)のための Chick-Bug として改造していきます。

  1. 実際にはカセットインターフェイスや ROM ライタのファームウェアをその都度入力するのは大変なので、連載期間中に誌上通販などの形でモニタ書き込み済み PROM の頒布が行われたであろうと推測されます。
  2. 「マイコン手づくり塾」単行本の目次と各章題ページの雑誌掲載号情報によると、次のような順になります。
    A:ウォーミングアップ(’78/2-6)

    B:Λ-1 本体基本部分製作(’78/8-12, ’79/1)
    C:6802 プログラミング(’79/2, 3, 4)
    D:VDG 製作(’79/5-8)
    E:キーボードインターフェイス製作(’79/10)
    カセットインターフェイス製作(’79/12, ’80/1)
    I/O 拡張基板(’80/5, 6)
    ROM ライタ製作(’80/8)
    F:Chick-Bug(’80/2, 3, 4)

    ‘N’ Tiny-Pilot 言語(’80/7)
    RAM68 アセンブラ(’80/9)
    電大版 Tiny Basic(単行本書き下ろし)