#include #include #include "apu.h" struct apu apu = {0}; void apu_init(void) { memset(&apu, 0, sizeof(apu)); } uint8_t apu_read(uint16_t addr) { switch (addr) { /* pulse1 */ case 0x4000: return (apu.pulse1.duty << 6) | (apu.pulse1.envelope << 5) | (apu.pulse1.const_vol << 4) | apu.pulse1.envelope_vol; case 0x4001: return (apu.pulse1.sweep_enable << 7) | (apu.pulse1.sweep_period << 4) | (apu.pulse1.sweep_negative << 3) | apu.pulse1.sweep_shift_count; case 0x4002: return apu.pulse1.timer_low; case 0x4003: return (apu.pulse1.length_counter_load << 3) | apu.pulse1.timer_high; /* pulse2 */ case 0x4004: return (apu.pulse2.duty << 6) | (apu.pulse2.envelope << 5) | (apu.pulse2.const_vol << 4) | apu.pulse2.envelope_vol; case 0x4005: return (apu.pulse1.sweep_enable << 7) | (apu.pulse1.sweep_period << 4) | (apu.pulse1.sweep_negative << 3) | apu.pulse1.sweep_shift_count; case 0x4006: return apu.pulse1.timer_low; case 0x4007: return (apu.pulse1.length_counter_load << 3) | apu.pulse1.timer_high; /* status */ case 0x4015: return (apu.status.dmc_int << 7) | (apu.status.frame_int << 6) | (apu.status.dmc_active << 4) | (apu.status.lc_noise << 3) | (apu.status.lc_triangle << 2) | (apu.status.lc_pulse2 << 1) | apu.status.lc_pulse1; default: fprintf(stderr, "Invalid APU read at $%04X!\n", addr); return 0; }; } void apu_write(uint16_t addr, uint8_t byte) { }