1 | |
2 | // Private oscillators used by Nes_Apu |
3 | |
4 | // Nes_Snd_Emu 0.1.7. Copyright (C) 2003-2005 Shay Green. GNU LGPL license. |
5 | |
6 | #ifndef NES_OSCS_H |
7 | #define NES_OSCS_H |
8 | |
9 | #include "Blip_Buffer.h" |
10 | |
11 | class Nes_Apu; |
12 | |
13 | struct Nes_Osc |
14 | { |
15 | unsigned char regs [4]; |
16 | bool reg_written [4]; |
17 | Blip_Buffer* output; |
18 | int length_counter;// length counter (0 if unused by oscillator) |
19 | int delay; // delay until next (potential) transition |
20 | int last_amp; // last amplitude oscillator was outputting |
21 | |
22 | void clock_length( int halt_mask ); |
23 | int period() const { |
24 | return (regs [3] & 7) * 0x100 + (regs [2] & 0xff); |
25 | } |
26 | void reset() { |
27 | delay = 0; |
28 | last_amp = 0; |
29 | } |
30 | int update_amp( int amp ) { |
31 | int delta = amp - last_amp; |
32 | last_amp = amp; |
33 | return delta; |
34 | } |
35 | }; |
36 | |
37 | struct Nes_Envelope : Nes_Osc |
38 | { |
39 | int envelope; |
40 | int env_delay; |
41 | |
42 | void clock_envelope(); |
43 | int volume() const; |
44 | void reset() { |
45 | envelope = 0; |
46 | env_delay = 0; |
47 | Nes_Osc::reset(); |
48 | } |
49 | }; |
50 | |
51 | // Nes_Square |
52 | struct Nes_Square : Nes_Envelope |
53 | { |
54 | enum { negate_flag = 0x08 }; |
55 | enum { shift_mask = 0x07 }; |
56 | enum { phase_range = 8 }; |
57 | int phase; |
58 | int sweep_delay; |
59 | |
60 | typedef Blip_Synth<blip_good_quality,15> Synth; |
61 | const Synth* synth; // shared between squares |
62 | |
63 | void clock_sweep( int adjust ); |
64 | void run( cpu_time_t, cpu_time_t ); |
65 | void reset() { |
66 | sweep_delay = 0; |
67 | Nes_Envelope::reset(); |
68 | } |
69 | }; |
70 | |
71 | // Nes_Triangle |
72 | struct Nes_Triangle : Nes_Osc |
73 | { |
74 | enum { phase_range = 16 }; |
75 | int phase; |
76 | int linear_counter; |
77 | Blip_Synth<blip_good_quality,15> synth; |
78 | |
79 | int calc_amp() const; |
80 | void run( cpu_time_t, cpu_time_t ); |
81 | void clock_linear_counter(); |
82 | void reset() { |
83 | linear_counter = 0; |
84 | phase = phase_range; |
85 | Nes_Osc::reset(); |
86 | } |
87 | }; |
88 | |
89 | // Nes_Noise |
90 | struct Nes_Noise : Nes_Envelope |
91 | { |
92 | int noise; |
93 | Blip_Synth<blip_med_quality,15> synth; |
94 | |
95 | void run( cpu_time_t, cpu_time_t ); |
96 | void reset() { |
97 | noise = 1 << 14; |
98 | Nes_Envelope::reset(); |
99 | } |
100 | }; |
101 | |
102 | // Nes_Dmc |
103 | struct Nes_Dmc : Nes_Osc |
104 | { |
105 | int address; // address of next byte to read |
106 | int period; |
107 | //int length_counter; // bytes remaining to play (already defined in Nes_Osc) |
108 | int buf; |
109 | int bits_remain; |
110 | int bits; |
111 | bool buf_empty; |
112 | bool silence; |
113 | |
114 | enum { loop_flag = 0x40 }; |
115 | |
116 | int dac; |
117 | |
118 | cpu_time_t next_irq; |
119 | bool irq_enabled; |
120 | bool irq_flag; |
121 | bool pal_mode; |
122 | bool nonlinear; |
123 | |
124 | int (*rom_reader)( void*, cpu_addr_t ); // needs to be initialized to rom read function |
125 | void* rom_reader_data; |
126 | |
127 | Nes_Apu* apu; |
128 | |
129 | Blip_Synth<blip_med_quality,127> synth; |
130 | |
131 | void start(); |
132 | void write_register( int, int ); |
133 | void run( cpu_time_t, cpu_time_t ); |
134 | void recalc_irq(); |
135 | void fill_buffer(); |
136 | void reload_sample(); |
137 | void reset(); |
138 | int count_reads( cpu_time_t, cpu_time_t* ) const; |
139 | }; |
140 | |
141 | #endif |
142 | |
143 | |