// 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" #include "screen.h" #include "speaker.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(*this, "oki%u", 1) , m_workram(*this, "workram") , m_vram(*this, "vram") , m_gfxdecode(*this, "gfxdecode") , m_palette(*this, "palette") { m_toggle = 0; } /* devices */ required_device m_maincpu; optional_device_array m_oki; /* memory pointers */ required_shared_ptr m_workram; required_shared_ptr m_vram; // uint32_t * m_nvram; // currently this uses generic nvram handling /* video-related */ uint32_t m_scrollx[3]; uint32_t m_scrolly[3]; /* misc */ int m_oki_bank[2]; int m_toggle; int m_xoffset; DECLARE_WRITE32_MEMBER(vram_w); template DECLARE_WRITE16_MEMBER(scrollx_w); template DECLARE_WRITE16_MEMBER(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); void init_gstream(); void init_x2222(); virtual void machine_start() override; virtual void machine_reset() override; virtual void video_start() override; uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void draw_bg(bitmap_rgb32 &bitmap, const rectangle &cliprect, int map, uint32_t* ram); void drawgfx_transpen_x2222(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,gfx_element *gfx2, uint32_t code, int flipx, int flipy, int32_t destx, int32_t desty); void rearrange_sprite_data(uint8_t* ROM, uint32_t* NEW, uint32_t* NEW2); void rearrange_tile_data(uint8_t* ROM, uint32_t* NEW, uint32_t* NEW2); required_device m_gfxdecode; required_device m_palette; void x2222(machine_config &config); void gstream(machine_config &config); void gstream_32bit_map(address_map &map); void gstream_io(address_map &map); void x2222_32bit_map(address_map &map); void x2222_io(address_map &map); }; 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::vram_w) { COMBINE_DATA(&m_vram[offset]); } template WRITE16_MEMBER(gstream_state::scrollx_w) { m_scrollx[Layer] = data; } template WRITE16_MEMBER(gstream_state::scrolly_w) { m_scrolly[Layer] = data; } void gstream_state::gstream_32bit_map(address_map &map) { map(0x00000000, 0x003fffff).ram().share("workram"); // work ram // map(0x40000000, 0x40ffffff).ram(); // ?? lots of data gets copied here if present, but game runs without it?? map(0x80000000, 0x80003fff).ram().w(this, FUNC(gstream_state::vram_w)).share("vram"); // video ram map(0x4E000000, 0x4e1fffff).rom().region("maindata", 0); // main game rom map(0x4f000000, 0x4f000003).w(this, FUNC(gstream_state::scrollx_w<2>)).umask32(0xffff0000).cswidth(32); map(0x4f200000, 0x4f200003).w(this, FUNC(gstream_state::scrolly_w<2>)).umask32(0xffff0000).cswidth(32); map(0x4f400000, 0x4f406fff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette"); map(0x4f800000, 0x4f800003).w(this, FUNC(gstream_state::scrollx_w<0>)).umask32(0xffff0000).cswidth(32); map(0x4fa00000, 0x4fa00003).w(this, FUNC(gstream_state::scrolly_w<0>)).umask32(0xffff0000).cswidth(32); map(0x4fc00000, 0x4fc00003).w(this, FUNC(gstream_state::scrollx_w<1>)).umask32(0xffff0000).cswidth(32); map(0x4fe00000, 0x4fe00003).w(this, FUNC(gstream_state::scrolly_w<1>)).umask32(0xffff0000).cswidth(32); map(0xffc00000, 0xffc01fff).ram().share("nvram"); // Backup RAM map(0xfff80000, 0xffffffff).rom().region("maincpu", 0); // boot rom } 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[0] = ((BIT(data, 6) & ~BIT(data, 7)) << 1) | (BIT(data, 2) & BIT(data, 3)); m_oki_bank[1] = ((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[0], m_oki_bank[1]); m_oki[0]->set_rom_bank(m_oki_bank[0]); m_oki[1]->set_rom_bank(m_oki_bank[1]); } // Some clocking? WRITE32_MEMBER(gstream_state::gstream_oki_4040_w) { // data == 0 or data == 0x81 } void gstream_state::gstream_io(address_map &map) { map(0x4000, 0x4003).portr("IN0"); map(0x4010, 0x4013).portr("IN1"); map(0x4020, 0x4023).portr("IN2"); // extra coin switches etc map(0x4030, 0x4033).w(this, FUNC(gstream_state::gstream_oki_banking_w)); // oki banking map(0x4040, 0x4043).w(this, FUNC(gstream_state::gstream_oki_4040_w)); // some clocking? map(0x4053, 0x4053).rw(m_oki[0], FUNC(okim6295_device::read), FUNC(okim6295_device::write)); // music and samples map(0x4063, 0x4063).rw(m_oki[1], FUNC(okim6295_device::read), FUNC(okim6295_device::write)); // music and samples } void gstream_state::x2222_32bit_map(address_map &map) { map(0x00000000, 0x003fffff).ram().share("workram"); // work ram map(0x40000000, 0x403fffff).ram(); // ?? data gets copied here if present, but game runs without it?? map(0x80000000, 0x80003fff).ram().w(this, FUNC(gstream_state::vram_w)).share("vram"); // video ram map(0x4fc00000, 0x4fc00003).w(this, FUNC(gstream_state::scrolly_w<1>)).umask32(0xffff0000).cswidth(32); map(0x4fd00000, 0x4fd00003).w(this, FUNC(gstream_state::scrollx_w<1>)).umask32(0xffff0000).cswidth(32); map(0x4fa00000, 0x4fa00003).w(this, FUNC(gstream_state::scrolly_w<2>)).umask32(0xffff0000).cswidth(32); map(0x4fb00000, 0x4fb00003).w(this, FUNC(gstream_state::scrollx_w<2>)).umask32(0xffff0000).cswidth(32); map(0x4fe00000, 0x4fe00003).w(this, FUNC(gstream_state::scrolly_w<0>)).umask32(0xffff0000).cswidth(32); map(0x4ff00000, 0x4ff00003).w(this, FUNC(gstream_state::scrollx_w<0>)).umask32(0xffff0000).cswidth(32); map(0xffc00000, 0xffc01fff).ram().share("nvram"); // Backup RAM (maybe) map(0xfff00000, 0xffffffff).rom().region("maincpu", 0); // boot rom } 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); } void gstream_state::x2222_io(address_map &map) { map(0x4000, 0x4003).portr("P1"); map(0x4004, 0x4007).portr("P2"); map(0x4008, 0x400b).portr("SYS"); map(0x4010, 0x4013).portr("DSW"); map(0x4028, 0x402b).w(this, FUNC(gstream_state::x2222_sound_w)); map(0x4034, 0x4037).portr("IN4"); } 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_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, gstream_state,gstream_mirror_service_r, nullptr) PORT_START("IN2") PORT_BIT( 0x004f, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, gstream_state,gstream_mirror_r, nullptr) 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_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, gstream_state,x2222_toggle_r, nullptr) INPUT_PORTS_END static const gfx_layout layout16x16 = { 16,16, RGN_FRAC(1,1), 8, { STEP8(0,1) }, { STEP16(0,8) }, { STEP16(0,8*16) }, 16*16*8, }; static const gfx_layout layout32x32 = { 32,32, RGN_FRAC(1,1), 8, { STEP8(0,1) }, { STEP32(0,8) }, { STEP32(0,8*32) }, 32*32*8, }; static GFXDECODE_START( gfx_gstream ) GFXDECODE_ENTRY( "gfx2", 0, layout32x32, 0x1000, 4 ) GFXDECODE_ENTRY( "gfx3", 0, layout32x32, 0x1400, 4 ) GFXDECODE_ENTRY( "gfx4", 0, layout32x32, 0x1800, 4 ) GFXDECODE_ENTRY( "gfx1", 0, layout16x16, 0, 32 ) GFXDECODE_END static GFXDECODE_START( gfx_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 gstream_state::drawgfx_transpen_x2222(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,gfx_element *gfx2, uint32_t code, int flipx, int flipy, int32_t destx, int32_t desty) { // use pen usage to optimize code %= gfx->elements(); const pen_t *rgb = m_palette->pens(); // 16 bit BGR // render do { g_profiler.start(PROFILER_DRAWGFX); do { const uint8_t *srcdata, *srcdata2; int32_t destendx, destendy; int32_t srcx, srcy; int32_t curx, cury; int32_t dy; assert(dest.valid()); assert(gfx != nullptr); 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_t 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 16bpp case */ if (!flipx) { /* iterate over pixels in Y */ for (cury = desty; cury <= destendy; cury++) { uint32_t *destptr = &dest.pix32(cury, destx); const uint8_t *srcptr = srcdata; const uint8_t *srcptr2 = srcdata2; srcdata += dy; srcdata2 += dy; /* iterate over leftover pixels */ for (curx = 0; curx < leftovers; curx++) { uint32_t srcdata = (srcptr[0]); uint32_t srcdata2 = (srcptr2[0]); uint16_t full = (srcdata | (srcdata2 << 8)); if (full != 0) destptr[0] = rgb[full]; srcptr++; srcptr2++; destptr++; } } } /* flipped 16bpp case */ else { /* iterate over pixels in Y */ for (cury = desty; cury <= destendy; cury++) { uint32_t *destptr = &dest.pix32(cury, destx); const uint8_t *srcptr = srcdata; const uint8_t *srcptr2 = srcdata2; srcdata += dy; srcdata2 += dy; /* iterate over leftover pixels */ for (curx = 0; curx < leftovers; curx++) { uint32_t srcdata = (srcptr[0]); uint32_t srcdata2 = (srcptr2[0]); uint16_t full = (srcdata | (srcdata2 << 8)); if (full != 0) destptr[0] = rgb[full]; srcptr--; srcptr2--; destptr++; } } } } while (0); g_profiler.stop(); } while (0); } void gstream_state::draw_bg(bitmap_rgb32 &bitmap, const rectangle &cliprect, int map, uint32_t* ram ) { int scrollx; int scrolly; scrollx = m_scrollx[map]&0x1ff; scrolly = m_scrolly[map]&0x1ff; uint16_t basey = scrolly>>5; for (int y=0;y<13;y++) { uint16_t basex = scrollx>>5; for (int x=0;x<16;x++) { int vram_data = (ram[(basex&0x0f)+((basey&0x0f)*0x10)]) >> 16; int pal = (vram_data & 0xc000) >> 14; int code = (vram_data & 0x0fff); if (m_gfxdecode->gfx(map+5)) drawgfx_transpen_x2222(bitmap,cliprect,m_gfxdecode->gfx(map),m_gfxdecode->gfx(map+5),code,0,0,(x*32)-(scrollx&0x1f)-m_xoffset,(y*32)-(scrolly&0x1f)); 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_t gstream_state::screen_update(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_scrollx[0], m_scrolly[0], m_scrollx[1], m_scrolly[1], m_scrollx[2], m_scrolly[2] ); bitmap.fill(0,cliprect); draw_bg(bitmap, cliprect, 2, m_vram + 0x800/4); draw_bg(bitmap, cliprect, 1, m_vram + 0x400/4); draw_bg(bitmap, cliprect, 0, m_vram + 0x000/4); // 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, 0, 0, x - m_xoffset, y); drawgfx_transpen_x2222(bitmap, cliprect, m_gfxdecode->gfx(3), m_gfxdecode->gfx(4), code, 0, 0, x - m_xoffset, y-0x100); drawgfx_transpen_x2222(bitmap, cliprect, m_gfxdecode->gfx(3), m_gfxdecode->gfx(4), code, 0, 0, x - m_xoffset - 0x200, y); drawgfx_transpen_x2222(bitmap, cliprect, m_gfxdecode->gfx(3), m_gfxdecode->gfx(4), code, 0, 0, x - m_xoffset - 0x200 , y-0x100); } 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_scrollx)); save_item(NAME(m_scrolly)); save_item(NAME(m_oki_bank)); } void gstream_state::machine_reset() { m_scrollx[0] = 0; m_scrollx[1] = 0; m_scrollx[2] = 0; m_scrolly[0] = 0; m_scrolly[1] = 0; m_scrolly[2] = 0; m_oki_bank[0] = m_oki_bank[1] = 0; } MACHINE_CONFIG_START(gstream_state::gstream) /* basic machine hardware */ MCFG_DEVICE_ADD("maincpu", E132XT, 16000000*4) /* 4x internal multiplier */ MCFG_DEVICE_PROGRAM_MAP(gstream_32bit_map) MCFG_DEVICE_IO_MAP(gstream_io) MCFG_DEVICE_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) MCFG_PALETTE_ADD("palette", 0x1000 + 0x400 + 0x400 + 0x400) // sprites + 3 bg layers MCFG_PALETTE_FORMAT(BBBBBGGGGGGRRRRR) MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_gstream) SPEAKER(config, "mono").front_center(); MCFG_DEVICE_ADD("oki1", OKIM6295, 1000000, okim6295_device::PIN7_HIGH) /* 1 Mhz? */ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) MCFG_DEVICE_ADD("oki2", OKIM6295, 1000000, okim6295_device::PIN7_HIGH) /* 1 Mhz? */ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) MACHINE_CONFIG_END MACHINE_CONFIG_START(gstream_state::x2222) /* basic machine hardware */ MCFG_DEVICE_ADD("maincpu", E132XT, 16000000*4) /* 4x internal multiplier */ MCFG_DEVICE_PROGRAM_MAP(x2222_32bit_map) MCFG_DEVICE_IO_MAP(x2222_io) MCFG_DEVICE_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) MCFG_PALETTE_ADD_BBBBBGGGGGGRRRRR("palette") MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_x2222) // unknown sound hw (no sound roms dumped) SPEAKER(config, "mono").front_center(); MCFG_DEVICE_ADD("oki1", OKIM6295, 1000000, okim6295_device::PIN7_HIGH) /* 1 Mhz? */ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) MACHINE_CONFIG_END ROM_START( gstream ) ROM_REGION32_BE( 0x80000, "maincpu", 0 ) /* Hyperstone CPU Code */ ROM_LOAD( "gs_prg_01.u56", 0x000000, 0x080000, CRC(0d0c6a38) SHA1(a810bfc1c9158cccc37710d0ea7268e26e520cc2) ) ROM_REGION32_BE( 0x200000, "maindata", 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, "maincpu", 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, "maincpu", 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]; } void gstream_state::init_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_t* ROM, uint32_t* NEW, uint32_t* 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_t* ROM, uint32_t* NEW, uint32_t* 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); } } void gstream_state::init_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_t*)memregion("gfx1")->base(), (uint32_t*)memregion("gfx1_lower")->base() ); rearrange_tile_data(memregion("bg1")->base(), (uint32_t*)memregion("gfx2")->base(), (uint32_t*)memregion("gfx2_lower")->base()); rearrange_tile_data(memregion("bg2")->base(), (uint32_t*)memregion("gfx3")->base(), (uint32_t*)memregion("gfx3_lower")->base()); rearrange_tile_data(memregion("bg3")->base(), (uint32_t*)memregion("gfx4")->base(), (uint32_t*)memregion("gfx4_lower")->base()); m_xoffset = 0; } GAME( 2002, gstream, 0, gstream, gstream, gstream_state, init_gstream, ROT270, "Oriental Soft Japan", "G-Stream G2020", MACHINE_SUPPORTS_SAVE ) GAME( 2000, x2222, 0, x2222, x2222, gstream_state, init_x2222, ROT270, "Oriental Soft / Promat", "X2222 (final debug?)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND ) GAME( 2000, x2222o, x2222, x2222, x2222, gstream_state, init_x2222, ROT270, "Oriental Soft / Promat", "X2222 (5-level prototype)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )