Previous 199869 Revisions Next

r41649 Sunday 8th November, 2015 at 12:17:03 UTC by Miodrag Milanović
renamed rest of files (nw)
[src/mame/drivers]carpolo.c carpolo.cpp*
[src/mame/machine]carpolo.c carpolo.cpp*
[src/mame/video]carpolo.c carpolo.cpp*

trunk/src/mame/drivers/carpolo.c
r250160r250161
1// license:BSD-3-Clause
2// copyright-holders:Zsolt Vasvari
3/***************************************************************************
4
5    Exidy Car Polo hardware
6
7    driver by Zsolt Vasvari
8
9    Games supported:
10        * Car Polo
11
12    Known issues:
13        * sound
14
15     Original Bugs:
16        * if you insert a coin too fast (before the GAME OVER sign appears),
17          the cars will chase *away* from the ball
18
19****************************************************************************/
20
21#include "emu.h"
22#include "cpu/m6502/m6502.h"
23#include "machine/74153.h"
24#include "machine/6821pia.h"
25#include "includes/carpolo.h"
26
27
28
29/*************************************
30 *
31 *  Main CPU memory handlers
32 *
33 *************************************/
34
35static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, carpolo_state )
36   AM_RANGE(0x0000, 0x01ff) AM_RAM
37   AM_RANGE(0x3000, 0x30ff) AM_WRITEONLY AM_SHARE("alpharam")
38   AM_RANGE(0x4000, 0x400f) AM_WRITEONLY AM_SHARE("spriteram")
39   AM_RANGE(0x5400, 0x5403) AM_DEVREADWRITE("pia0", pia6821_device, read, write)
40   AM_RANGE(0x5800, 0x5803) AM_DEVREADWRITE("pia1", pia6821_device, read, write)
41   AM_RANGE(0xa000, 0xa000) AM_READ(carpolo_ball_screen_collision_cause_r)
42   AM_RANGE(0xa001, 0xa001) AM_READ(carpolo_car_ball_collision_x_r)
43   AM_RANGE(0xa002, 0xa002) AM_READ(carpolo_car_ball_collision_y_r)
44   AM_RANGE(0xa003, 0xa003) AM_READ(carpolo_car_car_collision_cause_r)
45   AM_RANGE(0xa004, 0xa004) AM_READ(carpolo_car_border_collision_cause_r)
46   AM_RANGE(0xa005, 0xa005) AM_READ(carpolo_car_ball_collision_cause_r)
47   AM_RANGE(0xa006, 0xa006) AM_READ(carpolo_car_goal_collision_cause_r)
48   AM_RANGE(0xa007, 0xa007) AM_READ_PORT("IN1")
49   AM_RANGE(0xb000, 0xb000) AM_WRITE(carpolo_ball_screen_interrupt_clear_w)
50   AM_RANGE(0xb001, 0xb001) AM_WRITE(carpolo_timer_interrupt_clear_w)
51   AM_RANGE(0xb003, 0xb003) AM_WRITE(carpolo_car_car_interrupt_clear_w)
52   AM_RANGE(0xb004, 0xb004) AM_WRITE(carpolo_car_border_interrupt_clear_w)
53   AM_RANGE(0xb005, 0xb005) AM_WRITE(carpolo_car_ball_interrupt_clear_w)
54   AM_RANGE(0xb006, 0xb006) AM_WRITE(carpolo_car_goal_interrupt_clear_w)
55   AM_RANGE(0xc000, 0xc000) AM_READ(carpolo_interrupt_cause_r)
56   AM_RANGE(0xf000, 0xffff) AM_ROM
57ADDRESS_MAP_END
58
59
60
61/*************************************
62 *
63 *  Port definitions
64 *
65 *************************************/
66
67static INPUT_PORTS_START( carpolo )
68   PORT_START("IN0")       /* IN0 */
69   PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
70   PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_COIN2 )
71   PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_COIN3 )
72   PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_COIN4 )
73   PORT_BIT (0xf0, IP_ACTIVE_HIGH, IPT_UNUSED )
74
75   /* the value read from here is used directly,
76      the result is calculated by 60/value */
77   PORT_START("IN1")       /* IN1 */
78   PORT_BIT (0x03, IP_ACTIVE_HIGH, IPT_UNUSED )    /* the lowest 2 bits of the counter */
79   PORT_DIPNAME( 0xfc, 0x3c, "Game Sec/Real Sec" )
80   PORT_DIPSETTING(    0x00, "0.23 (Longest)" )
81   PORT_DIPSETTING(    0xfc, "0.24" )
82   PORT_DIPSETTING(    0xf8, "0.24" )
83   PORT_DIPSETTING(    0xf4, "0.25" )
84   PORT_DIPSETTING(    0xf0, "0.25" )
85   PORT_DIPSETTING(    0xec, "0.25" )
86   PORT_DIPSETTING(    0xe8, "0.26" )
87   PORT_DIPSETTING(    0xe4, "0.26" )
88   PORT_DIPSETTING(    0xe0, "0.27" )
89   PORT_DIPSETTING(    0xdc, "0.27" )
90   PORT_DIPSETTING(    0xd8, "0.28" )
91   PORT_DIPSETTING(    0xd4, "0.28" )
92   PORT_DIPSETTING(    0xd0, "0.29" )
93   PORT_DIPSETTING(    0xcc, "0.29" )
94   PORT_DIPSETTING(    0xc8, "0.30" )
95   PORT_DIPSETTING(    0xc4, "0.31" )
96   PORT_DIPSETTING(    0xc0, "0.31" )
97   PORT_DIPSETTING(    0xbc, "0.32" )
98   PORT_DIPSETTING(    0xb8, "0.33" )
99   PORT_DIPSETTING(    0xb4, "0.33" )
100   PORT_DIPSETTING(    0xb0, "0.34" )
101   PORT_DIPSETTING(    0xac, "0.35" )
102   PORT_DIPSETTING(    0xa8, "0.36" )
103   PORT_DIPSETTING(    0xa4, "0.37" )
104   PORT_DIPSETTING(    0xa0, "0.38" )
105   PORT_DIPSETTING(    0x9c, "0.38" )
106   PORT_DIPSETTING(    0x98, "0.39" )
107   PORT_DIPSETTING(    0x94, "0.41" )
108   PORT_DIPSETTING(    0x90, "0.42" )
109   PORT_DIPSETTING(    0x8c, "0.44" )
110   PORT_DIPSETTING(    0x84, "0.46" )
111   PORT_DIPSETTING(    0x80, "0.47" )
112   PORT_DIPSETTING(    0x7c, "0.48" )
113   PORT_DIPSETTING(    0x78, "0.50" )
114   PORT_DIPSETTING(    0x74, "0.52" )
115   PORT_DIPSETTING(    0x70, "0.54" )
116   PORT_DIPSETTING(    0x6c, "0.56" )
117   PORT_DIPSETTING(    0x68, "0.58" )
118   PORT_DIPSETTING(    0x64, "0.60" )
119   PORT_DIPSETTING(    0x60, "0.63" )
120   PORT_DIPSETTING(    0x5c, "0.65" )
121   PORT_DIPSETTING(    0x58, "0.68" )
122   PORT_DIPSETTING(    0x54, "0.71" )
123   PORT_DIPSETTING(    0x50, "0.75" )
124   PORT_DIPSETTING(    0x4c, "0.79" )
125   PORT_DIPSETTING(    0x48, "0.83" )
126   PORT_DIPSETTING(    0x44, "0.88" )
127   PORT_DIPSETTING(    0x40, "0.94" )
128   PORT_DIPSETTING(    0x3c, "1.00" )
129   PORT_DIPSETTING(    0x38, "1.07" )
130   PORT_DIPSETTING(    0x34, "1.15" )
131   PORT_DIPSETTING(    0x30, "1.25" )
132   PORT_DIPSETTING(    0x2c, "1.36" )
133   PORT_DIPSETTING(    0x28, "1.50" )
134   PORT_DIPSETTING(    0x24, "1.67" )
135   PORT_DIPSETTING(    0x20, "1.88" )
136   PORT_DIPSETTING(    0x1c, "2.14" )
137   PORT_DIPSETTING(    0x18, "2.50" )
138   PORT_DIPSETTING(    0x14, "3.00" )
139   PORT_DIPSETTING(    0x10, "3.75" )
140   PORT_DIPSETTING(    0x0c, "5.00" )
141   PORT_DIPSETTING(    0x08, "7.50" )
142   PORT_DIPSETTING(    0x04, "15.00 (Shortest)" )
143
144   PORT_START("DIAL0")     /* IN2 */
145   PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(1)
146
147   PORT_START("DIAL1")     /* IN3 */
148   PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(2)
149
150   PORT_START("DIAL2")     /* IN4 */
151   PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(3)
152
153   PORT_START("DIAL3")     /* IN5 */
154   PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(4)
155
156   PORT_START("PEDALS")    /* IN6 - accelerator pedals */
157   PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1)
158   PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1)
159   PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
160   PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2)
161   PORT_BIT (0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(3)
162   PORT_BIT (0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(3)
163   PORT_BIT (0x40, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(4)
164   PORT_BIT (0x80, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(4)
165
166   PORT_START("IN2")       /* IN7 - forward/reverse */
167   PORT_BIT (0x0f, IP_ACTIVE_HIGH, IPT_UNUSED )
168   PORT_BIT (0x10, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4)
169   PORT_BIT (0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3)
170   PORT_BIT (0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
171   PORT_BIT (0x80, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
172INPUT_PORTS_END
173
174
175
176/*************************************
177 *
178 *  Graphics definitions
179 *
180 *************************************/
181
182static const gfx_layout spritelayout =
183{
184   16,16,
185   RGN_FRAC(1,4),
186   1,
187   { 0 },
188   { STEP4(3*0x100*8+4,1),
189      STEP4(2*0x100*8+4,1),
190      STEP4(1*0x100*8+4,1),
191      STEP4(0*0x100*8+4,1) },
192   { STEP16(0,8) },
193   16*8
194};
195
196static const gfx_layout goallayout =
197{
198   8,32,
199   1,
200   4,
201   { 4, 5, 6, 7 },
202   { STEP8(0,8) },
203   { STEP8(192*8,8*8),
204      STEP16( 0*8,8*8),
205      STEP8(128*8,8*8) },
206   0
207};
208
209static const gfx_layout alphalayout =
210{
211   8,8,
212   RGN_FRAC(1,1),
213   1,
214   { 0 },
215   { STEP8(0,1) },
216   { STEP8(0,8) },
217   8*8
218};
219
220static GFXDECODE_START( carpolo )
221   GFXDECODE_ENTRY( "gfx1", 0, spritelayout, 0,         12 )
222   GFXDECODE_ENTRY( "gfx2", 0, goallayout,   12*2,      2 )
223   GFXDECODE_ENTRY( "gfx3", 0, alphalayout,  12*2+2*16, 4 )
224GFXDECODE_END
225
226/*************************************
227 *
228 *  Machine driver
229 *
230 *************************************/
231
232static MACHINE_CONFIG_START( carpolo, carpolo_state )
233
234   /* basic machine hardware */
235   MCFG_CPU_ADD("maincpu", M6502, XTAL_11_289MHz/12)       /* 940.75 kHz */
236   MCFG_CPU_PROGRAM_MAP(main_map)
237   MCFG_CPU_VBLANK_INT_DRIVER("screen", carpolo_state,  carpolo_timer_interrupt)   /* this not strictly VBLANK,
238                                                       but it's supposed to happen 60
239                                                       times a sec, so it's a good place */
240
241   MCFG_DEVICE_ADD("pia0", PIA6821, 0)
242   MCFG_PIA_READPB_HANDLER(READ8(carpolo_state, pia_0_port_b_r))
243   MCFG_PIA_WRITEPA_HANDLER(WRITE8(carpolo_state, pia_0_port_a_w))
244   MCFG_PIA_WRITEPB_HANDLER(WRITE8(carpolo_state, pia_0_port_b_w))
245   MCFG_PIA_CA2_HANDLER(WRITELINE(carpolo_state, coin1_interrupt_clear_w))
246   MCFG_PIA_CB2_HANDLER(WRITELINE(carpolo_state,coin2_interrupt_clear_w))
247
248   MCFG_DEVICE_ADD("pia1", PIA6821, 0)
249   MCFG_PIA_READPA_HANDLER(READ8(carpolo_state, pia_1_port_a_r))
250   MCFG_PIA_READPB_HANDLER(READ8(carpolo_state, pia_1_port_b_r))
251   MCFG_PIA_CA2_HANDLER(WRITELINE(carpolo_state, coin3_interrupt_clear_w))
252   MCFG_PIA_CB2_HANDLER(WRITELINE(carpolo_state, coin4_interrupt_clear_w))
253
254   MCFG_DEVICE_ADD("7474_2s_1", TTL7474, 0)
255   MCFG_7474_COMP_OUTPUT_CB(WRITELINE(carpolo_state, carpolo_7474_2s_1_q_cb))
256
257   MCFG_DEVICE_ADD("7474_2s_2", TTL7474, 0)
258   MCFG_7474_COMP_OUTPUT_CB(WRITELINE(carpolo_state, carpolo_7474_2s_2_q_cb))
259
260   MCFG_DEVICE_ADD("7474_2u_1", TTL7474, 0)
261   MCFG_7474_COMP_OUTPUT_CB(WRITELINE(carpolo_state, carpolo_7474_2u_1_q_cb))
262
263   MCFG_DEVICE_ADD("7474_2u_2", TTL7474, 0)
264   MCFG_7474_COMP_OUTPUT_CB(WRITELINE(carpolo_state, carpolo_7474_2u_2_q_cb))
265
266   MCFG_DEVICE_ADD("7474_1f_1", TTL7474, 0)
267   MCFG_DEVICE_ADD("7474_1f_2", TTL7474, 0)
268   MCFG_DEVICE_ADD("7474_1d_1", TTL7474, 0)
269   MCFG_DEVICE_ADD("7474_1d_2", TTL7474, 0)
270   MCFG_DEVICE_ADD("7474_1c_1", TTL7474, 0)
271   MCFG_DEVICE_ADD("7474_1c_2", TTL7474, 0)
272   MCFG_DEVICE_ADD("7474_1a_1", TTL7474, 0)
273   MCFG_DEVICE_ADD("7474_1a_2", TTL7474, 0)
274
275   MCFG_DEVICE_ADD("74148_3s", TTL74148, 0)
276   MCFG_74148_OUTPUT_CB(carpolo_state, ttl74148_3s_cb)
277
278   MCFG_DEVICE_ADD("74153_1k", TTL74153, 0)
279
280   /* video hardware */
281   MCFG_SCREEN_ADD("screen", RASTER)
282   MCFG_SCREEN_REFRESH_RATE(60)
283   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
284   MCFG_SCREEN_SIZE(256, 256)
285   MCFG_SCREEN_VISIBLE_AREA(0, 239, 0, 255)
286   MCFG_SCREEN_UPDATE_DRIVER(carpolo_state, screen_update_carpolo)
287   MCFG_SCREEN_VBLANK_DRIVER(carpolo_state, screen_eof_carpolo)
288   MCFG_SCREEN_PALETTE("palette")
289
290   MCFG_GFXDECODE_ADD("gfxdecode", "palette", carpolo)
291   MCFG_PALETTE_ADD("palette", 12*2+2*16+4*2)
292   MCFG_PALETTE_INIT_OWNER(carpolo_state,carpolo)
293
294MACHINE_CONFIG_END
295
296
297
298/*************************************
299 *
300 *  ROM definitions
301 *
302 *************************************/
303
304ROM_START( carpolo )
305   ROM_REGION( 0x10000, "maincpu", 0 )
306   ROM_LOAD( "4000.6c",   0xf000, 0x0200, CRC(9d2e75a5) SHA1(c249d0b31de452738516f04a7bc3fb472d54f79d) )
307   ROM_LOAD( "4001.6d",   0xf200, 0x0200, CRC(69fb3768) SHA1(5fcc0807e560de0d73f8bab6943f3cad5ee324c9) )
308   ROM_LOAD( "4002.6h",   0xf400, 0x0200, CRC(5db179c7) SHA1(83615cdc1e3d8930cbdafbd0d327e1d6611faefd) )
309   ROM_LOAD( "4003.6k",   0xf600, 0x0200, CRC(0f992f09) SHA1(dfb8d96b94850166a1b5332f200ae9ceeffc1ce6) )
310   ROM_LOAD( "4004.6e",   0xf800, 0x0200, CRC(be731610) SHA1(70b035f75dd6eace94b4d7a8a344f136b8af743d) )
311   ROM_LOAD( "4005.6f",   0xfa00, 0x0200, CRC(7332f84f) SHA1(be548329918c4ac512fd6027d6bcd16d20c9dd98) )
312   ROM_LOAD( "4006.6l",   0xfc00, 0x0200, CRC(8479c350) SHA1(391c737947498aad4d478639cbbc72181d680fce) )
313   ROM_LOAD( "4007a.6n",  0xfe00, 0x0200, CRC(c6a619de) SHA1(c1b650a0126791fa733f89d9e9bdeeb605486a2c) )
314
315   ROM_REGION( 0x0400, "gfx1", 0 ) /* sprites */
316   ROM_LOAD( "1024.10w",  0x0000, 0x0100, CRC(eedacc7e) SHA1(d89628f013039ca387cafe22180de71e1553cffc) )
317   ROM_LOAD( "1023.10v",  0x0100, 0x0100, CRC(45df6c74) SHA1(a986b62b4c263c5d217bae0d51e74197f5288180) )
318   ROM_LOAD( "1022.10u",  0x0200, 0x0100, CRC(00868768) SHA1(2388e428db300a1e0005cccb9165ec604518033d) )
319   ROM_LOAD( "1021.10t",  0x0300, 0x0100, CRC(a508af9c) SHA1(219ba776d8cccf6726519aff17e37f2a6a85d0d1) )
320
321   ROM_REGION( 0x0100, "gfx2", 0 ) /* goal */
322   ROM_LOAD( "1020.6v",   0x0000, 0x0100, CRC(5e89fbcd) SHA1(6be171168924cd8aa94ff5e1994faecb6f303bd9) )
323
324   ROM_REGION( 0x0200, "gfx3", 0 ) /* alpha */
325   ROM_LOAD( "2513.4l",   0x0000, 0x0200, BAD_DUMP CRC(f80d8889) SHA1(ca573543dcce1221459d5693c476cef14bfac4f4)  ) /* MIA - stolen from Night Driver */
326
327   ROM_REGION( 0x0060, "proms", 0 )
328   ROM_LOAD( "328.5u",    0x0000, 0x0020, CRC(f295e0fc) SHA1(974a0481e0c6d5c0b6f0129653d8ed87880916e0) )       /* color PROM */
329   ROM_LOAD( "325.6t",    0x0020, 0x0020, CRC(b8b44022) SHA1(29fe6159c8d239c322296cef68ad59bcf290f246) )       /* horizontal timing */
330   ROM_LOAD( "326.6w",    0x0040, 0x0020, CRC(628ae3d1) SHA1(e6d43d2b5e8ec4b8c1adf6f29c2c9a43ab67ff50) )       /* vertical timing */
331
332   ROM_REGION( 0x0020, "user1", 0 )
333   ROM_LOAD( "327.10s",   0x0000, 0x0020, CRC(e047d24d) SHA1(2ea7afc8d97c906295bf2af929e0515f6c34137f) )       /* sprite image map */
334ROM_END
335
336
337
338/*************************************
339 *
340 *  Game drivers
341 *
342 *************************************/
343
344DRIVER_INIT_MEMBER(carpolo_state,carpolo)
345{
346   size_t i, len;
347   UINT8 *ROM;
348
349
350   /* invert gfx PROM since the bits are active LO */
351   ROM = memregion("gfx2")->base();
352   len = memregion("gfx2")->bytes();
353   for (i = 0;i < len; i++)
354      ROM[i] ^= 0x0f;
355}
356
357GAME( 1977, carpolo, 0, carpolo, carpolo, carpolo_state, carpolo, ROT0, "Exidy", "Car Polo", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND )
trunk/src/mame/drivers/carpolo.cpp
r0r250161
1// license:BSD-3-Clause
2// copyright-holders:Zsolt Vasvari
3/***************************************************************************
4
5    Exidy Car Polo hardware
6
7    driver by Zsolt Vasvari
8
9    Games supported:
10        * Car Polo
11
12    Known issues:
13        * sound
14
15     Original Bugs:
16        * if you insert a coin too fast (before the GAME OVER sign appears),
17          the cars will chase *away* from the ball
18
19****************************************************************************/
20
21#include "emu.h"
22#include "cpu/m6502/m6502.h"
23#include "machine/74153.h"
24#include "machine/6821pia.h"
25#include "includes/carpolo.h"
26
27
28
29/*************************************
30 *
31 *  Main CPU memory handlers
32 *
33 *************************************/
34
35static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, carpolo_state )
36   AM_RANGE(0x0000, 0x01ff) AM_RAM
37   AM_RANGE(0x3000, 0x30ff) AM_WRITEONLY AM_SHARE("alpharam")
38   AM_RANGE(0x4000, 0x400f) AM_WRITEONLY AM_SHARE("spriteram")
39   AM_RANGE(0x5400, 0x5403) AM_DEVREADWRITE("pia0", pia6821_device, read, write)
40   AM_RANGE(0x5800, 0x5803) AM_DEVREADWRITE("pia1", pia6821_device, read, write)
41   AM_RANGE(0xa000, 0xa000) AM_READ(carpolo_ball_screen_collision_cause_r)
42   AM_RANGE(0xa001, 0xa001) AM_READ(carpolo_car_ball_collision_x_r)
43   AM_RANGE(0xa002, 0xa002) AM_READ(carpolo_car_ball_collision_y_r)
44   AM_RANGE(0xa003, 0xa003) AM_READ(carpolo_car_car_collision_cause_r)
45   AM_RANGE(0xa004, 0xa004) AM_READ(carpolo_car_border_collision_cause_r)
46   AM_RANGE(0xa005, 0xa005) AM_READ(carpolo_car_ball_collision_cause_r)
47   AM_RANGE(0xa006, 0xa006) AM_READ(carpolo_car_goal_collision_cause_r)
48   AM_RANGE(0xa007, 0xa007) AM_READ_PORT("IN1")
49   AM_RANGE(0xb000, 0xb000) AM_WRITE(carpolo_ball_screen_interrupt_clear_w)
50   AM_RANGE(0xb001, 0xb001) AM_WRITE(carpolo_timer_interrupt_clear_w)
51   AM_RANGE(0xb003, 0xb003) AM_WRITE(carpolo_car_car_interrupt_clear_w)
52   AM_RANGE(0xb004, 0xb004) AM_WRITE(carpolo_car_border_interrupt_clear_w)
53   AM_RANGE(0xb005, 0xb005) AM_WRITE(carpolo_car_ball_interrupt_clear_w)
54   AM_RANGE(0xb006, 0xb006) AM_WRITE(carpolo_car_goal_interrupt_clear_w)
55   AM_RANGE(0xc000, 0xc000) AM_READ(carpolo_interrupt_cause_r)
56   AM_RANGE(0xf000, 0xffff) AM_ROM
57ADDRESS_MAP_END
58
59
60
61/*************************************
62 *
63 *  Port definitions
64 *
65 *************************************/
66
67static INPUT_PORTS_START( carpolo )
68   PORT_START("IN0")       /* IN0 */
69   PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
70   PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_COIN2 )
71   PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_COIN3 )
72   PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_COIN4 )
73   PORT_BIT (0xf0, IP_ACTIVE_HIGH, IPT_UNUSED )
74
75   /* the value read from here is used directly,
76      the result is calculated by 60/value */
77   PORT_START("IN1")       /* IN1 */
78   PORT_BIT (0x03, IP_ACTIVE_HIGH, IPT_UNUSED )    /* the lowest 2 bits of the counter */
79   PORT_DIPNAME( 0xfc, 0x3c, "Game Sec/Real Sec" )
80   PORT_DIPSETTING(    0x00, "0.23 (Longest)" )
81   PORT_DIPSETTING(    0xfc, "0.24" )
82   PORT_DIPSETTING(    0xf8, "0.24" )
83   PORT_DIPSETTING(    0xf4, "0.25" )
84   PORT_DIPSETTING(    0xf0, "0.25" )
85   PORT_DIPSETTING(    0xec, "0.25" )
86   PORT_DIPSETTING(    0xe8, "0.26" )
87   PORT_DIPSETTING(    0xe4, "0.26" )
88   PORT_DIPSETTING(    0xe0, "0.27" )
89   PORT_DIPSETTING(    0xdc, "0.27" )
90   PORT_DIPSETTING(    0xd8, "0.28" )
91   PORT_DIPSETTING(    0xd4, "0.28" )
92   PORT_DIPSETTING(    0xd0, "0.29" )
93   PORT_DIPSETTING(    0xcc, "0.29" )
94   PORT_DIPSETTING(    0xc8, "0.30" )
95   PORT_DIPSETTING(    0xc4, "0.31" )
96   PORT_DIPSETTING(    0xc0, "0.31" )
97   PORT_DIPSETTING(    0xbc, "0.32" )
98   PORT_DIPSETTING(    0xb8, "0.33" )
99   PORT_DIPSETTING(    0xb4, "0.33" )
100   PORT_DIPSETTING(    0xb0, "0.34" )
101   PORT_DIPSETTING(    0xac, "0.35" )
102   PORT_DIPSETTING(    0xa8, "0.36" )
103   PORT_DIPSETTING(    0xa4, "0.37" )
104   PORT_DIPSETTING(    0xa0, "0.38" )
105   PORT_DIPSETTING(    0x9c, "0.38" )
106   PORT_DIPSETTING(    0x98, "0.39" )
107   PORT_DIPSETTING(    0x94, "0.41" )
108   PORT_DIPSETTING(    0x90, "0.42" )
109   PORT_DIPSETTING(    0x8c, "0.44" )
110   PORT_DIPSETTING(    0x84, "0.46" )
111   PORT_DIPSETTING(    0x80, "0.47" )
112   PORT_DIPSETTING(    0x7c, "0.48" )
113   PORT_DIPSETTING(    0x78, "0.50" )
114   PORT_DIPSETTING(    0x74, "0.52" )
115   PORT_DIPSETTING(    0x70, "0.54" )
116   PORT_DIPSETTING(    0x6c, "0.56" )
117   PORT_DIPSETTING(    0x68, "0.58" )
118   PORT_DIPSETTING(    0x64, "0.60" )
119   PORT_DIPSETTING(    0x60, "0.63" )
120   PORT_DIPSETTING(    0x5c, "0.65" )
121   PORT_DIPSETTING(    0x58, "0.68" )
122   PORT_DIPSETTING(    0x54, "0.71" )
123   PORT_DIPSETTING(    0x50, "0.75" )
124   PORT_DIPSETTING(    0x4c, "0.79" )
125   PORT_DIPSETTING(    0x48, "0.83" )
126   PORT_DIPSETTING(    0x44, "0.88" )
127   PORT_DIPSETTING(    0x40, "0.94" )
128   PORT_DIPSETTING(    0x3c, "1.00" )
129   PORT_DIPSETTING(    0x38, "1.07" )
130   PORT_DIPSETTING(    0x34, "1.15" )
131   PORT_DIPSETTING(    0x30, "1.25" )
132   PORT_DIPSETTING(    0x2c, "1.36" )
133   PORT_DIPSETTING(    0x28, "1.50" )
134   PORT_DIPSETTING(    0x24, "1.67" )
135   PORT_DIPSETTING(    0x20, "1.88" )
136   PORT_DIPSETTING(    0x1c, "2.14" )
137   PORT_DIPSETTING(    0x18, "2.50" )
138   PORT_DIPSETTING(    0x14, "3.00" )
139   PORT_DIPSETTING(    0x10, "3.75" )
140   PORT_DIPSETTING(    0x0c, "5.00" )
141   PORT_DIPSETTING(    0x08, "7.50" )
142   PORT_DIPSETTING(    0x04, "15.00 (Shortest)" )
143
144   PORT_START("DIAL0")     /* IN2 */
145   PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(1)
146
147   PORT_START("DIAL1")     /* IN3 */
148   PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(2)
149
150   PORT_START("DIAL2")     /* IN4 */
151   PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(3)
152
153   PORT_START("DIAL3")     /* IN5 */
154   PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(4)
155
156   PORT_START("PEDALS")    /* IN6 - accelerator pedals */
157   PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1)
158   PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1)
159   PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
160   PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2)
161   PORT_BIT (0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(3)
162   PORT_BIT (0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(3)
163   PORT_BIT (0x40, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(4)
164   PORT_BIT (0x80, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(4)
165
166   PORT_START("IN2")       /* IN7 - forward/reverse */
167   PORT_BIT (0x0f, IP_ACTIVE_HIGH, IPT_UNUSED )
168   PORT_BIT (0x10, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4)
169   PORT_BIT (0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3)
170   PORT_BIT (0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
171   PORT_BIT (0x80, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
172INPUT_PORTS_END
173
174
175
176/*************************************
177 *
178 *  Graphics definitions
179 *
180 *************************************/
181
182static const gfx_layout spritelayout =
183{
184   16,16,
185   RGN_FRAC(1,4),
186   1,
187   { 0 },
188   { STEP4(3*0x100*8+4,1),
189      STEP4(2*0x100*8+4,1),
190      STEP4(1*0x100*8+4,1),
191      STEP4(0*0x100*8+4,1) },
192   { STEP16(0,8) },
193   16*8
194};
195
196static const gfx_layout goallayout =
197{
198   8,32,
199   1,
200   4,
201   { 4, 5, 6, 7 },
202   { STEP8(0,8) },
203   { STEP8(192*8,8*8),
204      STEP16( 0*8,8*8),
205      STEP8(128*8,8*8) },
206   0
207};
208
209static const gfx_layout alphalayout =
210{
211   8,8,
212   RGN_FRAC(1,1),
213   1,
214   { 0 },
215   { STEP8(0,1) },
216   { STEP8(0,8) },
217   8*8
218};
219
220static GFXDECODE_START( carpolo )
221   GFXDECODE_ENTRY( "gfx1", 0, spritelayout, 0,         12 )
222   GFXDECODE_ENTRY( "gfx2", 0, goallayout,   12*2,      2 )
223   GFXDECODE_ENTRY( "gfx3", 0, alphalayout,  12*2+2*16, 4 )
224GFXDECODE_END
225
226/*************************************
227 *
228 *  Machine driver
229 *
230 *************************************/
231
232static MACHINE_CONFIG_START( carpolo, carpolo_state )
233
234   /* basic machine hardware */
235   MCFG_CPU_ADD("maincpu", M6502, XTAL_11_289MHz/12)       /* 940.75 kHz */
236   MCFG_CPU_PROGRAM_MAP(main_map)
237   MCFG_CPU_VBLANK_INT_DRIVER("screen", carpolo_state,  carpolo_timer_interrupt)   /* this not strictly VBLANK,
238                                                       but it's supposed to happen 60
239                                                       times a sec, so it's a good place */
240
241   MCFG_DEVICE_ADD("pia0", PIA6821, 0)
242   MCFG_PIA_READPB_HANDLER(READ8(carpolo_state, pia_0_port_b_r))
243   MCFG_PIA_WRITEPA_HANDLER(WRITE8(carpolo_state, pia_0_port_a_w))
244   MCFG_PIA_WRITEPB_HANDLER(WRITE8(carpolo_state, pia_0_port_b_w))
245   MCFG_PIA_CA2_HANDLER(WRITELINE(carpolo_state, coin1_interrupt_clear_w))
246   MCFG_PIA_CB2_HANDLER(WRITELINE(carpolo_state,coin2_interrupt_clear_w))
247
248   MCFG_DEVICE_ADD("pia1", PIA6821, 0)
249   MCFG_PIA_READPA_HANDLER(READ8(carpolo_state, pia_1_port_a_r))
250   MCFG_PIA_READPB_HANDLER(READ8(carpolo_state, pia_1_port_b_r))
251   MCFG_PIA_CA2_HANDLER(WRITELINE(carpolo_state, coin3_interrupt_clear_w))
252   MCFG_PIA_CB2_HANDLER(WRITELINE(carpolo_state, coin4_interrupt_clear_w))
253
254   MCFG_DEVICE_ADD("7474_2s_1", TTL7474, 0)
255   MCFG_7474_COMP_OUTPUT_CB(WRITELINE(carpolo_state, carpolo_7474_2s_1_q_cb))
256
257   MCFG_DEVICE_ADD("7474_2s_2", TTL7474, 0)
258   MCFG_7474_COMP_OUTPUT_CB(WRITELINE(carpolo_state, carpolo_7474_2s_2_q_cb))
259
260   MCFG_DEVICE_ADD("7474_2u_1", TTL7474, 0)
261   MCFG_7474_COMP_OUTPUT_CB(WRITELINE(carpolo_state, carpolo_7474_2u_1_q_cb))
262
263   MCFG_DEVICE_ADD("7474_2u_2", TTL7474, 0)
264   MCFG_7474_COMP_OUTPUT_CB(WRITELINE(carpolo_state, carpolo_7474_2u_2_q_cb))
265
266   MCFG_DEVICE_ADD("7474_1f_1", TTL7474, 0)
267   MCFG_DEVICE_ADD("7474_1f_2", TTL7474, 0)
268   MCFG_DEVICE_ADD("7474_1d_1", TTL7474, 0)
269   MCFG_DEVICE_ADD("7474_1d_2", TTL7474, 0)
270   MCFG_DEVICE_ADD("7474_1c_1", TTL7474, 0)
271   MCFG_DEVICE_ADD("7474_1c_2", TTL7474, 0)
272   MCFG_DEVICE_ADD("7474_1a_1", TTL7474, 0)
273   MCFG_DEVICE_ADD("7474_1a_2", TTL7474, 0)
274
275   MCFG_DEVICE_ADD("74148_3s", TTL74148, 0)
276   MCFG_74148_OUTPUT_CB(carpolo_state, ttl74148_3s_cb)
277
278   MCFG_DEVICE_ADD("74153_1k", TTL74153, 0)
279
280   /* video hardware */
281   MCFG_SCREEN_ADD("screen", RASTER)
282   MCFG_SCREEN_REFRESH_RATE(60)
283   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
284   MCFG_SCREEN_SIZE(256, 256)
285   MCFG_SCREEN_VISIBLE_AREA(0, 239, 0, 255)
286   MCFG_SCREEN_UPDATE_DRIVER(carpolo_state, screen_update_carpolo)
287   MCFG_SCREEN_VBLANK_DRIVER(carpolo_state, screen_eof_carpolo)
288   MCFG_SCREEN_PALETTE("palette")
289
290   MCFG_GFXDECODE_ADD("gfxdecode", "palette", carpolo)
291   MCFG_PALETTE_ADD("palette", 12*2+2*16+4*2)
292   MCFG_PALETTE_INIT_OWNER(carpolo_state,carpolo)
293
294MACHINE_CONFIG_END
295
296
297
298/*************************************
299 *
300 *  ROM definitions
301 *
302 *************************************/
303
304ROM_START( carpolo )
305   ROM_REGION( 0x10000, "maincpu", 0 )
306   ROM_LOAD( "4000.6c",   0xf000, 0x0200, CRC(9d2e75a5) SHA1(c249d0b31de452738516f04a7bc3fb472d54f79d) )
307   ROM_LOAD( "4001.6d",   0xf200, 0x0200, CRC(69fb3768) SHA1(5fcc0807e560de0d73f8bab6943f3cad5ee324c9) )
308   ROM_LOAD( "4002.6h",   0xf400, 0x0200, CRC(5db179c7) SHA1(83615cdc1e3d8930cbdafbd0d327e1d6611faefd) )
309   ROM_LOAD( "4003.6k",   0xf600, 0x0200, CRC(0f992f09) SHA1(dfb8d96b94850166a1b5332f200ae9ceeffc1ce6) )
310   ROM_LOAD( "4004.6e",   0xf800, 0x0200, CRC(be731610) SHA1(70b035f75dd6eace94b4d7a8a344f136b8af743d) )
311   ROM_LOAD( "4005.6f",   0xfa00, 0x0200, CRC(7332f84f) SHA1(be548329918c4ac512fd6027d6bcd16d20c9dd98) )
312   ROM_LOAD( "4006.6l",   0xfc00, 0x0200, CRC(8479c350) SHA1(391c737947498aad4d478639cbbc72181d680fce) )
313   ROM_LOAD( "4007a.6n",  0xfe00, 0x0200, CRC(c6a619de) SHA1(c1b650a0126791fa733f89d9e9bdeeb605486a2c) )
314
315   ROM_REGION( 0x0400, "gfx1", 0 ) /* sprites */
316   ROM_LOAD( "1024.10w",  0x0000, 0x0100, CRC(eedacc7e) SHA1(d89628f013039ca387cafe22180de71e1553cffc) )
317   ROM_LOAD( "1023.10v",  0x0100, 0x0100, CRC(45df6c74) SHA1(a986b62b4c263c5d217bae0d51e74197f5288180) )
318   ROM_LOAD( "1022.10u",  0x0200, 0x0100, CRC(00868768) SHA1(2388e428db300a1e0005cccb9165ec604518033d) )
319   ROM_LOAD( "1021.10t",  0x0300, 0x0100, CRC(a508af9c) SHA1(219ba776d8cccf6726519aff17e37f2a6a85d0d1) )
320
321   ROM_REGION( 0x0100, "gfx2", 0 ) /* goal */
322   ROM_LOAD( "1020.6v",   0x0000, 0x0100, CRC(5e89fbcd) SHA1(6be171168924cd8aa94ff5e1994faecb6f303bd9) )
323
324   ROM_REGION( 0x0200, "gfx3", 0 ) /* alpha */
325   ROM_LOAD( "2513.4l",   0x0000, 0x0200, BAD_DUMP CRC(f80d8889) SHA1(ca573543dcce1221459d5693c476cef14bfac4f4)  ) /* MIA - stolen from Night Driver */
326
327   ROM_REGION( 0x0060, "proms", 0 )
328   ROM_LOAD( "328.5u",    0x0000, 0x0020, CRC(f295e0fc) SHA1(974a0481e0c6d5c0b6f0129653d8ed87880916e0) )       /* color PROM */
329   ROM_LOAD( "325.6t",    0x0020, 0x0020, CRC(b8b44022) SHA1(29fe6159c8d239c322296cef68ad59bcf290f246) )       /* horizontal timing */
330   ROM_LOAD( "326.6w",    0x0040, 0x0020, CRC(628ae3d1) SHA1(e6d43d2b5e8ec4b8c1adf6f29c2c9a43ab67ff50) )       /* vertical timing */
331
332   ROM_REGION( 0x0020, "user1", 0 )
333   ROM_LOAD( "327.10s",   0x0000, 0x0020, CRC(e047d24d) SHA1(2ea7afc8d97c906295bf2af929e0515f6c34137f) )       /* sprite image map */
334ROM_END
335
336
337
338/*************************************
339 *
340 *  Game drivers
341 *
342 *************************************/
343
344DRIVER_INIT_MEMBER(carpolo_state,carpolo)
345{
346   size_t i, len;
347   UINT8 *ROM;
348
349
350   /* invert gfx PROM since the bits are active LO */
351   ROM = memregion("gfx2")->base();
352   len = memregion("gfx2")->bytes();
353   for (i = 0;i < len; i++)
354      ROM[i] ^= 0x0f;
355}
356
357GAME( 1977, carpolo, 0, carpolo, carpolo, carpolo_state, carpolo, ROT0, "Exidy", "Car Polo", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND )
trunk/src/mame/machine/carpolo.c
r250160r250161
1// license:BSD-3-Clause
2// copyright-holders:Zsolt Vasvari
3/***************************************************************************
4
5    Exidy Car Polo hardware
6
7    driver by Zsolt Vasvari
8
9****************************************************************************/
10
11#include "emu.h"
12#include "cpu/m6502/m6502.h"
13#include "machine/6821pia.h"
14#include "includes/carpolo.h"
15
16
17/*************************************
18 *
19 *  Interrupt system
20 *
21 *************************************/
22
23/* the interrupt system consists of a 74148 priority encoder
24   with the following interrupt priorites.  A lower number
25   indicates a lower priority (coins handled first):
26
27    7 - player 1 coin
28    6 - player 2 coin
29    5 - player 3 coin
30    4 - player 4 coin
31    3 - ball/screen object collision
32    2 - car/car collision
33    1 - car/goal collision
34    0 - timer               (bit 4=0, bit 6=0)
35    0 - car/ball collision  (bit 4=0, bit 6=1)
36    0 - car/border          (bit 4=1, bit 6=1)
37
38   After the interrupt is serviced, the code clears the
39   priority encoder's appropriate line by pulling it HI.  This
40   can trigger another interrupt immediately if there were
41   lower priority lines LO.
42
43   The four coin inputs are latched via 7474 flip-flop's. */
44
45#define COIN1_PRIORITY_LINE         7
46#define COIN2_PRIORITY_LINE         6
47#define COIN3_PRIORITY_LINE         5
48#define COIN4_PRIORITY_LINE         4
49#define BALL_SCREEN_PRIORITY_LINE   3
50#define CAR_CAR_PRIORITY_LINE       2
51#define CAR_GOAL_PRIORITY_LINE      1
52#define PRI0_PRIORTITY_LINE         0
53
54/* priority 0 controls three different things */
55#define TIMER_EXTRA_BITS            0x00
56#define CAR_BALL_EXTRA_BITS         0x40
57#define CAR_BORDER_EXTRA_BITS       0x50
58
59
60TTL74148_OUTPUT_CB(carpolo_state::ttl74148_3s_cb)
61{
62   m_maincpu->set_input_line(M6502_IRQ_LINE, m_ttl74148_3s->output_valid_r() ? CLEAR_LINE : ASSERT_LINE);
63}
64
65
66/* the outputs of the flip-flops are connected to the priority encoder */
67WRITE_LINE_MEMBER(carpolo_state::carpolo_7474_2s_1_q_cb)
68{
69   m_ttl74148_3s->input_line_w(COIN1_PRIORITY_LINE, state);
70   m_ttl74148_3s->update();
71}
72
73WRITE_LINE_MEMBER(carpolo_state::carpolo_7474_2s_2_q_cb)
74{
75   m_ttl74148_3s->input_line_w(COIN2_PRIORITY_LINE, state);
76   m_ttl74148_3s->update();
77}
78
79WRITE_LINE_MEMBER(carpolo_state::carpolo_7474_2u_1_q_cb)
80{
81   m_ttl74148_3s->input_line_w(COIN3_PRIORITY_LINE, state);
82   m_ttl74148_3s->update();
83}
84
85WRITE_LINE_MEMBER(carpolo_state::carpolo_7474_2u_2_q_cb)
86{
87   m_ttl74148_3s->input_line_w(COIN4_PRIORITY_LINE, state);
88   m_ttl74148_3s->update();
89}
90
91
92void carpolo_state::carpolo_generate_ball_screen_interrupt(UINT8 cause)
93{
94   m_ball_screen_collision_cause = cause;
95
96   m_ttl74148_3s->input_line_w(BALL_SCREEN_PRIORITY_LINE, 0);
97   m_ttl74148_3s->update();
98}
99
100void carpolo_state::carpolo_generate_car_car_interrupt(int car1, int car2)
101{
102   m_car_car_collision_cause = ~((1 << (3 - car1)) | (1 << (3 - car2)));
103
104   m_ttl74148_3s->input_line_w(CAR_CAR_PRIORITY_LINE, 0);
105   m_ttl74148_3s->update();
106}
107
108void carpolo_state::carpolo_generate_car_goal_interrupt(int car, int right_goal)
109{
110   m_car_goal_collision_cause = car | (right_goal ? 0x08 : 0x00);
111
112   m_ttl74148_3s->input_line_w(CAR_GOAL_PRIORITY_LINE, 0);
113   m_ttl74148_3s->update();
114}
115
116void carpolo_state::carpolo_generate_car_ball_interrupt(int car, int car_x, int car_y)
117{
118   m_car_ball_collision_cause = car;
119   m_car_ball_collision_x = car_x;
120   m_car_ball_collision_y = car_y;
121
122   m_priority_0_extension = CAR_BALL_EXTRA_BITS;
123
124   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 0);
125   m_ttl74148_3s->update();
126}
127
128void carpolo_state::carpolo_generate_car_border_interrupt(int car, int horizontal_border)
129{
130   m_car_border_collision_cause = car | (horizontal_border ? 0x04 : 0x00);
131
132   m_priority_0_extension = CAR_BORDER_EXTRA_BITS;
133
134   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 0);
135   m_ttl74148_3s->update();
136}
137
138
139READ8_MEMBER(carpolo_state::carpolo_ball_screen_collision_cause_r)
140{
141   /* bit 0 - 0=ball collided with border
142      bit 1 - 0=ball collided with goal
143      bit 2 - 0=ball collided with score area
144      bit 3 - which goal/score collided (0=left, 1=right) */
145   return m_ball_screen_collision_cause;
146}
147
148READ8_MEMBER(carpolo_state::carpolo_car_ball_collision_x_r)
149{
150   /* the x coordinate of the colliding pixel */
151   return m_car_ball_collision_x;
152}
153
154READ8_MEMBER(carpolo_state::carpolo_car_ball_collision_y_r)
155{
156   /* the y coordinate of the colliding pixel */
157   return m_car_ball_collision_y;
158}
159
160READ8_MEMBER(carpolo_state::carpolo_car_car_collision_cause_r)
161{
162   /* bit 0 - car 4 collided
163      bit 1 - car 3 collided
164      bit 2 - car 2 collided
165      bit 3 - car 1 collided */
166   return m_car_car_collision_cause;
167}
168
169READ8_MEMBER(carpolo_state::carpolo_car_goal_collision_cause_r)
170{
171   /* bit 0-1 - which car collided
172      bit 2   - horizontal timing bit 1TEC4 (not accessed)
173      bit 3   - which goal collided (0=left, 1=right) */
174   return m_car_goal_collision_cause;
175}
176
177READ8_MEMBER(carpolo_state::carpolo_car_ball_collision_cause_r)
178{
179   /* bit 0-1 - which car collided
180      bit 2-3 - unconnected */
181   return m_car_ball_collision_cause;
182}
183
184READ8_MEMBER(carpolo_state::carpolo_car_border_collision_cause_r)
185{
186   /* bit 0-1 - which car collided
187      bit 2   - 0=vertical border, 1=horizontal border */
188   return m_car_border_collision_cause;
189}
190
191
192READ8_MEMBER(carpolo_state::carpolo_interrupt_cause_r)
193{
194   /* the output of the 148 goes to bits 1-3 (which is priority ^ 7) */
195   return (m_ttl74148_3s->output_r() << 1) | m_priority_0_extension;
196}
197
198
199INTERRUPT_GEN_MEMBER(carpolo_state::carpolo_timer_interrupt)
200{
201   UINT8 port_value;
202   int player;
203
204
205   /* cause the timer interrupt */
206   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 0);
207   m_priority_0_extension = TIMER_EXTRA_BITS;
208
209   m_ttl74148_3s->update();
210
211
212   /* check the coins here as well - they drive the clock of the flip-flops */
213   port_value = ioport("IN0")->read();
214
215   m_ttl7474_2s_1->clock_w((port_value & 0x01) >> 0);
216   m_ttl7474_2s_2->clock_w((port_value & 0x02) >> 1);
217   m_ttl7474_2u_1->clock_w((port_value & 0x04) >> 2);
218   m_ttl7474_2u_2->clock_w((port_value & 0x08) >> 3);
219
220   /* read the steering controls */
221   for (player = 0; player < 4; player++)
222   {
223      static const char *const portnames[] = { "DIAL0", "DIAL1", "DIAL2", "DIAL3" };
224      ttl7474_device *movement_flip_flop;
225      ttl7474_device *dir_flip_flop;
226
227      switch (player)
228      {
229         default:
230         case 0: movement_flip_flop = m_ttl7474_1f_1;    dir_flip_flop = m_ttl7474_1f_2; break;
231         case 1: movement_flip_flop = m_ttl7474_1d_1;    dir_flip_flop = m_ttl7474_1d_2; break;
232         case 2: movement_flip_flop = m_ttl7474_1c_1;    dir_flip_flop = m_ttl7474_1c_2; break;
233         case 3: movement_flip_flop = m_ttl7474_1a_1;    dir_flip_flop = m_ttl7474_1a_2; break;
234      }
235
236      port_value = ioport(portnames[player])->read();
237
238      if (port_value != m_last_wheel_value[player])
239      {
240         /* set the movement direction */
241         dir_flip_flop->d_w(((port_value - m_last_wheel_value[player]) & 0x80) ? 1 : 0);
242
243         m_last_wheel_value[player] = port_value;
244      }
245
246      /* as the wheel moves, both flip-flops are clocked */
247      movement_flip_flop->clock_w(port_value & 0x01);
248      dir_flip_flop->clock_w(     port_value & 0x01);
249   }
250
251
252
253   /* finally read the accelerator pedals */
254   port_value = ioport("PEDALS")->read();
255
256   for (player = 0; player < 4; player++)
257   {
258      /* one line indicates if the pedal is pressed and the other
259         how much, resulting in only two different possible levels */
260      if (port_value & 0x01)
261      {
262         m_ttl74153_1k->input_line_w(0, player, 1);
263         m_ttl74153_1k->input_line_w(1, player, 0);
264      }
265      else if (port_value & 0x02)
266      {
267         m_ttl74153_1k->input_line_w(0, player, 1);
268         m_ttl74153_1k->input_line_w(1, player, 1);
269      }
270      else
271      {
272         m_ttl74153_1k->input_line_w(0, player, 0);
273         /* the other line is irrelevant */
274      }
275
276      port_value >>= 2;
277   }
278
279   m_ttl74153_1k->update();
280}
281
282// FIXME: Remove trampolines
283
284WRITE_LINE_MEMBER(carpolo_state::coin1_interrupt_clear_w)
285{
286   m_ttl7474_2s_1->clear_w(state);
287}
288
289WRITE_LINE_MEMBER(carpolo_state::coin2_interrupt_clear_w)
290{
291   m_ttl7474_2s_2->clear_w(state);
292}
293
294WRITE_LINE_MEMBER(carpolo_state::coin3_interrupt_clear_w)
295{
296   m_ttl7474_2u_1->clear_w(state);
297}
298
299WRITE_LINE_MEMBER(carpolo_state::coin4_interrupt_clear_w)
300{
301   m_ttl7474_2u_2->clear_w(state);
302}
303
304WRITE8_MEMBER(carpolo_state::carpolo_ball_screen_interrupt_clear_w)
305{
306   m_ttl74148_3s->input_line_w(BALL_SCREEN_PRIORITY_LINE, 1);
307   m_ttl74148_3s->update();
308}
309
310WRITE8_MEMBER(carpolo_state::carpolo_car_car_interrupt_clear_w)
311{
312   m_ttl74148_3s->input_line_w(CAR_CAR_PRIORITY_LINE, 1);
313   m_ttl74148_3s->update();
314}
315
316WRITE8_MEMBER(carpolo_state::carpolo_car_goal_interrupt_clear_w)
317{
318   m_ttl74148_3s->input_line_w(CAR_GOAL_PRIORITY_LINE, 1);
319   m_ttl74148_3s->update();
320}
321
322WRITE8_MEMBER(carpolo_state::carpolo_car_ball_interrupt_clear_w)
323{
324   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 1);
325   m_ttl74148_3s->update();
326}
327
328WRITE8_MEMBER(carpolo_state::carpolo_car_border_interrupt_clear_w)
329{
330   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 1);
331   m_ttl74148_3s->update();
332}
333
334WRITE8_MEMBER(carpolo_state::carpolo_timer_interrupt_clear_w)
335{
336   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 1);
337   m_ttl74148_3s->update();
338}
339
340
341/*************************************
342 *
343 *  Input port handling
344 *
345 *************************************/
346
347WRITE8_MEMBER(carpolo_state::pia_0_port_a_w)
348{
349   /* bit 0 - Coin counter
350      bit 1 - Player 4 crash sound
351      bit 2 - Player 3 crash sound
352      bit 3 - Clear steering wheel logic
353      bit 4 - Player 2 crash sound
354      bit 5 - Score pulse sound
355      bit 6 - Player 1 crash sound
356      bit 7 - Ball hit pulse sound */
357
358   coin_counter_w(machine(), 0, data & 0x01);
359
360
361   m_ttl7474_1f_1->clear_w((data & 0x08) >> 3);
362   m_ttl7474_1d_1->clear_w((data & 0x08) >> 3);
363   m_ttl7474_1c_1->clear_w((data & 0x08) >> 3);
364   m_ttl7474_1a_1->clear_w((data & 0x08) >> 3);
365}
366
367
368WRITE8_MEMBER(carpolo_state::pia_0_port_b_w)
369{
370   /* bit 0 - Strobe speed bits sound
371      bit 1 - Speed bit 0 sound
372      bit 2 - Speed bit 1 sound
373      bit 3 - Speed bit 2 sound
374      bit 6 - Select pedal 0
375      bit 7 - Select pdeal 1 */
376
377   m_ttl74153_1k->a_w(data & 0x40);
378   m_ttl74153_1k->b_w(data & 0x80);
379
380   m_ttl74153_1k->update();
381}
382
383READ8_MEMBER(carpolo_state::pia_0_port_b_r)
384{
385   /* bit 4 - Pedal bit 0
386      bit 5 - Pedal bit 1 */
387
388   return (m_ttl74153_1k->output_r(0) << 5) |
389         (m_ttl74153_1k->output_r(1) << 4);
390}
391
392
393READ8_MEMBER(carpolo_state::pia_1_port_a_r)
394{
395   UINT8 ret;
396
397   /* bit 0 - Player 4 steering input (left or right)
398      bit 1 - Player 3 steering input (left or right)
399      bit 2 - Player 2 steering input (left or right)
400      bit 3 - Player 1 steering input (left or right)
401      bit 4 - Player 4 forward/reverse input
402      bit 5 - Player 3 forward/reverse input
403      bit 6 - Player 2 forward/reverse input
404      bit 7 - Player 1 forward/reverse input */
405
406   ret = (m_ttl7474_1a_2->output_r() ? 0x01 : 0x00) |
407         (m_ttl7474_1c_2->output_r() ? 0x02 : 0x00) |
408         (m_ttl7474_1d_2->output_r() ? 0x04 : 0x00) |
409         (m_ttl7474_1f_2->output_r() ? 0x08 : 0x00) |
410         (ioport("IN2")->read() & 0xf0);
411
412   return ret;
413}
414
415
416READ8_MEMBER(carpolo_state::pia_1_port_b_r)
417{
418   UINT8 ret;
419
420   /* bit 4 - Player 4 steering input (wheel moving or stopped)
421      bit 5 - Player 3 steering input (wheel moving or stopped)
422      bit 6 - Player 2 steering input (wheel moving or stopped)
423      bit 7 - Player 1 steering input (wheel moving or stopped) */
424
425   ret = (m_ttl7474_1a_1->output_r() ? 0x10 : 0x00) |
426         (m_ttl7474_1c_1->output_r() ? 0x20 : 0x00) |
427         (m_ttl7474_1d_1->output_r() ? 0x40 : 0x00) |
428         (m_ttl7474_1f_1->output_r() ? 0x80 : 0x00);
429
430   return ret;
431}
432
433void carpolo_state::machine_start()
434{
435   save_item(NAME(m_ball_screen_collision_cause));
436   save_item(NAME(m_car_ball_collision_x));
437   save_item(NAME(m_car_ball_collision_y));
438   save_item(NAME(m_car_car_collision_cause));
439   save_item(NAME(m_car_goal_collision_cause));
440   save_item(NAME(m_car_ball_collision_cause));
441   save_item(NAME(m_car_border_collision_cause));
442   save_item(NAME(m_priority_0_extension));
443   save_item(NAME(m_last_wheel_value));
444}
445
446void carpolo_state::machine_reset()
447{
448   /* set up the priority encoder */
449   m_ttl74148_3s->enable_input_w(0);  /* always enabled */
450
451   /* set up the coin handling flip-flops */
452   m_ttl7474_2s_1->d_w     (1);
453   m_ttl7474_2s_1->preset_w(1);
454
455   m_ttl7474_2s_2->d_w     (1);
456   m_ttl7474_2s_2->preset_w(1);
457
458   m_ttl7474_2u_1->d_w     (1);
459   m_ttl7474_2u_1->preset_w(1);
460
461   m_ttl7474_2u_2->d_w     (1);
462   m_ttl7474_2u_2->preset_w(1);
463
464
465   /* set up the steering handling flip-flops */
466   m_ttl7474_1f_1->d_w     (1);
467   m_ttl7474_1f_1->preset_w(1);
468
469   m_ttl7474_1f_2->clear_w (1);
470   m_ttl7474_1f_2->preset_w(1);
471
472   m_ttl7474_1d_1->d_w     (1);
473   m_ttl7474_1d_1->preset_w(1);
474
475   m_ttl7474_1d_2->clear_w (1);
476   m_ttl7474_1d_2->preset_w(1);
477
478   m_ttl7474_1c_1->d_w     (1);
479   m_ttl7474_1c_1->preset_w(1);
480
481   m_ttl7474_1c_2->clear_w (1);
482   m_ttl7474_1c_2->preset_w(1);
483
484   m_ttl7474_1a_1->d_w     (1);
485   m_ttl7474_1a_1->preset_w(1);
486
487   m_ttl7474_1a_2->clear_w (1);
488   m_ttl7474_1a_2->preset_w(1);
489
490
491   /* set up the pedal handling chips */
492   m_ttl74153_1k->enable_w(0, 0);
493   m_ttl74153_1k->enable_w(1, 0);
494}
trunk/src/mame/machine/carpolo.cpp
r0r250161
1// license:BSD-3-Clause
2// copyright-holders:Zsolt Vasvari
3/***************************************************************************
4
5    Exidy Car Polo hardware
6
7    driver by Zsolt Vasvari
8
9****************************************************************************/
10
11#include "emu.h"
12#include "cpu/m6502/m6502.h"
13#include "machine/6821pia.h"
14#include "includes/carpolo.h"
15
16
17/*************************************
18 *
19 *  Interrupt system
20 *
21 *************************************/
22
23/* the interrupt system consists of a 74148 priority encoder
24   with the following interrupt priorites.  A lower number
25   indicates a lower priority (coins handled first):
26
27    7 - player 1 coin
28    6 - player 2 coin
29    5 - player 3 coin
30    4 - player 4 coin
31    3 - ball/screen object collision
32    2 - car/car collision
33    1 - car/goal collision
34    0 - timer               (bit 4=0, bit 6=0)
35    0 - car/ball collision  (bit 4=0, bit 6=1)
36    0 - car/border          (bit 4=1, bit 6=1)
37
38   After the interrupt is serviced, the code clears the
39   priority encoder's appropriate line by pulling it HI.  This
40   can trigger another interrupt immediately if there were
41   lower priority lines LO.
42
43   The four coin inputs are latched via 7474 flip-flop's. */
44
45#define COIN1_PRIORITY_LINE         7
46#define COIN2_PRIORITY_LINE         6
47#define COIN3_PRIORITY_LINE         5
48#define COIN4_PRIORITY_LINE         4
49#define BALL_SCREEN_PRIORITY_LINE   3
50#define CAR_CAR_PRIORITY_LINE       2
51#define CAR_GOAL_PRIORITY_LINE      1
52#define PRI0_PRIORTITY_LINE         0
53
54/* priority 0 controls three different things */
55#define TIMER_EXTRA_BITS            0x00
56#define CAR_BALL_EXTRA_BITS         0x40
57#define CAR_BORDER_EXTRA_BITS       0x50
58
59
60TTL74148_OUTPUT_CB(carpolo_state::ttl74148_3s_cb)
61{
62   m_maincpu->set_input_line(M6502_IRQ_LINE, m_ttl74148_3s->output_valid_r() ? CLEAR_LINE : ASSERT_LINE);
63}
64
65
66/* the outputs of the flip-flops are connected to the priority encoder */
67WRITE_LINE_MEMBER(carpolo_state::carpolo_7474_2s_1_q_cb)
68{
69   m_ttl74148_3s->input_line_w(COIN1_PRIORITY_LINE, state);
70   m_ttl74148_3s->update();
71}
72
73WRITE_LINE_MEMBER(carpolo_state::carpolo_7474_2s_2_q_cb)
74{
75   m_ttl74148_3s->input_line_w(COIN2_PRIORITY_LINE, state);
76   m_ttl74148_3s->update();
77}
78
79WRITE_LINE_MEMBER(carpolo_state::carpolo_7474_2u_1_q_cb)
80{
81   m_ttl74148_3s->input_line_w(COIN3_PRIORITY_LINE, state);
82   m_ttl74148_3s->update();
83}
84
85WRITE_LINE_MEMBER(carpolo_state::carpolo_7474_2u_2_q_cb)
86{
87   m_ttl74148_3s->input_line_w(COIN4_PRIORITY_LINE, state);
88   m_ttl74148_3s->update();
89}
90
91
92void carpolo_state::carpolo_generate_ball_screen_interrupt(UINT8 cause)
93{
94   m_ball_screen_collision_cause = cause;
95
96   m_ttl74148_3s->input_line_w(BALL_SCREEN_PRIORITY_LINE, 0);
97   m_ttl74148_3s->update();
98}
99
100void carpolo_state::carpolo_generate_car_car_interrupt(int car1, int car2)
101{
102   m_car_car_collision_cause = ~((1 << (3 - car1)) | (1 << (3 - car2)));
103
104   m_ttl74148_3s->input_line_w(CAR_CAR_PRIORITY_LINE, 0);
105   m_ttl74148_3s->update();
106}
107
108void carpolo_state::carpolo_generate_car_goal_interrupt(int car, int right_goal)
109{
110   m_car_goal_collision_cause = car | (right_goal ? 0x08 : 0x00);
111
112   m_ttl74148_3s->input_line_w(CAR_GOAL_PRIORITY_LINE, 0);
113   m_ttl74148_3s->update();
114}
115
116void carpolo_state::carpolo_generate_car_ball_interrupt(int car, int car_x, int car_y)
117{
118   m_car_ball_collision_cause = car;
119   m_car_ball_collision_x = car_x;
120   m_car_ball_collision_y = car_y;
121
122   m_priority_0_extension = CAR_BALL_EXTRA_BITS;
123
124   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 0);
125   m_ttl74148_3s->update();
126}
127
128void carpolo_state::carpolo_generate_car_border_interrupt(int car, int horizontal_border)
129{
130   m_car_border_collision_cause = car | (horizontal_border ? 0x04 : 0x00);
131
132   m_priority_0_extension = CAR_BORDER_EXTRA_BITS;
133
134   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 0);
135   m_ttl74148_3s->update();
136}
137
138
139READ8_MEMBER(carpolo_state::carpolo_ball_screen_collision_cause_r)
140{
141   /* bit 0 - 0=ball collided with border
142      bit 1 - 0=ball collided with goal
143      bit 2 - 0=ball collided with score area
144      bit 3 - which goal/score collided (0=left, 1=right) */
145   return m_ball_screen_collision_cause;
146}
147
148READ8_MEMBER(carpolo_state::carpolo_car_ball_collision_x_r)
149{
150   /* the x coordinate of the colliding pixel */
151   return m_car_ball_collision_x;
152}
153
154READ8_MEMBER(carpolo_state::carpolo_car_ball_collision_y_r)
155{
156   /* the y coordinate of the colliding pixel */
157   return m_car_ball_collision_y;
158}
159
160READ8_MEMBER(carpolo_state::carpolo_car_car_collision_cause_r)
161{
162   /* bit 0 - car 4 collided
163      bit 1 - car 3 collided
164      bit 2 - car 2 collided
165      bit 3 - car 1 collided */
166   return m_car_car_collision_cause;
167}
168
169READ8_MEMBER(carpolo_state::carpolo_car_goal_collision_cause_r)
170{
171   /* bit 0-1 - which car collided
172      bit 2   - horizontal timing bit 1TEC4 (not accessed)
173      bit 3   - which goal collided (0=left, 1=right) */
174   return m_car_goal_collision_cause;
175}
176
177READ8_MEMBER(carpolo_state::carpolo_car_ball_collision_cause_r)
178{
179   /* bit 0-1 - which car collided
180      bit 2-3 - unconnected */
181   return m_car_ball_collision_cause;
182}
183
184READ8_MEMBER(carpolo_state::carpolo_car_border_collision_cause_r)
185{
186   /* bit 0-1 - which car collided
187      bit 2   - 0=vertical border, 1=horizontal border */
188   return m_car_border_collision_cause;
189}
190
191
192READ8_MEMBER(carpolo_state::carpolo_interrupt_cause_r)
193{
194   /* the output of the 148 goes to bits 1-3 (which is priority ^ 7) */
195   return (m_ttl74148_3s->output_r() << 1) | m_priority_0_extension;
196}
197
198
199INTERRUPT_GEN_MEMBER(carpolo_state::carpolo_timer_interrupt)
200{
201   UINT8 port_value;
202   int player;
203
204
205   /* cause the timer interrupt */
206   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 0);
207   m_priority_0_extension = TIMER_EXTRA_BITS;
208
209   m_ttl74148_3s->update();
210
211
212   /* check the coins here as well - they drive the clock of the flip-flops */
213   port_value = ioport("IN0")->read();
214
215   m_ttl7474_2s_1->clock_w((port_value & 0x01) >> 0);
216   m_ttl7474_2s_2->clock_w((port_value & 0x02) >> 1);
217   m_ttl7474_2u_1->clock_w((port_value & 0x04) >> 2);
218   m_ttl7474_2u_2->clock_w((port_value & 0x08) >> 3);
219
220   /* read the steering controls */
221   for (player = 0; player < 4; player++)
222   {
223      static const char *const portnames[] = { "DIAL0", "DIAL1", "DIAL2", "DIAL3" };
224      ttl7474_device *movement_flip_flop;
225      ttl7474_device *dir_flip_flop;
226
227      switch (player)
228      {
229         default:
230         case 0: movement_flip_flop = m_ttl7474_1f_1;    dir_flip_flop = m_ttl7474_1f_2; break;
231         case 1: movement_flip_flop = m_ttl7474_1d_1;    dir_flip_flop = m_ttl7474_1d_2; break;
232         case 2: movement_flip_flop = m_ttl7474_1c_1;    dir_flip_flop = m_ttl7474_1c_2; break;
233         case 3: movement_flip_flop = m_ttl7474_1a_1;    dir_flip_flop = m_ttl7474_1a_2; break;
234      }
235
236      port_value = ioport(portnames[player])->read();
237
238      if (port_value != m_last_wheel_value[player])
239      {
240         /* set the movement direction */
241         dir_flip_flop->d_w(((port_value - m_last_wheel_value[player]) & 0x80) ? 1 : 0);
242
243         m_last_wheel_value[player] = port_value;
244      }
245
246      /* as the wheel moves, both flip-flops are clocked */
247      movement_flip_flop->clock_w(port_value & 0x01);
248      dir_flip_flop->clock_w(     port_value & 0x01);
249   }
250
251
252
253   /* finally read the accelerator pedals */
254   port_value = ioport("PEDALS")->read();
255
256   for (player = 0; player < 4; player++)
257   {
258      /* one line indicates if the pedal is pressed and the other
259         how much, resulting in only two different possible levels */
260      if (port_value & 0x01)
261      {
262         m_ttl74153_1k->input_line_w(0, player, 1);
263         m_ttl74153_1k->input_line_w(1, player, 0);
264      }
265      else if (port_value & 0x02)
266      {
267         m_ttl74153_1k->input_line_w(0, player, 1);
268         m_ttl74153_1k->input_line_w(1, player, 1);
269      }
270      else
271      {
272         m_ttl74153_1k->input_line_w(0, player, 0);
273         /* the other line is irrelevant */
274      }
275
276      port_value >>= 2;
277   }
278
279   m_ttl74153_1k->update();
280}
281
282// FIXME: Remove trampolines
283
284WRITE_LINE_MEMBER(carpolo_state::coin1_interrupt_clear_w)
285{
286   m_ttl7474_2s_1->clear_w(state);
287}
288
289WRITE_LINE_MEMBER(carpolo_state::coin2_interrupt_clear_w)
290{
291   m_ttl7474_2s_2->clear_w(state);
292}
293
294WRITE_LINE_MEMBER(carpolo_state::coin3_interrupt_clear_w)
295{
296   m_ttl7474_2u_1->clear_w(state);
297}
298
299WRITE_LINE_MEMBER(carpolo_state::coin4_interrupt_clear_w)
300{
301   m_ttl7474_2u_2->clear_w(state);
302}
303
304WRITE8_MEMBER(carpolo_state::carpolo_ball_screen_interrupt_clear_w)
305{
306   m_ttl74148_3s->input_line_w(BALL_SCREEN_PRIORITY_LINE, 1);
307   m_ttl74148_3s->update();
308}
309
310WRITE8_MEMBER(carpolo_state::carpolo_car_car_interrupt_clear_w)
311{
312   m_ttl74148_3s->input_line_w(CAR_CAR_PRIORITY_LINE, 1);
313   m_ttl74148_3s->update();
314}
315
316WRITE8_MEMBER(carpolo_state::carpolo_car_goal_interrupt_clear_w)
317{
318   m_ttl74148_3s->input_line_w(CAR_GOAL_PRIORITY_LINE, 1);
319   m_ttl74148_3s->update();
320}
321
322WRITE8_MEMBER(carpolo_state::carpolo_car_ball_interrupt_clear_w)
323{
324   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 1);
325   m_ttl74148_3s->update();
326}
327
328WRITE8_MEMBER(carpolo_state::carpolo_car_border_interrupt_clear_w)
329{
330   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 1);
331   m_ttl74148_3s->update();
332}
333
334WRITE8_MEMBER(carpolo_state::carpolo_timer_interrupt_clear_w)
335{
336   m_ttl74148_3s->input_line_w(PRI0_PRIORTITY_LINE, 1);
337   m_ttl74148_3s->update();
338}
339
340
341/*************************************
342 *
343 *  Input port handling
344 *
345 *************************************/
346
347WRITE8_MEMBER(carpolo_state::pia_0_port_a_w)
348{
349   /* bit 0 - Coin counter
350      bit 1 - Player 4 crash sound
351      bit 2 - Player 3 crash sound
352      bit 3 - Clear steering wheel logic
353      bit 4 - Player 2 crash sound
354      bit 5 - Score pulse sound
355      bit 6 - Player 1 crash sound
356      bit 7 - Ball hit pulse sound */
357
358   coin_counter_w(machine(), 0, data & 0x01);
359
360
361   m_ttl7474_1f_1->clear_w((data & 0x08) >> 3);
362   m_ttl7474_1d_1->clear_w((data & 0x08) >> 3);
363   m_ttl7474_1c_1->clear_w((data & 0x08) >> 3);
364   m_ttl7474_1a_1->clear_w((data & 0x08) >> 3);
365}
366
367
368WRITE8_MEMBER(carpolo_state::pia_0_port_b_w)
369{
370   /* bit 0 - Strobe speed bits sound
371      bit 1 - Speed bit 0 sound
372      bit 2 - Speed bit 1 sound
373      bit 3 - Speed bit 2 sound
374      bit 6 - Select pedal 0
375      bit 7 - Select pdeal 1 */
376
377   m_ttl74153_1k->a_w(data & 0x40);
378   m_ttl74153_1k->b_w(data & 0x80);
379
380   m_ttl74153_1k->update();
381}
382
383READ8_MEMBER(carpolo_state::pia_0_port_b_r)
384{
385   /* bit 4 - Pedal bit 0
386      bit 5 - Pedal bit 1 */
387
388   return (m_ttl74153_1k->output_r(0) << 5) |
389         (m_ttl74153_1k->output_r(1) << 4);
390}
391
392
393READ8_MEMBER(carpolo_state::pia_1_port_a_r)
394{
395   UINT8 ret;
396
397   /* bit 0 - Player 4 steering input (left or right)
398      bit 1 - Player 3 steering input (left or right)
399      bit 2 - Player 2 steering input (left or right)
400      bit 3 - Player 1 steering input (left or right)
401      bit 4 - Player 4 forward/reverse input
402      bit 5 - Player 3 forward/reverse input
403      bit 6 - Player 2 forward/reverse input
404      bit 7 - Player 1 forward/reverse input */
405
406   ret = (m_ttl7474_1a_2->output_r() ? 0x01 : 0x00) |
407         (m_ttl7474_1c_2->output_r() ? 0x02 : 0x00) |
408         (m_ttl7474_1d_2->output_r() ? 0x04 : 0x00) |
409         (m_ttl7474_1f_2->output_r() ? 0x08 : 0x00) |
410         (ioport("IN2")->read() & 0xf0);
411
412   return ret;
413}
414
415
416READ8_MEMBER(carpolo_state::pia_1_port_b_r)
417{
418   UINT8 ret;
419
420   /* bit 4 - Player 4 steering input (wheel moving or stopped)
421      bit 5 - Player 3 steering input (wheel moving or stopped)
422      bit 6 - Player 2 steering input (wheel moving or stopped)
423      bit 7 - Player 1 steering input (wheel moving or stopped) */
424
425   ret = (m_ttl7474_1a_1->output_r() ? 0x10 : 0x00) |
426         (m_ttl7474_1c_1->output_r() ? 0x20 : 0x00) |
427         (m_ttl7474_1d_1->output_r() ? 0x40 : 0x00) |
428         (m_ttl7474_1f_1->output_r() ? 0x80 : 0x00);
429
430   return ret;
431}
432
433void carpolo_state::machine_start()
434{
435   save_item(NAME(m_ball_screen_collision_cause));
436   save_item(NAME(m_car_ball_collision_x));
437   save_item(NAME(m_car_ball_collision_y));
438   save_item(NAME(m_car_car_collision_cause));
439   save_item(NAME(m_car_goal_collision_cause));
440   save_item(NAME(m_car_ball_collision_cause));
441   save_item(NAME(m_car_border_collision_cause));
442   save_item(NAME(m_priority_0_extension));
443   save_item(NAME(m_last_wheel_value));
444}
445
446void carpolo_state::machine_reset()
447{
448   /* set up the priority encoder */
449   m_ttl74148_3s->enable_input_w(0);  /* always enabled */
450
451   /* set up the coin handling flip-flops */
452   m_ttl7474_2s_1->d_w     (1);
453   m_ttl7474_2s_1->preset_w(1);
454
455   m_ttl7474_2s_2->d_w     (1);
456   m_ttl7474_2s_2->preset_w(1);
457
458   m_ttl7474_2u_1->d_w     (1);
459   m_ttl7474_2u_1->preset_w(1);
460
461   m_ttl7474_2u_2->d_w     (1);
462   m_ttl7474_2u_2->preset_w(1);
463
464
465   /* set up the steering handling flip-flops */
466   m_ttl7474_1f_1->d_w     (1);
467   m_ttl7474_1f_1->preset_w(1);
468
469   m_ttl7474_1f_2->clear_w (1);
470   m_ttl7474_1f_2->preset_w(1);
471
472   m_ttl7474_1d_1->d_w     (1);
473   m_ttl7474_1d_1->preset_w(1);
474
475   m_ttl7474_1d_2->clear_w (1);
476   m_ttl7474_1d_2->preset_w(1);
477
478   m_ttl7474_1c_1->d_w     (1);
479   m_ttl7474_1c_1->preset_w(1);
480
481   m_ttl7474_1c_2->clear_w (1);
482   m_ttl7474_1c_2->preset_w(1);
483
484   m_ttl7474_1a_1->d_w     (1);
485   m_ttl7474_1a_1->preset_w(1);
486
487   m_ttl7474_1a_2->clear_w (1);
488   m_ttl7474_1a_2->preset_w(1);
489
490
491   /* set up the pedal handling chips */
492   m_ttl74153_1k->enable_w(0, 0);
493   m_ttl74153_1k->enable_w(1, 0);
494}
trunk/src/mame/video/carpolo.c
r250160r250161
1// license:BSD-3-Clause
2// copyright-holders:Zsolt Vasvari
3/***************************************************************************
4
5    Exidy Car Polo hardware
6
7    driver by Zsolt Vasvari
8
9****************************************************************************/
10
11#include "emu.h"
12#include "includes/carpolo.h"
13
14
15/* the screen elements' priorties determine their color */
16#define CHARSET_COLOR_BASE  (0x00)
17#define BACKGROUND_PEN      ((0x00 << 1) + 1)
18#define FIELD_PEN           ((0x01 << 1) + 1)
19#define CAR1_COLOR          (0x02)
20#define LINE_PEN            ((0x03 << 1) + 1)
21#define CAR4_COLOR          (0x04)
22#define CAR3_COLOR          (0x05)
23#define CAR2_COLOR          (0x06)
24#define BALL_COLOR          (0x07)
25#define NET_COLOR           (0x08)
26#define LEFT_GOAL_COLOR     (0x09)
27#define LEFT_GOAL_PEN       (0x18 + 0x08)
28#define LEFT_SCORE_PEN      (0x18 + 0x06)
29#define RIGHT_GOAL_COLOR    (0x0a)
30#define RIGHT_GOAL_PEN      (0x18 + 0x18)
31#define RIGHT_SCORE_PEN     (0x18 + 0x16)
32#define SPECIAL_CHAR_COLOR  (0x0b)
33#define ALPHA_COLOR_BASE    (0x0c)  /* 0x0c - 0x0f */
34
35#define SPRITE_WIDTH        (16)
36#define SPRITE_HEIGHT       (16)
37#define GOAL_WIDTH          (16)
38#define GOAL_HEIGHT         (64)
39
40#define LEFT_GOAL_X         ((2 * 16) - 8)
41#define RIGHT_GOAL_X        ((13 * 16) - 8)
42#define GOAL_Y              (7 * 16)
43
44#define TOP_BORDER          (16)
45#define BOTTOM_BORDER       (255)
46#define LEFT_BORDER         (0)
47#define RIGHT_BORDER        (239)
48
49
50
51
52/***************************************************************************
53 *
54 *  Palette generation
55 *
56 *  The palette PROM is connected to the RGB output this way.
57 *
58 *  bit 0 -- 220 ohm resistor  -- BLUE (probably an error on schematics)
59 *        -- 470 ohm resistor  -- BLUE (probably an error on schematics)
60 *        -- 220 ohm resistor  -- GREEN
61 *        -- 470 ohm resistor  -- GREEN
62 *        -- 1  kohm resistor  -- GREEN
63 *        -- 220 ohm resistor  -- RED
64 *        -- 470 ohm resistor  -- RED
65 *  bit 7 -- 1  kohm resistor  -- RED
66 *
67 **************************************************************************/
68
69PALETTE_INIT_MEMBER(carpolo_state, carpolo)
70{
71   const UINT8 *color_prom = memregion("proms")->base();
72   int i;
73
74   /* thanks to Jarek Burczynski for analyzing the circuit */
75   /* static const float MAX_VOLTAGE = 6.9620f; */
76   static const float MIN_VOLTAGE = 1.7434f;
77   static const float MAX_VOLTAGE = 5.5266f;
78
79   static const float r_voltage[] =
80   {
81      1.7434f, 2.1693f, 2.5823f, 3.0585f, 3.4811f, 4.0707f, 4.7415f, 5.4251f
82   };
83
84   static const float g_voltage[] =
85   {
86      1.7434f, 2.1693f, 2.5823f, 3.0585f, 3.4811f, 4.0707f, 4.7415f, 5.4251f
87      /* 4.7871f, 5.0613f, 5.3079f, 5.6114f, 5.7940f, 6.1608f, 6.5436f, 6.9620f */
88   };
89
90   static const float b_voltage[] =
91   {
92      1.9176f, 2.8757f, 3.9825f, 5.5266f
93   };
94
95
96   for (i = 0; i < palette.entries(); i++)
97   {
98      UINT8 pen, r, g, b;
99
100      if (i < 0x18)
101         /* sprites */
102         pen = ((i - 0x00) & 0x01) ? CHARSET_COLOR_BASE + ((i - 0x00) >> 1) : 0;
103
104      else if (i < 0x38)
105         /* the bits in the goal gfx PROM are hooked up as follows (all active LO):
106            D3 - goal post
107            D2 - scoring area
108            D1 - net
109            D0 - n/c
110            I am only filling in the colors actually used. */
111         switch (i - 0x18)
112         {
113         case (0x00 | (0x07 ^ 0x0f)): pen = LEFT_GOAL_COLOR; break;
114         case (0x00 | (0x0d ^ 0x0f)): pen = NET_COLOR; break;
115         case (0x00 | (0x09 ^ 0x0f)): pen = NET_COLOR; break;  /* score */
116         case (0x10 | (0x07 ^ 0x0f)): pen = RIGHT_GOAL_COLOR; break;
117         case (0x10 | (0x0d ^ 0x0f)): pen = NET_COLOR; break;
118         case (0x10 | (0x09 ^ 0x0f)): pen = NET_COLOR; break; /* score */
119         default: pen = 0; break;
120         }
121
122      else
123         /* alpha layer */
124         pen = ((i - 0x38) & 0x01) ? ALPHA_COLOR_BASE   + ((i - 0x38) >> 1) : 0;
125
126      /* red component */
127      r = ((r_voltage[(color_prom[pen] >> 5) & 0x07] - MIN_VOLTAGE) / (MAX_VOLTAGE - MIN_VOLTAGE)) * 255.0f;
128
129      /* green component */
130      g = ((g_voltage[(color_prom[pen] >> 2) & 0x07] - MIN_VOLTAGE) / (MAX_VOLTAGE - MIN_VOLTAGE)) * 255.0f;
131
132      /* blue component */
133      b = ((b_voltage[(color_prom[pen] >> 0) & 0x03] - MIN_VOLTAGE) / (MAX_VOLTAGE - MIN_VOLTAGE)) * 255.0f;
134
135      palette.set_pen_color(i, rgb_t(r, g, b));
136   }
137}
138
139
140/*************************************
141 *
142 *  Video system start
143 *
144 *************************************/
145
146void carpolo_state::video_start()
147{
148   m_sprite_sprite_collision_bitmap1 = auto_bitmap_ind16_alloc(machine(), SPRITE_WIDTH*2, SPRITE_HEIGHT*2);
149   m_sprite_sprite_collision_bitmap2 = auto_bitmap_ind16_alloc(machine(), SPRITE_WIDTH*2, SPRITE_HEIGHT*2);
150
151   m_sprite_goal_collision_bitmap1 = auto_bitmap_ind16_alloc(machine(), SPRITE_WIDTH+GOAL_WIDTH, SPRITE_HEIGHT+GOAL_HEIGHT);
152   m_sprite_goal_collision_bitmap2 = auto_bitmap_ind16_alloc(machine(), SPRITE_WIDTH+GOAL_WIDTH, SPRITE_HEIGHT+GOAL_HEIGHT);
153
154   m_sprite_border_collision_bitmap = auto_bitmap_ind16_alloc(machine(), SPRITE_WIDTH, SPRITE_HEIGHT);
155
156   save_item(NAME(*m_sprite_sprite_collision_bitmap1));
157   save_item(NAME(*m_sprite_sprite_collision_bitmap2));
158   save_item(NAME(*m_sprite_goal_collision_bitmap1));
159   save_item(NAME(*m_sprite_goal_collision_bitmap2));
160   save_item(NAME(*m_sprite_border_collision_bitmap));
161}
162
163
164/*************************************
165 *
166 *  Core video refresh
167 *
168 *************************************/
169
170void carpolo_state::draw_alpha_line(bitmap_ind16 &bitmap, const rectangle &cliprect,
171                     int alpha_line, int video_line)
172{
173   for (int x = 0; x < 32; x++)
174   {
175      UINT8 code, col;
176
177      code = m_alpharam[alpha_line * 32 + x] >> 2;
178      col  = m_alpharam[alpha_line * 32 + x] & 0x03;
179
180      m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
181            code,col,
182            0,0,
183            x*8,video_line*8,0);
184   }
185}
186
187
188void carpolo_state::remap_sprite_code(int bank, int code, int *remapped_code, int *flipy)
189{
190   UINT8* PROM = memregion("user1")->base();
191
192   code = (bank << 4) | code;
193   *remapped_code = PROM[code] & 0x0f;
194   *flipy = (PROM[code] & 0x10) >> 4;
195}
196
197
198void carpolo_state::draw_sprite(bitmap_ind16 &bitmap, const rectangle &cliprect,
199                  UINT8 x, UINT8 y, int bank, int code, int col)
200{
201   int remapped_code, flipy;
202
203   remap_sprite_code(bank, code, &remapped_code, &flipy);
204
205   x = 240 - x;
206   y = 240 - y;
207
208   m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
209         remapped_code, col,
210         0, flipy,
211         x, y,0);
212
213   /* draw with wrap around */
214   m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
215         remapped_code, col,
216         0, flipy,
217         (INT16)x - 256, y,0);
218}
219
220
221UINT32 carpolo_state::screen_update_carpolo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
222{
223   /* draw the playfield elements in the correct priority order */
224
225   /* score area - position determined by bit 4 of the vertical timing PROM */
226   bitmap.plot_box(0,0,RIGHT_BORDER+1,TOP_BORDER,BACKGROUND_PEN);
227
228   /* field */
229   bitmap.plot_box(0,TOP_BORDER,RIGHT_BORDER+1,BOTTOM_BORDER-TOP_BORDER+1,FIELD_PEN);
230
231   /* car 1 */
232   draw_sprite(bitmap, cliprect,
233            m_spriteram[0x00], m_spriteram[0x01],
234            0, m_spriteram[0x0c] & 0x0f, CAR1_COLOR);
235
236   /* border - position determined by bit 4 and 7 of the vertical timing PROM */
237   bitmap.plot_box(0,TOP_BORDER,   RIGHT_BORDER+1,1,LINE_PEN);
238   bitmap.plot_box(0,BOTTOM_BORDER,RIGHT_BORDER+1,1,LINE_PEN);
239   bitmap.plot_box(LEFT_BORDER,TOP_BORDER, 1,BOTTOM_BORDER-TOP_BORDER+1,LINE_PEN);
240   bitmap.plot_box(RIGHT_BORDER,TOP_BORDER,1,BOTTOM_BORDER-TOP_BORDER+1,LINE_PEN);
241
242   /* car 4 */
243   draw_sprite(bitmap, cliprect,
244            m_spriteram[0x06], m_spriteram[0x07],
245            0, m_spriteram[0x0d] >> 4, CAR4_COLOR);
246
247   /* car 3 */
248   draw_sprite(bitmap, cliprect,
249            m_spriteram[0x04], m_spriteram[0x05],
250            0, m_spriteram[0x0d] & 0x0f, CAR3_COLOR);
251
252   /* car 2 */
253   draw_sprite(bitmap, cliprect,
254            m_spriteram[0x02], m_spriteram[0x03],
255            0, m_spriteram[0x0c] >> 4, CAR2_COLOR);
256
257   /* ball */
258   draw_sprite(bitmap, cliprect,
259            m_spriteram[0x08], m_spriteram[0x09],
260            1, m_spriteram[0x0e] & 0x0f, BALL_COLOR);
261
262   /* left goal - position determined by bit 6 of the
263      horizontal and vertical timing PROMs */
264   m_gfxdecode->gfx(1)->zoom_transpen(bitmap,cliprect,
265            0,0,
266            0,0,
267            LEFT_GOAL_X,GOAL_Y,
268            0x20000,0x20000,0);
269
270   /* right goal */
271   m_gfxdecode->gfx(1)->zoom_transpen(bitmap,cliprect,
272            0,1,
273            1,0,
274            RIGHT_GOAL_X,GOAL_Y,
275            0x20000,0x20000,0);
276
277   /* special char - bit 0 of 0x0f enables it,
278                     bit 1 marked as WIDE, but never appears to be set */
279   if (m_spriteram[0x0f] & 0x02)
280      popmessage("WIDE!\n");
281
282   if (m_spriteram[0x0f] & 0x01)
283      draw_sprite(bitmap, cliprect,
284               m_spriteram[0x0a], m_spriteram[0x0b],
285               1, m_spriteram[0x0e] >> 4, SPECIAL_CHAR_COLOR);
286
287
288   /* draw the alpha layer */
289
290   /* there are only 8 lines of text repeated 4 times
291      and bit 3 of the vertical timing PROM controls in
292      which quadrant the line will actually appear */
293
294   draw_alpha_line(bitmap, cliprect, 0, (0*4+0)*2  );
295   draw_alpha_line(bitmap, cliprect, 1, (0*4+0)*2+1);
296   draw_alpha_line(bitmap, cliprect, 2, (3*4+1)*2  );
297   draw_alpha_line(bitmap, cliprect, 3, (3*4+1)*2+1);
298   draw_alpha_line(bitmap, cliprect, 4, (1*4+2)*2  );
299   draw_alpha_line(bitmap, cliprect, 5, (1*4+2)*2+1);
300   draw_alpha_line(bitmap, cliprect, 6, (0*4+3)*2  );
301   draw_alpha_line(bitmap, cliprect, 7, (0*4+3)*2+1);
302
303   return 0;
304}
305
306
307/*************************************
308 *
309 *  End of frame callback
310 *
311 *************************************/
312
313void carpolo_state::normalize_coordinates(int *x1, int *y1, int *x2, int *y2)
314{
315   if (*x1 < *x2)
316   {
317      *x2 = *x2 - *x1;
318      *x1 = 0;
319   }
320   else
321   {
322      *x1 = *x1 - *x2;
323      *x2 = 0;
324   }
325
326   if (*y1 < *y2)
327   {
328      *y2 = *y2 - *y1;
329      *y1 = 0;
330   }
331   else
332   {
333      *y1 = *y1 - *y2;
334      *y2 = 0;
335   }
336}
337
338
339int carpolo_state::check_sprite_sprite_collision(int x1, int y1, int code1, int flipy1,
340                                 int x2, int y2, int code2, int flipy2,
341                                 int *col_x, int *col_y)
342{
343   int collided = 0;
344
345   x1 = 240 - x1;
346   y1 = 240 - y1;
347   x2 = 240 - x2;
348   y2 = 240 - y2;
349
350   /* check if the two sprites are even within collision range */
351   if ((abs(x1 - x2) < SPRITE_WIDTH) && (abs(y1 - y2) < SPRITE_HEIGHT))
352   {
353      int x,y;
354
355      normalize_coordinates(&x1, &y1, &x2, &y2);
356
357      m_sprite_sprite_collision_bitmap1->fill(0);
358      m_sprite_sprite_collision_bitmap2->fill(0);
359
360      m_gfxdecode->gfx(0)->opaque(*m_sprite_sprite_collision_bitmap1,m_sprite_sprite_collision_bitmap1->cliprect(),
361            code1,0,
362            0,flipy1,
363            x1,y1);
364
365      m_gfxdecode->gfx(0)->opaque(*m_sprite_sprite_collision_bitmap2,m_sprite_sprite_collision_bitmap2->cliprect(),
366            code2,0,
367            0,flipy2,
368            x2,y2);
369
370      for (x = x1; x < x1 + SPRITE_WIDTH; x++)
371         for (y = y1; y < y1 + SPRITE_HEIGHT; y++)
372            if ((m_sprite_sprite_collision_bitmap1->pix16(y, x) == 1) &&
373               (m_sprite_sprite_collision_bitmap2->pix16(y, x) == 1))
374            {
375               *col_x = (x1 + x) & 0x0f;
376               *col_y = (y1 + y) & 0x0f;
377
378               collided = 1;
379
380               break;
381            }
382   }
383
384   return collided;
385}
386
387
388/* returns 1 for collision with goal post,
389   2 for collision with scoring area */
390int carpolo_state::check_sprite_left_goal_collision(int x1, int y1, int code1, int flipy1, int goalpost_only)
391{
392   int collided = 0;
393
394   x1 = 240 - x1;
395   y1 = 240 - y1;
396
397   /* check if the sprite is even within the range of the goal */
398   if (((y1 + 16) > GOAL_Y) && (y1 < (GOAL_Y + GOAL_HEIGHT)) &&
399      ((x1 + 16) > LEFT_GOAL_X) && (x1 < (LEFT_GOAL_X + GOAL_WIDTH)))
400   {
401      int x,y;
402      int x2,y2;
403
404
405      x2 = LEFT_GOAL_X;
406      y2 = GOAL_Y;
407
408      normalize_coordinates(&x1, &y1, &x2, &y2);
409
410      m_sprite_goal_collision_bitmap1->fill(0);
411      m_sprite_goal_collision_bitmap2->fill(0);
412
413      m_gfxdecode->gfx(0)->opaque(*m_sprite_goal_collision_bitmap1,m_sprite_goal_collision_bitmap1->cliprect(),
414            code1,0,
415            0,flipy1,
416            x1,y1);
417
418      m_gfxdecode->gfx(1)->zoom_transpen(*m_sprite_goal_collision_bitmap2,m_sprite_goal_collision_bitmap2->cliprect(),
419               0,0,
420               0,0,
421               x2,y2,
422               0x20000,0x20000,0);
423
424      for (x = x1; x < x1 + SPRITE_WIDTH; x++)
425         for (y = y1; y < y1 + SPRITE_HEIGHT; y++)
426            if (m_sprite_goal_collision_bitmap1->pix16(y, x) == 1)
427            {
428               pen_t pix = m_sprite_goal_collision_bitmap2->pix16(y, x);
429
430               if (pix == LEFT_GOAL_PEN)
431               {
432                  collided = 1;
433                  break;
434               }
435
436               if (!goalpost_only && (pix == LEFT_SCORE_PEN))
437               {
438                  collided = 2;
439                  break;
440               }
441            }
442   }
443
444   return collided;
445}
446
447
448int carpolo_state::check_sprite_right_goal_collision(int x1, int y1, int code1, int flipy1, int goalpost_only)
449{
450   int collided = 0;
451
452   x1 = 240 - x1;
453   y1 = 240 - y1;
454
455   /* check if the sprite is even within the range of the goal */
456   if (((y1 + 16) > GOAL_Y) && (y1 < (GOAL_Y + GOAL_HEIGHT)) &&
457      ((x1 + 16) > RIGHT_GOAL_X) && (x1 < (RIGHT_GOAL_X + GOAL_WIDTH)))
458   {
459      int x,y;
460      int x2,y2;
461
462      x2 = RIGHT_GOAL_X;
463      y2 = GOAL_Y;
464
465      normalize_coordinates(&x1, &y1, &x2, &y2);
466
467      m_sprite_goal_collision_bitmap1->fill(0);
468      m_sprite_goal_collision_bitmap2->fill(0);
469
470      m_gfxdecode->gfx(0)->opaque(*m_sprite_goal_collision_bitmap1,m_sprite_goal_collision_bitmap1->cliprect(),
471            code1,0,
472            0,flipy1,
473            x1,y1);
474
475      m_gfxdecode->gfx(1)->zoom_transpen(*m_sprite_goal_collision_bitmap2,m_sprite_goal_collision_bitmap2->cliprect(),
476               0,1,
477               1,0,
478               x2,y2,
479               0x20000,0x20000,0);
480
481      for (x = x1; x < x1 + SPRITE_WIDTH; x++)
482         for (y = y1; y < y1 + SPRITE_HEIGHT; y++)
483            if (m_sprite_goal_collision_bitmap1->pix16(y, x) == 1)
484            {
485               pen_t pix = m_sprite_goal_collision_bitmap2->pix16(y, x);
486
487               if (pix == RIGHT_GOAL_PEN)
488               {
489                  collided = 1;
490                  break;
491               }
492
493               if (!goalpost_only && (pix == RIGHT_SCORE_PEN))
494               {
495                  collided = 2;
496                  break;
497               }
498            }
499   }
500
501   return collided;
502}
503
504
505/* returns 1 for collision with vertical border,
506   2 for collision with horizontal border */
507int carpolo_state::check_sprite_border_collision(UINT8 x1, UINT8 y1, int code1, int flipy1)
508{
509   UINT8 x,y;
510   int collided = 0;
511
512   x1 = 240 - x1;
513   y1 = 240 - y1;
514
515   m_gfxdecode->gfx(0)->opaque(*m_sprite_border_collision_bitmap,m_sprite_border_collision_bitmap->cliprect(),
516         code1,0,
517         0,flipy1,
518         0,0);
519
520   for (x = 0; x < SPRITE_WIDTH; x++)
521      for (y = 0; y < SPRITE_HEIGHT; y++)
522         if (m_sprite_border_collision_bitmap->pix16(y, x) == 1)
523         {
524            if (((UINT8)(x1 + x) == LEFT_BORDER) ||
525               ((UINT8)(x1 + x) == RIGHT_BORDER))
526            {
527               collided = 1;
528               break;
529            }
530
531            if (((UINT8)(y1 + y) == TOP_BORDER) ||
532               ((UINT8)(y1 + y) == BOTTOM_BORDER))
533            {
534               collided = 2;
535               break;
536            }
537         }
538
539   return collided;
540}
541
542
543void carpolo_state::screen_eof_carpolo(screen_device &screen, bool state)
544{
545   // rising edge
546   if (state)
547   {
548      int col_x, col_y;
549      int car1_x, car2_x, car3_x, car4_x, ball_x;
550      int car1_y, car2_y, car3_y, car4_y, ball_y;
551      int car1_code, car2_code, car3_code, car4_code, ball_code;
552      int car1_flipy, car2_flipy, car3_flipy, car4_flipy, ball_flipy;
553
554
555      /* check car-car collision first */
556
557      car1_x = m_spriteram[0x00];
558      car1_y = m_spriteram[0x01];
559      remap_sprite_code(0, m_spriteram[0x0c] & 0x0f, &car1_code, &car1_flipy);
560
561      car2_x = m_spriteram[0x02];
562      car2_y = m_spriteram[0x03];
563      remap_sprite_code(0, m_spriteram[0x0c] >> 4,   &car2_code, &car2_flipy);
564
565      car3_x = m_spriteram[0x04];
566      car3_y = m_spriteram[0x05];
567      remap_sprite_code(0, m_spriteram[0x0d] & 0x0f, &car3_code, &car3_flipy);
568
569      car4_x = m_spriteram[0x06];
570      car4_y = m_spriteram[0x07];
571      remap_sprite_code(0, m_spriteram[0x0d] >> 4,   &car4_code, &car4_flipy);
572
573      ball_x = m_spriteram[0x08];
574      ball_y = m_spriteram[0x09];
575      remap_sprite_code(1, m_spriteram[0x0e] & 0x0f, &ball_code, &ball_flipy);
576
577
578      /* cars 1 and 2 */
579      if (check_sprite_sprite_collision(car1_x, car1_y, car1_code, car1_flipy,
580                                 car2_x, car2_y, car2_code, car2_flipy,
581                                 &col_x, &col_y))
582         carpolo_generate_car_car_interrupt(0, 1);
583
584      /* cars 1 and 3 */
585      else if (check_sprite_sprite_collision(car1_x, car1_y, car1_code, car1_flipy,
586                                    car3_x, car3_y, car3_code, car3_flipy,
587                                    &col_x, &col_y))
588         carpolo_generate_car_car_interrupt(0, 2);
589
590      /* cars 1 and 4 */
591      else if (check_sprite_sprite_collision(car1_x, car1_y, car1_code, car1_flipy,
592                                    car4_x, car4_y, car4_code, car4_flipy,
593                                    &col_x, &col_y))
594         carpolo_generate_car_car_interrupt(0, 3);
595
596      /* cars 2 and 3 */
597      else if (check_sprite_sprite_collision(car2_x, car2_y, car2_code, car2_flipy,
598                                    car3_x, car3_y, car3_code, car3_flipy,
599                                    &col_x, &col_y))
600         carpolo_generate_car_car_interrupt(1, 2);
601
602      /* cars 2 and 4 */
603      else if (check_sprite_sprite_collision(car2_x, car2_y, car2_code, car2_flipy,
604                                    car4_x, car4_y, car4_code, car4_flipy,
605                                    &col_x, &col_y))
606         carpolo_generate_car_car_interrupt(1, 3);
607
608      /* cars 3 and 4 */
609      else if (check_sprite_sprite_collision(car3_x, car3_y, car3_code, car3_flipy,
610                                    car4_x, car4_y, car4_code, car4_flipy,
611                                    &col_x, &col_y))
612         carpolo_generate_car_car_interrupt(2, 3);
613
614
615
616      /* check car-ball collision */
617      if (check_sprite_sprite_collision(car1_x, car1_y, car1_code, car1_flipy,
618                                 ball_x, ball_y, ball_code, ball_flipy,
619                                 &col_x, &col_y))
620         carpolo_generate_car_ball_interrupt(0, col_x, col_y);
621
622      else if (check_sprite_sprite_collision(car2_x, car2_y, car2_code, car2_flipy,
623                                    ball_x, ball_y, ball_code, ball_flipy,
624                                    &col_x, &col_y))
625         carpolo_generate_car_ball_interrupt(1, col_x, col_y);
626
627      else if (check_sprite_sprite_collision(car3_x, car3_y, car3_code, car3_flipy,
628                                    ball_x, ball_y, ball_code, ball_flipy,
629                                    &col_x, &col_y))
630         carpolo_generate_car_ball_interrupt(2, col_x, col_y);
631
632      else if (check_sprite_sprite_collision(car4_x, car4_y, car4_code, car4_flipy,
633                                    ball_x, ball_y, ball_code, ball_flipy,
634                                    &col_x, &col_y))
635         carpolo_generate_car_ball_interrupt(3, col_x, col_y);
636
637
638      /* check car-goal collision */
639      if (check_sprite_left_goal_collision(car1_x, car1_y, car1_code, car1_flipy, 1))
640         carpolo_generate_car_goal_interrupt(0, 0);
641
642      else if (check_sprite_right_goal_collision(car1_x, car1_y, car1_code, car1_flipy, 1))
643         carpolo_generate_car_goal_interrupt(0, 1);
644
645      else if (check_sprite_left_goal_collision(car2_x, car2_y, car2_code, car2_flipy, 1))
646         carpolo_generate_car_goal_interrupt(1, 0);
647
648      else if (check_sprite_right_goal_collision(car2_x, car2_y, car2_code, car2_flipy, 1))
649         carpolo_generate_car_goal_interrupt(1, 1);
650
651      else if (check_sprite_left_goal_collision(car3_x, car3_y, car3_code, car3_flipy, 1))
652         carpolo_generate_car_goal_interrupt(2, 0);
653
654      else if (check_sprite_right_goal_collision(car3_x, car3_y, car3_code, car3_flipy, 1))
655         carpolo_generate_car_goal_interrupt(2, 1);
656
657      else if (check_sprite_left_goal_collision(car4_x, car4_y, car4_code, car4_flipy, 1))
658         carpolo_generate_car_goal_interrupt(3, 0);
659
660      else if (check_sprite_right_goal_collision(car4_x, car4_y, car4_code, car4_flipy, 1))
661         carpolo_generate_car_goal_interrupt(3, 1);
662
663
664      /* check ball collision with static screen elements */
665      {
666         int col;
667
668         col = check_sprite_left_goal_collision(ball_x, ball_y, ball_code, ball_flipy, 0);
669
670         if (col == 1)  carpolo_generate_ball_screen_interrupt(0x05);
671         if (col == 2)  carpolo_generate_ball_screen_interrupt(0x03);
672
673
674         col = check_sprite_right_goal_collision(ball_x, ball_y, ball_code, ball_flipy, 0);
675
676         if (col == 1)  carpolo_generate_ball_screen_interrupt(0x05 | 0x08);
677         if (col == 2)  carpolo_generate_ball_screen_interrupt(0x03 | 0x08);
678
679
680         if (check_sprite_border_collision(ball_x, ball_y, ball_code, ball_flipy))
681            carpolo_generate_ball_screen_interrupt(0x06);
682      }
683
684
685      /* check car-border collision */
686      {
687         int col;
688
689         col = check_sprite_border_collision(car1_x, car1_y, car1_code, car1_flipy);
690
691         if (col)
692            carpolo_generate_car_border_interrupt(0, (col == 2));
693         else
694         {
695            col = check_sprite_border_collision(car2_x, car2_y, car2_code, car2_flipy);
696
697            if (col)
698               carpolo_generate_car_border_interrupt(1, (col == 2));
699            else
700            {
701               col = check_sprite_border_collision(car3_x, car3_y, car3_code, car3_flipy);
702
703               if (col)
704                  carpolo_generate_car_border_interrupt(2, (col == 2));
705               else
706               {
707                  col = check_sprite_border_collision(car4_x, car4_y, car4_code, car4_flipy);
708
709                  if (col)
710                     carpolo_generate_car_border_interrupt(3, (col == 2));
711               }
712            }
713         }
714      }
715   }
716}
trunk/src/mame/video/carpolo.cpp
r0r250161
1// license:BSD-3-Clause
2// copyright-holders:Zsolt Vasvari
3/***************************************************************************
4
5    Exidy Car Polo hardware
6
7    driver by Zsolt Vasvari
8
9****************************************************************************/
10
11#include "emu.h"
12#include "includes/carpolo.h"
13
14
15/* the screen elements' priorties determine their color */
16#define CHARSET_COLOR_BASE  (0x00)
17#define BACKGROUND_PEN      ((0x00 << 1) + 1)
18#define FIELD_PEN           ((0x01 << 1) + 1)
19#define CAR1_COLOR          (0x02)
20#define LINE_PEN            ((0x03 << 1) + 1)
21#define CAR4_COLOR          (0x04)
22#define CAR3_COLOR          (0x05)
23#define CAR2_COLOR          (0x06)
24#define BALL_COLOR          (0x07)
25#define NET_COLOR           (0x08)
26#define LEFT_GOAL_COLOR     (0x09)
27#define LEFT_GOAL_PEN       (0x18 + 0x08)
28#define LEFT_SCORE_PEN      (0x18 + 0x06)
29#define RIGHT_GOAL_COLOR    (0x0a)
30#define RIGHT_GOAL_PEN      (0x18 + 0x18)
31#define RIGHT_SCORE_PEN     (0x18 + 0x16)
32#define SPECIAL_CHAR_COLOR  (0x0b)
33#define ALPHA_COLOR_BASE    (0x0c)  /* 0x0c - 0x0f */
34
35#define SPRITE_WIDTH        (16)
36#define SPRITE_HEIGHT       (16)
37#define GOAL_WIDTH          (16)
38#define GOAL_HEIGHT         (64)
39
40#define LEFT_GOAL_X         ((2 * 16) - 8)
41#define RIGHT_GOAL_X        ((13 * 16) - 8)
42#define GOAL_Y              (7 * 16)
43
44#define TOP_BORDER          (16)
45#define BOTTOM_BORDER       (255)
46#define LEFT_BORDER         (0)
47#define RIGHT_BORDER        (239)
48
49
50
51
52/***************************************************************************
53 *
54 *  Palette generation
55 *
56 *  The palette PROM is connected to the RGB output this way.
57 *
58 *  bit 0 -- 220 ohm resistor  -- BLUE (probably an error on schematics)
59 *        -- 470 ohm resistor  -- BLUE (probably an error on schematics)
60 *        -- 220 ohm resistor  -- GREEN
61 *        -- 470 ohm resistor  -- GREEN
62 *        -- 1  kohm resistor  -- GREEN
63 *        -- 220 ohm resistor  -- RED
64 *        -- 470 ohm resistor  -- RED
65 *  bit 7 -- 1  kohm resistor  -- RED
66 *
67 **************************************************************************/
68
69PALETTE_INIT_MEMBER(carpolo_state, carpolo)
70{
71   const UINT8 *color_prom = memregion("proms")->base();
72   int i;
73
74   /* thanks to Jarek Burczynski for analyzing the circuit */
75   /* static const float MAX_VOLTAGE = 6.9620f; */
76   static const float MIN_VOLTAGE = 1.7434f;
77   static const float MAX_VOLTAGE = 5.5266f;
78
79   static const float r_voltage[] =
80   {
81      1.7434f, 2.1693f, 2.5823f, 3.0585f, 3.4811f, 4.0707f, 4.7415f, 5.4251f
82   };
83
84   static const float g_voltage[] =
85   {
86      1.7434f, 2.1693f, 2.5823f, 3.0585f, 3.4811f, 4.0707f, 4.7415f, 5.4251f
87      /* 4.7871f, 5.0613f, 5.3079f, 5.6114f, 5.7940f, 6.1608f, 6.5436f, 6.9620f */
88   };
89
90   static const float b_voltage[] =
91   {
92      1.9176f, 2.8757f, 3.9825f, 5.5266f
93   };
94
95
96   for (i = 0; i < palette.entries(); i++)
97   {
98      UINT8 pen, r, g, b;
99
100      if (i < 0x18)
101         /* sprites */
102         pen = ((i - 0x00) & 0x01) ? CHARSET_COLOR_BASE + ((i - 0x00) >> 1) : 0;
103
104      else if (i < 0x38)
105         /* the bits in the goal gfx PROM are hooked up as follows (all active LO):
106            D3 - goal post
107            D2 - scoring area
108            D1 - net
109            D0 - n/c
110            I am only filling in the colors actually used. */
111         switch (i - 0x18)
112         {
113         case (0x00 | (0x07 ^ 0x0f)): pen = LEFT_GOAL_COLOR; break;
114         case (0x00 | (0x0d ^ 0x0f)): pen = NET_COLOR; break;
115         case (0x00 | (0x09 ^ 0x0f)): pen = NET_COLOR; break;  /* score */
116         case (0x10 | (0x07 ^ 0x0f)): pen = RIGHT_GOAL_COLOR; break;
117         case (0x10 | (0x0d ^ 0x0f)): pen = NET_COLOR; break;
118         case (0x10 | (0x09 ^ 0x0f)): pen = NET_COLOR; break; /* score */
119         default: pen = 0; break;
120         }
121
122      else
123         /* alpha layer */
124         pen = ((i - 0x38) & 0x01) ? ALPHA_COLOR_BASE   + ((i - 0x38) >> 1) : 0;
125
126      /* red component */
127      r = ((r_voltage[(color_prom[pen] >> 5) & 0x07] - MIN_VOLTAGE) / (MAX_VOLTAGE - MIN_VOLTAGE)) * 255.0f;
128
129      /* green component */
130      g = ((g_voltage[(color_prom[pen] >> 2) & 0x07] - MIN_VOLTAGE) / (MAX_VOLTAGE - MIN_VOLTAGE)) * 255.0f;
131
132      /* blue component */
133      b = ((b_voltage[(color_prom[pen] >> 0) & 0x03] - MIN_VOLTAGE) / (MAX_VOLTAGE - MIN_VOLTAGE)) * 255.0f;
134
135      palette.set_pen_color(i, rgb_t(r, g, b));
136   }
137}
138
139
140/*************************************
141 *
142 *  Video system start
143 *
144 *************************************/
145
146void carpolo_state::video_start()
147{
148   m_sprite_sprite_collision_bitmap1 = auto_bitmap_ind16_alloc(machine(), SPRITE_WIDTH*2, SPRITE_HEIGHT*2);
149   m_sprite_sprite_collision_bitmap2 = auto_bitmap_ind16_alloc(machine(), SPRITE_WIDTH*2, SPRITE_HEIGHT*2);
150
151   m_sprite_goal_collision_bitmap1 = auto_bitmap_ind16_alloc(machine(), SPRITE_WIDTH+GOAL_WIDTH, SPRITE_HEIGHT+GOAL_HEIGHT);
152   m_sprite_goal_collision_bitmap2 = auto_bitmap_ind16_alloc(machine(), SPRITE_WIDTH+GOAL_WIDTH, SPRITE_HEIGHT+GOAL_HEIGHT);
153
154   m_sprite_border_collision_bitmap = auto_bitmap_ind16_alloc(machine(), SPRITE_WIDTH, SPRITE_HEIGHT);
155
156   save_item(NAME(*m_sprite_sprite_collision_bitmap1));
157   save_item(NAME(*m_sprite_sprite_collision_bitmap2));
158   save_item(NAME(*m_sprite_goal_collision_bitmap1));
159   save_item(NAME(*m_sprite_goal_collision_bitmap2));
160   save_item(NAME(*m_sprite_border_collision_bitmap));
161}
162
163
164/*************************************
165 *
166 *  Core video refresh
167 *
168 *************************************/
169
170void carpolo_state::draw_alpha_line(bitmap_ind16 &bitmap, const rectangle &cliprect,
171                     int alpha_line, int video_line)
172{
173   for (int x = 0; x < 32; x++)
174   {
175      UINT8 code, col;
176
177      code = m_alpharam[alpha_line * 32 + x] >> 2;
178      col  = m_alpharam[alpha_line * 32 + x] & 0x03;
179
180      m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
181            code,col,
182            0,0,
183            x*8,video_line*8,0);
184   }
185}
186
187
188void carpolo_state::remap_sprite_code(int bank, int code, int *remapped_code, int *flipy)
189{
190   UINT8* PROM = memregion("user1")->base();
191
192   code = (bank << 4) | code;
193   *remapped_code = PROM[code] & 0x0f;
194   *flipy = (PROM[code] & 0x10) >> 4;
195}
196
197
198void carpolo_state::draw_sprite(bitmap_ind16 &bitmap, const rectangle &cliprect,
199                  UINT8 x, UINT8 y, int bank, int code, int col)
200{
201   int remapped_code, flipy;
202
203   remap_sprite_code(bank, code, &remapped_code, &flipy);
204
205   x = 240 - x;
206   y = 240 - y;
207
208   m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
209         remapped_code, col,
210         0, flipy,
211         x, y,0);
212
213   /* draw with wrap around */
214   m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
215         remapped_code, col,
216         0, flipy,
217         (INT16)x - 256, y,0);
218}
219
220
221UINT32 carpolo_state::screen_update_carpolo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
222{
223   /* draw the playfield elements in the correct priority order */
224
225   /* score area - position determined by bit 4 of the vertical timing PROM */
226   bitmap.plot_box(0,0,RIGHT_BORDER+1,TOP_BORDER,BACKGROUND_PEN);
227
228   /* field */
229   bitmap.plot_box(0,TOP_BORDER,RIGHT_BORDER+1,BOTTOM_BORDER-TOP_BORDER+1,FIELD_PEN);
230
231   /* car 1 */
232   draw_sprite(bitmap, cliprect,
233            m_spriteram[0x00], m_spriteram[0x01],
234            0, m_spriteram[0x0c] & 0x0f, CAR1_COLOR);
235
236   /* border - position determined by bit 4 and 7 of the vertical timing PROM */
237   bitmap.plot_box(0,TOP_BORDER,   RIGHT_BORDER+1,1,LINE_PEN);
238   bitmap.plot_box(0,BOTTOM_BORDER,RIGHT_BORDER+1,1,LINE_PEN);
239   bitmap.plot_box(LEFT_BORDER,TOP_BORDER, 1,BOTTOM_BORDER-TOP_BORDER+1,LINE_PEN);
240   bitmap.plot_box(RIGHT_BORDER,TOP_BORDER,1,BOTTOM_BORDER-TOP_BORDER+1,LINE_PEN);
241
242   /* car 4 */
243   draw_sprite(bitmap, cliprect,
244            m_spriteram[0x06], m_spriteram[0x07],
245            0, m_spriteram[0x0d] >> 4, CAR4_COLOR);
246
247   /* car 3 */
248   draw_sprite(bitmap, cliprect,
249            m_spriteram[0x04], m_spriteram[0x05],
250            0, m_spriteram[0x0d] & 0x0f, CAR3_COLOR);
251
252   /* car 2 */
253   draw_sprite(bitmap, cliprect,
254            m_spriteram[0x02], m_spriteram[0x03],
255            0, m_spriteram[0x0c] >> 4, CAR2_COLOR);
256
257   /* ball */
258   draw_sprite(bitmap, cliprect,
259            m_spriteram[0x08], m_spriteram[0x09],
260            1, m_spriteram[0x0e] & 0x0f, BALL_COLOR);
261
262   /* left goal - position determined by bit 6 of the
263      horizontal and vertical timing PROMs */
264   m_gfxdecode->gfx(1)->zoom_transpen(bitmap,cliprect,
265            0,0,
266            0,0,
267            LEFT_GOAL_X,GOAL_Y,
268            0x20000,0x20000,0);
269
270   /* right goal */
271   m_gfxdecode->gfx(1)->zoom_transpen(bitmap,cliprect,
272            0,1,
273            1,0,
274            RIGHT_GOAL_X,GOAL_Y,
275            0x20000,0x20000,0);
276
277   /* special char - bit 0 of 0x0f enables it,
278                     bit 1 marked as WIDE, but never appears to be set */
279   if (m_spriteram[0x0f] & 0x02)
280      popmessage("WIDE!\n");
281
282   if (m_spriteram[0x0f] & 0x01)
283      draw_sprite(bitmap, cliprect,
284               m_spriteram[0x0a], m_spriteram[0x0b],
285               1, m_spriteram[0x0e] >> 4, SPECIAL_CHAR_COLOR);
286
287
288   /* draw the alpha layer */
289
290   /* there are only 8 lines of text repeated 4 times
291      and bit 3 of the vertical timing PROM controls in
292      which quadrant the line will actually appear */
293
294   draw_alpha_line(bitmap, cliprect, 0, (0*4+0)*2  );
295   draw_alpha_line(bitmap, cliprect, 1, (0*4+0)*2+1);
296   draw_alpha_line(bitmap, cliprect, 2, (3*4+1)*2  );
297   draw_alpha_line(bitmap, cliprect, 3, (3*4+1)*2+1);
298   draw_alpha_line(bitmap, cliprect, 4, (1*4+2)*2  );
299   draw_alpha_line(bitmap, cliprect, 5, (1*4+2)*2+1);
300   draw_alpha_line(bitmap, cliprect, 6, (0*4+3)*2  );
301   draw_alpha_line(bitmap, cliprect, 7, (0*4+3)*2+1);
302
303   return 0;
304}
305
306
307/*************************************
308 *
309 *  End of frame callback
310 *
311 *************************************/
312
313void carpolo_state::normalize_coordinates(int *x1, int *y1, int *x2, int *y2)
314{
315   if (*x1 < *x2)
316   {
317      *x2 = *x2 - *x1;
318      *x1 = 0;
319   }
320   else
321   {
322      *x1 = *x1 - *x2;
323      *x2 = 0;
324   }
325
326   if (*y1 < *y2)
327   {
328      *y2 = *y2 - *y1;
329      *y1 = 0;
330   }
331   else
332   {
333      *y1 = *y1 - *y2;
334      *y2 = 0;
335   }
336}
337
338
339int carpolo_state::check_sprite_sprite_collision(int x1, int y1, int code1, int flipy1,
340                                 int x2, int y2, int code2, int flipy2,
341                                 int *col_x, int *col_y)
342{
343   int collided = 0;
344
345   x1 = 240 - x1;
346   y1 = 240 - y1;
347   x2 = 240 - x2;
348   y2 = 240 - y2;
349
350   /* check if the two sprites are even within collision range */
351   if ((abs(x1 - x2) < SPRITE_WIDTH) && (abs(y1 - y2) < SPRITE_HEIGHT))
352   {
353      int x,y;
354
355      normalize_coordinates(&x1, &y1, &x2, &y2);
356
357      m_sprite_sprite_collision_bitmap1->fill(0);
358      m_sprite_sprite_collision_bitmap2->fill(0);
359
360      m_gfxdecode->gfx(0)->opaque(*m_sprite_sprite_collision_bitmap1,m_sprite_sprite_collision_bitmap1->cliprect(),
361            code1,0,
362            0,flipy1,
363            x1,y1);
364
365      m_gfxdecode->gfx(0)->opaque(*m_sprite_sprite_collision_bitmap2,m_sprite_sprite_collision_bitmap2->cliprect(),
366            code2,0,
367            0,flipy2,
368            x2,y2);
369
370      for (x = x1; x < x1 + SPRITE_WIDTH; x++)
371         for (y = y1; y < y1 + SPRITE_HEIGHT; y++)
372            if ((m_sprite_sprite_collision_bitmap1->pix16(y, x) == 1) &&
373               (m_sprite_sprite_collision_bitmap2->pix16(y, x) == 1))
374            {
375               *col_x = (x1 + x) & 0x0f;
376               *col_y = (y1 + y) & 0x0f;
377
378               collided = 1;
379
380               break;
381            }
382   }
383
384   return collided;
385}
386
387
388/* returns 1 for collision with goal post,
389   2 for collision with scoring area */
390int carpolo_state::check_sprite_left_goal_collision(int x1, int y1, int code1, int flipy1, int goalpost_only)
391{
392   int collided = 0;
393
394   x1 = 240 - x1;
395   y1 = 240 - y1;
396
397   /* check if the sprite is even within the range of the goal */
398   if (((y1 + 16) > GOAL_Y) && (y1 < (GOAL_Y + GOAL_HEIGHT)) &&
399      ((x1 + 16) > LEFT_GOAL_X) && (x1 < (LEFT_GOAL_X + GOAL_WIDTH)))
400   {
401      int x,y;
402      int x2,y2;
403
404
405      x2 = LEFT_GOAL_X;
406      y2 = GOAL_Y;
407
408      normalize_coordinates(&x1, &y1, &x2, &y2);
409
410      m_sprite_goal_collision_bitmap1->fill(0);
411      m_sprite_goal_collision_bitmap2->fill(0);
412
413      m_gfxdecode->gfx(0)->opaque(*m_sprite_goal_collision_bitmap1,m_sprite_goal_collision_bitmap1->cliprect(),
414            code1,0,
415            0,flipy1,
416            x1,y1);
417
418      m_gfxdecode->gfx(1)->zoom_transpen(*m_sprite_goal_collision_bitmap2,m_sprite_goal_collision_bitmap2->cliprect(),
419               0,0,
420               0,0,
421               x2,y2,
422               0x20000,0x20000,0);
423
424      for (x = x1; x < x1 + SPRITE_WIDTH; x++)
425         for (y = y1; y < y1 + SPRITE_HEIGHT; y++)
426            if (m_sprite_goal_collision_bitmap1->pix16(y, x) == 1)
427            {
428               pen_t pix = m_sprite_goal_collision_bitmap2->pix16(y, x);
429
430               if (pix == LEFT_GOAL_PEN)
431               {
432                  collided = 1;
433                  break;
434               }
435
436               if (!goalpost_only && (pix == LEFT_SCORE_PEN))
437               {
438                  collided = 2;
439                  break;
440               }
441            }
442   }
443
444   return collided;
445}
446
447
448int carpolo_state::check_sprite_right_goal_collision(int x1, int y1, int code1, int flipy1, int goalpost_only)
449{
450   int collided = 0;
451
452   x1 = 240 - x1;
453   y1 = 240 - y1;
454
455   /* check if the sprite is even within the range of the goal */
456   if (((y1 + 16) > GOAL_Y) && (y1 < (GOAL_Y + GOAL_HEIGHT)) &&
457      ((x1 + 16) > RIGHT_GOAL_X) && (x1 < (RIGHT_GOAL_X + GOAL_WIDTH)))
458   {
459      int x,y;
460      int x2,y2;
461
462      x2 = RIGHT_GOAL_X;
463      y2 = GOAL_Y;
464
465      normalize_coordinates(&x1, &y1, &x2, &y2);
466
467      m_sprite_goal_collision_bitmap1->fill(0);
468      m_sprite_goal_collision_bitmap2->fill(0);
469
470      m_gfxdecode->gfx(0)->opaque(*m_sprite_goal_collision_bitmap1,m_sprite_goal_collision_bitmap1->cliprect(),
471            code1,0,
472            0,flipy1,
473            x1,y1);
474
475      m_gfxdecode->gfx(1)->zoom_transpen(*m_sprite_goal_collision_bitmap2,m_sprite_goal_collision_bitmap2->cliprect(),
476               0,1,
477               1,0,
478               x2,y2,
479               0x20000,0x20000,0);
480
481      for (x = x1; x < x1 + SPRITE_WIDTH; x++)
482         for (y = y1; y < y1 + SPRITE_HEIGHT; y++)
483            if (m_sprite_goal_collision_bitmap1->pix16(y, x) == 1)
484            {
485               pen_t pix = m_sprite_goal_collision_bitmap2->pix16(y, x);
486
487               if (pix == RIGHT_GOAL_PEN)
488               {
489                  collided = 1;
490                  break;
491               }
492
493               if (!goalpost_only && (pix == RIGHT_SCORE_PEN))
494               {
495                  collided = 2;
496                  break;
497               }
498            }
499   }
500
501   return collided;
502}
503
504
505/* returns 1 for collision with vertical border,
506   2 for collision with horizontal border */
507int carpolo_state::check_sprite_border_collision(UINT8 x1, UINT8 y1, int code1, int flipy1)
508{
509   UINT8 x,y;
510   int collided = 0;
511
512   x1 = 240 - x1;
513   y1 = 240 - y1;
514
515   m_gfxdecode->gfx(0)->opaque(*m_sprite_border_collision_bitmap,m_sprite_border_collision_bitmap->cliprect(),
516         code1,0,
517         0,flipy1,
518         0,0);
519
520   for (x = 0; x < SPRITE_WIDTH; x++)
521      for (y = 0; y < SPRITE_HEIGHT; y++)
522         if (m_sprite_border_collision_bitmap->pix16(y, x) == 1)
523         {
524            if (((UINT8)(x1 + x) == LEFT_BORDER) ||
525               ((UINT8)(x1 + x) == RIGHT_BORDER))
526            {
527               collided = 1;
528               break;
529            }
530
531            if (((UINT8)(y1 + y) == TOP_BORDER) ||
532               ((UINT8)(y1 + y) == BOTTOM_BORDER))
533            {
534               collided = 2;
535               break;
536            }
537         }
538
539   return collided;
540}
541
542
543void carpolo_state::screen_eof_carpolo(screen_device &screen, bool state)
544{
545   // rising edge
546   if (state)
547   {
548      int col_x, col_y;
549      int car1_x, car2_x, car3_x, car4_x, ball_x;
550      int car1_y, car2_y, car3_y, car4_y, ball_y;
551      int car1_code, car2_code, car3_code, car4_code, ball_code;
552      int car1_flipy, car2_flipy, car3_flipy, car4_flipy, ball_flipy;
553
554
555      /* check car-car collision first */
556
557      car1_x = m_spriteram[0x00];
558      car1_y = m_spriteram[0x01];
559      remap_sprite_code(0, m_spriteram[0x0c] & 0x0f, &car1_code, &car1_flipy);
560
561      car2_x = m_spriteram[0x02];
562      car2_y = m_spriteram[0x03];
563      remap_sprite_code(0, m_spriteram[0x0c] >> 4,   &car2_code, &car2_flipy);
564
565      car3_x = m_spriteram[0x04];
566      car3_y = m_spriteram[0x05];
567      remap_sprite_code(0, m_spriteram[0x0d] & 0x0f, &car3_code, &car3_flipy);
568
569      car4_x = m_spriteram[0x06];
570      car4_y = m_spriteram[0x07];
571      remap_sprite_code(0, m_spriteram[0x0d] >> 4,   &car4_code, &car4_flipy);
572
573      ball_x = m_spriteram[0x08];
574      ball_y = m_spriteram[0x09];
575      remap_sprite_code(1, m_spriteram[0x0e] & 0x0f, &ball_code, &ball_flipy);
576
577
578      /* cars 1 and 2 */
579      if (check_sprite_sprite_collision(car1_x, car1_y, car1_code, car1_flipy,
580                                 car2_x, car2_y, car2_code, car2_flipy,
581                                 &col_x, &col_y))
582         carpolo_generate_car_car_interrupt(0, 1);
583
584      /* cars 1 and 3 */
585      else if (check_sprite_sprite_collision(car1_x, car1_y, car1_code, car1_flipy,
586                                    car3_x, car3_y, car3_code, car3_flipy,
587                                    &col_x, &col_y))
588         carpolo_generate_car_car_interrupt(0, 2);
589
590      /* cars 1 and 4 */
591      else if (check_sprite_sprite_collision(car1_x, car1_y, car1_code, car1_flipy,
592                                    car4_x, car4_y, car4_code, car4_flipy,
593                                    &col_x, &col_y))
594         carpolo_generate_car_car_interrupt(0, 3);
595
596      /* cars 2 and 3 */
597      else if (check_sprite_sprite_collision(car2_x, car2_y, car2_code, car2_flipy,
598                                    car3_x, car3_y, car3_code, car3_flipy,
599                                    &col_x, &col_y))
600         carpolo_generate_car_car_interrupt(1, 2);
601
602      /* cars 2 and 4 */
603      else if (check_sprite_sprite_collision(car2_x, car2_y, car2_code, car2_flipy,
604                                    car4_x, car4_y, car4_code, car4_flipy,
605                                    &col_x, &col_y))
606         carpolo_generate_car_car_interrupt(1, 3);
607
608      /* cars 3 and 4 */
609      else if (check_sprite_sprite_collision(car3_x, car3_y, car3_code, car3_flipy,
610                                    car4_x, car4_y, car4_code, car4_flipy,
611                                    &col_x, &col_y))
612         carpolo_generate_car_car_interrupt(2, 3);
613
614
615
616      /* check car-ball collision */
617      if (check_sprite_sprite_collision(car1_x, car1_y, car1_code, car1_flipy,
618                                 ball_x, ball_y, ball_code, ball_flipy,
619                                 &col_x, &col_y))
620         carpolo_generate_car_ball_interrupt(0, col_x, col_y);
621
622      else if (check_sprite_sprite_collision(car2_x, car2_y, car2_code, car2_flipy,
623                                    ball_x, ball_y, ball_code, ball_flipy,
624                                    &col_x, &col_y))
625         carpolo_generate_car_ball_interrupt(1, col_x, col_y);
626
627      else if (check_sprite_sprite_collision(car3_x, car3_y, car3_code, car3_flipy,
628                                    ball_x, ball_y, ball_code, ball_flipy,
629                                    &col_x, &col_y))
630         carpolo_generate_car_ball_interrupt(2, col_x, col_y);
631
632      else if (check_sprite_sprite_collision(car4_x, car4_y, car4_code, car4_flipy,
633                                    ball_x, ball_y, ball_code, ball_flipy,
634                                    &col_x, &col_y))
635         carpolo_generate_car_ball_interrupt(3, col_x, col_y);
636
637
638      /* check car-goal collision */
639      if (check_sprite_left_goal_collision(car1_x, car1_y, car1_code, car1_flipy, 1))
640         carpolo_generate_car_goal_interrupt(0, 0);
641
642      else if (check_sprite_right_goal_collision(car1_x, car1_y, car1_code, car1_flipy, 1))
643         carpolo_generate_car_goal_interrupt(0, 1);
644
645      else if (check_sprite_left_goal_collision(car2_x, car2_y, car2_code, car2_flipy, 1))
646         carpolo_generate_car_goal_interrupt(1, 0);
647
648      else if (check_sprite_right_goal_collision(car2_x, car2_y, car2_code, car2_flipy, 1))
649         carpolo_generate_car_goal_interrupt(1, 1);
650
651      else if (check_sprite_left_goal_collision(car3_x, car3_y, car3_code, car3_flipy, 1))
652         carpolo_generate_car_goal_interrupt(2, 0);
653
654      else if (check_sprite_right_goal_collision(car3_x, car3_y, car3_code, car3_flipy, 1))
655         carpolo_generate_car_goal_interrupt(2, 1);
656
657      else if (check_sprite_left_goal_collision(car4_x, car4_y, car4_code, car4_flipy, 1))
658         carpolo_generate_car_goal_interrupt(3, 0);
659
660      else if (check_sprite_right_goal_collision(car4_x, car4_y, car4_code, car4_flipy, 1))
661         carpolo_generate_car_goal_interrupt(3, 1);
662
663
664      /* check ball collision with static screen elements */
665      {
666         int col;
667
668         col = check_sprite_left_goal_collision(ball_x, ball_y, ball_code, ball_flipy, 0);
669
670         if (col == 1)  carpolo_generate_ball_screen_interrupt(0x05);
671         if (col == 2)  carpolo_generate_ball_screen_interrupt(0x03);
672
673
674         col = check_sprite_right_goal_collision(ball_x, ball_y, ball_code, ball_flipy, 0);
675
676         if (col == 1)  carpolo_generate_ball_screen_interrupt(0x05 | 0x08);
677         if (col == 2)  carpolo_generate_ball_screen_interrupt(0x03 | 0x08);
678
679
680         if (check_sprite_border_collision(ball_x, ball_y, ball_code, ball_flipy))
681            carpolo_generate_ball_screen_interrupt(0x06);
682      }
683
684
685      /* check car-border collision */
686      {
687         int col;
688
689         col = check_sprite_border_collision(car1_x, car1_y, car1_code, car1_flipy);
690
691         if (col)
692            carpolo_generate_car_border_interrupt(0, (col == 2));
693         else
694         {
695            col = check_sprite_border_collision(car2_x, car2_y, car2_code, car2_flipy);
696
697            if (col)
698               carpolo_generate_car_border_interrupt(1, (col == 2));
699            else
700            {
701               col = check_sprite_border_collision(car3_x, car3_y, car3_code, car3_flipy);
702
703               if (col)
704                  carpolo_generate_car_border_interrupt(2, (col == 2));
705               else
706               {
707                  col = check_sprite_border_collision(car4_x, car4_y, car4_code, car4_flipy);
708
709                  if (col)
710                     carpolo_generate_car_border_interrupt(3, (col == 2));
711               }
712            }
713         }
714      }
715   }
716}


Previous 199869 Revisions Next


© 1997-2024 The MAME Team