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.1 by cebix, 2003-07-01T17:36:32Z vs.
Revision 1.5 by cebix, 2004-12-04T13:24:35Z

# Line 1 | Line 1
1   /*
2   *  SID_linux.h - 6581 emulation, Linux specific stuff
3   *
4 < *  Frodo (C) 1994-1997,2002 Christian Bauer
4 > *  Frodo (C) 1994-1997,2002-2004 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  
40  
# Line 32 | Line 44
44  
45   void DigitalRenderer::init_sound(void)
46   {
47 <    int tmp;
48 <    unsigned long format;
47 >        int arg;
48 >        unsigned long format;
49  
50 <    ready = false;
51 <    devfd = open("/dev/dsp", O_WRONLY);
52 <    if (devfd < 0)
53 <        return;
54 <
55 <    ioctl(devfd, SNDCTL_DSP_GETFMTS, &format);
56 <    if (!(format & AFMT_S16_LE))
57 <        return;
58 <    format = AFMT_S16_LE;
59 <    ioctl(devfd, SNDCTL_DSP_SETFMT, &format);
60 <            
61 <    /*
62 <     * Buffer size: 2^9 == 512 bytes. Note that too large buffers will not work
63 <     * very well: The speed of the C64 is slowed down to an average speed of
64 <     * 100% by the blocking write() call in EmulateLine(). If you use a buffer
65 <     * of, say 4096 bytes, that will happen only about every 4 frames, which
66 <     * means that the emulation runs much faster in some frames, and much
67 <     * slower in others.
68 <     * On really fast machines, it might make sense to use an even smaller
69 <     * buffer size.
70 <     */
71 <    tmp = 0x00100009;
72 <    ioctl(devfd, SNDCTL_DSP_SETFRAGMENT, &tmp);
73 <    tmp = 0;
74 <    ioctl(devfd, SNDCTL_DSP_STEREO, &tmp);
75 <    tmp = 44100;
76 <    ioctl(devfd, SNDCTL_DSP_SPEED, &tmp);
77 <    ioctl(devfd, SOUND_PCM_READ_RATE, &tmp);
78 <    if (tmp < 43000 || tmp > 45000)
79 <        return;
80 <
81 <    ioctl(devfd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize);
70 <    sound_buffer = new int16[sndbufsize];
71 <    ready = true;
50 >        ready = false;
51 >        devfd = open("/dev/dsp", O_WRONLY);
52 >        if (devfd < 0)
53 >                return;
54 >
55 >        ioctl(devfd, SNDCTL_DSP_GETFMTS, &format);
56 >        if (!(format & AFMT_S16_LE))
57 >                return;
58 >        format = AFMT_S16_LE;
59 >        ioctl(devfd, SNDCTL_DSP_SETFMT, &format);
60 >
61 >        // Buffer size: 2^9 == 512 bytes. Note that too large buffers will not work
62 >        // very well: The speed of the C64 is slowed down to an average speed of
63 >        // 100% by the blocking write() call in EmulateLine(). If you use a buffer
64 >        // of, say 4096 bytes, that will happen only about every 4 frames, which
65 >        // means that the emulation runs much faster in some frames, and much
66 >        // slower in others.
67 >        // On really fast machines, it might make sense to use an even smaller
68 >        // buffer size.
69 >        arg = 0x00100009;
70 >        ioctl(devfd, SNDCTL_DSP_SETFRAGMENT, &arg);
71 >        arg = 0;
72 >        ioctl(devfd, SNDCTL_DSP_STEREO, &arg);
73 >        arg = 44100;
74 >        ioctl(devfd, SNDCTL_DSP_SPEED, &arg);
75 >        ioctl(devfd, SOUND_PCM_READ_RATE, &arg);
76 >        if (arg < 43000 || arg > 45000)
77 >                return;
78 >
79 >        ioctl(devfd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize);
80 >        sound_buffer = new int16[sndbufsize];
81 >        ready = true;
82   }
83  
84  
# Line 78 | Line 88 | void DigitalRenderer::init_sound(void)
88  
89   DigitalRenderer::~DigitalRenderer()
90   {
91 <    if (devfd >= 0)
92 <        close(devfd);
91 >        if (devfd >= 0)
92 >                close(devfd);
93   }
94  
95  
# Line 107 | Line 117 | void DigitalRenderer::Resume(void)
117  
118   void DigitalRenderer::EmulateLine(void)
119   {
120 <    static int divisor = 0;
121 <    static int to_output = 0;
122 <    static int buffer_pos = 0;
120 >        static int divisor = 0;
121 >        static int to_output = 0;
122 >        static int buffer_pos = 0;
123  
124 <    if (!ready)
125 <        return;
124 >        if (!ready)
125 >                return;
126  
127          sample_buf[sample_in_ptr] = volume;
128          sample_in_ptr = (sample_in_ptr + 1) % SAMPLE_BUF_SIZE;
129  
130 <    /*
131 <     * Now see how many samples have to be added for this line
132 <     */
133 <    divisor += SAMPLE_FREQ;
134 <    while (divisor >= 0)
135 <        divisor -= TOTAL_RASTERS*SCREEN_FREQ, to_output++;
136 <
137 <    /*
138 <     * Calculate the sound data only when we have enough to fill
139 <     * the buffer entirely.
140 <     */
141 <    if ((buffer_pos + to_output) >= sndbufsize) {
142 <        int datalen = sndbufsize - buffer_pos;
143 <        to_output -= datalen;
144 <        calc_buffer(sound_buffer + buffer_pos, datalen*2);
145 <        write(devfd, sound_buffer, sndbufsize*2);
146 <        buffer_pos = 0;
147 <    }    
130 >        // Now see how many samples have to be added for this line
131 >        divisor += SAMPLE_FREQ;
132 >        while (divisor >= 0)
133 >                divisor -= TOTAL_RASTERS*SCREEN_FREQ, to_output++;
134 >
135 >        // Calculate the sound data only when we have enough to fill
136 >        // the buffer entirely
137 >        if ((buffer_pos + to_output) >= sndbufsize) {
138 >                int datalen = sndbufsize - buffer_pos;
139 >                to_output -= datalen;
140 >                calc_buffer(sound_buffer + buffer_pos, datalen*2);
141 >                write(devfd, sound_buffer, sndbufsize*2);
142 >                buffer_pos = 0;
143 >        }
144 > }
145 >
146 >
147 > /*
148 > *  Renderer for Catweasel card
149 > */
150 >
151 > // Renderer class
152 > class CatweaselRenderer : public SIDRenderer {
153 > public:
154 >        CatweaselRenderer();
155 >        virtual ~CatweaselRenderer();
156 >
157 >        virtual void Reset(void);
158 >        virtual void EmulateLine(void) {}
159 >        virtual void WriteRegister(uint16 adr, uint8 byte);
160 >        virtual void NewPrefs(Prefs *prefs) {}
161 >        virtual void Pause(void) {}
162 >        virtual void Resume(void) {}
163 >
164 > private:
165 >        int cwsid_fh; // Catweasel device file handle
166 > };
167 >
168 > // Constructor: Open Catweasel device and reset SID
169 > CatweaselRenderer::CatweaselRenderer()
170 > {
171 >        cwsid_fh = open("/dev/sid", O_WRONLY);
172 >        if (cwsid_fh >= 0) {
173 >                int i;
174 >                if (ioctl(cwsid_fh, CWSID_IOCTL_CARDTYPE, &i) < 0 || i != CWSID_MAGIC) {
175 >                        close(cwsid_fh);
176 >                        cwsid_fh = -1;
177 >                } else {
178 >                        ioctl(cwsid_fh, CWSID_IOCTL_RESET);
179 >                        ioctl(cwsid_fh, CWSID_IOCTL_DOUBLEBUFFER, 0);
180 >                }
181 >        }
182 >
183 >        Reset();
184 > }
185 >
186 > // Destructor: Reset SID and close Catweasel device
187 > CatweaselRenderer::~CatweaselRenderer()
188 > {
189 >        Reset();
190 >
191 >        if (cwsid_fh >= 0) {
192 >                close(cwsid_fh);
193 >                cwsid_fh = -1;
194 >        }
195 > }
196 >
197 > // Reset SID
198 > void CatweaselRenderer::Reset(void)
199 > {
200 >        if (cwsid_fh >= 0) {
201 >                uint8 zero = 0;
202 >                ioctl(cwsid_fh, CWSID_IOCTL_RESET);
203 >                lseek(cwsid_fh, 24, SEEK_SET);
204 >                write(cwsid_fh, &zero, 1);
205 >        }
206 > }
207 >
208 > // Write to register
209 > void CatweaselRenderer::WriteRegister(uint16 adr, uint8 byte)
210 > {
211 >        if (cwsid_fh >= 0 && adr < 0x1a) {
212 >                lseek(cwsid_fh, adr, SEEK_SET);
213 >                write(cwsid_fh, &byte, 1);
214 >                lseek(cwsid_fh, adr, SEEK_SET);
215 >                write(cwsid_fh, &byte, 1);
216 >        }
217   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines