Added driver data struct to airbustr.c and djboy.c. Now the latter also supports saves (the former already did).

This commit is contained in:
Fabio Priuli 2009-12-11 10:51:55 +00:00
parent 9f1254ed51
commit 989a275f22
4 changed files with 504 additions and 463 deletions

View File

@ -223,46 +223,32 @@ Code at 505: waits for bit 1 to go low, writes command, waits for bit
#include "sound/2203intf.h" #include "sound/2203intf.h"
#include "sound/okim6295.h" #include "sound/okim6295.h"
#include "video/kan_pand.h" #include "video/kan_pand.h"
#include "includes/airbustr.h"
static UINT8 *devram;
static int soundlatch_status, soundlatch2_status;
static int master_addr;
static int slave_addr;
extern UINT8 *airbustr_videoram2, *airbustr_colorram2;
extern WRITE8_HANDLER( airbustr_videoram_w );
extern WRITE8_HANDLER( airbustr_colorram_w );
extern WRITE8_HANDLER( airbustr_videoram2_w );
extern WRITE8_HANDLER( airbustr_colorram2_w );
extern WRITE8_HANDLER( airbustr_scrollregs_w );
extern VIDEO_START( airbustr );
extern VIDEO_UPDATE( airbustr );
extern VIDEO_EOF( airbustr );
/* Read/Write Handlers */ /* Read/Write Handlers */
static READ8_HANDLER( devram_r ) static READ8_HANDLER( devram_r )
{ {
// There's an MCU here, possibly airbustr_state *state = (airbustr_state *)space->machine->driver_data;
// There's an MCU here, possibly
switch (offset) switch (offset)
{ {
/* Reading efe0 probably resets a watchdog mechanism /* Reading efe0 probably resets a watchdog mechanism
that would reset the main cpu. We avoid this and patch that would reset the main cpu. We avoid this and patch
the rom instead (main cpu has to be reset once at startup) */ the rom instead (main cpu has to be reset once at startup) */
case 0xfe0: case 0xfe0:
return watchdog_reset_r(space,0); return watchdog_reset_r(space, 0);
/* Reading a word at eff2 probably yelds the product /* Reading a word at eff2 probably yelds the product
of the words written to eff0 and eff2 */ of the words written to eff0 and eff2 */
case 0xff2: case 0xff2:
case 0xff3: case 0xff3:
{ {
int x = (devram[0xff0] + devram[0xff1] * 256) * int x = (state->devram[0xff0] + state->devram[0xff1] * 256) * (state->devram[0xff2] + state->devram[0xff3] * 256);
(devram[0xff2] + devram[0xff3] * 256); if (offset == 0xff2)
if (offset == 0xff2) return (x & 0x00FF) >> 0; return (x & 0x00ff) >> 0;
else return (x & 0xFF00) >> 8; else
return (x & 0xff00) >> 8;
} break; } break;
/* Reading eff4, F0 times must yield at most 80-1 consecutive /* Reading eff4, F0 times must yield at most 80-1 consecutive
@ -271,91 +257,88 @@ static READ8_HANDLER( devram_r )
return mame_rand(space->machine); return mame_rand(space->machine);
default: default:
return devram[offset]; return state->devram[offset];
} }
} }
static WRITE8_HANDLER( master_nmi_trigger_w ) static WRITE8_HANDLER( master_nmi_trigger_w )
{ {
cputag_set_input_line(space->machine, "slave", INPUT_LINE_NMI, PULSE_LINE); airbustr_state *state = (airbustr_state *)space->machine->driver_data;
} cpu_set_input_line(state->slave, INPUT_LINE_NMI, PULSE_LINE);
static void airbustr_bankswitch(running_machine *machine, const char *cpu, const char *bank, int data)
{
UINT8 *ROM = memory_region(machine, cpu);
if ((data & 0x07) < 3)
ROM = &ROM[0x4000 * (data & 0x07)];
else
ROM = &ROM[0x10000 + 0x4000 * ((data & 0x07) - 3)];
memory_set_bankptr(machine, bank, ROM);
} }
static WRITE8_HANDLER( master_bankswitch_w ) static WRITE8_HANDLER( master_bankswitch_w )
{ {
airbustr_bankswitch(space->machine, "master", "bank1", data); memory_set_bank(space->machine, "bank1", data & 0x07);
} }
static WRITE8_HANDLER( slave_bankswitch_w ) static WRITE8_HANDLER( slave_bankswitch_w )
{ {
const device_config *pandora = devtag_get_device(space->machine, "pandora"); airbustr_state *state = (airbustr_state *)space->machine->driver_data;
airbustr_bankswitch(space->machine, "slave", "bank2", data);
memory_set_bank(space->machine, "bank2", data & 0x07);
flip_screen_set(space->machine, data & 0x10); flip_screen_set(space->machine, data & 0x10);
// used at the end of levels, after defeating the boss, to leave trails // used at the end of levels, after defeating the boss, to leave trails
pandora_set_clear_bitmap(pandora, data&0x20); pandora_set_clear_bitmap(state->pandora, data & 0x20);
} }
static WRITE8_HANDLER( sound_bankswitch_w ) static WRITE8_HANDLER( sound_bankswitch_w )
{ {
airbustr_bankswitch(space->machine, "audiocpu", "bank3", data); memory_set_bank(space->machine, "bank3", data & 0x07);
} }
static READ8_HANDLER( soundcommand_status_r ) static READ8_HANDLER( soundcommand_status_r )
{ {
airbustr_state *state = (airbustr_state *)space->machine->driver_data;
// bits: 2 <-> ? 1 <-> soundlatch full 0 <-> soundlatch2 empty // bits: 2 <-> ? 1 <-> soundlatch full 0 <-> soundlatch2 empty
return 4 + soundlatch_status * 2 + (1 - soundlatch2_status); return 4 + state->soundlatch_status * 2 + (1 - state->soundlatch2_status);
} }
static READ8_HANDLER( soundcommand_r ) static READ8_HANDLER( soundcommand_r )
{ {
soundlatch_status = 0; // soundlatch has been read airbustr_state *state = (airbustr_state *)space->machine->driver_data;
return soundlatch_r(space,0); state->soundlatch_status = 0; // soundlatch has been read
return soundlatch_r(space, 0);
} }
static READ8_HANDLER( soundcommand2_r ) static READ8_HANDLER( soundcommand2_r )
{ {
soundlatch2_status = 0; // soundlatch2 has been read airbustr_state *state = (airbustr_state *)space->machine->driver_data;
return soundlatch2_r(space,0); state->soundlatch2_status = 0; // soundlatch2 has been read
return soundlatch2_r(space, 0);
} }
static WRITE8_HANDLER( soundcommand_w ) static WRITE8_HANDLER( soundcommand_w )
{ {
airbustr_state *state = (airbustr_state *)space->machine->driver_data;
soundlatch_w(space, 0, data); soundlatch_w(space, 0, data);
soundlatch_status = 1; // soundlatch has been written state->soundlatch_status = 1; // soundlatch has been written
cputag_set_input_line(space->machine, "audiocpu", INPUT_LINE_NMI, PULSE_LINE); // cause a nmi to sub cpu cpu_set_input_line(state->audiocpu, INPUT_LINE_NMI, PULSE_LINE); // cause a nmi to sub cpu
} }
static WRITE8_HANDLER( soundcommand2_w ) static WRITE8_HANDLER( soundcommand2_w )
{ {
airbustr_state *state = (airbustr_state *)space->machine->driver_data;
soundlatch2_w(space, 0, data); soundlatch2_w(space, 0, data);
soundlatch2_status = 1; // soundlatch2 has been written state->soundlatch2_status = 1; // soundlatch2 has been written
} }
static WRITE8_HANDLER( airbustr_paletteram_w ) static WRITE8_HANDLER( airbustr_paletteram_w )
{ {
airbustr_state *state = (airbustr_state *)space->machine->driver_data;
int val; int val;
/* ! byte 1 ! ! byte 0 ! */ /* ! byte 1 ! ! byte 0 ! */
/* xGGG GGRR RRRB BBBB */ /* xGGG GGRR RRRB BBBB */
/* x432 1043 2104 3210 */ /* x432 1043 2104 3210 */
space->machine->generic.paletteram.u8[offset] = data; state->paletteram[offset] = data;
val = (space->machine->generic.paletteram.u8[offset | 1] << 8) | space->machine->generic.paletteram.u8[offset & ~1]; val = (state->paletteram[offset | 1] << 8) | state->paletteram[offset & ~1];
palette_set_color_rgb(space->machine, offset/2, pal5bit(val >> 5), pal5bit(val >> 10), pal5bit(val >> 0)); palette_set_color_rgb(space->machine, offset / 2, pal5bit(val >> 5), pal5bit(val >> 10), pal5bit(val >> 0));
} }
static WRITE8_HANDLER( airbustr_coin_counter_w ) static WRITE8_HANDLER( airbustr_coin_counter_w )
@ -367,13 +350,12 @@ static WRITE8_HANDLER( airbustr_coin_counter_w )
} }
/* Memory Maps */ /* Memory Maps */
static ADDRESS_MAP_START( master_map, ADDRESS_SPACE_PROGRAM, 8 ) static ADDRESS_MAP_START( master_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x7fff) AM_ROM AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank1") AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank1")
AM_RANGE(0xc000, 0xcfff) AM_DEVREADWRITE("pandora", pandora_spriteram_r, pandora_spriteram_w) AM_RANGE(0xc000, 0xcfff) AM_DEVREADWRITE("pandora", pandora_spriteram_r, pandora_spriteram_w)
AM_RANGE(0xd000, 0xdfff) AM_RAM AM_RANGE(0xd000, 0xdfff) AM_RAM
AM_RANGE(0xe000, 0xefff) AM_RAM AM_BASE(&devram) // shared with protection device AM_RANGE(0xe000, 0xefff) AM_RAM AM_BASE_MEMBER(airbustr_state, devram) // shared with protection device
AM_RANGE(0xf000, 0xffff) AM_RAM AM_SHARE("share1") AM_RANGE(0xf000, 0xffff) AM_RAM AM_SHARE("share1")
ADDRESS_MAP_END ADDRESS_MAP_END
@ -387,11 +369,11 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( slave_map, ADDRESS_SPACE_PROGRAM, 8 ) static ADDRESS_MAP_START( slave_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x7fff) AM_ROM AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank2") AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank2")
AM_RANGE(0xc000, 0xc3ff) AM_RAM_WRITE(airbustr_videoram2_w) AM_BASE(&airbustr_videoram2) AM_RANGE(0xc000, 0xc3ff) AM_RAM_WRITE(airbustr_videoram2_w) AM_BASE_MEMBER(airbustr_state, videoram2)
AM_RANGE(0xc400, 0xc7ff) AM_RAM_WRITE(airbustr_colorram2_w) AM_BASE(&airbustr_colorram2) AM_RANGE(0xc400, 0xc7ff) AM_RAM_WRITE(airbustr_colorram2_w) AM_BASE_MEMBER(airbustr_state, colorram2)
AM_RANGE(0xc800, 0xcbff) AM_RAM_WRITE(airbustr_videoram_w) AM_BASE_GENERIC(videoram) AM_RANGE(0xc800, 0xcbff) AM_RAM_WRITE(airbustr_videoram_w) AM_BASE_MEMBER(airbustr_state, videoram)
AM_RANGE(0xcc00, 0xcfff) AM_RAM_WRITE(airbustr_colorram_w) AM_BASE_GENERIC(colorram) AM_RANGE(0xcc00, 0xcfff) AM_RAM_WRITE(airbustr_colorram_w) AM_BASE_MEMBER(airbustr_state, colorram)
AM_RANGE(0xd000, 0xd5ff) AM_RAM_WRITE(airbustr_paletteram_w) AM_BASE_GENERIC(paletteram) AM_RANGE(0xd000, 0xd5ff) AM_RAM_WRITE(airbustr_paletteram_w) AM_BASE_MEMBER(airbustr_state, paletteram)
AM_RANGE(0xd600, 0xdfff) AM_RAM AM_RANGE(0xd600, 0xdfff) AM_RAM
AM_RANGE(0xe000, 0xefff) AM_RAM AM_RANGE(0xe000, 0xefff) AM_RAM
AM_RANGE(0xf000, 0xffff) AM_RAM AM_SHARE("share1") AM_RANGE(0xf000, 0xffff) AM_RAM AM_SHARE("share1")
@ -577,35 +559,66 @@ static const ym2203_interface ym2203_config =
static INTERRUPT_GEN( master_interrupt ) static INTERRUPT_GEN( master_interrupt )
{ {
master_addr ^= 0x02; airbustr_state *state = (airbustr_state *)device->machine->driver_data;
cpu_set_input_line_and_vector(device, 0, HOLD_LINE, master_addr); state->master_addr ^= 0x02;
cpu_set_input_line_and_vector(device, 0, HOLD_LINE, state->master_addr);
} }
static INTERRUPT_GEN( slave_interrupt ) static INTERRUPT_GEN( slave_interrupt )
{ {
slave_addr ^= 0x02; airbustr_state *state = (airbustr_state *)device->machine->driver_data;
cpu_set_input_line_and_vector(device, 0, HOLD_LINE, slave_addr); state->slave_addr ^= 0x02;
cpu_set_input_line_and_vector(device, 0, HOLD_LINE, state->slave_addr);
} }
/* Machine Initialization */ /* Machine Initialization */
static MACHINE_START( airbustr ) static MACHINE_START( airbustr )
{ {
state_save_register_global(machine, soundlatch_status); airbustr_state *state = (airbustr_state *)machine->driver_data;
state_save_register_global(machine, soundlatch2_status); UINT8 *MASTER = memory_region(machine, "master");
state_save_register_global(machine, master_addr); UINT8 *SLAVE = memory_region(machine, "slave");
state_save_register_global(machine, slave_addr); UINT8 *AUDIO = memory_region(machine, "audiocpu");
memory_configure_bank(machine, "bank1", 0, 3, &MASTER[0x00000], 0x4000);
memory_configure_bank(machine, "bank1", 3, 5, &MASTER[0x10000], 0x4000);
memory_configure_bank(machine, "bank2", 0, 3, &SLAVE[0x00000], 0x4000);
memory_configure_bank(machine, "bank2", 3, 5, &SLAVE[0x10000], 0x4000);
memory_configure_bank(machine, "bank3", 0, 3, &AUDIO[0x00000], 0x4000);
memory_configure_bank(machine, "bank3", 3, 5, &AUDIO[0x10000], 0x4000);
state->master = devtag_get_device(machine, "master");
state->slave = devtag_get_device(machine, "slave");
state->audiocpu = devtag_get_device(machine, "audiocpu");
state->pandora = devtag_get_device(machine, "pandora");
state_save_register_global(machine, state->soundlatch_status);
state_save_register_global(machine, state->soundlatch2_status);
state_save_register_global(machine, state->master_addr);
state_save_register_global(machine, state->slave_addr);
state_save_register_global(machine, state->bg_scrollx);
state_save_register_global(machine, state->bg_scrolly);
state_save_register_global(machine, state->fg_scrollx);
state_save_register_global(machine, state->fg_scrolly);
state_save_register_global(machine, state->highbits);
} }
static MACHINE_RESET( airbustr ) static MACHINE_RESET( airbustr )
{ {
const address_space *space = cputag_get_address_space(machine, "master", ADDRESS_SPACE_PROGRAM); airbustr_state *state = (airbustr_state *)machine->driver_data;
soundlatch_status = soundlatch2_status = 0;
master_addr = 0xff; state->soundlatch_status = state->soundlatch2_status = 0;
slave_addr = 0xfd; state->master_addr = 0xff;
master_bankswitch_w(space, 0, 0x02); state->slave_addr = 0xfd;
slave_bankswitch_w(space, 0, 0x02); state->bg_scrollx = 0;
sound_bankswitch_w(space, 0, 0x02); state->bg_scrolly = 0;
state->fg_scrollx = 0;
state->fg_scrolly = 0;
state->highbits = 0;
memory_set_bank(machine, "bank1", 0x02);
memory_set_bank(machine, "bank2", 0x02);
memory_set_bank(machine, "bank3", 0x02);
} }
/* Machine Driver */ /* Machine Driver */
@ -618,7 +631,11 @@ static const kaneko_pandora_interface airbustr_pandora_config =
}; };
static MACHINE_DRIVER_START( airbustr ) static MACHINE_DRIVER_START( airbustr )
// basic machine hardware
/* driver data */
MDRV_DRIVER_DATA(airbustr_state)
/* basic machine hardware */
MDRV_CPU_ADD("master", Z80, 6000000) // ??? MDRV_CPU_ADD("master", Z80, 6000000) // ???
MDRV_CPU_PROGRAM_MAP(master_map) MDRV_CPU_PROGRAM_MAP(master_map)
MDRV_CPU_IO_MAP(master_io_map) MDRV_CPU_IO_MAP(master_io_map)
@ -640,7 +657,7 @@ static MACHINE_DRIVER_START( airbustr )
MDRV_MACHINE_RESET(airbustr) MDRV_MACHINE_RESET(airbustr)
MDRV_WATCHDOG_TIME_INIT(SEC(3)) /* a guess, and certainly wrong */ MDRV_WATCHDOG_TIME_INIT(SEC(3)) /* a guess, and certainly wrong */
// video hardware /* video hardware */
MDRV_SCREEN_ADD("screen", RASTER) MDRV_SCREEN_ADD("screen", RASTER)
MDRV_SCREEN_REFRESH_RATE(60) MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
@ -656,7 +673,7 @@ static MACHINE_DRIVER_START( airbustr )
MDRV_VIDEO_UPDATE(airbustr) MDRV_VIDEO_UPDATE(airbustr)
MDRV_VIDEO_EOF(airbustr) MDRV_VIDEO_EOF(airbustr)
// sound hardware /* sound hardware */
MDRV_SPEAKER_STANDARD_MONO("mono") MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_SOUND_ADD("ymsnd", YM2203, 3000000) MDRV_SOUND_ADD("ymsnd", YM2203, 3000000)

