/src/lib/formats/oric_tap.c

https://github.com/groovybits/groovymame · C · 519 lines · 343 code · 107 blank · 69 comment · 35 complexity · 595d3c13cba4c372605a61c7957272bf MD5 · raw file

  1. #include "oric_tap.h"
  2. #define ORIC_WAV_DEBUG 0
  3. #define LOG(x) do { if (ORIC_WAV_DEBUG) printf x; } while (0)
  4. /* this code based heavily on tap2wav by Fabrice Frances */
  5. #define ORIC_SYNC_BYTE 0x016
  6. /* frequency of wave */
  7. /* tapes use 1200Hz and 2400Hz samples */
  8. #define ORIC_WAV_FREQUENCY 4800
  9. /* 13 bits define a byte on the cassette */
  10. /* 1 start bit, 8 data bits, 1 parity bit and 3 stop bits */
  11. #define ORIC_BYTE_TO_BITS_ON_CASSETTE 13
  12. #define ORIC_WAVESAMPLES_HEADER 3000
  13. #define ORIC_WAVESAMPLES_TRAILER 1000
  14. enum
  15. {
  16. ORIC_CASSETTE_SEARCHING_FOR_SYNC_BYTE,
  17. ORIC_CASSETTE_GOT_SYNC_BYTE,
  18. ORIC_CASSETTE_READ_HEADER,
  19. ORIC_CASSETTE_READ_FILENAME,
  20. ORIC_CASSETTE_WRITE_DATA
  21. };
  22. #define WAVEENTRY_LOW -32768
  23. #define WAVEENTRY_HIGH 32767
  24. #define WAVEENTRY_NULL 0
  25. #define ORIC_LEADER_LENGTH 512
  26. struct oric_t
  27. {
  28. int cassette_state;
  29. int data_count;
  30. int data_length;
  31. int tap_size;
  32. };
  33. static oric_t oric;
  34. /* to write a bit to the tape, the rom routines output either 4 periods at 1200 Hz for a 0 or 8 periods at 2400 Hz for a 1 */
  35. /* 4800 is twice 2400Hz */
  36. /* 8 periods at 2400Hz */
  37. /* hi,lo, hi,lo, hi,lo, hi,lo */
  38. static INT16 *oric_emit_level(INT16 *p, int count, INT16 wave_state)
  39. {
  40. int i;
  41. for (i=0; i<count; i++)
  42. {
  43. *(p++) = wave_state;
  44. }
  45. return p;
  46. }
  47. /* 4 periods at 1200Hz */
  48. static INT16* oric_output_bit(INT16 *p, UINT8 b)
  49. {
  50. p = oric_emit_level(p, 1, WAVEENTRY_HIGH);
  51. p = oric_emit_level(p, b ? 1 : 2, WAVEENTRY_LOW);
  52. return p;
  53. }
  54. static int oric_get_bit_size_in_samples(UINT8 b)
  55. {
  56. int count;
  57. count = 1;
  58. if (b)
  59. {
  60. count++;
  61. }
  62. else
  63. {
  64. count+=2;
  65. }
  66. return count;
  67. }
  68. /* each byte on cassette is stored as:
  69. start bit 0 * 1
  70. data bits 8 * x (x is 0 or 1, and depends on data-bit value)
  71. parity bit 1 * x (x is 0 or 1, and depends on the parity of the data bits)
  72. stop bits 1 * 3
  73. if data has even parity, parity bit will be 1.
  74. if data has odd parity, parity bit will be 0.
  75. */
  76. /*
  77. 512 * data byte 0x016 -> leader
  78. 1 * data byte 0x024 -> sync byte
  79. 9 * data byte -> header
  80. delay (of last pulse written)
  81. x * data byte -> length
  82. header structure:
  83. 3 * ? -> ???
  84. 1 * ? -> ???
  85. 1 * x -> end address high byte
  86. 1 * x -> end address low byte
  87. 1 * x -> start address high byte
  88. 1 * x -> start address low byte
  89. 1 * ? -> ???
  90. */
  91. static int oric_calculate_byte_size_in_samples(UINT8 byte)
  92. {
  93. int count;
  94. int i;
  95. UINT8 parity;
  96. UINT8 data;
  97. count = 0;
  98. /* start bit */
  99. count+=oric_get_bit_size_in_samples(0);
  100. /* set initial parity */
  101. parity = 1;
  102. /* data bits, written bit 0, bit 1...bit 7 */
  103. data = byte;
  104. for (i=0; i<8; i++)
  105. {
  106. UINT8 data_bit;
  107. data_bit = data & 0x01;
  108. parity = parity + data_bit;
  109. count+=oric_get_bit_size_in_samples(data_bit);
  110. data = data>>1;
  111. }
  112. /* parity */
  113. count+=oric_get_bit_size_in_samples((parity & 0x01));
  114. /* stop bits */
  115. count+=oric_get_bit_size_in_samples(1);
  116. count+=oric_get_bit_size_in_samples(1);
  117. count+=oric_get_bit_size_in_samples(1);
  118. count+=oric_get_bit_size_in_samples(1);
  119. return count;
  120. }
  121. static INT16 *oric_output_byte(INT16 *p, UINT8 byte)
  122. {
  123. int i;
  124. UINT8 parity;
  125. UINT8 data;
  126. /* start bit */
  127. p = oric_output_bit(p, 0);
  128. /* set initial parity */
  129. parity = 1;
  130. /* data bits, written bit 0, bit 1...bit 7 */
  131. data = byte;
  132. for (i=0; i<8; i++)
  133. {
  134. UINT8 data_bit;
  135. data_bit = data & 0x01;
  136. parity = parity + data_bit;
  137. p = oric_output_bit(p, data_bit);
  138. data = data>>1;
  139. }
  140. /* parity */
  141. p = oric_output_bit(p, parity & 0x01);
  142. /* stop bits */
  143. p = oric_output_bit(p, 1);
  144. p = oric_output_bit(p, 1);
  145. p = oric_output_bit(p, 1);
  146. p = oric_output_bit(p, 1);
  147. return p;
  148. }
  149. static INT16 *oric_fill_pause(INT16 *p, int sample_count)
  150. {
  151. int i;
  152. for (i=0; i<sample_count; i++)
  153. {
  154. *(p++) = WAVEENTRY_NULL;
  155. }
  156. return p;
  157. }
  158. static int oric_seconds_to_samples(float seconds)
  159. {
  160. return (int)((float)seconds*(float)ORIC_WAV_FREQUENCY);
  161. }
  162. /* length is length of .tap file! */
  163. static int oric_cassette_calculate_size_in_samples(const UINT8 *bytes, int length)
  164. {
  165. unsigned char header[9];
  166. int count;
  167. const UINT8 *data_ptr;
  168. int i;
  169. UINT8 data;
  170. oric.tap_size = length;
  171. oric.cassette_state = ORIC_CASSETTE_SEARCHING_FOR_SYNC_BYTE;
  172. count = 0;
  173. data_ptr = bytes;
  174. while (data_ptr<(bytes+length))
  175. {
  176. data = data_ptr[0];
  177. data_ptr++;
  178. switch (oric.cassette_state)
  179. {
  180. case ORIC_CASSETTE_SEARCHING_FOR_SYNC_BYTE:
  181. {
  182. if (data==ORIC_SYNC_BYTE)
  183. {
  184. LOG_FORMATS("found sync byte!\n");
  185. /* found first sync byte */
  186. oric.cassette_state = ORIC_CASSETTE_GOT_SYNC_BYTE;
  187. }
  188. }
  189. break;
  190. case ORIC_CASSETTE_GOT_SYNC_BYTE:
  191. {
  192. if (data!=ORIC_SYNC_BYTE)
  193. {
  194. /* 0.25 second pause */
  195. count += oric_seconds_to_samples(0.25);
  196. LOG_FORMATS("found end of sync bytes!\n");
  197. /* oric writes approx 512 bytes */
  198. /* found end of sync bytes */
  199. for (i=0; i<ORIC_LEADER_LENGTH; i++)
  200. {
  201. count+=oric_calculate_byte_size_in_samples(0x016);
  202. }
  203. if (data==0x024)
  204. {
  205. //LOG_FORMATS("reading header!\n");
  206. count+=oric_calculate_byte_size_in_samples(0x024);
  207. oric.cassette_state = ORIC_CASSETTE_READ_HEADER;
  208. oric.data_count = 0;
  209. oric.data_length = 9;
  210. }
  211. }
  212. }
  213. break;
  214. case ORIC_CASSETTE_READ_HEADER:
  215. {
  216. header[oric.data_count] = data;
  217. count+=oric_calculate_byte_size_in_samples(data);
  218. oric.data_count++;
  219. if (oric.data_count==oric.data_length)
  220. {
  221. //LOG_FORMATS("finished reading header!\n");
  222. oric.cassette_state = ORIC_CASSETTE_READ_FILENAME;
  223. }
  224. }
  225. break;
  226. case ORIC_CASSETTE_READ_FILENAME:
  227. {
  228. count+=oric_calculate_byte_size_in_samples(data);
  229. /* got end of filename? */
  230. if (data==0)
  231. {
  232. UINT16 end, start;
  233. LOG_FORMATS("got end of filename\n");
  234. /* 100 1 bits to seperate header from data */
  235. for (i=0; i<100; i++)
  236. {
  237. count+=oric_get_bit_size_in_samples(1);
  238. }
  239. oric.cassette_state = ORIC_CASSETTE_WRITE_DATA;
  240. oric.data_count = 0;
  241. end = (((header[4] & 0x0ff)<<8) | (header[5] & 0x0ff));
  242. start = (((header[6] & 0x0ff)<<8) | (header[7] & 0x0ff));
  243. LOG(("start (from header): %02x\n",start));
  244. LOG(("end (from header): %02x\n",end));
  245. oric.data_length = end - start + 1;
  246. }
  247. }
  248. break;
  249. case ORIC_CASSETTE_WRITE_DATA:
  250. {
  251. count+=oric_calculate_byte_size_in_samples(data);
  252. oric.data_count++;
  253. if (oric.data_count==oric.data_length)
  254. {
  255. LOG_FORMATS("finished writing data!\n");
  256. oric.cassette_state = ORIC_CASSETTE_SEARCHING_FOR_SYNC_BYTE;
  257. }
  258. }
  259. break;
  260. }
  261. }
  262. return count;
  263. }
  264. /* length is length of sample buffer to fill! */
  265. static int oric_cassette_fill_wave(INT16 *buffer, int length, UINT8 *bytes)
  266. {
  267. unsigned char header[9];
  268. UINT8 *data_ptr;
  269. INT16 *p;
  270. int i;
  271. UINT8 data;
  272. p = buffer;
  273. /* header and trailer act as pauses */
  274. /* the trailer is required so that the via sees the last bit of the last
  275. byte */
  276. if (bytes == CODE_HEADER) {
  277. for (i = 0; i < ORIC_WAVESAMPLES_HEADER; i++)
  278. *(p++) = WAVEENTRY_NULL;
  279. }
  280. else if (bytes == CODE_TRAILER) {
  281. for (i = 0; i < ORIC_WAVESAMPLES_TRAILER; i++)
  282. *(p++) = WAVEENTRY_NULL;
  283. }
  284. else
  285. {
  286. /* the length is the number of samples left in the buffer and NOT the number of bytes for the input file */
  287. length = length - ORIC_WAVESAMPLES_TRAILER;
  288. oric.cassette_state = ORIC_CASSETTE_SEARCHING_FOR_SYNC_BYTE;
  289. data_ptr = bytes;
  290. while ((data_ptr<(bytes + oric.tap_size)) && (p < (buffer+length)) )
  291. {
  292. data = data_ptr[0];
  293. data_ptr++;
  294. switch (oric.cassette_state)
  295. {
  296. case ORIC_CASSETTE_SEARCHING_FOR_SYNC_BYTE:
  297. {
  298. if (data==ORIC_SYNC_BYTE)
  299. {
  300. LOG_FORMATS("found sync byte!\n");
  301. /* found first sync byte */
  302. oric.cassette_state = ORIC_CASSETTE_GOT_SYNC_BYTE;
  303. }
  304. }
  305. break;
  306. case ORIC_CASSETTE_GOT_SYNC_BYTE:
  307. {
  308. if (data!=ORIC_SYNC_BYTE)
  309. {
  310. /* 0.25 second pause */
  311. p = oric_fill_pause(p, oric_seconds_to_samples(0.25));
  312. LOG_FORMATS("found end of sync bytes!\n");
  313. /* found end of sync bytes */
  314. for (i=0; i<ORIC_LEADER_LENGTH; i++)
  315. {
  316. p = oric_output_byte(p,0x016);
  317. }
  318. if (data==0x024)
  319. {
  320. //LOG_FORMATS("reading header!\n");
  321. p = oric_output_byte(p,data);
  322. oric.cassette_state = ORIC_CASSETTE_READ_HEADER;
  323. oric.data_count = 0;
  324. oric.data_length = 9;
  325. }
  326. }
  327. }
  328. break;
  329. case ORIC_CASSETTE_READ_HEADER:
  330. {
  331. header[oric.data_count] = data;
  332. p = oric_output_byte(p, data);
  333. oric.data_count++;
  334. if (oric.data_count==oric.data_length)
  335. {
  336. //LOG_FORMATS("finished reading header!\n");
  337. oric.cassette_state = ORIC_CASSETTE_READ_FILENAME;
  338. }
  339. }
  340. break;
  341. case ORIC_CASSETTE_READ_FILENAME:
  342. {
  343. p = oric_output_byte(p, data);
  344. /* got end of filename? */
  345. if (data==0)
  346. {
  347. UINT16 end, start;
  348. LOG_FORMATS("got end of filename\n");
  349. /* oric includes a small delay, but I don't see
  350. it being 1 bits */
  351. for (i=0; i<100; i++)
  352. {
  353. p = oric_output_bit(p,1);
  354. }
  355. oric.cassette_state = ORIC_CASSETTE_WRITE_DATA;
  356. oric.data_count = 0;
  357. end = (((header[4] & 0x0ff)<<8) | (header[5] & 0x0ff));
  358. start = (((header[6] & 0x0ff)<<8) | (header[7] & 0x0ff));
  359. LOG(("start (from header): %02x\n",start));
  360. LOG(("end (from header): %02x\n",end));
  361. oric.data_length = end - start + 1;
  362. }
  363. }
  364. break;
  365. case ORIC_CASSETTE_WRITE_DATA:
  366. {
  367. p = oric_output_byte(p, data);
  368. oric.data_count++;
  369. if (oric.data_count==oric.data_length)
  370. {
  371. LOG_FORMATS("finished writing data!\n");
  372. oric.cassette_state = ORIC_CASSETTE_SEARCHING_FOR_SYNC_BYTE;
  373. }
  374. }
  375. break;
  376. }
  377. }
  378. }
  379. return p - buffer;
  380. }
  381. static const struct CassetteLegacyWaveFiller oric_legacy_fill_wave =
  382. {
  383. oric_cassette_fill_wave, /* fill_wave */
  384. -1, /* chunk_size */
  385. 0, /* chunk_samples */
  386. oric_cassette_calculate_size_in_samples, /* chunk_sample_calc */
  387. ORIC_WAV_FREQUENCY, /* sample_frequency */
  388. ORIC_WAVESAMPLES_HEADER, /* header_samples */
  389. ORIC_WAVESAMPLES_TRAILER /* trailer_samples */
  390. };
  391. static casserr_t oric_tap_identify(cassette_image *cassette, struct CassetteOptions *opts)
  392. {
  393. return cassette_legacy_identify(cassette, opts, &oric_legacy_fill_wave);
  394. }
  395. static casserr_t oric_tap_load(cassette_image *cassette)
  396. {
  397. return cassette_legacy_construct(cassette, &oric_legacy_fill_wave);
  398. }
  399. static const struct CassetteFormat oric_tap_format =
  400. {
  401. "tap",
  402. oric_tap_identify,
  403. oric_tap_load,
  404. NULL
  405. };
  406. CASSETTE_FORMATLIST_START(oric_cassette_formats)
  407. CASSETTE_FORMAT(oric_tap_format)
  408. CASSETTE_FORMATLIST_END