Chromatix wrote:
Okay, for an NMOS version we need to substitute the STZ and DEC A instructions. STZ is easily done by LDA #0 : STA, assuming A can be clobbered. To permit that and also to work around DEC A efficiently, we pass the argument in the Y register and use A only for arithmetic.
Code:
fib: ; Enter with argument in Y, X pointing to the beginning of a clear area in ZP. Returns with Y,X preserved, X pointing to result in ZP, A clobbered.
Very nicely done!
Code:
0200 00023 org $200
00024
0200 00025 fib:
0200 C0 02 [2] 00026 cpy #2
0202 10 07 (020B) [2/3] 00027 bpl 2f
00028
0204 94 00 [4] 00029 sty 0,X
0206 A9 00 [2] 00030 lda #0
0208 95 01 [4] 00031 sta 1,X
020A 60 [6] 00032 rts
00033
020B 00034 2:
020B 88 [2] 00035 dey
020C 20 0200 [6] 00036 jsr fib
020F E8 [2] 00037 inx
0210 E8 [2] 00038 inx
0211 88 [2] 00039 dey
0212 20 0200 [6] 00040 jsr fib
0215 CA [2] 00041 dex
0216 CA [2] 00042 dex
0217 18 [2] 00043 clc
0218 B5 02 [4] 00044 lda 2,X
021A 75 00 [4] 00045 adc 0,X
021C 95 00 [4] 00046 sta 0,X
021E B5 03 [4] 00047 lda 3,X
0220 75 01 [4] 00048 adc 1,X
0222 95 01 [4] 00049 sta 1,X
0224 C8 [2] 00050 iny
0225 C8 [2] 00051 iny
0226 60 [6] 00052 rts
00053
0227 00054 Test:
0227 A0 17 [2] 00055 ldy #23
0229 A2 00 [2] 00056 ldx #0
022B 20 0200 [6] 00057 jsr fib
00058
0227 00059 end Test
3,941,225 cycles
With the adoption of a couple of your techniques, n is always less than 256 and keeping n in a register along with extensive use of the depessimizer between the ears, the code for the other processors got better.
The 6809 saw some improvement, but it is clearly in diminishing returns territory:
Code:
0100 00023 org $100
00024
0100 00025 fib
0100 8C 0002 [4] 00026 cmpx #2 ; Is n < 2?
0103 24 03 (0108) [3] 00027 bhs 2f ; No
00028
0105 1F 10 [6] 00029 tfr X,D ; Return n
00030
0107 39 [5] 00031 rts
00032
0108 00033 2
0108 30 1F [5] 00034 dex ; Do fib(n - 1)
010A 8D F4 (0100) [7] 00035 bsr fib
00036
010C 34 06 [7] 00037 pshs D ; Save fib(n - 1)
00038
010E 30 1F [5] 00039 dex ; Do fib(n - 2)
0110 8D EE (0100) [7] 00040 bsr fib
00041
0112 E3 E1 [9] 00042 addd ,S++ ; Add them together
00043
0114 30 02 [5] 00044 leax 2,X ; Restore original n
00045
0116 39 [5] 00046 rts
00047
0117 00048 Test
0117 8E 0017 [3] 00049 ldx #23
011A 8D E4 (0100) [7] 00050 bsr fib
00051
0117 00052 end Test
3,523,921 cycles
The 8080 showed a substantial gain:
Code:
0100 00023 org 100h
00024
0100 00025 fib:
0100 FE 02 [7] 00026 cpi 2 ; n < 2?
0102 D2 0108 [10] 00027 jnc 2f ; No
00028
0105 6F [5] 00029 mov L,A ; Return n
0106 60 [5] 00030 mov H,B
00031
0107 C9 [10] 00032 ret
00033
0108 00034 2:
0108 3D [5] 00035 dcr A ; Do fib(n - 1)
0109 CD 0100 [17] 00036 call fib
00037
010C E5 [11] 00038 push H ; Save fib(n - 1)
00039
010D 3D [5] 00040 dcr A ; Do fib(n - 2)
010E CD 0100 [17] 00041 call fib
00042
0111 D1 [10] 00043 pop D ; Add them together
0112 19 [10] 00044 dad D
00045
0113 81 [4] 00046 add C ; Restore original n
00047
0114 C9 [10] 00048 ret
00049
0115 00050 Test:
0115 3E 17 [7] 00051 mvi A,23
0117 01 0002 [10] 00052 lxi B,2 ; Keep 0 and 2 handy in spare registers
011A CD 0100 [17] 00053 call fib
00054
0115 00055 end Test
6,630,552 cycles
The lowly 6800 also saw major improvement, almost catching up to the 6502:
Code:
0000 00023 Tmp rmb 1
00024
0100 00025 org $100
00026
0100 00027 fib
0100 C1 02 [2] 00028 cmpb #2 ; Is n < 2
0102 24 02 (0106) [4] 00029 bhs 2f ; No
00030
0104 4F [2] 00031 clra ; Return n
00032
0105 39 [5] 00033 rts
00034
0106 00035 2
0106 37 [4] 00036 pshb ; Save original n
00037
0107 5A [2] 00038 decb ; Do fib(n - 1)
0108 8D F6 (0100) [8] 00039 bsr fib
00040
010A D7 00 [4] 00041 stab Tmp ; Stash low byte of result
00042
010C 33 [4] 00043 pulb ; Retrieve original n
00044
010D 36 [4] 00045 psha ; Save fib(n - 1)
010E 96 00 [3] 00046 ldaa Tmp
0110 36 [4] 00047 psha
00048
0111 C0 02 [2] 00049 subb #2 ; Do fib(n - 2)
0113 8D EB (0100) [8] 00050 bsr fib
00051
0115 30 [4] 00052 tsx ; Address the stack
00053
0116 EB 00 [5] 00054 addb ,X ; Add them together
0118 A9 01 [5] 00055 adca 1,X
00056
011A 31 [4] 00057 ins ; Clean the stack
011B 31 [4] 00058 ins
00059
011C 39 [5] 00060 rts
00061
011D 00062 Test
011D C6 17 [2] 00063 ldab #23
011F 8D DF (0100) [8] 00064 bsr fib
00065
011D 00066 end Test
4,126,686 cycles