106 lines
2.0 KiB
C
106 lines
2.0 KiB
C
|
#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 */
|