1 // --------------------------------------------------------------------------- 2 // This file is part of reSID, a MOS6581 SID emulator engine. 3 // Copyright (C) 2004 Dag Lem <resid@nimrod.no> 4 // 5 // This program is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation; either version 2 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 // --------------------------------------------------------------------------- 19 // C64 DTV modifications written by 20 // Daniel Kahlin <daniel@kahlin.net> 21 // Copyright (C) 2007 Daniel Kahlin <daniel@kahlin.net> 22 // Antti S. Lankila <alankila@bel.fi> 23 // Copyright (C) 2009 Antti S. Lankila <alankila@bel.fi> 24 25 #define __WAVE_CC__ 26 #include "wave.h" 27 28 namespace reSID_dtv 29 { 30 31 // ---------------------------------------------------------------------------- 32 // Constructor. 33 // ---------------------------------------------------------------------------- WaveformGenerator()34WaveformGenerator::WaveformGenerator() 35 { 36 sync_source = this; 37 reset(); 38 } 39 40 41 // ---------------------------------------------------------------------------- 42 // Set sync source. 43 // ---------------------------------------------------------------------------- set_sync_source(WaveformGenerator * source)44void WaveformGenerator::set_sync_source(WaveformGenerator* source) 45 { 46 sync_source = source; 47 source->sync_dest = this; 48 } 49 50 // ---------------------------------------------------------------------------- 51 // Register functions. 52 // ---------------------------------------------------------------------------- writeFREQ_LO(reg8 freq_lo)53void WaveformGenerator::writeFREQ_LO(reg8 freq_lo) 54 { 55 freq = (freq & 0xff00) | (freq_lo & 0x00ff); 56 } 57 writeFREQ_HI(reg8 freq_hi)58void WaveformGenerator::writeFREQ_HI(reg8 freq_hi) 59 { 60 freq = ((freq_hi << 8) & 0xff00) | (freq & 0x00ff); 61 } 62 writePW_LO(reg8 pw_lo)63void WaveformGenerator::writePW_LO(reg8 pw_lo) 64 { 65 pw = (pw & 0xf00) | (pw_lo & 0x0ff); 66 } 67 writePW_HI(reg8 pw_hi)68void WaveformGenerator::writePW_HI(reg8 pw_hi) 69 { 70 pw = ((pw_hi << 8) & 0xf00) | (pw & 0x0ff); 71 } 72 writeCONTROL_REG(reg8 control)73void WaveformGenerator::writeCONTROL_REG(reg8 control) 74 { 75 waveform = (control >> 4) & 0x0f; 76 ring_mod = control & 0x04; 77 sync = control & 0x02; 78 test = control & 0x08; 79 80 // Test bit set. Accumulator is cleared. 81 if (test) { 82 accumulator = 0; 83 } 84 85 // The gate bit is handled by the EnvelopeGenerator. 86 } 87 readOSC()88reg8 WaveformGenerator::readOSC() 89 { 90 return outputN___() >> 4; 91 } 92 93 /* LFSR is clocked if the bit 19 is incremented */ writeACC_HI(reg8 value)94void WaveformGenerator::writeACC_HI(reg8 value) 95 { 96 reg24 accumulator_prev = accumulator; 97 accumulator = (value << 16) | (accumulator & 0xffff); 98 if (!(accumulator_prev & 0x080000) && (accumulator & 0x080000)) { 99 /* This has been measured to happen also with test bit on. */ 100 clock_noise(); 101 } 102 } 103 104 // ---------------------------------------------------------------------------- 105 // SID reset. 106 // ---------------------------------------------------------------------------- reset()107void WaveformGenerator::reset() 108 { 109 accumulator = 0; 110 counter = 0; 111 shift_register = 0x7fffff; 112 noise = 0xfff; 113 freq = 0; 114 pw = 0; 115 116 test = 0; 117 ring_mod = 0; 118 sync = 0; 119 120 msb_rising = false; 121 } 122 123 } // namespace reSID_dtv 124