sound.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. // This is part of Pico Library
  2. // (c) Copyright 2004 Dave, All rights reserved.
  3. // (c) Copyright 2006 notaz, All rights reserved.
  4. // Free for non-commercial use.
  5. // For commercial use, separate licencing terms must be obtained.
  6. #include <string.h>
  7. #include "ym2612.h"
  8. #include "sn76496.h"
  9. #if defined(_USE_MZ80)
  10. #include "../../cpu/mz80/mz80.h"
  11. #elif defined(_USE_DRZ80)
  12. #include "../../cpu/DrZ80/drz80.h"
  13. #elif defined(_USE_CZ80)
  14. #include "../../cpu/cz80/cz80.h"
  15. #endif
  16. #include "../PicoInt.h"
  17. #include "../cd/pcm.h"
  18. #include "mix.h"
  19. // master int buffer to mix to
  20. static int PsndBuffer[2*44100/50];
  21. // dac
  22. static unsigned short dac_info[312]; // pppppppp ppppllll, p - pos in buff, l - length to write for this sample
  23. // for Pico
  24. int PsndRate=0;
  25. int PsndLen=0; // number of mono samples, multiply by 2 for stereo
  26. int PsndLen_exc_add=0; // this is for non-integer sample counts per line, eg. 22050/60
  27. int PsndLen_exc_cnt=0;
  28. short *PsndOut=NULL; // PCM data buffer
  29. // from ym2612.c
  30. extern int *ym2612_dacen;
  31. extern INT32 *ym2612_dacout;
  32. void YM2612TimerHandler(int c,int cnt);
  33. // sn76496
  34. extern int *sn76496_regs;
  35. static void dac_recalculate(void)
  36. {
  37. int i, dac_cnt, pos, len, lines = Pico.m.pal ? 312 : 262, mid = Pico.m.pal ? 68 : 93;
  38. if(PsndLen <= lines) {
  39. // shrinking algo
  40. dac_cnt = -PsndLen;
  41. len=1; pos=0;
  42. dac_info[225] = 1;
  43. for(i=226; i != 225; i++) {
  44. if (i >= lines) i = 0;
  45. len = 0;
  46. if(dac_cnt < 0) {
  47. len=1;
  48. pos++;
  49. dac_cnt += lines;
  50. }
  51. dac_cnt -= PsndLen;
  52. dac_info[i] = (pos<<4)|len;
  53. }
  54. } else {
  55. // stretching
  56. dac_cnt = PsndLen;
  57. pos=0;
  58. for(i = 225; i != 224; i++) {
  59. if (i >= lines) i = 0;
  60. len=0;
  61. while(dac_cnt >= 0) {
  62. dac_cnt -= lines;
  63. len++;
  64. }
  65. if (i == mid) // midpoint
  66. while(pos+len < PsndLen/2) {
  67. dac_cnt -= lines;
  68. len++;
  69. }
  70. dac_cnt += PsndLen;
  71. dac_info[i] = (pos<<4)|len;
  72. pos+=len;
  73. }
  74. // last sample
  75. for(len = 0, i = pos; i < PsndLen; i++) len++;
  76. if (PsndLen_exc_add) len++;
  77. dac_info[224] = (pos<<4)|len;
  78. }
  79. //for(i=len=0; i < lines; i++) {
  80. // printf("%03i : %03i : %i\n", i, dac_info[i]>>4, dac_info[i]&0xf);
  81. // len+=dac_info[i]&0xf;
  82. //}
  83. //printf("rate is %i, len %f\n", PsndRate, (double)PsndRate/(Pico.m.pal ? 50.0 : 60.0));
  84. //printf("len total: %i, last pos: %i\n", len, pos);
  85. //exit(8);
  86. }
  87. PICO_INTERNAL void PsndReset(void)
  88. {
  89. void *ym2612_regs;
  90. // also clear the internal registers+addr line
  91. ym2612_regs = YM2612GetRegs();
  92. memset(ym2612_regs, 0, 0x200+4);
  93. z80startCycle = z80stopCycle = 0;
  94. PsndRerate(0);
  95. }
  96. // to be called after changing sound rate or chips
  97. void PsndRerate(int preserve_state)
  98. {
  99. void *state = NULL;
  100. int target_fps = Pico.m.pal ? 50 : 60;
  101. // not all rates are supported in MCD mode due to mp3 decoder limitations
  102. if (PicoMCD & 1) {
  103. if (PsndRate != 11025 && PsndRate != 22050 && PsndRate != 44100) PsndRate = 22050;
  104. PicoOpt |= 8; // force stereo
  105. }
  106. if (preserve_state) {
  107. state = malloc(0x200);
  108. if (state == NULL) return;
  109. memcpy(state, YM2612GetRegs(), 0x200);
  110. if ((PicoMCD & 1) && Pico_mcd->m.audio_track)
  111. Pico_mcd->m.audio_offset = mp3_get_offset();
  112. }
  113. YM2612Init(Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7, PsndRate);
  114. if (preserve_state) {
  115. // feed it back it's own registers, just like after loading state
  116. memcpy(YM2612GetRegs(), state, 0x200);
  117. YM2612PicoStateLoad();
  118. if ((PicoMCD & 1) && Pico_mcd->m.audio_track)
  119. mp3_start_play(Pico_mcd->TOC.Tracks[Pico_mcd->m.audio_track].F, Pico_mcd->m.audio_offset);
  120. }
  121. if (preserve_state) memcpy(state, sn76496_regs, 28*4); // remember old state
  122. SN76496_init(Pico.m.pal ? OSC_PAL/15 : OSC_NTSC/15, PsndRate);
  123. if (preserve_state) memcpy(sn76496_regs, state, 28*4); // restore old state
  124. if (state)
  125. free(state);
  126. // calculate PsndLen
  127. PsndLen=PsndRate / target_fps;
  128. PsndLen_exc_add=((PsndRate - PsndLen*target_fps)<<16) / target_fps;
  129. PsndLen_exc_cnt=0;
  130. // recalculate dac info
  131. dac_recalculate();
  132. if (PicoMCD & 1)
  133. pcm_set_rate(PsndRate);
  134. // clear all buffers
  135. memset32(PsndBuffer, 0, sizeof(PsndBuffer)/4);
  136. if (PsndOut)
  137. PsndClear();
  138. }
  139. // This is called once per raster (aka line), but not necessarily for every line
  140. PICO_INTERNAL void Psnd_timers_and_dac(int raster)
  141. {
  142. int pos, len;
  143. int do_dac = PsndOut && (PicoOpt&1) && *ym2612_dacen;
  144. // int do_pcm = PsndOut && (PicoMCD&1) && (PicoOpt&0x400);
  145. // Our raster lasts 63.61323/64.102564 microseconds (NTSC/PAL)
  146. YM2612PicoTick(1);
  147. if (!do_dac /*&& !do_pcm*/) return;
  148. pos=dac_info[raster], len=pos&0xf;
  149. if (!len) return;
  150. pos>>=4;
  151. if (do_dac) {
  152. short *d = PsndOut + pos*2;
  153. int dout = *ym2612_dacout;
  154. if(PicoOpt&8) {
  155. // some manual loop unrolling here :)
  156. d[0] = dout;
  157. if (len > 1) {
  158. d[2] = dout;
  159. if (len > 2)
  160. d[4] = dout;
  161. }
  162. } else {
  163. short *d = PsndOut + pos;
  164. d[0] = dout;
  165. if (len > 1) {
  166. d[1] = dout;
  167. if (len > 2)
  168. d[2] = dout;
  169. }
  170. }
  171. }
  172. #if 0
  173. if (do_pcm) {
  174. int *d = PsndBuffer;
  175. d += (PicoOpt&8) ? pos*2 : pos;
  176. pcm_update(d, len, 1);
  177. }
  178. #endif
  179. }
  180. PICO_INTERNAL void PsndClear(void)
  181. {
  182. int len = PsndLen;
  183. if (PsndLen_exc_add) len++;
  184. if (PicoOpt & 8) memset32((int *) PsndOut, 0, len); // clear both channels at once
  185. else memset(PsndOut, 0, len<<1);
  186. }
  187. PICO_INTERNAL int PsndRender(int offset, int length)
  188. {
  189. int buf32_updated = 0;
  190. int *buf32 = PsndBuffer+offset;
  191. int stereo = (PicoOpt & 8) >> 3;
  192. // emulating CD && PCM option enabled && PCM chip on && have enabled channels
  193. int do_pcm = (PicoMCD&1) && (PicoOpt&0x400) && (Pico_mcd->pcm.control & 0x80) && Pico_mcd->pcm.enabled;
  194. offset <<= stereo;
  195. if (offset == 0) { // should happen once per frame
  196. // compensate for float part of PsndLen
  197. PsndLen_exc_cnt += PsndLen_exc_add;
  198. if (PsndLen_exc_cnt >= 0x10000) {
  199. PsndLen_exc_cnt -= 0x10000;
  200. length++;
  201. }
  202. }
  203. // PSG
  204. if (PicoOpt & 2)
  205. SN76496Update(PsndOut+offset, length, stereo);
  206. // Add in the stereo FM buffer
  207. if (PicoOpt & 1) {
  208. buf32_updated = YM2612UpdateOne(buf32, length, stereo, 1);
  209. } else
  210. memset32(buf32, 0, length<<stereo);
  211. //printf("active_chs: %02x\n", buf32_updated);
  212. // CD: PCM sound
  213. if (do_pcm) {
  214. pcm_update(buf32, length, stereo);
  215. //buf32_updated = 1;
  216. }
  217. // CD: CDDA audio
  218. // CD mode, cdda enabled, not data track, CDC is reading
  219. if ((PicoMCD & 1) && (PicoOpt & 0x800) && !(Pico_mcd->s68k_regs[0x36] & 1) && (Pico_mcd->scd.Status_CDC & 1))
  220. mp3_update(buf32, length, stereo);
  221. // convert + limit to normal 16bit output
  222. if (stereo)
  223. mix_32_to_16l_stereo(PsndOut+offset, buf32, length);
  224. else mix_32_to_16_mono (PsndOut+offset, buf32, length);
  225. return length;
  226. }
  227. #if defined(_USE_MZ80)
  228. // memhandlers for mz80 core
  229. unsigned char mz80_read(UINT32 a, struct MemoryReadByte *w) { return z80_read(a); }
  230. void mz80_write(UINT32 a, UINT8 d, struct MemoryWriteByte *w) { z80_write(d, a); }
  231. // structures for mz80 core
  232. static struct MemoryReadByte mz80_mem_read[]=
  233. {
  234. {0x0000,0xffff,mz80_read},
  235. {(UINT32) -1,(UINT32) -1,NULL}
  236. };
  237. static struct MemoryWriteByte mz80_mem_write[]=
  238. {
  239. {0x0000,0xffff,mz80_write},
  240. {(UINT32) -1,(UINT32) -1,NULL}
  241. };
  242. static struct z80PortRead mz80_io_read[] ={
  243. {(UINT16) -1,(UINT16) -1,NULL}
  244. };
  245. static struct z80PortWrite mz80_io_write[]={
  246. {(UINT16) -1,(UINT16) -1,NULL}
  247. };
  248. #elif defined(_USE_DRZ80)
  249. static struct DrZ80 drZ80;
  250. static unsigned int DrZ80_rebasePC(unsigned short a)
  251. {
  252. drZ80.Z80PC_BASE = (unsigned int) Pico.zram;
  253. return drZ80.Z80PC_BASE + a;
  254. }
  255. static unsigned int DrZ80_rebaseSP(unsigned short a)
  256. {
  257. drZ80.Z80SP_BASE = (unsigned int) Pico.zram;
  258. return drZ80.Z80SP_BASE + a;
  259. }
  260. static void DrZ80_irq_callback()
  261. {
  262. drZ80.Z80_IRQ = 0; // lower irq when accepted
  263. }
  264. #endif
  265. #if defined(_USE_DRZ80) || defined(_USE_CZ80)
  266. static unsigned char z80_in(unsigned short p)
  267. {
  268. elprintf(EL_ANOMALY, "Z80 port %04x read", p);
  269. return 0xff;
  270. }
  271. static void z80_out(unsigned short p,unsigned char d)
  272. {
  273. elprintf(EL_ANOMALY, "Z80 port %04x write %02x", p, d);
  274. }
  275. #endif
  276. // z80 functionality wrappers
  277. PICO_INTERNAL void z80_init(void)
  278. {
  279. #if defined(_USE_MZ80)
  280. struct mz80context z80;
  281. // z80
  282. mz80init();
  283. // Modify the default context
  284. mz80GetContext(&z80);
  285. // point mz80 stuff
  286. z80.z80Base=Pico.zram;
  287. z80.z80MemRead=mz80_mem_read;
  288. z80.z80MemWrite=mz80_mem_write;
  289. z80.z80IoRead=mz80_io_read;
  290. z80.z80IoWrite=mz80_io_write;
  291. mz80SetContext(&z80);
  292. #elif defined(_USE_DRZ80)
  293. memset(&drZ80, 0, sizeof(struct DrZ80));
  294. drZ80.z80_rebasePC=DrZ80_rebasePC;
  295. drZ80.z80_rebaseSP=DrZ80_rebaseSP;
  296. drZ80.z80_read8 =z80_read;
  297. drZ80.z80_read16 =z80_read16;
  298. drZ80.z80_write8 =z80_write;
  299. drZ80.z80_write16 =z80_write16;
  300. drZ80.z80_in =z80_in;
  301. drZ80.z80_out =z80_out;
  302. drZ80.z80_irq_callback=DrZ80_irq_callback;
  303. #elif defined(_USE_CZ80)
  304. memset(&CZ80, 0, sizeof(CZ80));
  305. Cz80_Init(&CZ80);
  306. Cz80_Set_Fetch(&CZ80, 0x0000, 0x1fff, (UINT32)Pico.zram); // main RAM
  307. Cz80_Set_Fetch(&CZ80, 0x2000, 0x3fff, (UINT32)Pico.zram - 0x2000); // mirror
  308. Cz80_Set_ReadB(&CZ80, (UINT8 (*)(UINT32 address))z80_read);
  309. Cz80_Set_WriteB(&CZ80, z80_write);
  310. Cz80_Set_INPort(&CZ80, z80_in);
  311. Cz80_Set_OUTPort(&CZ80, z80_out);
  312. #endif
  313. }
  314. PICO_INTERNAL void z80_reset(void)
  315. {
  316. #if defined(_USE_MZ80)
  317. mz80reset();
  318. #elif defined(_USE_DRZ80)
  319. memset(&drZ80, 0, 0x54);
  320. drZ80.Z80F = (1<<2); // set ZFlag
  321. drZ80.Z80F2 = (1<<2); // set ZFlag
  322. drZ80.Z80IX = 0xFFFF << 16;
  323. drZ80.Z80IY = 0xFFFF << 16;
  324. drZ80.Z80IM = 0; // 1?
  325. drZ80.Z80PC = drZ80.z80_rebasePC(0);
  326. drZ80.Z80SP = drZ80.z80_rebaseSP(0x2000); // 0xf000 ?
  327. #elif defined(_USE_CZ80)
  328. Cz80_Reset(&CZ80);
  329. #endif
  330. Pico.m.z80_fakeval = 0; // for faking when Z80 is disabled
  331. }
  332. PICO_INTERNAL void z80_resetCycles(void)
  333. {
  334. #if defined(_USE_MZ80)
  335. mz80GetElapsedTicks(1);
  336. #endif
  337. }
  338. PICO_INTERNAL void z80_int(void)
  339. {
  340. #if defined(_USE_MZ80)
  341. mz80int(0);
  342. #elif defined(_USE_DRZ80)
  343. drZ80.z80irqvector = 0xFF; // default IRQ vector RST opcode
  344. drZ80.Z80_IRQ = 1;
  345. #elif defined(_USE_CZ80)
  346. Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE);
  347. #endif
  348. }
  349. // returns number of cycles actually executed
  350. PICO_INTERNAL int z80_run(int cycles)
  351. {
  352. #if defined(_USE_MZ80)
  353. int ticks_pre = mz80GetElapsedTicks(0);
  354. mz80exec(cycles);
  355. return mz80GetElapsedTicks(0) - ticks_pre;
  356. #elif defined(_USE_DRZ80)
  357. return cycles - DrZ80Run(&drZ80, cycles);
  358. #elif defined(_USE_CZ80)
  359. return Cz80_Exec(&CZ80, cycles);
  360. #else
  361. return cycles;
  362. #endif
  363. }
  364. PICO_INTERNAL void z80_pack(unsigned char *data)
  365. {
  366. #if defined(_USE_MZ80)
  367. struct mz80context mz80;
  368. *(int *)data = 0x00005A6D; // "mZ"
  369. mz80GetContext(&mz80);
  370. memcpy(data+4, &mz80.z80clockticks, sizeof(mz80)-5*4); // don't save base&memhandlers
  371. #elif defined(_USE_DRZ80)
  372. *(int *)data = 0x015A7244; // "DrZ" v1
  373. drZ80.Z80PC = drZ80.z80_rebasePC(drZ80.Z80PC-drZ80.Z80PC_BASE);
  374. drZ80.Z80SP = drZ80.z80_rebaseSP(drZ80.Z80SP-drZ80.Z80SP_BASE);
  375. memcpy(data+4, &drZ80, 0x54);
  376. #elif defined(_USE_CZ80)
  377. *(int *)data = 0x00007a43; // "Cz"
  378. *(int *)(data+4) = Cz80_Get_Reg(&CZ80, CZ80_PC);
  379. memcpy(data+8, &CZ80, (INT32)&CZ80.BasePC - (INT32)&CZ80);
  380. #endif
  381. }
  382. PICO_INTERNAL void z80_unpack(unsigned char *data)
  383. {
  384. #if defined(_USE_MZ80)
  385. if (*(int *)data == 0x00005A6D) { // "mZ" save?
  386. struct mz80context mz80;
  387. mz80GetContext(&mz80);
  388. memcpy(&mz80.z80clockticks, data+4, sizeof(mz80)-5*4);
  389. mz80SetContext(&mz80);
  390. } else {
  391. z80_reset();
  392. z80_int();
  393. }
  394. #elif defined(_USE_DRZ80)
  395. if (*(int *)data == 0x015A7244) { // "DrZ" v1 save?
  396. memcpy(&drZ80, data+4, 0x54);
  397. // update bases
  398. drZ80.Z80PC = drZ80.z80_rebasePC(drZ80.Z80PC-drZ80.Z80PC_BASE);
  399. drZ80.Z80SP = drZ80.z80_rebaseSP(drZ80.Z80SP-drZ80.Z80SP_BASE);
  400. } else {
  401. z80_reset();
  402. drZ80.Z80IM = 1;
  403. z80_int(); // try to goto int handler, maybe we won't execute trash there?
  404. }
  405. #elif defined(_USE_CZ80)
  406. if (*(int *)data == 0x00007a43) { // "Cz" save?
  407. memcpy(&CZ80, data+8, (INT32)&CZ80.BasePC - (INT32)&CZ80);
  408. Cz80_Set_Reg(&CZ80, CZ80_PC, *(int *)(data+4));
  409. } else {
  410. z80_reset();
  411. z80_int();
  412. }
  413. #endif
  414. }
  415. PICO_INTERNAL void z80_exit(void)
  416. {
  417. #if defined(_USE_MZ80)
  418. mz80shutdown();
  419. #endif
  420. }
  421. #if 1 // defined(__DEBUG_PRINT) || defined(__GP2X__) || defined(__GIZ__)
  422. PICO_INTERNAL void z80_debug(char *dstr)
  423. {
  424. #if defined(_USE_DRZ80)
  425. sprintf(dstr, "Z80 state: PC: %04x SP: %04x\n", drZ80.Z80PC-drZ80.Z80PC_BASE, drZ80.Z80SP-drZ80.Z80SP_BASE);
  426. #elif defined(_USE_CZ80)
  427. sprintf(dstr, "Z80 state: PC: %04x SP: %04x\n", CZ80.PC - CZ80.BasePC, CZ80.SP.W);
  428. #endif
  429. }
  430. #endif