-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproblem2-memcpy.asm
176 lines (151 loc) · 2.35 KB
/
problem2-memcpy.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
.org $080D
.segment "STARTUP"
.segment "INIT"
.segment "ONCE"
.segment "CODE"
;; KERNAL
CHROUT = $FFD2
MEMORY_COPY = $FEE7
;; zero page "registers"
ZP_r0 = $02
ZP_r1 = $04
ZP_r2 = $06
;; PETSCII
NEWLINE = $0D
ZP_FA = $22
ZP_FB = $26
ZP_FS = $32
ZP_FC = $36
ZP_X = $3A
jmp start
start:
clc
;; FA = 1
stz ZP_FA
stz ZP_FA+1
stz ZP_FA+2
lda #1
sta ZP_FA+3
;; FB = 1
stz ZP_FB
stz ZP_FB+1
stz ZP_FB+2
lda #1
sta ZP_FB+3
;; FS = 0 - This stores the fibonacci sum, but only for even values
stz ZP_FS
stz ZP_FS+1
stz ZP_FS+2
stz ZP_FS+3
;; kernel registers - setting static values/zeroing high bytes
stz ZP_r0+1
stz ZP_r1+1
stz ZP_r2+1
lda #4
sta ZP_r2
while:
;; IF FB is even, we need to add to the fib sum
bbs0 ZP_FB+3, oddvalue
clc
lda ZP_FB+3
adc ZP_FS+3
sta ZP_FS+3
lda ZP_FB+2
adc ZP_FS+2
sta ZP_FS+2
lda ZP_FB+1
adc ZP_FS+1
sta ZP_FS+1
lda ZP_FB
adc ZP_FS
sta ZP_FS
oddvalue:
;; FB was odd
;; copy FB to FC, for temp storage. We'll use this later to copy back to FA (26 cycles+memcpy)
lda #ZP_FB
sta ZP_r0
lda #ZP_FC
sta ZP_r1
jsr MEMORY_COPY
;; Add FA to FB to get next fib number
clc
lda ZP_FB+3
adc ZP_FA+3
sta ZP_FB+3
lda ZP_FB+2
adc ZP_FA+2
sta ZP_FB+2
lda ZP_FB+1
adc ZP_FA+1
sta ZP_FB+1
lda ZP_FB
adc ZP_FA
sta ZP_FB
;; copy the last greatest fib number to FA (FC -> FA)
lda #ZP_FC
sta ZP_r0
lda #ZP_FA
sta ZP_r1
jsr MEMORY_COPY
;; print current fib number
lda ZP_FB
jsr print_hex
lda ZP_FB+1
jsr print_hex
lda ZP_FB+2
jsr print_hex
lda ZP_FB+3
jsr print_hex
lda #NEWLINE
jsr CHROUT
;; if FB < 4,000,000 then goto oddvalue
;; $3d0900 = 4000000
sec
lda #$00
sbc ZP_FB+3
sta ZP_X+3
lda #$09
sbc ZP_FB+2
sta ZP_X+2
lda #$3D
sbc ZP_FB+1
sta ZP_X+1
lda #0
sbc ZP_FB
sta ZP_X
bbr7 ZP_X, while
;; while end
;; print FS (fib sum)
lda ZP_FS
jsr print_hex
lda ZP_FS+1
jsr print_hex
lda ZP_FS+2
jsr print_hex
lda ZP_FS+3
jsr print_hex
lda #NEWLINE
jsr CHROUT
rts
print_hex:
pha ; push original A to stack
lsr
lsr
lsr
lsr ; A=A >> 4
jsr print_hex_digit
pla ; pull original A back from stack
and #$0F ; A=A & 0b00001111
jsr print_hex_digit
rts
print_hex_digit:
cmp #$A
bpl @letter
ora #$30 ; PETSCII numbers: 1=$31, 2=$32, 3=$33, etc
bra @print
@letter:
clc
adc #$37 ; PETSCII letters: A=$41, B=$42, etc
@print:
jsr CHROUT
rts