Previous 199869 Revisions Next

r21542 Saturday 2nd March, 2013 at 20:41:12 UTC by Sandro Ronco
(MESS) modernized socrates sound device. (nw)
[src/mess/audio]socrates.c socrates.h
[src/mess/drivers]socrates.c

trunk/src/mess/drivers/socrates.c
r21541r21542
652652
653653WRITE8_MEMBER(socrates_state::socrates_sound_w)
654654{
655   device_t *socr_snd = machine().device("soc_snd");
656655   switch(offset)
657656   {
658657      case 0:
659      socrates_snd_reg0_w(socr_snd, data);
658      m_sound->reg0_w(data);
660659      break;
661660      case 1:
662      socrates_snd_reg1_w(socr_snd, data);
661      m_sound->reg1_w(data);
663662      break;
664663      case 2:
665      socrates_snd_reg2_w(socr_snd, data);
664      m_sound->reg2_w(data);
666665      break;
667666      case 3:
668      socrates_snd_reg3_w(socr_snd, data);
667      m_sound->reg3_w(data);
669668      break;
670669      case 4: case 5: case 6: case 7: default:
671      socrates_snd_reg4_w(socr_snd, data);
670      m_sound->reg4_w(data);
672671      break;
673672   }
674673}
r21541r21542
942941
943942   /* sound hardware */
944943   MCFG_SPEAKER_STANDARD_MONO("mono")
945   MCFG_SOUND_ADD("soc_snd", SOCRATES, XTAL_21_4772MHz/(512+256)) // this is correct, as strange as it sounds.
944   MCFG_SOUND_ADD("soc_snd", SOCRATES_SOUND, XTAL_21_4772MHz/(512+256)) // this is correct, as strange as it sounds.
946945   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
947946
948947   MCFG_CARTSLOT_ADD("cart")
r21541r21542
976975
977976   /* sound hardware */
978977   MCFG_SPEAKER_STANDARD_MONO("mono")
979   MCFG_SOUND_ADD("soc_snd", SOCRATES, XTAL_26_601712MHz/(512+256)) // TODO: verify divider for pal mode
978   MCFG_SOUND_ADD("soc_snd", SOCRATES_SOUND, XTAL_26_601712MHz/(512+256)) // TODO: verify divider for pal mode
980979   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
981980
982981   MCFG_CARTSLOT_ADD("cart")
r21541r21542
997996    MCFG_SCREEN_SIZE(264, 256) // technically the screen size is 256x228 but super painter abuses what I suspect is a hardware bug to display repeated pixels of the very last pixel beyond this horizontal space, well into hblank
998997    MCFG_SCREEN_VISIBLE_AREA(0, 263, 0, 256) // the last few rows are usually cut off by the screen bottom but are indeed displayed if you mess with v-hold
999998    MCFG_SCREEN_UPDATE_DRIVER(socrates_state, screen_update_socrates)
1000    MCFG_SOUND_REPLACE("soc_snd", SOCRATES, XTAL_26_601712MHz/(512+256)) // this is correct, as strange as it sounds.
999    MCFG_SOUND_REPLACE("soc_snd", SOCRATES_SOUND, XTAL_26_601712MHz/(512+256)) // this is correct, as strange as it sounds.
10011000    MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
10021001MACHINE_CONFIG_END
10031002*/
trunk/src/mess/audio/socrates.c
r21541r21542
1010#include "emu.h"
1111#include "socrates.h"
1212
13struct SocratesASIC
13
14// device type definition
15const device_type SOCRATES_SOUND = &device_creator<socrates_snd_device>;
16
17
18//-------------------------------------------------
19//  socrates_snd_device - constructor
20//-------------------------------------------------
21
22socrates_snd_device::socrates_snd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
23   : device_t(mconfig, SOCRATES_SOUND, "Socrates Sound", tag, owner, clock),
24   device_sound_interface(mconfig, *this)
1425{
15   sound_stream *stream;
16   UINT8 freq[2]; /* channel 1,2 frequencies */
17   UINT8 vol[2]; /* channel 1,2 volume */
18   UINT8 enable[2]; /* channel 1,2 enable */
19   UINT8 channel3; /* channel 3 weird register */
20   UINT8 state[3]; /* output states for channels 1,2,3 */
21   UINT8 accum[3]; /* accumulators for channels 1,2,3 */
22   UINT16 DAC_output; /* output */
23};
26}
2427
2528
26INLINE SocratesASIC *get_safe_token(device_t *device)
29//-------------------------------------------------
30//  device_start - device-specific startup
31//-------------------------------------------------
32
33void socrates_snd_device::device_start()
2734{
28   assert(device != NULL);
29   assert(device->type() == SOCRATES);
30   return (SocratesASIC *)downcast<socrates_snd_device *>(device)->token();
35   m_freq[0] = m_freq[1] = 0xff; /* channel 1,2 frequency */
36   m_vol[0] = m_vol[1] = 0x07; /* channel 1,2 volume */
37   m_enable[0] = m_enable[1] = 0x01; /* channel 1,2 enable */
38   m_channel3 = 0x00; /* channel 3 weird register */
39   m_DAC_output = 0x00; /* output */
40   m_state[0] = m_state[1] = m_state[2] = 0;
41   m_accum[0] = m_accum[1] = m_accum[2] = 0xFF;
42   m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() ? clock() : machine().sample_rate(), this);
3143}
3244
33static const UINT8 volumeLUT[16] =
45
46//-------------------------------------------------
47//  sound_stream_update - handle a stream update
48//-------------------------------------------------
49
50void socrates_snd_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
3451{
52   for (int i = 0; i < samples; i++)
53   {
54      snd_clock();
55      outputs[0][i] = ((int)m_DAC_output<<4);
56   }
57}
58
59
60const UINT8 socrates_snd_device::s_volumeLUT[16] =
61{
35620, 61, 100, 132, 158, 183, 201, 218,
3663233, 242, 253, 255, 250, 240, 224, 211
3764}; // this table is actually quite weird on the real console.
3865// 0, 0.033, 0.055, 0.07175, 0.086, 0.1, 0.11, 0.119, 0.127, 0.132, 0.138, 0.139, 0.136, 0.131, 0.122, 0.115 are the voltage amplitudes for the steps on channel 2. the last four are particularly bizarre, probably caused by some sort of internal clipping.
39static void socrates_snd_clock(SocratesASIC *chip) /* called once per clock */
66
67void socrates_snd_device::snd_clock() /* called once per clock */
4068{
41   int channel;
42   for (channel = 0; channel < 2; channel++)
69   for (int channel = 0; channel < 2; channel++)
4370   {
44      if ((chip->accum[channel] == 0) && chip->enable[channel])
71      if ((m_accum[channel] == 0) && m_enable[channel])
4572      {
46      chip->state[channel] = (chip->state[channel]^0x1);
47      chip->accum[channel] = chip->freq[channel];
73         m_state[channel] = (m_state[channel]^0x1);
74         m_accum[channel] = m_freq[channel];
4875      }
49      else if (chip->enable[channel])
76      else if (m_enable[channel])
5077      {
51      chip->accum[channel]--;
78         m_accum[channel]--;
5279      }
5380      else
5481      {
55      chip->accum[channel] = 0; // channel is disabled
56      chip->state[channel] = 0;
82         m_accum[channel] = 0; // channel is disabled
83         m_state[channel] = 0;
5784      }
5885   }
5986   // handle channel 3 here
60   chip->DAC_output = (chip->state[0]?(volumeLUT[chip->vol[0]]*9.4):0); // channel 1 is ~2.4 times as loud as channel 2
61   chip->DAC_output += (chip->state[1]?(volumeLUT[chip->vol[1]]<<2):0);
87   m_DAC_output = (m_state[0]?(s_volumeLUT[m_vol[0]]*9.4):0); // channel 1 is ~2.4 times as loud as channel 2
88   m_DAC_output += (m_state[1]?(s_volumeLUT[m_vol[1]]<<2):0);
6289   // add channel 3 to dac output here
6390}
6491
65/*************************************
66 *
67 *  Stream updater
68 *
69 *************************************/
70static STREAM_UPDATE( socrates_snd_pcm_update )
71{
72   SocratesASIC *chip = (SocratesASIC *)param;
73   int i;
7492
75   for (i = 0; i < samples; i++)
76   {
77      socrates_snd_clock(chip);
78      outputs[0][i] = ((int)chip->DAC_output<<4);
79   }
80}
81
82
83
84/*************************************
85 *
86 *  Sound handler start
87 *
88 *************************************/
89
90static DEVICE_START( socrates_snd )
93void socrates_snd_device::reg0_w(int data)
9194{
92   SocratesASIC *chip = get_safe_token(device);
93   chip->freq[0] = chip->freq[1] = 0xff; /* channel 1,2 frequency */
94   chip->vol[0] = chip->vol[1] = 0x07; /* channel 1,2 volume */
95   chip->enable[0] = chip->enable[1] = 0x01; /* channel 1,2 enable */
96   chip->channel3 = 0x00; /* channel 3 weird register */
97   chip->DAC_output = 0x00; /* output */
98   chip->state[0] = chip->state[1] = chip->state[2] = 0;
99   chip->accum[0] = chip->accum[1] = chip->accum[2] = 0xFF;
100   chip->stream = device->machine().sound().stream_alloc(*device, 0, 1, device->clock() ? device->clock() : device->machine().sample_rate(), chip, socrates_snd_pcm_update);
95   m_stream->update();
96   m_freq[0] = data;
10197}
10298
103
104void socrates_snd_reg0_w(device_t *device, int data)
99void socrates_snd_device::reg1_w(int data)
105100{
106   SocratesASIC *chip = get_safe_token(device);
107   chip->stream->update();
108   chip->freq[0] = data;
101   m_stream->update();
102   m_freq[1] = data;
109103}
110104
111void socrates_snd_reg1_w(device_t *device, int data)
105void socrates_snd_device::reg2_w(int data)
112106{
113   SocratesASIC *chip = get_safe_token(device);
114   chip->stream->update();
115   chip->freq[1] = data;
107   m_stream->update();
108   m_vol[0] = data&0xF;
109   m_enable[0] = (data&0x10)>>4;
116110}
117111
118void socrates_snd_reg2_w(device_t *device, int data)
112void socrates_snd_device::reg3_w(int data)
119113{
120   SocratesASIC *chip = get_safe_token(device);
121   chip->stream->update();
122   chip->vol[0] = data&0xF;
123   chip->enable[0] = (data&0x10)>>4;
114   m_stream->update();
115   m_vol[1] = data&0xF;
116   m_enable[1] = (data&0x10)>>4;
124117}
125118
126void socrates_snd_reg3_w(device_t *device, int data)
119void socrates_snd_device::reg4_w(int data)
127120{
128   SocratesASIC *chip = get_safe_token(device);
129   chip->stream->update();
130   chip->vol[1] = data&0xF;
131   chip->enable[1] = (data&0x10)>>4;
121   m_stream->update();
122   m_channel3 = data;
132123}
133
134void socrates_snd_reg4_w(device_t *device, int data)
135{
136   SocratesASIC *chip = get_safe_token(device);
137   chip->stream->update();
138   chip->channel3 = data;
139}
140
141
142/**************************************************************************
143 * Generic get_info
144 **************************************************************************/
145
146const device_type SOCRATES = &device_creator<socrates_snd_device>;
147
148socrates_snd_device::socrates_snd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
149   : device_t(mconfig, SOCRATES, "Socrates Sound", tag, owner, clock),
150      device_sound_interface(mconfig, *this)
151{
152   m_token = global_alloc_clear(SocratesASIC);
153}
154
155//-------------------------------------------------
156//  device_config_complete - perform any
157//  operations now that the configuration is
158//  complete
159//-------------------------------------------------
160
161void socrates_snd_device::device_config_complete()
162{
163}
164
165//-------------------------------------------------
166//  device_start - device-specific startup
167//-------------------------------------------------
168
169void socrates_snd_device::device_start()
170{
171   DEVICE_START_NAME( socrates_snd )(this);
172}
173
174//-------------------------------------------------
175//  sound_stream_update - handle a stream update
176//-------------------------------------------------
177
178void socrates_snd_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
179{
180   // should never get here
181   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
182}
trunk/src/mess/audio/socrates.h
r21541r21542
33#ifndef __SOCR_SND_H__
44#define __SOCR_SND_H__
55
6void socrates_snd_reg0_w(device_t *device, int data);
7void socrates_snd_reg1_w(device_t *device, int data);
8void socrates_snd_reg2_w(device_t *device, int data);
9void socrates_snd_reg3_w(device_t *device, int data);
10void socrates_snd_reg4_w(device_t *device, int data);
11
126class socrates_snd_device : public device_t,
13                           public device_sound_interface
7                     public device_sound_interface
148{
159public:
1610   socrates_snd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
17   ~socrates_snd_device() { global_free(m_token); }
1811
19   // access to legacy token
20   void *token() const { assert(m_token != NULL); return m_token; }
12   void reg0_w(int data);
13   void reg1_w(int data);
14   void reg2_w(int data);
15   void reg3_w(int data);
16   void reg4_w(int data);
17
2118protected:
2219   // device-level overrides
23   virtual void device_config_complete();
2420   virtual void device_start();
2521
2622   // sound stream update overrides
2723   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
2824private:
25   void snd_clock();
26   static const UINT8 s_volumeLUT[];
27
2928   // internal state
30   void *m_token;
29   sound_stream *  m_stream;
30   UINT8           m_freq[2];      // channel 1,2 frequencies
31   UINT8           m_vol[2];       // channel 1,2 volume
32   UINT8           m_enable[2];    // channel 1,2 enable
33   UINT8           m_channel3;     // channel 3 weird register
34   UINT8           m_state[3];     // output states for channels 1,2,3
35   UINT8           m_accum[3];     // accumulators for channels 1,2,3
36   UINT16          m_DAC_output;   // output
3137};
3238
33extern const device_type SOCRATES;
39extern const device_type SOCRATES_SOUND;
3440
3541
3642#endif /* __SOCR_SND_H__ */

Previous 199869 Revisions Next


© 1997-2024 The MAME Team