New games added as GAME_NOT_WORKING:

Pirate Ship [Phil Bennett, R. Belmont, (dump credits?)]
This commit is contained in:
arbee 2017-04-01 16:53:24 -04:00
parent 5769f31c7d
commit 9c963f9b53
8 changed files with 1379 additions and 2 deletions

View File

@ -2323,6 +2323,7 @@ files {
MAME_DIR .. "src/mame/drivers/pingpong.cpp",
MAME_DIR .. "src/mame/includes/pingpong.h",
MAME_DIR .. "src/mame/video/pingpong.cpp",
MAME_DIR .. "src/mame/drivers/piratesh.cpp",
MAME_DIR .. "src/mame/drivers/plygonet.cpp",
MAME_DIR .. "src/mame/includes/plygonet.h",
MAME_DIR .. "src/mame/video/plygonet.cpp",
@ -2441,6 +2442,8 @@ files {
MAME_DIR .. "src/mame/video/k052109.h",
MAME_DIR .. "src/mame/video/k053250.cpp",
MAME_DIR .. "src/mame/video/k053250.h",
MAME_DIR .. "src/mame/video/k053250_ps.cpp",
MAME_DIR .. "src/mame/video/k053250_ps.h",
MAME_DIR .. "src/mame/video/k053251.cpp",
MAME_DIR .. "src/mame/video/k053251.h",
MAME_DIR .. "src/mame/video/k054156_k054157_k056832.cpp",

View File

@ -170,7 +170,7 @@
#define PALETTE_FORMAT_XGRB raw_to_rgb_converter(4, &raw_to_rgb_converter::standard_rgb_decoder<8,8,8, 8,16,0>)
#define PALETTE_FORMAT_RGBX raw_to_rgb_converter(4, &raw_to_rgb_converter::standard_rgb_decoder<8,8,8, 24,16,8>)
#define PALETTE_FORMAT_GRBX raw_to_rgb_converter(4, &raw_to_rgb_converter::standard_rgb_decoder<8,8,8, 16,24,8>)
#define PALETTE_FORMAT_BGRX raw_to_rgb_converter(4, &raw_to_rgb_converter::standard_rgb_decoder<8,8,8, 8,16,24>)
//**************************************************************************

View File

@ -0,0 +1,679 @@
// license:BSD-3-Clause
/**************************************************************************
Pirate Ship
PWB(A)354460B
MC68HC00FN16
054539 - 8-Channel ADPCM sound generator. Clock input 18.432MHz. Clock outputs 18.432/4 & 18.432/8
053250 - LVC road generator
053246A - Sprite generator
055673 - Sprite generator
055555 - Mixer/Priority encoder
056832 - Tilemap generator
054156 - Tilemap generator
053252 - CRTC
053250 config:
SELC (69) GND
SEL1 (83) GND
SEL0 (82) GND
MODE (68) GND
TODO: Music stops if a coin is inserted. MAME or BTNAB?
**************************************************************************/
#include "emu.h"
#include "speaker.h"
#include "video/k053250_ps.h"
#include "machine/nvram.h"
#include "cpu/m68000/m68000.h"
#include "sound/k054539.h"
#include "includes/konamigx.h" // TODO: WHY?
#include "video/konami_helper.h"
#include "machine/ticket.h"
#include "machine/gen_latch.h"
#include "machine/k053252.h"
#include "video/k055555.h"
#include "video/k054000.h"
#include "video/k053246_k053247_k055673.h"
class piratesh_state : public driver_device
{
public:
piratesh_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this,"maincpu"),
m_k053250(*this, "k053250"),
m_k053252(*this, "k053252"),
m_k056832(*this, "k056832"),
m_k055673(*this, "k055673"),
m_k055555(*this, "k055555"),
// m_k053246(*this, "k053246"),
m_k054539(*this, "k054539"),
m_spriteram(*this,"spriteram")
{ }
required_device<cpu_device> m_maincpu;
required_device<k053250ps_device> m_k053250;
required_device<k053252_device> m_k053252;
required_device<k056832_device> m_k056832;
required_device<k055673_device> m_k055673;
required_device<k055555_device> m_k055555;
required_device<k054539_device> m_k054539;
// required_device<k053247_device> m_k053246;
optional_shared_ptr<uint16_t> m_spriteram;
int m_layer_colorbase[6];
int m_sprite_colorbase;
int m_lvc_colorbase;
uint8_t m_int_enable;
uint8_t m_int_status;
uint8_t m_sound_ctrl;
uint8_t m_sound_nmi_clk;
uint16_t m_control;
void update_interrupts();
DECLARE_READ16_MEMBER(K056832_rom_r);
DECLARE_WRITE16_MEMBER(control1_w);
DECLARE_WRITE16_MEMBER(control2_w);
DECLARE_WRITE16_MEMBER(control3_w);
DECLARE_WRITE16_MEMBER(irq_ack_w);
DECLARE_READ16_MEMBER(k053247_scattered_word_r);
DECLARE_WRITE16_MEMBER(k053247_scattered_word_w);
DECLARE_READ16_MEMBER(k053247_martchmp_word_r);
DECLARE_WRITE16_MEMBER(k053247_martchmp_word_w);
DECLARE_CUSTOM_INPUT_MEMBER(helm_r);
DECLARE_CUSTOM_INPUT_MEMBER(battery_r);
DECLARE_MACHINE_START(piratesh);
DECLARE_MACHINE_RESET(piratesh);
DECLARE_VIDEO_START(piratesh);
uint32_t screen_update_piratesh(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(k054539_nmi_gen);
TIMER_DEVICE_CALLBACK_MEMBER(piratesh_interrupt);
K056832_CB_MEMBER(piratesh_tile_callback);
K055673_CB_MEMBER(piratesh_sprite_callback);
};
void piratesh_state::update_interrupts()
{
m_maincpu->set_input_line(M68K_IRQ_2, m_int_status & 2 ? ASSERT_LINE : CLEAR_LINE); // INT 1
m_maincpu->set_input_line(M68K_IRQ_4, m_int_status & 1 ? ASSERT_LINE : CLEAR_LINE);
m_maincpu->set_input_line(M68K_IRQ_5, m_int_status & 4 ? ASSERT_LINE : CLEAR_LINE);
}
/*
Priority issues:
1. On title screen, stars should be behind the helm
2. The Konami logo is a square transition
3.
*/
K056832_CB_MEMBER(piratesh_state::piratesh_tile_callback)
{
// Layer
// Code
// Color
// Flags
// if (*color != 0)
// printf("%x %x %x\n", layer, *code, *color >> 2);
*color = (m_layer_colorbase[layer] << 4) + ((*color >> 2));// & 0x0f);
}
K055673_CB_MEMBER(piratesh_state::piratesh_sprite_callback)
{
int c = *color;
*color = (c & 0x001f);
//int pri = (c >> 5) & 7;
// .... .... ...x xxxx - Color
// .... .... xxx. .... - Priority?
// .... ..x. .... .... - ?
// ..x. .... .... .... - ?
#if 0
int layerpri[4];
static const int pris[4] = { K55_PRIINP_0, K55_PRIINP_3, K55_PRIINP_6, K55_PRIINP_7 };
for (uint32_t i = 0; i < 4; i++)
{
layerpri[i] = m_k055555->K055555_read_register(pris[i]);
}
// TODO: THIS IS ALL WRONG
if (pri <= layerpri[0])
*priority_mask = 0;
else if (pri <= layerpri[1])
*priority_mask = 0xf0;
else if (pri <= layerpri[2])
*priority_mask = 0xf0|0xcc;
else
*priority_mask = 0xf0|0xcc|0xaa;
#endif
*priority_mask = 0;
// 0 - Sprites over everything
// f0 -
// f0 cc -
// f0 cc aa -
// 1111 0000
// 1100 1100
// 1010 1010
}
VIDEO_START_MEMBER(piratesh_state, piratesh)
{
// TODO: These come from the 055555
m_layer_colorbase[0] = 0;
m_layer_colorbase[1] = 2;
m_layer_colorbase[2] = 4;
m_layer_colorbase[3] = 6;
m_sprite_colorbase = 1;
m_lvc_colorbase = 3;
#if 0
konamigx_mixer_init(*m_screen, 0);
m_k056832->set_layer_offs(0, -2+2-1, 0-1);
m_k056832->set_layer_offs(1, 0+2, 0);
m_k056832->set_layer_offs(2, 2+2, 0);
m_k056832->set_layer_offs(3, 3+2, 0);
#endif
}
uint32_t piratesh_state::screen_update_piratesh(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0, cliprect);
#if 1
int layers[4], layerpri[4];
static const int pris[4] = { K55_PRIINP_0, K55_PRIINP_3, K55_PRIINP_6, K55_PRIINP_7 };
static const int enables[4] = { K55_INP_VRAM_A, K55_INP_VRAM_B, K55_INP_VRAM_C, K55_INP_VRAM_D };
for (uint32_t i = 0; i < 4; i++)
{
layers[i] = i;
layerpri[i] = m_k055555->K055555_read_register(pris[i]);
}
konami_sortlayers4(layers, layerpri);
screen.priority().fill(0, cliprect);
const uint32_t input_enables = m_k055555->K055555_read_register(K55_INPUT_ENABLES);
// TODO: FIX COLORBASES
if (input_enables & K55_INP_SUB3)
m_k053250->draw(bitmap, cliprect, 0x20, 0, screen.priority(), 2);
for (uint32_t i = 0; i < 4; i++)
{
if (input_enables & enables[layers[i]])
{
m_k056832->tilemap_draw(screen, bitmap, cliprect, layers[i], 0, 1 << i);
}
}
if (input_enables & K55_INP_SUB2)
m_k055673->k053247_sprites_draw(bitmap, cliprect);
#if 0
#define K55_INP_VRAM_A 0x01
#define K55_INP_VRAM_B 0x02
#define K55_INP_VRAM_C 0x04
#define K55_INP_VRAM_D 0x08
#define K55_INP_OBJ 0x10
#define K55_INP_SUB1 0x20
#define K55_INP_SUB2 0x40
#define K55_INP_SUB3 0x80
#endif
//055555: 4 to reg 7 (A PRI 0)
//055555: 0 to reg 8 (A PRI 1)
//055555: 0 to reg 9 (A COLPRI)
//055555: 6 to reg a (B PRI 0)
//055555: 0 to reg b (B PRI 1)
//055555: 0 to reg c (B COLPRI)
//055555: 16 to reg d (C PRI)
//055555: 18 to reg e (D PRI)
//055555: 0 to reg 11 (SUB2 PRI)
//055555: 0 to reg 12 (SUB3 PRI)
//055555: 0 to reg 17 (A PAL)
//055555: 2 to reg 18 (B PAL)
//055555: 4 to reg 19 (C PAL)
//055555: 6 to reg 1a (D PAL)
//055555: 3 to reg 1d (SUB2 PAL)
//055555: 1 to reg 1e (SUB3 PAL)
#else
// LAYER, FLAGS, PRIORITY
m_k056832->tilemap_draw(screen, bitmap, cliprect, 3, K056832_DRAW_FLAG_MIRROR, 1);
m_k056832->tilemap_draw(screen, bitmap, cliprect, 2, K056832_DRAW_FLAG_MIRROR, 2);
// TODO: Fix priority
m_k053250->draw(bitmap, cliprect, 0x20, 0, screen.priority(), 8);
m_k055673->k053247_sprites_draw(bitmap, cliprect);
m_k056832->tilemap_draw(screen, bitmap, cliprect, 1, K056832_DRAW_FLAG_MIRROR, 4);
m_k056832->tilemap_draw(screen, bitmap, cliprect, 0, K056832_DRAW_FLAG_MIRROR, 0);
#endif
return 0;
}
/**********************************************************************************/
/* IRQ controllers */
TIMER_DEVICE_CALLBACK_MEMBER(piratesh_state::piratesh_interrupt)
{
int scanline = param;
// IRQ2 - CCUINT1 (VBL START)
// IRQ4 - Sound
// IRQ5 - CCUINT2 (VBL END)
if (scanline == 240)
{
m_k053250->vblank_w(1);
if (m_int_enable & 2)
{
m_int_status |= 2;
update_interrupts();
}
}
if (scanline == 0)
{
m_k053250->vblank_w(0);
if (m_int_enable & 4)
{
m_int_status |= 4;
update_interrupts();
}
}
}
READ16_MEMBER(piratesh_state::K056832_rom_r)
{
uint16_t offs;
offs = (m_control & 2 ? 0x1000 : 0) + offset;
return m_k056832->piratesh_rom_r(space, offs, mem_mask);
}
WRITE16_MEMBER(piratesh_state::control1_w)
{
// .... ..xx .... .... - Unknown
// .... .x.. .... .... - Unknown - Active during attract, clear during game
// .... x... .... .... - Lamp? (active when waiting to start game)
if (data & ~0x0f00)
printf("CTRL3: %x %x %x\n", offset, data, mem_mask);
}
WRITE16_MEMBER(piratesh_state::control2_w)
{
// .... .... ...x .... - Unknown (always 1?)
// .... .... ..x. .... - Unknown
// .... .... .x.. .... - Counter out
// .... .... x... .... - Counter in
// .... ...x .... .... - 053246A OBJCRBK (Pin 9)
// .... ..x. .... .... - LV related
// .... x... .... .... - INT4/SND control (0=clear 1=enable)
// ...x .... .... .... - INT2/CCUINT1 control (0=clear 1=enable)
// ..x. .... .... .... - INT5/CCUINT2 control (0=clear 1=enable)
// .x.. .... .... .... - Unknown
// x... .... .... .... - Unknown
m_int_enable = (data >> 11) & 7;
m_int_status &= m_int_enable;
update_interrupts();
if (data & ~0xfbf0)
printf("CTRL2: %x %x %x\n", offset, data, mem_mask);
}
WRITE16_MEMBER(piratesh_state::control3_w)
{
// .... .... .... ...x - Watchdog? (051550?)
// .... .... .... ..x. - 056832 ROM bank control
// .... .... ...x .... - Ticket dispenser enable (active high)
// .... .... ..x. .... - Hopper enable (active high)
// .... ...x .... .... - Unknown (always 1?)
if ((data & ~0x0133) || (~data & 0x100))
printf("CTRL1 W: %x %x %x\n", offset, data, mem_mask);
// printf("CTRL 1: %x\n", data & 0x0010);
machine().device<ticket_dispenser_device>("ticket")->motor_w(data & 0x0010 ? 1 : 0);
machine().device<ticket_dispenser_device>("hopper")->motor_w(data & 0x0020 ? 1 : 0);
m_control = data;
}
static ADDRESS_MAP_START( piratesh_map, AS_PROGRAM, 16, piratesh_state )
AM_RANGE(0x000000, 0x07ffff) AM_ROM
AM_RANGE(0x080000, 0x083fff) AM_RAM AM_SHARE("nvram")
AM_RANGE(0x084000, 0x087fff) AM_RAM
AM_RANGE(0x100000, 0x10001f) AM_DEVREADWRITE8("k053252", k053252_device, read, write, 0x00ff) // CRTC
AM_RANGE(0x180000, 0x18003f) AM_DEVWRITE("k056832", k056832_device, word_w) // TILEMAP
AM_RANGE(0x280000, 0x280007) AM_DEVWRITE("k055673", k055673_device, k053246_word_w) // SPRITES
AM_RANGE(0x290000, 0x29000f) AM_DEVREAD("k055673", k055673_device, k055673_rom_word_r) // SPRITES
AM_RANGE(0x290010, 0x29001f) AM_DEVWRITE("k055673", k055673_device, k055673_reg_word_w) // SPRITES
AM_RANGE(0x2a0000, 0x2a0fff) AM_DEVREADWRITE("k055673", k055673_device, k053247_word_r, k053247_word_w) // SPRITES
AM_RANGE(0x2a1000, 0x2a3fff) AM_WRITENOP
AM_RANGE(0x2b0000, 0x2b000f) AM_DEVREADWRITE("k053250", k053250ps_device, reg_r, reg_w) // LVC
AM_RANGE(0x300000, 0x3000ff) AM_DEVWRITE("k055555", k055555_device, K055555_word_w)
AM_RANGE(0x380000, 0x381fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x400000, 0x400001) AM_READ_PORT("IN0")
AM_RANGE(0x400002, 0x400003) AM_READ_PORT("IN1")
AM_RANGE(0x400004, 0x400005) AM_READ_PORT("DSW1")
AM_RANGE(0x400006, 0x400007) AM_READ_PORT("DSW2")
AM_RANGE(0x400008, 0x400009) AM_READ_PORT("SPECIAL")
AM_RANGE(0x40000c, 0x40000d) AM_WRITE(control1_w)
AM_RANGE(0x400010, 0x400011) AM_WRITE(control2_w)
AM_RANGE(0x400014, 0x400015) AM_WRITE(control3_w)
AM_RANGE(0x500000, 0x50ffff) AM_READ(K056832_rom_r) // VRAM ROM
AM_RANGE(0x580000, 0x581fff) AM_DEVREAD("k053250", k053250ps_device, rom_r) // LVC ROM access
AM_RANGE(0x600000, 0x6004ff) AM_DEVREADWRITE8("k054539", k054539_device, read, write, 0xff00) // SOUND
AM_RANGE(0x680000, 0x681fff) AM_DEVREADWRITE("k056832", k056832_device, ram_word_r, ram_word_w) // TILEMAP
AM_RANGE(0x700000, 0x703fff) AM_DEVREADWRITE("k053250", k053250ps_device, ram_r, ram_w) // LVC
ADDRESS_MAP_END
WRITE_LINE_MEMBER(piratesh_state::k054539_nmi_gen)
{
static int m_sound_intck = 0; // TODO: KILL ME
// Trigger an interrupt on the rising edge
if (!m_sound_intck && state)
{
if (m_int_enable & 1)
{
m_int_status |= 1;
update_interrupts();
}
}
m_sound_intck = state;
}
CUSTOM_INPUT_MEMBER(piratesh_state::helm_r)
{
// Appears to be a quadrature encoder
uint8_t xa, xb;
uint16_t dx = ioport("HELM")->read();
xa = ((dx + 1) & 7) <= 3;
xb = (dx & 7) <= 3;
return (xb << 1) | xa;
}
CUSTOM_INPUT_MEMBER(piratesh_state::battery_r)
{
// .x MB3790 /ALARM1
// x. MB3790 /ALARM2
return 0x3;
}
/**********************************************************************************/
static INPUT_PORTS_START( piratesh )
PORT_START("IN0")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON3 ) // 7f60 btst $7,$40000
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) // HELM?
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) // HELM?
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("Reset")
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_START )
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME(DEF_STR( Test )) PORT_CODE(KEYCODE_F2)
PORT_START("SPECIAL")
PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER("k053250", k053250ps_device, dmairq_r)
PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // FIXME: NCPU from 053246 (DMA)
PORT_BIT( 0x0c00, IP_ACTIVE_HIGH, IPT_SPECIAL )PORT_CUSTOM_MEMBER(DEVICE_SELF, piratesh_state, battery_r, nullptr)
PORT_START("HELM")
PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(25) PORT_KEYDELTA(1)
PORT_START("IN1")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Service")
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER("ticket", ticket_dispenser_device, line_r)
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER("hopper", ticket_dispenser_device, line_r)
PORT_BIT( 0x1800, IP_ACTIVE_HIGH, IPT_SPECIAL )PORT_CUSTOM_MEMBER(DEVICE_SELF, piratesh_state, helm_r, nullptr)
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("DSW1") // TODO: DIP switches are used for settings when battery failure has occurred
PORT_DIPNAME( 0x0100, 0x0100, "DSW1:0" ) PORT_DIPLOCATION("DSW1:1")
PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0200, 0x0200, "DSW1:1" ) PORT_DIPLOCATION("DSW1:2")
PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0400, 0x0400, "DSW1:2" ) PORT_DIPLOCATION("DSW1:3")
PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0800, 0x0800, "DSW1:3" ) PORT_DIPLOCATION("DSW1:4")
PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x3000, 0x1000, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("DSW1:5,6")
PORT_DIPSETTING( 0x0000, "A" )
PORT_DIPSETTING( 0x1000, "B" )
PORT_DIPSETTING( 0x2000, "C" )
PORT_DIPSETTING( 0x3000, "D" )
PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("DSW1:7")
PORT_DIPSETTING( 0x0000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x4000, DEF_STR( On ) )
PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Free_Play ) ) PORT_DIPLOCATION("DSW1:8")
PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_START("DSW2") // TODO: Finish me
PORT_DIPNAME( 0x0100, 0x0100, "DSW2:0" ) PORT_DIPLOCATION("DSW2:1")
PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0200, 0x0200, "DSW2:1" ) PORT_DIPLOCATION("DSW2:2")
PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0400, 0x0400, "DSW2:2" ) PORT_DIPLOCATION("DSW2:3")
PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0800, 0x0800, "DSW2:3" ) PORT_DIPLOCATION("DSW2:4")
PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x1000, 0x1000, "DSW2:4" ) PORT_DIPLOCATION("DSW2:5")
PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x2000, 0x2000, "DSW2:5" ) PORT_DIPLOCATION("DSW2:6")
PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x4000, 0x4000, "DSW2:6" ) PORT_DIPLOCATION("DSW2:7")
PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x8000, 0x8000, "Redemption Type" ) PORT_DIPLOCATION("DSW2:8")
PORT_DIPSETTING( 0x8000, "Ticket" )
PORT_DIPSETTING( 0x0000, "Capsule" )
INPUT_PORTS_END
/**********************************************************************************/
MACHINE_START_MEMBER(piratesh_state, piratesh)
{
#if 0
m_sound_ctrl = 2;
m_mw_irq_control = 0;
/* konamigx_mixer uses this, so better initialize it */
m_gx_wrport1_0 = 0;
save_item(NAME(m_mw_irq_control));
save_item(NAME(m_sound_ctrl));
save_item(NAME(m_sound_nmi_clk));
#endif
}
MACHINE_RESET_MEMBER(piratesh_state,piratesh)
{
m_int_status = 0;
int i;
// soften chorus(chip 0 channel 0-3), boost voice(chip 0 channel 4-7)
for (i=0; i<=7; i++)
{
// m_k054539->set_gain(i, 0.5);
}
// // soften percussions(chip 1 channel 0-7)
// for (i=0; i<=7; i++) m_k054539_2->set_gain(i, 0.5);
}
static MACHINE_CONFIG_START( piratesh, piratesh_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", M68000, XTAL_32MHz/2)
MCFG_CPU_PROGRAM_MAP(piratesh_map)
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", piratesh_state, piratesh_interrupt, "screen", 0, 1)
MCFG_NVRAM_ADD_0FILL("nvram")
MCFG_DEVICE_ADD("k053252", K053252, XTAL_32MHz/4)
MCFG_K053252_OFFSETS(40, 16) // TODO
MCFG_MACHINE_START_OVERRIDE(piratesh_state, piratesh)
MCFG_MACHINE_RESET_OVERRIDE(piratesh_state, piratesh)
MCFG_TICKET_DISPENSER_ADD("ticket", attotime::from_msec(200), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_HIGH)
MCFG_TICKET_DISPENSER_ADD("hopper", attotime::from_msec(200), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_HIGH)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK)
// MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_RAW_PARAMS(6000000, 288+16+32+48, 0, 287, 224+16+8+16, 0, 223) // TODO
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(600))
MCFG_SCREEN_SIZE(64*8, 32*8)
MCFG_SCREEN_VISIBLE_AREA(24, 24+288-1, 16, 16+224-1)
MCFG_SCREEN_UPDATE_DRIVER(piratesh_state, screen_update_piratesh)
MCFG_PALETTE_ADD("palette", 2048)
MCFG_PALETTE_FORMAT(BGRX)
MCFG_PALETTE_ENABLE_SHADOWS()
MCFG_PALETTE_ENABLE_HILIGHTS()
MCFG_DEVICE_ADD("k056832", K056832, 0)
MCFG_K056832_CB(piratesh_state, piratesh_tile_callback)
MCFG_K056832_CONFIG("gfx1", K056832_BPP_4PIRATESH, 1, 0, "none")
MCFG_K056832_PALETTE("palette")
MCFG_K055555_ADD("k055555")
MCFG_K053250PS_ADD("k053250", "palette", "screen", -16, 0)
MCFG_DEVICE_ADD("k055673", K055673, 0)
MCFG_K055673_CB(piratesh_state, piratesh_sprite_callback)
MCFG_K055673_CONFIG("gfx2", K055673_LAYOUT_PS, -60, 24)
MCFG_K055673_PALETTE("palette")
// ????
//MCFG_DEVICE_ADD("k053246", K053246, 0)
//MCFG_K053246_CB(moo_state, sprite_callback)
//MCFG_K053246_CONFIG("gfx2", NORMAL_PLANE_ORDER, -48+1, 23)
//MCFG_K053246_PALETTE("palette")
MCFG_DEVICE_ADD("k054338", K054338, 0)
MCFG_K054338_ALPHAINV(1)
MCFG_K054338_MIXER("k055555")
MCFG_VIDEO_START_OVERRIDE(piratesh_state, piratesh)
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_DEVICE_ADD("k054539", K054539, XTAL_18_432MHz)
MCFG_K054539_TIMER_HANDLER(WRITELINE(piratesh_state, k054539_nmi_gen))
MCFG_SOUND_ROUTE(0, "lspeaker", 0.2)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.2)
MACHINE_CONFIG_END
ROM_START( piratesh )
ROM_REGION( 0x80000, "maincpu", 0 )
ROM_LOAD16_WORD_SWAP( "360ua-c04.4p", 0x000000, 0x80000, CRC(6d69dd90) SHA1(ccbdbfea406d9cbc3f242211290ba82ccbbe3795) )
/* tiles */
ROM_REGION( 0x80000, "gfx1", ROMREGION_ERASE00 ) // 27C4096
ROM_LOAD( "360ua-a01.17g", 0x000000, 0x80000, CRC(e39153f5) SHA1(5da9132a2c24a15b55c3f65c26e2ad0467411a88) )
/* sprites */
ROM_REGION( 0x80000*8, "gfx2", ROMREGION_ERASE00 ) // 27C4096
ROM_LOAD16_BYTE( "360ua-a02.21l", 0x000000, 0x80000, CRC(82207997) SHA1(fe143285a12fab5227e883113d798acad7bf4c97) )
ROM_LOAD16_BYTE( "360ua-a03.23l", 0x000001, 0x80000, CRC(a9e36d51) SHA1(1a8de8d8d2abfee5ac0f0822e203846f7f5f1767) )
/* road generator */
ROM_REGION( 0x080000, "k053250", ROMREGION_ERASE00 ) // 27C040
ROM_LOAD( "360ua-a05.26p", 0x000000, 0x80000, CRC(dab7f439) SHA1(2372612c0b04c77a85ccbadc100cb741b85f0481) )
/* sound data */
ROM_REGION( 0x100000, "k054539", 0 ) // 27C040
ROM_LOAD( "360ua-a06.15t", 0x000000, 0x80000, CRC(6816a493) SHA1(4fc4cfbc164d84bbf8d75ccd78c9f40f3273d852) )
ROM_LOAD( "360ua-a07.17t", 0x080000, 0x80000, CRC(af7127c5) SHA1(b525f3c6b831e3354eba46016d414bedcb3ae8dc) )
// ROM_REGION( 0x80, "eeprom", 0 ) // default eeprom to prevent game booting upside down with error
// ROM_LOAD( "piratesh.nv", 0x0000, 0x080, CRC(28df2269) SHA1(3f071c97662745a199f96964e2e79f795bd5a391) )
ROM_END
/* ROM parent machine inp init */
GAME( 1995, piratesh, 0, piratesh, piratesh, driver_device, 0, ROT90, "Konami", "Pirate Ship (ver UAA)", MACHINE_IMPERFECT_GRAPHICS )

