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 int route16_hardware;
17
18 static struct mame_bitmap *tmpbitmap1;
19 static struct mame_bitmap *tmpbitmap2;
20
21 static int video_flip;
22 static int video_color_select_1;
23 static int video_color_select_2;
24 static int video_disable_1 = 0;
25 static int video_disable_2 = 0;
26 static int video_remap_1;
27 static int video_remap_2;
28 static const unsigned char *route16_color_prom;
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 mame_bitmap *bitmap);
34
35
36
PALETTE_INIT(route16)37 PALETTE_INIT( route16 )
38 {
39 route16_color_prom = color_prom; /* we'll need this later */
40 }
41
42
43 /***************************************************************************
44
45 Start the video hardware emulation.
46
47 ***************************************************************************/
VIDEO_START(route16)48 VIDEO_START( route16 )
49 {
50 if ((tmpbitmap1 = auto_bitmap_alloc(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
51 return 1;
52
53 if ((tmpbitmap2 = auto_bitmap_alloc(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
54 return 1;
55
56 video_flip = 0;
57 video_color_select_1 = 0;
58 video_color_select_2 = 0;
59 video_disable_1 = 0;
60 video_disable_2 = 0;
61 video_remap_1 = 1;
62 video_remap_2 = 1;
63
64 return 0;
65 }
66
67
68 /***************************************************************************
69 route16_out0_w
70 ***************************************************************************/
WRITE_HANDLER(route16_out0_w)71 WRITE_HANDLER( route16_out0_w )
72 {
73 static int last_write = 0;
74
75 if (data == last_write) return;
76
77 video_disable_1 = ((data & 0x02) << 6) && route16_hardware;
78 video_color_select_1 = ((data & 0x1f) << 2);
79
80 /* Bit 5 is the coin counter. */
81 coin_counter_w(0, data & 0x20);
82
83 video_remap_1 = 1;
84 last_write = data;
85 }
86
87 /***************************************************************************
88 route16_out1_w
89 ***************************************************************************/
WRITE_HANDLER(route16_out1_w)90 WRITE_HANDLER( route16_out1_w )
91 {
92 static int last_write = 0;
93
94 if (data == last_write) return;
95
96 video_disable_2 = ((data & 0x02) << 6 ) && route16_hardware;
97 video_color_select_2 = ((data & 0x1f) << 2);
98
99 if (video_flip != ((data & 0x20) >> 5))
100 {
101 video_flip = (data & 0x20) >> 5;
102 }
103
104 video_remap_2 = 1;
105 last_write = data;
106 }
107
108 /***************************************************************************
109
110 Handle Stratovox's extra sound effects.
111
112 ***************************************************************************/
WRITE_HANDLER(stratvox_sn76477_w)113 WRITE_HANDLER( stratvox_sn76477_w )
114 {
115 /* get out for Route 16 */
116 if (route16_hardware) return;
117
118 /***************************************************************
119 * AY8910 output bits are connected to...
120 * 7 - direct: 5V * 30k/(100+30k) = 1.15V - via DAC??
121 * 6 - SN76477 mixer a
122 * 5 - SN76477 mixer b
123 * 4 - SN76477 mixer c
124 * 3 - SN76477 envelope 1
125 * 2 - SN76477 envelope 2
126 * 1 - SN76477 vco
127 * 0 - SN76477 enable
128 ***************************************************************/
129 SN76477_mixer_w(0,(data >> 4) & 7);
130 SN76477_envelope_w(0,(data >> 2) & 3);
131 SN76477_vco_w(0,(data >> 1) & 1);
132 SN76477_enable_w(0,data & 1);
133 }
134
135 /***************************************************************************
136 route16_sharedram_r
137 ***************************************************************************/
READ_HANDLER(route16_sharedram_r)138 READ_HANDLER( route16_sharedram_r )
139 {
140 return route16_sharedram[offset];
141 }
142
143 /***************************************************************************
144 route16_sharedram_w
145 ***************************************************************************/
WRITE_HANDLER(route16_sharedram_w)146 WRITE_HANDLER( route16_sharedram_w )
147 {
148 route16_sharedram[offset] = data;
149
150 // 4313-4319 are used in Route 16 as triggers to wake the other CPU
151 if (offset >= 0x0313 && offset <= 0x0319 && data == 0xff && route16_hardware)
152 {
153 // Let the other CPU run
154 cpu_yield();
155 }
156 }
157
158 /***************************************************************************
159 guessing that the unconnected IN3 and OUT2 on the stratvox schematic
160 are hooked up for speakres and spacecho to somehow read the variable
161 resistors (eg a voltage ramp), using a write to OUT2 as a trigger
162 and then bits 0-2 of IN3 going low when each pot "matches". the VRx
163 values can be seen when IN0=0x55 and p1b1 is held during power on.
164 this would then be checking that the sounds are mixed correctly.
165 ***************************************************************************/
166 static int speakres_vrx;
167
READ_HANDLER(speakres_in3_r)168 READ_HANDLER ( speakres_in3_r )
169 {
170 int bit2=4, bit1=2, bit0=1;
171
172 /* just using a counter, the constants are the number of reads
173 before going low, each read is 40 cycles apart. the constants
174 were chosen based on the startup tests and for vr0=vr2 */
175 speakres_vrx++;
176 if(speakres_vrx>0x300) bit0=0; /* VR0 100k ohm - speech */
177 if(speakres_vrx>0x200) bit1=0; /* VR1 50k ohm - main volume */
178 if(speakres_vrx>0x300) bit2=0; /* VR2 100k ohm - explosion */
179
180 return 0xf8|bit2|bit1|bit0;
181 }
182
WRITE_HANDLER(speakres_out2_w)183 WRITE_HANDLER ( speakres_out2_w )
184 {
185 speakres_vrx=0;
186 }
187
188
189 /***************************************************************************
190 route16_videoram1_r
191 ***************************************************************************/
READ_HANDLER(route16_videoram1_r)192 READ_HANDLER( route16_videoram1_r )
193 {
194 return route16_videoram1[offset];
195 }
196
197 /***************************************************************************
198 route16_videoram2_r
199 ***************************************************************************/
READ_HANDLER(route16_videoram2_r)200 READ_HANDLER( route16_videoram2_r )
201 {
202 return route16_videoram1[offset];
203 }
204
205 /***************************************************************************
206 route16_videoram1_w
207 ***************************************************************************/
WRITE_HANDLER(route16_videoram1_w)208 WRITE_HANDLER( route16_videoram1_w )
209 {
210 route16_videoram1[offset] = data;
211
212 common_videoram_w(offset, data, 0, tmpbitmap1);
213 }
214
215 /***************************************************************************
216 route16_videoram2_w
217 ***************************************************************************/
WRITE_HANDLER(route16_videoram2_w)218 WRITE_HANDLER( route16_videoram2_w )
219 {
220 route16_videoram2[offset] = data;
221
222 common_videoram_w(offset, data, 4, tmpbitmap2);
223 }
224
225 /***************************************************************************
226 common_videoram_w
227 ***************************************************************************/
common_videoram_w(int offset,int data,int coloroffset,struct mame_bitmap * bitmap)228 static void common_videoram_w(int offset,int data,
229 int coloroffset, struct mame_bitmap *bitmap)
230 {
231 int x, y, color1, color2, color3, color4;
232
233 x = ((offset & 0x3f) << 2);
234 y = (offset & 0xffc0) >> 6;
235
236 if (video_flip)
237 {
238 x = 255 - x;
239 y = 255 - y;
240 }
241
242 color4 = ((data & 0x80) >> 6) | ((data & 0x08) >> 3);
243 color3 = ((data & 0x40) >> 5) | ((data & 0x04) >> 2);
244 color2 = ((data & 0x20) >> 4) | ((data & 0x02) >> 1);
245 color1 = ((data & 0x10) >> 3) | ((data & 0x01) );
246
247 if (video_flip)
248 {
249 plot_pixel(bitmap, x , y, Machine->pens[color1 | coloroffset]);
250 plot_pixel(bitmap, x-1, y, Machine->pens[color2 | coloroffset]);
251 plot_pixel(bitmap, x-2, y, Machine->pens[color3 | coloroffset]);
252 plot_pixel(bitmap, x-3, y, Machine->pens[color4 | coloroffset]);
253 }
254 else
255 {
256 plot_pixel(bitmap, x , y, Machine->pens[color1 | coloroffset]);
257 plot_pixel(bitmap, x+1, y, Machine->pens[color2 | coloroffset]);
258 plot_pixel(bitmap, x+2, y, Machine->pens[color3 | coloroffset]);
259 plot_pixel(bitmap, x+3, y, Machine->pens[color4 | coloroffset]);
260 }
261 }
262
263 /***************************************************************************
264
265 Draw the game screen in the given mame_bitmap.
266 Do NOT call osd_update_display() from this function, it will be called by
267 the main emulation engine.
268
269 ***************************************************************************/
VIDEO_UPDATE(route16)270 VIDEO_UPDATE( route16 )
271 {
272 if (video_remap_1)
273 {
274 modify_pen(0, video_color_select_1 + 0);
275 modify_pen(1, video_color_select_1 + 1);
276 modify_pen(2, video_color_select_1 + 2);
277 modify_pen(3, video_color_select_1 + 3);
278 }
279
280 if (video_remap_2)
281 {
282 modify_pen(4, video_color_select_2 + 0);
283 modify_pen(5, video_color_select_2 + 1);
284 modify_pen(6, video_color_select_2 + 2);
285 modify_pen(7, video_color_select_2 + 3);
286 }
287
288
289 if (get_vh_global_attribute_changed() || video_remap_1 || video_remap_2)
290 {
291 int offs;
292
293 // redraw bitmaps
294 for (offs = 0; offs < route16_videoram_size; offs++)
295 {
296 route16_videoram1_w(offs, route16_videoram1[offs]);
297 route16_videoram2_w(offs, route16_videoram2[offs]);
298 }
299 }
300
301 video_remap_1 = 0;
302 video_remap_2 = 0;
303
304
305 if (!video_disable_2)
306 {
307 copybitmap(bitmap,tmpbitmap2,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
308 }
309
310 if (!video_disable_1)
311 {
312 if (video_disable_2)
313 copybitmap(bitmap,tmpbitmap1,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
314 else
315 copybitmap(bitmap,tmpbitmap1,0,0,0,0,&Machine->visible_area,TRANSPARENCY_COLOR,0);
316 }
317 }
318
319 /***************************************************************************
320 mofify_pen
321 ***************************************************************************/
modify_pen(int pen,int colorindex)322 static void modify_pen(int pen, int colorindex)
323 {
324 int r,g,b,color;
325
326 color = route16_color_prom[colorindex];
327
328 r = ((color & 1) ? 0xff : 0x00);
329 g = ((color & 2) ? 0xff : 0x00);
330 b = ((color & 4) ? 0xff : 0x00);
331
332 palette_set_color(pen,r,g,b);
333 }
334