GMC-no

外観 Arduinoで作るGMC-4互換機です。 むしろFXマイコン互換機と言うべきかも。

回路図

シールドの回路図です。見やすいように3つに分割しました。

メイン部分

メイン部分の回路図 7セグLEDはアノードコモンです。小数点も使います。 抵抗は使うLEDによって調整してください。

キーパッド部分

キーパッド部分の回路図 途中を省略していますが、ボタンは全部で21個です。“0"から"F"までは順番どおりに並びます。 抵抗も各ボタンの間に1個ずつ入ります。抵抗値は1kΩと10kΩとかの組み合わせでも良いです。 “CLEAR"はハードウェアリセットボタンのことです。RESETキーと紛らわしいので勝手に名前をつけました。スケッチの中でもこの名前を使っています。

オーディオ出力部分

オーディオ出力部分の回路図

ヒント

(2022/5/1追記) この部分は変な回路ですね。 特に意味があるわけではなく、これを作った当時の作者が無知だっただけなので、実際に作る場合は参考にしないほうがいいと思います。。

ソフト

スケッチ
別途pitches.hが必要です。


使い方

ほぼGMC-4と同じです。内蔵プログラムもすべて実装されています。ソフト的にGMC-4の上位互換(のはず)なので既存のプログラムはそのまま動くはずです。

GMC-4と違うところ

  • LEDはすべてスタティック点灯なので、ちゃんとしたPOVができます。
  • FXマイコンにならって、オーディオ出力は中央のバイナリLEDと共用しているので、中央のLEDの状態が変わるときにもプチッという音が出ます。
  • スピーカが小さいと低音があんまり出ないので、電子オルガンなどの音はGMC-4よりも1オクターブ高くしてあります。
  • GMC-4で削除されていたCAL INPT命令(E3)が使えます。(動作がFXマイコンと違うかも?)
  • セーブ/ロードなどのコマンドが追加されています。
  • メモリ空間は256ニブルに拡張されています。アドレスの8ビット目は7セグの小数点で表します。
  • 拡張命令が16個追加されています。

拡張された機能

コマンド

  • [3][RUN][番号]で、メモリの内容をセーブできます。0番~3番だとEEPROM内の各スロットに保存、4番以上だとシリアル通信でテキストデータとして送信します。
  • [7][RUN][番号]で、メモリの内容をロードできます。0番~3番だとEEPROM内の各スロットから読み込み、4番以上だとシリアル通信でテキストデータとして受信します。各種シミュレータのデータ形式(.hex,.dmp,.fxp)にも対応しています。
  • [9][RUN]の電子オルガンでは、[0]と[F]でキーを半音ずつ変えられます。
  • [A][RUN]の自動演奏では、最大データサイズが255ニブルに増えています。また[F][番号]でキーを変更できるので半音も出せます。指定できる番号は1~Eで、1がデフォルトです。
  • [D][RUN]のテニスゲームでは、[F]を押すと7セグの小数点が点灯し、コンピュータと対戦できます。
  • [F][RUN]のモールス符号自動送信では、最大データサイズが256ニブルに増えています。

メモリ空間

8ビットで表すことのできるメモリ空間すべて(256ニブル)を利用できる。 ただし60-6Fの16ニブルはシステム領域として予約されているため、ユーザが利用できるのは最大で合計240ニブル。 データ領域は50-5Fだけでなく任意の位置に変更できる。 F0-FFは16ニブルのスタック領域として利用できる。

プログラム領域(00-5F,70-FF)

プログラムの実行はアドレス00から始まる。 60-6Fはプログラム領域として利用できないので、70以降をプログラム領域として使うには、JUMP命令でこの領域を飛び越える必要がある。これを行わずにプログラムカウンタが60に達した場合は、00に戻される。

データ領域(00-FF)

デフォルトでは50-5Fが割り当てられているが、EXT RAM命令でアドレスの上位4ビットを変更することにより、メモリ空間上の任意の位置にアクセスできる。 60-6Fの領域に割り当てることも可能だが、その領域への書き込みはできない。

スタック(F0-FF)

サブルーチン呼び出しなどで利用する。 任意のデータを入れることもできる。 サイズは16ニブルで、オーバーフロー/アンダーフローのチェックはなし。 初期状態では、スタックポインタはFFを指している。

システム領域(60-6F)

レジスタの実体がマップされている(という想定)。 プログラム開始時やRESETボタンを押したときにも内容は初期化されない。 プログラムから直接書き換えることはできないが、データ領域として読むことはできる。この領域の内容をモニタから書き変えることはできるが、プログラムを書き込んでも実行することはできない。

アドレス 内容
60 予約
61 予約
62 予約
63 Sレジスタ(スタックポインタの下位4ビット)
64 Mレジスタ(データメモリのアドレス上位4ビット)
65 Kレジスタ(音のキー)
66 Z’レジスタ
67 B’レジスタ
68 Y’レジスタ
69 A’レジスタ
6A 予約
6B 予約
6C Bレジスタ
6D Zレジスタ
6E Yレジスタ
6F Aレジスタ

拡張命令

システム領域(60-6F)へのジャンプは無意味なので、それに該当する命令コード(F60~F6F)は拡張命令に割り当てられている。 JUMP命令やCAL命令は実行フラグが1の場合のみ実行されるが、拡張命令が実行される条件は命令ごとに異なっていて、ジャンプ系の命令以外は実行フラグに関係なく実行される。

EXT INIT (F60)

次の動作を行う。

  • スタックポインタをリセットする
  • データ領域のアドレス上位4ビットを5にする
  • 音のキーをデフォルトに戻す 実行フラグが1になる。

EXT PUSH (F61)

Aレジスタの内容をスタックにpushする。 実行フラグが1になる。

EXT POP (F62)

スタックからpopした内容をAレジスタに入れる。 実行フラグが1になる。

EXT INPA (F63)

入力ポートの電圧をA/D変換したものをAレジスタに入れる。 実行フラグが1になる。

EXT NOT (F64)

実行フラグの状態を反転する。

EXT RAM (F65)

Aレジスタに入っている値を、データ領域のアドレス上位4ビットとして設定する。 実行フラグが1になる。

EXT LSFT (F66)

Aレジスタの内容を左に1ビットシフトする。 AレジスタのLSBには、実行フラグを反転したものが入る。 この命令を実行した後、実行フラグはシフト前のMSBを反転したものになる。

EXT CB (F67)

AレジスタとBレジスタの内容を交換する。(YとZは交換しない。) 実行フラグが1になる。

EXT AND (F68)

Aレジスタとデータメモリ[Y]をandしたものをAレジスタに入れる。 その結果が0なら実行フラグが0に、そうでなければ実行フラグが1になる。

EXT OR (F69)

Aレジスタとデータメモリ[Y]をorしたものをAレジスタに入れる。 その結果が0なら実行フラグが0に、そうでなければ実行フラグが1になる。

EXT XOR (F6A)

Aレジスタとデータメモリ[Y]をxorしたものをAレジスタに入れる。 その結果が0なら実行フラグが0に、そうでなければ実行フラグが1になる。

EXT XSND (F6B)

Aレジスタの値に対応する音階の音を、(Bレジスタの値+1)x60ミリ秒鳴らす。 ただしAレジスタの値がFの場合は、Bレジスタの値をキーとして設定する。 キーの値としては1~Eを指定できる。1がデフォルト。 実行フラグが1になる。

EXT TIMS (F6C)

(Aレジスタ+1)x10mSのスリープ。 実行フラグが1になる。 EXT DSP7 (F6D) データメモリ[E][F]の内容にしたがって、7セグLEDの各セグメントの状態を変更する。

FFFF EEEE  ←各レジスタの内容
-gfe dcba  ←7セグのセグメント

実行フラグが1になる。

EXT SR (F6E)

実行フラグが1の場合、この命令の直後から3ニブル先の位置のアドレスをスタックにpushする。 実行フラグが0の場合、なにもしない。 この命令を実行しても、実行フラグの値は変化しない。 通常は直後のJUMP命令と組み合わせてサブルーチン呼び出しとして使う。

(例) サブルーチンSUBを呼び出す

EXT  SR
JUMP SUB

また、実行フラグによる分岐条件はそのままサブルーチン呼び出しにも適用できる。

EXT RET (F6F)

実行フラグが1の場合、スタックからpopしたアドレスにジャンプする。 実行フラグが0の場合、なにもしない。 この命令を実行すると、実行フラグの値は1になる。 通常この命令はEXT SR命令を使って呼び出されたサブルーチンから戻るときに使う。

(例) サブルーチンの終了

EXT  RET