00001 /* 00002 * SID.h - 6581 emulation 00003 * 00004 * Frodo (C) 1994-1997 Christian Bauer 00005 */ 00006 00007 #ifndef _SID_H 00008 #define _SID_H 00009 00010 #include <stdlib.h> 00011 00012 00013 // Define this if you want an emulation of an 8580 00014 // (affects combined waveforms) 00015 #undef EMUL_MOS8580 00016 00017 00018 class Prefs; 00019 class C64; 00020 class SIDRenderer; 00021 struct MOS6581State; 00022 00023 // Class for administrative functions 00024 class MOS6581 { 00025 public: 00026 MOS6581(C64 *c64); 00027 ~MOS6581(); 00028 00029 void Reset(void); 00030 uint8 ReadRegister(uint16 adr); 00031 void WriteRegister(uint16 adr, uint8 byte); 00032 void NewPrefs(Prefs *prefs); 00033 void PauseSound(void); 00034 void ResumeSound(void); 00035 void GetState(MOS6581State *ss); 00036 void SetState(MOS6581State *ss); 00037 void EmulateLine(void); 00038 00039 private: 00040 void open_close_renderer(int old_type, int new_type); 00041 00042 C64 *the_c64; // Pointer to C64 object 00043 SIDRenderer *the_renderer; // Pointer to current renderer 00044 uint8 regs[32]; // Copies of the 25 write-only SID registers 00045 uint8 last_sid_byte; // Last value written to SID 00046 Prefs& ThePrefs; 00047 }; 00048 00049 00050 // Renderers do the actual audio data processing 00051 class SIDRenderer { 00052 public: 00053 virtual ~SIDRenderer() {} 00054 virtual void Reset(void)=0; 00055 virtual void EmulateLine(void)=0; 00056 virtual void WriteRegister(uint16 adr, uint8 byte)=0; 00057 virtual void NewPrefs(Prefs *prefs)=0; 00058 virtual void Pause(void)=0; 00059 virtual void Resume(void)=0; 00060 }; 00061 00062 00063 // SID state 00064 struct MOS6581State { 00065 uint8 freq_lo_1; 00066 uint8 freq_hi_1; 00067 uint8 pw_lo_1; 00068 uint8 pw_hi_1; 00069 uint8 ctrl_1; 00070 uint8 AD_1; 00071 uint8 SR_1; 00072 00073 uint8 freq_lo_2; 00074 uint8 freq_hi_2; 00075 uint8 pw_lo_2; 00076 uint8 pw_hi_2; 00077 uint8 ctrl_2; 00078 uint8 AD_2; 00079 uint8 SR_2; 00080 00081 uint8 freq_lo_3; 00082 uint8 freq_hi_3; 00083 uint8 pw_lo_3; 00084 uint8 pw_hi_3; 00085 uint8 ctrl_3; 00086 uint8 AD_3; 00087 uint8 SR_3; 00088 00089 uint8 fc_lo; 00090 uint8 fc_hi; 00091 uint8 res_filt; 00092 uint8 mode_vol; 00093 00094 uint8 pot_x; 00095 uint8 pot_y; 00096 uint8 osc_3; 00097 uint8 env_3; 00098 }; 00099 00100 00101 /* 00102 * Fill buffer (for Unix sound routines), sample volume (for sampled voice) 00103 */ 00104 00105 inline void MOS6581::EmulateLine(void) 00106 { 00107 if (the_renderer != NULL) 00108 the_renderer->EmulateLine(); 00109 } 00110 00111 00112 /* 00113 * Read from register 00114 */ 00115 00116 inline uint8 MOS6581::ReadRegister(uint16 adr) 00117 { 00118 // A/D converters 00119 if (adr == 0x19 || adr == 0x1a) { 00120 last_sid_byte = 0; 00121 return 0xff; 00122 } 00123 00124 // Voice 3 oscillator/EG readout 00125 if (adr == 0x1b || adr == 0x1c) { 00126 last_sid_byte = 0; 00127 return rand(); 00128 } 00129 00130 // Write-only register: Return last value written to SID 00131 return last_sid_byte; 00132 } 00133 00134 00135 /* 00136 * Write to register 00137 */ 00138 00139 inline void MOS6581::WriteRegister(uint16 adr, uint8 byte) 00140 { 00141 // Keep a local copy of the register values 00142 last_sid_byte = regs[adr] = byte; 00143 00144 if (the_renderer != NULL) 00145 the_renderer->WriteRegister(adr, byte); 00146 } 00147 00148 #endif