ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/SID_linux.h
(Generate patch)

Comparing Frodo4/Src/SID_linux.h (file contents):
Revision 1.3 by cebix, 2004-01-10T18:11:07Z vs.
Revision 1.7 by cebix, 2010-04-22T09:09:28Z

# Line 1 | Line 1
1   /*
2   *  SID_linux.h - 6581 emulation, Linux specific stuff
3   *
4 < *  Frodo (C) 1994-1997,2002-2003 Christian Bauer
4 > *  Frodo Copyright (C) Christian Bauer
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 23 | Line 23
23   #include <sys/ioctl.h>
24   #include <linux/soundcard.h>
25  
26 // Catweasel ioctls (included here for convenience)
27 #include <linux/ioctl.h>
28 #define CWSID_IOCTL_TYPE ('S')
29 #define CWSID_IOCTL_RESET        _IO(CWSID_IOCTL_TYPE, 0)
30 #define CWSID_IOCTL_CARDTYPE     _IOR(CWSID_IOCTL_TYPE, 4, int)
31 #define CWSID_IOCTL_PAL          _IO(CWSID_IOCTL_TYPE, 0x11)
32 #define CWSID_IOCTL_NTSC         _IO(CWSID_IOCTL_TYPE, 0x12)
33 #define CWSID_IOCTL_DOUBLEBUFFER _IOW(CWSID_IOCTL_TYPE, 0x21, int)
34 #define CWSID_IOCTL_DELAY        _IOW(CWSID_IOCTL_TYPE, 0x22, int)
35 #define CWSID_MAGIC 0x100
36 #define HAVE_CWSID 1
37
38 #include "VIC.h"
39
26  
27   /*
28   *  Initialization
# Line 44 | Line 30
30  
31   void DigitalRenderer::init_sound(void)
32   {
33 <    int tmp;
34 <    unsigned long format;
33 >        int arg;
34 >        unsigned long format;
35  
36 <    ready = false;
37 <    devfd = open("/dev/dsp", O_WRONLY);
38 <    if (devfd < 0)
39 <        return;
40 <
41 <    ioctl(devfd, SNDCTL_DSP_GETFMTS, &format);
42 <    if (!(format & AFMT_S16_LE))
43 <        return;
44 <    format = AFMT_S16_LE;
45 <    ioctl(devfd, SNDCTL_DSP_SETFMT, &format);
46 <            
47 <    /*
48 <     * Buffer size: 2^9 == 512 bytes. Note that too large buffers will not work
49 <     * very well: The speed of the C64 is slowed down to an average speed of
50 <     * 100% by the blocking write() call in EmulateLine(). If you use a buffer
51 <     * of, say 4096 bytes, that will happen only about every 4 frames, which
52 <     * means that the emulation runs much faster in some frames, and much
53 <     * slower in others.
54 <     * On really fast machines, it might make sense to use an even smaller
55 <     * buffer size.
56 <     */
57 <    tmp = 0x00100009;
58 <    ioctl(devfd, SNDCTL_DSP_SETFRAGMENT, &tmp);
59 <    tmp = 0;
60 <    ioctl(devfd, SNDCTL_DSP_STEREO, &tmp);
61 <    tmp = 44100;
62 <    ioctl(devfd, SNDCTL_DSP_SPEED, &tmp);
63 <    ioctl(devfd, SOUND_PCM_READ_RATE, &tmp);
64 <    if (tmp < 43000 || tmp > 45000)
65 <        return;
66 <
67 <    ioctl(devfd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize);
82 <    sound_buffer = new int16[sndbufsize];
83 <    ready = true;
36 >        ready = false;
37 >        devfd = open("/dev/dsp", O_WRONLY);
38 >        if (devfd < 0)
39 >                return;
40 >
41 >        ioctl(devfd, SNDCTL_DSP_GETFMTS, &format);
42 >        if (!(format & AFMT_S16_LE))
43 >                return;
44 >        format = AFMT_S16_LE;
45 >        ioctl(devfd, SNDCTL_DSP_SETFMT, &format);
46 >
47 >        // Buffer size: 2^9 == 512 bytes. Note that too large buffers will not work
48 >        // very well: The speed of the C64 is slowed down to an average speed of
49 >        // 100% by the blocking write() call in EmulateLine(). If you use a buffer
50 >        // of, say 4096 bytes, that will happen only about every 4 frames, which
51 >        // means that the emulation runs much faster in some frames, and much
52 >        // slower in others.
53 >        // On really fast machines, it might make sense to use an even smaller
54 >        // buffer size.
55 >        arg = 0x00100009;
56 >        ioctl(devfd, SNDCTL_DSP_SETFRAGMENT, &arg);
57 >        arg = 0;
58 >        ioctl(devfd, SNDCTL_DSP_STEREO, &arg);
59 >        arg = 44100;
60 >        ioctl(devfd, SNDCTL_DSP_SPEED, &arg);
61 >        ioctl(devfd, SOUND_PCM_READ_RATE, &arg);
62 >        if (arg < 43000 || arg > 45000)
63 >                return;
64 >
65 >        ioctl(devfd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize);
66 >        sound_buffer = new int16[sndbufsize];
67 >        ready = true;
68   }
69  
70  
# Line 90 | Line 74 | void DigitalRenderer::init_sound(void)
74  
75   DigitalRenderer::~DigitalRenderer()
76   {
77 <    if (devfd >= 0)
78 <        close(devfd);
77 >        if (devfd >= 0)
78 >                close(devfd);
79   }
80  
81  
# Line 119 | Line 103 | void DigitalRenderer::Resume(void)
103  
104   void DigitalRenderer::EmulateLine(void)
105   {
106 <    static int divisor = 0;
107 <    static int to_output = 0;
108 <    static int buffer_pos = 0;
106 >        static int divisor = 0;
107 >        static int to_output = 0;
108 >        static int buffer_pos = 0;
109  
110 <    if (!ready)
111 <        return;
110 >        if (!ready)
111 >                return;
112  
113          sample_buf[sample_in_ptr] = volume;
114          sample_in_ptr = (sample_in_ptr + 1) % SAMPLE_BUF_SIZE;
115  
116 <    /*
117 <     * Now see how many samples have to be added for this line
118 <     */
119 <    divisor += SAMPLE_FREQ;
120 <    while (divisor >= 0)
121 <        divisor -= TOTAL_RASTERS*SCREEN_FREQ, to_output++;
122 <
123 <    /*
124 <     * Calculate the sound data only when we have enough to fill
125 <     * the buffer entirely.
126 <     */
127 <    if ((buffer_pos + to_output) >= sndbufsize) {
128 <        int datalen = sndbufsize - buffer_pos;
145 <        to_output -= datalen;
146 <        calc_buffer(sound_buffer + buffer_pos, datalen*2);
147 <        write(devfd, sound_buffer, sndbufsize*2);
148 <        buffer_pos = 0;
149 <    }    
150 < }
151 <
152 <
153 < /*
154 < *  Renderer for Catweasel card
155 < */
156 <
157 < // Rendere class
158 < class CatweaselRenderer : public SIDRenderer {
159 < public:
160 <        CatweaselRenderer();
161 <        virtual ~CatweaselRenderer();
162 <
163 <        virtual void Reset(void);
164 <        virtual void EmulateLine(void) {}
165 <        virtual void WriteRegister(uint16 adr, uint8 byte);
166 <        virtual void NewPrefs(Prefs *prefs) {}
167 <        virtual void Pause(void) {}
168 <        virtual void Resume(void) {}
169 <
170 < private:
171 <        int cwsid_fh; // Catweasel device file handle
172 < };
173 <
174 < // Constructor: Open Catweasel device and reset SID
175 < CatweaselRenderer::CatweaselRenderer()
176 < {
177 <        cwsid_fh = open("/dev/sid", O_WRONLY);
178 <        if (cwsid_fh >= 0) {
179 <                int i;
180 <                if (ioctl(cwsid_fh, CWSID_IOCTL_CARDTYPE, &i) < 0 || i != CWSID_MAGIC) {
181 <                        close(cwsid_fh);
182 <                        cwsid_fh = -1;
183 <                } else {
184 <                        ioctl(cwsid_fh, CWSID_IOCTL_RESET);
185 <                        ioctl(cwsid_fh, CWSID_IOCTL_DOUBLEBUFFER, 0);
186 <                }
187 <        }
188 <
189 <        Reset();
190 < }
191 <
192 < // Destructor: Reset SID and close Catweasel device
193 < CatweaselRenderer::~CatweaselRenderer()
194 < {
195 <        Reset();
196 <
197 <        if (cwsid_fh >= 0) {
198 <                close(cwsid_fh);
199 <                cwsid_fh = -1;
200 <        }
201 < }
202 <
203 < // Reset SID
204 < void CatweaselRenderer::Reset(void)
205 < {
206 <        if (cwsid_fh >= 0) {
207 <                uint8 zero = 0;
208 <                ioctl(cwsid_fh, CWSID_IOCTL_RESET);
209 <                lseek(cwsid_fh, 24, SEEK_SET);
210 <                write(cwsid_fh, &zero, 1);
211 <        }
212 < }
213 <
214 < // Write to register
215 < void CatweaselRenderer::WriteRegister(uint16 adr, uint8 byte)
216 < {
217 <        if (cwsid_fh >= 0 && adr < 0x1a) {
218 <                lseek(cwsid_fh, adr, SEEK_SET);
219 <                write(cwsid_fh, &byte, 1);
220 <                lseek(cwsid_fh, adr, SEEK_SET);
221 <                write(cwsid_fh, &byte, 1);
116 >        // Now see how many samples have to be added for this line
117 >        divisor += SAMPLE_FREQ;
118 >        while (divisor >= 0)
119 >                divisor -= TOTAL_RASTERS*SCREEN_FREQ, to_output++;
120 >
121 >        // Calculate the sound data only when we have enough to fill
122 >        // the buffer entirely
123 >        if ((buffer_pos + to_output) >= sndbufsize) {
124 >                int datalen = sndbufsize - buffer_pos;
125 >                to_output -= datalen;
126 >                calc_buffer(sound_buffer + buffer_pos, datalen*2);
127 >                write(devfd, sound_buffer, sndbufsize*2);
128 >                buffer_pos = 0;
129          }
130   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines