1 // license:BSD-3-Clause
2 // copyright-holders:Luca Elia,Paul Priest
3 /***************************************************************************
4
5 -= Fuuki 16 Bit Games =-
6
7 driver by Luca Elia (l.elia@tin.it)
8
9
10 Main CPU : M68000
11 Sound Chips : YM2203 + YM3812 + M6295
12 Video Chips : FI-002K (208pin PQFP, GA2)
13 FI-003K (208pin PQFP, GA3)
14 Other : Mitsubishi M60067-0901FP 452100 (208pin PQFP, GA1)
15
16
17 ---------------------------------------------------------------------------
18 Year + Game
19 ---------------------------------------------------------------------------
20 95 Susume! Mile Smile / Go Go! Mile Smile
21 96 Gyakuten!! Puzzle Bancho
22 ---------------------------------------------------------------------------
23
24 Do NOT trust the Service Mode for dipswitch settings for Go Go! Mile Smile:
25 Service Mode shows Coin A as SW2:3-5 & Coin B as SW2:6-8, but the game ignores the
26 setting of Coin B and only uses the settings for Coin A, except for Coin B "Free Play"
27 The game says Press 1 or 2, and will start the game, but jumps right to the Game Over
28 and "Continue" countdown.
29 The Service Mode is WAY off on effects of dipswitches for the ealier set!!! It reports
30 the effects of MAME's SW1:3-8 have been moved to SW1:2-7 and Demo Sound has moved to
31 SW2:7. What MAME shows as settings are according to actual game effect and reflect what
32 the manual states.
33
34
35 To Do:
36
37 - Raster effects (level 5 interrupt is used for that). In pbancho
38 they involve changing the *vertical* scroll value of the layers
39 each scanline (when you are about to die, in the solo game).
40 In gogomile they weave the water backgrounds and do some
41 parallactic scrolling on later levels. *partly done, could do with
42 some tweaking
43
44 - The scroll values are generally wrong when flip screen is on and rasters are often incorrect
45
46 ***************************************************************************/
47
48 #include "emu.h"
49 #include "includes/fuukifg2.h"
50
51 #include "cpu/z80/z80.h"
52 #include "cpu/m68000/m68000.h"
53 #include "sound/2203intf.h"
54 #include "sound/3812intf.h"
55 #include "speaker.h"
56
57
58 /***************************************************************************
59
60
61 Memory Maps - Main CPU
62
63
64 ***************************************************************************/
65
vregs_w(offs_t offset,u16 data,u16 mem_mask)66 void fuuki16_state::vregs_w(offs_t offset, u16 data, u16 mem_mask)
67 {
68 const u16 old = m_vregs[offset];
69 data = COMBINE_DATA(&m_vregs[offset]);
70 if (old != data)
71 {
72 if (offset == 0x1c / 2)
73 {
74 const rectangle &visarea = m_screen->visible_area();
75 attotime period = m_screen->frame_period();
76 m_raster_interrupt_timer->adjust(m_screen->time_until_pos(data, visarea.max_x + 1), 0, period);
77 }
78 if (offset == 0x1e / 2)
79 {
80 if ((old ^ data) & 0x40)
81 m_tilemap[2]->mark_all_dirty();
82 }
83 }
84 }
85
sound_command_w(u8 data)86 void fuuki16_state::sound_command_w(u8 data)
87 {
88 m_soundlatch->write(data & 0xff);
89 m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
90 // m_maincpu->spin_until_time(attotime::from_usec(50)); // Allow the other CPU to reply
91 machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(50)); // Fixes glitching in rasters
92 }
93
94 template<int Layer>
vram_w(offs_t offset,u16 data,u16 mem_mask)95 void fuuki16_state::vram_w(offs_t offset, u16 data, u16 mem_mask)
96 {
97 COMBINE_DATA(&m_vram[Layer][offset]);
98 m_tilemap[Layer]->mark_tile_dirty(offset / 2);
99 }
100
101 template<int Layer>
vram_buffered_w(offs_t offset,u16 data,u16 mem_mask)102 void fuuki16_state::vram_buffered_w(offs_t offset, u16 data, u16 mem_mask)
103 {
104 const int buffer = (m_vregs[0x1e / 2] & 0x40) >> 6;
105 COMBINE_DATA(&m_vram[Layer][offset]);
106 if ((Layer & 1) == buffer)
107 m_tilemap[2]->mark_tile_dirty(offset / 2);
108 }
109
fuuki16_map(address_map & map)110 void fuuki16_state::fuuki16_map(address_map &map)
111 {
112 map(0x000000, 0x0fffff).rom(); // ROM
113 map(0x400000, 0x40ffff).ram(); // RAM
114 map(0x500000, 0x501fff).ram().w(FUNC(fuuki16_state::vram_w<0>)).share("vram.0"); // Layers
115 map(0x502000, 0x503fff).ram().w(FUNC(fuuki16_state::vram_w<1>)).share("vram.1"); //
116 map(0x504000, 0x505fff).ram().w(FUNC(fuuki16_state::vram_buffered_w<2>)).share("vram.2"); //
117 map(0x506000, 0x507fff).ram().w(FUNC(fuuki16_state::vram_buffered_w<3>)).share("vram.3"); //
118 map(0x600000, 0x601fff).mirror(0x008000).ram().share("spriteram"); // Sprites, mirrored?
119 map(0x700000, 0x703fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // Palette
120 map(0x800000, 0x800001).portr("SYSTEM");
121 map(0x810000, 0x810001).portr("P1_P2");
122 map(0x880000, 0x880001).portr("DSW");
123 map(0x8a0001, 0x8a0001).w(FUNC(fuuki16_state::sound_command_w)); // To Sound CPU
124 map(0x8c0000, 0x8c001f).ram().w(FUNC(fuuki16_state::vregs_w)).share("vregs"); // Video Registers
125 map(0x8d0000, 0x8d0003).ram().share("unknown"); //
126 map(0x8e0000, 0x8e0001).ram().share("priority"); //
127 }
128
129
130 /***************************************************************************
131
132
133 Memory Maps - Sound CPU
134
135
136 ***************************************************************************/
137
sound_rombank_w(u8 data)138 void fuuki16_state::sound_rombank_w(u8 data)
139 {
140 if (data <= 2)
141 m_soundbank->set_entry(data);
142 else
143 logerror("CPU #1 - PC %04X: unknown bank bits: %02X\n", m_audiocpu->pc(), data);
144 }
145
oki_banking_w(u8 data)146 void fuuki16_state::oki_banking_w(u8 data)
147 {
148 /*
149 data & 0x06 is always equals to data & 0x60
150 data & 0x10 is always set
151 */
152
153 m_oki->set_rom_bank((data & 6) >> 1);
154 }
155
fuuki16_sound_map(address_map & map)156 void fuuki16_state::fuuki16_sound_map(address_map &map)
157 {
158 map(0x0000, 0x5fff).rom(); // ROM
159 map(0x6000, 0x7fff).ram(); // RAM
160 map(0x8000, 0xffff).bankr("soundbank"); // Banked ROM
161 }
162
fuuki16_sound_io_map(address_map & map)163 void fuuki16_state::fuuki16_sound_io_map(address_map &map)
164 {
165 map.global_mask(0xff);
166 map(0x00, 0x00).w(FUNC(fuuki16_state::sound_rombank_w)); // ROM Bank
167 map(0x11, 0x11).r(m_soundlatch, FUNC(generic_latch_8_device::read)).nopw(); // From Main CPU / ? To Main CPU ?
168 map(0x20, 0x20).w(FUNC(fuuki16_state::oki_banking_w)); // Oki Banking
169 map(0x30, 0x30).nopw(); // ? In the NMI routine
170 map(0x40, 0x41).w("ym1", FUNC(ym2203_device::write));
171 map(0x50, 0x51).rw("ym2", FUNC(ym3812_device::read), FUNC(ym3812_device::write));
172 map(0x60, 0x60).r(m_oki, FUNC(okim6295_device::read)); // M6295
173 map(0x61, 0x61).w(m_oki, FUNC(okim6295_device::write)); // M6295
174 }
175
176
177 /***************************************************************************
178
179
180 Input Ports
181
182
183 ***************************************************************************/
184
185 static INPUT_PORTS_START( gogomile )
186 PORT_START("SYSTEM") // $800000.w
187 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 )
188 PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_SERVICE1 )
189 PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
190 PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
191 PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_START1 )
192 PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_START2 )
193 PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
194 PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
195 PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_COIN2 )
196 PORT_BIT( 0xfe00, IP_ACTIVE_LOW, IPT_UNKNOWN )
197
198 PORT_START("P1_P2") // $810000.w
199 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
200 PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
201 PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
202 PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
203 PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
204 PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN ) // There's code that uses
205 PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN ) // these unknown bits
206 PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
207
208 PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
209 PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
210 PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
211 PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
212 PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
213 PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN )
214 PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN )
215 PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN )
216
217 PORT_START("DSW") // $880000.w
218 PORT_SERVICE_DIPLOC( 0x0001, IP_ACTIVE_LOW, "SW1:1" )
219 PORT_DIPNAME( 0x0002, 0x0002, "Demo Music" ) PORT_DIPLOCATION("SW1:2") /* Game play sounds still play, only effects Music */
220 PORT_DIPSETTING( 0x0000, DEF_STR( Off ) )
221 PORT_DIPSETTING( 0x0002, DEF_STR( On ) )
222 PORT_DIPNAME( 0x000c, 0x000c, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:3,4")
223 PORT_DIPSETTING( 0x0000, DEF_STR( Easy ) )
224 PORT_DIPSETTING( 0x000c, DEF_STR( Normal ) )
225 PORT_DIPSETTING( 0x0008, DEF_STR( Hard ) )
226 PORT_DIPSETTING( 0x0004, DEF_STR( Very_Hard ) )
227 PORT_DIPNAME( 0x0030, 0x0030, DEF_STR( Language ) ) PORT_DIPLOCATION("SW1:5,6")
228 PORT_DIPSETTING( 0x0010, DEF_STR( Chinese ) )
229 PORT_DIPSETTING( 0x0030, DEF_STR( Japanese ) ) /* Only setting to give a "For use only in...." Copyright Notice */
230 PORT_DIPSETTING( 0x0000, DEF_STR( Korean ) )
231 PORT_DIPSETTING( 0x0020, DEF_STR( English ) )
232 PORT_DIPNAME( 0x00c0, 0x00c0, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:7,8")
233 PORT_DIPSETTING( 0x0000, "2" )
234 PORT_DIPSETTING( 0x00c0, "3" )
235 PORT_DIPSETTING( 0x0080, "4" )
236 PORT_DIPSETTING( 0x0040, "5" )
237
238 PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW2:1")
239 PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
240 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
241 PORT_DIPUNUSED_DIPLOC( 0x0200, 0x0200, "SW2:2" ) /* Manual states this dip is "Unused" */
242 PORT_DIPNAME( 0x1c00, 0x1c00, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW2:3,4,5")
243 PORT_DIPSETTING( 0x0400, DEF_STR( 4C_1C ) )
244 PORT_DIPSETTING( 0x1400, DEF_STR( 3C_1C ) )
245 PORT_DIPSETTING( 0x0c00, DEF_STR( 2C_1C ) )
246 PORT_DIPSETTING( 0x1c00, DEF_STR( 1C_1C ) )
247 PORT_DIPSETTING( 0x1800, DEF_STR( 1C_2C ) )
248 PORT_DIPSETTING( 0x0800, DEF_STR( 1C_3C ) )
249 PORT_DIPSETTING( 0x1000, DEF_STR( 1C_4C ) )
250 PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) )
251 PORT_DIPUNUSED_DIPLOC( 0x2000, 0x2000, "SW2:6" )
252 PORT_DIPUNUSED_DIPLOC( 0x4000, 0x4000, "SW2:7" )
253 PORT_DIPUNUSED_DIPLOC( 0x8000, 0x8000, "SW2:8" )
254 /*
255 PORT_DIPNAME( 0xe000, 0xe000, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW2:6,7,8")
256 PORT_DIPSETTING( 0x2000, DEF_STR( 4C_1C ) )
257 PORT_DIPSETTING( 0xa000, DEF_STR( 3C_1C ) )
258 PORT_DIPSETTING( 0x6000, DEF_STR( 2C_1C ) )
259 PORT_DIPSETTING( 0xe000, DEF_STR( 1C_1C ) )
260 PORT_DIPSETTING( 0xc000, DEF_STR( 1C_2C ) )
261 PORT_DIPSETTING( 0x4000, DEF_STR( 1C_3C ) )
262 PORT_DIPSETTING( 0x8000, DEF_STR( 1C_4C ) )
263 PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) )
264 */
265 INPUT_PORTS_END
266
267
268 static INPUT_PORTS_START( gogomileo ) /* The ealier version has different coinage settings. */
269 PORT_INCLUDE( gogomile )
270
271 PORT_MODIFY("DSW") // $880000.w
272 PORT_DIPNAME( 0x1c00, 0x1c00, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW2:3,4,5")
273 PORT_DIPSETTING( 0x1800, DEF_STR( 4C_1C ) )
274 PORT_DIPSETTING( 0x1400, DEF_STR( 3C_1C ) )
275 PORT_DIPSETTING( 0x1000, DEF_STR( 2C_1C ) )
276 PORT_DIPSETTING( 0x1c00, DEF_STR( 1C_1C ) )
277 PORT_DIPSETTING( 0x0400, DEF_STR( 1C_2C ) )
278 PORT_DIPSETTING( 0x0800, DEF_STR( 1C_3C ) )
279 PORT_DIPSETTING( 0x0c00, DEF_STR( 1C_4C ) )
280 PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) )
281 /*
282 PORT_DIPNAME( 0xe000, 0xe000, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW2:6,7,8")
283 PORT_DIPSETTING( 0xc000, DEF_STR( 4C_1C ) )
284 PORT_DIPSETTING( 0xa000, DEF_STR( 3C_1C ) )
285 PORT_DIPSETTING( 0x8000, DEF_STR( 2C_1C ) )
286 PORT_DIPSETTING( 0xe000, DEF_STR( 1C_1C ) )
287 PORT_DIPSETTING( 0x2000, DEF_STR( 1C_2C ) )
288 PORT_DIPSETTING( 0x4000, DEF_STR( 1C_3C ) )
289 PORT_DIPSETTING( 0x6000, DEF_STR( 1C_4C ) )
290 PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) )
291 */
292 INPUT_PORTS_END
293
294 static INPUT_PORTS_START( pbancho )
295 PORT_INCLUDE( gogomile )
296
297 PORT_MODIFY("SYSTEM") // $800000.w
298 PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN2 )
299 PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_SERVICE1 )
300
301 PORT_MODIFY("DSW") // $880000.w
302 PORT_DIPNAME( 0x001c, 0x001c, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:3,4,5")
303 PORT_DIPSETTING( 0x0008, DEF_STR( Easiest ) ) // 1
304 PORT_DIPSETTING( 0x0010, DEF_STR( Easy ) ) // 2
305 PORT_DIPSETTING( 0x001c, DEF_STR( Normal ) ) // 3
306 PORT_DIPSETTING( 0x0018, DEF_STR( Hard ) ) // 4
307 PORT_DIPSETTING( 0x0004, DEF_STR( Hardest ) ) // 5
308 // PORT_DIPSETTING( 0x0000, DEF_STR( Normal ) ) // 3
309 // PORT_DIPSETTING( 0x000c, DEF_STR( Normal ) ) // 3
310 // PORT_DIPSETTING( 0x0014, DEF_STR( Normal ) ) // 3
311 PORT_DIPNAME( 0x0060, 0x0060, "Lives (Vs Mode)" ) PORT_DIPLOCATION("SW1:6,7")
312 PORT_DIPSETTING( 0x0000, "1" ) // 1 1
313 PORT_DIPSETTING( 0x0060, "2" ) // 2 3
314 // PORT_DIPSETTING( 0x0020, "2" ) // 2 3
315 PORT_DIPSETTING( 0x0040, "3" ) // 3 5
316 PORT_DIPNAME( 0x0080, 0x0080, "? Senin Mode ?" ) PORT_DIPLOCATION("SW1:8")
317 PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
318 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
319
320 PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW2:1")
321 PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
322 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
323 PORT_DIPNAME( 0x0200, 0x0200, "Allow Versus Mode" ) PORT_DIPLOCATION("SW2:2") // "unused" in the manual?
324 PORT_DIPSETTING( 0x0000, DEF_STR( No ) )
325 PORT_DIPSETTING( 0x0200, DEF_STR( Yes ) )
326 PORT_DIPNAME( 0x1c00, 0x1c00, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW2:3,4,5")
327 PORT_DIPSETTING( 0x0c00, DEF_STR( 4C_1C ) )
328 PORT_DIPSETTING( 0x1400, DEF_STR( 3C_1C ) )
329 PORT_DIPSETTING( 0x0400, DEF_STR( 2C_1C ) )
330 PORT_DIPSETTING( 0x1c00, DEF_STR( 1C_1C ) )
331 PORT_DIPSETTING( 0x1000, DEF_STR( 1C_2C ) )
332 PORT_DIPSETTING( 0x0800, DEF_STR( 1C_3C ) )
333 PORT_DIPSETTING( 0x1800, DEF_STR( 1C_4C ) )
334 PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) )
335 PORT_DIPNAME( 0xe000, 0xe000, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW2:6,7,8")
336 PORT_DIPSETTING( 0x6000, DEF_STR( 4C_1C ) )
337 PORT_DIPSETTING( 0xa000, DEF_STR( 3C_1C ) )
338 PORT_DIPSETTING( 0x2000, DEF_STR( 2C_1C ) )
339 PORT_DIPSETTING( 0xe000, DEF_STR( 1C_1C ) )
340 PORT_DIPSETTING( 0x8000, DEF_STR( 1C_2C ) )
341 PORT_DIPSETTING( 0x4000, DEF_STR( 1C_3C ) )
342 PORT_DIPSETTING( 0xc000, DEF_STR( 1C_4C ) )
343 PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) )
344 INPUT_PORTS_END
345
346
347
348 /***************************************************************************
349
350
351 Graphics Layouts
352
353
354 ***************************************************************************/
355
356 /* 8x8x4 */
357 static const gfx_layout layout_8x8x4 =
358 {
359 8,8,
360 RGN_FRAC(1,1),
361 4,
362 { STEP4(0,1) },
363 { STEP8(0,4) },
364 { STEP8(0,8*4) },
365 8*8*4
366 };
367
368 /* 16x16x4 */
369 static const gfx_layout layout_16x16x4 =
370 {
371 16,16,
372 RGN_FRAC(1,1),
373 4,
374 { STEP4(0,1) },
375 { STEP16(0,4) },
376 { STEP16(0,16*4) },
377 16*16*4
378 };
379
380 /* 16x16x8 */
381 static const gfx_layout layout_16x16x8 =
382 {
383 16,16,
384 RGN_FRAC(1,1),
385 8,
386 { STEP4(0,1), STEP4(16,1) },
387 { STEP4(0,4), STEP4(16*2,4), STEP4(16*4,4), STEP4(16*6,4) },
388 { STEP16(0,16*8) },
389 16*16*8
390 };
391
392 static GFXDECODE_START( gfx_fuuki16 )
393 GFXDECODE_ENTRY( "gfx2", 0, layout_16x16x4, 0x400*0, 0x40 ) // [0] Layer 0
394 GFXDECODE_ENTRY( "gfx3", 0, layout_16x16x8, 0x400*1, 0x40 ) // [1] Layer 1
395 GFXDECODE_ENTRY( "gfx4", 0, layout_8x8x4, 0x400*3, 0x40 ) // [2] Layer 2
396 GFXDECODE_END
397
398
399 /***************************************************************************
400
401
402 Machine Drivers
403
404
405 ***************************************************************************/
406
407 /*
408 - Interrupts (pbancho) -
409
410 Lev 1: Sets bit 5 of $400010. Prints "credit .." with sprites.
411 Lev 2: Sets bit 7 of $400010. Clears $8c0012.
412 It seems unused by the game.
413 Lev 3: VBlank.
414 Lev 5: Programmable to happen on a raster line. Used to do raster
415 effects when you die and its clearing the blocks
416 also used for water effects and titlescreen linescroll on gogomile
417 */
418
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)419 void fuuki16_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
420 {
421 switch (id)
422 {
423 case TIMER_LEVEL_1_INTERRUPT:
424 m_maincpu->set_input_line(1, HOLD_LINE);
425 m_level_1_interrupt_timer->adjust(m_screen->time_until_pos(248));
426 break;
427 case TIMER_VBLANK_INTERRUPT:
428 m_maincpu->set_input_line(3, HOLD_LINE); // VBlank IRQ
429 m_vblank_interrupt_timer->adjust(m_screen->time_until_vblank_start());
430 break;
431 case TIMER_RASTER_INTERRUPT:
432 m_maincpu->set_input_line(5, HOLD_LINE); // Raster Line IRQ
433 m_screen->update_partial(m_screen->vpos());
434 m_raster_interrupt_timer->adjust(m_screen->frame_period());
435 break;
436 default:
437 throw emu_fatalerror("Unknown id in fuuki16_state::device_timer");
438 }
439 }
440
441
machine_start()442 void fuuki16_state::machine_start()
443 {
444 u8 *ROM = memregion("audiocpu")->base();
445
446 m_soundbank->configure_entries(0, 3, &ROM[0x8000], 0x8000);
447
448 m_level_1_interrupt_timer = timer_alloc(TIMER_LEVEL_1_INTERRUPT);
449 m_vblank_interrupt_timer = timer_alloc(TIMER_VBLANK_INTERRUPT);
450 m_raster_interrupt_timer = timer_alloc(TIMER_RASTER_INTERRUPT);
451 }
452
453
machine_reset()454 void fuuki16_state::machine_reset()
455 {
456 const rectangle &visarea = m_screen->visible_area();
457
458 m_level_1_interrupt_timer->adjust(m_screen->time_until_pos(248));
459 m_vblank_interrupt_timer->adjust(m_screen->time_until_vblank_start());
460 m_raster_interrupt_timer->adjust(m_screen->time_until_pos(0, visarea.max_x + 1));
461 }
462
463
fuuki16(machine_config & config)464 void fuuki16_state::fuuki16(machine_config &config)
465 {
466 /* basic machine hardware */
467 M68000(config, m_maincpu, XTAL(32'000'000) / 2); /* 16 MHz */
468 m_maincpu->set_addrmap(AS_PROGRAM, &fuuki16_state::fuuki16_map);
469
470 Z80(config, m_audiocpu, XTAL(12'000'000) / 2); /* 6 MHz */
471 m_audiocpu->set_addrmap(AS_PROGRAM, &fuuki16_state::fuuki16_sound_map);
472 m_audiocpu->set_addrmap(AS_IO, &fuuki16_state::fuuki16_sound_io_map);
473
474 /* video hardware */
475 SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
476 m_screen->set_refresh_hz(60);
477 m_screen->set_size(320, 256);
478 m_screen->set_visarea(0, 320-1, 0, 256-16-1);
479 m_screen->set_screen_update(FUNC(fuuki16_state::screen_update));
480 m_screen->set_palette(m_palette);
481
482 GFXDECODE(config, m_gfxdecode, m_palette, gfx_fuuki16);
483 PALETTE(config, m_palette).set_format(palette_device::xRGB_555, 0x4000 / 2);
484
485 FUUKI_VIDEO(config, m_fuukivid, 0);
486 m_fuukivid->set_palette(m_palette);
487 m_fuukivid->set_color_base(0x400*2);
488 m_fuukivid->set_color_num(0x40);
489 m_fuukivid->set_colpri_callback(FUNC(fuuki16_state::fuuki16_colpri_cb));
490
491 /* sound hardware */
492 SPEAKER(config, "mono").front_center();
493
494 GENERIC_LATCH_8(config, m_soundlatch);
495
496 ym2203_device &ym1(YM2203(config, "ym1", XTAL(28'640'000) / 8)); /* 3.58 MHz */
497 ym1.add_route(ALL_OUTPUTS, "mono", 0.15);
498
499 ym3812_device &ym2(YM3812(config, "ym2", XTAL(28'640'000) / 8)); /* 3.58 MHz */
500 ym2.irq_handler().set_inputline(m_audiocpu, 0);
501 ym2.add_route(ALL_OUTPUTS, "mono", 0.30);
502
503 OKIM6295(config, m_oki, XTAL(32'000'000) / 32, okim6295_device::PIN7_HIGH); /* 1 Mhz */
504 m_oki->add_route(ALL_OUTPUTS, "mono", 0.85);
505 }
506
507
508 /***************************************************************************
509
510 ROM Loading
511
512 ***************************************************************************/
513
514 /***************************************************************************
515
516 Go! Go! Mile Smile / Susume! Mile Smile
517
518 (c)1995 Fuuki
519 FG-1C AI AM-2 (same board as Gyakuten Puzzle Banchou)
520
521 CPU : TMP68HC000P-16
522 Sound: Z80 YM2203C YM3812 M6295 Y3014Bx2
523 OSC : 32.00000MHz(OSC1) 28.64000MHz(OSC2) 12.000MHz(Xtal1)
524
525 ROMs:
526 fp2.rom2 - Main programs (27c4000)
527 fp1.rom1 /
528
529 lh538n1d.rom25 - Samples (Sharp mask, read as 27c8001)
530 fs1.rom24 - Sound program (27c010)
531
532 lh5370h8.rom11 - Sprites? (Sharp Mask, read as 27c160)
533 lh5370ha.rom12 |
534 lh5370h7.rom15 |
535 lh5370h9.rom16 /
536
537 lh537k2r.rom20 - Tiles? (Sharp Mask, read as 27c160)
538 lh5370hb.rom19 |
539 lh5370h6.rom3 /
540
541 Custom chips:
542 FI-002K (208pin PQFP, GA2)
543 FI-003K (208pin PQFP, GA3)
544
545
546 Others:
547 Mitsubishi M60067-0901FP 452100 (208pin PQFP, GA1)
548 5 GALs (GAL16V8B, not dumped)
549
550 Measured clocks:
551
552 68k - 16mhz, OSC1 / 2
553 Z80 - 6mhz, Xtal1 / 2
554 M6295 - 1mhz, OSC1 / 32
555 YM2203C - 3.58mhz, OSC2 / 8
556 YM3812 - 3.58mhz, OSC2 / 8
557
558 ***************************************************************************/
559
560 ROM_START( gogomile )
561 ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 Code */
562 ROM_LOAD16_BYTE( "fp2n.rom2", 0x000000, 0x080000, CRC(e73583a0) SHA1(05c6ee5cb2c151b32c462e8b920f9a57fb6cce5b) )
563 ROM_LOAD16_BYTE( "fp1n.rom1", 0x000001, 0x080000, CRC(7b110824) SHA1(980e326d3b9e113ed522be3076663a249da4e739) )
564
565 ROM_REGION( 0x20000, "audiocpu", 0 ) /* Z80 Code */
566 ROM_LOAD( "fs1.rom24", 0x00000, 0x20000, CRC(4e4bd371) SHA1(429e776135ce8960e147762763d952d16ed3f9d4) )
567
568 ROM_REGION( 0x200000, "fuukivid", 0 ) /* 16x16x4 Sprites */
569 ROM_LOAD16_WORD_SWAP( "lh537k2r.rom20", 0x000000, 0x200000, CRC(525dbf51) SHA1(f21876676cc60ed65bc86884da894b24830826bb) )
570
571 ROM_REGION( 0x200000, "gfx2", 0 ) /* 16x16x4 Tiles */
572 ROM_LOAD16_WORD_SWAP( "lh5370h6.rom3", 0x000000, 0x200000, CRC(e2ca7107) SHA1(7174c2e1e2106275ad41b53af22651dca492367a) ) // x11xxxxxxxxxxxxxxxxxx = 0xFF
573
574 ROM_REGION( 0x800000, "gfx3", 0 ) /* 16x16x8 Tiles */
575 ROM_LOAD32_WORD_SWAP( "lh5370h7.rom15", 0x000000, 0x200000, CRC(34921680) SHA1(d9862f106caa14ea6ad925174e6bf2d542511593) )
576 ROM_LOAD32_WORD_SWAP( "lh5370h8.rom11", 0x000002, 0x200000, CRC(9961c925) SHA1(c47b4f19f090527b3e0c04dd046aa9cd51ca0e16) )
577 ROM_LOAD32_WORD_SWAP( "lh5370h9.rom16", 0x400000, 0x200000, CRC(e0118483) SHA1(36f9068e6c81c171b4426c3794277742bbc926f5) )
578 ROM_LOAD32_WORD_SWAP( "lh5370ha.rom12", 0x400002, 0x200000, CRC(5f2a87de) SHA1(d7ed8f01b40aaf58126aaeee10ec7d948a144080) )
579
580 ROM_REGION( 0x200000, "gfx4", 0 ) /* 16x16x4 Tiles */
581 ROM_LOAD16_WORD_SWAP( "lh5370hb.rom19", 0x000000, 0x200000, CRC(bd1e896f) SHA1(075f7600cbced1d285cf32fc196844720eb12671) ) // FIRST AND SECOND HALF IDENTICAL
582
583 /* 0x40000 * 4: sounds+speech (japanese), sounds+speech (english) */
584 ROM_REGION( 0x100000, "oki", 0 ) /* Samples */
585 ROM_LOAD( "lh538n1d.rom25", 0x000000, 0x100000, CRC(01622a95) SHA1(8d414bfc6dcfab1cf9cfe5738eb5c2ff31b77df6) ) // 0x40000 * 4
586 ROM_END
587
588 ROM_START( gogomileo )
589 ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 Code */
590 ROM_LOAD16_BYTE( "fp2.rom2", 0x000000, 0x080000, CRC(28fd3e4e) SHA1(3303e5759c0781035c74354587e1916719695754) ) // 1xxxxxxxxxxxxxxxxxx = 0xFF
591 ROM_LOAD16_BYTE( "fp1.rom1", 0x000001, 0x080000, CRC(35a5fc45) SHA1(307207791cee7f40e88feffc5805ac25008a8566) ) // 1xxxxxxxxxxxxxxxxxx = 0xFF
592
593 ROM_REGION( 0x20000, "audiocpu", 0 ) /* Z80 Code */
594 ROM_LOAD( "fs1.rom24", 0x00000, 0x20000, CRC(4e4bd371) SHA1(429e776135ce8960e147762763d952d16ed3f9d4) )
595
596 ROM_REGION( 0x200000, "fuukivid", 0 ) /* 16x16x4 Sprites */
597 ROM_LOAD16_WORD_SWAP( "lh537k2r.rom20", 0x000000, 0x200000, CRC(525dbf51) SHA1(f21876676cc60ed65bc86884da894b24830826bb) )
598
599 ROM_REGION( 0x200000, "gfx2", 0 ) /* 16x16x4 Tiles */
600 ROM_LOAD16_WORD_SWAP( "lh5370h6.rom3", 0x000000, 0x200000, CRC(e2ca7107) SHA1(7174c2e1e2106275ad41b53af22651dca492367a) ) // x11xxxxxxxxxxxxxxxxxx = 0xFF
601
602 ROM_REGION( 0x800000, "gfx3", 0 ) /* 16x16x8 Tiles */
603 ROM_LOAD32_WORD_SWAP( "lh5370h7.rom15", 0x000000, 0x200000, CRC(34921680) SHA1(d9862f106caa14ea6ad925174e6bf2d542511593) )
604 ROM_LOAD32_WORD_SWAP( "lh5370h8.rom11", 0x000002, 0x200000, CRC(9961c925) SHA1(c47b4f19f090527b3e0c04dd046aa9cd51ca0e16) )
605 ROM_LOAD32_WORD_SWAP( "lh5370h9.rom16", 0x400000, 0x200000, CRC(e0118483) SHA1(36f9068e6c81c171b4426c3794277742bbc926f5) )
606 ROM_LOAD32_WORD_SWAP( "lh5370ha.rom12", 0x400002, 0x200000, CRC(5f2a87de) SHA1(d7ed8f01b40aaf58126aaeee10ec7d948a144080) )
607
608 ROM_REGION( 0x200000, "gfx4", 0 ) /* 16x16x4 Tiles */
609 ROM_LOAD16_WORD_SWAP( "lh5370hb.rom19", 0x000000, 0x200000, CRC(bd1e896f) SHA1(075f7600cbced1d285cf32fc196844720eb12671) ) // FIRST AND SECOND HALF IDENTICAL
610
611 /* 0x40000 * 4: sounds+speech (japanese), sounds+speech (english) */
612 ROM_REGION( 0x100000, "oki", 0 ) /* Samples */
613 ROM_LOAD( "lh538n1d.rom25", 0x000000, 0x100000, CRC(01622a95) SHA1(8d414bfc6dcfab1cf9cfe5738eb5c2ff31b77df6) ) // 0x40000 * 4
614 ROM_END
615
616
617
618 /***************************************************************************
619
620 Gyakuten!! Puzzle Bancho
621
622 (c)1996 Fuuki
623 FG-1C AI AM-2
624
625 CPU : TMP68HC000P-16
626 Sound: Z80 YM2203 YM3812 M6295
627 OSC : 32.00000MHz(OSC1) 28.64000MHz(OSC2) 12.000MHz(Xtal1)
628
629 ROMs:
630 no1.rom2 - Main program (even)(27c4000)
631 no2.rom1 - Main program (odd) (27c4000)
632
633 no3.rom25 - Samples (27c2001)
634 no4.rom24 - Sound program (27c010)
635
636 61.rom11 - Graphics (Mask, read as 27c160)
637 59.rom15 |
638 58.rom20 |
639 60.rom3 /
640
641 Custom chips:
642 FI-002K (208pin PQFP, GA2)
643 FI-003K (208pin PQFP, GA3)
644
645 Others:
646 Mitsubishi M60067-0901FP 452100 (208pin PQFP, GA1)
647
648 ***************************************************************************/
649
650 ROM_START( pbancho )
651 ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 Code */
652 ROM_LOAD16_BYTE( "no1.rom2", 0x000000, 0x080000, CRC(1b4fd178) SHA1(02cf3d2554b29cd253470d68ea959738f3b98dbe) ) // 1xxxxxxxxxxxxxxxxxx = 0xFF
653 ROM_LOAD16_BYTE( "no2,rom1", 0x000001, 0x080000, CRC(9cf510a5) SHA1(08e79b5bbd1c011c32f82dd15fba42d7898861be) ) // 1xxxxxxxxxxxxxxxxxx = 0xFF
654
655 ROM_REGION( 0x20000, "audiocpu", 0 ) /* Z80 Code */
656 ROM_LOAD( "no4.rom23", 0x00000, 0x20000, CRC(dfbfdb81) SHA1(84b0cbe843a9bbae43975afdbd029a9b76fd488b) )
657
658 ROM_REGION( 0x200000, "fuukivid", 0 ) /* 16x16x4 Sprites */
659 ROM_LOAD16_WORD_SWAP( "58.rom20", 0x000000, 0x200000, CRC(4dad0a2e) SHA1(a4f70557503110a5457b9096a79a5f249095fa55) )
660
661 ROM_REGION( 0x200000, "gfx2", 0 ) /* 16x16x4 Tiles */
662 ROM_LOAD16_WORD_SWAP( "60.rom3", 0x000000, 0x200000, CRC(a50a3c1b) SHA1(a2b30f9f83f5dc2e069d7559aefbda9929fc640c) )
663
664 ROM_REGION( 0x400000, "gfx3", 0 ) /* 16x16x8 Tiles */
665 ROM_LOAD32_WORD_SWAP( "59.rom15", 0x000000, 0x200000, CRC(b83dcb70) SHA1(b0b9df451535d85612fa095b4f694cf2e7930bca) )
666 ROM_LOAD32_WORD_SWAP( "61.rom11", 0x000002, 0x200000, CRC(7f1213b9) SHA1(f8d6432b270c4d0954602e430ddd26841eb05656) )
667
668 ROM_REGION( 0x200000, "gfx4", 0 ) /* 16x16x4 Tiles */
669 ROM_LOAD16_WORD_SWAP( "60.rom3", 0x000000, 0x200000, CRC(a50a3c1b) SHA1(a2b30f9f83f5dc2e069d7559aefbda9929fc640c) ) // ?maybe?
670
671 ROM_REGION( 0x040000, "oki", 0 ) /* Samples */
672 ROM_LOAD( "n03.rom25", 0x000000, 0x040000, CRC(a7bfb5ea) SHA1(61937eae4f8855bc09c494aff52d76d41dc3b76a) )
673 ROM_END
674
675
676 /***************************************************************************
677
678
679 Game Drivers
680
681
682 ***************************************************************************/
683
684 GAME( 1995, gogomile, 0, fuuki16, gogomile, fuuki16_state, empty_init, ROT0, "Fuuki", "Susume! Mile Smile / Go Go! Mile Smile (newer)", MACHINE_SUPPORTS_SAVE )
685 GAME( 1995, gogomileo, gogomile, fuuki16, gogomileo, fuuki16_state, empty_init, ROT0, "Fuuki", "Susume! Mile Smile / Go Go! Mile Smile (older)", MACHINE_SUPPORTS_SAVE )
686 GAME( 1996, pbancho, 0, fuuki16, pbancho, fuuki16_state, empty_init, ROT0, "Fuuki", "Gyakuten!! Puzzle Bancho (Japan)", MACHINE_SUPPORTS_SAVE )
687