1 /***************************************************************************
2 
3   vidhrdw.c
4 
5   Functions to emulate the video hardware of the machine.
6 
7 ***************************************************************************/
8 
9 #include "driver.h"
10 #include "vidhrdw/generic.h"
11 
12 unsigned char *route16_sharedram;
13 unsigned char *route16_videoram1;
14 unsigned char *route16_videoram2;
15 size_t route16_videoram_size;
16 
17 static struct osd_bitmap *tmpbitmap1;
18 static struct osd_bitmap *tmpbitmap2;
19 
20 static int video_flip;
21 static int video_color_select_1;
22 static int video_color_select_2;
23 static int video_disable_1 = 0;
24 static int video_disable_2 = 0;
25 static int video_remap_1;
26 static int video_remap_2;
27 static const unsigned char *route16_color_prom;
28 static int route16_hardware;
29 
30 /* Local functions */
31 static void modify_pen(int pen, int colorindex);
32 static void common_videoram_w(int offset,int data,
33                               int coloroffset, struct osd_bitmap *bitmap);
34 
35 
36 
route16_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)37 void route16_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
38 {
39 	route16_color_prom = color_prom;	/* we'll need this later */
40 }
41 
42 
43 /***************************************************************************
44 
45   Set hardware dependent flag.
46 
47 ***************************************************************************/
init_route16b(void)48 void init_route16b(void)
49 {
50     route16_hardware = 1;
51 }
52 
init_route16(void)53 void init_route16(void)
54 {
55 	unsigned char *rom = memory_region(REGION_CPU1);
56 
57 
58 	/* patch the protection */
59 	rom[0x00e9] = 0x3a;
60 
61 	rom[0x0754] = 0xc3;
62 	rom[0x0755] = 0x63;
63 	rom[0x0756] = 0x07;
64 
65 	init_route16b();
66 }
67 
init_stratvox(void)68 void init_stratvox(void)
69 {
70     route16_hardware = 0;
71 }
72 
73 
74 /***************************************************************************
75 
76   Start the video hardware emulation.
77 
78 ***************************************************************************/
route16_vh_start(void)79 int route16_vh_start(void)
80 {
81 	if ((tmpbitmap1 = bitmap_alloc(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
82 	{
83 		return 1;
84 	}
85 
86 	if ((tmpbitmap2 = bitmap_alloc(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
87 	{
88 
89 		bitmap_free(tmpbitmap1);
90 		tmpbitmap1 = 0;
91 		return 1;
92 	}
93 
94 	video_flip = 0;
95 	video_color_select_1 = 0;
96 	video_color_select_2 = 0;
97 	video_disable_1 = 0;
98 	video_disable_2 = 0;
99 	video_remap_1 = 1;
100 	video_remap_2 = 1;
101 
102 	return 0;
103 }
104 
105 /***************************************************************************
106 
107   Stop the video hardware emulation.
108 
109 ***************************************************************************/
route16_vh_stop(void)110 void route16_vh_stop(void)
111 {
112 	bitmap_free(tmpbitmap1);
113 	bitmap_free(tmpbitmap2);
114 }
115 
116 
117 /***************************************************************************
118   route16_out0_w
119 ***************************************************************************/
WRITE_HANDLER(route16_out0_w)120 WRITE_HANDLER( route16_out0_w )
121 {
122 	static int last_write = 0;
123 
124 	if (data == last_write) return;
125 
126 	video_disable_1 = ((data & 0x02) << 6) && route16_hardware;
127 	video_color_select_1 = ((data & 0x1f) << 2);
128 
129 	/* Bit 5 is the coin counter. */
130 	coin_counter_w(0, data & 0x20);
131 
132 	video_remap_1 = 1;
133 	last_write = data;
134 }
135 
136 /***************************************************************************
137   route16_out1_w
138 ***************************************************************************/
WRITE_HANDLER(route16_out1_w)139 WRITE_HANDLER( route16_out1_w )
140 {
141 	static int last_write = 0;
142 
143 	if (data == last_write) return;
144 
145 	video_disable_2 = ((data & 0x02) << 6 ) && route16_hardware;
146 	video_color_select_2 = ((data & 0x1f) << 2);
147 
148 	if (video_flip != ((data & 0x20) >> 5))
149 	{
150 		video_flip = (data & 0x20) >> 5;
151 	}
152 
153 	video_remap_2 = 1;
154 	last_write = data;
155 }
156 
157 /***************************************************************************
158 
159   Handle Stratovox's extra sound effects.
160 
161 ***************************************************************************/
WRITE_HANDLER(stratvox_sn76477_w)162 WRITE_HANDLER( stratvox_sn76477_w )
163 {
164 	/* get out for Route 16 */
165 	if (route16_hardware) return;
166 
167     /***************************************************************
168      * AY8910 output bits are connected to...
169      * 7    - direct: 5V * 30k/(100+30k) = 1.15V - via DAC??
170      * 6    - SN76477 mixer a
171      * 5    - SN76477 mixer b
172      * 4    - SN76477 mixer c
173      * 3    - SN76477 envelope 1
174 	 * 2	- SN76477 envelope 2
175      * 1    - SN76477 vco
176      * 0    - SN76477 enable
177      ***************************************************************/
178     SN76477_mixer_w(0,(data >> 4) & 7);
179 	SN76477_envelope_w(0,(data >> 2) & 3);
180     SN76477_vco_w(0,(data >> 1) & 1);
181     SN76477_enable_w(0,data & 1);
182 }
183 
184 /***************************************************************************
185   route16_sharedram_r
186 ***************************************************************************/
READ_HANDLER(route16_sharedram_r)187 READ_HANDLER( route16_sharedram_r )
188 {
189 	return route16_sharedram[offset];
190 }
191 
192 /***************************************************************************
193   route16_sharedram_w
194 ***************************************************************************/
WRITE_HANDLER(route16_sharedram_w)195 WRITE_HANDLER( route16_sharedram_w )
196 {
197 	route16_sharedram[offset] = data;
198 
199 	// 4313-4319 are used in Route 16 as triggers to wake the other CPU
200 	if (offset >= 0x0313 && offset <= 0x0319 && data == 0xff && route16_hardware)
201 	{
202 		// Let the other CPU run
203 		cpu_yield();
204 	}
205 }
206 
207 /***************************************************************************
208   route16_videoram1_r
209 ***************************************************************************/
READ_HANDLER(route16_videoram1_r)210 READ_HANDLER( route16_videoram1_r )
211 {
212 	return route16_videoram1[offset];
213 }
214 
215 /***************************************************************************
216   route16_videoram2_r
217 ***************************************************************************/
READ_HANDLER(route16_videoram2_r)218 READ_HANDLER( route16_videoram2_r )
219 {
220 	return route16_videoram1[offset];
221 }
222 
223 /***************************************************************************
224   route16_videoram1_w
225 ***************************************************************************/
WRITE_HANDLER(route16_videoram1_w)226 WRITE_HANDLER( route16_videoram1_w )
227 {
228 	route16_videoram1[offset] = data;
229 
230 	common_videoram_w(offset, data, 0, tmpbitmap1);
231 }
232 
233 /***************************************************************************
234   route16_videoram2_w
235 ***************************************************************************/
WRITE_HANDLER(route16_videoram2_w)236 WRITE_HANDLER( route16_videoram2_w )
237 {
238 	route16_videoram2[offset] = data;
239 
240 	common_videoram_w(offset, data, 4, tmpbitmap2);
241 }
242 
243 /***************************************************************************
244   common_videoram_w
245 ***************************************************************************/
common_videoram_w(int offset,int data,int coloroffset,struct osd_bitmap * bitmap)246 static void common_videoram_w(int offset,int data,
247                               int coloroffset, struct osd_bitmap *bitmap)
248 {
249 	int x, y, color1, color2, color3, color4;
250 
251 	x = ((offset & 0x3f) << 2);
252 	y = (offset & 0xffc0) >> 6;
253 
254 	if (video_flip)
255 	{
256 		x = 255 - x;
257 		y = 255 - y;
258 	}
259 
260 	color4 = ((data & 0x80) >> 6) | ((data & 0x08) >> 3);
261 	color3 = ((data & 0x40) >> 5) | ((data & 0x04) >> 2);
262 	color2 = ((data & 0x20) >> 4) | ((data & 0x02) >> 1);
263 	color1 = ((data & 0x10) >> 3) | ((data & 0x01)     );
264 
265 	if (video_flip)
266 	{
267 		plot_pixel(bitmap, x  , y, Machine->pens[color1 | coloroffset]);
268 		plot_pixel(bitmap, x-1, y, Machine->pens[color2 | coloroffset]);
269 		plot_pixel(bitmap, x-2, y, Machine->pens[color3 | coloroffset]);
270 		plot_pixel(bitmap, x-3, y, Machine->pens[color4 | coloroffset]);
271 	}
272 	else
273 	{
274 		plot_pixel(bitmap, x  , y, Machine->pens[color1 | coloroffset]);
275 		plot_pixel(bitmap, x+1, y, Machine->pens[color2 | coloroffset]);
276 		plot_pixel(bitmap, x+2, y, Machine->pens[color3 | coloroffset]);
277 		plot_pixel(bitmap, x+3, y, Machine->pens[color4 | coloroffset]);
278 	}
279 }
280 
281 /***************************************************************************
282 
283   Draw the game screen in the given osd_bitmap.
284   Do NOT call osd_update_display() from this function, it will be called by
285   the main emulation engine.
286 
287 ***************************************************************************/
route16_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)288 void route16_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
289 {
290     if (video_remap_1)
291 	{
292 		modify_pen(0, video_color_select_1 + 0);
293 		modify_pen(1, video_color_select_1 + 1);
294 		modify_pen(2, video_color_select_1 + 2);
295 		modify_pen(3, video_color_select_1 + 3);
296 	}
297 
298 	if (video_remap_2)
299 	{
300 		modify_pen(4, video_color_select_2 + 0);
301 		modify_pen(5, video_color_select_2 + 1);
302 		modify_pen(6, video_color_select_2 + 2);
303 		modify_pen(7, video_color_select_2 + 3);
304 	}
305 
306 
307 	if (palette_recalc() || video_remap_1 || video_remap_2)
308 	{
309 		int offs;
310 
311 		// redraw bitmaps
312 		for (offs = 0; offs < route16_videoram_size; offs++)
313 		{
314 			route16_videoram1_w(offs, route16_videoram1[offs]);
315 			route16_videoram2_w(offs, route16_videoram2[offs]);
316 		}
317 	}
318 
319 	video_remap_1 = 0;
320 	video_remap_2 = 0;
321 
322 
323 	if (!video_disable_2)
324 	{
325 		copybitmap(bitmap,tmpbitmap2,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
326 	}
327 
328 	if (!video_disable_1)
329 	{
330 		if (video_disable_2)
331 			copybitmap(bitmap,tmpbitmap1,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
332 		else
333 			copybitmap(bitmap,tmpbitmap1,0,0,0,0,&Machine->visible_area,TRANSPARENCY_COLOR,0);
334 	}
335 }
336 
337 /***************************************************************************
338   mofify_pen
339  ***************************************************************************/
modify_pen(int pen,int colorindex)340 static void modify_pen(int pen, int colorindex)
341 {
342 	int r,g,b,color;
343 
344 	color = route16_color_prom[colorindex];
345 
346 	r = ((color & 1) ? 0xff : 0x00);
347 	g = ((color & 2) ? 0xff : 0x00);
348 	b = ((color & 4) ? 0xff : 0x00);
349 
350 	palette_change_color(pen,r,g,b);
351 }
352