Skip to main content

ym2149_core/
io.rs

1/// One of the two modes of the I/O ports.
2#[repr(u8)]
3#[derive(Debug, Clone, Copy)]
4pub enum IoPortMode {
5    Input = 0,
6    Output = 1,
7}
8
9/// One of the two GPIO ports of the YM2149.
10#[repr(u8)]
11#[derive(Debug, Clone, Copy)]
12pub enum IoPort {
13    A = 0xE,
14    B = 0xF,
15}
16
17/// IO port and mixer settings.
18///
19/// Note: Whereas the YM2149 enables tone / noise generators when the register stores
20/// a value of 0 (false), I wrote the code in a way to seem more logical. The fields
21/// that take a `bool` argument instead enable a generator when its value is `true`.
22#[derive(Debug)]
23pub struct IoPortMixerSettings {
24    pub gpio_port_a_mode: IoPortMode,
25    pub gpio_port_b_mode: IoPortMode,
26    pub noise_ch_c: bool,
27    pub noise_ch_b: bool,
28    pub noise_ch_a: bool,
29    pub tone_ch_c: bool,
30    pub tone_ch_b: bool,
31    pub tone_ch_a: bool,
32}
33
34impl IoPortMixerSettings {
35    /// Returns a u8 containing the settings that can be written directly to register 7 of the YM2149.
36    pub fn as_u8(self) -> u8 {
37        let self_array = [
38            self.gpio_port_a_mode as u8 == 0,
39            self.gpio_port_b_mode as u8 == 0,
40            self.noise_ch_c,
41            self.noise_ch_b,
42            self.noise_ch_a,
43            self.tone_ch_c,
44            self.tone_ch_b,
45            self.tone_ch_a,
46        ];
47
48        let mut byte = 0_u8;
49
50        for i in 0..8 {
51            byte += (!(self_array[i as usize]) as u8) << 7 - i;
52        }
53
54        byte
55    }
56}
57
58impl Default for IoPortMixerSettings {
59    fn default() -> Self {
60        IoPortMixerSettings {
61            gpio_port_a_mode: IoPortMode::Output,
62            gpio_port_b_mode: IoPortMode::Output,
63            noise_ch_c: false,
64            noise_ch_b: false,
65            noise_ch_a: false,
66            tone_ch_c: false,
67            tone_ch_b: false,
68            tone_ch_a: false,
69        }
70    }
71}
72
73/// The four modes of the YM2149's bus control decoder.
74///
75/// Bus control decoder table, no redundancy:
76///
77/// | Mode         | BDIR | BC2 | BC1 |
78/// | ------------ | ---- | --- | --- |
79/// | **INACTIVE** |  0   |  1  |  0  |
80/// | **READ**     |  0   |  1  |  1  |
81/// | **WRITE**    |  1   |  1  |  0  |
82/// | **ADDRESS**  |  1   |  1  |  1  |
83#[repr(u8)]
84#[derive(Debug)]
85pub enum ChipMode {
86    /// DA7~DA0 has high impedance.
87    INACTIVE,
88    /// DA7~DA0 set to output mode, and contents of register currently being addressed are output.
89    ///
90    /// ---
91    /// ### Warning!
92    ///
93    /// ``Mode::READ`` makes the chip output 5V to the data bus. If you're using this crate in an embedded project,
94    /// make sure that 5V isn't too high for your board! If it is, you can use a level shifter to prevent damage to your board.
95    READ,
96    /// DA7~DA0 set to input mode, and data is written to register currently being addressed.
97    WRITE,
98    /// DA7~DA0 set to input mode, and address is fetched from register array.
99    ADDRESS,
100}