From 76df5c2a8ffda8bbdee8637a7d1e47eafcaef6be Mon Sep 17 00:00:00 2001 From: David Haywood <28625134+DavidHaywood@users.noreply.github.com> Date: Wed, 1 Jan 2020 21:36:47 +0000 Subject: jak_gtg / jak_car2 / jak_tsm / beambox / unsp - handful of changes to keep things progressing (nw) (#6118) * improve bootstrap HLE (nw) * misc unsp stuff for jak_tsm (nw) * keep hack disabled (nw) * (unrelated, minor flag change) * this hack goes away now (nw) --- src/devices/cpu/unsp/unsp_extended.cpp | 59 +++++++++++++++++----- src/devices/machine/sunplus_gcm394.cpp | 89 ++++++++++++++++++++++++++++------ src/devices/machine/sunplus_gcm394.h | 7 ++- src/mame/drivers/sunplus_gcm394.cpp | 42 +++++++++------- 4 files changed, 150 insertions(+), 47 deletions(-) diff --git a/src/devices/cpu/unsp/unsp_extended.cpp b/src/devices/cpu/unsp/unsp_extended.cpp index 4d10495f31c..114424c098c 100644 --- a/src/devices/cpu/unsp/unsp_extended.cpp +++ b/src/devices/cpu/unsp/unsp_extended.cpp @@ -142,13 +142,29 @@ void unsp_20_device::execute_extended_group(uint16_t op) break; } case 0x0a: // or + { // 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]); + uint16_t a = (ra & 0x8) ? m_secondary_r[ra & 0x7] : m_core->m_r[ra & 0x7]; + uint16_t b = (rb & 0x8) ? m_secondary_r[rb & 0x7] : m_core->m_r[rb & 0x7]; + + uint32_t lres = a | b; + + update_nz(lres); + 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 0x0b: // and // A &= B logerror( "(Extended group 0) %s &= %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] @@ -363,14 +379,27 @@ void unsp_20_device::execute_extended_group(uint16_t op) break; case 0x0b: // and + { // A = B & C - logerror( "(Extended group 1) %s = %s & %04x\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); + //logerror("(Extended group 1) %s = %s & %04x\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] + // , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] + // , imm16_2); + + uint16_t b = (rb & 0x8) ? m_secondary_r[rb & 0x7] : m_core->m_r[rb & 0x7]; + uint32_t lres = b & imm16_2; + 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 0x0c: // test // TEST B,C logerror( "(Extended group 1) test %s, %04x\n", (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] @@ -983,12 +1012,18 @@ void unsp_20_device::execute_extended_group(uint16_t op) break; case 0x02: // sub + { // A -= B - logerror("(Extended group 6) %s -= %02x\n", extregs[rx], imm6); - unimplemented_opcode(op, ximm); + //logerror("(Extended group 6) %s -= %02x\n", extregs[rx], imm6); + m_core->m_icount -= 1; // TODO + + uint32_t lres = m_secondary_r[rx] + (uint16_t)(~imm6) + uint32_t(1); + update_nzsc(lres, m_secondary_r[rx], ~imm6); + m_secondary_r[rx] = (uint16_t)lres; + return; break; - + } case 0x03: // sbc // A -= B, Carry logerror("(Extended group 6) %s -= %02x, carry\n", extregs[rx], imm6); diff --git a/src/devices/machine/sunplus_gcm394.cpp b/src/devices/machine/sunplus_gcm394.cpp index 5a94ae6ac60..ed0522de90d 100644 --- a/src/devices/machine/sunplus_gcm394.cpp +++ b/src/devices/machine/sunplus_gcm394.cpp @@ -21,15 +21,15 @@ DEFINE_DEVICE_TYPE(GCM394, sunplus_gcm394_device, "gcm394", "SunPlus GCM394 System-on-a-Chip") -sunplus_gcm394_device::sunplus_gcm394_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sunplus_gcm394_base_device(mconfig, GCM394, tag, owner, clock) +sunplus_gcm394_device::sunplus_gcm394_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + sunplus_gcm394_base_device(mconfig, GCM394, tag, owner, clock) { } DEFINE_DEVICE_TYPE(GPAC800, generalplus_gpac800_device, "gpac800", "GeneralPlus GPAC800 System-on-a-Chip") -generalplus_gpac800_device::generalplus_gpac800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : sunplus_gcm394_base_device(mconfig, GPAC800, tag, owner, clock, address_map_constructor(FUNC(generalplus_gpac800_device::gpac800_internal_map), this)) +generalplus_gpac800_device::generalplus_gpac800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + sunplus_gcm394_base_device(mconfig, GPAC800, tag, owner, clock, address_map_constructor(FUNC(generalplus_gpac800_device::gpac800_internal_map), this)) { } @@ -734,40 +734,96 @@ READ16_MEMBER(generalplus_gpac800_device::unkarea_7850_r) return machine().rand(); } +//[:maincpu] ':maincpu' (001490):sunplus_gcm394_base_device::unk_r @ 0x785f +READ16_MEMBER(generalplus_gpac800_device::nand_ecc_low_byte_error_flag_1_r) +{ + return 0x0000; +} + + + + +// GPR27P512A = C2 76 +// HY27UF081G2A = AD F1 80 1D +// H27U518S2C = AD 76 + READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r) { + // TODO: use actual NAND / Smart Media devices once this is better understood. + // The games have extensive checks on startup to determine the flash types, but then it appears that + // certain games (eg jak_tsm) will only function correctly with specific ones, even if the code + // continues regardless. Others will bail early if they don't get what they want. - //logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r\n", machine().describe_context()); + // I think some unSP core maths bugs are causing severe issues after the initial load for jak_tsm + // at the moment, possibly the same ones that are causing rendering issues in the jak_gtg bitmap + // test and seemingly incorrect road data for jak_car2, either that or the hookup here is very + // non-standard outside of the ident codes - // jak_tsm code looks for various 'magic values' + // real TSM code starts at 4c000 + + + //logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r\n", machine().describe_context()); if (m_nandcommand == 0x90) // read ident { - m_testval ^= 1; + logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ IDENT byte %d\n", machine().describe_context(), m_curblockaddr); + + uint8_t data = 0x00; - if (m_testval == 0) - return 0x73; + if (m_romtype == 0) + { + if (m_curblockaddr == 0) + data = 0xc2; + else + data = 0x76; + } + else if (m_romtype == 1) + { + if (m_curblockaddr == 0) + data = 0xad; + else if (m_curblockaddr == 1) + data = 0x76; + } else - return 0x98; + { + if (m_curblockaddr == 2) + data = 0xad; + else if (m_curblockaddr == 1) + data = 0xf1; + else if (m_curblockaddr == 2) + data = 0x80; + else if (m_curblockaddr == 3) + data = 0x1d; + } + + m_curblockaddr++; + + return data; } - else if (m_nandcommand == 0x00) // read data + else if (m_nandcommand == 0x00) { - //uint8_t d + //logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ DATA byte %d\n", machine().describe_context(), m_curblockaddr); + uint32_t nandaddress = (m_flash_addr_high << 16) | m_flash_addr_low; uint8_t data = m_nand_read_cb((nandaddress * 2) + m_curblockaddr); - //logerror("reading nand byte %02x\n", data); - m_curblockaddr++; return data; } else if (m_nandcommand == 0x70) // read status { + logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ STATUS byte %d\n", machine().describe_context(), m_curblockaddr); + + return 0xffff; + } + else + { + logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ UNKNOWN byte %d\n", machine().describe_context(), m_curblockaddr); return 0xffff; } - return 0x00; + return 0x0000; } // 7998 @@ -792,7 +848,6 @@ WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_high_w) uint32_t address = (m_flash_addr_high << 16) | m_flash_addr_low; - logerror("%s: flash address is now %08x\n", machine().describe_context(), address); m_curblockaddr = 0; @@ -813,6 +868,8 @@ void generalplus_gpac800_device::gpac800_internal_map(address_map& map) map(0x007854, 0x007854).r(FUNC(generalplus_gpac800_device::unkarea_7854_r)); // NAND Data Reg // map(0x007855, 0x007855).w(FUNC(generalplus_gpac800_device::nand_dma_ctrl_w)); // NAND DMA / INT Control + map(0x00785f, 0x00785f).r(FUNC(generalplus_gpac800_device::nand_ecc_low_byte_error_flag_1_r)); // ECC Low Byte Error Flag 1 (maybe) + // 128kwords internal ROM //map(0x08000, 0x0ffff).rom().region("internal", 0); // lower 32kwords of internal ROM is visible / shadowed depending on boot pins and register map(0x08000, 0x0ffff).r(FUNC(generalplus_gpac800_device::internalrom_lower32_r)).nopw(); diff --git a/src/devices/machine/sunplus_gcm394.h b/src/devices/machine/sunplus_gcm394.h index 72432980f85..b211089187b 100644 --- a/src/devices/machine/sunplus_gcm394.h +++ b/src/devices/machine/sunplus_gcm394.h @@ -39,6 +39,7 @@ public: m_porta_out(*this), m_nand_read_cb(*this), m_csbase(0x20000), + m_romtype(0), m_space_read_cb(*this), m_space_write_cb(*this), m_boot_mode(0), @@ -72,6 +73,7 @@ public: void set_paldisplaybank_high_hack(int pal_displaybank_high) { m_spg_video->set_paldisplaybank_high(pal_displaybank_high); } void set_alt_tile_addressing_hack(int alt_tile_addressing) { m_spg_video->set_alt_tile_addressing(alt_tile_addressing); } + void set_romtype(int romtype) { m_romtype = romtype; } protected: @@ -168,6 +170,7 @@ protected: DECLARE_WRITE16_MEMBER(cs_space_w); DECLARE_READ16_MEMBER(cs_bank_space_r); DECLARE_WRITE16_MEMBER(cs_bank_space_w); + int m_romtype; private: devcb_read16 m_space_read_cb; @@ -296,7 +299,6 @@ private: // config registers (external pins) int m_boot_mode; // 2 pins determine boot mode, likely only read at power-on sunplus_gcm394_cs_callback_device m_cs_callback; - }; @@ -343,6 +345,8 @@ private: DECLARE_WRITE16_MEMBER(flash_addr_low_w); DECLARE_WRITE16_MEMBER(flash_addr_high_w); + + DECLARE_READ16_MEMBER(nand_ecc_low_byte_error_flag_1_r); int m_testval; @@ -352,7 +356,6 @@ private: uint16_t m_flash_addr_high; int m_curblockaddr; - }; diff --git a/src/mame/drivers/sunplus_gcm394.cpp b/src/mame/drivers/sunplus_gcm394.cpp index 3ff7bbf7b98..d71101052f1 100644 --- a/src/mame/drivers/sunplus_gcm394.cpp +++ b/src/mame/drivers/sunplus_gcm394.cpp @@ -236,8 +236,7 @@ public: generalplus_gpac800_game_state(const machine_config& mconfig, device_type type, const char* tag) : gcm394_game_state(mconfig, type, tag), m_has_nand(false), - m_initial_copy_words(0x2000), - m_nandreadbase(0) + m_initial_copy_words(0x2000) { } @@ -248,6 +247,7 @@ public: void nand_wlsair60(); void nand_vbaby(); void nand_tsm(); + void nand_beambox(); protected: virtual void machine_reset() override; @@ -269,7 +269,7 @@ private: int m_strippedsize; int m_initial_copy_words; - int m_nandreadbase; + int m_vectorbase; }; @@ -368,7 +368,7 @@ READ8_MEMBER(generalplus_gpac800_game_state::read_nand) if (!m_has_nand) return 0x0000; - return m_strippedrom[(offset + m_nandreadbase) & (m_strippedsize - 1)]; + return m_strippedrom[offset & (m_strippedsize - 1)]; } READ16_MEMBER(gcm394_game_state::read_external_space) @@ -1029,17 +1029,17 @@ void generalplus_gpac800_game_state::machine_reset() // these vectors must either directly point to RAM, or at least redirect there after some code uint16_t* internal = (uint16_t*)memregion("maincpu:internal")->base(); - internal[0x7ff5] = 0x6fea; - internal[0x7ff6] = 0x6fec; + internal[0x7ff5] = m_vectorbase + 0x0a; + internal[0x7ff6] = m_vectorbase + 0x0c; internal[0x7ff7] = dest + 0x20; // point boot vector at code in RAM (probably in reality points to internal code that copies the first block) - internal[0x7ff8] = 0x6ff0; - internal[0x7ff9] = 0x6ff2; - internal[0x7ffa] = 0x6ff4; - internal[0x7ffb] = 0x6ff6; - internal[0x7ffc] = 0x6ff8; - internal[0x7ffd] = 0x6ffa; - internal[0x7ffe] = 0x6ffc; - internal[0x7fff] = 0x6ffe; + internal[0x7ff8] = m_vectorbase + 0x10; + internal[0x7ff9] = m_vectorbase + 0x12; + internal[0x7ffa] = m_vectorbase + 0x14; + internal[0x7ffb] = m_vectorbase + 0x16; + internal[0x7ffc] = m_vectorbase + 0x18; + internal[0x7ffd] = m_vectorbase + 0x1a; + internal[0x7ffe] = m_vectorbase + 0x1c; + internal[0x7fff] = m_vectorbase + 0x1e; internal[0x8000] = 0xb00b; } @@ -1089,6 +1089,7 @@ void generalplus_gpac800_game_state::nand_init(int blocksize, int blocksize_stri } m_has_nand = true; + m_vectorbase = 0x6fe0; } void generalplus_gpac800_game_state::nand_init210() @@ -1111,11 +1112,11 @@ void generalplus_gpac800_game_state::nand_vbaby() { nand_init840(); m_initial_copy_words = 0x1000; + m_maincpu->set_romtype(2); } void generalplus_gpac800_game_state::nand_tsm() { - nand_init210(); // something odd must be going on with the bootloader? // structure has the first 0x4000 block repeated 3 times (must appear in RAM on startup?) @@ -1124,7 +1125,14 @@ void generalplus_gpac800_game_state::nand_tsm() // the addresses written to the NAND device don't compensate for these data repeats, however dump seems ok as no other data is being repeated? // reads after startup still need checking - m_nandreadbase = (0x2000 + 0x2000 + 0x8000 + 0x8000 + 0x8000) * 2; + nand_init210(); + m_maincpu->set_romtype(1); +} + +void generalplus_gpac800_game_state::nand_beambox() +{ + nand_init210(); + m_vectorbase = 0x2fe0; } @@ -1136,4 +1144,4 @@ CONS(200?, jak_gtg, 0, 0, generalplus_gpac800, jak_gtg, generalplus_gpac800_ga 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_tsm, "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_vbaby, "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) +CONS(200?, beambox, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_beambox, "Hasbro", "Playskool Heroes Transformers Rescue Bots Beam Box (Spain)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -- cgit v1.2.3