View File

@ -30881,6 +30881,9 @@ genix // (c) 199? NIX
pirates // (c) 1994 NIX
piratesb // bootleg?
@source:piratesh.cpp
piratesh // (c) 1995 Konami
@source:pitagjr.cpp
pitagjr // Pitagorin Junior

View File

@ -960,6 +960,16 @@ void k055673_device::device_start()
12*8*9, 12*8*10, 12*8*11, 12*8*12, 12*8*13, 12*8*14, 12*8*15 },
16*16*6
};
static const gfx_layout spritelayout5 = /* Pirate Ship layout */
{
16,16,
0,
4,
{ 24, 8, 16, 0 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 32, 33, 34, 35, 36, 37, 38, 39 },
{ 0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960 },
16*16*4
};
uint8_t *s1, *s2, *d;
long i;
uint16_t *alt_k055673_rom;
@ -997,6 +1007,11 @@ void k055673_device::device_start()
konami_decode_gfx(*this, gfx_index, (uint8_t *)alt_k055673_rom, total, &spritelayout2, 4);
break;
case K055673_LAYOUT_PS:
total = machine().root_device().memregion(m_memory_region)->bytes() / (16*16/2);
konami_decode_gfx(*this, gfx_index, (uint8_t *)alt_k055673_rom, total, &spritelayout5, 4);
break;
case K055673_LAYOUT_LE2:
total = machine().root_device().memregion(m_memory_region)->bytes() / (16*16);
konami_decode_gfx(*this, gfx_index, (uint8_t *)alt_k055673_rom, total, &spritelayout3, 8);

