-
Notifications
You must be signed in to change notification settings - Fork 2
/
tilelib.asm
303 lines (297 loc) · 4.63 KB
/
tilelib.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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
.ifndef TILELIB_INC
TILELIB_INC = 1
xy2vaddr: ; Input:
; A: layer
; X: tile display x position
; Y: tile display y position
; Output:
; A: VRAM bank
; X/Y: VRAM addr
jmp @start
@vars:
@config: .byte 0
@tilebase: .byte 0
@map: .word 0
@xoff: .word 0
@yoff: .word 0
@end_vars:
@banks: .byte 0,1
@start:
phx
ldx #(@end_vars-@vars-1)
@init:
stz @vars,x
dex
bpl @init
plx
cmp #0
bne @layer1
lda VERA_L0_config
sta @config
lda VERA_L0_tilebase
sta @tilebase
stz @map
lda VERA_L0_mapbase
sta @map+1
lda VERA_L0_hscroll_l
sta @xoff
lda VERA_L0_hscroll_h
sta @xoff+1
lda VERA_L0_vscroll_l
sta @yoff
lda VERA_L0_vscroll_h
sta @yoff+1
jmp @do_calc
@layer1:
lda VERA_L1_config
sta @config
lda VERA_L1_tilebase
sta @tilebase
stz @map
lda VERA_L1_mapbase
sta @map+1
lda VERA_L1_hscroll_l
sta @xoff
lda VERA_L1_hscroll_h
sta @xoff+1
lda VERA_L1_vscroll_l
sta @yoff
lda VERA_L1_vscroll_h
sta @yoff+1
@do_calc:
lda @tilebase
and #$01
beq @xoff_div8
clc ; tiles are 16 pixels wide, xoff >> 4
ror @xoff+1
ror @xoff
@xoff_div8:
lsr @xoff+1
ror @xoff
lsr @xoff+1
ror @xoff
lsr @xoff+1
ror @xoff
txa
clc
adc @xoff
sta @xoff
bcc @calc_yoff
lda #1
sta @xoff+1
@calc_yoff:
lda @tilebase
and #$02
beq @yoff_div8
clc ; tiles are 16 pixels high, yoff >> 4
ror @yoff+1
ror @yoff
@yoff_div8:
lsr @yoff+1
ror @yoff
lsr @yoff+1
ror @yoff
lsr @yoff+1
ror @yoff
tya
clc
adc @yoff
sta @yoff
bcc @calcaddr
lda #1
sta @yoff+1
@calcaddr: ; address = map_base+(yoff*MAPW+xoff)*2
lda @config
and #$30
lsr
lsr
lsr
lsr
clc
adc #5
tax ; X = log2(MAPW)
@mult_loop:
txa
beq @end_mult_loop
asl @yoff
rol @yoff+1
dex
jmp @mult_loop
@end_mult_loop: ; yoff = yoff*MAPW
clc
lda @yoff
adc @xoff
sta @yoff
lda @yoff+1
adc @xoff+1
sta @yoff+1 ; yoff = yoff + xoff
asl @yoff
rol @yoff+1 ; yoff = yoff * 2
asl @map+1
lda #0
bcc @push_bank
lda #1
@push_bank:
pha
lda @yoff
sta @map
lda @map+1
clc
adc @yoff+1
sta @map+1
ldx #0
bcc @pull_bank
ldx #1
@pull_bank:
pla
clc
adc @banks,x
ldx @map
ldy @map+1
rts
pix2tilexy: ; Input:
; A: bit 4: layer; bits 3,2: x (9:8), bits 1,0: y (9:8)
; X: display x (7:0)
; Y: display y (7:0)
; Output:
; A: bits 7-4: TILEW/2, bits 3-0: TILEH/2
; X: tile x
; Y: tile y
jmp @start
@tilebase: .byte 0
@xoff: .word 0
@yoff: .word 0
@xshift: .byte 3
@yshift: .byte 3
@start:
pha ; push A params
and #$10
cmp #0
bne @layer1
lda VERA_L0_tilebase
sta @tilebase
lda VERA_L0_hscroll_l
sta @xoff
lda VERA_L0_vscroll_l
sta @yoff
bra @gettw
@layer1:
lda VERA_L1_tilebase
sta @tilebase
lda VERA_L1_hscroll_l
sta @xoff
lda VERA_L1_vscroll_l
sta @yoff
@gettw:
lda @tilebase
and #$01
bne @tw16
lda #3
sta @xshift
lda @xoff
and #$07 ; A = xoff % 8
jmp @calcx
@tw16:
lda #4
sta @xshift
lda @xoff
and #$0F ; A = xoff % 16
@calcx:
sta @xoff
txa
sec
sbc @xoff
php
plx
sta @xoff
pla
pha
and #$0C
lsr
lsr
phx
plp
sbc #0
bpl @do_xshift
stz @xoff
stz @xoff+1
bra @getth
@do_xshift:
sta @xoff+1
ldx @xshift
@xshift_loop:
beq @getth
lsr @xoff+1
ror @xoff
dex
bra @xshift_loop
@getth:
lda @tilebase
and #$02
bne @th16
lda #3
sta @yshift
lda @yoff
and #$07 ; A = yoff % 8
jmp @calcy
@th16:
lda #4
sta @yshift
lda @yoff
and #$0F ; A = yoff %16
@calcy:
sta @yoff
tya
sec
sbc @yoff
php
plx
sta @yoff
pla
and #$03
phx
plp
sbc #0
bpl @do_yshift
stz @yoff
stz @yoff+1
bra @end
@do_yshift:
ldy @yshift
@yshift_loop:
beq @end
lsr @yoff+1
ror @yoff
dey
bra @yshift_loop
@end:
lda @xshift
asl
asl
asl
asl
ora @yshift
asl
ldx @xoff
ldy @yoff
rts
get_tile: ; Input:
; A: layer
; X: tile display x position
; Y: tile display y position
; Output:
; A: layer
; X: tile entry 0
; Y: tile entry 1
pha
jsr xy2vaddr
stz VERA_ctrl
ora #$10
sta VERA_addr_bank
stx VERA_addr_low
sty VERA_addr_high
ldx VERA_data0
ldy VERA_data0
pla
rts
.endif