Path: blob/master/libsnes/bsnes/gameboy/apu/square2/square2.cpp
2 views
#ifdef APU_CPP12bool APU::Square2::dac_enable() {3return (envelope_volume || envelope_direction);4}56void APU::Square2::run() {7if(period && --period == 0) {8period = 4 * (2048 - frequency);9phase++;10switch(duty) {11case 0: duty_output = (phase == 6); break; //______-_12case 1: duty_output = (phase >= 6); break; //______--13case 2: duty_output = (phase >= 4); break; //____----14case 3: duty_output = (phase <= 5); break; //------__15}16}1718uint4 sample = (duty_output ? volume : (uint4)0);19if(enable == false) sample = 0;2021output = sample;22}2324void APU::Square2::clock_length() {25if(counter && length) {26if(--length == 0) enable = false;27}28}2930void APU::Square2::clock_envelope() {31if(enable && envelope_frequency && --envelope_period == 0) {32envelope_period = envelope_frequency;33if(envelope_direction == 0 && volume > 0) volume--;34if(envelope_direction == 1 && volume < 15) volume++;35}36}3738void APU::Square2::write(unsigned r, uint8 data) {39if(r == 1) { //$ff16 NR2140duty = data >> 6;41length = 64 - (data & 0x3f);42}4344if(r == 2) { //$ff17 NR2245envelope_volume = data >> 4;46envelope_direction = data & 0x08;47envelope_frequency = data & 0x07;48if(dac_enable() == false) enable = false;49}5051if(r == 3) { //$ff18 NR2352frequency = (frequency & 0x0700) | data;53}5455if(r == 4) { //$ff19 NR2456bool initialize = data & 0x80;57counter = data & 0x40;58frequency = ((data & 7) << 8) | (frequency & 0x00ff);5960if(initialize) {61enable = dac_enable();62envelope_period = envelope_frequency;63volume = envelope_volume;64if(length == 0) length = 64;65}66}6768period = 4 * (2048 - frequency);69}7071void APU::Square2::power() {72enable = 0;7374duty = 0;75length = 0;76envelope_volume = 0;77envelope_direction = 0;78envelope_frequency = 0;79frequency = 0;80counter = 0;8182output = 0;83duty_output = 0;84phase = 0;85period = 0;86envelope_period = 0;87volume = 0;88}8990void APU::Square2::serialize(serializer &s) {91s.integer(enable);9293s.integer(duty);94s.integer(length);95s.integer(envelope_volume);96s.integer(envelope_direction);97s.integer(envelope_frequency);98s.integer(frequency);99s.integer(counter);100101s.integer(output);102s.integer(duty_output);103s.integer(phase);104s.integer(period);105s.integer(envelope_period);106s.integer(volume);107}108109#endif110111112