docastle: merge driver files, make idsoccer a subclass

This commit is contained in:
hap 2024-11-16 21:51:55 +01:00
parent e6402c0178
commit 7ca5080e79
5 changed files with 682 additions and 646 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,109 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Brad Oliver
/***************************************************************************
Mr. Do's Castle hardware
***************************************************************************/
#ifndef MAME_UNIVERSAL_DOCASTLE_H
#define MAME_UNIVERSAL_DOCASTLE_H
#pragma once
#include "machine/tms1024.h"
#include "video/mc6845.h"
#include "sound/msm5205.h"
#include "sound/sn76496.h"
#include "emupal.h"
#include "tilemap.h"
class docastle_state : public driver_device
{
public:
docastle_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_subcpu(*this, "subcpu"),
m_spritecpu(*this, "spritecpu"),
m_crtc(*this, "crtc"),
m_sn(*this, "sn%u", 1U),
m_msm(*this, "msm"),
m_inp(*this, "inp%u", 1),
m_videoram(*this, "videoram"),
m_colorram(*this, "colorram"),
m_spriteram(*this, "spriteram"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette")
{ }
void dorunrun(machine_config &config);
void idsoccer(machine_config &config);
void docastle(machine_config &config);
protected:
virtual void machine_start() override ATTR_COLD;
virtual void machine_reset() override ATTR_COLD;
virtual void video_start() override ATTR_COLD;
private:
// devices
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_subcpu;
required_device<cpu_device> m_spritecpu;
required_device<hd6845s_device> m_crtc;
required_device_array<sn76489a_device, 4> m_sn;
optional_device<msm5205_device> m_msm;
required_device_array<tms1025_device, 2> m_inp;
// memory pointers
required_shared_ptr<uint8_t> m_videoram;
required_shared_ptr<uint8_t> m_colorram;
required_shared_ptr<uint8_t> m_spriteram;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
// misc
int m_prev_ma6 = 0;
int m_adpcm_pos = 0;
int m_adpcm_idle = 0;
int m_adpcm_data = 0;
int m_adpcm_status = 0;
uint8_t m_shared_latch = 0;
bool m_maincpu_wait = false;
tilemap_t *m_do_tilemap = nullptr;
uint8_t main_from_sub_r(offs_t offset);
void main_to_sub_w(offs_t offset, uint8_t data);
uint8_t sub_from_main_r(offs_t offset);
void sub_to_main_w(offs_t offset, uint8_t data);
void subcpu_nmi_w(uint8_t data);
void videoram_w(offs_t offset, uint8_t data);
void colorram_w(offs_t offset, uint8_t data);
uint8_t inputs_flipscreen_r(offs_t offset);
void flipscreen_w(offs_t offset, uint8_t data);
uint8_t idsoccer_adpcm_status_r();
void idsoccer_adpcm_w(uint8_t data);
TILE_GET_INFO_MEMBER(get_tile_info);
void docastle_palette(palette_device &palette) const;
DECLARE_VIDEO_START(dorunrun);
uint32_t screen_update_docastle(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void video_start_common(uint32_t tile_transmask);
void draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void docastle_tint(int state);
void idsoccer_adpcm_int(int state);
void docastle_io_map(address_map &map) ATTR_COLD;
void docastle_map(address_map &map) ATTR_COLD;
void docastle_map2(address_map &map) ATTR_COLD;
void docastle_map3(address_map &map) ATTR_COLD;
void dorunrun_map(address_map &map) ATTR_COLD;
void dorunrun_map2(address_map &map) ATTR_COLD;
void idsoccer_map(address_map &map) ATTR_COLD;
};
#endif // MAME_UNIVERSAL_DOCASTLE_H

View File

@ -1,95 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Brad Oliver
/***************************************************************************
Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
I/O ports)
***************************************************************************/
#include "emu.h"
#include "cpu/z80/z80.h"
#include "docastle.h"
#define LOG_MAINSUB (1U << 1)
#define VERBOSE (0)
#include "logmacro.h"
/*
Communication between the two CPUs happens through a single bidirectional latch.
Whenever maincpu reads or writes it, its WAIT input is asserted. It is implicitly
cleared by subcpu, when it accesses the latch. This enforces synchronization
between the two CPUs.
It is initiated by maincpu triggering an NMI on subcpu. During this process,
timing needs to be cycle-accurate, both CPUs do LDIR opcodes in lockstep.
*/
uint8_t docastle_state::main_from_sub_r(offs_t offset)
{
if (!machine().side_effects_disabled())
{
m_maincpu_wait = !m_maincpu_wait;
if (m_maincpu_wait)
{
// steal 1 cycle ahead of WAIT to avoid race condition
m_maincpu->adjust_icount(-1);
machine().scheduler().perfect_quantum(attotime::from_usec(100));
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE);
// retry access after subcpu writes the latch and clears WAIT
m_maincpu->retry_access();
}
else
{
LOGMASKED(LOG_MAINSUB, "%dR%02X%c", offset, m_shared_latch, (offset == 8) ? '\n' : ' ');
// give back stolen cycle
m_maincpu->adjust_icount(1);
}
}
return m_shared_latch;
}
void docastle_state::main_to_sub_w(offs_t offset, uint8_t data)
{
LOGMASKED(LOG_MAINSUB, "%dW%02X ", offset, data);
m_shared_latch = data;
machine().scheduler().perfect_quantum(attotime::from_usec(100));
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE);
}
uint8_t docastle_state::sub_from_main_r(offs_t offset)
{
if (!machine().side_effects_disabled())
{
LOGMASKED(LOG_MAINSUB, "%dr%02X%c", offset, m_shared_latch, (offset == 8) ? '\n' : ' ');
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE);
}
return m_shared_latch;
}
void docastle_state::sub_to_main_w(offs_t offset, uint8_t data)
{
LOGMASKED(LOG_MAINSUB, "%dw%02X ", offset, data);
m_shared_latch = data;
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE);
}
void docastle_state::subcpu_nmi_w(uint8_t data)
{
LOGMASKED(LOG_MAINSUB, "%s trigger subcpu NMI\n", machine().describe_context());
machine().scheduler().perfect_quantum(attotime::from_usec(100));
m_subcpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}

