1MONO = 1
2STEREO = 2
3SURROUND = 3
4REAL = 4
5STEREO14 = 5
6
7BUFFER	equ	32*1024		;Audio mixing buffer size is 32K.
8
9
10_ciaa	=	$bfe001
11_ciab	=	$bfd000
12
13	incdir	amiga:includes/
14	include	heikki/RMacros.i
15	include	heikki/custom.i
16	include	exec/exec.i
17	include	hardware/cia.i
18	include	misc/deliplayer.i
19	include	misc/DevpacMacros.i
20
21	incdir amiga:work/players/mld/s3m/
22	include	"ps3m.i"
23
24
25	section	ps3m_player,code
26	moveq	#-1,d0
27	rts
28	dc.b	'EPPLAYER'
29	dc.l	table
30	even
31
32table	dc.l	DTP_PlayerName,ps3mname
33	dc.l	DTP_ModuleName,MNamePTR
34	dc.l	DTP_FormatName,FNamePTR
35	dc.l	DTP_Creator,ps3mcreator
36	dc.l	DTP_DeliBase,eaglebase
37	dc.l	DTP_Check2,Check2
38;	dc.l	DTP_SubSongRange,SubSongRange
39	dc.l	DTP_InitPlayer,InitPlayer
40	dc.l	DTP_InitSound,InitSound
41	dc.l	DTP_StartInt,StartInt
42	dc.l	DTP_StopInt,StopInt
43	dc.l	DTP_EndSound,EndSound
44	dc.l	DTP_EndPlayer,EndPlayer
45	dc.l	$80004474,2			* songend support
46	dc.l	0
47uadename	dc.b	'uade.library',0
48ps3mcreator
49	dc.b	'Eagleplayer for Multichannel PC-Tracker files V0.3 (12.05.2005)',10,10
50	dc.b	'based on PS3M player 3.13 (c) by Jarno Paananen',10
51	dc.b	'Screamtracker 3 - (c) 93/94 Sami Tammilehto PSI/Future Crew',10
52	dc.b	'Fasttracker1 6/8 Channel - (c) Triton',10
53	dc.b	'Taketracker - (c) Vogue & Mr.H/Triton',10
54	dc.b	'Multitracker - D. Goldstein',10
55	dc.b	'Octalyser (CD81) Atari-ST Tracker',10,10
56	dc.b	'Adapted for UADE by shd and mld',0
57
58ps3mname	dc.b	'PS3M',0
59
60MName
61	ds.b	31
62	dc.b	0
63FName
64	dc.b 'type: '
65FNametype
66	ds.b	31
67	dc.b	0
68	even
69
70
71MNamePTR	dc.l	MName
72FNamePTR	dc.l	FName
73eaglebase	dc.l	0
74moduleptr	dc.l	0
75mixing_mode	dc.l	STEREO
76mixing_rate	dc.l	14000
77volume_boost	dc.l	0
78uadebase	dc.l	0
79end_song_bit	dc.l	0
80
81Check2	move.l	dtg_ChkData(a5),a0
82	move.l	a0,moduleptr
83	bsr	CheckSong
84	rts
85
86cfgfile	dc.b	'ENV:EaglePlayer/EP-S3M.cfg',0
87	even
88cfgbuffer	ds.b	256
89
90* sample cfgfile format:
91* 1
92* 14000
93* 2
94*
95* 1 means mono (2 would mean stereo)
96* 14000 is mixing rate
97* 2 is volume boost (in range 0-8)
98
99InitPlayer	push	all
100	move.l	dtg_AudioAlloc(a5),A0
101	jsr	(A0)
102
103	move.l	4.w,a6
104	lea	uadename,a1
105	moveq	#0,d0
106	jsr	_LVOOpenLibrary(a6)
107	move.l	d0,uadebase
108
109	bsr	uade_time_critical_on
110
111	move.l	dtg_DOSBase(a5),a6
112	move.l	#cfgfile,d1
113	move.l	#1005,d2		* MODE_OLDFILE
114	jsr	_LVOOpen(a6)
115	move.l	d0,d1
116	beq	dont_read_cfgfile
117	move.l	d1,-(a7)
118	move.l	#cfgbuffer,d2
119	move.l	#256,d3
120	jsr	_LVORead(a6)
121	push	all
122	lea	cfgbuffer,a0
123
124	move.b	(a0)+,d0
125	sub.b	#$30,d0
126	and.l	#$7,d0
127	move.l	d0,mixing_mode
128
129	move.b	(a0)+,d0
130	cmp.b	#10,d0
131	bne.b	illegal_config_file
132
133	moveq	#0,d0
134	moveq	#0,d1
135digit_loop	move.b	(a0)+,d1
136	cmp.b	#10,d1
137	beq.b	end_digit_loop
138	cmp.b	#$20,d1
139	beq.b	end_digit_loop
140	cmp	#$30,d1
141	blt.b	illegal_config_file
142	cmp	#$39,d1
143	bgt.b	illegal_config_file
144	sub.b	#$30,d1
145	mulu	#10,d0
146	add.b	d1,d0
147	bra.b	digit_loop
148end_digit_loop	move.l	d0,mixing_rate
149
150	moveq	#3-1,d7
151volume_boost_l	move.b	(a0)+,d0
152	moveq	#$f,d1
153	and.l	d0,d1
154	and	#$f0,d0
155	cmp	#$30,d0
156	bne.b	not_a_digit
157	move.l	d1,volume_boost
158	moveq	#0,d7
159not_a_digit	dbf	d7,volume_boost_l
160
161illegal_config_file
162	pull	all
163	move.l	(a7)+,d1
164	jsr	_LVOClose(a6)
165dont_read_cfgfile
166	pull	all
167	moveq	#0,d0
168	rts
169
170report_song_end	push	all
171	st	end_song_bit
172	move.l	eaglebase,a5
173	move.l	dtg_SongEnd(a5),a0
174	jsr	(a0)
175	pull	all
176	rts
177
178EndSound	push	all
179	lea	$dff000,a2
180	moveq	#0,d0
181	move	d0,aud0vol(a2)
182	move	d0,aud1vol(a2)
183	move	d0,aud2vol(a2)
184	move	d0,aud3vol(a2)
185	move	#$000f,dmacon(a2)
186	pull	all
187	rts
188
189EndPlayer	move.l	dtg_AudioFree(a5),A0
190	jsr	(a0)
191	rts
192
193
194CheckSong
195	move.l	moduleptr,a0
196	;moveq	#0,d0
197	;move	dtg_SndNum(a5),d0
198	bsr	init
199	rts
200check_failed	moveq	#-1,d0
201	rts
202
203
204	* a0 pointer to the module
205InitSound
206
207	clr.l	uade_restart_cmd
208	clr.l	uade_stop_cmd
209	clr.l	end_song_bit
210
211	rts
212
213StartInt	push	all
214	* d1 mixing mode (MONO, STEREO, ...)
215	* d2 mixing rate
216	* d3 volume boost (0-8)
217	** "playmode" is one of the following:
218	**	"STEREO14", "STEREO", "SURROUND", "REAL", "MONO".
219	**
220	** The maximum rate for the system is 28000 (28KHZ), and going above
221	** or below this limit will cause either slowdown or skipping of the
222	** sample mixing, so don't go above those limits.
223	move.l	mixing_mode,d1		;Set the playmode to STANDARD STEREO.
224	move.l	mixing_rate,d2		;Set the mixing rate to nnn Khz.
225	move.l	volume_boost,d3		;Set volume boost up to 8.
226	bsr	start_interrupt
227	pull	all
228	rts
229
230StopInt	push	all
231	bsr	stop_interrupt
232	pull	all
233	rts
234
235uade_time_critical_on
236	pushr	d0
237	move.l	uadebase,d0
238	beq.b	no_uade_1
239	push	all
240	move.l	d0,a6
241	moveq	#-1,d0
242	jsr	-6(a6)
243	pull	all
244no_uade_1	pullr	d0
245	rts
246
247uade_time_critical_off
248	pushr	d0
249	move.l	uadebase,d0
250	beq.b	no_uade_2
251	push	all
252	move.l	d0,a6
253	moveq	#0,d0
254	jsr	-6(a6)
255	pull	all
256no_uade_2	pullr	d0
257	rts
258
259;PS3M Replay version 0.942/020+ / 30.10.1994
260;Copyright (c) Jarno Paananen a.k.a. Guru / S2 1994-95
261
262;Some portions based on STMIK 0.9� by Sami Tammilehto / PSI of Future Crew
263
264;ASM-ONE 1.20 or newer is required unless disable020 is set to 1, when
265;at least 1.09 (haven't tried older) is sufficient.
266
267*****************************************************************************
268** Contraption by K-P / HpD / iNS (14.12.1995)
269** What's left: killermode, 000/020+ mixingroutines, all 5 playmodes, and
270** the S3M replayer.
271*****************************************************************************
272
273;---- CIA Interrupt ----
274
275mtS3M = 1
276mtMOD = 2
277mtMTM = 3
278mtXM = 4
279
280ENABLED = 0
281DISABLED = 1
282
283* Mixauspuskurin koko
284
285disable020	=	0
286
287
288pop	macro
289	movem.l	(sp)+,\1
290	endm
291
292lob	macro
293	jsr	_LVO\1(a6)
294	endm
295
296iword	macro
297	ror	#8,\1
298	endm
299
300ilword	macro
301	ror	#8,\1
302	swap	\1
303	ror	#8,\1
304	endm
305
306tlword	macro
307	move.b	\1,\2
308	ror.l	#8,\2
309	move.b	\1,\2
310	ror.l	#8,\2
311	move.b	\1,\2
312	ror.l	#8,\2
313	move.b	\1,\2
314	ror.l	#8,\2
315	endm
316
317tword	macro
318	move.b	\1,\2
319	ror	#8,\2
320	move.b	\1,\2
321	ror	#8,\2
322	endm
323
324;	illegal
325;	bra.w	start_interrupt
326;	bra.w	stop_interrupt
327;	bra.w	toggle_channel
328;	bra.w	set_vbvalue
329;herepoint:
330;	dc.l	cha0-herepoint
331
332set_vbvalue:
333	movem.l	d0-a6,-(sp)		;Save these two registers.
334	lea	data,a5		;Pointer to data storage structure.
335	basereg	data,a5
336	and.l	#$0f,d0			;Limit to 0-15.
337	move.l	d0,vboost(a5)		;Set up the volume boost.
338	bsr	makedivtabs		;Make the division tables.
339	movem.l	(sp)+,d0-a6		;Restore registers.
340	rts
341
342
343start_interrupt
344	lea	data,a5
345	move.l	d3,vboost(a5)		;Volume boost from 0-8.
346	move.l	d2,mixingrate(a5)	;Set the mixing rate.
347	move.w	d1,pmode(a5)		;Restore and set the playmode value.
348
349
350	;move	#64,PS3M_master(a5)	;Master volume level.
351	;move	#1,fformat(a5)		;Sample format is signed samples.
352
353	;move.l	#14317056/4,clock(a5)	;Clock constant
354	;move	#64,globalVol(a5)	;Set this global volume too.
355
356
357	lea	data,a5
358*** Alloc mem
359
360	move.l	#BUFFER,d0
361	move.l	d0,buffSize(a5)
362	subq.l	#1,d0
363	move.l	d0,buffSizeMask(a5)
364	lsl.l	#8,d0
365	move.b	#$ff,d0
366	lea	buffSizeMaskFF,a3
367	move.l	d0,(a3)
368
369	move.l	4.w,a6
370	move.l	#1024*4*2,d0
371	move.l	#MEMF_PUBLIC!MEMF_CLEAR,d1
372	lob	AllocMem
373	move.l	d0,tbuf(a5)
374	beq.w	_memerr
375	add.l	#1024*4,d0
376	move.l	d0,tbuf2(a5)
377
378	move.l	buffSize(a5),d0
379	move.l	#MEMF_CHIP!MEMF_CLEAR,d1
380	lob	AllocMem
381	move.l	d0,buff1(a5)
382	beq.w	_memerr
383
384	move.l	buffSize(a5),d0
385	move.l	#MEMF_CHIP!MEMF_CLEAR,d1
386	lob	AllocMem
387	move.l	d0,buff2(a5)
388	beq.w	_memerr
389
390	move.l	#66*256,d7			; Volume tab size
391
392	cmp	#REAL,pmode(a5)
393	beq.b	.varaa
394	cmp	#STEREO14,pmode(a5)
395	bne.b	.ala2
396
397.varaa	move.l	buffSize(a5),d0
398	move.l	#MEMF_CHIP!MEMF_CLEAR,d1
399	lob	AllocMem
400	move.l	d0,buff3(a5)
401	beq.b	_memerr
402
403	move.l	buffSize(a5),d0
404	move.l	#MEMF_CHIP!MEMF_CLEAR,d1
405	lob	AllocMem
406	move.l	d0,buff4(a5)
407	beq.b	_memerr
408
409.ala2	cmp	#STEREO14,pmode(a5)
410	beq.b	_bit14
411
412	moveq	#0,d0
413	move	maxchan(a5),d1
414	move.l	#256,d2
415	subq	#1,d1
416_l	add.l	d2,d0
417	add.l	#256,d2
418	dbf	d1,_l
419
420	move.l	d0,dtabsize(a5)
421	moveq	#MEMF_PUBLIC,d1
422	lob	AllocMem
423	move.l	d0,dtab(a5)
424	beq.b	_memerr
425	bra.b	_alavaraa
426
427_bit14	move.l	#66*256*2,d7			; Volume tab size
428
429	move.l	#64*1024,d0
430	moveq	#MEMF_PUBLIC,d1
431	lob	AllocMem
432	move.l	d0,buff14(a5)
433	bne.b	_alavaraa
434
435_memerr	bsr.w	s3end
436
437	moveq	#-1,d0			* ERROR: no mem!
438	rts
439
440_alavaraa
441	move.l	d7,d0
442	moveq	#MEMF_PUBLIC,d1
443	lob	AllocMem
444	move.l	d0,vtab(a5)
445	beq.b	_memerr
446
447	add.l	#255,d0
448	and.l	#~$ff,d0
449	move.l	d0,vtabaddr(a5)
450
451
452	bsr.w	s3mPlay
453	moveq	#0,d0			* All ok
454	rts
455
456
457
458
459
460
461** End music
462
463s3end
464
465	lea	data,a5
466
467	clr.l	vtabaddr(a5)
468	move.l	4.w,a6
469	move.l	tbuf(a5),d0
470	beq.b	.eumg
471	move.l	d0,a1
472	move.l	#1024*4*2,d0
473	lob	FreeMem
474	clr.l	tbuf(a5)
475	clr.l	tbuf2(a5)
476
477.eumg	move.l	buff1(a5),d0
478	beq.b	.eimem
479	move.l	d0,a1
480	move.l	buffSize(a5),d0
481	lob	FreeMem
482	clr.l	buff1(a5)
483
484.eimem	move.l	buff2(a5),d0
485	beq.b	.eimem1
486	move.l	d0,a1
487	move.l	buffSize(a5),d0
488	lob	FreeMem
489	clr.l	buff2(a5)
490
491.eimem1	move.l	buff3(a5),d0
492	beq.b	.eimem2
493	move.l	d0,a1
494	move.l	buffSize(a5),d0
495	lob	FreeMem
496	clr.l	buff3(a5)
497
498.eimem2	move.l	buff4(a5),d0
499	beq.b	.eimem3
500	move.l	d0,a1
501	move.l	buffSize(a5),d0
502	lob	FreeMem
503	clr.l	buff4(a5)
504
505.eimem3	move.l	buff14(a5),d0
506	beq.b	.eimem4
507	move.l	d0,a1
508	move.l	#64*1024,d0
509	lob	FreeMem
510	clr.l	buff14(a5)
511
512.eimem4	move.l	vtab(a5),d0
513	beq.b	.eimem5
514	move.l	d0,a1
515	move.l	#66*256,d0
516	cmp	#STEREO14,pmode(a5)
517	bne.b	.cd
518	add.l	d0,d0
519.cd	lob	FreeMem
520	clr.l	vtab(a5)
521
522.eimem5	move.l	dtab(a5),d0
523	beq.b	.eimem6
524	move.l	d0,a1
525	move.l	dtabsize(a5),d0
526	lob	FreeMem
527	clr.l	dtab(a5)
528
529.eimem6	rts
530
531
532***********************************
533* PS3M 0.959 Audio mixer routines *
534*    � 1994-95 Jarno Paananen	  *
535*      All rights reserved	  *
536***********************************
537
538;	/*
539;	** LEVEL 4 AUDIO IRQ HANDLER.
540;	*/
541
542lev4	move.l	a0,-(sp)
543	lea	playpos,a0
544	clr.l	(a0)
545	move.w	#$80,$dff09c
546	move.l	(sp)+,a0
547	nop
548	rte
549
550;	/*
551;	** LEVEL 3 VERTICAL BLANK IRQ HANDLER.
552;	*/
553
554
555buffSizeMaskFF
556	dc.l	(BUFFER-1)<<8!$ff
557
558
559play:	movem.l	d0-d7/a0-a6,-(sp)
560	lea	data,a5
561	move.l	mrate50(a5),d0
562	add.l	d0,playpos(a5)
563	move.l	buffSizeMaskFF,d0
564	and.l	d0,playpos(a5)
565	bsr.s	play2
566	movem.l	(sp)+,d0-d7/a0-a6
567	rts
568
569play2:	lea	data,a5
570
571	move.l	playpos(a5),d2
572	lsr.l	#8,d2
573	move.l	bufpos(a5),d0
574	cmp.l	d2,d0
575	ble.b	.norm
576	sub.l	buffSize(a5),d0
577.norm	move.l	mrate50(a5),d1
578	lsr.l	#7,d1
579	add.l	d0,d1
580
581	sub.l	d1,d2
582	bmi.s	.ei
583
584	moveq	#1,d0
585	and.l	d2,d0
586	add	d0,d2
587
588	cmp.l	#16,d2
589	blt.s	.ei
590
591	move	d2,todobytes(a5)
592
593.mix	move	bytes2music(a5),d0
594	cmp	todobytes(a5),d0
595	bgt.b	.mixaa
596
597	sub	d0,todobytes(a5)
598	sub	d0,bytes2music(a5)
599	move	d0,bytes2do(a5)
600	beq.b	.q
601
602	bsr.w	domix
603
604.q
605	lea	data,a5
606	cmp.w	#mtS3M,mtype(a5)
607	bne	.xm
608	bsr	s3m_music
609	bra.b	.kool
610.xm
611	cmp.w	#mtXM,mtype(a5)
612	bne	.mod
613	bsr	xm_music
614	bra.b	.kool
615
616.mod	bsr	mt_music
617
618.kool	lea	data,a5
619	move	bytesperframe(a5),d0
620	add	d0,bytes2music(a5)
621	bra.b	.mix
622
623.mixaa	move	todobytes(a5),d0
624	sub	d0,bytes2music(a5)
625	move	d0,bytes2do(a5)
626	beq.b	.q2
627
628	bsr.w	domix
629
630.q2	lea	data,a5
631.ei	moveq	#0,d7
632	rts
633
634scanpoint:
635	dc.b	0
636	even
637
638FinalInit
639	lea	data,a5
640	clr.l	bufpos(a5)
641	clr.l	playpos(a5)
642
643	*clr	cn(a5)		;UADE
644	*clr.b	mt_counter
645
646;	/*
647;	** First, clear the circular audio buffers to 0 just incase there is
648;	** some old data sitting there.
649;	*/
650
651	lea	buff1,a0
652	moveq	#3,d6
653.clloop
654	move.l	(a0)+,d0
655	beq.b	.skip
656	move.l	d0,a1
657
658	move.l	buffSize(a5),d7
659	lsr.l	#2,d7
660	subq.l	#1,d7
661.cl	clr.l	(a1)+
662	dbf	d7,.cl
663.skip	dbf	d6,.clloop
664
665;	/*
666;	** Clear the audio mixer structure too.
667;	*/
668
669.huu	lea	cha0,a0
670	move	#mChanBlock_SIZE*16-1,d7
671.cl2	clr	(a0)+
672	dbf	d7,.cl2
673
674
675	lea	c0(a5),a0
676	move	#s3mChanBlock_SIZE*8-1,d7
677.cl3	clr.l	(a0)+
678	dbf	d7,.cl3
679
680;	/*
681;	** Initialize mixing rates/audio/clock periods.
682;	*/
683	move	tempo(a5),d0
684	bne.b	.qw
685	moveq	#125,d0
686.qw	move.l	mrate(a5),d1
687	move.l	d1,d2
688	lsl.l	#2,d1
689	add.l	d2,d1
690	add	d0,d0
691	divu	d0,d1
692
693	addq	#1,d1
694	and	#~1,d1
695
696	move	d1,bytesperframe(a5)
697	clr	bytes2do(a5)
698
699	bset	#1,$bfe001
700
701	bsr.w	makedivtabs
702	bsr.w	Makevoltable
703
704	ifeq	disable020
705
706	move.l	4.w,a6
707	btst	#1,297(a6)
708	beq.b	.no020
709
710; Processor is 020+!
711
712	st	opt020(a5)
713
714	cmp	#STEREO14,pmode(a5)
715	beq.b	.s14_020
716
717	lea	mix_020,a2
718	lea	mix2_020,a3
719	move.l	a2,mixad1(a5)
720	move.l	a3,mixad2(a5)
721	bra.b	.e
722
723.s14_020
724	lea	mix16_020,a2
725	lea	mix162_020,a3
726	move.l	a2,mixad1(a5)
727	move.l	a3,mixad2(a5)
728	bra.b	.e
729
730	endc
731
732; Processor is 000/010
733
734.no020	clr	opt020(a5)
735
736	cmp	#STEREO14,pmode(a5)
737	beq.b	.s14_000
738
739	lea	mix,a2
740	lea	mix2,a3
741	move.l	a2,mixad1(a5)
742	move.l	a3,mixad2(a5)
743	bra.b	.e
744
745.s14_000
746	lea	mix16,a2
747	lea	mix162,a3
748	move.l	a2,mixad1(a5)
749	move.l	a3,mixad2(a5)
750
751.e	cmp	#STEREO14,pmode(a5)
752	bne.b	.nop
753
754	lea	copybuf14,a2
755	move.l	a2,cbufad(a5)
756
757	bsr.w	do14tab
758	bra.b	.q
759
760.nop	cmp	#REAL,pmode(a5)
761	beq.b	.surr
762
763	lea	copybuf,a2
764	move.l	a2,cbufad(a5)
765	bra.b	.q
766
767.surr	lea	copysurround,a2
768	move.l	a2,cbufad(a5)
769
770.q	moveq	#0,d0
771	rts
772
773;;***** Mixing routines *********
774
775
776domix	lea	cha0,a4
777	lea	pantab,a0
778	moveq	#31,d7
779	move.l	mixad1(a5),a1
780.loo	tst.b	(a0)+
781	beq.b	.n
782	bmi.b	.n
783
784	move.l	tbuf(a5),a2
785	push	a0/a1/d7
786	jsr	(a1)				; Mix
787	pull	a0/a1/d7
788	move	#1,chans(a5)
789	lea	mChanBlock_SIZE(a4),a4
790	subq	#1,d7
791	bra.b	.loo2
792
793.n	lea	mChanBlock_SIZE(a4),a4
794	dbf	d7,.loo
795	bra.b	.ddq
796
797
798.loo2	cmp	#1,maxchan(a5)
799	beq.b	.ddq
800
801	move.l	mixad2(a5),a1
802.loka	tst.b	(a0)+
803	beq.b	.n2
804	bmi.b	.n2
805
806	move.l	tbuf(a5),a2
807	push	a0/a1/d7
808	jsr	(a1)
809	pull	a0/a1/d7
810
811.n2	lea	mChanBlock_SIZE(a4),a4
812	dbf	d7,.loka
813
814.ddq	move.l	tbuf(a5),a0
815	move.l	buff1(a5),a1
816	move.l	buff3(a5),a4
817	move.l	cbufad(a5),a2
818	jsr	(a2)
819
820
821right	lea	cha0,a4
822	lea	pantab,a0
823	move.l	mixad1(a5),a1
824	moveq	#31,d7
825.loo	tst.b	(a0)+
826	bpl.b	.n
827
828	move.l	tbuf2(a5),a2
829	push	a0/a1/d7
830	jsr	(a1)
831	pull	a0/a1/d7
832	move	#1,chans(a5)
833	lea	mChanBlock_SIZE(a4),a4
834	subq	#1,d7
835	bra.b	.loo2
836
837.n	lea	mChanBlock_SIZE(a4),a4
838	dbf	d7,.loo
839	bra.b	.ddq
840
841
842.loo2	cmp	#1,maxchan(a5)
843	beq.b	.ddq
844	move.l	mixad2(a5),a1
845.loka	tst.b	(a0)+
846	bpl.b	.n2
847
848	move.l	tbuf2(a5),a2
849	push	a0/a1/d7
850	jsr	(a1)
851	pull	a0/a1/d7
852
853.n2	lea	mChanBlock_SIZE(a4),a4
854	dbf	d7,.loka
855
856.ddq	move.l	tbuf2(a5),a0
857	move.l	buff2(a5),a1
858	move.l	buff4(a5),a4
859	move.l	cbufad(a5),a2
860	jsr	(a2)
861
862	moveq	#0,d0
863	move	bytes2do(a5),d0
864	add.l	d0,bufpos(a5)
865	move.l	buffSizeMask(a5),d0
866	and.l	d0,bufpos(a5)
867	clr	bytes2do(a5)
868	rts
869
870
871copybuf	move.l	bufpos(a5),d0
872	move.l	d0,d1
873	moveq	#0,d2
874	move	bytes2do(a5),d2
875	add.l	d2,d1
876	cmp.l	buffSizeMask(a5),d1
877	ble.b	.dd
878
879	move.l	a1,a3
880
881	move.l	buffSize(a5),d7
882	sub.l	d0,d7
883	lsr.l	#1,d7
884	subq	#1,d7
885	add.l	d0,a1
886	lea	divtabs,a2
887	move	chans(a5),d0
888	lsl	#2,d0
889	move.l	-4(a2,d0),a2
890
891.ldd	move	(a0)+,d2
892	move.b	(a2,d2),(a1)+
893	move	(a0)+,d2
894	move.b	(a2,d2),(a1)+
895	dbf	d7,.ldd
896
897	move.l	a3,a1
898	move.l	d1,d7
899	sub.l	buffSize(a5),d7
900	lsr.l	#1,d7
901	subq	#1,d7
902	bmi.b	.ddq
903.ldd2	move	(a0)+,d2
904	move.b	(a2,d2),(a1)+
905	move	(a0)+,d2
906	move.b	(a2,d2),(a1)+
907	dbf	d7,.ldd2
908.ddq	rts
909
910.dd	add.l	d0,a1
911	lea	divtabs,a2
912	move	chans(a5),d0
913	lsl	#2,d0
914	move.l	-4(a2,d0),a2
915	move	bytes2do(a5),d7
916	lsr	#1,d7
917	subq	#1,d7
918.ldd3	move	(a0)+,d1
919	move.b	(a2,d1),(a1)+
920	move	(a0)+,d1
921	move.b	(a2,d1),(a1)+
922	dbf	d7,.ldd3
923	rts
924
925copysurround
926	move.l	bufpos(a5),d0
927	move.l	d0,d1
928
929	moveq	#0,d2
930	move	bytes2do(a5),d2
931	add.l	d2,d1
932
933	cmp.l	buffSizeMask(a5),d1
934	ble.b	.dd
935
936	movem.l	a1/a4,-(sp)
937
938	move.l	buffSize(a5),d7
939	sub.l	d0,d7
940	lsr.l	#1,d7
941	subq	#1,d7
942	add.l	d0,a1
943	add.l	d0,a4
944	lea	divtabs,a2
945	move	chans(a5),d0
946	lsl	#2,d0
947	move.l	-4(a2,d0),a2
948
949.ldd	move	(a0)+,d2
950	move.b	(a2,d2),d2
951	move.b	d2,(a1)+
952	not	d2
953	move.b	d2,(a4)+
954
955	move	(a0)+,d2
956	move.b	(a2,d2),d2
957	move.b	d2,(a1)+
958	not	d2
959	move.b	d2,(a4)+
960	dbf	d7,.ldd
961
962	movem.l	(sp)+,a1/a4
963
964	move.l	d1,d7
965	sub.l	buffSize(a5),d7
966	lsr.l	#1,d7
967	subq	#1,d7
968	bmi.b	.ddq
969.ldd2	move	(a0)+,d2
970	move.b	(a2,d2),d2
971	move.b	d2,(a1)+
972	not	d2
973	move.b	d2,(a4)+
974
975	move	(a0)+,d2
976	move.b	(a2,d2),d2
977	move.b	d2,(a1)+
978	not	d2
979	move.b	d2,(a4)+
980	dbf	d7,.ldd2
981.ddq	rts
982
983.dd	add.l	d0,a1
984	add.l	d0,a4
985	lea	divtabs,a2
986	move	chans(a5),d0
987	lsl	#2,d0
988	move.l	-4(a2,d0),a2
989	move	bytes2do(a5),d7
990	lsr	#1,d7
991	subq	#1,d7
992.ldd3	move	(a0)+,d2
993	move.b	(a2,d2),d2
994	move.b	d2,(a1)+
995	not	d2
996	move.b	d2,(a4)+
997
998	move	(a0)+,d2
999	move.b	(a2,d2),d2
1000	move.b	d2,(a1)+
1001	not	d2
1002	move.b	d2,(a4)+
1003	dbf	d7,.ldd3
1004	rts
1005
1006
1007copybuf14
1008	move.l	bufpos(a5),d0
1009	move.l	d0,d1
1010	moveq	#0,d2
1011	move	bytes2do(a5),d2
1012	add.l	d2,d1
1013	cmp.l	buffSizeMask(a5),d1
1014	ble.b	.dd
1015
1016	movem.l	a1/a4,-(sp)
1017
1018	move.l	buffSize(a5),d7
1019	sub.l	d0,d7
1020	subq	#1,d7
1021	add.l	d0,a1
1022	add.l	d0,a4
1023	moveq	#0,d2
1024	move.l	buff14(a5),a2
1025	moveq	#-2,d0
1026.ldd	move	(a0)+,d2
1027	and.l	d0,d2
1028	move.b	(a2,d2.l),(a1)+
1029	move.b	1(a2,d2.l),(a4)+
1030	dbf	d7,.ldd
1031
1032.huu	movem.l	(sp)+,a1/a4
1033	move.l	d1,d7
1034	sub.l	buffSize(a5),d7
1035	subq	#1,d7
1036	bmi.b	.ddq
1037
1038.ldd2	move	(a0)+,d2
1039	and.l	d0,d2
1040	move.b	(a2,d2.l),(a1)+
1041	move.b	1(a2,d2.l),(a4)+
1042	dbf	d7,.ldd2
1043.ddq	rts
1044
1045
1046.dd	add.l	d0,a1
1047	add.l	d0,a4
1048	move	bytes2do(a5),d7
1049	subq	#1,d7
1050	move.l	buff14(a5),a2
1051	moveq	#0,d2
1052	moveq	#-2,d0
1053.ldd3	move	(a0)+,d2
1054	and.l	d0,d2
1055	move.b	(a2,d2.l),(a1)+
1056	move.b	1(a2,d2.l),(a4)+
1057	dbf	d7,.ldd3
1058	rts
1059
1060
1061; 000/010 Mixing routines
1062
1063; Mixing routine for the first channel (moves data)
1064
1065
1066mix	moveq	#0,d7
1067	move	bytes2do(a5),d7
1068	subq	#1,d7
1069
1070	tst	mPeriod(a4)
1071	beq.w	.ty
1072	tst.b	mOnOff(a4)
1073	bne.w	.ty			;sound off
1074
1075	tst	mVolume(a4)
1076	beq.w	.vol0
1077
1078.dw	move.l	clock(a5),d4
1079	divu	mPeriod(a4),d4
1080	swap	d4
1081	clr	d4
1082	lsr.l	#2,d4
1083
1084	move.l	mrate(a5),d0
1085	divu	d0,d4
1086	swap	d4
1087	clr	d4
1088	rol.l	#4,d4
1089
1090	move.l	vtabaddr(a5),d2
1091	move	mVolume(a4),d0
1092	mulu	PS3M_master(a5),d0
1093	lsr	#6,d0
1094	lsl.l	#8,d0
1095	add.l	d0,d2				; Position in volume table
1096
1097	move.l	(a4),a0				;mStart
1098	move.l	mFPos(a4),d0
1099
1100	moveq	#0,d3
1101	moveq	#0,d5
1102
1103	move.l	mLength(a4),d6
1104	bne.b	.2
1105
1106	tst.b	mLoop(a4)
1107	bne.b	.q
1108	st	mOnOff(a4)
1109	bra.b	.qw
1110
1111.2	cmp.l	#$ffff,d6
1112	bls.b	.leii
1113	move	#$ffff,d6
1114
1115.leii	cmp	#32,d7
1116	blt.b	.lep
1117	move.l	d4,d1
1118	swap	d1
1119	lsl.l	#5,d1
1120	swap	d1
1121	add.l	d0,d1
1122	cmp	d6,d1
1123	bhs.b	.lep
1124	pea	.leii
1125	bra.w	.mix32
1126
1127.lep	move.b	(a0,d0),d2
1128	move.l	d2,a1
1129	add.l	d4,d0
1130	move.b	(a1),d3
1131	addx	d5,d0
1132	move	d3,(a2)+
1133
1134	cmp	d6,d0
1135	bhs.b	.ddwq
1136	dbf	d7,.lep
1137	bra.b	.qw
1138
1139.ddwq	tst.b	mLoop(a4)
1140	bne.b	.q
1141	st	mOnOff(a4)
1142	dbf	d7,.ty
1143	bra.b	.qw
1144
1145.q	move.l	mLStart(a4),a0
1146	moveq	#0,d1
1147	move	d0,d1
1148	sub.l	mLength(a4),d1
1149	add.l	d1,a0
1150	move.l	mLLength(a4),d6
1151	sub.l	d1,d6
1152	move.l	d6,mLength(a4)
1153
1154	cmp.l	#$ffff,d6
1155	bls.b	.j
1156	move	#$ffff,d6
1157.j	clr	d0				;reset integer part
1158	dbf	d7,.leii
1159
1160.qw	moveq	#0,d1
1161	move	d0,d1
1162	add.l	d1,a0
1163	clr	d0
1164	move.l	a0,(a4)				;mStart
1165	move.l	d0,mFPos(a4)
1166
1167	sub.l	d1,mLength(a4)
1168	bpl.b	.u
1169
1170	tst.b	mLoop(a4)
1171	bne.b	.q2
1172	st	mOnOff(a4)
1173	bra.b	.u
1174
1175.q2	move.l	mLLength(a4),d6
1176	sub.l	(a4),a0
1177	add.l	mLStart(a4),a0
1178	sub.l	d6,a0
1179	add.l	d6,mLength(a4)
1180	move.l	a0,(a4)				; mStart
1181.u	rts
1182
1183.ty	addq	#1,d7
1184	beq.b	.u
1185
1186	move.l	#$800080,d0
1187	lsr	d7
1188	bcc.b	.sk
1189	move	d0,(a2)+
1190.sk	subq	#1,d7
1191	bmi.b	.u
1192.lk	move.l	d0,(a2)+
1193	dbf	d7,.lk
1194	rts
1195
1196.mix32:
1197	rept	16
1198	move.b	(a0,d0),d2
1199	move.l	d2,a1
1200	move.b	(a1),d3
1201	add.l	d4,d0
1202	addx	d5,d0
1203	swap	d3
1204	move.b	(a0,d0),d2
1205	move.l	d2,a1
1206	move.b	(a1),d3
1207	move.l	d3,(a2)+
1208	add.l	d4,d0
1209	addx	d5,d0
1210	endr
1211
1212	sub	#32,d7
1213	rts
1214
1215
1216
1217.vol0	move.l	clock(a5),d4
1218	divu	mPeriod(a4),d4		;period
1219	swap	d4
1220	clr	d4
1221	lsr.l	#2,d4
1222
1223	move.l	mrate(a5),d0
1224	divu	d0,d4
1225	swap	d4
1226	clr	d4
1227	rol.l	#4,d4
1228	swap	d4
1229
1230	move.l	(a4),a0			;mStart
1231	move.l	mFPos(a4),d0
1232
1233	addq	#1,d7
1234
1235	movem.l	d0/d1,-(sp)
1236	move.l	d7,d1
1237	move.l	d4,d0
1238	bsr.w	mulu_32
1239	move.l	d0,d4
1240	movem.l	(sp)+,d0/d1
1241
1242	subq	#1,d7
1243
1244	swap	d0
1245	add.l	d4,d0			; Position after "mixing"
1246	swap	d0
1247
1248	moveq	#0,d1
1249	move	d0,d1
1250	add.l	d1,a0
1251	clr	d0
1252	move.l	a0,(a4)
1253	move.l	d0,mFPos(a4)
1254	sub.l	d1,mLength(a4)
1255	bpl.w	.ty			; OK, Done!
1256
1257; We're about to mix past the end of the sample
1258
1259	tst.b	mLoop(a4)
1260	bne.b	.q3
1261	st	mOnOff(a4)
1262	bra.w	.ty
1263
1264.q3	move.l	mLLength(a4),d6
1265.loop	sub.l	d6,a0
1266	add.l	d6,mLength(a4)
1267	bmi.b	.loop
1268	beq.b	.loop
1269
1270	move.l	a0,(a4)
1271	bra.w	.ty
1272
1273
1274
1275; Mixing routine for rest of the channels (adds data)
1276
1277mix2	moveq	#0,d7
1278	move	bytes2do(a5),d7
1279
1280	tst	mPeriod(a4)
1281	beq.w	.ty
1282	tst.b	mOnOff(a4)
1283	bne.w	.ty			;noloop
1284
1285	tst	mVolume(a4)
1286	beq.w	.vol0
1287
1288.dw	subq	#1,d7
1289
1290	move.l	clock(a5),d4
1291	divu	mPeriod(a4),d4
1292	swap	d4
1293	clr	d4
1294	lsr.l	#2,d4
1295
1296	move.l	mrate(a5),d0
1297	divu	d0,d4
1298	swap	d4
1299	clr	d4
1300	rol.l	#4,d4
1301
1302	move.l	vtabaddr(a5),d2
1303	move	mVolume(a4),d0
1304	mulu	PS3M_master(a5),d0
1305	lsr	#6,d0
1306	lsl.l	#8,d0
1307	add.l	d0,d2
1308
1309	move.l	(a4),a0			;mStart
1310	move.l	mFPos(a4),d0
1311
1312	moveq	#0,d3
1313	moveq	#0,d5
1314
1315	move.l	mLength(a4),d6
1316	bne.b	.2
1317
1318	tst.b	mLoop(a4)
1319	bne.b	.q
1320	st	mOnOff(a4)
1321	bra.b	.qw
1322
1323.2	cmp.l	#$ffff,d6
1324	bls.b	.leii
1325	move	#$ffff,d6
1326
1327.leii	cmp	#32,d7
1328	blt.b	.lep
1329	move.l	d4,d1
1330	swap	d1
1331	lsl.l	#5,d1
1332	swap	d1
1333	add.l	d0,d1
1334	cmp	d6,d1
1335	bhs.b	.lep
1336	pea	.leii
1337	bra.w	.mix32
1338
1339.lep	move.b	(a0,d0),d2
1340	move.l	d2,a1
1341	add.l	d4,d0
1342	move.b	(a1),d3
1343	addx	d5,d0
1344	add	d3,(a2)+
1345
1346	cmp	d6,d0
1347	bhs.b	.ddwq
1348	dbf	d7,.lep
1349	bra.b	.qw
1350
1351.ddwq	tst.b	mLoop(a4)
1352	bne.b	.q
1353	st	mOnOff(a4)
1354	dbf	d7,.tyy
1355	bra.b	.qw
1356
1357.q	move.l	mLStart(a4),a0
1358	moveq	#0,d1
1359	move	d0,d1
1360	sub.l	mLength(a4),d1
1361	add.l	d1,a0
1362	move.l	mLLength(a4),d6
1363	sub.l	d1,d6
1364	move.l	d6,mLength(a4)
1365	cmp.l	#$ffff,d6
1366	bls.b	.j
1367	move	#$ffff,d6
1368.j	clr	d0			;reset integer part
1369	dbf	d7,.leii
1370
1371.qw	moveq	#0,d1
1372	move	d0,d1
1373	add.l	d1,a0
1374	clr	d0
1375	move.l	a0,(a4)
1376	move.l	d0,mFPos(a4)
1377
1378	sub.l	d1,mLength(a4)
1379	bpl.b	.u
1380
1381	tst.b	mLoop(a4)
1382	bne.b	.q2
1383	st	mOnOff(a4)
1384	bra.b	.u
1385
1386.q2	move.l	mLLength(a4),d6
1387	sub.l	(a4),a0
1388	add.l	mLStart(a4),a0
1389	sub.l	d6,a0
1390	add.l	d6,mLength(a4)
1391	move.l	a0,(a4)
1392
1393.u	addq	#1,chans(a5)
1394.ty	rts
1395
1396.tyy	addq	#1,d7
1397	beq.b	.u
1398
1399	move.l	#$800080,d0
1400	lsr	d7
1401	bcc.b	.sk
1402	add	d0,(a2)+
1403.sk	subq	#1,d7
1404	bmi.b	.u
1405.lk	add.l	d0,(a2)+
1406	dbf	d7,.lk
1407	bra.b	.u
1408
1409.mix32:
1410	rept	16
1411	move.b	(a0,d0),d2
1412	move.l	d2,a1
1413	move.b	(a1),d3
1414	add.l	d4,d0
1415	addx	d5,d0
1416	swap	d3
1417	move.b	(a0,d0),d2
1418	move.l	d2,a1
1419	move.b	(a1),d3
1420	add.l	d3,(a2)+
1421	add.l	d4,d0
1422	addx	d5,d0
1423	endr
1424	sub	#32,d7
1425	rts
1426
1427
1428.vol0	move.l	clock(a5),d4
1429	divu	mPeriod(a4),d4
1430	swap	d4
1431	clr	d4
1432	lsr.l	#2,d4
1433
1434	move.l	mrate(a5),d0
1435	divu	d0,d4
1436	swap	d4
1437	clr	d4
1438	rol.l	#4,d4
1439	swap	d4
1440
1441	move.l	(a4),a0			;pos (addr)
1442	move.l	mFPos(a4),d0
1443
1444	addq	#1,d7
1445	movem.l	d0/d1,-(sp)
1446	move.l	d7,d1
1447	move.l	d4,d0
1448	bsr.w	mulu_32
1449	move.l	d0,d4
1450	movem.l	(sp)+,d0/d1
1451
1452	subq	#1,d7
1453	swap	d0
1454	add.l	d4,d0			; Position after "mixing"
1455	swap	d0
1456
1457	moveq	#0,d1
1458	move	d0,d1
1459	add.l	d1,a0
1460	clr	d0
1461	move.l	a0,(a4)
1462	move.l	d0,mFPos(a4)
1463	sub.l	d1,mLength(a4)
1464	bpl.w	.ty			; OK, Done!
1465
1466; We're about to mix past the end of the sample
1467
1468	tst.b	mLoop(a4)
1469	bne.b	.q3
1470	st	mOnOff(a4)
1471	bra.w	.ty
1472
1473.q3	move.l	mLLength(a4),d6
1474.loop	sub.l	d6,a0
1475	add.l	d6,mLength(a4)
1476	bmi.b	.loop
1477	beq.b	.loop
1478
1479	move.l	a0,(a4)
1480	bra.w	.ty
1481
1482
1483; 16-bit mixing routine for first channel (moves data)
1484
1485mix16	moveq	#0,d7
1486	move	bytes2do(a5),d7
1487	subq	#1,d7
1488
1489	tst	mPeriod(a4)
1490	beq.w	.ty
1491	tst.b	mOnOff(a4)
1492	bne.w	.ty
1493
1494	tst	mVolume(a4)
1495	beq.w	.vol0
1496
1497.dw	move.l	clock(a5),d4
1498	divu	mPeriod(a4),d4
1499	swap	d4
1500	clr	d4
1501	lsr.l	#2,d4
1502
1503	move.l	mrate(a5),d0
1504	divu	d0,d4
1505	swap	d4
1506	clr	d4
1507	rol.l	#4,d4
1508
1509	move.l	vtabaddr(a5),a3
1510	move	mVolume(a4),d0
1511	mulu	PS3M_master(a5),d0
1512	lsr	#6,d0
1513	add	d0,d0
1514	lsl.l	#8,d0
1515	add.l	d0,a3				; Position in volume table
1516
1517	move.l	(a4),a0				;mStart
1518	move.l	mFPos(a4),d0
1519
1520	moveq	#0,d3
1521	moveq	#0,d5
1522
1523	move.l	mLength(a4),d6
1524	bne.b	.2
1525
1526	tst.b	mLoop(a4)
1527	bne.b	.q
1528	st	mOnOff(a4)
1529	bra.b	.qw
1530
1531.2	cmp.l	#$ffff,d6
1532	bls.b	.leii
1533	move	#$ffff,d6
1534
1535.leii	cmp	#32,d7
1536	blt.b	.lep
1537	move.l	d4,d1
1538	swap	d1
1539	lsl.l	#5,d1
1540	swap	d1
1541	add.l	d0,d1
1542	cmp	d6,d1
1543	bhs.b	.lep
1544	pea	.leii
1545	bra.w	.mix32
1546
1547.lep	moveq	#0,d2
1548	move.b	(a0,d0),d2
1549	add	d2,d2
1550	add.l	d4,d0
1551	move	(a3,d2),(a2)+
1552	addx	d5,d0
1553
1554	cmp	d6,d0
1555	bhs.b	.ddwq
1556	dbf	d7,.lep
1557	bra.b	.qw
1558
1559.ddwq	tst.b	mLoop(a4)
1560	bne.b	.q
1561	st	mOnOff(a4)
1562	dbf	d7,.ty
1563	bra.b	.qw
1564
1565.q	move.l	mLStart(a4),a0
1566	moveq	#0,d1
1567	move	d0,d1
1568	sub.l	mLength(a4),d1
1569	add.l	d1,a0
1570	move.l	mLLength(a4),d6
1571	sub.l	d1,d6
1572	move.l	d6,mLength(a4)
1573
1574	cmp.l	#$ffff,d6
1575	bls.b	.j
1576	move	#$ffff,d6
1577.j	clr	d0				;reset integer part
1578	dbf	d7,.leii
1579
1580.qw	moveq	#0,d1
1581	move	d0,d1
1582	add.l	d1,a0
1583	clr	d0
1584	move.l	a0,(a4)				;mStart
1585	move.l	d0,mFPos(a4)
1586
1587	sub.l	d1,mLength(a4)
1588	bpl.b	.u
1589
1590	tst.b	mLoop(a4)
1591	bne.b	.q2
1592	st	mOnOff(a4)
1593	bra.b	.u
1594
1595.q2	move.l	mLLength(a4),d6
1596	sub.l	(a4),a0
1597	add.l	mLStart(a4),a0
1598	sub.l	d6,a0
1599	add.l	d6,mLength(a4)
1600	move.l	a0,(a4)				; mStart
1601.u	rts
1602
1603.ty	addq	#1,d7
1604	beq.b	.u
1605
1606	moveq	#0,d0
1607	lsr	d7
1608	bcc.b	.sk
1609	move	d0,(a2)+
1610.sk	subq	#1,d7
1611	bmi.b	.u
1612.lk	move.l	d0,(a2)+
1613	dbf	d7,.lk
1614	rts
1615
1616.mix32:
1617	rept	32
1618
1619	moveq	#0,d2
1620	move.b	(a0,d0),d2
1621	add	d2,d2
1622	add.l	d4,d0
1623	move	(a3,d2),(a2)+
1624	addx	d5,d0
1625
1626	endr
1627
1628	sub	#32,d7
1629	rts
1630
1631
1632.vol0	move.l	clock(a5),d4
1633	divu	mPeriod(a4),d4		;period
1634	swap	d4
1635	clr	d4
1636	lsr.l	#2,d4
1637
1638	move.l	mrate(a5),d0
1639	divu	d0,d4
1640	swap	d4
1641	clr	d4
1642	rol.l	#4,d4
1643	swap	d4
1644
1645	move.l	(a4),a0			;mStart
1646	move.l	mFPos(a4),d0
1647
1648	addq	#1,d7
1649
1650	movem.l	d0/d1,-(sp)
1651	move.l	d7,d1
1652	move.l	d4,d0
1653	bsr.w	mulu_32
1654	move.l	d0,d4
1655	movem.l	(sp)+,d0/d1
1656
1657	subq	#1,d7
1658
1659	swap	d0
1660	add.l	d4,d0			; Position after "mixing"
1661	swap	d0
1662
1663	moveq	#0,d1
1664	move	d0,d1
1665	add.l	d1,a0
1666	clr	d0
1667	move.l	a0,(a4)
1668	move.l	d0,mFPos(a4)
1669	sub.l	d1,mLength(a4)
1670	bpl.w	.ty			; OK, Done!
1671
1672; We're about to mix past the end of the sample
1673
1674	tst.b	mLoop(a4)
1675	bne.b	.q3
1676	st	mOnOff(a4)
1677	bra.w	.ty
1678
1679.q3	move.l	mLLength(a4),d6
1680.loop	sub.l	d6,a0
1681	add.l	d6,mLength(a4)
1682	bmi.b	.loop
1683	beq.b	.loop
1684
1685	move.l	a0,(a4)
1686	bra.w	.ty
1687
1688
1689
1690; Mixing routine for rest of the channels (adds data)
1691
1692mix162	moveq	#0,d7
1693	move	bytes2do(a5),d7
1694
1695	tst	mPeriod(a4)
1696	beq.w	.ty
1697	tst.b	mOnOff(a4)
1698	bne.w	.ty
1699
1700	tst	mVolume(a4)
1701	beq.w	.vol0
1702
1703.dw	subq	#1,d7
1704
1705	move.l	clock(a5),d4
1706	divu	mPeriod(a4),d4
1707	swap	d4
1708	clr	d4
1709	lsr.l	#2,d4
1710
1711	move.l	mrate(a5),d0
1712	divu	d0,d4
1713	swap	d4
1714	clr	d4
1715	rol.l	#4,d4
1716
1717	move.l	vtabaddr(a5),a3
1718	move	mVolume(a4),d0		;volu
1719	mulu	PS3M_master(a5),d0
1720	lsr	#6,d0
1721	add	d0,d0
1722	lsl.l	#8,d0
1723	add.l	d0,a3
1724
1725	move.l	(a4),a0			;mStart
1726	move.l	mFPos(a4),d0
1727
1728	moveq	#0,d3
1729	moveq	#0,d5
1730
1731	move.l	mLength(a4),d6
1732	bne.b	.2
1733
1734	tst.b	mLoop(a4)
1735	bne.b	.q
1736	st	mOnOff(a4)
1737	bra.b	.qw
1738
1739.2	cmp.l	#$ffff,d6
1740	bls.b	.leii
1741	move	#$ffff,d6
1742
1743.leii	cmp	#32,d7
1744	blt.b	.lep
1745	move.l	d4,d1
1746	swap	d1
1747	lsl.l	#5,d1
1748	swap	d1
1749	add.l	d0,d1
1750	cmp	d6,d1
1751	bhs.b	.lep
1752	pea	.leii
1753	bra.w	.mix32
1754
1755.lep	moveq	#0,d2
1756	move.b	(a0,d0),d2
1757	add	d2,d2
1758	add.l	d4,d0
1759	move	(a3,d2),d3
1760	addx	d5,d0
1761	add	d3,(a2)+
1762
1763	cmp	d6,d0
1764	bhs.b	.ddwq
1765	dbf	d7,.lep
1766	bra.b	.qw
1767
1768.ddwq	tst.b	mLoop(a4)
1769	bne.b	.q
1770	st	mOnOff(a4)
1771	dbf	d7,.tyy
1772	bra.b	.qw
1773
1774.q	move.l	mLStart(a4),a0
1775	moveq	#0,d1
1776	move	d0,d1
1777	sub.l	mLength(a4),d1
1778	add.l	d1,a0
1779	move.l	mLLength(a4),d6
1780	sub.l	d1,d6
1781	move.l	d6,mLength(a4)
1782	cmp.l	#$ffff,d6
1783	bls.b	.j
1784	move	#$ffff,d6
1785.j	clr	d0			;reset integer part
1786	dbf	d7,.leii
1787
1788.qw	moveq	#0,d1
1789	move	d0,d1
1790	add.l	d1,a0
1791	clr	d0
1792	move.l	a0,(a4)
1793	move.l	d0,mFPos(a4)
1794
1795	sub.l	d1,mLength(a4)
1796	bpl.b	.u
1797
1798	tst.b	mLoop(a4)
1799	bne.b	.q2
1800	st	mOnOff(a4)
1801	bra.b	.u
1802
1803.q2	move.l	mLLength(a4),d6
1804	sub.l	(a4),a0
1805	add.l	mLStart(a4),a0
1806	sub.l	d6,a0
1807	add.l	d6,mLength(a4)
1808	move.l	a0,(a4)
1809
1810.u
1811.ty
1812.tyy
1813	rts
1814
1815
1816.mix32:
1817	rept	32
1818	moveq	#0,d2
1819	move.b	(a0,d0),d2
1820	add	d2,d2
1821	move	(a3,d2),d3
1822	add	d3,(a2)+
1823	add.l	d4,d0
1824	addx	d5,d0
1825	endr
1826	sub	#32,d7
1827	rts
1828
1829.vol0	move.l	clock(a5),d4
1830	divu	mPeriod(a4),d4
1831	swap	d4
1832	clr	d4
1833	lsr.l	#2,d4
1834
1835	move.l	mrate(a5),d0
1836	divu	d0,d4
1837	swap	d4
1838	clr	d4
1839	rol.l	#4,d4
1840	swap	d4
1841
1842	move.l	(a4),a0			;pos (addr)
1843	move.l	mFPos(a4),d0
1844
1845	addq	#1,d7
1846	movem.l	d0/d1,-(sp)
1847	move.l	d7,d1
1848	move.l	d4,d0
1849	bsr.w	mulu_32
1850	move.l	d0,d4
1851	movem.l	(sp)+,d0/d1
1852
1853	subq	#1,d7
1854	swap	d0
1855	add.l	d4,d0			; Position after "mixing"
1856	swap	d0
1857
1858	moveq	#0,d1
1859	move	d0,d1
1860	add.l	d1,a0
1861	clr	d0
1862	move.l	a0,(a4)
1863	move.l	d0,mFPos(a4)
1864	sub.l	d1,mLength(a4)
1865	bpl.w	.ty			; OK, Done!
1866
1867; We're about to mix past the end of the sample
1868
1869	tst.b	mLoop(a4)
1870	bne.b	.q3
1871	st	mOnOff(a4)
1872	bra.w	.ty
1873
1874.q3	move.l	mLLength(a4),d6
1875.loop	sub.l	d6,a0
1876	add.l	d6,mLength(a4)
1877	bmi.b	.loop
1878	beq.b	.loop
1879
1880	move.l	a0,(a4)
1881	bra.w	.ty
1882
1883
1884
1885
1886	ifeq	disable020
1887
1888; 020+ Optimized versions!
1889
1890; Mixing routine for the first channel (moves data)
1891
1892
1893mix_020	moveq	#0,d7
1894	move	bytes2do(a5),d7
1895	tst	mPeriod(a4)
1896	beq.w	.ty
1897	tst.b	mOnOff(a4)
1898	bne.w	.ty
1899
1900	tst	mVolume(a4)
1901	beq.w	.vol0
1902
1903.dw	move.l	clock(a5),d4
1904	moveq	#0,d0
1905	move	mPeriod(a4),d0
1906
1907	divu.l	d0,d4
1908
1909	lsl.l	#8,d4
1910	lsl.l	#6,d4
1911
1912	move.l	mrate(a5),d0
1913	lsr.l	#4,d0
1914
1915	divu.l	d0,d4
1916	swap	d4
1917
1918	move.l	vtabaddr(a5),d2
1919	move	mVolume(a4),d0
1920	mulu	PS3M_master(a5),d0
1921	lsr	#6,d0
1922	lsl.l	#8,d0
1923	add.l	d0,d2			; Position in volume table
1924
1925	move.l	(a4),a0			;pos (addr)
1926	move.l	mFPos(a4),d0		;fpos
1927
1928	move.l	mLength(a4),d6		;len
1929	beq.w	.resloop
1930
1931	cmp.l	#$ffff,d6
1932	bls.b	.restart
1933	move	#$ffff,d6
1934.restart
1935	swap	d6
1936	swap	d0
1937	sub.l	d0,d6
1938	swap	d0
1939	move.l	d4,d5
1940	swap	d5
1941
1942	divul.l	d5,d5:d6		; bytes left to loop end
1943	tst.l	d5
1944	beq.b	.e
1945	addq.l	#1,d6
1946.e
1947	moveq	#0,d3
1948	moveq	#0,d5
1949.mixloop
1950	moveq	#8,d1
1951	cmp	d1,d7
1952	bhs.b	.ok
1953	move	d7,d1
1954.ok	cmp.l	d1,d6
1955	bhs.b	.ok2
1956	move.l	d6,d1
1957.ok2	sub	d1,d7
1958	sub.l	d1,d6
1959
1960	jmp	.jtab1(pc,d1*2)
1961
1962.a set 0
1963.jtab1
1964	rept	8
1965	bra.b	.mend-.a
1966.a set .a+14				; (mend - dmix) / 8
1967	endr
1968
1969.dmix	rept	8
1970	move.b	(a0,d0),d2
1971	move.l	d2,a1
1972	move.b	(a1),d3
1973	add.l	d4,d0
1974	move	d3,(a2)+
1975	addx	d5,d0
1976	endr
1977.mend	tst	d7
1978	beq.b	.done
1979	tst.l	d6
1980	bne.w	.mixloop
1981
1982.resloop
1983	tst.b	mLoop(a4)
1984	bne.b	.q
1985	st	mOnOff(a4)
1986	bra.b	.ty
1987
1988.q	moveq	#0,d1
1989	move	d0,d1
1990	sub.l	mLength(a4),d1
1991	move.l	mLStart(a4),a0
1992	add.l	d1,a0
1993	move.l	mLLength(a4),d6
1994	sub.l	d1,d6
1995	move.l	d6,mLength(a4)
1996	cmp.l	#$ffff,d6
1997	bls.b	.j
1998	move	#$ffff,d6
1999.j	clr	d0			;reset integer part
2000	bra.w	.restart
2001
2002.done	moveq	#0,d1
2003	move	d0,d1
2004	add.l	d1,a0
2005	clr	d0
2006	move.l	a0,(a4)
2007	move.l	d0,mFPos(a4)
2008	sub.l	d1,mLength(a4)
2009	bpl.b	.u
2010
2011	tst.b	mLoop(a4)
2012	bne.b	.q2
2013	st	mOnOff(a4)
2014	bra.b	.u
2015
2016.q2	move.l	mLLength(a4),d6
2017	sub.l	(a4),a0
2018	add.l	mLStart(a4),a0
2019	sub.l	d6,a0
2020	add.l	d6,mLength(a4)
2021	move.l	a0,(a4)
2022.u	rts
2023
2024.ty	move.l	#$800080,d0
2025	lsr	d7
2026	bcc.b	.sk
2027	move	d0,(a2)+
2028.sk	subq	#1,d7
2029	bmi.b	.u
2030.lk	move.l	d0,(a2)+
2031	dbf	d7,.lk
2032	rts
2033
2034
2035.vol0	move.l	clock(a5),d4
2036	moveq	#0,d0
2037	move	mPeriod(a4),d0
2038
2039	divu.l	d0,d4
2040
2041	lsl.l	#8,d4
2042	lsl.l	#6,d4
2043
2044	move.l	mrate(a5),d0
2045	lsr.l	#4,d0
2046
2047	divu.l	d0,d4
2048
2049	move.l	(a4),a0
2050	move.l	mFPos(a4),d0
2051
2052	mulu.l	d7,d4
2053
2054	swap	d0
2055	add.l	d4,d0			; Position after "mixing"
2056	swap	d0
2057
2058	moveq	#0,d1
2059	move	d0,d1
2060	add.l	d1,a0
2061	clr	d0
2062	move.l	a0,(a4)
2063	move.l	d0,mFPos(a4)
2064	sub.l	d1,mLength(a4)
2065	bpl.b	.ty			; OK, Done!
2066
2067; We're about to mix past the end of the sample
2068
2069	tst.b	mLoop(a4)
2070	bne.b	.q3
2071	st	mOnOff(a4)
2072	bra.b	.ty
2073
2074.q3	move.l	mLLength(a4),d6
2075.loop	sub.l	d6,a0
2076	add.l	d6,mLength(a4)
2077	bmi.b	.loop
2078	beq.b	.loop
2079
2080	move.l	a0,(a4)
2081	bra.b	.ty
2082
2083
2084; Mixing routine for rest of the channels (adds data)
2085
2086mix2_020
2087	moveq	#0,d7
2088	move	bytes2do(a5),d7
2089	tst	mPeriod(a4)
2090	beq.w	.ty
2091	tst.b	mOnOff(a4)
2092	bne.w	.ty
2093
2094	tst	mVolume(a4)
2095	beq.w	.vol0
2096
2097.dw	move.l	clock(a5),d4
2098	moveq	#0,d0
2099	move	mPeriod(a4),d0
2100
2101	divu.l	d0,d4
2102
2103	lsl.l	#8,d4
2104	lsl.l	#6,d4
2105
2106	move.l	mrate(a5),d0
2107	lsr.l	#4,d0
2108
2109	divu.l	d0,d4
2110
2111	swap	d4
2112
2113	move.l	vtabaddr(a5),d2
2114	move	mVolume(a4),d0
2115	mulu	PS3M_master(a5),d0
2116	lsr	#6,d0
2117	lsl.l	#8,d0
2118	add.l	d0,d2			; Position in volume table
2119
2120	move.l	(a4),a0
2121	move.l	mFPos(a4),d0
2122
2123	move.l	mLength(a4),d6
2124	beq.w	.resloop
2125
2126	cmp.l	#$ffff,d6
2127	bls.b	.restart
2128	move	#$ffff,d6
2129.restart
2130	swap	d6
2131	swap	d0
2132	sub.l	d0,d6
2133	swap	d0
2134
2135	move.l	d4,d5
2136	swap	d5
2137
2138	divul.l	d5,d5:d6		; bytes left to loop end
2139	tst.l	d5
2140	beq.b	.e
2141	addq.l	#1,d6
2142.e	moveq	#0,d3
2143	moveq	#0,d5
2144.mixloop
2145	moveq	#8,d1
2146	cmp	d1,d7
2147	bhi.b	.ok
2148	move	d7,d1
2149.ok	cmp.l	d1,d6
2150	bhi.b	.ok2
2151	move	d6,d1
2152.ok2	sub	d1,d7
2153	sub.l	d1,d6
2154	jmp	.jtab1(pc,d1*2)
2155
2156.a set 0
2157.jtab1
2158	rept	8
2159	bra.b	.mend-.a
2160.a set .a+14				; (mend - dmix) / 8
2161	endr
2162
2163.dmix	rept	8
2164	move.b	(a0,d0),d2
2165	move.l	d2,a1
2166	move.b	(a1),d3
2167	add	d3,(a2)+
2168	add.l	d4,d0
2169	addx	d5,d0
2170	endr
2171.mend	tst	d7
2172	beq.b	.done
2173	tst.l	d6
2174	bne.w	.mixloop
2175
2176.resloop
2177	tst.b	mLoop(a4)
2178	bne.b	.q
2179	st	mOnOff(a4)
2180	bra.b	.tyy
2181
2182.q	moveq	#0,d1
2183	move	d0,d1
2184	sub.l	mLength(a4),d1
2185	move.l	mLStart(a4),a0
2186	add.l	d1,a0
2187	move.l	mLLength(a4),d6
2188	sub.l	d1,d6
2189	move.l	d6,mLength(a4)
2190	cmp.l	#$ffff,d6
2191	bls.b	.j
2192	move	#$ffff,d6
2193.j	clr	d0			;reset integer part
2194	bra.w	.restart
2195
2196.done	moveq	#0,d1
2197	move	d0,d1
2198	add.l	d1,a0
2199	clr	d0
2200	move.l	a0,(a4)
2201	move.l	d0,mFPos(a4)
2202	sub.l	d1,mLength(a4)
2203	bpl.b	.u
2204
2205	tst.b	mLoop(a4)
2206	bne.b	.q2
2207	st	mOnOff(a4)
2208	bra.b	.u
2209
2210.q2	move.l	mLLength(a4),d6
2211	sub.l	(a4),a0
2212	add.l	mLStart(a4),a0
2213	sub.l	d6,a0
2214	add.l	d6,mLength(a4)
2215	move.l	a0,(a4)
2216
2217.u	addq	#1,chans(a5)
2218.ty	rts
2219
2220.tyy	move.l	#$800080,d0
2221	lsr	d7
2222	bcc.b	.sk
2223	add	d0,(a2)+
2224.sk	subq	#1,d7
2225	bmi.b	.u
2226.lk	add.l	d0,(a2)+
2227	dbf	d7,.lk
2228	bra.b	.u
2229
2230
2231.vol0	move.l	clock(a5),d4
2232	moveq	#0,d0
2233	move	mPeriod(a4),d0
2234
2235	divu.l	d0,d4
2236
2237	lsl.l	#8,d4
2238	lsl.l	#6,d4
2239
2240	move.l	mrate(a5),d0
2241	lsr.l	#4,d0
2242
2243	divu.l	d0,d4
2244
2245	move.l	(a4),a0
2246	move.l	mFPos(a4),d0
2247
2248	mulu.l	d7,d4
2249
2250	swap	d0
2251	add.l	d4,d0			; Position after "mixing"
2252	swap	d0
2253
2254	moveq	#0,d1
2255	move	d0,d1
2256	add.l	d1,a0
2257	clr	d0
2258	move.l	a0,(a4)
2259	move.l	d0,mFPos(a4)
2260	sub.l	d1,mLength(a4)
2261	bpl.b	.ty			; OK, Done!
2262
2263; We're about to mix past the end of the sample
2264
2265	tst.b	mLoop(a4)
2266	bne.b	.q3
2267	st	mOnOff(a4)
2268	bra.b	.ty
2269
2270.q3	move.l	mLLength(a4),d6
2271.loop	sub.l	d6,a0
2272	add.l	d6,mLength(a4)
2273	bmi.b	.loop
2274	beq.b	.loop
2275
2276	move.l	a0,(a4)
2277	bra.b	.ty
2278
2279
2280
2281; Mixing routine for the first channel (moves data)
2282
2283
2284mix16_020
2285	moveq	#0,d7
2286	move	bytes2do(a5),d7
2287	tst	mPeriod(a4)
2288	beq.w	.ty
2289	tst.b	mOnOff(a4)
2290	bne.w	.ty
2291
2292	tst	mVolume(a4)
2293	beq.w	.vol0
2294
2295.dw	move.l	clock(a5),d4
2296	moveq	#0,d0
2297	move	mPeriod(a4),d0
2298
2299	divu.l	d0,d4
2300
2301	lsl.l	#8,d4
2302	lsl.l	#6,d4
2303
2304	move.l	mrate(a5),d0
2305	lsr.l	#4,d0
2306
2307	divu.l	d0,d4
2308	swap	d4
2309
2310	move.l	vtabaddr(a5),a3
2311	move	mVolume(a4),d0
2312	mulu	PS3M_master(a5),d0
2313	lsr	#6,d0
2314	add	d0,d0
2315	lsl.l	#8,d0
2316	add.l	d0,a3			; Position in volume table
2317
2318	move.l	(a4),a0			;pos (addr)
2319	move.l	mFPos(a4),d0		;fpos
2320
2321	move.l	mLength(a4),d6		;len
2322	beq.w	.resloop
2323
2324	cmp.l	#$ffff,d6
2325	bls.b	.restart
2326	move	#$ffff,d6
2327.restart
2328	swap	d6
2329	swap	d0
2330	sub.l	d0,d6
2331	swap	d0
2332	move.l	d4,d5
2333	swap	d5
2334
2335	divul.l	d5,d5:d6		; bytes left to loop end
2336	tst.l	d5
2337	beq.b	.e
2338	addq.l	#1,d6
2339.e
2340	moveq	#0,d5
2341	moveq	#0,d2
2342.mixloop
2343	moveq	#8,d1
2344	cmp	d1,d7
2345	bhs.b	.ok
2346	move	d7,d1
2347.ok	cmp.l	d1,d6
2348	bhs.b	.ok2
2349	move.l	d6,d1
2350.ok2	sub	d1,d7
2351	sub.l	d1,d6
2352
2353	jmp	.jtab1(pc,d1*2)
2354
2355.a set 0
2356.jtab1
2357	rept	8
2358	bra.b	.mend-.a
2359.a set .a+12				; (mend - dmix) / 8
2360	endr
2361
2362.dmix	rept	8
2363	move.b	(a0,d0),d2
2364	add.l	d4,d0
2365	move	(a3,d2*2),(a2)+
2366	addx	d5,d0
2367	endr
2368
2369.mend	tst	d7
2370	beq.b	.done
2371	tst.l	d6
2372	bne.w	.mixloop
2373
2374.resloop
2375	tst.b	mLoop(a4)
2376	bne.b	.q
2377	st	mOnOff(a4)
2378	bra.b	.ty
2379
2380.q	moveq	#0,d1
2381	move	d0,d1
2382	sub.l	mLength(a4),d1
2383	move.l	mLStart(a4),a0
2384	add.l	d1,a0
2385	move.l	mLLength(a4),d6
2386	sub.l	d1,d6
2387	move.l	d6,mLength(a4)
2388	cmp.l	#$ffff,d6
2389	bls.b	.j
2390	move	#$ffff,d6
2391.j	clr	d0			;reset integer part
2392	bra.w	.restart
2393
2394.done	moveq	#0,d1
2395	move	d0,d1
2396	add.l	d1,a0
2397	clr	d0
2398	move.l	a0,(a4)
2399	move.l	d0,mFPos(a4)
2400	sub.l	d1,mLength(a4)
2401	bpl.b	.u
2402
2403	tst.b	mLoop(a4)
2404	bne.b	.q2
2405	st	mOnOff(a4)
2406	bra.b	.u
2407
2408.q2	move.l	mLLength(a4),d6
2409	sub.l	(a4),a0
2410	add.l	mLStart(a4),a0
2411	sub.l	d6,a0
2412	add.l	d6,mLength(a4)
2413	move.l	a0,(a4)
2414.u	rts
2415
2416.ty	addq	#1,d7
2417	beq.b	.u
2418
2419	moveq	#0,d0
2420	lsr	d7
2421	bcc.b	.sk
2422	move	d0,(a2)+
2423.sk	subq	#1,d7
2424	bmi.b	.u
2425.lk	move.l	d0,(a2)+
2426	dbf	d7,.lk
2427	rts
2428
2429.vol0	move.l	clock(a5),d4
2430	moveq	#0,d0
2431	move	mPeriod(a4),d0
2432
2433	divu.l	d0,d4
2434
2435	lsl.l	#8,d4
2436	lsl.l	#6,d4
2437
2438	move.l	mrate(a5),d0
2439	lsr.l	#4,d0
2440
2441	divu.l	d0,d4
2442
2443	move.l	(a4),a0
2444	move.l	mFPos(a4),d0
2445
2446	mulu.l	d7,d4
2447
2448	swap	d0
2449	add.l	d4,d0			; Position after "mixing"
2450	swap	d0
2451
2452	moveq	#0,d1
2453	move	d0,d1
2454	add.l	d1,a0
2455	clr	d0
2456	move.l	a0,(a4)
2457	move.l	d0,mFPos(a4)
2458	sub.l	d1,mLength(a4)
2459	bpl.b	.ty			; OK, Done!
2460
2461; We're about to mix past the end of the sample
2462
2463	tst.b	mLoop(a4)
2464	bne.b	.q3
2465	st	mOnOff(a4)
2466	bra.b	.ty
2467
2468.q3	move.l	mLLength(a4),d6
2469.loop	sub.l	d6,a0
2470	add.l	d6,mLength(a4)
2471	bmi.b	.loop
2472	beq.b	.loop
2473
2474	move.l	a0,(a4)
2475	bra.b	.ty
2476
2477
2478; Mixing routine for rest of the channels (adds data)
2479
2480mix162_020
2481	moveq	#0,d7
2482	move	bytes2do(a5),d7
2483	tst	mPeriod(a4)
2484	beq.w	.ty
2485	tst.b	mOnOff(a4)
2486	bne.w	.ty
2487
2488	tst	mVolume(a4)
2489	beq.w	.vol0
2490
2491.dw	move.l	clock(a5),d4
2492	moveq	#0,d0
2493	move	mPeriod(a4),d0
2494
2495	divu.l	d0,d4
2496
2497	lsl.l	#8,d4
2498	lsl.l	#6,d4
2499
2500	move.l	mrate(a5),d0
2501	lsr.l	#4,d0
2502
2503	divu.l	d0,d4
2504
2505	swap	d4
2506
2507	move.l	vtabaddr(a5),a3
2508	move	mVolume(a4),d0
2509	mulu	PS3M_master(a5),d0
2510	lsr	#6,d0
2511	add	d0,d0
2512	lsl.l	#8,d0
2513	add.l	d0,a3			; Position in volume table
2514
2515	move.l	(a4),a0
2516	move.l	mFPos(a4),d0
2517
2518	move.l	mLength(a4),d6
2519	beq.w	.resloop
2520
2521	cmp.l	#$ffff,d6
2522	bls.b	.restart
2523	move	#$ffff,d6
2524.restart
2525	swap	d6
2526	swap	d0
2527	sub.l	d0,d6
2528	swap	d0
2529
2530	move.l	d4,d5
2531	swap	d5
2532
2533	divul.l	d5,d5:d6		; bytes left to loop end
2534	tst.l	d5
2535	beq.b	.e
2536	addq.l	#1,d6
2537.e	moveq	#0,d2
2538	moveq	#0,d5
2539.mixloop
2540	moveq	#8,d1
2541	cmp	d1,d7
2542	bhi.b	.ok
2543	move	d7,d1
2544.ok	cmp.l	d1,d6
2545	bhi.b	.ok2
2546	move	d6,d1
2547.ok2	sub	d1,d7
2548	sub.l	d1,d6
2549	jmp	.jtab1(pc,d1*2)
2550
2551.a set 0
2552.jtab1
2553	rept	8
2554	bra.b	.mend-.a
2555.a set .a+14				; (mend - dmix) / 8
2556	endr
2557
2558.dmix	rept	8
2559	move.b	(a0,d0),d2
2560	add.l	d4,d0
2561	move	(a3,d2*2),d3
2562	addx	d5,d0
2563	add	d3,(a2)+
2564	endr
2565
2566.mend	tst	d7
2567	beq.b	.done
2568	tst.l	d6
2569	bne.w	.mixloop
2570
2571.resloop
2572	tst.b	mLoop(a4)
2573	bne.b	.q
2574	st	mOnOff(a4)
2575	bra.b	.tyy
2576
2577.q	moveq	#0,d1
2578	move	d0,d1
2579	sub.l	mLength(a4),d1
2580	move.l	mLStart(a4),a0
2581	add.l	d1,a0
2582	move.l	mLLength(a4),d6
2583	sub.l	d1,d6
2584	move.l	d6,mLength(a4)
2585	cmp.l	#$ffff,d6
2586	bls.b	.j
2587	move	#$ffff,d6
2588.j	clr	d0			;reset integer part
2589	bra.w	.restart
2590
2591.done	moveq	#0,d1
2592	move	d0,d1
2593	add.l	d1,a0
2594	clr	d0
2595	move.l	a0,(a4)
2596	move.l	d0,mFPos(a4)
2597	sub.l	d1,mLength(a4)
2598	bpl.b	.u
2599
2600	tst.b	mLoop(a4)
2601	bne.b	.q2
2602	st	mOnOff(a4)
2603	bra.b	.u
2604
2605.q2	move.l	mLLength(a4),d6
2606	sub.l	(a4),a0
2607	add.l	mLStart(a4),a0
2608	sub.l	d6,a0
2609	add.l	d6,mLength(a4)
2610	move.l	a0,(a4)
2611.u
2612.ty
2613.tyy	rts
2614
2615
2616.vol0	move.l	clock(a5),d4
2617	moveq	#0,d0
2618	move	mPeriod(a4),d0
2619
2620	divu.l	d0,d4
2621
2622	lsl.l	#8,d4
2623	lsl.l	#6,d4
2624
2625	move.l	mrate(a5),d0
2626	lsr.l	#4,d0
2627
2628	divu.l	d0,d4
2629
2630	move.l	(a4),a0
2631	move.l	mFPos(a4),d0
2632
2633	mulu.l	d7,d4
2634
2635	swap	d0
2636	add.l	d4,d0			; Position after "mixing"
2637	swap	d0
2638
2639	moveq	#0,d1
2640	move	d0,d1
2641	add.l	d1,a0
2642	clr	d0
2643	move.l	a0,(a4)
2644	move.l	d0,mFPos(a4)
2645	sub.l	d1,mLength(a4)
2646	bpl.b	.ty			; OK, Done!
2647
2648; We're about to mix past the end of the sample
2649
2650	tst.b	mLoop(a4)
2651	bne.b	.q3
2652	st	mOnOff(a4)
2653	bra.b	.ty
2654
2655.q3	move.l	mLLength(a4),d6
2656.loop	sub.l	d6,a0
2657	add.l	d6,mLength(a4)
2658	bmi.b	.loop
2659	beq.b	.loop
2660
2661	move.l	a0,(a4)
2662	bra.b	.ty
2663
2664	endc
2665
2666
2667* mulu_32 --- d0 = d0*d1
2668mulu_32	movem.l	d2/d3,-(sp)
2669	move.l	d0,d2
2670	move.l	d1,d3
2671	swap	d2
2672	swap	d3
2673	mulu	d1,d2
2674	mulu	d0,d3
2675	mulu	d1,d0
2676	add	d3,d2
2677	swap	d2
2678	clr	d2
2679	add.l	d2,d0
2680	movem.l	(sp)+,d2/d3
2681	rts
2682
2683* divu_32 --- d0 = d0/d1, d1=jakoj��nn�s
2684divu_32	move.l	d3,-(a7)
2685	swap	d1
2686	tst	d1
2687	bne.b	lb_5f8c
2688	swap	d1
2689	move.l	d1,d3
2690	swap	d0
2691	move	d0,d3
2692	beq.b	lb_5f7c
2693	divu	d1,d3
2694	move	d3,d0
2695lb_5f7c	swap	d0
2696	move	d0,d3
2697	divu	d1,d3
2698	move	d3,d0
2699	swap	d3
2700	move	d3,d1
2701	move.l	(a7)+,d3
2702	rts
2703
2704lb_5f8c	swap	d1
2705	move	d2,-(a7)
2706	moveq	#16-1,d3
2707	move	d3,d2
2708	move.l	d1,d3
2709	move.l	d0,d1
2710	clr	d1
2711	swap	d1
2712	swap	d0
2713	clr	d0
2714lb_5fa0	add.l	d0,d0
2715	addx.l	d1,d1
2716	cmp.l	d1,d3
2717	bhi.b	lb_5fac
2718	sub.l	d3,d1
2719	addq	#1,d0
2720lb_5fac	dbf	d2,lb_5fa0
2721	move	(a7)+,d2
2722	move.l	(a7)+,d3
2723	rts
2724
2725
2726
2727;;******** Init routines ***********
2728
2729detectchannels
2730	lea	ch(pc),a0
2731	moveq	#7,d0
2732.l2	clr.l	(a0)+
2733	dbf	d0,.l2
2734
2735	move.l	patts(a5),a1
2736	lea	ch(pc),a2
2737	move.l	s3m(a5),a0
2738	move	pats(a5),d7
2739	subq	#1,d7
2740.pattloop
2741	moveq	#0,d0
2742	move	(a1)+,d0
2743	beq.b	.qt
2744	iword	d0
2745	lsl.l	#4,d0
2746	lea	(a0,d0.l),a3
2747	addq.l	#2,a3
2748	moveq	#63,d6
2749.rowloop
2750	move.b	(a3)+,d0
2751	beq.b	.newrow
2752
2753	moveq	#31,d1
2754	and	d0,d1
2755
2756	moveq	#32,d2
2757	and	d0,d2
2758	beq.b	.nnot
2759
2760	tst.b	(a3)
2761	bmi.b	.skip
2762	beq.b	.skip
2763
2764	tst.b	1(a3)
2765	bmi.b	.skip
2766	beq.b	.skip
2767
2768	st	(a2,d1)
2769
2770.skip	addq.l	#2,a3
2771
2772.nnot	moveq	#64,d2
2773	and	d0,d2
2774	beq.b	.nvol
2775
2776	addq.l	#1,a3
2777
2778.nvol	and	#128,d0
2779	beq.b	.rowloop
2780
2781	move.b	(a3),d0
2782	cmp.b	#1,d0
2783	blo.b	.skip2
2784
2785	cmp.b	#`Z`-`@`,d0
2786	bhi.b	.skip2
2787
2788	st	(a2,d1)
2789
2790.skip2	addq.l	#2,a3
2791	bra.b	.rowloop
2792
2793.newrow
2794	dbf	d6,.rowloop
2795.qt
2796	dbf	d7,.pattloop
2797
2798	moveq	#1,d0
2799	moveq	#1,d1
2800	moveq	#31,d7
2801	moveq	#0,d5
2802	moveq	#0,d6
2803	lea	$40(a0),a1
2804	lea	pantab(a5),a0
2805.l	clr.b	(a0)
2806	tst.b	(a2)+
2807	beq.b	.d
2808
2809	move.b	(a1),d2
2810	bmi.b	.d
2811	cmp.b	#8,d2
2812	blo.b	.vas
2813	move.b	#-1,(a0)
2814	move	d1,d0
2815	addq	#1,d5
2816	bra.b	.d
2817.vas	move.b	#1,(a0)
2818	move	d1,d0
2819	addq	#1,d6
2820.d	addq.l	#1,a1
2821	addq.l	#1,a0
2822	addq	#1,d1
2823	dbf	d7,.l
2824
2825	cmp	d5,d6
2826	bls.b	.k
2827	move	d6,d5
2828.k	move	d5,maxchan(a5)
2829
2830	move	d0,numchans(a5)
2831	rts
2832
2833ch	ds.b	32
2834
2835
2836makedivtabs
2837	lea	data,a5
2838	move.l	vtabaddr(a5),d0			;Get address.
2839	tst.l	d0				;Is it 0?
2840	bne.s	making_tables			;>0 then make tables (Sean).
2841	rts
2842making_tables:
2843	cmp	#STEREO14,pmode(a5)
2844	beq.b	ret
2845
2846	lea	divtabs,a1
2847	move.l	dtab(a5),a0
2848
2849	move	#255,d6
2850	moveq	#0,d5
2851	move	maxchan(a5),d5
2852	move.l	d5,d3
2853	move.l	d5,d2
2854
2855	subq	#1,d5
2856	move	d5,d4
2857	lsl.l	#7,d5
2858
2859	lsl.l	#7,d2
2860
2861	sub.l	vboost(a5),d3
2862	cmp	#1,d3
2863	bge.b	.laa
2864	moveq	#1,d3
2865
2866.laa	moveq	#0,d0
2867	move	d6,d7
2868	move.l	a0,(a1)+
2869.al	move.l	d0,d1
2870	add.l	d5,d1
2871	sub.l	d2,d1
2872	divs	d3,d1
2873	cmp	#$7f,d1
2874	ble.b	.d
2875	move	#$7f,d1
2876.d	cmp	#$ff80,d1
2877	bge.b	.d2
2878	move	#$80,d1
2879.d2	move.b	d1,(a0)+
2880	addq.l	#1,d0
2881	dbf	d7,.al
2882
2883	add	#256,d6
2884	sub.l	#$80,d5
2885	dbf	d4,.laa
2886ret:	rts
2887
2888
2889Makevoltable
2890	move.l	vtabaddr(a5),a0
2891	move.l	a0,d0				;Address of table.
2892	tst.l	d0				;Is there a table yet?
2893	bne.s	mvt2				;Yes. (Sean).
2894	rts
2895
2896mvt2:	cmp	#STEREO14,pmode(a5)
2897	beq.b	bit16
2898
2899	moveq	#0,d3		;volume
2900	cmp	#1,fformat(a5)
2901	beq.b	signed
2902
2903.lop	moveq	#0,d4		;data
2904.lap	move	d4,d5
2905	sub	#$80,d5
2906	mulu	d3,d5
2907	asr.l	#6,d5
2908	add	#$80,d5
2909	move.b	d5,(a0)+
2910	addq	#1,d4
2911	cmp	#256,d4
2912	bne.b	.lap
2913	addq	#1,d3
2914	cmp	#65,d3
2915	bne.b	.lop
2916	rts
2917
2918signed
2919.lop	moveq	#0,d4		;data
2920.lap	move.b	d4,d5
2921	ext	d5
2922	mulu	d3,d5
2923	asr.l	#6,d5
2924	add	#$80,d5
2925	move.b	d5,(a0)+
2926	addq	#1,d4
2927	cmp	#256,d4
2928	bne.b	.lap
2929	addq	#1,d3
2930	cmp	#65,d3
2931	bne.b	.lop
2932	rts
2933
2934
2935bit16	move	maxchan(a5),d3
2936	moveq	#0,d7			; "index"
2937	cmp	#1,fformat(a5)
2938	beq.b	signed2
2939
2940.lop	move	d7,d6
2941	tst.b	d7
2942	bmi.b	.above
2943
2944	and	#127,d6
2945	move	#128,d5
2946	sub	d6,d5
2947	lsl	#8,d5
2948	move	d7,d6
2949	lsr	#8,d6
2950	mulu	d6,d5
2951	divu	#63,d5
2952	swap	d5
2953	clr	d5
2954	swap	d5
2955	divu	d3,d5
2956.ska1	neg	d5
2957	move	d5,(a0)+
2958	addq	#1,d7
2959	cmp	#256*65,d7
2960	bne.b	.lop
2961	rts
2962
2963.above	and	#127,d6
2964	lsl	#8,d6
2965
2966	move	d7,d5
2967	lsr	#8,d5
2968	mulu	d6,d5
2969	divu	#63,d5
2970	swap	d5
2971	clr	d5
2972	swap	d5
2973	divu	d3,d5
2974.ska2	move	d5,(a0)+
2975	addq	#1,d7
2976	cmp	#256*65,d7
2977	bne.b	.lop
2978	rts
2979
2980signed2
2981.lop	move	d7,d6
2982	tst.b	d7
2983	bpl.b	.above
2984
2985	and	#127,d6
2986	move	#128,d5
2987	sub	d6,d5
2988	lsl	#8,d5
2989	move	d7,d6
2990	lsr	#8,d6
2991	mulu	d6,d5
2992	divu	#63,d5
2993	swap	d5
2994	clr	d5
2995	swap	d5
2996	divu	d3,d5
2997.ska3	neg	d5
2998	move	d5,(a0)+
2999	addq	#1,d7
3000	cmp	#256*65,d7
3001	bne.b	.lop
3002	rts
3003
3004.above	and	#127,d6
3005	lsl	#8,d6
3006
3007	move	d7,d5
3008	lsr	#8,d5
3009	mulu	d6,d5
3010	divu	#63,d5
3011	swap	d5
3012	clr	d5
3013	swap	d5
3014	divu	d3,d5
3015.ska4	move	d5,(a0)+
3016	addq	#1,d7
3017	cmp	#256*65,d7
3018	bne.b	.lop
3019	rts
3020
3021
3022do14tab	move.l	buff14(a5),a0
3023	moveq	#0,d7
3024.loo	move	d7,d2
3025	bpl.b	.plus
3026
3027	neg	d2
3028	move	d2,d3
3029	lsr	#8,d2
3030	neg.b	d2
3031
3032	lsr.b	#2,d3
3033	neg	d3
3034
3035	move.b	d2,(a0)+
3036	move.b	d3,(a0)+
3037	addq.l	#2,d7
3038	cmp.l	#$10000,d7
3039	bne.b	.loo
3040	rts
3041
3042.plus	move	d2,d3
3043	lsr	#8,d2
3044	lsr.b	#2,d3
3045	move.b	d2,(a0)+
3046	move.b	d3,(a0)+
3047	addq.l	#2,d7
3048	cmp.l	#$10000,d7
3049	bne.b	.loo
3050	rts
3051
3052
3053
3054
3055
3056
3057
3058******************************************************************************
3059******************************************************************************
3060******************************************************************************
3061* Soittolooppi
3062
3063
3064; PLAYING PROCESSES: HALF-FRIENDLY mode.
3065; ��������������������������������������
3066
3067
3068s3mPlay	lea	data,a5
3069	move.w	#$0f,$dff096		;Clear audio DMA.
3070
3071	move.l	4.w,a6
3072	move.b	PowerSupplyFrequency(a6),d0
3073	cmp.b	#60,d0
3074	beq.b	.NTSC
3075	move.l	#3546895,audiorate(a5)
3076	bra.b	.qw
3077.NTSC
3078	move.l	#3579545,audiorate(a5)
3079.qw
3080	move.l	audiorate(a5),d0
3081	move.l	mixingrate(a5),d1
3082	divu	d1,d0
3083	move.l	audiorate(a5),d1
3084	divu	d0,d1
3085	swap	d1
3086	clr	d1
3087	swap	d1
3088	move.l	d1,mrate(a5)
3089
3090	move.l	audiorate(a5),d0
3091	divu	d1,d0
3092
3093	swap	d0
3094	clr	d0
3095	swap	d0
3096	move.l	d0,mixingperiod(a5)
3097
3098	lsl.l	#8,d1				; 8-bit fraction
3099	move.l	d1,d0
3100	move.l	4.w,a6
3101	moveq	#0,d1
3102	move.b	VBlankFrequency(a6),d1
3103	bsr.w	divu_32
3104	move.l	d0,mrate50(a5)			;In fact vblank frequency
3105
3106	movem.l	buff1(a5),a0-a3
3107	move.l	mixingperiod(a5),d0
3108
3109	lea	$dff000,a6
3110	move.l	buffSize(a5),d1
3111	lsr.l	#1,d1
3112	move	d1,$a4(a6)
3113	move	d1,$b4(a6)
3114	move	d1,$c4(a6)
3115	move	d1,$d4(a6)
3116	move	d0,$a6(a6)
3117	move	d0,$b6(a6)
3118	move	d0,$c6(a6)
3119	move	d0,$d6(a6)
3120
3121	moveq	#64,d1
3122
3123	move	pmode(a5),d0
3124	cmp.w	#SURROUND,d0
3125	bne.b	.nosurround
3126
3127	moveq	#32,d2
3128
3129	move.l	a0,$a0(a6)
3130	move.l	a1,$b0(a6)
3131	move.l	a0,$c0(a6)
3132	move.l	a1,$d0(a6)
3133	move	d1,$a8(a6)
3134	move	d1,$b8(a6)
3135	move	d2,$c8(a6)
3136	move	d2,$d8(a6)
3137	bra.w	.ohiis
3138
3139.nosurround
3140	cmp.w	#STEREO,d0
3141	bne.b	.nostereo
3142
3143	move.l	a0,$a0(a6)
3144	move.l	a1,$b0(a6)
3145	move.l	a1,$c0(a6)
3146	move.l	a0,$d0(a6)
3147	move	d1,$a8(a6)
3148	move	d1,$b8(a6)
3149	move	d1,$c8(a6)
3150	move	d1,$d8(a6)
3151	bra.b	.ohiis
3152
3153.nostereo
3154	cmp.w	#MONO,d0
3155	bne.b	.nomono
3156
3157	move.l	a0,$a0(a6)
3158	move.l	a1,$b0(a6)
3159	move.l	a0,$c0(a6)
3160	move.l	a1,$d0(a6)
3161	move	d1,$a8(a6)
3162	move	d1,$b8(a6)
3163	move	d1,$c8(a6)
3164	move	d1,$d8(a6)
3165	bra.b	.ohiis
3166
3167.nomono
3168
3169; REAL SURROUND!
3170
3171	cmp.w	#REAL,d0
3172	bne.b	.bit14
3173
3174	move.l	a0,$a0(a6)
3175	move.l	a1,$b0(a6)
3176	move.l	a2,$c0(a6)
3177	move.l	a3,$d0(a6)
3178	move	d1,$a8(a6)
3179	move	d1,$b8(a6)
3180	move	d1,$c8(a6)
3181	move	d1,$d8(a6)
3182	bra.b	.ohiis
3183
3184
3185; 14-BIT STEREO
3186
3187.bit14	moveq	#1,d2
3188
3189	move.l	a0,$a0(a6)
3190	move.l	a1,$b0(a6)
3191	move.l	a3,$c0(a6)
3192	move.l	a2,$d0(a6)
3193	move	d1,$a8(a6)
3194	move	d1,$b8(a6)
3195	move	d2,$c8(a6)
3196	move	d2,$d8(a6)
3197
3198.ohiis	move.l	4.w,a6
3199	moveq	#0,d0
3200	btst	d0,AttnFlags+1(a6)
3201	beq.b	.no68010
3202
3203	push	a5
3204	lea	liko,a5
3205	call	_LVOSupervisor
3206	pull	a5
3207.no68010
3208	move.l	d0,vbrr(a5)
3209
3210	push	a5
3211	bsr	FinalInit
3212	pull	a5
3213
3214	lea	$dff000,a6
3215	move.l	vbrr(a5),a0
3216	move.l	$70(a0),olev4(a5)
3217	lea	lev4,a3
3218	move.l	a3,$70(a0)
3219	move.w	#$800f,$96(a6)
3220	move.w	#$c080,$9a(a6)
3221StartModule:
3222	bsr	SetCIAInt
3223	rts
3224** You don't have to call play within regular intervals. The routine just
3225** swallows cpu as it sees fit, but probably some 50Hz is the best.
3226
3227
3228stop_interrupt	lea	data,a5
3229	bsr	RemCIAInt
3230	move.l	vbrr(a5),a0
3231	move.l	olev4(a5),$70(a0)
3232	lea	$dff000,a6
3233	clr	$a8(a6)			;Volumes down...
3234	clr	$b8(a6)
3235	clr	$c8(a6)
3236	clr	$d8(a6)
3237	move.w	#$80,$9a(a6)
3238	bsr	s3end
3239	moveq.l	#0,d0
3240	rts
3241
3242liko
3243	ifeq	disable020
3244	MOVEC	VBR,d0
3245	endc
3246	rte
3247
3248
3249
3250;	/*
3251;	** Routines to setup/stop the interrupt servers.
3252;	*/
3253
3254****************************************************************************
3255*
3256* A system friendly way to use the CIA timer interrupts
3257*
3258* By K-P Koljonen 7.8.1996
3259*
3260* E-mail: k-p@kalahari.ton.tut.fi
3261*         kpk@pcuf.fi
3262*
3263* ---
3264*
3265* Call init_ciaint() to initialize interrupt and rem_ciaint()
3266* to remove interrupt.
3267*
3268****************************************************************************
3269
3270
3271
3272
3273
3274SetCIAInt	lea	icause,a0
3275	lea	ciainterrupt,a1
3276	move.l	a1,(a0)
3277	lea	sptr1,a0
3278	lea	softserver,a1
3279	move.l	a1,(a0)
3280	lea	sint,a0
3281	lea	softint,a1
3282	move.l	a1,(a0)
3283	bsr.b	init_ciaint
3284	rts
3285
3286init_ciaint	lea	data,a5			;Pointer to data structure.
3287	lea	cianame,a1			;Pointer to CIA name.
3288	move.l	a1,-(sp)			;Save address.
3289	move.b	#'a',3(a1)			;Set up CIA-A first.
3290	move.l	$4.w,a6				;Execbase address.
3291	moveq.l	#0,d0				;Clear D0.
3292	jsr	_LVOOpenResource(a6)		;Open CIA resources.
3293	move.l	d0,ciabasea(a5)			;Store CIA pointer.
3294	move.l	(sp)+,a1			;Restore CIA name pointer.
3295	move.b	#'b',3(a1)			;Setup CIA-B second.
3296	moveq.l	#0,d0				;Clear D0.
3297	jsr	_LVOOpenResource(a6)		;Open CIA resources.
3298	move.l	d0,ciabaseb(a5)			;Store CIA pointer.
3299
3300	movem.l	d1-a6,-(sp)			;Save registers.
3301
3302	move.w	#28419/2,timerhi(a5)		;50 hz timer interval.
3303** CIAA
3304	lea	_ciaa,a3			;Pointer to CIA-A base.
3305	lea	ciaserver,a4		;Pointer to CIA server.
3306	moveq.l	#0,d6				;Clear D6.
3307	move.l	ciabasea(a5),a6			;Pointer to CIA base address.
3308	lea	(a4),a1				;Get address.
3309	moveq.l	#0,d0				;Timer A.
3310	move.l	d0,d6				;Setup D6.
3311	jsr	_LVOAddICRVector(a6)		;Set ICR vector.
3312	tst.l	d0				;OK?
3313	beq.s	gottimer			;Yes.
3314
3315	lea	(a4),a1				;Address to A1.
3316	moveq.l	#1,d0				;Timer B.
3317	move.l	d0,d6				;Timer B to d6.
3318	jsr	_LVOAddICRVector(a6)		;Set ICR vector.
3319	tst.l	d0				;OK?
3320	beq.s	gottimer			;Yes.
3321
3322** CIAB
3323	lea	_ciab,a3			;Pointer to CIA-B base.
3324	lea	ciaserver,a4		;Pointer to CIA server.
3325	moveq.l	#0,d6				;Clear D6.
3326	move.l	ciabaseb(a5),a6			;Get pointer.
3327	lea	(a4),a1				;Address to A1.
3328	moveq.l	#0,d0				;Timer a
3329	move.l	d0,d6				;Clear D6.
3330	jsr	_LVOAddICRVector(a6)		;Set ICR vector.
3331	tst.l	d0				;OK?
3332	beq.s	gottimer			;Yes.
3333
3334	lea	(a4),a1				;Address to A1.
3335	moveq.l	#1,d0				;Timer B.
3336	move.l	d0,d6				;D6=1.
3337	jsr	_LVOAddICRVector(a6)		;Add interrupt server.
3338	tst.l	d0				;Is it OK?
3339	beq.s	gottimer			;Yes.
3340
3341	movem.l	(sp)+,d1-a6			;Restore regs.
3342	moveq.l	#-1,d0				;ERROR! No timer available!
3343	rts
3344
3345gottimer
3346	move.l	a3,ciaddr(a5)			;Address set up.
3347	move.l	a6,ciabase(a5)			;Address set up.
3348	move.b	d6,whichtimer(a5)		;0: timer a, 1:timer b.
3349
3350** Set up timer registers
3351
3352	lea	ciatalo(a3),a2			;Address to A2.
3353	tst.b	d6				;Is it timer A?
3354	beq.b	timera				;Yes.
3355	lea	ciatblo(a3),a2			;Timer B low address.
3356timera	move.b	timerlo(a5),(a2)		;Timer low byte.
3357	move.b	timerhi(a5),$100(a2)		;High byte.
3358
3359	lea	ciacra(a3),a2			;Address to A2.
3360	tst.b	d6				;Is it timer A?
3361	beq.b	tima				;Yes.
3362	lea	ciacrb(a3),a2			;Address to A2.
3363tima
3364
3365** timer control register
3366wraster:
3367	cmp.b	#$c0,$dff006
3368	bne.s	wraster
3369	move.b	#%00010001,(a2)			;Continuous, force load.
3370	movem.l	(sp)+,d1-a6			;Restore regs.
3371	moveq.l	#0,d0				;OK message.
3372	rts					;End.
3373
3374
3375
3376RemCIAInt:
3377	movem.l	d0-a6,-(sp)			;Save regs.
3378	move.l	ciaddr(a5),a3			;Address to A3.
3379
3380	moveq.l	#0,d0				;Clear D0.
3381	move.b	whichtimer(a5),d0		;Get timer value.
3382	bne.b	tb				;1=Timer B.
3383	move.b	#%00000000,ciacra(a3)		;Clear timer A.
3384	bra.b	ta				;Skip next command.
3385tb	move.b	#%00000000,ciacrb(a3)		;Clear timer B.
3386ta	move.l	ciabase(a5),a6			;CIA address to A6.
3387	lea	ciaserver,a1		;Pointer to server.
3388	jsr	_LVORemICRVector(a6)		;Remove ICR vector.
3389	movem.l	(sp)+,d0-a6			;Restore regs.
3390	rts
3391
3392
3393
3394ciaserver:
3395	dc.l	0,0
3396	dc.b	2
3397	dc.b	0		* interrupt priority
3398nptr1:	dc.l	0		* node name
3399sptr1:	dc.l	0		* IS_DATA
3400icause:	dc.l	0		* IS_CODE
3401
3402intname2:
3403	dc.b	"PS3M Audio Interrupt",0
3404	even
3405cianame:
3406	dc.b	"ciaa.resource",0
3407	even
3408
3409* Cause() a level 1 software interrupt to avoid executing code in high
3410* priority interrupts (CIAA = lev 2, CIAB = lev 6). Lev 6 easily
3411* interferes with serial transfers.
3412
3413ciainterrupt
3414* a6 = execbase
3415* a1 = softserver address
3416	move.l	4.w,a6
3417	jsr	_LVOCause(a6)
3418	moveq	#0,d0
3419	rts
3420
3421softserver	dc.l	0,0
3422	dc.b	2
3423	dc.b	0		* interrupt priority
3424	dc.l	0		* node name
3425	dc.l	$bfe001		* IS_DATA
3426sint	dc.l	0		* IS_CODE
3427
3428interrupt_mutex		dc.l	0
3429uade_restart_cmd	dc.l	0
3430uade_stop_cmd		dc.l	0
3431uade_active_channels	dc.l	0
3432
3433softint	tst.l	interrupt_mutex
3434	bne.b	no_softint
3435	st	interrupt_mutex
3436
3437	movem.l	d2-d7/a0/a2-a4/a6,-(sp)
3438	bsr	play
3439	movem.l	(sp)+,d2-d7/a0/a2-a4/a6
3440
3441	move.l	uade_restart_cmd,d0
3442	;or.l	uade_stop_cmd,d0
3443	cmp.l	#-1,d0
3444	bne.b	not_song_end
3445	bsr	report_song_end
3446not_song_end
3447	clr.l	interrupt_mutex
3448no_softint	moveq	#0,d0
3449	rts
3450
3451;	/*
3452;	** Time to declare the S3M audio mixer structure space.
3453;	*/
3454
3455;*** Datas ***
3456
3457data:
3458
3459vbrr		dc.l	0
3460olev4		dc.l	0
3461olev3		dc.l	0
3462vtabaddr	dc.l	0
3463playpos		dc.l	0
3464bufpos		dc.l	0
3465buffSize	dc.l	BUFFER
3466buffSizeMask	dc.l	BUFFER-1
3467
3468bytesperframe	dc	0
3469bytes2do	dc	0
3470todobytes	dc	0
3471bytes2music	dc	0
3472;	ifne	debug
3473kalas		dc.l	$c70000
3474;	endc
3475
3476mixad1		dc.l	0
3477mixad2		dc.l	0
3478cbufad		dc.l	0
3479opt020		dc	0
3480
3481mixingrate	dc.l	16000
3482mixingperiod	dc.l	0
3483vboost		dc.l	0
3484pmode		dc	SURROUND
3485system		dc	DISABLED
3486
3487PS3M_play	dc	0
3488PS3M_break	dc	0
3489PS3M_poscha	dc	0
3490PS3M_position	dc	0
3491PS3M_master	dc	64
3492PS3M_eject	dc	0
3493PS3M_wait	dc	0
3494PS3M_cont	dc	0
3495PS3M_paused	dc	0
3496PS3M_initialized dc	0
3497PS3M_reinit	dc	0
3498
3499audiorate	dc.l	0
3500mrate		dc.l	0
3501mrate50		dc.l	0
3502
3503slen		dc	0
3504pats		dc	0
3505inss		dc	0
3506
3507samples		dc.l	0
3508patts		dc.l	0
3509
3510fformat		dc	0
3511sflags		dc	0
3512
3513rows		dc	63
3514pbrkrow		dc	0
3515pjmpflag	dc	0
3516pbrkflag	dc	0
3517spd		dc	6
3518tempo		dc	125
3519
3520cn		dc	0
3521pdelaycnt	dc	0
3522
3523chans		dc	0
3524numchans	dc	0
3525maxchan		dc	0
3526mtype		dc	0
3527clock		dc.l	0			; 14317056/4 for S3Ms
3528globalVol	dc	0
3529
3530pos		dc	0
3531plen		dc	0
3532ppos		dc.l	0
3533
3534divtabs		ds.l	16
3535
3536c0		ds.b	s3mChanBlock_SIZE*32
3537
3538cha0		ds.b	mChanBlock_SIZE*32
3539
3540pantab		ds.b	32			;channel panning infos
3541
3542
3543s3m		dc.l	0
3544s3mlen		dc.l	0
3545
3546tbuf		dc.l	0
3547tbuf2		dc.l	0
3548
3549buff1		dc.l	0
3550buff2		dc.l	0
3551buff3		dc.l	0
3552buff4		dc.l	0
3553buff14		dc.l	0
3554vtab		dc.l	0
3555dtab		dc.l	0
3556dtabsize	dc.l	0
3557
3558mname		dc.l	0
3559
3560frate		dc.l	16000
3561fboost		dc.l	0
3562fpmode		dc	SURROUND
3563fstate		dc	DISABLED
3564forced		dc	0	; Bits:
3565				; 0 mixing rate
3566				; 1 volume boost
3567				; 2 playing mode
3568				; 3 system state
3569
3570segment		dc.l	0
3571errorcode	dc.l	0
3572params		dc	0
3573bann		dc	0
3574
3575config		dc.l	0
3576conlen		dc.l	0
3577
3578buhku		dc.l	0,0
3579lock		dc.l	0
3580
3581ciabasea	dc.l	0	;(LONG) *
3582ciabaseb	dc.l	0	;(LONG) *
3583ciabase		dc.l	0	;(LONG) *
3584ciaddr		dc.l	0	;(LONG) *
3585positioneita	dc	1
3586
3587;loopcnt		dc	0
3588;loopflag	dc	0
3589;looprow		dc	0
3590
3591timerhi		dc.b	0	;(BYTE) *
3592timerlo		dc.b	0	;(BYTE) *
3593whichtimer	dc.b	0	;(BYTE) *
3594xmsign		dc.b	'Extended Module:'
3595
3596dosname	dc.b	"dos.library",0
3597	even
3598dosbase	dc.l	0
3599
3600	incdir amiga:work/uade-2/amigasrc/players/ps3m/
3601	include chk_ps3m.s
3602	include	ply_s3m.s
3603	include	ply_mod.s
3604	include	ply_xm.s
3605
3606