forked from maccasoft/propeller-graphics-card
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscanline_renderer.inc
583 lines (470 loc) · 22 KB
/
scanline_renderer.inc
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
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
/*
* P8X Game System
* Video Scanline Renderer
*
* 256 or 320 horizontal pixels lines
* 6-bits per pixels (direct palette)
* 8x8 pixels tiles
* 8x8 up to 32x32 pixels sprites
* Full-screen scrolling
*
* Copyright (c) 2015-2018 Marco Maccaferri
* MIT Licensed.
*/
#include "defines.inc"
.org 0
jmp #setup
vsync
rdlong a, hub_fi wz
if_nz jmp #$-1 // wait for line counter reset (vsync)
mov sbuf_ptr, #0
movd _rd0, #sprites_table + MAX_SPRITES - 1
movd _rd1, #sprites_table + MAX_SPRITES - 2
add sbuf_ptr, #MAX_SPRITES * 4 -1
movi sbuf_ptr, #MAX_SPRITES - 2
_rd0 rdlong 0-0, sbuf_ptr
sub _rd0, inc_dest_2
sub sbuf_ptr, i2s7 wc
_rd1 rdlong 0-0, sbuf_ptr
sub _rd1, inc_dest_2
if_nc djnz sbuf_ptr, #_rd0
mov sbuf_ptr, hub_attributes_ptr
rdword hub_tiles_data, sbuf_ptr
add sbuf_ptr, #2
rdword hub_sprites_data, sbuf_ptr
add sbuf_ptr, #2
rdword xs, sbuf_ptr
add sbuf_ptr, #2
rdword ys, sbuf_ptr
mov scnt, offset
// tiles
loop
mov loffs, scnt
add loffs, ys
_vsub1 cmpsub loffs, #V_RES
#if VRAM_TILES_H == 40
mov a, loffs
shr a, #3
_hmul1 shl a, #3
mov video_ptr, a
shl video_ptr, #2
add video_ptr, a
#elif VRAM_TILES_H == 32
mov video_ptr, loffs
shr video_ptr, #3
_hmul1 shl video_ptr, #5
#endif
and loffs, #7
shl loffs, #3 // 8-bytes per scanline
add loffs, hub_tiles_data
test xs, #%100 wz
if_z movd str0, #sbuf
if_nz movd str0, #sbuf-1
if_z movd str1, #sbuf+1
if_nz movd str1, #sbuf
mov a, xs
shr a, #3
add video_ptr, a
add video_ptr, hub_video_ram
_htiles1 mov ccnt, #VRAM_TILES_H
sub ccnt, a
mov ecnt, #VRAM_TILES_H+1
_l1 rdbyte tile_ptr, video_ptr // read tile number to display
shl tile_ptr, #6 // 64 bytes per tile
add tile_ptr, loffs
rdlong colors1, tile_ptr // pixels, 8 bit per pixel, from msb
and colors1, color_mask
add tile_ptr, #4
rdlong colors2, tile_ptr
and colors2, color_mask
str0 mov 0-0, colors1
add str0, inc_dest_2
str1 mov 0-0, colors2
add str1, inc_dest_2
add video_ptr, #1
sub ccnt, #1 wz
_htiles2 if_z sub video_ptr, #VRAM_TILES_H
_htiles3 if_z mov ccnt, #VRAM_TILES_H
djnz ecnt, #_l1
// fine scroll
movs _src1h,#sbuf
movs _src2h,#sbuf+1
movd _dst1h,#sbuf
mov b, xs
and b, #3 wz
shl b, #3
mov x, #32
sub x, b
mov ecnt, #H_RES/4
_src1h mov colors1, 0-0
_src2h mov colors2, 0-0
if_nz shr colors1, b
if_nz shl colors2, x
if_nz or colors1, colors2
_dst1h mov 0-0, colors1
add _src1h, #1
add _src2h, #1
add _dst1h, inc_dest
djnz ecnt, #_src1h
// sprites
movs _tile, #sprites_table // Initialize sprite rendering
mov pcnt, #MAX_SPRITES
_tile mov tile, 0-0 wz
if_z jmp #_next
test tile, y_sign_mask wc // check 9th bit
mov y, tile
shl y, #16
rcr y, #24 // sign-extend y
cmps y, neg_clip wz,wc
if_c and y, #$1FF // max -32
mov h, tile // calculate height
shr h, #25
and h, #$18
add h, #8
mov a, scnt // check sprite scanline visibility
subs a, y wc,wz
if_c jmp #_next
cmp a, h wc,wz
if_nc jmp #_next
test tile, flip_mask wz // adjust y if sprite is flipped
if_nz mov y, h
if_nz sub y, #1
if_nz sub y, a
if_nz mov a, y
shl a, #3 // 8-bits per pixel
shl h, #3
mov ecnt, tile // calculate width
shr ecnt, #27
and ecnt, #$18
add ecnt, #8
mov tile_ptr, tile
and tile_ptr, tile_mask
shr tile_ptr, #10
add tile_ptr, hub_sprites_data
add tile_ptr, a
test tile, mirror_mask wz
cmp ecnt, #16 wc
if_nz_and_nc add tile_ptr, h
if_nc cmp ecnt, #24 wc
if_nz_and_nc add tile_ptr, h
if_nc cmp ecnt, #32 wc
if_nz_and_nc add tile_ptr, h
sumz h, #4
test tile, x_sign_mask wc // check 9th bit
mov x, tile
shl x, #24
rcr x, #24 // sign-extend x
cmps x, neg_clip wz,wc
if_c and x, #$1FF // max -32
movd _src0, #sbuf // sets source and destination buffer pointers
movd _src1, #sbuf+1
movd _dst0, #sbuf
movd _dst1, #sbuf+1
mov a, x // adjust scanline buffer pointer to x location
sar a, #2
shl a, #9
add _src0, a
add _src1, a
add _dst0, a
add _dst1, a
and x, #3
mov ccnt, #8
sub ccnt, x
shl x, #3 // 8-bits per pixel
mov b, #32
sub b, x
mov pixels2, #0
_l2 rdlong data1, tile_ptr
xor data1, transparency_mask
add tile_ptr, #4
rdlong data2, tile_ptr
xor data2, transparency_mask
_l2b test tile, mirror_mask wc
sumc tile_ptr, h
if_c ror data1, #24
if_c mov a, data1
if_c and a, swap_mask
if_c ror data1, #16
if_c andn data1, swap_mask
if_c or a, data1
if_c ror data2, #24
if_c mov data1, data2
if_c and data1, swap_mask
if_c ror data2, #16
if_c andn data2, swap_mask
if_c or data1, data2
if_c mov data2, a
mov pixels1, data1
shl pixels1, x
or pixels1, pixels2
cmp x, #0 wz
if_nz mov pixels2, data1
shr pixels2, b
mov colors1, #0
test pixels1, t_mask_0 wz
if_z or colors1, mask_0
test pixels1, t_mask_1 wz
if_z or colors1, mask_1
test pixels1, t_mask_2 wz
if_z or colors1, mask_2
test pixels1, t_mask_3 wz
if_z or colors1, mask_3
_src0 and 0-0, colors1
andn pixels1, colors1
_dst0 or 0-0, pixels1
mov pixels1, data2
shl pixels1, x
or pixels1, pixels2
cmp x, #0 wz
if_nz mov pixels2, data2
shr pixels2, b
mov colors1, #0
test pixels1, t_mask_0 wz
if_z or colors1, mask_0
test pixels1, t_mask_1 wz
if_z or colors1, mask_1
test pixels1, t_mask_2 wz
if_z or colors1, mask_2
test pixels1, t_mask_3 wz
if_z or colors1, mask_3
_src1 and 0-0, colors1
andn pixels1, colors1
_dst1 or 0-0, pixels1
sub ecnt, ccnt wc,wz
if_z_or_c jmp #_next
add _src0, inc_dest_2
add _src1, inc_dest_2
add _dst0, inc_dest_2
add _dst1, inc_dest_2
mov ccnt, #8
cmp ecnt, #8 wc,wz
if_nc jmp #_l2
mov data1, #0
mov data2, #0
jmp #_l2b
_next add _tile, #1
djnz pcnt, #_tile
// overlay
mov loffs, scnt
cmpsub loffs, overlay1_start wz,wc
if_c cmp loffs, overlay1_lines wz,wc
if_c jmp #overlay
mov loffs, scnt
cmpsub loffs, overlay2_start wz,wc
if_c cmp loffs, overlay2_lines wz,wc
if_c add loffs, overlay1_lines
if_nc jmp #emit
overlay
#if VRAM_TILES_H == 40
mov a, loffs
andn a, #$07
mov video_ptr, a
shl video_ptr, #2
add video_ptr, a
#elif VRAM_TILES_H == 32
mov video_ptr, loffs
shr video_ptr, #3
shl video_ptr, #5
#endif
add video_ptr, hub_video_overlay_ram
and loffs, #7
shl loffs, #3
add loffs, hub_tiles_data
movd _sr0, #sbuf
movd _sr1, #sbuf+1
movd _st0, #sbuf
movd _st1, #sbuf+1
mov ecnt, #VRAM_TILES_H
_l4 rdbyte tile_ptr, video_ptr
shl tile_ptr, #6
add tile_ptr, loffs
rdlong pixels1, tile_ptr
mov colors1, #0
test pixels1, t_mask_0 wz
if_nz or colors1, mask_0
test pixels1, t_mask_1 wz
if_nz or colors1, mask_1
test pixels1, t_mask_2 wz
if_nz or colors1, mask_2
test pixels1, t_mask_3 wz
if_nz or colors1, mask_3
_sr0 and 0-0, colors1
andn pixels1, colors1
_st0 or 0-0, pixels1
add tile_ptr, #4
rdlong pixels1, tile_ptr
mov colors1, #0
test pixels1, t_mask_0 wz
if_nz or colors1, mask_0
test pixels1, t_mask_1 wz
if_nz or colors1, mask_1
test pixels1, t_mask_2 wz
if_nz or colors1, mask_2
test pixels1, t_mask_3 wz
if_nz or colors1, mask_3
_sr1 and 0-0, colors1
andn pixels1, colors1
_st1 or 0-0, pixels1
add _sr0, inc_dest_2
add _sr1, inc_dest_2
add _st0, inc_dest_2
add _st1, inc_dest_2
add video_ptr, #1
djnz ecnt, #_l4
// scanline buffer output
emit
rdlong a, hub_fi
cmp a, scnt wz,wc
if_ne jmp #$-2 // wait for line fetch start
mov sbuf_ptr, hub_sbuf
wrlong sbuf, sbuf_ptr
add sbuf_ptr, #4
wrlong sbuf + 1, sbuf_ptr
add sbuf_ptr, #4
wrlong sbuf + 2, sbuf_ptr
add sbuf_ptr, #4
wrlong sbuf + 3, sbuf_ptr
add sbuf_ptr, #4
wrlong sbuf + 4, sbuf_ptr
add sbuf_ptr, #4
wrlong sbuf + 5, sbuf_ptr
add sbuf_ptr, #4
wrlong sbuf + 6, sbuf_ptr
add sbuf_ptr, #4
wrlong sbuf + 7, sbuf_ptr
add sbuf_ptr, #4
wrlong sbuf + 8, sbuf_ptr
add sbuf_ptr, #4
wrlong sbuf + 9, sbuf_ptr
add sbuf_ptr, #4
movd _wr0, #sbuf +(H_RES/4) -1
movd _wr1, #sbuf +(H_RES/4) -2
add sbuf_ptr, #(H_RES-40) -1
movi sbuf_ptr, #((H_RES/4)-10) -2
_wr0 wrlong 0-0, sbuf_ptr
sub _wr0, inc_dest_2
sub sbuf_ptr, i2s7 wc
_wr1 wrlong 0-0, sbuf_ptr
sub _wr1, inc_dest_2
if_nc djnz sbuf_ptr, #_wr0
add scnt, #COGS // next line to render
cmp scnt, #V_RES wc,wz
if_b jmp #loop
jmp #vsync
// driver parameters
hub_video_ram long $0000 + (MAX_SPRITES * 4)
hub_video_overlay_ram long $0000 + (MAX_SPRITES * 4)
hub_tiles_data long $0000 + (MAX_SPRITES * 4)
hub_sprites_data long $0000 + (MAX_SPRITES * 4)
hub_attributes_ptr long $7EB0
hub_fi long $7EBC
hub_sbuf long $7EC0 + SBUF_OFS
// initialised data and/or presets
inc_dest long 1 << 9
inc_dest_2 long 2 << 9
i2s7 long 2 << 23 | 7
mask_0 long $00_00_00_FF
mask_1 long $00_00_FF_00
mask_2 long $00_FF_00_00
mask_3 long $FF_00_00_00
swap_mask long $00_FF_00_FF
t_mask_0 long %00000000_00000000_00000000_00000001
t_mask_1 long %00000000_00000000_00000001_00000000
t_mask_2 long %00000000_00000001_00000000_00000000
t_mask_3 long %00000001_00000000_00000000_00000000
color_mask long %11111100_11111100_11111100_11111100
transparency_mask long %00000001_00000001_00000001_00000001
x_sign_mask long %00000001_00000000_00000000_00000000
y_sign_mask long %00000010_00000000_00000000_00000000
mirror_mask long %00000100_00000000_00000000_00000000
flip_mask long %00001000_00000000_00000000_00000000
tile_mask long %00000000_11111111_00000000_00000000
neg_clip long -32
overlay1_start long 0
overlay1_lines long 0
overlay2_start long 0
overlay2_lines long 0
pixels1 long 0
pixels2 long 0
colors1 long 0
colors2 long 0
// uninitialised data and/or temporaries
sprites_table res MAX_SPRITES
a res 1
b res 1
h res 1
x res 1
y res 1
data1 res 1
data2 res 1
tile res 1
offset res 1
loffs res 1
xs res 1
ys res 1
ecnt res 1
scnt res 1
ccnt res 1
pcnt res 1
tile_ptr res 1
video_ptr res 1
// code and/or data repurposed for scanline buffer
setup
sbuf_ptr
mov offset, PAR
shr offset, #2
and offset, #$7
rdbyte data, cog_param_addr
add cog_param_addr, #1
rdbyte data1, cog_param_addr
add cog_param_addr, #1
rdbyte data2, cog_param_addr
sbuf
test vram_expand_h_flag, PAR wz
if_nz add _htiles1, #VRAM_TILES_H
if_nz add _htiles2, #VRAM_TILES_H
if_nz add _htiles3, #VRAM_TILES_H
if_nz add _hmul1, #1
if_nz shl hub_vram_size, #1
test vram_expand_v_flag, PAR wz
if_nz add _vsub1, #V_RES
if_nz shl hub_vram_size, #1
add hub_video_overlay_ram, hub_vram_size
mov overlay1_lines, data1 // overlay 1 rows
and overlay1_lines, #$0F
mov overlay1_start, data1
shr overlay1_start, #4 // overlay 1 start
mov overlay2_lines, data2 // overlay 2 rows
and overlay2_lines, #$0F
shr data2, #4
mov overlay2_start, #VRAM_TILES_V // overlay 2 start from bottom
sub overlay2_start, overlay2_lines
sub overlay2_start, data2
test vram_expand_h_flag, PAR wz
test vram_expand_v_flag, PAR wz
shl overlay1_start, #3
shl overlay1_lines, #3
shl overlay2_start, #3
shl overlay2_lines, #3
jmp #vsync
vram_expand_h_flag long VRAM_EXPAND_H << 5
vram_expand_v_flag long VRAM_EXPAND_V << 5
hub_vram_size long VRAM_TILES_H * VRAM_TILES_V
cog_param_addr long $6E00
data res 1
fit $1F0
/*
* TERMS OF USE: MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
* is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/