📄 system16.c
字号:
/*
working:
Alien Syndrome
Altered Beast
Aurail: some graphics glitches
Dynamite Dux: some graphics glitches
Flash Point: dipswitches are wrong
Golden Axe
Passing Shot: wrong screen orientation
SDI: I think it needs the analog controls mapped
Shinobi
Tetris
Time Scanner: wrong screen orientation; transparency and sprite glitches
Tough Turf: background glitches
Wonderboy 3 - Monster Lair
Wrestle War: some sprite glitches, wrong orientation
not really working:
Alex Kidd: no sprites, messed up graphics
Alien Storm: black screen
E-Swat: black screen
Heavyweight Champ: messed up graphics
Major League: missing sprites?
Quartet 2: no sprites, messed up background
other System16/18 games, not yet described in this file:
Hang-on
Space Harrier
Moonwalker
Outrun
Super Hangon
Shadow Dancer
*/
#define SYS16_CREDITS \
"Thierry Lescot & Nao (Hardware Info)\n" \
"Mirko Buffoni (MAME driver)\n" \
"Phil Stroffolino"
#include "driver.h"
#include "vidhrdw/generic.h"
#include "sndhrdw/2151intf.h"
/***************************************************************************/
extern int sys16_vh_start( void );
extern void sys16_vh_stop( void );
extern void sys16_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
/* video driver constants (vary with game) */
extern int sys16_spritesystem;
extern int sys16_sprxoffset;
extern int *sys16_obj_bank;
void (* sys16_update_proc)( void );
/* video driver registers */
extern int sys16_refreshenable;
extern int sys16_tile_bank0;
extern int sys16_tile_bank1;
extern int sys16_bg_scrollx, sys16_bg_scrolly;
extern int sys16_bg_page[4];
extern int sys16_fg_scrollx, sys16_fg_scrolly;
extern int sys16_fg_page[4];
/* video driver has access to these memory regions */
unsigned char *sys16_tileram;
unsigned char *sys16_textram;
unsigned char *sys16_spriteram;
/* other memory regions */
static unsigned char *sys16_ROM;
static unsigned char *sys16_workingram;
static unsigned char *sys16_extraram;
static unsigned char *sys16_extraram2;
static unsigned char *sys16_extraram3;
/* shared memory */
static int mirror1_hi_addr;
static int mirror1_lo_addr;
static int mirror1_word;
static int mirror2_hi_addr;
static int mirror2_lo_addr;
static int mirror2_word;
static int mirror3_hi_addr;
static int mirror3_lo_addr;
static int mirror3_word;
/***************************************************************************/
#define MWA_PALETTERAM sys16_paletteram_w, &paletteram
#define MRA_PALETTERAM paletteram_word_r
#define MRA_WORKINGRAM MRA_BANK1
#define MWA_WORKINGRAM MWA_BANK1,&sys16_workingram
#define MRA_SPRITERAM MRA_BANK2
#define MWA_SPRITERAM MWA_BANK2,&sys16_spriteram
#define MRA_TILERAM MRA_BANK3
#define MWA_TILERAM MWA_BANK3,&sys16_tileram
#define MRA_TEXTRAM MRA_BANK4
#define MWA_TEXTRAM MWA_BANK4,&sys16_textram
#define MRA_EXTRAM MRA_BANK5
#define MWA_EXTRAM MWA_BANK5,&sys16_extraram
#define MRA_EXTRAM2 MRA_BANK6
#define MWA_EXTRAM2 MWA_BANK6,&sys16_extraram2
#define MRA_EXTRAM3 MRA_BANK7
#define MWA_EXTRAM3 MWA_BANK7,&sys16_extraram3
/****************************************************************************
Some System16 games need mirrored addresses. In MAME this presents some
difficulties, because memory read/write handlers for 68000 games are
word-based. The following private functions make supporting mirrored
bytes easier.
****************************************************************************/
static void mirror1_w( int offset, int data ){
if( (data&0xff000000)==0 ){
if( mirror1_hi_addr )
cpu_writemem24( mirror1_hi_addr, (data>>8)&0xff );
else
mirror1_word = (mirror1_word&0x00ff) | (data&0xff00);
}
if( (data&0x00ff0000)==0 ){
if( mirror1_lo_addr )
cpu_writemem24( mirror1_lo_addr, data&0xff );
else
mirror1_word = (mirror1_word&0xff00) | (data&0xff);
}
}
static int mirror1_r( int offset ){
int data = mirror1_word;
if( mirror1_hi_addr ) data |= cpu_readmem24( mirror1_hi_addr )<<8;
if( mirror1_lo_addr ) data |= cpu_readmem24( mirror1_lo_addr );
if( data!= (input_port_0_r(offset) << 8) + input_port_1_r(offset) ){
/*if( errorlog ) fprintf( errorlog, "bad\n" );*/
}
return data;
}
static void define_mirror1( int hi_addr, int lo_addr ){
mirror1_word = 0;
mirror1_hi_addr = hi_addr;
mirror1_lo_addr = lo_addr;
}
static void mirror2_w( int offset, int data ){
if( (data&0xff000000)==0 ){
if( mirror2_hi_addr )
cpu_writemem24( mirror2_hi_addr, (data>>8)&0xff );
else
mirror2_word = (mirror2_word&0x00ff) | (data&0xff00);
}
if( (data&0x00ff0000)==0 ){
if( mirror2_lo_addr )
cpu_writemem24( mirror2_lo_addr, data&0xff );
else
mirror2_word = (mirror2_word&0xff00) | (data&0xff);
}
}
static int mirror2_r( int offset ){
int data = mirror2_word;
if( mirror2_hi_addr ) data |= cpu_readmem24( mirror2_hi_addr )<<8;
if( mirror2_lo_addr ) data |= cpu_readmem24( mirror2_lo_addr );
if( data!= (input_port_0_r(offset) << 8) + input_port_1_r(offset) ){
/*if( errorlog ) fprintf( errorlog, "bad\n" );*/
}
return data;
}
static void define_mirror2( int hi_addr, int lo_addr ){
mirror2_word = 0;
mirror2_hi_addr = hi_addr;
mirror2_lo_addr = lo_addr;
}
static void mirror3_w( int offset, int data ){
if( (data&0xff000000)==0 ){
if( mirror3_hi_addr )
cpu_writemem24( mirror3_hi_addr, (data>>8)&0xff );
else
mirror3_word = (mirror3_word&0x00ff) | (data&0xff00);
}
if( (data&0x00ff0000)==0 ){
if( mirror3_lo_addr )
cpu_writemem24( mirror3_lo_addr, data&0xff );
else
mirror3_word = (mirror3_word&0xff00) | (data&0xff);
}
}
static int mirror3_r( int offset ){
int data = mirror3_word;
if( mirror3_hi_addr ) data |= cpu_readmem24( mirror3_hi_addr )<<8;
if( mirror3_lo_addr ) data |= cpu_readmem24( mirror3_lo_addr );
if( data!= (input_port_0_r(offset) << 8) + input_port_1_r(offset) ){
/*if( errorlog ) fprintf( errorlog, "bad\n" );*/
}
return data;
}
static void define_mirror3( int hi_addr, int lo_addr ){
mirror3_word = 0;
mirror3_hi_addr = hi_addr;
mirror3_lo_addr = lo_addr;
}
/***************************************************************************/
#define MACHINE_DRIVER( GAMENAME,READMEM,WRITEMEM,INITMACHINE,GFXSIZE ) \
static struct MachineDriver GAMENAME = \
{ \
{ \
{ \
CPU_M68000, \
10000000, \
0, \
READMEM,WRITEMEM,0,0, \
sys16_interrupt,1 \
}, \
{ \
CPU_Z80 | CPU_AUDIO_CPU, \
4096000, \
3, \
sound_readmem,sound_writemem,sound_readport,sound_writeport, \
ignore_interrupt,1 \
}, \
}, \
60, DEFAULT_60HZ_VBLANK_DURATION, \
1, \
INITMACHINE, \
40*8, 28*8, { 0*8, 40*8-1, 0*8, 28*8-1 }, \
GFXSIZE, \
2048,2048, \
0, \
VIDEO_TYPE_RASTER | VIDEO_MODIFIES_PALETTE | VIDEO_SUPPORTS_DIRTY, \
0, \
sys16_vh_start, \
sys16_vh_stop, \
sys16_vh_screenrefresh, \
SOUND_SUPPORTS_STEREO,0,0,0, \
{ \
{ \
SOUND_YM2151, \
&ym2151_interface \
} \
} \
};
/***************************************************************************/
int sys16_interrupt( void ){
return 4; /* Interrupt vector 4, used by VBlank */
}
/***************************************************************************/
static struct MemoryReadAddress sound_readmem[] =
{
{ 0x0000, 0x7fff, MRA_ROM },
{ 0xf800, 0xffff, MRA_RAM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress sound_writemem[] =
{
{ 0x0000, 0x7fff, MWA_ROM },
{ 0xf800, 0xffff, MWA_RAM },
{ -1 } /* end of table */
};
static struct IOReadPort sound_readport[] =
{
{ 0x01, 0x01, YM2151_status_port_0_r },
{ 0xc0, 0xc0, soundlatch_r },
{ -1 } /* end of table */
};
static struct IOWritePort sound_writeport[] =
{
{ 0x00, 0x00, YM2151_register_port_0_w },
{ 0x01, 0x01, YM2151_data_port_0_w },
{ 0x40, 0x40, IOWP_NOP }, /* adpcm? */
{ 0x80, 0x80, IOWP_NOP }, /* ??? */
{ -1 }
};
static void sound_command_w(int offset, int data){
/*if( errorlog ) fprintf( errorlog, "SOUND COMMAND %04x <- %02x\n", offset, data&0xff );*/
soundlatch_w( 0,data&0xff );
cpu_cause_interrupt( 1, 0 );
}
static void irq_handler_mus(void){
}
static struct YM2151interface ym2151_interface =
{
1, /* 1 chip */
4096000, /* 3.58 MHZ ? */
{ 60 },
{ irq_handler_mus }
};
/***************************************************************************/
static struct GfxLayout charlayout1 =
{
8,8, /* 8*8 chars */
16384, /* 16384 chars */
3, /* 3 bits per pixel */
{ 0x20000*8, 0x10000*8, 0 },
{ 0, 1, 2, 3, 4, 5, 6, 7 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
8*8 /* every sprite takes 8 consecutive bytes */
};
static struct GfxLayout charlayout2 =
{
8,8, /* 8*8 chars */
16384, /* 16384 chars */
3, /* 3 bits per pixel */
{ 0x40000*8, 0x20000*8, 0 },
{ 0, 1, 2, 3, 4, 5, 6, 7 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
8*8 /* every sprite takes 8 consecutive bytes */
};
static struct GfxLayout charlayout4 =
{
8,8, /* 8*8 chars */
16384, /* 16384 chars */
3, /* 3 bits per pixel */
{ 0x80000*8, 0x40000*8, 0 },
{ 0, 1, 2, 3, 4, 5, 6, 7 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
8*8 /* every sprite takes 8 consecutive bytes */
};
static struct GfxLayout charlayout8 =
{
8,8, /* 8*8 chars */
16384, /* 16384 chars */
3, /* 3 bits per pixel */
{ 0x10000*8, 0x08000*8, 0 },
{ 0, 1, 2, 3, 4, 5, 6, 7 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
8*8 /* every sprite takes 8 consecutive bytes */
};
static struct GfxDecodeInfo gfx1[] =
{
{ 1, 0x00000, &charlayout1, 0, 256 },
{ -1 } /* end of array */
};
static struct GfxDecodeInfo gfx2[] =
{
{ 1, 0x00000, &charlayout2, 0, 256 },
{ -1 } /* end of array */
};
static struct GfxDecodeInfo gfx4[] =
{
{ 1, 0x00000, &charlayout4, 0, 256 },
{ -1 } /* end of array */
};
static struct GfxDecodeInfo gfx8[] =
{
{ 1, 0x00000, &charlayout8, 0, 256 },
{ -1 } /* end of array */
};
/***************************************************************************/
void sys16_paletteram_w(int offset, int data){
int oldword = READ_WORD (&paletteram[offset]);
int newword = COMBINE_WORD (oldword, data);
if( oldword!=newword ){
/* we can do this, because we initialize palette RAM to all black in vh_start */
/* byte 0 byte 1 */
/* GBGR BBBB GGGG RRRR */
/* 5444 3210 3210 3210 */
int r = (newword >> 0) & 0x0f;
int g = (newword >> 4) & 0x0f;
int b = (newword >> 8) & 0x0f;
r = (r << 1);
g = (g << 1);
b = (b << 1);
r = (r << 3) | (r >> 2);
g = (g << 3) | (g >> 2);
b = (b << 3) | (b >> 2);
palette_change_color( offset/2, r,g,b );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -