OSDN Git Service

[VM][FMTOWNS][MEMORY] Fix setup around memory banks by I/O 0404h and 0480h.
[csp-qt/common_source_project-fm7.git] / source / src / vm / msx / scc.cpp
1 /****************************************************************************
2
3   emu2212.c -- S.C.C. emulator by Mitsutaka Okazaki 2001
4
5   2001 09-30 : Version 1.00
6   2001 10-03 : Version 1.01 -- Added SCC_set_quality().
7   2002 02-14 : Version 1.10 -- Added SCC_writeReg(), SCC_set_type().
8                                Fixed SCC_write().
9   2002 02-17 : Version 1.11 -- Fixed SCC_write().
10   2002 03-02 : Version 1.12 -- Removed SCC_init & SCC_close.
11   2003 09-19 : Version 1.13 -- Added SCC_setMask() and SCC_toggleMask()
12   2004 10-21 : Version 1.14 -- Fixed the problem where SCC+ is disabled.
13   2015 12-13 : Version 1.15 -- Changed own integer types to C99 stdint.h types.
14
15   Registar map for SCC_writeReg()
16
17   $00-1F : WaveTable CH.A
18   $20-3F : WaveTable CH.B
19   $40-5F : WaveTable CH.C
20   $60-7F : WaveTable CH.D&E(SCC), CH.D(SCC+)
21   $80-9F : WaveTable CH.E
22  
23   $C0    : CH.A Freq(L)
24   $C1    : CH.A Freq(H)
25   $C2    : CH.B Freq(L)
26   $C3    : CH.B Freq(H)
27   $C4    : CH.C Freq(L)
28   $C5    : CH.C Freq(H)
29   $C6    : CH.D Freq(L)
30   $C7    : CH.D Freq(H)
31   $C8    : CH.E Freq(L)
32   $C9    : CH.E Freq(H)
33
34   $D0    : CH.A Volume
35   $D1    : CH.B Volume
36   $D2    : CH.C Volume
37   $D3    : CH.D Volume
38   $D4    : CH.E Volume
39  
40   $E0    : Bit0 = 0:SCC, 1:SCC+
41   $E1    : CH mask
42   $E2    : Extra Flags
43
44 *****************************************************************************/
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include "scc.h"
49 #include "../../types/util_sound.h"
50
51 #define SCC EMU2212
52
53 #define GETA_BITS 22
54
55 namespace MSX {
56
57 static void
58 internal_refresh (SCC * scc)
59 {
60   if (scc->quality)
61   {
62     scc->base_incr = 2 << GETA_BITS;
63     scc->realstep = (uint32_t) ((1 << 31) / scc->rate);
64     scc->sccstep = (uint32_t) ((1 << 31) / (scc->clk / 2));
65     scc->scctime = 0;
66   }
67   else
68   {
69     scc->base_incr = (uint32_t) ((double) scc->clk * (1 << GETA_BITS) / scc->rate);
70   }
71 }
72
73 uint32_t
74 SCC_setMask (SCC *scc, uint32_t mask)
75 {
76   uint32_t ret = 0;
77   if(scc)
78   {
79     ret = scc->mask;
80     scc->mask = mask;
81   }  
82   return ret;
83 }
84
85 uint32_t
86 SCC_toggleMask (SCC *scc, uint32_t mask)
87 {
88   uint32_t ret = 0;
89   if(scc)
90   {
91     ret = scc->mask;
92     scc->mask ^= mask;
93   }
94   return ret;
95 }
96
97 void
98 SCC_set_quality (SCC * scc, uint32_t q)
99 {
100   scc->quality = q;
101   internal_refresh (scc);
102 }
103
104 void
105 SCC_set_rate (SCC * scc, uint32_t r)
106 {
107   scc->rate = r ? r : 44100;
108   internal_refresh (scc);
109 }
110
111 SCC *
112 SCC_new (uint32_t c, uint32_t r)
113 {
114   SCC *scc;
115
116   scc = (SCC *) malloc (sizeof (SCC));
117   if (scc == NULL)
118     return NULL;
119   memset(scc, 0, sizeof (SCC));
120
121   scc->clk = c;
122   scc->rate = r ? r : 44100;
123   SCC_set_quality (scc, 0);
124   scc->type = SCC_ENHANCED;
125   return scc;
126 }
127
128 void
129 SCC_reset (SCC * scc)
130 {
131   int i, j;
132
133   if (scc == NULL)
134     return;
135
136   scc->mode = 0;
137   scc->active = 0;
138   scc->base_adr = 0x9000;
139
140   for (i = 0; i < 5; i++)
141   {
142     for (j = 0; j < 5; j++)
143       scc->wave[i][j] = 0;
144     scc->count[i] = 0;
145     scc->freq[i] = 0;
146     scc->phase[i] = 0;
147     scc->volume[i] = 0;
148     scc->offset[i] = 0;
149     scc->rotate[i] = 0;
150   }
151
152   memset(scc->reg,0,0x100-0xC0);
153
154   scc->mask = 0;
155
156   scc->ch_enable = 0xff;
157   scc->ch_enable_next = 0xff;
158
159   scc->cycle_4bit = 0;
160   scc->cycle_8bit = 0;
161   scc->refresh = 0;
162
163   scc->out = 0;
164   scc->prev = 0;
165   scc->next = 0;
166
167   return;
168 }
169
170 void
171 SCC_delete (SCC * scc)
172 {
173   if (scc != NULL)
174     free (scc);
175 }
176
177 static inline int16_t
178 calc (SCC * scc)
179 {
180   int i;
181   int32_t mix = 0;
182
183   for (i = 0; i < 5; i++)
184   {
185     scc->count[i] = (scc->count[i] + scc->incr[i]);
186
187     if (scc->count[i] & (1 << (GETA_BITS + 5)))
188     {
189       scc->count[i] &= ((1 << (GETA_BITS + 5)) - 1);
190       scc->offset[i] = (scc->offset[i] + 31) & scc->rotate[i];
191       scc->ch_enable &= ~(1 << i);
192       scc->ch_enable |= scc->ch_enable_next & (1 << i);
193     }
194
195     if (scc->ch_enable & (1 << i))
196     {
197       scc->phase[i] = ((scc->count[i] >> (GETA_BITS)) + scc->offset[i]) & 0x1F;
198       if(!(scc->mask&SCC_MASK_CH(i)))
199         mix += ((((int8_t) (scc->wave[i][scc->phase[i]]) * (int8_t) scc->volume[i]))) >> 4;
200     }
201   }
202
203   return (int16_t) (mix << 4);
204 }
205
206 int16_t
207 SCC_calc (SCC * scc)
208 {
209   if (!scc->quality)
210     return calc (scc);
211
212   while (scc->realstep > scc->scctime)
213   {
214     scc->scctime += scc->sccstep;
215     scc->prev = scc->next;
216     scc->next = calc (scc);
217   }
218
219   scc->scctime -= scc->realstep;
220   scc->out = (int16_t) (((double) scc->next * (scc->sccstep - scc->scctime) + (double) scc->prev * scc->scctime) / scc->sccstep);
221
222   return (int16_t) (scc->out);
223 }
224
225 uint32_t
226 SCC_readReg (SCC * scc, uint32_t adr)
227 {
228   if (adr < 0xA0)
229     return scc->wave[adr >> 5][adr & 0x1f];
230   else if( 0xC0 < adr && adr < 0xF0 )
231     return scc->reg[adr-0xC0];
232   else
233     return 0;
234 }
235
236 void
237 SCC_writeReg (SCC * scc, uint32_t adr, uint32_t val)
238 {
239   int ch;
240   uint32_t freq;
241
242   adr &= 0xFF;
243
244   if (adr < 0xA0)
245   {
246     ch = (adr & 0xF0) >> 5;
247     if (!scc->rotate[ch])
248     {
249       scc->wave[ch][adr & 0x1F] = (int8_t) val;
250       if (scc->mode == 0 && ch == 3)
251         scc->wave[4][adr & 0x1F] = (int8_t) val;
252     }
253   }
254   else if (0xC0 <= adr && adr <= 0xC9)
255   {
256     scc->reg[adr-0xC0] = val;
257     ch = (adr & 0x0F) >> 1;
258     if (adr & 1)
259       scc->freq[ch] = ((val & 0xF) << 8) | (scc->freq[ch] & 0xFF);
260     else
261       scc->freq[ch] = (scc->freq[ch] & 0xF00) | (val & 0xFF);
262
263     if (scc->refresh)
264       scc->count[ch] = 0;
265     freq = scc->freq[ch];
266     if (scc->cycle_8bit)
267       freq &= 0xFF;
268     if (scc->cycle_4bit)
269       freq >>= 8;
270     if (freq <= 8)
271       scc->incr[ch] = 0;
272     else
273       scc->incr[ch] = scc->base_incr / (freq + 1);
274   }
275   else if (0xD0 <= adr && adr <= 0xD4)
276   {
277     scc->reg[adr-0xC0] = val;
278     scc->volume[adr & 0x0F] = (uint8_t) (val & 0xF);
279   }
280   else if (adr == 0xE0)
281   {
282     scc->reg[adr-0xC0] = val;
283     scc->mode = (uint8_t) val & 1;
284   }
285   else if (adr == 0xE1)
286   {
287     scc->reg[adr-0xC0] = val;
288     scc->ch_enable_next = (uint8_t) val & 0x1F;
289   }
290   else if (adr == 0xE2)
291   {
292     scc->reg[adr-0xC0] = val;
293     scc->cycle_4bit = val & 1;
294     scc->cycle_8bit = val & 2;
295     scc->refresh = val & 32;
296     if (val & 64)
297       for (ch = 0; ch < 5; ch++)
298         scc->rotate[ch] = 0x1F;
299     else
300       for (ch = 0; ch < 5; ch++)
301         scc->rotate[ch] = 0;
302     if (val & 128)
303       scc->rotate[3] = scc->rotate[4] = 0x1F;
304   }
305
306   return;
307 }
308
309 static inline void
310 write_standard (SCC * scc, uint32_t adr, uint32_t val)
311 {
312   adr &= 0xFF;
313
314   if (adr < 0x80)               /* wave */
315   {
316     SCC_writeReg (scc, adr, val);
317   }
318   else if (adr < 0x8A)          /* freq */
319   {
320     SCC_writeReg (scc, adr + 0xC0 - 0x80, val);
321   }
322   else if (adr < 0x8F)          /* volume */
323   {
324     SCC_writeReg (scc, adr + 0xD0 - 0x8A, val);
325   }
326   else if (adr == 0x8F)         /* ch enable */
327   {
328     SCC_writeReg (scc, 0xE1, val);
329   }
330   else if (0xE0 <= adr)         /* flags */
331   {
332     SCC_writeReg (scc, 0xE2, val);
333   }
334 }
335
336 static inline void
337 write_enhanced (SCC * scc, uint32_t adr, uint32_t val)
338 {
339   adr &= 0xFF;
340
341   if (adr < 0xA0)               /* wave */
342   {
343     SCC_writeReg (scc, adr, val);
344   }
345   else if (adr < 0xAA)          /* freq */
346   {
347     SCC_writeReg (scc, adr + 0xC0 - 0xA0, val);
348   }
349   else if (adr < 0xAF)          /* volume */
350   {
351     SCC_writeReg (scc, adr + 0xD0 - 0xAA, val);
352   }
353   else if (adr == 0xAF)         /* ch enable */
354   {
355     SCC_writeReg (scc, 0xE1, val);
356   }
357   else if (0xC0 <= adr && adr <= 0xDF)  /* flags */
358   {
359     SCC_writeReg (scc, 0xE2, val);
360   }
361 }
362
363 static inline uint32_t 
364 read_enhanced (SCC * scc, uint32_t adr)
365 {
366   adr &= 0xFF;
367   if (adr < 0xA0)
368     return SCC_readReg (scc, adr);
369   else if (adr < 0xAA)
370     return SCC_readReg (scc, adr + 0xC0 - 0xA0);
371   else if (adr < 0xAF)
372     return SCC_readReg (scc, adr + 0xD0 - 0xAA);
373   else if (adr == 0xAF)
374     return SCC_readReg (scc, 0xE1);
375   else if (0xC0 <= adr && adr <= 0xDF)
376     return SCC_readReg (scc, 0xE2);
377   else
378     return 0;
379 }
380
381 static inline uint32_t
382 read_standard (SCC * scc, uint32_t adr)
383 {
384   adr &= 0xFF;
385   if(adr<0x80)
386     return SCC_readReg (scc, adr);
387   else if (0xA0<=adr&&adr<=0xBF)
388     return SCC_readReg (scc, 0x80+(adr&0x1F));
389   else if (adr < 0x8A)          
390     return SCC_readReg (scc, adr + 0xC0 - 0x80);
391   else if (adr < 0x8F)          
392     return SCC_readReg (scc, adr + 0xD0 - 0x8A);
393   else if (adr == 0x8F)         
394     return SCC_readReg (scc, 0xE1);
395   else if (0xE0 <= adr)         
396     return SCC_readReg (scc, 0xE2);
397   else return 0;
398 }
399
400 uint32_t
401 SCC_read (SCC * scc, uint32_t adr)
402 {
403   if( scc->type == SCC_ENHANCED && (adr&0xFFFE) == 0xBFFE ) 
404     return (scc->base_adr>>8)&0x20;
405   
406   if( adr < scc->base_adr ) return 0;
407   adr -= scc->base_adr;
408   
409   if( adr == 0 ) 
410   {
411     if(scc->mode) return 0x80; else return 0x3F;
412   }
413
414   if(!scc->active||adr<0x800||0x8FF<adr) return 0;
415
416   switch (scc->type) 
417   {
418   case SCC_STANDARD:
419       return read_standard (scc, adr);
420     break;
421   case SCC_ENHANCED:
422     if(!scc->mode)
423       return read_standard (scc, adr);
424     else 
425       return read_enhanced (scc, adr);
426     break;
427   default:
428     break;
429   }
430
431   return 0;
432 }
433
434 void
435 SCC_write (SCC * scc, uint32_t adr, uint32_t val)
436 {
437   val = val & 0xFF;
438
439   if( scc->type == SCC_ENHANCED && (adr&0xFFFE) == 0xBFFE ) 
440   {
441     scc->base_adr = 0x9000 | ((val&0x20)<<8);
442     return;
443   }
444   
445   if( adr < scc->base_adr ) return;
446   adr -= scc->base_adr;
447
448   if(adr == 0) 
449   {
450     if( val == 0x3F ) 
451     {
452       scc->mode = 0;
453       scc->active = 1;
454     }
455     else if( val&0x80 && scc->type == SCC_ENHANCED)
456     {
457       scc->mode = 1;
458       scc->active = 1;
459     }
460     else
461     {
462       scc->mode = 0;
463       scc->active = 0;
464     }
465     return;
466   }
467   
468   if(!scc->active||adr<0x800||0x8FF<adr) return;
469
470   switch (scc->type) 
471   {
472   case SCC_STANDARD:
473       write_standard (scc, adr, val);
474     break;
475   case SCC_ENHANCED:
476     if(scc->mode)
477       write_enhanced (scc, adr, val);
478     else 
479       write_standard (scc, adr, val);
480   default:
481     break;
482   }
483
484   return;
485 }
486
487 void
488 SCC_set_type (SCC * scc, uint32_t type)
489 {
490   scc->type = type;
491 }
492
493 #undef SCC
494
495 /*
496         Common Source Code Project
497         MSX Series (experimental)
498
499         Origin : emu2212
500         modified by umaiboux
501         Date   : 2016.04.xx-
502
503         [ SCC ]
504 */
505
506
507 SCC::SCC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu)
508 {
509         emu2212 = SCC_new(3579545, 48000);
510         volume_l = volume_r = 1024;
511         set_device_name(_T("SCC"));
512 }
513
514 void SCC::write_data8(uint32_t addr, uint32_t data)
515 {
516         SCC_write(emu2212, addr, data);
517 }
518
519 uint32_t SCC::read_data8(uint32_t addr)
520 {
521         return SCC_read(emu2212, addr);
522 }
523
524 void SCC::initialize()
525 {
526         SCC_set_type(emu2212, SCC_STANDARD);
527 }
528
529 void SCC::release()
530 {
531         SCC_delete(emu2212);
532 }
533
534 void SCC::reset()
535 {
536         SCC_reset(emu2212);
537 }
538
539 void SCC::mix(int32_t* buffer, int cnt)
540 {
541         int i;
542         for(i=0; i<cnt; i++) {
543                 int16_t c = (SCC_calc(emu2212)) << 1;
544                 buffer[i*2  ] += apply_volume(c, volume_l); // L
545                 buffer[i*2+1] += apply_volume(c, volume_r); // R
546         }
547 }
548
549 void SCC::initialize_sound(int rate, int clock, int samples)
550 {
551         this->release();
552         emu2212 = SCC_new(clock, rate);
553         this->reset();
554         this->initialize();
555 }
556
557 void SCC::set_volume(int ch, int decibel_l, int decibel_r)
558 {
559         volume_l = decibel_to_volume(decibel_l);
560         volume_r = decibel_to_volume(decibel_r);
561 }
562
563 #define STATE_VERSION   1
564
565 bool SCC::process_state(FILEIO* state_fio, bool loading)
566 {
567         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
568                 return false;
569         }
570         if(!state_fio->StateCheckInt32(this_device_id)) {
571                 return false;
572         }
573         save_load_state(state_fio, !loading);
574         return true;
575 }
576
577 #if 0
578 void SCC::decl_state_scc()
579 {
580         DECL_STATE_ENTRY_UINT32((emu2212->clk));
581     DECL_STATE_ENTRY_UINT32((emu2212->rate));
582         DECL_STATE_ENTRY_UINT32((emu2212->base_incr));
583         DECL_STATE_ENTRY_UINT32((emu2212->quality));
584
585         DECL_STATE_ENTRY_INT32((emu2212->out));
586         DECL_STATE_ENTRY_INT32((emu2212->prev));
587         DECL_STATE_ENTRY_INT32((emu2212->next));
588         DECL_STATE_ENTRY_UINT32((emu2212->type));
589         DECL_STATE_ENTRY_UINT32((emu2212->mode));
590         DECL_STATE_ENTRY_UINT32((emu2212->active));
591         DECL_STATE_ENTRY_UINT32((emu2212->base_adr));
592         DECL_STATE_ENTRY_UINT32((emu2212->mask));
593         
594         DECL_STATE_ENTRY_UINT32((emu2212->realstep));
595         DECL_STATE_ENTRY_UINT32((emu2212->scctime));
596         DECL_STATE_ENTRY_UINT32((emu2212->sccstep));
597         
598         DECL_STATE_ENTRY_1D_ARRAY(emu2212->incr, 5);
599
600         DECL_STATE_ENTRY_2D_ARRAY(emu2212->wave, 5, 32);
601
602         DECL_STATE_ENTRY_1D_ARRAY(emu2212->count, 5);
603         DECL_STATE_ENTRY_1D_ARRAY(emu2212->freq, 5);
604         DECL_STATE_ENTRY_1D_ARRAY(emu2212->phase, 5);
605         DECL_STATE_ENTRY_1D_ARRAY(emu2212->volume, 5);
606         DECL_STATE_ENTRY_1D_ARRAY(emu2212->offset, 5);
607         DECL_STATE_ENTRY_1D_ARRAY(emu2212->reg, 0x100-0xC0);
608
609         DECL_STATE_ENTRY_INT32((emu2212->ch_enable));
610         DECL_STATE_ENTRY_INT32((emu2212->ch_enable_next));
611
612         DECL_STATE_ENTRY_INT32((emu2212->cycle_4bit));
613         DECL_STATE_ENTRY_INT32((emu2212->cycle_8bit));
614         DECL_STATE_ENTRY_INT32((emu2212->refresh));
615         DECL_STATE_ENTRY_1D_ARRAY(emu2212->rotate, 5) ;
616 }
617 #endif
618
619 // ToDo: Dedicate endianness. 20181017 K.O.
620 void SCC::save_load_state(FILEIO* state_fio, bool is_save)
621 {
622 #define STATE_ENTRY(x) {&(x), sizeof(x)}
623         typedef struct {
624                 void *address;
625                 size_t size;
626         } t_state_table;
627         t_state_table state_table[] = {
628                 STATE_ENTRY(*emu2212),
629                 { NULL, 0 }
630         };
631         int i;
632         for(i=0; state_table[i].size>0; i++) {
633                 if (is_save) {
634                         state_fio->Fwrite(state_table[i].address, state_table[i].size, 1);
635                 }
636                 else {
637                         state_fio->Fread(state_table[i].address, state_table[i].size, 1);
638                 }
639         }
640         return;
641 }
642
643 }