apu.c (1465B)
1 #include <stdio.h> 2 #include <string.h> 3 4 #include "apu.h" 5 6 struct apu apu = {0}; 7 8 void 9 apu_init(void) 10 { 11 memset(&apu, 0, sizeof(apu)); 12 } 13 14 uint8_t 15 apu_read(uint16_t addr) 16 { 17 switch (addr) { 18 /* pulse1 */ 19 case 0x4000: 20 return (apu.pulse1.duty << 6) | (apu.pulse1.envelope << 5) 21 | (apu.pulse1.const_vol << 4) | apu.pulse1.envelope_vol; 22 case 0x4001: 23 return (apu.pulse1.sweep_enable << 7) | (apu.pulse1.sweep_period << 4) 24 | (apu.pulse1.sweep_negative << 3) | apu.pulse1.sweep_shift_count; 25 case 0x4002: 26 return apu.pulse1.timer_low; 27 case 0x4003: 28 return (apu.pulse1.length_counter_load << 3) | apu.pulse1.timer_high; 29 /* pulse2 */ 30 case 0x4004: 31 return (apu.pulse2.duty << 6) | (apu.pulse2.envelope << 5) 32 | (apu.pulse2.const_vol << 4) | apu.pulse2.envelope_vol; 33 case 0x4005: 34 return (apu.pulse1.sweep_enable << 7) | (apu.pulse1.sweep_period << 4) 35 | (apu.pulse1.sweep_negative << 3) | apu.pulse1.sweep_shift_count; 36 case 0x4006: 37 return apu.pulse1.timer_low; 38 case 0x4007: 39 return (apu.pulse1.length_counter_load << 3) | apu.pulse1.timer_high; 40 /* status */ 41 case 0x4015: 42 return (apu.status.dmc_int << 7) | (apu.status.frame_int << 6) 43 | (apu.status.dmc_active << 4) | (apu.status.lc_noise << 3) 44 | (apu.status.lc_triangle << 2) | (apu.status.lc_pulse2 << 1) 45 | apu.status.lc_pulse1; 46 default: 47 fprintf(stderr, "Invalid APU read at $%04X!\n", addr); 48 return 0; 49 }; 50 } 51 52 void 53 apu_write(uint16_t addr, uint8_t byte) 54 { 55 }