(MESS)-gamate: audio emulation [Peter Trauner]

This commit is contained in:
Miodrag Milanovic 2015-02-22 11:45:55 +01:00
parent 79fcba5fe6
commit 3623554da7
4 changed files with 289 additions and 116 deletions

127
src/mess/audio/gamate.c Normal file
View File

@ -0,0 +1,127 @@
/***************************************************************************
gamate sound hardware
PeT mess@utanet.at
***************************************************************************/
#include "emu.h"
#include "includes/gamate.h"
// device type definition
const device_type GAMATE_SND = &device_creator<gamate_sound_device>;
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// gamate_sound_device - constructor
//-------------------------------------------------
gamate_sound_device::gamate_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, GAMATE_SND, "Gamate Audio Custom", tag, owner, clock, "gamate_sound", __FILE__),
device_sound_interface(mconfig, *this),
m_mixer_channel(NULL)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void gamate_sound_device::device_start()
{
// bind callbacks
// m_irq_cb.bind_relative_to(*owner());
memset(m_channels, 0, sizeof(m_channels));
memset(reg, 0, sizeof(reg));
m_mixer_channel = stream_alloc(0, 2, machine().sample_rate());
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void gamate_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
stream_sample_t *left=outputs[0], *right=outputs[1];
int i, j;
GAMATE_CHANNEL *channel;
for (i = 0; i < samples; i++, left++, right++)
{
*left = 0;
*right = 0;
for (channel=m_channels, j=0; j<ARRAY_LENGTH(m_channels); j++, channel++)
{
if (channel->size != 0)
{
if (channel->on)//||channel->count)
{
int on = FALSE;
on = channel->pos <= channel->size / 2;
{
INT16 s = on ? channel->volume << 8 : 0;
if (j == 0)
*right += s;
else if (j==1)
*left += s;
else {
*right += s;
*left += s;
}
}
}
channel->pos++;
if (channel->pos >= channel->size)
channel->pos = 0;
}
}
}
}
WRITE8_MEMBER( gamate_sound_device::device_w )
{
UINT16 size;
m_mixer_channel->update();
reg[offset] = data;
int chan=-1;
switch (offset)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
chan=offset/2;
size = reg[chan*2] | ((reg[chan*2+1] & 0xf) << 8);
if (size)
{
m_channels[chan].size= (int) (machine().sample_rate() * (size << 5) / machine().device("maincpu")->unscaled_clock());
}
else
{
m_channels[chan].size = 0;
}
m_channels[chan].pos = 0;
break;
case 6:
case 7:
case 8:
chan=offset-6;
// m_channels[chan]->on = data & 0x40;
// channel->waveform = (data & 0x30) >> 4;
m_channels[chan].volume = data & 0xf;
break;
}
if (chan!=-1) m_channels[chan].on=m_channels[chan].volume!=0 && m_channels[chan].size>3/* avoid speed loss for unhearable >=23khz*/;
}

View File

