summaryrefslogtreecommitdiff
path: root/apu.h
diff options
context:
space:
mode:
Diffstat (limited to 'apu.h')
-rw-r--r--apu.h105
1 files changed, 105 insertions, 0 deletions
diff --git a/apu.h b/apu.h
new file mode 100644
index 0000000..4c39a82
--- /dev/null
+++ b/apu.h
@@ -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 */