学研の4ビットマイコン GMC-4 でフィボナッチ数列を計算してみた。
フィボナッチ数列
最初の2項は 0, 1
であり、3項目からは前の2項の和である数列。
0, 1, 1, 2, 3, 5, 8, 13, 21, …
今回の仕様
フィボナッチ数列の各項を16進数で表現し、下位4ビットを7セグメントLEDに、上位7ビットを2進LEDに表示する。
以下のC言語のプログラムにより、表示されるはずの値を求めることができる。
#include <stdio.h>
int main(void) {
int cur = 0, prev = 1, pprev;
int i, j;
for (i = 0; i < 100; i++) {
/* 値をコピーする */
pprev = prev;
prev = cur;
/* 現在の値を表示する */
for (j = 7; j >= 0; j--) {
putchar("o*"[(cur >> (j + 4)) & 1]);
}
printf(" %X\n", cur & 0xf);
/* 現在の値に前の値を足す */
cur = (prev + pprev) & 0xfff;
}
return 0;
}
実行結果のうちオーバーフローしない範囲は、以下のようになった。
(GMC-4 の2進LEDは7桁であるが、ORANGE-4 にも対応できるように8桁で出力している)
oooooooo 0
oooooooo 1
oooooooo 1
oooooooo 2
oooooooo 3
oooooooo 5
oooooooo 8
oooooooo D
ooooooo* 5
oooooo*o 2
oooooo** 7
ooooo*o* 9
oooo*oo* 0
oooo***o 9
ooo*o*** 9
oo*oo**o 2
oo****o* B
o**ooo** D
*o*oooo* 8
プログラム
以下のプログラムは、MikeAssembler でアセンブルできる。
target gmc4
; [0xF]:[0xE]:[0xD] : 現在の値
; [0xC]:[0xB]:[0xA] : 前の値
; [0x9]:[0x8]:[0x7] : 前の前の値
main_loop:
; 値をコピーする (前の前の値←前の値、前の値←現在の値)
TIY 0xC
copy_loop:
MA
AIY -3
AM
AIY 6
MA
AIY -3
AM
AIY -1
CIY 0x9
JUMP copy_loop
; 現在の値を表示する (最後にコピーするのが現在の値の1の位であることを利用する)
AO
CAL DSPR
TIA 9
CAL TIMR
; 現在の値に前の値を足す
; 1の位を足す
TIY 0x7
MA
TIY 0xD
M+
JUMP carry0
AM
carry0_end:
; 0x10の位を足す
TIY 0x8
MA
TIY 0xE
M+
JUMP carry1
AM
carry1_end:
; 0x100の位を足す
TIY 0x9
MA
TIY 0xF
M+
AM
JUMP main_loop
; 足し算の処理の一部 (1の位→0x10の位への繰り上がり)
carry0:
AM
TIY 0xE
MA
; 足される数に1を足す
AIA 1
AM
; 足した結果が0なら、0x100の位へ繰り上がる (0x100の位からの繰り上がりは捨てる)
CIA 0
JUMP carry0_end
TIY 0xF
MA
AIA 1
AM
JUMP carry0_end
; 足し算の処理の一部 (0x10の位→0x100の位への繰り上がり)
carry1:
AM
TIY 0xF
MA
AIA 1
AM
JUMP carry1_end
org 0x5A
datan 1, 0, 0, 0, 0, 0
以下は、このプログラムの機械語表現である。
| 0 1 2 3 4 5 6 7 8 9 A B C D E F
--+-----------------------------------
0 | A C 5 B D 4 B 6 5 B D 4 B F D 9
1 | F 0 2 1 E D 8 9 E C A 7 5 A D 6
2 | F 3 8 4 A 8 5 A E 6 F 4 D 4 A 9
3 | 5 A F 6 4 F 0 0 4 A E 5 9 1 4 C
4 | 0 F 2 4 A F 5 9 1 4 F 2 4 4 A F
5 | 5 9 1 4 F 2 E
さらに、以下のように手動でデータメモリを初期化してから実行する。
(数列の初期値を設定する)
| 0 1 2 3 4 5 6 7 8 9 A B C D E F
--+-----------------------------------
5 | 1 0 0 0 0 0
実行結果
フィボナッチ数列の各項が求まっている。