@ -10,8 +10,8 @@
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
#include "rendlay.h"
//#define USE_GFX
#include "includes/gamate.h"
#include "ui/ui.h"
class gamate_state : public driver_device
{
@ -19,10 +19,8 @@ public:
gamate_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_sound(*this, "custom")
, m_cart(*this, "cartslot")
#ifdef USE_GFX
, m_gfxdecode(*this, "gfxdecode")
#endif
, m_io_joy(*this, "JOY")
, m_palette(*this, "palette")
, m_bios(*this, "bios")
@ -53,51 +51,48 @@ private:
struct
{
UINT8 reg[8];
struct {
bool write;
bool page2; // else page1
UINT8 reg[8];
struct {
bool write;
bool page2; // else page1
UINT8 ypos, xpos/*tennis*/;
UINT8 data[2][0x100][0x20];
} bitmap;
UINT8 x, y;
UINT8 data[2][0x100][0x20];
} bitmap;
UINT8 x, y;
bool y_increment;
} video;
struct {
bool set;
bool set;
int bit_shifter;
UINT8 cartridge_byte;
UINT16 address; // in reality something more like short local cartridge address offset
bool unprotected;
bool failed;
} card_protection;
required_device<cpu_device> m_maincpu;
required_device<gamate_sound_device> m_sound;
required_device<generic_slot_device> m_cart;
#ifdef USE_GFX
required_device<gfxdecode_device> m_gfxdecode;
#endif
required_ioport m_io_joy;
required_device<palette_device> m_palette;
required_shared_ptr<UINT8> m_bios;
emu_timer *timer1;
emu_timer *timer2;
UINT8 bank_multi;
UINT8 *m_cart_ptr;
UINT8 bank_multi;
};
WRITE8_MEMBER( gamate_state::gamate_cart_protection_w )
{
logerror("%.6f protection write %x %x address:%x data:%x shift:%d\n",machine().time().as_double(), offset, data, card_protection.address, card_protection.cartridge_byte, card_protection.bit_shifter);
logerror("%.6f protection write %x %x address:%x data:%x shift:%d\n",machine().time().as_double(), offset, data, card_protection.address, card_protection.cartridge_byte, card_protection.bit_shifter);
switch (offset) {
case 0:
card_protection.failed= card_protection.failed || ((card_protection.cartridge_byte&0x80)!=0) != ((data&4)!=0);
card_protection.bit_shifter++;
if (card_protection.bit_shifter>=8) {
card_protection.cartridge_byte=m_cart_ptr[card_protection.address++];
card_protection.cartridge_byte=m_cart->get_rom_base()[card_protection.address++];
card_protection.bit_shifter=0;
}
break;
@ -107,7 +102,7 @@ READ8_MEMBER( gamate_state::gamate_cart_protection_r )
{
UINT8 ret=1;
if (card_protection.bit_shifter==7 && card_protection.unprotected) {
ret=m_cart_ptr[bank_multi*0x4000];
ret=m_cart->get_rom_base()[bank_multi*0x4000];
} else {
card_protection.bit_shifter++;
if (card_protection.bit_shifter==8) {
@ -117,7 +112,7 @@ READ8_MEMBER( gamate_state::gamate_cart_protection_r )
}
ret=(card_protection.cartridge_byte&0x80)?2:0;
if (card_protection.bit_shifter==7 && !card_protection.failed) { // now protection chip on cartridge activates cartridge chip select on cpu accesses
// m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r)); // next time I will try to get this working
// m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r)); // next time I will try to get this working
}
card_protection.cartridge_byte<<=1;
}
@ -132,7 +127,7 @@ WRITE8_MEMBER( gamate_state::protection_reset )
// writes 0x20
card_protection.address=0x6005-0x6001;
card_protection.bit_shifter=0;
card_protection.cartridge_byte=m_cart_ptr[card_protection.address++];//m_cart_rom[card_protection.address++];
card_protection.cartridge_byte=m_cart->get_rom_base()[card_protection.address++];//m_cart_rom[card_protection.address++];
card_protection.failed=false;
card_protection.unprotected=false;
}
@ -148,19 +143,23 @@ WRITE8_MEMBER( gamate_state::gamate_video_w )
{
video.reg[offset]=data;
switch (offset) {
case 1: video.bitmap.write=data&0xc0; // more addressing mode
case 1:
if (data&0xf) printf("lcd mode %x\n", data);
video.bitmap.write=data&0xc0; // more addressing mode
video.y_increment=data&0x40;
break;
case 2: video.bitmap.xpos=data;break; // at least 7 bits
case 3: video.bitmap.ypos=data;break; // at least 7 bits
case 2: video.bitmap.xpos=data;break;
case 3:
if (data>=200) printf("lcd ypos: %x\n", data);
video.bitmap.ypos=data;
break;
case 4: video.bitmap.page2=data&0x80;video.x=data&0x7f;break;
case 5: video.y=data;break;
case 7:
if (video.y>=200)
machine().ui().popup_time(2, "bitmap write to x:%x y:%x mode:%x data:%x\n", video.x, video.y, video.reg[1], data);
if (video.bitmap.write) {
if (video.x<ARRAY_LENGTH(video.bitmap.data[0][0]) /*&& video.y<ARRAY_LENGTH(video.bitmap.data[0])*/)
video.bitmap.data[video.bitmap.page2][video.y][video.x]=data;
else
logerror("%.6f %04x video bitmap x %x invalid\n",machine().time().as_double(), m_maincpu->pc(), video.x);
} else {
video.bitmap.data[0][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)]=data;
}
@ -172,66 +171,65 @@ WRITE8_MEMBER( gamate_state::gamate_video_w )
WRITE8_MEMBER( gamate_state::cart_bankswitchmulti_w )
{
bank_multi=data;
membank("bankmulti")->set_base(m_cart_ptr+0x4000*data+1);
membank("bankmulti")->set_base(m_cart->get_rom_base()+0x4000*data+1);
}
WRITE8_MEMBER( gamate_state::cart_bankswitch_w )
{
membank("bank")->set_base(m_cart_ptr+0x4000*data);
membank("bank")->set_base(m_cart->get_rom_base()+0x4000*data);
}
READ8_MEMBER( gamate_state::gamate_video_r )
{
if (offset!=6) return 0;
UINT8 data=0;
if (video.bitmap.write) {
if (video.x<ARRAY_LENGTH(video.bitmap.data[0][0]) /*&& video.y<ARRAY_LENGTH(video.bitmap.data[0])*/)
data=video.bitmap.data[video.bitmap.page2][video.y][video.x];
else
logerror("%.6f video bitmap x %x invalid\n",machine().time().as_double(),video.x);
} else {
data=video.bitmap.data[0][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)];
}
if (m_maincpu->pc()<0xf000)
logerror("%.6f video read %04x %02x\n",machine().time().as_double(),offset, data);
return data;
if (offset!=6) return 0;
UINT8 data=0;
if (video.bitmap.write) {
data=video.bitmap.data[video.bitmap.page2][video.y][video.x];
} else {
data=video.bitmap.data[0][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)];
}
// if (m_maincpu->pc()<0xf000)
// machine().ui().popup_time(2, "lcd read x:%x y:%x mode:%x data:%x\n", video.x, video.y, video.reg[1], data);
return data;
}
WRITE8_MEMBER( gamate_state::gamate_audio_w )
{
logerror("%.6f %04x audio write %04x %02x\n",machine().time().as_double(),m_maincpu->pc(),offset,data);
// printf("audio write %x:%x\n", offset, data);//logerror("%.6f %04x audio write %04x %02x\n",machine().time().as_double(),m_maincpu->pc(),offset,data);
m_sound->device_w(space, offset, data);
}
READ8_MEMBER( gamate_state::gamate_audio_r )
{
logerror("%.6f %04x audio read %04x \n",machine().time().as_double(),m_maincpu->pc(),offset);
return 0;
// legend of dragon knight
// machine().ui().popup_time(2, "%.6f %04x audio read %04x \n",machine().time().as_double(),m_maincpu->pc(),offset);
return 0;
}
READ8_MEMBER( gamate_state::gamate_pad_r )
{
UINT8 data=m_io_joy->read();
return data;
UINT8 data=m_io_joy->read();
return data;
}
static ADDRESS_MAP_START( gamate_mem, AS_PROGRAM, 8, gamate_state )
AM_RANGE(0x0000, 0x03ff) AM_RAM
AM_RANGE(0x4000, 0x400d) AM_READWRITE(gamate_audio_r, gamate_audio_w)
AM_RANGE(0x4400, 0x4400) AM_READ(gamate_pad_r)
AM_RANGE(0x5000, 0x5007) AM_READWRITE(gamate_video_r, gamate_video_w)
AM_RANGE(0x5800, 0x5800) AM_READ(newer_protection_set)
AM_RANGE(0x5900, 0x5900) AM_WRITE(protection_reset)
AM_RANGE(0x5a00, 0x5a00) AM_READ(protection_r)
AM_RANGE(0x0000, 0x03ff) AM_RAM
AM_RANGE(0x4000, 0x400d) AM_READWRITE(gamate_audio_r, gamate_audio_w)
AM_RANGE(0x4400, 0x4400) AM_READ(gamate_pad_r)
AM_RANGE(0x5000, 0x5007) AM_READWRITE(gamate_video_r, gamate_video_w)
AM_RANGE(0x5800, 0x5800) AM_READ(newer_protection_set)
AM_RANGE(0x5900, 0x5900) AM_WRITE(protection_reset)
AM_RANGE(0x5a00, 0x5a00) AM_READ(protection_r)
AM_RANGE(0x6001, 0x9fff) AM_READ_BANK("bankmulti")
AM_RANGE(0xa000, 0xdfff) AM_READ_BANK("bank")
AM_RANGE(0x6001, 0x9fff) AM_READ_BANK("bankmulti")
AM_RANGE(0xa000, 0xdfff) AM_READ_BANK("bank")
AM_RANGE(0x6000, 0x6000) AM_READWRITE(gamate_cart_protection_r, gamate_cart_protection_w)
AM_RANGE(0x8000, 0x8000) AM_WRITE(cart_bankswitchmulti_w)
AM_RANGE(0xc000, 0xc000) AM_WRITE(cart_bankswitch_w)
AM_RANGE(0xf000, 0xffff) AM_ROM AM_SHARE("bios")
AM_RANGE(0xf000, 0xffff) AM_ROM AM_SHARE("bios")
ADDRESS_MAP_END
@ -247,33 +245,19 @@ static INPUT_PORTS_START( gamate )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SELECT) PORT_NAME("Select")
INPUT_PORTS_END
#ifdef USE_GFX
static const struct gfx_layout gamate_charlayout =
static const unsigned short gamate_palette[4] =
{
4, /* width of object */
1, /* height of object */
256,/* 256 characters */
2, /* bits per pixel */
{ 0,4 }, /* no bitplanes */
/* x offsets */
{ 0,1,2,3 },
/* y offsets */
{ 0 },
8*1 /* size of 1 object in bits */
0,1,2,3
};
static GFXDECODE_START( gamate )
GFXDECODE_ENTRY( "gfx1", 0x0000, gamate_charlayout, 0, 0x100 )
GFXDECODE_END
#endif
/* palette in red, green, blue tribles */
static const unsigned char gamate_colors[4][3] =
{
{ 255,255,255 },
{ 0xa0, 0xa0, 0xa0 },
{ 0x60, 0x60, 0x60 },
{ 0, 0, 0 }
{ 255,255,255 },
{ 0xa0, 0xa0, 0xa0 },
{ 0x60, 0x60, 0x60 },
{ 0, 0, 0 }
};
PALETTE_INIT_MEMBER(gamate_state, gamate)
@ -286,7 +270,6 @@ PALETTE_INIT_MEMBER(gamate_state, gamate)
}
}
#ifndef USE_GFX
static void BlitPlane(UINT16* line, UINT8 plane1, UINT8 plane2)
{
line[3]=(plane1&1)|((plane2<<1)&2);
@ -294,34 +277,35 @@ static void BlitPlane(UINT16* line, UINT8 plane1, UINT8 plane2)
line[1]=((plane1>>2)&1)|((plane2>>1)&2);
line[0]=((plane1>>3)&1)|((plane2>>2)&2);
}
#endif
UINT32 gamate_state::screen_update_gamate(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int x, y, j;
for (y=0;y<152;y++) {
for (x=-(video.bitmap.xpos&7), j=0;x<160;x+=8, j++) {
UINT8 d1=video.bitmap.data[0][(y+video.bitmap.ypos)&0xff][(j+video.bitmap.xpos/8)&0x1f];
UINT8 d2=video.bitmap.data[1][(y+video.bitmap.ypos)&0xff][(j+video.bitmap.xpos/8)&0x1f];
#ifdef USE_GFX
m_gfxdecode->gfx(0)->opaque(bitmap,cliprect, (d1&0xf)|((d2&0xf)<<4), 0,0,0,x+4,y);
m_gfxdecode->gfx(0)->opaque(bitmap,cliprect, (d1>>4)|(d2&0xf0),0,0,0,x,y);
#else
BlitPlane(&bitmap.pix16(y, x+4), d1, d2);
BlitPlane(&bitmap.pix16(y, x), d1>>4, d2>>4);
#endif
}
}
return 0;
int x, y, j;
for (y=0;y<152;y++) {
for (x=-(video.bitmap.xpos&7), j=0;x<160;x+=8, j++) {
UINT8 d1, d2;
if (video.bitmap.ypos<200) {
d1=video.bitmap.data[0][(y+video.bitmap.ypos)%200][(j+video.bitmap.xpos/8)&0x1f];
d2=video.bitmap.data[1][(y+video.bitmap.ypos)%200][(j+video.bitmap.xpos/8)&0x1f];
} else if ((video.bitmap.ypos&0xf)<8) { // lcdtest, of course still some registers not known, my gamate doesn't display bottom lines
int yi=(y+(video.bitmap.ypos&0xf)-8);
if (yi<0) yi=video.bitmap.ypos+y; // in this case only 2nd plane used!?, source of first plane?
d1=video.bitmap.data[0][yi][(j+video.bitmap.xpos/8)&0x1f]; // value of lines bevor 0 chaos
d2=video.bitmap.data[1][yi][(j+video.bitmap.xpos/8)&0x1f];
} else {
d1=video.bitmap.data[0][y][(j+video.bitmap.xpos/8)&0x1f];
d2=video.bitmap.data[1][y][(j+video.bitmap.xpos/8)&0x1f];
}
BlitPlane(&bitmap.pix16(y, x+4), d1, d2);
BlitPlane(&bitmap.pix16(y, x), d1>>4, d2>>4);
}
}
return 0;
}
DRIVER_INIT_MEMBER(gamate_state,gamate)
{
memset(&video, 0, sizeof(video));/* memset(m_ram, 0, sizeof(m_ram));*/
#ifdef USE_GFX
UINT8 *gfx=memregion("gfx1")->base();
for (int i=0; i<256; i++) gfx[i]=i;
#endif
timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gamate_state::gamate_timer),this));
timer2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gamate_state::gamate_timer2),this));
}
@ -329,14 +313,12 @@ DRIVER_INIT_MEMBER(gamate_state,gamate)
void gamate_state::machine_start()
{
m_cart_ptr = memregion("maincpu")->base() + 0x6000;
if (m_cart->exists()) {
// m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r));
m_cart_ptr = m_cart->get_rom_base();
// m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r));
membank("bankmulti")->set_base(m_cart->get_rom_base()+1);
membank("bank")->set_base(m_cart->get_rom_base()+0x4000); // bankswitched games in reality no offset
}
// m_bios[0xdf1]=0xea; m_bios[0xdf2]=0xea; // default bios: $47 protection readback
// m_bios[0xdf1]=0xea; m_bios[0xdf2]=0xea; // default bios: $47 protection readback
card_protection.set=false;
bank_multi=0;
card_protection.unprotected=false;
@ -367,7 +349,7 @@ TIMER_CALLBACK_MEMBER(gamate_state::gamate_timer2)
timer1->enable(TRUE);
timer1->reset(m_maincpu->cycles_to_attotime(10/* cycles short enought to clear irq line early enough*/));
timer2->enable(TRUE);
timer2->reset(m_maincpu->cycles_to_attotime(40000));
timer2->reset(m_maincpu->cycles_to_attotime(32768/2));
}
@ -376,7 +358,7 @@ INTERRUPT_GEN_MEMBER(gamate_state::gamate_interrupt)
}
static MACHINE_CONFIG_START( gamate, gamate_state )
MCFG_CPU_ADD("maincpu", M6502, 4433000)
MCFG_CPU_ADD("maincpu", M6502, 4433000/2)
MCFG_CPU_PROGRAM_MAP(gamate_mem)
MCFG_CPU_VBLANK_INT_DRIVER("screen", gamate_state, gamate_interrupt)
@ -387,13 +369,16 @@ static MACHINE_CONFIG_START( gamate, gamate_state )
MCFG_SCREEN_UPDATE_DRIVER(gamate_state, screen_update_gamate)
MCFG_SCREEN_PALETTE("palette")
#ifdef USE_GFX
MCFG_GFXDECODE_ADD("gfxdecode", "palette", gamate )
#endif
MCFG_PALETTE_ADD("palette", ARRAY_LENGTH(gamate_colors))
MCFG_PALETTE_INIT_OWNER(gamate_state, gamate)
MCFG_DEFAULT_LAYOUT(layout_lcd)
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("custom", GAMATE_SND, 0)
MCFG_SOUND_ROUTE(0, "lspeaker", 0.50)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.50)
MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_linear_slot, "gamate_cart")
MCFG_GENERIC_MANDATORY
@ -407,11 +392,10 @@ ROM_START(gamate)
ROMX_LOAD("gamate_bios_umc.bin", 0xf000, 0x1000, CRC(07090415) SHA1(ea449dc607601f9a68d855ad6ab53800d2e99297), ROM_BIOS(1) )
ROM_SYSTEM_BIOS(1, "newer", "NEWER")
ROMX_LOAD("gamate_bios_9130__unknown__bit_icasc00001_9130-bs_r32261.bin", 0xf000, 0x1000, CRC(03a5f3a7) SHA1(4e9dfbfe916ca485530ef4221593ab68738e2217), ROM_BIOS(2) )
#ifdef USE_GFX
ROM_REGION(0x100,"gfx1", ROMREGION_ERASEFF)
#endif
ROM_END
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */
CONS( 19??, gamate, 0, 0, gamate, gamate, gamate_state, gamate, "Bit Corp", "Gamate", GAME_NO_SOUND)
CONS( 19??, gamate, 0, 0, gamate, gamate, gamate_state, gamate, "Bit Corp", "Gamate", GAME_IMPERFECT_SOUND)

