-
Notifications
You must be signed in to change notification settings - Fork 0
/
sprites.s
1616 lines (1419 loc) · 31.2 KB
/
sprites.s
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
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; sprites boiler code
;1. regular sprite code, preshift 16 sprite versions, for each sprite to be painted, determine source buffer and copy it to screen (basically, bounding square copy, unoptimized)
;2. regular sprite code, generated; for each sprite, determine specific sprite draw code (basically, omit copying words that are not filled)
;3. regular sprite code, generated, but reuse registers (same as 2, but instead of using immediate addressing, preload registers if words are used more than once; -> needed for sprites that are mirrored over y)
;1a. regular sprite code, preshift 16 versions, but instead of iterate per sprite, sort the sprites per sprite source, so draw list for 0 first, then lsit for 1, etc.
;4. combine 1a and 3
; todo, in a list of linked jump execution code, based on an offset, you can use the offset that is used to determine the code to be excuted, to point to an
; exclusive terminating rout, and thus not needing the -1 for checking to terminate the list of data
BITPLANES equ 2 ; 1 = 1 bitplane, 2 = 2 bitplanes
spriteSize equ 0 ; 0 = 16 x 16 / 1 = 32 x 32 1 plane 2 plane
SPRITEROUT equ 3 ; 1 = naive normal 125 / 44 92 / 31
; 2 = generated sprite rout 145 / 60 136 / 49 ; todo: remove blt in drawSprites, for sprites*8 cpu
; 3 = generated sprite rout regs 160 / 66 142 / 54
; 4 = generated sprite rout + partition
; for this rout, we do code generation for setting up regs seperate from the drawing code
; and we use all masks into regs
spriteCodeSize equ 1024
listSize set 64
IF spriteSize=0
spriteHeight equ 16
spriteWidth equ 16/16 ; per 16 pixel blocks
IF BITPLANES=1
nr_sprites set 142
ENDC
IF BITPLANES=2
nr_sprites set 142
ENDC
ENDC
IF spriteSize=1
spriteHeight equ 32
spriteWidth equ 32/16 ; per 16 pixel blocks
listSize set 64*2
IF BITPLANES=1
nr_sprites set 44
ENDC
IF BITPLANES=2
nr_sprites set 54
ENDC
ENDC
IFD DEMOSYSTEM
IFD STANDALONE
ELSE
STANDALONE equ 1
ENDC
ELSE
STANDALONE equ 0
ENDC
IFEQ STANDALONE
TRUE equ 0
FALSE equ 1
true equ 0
false equ 1
ENDC
incdir gfx
incdir lib
incdir msx
incdir res/smfx
section TEXT
include macro.s
IFEQ STANDALONE
initAndRun standalone_init
standalone_init
jsr init_effect
.x
cmp.b #$39,$fffffc02.w ; spacebar to exit
bne .x ;
rts
ENDC
init_effect
move.w #$700,$ffff8240
move.l #memBase+65536,d0
sub.w d0,d0
move.l d0,screenpointer
add.l #$10000,d0
move.l d0,screenpointer2
add.l #$10000,d0
move.l d0,d1
move.l d1,y2pointer
add.l #1536*2*2,d1 ;-3072
move.l d1,y1pointer
add.l #512*2*2,d1 ;-1024
move.l d1,x1pointer
add.l #8*273*2*2,d1 ;-4368
move.l d1,x2pointer
add.l #9*128*2*2,d1 ;-2304
add.l #$10000,d0
move.l d0,xPositionPointer
add.l #$10000,d0
move.l d0,drawSpriteCodeBuffersPointer
add.l #$10000,d0
move.l d0,clearSpriteCodeBuffersPointer
jsr generateDrawSpriteCodeBuffers
jsr generateClearSpriteCodeBuffers
IF SPRITEROUT=1
jsr generateXPointerNaive
jsr generateSineTablesNaive
ENDC
IF BITPLANES=1
jsr prepSprites1Bitplane
ENDC
IF BITPLANES=2
jsr prepSprites2Bitplanes
ENDC
IF SPRITEROUT=2
jsr genSpriteCodeImmediate
jsr genSpriteClearCode
jsr generateXPointerImmediate
jsr generateSineTablesImmediate
lea cspr1,a0
move.w #16*spriteCodeSize,(a0)+
move.w #16*spriteCodeSize,(a0)+
lea cspr2,a0
move.w #16*spriteCodeSize,(a0)+
move.w #16*spriteCodeSize,(a0)+
ENDC
IF SPRITEROUT=3
jsr genSpriteClearCode
jsr generateXPointerImmediate
jsr generateSineTablesImmediate
lea cspr1,a0
move.w #16*spriteCodeSize,(a0)+
move.w #16*spriteCodeSize,(a0)+
lea cspr2,a0
move.w #16*spriteCodeSize,(a0)+
move.w #16*spriteCodeSize,(a0)+
IF BITPLANES=1
jsr analyseSprite1Bitplane
ENDC
IF BITPLANES=2
jsr analyseSprite2Bitplanes
ENDC
ENDC
; IF SPRITEROUT=4
; jsr genSpriteClearCode
; jsr generateXPointerImmediate
; jsr generateSineTablesImmediate
; lea cspr1,a0
; move.w #16*spriteCodeSize,(a0)+
; move.w #16*spriteCodeSize,(a0)+
; lea cspr2,a0
; move.w #16*spriteCodeSize,(a0)+
; move.w #16*spriteCodeSize,(a0)+
; jsr analyseSprite1Bitplane
; ENDC
move.l drawSpriteCodeBuffersPointer,a6
rept 16
; move.b #0,$ffffc123
add.l #spriteCodeSize,a6
endr
; rts
move.w #$2700,sr
move.l #.wvbl,$70
move.w #$2300,sr
move.b #0,$ffffc123
move.w #0,$466
.w tst.w $466.w
beq .w
move.w #0,$466
move.w #$2700,sr
move.l #effect_vbl,$70
move.w #$2300,sr
rts
.vblwaiter dc.w 20
.wvbl
addq.w #1,$466.w
rte
effect_vbl
move.w #$0,$ffff8240
move.l screenpointer2,$ffff8200
pushall
IF SPRITEROUT=1
add.w #$001,$ffff8240
jsr clearSpritesNaive
add.w #$001,$ffff8240
jsr swapClearPointers
jsr advanceSprites
add.w #$001,$ffff8240
jsr drawSpritesNaive
ENDC
IF SPRITEROUT=2
add.w #$001,$ffff8240
jsr clearSpritesImmediate
add.w #$001,$ffff8240
jsr swapClearPointers
add.w #$001,$ffff8240
jsr advanceSprites
add.w #$001,$ffff8240
jsr drawSpritesImmediate
move.w savedHax,-2(a1)
ENDC
IF SPRITEROUT=3
add.w #$001,$ffff8240
jsr clearSpritesImmediate
add.w #$001,$ffff8240
jsr swapClearPointers
add.w #$001,$ffff8240
jsr advanceSprites
add.w #$001,$ffff8240
jsr drawSpritesImmediate
move.w savedHax,-2(a1)
ENDC
IF SPRITEROUT=4
add.w #$001,$ffff8240
jsr clearSpritesImmediate
add.w #$001,$ffff8240
jsr swapClearPointers
add.w #$001,$ffff8240
jsr advanceSprites
add.w #$001,$ffff8240
jsr drawSpritesImmediate
move.w savedHax,-2(a1)
ENDC
move.w #$200,$ffff8240
popall
swapscreens
rte
;;;;;------------------ GENERIC CODE ---------------------
;;;;;------------------ GENERIC CODE ---------------------
;;;;;------------------ GENERIC CODE ---------------------
swapClearPointers
move.l clearSpritesPointer2,d0
move.l clearSpritesPointer,clearSpritesPointer2
move.l d0,clearSpritesPointer
rts
generateDrawSpriteCodeBuffers
lea drawSpriteCodeBuffers,a0
move.l drawSpriteCodeBuffersPointer,d0
REPT 17
move.l d0,(a0)+
add.w #spriteCodeSize,d0
ENDR
rts
generateClearSpriteCodeBuffers
lea clearSpriteCodeBuffers,a0
move.l clearSpriteCodeBuffersPointer,d0
REPT 17
move.l d0,(a0)+
add.w #spriteCodeSize,d0
ENDR
rts
prepSprites1Bitplane
lea sprites+128,a0
lea sprite0,a1
moveq #0,d0
;.y set 0
moveq #0,d6
move.w #spriteHeight-1,d5
.ol
; REPT spriteHeight
move.w d6,d4
;.x set .y
move.w #spriteWidth-1,d3
.il
; REPT spriteWidth
move.w (a0,d4.w),(a1)+
;.x set .x+8
addq.w #8,d4
dbra d3,.il
; ENDR
move.w #0,(a1)+
;.y set .y+160
add.w #160,d6
; ENDR
dbra d5,.ol
lea sprite0,a0
lea spriteHeight*(spriteWidth+1)*2(a0),a1
move.w #spriteHeight*15-1,d7
.ol2
move.w #spriteWidth,d6
.il2
; REPT spriteWidth+1
move.w (a0)+,d0
roxr.w d0
move.w d0,(a1)+
dbra d6,.il2
; ENDR
dbra d7,.ol2
rts
prepSprites2Bitplanes
lea sprites+128,a0
add.w #32*160,a0
lea sprite0,a1
moveq #0,d0
.y set 0
REPT spriteHeight
.x set .y
REPT spriteWidth
move.l .x(a0),(a1)+
.x set .x+8
ENDR
move.l #0,(a1)+
.y set .y+160
ENDR
lea sprite0,a0
lea spriteHeight*(spriteWidth+1)*4(a0),a1
move.w #spriteHeight*15-1,d7
.l
REPT spriteWidth+1
move.w (a0)+,d0
roxr.w d0
move.w d0,(a1)+
lea 2(a0),a0
lea 2(a1),a1
ENDR
dbra d7,.l
lea sprite0,a0
lea spriteHeight*(spriteWidth+1)*4(a0),a1
move.w #spriteHeight*15-1,d7
moveq #0,d0
roxr.w d0
lea 2(a0),a0
lea 2(a1),a1
.l2
REPT spriteWidth+1
move.w (a0)+,d0
roxr.w d0
move.w d0,(a1)+
lea 2(a0),a0
lea 2(a1),a1
ENDR
dbra d7,.l2
rts
advanceSprites
add.w #2,sine_y1_step
and.w #sine_y1_step_mask,sine_y1_step
sub.w #10,sine_y2_step
and.w #sine_y2_step_mask,sine_y2_step
add.w #2,sine_x1_step
and.w #sine_x1_step_mask,sine_x1_step
add.w #2,sine_x2_step
and.w #sine_x2_step_mask,sine_x2_step
rts
;;;;;---------------- NAIVE CODE --------------------
;;;;;---------------- NAIVE CODE --------------------
;;;;;---------------- NAIVE CODE --------------------
generateSineTablesNaive
lea y1s,a0 ;64 words = 128 data
move.l y1pointer,a2
move.w #8-1,d7
.copy
move.l a0,a1
REPT 32
move.l (a1)+,(a2)+
ENDR
dbra d7,.copy
lea y2s,a0
move.l y2pointer,a2
move.w #3-1,d7 ; 3 * 512 * 2 = 1536 -> 3072
.copy2
move.l a0,a1
move.w #16-1,d6 ; 512
.il2
REPT 16
move.l (a1)+,(a2)+ ; 64
ENDR
dbra d6,.il2
dbra d7,.copy2
lea x1s,a0
move.l x1pointer,a2
move.w #8-1,d7
.ol3
move.l a0,a1
move.w #8-1,d6
.il3
REPT 17
move.l (a1)+,(a2)+ ;68
ENDR
dbra d6,.il3
move.w (a1)+,(a2)+
dbra d7,.ol3
lea x2s,a0
move.l x2pointer,a2
move.w #9-1,d7
.ol4
move.l a0,a1
move.w #4-1,d6 ;128
.il4
REPT 16
move.l (a1)+,(a2)+ ;64
ENDR
dbra d6,.il4
dbra d7,.ol4
rts
generateXPointerNaive
move.l xPositionPointer,a0
moveq #0,d0
move.w #20-1,d7 ; 20*16*16*2*2*2 = 320 * 16 * 2 * 2 * 2 = 5120 * 8 =
.ol
moveq #0,d1
move.w #16-1,d6
.il
move.w d0,(a0)+
move.w d1,(a0)+
add.w #spriteHeight*(spriteWidth+1)*2*BITPLANES,d1
dbra d6,.il
addq.w #8,d0
dbra d7,.ol
rts
IF SPRITEROUT=1
drawSpritesNaive
move.l screenpointer2,d1
move.l x1pointer,a1
add.w sine_x1_step,a1
move.l x2pointer,a2
add.w sine_x2_step,a2
move.l y1pointer,a3
add.w sine_y1_step,a3
move.l y2pointer,a4
add.w sine_y2_step,a4
move.l xPositionPointer,d0 ; aligned
lea sprite0,a6
move.l a6,usp
move.l clearSpritesPointer,a6
REPT nr_sprites
move.w (a1)+,d0 ;8 ; first x value
; add.w (a2)+,d0 ;8 ; second x value
move.l d0,a0 ;4 ; use x value as lookup
move.w (a0)+,d1 ;8 ; offset into screen
move.l usp,a5 ;4 ; use sprite lookup ; this could be 64kb aligned address; and save these cycles
add.w (a0),a5 ;12 ; add offset to source ; move.w (a0),d2 ; move.l d2,a5
add.w (a3)+,d1 ;8 ; add y1
; add.w (a4)+,d1 ;8 ; add y2
move.l d1,a0 ;4 ; use as screen
move.w d1,(a6)+ ;8 -->72 ; save screen off for clearing
IF BITPLANES=2
.p set 0
REPT 5
movem.l (a5)+,d2-d7 ;2,3,4,5,6 = 6
or.l d2,.p(a0)
or.l d3,.p+8(a0)
or.l d4,.p+160(a0)
or.l d5,.p+168(a0)
or.l d6,.p+320(a0)
or.l d7,.p+328(a0)
.p set .p+480
ENDR
move.l (a5)+,d2
move.l (a5)+,d3
or.l d2,.p(a0)
or.l d2,.p(a0)
ENDC
.p set 0
REPT spriteHeight
.c set .p
REPT spriteWidth+1
IF BITPLANES=1
move.w (a5)+,d0
or.w d0,.c(a0)
ENDC
IF BITPLANES=2
; move.l (a5)+,d5
; or.l d5,.c(a0)
ENDC
.c set .c+8
ENDR
.p set .p+160
ENDR
ENDR
rts
clearSpritesNaive
move.l screenpointer2,d0
move.l clearSpritesPointer2,a0
moveq #0,d1
REPT nr_sprites
move.w (a0)+,d0
move.l d0,a1
.c set 0
REPT spriteHeight
.p set .c
REPT spriteWidth+1
IF BITPLANES=1
move.w d1,.p(a1)
ENDC
IF BITPLANES=2
move.l d1,.p(a1)
ENDC
.p set .p+8
ENDR
.c set .c+160
ENDR
ENDR
rts
ENDC
;;;-------------- IMMEDIATE CODE -----------------
;;;-------------- IMMEDIATE CODE -----------------
;;;-------------- IMMEDIATE CODE -----------------
generateSineTablesImmediate
lea x1s,a0
move.l x1pointer,a2
move.w #8-1,d7
.ol3
move.l a0,a1
move.w #8-1,d6
.il3
REPT 17*2
move.w (a1)+,d0
add.w d0,d0
move.w d0,(a2)+ ;68
ENDR
dbra d6,.il3
move.w (a1)+,d0
add.w d0,d0
move.w d0,(a2)+
dbra d7,.ol3
lea x2s,a0
move.l x2pointer,a2
move.w #9-1,d7
.ol4
move.l a0,a1
move.w #4-1,d6 ;128
.il4
REPT 16*2
move.w (a1)+,d0
add.w d0,d0
move.w d0,(a2)+ ;64
ENDR
dbra d6,.il4
dbra d7,.ol4
lea y1s,a0 ;64 words = 128 data
move.l y1pointer,a2
move.w #8-1,d7
.copy
move.l a0,a1
REPT 32
move.l (a1)+,(a2)+
ENDR
dbra d7,.copy
lea y2s,a0
move.l y2pointer,a2
move.w #3-1,d7 ; 3 * 512 * 2 = 1536 -> 3072
.copy2
move.l a0,a1
move.w #16-1,d6 ; 512
.il2
REPT 16
move.l (a1)+,(a2)+ ; 64
ENDR
dbra d6,.il2
dbra d7,.copy2
rts
generateXPointerImmediate
move.l xPositionPointer,a0
move.l drawSpriteCodeBuffersPointer,a6
moveq #0,d0
move.w #20-1,d7
.ol
moveq #0,d1
move.w #16-1,d6
.il
move.w d0,(a0)+
move.w d1,(a0)+
move.l #0,(a0)+
add.l #spriteCodeSize,d1
dbra d6,.il
addq.w #8,d0
dbra d7,.ol
rts
drawSpritesImmediate
move.l screenpointer2,d1
move.l x1pointer,a1
add.w sine_x1_step,a1
move.l x2pointer,a2
add.w sine_x2_step,a2
move.l y1pointer,a3
add.w sine_y1_step,a3
move.l y2pointer,a4
add.w sine_y2_step,a4
move.l xPositionPointer,d0 ; aligned
lea sprite0,a6
move.l a6,usp
move.l clearSpritesPointer,a6
move.l drawSpriteCodeBuffersPointer,d2
move.w nr_sprites*2(a1),savedHax
move.w #-1,nr_sprites*2(a1)
; REPT nr_sprites
move.w (a1)+,d0 ;8 ; first x value
blt .exit
; add.w (a2)+,d0 ;8 ; second x value
move.l d0,a0 ;4 ; use x value as lookup
move.w (a0)+,d1 ;8 ; offset into screen
move.w (a0),d2 ;12 ; offset into drawing/clearing rout
add.w (a3)+,d1 ;8 ; add y1
; add.w (a4)+,d1 ;8 ; add y2
move.w d1,(a6)+ ;8 ; save total offset into screen
move.w d2,(a6)+ ;8 ; save offset for clearing rout
move.l d1,a0 ;4 ; use as screen
move.l d2,a5 ;4 ; use as drawing rout pointer
jmp (a5) ;8 ; do the drawing rout ; jmp (a5) = -8
;---> 88
; ENDR
.exit
rts
savedHax dc.l 0
clearSpritesImmediate
move.l clearSpritesPointer2,a6
move.l clearSpriteCodeBuffersPointer,d7
move.l screenpointer2,d1
moveq #0,d0
; REPT nr_sprites
move.w (a6)+,d1 ;8 ; get offset into screen
move.l d1,a0 ;4 ; use offset as screen
move.w (a6)+,d7 ;8 ; get clear rout
move.l d7,a5 ;4 ; use as clearing rout
jmp (a5) ;8 ; do the clearing rout ; 16*256 value does rts
; ENDR
; rts
drawSpriteCodeBuffers
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
clearSpriteCodeBuffers
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
dc.l 0
genClear macro
IF BITPLANES=1
move.w (a0)+,d0
beq .skip\@
move.w d2,d3
move.l d3,(a4)+
.skip\@
addq.w #8,d2 ; offset+8
ENDC
IF BITPLANES=2
move.w (a0)+,d0
beq .skipFirst\@
move.w (a0)+,d0
beq .skipSecond\@
.clearBoth\@
move.w d2,d0
move.l d0,(a4)+
jmp .skip\@
.skipSecond\@
move.w d2,d3
move.l d3,(a4)+
jmp .skip\@
.skipFirst\@
move.w (a0)+,d0
beq .skip\@
move.w d2,d3
add.w #2,d3
move.l d3,(a4)+
jmp .skip\@
.skip\@
addq.w #8,d2
ENDC
endm
genSpriteClearCode
lea sprite0,a0
lea clearSpriteCodeBuffers,a3
move.w #16-1,d5
move.l .clearCode(pc),d3
move.l .clearCode2(pc),d0
.doSprite
move.l (a3)+,a4
move.w #spriteHeight-1,d7
moveq #0,d1
.ol
move.l d1,d2
move.w #spriteWidth,d6
; REPT spriteWidth+1
.il
genClear
; ENDR
dbra d6,.il
add.w #160,d1 ; add 160 to y offset
dbra d7,.ol
lea .clearIter,a5
REPT 7
move.w (a5)+,(a4)+
ENDR
dbra d5,.doSprite
move.l (a3)+,a4
move.w .clearIterExit,(a4)+
rts
.clearCode
move.w d0,2(a0)
.clearCode2
move.l d0,2(a0)
.rts
rts
.clearIter
move.w (a6)+,d1 ;2 ;
move.l d1,a0 ;2
move.w (a6)+,d7 ;2
move.l d7,a5 ;2
jmp (a5) ;2
.clearIterExit
rts ;2 ;-> 14
genSprite macro
IF BITPLANES=1
move.w (a0)+,d0 ; value
beq .skip\@
move.l d0,(a2)+
move.w d2,(a2)+
.skip\@
addq.w #8,d2 ; offset+8
ENDC
IF BITPLANES=2
move.w (a0)+,d0 ; top word
beq .skipFirst\@
;--------------- top word filled
move.w (a0)+,d4 ; low word
beq .firstFilled\@
.bothFilled\@
move.w d3,(a2)+ ; operand
move.w d0,(a2)+ ; top word
move.w d4,(a2)+ ; bot word
move.w d2,(a2)+ ; word offset
jmp .skip\@
.firstFilled\@
move.l d0,(a2)+ ; operand .w + top word
move.w d2,(a2)+ ; word offset
jmp .skip\@
;--------------- end top word filled
.skipFirst\@
move.w (a0)+,d0
beq .skip\@
;--------------- lower word filled
move.l d0,(a2)+ ; operand .w + low word
move.w d2,(a2)+ ; offset
add.w #2,-2(a2) ; offset+2
jmp .skip\@
.skip\@
addq.w #8,d2
ENDC
endm
genSpriteCodeImmediate
lea sprite0,a0
lea drawSpriteCodeBuffers,a1
move.w #16-1,d5
move.l .drawCode(pc),d0 ; or.w #WORD,OFFSET(a0)
move.w .drawCode2(pc),d3 ; or.l #LONG,OFFSET(a0)
.doSprite
move.l (a1)+,a2 ; get target write buffer
move.w #spriteHeight-1,d7 ; hline
moveq #0,d1 ; offset-y
.ol
move.l d1,d2 ; offset-x
REPT spriteWidth+1
genSprite
ENDR
add.w #160,d1 ; add 160 to y offset
dbra d7,.ol
lea .drawIter,a5
REPT 18
move.w (a5)+,(a2)+
ENDR
dbra d5,.doSprite
move.l (a1)+,a2
move.l .drawIterExit,(a2)+
move.w .drawIterExit+2,(a2)+
rts
.drawCode
or.w #-1,2(a0)
.drawCode2
or.l #-1,2(a0)
.rts
rts
.drawIter
move.w (a1)+,d0 ;2
blt .drawIterExit ;2 ; to remove this: alter 2*nr_sprites(a1,a2,a3,a4) so that d2 becomes 16*256, for rts, and alter a0 with extra entry
; add.w (a2)+,d0 ;2
move.l d0,a0 ;2
move.w (a0)+,d1 ;2
move.w (a0),d2 ;2
add.w (a3)+,d1 ;2
; add.w (a4)+,d1 ;2
move.w d1,(a6)+ ;2
move.w d2,(a6)+ ;2
move.l d1,a0 ;2
move.l d2,a5 ;2
jmp (a5) ;2
.drawIterExit
move.w #16*spriteCodeSize,(a6)+
move.w #16*spriteCodeSize,(a6)+
rts ;2 ;-> 36/2
;;;;------------ GENERATED SPRITEROUT REGISTERS ------------------
;;;;------------ GENERATED SPRITEROUT REGISTERS ------------------
;;;;------------ GENERATED SPRITEROUT REGISTERS ------------------
;;;;------------ GENERATED SPRITEROUT REGISTERS ------------------
;;;;------------ GENERATED SPRITEROUT REGISTERS ------------------
; move.w #someval,d0 ;8
; move.w d0,x(a0) ;12
; move.w d0,x+160(a0) ;12
;
; move.w #someval,x(a0) ;16
; move.w #someval,x(a0) ;16
;
; so from 2 and up, we're good
; time to generate some code using registers, so what do we do?
; we should parse the sprite into a list of:
; word,times
; then we can sort this list
; then iterate through the list
; first 7 that are count > 1, will be assigned to
;
; sooo. lets structure stuff, each block of the sprite has 2 values;
; `mask' and `position'
; masks can be shared over multiple positions
; if a mask is -1, we can do move.w instead of or.w
; if mask is used = 2 times in sprite AND mask value is between -128 and 127 -> moveq
;
; so first, list of masks, and how many times
; sort this list
; then deal with each of them individually
;
; moveq #127,d0 ; -128 < x < 127
; move.b #0,$ffffc123
;
; in order to get unique list of masks and counts;
;
; maskList,a0
; check if d0 is in a0
; if not, add d0 to end of list, count 1
; if it is, increase count by 1 in list
;
; maskList - mask,count,offsets terminated with -1
; ; whats a useful datastructure
;
findPosition2 macro
move.l a1,a6
moveq #0,d1 ; index; if found, or pointer to store if found
.FPtest\@
move.l (a6)+,d7
beq .FPnotFound\@
.FPvalidValue\@
cmp.l d0,d7
beq .FPfound\@
addq.w #4,d1
jmp .FPtest\@
.FPnotFound\@ ; if not found, d7 != d0
.FPfound\@ ; if found, d7 = d0
endm
analyseSprite2Bitplanes
lea sprite0,a0
move.w #16-1,d7 ; 16 sprites to handle
.doSprite
pushd7