「Rubyで8ビットCPUを作る」のアプリケーション

※ 前に掲載していたものはバグバグでした。試されて悩んじゃった人は済みません。今回のもバグがあるかもです。

ha-tanさんの「8ビットCPUを作る」(http://d.hatena.ne.jp/ha-tan/20080108/1199725414#seemore)を読んで、何かプログラムが書きたくなったので、書いてみました。とりあえずお約束のFIBです。プログラムの最後にパラメータを入れて、HALT時のr0が答えです。

	mov	[PARA], r0	; 1 * 8 + 5, PARA(41)	; 13, 41
	mov	r0, r1		; 1 * 8 + 3, 0x01       ; 11, 1
	movi	255, r5		; 4 * 8 + 5, 0xff       ; 37, 255
	call    FIB		; 18 * 8 + 0, FIB(9)    ; 144, 9
	hlt			; 31 * 8                ; 248
FIB:				; ADR 9               
	subi	1, r1		; 6 * 8 + 1, 1          ; 49, 1
	jnz	L1		; 14 * 8 + 0, L1(16)    ; 112, 16
	movi	1, r0		; 4 * 8 + 0, 1          ; 32, 1
	ret			; 19 * 8 + 0            ; 152
L1:				; ADR 16 
	push	r1		; 16 * 8 + 1            ; 129
	subi	1, r1		; 6 * 8 + 1, 1          ; 49, 1
	jnz	L2		; 14 * 8 + 0, L2(25)    ; 112, 25
	pop	r1		; 17 * 8 + 1            ; 137
	movi	1, r0		; 4 * 8 + 0, 1          ; 32, 1
	ret			; 19 * 8 + 0            ; 152
L2:				; ADR 25            
	call	FIB		; 18 * 8 + 0, FIB(9)    ; 144, 9
	pop	r1		; 17 * 8 + 1            ; 137
	mov	r0, r2		; 1 * 8 + 3, 0x02       ; 11, 2
	push	r2		; 16 * 8 + 2            ; 130
	call	FIB		; 18 * 8 + 0, FIB(9)    ; 144, 9
	pop	r1		; 17 * 8 + 1            ; 137
	mov	r0, [$+3]	; 1 * 8 + 4, 37         ; 12, 37
	addi	0, r1		; 5 * 8 + 1, 0          ; 41, 0
	mov	r1, r0		; 1 * 8 + 3, 0x10       ; 11, 16
	ret			; 19 * 8 + 0            ; 152

PARA:	dc	n		; ADR(41)

アセンブラが書きたくなりますが、ハンドアセンブルの方が趣がありそうです。

FIB(1)

d:\work\ruby>ruby octopus3.rb 13 41 11 1 37 255 144 9 248 49 1 112 16 32 1 152 129 49 1 112 25 137 32 1 152 144 9 137 11 2 130 144 9 137 12 37 41 0 11 16 152 1
ruby octopus3.rb 13 41 11 1 37 255 144 9 248 49 1 112 16 32 1 152 129 49 1 112 25 137 32 1 152 144 9 137 11 2 130 144 9 137 12 37 41 0 11 16 152 1
  Memory = 0d 29 0b 01 25 ff 90 09 f8 31 01 70 10 20 01 98 
         = 81 31 01 70 19 89 20 01 98 90 09 89 0b 02 82 90 
----------------------------------------------------------
00: mov [ 0x29 ], r0
02: mov r0, r1
04: movi 0xff, r5
06: call 0x09
09: subi 0x01, r1
0b: jnz 0x10
0d: movi 0x01, r0
0f: ret 
08: hlt 
### System is halted.
----------------------------------------------------------
            0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  Memory = 0d 29 0b 01 25 ff 90 09 f8 31 01 70 10 20 01 98 
         = 81 31 01 70 19 89 20 01 98 90 09 89 0b 02 82 90 
    Port = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
         = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
Register = 01 00 00 00 00 ff 00 09 00 00 00 00 00 00 00 00 
    Flag = NZ
   Steps = 8

FIB(2)

d:\work\ruby>ruby octopus3.rb 13 41 11 1 37 255 144 9 248 49 1 112 16 32 1 152 129 49 1 112 25 137 32 1 152 144 9 137 11 2 130 144 9 137 12 37 41 0 11 16 152 2
ruby octopus3.rb 13 41 11 1 37 255 144 9 248 49 1 112 16 32 1 152 129 49 1 112 25 137 32 1 152 144 9 137 11 2 130 144 9 137 12 37 41 0 11 16 152 2
  Memory = 0d 29 0b 01 25 ff 90 09 f8 31 01 70 10 20 01 98 
         = 81 31 01 70 19 89 20 01 98 90 09 89 0b 02 82 90 
----------------------------------------------------------
00: mov [ 0x29 ], r0
02: mov r0, r1
04: movi 0xff, r5
06: call 0x09
09: subi 0x01, r1
0b: jnz 0x10
10: push r1
11: subi 0x01, r1
13: jnz 0x19
15: pop r1
16: movi 0x01, r0
18: ret 
08: hlt 
### System is halted.
----------------------------------------------------------
            0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  Memory = 0d 29 0b 01 25 ff 90 09 f8 31 01 70 10 20 01 98 
         = 81 31 01 70 19 89 20 01 98 90 09 89 0b 02 82 90 
    Port = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
         = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
Register = 01 01 00 00 00 ff 00 09 00 00 00 00 00 00 00 00 
    Flag = NZ
   Steps = 12

FIB(5)

d:\work\ruby>ruby octopus3.rb 13 41 11 1 37 255 144 9 248 49 1 112 16 32 1 152 129 49 1 112 25 137 32 1 152 144 9 137 11 2 130 144 9 137 12 37 41 0 11 16 152 5
ruby octopus3.rb 13 41 11 1 37 255 144 9 248 49 1 112 16 32 1 152 129 49 1 112 25 137 32 1 152 144 9 137 11 2 130 144 9 137 12 37 41 0 11 16 152 5
  Memory = 0d 29 0b 01 25 ff 90 09 f8 31 01 70 10 20 01 98 
         = 81 31 01 70 19 89 20 01 98 90 09 89 0b 02 82 90 
----------------------------------------------------------
00: mov [ 0x29 ], r0
02: mov r0, r1
04: movi 0xff, r5
06: call 0x09
09: subi 0x01, r1
0b: jnz 0x10
10: push r1
11: subi 0x01, r1
13: jnz 0x19

〜 略 〜

28: ret 
08: hlt 
### System is halted.
----------------------------------------------------------
            0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  Memory = 0d 29 0b 01 25 ff 90 09 f8 31 01 70 10 20 01 98 
         = 81 31 01 70 19 89 20 01 98 90 09 89 0b 02 82 90 
    Port = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
         = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
Register = 05 05 01 00 00 ff 00 09 00 00 00 00 00 00 00 00 
    Flag = NZ
   Steps = 96

ha-tanさん、パッチを取り込んでくれてありがとうございます。混乱を防ぐためにパッチは削除します。