View File

@ -1,222 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Brad Oliver
/***************************************************************************
Mr. Do's Castle hardware
Functions to emulate the video hardware of the machine.
***************************************************************************/
#include "emu.h"
#include "docastle.h"
#include "screen.h"
/***************************************************************************
Convert the color PROMs into a more useable format.
Mr. Do's Castle / Wild Ride / Run Run have a 256 bytes palette PROM which
is connected to the RGB output this way:
bit 7 -- 200 ohm resistor -- RED
-- 390 ohm resistor -- RED
-- 820 ohm resistor -- RED
-- 200 ohm resistor -- GREEN
-- 390 ohm resistor -- GREEN
-- 820 ohm resistor -- GREEN
-- 200 ohm resistor -- BLUE
bit 0 -- 390 ohm resistor -- BLUE
***************************************************************************/
void docastle_state::docastle_palette(palette_device &palette) const
{
uint8_t const *const color_prom = memregion("proms")->base();
for (int i = 0; i < 256; i++)
{
int bit0, bit1, bit2;
// red component
bit0 = BIT(color_prom[i], 5);
bit1 = BIT(color_prom[i], 6);
bit2 = BIT(color_prom[i], 7);
int const r = 0x23 * bit0 + 0x4b * bit1 + 0x91 * bit2;
// green component
bit0 = BIT(color_prom[i], 2);
bit1 = BIT(color_prom[i], 3);
bit2 = BIT(color_prom[i], 4);
int const g = 0x23 * bit0 + 0x4b * bit1 + 0x91 * bit2;
// blue component
bit0 = 0;
bit1 = BIT(color_prom[i], 0);
bit2 = BIT(color_prom[i], 1);
int const b = 0x23 * bit0 + 0x4b * bit1 + 0x91 * bit2;
/* because the graphics are decoded as 4bpp with the top bit used for transparency
or priority, we create matching 3bpp sets of palette entries, which effectively
ignores the value of the top bit */
palette.set_pen_color(((i & 0xf8) << 1) | 0x00 | (i & 0x07), rgb_t(r, g, b));
palette.set_pen_color(((i & 0xf8) << 1) | 0x08 | (i & 0x07), rgb_t(r, g, b));
}
}
void docastle_state::videoram_w(offs_t offset, uint8_t data)
{
m_videoram[offset] = data;
m_do_tilemap->mark_tile_dirty(offset);
}
void docastle_state::colorram_w(offs_t offset, uint8_t data)
{
m_colorram[offset] = data;
m_do_tilemap->mark_tile_dirty(offset);
}
uint8_t docastle_state::inputs_flipscreen_r(offs_t offset)
{
uint8_t buf = 0xff;
if (!machine().side_effects_disabled())
{
// inputs pass through LS244 non-inverting buffer
buf = (m_inp[1]->read_h() << 4) | m_inp[0]->read_h();
// LS273 latches address bits on rising edge of address decode
flip_screen_set(BIT(offset, 7));
m_inp[0]->write_s(offset & 7);
m_inp[1]->write_s(offset & 7);
}
return buf;
}
void docastle_state::flipscreen_w(offs_t offset, uint8_t data)
{
flip_screen_set(BIT(offset, 7));
}
TILE_GET_INFO_MEMBER(docastle_state::get_tile_info)
{
int code = m_videoram[tile_index] + 8 * (m_colorram[tile_index] & 0x20);
int color = m_colorram[tile_index] & 0x1f;
tileinfo.set(0, code, color, 0);
}
void docastle_state::video_start_common(uint32_t tile_transmask)
{
m_do_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(docastle_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_do_tilemap->set_scrolldy(-32, -32);
m_do_tilemap->set_transmask(0, tile_transmask, 0x0000);
}
void docastle_state::video_start()
{
video_start_common(0x00ff);
}
VIDEO_START_MEMBER(docastle_state,dorunrun)
{
video_start_common(0xff00);
}
void docastle_state::draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
screen.priority().fill(1);
for (int offs = m_spriteram.bytes() - 4; offs >= 0; offs -= 4)
{
int sx, sy, flipx, flipy, code, color;
if (m_gfxdecode->gfx(1)->elements() > 256)
{
/* spriteram
indoor soccer appears to have a slightly different spriteram
format to the other games, allowing a larger number of sprite
tiles
yyyy yyyy xxxx xxxx TX-T pppp tttt tttt
y = ypos
x = xpos
X = x-flip
T = extra tile number bits
p = palette
t = tile number
*/
code = m_spriteram[offs + 3];
color = m_spriteram[offs + 2] & 0x0f;
sx = ((m_spriteram[offs + 1] + 8) & 0xff) - 8;
sy = m_spriteram[offs] - 32;
flipx = m_spriteram[offs + 2] & 0x40;
flipy = 0;
if (m_spriteram[offs + 2] & 0x10) code += 0x100;
if (m_spriteram[offs + 2] & 0x80) code += 0x200;
}
else
{
/* spriteram
this is the standard spriteram layout, used by most games
yyyy yyyy xxxx xxxx YX-p pppp tttt tttt
y = ypos
x = xpos
X = x-flip
Y = y-flip
p = palette
t = tile number
*/
code = m_spriteram[offs + 3];
color = m_spriteram[offs + 2] & 0x1f;
sx = ((m_spriteram[offs + 1] + 8) & 0xff) - 8;
sy = m_spriteram[offs] - 32;
flipx = m_spriteram[offs + 2] & 0x40;
flipy = m_spriteram[offs + 2] & 0x80;
}
if (flip_screen())
{
sx = 240 - sx;
sy = 176 - sy;
flipx = !flipx;
flipy = !flipy;
}
// first draw the sprite, visible
m_gfxdecode->gfx(1)->prio_transmask(bitmap,cliprect,
code,
color,
flipx,flipy,
sx,sy,
screen.priority(),
0x00,0x80ff);
// then draw the mask, behind the background but obscuring following sprites
m_gfxdecode->gfx(1)->prio_transmask(bitmap,cliprect,
code,
color,
flipx,flipy,
sx,sy,
screen.priority(),
0x02,0x7fff);
}
}
uint32_t docastle_state::screen_update_docastle(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
m_do_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
draw_sprites(screen, bitmap, cliprect);
m_do_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0, 0);
return 0;
}

