Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dt7.cpp - improve text layer handling (adds rowselect, fixes course select screen) [David Haywood] #13039

Merged
merged 7 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 128 additions & 57 deletions src/mame/toaplan/dt7.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@
differences to keep it separate

TODO:
- verify audio CPU opcodes
- verify audio CPU opcodes (see toaplan_v25_tables.h)
- correctly hook up interrupts (especially V25)
- correctly hook up inputs (there's a steering wheel test? is the game switchable)
- serial comms (needs support in V25 core?) for linked units
- verify frequencies on chips
- verify alt titles, some regions have 'Car Fighting' as a subtitle, region comes from EEPROM?
- verify text layer palettes
- currently only coins up with service button
- course selection cursor doesn't move?
- sound dies after one stage?
- game crashes after two stages?
- service mode doesn't display properly
- currently only coins up with service button
- sound dies after one stage?
*/


Expand Down Expand Up @@ -55,6 +54,11 @@ class dt7_state : public driver_device
, m_palette(*this, "palette%u", 0U)
, m_shared_ram(*this, "shared_ram")
, m_tx_videoram(*this, "tx_videoram")
, m_lineram(*this, "lineram")
, m_eepromport(*this, "EEPROM")
, m_sysport(*this, "SYS")
, m_p1port(*this, "IN1")
, m_p2port(*this, "IN2")
{ }

public:
Expand All @@ -71,15 +75,17 @@ class dt7_state : public driver_device

void tx_videoram_dt7_w(offs_t offset, u16 data, u16 mem_mask = ~0);

TILE_GET_INFO_MEMBER(get_text_dt7_tile_info);
TILE_GET_INFO_MEMBER(get_tx_dt7_tile_info);

void draw_tx_tilemap(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect, int table);

void dt7_68k_0_mem(address_map &map);
void dt7_68k_1_mem(address_map &map);
void dt7_v25_mem(address_map &map);
void dt7_shared_mem(address_map &map);

void dt7_irq(int state);
void dt7_unk_w(u8 data);
void dt7_sndreset_coin_w(offs_t offset, u16 data, u16 mem_mask);

uint8_t unmapped_v25_io1_r();
uint8_t unmapped_v25_io2_r();
Expand All @@ -88,8 +94,13 @@ class dt7_state : public driver_device
uint8_t read_port_2();
void write_port_2(uint8_t data);

uint8_t eeprom_r();
void eeprom_w(uint8_t data);


u8 dt7_shared_ram_hack_r(offs_t offset);
void shared_ram_w(offs_t offset, u8 data);
void shared_ram_audio_w(offs_t offset, u8 data);

void screen_vblank(int state);

Expand All @@ -110,6 +121,11 @@ class dt7_state : public driver_device
required_device_array<palette_device, 2> m_palette;
required_shared_ptr<u8> m_shared_ram; // 8 bit RAM shared between 68K and sound CPU
required_shared_ptr<u16> m_tx_videoram;
required_shared_ptr<u16> m_lineram;
required_ioport m_eepromport;
required_ioport m_sysport;
required_ioport m_p1port;
required_ioport m_p2port;
};


Expand All @@ -131,16 +147,48 @@ void dt7_state::dt7_irq(int state)
// this is conditional on the unknown type of branch (see #define G_B0 in the table0
uint8_t dt7_state::read_port_t()
{
logerror("%s: read port t\n", machine().describe_context()); return machine().rand();
logerror("%s: read port t\n", machine().describe_context());
return machine().rand();
}

uint8_t dt7_state::read_port_2()
{
logerror("%s: read port 2\n", machine().describe_context());

return 0xff;
}

uint8_t dt7_state::eeprom_r()
{
if (m_ioport_state & 0x10)
{
logerror("%s: eeprom_r\n", machine().describe_context());
// if you allow eeprom hookup at the moment (remove the ram hack reads)
// the game will init it the first time but then 2nd boot will be upside
// down as Japan region, and hang after the region warning
//return 0xff;
return m_eepromport->read();
}
else
{
logerror("%s: eeprom_r without eeprom enabled?\n", machine().describe_context());
return 0xff;
}
}

void dt7_state::eeprom_w(uint8_t data)
{
if (m_ioport_state & 0x10)
{
logerror("%s: eeprom_w %02x\n", machine().describe_context(), data);
m_eepromport->write(data);
}
else
{
logerror("%s: eeprom_w without eeprom enabled %02x\n", machine().describe_context(), data);
}
}