View File

@ -1,5 +1,5 @@
/* /*
DJ Boy (c)1989 Kanako DJ Boy (c)1989 Kaneko
Hardware has many similarities to Airbusters. Hardware has many similarities to Airbusters.
@ -159,76 +159,28 @@ Notes:
#include "sound/2203intf.h" #include "sound/2203intf.h"
#include "sound/okim6295.h" #include "sound/okim6295.h"
#include "video/kan_pand.h" #include "video/kan_pand.h"
#include "includes/djboy.h"
/* public functions from video/djboy.h */
extern void djboy_set_videoreg( UINT8 data );
extern WRITE8_HANDLER( djboy_scrollx_w );
extern WRITE8_HANDLER( djboy_scrolly_w );
extern WRITE8_HANDLER( djboy_videoram_w );
extern WRITE8_HANDLER( djboy_paletteram_w );
extern VIDEO_START( djboy );
extern VIDEO_UPDATE( djboy );
extern VIDEO_EOF( djboy );
/******************************************************************************/
/* KANEKO BEAST state */ /* KANEKO BEAST state */
#define PROT_OUTPUT_BUFFER_SIZE 8 static void ProtectionOut( running_machine *machine, int i, UINT8 data )
static int prot_busy_count;
static UINT8 prot_output_buffer[PROT_OUTPUT_BUFFER_SIZE];
static int prot_available_data_count;
static int prot_offs; /* internal state */
static UINT8 prot_ram[0x80]; /* internal RAM */
static UINT8 prot_param[8];
static int coin;
static int complete;
static int lives[2];
static int addr;
static int bankxor;
static enum
{ {
eDJBOY_ATTRACT_HIGHSCORE, djboy_state *state = (djboy_state *)machine->driver_data;
eDJBOY_ATTRACT_TITLE,
eDJBOY_ATTRACT_GAMEPLAY,
eDJBOY_PRESS_P1_START,
eDJBOY_PRESS_P1_OR_P2_START,
eDJBOY_ACTIVE_GAMEPLAY
} mDjBoyState;
static enum if (state->prot_available_data_count == i)
{ state->prot_output_buffer[state->prot_available_data_count++] = data;
ePROT_NORMAL,
ePROT_WRITE_BYTES,
ePROT_WRITE_BYTE,
ePROT_READ_BYTES,
ePROT_WAIT_DSW1_WRITEBACK,
ePROT_WAIT_DSW2_WRITEBACK,
ePROT_STORE_PARAM
} prot_mode;
static void
ProtectionOut( int i, UINT8 data )
{
if( prot_available_data_count == i )
{
prot_output_buffer[prot_available_data_count++] = data;
}
else else
{ {
logerror( "prot_output_buffer overflow!\n" ); logerror("prot_output_buffer overflow!\n");
exit(1); exit(1);
} }
} /* ProtectionOut */ } /* ProtectionOut */
static int static int GetLives( running_machine *machine )
GetLives( running_machine *machine )
{ {
int dsw = input_port_read(machine, "DSW2"); int dsw = input_port_read(machine, "DSW2");
switch( dsw&0x30 ) switch (dsw & 0x30)
{ {
case 0x10: return 3; case 0x10: return 3;
case 0x00: return 5; case 0x00: return 5;
@ -238,370 +190,370 @@ GetLives( running_machine *machine )
return 0; return 0;
} /* GetLives */ } /* GetLives */
static WRITE8_HANDLER( coinplus_w ) static WRITE8_HANDLER( coinplus_w )
{ {
djboy_state *state = (djboy_state *)space->machine->driver_data;
int dsw = input_port_read(space->machine, "DSW1"); int dsw = input_port_read(space->machine, "DSW1");
coin_counter_w( space->machine, 0, data&1 ); coin_counter_w(space->machine, 0, data & 1);
coin_counter_w( space->machine, 1, data&2 ); coin_counter_w(space->machine, 1, data & 2);
if( data&1 )
if (data & 1)
{ /* TODO: coinage adjustments */ { /* TODO: coinage adjustments */
logerror( "COIN A+\n" ); logerror("COIN A+\n");
switch( (dsw&0x30)>>4 ) switch ((dsw & 0x30) >> 4)
{ {
case 0: coin += 4; break; /* 1 coin, 1 credit */ case 0: state->coin += 4; break; /* 1 coin, 1 credit */
case 1: coin += 8; break; /* 1 coin, 2 credits */ case 1: state->coin += 8; break; /* 1 coin, 2 credits */
case 2: coin += 2; break; /* 2 coins, 1 credit */ case 2: state->coin += 2; break; /* 2 coins, 1 credit */
case 3: coin += 6; break; /* 2 coins, 3 credits */ case 3: state->coin += 6; break; /* 2 coins, 3 credits */
} }
} }
if( data&2 ) if (data & 2)
{ {
logerror( "COIN B+\n" ); logerror("COIN B+\n");
switch( (dsw&0xc0)>>6 ) switch ((dsw & 0xc0) >> 6)
{ {
case 0: coin += 4; break; /* 1 coin, 1 credit */ case 0: state->coin += 4; break; /* 1 coin, 1 credit */
case 1: coin += 8; break; /* 1 coin, 2 credits */ case 1: state->coin += 8; break; /* 1 coin, 2 credits */
case 2: coin += 2; break; /* 2 coins, 1 credit */ case 2: state->coin += 2; break; /* 2 coins, 1 credit */
case 3: coin += 6; break; /* 2 coins, 3 credits */ case 3: state->coin += 6; break; /* 2 coins, 3 credits */
} }
} }
} /* coinplus_w */ } /* coinplus_w */
static void static void OutputProtectionState( running_machine *machine, int i, int type )
OutputProtectionState( running_machine *machine, int i, int type )
{ {
djboy_state *state = (djboy_state *)machine->driver_data;
int io = ~input_port_read(machine, "IN0"); int io = ~input_port_read(machine, "IN0");
int dat = 0x00; int dat = 0x00;
switch( mDjBoyState ) switch (state->mDjBoyState)
{ {
case eDJBOY_ATTRACT_HIGHSCORE: case eDJBOY_ATTRACT_HIGHSCORE:
if( coin>=4 ) if (state->coin >= 4)
{ {
dat = 0x01; dat = 0x01;
mDjBoyState = eDJBOY_PRESS_P1_START; state->mDjBoyState = eDJBOY_PRESS_P1_START;
logerror( "COIN UP\n" ); logerror("COIN UP\n");
} }
else if( complete ) else if (state->complete)
{ {
dat = 0x06; dat = 0x06;
mDjBoyState = eDJBOY_ATTRACT_TITLE; state->mDjBoyState = eDJBOY_ATTRACT_TITLE;
} }
break; break;
case eDJBOY_ATTRACT_TITLE: case eDJBOY_ATTRACT_TITLE:
if( coin>=4 ) if (state->coin >= 4)
{ {
dat = 0x01; dat = 0x01;
mDjBoyState = eDJBOY_PRESS_P1_START; state->mDjBoyState = eDJBOY_PRESS_P1_START;
logerror( "COIN UP\n" ); logerror("COIN UP\n");
} }
else if( complete ) else if (state->complete)
{ {
dat = 0x15; dat = 0x15;
mDjBoyState = eDJBOY_ATTRACT_GAMEPLAY; state->mDjBoyState = eDJBOY_ATTRACT_GAMEPLAY;
} }
break; break;
case eDJBOY_ATTRACT_GAMEPLAY: case eDJBOY_ATTRACT_GAMEPLAY:
if( coin>=4 ) if (state->coin>=4)
{ {
dat = 0x01; dat = 0x01;
mDjBoyState = eDJBOY_PRESS_P1_START; state->mDjBoyState = eDJBOY_PRESS_P1_START;
logerror( "COIN UP\n" ); logerror("COIN UP\n");
} }
else if( complete ) else if (state->complete)
{ {
dat = 0x0b; dat = 0x0b;
mDjBoyState = eDJBOY_ATTRACT_HIGHSCORE; state->mDjBoyState = eDJBOY_ATTRACT_HIGHSCORE;
} }
break; break;
case eDJBOY_PRESS_P1_START: case eDJBOY_PRESS_P1_START:
if( io&1 ) if (io & 1) /* p1 start */
{ /* p1 start */ {
dat = 0x16; dat = 0x16;
mDjBoyState = eDJBOY_ACTIVE_GAMEPLAY; state->mDjBoyState = eDJBOY_ACTIVE_GAMEPLAY;
logerror( "P1 START\n" ); logerror("P1 START\n");
} }
else if( coin>=8 ) else if (state->coin >= 8)
{ {
dat = 0x05; dat = 0x05;
mDjBoyState = eDJBOY_PRESS_P1_OR_P2_START; state->mDjBoyState = eDJBOY_PRESS_P1_OR_P2_START;
logerror( "COIN2 UP\n" ); logerror("COIN2 UP\n");
} }
break; break;
case eDJBOY_PRESS_P1_OR_P2_START: case eDJBOY_PRESS_P1_OR_P2_START:
if( io&1 ) if (io & 1) /* p1 start */
{ /* p1 start */ {
dat = 0x16; dat = 0x16;
mDjBoyState = eDJBOY_ACTIVE_GAMEPLAY; state->mDjBoyState = eDJBOY_ACTIVE_GAMEPLAY;
lives[0] = GetLives(machine); state->lives[0] = GetLives(machine);
logerror( "P1 START!\n" ); logerror("P1 START!\n");
coin-=4; state->coin -= 4;
} }
else if( io&2 ) else if (io & 2) /* p2 start */
{ /* p2 start */ {
dat = 0x0a; dat = 0x0a;
mDjBoyState = eDJBOY_ACTIVE_GAMEPLAY; state->mDjBoyState = eDJBOY_ACTIVE_GAMEPLAY;
lives[0] = GetLives(machine); state->lives[0] = GetLives(machine);
lives[1] = GetLives(machine); state->lives[1] = GetLives(machine);
logerror( "P2 START!\n" ); logerror("P2 START!\n");
coin-=8; state->coin -= 8;
} }
break; break;
case eDJBOY_ACTIVE_GAMEPLAY: case eDJBOY_ACTIVE_GAMEPLAY:
if( lives[0]==0 && lives[1]==0 && complete ) if (state->lives[0] == 0 && state->lives[1] == 0 && state->complete) /* continue countdown complete */
{ /* continue countdown complete */
dat = 0x0f;
logerror( "countdown complete!\n" );
mDjBoyState = eDJBOY_ATTRACT_HIGHSCORE;
}
else if( coin>=4 )
{ {
if( (io&1) && lives[0]==0 ) dat = 0x0f;
logerror("countdown complete!\n");
state->mDjBoyState = eDJBOY_ATTRACT_HIGHSCORE;
}
else if (state->coin >= 4)
{
if ((io & 1) && state->lives[0] == 0)
{ {
dat = 0x12; /* continue (P1) */ dat = 0x12; /* continue (P1) */
lives[0] = GetLives(machine); state->lives[0] = GetLives(machine);
mDjBoyState = eDJBOY_ACTIVE_GAMEPLAY; state->mDjBoyState = eDJBOY_ACTIVE_GAMEPLAY;
coin-=4; state->coin -= 4;
logerror( "P1 CONTINUE!\n" ); logerror("P1 CONTINUE!\n");
} }
else if( (io&2) && lives[1]==0 ) else if ((io & 2) && state->lives[1] == 0)
{ {
dat = 0x08; /* continue (P2) */ dat = 0x08; /* continue (P2) */
lives[1] = GetLives(machine); state->lives[1] = GetLives(machine);
mDjBoyState = eDJBOY_ACTIVE_GAMEPLAY; state->mDjBoyState = eDJBOY_ACTIVE_GAMEPLAY;
coin-=4; state->coin -= 4;
logerror( "P2 CONTINUE!\n" ); logerror("P2 CONTINUE!\n");
} }
} }
break; break;
} }
complete = 0; state->complete = 0;
ProtectionOut( i, dat ); ProtectionOut(machine, i, dat);
} /* OutputProtectionState */ } /* OutputProtectionState */
static void static void CommonProt( running_machine *machine, int i, int type )
CommonProt( running_machine *machine, int i, int type )
{ {
int displayedCredits = coin/4; djboy_state *state = (djboy_state *)machine->driver_data;
if( displayedCredits>9 ) int displayedCredits = state->coin / 4;
{ if (displayedCredits > 9)
displayedCredits = 9; displayedCredits = 9;
}
ProtectionOut( i++, displayedCredits ); ProtectionOut(machine, i++, displayedCredits);
ProtectionOut( i++, input_port_read(machine, "IN0") ); /* COIN/START */ ProtectionOut(machine, i++, input_port_read(machine, "IN0")); /* COIN/START */
OutputProtectionState( machine, i, type ); OutputProtectionState(machine, i, type);
} /* CommonProt */ } /* CommonProt */
static WRITE8_HANDLER( beast_data_w ) static WRITE8_HANDLER( beast_data_w )
{ {
prot_busy_count = 1; djboy_state *state = (djboy_state *)space->machine->driver_data;
logerror( "0x%04x: prot_w(0x%02x)\n", cpu_get_pc(space->cpu), data ); state->prot_busy_count = 1;
watchdog_reset_w(space,0,0); logerror("0x%04x: prot_w(0x%02x)\n", cpu_get_pc(space->cpu), data);
if( prot_mode == ePROT_WAIT_DSW1_WRITEBACK ) watchdog_reset_w(space, 0, 0);
if (state->prot_mode == ePROT_WAIT_DSW1_WRITEBACK)
{ {
logerror( "[DSW1_WRITEBACK]\n" ); logerror("[DSW1_WRITEBACK]\n");
ProtectionOut( 0, input_port_read(space->machine, "DSW2") ); /* DSW2 */ ProtectionOut(space->machine, 0, input_port_read(space->machine, "DSW2")); /* DSW2 */
prot_mode = ePROT_WAIT_DSW2_WRITEBACK; state->prot_mode = ePROT_WAIT_DSW2_WRITEBACK;
} }
else if( prot_mode == ePROT_WAIT_DSW2_WRITEBACK ) else if (state->prot_mode == ePROT_WAIT_DSW2_WRITEBACK)
{ {
logerror( "[DSW2_WRITEBACK]\n" ); logerror("[DSW2_WRITEBACK]\n");
prot_mode = ePROT_STORE_PARAM; state->prot_mode = ePROT_STORE_PARAM;
prot_offs = 0; state->prot_offs = 0;
} }
else if( prot_mode == ePROT_STORE_PARAM ) else if (state->prot_mode == ePROT_STORE_PARAM)
{ {
logerror( "prot param[%d]: 0x%02x\n", prot_offs, data ); logerror("prot param[%d]: 0x%02x\n", state->prot_offs, data);
if( prot_offs<8 ) if (state->prot_offs < 8)
{ state->prot_param[state->prot_offs++] = data;
prot_param[prot_offs++] = data;
} if(state->prot_offs == 8)
if( prot_offs == 8 ) state->prot_mode = ePROT_NORMAL;
{
prot_mode = ePROT_NORMAL;
}
} }
else if( prot_mode == ePROT_WRITE_BYTE ) else if (state->prot_mode == ePROT_WRITE_BYTE)
{ /* pc == 0x79cd */ { /* pc == 0x79cd */
prot_ram[(prot_offs++)&0x7f] = data; state->prot_ram[(state->prot_offs++) & 0x7f] = data;
prot_mode = ePROT_WRITE_BYTES; state->prot_mode = ePROT_WRITE_BYTES;
} }
else else
{ {
switch( data ) switch (data)
{ {
case 0x00: case 0x00:
if( prot_mode == ePROT_WRITE_BYTES ) if (state->prot_mode == ePROT_WRITE_BYTES)
{ /* next byte is data to write to internal prot RAM */ { /* next byte is data to write to internal prot RAM */
prot_mode = ePROT_WRITE_BYTE; state->prot_mode = ePROT_WRITE_BYTE;
} }
else if( prot_mode == ePROT_READ_BYTES ) else if (state->prot_mode == ePROT_READ_BYTES)
{ /* request next byte of internal prot RAM */ { /* request next byte of internal prot RAM */
ProtectionOut( 0, prot_ram[(prot_offs++)&0x7f] ); ProtectionOut(space->machine, 0, state->prot_ram[(state->prot_offs++) & 0x7f]);
} }
else else
{ logerror("UNEXPECTED PREFIX!\n");
logerror( "UNEXPECTED PREFIX!\n" );
}
break; break;
case 0x01: // pc=7389 case 0x01: // pc=7389
OutputProtectionState( space->machine, 0, 0x01 ); OutputProtectionState(space->machine, 0, 0x01);
break; break;
case 0x02: case 0x02:
CommonProt( space->machine,0,0x02 ); CommonProt(space->machine, 0, 0x02);
break; break;
case 0x03: /* prepare for memory write to protection device ram (pc == 0x7987) */ // -> 0x02 case 0x03: /* prepare for memory write to protection device ram (pc == 0x7987) */ // -> 0x02
logerror( "[WRITE BYTES]\n" ); logerror("[WRITE BYTES]\n");
prot_mode = ePROT_WRITE_BYTES; state->prot_mode = ePROT_WRITE_BYTES;
prot_offs = 0; state->prot_offs = 0;
break; break;
case 0x04: case 0x04:
ProtectionOut( 0,0 ); // ? ProtectionOut(space->machine, 0, 0); // ?
ProtectionOut( 1,0 ); // ? ProtectionOut(space->machine, 1, 0); // ?
ProtectionOut( 2,0 ); // ? ProtectionOut(space->machine, 2, 0); // ?
ProtectionOut( 3,0 ); // ? ProtectionOut(space->machine, 3, 0); // ?
CommonProt( space->machine, 4,0x04 ); CommonProt(space->machine, 4, 0x04);
break; break;
case 0x05: /* 0x71f4 */ case 0x05: /* 0x71f4 */
ProtectionOut( 0,input_port_read(space->machine, "IN1") ); // to $42 ProtectionOut(space->machine, 0, input_port_read(space->machine, "IN1")); // to $42
ProtectionOut( 1,0 ); // ? ProtectionOut(space->machine, 1, 0); // ?
ProtectionOut( 2,input_port_read(space->machine, "IN2") ); // to $43 ProtectionOut(space->machine, 2, input_port_read(space->machine, "IN2")); // to $43
ProtectionOut( 3,0 ); // ? ProtectionOut(space->machine, 3, 0); // ?
ProtectionOut( 4,0 ); // ? ProtectionOut(space->machine, 4, 0); // ?
CommonProt( space->machine, 5,0x05 ); CommonProt(space->machine, 5, 0x05);
break; break;
case 0x07: case 0x07:
CommonProt( space->machine, 0,0x07 ); CommonProt(space->machine, 0, 0x07);
break; break;
case 0x08: /* pc == 0x727a */ case 0x08: /* pc == 0x727a */
ProtectionOut( 0,input_port_read(space->machine, "IN0") ); /* COIN/START */ ProtectionOut(space->machine, 0, input_port_read(space->machine, "IN0")); /* COIN/START */
ProtectionOut( 1,input_port_read(space->machine, "IN1") ); /* JOY1 */ ProtectionOut(space->machine, 1, input_port_read(space->machine, "IN1")); /* JOY1 */
ProtectionOut( 2,input_port_read(space->machine, "IN2") ); /* JOY2 */ ProtectionOut(space->machine, 2, input_port_read(space->machine, "IN2")); /* JOY2 */
ProtectionOut( 3,input_port_read(space->machine, "DSW1") ); /* DSW1 */ ProtectionOut(space->machine, 3, input_port_read(space->machine, "DSW1")); /* DSW1 */
ProtectionOut( 4,input_port_read(space->machine, "DSW2") ); /* DSW2 */ ProtectionOut(space->machine, 4, input_port_read(space->machine, "DSW2")); /* DSW2 */
CommonProt( space->machine, 5, 0x08 ); CommonProt(space->machine, 5, 0x08);
break; break;
case 0x09: case 0x09:
ProtectionOut( 0,0 ); // ? ProtectionOut(space->machine, 0, 0); // ?
ProtectionOut( 1,0 ); // ? ProtectionOut(space->machine, 1, 0); // ?
ProtectionOut( 2,0 ); // ? ProtectionOut(space->machine, 2, 0); // ?
CommonProt( space->machine, 3, 0x09 ); CommonProt(space->machine, 3, 0x09);
break; break;
case 0x0a: case 0x0a:
CommonProt( space->machine,0,0x0a ); CommonProt(space->machine, 0, 0x0a);
break; break;
case 0x0c: case 0x0c:
CommonProt( space->machine,1,0x0c ); CommonProt(space->machine, 1, 0x0c);
break; break;
case 0x0d: case 0x0d:
CommonProt( space->machine,2,0x0d ); CommonProt(space->machine, 2, 0x0d);
break; break;
case 0xfe: /* prepare for memory read from protection device ram (pc == 0x79ee, 0x7a3f) */ case 0xfe: /* prepare for memory read from protection device ram (pc == 0x79ee, 0x7a3f) */
if( prot_mode == ePROT_WRITE_BYTES ) if (state->prot_mode == ePROT_WRITE_BYTES)
{ {
prot_mode = ePROT_READ_BYTES; state->prot_mode = ePROT_READ_BYTES;
logerror( "[READ BYTES]\n" ); logerror("[READ BYTES]\n");
} }
else else
{ {
prot_mode = ePROT_WRITE_BYTES; state->prot_mode = ePROT_WRITE_BYTES;
logerror( "[WRITE BYTES*]\n" ); logerror("[WRITE BYTES*]\n");
} }
prot_offs = 0; state->prot_offs = 0;
break; break;
case 0xff: /* read DSW (pc == 0x714d) */ case 0xff: /* read DSW (pc == 0x714d) */
ProtectionOut( 0,input_port_read(space->machine, "DSW1") ); /* DSW1 */ ProtectionOut(space->machine, 0, input_port_read(space->machine, "DSW1")); /* DSW1 */
prot_mode = ePROT_WAIT_DSW1_WRITEBACK; state->prot_mode = ePROT_WAIT_DSW1_WRITEBACK;
break; break;
case 0xa9: /* 1-player game: P1 dies case 0xa9: /* 1-player game: P1 dies
2-player game: P2 dies */ 2-player game: P2 dies */
if( lives[0]>0 && lives[1]>0 ) if (state->lives[0] > 0 && state->lives[1] > 0 )
{ {
lives[1]--; state->lives[1]--;
logerror( "%02x P2 DIE(%d)\n", data, lives[1] ); logerror("%02x P2 DIE(%d)\n", data, state->lives[1]);
} }
else if( lives[0]>0 ) else if (state->lives[0] > 0)
{ {
lives[0]--; state->lives[0]--;
logerror( "%02x P1 DIE(%d)\n", data, lives[0] ); logerror("%02x P1 DIE(%d)\n", data, state->lives[0]);
} }
else else
{ {
logerror( "%02x COMPLETE.\n", data ); logerror("%02x COMPLETE.\n", data);
complete = 0xa9; state->complete = 0xa9;
} }
break; break;
case 0x92: /* p2 lost life; in 2-p game, P1 died */ case 0x92: /* p2 lost life; in 2-p game, P1 died */
if( lives[0]>0 && lives[1]>0 ) if (state->lives[0] > 0 && state->lives[1] > 0 )
{ {
lives[0]--; state->lives[0]--;
logerror( "%02x P1 DIE(%d)\n", data, lives[0] ); logerror("%02x P1 DIE(%d)\n", data, state->lives[0]);
} }
else if( lives[1]>0 ) else if (state->lives[1] > 0)
{ {
lives[1]--; state->lives[1]--;
logerror( "%02x P2 DIE (%d)\n", data, lives[1] ); logerror("%02x P2 DIE (%d)\n", data, state->lives[1]);
} }
else else
{ {
logerror( "%02x COMPLETE.\n", data ); logerror("%02x COMPLETE.\n", data);
complete = 0x92; state->complete = 0x92;
} }
break; break;
case 0xa3: /* p2 bonus life */ case 0xa3: /* p2 bonus life */
lives[1]++; state->lives[1]++;
logerror( "%02x P2 BONUS(%d)\n", data, lives[1] ); logerror("%02x P2 BONUS(%d)\n", data, state->lives[1]);
break; break;
case 0xa5: /* p1 bonus life */ case 0xa5: /* p1 bonus life */
lives[0]++; state->lives[0]++;
logerror( "%02x P1 BONUS(%d)\n", data, lives[0] ); logerror("%02x P1 BONUS(%d)\n", data, state->lives[0]);
break; break;
case 0xad: /* 1p game start ack */ case 0xad: /* 1p game start ack */
logerror( "%02x 1P GAME START\n", data ); logerror("%02x 1P GAME START\n", data);
break; break;
case 0xb0: /* 1p+2p game start ack */ case 0xb0: /* 1p+2p game start ack */
logerror( "%02x 1P+2P GAME START\n", data ); logerror("%02x 1P+2P GAME START\n", data);
break; break;
case 0xb3: /* 1p continue ack */ case 0xb3: /* 1p continue ack */
logerror( "%02x 1P CONTINUE\n", data ); logerror("%02x 1P CONTINUE\n", data);
break; break;
case 0xb7: /* 2p continue ack */ case 0xb7: /* 2p continue ack */
logerror( "%02x 2P CONTINUE\n", data ); logerror("%02x 2P CONTINUE\n", data);
break; break;
default: default:
case 0x97: case 0x97:
case 0x9a: case 0x9a:
logerror( "!!0x%04x: prot_w(0x%02x)\n", cpu_get_pc(space->cpu), data ); logerror("!!0x%04x: prot_w(0x%02x)\n", cpu_get_pc(space->cpu), data);
break; break;
} }
} }
@ -609,75 +561,56 @@ static WRITE8_HANDLER( beast_data_w )
static READ8_HANDLER( beast_data_r ) static READ8_HANDLER( beast_data_r )
{ /* port#4 */ { /* port#4 */
djboy_state *state = (djboy_state *)space->machine->driver_data;
UINT8 data = 0x00; UINT8 data = 0x00;
if( prot_available_data_count ) if (state->prot_available_data_count)
{ {
int i; int i;
data = prot_output_buffer[0]; data = state->prot_output_buffer[0];
prot_available_data_count--; state->prot_available_data_count--;
for( i=0; i<prot_available_data_count; i++ ) for (i = 0; i < state->prot_available_data_count; i++)
{ state->prot_output_buffer[i] = state->prot_output_buffer[i + 1];
prot_output_buffer[i] = prot_output_buffer[i+1];
}
} }
else else
{ {
logerror( "prot_r: data expected!\n" ); logerror("prot_r: data expected!\n");
} }
logerror( "0x%04x: prot_r() == 0x%02x\n", cpu_get_pc(space->cpu), data ); logerror("0x%04x: prot_r() == 0x%02x\n", cpu_get_pc(space->cpu), data);
return data; return data;
} /* beast_data_r */ } /* beast_data_r */
static READ8_HANDLER( beast_status_r ) static READ8_HANDLER( beast_status_r )
{ /* port 0xc */ { /* port 0xc */
djboy_state *state = (djboy_state *)space->machine->driver_data;
UINT8 result = 0; UINT8 result = 0;
if( prot_busy_count )
if (state->prot_busy_count)
{ {
prot_busy_count--; state->prot_busy_count--;
result |= 1<<3; result |= 1 << 3;
} }
if( !prot_available_data_count ) if (!state->prot_available_data_count)
{ {
result |= 1<<2; result |= 1 << 2;
} }
return result; return result;
} /* beast_status_r */ } /* beast_status_r */
/******************************************************************************/ /******************************************************************************/
static DRIVER_INIT( djboy )
{
coin = 0;
complete = 0;
memset(lives, 0, sizeof(lives));
addr = 0xff;
bankxor = 0x00;
}
static DRIVER_INIT( djboyj )
{
DRIVER_INIT_CALL( djboy );
bankxor = 0x1f;
}
static WRITE8_HANDLER( trigger_nmi_on_cpu0 ) static WRITE8_HANDLER( trigger_nmi_on_cpu0 )
{ {
cputag_set_input_line(space->machine, "maincpu", INPUT_LINE_NMI, PULSE_LINE); djboy_state *state = (djboy_state *)space->machine->driver_data;
cpu_set_input_line(state->maincpu, INPUT_LINE_NMI, PULSE_LINE);
} }
static WRITE8_HANDLER( cpu0_bankswitch_w ) static WRITE8_HANDLER( cpu0_bankswitch_w )
{ {
unsigned char *RAM = memory_region(space->machine, "maincpu"); djboy_state *state = (djboy_state *)space->machine->driver_data;
data ^= bankxor;
memory_set_bankptr(space->machine, "bank4",&RAM[0x10000]); /* unsure if/how this area is banked */ data ^= state->bankxor;
if( data < 4 ) memory_set_bank(space->machine, "bank1", data);
{ memory_set_bank(space->machine, "bank4", 0); /* unsure if/how this area is banked */
RAM = &RAM[0x2000 * data];
}
else
{
RAM = &RAM[0x10000 + 0x2000 * (data-4)];
}
memory_set_bankptr(space->machine, "bank1",RAM);
} }
/******************************************************************************/ /******************************************************************************/
@ -690,25 +623,30 @@ static WRITE8_HANDLER( cpu0_bankswitch_w )
*/ */
static WRITE8_HANDLER( cpu1_bankswitch_w ) static WRITE8_HANDLER( cpu1_bankswitch_w )
{ {
UINT8 *RAM = memory_region(space->machine, "cpu1"); djboy_state *state = (djboy_state *)space->machine->driver_data;
djboy_set_videoreg( data ); state->videoreg = data;
switch( data&0xf )
switch (data & 0xf)
{ {
/* bs65.5y */ /* bs65.5y */
case 0x00: memory_set_bankptr(space->machine, "bank2",&RAM[0x00000]); break; case 0x00:
case 0x01: memory_set_bankptr(space->machine, "bank2",&RAM[0x04000]); break; case 0x01:
case 0x02: memory_set_bankptr(space->machine, "bank2",&RAM[0x10000]); break; case 0x02:
case 0x03: memory_set_bankptr(space->machine, "bank2",&RAM[0x14000]); break; case 0x03:
memory_set_bank(space->machine, "bank2", (data & 0xf));
break;
/* bs101.6w */ /* bs101.6w */
case 0x08: memory_set_bankptr(space->machine, "bank2",&RAM[0x18000]); break; case 0x08:
case 0x09: memory_set_bankptr(space->machine, "bank2",&RAM[0x1c000]); break; case 0x09:
case 0x0a: memory_set_bankptr(space->machine, "bank2",&RAM[0x20000]); break; case 0x0a:
case 0x0b: memory_set_bankptr(space->machine, "bank2",&RAM[0x24000]); break; case 0x0b:
case 0x0c: memory_set_bankptr(space->machine, "bank2",&RAM[0x28000]); break; case 0x0c:
case 0x0d: memory_set_bankptr(space->machine, "bank2",&RAM[0x2c000]); break; case 0x0d:
case 0x0e: memory_set_bankptr(space->machine, "bank2",&RAM[0x30000]); break; case 0x0e:
case 0x0f: memory_set_bankptr(space->machine, "bank2",&RAM[0x34000]); break; case 0x0f:
memory_set_bank(space->machine, "bank2", (data & 0xf) - 4);
break;
default: default:
break; break;
@ -719,23 +657,14 @@ static WRITE8_HANDLER( cpu1_bankswitch_w )
static WRITE8_HANDLER( trigger_nmi_on_sound_cpu2 ) static WRITE8_HANDLER( trigger_nmi_on_sound_cpu2 )
{ {
djboy_state *state = (djboy_state *)space->machine->driver_data;
soundlatch_w(space, 0, data); soundlatch_w(space, 0, data);
cputag_set_input_line(space->machine, "cpu2", INPUT_LINE_NMI, PULSE_LINE); cpu_set_input_line(state->cpu2, INPUT_LINE_NMI, PULSE_LINE);
} /* trigger_nmi_on_sound_cpu2 */ } /* trigger_nmi_on_sound_cpu2 */
static WRITE8_HANDLER( cpu2_bankswitch_w ) static WRITE8_HANDLER( cpu2_bankswitch_w )
{ {
UINT8 *RAM = memory_region(space->machine, "cpu2"); memory_set_bank(space->machine, "bank3", data); // shall we check data<0x07?
if( data < 3 )
{
RAM = &RAM[0x04000 * data];
}
else
{
RAM = &RAM[0x10000 + 0x4000 * (data - 3)];
}
memory_set_bankptr(space->machine, "bank3", RAM);
} }
/******************************************************************************/ /******************************************************************************/
@ -760,8 +689,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( cpu1_am, ADDRESS_SPACE_PROGRAM, 8 ) static ADDRESS_MAP_START( cpu1_am, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x7fff) AM_ROM AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank2") AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank2")
AM_RANGE(0xc000, 0xcfff) AM_RAM_WRITE(djboy_videoram_w) AM_BASE_GENERIC(videoram) AM_RANGE(0xc000, 0xcfff) AM_RAM_WRITE(djboy_videoram_w) AM_BASE_MEMBER(djboy_state, videoram)
AM_RANGE(0xd000, 0xd3ff) AM_RAM_WRITE(djboy_paletteram_w) AM_BASE_GENERIC(paletteram) AM_RANGE(0xd000, 0xd3ff) AM_RAM_WRITE(djboy_paletteram_w) AM_BASE_MEMBER(djboy_state, paletteram)
AM_RANGE(0xd400, 0xd8ff) AM_RAM AM_RANGE(0xd400, 0xd8ff) AM_RAM
AM_RANGE(0xe000, 0xffff) AM_RAM AM_SHARE("share1") AM_RANGE(0xe000, 0xffff) AM_RAM AM_SHARE("share1")
ADDRESS_MAP_END ADDRESS_MAP_END
@ -903,8 +832,9 @@ GFXDECODE_END
static INTERRUPT_GEN( djboy_interrupt ) static INTERRUPT_GEN( djboy_interrupt )
{ /* CPU1 uses interrupt mode 2. For now, just alternate the two interrupts. */ { /* CPU1 uses interrupt mode 2. For now, just alternate the two interrupts. */
addr ^= 0x02; djboy_state *state = (djboy_state *)device->machine->driver_data;
cpu_set_input_line_and_vector(device, 0, HOLD_LINE, addr); state->addr ^= 0x02;
cpu_set_input_line_and_vector(device, 0, HOLD_LINE, state->addr);
} }
static const kaneko_pandora_interface djboy_pandora_config = static const kaneko_pandora_interface djboy_pandora_config =
@ -914,7 +844,77 @@ static const kaneko_pandora_interface djboy_pandora_config =
0, 0 /* x_offs, y_offs */ 0, 0 /* x_offs, y_offs */
}; };
static MACHINE_START( djboy )
{
djboy_state *state = (djboy_state *)machine->driver_data;
UINT8 *MAIN = memory_region(machine, "maincpu");
UINT8 *CPU1 = memory_region(machine, "cpu1");
UINT8 *CPU2 = memory_region(machine, "cpu2");
memory_configure_bank(machine, "bank1", 0, 4, &MAIN[0x00000], 0x2000);
memory_configure_bank(machine, "bank1", 4, 28, &MAIN[0x10000], 0x2000);
memory_configure_bank(machine, "bank2", 0, 2, &CPU1[0x00000], 0x4000);
memory_configure_bank(machine, "bank2", 2, 10, &CPU1[0x10000], 0x4000);
memory_configure_bank(machine, "bank3", 0, 3, &CPU2[0x00000], 0x4000);
memory_configure_bank(machine, "bank3", 3, 5, &CPU2[0x10000], 0x4000);
memory_configure_bank(machine, "bank4", 0, 1, &MAIN[0x10000], 0x3000); /* unsure if/how this area is banked */
state->maincpu = devtag_get_device(machine, "maincpu");
state->cpu1 = devtag_get_device(machine, "cpu1");
state->cpu2 = devtag_get_device(machine, "cpu2");
state->pandora = devtag_get_device(machine, "pandora");
state_save_register_global(machine, state->videoreg);
state_save_register_global(machine, state->scrollx);
state_save_register_global(machine, state->scrolly);
/* Kaneko BEAST */
state_save_register_global(machine, state->coin);
state_save_register_global(machine, state->complete);
state_save_register_global(machine, state->addr);
state_save_register_global_array(machine, state->lives);
state_save_register_global(machine, state->mDjBoyState );
state_save_register_global(machine, state->prot_mode);
state_save_register_global(machine, state->prot_busy_count);
state_save_register_global(machine, state->prot_available_data_count);
state_save_register_global(machine, state->prot_offs);
state_save_register_global_array(machine, state->prot_output_buffer);
state_save_register_global_array(machine, state->prot_ram);
state_save_register_global_array(machine, state->prot_param);
}
static MACHINE_RESET( djboy )
{
djboy_state *state = (djboy_state *)machine->driver_data;
state->videoreg = 0;
state->scrollx = 0;
state->scrolly = 0;
/* Kaneko BEAST */
state->coin = 0;
state->complete = 0;
state->addr = 0xff;
state->lives[0] = 0;
state->lives[1] = 0;
state->prot_busy_count = 0;
state->prot_available_data_count = 0;
state->prot_offs = 0;
memset(state->prot_output_buffer, 0, PROT_OUTPUT_BUFFER_SIZE);
memset(state->prot_ram, 0, 0x80);
memset(state->prot_param, 0, 8);
state->mDjBoyState = eDJBOY_ATTRACT_HIGHSCORE;
state->prot_mode = ePROT_NORMAL;
}
static MACHINE_DRIVER_START( djboy ) static MACHINE_DRIVER_START( djboy )
MDRV_DRIVER_DATA(djboy_state)
MDRV_CPU_ADD("maincpu", Z80,6000000) MDRV_CPU_ADD("maincpu", Z80,6000000)
MDRV_CPU_PROGRAM_MAP(cpu0_am) MDRV_CPU_PROGRAM_MAP(cpu0_am)
MDRV_CPU_IO_MAP(cpu0_port_am) MDRV_CPU_IO_MAP(cpu0_port_am)
@ -932,6 +932,9 @@ static MACHINE_DRIVER_START( djboy )
MDRV_QUANTUM_TIME(HZ(6000)) MDRV_QUANTUM_TIME(HZ(6000))
MDRV_MACHINE_START(djboy)
MDRV_MACHINE_RESET(djboy)
MDRV_SCREEN_ADD("screen", RASTER) MDRV_SCREEN_ADD("screen", RASTER)
MDRV_SCREEN_REFRESH_RATE(60) MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
@ -1072,8 +1075,19 @@ ROM_START( djboyj )
ROM_END ROM_END
static DRIVER_INIT( djboy )
{
djboy_state *state = (djboy_state *)machine->driver_data;
state->bankxor = 0x00;
}
static DRIVER_INIT( djboyj )
{
djboy_state *state = (djboy_state *)machine->driver_data;
state->bankxor = 0x1f;
}
/* YEAR, NAME, PARENT, MACHINE, INPUT, INIT, MNTR, COMPANY, FULLNAME, FLAGS */ /* YEAR, NAME, PARENT, MACHINE, INPUT, INIT, MNTR, COMPANY, FULLNAME, FLAGS */
GAME( 1989, djboy, 0, djboy, djboy, djboy, ROT0, "Kaneko (American Sammy license)", "DJ Boy (set 1)", 0) // Sammy & Williams logos in FG ROM GAME( 1989, djboy, 0, djboy, djboy, djboy, ROT0, "Kaneko (American Sammy license)", "DJ Boy (set 1)", GAME_SUPPORTS_SAVE) // Sammy & Williams logos in FG ROM
GAME( 1989, djboya, djboy, djboy, djboy, djboy, ROT0, "Kaneko (American Sammy license)", "DJ Boy (set 2)", 0) // Sammy & Williams logos in FG ROM GAME( 1989, djboya, djboy, djboy, djboy, djboy, ROT0, "Kaneko (American Sammy license)", "DJ Boy (set 2)", GAME_SUPPORTS_SAVE) // Sammy & Williams logos in FG ROM
GAME( 1989, djboyj, djboy, djboy, djboy, djboyj, ROT0, "Kaneko (Sega license)", "DJ Boy (Japan)", 0 ) // Sega logo in FG ROM GAME( 1989, djboyj, djboy, djboy, djboy, djboyj, ROT0, "Kaneko (Sega license)", "DJ Boy (Japan)", GAME_SUPPORTS_SAVE ) // Sega logo in FG ROM

View File

@ -31,35 +31,35 @@
**************************************************************************/ **************************************************************************/
#include "driver.h" #include "driver.h"
#include "kan_pand.h" #include "video/kan_pand.h"
#include "includes/airbustr.h"
UINT8 *airbustr_videoram2, *airbustr_colorram2;
//int airbustr_clear_sprites;
static tilemap *bg_tilemap, *fg_tilemap;
static bitmap_t *sprites_bitmap;
WRITE8_HANDLER( airbustr_videoram_w ) WRITE8_HANDLER( airbustr_videoram_w )
{ {
space->machine->generic.videoram.u8[offset] = data; airbustr_state *state = (airbustr_state *)space->machine->driver_data;
tilemap_mark_tile_dirty(bg_tilemap, offset); state->videoram[offset] = data;
tilemap_mark_tile_dirty(state->bg_tilemap, offset);
} }
WRITE8_HANDLER( airbustr_colorram_w ) WRITE8_HANDLER( airbustr_colorram_w )
{ {
space->machine->generic.colorram.u8[offset] = data; airbustr_state *state = (airbustr_state *)space->machine->driver_data;
tilemap_mark_tile_dirty(bg_tilemap, offset); state->colorram[offset] = data;
tilemap_mark_tile_dirty(state->bg_tilemap, offset);
} }
WRITE8_HANDLER( airbustr_videoram2_w ) WRITE8_HANDLER( airbustr_videoram2_w )
{ {
airbustr_videoram2[offset] = data; airbustr_state *state = (airbustr_state *)space->machine->driver_data;
tilemap_mark_tile_dirty(fg_tilemap, offset); state->videoram2[offset] = data;
tilemap_mark_tile_dirty(state->fg_tilemap, offset);
} }
WRITE8_HANDLER( airbustr_colorram2_w ) WRITE8_HANDLER( airbustr_colorram2_w )
{ {
airbustr_colorram2[offset] = data; airbustr_state *state = (airbustr_state *)space->machine->driver_data;
tilemap_mark_tile_dirty(fg_tilemap, offset); state->colorram2[offset] = data;
tilemap_mark_tile_dirty(state->fg_tilemap, offset);
} }
/* Scroll Registers /* Scroll Registers
@ -76,29 +76,29 @@ WRITE8_HANDLER( airbustr_colorram2_w )
WRITE8_HANDLER( airbustr_scrollregs_w ) WRITE8_HANDLER( airbustr_scrollregs_w )
{ {
static int bg_scrollx, bg_scrolly, fg_scrollx, fg_scrolly, highbits; airbustr_state *state = (airbustr_state *)space->machine->driver_data;
switch (offset) // offset 0 <-> port 4 switch (offset) // offset 0 <-> port 4
{ {
case 0x00: fg_scrolly = data; break; // low 8 bits case 0x00: state->fg_scrolly = data; break; // low 8 bits
case 0x02: fg_scrollx = data; break; case 0x02: state->fg_scrollx = data; break;
case 0x04: bg_scrolly = data; break; case 0x04: state->bg_scrolly = data; break;
case 0x06: bg_scrollx = data; break; case 0x06: state->bg_scrollx = data; break;
case 0x08: highbits = ~data; break; // complemented high bits case 0x08: state->highbits = ~data; break; // complemented high bits
default: logerror("CPU #2 - port %02X written with %02X - PC = %04X\n", offset, data, cpu_get_pc(space->cpu)); default: logerror("CPU #2 - port %02X written with %02X - PC = %04X\n", offset, data, cpu_get_pc(space->cpu));
} }
tilemap_set_scrolly(bg_tilemap, 0, ((highbits << 5) & 0x100) + bg_scrolly); tilemap_set_scrolly(state->bg_tilemap, 0, ((state->highbits << 5) & 0x100) + state->bg_scrolly);
tilemap_set_scrollx(bg_tilemap, 0, ((highbits << 6) & 0x100) + bg_scrollx); tilemap_set_scrollx(state->bg_tilemap, 0, ((state->highbits << 6) & 0x100) + state->bg_scrollx);
tilemap_set_scrolly(fg_tilemap, 0, ((highbits << 7) & 0x100) + fg_scrolly); tilemap_set_scrolly(state->fg_tilemap, 0, ((state->highbits << 7) & 0x100) + state->fg_scrolly);
tilemap_set_scrollx(fg_tilemap, 0, ((highbits << 8) & 0x100) + fg_scrollx); tilemap_set_scrollx(state->fg_tilemap, 0, ((state->highbits << 8) & 0x100) + state->fg_scrollx);
} }
static TILE_GET_INFO( get_fg_tile_info ) static TILE_GET_INFO( get_fg_tile_info )
{ {
int attr = airbustr_colorram2[tile_index]; airbustr_state *state = (airbustr_state *)machine->driver_data;
int code = airbustr_videoram2[tile_index] + ((attr & 0x0f) << 8); int attr = state->colorram2[tile_index];
int code = state->videoram2[tile_index] + ((attr & 0x0f) << 8);
int color = attr >> 4; int color = attr >> 4;
SET_TILE_INFO(0, code, color, 0); SET_TILE_INFO(0, code, color, 0);
@ -106,8 +106,9 @@ static TILE_GET_INFO( get_fg_tile_info )
static TILE_GET_INFO( get_bg_tile_info ) static TILE_GET_INFO( get_bg_tile_info )
{ {
int attr = machine->generic.colorram.u8[tile_index]; airbustr_state *state = (airbustr_state *)machine->driver_data;
int code = machine->generic.videoram.u8[tile_index] + ((attr & 0x0f) << 8); int attr = state->colorram[tile_index];
int code = state->videoram[tile_index] + ((attr & 0x0f) << 8);
int color = (attr >> 4) + 16; int color = (attr >> 4) + 16;
SET_TILE_INFO(0, code, color, 0); SET_TILE_INFO(0, code, color, 0);
@ -115,36 +116,41 @@ static TILE_GET_INFO( get_bg_tile_info )
VIDEO_START( airbustr ) VIDEO_START( airbustr )
{ {
bg_tilemap = tilemap_create(machine, get_bg_tile_info, tilemap_scan_rows, 16, 16, 32, 32); airbustr_state *state = (airbustr_state *)machine->driver_data;
fg_tilemap = tilemap_create(machine, get_fg_tile_info, tilemap_scan_rows, 16, 16, 32, 32);
sprites_bitmap = video_screen_auto_bitmap_alloc(machine->primary_screen); state->bg_tilemap = tilemap_create(machine, get_bg_tile_info, tilemap_scan_rows, 16, 16, 32, 32);
state_save_register_global_bitmap(machine, sprites_bitmap); state->fg_tilemap = tilemap_create(machine, get_fg_tile_info, tilemap_scan_rows, 16, 16, 32, 32);
tilemap_set_transparent_pen(fg_tilemap, 0);
tilemap_set_scrolldx(bg_tilemap, 0x094, 0x06a); state->sprites_bitmap = video_screen_auto_bitmap_alloc(machine->primary_screen);
tilemap_set_scrolldy(bg_tilemap, 0x100, 0x1ff); tilemap_set_transparent_pen(state->fg_tilemap, 0);
tilemap_set_scrolldx(fg_tilemap, 0x094, 0x06a);
tilemap_set_scrolldy(fg_tilemap, 0x100, 0x1ff); tilemap_set_scrolldx(state->bg_tilemap, 0x094, 0x06a);
tilemap_set_scrolldy(state->bg_tilemap, 0x100, 0x1ff);
tilemap_set_scrolldx(state->fg_tilemap, 0x094, 0x06a);
tilemap_set_scrolldy(state->fg_tilemap, 0x100, 0x1ff);
state_save_register_global_bitmap(machine, state->sprites_bitmap);
} }
VIDEO_UPDATE( airbustr ) VIDEO_UPDATE( airbustr )
{ {
const device_config *pandora = devtag_get_device(screen->machine, "pandora"); airbustr_state *state = (airbustr_state *)screen->machine->driver_data;
tilemap_draw(bitmap, cliprect, bg_tilemap, 0, 0);
tilemap_draw(bitmap, cliprect, fg_tilemap, 0, 0); tilemap_draw(bitmap, cliprect, state->bg_tilemap, 0, 0);
tilemap_draw(bitmap, cliprect, state->fg_tilemap, 0, 0);
// copy the sprite bitmap to the screen // copy the sprite bitmap to the screen
pandora_update(pandora, bitmap, cliprect); pandora_update(state->pandora, bitmap, cliprect);
return 0; return 0;
} }
VIDEO_EOF( airbustr ) VIDEO_EOF( airbustr )
{ {
const device_config *pandora = devtag_get_device(machine, "pandora"); airbustr_state *state = (airbustr_state *)machine->driver_data;
// update the sprite bitmap // update the sprite bitmap
pandora_eof(pandora); pandora_eof(state->pandora);
} }

View File

@ -4,58 +4,58 @@
* video hardware for DJ Boy * video hardware for DJ Boy
*/ */
#include "driver.h" #include "driver.h"
#include "kan_pand.h" #include "video/kan_pand.h"
#include "includes/djboy.h"
static UINT8 djboy_videoreg, djboy_scrollx, djboy_scrolly;
static tilemap *background;
void djboy_set_videoreg( UINT8 data )
{
djboy_videoreg = data;
}
WRITE8_HANDLER( djboy_scrollx_w ) WRITE8_HANDLER( djboy_scrollx_w )
{ {
djboy_scrollx = data; djboy_state *state = (djboy_state *)space->machine->driver_data;
state->scrollx = data;
} }
WRITE8_HANDLER( djboy_scrolly_w ) WRITE8_HANDLER( djboy_scrolly_w )
{ {
djboy_scrolly = data; djboy_state *state = (djboy_state *)space->machine->driver_data;
state->scrolly = data;
} }
static TILE_GET_INFO( get_bg_tile_info ) static TILE_GET_INFO( get_bg_tile_info )
{ {
UINT8 attr = machine->generic.videoram.u8[tile_index + 0x800]; djboy_state *state = (djboy_state *)machine->driver_data;
int code = machine->generic.videoram.u8[tile_index] + (attr&0xf)*256; UINT8 attr = state->videoram[tile_index + 0x800];
int color = attr>>4; int code = state->videoram[tile_index] + (attr & 0xf) * 256;
if( color&8 ) int color = attr >> 4;
{
if (color & 8)
code |= 0x1000; code |= 0x1000;
}
SET_TILE_INFO(1, code, color, 0); /* no flip */ SET_TILE_INFO(1, code, color, 0); /* no flip */
} }
WRITE8_HANDLER( djboy_videoram_w ) WRITE8_HANDLER( djboy_videoram_w )
{ {
space->machine->generic.videoram.u8[offset] = data; djboy_state *state = (djboy_state *)space->machine->driver_data;
tilemap_mark_tile_dirty( background, offset & 0x7ff);
state->videoram[offset] = data;
tilemap_mark_tile_dirty(state->background, offset & 0x7ff);
} }
VIDEO_START( djboy ) VIDEO_START( djboy )
{ {
background = tilemap_create(machine, get_bg_tile_info,tilemap_scan_rows,16,16,64,32); djboy_state *state = (djboy_state *)machine->driver_data;
state->background = tilemap_create(machine, get_bg_tile_info, tilemap_scan_rows, 16, 16, 64, 32);
} }
WRITE8_HANDLER( djboy_paletteram_w ) WRITE8_HANDLER( djboy_paletteram_w )
{ {
djboy_state *state = (djboy_state *)space->machine->driver_data;
int val; int val;
space->machine->generic.paletteram.u8[offset] = data; state->paletteram[offset] = data;
offset &= ~1; offset &= ~1;
val = (space->machine->generic.paletteram.u8[offset]<<8) | space->machine->generic.paletteram.u8[offset+1]; val = (state->paletteram[offset] << 8) | state->paletteram[offset + 1];
palette_set_color_rgb(space->machine,offset/2,pal4bit(val >> 8),pal4bit(val >> 4),pal4bit(val >> 0)); palette_set_color_rgb(space->machine, offset / 2, pal4bit(val >> 8), pal4bit(val >> 4), pal4bit(val >> 0));
} }
VIDEO_UPDATE( djboy ) VIDEO_UPDATE( djboy )
@ -66,19 +66,23 @@ VIDEO_UPDATE( djboy )
* ---x---- flipscreen? * ---x---- flipscreen?
* ----xxxx ROM bank * ----xxxx ROM bank
*/ */
const device_config *pandora = devtag_get_device(screen->machine, "pandora"); djboy_state *state = (djboy_state *)screen->machine->driver_data;
int scroll; int scroll;
scroll = djboy_scrollx | ((djboy_videoreg&0xc0)<<2);
tilemap_set_scrollx( background, 0, scroll-0x391 ); scroll = state->scrollx | ((state->videoreg & 0xc0) << 2);
scroll = djboy_scrolly | ((djboy_videoreg&0x20)<<3); tilemap_set_scrollx(state->background, 0, scroll - 0x391);
tilemap_set_scrolly( background, 0, scroll );
tilemap_draw( bitmap, cliprect,background,0,0 ); scroll = state->scrolly | ((state->videoreg & 0x20) << 3);
pandora_update(pandora, bitmap, cliprect); tilemap_set_scrolly(state->background, 0, scroll);
tilemap_draw(bitmap, cliprect, state->background, 0, 0);
pandora_update(state->pandora, bitmap, cliprect);
return 0; return 0;
} }
VIDEO_EOF( djboy ) VIDEO_EOF( djboy )
{ {
const device_config *pandora = devtag_get_device(machine, "pandora"); djboy_state *state = (djboy_state *)machine->driver_data;
pandora_eof(pandora); pandora_eof(state->pandora);
} }