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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
; Brick Out by Blake Ramsdell <blaker@gmail.com> http://www.blakeramsdell.com
; A poor attempt at brick out with no player involved. Maybe someday I'll
; let you play it, or you can view this as an exercise for the reader to put
; in a paddle that is user-controlled.
; I guess this is Copyright (C) 2007 Blake Ramsdell, and you have a license to
; do whatever you want with it, just tell me what you did and give me a
; mention. If you want to sell it, and you make a billion dollars, then good
; for you. You might at least throw a party and invite me.
; The gist of it is pretty simple -- you have a ball, and the ball has an X
; and a Y velocity. When it hits something, it bounces off of it. If the thing
; that it hits is not a wall, then it erases it. Pretty dead-simple behavior.
; I don't like the vertical movement -- there's a shortcut in here somewhere
; to make it less computationally expensive I think. Right now it just does a
; two byte add and subtract of $20.
; The ball motion is also a bit weird looking. I don't know if this is an
; artifact of the simulation environment combined with a normal tearing
; artifact related to refresh or what.
; Blake Ramsdell, May 2007
init:
lda #$fe
sta $2 ; X velocity (0 = fast, ff = slow)
; (low bit is direction, 0 = down or right, 1 = up or left)
lda #$ee
sta $3 ; Y velocity
drawbox:
lda #0 ; Use $0-$1 as a screen address for drawing the field
sta $0
lda #2
sta $1
ldx #$20 ; Loop $20 times
boxloop:
lda #2 ; Line color (red)
sta $1ff,x ; Top line
sta $5df,x ; Bottom line
ldy #0
sta ($0),y ; Left line
ldy #$1f
sta ($0),y ; Right line
cpx #$1 ; If we're just before the bottom line...
beq noblocks ; Don't draw any blocks there
lda #3 ; First block for this row, Cyan in color
ldy #$17 ; It's at X position $17
sta ($0),y ; Draw it
lda #4 ; Second block for this row, Purple in color
iny ; It's at the next X position
sta ($0),y ; Draw it
lda #5 ; Third block for this row, Green in color
iny ; It's at the next X position
sta ($0),y ; Draw it
lda #6 ; Fourth block for this row, Blue in color
iny ; It's at the next X position
sta ($0),y ; Draw it
noblocks:
clc ; Get ready to increment the row, clear the carry for add
lda $0 ; Get the low byte
adc #$20 ; Add $20 to it for the next row
sta $0 ; Put it back
lda $1 ; Get the high byte
adc #0 ; Factor in the carry
sta $1 ; Put it back
dex ; Decrement the loop counter
bne boxloop ; Do it again unless it's zero
ldx $2 ; Load the X velocity
ldy $3 ; Load the Y velocity
lda #$44 ; Pick a start point
sta $0 ; Ball position low
lda #$02
sta $1 ; Ball position high
drawball:
txa ; Preserve X
pha
lda #1 ; Ball color (white)
ldx #0 ; Clear X for indirect addressing for writing to screen
sta ($0,x) ; Draw the ball
pla ; Restore X
tax
decloop:
dex ; Decrement the X velocity
beq updatexpos ; If it's zero, time to adjust X
dey ; Decrement the Y velocity
bne decloop ; If it's not zero, loop, otherwise fall through to adjust Y
updateypos:
txa ; Preserve X
pha
jsr clearball ; Put background over the current ball position
updateyposnoclear:
lda $3 ; Get the Y velocity
and #1 ; See if it's down
bne moveup ; If not, then it's up, otherwise fall through to down
movedown:
clc ; Prepare for moving to the next Y line and doing the add
lda $0 ; Low byte of the current ball position
adc #$20 ; Next row
sta $0 ; Put it back
bcc ycollision ; If no carry, go on to check for collision
inc $1 ; Had a carry, fix the high byte of the address
bne ycollision ; Z flag is always clear ($1 will never be zero)
moveup:
sec ; Prepare for moving to the previous Y line and subtracting
lda $0 ; Low byte of the current ball position
sbc #$20 ; Previous row
sta $0 ; Put it back
lda $1 ; High byte
sbc #$0 ; Factor out the carry
sta $1 ; Put it back
ycollision:
ldx #0 ; Prepare for indirect read
lda ($0,x) ; Get the current pixel at the new ball position
bne ycollided ; If it's not zero (the background color) then we hit
ldy $3 ; Otherwise, load up the current Y velocity
pla ; Restore the X velocity
tax
jmp drawball ; Back to the top
ycollided:
cmp #$2 ; Border color?
beq ycollided2 ; If so, then we just bounce, don't eat a brick
; Erase brick
lda #0 ; Background color (black)
sta ($0,x) ; Erase it
ycollided2:
lda #1 ; Get ready to change direction
eor $3 ; Flip the low bit on the Y velocity (change direction)
sta $3 ; Put it back
jmp updateyposnoclear ; Go back to make sure we didn't hit anything else
updatexpos:
jsr clearball ; Put background over the current ball position
updatexposnoclear:
lda $2 ; Get the current X velocity
and #1 ; See if it's right by testing the low bit
bne moveleft ; If not, move left
moveright:
inc $0 ; Move right
bne xcollision ; Z flag is always clear
moveleft:
dec $0 ; Move left
xcollision:
ldx #0 ; Prepare for indirect read
lda ($0,x) ; Get the current pixel at the new ball position
bne xcollided ; If it's not zero (the background color) then we hit
ldx $2 ; Otherwise, load up the current X velocity
jmp drawball ; Back to the top
xcollided:
cmp #$2 ; Border color?
beq xcollided2 ; If so, then we just bounce, don't eat a brick
; Erase brick
lda #0 ; Background color (black)
sta ($0,x) ; Erase it
xcollided2:
lda #1 ; Get ready to change direction
eor $2 ; Flip the low bit on the X velocity (change direction)
sta $2 ; Put it back
jmp updatexposnoclear ; Go back to make sure we didn't hit anything else
clearball:
lda #0 ; Background color (black)
tax ; Clear X for indirect
sta ($0,x) ; Black out the ball
rts ; Return to caller
|