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
end up landing in an even higher position, and appear over the backgrounds!
I think this is just a game bug..
- 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!
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,23 +160,8 @@ 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;
printf("blackt96_c0000_w %04x %04x\n",data & 0xfc,mem_mask);
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);
}
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 )