1; SOUND.ASM
2; ---------
3;
4; A PSG driver which is compatible with the "track data"
5; and other bytecodes as used by the CDROM System Card
6;
7
8
9psg_bios:	phx
10		phy
11		tma	#PAGE(psg_on)
12		pha
13		lda	#BANK(psg_on)
14		tam	#PAGE(psg_on)
15		lda	<_dh
16		asl	A
17		tax
18		jsr	.indir_jmp
19		tax
20		pla
21		tam	#PAGE(psg_on)
22		txa
23		ply
24		plx
25		rts
26.indir_jmp:	jmp	[.functbl,X]
27
28.functbl:	.dw	psg_on		; psg_on       (00)
29		.dw	psg_off		; psg_off      (01)
30		.dw	psg_init	; psg_init     (02)
31		.dw	psg_bank	; psg_bank     (03)
32		.dw	psg_track	; psg_track    (04)
33		.dw	psg_wave	; psg_wave     (05)
34		.dw	psg_env 	; psg_env      (06)
35		.dw	psg_fm		; psg_fm       (07)
36		.dw	psg_pe		; psg_pe       (08)
37		.dw	psg_pc		; psg_pc       (09)
38		.dw	psg_settempo	; psg_settempo (0a)
39		.dw	psg_play	; psg_play     (0b)
40		.dw	psg_mstat	; psg_mstat    (0c)
41		.dw	psg_sstat	; psg_sstat    (0d)
42		.dw	psg_mstop	; psg_mstop    (0e)
43		.dw	psg_sstop	; psg_sstop    (0f)
44		.dw	psg_astop	; psg_astop    (10)
45		.dw	psg_mvoff	; psg_mvoff    (11)
46		.dw	psg_cont	; psg_cont     (12)
47		.dw	psg_fdout	; psg_fdout    (13)
48		.dw	psg_dcnt	; psg_dcnt     (14)
49
50;
51; Origin is at $C000.
52;
53; This is normally occupied by "START_BANK" when the program
54; is destined for CDROM, but should be OK for HuCard-only
55; development (note: PSG player exists in system card when
56; developing for CDROM)
57;
58
59	.bank	PSG_BANK,"PSG Driver"
60	.org	$C000
61
62
63; ----
64; PSG_ON
65; ----
66; CDROM version takes a parameter in _al
67; 0=TIMER, 1=VSYNC
68;
69; This version will only support TIMER interrupt
70;
71psg_on:
72	bbs7	<psg_inhibit,.noturnoff
73	bsr	psg_off
74	smb7	<psg_inhibit
75.noturnoff:
76	lda	#1
77	sta	timer_ctrl
78	rts
79
80
81; ----
82; PSG_OFF
83; ----
84;
85; turn off PSG
86; - all sound
87; - interrupt service (if TIMER)
88;
89psg_off:
90	bbs7	<psg_inhibit,.nostop
91	jsr	psg_astop
92.nostop:
93	stz	timer_ctrl
94	rts
95
96
97; ----
98; PSG_INIT
99; ----
100;
101; Initialize PSG.  CDROM version has a parameter:
102; 0=main track only; 60Hz
103; 1=sub track only; 60Hz
104; 2=both tracks; 60Hz
105; 3=both tracks; 120Hz
106; 4=both tracks; 240Hz
107; 5=both tracks; 300Hz
108;
109; This version only supports "both channels/60Hz" for now
110;
111psg_init:
112
113; initialize some IRQ stuff & zero values
114
115	stz	psg_tempo	; clear header info
116	tii	psg_tempo, psg_tempo+1, 19
117
118;	stz	psg_trkptr_l	; clear per-track info
119;	tii	psg_trkptr_l,psg_trkptr_l+1,????
120
121	stz	<psg_irqflag
122	stz	<psg_tmpptr
123	stz	<psg_tmpptr+1
124	stz	<psg_tmpptr1
125	stz	<psg_tmpptr1+1
126
127	smb7	<psg_inhibit
128
129;
130; reset hardware
131;
132	ldx	#5
133	lda	#PSG_DDA
134.loop1:	stx	psg_ch_value	; $0800 register value
135	stx	psg_ch		; set channel
136	sta	psg_ctrl	; reset channel
137	stz	psg_ctrl	; reset wave buffer
138	tin	psg_waveforms,psg_wavebuf,$0020	; simple squarewave
139	dex
140	bpl	.loop1
141
142	lda	#$ff		; set global hardware values
143	sta	psg_mainvol
144
145	lda	#$01
146	sta	psg_lfofreq
147	stz	psg_lfoctrl
148
149;
150; set some basic default values
151;
152	lda	#$80
153	sta	psg_song
154
155	lda	#(PSG_MAINPAUSE | PSG_SUBPAUSE)
156	sta	psg_trkctrl
157
158	lda	#$26		; is this right ?
159	jsr	psg_settempo
160
161	rts
162
163
164; ----
165; PSG_BANK
166; ----
167
168psg_bank:
169      __ldw	<_ax
170      __stw	psg_bank1
171	rts
172
173
174; ----
175; PSG_TRACK
176; ----
177
178psg_track:
179      __ldw	<_ax
180      __stw	psg_trkhdr
181	rts
182
183
184; ----
185; PSG_WAVE
186; ----
187
188psg_wave:
189      __ldw	<_ax
190      __stw	psg_wavehdr
191	rts
192
193
194; ----
195; PSG_ENV
196; ----
197
198psg_env:
199      __ldw	<_ax
200      __stw	psg_envhdr
201	rts
202
203
204; ----
205; PSG_FM
206; ----
207
208psg_fm:
209      __ldw	<_ax
210      __stw	psg_fmhdr
211	rts
212
213
214; ----
215; PSG_PE
216; ----
217
218psg_pe:
219      __ldw	<_ax
220      __stw	psg_pehdr
221	rts
222
223
224; ----
225; PSG_PC
226; ----
227
228psg_pc:
229      __ldw	<_ax
230      __stw	psg_percusshdr
231	rts
232
233
234; ----
235; PSG_SETTEMPO
236; ----
237
238psg_settempo:
239	lda	<_al
240	sub	#$23
241	bpl	.okvalue
242	cla
243.okvalue:
244	tax
245	lda	psg_tempotbl,X
246	sta	psg_tempo
247	rts
248
249
250; ----
251; PSG_PLAY
252;
253; play song # in track list (_al = song #)
254; ----
255
256psg_play:
257	lda	<_al
258	sta	psg_song
259	rmb7	<psg_inhibit
260	rts
261
262
263; ----
264; PSG_MSTAT
265;
266; return bitmask of voices in use for main track
267; ----
268
269psg_mstat:
270	ldy	#5
271	cla
272
273.loop:	ldx	psg_voicectrl,Y
274	beq	.empty
275	sec
276	rol	A
277	bra	.next
278.empty:	clc
279	rol	A
280.next:	dey
281	bpl	.loop
282	rts
283
284
285; ----
286; PSG_SSTAT
287;
288; return bitmask of voices in use for sub track
289; ----
290
291psg_sstat:
292	ldy	#5
293	cla
294
295.loop:	ldx	psg_voicectrl+6,Y
296	beq	.empty
297	sec
298	rol	A
299	bra	.next
300.empty:	clc
301	rol	A
302.next:	dey
303	bpl	.loop
304	rts
305
306
307; ----
308; PSG_MSTOP
309;
310; Stop voices in main track, as described in bitmask (in _al)
311; ----
312
313psg_mstop:
314	lda	<_al
315	bpl	.nopause
316
317	lda	#PSG_MAINPAUSE	; set pause on MAIN track
318	tsb	psg_trkctrl
319
320	lda	<_al
321
322.nopause:
323	tay
324	clx
325
326.loop:	lda	psg_voicectrl,X
327	beq	.nextvoice
328	tya
329	bmi	.pause		; is it a 'pause' for voice ?
330
331	lsr	A		; no, it is a 'stop'
332	bcc	.nextvoice	; this voice not in mask; skip it
333
334	stz	psg_voicectrl,X
335
336.pause:	lda	psg_voicectrl+6,X	; check subtrack
337	cmp	#1
338	beq	.nextvoice
339
340	stx	psg_ch_value
341	stx	psg_ch
342	stz	psg_ctrl
343
344.nextvoice:
345	inx
346	cpx	#6
347	bcs	.out
348	tya
349	bmi	.pause2
350
351	lsr	A
352	tay
353	bra	.loop
354
355.pause2:
356	lsr	A
357	ora	#$80		; retain high-bit set
358	tay
359	bra	.loop
360
361.out:	rts
362
363
364; ----
365; PSG_SSTOP
366;
367; Stop voices in sub track, as described in bitmask (in _al)
368; ----
369
370psg_sstop:
371	lda	<_al
372	bpl	.nopause
373
374	lda	#PSG_SUBPAUSE	; set pause on SUB track
375	tsb	psg_trkctrl
376
377	lda	<_al
378
379.nopause:
380	tay
381	clx
382
383.loop:	lda	psg_voicectrl+6,X
384	beq	.nextvoice
385	tya
386	bmi	.pause		; is it a 'pause' ?
387
388	lsr	A		; no, it is a 'stop'
389	bcc	.nextvoice	; voice not in mask; skip it
390
391	stz	psg_voicectrl+6,X
392	bra	.pause1
393.pause:
394	lda	#$ff		; pause control
395	sta	psg_voicectrl+6,X
396
397.pause1:
398	lda	psg_voicectrl,X
399	beq	.skipwave
400
401	lda	psg_wavenum,X
402	and	#$80
403	sta	psg_wavenum,X
404
405.skipwave:
406	lda	psg_trkctrl	; is anything playing on main track ?
407	bpl	.nextvoice	; yes... so don't stop it
408
409	stx	psg_ch_value
410	stx	psg_ch
411	stz	psg_ctrl
412
413.nextvoice:
414	inx
415	cpx	#6
416	bcs	.out
417	tya
418	bmi	.pause2
419
420	lsr	A
421	tay
422	bra	.loop
423
424.pause2:
425	lsr	A
426	ora	#$80
427	tay
428	bra	.loop
429
430.out:	rts
431
432
433; ----
434; PSG_ASTOP
435;
436; Stop all voices
437; ----
438
439psg_astop:
440	smb7	<psg_inhibit
441
442	lda	#(PSG_MAINPAUSE | PSG_SUBPAUSE)
443	sta	psg_trkctrl
444
445	ldx	#5
446.loop:	stz	psg_voicectrl,X		; disable main track
447	stz	psg_voicectrl+6,X	; disable sub track
448	stx	psg_ch
449	stz	psg_ctrl		; disable voice
450	dex
451	bpl	.loop
452
453	rts
454
455; ----
456; PSG_MVOFF
457;
458; Main volume off for voices specified in bitmask (in _al)
459; ----
460
461psg_mvoff:
462	lda	<_al
463	clx
464
465.loop:	lsr	A
466	bcc	.skip
467
468	ldy	psg_voicectrl,X
469	beq	.skip
470
471	pha
472	lda	#$ff		; turn off sound on voice
473	sta	psg_voicectrl,X
474	pla
475
476	ldy	psg_voicectrl+6,X
477	cpy	#1
478	beq	.skip
479
480	stx	psg_ch_value	; turn off voice
481	stx	psg_ch
482	stz	psg_ctrl
483
484.skip:	inx
485	cpx	#6
486	bcc	.loop
487
488	rts
489
490
491; ----
492; PSG_CONT
493;
494; "continue"
495; ----
496;
497; parameter:
498; 0 = main track
499; 1 = sub track
500; 2 = both
501;
502psg_cont:
503	lda	<_al
504	cmp	#1
505	beq	.sub
506
507	ldx	#5
508.loop:	lda	psg_voicectrl,X
509	beq	.next			; skip if disabled
510
511	lda	#1			; restart voice
512	sta	psg_voicectrl,X
513
514.next:	dex
515	bpl	.loop
516
517	lda	#PSG_MAINPAUSE		; release pause on main tracks
518	trb	psg_trkctrl
519
520.sub:	lda	<_al
521	beq	.end
522
523	ldx	#5
524.loop1:	lda	psg_voicectrl+6,X
525	beq	.next1			; skip if disabled
526
527	lda	#1			; restart voice
528	sta	psg_voicectrl+6,X
529
530	lda	psg_wavenum,X
531	and	#$80			; force re-download of waveform
532	sta	psg_wavenum,X
533
534.next1:	dex
535	bpl	.loop1
536
537	lda	#PSG_SUBPAUSE		; release pause on sub tracks
538	trb	psg_trkctrl
539
540.end:	rmb7	<psg_inhibit		; remove pause on irq processing
541	rts
542
543
544; ----
545; PSG_FDOUT
546; ----
547
548psg_fdout:
549	lda	<_al
550	bpl	.positive
551
552	eor	#$ff		; get absolute value from negative
553	inc	A
554
555.positive:
556	sta	psg_fadespeed	; store it as fade speed
557	stz	psg_fadecount	; reset fade levels
558	stz	psg_fadevolcut
559
560	rts
561
562
563; ----
564; PSG_DCNT
565;
566;  set delay counter - sets an up-counter to use if interrupt
567;  frequency is >60Hz, and this will act as a frequency divider
568;  (by ignoring interrupts until up-counter value is hit)
569;
570;  Not used in this implementation of PSG driver
571; ----
572
573psg_dcnt:
574	rts
575
576
577; ----
578; psg_drive - driver for MAIN tracks
579; ----
580
581psg_drive:
582	lda	psg_song
583	bmi	.skipsong
584
585	jsr	psg_initsong
586
587.skipsong:
588	lda	#11
589	sta	psg_currvoice
590
591.loop:	ldx	psg_currvoice
592	cpx	#6
593	bcc	.chkmain
594
595.chksub:
596	lda	psg_trkctrl
597	and	#PSG_SUBPAUSE
598	bne	.next
599	bra	.dovoice
600
601.chkmain:
602	lda	psg_trkctrl
603	bmi	.next
604
605.dovoice:
606	lda	psg_voicectrl,X
607	beq	.next
608
609	jsr	psg_drivevoice
610
611.next:	dec	psg_currvoice
612	bpl	.loop
613
614; now loop is done...
615; so now we look at general items
616
617	jsr	psg_dofade
618	jsr	psg_dodata2hdwr
619
620	jsr	psg_mstat
621	cmp	#$00
622	bne	.mainok
623
624	lda	#PSG_MAINPAUSE
625	tsb	psg_trkctrl
626
627.mainok:
628	jsr	psg_sstat
629	cmp	#$00
630	bne	.subok
631
632	lda	#PSG_SUBPAUSE
633	tsb	psg_trkctrl
634
635.subok:
636	rts
637
638
639; ----
640; psg_initsong - initialize stuff for playing song
641; ----
642
643; ???? MAY NOT BE COMPLETE
644
645psg_initsong:
646	lda	psg_song
647
648	asl	A		; make index for 16-bit data
649	tay
650
651      __ldw	psg_trkhdr
652
653      __stw	<psg_tmpptr1
654	lda	[psg_tmpptr1],Y
655	sta	<psg_tmpptr
656	iny
657	lda	[psg_tmpptr1],Y
658	sta	<psg_tmpptr+1
659
660	lda	[psg_tmpptr]
661	sta	<psg_tmpptr1
662	sta	<psg_tmpptr1+1
663
664	bmi	.subtrack	; starting voice = 0 (main), 6 (sub)
665	clx
666	bra	.processmask
667.subtrack:
668	ldx	#6
669
670.processmask:
671	cly
672	lsr	psg_tmpptr1+1
673	lbcc	.nextvoice
674
675	lda	#1
676	sta	psg_voicectrl,X
677	sta	psg_cntdown,X
678	stz	psg_strikephase,X
679	stz	psg_transpose,X
680	stz	psg_mode,X
681	stz	psg_stkoff,X
682	stz	psg_detune,X
683	stz	psg_duratnmult,X
684	stz	psg_fmcorrect,X
685	stz	psg_fmdelay,X
686	stz	psg_fmdelcntdn,X
687	stz	psg_pedelay,X
688	stz	psg_pedelcntdn,X
689	stz	psg_volchg,X
690	stz	psg_volchgaccum,X
691	stz	psg_panpotchg,X
692	stz	psg_panpotaccum,X
693
694	lda	#4
695	sta	psg_octave,X
696	lda	#8
697	sta	psg_keyonratio,X
698	sta	psg_keycntdown,X
699	lda	#$1f
700	sta	psg_perchvol,X
701
702	lda	psg_envtbl	; set to basic envelope
703	sta	psg_envptr_l,X
704	lda	psg_envtbl+1
705	sta	psg_envptr_h,X
706	stz	psg_envptr_off,X
707	lda	#$84		; set default level to $8400
708	stz	psg_envrels_l,X
709	sta	psg_envrels_h,X
710
711	iny
712	lda	[psg_tmpptr],Y	; put voice address into correct voice
713	sta	psg_trkptr_l,X
714	sta	psg_savepoint_l,X
715	iny
716	lda	[psg_tmpptr],Y
717	sta	psg_trkptr_h,X
718	sta	psg_savepoint_h,X
719
720.nextvoice:
721	inx
722	lda	<psg_tmpptr1
723	bmi	.nextsub
724
725.nextmain:
726	cpx	#6
727	lbcc	.processmask
728	bra	.endloop
729
730.nextsub:
731	cpx	#12
732	lbcc	.processmask
733
734.endloop:
735	stz	psg_fadespeed
736	stz	psg_fadecount
737	stz	psg_fadevolcut
738
739	lda	psg_song
740	ora	#$80
741	sta	psg_song
742
743	rts
744
745
746; ----
747; psg_dofade
748; ----
749
750; ???? MAY NOT BE COMPLETE
751
752psg_dofade:
753	rts
754
755
756; ----
757; psg_dodata2hdwr
758; ----
759
760; ???? MAY NOT BE COMPLETE
761
762psg_dodata2hdwr:
763	rts
764
765
766; ----
767; psg_drivevoice - driver for individual voice
768; ----
769
770psg_drivevoice:
771	jsr	psg_dobytecodes	; process track bytecodes
772	jsr	psg_doreladjust	; adjust relative volume/pan
773	jsr	psg_dopercuss
774	jsr	psg_doenvelope
775	jsr	psg_dofreqstuff
776	rts
777
778
779; ----
780; psg_dobytecodes
781; ----
782
783; ???? MAY NOT BE COMPLETE
784
785psg_dobytecodes:
786	dec	psg_cntdown,X	; is last note done yet ?
787	beq	.next
788	rts
789
790.next:	lda	psg_trkptr_l,X	; get pointer
791	sta	<psg_tmpptr
792	lda	psg_trkptr_h,X
793	sta	<psg_tmpptr
794
795	lda	[psg_tmpptr]	; read next bytecode
796	incw	<psg_tmpptr	; increment
797
798	cmp	#$D0		; if <$d0, it's a tone
799	bcc	psg_dotone
800
801	sxy			; use Y as voice index now
802	tax			; save byte
803
804	sub	#$D0	; table starts with bytecode $D0
805	asl	A	; 2 bytes per entry
806	sax		; X = index; A = byte value
807
808	bsr	.tablejump
809	bsr	psg_trkptr_replace
810	rts
811
812.tablejump:
813	jmp	[psg_bytefunctbl,X]
814
815
816psg_dotone:
817
818	bsr	psg_trkptr_replace
819	rts
820
821psg_trkptr_replace:
822	ldx	psg_currvoice
823	lda	<psg_tmpptr
824	sta	psg_trkptr_l,X
825	lda	<psg_tmpptr+1
826	sta	psg_trkptr_h,X
827	rts
828
829psg_octavetbl:
830	.db	0
831	.db	(12*2*1)
832	.db	(12*2*2)
833	.db	(12*2*3)
834	.db	(12*2*4)
835	.db	(12*2*5)
836	.db	(12*2*6)
837	.db	(12*2*7)
838
839psg_bytefunctbl:
840	.dw	psgf_timebase	; d0
841	.dw	psgf_octave	; d1
842	.dw	psgf_octave	; d2
843	.dw	psgf_octave	; d3
844	.dw	psgf_octave	; d4
845	.dw	psgf_octave	; d5
846	.dw	psgf_octave	; d6
847	.dw	psgf_octave	; d7
848	.dw	psgf_octup	; d8
849	.dw	psgf_octdown	; d9
850	.dw	psgf_tie	; da
851	.dw	psgf_tempo	; db
852	.dw	psgf_volume	; dc
853	.dw	psgf_panpot	; dd
854	.dw	psgf_keyratio	; de
855	.dw	psgf_relvolume	; df
856	.dw	psgf_notused	; e0
857	.dw	psgf_contfromsave	; e1
858	.dw	psgf_savepoint	; e2
859	.dw	psgf_rptbegin	; e3
860	.dw	psgf_rptend	; e4
861	.dw	psgf_wave	; e5
862	.dw	psgf_envelope	; e6
863	.dw	psgf_freqmod	; e7
864	.dw	psgf_fmdelay	; e8
865	.dw	psgf_fmcorrect	; e9
866	.dw	psgf_pitchenv	; ea
867	.dw	psgf_pedelay	; eb
868	.dw	psgf_detune	; ec
869	.dw	psgf_sweep	; ed
870	.dw	psgf_sweeptime	; ee
871	.dw	psgf_jump	; ef
872	.dw	psgf_call	; f0
873	.dw	psgf_return	; f1
874	.dw	psgf_transpose	; f2
875	.dw	psgf_reltransp	; f3
876	.dw	psgf_fulltransp	; f4
877	.dw	psgf_voladjust	; f5
878	.dw	psgf_panrtadjust	; f6
879	.dw	psgf_panlftadjust	; f7
880	.dw	psgf_setmode	; f8
881	.dw	psgf_notused	; f9
882	.dw	psgf_notused	; fa
883	.dw	psgf_notused	; fb
884	.dw	psgf_notused	; fc
885	.dw	psgf_notused	; fd
886	.dw	psgf_fadeout	; fe
887	.dw	psgf_dataend	; ff
888
889
890psgf_inctmpptr:
891	incw	<psg_tmpptr
892psgf_notused:
893	rts
894
895;
896; $d0
897;
898psgf_timebase:
899	lda	[psg_tmpptr]
900	and	#$0f
901	sta	psg_duratnmult,Y
902	jmp	psgf_inctmpptr
903
904;
905; $d1-7
906;
907psgf_octave:
908	and	#$07
909	sta	psg_octave,Y
910	rts
911
912;
913; $d8
914;
915psgf_octup:
916	ldx	psg_currvoice
917	inc	psg_octave,X
918	rts
919
920;
921; $d9
922;
923psgf_octdown:
924	ldx	psg_currvoice
925	dec	psg_octave,X
926	rts
927
928;
929; $da
930;
931psgf_tie:
932	lda	#3
933	sta	psg_strikephase,Y
934	rts
935
936;
937; $db
938;
939psgf_tempo:
940	lda	[psg_tmpptr]
941	sub	#$23
942	bpl	.okval
943	cla
944.okval:	tax
945	lda	psg_tempotbl,X
946	sta	psg_tempo
947	jmp	psgf_inctmpptr
948
949;
950; $dc
951;
952psgf_volume:
953	lda	[psg_tmpptr]
954	sta	psg_perchvol,Y
955	cla
956	sta	psg_volchg,Y
957	sta	psg_volchgaccum,Y
958	jmp	psgf_inctmpptr
959
960;
961; $dd
962;
963psgf_panpot:
964	lda	[psg_tmpptr]
965	sta	psg_panpot,Y
966	cla
967	sta	psg_panpotchg,Y
968	sta	psg_panpotaccum,Y
969	jmp	psgf_inctmpptr
970
971;
972; $de
973;
974psgf_keyratio:
975	lda	#8
976	sub	[psg_tmpptr]
977	sta	psg_keyonratio,Y
978	jmp	psgf_inctmpptr
979
980;
981; $df
982;
983psgf_relvolume:
984	lda	psg_perchvol,Y
985	add	[psg_tmpptr]
986	and	#$1f
987	sta	psg_perchvol,Y
988	jmp	psgf_inctmpptr
989
990;
991; $e1
992;
993psgf_contfromsave:
994	lda	psg_savepoint_l,Y
995	sta	<psg_tmpptr
996	lda	psg_savepoint_h,Y
997	sta	<psg_tmpptr+1
998	rts
999
1000;
1001; $e2
1002;
1003psgf_savepoint:
1004	lda	<psg_tmpptr
1005	sta	psg_savepoint_l,Y
1006	lda	<psg_tmpptr+1
1007	sta	psg_savepoint_h,Y
1008	rts
1009
1010;
1011; $e3
1012;
1013psgf_rptbegin:
1014	rts
1015
1016;
1017; $e4
1018;
1019psgf_rptend:
1020	rts
1021
1022;
1023; $e5
1024;
1025psgf_wave:
1026	lda	[psg_tmpptr]
1027	sta	psg_wavenum,Y
1028	jmp	psgf_inctmpptr
1029
1030;
1031; $e6
1032;
1033psgf_envelope:
1034	rts
1035
1036;
1037; $e7
1038;
1039psgf_freqmod:
1040	rts
1041
1042;
1043; $e8
1044;
1045psgf_fmdelay:
1046	rts
1047
1048;
1049; $e9
1050;
1051psgf_fmcorrect:
1052	rts
1053
1054;
1055; $ea
1056;
1057psgf_pitchenv:
1058	rts
1059
1060;
1061; $eb
1062;
1063psgf_pedelay:
1064	rts
1065
1066;
1067; $ec
1068;
1069psgf_detune:
1070	lda	[psg_tmpptr]
1071	sta	psg_detune,Y
1072	jmp	psgf_inctmpptr
1073
1074;
1075; $ed
1076;
1077psgf_sweep:
1078	rts
1079
1080;
1081; $ee
1082;
1083psgf_sweeptime:
1084	rts
1085
1086;
1087; $ef
1088;
1089psgf_jump:
1090	lda	[psg_tmpptr]
1091	tax
1092	incw	<psg_tmpptr
1093	lda	[psg_tmpptr]
1094      __stw	<psg_tmpptr
1095	rts
1096
1097;
1098; $f0
1099;
1100psgf_call:
1101	rts
1102
1103;
1104; $f1
1105;
1106psgf_return:
1107	rts
1108
1109;
1110; $f2
1111;
1112psgf_transpose:
1113	lda	[psg_tmpptr]
1114	asl	A
1115	sta	psg_transpose,Y
1116	jmp	psgf_inctmpptr
1117
1118;
1119; $f3
1120;
1121psgf_reltransp:
1122	lda	[psg_tmpptr]
1123	asl	A
1124	ldx	psg_currvoice
1125	add	psg_transpose,X
1126	sta	psg_transpose,X
1127	jmp	psgf_inctmpptr
1128
1129;
1130; $f4
1131;
1132psgf_fulltransp:
1133	rts
1134
1135;
1136; $f5
1137;
1138psgf_voladjust:
1139	rts
1140
1141;
1142; $f6
1143;
1144psgf_panrtadjust:
1145	rts
1146
1147;
1148; $f7
1149;
1150psgf_panlftadjust:
1151	rts
1152
1153;
1154; $f8
1155;
1156psgf_setmode:
1157	rts
1158
1159;
1160; $fe
1161;
1162psgf_fadeout:
1163	lda	[psg_tmpptr]
1164	bpl	.positive
1165	eor	#$ff
1166	inc	A
1167.positive:
1168	sta	psg_fadespeed
1169	stz	psg_fadecount
1170	stz	psg_fadevolcut
1171	rts
1172
1173;
1174; $ff
1175;
1176psgf_dataend:
1177	lda	#2
1178	sta	psg_voicectrl
1179	rts
1180
1181
1182; ----
1183; PSG_DORELADJUST
1184; ----
1185
1186; NOT IMPLEMENTED YET
1187
1188psg_doreladjust:
1189	rts
1190
1191
1192; ----
1193; PSG_DOPERCUSS
1194; ----
1195
1196; NOT IMPLEMENTED YET
1197
1198psg_dopercuss:
1199	rts
1200
1201
1202; ----
1203; PSG_DOENVELOPE
1204; ----
1205
1206; NOT IMPLEMENTED YET
1207
1208psg_doenvelope:
1209	rts
1210
1211
1212; ----
1213; PSG_DOFREQSTUFF
1214; ----
1215
1216; NOT IMPLEMENTED YET
1217
1218psg_dofreqstuff:
1219	rts
1220
1221
1222;
1223;;
1224;; load a waveform into a PSG channel
1225;; PSG channel must already be set
1226;;
1227;snd_loadwave:	lda	#0
1228;		sta	psg_ctrl
1229;
1230;		ldx	#$20
1231;.l1:		lda	[wavptr]
1232;		sta	psg_wave
1233;		incw	<wavptr
1234;		dex
1235;		bne	.l1
1236;
1237;		lda	#PSG_ENABLE
1238;		ora	#$1F		; full volume
1239;		sta	psg_ctrl
1240;		lda	#$ff
1241;		sta	psg_pan
1242;		rts
1243;
1244
1245
1246; careful with these wave data (etc.)
1247
1248;
1249; wave #0
1250;
1251psg_waveforms:
1252	.db $00,$00,$00,$00
1253	.db $00,$00,$00,$00
1254	.db $00,$00,$00,$00
1255	.db $00,$00,$00,$00
1256	.db $1f,$1f,$1f,$1f
1257	.db $1f,$1f,$1f,$1f
1258	.db $1f,$1f,$1f,$1f
1259	.db $1f,$1f,$1f,$1f
1260
1261;
1262; wave #1
1263;
1264	.db $10,$0d,$0a,$07
1265	.db $05,$03,$02,$01
1266	.db $00,$01,$02,$03
1267	.db $05,$07,$09,$0d
1268	.db $0f,$12,$15,$17
1269	.db $19,$1b,$1d,$1e
1270	.db $1e,$1e,$1d,$1b
1271	.db $19,$17,$15,$13
1272
1273;
1274; wave #2
1275;
1276	.db $10,$11,$12,$13
1277	.db $14,$15,$16,$17
1278	.db $18,$19,$1a,$1b
1279	.db $1c,$1d,$1e,$1f
1280	.db $00,$01,$02,$03
1281	.db $04,$05,$06,$07
1282	.db $08,$09,$0a,$0b
1283	.db $0c,$0d,$0e,$0f
1284
1285;
1286; wave #3
1287;
1288	.db $05,$05,$09,$09
1289	.db $02,$16,$16,$10
1290	.db $10,$1f,$1f,$0e
1291	.db $0e,$04,$04,$12
1292	.db $19,$19,$09,$09
1293	.db $02,$02,$13,$13
1294	.db $07,$07,$1e,$1e
1295	.db $0b,$0b,$15,$15
1296
1297;
1298; wave #4
1299;
1300	.db $0f,$0b,$0f,$11
1301	.db $0f,$0d,$0f,$10
1302	.db $10,$10,$10,$07
1303	.db $07,$07,$10,$07
1304	.db $01,$07,$10,$17
1305	.db $1e,$17,$10,$07
1306	.db $01,$07,$10,$17
1307	.db $0f,$07,$10,$13
1308
1309;
1310; wave #5
1311;
1312	.db $00,$00,$00,$00
1313	.db $00,$00,$00,$00
1314	.db $00,$00,$00,$00
1315	.db $00,$00,$00,$1f
1316	.db $1e,$1c,$1a,$18
1317	.db $16,$14,$12,$10
1318	.db $0e,$0c,$0a,$08
1319	.db $06,$04,$02,$01
1320
1321;
1322; wave #6
1323;
1324	.db $10,$06,$03,$02
1325	.db $01,$00,$00,$00
1326	.db $00,$00,$00,$01
1327	.db $01,$02,$03,$06
1328	.db $10,$19,$1c,$1d
1329	.db $1e,$1f,$1f,$1f
1330	.db $1f,$1f,$1f,$1f
1331	.db $1e,$1d,$1c,$19
1332
1333; OK to here -----------------
1334;
1335; wave #7
1336;
1337	.db $1d,$0f,$09,$05
1338	.db $03,$01,$03,$05
1339	.db $09,$0f,$15,$19
1340	.db $1b,$1d,$1b,$19
1341	.db $15,$0f,$07,$03
1342	.db $01,$03,$07,$0f
1343	.db $17,$1b,$1d,$1b
1344	.db $17,$0f,$01,$0f
1345
1346;
1347; wave #8
1348;
1349	.db $10,$13,$16,$18
1350	.db $1b,$1d,$1e,$1f
1351	.db $1f,$1f,$1e,$1d
1352	.db $1b,$18,$16,$13
1353	.db $10,$0c,$09,$07
1354	.db $04,$02,$01,$01
1355	.db $01,$01,$01,$02
1356	.db $04,$07,$09,$0c
1357
1358;
1359; wave #9
1360;
1361	.db $1b,$1d,$1b,$17
1362	.db $0f,$0f,$15,$19
1363	.db $19,$15,$0f,$0f
1364	.db $09,$05,$05,$09
1365	.db $0f,$0f,$0d,$07
1366	.db $03,$01,$03,$09
1367	.db $11,$13,$13,$0f
1368	.db $0b,$0b,$0d,$17
1369
1370;
1371; wave #$0a
1372;
1373	.db $1f,$1f,$1f,$1f
1374	.db $1f,$1f,$1f,$1f
1375	.db $1f,$1f,$1f,$1f
1376	.db $1f,$1f,$1f,$1f
1377	.db $1f,$1f,$1f,$1f
1378	.db $1f,$1f,$1f,$1f
1379	.db $01,$01,$01,$01
1380	.db $01,$01,$01,$01
1381
1382;
1383; wave #$0b
1384;
1385	.db $1f,$00,$04,$06
1386	.db $08,$0a,$0c,$0e
1387	.db $10,$12,$14,$16
1388	.db $18,$1a,$1c,$1e
1389	.db $1f,$1e,$1c,$1a
1390	.db $18,$16,$14,$12
1391	.db $10,$0e,$0c,$0a
1392	.db $08,$06,$04,$02
1393
1394;
1395; wave #$0c
1396;
1397	.db $12,$10,$1a,$1f
1398	.db $18,$0d,$14,$1c
1399	.db $18,$12,$18,$1c
1400	.db $10,$01,$05,$0b
1401	.db $05,$01,$09,$10
1402	.db $05,$00,$03,$0d
1403	.db $09,$07,$10,$1a
1404	.db $0d,$03,$10,$14
1405
1406
1407;
1408; wave #$0d
1409;
1410	.db $0f,$15,$17,$18
1411	.db $1a,$1d,$1e,$10
1412	.db $1f,$1f,$1d,$1c
1413	.db $1a,$18,$14,$10
1414	.db $0f,$0f,$0b,$07
1415	.db $05,$03,$02,$10
1416	.db $00,$01,$01,$02
1417	.db $05,$07,$08,$10
1418
1419;
1420; wave #$0e
1421;
1422	.db $1f,$1e,$1b,$17
1423	.db $13,$0f,$0b,$07
1424	.db $03,$0f,$0c,$09
1425	.db $07,$04,$02,$01
1426	.db $00,$00,$01,$02
1427	.db $04,$07,$09,$0c
1428	.db $1f,$1b,$17,$13
1429	.db $0f,$0b,$07,$03
1430
1431;
1432; wave #$0f
1433;
1434	.db $18,$1f,$1d,$1d
1435	.db $1f,$1c,$14,$0f
1436	.db $12,$1c,$1e,$12
1437	.db $05,$02,$03,$0a
1438	.db $15,$1c,$1d,$1a
1439	.db $0d,$01,$03,$0d
1440	.db $10,$0b,$03,$00
1441	.db $02,$02,$00,$07
1442
1443;
1444; wave #$10
1445;
1446	.db $1f,$00,$1f,$00
1447	.db $1f,$00,$1f,$00
1448	.db $1f,$00,$1f,$00
1449	.db $1f,$00,$1f,$00
1450	.db $1f,$00,$1f,$00
1451	.db $1f,$00,$1f,$00
1452	.db $1f,$00,$1f,$00
1453	.db $1f,$00,$1f,$00
1454
1455;
1456; wave #$11
1457;
1458	.db $0d,$0f,$0b,$00
1459	.db $10,$1e,$1d,$1f
1460	.db $13,$10,$0f,$04
1461	.db $0e,$0d,$10,$01
1462	.db $00,$02,$02,$0e
1463	.db $01,$0d,$0f,$10
1464	.db $0e,$01,$01,$03
1465	.db $0e,$01,$01,$00
1466
1467;
1468; wave #$12
1469;
1470	.db $10,$1a,$1f,$1c
1471	.db $14,$10,$11,$14
1472	.db $16,$14,$11,$10
1473	.db $14,$1c,$1f,$1a
1474	.db $10,$05,$01,$03
1475	.db $0b,$0f,$0e,$0b
1476	.db $09,$0b,$0e,$0f
1477	.db $0b,$03,$01,$05
1478
1479;
1480; wave #$13
1481;
1482	.db $16,$1e,$1e,$17
1483	.db $0d,$06,$01,$00
1484	.db $00,$00,$00,$00
1485	.db $01,$03,$07,$0c
1486	.db $13,$18,$1c,$1e
1487	.db $1f,$1f,$1f,$1f
1488	.db $1f,$1e,$19,$12
1489	.db $08,$01,$01,$09
1490
1491;
1492; wave #$14
1493;
1494	.db $14,$1a,$1e,$1f
1495	.db $1f,$1f,$1f,$1f
1496	.db $1f,$1f,$1f,$1f
1497	.db $1f,$1e,$1a,$14
1498	.db $0b,$05,$01,$00
1499	.db $00,$00,$00,$00
1500	.db $00,$00,$00,$00
1501	.db $00,$01,$05,$0b
1502
1503;
1504; wave #$15
1505;
1506	.db $17,$1e,$1d,$17
1507	.db $10,$16,$1f,$1c
1508	.db $1a,$1e,$1f,$1f
1509	.db $1c,$0e,$07,$0a
1510	.db $14,$18,$11,$03
1511	.db $00,$00,$01,$05
1512	.db $03,$00,$09,$0f
1513	.db $08,$02,$01,$08
1514
1515;
1516; wave #$16
1517;
1518	.db $18,$1e,$19,$0f
1519	.db $12,$1e,$1d,$1e
1520	.db $1e,$1d,$1e,$12
1521	.db $0f,$19,$1e,$18
1522	.db $07,$01,$06,$10
1523	.db $0d,$01,$02,$01
1524	.db $01,$02,$01,$0d
1525	.db $10,$06,$01,$07
1526
1527;
1528; wave #$17
1529;
1530	.db $10,$16,$1a,$1c
1531	.db $1e,$1c,$1a,$16
1532	.db $10,$0a,$06,$04
1533	.db $02,$04,$06,$0a
1534	.db $10,$18,$1c,$1e
1535	.db $1c,$18,$10,$08
1536	.db $02,$08,$10,$1e
1537	.db $10,$02,$10,$02
1538
1539;
1540; wave #$18
1541;
1542	.db $10,$13,$16,$18
1543	.db $1b,$1d,$1e,$1f
1544	.db $1f,$1f,$1e,$1d
1545	.db $1b,$18,$16,$13
1546	.db $10,$01,$04,$08
1547	.db $0c,$10,$14,$18
1548	.db $1c,$01,$04,$08
1549	.db $0c,$10,$14,$18
1550
1551;
1552; wave #$19
1553;
1554	.db $1a,$1c,$1d,$1e
1555	.db $1f,$1f,$1f,$1f
1556	.db $1f,$1f,$1f,$1f
1557	.db $1e,$1d,$1b,$19
1558	.db $06,$04,$02,$01
1559	.db $00,$00,$00,$00
1560	.db $00,$00,$00,$00
1561	.db $01,$02,$04,$06
1562
1563;
1564; wave #$1a
1565;
1566	.db $1b,$14,$10,$0e
1567	.db $0c,$0b,$16,$09
1568	.db $02,$07,$0a,$05
1569	.db $03,$03,$02,$01
1570	.db $0b,$15,$1c,$1e
1571	.db $1a,$0c,$15,$19
1572	.db $0c,$18,$07,$12
1573	.db $0c,$09,$16,$1a
1574
1575;
1576; wave #$1b
1577;
1578	.db $0f,$15,$1a,$1c
1579	.db $1f,$1c,$1a,$15
1580	.db $0f,$08,$04,$02
1581	.db $00,$02,$04,$08
1582	.db $0f,$17,$1c,$1f
1583	.db $1c,$17,$0f,$06
1584	.db $01,$02,$07,$0f
1585	.db $0f,$13,$0f,$00
1586
1587;
1588; wave #$1c
1589;
1590	.db $1f,$1b,$19,$1c
1591	.db $1f,$1c,$1a,$17
1592	.db $0c,$04,$03,$02
1593	.db $08,$0e,$0d,$04
1594	.db $00,$06,$09,$05
1595	.db $00,$00,$00,$01
1596	.db $0a,$10,$11,$12
1597	.db $0e,$0c,$0e,$19
1598
1599;
1600; wave #$1d
1601;
1602	.db $0f,$02,$11,$1f
1603	.db $0f,$1c,$0d,$00
1604	.db $0f,$02,$11,$1f
1605	.db $0f,$1c,$0d,$00
1606	.db $0f,$02,$11,$1f
1607	.db $0f,$1c,$0d,$00
1608	.db $0f,$02,$11,$1f
1609	.db $0f,$1c,$0d,$00
1610
1611;
1612; wave #$1e
1613;
1614	.db $10,$0a,$14,$1c
1615	.db $15,$1d,$16,$10
1616	.db $18,$11,$18,$1f
1617	.db $15,$1b,$12,$0a
1618	.db $10,$08,$0e,$14
1619	.db $0a,$10,$07,$00
1620	.db $08,$01,$09,$12
1621	.db $0a,$12,$0b,$06
1622
1623;
1624; wave #$1f
1625;
1626	.db $12,$19,$1d,$1e
1627	.db $1f,$1f,$1f,$1e
1628	.db $1c,$17,$12,$0c
1629	.db $0d,$12,$16,$11
1630	.db $08,$04,$01,$00
1631	.db $00,$00,$00,$00
1632	.db $00,$00,$00,$00
1633	.db $00,$01,$04,$0c
1634
1635;
1636; wave #$20
1637;
1638	.db $04,$14,$1e,$17
1639	.db $00,$17,$1e,$16
1640	.db $10,$1a,$1f,$1c
1641	.db $12,$16,$18,$10
1642	.db $06,$12,$1c,$10
1643	.db $0c,$0e,$10,$06
1644	.db $02,$08,$12,$0c
1645	.db $04,$08,$0e,$08
1646
1647;
1648; wave #$21
1649;
1650	.db $0a,$0c,$0e,$0f
1651	.db $1f,$1f,$1f,$1f
1652	.db $14,$14,$13,$12
1653	.db $1b,$1b,$1b,$1b
1654	.db $0a,$08,$06,$04
1655	.db $0e,$0e,$0e,$0e
1656	.db $00,$00,$00,$02
1657	.db $13,$13,$13,$13
1658
1659;
1660; wave #$22
1661;
1662	.db $1b,$1b,$05,$05
1663	.db $09,$09,$1f,$1f
1664	.db $1b,$1b,$16,$16
1665	.db $1a,$1a,$07,$07
1666	.db $17,$17,$15,$15
1667	.db $19,$19,$0c,$0c
1668	.db $1b,$1b,$0c,$0c
1669	.db $00,$00,$03,$03
1670
1671;
1672; wave #$23
1673;
1674	.db $1f,$1d,$1b,$19
1675	.db $17,$15,$13,$11
1676	.db $0f,$0d,$0b,$09
1677	.db $07,$05,$03,$01
1678	.db $00,$0f,$11,$0d
1679	.db $13,$0b,$15,$09
1680	.db $17,$07,$19,$05
1681	.db $1b,$03,$1d,$01
1682
1683;
1684; wave #$24
1685;
1686	.db $0b,$0e,$11,$13
1687	.db $1f,$1d,$1a,$17
1688	.db $09,$05,$02,$00
1689	.db $0a,$0b,$0e,$11
1690	.db $0b,$0e,$1b,$1e
1691	.db $14,$12,$1a,$17
1692	.db $09,$05,$0d,$0a
1693	.db $00,$01,$0e,$11
1694
1695;
1696; wave #$25
1697;
1698	.db $0f,$16,$1b,$1e
1699	.db $1f,$1e,$1b,$16
1700	.db $0f,$08,$04,$01
1701	.db $00,$01,$04,$08
1702	.db $0f,$00,$00,$00
1703	.db $1f,$1f,$1f,$1f
1704	.db $1c,$18,$14,$10
1705	.db $0c,$07,$03,$00
1706
1707;
1708; wave #$26
1709;
1710	.db $02,$01,$05,$0b
1711	.db $11,$17,$1b,$1f
1712	.db $1e,$1b,$17,$13
1713	.db $0f,$0b,$09,$0e
1714	.db $18,$1d,$1c,$17
1715	.db $0f,$0a,$07,$06
1716	.db $11,$19,$1a,$19
1717	.db $10,$0b,$06,$03
1718
1719;
1720; wave #$27
1721;
1722	.db $1d,$1d,$1d,$10
1723	.db $10,$10,$1d,$1d
1724	.db $1d,$1d,$1b,$1b
1725	.db $1b,$1b,$1b,$1b
1726	.db $00,$00,$00,$00
1727	.db $00,$00,$02,$02
1728	.db $02,$02,$10,$10
1729	.db $10,$02,$02,$02
1730
1731;
1732; wave #$28
1733;
1734	.db $19,$16,$10,$12
1735	.db $12,$09,$16,$1f
1736	.db $0f,$17,$0f,$10
1737	.db $1d,$13,$11,$10
1738	.db $0e,$19,$1b,$00
1739	.db $0f,$03,$0c,$12
1740	.db $17,$0f,$16,$11
1741	.db $12,$05,$0d,$06
1742
1743;
1744; wave #$29
1745;
1746	.db $00,$07,$0b,$0b
1747	.db $09,$03,$00,$01
1748	.db $17,$17,$15,$10
1749	.db $0c,$0a,$0d,$13
1750	.db $07,$0e,$12,$11
1751	.db $0f,$09,$07,$07
1752	.db $1f,$1e,$1d,$17
1753	.db $13,$11,$13,$1a
1754
1755;
1756; wave #$2a
1757;
1758	.db $19,$04,$03,$03
1759	.db $02,$02,$01,$01
1760	.db $03,$03,$01,$01
1761	.db $01,$01,$00,$01
1762	.db $00,$01,$19,$19
1763	.db $1b,$1b,$1b,$1b
1764	.db $19,$1e,$1e,$1e
1765	.db $0d,$1e,$19,$04
1766
1767;
1768; wave #$2b
1769;
1770	.db $0f,$15,$19,$1b
1771	.db $1d,$1e,$1f,$1e
1772	.db $1d,$1b,$19,$15
1773	.db $0f,$07,$17,$0a
1774	.db $14,$0d,$12,$0f
1775	.db $10,$0a,$06,$04
1776	.db $02,$01,$00,$01
1777	.db $02,$04,$06,$0a
1778
1779;
1780; wave #$2c
1781;
1782	.db $09,$18,$1d,$0b
1783	.db $00,$06,$13,$1c
1784	.db $18,$10,$06,$02
1785	.db $00,$00,$00,$00
1786	.db $02,$08,$16,$1b
1787	.db $09,$03,$10,$1e
1788	.db $1e,$1b,$16,$0b
1789	.db $05,$01,$00,$00
1790
1791
1792;
1793; frequency data
1794;
1795psg_freqtbl:
1796	.dw $0fe4	; A0
1797	.dw $0f00	; A0#
1798	.dw $0e28	; B0
1799	.dw $0d5d	; C1 (octave starts at 'C')
1800	.dw $0c9d	; C1#
1801	.dw $0be7	; D1
1802	.dw $0b3d	; D1#
1803	.dw $0a9b	; E1
1804	.dw $0a03	; F1
1805	.dw $0973	; F1#
1806	.dw $08eb	; G1
1807	.dw $086a	; G1#
1808	.dw $07f2	; A1
1809	.dw $0780	; A1#
1810	.dw $0714	; B1
1811	.dw $06af	; C2
1812	.dw $064f
1813	.dw $05f4
1814	.dw $059e
1815	.dw $054e
1816	.dw $0502
1817	.dw $04b9
1818	.dw $0476
1819	.dw $0435
1820	.dw $03f9
1821	.dw $03c0
1822	.dw $038a
1823	.dw $0357	; C3
1824	.dw $0327
1825	.dw $02fa
1826	.dw $02cf
1827	.dw $02a7
1828	.dw $0281
1829	.dw $025d
1830	.dw $023b
1831	.dw $021b
1832	.dw $01fc
1833	.dw $01e0
1834	.dw $01c5
1835	.dw $01ac	; C4
1836	.dw $0193
1837	.dw $017d
1838	.dw $0168
1839	.dw $0153
1840	.dw $0140
1841	.dw $012e
1842	.dw $011d
1843	.dw $010d
1844	.dw $00fe
1845	.dw $00f0
1846	.dw $00e3
1847	.dw $00d6	; C5
1848	.dw $00ca
1849	.dw $00be
1850	.dw $00b4
1851	.dw $00aa
1852	.dw $00a0
1853	.dw $0097
1854	.dw $008f
1855	.dw $0087
1856	.dw $007f
1857	.dw $0078
1858	.dw $0071
1859	.dw $006b	; C6
1860	.dw $0065
1861	.dw $005f
1862	.dw $005a
1863	.dw $0055
1864	.dw $0050
1865	.dw $004b
1866	.dw $0046
1867	.dw $0043
1868	.dw $0040
1869	.dw $003c
1870	.dw $0039
1871	.dw $0035	; C7
1872	.dw $0032
1873	.dw $0030
1874	.dw $002d
1875	.dw $002a
1876	.dw $0028
1877	.dw $0026
1878	.dw $0024
1879	.dw $0022
1880	.dw $0020
1881	.dw $001e
1882	.dw $001c
1883	.dw $001b	; C8
1884
1885
1886;
1887; TEMPO DATA
1888;
1889; starting with value $23 (as sent to PSG_TEMPO),
1890; these numbers are the timer values to use for
1891; that tempo
1892;
1893psg_tempotbl:
1894	.db $7d,$79,$76,$73
1895	.db $70,$6d,$6b,$68
1896	.db $65,$63,$61,$5f
1897	.db $5d,$5b,$59,$57
1898	.db $56,$54,$52,$51
1899	.db $4f,$4e,$4d,$4b
1900	.db $4a,$49,$48,$46
1901	.db $45,$44,$43,$42
1902	.db $41,$40,$3f,$3e
1903	.db $3e,$3d,$3c,$3b
1904	.db $3a,$3a,$39,$38
1905	.db $37,$37,$36,$35
1906	.db $35,$34,$33,$33
1907	.db $32,$32,$31,$31
1908	.db $30,$30,$2f,$2f
1909	.db $2e,$2e,$2d,$2d
1910	.db $2c,$2c,$2b,$2b
1911	.db $2a,$2a,$2a,$29
1912	.db $29,$28,$28,$28
1913	.db $27,$27,$27,$26
1914	.db $26,$26,$25,$25
1915	.db $25,$24,$24,$24
1916	.db $24,$23,$23,$23
1917	.db $22,$22,$22,$22
1918	.db $22,$21,$21,$21
1919	.db $20,$20,$20,$20
1920	.db $1f,$1f,$1f,$1f
1921	.db $1f,$1e,$1e,$1e
1922	.db $1e,$1e,$1d,$1d
1923	.db $1d,$1d,$1d,$1c
1924	.db $1c,$1c,$1c,$1c
1925	.db $1b,$1b,$1b,$1b
1926	.db $1b,$1b,$1a,$1a
1927	.db $1a,$1a,$1a,$1a
1928	.db $1a,$19,$19,$19
1929	.db $19,$19,$19,$19
1930	.db $18,$18,$18,$18
1931	.db $18,$18,$18,$17
1932	.db $17,$17,$17,$17
1933	.db $17,$17,$17,$17
1934	.db $16,$16,$16,$16
1935	.db $16,$16,$16,$16
1936	.db $16,$15,$15,$15
1937	.db $15,$15,$15,$15
1938	.db $15,$15,$15,$14
1939	.db $14,$14,$14,$14
1940	.db $14,$14,$14,$14
1941	.db $14,$14,$13,$13
1942	.db $13,$13,$13,$13
1943	.db $13,$13,$13,$13
1944	.db $13,$13,$12,$12
1945	.db $12,$12,$12,$12
1946	.db $12,$12,$12,$12
1947	.db $12,$12,$12,$11
1948	.db $11,$11,$11,$11
1949	.db $11
1950
1951
1952;
1953; Envelope Data
1954;
1955
1956
1957;
1958; envelope #0
1959;
1960psg_env0:
1961	ENV_RLS	$8410
1962	ENV_LEV	$7c40
1963	ENV_DLY $00,$0000
1964	ENV_END
1965
1966;
1967; envelope #1
1968;
1969psg_env1:
1970	ENV_RLS	$fa05
1971	ENV_LEV $7c40
1972	ENV_DLY $0c,$fe01
1973	ENV_END
1974
1975;
1976; envelope #2
1977;
1978psg_env2:
1979	ENV_RLS	$fd05
1980	ENV_LEV $7c40
1981	ENV_DLY $0c,$fe01
1982	ENV_END
1983
1984;
1985; envelope #3
1986;
1987psg_env3:
1988	ENV_RLS	$ff01
1989	ENV_LEV $7c40
1990	ENV_DLY $0c,$fe01
1991	ENV_END
1992
1993;
1994; envelope #4
1995;
1996psg_env4:
1997	ENV_RLS	$fa05
1998	ENV_LEV $7c40
1999	ENV_DLY $00,$ff81
2000	ENV_END
2001
2002;
2003; envelope #5
2004;
2005psg_env5:
2006	ENV_RLS	$fa05
2007	ENV_LEV $7c40
2008	ENV_DLY $00,$ff01
2009	ENV_END
2010
2011;
2012; envelope #6
2013;
2014psg_env6:
2015	ENV_RLS	$fa05
2016	ENV_LEV $7c40
2017	ENV_DLY $00,$fe01
2018	ENV_END
2019
2020;
2021; envelope #7
2022;
2023psg_env7:
2024	ENV_RLS	$fb05
2025	ENV_LEV $2c40
2026	ENV_DLY $02,$2801
2027	ENV_DLY $00,$ff81
2028	ENV_END
2029
2030;
2031; envelope #8
2032;
2033psg_env8:
2034	ENV_RLS	$fb05
2035	ENV_LEV $3440
2036	ENV_DLY $03,$1801
2037	ENV_DLY $00,$ff81
2038	ENV_END
2039
2040;
2041; envelope #9
2042;
2043psg_env9:
2044	ENV_RLS	$fb05
2045	ENV_LEV $1c40
2046	ENV_DLY $01,$6001
2047	ENV_DLY $02,$fe01
2048	ENV_DLY $08,$fc01
2049	ENV_DLY $32,$0081
2050	ENV_END
2051
2052;
2053; envelope #$0a
2054;
2055psg_enva:
2056	ENV_RLS	$fd01
2057	ENV_LEV $0440
2058	ENV_DLY $03,$2801
2059	ENV_DLY $04,$fe01
2060	ENV_END
2061
2062;
2063; envelope #$0b
2064;
2065psg_envb:
2066	ENV_RLS	$fd01
2067	ENV_LEV $0000
2068	ENV_LEV $0000
2069	ENV_LEV $7c40
2070	ENV_DLY $00,$ffc1
2071	ENV_END
2072
2073;
2074; envelope #$0c
2075;
2076psg_envc:
2077	ENV_RLS	$fa05
2078	ENV_LEV $0000
2079	ENV_LEV $0000
2080	ENV_LEV $6840
2081	ENV_DLY $00,$0061
2082	ENV_END
2083
2084;
2085; envelope #$0d
2086;
2087psg_envd:
2088	ENV_RLS	$fa05
2089	ENV_LEV $7c40
2090	ENV_DLY $04,$f801
2091	ENV_DLY $00,$ff41
2092	ENV_END
2093
2094;
2095; envelope #$0e
2096;
2097psg_enve:
2098	ENV_RLS	$fa05
2099	ENV_LEV $7c40
2100	ENV_DLY $08,$f801
2101	ENV_DLY $00,$ff41
2102	ENV_END
2103
2104;
2105; envelope #$0f
2106;
2107psg_envf:
2108	ENV_RLS	$ff00
2109	ENV_LEV $7c40
2110	ENV_DLY $05,$fc01
2111	ENV_LEV $7040
2112	ENV_DLY $05,$fc01
2113	ENV_LEV $6440
2114	ENV_DLY $05,$fc01
2115	ENV_LEV $5840
2116	ENV_DLY $05,$fc01
2117	ENV_LEV $4c40
2118	ENV_DLY $05,$fc01
2119	ENV_LEV $4040
2120	ENV_DLY $05,$fc01
2121	ENV_DLY $00,$ff01
2122	ENV_END
2123
2124
2125;
2126; Envelope Header (pointers to data)
2127;
2128psg_envtbl:
2129	.dw psg_env0
2130	.dw psg_env1
2131	.dw psg_env2
2132	.dw psg_env3
2133	.dw psg_env4
2134	.dw psg_env5
2135	.dw psg_env6
2136	.dw psg_env7
2137	.dw psg_env8
2138	.dw psg_env9
2139	.dw psg_enva
2140	.dw psg_envb
2141	.dw psg_envc
2142	.dw psg_envd
2143	.dw psg_enve
2144	.dw psg_envf
2145
2146
2147;
2148; now, return context to bank established in
2149; file which included this
2150;
2151	.bank	START_BANK
2152
2153