mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
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
This commit is contained in:
parent
de1637512b
commit
a524a99cd0
@ -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;
|
||||
|
||||
case 0x09:
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
Loading…
Reference in New Issue
Block a user