Speeding up the 8080 version:
The code for the 8080 did not have any easy improvements like the 6800.
So here are the structural changes:
Code:
00024 ; 67,519,041 cycles checking x <= y before calling tarai
00025 ; 135,778,117 cycles originally
00026 ;
00027
0100 00028 org 100h
00029
0003 00030 X_Offset equ 3
0002 00031 Y_Offset equ 2
0001 00032 Z_Offset equ 1
00033
0100 00034 tarai:
00035
0002 00036 Frame set 2 ; After return address
00037
0100 21 0005 [10] 00038 lxi H,Frame+X_Offset ; Address the stack
0103 39 [10] 00039 dad SP
00040
0104 46 [7] 00041 mov B,M ; Get x - 1
0105 05 [5] 00042 dcr B
0106 2B [5] 00043 dcx H ; Get y
0107 7E [7] 00044 mov A,M
0108 B8 [4] 00045 cmp B ; Is x - 1 <= y?
0109 F2 0114 [10] 00046 jp 2f ; Yes, "return value" is y
00047
010C 4F [5] 00048 mov C,A ; Get y in position
010D C5 [11] 00049 push B ; Push them
010E 2B [5] 00050 dcx H ; Push z
010F 7E [7] 00051 mov A,M
0110 F5 [11] 00052 push PSW
0111 CD 0100 [17] 00053 call tarai ; tarai(x - 1, y, z)
00054
0114 00055 2:
0114 F5 [11] 00056 push PSW ; Push its value
00057
0004 00058 Frame set 4 ; After return address and 2 bytes pushed
00059
0115 21 0006 [10] 00060 lxi H,Frame+Y_Offset ; Address the stack
0118 39 [10] 00061 dad SP
00062
0119 46 [7] 00063 mov B,M ; Get y - 1
011A 05 [5] 00064 dcr B
011B 2B [5] 00065 dcx H ; Get z
011C 7E [7] 00066 mov A,M
011D B8 [4] 00067 cmp B ; Is y - 1 <= z?
011E F2 012A [10] 00068 jp 2f ; Yes, "return value" is y
00069
0121 4F [5] 00070 mov C,A ; Get z in position
0122 C5 [11] 00071 push B ; Push them
0123 23 [5] 00072 inx H ; Push x
0124 23 [5] 00073 inx H
0125 7E [7] 00074 mov A,M
0126 F5 [11] 00075 push PSW
00076
0127 CD 0100 [17] 00077 call tarai ; tarai(y - 1, z, x),
00078
012A 00079 2:
012A C1 [10] 00080 pop B ; Combine last two values
012B 4F [5] 00081 mov C,A
012C C5 [11] 00082 push B ; Push them
00083
012D 21 0005 [10] 00084 lxi H,Frame+Z_Offset ; Address the stack
0130 39 [10] 00085 dad SP
00086
0131 46 [7] 00087 mov B,M ; Get z - 1
0132 05 [5] 00088 dcr B
0133 23 [5] 00089 inx H ; Get x
0134 23 [5] 00090 inx H
0135 7E [7] 00091 mov A,M
0136 B8 [4] 00092 cmp B ; Is y - 1 <= z?
0137 F2 0142 [10] 00093 jp 2f ; Yes, "return value" is y
00094
013A 4F [5] 00095 mov C,A ; Get x in position
013B C5 [11] 00096 push B ; Push them
013C 2B [5] 00097 dcx H ; Push y
013D 7E [7] 00098 mov A,M
013E F5 [11] 00099 push PSW
00100
013F CD 0100 [17] 00101 call tarai ; tarai(z - 1, x, y)
00102
0142 00103 2:
0142 57 [5] 00104 mov D,A ; Stash its value
00105
0143 C1 [10] 00106 pop B ; Get first and second value
0144 79 [5] 00107 mov A,C ; The second value
0145 B8 [4] 00108 cmp B ; Is second value <= first value?
0146 F2 014E [10] 00109 jp Return ; Yes, "return value" is second value
00110
0149 C5 [11] 00111 push B ; Push first and second values
014A D5 [11] 00112 push D ; Push third value
00113
014B CD 0100 [17] 00114 call tarai ; The final call
00115
014E 00116 Return:
014E E1 [10] 00117 pop H ; Get return address
00118
014F C1 [10] 00119 pop B ; Clean the stack
0150 C1 [10] 00120 pop B
00121
0151 E9 [5] 00122 pchl ; Return
00123
0152 00124 Test
0152 01 0A01 [10] 00125 lxi B,10*256+1h
0155 C5 [11] 00126 push B
0156 AF [4] 00127 xra A
0157 F5 [11] 00128 push PSW
0158 CD 0100 [17] 00129 call tarai
00130
0152 00131 end Test
Finally, the big one:
Code:
00024 ; 13,524 cycles checking x <= y after tarai(x - 1, ...) and (y - 1, ...)
00025 ; 67,519,041 cycles checking x <= y before calling tarai
00026 ; 135,778,117 cycles originally
00027 ;
00028
0100 00029 org 100h
00030
0003 00031 X_Offset equ 3
0002 00032 Y_Offset equ 2
0001 00033 Z_Offset equ 1
00034
0100 00035 tarai:
00036
0002 00037 Frame set 2 ; After return address
00038
0100 21 0005 [10] 00039 lxi H,Frame+X_Offset ; Address the stack
0103 39 [10] 00040 dad SP
00041
0104 46 [7] 00042 mov B,M ; Get x - 1
0105 05 [5] 00043 dcr B
0106 2B [5] 00044 dcx H ; Get y
0107 7E [7] 00045 mov A,M
0108 B8 [4] 00046 cmp B ; Is x - 1 <= y?
0109 F2 0114 [10] 00047 jp 2f ; Yes, "return value" is y
00048
010C 4F [5] 00049 mov C,A ; Get y in position
010D C5 [11] 00050 push B ; Push them
010E 2B [5] 00051 dcx H ; Push z
010F 7E [7] 00052 mov A,M
0110 F5 [11] 00053 push PSW
0111 CD 0100 [17] 00054 call tarai ; tarai(x - 1, y, z)
00055
0114 00056 2:
0114 F5 [11] 00057 push PSW ; Push its value
00058
0004 00059 Frame set 4 ; After return address and 2 bytes pushed
00060
0115 21 0006 [10] 00061 lxi H,Frame+Y_Offset ; Address the stack
0118 39 [10] 00062 dad SP
00063
0119 46 [7] 00064 mov B,M ; Get y - 1
011A 05 [5] 00065 dcr B
011B 2B [5] 00066 dcx H ; Get z
011C 7E [7] 00067 mov A,M
011D B8 [4] 00068 cmp B ; Is y - 1 <= z?
011E F2 012A [10] 00069 jp 2f ; Yes, "return value" is y
00070
0121 4F [5] 00071 mov C,A ; Get z in position
0122 C5 [11] 00072 push B ; Push them
0123 23 [5] 00073 inx H ; Push x
0124 23 [5] 00074 inx H
0125 7E [7] 00075 mov A,M
0126 F5 [11] 00076 push PSW
00077
0127 CD 0100 [17] 00078 call tarai ; tarai(y - 1, z, x),
00079
012A 00080 2:
012A C1 [10] 00081 pop B ; Get new x
012B B8 [4] 00082 cmp B ; Is new y <= new x?
012C F2 014A [10] 00083 jp Return ; Yes, "return value" is new y
00084
012F 4F [5] 00085 mov C,A ; Combine last two values
0130 C5 [11] 00086 push B ; Push them
00087
0131 21 0005 [10] 00088 lxi H,Frame+Z_Offset ; Address the stack
0134 39 [10] 00089 dad SP
00090
0135 46 [7] 00091 mov B,M ; Get z - 1
0136 05 [5] 00092 dcr B
0137 23 [5] 00093 inx H ; Get x
0138 23 [5] 00094 inx H
0139 7E [7] 00095 mov A,M
013A B8 [4] 00096 cmp B ; Is y - 1 <= z?
013B F2 0146 [10] 00097 jp 2f ; Yes, "return value" is y
00098
013E 4F [5] 00099 mov C,A ; Get x in position
013F C5 [11] 00100 push B ; Push them
0140 2B [5] 00101 dcx H ; Push y
0141 7E [7] 00102 mov A,M
0142 F5 [11] 00103 push PSW
00104
0143 CD 0100 [17] 00105 call tarai ; tarai(z - 1, x, y)
00106
0146 00107 2:
0146 F5 [11] 00108 push PSW ; Push its value
00109
0147 CD 0100 [17] 00110 call tarai ; The final call
00111
014A 00112 Return:
014A E1 [10] 00113 pop H ; Get return address
00114
014B C1 [10] 00115 pop B ; Clean the stack
014C C1 [10] 00116 pop B
00117
014D E9 [5] 00118 pchl ; Return
00119
014E 00120 Test:
014E 01 0A01 [10] 00121 lxi B,10*256+1h
0151 C5 [11] 00122 push B
0152 AF [4] 00123 xra A
0153 F5 [11] 00124 push PSW
0154 CD 0100 [17] 00125 call tarai
00126
014E 00127 end Test
Speeding up the 6809 version:
Like the 6800, start with some easy changes, using bsr instead of jsr, moving data two bytes at a time when possible:
Code:
00024 * 49,209,528 cycles after replacing jsr with bsr
00025 * 53,628,345 cycles originally
00026 *
00027
0100 00028 org $100
00029
0002 00030 X_Offset equ 2
0001 00031 Y_Offset equ 1
0000 00032 Z_Offset equ 0
00033
0100 00034 tarai
00035
0002 00036 Frame set 2 ; After return address
00037
0100 A6 63 [5] 00038 lda Frame+Y_Offset,S ; Get y
0102 A1 64 [5] 00039 cmpa Frame+X_Offset,S ; Is it >= x?
0104 2C 2D (0133) [3] 00040 bge Return ; Yes, go return y
00041
0106 A6 64 [5] 00042 lda Frame+X_Offset,S ; Push x - 1
0108 4A [2] 00043 deca
0109 34 02 [6] 00044 pshs A
0003 00045 Frame set Frame+1
010B EC 63 [6] 00046 ldd Frame+Z_Offset,S ; Push y and z
010D 34 06 [7] 00047 pshs D
0005 00048 Frame set Frame+2
010F 8D EF (0100) [7] 00049 bsr tarai ; tarai(x - 1, y, z)
0002 00050 Frame set Frame-3
00051
0111 34 02 [6] 00052 pshs A ; Push its value
0003 00053 Frame set Frame+1
00054
0113 A6 64 [5] 00055 lda Frame+Y_Offset,S ; Push y - 1
0115 4A [2] 00056 deca
0116 34 02 [6] 00057 pshs A
0004 00058 Frame set Frame+1
0118 A6 64 [5] 00059 lda Frame+Z_Offset,S ; Push z
011A 34 02 [6] 00060 pshs A
0005 00061 Frame set Frame+1
011C A6 67 [5] 00062 lda Frame+X_Offset,S ; Push x
011E 34 02 [6] 00063 pshs A
0006 00064 Frame set Frame+1
00065
0120 8D DE (0100) [7] 00066 bsr tarai ; tarai(y - 1, z, x),
0003 00067 Frame set Frame-3
00068
0122 34 02 [6] 00069 pshs A ; Push its value
0004 00070 Frame set Frame+1
00071
0124 A6 64 [5] 00072 lda Frame+Z_Offset,S ; Push z - 1
0126 4A [2] 00073 deca
0127 34 02 [6] 00074 pshs A
0005 00075 Frame set Frame+1
0129 EC 66 [6] 00076 ldd Frame+Y_Offset,S ; Push x and y
012B 34 06 [7] 00077 pshs D
0007 00078 Frame set Frame+2
00079
012D 8D D1 (0100) [7] 00080 bsr tarai ; tarai(z - 1, x, y)
0004 00081 Frame set Frame-3
00082
012F 34 02 [6] 00083 pshs A ; Push its value
0005 00084 Frame set Frame+1
00085
0131 8D CD (0100) [7] 00086 bsr tarai ; The final call
0002 00087 Frame set Frame-3
00088
0133 00089 Return
0133 35 20 [7] 00090 puls Y ; Get return address
00091
0135 32 63 [5] 00092 leas 3,S ; Clean the stack
00093
0137 6E A4 [3] 00094 jmp ,Y ; Return
00095
0139 00096 Test
0139 CC 010A [3] 00097 ldd #10+1*256
013C 34 06 [7] 00098 pshs D
013E 4F [2] 00099 clra
013F 34 02 [6] 00100 pshs A
0141 8D BD (0100) [7] 00101 bsr tarai
00102
0139 00103 end Test
Stack unwinding had some room to improve, though not as much as on the 6800:
Code:
00024 * 47,803,543 cycles after tail recursion elimination
00025 * 49,209,528 cycles after replacing jsr with bsr
00026 * 53,628,345 cycles originally
00027 *
00028
0100 00029 org $100
00030
0002 00031 X_Offset equ 2
0001 00032 Y_Offset equ 1
0000 00033 Z_Offset equ 0
00034
0100 00035 tarai
00036
0002 00037 Frame set 2 ; After return address
00038
0100 A6 63 [5] 00039 lda Frame+Y_Offset,S ; Get y
0102 A1 64 [5] 00040 cmpa Frame+X_Offset,S ; Is it >= x?
0104 2C 31 (0137) [3] 00041 bge Return ; Yes, go return y
00042
0106 A6 64 [5] 00043 lda Frame+X_Offset,S ; Push x - 1
0108 4A [2] 00044 deca
0109 34 02 [6] 00045 pshs A
0003 00046 Frame set Frame+1
010B EC 63 [6] 00047 ldd Frame+Z_Offset,S ; Push y and z
010D 34 06 [7] 00048 pshs D
0005 00049 Frame set Frame+2
010F 8D EF (0100) [7] 00050 bsr tarai ; tarai(x - 1, y, z)
0002 00051 Frame set Frame-3
00052
0111 34 02 [6] 00053 pshs A ; Push its value
0003 00054 Frame set Frame+1
00055
0113 A6 64 [5] 00056 lda Frame+Y_Offset,S ; Push y - 1
0115 4A [2] 00057 deca
0116 34 02 [6] 00058 pshs A
0004 00059 Frame set Frame+1
0118 A6 64 [5] 00060 lda Frame+Z_Offset,S ; Push z
011A 34 02 [6] 00061 pshs A
0005 00062 Frame set Frame+1
011C A6 67 [5] 00063 lda Frame+X_Offset,S ; Push x
011E 34 02 [6] 00064 pshs A
0006 00065 Frame set Frame+1
00066
0120 8D DE (0100) [7] 00067 bsr tarai ; tarai(y - 1, z, x),
0003 00068 Frame set Frame-3
00069
0122 34 02 [6] 00070 pshs A ; Push its value
0004 00071 Frame set Frame+1
00072
0124 A6 64 [5] 00073 lda Frame+Z_Offset,S ; Push z - 1
0126 4A [2] 00074 deca
0127 34 02 [6] 00075 pshs A
0005 00076 Frame set Frame+1
0129 EC 66 [6] 00077 ldd Frame+Y_Offset,S ; Push x and y
012B 34 06 [7] 00078 pshs D
0007 00079 Frame set Frame+2
00080
012D 8D D1 (0100) [7] 00081 bsr tarai ; tarai(z - 1, x, y)
0004 00082 Frame set Frame-3
00083
012F A7 64 [5] 00084 sta Frame+Z_Offset,S ; Replace z value
00085
0131 35 06 [7] 00086 puls D ; Get first and second values
0002 00087 Frame set Frame-2
00088
0133 ED 63 [6] 00089 std Frame+Y_Offset,S ; Replace x and y values
00090
0135 20 C9 (0100) [3] 00091 bra tarai ; The final "call"
00092
0137 00093 Return
0137 35 20 [7] 00094 puls Y ; Get return address
00095
0139 32 63 [5] 00096 leas 3,S ; Clean the stack
00097
013B 6E A4 [3] 00098 jmp ,Y ; Return
00099
013D 00100 Test
013D CC 010A [3] 00101 ldd #10+1*256
0140 34 06 [7] 00102 pshs D
0142 4F [2] 00103 clra
0143 34 02 [6] 00104 pshs A
0145 8D B9 (0100) [7] 00105 bsr tarai
00106
013D 00107 end Test
Now we get serious...
This step revealed an area where Motorola took a huge step backward with the design of the 6809. The 6800 had some instructions for interacting between the two accumulators such as transfer, add, subtract, compare, etc.
These were removed. In its place was the TFR (transfer) instruction and suggestions to use the new addressing modes.
In this particular case, instead of the CBA (compare accumulators) instruction, Motorola suggested doing:
Code:
pshs B
cmpa ,S+
which is three bytes bigger and a whopping ten cycles slower. Using a temporary variable is a bit faster.
Code:
00024 * 27,860,317 cycles checking x <= y before calling tarai
00025 * 47,803,543 cycles after tail recursion elimination
00026 * 49,209,528 cycles after replacing jsr with bsr
00027 * 53,628,345 cycles originally
00028 *
00029
0000 00030 Tmp rmb 1
00031
0100 00032 org $100
00033
0002 00034 X_Offset equ 2
0001 00035 Y_Offset equ 1
0000 00036 Z_Offset equ 0
00037
0100 00038 tarai
00039
0002 00040 Frame set 2 ; After return address
00041
0100 A6 63 [5] 00042 lda Frame+Y_Offset,S ; Get y
0102 E6 64 [5] 00043 ldb Frame+X_Offset,S ; Get x - 1
0104 5A [2] 00044 decb
0105 D7 00 [4] 00045 stb Tmp
0107 91 00 [4] 00046 cmpa Tmp ; Is it >= x - 1?
0109 2C 0A (0115) [3] 00047 bge 2f ; Yes, "return value" is y
00048
010B 34 04 [6] 00049 pshs B ; Push x - 1
0003 00050 Frame set Frame+1
010D 34 02 [6] 00051 pshs A ; Push y
0004 00052 Frame set Frame+1
010F A6 64 [5] 00053 lda Frame+Z_Offset,S ; Push z
0111 34 02 [6] 00054 pshs A
0005 00055 Frame set Frame+1
0113 8D EB (0100) [7] 00056 bsr tarai ; tarai(x - 1, y, z)
0002 00057 Frame set Frame-3
00058
0115 00059 2
0115 34 02 [6] 00060 pshs A ; Push its value
0003 00061 Frame set Frame+1
00062
0117 A6 63 [5] 00063 lda Frame+Z_Offset,S ; Get z
0119 E6 64 [5] 00064 ldb Frame+Y_Offset,S ; Get y - 1
011B 5A [2] 00065 decb
011C D7 00 [4] 00066 stb Tmp
011E 91 00 [4] 00067 cmpa Tmp ; Is it >= y - 1?
0120 2C 0A (012C) [3] 00068 bge 2f ; Yes, "return value" is z
00069
0122 34 04 [6] 00070 pshs B ; Push y - 1
0004 00071 Frame set Frame+1
0124 34 02 [6] 00072 pshs A ; Push z
0005 00073 Frame set Frame+1
0126 A6 67 [5] 00074 lda Frame+X_Offset,S ; Push x
0128 34 02 [6] 00075 pshs A
0006 00076 Frame set Frame+1
00077
012A 8D D4 (0100) [7] 00078 bsr tarai ; tarai(y - 1, z, x),
0003 00079 Frame set Frame-3
00080
012C 00081 2
012C 34 02 [6] 00082 pshs A ; Push its value
0004 00083 Frame set Frame+1
00084
012E A6 66 [5] 00085 lda Frame+X_Offset,S ; Get x
0130 E6 64 [5] 00086 ldb Frame+Z_Offset,S ; Get z - 1
0132 5A [2] 00087 decb
0133 D7 00 [4] 00088 stb Tmp
0135 91 00 [4] 00089 cmpa Tmp ; Is it > z?
0137 2C 0A (0143) [3] 00090 bge 2f ; Yes, "return value" is x
00091
0139 34 04 [6] 00092 pshs B ; Push z - 1
0005 00093 Frame set Frame+1
013B 34 02 [6] 00094 pshs A ; Push x
0006 00095 Frame set Frame+1
013D A6 67 [5] 00096 lda Frame+Y_Offset,S ; Push y
013F 34 02 [6] 00097 pshs A
0007 00098 Frame set Frame+1
00099
0141 8D BD (0100) [7] 00100 bsr tarai ; tarai(z - 1, x, y)
0004 00101 Frame set Frame-3
00102
0143 00103 2
0143 A7 64 [5] 00104 sta Frame+Z_Offset,S ; Replace z value
00105
0145 35 02 [6] 00106 puls A ; Get second value
0003 00107 Frame set Frame-1
00108
0147 A1 E4 [4] 00109 cmpa ,S ; Is it >= first value?
0149 2C 06 (0151) [3] 00110 bge Return ; Yes, "return value" is the second value
00111
014B 35 04 [6] 00112 puls B ; Get first value
0002 00113 Frame set Frame-1
014D ED 63 [6] 00114 std Frame+Y_Offset,S ; Replace x and y values
00115
014F 20 AF (0100) [3] 00116 bra tarai ; The final "call"
00117
0151 00118 Return
0151 35 04 [6] 00119 puls B ; Get rid of first value
00120
0153 35 20 [7] 00121 puls Y ; Get return address
00122
0155 32 63 [5] 00123 leas 3,S ; Clean the stack
00124
0157 6E A4 [3] 00125 jmp ,Y ; Return
00126
0159 00127 Test
0159 CC 010A [3] 00128 ldd #10+1*256
015C 34 06 [7] 00129 pshs D
015E 4F [2] 00130 clra
015F 34 02 [6] 00131 pshs A
0161 8D 9D (0100) [7] 00132 bsr tarai
00133
0159 00134 end Test
And the nuclear option:
Code:
00024 * 5,926 cycles checking x <= y after tarai(x - 1, ...) and (y - 1, ...)
00025 * 27,860,317 cycles checking x <= y before calling tarai
00026 * 47,803,543 cycles after tail recursion elimination
00027 * 49,209,528 cycles after replacing jsr with bsr
00028 * 53,628,345 cycles originally
00029 *
00030
0000 00031 Tmp rmb 1
00032
0100 00033 org $100
00034
0002 00035 X_Offset equ 2
0001 00036 Y_Offset equ 1
0000 00037 Z_Offset equ 0
00038
0100 00039 tarai
00040
0002 00041 Frame set 2 ; After return address
00042
0100 A6 63 [5] 00043 lda Frame+Y_Offset,S ; Get y
0102 E6 64 [5] 00044 ldb Frame+X_Offset,S ; Get x - 1
0104 5A [2] 00045 decb
0105 D7 00 [4] 00046 stb Tmp
0107 91 00 [4] 00047 cmpa Tmp ; Is it >= x - 1?
0109 2C 0A (0115) [3] 00048 bge 2f ; Yes, "return value" is y
00049
010B 34 04 [6] 00050 pshs B ; Push x - 1
0003 00051 Frame set Frame+1
010D 34 02 [6] 00052 pshs A ; Push y
0004 00053 Frame set Frame+1
010F A6 64 [5] 00054 lda Frame+Z_Offset,S ; Push z
0111 34 02 [6] 00055 pshs A
0005 00056 Frame set Frame+1
0113 8D EB (0100) [7] 00057 bsr tarai ; tarai(x - 1, y, z)
0002 00058 Frame set Frame-3
00059
0115 00060 2
0115 34 02 [6] 00061 pshs A ; Push its value
0003 00062 Frame set Frame+1
00063
0117 A6 63 [5] 00064 lda Frame+Z_Offset,S ; Get z
0119 E6 64 [5] 00065 ldb Frame+Y_Offset,S ; Get y - 1
011B 5A [2] 00066 decb
011C D7 00 [4] 00067 stb Tmp
011E 91 00 [4] 00068 cmpa Tmp ; Is it >= y - 1?
0120 2C 0A (012C) [3] 00069 bge 2f ; Yes, "return value" is z
00070
0122 34 04 [6] 00071 pshs B ; Push y - 1
0004 00072 Frame set Frame+1
0124 34 02 [6] 00073 pshs A ; Push z
0005 00074 Frame set Frame+1
0126 A6 67 [5] 00075 lda Frame+X_Offset,S ; Push x
0128 34 02 [6] 00076 pshs A
0006 00077 Frame set Frame+1
00078
012A 8D D4 (0100) [7] 00079 bsr tarai ; tarai(y - 1, z, x),
0003 00080 Frame set Frame-3
00081
012C 00082 2
012C A1 E4 [4] 00083 cmpa ,S ; Is it >= first value?
012E 2C 1F (014F) [3] 00084 bge Return ; Yes, "return value" is the second value
00085
0130 34 02 [6] 00086 pshs A ; Push its value
0004 00087 Frame set Frame+1
00088
0132 A6 66 [5] 00089 lda Frame+X_Offset,S ; Get x
0134 E6 64 [5] 00090 ldb Frame+Z_Offset,S ; Get z - 1
0136 5A [2] 00091 decb
0137 D7 00 [4] 00092 stb Tmp
0139 91 00 [4] 00093 cmpa Tmp ; Is it > z?
013B 2C 0A (0147) [3] 00094 bge 2f ; Yes, "return value" is x
00095
013D 34 04 [6] 00096 pshs B ; Push z - 1
0005 00097 Frame set Frame+1
013F 34 02 [6] 00098 pshs A ; Push x
0006 00099 Frame set Frame+1
0141 A6 67 [5] 00100 lda Frame+Y_Offset,S ; Push y
0143 34 02 [6] 00101 pshs A
0007 00102 Frame set Frame+1
00103
0145 8D B9 (0100) [7] 00104 bsr tarai ; tarai(z - 1, x, y)
0004 00105 Frame set Frame-3
00106
0147 00107 2
0147 A7 64 [5] 00108 sta Frame+Z_Offset,S ; Replace z value
00109
0149 35 06 [7] 00110 puls D ; Get first and second values
0002 00111 Frame set Frame-2
00112
014B ED 63 [6] 00113 std Frame+Y_Offset,S ; Replace x and y values
00114
014D 20 B1 (0100) [3] 00115 bra tarai ; The final "call"
00116
014F 00117 Return
014F 35 04 [6] 00118 puls B ; Get rid of first value
00119
0151 35 20 [7] 00120 puls Y ; Get return address
00121
0153 32 63 [5] 00122 leas 3,S ; Clean the stack
00123
0155 6E A4 [3] 00124 jmp ,Y ; Return
00125
0157 00126 Test
0157 CC 010A [3] 00127 ldd #10+1*256
015A 34 06 [7] 00128 pshs D
015C 4F [2] 00129 clra
015D 34 02 [6] 00130 pshs A
015F 8D 9F (0100) [7] 00131 bsr tarai
00132
0157 00133 end Test