ddealer.cpp: fixed flip screen regression, removed prefixes / suffixes (nw)

This commit is contained in:
Ivan Vangelista 2016-12-12 11:47:38 +01:00 committed by GitHub
parent dafd2dccc6
commit ecdf2d1c63

View File

@ -9,7 +9,7 @@
Appears to be a down-grade of the nmk16 HW
TODO:
-When you use the "gun card" the game gives "minus" points,but points are always added,inaccurate protection?
-When you use the "gun card" the game gives "minus" points, but points are always added, inaccurate protection?
-Understand better the video emulation and convert it to tilemaps;
-Coinage settings based on those listed at www.crazykong.com/dips/DoubleDealer.txt - coin/credit simulation need fixing;
-Decap + emulate MCU, required if the random number generation is going to be accurate;
@ -51,10 +51,10 @@
- There's also MCU response (write/read/test) test just after these writes.
(probably data used in the check depends on above writes). It's similar to
jalmah.c tests, but num of responses is different, and shared ram is
jalmah.cpp tests, but num of responses is different, and shared ram is
used to communicate with MCU
- After last check (or maybe durning tests ... no idea)
- After last check (or maybe during tests ... no idea)
MCU writes $4ef900000604 (jmp $604) to $fe000 and game jumps to this address.
- code at $604 writes $20.w to $fe018 and $1.w to $fe01e.
@ -144,38 +144,40 @@ public:
required_shared_ptr<uint16_t> m_work_ram;
required_shared_ptr<uint16_t> m_mcu_shared_ram;
/* devices */
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
/* video-related */
tilemap_t *m_back_tilemap;
int m_respcount;
int m_flipscreen;
/* misc */
uint8_t m_input_pressed;
uint16_t m_coin_input;
DECLARE_WRITE16_MEMBER(ddealer_flipscreen_w);
DECLARE_WRITE16_MEMBER(flipscreen_w);
DECLARE_WRITE16_MEMBER(back_vram_w);
DECLARE_WRITE16_MEMBER(ddealer_vregs_w);
DECLARE_WRITE16_MEMBER(ddealer_mcu_shared_w);
DECLARE_READ16_MEMBER(ddealer_mcu_r);
DECLARE_WRITE16_MEMBER(mcu_shared_w);
DECLARE_READ16_MEMBER(mcu_r);
DECLARE_DRIVER_INIT(ddealer);
TILE_GET_INFO_MEMBER(get_back_tile_info);
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
uint32_t screen_update_ddealer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(ddealer_interrupt);
TIMER_DEVICE_CALLBACK_MEMBER(ddealer_mcu_sim);
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
void ddealer_draw_video_layer( uint16_t* vreg_base, uint16_t* top, uint16_t* bottom, bitmap_ind16 &bitmap, const rectangle &cliprect, int flipy);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(interrupt);
TIMER_DEVICE_CALLBACK_MEMBER(mcu_sim);
void draw_video_layer(uint16_t* vreg_base, uint16_t* top, uint16_t* bottom, bitmap_ind16 &bitmap, const rectangle &cliprect, int flipy);
};
WRITE16_MEMBER(ddealer_state::ddealer_flipscreen_w)
WRITE16_MEMBER(ddealer_state::flipscreen_w)
{
m_flipscreen = data & 0x01;
flip_screen_set(data & 0x01);
}
TILE_GET_INFO_MEMBER(ddealer_state::get_back_tile_info)
@ -189,11 +191,10 @@ TILE_GET_INFO_MEMBER(ddealer_state::get_back_tile_info)
void ddealer_state::video_start()
{
m_flipscreen = 0;
m_back_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(ddealer_state::get_back_tile_info),this), TILEMAP_SCAN_COLS, 8, 8, 64, 32);
}
void ddealer_state::ddealer_draw_video_layer( uint16_t* vreg_base, uint16_t* top, uint16_t* bottom, bitmap_ind16 &bitmap, const rectangle &cliprect, int flipy)
void ddealer_state::draw_video_layer(uint16_t* vreg_base, uint16_t* top, uint16_t* bottom, bitmap_ind16 &bitmap, const rectangle &cliprect, int flipy)
{
gfx_element *gfx = m_gfxdecode->gfx(1);
@ -276,40 +277,40 @@ void ddealer_state::ddealer_draw_video_layer( uint16_t* vreg_base, uint16_t* top
}
uint32_t ddealer_state::screen_update_ddealer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
uint32_t ddealer_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_back_tilemap->set_scrollx(0, m_flipscreen ? -192 : -64);
m_back_tilemap->set_flip(m_flipscreen ? TILEMAP_FLIPY | TILEMAP_FLIPX : 0);
m_back_tilemap->set_scrollx(0, -64);
m_back_tilemap->draw(screen, bitmap, cliprect, 0, 0);
/* the fg tilemap handling is a little hacky right now,
i'm not sure if it should be a single tilemap with
I'm not sure if it should be a single tilemap with
rowscroll / linescroll, or two tilemaps which can be
combined, the flipscreen case makes things more
difficult to understand */
if (!m_flipscreen)
bool const flip = flip_screen();
if (!flip)
{
if (m_vregs[0xcc / 2] & 0x80)
{
ddealer_draw_video_layer(&m_vregs[0x1e0 / 2], m_left_fg_vram_top, m_left_fg_vram_bottom, bitmap, cliprect, m_flipscreen);
ddealer_draw_video_layer(&m_vregs[0xcc / 2], m_right_fg_vram_top, m_right_fg_vram_bottom, bitmap, cliprect, m_flipscreen);
draw_video_layer(&m_vregs[0x1e0 / 2], m_left_fg_vram_top, m_left_fg_vram_bottom, bitmap, cliprect, flip);
draw_video_layer(&m_vregs[0xcc / 2], m_right_fg_vram_top, m_right_fg_vram_bottom, bitmap, cliprect, flip);
}
else
{
ddealer_draw_video_layer(&m_vregs[0x1e0 / 2], m_left_fg_vram_top, m_left_fg_vram_bottom, bitmap, cliprect, m_flipscreen);
draw_video_layer(&m_vregs[0x1e0 / 2], m_left_fg_vram_top, m_left_fg_vram_bottom, bitmap, cliprect, flip);
}
}
else
{
if (m_vregs[0xcc / 2] & 0x80)
{
ddealer_draw_video_layer(&m_vregs[0xcc / 2], m_left_fg_vram_top, m_left_fg_vram_bottom, bitmap, cliprect, m_flipscreen);
ddealer_draw_video_layer(&m_vregs[0x1e0 / 2], m_right_fg_vram_top, m_right_fg_vram_bottom, bitmap, cliprect, m_flipscreen);
draw_video_layer(&m_vregs[0xcc / 2], m_left_fg_vram_top, m_left_fg_vram_bottom, bitmap, cliprect, flip);
draw_video_layer(&m_vregs[0x1e0 / 2], m_right_fg_vram_top, m_right_fg_vram_bottom, bitmap, cliprect, flip);
}
else
{
ddealer_draw_video_layer(&m_vregs[0x1e0 / 2], m_left_fg_vram_top, m_left_fg_vram_bottom, bitmap, cliprect, m_flipscreen);
draw_video_layer(&m_vregs[0x1e0 / 2], m_left_fg_vram_top, m_left_fg_vram_bottom, bitmap, cliprect, flip);
}
}
@ -317,7 +318,7 @@ uint32_t ddealer_state::screen_update_ddealer(screen_device &screen, bitmap_ind1
return 0;
}
TIMER_DEVICE_CALLBACK_MEMBER(ddealer_state::ddealer_mcu_sim)
TIMER_DEVICE_CALLBACK_MEMBER(ddealer_state::mcu_sim)
{
/*coin/credit simulation*/
/*$fe002 is used,might be for multiple coins for one credit settings.*/
@ -351,7 +352,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(ddealer_state::ddealer_mcu_sim)
m_input_pressed = (m_input_pressed & 0xfb);
/*0x104/2 is some sort of "start-lock",i.e. used on the girl selection.
Without it,the game "steals" one credit if you press the start button on that.*/
Without it, the game "steals" one credit if you press the start button on that.*/
if (m_mcu_shared_ram[0x000 / 2] > 0 && m_work_ram[0x104 / 2] & 1)
{
if (m_coin_input & 0x08)//start 1
@ -373,7 +374,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(ddealer_state::ddealer_mcu_sim)
m_input_pressed = (m_input_pressed & 0xef);
}
/*random number generators,controls order of cards*/
/*random number generators, controls order of cards*/
m_mcu_shared_ram[0x10 / 2] = machine().rand() & 0xffff;
m_mcu_shared_ram[0x12 / 2] = machine().rand() & 0xffff;
m_mcu_shared_ram[0x14 / 2] = machine().rand() & 0xffff;
@ -389,14 +390,9 @@ WRITE16_MEMBER(ddealer_state::back_vram_w)
}
WRITE16_MEMBER(ddealer_state::ddealer_vregs_w)
{
COMBINE_DATA(&m_vregs[offset]);
}
/******************************************************************************************************
Protection handling,identical to Hacha Mecha Fighter / Thunder Dragon with different vectors.
Protection handling, identical to Hacha Mecha Fighter / Thunder Dragon with different vectors.
******************************************************************************************************/
@ -415,7 +411,7 @@ Protection handling,identical to Hacha Mecha Fighter / Thunder Dragon with diffe
m_mcu_shared_ram[_protinput_+1] = (_input_ & 0x0000ffff);\
}
WRITE16_MEMBER(ddealer_state::ddealer_mcu_shared_w)
WRITE16_MEMBER(ddealer_state::mcu_shared_w)
{
COMBINE_DATA(&m_mcu_shared_ram[offset]);
@ -425,7 +421,7 @@ WRITE16_MEMBER(ddealer_state::ddealer_mcu_shared_w)
case 0x164/2: PROT_INPUT(0x164/2,0x5678,0x104/2,0x80002); break;
case 0x62e/2: PROT_INPUT(0x62e/2,0x9ca3,0x108/2,0x80008); break;
case 0x734/2: PROT_INPUT(0x734/2,0xaba2,0x10c/2,0x8000a); break;
/*These enables something for sure,maybe the random number generator?*/
/*These enables something for sure, maybe the random number generator?*/
//00054C: 33FC B891 000F E828 move.w #$b891, $fe828.l
//000554: 33FC C760 000F E950 move.w #$c760, $fe950.l
//00055C: 33FC D45F 000F EA7C move.w #$d45f, $fea7c.l
@ -447,7 +443,7 @@ WRITE16_MEMBER(ddealer_state::ddealer_mcu_shared_w)
case 0x4de/2: PROT_JSR(0x4de,0x803b,0x96c2); break;
case 0x4ee/2: PROT_JSR(0x4ee,0x800c,0x5ca4); break;//palette ram buffer
case 0x4fe/2: PROT_JSR(0x4fe,0x8018,0x9818); break;
/*Start-up vector,I think that only the first ram address can be written by the main CPU,or it is a whole sequence.*/
/*Start-up vector, I think that only the first ram address can be written by the main CPU, or it is a whole sequence.*/
case 0x000/2:
if (m_mcu_shared_ram[0x000 / 2] == 0x60fe)
{
@ -480,7 +476,7 @@ static ADDRESS_MAP_START( ddealer, AS_PROGRAM, 16, ddealer_state )
AM_RANGE(0x08000a, 0x08000b) AM_READ_PORT("UNK")
AM_RANGE(0x084000, 0x084003) AM_DEVWRITE8("ymsnd", ym2203_device, write, 0x00ff) // ym ?
AM_RANGE(0x088000, 0x0887ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x08c000, 0x08cfff) AM_RAM_WRITE(ddealer_vregs_w) AM_SHARE("vregs") // palette ram
AM_RANGE(0x08c000, 0x08cfff) AM_RAM AM_SHARE("vregs") // palette ram
/* this might actually be 1 tilemap with some funky rowscroll / columnscroll enabled, I'm not sure */
AM_RANGE(0x090000, 0x090fff) AM_RAM AM_SHARE("left_fg_vratop")
@ -488,10 +484,10 @@ static ADDRESS_MAP_START( ddealer, AS_PROGRAM, 16, ddealer_state )
AM_RANGE(0x092000, 0x092fff) AM_RAM AM_SHARE("left_fg_vrabot")
AM_RANGE(0x093000, 0x093fff) AM_RAM AM_SHARE("right_fg_vrabot")
//AM_RANGE(0x094000, 0x094001) AM_NOP // always 0?
AM_RANGE(0x098000, 0x098001) AM_WRITE(ddealer_flipscreen_w)
AM_RANGE(0x098000, 0x098001) AM_WRITE(flipscreen_w)
AM_RANGE(0x09c000, 0x09cfff) AM_RAM_WRITE(back_vram_w) AM_SHARE("back_vram") // bg tilemap
AM_RANGE(0x0f0000, 0x0fdfff) AM_RAM AM_SHARE("work_ram")
AM_RANGE(0x0fe000, 0x0fefff) AM_RAM_WRITE(ddealer_mcu_shared_w) AM_SHARE("mcu_shared_ram")
AM_RANGE(0x0fe000, 0x0fefff) AM_RAM_WRITE(mcu_shared_w) AM_SHARE("mcu_shared_ram")
AM_RANGE(0x0ff000, 0x0fffff) AM_RAM
ADDRESS_MAP_END
@ -502,7 +498,7 @@ static INPUT_PORTS_START( ddealer )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) //used,"test" in service mode,unknown purpose
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) //used, "test" in service mode, unknown purpose
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@ -601,7 +597,6 @@ GFXDECODE_END
void ddealer_state::machine_start()
{
save_item(NAME(m_respcount));
save_item(NAME(m_flipscreen));
save_item(NAME(m_input_pressed));
save_item(NAME(m_coin_input));
}
@ -609,12 +604,11 @@ void ddealer_state::machine_start()
void ddealer_state::machine_reset()
{
m_respcount = 0;
m_flipscreen = 0;
m_input_pressed = 0;
m_coin_input = 0;
}
INTERRUPT_GEN_MEMBER(ddealer_state::ddealer_interrupt)
INTERRUPT_GEN_MEMBER(ddealer_state::interrupt)
{
device.execute().set_input_line(4, HOLD_LINE);
}
@ -623,8 +617,8 @@ static MACHINE_CONFIG_START( ddealer, ddealer_state )
MCFG_CPU_ADD("maincpu" , M68000, XTAL_16MHz/2) /* 8MHz */
MCFG_CPU_PROGRAM_MAP(ddealer)
MCFG_CPU_VBLANK_INT_DRIVER("screen", ddealer_state, ddealer_interrupt)
MCFG_CPU_PERIODIC_INT_DRIVER(ddealer_state, irq1_line_hold, 90)//guess,controls music tempo,112 is way too fast
MCFG_CPU_VBLANK_INT_DRIVER("screen", ddealer_state, interrupt)
MCFG_CPU_PERIODIC_INT_DRIVER(ddealer_state, irq1_line_hold, 90)//guess, controls music tempo, 112 is way too fast
// M50747 or NMK-110 8131 MCU
@ -636,13 +630,13 @@ static MACHINE_CONFIG_START( ddealer, ddealer_state )
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
MCFG_SCREEN_SIZE(512, 256)
MCFG_SCREEN_VISIBLE_AREA(0*8, 48*8-1, 2*8, 30*8-1)
MCFG_SCREEN_UPDATE_DRIVER(ddealer_state, screen_update_ddealer)
MCFG_SCREEN_UPDATE_DRIVER(ddealer_state, screen_update)
MCFG_SCREEN_PALETTE("palette")
MCFG_PALETTE_ADD("palette", 0x400)
MCFG_PALETTE_FORMAT(RRRRGGGGBBBBRGBx)
MCFG_TIMER_DRIVER_ADD_PERIODIC("coinsim", ddealer_state, ddealer_mcu_sim, attotime::from_hz(10000))
MCFG_TIMER_DRIVER_ADD_PERIODIC("coinsim", ddealer_state, mcu_sim, attotime::from_hz(10000))
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("ymsnd", YM2203, XTAL_6MHz / 8) /* 7.5KHz */
@ -651,7 +645,7 @@ MACHINE_CONFIG_END
READ16_MEMBER(ddealer_state::ddealer_mcu_r)
READ16_MEMBER(ddealer_state::mcu_r)
{
static const int resp[] =
{
@ -674,7 +668,7 @@ READ16_MEMBER(ddealer_state::ddealer_mcu_r)
DRIVER_INIT_MEMBER(ddealer_state,ddealer)
{
m_maincpu->space(AS_PROGRAM).install_read_handler(0xfe01c, 0xfe01d, read16_delegate(FUNC(ddealer_state::ddealer_mcu_r), this));
m_maincpu->space(AS_PROGRAM).install_read_handler(0xfe01c, 0xfe01d, read16_delegate(FUNC(ddealer_state::mcu_r), this));
}
ROM_START( ddealer )