summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/nasco/suprgolf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/nasco/suprgolf.cpp')
-rw-r--r--src/mame/nasco/suprgolf.cpp220
1 files changed, 110 insertions, 110 deletions
diff --git a/src/mame/nasco/suprgolf.cpp b/src/mame/nasco/suprgolf.cpp
index 7cf3a5d720c..cd28a469310 100644
--- a/src/mame/nasco/suprgolf.cpp
+++ b/src/mame/nasco/suprgolf.cpp
@@ -1,25 +1,33 @@
// license:LGPL-2.1+
// copyright-holders:Angelo Salese, Tomasz Slanina
-/************************************************************************************
+/**************************************************************************************************
Super Crowns Golf (c) 1989 Nasco Japan
driver by Tomasz Slanina & Angelo Salese
TODO:
- - understand what needs to be modified for the gfxs;
- - Some weird framebuffer vertical gaps with some object, namely the green and the
- trees (zooming?)
+ - framebuffer handling is exotic and definitely not right, it is unknown how the HW really
+ arranges for RMW drawing, and how the pens really mix/if they are readable:
+ \- Polygons won't fill properly without a ROM patch (which actually sets up BG bank & 0x08,
+ readback correction?). Note that wrong handling of the area will make the game to crash.
+ \- Uneven vertical gaps with some object, namely the green and the trees (RMW extension? Wrong
+ readback?)
+ \- Map display arrow direction (transparency) and ball plot tracing;
+ \- Mixing, map display may as well go above tilemap but that normally breaks club / ball
+ \- Color of the ball (green) during attract mode how to play screen;
+ \- Display in cocktail mode;
- not sure if the analog inputs are handled correctly;
- - Fix the framebuffer display in cocktail mode;
+ - Confirm ADPCM hookup.
- Albatross: controls.
+
Notes:
- The game uses special control panel with 1 golf club shaped device to select shot
strength (0,1,2,3), and 6 buttons (direction L&R, select angle of club head, club
select, shot, and power to use items). -YO
-************************************************************************************/
+**************************************************************************************************/
#include "emu.h"
#include "cpu/z80/z80.h"
@@ -37,17 +45,22 @@ namespace {
class suprgolf_state : public driver_device
{
public:
- suprgolf_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_msm(*this, "msm"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette"),
- m_videoram(*this, "videoram")
+ suprgolf_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_msm(*this, "msm")
+ , m_gfxdecode(*this, "gfxdecode")
+ , m_palette(*this, "palette")
+ , m_videoram(*this, "videoram")
+ , m_paletteram(*this, "paletteram")
+ , m_vram_palette_view(*this, "vram_palette_view")
{ }
void suprgolf(machine_config &config);
+ void init_suprgolf();
+ void init_suprgolfj();
+
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
@@ -60,21 +73,22 @@ private:
required_device<palette_device> m_palette;
required_shared_ptr<uint8_t> m_videoram;
+ required_shared_ptr<uint8_t> m_paletteram;
+
+ memory_view m_vram_palette_view;
tilemap_t *m_tilemap = nullptr;
- std::unique_ptr<uint8_t[]> m_paletteram;
std::unique_ptr<uint8_t[]> m_bg_vram;
std::unique_ptr<uint16_t[]> m_bg_fb;
std::unique_ptr<uint16_t[]> m_fg_fb;
- uint8_t m_rom_bank = 0;
uint8_t m_bg_bank = 0;
- uint8_t m_msm5205next = 0;
- uint8_t m_msm_nmi_mask = 0;
uint8_t m_vreg_pen = 0;
- uint8_t m_palette_switch = 0;
- uint8_t m_toggle = 0;
- uint8_t videoram_r(offs_t offset);
+ uint8_t m_adpcm_data = 0;
+ bool m_adpcm_nmi_enable = 0;
+ uint8_t m_adpcm_available_data = 0;
+
+ void paletteram_w(offs_t offset, uint8_t data);
void videoram_w(offs_t offset, uint8_t data);
uint8_t bg_vram_r(offs_t offset);
void bg_vram_w(offs_t offset, uint8_t data);
@@ -82,14 +96,11 @@ private:
void adpcm_data_w(uint8_t data);
void rom2_bank_select_w(uint8_t data);
void vregs_w(uint8_t data);
- uint8_t rom_bank_select_r();
void rom_bank_select_w(uint8_t data);
uint8_t pedal_extra_bits_r();
uint8_t p1_r();
uint8_t p2_r();
- void writeA(uint8_t data);
- void writeB(uint8_t data);
- DECLARE_WRITE_LINE_MEMBER(adpcm_int);
+ void adpcm_int(int state);
TILE_GET_INFO_MEMBER(get_tile_info);
@@ -111,18 +122,15 @@ TILE_GET_INFO_MEMBER(suprgolf_state::get_tile_info)
void suprgolf_state::video_start()
{
- m_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(suprgolf_state::get_tile_info)), TILEMAP_SCAN_ROWS,8,8,32,32 );
- m_paletteram = std::make_unique<uint8_t[]>(0x1000);
+ m_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(suprgolf_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32 );
m_bg_vram = std::make_unique<uint8_t[]>(0x2000*0x20);
m_bg_fb = std::make_unique<uint16_t[]>(0x2000*0x20);
m_fg_fb = std::make_unique<uint16_t[]>(0x2000*0x20);
- m_tilemap->set_transparent_pen(15);
+ m_tilemap->set_transparent_pen(0xf);
save_item(NAME(m_bg_bank));
save_item(NAME(m_vreg_pen));
- save_item(NAME(m_palette_switch));
- save_pointer(NAME(m_paletteram), 0x1000);
save_pointer(NAME(m_bg_vram), 0x2000*0x20);
save_pointer(NAME(m_bg_fb), 0x2000*0x20);
save_pointer(NAME(m_fg_fb), 0x2000*0x20);
@@ -167,42 +175,34 @@ uint32_t suprgolf_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
return 0;
}
-uint8_t suprgolf_state::videoram_r(offs_t offset)
+void suprgolf_state::videoram_w(offs_t offset, uint8_t data)
{
- if (m_palette_switch)
- return m_paletteram[offset];
- else
- return m_videoram[offset];
+ m_videoram[offset] = data;
+ m_tilemap->mark_tile_dirty((offset & 0x7fe) >> 1);
}
-void suprgolf_state::videoram_w(offs_t offset, uint8_t data)
+void suprgolf_state::paletteram_w(offs_t offset, uint8_t data)
{
- if(m_palette_switch)
- {
- int r,g,b,datax;
- m_paletteram[offset] = data;
- offset>>=1;
- datax = m_paletteram[offset*2] + 256*m_paletteram[offset*2 + 1];
+ u16 datax;
+ u16 r, g, b;
- b = (datax & 0x8000) ? 0 : ((datax)&0x001f)>>0;
- g = (datax & 0x8000) ? 0 : ((datax)&0x03e0)>>5;
- r = (datax & 0x8000) ? 0 : ((datax)&0x7c00)>>10;
+ m_paletteram[offset] = data;
+ offset >>= 1;
+ datax = m_paletteram[offset * 2] + (m_paletteram[offset*2 + 1] << 8);
- m_palette->set_pen_color(offset, pal5bit(r), pal5bit(g), pal5bit(b));
- }
- else
- {
- m_videoram[offset] = data;
- m_tilemap->mark_tile_dirty((offset & 0x7fe) >> 1);
- }
+ b = (datax & 0x8000) ? 0 : ((datax)&0x001f)>>0;
+ g = (datax & 0x8000) ? 0 : ((datax)&0x03e0)>>5;
+ r = (datax & 0x8000) ? 0 : ((datax)&0x7c00)>>10;
+
+ m_palette->set_pen_color(offset, pal5bit(r), pal5bit(g), pal5bit(b));
}
void suprgolf_state::vregs_w(uint8_t data)
{
//printf("%02x\n",data);
+ m_vram_palette_view.select(BIT(data, 7));
//bits 0,1,2 and probably 3 controls the background vram banking
- m_palette_switch = (data & 0x80);
m_bg_bank = (data & 0x1f);
//if(data & 0x60)
@@ -259,17 +259,6 @@ void suprgolf_state::bg_vram_w(offs_t offset, uint8_t data)
}
}
-void suprgolf_state::machine_start()
-{
- membank("bank1")->configure_entries(0, 16, memregion("user2")->base(), 0x4000);
- membank("bank2")->configure_entries(0, 64, memregion("user1")->base(), 0x4000);
-
- save_item(NAME(m_rom_bank));
- save_item(NAME(m_msm5205next));
- save_item(NAME(m_msm_nmi_mask));
- save_item(NAME(m_toggle));
-}
-
void suprgolf_state::pen_w(uint8_t data)
{
m_vreg_pen = data;
@@ -277,33 +266,23 @@ void suprgolf_state::pen_w(uint8_t data)
void suprgolf_state::adpcm_data_w(uint8_t data)
{
- m_msm5205next = data;
-}
-
-uint8_t suprgolf_state::rom_bank_select_r()
-{
- return m_rom_bank;
+ m_adpcm_data = data;
+ m_adpcm_available_data = 2;
}
void suprgolf_state::rom_bank_select_w(uint8_t data)
{
- m_rom_bank = data;
-
- //popmessage("%08x %02x",((data & 0x3f) * 0x4000),data);
- //osd_printf_debug("ROM_BANK 0x8000 - %X @%X\n",data,m_maincpu->pcbase());
membank("bank2")->set_entry(data & 0x3f);
- m_msm_nmi_mask = data & 0x40;
- flip_screen_set(data & 0x80);
+ m_adpcm_nmi_enable = bool(BIT(data, 6));
+ flip_screen_set(BIT(data, 7));
+ // assuming a reset is triggered if NMI is off
+ m_msm->reset_w(!m_adpcm_nmi_enable);
}
void suprgolf_state::rom2_bank_select_w(uint8_t data)
{
- //osd_printf_debug("ROM_BANK 0x4000 - %X @%X\n",data,m_maincpu->pcbase());
membank("bank1")->set_entry(data & 0x0f);
-
- if(data & 0xf0)
- printf("Rom bank select 2 with data %02x activated\n",data);
}
uint8_t suprgolf_state::pedal_extra_bits_r()
@@ -333,7 +312,9 @@ void suprgolf_state::suprgolf_map(address_map &map)
map(0x4000, 0x4000).w(FUNC(suprgolf_state::rom2_bank_select_w));
map(0x8000, 0xbfff).bankr("bank2");
map(0xc000, 0xdfff).rw(FUNC(suprgolf_state::bg_vram_r), FUNC(suprgolf_state::bg_vram_w)); // banked background vram
- map(0xe000, 0xefff).rw(FUNC(suprgolf_state::videoram_r), FUNC(suprgolf_state::videoram_w)).share("videoram"); //foreground vram + paletteram
+ map(0xe000, 0xefff).view(m_vram_palette_view);
+ m_vram_palette_view[0](0xe000, 0xefff).ram().w(FUNC(suprgolf_state::videoram_w)).share("videoram");
+ m_vram_palette_view[1](0xe000, 0xefff).ram().w(FUNC(suprgolf_state::paletteram_w)).share("paletteram");
map(0xf000, 0xf000).w(FUNC(suprgolf_state::pen_w));
map(0xf800, 0xffff).ram();
}
@@ -432,38 +413,41 @@ static INPUT_PORTS_START( suprgolf )
PORT_DIPUNUSED_DIPLOC( 0x80, 0x00, "SW2:8" )
INPUT_PORTS_END
-void suprgolf_state::writeA(uint8_t data)
+// guesswork, assume played back from VCLK control
+// 0 -> 1 clocks NMI, 1 -> 0 pushes data to the ADPCM if available from the bus.
+void suprgolf_state::adpcm_int(int state)
{
- osd_printf_debug("ymwA\n");
-}
-
-void suprgolf_state::writeB(uint8_t data)
-{
- osd_printf_debug("ymwA\n");
-}
-
-WRITE_LINE_MEMBER(suprgolf_state::adpcm_int)
-{
- m_msm->reset_w(0);
- m_toggle ^= 1;
- if(m_toggle)
+ if(!state && m_adpcm_available_data)
{
- m_msm->data_w((m_msm5205next & 0xf0) >> 4);
- if(m_msm_nmi_mask) { m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); }
- }
- else
- {
- m_msm->data_w((m_msm5205next & 0x0f) >> 0);
+ m_msm->data_w(m_adpcm_data >> 4);
+ m_adpcm_data <<= 4;
+ m_adpcm_available_data--;
+ return;
}
+
+ if(state && m_adpcm_available_data == 0 && m_adpcm_nmi_enable)
+ m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
static GFXDECODE_START( gfx_suprgolf )
GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x4_packed_lsb, 0, 0x80 )
GFXDECODE_END
+void suprgolf_state::machine_start()
+{
+ membank("bank1")->configure_entries(0, 16, memregion("user2")->base(), 0x4000);
+ membank("bank2")->configure_entries(0, 64, memregion("user1")->base(), 0x4000);
+
+ save_item(NAME(m_adpcm_data));
+ save_item(NAME(m_adpcm_nmi_enable));
+ save_item(NAME(m_adpcm_available_data));
+}
+
void suprgolf_state::machine_reset()
{
- m_msm_nmi_mask = 0;
+ m_adpcm_nmi_enable = 0;
+ m_adpcm_available_data = 0;
+ m_vram_palette_view.select(0);
}
#define MASTER_CLOCK XTAL(12'000'000)
@@ -483,7 +467,6 @@ void suprgolf_state::suprgolf(machine_config &config)
i8255_device &ppi1(I8255A(config, "ppi8255_1"));
ppi1.in_pa_callback().set_ioport("SYSTEM");
- ppi1.in_pb_callback().set(FUNC(suprgolf_state::rom_bank_select_r));
ppi1.out_pb_callback().set(FUNC(suprgolf_state::rom_bank_select_w));
ppi1.out_pc_callback().set(FUNC(suprgolf_state::vregs_w));
@@ -506,13 +489,11 @@ void suprgolf_state::suprgolf(machine_config &config)
//ymsnd.irq_handler().set_inputline(m_maincpu, INPUT_LINE_NMI);
ymsnd.port_a_read_callback().set_ioport("DSW0");
ymsnd.port_b_read_callback().set_ioport("DSW1");
- ymsnd.port_a_write_callback().set(FUNC(suprgolf_state::writeA));
- ymsnd.port_b_write_callback().set(FUNC(suprgolf_state::writeB));
- ymsnd.add_route(ALL_OUTPUTS, "mono", 0.5);
+ ymsnd.add_route(ALL_OUTPUTS, "mono", 0.25);
MSM5205(config, m_msm, XTAL(384'000)); /* guess */
- m_msm->vck_legacy_callback().set(FUNC(suprgolf_state::adpcm_int)); /* interrupt function */
- m_msm->set_prescaler_selector(msm5205_device::S48_4B); /* 4KHz 4-bit */
+ m_msm->vck_callback().set(FUNC(suprgolf_state::adpcm_int));
+ m_msm->set_prescaler_selector(msm5205_device::S48_4B);
m_msm->add_route(ALL_OUTPUTS, "mono", 1.0);
}
@@ -645,9 +626,28 @@ ROM_START( albatross )
ROM_LOAD( "chr4.3d", 0x030000, 0x010000, CRC(0fb88270) SHA1(d85a7f1bc5b3c4b13bbd887cea4c055541cbb737) )
ROM_END
+
+void suprgolf_state::init_suprgolf()
+{
+ uint8_t *ROM = memregion("user2")->base();
+
+ ROM[0x74f4-0x4000] = 0x00;
+ ROM[0x74f5-0x4000] = 0x00;
+ ROM[0x74fa+(0x4000*3)-0x4000] = 0x20; // patch ROM check
+}
+
+void suprgolf_state::init_suprgolfj()
+{
+ uint8_t *ROM = memregion("user2")->base();
+
+ ROM[0x74f4-0x4000] = 0x00;
+ ROM[0x74f5-0x4000] = 0x00;
+ ROM[0x6d72+(0x4000*3)-0x4000] = 0x20; // patch ROM check
+}
+
} // Anonymous namespace
-GAME( 1989, suprgolf, 0, suprgolf, suprgolf, suprgolf_state, empty_init, ROT0, "Nasco", "Super Crowns Golf (World)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
-GAME( 1989, suprgolfj, suprgolf, suprgolf, suprgolf, suprgolf_state, empty_init, ROT0, "Nasco", "Super Crowns Golf (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
-GAME( 1989, albatross, suprgolf, suprgolf, suprgolf, suprgolf_state, empty_init, ROT0, "Nasco", "Albatross (US Prototype?)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL| MACHINE_SUPPORTS_SAVE )
+GAME( 1989, suprgolf, 0, suprgolf, suprgolf, suprgolf_state, init_suprgolf, ROT0, "Nasco", "Super Crowns Golf (World)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
+GAME( 1989, suprgolfj, suprgolf, suprgolf, suprgolf, suprgolf_state, init_suprgolfj, ROT0, "Nasco", "Super Crowns Golf (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
+GAME( 1989, albatross, suprgolf, suprgolf, suprgolf, suprgolf_state, init_suprgolf, ROT0, "Nasco (Technos license)", "Albatross (US prototype?)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL| MACHINE_SUPPORTS_SAVE )