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