-
Notifications
You must be signed in to change notification settings - Fork 0
/
lsp_v15.S
1678 lines (1424 loc) · 50.5 KB
/
lsp_v15.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
USE_JOYPAD EQU 0
DSP_STACK_SIZE equ 32 ; long words
DSP_USP equ (D_ENDRAM-(4*DSP_STACK_SIZE))
DSP_ISP equ (DSP_USP-(4*DSP_STACK_SIZE))
; ------------------------------------
; LSP
; ------------------------------------
silence:
dc.b $0,$0,$0,$0
dc.b $0,$0,$0,$0
dc.b $0,$0,$0,$0
; ------------------------------------
; Init
LSP_PlayerInit:
; a0: music data (any mem)
; a1: sound bank data (chip mem)
; (a2: 16bit DMACON word address)
; Out:a0: music BPM pointer (16bits)
; d0: music len in tick count
cmpi.l #'LSP1',(a0)+
bne .dataError
move.l (a0)+,d0 ; unique id
cmp.l (a1),d0 ; check that sample bank is this one
bne .dataError
lea LSPVars,a3
cmpi.w #$0105,(a0)+ ; minimal major & minor version of latest compatible LSPConvert.exe = V 1.05
blt .dataError
moveq #0,d6
move.w (a0)+,d6
move.l d6,m_currentBpm-LSPVars(a3) ; default BPM
move.l d6,LSP_BPM_frequence_replay
move.w (a0)+,d6
move.l d6,m_escCodeRewind-LSPVars(a3) ; tout en .L
move.w (a0)+,d6
move.l d6,m_escCodeSetBpm-LSPVars(a3)
move.l (a0)+,-(a7) ; nb de ticks du module en tout = temps de replay ( /BPM)
;move.l a2,m_dmaconPatch(a3)
;move.w #$8000,-1(a2) ; Be sure DMACon word is $8000 (note: a2 should be ODD address)
moveq #0,d0
move.w (a0)+,d0 ; instrument count
lea -12(a0),a2 ; LSP data has -12 offset on instrument tab ( to win 2 cycles in fast player :) )
move.l a2,m_lspInstruments-LSPVars(a3) ; instrument tab addr ( minus 4 )
subq.w #1,d0
move.l a1,d1
.relocLoop:
;bset.b #0,3(a0) ; bit0 is relocation done flag
;bne.s .relocated
move.l (a0),d5 ; pointeur sample
add.l d1,d5 ; passage de relatif en absolu
;lsl.l #nb_bits_virgule_offset,d6
move.l d5,(a0) ; pointeur sample
moveq #0,d6
move.w 4(a0),d6 ; taille en words
add.l d6,d6
move.w d6,4(a0) ; taille en bytes
move.l (a0),a4
move.l 6(a0),d6 ; pointeur sample repeat
add.l d1,d6 ; passage de relatif en absolu
cmp.l d5,d6 ; corrige pointeur de repeat avant le debut de l'instrument
bge.s .ok_loop
move.l d5,d6
.ok_loop:
;lsl.l #nb_bits_virgule_offset,d6
move.l d6,6(a0) ; pointeur sample repeat
moveq #0,d6
move.w 10(a0),d6 ; taille repeat en words
add.l d6,d6
move.w d6,10(a0) ; taille repeat en bytes
.relocated:
lea 12(a0),a0
dbf.w d0,.relocLoop
move.w (a0)+,d0 ; codes count (+2)
move.l a0,m_codeTableAddr-LSPVars(a3) ; code table
add.w d0,d0
add.w d0,a0
move.l (a0)+,d0 ; word stream size
move.l (a0)+,d1 ; byte stream loop point
move.l (a0)+,d2 ; word stream loop point
move.l a0,m_wordStream-LSPVars(a3)
lea 0(a0,d0.l),a1 ; byte stream
move.l a1,m_byteStream-LSPVars(a3)
add.l d2,a0
add.l d1,a1
move.l a0,m_wordStreamLoop-LSPVars(a3)
move.l a1,m_byteStreamLoop-LSPVars(a3)
;bset.b #1,$bfe001 ; disabling this fucking Low pass filter!!
lea m_currentBpm-LSPVars(a3),a0
move.l (a7)+,d0 ; music len in frame ticks
rts
.dataError: illegal
.text
;-------------------------------------
;
; DSP
;
;-------------------------------------
.phrase
YM_DSP_debut:
.dsp
.org D_RAM
DSP_base_memoire:
; CPU interrupt
.rept 8
nop
.endr
; I2S interrupt
movei #DSP_LSP_routine_interruption_I2S,r17 ; 6 octets
movei #D_FLAGS,r30 ; 6 octets
jump (r17) ; 2 octets
load (r30),r29 ; read flags ; 2 octets = 16 octets
; Timer 1 interrupt
movei #DSP_LSP_routine_interruption_Timer1,r12 ; 6 octets
movei #D_FLAGS,r11 ; 6 octets
jump (r12) ; 2 octets
load (r11),r13 ; read flags ; 2 octets = 16 octets
; Timer 2 interrupt
movei #DSP_LSP_routine_interruption_Timer2,r12 ; 6 octets
movei #D_FLAGS,r11 ; 6 octets
jump (r12) ; 2 octets
load (r11),r13 ; read flags ; 2 octets = 16 octets
; External 0 interrupt
.rept 8
nop
.endr
; External 1 interrupt
.rept 8
nop
.endr
; ----------------------------------
; DSP : routines en interruption I2S
; ----------------------------------
; registres permanents : R31/R30/R29
; utilisés : R29/R30/R31
; R22/R23/R24/R25/R26/R27/R28
; R17/R16
; resultats samples = R18/R19/R20/R21
;
; R16 = 4 octets en cours channel 3 / LSP_DSP_PAULA_AUD3DAT
; R24 = 4 octets en cours channel 2 / LSP_DSP_PAULA_AUD2DAT
; R25 = 4 octets en cours channel 1 / LSP_DSP_PAULA_AUD1DAT
; R28 = 4 octets en cours channel 0 / LSP_DSP_PAULA_AUD0DAT
; I2S : replay sample
; - version simple, lit un octet à chaque fois
; - puis version plus compleque : lit 1 long, et utilise ses octets
DSP_LSP_routine_interruption_I2S:
store R18,(R26) ; write left channel
store R19,(R27) ; write right channel
.if DSP_DEBUG
; change la couleur du fond
movei #$777,R26
movei #BG,r27
storew r26,(r27)
.endif
; version complexe avec stockage de 4 octets
; et tout en registres / alternatifs
; ----------
; channel 3
; movei #LSP_DSP_PAULA_internal_location3,R1
; movei #LSP_DSP_PAULA_internal_increment3,R2
; movei #LSP_DSP_PAULA_internal_length3,R3
; movei #LSP_DSP_PAULA_AUD3LEN,R4
; movei #LSP_DSP_PAULA_AUD3L,R5
;movei #LSP_DSP_PAULA_internal_location3,R28 ; adresse sample actuelle, a virgule
;movefa R1,R28
;movei #LSP_DSP_PAULA_internal_increment3,R27
;load (R28),R26 ; R26=current pointeur sample 16:16
movefa R1,R26 ; alt R1 = direct sample adress
movefa R2,R27 ; alt R2 = direct increment value
;load (R27),R27 ; R27=increment 16:16
move R26,R17 ; R17 = pointeur sample a virgule avant increment
;movei #LSP_DSP_PAULA_internal_length3,R25 ; =FIN
movefa R3,R23 ; alt R3 = (LSP_DSP_PAULA_internal_length3)
add R27,R26 ; R26=adresse+increment , a virgule
;load (R25),R23
movefa R0,R22 ; alt R0 = mask $FFFFFFFC = 11111111 11111111 11111111 11111100
cmp R23,R26
jr mi,DSP_LSP_routine_interruption_I2S_pas_fin_de_sample_channel3
;nop
shrq #nb_bits_virgule_offset,R17 ; ancien pointeur adresse sample partie entiere
; fin de sample => on recharge les infos des registres externes
shlq #32-nb_bits_virgule_offset,R26
;movei #LSP_DSP_PAULA_AUD3LEN,R27 ; fin, a virgule
movefa R4,R27 ; alt R4 = direct (LSP_DSP_PAULA_AUD3LEN)
shrq #32-nb_bits_virgule_offset,R26 ; on ne garde que la virgule
;movei #LSP_DSP_PAULA_AUD3L,R24 ; sample location a virgule
; movefa R5,R24
movefa R5,R23 ; alt R5 = direct (LSP_DSP_PAULA_AUD3L)
;load (R27),R27
;load (R24),R23
;store R27,(R25) ; update internal sample end, a virgule
moveta R27,R3 ; update alt R3 = (LSP_DSP_PAULA_internal_length3)
or R23,R26 ; on garde la virgule en cours
DSP_LSP_routine_interruption_I2S_pas_fin_de_sample_channel3:
moveta R26,R1 ; store internal sample pointeur, a virgule dans alt R1
;store R26,(R28) ; stocke internal sample pointeur, a virgule
; read sample datas
shrq #nb_bits_virgule_offset,R26 ; nouveau pointeur adresse sample partie entiere
;shrq #nb_bits_virgule_offset,R17 ; ancien pointeur adresse sample partie entiere
move R26,R27 ; R27 = nouveau pointeur sample
and R22,R17 ; ancien pointeur sample modulo 4
and R22,R26 ; nouveau pointeur sample modulo 4
;movei #LSP_DSP_PAULA_AUD3DAT,R28 ; 4 octets actuels
;subq #4,R28 ; de LSP_DSP_PAULA_internal_location3 => LSP_DSP_PAULA_AUD3DAT
not R22 ; => %11
;load (R28),R16 ; R21 = octets actuels en stock
and R22,R27 ; R27 = position octet à lire
cmp R17,R26
jr eq,DSP_LSP_routine_interruption_I2S_pas_nouveau_long_word3
shlq #3,R27 ; numero d'octet à lire * 8
; il faut rafraichir R21
load (R26),R16 ; lit 4 nouveaux octets de sample
;store R16,(R28) ; rafraichit le stockage des 4 octets
DSP_LSP_routine_interruption_I2S_pas_nouveau_long_word3:
;movei #LSP_DSP_PAULA_AUD3VOL,R23/R24
;subq #4,R28 ; de LSP_DSP_PAULA_AUD3DAT => LSP_DSP_PAULA_AUD3VOL
move R16,R21 ; 4 octets dispos dans registre de travail
neg R27 ; -0 -8 -16 -24
; R27=numero d'octet à lire
; ch2
;movei #LSP_DSP_PAULA_internal_increment2,R27
sh R27,R21 ; shift les 4 octets en stock vers la gauche, pour positionner l'octet à lire en haut
movefa R21,R23 ; alt R21 = volume channel 3
;load (R23),R23 ; R23 = volume : 6 bits
sharq #24,R21 ; descends l'octet à lire
movefa R7,R27 ; alt R7 = direct increment value channel 2
; ch2
imult R23,R21 ; unsigned multiplication : unsigned sample * volume => 8bits + 6 bits = 14 bits
; R21=sample channel 3 on 14 bits
; ----------
; channel 2
; movei #LSP_DSP_PAULA_internal_location2,R6
; movei #LSP_DSP_PAULA_internal_increment2,R7
; movei #LSP_DSP_PAULA_internal_length2,R8
; movei #LSP_DSP_PAULA_AUD2LEN,R9
; movei #LSP_DSP_PAULA_AUD2L,R10
;load (R27),R27 ; R27=increment 16:16
;movei #LSP_DSP_PAULA_internal_location2,R28 ; adresse sample actuelle, a virgule
;movefa R6,R28
;movei #LSP_DSP_PAULA_internal_length2,R25 ; =FIN
;movei #LSP_DSP_PAULA_internal_increment2,R27
;load (R28),R26 ; R26=current pointeur sample 16:16
movefa R6,R26 ; alt R1 = direct sample adress
movefa R8,R23 ; alt R8 = (LSP_DSP_PAULA_internal_length2)
move R26,R17 ; R17 = pointeur sample a virgule avant increment
add R27,R26 ; R26=adresse+increment , a virgule
;load (R25),R23
movefa R0,R22
cmp R23,R26
jr mi,DSP_LSP_routine_interruption_I2S_pas_fin_de_sample_channel2
shrq #nb_bits_virgule_offset,R17 ; ancien pointeur adresse sample partie entiere
; fin de sample => on recharge les infos des registres externes
shlq #32-nb_bits_virgule_offset,R26
;movei #LSP_DSP_PAULA_AUD2LEN,R27 ; fin, a virgule
movefa R9,R27 ; alt R9 = direct (LSP_DSP_PAULA_AUD2LEN)
shrq #32-nb_bits_virgule_offset,R26 ; on ne garde que la virgule
;movei #LSP_DSP_PAULA_AUD2L,R24 ; sample location a virgule
;movefa R10,R24
movefa R10,R23 ; alt R5 = direct (LSP_DSP_PAULA_AUD2L)
;load (R27),R27
;load (R24),R23
;store R27,(R25) ; update internal sample end, a virgule
moveta R27,R8 ; update alt R8 = (LSP_DSP_PAULA_internal_length2)
or R23,R26 ; on garde la virgule en cours
DSP_LSP_routine_interruption_I2S_pas_fin_de_sample_channel2:
moveta R26,R6 ; store internal sample pointeur, a virgule dans alt R6
;store R26,(R28) ; stocke internal sample pointeur, a virgule
shrq #nb_bits_virgule_offset,R26 ; nouveau pointeur adresse sample partie entiere
;shrq #nb_bits_virgule_offset,R17 ; ancien pointeur adresse sample partie entiere
move R26,R27 ; R27 = nouveau pointeur sample
and R22,R17 ; ancien pointeur sample modulo 4
and R22,R26 ; nouveau pointeur sample modulo 4
;movei #LSP_DSP_PAULA_AUD2DAT,R28 ; 4 octets actuels
;subq #4,R28 ; de LSP_DSP_PAULA_internal_location2 => LSP_DSP_PAULA_AUD2DAT
not R22 ; => %11
;load (R28),R20 ; R20 = octets actuels en stock
and R22,R27 ; R27 = position octet à lire
cmp R17,R26
jr eq,DSP_LSP_routine_interruption_I2S_pas_nouveau_long_word2
;nop
shlq #3,R27 ; numero d'octet à lire * 8
; il faut rafraichir R20
load (R26),R24 ; lit 4 nouveaux octets de sample
;store R24,(R28) ; rafraichit le stockage des 4 octets
DSP_LSP_routine_interruption_I2S_pas_nouveau_long_word2:
;movei #LSP_DSP_PAULA_AUD2VOL,R23
;subq #4,R28 ; de LSP_DSP_PAULA_AUD2DAT => LSP_DSP_PAULA_AUD2VOL
move R24,R20 ; 4 octets dispos dans registre de travail
neg R27 ; -0 -8 -16 -24
; R27=numero d'octet à lire
; ch1
;movei #LSP_DSP_PAULA_internal_increment1,R27
sh R27,R20 ; shift les 4 octets en stock vers la gauche, pour positionner l'octet à lire en haut
movefa R22,R23 ; alt R22 = volume channel 2
;load (R23),R23 ; R23 = volume : 6 bits
sharq #24,R20 ; descends l'octet à lire
movefa R12,R27 ; alt R12 = direct increment value channel 1
imult R23,R20 ; unsigned multiplication : unsigned sample * volume => 8bits + 6 bits = 14 bits
; R20=sample channel 2 on 14 bits
; ----------
; channel 1
; movei #LSP_DSP_PAULA_internal_location1,R11
; movei #LSP_DSP_PAULA_internal_increment1,R12
; movei #LSP_DSP_PAULA_internal_length1,R13
; movei #LSP_DSP_PAULA_AUD1LEN,R14
; movei #LSP_DSP_PAULA_AUD1L,R15
;movei #LSP_DSP_PAULA_internal_location1,R28 ; adresse sample actuelle, a virgule
;movefa R11,R28
;load (R28),R26 ; R26=current pointeur sample 16:16
movefa R11,R26 ; alt R11 = direct sample adress
;load (R27),R27 ; R27=increment 16:16
movefa R13,R23 ; alt R13 = (LSP_DSP_PAULA_internal_length1)
move R26,R17 ; R17 = pointeur sample a virgule avant increment
;movei #LSP_DSP_PAULA_internal_length1,R25 ; =FIN
add R27,R26 ; R26=adresse+increment , a virgule
;load (R25),R23
movefa R0,R22
cmp R23,R26
jr mi,DSP_LSP_routine_interruption_I2S_pas_fin_de_sample_channel1
;nop
shrq #nb_bits_virgule_offset,R17 ; ancien pointeur adresse sample partie entiere
; fin de sample => on recharge les infos des registres externes
shlq #32-nb_bits_virgule_offset,R26
;movei #LSP_DSP_PAULA_AUD1LEN,R27 ; fin, a virgule
movefa R14,R27 ; alt R14 = direct (LSP_DSP_PAULA_AUD1LEN)
shrq #32-nb_bits_virgule_offset,R26 ; on ne garde que la virgule
;movei #LSP_DSP_PAULA_AUD1L,R24 ; sample location a virgule
;movefa R15,R24
movefa R15,R23
;load (R27),R27
;load (R24),R23
;store R27,(R25) ; update internal sample end, a virgule
moveta R27,R13 ; update alt R13 = (LSP_DSP_PAULA_internal_length1)
or R23,R26 ; on garde la virgule en cours
DSP_LSP_routine_interruption_I2S_pas_fin_de_sample_channel1:
moveta R26,R11 ; store internal sample pointeur, a virgule dans alt R11
;store R26,(R28) ; stocke internal sample pointeur, a virgule
shrq #nb_bits_virgule_offset,R26 ; nouveau pointeur adresse sample partie entiere
;shrq #nb_bits_virgule_offset,R17 ; ancien pointeur adresse sample partie entiere
move R26,R27 ; R27 = nouveau pointeur sample
and R22,R17 ; ancien pointeur sample modulo 4
and R22,R26 ; nouveau pointeur sample modulo 4
;movei #LSP_DSP_PAULA_AUD1DAT,R28 ; 4 octets actuels
;subq #4,R28 ; de LSP_DSP_PAULA_internal_location1 => LSP_DSP_PAULA_AUD1DAT
not R22 ; => %11
;load (R28),R19 ; R19 = octets actuels en stock
and R22,R27 ; R27 = position octet à lire
cmp R17,R26
jr eq,DSP_LSP_routine_interruption_I2S_pas_nouveau_long_word1
;nop
shlq #3,R27 ; numero d'octet à lire * 8
; il faut rafraichir R19
load (R26),R25 ; lit 4 nouveaux octets de sample
;store R19,(R28) ; rafraichit le stockage des 4 octets
DSP_LSP_routine_interruption_I2S_pas_nouveau_long_word1:
;movei #LSP_DSP_PAULA_AUD1VOL,R23
;subq #4,R28 ; de LSP_DSP_PAULA_AUD1DAT => LSP_DSP_PAULA_AUD1VOL
move R25,R19 ; 4 octets dispos dans registre de travail
neg R27 ; -0 -8 -16 -24
; R27=numero d'octet à lire
; ch0
;movei #LSP_DSP_PAULA_internal_increment0,R27
sh R27,R19 ; shift les 4 octets en stock vers la gauche, pour positionner l'octet à lire en haut
movefa R23,R23 ; alt R23 = volume channel 1
; load (R28),R23 ; R23 = volume : 6 bits
sharq #24,R19 ; descends l'octet à lire
; ch0
;movei #LSP_DSP_PAULA_internal_location0,R28 ; adresse sample actuelle, a virgule
movefa R17,R27 ; alt R17 = direct increment value channel 0
imult R23,R19 ; unsigned multiplication : unsigned sample * volume => 8bits + 6 bits = 14 bits
; R19=sample channel 1 on 14 bits
; ----------
; channel 0
; movei #LSP_DSP_PAULA_internal_location0,R16
; movei #LSP_DSP_PAULA_internal_increment0,R17
; movei #LSP_DSP_PAULA_internal_length0,R18
; movei #LSP_DSP_PAULA_AUD0LEN,R19
; movei #LSP_DSP_PAULA_AUD0L,R20
;movefa R16,R28
;load (R28),R26 ; R26=current pointeur sample 16:16
movefa R16,R26 ; alt R16 = direct sample adress channl 0
movefa R18,R23 ; alt R18 = (LSP_DSP_PAULA_internal_length0)
move R26,R17 ; R17 = pointeur sample a virgule avant increment
;movei #LSP_DSP_PAULA_internal_length0,R25 ; =FIN
;movefa R18,R25
add R27,R26 ; R26=adresse+increment , a virgule
;load (R25),R23
movefa R0,R22 ; -FFFFFFC
cmp R23,R26
jr mi,DSP_LSP_routine_interruption_I2S_pas_fin_de_sample_channel0
shrq #nb_bits_virgule_offset,R17 ; ancien pointeur adresse sample partie entiere
; fin de sample => on recharge les infos des registres externes
shlq #32-nb_bits_virgule_offset,R26
;movei #LSP_DSP_PAULA_AUD0LEN,R27 ; fin, a virgule
movefa R19,R27
shrq #32-nb_bits_virgule_offset,R26 ; on ne garde que la virgule
;movei #LSP_DSP_PAULA_AUD0L,R24 ; sample location a virgule
movefa R20,R23
;load (R27),R27
;load (R24),R23
;store R27,(R25) ; update internal sample end, a virgule
moveta R27,R18 ; update alt R18 = (LSP_DSP_PAULA_internal_length0)
or R23,R26 ; on garde la virgule en cours
DSP_LSP_routine_interruption_I2S_pas_fin_de_sample_channel0:
; store R26,(R28) ; stocke internal sample pointeur, a virgule
moveta R26,R16 ; store internal sample pointeur, a virgule dans alt R16
shrq #nb_bits_virgule_offset,R26 ; nouveau pointeur adresse sample partie entiere
move R26,R27 ; R27 = nouveau pointeur sample
and R22,R17 ; ancien pointeur sample modulo 4
and R22,R26 ; nouveau pointeur sample modulo 4
;movei #LSP_DSP_PAULA_AUD0DAT,R28 ; 4 octets actuels
;subq #4,R28 ; de LSP_DSP_PAULA_internal_location0 => LSP_DSP_PAULA_AUD0DAT
not R22 ; => %11
;load (R28),R18 ; R18 = octets actuels en stock
and R22,R27 ; R27 = position octet à lire
cmp R17,R26
jr eq,DSP_LSP_routine_interruption_I2S_pas_nouveau_long_word0
shlq #3,R27 ; numero d'octet à lire * 8
; il faut rafraichir R18
load (R26),R28 ; lit 4 nouveaux octets de sample
;store R18,(R28) ; rafraichit le stockage des 4 octets
DSP_LSP_routine_interruption_I2S_pas_nouveau_long_word0:
;movei #LSP_DSP_PAULA_AUD0VOL,R23
;subq #4,R28 ; de LSP_DSP_PAULA_AUD0DAT => LSP_DSP_PAULA_AUD0VOL
move R28,R18 ; 4 octets dispos dans registre de travail
neg R27 ; -0 -8 -16 -24
; R27=numero d'octet à lire
; suite
.if channel_2=0
moveq #0,R19
.endif
.if channel_3=0
moveq #0,R20
.endif
add R20,R19 ; R19 = right 15 bits unsigned
;--
sh R27,R18 ; shift les 4 octets en stock vers la gauche, pour positionner l'octet à lire en haut
movefa R24,R23 ; alt R24 = volume channel 0
;load (R28),R23 ; R23 = volume : 6 bits
sharq #24,R18 ; descends l'octet à lire
; suite
;movei #$8000,R26
movei #L_I2S,R27
imult R23,R18 ; unsigned multiplication : unsigned sample * volume => 8bits + 6 bits = 14 bits
; R18=sample channel 0 on 14 bits
; Stéreo Amiga:
; les canaux 0 et 3 formant la voie stéréo gauche et 1 et 2 la voie stéréo droite
; R18=channel 0
; R19=channel 1
; R20=channel 2
; R21=channel 3
.if channel_1=0
moveq #0,R18
.endif
.if channel_4=0
moveq #0,R21
.endif
;movei #$8000,R26
movei #L_I2S+4,R26
add R21,R18 ; R18 = left 15 bits unsigned
;add R20,R19 ; R19 = right 15 bits unsigned
shlq #1,R19
shlq #1,R18 ; 16 bits unsigned
;sub R26,R18 ; 16 bits signed
;sub R26,R19
; moved to top of I2S
;store R19,(R27) ; write right channel
;store R18,(R26) ; write left channel
.if DSP_DEBUG
; change la couleur du fond
movei #$000,R26
movei #BG,r27
storew r26,(r27)
.endif
;------------------------------------
; return from interrupt I2S
load (r31),r17 ; return address
bset #10,r29 ; clear latch 1 = I2S
addqt #2,r17 ; next instruction
bclr #3,r29 ; clear IMASK
addq #4,r31 ; pop from stack
jump t,(r17) ; return
store r29,(r30) ; restore flags
;--------------------------------------------
; ---------------- Timer 1 ------------------
;--------------------------------------------
; autorise interruptions, pour timer I2S
;
; registres utilisés :
; R13/R11 /R31
; R0/R1/R2/R3/R4/R5/R6/R7/R8/R9/R10 R12/R13/R14
DSP_LSP_routine_interruption_Timer1:
.if I2S_during_Timer1=1
bclr #3,r13 ; clear IMASK
store r13,(r11) ; restore flags
.endif
; gestion replay LSP
movei #LSPVars,R14
load (R14),R0 ; R0 = byte stream
DSP_LSP_Timer1_process:
moveq #0,r3
moveq #0,R2
bset #8,r3 ; r3 = $100
DSP_LSP_Timer1_cloop:
loadb (R0),R6 ; R6 = byte code
addq #1,R0
cmpq #0,R6
jr eq,DSP_LSP_Timer1_cloop
add R3,R2
sub r3,r2
DSP_LSP_Timer1_swCode:
add R6,R2
move R2,R6
add R2,R2
load (R14+2),R3 ; R3=code table / m_codeTableAddr
add R2,R3
loadw (R3),R2 ; R2 = code
cmpq #0,R2
movei #DSP_LSP_Timer1_noInst,R12
jump eq,(R12)
load (R14+3),R4 ; R4=escape code rewind / m_escCodeRewind
cmp R4,R2
movei #DSP_LSP_Timer1_r_rewind,R12
jump eq,(R12)
cmp R4,R2
movei #DSP_LSP_Timer1_r_chgbpm,R12
jump eq,(R12)
load (R14+4),R4 ; R4=escape code set bpm / m_escCodeSetBpm
;--------------------------
; gestion des volumes
;--------------------------
; test volume canal 3
btst #7,R2
loadb (R0),R4
jr eq,DSP_LSP_Timer1_noVd
btst #6,R2
addqt #1,R0
moveta R4,R21 ; alt R21 = volume channel 3
loadb (R0),R4
DSP_LSP_Timer1_noVd:
; test volume canal 2
jr eq,DSP_LSP_Timer1_noVc
btst #5,R2
addqt #1,R0
moveta R4,R22 ; alt R22 = volume channel 2
loadb (R0),R4
DSP_LSP_Timer1_noVc:
; test volume canal 1
jr eq,DSP_LSP_Timer1_noVb
btst #4,R2
addqt #1,R0
moveta R4,R23 ; alt R23 = volume channel 1
loadb (R0),R4
DSP_LSP_Timer1_noVb:
; test volume canal 0
jr eq,DSP_LSP_Timer1_noVa
nop
addq #1,R0
moveta R4,R24 ; alt R24 = volume channel 0
DSP_LSP_Timer1_noVa:
.if LSP_avancer_module=1
store R0,(R14) ; store byte stream ptr
.endif
addq #4,R14 ; avance a word stream ptr
load (R14),R0 ; R0 = word stream
;--------------------------
; gestion des notes
;--------------------------
; test period canal 3
movei #LSP_DSP_PAULA_AUD3PER,R5
btst #3,R2
loadw (R0),R4
jr eq,DSP_LSP_Timer1_noPd
btst #2,R2
addqt #2,R0
store R4,(R5)
loadw (R0),R4
DSP_LSP_Timer1_noPd:
; test period canal 2
subqt #4,r5
jr eq,DSP_LSP_Timer1_noPc
btst #1,R2
addqt #2,R0
store R4,(R5)
loadw (R0),R4
DSP_LSP_Timer1_noPc:
; test period canal 1
subqt #4,r5
jr eq,DSP_LSP_Timer1_noPb
btst #0,R2
addqt #2,R0
store R4,(R5)
loadw (R0),R4
DSP_LSP_Timer1_noPb:
; test period canal 0
jr eq,DSP_LSP_Timer1_noPa
subqt #4,r5
addqt #2,R0
store R4,(R5)
DSP_LSP_Timer1_noPa:
; pas de test des 8 bits du haut en entier pour zapper la lecture des instruments
; tst.w d0 ; d0.w, avec d0.b qui a avancé ! / beq.s .noInst
load (R14+4),R5 ; R5= instrument table ( =+$10) = a2 / m_lspInstruments-1 = 5-1
;--------------------------
; gestion des instruments
;--------------------------
;--- test instrument voie 3
movei #LSP_DSP_repeat_pointeur3,R7
btst #15,R2
movei #DSP_LSP_Timer1_skip3,R12
jr ne,DSP_LSP_Timer1_setIns3
btst #14,R2
jump eq,(R12)
nop
; repeat voie 3
load (R7),R3 ; pointeur sauvegardé, sur infos de repeats
addqt #4,r7 ;LSP_DSP_repeat_length3,R8
load (R7),R4
moveta R3,R5 ; alt R5 = (LSP_DSP_PAULA_AUD3L)
jump (R12) ; jump en DSP_LSP_Timer1_skip3
moveta R4,R4 ; new length => alt R4
DSP_LSP_Timer1_setIns3:
loadw (R0),R3 ; offset de l'instrument par rapport au precedent
; addition en .w
; passage en .L
shlq #16,R3
addq #2,R0
sharq #16,R3
add R3,R5 ;R5=pointeur datas instruments
;movei #LSP_DSP_PAULA_AUD3L,R7
loadw (R5),R6
addq #2,R5
shlq #16,R6
loadw (R5),R8
or R8,R6
;movei #LSP_DSP_PAULA_AUD3LEN,R8
shlq #nb_bits_virgule_offset,R6
;store R6,(R7) ; stocke le pointeur sample a virgule dans LSP_DSP_PAULA_AUD3L
addq #2,R5
moveta R6,R5 ; alt R5 = (LSP_DSP_PAULA_AUD3L)
loadw (R5),R9 ; .w = R9 = taille du sample
shlq #nb_bits_virgule_offset,R9 ; en 16:16
add R6,R9 ; taille devient fin du sample, a virgule
;store R9,(R8) ; stocke la nouvelle fin a virgule
moveta R9,R4 ; new length => alt R4
addq #2,R5 ; positionne sur pointeur de repeat
; repeat pointeur
loadw (R5),R4
addq #2,R5
shlq #16,R4
loadw (R5),R8
or R8,R4
addq #2,R5
shlq #nb_bits_virgule_offset,R4
store R4,(R7) ; pointeur sample repeat, a virgule
; repeat length
loadw (R5),R8 ; .w = R8 = taille du sample
addqt #4,r7 ;LSP_DSP_repeat_length3
shlq #nb_bits_virgule_offset,R8 ; en 16:16
add R4,R8
; test le reset pour prise en compte immediate du changement de sample
btst #14,R2
store R8,(R7) ; stocke la nouvelle taille
//-> subq #4,R5 ; moved down
jr eq,DSP_LSP_Timer1_noreset3
subqt #4,R5
; reset a travers le dmacon, il faut rafraichir : LSP_DSP_PAULA_internal_location3 & LSP_DSP_PAULA_internal_length3 & LSP_DSP_PAULA_internal_offset3=0
;movei #LSP_DSP_PAULA_internal_location3,R7
;movei #LSP_DSP_PAULA_internal_length3,R8
;store R6,(R7) ; stocke le pointeur sample dans LSP_DSP_PAULA_internal_location3
moveta R6,R1 ; alt R1 = (LSP_DSP_PAULA_internal_location3)
;store R9,(R8) ; stocke la nouvelle taille en 16:16: dans LSP_DSP_PAULA_internal_length3
moveta R9,R3 ; alt R3 = (LSP_DSP_PAULA_internal_length3)
; remplace les 4 octets en stock
move R6,R12
shrq #nb_bits_virgule_offset+2,R12 ; enleve la virgule + 2 bits du bas
;movei #LSP_DSP_PAULA_AUD3DAT,R8
shlq #2,R12
load (R12),R16 ; R16 = 4 octets dispos channel 3
;store R7,(R8)
DSP_LSP_Timer1_noreset3:
DSP_LSP_Timer1_skip3:
;--- test instrument voie 2
movei #LSP_DSP_repeat_pointeur2,R7
btst #13,R2
movei #DSP_LSP_Timer1_skip2,R12
jr ne,DSP_LSP_Timer1_setIns2
btst #12,R2
jump eq,(R12)
nop
; repeat voie 2
load (R7),R3 ; pointeur sauvegardé, sur infos de repeats
addqt #4,r7 ;LSP_DSP_repeat_length2
load (R7),R4
moveta R3,R10
jump (R12) ; jump en DSP_LSP_Timer1_skip3
moveta R4,R9
DSP_LSP_Timer1_setIns2:
loadw (R0),R3 ; offset de l'instrument par rapport au precedent
; addition en .w
; passage en .L
shlq #16,R3
addq #2,R0
sharq #16,R3
add R3,R5 ;R5=pointeur datas instruments
;movei #LSP_DSP_PAULA_AUD2L,R7
loadw (R5),R6
addq #2,R5
shlq #16,R6
loadw (R5),R8
or R8,R6
;movei #LSP_DSP_PAULA_AUD2LEN,R8
shlq #nb_bits_virgule_offset,R6
;store R6,(R7) ; stocke le pointeur sample a virgule dans LSP_DSP_PAULA_AUD2L
moveta R6,R10
addq #2,R5
loadw (R5),R9 ; .w = R9 = taille du sample
shlq #nb_bits_virgule_offset,R9 ; en 16:16
add R6,R9 ; taille devient fin du sample, a virgule
;store R9,(R8) ; stocke la nouvelle fin a virgule
moveta R9,R9
addq #2,R5 ; positionne sur pointeur de repeat
; repeat pointeur
loadw (R5),R4
addq #2,R5
shlq #16,R4
loadw (R5),R8
or R8,R4
addq #2,R5
shlq #nb_bits_virgule_offset,R4
store R4,(R7) ; pointeur sample repeat, a virgule
; repeat length
addqt #4,r7 ;LSP_DSP_repeat_length2
loadw (R5),R8 ; .w = R8 = taille du sample
shlq #nb_bits_virgule_offset,R8 ; en 16:16
add R4,R8
; test le reset pour prise en compte immediate du changement de sample
btst #12,R2
store R8,(R7) ; stocke la nouvelle taille
//-> subq #4,R5 ; moved down
jr eq,DSP_LSP_Timer1_noreset2
subqt #4,R5
; reset a travers le dmacon, il faut rafraichir : LSP_DSP_PAULA_internal_location2 & LSP_DSP_PAULA_internal_length2 & LSP_DSP_PAULA_internal_offset2=0
;movei #LSP_DSP_PAULA_internal_location2,R7
;movei #LSP_DSP_PAULA_internal_length2,R8
;store R6,(R7) ; stocke le pointeur sample dans LSP_DSP_PAULA_internal_location2
moveta R6,R6 ; R6 = (LSP_DSP_PAULA_internal_location2)
;store R9,(R8) ; stocke la nouvelle taille en 16:16: dans LSP_DSP_PAULA_internal_length2
moveta R9,R8
; remplace les 4 octets en stock
move R6,R12
shrq #nb_bits_virgule_offset+2,R12 ; enleve la virgule + 2 bits du bas
;movei #LSP_DSP_PAULA_AUD2DAT,R8
shlq #2,R12
load (R12),R24 ; R24 = 4 octets dispos channel 2
;store R7,(R8)
DSP_LSP_Timer1_noreset2:
DSP_LSP_Timer1_skip2:
;--- test instrument voie 1
movei #LSP_DSP_repeat_pointeur1,R7
btst #11,R2
movei #DSP_LSP_Timer1_skip1,R12
jr ne,DSP_LSP_Timer1_setIns1
btst #10,R2
jump eq,(R12)
nop
; repeat voie 1
load (R7),R3 ; pointeur sauvegardé, sur infos de repeats
addqt #4,r7 ;LSP_DSP_repeat_length1,R4
load (R7),R4
moveta R3,R15
jump (R12) ; jump en DSP_LSP_Timer1_skip1
moveta R4,R14
DSP_LSP_Timer1_setIns1:
loadw (R0),R3 ; offset de l'instrument par rapport au precedent
; addition en .w
; passage en .L
shlq #16,R3
addq #2,R0
sharq #16,R3
add R3,R5 ;R5=pointeur datas instruments
;movei #LSP_DSP_PAULA_AUD1L,R7
loadw (R5),R6
addq #2,R5
shlq #16,R6
loadw (R5),R8
or R8,R6
;movei #LSP_DSP_PAULA_AUD1LEN,R8
shlq #nb_bits_virgule_offset,R6
;store R6,(R7) ; stocke le pointeur sample a virgule dans LSP_DSP_PAULA_AUD1L
moveta R6,R15
addq #2,R5
loadw (R5),R9 ; .w = R9 = taille du sample
shlq #nb_bits_virgule_offset,R9 ; en 16:16
add R6,R9 ; taille devient fin du sample, a virgule
;store R9,(R8) ; stocke la nouvelle fin a virgule
moveta R9,R14
addq #2,R5 ; positionne sur pointeur de repeat
; repeat pointeur
loadw (R5),R4
addq #2,R5
shlq #16,R4
loadw (R5),R8
or R8,R4
addq #2,R5
shlq #nb_bits_virgule_offset,R4
store R4,(R7) ; pointeur sample repeat, a virgule
; repeat length
addqt #4,r7 ;LSP_DSP_repeat_length1
loadw (R5),R8 ; .w = R8 = taille du sample
shlq #nb_bits_virgule_offset,R8 ; en 16:16
add R4,R8
; test le reset pour prise en compte immediate du changement de sample
btst #10,R2
store R8,(R7) ; stocke la nouvelle taille
//-> subq #4,R5
jr eq,DSP_LSP_Timer1_noreset1
subqt #4,R5
; reset a travers le dmacon, il faut rafraichir : LSP_DSP_PAULA_internal_location1 & LSP_DSP_PAULA_internal_length1 & LSP_DSP_PAULA_internal_offset1=0
;movei #LSP_DSP_PAULA_internal_location1,R7
;movei #LSP_DSP_PAULA_internal_length1,R8
;store R6,(R7) ; stocke le pointeur sample dans LSP_DSP_PAULA_internal_location1
moveta R6,R11 ; alt R11 = (LSP_DSP_PAULA_internal_location1)
;store R9,(R8) ; stocke la nouvelle taille en 16:16: dans LSP_DSP_PAULA_internal_length1
moveta R9,R13
; remplace les 4 octets en stock
move R6,R12
shrq #nb_bits_virgule_offset+2,R12 ; enleve la virgule + 2 bits du bas
;movei #LSP_DSP_PAULA_AUD1DAT,R8
shlq #2,R12
load (R12),R25 ; R25 = 4 octets dispos channel 1
; store R7,(R8)
DSP_LSP_Timer1_noreset1:
DSP_LSP_Timer1_skip1:
;--- test instrument voie 0
movei #LSP_DSP_repeat_pointeur0,R7
btst #9,R2
movei #DSP_LSP_Timer1_skip0,R12
jr ne,DSP_LSP_Timer1_setIns0
btst #8,R2
jump eq,(R12)
nop
; repeat voie 0
load (r7),R3 ; pointeur sauvegardé, sur infos de repeats
addqt #4,r7 ;LSP_DSP_repeat_length0,R4
load (R7),R4
moveta R3,R20
jump (R12) ; jump en DSP_LSP_Timer1_skip0
moveta R4,R19
DSP_LSP_Timer1_setIns0:
loadw (R0),R3 ; offset de l'instrument par rapport au precedent