View File

@ -1,6 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
/***************************************************************************
/*******************************************************************************
Zero Hour / Red Clash
@ -32,7 +32,7 @@ BTANB:
- other than the pitch being inaccurate (see TODO), redclash beeper really does
sound like garbage, the only time it sounds pleasing is during the boss fight
***************************************************************************/
*******************************************************************************/
#include "emu.h"
#include "zerohour_stars.h"
@ -180,18 +180,18 @@ void redclash_state::machine_start()
/***************************************************************************
/*******************************************************************************
Video
***************************************************************************/
*******************************************************************************/
/***************************************************************************
/*******************************************************************************
Convert the color PROMs into a more useable format.
I'm using the same palette conversion as Lady Bug, but the Zero Hour
schematics show a different resistor network.
***************************************************************************/
*******************************************************************************/
void zerohour_state::palette(palette_device &palette) const
{
@ -445,9 +445,9 @@ u32 redclash_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c
/***************************************************************************
/*******************************************************************************
Sound
***************************************************************************/
*******************************************************************************/
static const char *const zerohour_sample_names[] =
{
@ -527,9 +527,9 @@ void redclash_state::beep_trigger_w(int state)
/***************************************************************************
/*******************************************************************************
Address Maps
***************************************************************************/
*******************************************************************************/
void zerohour_state::zerohour_map(address_map &map)
{
@ -567,9 +567,9 @@ void redclash_state::redclash_map(address_map &map)
/***************************************************************************
/*******************************************************************************
Input Ports
***************************************************************************/
*******************************************************************************/
INPUT_CHANGED_MEMBER( zerohour_state::left_coin_inserted )
{
@ -724,9 +724,9 @@ INPUT_PORTS_END
/***************************************************************************
/*******************************************************************************
GFX Layouts
***************************************************************************/
*******************************************************************************/
static const gfx_layout charlayout =
{
@ -794,9 +794,9 @@ GFXDECODE_END
/***************************************************************************
/*******************************************************************************
Machine Configs
***************************************************************************/
*******************************************************************************/
void zerohour_state::base(machine_config &config)
{
@ -884,9 +884,9 @@ void redclash_state::redclash(machine_config &config)
/***************************************************************************
/*******************************************************************************
ROM Definitions
***************************************************************************/
*******************************************************************************/
ROM_START( zerohour )
ROM_REGION( 0x10000, "maincpu", 0 )
@ -1074,11 +1074,11 @@ ROM_END
/***************************************************************************
/*******************************************************************************
Drivers
***************************************************************************/
*******************************************************************************/
// YEAR NAME PARENT MACHINE INPUT STATE INIT SCREEN COMPANY FULLNAME FLAGS
// YEAR NAME PARENT MACHINE INPUT CLASS INIT SCREEN COMPANY FULLNAME FLAGS
GAME( 1980, zerohour, 0, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "Universal", "Zero Hour (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1980, zerohoura, zerohour, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "Universal", "Zero Hour (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1980, zerohouri, zerohour, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "bootleg (Inder SA)", "Zero Hour (bootleg)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )