1 /* 2 * SID.h - 6581 emulation 3 * 4 * Frodo (C) 1994-1997,2002 Christian Bauer 5 */ 6 7 #ifndef _SID_H 8 #define _SID_H 9 10 #include <stdlib.h> 11 12 13 // Define this if you want an emulation of an 8580 14 // (affects combined waveforms) 15 #undef EMUL_MOS8580 16 17 18 class Prefs; 19 class C64; 20 class SIDRenderer; 21 struct MOS6581State; 22 23 // Class for administrative functions 24 class MOS6581 { 25 public: 26 MOS6581(C64 *c64); 27 ~MOS6581(); 28 29 void Reset(void); 30 uint8 ReadRegister(uint16 adr); 31 void WriteRegister(uint16 adr, uint8 byte); 32 void NewPrefs(Prefs *prefs); 33 void PauseSound(void); 34 void ResumeSound(void); 35 void GetState(MOS6581State *ss); 36 void SetState(MOS6581State *ss); 37 void EmulateLine(void); 38 39 private: 40 void open_close_renderer(int old_type, int new_type); 41 42 C64 *the_c64; // Pointer to C64 object 43 SIDRenderer *the_renderer; // Pointer to current renderer 44 uint8 regs[32]; // Copies of the 25 write-only SID registers 45 uint8 last_sid_byte; // Last value written to SID 46 }; 47 48 49 // Renderers do the actual audio data processing 50 class SIDRenderer { 51 public: ~SIDRenderer()52 virtual ~SIDRenderer() {} 53 virtual void Reset(void)=0; 54 virtual void EmulateLine(void)=0; 55 virtual void WriteRegister(uint16 adr, uint8 byte)=0; 56 virtual void NewPrefs(Prefs *prefs)=0; 57 virtual void Pause(void)=0; 58 virtual void Resume(void)=0; 59 }; 60 61 62 // SID state 63 struct MOS6581State { 64 uint8 freq_lo_1; 65 uint8 freq_hi_1; 66 uint8 pw_lo_1; 67 uint8 pw_hi_1; 68 uint8 ctrl_1; 69 uint8 AD_1; 70 uint8 SR_1; 71 72 uint8 freq_lo_2; 73 uint8 freq_hi_2; 74 uint8 pw_lo_2; 75 uint8 pw_hi_2; 76 uint8 ctrl_2; 77 uint8 AD_2; 78 uint8 SR_2; 79 80 uint8 freq_lo_3; 81 uint8 freq_hi_3; 82 uint8 pw_lo_3; 83 uint8 pw_hi_3; 84 uint8 ctrl_3; 85 uint8 AD_3; 86 uint8 SR_3; 87 88 uint8 fc_lo; 89 uint8 fc_hi; 90 uint8 res_filt; 91 uint8 mode_vol; 92 93 uint8 pot_x; 94 uint8 pot_y; 95 uint8 osc_3; 96 uint8 env_3; 97 }; 98 99 100 /* 101 * Fill buffer (for Unix sound routines), sample volume (for sampled voice) 102 */ 103 EmulateLine(void)104inline void MOS6581::EmulateLine(void) 105 { 106 if (the_renderer != NULL) 107 the_renderer->EmulateLine(); 108 } 109 110 111 /* 112 * Read from register 113 */ 114 ReadRegister(uint16 adr)115inline uint8 MOS6581::ReadRegister(uint16 adr) 116 { 117 // A/D converters 118 if (adr == 0x19 || adr == 0x1a) { 119 last_sid_byte = 0; 120 return 0xff; 121 } 122 123 // Voice 3 oscillator/EG readout 124 if (adr == 0x1b || adr == 0x1c) { 125 last_sid_byte = 0; 126 return rand(); 127 } 128 129 // Write-only register: Return last value written to SID 130 return last_sid_byte; 131 } 132 133 134 /* 135 * Write to register 136 */ 137 WriteRegister(uint16 adr,uint8 byte)138inline void MOS6581::WriteRegister(uint16 adr, uint8 byte) 139 { 140 // Keep a local copy of the register values 141 last_sid_byte = regs[adr] = byte; 142 143 if (the_renderer != NULL) 144 the_renderer->WriteRegister(adr, byte); 145 } 146 147 #endif 148