-
Notifications
You must be signed in to change notification settings - Fork 2
/
demo3_4.asm
228 lines (199 loc) · 4.64 KB
/
demo3_4.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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
;
; Horizontal/vertical positioning demo (Chapter 3 section 4)
;
; by Oscar Toledo G.
; https://nanochess.org/
;
; Creation date: Jun/04/2022.
;
PROCESSOR 6502
INCLUDE "vcs.h"
XPOS = $0080 ; Current X position
XDIR = $0081 ; Current X direction
XPOS2 = $0082 ; Current X position (2)
YPOS2 = $0083 ; Current Y position (2)
ORG $F000
START:
SEI ; Disable interrupts.
CLD ; Clear decimal mode.
LDX #$FF ; X = $ff
TXS ; S = $ff
LDA #$00 ; A = $00
CLEAR:
STA 0,X ; Clear memory.
DEX ; Decrement X.
BNE CLEAR ; Branch if not zero.
LDA #76 ; Center of screen
STA XPOS
LDA #1 ; Go to right
STA XDIR
LDA #1
STA XPOS2
LDA #20
STA YPOS2
LDA #$00 ; Configure SWCHA as input
STA SWACNT
SHOW_FRAME:
LDA #$88 ; Blue.
STA COLUBK ; Background color.
LDA #$0F ; White.
STA COLUP0 ; Player 0 color.
LDA #$cF ; Green.
STA COLUP1 ; Player 1 color.
STA HMCLR ; Clear horizontal motion registers
STA WSYNC
LDA #2 ; Start of vertical retrace.
STA VSYNC
STA WSYNC
STA WSYNC
STA WSYNC
LDA #42 ; Time for NTSC top border
STA TIM64T
LDA #0 ; End of vertical retrace.
STA VSYNC
LDA XPOS ; Desired X position
LDX #0 ; Player 0
JSR x_position
LDA XPOS2 ; Desired X position
LDX #1 ; Player 1
JSR x_position
STA WSYNC ; Wait for scanline start
STA HMOVE ; Write HMOVE, only can be done
; just after STA WSYNC.
WAIT_FOR_TOP:
LDA INTIM ; Read timer
BNE WAIT_FOR_TOP ; Branch if not zero.
STA WSYNC ; Resynchronize on last border scanline
STA WSYNC
LDA #0 ; Disable blanking
STA VBLANK
LDX #183 ; 183 scanlines in blue.
LDY YPOS2 ; Y position of fly.
SPRITE1:
STA WSYNC ; Synchronize with scanline.
LDA #0 ; A = $00 no graphic.
DEY ; Decrement Y.
CPY #$F8 ; Y >= $f8? (carry = 1)
BCC L3 ; No, jump if carry clear.
LDA FLY_BITMAP-$F8,Y ; Load byte of graphic.
L3: STA GRP1 ; Update GRP1.
DEX ; Decrease X.
BNE SPRITE1 ; Repeat until zero.
LDX #9
LDY #0
SPRITE0:
STA WSYNC ; Synchronize with scanline.
LDA #0 ; A = $00 no graphic.
DEY ; Decrement Y.
CPY #$F8 ; Y >= $f8? (carry = 1)
BCC L4 ; No, jump if carry clear.
LDA SHIP_BITMAP-$F8,Y ; Load byte of graphic.
L4: STA GRP0 ; Update GRP0.
DEX ; Decrease X.
BNE SPRITE0 ; Repeat until zero.
LDA #2 ; Enable blanking
STA VBLANK
LDX #30 ; 30 scanlines of bottom border
BOTTOM:
STA WSYNC
DEX
BNE BOTTOM
; Move the ship
LDX XPOS ; Reg. X = XPOS
LDA SWCHA ; Read joystick.
AND #$40 ; Test left movement.
BNE L6 ; Jump if not moved.
DEX ; If moved, decrement X.
L6: LDA SWCHA ; Read joystick.
AND #$80 ; Test right movement.
BNE L7 ; Jump if not moved.
INX ; If moved, increment X.
L7:
CPX #1 ; X < 1?
BCS L8 ; No, jump.
LDX #1 ; X = 1
L8:
CPX #153 ; X >= 153?
BCC L9 ; No, jump.
LDX #152 ; X = 152
L9:
STX XPOS ; XPOS = Reg. X
; Move the fly
LDA XPOS2 ; A = XPOS2
CLC ; Clear carry (becomes zero)
ADC #1 ; A = A + 1 + Carry
CMP #153 ; Reached X-position 153?
BNE L5 ; Branch if Not Equal
LDA #0 ; If equal, reset to zero
L5: STA XPOS2 ; XPOS2 = A
AND #3 ; Get modulo 4 of XPOS2
ADC #20 ; Add base Y-coordinate
STA YPOS2 ; YPOS2 = A
JMP SHOW_FRAME
;
; Position an item in X
; Input:
; A = X position (1-159)
; X = Object to position (0=P0, 1=P1, 2=M0, 3=M1, 4=BALL)
;
; The internal loop should fit a 256-byte page.
;
x_position: ; Start cycle
sta WSYNC ; 3: Start scanline synchro
sec ; 5: Set carry (so SBC doesn't subtract extra)
ldy $80 ; 7: Eat 3 cycles
x_p1:
sbc #15 ; 10: Divide X by 15
bcs x_p1 ; 12: If the loop goes on, add 5 cycles each time
x_p2:
tay ; 14:
lda fine_adjust-$f1,y ; 18:
sta HMP0,x ; 22: Fine position
sta RESP0,x ; 26: Time of setup for coarse position.
rts
x_position_end:
; Detect code divided between two pages
; Cannot afford it because it takes one cycle more
if (x_p1 & $ff00) != (x_p2 & $ff00)
echo "Error: Page crossing"
err ; Force assembler error
endif
org $fef1 ; Table at last page of ROM
; Shouldn't cross page
fine_adjust:
.byte $70 ; 7px to left.
.byte $60 ; 6px to left.
.byte $50 ; 5px to left.
.byte $40 ; 4px to left.
.byte $30 ; 3px to left.
.byte $20 ; 2px to left.
.byte $10 ; 1px to left.
.byte $00 ; No adjustment.
.byte $f0 ; 1px to right.
.byte $e0 ; 2px to right.
.byte $d0 ; 3px to right.
.byte $c0 ; 4px to right.
.byte $b0 ; 5px to right.
.byte $a0 ; 6px to right.
.byte $90 ; 7px to right.
FLY_BITMAP:
.byte %00000000
.byte %01100000
.byte %11100100
.byte %01101000
.byte %00010000
.byte %00101100
.byte %00101110
.byte %00000100
SHIP_BITMAP:
.byte %00100100
.byte %11111111
.byte %01100110
.byte %00100100
.byte %00111100
.byte %00011000
.byte %00011000
.byte %00011000
ORG $FFFC
.word START
.word START