blackt96.cpp: various changes/fixes [Angelo Salese]

* Added flip screen & coin counter support;
* Rewritten text layer to tilemap;
* Added notes on top and promoted game with MACHINE_IS_INCOMPLETE, having many bugs that are actually from very sloppy coding;
This commit is contained in:
angelosa 2017-07-06 23:15:14 +02:00
parent 76c4fc09e2
commit 96f42eda71

View File

@ -48,16 +48,33 @@ The hardware is cloned from 'snk68' with some extra capabilities
the drivers can probably be merged.
Bugs:
Bugs (all of these looks BTANBs):
Sometimes if you attack an enemy when you're at the top of the screen they'll
- Sometimes if you attack an enemy when you're at the top of the screen they'll
end up landing in an even higher position, and appear over the backgrounds!
I think this is just a game bug..
The timer doesn't work (PIC?, RAM Mirror?)
- The timer doesn't work
Each frame calls:
00E8CC: 0C39 0000 00C0 16AF cmpi.b #$0, $c016af.l
00E8D4: 6600 0026 bne $e8fc
00E8D8: 0C39 000F 00C0 002E cmpi.b #$f, $c0002e.l
00E8E0: 6700 001A beq $e8fc
00E8E4: 0C39 000F 00C0 008E cmpi.b #$f, $c0008e.l
00E8EC: 6700 000E beq $e8fc
00E8F0: 33FC 2000 00C0 1982 move.w #$2000, $c01982.l // timer inited again???
00E8F8: 6100 0118 bsr $ea12
00E8FC: 4E75 rts
---
00EA12: 48A7 FCF0 movem.w D0-D5/A0-A3, -(A7)
00EA16: 3039 00C0 1982 move.w $c01982.l, D0
// then calls setup data and drawing for the timer which is always 20 for whatever reason.
There are some unmapped writes past the end of text ram too
- There are some unmapped writes scattered across different areas (text ram, spriteram, 0xe0000 area etc.)
- flip screen doesn't work properly,
game code explicitly sets flip screen off & the correlated work RAM buffer at 0xee2 no matter the dip setting
- some service mode items are buggy or not functioning properly;
*/
@ -82,14 +99,25 @@ public:
{ }
required_shared_ptr<uint16_t> m_tilemapram;
DECLARE_WRITE16_MEMBER(blackt96_c0000_w);
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<snk68_spr_device> m_sprites;
tilemap_t *m_tx_tilemap;
DECLARE_WRITE8_MEMBER(output_w);
DECLARE_WRITE16_MEMBER(blackt96_80000_w);
DECLARE_WRITE16_MEMBER(tx_vram_w);
DECLARE_WRITE8_MEMBER(blackt96_soundio_port00_w);
DECLARE_READ8_MEMBER(blackt96_soundio_port01_r);
DECLARE_WRITE8_MEMBER(blackt96_soundio_port01_w);
DECLARE_READ8_MEMBER(blackt96_soundio_port02_r);
DECLARE_WRITE8_MEMBER(blackt96_soundio_port02_w);
TILE_GET_INFO_MEMBER(get_tx_tile_info);
void tile_callback(int &tile, int& fx, int& fy, int& region);
DECLARE_READ16_MEMBER( random_r )
@ -101,15 +129,29 @@ public:
virtual void video_start() override;
uint32_t screen_update_blackt96(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<snk68_spr_device> m_sprites;
};
TILE_GET_INFO_MEMBER(blackt96_state::get_tx_tile_info)
{
uint16_t tile = m_tilemapram[tile_index*2] & 0xff;
// following is guessed, game just uses either color 0 or 1 anyway (which is identical palette wise)
uint8_t color = m_tilemapram[tile_index*2+1] & 0x0f;
tile += m_txt_bank * 0x100;
SET_TILE_INFO_MEMBER(2,
tile,
color,
0);
}
void blackt96_state::video_start()
{
m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(blackt96_state::get_tx_tile_info),this), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
m_tx_tilemap->set_transparent_pen(0);
}
@ -118,22 +160,7 @@ uint32_t blackt96_state::screen_update_blackt96(screen_device &screen, bitmap_in
bitmap.fill(m_palette->black_pen(), cliprect);
m_sprites->draw_sprites_all(bitmap, cliprect);
/* Text Layer */
int count = 0;
int x,y;
gfx_element *gfx = m_gfxdecode->gfx(2);
for (x=0;x<64;x++)
{
for (y=0;y<32;y++)
{
uint16_t tile = (m_tilemapram[count*2]&0xff);
tile += m_txt_bank * 0x100;
gfx->transpen(bitmap,cliprect,tile,0,0,0,x*8,y*8,0);
count++;
}
}
m_tx_tilemap->draw(screen,bitmap, cliprect, 0, 0);
return 0;
}
@ -146,35 +173,43 @@ WRITE16_MEMBER(blackt96_state::blackt96_80000_w)
}
WRITE16_MEMBER(blackt96_state::blackt96_c0000_w)
WRITE8_MEMBER(blackt96_state::output_w)
{
// unknown, also sound mcu?
// -bbb --21
// -bbb 8-21
// 1 - coin counter 1
// 2 - coin counter 2
// b = text tile bank?
// 8 - flip screen
// b = text tile bank
m_txt_bank = (data & 0xf0)>>4;
m_txt_bank = (data & 0x70)>>4;
flip_screen_set(data & 0x08);
m_sprites->set_flip(data & 0x08);
machine().bookkeeping().coin_counter_w(0, data & 1);
machine().bookkeeping().coin_counter_w(1, data & 2);
printf("blackt96_c0000_w %04x %04x\n",data & 0xfc,mem_mask);
// printf("blackt96_c0000_w %04x %04x\n",data & 0xfc,mem_mask);
}
WRITE16_MEMBER(blackt96_state::tx_vram_w)
{
m_tilemapram[offset] = data;
m_tx_tilemap->mark_tile_dirty(offset/2);
}
static ADDRESS_MAP_START( blackt96_map, AS_PROGRAM, 16, blackt96_state )
AM_RANGE(0x000000, 0x07ffff) AM_ROM
AM_RANGE(0x080000, 0x080001) AM_READ_PORT("P1_P2") AM_WRITE(blackt96_80000_w)
AM_RANGE(0x0c0000, 0x0c0001) AM_READ_PORT("IN1") AM_WRITE(blackt96_c0000_w) // COIN INPUT
AM_RANGE(0x0e0000, 0x0e0001) AM_READ( random_r ) // AM_READ_PORT("IN2") // unk, from sound?
AM_RANGE(0x0e8000, 0x0e8001) AM_READ( random_r ) // AM_READ_PORT("IN3") // unk, from sound?
AM_RANGE(0x080000, 0x080001) AM_READ_PORT("P1_P2") AM_WRITE(blackt96_80000_w) // soundlatch
AM_RANGE(0x0c0000, 0x0c0001) AM_READ_PORT("IN1") AM_WRITE8(output_w,0x00ff) // COIN INPUT
AM_RANGE(0x0e0000, 0x0e0001) AM_READ( random_r ) // unk, from sound? - called in tandem with result discarded, watchdog?
AM_RANGE(0x0e8000, 0x0e8001) AM_READ( random_r ) // unk, from sound? /
AM_RANGE(0x0f0000, 0x0f0001) AM_READ_PORT("DSW1")
AM_RANGE(0x0f0008, 0x0f0009) AM_READ_PORT("DSW2")
AM_RANGE(0x0f0008, 0x0f0009) AM_READ_PORT("DSW2") AM_WRITENOP // service mode, left-over?
AM_RANGE(0x100000, 0x100fff) AM_RAM AM_SHARE("tilemapram") // text tilemap
AM_RANGE(0x100000, 0x100fff) AM_RAM_WRITE(tx_vram_w) AM_SHARE("tilemapram") // text tilemap
AM_RANGE(0x200000, 0x207fff) AM_DEVREADWRITE("sprites", snk68_spr_device, spriteram_r, spriteram_w) AM_SHARE("spriteram") // only partially populated
AM_RANGE(0x400000, 0x400fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0xc00000, 0xc03fff) AM_RAM // main ram
ADDRESS_MAP_END
@ -200,10 +235,10 @@ static INPUT_PORTS_START( blackt96 )
PORT_START("IN1")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) // Test mode lists this as Service 1, but it appears to be Coin 1 (uses Coin 1 coinage etc.)
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_SERVICE1 ) // acts as a serive mode mirror
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_SERVICE1 ) // acts as a service mode mirror
PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // Test mode lists this as Coin 1, but it doesn't work
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN ) // Test mode lists this as Coin 1, but it doesn't work
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_UNKNOWN )
@ -230,9 +265,9 @@ static INPUT_PORTS_START( blackt96 )
PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW1:!2") // ?
PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW1:!1")
PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x8000, 0x0000, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW1:!1")
PORT_DIPSETTING( 0x0000, DEF_STR( No ) )
PORT_DIPSETTING( 0x8000, DEF_STR( Yes ) ) // buggy, applies to attract mode only.
/* Dipswitch Port B */
PORT_START("DSW2")
@ -295,9 +330,9 @@ static const gfx_layout blackt96_text_layout =
};
static GFXDECODE_START( blackt96 )
GFXDECODE_ENTRY( "gfx1", 0, blackt96_layout, 0x0, 0x10 )
GFXDECODE_ENTRY( "gfx2", 0, blackt962_layout, 0x0, 0x80 )
GFXDECODE_ENTRY( "gfx3", 0, blackt96_text_layout, 0x0, 0x80 )
GFXDECODE_ENTRY( "gfx1", 0, blackt96_layout, 0, 8 )
GFXDECODE_ENTRY( "gfx2", 0, blackt962_layout, 0, 64 )
GFXDECODE_ENTRY( "gfx3", 0, blackt96_text_layout, 0, 16 )
GFXDECODE_END
@ -416,4 +451,4 @@ ROM_START( blackt96 )
ROM_CONTINUE( 0x00001, 0x08000 ) // first half is empty
ROM_END
GAME( 1996, blackt96, 0, blackt96, blackt96, blackt96_state, 0, ROT0, "D.G.R.M.", "Black Touch '96", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 1996, blackt96, 0, blackt96, blackt96, blackt96_state, 0, ROT0, "D.G.R.M.", "Black Touch '96", MACHINE_IS_INCOMPLETE | MACHINE_NO_SOUND )