📄 arkanoi2.c
字号:
/***************************************************************************
Arkanoid 2 - Revenge of Doh!
(C) 1987 Taito
driver by
Luca Elia (eliavit@unina.it)
Mirko Buffoni
This game runs on almost the same hardware as "The New Zealand Story"'s
or maybe it's all the way round since this is an earlier game. See the
tnzs driver for a description of how the hardware works. I'll just hint
at some differences here:
- The values making up the fixed security sequence (read at startup from
c000 by the sound cpu) are different.
- Reads from c000 will yeld the coin counter and the input port 1 values
in an alternate fashion.
- c000 will be reset to yeld the coin counter when c001 is written. The
real mechanism of this has to be more complex (for example some specific
values are written there in sequence: 54h 41h), and yet to be understood.
This goes for the handling of the coin counter as well.
- Writes to c000 will modify the coin counter (the data written gets
subracted from it, as it seems). I don't know if tnzs acts the same.
- Bits 3-0 of f301 seem to have a different meaning in this game:
the only values written are AFAIK 2c,2a,20 and 01 (when some hardware
error message is shown on screen). The background must be drawn in either
case. What's more, the tiles must be drawn from f400 to f5ff (the opposite
order of tnzs). Bits 1&2, seem to have a function also.
- The game doesn't write to f800-fbff (static palette)
To be done
----------
- Test mode 2 (press start2 when test dsw L) doesn't work\display well.
- What do writes at f400 and f381 do ?
- Why the game zeros the fd00 area ?
- Does it need bankswitching ?
Interesting routines (main cpu)
-------------------------------
1ed prints the test screen (first string at 206)
47a prints dipsw1&2 e 1p&2p paddleL values:
e821 IN DIPSW1 e823-4 1P PaddleL (lo-hi)
e822 IN DIPSW2 e825-6 2P PaddleL (lo-hi)
584 prints OK or NG on each entry:
if (*addr)!=0 { if (*addr)!=2 OK else NG }
e880 1P PADDLEL e88a IN SERVICE
e881 1P PADDLER e88b IN TILT
e882 1P BUTTON e88c OUT LOCKOUT1
e883 1P START e88d OUT LOCKOUT2
e884 2P PADDLEL e88e IN DIP-SW1
e885 2P PADDLER e88f IN DIP-SW2
e886 2P BUTTON e890 SND OPN
e887 2P START e891 SND SSGCH1
e888 IN COIN1 e892 SND SSGCH2
e889 IN COIN2 e893 SND SSGCH3
672 prints a char
715 prints a string (0 terminated)
Shared Memory (values written mainly by the sound cpu)
------------------------------------------------------
e001=dip-sw A e399=coin counter value e72c-d=1P paddle (lo-hi)
e002=dip-sw B e3a0-2=1P score/10 (BCD) e72e-f=2P paddle (lo-hi)
e008=level=2*(shown_level-1)+x <- remember it's a binary tree (42 last)
e7f0=country code(from 9fde in sound rom)
e807=counter, reset by sound cpu, increased by main cpu each vblank
e80b=test progress=0(start) 1(first 8) 2(all ok) 3(error)
ec09-a~=ed05-6=xy pos of cursor in hi-scores
ec81-eca8=hi-scores(8bytes*5entries)
addr bit name active addr bit name active
e72d 6 coin[1] low e729 1 2p select low
5 service high 0 1p select low
4 coin[2] low
addr bit name active addr bit name active
e730 7 tilt low e7e7 4 1p fire low
0 2p fire low
Interesting routines (sound cpu)
--------------------------------
4ae check starts B73,B7a,B81,B99 coin related
8c1 check coins 62e lockout check 664 dsw check
Interesting locations (sound cpu)
---------------------------------
d006=each bit is on if a corresponding location (e880-e887) has changed
d00b=(c001)>>4=tilt if 0E (security sequence must be reset?)
addr bit name active
d00c 7 tilt
6 ?service?
5 coin2 low
4 coin1 low
d00d=each bit is on if the corresponding location (e880-e887) is 1 (OK)
d00e=each of the 4 MSBs is on if ..
d00f=FF if tilt, 00 otherwise
d011=if 00 checks counter, if FF doesn't
d23f=input port 1 value
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
/* prototypes for functions in ../machine/tnzs.c */
extern unsigned char *tnzs_objram, *tnzs_workram;
extern unsigned char *tnzs_vdcram, *tnzs_scrollram;
void tnzs_init_machine (void);
int tnzs_workram_r (int offset);
void tnzs_workram_w (int offset, int data);
extern int current_inputport; /* reads of c000 (sound cpu) expect a sequence of values */
extern int number_of_credits;
/* prototypes for functions in ../vidhrdw/tnzs.c */
int tnzs_vh_start(void);
void tnzs_vh_stop(void);
void arkanoi2_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
void arkanoi2_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
/*
**
** Main cpu data
**
**
*/
static struct MemoryReadAddress readmem[] =
{
{ 0x0000, 0x9fff, MRA_ROM }, /* Code ROM */
{ 0xc000, 0xdfff, MRA_RAM },
{ 0xe000, 0xefff, tnzs_workram_r }, /* WORK RAM (shared by the 2 z80's */
{ 0xf000, 0xf1ff, MRA_RAM }, /* VDC RAM */
{ -1 } /* end of table */
};
static struct MemoryWriteAddress writemem[] =
{
{ 0x0000, 0x9fff, MWA_ROM }, /* Code ROM */
{ 0xc000, 0xdfff, MWA_RAM, &tnzs_objram },
{ 0xe000, 0xefff, tnzs_workram_w, &tnzs_workram },
{ 0xf000, 0xf1ff, MWA_RAM, &tnzs_vdcram },
{ 0xf200, 0xf3ff, MWA_RAM, &tnzs_scrollram }, /* scrolling info */
{ -1 } /* end of table */
};
/*
**
** Sound cpu data
**
*/
/* number of input ports to be cycled through (coins, buttons etc.) */
#define ip_num 2
int arkanoi2_inputport_r(int offset)
{
int ret;
if (offset == 0)
{
switch(current_inputport)
{
case -3: ret = 0x55; break;
case -2: ret = 0xaa; break;
case -1: ret = 0x5a; break;
case ip_num: current_inputport = 0; /* fall through */
case 0: ret = number_of_credits; break;
default: ret = readinputport(current_inputport); break;
}
current_inputport++;
return ret;
}
else
return (0x01); /* 0xE1 for tilt, 31 service ok */
}
void arkanoi2_inputport_w(int offset, int data)
{
if (offset == 0)
number_of_credits -= ((~data)&0xff)+1; /* sub data from credits */
else
/* TBD: value written (or its low nibble) subtracted from sequence index? */
if (current_inputport>=0) /* if the initial sequence is done */
current_inputport=0; /* reset input port number */
}
/* Here we simulate a 12 bit dial position with mame's built-in 8 bit one */
int arkanoi2_sh_f000_r(int offs)
{
static int pos=0;
static int lastval=0;
int val;
int cur_pos;
char diff;
cur_pos=pos;
val = readinputport(0)&0xff;
diff = (char)val-(char)lastval;
lastval = val;
pos += diff;
if(offs==0) cur_pos=pos;
val = (readinputport(4)<<8)+(cur_pos&0x0fff);
if (offs==0)
return val&0xff;
else
return val>>8;
}
static struct MemoryReadAddress sound_readmem[] =
{
{ 0x0000, 0x9fff, MRA_ROM }, /* code ROM */
{ 0xb000, 0xb000, YM2203_status_port_0_r },
{ 0xb001, 0xb001, YM2203_read_port_0_r },
{ 0xc000, 0xc001, arkanoi2_inputport_r }, /* returns coins,input port, etc. */
{ 0xd000, 0xdfff, MRA_RAM },
{ 0xe000, 0xefff, tnzs_workram_r },
{ 0xf000, 0xf001, arkanoi2_sh_f000_r }, /* IN0 paddle */
{ 0xf002, 0xf003, arkanoi2_sh_f000_r }, /* IN0 paddle (the same?)*/
{ -1 } /* end of table */
};
static struct MemoryWriteAddress sound_writemem[] =
{
{ 0x0000, 0x9fff, MWA_ROM }, /* code ROM */
{ 0xb000, 0xb000, YM2203_control_port_0_w }, /* YM control */
{ 0xb001, 0xb001, YM2203_write_port_0_w }, /* YM data write */
{ 0xc000, 0xc001, arkanoi2_inputport_w }, /* sub coins, reset input port */
{ 0xd000, 0xdfff, MWA_RAM },
{ 0xe000, 0xefff, tnzs_workram_w },
{ -1 } /* end of table */
};
INPUT_PORTS_START( input_ports )
PORT_START /* IN0 - spinner (1 paddle?) */
PORT_ANALOG( 0xff, 0x00, IPT_DIAL, 32, 0, 0, 0)
PORT_START /* IN1 - read at c000 (sound cpu) */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 )
PORT_START /* DSW1 - IN2 */
PORT_DIPNAME( 0x01, 0x01, "Game Style", IP_KEY_NONE )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -