summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author arbee <rb6502@users.noreply.github.com>2018-08-25 19:38:35 -0400
committer arbee <rb6502@users.noreply.github.com>2018-08-25 19:38:35 -0400
commita524a99cd0624a27a89d74c9c857d5dc8c770c77 (patch)
treee566246e68700b5e0fa276c43159cbfb3054096b
parentde1637512bee15c715c2e0bf70d0f3923e6b833e (diff)
cmmb: Misc. improvements (nw)
- Better flash mapping means the IRQ handler can run now without crashing - Hooked up up/down and service2 (0) keys to navigate service mode - Bankdev added to handle 2000-AFFF region
-rw-r--r--src/mame/drivers/cmmb.cpp123
1 files changed, 60 insertions, 63 deletions
diff --git a/src/mame/drivers/cmmb.cpp b/src/mame/drivers/cmmb.cpp
index 9a8dc85aed7..dc838b7518d 100644
--- a/src/mame/drivers/cmmb.cpp
+++ b/src/mame/drivers/cmmb.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Angelo Salese
+// copyright-holders:Angelo Salese, R. Belmont
/***************************************************************************
Centipede / Millipede / Missile Command / Let's Go Bowling
@@ -13,17 +13,17 @@ Earlier revisions of this cabinet did not include the bowling game.
a port or prototype of an old Atari game.
TODO:
-- flash ROM hookup (by the looks of it, at29x needs an address map?);
+- flash ROM hookup
- finish video emulation;
- trackball inputs
- sound;
- NVRAM (flash ROM, as per NVRAM test at 0xC2A7).
- untangle switch-cases for inputs;
-- One bit of the control register seems to want to bank the flash into 2000-7FFF
- which would require bankdev if verified.
-- IRQ handler is super-strange, it wants to JMP ($7FFE) and JMP ($3FFE) a lot,
- which currently sends the game off into the weeds.
-- In fact, the game goes off into the weeds anyway right now due to doing that.
+- IRQs are problematic. Haven't yet found a reliable enable that works
+ for both mainline and service mode; maybe there's no mask and the
+ processor's SEI/CLI instructions are used for that?
+ - If IRQs are enabled in service mode, they eventually trash all of memory.
+
Probably on the CPLD (CY39100V208B) - Quoted from Cosmodog's website:
"Instead, we used a programmable chip that we could reconfigure very
@@ -52,6 +52,7 @@ OSC @ 72.576MHz
#include "emu.h"
#include "cpu/m6502/m65sc02.h"
#include "machine/at29x.h"
+#include "machine/bankdev.h"
#include "emupal.h"
#include "screen.h"
@@ -66,7 +67,8 @@ public:
m_flash(*this, "at29c020" ),
m_videoram(*this, "videoram"),
m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette")
+ m_palette(*this, "palette"),
+ m_bnk2000(*this, "bnk2000")
{ }
required_device<cpu_device> m_maincpu;
@@ -74,6 +76,7 @@ public:
required_shared_ptr<uint8_t> m_videoram;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
+ required_device<address_map_bank_device> m_bnk2000;
uint8_t m_irq_mask;
@@ -81,26 +84,14 @@ public:
DECLARE_WRITE8_MEMBER(cmmb_charram_w);
DECLARE_READ8_MEMBER(cmmb_input_r);
DECLARE_WRITE8_MEMBER(cmmb_output_w);
- DECLARE_WRITE8_MEMBER(flash_dbg_0_w);
- DECLARE_WRITE8_MEMBER(flash_dbg_1_w);
-
- DECLARE_WRITE8_MEMBER(irq_ack_w)
- {
- m_maincpu->set_input_line(0, CLEAR_LINE);
- }
- DECLARE_WRITE8_MEMBER(irq_enable_w)
- {
- m_irq_mask = data & 0x80;
- }
-
- //DECLARE_READ8_MEMBER(kludge_r);
virtual void machine_reset() override;
virtual void video_start() override;
uint32_t screen_update_cmmb(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(vblank_irq);
void cmmb(machine_config &config);
void cmmb_map(address_map &map);
+ void bnk2000_map(address_map &map);
};
@@ -120,7 +111,7 @@ uint32_t cmmb_state::screen_update_cmmb(screen_device &screen, bitmap_ind16 &bit
{
for (x=0;x<32;x++)
{
- int tile = videoram[count] & 0x3f;
+ int tile = videoram[count] & 0x7f;
int colour = (videoram[count] & 0xc0)>>6;
gfx->opaque(bitmap,cliprect,tile,colour,0,0,x*8,y*8);
@@ -170,13 +161,18 @@ WRITE8_MEMBER(cmmb_state::cmmb_output_w)
//printf("%02x -> [%02x] W\n",data,offset);
switch(offset)
{
+ case 0x00: // IRQ ack? may also be 0x09.
+ m_maincpu->set_input_line(0, CLEAR_LINE);
+ //printf("IRQ ack\n");
+ break;
case 0x01:
-// m_irq_mask = data & 0x80;
+ m_irq_mask = data;
break;
case 0x02:
// bit 7 toggled - watchdog or status LED
// toggled by code at E3DB in IRQ handler - it's on when the frame count & 0x30 is 1 and off otherwise
- // bit 6 set means accessing flash ROM, possibly that entire 2000-7FFF banks over to the flash?
+ // bit 6 set means accessing flash ROM at 0x2000
+ m_bnk2000->set_bank((data & 0x40) ? 1 : 0);
break;
case 0x03:
@@ -184,55 +180,57 @@ WRITE8_MEMBER(cmmb_state::cmmb_output_w)
uint8_t *ROM = memregion("maincpu")->base();
uint32_t bankaddress;
- bankaddress = 0x10000 + (0x4000 * (data & 0x0f));
+ //bankaddress = 0x10000 + (0x4000 * ((data & 0x0f)^0xf));
+ //printf("bank %02x => %x\n", data, bankaddress);
+ bankaddress = 0x10000 + 0x3a000;
membank("bank1")->set_base(&ROM[bankaddress]);
+ // bit 7 sub-devCB's flash at 0x2000-0x4000?
}
break;
case 0x07:
break;
- }
-}
-WRITE8_MEMBER(cmmb_state::flash_dbg_0_w)
-{
- m_flash->write(space,0x2aaa,data);
-}
-
-WRITE8_MEMBER(cmmb_state::flash_dbg_1_w)
-{
- m_flash->write(space,0x5555,data);
+ case 0x09:
+ break;
+ }
}
/* overlap empty addresses */
void cmmb_state::cmmb_map(address_map &map)
{
- map.global_mask(0xffff);
map(0x0000, 0x0fff).ram(); /* zero page address */
// AM_RANGE(0x13c0, 0x13ff) AM_RAM //spriteram
- map(0x1000, 0x13ff).ram().share("videoram");
- map(0x2000, 0x2000).portr("IN3");
- map(0x2001, 0x2001).portr("IN4");
- map(0x2011, 0x2011).portr("IN5");
- map(0x2480, 0x249f).ram().w(m_palette, FUNC(palette_device::write8)).share("palette");
- map(0x2505, 0x2505).w(FUNC(cmmb_state::irq_enable_w));
- map(0x2600, 0x2600).w(FUNC(cmmb_state::irq_ack_w));
- //AM_RANGE(0x4000, 0x400f) AM_READWRITE(cmmb_input_r,cmmb_output_w)
- //AM_RANGE(0x4900, 0x4900) AM_READ(kludge_r)
- map(0x4000, 0x7fff).bankr("bank1");
- map(0x8000, 0x9fff).rom().region("maincpu", 0x18000);
+ map(0x1000, 0x1fff).ram().share("videoram");
+ map(0x2000, 0x9fff).m(m_bnk2000, FUNC(address_map_bank_device::amap8));
map(0xa000, 0xafff).ram();
map(0xb000, 0xbfff).rw(FUNC(cmmb_state::cmmb_charram_r), FUNC(cmmb_state::cmmb_charram_w));
map(0xc000, 0xc00f).rw(FUNC(cmmb_state::cmmb_input_r), FUNC(cmmb_state::cmmb_output_w));
- // debugging, to be removed
-// AM_RANGE(0x2aaa, 0x2aaa) AM_WRITE(flash_dbg_0_w)
-// AM_RANGE(0x5555, 0x5555) AM_WRITE(flash_dbg_1_w)
map(0xc010, 0xffff).rom().region("maincpu", 0x1c010);
}
+void cmmb_state::bnk2000_map(address_map &map)
+{
+ map(0x0000, 0x5fff).bankr("bank1");
+ map(0x0000, 0x0000).portr("IN3");
+ map(0x0001, 0x0001).portr("IN4");
+ map(0x0011, 0x0011).portr("IN5");
+ map(0x0480, 0x049f).ram().w(m_palette, FUNC(palette_device::write8)).share("palette");
+// map(0x0505, 0x0505).w(FUNC(cmmb_state::irq_enable_w));
+// map(0x0600, 0x0600).w(FUNC(cmmb_state::irq_ack_w));
+ map(0x0680, 0x0680).nopw();
+ map(0x6000, 0x7fff).rom().region("maincpu", 0x18000);
+
+ map(0x8000, 0xffff).rw("at29c020", FUNC(at29c020_device::read), FUNC(at29c020_device::write));
+}
static INPUT_PORTS_START( cmmb )
PORT_START("IN3")
+ #if 1
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE2 )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
+ PORT_BIT( 0xcf, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ #else
PORT_DIPNAME( 0x01, 0x01, "IN3" )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
@@ -257,8 +255,13 @@ static INPUT_PORTS_START( cmmb )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ #endif
PORT_START("IN4")
+ #if 1
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
+ PORT_BIT( 0xdf, IP_ACTIVE_LOW, IPT_UNKNOWN)
+ #else
PORT_DIPNAME( 0x01, 0x01, "IN4" )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
@@ -283,9 +286,9 @@ static INPUT_PORTS_START( cmmb )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
-
+ #endif
// TODO: pin-point writes for trackball
- // TODO: trackball might be muxed for 1p & 2p sides
+ // TODO: bit 7 of 0x2507 selects trackball 1 and 2
PORT_START("IN5")
PORT_DIPNAME( 0x01, 0x01, "IN5" ) // trackball V clk
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
@@ -331,7 +334,7 @@ static INPUT_PORTS_START( cmmb )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 )
- PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x40, 0x40, "Magic" ) // makes part of the IRQ handler skip if ON
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Service_Mode ) )
@@ -356,12 +359,7 @@ static INPUT_PORTS_START( cmmb )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // if this is lit up, coins will auto-insert each frame until they hit 99 (?!)
INPUT_PORTS_END
static const gfx_layout charlayout =
@@ -394,12 +392,10 @@ GFXDECODE_END
INTERRUPT_GEN_MEMBER(cmmb_state::vblank_irq)
{
- #if 0
- if (m_irq_mask & 0x80)
+ if (m_irq_mask & 0x08)
{
m_maincpu->set_input_line(0, ASSERT_LINE);
}
- #endif
}
void cmmb_state::machine_reset()
@@ -417,6 +413,8 @@ MACHINE_CONFIG_START(cmmb_state::cmmb)
AT29C020(config, "at29c020");
+ ADDRESS_MAP_BANK(config, "bnk2000").set_map(&cmmb_state::bnk2000_map).set_options(ENDIANNESS_LITTLE, 8, 32, 0x8000);
+
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(MAIN_CLOCK/12, 384, 0, 256, 264, 0, 240) // TBD, not real measurements
@@ -446,7 +444,6 @@ ROM_START( cmmb162 )
ROM_LOAD( "cmmb162.u2", 0x10000, 0x40000, CRC(71a5a75d) SHA1(0ad7b97580082cda98cb1e8aab8efcf491d0ed25) )
ROM_COPY( "maincpu", 0x18000, 0x08000, 0x08000 )
ROM_FILL( 0x1c124, 2, 0xea ) // temporary patch to avoid waiting on IRQs
- ROM_FILL( 0x1e3c3, 3, 0xea ) // patch out weird IRQ handler code that causes reboot each IRQ
ROM_REGION( 0x1000, "gfx", ROMREGION_ERASE00 )
ROM_END