// it seems to attempt to read inputs (including the tilt switch?) here on startup
// strangely all the EEPROM access code (which is otherwise very similar to FixEight
// also has accesses to this port added, maybe something is sitting in the middle?
Expand Down Expand Up @@ -218,29 +266,22 @@ void dt7_state::write_port_2(uint8_t data)
u8 dt7_state::dt7_shared_ram_hack_r(offs_t offset)
{
u16 ret = m_shared_ram[offset];

int pc = m_maincpu->pc();

if (pc == 0x7d84) { return 0xff; } // status?

u32 addr = (offset * 2) + 0x610000;

if (addr == 0x061f00c)
return ioport("SYS")->read();// machine().rand();

//return ret;


u32 pc = m_maincpu->pc();
if (pc == 0x7d84)
return 0xff;
if (addr == 0x061d000) // settings (from EEPROM?) including flipscreen
return 0x00;
if (addr == 0x061d002) // settings (from EEPROM?) dipswitch?
return 0x00;
if (addr == 0x061d004) // settings (from EEPROM?) region
return 0xff;
if (addr == 0x061f004)
return ioport("IN1")->read(); ;// machine().rand(); // p1 inputs
if (addr == 0x061f006)
return ioport("IN2")->read();// machine().rand(); // P2 inputs
// logerror("%08x: dt7_shared_ram_hack_r address %08x ret %02x\n", pc, addr, ret);

if (addr == 0x061f00c) { return m_sysport->read(); }
if (addr == 0x061d000) { return 0x00; } // settings (from EEPROM?) including flipscreen
if (addr == 0x061d002) { return 0x00; } // settings (from EEPROM?) dipswitch?
if (addr == 0x061d004) { return 0x00; } // settings (from EEPROM?) region
if (addr == 0x061f004) { return m_p1port->read(); } // P1 inputs
if (addr == 0x061f006) { return m_p2port->read(); } // P2 inputs
//if (addr == 0x061f00e) { return machine().rand(); } // P2 coin / start

logerror("%08x: dt7_shared_ram_hack_r address %08x ret %02x\n", pc, addr, ret);
return ret;
}

Expand All @@ -249,10 +290,20 @@ void dt7_state::shared_ram_w(offs_t offset, u8 data)
m_shared_ram[offset] = data;
}

void dt7_state::shared_ram_audio_w(offs_t offset, u8 data)
{
// just a helper function to try and debug the sound CPU a bit more easily
//int pc = m_audiocpu->pc();
//if (offset == 0xf004 / 2)
// logerror("%08x: shared_ram_audio_w address %08x data %02x\n", pc, offset, data);
shared_ram_w(offset, data);
}

void dt7_state::dt7_unk_w(u8 data)
void dt7_state::dt7_sndreset_coin_w(offs_t offset, u16 data, u16 mem_mask)
{
m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x80) ? CLEAR_LINE : ASSERT_LINE);
m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x8000) ? CLEAR_LINE : ASSERT_LINE);
logerror("%s: dt7_sndreset_coin_w %04x %04x\n", machine().describe_context(), data, mem_mask);
// coin counters in lower byte?
}


Expand All @@ -266,7 +317,7 @@ void dt7_state::dt7_68k_0_mem(address_map &map)
map(0x200000, 0x200fff).ram().w(m_palette[0], FUNC(palette_device::write16)).share("palette0");
map(0x280000, 0x280fff).ram().w(m_palette[1], FUNC(palette_device::write16)).share("palette1");

map(0x300000, 0x300000).w(FUNC(dt7_state::dt7_unk_w));
map(0x300000, 0x300001).w(FUNC(dt7_state::dt7_sndreset_coin_w));

