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