Previous 199869 Revisions Next

r31131 Saturday 28th June, 2014 at 01:44:50 UTC by R. Belmont
(MESS) Apple II: Support for the Mountain Computer Music System. [R. Belmont]
[src/emu/bus]bus.mak
[src/emu/bus/a2bus]a2bus.h a2mcms.c* a2mcms.h*
[src/mess/drivers]apple2.c

trunk/src/emu/bus/bus.mak
r31130r31131
699699BUSOBJS += $(BUSOBJ)/a2bus/a2eramworks3.o
700700BUSOBJS += $(BUSOBJ)/a2bus/a2corvus.o
701701BUSOBJS += $(BUSOBJ)/a2bus/a2diskiing.o
702BUSOBJS += $(BUSOBJ)/a2bus/a2mcms.o
702703endif
703704
704705#-------------------------------------------------
trunk/src/emu/bus/a2bus/a2bus.h
r31130r31131
1// license:BSD-3-Clause
2// copyright-holders:R. Belmont
13/***************************************************************************
24
35  a2bus.h - Apple II slot bus and card emulation
r31130r31131
7577// ======================> a2bus_device
7678class a2bus_device : public device_t
7779{
80   // multi-card devices need to access m_device_list, so they get friend'ed here.
81   friend class a2bus_mcms2_device;
7882public:
7983   // construction/destruction
8084   a2bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
trunk/src/emu/bus/a2bus/a2mcms.c
r0r31131
1// license:BSD-3-Clause
2// copyright-holders:R. Belmont
3/*********************************************************************
4
5    a2mcms.c
6
7    Implementation of the Mountain Computer Music System.
8    This was sold standalone and also used as part of the alphaSyntauri
9    and SoundChaser systems.
10 
11*********************************************************************/
12
13#include "a2mcms.h"
14#include "includes/apple2.h"
15
16// the actual sound device (a slot device can't currently also be a sound device so we keep this private here)
17enum
18{
19   CTRL_IRQS = 0,
20   CTRL_DMA,
21   CTRL_MASTERVOL
22};
23
24
25class mcms_device : public device_t, public device_sound_interface
26{
27public:
28   // construction/destruction
29   mcms_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
30
31   DECLARE_WRITE8_MEMBER(voiceregs_w);
32   DECLARE_WRITE8_MEMBER(control_w);
33   UINT8 get_pen_rand(void) { m_stream->update(); return m_rand; }
34
35   template<class _Object> static devcb_base &set_irq_cb(device_t &device, _Object wr) { return downcast<mcms_device &>(device).m_write_irq.set_callback(wr); }
36   devcb_write_line m_write_irq;
37
38protected:
39   // device-level overrides
40   virtual void device_start();
41   virtual void device_reset();
42   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
43
44   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
45
46private:
47   sound_stream *m_stream;
48   address_space *m_6502space;
49   emu_timer *m_timer, *m_clrtimer;
50   bool m_enabled;
51   UINT8 m_vols[16];
52   UINT8 m_table[16];
53   UINT16 m_freq[16];
54   UINT16 m_acc[16];
55   UINT8 m_mastervol;
56   UINT8 m_rand;
57};
58
59const device_type MCMS = &device_creator<mcms_device>;
60
61/***************************************************************************
62    PARAMETERS
63***************************************************************************/
64
65//**************************************************************************
66//  GLOBAL VARIABLES
67//**************************************************************************
68
69const device_type A2BUS_MCMS1 = &device_creator<a2bus_mcms1_device>;
70const device_type A2BUS_MCMS2 = &device_creator<a2bus_mcms2_device>;
71
72#define ENGINE_TAG   "engine"
73
74#define MCFG_MCMS_IRQ_CALLBACK(_cb) \
75   devcb = &mcms_device::set_irq_cb(*device, DEVCB_##_cb);
76
77MACHINE_CONFIG_FRAGMENT( a2mcms )
78   MCFG_SPEAKER_STANDARD_STEREO("mcms_l", "mcms_r")
79
80   MCFG_DEVICE_ADD(ENGINE_TAG, MCMS, 1000000)
81   MCFG_MCMS_IRQ_CALLBACK(WRITELINE(a2bus_mcms1_device, irq_w))
82
83   MCFG_SOUND_ROUTE(0, "mcms_l", 1.0)
84   MCFG_SOUND_ROUTE(1, "mcms_r", 1.0)
85MACHINE_CONFIG_END
86
87/***************************************************************************
88    FUNCTION PROTOTYPES
89***************************************************************************/
90
91//-------------------------------------------------
92//  machine_config_additions - device-specific
93//  machine configurations
94//-------------------------------------------------
95
96machine_config_constructor a2bus_mcms1_device::device_mconfig_additions() const
97{
98   return MACHINE_CONFIG_NAME( a2mcms );
99}
100
101//**************************************************************************
102//  LIVE DEVICE - Card 1
103//**************************************************************************
104
105a2bus_mcms1_device::a2bus_mcms1_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
106   device_t(mconfig, type, name, tag, owner, clock, shortname, source),
107   device_a2bus_card_interface(mconfig, *this),
108   m_mcms(*this, ENGINE_TAG)
109{
110}
111
112a2bus_mcms1_device::a2bus_mcms1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
113   device_t(mconfig, A2BUS_MCMS1, "Mountain Computer Music System (card 1)", tag, owner, clock, "a2mcms1", __FILE__),
114   device_a2bus_card_interface(mconfig, *this),
115   m_mcms(*this, ENGINE_TAG)
116{
117}
118
119//-------------------------------------------------
120//  device_start - device-specific startup
121//-------------------------------------------------
122
123void a2bus_mcms1_device::device_start()
124{
125   // set_a2bus_device makes m_slot valid
126   set_a2bus_device();
127}
128
129void a2bus_mcms1_device::device_reset()
130{
131}
132
133// read once at c0n0 to disable 125 Hz IRQs
134// read once at c0n1 to enable 125 Hz IRQs
135UINT8 a2bus_mcms1_device::read_c0nx(address_space &space, UINT8 offset)
136{
137   if (offset == 0)
138   {
139      m_mcms->control_w(space, CTRL_IRQS, 0);
140   }
141   else if (offset == 1)
142   {
143      m_mcms->control_w(space, CTRL_IRQS, 1);
144   }
145
146   return 0xff;
147}
148
149// read at Cn00: light gun in bit 7, bits 0-5 = 'random' number
150UINT8 a2bus_mcms1_device::read_cnxx(address_space &space, UINT8 offset)
151{
152   return m_mcms->get_pen_rand();
153}
154
155// write 0-255 to Cn00 to set the master volume
156void a2bus_mcms1_device::write_cnxx(address_space &space, UINT8 offset, UINT8 data)
157{
158   if (offset == 0)
159   {
160      m_mcms->control_w(space, CTRL_MASTERVOL, data);
161   }
162}
163
164mcms_device *a2bus_mcms1_device::get_engine(void)
165{
166   return m_mcms;
167}   
168
169WRITE_LINE_MEMBER(a2bus_mcms1_device::irq_w)
170{
171   if (state == ASSERT_LINE)
172   {
173      raise_slot_irq();
174   }
175   else
176   {
177      lower_slot_irq();
178   }
179}
180
181//**************************************************************************
182//  LIVE DEVICE - Card 2
183//**************************************************************************
184
185a2bus_mcms2_device::a2bus_mcms2_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
186   device_t(mconfig, type, name, tag, owner, clock, shortname, source),
187   device_a2bus_card_interface(mconfig, *this)
188{
189}
190
191a2bus_mcms2_device::a2bus_mcms2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
192   device_t(mconfig, A2BUS_MCMS2, "Mountain Computer Music System (card 2)", tag, owner, clock, "a2mcms2", __FILE__),
193   device_a2bus_card_interface(mconfig, *this)
194{
195}
196
197//-------------------------------------------------
198//  device_start - device-specific startup
199//-------------------------------------------------
200
201void a2bus_mcms2_device::device_start()
202{
203   // set_a2bus_device makes m_slot valid
204   set_a2bus_device();
205
206   if (m_slot < 2)
207   {
208      fatalerror("MCMS: Card 2 must be in slot 2 or greater\n");
209   }
210}
211
212void a2bus_mcms2_device::device_reset()
213{
214   m_card1 = static_cast<a2bus_mcms1_device *>(m_a2bus->m_device_list[m_slot-1]);
215   m_engine = m_card1->get_engine();
216}
217
218// here to soak up false reads from indexed accesses
219UINT8 a2bus_mcms2_device::read_c0nx(address_space &space, UINT8 offset)
220{
221   return 0xff;
222}
223
224// write once to c0n0 to disable the card (reset also disables)
225// write twice to c0n1 to enable the card (value doesn't matter)
226void a2bus_mcms2_device::write_c0nx(address_space &space, UINT8 offset, UINT8 data)
227{
228   if (offset == 0)
229   {
230      m_engine->control_w(space, CTRL_DMA, 0);
231   }
232   else if (offset == 1)
233   {
234      m_engine->control_w(space, CTRL_DMA, 1);
235   }
236}
237
238void a2bus_mcms2_device::write_cnxx(address_space &space, UINT8 offset, UINT8 data)
239{
240   m_engine->voiceregs_w(space, offset, data);
241}
242
243
244/*
245   Sound device implementation
246*/
247
248mcms_device::mcms_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
249   : device_t(mconfig, MCMS, "Mountain Computer Music System engine", tag, owner, clock, "msmseng", __FILE__),
250   device_sound_interface(mconfig, *this),
251   m_write_irq(*this)
252{
253}
254
255void mcms_device::device_start()
256{
257   m_write_irq.resolve();
258   m_stream = machine().sound().stream_alloc(*this, 0, 2, 31250);
259   m_timer = timer_alloc(0, NULL);
260   m_clrtimer = timer_alloc(1, NULL);
261   m_enabled = false;
262   memset(m_vols, 0, sizeof(m_vols));
263   memset(m_table, 0, sizeof(m_table));
264   memset(m_freq, 0, sizeof(m_freq));
265   memset(m_acc, 0, sizeof(m_acc));
266
267   // the card detect programs volumes and wavetable page but not freq and expects the accumulator to increment
268   for (int i = 0; i < 16; i++)
269   {
270      m_freq[i] = 0x0040;
271   }
272
273   save_item(NAME(m_enabled));
274   save_item(NAME(m_vols));
275   save_item(NAME(m_table));
276   save_item(NAME(m_freq));
277   save_item(NAME(m_acc));
278   save_item(NAME(m_mastervol));
279   save_item(NAME(m_rand));
280}
281
282void mcms_device::device_reset()
283{
284   m_write_irq(CLEAR_LINE);
285   m_timer->adjust(attotime::never);
286   m_clrtimer->adjust(attotime::never);
287   m_enabled = false;
288}
289
290void mcms_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
291{
292   if (tid == 0)
293   {
294      m_write_irq(ASSERT_LINE);
295      // clear this IRQ in 10 cycles (?)
296      m_clrtimer->adjust(attotime::from_usec(10), 0);
297   }
298   else if (tid == 1)
299   {
300      m_write_irq(CLEAR_LINE);
301   }
302}
303
304void mcms_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
305{
306   stream_sample_t *outL, *outR;
307   int i, v;
308   UINT16 wptr;
309   INT8 sample;
310   INT32 mixL, mixR;
311
312   outL = outputs[1];
313   outR = outputs[0];
314
315   if (m_enabled)
316   {
317      for (i = 0; i < samples; i++)
318      {
319         mixL = mixR = 0;
320
321         for (v = 0; v < 16; v++)
322         {
323            m_acc[v] += m_freq[v];
324            wptr = (m_table[v]<<8) | (m_acc[v]>>8);
325            m_rand = (m_acc[v]>>8) & 0x1f;
326
327            sample = (m_6502space->read_byte(wptr) ^ 0x80);
328            if (v & 1)
329            {
330               mixL += sample * m_vols[v];
331            }
332            else
333            {
334               mixR += sample * m_vols[v];
335            }
336         }
337
338         outL[i] = (mixL * m_mastervol)>>9;
339         outR[i] = (mixR * m_mastervol)>>9;
340      }
341   }
342   else
343   {
344      for (i = 0; i < samples; i++)
345      {
346         outL[i] = outR[i] = 0;
347      }
348   }
349}
350
351WRITE8_MEMBER(mcms_device::voiceregs_w)
352{
353   m_stream->update();
354   if (offset >= 0x20)
355   {
356      if (offset & 1)   // amp
357      {
358         m_vols[(offset-0x21)/2] = data;
359      }
360      else   // wavetable page
361      {
362         m_table[(offset-0x20)/2] = data;
363      }
364   }
365   else
366   {
367      if (offset & 1)   // freq L
368      {
369         if (offset == 0x1f)
370         {
371            m_freq[0] &= 0xff00;
372            m_freq[0] |= data;
373         }
374         else
375         {
376            int reg = (offset/2)+1;
377            m_freq[reg] &= 0xff00;
378            m_freq[reg] |= data;
379         }
380      }
381      else   // freq H
382      {
383         int reg = (offset/2);
384         m_freq[reg] &= 0x00ff;
385         m_freq[reg] |= (data<<8);
386      }
387   }
388}
389
390WRITE8_MEMBER(mcms_device::control_w)
391{
392   // keep the space (TODO: we need to define a formal DMA mechanism from machine/apple2 out to the slots)
393   m_6502space = &space;
394
395   m_stream->update();
396
397   switch (offset)
398   {
399      case CTRL_IRQS:
400         if (data == 0)
401         {
402            m_timer->adjust(attotime::never);
403         }
404         else
405         {
406            m_timer->adjust(attotime::zero, 0, attotime::from_hz(125));
407         }
408         break;
409
410      case CTRL_DMA:
411         m_enabled = (data == 0) ? false : true;
412         break;
413
414      case CTRL_MASTERVOL:
415         m_mastervol = data;
416         break;
417   }
418}
419
Property changes on: trunk/src/emu/bus/a2bus/a2mcms.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/bus/a2bus/a2mcms.h
r0r31131
1// license:BSD-3-Clause
2// copyright-holders:R. Belmont
3/*********************************************************************
4
5    a2mcms.h
6
7    Implementation of the Mountain Computer Music System.
8    This was sold standalone and also used as part of the alphaSyntauri
9    and SoundChaser systems.
10
11*********************************************************************/
12
13#ifndef __A2BUS_MCMS__
14#define __A2BUS_MCMS__
15
16#include "emu.h"
17#include "a2bus.h"
18
19//**************************************************************************
20//  TYPE DEFINITIONS
21//**************************************************************************
22
23// forward declaration
24class mcms_device;
25
26// card 1
27class a2bus_mcms1_device:
28   public device_t,
29   public device_a2bus_card_interface
30{
31public:
32   // construction/destruction
33   a2bus_mcms1_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
34   a2bus_mcms1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
35
36   // optional information overrides
37   virtual machine_config_constructor device_mconfig_additions() const;
38
39   // comms from card 2 (oscillator parameter writes)
40   mcms_device *get_engine(void);
41
42   DECLARE_WRITE_LINE_MEMBER(irq_w);
43
44   required_device<mcms_device> m_mcms;
45
46protected:
47   virtual void device_start();
48   virtual void device_reset();
49
50   // overrides of standard a2bus slot functions
51   virtual UINT8 read_c0nx(address_space &space, UINT8 offset);
52   virtual UINT8 read_cnxx(address_space &space, UINT8 offset);
53   virtual void write_cnxx(address_space &space, UINT8 offset, UINT8 data);
54   virtual bool take_c800() { return false; }
55};
56
57// card 2
58class a2bus_mcms2_device:
59   public device_t,
60   public device_a2bus_card_interface
61{
62public:
63   // construction/destruction
64   a2bus_mcms2_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
65   a2bus_mcms2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
66
67protected:
68   virtual void device_start();
69   virtual void device_reset();
70
71   // overrides of standard a2bus slot functions
72   virtual UINT8 read_c0nx(address_space &space, UINT8 offset);
73   virtual void write_c0nx(address_space &space, UINT8 offset, UINT8 data);
74   virtual void write_cnxx(address_space &space, UINT8 offset, UINT8 data);
75   virtual bool take_c800() { return false; }
76
77private:
78   a2bus_mcms1_device *m_card1;   // card 1 for passthrough
79   class mcms_device *m_engine;
80};
81
82// device type definition
83extern const device_type A2BUS_MCMS1;
84extern const device_type A2BUS_MCMS2;
85
86#endif /* __A2BUS_MCMS__ */
Property changes on: trunk/src/emu/bus/a2bus/a2mcms.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/drivers/apple2.c
r31130r31131
212212#include "bus/a2bus/a2ultraterm.h"
213213#include "bus/a2bus/a2pic.h"
214214#include "bus/a2bus/a2corvus.h"
215#include "bus/a2bus/a2mcms.h"
215216#include "bus/a2bus/a2estd80col.h"
216217#include "bus/a2bus/a2eext80col.h"
217218#include "bus/a2bus/a2eramworks3.h"
r31130r31131
977978   SLOT_INTERFACE("aevm80", A2BUS_VTC2)    /* Applied Engineering ViewMaster 80 */
978979   SLOT_INTERFACE("parallel", A2BUS_PIC)   /* Apple Parallel Interface Card */
979980   SLOT_INTERFACE("corvus", A2BUS_CORVUS)  /* Corvus flat-cable HDD interface (must go in slot 6) */
981   SLOT_INTERFACE("mcms1", A2BUS_MCMS1)  /* Mountain Computer Music System, card 1 of 2 */
982   SLOT_INTERFACE("mcms2", A2BUS_MCMS2)  /* Mountain Computer Music System, card 2 of 2.  must be in card 1's slot + 1! */
980983SLOT_INTERFACE_END
981984
982985static SLOT_INTERFACE_START(apple2eaux_cards)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team