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)104 inline 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)115 inline 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)138 inline 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