From 699b8b14c75efb0862f20f458be4ef2ef1202c5f Mon Sep 17 00:00:00 2001 From: David Haywood <28625134+DavidHaywood@users.noreply.github.com> Date: Thu, 19 Dec 2019 17:13:11 +0000 Subject: Sunplus unsp2.0 experiments for jak_car2 (nw) (#6073) * let the hacking move us forward (nw) * testing (nw) * shifter behavior seems to bleed between regs (nw) * (nw) * avoid hang (nw) * some hacks to get to the jak_gtg service mode too (nw) --- src/devices/cpu/unsp/unsp_extended.cpp | 109 ++++++++++-- src/devices/cpu/unsp/unsp_exxx.cpp | 48 ++++- src/devices/cpu/unsp/unsp_fxxx.cpp | 4 +- src/devices/machine/sunplus_gcm394.cpp | 48 ++++- src/devices/machine/sunplus_gcm394.h | 11 ++ src/devices/machine/sunplus_gcm394_video.cpp | 78 ++++++--- src/devices/machine/sunplus_gcm394_video.h | 1 + src/mame/drivers/sunplus_gcm394.cpp | 251 ++++++++++++++++++++++++++- 8 files changed, 482 insertions(+), 68 deletions(-) diff --git a/src/devices/cpu/unsp/unsp_extended.cpp b/src/devices/cpu/unsp/unsp_extended.cpp index a3986d124b8..653a63c1c75 100644 --- a/src/devices/cpu/unsp/unsp_extended.cpp +++ b/src/devices/cpu/unsp/unsp_extended.cpp @@ -35,12 +35,32 @@ void unsp_20_device::execute_extended_group(uint16_t op) switch (aluop) { case 0x00: // add + { // A += B - logerror( "(Extended group 0) %s += %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - unimplemented_opcode(op, ximm); + //logerror( "(Extended group 0) %s += %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] + // , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); + m_core->m_icount -= 1; // TODO + + uint16_t r0 = (ra & 0x8) ? m_secondary_r[ra & 0x7] : m_core->m_r[ra & 0x7]; + uint16_t r1 = (rb & 0x8) ? m_secondary_r[rb & 0x7] : m_core->m_r[rb & 0x7]; + + uint32_t lres = r0 + r1; + + update_nzsc(lres, r0, r1); + + if (ra & 0x8) + { + m_secondary_r[ra & 0x7] = (uint16_t)lres; + } + else + { + m_core->m_r[ra & 0x7] = (uint16_t)lres; + } + + //unimplemented_opcode(op, ximm); return; break; + } case 0x01: // adc // A += B, Carry @@ -67,12 +87,22 @@ void unsp_20_device::execute_extended_group(uint16_t op) break; case 0x04: // cmp + { // CMP A,B - logerror( "(Extended group 0) cmp %s, %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - unimplemented_opcode(op, ximm); + //logerror( "(Extended group 0) cmp %s, %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] + // , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); + m_core->m_icount -= 1; // TODO + + uint16_t r0 = (ra & 0x8) ? m_secondary_r[ra & 0x7] : m_core->m_r[ra & 0x7]; + uint16_t r1 = (rb & 0x8) ? m_secondary_r[rb & 0x7] : m_core->m_r[rb & 0x7]; + + uint32_t lres = r0 + (uint16_t)(~r1) + uint32_t(1); + update_nzsc(lres, r0 , ~r1); + + //unimplemented_opcode(op, ximm); return; break; + } case 0x06: // neg // A = -B @@ -91,13 +121,26 @@ void unsp_20_device::execute_extended_group(uint16_t op) break; case 0x09: // load + { // A = B - logerror( "(Extended group 0) %s = %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - unimplemented_opcode(op, ximm); + //logerror("(Extended group 0) %s = %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] + // , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); + m_core->m_icount -= 1; // TODO + + uint32_t lres = (rb & 0x8) ? m_secondary_r[rb & 0x7] : m_core->m_r[rb & 0x7]; + update_nz(lres); + if (ra & 0x8) + { + m_secondary_r[ra & 0x7] = (uint16_t)lres; + } + else + { + m_core->m_r[ra & 0x7] = (uint16_t)lres; + } + return; break; - + } case 0x0a: // or // A |= B logerror( "(Extended group 0) %s |= %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] @@ -296,7 +339,7 @@ void unsp_20_device::execute_extended_group(uint16_t op) // , imm16_2); m_core->m_icount -= 1; // TODO - uint16_t lres = imm16_2; + uint32_t lres = imm16_2; update_nz(lres); if (ra & 0x8) { @@ -437,7 +480,7 @@ void unsp_20_device::execute_extended_group(uint16_t op) //uin32_t lreg = UNSP_LREG_I(imm16_2); - uint16_t lres = read16(imm16_2); + uint32_t lres = read16(imm16_2); update_nz(lres); if (ra & 0x8) { @@ -960,7 +1003,7 @@ void unsp_20_device::execute_extended_group(uint16_t op) m_core->m_icount -= 1; // TODO - uint16_t lres = m_secondary_r[rx] + (uint16_t)(~imm6) + uint32_t(1); + uint32_t lres = m_secondary_r[rx] + (uint16_t)(~imm6) + uint32_t(1); update_nzsc(lres, m_secondary_r[rx] , ~imm6); //unimplemented_opcode(op, ximm); @@ -988,7 +1031,7 @@ void unsp_20_device::execute_extended_group(uint16_t op) m_core->m_icount -= 1; // TODO - uint16_t lres = imm6; + uint32_t lres = imm6; update_nz(lres); m_secondary_r[rx] = (uint16_t)lres; @@ -1042,18 +1085,46 @@ void unsp_20_device::execute_extended_group(uint16_t op) switch (aluop) { case 0x00: // add + { // A += B - logerror( "(Extended group 7) %s += [BP+%02x]\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); + // logerror( "(Extended group 7) %s += [BP+%02x]\n", extregs[rx], imm6 ); + m_core->m_icount -= 1; // TODO + + uint16_t addr = (uint16_t)(m_core->m_r[REG_BP] + (imm6 & 0x3f)); + uint16_t r0 = m_secondary_r[rx]; + uint16_t r1 = read16(addr); + + uint32_t lres = r0 + r1; + + update_nzsc(lres, r0, r1); + + m_secondary_r[rx] = lres; + + //unimplemented_opcode(op, ximm); return; break; - + } case 0x01: // adc + { // A += B, Carry - logerror( "(Extended group 7) %s += [BP+%02x], carry\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); + //logerror( "(Extended group 7) %s += [BP+%02x], carry\n", extregs[rx], imm6 ); + m_core->m_icount -= 1; // TODO + + uint32_t c = (m_core->m_r[REG_SR] & UNSP_C) ? 1 : 0; + uint16_t addr = (uint16_t)(m_core->m_r[REG_BP] + (imm6 & 0x3f)); + uint16_t r0 = m_secondary_r[rx]; + uint16_t r1 = read16(addr); + + uint32_t lres = r0 + r1 + c; + + update_nzsc(lres, r0, r1); + + m_secondary_r[rx] = lres; + + //unimplemented_opcode(op, ximm); return; break; + } case 0x02: // sub // A -= B diff --git a/src/devices/cpu/unsp/unsp_exxx.cpp b/src/devices/cpu/unsp/unsp_exxx.cpp index 5e8f108ed52..25f754bb2e8 100644 --- a/src/devices/cpu/unsp/unsp_exxx.cpp +++ b/src/devices/cpu/unsp/unsp_exxx.cpp @@ -181,34 +181,64 @@ void unsp_12_device::execute_exxx_group(uint16_t op) case 0x02: logerror("pc:%06x: %s = %s lsl %s (%04x %04x) : ", UNSP_LPC, regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); - m_core->m_r[rd] = (uint16_t)((m_core->m_r[rd]&0xffff) << (m_core->m_r[rs] & 0x0f)); + + m_core->m_r[rd] = (uint16_t)((m_core->m_r[rd]&0xffff) << (m_core->m_r[rs] & 0x01f)); + logerror("result %04x\n", m_core->m_r[rd]); + return; case 0x03: { // wrlshunt uses this logerror("pc:%06x: %s = %s lslor %s (%04x %04x) : ", UNSP_LPC, regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); - uint16_t tmp = m_core->m_r[rd]; - m_core->m_r[rd] = (uint16_t)((m_core->m_r[rd]&0xffff) << (m_core->m_r[rs] & 0x0f)); - m_core->m_r[rd] |= tmp; // guess + + if (rd != 3) // 4 = R4 3 = R3 - the 'register bleeding' is only verified as needed between r3/r4, so bail for other regs until verified + unimplemented_opcode(op); + + uint32_t res = (uint16_t)(m_core->m_r[rd]); + + res <<= (m_core->m_r[rs] & 0x01f); + + m_core->m_r[rd] = (res & 0xffff); + m_core->m_r[rd + 1] |= (res >> 16); // register bleeding? + logerror("result %04x\n", m_core->m_r[rd]); return; } case 0x04: - // smartfp loops increasing shift by 4 up to values of 28? (but regs are 16-bit?) + // smartfp loops increasing shift by 4 up to values of 28? (but regs are 16-bit?) logerror("pc:%06x: %s = %s lsr %s (%04x %04x) : ", UNSP_LPC, regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); - m_core->m_r[rd] = (uint16_t)((m_core->m_r[rd]&0xffff) >> (m_core->m_r[rs] & 0xf)); + m_core->m_r[rd] = (uint16_t)((m_core->m_r[rd]&0xffff) >> (m_core->m_r[rs] & 0x1f)); logerror("result %04x\n", m_core->m_r[rd]); return; case 0x05: { logerror("pc:%06x: %s = %s lsror %s (%04x %04x) : ", UNSP_LPC, regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); - uint16_t tmp = m_core->m_r[rd]; - m_core->m_r[rd] = (uint16_t)((m_core->m_r[rd]&0xffff) >> (m_core->m_r[rs] & 0x0f)); - m_core->m_r[rd] |= tmp; // guess + + if (rd != 4) // 4 = R4 3 = R3 - the 'register bleeding' is only verified as needed between r3/r4, so bail for other regs until verified + unimplemented_opcode(op); + + uint32_t res = (uint16_t)(m_core->m_r[rd]); + + res <<= 16; + + res = res >> (m_core->m_r[rs] & 0x01f); + + // register bleeding behavior needed (for example) in jak_cars2 nand browser when increasing upper digits of address + // TODO: check if I'm missing something becaus this doesn't really seem logical, maybe other code is meant to take care of those bits? + // (although R3/R4 are the 'MR' register used for multiply stuff, so maybe there is some logic to this?) + + // code attempts to put a 32-bit value in r4/r3 then shift it like this? + //3c990: e92a r4 = r4 lsl r2 + //3c991: e73a r3 = r3 lslor r2 + + m_core->m_r[rd] = (res >> 16); + m_core->m_r[rd - 1] |= (res & 0xffff); // register bleeding? + + logerror("result %04x\n", m_core->m_r[rd]); return; } diff --git a/src/devices/cpu/unsp/unsp_fxxx.cpp b/src/devices/cpu/unsp/unsp_fxxx.cpp index c563ac1d88c..97cc652e649 100644 --- a/src/devices/cpu/unsp/unsp_fxxx.cpp +++ b/src/devices/cpu/unsp/unsp_fxxx.cpp @@ -45,14 +45,14 @@ inline void unsp_device::execute_fxxx_000_group(uint16_t op) { int r = op & 0x7; logerror("%s = fr\n", regs[r]); - unimplemented_opcode(op); + // unimplemented_opcode(op); return; } else if (((op & 0xf1f8) == 0xf038) && m_iso >= 12) { int r = op & 0x7; logerror("fr = %s\n", regs[r]); - unimplemented_opcode(op); + // unimplemented_opcode(op); return; } diff --git a/src/devices/machine/sunplus_gcm394.cpp b/src/devices/machine/sunplus_gcm394.cpp index 01c8104568e..6e1681fa800 100644 --- a/src/devices/machine/sunplus_gcm394.cpp +++ b/src/devices/machine/sunplus_gcm394.cpp @@ -258,6 +258,12 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7883_w) { LOGMASKED(LOG_GCM39 WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_78a0_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a0_w %04x\n", machine().describe_context(), data); m_78a0 = data; } +READ16_MEMBER(sunplus_gcm394_base_device::unkarea_78a0_r) +{ + LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a0_r\n", machine().describe_context()); + return machine().rand(); +} + READ16_MEMBER(sunplus_gcm394_base_device::unkarea_78a1_r) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a1_r\n", machine().describe_context()); @@ -367,6 +373,7 @@ void sunplus_gcm394_base_device::gcm394_internal_map(address_map &map) map(0x00702f, 0x00702f).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid2_gfxbase_msb_w)); // written with other unknown_video_device2 regs (roz layer or line layer?) map(0x007030, 0x007030).rw(m_spg_video, FUNC(gcm394_base_video_device::video_7030_brightness_r), FUNC(gcm394_base_video_device::video_7030_brightness_w)); + map(0x007038, 0x007038).r(m_spg_video, FUNC(gcm394_base_video_device::video_curline_r)); map(0x00703a, 0x00703a).rw(m_spg_video, FUNC(gcm394_base_video_device::video_703a_palettebank_r), FUNC(gcm394_base_video_device::video_703a_palettebank_w)); map(0x00703c, 0x00703c).w(m_spg_video, FUNC(gcm394_base_video_device::video_703c_w)); // TV Control 1 @@ -455,7 +462,7 @@ void sunplus_gcm394_base_device::gcm394_internal_map(address_map &map) map(0x007882, 0x007882).rw(FUNC(sunplus_gcm394_base_device::unkarea_7882_r), FUNC(sunplus_gcm394_base_device::unkarea_7882_w)); map(0x007883, 0x007883).rw(FUNC(sunplus_gcm394_base_device::unkarea_7883_r), FUNC(sunplus_gcm394_base_device::unkarea_7883_w)); - map(0x0078a0, 0x0078a0).w(FUNC(sunplus_gcm394_base_device::unkarea_78a0_w)); + map(0x0078a0, 0x0078a0).rw(FUNC(sunplus_gcm394_base_device::unkarea_78a0_r), FUNC(sunplus_gcm394_base_device::unkarea_78a0_w)); map(0x0078a1, 0x0078a1).r(FUNC(sunplus_gcm394_base_device::unkarea_78a1_r)); @@ -518,11 +525,31 @@ READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r) // jak_tsm code looks for various 'magic values' if (m_testval == 1) - return 0xc2; + return 0x98; else - return 0x58; + return 0x79; + +} + +// 7998 + +WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_low_w) +{ + //logerror("%s:sunplus_gcm394_base_device::flash_addr_low_w %04x\n", machine().describe_context(), data); + m_flash_addr_low = data; +} + +WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_high_w) +{ + //logerror("%s:sunplus_gcm394_base_device::flash_addr_high_w %04x\n", machine().describe_context(), data); + m_flash_addr_high = data; + + uint32_t address = (m_flash_addr_high << 16) | m_flash_addr_low; + + logerror("%s: flash address is now %08x\n", machine().describe_context(), address); } + // all tilemap registers etc. appear to be in the same place as the above system, including the 'extra' ones not on the earlier models // so it's likely this is built on top of that just with NAND support void generalplus_gpac800_device::gpac800_internal_map(address_map& map) @@ -535,6 +562,11 @@ void generalplus_gpac800_device::gpac800_internal_map(address_map& map) // this should be the NAND device, as the games attempt to do a DMA operation with '7854' as the source, and the target // as the RAM location where code needs to end up before jumping to it map(0x007850, 0x007850).r(FUNC(generalplus_gpac800_device::unkarea_7850_r)); // 'device ready' status flag? + + map(0x007852, 0x007852).w(FUNC(generalplus_gpac800_device::flash_addr_low_w)); + map(0x007853, 0x007853).w(FUNC(generalplus_gpac800_device::flash_addr_high_w)); + + map(0x007854, 0x007854).r(FUNC(generalplus_gpac800_device::unkarea_7854_r)); // data read port (timing appears to be important) } @@ -637,9 +669,17 @@ void sunplus_gcm394_base_device::device_reset() } +void generalplus_gpac800_device::device_reset() +{ + sunplus_gcm394_base_device::device_reset(); + + m_flash_addr_low = 0x0000; + m_flash_addr_high = 0x0000; +} + IRQ_CALLBACK_MEMBER(sunplus_gcm394_base_device::irq_vector_cb) { - //printf("irq_vector_cb %d\n", irqline); + //logerror("irq_vector_cb %d\n", irqline); if (irqline == UNSP_IRQ6_LINE) set_state_unsynced(UNSP_IRQ6_LINE, CLEAR_LINE); diff --git a/src/devices/machine/sunplus_gcm394.h b/src/devices/machine/sunplus_gcm394.h index 77c57ba3602..5ce0ff9a433 100644 --- a/src/devices/machine/sunplus_gcm394.h +++ b/src/devices/machine/sunplus_gcm394.h @@ -213,6 +213,7 @@ private: DECLARE_WRITE16_MEMBER(unkarea_78a0_w); + DECLARE_READ16_MEMBER(unkarea_78a0_r); DECLARE_READ16_MEMBER(unkarea_78a1_r); DECLARE_WRITE16_MEMBER(unkarea_78a4_w); @@ -291,11 +292,21 @@ public: protected: void gpac800_internal_map(address_map &map); + //virtual void device_start() override; + virtual void device_reset() override; + private: DECLARE_READ16_MEMBER(unkarea_7850_r); DECLARE_READ16_MEMBER(unkarea_7854_r); + DECLARE_WRITE16_MEMBER(flash_addr_low_w); + DECLARE_WRITE16_MEMBER(flash_addr_high_w); + int m_testval; + + uint16_t m_flash_addr_low; + uint16_t m_flash_addr_high; + }; diff --git a/src/devices/machine/sunplus_gcm394_video.cpp b/src/devices/machine/sunplus_gcm394_video.cpp index 7f6d32eb03c..e3f0a789540 100644 --- a/src/devices/machine/sunplus_gcm394_video.cpp +++ b/src/devices/machine/sunplus_gcm394_video.cpp @@ -389,24 +389,24 @@ void gcm394_base_video_device::draw_page(const rectangle &cliprect, uint32_t sca { uint32_t xscroll = regs[0]; uint32_t yscroll = regs[1]; - uint32_t attr = regs[2]; - uint32_t ctrl = regs[3]; + uint32_t attr_reg = regs[2]; + uint32_t ctrl_reg = regs[3]; uint32_t tilemap = regs[4]; uint32_t palette_map = regs[5]; address_space &space = m_cpu->space(AS_PROGRAM); - if (!(ctrl & PAGE_ENABLE_MASK)) + if (!(ctrl_reg & PAGE_ENABLE_MASK)) { return; } - if (((attr & PAGE_PRIORITY_FLAG_MASK) >> PAGE_PRIORITY_FLAG_SHIFT) != priority) + if (((attr_reg & PAGE_PRIORITY_FLAG_MASK) >> PAGE_PRIORITY_FLAG_SHIFT) != priority) { return; } - uint32_t tile_h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT); - uint32_t tile_w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT); + uint32_t tile_h = 8 << ((attr_reg & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT); + uint32_t tile_w = 8 << ((attr_reg & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT); uint32_t tile_count_x = 512 / tile_w; @@ -419,23 +419,22 @@ void gcm394_base_video_device::draw_page(const rectangle &cliprect, uint32_t sca { uint32_t yy = ((tile_h * y0 - yscroll + 0x10) & 0xff) - 0x10; uint32_t xx = (tile_w * x0 - xscroll) & 0x1ff; - uint32_t tile = (ctrl & PAGE_WALLPAPER_MASK) ? space.read_word(tilemap) : space.read_word(tilemap + tile_address); + uint32_t tile = (ctrl_reg & PAGE_WALLPAPER_MASK) ? space.read_word(tilemap) : space.read_word(tilemap + tile_address); - uint16_t palette = (ctrl & PAGE_WALLPAPER_MASK) ? space.read_word(palette_map) : space.read_word(palette_map + tile_address / 2); + uint16_t palette = (ctrl_reg & PAGE_WALLPAPER_MASK) ? space.read_word(palette_map) : space.read_word(palette_map + tile_address / 2); if (x0 & 1) palette >>= 8; - tile |= (palette & 0x0007) << 16; if (!tile) continue; - uint32_t tileattr = attr; - uint32_t tilectrl = ctrl; + uint32_t tileattr = attr_reg; + uint32_t tilectrl = ctrl_reg; #if 0 - if ((ctrl & 2) == 0) + if ((ctrl_reg & 2) == 0) { // -(1) bld(1) flip(2) pal(4) tileattr &= ~0x000c; tileattr |= (palette >> 2) & 0x000c; // flip @@ -447,32 +446,55 @@ void gcm394_base_video_device::draw_page(const rectangle &cliprect, uint32_t sca tilectrl |= (palette << 2) & 0x0100; // blend } #endif - const bool blend = (tileattr & 0x4000 || tilectrl & 0x0100); - const bool row_scroll = (tilectrl & 0x0010); - const bool flip_x = (tileattr & TILE_X_FLIP); - const uint32_t yflipmask = tileattr & TILE_Y_FLIP ? tile_h - 1 : 0; - uint32_t palette_offset = (tileattr & 0x0f00) >> 4; + bool blend; + bool row_scroll; + bool flip_x; + uint32_t yflipmask; + uint32_t palette_offset; + + blend = (tileattr & 0x4000 || tilectrl & 0x0100); + row_scroll = (tilectrl & 0x0010); + + int use_alt_drawmode; + + if ((ctrl_reg & 2) == 0) + { + flip_x = 0; + yflipmask = 0; + palette_offset = (palette & 0x0f) << 4; + use_alt_drawmode = 1; + } + else + { + flip_x = (tileattr & TILE_X_FLIP); + yflipmask = tileattr & TILE_Y_FLIP ? tile_h - 1 : 0; + palette_offset = (tileattr & 0x0f00) >> 4; + tile |= (palette & 0x0007) << 16; + use_alt_drawmode = 0; + } + //palette_offset |= 0x0900; palette_offset |= 0x0100; const uint8_t bpp = tileattr & 0x0003; + if (blend) { if (row_scroll) { if (flip_x) - draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, 0); + draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); else - draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, 0); + draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); } else { if (flip_x) - draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, 0); + draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); else - draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, 0); + draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); } } else @@ -480,16 +502,16 @@ void gcm394_base_video_device::draw_page(const rectangle &cliprect, uint32_t sca if (row_scroll) { if (flip_x) - draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, 0); + draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); else - draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, 0); + draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); } else { if (flip_x) - draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, 0); + draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); else - draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, 0); + draw(cliprect, tile_scanline, xx, yy, bitmap_addr, tile, tile_h, tile_w, bpp, yflipmask, palette_offset, use_alt_drawmode); } } } @@ -963,6 +985,12 @@ WRITE16_MEMBER(gcm394_base_video_device::video_7063_videoirq_source_ack_w) WRITE16_MEMBER(gcm394_base_video_device::video_702a_w) { LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::video_702a_w %04x\n", machine().describe_context(), data); m_702a = data; } +READ16_MEMBER(gcm394_base_video_device::video_curline_r) +{ + LOGMASKED(LOG_GCM394_VIDEO, "%s: video_r: Current Line: %04x\n", machine().describe_context(), m_screen->vpos()); + return m_screen->vpos(); +} + // read in IRQ READ16_MEMBER(gcm394_base_video_device::video_7030_brightness_r) { diff --git a/src/devices/machine/sunplus_gcm394_video.h b/src/devices/machine/sunplus_gcm394_video.h index fe80a81b59d..73d9da3e5c7 100644 --- a/src/devices/machine/sunplus_gcm394_video.h +++ b/src/devices/machine/sunplus_gcm394_video.h @@ -68,6 +68,7 @@ public: DECLARE_WRITE16_MEMBER(video_702a_w); DECLARE_READ16_MEMBER(video_7030_brightness_r); DECLARE_WRITE16_MEMBER(video_7030_brightness_w); + DECLARE_READ16_MEMBER(video_curline_r); DECLARE_WRITE16_MEMBER(video_703c_w); DECLARE_READ16_MEMBER(video_707c_r); diff --git a/src/mame/drivers/sunplus_gcm394.cpp b/src/mame/drivers/sunplus_gcm394.cpp index 7663c87ab96..1268a646a7e 100644 --- a/src/mame/drivers/sunplus_gcm394.cpp +++ b/src/mame/drivers/sunplus_gcm394.cpp @@ -5,12 +5,29 @@ Compared to vii.cpp this is clearly newer, has extra opcodes, different internal map etc. also scaling and higher resolutions based on Spongebob + + GPL600 Smart Fit Park SpongeBob SquarePants Bikini Bottom 500 Spiderman - The Masked Menace 'Spider Sense' (pad type with Spiderman model) (Wireless Hunting? - maybe, register map looks the same even if it sets stack to 2fff not 6fff) - as these use newer opcodes in the FExx range they probably need a derived unSP type too + GPL800 (== GPL600 with NAND support + maybe more) + Wireless Air 60 + Golden Tee Golf + Cars 2 + Toy Story Mania + V.Baby + Playskool Heroes Transformers Rescue Bots Beam Box + + GPL500 (unknown, might be GPL600 but without the higher resolution support?) + The Price is Right + Bejeweled? (might be GPL600) + + Notes + smartfp: hold button Circle, Star and Home on startup for Test Menu + + these are both unsp 2.0 type, as they use the extended ocpodes */ #include "emu.h" @@ -373,7 +390,7 @@ static INPUT_PORTS_START( gcm394 ) PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON15 ) PORT_CODE(KEYCODE_OPENBRACE) PORT_NAME("10") PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_BUTTON16 ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_NAME("11") - PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CODE(KEYCODE_A) PORT_NAME("Circle / Red") // hold button Circle and Star on startup for test menu (other conditions? doesn't always work?) + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CODE(KEYCODE_A) PORT_NAME("Circle / Red") PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CODE(KEYCODE_S) PORT_NAME("Square / Orange") PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_CODE(KEYCODE_D) PORT_NAME("Triangle / Yellow") PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_CODE(KEYCODE_F) PORT_NAME("Star / Blue") @@ -432,6 +449,188 @@ static INPUT_PORTS_START( wrlshunt ) PORT_START("P2") INPUT_PORTS_END +static INPUT_PORTS_START( jak_car2 ) + PORT_START("P1") + PORT_DIPNAME( 0x0001, 0x0001, "P1" ) + 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_BIT( 0x0020, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON3 ) // unused + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) + PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + + PORT_START("P2") + PORT_DIPNAME( 0x0001, 0x0001, "P2" ) + 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_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0080, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0100, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0200, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0400, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0800, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) +INPUT_PORTS_END + +static INPUT_PORTS_START( jak_gtg ) + PORT_START("P1") + PORT_DIPNAME( 0x0001, 0x0001, "P1" ) + 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_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) + PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0080, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0100, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0200, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0400, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0800, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + + PORT_START("P2") + PORT_DIPNAME( 0x0001, 0x0001, "P2" ) + 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_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0080, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0100, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0200, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0400, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0800, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) +INPUT_PORTS_END + /* Wireless Hunting Video Game System (info provided with dump) @@ -605,7 +804,41 @@ void generalplus_gpac800_game_state::machine_reset() mem.write_word(dest+i, word); } + int rambase = 0x30000; + for (int i = 0x4000/2; i < 0x37c000/2; i++) + { + uint16_t word = m_strippedrom[(i * 2) + 0] | (m_strippedrom[(i * 2) + 1] << 8); + + m_mainram[rambase] = word; + rambase++; + } + + mem.write_word(0xfff5, 0x6fea); + mem.write_word(0xfff6, 0x6fec); mem.write_word(0xfff7, dest+0x20); // point boot vector at code in RAM + mem.write_word(0xfff8, 0x6ff0); + mem.write_word(0xfff9, 0x6ff2); + mem.write_word(0xfffa, 0x6ff4); + mem.write_word(0xfffb, 0x6ff6); + mem.write_word(0xfffc, 0x6ff8); + mem.write_word(0xfffd, 0x6ffa); + mem.write_word(0xfffe, 0x6ffc); + mem.write_word(0xffff, 0x6ffe); + + // note, these patch the code copied to SRAM so the 'PROGRAM ROM' check fails (it passes otherwise) + if (mem.read_word(0x3f368) == 0x4840) + mem.write_word(0x3f368, 0x4841); // cars 2 IRQ? wait hack + + if (mem.read_word(0x4368c) == 0x4846) + mem.write_word(0x4368c, 0x4840); // cars 2 force service mode + + if (mem.read_word(0x4d8d4) == 0x4840) + mem.write_word(0x4d8d4, 0x4841); // golden tee IRQ? wait hack + + if (mem.read_word(0x34410) == 0x4846) + mem.write_word(0x34410, 0x4840); // golden tee force service mode + + m_maincpu->reset(); // reset CPU so vector gets read etc. } @@ -631,7 +864,7 @@ void generalplus_gpac800_game_state::nand_init(int blocksize, int blocksize_stri } // debug to allow for easy use of unidasm.exe - if (1) + if (0) { FILE *fp; char filename[256]; @@ -657,9 +890,9 @@ void generalplus_gpac800_game_state::nand_init840() // NAND dumps w/ internal bootstrap (and u'nSP 2.0 extended opcodes) (have gpnandnand strings) // the JAKKS ones seem to be known as 'Generalplus GPAC800' hardware -CONS(2010, wlsair60, 0, 0, generalplus_gpac800, gcm394, generalplus_gpac800_game_state, nand_init840, "Jungle Soft / Kids Station Toys Inc", "Wireless Air 60", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -CONS(200?, jak_gtg, 0, 0, generalplus_gpac800, gcm394, generalplus_gpac800_game_state, nand_init210, "JAKKS Pacific Inc", "Golden Tee Golf (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -CONS(200?, jak_car2, 0, 0, generalplus_gpac800, gcm394, generalplus_gpac800_game_state, nand_init210, "JAKKS Pacific Inc", "Cars 2 (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -CONS(200?, jak_tsm , 0, 0, generalplus_gpac800, gcm394, generalplus_gpac800_game_state, nand_init210, "JAKKS Pacific Inc", "Toy Story Mania (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -CONS(200?, vbaby, 0, 0, generalplus_gpac800, gcm394, generalplus_gpac800_game_state, nand_init840, "VTech", "V.Baby", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -CONS(200?, beambox, 0, 0, generalplus_gpac800, gcm394, generalplus_gpac800_game_state, nand_init210, "Hasbro", "Playskool Heroes Transformers Rescue Bots Beam Box (Spain)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(2010, wlsair60, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init840, "Jungle Soft / Kids Station Toys Inc", "Wireless Air 60", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(200?, jak_gtg, 0, 0, generalplus_gpac800, jak_gtg, generalplus_gpac800_game_state, nand_init210, "JAKKS Pacific Inc", "Golden Tee Golf (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(200?, jak_car2, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init210, "JAKKS Pacific Inc", "Cars 2 (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(200?, jak_tsm , 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init210, "JAKKS Pacific Inc", "Toy Story Mania (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(200?, vbaby, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init840, "VTech", "V.Baby", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(200?, beambox, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init210, "Hasbro", "Playskool Heroes Transformers Rescue Bots Beam Box (Spain)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -- cgit v1.2.3