学研の4ビットマイコン GMC-4 で砂時計的な何かを作ってみた。
仕様
プログラムを実行すると、2進LEDの上位3個が点灯する。
時間が経過すると、点灯する位置が下位に「落ちて」いく。
2進LEDの真ん中を中心とした砂時計で、光っているLEDが砂のイメージ。
点灯する位置が落ちきったら終了。砂時計なので終了時も特に電子音などは鳴らさない。
プログラム
以下のプログラムは、MikeAssembler でアセンブルできる。
target gmc4
; [0] : 点灯させに行くときに足す数
; [1] : 消灯させに行くときに足す数
TIY 4
CAL SETR
TIY 5
CAL SETR
TIY 6
CAL SETR
TIY 0
TIA -8
AM
TIY 1
TIA 7
AM
TIY 6
drop_loop:
CH
; LEDの状態を更新する位置を更新する
TIY 0
MA
AIA 2
AM
TIY 1
MA
AIA -2
AM
; 計時用に待ちを入れる
;TIA 14 ; 3分計
TIA 4 ; 1分計
TIY 9
wait_loop:
CAL TIMR
CAL TIMR
CAL TIMR
CAL TIMR
AIY -1
JUMP wait_loop
CH
CAL RSTR
CY
TIY 0
M+
CY
CAL SETR
CY
TIY 1
M+
CY
CIY 3
JUMP drop_loop
finished:
JUMP finished
以下は、このプログラムの機械語表現である。
| 0 1 2 3 4 5 6 7 8 9 A B C D E F
--+-----------------------------------
0 | A 4 E 1 A 5 E 1 A 6 E 1 A 0 8 8
1 | 4 A 1 8 7 4 A 6 2 A 0 5 9 2 4 A
2 | 1 5 9 E 4 8 4 A 9 E C E C E C E
3 | C B F F 2 9 2 E 2 3 A 0 6 3 E 1
4 | 3 A 1 6 3 D 3 F 1 8 F 4 A
これは1分計のプログラムである。
0x26番地の 4
を E
に変えると3分計になる。
解説
時間経過によるLEDの操作は、
- 6を消灯 → 0を点灯
- 5を消灯 → 1を点灯
- 4を消灯 → 2を点灯
となる。操作を行う順番に位置を並べると、6 0 5 1 4 2
であり、その差は -6 5 -4 3 -2
である。
そこで、マイナスの差とプラスの差にわけ、それぞれの差 (移動幅) をデータメモリに格納することにした。
待つ際にLEDの操作位置を格納したレジスタを退避するので、そのついでに移動幅の更新を行う。