Some more debugger fixes.

Added AM_WRITEONLY as a shortcut for AM_WRITE(MWAx_RAM).

Cleaned up Kangaroo driver:
 * documented MB8841 (needs to be decapped to get code)
 * proper video timing
 * full memory maps
 * simplified and more accurate video logic
This commit is contained in:
Aaron Giles 2008-02-03 00:52:20 +00:00
parent fbe8745472
commit 2409522389
8 changed files with 330 additions and 425 deletions

View File

@ -673,6 +673,7 @@ address_map *construct_map_##_name(address_map *map) \
#define AM_READWRITE(_read,_write) AM_READ(_read) AM_WRITE(_write)
#define AM_ROM AM_READ((_rh_t)STATIC_ROM)
#define AM_RAM AM_READWRITE((_rh_t)STATIC_RAM, (_wh_t)STATIC_RAM)
#define AM_WRITEONLY AM_WRITE((_wh_t)STATIC_RAM)
#define AM_UNMAP AM_READWRITE((_rh_t)STATIC_UNMAP, (_wh_t)STATIC_UNMAP)
#define AM_ROMBANK(_bank) AM_READ((_rh_t)(STATIC_BANK1 + (_bank) - 1))
#define AM_RAMBANK(_bank) AM_READWRITE((_rh_t)(STATIC_BANK1 + (_bank) - 1), (_wh_t)(STATIC_BANK1 + (_bank) - 1))

View File

