FX-マイコンR-165付属のプログラム集には、「No.82 モールス, エレキー」がある。
しかし、これはキー入力を用いているので、同時押しができない。
そこで、CAL INPT
命令を用いて左右同時押しにより短点と長点を交互に鳴らす操作に対応したキーヤーを作成することにした。
プログラム (失敗)
以下のプログラムは、MikeAssembler でアセンブルできる。
target gmc4
; K1 : 短点 (左)
; K2 : 長点 (右)
TIA 0
AO
main_loop:
DATAN 0xE, 0x3 ; CAL INPT
AIA 0xE
JUMP sound_long
; K2が非導通だった
AIA 1
JUMP sound_short
JUMP main_loop
sound_long:
CAL LONS
; K1が導通なら、K2の状態にかかわらず短点を鳴らす (短点 or 同時押し)
DATAN 0xE, 0x3 ; CAL INPT
CAL SIFT
JUMP sound_long_after
sound_short:
CAL SHTS
; K2が導通なら、K1の状態にかかわらず長点を鳴らす (長点 or 同時押し)
DATAN 0xE, 0x3 ; CAL INPT
AIA 0xE
JUMP sound_long
; K2が非導通、K1が導通なら、短点を鳴らす
AIA 1
JUMP sound_short
; K1もK2も非導通なので、待機
JUMP main_loop
sound_long_after:
; K1が非導通、K2が導通なら、長点を鳴らす
AIA 0xF
JUMP sound_long
; K1もK2も非導通なので、待機
JUMP main_loop
以下は、このプログラムの機械語表現である。
| 0 1 2 3 4 5 6 7 8 9 A B C D E F
--+-----------------------------------
0 | 8 0 1 E 3 9 E F 1 2 9 1 F 1 B F
1 | 0 3 E A E 3 E 6 F 2 C E 9 E 3 9
2 | E F 1 2 9 1 F 1 B F 0 3 9 F F 1
3 | 2 F 0 3
実行結果 (失敗)
3.5mmステレオジャックのGNDにK1・K2に入力する信号、LにK1、RにK2を接続し、これを介して CW-ONE を接続して実行した。
結果、パドルを押しっぱなしにするとなぜか音が鳴りっぱなしになってしまった。
何がいけなかったのか
調査の結果、CAL SHTS
や CAL LONS
命令は、7セグメントLEDが点灯した状態で CAL INPT
命令でAレジスタのビットを1にするような入力をすると、なぜか実行が停止することがわかった。
以下のプログラムは、2進LEDを点灯させて短い音を鳴らし、2進LEDを消灯させて0.5秒待つ、を繰り返すプログラムである。
このプログラムを実行し、パドルを操作すると、タイミングによって音が鳴りっぱなしになったり、止まりっぱなしになったりした。
しかし、2進LEDが消えたタイミングでパドルを操作しても、必ず2進LEDが点いてから実行が停止した。
すなわち、CAL TIMR
命令はK1やK2の影響を受けないようである。
機械語 アセンブリ言語
---------------------
A 0 TIY 0
1 AO
loop:
E 1 CAL SETR
E 9 CAL SHTS
8 4 TIA 4
E 2 CAL RSTR
E C CAL TIMR
F 0 3 JUMP loop
プログラム (罠回避)
残念ながら CAL INPT
命令用の入力と CAL SHTS
や CAL LONS
命令の併用は難しそうなので、かわりに2進LEDの最下位を用いてモールス信号を出力することにした。
この出力は、マイコンユニット右側の下から2番目の端子にも出ているため、外部に取り出し、連動して音を鳴らすなどの応用も可能だろう。
ただし、この端子は8V付近の電圧が出ることがあるので、接続する部品の最大入力電圧には注意したい。
(以前の記事を参照)
target gmc4
; K1 : 短点 (左)
; K2 : 長点 (右)
TIA 0
TIY 0
AO
main_loop:
DATAN 0xE, 0x3 ; CAL INPT
AIA 0xE
JUMP sound_long
; K2が非導通だった
AIA 1
JUMP sound_short
JUMP main_loop
sound_long:
CAL SETR
TIA 2
CAL TIMR
CAL RSTR
TIA 0
CAL TIMR
; K1が導通なら、K2の状態にかかわらず短点を鳴らす (短点 or 同時押し)
DATAN 0xE, 0x3 ; CAL INPT
CAL SIFT
JUMP sound_long_after
sound_short:
CAL SETR
TIA 0
CAL TIMR
CAL RSTR
CAL TIMR
; K2が導通なら、K1の状態にかかわらず長点を鳴らす (長点 or 同時押し)
DATAN 0xE, 0x3 ; CAL INPT
AIA 0xE
JUMP sound_long
; K2が非導通、K1が導通なら、短点を鳴らす
AIA 1
JUMP sound_short
; K1もK2も非導通なので、待機
JUMP main_loop
sound_long_after:
; K1が非導通、K2が導通なら、長点を鳴らす
AIA 0xF
JUMP sound_long
; K1もK2も非導通なので、待機
JUMP main_loop
以下は、このプログラムの機械語表現である。
| 0 1 2 3 4 5 6 7 8 9 A B C D E F
--+-----------------------------------
0 | 8 0 A 0 1 E 3 9 E F 1 4 9 1 F 2
1 | 7 F 0 5 E 1 8 2 E C E 2 8 0 E C
2 | E 3 E 6 F 4 0 E 1 8 0 E C E 2 E
3 | C E 3 9 E F 1 4 9 1 F 2 7 F 0 5
4 | 9 F F 1 4 F 0 5
実行結果 (罠回避)
パドルの操作によってモールス信号を出力できている。