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 
13 
14 static int gfxbank;
15 static unsigned char *superqix_bitmapram,*superqix_bitmapram2,*superqix_bitmapram_dirty,*superqix_bitmapram2_dirty;
16 static struct osd_bitmap *tmpbitmap2;
17 int sqix_minx,sqix_maxx,sqix_miny,sqix_maxy;
18 int sqix_last_bitmap;
19 int sqix_current_bitmap;
20 
21 
22 
23 /***************************************************************************
24 
25   Start the video hardware emulation.
26 
27 ***************************************************************************/
superqix_vh_start(void)28 int superqix_vh_start(void)
29 {
30 	if (generic_vh_start() != 0)
31 		return 1;
32 
33 	/* palette RAM is accessed thorough I/O ports, so we have to */
34 	/* allocate it ourselves */
35 	if ((paletteram = (unsigned char*)malloc(256 * sizeof(unsigned char))) == 0)
36 	{
37 		generic_vh_stop();
38 		return 1;
39 	}
40 
41 	if ((superqix_bitmapram = (unsigned char*)malloc(0x7000 * sizeof(unsigned char))) == 0)
42 	{
43 		free(paletteram);
44 		generic_vh_stop();
45 		return 1;
46 	}
47 
48 	if ((superqix_bitmapram2 = (unsigned char*)malloc(0x7000 * sizeof(unsigned char))) == 0)
49 	{
50 		free(superqix_bitmapram);
51 		free(paletteram);
52 		generic_vh_stop();
53 		return 1;
54 	}
55 
56 	if ((superqix_bitmapram_dirty = (unsigned char*)malloc(0x7000 * sizeof(unsigned char))) == 0)
57 	{
58 		free(superqix_bitmapram2);
59 		free(superqix_bitmapram);
60 		free(paletteram);
61 		generic_vh_stop();
62 		return 1;
63 	}
64 	memset(superqix_bitmapram_dirty,1,0x7000);
65 
66 	if ((superqix_bitmapram2_dirty = (unsigned char*)malloc(0x7000 * sizeof(unsigned char))) == 0)
67 	{
68 		free(superqix_bitmapram_dirty);
69 		free(superqix_bitmapram2);
70 		free(superqix_bitmapram);
71 		free(paletteram);
72 		generic_vh_stop();
73 		return 1;
74 	}
75 	memset(superqix_bitmapram2_dirty,1,0x7000);
76 
77 	if ((tmpbitmap2 = bitmap_alloc(256, 256)) == 0)
78 	{
79 		free(superqix_bitmapram2_dirty);
80 		free(superqix_bitmapram_dirty);
81 		free(superqix_bitmapram2);
82 		free(superqix_bitmapram);
83 		free(paletteram);
84 		generic_vh_stop();
85 		return 1;
86 	}
87 
88 	sqix_minx=0;sqix_maxx=127;sqix_miny=0;sqix_maxy=223;
89 	sqix_last_bitmap=0;
90 
91 	return 0;
92 }
93 
94 
95 
96 /***************************************************************************
97 
98   Stop the video hardware emulation.
99 
100 ***************************************************************************/
superqix_vh_stop(void)101 void superqix_vh_stop(void)
102 {
103 	free(superqix_bitmapram2);
104 	free(superqix_bitmapram);
105 	free(superqix_bitmapram_dirty);
106 	free(superqix_bitmapram2_dirty);
107 	bitmap_free(tmpbitmap2);
108 	free(paletteram);
109 	generic_vh_stop();
110 }
111 
112 
113 
READ_HANDLER(superqix_bitmapram_r)114 READ_HANDLER( superqix_bitmapram_r )
115 {
116 	return superqix_bitmapram[offset];
117 }
118 
119 
WRITE_HANDLER(superqix_bitmapram_w)120 WRITE_HANDLER( superqix_bitmapram_w )
121 {
122 	if(data != superqix_bitmapram[offset])
123 	{
124 		int x,y;
125 		superqix_bitmapram[offset] = data;
126 		superqix_bitmapram_dirty[offset] = 1;
127 		x=offset%128;
128 		y=offset/128;
129 		if(x<sqix_minx) sqix_minx=x;
130 		if(x>sqix_maxx) sqix_maxx=x;
131 		if(y<sqix_miny) sqix_miny=y;
132 		if(y>sqix_maxy) sqix_maxy=y;
133 	}
134 }
135 
READ_HANDLER(superqix_bitmapram2_r)136 READ_HANDLER( superqix_bitmapram2_r )
137 {
138 	return superqix_bitmapram2[offset];
139 }
140 
WRITE_HANDLER(superqix_bitmapram2_w)141 WRITE_HANDLER( superqix_bitmapram2_w )
142 {
143 	if(data != superqix_bitmapram2[offset])
144 	{
145 		int x,y;
146 		superqix_bitmapram2[offset] = data;
147 		superqix_bitmapram2_dirty[offset] = 1;
148 		x=offset%128;
149 		y=offset/128;
150 		if(x<sqix_minx) sqix_minx=x;
151 		if(x>sqix_maxx) sqix_maxx=x;
152 		if(y<sqix_miny) sqix_miny=y;
153 		if(y>sqix_maxy) sqix_maxy=y;
154 	}
155 }
156 
157 
158 
WRITE_HANDLER(superqix_0410_w)159 WRITE_HANDLER( superqix_0410_w )
160 {
161 	int bankaddress;
162 	unsigned char *RAM = memory_region(REGION_CPU1);
163 
164 
165 	/* bits 0-1 select the tile bank */
166 	if (gfxbank != (data & 0x03))
167 	{
168 		gfxbank = data & 0x03;
169 		memset(dirtybuffer,1,videoram_size);
170 	}
171 
172 	/* bit 2 controls bitmap 1/2 */
173 	sqix_current_bitmap=data&4;
174 	if(sqix_current_bitmap !=sqix_last_bitmap)
175 	{
176 		sqix_last_bitmap=sqix_current_bitmap;
177 		memset(superqix_bitmapram_dirty,1,0x7000);
178 		memset(superqix_bitmapram2_dirty,1,0x7000);
179 		sqix_minx=0;sqix_maxx=127;sqix_miny=0;sqix_maxy=223;
180 	}
181 
182 	/* bit 3 enables NMI */
183 	interrupt_enable_w(offset,data & 0x08);
184 
185 	/* bits 4-5 control ROM bank */
186 	bankaddress = 0x10000 + ((data & 0x30) >> 4) * 0x4000;
187 	cpu_setbank(1,&RAM[bankaddress]);
188 }
189 
190 
191 
192 /***************************************************************************
193 
194   Draw the game screen in the given osd_bitmap.
195   Do NOT call osd_update_display() from this function, it will be called by
196   the main emulation engine.
197 
198 ***************************************************************************/
superqix_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)199 void superqix_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
200 {
201 	int offs,i;
202 	unsigned char pens[16];
203 
204 
205 	/* recalc the palette if necessary */
206 	if (palette_recalc())
207 	{
208 		memset(dirtybuffer,1,videoram_size);
209 		memset(superqix_bitmapram_dirty,1,0x7000);
210 		memset(superqix_bitmapram2_dirty,1,0x7000);
211 		sqix_minx=0;sqix_maxx=127;sqix_miny=0;sqix_maxy=223;
212 	}
213 
214 
215 	/* for every character in the Video RAM, check if it has been modified */
216 	/* since last time and update it accordingly. */
217 	for (offs = videoram_size - 1;offs >= 0;offs--)
218 	{
219 		if (dirtybuffer[offs])
220 		{
221 			int sx,sy;
222 
223 
224 			dirtybuffer[offs] = 0;
225 
226 			sx = offs % 32;
227 			sy = offs / 32;
228 
229 			drawgfx(tmpbitmap,Machine->gfx[(colorram[offs] & 0x04) ? 0 : (1 + gfxbank)],
230 					videoram[offs] + 256 * (colorram[offs] & 0x03),
231 					(colorram[offs] & 0xf0) >> 4,
232 					0,0,
233 					8*sx,8*sy,
234 					&Machine->visible_area,TRANSPARENCY_NONE,0);
235 		}
236 	}
237 
238 
239 	/* copy the character mapped graphics */
240 	copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
241 
242 	for(i=1;i<16;i++)
243 		pens[i]=Machine->pens[i];
244 	pens[0]=palette_transparent_pen;
245 
246 	if(sqix_current_bitmap==0)		/* Bitmap 1 */
247 	{
248 		int x,y;
249 
250 		for (y = sqix_miny;y <= sqix_maxy;y++)
251 		{
252 			for (x = sqix_minx;x <= sqix_maxx;x++)
253 			{
254 				int sx,sy,d;
255 
256 				if(superqix_bitmapram_dirty[y*128+x])
257 				{
258 					superqix_bitmapram_dirty[y*128+x]=0;
259 					d = superqix_bitmapram[y*128+x];
260 
261 					sx = 2*x;
262 					sy = y+16;
263 
264 					plot_pixel(tmpbitmap2, sx    , sy, pens[d >> 4]);
265 					plot_pixel(tmpbitmap2, sx + 1, sy, pens[d & 0x0f]);
266 				}
267 			}
268 		}
269 	}
270 	else		/* Bitmap 2 */
271 	{
272 		int x,y;
273 
274 		for (y = sqix_miny;y <= sqix_maxy;y++)
275 		{
276 			for (x = sqix_minx;x <= sqix_maxx;x++)
277 			{
278 				int sx,sy,d;
279 
280 				if(superqix_bitmapram2_dirty[y*128+x])
281 				{
282 					superqix_bitmapram2_dirty[y*128+x]=0;
283 					d = superqix_bitmapram2[y*128+x];
284 
285 					sx = 2*x;
286 					sy = y+16;
287 
288 					plot_pixel(tmpbitmap2, sx    , sy, pens[d >> 4]);
289 					plot_pixel(tmpbitmap2, sx + 1, sy, pens[d & 0x0f]);
290 				}
291 			}
292 		}
293 	}
294 	copybitmap(bitmap,tmpbitmap2,0,0,0,0,&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
295 
296 	/* Draw the sprites. Note that it is important to draw them exactly in this */
297 	/* order, to have the correct priorities. */
298 	for (offs = 0;offs < spriteram_size;offs += 4)
299 	{
300 		drawgfx(bitmap,Machine->gfx[5],
301 				spriteram[offs] + 256 * (spriteram[offs + 3] & 0x01),
302 				(spriteram[offs + 3] & 0xf0) >> 4,
303 				spriteram[offs + 3] & 0x04,spriteram[offs + 3] & 0x08,
304 				spriteram[offs + 1],spriteram[offs + 2],
305 				&Machine->visible_area,TRANSPARENCY_PEN,0);
306 	}
307 
308 
309 	/* redraw characters which have priority over the bitmap */
310 	for (offs = videoram_size - 1;offs >= 0;offs--)
311 	{
312 		if (colorram[offs] & 0x08)
313 		{
314 			int sx,sy;
315 
316 
317 			sx = offs % 32;
318 			sy = offs / 32;
319 
320 			drawgfx(bitmap,Machine->gfx[(colorram[offs] & 0x04) ? 0 : 1],
321 					videoram[offs] + 256 * (colorram[offs] & 0x03),
322 					(colorram[offs] & 0xf0) >> 4,
323 					0,0,
324 					8*sx,8*sy,
325 					&Machine->visible_area,TRANSPARENCY_PEN,0);
326 		}
327 	}
328 
329 	sqix_minx=1000;sqix_maxx=-1;sqix_miny=1000;sqix_maxy=-1;
330 }
331