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
11class Nes_Apu;
12
13struct 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
37struct 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
52struct 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
72struct 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
90struct 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
103struct 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