-
Notifications
You must be signed in to change notification settings - Fork 0
/
P6112-Play.i
4058 lines (3827 loc) · 86.3 KB
/
P6112-Play.i
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
; #-----+-----------------------------------------#
; |Name:| P6112 - Optimized Player 6.1 Playroutine|
; +-----+-----------------------------------------+
; |V1.06| P6112,E1x/E2x fix |
; |V1.05| P6111, EDx fix,better init/exit,Dxx note|
; |V1.04| P6110, E6x command fix+new option |
; |V1.03| P6109, compatibility changes only. |
; |V1.02| Cleaned up P6108 with minor changes. |
; |V1.01| 2.4-3 scanlines faster than my p6107. |
; | | SLen (song length) bug fixed |
; | | lev6 implemented with "poke DMA here" |
; | | Two options for clickless sound start |
; | | P61_Osc precis samplewindow tracking |
; | | Many optimization options - read the |
; | | info or leave them at defaults. |
; +-----+-----------------------------------------+
; | by Photon/Scoopex |
; #-----------------------------------------------#
;SPECIAL NOTE FOR THIS VERSION:
;-----------------------------
;Tutorial here: http://youtu.be/xBtHO-IuN9E
;Put it in your demo: http://youtu.be/JYLcIR6tyO4
;I'm leaving the P61 project, feeling I've left it in good shape.
;There is nothing left to optimize, and I've gone through everything I could
;find that was bad and fixed it.
;I support this only with the readme.txt and all the comment documentation.
;Please follow the advice in my Youtube tutorial specifically made for adding
;P61 to your demo before deciding the playroutine is at fault. If you are sure
;you have found a bug, fix it yourself.
;A song must fail in the example source and play correctly in P61con, before
;you can suspect the playroutine is at fault.
;A note on syncing: apart from the new options for $1Fx, channel triggers, and
;oscilloscope ptrs I added, you should no longer ask musicians to scatter E8x
;commands in the song. Don't worry, it plays fine in P61 and always has.
;But some non-legacy trackers destroy the loop with a filter where E8x commands
;are used. 80x is an alternative, which works in all trackers, according to
;them. To use it, just replace E8x with 80x in the module and you need change
;nothing else.
;P6112:
;E1x/E2x fix. One line changed in the source, in the GetNote macro used by
;these two effects combined with a note trigger (i.e. for F-3 E1x, not --- E1x)
;P6111:
;- Fix notedelay bug introduced in P6108
;- Fix in legacy code, CIA regs were modified in init/exit even when p61_cia=0.
;- Verified that $9xx offset behavior takes effect at loop end, a behavior
;used by chip musicians.
;Dxx command: P61 has never implemented Dxx support other than for xx=00.
;I took a good look, and the way I see it, only pointers to previously
;decrunched notesteps are stored. This means patternloop backjumps work, but
;forward jumps to some offset from the pattern start pointer - doesn't.
;xx steps must first be decrunched. This will cause a spike in rastertime
;(CPU load) used, which is counter to my efforts to make the P61 playroutine
;match the performance of optimized normal Protracker playroutines.
;So I've decided to not implement it. Instead, musicians are recommended to
;copy the jumped-to pattern and delete xx notes to make the offset=0. Then
;the Dxx command can be changed to a D00 command, which is supported.
;The copied pattern will only add 16 bytes or so to the filesize, and
;performance will remain excellent.
;---
;P6110: A bug regarding Patternloops (E6x) was introduced in P6108 when I added
;super optimization flags. This is fixed, but it also revealed the obvious:
;that Patternloop is incompatible with suppF01=0. The example will set this
;automatically for you, but you will not get the great speed gains if you try
;split4=1 unless you SET THE USECODE PROPERLY.
;Of course all modes will work properly if you leave everything at default
;in the example, but I recommend to set the usecode to get the most out of p61
; - not just the size gain.
;Also, new option: set visuctrs=1 to get elapsed time since last instrument
;trigger in P61visuctr0..3.
;NOTE: vasm users MUST turn optimizations off for the jmp xx(PC) instructions
;in the jump tables and at P61_motuuli. If not, the source will assemble
;without errors, but generate bra.b which WILL cause fatal run-time errors.
;May the Source be with you! //Photon
;Credits to Jarno for V6.1A, and bugfixers up to 6.1.0.6.
;(Notes from previous versions below.)
* The Player 6.1A - by Guru / Sahara Surfers
* Interrupt problem with 060 fixed by NoName/Haujobb^Sector 7
* Some Enforcer Hits fixed by Platon42
* Memory trashing bug in routine P61_End fixed by Tolkien
* Bug in routine P61_Init (when opt020=1) fixed by The Dark Coder/Trinity^Morbid Visions
* for Devpac 3, ASM-One, PhxAss and maybe some other assemblers
*
* NEEDS: Default sizes must be words (ASM-One default...)
* Preferably no optimizations on (the jump table must be word jumps)
*
* Tested with Devpac 3.04 by Guru
* Tested with PhxAss 4.14, Asm-Pro 1.1 and ASM-One 1.29
*
* Note 1:All the bugfixes done after version 610.2 (the latest release from
* Guru / Sahara Surfers) are marked with the comment "* BUGFIX"
* followed by some explanations, so that if can quickly copy them
* into a previous version tailored to your needs.
*
* Note 2:The unelegant double WRITE to INTREQ unforunately seems to be
* the best solution to the "interrupt problem" that occurs on
* some 040/060 equipped Amiga. On many 040/060 Amigas it is enough
* to put an access to whatever hardware register and a NOP between
* the first write to INTREQ and he RTE. However we had reports that
* on some Amiga it is really necessary to do a double write to INTREQ
********************************
* Player 6.1A � *
* All in one-version *
* Version 610.6 *
* � 1992-95 Jarno Paananen *
* All rights reserved *
* Fixed by: NoName, Platon42, *
* Tolkien and The Dark Coder *
********************************
nowaveforms=noshorts
copdma=1-lev6
Custom_Block_Size=16 ;d7 used to replace clr.* instead of this const
ifnd player61_i
player61_i:set 1
ifnd exec_types_i
exec_types_i:set 1
include_version:equ 40
extern_lib:macro
xref _lvo\1
endm
structure:macro
\1:equ 0
soffset:set \2
endm
fptr:macro
\1:equ soffset
soffset:set soffset+4
endm
bool:macro
\1:equ soffset
soffset:set soffset+2
endm
byte:macro
\1:equ soffset
soffset:set soffset+1
endm
ubyte:macro
\1:equ soffset
soffset:set soffset+1
endm
word:macro
\1:equ soffset
soffset:set soffset+2
endm
uword:macro
\1:equ soffset
soffset:set soffset+2
endm
short:macro
\1:equ soffset
soffset:set soffset+2
endm
ushort:macro
\1:equ soffset
soffset:set soffset+2
endm
long:macro
\1:equ soffset
soffset:set soffset+4
endm
ulong:macro
\1:equ soffset
soffset:set soffset+4
endm
float:macro
\1:equ soffset
soffset:set soffset+4
endm
double:macro
\1:equ soffset
soffset:set soffset+8
endm
aptr:macro
\1:equ soffset
soffset:set soffset+4
endm
cptr:macro
\1:equ soffset
soffset:set soffset+4
endm
rptr:macro
\1:equ soffset
soffset:set soffset+2
endm
label:macro
\1:equ soffset
endm
struct:macro
\1:equ soffset
soffset:set soffset+\2
endm
alignword:macro
soffset:set (soffset+1)&$fffffffe
endm
alignlong:macro
soffset:set (soffset+3)&$fffffffc
endm
enum:macro
ifc '\1',''
eoffset:set 0
endc
ifnc '\1',''
eoffset:set \1
endc
endm
eitem:macro
\1:equ eoffset
eoffset:set eoffset+1
endm
bitdef0:macro
\1\3\2:equ \4
endm
bitdef:macro
bitdef0 \1,\2,b_,\3
\@bitdef:set 1<<\3
bitdef0 \1,\2,f_,\@bitdef
endm
library_minimum:equ 33
endc ;ifnd
structure Player_Header,0
ulong P61_InitOffset
ulong P61_MusicOffset
ulong P61_EndOffset
ulong P61_SetRepeatOffset
ulong P61_SetPositionOffset
uword P61_MasterVolume
uword P61_UseTempo
uword P61_PlayFlag
uword P61_E8_info
aptr P61_UseVBR
uword P61_Position
uword P61_Pattern
uword P61_Row
aptr P61_Cha0Offset
aptr P61_Cha1Offset
aptr P61_Cha2Offset
aptr P61_Cha3Offset
label Player_Header_SIZE
structure Channel_Block,0
ubyte P61_SN_Note
ubyte P61_Command
ubyte P61_Info
ubyte P61_Pack
aptr P61_Sample
uword P61_OnOff
aptr P61_ChaPos
aptr P61_TempPos
uword P61_TempLen
uword P61_Note
uword P61_Period
uword P61_Volume
uword P61_Fine
uword P61_Offset
uword P61_LOffset
uword P61_ToPeriod
uword P61_TPSpeed
ubyte P61_VibCmd
ubyte P61_VibPos
ubyte P61_TreCmd
ubyte P61_TrePos
uword P61_RetrigCount
ubyte P61_Funkspd
ubyte P61_Funkoff
aptr P61_Wave
uword P61_TData
aptr P61_TChaPos
aptr P61_TTempPos
uword P61_TTempLen
uword P61_Shadow
ifne oscillo ;Filled in by P61_osc call (div ptrs by 4)
aptr P61_oscptr ;points to end of current frame's sample-chunk.
uword P61_oscptrrem ;remainder for precision (internal use only)
aptr P61_oscptrWrap ;wrap (end) pointer for current Paula soundloop
endc
uword P61_DMABit
label Channel_Block_Size
structure Sample_Block,0
aptr P61_SampleOffset
uword P61_SampleLength
aptr P61_RepeatOffset
uword P61_RepeatLength
uword P61_SampleVolume
uword P61_FineTune
label Sample_Block_SIZE
P61_ft=usecode&1
P61_pu=usecode&2
P61_pd=usecode&4
P61_tp=usecode&40
P61_vib=usecode&80
P61_tpvs=usecode&32
P61_vbvs=usecode&64
P61_tre=usecode&$80
P61_arp=usecode&$100
P61_sof=usecode&$200
P61_vs=usecode&$400
P61_pj=usecode&$800
P61_vl=usecode&$1000
P61_pb=usecode&$2800
P61_sd=usecode&$8000
P61_ec=usecode&$ffff0000
P61_fi=usecode&$10000
P61_fsu=usecode&$20000
P61_fsd=usecode&$40000
P61_sft=usecode&$200000
P61_pl=usecode&$400000&((1-split4)*$400000) ;incompatible with split4.
P61_timing=usecode&$1000000
P61_rt=usecode&$2000000
P61_fvu=usecode&$4000000
P61_fvd=usecode&$8000000
P61_nc=usecode&$10000000
P61_nd=usecode&$20000000
P61_pde=usecode&$40000000
P61_il=usecode&$80000000
endc
ifne asmonereport
********** REPORT **********
printt ""
printt "Options used:"
printt "-------------"
ifne p61fade
printt "Mastervolume on"
else
printt "Mastervolume off"
endc
ifne p61system
printt "System friendly"
else
printt "System killer"
endc
ifne p61cia
printt "CIA-tempo on"
else
printt "CIA-tempo off"
endc
ifne p61exec
printt "ExecBase valid"
else
printt "ExecBase invalid"
endc
;; --- wicked nasty nested ifs ---
ifne lev6
printt "Level 6 IRQ on"
else
ifeq (noshorts&(1-p61system))
printt "FAIL: Non-lev6 NOT available for p61system=1 or noshorts=0!"
else
printt "Non-lev6 implemented with 'poke DMAbits byte to a specified address'."
printt "* READ DOCS for how to specify it and how it works."
endc ;noshorts&(1-p61system)
endc ;lev6
;; --- end of wicked nasty nested ifs ---
ifne opt020
printt "MC68020 optimizations"
else
printt "Normal MC68000 code"
endc
printt "Channels:"
printv channels
ifgt channels-4
printt "FAIL: More than 4 channels."
endc
ifeq channels
printt "FAIL: Can't have 0 channels."
endc
printt "UseCode:"
printv usecode
printt "Player binary size:"
printv P61E-P61B
********** REPORT END **********
endc ;ifne asmonereport
P61B:
P61_motuuli:
jmp P61_Init(PC)
ifeq p61cia
jmp P61_Music(PC)
else
rts
rts
endc
jmp P61_End(PC)
rts ;no P61_SetRepeat
rts
ifne p61jump
jmp P61_SetPosition(PC)
else
rts
rts
endc
P61_Master:
dc.w 64
P61_Tempo:
dc.w 1
P61_Play:
dc.w 1
P61_E8:
dc.w 0
P61_VBR:
dc.l 0
P61_Pos:
dc.w 0
P61_Patt:
dc.w 0
P61_CRow:
dc.w 0
P61_Temp0Offset:
dc.l P61_temp0-P61_motuuli
P61_Temp1Offset:
dc.l P61_temp1-P61_motuuli
P61_Temp2Offset:
dc.l P61_temp2-P61_motuuli
P61_Temp3Offset:
dc.l P61_temp3-P61_motuuli
P61_getnote:macro
moveq #$7e,d0
and.b (a5),d0
beq.b .nonote
ifne P61_vib
clr.b P61_VibPos(a5)
endc
ifne P61_tre
clr.b P61_TrePos(a5)
endc
ifne P61_ft
add P61_Fine(a5),d0
endc
move d0,P61_Note(a5)
move P61_periods-P61_cn(a3,d0),P61_Period(a5) ;P6112 fix.
.nonote:
endm
ifeq p61system
ifne p61cia
P61_intti:
movem.l d0-a6,-(sp)
tst.b $bfdd00
lea $dff000+C,a6
move #$2000,$9c-C(a6)
move #$2000,$9c-C(a6)
bsr P61_Music
movem.l (sp)+,d0-a6
nop
rte
endc
endc
ifne p61system
P61_lev6server:
movem.l d2-d7/a2-a6,-(sp)
lea P61_timeron(pc),a0
tst (a0)
beq.b P61_ohi
lea $dff000+C,a6
move P61_server(pc),d0
beq.b P61_musica
subq #1,d0
beq P61_dmason
ifeq nowaveforms
bra P61_setrepeat
else
bra.b P61_ohi
endc
P61_musica:
bsr P61_Music
P61_ohi:
movem.l (sp)+,d2-d7/a2-a6
moveq #1,d0
rts
endc
********** P61_Init **********
* Input: A0=P61-module addr.
* A1 [LONG] = 0 if samples are internal to the module
* Address of samples otherwise
* A2 [LONG] = Address of sample buffer if the module uses packed
* samples, otherwise can be left uninitialized
* A4 [LONG] = Address where 'DMA ON' byte (low 8 bits of DMACON)
* should be poked. ONLY used together with lev6=0.
* D0 [WORD] = 0 autodetect CIA Timer frequency, if ExecBase
* is valid otherwise assume PAL
* 1 assume PAL
* 2 assume NTSC
* [Used only in CIA-enabled mode]
* Uses: D0-A7, A6 set to $dff000+C (your custombase) at exit.
* Returns: D0=0 if okay (i.e. P61 module!). No need to change D0.l.
* NOTE: the define 'start' has been made runtime. move.w #<startpos>,P61_InitPos instead.
P61_Init:
lea $dff000+C,a6
ifeq p61system
ifne quietstart
move.w #$f,$96-C(A6) ;audiodma off
lea $a0-C(A6),a5 ;chan 0
lea P61_Quiet(PC),a3
moveq #0,d1
moveq #channels-1,d5
.choffl:move.l a3,(a5)+ ;ptr
move.l #1<<16+124,(a5)+ ;len, 'fastest common' period
move.l d1,(a5)+ ;quiet volume & audchan.
addq.w #4,a5
dbf d5,.choffl
endc
endc
cmp.l #"P61A",(a0)+
beq.b .modok
subq.l #4,a0
.modok:
ifne p61cia
move d0,-(sp)
endc
moveq #0,d0
cmp.l d0,a1
bne.b .redirect
move (a0),d0
lea (a0,d0.l),a1
.redirect:
move.l a2,a6
lea 8(a0),a2
moveq #$40,d0
and.b 3(a0),d0
bne.b .buffer
move.l a1,a6
subq.l #4,a2
.buffer:
lea P61_cn(pc),a3
move.w #$ff00,d1
move.w d1,P61_OnOff+P61_temp0-P61_cn(a3) ;stop active decsteps
move.w d1,P61_OnOff+P61_temp1-P61_cn(a3)
move.w d1,P61_OnOff+P61_temp2-P61_cn(a3)
move.w d1,P61_OnOff+P61_temp3-P61_cn(a3)
ifne copdma
move.l a4,p61_DMApokeAddr-P61_cn(a3)
endc
moveq #$1f,d1
and.b 3(a0),d1
move.l a0,-(sp)
;; --- insert pan/echo in this loop ---
lea P61_samples(pc),a4
subq #1,d1
moveq #0,d4
P61_lopos:
move.l a6,(a4)+
move (a2)+,d4
bpl.b P61_kook
neg d4
lea P61_samples-16(pc),a5
ifeq opt020
asl #4,d4
move.l (a5,d4),d6
else
add d4,d4
move.l (a5,d4*8),d6
endc
move.l d6,-4(a4)
ifeq opt020
move 4(a5,d4),d4
else
move 4(a5,d4*8),d4
endc
sub.l d4,a6
sub.l d4,a6
bra.b P61_jatk
P61_kook:
move.l a6,d6
tst.b 3(a0)
bpl.b P61_jatk
tst.b (a2)
bmi.b P61_jatk
move d4,d0
subq #2,d0
bmi.b P61_jatk
move.l a1,a5
move.b (a5)+,d2
sub.b (a5),d2
move.b d2,(a5)+
.loop:sub.b (a5),d2
move.b d2,(a5)+
sub.b (a5),d2
move.b d2,(a5)+
dbf d0,.loop
P61_jatk:
move d4,(a4)+
moveq #0,d2
move.b (a2)+,d2
moveq #0,d3
move.b (a2)+,d3
moveq #0,d0
move (a2)+,d0
bmi.b .norepeat
move d4,d5
sub d0,d5
move.l d6,a5
add.l d0,a5
add.l d0,a5
move.l a5,(a4)+
move d5,(a4)+
bra.b P61_gene
.norepeat:
move.l d6,(a4)+
move #1,(a4)+
P61_gene:
move d3,(a4)+
moveq #$f,d0
and d2,d0
mulu #74,d0
move d0,(a4)+
tst -6(a2)
bmi.b .nobuffer
moveq #$40,d0
and.b 3(a0),d0
beq.b .nobuffer
move d4,d7
tst.b d2
bpl.b .copy
subq #1,d7
moveq #0,d5
moveq #0,d4
.lo: move.b (a1)+,d4
moveq #$f,d3
and d4,d3
lsr #4,d4
sub.b .table(pc,d4),d5
move.b d5,(a6)+
sub.b .table(pc,d3),d5
move.b d5,(a6)+
dbf d7,.lo
bra.b .kop
.copy:
add d7,d7
subq #1,d7
.cob:
move.b (a1)+,(a6)+
dbf d7,.cob
bra.b .kop
.table:
dc.b 0,1,2,4,8,16,32,64,128,-64,-32,-16,-8,-4,-2,-1
.nobuffer:
move.l d4,d6
add.l d6,d6
add.l d6,a6
add.l d6,a1
.kop:
dbf d1,P61_lopos
move.l (sp)+,a0
and.b #$7f,3(a0)
move.l a2,-(sp)
lea P61_temp0(pc),a1
lea P61_temp1(pc),a2
lea P61_temp2(pc),a4
lea P61_temp3(pc),a5
moveq #Channel_Block_Size/2-2,d0
moveq #0,d1
.cl: move d1,(a1)+
move d1,(a2)+
move d1,(a4)+
move d1,(a5)+
dbf d0,.cl
lea P61_temp0-P61_cn(a3),a1
lea P61_emptysample-P61_cn(a3),a2
moveq #channels-1,d0
.loo:
move.l a2,P61_Sample(a1)
lea Channel_Block_Size(a1),a1
dbf d0,.loo
move.l (sp)+,a2
move.l a2,P61_positionbase-P61_cn(a3)
moveq #$7f,d1
and.b 2(a0),d1
ifeq opt020
lsl #3,d1
lea (a2,d1.l),a4
else
lea (a2,d1.l*8),a4
endc
move.l a4,P61_possibase-P61_cn(a3) ;base to pos. indices.
move.l a4,a1
moveq #-1,d0
.search:
cmp.b (a1)+,d0
bne.b .search
move.l a1,P61_patternbase-P61_cn(a3)
move.l a1,d0
sub.l a4,d0
subq.w #1,d0 ;this is the * BUGFIX! whoa!
move d0,P61_slen-P61_cn(a3)
;; --- Bugfix: P61_Init gives P61_slen=actual songlength +1.
;; --- This did not affect NextPattern, because it looks for endbyte flag.
;; --- It did affect Bxx/Dxx, but I guess nobody has tried to jump or
;; --- break to Last Pattern, ever. Now fixed to set correct SLen and
;; --- suddenly Bxx/Dxx/Setposition works as they should. //Photon
add.w P61_InitPos(pc),a4 ;position from which to start playing the song
moveq #0,d0
move.b (a4)+,d0
move.l a4,P61_spos-P61_cn(a3)
lsl #3,d0
add.l d0,a2
move.l a1,a4
moveq #0,d0 ;hi word must be clear to manage >32K of patterns
move (a2)+,d0 ;and no movem-signextend. This code is correct.
lea (a4,d0.l),a1
move.l a1,P61_ChaPos+P61_temp0-P61_cn(a3)
move (a2)+,d0
lea (a4,d0.l),a1
move.l a1,P61_ChaPos+P61_temp1-P61_cn(a3)
move (a2)+,d0
lea (a4,d0.l),a1
move.l a1,P61_ChaPos+P61_temp2-P61_cn(a3)
move (a2)+,d0
lea (a4,d0.l),a1
move.l a1,P61_ChaPos+P61_temp3-P61_cn(a3)
ifeq nowaveforms
lea P61_setrepeat(pc),a0
move.l a0,P61_intaddr-P61_cn(a3)
endc
move #63,P61_rowpos-P61_cn(a3)
move #6,P61_speed-P61_cn(a3)
move #5,P61_speed2-P61_cn(a3)
clr P61_speedis1-P61_cn(a3)
ifne P61_pl
clr.l P61_plcount-P61_cn(a3)
endc
ifne P61_pde
clr P61_pdelay-P61_cn(a3)
clr P61_pdflag-P61_cn(a3)
endc
clr (a3) ;start frame of very first song note.
;"reused" patterns with effects coming out of nowhere
;at start of song require 0. Otherwise F0x speed-2 is
;ok, except if split4=1, set to F-speed - #channels.
;Don't change if you don't need 'the very quickest click to start' speed.
moveq #2,d0
and.b $bfe001,d0
move.b d0,P61_ofilter-P61_cn(a3)
bset #1,$bfe001
ifeq p61system
ifne p61exec
move.l 4.w,a6
moveq #0,d0
btst d0,297(a6)
beq.b .no68010
lea P61_liko(pc),a5
jsr -$1e(a6)
.no68010:
move.l d0,P61_VBR-P61_cn(a3)
endc
move.l P61_VBR-P61_cn(a3),a0
lea $78(a0),a0
move.l a0,P61_vektori-P61_cn(a3)
move.l (a0),P61_oldlev6-P61_cn(a3)
ifeq copdma
lea P61_dmason(pc),a1 ;set 'dma-on-interrupt'.
move.l a1,(a0)
endc
endc
moveq #$f,d0
lea $dff000+C,a6 ;a6 trashed above.
ifeq quietstart
moveq #$0,d1 ;original code
move d1,$a8-C(a6)
move d1,$b8-C(a6)
move d1,$c8-C(a6)
move d1,$d8-C(a6)
move d0,$96-C(a6)
endc
ifne nowaveforms
move.w d0,P61_NewDMA-P61_cn(a3) ;"NEXTframe setloop" to be triggered
endc
ifeq p61system
ifeq copdma
lea P61_dmason(pc),a1 ;again?
move.l a1,(a0)
endc
move #$2000,$9a-C(a6) ;old timerb OFF
lea $bfd000,a0
lea P61_timers(pc),a1
move.b #$7f,$d00(a0)
ifne p61cia ;only affect cia if actually used
move.b #$10,$e00(a0)
endc
move.b #$10,$f00(a0)
ifne p61cia
move.b $400(a0),(a1)+
move.b $500(a0),(a1)+
else
addq.w #2,a1
endc
move.b $600(a0),(a1)+
move.b $700(a0),(a1)
endc
ifeq (p61system+p61cia)
move.b #$82,$d00(a0)
endc
ifne p61cia
move (sp)+,d0
subq #1,d0
beq.b P61_ForcePAL
subq #1,d0
beq.b P61_NTSC
ifne p61exec
move.l 4.w,a1
cmp.b #60,$213(a1)
beq.b P61_NTSC
endc
P61_ForcePAL:
move.l #1773447,d0
bra.b P61_setcia
P61_NTSC:
move.l #1789773,d0
P61_setcia:
move.l d0,P61_timer-P61_cn(a3)
divu #125,d0
move d0,P61_thi2-P61_cn(a3)
sub #$1f0*2,d0
move d0,P61_thi-P61_cn(a3)
ifeq p61system
move P61_thi2-P61_cn(a3),d0
move.b d0,$400(a0)
lsr #8,d0
move.b d0,$500(a0)
lea P61_intti(pc),a1
move.l a1,P61_tintti-P61_cn(a3)
move.l P61_vektori(pc),a2
move.l a1,(a2)
move.b #$83,$d00(a0)
move.b #$11,$e00(a0)
endc
endc
ifeq p61system
ifeq copdma
move #$e000,$9a-C(a6) ;level 6 timer B int, at least for setloop
else
move #$c000,$9a-C(a6) ;no level 6 timer B int, please
;(bit 14 is cleared above.)
endc
ifne quietstart
move.w #$800f,$96-C(A6) ;make all used channels start a quiet loop.
endc
moveq #0,d0
rts
ifne p61exec
P61_liko:
dc.l $4E7A0801
rte
endc
endc
ifne p61system
move.l a6,-(sp)
ifne p61cia
clr P61_server-P61_cn(a3)
else
move #1,P61_server-P61_cn(a3)
endc
move.l 4.w,a6
moveq #-1,d0
jsr -$14a(a6)
move.b d0,P61_sigbit-P61_cn(a3)
bmi P61_err
lea P61_allocport(pc),a1
move.l a1,P61_portti-P61_cn(a3)
move.b d0,15(a1)
move.l a1,-(sp)
suba.l a1,a1
jsr -$126(a6)
move.l (sp)+,a1
move.l d0,16(a1)
lea P61_reqlist(pc),a0
move.l a0,(a0)
addq.l #4,(a0)
clr.l 4(a0)
move.l a0,8(a0)
lea P61_dat(pc),a1
move.l a1,P61_reqdata-P61_cn(a3)
lea P61_allocreq(pc),a1
lea P61_audiodev(pc),a0
moveq #0,d0
moveq #0,d1
jsr -$1bc(a6)
tst.l d0
bne P61_err
st.b P61_audioopen-P61_cn(a3)
lea P61_timerint(pc),a1
move.l a1,P61_timerdata-P61_cn(a3)
lea P61_lev6server(pc),a1
move.l a1,P61_timerdata+8-P61_cn(a3)
moveq #0,d3
lea P61_cianame(pc),a1
P61_openciares:
moveq #0,d0
move.l 4.w,a6
jsr -$1f2(a6)
move.l d0,P61_ciares-P61_cn(a3)
beq.b P61_err
move.l d0,a6
lea P61_timerinterrupt(pc),a1
moveq #0,d0
jsr -6(a6)
tst.l d0
beq.b P61_gottimer
addq.l #4,d3
lea P61_timerinterrupt(pc),a1
moveq #1,d0
jsr -6(a6)
tst.l d0
bne.b P61_err
P61_gottimer:
lea P61_craddr+8(pc),a6
move.l P61_ciaaddr(pc,d3),d0
move.l d0,(a6)
sub #$100,d0
move.l d0,-(a6)
moveq #2,d3
btst #9,d0
bne.b P61_timerB
subq.b #1,d3
add #$100,d0
P61_timerB:
add #$900,d0
move.l d0,-(a6)
move.l d0,a0
and.b #%10000000,(a0)
move.b d3,P61_timeropen-P61_cn(a3)
moveq #0,d0
ifne p61cia
move.l P61_craddr+4(pc),a1
move.b P61_tlo(pc),(a1)
move.b P61_thi(pc),$100(a1)
endc