map(0x400000, 0x40000d).rw(m_vdp[0], FUNC(gp9001vdp_device::read), FUNC(gp9001vdp_device::write));
map(0x480000, 0x48000d).rw(m_vdp[1], FUNC(gp9001vdp_device::read), FUNC(gp9001vdp_device::write));
Expand All @@ -282,6 +333,7 @@ void dt7_state::dt7_shared_mem(address_map &map)
map(0x500000, 0x50ffff).ram().share("shared_ram2");
// is this really in the middle of shared RAM, or is there a DMA to get it out?
map(0x509000, 0x50afff).ram().w(FUNC(dt7_state::tx_videoram_dt7_w)).share("tx_videoram");
map(0x50f000, 0x50ffff).ram().share("lineram");

}
void dt7_state::dt7_68k_1_mem(address_map &map)
Expand All @@ -307,13 +359,13 @@ uint8_t dt7_state::unmapped_v25_io2_r()
void dt7_state::dt7_v25_mem(address_map &map)
{
// exact mirroring unknown, don't cover up where the inputs/sound maps
map(0x00000, 0x07fff).ram().share("shared_ram");
map(0x20000, 0x27fff).ram().share("shared_ram");
map(0x28000, 0x2ffff).ram().share("shared_ram");
map(0x60000, 0x67fff).ram().share("shared_ram");
map(0x68000, 0x6ffff).ram().share("shared_ram");
map(0x70000, 0x77fff).ram().share("shared_ram");
map(0xf8000, 0xfffff).ram().share("shared_ram");
map(0x00000, 0x07fff).ram().w(FUNC(shared_ram_audio_w)).share("shared_ram");
map(0x20000, 0x27fff).ram().w(FUNC(shared_ram_audio_w)).share("shared_ram");
map(0x28000, 0x2ffff).ram().w(FUNC(shared_ram_audio_w)).share("shared_ram");
map(0x60000, 0x67fff).ram().w(FUNC(shared_ram_audio_w)).share("shared_ram");
map(0x68000, 0x6ffff).ram().w(FUNC(shared_ram_audio_w)).share("shared_ram");
map(0x70000, 0x77fff).ram().w(FUNC(shared_ram_audio_w)).share("shared_ram");
map(0xf8000, 0xfffff).ram().w(FUNC(shared_ram_audio_w)).share("shared_ram");

map(0x58000, 0x58001).rw("ymsnd", FUNC(ym2151_device::read), FUNC(ym2151_device::write));
map(0x58002, 0x58002).rw(m_oki[0], FUNC(okim6295_device::read), FUNC(okim6295_device::write));
Expand Down Expand Up @@ -356,8 +408,8 @@ void dt7_state::dt7(machine_config &config)
audiocpu.pt_in_cb().set(FUNC(dt7_state::read_port_t));
audiocpu.p2_in_cb().set(FUNC(dt7_state::read_port_2));
audiocpu.p2_out_cb().set(FUNC(dt7_state::write_port_2));
//audiocpu.p1_in_cb().set_ioport("EEPROM");
//audiocpu.p1_out_cb().set_ioport("EEPROM");
audiocpu.p1_in_cb().set(FUNC(dt7_state::eeprom_r));
audiocpu.p1_out_cb().set(FUNC(dt7_state::eeprom_w));

// eeprom type confirmed, and gets inited after first boot, but then game won't boot again?
EEPROM_93C66_16BIT(config, m_eeprom);
Expand Down Expand Up @@ -436,7 +488,7 @@ static INPUT_PORTS_START( dt7 )
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", FUNC(eeprom_serial_93cxx_device::do_read))
INPUT_PORTS_END

TILE_GET_INFO_MEMBER(dt7_state::get_text_dt7_tile_info)
TILE_GET_INFO_MEMBER(dt7_state::get_tx_dt7_tile_info)
{
const u16 attrib = m_tx_videoram[tile_index];
const u32 tile_number = attrib & 0x3ff;
Expand All @@ -460,8 +512,8 @@ void dt7_state::video_start()

// a different part of this tilemap is displayed on each screen
// each screen has a different palette and uses a ROM in a different location on the PCB
m_tx_tilemap[0] = &machine().tilemap().create(*m_gfxdecode[0], tilemap_get_info_delegate(*this, FUNC(dt7_state::get_text_dt7_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
m_tx_tilemap[1] = &machine().tilemap().create(*m_gfxdecode[1], tilemap_get_info_delegate(*this, FUNC(dt7_state::get_text_dt7_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
m_tx_tilemap[0] = &machine().tilemap().create(*m_gfxdecode[0], tilemap_get_info_delegate(*this, FUNC(dt7_state::get_tx_dt7_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
m_tx_tilemap[1] = &machine().tilemap().create(*m_gfxdecode[1], tilemap_get_info_delegate(*this, FUNC(dt7_state::get_tx_dt7_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);

m_tx_tilemap[0]->set_transparent_pen(0);
m_tx_tilemap[1]->set_transparent_pen(0);
Expand All @@ -470,10 +522,34 @@ void dt7_state::video_start()
void dt7_state::tx_videoram_dt7_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_tx_videoram[offset]);
if (offset < 64 * 64)
m_tx_tilemap[0]->mark_tile_dirty(offset);
m_tx_tilemap[1]->mark_tile_dirty(offset);
}


void dt7_state::draw_tx_tilemap(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect, int table)
{
// there seems to be RAM for another tx tilemap
// but there were 2 empty sockets / sockets with blank tx ROMs, so
// it's likely only one of them is used

// see comments in other toaplan drivers, this is likely per-line
int flipx = m_lineram[(table * 2)] & 0x8000;
m_tx_tilemap[table / 2]->set_flip(flipx ? 0 : TILEMAP_FLIPX);

rectangle clip = cliprect;
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
m_tx_tilemap[0]->mark_tile_dirty(offset);
m_tx_tilemap[1]->mark_tile_dirty(offset);
clip.min_y = clip.max_y = y;

u16 scroll1 = m_lineram[((y * 8) + (table * 2) + 0) & 0x7ff]; // lineselect
//u16 scroll2 = m_lineram[((y * 8) + (table * 2) + 1) & 0x7ff]; // xscroll

scroll1 &= 0x7fff; // 0x8000 is per-line flip
scroll1 -= 0x0900; // are all these scroll bits?

m_tx_tilemap[table / 2]->set_scrolly(0, scroll1 - y);
m_tx_tilemap[table / 2]->draw(screen, bitmap, clip, 0);
}
}

Expand All @@ -482,22 +558,17 @@ u32 dt7_state::screen_update_dt7_1(screen_device &screen, bitmap_ind16 &bitmap,
bitmap.fill(0, cliprect);
m_custom_priority_bitmap.fill(0, cliprect);
m_vdp[0]->render_vdp(bitmap, cliprect);

m_tx_tilemap[0]->set_scrolldy(0, 0);
m_tx_tilemap[0]->draw(screen, bitmap, cliprect, 0);

draw_tx_tilemap(screen, bitmap, cliprect, 0);
return 0;
}


u32 dt7_state::screen_update_dt7_2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0, cliprect);
m_custom_priority_bitmap.fill(0, cliprect);
m_vdp[1]->render_vdp(bitmap, cliprect);

m_tx_tilemap[1]->set_scrolldy(256 + 16, 256 + 16);
m_tx_tilemap[1]->draw(screen, bitmap, cliprect, 0);

draw_tx_tilemap(screen, bitmap, cliprect, 2);
return 0;
}

Expand Down Expand Up @@ -558,4 +629,4 @@ ROM_END
} // anonymous namespace

// The region comes from the EEPROM? so will need clones like FixEight
GAME( 1993, dt7, 0, dt7, dt7, dt7_state,empty_init, ROT270, "Toaplan", "DT7 (prototype)", MACHINE_NOT_WORKING )
GAME( 1993, dt7, 0, dt7, dt7, dt7_state,empty_init, ROT270, "Toaplan", "DT7 (prototype)", MACHINE_NOT_WORKING ) // flyer shows "Survival Battle Dynamic Trial 7"
10 changes: 5 additions & 5 deletions src/mame/toaplan/toaplan_v25_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ class toaplan_v25_tables
// some kind of branch, not sure which
// it's used after compares in blocks, sometimes with a 'be' then a 'br' straight after, so it must be a condition that could also fail a be and fall to the br
//#define G_B0 0x74
#define G_B0 0x79
#define G_B0 0x77 // context suggests that this might instead be 0x77 (it follows comparing a bit position against 7)
//#define G_B0 0x75

// 6b @ 73827
#define G_6B 0x34 // must be a 2 byte operation on al? after an AND, 2nd byte is 0x08
// 6b @ 73827 // must be a 2 byte operation on al? after an AND, at end of interrupt, 2nd byte is 0x08
#define G_6B 0x34 // treat as XOR, could be OR?

// 59 @ 73505 and 7379B (maybe ret?, or di?)
// 59 @ 73505 and 7379B
//#define G_59 0xfa
#define G_59 0xc3
#define G_59 0xc3 // almost certainly has to be ret

static constexpr u8 dt7_decryption_table[256] = {
// 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, /* 00 */
Expand Down
Loading