mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
espial,zodiack: add sound nmi timer, small cleanup, increase netwars sound nmi frequency
This commit is contained in:
parent
1cdd24ebb8
commit
a6fddc3fe4
@ -68,15 +68,15 @@ void namcos1_state::TilemapCB(u16 code, int &tile, int &mask)
|
||||
|
||||
void namcos1_state::video_start()
|
||||
{
|
||||
/* set table for sprite color == 0x7f */
|
||||
// set table for sprite color == 0x7f
|
||||
for (int i = 0; i < 15; i++)
|
||||
m_drawmode_table[i] = DRAWMODE_SHADOW;
|
||||
m_drawmode_table[15] = DRAWMODE_NONE;
|
||||
|
||||
/* all palette entries are not affected by shadow sprites... */
|
||||
// all palette entries are not affected by shadow sprites...
|
||||
for (int i = 0; i < 0x2000; i++)
|
||||
m_c116->shadow_table()[i] = i;
|
||||
/* ... except for tilemap colors */
|
||||
// ... except for tilemap colors
|
||||
for (int i = 0x0800; i < 0x1000; i++)
|
||||
m_c116->shadow_table()[i] = i + 0x0800;
|
||||
|
||||
@ -95,11 +95,11 @@ void namcos1_state::video_start()
|
||||
|
||||
void namcos1_state::spriteram_w(offs_t offset, u8 data)
|
||||
{
|
||||
/* 0000-07ff work ram */
|
||||
/* 0800-0fff sprite ram */
|
||||
// 0000-07ff work ram
|
||||
// 0800-0fff sprite ram
|
||||
m_spriteram[offset] = data;
|
||||
|
||||
/* a write to this offset tells the sprite chip to buffer the sprite list */
|
||||
// a write to this offset tells the sprite chip to buffer the sprite list
|
||||
if (offset == 0x0ff2)
|
||||
m_copy_sprites = true;
|
||||
}
|
||||
@ -135,7 +135,7 @@ sprite format:
|
||||
void namcos1_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
u8 *spriteram = m_spriteram + 0x800;
|
||||
const u8 *source = &spriteram[0x800-0x20]; /* the last is NOT a sprite */
|
||||
const u8 *source = &spriteram[0x800-0x20]; // the last is NOT a sprite
|
||||
const u8 *finish = &spriteram[0];
|
||||
gfx_element *gfx = m_gfxdecode->gfx(0);
|
||||
|
||||
@ -175,7 +175,7 @@ void namcos1_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
flipy = !flipy;
|
||||
}
|
||||
|
||||
sy++; /* sprites are buffered and delayed by one scanline */
|
||||
sy++; // sprites are buffered and delayed by one scanline
|
||||
|
||||
gfx->set_source_clip(tx, sizex, ty, sizey);
|
||||
if (color != 0x7f)
|
||||
@ -207,13 +207,13 @@ u32 namcos1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
{
|
||||
rectangle new_clip = cliprect;
|
||||
|
||||
/* flip screen is embedded in the sprite control registers */
|
||||
// flip screen is embedded in the sprite control registers
|
||||
flip_screen_set(m_spriteram[0x0ff6] & 1);
|
||||
|
||||
/* background color */
|
||||
// background color
|
||||
bitmap.fill(m_c116->black_pen(), cliprect);
|
||||
|
||||
/* berabohm uses asymmetrical visibility windows to iris on the character */
|
||||
// berabohm uses asymmetrical visibility windows to iris on the character
|
||||
int i = m_c116->get_reg(0) - 1; // min x
|
||||
if (new_clip.min_x < i) new_clip.min_x = i;
|
||||
i = m_c116->get_reg(1) - 1 - 1; // max x
|
||||
@ -230,8 +230,8 @@ u32 namcos1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
|
||||
screen.priority().fill(0, new_clip);
|
||||
|
||||
/* bit 0-2 priority */
|
||||
/* bit 3 disable */
|
||||
// bit 0-2 priority
|
||||
// bit 3 disable
|
||||
for (int priority = 0; priority < 8; priority++)
|
||||
{
|
||||
m_c123tmap->draw(screen, bitmap, new_clip, priority, priority, 0);
|
||||
@ -244,9 +244,9 @@ u32 namcos1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
|
||||
void namcos1_state::screen_vblank(int state)
|
||||
{
|
||||
// rising edge
|
||||
if (state)
|
||||
{
|
||||
// rising edge
|
||||
if (m_copy_sprites)
|
||||
{
|
||||
u8 *spriteram = m_spriteram + 0x800;
|
||||
@ -265,6 +265,8 @@ void namcos1_state::screen_vblank(int state)
|
||||
}
|
||||
else
|
||||
{
|
||||
// falling edge
|
||||
// splatter 2nd bossfight music fails if audiocpu irq is at the same time as main/sub irq
|
||||
m_audiocpu->set_input_line(M6809_IRQ_LINE, ASSERT_LINE);
|
||||
m_mcu->set_input_line(HD6301_IRQ1_LINE, ASSERT_LINE);
|
||||
}
|
||||
|
@ -3,7 +3,10 @@
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Espial hardware games
|
||||
Espial hardware games
|
||||
|
||||
2 XTALS (12.0MHz and 18.432MHz), both CPUs are 3.0MHz and the AY is 1.5MHz.
|
||||
18.432MHz XTAL is probably for the pixel clock.
|
||||
|
||||
Espial: The Orca logo is displayed, but looks to be "blacked out" via the
|
||||
color PROMs by having 0x1c & 0x1d set to black.
|
||||
@ -43,7 +46,6 @@ Stephh's notes (based on the games Z80 code and some tests) :
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/gen_latch.h"
|
||||
#include "machine/timer.h"
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/ay8910.h"
|
||||
|
||||
@ -67,9 +69,11 @@ public:
|
||||
m_colorram(*this, "colorram"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_audiocpu(*this, "audiocpu"),
|
||||
m_screen(*this, "screen"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_palette(*this, "palette"),
|
||||
m_soundlatch(*this, "soundlatch")
|
||||
m_soundlatch(*this, "soundlatch%u", 0),
|
||||
m_aysnd(*this, "aysnd")
|
||||
{ }
|
||||
|
||||
void espial(machine_config &config);
|
||||
@ -88,22 +92,29 @@ protected:
|
||||
|
||||
// video-related
|
||||
tilemap_t *m_bg_tilemap = nullptr;
|
||||
uint8_t m_flipscreen = 0U;
|
||||
uint8_t m_flipscreen = 0;
|
||||
|
||||
// sound-related
|
||||
uint8_t m_main_nmi_enabled = 0U;
|
||||
uint8_t m_sound_nmi_enabled = 0U;
|
||||
uint8_t m_main_nmi_enabled = 0;
|
||||
uint8_t m_sound_nmi_enabled = 0;
|
||||
uint8_t m_sound_nmi_freq = 0;
|
||||
emu_timer *sound_nmi_timer;
|
||||
|
||||
// devices
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<generic_latch_8_device> m_soundlatch;
|
||||
required_device_array<generic_latch_8_device, 2> m_soundlatch;
|
||||
required_device<ay8910_device> m_aysnd;
|
||||
|
||||
void master_interrupt_mask_w(uint8_t data);
|
||||
void master_soundlatch_w(uint8_t data);
|
||||
void sound_nmi_mask_w(uint8_t data);
|
||||
void porta_w(offs_t offset, uint8_t data, uint8_t mem_mask);
|
||||
TIMER_CALLBACK_MEMBER(sound_nmi_gen);
|
||||
void vblank(int state);
|
||||
|
||||
void videoram_w(offs_t offset, uint8_t data);
|
||||
void colorram_w(offs_t offset, uint8_t data);
|
||||
void attributeram_w(offs_t offset, uint8_t data);
|
||||
@ -112,9 +123,8 @@ protected:
|
||||
TILE_GET_INFO_MEMBER(get_tile_info);
|
||||
void palette(palette_device &palette) const;
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
INTERRUPT_GEN_MEMBER(sound_nmi_gen);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(scanline);
|
||||
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void main_map(address_map &map) ATTR_COLD;
|
||||
void sound_io_map(address_map &map) ATTR_COLD;
|
||||
void sound_map(address_map &map) ATTR_COLD;
|
||||
@ -123,7 +133,9 @@ protected:
|
||||
class netwars_state : public espial_state
|
||||
{
|
||||
public:
|
||||
using espial_state::espial_state;
|
||||
netwars_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
espial_state(mconfig, type, tag)
|
||||
{ }
|
||||
|
||||
void netwars(machine_config &config);
|
||||
|
||||
@ -135,7 +147,32 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Machine initialization
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void espial_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_flipscreen));
|
||||
save_item(NAME(m_main_nmi_enabled));
|
||||
save_item(NAME(m_sound_nmi_enabled));
|
||||
save_item(NAME(m_sound_nmi_freq));
|
||||
|
||||
sound_nmi_timer = timer_alloc(FUNC(espial_state::sound_nmi_gen), this);
|
||||
}
|
||||
|
||||
void espial_state::machine_reset()
|
||||
{
|
||||
m_main_nmi_enabled = false;
|
||||
m_sound_nmi_enabled = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
|
||||
Convert the color PROMs into a more useable format.
|
||||
|
||||
@ -153,7 +190,7 @@ private:
|
||||
-- 470 ohm resistor -- RED
|
||||
bit 0 -- 1 kohm resistor -- RED
|
||||
|
||||
***************************************************************************/
|
||||
*************************************/
|
||||
|
||||
void espial_state::palette(palette_device &palette) const
|
||||
{
|
||||
@ -168,11 +205,13 @@ void espial_state::palette(palette_device &palette) const
|
||||
bit1 = BIT(color_prom[i], 1);
|
||||
bit2 = BIT(color_prom[i], 2);
|
||||
int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
|
||||
|
||||
// green component
|
||||
bit0 = BIT(color_prom[i], 3);
|
||||
bit1 = BIT(color_prom[i + palette.entries()], 0);
|
||||
bit2 = BIT(color_prom[i + palette.entries()], 1);
|
||||
int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
|
||||
|
||||
// blue component
|
||||
bit0 = 0;
|
||||
bit1 = BIT(color_prom[i + palette.entries()], 2);
|
||||
@ -185,23 +224,6 @@ void espial_state::palette(palette_device &palette) const
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Callbacks for the TileMap code
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
TILE_GET_INFO_MEMBER(espial_state::get_tile_info)
|
||||
{
|
||||
uint8_t const code = m_videoram[tile_index];
|
||||
uint8_t const col = m_colorram[tile_index];
|
||||
uint8_t const attr = m_attributeram[tile_index];
|
||||
|
||||
tileinfo.set(0, code | ((attr & 0x03) << 8), col & 0x3f, TILE_FLIPYX(attr >> 2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video system start
|
||||
@ -212,61 +234,25 @@ void espial_state::video_start()
|
||||
{
|
||||
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(espial_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
m_bg_tilemap->set_scroll_cols(32);
|
||||
|
||||
save_item(NAME(m_flipscreen));
|
||||
}
|
||||
|
||||
void netwars_state::video_start()
|
||||
{
|
||||
// Net Wars has a tile map that's twice as big as Espial's
|
||||
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(netwars_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 64);
|
||||
|
||||
m_bg_tilemap->set_scroll_cols(32);
|
||||
|
||||
save_item(NAME(m_flipscreen));
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Memory handlers
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void espial_state::videoram_w(offs_t offset, uint8_t data)
|
||||
TILE_GET_INFO_MEMBER(espial_state::get_tile_info)
|
||||
{
|
||||
m_videoram[offset] = data;
|
||||
m_bg_tilemap->mark_tile_dirty(offset);
|
||||
uint8_t const code = m_videoram[tile_index];
|
||||
uint8_t const col = m_colorram[tile_index];
|
||||
uint8_t const attr = m_attributeram[tile_index];
|
||||
|
||||
tileinfo.set(0, code | ((attr & 0x03) << 8), col & 0x3f, TILE_FLIPYX(attr >> 2));
|
||||
}
|
||||
|
||||
|
||||
void espial_state::colorram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_colorram[offset] = data;
|
||||
m_bg_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
|
||||
void espial_state::attributeram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_attributeram[offset] = data;
|
||||
m_bg_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
|
||||
void espial_state::scrollram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_scrollram[offset] = data;
|
||||
m_bg_tilemap->set_scrolly(offset, data);
|
||||
}
|
||||
|
||||
|
||||
void espial_state::flipscreen_w(uint8_t data)
|
||||
{
|
||||
m_flipscreen = data;
|
||||
m_bg_tilemap->set_flip(m_flipscreen ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0);
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -333,7 +319,6 @@ void espial_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t espial_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
@ -342,20 +327,66 @@ uint32_t espial_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap
|
||||
}
|
||||
|
||||
|
||||
void espial_state::machine_reset()
|
||||
{
|
||||
m_flipscreen = 0;
|
||||
|
||||
m_main_nmi_enabled = false;
|
||||
m_sound_nmi_enabled = false;
|
||||
/*************************************
|
||||
*
|
||||
* Memory handlers
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void espial_state::vblank(int state)
|
||||
{
|
||||
// vblank irq
|
||||
if (state && m_main_nmi_enabled)
|
||||
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
|
||||
// timer irq, checks soundlatch port then updates some sound related work RAM buffers
|
||||
if (state)
|
||||
m_maincpu->set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
|
||||
void espial_state::machine_start()
|
||||
|
||||
TIMER_CALLBACK_MEMBER(espial_state::sound_nmi_gen)
|
||||
{
|
||||
save_item(NAME(m_sound_nmi_enabled));
|
||||
if (m_sound_nmi_enabled)
|
||||
m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
}
|
||||
|
||||
|
||||
void espial_state::videoram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_videoram[offset] = data;
|
||||
m_bg_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
|
||||
void espial_state::colorram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_colorram[offset] = data;
|
||||
m_bg_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
|
||||
void espial_state::attributeram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_attributeram[offset] = data;
|
||||
m_bg_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
|
||||
void espial_state::scrollram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_scrollram[offset] = data;
|
||||
m_bg_tilemap->set_scrolly(offset, data);
|
||||
}
|
||||
|
||||
|
||||
void espial_state::flipscreen_w(uint8_t data)
|
||||
{
|
||||
m_flipscreen = data;
|
||||
m_bg_tilemap->set_flip(m_flipscreen ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0);
|
||||
}
|
||||
|
||||
void espial_state::master_interrupt_mask_w(uint8_t data)
|
||||
{
|
||||
m_main_nmi_enabled = ~(data & 1);
|
||||
@ -367,31 +398,46 @@ void espial_state::sound_nmi_mask_w(uint8_t data)
|
||||
m_sound_nmi_enabled = data & 1;
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(espial_state::scanline)
|
||||
void espial_state::porta_w(offs_t offset, uint8_t data, uint8_t mem_mask)
|
||||
{
|
||||
int const scanline = param;
|
||||
if (mem_mask && data != m_sound_nmi_freq)
|
||||
{
|
||||
// sound NMI frequency
|
||||
m_sound_nmi_freq = data;
|
||||
attotime period;
|
||||
|
||||
if (scanline == 240 && m_main_nmi_enabled) // vblank-out irq
|
||||
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
// netwars writes 0xf8 and expects 32 NMIs per frame
|
||||
// espial writes 0xfe and expects 4 NMIs per frame
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
period = attotime::never;
|
||||
break;
|
||||
|
||||
if (scanline == 16) // timer irq, checks soundlatch port then updates some sound related work RAM buffers
|
||||
m_maincpu->set_input_line(0, HOLD_LINE);
|
||||
case 0xfe:
|
||||
period = m_screen->frame_period() / 4;
|
||||
break;
|
||||
|
||||
case 0xf8:
|
||||
period = m_screen->frame_period() / 32;
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("%s: unknown sound NMI frequency %02X", machine().describe_context(), data);
|
||||
return;
|
||||
}
|
||||
|
||||
sound_nmi_timer->adjust(period, 0, period);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INTERRUPT_GEN_MEMBER(espial_state::sound_nmi_gen)
|
||||
{
|
||||
if (m_sound_nmi_enabled)
|
||||
m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
}
|
||||
|
||||
|
||||
void espial_state::master_soundlatch_w(uint8_t data)
|
||||
{
|
||||
m_soundlatch->write(data);
|
||||
m_audiocpu->set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Address maps
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void espial_state::main_map(address_map &map)
|
||||
{
|
||||
@ -401,7 +447,7 @@ void espial_state::main_map(address_map &map)
|
||||
map(0x6082, 0x6082).portr("DSW1");
|
||||
map(0x6083, 0x6083).portr("IN1");
|
||||
map(0x6084, 0x6084).portr("IN2");
|
||||
map(0x6090, 0x6090).r("soundlatch2", FUNC(generic_latch_8_device::read)).w(FUNC(espial_state::master_soundlatch_w));
|
||||
map(0x6090, 0x6090).r(m_soundlatch[1], FUNC(generic_latch_8_device::read)).w(m_soundlatch[0], FUNC(generic_latch_8_device::write));
|
||||
map(0x7000, 0x7000).rw("watchdog", FUNC(watchdog_timer_device::reset_r), FUNC(watchdog_timer_device::reset_w));
|
||||
map(0x7100, 0x7100).w(FUNC(espial_state::master_interrupt_mask_w));
|
||||
map(0x7200, 0x7200).w(FUNC(espial_state::flipscreen_w));
|
||||
@ -427,7 +473,7 @@ void netwars_state::main_map(address_map &map)
|
||||
map(0x6082, 0x6082).portr("DSW1");
|
||||
map(0x6083, 0x6083).portr("IN1");
|
||||
map(0x6084, 0x6084).portr("IN2");
|
||||
map(0x6090, 0x6090).r("soundlatch2", FUNC(generic_latch_8_device::read)).w(FUNC(netwars_state::master_soundlatch_w));
|
||||
map(0x6090, 0x6090).r(m_soundlatch[1], FUNC(generic_latch_8_device::read)).w(m_soundlatch[0], FUNC(generic_latch_8_device::write));
|
||||
map(0x7000, 0x7000).rw("watchdog", FUNC(watchdog_timer_device::reset_r), FUNC(watchdog_timer_device::reset_w));
|
||||
map(0x7100, 0x7100).w(FUNC(netwars_state::master_interrupt_mask_w));
|
||||
map(0x7200, 0x7200).w(FUNC(netwars_state::flipscreen_w));
|
||||
@ -446,16 +492,23 @@ void espial_state::sound_map(address_map &map)
|
||||
map(0x0000, 0x1fff).rom();
|
||||
map(0x2000, 0x23ff).ram();
|
||||
map(0x4000, 0x4000).w(FUNC(espial_state::sound_nmi_mask_w));
|
||||
map(0x6000, 0x6000).r(m_soundlatch, FUNC(generic_latch_8_device::read)).w("soundlatch2", FUNC(generic_latch_8_device::write));
|
||||
map(0x6000, 0x6000).r(m_soundlatch[0], FUNC(generic_latch_8_device::read)).w(m_soundlatch[1], FUNC(generic_latch_8_device::write));
|
||||
}
|
||||
|
||||
void espial_state::sound_io_map(address_map &map)
|
||||
{
|
||||
map.global_mask(0xff);
|
||||
map(0x00, 0x01).w("aysnd", FUNC(ay8910_device::address_data_w));
|
||||
map(0x00, 0x01).w(m_aysnd, FUNC(ay8910_device::address_data_w));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Input ports
|
||||
*
|
||||
*************************************/
|
||||
|
||||
// verified from Z80 code
|
||||
static INPUT_PORTS_START( espial )
|
||||
PORT_START("IN0")
|
||||
@ -580,6 +633,13 @@ static INPUT_PORTS_START( netwars )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* GFX layouts
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static const gfx_layout charlayout =
|
||||
{
|
||||
8,8,
|
||||
@ -610,29 +670,35 @@ GFXDECODE_END
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Machine configs
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void espial_state::espial(machine_config &config)
|
||||
{
|
||||
// basic machine hardware
|
||||
Z80(config, m_maincpu, 3'072'000); // 3.072 MHz
|
||||
Z80(config, m_maincpu, 12_MHz_XTAL / 4);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &espial_state::main_map);
|
||||
TIMER(config, "scantimer").configure_scanline(FUNC(espial_state::scanline), "screen", 0, 1);
|
||||
|
||||
Z80(config, m_audiocpu, 3'072'000); // 2 MHz??????
|
||||
Z80(config, m_audiocpu, 12_MHz_XTAL / 4);
|
||||
m_audiocpu->set_addrmap(AS_PROGRAM, &espial_state::sound_map);
|
||||
m_audiocpu->set_addrmap(AS_IO, &espial_state::sound_io_map);
|
||||
m_audiocpu->set_periodic_int(FUNC(espial_state::sound_nmi_gen), attotime::from_hz(4 * 60));
|
||||
|
||||
config.set_maximum_quantum(attotime::from_hz(600));
|
||||
|
||||
WATCHDOG_TIMER(config, "watchdog");
|
||||
|
||||
// video hardware
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(60);
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
|
||||
screen.set_size(32*8, 32*8);
|
||||
screen.set_visarea(0*8, 32*8-1, 2*8, 30*8-1);
|
||||
screen.set_screen_update(FUNC(espial_state::screen_update));
|
||||
screen.set_palette(m_palette);
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_refresh_hz(59);
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
|
||||
m_screen->set_size(32*8, 32*8);
|
||||
m_screen->set_visarea(0*8, 32*8-1, 2*8, 30*8-1);
|
||||
m_screen->set_screen_update(FUNC(espial_state::screen_update));
|
||||
m_screen->set_palette(m_palette);
|
||||
m_screen->screen_vblank().set(FUNC(espial_state::vblank));
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_espial);
|
||||
PALETTE(config, m_palette, FUNC(espial_state::palette), 256);
|
||||
@ -640,10 +706,14 @@ void espial_state::espial(machine_config &config)
|
||||
// sound hardware
|
||||
SPEAKER(config, "mono").front_center();
|
||||
|
||||
GENERIC_LATCH_8(config, m_soundlatch);
|
||||
GENERIC_LATCH_8(config, "soundlatch2");
|
||||
GENERIC_LATCH_8(config, m_soundlatch[0]);
|
||||
m_soundlatch[0]->data_pending_callback().set_inputline(m_audiocpu, 0);
|
||||
|
||||
AY8910(config, "aysnd", 1'500'000).add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
GENERIC_LATCH_8(config, m_soundlatch[1]);
|
||||
|
||||
AY8910(config, m_aysnd, 12_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
m_aysnd->port_a_write_callback().set(FUNC(espial_state::porta_w));
|
||||
m_aysnd->port_b_write_callback().set_nop(); // spams 0x00
|
||||
}
|
||||
|
||||
void netwars_state::netwars(machine_config &config)
|
||||
@ -652,18 +722,15 @@ void netwars_state::netwars(machine_config &config)
|
||||
|
||||
// basic machine hardware
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &netwars_state::main_map);
|
||||
|
||||
// video hardware
|
||||
subdevice<screen_device>("screen")->set_size(32*8, 64*8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Game driver(s)
|
||||
|
||||
***************************************************************************/
|
||||
/*************************************
|
||||
*
|
||||
* ROM definitions
|
||||
*
|
||||
*************************************/
|
||||
|
||||
ROM_START( espial )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 )
|
||||
@ -786,6 +853,13 @@ ROM_END
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Game driver(s)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
GAME( 1983, espial, 0, espial, espial, espial_state, empty_init, ROT0, "Orca / Thunderbolt", "Espial (Europe)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1983, espialj, espial, espial, espial, espial_state, empty_init, ROT0, "Orca / Thunderbolt", "Espial (Japan)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1983, espialn, espial, espial, espial, espial_state, empty_init, ROT0, "Orca / Thunderbolt", "Espial (Nova Apparate license)", MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -28,17 +28,17 @@
|
||||
|
||||
DEFINE_DEVICE_TYPE(ORCA_OVG_40C, orca_ovg_40c_device, "orca_ovg_40c", "Orca OVG 40c video PCB")
|
||||
|
||||
orca_ovg_40c_device::orca_ovg_40c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, ORCA_OVG_40C, tag, owner, clock),
|
||||
device_gfx_interface(mconfig, *this, nullptr, "palette"),
|
||||
device_video_interface(mconfig, *this),
|
||||
m_videoram(*this, "videoram"),
|
||||
m_videoram_2(*this,"videoram_2"),
|
||||
m_attributeram(*this, "attributeram"),
|
||||
m_spriteram(*this, "spriteram"),
|
||||
m_bulletsram(*this, "bulletsram"),
|
||||
m_percuss_hardware(false),
|
||||
m_flip_screen(false)
|
||||
orca_ovg_40c_device::orca_ovg_40c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, ORCA_OVG_40C, tag, owner, clock),
|
||||
device_gfx_interface(mconfig, *this, nullptr, "palette"),
|
||||
device_video_interface(mconfig, *this),
|
||||
m_videoram(*this, "videoram"),
|
||||
m_videoram_2(*this,"videoram_2"),
|
||||
m_attributeram(*this, "attributeram"),
|
||||
m_spriteram(*this, "spriteram"),
|
||||
m_bulletsram(*this, "bulletsram"),
|
||||
m_percuss_hardware(false),
|
||||
m_flip_screen(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -700,7 +700,7 @@ ROM_START( dogfightp ) // all 2732
|
||||
ROM_LOAD( "10.7p", 0x1800, 0x1000, CRC(2cb51793) SHA1(d90177ef28730774202a04a0846281537a1883df) )
|
||||
|
||||
ROM_REGION( 0x0040, "videopcb:proms", 0 ) // on ORCA OVG-40c sub board
|
||||
ROM_LOAD( "blue.2a.82s123", 0x0000, 0x0020, CRC(aa839a24) SHA1(9b8217e1c257d24e873888fd083c099fc93c7878) ) //doesn't match parent
|
||||
ROM_LOAD( "blue.2a.82s123", 0x0000, 0x0020, CRC(aa839a24) SHA1(9b8217e1c257d24e873888fd083c099fc93c7878) ) // doesn't match parent
|
||||
ROM_LOAD( "pink.2b.82s123", 0x0020, 0x0020, CRC(596ae457) SHA1(1c1a3130d88c5fd5c66ce9f91d97a09c0a0b535f) )
|
||||
ROM_END
|
||||
|
||||
|
@ -117,11 +117,12 @@ public:
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_audiocpu(*this, "audiocpu"),
|
||||
m_soundlatch(*this, "soundlatch%u", 0)
|
||||
m_screen(*this, "screen"),
|
||||
m_soundlatch(*this, "soundlatch%u", 0),
|
||||
m_aysnd(*this, "aysnd")
|
||||
{ }
|
||||
|
||||
void zodiack(machine_config &config);
|
||||
void dogfight(machine_config &config);
|
||||
void percuss(machine_config &config);
|
||||
|
||||
protected:
|
||||
@ -133,18 +134,23 @@ private:
|
||||
void irq_mask_w(uint8_t data);
|
||||
void sound_nmi_enable_w(uint8_t data);
|
||||
void control_w(uint8_t data);
|
||||
void porta_w(offs_t offset, uint8_t data, uint8_t mem_mask);
|
||||
|
||||
// devices
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_device<z80_device> m_audiocpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device_array<generic_latch_8_device, 2> m_soundlatch;
|
||||
required_device<ay8910_device> m_aysnd;
|
||||
|
||||
// state
|
||||
uint8_t m_main_nmi_enabled = 0;
|
||||
uint8_t m_main_irq_enabled = 0;
|
||||
uint8_t m_sound_nmi_enabled = 0;
|
||||
uint8_t m_sound_nmi_freq = 0;
|
||||
emu_timer *sound_nmi_timer;
|
||||
|
||||
INTERRUPT_GEN_MEMBER(sound_nmi_gen);
|
||||
TIMER_CALLBACK_MEMBER(sound_nmi_gen);
|
||||
void vblank(int state);
|
||||
|
||||
void io_map(address_map &map) ATTR_COLD;
|
||||
@ -152,6 +158,39 @@ private:
|
||||
void sound_map(address_map &map) ATTR_COLD;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Machine initialization
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void zodiack_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_main_nmi_enabled));
|
||||
save_item(NAME(m_main_irq_enabled));
|
||||
save_item(NAME(m_sound_nmi_enabled));
|
||||
save_item(NAME(m_sound_nmi_freq));
|
||||
|
||||
sound_nmi_timer = timer_alloc(FUNC(zodiack_state::sound_nmi_gen), this);
|
||||
}
|
||||
|
||||
void zodiack_state::machine_reset()
|
||||
{
|
||||
m_main_nmi_enabled = 0;
|
||||
m_main_irq_enabled = 0;
|
||||
m_sound_nmi_enabled = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Memory handlers
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void zodiack_state::nmi_mask_w(uint8_t data)
|
||||
{
|
||||
m_main_nmi_enabled = (data & 1) ^ 1;
|
||||
@ -176,7 +215,7 @@ void zodiack_state::vblank(int state)
|
||||
m_maincpu->set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
|
||||
INTERRUPT_GEN_MEMBER(zodiack_state::sound_nmi_gen)
|
||||
TIMER_CALLBACK_MEMBER(zodiack_state::sound_nmi_gen)
|
||||
{
|
||||
if (m_sound_nmi_enabled)
|
||||
m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
@ -190,6 +229,46 @@ void zodiack_state::control_w(uint8_t data)
|
||||
// Bit 2 - ????
|
||||
}
|
||||
|
||||
void zodiack_state::porta_w(offs_t offset, uint8_t data, uint8_t mem_mask)
|
||||
{
|
||||
if (mem_mask && data != m_sound_nmi_freq)
|
||||
{
|
||||
// sound NMI frequency
|
||||
m_sound_nmi_freq = data;
|
||||
attotime period;
|
||||
|
||||
// dogfight writes 0xc0 and expects 4 NMIs per frame
|
||||
// others write 0xe0 and expect 8 NMIs per frame
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
period = attotime::never;
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
period = m_screen->frame_period() / 4;
|
||||
break;
|
||||
|
||||
case 0xe0:
|
||||
period = m_screen->frame_period() / 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("%s: unknown sound NMI frequency %02X", machine().describe_context(), data);
|
||||
return;
|
||||
}
|
||||
|
||||
sound_nmi_timer->adjust(period, 0, period);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Address maps
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void zodiack_state::main_map(address_map &map)
|
||||
{
|
||||
@ -224,11 +303,17 @@ void zodiack_state::sound_map(address_map &map)
|
||||
void zodiack_state::io_map(address_map &map)
|
||||
{
|
||||
map.global_mask(0xff);
|
||||
map(0x00, 0x01).w("aysnd", FUNC(ay8910_device::address_data_w));
|
||||
map(0x00, 0x01).w(m_aysnd, FUNC(ay8910_device::address_data_w));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Input ports
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static INPUT_PORTS_START( zodiack )
|
||||
PORT_START("DSW0") // never read in this game
|
||||
PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
@ -540,39 +625,30 @@ static INPUT_PORTS_START( bounty )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY
|
||||
INPUT_PORTS_END
|
||||
|
||||
void zodiack_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_main_nmi_enabled));
|
||||
save_item(NAME(m_main_irq_enabled));
|
||||
save_item(NAME(m_sound_nmi_enabled));
|
||||
}
|
||||
|
||||
void zodiack_state::machine_reset()
|
||||
{
|
||||
m_main_nmi_enabled = 0;
|
||||
m_main_irq_enabled = 0;
|
||||
m_sound_nmi_enabled = 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Machine configs
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void zodiack_state::zodiack(machine_config &config)
|
||||
{
|
||||
// basic machine hardware
|
||||
Z80(config, m_maincpu, XTAL(18'432'000) / 6);
|
||||
Z80(config, m_maincpu, 18.432_MHz_XTAL / 6);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &zodiack_state::main_map);
|
||||
|
||||
Z80(config, m_audiocpu, XTAL(18'432'000) / 6);
|
||||
Z80(config, m_audiocpu, 18.432_MHz_XTAL / 6);
|
||||
m_audiocpu->set_addrmap(AS_PROGRAM, &zodiack_state::sound_map);
|
||||
m_audiocpu->set_addrmap(AS_IO, &zodiack_state::io_map);
|
||||
m_audiocpu->set_periodic_int(FUNC(zodiack_state::sound_nmi_gen), attotime::from_hz(8 * 60)); // sound tempo - unknown source, timing is guessed
|
||||
|
||||
config.set_maximum_quantum(attotime::from_hz(600));
|
||||
|
||||
WATCHDOG_TIMER(config, "watchdog");
|
||||
|
||||
// video hardware
|
||||
SCREEN(config, "screen", SCREEN_TYPE_RASTER).screen_vblank().set(FUNC(zodiack_state::vblank));
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER).screen_vblank().set(FUNC(zodiack_state::vblank));
|
||||
|
||||
orca_ovg_40c_device &videopcb(ORCA_OVG_40C(config, "videopcb", 0));
|
||||
videopcb.set_screen("screen");
|
||||
@ -585,7 +661,8 @@ void zodiack_state::zodiack(machine_config &config)
|
||||
|
||||
GENERIC_LATCH_8(config, m_soundlatch[1]);
|
||||
|
||||
AY8910(config, "aysnd", XTAL(18'432'000) / 12).add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
AY8910(config, m_aysnd, 18.432_MHz_XTAL / 12).add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
m_aysnd->port_a_write_callback().set(FUNC(zodiack_state::porta_w));
|
||||
}
|
||||
|
||||
void zodiack_state::percuss(machine_config &config)
|
||||
@ -596,19 +673,13 @@ void zodiack_state::percuss(machine_config &config)
|
||||
videopcb.set_percuss_hardware(true);
|
||||
}
|
||||
|
||||
void zodiack_state::dogfight(machine_config &config)
|
||||
{
|
||||
zodiack(config);
|
||||
|
||||
m_audiocpu->set_periodic_int(FUNC(zodiack_state::sound_nmi_gen), attotime::from_hz(4 * 60)); // 4 interrupts per frame
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Game driver(s)
|
||||
|
||||
***************************************************************************/
|
||||
/*************************************
|
||||
*
|
||||
* ROM definitions
|
||||
*
|
||||
*************************************/
|
||||
|
||||
ROM_START( zodiack )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 )
|
||||
@ -735,9 +806,16 @@ ROM_END
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
GAME( 1983, zodiack, 0, zodiack, zodiack, zodiack_state, empty_init, ROT270, "Orca (Esco Trading Co., Inc. license)", "Zodiack", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) // bullet color needs to be verified
|
||||
GAME( 1983, dogfight, 0, dogfight, dogfight, zodiack_state, empty_init, ROT270, "Orca / Thunderbolt", "Dog Fight (Thunderbolt)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, moguchan, 0, percuss, moguchan, zodiack_state, empty_init, ROT270, "Orca (Eastern Commerce Inc. license)", "Mogu Chan (bootleg?)", MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) // license copyright taken from ROM string at $0b5c
|
||||
GAME( 1981, percuss, 0, percuss, percuss, zodiack_state, empty_init, ROT270, "Orca", "The Percussor", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, bounty, 0, percuss, bounty, zodiack_state, empty_init, ROT180, "Orca", "The Bounty (set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, bounty2, bounty, percuss, bounty, zodiack_state, empty_init, ROT180, "Orca", "The Bounty (set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // seems to use a different memory map
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Game driver(s)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
GAME( 1983, zodiack, 0, zodiack, zodiack, zodiack_state, empty_init, ROT270, "Orca (Esco Trading Co., Inc. license)", "Zodiack", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) // bullet color needs to be verified
|
||||
GAME( 1983, dogfight, 0, zodiack, dogfight, zodiack_state, empty_init, ROT270, "Orca / Thunderbolt", "Dog Fight (Thunderbolt)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, moguchan, 0, percuss, moguchan, zodiack_state, empty_init, ROT270, "Orca (Eastern Commerce Inc. license)", "Mogu Chan (bootleg?)", MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) // license copyright taken from ROM string at $0b5c
|
||||
GAME( 1981, percuss, 0, percuss, percuss, zodiack_state, empty_init, ROT270, "Orca", "The Percussor", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, bounty, 0, percuss, bounty, zodiack_state, empty_init, ROT180, "Orca", "The Bounty (set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, bounty2, bounty, percuss, bounty, zodiack_state, empty_init, ROT180, "Orca", "The Bounty (set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // seems to use a different memory map
|
||||
|
Loading…
Reference in New Issue
Block a user