diff options
Diffstat (limited to 'apu.h')
-rw-r--r-- | apu.h | 105 |
1 files changed, 105 insertions, 0 deletions
@@ -0,0 +1,105 @@ +#ifndef APU_H +#define APU_H + +#include <stdint.h> + +struct pulse { + /* $4000/$4004 */ + uint8_t duty : 2; + uint8_t envelope : 1; + uint8_t const_vol : 1; + uint8_t envelope_vol : 4; + /* $4001/$4005 */ + uint8_t sweep_enable : 1; + uint8_t sweep_period : 3; + uint8_t sweep_negative : 1; + uint8_t sweep_shift_count : 3; + /* $4002/$4006 */ + uint8_t timer_low; + /* $4003/$4007 */ + uint8_t length_counter_load : 5; + uint8_t timer_high : 3; +}; + +struct triangle { + /* $4008 */ + uint8_t counter_disable : 1; + uint8_t counter_reload : 7; + /* $400A */ + uint8_t timer_low; + /* $400B */ + uint8_t counter_load : 5; + uint8_t timer_high : 3; +}; + +struct noise { + /* $400C */ + uint8_t padding1 : 2; + uint8_t loop_envelope : 1; + uint8_t constant_volume : 1; + uint8_t envelope_volume : 4; + /* $400E */ + uint8_t loop_noise : 1; + uint8_t padding2 : 3; + uint8_t noise_period : 4; + /* $400F */ + uint8_t length_counter_load : 5; + uint8_t padding3 : 3; +}; + +struct dmc { + /* $4010 */ + uint8_t irq_enable : 1; + uint8_t loop : 1; + uint8_t padding1 : 2; + uint8_t frequency : 4; + /* $4011 */ + uint8_t padding2 : 1; + uint8_t load_counter : 7; + /* $4012 */ + uint8_t sample_addr; + /* $4013 */ + uint8_t sample_length; +}; + +struct apu { + /* $4000-$4013 (write) */ + struct pulse pulse1; + struct pulse pulse2; + struct triangle triangle; + struct noise noise; + struct dmc dmc; + /* $4015 (write) */ + struct control { + uint8_t padding : 3; + uint8_t dmc_enable : 1; + uint8_t noise_enable : 1; + uint8_t triangle_enable : 1; + uint8_t pulse2_enable : 1; + uint8_t pulse1_enable : 1; + } control; + /* $4015 (read) */ + struct status { + uint8_t dmc_int : 1; + uint8_t frame_int : 1; + uint8_t padding : 1; + uint8_t dmc_active : 1; + uint8_t lc_noise : 1; + uint8_t lc_triangle : 1; + uint8_t lc_pulse2 : 1; + uint8_t lc_pulse1 : 1; + } status; + /* $4017 (write) */ + struct frame_counter { + uint8_t mode : 1; + uint8_t irq_inhibit : 1; + uint8_t padding : 6; + } frame_counter; +}; +extern struct apu apu; + +void apu_tick(void); +uint8_t apu_read(uint16_t addr); +void apu_write(uint16_t addr, uint8_t byte); + +#endif /* APU_H */ |