summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author David Shah <davey1576@gmail.com>2018-01-21 21:25:31 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2018-01-21 16:25:31 -0500
commit68b08ceabfad7237ea605c272623bb04fd9d2ec1 (patch)
tree2989e76dfbc084f1d1035c81ed307e6c38f62869
parent0dd46b8f5e526d2c747350fe844ce97f47790a47 (diff)
Multiple nes_vt Improvements (#3099)
* Work on lexcyber * Fix VT03 colours * Video mode tweaks for various VTxx systems (WIP) * Improve VTxx colours * Add some more VTxx systems (all currently broken) * Further graphical improvements for newer VTxx systems * Tweak colours for newer VTxx systems * Fix mirroring in VTxx games * Promote some VTxx systems from MACHINE_NOT_WORKING * Add BittBoy, remove non-VTxx systems, general ordering * Work on MMC3 compatability in VT03 driver * Address decoding fixes * Connect BittBoy ROM A24 to GPIO * More machine promotions following various fixes * Fixes for dgun2500 * VTxxx tidying, remove debugging * Fix nes_vt compilation after merge
-rw-r--r--src/devices/video/ppu2c0x.cpp5
-rw-r--r--src/devices/video/ppu2c0x.h4
-rw-r--r--src/devices/video/ppu2c0x_vt.cpp93
-rw-r--r--src/devices/video/ppu2c0x_vt.h1
-rw-r--r--src/mame/drivers/nes_vt.cpp498
-rw-r--r--src/mame/mame.lst2
6 files changed, 433 insertions, 170 deletions
diff --git a/src/devices/video/ppu2c0x.cpp b/src/devices/video/ppu2c0x.cpp
index 2b4aedd0940..86c265e9035 100644
--- a/src/devices/video/ppu2c0x.cpp
+++ b/src/devices/video/ppu2c0x.cpp
@@ -1325,6 +1325,11 @@ WRITE8_MEMBER( ppu2c0x_device::write )
m_data_latch = data;
}
+uint16_t ppu2c0x_device::get_vram_dest() {
+ return m_videomem_addr;
+}
+
+
/*************************************
*
* Sprite DMA
diff --git a/src/devices/video/ppu2c0x.h b/src/devices/video/ppu2c0x.h
index 4fd5a2e27a5..3f8408b70cc 100644
--- a/src/devices/video/ppu2c0x.h
+++ b/src/devices/video/ppu2c0x.h
@@ -158,6 +158,7 @@ public:
ppu2c0x_device &dev = downcast<ppu2c0x_device &>(device);
dev.m_use_sprite_write_limitation = false;
}
+ uint16_t get_vram_dest();
protected:
// registers definition
@@ -218,7 +219,8 @@ protected:
uint8_t m_planebuf[2];
int m_scanline; /* scanline count */
std::unique_ptr<uint8_t[]> m_spriteram; /* sprite ram */
-
+
+
private:
static constexpr device_timer_id TIMER_HBLANK = 0;
static constexpr device_timer_id TIMER_NMI = 1;
diff --git a/src/devices/video/ppu2c0x_vt.cpp b/src/devices/video/ppu2c0x_vt.cpp
index a9f02890832..fad7f78ab97 100644
--- a/src/devices/video/ppu2c0x_vt.cpp
+++ b/src/devices/video/ppu2c0x_vt.cpp
@@ -47,23 +47,100 @@ void ppu_vt03_device::set_new_pen(int i)
uint8_t red = (rgbval & 0x7C00) >> 7;
m_palette->set_pen_color(i & 0x7f, rgb_t(red, green, blue));
} else {
+ // TODO: should this be tidied up?
uint16_t palval = (m_newpal[i&0x7f] & 0x3f) | ((m_newpal[(i&0x7f)+0x80] & 0x3f)<<6);
- // &0x3f so we don't attempt to use any of the extended colours right now because
- // I haven't managed to work out the format
- m_palette->set_pen_indirect(i&0x7f,palval&0x3f);
+
+ uint8_t rhue = palval & 0x0F;
+ uint8_t rlum = (palval >> 4) & 0x0F;
+ uint8_t rsat = (palval >> 8) & 0x0F;
+ //See http://wiki.nesdev.com/w/index.php/VT03%2B_Enhanced_Palette#Inverted_extended_color_numbers
+ bool inverted = (rlum < ((rsat + 1) >> 1) || rlum > (15 - (rsat >>1)));
+ if(inverted && (m_pal_mode != PAL_MODE_NEW_VG)) {
+ rsat = 16 - rsat;
+ rlum = (rlum - 8) & 0x0F;
+ uint8_t hue_lut[16] = {0xD, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x0, 0xE, 0xF};
+ rhue = hue_lut[rhue];
+ }
+
+ // Get base color
+ double hue = 287.0;
+
+ double Kr = 0.2989;
+ double Kb = 0.1145;
+ double Ku = 2.029;
+ double Kv = 1.140;
+
+ double sat;
+ double y, u, v;
+ double rad;
+ int R, G, B;
+ switch (rhue)
+ {
+ case 0:
+ sat = 0; rad = 0;
+ y = 1.0;
+ break;
+
+ case 13:
+ sat = 0; rad = 0;
+ y = 0.77;
+ break;
+
+ case 14:
+ case 15:
+ sat = 0; rad = 0; y = 0;
+ break;
+
+ default:
+ sat = (m_pal_mode == PAL_MODE_NEW_VG) ? 0.5 : 0.7;
+ rad = M_PI * ((rhue * 30 + hue) / 180.0);
+ y = (m_pal_mode == PAL_MODE_NEW_VG) ? 0.4 : 0.9;
+ break;
+ }
+
+ sat *= (rsat / 15.0);
+ y *= (rlum / 15.0);
+ u = sat * cos(rad);
+ v = sat * sin(rad);
+
+ /* Transform to RGB */
+ R = (y + Kv * v) * 255.0;
+ G = (y - (Kb * Ku * u + Kr * Kv * v) / (1 - Kb - Kr)) * 255.0;
+ B = (y + Ku * u) * 255.0;
+
+ /* Clipping, in case of saturation */
+ if (R < 0)
+ R = 0;
+ if (R > 255)
+ R = 255;
+ if (G < 0)
+ G = 0;
+ if (G > 255)
+ G = 255;
+ if (B < 0)
+ B = 0;
+ if (B > 255)
+ B = 255;
+
+ m_palette->set_pen_color(i & 0x7f, rgb_t(R, G ,B));
}
}
WRITE8_MEMBER(ppu_vt03_device::palette_write)
{
- if (m_201x_regs[0] & 0x80)
+ //logerror("pal write %d %02x\n", offset, data);
+ uint8_t pal_mask = (m_pal_mode == PAL_MODE_NEW_VG) ? 0x04 : 0x80;
+
+ if (m_201x_regs[0] & pal_mask)
{
m_newpal[offset] = data;
set_new_pen(offset);
}
else
{
+ if(m_pal_mode == PAL_MODE_NEW_VG)
+ m_newpal[offset] = data;
ppu2c0x_device::palette_write(space, offset, data);
}
}
@@ -118,7 +195,7 @@ void ppu_vt03_device::device_reset()
for (int i = 0;i < 0x20;i++)
set_201x_reg(i, 0x00);
-
+ init_palette(*m_palette, 0);
m_read_bg4_bg3 = 0;
m_va34 = 0;
}
@@ -294,10 +371,10 @@ void ppu_vt03_device::set_2010_reg(uint8_t data)
2 : SP16EN
1 : BK16EN
0 : PIX16EN */
-
- if ((m_201x_regs[0x0] & 0x80) != (data & 0x80))
+ uint8_t pal_mask = (m_pal_mode == PAL_MODE_NEW_VG) ? 0x08 : 0x80;
+ if ((m_201x_regs[0x0] & pal_mask) != (data & pal_mask))
{
- if (data & 0x80)
+ if (data & pal_mask)
{
for (int i = 0;i < 256;i++)
{
diff --git a/src/devices/video/ppu2c0x_vt.h b/src/devices/video/ppu2c0x_vt.h
index 757254ee966..bc1a723d273 100644
--- a/src/devices/video/ppu2c0x_vt.h
+++ b/src/devices/video/ppu2c0x_vt.h
@@ -33,6 +33,7 @@
enum vtxx_pal_mode {
PAL_MODE_VT0x,
PAL_MODE_NEW_RGB,
+ PAL_MODE_NEW_VG
};
class ppu_vt03_device : public ppu2c0x_device {
diff --git a/src/mame/drivers/nes_vt.cpp b/src/mame/drivers/nes_vt.cpp
index aa8f7eb1a66..a4af638497e 100644
--- a/src/mame/drivers/nes_vt.cpp
+++ b/src/mame/drivers/nes_vt.cpp
@@ -21,7 +21,7 @@
VT16 - ?
VT18 - ?
- Mystery handheld SoC, may or may not be VRT:
+ 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
@@ -34,12 +34,10 @@
driver)
todo (VT03):
-
- add support for basic NES PPU page mirroring (selectable with register)
- work out format of the 12-bit palette, it's meant to be
- 4-bits saturation, 4-bits luminance, 4-bits phase
- as opposed to the basic NES format of 2-luminance, 4-phase
- but getting it correct is tricky:
+
+ 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*
@@ -106,6 +104,14 @@ public:
DECLARE_WRITE8_MEMBER(vt03_410x_w);
DECLARE_WRITE8_MEMBER(vt03_8000_w);
DECLARE_WRITE8_MEMBER(vt03_4034_w);
+
+ DECLARE_WRITE8_MEMBER(vt03_41bx_w);
+ DECLARE_READ8_MEMBER(vt03_41bx_r);
+ DECLARE_WRITE8_MEMBER(vt03_411c_w);
+ DECLARE_WRITE8_MEMBER(vt03_412c_w);
+
+ DECLARE_WRITE8_MEMBER(vt03_48ax_w);
+ DECLARE_READ8_MEMBER(vt03_48ax_r);
/* OneBus read callbacks for getting sprite and tile data during rendering*/
DECLARE_READ8_MEMBER(spr_r);
@@ -114,6 +120,11 @@ public:
void nes_vt(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);
+
private:
/* expansion nametable - todo, see if we can refactor NES code to be reusable without having to add full NES bus etc. */
@@ -122,8 +133,12 @@ private:
DECLARE_WRITE8_MEMBER(nt_w);
void scanline_irq(int scanline, int vblank, int blanked);
+ void hblank_irq(int scanline, int vblank, int blanked);
+ 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_vdma_ctrl;
int m_timer_irq_enabled;
@@ -151,20 +166,23 @@ private:
required_memory_bank m_prgbank2;
required_memory_bank m_prgbank3;
required_region_ptr<uint8_t> m_prgrom;
+
+ uint16_t decode_nt_addr(uint16_t addr);
+ void do_dma(uint8_t data, bool broken);
};
uint32_t nes_vt_state::get_banks(uint8_t bnk)
{
switch (m_410x[0xb] & 0x07)
{
- case 0: return ((m_410x[0x0] & 0xF0) << 4) | (m_410x[0xa] & 0xC0) | (bnk & 0x3F); // makes bank 0xff at 0xe000 map to 0x07e000 by default for vectors at 0x007fffx
- case 1: return ((m_410x[0x0] & 0xF0) << 4) | (m_410x[0xa] & 0xE0) | (bnk & 0x1F);
- case 2: return ((m_410x[0x0] & 0xF0) << 4) | (m_410x[0xa] & 0xF0) | (bnk & 0x0F);
- case 3: return ((m_410x[0x0] & 0xF0) << 4) | (m_410x[0xa] & 0xF8) | (bnk & 0x07);
- case 4: return ((m_410x[0x0] & 0xF0) << 4) | (m_410x[0xa] & 0xFC) | (bnk & 0x03);
- case 5: return ((m_410x[0x0] & 0xF0) << 4) | (m_410x[0xa] & 0xFE) | (bnk & 0x01);
- case 6: return ((m_410x[0x0] & 0xF0) << 4) | m_410x[0xa];
- case 7: return ((m_410x[0x0] & 0xF0) << 4) | bnk;
+ case 0: return ((m_410x[0x0] & 0xF0) << 4) + ((m_410x[0xa] & 0xC0) | (bnk & 0x3F)); // makes bank 0xff at 0xe000 map to 0x07e000 by default for vectors at 0x007fffx
+ case 1: return ((m_410x[0x0] & 0xF0) << 4) + ((m_410x[0xa] & 0xE0) | (bnk & 0x1F));
+ case 2: return ((m_410x[0x0] & 0xF0) << 4) + ((m_410x[0xa] & 0xF0) | (bnk & 0x0F));
+ case 3: return ((m_410x[0x0] & 0xF0) << 4) + ((m_410x[0xa] & 0xF8) | (bnk & 0x07));
+ case 4: return ((m_410x[0x0] & 0xF0) << 4) + ((m_410x[0xa] & 0xFC) | (bnk & 0x03));
+ case 5: return ((m_410x[0x0] & 0xF0) << 4) + ((m_410x[0xa] & 0xFE) | (bnk & 0x01));
+ case 6: return ((m_410x[0x0] & 0xF0) << 4) + (m_410x[0xa]);
+ case 7: return ((m_410x[0x0] & 0xF0) << 4) + bnk;
}
return 0;
@@ -173,10 +191,12 @@ 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;
+
uint8_t bank;
// 8000-9fff
- if ((m_410x[0xb] & 0x40) == 0)
+ if ((m_410x[0xb] & 0x40) != 0 || (m_410x[0x5] & 0x40) == 0)
{
if ((m_410x[0x5] & 0x40) == 0)
bank = m_410x[0x7];
@@ -186,14 +206,14 @@ void nes_vt_state::update_banks()
else
bank = 0xfe;
- m_prgbank0->set_entry(get_banks(bank) & (m_numbanks-1));
+ m_prgbank0->set_entry((amod | get_banks(bank)) & (m_numbanks-1));
// a000-bfff
bank = m_410x[0x8];
- m_prgbank1->set_entry(get_banks(bank) & (m_numbanks-1));
+ m_prgbank1->set_entry((amod | get_banks(bank)) & (m_numbanks-1));
// c000-dfff
- if ((m_410x[0xb] & 0x40) != 0)
+ if ((m_410x[0xb] & 0x40) != 0 || (m_410x[0x5] & 0x40) != 0)
{
if ((m_410x[0x5] & 0x40) == 0)
bank = m_410x[0x9];
@@ -203,11 +223,19 @@ void nes_vt_state::update_banks()
else
bank = 0xfe;
- m_prgbank2->set_entry(get_banks(bank) & (m_numbanks-1));
+ m_prgbank2->set_entry((amod | get_banks(bank)) & (m_numbanks-1));
// e000 - ffff
bank = 0xff;
- m_prgbank3->set_entry(get_banks(bank) & (m_numbanks-1));
+ m_prgbank3->set_entry((amod | get_banks(bank)) & (m_numbanks-1));
+}
+
+uint16_t nes_vt_state::decode_nt_addr(uint16_t addr) {
+ bool vert_mirror = !(m_410x[0x6] & 0x01);
+ int a11 = (addr >> 11) & 0x01;
+ int a10 = (addr >> 10) & 0x01;
+ uint16_t base = (addr & 0x3FF);
+ return ((vert_mirror ? a10 : a11) << 10) | base;
}
WRITE8_MEMBER(nes_vt_state::vt03_410x_w)
@@ -271,6 +299,7 @@ WRITE8_MEMBER(nes_vt_state::vt03_410x_w)
break;
case 0xa:
+ logerror("vt03_410aw %02x\n", data);
m_410x[0xa] = data;
update_banks();
break;
@@ -294,6 +323,52 @@ WRITE8_MEMBER(nes_vt_state::vt03_410x_w)
}
}
+WRITE8_MEMBER(nes_vt_state::vt03_41bx_w)
+{
+ logerror("vt03_41bx_w %02x %02x\n", offset, data);
+}
+
+WRITE8_MEMBER(nes_vt_state::vt03_411c_w)
+{
+ logerror("vt03_411c_w %02x\n", data);
+ m_411c = data;
+ update_banks();
+}
+
+WRITE8_MEMBER(nes_vt_state::vt03_412c_w)
+{
+ logerror("vt03_412c_w %02x\n", data);
+ m_412c = data;
+ update_banks();
+}
+
+READ8_MEMBER(nes_vt_state::vt03_41bx_r)
+{
+ switch(offset) {
+ case 0x07:
+ return 0x04;
+ default:
+ return 0x00;
+ }
+}
+
+WRITE8_MEMBER(nes_vt_state::vt03_48ax_w)
+{
+ logerror("vt03_48ax_w %02x %02x\n", offset, data);
+}
+
+READ8_MEMBER(nes_vt_state::vt03_48ax_r)
+{
+ switch(offset) {
+ case 0x04:
+ return 0x01;
+ case 0x05:
+ return 0x01;
+ default:
+ return 0x00;
+ }
+}
+
uint32_t nes_vt_state::screen_update_vt(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
@@ -321,39 +396,53 @@ PALETTE_INIT_MEMBER(nes_vt_state, nesvt)
void nes_vt_state::scanline_irq(int scanline, int vblank, int blanked)
{
- int irqstate = 0;
+ video_irq(false, scanline, vblank, blanked);
+}
- //logerror("scanline_irq %d\n", scanline);
+void nes_vt_state::hblank_irq(int scanline, int vblank, int blanked)
+{
+ video_irq(true, scanline, vblank, blanked);
+}
- if (m_timer_running && scanline < 0xe0)
- {
- m_timer_val--;
+void nes_vt_state::video_irq(bool hblank, int scanline, int vblank, int blanked)
+{
+ //TSYNEN
+ if(((m_410x[0xb] >> 7) & 0x01) == hblank) {
+ int irqstate = 0;
+
+ //logerror("scanline_irq %d\n", scanline);
- if (m_timer_val < 1)
+ if (m_timer_running && scanline < 0xe0)
{
- if (m_timer_irq_enabled)
+ m_timer_val--;
+
+ if (m_timer_val < 0)
{
- logerror("scanline_irq %d\n", scanline);
- irqstate = 1;
+ if (m_timer_irq_enabled)
+ {
+ logerror("scanline_irq %d\n", scanline);
+ irqstate = 1;
+ }
}
}
+
+ if (irqstate)
+ m_maincpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
+ else
+ m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE);
}
- if (irqstate)
- m_maincpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
- else
- m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE);
}
/* todo, handle custom VT nametable stuff here */
READ8_MEMBER(nes_vt_state::nt_r)
{
- return m_ntram[offset];
+ return m_ntram[decode_nt_addr(offset)];
}
WRITE8_MEMBER(nes_vt_state::nt_w)
{
- m_ntram[offset] = data;
+ m_ntram[decode_nt_addr(offset)] = data;
}
void nes_vt_state::machine_start()
@@ -379,6 +468,8 @@ void nes_vt_state::machine_start()
save_pointer(NAME(m_ntram.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));
@@ -399,7 +490,8 @@ void nes_vt_state::machine_reset()
m_410x[0x9] = 0x02;
m_410x[0xa] = 0x00;
m_410x[0xb] = 0x00;
-
+ m_411c = 0x00;
+ m_412c = 0x00;
m_timer_irq_enabled = 0;
m_timer_running = 0;
m_timer_val = 0;
@@ -613,8 +705,8 @@ int nes_vt_state::calculate_real_video_address(int addr, int extended, int readt
}
}
-
- return finaladdr;
+ uint32_t amod = (m_412c & 0x04) ? (1 << 24) : 0x0;
+ return amod | finaladdr;
}
/*
@@ -626,103 +718,76 @@ int nes_vt_state::calculate_real_video_address(int addr, int extended, int readt
so I'm not sure if it's just an incomplete demo, or there is more to this
*/
-// the demo program writes to the banking registers like this.. how does this really work? is this mode selectable? some kind of legacy mode?
+// MMC3 compatibility mode
WRITE8_MEMBER(nes_vt_state::vt03_8000_w)
{
- switch (offset + 0x8000)
- {
- case 0x8000:
- m_8000_addr_latch = data;
- break;
-
- case 0x8001:
- 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?
- //if ((data != 0x00) && (data != 0x2f) && (data != 0x31) && (data != 0x32) )
- // logerror("%s vt03_8001_data_w latch %02x data %02x\n", machine().describe_context(), m_8000_addr_latch, data);
- m_ppu->set_201x_reg(0x2, data);
- break;
-
- case 0x03: // dog?
- //if ((data != 0x00) && (data != 0x2c) && (data != 0x2d) && (data != 0x2e) && (data != 0x2f) && (data != 0x32) && (data != 0x3d) && (data != 0x3e) && (data != 0x3f) && (data != 0x40) && (data != 0x41) && (data != 0x42) && (data != 0x43) && (data != 0x44) && (data != 0x45) && (data != 0x46))
- // logerror("%s vt03_8001_data_w latch %02x data %02x\n", machine().describe_context(), m_8000_addr_latch, data);
- m_ppu->set_201x_reg(0x3, data);
- break;
-
- case 0x04: // ball thrown
- //if ((data != 0x00) && (data != 0x10) && (data != 0x12))
- // logerror("%s vt03_8001_data_w latch %02x data %02x\n", machine().describe_context(), m_8000_addr_latch, data);
- m_ppu->set_201x_reg(0x4, data);
- break;
-
- case 0x05: // ball thrown
- //if ((data != 0x00) && (data != 0x11))
- // logerror("%s vt03_8001_data_w latch %02x data %02x\n", machine().describe_context(), m_8000_addr_latch, data);
- m_ppu->set_201x_reg(0x5, data);
- break;
-
- case 0x06:
- m_410x[0x7] = data;
- update_banks();
- break;
-
- case 0x07:
- m_410x[0x8] = data;
- update_banks();
- break;
- default:
- logerror("%s vt03_8001_data_w latch %02x data %02x\n", machine().describe_context(), m_8000_addr_latch, data);
- break;
+ //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);
+ 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;
}
- break;
-
- case 0xa000:
- logerror("%s: vt03_a000_w %02x\n", machine().describe_context(), data);
- break;
-
- case 0xa001:
- logerror("%s: vt03_a001_w %02x\n", machine().describe_context(), data);
- break;
-
- // registers below appear to provide an alt way of setting the scanline counter/timer
-
- case 0xc000:
- // seems to be a mirror of 4101 (timer latch)
- //logerror("%s: vt03_c000_w %02x\n", machine().describe_context(), data);
+ } 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);
- break;
-
- case 0xc001:
- // seems to be a mirror of 4102 (load timer with latched data, start counting)
- // logerror("%s: vt03_c001_w %02x\n", machine().describe_context(), data);
+ } else if((addr >= 0xC000) && (addr < 0xE000) && (addr & 0x01)) {
+ // IRQ reload
vt03_410x_w(space, 2, data);
- break;
-
- case 0xe000:
- // seems to be a mirror of 4103 (disable timer interrupt)
- // logerror("%s: vt03_e000_w %02x\n", machine().describe_context(), data);
+ } else if((addr >= 0xE000) && !(addr & 0x01)) {
+ // IRQ disable
vt03_410x_w(space, 3, data);
- break;
-
- case 0xe001:
- // seems to be a mirror of 4104 (enable timer interrupt)
- //logerror("%s: vt03_e001_w %02x\n", machine().describe_context(), data);
+ } else if((addr >= 0xE000) && (addr & 0x01)) {
+ // IRQ enable
vt03_410x_w(space, 4, data);
- break;
-
- default:
- logerror("%s: vt03_8000_w (%04x) unhandled %02x\n", machine().describe_context(), offset+0x8000, data );
- break;
+ } else {
+
}
+
}
/* APU plumbing, this is because we have a plain M6502 core in the VT03, otherwise this is handled in the core */
@@ -749,11 +814,16 @@ WRITE8_MEMBER(nes_vt_state::psg1_4017_w)
WRITE8_MEMBER(nes_vt_state::nes_vh_sprite_dma_w)
{
- m_ppu->spriteram_dma(space, data);
+ do_dma(data, true);
}
WRITE8_MEMBER(nes_vt_state::vt_hh_sprite_dma_w)
{
+ do_dma(data, false);
+}
+
+void nes_vt_state::do_dma(uint8_t data, bool broken)
+{
uint8_t dma_mode = m_vdma_ctrl & 0x01;
uint8_t dma_len = (m_vdma_ctrl >> 1) & 0x07;
uint8_t src_nib_74 = (m_vdma_ctrl >> 4) & 0x0F;
@@ -767,20 +837,24 @@ WRITE8_MEMBER(nes_vt_state::vt_hh_sprite_dma_w)
}
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(broken && (dma_mode == 1) && ((m_ppu->get_vram_dest() & 0xFF00) == 0x3F00)
+ && !(m_ppu->get_201x_reg(0x1) & 0x80)) {
+ length -= 1;
+ src_addr += 1;
+ }
for (int i = 0; i < length; i++)
{
-
- uint8_t spriteData = space.read_byte(src_addr + i);
+ uint8_t spriteData = m_maincpu->space(AS_PROGRAM).read_byte(src_addr + i);
if(dma_mode) {
- space.write_byte(0x2007, spriteData);
+ m_maincpu->space(AS_PROGRAM).write_byte(0x2007, spriteData);
} else {
- space.write_byte(0x2004, spriteData);
+ m_maincpu->space(AS_PROGRAM).write_byte(0x2004, spriteData);
}
if(((src_addr + i) & 0xFF) == length) break;
}
// should last (length * 4 - 1) CPU cycles.
- space.device().execute().adjust_icount(-(length * 4 - 1));
+ //((device_t*)m_maincpu)->execute().adjust_icount(-(length * 4 - 1));
}
@@ -790,19 +864,22 @@ WRITE8_MEMBER(nes_vt_state::vt03_4034_w)
}
static ADDRESS_MAP_START( nes_vt_map, AS_PROGRAM, 8, nes_vt_state )
- AM_RANGE(0x0000, 0x07ff) AM_RAM
- AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write) /* PPU registers */
+ AM_RANGE(0x0000, 0x1fff) AM_MASK(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)
AM_RANGE(0x4014, 0x4014) AM_READ(psg1_4014_r) AM_WRITE(nes_vh_sprite_dma_w)
AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg1_4015_r, psg1_4015_w) /* PSG status / first control register */
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(0x4034, 0x4034) AM_WRITE(vt03_4034_w)
+
AM_RANGE(0x4100, 0x410b) AM_WRITE(vt03_410x_w)
AM_RANGE(0x8000, 0xffff) AM_WRITE(vt03_8000_w)
AM_RANGE(0x8000, 0xffff) AM_DEVICE("prg", address_map_bank_device, amap8)
+ AM_RANGE(0x6000, 0x7fff) AM_RAM
ADDRESS_MAP_END
/* Some later VT models have more RAM */
@@ -811,8 +888,20 @@ static ADDRESS_MAP_START( nes_vt_xx_map, AS_PROGRAM, 8, nes_vt_state )
AM_RANGE(0x0800, 0x0fff) AM_RAM
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)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( nes_vt_bt_map, AS_PROGRAM, 8, nes_vt_state )
+ AM_IMPORT_FROM(nes_vt_xx_map)
+ AM_RANGE(0x412c, 0x412c) AM_WRITE(vt03_412c_w)
+ADDRESS_MAP_END
+
+
static ADDRESS_MAP_START( nes_vt_hh_map, AS_PROGRAM, 8, nes_vt_state )
- AM_RANGE(0x0000, 0x0fff) AM_RAM
+ AM_RANGE(0x0000, 0x1fff) AM_MASK(0x0fff) AM_RAM
AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write) /* PPU registers */
AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("apu", nesapu_device, read, write)
@@ -827,7 +916,28 @@ static ADDRESS_MAP_START( nes_vt_hh_map, AS_PROGRAM, 8, nes_vt_state )
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(0x6000, 0x6fff) AM_RAM
+ AM_RANGE(0x6000, 0x7fff) AM_RAM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( nes_vt_dg_map, AS_PROGRAM, 8, nes_vt_state )
+ AM_RANGE(0x0000, 0x1fff) AM_RAM
+ AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write) /* PPU registers */
+
+ AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("apu", nesapu_device, read, write)
+ AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg1_4015_r, psg1_4015_w) /* PSG status / first control register */
+ 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(0x411c, 0x411c) AM_WRITE(vt03_411c_w)
+
+ AM_RANGE(0x8000, 0xffff) AM_WRITE(vt03_8000_w)
+ AM_RANGE(0x8000, 0xffff) AM_DEVICE("prg", address_map_bank_device, amap8)
+
+ AM_RANGE(0x4034, 0x4034) AM_WRITE(vt03_4034_w)
+ AM_RANGE(0x4014, 0x4014) AM_READ(psg1_4014_r) AM_WRITE(nes_vh_sprite_dma_w)
+ AM_RANGE(0x6000, 0x7fff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START( prg_map, AS_PROGRAM, 8, nes_vt_state )
@@ -938,6 +1048,37 @@ MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_xx, nes_vt)
MCFG_CPU_PROGRAM_MAP(nes_vt_xx_map)
MACHINE_CONFIG_END
+MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_cy, nes_vt_xx)
+ MCFG_CPU_MODIFY("maincpu")
+ MCFG_CPU_PROGRAM_MAP(nes_vt_cy_map)
+MACHINE_CONFIG_END
+
+MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_bt, nes_vt_xx)
+ MCFG_CPU_MODIFY("maincpu")
+ MCFG_CPU_PROGRAM_MAP(nes_vt_bt_map)
+MACHINE_CONFIG_END
+
+MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_dg, nes_vt_xx)
+ MCFG_CPU_MODIFY("maincpu")
+ MCFG_CPU_PROGRAM_MAP(nes_vt_dg_map)
+
+ MCFG_SCREEN_MODIFY("screen")
+ MCFG_SCREEN_REFRESH_RATE(50.0070)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC((106.53/(PAL_APU_CLOCK/1000000)) * (ppu2c0x_device::VBLANK_LAST_SCANLINE_PAL-ppu2c0x_device::VBLANK_FIRST_SCANLINE+1+2)))
+ MCFG_SCREEN_SIZE(32*8, 312)
+ MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 30*8-1)
+MACHINE_CONFIG_END
+
+MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_vg, nes_vt_dg )
+
+ MCFG_CPU_MODIFY("maincpu")
+ MCFG_CPU_PROGRAM_MAP(nes_vt_hh_map)
+
+ MCFG_PPU_VT03_MODIFY("ppu")
+ MCFG_PPU_VT03_SET_PAL_MODE(PAL_MODE_NEW_VG);
+
+MACHINE_CONFIG_END
+
// New mystery handheld architecture, VTxx derived
MACHINE_CONFIG_DERIVED(nes_vt_state::nes_vt_hh, nes_vt_xx)
MCFG_CPU_MODIFY("maincpu")
@@ -1133,6 +1274,31 @@ ROM_START( sy889 )
ROM_LOAD( "sy889_w25q64.bin", 0x00000, 0x800000, CRC(fcdaa6fc) SHA1(0493747facf2172b8af22010851668bb18cbb3e4) )
ROM_END
+ROM_START( mc_15kin1 )
+ ROM_REGION( 0x200000, "mainrom", 0 )
+ ROM_LOAD( "15000in1.bin", 0x00000, 0x200000, CRC(29a8cb96) SHA1(c4b31964fbfc5ee97d4a4c7e4d418ea5d84a568d) )
+ROM_END
+
+ROM_START( mc_18kin1 )
+ ROM_REGION( 0x400000, "mainrom", 0 )
+ ROM_LOAD( "18000in1.bin", 0x00000, 0x400000, CRC(23c0c325) SHA1(4ad53b5e5a8e65571fd39760278cdf7a6371da47) )
+ROM_END
+
+ROM_START( gx121in1 )
+ ROM_REGION( 0x400000, "mainrom", 0 )
+ ROM_LOAD( "gx121in1.bin", 0x00000, 0x400000, CRC(0282d975) SHA1(9ead7505b99a60834724a5818ee120e03c8bf975) )
+ROM_END
+
+ROM_START( dgun2573 )
+ ROM_REGION( 0x2000000, "mainrom", 0 )
+ ROM_LOAD( "dgun2573.bin", 0x00000, 0x2000000, CRC(cde71a53) SHA1(d0d4c1965876291861781ecde46b1142b062f1f3) )
+ROM_END
+
+ROM_START( bittboy )
+ ROM_REGION( 0x2000000, "mainrom", 0 )
+ ROM_LOAD( "bittboy_flash_read_S29GL256N-TF-V2.bin", 0x00000, 0x2000000, CRC(24c802d7) SHA1(c1300ff799b93b9b53060b94d3985db4389c5d3a) )
+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 )
@@ -1141,22 +1307,30 @@ CONS( 200?, vdogdemo, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "VRT", "V-Do
// should be VT03 based
// for testing 'Shark', 'Octopus', 'Harbor', and 'Earth Fighter' use the extended colour modes, other games just seem to use standard NES modes
-CONS( 200?, mc_dgear, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "dreamGEAR", "dreamGEAR 75-in-1", MACHINE_NOT_WORKING )
-// all software in this runs in the VT03 enhanced mode, it also includes an actual licensed VT03 port of Frogger. If running on EmuVT set to PAL or the colours are broken
-CONS( 2006, vgtablet, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown> / Konami", "VG Pocket Tablet", MACHINE_NOT_WORKING )
+CONS( 200?, mc_dgear, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "dreamGEAR", "dreamGEAR 75-in-1", MACHINE_IMPERFECT_GRAPHICS )
+// all software in this runs in the VT03 enhanced mode, it also includes an actual licensed VT03 port of Frogger.
+// all games work OK except Frogger which has serious graphical issues
+CONS( 2006, vgtablet, 0, 0, nes_vt_vg, nes_vt, nes_vt_state, 0, "<unknown> / Konami", "VG Pocket Tablet", MACHINE_NOT_WORKING )
// There is a 2004 Majesco Frogger "TV game" that appears to contain the same version of Frogger as above but with no other games, so probably fits here.
-// this is VT09 based, and needs 8bpp modes at least
-// it boots, but gfx look wrong due to unsupported mode
-CONS( 2009, cybar120, 0, 0, nes_vt_xx, nes_vt, nes_vt_state, 0, "Defender", "Defender M2500P 120-in-1", MACHINE_NOT_WORKING )
-CONS( 200?, vgpocket, 0, 0, nes_vt_xx, nes_vt, nes_vt_state, 0, "<unknown>", "VG Pocket (VG-2000)", MACHINE_NOT_WORKING )
-CONS( 200?, vgpmini, 0, 0, nes_vt_xx, nes_vt, nes_vt_state, 0, "<unknown>", "VG Pocket Mini (VG-1500)", MACHINE_NOT_WORKING )
+// this is VT09 based
+// it boots, most games correct, but palette issues in some games still (usually they appear greyscale)
+// and colors overall a bit off
+CONS( 2009, cybar120, 0, 0, nes_vt_vg, nes_vt, nes_vt_state, 0, "Defender", "Defender M2500P 120-in-1", MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS )
+CONS( 200?, vgpocket, 0, 0, nes_vt_vg, nes_vt, nes_vt_state, 0, "<unknown>", "VG Pocket (VG-2000)", MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS )
+CONS( 200?, vgpmini, 0, 0, nes_vt_vg, nes_vt, nes_vt_state, 0, "<unknown>", "VG Pocket Mini (VG-1500)", MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS )
+
+// Runs fine, non-sport 121 in 1 games perfect, but minor graphical issues in
+// sport games, also no sound in menu or sport games due to missing PCM
+// 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)
-CONS( 200?, dgun2500, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "dreamGEAR", "dreamGEAR Wireless Motion Control with 130 games (DGUN-2500)", MACHINE_NOT_WORKING )
-CONS( 2012, dgun2561, 0, 0, nes_vt, 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_xx, nes_vt, nes_vt_state, 0, "Lexibook", "Lexibook Compact Cyber Arcade", MACHINE_NOT_WORKING )
+// 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 )
+CONS( 200?, lexcyber, 0, 0, nes_vt_cy, nes_vt, nes_vt_state, 0, "Lexibook", "Lexibook Compact Cyber Arcade", MACHINE_NOT_WORKING )
// these are VT1682 based and have scrambled CPU opcodes. Will need VT1682 CPU and PPU
// to be emulated
@@ -1180,21 +1354,23 @@ CONS( 200?, pjoys60, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unk
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 )
// 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_NOT_WORKING )
-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_NOT_WORKING )
+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 )
-CONS( 200?, gprnrs1, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "Game Prince RS-1", MACHINE_NOT_WORKING )
-CONS( 200?, gprnrs16, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "Game Prince RS-16", 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_NOT_WORKING ) // dreamGear, but no enhanced games?
+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_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_7x6ss, 0, 0, nes_vt, nes_vt, nes_vt_state, 0, "<unknown>", "777777 in 1 (8 bit Slim Station, NEWPXP-DVT22-A PCB)", MACHINE_NOT_WORKING )
-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_NOT_WORKING )
-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_NOT_WORKING )
-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_NOT_WORKING )
-
+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 )
+// 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 )
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index c9506c66427..56c93b65394 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -29778,6 +29778,8 @@ gprnrs16
vgpocket
vgpmini
sy889
+dgun2573
+bittboy
@source:newbrain.cpp
newbrain //