summaryrefslogtreecommitdiff
path: root/apps/codecs/libgme/nes_apu.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libgme/nes_apu.h')
-rw-r--r--apps/codecs/libgme/nes_apu.h43
1 files changed, 22 insertions, 21 deletions
diff --git a/apps/codecs/libgme/nes_apu.h b/apps/codecs/libgme/nes_apu.h
index 11f1f26cc7..0a2b1f57cd 100644
--- a/apps/codecs/libgme/nes_apu.h
+++ b/apps/codecs/libgme/nes_apu.h
@@ -1,6 +1,6 @@
1// NES 2A03 APU sound chip emulator 1// NES 2A03 APU sound chip emulator
2 2
3// Nes_Snd_Emu 0.1.8 3// Nes_Snd_Emu 0.2.0-pre
4#ifndef NES_APU_H 4#ifndef NES_APU_H
5#define NES_APU_H 5#define NES_APU_H
6 6
@@ -9,7 +9,7 @@
9 9
10enum { apu_status_addr = 0x4015 }; 10enum { apu_status_addr = 0x4015 };
11enum { apu_osc_count = 5 }; 11enum { apu_osc_count = 5 };
12enum { apu_no_irq = INT_MAX / 2 + 1 }; 12enum { apu_no_irq = INT_MAX/2 + 1 };
13enum { apu_irq_waiting = 0 }; 13enum { apu_irq_waiting = 0 };
14 14
15enum { apu_io_addr = 0x4000 }; 15enum { apu_io_addr = 0x4000 };
@@ -17,24 +17,16 @@ enum { apu_io_size = 0x18 };
17 17
18struct apu_state_t; 18struct apu_state_t;
19 19
20struct Nes_Apu { 20struct Nes_Apu {
21 nes_time_t last_dmc_time;
22 int osc_enables;
23
24 struct Nes_Osc* oscs [apu_osc_count];
25 struct Nes_Square square1;
26 struct Nes_Square square2;
27 struct Nes_Noise noise;
28 struct Nes_Triangle triangle;
29 struct Nes_Dmc dmc;
30
31 int tempo_; 21 int tempo_;
32 nes_time_t last_time; // has been run until this time in current frame 22 nes_time_t last_time; // has been run until this time in current frame
23 nes_time_t last_dmc_time;
33 nes_time_t earliest_irq_; 24 nes_time_t earliest_irq_;
34 nes_time_t next_irq; 25 nes_time_t next_irq;
35 int frame_period; 26 int frame_period;
36 int frame_delay; // cycles until frame counter runs next 27 int frame_delay; // cycles until frame counter runs next
37 int frame; // current frame (0-3) 28 int frame; // current frame (0-3)
29 int osc_enables;
38 int frame_mode; 30 int frame_mode;
39 bool irq_flag; 31 bool irq_flag;
40 32
@@ -42,6 +34,13 @@ struct Nes_Apu {
42 void* irq_data; 34 void* irq_data;
43 35
44 Synth square_synth; // shared by squares 36 Synth square_synth; // shared by squares
37
38 struct Nes_Osc* oscs [apu_osc_count];
39 struct Nes_Square square1;
40 struct Nes_Square square2;
41 struct Nes_Noise noise;
42 struct Nes_Triangle triangle;
43 struct Nes_Dmc dmc;
45}; 44};
46 45
47// Init Nes apu 46// Init Nes apu
@@ -49,22 +48,22 @@ void Apu_init( struct Nes_Apu* this );
49 48
50// Set buffer to generate all sound into, or disable sound if NULL 49// Set buffer to generate all sound into, or disable sound if NULL
51void Apu_output( struct Nes_Apu* this, struct Blip_Buffer* ); 50void Apu_output( struct Nes_Apu* this, struct Blip_Buffer* );
52 51
53// All time values are the number of cpu clock cycles relative to the 52// All time values are the number of cpu clock cycles relative to the
54// beginning of the current time frame. Before resetting the cpu clock 53// beginning of the current time frame. Before resetting the cpu clock
55// count, call end_frame( last_cpu_time ). 54// count, call end_frame( last_cpu_time ).
56 55
57// Write to register (0x4000-0x4017, except 0x4014 and 0x4016) 56// Write to register (0x4000-0x4017, except 0x4014 and 0x4016)
58void Apu_write_register( struct Nes_Apu* this, nes_time_t, addr_t, int data ); 57void Apu_write_register( struct Nes_Apu* this, nes_time_t, addr_t, int data );
59 58
60// Read from status register at 0x4015 59// Read from status register at 0x4015
61int Apu_read_status( struct Nes_Apu* this, nes_time_t ); 60int Apu_read_status( struct Nes_Apu* this, nes_time_t );
62 61
63// Run all oscillators up to specified time, end current time frame, then 62// Run all oscillators up to specified time, end current time frame, then
64// start a new time frame at time 0. Time frames have no effect on emulation 63// start a new time frame at time 0. Time frames have no effect on emulation
65// and each can be whatever length is convenient. 64// and each can be whatever length is convenient.
66void Apu_end_frame( struct Nes_Apu* this, nes_time_t ); 65void Apu_end_frame( struct Nes_Apu* this, nes_time_t );
67 66
68// Additional optional features (can be ignored without any problem) 67// Additional optional features (can be ignored without any problem)
69 68
70// Reset internal frame counter, registers, and all oscillators. 69// Reset internal frame counter, registers, and all oscillators.
@@ -72,13 +71,13 @@ void Apu_end_frame( struct Nes_Apu* this, nes_time_t );
72// Set the DMC oscillator's initial DAC value to initial_dmc_dac without 71// Set the DMC oscillator's initial DAC value to initial_dmc_dac without
73// any audible click. 72// any audible click.
74void Apu_reset( struct Nes_Apu* this, bool pal_mode, int initial_dmc_dac ); 73void Apu_reset( struct Nes_Apu* this, bool pal_mode, int initial_dmc_dac );
75 74
76// Adjust frame period 75// Adjust frame period
77void Apu_set_tempo( struct Nes_Apu* this, int ); 76void Apu_set_tempo( struct Nes_Apu* this, int );
78 77
79// Set overall volume (default is 1.0) 78// Set overall volume (default is 1.0)
80void Apu_volume( struct Nes_Apu* this, int ); 79void Apu_volume( struct Nes_Apu* this, int );
81 80
82// Run DMC until specified time, so that any DMC memory reads can be 81// Run DMC until specified time, so that any DMC memory reads can be
83// accounted for (i.e. inserting cpu wait states). 82// accounted for (i.e. inserting cpu wait states).
84void Apu_run_until( struct Nes_Apu* this, nes_time_t ); 83void Apu_run_until( struct Nes_Apu* this, nes_time_t );
@@ -124,11 +123,13 @@ static inline nes_time_t Dmc_next_read_time( struct Nes_Dmc* this )
124 if ( this->osc.length_counter == 0 ) 123 if ( this->osc.length_counter == 0 )
125 return apu_no_irq; // not reading 124 return apu_no_irq; // not reading
126 125
127 return this->apu->last_dmc_time + this->osc.delay + (long) (this->bits_remain - 1) * this->period; 126 return this->apu->last_dmc_time + this->osc.delay + (this->bits_remain - 1) * this->period;
128} 127}
129 128
130// Time when next DMC memory read will occur 129// Time when next DMC memory read will occur
131static inline nes_time_t Apu_next_dmc_read_time( struct Nes_Apu* this ) { return Dmc_next_read_time( &this->dmc ); } 130static inline nes_time_t Apu_next_dmc_read_time( struct Nes_Apu* this ) { return Dmc_next_read_time( &this->dmc ); }
132void Apu_irq_changed( struct Nes_Apu* this ); 131void Apu_irq_changed( struct Nes_Apu* this );
133 132
133// Experimental
134void Apu_enable_nonlinear_( struct Nes_Apu* this, double sq, double tnd );
134#endif 135#endif