View File

@ -34,7 +34,7 @@ typedef device_delegate<void (int *code, int *color, int *priority_mask)> k05324
#define K055673_LAYOUT_RNG 4
#define K055673_LAYOUT_LE2 8
#define K055673_LAYOUT_GX6 6
#define K055673_LAYOUT_PS 7
/*
Callback procedures for non-standard shadows:

View File

@ -0,0 +1,597 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
#include "emu.h"
#include "k053250_ps.h"
#include "screen.h"
/*
Registers
0
xxxx xxxx X-Scroll [7:0]
1
xxxx xxxx X-Scroll [15:8]
2
xxxx xxxx Y-Scroll [7:0]
3
xxxx xxxx Y-Scroll [15:8]
4 Control
.... ...x 0:Swap XY 1:Normal
.... ..x. Interrupt related?
.... .x.. 0:Disable 1:Enable source clipping
.... x... Flip X
...x .... Flip Y
xxx. .... Wrap control
5
.... .... Unknown
6
xxxx xxxx ROM access address [7:0]
7
xxxx xxxx ROM access address [15:8]
*/
const device_type K053250PS = device_creator<k053250ps_device>;
k053250ps_device::k053250ps_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, K053250PS, "K053250PS LVC", tag, owner, clock, "k053250ps", __FILE__),
device_gfx_interface(mconfig, *this),
device_video_interface(mconfig, *this),
m_dmairq_cb(*this),
m_rom(*this, DEVICE_SELF)
{
}
void k053250ps_device::static_set_offsets(device_t &device, int offx, int offy)
{
k053250ps_device &dev = downcast<k053250ps_device &>(device);
dev.m_offx = offx;
dev.m_offy = offy;
}
void k053250ps_device::unpack_nibbles()
{
m_unpacked_rom.resize(m_rom.length()*2);
for (int i = 0; i < m_rom.length(); i++)
{
m_unpacked_rom[2*i] = m_rom[i] >> 4;
m_unpacked_rom[2*i+1] = m_rom[i] & 0xf;
}
}
void k053250ps_device::device_start()
{
m_ram.resize(0x6000/2);
m_buffer[0] = &m_ram[0x0000];
m_buffer[1] = &m_ram[0x0800];
// m_buffer[0] = &m_ram[0x2000];
// m_buffer[1] = &m_ram[0x2800];
unpack_nibbles();
save_item(NAME(m_ram));
save_item(NAME(m_regs));
save_item(NAME(m_page));
save_item(NAME(m_dmairq_on));
m_dmairq_cb.resolve_safe();
m_timer_lvcdma = timer_alloc(0);
}
void k053250ps_device::device_reset()
{
m_page = 0;
memset(m_regs, 0, sizeof(m_regs));
m_timer_lvcdma_state = OD_IDLE;
m_timer_lvcdma->adjust(attotime::never);
m_dmairq_on = false;
}
// utility function to render a clipped scanline vertically or horizontally
inline void k053250ps_device::pdraw_scanline32(bitmap_rgb32 &bitmap, const pen_t *pal_base, uint8_t *source,
const rectangle &cliprect, int linepos, int scroll, int zoom,
uint32_t clipmask, uint32_t wrapmask, uint32_t orientation, bitmap_ind8 &priority, uint8_t pri)
{
// a sixteen-bit fixed point resolution should be adequate to our application
#define FIXPOINT_PRECISION 16
#define FIXPOINT_PRECISION_HALF (1<<(FIXPOINT_PRECISION-1))
int end_pixel, flip, dst_min, dst_max, dst_start, dst_length;
uint32_t src_wrapmask;
uint8_t *src_base;
int src_fx, src_fdx;
int pix_data, dst_offset;
uint8_t *pri_base;
uint32_t *dst_base;
int dst_adv;
// flip X and flip Y also switch role when the X Y coordinates are swapped
if (!(orientation & ORIENTATION_SWAP_XY))
{
flip = orientation & ORIENTATION_FLIP_X;
dst_min = cliprect.min_x;
dst_max = cliprect.max_x;
}
else
{
flip = orientation & ORIENTATION_FLIP_Y;
dst_min = cliprect.min_y;
dst_max = cliprect.max_y;
}
if (clipmask)
{
// reject scanlines that are outside of the target bitmap's right(bottom) clip boundary
dst_start = -scroll;
if (dst_start > dst_max) return;
// calculate target length
dst_length = clipmask + 1;
if (zoom) dst_length = (dst_length << 6) / zoom;
// reject scanlines that are outside of the target bitmap's left(top) clip boundary
end_pixel = dst_start + dst_length - 1;
if (end_pixel < dst_min) return;
// clip scanline tail
if ((end_pixel -= dst_max) > 0) dst_length -= end_pixel;
// reject 0-length scanlines
if (dst_length <= 0) return;
// calculate zoom factor
src_fdx = zoom << (FIXPOINT_PRECISION-6);
// clip scanline head
end_pixel = dst_min;
if ((end_pixel -= dst_start) > 0)
{
// chop scanline to the correct length and move target start location to the left(top) clip boundary
dst_length -= end_pixel;
dst_start = dst_min;
// and skip the source for the left(top) clip region
src_fx = end_pixel * src_fdx + FIXPOINT_PRECISION_HALF;
}
else
// the point five bias is to ensure even distribution of stretched or shrinked pixels
src_fx = FIXPOINT_PRECISION_HALF;
// adjust flipped source
if (flip)
{
// start from the target's clipped end if the scanline is flipped
dst_start = dst_max + dst_min - dst_start - (dst_length-1);
// and move source start location to the opposite end
src_fx += (dst_length-1) * src_fdx - 1;
src_fdx = -src_fdx;
}
}
else
{
// draw wrapped scanline at virtual bitmap boundary when source clipping is off
dst_start = dst_min;
dst_length = dst_max - dst_min + 1; // target scanline spans the entire visible area
src_fdx = zoom << (FIXPOINT_PRECISION-6);
// pre-advance source for the clipped region
if (!flip)
src_fx = (scroll + dst_min) * src_fdx + FIXPOINT_PRECISION_HALF;
else
{
src_fx = (scroll + dst_max) * src_fdx + FIXPOINT_PRECISION_HALF-1;
src_fdx = -src_fdx;
}
}
if (!(orientation & ORIENTATION_SWAP_XY))
{
// calculate target increment for horizontal scanlines which is exactly one
dst_adv = 1;
dst_offset = dst_length;
pri_base = &priority.pix8(linepos, dst_start + dst_offset);
dst_base = &bitmap.pix32(linepos, dst_start + dst_length);
}
else
{
// calculate target increment for vertical scanlines which is the bitmap's pitch value
dst_adv = bitmap.rowpixels();
dst_offset= dst_length * dst_adv;
pri_base = &priority.pix8(dst_start, linepos + dst_offset);
dst_base = &bitmap.pix32(dst_start, linepos + dst_offset);
}
// generalized
src_base = source;
// there is no need to wrap source offsets along with source clipping
// so we set all bits of the wrapmask to one
src_wrapmask = (clipmask) ? ~0 : wrapmask;
dst_offset = -dst_offset; // negate target offset in order to terminated draw loop at 0 condition
if (pri)
{
// draw scanline and update priority bitmap
do
{
pix_data = src_base[(src_fx>>FIXPOINT_PRECISION) & src_wrapmask];
src_fx += src_fdx;
if (pix_data)
{
pix_data = pal_base[pix_data];
pri_base[dst_offset] = pri;
dst_base[dst_offset] = pix_data;
}
}
while (dst_offset += dst_adv);
}
else
{
// draw scanline but do not update priority bitmap
do
{
pix_data = src_base[(src_fx>>FIXPOINT_PRECISION) & src_wrapmask];
src_fx += src_fdx;
if (pix_data)
{
dst_base[dst_offset] = pal_base[pix_data];
}
}
while (dst_offset += dst_adv);
}
#undef FIXPOINT_PRECISION
#undef FIXPOINT_PRECISION_HALF
}
void k053250ps_device::draw( bitmap_rgb32 &bitmap, const rectangle &cliprect, int colorbase, int flags, bitmap_ind8 &priority_bitmap, int priority )
{
static int16_t scroll_x;
if (machine().input().code_pressed(KEYCODE_A))
{
scroll_x--;
popmessage("SCROLL: %d\n", scroll_x);
}
else if (machine().input().code_pressed(KEYCODE_S))
{
scroll_x++;
popmessage("SCROLL: %d\n", scroll_x);
}
uint8_t *pix_ptr;
const pen_t *pal_base, *pal_ptr;
uint32_t src_clipmask, src_wrapmask, dst_wrapmask;
int linedata_offs, line_pos, line_start, line_end, scroll_corr;
int color, offset, zoom, scroll, passes, i;
bool wrap500 = false;
uint16_t *line_ram = m_buffer[0]; // pointer to physical line RAM
int map_scrollx = short(m_regs[0] << 8 | m_regs[1]) - m_offx; // signed horizontal scroll value
int map_scrolly = short(m_regs[2] << 8 | m_regs[3]) - m_offy; // signed vertical scroll value
uint8_t ctrl = m_regs[4]; // register four is the main control register
// copy visible boundary values to more accessible locations
int dst_minx = cliprect.min_x;
int dst_maxx = cliprect.max_x;
int dst_miny = cliprect.min_y;
int dst_maxy = cliprect.max_y;
int orientation = 0; // orientation defaults to no swapping and no flipping
int dst_height = 512; // virtual bitmap height defaults to 512 pixels
int linedata_adv = 4; // line info packets are four words(eight bytes) apart
// switch X and Y parameters when the first bit of the control register is cleared
if (!(ctrl & 0x01)) orientation |= ORIENTATION_SWAP_XY;
// invert X parameters when the forth bit of the control register is set
if (ctrl & 0x08) orientation |= ORIENTATION_FLIP_X;
// invert Y parameters when the fifth bit of the control register is set
if (ctrl & 0x10) orientation |= ORIENTATION_FLIP_Y;
//printf("CTRL: %x\n", ctrl);
// 00
// 0x12
// 0x10
switch (ctrl >> 5) // the upper four bits of the control register select source and target dimensions
{
case 0 :
// PirateSH
// Xexex: L6 galaxies
// Metam: L4 forest, L5 arena, L6 tower interior, final boss
// crop source offset between 0 and 255 inclusive,
// and set virtual bitmap height to 256 pixels
src_wrapmask = src_clipmask = 0xff;
dst_height = 0x100;
break;
case 1 :
// Xexex: prologue, L7 nebulae
// the source offset is cropped to 0 and 511 inclusive
src_wrapmask = src_clipmask = 0x1ff;
break;
case 4 :
// Xexex: L1 sky and boss, L3 planet, L5 poly-face, L7 battle ship patches
// Metam: L1 summoning circle, L3 caves, L6 gargoyle towers
// crop source offset between 0 and 255 inclusive,
// and allow source offset to wrap back at 0x500 to -0x300
src_wrapmask = src_clipmask = 0xff;
wrap500 = true;
break;
// case 2 : // Xexex: title
// case 7 : // Xexex: L4 organic stage
default:
// crop source offset between 0 and 1023 inclusive,
// keep other dimensions to their defaults
src_wrapmask = src_clipmask = 0x3ff;
break;
}
// disable source clipping when the third bit of the control register is set
if (ctrl & 0x04)
src_clipmask = 0;
if (!(orientation & ORIENTATION_SWAP_XY)) // normal orientaion with no X Y switching
{
line_start = dst_miny; // the first scanline starts at the minimum Y clip location
line_end = dst_maxy; // the last scanline ends at the maximum Y clip location
scroll_corr = map_scrollx; // concentrate global X scroll
linedata_offs = map_scrolly; // determine where to get info for the first line
if (orientation & ORIENTATION_FLIP_X)
{
scroll_corr = -scroll_corr; // X scroll adjustment should be negated in X flipped scenarioes
}
if (orientation & ORIENTATION_FLIP_Y)
{
linedata_adv = -linedata_adv; // traverse line RAM backward in Y flipped scenarioes
linedata_offs += bitmap.height() - 1; // and get info for the first line from the bottom
}
dst_wrapmask = ~0; // scanlines don't seem to wrap horizontally in normal orientation
passes = 1; // draw scanline in a single pass
}
else // orientaion with X and Y parameters switched
{
line_start = dst_minx; // the first scanline starts at the minimum X clip location
line_end = dst_maxx; // the last scanline ends at the maximum X clip location
scroll_corr = map_scrolly; // concentrate global Y scroll
linedata_offs = map_scrollx; // determine where to get info for the first line
if (orientation & ORIENTATION_FLIP_Y)
{
scroll_corr = 0x100 - scroll_corr; // apply common vertical correction
// Y correction (ref: 1st and 5th boss)
scroll_corr -= 2; // apply unique vertical correction
// X correction (ref: 1st boss, seems to undo non-rotated global X offset)
linedata_offs -= 5; // apply unique horizontal correction
}
if (orientation & ORIENTATION_FLIP_X)
{
linedata_adv = -linedata_adv; // traverse line RAM backward in X flipped scenarioes
linedata_offs += bitmap.width() - 1; // and get info for the first line from the bottom
}
if (src_clipmask)
{
// determine target wrap boundary and draw scanline in two passes if the source is clipped
dst_wrapmask = dst_height - 1;
passes = 2;
}
else
{
// otherwise disable target wraparound and draw scanline in a single pass
dst_wrapmask = ~0;
passes = 1;
}
}
// PJB - HOW IS THIS DETERMINED?
src_clipmask = 0;
linedata_offs *= 4; // each line info packet has four words(eight bytes)
linedata_offs &= 0x7ff; // and it should wrap at the four-kilobyte boundary
linedata_offs += line_start * linedata_adv; // pre-advance line info offset for the clipped region
// load physical palette base
pal_base = palette().pens() + (colorbase << 4) % palette().entries();
//printf("Line Start: %u Line End: %u Advance: %u\n", line_start, line_end, linedata_adv);
// walk the target bitmap within the visible area vertically or horizontally, one line at a time
for (line_pos=line_start; line_pos <= line_end; linedata_offs += linedata_adv, line_pos++)
{
linedata_offs &= 0x7ff; // line info data wraps at the four-kilobyte boundary
color = line_ram[linedata_offs]; // get scanline color code
if (color == 0xffff) continue; // reject scanline if color code equals minus one
offset = line_ram[linedata_offs + 1]; // get first pixel offset in ROM
if (!(color & 0xff) && !offset) continue; // reject scanline if both color and pixel offset are 0
// calculate physical palette location
// there can be thirty-two color codes and each code represents sixteen pens
pal_ptr = pal_base + ((color & 0x1f) << 4);
// calculate physical pixel location
// each offset unit represents 256 pixels and should wrap at ROM boundary for safety
pix_ptr = &m_unpacked_rom[((offset << 8) % m_unpacked_rom.size())];
// get scanline zoom factor
// For example, 0x20 doubles the length, 0x40 maintains a one-to-one length,
// and 0x80 halves the length. The zoom center is at the beginning of the
// scanline therefore it is not necessary to adjust render start position
zoom = line_ram[linedata_offs + 2];
scroll = ((short)line_ram[linedata_offs + 3]); // get signed local scroll value for the current scanline
// scavenged from old code; improves Xexex' first level sky
if (wrap500 && scroll >= 0x500) scroll -= 0x800;
if (1 && scroll >= 0x500) scroll -= 0x800;
scroll += scroll_corr; // apply final scroll correction
// PJB
//scroll &= src_wrapmask; // wraparound scroll value if necessary
if (0)
{
printf("%u: [%x] COLR:%x OFFS:%x ZOOM:%x SCRL:%d (%.4x)\n", line_pos, linedata_offs, color, offset, zoom, scroll, line_ram[linedata_offs + 3]);
}
// draw scanlines wrapped at virtual bitmap boundary in two passes
// this should not impose too much overhead due to clipping performed by the render code
i = passes;
do
{
/*
Parameter descriptions:
bitmap : pointer to a MAME bitmap as the render target
pal_ptr : pointer to the palette's physical location relative to the scanline
pix_ptr : pointer to the physical start location of source pixels in ROM
cliprect : pointer to a rectangle structue which describes the visible area of the target bitmap
line_pos : scanline render position relative to the target bitmap
should be a Y offset to the target bitmap in normal orientaion,
or an X offset to the target bitmap if X,Y are swapped
scroll : source scroll value of the scanline
zoom : source zoom factor of the scanline
src_clipmask : source offset clip mask; source pixels with offsets beyond the scope of this mask will not be drawn
src_wrapmask : source offset wrap mask; wraps source offset around, no effect when src_clipmask is set
orientation : flags indicating whether scanlines should be drawn horizontally, vertically, forward or backward
priority : value to be written to the priority bitmap, no effect when equals 0
*/
pdraw_scanline32(bitmap, pal_ptr, pix_ptr, cliprect,
line_pos, scroll, zoom, src_clipmask, src_wrapmask, orientation, priority_bitmap, (uint8_t)priority);
// shift scanline position one virtual screen upward to render the wrapped end if necessary
scroll -= dst_height;
}
while (--i);
}
}
READ16_MEMBER(k053250ps_device::reg_r)
{
return m_regs[offset];
}
void k053250ps_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch(m_timer_lvcdma_state)
{
case OD_WAIT_START:
m_timer_lvcdma_state = OD_WAIT_END;
m_timer_lvcdma->adjust(attotime::from_ticks(4096, clock()));
m_dmairq_cb(ASSERT_LINE);
// memcpy(m_buffer[m_page], &m_ram[0], 0x1000);
// m_page ^= 1;
break;
case OD_WAIT_END:
m_timer_lvcdma_state = OD_IDLE;
m_timer_lvcdma->adjust(attotime::never);
m_dmairq_cb(CLEAR_LINE);
if(/*(m_regs[4] & 0x02) &&*/ !m_dmairq_on)
{
m_dmairq_on = true;
m_dmairq_cb(ASSERT_LINE);
}
break;
}
}
WRITE_LINE_MEMBER(k053250ps_device::vblank_w)
{
if (state == 1)
{
if (1)
{
if(m_dmairq_on)
{
m_dmairq_on = false;
m_dmairq_cb(CLEAR_LINE);
}
m_timer_lvcdma_state = OD_WAIT_START;
m_timer_lvcdma->adjust(attotime::from_ticks(256, clock()));
}
else
{
//memset(m_sram, 0, sizeof(m_sram));
}
}
}
READ_LINE_MEMBER(k053250ps_device::dmairq_r)
{
return !m_dmairq_on;
}
WRITE16_MEMBER(k053250ps_device::reg_w)
{
#if 0
static const char * regnames[] =
{
"SCROLL_X_L",
"SCROLL_X_H",
"SCROLL_Y_L",
"SCROLL_X_H",
"DMA Control",
"UNKNOWN",
"ROM_H",
"ROM_L",
};
printf("053250 REG_W[%x] (%s): %.2x\n", offset, regnames[offset], data & 0xff);
#endif
if (ACCESSING_BITS_0_7)
m_regs[offset] = data;
}
READ16_MEMBER(k053250ps_device::ram_r)
{
return m_ram[offset];
}
WRITE16_MEMBER(k053250ps_device::ram_w)
{
COMBINE_DATA(&m_ram[offset]);
}
READ16_MEMBER(k053250ps_device::rom_r)
{
return m_rom[0x80000 * m_regs[6] + 0x800 * m_regs[7] + offset/2];
}

