DOSBox-X
|
00001 #include "np2glue.h" 00002 //#include "compiler.h" 00003 #include "sound.h" 00004 #include "opngen.h" 00005 #include "adpcm.h" 00006 00007 00008 ADPCMCFG adpcmcfg; 00009 00010 void adpcm_initialize(UINT rate) { 00011 00012 adpcmcfg.rate = rate; 00013 } 00014 00015 void adpcm_setvol(UINT vol) { 00016 00017 adpcmcfg.vol = vol; 00018 } 00019 00020 void adpcm_reset(ADPCM ad) { 00021 00022 ZeroMemory(ad, sizeof(_ADPCM)); 00023 ad->mask = 0; // (UINT8)~0x1c; 00024 ad->delta = 127; 00025 STOREINTELWORD(ad->reg.stop, 0x0002); 00026 STOREINTELWORD(ad->reg.limit, 0xffff); 00027 ad->stop = 0x000060; 00028 ad->limit = 0x200000; 00029 adpcm_update(ad); 00030 } 00031 00032 void adpcm_update(ADPCM ad) { 00033 00034 UINT32 addr; 00035 00036 if (adpcmcfg.rate) { 00037 ad->base = ADTIMING * (OPNA_CLOCK / 72) / adpcmcfg.rate; 00038 } 00039 addr = LOADINTELWORD(ad->reg.delta); 00040 addr = (addr * ad->base) >> 16; 00041 if (addr < 0x80) { 00042 addr = 0x80; 00043 } 00044 ad->step = addr; 00045 ad->pertim = (1 << (ADTIMING_BIT * 2)) / addr; 00046 ad->level = (ad->reg.level * adpcmcfg.vol) >> 4; 00047 } 00048 00049 void adpcm_setreg(ADPCM ad, UINT reg, REG8 value) { 00050 00051 UINT32 addr; 00052 00053 sound_sync(); 00054 ((UINT8 *)(&ad->reg))[reg] = value; 00055 switch(reg) { 00056 case 0x00: // control1 00057 if ((value & 0x80) && (!ad->play)) { 00058 ad->play = 0x20; 00059 ad->pos = ad->start; 00060 ad->samp = 0; 00061 ad->delta = 127; 00062 ad->remain = 0; 00063 } 00064 if (value & 1) { 00065 ad->play = 0; 00066 } 00067 break; 00068 00069 case 0x01: // control2 00070 break; 00071 00072 case 0x02: case 0x03: // start address 00073 addr = (LOADINTELWORD(ad->reg.start)) << 5; 00074 ad->pos = addr; 00075 ad->start = addr; 00076 break; 00077 00078 case 0x04: case 0x05: // stop address 00079 addr = (LOADINTELWORD(ad->reg.stop) + 1) << 5; 00080 ad->stop = addr; 00081 break; 00082 00083 case 0x08: // data 00084 if ((ad->reg.ctrl1 & 0x60) == 0x60) { 00085 adpcm_datawrite(ad, value); 00086 } 00087 break; 00088 00089 case 0x09: case 0x0a: // delta 00090 addr = LOADINTELWORD(ad->reg.delta); 00091 addr = (addr * ad->base) >> 16; 00092 if (addr < 0x80) { 00093 addr = 0x80; 00094 } 00095 ad->step = addr; 00096 ad->pertim = (1 << (ADTIMING_BIT * 2)) / addr; 00097 break; 00098 00099 case 0x0b: // level 00100 ad->level = (value * adpcmcfg.vol) >> 4; 00101 break; 00102 00103 case 0x0c: case 0x0d: // limit address 00104 addr = (LOADINTELWORD(ad->reg.limit) + 1) << 5; 00105 ad->limit = addr; 00106 break; 00107 00108 case 0x10: // flag 00109 if (value & 0x80) { 00110 ad->status = 0; 00111 } 00112 else { 00113 ad->mask = ~(value & 0x1f); 00114 } 00115 break; 00116 } 00117 } 00118 00119 REG8 adpcm_status(ADPCM ad) { 00120 00121 return(((ad->status | 8) & ad->mask) | ad->play); 00122 } 00123