-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathengine.asm
2617 lines (2183 loc) · 65.4 KB
/
engine.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
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
;======================================================
;Licensed under the 3-Clause BSD License
;Copyright 2021, Martin 'enthusi' Wendt / PriorArt
;Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
;
;1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
;
;2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
;
;3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
;
;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
;TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
;CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
;PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
;LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;======================================================
ISV810
PUBALL
CAPSON
OFFBANKGROUP
bank0 group 0
FILE vbdefines.asm
;some handy 8bit world macros, taken from redsquare/Kresna!
push macro op1
add -4, sp
st.w op1, $0[sp]
endm
pop macro op1
ld.w $0[sp], op1
add 4, sp
endm
call macro op1
push r31
jal op1
pop r31
endm
ret macro
jmp [r31]
endm
movw macro op1, op2
movea #op1'lo, r0, op2
movhi #op1'hi1, op2, op2
endm
jump macro op1
movw op1, r30
jmp [r30]
endm
;-------------------------------------------------------------------------------
; RAM
;-------------------------------------------------------------------------------
;definitions for offsets for PRINT_LINE ;2 per char
R_current_channel def r4
R_chan_reg_offset def r29
R_chan_reg_base def r19
R_ram_base def r18
;player output of tracker data
SCREENOUTPUT def 1
;write registers to check their state
REGCHECK def 1
;can channels be muted?
MUTEABLE def 1
;disable for some EMU friendly fx
;such as no negative depths for text
;REALHW def 1
;offsets for pattern info display
dnot equ 6
dins equ dnot+2
dvol equ dnot+4
dpan equ dnot+6
o_S1INT equ $00 ;Channel 1 Sound Interval Specification Register
o_S1LRV equ $04 ;Channel 1 Level Setting Register
o_S1FQL equ $08 ;Channel 1 Frequency Setting Low Register
o_S1FQH equ $0C ;Channel 1 Frequency Setting High Register
o_S1EV0 equ $10 ;Channel 1 Envelope Specification Register 0
o_S1EV1 equ $14 ;Channel 1 Envelope Specification Register 1
o_S1RAM equ $18 ;Channel 1 Base Address Setting Register
org $05000000
begin_variables
PRINT_LINE equ BG_MAP+(64*2)*20
PRINT_STAT equ BG_MAP
;variables for proper i/o
keypad_state ds 2
keypad_pressed ds 2
keypad_previous ds 2
frame_counter ds 2
audio_enable ds 1
pattern_ptr ds 1
tune_toggle ds 1
cache_state ds 1
cursor_position ds 1
text_ptr ds 1
text_ptr_next ds 1
text_ptr_last ds 1
text_fade_ptr ds 2
EVEN 2
timer_value ds 2
EVEN 4
total_time ds 4
timer_count ds 4
;these should stay unaffected during 'audio init' so we can reset waves back
new_wave ds 1
new_wave_src ds 1
EVEN 4
audio_init_area_start
chn0
ds 4 ;pattern start
ds 4 ;instrument_ptr
ds 1 ;ptr
ds 1 ;vol
ds 1 ;base_note
ds 1 ;panning
ds 1 ;flag instrument running
ds 1 ;instrument frame
ds 1 ;instrument frame NEXT
ds 1 ;skip rows
;chn1-5
ds 16*5
;the offsets into the chn* channel structures in RAM
o_pattern_start equ 0
o_inst_ptr equ 4
o_ptr equ 8
o_vol equ 9
o_base_note equ 10
o_panning equ 11
o_inst_on equ 12
o_inst_now equ 13
o_inst_next equ 14
o_skip equ 15
main_pattern_speed ds 1
pattern_speed ds 1
cmd_flag ds 1
pan_flag ds 1
note ds 1
instrument ds 1
volume ds 1
trap ds 1
row ds 1
scroll_flag ds 1
break_flag ds 1
break_target ds 1
channel_on ds 6 ;only if you want to be able to MUTE it
audio_init_area_end
end_variables
;==========================================
org $07000000
begin_binary
Reset:
begin_init
; stack pointer
movw $05008000, sp ;could be placed at very end of RAM as well :)
; Reset PSW
ldsr r0, 5
sei
ldsr r0, 24
; early mute
movw VSU_SSTOP, r30
movea $1, r0, r29
st.h r29, $0[r30]
; Extended WRAM warmup
movw $FFFF, r6
_warmup
add -1, r6
bnz _warmup
;init memory - can't hurt though technically not required
movw VSU, r20
movw VSU_END,r21
_loop1
st.h r0, $0[r20]
add #2, r20
cmp r20,r21
bne _loop1
movw WRAM, r20
movw WRAM_END,r21
_loop2
st.h r0, $0[r20]
add #2, r20
cmp r20,r21
bne _loop2
movw VIP, r20
movw VIP_END,r21
_loop3
st.h r0, $0[r20]
add #2, r20
cmp r20,r21
bne _loop3
movw FRMCYC, r6
st.h r0, $0[r6] ;no frame delay
;nice short approach by GuyPerfect
; Configure the left and right column table in one go
movhi column_table_data'hi1, r0, r10
movea $3DC0, r0, r11 ; Start of column table
shl 4, r11
movea 510, r11, r12 ; End of column table
movea 128, r0, r13 ; Remaining bytes
; Write all 128 bytes as halfwords to the four appropriate destinations
_column_loop
in.b column_table_data'lo[r10], r14
st.h r14, 0[r11] ; Start of table, up
st.h r14, 512[r11]
add 1, r10 ; Breaks up the sequence of store instructions
st.h r14, [r12] ; End of table, down
st.h r14, 512[r12]
add 2, r11
add -2, r12
add -1, r13
bnz _column_loop
; Turn on the display
mov XP_XPEN | XP_XPRST, r29
movw XPCTRL, r30
st.h r29, [r30]
movw DP_SYNCE | DP_RE | DP_DISP, r29
movw DPCTRL, r30
st.h r29, [r30]
movw palette_data, r29
movw GPLT0, r28
mov 8, r26
_fill_palette:
ld.h [r29], r25
st.h r25, [r28]
add 2, r29
add 2, r28
add -2, r26
bnz _fill_palette
movw keypad_previous, r6
st.h r0, [r6]
movw WCR, r6;wait state
mov %11, r7
st.b r7, [r6]
;ack pending IRQs
movw INTPND, r6
movw INTCLR, r7
ld.h [r6], r8
st.h r8, [r7]
movw INTENB, r6
st.h r0, [r6] ;disable all VIP IRQs
cli
;==================================================
;set colors!
movw BRTA, r29
movea BRTA_DEFAULT, r0, r28
movea BRTB_DEFAULT, r0, r27
movea BRTC_DEFAULT, r0, r26
st.h r28, [r29]
st.h r27, $2[r29]
st.h r26, $4[r29]
;set up palettes including a simple fade
movw GPLT0, r10
movw (((1<<0)+(2<<2)+(3<<4))<<2),r11; %01010100,r11
st.h r11,0[r10]
movw (((0<<0)+(1<<2)+(2<<4))<<2),r11; %01010100,r11
st.h r11,2[r10]
movw (((3<<0)+(0<<2)+(1<<4))<<2),r11; %01010100,r11
st.h r11,4[r10]
movw (((2<<0)+(3<<2)+(0<<4))<<2),r11; %01010100,r11
st.h r11,6[r10]
;------------------------------------------
;set timer
aaa
;init timer value
movw timer_value, r6
movw $c7,r7 ;for mednafen
;if you use a 20us timer
;at the time of this code, mednafen was too buggy to use it
;movw $3e8,r7 ;in theory for real hardware,
;it's more like 3e5 given my column table
st.h r7,[r6]
movw TIMER_TLR, r30
movw timer_value, r29
in.b [r29],r29
st.b r29, [r30]
movw TIMER_THR, r30
movw (timer_value+1), r29
in.b [r29],r29
st.b r29, [r30]
;bit4 of TCR
;0 100 µs
;1 20 µs
movw TIMER_TCR, r30
movea %00001101, r0, r29 ;20 us
st.b r29, [r30]
;------------------------------------------
;set up PCM waves
; Disable all sound to avoid cracks
; and to allow writing to WAVE register
sei
movw VSU_SSTOP, r30
movea $1, r0, r29
st.h r29, [r30]
movw VSU_WAVE_0, r10
movw MY_WAVE_0, r6
movw (32*5), r7
_loop
in.b [r6], r8
st.b r8,[r10]
add 1, r6
add 4, r10
add -1, r7
bne _loop
;==================================================
;my init stuff
call setup_bitmap
;clear BG map
movw BG_MAP, r29
addi ((64*2)*32),r29,r28 ;how many words to be filled
movea 256,r0,r27
_filler
st.h r27, [r29]
add #2, r29
cmp r29, r28
bnz _filler
;------------------
draw_test_line
;shows the routine's usage per frame in this bar
movw $2101,r10
movw (BG_MAP+128*22),r11
movw 48,r12
_loopk
st.h r10,[r11]
add 2,r11
add -1, r12
bp _loopk
;------------------
;init which playlist position to start at!
movw pattern_ptr, r8
mov 0,r7
st.b r7, [r8]
movw chn0, r4
mov r0,r29
call init_player
ifdef SCREENOUTPUT
;write channel IDs in top
movw BG_MAP, r9
mov 1,r5
st.h r5, 8[r9]
add 1, r5
st.h r5, 24[r9]
add 1, r5
st.h r5, 40[r9]
add 1, r5
st.h r5, 56[r9]
add 1, r5
st.h r5, 72[r9]
add 1, r5
st.h r5, 88[r9]
endif
mov 1,r6
movw audio_enable, r5
st.b r6, [r5]
movw VSU_SSTOP, r6 ;probably not required
st.h r0, [r6]
cli ;dont start music before things are set
movw INTPND, r6
movw INTCLR, r7
ld.h [r6], r8
st.h r8, [r7]
movw $05000000, R_ram_base ;variables BASE
;init which tune to start with
st.b r0, tune_toggle'lo[R_ram_base]
mov 1,r7
st.b r7, cache_state'lo[R_ram_base] ;just in case you want to change this as user input
movw timer_count,r6
mov 10, r7
st.w r7,0[r6] ;reset timer count
movw total_time,r6
st.w r0,0[r6]
st.b r0, new_wave'lo[R_ram_base]
st.b r0, scroll_flag'lo[R_ram_base]
st.b r0, cmd_flag'lo[R_ram_base]
st.b r0, pan_flag'lo[R_ram_base]
st.b r0, break_flag'lo[R_ram_base]
st.b r0, break_target'lo[R_ram_base]
st.b r0,text_ptr'lo[R_ram_base]
st.h r0,text_fade_ptr'lo[R_ram_base]
st.b r0,text_ptr_next'lo[R_ram_base]
mov 2, r22 ;enable cache as default
ldsr r22, 24;CHCW
end_init
;-----------------------------------------------
mainloop:
_mainloop
;===============================================
;should use HALT instruction here but heard of emulation inconsistencies currenlty
_sync_loop:
movw XPSTTS, r20
ld.h $0[r20],r20
andi %1100, r20, r20
bne _sync_loop ;wait till drawing stopped!
;animate bg
movw (WORLD_TBL + 31*32),r9 ;parallax for world 31
movw frame_counter, r7
ld.h [r7], r7 ;frame counter to r7
shr 1,r7
andi 15,r7,r7 ;limit range
mov 15,r6
sub r7,r6
mov r6,r7
addi -16,r7,r7 ;static offset
st.h r7,6[r9]
shr 1,r7 ;dont scroll at 45 deg
st.h r7,2[r9]
;-----------------------------
;do we need to scroll?
in.b scroll_flag'lo[R_ram_base], r6
cmp r0,r6
be _no_scroll
call scroll_up
st.b r0,scroll_flag'lo[R_ram_base]
_no_scroll
;--------------------------------------
call write_text
;------------------------------------------------
call read_keypad_hw
call act_on_keys
in.b cursor_position'lo[R_ram_base], r6
shl 4,r6
movw BG_MAP, r7
movw 256,r8 ;erase pointer first
st.h r8, (10+16*0)[r7]
st.h r8, (10+16*1)[r7]
st.h r8, (10+16*2)[r7]
st.h r8, (10+16*3)[r7]
st.h r8, (10+16*4)[r7]
st.h r8, (10+16*5)[r7]
add r6,r7
movw 261,r6
;ori $1000,r6,r6 ;flip
st.h r6, 10[r7]
jump _mainloop
;===============================================
begin_timerirq
Timer_Interrupt:
sei
; of course this could be solved WAY more efficient without macros
; and with a single stackpointer addition and a series of offset writes
; it is simply more flexible for others to use like this
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r16
;push r17
push r18
push r19
push r20
push r21
;push r22
;push r23
;push r24
;push r25
;push r26
push r27
push r28
push r29
push r30
push r31
;this may come in handy for later users
;setup all registers with a certain pattern
;to see which ones are being used in the end
ifdef REGCHECK
movw $aa55aa55,r5
acheck_regs
mov r5,r4
mov r5,r5
mov r5,r6
mov r5,r7
mov r5,r8
mov r5,r9
mov r5,r10
mov r5,r11
mov r5,r12
mov r5,r13
mov r5,r14
mov r5,r15
mov r5,r16
;mov r5,r17
mov r5,r18
mov r5,r19
mov r5,r20
mov r5,r21
;mov r5,r22
;mov r5,r23
;mov r5,r24
;mov r5,r25
;mov r5,r26
mov r5,r27
mov r5,r28
mov r5,r29
mov r5,r30
mov r5,r31
;possibyl unused:
;free r17, r24, r25
;free r22, r23 (scrollup)
;r23,r24,r25,r26
endif
movw audio_enable, r5
in.b [r5],r5
cmp r5,r0
bne _play_audio
jump skip_audio
_play_audio
movw TIMER_TCR, r6
movea %00001100, r0, r7 ;disable + ack
st.b r7, [r6]
movea %00001101, r0, r7 ;re-enable
st.b r7, [r6]
beforecall
movw BRTA, r29
movea BRTB_DEFAULT, r0, r27
st.h r0, 2[r29]
;this should in fact be global to the whole player!
;global registers is what I would do for a rewrite from scratch ;)
movw $05000000, R_ram_base ;variables BASE
in.b cache_state'lo[R_ram_base], r6
mov r0, r16
cmp r6,r0
be _disable_cache
mov 2,r16 ;just enable
_disable_cache
ldsr r16, 24;CHCW
call audio_playframe
ldsr r0, 24;CHCW
movw BRTA, r29
movea BRTB_DEFAULT, r0, r27
st.h r27, 2[r29]
;=======================================
skip_audio
aftercall
;OLD behavior:
;ACK timer IRQ _AFTER_ audio_playframe
;to ensure the counter is no longer at 0
;in which case it would not ACK.
;alternatively: disable timer (+ack), then re-enable which we do now
movw TIMER_TLR, r6
in.b [r6], r6
movw TIMER_THR, r7
in.b [r7], r7
cmp r6,r0
bz _was_still_zero
shl 8,r7
add r7,r6 ;16bit timer in r6
;compute required time
movw timer_value,r7
in.h [r7],r7
sub r6,r7
_was_still_zero
;add time to total
movw total_time,r6
ld.w [r6],r8
add r7,r8
st.w r8, [r6]
;add time to total
movw timer_count,r6
in.b [r6],r7
add -1,r7
st.b r7,[r6]
bp _keep_adding
;optional, currently not used
movw 0, r7 ;AVERAGE OVER THIS MANY FRAMES
st.w r7,[r6] ;reset timer count
;divide for number
;shr 0,r8 ;AVERAGE OVER THIS MANY FRAMES
;mov r8,r7
;andi $ff, r7,r6 ;low
;st.h r6, 2[r9]
;reset counter
movw total_time,r6
st.w r0,[r6]
mov r8,r6
;also show a funny bar
;clear first
movw 90, r7
movw $0100, r9
movw (PRINT_STAT+128*27),r8
_clear_loop
st.h r9,[r8]
add 2, r8
add -1, r7
bne _clear_loop
;r6 is bar length = time
;cmp r0,r6
;bz _no_bar ;dont draw anything if value is still 0
mov 0,r9
movw $00ff, r7
movw (PRINT_STAT+128*27),r8
_bar_loop
st.h r9,[r8]
add 2, r8
add 1, r9
add -1, r6
bp _bar_loop
_no_bar
_keep_adding
ifdef SCREENOUTPUT
movw row, r6
in.b [r6], r7 ;row counter to r7
movw PRINT_LINE, r8
st.h r7, [r8]
endif
movw frame_counter, r6
ld.h [r6], r7 ;frame counter to r7
add 1, r7
st.h r7, [r6]
;place logo
CHAR_PA def 256 + 97
shr 3,r7
andi 7,r7,r7 ;r7 is frame counter
movw logo_palette, r8
add r7,r8
in.b [r8],r8
shl 14,r8
movea CHAR_PA,r0,r5
movw BG_MAP, r9
or r8,r5
st.h r5, 92[r9]
add 1,r5
st.h r5, 94[r9]
addi 98,r5,r5
st.h r5, (92+128)[r9]
add 1,r5
st.h r5, (94+128)[r9]
bcheck_regs
pop r31
pop r30
pop r29
pop r28
pop r27
;pop r26
;pop r25
;pop r24
;pop r23
;pop r22
pop r21
pop r20
pop r19
pop r18
;pop r17
pop r16
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r30
reti
end_timerirq
logo_palette
db 3,2,1,0,0,0,1,2
;---------------------------------------------------
;===========================================================
init_player:
movw $05000000, R_ram_base ;variables
;clear a couple of variables
;place those in registers?!
movea (audio_init_area_end - audio_init_area_start), r0, r6
movw audio_init_area_start, r5
_loop
st.b r0, [r5]
add #1, r5
add -1, r6
bne _loop
;---
;preset pattern speed
;overwritten by s3m tempo command if present
movw main_pattern_speed, r5
mov 6, r6
st.b r6, [r5]
movw pattern_speed, r7
st.b r6, [r7]
call audio_set_pattern
;preset panning
movw chn0,r6
mov 3,r7
st.b r7, (16*0+o_panning)[r6]
st.b r7, (16*1+o_panning)[r6]
st.b r7, (16*2+o_panning)[r6]
st.b r7, (16*3+o_panning)[r6]
st.b r7, (16*4+o_panning)[r6]
st.b r7, (16*5+o_panning)[r6]
mov 1,r7
st.b r7 (channel_on'lo + 0)[R_ram_base]
st.b r7 (channel_on'lo + 1)[R_ram_base]
st.b r7 (channel_on'lo + 2)[R_ram_base]
st.b r7 (channel_on'lo + 3)[R_ram_base]
st.b r7 (channel_on'lo + 4)[R_ram_base]
st.b r7 (channel_on'lo + 5)[R_ram_base]
ret
;===========================================================
set_new_waves
;we set a new wave
;which set do we use?
in.b new_wave_src'lo[R_ram_base], r5
shl 3,r5; *8 size of set
movw WAVESET_TABLE, r14
add r5,r14
movw VSU_WAVE_0, r5
movw MY_WAVE_0, r29
;stop all sounds to be able to write to wave tables
movw VSU_SSTOP, r8
movea $1, r0, r9
st.h r9, [r8]
movw 5, r9 ;loops
_loop
;read in source for every wave
ld.b [r14],r6
add 1,r6
bnz _we_exchange_this_wave
jump _skip_this_wave
_we_exchange_this_wave
add -1, r6
; set source pointer
shl 5,r6 ;size of wave
add r29,r6 ;absolute pointer
;as fast as we think we can here!
in.b $00[r6], r8 ;src
st.b r8,$00[r5] ;dst
in.b $01[r6], r8 ;src
st.b r8,$04[r5] ;dst
in.b $02[r6], r8 ;src
st.b r8,$08[r5] ;dst
in.b $03[r6], r8 ;src
st.b r8,$0c[r5] ;dst
in.b $04[r6], r8 ;src
st.b r8,$10[r5] ;dst
in.b $05[r6], r8 ;src
st.b r8,$14[r5] ;dst
in.b $06[r6], r8 ;src
st.b r8,$18[r5] ;dst
in.b $07[r6], r8 ;src
st.b r8,$1c[r5] ;dst
in.b $08[r6], r8 ;src
st.b r8,$20[r5] ;dst
in.b $09[r6], r8 ;src
st.b r8,$24[r5] ;dst
in.b $0a[r6], r8 ;src
st.b r8,$28[r5] ;dst
in.b $0b[r6], r8 ;src
st.b r8,$2c[r5] ;dst
in.b $0c[r6], r8 ;src
st.b r8,$30[r5] ;dst
in.b $0d[r6], r8 ;src
st.b r8,$34[r5] ;dst
in.b $0e[r6], r8 ;src
st.b r8,$38[r5] ;dst
in.b $0f[r6], r8 ;src
st.b r8,$3c[r5] ;dst
in.b $10[r6], r8 ;src
st.b r8,$40[r5] ;dst
in.b $11[r6], r8 ;src
st.b r8,$44[r5] ;dst
in.b $12[r6], r8 ;src
st.b r8,$48[r5] ;dst
in.b $13[r6], r8 ;src
st.b r8,$4c[r5] ;dst
in.b $14[r6], r8 ;src
st.b r8,$50[r5] ;dst
in.b $15[r6], r8 ;src
st.b r8,$54[r5] ;dst
in.b $16[r6], r8 ;src
st.b r8,$58[r5] ;dst
in.b $17[r6], r8 ;src
st.b r8,$5c[r5] ;dst
in.b $18[r6], r8 ;src
st.b r8,$60[r5] ;dst
in.b $19[r6], r8 ;src
st.b r8,$64[r5] ;dst
in.b $1a[r6], r8 ;src
st.b r8,$68[r5] ;dst
in.b $1b[r6], r8 ;src
st.b r8,$6c[r5] ;dst
in.b $1c[r6], r8 ;src
st.b r8,$70[r5] ;dst
in.b $1d[r6], r8 ;src
st.b r8,$74[r5] ;dst
in.b $1e[r6], r8 ;src
st.b r8,$78[r5] ;dst
in.b $1f[r6], r8 ;src
st.b r8,$7c[r5] ;dst
_skip_this_wave
addi $80, r5, r5 ;next wave ram
add 1, r14 ;next entry in set
add -1, r9
bz _we_are_done
jump _loop
_we_are_done
;new wave implemented, clear flag
st.b r0,new_wave'lo[R_ram_base]
ret
;---------------------------------------------
begin_player1
audio_playframe
movw pattern_speed, r5
in.b [r5], r6
add -1, r6
st.b r6, [r5]
bne _cont
mov 1,r6
st.b r6,scroll_flag'lo[R_ram_base]
;reset pattern speed
movw main_pattern_speed, r6
in.b [r6], r6
st.b r6, [r5]
;---------------------------
;2021 exhange wave table on request BEFORE play
in.b new_wave'lo[R_ram_base], r5
cmp r0,r5
bz _no_new_wave
call set_new_waves
_no_new_wave
;---------------------------
call audio_read_pattern_data
_cont
movw chn0, R_current_channel ;init to chn0
mov r0,r29 ;init register pointer to 0-offset from HW channel 0
;r18 is RAM 0 pointer
movw VSU_S1INT, R_chan_reg_base ;HW reg BASE
_instrument_play_loop
mov r29, r14
shr 4,r14
;play all instrument channels now
call play_instrument
addi 16,R_current_channel,R_current_channel
addi 64, r29,r29
addi 64, R_chan_reg_base,R_chan_reg_base
movw 64*6,r7
cmp r7,r29
bne _instrument_play_loop
_all_done
;reset channel to 0
movw chn0, R_current_channel ;init to chn0
mov r0,r29 ;init register pointer to 0-offset from HW channel 0
mov r0,r14
movw VSU_S1INT, R_chan_reg_base ;HW reg BASE
ret
;--------------------------------------------------------------