Skip to content

Commit 6c056e5

Browse files
atari/atarisy2: add Garfield prototype (1984, unreleased)
Add driver support for the unreleased 1984 Garfield arcade prototype for Atari System 2 hardware. The game was developed by Eddie Babcock (programmer), Paul Watmore (engineer), and a team of animators, but was cancelled before release. The prototype uses a Winchester disk drive for loading graphics and level data into 128KB shared Graphics DRAM. Without the disk image, the game boots into its attract mode but cannot load gameplay content. Marked MACHINE_NOT_WORKING accordingly. Hardware differences from standard System 2: - Slapstic 105 banking - Sequential (non-linked) motion object list - 4KB playfield tile ROM (single ROM replicated across region) - Quad POKEY sound (8 channels) instead of YM2151+POKEY - Winchester disk controller at 0x5000 (no EEPROM) ROM set includes program ROMs, sprite ROMs (park/wave pairs), playfield tile ROM, and a motion object size lookup table. Sound and character ROMs are Paperboy placeholders. All dumps marked BAD_DUMP pending verification. Contributed by Matt Munroe. Made-with: Cursor
1 parent 4b6f920 commit 6c056e5

File tree

4 files changed

+224
-7
lines changed

4 files changed

+224
-7
lines changed

src/mame/atari/atarisy2.cpp

Lines changed: 168 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
99
Games supported:
1010
* Paperboy (1984) [3 sets]
11+
* Garfield (1984) [prototype, unreleased]
1112
* 720 Degrees (1986) [6 sets]
1213
* Super Sprint (1986) [7 sets]
1314
* Championship Sprint (1986) [8 sets]
@@ -145,15 +146,18 @@ static constexpr XTAL MASTER_CLOCK = XTAL(20'000'000);
145146

146147
void atarisy2_state::update_interrupts()
147148
{
149+
int vblank_line = m_swap_irq_lines ? t11_device::CP2_LINE : t11_device::CP3_LINE;
150+
int scanline_line = m_swap_irq_lines ? t11_device::CP3_LINE : t11_device::CP2_LINE;
151+
148152
if (m_video_int_state)
149-
m_maincpu->set_input_line(t11_device::CP3_LINE, ASSERT_LINE);
153+
m_maincpu->set_input_line(vblank_line, ASSERT_LINE);
150154
else
151-
m_maincpu->set_input_line(t11_device::CP3_LINE, CLEAR_LINE);
155+
m_maincpu->set_input_line(vblank_line, CLEAR_LINE);
152156

153157
if (m_scanline_int_state)
154-
m_maincpu->set_input_line(t11_device::CP2_LINE, ASSERT_LINE);
158+
m_maincpu->set_input_line(scanline_line, ASSERT_LINE);
155159
else
156-
m_maincpu->set_input_line(t11_device::CP2_LINE, CLEAR_LINE);
160+
m_maincpu->set_input_line(scanline_line, CLEAR_LINE);
157161

158162
if (m_p2portwr_state)
159163
m_maincpu->set_input_line(t11_device::CP1_LINE, ASSERT_LINE);
@@ -181,6 +185,52 @@ void atarisy2_state::video_int_ack_w(uint8_t data)
181185
}
182186

183187

188+
uint16_t atarisy2_state::garfield_irq_status_r()
189+
{
190+
return 0x0000;
191+
}
192+
193+
194+
uint16_t atarisy2_state::garfield_scanline_status_r()
195+
{
196+
return 0x0000;
197+
}
198+
199+
200+
uint16_t atarisy2_state::garfield_int_enable_r()
201+
{
202+
return m_interrupt_enable;
203+
}
204+
205+
206+
uint16_t atarisy2_state::garfield_soundlatch_r()
207+
{
208+
return 0x0000;
209+
}
210+
211+
212+
uint16_t atarisy2_state::garfield_xscroll_r()
213+
{
214+
return m_xscroll[0];
215+
}
216+
217+
218+
uint16_t atarisy2_state::garfield_yscroll_r()
219+
{
220+
return m_yscroll[0];
221+
}
222+
223+
224+
void atarisy2_state::garfield_spriteram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
225+
{
226+
spriteram_w(offset, data, mem_mask);
227+
}
228+
229+
void atarisy2_state::garfield_alpha_w(offs_t offset, uint16_t data, uint16_t mem_mask)
230+
{
231+
m_alpha_tilemap->write16(offset, data, mem_mask);
232+
}
233+
184234

