summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2020-06-16 21:09:13 +0200
committer hap <happppp@users.noreply.github.com>2020-06-16 21:09:26 +0200
commitd34460d1ccf44446165e3b7a34322620967e9b7c (patch)
tree817df263b5e1e31d5121660b44c51aa176f1a9b7
parent1eca1509e1795d04593b2f2ac929f373c8726f05 (diff)
atarifb: improve interrupts, led multiplexing, sprite raster effects (nw)
-rw-r--r--src/emu/xtal.cpp2
-rw-r--r--src/mame/drivers/atarifb.cpp94
-rw-r--r--src/mame/drivers/firetrk.cpp2
-rw-r--r--src/mame/drivers/tubep.cpp2
-rw-r--r--src/mame/drivers/videopin.cpp16
-rw-r--r--src/mame/includes/atarifb.h43
-rw-r--r--src/mame/layout/abaseb.lay21
-rw-r--r--src/mame/layout/atarifb.lay21
-rw-r--r--src/mame/layout/atarifb4.lay25
-rw-r--r--src/mame/machine/atarifb.cpp125
-rw-r--r--src/mame/video/atarifb.cpp130
11 files changed, 237 insertions, 244 deletions
diff --git a/src/emu/xtal.cpp b/src/emu/xtal.cpp
index 6a70f660616..7e6227f9487 100644
--- a/src/emu/xtal.cpp
+++ b/src/emu/xtal.cpp
@@ -347,7 +347,7 @@ const double XTAL::known_xtals[] = {
28'480'000, /* 28.48_MHz_XTAL Chromatics CGC-7900 */
28'636'000, /* 28.636_MHz_XTAL Super Kaneko Nova System */
28'636'363, /* 28.636363_MHz_XTAL Later Leland games and Atari GT, Amiga NTSC, Raiden2 h/w (8x NTSC subcarrier)*/
- 28'640'000, /* 28.64_MHz_XTAL Fukki FG-1c AI AM-2 PCB */
+ 28'640'000, /* 28.64_MHz_XTAL Fuuki FG-1c AI AM-2 PCB */
28'700'000, /* 28.7_MHz_XTAL - */
29'376'000, /* 29.376_MHz_XTAL Qume QVT-103 */
29'491'200, /* 29.4912_MHz_XTAL Xerox Alto-II system clock (tagged 29.4MHz in the schematics) */
diff --git a/src/mame/drivers/atarifb.cpp b/src/mame/drivers/atarifb.cpp
index 127bfcbab2b..7b3887fe187 100644
--- a/src/mame/drivers/atarifb.cpp
+++ b/src/mame/drivers/atarifb.cpp
@@ -11,20 +11,10 @@
* Atari Baseball
* Atari Soccer
- Known issues:
- * The down marker sprite is multiplexed so that it will be drawn at the
- top and bottom of the screen. We fake this feature. Additionally, we
- draw it at a different location which seems to make more sense.
-
- * The play which is chosen is drawn in text at the top of the screen;
- no backdrop/overlay is supported yet. High quality artwork would be
- appreciated.
-
- * I'm not good at reading the schematics, so I'm unsure about the
- exact vblank duration. I'm pretty sure it is one of two values though.
-
- * The 4-player variation is slightly broken. I'm unsure of the
- LED multiplexing.
+ TODO:
+ * these are cocktail arcade cabs, should view be rotated?
+ * atarifb play-select LED sometimes remains on, or is this normal?
+ * confirm sprite 'colors' in soccer
****************************************************************************
@@ -118,29 +108,27 @@
/*************************************
*
- * Palette generation
+ * Interrupts
*
*************************************/
-void atarifb_state::atarifb_palette(palette_device &palette) const
+TIMER_DEVICE_CALLBACK_MEMBER(atarifb_state::interrupt)
+{
+ int scanline = param;
+ m_screen->update_partial(scanline - 1);
+
+ // periodic interrupts from _32V
+ // 4 interrupts per frame, including vblank irq
+ if (scanline != 0)
+ m_maincpu->set_input_line(0, ASSERT_LINE);
+
+ // LED latch is cleared
+ m_led_pwm->clear();
+}
+
+void atarifb_state::intack_w(uint8_t data)
{
- // chars
- palette.set_pen_color(0, rgb_t(0xff,0xff,0xff)); // white
- palette.set_pen_color(1, rgb_t(0x00,0x00,0x00)); // black
-
- // sprites
- palette.set_pen_color(2, rgb_t(0x40,0x40,0x40)); // dark grey (?) - used in Soccer only
- palette.set_pen_color(3, rgb_t(0xff,0xff,0xff)); // white
- palette.set_pen_color(4, rgb_t(0x40,0x40,0x40)); // dark grey (?) - used in Soccer only
- palette.set_pen_color(5, rgb_t(0x00,0x00,0x00)); // black
-
- // sprite masks
- palette.set_pen_color(6, rgb_t(0x40,0x40,0x40)); // dark grey (?) - used in Soccer only
- palette.set_pen_color(7, rgb_t(0x80,0x80,0x80)); // grey
- palette.set_pen_color(8, rgb_t(0x40,0x40,0x40)); // dark grey (?) - used in Soccer only
- palette.set_pen_color(9, rgb_t(0x00,0x00,0x00)); // black
- palette.set_pen_color(10, rgb_t(0x40,0x40,0x40)); // dark grey (?) - used in Soccer only
- palette.set_pen_color(11, rgb_t(0xff,0xff,0xff)); // white
+ m_maincpu->set_input_line(0, CLEAR_LINE);
}
@@ -164,7 +152,7 @@ void atarifb_state::atarifb_map(address_map &map)
map(0x2001, 0x2001).w(FUNC(atarifb_state::atarifb_out1_w)); /* OUT 1 */
map(0x2002, 0x2002).w(FUNC(atarifb_state::atarifb_out2_w)); /* OUT 2 */
map(0x2003, 0x2003).w(FUNC(atarifb_state::atarifb_out3_w)); /* OUT 3 */
- map(0x3000, 0x3000).noprw(); /* Interrupt Acknowledge */
+ map(0x3000, 0x3000).w(FUNC(atarifb_state::intack_w));
map(0x4000, 0x4000).r(FUNC(atarifb_state::atarifb_in0_r));
map(0x4002, 0x4002).r(FUNC(atarifb_state::atarifb_in2_r));
map(0x5000, 0x5000).w("watchdog", FUNC(watchdog_timer_device::reset_w));
@@ -185,7 +173,7 @@ void atarifb_state::atarifb4_map(address_map &map)
map(0x2001, 0x2001).w(FUNC(atarifb_state::atarifb4_out1_w)); /* OUT 1 */
map(0x2002, 0x2002).w(FUNC(atarifb_state::atarifb_out2_w)); /* OUT 2 */
map(0x2003, 0x2003).w(FUNC(atarifb_state::atarifb_out3_w)); /* OUT 3 */
- map(0x3000, 0x3000).noprw(); /* Interrupt Acknowledge */
+ map(0x3000, 0x3000).w(FUNC(atarifb_state::intack_w));
map(0x4000, 0x4000).r(FUNC(atarifb_state::atarifb4_in0_r));
map(0x4001, 0x4001).portr("EXTRA");
map(0x4002, 0x4002).r(FUNC(atarifb_state::atarifb4_in2_r));
@@ -207,7 +195,7 @@ void atarifb_state::abaseb_map(address_map &map)
map(0x2001, 0x2001).w(FUNC(atarifb_state::abaseb_out1_w)); /* OUT 1 */
map(0x2002, 0x2002).w(FUNC(atarifb_state::atarifb_out2_w)); /* OUT 2 */
map(0x2003, 0x2003).w(FUNC(atarifb_state::atarifb_out3_w)); /* OUT 3 */
- map(0x3000, 0x3000).noprw(); /* Interrupt Acknowledge */
+ map(0x3000, 0x3000).w(FUNC(atarifb_state::intack_w));
map(0x4000, 0x4000).r(FUNC(atarifb_state::atarifb_in0_r));
map(0x4002, 0x4002).r(FUNC(atarifb_state::atarifb_in2_r));
map(0x5000, 0x5000).w("watchdog", FUNC(watchdog_timer_device::reset_w));
@@ -227,7 +215,7 @@ void atarifb_state::soccer_map(address_map &map)
map(0x1000, 0x1000).writeonly().share("scroll_register"); /* OUT 0 */
map(0x1001, 0x1001).w(FUNC(atarifb_state::soccer_out1_w)); /* OUT 1 */
map(0x1002, 0x1002).w(FUNC(atarifb_state::soccer_out2_w)); /* OUT 2 */
- map(0x1004, 0x1004).nopw(); /* Interrupt Acknowledge */
+ map(0x1004, 0x1004).w(FUNC(atarifb_state::intack_w));
map(0x1005, 0x1005).w("watchdog", FUNC(watchdog_timer_device::reset_w));
map(0x1800, 0x1800).r(FUNC(atarifb_state::atarifb4_in0_r));
map(0x1801, 0x1801).portr("EXTRA");
@@ -493,16 +481,16 @@ static const gfx_layout spritemasklayout =
static GFXDECODE_START( gfx_atarifb )
- GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0x00, 0x01 ) /* offset into colors, # of colors */
- GFXDECODE_ENTRY( "gfx2", 0, fieldlayout, 0x02, 0x01 ) /* offset into colors, # of colors */
+ GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0x00, 0x01 )
+ GFXDECODE_ENTRY( "gfx2", 0, fieldlayout, 0x02, 0x02 )
GFXDECODE_END
static GFXDECODE_START( gfx_soccer )
- GFXDECODE_ENTRY( "gfx1", 0x0000, charlayout, 0x00, 0x01 ) /* offset into colors, # of colors */
- GFXDECODE_ENTRY( "gfx3", 0x0400, soccer_fieldlayout, 0x06, 0x01 ) /* offset into colors, # of colors */
- GFXDECODE_ENTRY( "gfx2", 0x0000, spritelayout, 0x02, 0x02 ) /* offset into colors, # of colors */
- GFXDECODE_ENTRY( "gfx3", 0x0000, spritemasklayout, 0x06, 0x03 ) /* offset into colors, # of colors */
+ GFXDECODE_ENTRY( "gfx1", 0x0000, charlayout, 0x00, 0x01 )
+ GFXDECODE_ENTRY( "gfx3", 0x0400, soccer_fieldlayout, 0x02, 0x01 )
+ GFXDECODE_ENTRY( "gfx2", 0x0000, spritelayout, 0x04, 0x02 )
+ GFXDECODE_ENTRY( "gfx3", 0x0000, spritemasklayout, 0x08, 0x03 )
GFXDECODE_END
@@ -517,7 +505,7 @@ void atarifb_state::machine_start()
{
m_leds.resolve();
- save_item(NAME(m_CTRLD));
+ save_item(NAME(m_ctrld));
save_item(NAME(m_sign_x_1));
save_item(NAME(m_sign_x_2));
save_item(NAME(m_sign_x_3));
@@ -538,7 +526,7 @@ void atarifb_state::machine_start()
void atarifb_state::machine_reset()
{
- m_CTRLD = 0;
+ m_ctrld = 0;
m_sign_x_1 = 0;
m_sign_y_1 = 0;
m_sign_x_2 = 0;
@@ -560,27 +548,26 @@ void atarifb_state::machine_reset()
void atarifb_state::atarifb(machine_config &config)
{
/* basic machine hardware */
- M6502(config, m_maincpu, 750000);
+ M6502(config, m_maincpu, 12.096_MHz_XTAL/16);
m_maincpu->set_addrmap(AS_PROGRAM, &atarifb_state::atarifb_map);
- m_maincpu->set_periodic_int(FUNC(atarifb_state::irq0_line_hold), attotime::from_hz(4*60));
+ m_maincpu->set_vblank_int("screen", FUNC(atarifb_state::irq0_line_assert)); // overrides irq_timer
+ TIMER(config, "irq_timer").configure_scanline(FUNC(atarifb_state::interrupt), "screen", 0, 64);
WATCHDOG_TIMER(config, "watchdog");
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
- m_screen->set_refresh_hz(60);
- m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2037) /* 16.3ms * 1/8 = 2037.5. Is it 1/8th or 3/32nds? (1528?) */);
- m_screen->set_size(38*8, 32*8);
- m_screen->set_visarea(0*8, 38*8-1, 1*8, 31*8-1);
+ m_screen->set_raw(12.096_MHz_XTAL/2, 384, 0, 304, 262, 8, 248);
m_screen->set_screen_update(FUNC(atarifb_state::screen_update_atarifb));
m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_atarifb);
- PALETTE(config, m_palette, FUNC(atarifb_state::atarifb_palette), 12);
+ PALETTE(config, m_palette, FUNC(atarifb_state::atarifb_palette), 14);
+
+ PWM_DISPLAY(config, m_led_pwm).set_size(3, 4);
/* sound hardware */
SPEAKER(config, "mono").front_center();
-
DISCRETE(config, m_discrete, atarifb_discrete).add_route(ALL_OUTPUTS, "mono", 0.18);
}
@@ -617,7 +604,6 @@ void atarifb_state::soccer(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &atarifb_state::soccer_map);
/* video hardware */
- m_screen->set_visarea(0*8, 38*8-1, 2*8, 32*8-1);
m_screen->set_screen_update(FUNC(atarifb_state::screen_update_soccer));
m_gfxdecode->set_info(gfx_soccer);
}
diff --git a/src/mame/drivers/firetrk.cpp b/src/mame/drivers/firetrk.cpp
index b19d3bb672a..36ceb9d8344 100644
--- a/src/mame/drivers/firetrk.cpp
+++ b/src/mame/drivers/firetrk.cpp
@@ -57,7 +57,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(firetrk_state::firetrk_scanline)
int scanline = param;
// periodic IRQs are generated by inverse 16V signal
- if ((scanline & 0x1f) == 0)
+ if ((scanline & 0x1f) == 0 && scanline != 0)
m_maincpu->pulse_input_line(0, attotime::from_hz(MASTER_CLOCK/2/64));
// vblank interrupt
diff --git a/src/mame/drivers/tubep.cpp b/src/mame/drivers/tubep.cpp
index 75c2fd7d8cb..70e3886bced 100644
--- a/src/mame/drivers/tubep.cpp
+++ b/src/mame/drivers/tubep.cpp
@@ -110,7 +110,7 @@ TP-S.1 TP-S.2 TP-S.3 TP-B.1 8212 TP-B.2 TP-B.3 TP-B.4
#include "sound/msm5205.h"
#include "speaker.h"
-#define LOG_IRQ (1U << 0)
+#define LOG_IRQ (1U << 1)
//#define VERBOSE (LOG_IRQ)
#include "logmacro.h"
diff --git a/src/mame/drivers/videopin.cpp b/src/mame/drivers/videopin.cpp
index 06b2bd74b9b..5815f98bca3 100644
--- a/src/mame/drivers/videopin.cpp
+++ b/src/mame/drivers/videopin.cpp
@@ -8,12 +8,12 @@
Known issues:
-videopin
-- plunger doesn't work in test mode - bug in the game code?
+ videopin
+ - plunger doesn't work in test mode - bug in the game code?
-solarwar
-- coins not working (free play is default for now)
-- needs correct layout file
+ solarwar
+ - coins not working (free play is default for now)
+ - needs correct layout file
*************************************************************************/
@@ -486,6 +486,6 @@ ROM_END
*
*************************************/
-GAMEL( 1979, videopin, 0, videopin, videopin, videopin_state, empty_init, ROT270, "Atari", "Video Pinball (16 PROMs version)", MACHINE_SUPPORTS_SAVE, layout_videopin )
-GAMEL( 1979, videopina, videopin, videopin, videopin, videopin_state, empty_init, ROT270, "Atari", "Video Pinball (4 ROMs version)", MACHINE_SUPPORTS_SAVE, layout_videopin )
-GAMEL( 1979, solarwar, 0, videopin, solarwar, videopin_state, empty_init, ROT270, "Atari", "Solar War", MACHINE_SUPPORTS_SAVE, layout_videopin )
+GAMEL( 1979, videopin, 0, videopin, videopin, videopin_state, empty_init, ROT270, "Atari", "Video Pinball (16 PROMs version)", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK, layout_videopin )
+GAMEL( 1979, videopina, videopin, videopin, videopin, videopin_state, empty_init, ROT270, "Atari", "Video Pinball (4 ROMs version)", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK, layout_videopin )
+GAMEL( 1979, solarwar, 0, videopin, solarwar, videopin_state, empty_init, ROT270, "Atari", "Solar War", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK, layout_videopin )
diff --git a/src/mame/includes/atarifb.h b/src/mame/includes/atarifb.h
index 738fb508096..00a3fc05032 100644
--- a/src/mame/includes/atarifb.h
+++ b/src/mame/includes/atarifb.h
@@ -5,12 +5,16 @@
Atari Football hardware
*************************************************************************/
+
#ifndef MAME_INCLUDES_ATARIFB_H
#define MAME_INCLUDES_ATARIFB_H
#pragma once
+#include "machine/timer.h"
#include "sound/discrete.h"
+#include "video/pwm.h"
+
#include "emupal.h"
#include "screen.h"
#include "tilemap.h"
@@ -29,19 +33,21 @@ class atarifb_state : public driver_device
public:
atarifb_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
- m_alphap1_videoram(*this, "p1_videoram"),
- m_alphap2_videoram(*this, "p2_videoram"),
- m_field_videoram(*this, "field_videoram"),
- m_spriteram(*this, "spriteram"),
- m_scroll_register(*this, "scroll_register"),
m_maincpu(*this, "maincpu"),
m_discrete(*this, "discrete"),
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
- m_leds(*this, "led%u", 0U)
+ m_led_pwm(*this, "led_pwm"),
+ m_leds(*this, "led%u", 0U),
+ m_alphap1_videoram(*this, "p1_videoram"),
+ m_alphap2_videoram(*this, "p2_videoram"),
+ m_field_videoram(*this, "field_videoram"),
+ m_spriteram(*this, "spriteram"),
+ m_scroll_register(*this, "scroll_register")
{ }
+ void intack_w(uint8_t data);
void atarifb_out1_w(uint8_t data);
void atarifb4_out1_w(uint8_t data);
void abaseb_out1_w(uint8_t data);
@@ -65,7 +71,8 @@ public:
uint32_t screen_update_soccer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void get_tile_info_common( tile_data &tileinfo, tilemap_memory_index tile_index, uint8_t *alpha_videoram );
void draw_playfield_and_alpha( bitmap_ind16 &bitmap, const rectangle &cliprect, int playfield_x_offset, int playfield_y_offset );
- void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect, int gfx, int is_soccer );
+ void draw_sprites_atarifb( bitmap_ind16 &bitmap, const rectangle &cliprect );
+ void draw_sprites_soccer( bitmap_ind16 &bitmap, const rectangle &cliprect );
void atarifb4(machine_config &config);
void atarifb(machine_config &config);
void soccer(machine_config &config);
@@ -80,6 +87,18 @@ protected:
virtual void machine_reset() override;
virtual void video_start() override;
+ /* devices */
+ required_device<cpu_device> m_maincpu;
+ required_device<discrete_device> m_discrete;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<screen_device> m_screen;
+ required_device<palette_device> m_palette;
+ required_device<pwm_display_device> m_led_pwm;
+
+ output_finder<2> m_leds;
+
+ TIMER_DEVICE_CALLBACK_MEMBER(interrupt);
+
/* video-related */
required_shared_ptr<uint8_t> m_alphap1_videoram;
required_shared_ptr<uint8_t> m_alphap2_videoram;
@@ -92,7 +111,7 @@ protected:
tilemap_t *m_field_tilemap;
/* sound-related */
- int m_CTRLD;
+ int m_ctrld;
int m_sign_x_1;
int m_sign_y_1;
int m_sign_x_2;
@@ -109,14 +128,6 @@ protected:
int m_counter_y_in2;
int m_counter_x_in2b;
int m_counter_y_in2b;
-
- /* devices */
- required_device<cpu_device> m_maincpu;
- required_device<discrete_device> m_discrete;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<screen_device> m_screen;
- required_device<palette_device> m_palette;
- output_finder<2> m_leds;
};
//----------- defined in audio/atarifb.cpp -----------
diff --git a/src/mame/layout/abaseb.lay b/src/mame/layout/abaseb.lay
index 49968d8d928..2d93b3d8865 100644
--- a/src/mame/layout/abaseb.lay
+++ b/src/mame/layout/abaseb.lay
@@ -3,6 +3,9 @@
license:CC0
-->
<mamelayout version="2">
+
+<!-- simplified layout for the leds (play-select leds are unused according to manual) -->
+
<element name="rswing" defstate="0">
<rect state="1">
<color red="0.0" green="0.0" blue="0.0" />
@@ -43,32 +46,32 @@ license:CC0
</text>
</element>
- <view name="Lamps">
+ <view name="Internal Layout">
<screen index="0">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
- <bezel name="ledleft0" element="rswing">
+ <bezel name="0.0" element="rswing">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledleft1" element="lswing">
+ <bezel name="0.1" element="lswing">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledleft2" element="rbunt">
+ <bezel name="0.2" element="rbunt">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledleft3" element="lbunt">
+ <bezel name="0.3" element="lbunt">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright0" element="rswing">
+ <bezel name="2.0" element="rswing">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright1" element="lswing">
+ <bezel name="2.1" element="lswing">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright2" element="rbunt">
+ <bezel name="2.2" element="rbunt">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright3" element="lbunt">
+ <bezel name="2.3" element="lbunt">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
</view>
diff --git a/src/mame/layout/atarifb.lay b/src/mame/layout/atarifb.lay
index 8ee7d0a7f1a..967fb8fac56 100644
--- a/src/mame/layout/atarifb.lay
+++ b/src/mame/layout/atarifb.lay
@@ -3,6 +3,9 @@
license:CC0
-->
<mamelayout version="2">
+
+<!-- simplified layout for the leds, play-select leds would be on 1.0 and 1.1 -->
+
<element name="sweep" defstate="0">
<rect state="1">
<color red="0.0" green="0.0" blue="0.0" />
@@ -43,32 +46,32 @@ license:CC0
</text>
</element>
- <view name="Lamps">
+ <view name="Internal Layout">
<screen index="0">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
- <bezel name="ledleft0" element="sweep">
+ <bezel name="0.0" element="sweep">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledleft1" element="keeper">
+ <bezel name="0.1" element="keeper">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledleft2" element="bomb">
+ <bezel name="0.2" element="bomb">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledleft3" element="down">
+ <bezel name="0.3" element="down">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright0" element="sweep">
+ <bezel name="2.0" element="sweep">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright1" element="keeper">
+ <bezel name="2.1" element="keeper">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright2" element="bomb">
+ <bezel name="2.2" element="bomb">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright3" element="down">
+ <bezel name="2.3" element="down">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
</view>
diff --git a/src/mame/layout/atarifb4.lay b/src/mame/layout/atarifb4.lay
index 8d1e6bc8c99..f2e9df0f138 100644
--- a/src/mame/layout/atarifb4.lay
+++ b/src/mame/layout/atarifb4.lay
@@ -3,6 +3,9 @@
license:CC0
-->
<mamelayout version="2">
+
+<!-- simplified layout for the leds, play-select leds would be on 1.1 and 1.3 -->
+
<element name="out" defstate="0">
<rect state="1">
<color red="0.0" green="0.0" blue="0.0" />
@@ -53,38 +56,38 @@ license:CC0
</text>
</element>
- <view name="Lamps">
+ <view name="Internal Layout">
<screen index="0">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
- <bezel name="ledleft0" element="out">
+ <bezel name="0.0" element="out">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledleft1" element="in">
+ <bezel name="0.1" element="in">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledleft2" element="bomb">
+ <bezel name="0.2" element="bomb">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledleft3" element="down">
+ <bezel name="0.3" element="down">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledleft4" element="kick">
+ <bezel name="1.0" element="kick">
<bounds x="0" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright0" element="out">
+ <bezel name="2.0" element="out">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright1" element="in">
+ <bezel name="2.1" element="in">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright2" element="bomb">
+ <bezel name="2.2" element="bomb">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright3" element="down">
+ <bezel name="2.3" element="down">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
- <bezel name="ledright4" element="kick">
+ <bezel name="1.2" element="kick">
<bounds x="2" y="-0.2" width="2" height="0.2" />
</bezel>
</view>
diff --git a/src/mame/machine/atarifb.cpp b/src/mame/machine/atarifb.cpp
index 74a5e59aa79..5c31ae29be3 100644
--- a/src/mame/machine/atarifb.cpp
+++ b/src/mame/machine/atarifb.cpp
@@ -11,25 +11,31 @@
#include "sound/discrete.h"
+/*************************************
+ *
+ * Output ports
+ *
+ *************************************/
+
void atarifb_state::atarifb_out1_w(uint8_t data)
{
- m_CTRLD = data;
+ m_ctrld = data;
- m_discrete->write(ATARIFB_WHISTLE_EN, data & 0x01); // Whistle
- m_discrete->write(ATARIFB_HIT_EN, data & 0x02); // Hit
- m_discrete->write(ATARIFB_ATTRACT_EN, data & 0x10); // Attract
- m_discrete->write(ATARIFB_NOISE_EN, data & 0x04); // Noise Enable / Kicker
+ m_discrete->write(ATARIFB_WHISTLE_EN, data & 0x01); // Whistle
+ m_discrete->write(ATARIFB_HIT_EN, data & 0x02); // Hit
+ m_discrete->write(ATARIFB_ATTRACT_EN, data & 0x10); // Attract
+ m_discrete->write(ATARIFB_NOISE_EN, data & 0x04); // Noise Enable / Kicker
}
void atarifb_state::atarifb4_out1_w(uint8_t data)
{
- m_CTRLD = data;
+ m_ctrld = data;
- m_discrete->write(ATARIFB_WHISTLE_EN, data & 0x01); // Whistle
- m_discrete->write(ATARIFB_HIT_EN, data & 0x02); // Hit
- m_discrete->write(ATARIFB_ATTRACT_EN, data & 0x10); // Attract
- m_discrete->write(ATARIFB_NOISE_EN, data & 0x04); // Noise Enable / Kicker
+ m_discrete->write(ATARIFB_WHISTLE_EN, data & 0x01); // Whistle
+ m_discrete->write(ATARIFB_HIT_EN, data & 0x02); // Hit
+ m_discrete->write(ATARIFB_ATTRACT_EN, data & 0x10); // Attract
+ m_discrete->write(ATARIFB_NOISE_EN, data & 0x04); // Noise Enable / Kicker
machine().bookkeeping().coin_counter_w(1, data & 0x80);
}
@@ -37,46 +43,36 @@ void atarifb_state::atarifb4_out1_w(uint8_t data)
void atarifb_state::abaseb_out1_w(uint8_t data)
{
- m_CTRLD = data;
+ m_ctrld = data;
- m_discrete->write(ATARIFB_WHISTLE_EN, data & 0x01); // Whistle
- m_discrete->write(ATARIFB_HIT_EN, data & 0x02); // Hit
- m_discrete->write(ATARIFB_ATTRACT_EN, data & 0x10); // Attract
- m_discrete->write(ATARIFB_NOISE_EN, data & 0x04); // Noise Enable / Kicker
+ m_discrete->write(ATARIFB_WHISTLE_EN, data & 0x01); // Whistle
+ m_discrete->write(ATARIFB_HIT_EN, data & 0x02); // Hit
+ m_discrete->write(ATARIFB_ATTRACT_EN, data & 0x10); // Attract
+ m_discrete->write(ATARIFB_NOISE_EN, data & 0x04); // Noise Enable / Kicker
- if (data & 0x80)
- {
- /* Invert video */
- m_palette->set_pen_color(1, rgb_t(0x00,0x00,0x00)); /* black */
- m_palette->set_pen_color(0, rgb_t(0xff,0xff,0xff)); /* white */
- }
- else
- {
- /* Regular video */
- m_palette->set_pen_color(0, rgb_t(0x00,0x00,0x00)); /* black */
- m_palette->set_pen_color(1, rgb_t(0xff,0xff,0xff)); /* white */
- }
+ // Invert Video
+ m_palette->set_pen_color(BIT(data, 7) ^ 0, rgb_t::white());
+ m_palette->set_pen_color(BIT(data, 7) ^ 1, rgb_t::black());
}
-
void atarifb_state::soccer_out1_w(uint8_t data)
{
- m_CTRLD = data;
+ m_ctrld = data;
/* bit 0 = whistle */
/* bit 1 = hit */
/* bit 2 = kicker */
/* bit 3 = unused */
- /* bit 4 = 2/4 Player LED */ // Say what?
+ /* bit 4 = 2/4 Player LED */
/* bit 5-6 = trackball CTRL bits */
/* bit 7 = Rule LED */
- m_discrete->write(ATARIFB_WHISTLE_EN, data & 0x01); // Whistle
- m_discrete->write(ATARIFB_HIT_EN, data & 0x02); // Hit
- m_discrete->write(ATARIFB_ATTRACT_EN, data & 0x10); // Attract
- m_discrete->write(ATARIFB_NOISE_EN, data & 0x04); // Noise Enable / Kicker
+ m_discrete->write(ATARIFB_WHISTLE_EN, data & 0x01); // Whistle
+ m_discrete->write(ATARIFB_HIT_EN, data & 0x02); // Hit
+ m_discrete->write(ATARIFB_ATTRACT_EN, data & 0x10); // Attract
+ m_discrete->write(ATARIFB_NOISE_EN, data & 0x04); // Noise Enable / Kicker
-// m_leds[0] = BIT(data, 4); // !!!!!!!!!! Is this correct????
+ m_leds[0] = BIT(data, 4);
m_leds[1] = BIT(data, 7);
}
@@ -88,7 +84,6 @@ void atarifb_state::atarifb_out2_w(uint8_t data)
machine().bookkeeping().coin_counter_w(0, data & 0x10);
}
-
void atarifb_state::soccer_out2_w(uint8_t data)
{
m_discrete->write(ATARIFB_CROWD_DATA, data & 0x0f); // Crowd
@@ -99,44 +94,28 @@ void atarifb_state::soccer_out2_w(uint8_t data)
}
-
-/*************************************
- *
- * LED control
- *
- *************************************/
-
-/* FIXME: almost surely not tied with screen vertical position */
void atarifb_state::atarifb_out3_w(uint8_t data)
{
- int loop = m_screen->vpos() >= 123;
+ // 64V and 128V to 7442 to LED anodes (output 0 unused)
+ int led_select = m_screen->vpos() >> 6 & 3;
- switch (loop)
- {
- case 0x00:
- /* Player 1 play select lamp */
- output().set_value("ledleft0", (data >> 0) & 1);
- output().set_value("ledleft1", (data >> 1) & 1);
- output().set_value("ledleft2", (data >> 2) & 1);
- output().set_value("ledleft3", (data >> 3) & 1);
- output().set_value("ledleft4", (data >> 4) & 1);
- break;
- case 0x01:
- /* Player 2 play select lamp */
- output().set_value("ledright0", (data >> 0) & 1);
- output().set_value("ledright1", (data >> 1) & 1);
- output().set_value("ledright2", (data >> 2) & 1);
- output().set_value("ledright3", (data >> 3) & 1);
- output().set_value("ledright4", (data >> 4) & 1);
- break;
- }
-// logerror("out3_w, %02x:%02x\n", loop, data);
+ // bit 0-3 = LED cathodes
+ // bit 4 = atarifb4 4-player LED
+ m_led_pwm->matrix((1 << led_select) >> 1, data & 0xf);
+ m_leds[0] = BIT(data, 4);
}
+
+/*************************************
+ *
+ * Input ports
+ *
+ *************************************/
+
uint8_t atarifb_state::atarifb_in0_r()
{
- if ((m_CTRLD & 0x20) == 0x00)
+ if ((m_ctrld & 0x20) == 0x00)
{
int val;
@@ -173,7 +152,7 @@ uint8_t atarifb_state::atarifb_in0_r()
uint8_t atarifb_state::atarifb_in2_r()
{
- if ((m_CTRLD & 0x20) == 0x00)
+ if ((m_ctrld & 0x20) == 0x00)
{
return ioport("IN1")->read();
}
@@ -203,7 +182,7 @@ uint8_t atarifb_state::atarifb_in2_r()
uint8_t atarifb_state::atarifb4_in0_r()
{
/* LD1 and LD2 low, return sign bits */
- if ((m_CTRLD & 0x60) == 0x00)
+ if ((m_ctrld & 0x60) == 0x00)
{
int val;
@@ -217,7 +196,7 @@ uint8_t atarifb_state::atarifb4_in0_r()
(m_sign_y_1 >> 0);
return val;
}
- else if ((m_CTRLD & 0x60) == 0x60)
+ else if ((m_ctrld & 0x60) == 0x60)
/* LD1 and LD2 both high, return Team 1 right player (player 1) */
{
int new_x, new_y;
@@ -239,7 +218,7 @@ uint8_t atarifb_state::atarifb4_in0_r()
return (((m_counter_y_in0 & 0x0f) << 4) | (m_counter_x_in0 & 0x0f));
}
- else if ((m_CTRLD & 0x60) == 0x40)
+ else if ((m_ctrld & 0x60) == 0x40)
/* LD1 high, LD2 low, return Team 1 left player (player 2) */
{
int new_x, new_y;
@@ -268,11 +247,11 @@ uint8_t atarifb_state::atarifb4_in0_r()
uint8_t atarifb_state::atarifb4_in2_r()
{
- if ((m_CTRLD & 0x40) == 0x00)
+ if ((m_ctrld & 0x40) == 0x00)
{
return ioport("IN1")->read();
}
- else if ((m_CTRLD & 0x60) == 0x60)
+ else if ((m_ctrld & 0x60) == 0x60)
/* LD1 and LD2 both high, return Team 2 right player (player 3) */
{
int new_x, new_y;
@@ -294,7 +273,7 @@ uint8_t atarifb_state::atarifb4_in2_r()
return (((m_counter_y_in2 & 0x0f) << 4) | (m_counter_x_in2 & 0x0f));
}
- else if ((m_CTRLD & 0x60) == 0x40)
+ else if ((m_ctrld & 0x60) == 0x40)
/* LD1 high, LD2 low, return Team 2 left player (player 4) */
{
int new_x, new_y;
diff --git a/src/mame/video/atarifb.cpp b/src/mame/video/atarifb.cpp
index b773aa60c2d..3cd865fb978 100644
--- a/src/mame/video/atarifb.cpp
+++ b/src/mame/video/atarifb.cpp
@@ -12,6 +12,39 @@
/*************************************
*
+ * Palette generation
+ *
+ *************************************/
+
+void atarifb_state::atarifb_palette(palette_device &palette) const
+{
+ // chars
+ palette.set_pen_color(0, rgb_t(0xff,0xff,0xff));
+ palette.set_pen_color(1, rgb_t(0x00,0x00,0x00));
+
+ // field
+ palette.set_pen_color(2, rgb_t(0x40,0x40,0x40));
+ palette.set_pen_color(3, rgb_t(0xc0,0xc0,0xc0));
+
+ // sprites
+ palette.set_pen_color(4, rgb_t(0x40,0x40,0x40));
+ palette.set_pen_color(5, rgb_t(0xff,0xff,0xff));
+ palette.set_pen_color(6, rgb_t(0x40,0x40,0x40));
+ palette.set_pen_color(7, rgb_t(0x00,0x00,0x00));
+
+ // sprite masks
+ palette.set_pen_color(8, rgb_t(0x40,0x40,0x40));
+ palette.set_pen_color(9, rgb_t(0x80,0x80,0x80));
+ palette.set_pen_color(10, rgb_t(0x40,0x40,0x40));
+ palette.set_pen_color(11, rgb_t(0x00,0x00,0x00));
+ palette.set_pen_color(12, rgb_t(0x40,0x40,0x40));
+ palette.set_pen_color(13, rgb_t(0xff,0xff,0xff));
+}
+
+
+
+/*************************************
+ *
* Tilemap callbacks
*
*************************************/
@@ -51,7 +84,6 @@ TILE_GET_INFO_MEMBER(atarifb_state::field_get_tile_info)
-
/*************************************
*
* Video RAM writes
@@ -94,10 +126,11 @@ void atarifb_state::video_start()
}
-
void atarifb_state::draw_playfield_and_alpha( bitmap_ind16 &bitmap, const rectangle &cliprect, int playfield_x_offset, int playfield_y_offset )
{
- const rectangle bigfield_area(4 * 8, 34 * 8 - 1, 0 * 8, 32 * 8 - 1);
+ bitmap.fill(1, cliprect);
+ rectangle clip(4 * 8, 34 * 8 - 1, 0 * 8, 32 * 8 - 1);
+ clip &= cliprect;
int scroll_x[1];
int scroll_y[1];
@@ -107,64 +140,47 @@ void atarifb_state::draw_playfield_and_alpha( bitmap_ind16 &bitmap, const rectan
copybitmap(bitmap, m_alpha1_tilemap->pixmap(), 0, 0, 35*8, 1*8, cliprect);
copybitmap(bitmap, m_alpha2_tilemap->pixmap(), 0, 0, 0*8, 1*8, cliprect);
- copyscrollbitmap(bitmap, m_field_tilemap->pixmap(), 1, scroll_x, 1, scroll_y, bigfield_area);
+ copyscrollbitmap(bitmap, m_field_tilemap->pixmap(), 1, scroll_x, 1, scroll_y, clip);
}
-void atarifb_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect, int gfx, int is_soccer )
+void atarifb_state::draw_sprites_atarifb( bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- const rectangle bigfield_area(4 * 8, 34 * 8 - 1, 0 * 8, 32 * 8 - 1);
-
- int obj;
+ rectangle clip(4 * 8, 34 * 8 - 1, 0 * 8, 32 * 8 - 1);
+ clip &= cliprect;
- for (obj = 0; obj < 16; obj++)
+ for (int obj = 0; obj < 16; obj++)
{
- int charcode;
- int flipx, flipy;
- int sx, sy;
- int shade = 0;
+ int charcode = m_spriteram[obj * 2] & 0x3f;
+ int flipx = (m_spriteram[obj * 2] & 0x40);
+ int flipy = (m_spriteram[obj * 2] & 0x80);
+ int sx = m_spriteram[obj * 2 + 0x20] + 8 * 3;
+ int sy = 256 - m_spriteram[obj * 2 + 1];
+
+ m_gfxdecode->gfx(1)->transpen(bitmap, clip, charcode, 1, flipx, flipy, sx, sy, 0);
+ }
+}
- sy = 255 - m_spriteram[obj * 2 + 1];
- if (sy == 255)
- continue;
+void atarifb_state::draw_sprites_soccer( bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ rectangle clip(4 * 8, 34 * 8 - 1, 0 * 8, 32 * 8 - 1);
+ clip &= cliprect;
- charcode = m_spriteram[obj * 2] & 0x3f;
- flipx = (m_spriteram[obj * 2] & 0x40);
- flipy = (m_spriteram[obj * 2] & 0x80);
- sx = m_spriteram[obj * 2 + 0x20] + 8 * 3;
+ for (int obj = 0; obj < 16; obj++)
+ {
+ int charcode = m_spriteram[obj * 2] & 0x3f;
+ int flipx = (m_spriteram[obj * 2] & 0x40);
+ int flipy = (m_spriteram[obj * 2] & 0x80);
+ int sx = m_spriteram[obj * 2 + 0x20] + 8 * 3;
+ int sy = 256 - m_spriteram[obj * 2 + 1] - 8;
- /* Note on Atari Soccer: */
/* There are 3 sets of 2 bits each, where the 2 bits represent */
/* black, dk grey, grey and white. I think the 3 sets determine the */
/* color of each bit in the sprite, but I haven't implemented it that way. */
- if (is_soccer)
- {
- shade = ((m_spriteram[obj * 2 + 1 + 0x20]) & 0x07);
-
- m_gfxdecode->gfx(gfx + 1)->transpen(bitmap,bigfield_area,
- charcode, shade,
- flipx, flipy, sx, sy, 0);
-
- shade = ((m_spriteram[obj * 2 + 1 + 0x20]) & 0x08) >> 3;
- }
-
- m_gfxdecode->gfx(gfx)->transpen(bitmap,bigfield_area,
- charcode, shade,
- flipx, flipy, sx, sy, 0);
-
- /* If this isn't soccer, handle the multiplexed sprites */
- if (!is_soccer)
- {
- /* The down markers are multiplexed by altering the y location during */
- /* mid-screen. We'll fake it by essentially doing the same thing here. */
- if ((charcode == 0x11) && (sy == 0x07))
- {
- sy = 0xf1; /* When multiplexed, it's 0x10...why? */
- m_gfxdecode->gfx(gfx)->transpen(bitmap,bigfield_area,
- charcode, 0,
- flipx, flipy, sx, sy, 0);
- }
- }
+ int shade = m_spriteram[obj * 2 + 1 + 0x20];
+
+ m_gfxdecode->gfx(3)->transpen(bitmap, clip, charcode, shade & 7, flipx, flipy, sx, sy, 0);
+ m_gfxdecode->gfx(2)->transpen(bitmap, clip, charcode, shade >> 3 & 1, flipx, flipy, sx, sy, 0);
}
}
@@ -172,28 +188,20 @@ void atarifb_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprec
uint32_t atarifb_state::screen_update_atarifb(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
draw_playfield_and_alpha(bitmap, cliprect, 0, 0);
-
- draw_sprites(bitmap, cliprect, 1, 0);
-
+ draw_sprites_atarifb(bitmap, cliprect);
return 0;
}
-
uint32_t atarifb_state::screen_update_abaseb(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
draw_playfield_and_alpha(bitmap, cliprect, -8, 0);
-
- draw_sprites(bitmap, cliprect, 1, 0);
-
+ draw_sprites_atarifb(bitmap, cliprect);
return 0;
}
-
uint32_t atarifb_state::screen_update_soccer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- draw_playfield_and_alpha(bitmap, cliprect, 0, 8);
-
- draw_sprites(bitmap, cliprect, 2, 1);
-
+ draw_playfield_and_alpha(bitmap, cliprect, 0, 0);
+ draw_sprites_soccer(bitmap, cliprect);
return 0;
}