diff options
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 |
commit | a524a99cd0624a27a89d74c9c857d5dc8c770c77 (patch) | |
tree | e566246e68700b5e0fa276c43159cbfb3054096b | |
parent | de1637512bee15c715c2e0bf70d0f3923e6b833e (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.cpp | 123 |
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 |