Previous 199869 Revisions Next

r19902 Friday 28th December, 2012 at 17:40:55 UTC by Andrew Gardner
Modernize the SegaPCM sound device. [Andrew Gardner]

Out of whatsnew:
Modernizing the QSound device has proven tricky, so I did this one just to make
sure my approach isn't wrong.  SegaPCM modernized fine, so I'm guessing the
modernized QSound device has some state that isn't getting cleared or something.
[src/emu/sound]segapcm.c segapcm.h
[src/mame/drivers]segahang.c segaorun.c segaxbd.c segaybd.c

trunk/src/mame/drivers/segaxbd.c
r19901r19902
961961static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, segaxbd_state )
962962   ADDRESS_MAP_UNMAP_HIGH
963963   AM_RANGE(0x0000, 0xefff) AM_ROM
964   AM_RANGE(0xf000, 0xf0ff) AM_MIRROR(0x0700) AM_DEVREADWRITE_LEGACY("pcm", sega_pcm_r, sega_pcm_w)
964   AM_RANGE(0xf000, 0xf0ff) AM_MIRROR(0x0700) AM_DEVREADWRITE("pcm", segapcm_device, sega_pcm_r, sega_pcm_w)
965965   AM_RANGE(0xf800, 0xffff) AM_RAM
966966ADDRESS_MAP_END
967967
r19901r19902
984984static ADDRESS_MAP_START( smgp_sound2_map, AS_PROGRAM, 8, segaxbd_state )
985985   ADDRESS_MAP_UNMAP_HIGH
986986   AM_RANGE(0x0000, 0xefff) AM_ROM
987   AM_RANGE(0xf000, 0xf0ff) AM_MIRROR(0x0700) AM_DEVREADWRITE_LEGACY("pcm2", sega_pcm_r, sega_pcm_w)
987   AM_RANGE(0xf000, 0xf0ff) AM_MIRROR(0x0700) AM_DEVREADWRITE("pcm2", segapcm_device, sega_pcm_r, sega_pcm_w)
988988   AM_RANGE(0xf800, 0xffff) AM_RAM
989989ADDRESS_MAP_END
990990
r19901r19902
16031603   MCFG_SOUND_ROUTE(0, "lspeaker", 0.43)
16041604   MCFG_SOUND_ROUTE(1, "rspeaker", 0.43)
16051605
1606   MCFG_SOUND_ADD("pcm", SEGAPCM, SOUND_CLOCK/4)
1606   MCFG_SEGAPCM_ADD("pcm", SOUND_CLOCK/4)
16071607   MCFG_SOUND_CONFIG(segapcm_interface)
16081608   MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
16091609   MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
r19901r19902
16501650   // sound hardware
16511651   MCFG_SPEAKER_STANDARD_STEREO("rearleft", "rearright")
16521652
1653   MCFG_SOUND_ADD("pcm2", SEGAPCM, SOUND_CLOCK/4)
1653   MCFG_SEGAPCM_ADD("pcm2", SOUND_CLOCK/4)
16541654   MCFG_SOUND_CONFIG(segapcm_interface)
16551655   MCFG_SOUND_ROUTE(0, "rearleft", 1.0)
16561656   MCFG_SOUND_ROUTE(1, "rearright", 1.0)
trunk/src/mame/drivers/segahang.c
r19901r19902
521521   AM_RANGE(0x0000, 0x7fff) AM_ROM
522522   AM_RANGE(0xc000, 0xc7ff) AM_MIRROR(0x0800) AM_RAM
523523   AM_RANGE(0xd000, 0xd001) AM_MIRROR(0x0ffe) AM_DEVREADWRITE_LEGACY("ymsnd", ym2203_r, ym2203_w)
524   AM_RANGE(0xe000, 0xe0ff) AM_MIRROR(0x0f00) AM_DEVREADWRITE_LEGACY("pcm", sega_pcm_r, sega_pcm_w)
524   AM_RANGE(0xe000, 0xe0ff) AM_MIRROR(0x0f00) AM_DEVREADWRITE("pcm", segapcm_device, sega_pcm_r, sega_pcm_w)
525525ADDRESS_MAP_END
526526
527527static ADDRESS_MAP_START( sound_portmap_2203, AS_IO, 8, segahang_state )
r19901r19902
533533static ADDRESS_MAP_START( sound_map_2151, AS_PROGRAM, 8, segahang_state )
534534   ADDRESS_MAP_UNMAP_HIGH
535535   AM_RANGE(0x0000, 0x7fff) AM_ROM
536   AM_RANGE(0xf000, 0xf0ff) AM_MIRROR(0x700) AM_DEVREADWRITE_LEGACY("pcm", sega_pcm_r, sega_pcm_w)
536   AM_RANGE(0xf000, 0xf0ff) AM_MIRROR(0x700) AM_DEVREADWRITE("pcm", segapcm_device, sega_pcm_r, sega_pcm_w)
537537   AM_RANGE(0xf800, 0xffff) AM_RAM
538538ADDRESS_MAP_END
539539
r19901r19902
899899   MCFG_SOUND_ROUTE(3, "lspeaker",  0.37)
900900   MCFG_SOUND_ROUTE(3, "rspeaker", 0.37)
901901
902   MCFG_SOUND_ADD("pcm", SEGAPCM, MASTER_CLOCK_8MHz)
902   MCFG_SEGAPCM_ADD("pcm", MASTER_CLOCK_8MHz)
903903   MCFG_SOUND_CONFIG(segapcm_interface)
904904   MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
905905   MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
r19901r19902
937937   MCFG_SOUND_ROUTE(3, "lspeaker",  0.37)
938938   MCFG_SOUND_ROUTE(3, "rspeaker", 0.37)
939939
940   MCFG_SOUND_ADD("pcm", SEGAPCM, MASTER_CLOCK_8MHz/2)
940   MCFG_SEGAPCM_ADD("pcm", MASTER_CLOCK_8MHz/2)
941941   MCFG_SOUND_CONFIG(segapcm_interface)
942942   MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
943943   MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
r19901r19902
959959   MCFG_SOUND_ROUTE(0, "lspeaker", 0.43)
960960   MCFG_SOUND_ROUTE(1, "rspeaker", 0.43)
961961
962   MCFG_SOUND_ADD("pcm", SEGAPCM, MASTER_CLOCK_8MHz/2)
962   MCFG_SEGAPCM_ADD("pcm", MASTER_CLOCK_8MHz/2)
963963   MCFG_SOUND_CONFIG(segapcm_interface)
964964   MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
965965   MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
r19901r19902
18061806//  GAME DRIVERS
18071807//**************************************************************************
18081808
1809//    YEAR, NAME,      PARENT,   MACHINE,  INPUT,     INIT,                        MONITOR,COMPANY,FULLNAME,FLAGS
1809//    YEAR, NAME,      PARENT,   MACHINE,  INPUT,     INIT,                   MONITOR,COMPANY,FULLNAME,FLAGS
18101810GAME( 1985, hangon,    0,        hangon,   hangon,    segahang_state,generic, ROT0,   "Sega", "Hang-On (Rev A)", 0 )
18111811GAME( 1985, hangon1,   hangon,   hangon,   hangon,    segahang_state,generic, ROT0,   "Sega", "Hang-On", 0 )
18121812GAME( 1987, shangonro, shangon,  shangonro,shangonro, segahang_state,generic, ROT0,   "Sega", "Super Hang-On (ride-on, Japan, FD1094 317-0038)", 0 )
trunk/src/mame/drivers/segaybd.c
r19901r19902
739739static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, segaybd_state )
740740   ADDRESS_MAP_UNMAP_HIGH
741741   AM_RANGE(0x0000, 0xefff) AM_ROM
742   AM_RANGE(0xf000, 0xf0ff) AM_MIRROR(0x0700) AM_DEVREADWRITE_LEGACY("pcm", sega_pcm_r, sega_pcm_w)
742   AM_RANGE(0xf000, 0xf0ff) AM_MIRROR(0x0700) AM_DEVREADWRITE("pcm", segapcm_device, sega_pcm_r, sega_pcm_w)
743743   AM_RANGE(0xf800, 0xffff) AM_RAM
744744ADDRESS_MAP_END
745745
r19901r19902
12291229   MCFG_SOUND_ROUTE(0, "lspeaker", 0.43)
12301230   MCFG_SOUND_ROUTE(1, "rspeaker", 0.43)
12311231
1232   MCFG_SOUND_ADD("pcm", SEGAPCM, SOUND_CLOCK/8)
1232   MCFG_SEGAPCM_ADD("pcm", SOUND_CLOCK/8)
12331233   MCFG_SOUND_CONFIG(segapcm_interface)
12341234   MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
12351235   MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
trunk/src/mame/drivers/segaorun.c
r19901r19902
845845static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, segaorun_state )
846846   ADDRESS_MAP_UNMAP_HIGH
847847   AM_RANGE(0x0000, 0xefff) AM_ROM
848   AM_RANGE(0xf000, 0xf0ff) AM_MIRROR(0x0700) AM_DEVREADWRITE_LEGACY("pcm", sega_pcm_r, sega_pcm_w)
848   AM_RANGE(0xf000, 0xf0ff) AM_MIRROR(0x0700) AM_DEVREADWRITE("pcm", segapcm_device, sega_pcm_r, sega_pcm_w)
849849   AM_RANGE(0xf800, 0xffff) AM_RAM
850850ADDRESS_MAP_END
851851
r19901r19902
10981098   MCFG_SOUND_ROUTE(0, "lspeaker", 0.43)
10991099   MCFG_SOUND_ROUTE(1, "rspeaker", 0.43)
11001100
1101   MCFG_SOUND_ADD("pcm", SEGAPCM, SOUND_CLOCK/4)
1101   MCFG_SEGAPCM_ADD("pcm", SOUND_CLOCK/4)
11021102   MCFG_SOUND_CONFIG(segapcm_interface)
11031103   MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
11041104   MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
trunk/src/emu/sound/segapcm.c
r19901r19902
55#include "emu.h"
66#include "segapcm.h"
77
8struct segapcm_state
9{
10   UINT8  *ram;
11   UINT8 low[16];
12   const UINT8 *rom;
13   int bankshift;
14   int bankmask;
15   int rgnmask;
16   sound_stream * stream;
17};
188
19INLINE segapcm_state *get_safe_token(device_t *device)
9// device type definition
10const device_type SEGAPCM = &device_creator<segapcm_device>;
11
12
13//-------------------------------------------------
14//  segapcm_device - constructor
15//-------------------------------------------------
16
17segapcm_device::segapcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
18   : device_t(mconfig, SEGAPCM, "Sega PCM", "segapcm", tag, owner, clock),
19     device_sound_interface(mconfig, *this),
20     m_ram(NULL),
21     m_rom(NULL),
22     m_bankshift(0),
23     m_bankmask(0),
24     m_rgnmask(0),
25     m_stream(NULL)
2026{
21   assert(device != NULL);
22   assert(device->type() == SEGAPCM);
23   return (segapcm_state *)downcast<segapcm_device *>(device)->token();
2427}
2528
26static STREAM_UPDATE( SEGAPCM_update )
29
30//-------------------------------------------------
31//  device_start - device-specific startup
32//-------------------------------------------------
33
34void segapcm_device::device_start()
2735{
28   segapcm_state *spcm = (segapcm_state *)param;
29   int rgnmask = spcm->rgnmask;
30   int ch;
36   int mask, rom_mask, len;
37   const sega_pcm_interface *intf = (const sega_pcm_interface *)static_config();
3138
39   m_rom = *region();
40   m_ram = auto_alloc_array(machine(), UINT8, 0x800);
41
42   memset(m_ram, 0xff, 0x800);
43
44   m_bankshift = (UINT8)(intf->bank);
45   mask = intf->bank >> 16;
46   if(!mask)
47      mask = BANK_MASK7>>16;
48
49   len = region()->bytes();
50   m_rgnmask = len - 1;
51
52   for(rom_mask = 1; rom_mask < len; rom_mask *= 2);
53
54   rom_mask--;
55
56   m_bankmask = mask & (rom_mask >> m_bankshift);
57
58   m_stream = stream_alloc(0, 2, clock() / 128);
59
60   save_item(NAME(m_low));
61   save_pointer(NAME(m_ram), 0x800);
62}
63
64
65//-------------------------------------------------
66//  sound_stream_update - handle a stream update
67//-------------------------------------------------
68
69void segapcm_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
70{
3271   /* clear the buffers */
3372   memset(outputs[0], 0, samples*sizeof(*outputs[0]));
3473   memset(outputs[1], 0, samples*sizeof(*outputs[1]));
r19901r19902
5594   // 0x87     ?
5695
5796   /* loop over channels */
58   for (ch = 0; ch < 16; ch++)
97   for (int ch = 0; ch < 16; ch++)
5998   {
60      UINT8 *regs = spcm->ram+8*ch;
99      UINT8 *regs = m_ram+8*ch;
61100
62101      /* only process active channels */
63102      if (!(regs[0x86]&1))
64103      {
65         const UINT8 *rom = spcm->rom + ((regs[0x86] & spcm->bankmask) << spcm->bankshift);
66         UINT32 addr = (regs[0x85] << 16) | (regs[0x84] << 8) | spcm->low[ch];
104         const UINT8 *rom = m_rom + ((regs[0x86] & m_bankmask) << m_bankshift);
105         UINT32 addr = (regs[0x85] << 16) | (regs[0x84] << 8) | m_low[ch];
67106         UINT32 loop = (regs[0x05] << 16) | (regs[0x04] << 8);
68107         UINT8 end = regs[6] + 1;
69108         int i;
r19901r19902
85124            }
86125
87126            /* fetch the sample */
88            v = rom[(addr >> 8) & rgnmask] - 0x80;
127            v = rom[(addr >> 8) & m_rgnmask] - 0x80;
89128
90129            /* apply panning and advance */
91130            outputs[0][i] += v * regs[2];
r19901r19902
96135         /* store back the updated address */
97136         regs[0x84] = addr >> 8;
98137         regs[0x85] = addr >> 16;
99         spcm->low[ch] = regs[0x86] & 1 ? 0 : addr;
138         m_low[ch] = regs[0x86] & 1 ? 0 : addr;
100139      }
101140   }
102141}
103142
104static DEVICE_START( segapcm )
105{
106   const sega_pcm_interface *intf = (const sega_pcm_interface *)device->static_config();
107   int mask, rom_mask, len;
108   segapcm_state *spcm = get_safe_token(device);
109143
110   spcm->rom = *device->region();
111   spcm->ram = auto_alloc_array(device->machine(), UINT8, 0x800);
112
113   memset(spcm->ram, 0xff, 0x800);
114
115   spcm->bankshift = (UINT8)(intf->bank);
116   mask = intf->bank >> 16;
117   if(!mask)
118      mask = BANK_MASK7>>16;
119
120   len = device->region()->bytes();
121   spcm->rgnmask = len - 1;
122
123   for(rom_mask = 1; rom_mask < len; rom_mask *= 2);
124
125   rom_mask--;
126
127   spcm->bankmask = mask & (rom_mask >> spcm->bankshift);
128
129   spcm->stream = device->machine().sound().stream_alloc(*device, 0, 2, device->clock() / 128, spcm, SEGAPCM_update);
130
131   device->save_item(NAME(spcm->low));
132   device->save_pointer(NAME(spcm->ram), 0x800);
133}
134
135
136WRITE8_DEVICE_HANDLER( sega_pcm_w )
144WRITE8_MEMBER( segapcm_device::sega_pcm_w )
137145{
138   segapcm_state *spcm = get_safe_token(device);
139   spcm->stream->update();
140   spcm->ram[offset & 0x07ff] = data;
146   m_stream->update();
147   m_ram[offset & 0x07ff] = data;
141148}
142149
143READ8_DEVICE_HANDLER( sega_pcm_r )
144{
145   segapcm_state *spcm = get_safe_token(device);
146   spcm->stream->update();
147   return spcm->ram[offset & 0x07ff];
148}
149150
150const device_type SEGAPCM = &device_creator<segapcm_device>;
151
152segapcm_device::segapcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
153   : device_t(mconfig, SEGAPCM, "Sega PCM", tag, owner, clock),
154     device_sound_interface(mconfig, *this)
151READ8_MEMBER( segapcm_device::sega_pcm_r )
155152{
156   m_token = global_alloc_clear(segapcm_state);
153   m_stream->update();
154   return m_ram[offset & 0x07ff];
157155}
158156
159//-------------------------------------------------
160//  device_config_complete - perform any
161//  operations now that the configuration is
162//  complete
163//-------------------------------------------------
164157
165void segapcm_device::device_config_complete()
166{
167}
168
169//-------------------------------------------------
170//  device_start - device-specific startup
171//-------------------------------------------------
172
173void segapcm_device::device_start()
174{
175   DEVICE_START_NAME( segapcm )(this);
176}
177
178//-------------------------------------------------
179//  sound_stream_update - handle a stream update
180//-------------------------------------------------
181
182void segapcm_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
183{
184   // should never get here
185   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
186}
187
188
trunk/src/emu/sound/segapcm.h
r19901r19902
77#ifndef __SEGAPCM_H__
88#define __SEGAPCM_H__
99
10#include "devlegcy.h"
11
1210#define   BANK_256    (11)
1311#define   BANK_512    (12)
1412#define   BANK_12M    (13)
r19901r19902
1614#define   BANK_MASKF    (0xf0<<16)
1715#define   BANK_MASKF8   (0xf8<<16)
1816
17
18//**************************************************************************
19//  INTERFACE CONFIGURATION MACROS
20//**************************************************************************
21
22#define MCFG_SEGAPCM_ADD(_tag, _clock) \
23   MCFG_DEVICE_ADD(_tag, SEGAPCM, _clock) \
24
25#define MCFG_SEGAPCM_REPLACE(_tag, _clock) \
26   MCFG_DEVICE_REPLACE(_tag, SEGAPCM, _clock) \
27
28
29//**************************************************************************
30//  TYPE DEFINITIONS
31//**************************************************************************
32
1933struct sega_pcm_interface
2034{
2135   int  bank;
2236};
2337
24DECLARE_WRITE8_DEVICE_HANDLER( sega_pcm_w );
25DECLARE_READ8_DEVICE_HANDLER( sega_pcm_r );
26
2738class segapcm_device : public device_t,
28                                  public device_sound_interface
39                  public device_sound_interface
2940{
3041public:
3142   segapcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
32   ~segapcm_device() { global_free(m_token); }
43   ~segapcm_device() { }
3344
34   // access to legacy token
35   void *token() const { assert(m_token != NULL); return m_token; }
3645protected:
3746   // device-level overrides
38   virtual void device_config_complete();
3947   virtual void device_start();
4048
4149   // sound stream update overrides
4250   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
51
52public:
53   DECLARE_WRITE8_MEMBER( sega_pcm_w );
54   DECLARE_READ8_MEMBER( sega_pcm_r );
55
4356private:
44   // internal state
45   void *m_token;
57   UINT8* m_ram;
58   UINT8 m_low[16];
59   const UINT8* m_rom;
60   int m_bankshift;
61   int m_bankmask;
62   int m_rgnmask;
63   sound_stream* m_stream;
4664};
4765
4866extern const device_type SEGAPCM;

Previous 199869 Revisions Next


© 1997-2024 The MAME Team