diff options
Diffstat (limited to 'src/mame/drivers/gstream.cpp')
-rw-r--r-- | src/mame/drivers/gstream.cpp | 1176 |
1 files changed, 1176 insertions, 0 deletions
diff --git a/src/mame/drivers/gstream.cpp b/src/mame/drivers/gstream.cpp new file mode 100644 index 00000000000..089e69d9cfe --- /dev/null +++ b/src/mame/drivers/gstream.cpp @@ -0,0 +1,1176 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood +/******************************************************************** + + G-Stream (c)2002 Oriental Soft Japan + X2222 (prototype) (c)2000 Oriental Soft + + --- + X2222 has corrupt boss graphics because the program roms we use don't match the sprite roms. + -- + + Hyperstone based hardware + + Simple Sprites (16x16x8bpp tiles) + 3 Simple Tilemaps (32x32x8bpp tiles) + + X2222 uses raw 16bpp palette data instead of 8bpp indexed colours. + + todo: sprite lag (sprites need buffering?) + sprite wraparound is imperfect + + The following is confirmed on G-Stream only + --- + + CPU: E1-32XT + Sound: 2x AD-65 (OKIM6295 clone) + + Xtals: 1.000Mhz (near AD-65a) + 16.000Mhz (near E1-32XT / u56.bin) + + 27.000Mhz (near GFX Section & 54.000Mhz) + 54.000Mhz (near GFX Section & 27.000Mhz) + + notes: + + cpu #0 (PC=00002C34): unmapped program memory dword read from 515ECE48 & FFFFFFFF + what is this, buggy code? + + Is there a problem with the OKI status reads for the AD-65 clone? the game reads + the status register all the time, causing severe slowdown etc, might be related to + bad OKI banking tho. + + --- + + Dump Notes::: + + G-Stream 2020, 2002 Oriental Soft Japan + + Shooter from Oriental soft, heavy influence from XII Stag + as well as Trizeal. Three weapons may be carried and their + power controlled by picking up capsules of a specific colour. + + Three capsule types: + . Red - Vulcan + . Green - Missiles + . Blue - Laser + + Points are awarded by picking up medals which are released + from shot down enemies. The medal value and appearance is + increased as long as you don't miss any. + + When enough medals have been picked up a "void" bomb becomes + available which when released (hold down main shot) will create + a circular "void". Enemy bullets which hit this "void" are transformed + into medals. If you place your ship inside this "void" it becomes + invulnerable like in XII Stag. + + The game is powered by a HyperStone E1-32XT. A battery on the PCB + saves hi-scores. Hi-Scores can be reset by toggling switch S2. + + Documentation: + + Name Size CRC32 + ---------------------------------------- + g-stream_demo.jpg 195939 0x37984e02 + g-stream_title.jpg 152672 0xf7b9bfd3 + g-stream_pcb.jpg 2563664 0x5ec864f3 + + Name Size CRC32 Chip Type + ---------------------------------------------- + gs_prg_02.u197 2097152 0x2f8a6bea 27C160 + gs_gr_01.u120 2097152 0xb82cfab8 27C160 + gs_gr_02.u121 2097152 0x37e19cbd 27C160 + gs_gr_03.u125 2097152 0x1a3b2b11 27C160 + gs_gr_04.u126 2097152 0xa4e8906c 27C160 + gs_gr_05.u174 2097152 0xef283a73 27C160 + gs_gr_06.u175 2097152 0xd4e3a2b2 27C160 + gs_gr_07.u107 2097152 0x84e66fe1 27C160 + gs_gr_08.u109 2097152 0xabd0d6aa 27C160 + gs_gr_09.u180 2097152 0xf2c4fd77 27C160 + gs_gr_10.u182 2097152 0xd696d15d 27C160 + gs_gr_11.u108 2097152 0x946d71d1 27C160 + gs_gr_12.u110 2097152 0x94b56e4e 27C160 + gs_gr_13.u181 2097152 0x7daaeff0 27C160 + gs_gr_14.u183 2097152 0x6bd2a1e1 27C160 + gs_snd_01.u192 524288 0x79b64d3f 27C040 + gs_snd_02.u194 524288 0xe49ed92c 27C040 + gs_snd_03.u191 524288 0x2bfff4ac 27C040 + gs_snd_04.u193 524288 0xb259de3b 27C040 + gs_prg_01.u56 524288 0x0d0c6a38 27C040 + + . Board supplied by Tormod + . Board dumped by Tormod + ++------------------------------------------------+ +| GS_SND_01 RAM4 16MHz RAM1 S2 BT1 | +| AD-65 GS_SND_02 GS_PRG_01 E1-32XT RAM1 | +| VOL GS_SND_03 | +|J AD-65 GS_SND_04 GS_GR_07 | +|A 1MHz GS_PRG_02 XC95288 RAM2 GS_GR_08 | +|M GS_GR_01 RAM2 GS_GR_09 | +|M RAM4 GS_GR_02 XC95288 27MHz GS_GR_10 | +|A RAM4 GS_GR_03 54MHz GS_GR_11 | +| GS_GR_04 S3 GS_GR_12 | +| GAL GS_GR_05 RAM3 RAM3 GS_GR_13 | +| GAL GS_GR_06 RAM3 RAM3 GS_GR_13 | ++------------------------------------------------+ + + CPU: Hyperstone E1-32XT +Sound: OKI 6295 x 2 (rebaged as AD-65) + OSC: 54.000MHz, 27.000MHz, 16.000MHz & 1.000MHz +Other: Sigma Xilinx XC95255 x 2 + +S2 is Toggle switch to reset high scores. +S3 is a 2 position dipswitch bank. +BT1 is 3.6V battery for high scores backup. + +RAM1 is SEC KM416C1204CJ-6 +RAM2 is SEC KM416C1002CJ-12 +RAM3 is EliteMT LP621024DM-70LL +RAM4 is HMC HM6264LP-70 + +*********************************************************************/ + +#include "emu.h" +#include "cpu/e132xs/e132xs.h" +#include "sound/okim6295.h" +#include "machine/nvram.h" + +class gstream_state : public driver_device +{ +public: + gstream_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_oki_1(*this, "oki1"), + m_oki_2(*this, "oki2") , + m_workram(*this, "workram"), + m_vram(*this, "vram"), + m_gfxdecode(*this, "gfxdecode"), + m_palette(*this, "palette") + { + m_toggle = 0; + } + + /* devices */ + required_device<e132xt_device> m_maincpu; + required_device<okim6295_device> m_oki_1; + optional_device<okim6295_device> m_oki_2; + + /* memory pointers */ + required_shared_ptr<UINT32> m_workram; + required_shared_ptr<UINT32> m_vram; +// UINT32 * m_nvram; // currently this uses generic nvram handling + + /* video-related */ + UINT32 m_tmap1_scrollx; + UINT32 m_tmap2_scrollx; + UINT32 m_tmap3_scrollx; + UINT32 m_tmap1_scrolly; + UINT32 m_tmap2_scrolly; + UINT32 m_tmap3_scrolly; + + /* misc */ + int m_oki_bank_1; + int m_oki_bank_2; + int m_toggle; + int m_xoffset; + + DECLARE_WRITE32_MEMBER(gstream_vram_w); + DECLARE_WRITE32_MEMBER(gstream_tilemap1_scrollx_w); + DECLARE_WRITE32_MEMBER(gstream_tilemap1_scrolly_w); + DECLARE_WRITE32_MEMBER(gstream_tilemap2_scrollx_w); + DECLARE_WRITE32_MEMBER(gstream_tilemap2_scrolly_w); + DECLARE_WRITE32_MEMBER(gstream_tilemap3_scrollx_w); + DECLARE_WRITE32_MEMBER(gstream_tilemap3_scrolly_w); + DECLARE_WRITE32_MEMBER(gstream_oki_banking_w); + DECLARE_WRITE32_MEMBER(gstream_oki_4040_w); + DECLARE_WRITE32_MEMBER(x2222_sound_w); + DECLARE_READ32_MEMBER(gstream_speedup_r); + DECLARE_READ32_MEMBER(x2222_speedup_r); + DECLARE_READ32_MEMBER(x2222_speedup2_r); + DECLARE_CUSTOM_INPUT_MEMBER(gstream_mirror_service_r); + DECLARE_CUSTOM_INPUT_MEMBER(gstream_mirror_r); + DECLARE_CUSTOM_INPUT_MEMBER(x2222_toggle_r); + DECLARE_DRIVER_INIT(gstream); + DECLARE_DRIVER_INIT(x2222); + virtual void machine_start(); + virtual void machine_reset(); + virtual void video_start(); + UINT32 screen_update_gstream(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + void draw_bg_gstream(bitmap_rgb32 &bitmap, const rectangle &cliprect, int xscrl, int yscrl, int map, UINT32* ram, int palbase); + + void rearrange_sprite_data(UINT8* ROM, UINT32* NEW, UINT32* NEW2); + void rearrange_tile_data(UINT8* ROM, UINT32* NEW, UINT32* NEW2); + + required_device<gfxdecode_device> m_gfxdecode; + required_device<palette_device> m_palette; +}; + +CUSTOM_INPUT_MEMBER(gstream_state::x2222_toggle_r) // or the game hangs when starting, might be a status flag for the sound? +{ + m_toggle ^= 0xffff; + return m_toggle; +} + + +CUSTOM_INPUT_MEMBER(gstream_state::gstream_mirror_service_r) +{ + int result; + + /* PORT_SERVICE_NO_TOGGLE */ + result = (ioport("IN0")->read() & 0x8000) >> 15; + + return ~result; +} + +CUSTOM_INPUT_MEMBER(gstream_state::gstream_mirror_r) +{ + int result; + + /* IPT_COIN1 */ + result = ((ioport("IN0")->read() & 0x200) >> 9) << 0; + /* IPT_COIN2 */ + result |= ((ioport("IN1")->read() & 0x200) >> 9) << 1; + /* IPT_START1 */ + result |= ((ioport("IN0")->read() & 0x400) >> 10) << 2; + /* IPT_START2 */ + result |= ((ioport("IN1")->read() & 0x400) >> 10) << 3; + /* PORT_SERVICE_NO_TOGGLE */ + result |= ((ioport("IN0")->read() & 0x8000) >> 15) << 6; + + return ~result; +} + + + +WRITE32_MEMBER(gstream_state::gstream_vram_w) +{ + COMBINE_DATA(&m_vram[offset]); +} + +WRITE32_MEMBER(gstream_state::gstream_tilemap1_scrollx_w) +{ + m_tmap1_scrollx = data; +} + +WRITE32_MEMBER(gstream_state::gstream_tilemap1_scrolly_w) +{ + m_tmap1_scrolly = data; +} + +WRITE32_MEMBER(gstream_state::gstream_tilemap2_scrollx_w) +{ + m_tmap2_scrollx = data; +} + +WRITE32_MEMBER(gstream_state::gstream_tilemap2_scrolly_w) +{ + m_tmap2_scrolly = data; +} + +WRITE32_MEMBER(gstream_state::gstream_tilemap3_scrollx_w) +{ + m_tmap3_scrollx = data; +} + +WRITE32_MEMBER(gstream_state::gstream_tilemap3_scrolly_w) +{ + m_tmap3_scrolly = data; +} + +static ADDRESS_MAP_START( gstream_32bit_map, AS_PROGRAM, 32, gstream_state ) + AM_RANGE(0x00000000, 0x003FFFFF) AM_RAM AM_SHARE("workram") // work ram +// AM_RANGE(0x40000000, 0x40FFFFFF) AM_RAM // ?? lots of data gets copied here if present, but game runs without it?? + AM_RANGE(0x80000000, 0x80003FFF) AM_RAM_WRITE(gstream_vram_w) AM_SHARE("vram") // video ram + AM_RANGE(0x4E000000, 0x4E1FFFFF) AM_ROM AM_REGION("user2",0) // main game rom + AM_RANGE(0x4F000000, 0x4F000003) AM_WRITE(gstream_tilemap3_scrollx_w) + AM_RANGE(0x4F200000, 0x4F200003) AM_WRITE(gstream_tilemap3_scrolly_w) + AM_RANGE(0x4F400000, 0x4F406FFF) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") + AM_RANGE(0x4F800000, 0x4F800003) AM_WRITE(gstream_tilemap1_scrollx_w) + AM_RANGE(0x4FA00000, 0x4FA00003) AM_WRITE(gstream_tilemap1_scrolly_w) + AM_RANGE(0x4FC00000, 0x4FC00003) AM_WRITE(gstream_tilemap2_scrollx_w) + AM_RANGE(0x4FE00000, 0x4FE00003) AM_WRITE(gstream_tilemap2_scrolly_w) + AM_RANGE(0xFFC00000, 0xFFC01FFF) AM_RAM AM_SHARE("nvram") // Backup RAM + AM_RANGE(0xFFF80000, 0xFFFFFFFF) AM_ROM AM_REGION("user1",0) // boot rom +ADDRESS_MAP_END + +WRITE32_MEMBER(gstream_state::gstream_oki_banking_w) +{ +/* + ****OKI BANKING**** + Possibly perfect? works perfectly in-game, may not cover all possibilities. + Needs code testing on PCB. + + The two OKIs can independently play music or samples, and have half of the + sound ROMs to themselves. Sometimes the first OKI will play music, and some + times it will play samples. The second OKI is the same way. The banks for + both OKIs are laid out like so: + + BANK MUSIC SAMPLES + 0 X + 1 X + 2 X + 3 X + + Bank 0 is the same in both ROMs. + + The banking seems to be concerned with half-nibbles in the data byte. For + OKI1, the half-nibbles are bits 76 and 32. For OKI2, 54 and 10. + The bank's '2' bit is the first half-nibble's bottom bit bitwise AND with + the inverse of its top bit. The bank's '1' bit is the second half-nibble's + bottom bit bitwise AND with the top bit. + + This may or may not be correct, but further PCB tests are required, and it + certainly sounds perfect in-game, without using any "hacks". */ + +/* +7654 3210 +1010 1010 needs oki2 to be bank 0 +1010 1011 needs oki2 to be bank 1 +1010 1011 needs oki1 to be bank 0 + +7654 3210 +1010 1111 needs oki1 to be bank 1 +1010 1110 needs oki1 to be bank 1 +1010 1110 needs oki2 to be bank 0 + +7654 3210 +0110 0110 needs oki1 to be bank 2 +0110 0110 needs oki2 to be bank 0 + +6and!7 & 2and3 + +4and!5 & 0and1 + +*/ + + m_oki_bank_1 = ((BIT(data, 6) & !BIT(data, 7)) << 1) | (BIT(data, 2) & BIT(data, 3)); + m_oki_bank_2 = ((BIT(data, 4) & !BIT(data, 5)) << 1) | (BIT(data, 0) & BIT(data, 1)); + + //popmessage("oki bank = %X\noki_1 = %X\noki_2 = %X\n",data, m_oki_bank_1, m_oki_bank_2); + + m_oki_1->set_bank_base(m_oki_bank_1 * 0x40000); + m_oki_2->set_bank_base(m_oki_bank_2 * 0x40000); +} + +// Some clocking? +WRITE32_MEMBER(gstream_state::gstream_oki_4040_w) +{ + // data == 0 or data == 0x81 +} + +static ADDRESS_MAP_START( gstream_io, AS_IO, 32, gstream_state ) + 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_banking_w) // oki banking + AM_RANGE(0x4040, 0x4043) AM_WRITE(gstream_oki_4040_w) // some clocking? + AM_RANGE(0x4050, 0x4053) AM_DEVREADWRITE8("oki1", okim6295_device, read, write, 0x000000ff) // music and samples + AM_RANGE(0x4060, 0x4063) AM_DEVREADWRITE8("oki2", okim6295_device, read, write, 0x000000ff) // music and samples +ADDRESS_MAP_END + + +static ADDRESS_MAP_START( x2222_32bit_map, AS_PROGRAM, 32, gstream_state ) + AM_RANGE(0x00000000, 0x003FFFFF) AM_RAM AM_SHARE("workram") // work ram + AM_RANGE(0x40000000, 0x403fffff) AM_RAM // ?? data gets copied here if present, but game runs without it?? + AM_RANGE(0x80000000, 0x80003FFF) AM_RAM_WRITE(gstream_vram_w) AM_SHARE("vram") // video ram + + AM_RANGE(0x4Fc00000, 0x4Fc00003) AM_WRITE(gstream_tilemap2_scrolly_w) + AM_RANGE(0x4Fd00000, 0x4Fd00003) AM_WRITE(gstream_tilemap2_scrollx_w) + + AM_RANGE(0x4Fa00000, 0x4Fa00003) AM_WRITE(gstream_tilemap3_scrolly_w) + AM_RANGE(0x4Fb00000, 0x4Fb00003) AM_WRITE(gstream_tilemap3_scrollx_w) + + AM_RANGE(0x4Fe00000, 0x4Fe00003) AM_WRITE(gstream_tilemap1_scrolly_w) + AM_RANGE(0x4Ff00000, 0x4Ff00003) AM_WRITE(gstream_tilemap1_scrollx_w) + + AM_RANGE(0xFFC00000, 0xFFC01FFF) AM_RAM AM_SHARE("nvram") // Backup RAM (maybe) + AM_RANGE(0xFFF00000, 0xFFFFFFFF) AM_ROM AM_REGION("user1",0) // boot rom +ADDRESS_MAP_END + +WRITE32_MEMBER(gstream_state::x2222_sound_w) +{ + // maybe sound in low 8-bits? but we have no samples anyway assuming it's an OKI + if (data & 0xffffff00) + printf("x2222_sound_w unk %08x\n", data); +} + +static ADDRESS_MAP_START( x2222_io, AS_IO, 32, gstream_state ) + AM_RANGE(0x4000, 0x4003) AM_READ_PORT("P1") + AM_RANGE(0x4004, 0x4007) AM_READ_PORT("P2") + AM_RANGE(0x4008, 0x400b) AM_READ_PORT("SYS") + AM_RANGE(0x4010, 0x4013) AM_READ_PORT("DSW") + AM_RANGE(0x4028, 0x402b) AM_WRITE( x2222_sound_w ) + AM_RANGE(0x4034, 0x4037) AM_READ_PORT("IN4") +ADDRESS_MAP_END + +static INPUT_PORTS_START( gstream ) + PORT_START("IN0") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_SERVICE1 ) + PORT_BIT( 0x7000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_SERVICE_NO_TOGGLE( 0x8000, IP_ACTIVE_LOW ) + + PORT_START("IN1") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_START2 ) + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_SERVICE2 ) + PORT_BIT( 0x7000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, gstream_state,gstream_mirror_service_r, NULL) + + PORT_START("IN2") + PORT_BIT( 0x004f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, gstream_state,gstream_mirror_r, NULL) + PORT_BIT( 0xffb0, IP_ACTIVE_LOW, IPT_UNUSED ) +INPUT_PORTS_END + + +static INPUT_PORTS_START( x2222 ) + PORT_START("P1") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("P2") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("SYS") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_DIPNAME( 0x0002, 0x0002, "IN1" ) + PORT_DIPSETTING( 0x0002, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_START2 ) + PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0010, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0020, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0040, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0080, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + + PORT_START("DSW") + PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Free_Play ) ) // always 99 credits + PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0006, 0x0004, DEF_STR( Difficulty ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0x0004, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x0002, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x0006, DEF_STR( Very_Hard ) ) + PORT_DIPNAME( 0x0018, 0x0008, DEF_STR( Lives ) ) + PORT_DIPSETTING( 0x0000, "1" ) + PORT_DIPSETTING( 0x0008, "2" ) + PORT_DIPSETTING( 0x0010, "3" ) + PORT_DIPSETTING( 0x0018, "4" ) + PORT_DIPNAME( 0x00e0, 0x0000, DEF_STR( Coin_A ) ) + PORT_DIPSETTING( 0x0020, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x0040, "2" ) + PORT_DIPSETTING( 0x0060, "3" ) + PORT_DIPSETTING( 0x0080, "4" ) + PORT_DIPSETTING( 0x00a0, "5" ) + PORT_DIPSETTING( 0x00c0, "6" ) + PORT_DIPSETTING( 0x00e0, "7" ) + + PORT_START("IN4") + PORT_DIPNAME( 0x0001, 0x0001, "IN4" ) + PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0002, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0004, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0008, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0010, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0020, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0040, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, gstream_state,x2222_toggle_r, NULL) +INPUT_PORTS_END + + +static const gfx_layout layout16x16 = +{ + 16,16, + RGN_FRAC(1,1), + 8, + { 0,1,2,3,4,5,6,7 }, + { 0,8,16,24, 32,40,48,56, 64,72,80,88 ,96,104,112,120 }, + { 0*128, 1*128, 2*128, 3*128, 4*128, 5*128, 6*128, 7*128, 8*128,9*128,10*128,11*128,12*128,13*128,14*128,15*128 }, + 16*128, +}; + + +static const gfx_layout layout32x32 = +{ + 32,32, + RGN_FRAC(1,1), + 8, + { 0,1,2,3,4,5,6,7 }, + { 0, 8, 16, 24, 32, 40, 48, 56, + 64, 72, 80, 88, 96, 104, 112, 120, + 128, 136, 144, 152, 160, 168, 176, 184, + 192, 200, 208, 216, 224, 232, 240, 248 }, + { 0*256, 1*256, 2*256, 3*256, 4*256, 5*256, 6*256, 7*256, + 8*256, 9*256, 10*256, 11*256, 12*256, 13*256, 14*256, 15*256, + 16*256, 17*256, 18*256, 19*256, 20*256, 21*256, 22*256, 23*256, + 24*256, 25*256, 26*256, 27*256, 28*256, 29*256, 30*256, 31*256, + }, + 32*256, +}; + +static GFXDECODE_START( gstream ) + GFXDECODE_ENTRY( "gfx2", 0, layout32x32, 0, 0x80 ) + GFXDECODE_ENTRY( "gfx3", 0, layout32x32, 0, 0x80 ) + GFXDECODE_ENTRY( "gfx4", 0, layout32x32, 0, 0x80 ) + GFXDECODE_ENTRY( "gfx1", 0, layout16x16, 0, 0x80 ) +GFXDECODE_END + + +static GFXDECODE_START( x2222 ) + GFXDECODE_ENTRY( "gfx2", 0, layout32x32, 0, 0x80 ) + GFXDECODE_ENTRY( "gfx3", 0, layout32x32, 0, 0x80 ) + GFXDECODE_ENTRY( "gfx4", 0, layout32x32, 0, 0x80 ) + GFXDECODE_ENTRY( "gfx1", 0, layout16x16, 0, 0x80 ) + GFXDECODE_ENTRY( "gfx1_lower", 0, layout16x16, 0, 0x80 ) + GFXDECODE_ENTRY( "gfx2_lower", 0, layout32x32, 0, 0x80 ) + GFXDECODE_ENTRY( "gfx3_lower", 0, layout32x32, 0, 0x80 ) + GFXDECODE_ENTRY( "gfx4_lower", 0, layout32x32, 0, 0x80 ) +GFXDECODE_END + + +void gstream_state::video_start() +{ +} + + + +// custom drawgfx function for x2222 to draw RGB data instead of indexed data, needed because our regular drawgfx and tilemap code don't support that +void drawgfx_transpen_x2222(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,gfx_element *gfx2, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 transpen) +{ + // use pen usage to optimize + code %= gfx->elements(); + + // render + + do { + g_profiler.start(PROFILER_DRAWGFX); + do { + const UINT8 *srcdata, *srcdata2; + INT32 destendx, destendy; + INT32 srcx, srcy; + INT32 curx, cury; + INT32 dy; + + assert(dest.valid()); + assert(gfx != NULL); + assert(dest.cliprect().contains(cliprect)); + assert(code < gfx->elements()); + + /* ignore empty/invalid cliprects */ + if (cliprect.empty()) + break; + + /* compute final pixel in X and exit if we are entirely clipped */ + destendx = destx + gfx->width() - 1; + if (destx > cliprect.max_x || destendx < cliprect.min_x) + break; + + /* apply left clip */ + srcx = 0; + if (destx < cliprect.min_x) + { + srcx = cliprect.min_x - destx; + destx = cliprect.min_x; + } + + /* apply right clip */ + if (destendx > cliprect.max_x) + destendx = cliprect.max_x; + + /* compute final pixel in Y and exit if we are entirely clipped */ + destendy = desty + gfx->height() - 1; + if (desty > cliprect.max_y || destendy < cliprect.min_y) + break; + + /* apply top clip */ + srcy = 0; + if (desty < cliprect.min_y) + { + srcy = cliprect.min_y - desty; + desty = cliprect.min_y; + } + + /* apply bottom clip */ + if (destendy > cliprect.max_y) + destendy = cliprect.max_y; + + /* apply X flipping */ + if (flipx) + srcx = gfx->width() - 1 - srcx; + + /* apply Y flipping */ + dy = gfx->rowbytes(); + if (flipy) + { + srcy = gfx->height() - 1 - srcy; + dy = -dy; + } + + /* fetch the source data */ + srcdata = gfx->get_data(code); + srcdata2 = gfx2->get_data(code); + + /* compute how many blocks of 4 pixels we have */ + UINT32 leftovers = (destendx + 1 - destx); + + /* adjust srcdata to point to the first source pixel of the row */ + srcdata += srcy * gfx->rowbytes() + srcx; + srcdata2 += srcy * gfx->rowbytes() + srcx; + + /* non-flipped 8bpp case */ + if (!flipx) + { + /* iterate over pixels in Y */ + for (cury = desty; cury <= destendy; cury++) + { + UINT32 *destptr = &dest.pixt<UINT32>(cury, destx); + const UINT8 *srcptr = srcdata; + const UINT8 *srcptr2 = srcdata2; + srcdata += dy; + srcdata2 += dy; + + + + /* iterate over leftover pixels */ + for (curx = 0; curx < leftovers; curx++) + { + UINT32 srcdata = (srcptr[0]); + UINT32 srcdata2 = (srcptr2[0]); + + UINT32 fullval = (srcdata | (srcdata2 << 8)); + UINT32 r = ((fullval >> 0) & 0x1f) << 3; + UINT32 g = ((fullval >> 5) & 0x3f) << 2; + UINT32 b = ((fullval >> 11) & 0x1f) << 3; + UINT32 full = (r << 16) | (g << 8) | (b << 0); + if (full != 0) + destptr[0] = full; + + srcptr++; + srcptr2++; + destptr++; + } + } + } + + /* flipped 8bpp case */ + else + { + /* iterate over pixels in Y */ + for (cury = desty; cury <= destendy; cury++) + { + UINT32 *destptr = &dest.pixt<UINT32>(cury, destx); + const UINT8 *srcptr = srcdata; + const UINT8 *srcptr2 = srcdata2; + + srcdata += dy; + srcdata2 += dy; + + /* iterate over leftover pixels */ + for (curx = 0; curx < leftovers; curx++) + { + UINT32 srcdata = (srcptr[0]); + UINT32 srcdata2 = (srcptr2[0]); + + UINT32 fullval = (srcdata | (srcdata2 << 8)); + UINT32 r = ((fullval >> 0) & 0x1f) << 3; + UINT32 g = ((fullval >> 5) & 0x3f) << 2; + UINT32 b = ((fullval >> 11) & 0x1f) << 3; + UINT32 full = (r << 16) | (g << 8) | (b << 0); + if (full != 0) + destptr[0] = full; + + srcptr--; + srcptr2--; + destptr++; + } + } + } + } while (0); + g_profiler.stop(); + } while (0); +} + +void gstream_state::draw_bg_gstream(bitmap_rgb32 &bitmap, const rectangle &cliprect, int xscrl, int yscrl, int map, UINT32* ram, int palbase ) +{ + int scrollx; + int scrolly; + + scrollx = xscrl&0x1ff; + scrolly = yscrl&0x1ff; + + UINT16 basey = scrolly>>5; + for (int y=0;y<13;y++) + { + UINT16 basex = scrollx>>5; + for (int x=0;x<16;x++) + { + int vram_data = (ram[(basex&0x0f)+((basey&0x0f)*0x10)]); + int pal = (vram_data & 0xc0000000) >> 30; + int code = (vram_data & 0x0fff0000) >> 16; + + pal += palbase; + + if (m_gfxdecode->gfx(map+5)) + drawgfx_transpen_x2222(bitmap,cliprect,m_gfxdecode->gfx(map),m_gfxdecode->gfx(map+5),code,0,0,0,(x*32)-(scrollx&0x1f)-m_xoffset,(y*32)-(scrolly&0x1f),0); + else + m_gfxdecode->gfx(map)->transpen(bitmap,cliprect,code,pal,0,0,(x*32)-(scrollx&0x1f)-m_xoffset,(y*32)-(scrolly&0x1f),0); + + basex++; + } + basey++; + } +} + +UINT32 gstream_state::screen_update_gstream(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + /* The tilemaps and sprite are interleaved together. + Even Words are tilemap tiles + Odd Words are sprite data + + Sprites start at the top of memory, tilemaps at + the bottom, but the areas can overlap + + *What seems an actual game bug* + when a sprite ends up with a negative co-ordinate + a value of 0xfffffffe gets set in the sprite list. + this could corrupt the tile value as both words + are being set ?! + + x2222 seems to set none of these bits but has other wraparound issues + + */ + + int i; + + //popmessage("(1) %08x %08x (2) %08x %08x (3) %08x %08x", m_tmap1_scrollx, m_tmap1_scrolly, m_tmap2_scrollx, m_tmap2_scrolly, m_tmap3_scrollx, m_tmap3_scrolly ); + bitmap.fill(0,cliprect); + + + draw_bg_gstream(bitmap, cliprect, m_tmap3_scrollx >> 16, m_tmap3_scrolly >> 16, 2, m_vram + 0x800/4, 0x18); + draw_bg_gstream(bitmap, cliprect, m_tmap2_scrollx >> 16, m_tmap2_scrolly >> 16, 1, m_vram + 0x400/4, 0x14); + draw_bg_gstream(bitmap, cliprect, m_tmap1_scrollx >> 16, m_tmap1_scrolly >> 16, 0, m_vram + 0x000/4, 0x10); // move on top for x2222 , check + + + for (i = 0x0000 / 4; i < 0x4000 / 4; i += 4) + { + /* Upper bits are used by the tilemaps */ + int code = m_vram[i + 0] & 0xffff; + int x = m_vram[i + 1] & 0x1ff; + int y = m_vram[i + 2] & 0xff; + int col = m_vram[i + 3] & 0x1f; + + if (m_gfxdecode->gfx(4)) + { + drawgfx_transpen_x2222(bitmap, cliprect, m_gfxdecode->gfx(3), m_gfxdecode->gfx(4), code, col, 0, 0, x - m_xoffset, y, 0); + drawgfx_transpen_x2222(bitmap, cliprect, m_gfxdecode->gfx(3), m_gfxdecode->gfx(4), code, col, 0, 0, x - m_xoffset, y-0x100, 0); + drawgfx_transpen_x2222(bitmap, cliprect, m_gfxdecode->gfx(3), m_gfxdecode->gfx(4), code, col, 0, 0, x - m_xoffset - 0x200, y, 0); + drawgfx_transpen_x2222(bitmap, cliprect, m_gfxdecode->gfx(3), m_gfxdecode->gfx(4), code, col, 0, 0, x - m_xoffset - 0x200 , y-0x100, 0); + + } + else + { + m_gfxdecode->gfx(3)->transpen(bitmap, cliprect, code, col, 0, 0, x - m_xoffset, y, 0); + m_gfxdecode->gfx(3)->transpen(bitmap, cliprect, code, col, 0, 0, x - m_xoffset, y-0x100, 0); + m_gfxdecode->gfx(3)->transpen(bitmap, cliprect, code, col, 0, 0, x - m_xoffset - 0x200, y, 0); + m_gfxdecode->gfx(3)->transpen(bitmap, cliprect, code, col, 0, 0, x - m_xoffset - 0x200, y-0x100, 0); + + } + } + return 0; +} + + +void gstream_state::machine_start() +{ + save_item(NAME(m_tmap1_scrollx)); + save_item(NAME(m_tmap2_scrollx)); + save_item(NAME(m_tmap3_scrollx)); + save_item(NAME(m_tmap1_scrolly)); + save_item(NAME(m_tmap2_scrolly)); + save_item(NAME(m_tmap3_scrolly)); + save_item(NAME(m_oki_bank_1)); + save_item(NAME(m_oki_bank_2)); +} + +void gstream_state::machine_reset() +{ + m_tmap1_scrollx = 0; + m_tmap2_scrollx = 0; + m_tmap3_scrollx = 0; + m_tmap1_scrolly = 0; + m_tmap2_scrolly = 0; + m_tmap3_scrolly = 0; + m_oki_bank_1 = 0; + m_oki_bank_2 = 0; +} + +static MACHINE_CONFIG_START( gstream, gstream_state ) + + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", E132XT, 16000000*4) /* 4x internal multiplier */ + MCFG_CPU_PROGRAM_MAP(gstream_32bit_map) + MCFG_CPU_IO_MAP(gstream_io) + MCFG_CPU_VBLANK_INT_DRIVER("screen", gstream_state, irq0_line_hold) + + + MCFG_NVRAM_ADD_1FILL("nvram") + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) + MCFG_SCREEN_SIZE(320, 240) + MCFG_SCREEN_VISIBLE_AREA(0, 319, 0, 239) + MCFG_SCREEN_UPDATE_DRIVER(gstream_state, screen_update_gstream) + + MCFG_PALETTE_ADD("palette", 0x1000 + 0x400 + 0x400 + 0x400) // sprites + 3 bg layers + MCFG_PALETTE_FORMAT(BBBBBGGGGGGRRRRR) + + + MCFG_GFXDECODE_ADD("gfxdecode", "palette", gstream) + + + MCFG_SPEAKER_STANDARD_MONO("mono") + + MCFG_OKIM6295_ADD("oki1", 1000000, OKIM6295_PIN7_HIGH) /* 1 Mhz? */ + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) + + MCFG_OKIM6295_ADD("oki2", 1000000, OKIM6295_PIN7_HIGH) /* 1 Mhz? */ + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_START( x2222, gstream_state ) + + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", E132XT, 16000000*4) /* 4x internal multiplier */ + MCFG_CPU_PROGRAM_MAP(x2222_32bit_map) + MCFG_CPU_IO_MAP(x2222_io) + MCFG_CPU_VBLANK_INT_DRIVER("screen", gstream_state, irq0_line_hold) + + +// MCFG_NVRAM_ADD_1FILL("nvram") + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) + MCFG_SCREEN_SIZE(320, 240) + MCFG_SCREEN_VISIBLE_AREA(0, 319, 0, 239) + MCFG_SCREEN_UPDATE_DRIVER(gstream_state, screen_update_gstream) + + MCFG_PALETTE_ADD("palette", 0x1000 + 0x400 + 0x400 + 0x400) // doesn't use a palette, but keep fake gfxdecode happy + MCFG_GFXDECODE_ADD("gfxdecode", "palette", x2222) + + // unknown sound hw (no sound roms dumped) + + MCFG_SPEAKER_STANDARD_MONO("mono") + + MCFG_OKIM6295_ADD("oki1", 1000000, OKIM6295_PIN7_HIGH) /* 1 Mhz? */ + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) +MACHINE_CONFIG_END + + +ROM_START( gstream ) + ROM_REGION32_BE( 0x80000, "user1", 0 ) /* Hyperstone CPU Code */ + ROM_LOAD( "gs_prg_01.u56", 0x000000, 0x080000, CRC(0d0c6a38) SHA1(a810bfc1c9158cccc37710d0ea7268e26e520cc2) ) + + ROM_REGION32_BE( 0x200000, "user2", 0 ) /* Hyperstone CPU Code */ + ROM_LOAD16_WORD_SWAP( "gs_prg_02.u197", 0x000000, 0x200000, CRC(2f8a6bea) SHA1(c0a32838f4bd8599f09002139f87562db625c1c5) ) + + ROM_REGION( 0x1000000, "gfx1", 0 ) /* sprite tiles (16x16x8) */ + ROM_LOAD32_WORD( "gs_gr_07.u107", 0x000000, 0x200000, CRC(84e66fe1) SHA1(73d828714f9ed9baffdc06998f5bf3298396fe9c) ) + ROM_LOAD32_WORD( "gs_gr_11.u108", 0x000002, 0x200000, CRC(946d71d1) SHA1(516bd3f4d7f5bce59f0593ed6565114dbd5a4ef0) ) + ROM_LOAD32_WORD( "gs_gr_08.u109", 0x400000, 0x200000, CRC(abd0d6aa) SHA1(dd294bbdda05697df84247257f735ab51bc26ca3) ) + ROM_LOAD32_WORD( "gs_gr_12.u110", 0x400002, 0x200000, CRC(94b56e4e) SHA1(7c3877f993e575326dbd4c2e5d7570747277b20d) ) + ROM_LOAD32_WORD( "gs_gr_09.u180", 0x800000, 0x200000, CRC(f2c4fd77) SHA1(284c850688e3c0fd292a91a53e24fe3436dc4076) ) + ROM_LOAD32_WORD( "gs_gr_13.u181", 0x800002, 0x200000, CRC(7daaeff0) SHA1(5766d9a3a8c0931305424e0089108ce8df7dfe41) ) + ROM_LOAD32_WORD( "gs_gr_10.u182", 0xc00000, 0x200000, CRC(d696d15d) SHA1(85aaa5cdb35f3a8d3266bb8debec0558c860cb53) ) + ROM_LOAD32_WORD( "gs_gr_14.u183", 0xc00002, 0x200000, CRC(6bd2a1e1) SHA1(aedca91643f14ececc101a7708255ce9b1d70f68) ) + + ROM_REGION( 0x400000, "gfx2", 0 ) /* bg tiles (32x32x8) */ + ROM_LOAD( "gs_gr_01.u120", 0x000000, 0x200000, CRC(b82cfab8) SHA1(08f0eaef5c927fb056c6cc9342e39f445aae9062) ) + ROM_LOAD( "gs_gr_02.u121", 0x200000, 0x200000, CRC(37e19cbd) SHA1(490ebb037fce09100ec4bba3f73ecdf101526641) ) + + ROM_REGION( 0x400000, "gfx3", 0 ) /* bg tiles (32x32x8) */ + ROM_LOAD( "gs_gr_03.u125", 0x000000, 0x200000, CRC(1a3b2b11) SHA1(a4b1dc1a9709f8f8f2ab2190d7badc246caa540f) ) + ROM_LOAD( "gs_gr_04.u126", 0x200000, 0x200000, CRC(a4e8906c) SHA1(b285d7697cdaa62014cf65d09a19fcbd6a95bb98) ) + + ROM_REGION( 0x400000, "gfx4", 0 ) /* bg tiles (32x32x8) */ + ROM_LOAD( "gs_gr_05.u174", 0x000000, 0x200000, CRC(ef283a73) SHA1(8b598facb344eac33138611abc141a2acb375983) ) + ROM_LOAD( "gs_gr_06.u175", 0x200000, 0x200000, CRC(d4e3a2b2) SHA1(4577c007172c718bf7ca55a8ccee5455c281026c) ) + + ROM_REGION( 0x100000, "oki1", 0 ) + ROM_LOAD( "gs_snd_01.u192", 0x000000, 0x080000, CRC(79b64d3f) SHA1(b2166210d3a3b85b9ace90749a444c881f69d551) ) + ROM_LOAD( "gs_snd_02.u194", 0x080000, 0x080000, CRC(e49ed92c) SHA1(a3d7b3fe93a786a246acf2657d9056398c793078) ) + + ROM_REGION( 0x100000, "oki2", 0 ) + ROM_LOAD( "gs_snd_03.u191", 0x000000, 0x080000, CRC(2bfff4ac) SHA1(cce1bb3c78b86722c926854c737f9589806012ba) ) + ROM_LOAD( "gs_snd_04.u193", 0x080000, 0x080000, CRC(b259de3b) SHA1(1a64f41d4344fefad5832332f1a7655e23f6b017) ) + + ROM_REGION( 0x2000, "nvram", 0 ) + ROM_LOAD( "gstream.nv", 0x000000, 0x2000, CRC(895d724b) SHA1(97941102f94923220d9beb270939f0ad9a40fe0e) ) +ROM_END + + + + +ROM_START( x2222 ) + ROM_REGION32_BE( 0x100000, "user1", 0 ) /* Hyperstone CPU Code */ + ROM_LOAD( "test.bin", 0x000000, 0x100000, CRC(6260421e) SHA1(095e955d029e98e024d4ec5c7f93a6d4845a92a0) ) // final version - but debug enabled, values on screen, maybe there's a flag in the ROM we can turn off? + + ROM_REGION32_BE( 0x0200000, "misc", 0 ) /* other code */ + ROM_LOAD( "test.hye", 0x000000, 0x0112dda, CRC(c1142b2f) SHA1(5807930820a53604013a6ac66e4d4ebe3628e1fc) ) // the above binary was built from this + + /* x2222 uses raw rgb16 data rather than 8bpp indexed, in order to use the same gfx decodes with a custom draw routine we arrange the data into 2 8bpp regions on init */ + ROM_REGION( 0x800000, "gfx1", ROMREGION_ERASE00 ) /* sprite tiles (16x16x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx2", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx3", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx4", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + /* 2nd 8-bits */ + ROM_REGION( 0x800000, "gfx1_lower", ROMREGION_ERASE00 ) /* sprite tiles (16x16x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx2_lower", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx3_lower", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx4_lower", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + ROM_REGION( 0x1000000, "sprites", 0 ) /* sprite tiles (16x16x16) */ + ROM_LOAD( "spr11.bin", 0x000000, 0x200000, CRC(1d15b444) SHA1(27ace509a7e4ec2e62453636acf444a861bb85ce) ) + ROM_LOAD( "spr21.bin", 0x200000, 0x1b8b00, CRC(1c392be2) SHA1(775882f588a8bef33a79fa4f25754a47dc82cb30) ) + ROM_LOAD( "spr12.bin", 0x400000, 0x200000, CRC(73225936) SHA1(50507c52b932198659e08d22d3c0a92e7c69e5ba) ) + ROM_LOAD( "spr22.bin", 0x600000, 0x1b8b00, CRC(cf7ebfa1) SHA1(c968dcf768e5598240f5a131414a5607899b4bef) ) + ROM_LOAD( "spr13.bin", 0x800000, 0x200000, CRC(52595c51) SHA1(a161a5f433aa7aa2f7824ea6b9b70d73ca63b62d) ) + ROM_LOAD( "spr23.bin", 0xa00000, 0x1b8b00, CRC(d894461e) SHA1(14dccfa8c762d928eaea0ac4cfff7d1272b69fdd) ) + ROM_LOAD( "spr14.bin", 0xc00000, 0x200000, CRC(f6cd6599) SHA1(170ea7a9a26fd8038df53fb333357766dabbe7c2) ) + ROM_LOAD( "spr24.bin", 0xe00000, 0x1b8b00, CRC(9542cb08) SHA1(d40c1f0b7d3e9deb12284c2f2c2df0ac43cb6cd2) ) + + ROM_REGION( 0x400000, "bg1", 0 ) /* bg tiles (32x32x16) */ + ROM_LOAD16_BYTE( "bg31.bin", 0x000000, 0x11ac00, CRC(12e67bc2) SHA1(18618a8931af3b3aeab34fd50424a7ffb3da6458) ) + ROM_LOAD16_BYTE( "bg32.bin", 0x000001, 0x11ac00, CRC(95afa0da) SHA1(e534bc0874329475ce7efa836000fe29fc76c44c) ) + + ROM_REGION( 0x400000, "bg2", 0 ) /* bg tiles (32x32x16) */ + ROM_LOAD16_BYTE( "bg21.bin", 0x000000, 0x1c8400, CRC(a10220f8) SHA1(9aa43a8e23cdf55d8623d2694b04971eaced9ba9) ) + ROM_LOAD16_BYTE( "bg22.bin", 0x000001, 0x1c8400, CRC(966f7c1d) SHA1(4699a3014c7e66d0dabd8d7982f43114b71181b7) ) + + ROM_REGION( 0x400000, "bg3", 0 ) /* bg tiles (32x32x16) */ + ROM_LOAD16_BYTE( "bg11.bin", 0x000000, 0x1bc800, CRC(68975462) SHA1(7a2458a3d2465b727f4f5bf45685f35eb4885975) ) + ROM_LOAD16_BYTE( "bg12.bin", 0x000001, 0x1bc800, CRC(feef1240) SHA1(9eb123a19ade74d8b3ce4df0b04ca97c03fb9fdc) ) + + // no idea what the sound hw is? + ROM_REGION( 0x100000, "oki1", ROMREGION_ERASE00 ) + ROM_LOAD( "x2222_sound", 0x000000, 0x080000,NO_DUMP ) // probably an oki.. is there a sound cpu too? +ROM_END + + + +ROM_START( x2222o ) + ROM_REGION32_BE( 0x100000, "user1", 0 ) /* Hyperstone CPU Code */ + ROM_LOAD( "older.bin", 0x080000, 0x080000, CRC(d12817bc) SHA1(2458f9d9020598a1646dfc848fddd323eebc5120) ) + + ROM_REGION32_BE( 0x0200000, "misc", 0 ) /* other code */ + ROM_LOAD( "older.hye", 0x000000, 0x010892f, CRC(cf3a004e) SHA1(1cba64cfa235b9540f33a5ee0cc02dfd267e00fc) ) // this corresponds to the older.bin we're using, for reference + + /* x2222 uses raw rgb16 data rather than 8bpp indexed, in order to use the same gfx decodes with a custom draw routine we arrange the data into 2 8bpp regions on init */ + ROM_REGION( 0x800000, "gfx1", ROMREGION_ERASE00 ) /* sprite tiles (16x16x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx2", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx3", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx4", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + /* 2nd 8-bits */ + ROM_REGION( 0x800000, "gfx1_lower", ROMREGION_ERASE00 ) /* sprite tiles (16x16x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx2_lower", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx3_lower", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + ROM_REGION( 0x200000, "gfx4_lower", ROMREGION_ERASE00 ) /* bg tiles (32x32x8) */ + /* filled in at init*/ + + ROM_REGION( 0x1000000, "sprites", 0 ) /* sprite tiles (16x16x16) */ // these sprite ROMs have the Boss tiles in the wrong location for the prototype program rom + ROM_LOAD( "spr11.bin", 0x000000, 0x200000, BAD_DUMP CRC(1d15b444) SHA1(27ace509a7e4ec2e62453636acf444a861bb85ce) ) + ROM_LOAD( "spr21.bin", 0x200000, 0x1b8b00, BAD_DUMP CRC(1c392be2) SHA1(775882f588a8bef33a79fa4f25754a47dc82cb30) ) + ROM_LOAD( "spr12.bin", 0x400000, 0x200000, BAD_DUMP CRC(73225936) SHA1(50507c52b932198659e08d22d3c0a92e7c69e5ba) ) + ROM_LOAD( "spr22.bin", 0x600000, 0x1b8b00, BAD_DUMP CRC(cf7ebfa1) SHA1(c968dcf768e5598240f5a131414a5607899b4bef) ) + ROM_LOAD( "spr13.bin", 0x800000, 0x200000, BAD_DUMP CRC(52595c51) SHA1(a161a5f433aa7aa2f7824ea6b9b70d73ca63b62d) ) + ROM_LOAD( "spr23.bin", 0xa00000, 0x1b8b00, BAD_DUMP CRC(d894461e) SHA1(14dccfa8c762d928eaea0ac4cfff7d1272b69fdd) ) + ROM_LOAD( "spr14.bin", 0xc00000, 0x200000, BAD_DUMP CRC(f6cd6599) SHA1(170ea7a9a26fd8038df53fb333357766dabbe7c2) ) + ROM_LOAD( "spr24.bin", 0xe00000, 0x1b8b00, BAD_DUMP CRC(9542cb08) SHA1(d40c1f0b7d3e9deb12284c2f2c2df0ac43cb6cd2) ) + + ROM_REGION( 0x400000, "bg1", 0 ) /* bg tiles (32x32x16) */ + ROM_LOAD16_BYTE( "bg31.bin", 0x000000, 0x11ac00, CRC(12e67bc2) SHA1(18618a8931af3b3aeab34fd50424a7ffb3da6458) ) + ROM_LOAD16_BYTE( "bg32.bin", 0x000001, 0x11ac00, CRC(95afa0da) SHA1(e534bc0874329475ce7efa836000fe29fc76c44c) ) + + ROM_REGION( 0x400000, "bg2", 0 ) /* bg tiles (32x32x16) */ + ROM_LOAD16_BYTE( "bg21.bin", 0x000000, 0x1c8400, CRC(a10220f8) SHA1(9aa43a8e23cdf55d8623d2694b04971eaced9ba9) ) + ROM_LOAD16_BYTE( "bg22.bin", 0x000001, 0x1c8400, CRC(966f7c1d) SHA1(4699a3014c7e66d0dabd8d7982f43114b71181b7) ) + + ROM_REGION( 0x400000, "bg3", 0 ) /* bg tiles (32x32x16) */ + ROM_LOAD16_BYTE( "bg11.bin", 0x000000, 0x1bc800, CRC(68975462) SHA1(7a2458a3d2465b727f4f5bf45685f35eb4885975) ) + ROM_LOAD16_BYTE( "bg12.bin", 0x000001, 0x1bc800, CRC(feef1240) SHA1(9eb123a19ade74d8b3ce4df0b04ca97c03fb9fdc) ) + + // no idea what the sound hw is? + ROM_REGION( 0x100000, "oki1", ROMREGION_ERASE00 ) + ROM_LOAD( "x2222_sound", 0x000000, 0x080000,NO_DUMP ) // probably an oki.. is there a sound cpu too? +ROM_END + + +READ32_MEMBER(gstream_state::gstream_speedup_r) +{ + if (m_maincpu->pc() == 0xc0001592) + { + m_maincpu->eat_cycles(50); + } + + return m_workram[0xd1ee0 / 4]; +} + + +READ32_MEMBER(gstream_state::x2222_speedup_r) +{ + if (m_maincpu->pc() == 0x22064) + { + m_maincpu->eat_cycles(50); + } + + return m_workram[0x7ffac / 4]; +} + +READ32_MEMBER(gstream_state::x2222_speedup2_r) +{ + if (m_maincpu->pc() == 0x23f44) + { + m_maincpu->eat_cycles(50); + } + + return m_workram[0x84e3c / 4]; +} + + +DRIVER_INIT_MEMBER(gstream_state,gstream) +{ + m_maincpu->space(AS_PROGRAM).install_read_handler(0xd1ee0, 0xd1ee3, read32_delegate(FUNC(gstream_state::gstream_speedup_r), this)); + + m_xoffset = 2; +} + + +void gstream_state::rearrange_tile_data(UINT8* ROM, UINT32* NEW, UINT32* NEW2) +{ + int i; + for (i = 0; i < 0x80000; i++) + { + NEW[i] = (ROM[(i * 8) + 0x000000] << 0) | (ROM[(i * 8) + 0x000001] << 8) | (ROM[(i * 8) + 0x000004] << 16) | (ROM[(i * 8) + 0x000005] << 24); + NEW2[i] = (ROM[(i * 8) + 0x000002] << 0) | (ROM[(i * 8) + 0x000003] << 8) | (ROM[(i * 8) + 0x000006] << 16) | (ROM[(i * 8) + 0x000007] << 24); + } +} + +void gstream_state::rearrange_sprite_data(UINT8* ROM, UINT32* NEW, UINT32* NEW2) +{ + int i; + for (i = 0; i < 0x200000; i++) + { + NEW[i] = (ROM[(i * 2) + 0xc00000] << 24) | (ROM[(i * 2) + 0x800000] << 16) | (ROM[(i * 2) + 0x400000] << 8) | (ROM[(i * 2) + 0x000000] << 0); + NEW2[i] = (ROM[(i * 2) + 0xc00001] << 24) | (ROM[(i * 2) + 0x800001] << 16) | (ROM[(i * 2) + 0x400001] << 8) | (ROM[(i * 2) + 0x000001] << 0); + } +} + +DRIVER_INIT_MEMBER(gstream_state,x2222) +{ + m_maincpu->space(AS_PROGRAM).install_read_handler(0x7ffac, 0x7ffaf, read32_delegate(FUNC(gstream_state::x2222_speedup_r), this)); // older + m_maincpu->space(AS_PROGRAM).install_read_handler(0x84e3c, 0x84e3f, read32_delegate(FUNC(gstream_state::x2222_speedup2_r), this)); // newer + + rearrange_sprite_data(memregion("sprites")->base(), (UINT32*)memregion("gfx1")->base(), (UINT32*)memregion("gfx1_lower")->base() ); + rearrange_tile_data(memregion("bg1")->base(), (UINT32*)memregion("gfx2")->base(), (UINT32*)memregion("gfx2_lower")->base()); + rearrange_tile_data(memregion("bg2")->base(), (UINT32*)memregion("gfx3")->base(), (UINT32*)memregion("gfx3_lower")->base()); + rearrange_tile_data(memregion("bg3")->base(), (UINT32*)memregion("gfx4")->base(), (UINT32*)memregion("gfx4_lower")->base()); + + m_xoffset = 0; +} + + +GAME( 2002, gstream, 0, gstream, gstream, gstream_state, gstream, ROT270, "Oriental Soft Japan", "G-Stream G2020", MACHINE_SUPPORTS_SAVE ) +GAME( 2000, x2222, 0, x2222, x2222, gstream_state, x2222, ROT270, "Oriental Soft / Promat", "X2222 (final debug?)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND ) +GAME( 2000, x2222o, x2222, x2222, x2222, gstream_state, x2222, ROT270, "Oriental Soft / Promat", "X2222 (5-level prototype)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND ) |