1 /***************************************************************************
2 ****************************************************************************
3 ****************************************************************************
4 *
5 * FunktrackerGOLD - By Jason Nunn
6 * Copyright (C) 1996,1998 Jason Nunn
7 *
8 * FunktrackerGOLD now comes under the GNU General Public License. Please
9 * read the COPYING notice in this distribution.
10 *
11 * ================================================================
12 * playback routines
13 *
14 ****************************************************************************
15 ****************************************************************************
16 ***************************************************************************/
17 #include "funktracker_defs.h"
18 #include "dsp_mixxer.h"
19 
20 /*funk ptrs*/
21 tfunk_info  funk_info;
22 tfunk_hr    *funk_hr_ptr;                   /*header pointer*/
23 tslot       *funk_pat_ptr;
24 void        *funk_sam_ptrs[64];                 /*sample pointers ptr*/
25 tfunk_chan  funk_chan[MAXIMUM_CHANNELS];
26 void        (*CARD_freq_convert)(int,long) = DSPi_freq_convert;
27 void        (*CARD_volume_convert)(int,int,int) = DSPi_volume_convert;
28 
29 /*******************************************
30 * private vars
31 *******************************************/
32 int note_table[64] =
33 {
34 13696,12928,12192,11520,10848,10240, 9664, 9120, 8608, 8128, 7680, 7248,
35  6848, 6464, 6096, 5760, 5424, 5120, 4832, 4560, 4304, 4064, 3840, 3624,
36  3424, 3232, 3048, 2880, 2712, 2560, 2416, 2280, 2152, 2032, 1920, 1808,
37  1712, 1616, 1520, 1440, 1360, 1280, 1208, 1144, 1080, 1016,  960,  904,
38   856,  808,  760,  720,  680,  640,  600,  568,  536,  504,  480,  448,
39     0,    0,    0,    0
40 };
41 
42 int com_volume_inc[16] =
43 {
44     1,  2,  3,  4,  5,  6,  7,  8,
45    10, 12, 16, 20, 24, 32, 48, 64
46 };
47 
48 int com_sine_table[64] =
49 {
50    -6, -19, -31, -43, -55, -66, -76, -86,
51   -95,-103,-110,-116,-120,-124,-127,-128,
52  -128,-127,-124,-121,-116,-110,-103, -95,
53   -86, -77, -66, -55, -44, -32, -19,  -7,
54     6,  18,  30,  42,  54,  65,  76,  85,
55    94, 102, 109, 115, 120, 124, 126, 127,
56   127, 126, 124, 121, 116, 110, 104,  96,
57    87,  77,  67,  56,  44,  32,  20,   8
58 };
59 
60 int com_triangle_table[64] =
61 {
62    -4, -12, -20, -28, -36, -44, -52, -60,
63   -68, -76, -84, -92,-100,-108,-116,-124,
64  -124,-116,-108,-100, -92, -84, -76, -68,
65   -60, -52, -44, -36, -28, -20, -12,  -4,
66     4,  12,  20,  28,  36,  44,  52,  60,
67    68,  76,  84,  92, 100, 108, 116, 124,
68   123, 115, 107,  99,  91,  83,  75,  67,
69    59,  51,  43,  35,  27,  19,  11,   3
70 };
71 
72 int com_square_table[64] =
73 {
74   -64,-128,-128,-127,-127,-128,-128,-127,
75  -127,-128,-128,-127,-127,-128,-128,-127,
76  -127,-128,-128,-127,-127,-128,-128,-127,
77  -127,-128,-128,-127,-127,-128,-128, -64,
78    95, 127, 127, 126, 126, 127, 127, 126,
79   126, 127, 127, 126, 126, 127, 127, 126,
80   126, 127, 127, 126, 126, 127, 127, 126,
81   126, 127, 127, 126, 126, 127, 127,  95
82 };
83 
84 int com_sawtooth_table[64] =
85 {
86    -1,  -5,  -9, -13, -17, -21, -25, -29,
87   -33, -37, -41, -45, -49, -53, -57, -61,
88   -65, -69, -73, -77, -81, -85, -89, -93,
89   -97,-101,-105,-109,-113,-117,-121,-125,
90   127, 123, 119, 115, 111, 107, 103,  99,
91    95,  91,  87,  83,  79,  75,  71,  67,
92    63,  59,  55,  51,  47,  43,  39,  35,
93    31,  27,  23,  19,  15,  11,   7,   3
94 };
95 
96 int com_random_table[64] =
97 {
98   168, 167, 167, 165, 201, 201, 202, 201,
99   244, 244, 244, 244,  85,  82,  85,  85,
100    44,  44,  44,  44, 114, 114, 114, 114,
101    77,  77,  73,  77, 116, 116, 116, 116,
102    87,  87,  87,  87,  31,  31,  31,  31,
103   198, 198, 198, 198, 105, 104, 105, 105,
104   103, 105, 103, 103, 166, 166, 165, 166,
105   171, 172, 171, 171, 217, 217, 217, 217
106 };
107 
108 int   c_channel;
109 tslot *pattern_ptr;  /*ptr to extract data from pattern*/
110 
111 /**************************************************************************
112 ***************************************************************************
113 ***************************************************************************
114 ***************************************************************************
115 ***************************************************************************
116 *
117 * Tracker Code
118 *
119 ***************************************************************************
120 ***************************************************************************
121 ***************************************************************************
122 ***************************************************************************
123 **************************************************************************/
124 
125 /**************************************************************************
126 *
127 **************************************************************************/
128 
129 /***********************************
130 *
131 * ebx = ifreq, returns = eax
132 *
133 ***********************************/
ifreq_to_rfreq(long ifreq)134 long ifreq_to_rfreq(long ifreq)
135 {
136   if(ifreq > 0)
137     return (0x1b4f4d0 / ifreq);
138   else
139     return 0;
140 }
141 
ifreq_to_rfreq_vib(long ifreq)142 long ifreq_to_rfreq_vib(long ifreq)
143 {
144   ifreq += funk_chan[c_channel].ifreq_vibrato;
145   if(ifreq <= 0) ifreq = 1;
146   return ifreq_to_rfreq(ifreq);
147 }
148 
149 /***********************************
150 *
151 ***********************************/
volume_convert(void)152 void volume_convert(void)
153 {
154   if(funk_chan[c_channel].channel_kill == STOP)
155     CARD_volume_convert(c_channel,0,0);
156   else
157     CARD_volume_convert(
158       c_channel,
159       funk_chan[c_channel].rvolume,
160       funk_chan[c_channel].balance);
161 }
162 
vol_to_realvol(void)163 void vol_to_realvol(void)
164 {
165   funk_chan[c_channel].rvolume = funk_chan[c_channel].volume;
166 }
167 
vol_to_realvol_vib(void)168 void vol_to_realvol_vib(void)
169 {
170   funk_chan[c_channel].rvolume =
171     funk_chan[c_channel].volume + funk_chan[c_channel].volume_vibrato;
172   if(funk_chan[c_channel].rvolume < 0) funk_chan[c_channel].rvolume = 0;
173   if(funk_chan[c_channel].rvolume > 255) funk_chan[c_channel].rvolume = 255;
174 }
175 
176 /***********************************
177 * bl = note, returns ebx = ifreq
178 ***********************************/
179 #define note_2_ifreq(note) note_table[note]
180 
181 /***********************************
182 *
183 * misc. vibrato function used by
184 * frequency and volume functions
185 *
186 * al = waveform
187 * ah = amplitude
188 * cl = speed
189 * ebx = ptr to vibrato table
190 * returns al = value, ebx = ptr
191 *
192 ***********************************/
com_vib_func(int waveform,int amplitude,int speed,int * vib_table_ptr)193 int com_vib_func(int waveform,
194                  int amplitude,
195                  int speed,
196                  int *vib_table_ptr)
197 {
198   register int tmp;
199 
200   amplitude++;
201   switch(waveform)
202   {
203     case 1:        /*triangle*/
204       tmp = com_triangle_table[*vib_table_ptr];
205       break;
206     case 2:        /*square*/
207       tmp = com_square_table[*vib_table_ptr];
208       break;
209     case 3:        /*sawtooth*/
210       tmp = com_sawtooth_table[*vib_table_ptr];
211       break;
212     case 4:        /*random*/
213       tmp = com_random_table[*vib_table_ptr];
214       break;
215     default:       /*sine*/
216       tmp = com_sine_table[*vib_table_ptr];
217       break;
218   }
219   *vib_table_ptr += (~speed & 0xf) + 1;
220   *vib_table_ptr &= 0x3f;
221   return (tmp * amplitude) >> 4;
222 }
223 
224 /***********************************
225 *
226 * Decode values form slot patterns
227 *
228 ***********************************/
decode_sample_no(void)229 int decode_sample_no(void)
230 {
231   funk_chan[c_channel].sample =
232     ((pattern_ptr->not_sam & 0x3) << 4) + (pattern_ptr->sam_com >> 4);
233   return funk_chan[c_channel].sample;
234 }
235 
decode_note_no(void)236 int decode_note_no(void)
237 {
238   return pattern_ptr->not_sam >> 2;
239 }
240 
241 /***********************************
242 *
243 * for NOTE 3D: reload samples attrs
244 *
245 * returns sample volume
246 *
247 ***********************************/
reload_sample2(int sam_no)248 int reload_sample2(int sam_no)
249 {
250   register int tmp1;
251 
252   funk_chan[c_channel].balance = funk_hr_ptr->funk_sb[sam_no].balance;
253 
254   tmp1 = funk_hr_ptr->funk_sb[sam_no].pt_and_sop;
255   funk_chan[c_channel].port_type = tmp1 >> 4;
256   funk_chan[c_channel].sample_ofs_parm = tmp1 & 0xf;
257 
258   tmp1 = funk_hr_ptr->funk_sb[sam_no].vv_waveform;
259   funk_chan[c_channel].vib_waveform = tmp1 >> 4;
260   funk_chan[c_channel].vol_vib_waveform = tmp1 & 0xf;
261 
262   tmp1 = funk_hr_ptr->funk_sb[sam_no].rl_and_as;
263   funk_chan[c_channel].retrig_limit = tmp1 >> 4;
264   funk_chan[c_channel].arp_speed = tmp1 & 0xf;
265 
266   return funk_hr_ptr->funk_sb[sam_no].volume;
267 }
268 
reload_sample_attr(void)269 int reload_sample_attr(void)
270 {
271   return reload_sample2(decode_sample_no());
272 }
273 
274 /***********************************
275 *
276 * returns sample volume
277 *
278 ***********************************/
do_retrig_sample(int sam_no)279 int do_retrig_sample(int sam_no)
280 {
281   if(funk_hr_ptr->funk_sb[sam_no].length > 0)
282   {
283     if(funk_hr_ptr->funk_sb[sam_no].start == 0xffffffff)
284       chmix[c_channel].funkctrl = 0x2;    /*set funkctrl*/
285     else
286       chmix[c_channel].funkctrl = 0x3;
287     chmix[c_channel].sample_addr = funk_sam_ptrs[sam_no];
288     chmix[c_channel].start = funk_hr_ptr->funk_sb[sam_no].start;
289 
290     if(chmix[c_channel].start > funk_hr_ptr->funk_sb[sam_no].length)
291       chmix[c_channel].start = funk_hr_ptr->funk_sb[sam_no].length;
292 
293     chmix[c_channel].length = funk_hr_ptr->funk_sb[sam_no].length;
294     chmix[c_channel].sample_ptr = 0;
295   }
296   return reload_sample2(sam_no);
297 }
298 
decode_sample(void)299 int decode_sample(void)
300 {
301   return do_retrig_sample(decode_sample_no());
302 }
303 
304 /***********************************
305 *
306 ***********************************/
do_full_note(int note,int volume)307 void do_full_note(int note,int volume)
308 {
309   funk_chan[c_channel].note = note;
310   funk_chan[c_channel].volume = volume;
311   funk_chan[c_channel].ifreq = note_2_ifreq(note);
312   funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
313   vol_to_realvol();
314   CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
315   volume_convert();
316 }
317 
load_attr_active(int volume)318 void load_attr_active(int volume)
319 {
320   funk_chan[c_channel].volume = volume;
321   vol_to_realvol();
322   volume_convert();
323 }
324 
325 /***********************************
326 *
327 ***********************************/
normal_decode_system(void)328 void normal_decode_system(void)
329 {
330   register int note,volume;
331 
332   note = decode_note_no();
333   if(note == 0x3d)                /*if ReLOad samples then ...*/
334     load_attr_active(reload_sample_attr());
335   else
336   {
337     volume = decode_sample();
338     if(note != 0x3e)              /*if SAMPLE ONLY slot,then dont change note*/
339     {
340       funk_chan[c_channel].note_command = 0xf;
341       funk_chan[c_channel].volume_command = 0xf;
342       do_full_note(note,volume);
343     }
344   }
345 }
346 
normal_decode_note(void)347 void normal_decode_note(void)
348 {
349   register int note,volume;
350 
351   note = decode_note_no();
352   if(note == 0x3d)                /*if ReLOad samples then ...*/
353     load_attr_active(reload_sample_attr());
354   else
355   {
356     volume = decode_sample();
357     if(note != 0x3e)              /*if SAMPLE ONLY slot,then dont change note*/
358     {
359       funk_chan[c_channel].volume_command = 0xf;
360       do_full_note(note,volume);
361     }
362   }
363 }
364 
normal_decode_volume(void)365 void normal_decode_volume(void)
366 {
367   register int note,volume;
368 
369   note = decode_note_no();
370   if(note == 0x3d)                /*if ReLOad samples then ...*/
371     load_attr_active(reload_sample_attr());
372   else
373   {
374     volume = decode_sample();
375     if(note != 0x3e)              /*if SAMPLE ONLY slot,then dont change note*/
376     {
377       funk_chan[c_channel].note_command = 0xf;
378       do_full_note(note,volume);
379     }
380   }
381 }
382 
383 /***********************************
384 *
385 ***********************************/
comc_decode(void)386 void comc_decode(void)
387 {
388   register int note,volume;
389 
390   note = decode_note_no();
391   if(note == 0x3d)                /*if ReLOad samples then ...*/
392     load_attr_active(reload_sample_attr());
393   else
394   {
395     volume = decode_sample();
396     if(note != 0x3e)              /*if SAMPLE ONLY slot,then dont change note*/
397     {
398       funk_chan[c_channel].volume_command = 0xf;
399       funk_chan[c_channel].volume = volume;
400       funk_chan[c_channel].note = note;
401       funk_chan[c_channel].ifreq_portdest = note_2_ifreq(note);
402       funk_chan[c_channel].rfreq_portdest = ifreq_to_rfreq(funk_chan[c_channel].ifreq_portdest);
403       vol_to_realvol();
404       CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
405       volume_convert();
406     }
407   }
408 }
409 
410 /***********************************
411 *
412 ***********************************/
comi_decode(void)413 void comi_decode(void)
414 {
415   register int note,volume;
416 
417   note = decode_note_no();
418   if(note == 0x3d)                /*if ReLOad samples then ...*/
419     funk_chan[c_channel].volume_portdest = reload_sample_attr();
420   else
421   {
422     volume = decode_sample();
423     if(note != 0x3e)              /*if SAMPLE ONLY slot,then dont change note*/
424     {
425       funk_chan[c_channel].note_command = 0xf;
426       funk_chan[c_channel].volume_portdest = volume;
427       funk_chan[c_channel].note = note;
428       funk_chan[c_channel].ifreq = note_2_ifreq(note);
429       funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
430       vol_to_realvol();
431       CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
432       volume_convert();
433     }
434     else
435     {
436       funk_chan[c_channel].volume_portdest = volume;
437     }
438   }
439 }
440 
441 /***************************************************************************
442 *
443 ***************************************************************************/
444 #define IPORT_TOP_LIM 448
445 #define RPORT_TOP_LIM (0x1b4f4d0 / 448)
446 
447 #define IPORT_BOT_LIM 13696
448 #define RPORT_BOT_LIM (0x1b4f4d0 / 13696)
449 
450 /***********************************
451 *0Com A: port up  (modified as from R2)
452 *
453 * com_val : 00000000
454 *           \ rate /
455 *
456 ***********************************/
com_port_up_log(int note_com_val)457 void com_port_up_log(int note_com_val)
458 {
459   funk_chan[c_channel].ifreq -= (note_com_val + 1) << 2;
460   if(funk_chan[c_channel].ifreq <= IPORT_TOP_LIM)
461   {
462     funk_chan[c_channel].note_command = 0xf;
463     funk_chan[c_channel].ifreq = IPORT_TOP_LIM;
464   }
465   funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
466   CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
467 }
468 
com_port_up_lin(int note_com_val)469 void com_port_up_lin(int note_com_val)
470 {
471   funk_chan[c_channel].rfreq += (note_com_val + 1) << 3;
472   if(funk_chan[c_channel].rfreq >= RPORT_TOP_LIM)
473   {
474     funk_chan[c_channel].note_command = 0xf;
475     funk_chan[c_channel].rfreq = RPORT_TOP_LIM;
476   }
477   CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
478 }
479 
480 /***********************************
481 *1Com B: port down (modified as of R2)
482 *
483 * com_val : 00000000
484 *           \ rate /
485 *
486 ***********************************/
com_port_dn_log(int note_com_val)487 void com_port_dn_log(int note_com_val)
488 {
489   funk_chan[c_channel].ifreq += (note_com_val + 1) << 2;
490   if(funk_chan[c_channel].ifreq >= IPORT_BOT_LIM)
491   {
492     funk_chan[c_channel].note_command = 0xf;
493     funk_chan[c_channel].ifreq = IPORT_BOT_LIM;
494   }
495   funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
496   CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
497 }
498 
com_port_dn_lin(int note_com_val)499 void com_port_dn_lin(int note_com_val)
500 {
501   funk_chan[c_channel].rfreq -= (note_com_val + 1) << 3;
502   if(funk_chan[c_channel].rfreq <= RPORT_BOT_LIM)
503   {
504     funk_chan[c_channel].note_command = 0xf;
505     funk_chan[c_channel].rfreq = RPORT_BOT_LIM;
506   }
507   CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
508 }
509 
510 /***********************************
511 *2Com C: port to note (modified as of R2)
512 *
513 ***********************************/
com_porta_log_subm1(void)514 void com_porta_log_subm1(void)
515 {
516   funk_chan[c_channel].note_command = 0xf;
517   funk_chan[c_channel].ifreq = funk_chan[c_channel].ifreq_portdest;
518   funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
519   CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
520 }
521 
com_porta_log(void)522 void com_porta_log(void)
523 {
524   if(funk_chan[c_channel].ifreq == funk_chan[c_channel].ifreq_portdest)
525     funk_chan[c_channel].note_command = 0xf;
526   else
527     if(funk_chan[c_channel].ifreq > funk_chan[c_channel].ifreq_portdest)
528     {
529       com_port_up_log(funk_chan[c_channel].note_com_val);
530       if(funk_chan[c_channel].ifreq <= funk_chan[c_channel].ifreq_portdest)
531         com_porta_log_subm1();
532     }
533     else
534     {
535       com_port_dn_log(funk_chan[c_channel].note_com_val);
536       if(funk_chan[c_channel].ifreq >= funk_chan[c_channel].ifreq_portdest)
537         com_porta_log_subm1();
538     }
539 }
540 
com_porta_lin_subm1(void)541 void com_porta_lin_subm1(void)
542 {
543   funk_chan[c_channel].note_command = 0xf;
544   funk_chan[c_channel].rfreq = funk_chan[c_channel].rfreq_portdest;
545   CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
546 }
547 
com_porta_lin(void)548 void com_porta_lin(void)
549 {
550   if(funk_chan[c_channel].rfreq == funk_chan[c_channel].rfreq_portdest)
551     funk_chan[c_channel].note_command = 0xf;
552   else
553     if(funk_chan[c_channel].rfreq < funk_chan[c_channel].rfreq_portdest)
554     {
555       com_port_up_lin(funk_chan[c_channel].note_com_val);
556       if(funk_chan[c_channel].rfreq >= funk_chan[c_channel].rfreq_portdest)
557         com_porta_lin_subm1();
558     }
559     else
560     {
561       com_port_dn_lin(funk_chan[c_channel].note_com_val);
562       if(funk_chan[c_channel].rfreq <= funk_chan[c_channel].rfreq_portdest)
563         com_porta_lin_subm1();
564     }
565 }
566 
567 /***********************************
568 *3Com D: vibrato
569 *
570 * com_val :   0000   0000
571 *           \speed/ \amplitude/
572 *
573 *vib_waveform = 0   : sine
574 *               1   : triangle
575 *               2   : square
576 *               3   : sawtooth
577 *               4   : random
578 *
579 ***********************************/
580 #define VIBAMP 1
581 
com_vibrato(void)582 void com_vibrato(void)
583 {
584   funk_chan[c_channel].ifreq_vibrato = com_vib_func(
585     funk_chan[c_channel].vib_waveform,
586     funk_chan[c_channel].note_com_val & 0xf, /*amp*/
587     funk_chan[c_channel].note_com_val >> 4,  /*speed*/
588     &funk_chan[c_channel].vib_ptr) << VIBAMP;
589   funk_chan[c_channel].rfreq = ifreq_to_rfreq_vib(funk_chan[c_channel].ifreq);
590   CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
591 }
592 
593 /***********************************
594 *4Com E: vibrato Fanin
595 *
596 * com_val :   0000   0000
597 *           \speed/ \fanin value/
598 *
599 *vib_waveform = 0   : sine
600 *               1   : triangle
601 *               2   : square
602 *               3   : sawtooth
603 *               4   : random
604 *
605 ***********************************/
com_vib_fanin(void)606 void com_vib_fanin(void)
607 {
608   register int fanin,speed;
609 
610   fanin = funk_chan[c_channel].note_com_val & 0xf;
611   speed = (funk_chan[c_channel].note_com_val & 0xf0) >> 2;
612 
613   if(funk_chan[c_channel].note_beat_count < 0xf)
614     if(funk_chan[c_channel].note_comspd_count < speed)
615       funk_chan[c_channel].note_comspd_count++;
616     else
617     {
618       funk_chan[c_channel].note_comspd_count = 0;
619       funk_chan[c_channel].note_beat_count++;
620     }
621   funk_chan[c_channel].ifreq_vibrato = com_vib_func(
622     funk_chan[c_channel].vib_waveform,
623     fanin,                                 /*amp*/
624     funk_chan[c_channel].note_beat_count,  /*speed*/
625     &funk_chan[c_channel].vib_ptr) << VIBAMP;
626   funk_chan[c_channel].rfreq = ifreq_to_rfreq_vib(funk_chan[c_channel].ifreq);
627   CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
628 }
629 
630 /***********************************
631 *5Com F: vibrato Fanout
632 *
633 * com_val :   0000   0000
634 *           \speed/ \fanin value/
635 *
636 *vib_waveform = 0   : sine
637 *               1   : triangle
638 *               2   : square
639 *               3   : sawtooth
640 *               4   : random
641 *
642 ***********************************/
com_vib_fanout(void)643 void com_vib_fanout(void)
644 {
645   register int fanin,speed;
646 
647   fanin = funk_chan[c_channel].note_com_val & 0xf;
648   speed = (funk_chan[c_channel].note_com_val & 0xf0) >> 2;
649 
650   if(funk_chan[c_channel].note_beat_count > 0)
651     if(funk_chan[c_channel].note_comspd_count < speed)
652       funk_chan[c_channel].note_comspd_count++;
653     else
654     {
655       funk_chan[c_channel].note_comspd_count = 0;
656       funk_chan[c_channel].note_beat_count--;
657     }
658   funk_chan[c_channel].ifreq_vibrato = com_vib_func(
659     funk_chan[c_channel].vib_waveform,
660     fanin,                                 /*amp*/
661     funk_chan[c_channel].note_beat_count,  /*speed*/
662     &funk_chan[c_channel].vib_ptr) << VIBAMP;
663   funk_chan[c_channel].rfreq = ifreq_to_rfreq_vib(funk_chan[c_channel].ifreq);
664   CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
665 }
666 
667 /***********************************
668 *6Com G: volume sld up
669 *
670 * com_val : 0000   0000
671 *                 \rate/
672 *
673 ***********************************/
com_vol_up(void)674 void com_vol_up(void)
675 {
676   funk_chan[c_channel].volume +=
677     com_volume_inc[funk_chan[c_channel].volume_com_val & 0xf];
678 
679   if(funk_chan[c_channel].volume > 255)
680   {
681     funk_chan[c_channel].volume_command = 0xf;
682     funk_chan[c_channel].volume = 255;
683   }
684   vol_to_realvol();
685   volume_convert();
686 }
687 
688 /***********************************
689 *7Com H: volume slide down
690 *
691 * com_val : 0000   0000
692 *                 \rate/
693 *
694 ***********************************/
com_vol_dn(void)695 void com_vol_dn(void)
696 {
697   funk_chan[c_channel].volume -=
698     com_volume_inc[funk_chan[c_channel].volume_com_val & 0xf];
699   if(funk_chan[c_channel].volume < 0)
700   {
701     funk_chan[c_channel].volume_command = 0xf;
702     funk_chan[c_channel].volume = 0;
703   }
704   vol_to_realvol();
705   volume_convert();
706 }
707 
708 /***********************************
709 *8Com I: volume porta (Rapid ctrl)
710 *
711 ***********************************/
com_vol_porta_subm1(void)712 void com_vol_porta_subm1(void)
713 {
714   funk_chan[c_channel].volume_command = 0xf;
715   funk_chan[c_channel].volume = funk_chan[c_channel].volume_portdest;
716   vol_to_realvol();
717   volume_convert();
718 }
719 
com_vol_porta(void)720 void com_vol_porta(void)
721 {
722   if(funk_chan[c_channel].volume == funk_chan[c_channel].volume_portdest)
723     funk_chan[c_channel].volume_command = 0xf;
724   else
725   {
726     if(funk_chan[c_channel].volume >= funk_chan[c_channel].volume_portdest)
727     {
728       com_vol_dn();
729       if(funk_chan[c_channel].volume <= funk_chan[c_channel].volume_portdest)
730         com_vol_porta_subm1();
731     }
732     else
733     {
734       com_vol_up();
735       if(funk_chan[c_channel].volume >= funk_chan[c_channel].volume_portdest)
736         com_vol_porta_subm1();
737     }
738   }
739 }
740 
741 /*********************************
742 *
743 *********************************/
vol_sys_rapid_p1(void)744 void vol_sys_rapid_p1(void)
745 {
746   if((funk_chan[c_channel].volume_command >= 6) &&
747      (funk_chan[c_channel].volume_command <= 8))
748     if(funk_chan[c_channel].volume_comspd_count <
749       (funk_chan[c_channel].volume_com_val >> 4))
750     {
751       funk_chan[c_channel].volume_comspd_count++;
752     }
753     else
754     {
755       funk_chan[c_channel].volume_comspd_count = 0;
756       switch(funk_chan[c_channel].volume_command)
757       {
758         case 0x6:
759           com_vol_up();
760           break;
761         case 0x7:
762           com_vol_dn();
763           break;
764         case 0x8:
765           com_vol_porta();
766           break;
767       }
768     }
769 }
770 
771 /***********************************
772 *9Com J: Volume Reverb
773 *
774 * A simulated echo effect
775 *
776 * com_val : 0000   0000
777 *
778 *
779 ***********************************/
com_reverb(void)780 void com_reverb(void)
781 {
782   register int incre = (funk_chan[c_channel].volume_com_val & 0xf);
783   register int speed = (funk_chan[c_channel].volume_com_val & 0xf0) >> 2;
784   if(funk_chan[c_channel].volume_comspd_count < speed)
785   {
786     funk_chan[c_channel].volume_comspd_count++;
787     if(funk_chan[c_channel].volume > 0)
788     {
789       funk_chan[c_channel].volume -= com_volume_inc[incre];
790       if(funk_chan[c_channel].volume < 0)
791         funk_chan[c_channel].volume = 0;
792     }
793   }
794   else /*echo*/
795   {
796     funk_chan[c_channel].volume_comspd_count = 0;
797     funk_chan[c_channel].volume_beat_count -=
798       (-funk_chan[c_channel].volume_com_val & 0xf0) >> 4;
799     if(funk_chan[c_channel].volume_beat_count > 0)
800     {
801       funk_chan[c_channel].volume = funk_chan[c_channel].volume_beat_count;
802     }
803     else
804     {
805       funk_chan[c_channel].volume_command = 0xf;
806       funk_chan[c_channel].volume = 0;
807     }
808   }
809   vol_to_realvol();
810   volume_convert();
811 }
812 
813 /***********************************
814 *ACom K: tremola
815 *
816 * com_val :  0000    0000
817 *                   \rate/
818 *
819 ***********************************/
com_tremola(void)820 void com_tremola(void)
821 {
822   funk_chan[c_channel].volume_vibrato = com_vib_func(
823     funk_chan[c_channel].vol_vib_waveform,
824     funk_chan[c_channel].volume_com_val & 0xf, /*amp*/
825     funk_chan[c_channel].volume_com_val >> 4,  /*speed*/
826     &funk_chan[c_channel].vol_vib_ptr);
827   vol_to_realvol_vib();
828   volume_convert();
829 }
830 
831 /***********************************
832 *BCom L: arpeggio
833 *
834 * com_val :  0000    0000
835 *            \N1/    \N2/
836 *
837 ***********************************/
com_arpeggio(void)838 void com_arpeggio(void)
839 {
840   register int arp_note;
841 
842   if(funk_chan[c_channel].note_comspd_count < funk_chan[c_channel].arp_speed)
843     funk_chan[c_channel].note_comspd_count++;
844   else
845   {
846     funk_chan[c_channel].note_comspd_count = 0;
847     arp_note = funk_chan[c_channel].note;
848     switch(funk_chan[c_channel].note_beat_count)
849     {
850       case 1:
851         arp_note += (funk_chan[c_channel].note_com_val >> 4);
852         break;
853       case 2:
854         arp_note += (funk_chan[c_channel].note_com_val & 0xf);
855         break;
856     }
857     if(arp_note > 59)
858       arp_note = funk_chan[c_channel].note;
859     funk_chan[c_channel].ifreq = note_2_ifreq(arp_note);
860     funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
861     CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
862     if(funk_chan[c_channel].note_beat_count == 2)
863       funk_chan[c_channel].note_beat_count = 0;
864     else
865       funk_chan[c_channel].note_beat_count++;
866   }
867 }
868 
869 /***********************************
870 *CCom M: sample offset
871 *
872 * This is a all present sample
873 * offset that is effective all the
874 * time for a given channel
875 *
876 *
877 ***********************************/
com_sample_offset(void)878 void com_sample_offset(void)
879 {
880   register long offs = funk_chan[c_channel].com_val <<
881                        funk_chan[c_channel].sample_ofs_parm;
882   if(offs > funk_hr_ptr->funk_sb[funk_chan[c_channel].sample].length)
883     offs = funk_hr_ptr->funk_sb[funk_chan[c_channel].sample].length;
884   chmix[c_channel].sample_ptr += offs;
885 }
886 
887 /***********************************
888 *DCom N: volume
889 *
890 ***********************************/
com_volume(void)891 void com_volume(void)
892 {
893   funk_chan[c_channel].volume = funk_chan[c_channel].volume_com_val;
894   vol_to_realvol();
895   volume_convert();
896 }
897 
898 /***********************************
899 *ECom O0: misc control (cmd revised since R1)
900 *
901 *value  control set
902 *------------------
903 *0     vibrato sine
904 *1     vibrato triangle
905 *2     vibrato square
906 *3     vibrato sawtooth
907 *4     vibrato random
908 *5     tremola sine
909 *6     tremola triangle
910 *7     tremola square
911 *8     tremola sawtooth
912 *9     tremola random
913 *a     halt note system
914 *b     halt volume system
915 *c     halt all systems
916 *d     invert funkcrtl
917 *e     fine balance pann left
918 *f     fine balance pann right
919 *
920 ***********************************/
com_misccrtl(void)921 void com_misccrtl(void)
922 {
923   switch(funk_chan[c_channel].com_val & 0xf)
924   {
925     case 0x0:
926       funk_chan[c_channel].vib_waveform = 0;
927       break;
928     case 0x1:
929       funk_chan[c_channel].vib_waveform = 1;
930       break;
931     case 0x2:
932       funk_chan[c_channel].vib_waveform = 2;
933       break;
934     case 0x3:
935       funk_chan[c_channel].vib_waveform = 3;
936       break;
937     case 0x4:
938       funk_chan[c_channel].vib_waveform = 4;
939       break;
940     case 0x5:
941       funk_chan[c_channel].vol_vib_waveform = 0;
942       break;
943     case 0x6:
944       funk_chan[c_channel].vol_vib_waveform = 1;
945       break;
946     case 0x7:
947       funk_chan[c_channel].vol_vib_waveform = 2;
948       break;
949     case 0x8:
950       funk_chan[c_channel].vol_vib_waveform = 3;
951       break;
952     case 0x9:
953       funk_chan[c_channel].vol_vib_waveform = 4;
954       break;
955     case 0xa:
956       funk_chan[c_channel].note_command = 0xf;
957       break;
958     case 0xb:
959       funk_chan[c_channel].volume_command = 0xf;
960       break;
961     case 0xc:
962       funk_chan[c_channel].note_command = 0xf;
963       funk_chan[c_channel].volume_command = 0xf;
964       break;
965     case 0xd:
966       /* NOT USED*/
967       break;
968     case 0xe:
969     case 0xf:
970       funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
971       funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
972       break;
973   }
974 }
975 
com_pan_left(void)976 void com_pan_left(void)
977 {
978   funk_chan[c_channel].balance--;
979   if(funk_chan[c_channel].balance < 0)
980   {
981     funk_chan[c_channel].volume_command = 0xf;
982     funk_chan[c_channel].balance = 0;
983   }
984   volume_convert();
985 }
986 
com_pan_right(void)987 void com_pan_right(void)
988 {
989   funk_chan[c_channel].balance++;
990   if(funk_chan[c_channel].balance > 0xff)
991   {
992     funk_chan[c_channel].volume_command = 0xf;
993     funk_chan[c_channel].balance = 0xff;
994   }
995   volume_convert();
996 }
997 
998 /***********************************
999 * Com O1: volume cut               *
1000 *                                  *
1001 ***********************************/
com_volume_cut(void)1002 void com_volume_cut(void)
1003 {
1004   if(funk_chan[c_channel].volume_comspd_count <
1005      (funk_chan[c_channel].volume_com_val & 0xf))
1006   {
1007     funk_chan[c_channel].volume_comspd_count++;
1008   }
1009   else
1010   {
1011     funk_chan[c_channel].volume_command = 0xf;
1012     funk_chan[c_channel].volume = 0;
1013     vol_to_realvol();
1014     volume_convert();
1015   }
1016 }
1017 
1018 /***********************************
1019 * Com O2: Note Delay
1020 *
1021 *NB/ will only work within a slot time period.
1022 *when the next slot is loaded, the command and value are
1023 *purged (just like retrig)
1024 ***********************************/
com_note_delay(void)1025 void com_note_delay(void)
1026 {
1027   if(funk_chan[c_channel].comspd_count <
1028      (funk_chan[c_channel].com_val & 0xf))
1029   {
1030     funk_chan[c_channel].comspd_count++;
1031   }
1032   else
1033   {
1034     funk_chan[c_channel].command = 0xf;
1035     pattern_ptr = funk_chan[c_channel].delay_pattern_ptr;
1036     normal_decode_system();
1037   }
1038 }
1039 
1040 /***********************************
1041 * Com O3: set arpeggio speed
1042 *
1043 ***********************************/
com_arp_speed_set(void)1044 void com_arp_speed_set(void)
1045 {
1046   funk_chan[c_channel].arp_speed = funk_chan[c_channel].com_val & 0xf;
1047 }
1048 
1049 /***********************************
1050 * Com O4: fine port_up
1051 *
1052 * com_val :     0000
1053 *           \ rate /
1054 *
1055 ***********************************/
com_fine_port_up(void)1056 void com_fine_port_up(void)
1057 {
1058   register int x = funk_chan[c_channel].note_com_val & 0xf;
1059   if(funk_chan[c_channel].port_type)
1060     com_port_up_lin(x);
1061   else
1062     com_port_up_log(x);
1063 }
1064 
1065 /***********************************
1066 * Com O5: fine port_dn
1067 *
1068 * com_val :     0000
1069 *           \ rate /
1070 *
1071 ***********************************/
com_fine_port_dn(void)1072 void com_fine_port_dn(void)
1073 {
1074   register int x = funk_chan[c_channel].note_com_val & 0xf;
1075   if(funk_chan[c_channel].port_type)
1076     com_port_dn_lin(x);
1077   else
1078     com_port_dn_log(x);
1079 }
1080 
1081 /***********************************
1082 * Com O6: fine vol sld up
1083 *
1084 * com_val :        0000
1085 *                 \rate/
1086 *
1087 ***********************************/
1088 
1089 /*refer to com_vol_up(void)*/
1090 
1091 /***********************************
1092 * Com O7: fine vol sld dn
1093 *
1094 * com_val :        0000
1095 *                 \rate/
1096 *
1097 ***********************************/
1098 
1099 /*refer to com_vol_dn(void)*/
1100 
1101 /***********************************
1102 * Com O8: volume crest
1103 *
1104 * com_val :        0000
1105 *                 \speed/ (prehand)
1106 *
1107 * volume slides up then down,
1108 * starting at current frequency
1109 *
1110 ***********************************/
com_vol_crest(void)1111 void com_vol_crest(void)
1112 {
1113   switch(funk_chan[c_channel].volume_beat_count)
1114   {
1115     case 1: /*@@wait_a_bit*/
1116       if(funk_chan[c_channel].volume_comspd_count <
1117         (-((funk_chan[c_channel].volume_com_val & 0xf) + 1) & 0xf))
1118       {
1119         funk_chan[c_channel].volume_comspd_count++;
1120       }
1121       else
1122       {
1123         funk_chan[c_channel].volume_comspd_count = 0;
1124         funk_chan[c_channel].volume_beat_count++;
1125       }
1126       break;
1127     case 2: /*@@slide_down*/
1128       funk_chan[c_channel].volume -=
1129         (com_volume_inc[funk_chan[c_channel].volume_com_val & 0xf] >> 2) + 1;
1130       if(funk_chan[c_channel].volume <= funk_chan[c_channel].volume_portdest)
1131       {
1132         funk_chan[c_channel].volume_command = 0xf;
1133         funk_chan[c_channel].volume = funk_chan[c_channel].volume_portdest;
1134       }
1135       vol_to_realvol();
1136       volume_convert();
1137       break;
1138     default:
1139       funk_chan[c_channel].volume +=
1140         com_volume_inc[funk_chan[c_channel].volume_com_val & 0xf];
1141       if(funk_chan[c_channel].volume > 0xff)
1142       {
1143         funk_chan[c_channel].volume_comspd_count = 0;
1144         funk_chan[c_channel].volume_beat_count++;
1145         funk_chan[c_channel].volume = 0xff;
1146       }
1147       vol_to_realvol();
1148       volume_convert();
1149       break;
1150   }
1151 }
1152 
1153 /***********************************
1154 * Com O9: Echo Feedback Gain (was volume though in R1)
1155 *
1156 ***********************************/
com_echo_feedback(void)1157 void com_echo_feedback(void)
1158 {
1159   chmix[c_channel].echo_feedback = funk_chan[c_channel].com_val & 0xf;
1160 }
1161 
1162 /***********************************
1163 * Com OA: master volume set (cmd revised since R1)
1164 *
1165 * master effects all volumes.
1166 *
1167 * format:  4 3 2 1
1168 *         \| \---/
1169 *         dir   increment
1170 *          1 = up
1171 *          0 = down
1172 ***********************************/
com_master_set(void)1173 void com_master_set(void)
1174 {
1175   register int tmp = c_channel;
1176   register int dec_val = (funk_chan[c_channel].com_val & 0x7) << 2;
1177 
1178   if(funk_chan[c_channel].com_val & 0x8)
1179   {
1180     funk_info.master_volume += dec_val;
1181     if(funk_info.master_volume > 0xff)
1182       funk_info.master_volume = 0xff;
1183   }
1184   else
1185   {
1186     funk_info.master_volume -= dec_val;
1187     if(funk_info.master_volume < 0)
1188       funk_info.master_volume = 0;
1189   }
1190   for(c_channel = 0;c_channel < funk_info.no_active_channels;c_channel++)
1191     volume_convert();
1192   c_channel = tmp;
1193 }
1194 
1195 /***********************************
1196 * Com OB: Echo Delay
1197 *
1198 * In the Funktracker Revision 1 (DOS32 Funktracker), this command
1199 * was "Expand Loop". As the command wasn't used very often (and
1200 * wasn't very useful anyway, it has been replaced by this extremely
1201 * useful command.
1202 ***********************************/
com_echo_delay(void)1203 void com_echo_delay(void)
1204 {
1205   chmix[c_channel].echo_delay = funk_chan[c_channel].com_val & 0xf;
1206 }
1207 
1208 /***********************************
1209 * Com OC: Echo Decay
1210 *
1211 * Refer to the above comment in Com OB. This command used to be
1212 * "Colapse Loop". I don't think i've ever used these old commands
1213 * actually.
1214 ***********************************/
com_echo_decay(void)1215 void com_echo_decay(void)
1216 {
1217    chmix[c_channel].echo_decay = funk_chan[c_channel].com_val & 0xf;
1218 }
1219 
1220 /***********************************
1221 * Com OD: note retrig
1222 *
1223 * com_val : ????   0000
1224 *                 \speed/ (prehand)
1225 *
1226 * command only handled on full
1227 * or sample only slots
1228 *
1229 ***********************************/
com_note_retrig(void)1230 void com_note_retrig(void)
1231 {
1232   if(funk_chan[c_channel].retrig_spd_count <
1233     (funk_chan[c_channel].com_val & 0xf))
1234   {
1235     funk_chan[c_channel].retrig_spd_count++;
1236   }
1237   else
1238   {
1239     funk_chan[c_channel].retrig_spd_count = 0;
1240     if(funk_chan[c_channel].retrig_count < funk_chan[c_channel].retrig_limit)
1241     {
1242       funk_chan[c_channel].retrig_count++;
1243       do_retrig_sample(funk_chan[c_channel].sample);
1244     }
1245     else
1246       funk_chan[c_channel].command = 0xf;
1247   }
1248 }
1249 
1250 /***********************************
1251 * Com OE: set channel balance
1252 *
1253 ***********************************/
com_balance(void)1254 void com_balance(void)
1255 {
1256   funk_chan[c_channel].balance = (funk_chan[c_channel].com_val & 0xf) << 4;
1257   volume_convert();
1258 }
1259 
1260 /***********************************
1261 * Com OF: tempo
1262 *
1263 ***********************************/
com_tempo(void)1264 void com_tempo(void)
1265 {
1266   funk_info.tempo = funk_chan[c_channel].com_val & 0xf;
1267 }
1268 
1269 /***************************************************************************
1270 *
1271 * Command control for null slots only
1272 *
1273 ***************************************************************************/
cnc_vs_basic(void)1274 void cnc_vs_basic(void)
1275 {
1276   funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1277   funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1278   funk_chan[c_channel].volume_comspd_count = 0;
1279 }
1280 
com_null_ctrl(void)1281 void com_null_ctrl(void)
1282 {
1283   switch(funk_chan[c_channel].command)
1284   {
1285     case 0x0:                                          /*com a*/
1286       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1287       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1288       break;
1289     case 0x1:                                          /*com b*/
1290       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1291       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1292       break;
1293     case 0x2:                                          /*com c*/
1294       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1295       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1296       break;
1297     case 0x3:                                          /*com d*/
1298       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1299       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1300       funk_chan[c_channel].note_comspd_count = 0;
1301       break;
1302     case 0x4:                                          /*com e*/
1303       funk_chan[c_channel].note_beat_count = 0;
1304       goto set_vib_fan;
1305     case 0x5:                                          /*com f*/
1306       funk_chan[c_channel].note_beat_count = 0xf;
1307 set_vib_fan:
1308       if(funk_chan[c_channel].note_command == 0x3)/*if vibrato command*/
1309         funk_chan[c_channel].note_beat_count =
1310           funk_chan[c_channel].note_com_val >> 4;
1311       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1312       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1313       funk_chan[c_channel].note_comspd_count = 0;
1314       break;
1315     case 0x6:                                          /*com g*/
1316       cnc_vs_basic();
1317       break;
1318     case 0x7:                                          /*com h*/
1319       cnc_vs_basic();
1320       break;
1321     case 0x8:                                          /*com i*/
1322       cnc_vs_basic();
1323       break;
1324     case 0x9:                                          /*com j*/
1325       funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1326       funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1327       funk_chan[c_channel].volume_comspd_count = 0;
1328       funk_chan[c_channel].volume_beat_count = funk_chan[c_channel].volume;
1329       break;
1330     case 0xa:                                          /*com k*/
1331       cnc_vs_basic();
1332       break;
1333     case 0xb:                                          /*com l*/
1334       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1335       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1336       funk_chan[c_channel].note_comspd_count = 0;
1337       funk_chan[c_channel].note_beat_count = 1;
1338       break;
1339     case 0xd:                                          /*com n*/
1340       funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1341       funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1342       com_volume();
1343       break;
1344     case 0xe:                                          /*O commands*/
1345       switch(funk_chan[c_channel].com_val & 0xf0)
1346       {
1347         case 0x00:                                     /*com o0*/
1348           com_misccrtl();
1349           break;
1350         case 0x10:                                     /*com o1*/
1351           cnc_vs_basic();
1352           break;
1353         case 0x30:                                     /*com o3*/
1354           com_arp_speed_set();
1355           break;
1356         case 0x40:                                     /*com o4*/
1357           funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1358           funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1359           com_fine_port_up();
1360           break;
1361         case 0x50:                                     /*com o5*/
1362           funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1363           funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1364           com_fine_port_dn();
1365           break;
1366         case 0x60:                                     /*com o6*/
1367           funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1368           funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1369           com_vol_up();
1370           break;
1371         case 0x70:                                     /*com o7*/
1372           funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1373           funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1374           com_vol_dn();
1375           break;
1376         case 0x80:                                     /*com o8*/
1377           funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1378           funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1379           funk_chan[c_channel].volume_comspd_count = 0;
1380           funk_chan[c_channel].volume_beat_count = 0;
1381           funk_chan[c_channel].volume_portdest = funk_chan[c_channel].volume;
1382           break;
1383         case 0x90:                                     /*com o9*/
1384           com_echo_feedback();
1385           break;
1386         case 0xa0:                                     /*com oa*/
1387           com_master_set();
1388           break;
1389         case 0xb0:                                     /*com ob*/
1390           com_echo_delay();
1391           break;
1392         case 0xc0:                                     /*com oc*/
1393           com_echo_decay();
1394           break;
1395         case 0xe0:                                     /*com oe*/
1396           com_balance();
1397           break;
1398         case 0xf0:                                     /*com of*/
1399           com_tempo();
1400           break;
1401       }
1402       break;
1403   }
1404 }
1405 
1406 /***************************************************************************
1407 *
1408 * Command control for full slots
1409 *
1410 ***************************************************************************/
cfc_vs_basic(void)1411 void cfc_vs_basic(void)
1412 {
1413   funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1414   funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1415   funk_chan[c_channel].volume_comspd_count = 0;
1416   normal_decode_volume();
1417 }
1418 
com_full_ctrl(void)1419 void com_full_ctrl(void)
1420 {
1421   switch(funk_chan[c_channel].command)
1422   {
1423     case 0x0:                                          /*com a*/
1424       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1425       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1426       normal_decode_note();
1427       break;
1428     case 0x1:                                          /*com b*/
1429       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1430       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1431       normal_decode_note();
1432       break;
1433     case 0x2:                                          /*com c*/
1434       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1435       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1436       comc_decode();
1437       break;
1438     case 0x3:                                          /*com d*/
1439       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1440       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1441       funk_chan[c_channel].note_comspd_count = 0;
1442       normal_decode_note();
1443       break;
1444     case 0x4:                                          /*com e*/
1445       funk_chan[c_channel].note_beat_count = 0;
1446       goto set_vib_fan;
1447     case 0x5:                                          /*com f*/
1448       funk_chan[c_channel].note_beat_count = 0xf;
1449 set_vib_fan:
1450       if(funk_chan[c_channel].note_command == 0x3) /*if vibrato command*/
1451         funk_chan[c_channel].note_beat_count =
1452           funk_chan[c_channel].note_com_val >> 4;
1453       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1454       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1455       funk_chan[c_channel].note_comspd_count = 0;
1456       normal_decode_note();
1457       break;
1458     case 0x6:                                          /*com g*/
1459       cfc_vs_basic();
1460       break;
1461     case 0x7:                                          /*com h*/
1462       cfc_vs_basic();
1463       break;
1464     case 0x8:                                          /*com i*/
1465       funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1466       funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1467       funk_chan[c_channel].volume_comspd_count = 0;
1468       comi_decode();
1469       break;
1470     case 0x9:                                          /*com j*/
1471       funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1472       funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1473       funk_chan[c_channel].volume_comspd_count = 0;
1474       normal_decode_volume();
1475       funk_chan[c_channel].volume_beat_count = funk_chan[c_channel].volume;
1476       break;
1477     case 0xa:                                          /*com k*/
1478       cfc_vs_basic();
1479       break;
1480     case 0xb:                                          /*com l*/
1481       funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1482       funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1483       funk_chan[c_channel].note_comspd_count = 0;
1484       funk_chan[c_channel].note_beat_count = 1;
1485       normal_decode_note();
1486       break;
1487     case 0xc:                                          /*com m*/
1488       normal_decode_system();
1489       com_sample_offset();
1490       break;
1491     case 0xd:                                          /*com n*/
1492       funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1493       funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1494       normal_decode_volume();
1495       com_volume();
1496       break;
1497     case 0xe:                                          /*O commands*/
1498       switch(funk_chan[c_channel].com_val & 0xf0)
1499       {
1500         case 0x00:                                     /*com o0*/
1501           normal_decode_system();
1502           com_misccrtl();
1503           break;
1504         case 0x10:                                     /*com o1*/
1505           cfc_vs_basic();
1506           break;
1507         case 0x20:                                     /*com o2*/
1508           funk_chan[c_channel].comspd_count = 0;
1509           funk_chan[c_channel].delay_pattern_ptr = pattern_ptr;
1510           break;
1511         case 0x30:                                     /*com o3*/
1512           normal_decode_system();
1513           com_arp_speed_set();
1514           break;
1515         case 0x40:                                     /*com o4*/
1516           funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1517           funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1518           normal_decode_note();
1519           com_fine_port_up();
1520           break;
1521         case 0x50:                                     /*com o5*/
1522           funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1523           funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1524           normal_decode_note();
1525           com_fine_port_dn();
1526           break;
1527         case 0x60:                                     /*com o6*/
1528           funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1529           funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1530           normal_decode_volume();
1531           com_vol_up();
1532           break;
1533         case 0x70:                                     /*com o7*/
1534           funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1535           funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1536           normal_decode_volume();
1537           com_vol_dn();
1538           break;
1539         case 0x80:                                     /*com o8*/
1540           funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1541           funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1542           funk_chan[c_channel].volume_comspd_count = 0;
1543           funk_chan[c_channel].volume_beat_count = 0;
1544           normal_decode_volume();
1545           funk_chan[c_channel].volume_portdest = funk_chan[c_channel].volume;
1546           break;
1547         case 0x90:                                     /*com o9*/
1548           normal_decode_system();
1549           com_echo_feedback();
1550           break;
1551         case 0xa0:                                     /*com oa*/
1552           com_master_set();
1553           normal_decode_system();
1554           break;
1555         case 0xb0:                                     /*com ob*/
1556           normal_decode_system();
1557           com_echo_delay();
1558           break;
1559         case 0xc0:                                     /*com oc*/
1560           normal_decode_system();
1561           com_echo_decay();
1562           break;
1563         case 0xd0:                                     /*com od*/
1564           funk_chan[c_channel].retrig_count = 1;
1565           funk_chan[c_channel].retrig_spd_count = 0;
1566           normal_decode_system();
1567           break;
1568         case 0xe0:                                     /*com oe*/
1569           normal_decode_system();
1570           com_balance();
1571           break;
1572         case 0xf0:                                     /*com of*/
1573           normal_decode_system();
1574           com_tempo();
1575           break;
1576       }
1577       break;
1578     case 0xf:
1579       normal_decode_system();
1580       break;
1581   }
1582 }
1583 
1584 /***************************************************************************
1585 *
1586 * Command control for rapid "on the fly"
1587 * Rapid commands that have a speed parameter
1588 *
1589 ***************************************************************************/
com_rapid_ctrl(void)1590 void com_rapid_ctrl(void)
1591 {
1592   for(c_channel = 0;c_channel < funk_info.no_active_channels;c_channel++)
1593   {
1594     vol_sys_rapid_p1();
1595     switch(funk_chan[c_channel].note_command)
1596     {
1597       case 0x0:
1598         if(funk_chan[c_channel].port_type)
1599           com_port_up_lin(funk_chan[c_channel].note_com_val);
1600         else
1601           com_port_up_log(funk_chan[c_channel].note_com_val);
1602         break;
1603       case 0x1:
1604         if(funk_chan[c_channel].port_type)
1605           com_port_dn_lin(funk_chan[c_channel].note_com_val);
1606         else
1607           com_port_dn_log(funk_chan[c_channel].note_com_val);
1608         break;
1609       case 0x2:
1610         if(funk_chan[c_channel].port_type)
1611           com_porta_lin();
1612         else
1613           com_porta_log();
1614         break;
1615       case 0x3:                                        /*command d*/
1616         com_vibrato();
1617         break;
1618       case 0x4:                                        /*command e*/
1619         com_vib_fanin();
1620         break;
1621       case 0x5:                                        /*command f*/
1622         com_vib_fanout();
1623         break;
1624       case 0xb:                                        /*command l*/
1625         com_arpeggio();
1626         break;
1627     }
1628     switch(funk_chan[c_channel].volume_command)
1629     {
1630       case 0x9:                                        /*command j*/
1631         com_reverb();
1632         break;
1633       case 0xa:                                        /*command k*/
1634         com_tremola();
1635         break;
1636       case 0xe:
1637         switch(funk_chan[c_channel].volume_com_val)
1638         {
1639           case 0x0e:
1640             com_pan_left();
1641             break;
1642           case 0x0f:
1643             com_pan_right();
1644             break;
1645         }
1646         switch(funk_chan[c_channel].volume_com_val & 0xf0)
1647         {
1648           case 0x10:                                   /*command o1*/
1649             com_volume_cut();
1650             break;
1651           case 0x80:                                   /*command o8*/
1652             com_vol_crest();
1653             break;
1654         }
1655         break;
1656     }
1657     if(funk_chan[c_channel].command == 0xe)
1658       switch(funk_chan[c_channel].com_val & 0xf0)
1659       {
1660         case 0x20:                                    /*command o2*/
1661           com_note_delay();
1662           break;
1663         case 0xd0:                                    /*command od*/
1664           com_note_retrig();
1665           break;
1666       }
1667   }
1668 }
1669 
1670 /***************************************************************************
1671 *
1672 * ESI = current pattern
1673 *
1674 * format:
1675 *
1676 * 00000000 11111111 22222222
1677 * \    /\     /\  / \      /
1678 *  note  sample com  command value
1679 *
1680 * - if note:  = 3D, then reload sample attrs
1681 *             = 3F, then it's a null slot
1682 *             = 3E, then sample only slot
1683 *
1684 ***************************************************************************/
trekk_slot(int pattern_no)1685 void trekk_slot(int pattern_no)
1686 {
1687   register tslot *pattern_addr =
1688     funk_pat_ptr + (pattern_no * 64 * funk_info.no_active_channels) +
1689     (funk_info.pattern_ofs * funk_info.no_active_channels);
1690   for(c_channel = 0;c_channel < funk_info.no_active_channels;c_channel++)
1691   {
1692     pattern_ptr = pattern_addr + c_channel;
1693     funk_chan[c_channel].command = pattern_ptr->sam_com & 0xf;
1694     funk_chan[c_channel].com_val = pattern_ptr->com_val;
1695     if((pattern_ptr->not_sam >> 2) == 0x3f)
1696       com_null_ctrl();
1697     else
1698       com_full_ctrl();                  /*IF FULL SLOT or SAMPLE ONLY SLOT*/
1699   }
1700 }
1701 
1702 /***************************************************************************
1703 ****************************************************************************
1704 ****************************************************************************
1705 ****************************************************************************
1706 *
1707 * The actual tracker thingy :) ....0.02 second tick (or roughly)
1708 *
1709 ****************************************************************************
1710 ****************************************************************************
1711 ****************************************************************************
1712 ***************************************************************************/
funk_tracker(void)1713 void funk_tracker(void)
1714 {
1715   if(funk_info.trek_status == PLAY)
1716   {
1717     com_rapid_ctrl();
1718     if(funk_info.tempo_count < funk_info.tempo)
1719       funk_info.tempo_count++;
1720     else
1721     {
1722       funk_info.tempo_count = 0;
1723       funk_info.pattern_ofs_display = funk_info.pattern_ofs;
1724       funk_info.sequence_ofs_display = funk_info.sequence_ofs;
1725       trekk_slot(funk_hr_ptr->order_list[funk_info.sequence_ofs]);
1726       if(funk_info.pattern_ofs ==
1727         funk_hr_ptr->break_list[funk_hr_ptr->order_list[funk_info.sequence_ofs]])
1728       {
1729         if(funk_info.sequence_ofs < funk_info.no_of_sequences)
1730         {
1731           funk_info.sequence_ofs++;
1732           funk_info.pattern_ofs = 0;
1733         }
1734         else
1735           if(funk_hr_ptr->loop_order == 0xFF)
1736             funk_info.trek_status = STOP;
1737           else
1738             if(funk_hr_ptr->loop_order > funk_info.no_of_sequences)
1739               funk_info.trek_status = STOP;
1740             else
1741             {
1742               funk_info.sequence_ofs = funk_hr_ptr->loop_order;
1743               funk_info.pattern_ofs = 0;
1744             }
1745       }
1746       else
1747         funk_info.pattern_ofs++;
1748     }
1749   }
1750 }
1751