mirror of
https://github.com/holub/mame
synced 2025-05-22 21:58:57 +03:00
More System 1 stuff, in addition to what was before:
* accurate collision detection in all games * correct full memory maps * hooked up 8255 and Z80 PIO correctly * unified many hacked variants into common hardware models * proper mixing using the mixing PROM * converted to tilemaps * fixed shtngmst sprites * correct Z80 timing * proper sound interrupt signaling and feedback * full description of video hardware We now have: * proper input hookup in dakkochn * cleaned up rendering code * fixed cocktail mode in pretty much all games * fixed stuck sprites in some games * partial 8751 simulation for choplift * proper global muting (attract sound off works in older games)
This commit is contained in:
parent
c9626a557a
commit
b6af00c0ae
@ -7,8 +7,6 @@ driver by Jarek Parchanski, Nicola Salmoria, Mirko Buffoni
|
||||
|
||||
Issues:
|
||||
* pitfall2 - missing title
|
||||
* wmatch - stuck sprites
|
||||
* what is P-0??
|
||||
|
||||
|
||||
Up'n Down, Mister Viking, Flicky, SWAT, Water Match and Bull Fight are known
|
||||
@ -18,9 +16,7 @@ DIP locations verified from manual for:
|
||||
- wboy
|
||||
- choplift
|
||||
|
||||
TODO: - background is misplaced in wbmlju
|
||||
- sprites stick in Pitfall II
|
||||
- remove patch in nobb if possible and fully understand the
|
||||
TODO: - remove patch in nobb if possible and fully understand the
|
||||
ports involved in the protection
|
||||
|
||||
*******************************************************************************
|
||||
@ -211,12 +207,13 @@ Notes:
|
||||
#define SOUND_CLOCK XTAL_8MHz
|
||||
|
||||
|
||||
static void (*i8751_reset)(running_machine *machine);
|
||||
static void (*i8751_run)(running_machine *machine, int init);
|
||||
static void (*videomode_custom)(running_machine *machine, UINT8 data, UINT8 prevdata);
|
||||
|
||||
static UINT8 *system1_ram;
|
||||
static UINT8 dakkochn_mux_data;
|
||||
|
||||
static UINT8 bank_bits;
|
||||
static UINT8 videomode_prev;
|
||||
static UINT8 i8751_active;
|
||||
|
||||
|
||||
|
||||
@ -361,14 +358,27 @@ static MACHINE_START( system1 )
|
||||
memory_set_bank(machine, 1, 0);
|
||||
|
||||
z80_set_cycle_tables(cputag_get_cpu(machine, "maincpu"), cc_op, cc_cb, cc_ed, cc_xy, cc_xycb, cc_ex);
|
||||
|
||||
state_save_register_global(machine, dakkochn_mux_data);
|
||||
state_save_register_global(machine, videomode_prev);
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_RESET( system1 )
|
||||
{
|
||||
dakkochn_mux_data = 0;
|
||||
if (i8751_reset != NULL)
|
||||
(*i8751_reset)(machine);
|
||||
i8751_active = FALSE;
|
||||
if (i8751_run != NULL)
|
||||
(*i8751_run)(machine, TRUE);
|
||||
}
|
||||
|
||||
|
||||
static INTERRUPT_GEN( vblank_irq )
|
||||
{
|
||||
irq0_line_hold(device);
|
||||
|
||||
if (i8751_run != NULL && i8751_active)
|
||||
(*i8751_run)(device->machine, FALSE);
|
||||
}
|
||||
|
||||
|
||||
@ -379,13 +389,27 @@ static MACHINE_RESET( system1 )
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void choplift_i8751_reset(running_machine *machine)
|
||||
static void choplift_i8751_run(running_machine *machine, int init)
|
||||
{
|
||||
const device_config *ppi = devtag_get_device(machine, "ppi");
|
||||
if (init)
|
||||
{
|
||||
const device_config *ppi = devtag_get_device(machine, "ppi");
|
||||
|
||||
/* the 8751 seems to do the 8255 initialization among other things */
|
||||
ppi8255_w(ppi, 3, 0xc0);
|
||||
ppi8255_w(ppi, 2, 0x00);
|
||||
/* the 8751 seems to do the 8255 initialization among other things */
|
||||
ppi8255_w(ppi, 3, 0xc0);
|
||||
ppi8255_w(ppi, 2, 0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
const UINT8 *rom = memory_region(machine, "maincpu");
|
||||
system1_ram[0x88] = 0x01;
|
||||
system1_ram[0x89] = 0xff;
|
||||
memcpy(&system1_ram[0x90], &rom[0x1f8e], 16);
|
||||
videoram[0x740] = 0x01;
|
||||
videoram[0x742] = 0x01;
|
||||
videoram[0x744] = 0x01;
|
||||
videoram[0x746] = 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -436,23 +460,71 @@ static WRITE8_HANDLER(mcuenable_hack_w)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void bank44_custom_w(running_machine *machine, UINT8 data, UINT8 prevdata)
|
||||
{
|
||||
/* bank bits are bits 6 and 2 */
|
||||
memory_set_bank(machine, 1, ((data & 0x40) >> 5) | ((data & 0x04) >> 2));
|
||||
}
|
||||
|
||||
|
||||
static void bank0c_custom_w(running_machine *machine, UINT8 data, UINT8 prevdata)
|
||||
{
|
||||
/* bank bits are bits 3 and 2 */
|
||||
memory_set_bank(machine, 1, (data & 0x0c) >> 2);
|
||||
}
|
||||
|
||||
|
||||
static WRITE8_HANDLER( videomode_w )
|
||||
{
|
||||
int curbit, accum;
|
||||
|
||||
/* find the appropriate bits in the data and update the bank */
|
||||
accum = 0;
|
||||
for (curbit = 7; curbit >= 0; curbit--)
|
||||
if (bank_bits & (1 << curbit))
|
||||
accum = (accum << 1) | ((data >> curbit) & 1);
|
||||
memory_set_bank(space->machine, 1, accum);
|
||||
if ((data & 0x40) && !(videomode_prev & 0x40))
|
||||
i8751_active = TRUE;
|
||||
|
||||
/* handle any custom banking or other stuff */
|
||||
if (videomode_custom != NULL)
|
||||
(*videomode_custom)(space->machine, data, videomode_prev);
|
||||
videomode_prev = data;
|
||||
|
||||
/* bit 0 is for the coin counters */
|
||||
coin_counter_w(0, data & 1);
|
||||
|
||||
/* remaining signals are video-related */
|
||||
system1_videomode_w(space, 0, data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* DakkoChan House custom inputs
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static CUSTOM_INPUT( dakkochn_mux_data_r )
|
||||
{
|
||||
static const char *ports[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5", "KEY6" };
|
||||
return input_port_read(field->port->machine, ports[dakkochn_mux_data]);
|
||||
}
|
||||
|
||||
|
||||
static CUSTOM_INPUT( dakkochn_mux_status_r )
|
||||
{
|
||||
/* reads from here indicate which mux port is selected */
|
||||
return 1 << (dakkochn_mux_data);
|
||||
}
|
||||
|
||||
|
||||
static void dakkochn_custom_w(running_machine *machine, UINT8 data, UINT8 prevdata)
|
||||
{
|
||||
/* bit 1 toggling on clocks the mux; we store the previous state in the high bit of dakkochn_mux_data */
|
||||
if ((data & 0x02) && !(prevdata & 0x02))
|
||||
dakkochn_mux_data = (dakkochn_mux_data + 1) % 7;
|
||||
|
||||
/* remaining stuff acts like bank0c */
|
||||
bank0c_custom_w(machine, data, prevdata);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Sound I/O
|
||||
@ -462,8 +534,9 @@ static WRITE8_HANDLER( videomode_w )
|
||||
static WRITE8_DEVICE_HANDLER( sound_control_w )
|
||||
{
|
||||
/* bit 0 = MUTE */
|
||||
sound_global_enable(~(data & 1));
|
||||
|
||||
/* bit 6 = /P-0??? */
|
||||
/* bit 6 = feedback from sound board that read occurrred */
|
||||
|
||||
/* bit 7 controls the sound CPU's NMI line */
|
||||
cputag_set_input_line(device->machine, "soundcpu", INPUT_LINE_NMI, (data & 0x80) ? CLEAR_LINE : ASSERT_LINE);
|
||||
@ -621,8 +694,8 @@ ADDRESS_MAP_END
|
||||
static ADDRESS_MAP_START( sound_map, ADDRESS_SPACE_PROGRAM, 8 )
|
||||
AM_RANGE(0x0000, 0x7fff) AM_ROM
|
||||
AM_RANGE(0x8000, 0x87ff) AM_MIRROR(0x1800) AM_RAM
|
||||
AM_RANGE(0xa000, 0xa003) AM_MIRROR(0x1ffc) AM_DEVWRITE("sn1", sn76496_w) /* Choplifter writes to the four addresses */
|
||||
AM_RANGE(0xc000, 0xc003) AM_MIRROR(0x1ffc) AM_DEVWRITE("sn2", sn76496_w) /* in sequence */
|
||||
AM_RANGE(0xa000, 0xa003) AM_MIRROR(0x1fff) AM_DEVWRITE("sn1", sn76496_w)
|
||||
AM_RANGE(0xc000, 0xc003) AM_MIRROR(0x1fff) AM_DEVWRITE("sn2", sn76496_w)
|
||||
AM_RANGE(0xe000, 0xe000) AM_MIRROR(0x1fff) AM_READ(sound_data_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
@ -1750,13 +1823,13 @@ static INPUT_PORTS_START( dakkochn )
|
||||
PORT_INCLUDE( choplift )
|
||||
|
||||
PORT_MODIFY("P1")
|
||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(dakkochn_mux_data_r, NULL)
|
||||
|
||||
PORT_MODIFY("P2")
|
||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM(dakkochn_mux_status_r, NULL)
|
||||
|
||||
PORT_MODIFY("SYSTEM")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) //start 1 & 2 not connected.
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) /* start 1 & 2 not connected. */
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
/*TODO: Dip-Switches */
|
||||
@ -1783,9 +1856,6 @@ static INPUT_PORTS_START( dakkochn )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
|
||||
PORT_START("KEY0")
|
||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("KEY1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_A )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_B )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_C )
|
||||
@ -1793,21 +1863,21 @@ static INPUT_PORTS_START( dakkochn )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_LAST_CHANCE )
|
||||
PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("KEY2")
|
||||
PORT_START("KEY1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_E )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_F )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_G )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_H )
|
||||
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("KEY3")
|
||||
PORT_START("KEY2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_I )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_J )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_K )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_L )
|
||||
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("KEY4")
|
||||
PORT_START("KEY3")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_M )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_N )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_CHI )
|
||||
@ -1815,16 +1885,19 @@ static INPUT_PORTS_START( dakkochn )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_FLIP_FLOP )
|
||||
PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("KEY5")
|
||||
PORT_START("KEY4")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_BET )
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("KEY6")
|
||||
PORT_START("KEY5")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_KAN )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_REACH )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_RON )
|
||||
PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("KEY6")
|
||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
INPUT_PORTS_END
|
||||
|
||||
/*
|
||||
@ -1934,7 +2007,7 @@ static MACHINE_DRIVER_START( sys1ppi )
|
||||
MDRV_CPU_ADD("maincpu", Z80, MASTER_CLOCK) /* not really, see notes above */
|
||||
MDRV_CPU_PROGRAM_MAP(system1_map,0)
|
||||
MDRV_CPU_IO_MAP(system1_ppi_io_map,0)
|
||||
MDRV_CPU_VBLANK_INT("screen", irq0_line_hold)
|
||||
MDRV_CPU_VBLANK_INT("screen", vblank_irq)
|
||||
|
||||
MDRV_CPU_ADD("soundcpu", Z80, SOUND_CLOCK/2)
|
||||
MDRV_CPU_PROGRAM_MAP(sound_map,0)
|
||||
@ -1946,7 +2019,7 @@ static MACHINE_DRIVER_START( sys1ppi )
|
||||
MDRV_PPI8255_ADD("ppi", ppi_interface)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_VIDEO_ATTRIBUTES(VIDEO_ALWAYS_UPDATE)// hw collisions
|
||||
MDRV_VIDEO_ATTRIBUTES(VIDEO_ALWAYS_UPDATE) /* needed for proper hardware collisions */
|
||||
|
||||
MDRV_SCREEN_ADD("screen", RASTER)
|
||||
MDRV_SCREEN_REFRESH_RATE(60)
|
||||
@ -2007,31 +2080,25 @@ MACHINE_DRIVER_END
|
||||
|
||||
/* main CPU hacked speed */
|
||||
static MACHINE_DRIVER_START( pitfall2 )
|
||||
MDRV_IMPORT_FROM( sys1pio )
|
||||
|
||||
/* basic machine hardware */
|
||||
MDRV_IMPORT_FROM( sys1pio )
|
||||
MDRV_CPU_REPLACE( "maincpu", Z80, 3600000 )/* should be 4 MHz but that value makes the title screen disappear */
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
/* alternate program map with RAM/collision swapped */
|
||||
static MACHINE_DRIVER_START( nob )
|
||||
MDRV_IMPORT_FROM( sys1ppis )
|
||||
|
||||
/* basic machine hardware */
|
||||
MDRV_IMPORT_FROM( sys1ppi )
|
||||
MDRV_CPU_MODIFY("maincpu")
|
||||
MDRV_CPU_PROGRAM_MAP(nobo_map,0)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_SCREEN_MODIFY("screen")
|
||||
MDRV_SCREEN_VISIBLE_AREA(1*8, 31*8-1, 0*8, 28*8-1)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
|
||||
/* system2 video */
|
||||
static MACHINE_DRIVER_START( sys2 )
|
||||
|
||||
/* basic machine hardware */
|
||||
MDRV_IMPORT_FROM( sys1ppi )
|
||||
|
||||
/* video hardware */
|
||||
@ -2039,9 +2106,8 @@ static MACHINE_DRIVER_START( sys2 )
|
||||
MDRV_VIDEO_UPDATE(system2)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
/* system 2 with small screen */
|
||||
static MACHINE_DRIVER_START( sys2s )
|
||||
|
||||
/* basic machine hardware */
|
||||
MDRV_IMPORT_FROM( sys2 )
|
||||
|
||||
/* video hardware */
|
||||
@ -2051,8 +2117,6 @@ MACHINE_DRIVER_END
|
||||
|
||||
/* system2 with rowscroll */
|
||||
static MACHINE_DRIVER_START( sys2row )
|
||||
|
||||
/* basic machine hardware */
|
||||
MDRV_IMPORT_FROM( sys2 )
|
||||
|
||||
/* video hardware */
|
||||
@ -2061,8 +2125,6 @@ MACHINE_DRIVER_END
|
||||
|
||||
/* rowscroll with small screen */
|
||||
static MACHINE_DRIVER_START( sys2rows )
|
||||
|
||||
/* basic machine hardware */
|
||||
MDRV_IMPORT_FROM( sys2row )
|
||||
|
||||
/* video hardware */
|
||||
@ -4413,9 +4475,9 @@ ROM_END
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static DRIVER_INIT( bank00 ) { i8751_reset = NULL; bank_bits = 0x00; }
|
||||
static DRIVER_INIT( bank44 ) { i8751_reset = NULL; bank_bits = 0x44; }
|
||||
static DRIVER_INIT( bank0c ) { i8751_reset = NULL; bank_bits = 0x0c; }
|
||||
static DRIVER_INIT( bank00 ) { i8751_run = NULL; videomode_custom = NULL; }
|
||||
static DRIVER_INIT( bank44 ) { i8751_run = NULL; videomode_custom = bank44_custom_w; }
|
||||
static DRIVER_INIT( bank0c ) { i8751_run = NULL; videomode_custom = bank0c_custom_w; }
|
||||
|
||||
static DRIVER_INIT( regulus ) { DRIVER_INIT_CALL(bank00); regulus_decode(machine, "maincpu"); }
|
||||
static DRIVER_INIT( mrviking ) { DRIVER_INIT_CALL(bank00); mrviking_decode(machine, "maincpu"); }
|
||||
@ -4444,70 +4506,19 @@ static DRIVER_INIT( wbml ) { DRIVER_INIT_CALL(bank0c); mc8123_decrypt_rom(machi
|
||||
static DRIVER_INIT( ufosensi ) { DRIVER_INIT_CALL(bank0c); mc8123_decrypt_rom(machine, "maincpu", "key", 1, 4); }
|
||||
static DRIVER_INIT( wboysys2 ) { DRIVER_INIT_CALL(bank0c); astrofl_decode(machine, "maincpu"); }
|
||||
|
||||
static UINT8 dakkochn_control;
|
||||
|
||||
/*
|
||||
This game doesn't seem to have any mux writes, so I'm assuming that the mux does HW auto-incrementing.
|
||||
I need schematics to understand how it's properly mapped anyway, because it could be for example tied
|
||||
with vblank/video bits.
|
||||
The program flow is:
|
||||
I/O $00 R
|
||||
I/O $15 W 0xe
|
||||
I/O $15 W 0xc
|
||||
I/O $00 R
|
||||
I/O $15 W 0xe
|
||||
(and so on)
|
||||
|
||||
*/
|
||||
static READ8_HANDLER( dakkochn_port_00_r )
|
||||
{
|
||||
static UINT8 res;
|
||||
|
||||
switch(dakkochn_mux_data)
|
||||
{
|
||||
case 0: res = input_port_read(space->machine, "KEY0"); break;
|
||||
case 1: res = input_port_read(space->machine, "KEY1"); break;
|
||||
case 2: res = input_port_read(space->machine, "KEY2"); break;
|
||||
case 3: res = input_port_read(space->machine, "KEY3"); break;
|
||||
case 4: res = input_port_read(space->machine, "KEY4"); break;
|
||||
case 5: res = input_port_read(space->machine, "KEY5"); break;
|
||||
case 6: res = input_port_read(space->machine, "KEY6"); break;
|
||||
}
|
||||
|
||||
dakkochn_mux_data++;
|
||||
if(dakkochn_mux_data >= 7)
|
||||
dakkochn_mux_data = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static READ8_HANDLER( dakkochn_port_03_r )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static READ8_HANDLER( dakkochn_port_04_r )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( dakkochn_port_15_w )
|
||||
{
|
||||
dakkochn_control = data; // check if any control multiplex bits are in here!
|
||||
videomode_w(space,offset,data);
|
||||
}
|
||||
|
||||
static DRIVER_INIT( dakkochn )
|
||||
{
|
||||
DRIVER_INIT_CALL(bank0c);
|
||||
videomode_custom = dakkochn_custom_w;
|
||||
|
||||
mc8123_decrypt_rom(machine, "maincpu", "proms", 1, 4);
|
||||
mc8123_decrypt_rom(machine, "maincpu", "key", 1, 4);
|
||||
|
||||
memory_install_read8_handler(cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_IO), 0x00, 0x00, 0, 0, dakkochn_port_00_r);
|
||||
memory_install_read8_handler(cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_IO), 0x03, 0x03, 0, 0, dakkochn_port_03_r);
|
||||
memory_install_read8_handler(cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_IO), 0x04, 0x04, 0, 0, dakkochn_port_04_r);
|
||||
// memory_install_read8_handler(cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_IO), 0x00, 0x00, 0, 0, dakkochn_port_00_r);
|
||||
// memory_install_read8_handler(cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_IO), 0x03, 0x03, 0, 0, dakkochn_port_03_r);
|
||||
// memory_install_read8_handler(cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_IO), 0x04, 0x04, 0, 0, dakkochn_port_04_r);
|
||||
|
||||
memory_install_write8_handler(cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_IO), 0x15, 0x15, 0, 0, dakkochn_port_15_w);
|
||||
// memory_install_write8_handler(cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_IO), 0x15, 0x15, 0, 0, dakkochn_port_15_w);
|
||||
}
|
||||
|
||||
|
||||
@ -4607,7 +4618,7 @@ static DRIVER_INIT( bootlegb )
|
||||
static DRIVER_INIT( choplift )
|
||||
{
|
||||
DRIVER_INIT_CALL(bank0c);
|
||||
i8751_reset = choplift_i8751_reset;
|
||||
i8751_run = choplift_i8751_run;
|
||||
}
|
||||
|
||||
static DRIVER_INIT( shtngmst )
|
||||
@ -4680,7 +4691,7 @@ GAME( 1986, wboyo, wboy, sys1pio, wboy, wboyo, ROT0, "Sega (
|
||||
GAME( 1986, wboy3, wboy, sys1pio, wboy3, wboyo, ROT0, "Sega (Escape license)", "Wonder Boy (set 3, 315-5135)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1986, wboy4, wboy, sys1pio, wboy, 4dwarrio, ROT0, "Sega (Escape license)", "Wonder Boy (315-5162, 4-D Warriors Conversion)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1986, wboyu, wboy, sys1pio, wboyu, bank00, ROT0, "Sega (Escape license)", "Wonder Boy (not encrypted)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, blockgal, 0, sys1pio, blockgal, blockgal, ROT90, "Sega / Vic Tokai", "Block Gal (MC-8123B, 317-0029)", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE)
|
||||
GAME( 1987, blockgal, 0, sys1pio, blockgal, blockgal, ROT90, "Sega / Vic Tokai", "Block Gal (MC-8123B, 317-0029)", GAME_SUPPORTS_SAVE)
|
||||
|
||||
/* PIO-based System 1 with ROM banking */
|
||||
GAME( 1985, hvymetal, 0, sys1pio, hvymetal, hvymetal, ROT0, "Sega", "Heavy Metal (315-5135)", GAME_SUPPORTS_SAVE )
|
||||
@ -4691,18 +4702,18 @@ GAME( 1986, brain, 0, sys1pio, brain, bank44, ROT0, "Corela
|
||||
GAME( 1985, choplift, 0, sys2row, choplift, choplift, ROT0, "Sega", "Choplifter (8751 315-5151)", GAME_UNEMULATED_PROTECTION | GAME_SUPPORTS_SAVE | GAME_NOT_WORKING )
|
||||
GAME( 1985, chopliftu, choplift, sys2row, choplift, bank0c, ROT0, "Sega", "Choplifter (unprotected)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1985, chopliftbl, choplift, sys2row, choplift, bank0c, ROT0, "bootleg", "Choplifter (bootleg)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1985, shtngmst, 0, sys2s, shtngmst, shtngmst, ROT0, "Sega", "Shooting Master (Rev A, 8751 315-5159a)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE | GAME_NOT_WORKING )
|
||||
GAME( 1985, shtngmst1, shtngmst, sys2s, shtngmst, shtngmst, ROT0, "Sega", "Shooting Master (8751 315-5159)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE | GAME_NOT_WORKING )
|
||||
GAME( 1985, shtngmsta, shtngmst, sys2s, shtngmst, shtngmst, ROT0, "Sega [EVG]", "Shooting Master (EVG, 8751 315-5159)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE | GAME_NOT_WORKING )
|
||||
GAME( 1986, gardiab, gardia, sys2, gardia, gardiab, ROT270, "bootleg", "Gardia (317-0007?, bootleg)", GAME_IMPERFECT_GRAPHICS | GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
|
||||
GAME( 1985, shtngmst, 0, sys2s, shtngmst, shtngmst, ROT0, "Sega", "Shooting Master (Rev A, 8751 315-5159a)", GAME_SUPPORTS_SAVE | GAME_NOT_WORKING )
|
||||
GAME( 1985, shtngmst1, shtngmst, sys2s, shtngmst, shtngmst, ROT0, "Sega", "Shooting Master (8751 315-5159)", GAME_SUPPORTS_SAVE | GAME_NOT_WORKING )
|
||||
GAME( 1985, shtngmsta, shtngmst, sys2s, shtngmst, shtngmst, ROT0, "Sega [EVG]", "Shooting Master (EVG, 8751 315-5159)", GAME_SUPPORTS_SAVE | GAME_NOT_WORKING )
|
||||
GAME( 1986, gardiab, gardia, sys2, gardia, gardiab, ROT270, "bootleg", "Gardia (317-0007?, bootleg)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
GAME( 1986, wboysys2, wboy, sys2, wboysys2, wboysys2, ROT0, "Sega (Escape license)", "Wonder Boy (system 2)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, tokisens, 0, sys2, tokisens, bank0c, ROT90, "Sega", "Toki no Senshi - Chrono Soldier", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, wbml, 0, sys2, wbml, wbml, ROT0, "Sega / Westone", "Wonder Boy in Monster Land (Japan New Ver., MC-8123, 317-0043)", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, wbmljo, wbml, sys2, wbml, wbml, ROT0, "Sega / Westone", "Wonder Boy in Monster Land (Japan Old Ver., MC-8123, 317-0043)", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, wbmljb, wbml, sys2, wbml, bootlegb, ROT0, "bootleg", "Wonder Boy in Monster Land (Japan not encrypted)", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, wbmlb, wbml, sys2, wbml, bootlegb, ROT0, "bootleg", "Wonder Boy in Monster Land (English bootleg)", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE)
|
||||
GAME( 1987, wbmlbg, wbml, sys2, wbml, bootlegb, ROT0, "bootleg", "Wonder Boy in Monster Land (Galaxy Electronics English bootleg)", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE)
|
||||
GAME( 1987, dakkochn, 0, sys2, dakkochn, dakkochn, ROT0, "Whiteboard", "DakkoChan House (MC-8123, 317-0014)", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE | GAME_IMPERFECT_GRAPHICS )
|
||||
GAME( 1987, blockgalb, blockgal, sys2, blockgal, bootleg, ROT90, "bootleg", "Block Gal (bootleg)", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, tokisens, 0, sys2, tokisens, bank0c, ROT90, "Sega", "Toki no Senshi - Chrono Soldier", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, wbml, 0, sys2, wbml, wbml, ROT0, "Sega / Westone", "Wonder Boy in Monster Land (Japan New Ver., MC-8123, 317-0043)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, wbmljo, wbml, sys2, wbml, wbml, ROT0, "Sega / Westone", "Wonder Boy in Monster Land (Japan Old Ver., MC-8123, 317-0043)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, wbmljb, wbml, sys2, wbml, bootlegb, ROT0, "bootleg", "Wonder Boy in Monster Land (Japan not encrypted)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, wbmlb, wbml, sys2, wbml, bootlegb, ROT0, "bootleg", "Wonder Boy in Monster Land (English bootleg)", GAME_SUPPORTS_SAVE)
|
||||
GAME( 1987, wbmlbg, wbml, sys2, wbml, bootlegb, ROT0, "bootleg", "Wonder Boy in Monster Land (Galaxy Electronics English bootleg)", GAME_SUPPORTS_SAVE)
|
||||
GAME( 1987, dakkochn, 0, sys2, dakkochn, dakkochn, ROT0, "Whiteboard", "DakkoChan House (MC-8123, 317-0014)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1987, blockgalb, blockgal, sys2, blockgal, bootleg, ROT90, "bootleg", "Block Gal (bootleg)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1988, ufosensi, 0, sys2rows, ufosensi, ufosensi, ROT0, "Sega", "Ufo Senshi Yohko Chan (MC-8123, 317-0064)", GAME_SUPPORTS_SAVE )
|
||||
GAME( 1988, ufosensib, ufosensi, sys2rows, ufosensi, bootlegb, ROT0, "bootleg", "Ufo Senshi Yohko Chan (not encrypted)", GAME_SUPPORTS_SAVE )
|
||||
|
@ -34,9 +34,8 @@
|
||||
pixel data and sprite index. During rendering, collisions are
|
||||
checked between sprites and if one is found a bit is set in a
|
||||
special 32x32x1 collision RAM indiciating which pair of sprites
|
||||
collided. Note that the sprite color is not stored in the line
|
||||
buffer, but it retrieved when the line buffer is read out on the
|
||||
following scanline using the stored sprite index.
|
||||
collided. Note that the sprite color is derived directly from the
|
||||
sprite index, giving each sprite its own set of 16 colors.
|
||||
|
||||
The 11-bit output from the two tilemaps (3 bits of pixel data,
|
||||
6 bits of color, 2 bits of priority), plus the 9-bit output from
|
||||
@ -51,7 +50,7 @@
|
||||
9 bits of data from the appropriate source are used as a lookup
|
||||
into a palette RAM, and the lookup PROM's low 2 bits are used as
|
||||
the upper 2 bits of the palette RAM address, providing 512
|
||||
independent colors for each souce.
|
||||
independent colors for each source.
|
||||
|
||||
The upper 2 bits of the lookup PROM are used for an additional
|
||||
mixer collision detection. Bit 2 indicates that a collision
|
||||
@ -91,14 +90,111 @@ static bitmap_t *sprite_bitmap;
|
||||
|
||||
static UINT8 system1_video_mode;
|
||||
|
||||
static UINT8 wbml_videoram_bank;
|
||||
|
||||
static int system1_sprite_xoffset;
|
||||
static UINT8 videoram_bank;
|
||||
|
||||
static tilemap *tilemap_page[8];
|
||||
static UINT8 tilemap_pages;
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Tile callback
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static TILE_GET_INFO( tile_get_info )
|
||||
{
|
||||
UINT8 *rambase = param;
|
||||
UINT32 tiledata = rambase[tile_index*2+0] | (rambase[tile_index*2+1] << 8);
|
||||
UINT32 code = ((tiledata >> 4) & 0x800) | (tiledata & 0x7ff);
|
||||
UINT32 color = (tiledata >> 5) & 0xff;
|
||||
|
||||
SET_TILE_INFO(0, code, color, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video startup
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void video_start_common(running_machine *machine, int pagecount)
|
||||
{
|
||||
int pagenum;
|
||||
|
||||
/* allocate memory for the collision arrays */
|
||||
mix_collide = auto_malloc(64);
|
||||
memset(mix_collide, 0, 64);
|
||||
sprite_collide = auto_malloc(1024);
|
||||
memset(sprite_collide, 0, 1024);
|
||||
|
||||
/* allocate memory for videoram */
|
||||
tilemap_pages = pagecount;
|
||||
videoram = auto_malloc(0x800 * pagecount);
|
||||
memset(videoram, 0, 0x800 * pagecount);
|
||||
|
||||
/* create the tilemap pages */
|
||||
for (pagenum = 0; pagenum < pagecount; pagenum++)
|
||||
{
|
||||
tilemap_page[pagenum] = tilemap_create(machine, tile_get_info, tilemap_scan_rows, 8,8, 32,32);
|
||||
tilemap_set_transparent_pen(tilemap_page[pagenum], 0);
|
||||
tilemap_set_user_data(tilemap_page[pagenum], videoram + 0x800 * pagenum);
|
||||
}
|
||||
|
||||
/* allocate a temporary bitmap for sprite rendering */
|
||||
sprite_bitmap = auto_bitmap_alloc(256, 256, BITMAP_FORMAT_INDEXED16);
|
||||
|
||||
/* register for save stats */
|
||||
state_save_register_global(machine, system1_video_mode);
|
||||
state_save_register_global(machine, mix_collide_summary);
|
||||
state_save_register_global(machine, sprite_collide_summary);
|
||||
state_save_register_global_pointer(machine, videoram, 0x800 * pagecount);
|
||||
state_save_register_global_pointer(machine, mix_collide, 64);
|
||||
state_save_register_global_pointer(machine, sprite_collide, 1024);
|
||||
}
|
||||
|
||||
|
||||
VIDEO_START( system1 )
|
||||
{
|
||||
video_start_common(machine, 2);
|
||||
}
|
||||
|
||||
|
||||
VIDEO_START( system2 )
|
||||
{
|
||||
video_start_common(machine, 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video control
|
||||
*
|
||||
*************************************/
|
||||
|
||||
WRITE8_HANDLER( system1_videomode_w )
|
||||
{
|
||||
if (data & 0x6e) logerror("videomode = %02x\n",data);
|
||||
|
||||
/* bit 4 is screen blank */
|
||||
system1_video_mode = data;
|
||||
|
||||
/* bit 7 is flip screen */
|
||||
flip_screen_set(space->machine, data & 0x80);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Mixer collision I/O
|
||||
*
|
||||
*************************************/
|
||||
|
||||
READ8_HANDLER( system1_mixer_collision_r )
|
||||
{
|
||||
video_screen_update_now(space->machine->primary_screen);
|
||||
@ -117,6 +213,14 @@ WRITE8_HANDLER( system1_mixer_collision_reset_w )
|
||||
mix_collide_summary = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Sprite collision I/O
|
||||
*
|
||||
*************************************/
|
||||
|
||||
READ8_HANDLER( system1_sprite_collision_r )
|
||||
{
|
||||
video_screen_update_now(space->machine->primary_screen);
|
||||
@ -136,15 +240,22 @@ WRITE8_HANDLER( system1_sprite_collision_reset_w )
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video RAM access
|
||||
*
|
||||
*************************************/
|
||||
|
||||
READ8_HANDLER( system1_videoram_r )
|
||||
{
|
||||
offset |= 0x1000 * ((wbml_videoram_bank >> 1) % (tilemap_pages / 2));
|
||||
offset |= 0x1000 * ((videoram_bank >> 1) % (tilemap_pages / 2));
|
||||
return videoram[offset];
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( system1_videoram_w )
|
||||
{
|
||||
offset |= 0x1000 * ((wbml_videoram_bank >> 1) % (tilemap_pages / 2));
|
||||
offset |= 0x1000 * ((videoram_bank >> 1) % (tilemap_pages / 2));
|
||||
videoram[offset] = data;
|
||||
|
||||
tilemap_mark_tile_dirty(tilemap_page[offset / 0x800], (offset % 0x800) / 2);
|
||||
@ -156,38 +267,43 @@ WRITE8_HANDLER( system1_videoram_w )
|
||||
|
||||
WRITE8_DEVICE_HANDLER( system1_videoram_bank_w )
|
||||
{
|
||||
wbml_videoram_bank = data;
|
||||
videoram_bank = data;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
There are two kind of color handling: in the System 1 games, values in the
|
||||
palette RAM are directly mapped to colors with the usual BBGGGRRR format;
|
||||
in the System 2 ones (Choplifter, WBML, etc.), the value in the palette RAM
|
||||
is a lookup offset for three palette PROMs in RRRRGGGGBBBB format.
|
||||
|
||||
It's hard to tell for sure because they use resistor packs, but here's
|
||||
what I think the values are from measurment with a volt meter:
|
||||
|
||||
Blue: .250K ohms
|
||||
Blue: .495K ohms
|
||||
Green:.250K ohms
|
||||
Green:.495K ohms
|
||||
Green:.995K ohms
|
||||
Red: .495K ohms
|
||||
Red: .250K ohms
|
||||
Red: .995K ohms
|
||||
|
||||
accurate to +/- .003K ohms.
|
||||
|
||||
***************************************************************************/
|
||||
/*************************************
|
||||
*
|
||||
* Palette RAM access
|
||||
*
|
||||
*************************************/
|
||||
|
||||
WRITE8_HANDLER( system1_paletteram_w )
|
||||
{
|
||||
const UINT8 *color_prom = memory_region(space->machine, "palette");
|
||||
int val,r,g,b;
|
||||
|
||||
/*
|
||||
There are two kind of color handling: in the System 1 games, values in the
|
||||
palette RAM are directly mapped to colors with the usual BBGGGRRR format;
|
||||
in the System 2 ones (Choplifter, WBML, etc.), the value in the palette RAM
|
||||
is a lookup offset for three palette PROMs in RRRRGGGGBBBB format.
|
||||
|
||||
It's hard to tell for sure because they use resistor packs, but here's
|
||||
what I think the values are from measurment with a volt meter:
|
||||
|
||||
Blue: .250K ohms
|
||||
Blue: .495K ohms
|
||||
Green:.250K ohms
|
||||
Green:.495K ohms
|
||||
Green:.995K ohms
|
||||
Red: .495K ohms
|
||||
Red: .250K ohms
|
||||
Red: .995K ohms
|
||||
|
||||
accurate to +/- .003K ohms.
|
||||
*/
|
||||
|
||||
paletteram[offset] = data;
|
||||
|
||||
if (color_prom != NULL)
|
||||
@ -225,192 +341,145 @@ WRITE8_HANDLER( system1_paletteram_w )
|
||||
palette_set_color(space->machine,offset,MAKE_RGB(r,g,b));
|
||||
}
|
||||
|
||||
static TILE_GET_INFO( tile_get_info )
|
||||
{
|
||||
UINT8 *rambase = param;
|
||||
UINT32 tiledata = rambase[tile_index*2+0] | (rambase[tile_index*2+1] << 8);
|
||||
UINT32 code = ((tiledata >> 4) & 0x800) | (tiledata & 0x7ff); /* Heavy Metal only */
|
||||
UINT32 color = (tiledata >> 5) & 0xff;
|
||||
|
||||
SET_TILE_INFO(0, code, color, 0);
|
||||
}
|
||||
|
||||
static void video_start_common(running_machine *machine, int pagecount)
|
||||
{
|
||||
int pagenum;
|
||||
|
||||
/* allocate memory for the collision arrays */
|
||||
mix_collide = auto_malloc(64);
|
||||
memset(mix_collide, 0, 64);
|
||||
sprite_collide = auto_malloc(1024);
|
||||
memset(sprite_collide, 0, 1024);
|
||||
|
||||
/* allocate memory for videoram */
|
||||
tilemap_pages = pagecount;
|
||||
videoram = auto_malloc(0x800 * pagecount);
|
||||
memset(videoram, 0, 0x800 * pagecount);
|
||||
|
||||
/* create the tilemap pages */
|
||||
for (pagenum = 0; pagenum < pagecount; pagenum++)
|
||||
{
|
||||
tilemap_page[pagenum] = tilemap_create(machine, tile_get_info, tilemap_scan_rows, 8,8, 32,32);
|
||||
tilemap_set_transparent_pen(tilemap_page[pagenum], 0);
|
||||
tilemap_set_user_data(tilemap_page[pagenum], videoram + 0x800 * pagenum);
|
||||
}
|
||||
|
||||
/* allocate a temporary bitmap for sprite rendering */
|
||||
sprite_bitmap = auto_bitmap_alloc(256, 256, BITMAP_FORMAT_INDEXED16);
|
||||
|
||||
state_save_register_global(machine, system1_video_mode);
|
||||
state_save_register_global_pointer(machine, videoram, 0x800 * pagecount);
|
||||
}
|
||||
|
||||
VIDEO_START( system1 )
|
||||
{
|
||||
video_start_common(machine, 2);
|
||||
system1_sprite_xoffset = 1;
|
||||
}
|
||||
|
||||
VIDEO_START( system2 )
|
||||
{
|
||||
video_start_common(machine, 8);
|
||||
system1_sprite_xoffset = 1+7*2;
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( system1_videomode_w )
|
||||
{
|
||||
if (data & 0x6e) logerror("videomode = %02x\n",data);
|
||||
|
||||
/* bit 0 is coin counter */
|
||||
coin_counter_w(0, data & 1);
|
||||
|
||||
/* bit 4 is screen blank */
|
||||
system1_video_mode = data;
|
||||
|
||||
/* bit 7 is flip screen */
|
||||
flip_screen_set(space->machine, data & 0x80);
|
||||
}
|
||||
|
||||
|
||||
INLINE void draw_sprite_pixel(bitmap_t *bitmap, int x, int y, int spr_number, int color)
|
||||
{
|
||||
UINT16 *destpix = BITMAP_ADDR16(bitmap, y, x);
|
||||
int prevpix = *destpix;
|
||||
|
||||
if ((prevpix & 0x0f) != 0)
|
||||
sprite_collide[(prevpix >> 11) + 32 * spr_number] = sprite_collide_summary = 1;
|
||||
|
||||
*destpix = color | (spr_number << 11);
|
||||
}
|
||||
|
||||
static void draw_sprite(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, int spr_number)
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Sprite rendering
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, int xoffset)
|
||||
{
|
||||
UINT32 gfxbanks = memory_region_length(machine, "sprites") / 0x8000;
|
||||
const UINT8 *gfxbase = memory_region(machine, "sprites");
|
||||
int flipscreen = flip_screen_get(machine);
|
||||
int sy,row,height,src,bank;
|
||||
UINT8 *sprite_base;
|
||||
int sprite_palette_base;
|
||||
INT16 skip; /* bytes to skip before drawing each row (can be negative) */
|
||||
UINT8 *gfx;
|
||||
int spritenum;
|
||||
|
||||
|
||||
sprite_base = spriteram + 0x10 * spr_number;
|
||||
|
||||
src = sprite_base[SPR_GFXOFS_LO] + (sprite_base[SPR_GFXOFS_HI] << 8);
|
||||
bank = 0x8000 * (((sprite_base[SPR_X_HI] & 0x80) >> 7) + ((sprite_base[SPR_X_HI] & 0x40) >> 5) + ((sprite_base[SPR_X_HI] & 0x20) >> 3));
|
||||
bank &= (memory_region_length(machine, "sprites")-1); /* limit to the range of available ROMs */
|
||||
skip = sprite_base[SPR_SKIP_LO] + (sprite_base[SPR_SKIP_HI] << 8);
|
||||
|
||||
height = sprite_base[SPR_Y_BOTTOM] - sprite_base[SPR_Y_TOP];
|
||||
sprite_palette_base = 0x10 * spr_number;
|
||||
|
||||
sy = sprite_base[SPR_Y_TOP] + 1;
|
||||
|
||||
/* graphics region #2 contains the packed sprite data */
|
||||
gfx = &memory_region(machine, "sprites")[bank];
|
||||
|
||||
for (row = 0;row < height;row++)
|
||||
/* up to 32 sprites total */
|
||||
for (spritenum = 0; spritenum < 32; spritenum++)
|
||||
{
|
||||
int x,x_flipped;
|
||||
int y,y_flipped;
|
||||
int src2;
|
||||
const UINT8 *spritedata = &spriteram[spritenum * 0x10];
|
||||
UINT16 srcaddr = spritedata[6] + (spritedata[7] << 8);
|
||||
UINT16 stride = spritedata[4] + (spritedata[5] << 8);
|
||||
UINT8 bank = ((spritedata[3] & 0x80) >> 7) | ((spritedata[3] & 0x40) >> 5) | ((spritedata[3] & 0x20) >> 3);
|
||||
int xstart = ((spritedata[2] + (spritedata[3] << 8)) & 0x1ff) / 2 + xoffset;
|
||||
int bottom = spritedata[1] + 1;
|
||||
int top = spritedata[0] + 1;
|
||||
UINT16 palettebase = spritenum * 0x10;
|
||||
const UINT8 *gfxbankbase;
|
||||
int x, y;
|
||||
|
||||
/* writing an 0xff into the first byte of sprite RAM seems to disable all sprites;
|
||||
not sure if this applies to each sprite or only to the first one; see pitfall2
|
||||
and wmatch for examples where this is done */
|
||||
if (spritedata[0] == 0xff)
|
||||
return;
|
||||
|
||||
src = src2 = src + skip;
|
||||
|
||||
x = sprite_base[SPR_X_LO] + ((sprite_base[SPR_X_HI] & 0x01) << 8) + system1_sprite_xoffset;
|
||||
x_flipped = x;
|
||||
y = y_flipped = sy+row;
|
||||
/* clamp the bank to the size of the sprite ROMs */
|
||||
bank %= gfxbanks;
|
||||
gfxbankbase = gfxbase + bank * 0x8000;
|
||||
|
||||
/* flip sprites vertically */
|
||||
if (flipscreen)
|
||||
{
|
||||
y_flipped = 258 - sy - height + row;
|
||||
x_flipped = (252*2) - x;
|
||||
int temp = top;
|
||||
top = 256 - bottom;
|
||||
bottom = 256 - temp;
|
||||
}
|
||||
|
||||
x /= 2; /* the hardware has sub-pixel placement, it seems */
|
||||
x_flipped /= 2;
|
||||
|
||||
while (1)
|
||||
/* iterate over all rows of the sprite */
|
||||
for (y = top; y < bottom; y++)
|
||||
{
|
||||
int color1,color2,data;
|
||||
|
||||
data = gfx[src2 & 0x7fff];
|
||||
|
||||
if (src & 0x8000)
|
||||
UINT16 *destbase = BITMAP_ADDR16(bitmap, y, 0);
|
||||
UINT16 curaddr;
|
||||
int addrdelta;
|
||||
|
||||
/* advance by the row counter */
|
||||
srcaddr += stride;
|
||||
|
||||
/* skip if outside of our clipping area */
|
||||
if (y < cliprect->min_y || y > cliprect->max_y)
|
||||
continue;
|
||||
|
||||
/* iterate over X */
|
||||
addrdelta = (srcaddr & 0x8000) ? -1 : 1;
|
||||
for (x = xstart, curaddr = srcaddr; ; x += 2, curaddr += addrdelta)
|
||||
{
|
||||
src2--;
|
||||
|
||||
color1 = data & 0x0f;
|
||||
color2 = data >> 4;
|
||||
UINT8 color1, color2;
|
||||
UINT8 data;
|
||||
|
||||
data = gfxbankbase[curaddr & 0x7fff];
|
||||
|
||||
/* non-flipped case */
|
||||
if (!(curaddr & 0x8000))
|
||||
{
|
||||
color1 = data >> 4;
|
||||
color2 = data & 0x0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
color1 = data & 0x0f;
|
||||
color2 = data >> 4;
|
||||
}
|
||||
|
||||
/* stop when we see color 0x0f */
|
||||
if (color1 == 0x0f)
|
||||
break;
|
||||
|
||||
/* draw if non-transparent */
|
||||
if (color1 != 0)
|
||||
{
|
||||
int effx = flipscreen ? 255 - (x + 0) : (x + 0);
|
||||
if (effx >= cliprect->min_x && effx <= cliprect->max_x)
|
||||
{
|
||||
int prevpix = destbase[effx];
|
||||
|
||||
if ((prevpix & 0x0f) != 0)
|
||||
sprite_collide[((prevpix >> 4) & 0x1f) + 32 * spritenum] = sprite_collide_summary = 1;
|
||||
destbase[effx] = color1 | palettebase;
|
||||
}
|
||||
}
|
||||
|
||||
/* stop when we see color 0x0f */
|
||||
if (color2 == 0x0f)
|
||||
break;
|
||||
|
||||
/* draw if non-transparent */
|
||||
if (color2 != 0)
|
||||
{
|
||||
int effx = flipscreen ? 255 - (x + 1) : (x + 1);
|
||||
if (effx >= cliprect->min_x && effx <= cliprect->max_x)
|
||||
{
|
||||
int prevpix = destbase[effx];
|
||||
|
||||
if ((prevpix & 0x0f) != 0)
|
||||
sprite_collide[((prevpix >> 4) & 0x1f) + 32 * spritenum] = sprite_collide_summary = 1;
|
||||
destbase[effx] = color2 | palettebase;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
src2++;
|
||||
|
||||
color1 = data >> 4;
|
||||
color2 = data & 0x0f;
|
||||
}
|
||||
|
||||
if (color1 == 15) break;
|
||||
if (color1 != 0 && x_flipped >= cliprect->min_x && x_flipped <= cliprect->max_x && y_flipped >= cliprect->min_y && y_flipped <= cliprect->max_y)
|
||||
draw_sprite_pixel(bitmap,x_flipped,y_flipped,spr_number,sprite_palette_base+color1);
|
||||
x++;
|
||||
x_flipped += flipscreen ? -1 : 1;
|
||||
|
||||
if (color2 == 15) break;
|
||||
if (color2 != 0 && x_flipped >= cliprect->min_x && x_flipped <= cliprect->max_x && y_flipped >= cliprect->min_y && y_flipped <= cliprect->max_y)
|
||||
draw_sprite_pixel(bitmap,x_flipped,y_flipped,spr_number,sprite_palette_base+color2);
|
||||
x++;
|
||||
x_flipped += flipscreen ? -1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect)
|
||||
{
|
||||
int spr_number,sprite_bottom_y,sprite_top_y;
|
||||
UINT8 *sprite_base;
|
||||
|
||||
for (spr_number = 0;spr_number < 32;spr_number++)
|
||||
{
|
||||
sprite_base = spriteram + 0x10 * spr_number;
|
||||
sprite_top_y = sprite_base[SPR_Y_TOP];
|
||||
sprite_bottom_y = sprite_base[SPR_Y_BOTTOM];
|
||||
if (sprite_bottom_y && (sprite_bottom_y-sprite_top_y > 0))
|
||||
draw_sprite(machine, bitmap, cliprect, spr_number);
|
||||
}
|
||||
}
|
||||
/*************************************
|
||||
*
|
||||
* Generic update code
|
||||
*
|
||||
*************************************/
|
||||
|
||||
|
||||
static void video_update_common(const device_config *screen, bitmap_t *bitmap, const rectangle *cliprect, bitmap_t *fgpixmap, bitmap_t **bgpixmaps, const int *bgrowscroll, int bgyscroll)
|
||||
static void video_update_common(const device_config *screen, bitmap_t *bitmap, const rectangle *cliprect, bitmap_t *fgpixmap, bitmap_t **bgpixmaps, const int *bgrowscroll, int bgyscroll, int spritexoffs)
|
||||
{
|
||||
const UINT8 *lookup = memory_region(screen->machine, "proms");
|
||||
int x, y;
|
||||
|
||||
/* first clear the sprite bitmap and draw sprites within this area */
|
||||
bitmap_fill(sprite_bitmap, cliprect, 0);
|
||||
draw_sprites(screen->machine, sprite_bitmap, cliprect);
|
||||
|
||||
draw_sprites(screen->machine, sprite_bitmap, cliprect, spritexoffs);
|
||||
|
||||
/* iterate over rows */
|
||||
for (y = cliprect->min_y; y <= cliprect->max_y; y++)
|
||||
{
|
||||
@ -420,7 +489,7 @@ static void video_update_common(const device_config *screen, bitmap_t *bitmap, c
|
||||
int bgy = (y + bgyscroll) & 0x1ff;
|
||||
int bgxscroll = bgrowscroll[y / 8];
|
||||
UINT16 *bgbase[2];
|
||||
|
||||
|
||||
/* get the base of the left and right pixmaps for the effective background Y */
|
||||
bgbase[0] = BITMAP_ADDR16(bgpixmaps[(bgy >> 8) * 2 + 0], bgy & 0xff, 0);
|
||||
bgbase[1] = BITMAP_ADDR16(bgpixmaps[(bgy >> 8) * 2 + 1], bgy & 0xff, 0);
|
||||
@ -445,7 +514,7 @@ static void video_update_common(const device_config *screen, bitmap_t *bitmap, c
|
||||
|
||||
/* compute collisions based on two of the PROM bits */
|
||||
if (!(lookup_value & 4))
|
||||
mix_collide[((lookup_value & 8) << 2) | (sprpix >> 11)] = mix_collide_summary = 1;
|
||||
mix_collide[((lookup_value & 8) << 2) | ((sprpix >> 4) & 0x1f)] = mix_collide_summary = 1;
|
||||
|
||||
/* the lower 2 PROM bits select the palette and which pixels */
|
||||
lookup_value &= 3;
|
||||
@ -462,40 +531,84 @@ static void video_update_common(const device_config *screen, bitmap_t *bitmap, c
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Board-specific update front-ends
|
||||
*
|
||||
*************************************/
|
||||
|
||||
VIDEO_UPDATE( system1 )
|
||||
{
|
||||
bitmap_t *bgpixmaps[4], *fgpixmap;
|
||||
int bgrowscroll[32];
|
||||
int xscroll, yscroll;
|
||||
int y;
|
||||
|
||||
/* all 4 background pages are the same, fixed to page 0 */
|
||||
bgpixmaps[0] = bgpixmaps[1] = bgpixmaps[2] = bgpixmaps[3] = tilemap_get_pixmap(tilemap_page[0]);
|
||||
|
||||
/* foreground is fixed to page 1 */
|
||||
fgpixmap = tilemap_get_pixmap(tilemap_page[1]);
|
||||
|
||||
/* get fixed scroll offsets */
|
||||
xscroll = (videoram[0xffc] | (videoram[0xffd] << 8)) / 2 + 14;
|
||||
yscroll = videoram[0xfbd];
|
||||
|
||||
/* adjust for flipping */
|
||||
if (flip_screen_get(screen->machine))
|
||||
{
|
||||
xscroll = 279 - xscroll;
|
||||
yscroll = 256 - yscroll;
|
||||
}
|
||||
|
||||
/* fill in the row scroll table */
|
||||
for (y = 0; y < 32; y++)
|
||||
bgrowscroll[y] = (videoram[0xffc] | (videoram[0xffd] << 8)) / 2 + 14;
|
||||
bgrowscroll[y] = xscroll;
|
||||
|
||||
video_update_common(screen, bitmap, cliprect, fgpixmap, bgpixmaps, bgrowscroll, videoram[0xfbd]);
|
||||
/* common update */
|
||||
video_update_common(screen, bitmap, cliprect, fgpixmap, bgpixmaps, bgrowscroll, yscroll, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
VIDEO_UPDATE( system2 )
|
||||
{
|
||||
int flip = flip_screen_get(screen->machine);
|
||||
int xscrolloffs = flip ? 0x7f6 : 0x7c0;
|
||||
int yscrolloffs = flip ? 0x784 : 0x7ba;
|
||||
bitmap_t *bgpixmaps[4], *fgpixmap;
|
||||
int rowscroll[32];
|
||||
int xscroll, yscroll;
|
||||
int sprxoffset;
|
||||
int y;
|
||||
|
||||
/* 4 independent background pages */
|
||||
bgpixmaps[0] = tilemap_get_pixmap(tilemap_page[videoram[0x740] & 7]);
|
||||
bgpixmaps[1] = tilemap_get_pixmap(tilemap_page[videoram[0x742] & 7]);
|
||||
bgpixmaps[2] = tilemap_get_pixmap(tilemap_page[videoram[0x744] & 7]);
|
||||
bgpixmaps[3] = tilemap_get_pixmap(tilemap_page[videoram[0x746] & 7]);
|
||||
fgpixmap = tilemap_get_pixmap(tilemap_page[0]);
|
||||
for (y = 0; y < 32; y++)
|
||||
rowscroll[y] = (((videoram[xscrolloffs + 0] | (videoram[xscrolloffs + 1] << 8)) / 2) & 0xff) - 256 + 5;
|
||||
|
||||
video_update_common(screen, bitmap, cliprect, fgpixmap, bgpixmaps, rowscroll, videoram[yscrolloffs]);
|
||||
/* foreground is fixed to page 0 */
|
||||
fgpixmap = tilemap_get_pixmap(tilemap_page[0]);
|
||||
|
||||
/* get scroll offsets */
|
||||
if (!flip_screen_get(screen->machine))
|
||||
{
|
||||
xscroll = (((videoram[0x7c0] | (videoram[0x7c1] << 8)) / 2) & 0xff) - 256 + 5;
|
||||
yscroll = videoram[0x7ba];
|
||||
sprxoffset = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
xscroll = 262+256 - ((((videoram[0x7f6] | (videoram[0x7f7] << 8)) / 2) & 0xff) - 256 + 5);
|
||||
yscroll = 256+256 - videoram[0x784];
|
||||
sprxoffset = -7;
|
||||
}
|
||||
|
||||
/* fill in the row scroll table */
|
||||
for (y = 0; y < 32; y++)
|
||||
rowscroll[y] = xscroll;
|
||||
|
||||
/* common update */
|
||||
video_update_common(screen, bitmap, cliprect, fgpixmap, bgpixmaps, rowscroll, yscroll, sprxoffset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -504,16 +617,33 @@ VIDEO_UPDATE( system2_rowscroll )
|
||||
{
|
||||
bitmap_t *bgpixmaps[4], *fgpixmap;
|
||||
int rowscroll[32];
|
||||
int yscroll;
|
||||
int y;
|
||||
|
||||
/* 4 independent background pages */
|
||||
bgpixmaps[0] = tilemap_get_pixmap(tilemap_page[videoram[0x740] & 7]);
|
||||
bgpixmaps[1] = tilemap_get_pixmap(tilemap_page[videoram[0x742] & 7]);
|
||||
bgpixmaps[2] = tilemap_get_pixmap(tilemap_page[videoram[0x744] & 7]);
|
||||
bgpixmaps[3] = tilemap_get_pixmap(tilemap_page[videoram[0x746] & 7]);
|
||||
fgpixmap = tilemap_get_pixmap(tilemap_page[0]);
|
||||
for (y = 0; y < 32; y++)
|
||||
rowscroll[y] = (((videoram[0x7c0 + y * 2] | (videoram[0x7c1 + y * 2] << 8)) / 2) & 0xff) - 256 + 5;
|
||||
|
||||
video_update_common(screen, bitmap, cliprect, fgpixmap, bgpixmaps, rowscroll, videoram[0x7ba]);
|
||||
/* foreground is fixed to page 0 */
|
||||
fgpixmap = tilemap_get_pixmap(tilemap_page[0]);
|
||||
|
||||
/* get scroll offsets */
|
||||
if (!flip_screen_get(screen->machine))
|
||||
{
|
||||
for (y = 0; y < 32; y++)
|
||||
rowscroll[y] = (((videoram[0x7c0 + y * 2] | (videoram[0x7c1 + y * 2] << 8)) / 2) & 0xff) - 256 + 5;
|
||||
yscroll = videoram[0x7ba];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < 32; y++)
|
||||
rowscroll[y] = 262+256 - ((((videoram[0x7fe - y * 2] | (videoram[0x7ff - y * 2] << 8)) / 2) & 0xff) - 256 + 5);
|
||||
yscroll = 256+256 - videoram[0x784];
|
||||
}
|
||||
|
||||
/* common update */
|
||||
video_update_common(screen, bitmap, cliprect, fgpixmap, bgpixmaps, rowscroll, yscroll, 7);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,15 +1,6 @@
|
||||
#ifndef _system1_H_
|
||||
#define _system1_H_
|
||||
|
||||
#define SPR_Y_TOP 0
|
||||
#define SPR_Y_BOTTOM 1
|
||||
#define SPR_X_LO 2
|
||||
#define SPR_X_HI 3
|
||||
#define SPR_SKIP_LO 4
|
||||
#define SPR_SKIP_HI 5
|
||||
#define SPR_GFXOFS_LO 6
|
||||
#define SPR_GFXOFS_HI 7
|
||||
|
||||
|
||||
VIDEO_START( system1 );
|
||||
VIDEO_START( system2 );
|
||||
|
Loading…
Reference in New Issue
Block a user