View File

@ -0,0 +1,80 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
#ifndef __K053250PS_H__
#define __K053250PS_H__
//
// Konami 053250 road generator (Pirate Ship version)
//
#define MCFG_K053250PS_ADD(_tag, _palette_tag, _screen_tag, offx, offy) \
MCFG_DEVICE_ADD(_tag, K053250PS, 12000000) \
MCFG_GFX_PALETTE(_palette_tag) \
MCFG_VIDEO_SET_SCREEN(_screen_tag) \
k053250ps_device::static_set_offsets(*device, offx, offy);
#define MCFG_K053250PS_DMAIRQ_CB(_cb) \
devcb = &k053250ps_device::set_dmairq_cb(*device, DEVCB_##_cb);
class k053250ps_device : public device_t,
public device_gfx_interface,
public device_video_interface
{
public:
k053250ps_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
static void static_set_offsets(device_t &device, int offx, int offy);
template<class _cb> static devcb_base &set_dmairq_cb(device_t &device, _cb cb) { return downcast<k053250ps_device &>(device).m_dmairq_cb.set_callback(cb); }
DECLARE_READ16_MEMBER(reg_r);
DECLARE_WRITE16_MEMBER(reg_w);
DECLARE_READ16_MEMBER(ram_r);
DECLARE_WRITE16_MEMBER(ram_w);
DECLARE_READ16_MEMBER(rom_r);
DECLARE_WRITE_LINE_MEMBER(vblank_w);
DECLARE_READ_LINE_MEMBER(dmairq_r);
void draw( bitmap_rgb32 &bitmap, const rectangle &cliprect, int colorbase, int flags, bitmap_ind8 &priority_bitmap, int priority );
protected:
// device-level overrides
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
virtual void device_start() override;
virtual void device_reset() override;
private:
enum {
OD_IDLE,
OD_WAIT_START,
OD_WAIT_END
};
devcb_write_line m_dmairq_cb;
int m_timer_lvcdma_state;
bool m_dmairq_on;
// configuration
int m_offx, m_offy;
emu_timer *m_timer_lvcdma;
// internal state
required_region_ptr<uint8_t> m_rom;
std::vector<uint8_t> m_unpacked_rom;
std::vector<uint16_t> m_ram;
uint16_t *m_buffer[2];
uint8_t m_regs[8];
uint8_t m_page;
// internal helpers
void unpack_nibbles();
static void pdraw_scanline32(bitmap_rgb32 &bitmap, const pen_t *pal_base, uint8_t *source,
const rectangle &cliprect, int linepos, int scroll, int zoom,
uint32_t clipmask, uint32_t wrapmask, uint32_t orientation, bitmap_ind8 &priority, uint8_t pri);
};
extern const device_type K053250PS;
#endif