View File

@ -0,0 +1,62 @@
/*****************************************************************************
*
* includes/gamate.h
*
****************************************************************************/
#ifndef GAMATE_H_
#define GAMATE_H_
#include "cpu/m6502/m6502.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
struct GAMATE_CHANNEL
{
GAMATE_CHANNEL() :
// on(0),
// waveform(0),
volume(0),
pos(0),
size(0)
// count(0)
{
}
int on;
int /*waveform,*/ volume;
int pos;
int size;
// int count;
};
// ======================> gamate_sound_device
class gamate_sound_device : public device_t,
public device_sound_interface
{
public:
gamate_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~gamate_sound_device() { }
protected:
// device-level overrides
virtual void device_start();
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
public:
DECLARE_WRITE8_MEMBER( device_w );
private:
sound_stream *m_mixer_channel;
GAMATE_CHANNEL m_channels[3];
UINT8 reg[14];
};
extern const device_type GAMATE_SND;
#endif /* GAMATE_H_ */

View File

@ -1950,7 +1950,7 @@ $(MESSOBJ)/skeleton.a: \
$(MESS_DRIVERS)/fc100.o \
$(MESS_DRIVERS)/fk1.o \
$(MESS_DRIVERS)/ft68m.o \
$(MESS_DRIVERS)/gamate.o \
$(MESS_DRIVERS)/gamate.o $(MESS_AUDIO)/gamate.o \
$(MESS_DRIVERS)/gameking.o \
$(MESS_DRIVERS)/gimix.o \
$(MESS_DRIVERS)/grfd2301.o \