alpha68k.cpp: converted to snk68 sprite chip [Angelo Salese]

This commit is contained in:
angelosa 2019-09-30 19:59:26 +02:00
parent 57f5a60bb5
commit b3ca144851
9 changed files with 420 additions and 469 deletions

View File

@ -204,12 +204,12 @@ void alpha68k_state::alpha_microcontroller_w(offs_t offset, u16 data, u16 mem_ma
logerror("%04x: Alpha write trigger at %04x (%04x)\n", m_maincpu->pc(), offset, data);
/* 0x44 = coin clear signal to microcontroller? */
if (offset == 0x2d && ACCESSING_BITS_0_7)
flipscreen_w(data & 1);
m_flipscreen = (data & 1);
}
/******************************************************************************/
u16 alpha68k_state::control_1_r()
u16 alpha68k_II_state::control_1_r()
{
if (m_invert_controls)
return ~(m_in[0]->read() + (m_in[1]->read() << 8));
@ -217,7 +217,7 @@ u16 alpha68k_state::control_1_r()
return m_in[0]->read() + (m_in[1]->read() << 8);
}
u16 alpha68k_state::control_2_r()
u16 alpha68k_II_state::control_2_r()
{
if (m_invert_controls)
return ~(m_in[3]->read() + ((~(1 << m_in[5]->read())) << 8));
@ -226,7 +226,7 @@ u16 alpha68k_state::control_2_r()
((~(1 << m_in[5]->read())) << 8);
}
u16 alpha68k_state::control_3_r()
u16 alpha68k_II_state::control_3_r()
{
if (m_invert_controls)
return ~(((~(1 << m_in[6]->read())) << 8) & 0xff00);
@ -235,7 +235,7 @@ u16 alpha68k_state::control_3_r()
}
/* High 4 bits of CN1 & CN2 */
u16 alpha68k_state::control_4_r()
u16 alpha68k_II_state::control_4_r()
{
if (m_invert_controls)
return ~((((~(1 << m_in[6]->read())) << 4) & 0xf000)
@ -245,7 +245,7 @@ u16 alpha68k_state::control_4_r()
+ (((~(1 << m_in[5]->read()))) & 0x0f00);
}
void alpha68k_state::outlatch_w(offs_t offset, u8 data)
void alpha68k_II_state::outlatch_w(offs_t offset, u8 data)
{
m_outlatch->write_bit((offset >> 3) & 7, BIT(offset, 6));
}
@ -253,7 +253,7 @@ void alpha68k_state::outlatch_w(offs_t offset, u8 data)
/******************************************************************************/
/* Time Soldiers, Sky Soldiers, Gold Medalist */
u16 alpha68k_state::alpha_II_trigger_r(offs_t offset)
u16 alpha68k_II_state::alpha_II_trigger_r(offs_t offset)
{
/* possible jump codes:
- Time Soldiers : 0x21,0x22,0x23,0x24,0x34,0x37,0x3a,0x3d,0x40,0x43,0x46,0x49
@ -347,7 +347,7 @@ u16 alpha68k_state::alpha_II_trigger_r(offs_t offset)
}
/* Sky Adventure, Gang Wars, Super Champion Baseball */
u16 alpha68k_state::alpha_V_trigger_r(offs_t offset)
u16 alpha68k_III_state::alpha_V_trigger_r(offs_t offset)
{
/* possible jump codes:
- Sky Adventure : 0x21,0x22,0x23,0x24,0x34,0x37,0x3a,0x3d,0x40,0x43,0x46,0x49
@ -493,72 +493,70 @@ u16 alpha68k_state::alpha_V_trigger_r(offs_t offset)
/******************************************************************************/
void alpha68k_state::alpha68k_II_map(address_map &map)
void alpha68k_II_state::alpha68k_II_map(address_map &map)
{
map(0x000000, 0x03ffff).rom();
map(0x008ffe, 0x008fff).nopw();
map(0x040000, 0x040fff).ram().share("shared_ram");
map(0x080000, 0x080001).r(FUNC(alpha68k_state::control_1_r)); /* Joysticks */
map(0x080000, 0x080001).r(FUNC(alpha68k_II_state::control_1_r)); /* Joysticks */
map(0x080001, 0x080001).w(m_soundlatch, FUNC(generic_latch_8_device::write));
map(0x0c0000, 0x0c0001).r(FUNC(alpha68k_state::control_2_r)); /* CN1 & Dip 1 */
map(0x0c0001, 0x0c0001).select(0x78).w(FUNC(alpha68k_state::outlatch_w));
map(0x0c8000, 0x0c8001).r(FUNC(alpha68k_state::control_3_r)); /* Bottom of CN2 */
map(0x0d0000, 0x0d0001).r(FUNC(alpha68k_state::control_4_r)); /* Top of CN1 & CN2 */
map(0x0c0000, 0x0c0001).r(FUNC(alpha68k_II_state::control_2_r)); /* CN1 & Dip 1 */
map(0x0c0001, 0x0c0001).select(0x78).w(FUNC(alpha68k_II_state::outlatch_w));
map(0x0c8000, 0x0c8001).r(FUNC(alpha68k_II_state::control_3_r)); /* Bottom of CN2 */
map(0x0d0000, 0x0d0001).r(FUNC(alpha68k_II_state::control_4_r)); /* Top of CN1 & CN2 */
map(0x0d8000, 0x0d8001).nopr(); /* IRQ ack? */
map(0x0e0000, 0x0e0001).nopr(); /* IRQ ack? */
map(0x0e8000, 0x0e8001).nopr(); /* watchdog? */
map(0x100000, 0x100fff).ram().w(FUNC(alpha68k_state::videoram_w)).share("videoram");
map(0x200000, 0x207fff).ram().share("spriteram");
map(0x300000, 0x3001ff).rw(FUNC(alpha68k_state::alpha_II_trigger_r), FUNC(alpha68k_state::alpha_microcontroller_w));
map(0x100000, 0x100fff).ram().w(FUNC(alpha68k_II_state::videoram_w)).share("videoram");
map(0x200000, 0x207fff).rw(m_sprites, FUNC(snk68_spr_device::spriteram_r), FUNC(snk68_spr_device::spriteram_w)).share("spriteram");
map(0x300000, 0x3001ff).rw(FUNC(alpha68k_II_state::alpha_II_trigger_r), FUNC(alpha68k_II_state::alpha_microcontroller_w));
map(0x400000, 0x400fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x800000, 0x83ffff).rom().region("maincpu", 0x40000);
}
void alpha68k_state::alpha68k_V_map(address_map &map)
void alpha68k_III_state::alpha68k_V_map(address_map &map)
{
map(0x000000, 0x03ffff).rom();
map(0x040000, 0x043fff).ram().share("shared_ram");
map(0x080000, 0x080001).r(FUNC(alpha68k_state::control_1_r)); /* Joysticks */
map(0x080000, 0x080000).w(FUNC(alpha68k_state::video_bank_w));
map(0x080000, 0x080001).r(FUNC(alpha68k_III_state::control_1_r)); /* Joysticks */
map(0x080000, 0x080000).w(FUNC(alpha68k_III_state::video_bank_w));
map(0x080001, 0x080001).w(m_soundlatch, FUNC(generic_latch_8_device::write));
map(0x0c0000, 0x0c0001).lr16("control_2_V_r", [this]() -> u16 { return m_in[3]->read(); }); /* Dip 2 */
map(0x0c0001, 0x0c0001).select(0x78).w(FUNC(alpha68k_state::outlatch_w));
map(0x0c0001, 0x0c0001).select(0x78).w(FUNC(alpha68k_III_state::outlatch_w));
map(0x0d8000, 0x0d8001).nopr(); /* IRQ ack? */
map(0x0e0000, 0x0e0001).nopr(); /* IRQ ack? */
map(0x0e8000, 0x0e8001).nopr(); /* watchdog? */
map(0x100000, 0x100fff).ram().w(FUNC(alpha68k_state::videoram_w)).share("videoram");
map(0x200000, 0x207fff).ram().share("spriteram"); // 16k for gang wars/sky adventure, 32k for sbaseball (mirror?)
map(0x300000, 0x303fff).r(FUNC(alpha68k_state::alpha_V_trigger_r));
map(0x300000, 0x3001ff).w(FUNC(alpha68k_state::alpha_microcontroller_w));
map(0x303e00, 0x303fff).w(FUNC(alpha68k_state::alpha_microcontroller_w)); /* Gang Wars mirror */
map(0x100000, 0x100fff).ram().w(FUNC(alpha68k_III_state::videoram_w)).share("videoram");
map(0x200000, 0x207fff).rw(m_sprites, FUNC(snk68_spr_device::spriteram_r), FUNC(snk68_spr_device::spriteram_w)).share("spriteram");
map(0x300000, 0x303fff).r(FUNC(alpha68k_III_state::alpha_V_trigger_r));
map(0x300000, 0x3001ff).w(FUNC(alpha68k_III_state::alpha_microcontroller_w));
map(0x303e00, 0x303fff).w(FUNC(alpha68k_III_state::alpha_microcontroller_w)); /* Gang Wars mirror */
map(0x400000, 0x401fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // upper bank actually a mirror?
map(0x800000, 0x83ffff).rom().region("maincpu", 0x40000);
}
void alpha68k_state::alpha68k_III_map(address_map &map)
void alpha68k_III_state::alpha68k_III_map(address_map &map)
{
alpha68k_V_map(map);
map(0x300000, 0x3001ff).rw(FUNC(alpha68k_state::alpha_II_trigger_r), FUNC(alpha68k_state::alpha_microcontroller_w));
alpha68k_III_state::alpha68k_V_map(map);
map(0x300000, 0x3001ff).rw(FUNC(alpha68k_III_state::alpha_II_trigger_r), FUNC(alpha68k_III_state::alpha_microcontroller_w));
map(0x300200, 0x303fff).unmaprw();
}
u16 alpha68k_state::sound_cpu_r(){ return 1; }
/******************************************************************************/
void alpha68k_state::sound_bank_w(u8 data)
void alpha68k_II_state::sound_bank_w(u8 data)
{
m_audiobank->set_entry(data & 0x1f);
}
void alpha68k_state::sound_map(address_map &map)
void alpha68k_II_state::sound_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0x8000, 0x87ff).ram();
map(0xc000, 0xffff).bankr("audiobank");
}
void alpha68k_state::sound_portmap(address_map &map)
void alpha68k_II_state::sound_portmap(address_map &map)
{
map.global_mask(0x0f);
map(0x00, 0x00).mirror(0x0f).r(m_soundlatch, FUNC(generic_latch_8_device::read));
@ -566,7 +564,7 @@ void alpha68k_state::sound_portmap(address_map &map)
map(0x08, 0x08).mirror(0x01).w("dac", FUNC(dac_byte_interface::data_w));
map(0x0a, 0x0b).w("ym2", FUNC(ym2413_device::write));
map(0x0c, 0x0d).w("ym1", FUNC(ym2203_device::write));
map(0x0e, 0x0e).mirror(0x01).w(FUNC(alpha68k_state::sound_bank_w));
map(0x0e, 0x0e).mirror(0x01).w(FUNC(alpha68k_II_state::sound_bank_w));
}
/******************************************************************************/
@ -1143,7 +1141,7 @@ GFXDECODE_END
/******************************************************************************/
void alpha68k_state::porta_w(u8 data)
void alpha68k_II_state::porta_w(u8 data)
{
if (data == 0xff)
return; // skip
@ -1186,7 +1184,7 @@ MACHINE_RESET_MEMBER(alpha68k_state,common)
m_flipscreen = 0;
}
MACHINE_START_MEMBER(alpha68k_state,alpha68k_V)
MACHINE_START_MEMBER(alpha68k_III_state,alpha68k_V)
{
u8 *ROM = memregion("audiocpu")->base();
@ -1199,19 +1197,19 @@ MACHINE_START_MEMBER(alpha68k_state,alpha68k_V)
save_item(NAME(m_sound_pa_latch));
}
MACHINE_RESET_MEMBER(alpha68k_state,alpha68k_V)
MACHINE_RESET_MEMBER(alpha68k_III_state,alpha68k_V)
{
MACHINE_RESET_CALL_MEMBER(common);
m_bank_base = 0;
}
MACHINE_RESET_MEMBER(alpha68k_state,alpha68k_II)
MACHINE_RESET_MEMBER(alpha68k_II_state,alpha68k_II)
{
MACHINE_RESET_CALL_MEMBER(common);
}
MACHINE_START_MEMBER(alpha68k_state,alpha68k_II)
MACHINE_START_MEMBER(alpha68k_II_state,alpha68k_II)
{
u8 *ROM = memregion("audiocpu")->base();
@ -1225,131 +1223,36 @@ MACHINE_START_MEMBER(alpha68k_state,alpha68k_II)
}
#define ALPHA68K_PIXEL_CLOCK (24_MHz_XTAL / 4)
#define ALPHA68K_HTOTAL 394
#define ALPHA68K_HTOTAL 384
void alpha68k_state::set_screen_raw_params(machine_config &config)
{
// Pixel clock, assuming that it can't be 4 MHz because 4 MHz / 15,20 KHz = 263 HTOTAL (VERY unlikely).
m_screen->set_raw(ALPHA68K_PIXEL_CLOCK,ALPHA68K_HTOTAL,0,256,253,16,240);
// TODO: Same as snk68.cpp, which in turn is awfully similar to NeoGeo CRTC parameters
m_screen->set_raw(ALPHA68K_PIXEL_CLOCK,ALPHA68K_HTOTAL,0,256,264,16,240);
}
INTERRUPT_GEN_MEMBER(alpha68k_state::sound_nmi)
INTERRUPT_GEN_MEMBER(alpha68k_II_state::sound_nmi)
{
if (m_sound_nmi_mask)
device.execute().pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
void alpha68k_state::alpha68k_II(machine_config &config)
void alpha68k_II_state::base_config(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, 8000000); /* Correct */
m_maincpu->set_addrmap(AS_PROGRAM, &alpha68k_state::alpha68k_II_map);
m_maincpu->set_vblank_int("screen", FUNC(alpha68k_state::irq3_line_hold)); /* VBL */
Z80(config, m_audiocpu, 6000000);
m_audiocpu->set_addrmap(AS_PROGRAM, &alpha68k_state::sound_map);
m_audiocpu->set_addrmap(AS_IO, &alpha68k_state::sound_portmap);
m_audiocpu->set_periodic_int(FUNC(alpha68k_state::sound_nmi), attotime::from_hz(7614));
LS259(config, m_outlatch); // 14A
m_outlatch->q_out_cb<2>().set(FUNC(alpha68k_state::video_control2_w));
m_outlatch->q_out_cb<3>().set(FUNC(alpha68k_state::video_control3_w));
m_outlatch->parallel_out_cb().set(FUNC(alpha68k_state::video_bank_w)).rshift(4).mask(0x07);
MCFG_MACHINE_START_OVERRIDE(alpha68k_state,alpha68k_II)
MCFG_MACHINE_RESET_OVERRIDE(alpha68k_state,alpha68k_II)
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
// m_screen->set_refresh_hz(60);
// m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0));
// m_screen->set_size(32*8, 32*8);
// m_screen->set_visarea(0*8, 32*8-1, 2*8, 30*8-1);
set_screen_raw_params(config);
m_screen->set_screen_update(FUNC(alpha68k_state::screen_update_alpha68k_II));
m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_alpha68k_II);
PALETTE(config, m_palette).set_format(2, &raw_to_rgb_converter::xRGBRRRRGGGGBBBB_bit0_decoder, 2048);
MCFG_VIDEO_START_OVERRIDE(alpha68k_state,alpha68k)
m_outlatch->q_out_cb<2>().set(FUNC(alpha68k_II_state::video_control2_w));
m_outlatch->q_out_cb<3>().set(FUNC(alpha68k_II_state::video_control3_w));
/* sound hardware */
SPEAKER(config, "speaker").front_center();
GENERIC_LATCH_8(config, m_soundlatch);
ym2203_device &ym1(YM2203(config, "ym1", 3000000));
ym1.port_a_write_callback().set(FUNC(alpha68k_state::porta_w));
ym2203_device &ym1(YM2203(config, "ym1", ALPHA68K_PIXEL_CLOCK / 2)); // TODO: verify me
ym1.port_a_write_callback().set(FUNC(alpha68k_II_state::porta_w));
ym1.add_route(ALL_OUTPUTS, "speaker", 0.65);
ym2413_device &ym2(YM2413(config, "ym2", 3.579545_MHz_XTAL));
ym2.add_route(ALL_OUTPUTS, "speaker", 1.0);
DAC_8BIT_R2R(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.75); // unknown DAC
voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0));
vref.add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT);
vref.add_route(0, "dac", -1.0, DAC_VREF_NEG_INPUT);
}
void alpha68k_state::btlfieldb(machine_config &config)
{
alpha68k_II(config);
m_maincpu->set_vblank_int("screen", FUNC(alpha68k_state::irq1_line_hold));
m_maincpu->set_periodic_int(FUNC(alpha68k_state::irq2_line_hold), attotime::from_hz(60*4)); // MCU irq
}
void alpha68k_state::alpha68k_II_gm(machine_config &config)
{
alpha68k_II(config);
m_maincpu->set_vblank_int("screen", FUNC(alpha68k_state::irq1_line_hold));
m_maincpu->set_periodic_int(FUNC(alpha68k_state::irq2_line_hold), attotime::from_hz(60*3)); // MCU irq
}
void alpha68k_state::alpha68k_V(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, 20_MHz_XTAL / 2);
m_maincpu->set_addrmap(AS_PROGRAM, &alpha68k_state::alpha68k_V_map);
m_maincpu->set_vblank_int("screen", FUNC(alpha68k_state::irq3_line_hold)); /* VBL */
Z80(config, m_audiocpu, 24_MHz_XTAL / 4);
m_audiocpu->set_addrmap(AS_PROGRAM, &alpha68k_state::sound_map);
m_audiocpu->set_addrmap(AS_IO, &alpha68k_state::sound_portmap);
m_audiocpu->set_periodic_int(FUNC(alpha68k_state::sound_nmi), attotime::from_hz(ALPHA68K_PIXEL_CLOCK / ALPHA68K_HTOTAL / 2));
LS259(config, m_outlatch); // 13C
m_outlatch->q_out_cb<2>().set(FUNC(alpha68k_state::video_control2_w));
m_outlatch->q_out_cb<3>().set(FUNC(alpha68k_state::video_control3_w));
MCFG_MACHINE_START_OVERRIDE(alpha68k_state,alpha68k_V)
MCFG_MACHINE_RESET_OVERRIDE(alpha68k_state,alpha68k_V)
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
// m_screen->set_refresh_hz(60);
// m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0));
// m_screen->set_soze(32*8, 32*8);
// m_screen->set_visarea(0*8, 32*8-1, 2*8, 30*8-1);;
set_screen_raw_params(config);
m_screen->set_screen_update(FUNC(alpha68k_state::screen_update_alpha68k_V));
m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_alpha68k_V);
PALETTE(config, m_palette).set_format(2, &raw_to_rgb_converter::xRGBRRRRGGGGBBBB_bit0_decoder, 4096);
MCFG_VIDEO_START_OVERRIDE(alpha68k_state,alpha68k)
/* sound hardware */
SPEAKER(config, "speaker").front_center();
GENERIC_LATCH_8(config, m_soundlatch);
ym2203_device &ym1(YM2203(config, "ym1", ALPHA68K_PIXEL_CLOCK / 2));
ym1.port_a_write_callback().set(FUNC(alpha68k_state::porta_w));
ym1.add_route(ALL_OUTPUTS, "speaker", 0.65);
ym2413_device &ym2(YM2413(config, "ym2", 3.579545_MHz_XTAL));
ym2413_device &ym2(YM2413(config, "ym2", 3.579545_MHz_XTAL)); // TODO: verify me
ym2.add_route(ALL_OUTPUTS, "speaker", 1.0);
DAC_8BIT_R2R(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.75); // ALPHA-VOICE88 custom DAC
@ -1358,24 +1261,110 @@ void alpha68k_state::alpha68k_V(machine_config &config)
vref.add_route(0, "dac", -1.0, DAC_VREF_NEG_INPUT);
}
void alpha68k_state::alpha68k_V_sb(machine_config &config)
void alpha68k_II_state::video_config(machine_config &config, u16 num_pens)
{
alpha68k_V(config);
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
set_screen_raw_params(config);
m_screen->set_screen_update(FUNC(alpha68k_II_state::screen_update));
m_screen->set_palette(m_palette);
// TODO: should really be same as snk68.cpp
MCFG_VIDEO_START_OVERRIDE(alpha68k_II_state,alpha68k)
SNK68_SPR(config, m_sprites, 0);
m_sprites->set_gfxdecode_tag(m_gfxdecode);
m_sprites->set_tile_indirect_cb(FUNC(alpha68k_II_state::tile_callback), this);
m_sprites->set_xpos_shift(15);
m_sprites->set_color_entry_mask((num_pens / 16) - 1);
// TODO: change into NeoGeo palette format ...
PALETTE(config, m_palette).set_format(2, &raw_to_rgb_converter::xRGBRRRRGGGGBBBB_bit0_decoder, num_pens);
// TODO: ... and make this a configuration option
m_backdrop_pen = num_pens - 1;
}
void alpha68k_II_state::alpha68k_II(machine_config &config)
{
base_config(config);
m_outlatch->parallel_out_cb().set(FUNC(alpha68k_II_state::video_bank_w)).rshift(4).mask(0x07);
/* basic machine hardware */
M68000(config, m_maincpu, 8000000); // TODO: verify me
m_maincpu->set_addrmap(AS_PROGRAM, &alpha68k_II_state::alpha68k_II_map);
m_maincpu->set_vblank_int("screen", FUNC(alpha68k_state::irq3_line_hold)); /* VBL */
Z80(config, m_audiocpu, 6000000); // TODO: verify me
m_audiocpu->set_addrmap(AS_PROGRAM, &alpha68k_II_state::sound_map);
m_audiocpu->set_addrmap(AS_IO, &alpha68k_II_state::sound_portmap);
m_audiocpu->set_periodic_int(FUNC(alpha68k_II_state::sound_nmi), attotime::from_hz(7614));
MCFG_MACHINE_START_OVERRIDE(alpha68k_II_state,alpha68k_II)
MCFG_MACHINE_RESET_OVERRIDE(alpha68k_II_state,alpha68k_II)
video_config(config, 2048);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_alpha68k_II);
}
void alpha68k_II_state::btlfieldb(machine_config &config)
{
alpha68k_II(config);
m_maincpu->set_vblank_int("screen", FUNC(alpha68k_II_state::irq1_line_hold));
m_maincpu->set_periodic_int(FUNC(alpha68k_II_state::irq2_line_hold), attotime::from_hz(60*4)); // MCU irq
}
void goldmedal_II_state::goldmedal(machine_config &config)
{
alpha68k_II(config);
m_maincpu->set_vblank_int("screen", FUNC(goldmedal_II_state::irq1_line_hold));
m_maincpu->set_periodic_int(FUNC(goldmedal_II_state::irq2_line_hold), attotime::from_hz(60*3)); // MCU irq
}
void alpha68k_III_state::alpha68k_III(machine_config &config)
{
base_config(config);
M68000(config, m_maincpu, 20_MHz_XTAL / 2);
m_maincpu->set_addrmap(AS_PROGRAM, &alpha68k_III_state::alpha68k_III_map);
m_maincpu->set_vblank_int("screen", FUNC(alpha68k_III_state::irq1_line_hold)); /* VBL */
Z80(config, m_audiocpu, 24_MHz_XTAL / 4);
m_audiocpu->set_addrmap(AS_PROGRAM, &alpha68k_III_state::sound_map);
m_audiocpu->set_addrmap(AS_IO, &alpha68k_III_state::sound_portmap);
m_audiocpu->set_periodic_int(FUNC(alpha68k_III_state::sound_nmi), attotime::from_hz(ALPHA68K_PIXEL_CLOCK / ALPHA68K_HTOTAL / 2));
MCFG_MACHINE_START_OVERRIDE(alpha68k_III_state,alpha68k_V)
MCFG_MACHINE_RESET_OVERRIDE(alpha68k_III_state,alpha68k_V)
/* video hardware */
m_screen->set_screen_update(FUNC(alpha68k_state::screen_update_alpha68k_V_sb));
video_config(config, 4096);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_alpha68k_V);
}
// goldmedla
void alpha68k_state::alpha68k_III(machine_config &config)
void goldmedal_III_state::goldmedal(machine_config &config)
{
// TODO: we conveniently override this, base should really be shuffled around in the first place.
alpha68k_V_sb(config);
m_maincpu->set_addrmap(AS_PROGRAM, &alpha68k_state::alpha68k_III_map);
m_maincpu->set_vblank_int("screen", FUNC(alpha68k_state::irq1_line_hold));
m_maincpu->set_periodic_int(FUNC(alpha68k_state::irq2_line_hold), attotime::from_hz(60*3)); // MCU irq
alpha68k_III_state::alpha68k_III(config);
m_maincpu->set_periodic_int(FUNC(goldmedal_III_state::irq2_line_hold), attotime::from_hz(60*3)); // MCU irq
}
void alpha68k_V_state::alpha68k_V(machine_config &config)
{
alpha68k_III_state::alpha68k_III(config);
m_maincpu->set_addrmap(AS_PROGRAM, &alpha68k_V_state::alpha68k_V_map);
m_maincpu->set_vblank_int("screen", FUNC(alpha68k_V_state::irq3_line_hold)); /* VBL */
}
void skyadventure_state::skyadventure(machine_config &config)
{
alpha68k_V_state::alpha68k_V(config);
m_sprites->set_tile_indirect_cb(FUNC(skyadventure_state::tile_callback_noflipx), this);
}
void gangwars_state::gangwars(machine_config &config)
{
alpha68k_V_state::alpha68k_V(config);
m_sprites->set_tile_indirect_cb(FUNC(gangwars_state::tile_callback_noflipy), this);
}
/******************************************************************************/
@ -2018,7 +2007,7 @@ ROM_END
/******************************************************************************/
void alpha68k_state::init_timesold()
void alpha68k_II_state::init_timesold()
{
m_invert_controls = 0;
m_microcontroller_id = 0;
@ -2026,7 +2015,7 @@ void alpha68k_state::init_timesold()
m_game_id = 0;
}
void alpha68k_state::init_timesold1()
void alpha68k_II_state::init_timesold1()
{
m_invert_controls = 1;
m_microcontroller_id = 0;
@ -2034,7 +2023,7 @@ void alpha68k_state::init_timesold1()
m_game_id = 0;
}
void alpha68k_state::init_btlfield()
void alpha68k_II_state::init_btlfield()
{
m_invert_controls = 1;
m_microcontroller_id = 0;
@ -2042,7 +2031,7 @@ void alpha68k_state::init_btlfield()
m_game_id = 0;
}
void alpha68k_state::init_btlfieldb()
void alpha68k_II_state::init_btlfieldb()
{
m_invert_controls = 1;
m_microcontroller_id = 0;
@ -2050,7 +2039,7 @@ void alpha68k_state::init_btlfieldb()
m_game_id = ALPHA68K_BTLFIELDB;
}
void alpha68k_state::init_skysoldr()
void alpha68k_II_state::init_skysoldr()
{
m_invert_controls = 0;
m_microcontroller_id = 0;
@ -2058,7 +2047,7 @@ void alpha68k_state::init_skysoldr()
m_game_id = 0;
}
void alpha68k_state::init_goldmedl()
void goldmedal_II_state::init_goldmedl()
{
m_invert_controls = 0;
m_microcontroller_id = 0x8803; //AT
@ -2066,7 +2055,7 @@ void alpha68k_state::init_goldmedl()
m_game_id = 0;
}
void alpha68k_state::init_goldmedla()
void goldmedal_III_state::init_goldmedla()
{
m_invert_controls = 0;
m_microcontroller_id = 0x8803; //Guess - routine to handle coinage is the same as in 'goldmedl'
@ -2074,7 +2063,7 @@ void alpha68k_state::init_goldmedla()
m_game_id = 0;
}
void alpha68k_state::init_skyadvnt()
void alpha68k_V_state::init_skyadvnt()
{
m_invert_controls = 0;
m_microcontroller_id = 0x8814;
@ -2082,7 +2071,7 @@ void alpha68k_state::init_skyadvnt()
m_game_id = 0;
}
void alpha68k_state::init_skyadvntu()
void alpha68k_V_state::init_skyadvntu()
{
m_invert_controls = 0;
m_microcontroller_id = 0x8814;
@ -2090,7 +2079,7 @@ void alpha68k_state::init_skyadvntu()
m_game_id = 0;
}
void alpha68k_state::init_gangwarsu()
void alpha68k_V_state::init_gangwarsu()
{
m_invert_controls = 0;
m_microcontroller_id = 0x8512;
@ -2098,7 +2087,7 @@ void alpha68k_state::init_gangwarsu()
m_game_id = 0;
}
void alpha68k_state::init_gangwars()
void alpha68k_V_state::init_gangwars()
{
m_invert_controls = 0;
m_microcontroller_id = 0x8512;
@ -2106,7 +2095,7 @@ void alpha68k_state::init_gangwars()
m_game_id = 0;
}
void alpha68k_state::init_sbasebal()
void alpha68k_V_state::init_sbasebal()
{
u16 *rom = (u16 *)memregion("maincpu")->base();
@ -2130,7 +2119,7 @@ void alpha68k_state::init_sbasebal()
m_game_id = 0;
}
void alpha68k_state::init_sbasebalj()
void alpha68k_V_state::init_sbasebalj()
{
m_invert_controls = 0;
m_microcontroller_id = 0x8512; // Same as 'gangwars' ?
@ -2140,29 +2129,33 @@ void alpha68k_state::init_sbasebalj()
/******************************************************************************/
GAME( 1987, timesold, 0, alpha68k_II, timesold, alpha68k_state, init_timesold, ROT90, "Alpha Denshi Co. (SNK/Romstar license)", "Time Soldiers (US Rev 3)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, timesold1, timesold, alpha68k_II, timesold, alpha68k_state, init_timesold1, ROT90, "Alpha Denshi Co. (SNK/Romstar license)", "Time Soldiers (US Rev 1)", MACHINE_SUPPORTS_SAVE )
// Alpha II HW
GAME( 1987, timesold, 0, alpha68k_II, timesold, alpha68k_II_state, init_timesold, ROT90, "Alpha Denshi Co. (SNK/Romstar license)", "Time Soldiers (US Rev 3)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, timesold1, timesold, alpha68k_II, timesold, alpha68k_II_state, init_timesold1, ROT90, "Alpha Denshi Co. (SNK/Romstar license)", "Time Soldiers (US Rev 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, btlfield, timesold, alpha68k_II, btlfield, alpha68k_state, init_btlfield, ROT90, "Alpha Denshi Co. (SNK license)", "Battle Field (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, btlfieldb, timesold, btlfieldb, btlfieldb, alpha68k_state, init_btlfieldb, ROT90, "bootleg", "Battle Field (bootleg)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, btlfield, timesold, alpha68k_II, btlfield, alpha68k_II_state, init_btlfield, ROT90, "Alpha Denshi Co. (SNK license)", "Battle Field (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, btlfieldb, timesold, btlfieldb, btlfieldb, alpha68k_II_state, init_btlfieldb, ROT90, "bootleg", "Battle Field (bootleg)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, skysoldr, 0, alpha68k_II, skysoldr, alpha68k_state, init_skysoldr, ROT90, "Alpha Denshi Co. (SNK of America/Romstar license)", "Sky Soldiers (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, skysoldrbl,skysoldr, alpha68k_II, skysoldr, alpha68k_state, init_skysoldr, ROT90, "bootleg", "Sky Soldiers (bootleg)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, skysoldr, 0, alpha68k_II, skysoldr, alpha68k_II_state, init_skysoldr, ROT90, "Alpha Denshi Co. (SNK of America/Romstar license)", "Sky Soldiers (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, skysoldrbl,skysoldr, alpha68k_II, skysoldr, alpha68k_II_state, init_skysoldr, ROT90, "bootleg", "Sky Soldiers (bootleg)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, goldmedl, 0, alpha68k_II_gm, goldmedl, alpha68k_state, init_goldmedl, ROT0, "SNK", "Gold Medalist (set 1, Alpha68k II PCB)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, goldmedla, goldmedl, alpha68k_III, goldmedl, alpha68k_state, init_goldmedla, ROT0, "SNK", "Gold Medalist (set 2, Alpha68k III PCB)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, goldmedlb, goldmedl, alpha68k_III, goldmedl, alpha68k_state, init_goldmedla, ROT0, "bootleg", "Gold Medalist (bootleg, Alpha68k III PCB)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, goldmedl, 0, goldmedal, goldmedl, goldmedal_II_state, init_goldmedl, ROT0, "SNK", "Gold Medalist (set 1, Alpha68k II PCB)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, skyadvnt, 0, alpha68k_V, skyadvnt, alpha68k_state, init_skyadvnt, ROT90, "Alpha Denshi Co.", "Sky Adventure (World)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, skyadvntu, skyadvnt, alpha68k_V, skyadvntu, alpha68k_state, init_skyadvntu, ROT90, "Alpha Denshi Co. (SNK of America license)", "Sky Adventure (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, skyadvntj, skyadvnt, alpha68k_V, skyadvnt, alpha68k_state, init_skyadvnt, ROT90, "Alpha Denshi Co.", "Sky Adventure (Japan)", MACHINE_SUPPORTS_SAVE )
// Alpha III HW
GAME( 1988, goldmedla, goldmedl, goldmedal, goldmedl, goldmedal_III_state, init_goldmedla, ROT0, "SNK", "Gold Medalist (set 2, Alpha68k III PCB)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, goldmedlb, goldmedl, goldmedal, goldmedl, goldmedal_III_state, init_goldmedla, ROT0, "bootleg", "Gold Medalist (bootleg, Alpha68k III PCB)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, gangwars, 0, alpha68k_V, gangwars, alpha68k_state, init_gangwars, ROT0, "Alpha Denshi Co.", "Gang Wars", MACHINE_SUPPORTS_SAVE )
GAME( 1989, gangwarsj, gangwars, alpha68k_V, gangwars, alpha68k_state, init_gangwars, ROT0, "Alpha Denshi Co.", "Gang Wars (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, gangwarsu, gangwars, alpha68k_V, gangwarsu, alpha68k_state, init_gangwarsu, ROT0, "Alpha Denshi Co.", "Gang Wars (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, gangwarsb, gangwars, alpha68k_V, gangwars, alpha68k_state, init_gangwars, ROT0, "bootleg", "Gang Wars (bootleg)", MACHINE_SUPPORTS_SAVE ) // has (undumped) 68705 MCU in place of Alpha MCU, otherwise the same as 'gangwars'
// Alpha V HW
GAME( 1989, skyadvnt, 0, skyadventure, skyadvnt, skyadventure_state, init_skyadvnt, ROT90, "Alpha Denshi Co.", "Sky Adventure (World)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, skyadvntu, skyadvnt, skyadventure, skyadvntu, skyadventure_state, init_skyadvntu, ROT90, "Alpha Denshi Co. (SNK of America license)", "Sky Adventure (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, skyadvntj, skyadvnt, skyadventure, skyadvnt, skyadventure_state, init_skyadvnt, ROT90, "Alpha Denshi Co.", "Sky Adventure (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, sbasebal, 0, alpha68k_V_sb, sbasebal, alpha68k_state, init_sbasebal, ROT0, "Alpha Denshi Co. (SNK of America license)", "Super Champion Baseball (US)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) // calculated pitcher launching speed
GAME( 1989, sbasebalj, sbasebal, alpha68k_V_sb, sbasebalj, alpha68k_state, init_sbasebalj, ROT0, "Alpha Denshi Co.", "Super Champion Baseball (Japan)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) // same as above
GAME( 1989, gangwars, 0, gangwars, gangwars, gangwars_state, init_gangwars, ROT0, "Alpha Denshi Co.", "Gang Wars", MACHINE_SUPPORTS_SAVE )
GAME( 1989, gangwarsj, gangwars, gangwars, gangwars, gangwars_state, init_gangwars, ROT0, "Alpha Denshi Co.", "Gang Wars (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, gangwarsu, gangwars, gangwars, gangwarsu, gangwars_state, init_gangwarsu, ROT0, "Alpha Denshi Co.", "Gang Wars (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, gangwarsb, gangwars, gangwars, gangwars, gangwars_state, init_gangwars, ROT0, "bootleg", "Gang Wars (bootleg)", MACHINE_SUPPORTS_SAVE ) // has (undumped) 68705 MCU in place of Alpha MCU, otherwise the same as 'gangwars'
GAME( 1989, sbasebal, 0, alpha68k_V, sbasebal, alpha68k_V_state, init_sbasebal, ROT0, "Alpha Denshi Co. (SNK of America license)", "Super Champion Baseball (US)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) // calculated pitcher launching speed
GAME( 1989, sbasebalj, sbasebal, alpha68k_V, sbasebalj, alpha68k_V_state, init_sbasebalj, ROT0, "Alpha Denshi Co.", "Super Champion Baseball (Japan)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) // same as above

View File

@ -79,9 +79,13 @@ void thenextspace_state::tnextspc_unknown_w(offs_t offset, u16 data)
{
logerror("tnextspc_unknown_w : PC = %04x - offset = %04x - data = %04x\n", m_maincpu->pc(), offset, data);
if (offset == 0)
flipscreen_w(data & 0x100);
m_flipscreen = data & 0x100;
}
// TODO: check me
u16 thenextspace_state::sound_cpu_r(){ return 1; }
/*
*
* Address Maps

View File

@ -282,7 +282,7 @@ void sstingray_state::alpha8511_control_w(u8 data)
m_maincpu->set_input_line(M68K_IRQ_2, HOLD_LINE);
if (!BIT(data, 6))
m_shared_ram[m_alpha8511_address] = (m_shared_ram[m_alpha8511_address] & 0xff00) | m_microcontroller_data;
flipscreen_w(!BIT(data, 7));
m_flipscreen = !BIT(data, 7);
m_alpha8511_control = data;
}

View File

@ -509,6 +509,8 @@ void blackt96_state::blackt96(machine_config &config)
m_sprites->set_gfxdecode_tag(m_gfxdecode);
m_sprites->set_tile_indirect_cb(FUNC(blackt96_state::tile_callback), this);
m_sprites->set_no_partial();
m_sprites->set_xpos_shift(12);
m_sprites->set_color_entry_mask(0x7f);
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();

View File

@ -600,6 +600,8 @@ void snk68_state::pow(machine_config &config)
SNK68_SPR(config, m_sprites, 0);
m_sprites->set_gfxdecode_tag(m_gfxdecode);
m_sprites->set_tile_indirect_cb(FUNC(snk68_state::tile_callback_pow), this);
m_sprites->set_xpos_shift(12);
m_sprites->set_color_entry_mask(0x7f);
/* sound hardware */
SPEAKER(config, "mono").front_center();

View File

@ -21,6 +21,7 @@
#include "sound/ym2413.h"
#include "machine/74259.h"
#include "machine/gen_latch.h"
#include "video/snk68_spr.h"
#include "emupal.h"
#include "screen.h"
#include "tilemap.h"
@ -47,27 +48,6 @@ public:
m_audiobank(*this, "audiobank")
{ }
void alpha68k_II(machine_config &config);
void btlfieldb(machine_config &config);
void alpha68k_II_gm(machine_config &config);
void alpha68k_III(machine_config &config);
void alpha68k_V(machine_config &config);
void alpha68k_V_sb(machine_config &config);
void init_btlfield();
void init_goldmedl();
void init_skyadvnt();
void init_goldmedla();
void init_gangwarsu();
void init_gangwars();
void init_timesold1();
void init_sbasebal();
void init_sbasebalj();
void init_skysoldr();
void init_skyadvntu();
void init_btlfieldb();
void init_timesold();
protected:
/* devices */
required_device<cpu_device> m_maincpu;
@ -88,14 +68,6 @@ protected:
optional_ioport_array<7> m_in;
optional_memory_bank m_audiobank;
void flipscreen_w(int flip);
u16 sound_cpu_r();
void sound_bank_w(u8 data);
DECLARE_MACHINE_START(common);
DECLARE_MACHINE_RESET(common);
DECLARE_VIDEO_START(alpha68k);
int m_flipscreen;
// MCU sims
@ -114,45 +86,149 @@ protected:
void set_screen_raw_params(machine_config &config);
private:
u16 control_1_r();
u16 control_2_r();
u16 control_3_r();
u16 control_4_r();
void outlatch_w(offs_t offset, u8 data = 0);
u16 alpha_II_trigger_r(offs_t offset);
u16 alpha_V_trigger_r(offs_t offset);
void porta_w(u8 data);
void videoram_w(offs_t offset, u16 data);
DECLARE_WRITE_LINE_MEMBER(video_control2_w);
DECLARE_WRITE_LINE_MEMBER(video_control3_w);
DECLARE_MACHINE_START(common);
DECLARE_MACHINE_RESET(common);
};
class alpha68k_II_state : public alpha68k_state
{
public:
alpha68k_II_state(const machine_config &mconfig, device_type type, const char *tag)
: alpha68k_state(mconfig, type, tag)
, m_sprites(*this, "sprites")
{}
void alpha68k_II(machine_config &config);
void btlfieldb(machine_config &config);
void init_skysoldr();
void init_timesold();
void init_timesold1();
void init_btlfield();
void init_btlfieldb();
protected:
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
required_device<snk68_spr_device> m_sprites;
void base_config(machine_config &config);
DECLARE_VIDEO_START(alpha68k);
void video_config(machine_config &config, u16 num_pens);
void tile_callback(int &tile, int& fx, int& fy, int& region);
void tile_callback_noflipx(int &tile, int& fx, int& fy, int& region);
void tile_callback_noflipy(int &tile, int& fx, int& fy, int& region);
INTERRUPT_GEN_MEMBER(sound_nmi);
void sound_bank_w(u8 data);
void flipscreen_w(int flip);
void porta_w(u8 data);
u8 m_sound_nmi_mask;
u8 m_sound_pa_latch;
TILE_GET_INFO_MEMBER(get_tile_info);
DECLARE_MACHINE_START(alpha68k_II);
DECLARE_MACHINE_RESET(alpha68k_II);
DECLARE_MACHINE_START(alpha68k_V);
DECLARE_MACHINE_RESET(alpha68k_V);
u32 screen_update_alpha68k_II(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_alpha68k_V(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_alpha68k_V_sb(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(sound_nmi);
void video_bank_w(u8 data);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int j, int s, int e);
void draw_sprites_V(bitmap_ind16 &bitmap, const rectangle &cliprect, int j, int s, int e, u16 fx_mask, u16 fy_mask, u16 sprite_mask);
void alpha68k_II_map(address_map &map);
void alpha68k_III_map(address_map &map);
void alpha68k_V_map(address_map &map);
void sound_map(address_map &map);
void sound_portmap(address_map &map);
u8 m_sound_nmi_mask;
u8 m_sound_pa_latch;
u16 alpha_II_trigger_r(offs_t offset);
/* video-related */
tilemap_t *m_fix_tilemap;
int m_bank_base;
void outlatch_w(offs_t offset, u8 data = 0);
u16 control_1_r();
u16 control_2_r();
u16 control_3_r();
u16 control_4_r();
void videoram_w(offs_t offset, u16 data);
DECLARE_WRITE_LINE_MEMBER(video_control2_w);
DECLARE_WRITE_LINE_MEMBER(video_control3_w);
private:
u16 m_backdrop_pen;
TILE_GET_INFO_MEMBER(get_tile_info);
};
class goldmedal_II_state : public alpha68k_II_state
{
public:
goldmedal_II_state(const machine_config &mconfig, device_type type, const char *tag)
: alpha68k_II_state(mconfig, type, tag)
{}
void init_goldmedl();
void goldmedal(machine_config &config);
};
class alpha68k_III_state : public alpha68k_II_state
{
public:
alpha68k_III_state(const machine_config &mconfig, device_type type, const char *tag)
: alpha68k_II_state(mconfig, type, tag)
{}
void alpha68k_III(machine_config &config);
protected:
DECLARE_MACHINE_START(alpha68k_V);
DECLARE_MACHINE_RESET(alpha68k_V);
void alpha68k_III_map(address_map &map);
void alpha68k_V_map(address_map &map);
u16 alpha_V_trigger_r(offs_t offset);
};
class goldmedal_III_state : public alpha68k_III_state
{
public:
goldmedal_III_state(const machine_config &mconfig, device_type type, const char *tag)
: alpha68k_III_state(mconfig, type, tag)
{}
void init_goldmedla();
void goldmedal(machine_config &config);
};
class alpha68k_V_state : public alpha68k_III_state
{
public:
alpha68k_V_state(const machine_config &mconfig, device_type type, const char *tag)
: alpha68k_III_state(mconfig, type, tag)
{}
void init_skyadvnt();
void init_skyadvntu();
void init_sbasebal();
void init_sbasebalj();
void init_gangwarsu();
void init_gangwars();
void alpha68k_V(machine_config &config);
};
class skyadventure_state : public alpha68k_V_state
{
public:
skyadventure_state(const machine_config &mconfig, device_type type, const char *tag)
: alpha68k_V_state(mconfig, type, tag)
{}
void skyadventure(machine_config &config);
};
class gangwars_state : public alpha68k_V_state
{
public:
gangwars_state(const machine_config &mconfig, device_type type, const char *tag)
: alpha68k_V_state(mconfig, type, tag)
{}
void gangwars(machine_config &config);
};
/*
* Base class for HWs with 4bpp PROMs for colors
*/
class alpha68k_prom_state : public alpha68k_state
{
public:
@ -309,6 +385,7 @@ private:
void tnextspc_coin_counters_w(offs_t offset, u16 data);
void tnextspc_unknown_w(offs_t offset, u16 data);
void tnextspc_soundlatch_w(u8 data);
u16 sound_cpu_r();
};
/* game_id - used to deal with a few game specific situations */

View File

@ -33,12 +33,13 @@ void alpha68k_prom_state::palette_init(palette_device &palette) const
}
}
void alpha68k_state::flipscreen_w(int flip)
void alpha68k_II_state::flipscreen_w(int flip)
{
m_flipscreen = flip;
m_sprites->set_flip(flip);
}
void alpha68k_state::video_bank_w(u8 data)
void alpha68k_II_state::video_bank_w(u8 data)
{
if ((m_bank_base ^ data) & 0xf)
{
@ -49,7 +50,7 @@ void alpha68k_state::video_bank_w(u8 data)
/******************************************************************************/
TILE_GET_INFO_MEMBER(alpha68k_state::get_tile_info)
TILE_GET_INFO_MEMBER(alpha68k_II_state::get_tile_info)
{
const u8 tile = m_videoram[2 * tile_index] & 0xff;
const u8 attr = m_videoram[2 * tile_index + 1] & 0xff;
@ -59,7 +60,7 @@ TILE_GET_INFO_MEMBER(alpha68k_state::get_tile_info)
SET_TILE_INFO_MEMBER(0, tile | (m_bank_base << 8), color, opaque ? TILE_FORCE_LAYER0 : 0);
}
void alpha68k_state::videoram_w(offs_t offset, u16 data)
void alpha68k_II_state::videoram_w(offs_t offset, u16 data)
{
/* 8 bit RAM, upper & lower byte writes end up in the same place due to m68k byte smearing */
m_videoram[offset] = data & 0xff;
@ -67,242 +68,56 @@ void alpha68k_state::videoram_w(offs_t offset, u16 data)
m_fix_tilemap->mark_tile_dirty(offset / 2);
}
VIDEO_START_MEMBER(alpha68k_state,alpha68k)
VIDEO_START_MEMBER(alpha68k_II_state,alpha68k)
{
m_fix_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(alpha68k_state::get_tile_info),this), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
m_fix_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(alpha68k_II_state::get_tile_info),this), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
m_fix_tilemap->set_transparent_pen(0);
}
/******************************************************************************/
//AT
void alpha68k_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int j, int s, int e)
{
for (int offs = s; offs < e; offs += 0x40)
{
int my = m_spriteram[offs + 3 + (j << 1)];
int mx = m_spriteram[offs + 2 + (j << 1)] << 1 | my >> 15;
my = -my & 0x1ff;
mx = ((mx + 0x100) & 0x1ff) - 0x100;
if (j == 0 && s == 0x7c0)
my++;
//ZT
if (m_flipscreen)
{
mx = 240 - mx;
my = 240 - my;
}
for (int i = 0; i < 0x40; i += 2)
{
u16 tile = m_spriteram[offs + 1 + i + (0x800 * j) + 0x800];
const u8 color = m_spriteram[offs + i + (0x800 * j) + 0x800] & 0x7f;
int fy = tile & 0x8000;
int fx = tile & 0x4000;
tile &= 0x3fff;
if (m_flipscreen)
{
if (fx) fx = 0; else fx = 1;
if (fy) fy = 0; else fy = 1;
}
m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
tile,
color,
fx,fy,
mx,my,0);
if (m_flipscreen)
my = (my - 16) & 0x1ff;
else
my = (my + 16) & 0x1ff;
}
}
}
/******************************************************************************/
u32 alpha68k_state::screen_update_alpha68k_II(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
machine().tilemap().set_flip_all(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
bitmap.fill(2047, cliprect);
//AT
draw_sprites(bitmap, cliprect, 0, 0x07c0, 0x0800);
draw_sprites(bitmap, cliprect, 1, 0x0000, 0x0800);
draw_sprites(bitmap, cliprect, 2, 0x0000, 0x0800);
draw_sprites(bitmap, cliprect, 0, 0x0000, 0x07c0);
//ZT
m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}
/******************************************************************************/
/*
Video banking:
Write to these locations in this order for correct bank:
20 28 30 for Bank 0
60 28 30 for Bank 1
20 68 30 etc
60 68 30
20 28 70
60 28 70
20 68 70
60 68 70 for Bank 7
Actual data values written don't matter!
*/
/* Graphics flags? Not related to fix chars anyway */
WRITE_LINE_MEMBER(alpha68k_state::video_control2_w)
// TODO: sprite flip select as in snk68.cpp, palette bank for V games if they ever trigger it
WRITE_LINE_MEMBER(alpha68k_II_state::video_control2_w)
{
logerror("%s: Q2 changed to %d\n", machine().describe_context(), state);
}
WRITE_LINE_MEMBER(alpha68k_state::video_control3_w)
WRITE_LINE_MEMBER(alpha68k_II_state::video_control3_w)
{
logerror("%s: Q3 changed to %d\n", machine().describe_context(), state);
}
/******************************************************************************/
/*
* Alpha 68k V sprite system
* tile-based, with 8-bit accesses.
* Two banks, first at 0x0000-0x1000, second at 0x1000 until end of VRAM.
* First bank is processed by 64 bytes stepping starting from address $4,
* then once it reaches end it restarts at $8, finally at $c.
*
* 0x0000-0x1000
* [0]
* ???? ???? untested in POST, actually written to by Gang Wars (likely NOP)
* [1]
* XXXX XXXX lower X offset
* [2]
* X--- ---- upper X offset
* -*** ---- unknown, more fractional X?
* ---- ---Y upper Y offset
* [3]
* YYYY YYYY lower Y offset
*
* Second bank has the actual tile info, and is arranged in vertical strips.
* [0]
* ???? ???? untested in POST, actually written to by Sky Adventure (likely NOP)
* [1]
* cccc cccc color entry
* [2]
* uuu- ---- user selectable, either flipx/flipy or tile bank
* ---t tttt high tile offset
* [3]
* tttt tttt low tile offset
*
* TODO:
* - Currently lags compared to itself, examples:
* - player death animation has first frame with inverted horizontal halves;
* - stage 1 priest desyncs with background;
* - glitchy first frame on title screen;
* Given how this and the actual HW works it is pretty likely this having a consistent delay,
* however it isn't known how exactly DMA triggers, and one frame of bufferd spriteram isn't enough.
* - Why entry 0x7c0 requires a one line and a priority hack?
*
*/
void alpha68k_state::draw_sprites_V(bitmap_ind16 &bitmap, const rectangle &cliprect, int j, int s, int e, u16 fx_mask, u16 fy_mask, u16 sprite_mask)
void alpha68k_II_state::tile_callback(int &tile, int& fx, int& fy, int& region)
{
for (int offs = s; offs < e; offs += 0x40)
{
int my = m_spriteram[offs + 3 + (j << 1)];
int mx = m_spriteram[offs + 2 + (j << 1)] << 1 | my >> 15;
my = -my & 0x1ff;
mx = ((mx + 0x100) & 0x1ff) - 0x100;
// TODO: remove this hack
if (j == 0 && s == 0x7c0)
my++;
if (m_flipscreen)
{
mx = 240 - mx;
my = 240 - my;
}
for (int i = 0; i < 0x40; i += 2)
{
u16 tile = m_spriteram[offs + 1 + i + (0x800 * j) + 0x800];
const u8 color = m_spriteram[offs + 0 + i + (0x800 * j) + 0x800] & 0xff;
int fx = tile & fx_mask;
int fy = tile & fy_mask;
tile = tile & sprite_mask;
if (m_flipscreen)
{
if (fx) fx = 0; else fx = 1;
if (fy) fy = 0; else fy = 1;
}
// color 0 is actually selectable, cfr. Sky Adventure service mode or Gold Medalist player 1 status bar on long jump
// TODO: are there any actual sprite disable conditions?
m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
tile,
color,
fx,fy,
mx,my,0);
if (m_flipscreen)
my = (my - 16) & 0x1ff;
else
my = (my + 16) & 0x1ff;
}
}
fx = tile & 0x4000;
fy = tile & 0x8000;
tile &= 0x3fff;
region = 1;
}
#ifdef UNUSED_FUNCTION
// AT: *KLUDGE* fixes priest priority in level 1(could be a game bug)
// Update: it is a btanb according to PCB reference, priest effectively goes above big ship (!)
// left here for reference
if (m_spriteram[0x1bde] == 0x24 && (m_spriteram[0x1bdf] >> 8) == 0x3b)
void alpha68k_II_state::tile_callback_noflipx(int &tile, int& fx, int& fy, int& region)
{
draw_sprites_V(bitmap, cliprect, 2, 0x03c0, 0x0800, 0, 0x8000, 0x7fff);
draw_sprites_V(bitmap, cliprect, 2, 0x0000, 0x03c0, 0, 0x8000, 0x7fff);
fx = 0;
fy = tile & 0x8000;
tile &= 0x7fff;
region = 1;
}
else
#endif
u32 alpha68k_state::screen_update_alpha68k_V(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
void alpha68k_II_state::tile_callback_noflipy(int &tile, int& fx, int& fy, int& region)
{
// TODO: should be an user selectable feature instead of using the MCU ID, it's also repeated below.
bool is_skyadventure = (m_microcontroller_id == 0x8814);
const u16 flipxmask = is_skyadventure ? 0 : 0x8000;
const u16 flipymask = is_skyadventure ? 0x8000 : 0;
machine().tilemap().set_flip_all(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
bitmap.fill(4095, cliprect);
fx = tile & 0x8000;
fy = 0;
tile &= 0x7fff;
region = 1;
}
draw_sprites_V(bitmap, cliprect, 0, 0x07c0, 0x0800, flipxmask, flipymask, 0x7fff);
draw_sprites_V(bitmap, cliprect, 1, 0x0000, 0x0800, flipxmask, flipymask, 0x7fff);
draw_sprites_V(bitmap, cliprect, 2, 0x0000, 0x0800, flipxmask, flipymask, 0x7fff);
draw_sprites_V(bitmap, cliprect, 0, 0x0000, 0x07c0, flipxmask, flipymask, 0x7fff);
uint32_t alpha68k_II_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(m_backdrop_pen, cliprect);
m_sprites->draw_sprites_alt(bitmap, cliprect);
m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}
u32 alpha68k_state::screen_update_alpha68k_V_sb(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
machine().tilemap().set_flip_all(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
bitmap.fill(4095, cliprect);
draw_sprites_V(bitmap, cliprect, 0, 0x07c0, 0x0800, 0x4000, 0x8000, 0x3fff);
draw_sprites_V(bitmap, cliprect, 1, 0x0000, 0x0800, 0x4000, 0x8000, 0x3fff);
draw_sprites_V(bitmap, cliprect, 2, 0x0000, 0x0800, 0x4000, 0x8000, 0x3fff);
draw_sprites_V(bitmap, cliprect, 0, 0x0000, 0x07c0, 0x4000, 0x8000, 0x3fff);
m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}

View File

@ -1,7 +1,46 @@
// license:BSD-3-Clause
// copyright-holders:Bryan McPhail, Acho A. Tang, Nicola Salmoria
/*
* Alpha 68k II/V sprite system
* tile-based, with 8-bit accesses.
* Two banks, first at 0x0000-0x1000, second at 0x1000 until end of VRAM.
* First bank is processed by 64 bytes stepping starting from address $8,
* then once it reaches end it restarts at $c, finally at $4.
*
* 0x0000-0x1000
* [0]
* ???? ???? untested in POST, actually written to by Gang Wars (likely NOP)
* [1]
* XXXX XXXX lower X offset
* [2]
* X--- ---- upper X offset
* -*** ---- unknown, more fractional X?
* ---- ---Y upper Y offset
* [3]
* YYYY YYYY lower Y offset
*
* Second bank has the actual tile info, and is arranged in vertical strips.
* [0]
* ???? ???? untested in POST, actually written to by Sky Adventure (likely NOP)
* [1]
* cccc cccc color entry
* [2]
* uuu- ---- user selectable, either flipx/flipy or tile bank
* ---t tttt high tile offset
* [3]
* tttt tttt low tile offset
*
* TODO:
* - Currently lags compared to itself in Sky Adventure at least, examples:
* - player death animation has first frame with inverted horizontal halves;
* - stage 1 priest desyncs with background;
* - glitchy first frame on title screen;
* Given how this and the actual HW works it is pretty likely this having a consistent delay,
* however it isn't known how exactly DMA triggers, and one frame of bufferd spriteram isn't enough.
* - Why entry 0x7c0 requires a one line and a priority hack?
*
*/
/* SNK68 Sprites */
#include "emu.h"
#include "snk68_spr.h"
@ -62,22 +101,27 @@ WRITE16_MEMBER(snk68_spr_device::spriteram_w)
}
}
void snk68_spr_device::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int group)
void snk68_spr_device::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int group, u16 start_offset, u16 end_offset)
{
const uint16_t* tiledata = &m_spriteram[0x800*group];
const uint16_t* tiledata = &m_spriteram[0x800*group + start_offset];
bool const flip = m_flipscreen;
for (int offs = 0; offs < 0x800; offs += 0x40)
for (int offs = start_offset; offs < end_offset; offs += 0x40)
{
int mx = (m_spriteram[offs + 2*group] & 0xff) << 4;
int mx = (m_spriteram[offs + 2*group] & 0xff) << (16-m_xpos_shift);
int my = m_spriteram[offs + 2*group + 1];
int i;
mx = mx | (my >> 12);
// TODO: for some reason alpha68k wants this to be 15 instead of 12, different row/col arrangement?
mx = mx | (my >> m_xpos_shift);
mx = ((mx + 16) & 0x1ff) - 16;
my = -my;
// TODO: alpha68k games all wants this hack, why?
if (group == 1 && start_offset == 0x7c0)
my++;
if (flip)
{
@ -92,7 +136,7 @@ void snk68_spr_device::draw_sprites(bitmap_ind16 &bitmap, const rectangle &clipr
if (my <= cliprect.max_y && my + 15 >= cliprect.min_y)
{
int color = *(tiledata++) & 0x7f;
int color = *(tiledata++) & m_color_entry_mask;
int tile = *(tiledata++);
int fx = 0,fy = 0;
int region = 0;
@ -132,9 +176,18 @@ void snk68_spr_device::draw_sprites(bitmap_ind16 &bitmap, const rectangle &clipr
void snk68_spr_device::draw_sprites_all(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* This appears to be the correct priority order */
draw_sprites(bitmap, cliprect, 2);
draw_sprites(bitmap, cliprect, 3);
draw_sprites(bitmap, cliprect, 1);
draw_sprites(bitmap, cliprect, 2, 0, 0x800);
draw_sprites(bitmap, cliprect, 3, 0, 0x800);
draw_sprites(bitmap, cliprect, 1, 0, 0x800);
}
void snk68_spr_device::draw_sprites_alt(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// TODO: alpha68k priority, different vram accessors? Special meaning of bit 0 for my variable?
draw_sprites(bitmap, cliprect, 1, 0x7c0, 0x800);
draw_sprites(bitmap, cliprect, 2, 0x000, 0x800);
draw_sprites(bitmap, cliprect, 3, 0x000, 0x800);
draw_sprites(bitmap, cliprect, 1, 0x000, 0x7c0);
}
void snk68_spr_device::set_flip(bool flip)

View File

@ -19,11 +19,14 @@ public:
template <typename T> void set_gfxdecode_tag(T &&tag) { m_gfxdecode.set_tag(std::forward<T>(tag)); }
template <typename... T> void set_tile_indirect_cb(T &&... args) { m_newtilecb = snk68_tile_indirection_delegate(std::forward<T>(args)...); }
void set_no_partial() { m_partialupdates = 0; }
void set_xpos_shift(u8 data) { m_xpos_shift = data; }
void set_color_entry_mask(u16 data) { m_color_entry_mask = data; }
DECLARE_READ16_MEMBER(spriteram_r);
DECLARE_WRITE16_MEMBER(spriteram_w);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int group);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int group, u16 start_offset, u16 end_offset);
void draw_sprites_all(bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_sprites_alt(bitmap_ind16 &bitmap, const rectangle &cliprect);
snk68_tile_indirection_delegate m_newtilecb;
@ -40,6 +43,8 @@ private:
required_device<screen_device> m_screen;
bool m_flipscreen;
int m_partialupdates; // the original hardware needs this, the cloned hardware does not.
u8 m_xpos_shift;
u16 m_color_entry_mask;
};