📄 tokio.c
字号:
/***************************************************************************
Tokio memory map
CPU 1
0000-bfff ROM (8000-bfff is banked)
c000-dcff Graphic RAM. This contains pointers to the video RAM columns and
to the sprites contained in Object RAM.
dd00-dfff Object RAM (groups of four bytes: X position, code [offset in the
Graphic RAM], Y position, gfx bank)
e000-f7ff RAM (Shared)
f800-f9ff Palette RAM
fa03 - DSW0
fa04 - DSW1
fa05 - Coins
fa06 - Controls Player 1
fa07 - Controls Player 1
CPU 2
0000-7fff ROM
8000-97ff RAM (Shared)
CPU 3
0000-7fff ROM
8000-8fff RAM
Here goes a list of known deficiencies of our drivers:
- The bootleg romset is functional. The original one hangs at
the title screen. This is because Fredrik and I have worked
on the first one, and got mostly done. Later Victor added support
for the original set (mainly sound), which is still deficient.
- Score saving is still wrong, I think.
- Sound support is a bit buggy.
- Gfx bug with large "block" sprites: the big tank on the main
street, the big mothership and (I guess) the ground turrets later
in the game.
I am pretty confident the scrolling is right (it was a bitch to get
right), and almost sure the normal sprites are handled correctly.
However, I think there's still some work to be done with the block
sprites.
The problem is that the object memory seems to have special
meaning associated with the higher two bits of the 'map' and the
'bank' entries. For example, the big tank on the ground should be
drawn with a height of 64 pixels instead of the usual 32.
One guess: after some bits are set, a number following entries in
the object ram could describe aditional sections of the block
sprite, to be positioned right next to the first one. So in this
scheme the tank would take two entries, but with just one with
valid positioning.
- "fake-r" routine make the "original" roms to restart the game after
some seconds.
Well, we know very little about the 0xFE00 address. It could be
some watchdog or a synchronization timer.
I remember scanning the main CPU code to find how it was
used on the bootleg set. Then I just figured out a constant value
that made the game run (it hang if just set unhandled, that is,
returning zero).
Maybe the solution is to patch the bootleg ROMs to skip some tests
at this location (I remember some of them being in the
initialization routine of the main CPU).
Marcelo de G. Malheiros <malheiro@dca.fee.unicamp.br>
1998.9.25
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#include "z80/z80.h"
extern unsigned char *tokio_objectram;
extern int tokio_objectram_size;
void bublbobl_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
int tokio_vh_start(void);
void tokio_vh_stop(void);
int tokio_videoram_r(int offset);
void tokio_videoram_w(int offset,int data);
int tokio_objectram_r(int offset);
void tokio_objectram_w(int offset,int data);
void tokio_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
unsigned char *tokio_sharedram;
int tokio_sharedram_r(int offset)
{
return tokio_sharedram[offset];
}
void tokio_sharedram_w(int offset, int data)
{
tokio_sharedram[offset] = data;
}
void tokio_bankswitch_w(int offset,int data)
{
unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];
cpu_setbank(1, &RAM[0x10000 + 0x4000 * (data & 7)]);
}
void tokio_nmitrigger_w(int offset, int data)
{
cpu_cause_interrupt(1,Z80_NMI_INT);
}
void tokio_sound_command_w(int offset,int data)
{
soundlatch_w(offset,data);
cpu_cause_interrupt(2,Z80_NMI_INT);
}
static int fake_r(int offset)
{
return 0xbf; /* ad-hoc value set to pass initial testing */
}
static struct MemoryReadAddress readmem[] =
{
{ 0x0000, 0x7fff, MRA_ROM },
{ 0x8000, 0xbfff, MRA_BANK1 },
{ 0xc000, 0xdcff, tokio_videoram_r },
{ 0xdd00, 0xdfff, tokio_objectram_r },
{ 0xe000, 0xf7ff, tokio_sharedram_r },
{ 0xf800, 0xf9ff, paletteram_r },
{ 0xfa03, 0xfa03, input_port_0_r },
{ 0xfa04, 0xfa04, input_port_1_r },
{ 0xfa05, 0xfa05, input_port_2_r },
{ 0xfa06, 0xfa06, input_port_3_r },
{ 0xfa07, 0xfa07, input_port_4_r },
{ 0xfe00, 0xfe00, fake_r },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress writemem[] =
{
{ 0x0000, 0xbfff, MWA_ROM },
{ 0xc000, 0xdcff, tokio_videoram_w, &videoram, &videoram_size },
{ 0xdd00, 0xdfff, tokio_objectram_w, &tokio_objectram, &tokio_objectram_size },
{ 0xe000, 0xf7ff, tokio_sharedram_w, &tokio_sharedram },
{ 0xf800, 0xf9ff, paletteram_RRRRGGGGBBBBxxxx_swap_w, &paletteram },
{ 0xfa00, 0xfa00, MWA_NOP },
{ 0xfa80, 0xfa80, tokio_bankswitch_w },
{ 0xfb00, 0xfb00, MWA_NOP }, /* ??? */
{ 0xfb80, 0xfb80, tokio_nmitrigger_w },
{ 0xfc00, 0xfc00, tokio_sound_command_w },
{ 0xfe00, 0xfe00, MWA_NOP }, /* ??? */
{ -1 } /* end of table */
};
static struct MemoryReadAddress readmem_video[] =
{
{ 0x0000, 0x7fff, MRA_ROM },
{ 0x8000, 0x97ff, tokio_sharedram_r },
{ 0xf800, 0xf9ff, paletteram_r },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress writemem_video[] =
{
{ 0x0000, 0x7fff, MWA_ROM },
{ 0x8000, 0x97ff, tokio_sharedram_w, &tokio_sharedram },
{ 0xf800, 0xf9ff, paletteram_RRRRGGGGBBBBxxxx_swap_w },
{ -1 } /* end of table */
};
static struct MemoryReadAddress sound_readmem[] =
{
{ 0x0000, 0x7fff, MRA_ROM },
{ 0x8000, 0x8fff, MRA_RAM },
{ 0x9000, 0x9000, soundlatch_r },
{ 0xb000, 0xb000, YM2203_status_port_0_r },
{ 0xb001, 0xb001, YM2203_read_port_0_r },
{ 0xe000, 0xefff, MRA_ROM }, /* space for diagnostic ROM? */
{ -1 } /* end of table */
};
static struct MemoryWriteAddress sound_writemem[] =
{
{ 0x0000, 0x7fff, MWA_ROM },
{ 0x8000, 0x8fff, MWA_RAM },
{ 0xb000, 0xb000, YM2203_control_port_0_w },
{ 0xb001, 0xb001, YM2203_write_port_0_w },
{ 0xe000, 0xefff, MWA_ROM }, /* space for diagnostic ROM? */
{ -1 } /* end of table */
};
INPUT_PORTS_START( tokio_input_ports )
PORT_START /* DSW0 */
PORT_DIPNAME( 0x01, 0x00, "Cabinet", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Upright" )
PORT_DIPSETTING( 0x01, "Cocktail" )
PORT_DIPNAME( 0x02, 0x02, "Flip Screen", IP_KEY_NONE )
PORT_DIPSETTING( 0x02, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BITX( 0x04, 0x04, IPT_DIPSWITCH_NAME | IPF_TOGGLE, "Service Mode", OSD_KEY_F2, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x04, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x08, 0x08, "Demo Sounds?", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Off" )
PORT_DIPSETTING( 0x08, "On" )
PORT_DIPNAME( 0x30, 0x30, "Coin A", IP_KEY_NONE )
PORT_DIPSETTING( 0x10, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x30, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x00, "2 Coins/3 Credits" )
PORT_DIPSETTING( 0x20, "1 Coin/2 Credits" )
PORT_DIPNAME( 0xc0, 0xc0, "Coin B", IP_KEY_NONE )
PORT_DIPSETTING( 0x40, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0xc0, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x00, "2 Coins/3 Credits" )
PORT_DIPSETTING( 0x80, "1 Coin/2 Credits" )
PORT_START /* DSW1 */
PORT_DIPNAME( 0x03, 0x02, "Difficulty", IP_KEY_NONE )
PORT_DIPSETTING( 0x03, "Easy" )
PORT_DIPSETTING( 0x02, "Medium" )
PORT_DIPSETTING( 0x01, "Hard" )
PORT_DIPSETTING( 0x00, "Hardest" )
PORT_DIPNAME( 0x0c, 0x08, "Bonus Life", IP_KEY_NONE )
PORT_DIPSETTING( 0x0C, "100000 400000" )
PORT_DIPSETTING( 0x08, "200000 400000" )
PORT_DIPSETTING( 0x04, "300000 400000" )
PORT_DIPSETTING( 0x00, "400000 400000" )
PORT_DIPNAME( 0x30, 0x30, "Lives", IP_KEY_NONE )
PORT_DIPSETTING( 0x30, "3" )
PORT_DIPSETTING( 0x20, "4" )
PORT_DIPSETTING( 0x10, "5" )
PORT_DIPSETTING( 0x00, "6" )
PORT_DIPNAME( 0x40, 0x40, "Unknown", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "A" )
PORT_DIPSETTING( 0x40, "B" )
PORT_DIPNAME( 0x80, 0x00, "Language", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "English" )
PORT_DIPSETTING( 0x80, "Japanese" )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_TILT )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN3 ) /* service */
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_2WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_2WAY )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_2WAY )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_2WAY )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* IN2 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_2WAY | IPF_PLAYER2 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_2WAY | IPF_PLAYER2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_2WAY | IPF_PLAYER2 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_2WAY | IPF_PLAYER2 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
INPUT_PORTS_START( tokiob_input_ports )
PORT_START /* DSW0 */
PORT_DIPNAME( 0x01, 0x00, "Cabinet", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Upright" )
PORT_DIPSETTING( 0x01, "Cocktail" )
PORT_DIPNAME( 0x02, 0x02, "Flip Screen", IP_KEY_NONE )
PORT_DIPSETTING( 0x02, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BITX( 0x04, 0x04, IPT_DIPSWITCH_NAME | IPF_TOGGLE, "Service Mode", OSD_KEY_F2, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x04, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x08, 0x08, "Demo Sounds?", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Off" )
PORT_DIPSETTING( 0x08, "On" )
PORT_DIPNAME( 0x30, 0x30, "Coin A", IP_KEY_NONE )
PORT_DIPSETTING( 0x10, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x30, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x00, "2 Coins/3 Credits" )
PORT_DIPSETTING( 0x20, "1 Coin/2 Credits" )
PORT_DIPNAME( 0xc0, 0xc0, "Coin B", IP_KEY_NONE )
PORT_DIPSETTING( 0x40, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0xc0, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x00, "2 Coins/3 Credits" )
PORT_DIPSETTING( 0x80, "1 Coin/2 Credits" )
PORT_START /* DSW1 */
PORT_DIPNAME( 0x03, 0x02, "Difficulty", IP_KEY_NONE )
PORT_DIPSETTING( 0x03, "Easy" )
PORT_DIPSETTING( 0x02, "Medium" )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -