diff options
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 |
commit | d34460d1ccf44446165e3b7a34322620967e9b7c (patch) | |
tree | 817df263b5e1e31d5121660b44c51aa176f1a9b7 | |
parent | 1eca1509e1795d04593b2f2ac929f373c8726f05 (diff) |
atarifb: improve interrupts, led multiplexing, sprite raster effects (nw)
-rw-r--r-- | src/emu/xtal.cpp | 2 | ||||
-rw-r--r-- | src/mame/drivers/atarifb.cpp | 94 | ||||
-rw-r--r-- | src/mame/drivers/firetrk.cpp | 2 | ||||
-rw-r--r-- | src/mame/drivers/tubep.cpp | 2 | ||||
-rw-r--r-- | src/mame/drivers/videopin.cpp | 16 | ||||
-rw-r--r-- | src/mame/includes/atarifb.h | 43 | ||||
-rw-r--r-- | src/mame/layout/abaseb.lay | 21 | ||||
-rw-r--r-- | src/mame/layout/atarifb.lay | 21 | ||||
-rw-r--r-- | src/mame/layout/atarifb4.lay | 25 | ||||
-rw-r--r-- | src/mame/machine/atarifb.cpp | 125 | ||||
-rw-r--r-- | src/mame/video/atarifb.cpp | 130 |
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; } |