-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhoripos.asm
213 lines (176 loc) · 6.49 KB
/
horipos.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
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
P0XPos byte ; sprite X coordinate
P0XBegin byte ; start moving X pos from here
P0XEnd 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 P0XBegin
sta P0XPos ; initialize player X coordinate
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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
; Do the border checking at this position
; where current P0XPos has just been loaded into register
; ; first, check if we are inside the lower boundary
; CheckLower:
; SEC ; C = 1
; CMP P0XBegin ; A == X ?
; BCS CheckUpper ; A (pos) >= X (begin) -> jump
; ; if A (pos) < limit
; LDA P0XBegin ; reset pos to min
; STA P0XPos ; and update memory
; JMP ContinueScanlines ; already reset - skip upper boundary check
; ; then, ensure we are under the upper boundary
; CheckUpper:
; SEC
; CMP P0XEnd
; BCC ContinueScanlines ; A (pos) < X (end)
; ; if A >= limit, reset
; LDA P0XBegin
; STA P0XPos
; ; jump to here if checks pass
; ContinueScanlines
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
REPEAT 90
sta WSYNC ; wait for empty scanlines
REPEND
ldy #8 ; counter to draw 8 rows of bitmap
DrawBitmap:
lda P0Bitmap,Y ; load player bitmap slice of data
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
sta WSYNC ; wait for next scanline
dey
bne DrawBitmap ; repeat next scanline until finished
lda #0
sta GRP0 ; disable P0 bitmap graphics
REPEAT 94
sta WSYNC ; wait for remaining empty scanlines
REPEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Increment X coordinate before next frame for animation.
;; Ensure position stays in pre-set boundaries and reset position if does
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lda P0XPos
cmp P0XEnd
BPL ResetPos ; if a > x, branch
inc P0XPos ; a <= X, pos++
jmp StartFrame ; goto next frame
; if pos >= limit, reset the X position to start
ResetPos:
LDX P0XBegin ; read X = begin
STX P0XPos ; Pos = begin
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Loop to next frame
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
jmp StartFrame
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Lookup table for the player graphics bitmap.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
P0Bitmap:
byte #%00000000
byte #%00010000
byte #%00001000
byte #%00011100
byte #%00110110
byte #%00101110
byte #%00101110
byte #%00111110
byte #%00011100
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Lookup table for the player colors.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
P0Color:
byte #$00
byte #$02
byte #$02
byte #$52
byte #$52
byte #$52
byte #$52
byte #$52
byte #$52
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Complete ROM size
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org $FFFC
word Reset
word Reset