1 /* Flower (c)1986 Komax
2  - Driver by InsideOutBoy
3 
4 todo:
5 
6 cleanups
7 colors, probably missing proms
8 fix sound
9 improve interrupts
10 sprite flipping is incorrect for one of the enemies so its probably wrong
11 screenshots look like the game has sprite zooming
12 http://emustatus.rainemu.com/games/flower.htm
13 
14 */
15 
16 /*
17 
18         FLOWER   CHIP PLACEMENT
19 
20 USES THREE Z80 CPU'S
21 
22 CHIP #  POSITION   TYPE
23 ------------------------
24 1        5J         27256   CONN BD
25 2        5F         27256    "
26 3        D9         27128    "
27 4        12A        27128    "
28 5        16A        27256    "
29 6        7E         2764    BOTTOM BD
30 15       9E          "       "
31 8        10E         "       "
32 9        12E         "       "
33 10       13E         "       "
34 11       14E         "       "
35 12       16E         "       "
36 13       17E         "       "
37 14       19E         "       "
38 */
39 
40 #include "vidhrdw/generic.h"
41 
42 data8_t *flower_sharedram;
43 
44 READ_HANDLER( flower_sharedram_r );
45 WRITE_HANDLER( flower_sharedram_w );
46 VIDEO_UPDATE( flower );
47 VIDEO_START( flower );
48 
49 
50 extern data8_t *flower_soundregs1,*flower_soundregs2;
51 int flower_sh_start(const struct MachineSound *msound);
52 void flower_sh_stop(void);
53 WRITE_HANDLER( flower_sound1_w );
54 WRITE_HANDLER( flower_sound2_w );
55 
56 
57 
58 
WRITE_HANDLER(flower_irq_ack)59 static WRITE_HANDLER( flower_irq_ack )
60 {
61 	cpu_set_irq_line(0, 0, CLEAR_LINE);
62 }
63 
64 
65 static int sn_irq_enable,sn_nmi_enable;
66 
WRITE_HANDLER(sn_irq_enable_w)67 static WRITE_HANDLER( sn_irq_enable_w )
68 {
69 	sn_irq_enable = data & 1;
70 
71 	cpu_set_irq_line(2, 0, CLEAR_LINE);
72 }
73 
INTERRUPT_GEN(sn_irq)74 static INTERRUPT_GEN( sn_irq )
75 {
76 	if (sn_irq_enable)
77 		cpu_set_irq_line(2, 0, ASSERT_LINE);
78 }
79 
WRITE_HANDLER(sn_nmi_enable_w)80 static WRITE_HANDLER( sn_nmi_enable_w )
81 {
82 	sn_nmi_enable = data & 1;
83 }
84 
WRITE_HANDLER(sound_command_w)85 static WRITE_HANDLER( sound_command_w )
86 {
87 	soundlatch_w(0,data);
88 	if (sn_nmi_enable)
89 		cpu_set_nmi_line(2, PULSE_LINE);
90 }
91 
92 
MEMORY_READ_START(flower_mn_readmem)93 static MEMORY_READ_START( flower_mn_readmem )
94 	{ 0x0000, 0x7fff, MRA_ROM },
95 	{ 0xa102, 0xa102, input_port_0_r },
96 	{ 0xa103, 0xa103, input_port_1_r },
97 	{ 0xc000, 0xffff, flower_sharedram_r },
98 MEMORY_END
99 
100 static MEMORY_WRITE_START( flower_mn_writemem )
101 	{ 0x0000, 0x7fff, MWA_ROM },
102 	{ 0xa000, 0xa000, MWA_NOP },	/*watchdog?*/
103 	{ 0xa001, 0xa001, MWA_NOP },	/*flip screen - check code at 0x759f*/
104 	{ 0xa002, 0xa002, flower_irq_ack },	/*irq ack / enable, maybe?*/
105 	{ 0xa004, 0xa004, MWA_NOP },	/*nmi enable (routine is empty)*/
106 	{ 0xc000, 0xffff, flower_sharedram_w, &flower_sharedram },	/*c23b-c62a cleared for something*/
107 MEMORY_END
108 
109 static MEMORY_READ_START( flower_sl_readmem )
110 	{ 0x0000, 0x7fff, MRA_ROM },
111 	{ 0xa100, 0xa100, input_port_2_r },
112 	{ 0xa101, 0xa101, input_port_3_r },
113 	{ 0xc000, 0xffff, flower_sharedram_r },
114 MEMORY_END
115 
116 static MEMORY_WRITE_START( flower_sl_writemem )
117 	{ 0x0000, 0x7fff, MWA_ROM },
118 	{ 0xa003, 0xa003, MWA_NOP },	/*irq enable*/
119 	{ 0xa005, 0xa005, MWA_NOP },	/*nmi enable (routine is empty)*/
120 	{ 0xa400, 0xa400, sound_command_w },
121 	{ 0xc000, 0xffff, flower_sharedram_w },
122 MEMORY_END
123 
124 static MEMORY_READ_START( flower_sn_readmem )
125 	{ 0x0000, 0x3fff, MRA_ROM },
126 	{ 0x6000, 0x6000, soundlatch_r },
127 	{ 0xc000, 0xc7ff, MRA_RAM },
128 MEMORY_END
129 
130 static MEMORY_WRITE_START( flower_sn_writemem )
131 	{ 0x0000, 0x3fff, MWA_ROM },
132 	{ 0x4000, 0x4000, sn_irq_enable_w },
133 	{ 0x4001, 0x4001, sn_nmi_enable_w },
134 	{ 0x8000, 0x803f, flower_sound1_w, &flower_soundregs1 },
135 	{ 0xa000, 0xa03f, flower_sound2_w, &flower_soundregs2 },
136 	{ 0xc000, 0xc7ff, MWA_RAM },
137 MEMORY_END
138 
139 
140 
141 INPUT_PORTS_START( flower )
142 	PORT_START	/* IN0 (CPU0) */
143 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
144 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1  )
145 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START2 )
146 	PORT_DIPNAME( 0x08, 0x08, DEF_STR( Difficulty ) )
147 	PORT_DIPSETTING(    0x08, "Easy" )
148 	PORT_DIPSETTING(    0x00, "Hard" )
149 	PORT_BITX(    0x10, 0x10, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Invulnerability", IP_KEY_NONE, IP_JOY_NONE )
150 	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
151 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
152 	PORT_DIPNAME( 0x20, 0x00, "Keep Items on Life Loss" )	/* check code at 0x74a2*/
153 	PORT_DIPSETTING(    0x20, DEF_STR( No ) )
154 	PORT_DIPSETTING(    0x00, DEF_STR( Yes ) )
155 	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unused ) )
156 	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
157 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
158 	PORT_DIPNAME( 0x80, 0x80, "Shot Range" )			/* check code at 0x75f9*/
159 	PORT_DIPSETTING(    0x80, "Medium" )
160 	PORT_DIPSETTING(    0x00, "Long" )
161 
162 	PORT_START	/* IN1 (CPU0) */
163 	PORT_DIPNAME( 0x07, 0x05, DEF_STR( Lives ) )		/* what should be the default value ?*/
164 	PORT_DIPSETTING(    0x07, "1" )
165 	PORT_DIPSETTING(    0x06, "2" )
166 	PORT_DIPSETTING(    0x05, "3" )
167 	PORT_DIPSETTING(    0x04, "4" )
168 	PORT_DIPSETTING(    0x03, "5" )
169 	PORT_DIPSETTING(    0x02, "6" )
170 	PORT_DIPSETTING(    0x01, "7" )
171 	PORT_BITX( 0,       0x00, IPT_DIPSWITCH_SETTING | IPF_CHEAT, "Infinite", 0, 0 )
172 	PORT_DIPNAME( 0x18, 0x18, DEF_STR( Coinage ) )
173 	PORT_DIPSETTING(    0x00, DEF_STR( 3C_1C ) )
174 	PORT_DIPSETTING(    0x08, DEF_STR( 2C_1C ) )
175 	PORT_DIPSETTING(    0x18, DEF_STR( 1C_1C ) )
176 	PORT_DIPSETTING(    0x10, DEF_STR( 1C_2C ) )
177 	PORT_DIPNAME( 0x20, 0x00, DEF_STR( Cabinet ) )		/* check code at 0x759f*/
178 	PORT_DIPSETTING(    0x00, DEF_STR( Upright ) )
179 	PORT_DIPSETTING(    0x20, DEF_STR( Cocktail ) )
180 	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unused ) )
181 	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
182 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
183 	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Bonus_Life ) )
184 	PORT_DIPSETTING(    0x80, "30k, 80k then every 50k" )
185 	PORT_DIPSETTING(    0x00, "50k, 130k then every 80k" )
186 
187 	PORT_START	/* IN0 (CPU1) */
188 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    )
189 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  )
190 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  )
191 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
192 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )			/* Fire (normal or laser)*/
193 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )			/* Missile*/
194 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 )			/* Cutter*/
195 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
196 
197 	PORT_START	/* IN1 (CPU1) */
198 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    | IPF_COCKTAIL )
199 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  | IPF_COCKTAIL )
200 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  | IPF_COCKTAIL )
201 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_COCKTAIL )
202 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_COCKTAIL )	/* Fire (normal or laser)*/
203 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_COCKTAIL )	/* Missile*/
204 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_COCKTAIL )	/* Cutter*/
205 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
206 INPUT_PORTS_END
207 
208 
209 
210 static struct GfxLayout flower_charlayout =
211 {
212 	8,8,
213 	RGN_FRAC(1,1),
214 	2,
215 	{ 0, 4 },
216 	{ STEP4(0,1), STEP4(8,1) },
217 	{ STEP8(0,16) },
218 	8*8*2
219 };
220 
221 static struct GfxLayout flower_spritelayout =
222 {
223 	16,16,
224 	RGN_FRAC(1,2),
225 	4,
226 	{ 0, 4, RGN_FRAC(1,2), RGN_FRAC(1,2)+4 },
227 	{ STEP4(0,1), STEP4(8,1), STEP4(8*8*2,1), STEP4(8*8*2+8,1) },
228 	{ STEP8(0,16), STEP8(8*8*4,16) },
229 	16*16*2
230 };
231 
232 static struct GfxDecodeInfo flower_gfxdecodeinfo[] =
233 {
234 	{ REGION_GFX1, 0, &flower_charlayout,   0,  8 },
235 	{ REGION_GFX2, 0, &flower_spritelayout, 0,  8 },
236 	{ REGION_GFX3, 0, &flower_spritelayout, 0,  8 },
237 	{ -1 }
238 };
239 
240 
241 
242 static struct CustomSound_interface custom_interface =
243 {
244 	flower_sh_start,
245 	flower_sh_stop,
246 	0
247 };
248 
249 
250 
251 static MACHINE_DRIVER_START( flower )
252 
253 	/* basic machine hardware */
254 	MDRV_CPU_ADD(Z80,8000000)
255 	MDRV_CPU_MEMORY(flower_mn_readmem,flower_mn_writemem)
256 	MDRV_CPU_VBLANK_INT(irq0_line_hold,10)
257 /*	MDRV_CPU_VBLANK_INT(nmi_line_pulse,1) */ /*nmis stuff up the writes to shared ram*/
258 
259 	MDRV_CPU_ADD(Z80,8000000)
260 	MDRV_CPU_MEMORY(flower_sl_readmem,flower_sl_writemem)
261 	MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
262 /*	MDRV_CPU_VBLANK_INT(nmi_line_pulse,1)*/
263 
264 	MDRV_CPU_ADD(Z80,8000000)
265 	MDRV_CPU_MEMORY(flower_sn_readmem,flower_sn_writemem)
266 	MDRV_CPU_PERIODIC_INT(sn_irq,90)	/* periodic interrupt, don't know about the frequency */
267 
268 
269 	MDRV_FRAMES_PER_SECOND(60)
270 	MDRV_VBLANK_DURATION(DEFAULT_60HZ_VBLANK_DURATION)
271 
272 	/* video hardware */
273 	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
274 	MDRV_SCREEN_SIZE(34*8, 33*8)
275 	MDRV_VISIBLE_AREA(0*8, 34*8-1, 0*8, 28*8-1)
276 	MDRV_GFXDECODE(flower_gfxdecodeinfo)
277 	MDRV_PALETTE_LENGTH(0x8000)
278 
279 	MDRV_VIDEO_START(flower)
280 	MDRV_VIDEO_UPDATE(flower)
281 
282 	/* sound hardware */
283 	MDRV_SOUND_ADD(CUSTOM, custom_interface)
284 MACHINE_DRIVER_END
285 
286 
287 ROM_START( flower )
288 	ROM_REGION( 0x10000, REGION_CPU1, 0 ) /* main cpu */
289 	ROM_LOAD( "1.5j",   0x0000, 0x8000, CRC(a4c3af78) SHA1(d149b0e0d82318273dd9cc5a143b175cdc818d0d) )
290 
291 	ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* sub cpu */
292 	ROM_LOAD( "2.5f",   0x0000, 0x8000, CRC(7c7ee2d8) SHA1(1e67bfe0f3585be5a6e6719ccf9db764bafbcb01) )
293 
294 	ROM_REGION( 0x10000, REGION_CPU3, 0 ) /* sound cpu */
295 	ROM_LOAD( "3.d9",   0x0000, 0x4000, CRC(8866c2b0) SHA1(d00f31994673e8087a1406f98e8832d07cedeb66) ) /* 1xxxxxxxxxxxxx = 0xFF*/
296 
297 	ROM_REGION( 0x2000, REGION_GFX1, 0 ) /* tx layer */
298 	ROM_LOAD( "10.13e", 0x0000, 0x2000, CRC(62f9b28c) SHA1(d57d06b99e72a4f68f197a5b6c042c926cc70ca0) ) /* FIRST AND SECOND HALF IDENTICAL*/
299 
300 	ROM_REGION( 0x8000, REGION_GFX2, 0 ) /* sprites */
301 	ROM_LOAD( "12.16e", 0x0000, 0x2000, CRC(e3779f7f) SHA1(8e12d06b3cdc2fcb7b77cc35f8eca45544cc4873) )
302 	ROM_LOAD( "11.14e", 0x2000, 0x2000, CRC(8801b34f) SHA1(256059fcd16b21e076db1c18fd9669128df1d658) )
303 	ROM_LOAD( "14.19e", 0x4000, 0x2000, CRC(11b491c5) SHA1(be1c4a0fbe8fd4e124c21e0f700efa0428376691) )
304 	ROM_LOAD( "13.17e", 0x6000, 0x2000, CRC(ea743986) SHA1(bbef4fd0f7d21cc89a52061fa50d7c2ea37287bd) )
305 
306 	ROM_REGION( 0x8000, REGION_GFX3, 0 ) /* bg layers */
307 	ROM_LOAD( "8.10e",  0x0000, 0x2000, CRC(f85eb20f) SHA1(699edc970c359143dee6de2a97cc2a552454785b) )
308 	ROM_LOAD( "6.7e",   0x2000, 0x2000, CRC(3e97843f) SHA1(4e4e5625dbf78eca97536b1428b2e49ad58c618f) )
309 	ROM_LOAD( "9.12e",  0x4000, 0x2000, CRC(f1d9915e) SHA1(158e1cc8c402f9ae3906363d99f2b25c94c64212) )
310 	ROM_LOAD( "15.9e",  0x6000, 0x2000, CRC(1cad9f72) SHA1(c38dbea266246ed4d47d12bdd8f9fae22a5f8bb8) )
311 
312 	ROM_REGION( 0x8000, REGION_SOUND1, 0 )
313 	ROM_LOAD( "4.12a",  0x0000, 0x8000, CRC(851ed9fd) SHA1(5dc048b612e45da529502bf33d968737a7b0a646) )	/* 8-bit samples */
314 
315 	ROM_REGION( 0x4000, REGION_SOUND2, 0 )
316 	ROM_LOAD( "5.16a",  0x0000, 0x4000, CRC(42fa2853) SHA1(cc1e8b8231d6f27f48b05d59390e93ea1c1c0e4c) )	/* volume tables? */
317 
318 	ROM_REGION( 0x100, REGION_PROMS, 0 )
319 	ROM_LOAD( "proms",  0x0000, 0x0100, NO_DUMP )
320 ROM_END
321 
322 
323 GAMEX( 1986, flower, 0, flower, flower, 0, ROT0, "Komax", "Flower", GAME_WRONG_COLORS | GAME_IMPERFECT_SOUND | GAME_NO_COCKTAIL )
324