@ -13,33 +13,61 @@
****************************************************************************
Memory map
0000-0fff tvg75
1000-1fff tvg76
2000-2fff tvg77
3000-3fff tvg78
4000-4fff tvg79
5000-5fff tvg80
8000-bfff VIDEO RAM (four banks)
c000-cfff tvg83/84 (banked)
d000-dfff tvg85/86 (banked)
e000-e3ff RAM
****************************************************************************
========================================================================
CPU #1
========================================================================
0000-7FFF R xxxxxxxx Program ROM
8000-BFFF R/W xxxxxxxx Bitmap RAM
C000 R ----xxxx Coin inputs
C200 R ----xxxx Option switches
D000-DFFF R/W xxxxxxxx Custom microprocessor RAM
E000 W ----xxxx BSEL Bank select
E001 W xxxxxxxx DMA ROM start address low
E002 W xxxxxxxx DMA ROM start address high
E003 W xxxxxxxx DMA RAM start address low
E004 W xxxxxxxx DMA RAM start address high
E005 W xxxxxxxx Picture size/DMA start low
E006 W xxxxxxxx Picture size/DMA start high
========================================================================
C800 W xxxxxxxx Sound chip address
CA00 R/W xxxxxxxx Sound chip data
========================================================================
Interrupts:
NMI not connected
IRQ generated by VBLANK
========================================================================
memory mapped ports:
read:
e400 DSW 0
ec00 IN 0
ed00 IN 1
ee00 IN 2
efxx (4 bits wide) security chip in. It seems to work like a clock.
write:
e800-e801 low/high byte start address of data in picture ROM for DMA
e802-e803 low/high byte start address in bitmap RAM (where picture is to be
written) during DMA
e804-e805 picture size for DMA, and DMA start
e806 vertical scroll of playfield
e807 horizontal scroll of playfield
e808 bank select latch
e809 A & B bitmap control latch (A=playfield B=motion)
bit 5 FLIP A
bit 4 FLIP B
bit 3 EN A
bit 2 EN B
bit 1 PRI A
bit 0 PRI B
e80a color shading latch
ec00 command to sound CPU
ed00 coin counters
efxx (4 bits wide) security chip out
---------------------------------------------------------------------------
CPU #1 (sound)
0000 0fff tvg81
4000 43ff RAM
6000 command from main CPU
I/O ports:
7000 AY-3-8910 write
8000 AY-3-8910 control
---------------------------------------------------------------------------
interrupts:
(CPU#0) standard IM 1 interrupt mode (rst #38 every vblank)
(CPU#1) same here
****************************************************************************
@ -55,73 +83,22 @@
***************************************************************************/
/*
CPU #0
0000-0fff tvg75
1000-1fff tvg76
2000-2fff tvg77
3000-3fff tvg78
4000-4fff tvg79
5000-5fff tvg80
8000-bfff VIDEO RAM (four banks)
c000-cfff tvg83/84 (banked)
d000-dfff tvg85/86 (banked)
e000-e3ff RAM
memory mapped ports:
read:
e400 DSW 0
ec00 IN 0
ed00 IN 1
ee00 IN 2
efxx (4 bits wide) security chip in. It seems to work like a clock.
write:
e800-e801 low/high byte start address of data in picture ROM for DMA
e802-e803 low/high byte start address in bitmap RAM (where picture is to be
written) during DMA
e804-e805 picture size for DMA, and DMA start
e806 vertical scroll of playfield
e807 horizontal scroll of playfield
e808 bank select latch
e809 A & B bitmap control latch (A=playfield B=motion)
bit 5 FLIP A
bit 4 FLIP B
bit 3 EN A
bit 2 EN B
bit 1 PRI A
bit 0 PRI B
e80a color shading latch
ec00 command to sound CPU
ed00 coin counters
efxx (4 bits wide) security chip out
---------------------------------------------------------------------------
CPU #1 (sound)
0000 0fff tvg81
4000 43ff RAM
6000 command from main CPU
I/O ports:
7000 AY-3-8910 write
8000 AY-3-8910 control
---------------------------------------------------------------------------
interrupts:
(CPU#0) standard IM 1 interrupt mode (rst #38 every vblank)
(CPU#1) same here
***************************************************************************/
#include "driver.h"
#include "kangaroo.h"
#include "cpu/z80/z80.h"
#include "sound/ay8910.h"
#define MASTER_CLOCK XTAL_10MHz
static READ8_HANDLER(mcu_sim_r);
static WRITE8_HANDLER(mcu_sim_w);
static UINT8 kangaroo_clock;
/*************************************
*
@ -129,6 +106,21 @@ interrupts:
*
*************************************/
static MACHINE_START( kangaroo )
{
memory_configure_bank(1, 0, 2, memory_region(REGION_GFX1), 0x2000);
state_save_register_global(kangaroo_clock);
}
static MACHINE_START( kangaroo_mcu )
{
MACHINE_START_CALL(kangaroo);
memory_install_readwrite8_handler(0, ADDRESS_SPACE_PROGRAM, 0xef00, 0xefff, 0, 0, mcu_sim_r, mcu_sim_w);
kangaroo_clock = 0;
}
static MACHINE_RESET( kangaroo )
{
/* I think there is a bug in the startup checks of the game. At the very */
@ -153,23 +145,17 @@ static MACHINE_RESET( kangaroo )
*
*************************************/
static UINT8 kangaroo_clock=0;
/* I have no idea what the security chip is nor whether it really does,
this just seems to do the trick -V-
*/
static READ8_HANDLER( kangaroo_sec_chip_r )
static READ8_HANDLER( mcu_sim_r )
{
/* kangaroo_clock = (kangaroo_clock << 1) + 1; */
kangaroo_clock++;
return (kangaroo_clock & 0x0f);
return ++kangaroo_clock & 0x0f;
}
static WRITE8_HANDLER( kangaroo_sec_chip_w )
static WRITE8_HANDLER( mcu_sim_w )
{
/* kangaroo_clock = val & 0x0f; */
}
@ -194,31 +180,16 @@ static WRITE8_HANDLER( kangaroo_coin_counter_w )
*
*************************************/
static ADDRESS_MAP_START( readmem, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x5fff) AM_READ(MRA8_ROM)
AM_RANGE(0xc000, 0xdfff) AM_READ(MRA8_BANK1)
AM_RANGE(0xe000, 0xe3ff) AM_READ(MRA8_RAM)
AM_RANGE(0xe400, 0xe400) AM_READ(input_port_3_r)
AM_RANGE(0xec00, 0xec00) AM_READ(input_port_0_r)
AM_RANGE(0xed00, 0xed00) AM_READ(input_port_1_r)
AM_RANGE(0xee00, 0xee00) AM_READ(input_port_2_r)
AM_RANGE(0xef00, 0xef00) AM_READ(kangaroo_sec_chip_r)
ADDRESS_MAP_END
static ADDRESS_MAP_START( writemem, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x5fff) AM_WRITE(MWA8_ROM)
static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x5fff) AM_ROM
AM_RANGE(0x8000, 0xbfff) AM_WRITE(kangaroo_videoram_w)
AM_RANGE(0xc000, 0xdfff) AM_WRITE(MWA8_ROM)
AM_RANGE(0xe000, 0xe3ff) AM_WRITE(MWA8_RAM)
AM_RANGE(0xe800, 0xe805) AM_WRITE(kangaroo_blitter_w) AM_BASE(&kangaroo_blitter)
AM_RANGE(0xe806, 0xe807) AM_WRITE(MWA8_RAM) AM_BASE(&kangaroo_scroll)
AM_RANGE(0xe808, 0xe808) AM_WRITE(kangaroo_bank_select_w) AM_BASE(&kangaroo_bank_select)
AM_RANGE(0xe809, 0xe809) AM_WRITE(kangaroo_video_control_w) AM_BASE(&kangaroo_video_control)
AM_RANGE(0xe80a, 0xe80a) AM_WRITE(kangaroo_color_mask_w)
AM_RANGE(0xec00, 0xec00) AM_WRITE(soundlatch_w)
AM_RANGE(0xed00, 0xed00) AM_WRITE(kangaroo_coin_counter_w)
AM_RANGE(0xef00, 0xefff) AM_WRITE(kangaroo_sec_chip_w)
AM_RANGE(0xc000, 0xdfff) AM_ROMBANK(1)
AM_RANGE(0xe000, 0xe3ff) AM_RAM
AM_RANGE(0xe400, 0xe400) AM_MIRROR(0x03ff) AM_READ_PORT("DSW0")
AM_RANGE(0xe800, 0xe80a) AM_MIRROR(0x03f0) AM_WRITE(kangaroo_video_control_w) AM_BASE(&kangaroo_video_control)
AM_RANGE(0xec00, 0xec00) AM_MIRROR(0x00ff) AM_READ_PORT("IN0") AM_WRITE(soundlatch_w)
AM_RANGE(0xed00, 0xed00) AM_MIRROR(0x00ff) AM_READ_PORT("IN1") AM_WRITE(kangaroo_coin_counter_w)
AM_RANGE(0xee00, 0xee00) AM_MIRROR(0x00ff) AM_READ_PORT("IN2")
ADDRESS_MAP_END
@ -229,22 +200,34 @@ ADDRESS_MAP_END
*
*************************************/
static ADDRESS_MAP_START( sound_readmem, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x0fff) AM_READ(MRA8_ROM)
AM_RANGE(0x4000, 0x43ff) AM_READ(MRA8_RAM)
AM_RANGE(0x6000, 0x6000) AM_READ(soundlatch_r)
static ADDRESS_MAP_START( sound_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x0fff) AM_ROM
AM_RANGE(0x4000, 0x43ff) AM_MIRROR(0x0c00) AM_RAM
AM_RANGE(0x6000, 0x6000) AM_MIRROR(0x0fff) AM_READ(soundlatch_r)
AM_RANGE(0x7000, 0x7000) AM_MIRROR(0x0fff) AM_WRITE(AY8910_write_port_0_w)
AM_RANGE(0x8000, 0x8000) AM_MIRROR(0x0fff) AM_WRITE(AY8910_control_port_0_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( sound_writemem, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x0fff) AM_WRITE(MWA8_ROM)
AM_RANGE(0x4000, 0x43ff) AM_WRITE(MWA8_RAM)
/* yes, this is indentical */
static ADDRESS_MAP_START( sound_portmap, ADDRESS_SPACE_IO, 8 )
AM_RANGE(0x0000, 0x0fff) AM_ROM
AM_RANGE(0x4000, 0x43ff) AM_MIRROR(0x0c00) AM_RAM
AM_RANGE(0x6000, 0x6000) AM_MIRROR(0x0fff) AM_READ(soundlatch_r)
AM_RANGE(0x7000, 0x7000) AM_MIRROR(0x0fff) AM_WRITE(AY8910_write_port_0_w)
AM_RANGE(0x8000, 0x8000) AM_MIRROR(0x0fff) AM_WRITE(AY8910_control_port_0_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( sound_writeport, ADDRESS_SPACE_IO, 8 )
AM_RANGE(0x7000, 0x7000) AM_WRITE(AY8910_write_port_0_w)
AM_RANGE(0x8000, 0x8000) AM_WRITE(AY8910_control_port_0_w)
/*************************************
*
* Microcontroller memory handlers
*
*************************************/
static ADDRESS_MAP_START( mcu_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x07ff) AM_ROM
ADDRESS_MAP_END
@ -256,37 +239,30 @@ ADDRESS_MAP_END
*************************************/
static INPUT_PORTS_START( fnkyfish )
PORT_START /* IN0 */
PORT_START_TAG("IN0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SERVICE1 )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START1 )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START2 )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START /* IN1 */
PORT_START_TAG("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0xe0, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START /* IN2 */
PORT_START_TAG("IN2")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0xe0, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START /* DSW0 */
PORT_START_TAG("DSW0")
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "5" )
@ -315,7 +291,7 @@ INPUT_PORTS_END
static INPUT_PORTS_START( kangaroo )
PORT_START /* IN0 */
PORT_START_TAG("IN0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SERVICE1 )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START1 )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START2 )
@ -331,7 +307,7 @@ static INPUT_PORTS_START( kangaroo )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
PORT_START /* IN1 */
PORT_START_TAG("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY
@ -341,7 +317,7 @@ static INPUT_PORTS_START( kangaroo )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_SERVICE( 0x80, IP_ACTIVE_HIGH )
PORT_START /* IN2 */
PORT_START_TAG("IN2")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL
@ -351,7 +327,7 @@ static INPUT_PORTS_START( kangaroo )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START /* DSW0 */
PORT_START_TAG("DSW0")
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "5" )
@ -391,42 +367,49 @@ INPUT_PORTS_END
*
*************************************/
static MACHINE_DRIVER_START( kangaroo )
static MACHINE_DRIVER_START( nomcu )
/* basic machine hardware */
MDRV_CPU_ADD(Z80, 10000000/4) /* 2.5 MHz */
MDRV_CPU_PROGRAM_MAP(readmem,writemem)
MDRV_CPU_ADD(Z80, MASTER_CLOCK/4)
MDRV_CPU_PROGRAM_MAP(main_map,0)
MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
MDRV_CPU_ADD(Z80, 10000000/4) /* 2.5 MHz */
/* audio CPU */
MDRV_CPU_PROGRAM_MAP(sound_readmem,sound_writemem)
MDRV_CPU_IO_MAP(0,sound_writeport)
MDRV_CPU_ADD(Z80, MASTER_CLOCK/8)
MDRV_CPU_PROGRAM_MAP(sound_map,0)
MDRV_CPU_IO_MAP(sound_portmap,0)
MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION)
MDRV_MACHINE_START(kangaroo)
MDRV_MACHINE_RESET(kangaroo)
/* video hardware */
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
MDRV_SCREEN_SIZE(32*8, 32*8)
MDRV_SCREEN_VISIBLE_AREA(0, 255, 8, 255-8)
MDRV_PALETTE_LENGTH(24)
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_UPDATE_SCANLINE)
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
MDRV_SCREEN_ADD("main", 0)
MDRV_SCREEN_RAW_PARAMS(MASTER_CLOCK, 320*2, 0*2, 256*2, 260, 8, 248)
MDRV_PALETTE_INIT(kangaroo)
MDRV_VIDEO_START(kangaroo)
MDRV_VIDEO_UPDATE(kangaroo)
/* sound hardware */
MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_SOUND_ADD(AY8910, 10000000/8)
MDRV_SOUND_ADD(AY8910, MASTER_CLOCK/8)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
MACHINE_DRIVER_END
static MACHINE_DRIVER_START( mcu )
MDRV_IMPORT_FROM(nomcu)
MDRV_MACHINE_START(kangaroo_mcu)
MDRV_CPU_ADD(MB8841, MASTER_CLOCK/4/12)
MDRV_CPU_FLAGS(CPU_DISABLE)
MDRV_CPU_PROGRAM_MAP(mcu_map,0)
MACHINE_DRIVER_END
/*************************************
*
@ -464,7 +447,10 @@ ROM_START( kangaroo )
ROM_REGION( 0x10000, REGION_CPU2, 0 )
ROM_LOAD( "tvg_81.8", 0x0000, 0x1000, CRC(fb449bfd) SHA1(f593a0339f47e121736a927587132aeb52704557) )
ROM_REGION( 0x0800, REGION_CPU3, 0 ) /* 8k for the MB8841 custom microcontroller (currently not emulated) */
ROM_REGION( 0x0800, REGION_CPU3, 0 ) /* code for the 8841 custom MCU */
ROM_LOAD( "8841.rom", 0x0000, 0x0800, NO_DUMP )
ROM_REGION( 0x0800, REGION_USER1, 0 ) /* data for the 8841 custom MCU */
ROM_LOAD( "tvg_82.12", 0x0000, 0x0800, CRC(57766f69) SHA1(94a7a557d8325799523d5e1a88653a9a3fbe34f9) )
ROM_REGION( 0x4000, REGION_GFX1, 0 )
@ -477,24 +463,27 @@ ROM_END
ROM_START( kangaroa )
ROM_REGION( 0x10000, REGION_CPU1, 0 )
ROM_LOAD( "tvg_75.0", 0x0000, 0x1000, CRC(0d18c581) SHA1(0e0f89d644b79e887c53e5294783843ca7e875ba) )
ROM_LOAD( "tvg_76.1", 0x1000, 0x1000, CRC(5978d37a) SHA1(684c1092de4a0927a03752903c86c3bbe99e868a) )
ROM_LOAD( "tvg_77.2", 0x2000, 0x1000, CRC(522d1097) SHA1(09fe627a46d32df2e098d9fad7757f9d61bef41f) )
ROM_LOAD( "tvg_78.3", 0x3000, 0x1000, CRC(063da970) SHA1(582ff21dd46c651f07a4846e0f8a7544a5891988) )
ROM_LOAD( "tvg79.bin", 0x4000, 0x1000, CRC(82a26c7d) SHA1(09087552dbe4d27df79396072c0f9b916f78f89b) )
ROM_LOAD( "tvg80.bin", 0x5000, 0x1000, CRC(3dead542) SHA1(0b5d329b1ebbacc650d06289b4e080304e728ea7) )
ROM_LOAD( "136008-101.ic7", 0x0000, 0x1000, CRC(0d18c581) SHA1(0e0f89d644b79e887c53e5294783843ca7e875ba) )
ROM_LOAD( "136008-102.ic8", 0x1000, 0x1000, CRC(5978d37a) SHA1(684c1092de4a0927a03752903c86c3bbe99e868a) )
ROM_LOAD( "136008-103.ic9", 0x2000, 0x1000, CRC(522d1097) SHA1(09fe627a46d32df2e098d9fad7757f9d61bef41f) )
ROM_LOAD( "136008-104.ic10", 0x3000, 0x1000, CRC(063da970) SHA1(582ff21dd46c651f07a4846e0f8a7544a5891988) )
ROM_LOAD( "136008-105.ic16", 0x4000, 0x1000, CRC(82a26c7d) SHA1(09087552dbe4d27df79396072c0f9b916f78f89b) )
ROM_LOAD( "136008-106.ic17", 0x5000, 0x1000, CRC(3dead542) SHA1(0b5d329b1ebbacc650d06289b4e080304e728ea7) )
ROM_REGION( 0x10000, REGION_CPU2, 0 )
ROM_LOAD( "tvg_81.8", 0x0000, 0x1000, CRC(fb449bfd) SHA1(f593a0339f47e121736a927587132aeb52704557) )
ROM_LOAD( "136008-107.ic24", 0x0000, 0x1000, CRC(fb449bfd) SHA1(f593a0339f47e121736a927587132aeb52704557) )
ROM_REGION( 0x0800, REGION_CPU3, 0 ) /* 8k for the MB8841 custom microcontroller (currently not emulated) */
ROM_LOAD( "tvg_82.12", 0x0000, 0x0800, CRC(57766f69) SHA1(94a7a557d8325799523d5e1a88653a9a3fbe34f9) )
ROM_REGION( 0x0800, REGION_CPU3, 0 ) /* code for the 8841 custom MCU */
ROM_LOAD( "8841.rom", 0x0000, 0x0800, NO_DUMP )
ROM_REGION( 0x0800, REGION_USER1, 0 ) /* data for the 8841 custom MCU */
ROM_LOAD( "136008-112.ic28", 0x0000, 0x0800, CRC(57766f69) SHA1(94a7a557d8325799523d5e1a88653a9a3fbe34f9) )
ROM_REGION( 0x4000, REGION_GFX1, 0 )
ROM_LOAD( "tvg_83.v0", 0x0000, 0x1000, CRC(c0446ca6) SHA1(fca6ba565051337c0198c93b7b8477632e0dd0b6) )
ROM_LOAD( "tvg_85.v2", 0x1000, 0x1000, CRC(72c52695) SHA1(87f4715fbb7d509bd9cc4e71e2afb0d475bbac13) )
ROM_LOAD( "tvg_84.v1", 0x2000, 0x1000, CRC(e4cb26c2) SHA1(5016db9d48fdcfb757618659d063b90862eb0e90) )
ROM_LOAD( "tvg_86.v3", 0x3000, 0x1000, CRC(9e6a599f) SHA1(76b4eddb4efcd8189d8cc5962d8497e82885f212) )
ROM_LOAD( "136008-108.ic76", 0x0000, 0x1000, CRC(c0446ca6) SHA1(fca6ba565051337c0198c93b7b8477632e0dd0b6) )
ROM_LOAD( "136008-110.ic77", 0x1000, 0x1000, CRC(72c52695) SHA1(87f4715fbb7d509bd9cc4e71e2afb0d475bbac13) )
ROM_LOAD( "136008-109.ic52", 0x2000, 0x1000, CRC(e4cb26c2) SHA1(5016db9d48fdcfb757618659d063b90862eb0e90) )
ROM_LOAD( "136008-111.ic53", 0x3000, 0x1000, CRC(9e6a599f) SHA1(76b4eddb4efcd8189d8cc5962d8497e82885f212) )
ROM_END
@ -525,7 +514,7 @@ ROM_END
*
*************************************/
GAME( 1981, fnkyfish, 0, kangaroo, fnkyfish, 0, ROT90, "Sun Electronics", "Funky Fish", 0 )
GAME( 1982, kangaroo, 0, kangaroo, kangaroo, 0, ROT90, "Sun Electronics", "Kangaroo", 0 )
GAME( 1982, kangaroa, kangaroo, kangaroo, kangaroo, 0, ROT90, "[Sun Electronics] (Atari license)", "Kangaroo (Atari)", 0 )
GAME( 1982, kangarob, kangaroo, kangaroo, kangaroo, 0, ROT90, "bootleg", "Kangaroo (bootleg)", 0 )
GAME( 1981, fnkyfish, 0, nomcu, fnkyfish, 0, ROT90, "Sun Electronics", "Funky Fish", 0 )
GAME( 1982, kangaroo, 0, mcu, kangaroo, 0, ROT90, "Sun Electronics", "Kangaroo", 0 )
GAME( 1982, kangaroa, kangaroo, mcu, kangaroo, 0, ROT90, "[Sun Electronics] (Atari license)", "Kangaroo (Atari)", 0 )
GAME( 1982, kangarob, kangaroo, nomcu, kangaroo, 0, ROT90, "bootleg", "Kangaroo (bootleg)", 0 )

View File

@ -9,9 +9,6 @@
/*----------- defined in video/kangaroo.c -----------*/
extern UINT8 *kangaroo_video_control;
extern UINT8 *kangaroo_bank_select;
extern UINT8 *kangaroo_blitter;
extern UINT8 *kangaroo_scroll;
PALETTE_INIT( kangaroo );
VIDEO_START( kangaroo );
@ -20,5 +17,3 @@ VIDEO_UPDATE( kangaroo );
WRITE8_HANDLER( kangaroo_blitter_w );
WRITE8_HANDLER( kangaroo_videoram_w );
WRITE8_HANDLER( kangaroo_video_control_w );
WRITE8_HANDLER( kangaroo_bank_select_w );
WRITE8_HANDLER( kangaroo_color_mask_w );

View File

@ -5,7 +5,7 @@
int fd1094_set_state(UINT8 *key,int state);
int fd1094_decode(int address,int val,UINT8 *key,int vector_fetch);
#ifdef MAME_DEBUG
#ifdef ENABLE_DEBUGGER
typedef struct _fd1094_constraint fd1094_constraint;
struct _fd1094_constraint

View File

@ -105,7 +105,7 @@
***************************************************************************/
#ifdef MAME_DEBUG
#ifdef ENABLE_DEBUGGER
#include "driver.h"
#include "deprecat.h"
@ -2203,7 +2203,6 @@ static void build_optable(void)
/* make sure we match the disassembler */
{
char dummybuffer[256];
UINT8 instrbuffer[10];
instrbuffer[0] = (opnum | eabits) >> 8;
instrbuffer[1] = (opnum | eabits);

View File

@ -143,7 +143,7 @@ void fd1094_machine_init(void)
}
#ifdef MAME_DEBUG
#ifdef ENABLE_DEBUGGER
static void key_changed(void)
{
int addr;
@ -188,7 +188,7 @@ void fd1094_driver_init(void (*set_decrypted)(UINT8 *))
}
fd1094_current_cacheposition = 0;
#ifdef MAME_DEBUG
#ifdef ENABLE_DEBUGGER
/* key debugging */
if (Machine->debug_mode && memory_region(REGION_USER2) != NULL)
{

View File

@ -10,300 +10,221 @@
UINT8 *kangaroo_video_control;
UINT8 *kangaroo_bank_select;
UINT8 *kangaroo_blitter;
UINT8 *kangaroo_scroll;
static int screen_flipped;
static mame_bitmap *tmpbitmap2;
/***************************************************************************
Convert the color PROMs into a more useable format.
Kangaroo doesn't have color PROMs, the playfield data is directly converted
into colors: 1 bit per gun, therefore only 8 possible colors, but there is
also a global mask register which controls intensities of the three guns,
separately for foreground and background. The fourth bit in the video RAM
data disables this mask, making the color display at full intensity
regardless of the mask value.
Actually the mask doesn't directly control intensity. The guns are rapidly
turned on and off at a subpixel rate, relying on the monitor to blend the
colors into a more or less uniform half intensity color.
We use three groups of 8 pens: the first is fixed and contains the 8
possible colors; the other two are dynamically modified when the mask
register is written to, one is for the background, the other for sprites.
***************************************************************************/
PALETTE_INIT( kangaroo )
{
int i;
for (i = 0;i < machine->drv->total_colors;i++)
palette_set_color_rgb(machine,i,pal1bit(i >> 2),pal1bit(i >> 1),pal1bit(i >> 0));
}
static void blitter_execute(void);
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
/*************************************
*
* Video setup
*
*************************************/
VIDEO_START( kangaroo )
{
tmpbitmap = auto_bitmap_alloc(machine->screen[0].width,machine->screen[0].height,machine->screen[0].format);
tmpbitmap2 = auto_bitmap_alloc(machine->screen[0].width,machine->screen[0].height,machine->screen[0].format);
videoram = auto_malloc(machine->screen[0].width*machine->screen[0].height);
videoram = auto_malloc(256 * 256);
state_save_register_global_pointer(videoram, 256 * 256);
}
/*************************************
*
* Video control writes
*
*************************************/
WRITE8_HANDLER( kangaroo_video_control_w )
{
/* A & B bitmap control latch (A=playfield B=motion)
bit 5 FLIP A
bit 4 FLIP B
bit 3 EN A
bit 2 EN B
bit 1 PRI A
bit 0 PRI B */
if ((*kangaroo_video_control & 0x30) != (data & 0x30))
kangaroo_video_control[offset] = data;
switch (offset)
{
screen_flipped = 1;
}
*kangaroo_video_control = data;
}
WRITE8_HANDLER( kangaroo_bank_select_w )
{
UINT8 *RAM = memory_region(REGION_GFX1);
/* this is a VERY crude way to handle the banked ROMs - but it's */
/* correct enough to pass the self test */
if (data & 0x05)
memory_set_bankptr(1,&RAM[0x0000]);
else
memory_set_bankptr(1,&RAM[0x2000]);
*kangaroo_bank_select = data;
}
WRITE8_HANDLER( kangaroo_color_mask_w )
{
int i;
/* color mask for A plane */
for (i = 0;i < 8;i++)
{
int r,g,b;
r = ((i & 4) >> 2) * ((data & 0x20) ? 0xff : 0x7f);
g = ((i & 2) >> 1) * ((data & 0x10) ? 0xff : 0x7f);
b = ((i & 1) >> 0) * ((data & 0x08) ? 0xff : 0x7f);
palette_set_color(Machine,8+i,MAKE_RGB(r,g,b));
}
/* color mask for B plane */
for (i = 0;i < 8;i++)
{
int r,g,b;
r = ((i & 4) >> 2) * ((data & 0x04) ? 0xff : 0x7f);
g = ((i & 2) >> 1) * ((data & 0x02) ? 0xff : 0x7f);
b = ((i & 1) >> 0) * ((data & 0x01) ? 0xff : 0x7f);
palette_set_color(Machine,16+i,MAKE_RGB(r,g,b));
case 5: /* blitter start */
blitter_execute();
break;
case 8: /* bank select */
memory_set_bank(1, (data & 0x05) ? 0 : 1);
break;
}
}
WRITE8_HANDLER( kangaroo_blitter_w )
/*************************************
*
* DMA blitter
*
*************************************/
static void blitter_execute(void)
{
kangaroo_blitter[offset] = data;
int src,dest;
int x,y,width,height,old_bank_select,new_bank_select;
if (offset == 5) /* trigger DMA */
src = kangaroo_video_control[0] + 256 * kangaroo_video_control[1];
dest = kangaroo_video_control[2] + 256 * kangaroo_video_control[3];
width = kangaroo_video_control[5];
height = kangaroo_video_control[4];
old_bank_select = new_bank_select = kangaroo_video_control[8];
if (new_bank_select & 0x0c) new_bank_select |= 0x0c;
if (new_bank_select & 0x03) new_bank_select |= 0x03;
kangaroo_video_control_w(8, new_bank_select & 0x05);
for (x = 0; x <= width; x++)
{
int src,dest;
int x,y,xb,yb,old_bank_select,new_bank_select;
for (y = 0; y <= height; y++)
program_write_byte(dest + y, program_read_byte(src++));
src = kangaroo_blitter[0] + 256 * kangaroo_blitter[1];
dest = kangaroo_blitter[2] + 256 * kangaroo_blitter[3];
xb = kangaroo_blitter[5];
yb = kangaroo_blitter[4];
old_bank_select = new_bank_select = *kangaroo_bank_select;
if (new_bank_select & 0x0c) new_bank_select |= 0x0c;
if (new_bank_select & 0x03) new_bank_select |= 0x03;
kangaroo_bank_select_w(0, new_bank_select & 0x05);
for (x = 0;x <= xb;x++)
{
for (y = 0;y <= yb;y++)
{
program_write_byte(dest++, program_read_byte(src++));
}
dest = dest - (yb + 1) + 256;
}
src = kangaroo_blitter[0] + 256 * kangaroo_blitter[1];
dest = kangaroo_blitter[2] + 256 * kangaroo_blitter[3];
kangaroo_bank_select_w(0, new_bank_select & 0x0a);
for (x = 0;x <= xb;x++)
{
for (y = 0;y <= yb;y++)
{
program_write_byte(dest++, program_read_byte(src++));
}
dest = dest - (yb + 1) + 256;
}
kangaroo_bank_select_w(0, old_bank_select);
}
}
INLINE void kangaroo_plot_pixel(mame_bitmap *bitmap, int x, int y, int col, int color_base, int flip)
{
if (flip)
{
x = bitmap->width - 1 - x;
y = bitmap->height - 1 - y;
dest += 256;
}
*BITMAP_ADDR16(bitmap, y, x) = Machine->pens[((col & 0x08) ? 0 : color_base) + (col & 0x07)];
src = kangaroo_video_control[0] + 256 * kangaroo_video_control[1];
dest = kangaroo_video_control[2] + 256 * kangaroo_video_control[3];
kangaroo_video_control_w(8, new_bank_select & 0x0a);
for (x = 0; x <= width; x++)
{
for (y = 0; y <= height; y++)
program_write_byte(dest + y, program_read_byte(src++));
dest += 256;
}
kangaroo_video_control_w(8, old_bank_select);
}
INLINE void kangaroo_redraw_4pixels(int x, int y)
{
int offs, flipA, flipB;
offs = y * 256 + x;
flipA = *kangaroo_video_control & 0x20;
flipB = *kangaroo_video_control & 0x10;
kangaroo_plot_pixel(tmpbitmap , x , y, videoram[offs ] & 0x0f, 8, flipA);
kangaroo_plot_pixel(tmpbitmap , x+1, y, videoram[offs+1] & 0x0f, 8, flipA);
kangaroo_plot_pixel(tmpbitmap , x+2, y, videoram[offs+2] & 0x0f, 8, flipA);
kangaroo_plot_pixel(tmpbitmap , x+3, y, videoram[offs+3] & 0x0f, 8, flipA);
kangaroo_plot_pixel(tmpbitmap2, x , y, videoram[offs ] >> 4, 16, flipB);
kangaroo_plot_pixel(tmpbitmap2, x+1, y, videoram[offs+1] >> 4, 16, flipB);
kangaroo_plot_pixel(tmpbitmap2, x+2, y, videoram[offs+2] >> 4, 16, flipB);
kangaroo_plot_pixel(tmpbitmap2, x+3, y, videoram[offs+3] >> 4, 16, flipB);
}
/*************************************
*
* Video RAM writes
*
*************************************/
WRITE8_HANDLER( kangaroo_videoram_w )
{
int a_Z_R,a_G_B,b_Z_R,b_G_B;
int sx, sy, offs;
a_Z_R = *kangaroo_bank_select & 0x01;
a_G_B = *kangaroo_bank_select & 0x02;
b_Z_R = *kangaroo_bank_select & 0x04;
b_G_B = *kangaroo_bank_select & 0x08;
sx = (offset / 256) * 4;
sy = offset % 256;
offs = sy * 256 + sx;
/* rearrange the bits to a more convenient pattern (from DCBADCBA to DDCCBBAA) */
data = BITSWAP8(data, 7,3,6,2,5,1,4,0);
if (a_G_B)
/* B layer, green & blue bits */
if (kangaroo_video_control[8] & 0x08)
{
videoram[offs ] = (videoram[offs ] & 0xfc) | ((data & 0x10) >> 3) | ((data & 0x01) >> 0);
videoram[offs+1] = (videoram[offs+1] & 0xfc) | ((data & 0x20) >> 4) | ((data & 0x02) >> 1);
videoram[offs+2] = (videoram[offs+2] & 0xfc) | ((data & 0x40) >> 5) | ((data & 0x04) >> 2);
videoram[offs+3] = (videoram[offs+3] & 0xfc) | ((data & 0x80) >> 6) | ((data & 0x08) >> 3);
videoram[offs ] = (videoram[offs ] & 0xcf) | (((data >> 0) & 3) << 4);
videoram[offs+1] = (videoram[offs+1] & 0xcf) | (((data >> 2) & 3) << 4);
videoram[offs+2] = (videoram[offs+2] & 0xcf) | (((data >> 4) & 3) << 4);
videoram[offs+3] = (videoram[offs+3] & 0xcf) | (((data >> 6) & 3) << 4);
}
if (a_Z_R)
/* B layer, Z & red bits */
if (kangaroo_video_control[8] & 0x04)
{
videoram[offs ] = (videoram[offs ] & 0xf3) | ((data & 0x10) >> 1) | ((data & 0x01) << 2);
videoram[offs+1] = (videoram[offs+1] & 0xf3) | ((data & 0x20) >> 2) | ((data & 0x02) << 1);
videoram[offs+2] = (videoram[offs+2] & 0xf3) | ((data & 0x40) >> 3) | ((data & 0x04) >> 0);
videoram[offs+3] = (videoram[offs+3] & 0xf3) | ((data & 0x80) >> 4) | ((data & 0x08) >> 1);
videoram[offs ] = (videoram[offs ] & 0x3f) | (((data >> 0) & 3) << 6);
videoram[offs+1] = (videoram[offs+1] & 0x3f) | (((data >> 2) & 3) << 6);
videoram[offs+2] = (videoram[offs+2] & 0x3f) | (((data >> 4) & 3) << 6);
videoram[offs+3] = (videoram[offs+3] & 0x3f) | (((data >> 6) & 3) << 6);
}
if (b_G_B)
/* A layer, green & blue bits */
if (kangaroo_video_control[8] & 0x02)
{
videoram[offs ] = (videoram[offs ] & 0xcf) | ((data & 0x10) << 1) | ((data & 0x01) << 4);
videoram[offs+1] = (videoram[offs+1] & 0xcf) | ((data & 0x20) >> 0) | ((data & 0x02) << 3);
videoram[offs+2] = (videoram[offs+2] & 0xcf) | ((data & 0x40) >> 1) | ((data & 0x04) << 2);
videoram[offs+3] = (videoram[offs+3] & 0xcf) | ((data & 0x80) >> 2) | ((data & 0x08) << 1);
videoram[offs ] = (videoram[offs ] & 0xfc) | (((data >> 0) & 3) << 0);
videoram[offs+1] = (videoram[offs+1] & 0xfc) | (((data >> 2) & 3) << 0);
videoram[offs+2] = (videoram[offs+2] & 0xfc) | (((data >> 4) & 3) << 0);
videoram[offs+3] = (videoram[offs+3] & 0xfc) | (((data >> 6) & 3) << 0);
}
if (b_Z_R)
/* A layer, Z & red bits */
if (kangaroo_video_control[8] & 0x01)
{
videoram[offs ] = (videoram[offs ] & 0x3f) | ((data & 0x10) << 3) | ((data & 0x01) << 6);
videoram[offs+1] = (videoram[offs+1] & 0x3f) | ((data & 0x20) << 2) | ((data & 0x02) << 5);
videoram[offs+2] = (videoram[offs+2] & 0x3f) | ((data & 0x40) << 1) | ((data & 0x04) << 4);
videoram[offs+3] = (videoram[offs+3] & 0x3f) | ((data & 0x80) << 0) | ((data & 0x08) << 3);
videoram[offs ] = (videoram[offs ] & 0xf3) | (((data >> 0) & 3) << 2);
videoram[offs+1] = (videoram[offs+1] & 0xf3) | (((data >> 2) & 3) << 2);
videoram[offs+2] = (videoram[offs+2] & 0xf3) | (((data >> 4) & 3) << 2);
videoram[offs+3] = (videoram[offs+3] & 0xf3) | (((data >> 6) & 3) << 2);
}
kangaroo_redraw_4pixels(sx, sy);
}
/*************************************
*
* Video updater
*
*************************************/
VIDEO_UPDATE( kangaroo )
{
int scrollx, scrolly;
UINT8 scrolly = kangaroo_video_control[6];
UINT8 scrollx = kangaroo_video_control[7];
UINT8 maska = kangaroo_video_control[10] >> 3;
UINT8 maskb = kangaroo_video_control[10] >> 0;
UINT8 xora = (kangaroo_video_control[9] & 0x20) ? 0xff : 0x00;
UINT8 xorb = (kangaroo_video_control[9] & 0x10) ? 0xff : 0x00;
UINT8 enaa = (kangaroo_video_control[9] & 0x08);
UINT8 enab = (kangaroo_video_control[9] & 0x04);
UINT8 pria = (~kangaroo_video_control[9] & 0x02);
UINT8 prib = (~kangaroo_video_control[9] & 0x01);
rgb_t pens[8];
int x, y;
/* build up the pens arrays */
for (x = 0; x < 8; x++)
pens[x] = MAKE_RGB(pal1bit(x >> 2), pal1bit(x >> 1), pal1bit(x >> 0));
if (screen_flipped)
/* iterate over pixels */
for (y = cliprect->min_y; y <= cliprect->max_y; y++)
{
int x, y;
/* redraw bitmap */
for (x = 0; x < 256; x+=4)
UINT32 *dest = BITMAP_ADDR32(bitmap, y, 0);
for (x = cliprect->min_x; x <= cliprect->max_x; x += 2)
{
for (y = 0; y < 256; y++)
UINT8 effxa = scrollx + ((x / 2) ^ xora);
UINT8 effya = scrolly + (y ^ xora);
UINT8 effxb = (x / 2) ^ xorb;
UINT8 effyb = y ^ xorb;
UINT8 pixa = videoram[effya * 256 + effxa] & 0x0f;
UINT8 pixb = videoram[effyb * 256 + effxb] >> 4;
UINT8 finalpens;
finalpens = 0;
if (enaa && (pria || pixb == 0))
finalpens |= pixa;
if (enab && (prib || pixa == 0))
finalpens |= pixb;
dest[x + 0] = pens[finalpens & 7];
/* KOS1 alternates at 5MHz, offset from the pixel clock by 1/2 clock */
/* when 0, it enables the color mask for pixels with Z = 0 */
finalpens = 0;
if (enaa && (pria || pixb == 0))
{
kangaroo_redraw_4pixels(x, y);
if (!(pixa & 0x08)) pixa &= ~maska;
finalpens |= pixa;
}
if (enab && (prib || pixa == 0))
{
if (!(pixb & 0x08)) pixb &= ~maskb;
finalpens |= pixb;
}
dest[x + 1] = pens[finalpens & 7];
}
screen_flipped = 0;
}
scrollx = kangaroo_scroll[1];
scrolly = kangaroo_scroll[0];
if (*kangaroo_bank_select & 0x01)
{
/* Plane B is primary */
copybitmap(bitmap,tmpbitmap2,0,0,0,0,cliprect);
copyscrollbitmap_trans(bitmap,tmpbitmap,1,&scrollx,1,&scrolly,cliprect,machine->pens[8]);
}
else
{
/* Plane A is primary */
copyscrollbitmap(bitmap,tmpbitmap,1,&scrollx,1,&scrolly,cliprect);
copybitmap_trans(bitmap,tmpbitmap2,0,0,0,0,cliprect,machine->pens[16]);
}
return 0;
}

View File

@ -906,7 +906,7 @@ VIDEO_UPDATE( metro )
}
#if MAME_DEBUG
#ifdef MAME_DEBUG
if (input_code_pressed(KEYCODE_Z))
{
int msk = 0;