DOSBox-X
|
00001 // --------------------------------------------------------------------------- 00002 // This file is part of reSID, a MOS6581 SID emulator engine. 00003 // Copyright (C) 2004 Dag Lem <resid@nimrod.no> 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 2 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License along 00016 // with this program; if not, write to the Free Software Foundation, Inc., 00017 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 // --------------------------------------------------------------------------- 00019 00020 #define __VOICE_CC__ 00021 #include "voice.h" 00022 00023 // ---------------------------------------------------------------------------- 00024 // Constructor. 00025 // ---------------------------------------------------------------------------- 00026 Voice::Voice() 00027 { 00028 set_chip_model(MOS6581); 00029 } 00030 00031 // ---------------------------------------------------------------------------- 00032 // Set chip model. 00033 // ---------------------------------------------------------------------------- 00034 void Voice::set_chip_model(chip_model model) 00035 { 00036 wave.set_chip_model(model); 00037 00038 if (model == MOS6581) { 00039 // The waveform D/A converter introduces a DC offset in the signal 00040 // to the envelope multiplying D/A converter. The "zero" level of 00041 // the waveform D/A converter can be found as follows: 00042 // 00043 // Measure the "zero" voltage of voice 3 on the SID audio output 00044 // pin, routing only voice 3 to the mixer ($d417 = $0b, $d418 = 00045 // $0f, all other registers zeroed). 00046 // 00047 // Then set the sustain level for voice 3 to maximum and search for 00048 // the waveform output value yielding the same voltage as found 00049 // above. This is done by trying out different waveform output 00050 // values until the correct value is found, e.g. with the following 00051 // program: 00052 // 00053 // lda #$08 00054 // sta $d412 00055 // lda #$0b 00056 // sta $d417 00057 // lda #$0f 00058 // sta $d418 00059 // lda #$f0 00060 // sta $d414 00061 // lda #$21 00062 // sta $d412 00063 // lda #$01 00064 // sta $d40e 00065 // 00066 // ldx #$00 00067 // lda #$38 ; Tweak this to find the "zero" level 00068 //l cmp $d41b 00069 // bne l 00070 // stx $d40e ; Stop frequency counter - freeze waveform output 00071 // brk 00072 // 00073 // The waveform output range is 0x000 to 0xfff, so the "zero" 00074 // level should ideally have been 0x800. In the measured chip, the 00075 // waveform output "zero" level was found to be 0x380 (i.e. $d41b 00076 // = 0x38) at 5.94V. 00077 00078 wave_zero = 0x380; 00079 00080 // The envelope multiplying D/A converter introduces another DC 00081 // offset. This is isolated by the following measurements: 00082 // 00083 // * The "zero" output level of the mixer at full volume is 5.44V. 00084 // * Routing one voice to the mixer at full volume yields 00085 // 6.75V at maximum voice output (wave = 0xfff, sustain = 0xf) 00086 // 5.94V at "zero" voice output (wave = any, sustain = 0x0) 00087 // 5.70V at minimum voice output (wave = 0x000, sustain = 0xf) 00088 // * The DC offset of one voice is (5.94V - 5.44V) = 0.50V 00089 // * The dynamic range of one voice is |6.75V - 5.70V| = 1.05V 00090 // * The DC offset is thus 0.50V/1.05V ~ 1/2 of the dynamic range. 00091 // 00092 // Note that by removing the DC offset, we get the following ranges for 00093 // one voice: 00094 // y > 0: (6.75V - 5.44V) - 0.50V = 0.81V 00095 // y < 0: (5.70V - 5.44V) - 0.50V = -0.24V 00096 // The scaling of the voice amplitude is not symmetric about y = 0; 00097 // this follows from the DC level in the waveform output. 00098 00099 voice_DC = 0x800*0xff; 00100 } 00101 else { 00102 // No DC offsets in the MOS8580. 00103 wave_zero = 0x800; 00104 voice_DC = 0; 00105 } 00106 } 00107 00108 // ---------------------------------------------------------------------------- 00109 // Set sync source. 00110 // ---------------------------------------------------------------------------- 00111 void Voice::set_sync_source(Voice* source) 00112 { 00113 wave.set_sync_source(&source->wave); 00114 } 00115 00116 // ---------------------------------------------------------------------------- 00117 // Register functions. 00118 // ---------------------------------------------------------------------------- 00119 void Voice::writeCONTROL_REG(reg8 control) 00120 { 00121 wave.writeCONTROL_REG(control); 00122 envelope.writeCONTROL_REG(control); 00123 } 00124 00125 // ---------------------------------------------------------------------------- 00126 // SID reset. 00127 // ---------------------------------------------------------------------------- 00128 void Voice::reset() 00129 { 00130 wave.reset(); 00131 envelope.reset(); 00132 } 00133