-
Notifications
You must be signed in to change notification settings - Fork 0
/
movement.asm
235 lines (193 loc) · 6.54 KB
/
movement.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
229
230
231
232
233
234
235
processor 6502
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Include required files with register mapping and macros
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include "vcs.h"
include "macro.h"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Start an uninitialized segment at $80 for var declaration.
;; We have memory from $80 to $FF to work with, minus a few at
;; the end if we use the stack.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
seg.u Variables
org $80
P0Height .byte ; player sprite height
P0XPos .byte ; sprite X coordinate
P0XBegin .byte ; start moving X pos from here
P0XEnd .byte ; stop moving X pos here and start again
P0YPos .byte ; sprite Y coordinate
P0YBegin .byte ; start moving X pos from here
P0YEnd .byte ; stop moving X pos here and start again
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Start our ROM code segment starting at $F000.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
seg Code
org $F000
Reset:
CLEAN_START ; macro to clean memory and TIA
ldx #$00 ; black background color
stx COLUBK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Initialize variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ldx #40 ; X = 40
; stx P0XBegin ; set P0Beg = X
; ldx #80 ; X = 80
; stx P0XEnd ; set P0End = X
lda #70
sta P0XPos ; initialize player X coordinate
lda #86 ; screen half - player size
sta P0YPos ; set plr y pos
lda #17
sta P0Height ; set player height
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Start a new frame by configuring VBLANK and VSYNC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
StartFrame:
lda #2
sta VBLANK ; turn VBLANK on
sta VSYNC ; turn VSYNC on
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Display 3 vertical lines of VSYNC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
REPEAT 3
sta WSYNC ; first three VSYNC scanlines
REPEND
lda #0
sta VSYNC ; turn VSYNC off
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set player horizontal position while in VBLANK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lda P0XPos ; load register A with desired X position
and #$7F ; same as AND 01111111, forces bit 7 to zero
; keeping the result positive
sec ; set carry flag before subtraction
sta WSYNC ; wait for next scanline
sta HMCLR ; clear old horizontal position values
DivideLoop:
sbc #15 ; Subtract 15 from A
bcs DivideLoop ; loop while carry flag is still set
eor #7 ; adjust the remainder in A between -8 and 7
REPEAT 4
asl ; shift left by 4, as HMP0 uses only 4 bits
REPEND
sta HMP0 ; set smooth position value
sta RESP0 ; fix rough position
sta WSYNC ; wait for next scanline
sta HMOVE ; apply the fine position offset
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Let the TIA output the 35 (37 - 2) recommended lines of VBLANK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
REPEAT 35
sta WSYNC
REPEND
lda #0
sta VBLANK ; turn VBLANK off
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Draw the 192 visible scanlines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ldx #192 ; A = 192
Scanline:
txa ; transfer X to A
sec ; make sure carry flag is set
sbc P0YPos ; subtract sprite Y coordinate
cmp P0Height ; are we inside the sprite height bounds?
bcc LoadBitmap ; if result < SpriteHeight, call subroutine
lda #0 ; else, set index to 0
LoadBitmap:
tay
lda P0Bitmap,Y ; load player bitmap slice of data
sta WSYNC ; wait for next scanline
sta GRP0 ; set graphics for player 0 slice
lda P0Color,Y ; load player color from lookup table
sta COLUP0 ; set color for player 0 slice
dex
bne Scanline ; repeat next scanline until finished
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Output 30 more VBLANK overscan lines to complete our frame
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Overscan:
lda #2
sta VBLANK ; turn VBLANK on again for overscan
REPEAT 30
sta WSYNC
REPEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Joystick input test for P0 up/down/left/right
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CheckP0Up:
lda #%00010000
bit SWCHA
bne CheckP0Down
inc P0YPos
CheckP0Down:
lda #%00100000
bit SWCHA
bne CheckP0Left
dec P0YPos
CheckP0Left:
lda #%01000000
bit SWCHA
bne CheckP0Right
dec P0XPos
CheckP0Right:
lda #%10000000
bit SWCHA
bne NoInput
inc P0XPos
NoInput:
; fallback when no input was performed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Loop to next frame
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
jmp StartFrame
; Goto near end of the rom
org $FF00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Lookup table for the player graphics bitmap
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
P0Bitmap:
.byte #%00000000
.byte #%00010100
.byte #%00010100
.byte #%00010100
.byte #%00010100
.byte #%00010100
.byte #%00011100
.byte #%01011101
.byte #%01011101
.byte #%01011101
.byte #%01011101
.byte #%01111111
.byte #%00111110
.byte #%00010000
.byte #%00011100
.byte #%00011100
.byte #%00011100
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Lookup table for the player colors
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
P0Color:
.byte #$00
.byte #$F6
.byte #$F2
.byte #$F2
.byte #$F2
.byte #$F2
.byte #$F2
.byte #$C2
.byte #$C2
.byte #$C2
.byte #$C2
.byte #$C2
.byte #$C2
.byte #$3E
.byte #$3E
.byte #$3E
.byte #$24
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Complete ROM size
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org $FFFC
.word Reset
.word Reset