trunk/src/mame/drivers/segaxbd.c
| r19901 | r19902 | |
| 961 | 961 | static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, segaxbd_state ) |
| 962 | 962 | ADDRESS_MAP_UNMAP_HIGH |
| 963 | 963 | 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) |
| 965 | 965 | AM_RANGE(0xf800, 0xffff) AM_RAM |
| 966 | 966 | ADDRESS_MAP_END |
| 967 | 967 | |
| r19901 | r19902 | |
| 984 | 984 | static ADDRESS_MAP_START( smgp_sound2_map, AS_PROGRAM, 8, segaxbd_state ) |
| 985 | 985 | ADDRESS_MAP_UNMAP_HIGH |
| 986 | 986 | 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) |
| 988 | 988 | AM_RANGE(0xf800, 0xffff) AM_RAM |
| 989 | 989 | ADDRESS_MAP_END |
| 990 | 990 | |
| r19901 | r19902 | |
| 1603 | 1603 | MCFG_SOUND_ROUTE(0, "lspeaker", 0.43) |
| 1604 | 1604 | MCFG_SOUND_ROUTE(1, "rspeaker", 0.43) |
| 1605 | 1605 | |
| 1606 | | MCFG_SOUND_ADD("pcm", SEGAPCM, SOUND_CLOCK/4) |
| 1606 | MCFG_SEGAPCM_ADD("pcm", SOUND_CLOCK/4) |
| 1607 | 1607 | MCFG_SOUND_CONFIG(segapcm_interface) |
| 1608 | 1608 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 1609 | 1609 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| r19901 | r19902 | |
| 1650 | 1650 | // sound hardware |
| 1651 | 1651 | MCFG_SPEAKER_STANDARD_STEREO("rearleft", "rearright") |
| 1652 | 1652 | |
| 1653 | | MCFG_SOUND_ADD("pcm2", SEGAPCM, SOUND_CLOCK/4) |
| 1653 | MCFG_SEGAPCM_ADD("pcm2", SOUND_CLOCK/4) |
| 1654 | 1654 | MCFG_SOUND_CONFIG(segapcm_interface) |
| 1655 | 1655 | MCFG_SOUND_ROUTE(0, "rearleft", 1.0) |
| 1656 | 1656 | MCFG_SOUND_ROUTE(1, "rearright", 1.0) |
trunk/src/mame/drivers/segahang.c
| r19901 | r19902 | |
| 521 | 521 | AM_RANGE(0x0000, 0x7fff) AM_ROM |
| 522 | 522 | AM_RANGE(0xc000, 0xc7ff) AM_MIRROR(0x0800) AM_RAM |
| 523 | 523 | 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) |
| 525 | 525 | ADDRESS_MAP_END |
| 526 | 526 | |
| 527 | 527 | static ADDRESS_MAP_START( sound_portmap_2203, AS_IO, 8, segahang_state ) |
| r19901 | r19902 | |
| 533 | 533 | static ADDRESS_MAP_START( sound_map_2151, AS_PROGRAM, 8, segahang_state ) |
| 534 | 534 | ADDRESS_MAP_UNMAP_HIGH |
| 535 | 535 | 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) |
| 537 | 537 | AM_RANGE(0xf800, 0xffff) AM_RAM |
| 538 | 538 | ADDRESS_MAP_END |
| 539 | 539 | |
| r19901 | r19902 | |
| 899 | 899 | MCFG_SOUND_ROUTE(3, "lspeaker", 0.37) |
| 900 | 900 | MCFG_SOUND_ROUTE(3, "rspeaker", 0.37) |
| 901 | 901 | |
| 902 | | MCFG_SOUND_ADD("pcm", SEGAPCM, MASTER_CLOCK_8MHz) |
| 902 | MCFG_SEGAPCM_ADD("pcm", MASTER_CLOCK_8MHz) |
| 903 | 903 | MCFG_SOUND_CONFIG(segapcm_interface) |
| 904 | 904 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 905 | 905 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| r19901 | r19902 | |
| 937 | 937 | MCFG_SOUND_ROUTE(3, "lspeaker", 0.37) |
| 938 | 938 | MCFG_SOUND_ROUTE(3, "rspeaker", 0.37) |
| 939 | 939 | |
| 940 | | MCFG_SOUND_ADD("pcm", SEGAPCM, MASTER_CLOCK_8MHz/2) |
| 940 | MCFG_SEGAPCM_ADD("pcm", MASTER_CLOCK_8MHz/2) |
| 941 | 941 | MCFG_SOUND_CONFIG(segapcm_interface) |
| 942 | 942 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 943 | 943 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| r19901 | r19902 | |
| 959 | 959 | MCFG_SOUND_ROUTE(0, "lspeaker", 0.43) |
| 960 | 960 | MCFG_SOUND_ROUTE(1, "rspeaker", 0.43) |
| 961 | 961 | |
| 962 | | MCFG_SOUND_ADD("pcm", SEGAPCM, MASTER_CLOCK_8MHz/2) |
| 962 | MCFG_SEGAPCM_ADD("pcm", MASTER_CLOCK_8MHz/2) |
| 963 | 963 | MCFG_SOUND_CONFIG(segapcm_interface) |
| 964 | 964 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 965 | 965 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| r19901 | r19902 | |
| 1806 | 1806 | // GAME DRIVERS |
| 1807 | 1807 | //************************************************************************** |
| 1808 | 1808 | |
| 1809 | | // YEAR, NAME, PARENT, MACHINE, INPUT, INIT, MONITOR,COMPANY,FULLNAME,FLAGS |
| 1809 | // YEAR, NAME, PARENT, MACHINE, INPUT, INIT, MONITOR,COMPANY,FULLNAME,FLAGS |
| 1810 | 1810 | GAME( 1985, hangon, 0, hangon, hangon, segahang_state,generic, ROT0, "Sega", "Hang-On (Rev A)", 0 ) |
| 1811 | 1811 | GAME( 1985, hangon1, hangon, hangon, hangon, segahang_state,generic, ROT0, "Sega", "Hang-On", 0 ) |
| 1812 | 1812 | GAME( 1987, shangonro, shangon, shangonro,shangonro, segahang_state,generic, ROT0, "Sega", "Super Hang-On (ride-on, Japan, FD1094 317-0038)", 0 ) |
trunk/src/emu/sound/segapcm.c
| r19901 | r19902 | |
| 5 | 5 | #include "emu.h" |
| 6 | 6 | #include "segapcm.h" |
| 7 | 7 | |
| 8 | | struct 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 | | }; |
| 18 | 8 | |
| 19 | | INLINE segapcm_state *get_safe_token(device_t *device) |
| 9 | // device type definition |
| 10 | const device_type SEGAPCM = &device_creator<segapcm_device>; |
| 11 | |
| 12 | |
| 13 | //------------------------------------------------- |
| 14 | // segapcm_device - constructor |
| 15 | //------------------------------------------------- |
| 16 | |
| 17 | segapcm_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) |
| 20 | 26 | { |
| 21 | | assert(device != NULL); |
| 22 | | assert(device->type() == SEGAPCM); |
| 23 | | return (segapcm_state *)downcast<segapcm_device *>(device)->token(); |
| 24 | 27 | } |
| 25 | 28 | |
| 26 | | static STREAM_UPDATE( SEGAPCM_update ) |
| 29 | |
| 30 | //------------------------------------------------- |
| 31 | // device_start - device-specific startup |
| 32 | //------------------------------------------------- |
| 33 | |
| 34 | void segapcm_device::device_start() |
| 27 | 35 | { |
| 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(); |
| 31 | 38 | |
| 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 | |
| 69 | void segapcm_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 70 | { |
| 32 | 71 | /* clear the buffers */ |
| 33 | 72 | memset(outputs[0], 0, samples*sizeof(*outputs[0])); |
| 34 | 73 | memset(outputs[1], 0, samples*sizeof(*outputs[1])); |
| r19901 | r19902 | |
| 55 | 94 | // 0x87 ? |
| 56 | 95 | |
| 57 | 96 | /* loop over channels */ |
| 58 | | for (ch = 0; ch < 16; ch++) |
| 97 | for (int ch = 0; ch < 16; ch++) |
| 59 | 98 | { |
| 60 | | UINT8 *regs = spcm->ram+8*ch; |
| 99 | UINT8 *regs = m_ram+8*ch; |
| 61 | 100 | |
| 62 | 101 | /* only process active channels */ |
| 63 | 102 | if (!(regs[0x86]&1)) |
| 64 | 103 | { |
| 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]; |
| 67 | 106 | UINT32 loop = (regs[0x05] << 16) | (regs[0x04] << 8); |
| 68 | 107 | UINT8 end = regs[6] + 1; |
| 69 | 108 | int i; |
| r19901 | r19902 | |
| 85 | 124 | } |
| 86 | 125 | |
| 87 | 126 | /* fetch the sample */ |
| 88 | | v = rom[(addr >> 8) & rgnmask] - 0x80; |
| 127 | v = rom[(addr >> 8) & m_rgnmask] - 0x80; |
| 89 | 128 | |
| 90 | 129 | /* apply panning and advance */ |
| 91 | 130 | outputs[0][i] += v * regs[2]; |
| r19901 | r19902 | |
| 96 | 135 | /* store back the updated address */ |
| 97 | 136 | regs[0x84] = addr >> 8; |
| 98 | 137 | regs[0x85] = addr >> 16; |
| 99 | | spcm->low[ch] = regs[0x86] & 1 ? 0 : addr; |
| 138 | m_low[ch] = regs[0x86] & 1 ? 0 : addr; |
| 100 | 139 | } |
| 101 | 140 | } |
| 102 | 141 | } |
| 103 | 142 | |
| 104 | | static 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); |
| 109 | 143 | |
| 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 | | |
| 136 | | WRITE8_DEVICE_HANDLER( sega_pcm_w ) |
| 144 | WRITE8_MEMBER( segapcm_device::sega_pcm_w ) |
| 137 | 145 | { |
| 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; |
| 141 | 148 | } |
| 142 | 149 | |
| 143 | | READ8_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 | | } |
| 149 | 150 | |
| 150 | | const device_type SEGAPCM = &device_creator<segapcm_device>; |
| 151 | | |
| 152 | | segapcm_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) |
| 151 | READ8_MEMBER( segapcm_device::sega_pcm_r ) |
| 155 | 152 | { |
| 156 | | m_token = global_alloc_clear(segapcm_state); |
| 153 | m_stream->update(); |
| 154 | return m_ram[offset & 0x07ff]; |
| 157 | 155 | } |
| 158 | 156 | |
| 159 | | //------------------------------------------------- |
| 160 | | // device_config_complete - perform any |
| 161 | | // operations now that the configuration is |
| 162 | | // complete |
| 163 | | //------------------------------------------------- |
| 164 | 157 | |
| 165 | | void segapcm_device::device_config_complete() |
| 166 | | { |
| 167 | | } |
| 168 | | |
| 169 | | //------------------------------------------------- |
| 170 | | // device_start - device-specific startup |
| 171 | | //------------------------------------------------- |
| 172 | | |
| 173 | | void segapcm_device::device_start() |
| 174 | | { |
| 175 | | DEVICE_START_NAME( segapcm )(this); |
| 176 | | } |
| 177 | | |
| 178 | | //------------------------------------------------- |
| 179 | | // sound_stream_update - handle a stream update |
| 180 | | //------------------------------------------------- |
| 181 | | |
| 182 | | void 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
| r19901 | r19902 | |
| 7 | 7 | #ifndef __SEGAPCM_H__ |
| 8 | 8 | #define __SEGAPCM_H__ |
| 9 | 9 | |
| 10 | | #include "devlegcy.h" |
| 11 | | |
| 12 | 10 | #define BANK_256 (11) |
| 13 | 11 | #define BANK_512 (12) |
| 14 | 12 | #define BANK_12M (13) |
| r19901 | r19902 | |
| 16 | 14 | #define BANK_MASKF (0xf0<<16) |
| 17 | 15 | #define BANK_MASKF8 (0xf8<<16) |
| 18 | 16 | |
| 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 | |
| 19 | 33 | struct sega_pcm_interface |
| 20 | 34 | { |
| 21 | 35 | int bank; |
| 22 | 36 | }; |
| 23 | 37 | |
| 24 | | DECLARE_WRITE8_DEVICE_HANDLER( sega_pcm_w ); |
| 25 | | DECLARE_READ8_DEVICE_HANDLER( sega_pcm_r ); |
| 26 | | |
| 27 | 38 | class segapcm_device : public device_t, |
| 28 | | public device_sound_interface |
| 39 | public device_sound_interface |
| 29 | 40 | { |
| 30 | 41 | public: |
| 31 | 42 | segapcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 32 | | ~segapcm_device() { global_free(m_token); } |
| 43 | ~segapcm_device() { } |
| 33 | 44 | |
| 34 | | // access to legacy token |
| 35 | | void *token() const { assert(m_token != NULL); return m_token; } |
| 36 | 45 | protected: |
| 37 | 46 | // device-level overrides |
| 38 | | virtual void device_config_complete(); |
| 39 | 47 | virtual void device_start(); |
| 40 | 48 | |
| 41 | 49 | // sound stream update overrides |
| 42 | 50 | virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); |
| 51 | |
| 52 | public: |
| 53 | DECLARE_WRITE8_MEMBER( sega_pcm_w ); |
| 54 | DECLARE_READ8_MEMBER( sega_pcm_r ); |
| 55 | |
| 43 | 56 | private: |
| 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; |
| 46 | 64 | }; |
| 47 | 65 | |
| 48 | 66 | extern const device_type SEGAPCM; |