185235
/*************************************
186236
*
@@ -193,10 +243,8 @@ TIMER_DEVICE_CALLBACK_MEMBER(atarisy2_state::scanline_update)
193243
int const scanline = param;
194244
if (scanline <= m_screen->height())
195245
{
196-
// generate the 32V interrupt (IRQ 2)
197246
if ((scanline % 64) == 0)
198247
{
199-
// clock the state through
200248
m_scanline_int_state = BIT(m_interrupt_enable, 2);
201249
update_interrupts();
202250
}
@@ -237,6 +285,14 @@ void atarisy2_state::machine_reset()
237285
m_interrupt_enable = 0;
238286

239287
sound_reset_w(1);
288+
289+
if (m_swap_irq_lines)
290+
{
291+
auto &palette = *subdevice<palette_device>("palette");
292+
for (int i = 0; i < 256; i++)
293+
palette.write16(i, 0);
294+
}
295+
240296
}
241297

242298

@@ -251,7 +307,6 @@ void atarisy2_state::vblank_int(int state)
251307
{
252308
if (state)
253309
{
254-
// clock the VBLANK through
255310
m_video_int_state = BIT(m_interrupt_enable, 3);
256311
update_interrupts();
257312
}
@@ -769,6 +824,39 @@ void atarisy2_state::main_map(address_map &map)
769824
map(0100000, 0177777).rom();
770825
}
771826

827+
void atarisy2_state::garfield_main_map(address_map &map)
828+
{
829+
map.unmap_value_high();
830+
map(0000000, 0007777).ram();
831+
map(0010000, 0010777).mirror(01000).ram().w("palette", FUNC(palette_device::write16)).share("palette");
832+
map(0012000, 0012000).mirror(00176).r("adc", FUNC(adc0808_device::data_r));
833+
map(0012000, 0012003).mirror(00174).w(FUNC(atarisy2_state::bankselect_w));
834+
map(0012200, 0012217).mirror(00160).w("adc", FUNC(adc0808_device::address_offset_start_w)).umask16(0x00ff);
835+
map(0012400, 0012401).mirror(00176).r(FUNC(atarisy2_state::garfield_irq_status_r));
836+
map(0012400, 0012400).mirror(00176).w(FUNC(atarisy2_state::video_int_ack_w));
837+
map(0012600, 0012601).mirror(00036).r(FUNC(atarisy2_state::garfield_scanline_status_r));
838+
map(0012600, 0012600).mirror(00036).w(FUNC(atarisy2_state::scanline_int_ack_w));
839+
map(0012640, 0012640).mirror(00036).w(FUNC(atarisy2_state::sound_reset_w));
840+
map(0013000, 0013001).mirror(00176).r(FUNC(atarisy2_state::garfield_int_enable_r));
841+
map(0013000, 0013000).mirror(00176).w(FUNC(atarisy2_state::int_enable_w));
842+
map(0013200, 0013201).mirror(00176).r(FUNC(atarisy2_state::garfield_soundlatch_r));
843+
map(0013200, 0013200).mirror(00176).w(m_soundlatch, FUNC(generic_latch_8_device::write));
844+
map(0013400, 0013401).mirror(00176).rw(FUNC(atarisy2_state::garfield_xscroll_r), FUNC(atarisy2_state::xscroll_w)).share(m_xscroll);
845+
map(0013600, 0013601).mirror(00176).rw(FUNC(atarisy2_state::garfield_yscroll_r), FUNC(atarisy2_state::yscroll_w)).share(m_yscroll);
846+
map(0014000, 0014001).mirror(01776).portr("IN0");
847+
map(0014000, 0014000).mirror(01776).w("watchdog", FUNC(watchdog_timer_device::reset_w));
848+
map(0016000, 0016001).mirror(01776).r(FUNC(atarisy2_state::sound_r));
849+
map(0020000, 0037777).view(m_vmmu);
850+
m_vmmu[0](020000, 033777).ram().w(FUNC(atarisy2_state::garfield_alpha_w)).share("alpha");
851+
m_vmmu[0](034000, 037777).ram().w(FUNC(atarisy2_state::garfield_spriteram_w)).share("mob");
852+
m_vmmu[1](020000, 037777).ram();
853+
m_vmmu[2](020000, 037777).ram().w(FUNC(atarisy2_state::playfieldt_w)).share(m_playfieldt);
854+
m_vmmu[3](020000, 037777).ram().w(FUNC(atarisy2_state::playfieldb_w)).share(m_playfieldb);
855+
map(0040000, 0057777).bankr(m_rombank[0]);
856+
map(0060000, 0077777).bankr(m_rombank[1]);
857+
map(0100000, 0177777).rom();
858+
}
859+
772860

773861
/*************************************
774862
*
@@ -1260,6 +1348,21 @@ void atarisy2_state::paperboy(machine_config &config)
12601348
}
12611349

12621350

1351+
void atarisy2_state::garfield(machine_config &config)
1352+
{
1353+
atarisy2(config);
1354+
m_maincpu->set_addrmap(AS_PROGRAM, &atarisy2_state::garfield_main_map);
1355+
1356+
m_mob->set_config(atarisy2_state::s_garfield_mob_config);
1357+
1358+
SLAPSTIC(config, m_slapstic, 105);
1359+
m_slapstic->set_range(m_maincpu, AS_PROGRAM, 0100000, 0100777, 0);
1360+
m_slapstic->set_view(m_vmmu);
1361+
1362+
subdevice<watchdog_timer_device>("watchdog")->set_time(attotime::never);
1363+
}
1364+
1365+
12631366
void atarisy2_state::_720(machine_config &config)
12641367
{
12651368
atarisy2(config);
@@ -1526,6 +1629,42 @@ ROM_START( paperboyp )
15261629
ROM_END
15271630

15281631

1632+
ROM_START( garfield )
1633+
ROM_REGION( 0x90000, "maincpu", 0 )
1634+
ROM_LOAD16_BYTE( "cpu_lo.bin", 0x008000, 0x004000, BAD_DUMP CRC(ef2d65b2) SHA1(87ae02fce6a34083792d785d50c725710f2ec9a0) )
1635+
ROM_LOAD16_BYTE( "cpu_hi.bin", 0x008001, 0x004000, BAD_DUMP CRC(f3f24c3e) SHA1(ca42120a54ef2859905a535555b5003315036bff) )
1636+
1637+
ROM_REGION( 0x10000, "audiocpu", 0 )
1638+
ROM_LOAD( "snd_dummy.bin", 0x00c000, 0x004000, BAD_DUMP CRC(1c1425d5) SHA1(23b9e5c02a3481c2b0a6fdd6da6b2d8e896faf0e) ) // Paperboy sound ROM used as placeholder
1639+
1640+
ROM_REGION( 0x20000, "tiles", 0 )
1641+
ROM_LOAD( "leash.bin", 0x000000, 0x004000, BAD_DUMP CRC(f517c9a9) SHA1(a970a7064061b2e2c84c382d63f21c8b6e14c1d0) )
1642+
ROM_RELOAD( 0x004000, 0x004000 )
1643+
ROM_RELOAD( 0x008000, 0x004000 )
1644+
ROM_RELOAD( 0x00c000, 0x004000 )
1645+
ROM_RELOAD( 0x010000, 0x004000 )
1646+
ROM_RELOAD( 0x014000, 0x004000 )
1647+
ROM_RELOAD( 0x018000, 0x004000 )
1648+
ROM_RELOAD( 0x01c000, 0x004000 )
1649+
1650+
ROM_REGION( 0x40000, "sprites", 0 )
1651+
ROM_LOAD( "park0.bin", 0x000000, 0x008000, BAD_DUMP CRC(b96977cd) SHA1(eea9912cf6caf6b631ef8326a9099ea404cb4340) )
1652+
ROM_LOAD( "park1.bin", 0x008000, 0x008000, BAD_DUMP CRC(4401d046) SHA1(92d49f36f41dbce34b2fc8fb3f4c7d7f3a362df0) )
1653+
ROM_LOAD( "park2.bin", 0x010000, 0x008000, BAD_DUMP CRC(67514167) SHA1(b3ffc0d1f661b091c1ed75e88dba98fd618f1dcb) )
1654+
ROM_LOAD( "park3.bin", 0x018000, 0x008000, BAD_DUMP CRC(3660d1d9) SHA1(16a4cea002cfe0c2e60560ce96c4af325c114ff5) )
1655+
ROM_LOAD( "wave0.bin", 0x020000, 0x008000, BAD_DUMP CRC(8ee5a47c) SHA1(af2b1e768fc0b11e01341b5122cf89b81c25f99b) )
1656+
ROM_LOAD( "wave1.bin", 0x028000, 0x008000, BAD_DUMP CRC(e9dc23f1) SHA1(66b675a86aac0b2dd578c306a9b425b554aaa691) )
1657+
ROM_LOAD( "wave2.bin", 0x030000, 0x008000, BAD_DUMP CRC(23c4f134) SHA1(593bb49a1dc2bde3d97d44ca3adf94ca793f6e27) )
1658+
ROM_LOAD( "wave3.bin", 0x038000, 0x008000, BAD_DUMP CRC(95e4d89c) SHA1(4a01bb8517c5afd5ad8bd86b260d902b9a33d7fe) )
1659+
1660+
ROM_REGION( 0x2000, "chars", 0 )
1661+
ROM_LOAD( "char_dummy.bin", 0x000000, 0x002000, BAD_DUMP CRC(60d7aebb) SHA1(ad74221c4270496ebcfedd46ea16dca2cda1b4be) ) // Paperboy char ROM used as placeholder
1662+
1663+
ROM_REGION( 0x200, "eeprom", 0 )
1664+
ROM_LOAD( "mosize.bin", 0x0000, 0x0200, BAD_DUMP CRC(16ea848b) SHA1(03d1411709a780efc1551137e8b0d7588248be91) )
1665+
ROM_END
1666+
1667+
15291668
ROM_START( 720 )
15301669
ROM_REGION( 0x90000, "maincpu", 0 ) // 9 * 64k T11 code
15311670
ROM_LOAD16_BYTE( "136047-3126.7lm", 0x008000, 0x004000, CRC(43abd367) SHA1(bb58c42f25ef0ee5357782652e9e2b28df0ba82e) )
@@ -3285,6 +3424,26 @@ void atarisy2_state::init_paperboy()
32853424
}
32863425

32873426

3427+
void atarisy2_state::init_garfield()
3428+
{
3429+
uint8_t *cpu1 = memregion("maincpu")->base();
3430+
3431+
for (int i = 0x10000; i < 0x90000; i += 0x20000)
3432+
{
3433+
memcpy(&cpu1[i + 0x08000], &cpu1[i], 0x8000);
3434+
memcpy(&cpu1[i + 0x10000], &cpu1[i], 0x8000);
3435+
memcpy(&cpu1[i + 0x18000], &cpu1[i], 0x8000);
3436+
}
3437+
3438+
m_pedal_count = 0;
3439+
if (m_tms5220.found())
3440+
m_tms5220->rsq_w(1);
3441+
3442+
m_vmmu.select(0);
3443+
m_swap_irq_lines = true;
3444+
}
3445+
3446+
32883447
void atarisy2_state::init_720()
32893448
{
32903449
m_pedal_count = -1;
@@ -3334,6 +3493,8 @@ GAME( 1984, paperboyr2, paperboy, paperboy, paperboy, atarisy2_state, init_paper
33343493
GAME( 1984, paperboyr1, paperboy, paperboy, paperboy, atarisy2_state, init_paperboy, ROT0, "Atari Games", "Paperboy (rev 1)", MACHINE_SUPPORTS_SAVE )
33353494
GAME( 1983, paperboyp, paperboy, paperboy, paperboy, atarisy2_state, init_paperboy, ROT0, "Atari Games", "Paperboy (prototype)", MACHINE_NOT_WORKING )
33363495

3496+
GAME( 1984, garfield, 0, garfield, paperboy, atarisy2_state, init_garfield, ROT0, "Atari Games", "Garfield (prototype)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
3497+
33373498
GAME( 1986, 720, 0, _720, 720, atarisy2_state, init_720, ROT0, "Atari Games", "720 Degrees (rev 4)", MACHINE_SUPPORTS_SAVE )
33383499
GAME( 1986, 720r3, 720, _720, 720, atarisy2_state, init_720, ROT0, "Atari Games", "720 Degrees (rev 3)", MACHINE_SUPPORTS_SAVE )
33393500
GAME( 1986, 720r2, 720, _720, 720, atarisy2_state, init_720, ROT0, "Atari Games", "720 Degrees (rev 2)", MACHINE_SUPPORTS_SAVE )

src/mame/atari/atarisy2.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,15 @@ class atarisy2_state : public driver_device
6464
void init_csprint() ATTR_COLD;
6565
void init_paperboy() ATTR_COLD;
6666
void init_720() ATTR_COLD;
67+
void init_garfield() ATTR_COLD;
6768

6869
void atarisy2(machine_config &config) ATTR_COLD;
6970
void apb(machine_config &config) ATTR_COLD;
7071
void paperboy(machine_config &config) ATTR_COLD;
7172
void ssprint(machine_config &config) ATTR_COLD;
7273
void _720(machine_config &config) ATTR_COLD;
7374
void csprint(machine_config &config) ATTR_COLD;
75+
void garfield(machine_config &config) ATTR_COLD;
7476

7577
protected:
7678
virtual void machine_start() override ATTR_COLD;
@@ -119,6 +121,8 @@ class atarisy2_state : public driver_device
119121
bool m_p2portwr_state = 0;
120122
bool m_p2portrd_state = 0;
121123

124+
bool m_swap_irq_lines = false;
125+
122126
uint8_t m_sound_reset_state = 0U;
123127

124128
emu_timer * m_yscroll_reset_timer = nullptr;
@@ -137,6 +141,13 @@ class atarisy2_state : public driver_device
137141

138142
void scanline_int_ack_w(uint8_t data);
139143
void video_int_ack_w(uint8_t data);
144+
uint16_t garfield_irq_status_r();
145+
uint16_t garfield_scanline_status_r();
146+
uint16_t garfield_int_enable_r();
147+
uint16_t garfield_soundlatch_r();
148+
uint16_t garfield_xscroll_r();
149+
uint16_t garfield_yscroll_r();
150+
void garfield_alpha_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
140151
void int0_ack_w(uint8_t data);
141152
void sound_reset_w(uint8_t data);
142153
void int_enable_w(uint8_t data);
@@ -165,12 +176,15 @@ class atarisy2_state : public driver_device
165176
void yscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
166177
void xscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
167178
void spriteram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
179+
void garfield_spriteram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
168180
void playfieldt_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
169181
void playfieldb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
170182
static rgb_t RRRRGGGGBBBBIIII(uint32_t raw);
171183

172184
static const atari_motion_objects_config s_mob_config;
185+
static const atari_motion_objects_config s_garfield_mob_config;
173186
void main_map(address_map &map) ATTR_COLD;
187+
void garfield_main_map(address_map &map) ATTR_COLD;
174188
void sound_map(address_map &map) ATTR_COLD;
175189
};
176190

src/mame/atari/atarisy2_v.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,53 @@ const atari_motion_objects_config atarisy2_state::s_mob_config =
7474
0 /* resulting value to indicate "special" */
7575
};
7676

77+
const atari_motion_objects_config atarisy2_state::s_garfield_mob_config =
78+
{
79+
1, /* index to which gfx system */
80+
1, /* number of motion object banks */
81+
0, /* are the entries linked? NO - Garfield uses sequential */
82+
0, /* are the entries split? */
83+
0, /* render in reverse order? */
84+
0, /* render in swapped X/Y order? */
85+
0, /* does the neighbor bit affect the next object? */
86+
0, /* pixels per SLIP entry (0 for no-slip) */
87+
0, /* pixel offset for SLIPs */
88+
0, /* maximum number of links to visit/scanline (0=all) */
89+
90+
0x00, /* base palette entry */
91+
15, /* transparent pen index */
92+
93+
{{ 0,0,0,0x07f8 }}, /* mask for the link (used as entry count in sequential mode) */
94+
{{ 0,0x07ff,0,0 }, { 0x0007,0,0,0 }}, /* mask for the code index */
95+
{{ 0,0,0,0x3000 }}, /* mask for the color */
96+
{{ 0,0,0xffc0,0 }}, /* mask for the X position */
97+
{{ 0x7fc0,0,0,0 }}, /* mask for the Y position */
98+
{{ 0 }}, /* mask for the width, in tiles*/
99+
{{ 0,0x3800,0,0 }}, /* mask for the height, in tiles */
100+
{{ 0,0x4000,0,0 }}, /* mask for the horizontal flip */
101+
{{ 0 }}, /* mask for the vertical flip */
102+
{{ 0,0,0,0xc000 }}, /* mask for the priority */
103+
{{ 0,0x8000,0,0 }}, /* mask for the neighbor */
104+
{{ 0 }}, /* mask for absolute coordinates */
105+
106+
{{ 0 }}, /* mask for the special value */
107+
0 /* resulting value to indicate "special" */
108+
};
109+
77110
void atarisy2_state::video_start()
78111
{
79112
// reset the statics
80113
m_yscroll_reset_timer = timer_alloc(FUNC(atarisy2_state::reset_yscroll_callback), this);
81114

82115
// save states
83116
save_item(NAME(m_playfield_tile_bank));
117+
118+
if (m_swap_irq_lines)
119+
{
120+
auto &clut = m_mob->color_lookup();
121+
for (size_t i = 0; i < clut.size(); i++)
122+
clut[i] = 0;
123+
}
84124
}
85125

86126

@@ -261,5 +301,6 @@ uint32_t atarisy2_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
261301

262302
// add the alpha on top
263303
m_alpha_tilemap->draw(screen, bitmap, cliprect, 0, 0);
304+
264305
return 0;
265306
}

src/mame/mame.lst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,6 +1826,7 @@ paperboy
18261826
paperboyr1
18271827
paperboyr2
18281828
paperboyp
1829+
garfield
18291830
ssprint
18301831
ssprint1
18311832
ssprint3

0 commit comments

Comments
 (0)