-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhively_player.S
1814 lines (1580 loc) · 70 KB
/
hively_player.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
include "jaguar.inc"
.dsp
;;; Compiletime configuration
READ_PAD equ 1
UPDATE_SONG_POS equ 1
DISPLAY_TIME equ 0
;;; ----------------------------------------
;;; parameters
DSP_song equ $f1d000-4
DSP_master_volume equ $f1d000-8
DSP_filterPreCalcTable equ $f1d000-12
DSP_panning_table equ $f1d000-16
;;; 0 = running
;;; 1 = i2S stopping
;;; 2 = timer1 stopping / I2S stopped
;;; 3 = main stopping
;;; 4 = DSP stopped
;;; 5 = pause playing
;;; 6 = (re)start new song
DSP_flag_replay_ON_OFF equ $f1d000-20
; xxxxxxCx xxBx2580 147*oxAP 369#RLDU
DSP_pad2 equ $f1d000-24 ; read by 68k/GPU
DSP_pad1 equ $f1d000-28 ; read by 68k/GPU
DSP_real_sample_rate equ $f1d000-32 ; read by 68k/GPU
DSP_stream_pos equ $f1d000-36 ; read by 68k/GPU
DSP_sample_ptr equ $f1d000-40
DSP_sample_size equ $f1d000-44
DSP_sample_fade equ $f1d000-48 ; 0 => left, $100 => right (TBD)
DSP_sample_volume equ $f1d000-52 ; 0 => silent, $100 full (TBD)
;;; ----------------------------------------
;;; Configuration (constant)
max_NB_channels equ 10
max_RM_channels equ 4 ; max. RM buffers in DSP RAM
RM_channels equ (1<<0)|(1<<1)|(1<<2)|(1<<9)
RM_buffers_main equ $200 ; start of RM buffers in main
DSP_Audio_frequence equ 32000
; mini freq = 16000 // freq amiga = 32000 // 32000/16000=2 => 2 bits // 128=>7 bits // 9 bits + signe : entiere = 10 bits
AHX_nb_bits_virgule_increment_period .equ 16
SCLK_PAL equ ((26593900*4/DSP_Audio_frequence+128)>>8)-1
DSP_frequence_de_replay_PAL equ 26593900/(SCLK_PAL+1)/64
A2J_RATIO_PAL equ ((3546895<<9)/DSP_frequence_de_replay_PAL)<<(AHX_nb_bits_virgule_increment_period-9)
SCLK_NTSC equ ((26590906*4/DSP_Audio_frequence+128)>>8)-1
DSP_frequence_de_replay_NTSC equ 26590906/(SCLK_NTSC+1)/64
A2J_RATIO_NTSC equ ((3546895<<9)/DSP_frequence_de_replay_NTSC)<<(AHX_nb_bits_virgule_increment_period-9)
;;; ----------------------------------------
;;; Song header
song_NB_channel equ 0
song_speed_multiplier equ 1
song_panningLeft equ 2
song_panningRight equ 3
song_rm_channels equ 4
song_restart_word equ 8
song_restart_bit equ 12
song_length equ 16
song_header_size equ 20
;;; ----------------------------------------
; HIVELY_datas_channels
DSP_index_vc_AudioVolume equ 0
DSP_index_vc_Waveform equ 1
DSP_index_vc_SquarePos equ 2
DSP_index_vc_WaveLength equ 3
DSP_index_vc_FilterPos equ 4
DSP_index_vc_AudioPeriod equ 5
DSP_index_vc_channel_on_off equ 6
DSP_index_vc_RingWaveform equ 7
DSP_index_vc_RingAudioPeriod equ 8
DSP_index_vc__total equ 9
; #AHX_enregistrements_N_voies
index_AHX_enregistrements_N_voies__I2S_offset .equ 0
index_AHX_enregistrements_N_voies__I2S_increment .equ 1
index_AHX_enregistrements_N_voies__I2S_mask_bouclage .equ 2
index_AHX_enregistrements_N_voies__I2S_buffer .equ 3
index_AHX_enregistrements_N_voies__I2S_panning_left .equ 4
index_AHX_enregistrements_N_voies__I2S_panning_right .equ 5
index_AHX_enregistrements_N_voies__I2S_offset__RM .equ 6
index_AHX_enregistrements_N_voies__I2S_increment__RM .equ 7
index_AHX_enregistrements_N_voies__I2S_buffer__RM .equ 8
AHX_enregistrements_N_voies__I2S_taille_totale .equ 9
;------------------------------------------------------------
I2S_tmp_1 .equr R0
I2S_tmp_2 .equr R1
; voie G
I2S_offset_entier_et_virgule__voie_G .equr R2
I2S_increment_entier_et_virgule__voie_G .equr R3
I2S_mask_bouclage_voie_G .equr R4
I2S_adresse_buffer_sample__voie_G .equr R5
; voie G
I2S_offset_entier_et_virgule__voie_D .equr R6
I2S_increment_entier_et_virgule__voie_D .equr R7
I2S_mask_bouclage_voie_D .equr R8
I2S_adresse_buffer_sample__voie_D .equr R9
I2S_adresse_code_boucle .equr R10
I2S_sample_gauche .equr R11
I2S_sample_droite .equr R12
I2S_mask_elimination_bits_adresse_pour_lecture_word .equr R13
I2S_pointeur_datas_voie_en_cours_G .equr R14
I2S_pointeur_datas_voie_en_cours_D .equr R15
I2S_compteur_nb_voie .equr R16
I2S_increment_taille_AHX_enregistrements_N_voies .equr R17
I2S_pointeur_DAC_voie_G .equr R18 ; init par moveta
I2S_pointeur_DAC_voie_D .equr R19 ; init par moveta
; R20
I2S_tmp_3 .equr R21
I2S_tmp_4 .equr R22
I2S_tmp_sample_G .equr R23
I2S_tmp_sample_D .equr R24
I2S_routine_actuelle .equr R28
I2S_save_flags .equr R29
;R30=used
;R31=stack
.org D_RAM
movei #DSP_routine_init,r0
jump (r0)
nop
.align 16
DSP_ISP:
;--------------------------------------------
; I2S interrupt
movei #D_FLAGS,r30
movei #DSP_NB_channels,I2S_compteur_nb_voie
jump (I2S_routine_actuelle)
load (r30),I2S_save_flags ; read flags
;--------------------------------------------
; Timer 1 interrupt
movei #D_FLAGS,r30
movei #DSP_flag_replay_ON_OFF,I2S_tmp_1
load (r30),r29 ; read flags
load (I2S_tmp_1),I2S_tmp_2
moveq #3,I2S_tmp_3
cmpq #2,I2S_tmp_2 ; stop timer 1?
moveta I2S_tmp_3,r21 ; set flag for main loop
jr ne,DSP_LSP_routine_interruption_Timer1__pas_de_sortie
bclr #3,R29 ; clear IMASK
bclr #6,R29 ; clear Timer 1 Interrupt Enable Bit
store I2S_tmp_3,(I2S_tmp_1)
DSP_LSP_routine_interruption_Timer1__pas_de_sortie:
load (r31),I2S_tmp_3 ; return address
bset #11,R29 ; clear latch 1 = timer 1
addqt #2,I2S_tmp_3 ; next instruction
addq #4,r31 ; pop from stack
jump (I2S_tmp_3) ; return
store R29,(R30) ; restore flags
;;; --------------------------------------------------
; I2S:
; version sans adaptation du volume, avec SAT
I2S_N_voies:
load (I2S_compteur_nb_voie),I2S_compteur_nb_voie
shrq #1,I2S_compteur_nb_voie
movei #AHX_enregistrements_N_voies,I2S_pointeur_datas_voie_en_cours_G
moveq #AHX_enregistrements_N_voies__I2S_taille_totale,I2S_increment_taille_AHX_enregistrements_N_voies
shlq #2,I2S_increment_taille_AHX_enregistrements_N_voies
move I2S_pointeur_datas_voie_en_cours_G,I2S_pointeur_datas_voie_en_cours_D
moveq #%00000010,I2S_mask_elimination_bits_adresse_pour_lecture_word
add I2S_increment_taille_AHX_enregistrements_N_voies,I2S_pointeur_datas_voie_en_cours_D
moveq #0,I2S_sample_gauche
add I2S_increment_taille_AHX_enregistrements_N_voies,I2S_increment_taille_AHX_enregistrements_N_voies
moveq #0,I2S_sample_droite
; offset 16.16
; increment 16.16
; mask bouclage
; adresse buffer sample
move pc,I2S_adresse_code_boucle
I2S_N_voies__boucle_voie:
load (I2S_pointeur_datas_voie_en_cours_G), I2S_offset_entier_et_virgule__voie_G
load (I2S_pointeur_datas_voie_en_cours_D), I2S_offset_entier_et_virgule__voie_D
load (I2S_pointeur_datas_voie_en_cours_G+index_AHX_enregistrements_N_voies__I2S_increment), I2S_increment_entier_et_virgule__voie_G
load (I2S_pointeur_datas_voie_en_cours_D+index_AHX_enregistrements_N_voies__I2S_increment), I2S_increment_entier_et_virgule__voie_D
add I2S_increment_entier_et_virgule__voie_G,I2S_offset_entier_et_virgule__voie_G
load (I2S_pointeur_datas_voie_en_cours_G+index_AHX_enregistrements_N_voies__I2S_mask_bouclage), I2S_mask_bouclage_voie_G
add I2S_increment_entier_et_virgule__voie_D,I2S_offset_entier_et_virgule__voie_D
load (I2S_pointeur_datas_voie_en_cours_D+index_AHX_enregistrements_N_voies__I2S_mask_bouclage), I2S_mask_bouclage_voie_D
load (I2S_pointeur_datas_voie_en_cours_G+index_AHX_enregistrements_N_voies__I2S_buffer), I2S_adresse_buffer_sample__voie_G
load (I2S_pointeur_datas_voie_en_cours_D+index_AHX_enregistrements_N_voies__I2S_buffer), I2S_adresse_buffer_sample__voie_D
store I2S_offset_entier_et_virgule__voie_G,(I2S_pointeur_datas_voie_en_cours_G)
store I2S_offset_entier_et_virgule__voie_D,(I2S_pointeur_datas_voie_en_cours_D)
and I2S_mask_bouclage_voie_G,I2S_offset_entier_et_virgule__voie_G ; mask a virgule sur offset à virgule
and I2S_mask_bouclage_voie_D,I2S_offset_entier_et_virgule__voie_D
sharq #AHX_nb_bits_virgule_increment_period-1,I2S_offset_entier_et_virgule__voie_G ; -2 pour *4 l'offset est multiplié par 4 car en 2 fois .W
sharq #AHX_nb_bits_virgule_increment_period-1,I2S_offset_entier_et_virgule__voie_D ; -2 pour *4
add I2S_adresse_buffer_sample__voie_G,I2S_offset_entier_et_virgule__voie_G
add I2S_adresse_buffer_sample__voie_D,I2S_offset_entier_et_virgule__voie_D
load (I2S_offset_entier_et_virgule__voie_G),I2S_tmp_sample_G ; lit le sample en .L, prémultiplié par le volume // l'arrondi à un multiple de 4 n'est pas important car lecture dans RAM DSP locale, donc lit la meme chose sur 0/1/2 ou 3
load (I2S_offset_entier_et_virgule__voie_D),I2S_tmp_sample_D
and I2S_mask_elimination_bits_adresse_pour_lecture_word,I2S_offset_entier_et_virgule__voie_G
and I2S_mask_elimination_bits_adresse_pour_lecture_word,I2S_offset_entier_et_virgule__voie_D
shlq #3,I2S_offset_entier_et_virgule__voie_G
shlq #3,I2S_offset_entier_et_virgule__voie_D
sha I2S_offset_entier_et_virgule__voie_G,I2S_tmp_sample_G
sha I2S_offset_entier_et_virgule__voie_D,I2S_tmp_sample_D
; si on a 2 words sur 1 .L
; l'adresse doit etre multipliée par 2, plus par 4
; and avec %00010000 : on elimine le reste de virgule, et on ne garde que 0 ou 1 sur l'adresse *2
; sharq #4 : de 0 ou 16 => 0 ou 1
; il faut aboutir a un sharq 0 ou 16
; ====> pas de sharq
; juste sharq adresse sur sample
; RM à gérer ici
; voie G
; load l'increment et si =0 => pas de RM
load (I2S_pointeur_datas_voie_en_cours_G+index_AHX_enregistrements_N_voies__I2S_increment__RM), I2S_increment_entier_et_virgule__voie_G
load (I2S_pointeur_datas_voie_en_cours_D+index_AHX_enregistrements_N_voies__I2S_increment__RM), I2S_increment_entier_et_virgule__voie_D
cmpq #0,I2S_increment_entier_et_virgule__voie_G
jr eq,I2S_N_voies__pas_de_RM__voie_G
; RM en voie G
load (I2S_pointeur_datas_voie_en_cours_G+index_AHX_enregistrements_N_voies__I2S_offset__RM), I2S_offset_entier_et_virgule__voie_G
load (I2S_pointeur_datas_voie_en_cours_G+index_AHX_enregistrements_N_voies__I2S_buffer__RM), I2S_adresse_buffer_sample__voie_G
add I2S_increment_entier_et_virgule__voie_G,I2S_offset_entier_et_virgule__voie_G
store I2S_offset_entier_et_virgule__voie_G,(I2S_pointeur_datas_voie_en_cours_G+index_AHX_enregistrements_N_voies__I2S_offset__RM)
and I2S_mask_bouclage_voie_G,I2S_offset_entier_et_virgule__voie_G
sharq #AHX_nb_bits_virgule_increment_period-2,I2S_offset_entier_et_virgule__voie_G ; -2 pour *4
add I2S_adresse_buffer_sample__voie_G,I2S_offset_entier_et_virgule__voie_G
load (I2S_offset_entier_et_virgule__voie_G),I2S_increment_entier_et_virgule__voie_G ; lit le sample en .L, du RM
imult I2S_increment_entier_et_virgule__voie_G,I2S_tmp_sample_G
sharq #7,I2S_tmp_sample_G
I2S_N_voies__pas_de_RM__voie_G:
; voie D
; load l'increment et si =0 => pas de RM
cmpq #0,I2S_increment_entier_et_virgule__voie_D
jr eq,I2S_N_voies__pas_de_RM__voie_D
; RM en voie G
load (I2S_pointeur_datas_voie_en_cours_D+index_AHX_enregistrements_N_voies__I2S_offset__RM), I2S_offset_entier_et_virgule__voie_D
load (I2S_pointeur_datas_voie_en_cours_D+index_AHX_enregistrements_N_voies__I2S_buffer__RM), I2S_adresse_buffer_sample__voie_D
add I2S_increment_entier_et_virgule__voie_D,I2S_offset_entier_et_virgule__voie_D
store I2S_offset_entier_et_virgule__voie_D,(I2S_pointeur_datas_voie_en_cours_D+index_AHX_enregistrements_N_voies__I2S_offset__RM)
and I2S_mask_bouclage_voie_D,I2S_offset_entier_et_virgule__voie_D
sharq #AHX_nb_bits_virgule_increment_period-2,I2S_offset_entier_et_virgule__voie_D ; -2 pour *4
add I2S_adresse_buffer_sample__voie_D,I2S_offset_entier_et_virgule__voie_D
load (I2S_offset_entier_et_virgule__voie_D),I2S_increment_entier_et_virgule__voie_D ; lit le sample en .L, du RM
imult I2S_increment_entier_et_virgule__voie_D,I2S_tmp_sample_D
sharq #7,I2S_tmp_sample_D
I2S_N_voies__pas_de_RM__voie_D:
; stereo panning
load (I2S_pointeur_datas_voie_en_cours_G+index_AHX_enregistrements_N_voies__I2S_panning_left),I2S_tmp_1 ; voie 1 / panning left
load (I2S_pointeur_datas_voie_en_cours_D+index_AHX_enregistrements_N_voies__I2S_panning_left),I2S_tmp_3 ; voie 2 / panning left
load (I2S_pointeur_datas_voie_en_cours_G+index_AHX_enregistrements_N_voies__I2S_panning_right),I2S_tmp_2 ; voie 1 / panning right
load (I2S_pointeur_datas_voie_en_cours_D+index_AHX_enregistrements_N_voies__I2S_panning_right),I2S_tmp_4 ; voie 2 / panning right
; sample * panning
; sample = 14 bits : 8+6(volume)
; panning = 8 bits
; 14+8=22
; 22-7=15
; 15+15 => 16
imultn I2S_tmp_sample_G,I2S_tmp_1
imacn I2S_tmp_sample_D,I2S_tmp_3
resmac I2S_tmp_1
imultn I2S_tmp_sample_G,I2S_tmp_2
imacn I2S_tmp_sample_D,I2S_tmp_4
resmac I2S_tmp_2
sharq #7,I2S_tmp_1
sharq #7,I2S_tmp_2
add I2S_tmp_1,I2S_sample_gauche
add I2S_tmp_2,I2S_sample_droite
add I2S_increment_taille_AHX_enregistrements_N_voies,I2S_pointeur_datas_voie_en_cours_G
subq #1,I2S_compteur_nb_voie
jump ne,(I2S_adresse_code_boucle)
add I2S_increment_taille_AHX_enregistrements_N_voies,I2S_pointeur_datas_voie_en_cours_D
continue_I2S:
movei #DSP_sample_ptr,I2S_tmp_1
sat16s I2S_sample_gauche
load (I2S_tmp_1),I2S_tmp_2
sat16s I2S_sample_droite
subqt #4,I2S_tmp_1
cmpq #0,I2S_tmp_2
movei #no_sample,I2S_tmp_4
move I2S_tmp_2,I2S_tmp_3
jump eq,(I2S_tmp_4)
shrq #1,I2S_tmp_3
movei #DSP_sample_volume,I2S_tmp_4
load (I2S_tmp_4),I2S_tmp_4
addqt #1,I2S_tmp_2
loadb (I2S_tmp_3),I2S_tmp_3
shlq #24,I2S_tmp_3
sharq #24,I2S_tmp_3
imult I2S_tmp_4,I2S_tmp_3
sat16s I2S_tmp_3
//-> sharq #8,I2S_tmp_3
add I2S_tmp_3,I2S_sample_gauche
load (I2S_tmp_1),I2S_tmp_4
add I2S_tmp_3,I2S_sample_droite
subq #1,I2S_tmp_4
store I2S_tmp_4,(I2S_tmp_1)
jr ne,no_sample0
addqt #4,I2S_tmp_1
moveq #0,I2S_tmp_2
no_sample0:
store I2S_tmp_2,(I2S_tmp_1)
no_sample:
sat16s I2S_sample_gauche
sat16s I2S_sample_droite
movei #DSP_master_volume,I2S_tmp_1
load (I2S_tmp_1),I2S_tmp_1
imult I2S_tmp_1,I2S_sample_gauche
imult I2S_tmp_1,I2S_sample_droite
sharq #8,I2S_sample_gauche
sharq #8,I2S_sample_droite
sat16s I2S_sample_gauche
sat16s I2S_sample_droite
store I2S_sample_gauche,(I2S_pointeur_DAC_voie_G)
store I2S_sample_droite,(I2S_pointeur_DAC_voie_D)
; return from interrupt I2S
load (r31),I2S_tmp_1 ; return address
bclr #3,I2S_save_flags ; clear IMASK
addqt #2,I2S_tmp_1 ; next instruction
bset #10,I2S_save_flags ; clear latch 1 = I2S
addq #4,r31 ; pop from stack
jump (I2S_tmp_1) ; return
store I2S_save_flags,(R30) ; restore flags
;;; ----------------------------------------
;;; -- I2S only for SFX, no song
;;; ----------------------------------------
empty_i2s:
movei #continue_I2S,I2S_tmp_1
moveq #0,I2S_sample_gauche
jump (I2S_tmp_1)
moveq #0,I2S_sample_droite
;------------------------------------------
;------------------------------------------
; ------------- main DSP ------------------
;------------------------------------------
;------------------------------------------
song_data_ptr equr r29
multiplier equr r28
panningDftLeft equr r27
panningDftRight equr r26
panningTableL equr r25
panningTableR equr r24
nextVoice equr r23
rm_mask equr r22
local_data equr r15
voiceTable equr r14
;; local data indexes
streamingbits_index equ 0
streamingbits_cur_index equ 1
streamingbits_end_index equ 2
NB_channel_index equ 3
DSP_routine_init:
movei #D_FLAGS,r0
moveq #0,r1
bset #14,r1
store r1,(r0) ; switch to bank 1
nop
nop
;;; ----------------------------------------
;;; Setup timer1 and I2C
movei #A2J_RATIO_PAL,r12
movei #SCLK_PAL,r11
movei #DSP_frequence_de_replay_PAL,r10
movei #JOYBUTS,r0
loadw (r0),r3
btst #4,r3
jr eq,initPAL
nop
movei #A2J_RATIO_NTSC,r12
movei #SCLK_NTSC,r11
movei #DSP_frequence_de_replay_NTSC,r10
initPAL:
movei #DSP_real_sample_rate,R2
store R10,(R2)
movei #DSP_ratio_Amiga_Jaguar__a_virgule_9_bits,R2
store R12,(R2)
; moveta, constantes I2S
movei #L_I2S,R0
moveta R0,I2S_pointeur_DAC_voie_D
addq #4,r0
moveta R0,I2S_pointeur_DAC_voie_G
//-> movei #I2S_N_voies,R0
movei #empty_i2s,r0
moveta R0,I2S_routine_actuelle
; init I2S
movei #SCLK,r0
moveq #%001101,r13 ; SMODE bascule sur RISING
store r11,(r0) ; SCLK
addq #4,r0
store r13,(r0) ; SMODE
; assume run from bank 1
movei #DSP_ISP,r31 ; init isp
moveta r31,r31 ; ISP (bank 0)
restart_with_new_song:
.if UPDATE_SONG_POS = 1
moveq #0,r0
movei #DSP_stream_pos,r1
store r0,(r1)
.endif
movei #DSP_song,song_data_ptr
movei #DSP_localData,local_data
load (song_data_ptr),song_data_ptr
loadb (song_data_ptr),r0 ;
store r0,(local_data+NB_channel_index)
addq #1,song_data_ptr
loadb (song_data_ptr),multiplier
addq #1,song_data_ptr
loadb (song_data_ptr),panningDftLeft
addq #1,song_data_ptr
loadb (song_data_ptr),panningDftRight
addq #1,song_data_ptr
load (song_data_ptr),rm_mask
addq #4,song_data_ptr
addq #8,song_data_ptr ; skip restart_word and bit
load (song_data_ptr),r0 ; length
addq #4,song_data_ptr
store song_data_ptr,(local_data)
store song_data_ptr,(local_data+streamingbits_cur_index)
add r0,song_data_ptr
store song_data_ptr,(local_data+streamingbits_end_index)
; gauche : 1 4 5 8 9 12 13 16
; droite : 2 3 6 7 10 11 14 15
initPanning:
movei #DSP_panning_table,panningTableL
moveq #0,panningTableR
load (panningTableL),panningTableL
bset #8,panningTableR
add panningTableL,panningTableR
movei #AHX_enregistrements_N_voies,voiceTable
moveq #AHX_enregistrements_N_voies__I2S_taille_totale,nextVoice
shlq #2,nextVoice
moveta voiceTable,voiceTable
moveta nextVoice,nextVoice
move panningDftLeft,r0
move panningDftLeft,r2
add panningTableL,r0
add panningTableR,r2
loadb (r0),r0
loadb (r2),r2
move panningDftRight,r1
move panningDftRight,r3
add panningTableL,r1
add panningTableR,r3
loadb (r1),r1
loadb (r3),r3
moveq #2,r4
initPanningLoop:
;;; #1
store r0,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_left)
store r2,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_right)
add nextVoice,voiceTable
;;; 2
store r1,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_left)
store r3,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_right)
add nextVoice,voiceTable
;;; 3
store r1,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_left)
store r3,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_right)
add nextVoice,voiceTable
;;; #4
store r0,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_left)
subq #1,r4
store r2,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_right)
jr ne,initPanningLoop
add nextVoice,voiceTable
;;; #9
store r0,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_left)
store r2,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_right)
add nextVoice,voiceTable
;;; 10
store r1,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_left)
store r3,(voiceTable+index_AHX_enregistrements_N_voies__I2S_panning_right)
//-> add nextVoice,voiceTable
;;; ----------------------------------------
;;; setup RM buffers
rm_buffer_int equr r27
rm_buffer_ext equr r26
buffer_offset equr r25
rm_channel_cnt equr r24
//->nextVoice equr r23
//->rm_mask equr r22
channel_cnt equr r21
movefa voiceTable,voiceTable
movefa nextVoice,nextVoice
movei #RM_buffers_main,rm_buffer_ext
movei #RM_buffers,rm_buffer_int
moveq #0,buffer_offset
bset #7+2,buffer_offset
moveq #max_RM_channels,rm_channel_cnt
moveq #max_NB_channels,channel_cnt
rm_init:
shrq #1,rm_mask
move rm_buffer_ext,r0
jr cc,rm_ext
nop
move rm_buffer_int,r0
subq #1,rm_channel_cnt
jr ne,rm_set
add buffer_offset,rm_buffer_int
jr rm_set
moveq #0,rm_mask ; all internal buffers use, swith to ext.
rm_ext:
move rm_buffer_ext,r0
add buffer_offset,rm_buffer_ext
rm_set:
subq #1,channel_cnt
store r0,(voiceTable+index_AHX_enregistrements_N_voies__I2S_buffer__RM)
jr ne,rm_init
add nextVoice,voiceTable
; init Timer 1 = 50 HZ
movei #3643*2,R13 ; valeur pour 50 Hz (original 3643)
div multiplier,R13 ; divise pour avoir la bonne vitesse de replay
subq #1,R13 ; -1 pour parametrage du timer 1
; 26593900 / 50 = 531 878 => 2 × 73 × 3643 => 146*3643
movei #JPIT1,r10
movei #(146/2-1)*65536,r12 ; Timer 1 Pre-scaler
or R13,R12
store r12,(r10) ; JPIT1 & JPIT2
; enable interrupts
movei #D_FLAGS,r24
movei #D_I2SENA|D_TIM1ENA|REGPAGE,r29 ; I2S+Timer 1
store r29,(r24) ; demarre les timers
;------------------------------------------------------
;
; boucle centrale
;
;------------------------------------------------------
; ------------------------------
; decode stream AHX version bits
;HIVELY_datas_channels:
; .rept NB_channels
; dc.l 0 ; vc_AudioVolume
; dc.l 0 ; vc_Waveform
; dc.l 0 ; vc_SquarePos
; dc.l 0 ; vc_WaveLength
; dc.l 0 ; vc_FilterPos
; dc.l 0 ; vc_AudioPeriod
; ; Ring Modulation : vc_Waveform+vc_WaveLength+vc_AudioPeriod
; .endr
DSP_decode_bits__nb_bits_a_lire .equr R0
DSP_decode_bits__bits_resultat .equr R1
DSP_decode_bits__tmp0 .equr R2
DSP_decode_bits__tmp1 .equr R3
DSP_decode_bits__compteur_voies .equr R4
DSP_decode_bits__flags_datas .equr R5
; .equr R6
DSP_decode_bits__taille_d_un_record_datas_channel .equr R7
DSP_decode_bits__tmp2 .equr R8
DSP_decode_bits__tmp3 .equr R9
DSP_decode_bits__adresse_pointeur_lecture_bits .equr R10
DSP_decode_bits__pointeur_lecture_bits .equr R11
DSP_decode_bits_bitcount .equr R12 ; do not re-use!
; .equr R13
DSP_decode_bits__datas_channels_destination .equr R14
DSP_decode_bits__datas_I2S_destination .equr R15
DSP_decode_bits__table_panning_voies .equr R19
DSP_decode_bits_bitbuffer .equr R20 ; do not re-use!
DSP_decode_bits__adresse_boucle_enreg_datas_channels .equr R21
DSP_decode_bits__increment_datas_I2S_destination .equr R22
DSP_decode_bits__adresse_routine_lecture_bits .equr R27
DSP_decode_bits__adresse_retour .equr R28
moveq #0,DSP_decode_bits_bitcount ; force loading first word
moveq #1,r21
DSP_boucle_centrale:
DSP_boucle_centrale__wait_for_timer1_and_68000tick:
cmpq #3,R21 ; attente du timer 1
jr ne,DSP_boucle_centrale__wait_for_timer1_and_68000tick
nop
; change la couleur de fond - debug
.if DISPLAY_TIME = 1
moveq #$f,r14
shlq #20,r14
store r14,(r14+$58/4)
.endif
movei #DSP_flag_replay_ON_OFF,R0
load (R0),R1
movei #DSP_sortie_finale,R2
cmpq #1,r1 ; gracefull stop?
jump eq,(r2)
cmpq #5,r1 ; pause?
movei #empty_i2s,r3
jr ne,no_pause
cmpq #6,r1
;;; pause song
movei #pause_music,r2
jump (r2)
moveta r3,I2S_routine_actuelle
no_pause:
jr ne,no_new_song
moveq #5,r1
movei #restart_with_new_song,r2
moveta r3,I2S_routine_actuelle
jump (r2)
store r1,(r0) ; new song starts paused
no_new_song:
movei #I2S_N_voies,r0
moveta r0,I2S_routine_actuelle
.if UPDATE_SONG_POS = 1
movei #DSP_localData,r14
load (r14+streamingbits_cur_index),r0
load (r14),r1
sub r1,r0
movei #DSP_stream_pos,r1
store r0,(r1)
.endif
movei #AHX_enregistrements_N_voies,DSP_decode_bits__datas_I2S_destination
moveq #AHX_enregistrements_N_voies__I2S_taille_totale,DSP_decode_bits__increment_datas_I2S_destination
shlq #2,DSP_decode_bits__increment_datas_I2S_destination
movei #DSP_AHX_decode_streaming_V4__read_bits_from_bits_streaming,DSP_decode_bits__adresse_routine_lecture_bits
movei #DSP_module_streaming_bits_cur,DSP_decode_bits__adresse_pointeur_lecture_bits
load (DSP_decode_bits__adresse_pointeur_lecture_bits),DSP_decode_bits__pointeur_lecture_bits
; tester fin de stream = bouclage du stream
movei #DSP_module_streaming_bits_end,DSP_decode_bits__tmp0
load (DSP_decode_bits__tmp0),DSP_decode_bits__tmp0
cmp DSP_decode_bits__tmp0,DSP_decode_bits__pointeur_lecture_bits
movei #DSP_song,r14
jr cs,DSP_boucle_read_bits_per_channel__pas_fin_du_fichier
load (r14),r14
;;; restart
load (r14+song_restart_word/4),DSP_decode_bits__pointeur_lecture_bits
add r14,DSP_decode_bits__pointeur_lecture_bits
load (r14+song_restart_bit/4),DSP_decode_bits_bitcount
addq #song_header_size,DSP_decode_bits__pointeur_lecture_bits
load (DSP_decode_bits__pointeur_lecture_bits),DSP_decode_bits_bitbuffer
addq #4,DSP_decode_bits__pointeur_lecture_bits
move DSP_decode_bits_bitcount,DSP_decode_bits__compteur_voies
subq #32,DSP_decode_bits__compteur_voies
sh DSP_decode_bits__compteur_voies,DSP_decode_bits_bitbuffer ; remove "used" bits
DSP_boucle_read_bits_per_channel__pas_fin_du_fichier:
movei #DSP_NB_channels,DSP_decode_bits__compteur_voies
load (DSP_decode_bits__compteur_voies),DSP_decode_bits__compteur_voies
movei #DSP_HVL_table_panning_voies_de_base,DSP_decode_bits__table_panning_voies
move pc,DSP_decode_bits__adresse_boucle_enreg_datas_channels
DSP_boucle_read_bits_per_channel:
load (DSP_decode_bits__table_panning_voies),DSP_decode_bits__datas_channels_destination
; lecture des 8 bits de description/flags
moveq #8,DSP_decode_bits__nb_bits_a_lire ; lit 7 bits => DSP_decode_bits__bits_resultat
move PC,DSP_decode_bits__adresse_retour
jump (DSP_decode_bits__adresse_routine_lecture_bits)
addq #6,DSP_decode_bits__adresse_retour
move DSP_decode_bits__bits_resultat,DSP_decode_bits__flags_datas
;--- 7
; vc_Pan : 8 bits
movei #DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_Pan,DSP_decode_bits__tmp0
btst #7,DSP_decode_bits__flags_datas
jump eq,(DSP_decode_bits__tmp0)
moveq #8,DSP_decode_bits__nb_bits_a_lire
move PC,DSP_decode_bits__adresse_retour
jump (DSP_decode_bits__adresse_routine_lecture_bits)
addq #6,DSP_decode_bits__adresse_retour
; R01=vc_Pan
; ici , convertir vc pan en ?
moveq #0,DSP_decode_bits__tmp1
movei #DSP_panning_table,DSP_decode_bits__tmp0
load (DSP_decode_bits__tmp0),DSP_decode_bits__tmp0
bset #8,DSP_decode_bits__tmp1
add DSP_decode_bits__tmp0,DSP_decode_bits__tmp1
add DSP_decode_bits__bits_resultat,DSP_decode_bits__tmp0
add DSP_decode_bits__bits_resultat,DSP_decode_bits__tmp1
loadb (DSP_decode_bits__tmp0),DSP_decode_bits__tmp0
loadb (DSP_decode_bits__tmp1),DSP_decode_bits__tmp1
or DSP_decode_bits__tmp0,DSP_decode_bits__tmp0
or DSP_decode_bits__tmp1,DSP_decode_bits__tmp1
store DSP_decode_bits__tmp0,(DSP_decode_bits__datas_I2S_destination+index_AHX_enregistrements_N_voies__I2S_panning_left)
store DSP_decode_bits__tmp1,(DSP_decode_bits__datas_I2S_destination+index_AHX_enregistrements_N_voies__I2S_panning_right)
;--- 6
DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_Pan:
; vc_AudioVolume : 6 bits
btst #6,DSP_decode_bits__flags_datas
jr eq,DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_AudioVolume
moveq #6,DSP_decode_bits__nb_bits_a_lire
move PC,DSP_decode_bits__adresse_retour
jump (DSP_decode_bits__adresse_routine_lecture_bits)
addq #6,DSP_decode_bits__adresse_retour
store DSP_decode_bits__bits_resultat,(DSP_decode_bits__datas_channels_destination) ;DSP_index_vc_AudioVolume
;--- 5
DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_AudioVolume:
; vc_Waveform : 2 bits
btst #5,DSP_decode_bits__flags_datas
jr eq,DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_Waveform
moveq #2,DSP_decode_bits__nb_bits_a_lire
move pc,DSP_decode_bits__adresse_retour
jump (DSP_decode_bits__adresse_routine_lecture_bits)
addq #6,DSP_decode_bits__adresse_retour
store DSP_decode_bits__bits_resultat,(DSP_decode_bits__datas_channels_destination+DSP_index_vc_Waveform)
;--- 4
DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_Waveform:
; vc_SquarePos : 6 bits
btst #4,DSP_decode_bits__flags_datas
jr eq,DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_SquarePos
moveq #6,DSP_decode_bits__nb_bits_a_lire
move pc,DSP_decode_bits__adresse_retour
jump (DSP_decode_bits__adresse_routine_lecture_bits)
addq #6,DSP_decode_bits__adresse_retour
store DSP_decode_bits__bits_resultat,(DSP_decode_bits__datas_channels_destination+DSP_index_vc_SquarePos)
;--- 3
DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_SquarePos:
; vc_WaveLength : 3 bits
btst #3,DSP_decode_bits__flags_datas
jr eq,DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_WaveLength
moveq #3,DSP_decode_bits__nb_bits_a_lire
move pc,DSP_decode_bits__adresse_retour
jump (DSP_decode_bits__adresse_routine_lecture_bits)
addq #6,DSP_decode_bits__adresse_retour
store DSP_decode_bits__bits_resultat,(DSP_decode_bits__datas_channels_destination+DSP_index_vc_WaveLength)
;--- 2
DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_WaveLength:
; vc_FilterPos : 6 bits
btst #2,DSP_decode_bits__flags_datas
jr eq,DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_FilterPos
moveq #6,DSP_decode_bits__nb_bits_a_lire
move pc,DSP_decode_bits__adresse_retour
jump (DSP_decode_bits__adresse_routine_lecture_bits)
addq #6,DSP_decode_bits__adresse_retour
store DSP_decode_bits__bits_resultat,(DSP_decode_bits__datas_channels_destination+DSP_index_vc_FilterPos)
;--- 1
DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_FilterPos:
; vc_AudioPeriod : 12 bits
btst #1,DSP_decode_bits__flags_datas
jr eq,DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_AudioPeriod
moveq #12,DSP_decode_bits__nb_bits_a_lire
move pc,DSP_decode_bits__adresse_retour
jump (DSP_decode_bits__adresse_routine_lecture_bits)
addq #6,DSP_decode_bits__adresse_retour
store DSP_decode_bits__bits_resultat,(DSP_decode_bits__datas_channels_destination+DSP_index_vc_AudioPeriod)
;--- 0
DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_vc_AudioPeriod:
; Ring Modulation N/A
btst #0,DSP_decode_bits__flags_datas
jr eq,DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_RM
moveq #1,DSP_decode_bits__nb_bits_a_lire
; en cas de RM, le bit est a 1 aussi si le RM vient d'etre coupé, dans ce cas là,
; vc_RingWaveform (1 bit) =0 + vc_RingAudioPeriod (12 bits) =0
; lecture vc_RingWaveform
move pc,DSP_decode_bits__adresse_retour
jump (DSP_decode_bits__adresse_routine_lecture_bits)
addq #6,DSP_decode_bits__adresse_retour
store DSP_decode_bits__bits_resultat,(DSP_decode_bits__datas_channels_destination+DSP_index_vc_RingWaveform)
; lecture vc_RingAudioPeriod
moveq #12,DSP_decode_bits__nb_bits_a_lire
move pc,DSP_decode_bits__adresse_retour
jump (DSP_decode_bits__adresse_routine_lecture_bits)
addq #6,DSP_decode_bits__adresse_retour
store DSP_decode_bits__bits_resultat,(DSP_decode_bits__datas_channels_destination+DSP_index_vc_RingAudioPeriod)
DSP_AHX_decode_streaming_V2__boucle_voie__pas_de_RM:
; check si channel on, si off on met le volume à zéro
load (DSP_decode_bits__datas_channels_destination+DSP_index_vc_channel_on_off),DSP_decode_bits__flags_datas
or DSP_decode_bits__flags_datas,DSP_decode_bits__flags_datas
jr ne,DSP_read_bits__pas_channel_off
moveq #0,DSP_decode_bits__nb_bits_a_lire
store DSP_decode_bits__nb_bits_a_lire,(DSP_decode_bits__datas_channels_destination)
//-> store DSP_decode_bits__nb_bits_a_lire,(DSP_decode_bits__datas_channels_destination+DSP_index_vc_AudioVolume)
DSP_read_bits__pas_channel_off:
subq #1,DSP_decode_bits__compteur_voies
addqt #4,DSP_decode_bits__table_panning_voies
jump ne,(DSP_decode_bits__adresse_boucle_enreg_datas_channels)
add DSP_decode_bits__increment_datas_I2S_destination,DSP_decode_bits__datas_I2S_destination
store DSP_decode_bits__pointeur_lecture_bits,(DSP_decode_bits__adresse_pointeur_lecture_bits)
; FIN DE : decode stream AHX version bits
; ------------------------------
; ------------------------------
; interprete valeurs dans datas pour chaque channels pour remplir increment, mask et buffer
;
; increment en fonction de l'audioperiod
; mask en fonction de wavelength uniquement ?
;
;
; vc_AudioVolume
; vc_Waveform
; vc_SquarePos
; vc_WaveLength
; vc_FilterPos
; vc_AudioPeriod
;
; --------------- code de gestion du AHX vers I2S ------------------------
; triangle et sawtooth : lire N octets ( wavelength) / appliquer le filtre sur N octets/ appliquer le volume sur N octets : 1 buffer temporaire = buffer_temp_wave
; square : generer 128 octets / apppliquer le filtre sur 128 octets / lire N octets ( wavelength) / appliquer le volume sur N octets : possible sur 1 buffer temporaire : source et dest meme adresse lors de la selection des octets
; noise : generer 128 octets / apppliquer le filtre sur 128 octets / appliquer le volume sur 128 octets : 1 buffer temporaire
;
; 4 routines :
; - lire wavelength octets d'une source vers une dest
; - appliquer le filtre sur une source/dest pour N octets
; - appliquer le volume pour une source/dest sur N octets
; - square generer 128 octets
; - noise generer 128 octets
; - si volume=0 => buffer tout à zéro, rapidement, double dest
; il faut remplir volume OK // wavelength en octets OK // décaleur en fonction de wavelength OK // filterpos // increment pour envoi à I2S OK // mask pour bouclage pour envoi à I2S OK
; reutilisable ?
DSP_genere_wave__tmp0 .equr R0 ;-------------
DSP_genere_wave__tmp1 .equr R1 ;-------------
DSP_genere_wave__tmp2 .equr R2 ;-------------
DSP_genere_wave__tmp3 .equr R3 ;-------------
DSP_genere_wave__tmp4 .equr R4 ;-------------
DSP_genere_wave__tmp5 .equr R5 ;-------------
DSP_genere_wave__ratio_amiga_jaguar .equr R6 ; si necessaire
DSP_genere_wave__wavelength_en_octets .equr R7 ; NON
DSP_genere_wave__increment_pour_lire_les_octets .equr R8 ; NON
DSP_genere_wave__compteur_channels .equr R9 ; NON
DSP_genere_wave__volume .equr R10 ; NON
DSP_genere_wave__wavelength .equr R11 ; NON
DSP_genere_wave__filterpos .equr R13 ; NON
DSP_genere_wave__source_datas_channel .equr R14 ; NON
DSP_genere_wave__dest_record_I2S .equr R15 ; NON
DSP_genere_wave__decaleur_wavelength .equr R16 ; -OUI-
DSP_genere_wave__mask_pour_I2S .equr R17 ; NON
DSP_genere_wave__waveform .equr R18 ; NON
DSP_genere_wave__squarepos .equr R19 ; NON
DSP_genere_wave__routines_a_executer .equr R21 ; si necessaire
DSP_genere_wave__tmp6 .equr R22 ;-------------
DSP_genere_wave__tmp7 .equr R23 ;-------------
DSP_genere_wave__wavelength_en_octets__pour_filtre .equr R24 ; NON
DSP_genere_wave__tmp9 .equr R25 ;-------------
DSP_genere_wave__tmp8 .equr R26 ;-------------
DSP_genere_wave__boucle_sur_un_channel .equr R27 ; NON
DSP_genere_wave__routine_volume_a_zero .equr R28 ; si necessaire
AHX__main__pointeur_adresse_routine_etape_suivante .equr R29 ; NON
DSP_genere_wave__increment_RM_pour_I2S .equr R30 ; NON
movei #AHX_enregistrements_N_voies,DSP_genere_wave__dest_record_I2S
movei #HIVELY_datas_channels,DSP_genere_wave__source_datas_channel
movei #DSP_ratio_Amiga_Jaguar__a_virgule_9_bits,DSP_genere_wave__ratio_amiga_jaguar
movei #DSP_NB_channels,DSP_genere_wave__compteur_channels
load (DSP_genere_wave__compteur_channels),DSP_genere_wave__compteur_channels
movei #DSP_genere_wave_routine_volume_a_zero,DSP_genere_wave__routine_volume_a_zero
load (DSP_genere_wave__ratio_amiga_jaguar),DSP_genere_wave__ratio_amiga_jaguar
movei #AHX_table_routines_a_executer,DSP_genere_wave__routines_a_executer
move pc,DSP_genere_wave__boucle_sur_un_channel
DSP_genere_wave__boucle:
//-> load (DSP_genere_wave__source_datas_channel+DSP_index_vc_AudioVolume),DSP_genere_wave__volume
load (DSP_genere_wave__source_datas_channel),DSP_genere_wave__volume
load (DSP_genere_wave__source_datas_channel+DSP_index_vc_Waveform),DSP_genere_wave__waveform
cmpq #0,DSP_genere_wave__volume
jump eq,(DSP_genere_wave__routine_volume_a_zero)
load (DSP_genere_wave__source_datas_channel+DSP_index_vc_SquarePos),DSP_genere_wave__squarepos
; = wavelength : 0 à 5 ( 2^(n+2) ) // $04/$08/$10/$20/$40/$80 0=$04, 1=$08, 2=$10, 3=$20, 4=$40, 5=$80
load (DSP_genere_wave__source_datas_channel+DSP_index_vc_WaveLength),DSP_genere_wave__wavelength
load (DSP_genere_wave__source_datas_channel+DSP_index_vc_FilterPos),DSP_genere_wave__filterpos
move DSP_genere_wave__wavelength,DSP_genere_wave__decaleur_wavelength
load (DSP_genere_wave__source_datas_channel+DSP_index_vc_AudioPeriod),DSP_genere_wave__tmp0 ;DSP_genere_wave__audioperiod
subq #5,DSP_genere_wave__decaleur_wavelength
moveq #1,DSP_genere_wave__increment_pour_lire_les_octets
addq #2,DSP_genere_wave__wavelength ; wavelength + 2
sh DSP_genere_wave__decaleur_wavelength,DSP_genere_wave__increment_pour_lire_les_octets
moveq #1,DSP_genere_wave__wavelength_en_octets
neg DSP_genere_wave__wavelength
move DSP_genere_wave__ratio_amiga_jaguar,DSP_genere_wave__tmp6
sh DSP_genere_wave__wavelength,DSP_genere_wave__wavelength_en_octets
div DSP_genere_wave__tmp0,DSP_genere_wave__tmp6
or DSP_genere_wave__tmp6,DSP_genere_wave__tmp6
move DSP_genere_wave__waveform,DSP_genere_wave__tmp0
store DSP_genere_wave__tmp6,(DSP_genere_wave__dest_record_I2S+index_AHX_enregistrements_N_voies__I2S_increment)
movei #buffer_temp_wave,DSP_genere_wave__tmp6 ;dest pour triangle et sawtooth, variaiblisé pour gérer le RM
shlq #2,DSP_genere_wave__tmp0 ; waveform * 4
move DSP_genere_wave__wavelength_en_octets,DSP_genere_wave__mask_pour_I2S
add DSP_genere_wave__routines_a_executer,DSP_genere_wave__tmp0 ; choix de la routine suivant waveform
movei #AHX__main__routine__filtre,AHX__main__pointeur_adresse_routine_etape_suivante
load (DSP_genere_wave__tmp0),DSP_genere_wave__tmp0
subq #1,DSP_genere_wave__mask_pour_I2S ; mask pour I2S
jump (DSP_genere_wave__tmp0)
shlq #AHX_nb_bits_virgule_increment_period,DSP_genere_wave__mask_pour_I2S ; avec virgule
AHX__main__adresse_retour_vers_main_suivant_voie:
; gestion de Ring Modulation
load (DSP_genere_wave__source_datas_channel+DSP_index_vc_RingAudioPeriod),DSP_genere_wave__increment_RM_pour_I2S
move DSP_genere_wave__ratio_amiga_jaguar,DSP_genere_wave__tmp0
cmpq #0,DSP_genere_wave__increment_RM_pour_I2S
load (DSP_genere_wave__dest_record_I2S+index_AHX_enregistrements_N_voies__I2S_buffer__RM),DSP_genere_wave__tmp6 ; buffer dest = buffer RM
jr eq,DSP_genere_wave__boucle__apres_RM
div DSP_genere_wave__increment_RM_pour_I2S,DSP_genere_wave__tmp0
; buffer dans DSP_genere_wave__tmp6
load (DSP_genere_wave__source_datas_channel+DSP_index_vc_RingWaveform),DSP_genere_wave__tmp1
shlq #2,DSP_genere_wave__tmp1 ; RM waveform * 4
; choix de la routine suivant waveform pour RM : 0 ou 1
add DSP_genere_wave__routines_a_executer,DSP_genere_wave__tmp1
load (DSP_genere_wave__tmp1),DSP_genere_wave__tmp1
move DSP_genere_wave__tmp0,DSP_genere_wave__increment_RM_pour_I2S
move pc,AHX__main__pointeur_adresse_routine_etape_suivante
jump (DSP_genere_wave__tmp1)
addq #6,AHX__main__pointeur_adresse_routine_etape_suivante
DSP_genere_wave__boucle__apres_RM:
store DSP_genere_wave__increment_RM_pour_I2S,(DSP_genere_wave__dest_record_I2S+index_AHX_enregistrements_N_voies__I2S_increment__RM)
store DSP_genere_wave__mask_pour_I2S,(DSP_genere_wave__dest_record_I2S+index_AHX_enregistrements_N_voies__I2S_mask_bouclage)