asap.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:22k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * asap.c - ASAP engine
  3.  *
  4.  * Copyright (C) 2005-2006  Piotr Fusik
  5.  *
  6.  * This file is part of ASAP (Another Slight Atari Player),
  7.  * see http://asap.sourceforge.net
  8.  *
  9.  * ASAP is free software; you can redistribute it and/or modify it
  10.  * under the terms of the GNU General Public License as published
  11.  * by the Free Software Foundation; either version 2 of the License,
  12.  * or (at your option) any later version.
  13.  *
  14.  * ASAP is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty
  16.  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17.  * See the GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with ASAP; if not, write to the Free Software Foundation, Inc.,
  21.  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  22.  */
  23. #include "config.h"
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include "asap.h"
  27. #include "asap_internal.h"
  28. #include "cpu.h"
  29. #include "pokey.h"
  30. #include "pokeysnd.h"
  31. #include "players.h"
  32. #define CMR_BASS_TABLE_OFFSET  0x70f
  33. static const unsigned char cmr_bass_table[] = {
  34. 0x5C, 0x56, 0x50, 0x4D, 0x47, 0x44, 0x41, 0x3E,
  35. 0x38, 0x35, 0x88, 0x7F, 0x79, 0x73, 0x6C, 0x67,
  36. 0x60, 0x5A, 0x55, 0x51, 0x4C, 0x48, 0x43, 0x3F,
  37. 0x3D, 0x39, 0x34, 0x33, 0x30, 0x2D, 0x2A, 0x28,
  38. 0x25, 0x24, 0x21, 0x1F, 0x1E
  39. };
  40. /* main clock in Hz, PAL (FREQ_17_EXACT is for NTSC!) */
  41. #define ASAP_MAIN_CLOCK  1773447U
  42. UBYTE memory[65536 + 2];
  43. int xpos = 0;
  44. int xpos_limit = 0;
  45. UBYTE wsync_halt = 0;
  46. /* structures to hold the 9 pokey control bytes */
  47. UBYTE AUDF[4 * MAXPOKEYS]; /* AUDFx (D200, D202, D204, D206) */
  48. UBYTE AUDC[4 * MAXPOKEYS]; /* AUDCx (D201, D203, D205, D207) */
  49. UBYTE AUDCTL[MAXPOKEYS]; /* AUDCTL (D208) */
  50. int Base_mult[MAXPOKEYS]; /* selects either 64Khz or 15Khz clock mult */
  51. UBYTE poly9_lookup[511];
  52. UBYTE poly17_lookup[16385];
  53. static ULONG random_scanline_counter;
  54. static unsigned int enable_stereo = 0;
  55. #ifndef SOUND_GAIN /* sound gain can be pre-defined in the configure/Makefile */
  56. #define SOUND_GAIN 4
  57. #endif
  58. static void POKEY_PutByte(UWORD addr, UBYTE byte)
  59. {
  60. #ifdef STEREO_SOUND
  61. addr &= enable_stereo ? 0x1f : 0x0f;
  62. #else
  63. addr &= 0x0f;
  64. #endif
  65. switch (addr) {
  66. case _AUDC1:
  67. AUDC[CHAN1] = byte;
  68. Update_pokey_sound(_AUDC1, byte, 0, SOUND_GAIN);
  69. break;
  70. case _AUDC2:
  71. AUDC[CHAN2] = byte;
  72. Update_pokey_sound(_AUDC2, byte, 0, SOUND_GAIN);
  73. break;
  74. case _AUDC3:
  75. AUDC[CHAN3] = byte;
  76. Update_pokey_sound(_AUDC3, byte, 0, SOUND_GAIN);
  77. break;
  78. case _AUDC4:
  79. AUDC[CHAN4] = byte;
  80. Update_pokey_sound(_AUDC4, byte, 0, SOUND_GAIN);
  81. break;
  82. case _AUDCTL:
  83. AUDCTL[0] = byte;
  84. /* determine the base multiplier for the 'div by n' calculations */
  85. if (byte & CLOCK_15)
  86. Base_mult[0] = DIV_15;
  87. else
  88. Base_mult[0] = DIV_64;
  89. Update_pokey_sound(_AUDCTL, byte, 0, SOUND_GAIN);
  90. break;
  91. case _AUDF1:
  92. AUDF[CHAN1] = byte;
  93. Update_pokey_sound(_AUDF1, byte, 0, SOUND_GAIN);
  94. break;
  95. case _AUDF2:
  96. AUDF[CHAN2] = byte;
  97. Update_pokey_sound(_AUDF2, byte, 0, SOUND_GAIN);
  98. break;
  99. case _AUDF3:
  100. AUDF[CHAN3] = byte;
  101. Update_pokey_sound(_AUDF3, byte, 0, SOUND_GAIN);
  102. break;
  103. case _AUDF4:
  104. AUDF[CHAN4] = byte;
  105. Update_pokey_sound(_AUDF4, byte, 0, SOUND_GAIN);
  106. break;
  107. case _STIMER:
  108. Update_pokey_sound(_STIMER, byte, 0, SOUND_GAIN);
  109. break;
  110. #ifdef STEREO_SOUND
  111. case _AUDC1 + _POKEY2:
  112. AUDC[CHAN1 + CHIP2] = byte;
  113. Update_pokey_sound(_AUDC1, byte, 1, SOUND_GAIN);
  114. break;
  115. case _AUDC2 + _POKEY2:
  116. AUDC[CHAN2 + CHIP2] = byte;
  117. Update_pokey_sound(_AUDC2, byte, 1, SOUND_GAIN);
  118. break;
  119. case _AUDC3 + _POKEY2:
  120. AUDC[CHAN3 + CHIP2] = byte;
  121. Update_pokey_sound(_AUDC3, byte, 1, SOUND_GAIN);
  122. break;
  123. case _AUDC4 + _POKEY2:
  124. AUDC[CHAN4 + CHIP2] = byte;
  125. Update_pokey_sound(_AUDC4, byte, 1, SOUND_GAIN);
  126. break;
  127. case _AUDCTL + _POKEY2:
  128. AUDCTL[1] = byte;
  129. /* determine the base multiplier for the 'div by n' calculations */
  130. if (byte & CLOCK_15)
  131. Base_mult[1] = DIV_15;
  132. else
  133. Base_mult[1] = DIV_64;
  134. Update_pokey_sound(_AUDCTL, byte, 1, SOUND_GAIN);
  135. break;
  136. case _AUDF1 + _POKEY2:
  137. AUDF[CHAN1 + CHIP2] = byte;
  138. Update_pokey_sound(_AUDF1, byte, 1, SOUND_GAIN);
  139. break;
  140. case _AUDF2 + _POKEY2:
  141. AUDF[CHAN2 + CHIP2] = byte;
  142. Update_pokey_sound(_AUDF2, byte, 1, SOUND_GAIN);
  143. break;
  144. case _AUDF3 + _POKEY2:
  145. AUDF[CHAN3 + CHIP2] = byte;
  146. Update_pokey_sound(_AUDF3, byte, 1, SOUND_GAIN);
  147. break;
  148. case _AUDF4 + _POKEY2:
  149. AUDF[CHAN4 + CHIP2] = byte;
  150. Update_pokey_sound(_AUDF4, byte, 1, SOUND_GAIN);
  151. break;
  152. case _STIMER + _POKEY2:
  153. Update_pokey_sound(_STIMER, byte, 1, SOUND_GAIN);
  154. break;
  155. #endif
  156. default:
  157. break;
  158. }
  159. }
  160. static void POKEY_Initialise(void)
  161. {
  162. int i;
  163. ULONG reg;
  164. for (i = 0; i < (MAXPOKEYS * 4); i++) {
  165. AUDC[i] = 0;
  166. AUDF[i] = 0;
  167. }
  168. for (i = 0; i < MAXPOKEYS; i++) {
  169. AUDCTL[i] = 0;
  170. Base_mult[i] = DIV_64;
  171. }
  172. /* initialise poly9_lookup */
  173. reg = 0x1ff;
  174. for (i = 0; i < 511; i++) {
  175. reg = ((((reg >> 5) ^ reg) & 1) << 8) + (reg >> 1);
  176. poly9_lookup[i] = (UBYTE) reg;
  177. }
  178. /* initialise poly17_lookup */
  179. reg = 0x1ffff;
  180. for (i = 0; i < 16385; i++) {
  181. reg = ((((reg >> 5) ^ reg) & 0xff) << 9) + (reg >> 8);
  182. poly17_lookup[i] = (UBYTE) (reg >> 1);
  183. }
  184. random_scanline_counter = 0;
  185. }
  186. UBYTE ASAP_GetByte(UWORD addr)
  187. {
  188. unsigned int i;
  189. switch (addr & 0xff0f) {
  190. case 0xd20a:
  191. i = random_scanline_counter + (unsigned int) xpos + (unsigned int) xpos / LINE_C * DMAR;
  192. if (AUDCTL[0] & POLY9)
  193. return poly9_lookup[i % POLY9_SIZE];
  194. else {
  195. const UBYTE *ptr;
  196. i %= POLY17_SIZE;
  197. ptr = poly17_lookup + (i >> 3);
  198. i &= 7;
  199. return (UBYTE) ((ptr[0] >> i) + (ptr[1] << (8 - i)));
  200. }
  201. case 0xd40b:
  202. return (UBYTE) ((unsigned int) xpos / (unsigned int) (2 * (LINE_C - DMAR)) % 156U);
  203. default:
  204. return dGetByte(addr);
  205. }
  206. }
  207. void ASAP_PutByte(UWORD addr, UBYTE byte)
  208. {
  209. /* TODO: implement WSYNC */
  210. #if 0
  211. if ((addr >> 8) == 0xd2)
  212. POKEY_PutByte(addr, byte);
  213. else if ((addr & 0xff0f) == 0xd40a) {
  214. if (xpos <= WSYNC_C && xpos_limit >= WSYNC_C)
  215. xpos = WSYNC_C;
  216. else {
  217. wsync_halt = TRUE;
  218. xpos = xpos_limit;
  219. }
  220. }
  221. else
  222. dPutByte(addr, byte);
  223. #else
  224. POKEY_PutByte(addr, byte);
  225. #endif
  226. }
  227. /* We use CIM opcode to return from a subroutine to ASAP */
  228. void ASAP_CIM(void)
  229. {
  230. xpos = xpos_limit;
  231. }
  232. static unsigned int block_rate;
  233. static unsigned int sample_format;
  234. static unsigned int sample_16bit;
  235. void ASAP_Initialize(unsigned int frequency, unsigned int audio_format, unsigned int quality)
  236. {
  237. block_rate = frequency;
  238. sample_format = audio_format;
  239. sample_16bit = audio_format == AUDIO_FORMAT_U8 ? 0 : 1;
  240. enable_stereo = 5; /* force Pokey_sound_init() in ASAP_PlaySong() */
  241. POKEY_Initialise();
  242. if (quality == 0)
  243. enable_new_pokey = FALSE;
  244. else {
  245. Pokey_set_mzquality(quality - 1);
  246. enable_new_pokey = TRUE;
  247. }
  248. }
  249. static char sap_type;
  250. static UWORD sap_player;
  251. static UWORD sap_music;
  252. static UWORD sap_init;
  253. static unsigned int sap_stereo;
  254. static unsigned int sap_songs;
  255. static unsigned int sap_defsong;
  256. static unsigned int sap_fastplay;
  257. /* This array maps subsong numbers to track positions for MPT and RMT formats. */
  258. static UBYTE song_pos[128];
  259. static unsigned int tmc_per_frame;
  260. static unsigned int tmc_per_frame_counter;
  261. static unsigned int blockclocks;
  262. static unsigned int blockclocks_per_player;
  263. static const unsigned int perframe2fastplay[] = { 312U, 312U / 2U, 312U / 3U, 312U / 4U };
  264. static int load_native(const unsigned char *module, unsigned int module_len,
  265.                        const unsigned char *player, char type)
  266. {
  267. UWORD player_last_byte;
  268. int block_len;
  269. if (module[0] != 0xff || module[1] != 0xff)
  270. return FALSE;
  271. sap_player = player[2] + (player[3] << 8);
  272. player_last_byte = player[4] + (player[5] << 8);
  273. sap_music = module[2] + (module[3] << 8);
  274. if (sap_music <= player_last_byte)
  275. return FALSE;
  276. block_len = module[4] + (module[5] << 8) + 1 - sap_music;
  277. if ((unsigned int) (6 + block_len) != module_len) {
  278. UWORD info_addr;
  279. int info_len;
  280. if (type != 'r' || (unsigned int) (11 + block_len) > module_len)
  281. return FALSE;
  282. /* allow optional info for Raster Music Tracker */
  283. info_addr = module[6 + block_len] + (module[7 + block_len] << 8);
  284. if (info_addr != sap_music + block_len)
  285. return FALSE;
  286. info_len = module[8 + block_len] + (module[9 + block_len] << 8) + 1 - info_addr;
  287. if ((unsigned int) (10 + block_len + info_len) != module_len)
  288. return FALSE;
  289. }
  290. memcpy(memory + sap_music, module + 6, block_len);
  291. memcpy(memory + sap_player, player + 6, player_last_byte + 1 - sap_player);
  292. sap_type = type;
  293. return TRUE;
  294. }
  295. static int load_cmc(const unsigned char *module, unsigned int module_len, int cmr)
  296. {
  297. int pos;
  298. if (module_len < 0x300)
  299. return FALSE;
  300. if (!load_native(module, module_len, cmc_obx, 'C'))
  301. return FALSE;
  302. if (cmr)
  303. memcpy(memory + 0x500 + CMR_BASS_TABLE_OFFSET, cmr_bass_table, sizeof(cmr_bass_table));
  304. /* auto-detect number of subsongs */
  305. pos = 0x54;
  306. while (--pos >= 0) {
  307. if (module[0x206 + pos] < 0xfe
  308.  || module[0x25b + pos] < 0xfe
  309.  || module[0x2b0 + pos] < 0xfe)
  310. break;
  311. }
  312. while (--pos >= 0) {
  313. if (module[0x206 + pos] == 0x8f || module[0x206 + pos] == 0xef)
  314. sap_songs++;
  315. }
  316. return TRUE;
  317. }
  318. static int load_mpt(const unsigned char *module, unsigned int module_len)
  319. {
  320. unsigned int i;
  321. unsigned int song_len;
  322. /* seen[i] == TRUE if the track position i is already processed */
  323. UBYTE seen[256];
  324. if (module_len < 0x1d0)
  325. return FALSE;
  326. if (!load_native(module, module_len, mpt_obx, 'm'))
  327. return FALSE;
  328. /* do not auto-detect number of subsongs if the address
  329.    of the first track is non-standard */
  330. if (module[0x1c6] + (module[0x1ca] << 8) != sap_music + 0x1ca) {
  331. song_pos[0] = 0;
  332. return TRUE;
  333. }
  334. /* Calculate the length of the first track. Address of the second track minus
  335.    address of the first track equals the length of the first track in bytes.
  336.    Divide by two to get number of track positions. */
  337. song_len = (module[0x1c7] + (module[0x1cb] << 8) - sap_music - 0x1ca) >> 1;
  338. if (song_len > 0xfe)
  339. return FALSE;
  340. memset(seen, FALSE, sizeof(seen));
  341. sap_songs = 0;
  342. for (i = 0; i < song_len; i++) {
  343. unsigned int j;
  344. UBYTE c;
  345. if (seen[i])
  346. continue;
  347. j = i;
  348. /* follow jump commands until a pattern or a stop command is found */
  349. do {
  350. seen[j] = TRUE;
  351. c = module[0x1d0 + j * 2];
  352. if (c != 0xff)
  353. break;
  354. j = module[0x1d1 + j * 2];
  355. } while (j < song_len && !seen[j]);
  356. /* if no pattern found then this is not a subsong */
  357. if (c >= 64)
  358. continue;
  359. /* found subsong */
  360. song_pos[sap_songs++] = (UBYTE) j;
  361. j++;
  362. /* follow this subsong */
  363. while (j < song_len && !seen[j]) {
  364. seen[j] = TRUE;
  365. c = module[0x1d0 + j * 2];
  366. if (c < 64)
  367. j++;
  368. else if (c == 0xff)
  369. j = module[0x1d1 + j * 2];
  370. else
  371. break;
  372. }
  373. }
  374. return sap_songs != 0;
  375. }
  376. static int load_rmt(const unsigned char *module, unsigned int module_len)
  377. {
  378. unsigned int i;
  379. UWORD song_start;
  380. UWORD song_last_byte;
  381. const unsigned char *song;
  382. unsigned int song_len;
  383. UBYTE seen[256];
  384. if (module_len < 0x30 || module[6] != 'R' || module[7] != 'M'
  385.  || module[8] != 'T' || module[13] != 1)
  386. return FALSE;
  387. switch (module[9]) {
  388. case '4':
  389. break;
  390. case '8':
  391. sap_stereo = 1;
  392. break;
  393. default:
  394. return FALSE;
  395. }
  396. i = module[12];
  397. if (i < 1 || i > 4)
  398. return FALSE;
  399. sap_fastplay = perframe2fastplay[i - 1];
  400. if (!load_native(module, module_len, sap_stereo ? rmt8_obx : rmt4_obx, 'r'))
  401. return FALSE;
  402. sap_player = 0x600;
  403. /* auto-detect number of subsongs */
  404. song_start = module[20] + (module[21] << 8);
  405. song_last_byte = module[4] + (module[5] << 8);
  406. if (song_start <= sap_music || song_start >= song_last_byte)
  407. return FALSE;
  408. song = module + 6 + song_start - sap_music;
  409. song_len = (song_last_byte + 1 - song_start) >> (2 + sap_stereo);
  410. if (song_len > 0xfe)
  411. song_len = 0xfe;
  412. memset(seen, FALSE, sizeof(seen));
  413. sap_songs = 0;
  414. for (i = 0; i < song_len; i++) {
  415. unsigned int j;
  416. if (seen[i])
  417. continue;
  418. j = i;
  419. do {
  420. seen[j] = TRUE;
  421. if (song[j << (2 + sap_stereo)] != 0xfe)
  422. break;
  423. j = song[(j << (2 + sap_stereo)) + 1];
  424. } while (j < song_len && !seen[j]);
  425. song_pos[sap_songs++] = (UBYTE) j;
  426. j++;
  427. while (j < song_len && !seen[j]) {
  428. seen[j] = TRUE;
  429. if (song[j << (2 + sap_stereo)] != 0xfe)
  430. j++;
  431. else
  432. j = song[(j << (2 + sap_stereo)) + 1];
  433. }
  434. }
  435. return sap_songs != 0;
  436. }
  437. static int load_tmc(const unsigned char *module, unsigned int module_len)
  438. {
  439. unsigned int i;
  440. if (module_len < 0x1d0)
  441. return FALSE;
  442. if (!load_native(module, module_len, tmc_obx, 't'))
  443. return FALSE;
  444. tmc_per_frame = module[37];
  445. if (tmc_per_frame < 1 || tmc_per_frame > 4)
  446. return FALSE;
  447. sap_fastplay = perframe2fastplay[tmc_per_frame - 1];
  448. i = 0;
  449. /* find first instrument */
  450. while (module[0x66 + i] == 0) {
  451. if (++i >= 64)
  452. return FALSE; /* no instrument */
  453. }
  454. i = (module[0x66 + i] << 8) + module[0x26 + i] - sap_music - 1 + 6;
  455. if (i >= module_len)
  456. return FALSE;
  457. /* skip trailing jumps */
  458. do {
  459. if (i <= 0x1b5)
  460. return FALSE; /* no pattern to play */
  461. i -= 16;
  462. } while (module[i] >= 0x80);
  463. while (i >= 0x1b5) {
  464. if (module[i] >= 0x80)
  465. sap_songs++;
  466. i -= 16;
  467. }
  468. return TRUE;
  469. }
  470. static int load_tm2(const unsigned char *module, unsigned int module_len)
  471. {
  472. unsigned int i;
  473. unsigned int song_end;
  474. unsigned char c;
  475. if (module_len < 0x3a4)
  476. return FALSE;
  477. i = module[0x25];
  478. if (i < 1 || i > 4)
  479. return FALSE;
  480. sap_fastplay = perframe2fastplay[i - 1];
  481. if (!load_native(module, module_len, tm2_obx, 'T'))
  482. return FALSE;
  483. /* TODO: quadrophonic */
  484. if (module[0x1f] != 0)
  485. #ifdef STEREO_SOUND
  486. sap_stereo = 1;
  487. #else
  488. return FALSE;
  489. #endif
  490. sap_player = 0x500;
  491. song_end = 0xffff;
  492. for (i = 0; i < 0x80; i++) {
  493. unsigned int instr_addr = module[0x86 + i] + (module[0x306 + i] << 8);
  494. if (instr_addr != 0 && instr_addr < song_end)
  495. song_end = instr_addr;
  496. }
  497. for (i = 0; i < 0x100; i++) {
  498. unsigned int pattern_addr = module[0x106 + i] + (module[0x206 + i] << 8);
  499. if (pattern_addr != 0 && pattern_addr < song_end)
  500. song_end = pattern_addr;
  501. }
  502. if (song_end < sap_music + 0x380U + 2U * 17U)
  503. return FALSE;
  504. i = song_end - sap_music - 0x380;
  505. if (0x386 + i >= module_len)
  506. return FALSE;
  507. i -= i % 17;
  508. /* skip trailing stop/jump commands */
  509. do {
  510. if (i == 0)
  511. return FALSE;
  512. i -= 17;
  513. c = module[0x386 + 16 + i];
  514. } while (c == 0 || c >= 0x80);
  515. /* count stop/jump commands */
  516. while (i > 0) {
  517. i -= 17;
  518. c = module[0x386 + 16 + i];
  519. if (c == 0 || c >= 0x80)
  520. sap_songs++;
  521. }
  522. return TRUE;
  523. }
  524. static int tag_matches(const char *tag, const UBYTE *sap_ptr, const UBYTE *sap_end)
  525. {
  526. size_t len = strlen(tag);
  527. return (sap_ptr + len + 8 < sap_end) && memcmp(tag, sap_ptr, len) == 0;
  528. }
  529. static int parse_hex(const UBYTE **ps, UWORD *retval)
  530. {
  531. int chars = 0;
  532. *retval = 0;
  533. while (**ps != 0x0d) {
  534. char c;
  535. if (++chars > 4)
  536. return FALSE;
  537. c = (char) *(*ps)++;
  538. *retval <<= 4;
  539. if (c >= '0' && c <= '9')
  540. *retval += c - '0';
  541. else if (c >= 'A' && c <= 'F')
  542. *retval += c - 'A' + 10;
  543. else if (c >= 'a' && c <= 'f')
  544. *retval += c - 'a' + 10;
  545. else
  546. return FALSE;
  547. }
  548. return chars != 0;
  549. }
  550. static int parse_dec(const UBYTE **ps, unsigned int *retval)
  551. {
  552. int chars = 0;
  553. *retval = 0;
  554. while (**ps != 0x0d) {
  555. char c;
  556. if (++chars > 3)
  557. return FALSE;
  558. c = (char) *(*ps)++;
  559. *retval *= 10;
  560. if (c >= '0' && c <= '9')
  561. *retval += c - '0';
  562. else
  563. return FALSE;
  564. }
  565. return chars != 0;
  566. }
  567. static int load_sap(const UBYTE *sap_ptr, const UBYTE * const sap_end)
  568. {
  569. if (!tag_matches("SAP", sap_ptr, sap_end))
  570. return FALSE;
  571. sap_type = '?';
  572. sap_player = 0xffff;
  573. sap_music = 0xffff;
  574. sap_init = 0xffff;
  575. sap_ptr += 3;
  576. for (;;) {
  577. if (sap_ptr + 8 >= sap_end || sap_ptr[0] != 0x0d || sap_ptr[1] != 0x0a)
  578. return FALSE;
  579. sap_ptr += 2;
  580. if (sap_ptr[0] == 0xff)
  581. break;
  582. if (tag_matches("TYPE ", sap_ptr, sap_end)) {
  583. sap_ptr += 5;
  584. sap_type = *sap_ptr++;
  585. }
  586. else if (tag_matches("PLAYER ", sap_ptr, sap_end)) {
  587. sap_ptr += 7;
  588. if (!parse_hex(&sap_ptr, &sap_player))
  589. return FALSE;
  590. }
  591. else if (tag_matches("MUSIC ", sap_ptr, sap_end)) {
  592. sap_ptr += 6;
  593. if (!parse_hex(&sap_ptr, &sap_music))
  594. return FALSE;
  595. }
  596. else if (tag_matches("INIT ", sap_ptr, sap_end)) {
  597. sap_ptr += 5;
  598. if (!parse_hex(&sap_ptr, &sap_init))
  599. return FALSE;
  600. }
  601. else if (tag_matches("SONGS ", sap_ptr, sap_end)) {
  602. sap_ptr += 6;
  603. if (!parse_dec(&sap_ptr, &sap_songs) || sap_songs < 1 || sap_songs > 255)
  604. return FALSE;
  605. }
  606. else if (tag_matches("DEFSONG ", sap_ptr, sap_end)) {
  607. sap_ptr += 8;
  608. if (!parse_dec(&sap_ptr, &sap_defsong))
  609. return FALSE;
  610. }
  611. else if (tag_matches("FASTPLAY ", sap_ptr, sap_end)) {
  612. sap_ptr += 9;
  613. if (!parse_dec(&sap_ptr, &sap_fastplay) || sap_fastplay < 1 || sap_fastplay > 312)
  614. return FALSE;
  615. }
  616. else if (tag_matches("STEREO", sap_ptr, sap_end))
  617. #ifdef STEREO_SOUND
  618. sap_stereo = 1;
  619. #else
  620. return FALSE;
  621. #endif
  622. /* ignore unknown tags */
  623. while (sap_ptr[0] != 0x0d) {
  624. sap_ptr++;
  625. if (sap_ptr >= sap_end)
  626. return FALSE;
  627. }
  628. }
  629. if (sap_defsong >= sap_songs)
  630. return FALSE;
  631. switch (sap_type) {
  632. case 'B':
  633. if (sap_player == 0xffff || sap_init == 0xffff)
  634. return FALSE;
  635. break;
  636. case 'C':
  637. if (sap_player == 0xffff || sap_music == 0xffff)
  638. return FALSE;
  639. break;
  640. default:
  641. return FALSE;
  642. }
  643. if (sap_ptr[1] != 0xff)
  644. return FALSE;
  645. memset(memory, 0, sizeof(memory));
  646. sap_ptr += 2;
  647. while (sap_ptr + 5 <= sap_end) {
  648. int start_addr = sap_ptr[0] + (sap_ptr[1] << 8);
  649. int block_len = sap_ptr[2] + (sap_ptr[3] << 8) + 1 - start_addr;
  650. if (block_len <= 0 || sap_ptr + block_len > sap_end)
  651. return FALSE;
  652. sap_ptr += 4;
  653. memcpy(memory + start_addr, sap_ptr, block_len);
  654. sap_ptr += block_len;
  655. if (sap_ptr == sap_end)
  656. return TRUE;
  657. if (sap_ptr + 7 <= sap_end && sap_ptr[0] == 0xff && sap_ptr[1] == 0xff)
  658. sap_ptr += 2;
  659. }
  660. return FALSE;
  661. }
  662. #define EXT(c1, c2, c3) ((c1 + (c2 << 8) + (c3 << 16)) | 0x202020)
  663. int ASAP_Load(const char *filename, const unsigned char *module, unsigned int module_len)
  664. {
  665. const char *p;
  666. int ext;
  667. for (p = filename; *p != ''; p++);
  668. ext = 0;
  669. for (;;) {
  670. if (--p <= filename || *p < ' ')
  671. return FALSE; /* no filename extension or invalid character */
  672. if (*p == '.')
  673. break;
  674. ext = (ext << 8) + (*p & 0xff);
  675. }
  676. sap_stereo = 0;
  677. sap_songs = 1;
  678. sap_defsong = 0;
  679. sap_fastplay = 312;
  680. switch (ext | 0x202020) {
  681. case EXT('C', 'M', 'C'):
  682. return load_cmc(module, module_len, FALSE);
  683. case EXT('C', 'M', 'R'):
  684. return load_cmc(module, module_len, TRUE);
  685. case EXT('D', 'M', 'C'):
  686. sap_fastplay = 156;
  687. return load_cmc(module, module_len, FALSE);
  688. case EXT('M', 'P', 'D'):
  689. sap_fastplay = 156;
  690. return load_mpt(module, module_len);
  691. case EXT('M', 'P', 'T'):
  692. return load_mpt(module, module_len);
  693. case EXT('R', 'M', 'T'):
  694. return load_rmt(module, module_len);
  695. case EXT('S', 'A', 'P'):
  696. return load_sap(module, module + module_len);
  697. case EXT('T', 'M', '2'):
  698. return load_tm2(module, module_len);
  699. #ifdef STEREO_SOUND
  700. case EXT('T', 'M', '8'):
  701. sap_stereo = 1;
  702. return load_tmc(module, module_len);
  703. #endif
  704. case EXT('T', 'M', 'C'):
  705. return load_tmc(module, module_len);
  706. default:
  707. return FALSE;
  708. }
  709. }
  710. unsigned int ASAP_GetChannels(void)
  711. {
  712. return 1 << sap_stereo;
  713. }
  714. unsigned int ASAP_GetSongs(void)
  715. {
  716. return sap_songs;
  717. }
  718. unsigned int ASAP_GetDefSong(void)
  719. {
  720. return sap_defsong;
  721. }
  722. static void call_6502(UWORD addr, int max_scanlines)
  723. {
  724. regPC = addr;
  725. /* put a CIM at 0xd20a and a return address on stack */
  726. dPutByte(0xd20a, 0xd2);
  727. dPutByte(0x01fe, 0x09);
  728. dPutByte(0x01ff, 0xd2);
  729. regS = 0xfd;
  730. xpos = 0;
  731. GO(max_scanlines * (LINE_C - DMAR));
  732. }
  733. /* 50 Atari frames for the initialization routine - some SAPs are self-extracting. */
  734. #define SCANLINES_FOR_INIT  (50 * 312)
  735. void ASAP_PlaySong(unsigned int song)
  736. {
  737. UWORD addr;
  738. if (enable_stereo != sap_stereo) {
  739. Pokey_sound_init(ASAP_MAIN_CLOCK, (uint16) block_rate,
  740. 1 << sap_stereo, sample_16bit ? SND_BIT16 : 0);
  741. enable_stereo = sap_stereo;
  742. }
  743. for (addr = _AUDF1; addr <= _STIMER; addr++)
  744. POKEY_PutByte(addr, 0);
  745. if (sap_stereo)
  746. for (addr = _AUDF1 + _POKEY2; addr <= _STIMER + _POKEY2; addr++)
  747. POKEY_PutByte(addr, 0);
  748. blockclocks = 0;
  749. blockclocks_per_player = 114U * sap_fastplay * block_rate;
  750. regP = 0x30;
  751. switch (sap_type) {
  752. case 'B':
  753. regA = (UBYTE) song;
  754. regX = 0x00;
  755. regY = 0x00;
  756. /* 5 frames should be enough */
  757. call_6502(sap_init, SCANLINES_FOR_INIT);
  758. break;
  759. case 'C':
  760. regA = 0x70;
  761. regX = (UBYTE) sap_music;
  762. regY = (UBYTE) (sap_music >> 8);
  763. call_6502((UWORD) (sap_player + 3), SCANLINES_FOR_INIT);
  764. regA = 0x00;
  765. regX = (UBYTE) song;
  766. call_6502((UWORD) (sap_player + 3), SCANLINES_FOR_INIT);
  767. break;
  768. case 'm':
  769. regA = 0x00;
  770. regX = (UBYTE) (sap_music >> 8);
  771. regY = (UBYTE) sap_music;
  772. call_6502(sap_player, SCANLINES_FOR_INIT);
  773. regA = 0x02;
  774. regX = song_pos[song];
  775. call_6502(sap_player, SCANLINES_FOR_INIT);
  776. break;
  777. case 'r':
  778. regA = song_pos[song];
  779. regX = (UBYTE) sap_music;
  780. regY = (UBYTE) (sap_music >> 8);
  781. call_6502(sap_player, SCANLINES_FOR_INIT);
  782. break;
  783. case 't':
  784. case 'T':
  785. regA = 0x70;
  786. regX = (UBYTE) (sap_music >> 8);
  787. regY = (UBYTE) sap_music;
  788. call_6502(sap_player, SCANLINES_FOR_INIT);
  789. regA = 0x00;
  790. regX = (UBYTE) song;
  791. call_6502(sap_player, SCANLINES_FOR_INIT);
  792. tmc_per_frame_counter = 1;
  793. break;
  794. }
  795. }
  796. void ASAP_Generate(void *buffer, unsigned int buffer_len)
  797. {
  798. /* convert number of bytes to number of blocks */
  799. buffer_len >>= sample_16bit + enable_stereo;
  800. if (buffer_len == 0U)
  801. return;
  802. for (;;) {
  803. unsigned int blocks = blockclocks / ASAP_MAIN_CLOCK;
  804. if (blocks != 0U) {
  805. unsigned int samples;
  806. if (blocks > buffer_len)
  807. blocks = buffer_len;
  808. buffer_len -= blocks;
  809. samples = blocks << enable_stereo;
  810. blockclocks -= blocks * ASAP_MAIN_CLOCK;
  811. Pokey_process(buffer, samples);
  812. /* swap bytes in non-native words if necessary */
  813. if (sample_format ==
  814. #ifdef WORDS_BIGENDIAN
  815. AUDIO_FORMAT_S16_LE
  816. #else
  817. AUDIO_FORMAT_S16_BE
  818. #endif
  819. ) {
  820. unsigned char *p = (unsigned char *) buffer;
  821. unsigned int n = samples;
  822. do {
  823. unsigned char t = p[0];
  824. p[0] = p[1];
  825. p[1] = t;
  826. p += 2;
  827. } while (--n != 0U);
  828. }
  829. if (buffer_len == 0U)
  830. return;
  831. buffer = (void *) ((unsigned char *) buffer +
  832. (samples << sample_16bit));
  833. }
  834. switch (sap_type) {
  835. case 'B':
  836. call_6502(sap_player, sap_fastplay);
  837. break;
  838. case 'C':
  839. call_6502((UWORD) (sap_player + 6), sap_fastplay);
  840. break;
  841. case 'm':
  842. case 'r':
  843. case 'T':
  844. call_6502((UWORD) (sap_player + 3), sap_fastplay);
  845. break;
  846. case 't':
  847. if (--tmc_per_frame_counter <= 0) {
  848. tmc_per_frame_counter = tmc_per_frame;
  849. call_6502((UWORD) (sap_player + 3), sap_fastplay);
  850. }
  851. else
  852. call_6502((UWORD) (sap_player + 6), sap_fastplay);
  853. break;
  854. }
  855. random_scanline_counter = (random_scanline_counter + LINE_C * sap_fastplay)
  856.                           % ((AUDCTL[0] & POLY9) ? POLY9_SIZE : POLY17_SIZE);
  857. blockclocks += blockclocks_per_player;
  858. }
  859. }