1 /*
2  * Universal library for Yamaha Programmable Sound Generator
3  * and similar chips
4  *
5  * $Id: psg.h,v 1.14 2016-06-11 19:53:08 dom Exp $
6  *
7  */
8 
9 #ifndef __PSG_H__
10 #define __PSG_H__
11 
12 #include <math.h>
13 
14 // convert a given frequency into a suitable period for PSG
15 
16 
17 // **************
18 //      C128
19 // **************
20 
21 // 1 Mhz clock but the SID is different
22 #ifdef __C128__
23 #include <c128/sid.h>
24 #define psgT(hz)		((int) (hz/0.0596))
25 #endif
26 
27 
28 // **************
29 //     SN PSG
30 // **************
31 
32 // depending on the chip variant clock is divided by 16 or by 32
33 
34 #ifdef __M5__
35 // Clock: 3579545
36 #define psgT(hz)		((int)(111860.8 / (hz)))
37 #endif
38 
39 #ifdef __MTX__
40 // Clock: 4000000
41 #define psgT(hz)		((int)(250000.0 / (hz)))
42 #endif
43 
44 #ifdef __SC3000__
45 #define psgT(hz)		((int)(167791.2 / (hz)))
46 #endif
47 
48 #ifdef __SMS__
49 // Masterclock PALN/3 = 3582056
50 #define psgT(hz)		((int)(223878.5 / (hz)))
51 #endif
52 
53 #ifdef __SHARPMZ__
54 // Clock: 3546894 ..sharpmz.org suggests: "11094/(FR/10)"
55 #define psgT(hz)		((int)(110840.4 / (hz)))
56 #endif
57 
58 #ifdef __RX78__
59 // 3579545
60 #define psgT(hz)		((int)(223722 / (hz)))
61 #endif
62 
63 #ifdef __COLECO__
64 // 3579545
65 #define psgT(hz)		((int)(223722 / (hz)))
66 #endif
67 
68 
69 // **************
70 //     YM PSG
71 // **************
72 
73 #ifdef __X1__
74 // Z80 is clocked at 4mhz
75 #define psgT(hz)		((int)(125000.0 / (hz)))
76 #endif
77 
78 #ifdef __GAL__
79 #define psgT(hz)		((int)(1536000.0 / (hz)))
80 #endif
81 
82 #ifdef __MC1000__
83 // CPU clock: 3.57 mhz, let's divide by 32
84 #define psgT(hz)		((int)(111562.5 / (hz)))
85 #endif
86 
87 #ifdef __AQUARIUS__
88 #define psgT(hz)		((int)(111861.0 / (hz)))
89 #endif
90 
91 #ifdef __EINSTEIN__
92 // 2 Mhz clock (divided internally by 16)
93 #define psgT(hz)		((int)(125000.0 / (hz)))
94 #endif
95 
96 #ifdef __MSX__
97 #include <msx.h>
98 // src clock: 17897725.5 divided internally by 16
99 #define psgT(hz)		((int)(111760.0 / (hz)))
100 #endif
101 
102 #ifdef __PC6001__
103 // 3.8 Mhz on earlier models, 4Mhz on next ones
104 #define psgT(hz)		((int)(118750.0 / (hz)))
105 #endif
106 
107 #ifdef __PASOPIA7__
108 // 1996800 / 16 ?
109 #define psgT(hz)		((int)(125000.0 / (hz)))
110 #endif
111 
112 #ifdef __PC88__
113 // 3.9936 Mhz, but is sounded bad when split as suggested.
114 //   This value was chosen by trial and error.
115 #define psgT(hz)		((int)(74000.0 / (hz)))
116 #endif
117 
118 #ifdef __SVI__
119 #include <msx.h>
120 #define psgT(hz)		((int)(111760.0 / (hz)))
121 #endif
122 
123 #ifdef __SPECTRUM__
124 // src clock: 1773400 divided internally by 16
125 // ..but clock differs on other interfaces, so let's permit programmers to override
126 #ifndef psgT
127 #define psgT(hz)		((int)(110837.5 / (hz)))
128 #endif
129 #endif
130 
131 #ifdef __MULTI8__
132 // Clock is 3579545
133 #ifndef psgT
134 #define psgT(hz)		((int)(118750.0 / (hz)))
135 #endif
136 #endif
137 
138 #ifdef __SPC1000__
139 // Clock is 4000000
140 #ifndef psgT
141 #define psgT(hz)		((int)(125000.0/ (hz)))
142 #endif
143 #endif
144 
145 #ifdef __SPRINTER__
146 // The PPS Sprinter PSG lib is totally untested, let's assume it is connected
147 // and clocked as for a Spectrum, but probably we're wrong
148 #define psgT(hz)		((int)(110837.5 / (hz)))
149 #endif
150 
151 #ifdef __TRS80__
152 // EACA Colour Genie EG2000 sound
153 #define psgT(hz)		((int)(138550.0 / (hz)))
154 #endif
155 
156 #ifdef __CPC__
157 // src clock: 1000000 divided internally by 16
158 #ifndef psgT
159 #define psgT(hz)		((int)(62500.0 / (hz)))
160 #endif
161 #endif
162 
163 #ifdef __VECTOR06C__
164 #define psgT(hz)		((int)(110837.5 / (hz)))
165 #endif
166 
167 #ifdef __ZX80__
168 // ZON-X81 clock: 1625000  divided internally by 16
169 #define psgT(hz)		((int)(101562.0 / (hz)))
170 #endif
171 
172 #ifdef __ZX81__
173 // ZON-X81 clock: 1625000  divided internally by 16
174 #ifndef psgT
175 #define psgT(hz)		((int)(101562.0 / (hz)))
176 #endif
177 #endif
178 
179 
180 // Keep CP/M at the end of the models list, so it can be overriden
181 
182 #ifdef __CPM__
183 // This one is tricky.
184 // Clock varies, so let's use a generic value which the programmer can override
185 #ifndef psgT
186 #define psgT(hz)		((int)(100000.0 / (hz)))
187 #endif
188 #endif
189 
190 
191 
192 // Play a sound by PSG
193 extern void __LIB__ set_psg(unsigned int reg, unsigned int val) __smallc;
194 extern void __LIB__    set_psg_callee(unsigned int reg, unsigned int val) __smallc __z88dk_callee;
195 #define set_psg(a,b)     set_psg_callee(a,b)
196 
197 // Read the PSG register
198 extern int __LIB__  get_psg(int regno) __z88dk_fastcall;
199 
200 // Init the PSG (reset sound etc..)
201 extern void __LIB__ psg_init();
202 
203 
204 // alias for setting psg registers (for the BASIC fans)
205 #define sound(reg, value) set_psg(reg, value)
206 
207 // Set a given tone for the channel (0-2)
208 extern void __LIB__ psg_tone(unsigned int channel, int period) __smallc;
209 
210 // Set the global noise period
211 extern void __LIB__ psg_noise(unsigned int period);
212 
213 // Set channel's volume
214 extern void __LIB__ psg_volume(unsigned int channel, unsigned int volume) __smallc;
215 
216 // Set the volume envelope of number \a waveform, with the given period, on a group of channels (ORed bits)
217 extern void __LIB__ psg_envelope(unsigned int waveform, int period, unsigned int channels) __smallc;
218 
219 // Set noise or tone generation on a group of channels (ORed bits)
220 extern void __LIB__ psg_channels(unsigned int tone_channels, unsigned int noise_channels) __smallc;
221 
222 // Get the group of channels currently generating tone (ORed bits)
223 extern unsigned char __LIB__ psg_tone_channels();
224 
225 // Get the group of channels currently generating noise (ORed bits)
226 extern unsigned char __LIB__ psg_noise_channels();
227 
228 
229 
230 enum {
231 	chanNone = 0,	///< no channel
232 	chan0 = 1,	///< the first audio channel
233 	chan1 = 2,	///< the second audio channel
234 	chan2 = 4,	///< the third audio channel
235 	chanAll = 7	///< all audio channels
236 };
237 
238 // volume envelopes, where U = up, D = down, H = high
239 enum {
240 	envD = 0,	///< envelope, falling into silence
241 	envU = 4,	///< envelope, raising to highest volume, then silenced
242 	envDD = 8,	///< envelope, falling into silence multiple times
243 	envDUD = 10,	///< envelope, first falling, and then triangle shaped
244 	envDH = 11,	///< envelope, falling into silence, then abrupt high volume
245 	envUU = 12,	///< envelope, raising until top multiple times
246 	envUH = 13,	///< envelope, raising until top and then mantaining high volume
247 	envUDUD = 14	///< envelope, triangle shaped
248 };
249 
250 
251 #endif
252