1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /*********************************************************************
4 
5     formats/sc3000_bit.c
6 
7     Cassette code for Sega SC-3000 *.bit files
8 
9 *********************************************************************/
10 #include "sc3000_bit.h"
11 
12 #include <cassert>
13 
14 
15 /***************************************************************************
16     PARAMETERS
17 ***************************************************************************/
18 
19 #define LOG 0
20 
21 /***************************************************************************
22     IMPLEMENTATION
23 ***************************************************************************/
24 
25 /*-------------------------------------------------
26     CassetteModulation sc3000_bit_modulation
27 -------------------------------------------------*/
28 
29 static const cassette_image::Modulation sc3000_bit_modulation =
30 {
31 	cassette_image::MODULATION_SINEWAVE,
32 	1200.0 - 300, 1200.0, 1200.0 + 300,
33 	2400.0 - 600, 2400.0, 2400.0 + 600
34 };
35 
36 /*-------------------------------------------------
37     sc3000_bit_identify - identify cassette
38 -------------------------------------------------*/
39 
sc3000_bit_identify(cassette_image * cassette,cassette_image::Options * opts)40 static cassette_image::error sc3000_bit_identify(cassette_image *cassette, cassette_image::Options *opts)
41 {
42 	return cassette->modulation_identify(sc3000_bit_modulation, opts);
43 }
44 
45 /*-------------------------------------------------
46     sc3000_bit_load - load cassette
47 -------------------------------------------------*/
48 
49 #define MODULATE(_value) \
50 	for (int i = 0; i < (_value ? 2 : 1); i++) { \
51 		err = cassette->put_modulated_data_bit(0, time_index, _value, sc3000_bit_modulation, &time_displacement);\
52 		if (err != cassette_image::error::SUCCESS) return err;\
53 		time_index += time_displacement;\
54 	}
55 
sc3000_bit_load(cassette_image * cassette)56 static cassette_image::error sc3000_bit_load(cassette_image *cassette)
57 {
58 	cassette_image::error err;
59 	uint64_t image_size = cassette->image_size();
60 	uint64_t image_pos = 0;
61 	double time_index = 0.0;
62 	double time_displacement;
63 	uint8_t data;
64 
65 	while (image_pos < image_size)
66 	{
67 		cassette->image_read(&data, image_pos, 1);
68 
69 		switch (data)
70 		{
71 		case '1':
72 			MODULATE(1);
73 			break;
74 
75 		case '0':
76 			MODULATE(0);
77 			break;
78 
79 		case ' ':
80 			err = cassette->put_sample(0, time_index, 1/1200.0, 0);
81 			if (err != cassette_image::error::SUCCESS) return err;
82 			time_index += 1/1200.0;
83 			break;
84 		}
85 
86 		image_pos++;
87 	}
88 
89 	return cassette_image::error::SUCCESS;
90 }
91 
92 /*-------------------------------------------------
93     CassetteFormat sc3000_bit_cassette_format
94 -------------------------------------------------*/
95 
96 const cassette_image::Format sc3000_bit_format =
97 {
98 	"bit",
99 	sc3000_bit_identify,
100 	sc3000_bit_load,
101 	nullptr
102 };
103 
104 CASSETTE_FORMATLIST_START( sc3000_cassette_formats )
105 	CASSETTE_FORMAT(sc3000_bit_format)
106 CASSETTE_FORMATLIST_END
107