📄 segar.c
字号:
/***************************************************************************
Sega G-80 Raster drivers
The G-80 Raster games are Astro Blaster, Monster Bash, 005, Space Odyssey,
and Pig Newton.
See also sega.c for the Sega G-80 Vector games.
Many thanks go to Dave Fish for the fine detective work he did into the
G-80 security chips (315-0064, 315-0070, 315-0076, 315-0082) which provided
me with enough information to emulate those chips at runtime along with
the 315-0062 Astro Blaster chip and the 315-0063 Space Odyssey chip.
Thanks also go to Paul Tonizzo, Clay Cowgill, John Bowes, and Kevin Klopp
for all the helpful information, samples, and schematics!
TODO:
- redo TMS3617 to use streams (and fix)
- fix Pig Newton colors
- fix Pig Newton hi load/save
- locate Pig Newton cocktail mode?
- verify Pig Newton DIPs
- attempt Pig Newton sound
- add Astro Blaster 8035 CPU
b4 - 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
b5 - 28 20 22 44 1f 06 1c 1d 00 07 00 00 00 00 00 00
00 101 000
00 100 000
00 100 010
01 000 100
00 011 111
00 000 110
00 011 100
00 011 101
b9 - 80, 81, 82, 83
bb - seems to be a counter of how many times b9 loops back to 80
b8 - always 00
ba - usually 00, had some 01 when b9=82
bc - 00 at the start, gets 05 right before b9=83
(probably sound?)
be - 00 and 05 alternating until the end,
there's a 04, 02, 06, 03, 01, 06, 01, 03, 05, 02, 07, 03,
07, 03, 07, 03, 07, 02, 05, 01, 04, 06, 01, 04,
06, 02, 04, 06, 01, 02, 03, 04, 05
- Mike Balfour (mab22@po.cwru.edu)
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
/* sndhrdw/segar.c */
extern void astrob_speech_port_w(int offset, int data);
extern void astrob_audio_ports_w(int offset, int data);
extern void spaceod_audio_ports_w(int offset, int data);
extern void monsterb_audio_8255_w(int offset, int data);
extern int monsterb_audio_8255_r(int offset);
/* temporary speech handling through samples */
extern int astrob_speech_sh_start(void);
extern void astrob_speech_sh_update(void);
/* sndhrdw/monsterb.c */
extern int TMS3617_sh_start(void);
extern void TMS3617_sh_stop(void);
extern void TMS3617_sh_update(void);
extern const char *astrob_sample_names[];
extern const char *s005_sample_names[];
extern const char *monsterb_sample_names[];
extern const char *spaceod_sample_names[];
/* machine/segar.c */
extern void sega_security(int chip);
extern void segar_wr(int offset, int data);
extern unsigned char *segar_mem;
/* vidhrdw/segar.c */
extern unsigned char *segar_characterram;
extern unsigned char *segar_characterram2;
extern unsigned char *segar_mem_colortable;
extern unsigned char *segar_mem_bcolortable;
extern unsigned char *segar_mem_blookup;
extern void segar_init_colors(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
extern void segar_video_port_w(int offset,int data);
extern void segar_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
extern void monsterb_back_port_w(int offset,int data);
extern void monsterb_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
extern int spaceod_vh_start(void);
extern void spaceod_vh_stop(void);
extern void spaceod_back_port_w(int offset,int data);
extern void spaceod_backshift_w(int offset,int data);
extern void spaceod_backshift_clear_w(int offset,int data);
extern void spaceod_backfill_w(int offset,int data);
extern void spaceod_nobackfill_w(int offset,int data);
extern void spaceod_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
extern void pignewt_back_color_w(int offset,int data);
extern void pignewt_back_ports_w(int offset,int data);
extern void pignewt_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
/* drivers/segar.c */
static int segar_interrupt(void);
static int segar_read_ports(int offset);
static struct MemoryReadAddress readmem[] =
{
{ 0x0000, 0xC7FF, MRA_ROM },
{ 0xC800, 0xCFFF, MRA_RAM }, /* Misc RAM */
{ 0xE000, 0xE3FF, MRA_RAM, &videoram, &videoram_size },
{ 0xE400, 0xE7FF, MRA_RAM }, /* Used by at least Monster Bash? */
{ 0xE800, 0xEFFF, MRA_RAM, &segar_characterram },
{ 0xF000, 0xF03F, MRA_RAM, &segar_mem_colortable }, /* Dynamic color table */
{ 0xF040, 0xF07F, MRA_RAM, &segar_mem_bcolortable }, /* Dynamic color table for background (Monster Bash)*/
{ 0xF080, 0xF7FF, MRA_RAM },
{ 0xF800, 0xFFFF, MRA_RAM, &segar_characterram2 },
{0x10000,0x13FFF, MRA_ROM, &segar_mem_blookup }, /* Background pattern ROMs (not all games use this) */
{ -1 } /* end of table */
};
static struct MemoryWriteAddress writemem[] =
{
{ 0x0000, 0xFFFF, segar_wr, &segar_mem },
{ -1 }
};
static struct IOReadPort readport[] =
{
{0x3f, 0x3f, MRA_NOP }, /* Pig Newton - read from 1D87 */
{ 0x0e, 0x0e, monsterb_audio_8255_r },
{ 0xf8, 0xfc, segar_read_ports },
{ -1 } /* end of table */
};
static struct IOWritePort astrob_writeport[] =
{
{ 0x38, 0x38, astrob_speech_port_w },
{ 0x3e, 0x3f, astrob_audio_ports_w },
{ 0xbf, 0xbf, segar_video_port_w }, /* bit0=cocktail flip, bit1=write to color RAM, bit2=always on?, bit6=write to background color RAM */
{ -1 } /* end of table */
};
static struct IOWritePort spaceod_writeport[] =
{
{ 0x08, 0x08, spaceod_back_port_w },
{ 0x09, 0x09, spaceod_backshift_clear_w },
{ 0x0a, 0x0a, spaceod_backshift_w },
{ 0x0b, 0x0c, spaceod_nobackfill_w }, /* I'm not sure what these ports really do */
{ 0x0d, 0x0d, spaceod_backfill_w },
{ 0x0e, 0x0f, spaceod_audio_ports_w },
{ 0xbf, 0xbf, segar_video_port_w }, /* bit0=cocktail flip, bit1=write to color RAM, bit2=always on?, bit6=write to background color RAM */
{ -1 } /* end of table */
};
static struct IOWritePort s005_writeport[] =
{
{ 0xbf, 0xbf, segar_video_port_w }, /* bit0=cocktail flip, bit1=write to color RAM, bit2=always on?, bit6=write to background color RAM */
{ -1 } /* end of table */
};
static struct IOWritePort monsterb_writeport[] =
{
{ 0x0c, 0x0f, monsterb_audio_8255_w },
{ 0xbc, 0xbc, monsterb_back_port_w },
{ 0xbf, 0xbf, segar_video_port_w }, /* bit0=cocktail flip, bit1=write to color RAM, bit2=always on?, bit6=write to background color RAM */
{ -1 } /* end of table */
};
static struct IOWritePort pignewt_writeport[] =
{
{ 0xb4, 0xb5, pignewt_back_color_w }, /* Just guessing */
{ 0xb8, 0xbc, pignewt_back_ports_w }, /* Just guessing */
{ 0xbe, 0xbe, MWA_NOP }, /* probably some type of music register */
{ 0xbf, 0xbf, segar_video_port_w }, /* bit0=cocktail flip, bit1=write to color RAM, bit2=always on?, bit6=write to background color RAM */
{ -1 } /* end of table */
};
static struct MemoryReadAddress speech_readmem[] =
{
{ 0x0000, 0x07ff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress speech_writemem[] =
{
{ 0x0000, 0x07ff, MWA_ROM },
{ -1 } /* end of table */
};
static struct IOReadPort speech_readport[] =
{
{ -1 } /* end of table */
};
static struct IOWritePort speech_writeport[] =
{
{ -1 } /* end of table */
};
/***************************************************************************
The Sega games use NMI to trigger the self test. We use a fake input port to
tie that event to a keypress.
***************************************************************************/
static int segar_interrupt(void)
{
if (readinputport(5) & 1) /* get status of the F2 key */
return nmi_interrupt(); /* trigger self test */
else return interrupt();
}
/***************************************************************************
The Sega games store the DIP switches in a very mangled format that's
not directly useable by MAME. This function mangles the DIP switches
into a format that can be used.
Original format:
Port 0 - 2-4, 2-8, 1-4, 1-8
Port 1 - 2-3, 2-7, 1-3, 1-7
Port 2 - 2-2, 2-6, 1-2, 1-6
Port 3 - 2-1, 2-5, 1-1, 1-5
MAME format:
Port 6 - 1-1, 1-2, 1-3, 1-4, 1-5, 1-6, 1-7, 1-8
Port 7 - 2-1, 2-2, 2-3, 2-4, 2-5, 2-6, 2-7, 2-8
***************************************************************************/
static int segar_read_ports(int offset)
{
int dip1, dip2;
dip1 = input_port_6_r(offset);
dip2 = input_port_7_r(offset);
switch(offset)
{
case 0:
return ((input_port_0_r(0) & 0xF0) | ((dip2 & 0x08)>>3) | ((dip2 & 0x80)>>6) |
((dip1 & 0x08)>>1) | ((dip1 & 0x80)>>4));
case 1:
return ((input_port_1_r(0) & 0xF0) | ((dip2 & 0x04)>>2) | ((dip2 & 0x40)>>5) |
((dip1 & 0x04)>>0) | ((dip1 & 0x40)>>3));
case 2:
return ((input_port_2_r(0) & 0xF0) | ((dip2 & 0x02)>>1) | ((dip2 & 0x20)>>4) |
((dip1 & 0x02)<<1) | ((dip1 & 0x20)>>2));
case 3:
return ((input_port_3_r(0) & 0xF0) | ((dip2 & 0x01)>>0) | ((dip2 & 0x10)>>3) |
((dip1 & 0x01)<<2) | ((dip1 & 0x10)>>1));
case 4:
return input_port_4_r(0);
}
return 0;
}
/***************************************************************************
Input Ports
***************************************************************************/
INPUT_PORTS_START( astrob_input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN3 )
PORT_BITX(0x40, IP_ACTIVE_LOW, IPT_COIN2 | IPF_IMPULSE,
IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 3 )
PORT_BITX(0x80, IP_ACTIVE_LOW, IPT_COIN1 | IPF_IMPULSE,
IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 3 )
PORT_START /* IN1 */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* IN2 */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* IN3 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -