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