diff --git a/src/mame/drivers/ddragon.c b/src/mame/drivers/ddragon.c index 575d5b3038f..3e9b62bb6da 100644 --- a/src/mame/drivers/ddragon.c +++ b/src/mame/drivers/ddragon.c @@ -81,7 +81,8 @@ Dip locations verified with manual for ddragon & ddragon2 #define MAIN_CLOCK XTAL_12MHz #define SOUND_CLOCK XTAL_3_579545MHz -#define MCU_CLOCK XTAL_4MHz +#define MCU_CLOCK MAIN_CLOCK / 3 +#define PIXEL_CLOCK MAIN_CLOCK / 2 /* from video */ @@ -97,8 +98,6 @@ extern UINT8 *ddragon_spriteram; extern UINT8 technos_video_hw; /* end of extern code & data */ -static emu_timer *scanline_timer; - /* private globals */ static UINT8 dd_sub_cpu_busy; static UINT8 sprite_irq, sound_irq, ym_irq; @@ -141,30 +140,24 @@ INLINE int scanline_to_vcount(int scanline) return (vcount - 0x18) | 0x100; } - -static TIMER_CALLBACK( ddragon_scanline_callback ) +static TIMER_DEVICE_CALLBACK( ddragon_scanline ) { int scanline = param; - int screen_height = video_screen_get_height(machine->primary_screen); + int screen_height = video_screen_get_height(timer->machine->primary_screen); int vcount_old = scanline_to_vcount((scanline == 0) ? screen_height - 1 : scanline - 1); int vcount = scanline_to_vcount(scanline); /* update to the current point */ if (scanline > 0) - video_screen_update_partial(machine->primary_screen, scanline - 1); + video_screen_update_partial(timer->machine->primary_screen, scanline - 1); /* on the rising edge of VBLK (vcount == F8), signal an NMI */ if (vcount == 0xf8) - cpu_set_input_line(machine->cpu[0], INPUT_LINE_NMI, ASSERT_LINE); + cpu_set_input_line(timer->machine->cpu[0], INPUT_LINE_NMI, ASSERT_LINE); /* set 1ms signal on rising edge of vcount & 8 */ if (!(vcount_old & 8) && (vcount & 8)) - cpu_set_input_line(machine->cpu[0], M6809_FIRQ_LINE, ASSERT_LINE); - - /* adjust for next scanline */ - if (++scanline >= screen_height) - scanline = 0; - timer_adjust_oneshot(scanline_timer, video_screen_get_time_until_pos(machine->primary_screen, scanline, 0), scanline); + cpu_set_input_line(timer->machine->cpu[0], M6809_FIRQ_LINE, ASSERT_LINE); } @@ -180,9 +173,6 @@ static MACHINE_START( ddragon ) /* configure banks */ memory_configure_bank(machine, 1, 0, 8, memory_region(machine, "main") + 0x10000, 0x4000); - /* allocate timer for scanlines */ - scanline_timer = timer_alloc(machine, ddragon_scanline_callback, NULL); - /* determine the sound CPU index */ snd_cpu = cputag_get_cpu(machine, "sound"); @@ -201,7 +191,6 @@ static MACHINE_RESET( ddragon ) adpcm_end[0] = adpcm_end[1] = 0; adpcm_idle[0] = adpcm_idle[1] = 1; adpcm_data[0] = adpcm_data[1] = -1; - timer_adjust_oneshot(scanline_timer, video_screen_get_time_until_pos(machine->primary_screen, 0, 0), 0); } @@ -978,16 +967,17 @@ static const msm5205_interface msm5205_config = static MACHINE_DRIVER_START( ddragon ) /* basic machine hardware */ - MDRV_CPU_ADD("main", HD6309, MAIN_CLOCK) /* 12MHz / 4 internally */ + MDRV_CPU_ADD("main", HD6309, MAIN_CLOCK) /* 12 MHz / 4 internally */ MDRV_CPU_PROGRAM_MAP(ddragon_map,0) + MDRV_TIMER_ADD_SCANLINE("scantimer", ddragon_scanline, "main", 0, 1) - MDRV_CPU_ADD("sub", HD63701, MAIN_CLOCK/2) /* 6Mhz / 4 internally */ + MDRV_CPU_ADD("sub", HD63701, MAIN_CLOCK / 2) /* 6 MHz / 4 internally */ MDRV_CPU_PROGRAM_MAP(sub_map,0) - MDRV_CPU_ADD("sound", M6809, MAIN_CLOCK/2) /* 6MHz / 4 internally */ + MDRV_CPU_ADD("sound", M6809, MAIN_CLOCK / 8) /* 1.5 MHz */ MDRV_CPU_PROGRAM_MAP(sound_map,0) - MDRV_QUANTUM_TIME(HZ(60000)) /* heavy interleaving to sync up sprite<->main cpu's */ + MDRV_QUANTUM_TIME(HZ(60000)) /* heavy interleaving to sync up sprite<->main cpu's */ MDRV_MACHINE_START(ddragon) MDRV_MACHINE_RESET(ddragon) @@ -998,7 +988,7 @@ static MACHINE_DRIVER_START( ddragon ) MDRV_SCREEN_ADD("main", RASTER) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_RAW_PARAMS(MAIN_CLOCK/2, 384, 0, 256, 272, 0, 240) + MDRV_SCREEN_RAW_PARAMS(PIXEL_CLOCK, 384, 0, 256, 272, 0, 240) MDRV_VIDEO_START(ddragon) MDRV_VIDEO_UPDATE(ddragon) @@ -1025,7 +1015,7 @@ static MACHINE_DRIVER_START( ddragonb ) MDRV_IMPORT_FROM(ddragon) /* basic machine hardware */ - MDRV_CPU_REPLACE("sub", M6809, MAIN_CLOCK/2) /* 6Mhz / 4 internally */ + MDRV_CPU_REPLACE("sub", M6809, MAIN_CLOCK / 8) /* 1.5Mhz */ MDRV_CPU_PROGRAM_MAP(sub_map,0) MACHINE_DRIVER_END @@ -1034,7 +1024,7 @@ static MACHINE_DRIVER_START( ddragnba ) MDRV_IMPORT_FROM(ddragon) /* basic machine hardware */ - MDRV_CPU_REPLACE("sub", M6803, MAIN_CLOCK/2) /* 6Mhz / 4 internally */ + MDRV_CPU_REPLACE("sub", M6803, MAIN_CLOCK / 2) /* 6Mhz / 4 internally */ MDRV_CPU_PROGRAM_MAP(ddragnba_sub_map,0) MDRV_CPU_IO_MAP(ddragnba_sub_portmap,0) MACHINE_DRIVER_END @@ -1043,13 +1033,14 @@ MACHINE_DRIVER_END static MACHINE_DRIVER_START( ddgn6809 ) /* basic machine hardware */ - MDRV_CPU_ADD("main", M6809, MAIN_CLOCK) /* 12MHz / 4 internally */ + MDRV_CPU_ADD("main", M6809, MAIN_CLOCK / 8) /* 1.5 MHz */ MDRV_CPU_PROGRAM_MAP(ddragon_map,0) + MDRV_TIMER_ADD_SCANLINE("scantimer", ddragon_scanline, "main", 0, 1) - MDRV_CPU_ADD("sub", M6809, MAIN_CLOCK/2) /* 6Mhz / 4 internally */ + MDRV_CPU_ADD("sub", M6809, MAIN_CLOCK / 8) /* 1.5 Mhz */ MDRV_CPU_PROGRAM_MAP(sub_map,0) - MDRV_CPU_ADD("sound", M6809, MAIN_CLOCK/2) /* 6MHz / 4 internally */ + MDRV_CPU_ADD("sound", M6809, MAIN_CLOCK / 8) /* 1.5 MHz */ MDRV_CPU_PROGRAM_MAP(sound_map,0) MDRV_QUANTUM_TIME(HZ(60000)) /* heavy interleaving to sync up sprite<->main cpu's */ @@ -1063,7 +1054,7 @@ static MACHINE_DRIVER_START( ddgn6809 ) MDRV_SCREEN_ADD("main", RASTER) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_RAW_PARAMS(MAIN_CLOCK/2, 384, 0, 256, 272, 0, 240) + MDRV_SCREEN_RAW_PARAMS(PIXEL_CLOCK, 384, 0, 256, 272, 0, 240) MDRV_VIDEO_START(ddragon) MDRV_VIDEO_UPDATE(ddragon) @@ -1089,10 +1080,11 @@ MACHINE_DRIVER_END static MACHINE_DRIVER_START( ddragon2 ) /* basic machine hardware */ - MDRV_CPU_ADD("main", HD6309, MAIN_CLOCK) /* 12MHz / 4 internally */ + MDRV_CPU_ADD("main", HD6309, MAIN_CLOCK) /* 12 MHz / 4 internally */ MDRV_CPU_PROGRAM_MAP(dd2_map,0) + MDRV_TIMER_ADD_SCANLINE("scantimer", ddragon_scanline, "main", 0, 1) - MDRV_CPU_ADD("sub", Z80, MAIN_CLOCK / 3) /* 4 MHz */ + MDRV_CPU_ADD("sub", Z80, MAIN_CLOCK / 3) /* 4 MHz */ MDRV_CPU_PROGRAM_MAP(dd2_sub_map,0) MDRV_CPU_ADD("sound", Z80, 3579545) @@ -1109,7 +1101,7 @@ static MACHINE_DRIVER_START( ddragon2 ) MDRV_SCREEN_ADD("main", RASTER) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_RAW_PARAMS(MAIN_CLOCK/2, 384, 0, 256, 272, 0, 240) + MDRV_SCREEN_RAW_PARAMS(PIXEL_CLOCK, 384, 0, 256, 272, 0, 240) MDRV_VIDEO_START(ddragon) MDRV_VIDEO_UPDATE(ddragon) @@ -2005,9 +1997,6 @@ GAME( 1987, ddragonb, ddragon, ddragonb, ddragon, ddragon, ROT0, "bootleg", " GAME( 1987, ddragnba, ddragon, ddragnba, ddragon, ddragon, ROT0, "bootleg", "Double Dragon (bootleg with M6803)", GAME_SUPPORTS_SAVE ) GAME( 1987, ddgn6809, ddragon, ddgn6809, ddragon, ddgn6809, ROT0, "bootleg", "Double Dragon (bootleg with 3xM6809, set 1)", GAME_NOT_WORKING ) GAME( 1987, dd6809a, ddragon, ddgn6809, ddragon, ddgn6809, ROT0, "bootleg", "Double Dragon (bootleg with 3xM6809, set 2)", GAME_NOT_WORKING ) - - - GAME( 1988, ddragon2, 0, ddragon2, ddragon2, ddragon2, ROT0, "Technos", "Double Dragon II - The Revenge (World)", GAME_SUPPORTS_SAVE ) GAME( 1988, ddragn2u, ddragon2, ddragon2, ddragon2, ddragon2, ROT0, "Technos", "Double Dragon II - The Revenge (US)", GAME_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/ddragon3.c b/src/mame/drivers/ddragon3.c index 480b6eebbad..4a170572319 100644 --- a/src/mame/drivers/ddragon3.c +++ b/src/mame/drivers/ddragon3.c @@ -602,12 +602,6 @@ static TIMER_DEVICE_CALLBACK( ddragon3_scanline ) video_screen_update_partial(timer->machine->primary_screen, scanline - 1); cpu_set_input_line(timer->machine->cpu[0], 6, ASSERT_LINE); } - - /* Adjust for next scanline */ - if (++scanline >= video_screen_get_height(timer->machine->primary_screen)) - { - scanline = 0; - } } /************************************* diff --git a/src/mame/drivers/gstream.c b/src/mame/drivers/gstream.c index 76f06472cd8..4237eac8906 100644 --- a/src/mame/drivers/gstream.c +++ b/src/mame/drivers/gstream.c @@ -200,36 +200,71 @@ static READ32_HANDLER( gstream_oki_1_r ) { return okim6295_status_1_r(space, 0); static WRITE32_HANDLER( gstream_oki_0_w ) { okim6295_data_0_w(space, 0, data & 0xff); } static WRITE32_HANDLER( gstream_oki_1_w ) { okim6295_data_1_w(space, 0, data & 0xff); } -static WRITE32_HANDLER( gstream_oki_4030_w ) +static WRITE32_HANDLER( gstream_oki_banking_w ) { -/* - // the only nibbles that are written are: 0x6 0x7 0x9 0xa 0xb 0xe 0xd 0xf which should map to the 8 oki banks + /* OKI BANKING (still far from perfect, based on game behaviour) - static const int bank_lookup[16] = { -1, -1, -1, -1, -1, -1, 0, 1, -1, 2, 3, 4, -1, 5, 6, 7 }; + The two okis can indifferently play music or samples and are switched on the fly during game + This is a preliminary table of the banks: - static int old_bank_0 = -1; - static int old_bank_1 = -1; + BANK MUSIC SAMPLES + 0 X + 1 X + 2 X + 3 X + 4 X + 5 X + 6 X + 7 X - if(bank_lookup[data & 0xf] != old_bank_0) - { - old_bank_0 = bank_lookup[data & 0xf]; + Two nibbles are used in this handler: (data & 0xf) and ((data >> 4) & 0xf) + The values for the first nibble are the followings and should map the 8 oki banks: + - 0x6, 0x7, 0x9, 0xa, 0xb, 0xd, 0xe, 0xf + The values for the second nibble are the followings and should probably be used too: + - 0x6, 0x9, 0xa - if(old_bank_0 != -1) - okim6295_set_bank_base(0, old_bank_0 * 0x40000); - else - logerror("oki_0 banking value = %X\n",data & 0xf); - } + Same values are redudant, for example: + level 2: data = 0x99 + level 6: data = 0x99 + (this means same background music for the two levels - it could be correct, though) - if(bank_lookup[(data >> 4) & 0xf] != old_bank_1) - { - old_bank_1 = bank_lookup[(data >> 4) & 0xf]; + Also with current implementation, using only (data & 0xf), we have to force some values + manually, because the correspondent places in the table are already used - if(old_bank_1 != -1) - okim6295_set_bank_base(1, old_bank_1 * 0x40000); - else - logerror("oki_1 banking value = %X\n",(data >> 4) & 0xf); - } -*/ + Musics order is completely guessed but close to what the original PCB game should be */ + + static const int bank_table_0[16] = { -1, -1, -1, -1, -1, -1, 0, 0, -1, 6, 0, 5, -1, 0, 0, 0 }; + static const int bank_table_1[16] = { -1, -1, -1, -1, -1, -1, 2, 2, -1, 0, 0, 4, -1, 1, 1, 1 }; + + static int bank_0 = 0; + static int bank_1 = 0; + + //popmessage("oki_0 banking value = %X\noki_1 banking value = %X\n",data & 0xf,(data >> 4) & 0xf); + + bank_0 = bank_table_0[data & 0xf]; + bank_1 = bank_table_1[data & 0xf]; // (data >> 4) & 0xf ?? + + /* some values are already used in the table, so we force them manually */ + if ((data == 0x6f) || (data == 0x6e)) + { + bank_0 = 0; // level 3b-5a samples + bank_1 = 6; // level 3b-5a music + } + + if (data == 0x9b) + { + bank_0 = 7; // level 7 music + bank_1 = 0; // level 7 samples + } + + if (data == 0x9f) + { + bank_0 = 0; // end sequence samples + bank_1 = 3; // end sequence music + } + + okim6295_set_bank_base(0, bank_0 * 0x40000); + okim6295_set_bank_base(1, bank_1 * 0x40000); } static WRITE32_HANDLER( gstream_oki_4040_w ) @@ -240,11 +275,11 @@ static WRITE32_HANDLER( gstream_oki_4040_w ) static ADDRESS_MAP_START( gstream_io, ADDRESS_SPACE_IO, 32 ) AM_RANGE(0x4000, 0x4003) AM_READ_PORT("IN0") AM_RANGE(0x4010, 0x4013) AM_READ_PORT("IN1") - AM_RANGE(0x4020, 0x4023) AM_READ_PORT("IN2") // extra coin switches etc - AM_RANGE(0x4030, 0x4033) AM_WRITE(gstream_oki_4030_w) // ?? - AM_RANGE(0x4040, 0x4043) AM_WRITE(gstream_oki_4040_w) // ?? - AM_RANGE(0x4050, 0x4053) AM_READWRITE(gstream_oki_1_r, gstream_oki_1_w) // music - AM_RANGE(0x4060, 0x4063) AM_READWRITE(gstream_oki_0_r, gstream_oki_0_w) // samples + AM_RANGE(0x4020, 0x4023) AM_READ_PORT("IN2") // extra coin switches etc + AM_RANGE(0x4030, 0x4033) AM_WRITE(gstream_oki_banking_w) // oki banking + AM_RANGE(0x4040, 0x4043) AM_WRITE(gstream_oki_4040_w) // ?? + AM_RANGE(0x4050, 0x4053) AM_READWRITE(gstream_oki_1_r, gstream_oki_1_w) // music and samples + AM_RANGE(0x4060, 0x4063) AM_READWRITE(gstream_oki_0_r, gstream_oki_0_w) // music and samples ADDRESS_MAP_END static INPUT_PORTS_START( gstream ) @@ -434,12 +469,12 @@ static MACHINE_DRIVER_START( gstream ) MDRV_SPEAKER_STANDARD_MONO("mono") MDRV_SOUND_ADD("oki1", OKIM6295, 1000000) /* 1 Mhz? */ - MDRV_SOUND_CONFIG(okim6295_interface_pin7low) // pin 7 not verified - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) + MDRV_SOUND_CONFIG(okim6295_interface_pin7high) // pin 7 not verified + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) MDRV_SOUND_ADD("oki2", OKIM6295, 1000000) /* 1 Mhz? */ - MDRV_SOUND_CONFIG(okim6295_interface_pin7low) // pin 7 not verified - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) + MDRV_SOUND_CONFIG(okim6295_interface_pin7high) // pin 7 not verified + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) MACHINE_DRIVER_END ROM_START( gstream ) @@ -481,7 +516,7 @@ static READ32_HANDLER( gstream_speedup_r ) { if (cpu_get_pc(space->cpu)==0xc0001592) { - cpu_eat_cycles(space->cpu, 50); + cpu_spinuntil_int(space->cpu); } return gstream_workram[0xd1ee0/4]; @@ -492,4 +527,5 @@ static DRIVER_INIT( gstream ) memory_install_read32_handler(cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_PROGRAM), 0xd1ee0, 0xd1ee3, 0, 0, gstream_speedup_r ); } + GAME( 2002, gstream, 0, gstream, gstream, gstream, ROT270, "Oriental Soft Japan", "G-Stream G2020", GAME_IMPERFECT_SOUND ) diff --git a/src/mame/drivers/shadfrce.c b/src/mame/drivers/shadfrce.c index d0a9a36d835..48a8d515582 100644 --- a/src/mame/drivers/shadfrce.c +++ b/src/mame/drivers/shadfrce.c @@ -311,12 +311,6 @@ static TIMER_DEVICE_CALLBACK( shadfrce_scanline ) cpu_set_input_line(timer->machine->cpu[0], 3, ASSERT_LINE); } } - - /* Adjust for next scanline */ - if (++scanline >= video_screen_get_height(timer->machine->primary_screen)) - { - scanline = 0; - } } diff --git a/src/mame/drivers/vball.c b/src/mame/drivers/vball.c index e3d11f9b5dc..ae8e41294db 100644 --- a/src/mame/drivers/vball.c +++ b/src/mame/drivers/vball.c @@ -95,6 +95,61 @@ VBlank = 58Hz #include "sound/okim6295.h" #include "includes/vball.h" +#define MAIN_CLOCK XTAL_12MHz +#define CPU_CLOCK MAIN_CLOCK / 6 +#define PIXEL_CLOCK MAIN_CLOCK / 2 + +/* Based on ddragon driver */ +INLINE int scanline_to_vcount(int scanline) +{ + int vcount = scanline + 8; + if (vcount < 0x100) + return vcount; + else + return (vcount - 0x18) | 0x100; +} + +static TIMER_DEVICE_CALLBACK( vball_scanline ) +{ + int scanline = param; + int screen_height = video_screen_get_height(timer->machine->primary_screen); + int vcount_old = scanline_to_vcount((scanline == 0) ? screen_height - 1 : scanline - 1); + int vcount = scanline_to_vcount(scanline); + + /* Update to the current point */ + if (scanline > 0) + { + video_screen_update_partial(timer->machine->primary_screen, scanline - 1); + } + + /* IRQ fires every on every 8th scanline */ + if (!(vcount_old & 8) && (vcount & 8)) + { + cpu_set_input_line(timer->machine->cpu[0], M6502_IRQ_LINE, ASSERT_LINE); + } + + /* NMI fires on scanline 248 (VBL) and is latched */ + if (vcount == 0xf8) + { + cpu_set_input_line(timer->machine->cpu[0], INPUT_LINE_NMI, ASSERT_LINE); + } + + /* Save the scroll x register value */ + if (scanline < 256) + { + scrollx[255 - scanline] = (vb_scrollx_hi + vb_scrollx_lo+4); + } +} + +static WRITE8_HANDLER( vball_irq_ack_w ) +{ + if (offset == 0) + cpu_set_input_line(space->machine->cpu[0], INPUT_LINE_NMI, CLEAR_LINE); + + else + cpu_set_input_line(space->machine->cpu[0], M6502_IRQ_LINE, CLEAR_LINE); +} + /* bit 0 = bank switch bit 1 = ? @@ -118,8 +173,6 @@ static WRITE8_HANDLER( vb_bankswitch_w ) } /* The sound system comes all but verbatim from Double Dragon */ - - static WRITE8_HANDLER( cpu_sound_command_w ) { soundlatch_w( space, offset, data ); cpu_set_input_line(space->machine->cpu[1], INPUT_LINE_NMI, PULSE_LINE ); @@ -144,6 +197,13 @@ static WRITE8_HANDLER( vb_scrollx_hi_w ) //logerror("%04x: vb_scrollx_hi = %d\n",cpu_get_previouspc(space->cpu), vb_scrollx_hi); } +static WRITE8_HANDLER(vb_scrollx_lo_w) +{ + vb_scrollx_lo = data; + //logerror("%04x: vb_scrollx_lo =%d\n",cpu_get_previouspc(space->cpu), vb_scrollx_lo); +} + + static ADDRESS_MAP_START( readmem, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x0fff) AM_READ(SMH_RAM) AM_RANGE(0x1000, 0x1000) AM_READ_PORT("P1") @@ -170,20 +230,13 @@ static ADDRESS_MAP_START( vball2pj_readmem, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x8000, 0xffff) AM_READ(SMH_ROM) ADDRESS_MAP_END -static WRITE8_HANDLER(vb_scrollx_lo_w) -{ - vb_scrollx_lo = data; - //logerror("%04x: vb_scrollx_lo =%d\n",cpu_get_previouspc(space->cpu), vb_scrollx_lo); -} - //Cheaters note: Scores are stored in ram @ 0x57-0x58 (though the space is used for other things between matches) static ADDRESS_MAP_START( writemem, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x07ff) AM_WRITE(SMH_RAM) AM_RANGE(0x0800, 0x08ff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram) AM_SIZE(&spriteram_size) AM_RANGE(0x1008, 0x1008) AM_WRITE(vb_scrollx_hi_w) AM_RANGE(0x1009, 0x1009) AM_WRITE(vb_bankswitch_w) - AM_RANGE(0x100a, 0x100a) AM_WRITE(SMH_RAM) - AM_RANGE(0x100b, 0x100b) AM_WRITE(SMH_RAM) //Counts from 0 to 7 continuously + AM_RANGE(0x100a, 0x100b) AM_WRITE(vball_irq_ack_w) /* is there a scanline counter here? */ AM_RANGE(0x100c, 0x100c) AM_WRITE(vb_scrollx_lo_w) AM_RANGE(0x100d, 0x100d) AM_WRITE(cpu_sound_command_w) AM_RANGE(0x100e, 0x100e) AM_WRITE(SMH_RAM) AM_BASE(&vb_scrolly_lo) @@ -369,6 +422,7 @@ static GFXDECODE_START( vb ) GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 128, 8 ) /* 16x16 sprites */ GFXDECODE_END + static void vball_irq_handler(running_machine *machine, int irq) { cpu_set_input_line(machine->cpu[1], 0 , irq ? ASSERT_LINE : CLEAR_LINE ); @@ -379,23 +433,22 @@ static const ym2151_interface ym2151_config = vball_irq_handler }; + static MACHINE_DRIVER_START( vball ) /* basic machine hardware */ - MDRV_CPU_ADD("main", M6502, 2000000) /* 2 MHz - measured by guru but it makes the game far far too slow ?! */ + MDRV_CPU_ADD("main", M6502, CPU_CLOCK) /* 2 MHz - measured by guru but it makes the game far far too slow ?! */ MDRV_CPU_PROGRAM_MAP(readmem,writemem) - MDRV_CPU_VBLANK_INT_HACK(vball_interrupt,32) /* ??1 IRQ every 8 visible scanlines, plus NMI for vblank?? */ + MDRV_TIMER_ADD_SCANLINE("scantimer", vball_scanline, "main", 0, 1) MDRV_CPU_ADD("audio", Z80, 3579545) /* 3.579545 MHz */ MDRV_CPU_PROGRAM_MAP(sound_readmem,sound_writemem) /* video hardware */ MDRV_SCREEN_ADD("main", RASTER) - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) MDRV_SCREEN_SIZE(32*8, 32*8) - MDRV_SCREEN_VISIBLE_AREA(1*8, 31*8-1, 1*8, 31*8-1) /* 240 x 240 */ + MDRV_SCREEN_RAW_PARAMS(PIXEL_CLOCK, 384, 0, 256, 272, 8, 248) /* based on ddragon driver */ MDRV_GFXDECODE(vb) MDRV_PALETTE_LENGTH(256) @@ -418,41 +471,10 @@ static MACHINE_DRIVER_START( vball ) MACHINE_DRIVER_END static MACHINE_DRIVER_START( vball2pj ) + MDRV_IMPORT_FROM(vball) - /* basic machine hardware */ - MDRV_CPU_ADD("main", M6502, 2000000) /* 2.0 MHz */ + MDRV_CPU_MODIFY("main") MDRV_CPU_PROGRAM_MAP(vball2pj_readmem,writemem) - MDRV_CPU_VBLANK_INT_HACK(vball_interrupt,32) /* ??1 IRQ every 8 visible scanlines, plus NMI for vblank?? */ - - MDRV_CPU_ADD("audio", Z80, 3579545) /* 3.579545 MHz */ - MDRV_CPU_PROGRAM_MAP(sound_readmem,sound_writemem) - - /* video hardware */ - MDRV_SCREEN_ADD("main", RASTER) - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) - MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_SIZE(32*8, 32*8) - MDRV_SCREEN_VISIBLE_AREA(1*8, 31*8-1, 1*8, 31*8-1) /* 240 x 240 */ - - MDRV_GFXDECODE(vb) - MDRV_PALETTE_LENGTH(256) - - MDRV_VIDEO_START(vb) - MDRV_VIDEO_UPDATE(vb) - - /* sound hardware */ - MDRV_SPEAKER_STANDARD_STEREO("left", "right") - - MDRV_SOUND_ADD("ym", YM2151, 3579545) - MDRV_SOUND_CONFIG(ym2151_config) - MDRV_SOUND_ROUTE(0, "left", 0.60) - MDRV_SOUND_ROUTE(1, "right", 0.60) - - MDRV_SOUND_ADD("oki", OKIM6295, 1056000) - MDRV_SOUND_CONFIG(okim6295_interface_pin7high) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 1.0) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 1.0) MACHINE_DRIVER_END diff --git a/src/mame/drivers/wwfsstar.c b/src/mame/drivers/wwfsstar.c index d09f5b4df3f..3b33260760c 100644 --- a/src/mame/drivers/wwfsstar.c +++ b/src/mame/drivers/wwfsstar.c @@ -278,12 +278,6 @@ static TIMER_DEVICE_CALLBACK( wwfsstar_scanline ) video_screen_update_partial(timer->machine->primary_screen, scanline - 1); cpu_set_input_line(timer->machine->cpu[0], 6, ASSERT_LINE); } - - /* Adjust for next scanline */ - if (++scanline >= video_screen_get_height(timer->machine->primary_screen)) - { - scanline = 0; - } } static CUSTOM_INPUT( wwfsstar_vblank_r ) diff --git a/src/mame/drivers/wwfwfest.c b/src/mame/drivers/wwfwfest.c index cb4f90b2020..67d9ee79349 100644 --- a/src/mame/drivers/wwfwfest.c +++ b/src/mame/drivers/wwfwfest.c @@ -361,12 +361,6 @@ static TIMER_DEVICE_CALLBACK( wwfwfest_scanline ) video_screen_update_partial(timer->machine->primary_screen, scanline - 1); cpu_set_input_line(timer->machine->cpu[0], 3, ASSERT_LINE); } - - /* Adjust for next scanline */ - if (++scanline >= video_screen_get_height(timer->machine->primary_screen)) - { - scanline = 0; - } } /******************************************************************************* diff --git a/src/mame/drivers/xain.c b/src/mame/drivers/xain.c index 7996701fc47..acaf517fa3d 100644 --- a/src/mame/drivers/xain.c +++ b/src/mame/drivers/xain.c @@ -147,6 +147,11 @@ TODO: #include "cpu/m6805/m6805.h" #include "sound/2203intf.h" +#define MASTER_CLOCK XTAL_12MHz +#define CPU_CLOCK MASTER_CLOCK / 8 +#define MCU_CLOCK MASTER_CLOCK / 4 +#define PIXEL_CLOCK MASTER_CLOCK / 2 + static UINT8 *xain_sharedram; static int vblank; @@ -164,6 +169,66 @@ WRITE8_HANDLER( xain_flipscreen_w ); extern UINT8 *xain_charram, *xain_bgram0, *xain_bgram1, xain_pri; +/* + Based on the Solar Warrior schematics, vertical timing counts as follows: + + 08,09,0A,0B,...,FC,FD,FE,FF,E8,E9,EA,EB,...,FC,FD,FE,FF, + 08,09,.... + + Thus, it counts from 08 to FF, then resets to E8 and counts to FF again. + This gives (256 - 8) + (256 - 232) = 248 + 24 = 272 total scanlines. + + VBLK is signalled starting when the counter hits F8, and continues through + the reset to E8 and through until the next reset to 08 again. + + Since MAME's video timing is 0-based, we need to convert this. +*/ + +INLINE int scanline_to_vcount(int scanline) +{ + int vcount = scanline + 8; + if (vcount < 0x100) + return vcount; + else + return (vcount - 0x18) | 0x100; +} + +static TIMER_DEVICE_CALLBACK( xain_scanline ) +{ + int scanline = param; + int screen_height = video_screen_get_height(timer->machine->primary_screen); + int vcount_old = scanline_to_vcount((scanline == 0) ? screen_height - 1 : scanline - 1); + int vcount = scanline_to_vcount(scanline); + + /* update to the current point */ + if (scanline > 0) + { + video_screen_update_partial(timer->machine->primary_screen, scanline - 1); + } + + /* FIRQ (IMS) fires every on every 8th scanline (except 0) */ + if (!(vcount_old & 8) && (vcount & 8)) + { + cpu_set_input_line(timer->machine->cpu[0], M6809_FIRQ_LINE, ASSERT_LINE); + } + + /* NMI fires on scanline 248 (VBL) and is latched */ + if (vcount == 0xf8) + { + cpu_set_input_line(timer->machine->cpu[0], INPUT_LINE_NMI, ASSERT_LINE); + } + + /* VBLANK input bit is held high from scanlines 248-255 */ + if (vcount >= 248-1) // -1 is a hack - see notes above + { + vblank = 1; + } + else + { + vblank = 0; + } +} + static READ8_HANDLER( xain_sharedram_r ) { return xain_sharedram[offset]; @@ -248,24 +313,6 @@ static CUSTOM_INPUT( xain_vblank_r ) return vblank; } -static INTERRUPT_GEN( xain_interrupt ) -{ - int scanline = 255 - cpu_getiloops(device); - - /* FIRQ (IMS) fires every on every 8th scanline (except 0) */ - if (scanline & 0x08) - cpu_set_input_line(device, M6809_FIRQ_LINE, ASSERT_LINE); - - /* NMI fires on scanline 248 (VBL) and is latched */ - if (scanline == 248) - cpu_set_input_line(device, INPUT_LINE_NMI, ASSERT_LINE); - - /* VBLANK input bit is held high from scanlines 248-255 */ - if (scanline >= 248-1) // -1 is a hack - see notes above - vblank = 1; - else - vblank = 0; -} static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x1fff) AM_READWRITE(xain_sharedram_r, xain_sharedram_w) AM_BASE(&xain_sharedram) @@ -293,7 +340,7 @@ static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x3c00, 0x3dff) AM_WRITE(paletteram_xxxxBBBBGGGGRRRR_split1_w) AM_BASE(&paletteram) AM_RANGE(0x3e00, 0x3fff) AM_WRITE(paletteram_xxxxBBBBGGGGRRRR_split2_w) AM_BASE(&paletteram_2) AM_RANGE(0x4000, 0x7fff) AM_READ(SMH_BANK1) - AM_RANGE(0x4000, 0xffff) AM_ROM + AM_RANGE(0x8000, 0xffff) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START( cpu_map_B, ADDRESS_SPACE_PROGRAM, 8 ) @@ -302,7 +349,7 @@ static ADDRESS_MAP_START( cpu_map_B, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x2800, 0x2800) AM_WRITE(xain_irqB_clear_w) AM_RANGE(0x3000, 0x3000) AM_WRITE(xainCPUB_bankswitch_w) AM_RANGE(0x4000, 0x7fff) AM_READ(SMH_BANK2) - AM_RANGE(0x4000, 0xffff) AM_ROM + AM_RANGE(0x8000, 0xffff) AM_ROM ADDRESS_MAP_END #if 0 @@ -322,6 +369,7 @@ static ADDRESS_MAP_START( sound_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x4000, 0xffff) AM_ROM ADDRESS_MAP_END + static INPUT_PORTS_START( xsleena ) PORT_START("P1") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY @@ -399,7 +447,6 @@ static INPUT_PORTS_START( xsleena ) INPUT_PORTS_END - static const gfx_layout charlayout = { 8,8, @@ -430,7 +477,6 @@ static GFXDECODE_START( xain ) GFXDECODE_END - /* handler called by the 2203 emulator when the internal timers cause an IRQ */ static void irqhandler(running_machine *machine, int irq) { @@ -447,30 +493,29 @@ static const ym2203_interface ym2203_config = irqhandler }; - static MACHINE_START( xsleena ) { - const address_space *space = cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_PROGRAM); + const address_space *space_main = cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_PROGRAM); + const address_space *space_sub = cpu_get_address_space(machine->cpu[1], ADDRESS_SPACE_PROGRAM); /* initialize the bank pointers */ - xainCPUA_bankswitch_w(space,0,0); - xainCPUB_bankswitch_w(space,0,0); + xainCPUA_bankswitch_w(space_main,0,0); + xainCPUB_bankswitch_w(space_sub,0,0); } - static MACHINE_DRIVER_START( xsleena ) /* basic machine hardware */ - MDRV_CPU_ADD("main", M6809, 1500000) /* Confirmed 1.5MHz */ + MDRV_CPU_ADD("main", M6809, CPU_CLOCK) /* Confirmed 1.5MHz */ MDRV_CPU_PROGRAM_MAP(main_map,0) - MDRV_CPU_VBLANK_INT_HACK(xain_interrupt,256) + MDRV_TIMER_ADD_SCANLINE("scantimer", xain_scanline, "main", 0, 1) - MDRV_CPU_ADD("sub", M6809, 1500000) /* Confirmed 1.5MHz */ + MDRV_CPU_ADD("sub", M6809, CPU_CLOCK) /* Confirmed 1.5MHz */ MDRV_CPU_PROGRAM_MAP(cpu_map_B,0) - MDRV_CPU_ADD("audio", M6809, 1500000) /* Confirmed 1.5MHz */ + MDRV_CPU_ADD("audio", M6809, CPU_CLOCK) /* Confirmed 1.5MHz */ MDRV_CPU_PROGRAM_MAP(sound_map,0) -// MDRV_CPU_ADD("mcu", M68705, 3000000) /* Confirmed 3MHz */ +// MDRV_CPU_ADD("mcu", M68705, MCU_CLOCK) /* Confirmed 3MHz */ // MDRV_CPU_PROGRAM_MAP(mcu_map,0) MDRV_MACHINE_START(xsleena) @@ -479,11 +524,8 @@ static MACHINE_DRIVER_START( xsleena ) /* video hardware */ MDRV_SCREEN_ADD("main", RASTER) - MDRV_SCREEN_REFRESH_RATE(57) - MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_SIZE(32*8, 32*8) - MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1) + MDRV_SCREEN_RAW_PARAMS(PIXEL_CLOCK, 384, 0, 256, 272, 8, 248) /* based on ddragon driver */ MDRV_GFXDECODE(xain) MDRV_PALETTE_LENGTH(512) @@ -509,7 +551,6 @@ static MACHINE_DRIVER_START( xsleena ) MACHINE_DRIVER_END - /*************************************************************************** Game driver(s) @@ -676,7 +717,6 @@ ROM_START( solarwar ) ROM_END - static DRIVER_INIT( xsleena ) { UINT8 *RAM = memory_region(machine, "main"); @@ -704,7 +744,6 @@ static DRIVER_INIT( solarwar ) } - GAME( 1986, xsleena, 0, xsleena, xsleena, xsleena, ROT0, "Technos", "Xain'd Sleena", 0 ) GAME( 1986, xsleenab, xsleena, xsleena, xsleena, 0, ROT0, "bootleg", "Xain'd Sleena (bootleg)", 0 ) GAME( 1986, solarwar, xsleena, xsleena, xsleena, solarwar, ROT0, "[Technos] Taito (Memetron license)", "Solar-Warrior", 0 ) diff --git a/src/mame/includes/vball.h b/src/mame/includes/vball.h index 1e5b8a00a0d..2edc958c08b 100644 --- a/src/mame/includes/vball.h +++ b/src/mame/includes/vball.h @@ -7,6 +7,7 @@ extern int vb_scrollx_hi; extern int vb_scrolly_hi; extern int vb_scrollx_lo; extern int vball_gfxset; +extern int scrollx[256]; VIDEO_START( vb ); VIDEO_UPDATE( vb ); @@ -15,5 +16,3 @@ void vb_spprombank_w(running_machine *machine, int bank); WRITE8_HANDLER( vb_attrib_w ); WRITE8_HANDLER( vb_videoram_w ); void vb_mark_all_dirty(void); - -INTERRUPT_GEN( vball_interrupt ); diff --git a/src/mame/video/vball.c b/src/mame/video/vball.c index a076d778ce9..285b6225f7f 100644 --- a/src/mame/video/vball.c +++ b/src/mame/video/vball.c @@ -14,6 +14,7 @@ int vb_scrollx_hi=0; int vb_scrollx_lo=0; int vb_scrolly_hi=0; +int scrollx[256]; UINT8 *vb_scrolly_lo; UINT8 *vb_videoram; @@ -23,7 +24,6 @@ static int vb_bgprombank=0xff; static int vb_spprombank=0xff; static tilemap *bg_tilemap; -static int scrollx[32]; /*************************************************************************** @@ -168,7 +168,7 @@ VIDEO_UPDATE( vb ) tilemap_set_scrolly(bg_tilemap,0,vb_scrolly_hi + *vb_scrolly_lo); /*To get linescrolling to work properly, we must ignore the 1st two scroll values, no idea why! -SJE */ - for (i = 2;i < 32;i++) { + for (i = 2; i < 256; i++) { tilemap_set_scrollx(bg_tilemap,i,scrollx[i-2]); //logerror("scrollx[%d] = %d\n",i,scrollx[i]); } @@ -176,18 +176,3 @@ VIDEO_UPDATE( vb ) draw_sprites(screen->machine,bitmap,cliprect); return 0; } - - -/*I don't really understand what the proper timing of this should be, - but after TONS of testing, the tilemap individual line scrolling works as long as flip screen is not set -SJE -*/ -INTERRUPT_GEN( vball_interrupt ) -{ - int line = 31 - cpu_getiloops(device); - if (line < 13) - cpu_set_input_line(device, M6502_IRQ_LINE, HOLD_LINE); - else if (line == 13) - cpu_set_input_line(device, INPUT_LINE_NMI, PULSE_LINE); - //save the scroll x register value - if(line<32) scrollx[31-line] = (vb_scrollx_hi + vb_scrollx_lo+4); -}