diff options
Diffstat (limited to 'src/mame/drivers/nes_vt.cpp')
-rw-r--r-- | src/mame/drivers/nes_vt.cpp | 748 |
1 files changed, 625 insertions, 123 deletions
diff --git a/src/mame/drivers/nes_vt.cpp b/src/mame/drivers/nes_vt.cpp index 6642fea66ed..0ba760e8472 100644 --- a/src/mame/drivers/nes_vt.cpp +++ b/src/mame/drivers/nes_vt.cpp @@ -20,13 +20,22 @@ VT16 - ? VT18 - ? - - VT3x - used in SY889 - Uses SQI rather than parallel flash - Vaguely OneBus compatible but some registers different ($411C in particular) - Uses RGB format for palettes - Credit to NewRisingSun2 for much of the reverse engineering - + + VT33 (?) - used in FC Pocket, dgun2573 + Adds scrambled opcodes (XORed with 0xA1) and RGB444 palette mode, + and more advanced PCM modes (CPU and video working, sound NYI) + + VT368 (?) - used in DGUN2561, lexcyber + Various enhancements not yet emulated. Different banking, possibly an ALU, + larger palette space + + VT36x (?) - used in SY889 + Uses SQI rather than parallel flash + Vaguely OneBus compatible but some registers different ($411C in particular) + Uses RGB format for palettes + Credit to NewRisingSun2 for much of the reverse engineering + same chipset used in Mogis M320, but uses more advanced feature set. + (more) VT1682 - NOT compatible with NES, different video system, sound CPU (4x @@ -35,15 +44,14 @@ todo (VT03): - Super Mario Bros 3 crashes after title screen, some kind of memory map issue - possibly with MMC3 emulation mode - APU refactoring to allow for mostly doubled up functionality + PCM channel *more* todo (newer VTxx): - everything + new PCM audio in FC Pocket and DGUN-2573 + add support for VT368 (?) in DGUN-2561 and lexcyber + add support for the VT369 (?) featurs used by the MOGIS M320 todo (general) @@ -65,16 +73,25 @@ #include "cpu/m6502/n2a03.h" #include "machine/bankdev.h" #include "video/ppu2c0x_vt.h" -#include "cpu/m6502/m6502.h" +#include "machine/m6502_vtscr.h" #include "screen.h" #include "speaker.h" +enum class vt_scramble_mode { + NO_SCRAMBLE = 0, + WAIXING = 1, + PJOY = 2, + HUMMER = 3, + SP69 = 4 +}; + class nes_vt_state : public nes_base_state { public: nes_vt_state(const machine_config &mconfig, device_type type, const char *tag) : nes_base_state(mconfig, type, tag) , m_ntram(nullptr) + , m_chrram(nullptr) , m_ppu(*this, "ppu") , m_apu(*this, "apu") , m_prg(*this, "prg") @@ -83,6 +100,8 @@ public: , m_prgbank2(*this, "prg_bank2") , m_prgbank3(*this, "prg_bank3") , m_prgrom(*this, "mainrom") + , m_csel(*this, "CARTSEL") + { } /* APU handling */ @@ -102,7 +121,19 @@ public: /* VT03 extension handling */ DECLARE_WRITE8_MEMBER(vt03_410x_w); + DECLARE_READ8_MEMBER(vt03_410x_r); + + DECLARE_WRITE8_MEMBER(vt03_410x_pjoy_w); + DECLARE_WRITE8_MEMBER(vt03_410x_hum_w); + DECLARE_WRITE8_MEMBER(vt03_410x_sp69_w); + DECLARE_WRITE8_MEMBER(vt03_8000_w); + DECLARE_WRITE8_MEMBER(vt03_8000_pjoy_w); + DECLARE_WRITE8_MEMBER(vt03_8000_hum_w); + DECLARE_WRITE8_MEMBER(vt03_8000_sp69_w); + + void scrambled_410x_w(uint16_t offset, uint8_t data, vt_scramble_mode scram); + void scrambled_8000_w(address_space &space, uint16_t offset, uint8_t data, vt_scramble_mode scram); DECLARE_WRITE8_MEMBER(vt03_4034_w); DECLARE_WRITE8_MEMBER(vt03_41bx_w); @@ -112,23 +143,52 @@ public: DECLARE_WRITE8_MEMBER(vt03_48ax_w); DECLARE_READ8_MEMBER(vt03_48ax_r); + + DECLARE_WRITE8_MEMBER(vt03_413x_w); + DECLARE_READ8_MEMBER(vt03_413x_r); + DECLARE_READ8_MEMBER(vt03_414f_r); + DECLARE_READ8_MEMBER(vt03_415c_r); + + DECLARE_READ8_MEMBER(vthh_414a_r); + DECLARE_WRITE8_MEMBER(vtfp_411e_w); + DECLARE_WRITE8_MEMBER(vtfp_4a00_w); + DECLARE_WRITE8_MEMBER(vtfp_412c_w); + DECLARE_WRITE8_MEMBER(vtfa_412c_w); + DECLARE_READ8_MEMBER(vtfp_412d_r); + DECLARE_WRITE8_MEMBER(vtfp_411d_w); + DECLARE_WRITE8_MEMBER(vtfp_4242_w); + DECLARE_READ8_MEMBER(vtfp_4119_r); + + DECLARE_READ8_MEMBER(vtfa_412c_r); /* OneBus read callbacks for getting sprite and tile data during rendering*/ DECLARE_READ8_MEMBER(spr_r); DECLARE_READ8_MEMBER(chr_r); + DECLARE_WRITE8_MEMBER(chr_w); + void nes_vt(machine_config &config); + + void nes_vt_hum(machine_config &config); + void nes_vt_pjoy(machine_config &config); + void nes_vt_sp69(machine_config &config); + + void nes_vt_xx(machine_config &config); void nes_vt_hh(machine_config &config); void nes_vt_cy(machine_config &config); void nes_vt_dg(machine_config &config); void nes_vt_bt(machine_config &config); void nes_vt_vg(machine_config &config); + void nes_vt_fp(machine_config &config); + void nes_vt_fa(machine_config &config); private: /* expansion nametable - todo, see if we can refactor NES code to be reusable without having to add full NES bus etc. */ std::unique_ptr<uint8_t[]> m_ntram; + std::unique_ptr<uint8_t[]> m_chrram; + DECLARE_READ8_MEMBER(nt_r); DECLARE_WRITE8_MEMBER(nt_w); @@ -137,8 +197,10 @@ private: void video_irq(bool hblank, int scanline, int vblank, int blanked); uint8_t m_410x[0xc]; - uint8_t m_411c; - uint8_t m_412c; + uint8_t m_413x[8]; + + uint8_t m_411c, m_411d, m_4242; + uint32_t m_ahigh; uint8_t m_vdma_ctrl; int m_timer_irq_enabled; @@ -167,6 +229,7 @@ private: required_memory_bank m_prgbank3; required_region_ptr<uint8_t> m_prgrom; + optional_ioport m_csel; uint16_t decode_nt_addr(uint16_t addr); void do_dma(uint8_t data, bool broken); }; @@ -191,7 +254,7 @@ uint32_t nes_vt_state::get_banks(uint8_t bnk) // 8000 needs to bank in 60000 ( bank 0x30 ) void nes_vt_state::update_banks() { - uint32_t amod = (m_412c & 0x04) ? 0x800 : 0x0; + uint32_t amod = m_ahigh >> 13; uint8_t bank; @@ -240,6 +303,38 @@ uint16_t nes_vt_state::decode_nt_addr(uint16_t addr) { WRITE8_MEMBER(nes_vt_state::vt03_410x_w) { + scrambled_410x_w(offset, data, vt_scramble_mode::NO_SCRAMBLE); +} + +READ8_MEMBER(nes_vt_state::vt03_410x_r) +{ + return m_410x[offset]; +} + +WRITE8_MEMBER(nes_vt_state::vt03_410x_hum_w) +{ + scrambled_410x_w(offset, data, vt_scramble_mode::HUMMER); +} +WRITE8_MEMBER(nes_vt_state::vt03_410x_pjoy_w) +{ + scrambled_410x_w(offset, data, vt_scramble_mode::PJOY); +} +WRITE8_MEMBER(nes_vt_state::vt03_410x_sp69_w) +{ + scrambled_410x_w(offset, data, vt_scramble_mode::SP69); +} +// Source: https://wiki.nesdev.com/w/index.php/NES_2.0_submappers/Proposals#NES_2.0_Mapper_256 + +static const uint16_t descram_4107_4108[5][2] = { + {0x7, 0x8}, + {0x7, 0x8}, + {0x8, 0x7}, + {0x7, 0x8}, + {0x7, 0x8}, +}; + +void nes_vt_state::scrambled_410x_w(uint16_t offset, uint8_t data, vt_scramble_mode scram) +{ switch (offset) { case 0x0: @@ -254,6 +349,7 @@ WRITE8_MEMBER(nes_vt_state::vt03_410x_w) break; case 0x2: + //logerror("vt03_4102_w %02x\n", data); // load latched value and start counting m_410x[0x2] = data; // value doesn't matter? m_timer_val = m_410x[0x1]; @@ -261,12 +357,15 @@ WRITE8_MEMBER(nes_vt_state::vt03_410x_w) break; case 0x3: + //logerror("vt03_4103_w %02x\n", data); + m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE); // disable timer irq m_410x[0x3] = data; // value doesn't matter? m_timer_irq_enabled = 0; break; case 0x4: + //logerror("vt03_4104_w %02x\n", data); // enable timer irq m_410x[0x4] = data; // value doesn't matter? m_timer_irq_enabled = 1; @@ -283,12 +382,12 @@ WRITE8_MEMBER(nes_vt_state::vt03_410x_w) break; case 0x7: - m_410x[0x7] = data; + m_410x[descram_4107_4108[(int)scram][0]] = data; update_banks(); break; case 0x8: - m_410x[0x8] = data; + m_410x[descram_4107_4108[(int)scram][1]] = data; update_banks(); break; @@ -338,10 +437,58 @@ WRITE8_MEMBER(nes_vt_state::vt03_411c_w) WRITE8_MEMBER(nes_vt_state::vt03_412c_w) { logerror("vt03_412c_w %02x\n", data); - m_412c = data; + m_ahigh = (data & 0x04) ? (1 << 24) : 0x0; update_banks(); } +WRITE8_MEMBER(nes_vt_state::vtfp_412c_w) +{ + logerror("vtfp_412c_w %02x\n", data); + m_ahigh = (data & 0x01) ? (1 << 25) : 0x0; + update_banks(); +} + +WRITE8_MEMBER(nes_vt_state::vtfp_4242_w) +{ + logerror("vtfp_4242_w %02x\n", data); + m_4242 = data; +} + + +WRITE8_MEMBER(nes_vt_state::vtfp_411d_w) +{ + logerror("vtfp_411d_w %02x\n", data); + m_411d = data; + update_banks(); +} + +WRITE8_MEMBER(nes_vt_state::vtfa_412c_w) +{ + logerror("vtfp_412c_w %02x\n", data); + m_ahigh = 0; + m_ahigh |= (data & 0x01) ? (1 << 25) : 0x0; + m_ahigh |= (data & 0x02) ? (1 << 24) : 0x0; + + //m_ahigh |= (m_csel->read() == 0x01) ? (1 << 25) : 0x0; + update_banks(); +} + +READ8_MEMBER(nes_vt_state::vtfa_412c_r) +{ + return m_csel->read(); +} + +READ8_MEMBER(nes_vt_state::vtfp_412d_r) +{ + return m_csel->read(); +} + +READ8_MEMBER(nes_vt_state::vtfp_4119_r) +{ + return 0x00; +} + + READ8_MEMBER(nes_vt_state::vt03_41bx_r) { switch(offset) { @@ -369,6 +516,52 @@ READ8_MEMBER(nes_vt_state::vt03_48ax_r) } } +WRITE8_MEMBER(nes_vt_state::vt03_413x_w) +{ + logerror("vt03_413x_w %02x %02x\n", offset, data); + // VT168 style ALU ?? + m_413x[offset] = data; + if(offset == 0x5) { + uint32_t res = uint32_t((m_413x[5] << 8) | m_413x[4]) * uint32_t((m_413x[1] << 8) | m_413x[0]); + m_413x[0] = res & 0xFF; + m_413x[1] = (res >> 8) & 0xFF; + m_413x[2] = (res >> 16) & 0xFF; + m_413x[3] = (res >> 24) & 0xFF; + m_413x[6] = 0x00; + + } else if(offset == 0x6) { + /*uint32_t res = uint32_t((m_413x[5] << 8) | m_413x[4]) * uint32_t((m_413x[1] << 8) | m_413x[0]); + m_413x[0] = res & 0xFF; + m_413x[1] = (res >> 8) & 0xFF; + m_413x[2] = (res >> 16) & 0xFF; + m_413x[3] = (res >> 24) & 0xFF;*/ + m_413x[6] = 0x00; + } + +} + + +READ8_MEMBER(nes_vt_state::vt03_413x_r) +{ + logerror("vt03_413x_r %02x\n", offset); + return m_413x[offset]; +} + +READ8_MEMBER(nes_vt_state::vt03_414f_r) +{ + return 0xff; +} + +READ8_MEMBER(nes_vt_state::vt03_415c_r) +{ + return 0xff; +} + +READ8_MEMBER(nes_vt_state::vthh_414a_r) +{ + return 0x80; +} + uint32_t nes_vt_state::screen_update_vt(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { @@ -379,16 +572,50 @@ uint32_t nes_vt_state::screen_update_vt(screen_device &screen, bitmap_ind16 &bit READ8_MEMBER(nes_vt_state::spr_r) { - int realaddr = calculate_real_video_address(offset, 0, 1); - return m_prgrom[realaddr & (m_romsize-1)]; + if(m_4242 & 0x1 || m_411d & 0x04) { + return m_chrram[offset]; + } else { + int realaddr = calculate_real_video_address(offset, 0, 1); + return m_prgrom[realaddr & (m_romsize-1)]; + } } READ8_MEMBER(nes_vt_state::chr_r) { - int realaddr = calculate_real_video_address(offset, 1, 0); - return m_prgrom[realaddr & (m_romsize-1)]; + if(m_4242 & 0x1 || m_411d & 0x04) { + return m_chrram[offset]; + } else { + int realaddr = calculate_real_video_address(offset, 1, 0); + return m_prgrom[realaddr & (m_romsize-1)]; + } +} + + +WRITE8_MEMBER(nes_vt_state::chr_w) +{ + if(m_4242 & 0x1 || m_411d & 0x04) { + logerror("vram write %04x %02x\n", offset, data); + m_chrram[offset] = data; + } + /*int realaddr = calculate_real_video_address(offset, 1, 0); + return m_prgrom[realaddr & (m_romsize-1)];*/ } +WRITE8_MEMBER(nes_vt_state::vtfp_411e_w) { + logerror("411e_w %02x\n", data); + if(data == 0x05) + dynamic_cast<m6502_vtscr&>(*m_maincpu).set_next_scramble(true); + else if(data == 0x00) + dynamic_cast<m6502_vtscr&>(*m_maincpu).set_next_scramble(false); +} + +WRITE8_MEMBER(nes_vt_state::vtfp_4a00_w) { + logerror("4a00_w %02x\n", data); + //if(data == 0x80) + // dynamic_cast<m6502_vtscr&>(*m_maincpu).set_scramble(false); +} + + PALETTE_INIT_MEMBER(nes_vt_state, nesvt) { m_ppu->init_palette(palette, 0); @@ -418,7 +645,7 @@ void nes_vt_state::video_irq(bool hblank, int scanline, int vblank, int blanked) if (m_timer_val < 0) { - if (m_timer_irq_enabled) + if (m_timer_irq_enabled && !blanked) { logerror("scanline_irq %d\n", scanline); irqstate = 1; @@ -428,8 +655,8 @@ void nes_vt_state::video_irq(bool hblank, int scanline, int vblank, int blanked) if (irqstate) m_maincpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE); - else - m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE); + //else + // m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE); } } @@ -442,6 +669,7 @@ READ8_MEMBER(nes_vt_state::nt_r) WRITE8_MEMBER(nes_vt_state::nt_w) { + //logerror("nt wr %04x %02x", offset, data); m_ntram[decode_nt_addr(offset)] = data; } @@ -458,6 +686,8 @@ void nes_vt_state::machine_start() m_prgbank3->configure_entries(0, m_numbanks, &m_prgrom[0x00000], 0x2000); save_item(NAME(m_410x)); + save_item(NAME(m_413x)); + save_item(NAME(m_8000_addr_latch)); save_item(NAME(m_timer_irq_enabled)); @@ -467,12 +697,18 @@ void nes_vt_state::machine_start() m_ntram = std::make_unique<uint8_t[]>(0x2000); save_pointer(NAME(m_ntram.get()), 0x2000); + m_chrram = std::make_unique<uint8_t[]>(0x2000); + save_pointer(NAME(m_chrram.get()), 0x2000); + m_ppu->set_scanline_callback(ppu2c0x_device::scanline_delegate(FUNC(nes_vt_state::scanline_irq),this)); m_ppu->set_hblank_callback(ppu2c0x_device::scanline_delegate(FUNC(nes_vt_state::hblank_irq),this)); // m_ppu->set_hblank_callback(ppu2c0x_device::hblank_delegate(FUNC(device_nes_cart_interface::hblank_irq),m_cartslot->m_cart)); // m_ppu->space(AS_PROGRAM).install_readwrite_handler(0, 0x1fff, read8_delegate(FUNC(device_nes_cart_interface::chr_r),m_cartslot->m_cart), write8_delegate(FUNC(device_nes_cart_interface::chr_w),m_cartslot->m_cart)); m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(nes_vt_state::nt_r),this), write8_delegate(FUNC(nes_vt_state::nt_w),this)); + m_ppu->space(AS_PROGRAM).install_readwrite_handler(0, 0x1fff, read8_delegate(FUNC(nes_vt_state::chr_r),this), write8_delegate(FUNC(nes_vt_state::chr_w),this)); + + } void nes_vt_state::machine_reset() @@ -491,7 +727,10 @@ void nes_vt_state::machine_reset() m_410x[0xa] = 0x00; m_410x[0xb] = 0x00; m_411c = 0x00; - m_412c = 0x00; + m_411d = 0x00; + m_4242 = 0x00; + + m_ahigh = (m_csel->read() == 0x01) ? (1 << 25) : 0x0; m_timer_irq_enabled = 0; m_timer_running = 0; m_timer_val = 0; @@ -705,96 +944,144 @@ int nes_vt_state::calculate_real_video_address(int addr, int extended, int readt } } - uint32_t amod = (m_412c & 0x04) ? (1 << 24) : 0x0; - return amod | finaladdr; + return m_ahigh | finaladdr; } /* nes_vt_state::vt03_8000_w notes - this is used by - VT03dogA.bin - at least, but even in EmuVT the sprite graphics there are corrupt - so I'm not sure if it's just an incomplete demo, or there is more to this + used for MMC3/other mapper compatibility + some consoles have scrambled registers for crude copy protection */ -// MMC3 compatibility mode -WRITE8_MEMBER(nes_vt_state::vt03_8000_w) +static const uint8_t descram_8000_mmc3[5][8] = { + {0x6, 0x7, 0x2, 0x3, 0x4, 0x5, 0x7, 0x8}, + {0x5, 0x4, 0x3, 0x2, 0x7, 0x6, 0x7, 0x8}, + {0x6, 0x7, 0x2, 0x3, 0x4, 0x5, 0x8, 0x7}, + {0x6, 0x7, 0x2, 0x3, 0x4, 0x5, 0x7, 0x8}, + {0x6, 0x7, 0x2, 0x3, 0x4, 0x5, 0x7, 0x8}, +}; + +void nes_vt_state::scrambled_8000_w(address_space &space, uint16_t offset, uint8_t data, vt_scramble_mode scram) { - //logerror("%s: vt03_8000_w (%04x) %02x\n", machine().describe_context(), offset+0x8000, data ); uint16_t addr = offset + 0x8000; - if((addr < 0xA000) && !(addr & 0x01)) { - // Bank select - m_8000_addr_latch = data & 0x07; - // Bank config - m_410x[0x05] &= 0x3F; - m_410x[0x05] |= (data & 0xC0); + if((m_411d & 0x01) && (m_411d & 0x03)) { + //CNROM compat + logerror("vtxx_cnrom_8000_w (%04x) %02x\n", offset+0x8000, data ); + m_ppu->set_201x_reg(0x6, data * 8); + m_ppu->set_201x_reg(0x7, data * 8 + 2); + m_ppu->set_201x_reg(0x2, data * 8 + 4); + m_ppu->set_201x_reg(0x3, data * 8 + 5); + m_ppu->set_201x_reg(0x4, data * 8 + 6); + m_ppu->set_201x_reg(0x5, data * 8 + 7); + + } else if(m_411d & 0x01) { + //MMC1 compat, TODO + logerror("vtxx_mmc1_8000_w (%04x) %02x\n", offset+0x8000, data ); + + } else if(m_411d & 0x02) { + //UNROM compat + logerror("vtxx_unrom_8000_w (%04x) %02x\n", offset+0x8000, data ); + + m_410x[0x7] = ((data & 0x0F) << 1); + m_410x[0x8] = ((data & 0x0F) << 1) + 1; update_banks(); - } else if((addr < 0xA000) && (addr & 0x01)) { - switch(m_8000_addr_latch) { - case 0x00: - m_ppu->set_201x_reg(0x6, data); - break; - - case 0x01: - m_ppu->set_201x_reg(0x7, data); - break; - - case 0x02: // hand? - m_ppu->set_201x_reg(0x2, data); - break; - - case 0x03: // dog? - m_ppu->set_201x_reg(0x3, data); - break; - - case 0x04: // ball thrown - m_ppu->set_201x_reg(0x4, data); - break; - - case 0x05: // ball thrown - m_ppu->set_201x_reg(0x5, data); - break; - case 0x06: - m_410x[0x7] = data; - //m_410x[0x9] = data; - update_banks(); - break; - - case 0x07: - m_410x[0x8] = data; - update_banks(); - break; - } - } else if((addr >= 0xA000) && (addr < 0xC000) && !(addr & 0x01)) { - // Mirroring - m_410x[0x6] &= 0xFE; - m_410x[0x6] |= data & 0x01; - } else if((addr >= 0xA000) && (addr < 0xC000) && (addr & 0x01)) { - // PRG RAM control, ignore - } else if((addr >= 0xC000) && (addr < 0xE000) && !(addr & 0x01)) { - // IRQ latch - vt03_410x_w(space, 1, data); - } else if((addr >= 0xC000) && (addr < 0xE000) && (addr & 0x01)) { - // IRQ reload - vt03_410x_w(space, 2, data); - } else if((addr >= 0xE000) && !(addr & 0x01)) { - // IRQ disable - vt03_410x_w(space, 3, data); - } else if((addr >= 0xE000) && (addr & 0x01)) { - // IRQ enable - vt03_410x_w(space, 4, data); } else { + //logerror("vtxx_mmc3_8000_w (%04x) %02x\n", offset+0x8000, data ); + + //MMC3 compat + if((addr < 0xA000) && !(addr & 0x01)) { + // Bank select + m_8000_addr_latch = data & 0x07; + // Bank config + m_410x[0x05] = data & ~(1 << 5); + update_banks(); + } else if((addr < 0xA000) && (addr & 0x01)) { + switch(m_410x[0x05] & 0x07) { + case 0x00: + m_ppu->set_201x_reg(descram_8000_mmc3[(int)scram][0], data); + break; + + case 0x01: + m_ppu->set_201x_reg(descram_8000_mmc3[(int)scram][1], data); + break; + + case 0x02: // hand? + m_ppu->set_201x_reg(descram_8000_mmc3[(int)scram][2], data); + break; + + case 0x03: // dog? + m_ppu->set_201x_reg(descram_8000_mmc3[(int)scram][3], data); + break; + + case 0x04: // ball thrown + m_ppu->set_201x_reg(descram_8000_mmc3[(int)scram][4], data); + break; + + case 0x05: // ball thrown + m_ppu->set_201x_reg(descram_8000_mmc3[(int)scram][5], data); + break; + case 0x06: + m_410x[descram_8000_mmc3[(int)scram][6]] = data; + //m_410x[0x9] = data; + update_banks(); + break; + + case 0x07: + m_410x[descram_8000_mmc3[(int)scram][7]] = data; + update_banks(); + break; + } + } else if((addr >= 0xA000) && (addr < 0xC000) && !(addr & 0x01)) { + // Mirroring + m_410x[0x6] &= 0xFE; + m_410x[0x6] |= data & 0x01; + } else if((addr >= 0xA000) && (addr < 0xC000) && (addr & 0x01)) { + // PRG RAM control, ignore + } else if((addr >= 0xC000) && (addr < 0xE000) && !(addr & 0x01)) { + // IRQ latch + vt03_410x_w(space, 1, data); + } else if((addr >= 0xC000) && (addr < 0xE000) && (addr & 0x01)) { + // IRQ reload + vt03_410x_w(space, 2, data); + } else if((addr >= 0xE000) && !(addr & 0x01)) { + // IRQ disable + vt03_410x_w(space, 3, data); + } else if((addr >= 0xE000) && (addr & 0x01)) { + // IRQ enable + vt03_410x_w(space, 4, data); + } else { + } } +} +// MMC3 compatibility mode +WRITE8_MEMBER(nes_vt_state::vt03_8000_w) +{ + scrambled_8000_w(space, offset, data, vt_scramble_mode::NO_SCRAMBLE); + //logerror("%s: vt03_8000_w (%04x) %02x\n", machine().describe_context(), offset+0x8000, data ); +} +WRITE8_MEMBER(nes_vt_state::vt03_8000_hum_w) +{ + scrambled_8000_w(space, offset, data, vt_scramble_mode::HUMMER); +} +WRITE8_MEMBER(nes_vt_state::vt03_8000_pjoy_w) +{ + scrambled_8000_w(space, offset, data, vt_scramble_mode::PJOY); +} + +WRITE8_MEMBER(nes_vt_state::vt03_8000_sp69_w) +{ + scrambled_8000_w(space, offset, data, vt_scramble_mode::SP69); } /* APU plumbing, this is because we have a plain M6502 core in the VT03, otherwise this is handled in the core */ READ8_MEMBER(nes_vt_state::psg1_4014_r) { - return m_apu->read(space, 0x14); + //return m_apu->read(space, 0x14); + return 0x00; } READ8_MEMBER(nes_vt_state::psg1_4015_r) @@ -837,10 +1124,18 @@ void nes_vt_state::do_dma(uint8_t data, bool broken) } uint16_t src_addr = (data << 8) | (src_nib_74 << 4); logerror("vthh dma start ctrl=%02x addr=%04x\n", m_vdma_ctrl, src_addr); + if(dma_mode == 1) { + logerror("vdma dest %04x\n", m_ppu->get_vram_dest()); + } if(broken && (dma_mode == 1) && ((m_ppu->get_vram_dest() & 0xFF00) == 0x3F00) && !(m_ppu->get_201x_reg(0x1) & 0x80)) { length -= 1; src_addr += 1; + } else if((dma_mode == 1) && ((m_ppu->get_vram_dest() & 0xFF00) == 0x3F01) + && !(m_ppu->get_201x_reg(0x1) & 0x80)) { + // Legacy mode for DGUN-2573 compat + m_ppu->set_vram_dest(0x3F00); + ppu_vt03_device::set_palette_mode(*m_ppu, PAL_MODE_VT0x); } for (int i = 0; i < length; i++) { @@ -850,7 +1145,7 @@ void nes_vt_state::do_dma(uint8_t data, bool broken) } else { m_maincpu->space(AS_PROGRAM).write_byte(0x2004, spriteData); } - if(((src_addr + i) & 0xFF) == length) break; + //if(((src_addr + i) & 0xFF) == length && (i != 0)) break; } // should last (length * 4 - 1) CPU cycles. @@ -860,11 +1155,12 @@ void nes_vt_state::do_dma(uint8_t data, bool broken) WRITE8_MEMBER(nes_vt_state::vt03_4034_w) { + logerror("vt03_4034_w %02x\n", data); m_vdma_ctrl = data; } static ADDRESS_MAP_START( nes_vt_map, AS_PROGRAM, 8, nes_vt_state ) - AM_RANGE(0x0000, 0x1fff) AM_MASK(0x07FF) AM_RAM + AM_RANGE(0x0000, 0x07ff) AM_RAM AM_RANGE(0x2000, 0x3fff) AM_MASK(0x001F) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write) /* PPU registers */ AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("apu", nesapu_device, read, write) @@ -875,23 +1171,48 @@ static ADDRESS_MAP_START( nes_vt_map, AS_PROGRAM, 8, nes_vt_state ) AM_RANGE(0x4034, 0x4034) AM_WRITE(vt03_4034_w) - AM_RANGE(0x4100, 0x410b) AM_WRITE(vt03_410x_w) + AM_RANGE(0x4100, 0x410b) AM_READ(vt03_410x_r) AM_WRITE(vt03_410x_w) AM_RANGE(0x8000, 0xffff) AM_DEVICE("prg", address_map_bank_device, amap8) AM_RANGE(0x8000, 0xffff) AM_WRITE(vt03_8000_w) AM_RANGE(0x6000, 0x7fff) AM_RAM ADDRESS_MAP_END + /* Some later VT models have more RAM */ static ADDRESS_MAP_START( nes_vt_xx_map, AS_PROGRAM, 8, nes_vt_state ) AM_IMPORT_FROM(nes_vt_map) AM_RANGE(0x0800, 0x0fff) AM_RAM ADDRESS_MAP_END + +static ADDRESS_MAP_START( nes_vt_hum_map, AS_PROGRAM, 8, nes_vt_state ) +AM_IMPORT_FROM(nes_vt_map) +AM_RANGE(0x4100, 0x410b) AM_WRITE(vt03_410x_hum_w) +AM_RANGE(0x8000, 0xffff) AM_WRITE(vt03_8000_hum_w) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( nes_vt_pjoy_map, AS_PROGRAM, 8, nes_vt_state ) +AM_IMPORT_FROM(nes_vt_map) +AM_RANGE(0x4100, 0x410b) AM_WRITE(vt03_410x_pjoy_w) +AM_RANGE(0x8000, 0xffff) AM_WRITE(vt03_8000_pjoy_w) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( nes_vt_sp69_map, AS_PROGRAM, 8, nes_vt_state ) +AM_IMPORT_FROM(nes_vt_map) +AM_RANGE(0x4100, 0x410b) AM_WRITE(vt03_410x_sp69_w) +AM_RANGE(0x8000, 0xffff) AM_WRITE(vt03_8000_sp69_w) +ADDRESS_MAP_END + + static ADDRESS_MAP_START( nes_vt_cy_map, AS_PROGRAM, 8, nes_vt_state ) AM_IMPORT_FROM(nes_vt_xx_map) AM_RANGE(0x41b0, 0x41bf) AM_READ(vt03_41bx_r) AM_WRITE(vt03_41bx_w) AM_RANGE(0x48a0, 0x48af) AM_READ(vt03_48ax_r) AM_WRITE(vt03_48ax_w) + AM_RANGE(0x4130, 0x4136) AM_READ(vt03_413x_r) AM_WRITE(vt03_413x_w) + AM_RANGE(0x414F, 0x414F) AM_READ(vt03_414f_r) + AM_RANGE(0x415C, 0x415C ) AM_READ(vt03_415c_r) + ADDRESS_MAP_END static ADDRESS_MAP_START( nes_vt_bt_map, AS_PROGRAM, 8, nes_vt_state ) @@ -909,13 +1230,17 @@ static ADDRESS_MAP_START( nes_vt_hh_map, AS_PROGRAM, 8, nes_vt_state ) AM_RANGE(0x4016, 0x4016) AM_READWRITE(nes_in0_r, nes_in0_w) AM_RANGE(0x4017, 0x4017) AM_READ(nes_in1_r) AM_WRITE(psg1_4017_w) - AM_RANGE(0x4100, 0x410b) AM_WRITE(vt03_410x_w) + AM_RANGE(0x4100, 0x410b) AM_READ(vt03_410x_r) AM_WRITE(vt03_410x_w) AM_RANGE(0x8000, 0xffff) AM_DEVICE("prg", address_map_bank_device, amap8) AM_RANGE(0x8000, 0xffff) AM_WRITE(vt03_8000_w) AM_RANGE(0x4034, 0x4034) AM_WRITE(vt03_4034_w) AM_RANGE(0x4014, 0x4014) AM_READ(psg1_4014_r) AM_WRITE(vt_hh_sprite_dma_w) + + AM_RANGE(0x414A, 0x414A) AM_READ(vthh_414a_r) + AM_RANGE(0x411d, 0x411d) AM_WRITE(vtfp_411d_w) + AM_RANGE(0x6000, 0x7fff) AM_RAM ADDRESS_MAP_END @@ -928,7 +1253,7 @@ static ADDRESS_MAP_START( nes_vt_dg_map, AS_PROGRAM, 8, nes_vt_state ) AM_RANGE(0x4016, 0x4016) AM_READWRITE(nes_in0_r, nes_in0_w) AM_RANGE(0x4017, 0x4017) AM_READ(nes_in1_r) AM_WRITE(psg1_4017_w) - AM_RANGE(0x4100, 0x410b) AM_WRITE(vt03_410x_w) + AM_RANGE(0x4100, 0x410b) AM_READ(vt03_410x_r) AM_WRITE(vt03_410x_w) AM_RANGE(0x411c, 0x411c) AM_WRITE(vt03_411c_w) @@ -940,6 +1265,26 @@ static ADDRESS_MAP_START( nes_vt_dg_map, AS_PROGRAM, 8, nes_vt_state ) AM_RANGE(0x6000, 0x7fff) AM_RAM ADDRESS_MAP_END +static ADDRESS_MAP_START( nes_vt_fp_map, AS_PROGRAM, 8, nes_vt_state ) + AM_IMPORT_FROM(nes_vt_hh_map) + AM_RANGE(0x411e, 0x411e) AM_WRITE(vtfp_411e_w) + AM_RANGE(0x4a00, 0x4a00) AM_WRITE(vtfp_4a00_w) + AM_RANGE(0x412c, 0x412c) AM_WRITE(vtfp_412c_w) + AM_RANGE(0x412d, 0x412d) AM_READ(vtfp_412d_r) + AM_RANGE(0x4242, 0x4242) AM_WRITE(vtfp_4242_w) + AM_RANGE(0x4119, 0x4119) AM_READ(vtfp_4119_r) + +ADDRESS_MAP_END + +static ADDRESS_MAP_START( nes_vt_fa_map, AS_PROGRAM, 8, nes_vt_state ) + + AM_IMPORT_FROM(nes_vt_dg_map) + + AM_RANGE(0x412c, 0x412c) AM_READ(vtfa_412c_r) AM_WRITE(vtfa_412c_w) + AM_RANGE(0x4242, 0x4242) AM_WRITE(vtfp_4242_w) + +ADDRESS_MAP_END + static ADDRESS_MAP_START( prg_map, AS_PROGRAM, 8, nes_vt_state ) AM_RANGE(0x0000, 0x1fff) AM_ROMBANK("prg_bank0") AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("prg_bank1") @@ -993,9 +1338,17 @@ static GFXDECODE_START( vt03_helper ) GFXDECODE_END +static const uint8_t descram_ppu_2012_2017[5][6] = { + {0x2, 0x3, 0x4, 0x5, 0x6, 0x7}, + {0x3, 0x2, 0x7, 0x6, 0x5, 0x4}, + {0x2, 0x3, 0x4, 0x5, 0x6, 0x7}, + {0x7, 0x6, 0x5, 0x4, 0x2, 0x3}, + {0x4, 0x7, 0x2, 0x6, 0x5, 0x3}, +}; + MACHINE_CONFIG_START(nes_vt_state::nes_vt) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", M6502, NTSC_APU_CLOCK) // selectable speed? + MCFG_CPU_ADD("maincpu", M6502_VTSCR, NTSC_APU_CLOCK) // selectable speed? MCFG_CPU_PROGRAM_MAP(nes_vt_map) MCFG_SCREEN_ADD("screen", RASTER) @@ -1043,6 +1396,32 @@ MACHINE_CONFIG_START(nes_vt_state::nes_vt) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) MACHINE_CONFIG_END +MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_hum, nes_vt) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(nes_vt_hum_map) + + MCFG_PPU_VT03_MODIFY("ppu") + MCFG_PPU_VT03_SET_DESCRAMBLE(descram_ppu_2012_2017[3]); +MACHINE_CONFIG_END + +MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_pjoy, nes_vt) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(nes_vt_pjoy_map) + + MCFG_PPU_VT03_MODIFY("ppu") + MCFG_PPU_VT03_SET_DESCRAMBLE(descram_ppu_2012_2017[2]); +MACHINE_CONFIG_END + + +MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_sp69, nes_vt) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(nes_vt_sp69_map) + + MCFG_PPU_VT03_MODIFY("ppu") + MCFG_PPU_VT03_SET_DESCRAMBLE(descram_ppu_2012_2017[4]); +MACHINE_CONFIG_END + + MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_xx, nes_vt) MCFG_CPU_MODIFY("maincpu") MCFG_CPU_PROGRAM_MAP(nes_vt_xx_map) @@ -1095,8 +1474,37 @@ MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_hh, nes_vt_xx) MACHINE_CONFIG_END static INPUT_PORTS_START( nes_vt ) +PORT_START("CARTSEL") INPUT_PORTS_END +MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_fp, nes_vt_xx) +MCFG_CPU_MODIFY("maincpu") +MCFG_CPU_PROGRAM_MAP(nes_vt_fp_map) + +MCFG_PPU_VT03_MODIFY("ppu") +MCFG_PPU_VT03_SET_PAL_MODE(PAL_MODE_NEW_RGB12); +MACHINE_CONFIG_END + +MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_fa, nes_vt_xx) +MCFG_CPU_MODIFY("maincpu") +MCFG_CPU_PROGRAM_MAP(nes_vt_fa_map) + +MACHINE_CONFIG_END + + +static INPUT_PORTS_START( nes_vt_fp ) + PORT_START("CARTSEL") + PORT_DIPNAME( 0x06, 0x00, "Cartridge Select" ) PORT_CODE(KEYCODE_3) PORT_TOGGLE + PORT_DIPSETTING( 0x00, "472-in-1" ) + PORT_DIPSETTING( 0x06, "128-in-1" ) +MACHINE_CONFIG_END + +static INPUT_PORTS_START( nes_vt_fa ) + PORT_START("CARTSEL") + PORT_DIPNAME( 0x01, 0x00, "Cartridge Select" ) PORT_CODE(KEYCODE_3) PORT_TOGGLE + PORT_DIPSETTING( 0x00, "508-in-1" ) + PORT_DIPSETTING( 0x01, "130-in-1" ) +MACHINE_CONFIG_END ROM_START( vdogdeme ) @@ -1273,6 +1681,11 @@ ROM_START( sy889 ) ROM_REGION( 0x800000, "mainrom", 0 ) ROM_LOAD( "sy889_w25q64.bin", 0x00000, 0x800000, CRC(fcdaa6fc) SHA1(0493747facf2172b8af22010851668bb18cbb3e4) ) ROM_END + +ROM_START( sy888b ) + ROM_REGION( 0x400000, "mainrom", 0 ) + ROM_LOAD( "sy888b_f25q32.bin", 0x00000, 0x400000, CRC(a8298c33) SHA1(7112dd13d5fb5f9f9d496816758defd22773ec6e) ) +ROM_END #if 0 ROM_START( mc_15kin1 ) ROM_REGION( 0x200000, "mainrom", 0 ) @@ -1291,7 +1704,7 @@ ROM_END #endif ROM_START( dgun2573 ) ROM_REGION( 0x2000000, "mainrom", 0 ) - ROM_LOAD( "dgun2573.bin", 0x00000, 0x2000000, CRC(cde71a53) SHA1(d0d4c1965876291861781ecde46b1142b062f1f3) ) + ROM_LOAD( "dgun2573.bin", 0x00000, 0x2000000, BAD_DUMP CRC(cde71a53) SHA1(d0d4c1965876291861781ecde46b1142b062f1f3) ) ROM_END ROM_START( bittboy ) @@ -1299,6 +1712,61 @@ ROM_START( bittboy ) ROM_LOAD( "bittboy_flash_read_S29GL256N-TF-V2.bin", 0x00000, 0x2000000, CRC(24c802d7) SHA1(c1300ff799b93b9b53060b94d3985db4389c5d3a) ) ROM_END +ROM_START( mc_89in1 ) + ROM_REGION( 0x400000, "mainrom", 0 ) + ROM_LOAD( "89in1.bin", 0x00000, 0x400000, CRC(b97f8ce5) SHA1(1a8e67f2b58a671ceec2b0ed18ec5954a71ae63a) ) +ROM_END + +ROM_START( mc_cb280 ) + ROM_REGION( 0x400000, "mainrom", 0 ) + ROM_LOAD( "w25q32.u5", 0x00000, 0x400000, CRC(c9541bdf) SHA1(f0ce46f18658ca5dbed881e5a80460e59820bbd0) ) +ROM_END + +ROM_START( mc_pg150 ) + ROM_REGION( 0x2000000, "mainrom", 0 ) + ROM_LOAD( "pocketgames150-in1.bin", 0x00000, 0x2000000, CRC(32f1176b) SHA1(2cfd9b61ebdfc328f020ae9bd5e5e2219321e828) ) +ROM_END + +ROM_START( mc_hh210 ) + ROM_REGION( 0x1000000, "mainrom", 0 ) + ROM_LOAD( "msp55lv128t.u4", 0x00000, 0x1000000, CRC(9ba520d4) SHA1(627f811b24314197e289a2ade668ff4115421bed) ) +ROM_END + +ROM_START( dvnimbus ) + ROM_REGION( 0x1000000, "mainrom", 0 ) + ROM_LOAD( "2012-7-4-V1.BIN", 0x00000, 0x1000000, CRC(a91d7aa6) SHA1(9421b70b281bb630752bc352c3715258044c0bbe) ) +ROM_END + +ROM_START( cbrs8 ) + ROM_REGION( 0x1000000, "mainrom", 0 ) + ROM_LOAD( "RS-8.bin", 0x00000, 0x1000000, BAD_DUMP CRC(10b2bed0) SHA1(0453a1e6769818ccf25dcf22b2c6198a5688a1d4) ) +ROM_END + +ROM_START( mc_tv200 ) + ROM_REGION( 0x800000, "mainrom", 0 ) + ROM_LOAD( "S29GL064N90.bin", 0x00000, 0x800000, CRC(ae1905d2) SHA1(11582055713ba937c1ad32c4ada8683eebc1c83c) ) +ROM_END + +ROM_START( fcpocket ) + ROM_REGION( 0x8000000, "mainrom", 0 ) + ROM_LOAD( "S29GL01GP.bin", 0x00000, 0x8000000, CRC(8703b18a) SHA1(07943443294e80ca93f83181c8bdbf950b87c52f) ) +ROM_END + +ROM_START( mog_m320 ) + ROM_REGION( 0x800000, "mainrom", 0 ) + ROM_LOAD( "W25Q64FV.bin", 0x00000, 0x800000, CRC(3c5e1b36) SHA1(4bcbf35ebf2b1714ccde5de758a89a6a39528f89) ) +ROM_END + +ROM_START( fapocket ) + ROM_REGION( 0x4000000, "mainrom", 0 ) + ROM_LOAD( "S29GL512N.bin", 0x00000, 0x4000000, CRC(37d0fb06) SHA1(0146a2fae32e23b65d4032c508f0d12cedd399c3) ) +ROM_END + +ROM_START( zdog ) + ROM_REGION( 0x400000, "mainrom", 0 ) + ROM_LOAD( "zdog.bin", 0x00000, 0x400000, CRC(5ed3485b) SHA1(5ab0e9370d4ed1535205deb0456878c4e400dd81) ) +ROM_END + // earlier version of vdogdemo CONS( 200?, vdogdeme, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "VRT", "V-Dog (prototype, earlier)", MACHINE_NOT_WORKING ) @@ -1325,52 +1793,86 @@ CONS( 200?, vgpmini, 0, 0, nes_vt_vg, nes_vt, nes_vt_state, 0, "<unknown>", // emulation CONS( 200?, dgun2500, 0, 0, nes_vt_dg, nes_vt, nes_vt_state, 0, "dreamGEAR", "dreamGEAR Wireless Motion Control with 130 games (DGUN-2500)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND) -// these are NOT VT03, but something newer but based around the same basic designs -// (no visible tiles in ROM using standard decodes tho, might need moving out of here) -// dgun2561 at least boots, but no visible gfx due to missing PPU features -CONS( 2012, dgun2561, 0, 0, nes_vt_dg, nes_vt, nes_vt_state, 0, "dreamGEAR", "dreamGEAR My Arcade Portable Gaming System (DGUN-2561)", MACHINE_NOT_WORKING ) -CONS( 2015, dgun2573, 0, 0, nes_vt_hh, nes_vt, nes_vt_state, 0, "dreamGEAR", "dreamGEAR My Arcade Gamer V Portable Gaming System (DGUN-2573)", MACHINE_NOT_WORKING ) +// don't even get to menu. very enhanced chipset, VT368/9? +CONS( 2012, dgun2561, 0, 0, nes_vt_cy, nes_vt, nes_vt_state, 0, "dreamGEAR", "dreamGEAR My Arcade Portable Gaming System (DGUN-2561)", MACHINE_NOT_WORKING ) CONS( 200?, lexcyber, 0, 0, nes_vt_cy, nes_vt, nes_vt_state, 0, "Lexibook", "Lexibook Compact Cyber Arcade", MACHINE_NOT_WORKING ) +// boots, same platform with scrambled opcodes as FC pocket +// palette issues in some games because they actually use the old VT style palette +// but no way to switch? +// some menu gfx broken, probably because this is a bad dump +CONS( 2015, dgun2573, 0, 0, nes_vt_fp, nes_vt, nes_vt_state, 0, "dreamGEAR", "dreamGEAR My Arcade Gamer V Portable Gaming System (DGUN-2573)", MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) + // these are VT1682 based and have scrambled CPU opcodes. Will need VT1682 CPU and PPU // to be emulated // (no visible tiles in ROM using standard decodes tho, might need moving out of here) CONS( 200?, ii8in1, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "Intec", "InterAct 8-in-1", MACHINE_NOT_WORKING ) CONS( 200?, ii32in1, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "Intec", "InterAct 32-in-1", MACHINE_NOT_WORKING ) -// this has 'Shark' and 'Octopus' etc. like mc_dgear but the graphics are entirely corrupt for any game using the extended modes, bad dump or different banking? -CONS( 200?, mc_sp69, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "Sports Game 69 in 1", MACHINE_NOT_WORKING ) +// this has 'Shark' and 'Octopus' etc. like mc_dgear but uses scrambled bank registers +CONS( 200?, mc_sp69, 0, 0, nes_vt_sp69, nes_vt, nes_vt_state, 0, "<unknown>", "Sports Game 69 in 1", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND) -// doesn't boot -CONS( 200?, mc_sam60, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "Hummer Technology Co., Ltd.", "Samuri (60 in 1)", MACHINE_NOT_WORKING ) +// Hummer systems, scrambled bank register +CONS( 200?, mc_sam60, 0, 0, nes_vt_hum, nes_vt, nes_vt_state, 0, "Hummer Technology Co., Ltd.", "Samuri (60 in 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) +CONS( 200?, zdog, 0, 0, nes_vt_hum, nes_vt, nes_vt_state, 0, "Hummer Technology Co., Ltd.", "ZDog (44 in 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) // titles below don't seem to use the enhanced modes, so probably VT01 / VT02 or plain standalone famiclones? // very plain menus -CONS( 200?, pjoyn50, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "PowerJoy Navigator 50 in 1", MACHINE_NOT_WORKING ) -CONS( 200?, pjoys30, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "PowerJoy Supermax 30 in 1", MACHINE_NOT_WORKING ) -CONS( 200?, pjoys60, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "PowerJoy Supermax 60 in 1", MACHINE_NOT_WORKING ) +CONS( 200?, pjoyn50, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "PowerJoy Navigator 50 in 1", MACHINE_IMPERFECT_GRAPHICS ) +CONS( 200?, pjoys30, 0, 0, nes_vt_pjoy, nes_vt, nes_vt_state, 0, "<unknown>", "PowerJoy Supermax 30 in 1", MACHINE_IMPERFECT_GRAPHICS ) +CONS( 200?, pjoys60, 0, 0, nes_vt_pjoy, nes_vt, nes_vt_state, 0, "<unknown>", "PowerJoy Supermax 60 in 1", MACHINE_IMPERFECT_GRAPHICS ) // has a non-enhanced version of 'Octopus' as game 30 -CONS( 200?, sarc110, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "Super Arcade 110 (set 1)", MACHINE_NOT_WORKING ) -CONS( 200?, sarc110a, sarc110, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "Super Arcade 110 (set 2)", MACHINE_NOT_WORKING ) +CONS( 200?, sarc110, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "Super Arcade 110 (set 1)", MACHINE_IMPERFECT_GRAPHICS ) +CONS( 200?, sarc110a, sarc110, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "Super Arcade 110 (set 2)", MACHINE_IMPERFECT_GRAPHICS ) // both offer chinese or english menus CONS( 200?, mc_110cb, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "CoolBoy", "110 in 1 CoolBaby (CoolBoy RS-1S)", MACHINE_IMPERFECT_GRAPHICS ) CONS( 200?, mc_138cb, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "CoolBoy", "138 in 1 CoolBaby (CoolBoy RS-5, PCB060-10009011V1.3)", MACHINE_IMPERFECT_GRAPHICS ) +// doesn't boot, bad dump +CONS( 201?, cbrs8, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "CoolBoy", "CoolBoy RS-8 168 in 1", MACHINE_NOT_WORKING ) + CONS( 200?, gprnrs1, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "Game Prince RS-1", MACHINE_IMPERFECT_GRAPHICS ) CONS( 200?, gprnrs16, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "Game Prince RS-16", MACHINE_IMPERFECT_GRAPHICS ) // unsorted, these were all in nes.xml listed as ONE BUS systems CONS( 200?, mc_dg101, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "dreamGEAR", "dreamGEAR 101 in 1", MACHINE_IMPERFECT_GRAPHICS ) // dreamGear, but no enhanced games? -CONS( 200?, mc_aa2, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "100 in 1 Arcade Action II (AT-103)", MACHINE_NOT_WORKING ) +CONS( 200?, mc_aa2, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "100 in 1 Arcade Action II (AT-103)", MACHINE_IMPERFECT_GRAPHICS ) CONS( 200?, mc_105te, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "2011 Super HiK 105 in 1 Turbo Edition", MACHINE_NOT_WORKING ) -CONS( 200?, mc_8x6cb, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "CoolBoy", "888888 in 1 (Coolboy AEF-390)", MACHINE_NOT_WORKING ) -CONS( 200?, mc_9x6ss, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "999999 in 1 (PXP2 Slim Station)", MACHINE_NOT_WORKING ) -CONS( 200?, mc_9x6sa, mc_9x6ss, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "999999 in 1 (8 bit Slim Station, NEWPXP-DVT22-A PCB)", MACHINE_NOT_WORKING ) +CONS( 200?, mc_8x6cb, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "CoolBoy", "888888 in 1 (Coolboy AEF-390)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) +CONS( 200?, mc_9x6ss, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "999999 in 1 (PXP2 Slim Station)", MACHINE_IMPERFECT_GRAPHICS ) +CONS( 200?, mc_9x6sa, mc_9x6ss, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "999999 in 1 (8 bit Slim Station, NEWPXP-DVT22-A PCB)", MACHINE_IMPERFECT_GRAPHICS ) CONS( 200?, mc_7x6ss, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "777777 in 1 (8 bit Slim Station, NEWPXP-DVT22-A PCB)", MACHINE_IMPERFECT_GRAPHICS ) CONS( 200?, mc_8x6ss, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "888888 in 1 (8 bit Slim Station, NEWPXP-DVT22-A PCB)", MACHINE_IMPERFECT_GRAPHICS ) CONS( 2004, mc_dcat8, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "100 in 1 (D-CAT8 8bit Console, set 1) (v5.01.11-frd, BL 20041217)", MACHINE_IMPERFECT_GRAPHICS ) CONS( 2004, mc_dcat8a, mc_dcat8, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "100 in 1 (D-CAT8 8bit Console, set 2)", MACHINE_IMPERFECT_GRAPHICS ) + // Runs well, minor GFX issues in intro -CONS( 2017, sy889, 0, 0, nes_vt_hh, nes_vt, nes_vt_state, 0, "SY Corp", "SY-889 300 in 1 Handheld", MACHINE_NOT_WORKING ) +CONS( 2017, sy889, 0, 0, nes_vt_hh, nes_vt, nes_vt_state, 0, "SY Corp", "SY-889 300 in 1 Handheld", MACHINE_IMPERFECT_GRAPHICS ) +CONS( 2016, sy888b, 0, 0, nes_vt_hh, nes_vt, nes_vt_state, 0, "SY Corp", "SY-888B 288 in 1 Handheld", MACHINE_IMPERFECT_GRAPHICS ) + +// Same hardware as SY-889 +CONS( 201?, mc_cb280, 0, 0, nes_vt_hh, nes_vt, nes_vt_state, 0, "CoolBoy", "Coolboy RS-18 (280 in 1)", MACHINE_IMPERFECT_GRAPHICS ) + // Runs well, only issues in SMB3 which crashes -CONS( 2017, bittboy, 0, 0, nes_vt_bt, nes_vt, nes_vt_state, 0, "BittBoy", "BittBoy Mini FC 300 in 1", MACHINE_NOT_WORKING ) +CONS( 2017, bittboy, 0, 0, nes_vt_bt, nes_vt, nes_vt_state, 0, "BittBoy", "BittBoy Mini FC 300 in 1", MACHINE_IMPERFECT_GRAPHICS ) +// Runs well, all games seem to work +CONS( 201?, mc_89in1, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "89 in 1 Mini Game Console (060-92023011V1.0)", MACHINE_IMPERFECT_GRAPHICS ) +// Broken GFX, investigate +CONS( 201?, mc_pg150, 0, 0, nes_vt_bt, nes_vt, nes_vt_state, 0, "<unknown>", "Pocket Games 150 in 1", MACHINE_NOT_WORKING ) +// No title screen, but press start and menu and games run fine. Makes odd +// memory accesses which probably explain broken title screen +CONS( 201?, mc_hh210, 0, 0, nes_vt_xx, nes_vt, nes_vt_state, 0, "<unknown>", "Handheld 210 in 1", MACHINE_NOT_WORKING ) +// First half of games don't work, probably bad dump +CONS( 201?, dvnimbus, 0, 0, nes_vt_vg, nes_vt, nes_vt_state, 0, "<unknown>", "DVTech Nimbus 176 in 1", MACHINE_NOT_WORKING ) +// Works fine, VT02 based +CONS( 201?, mc_tv200, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "Thumbs Up", "200 in 1 Retro TV Game", MACHINE_IMPERFECT_GRAPHICS ) +// New platform with scrambled opcodes, same as DGUN-2561. Runs fine with minor GFX and sound issues in menu +// Use DIP switch to select console or cartridge, as cartridge is fake and just toggles a GPIO +CONS( 2016, fcpocket, 0, 0, nes_vt_fp, nes_vt_fp, nes_vt_state, 0, "<unknown>", "FC Pocket 600 in 1", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) +// Probably VT09 or similar +// Use DIP switch to select console or cartridge, as cartridge is fake and just toggles a ROM high address bit +// (which can also be overriden by GPIO) +CONS( 2017, fapocket, 0, 0, nes_vt_fa, nes_vt_fa, nes_vt_state, 0, "<unknown>", "Family Pocket 638 in 1", MACHINE_IMPERFECT_GRAPHICS ) + +// Plays intro music but then crashes. same hardware as SY-88x but uses more features +CONS( 2016, mog_m320, 0, 0, nes_vt_hh, nes_vt, nes_vt_state, 0, "MOGIS", "MOGIS M320 246 in 1 Handheld", MACHINE_NOT_WORKING ) |