1 /***************************************************************************
2 
3 	Star Fire video system
4 
5 ***************************************************************************/
6 
7 #include "driver.h"
8 #include "vidhrdw/generic.h"
9 
10 
11 /* from the main driver */
12 extern UINT8 *starfire_videoram;
13 extern UINT8 *starfire_colorram;
14 
15 /* local allocated storage */
16 static UINT8 *scanline_dirty;
17 
18 static UINT8 starfire_vidctrl;
19 static UINT8 starfire_vidctrl1;
20 static UINT8 starfire_color;
21 
22 
23 
24 /*************************************
25  *
26  *	Initialize the video system
27  *
28  *************************************/
29 
VIDEO_START(starfire)30 VIDEO_START( starfire )
31 {
32 	/* make a temporary bitmap */
33 	tmpbitmap = auto_bitmap_alloc(Machine->drv->screen_width, Machine->drv->screen_height);
34 	if (!tmpbitmap)
35 		return 1;
36 
37 	/* make a dirty array */
38 	scanline_dirty = auto_malloc(256);
39 	if (!scanline_dirty)
40 		return 1;
41 
42 	/* reset videoram */
43 	memset(starfire_videoram, 0, 0x2000);
44 	memset(starfire_colorram, 0, 0x2000);
45 	memset(scanline_dirty, 1, 256);
46 
47 	return 0;
48 }
49 
50 
51 
52 /*************************************
53  *
54  *	Video control writes
55  *
56  *************************************/
57 
WRITE_HANDLER(starfire_vidctrl_w)58 WRITE_HANDLER( starfire_vidctrl_w )
59 {
60     starfire_vidctrl = data;
61 }
62 
WRITE_HANDLER(starfire_vidctrl1_w)63 WRITE_HANDLER( starfire_vidctrl1_w )
64 {
65     starfire_vidctrl1 = data;
66 }
67 
68 
69 
70 /*************************************
71  *
72  *	Color RAM read/writes
73  *
74  *************************************/
75 
WRITE_HANDLER(starfire_colorram_w)76 WRITE_HANDLER( starfire_colorram_w )
77 {
78 	/* handle writes to the pseudo-color RAM */
79 	if ((offset & 0xe0) == 0)
80 	{
81 		int palette_index = (offset & 0x1f) | ((offset & 0x200) >> 4);
82 		int r = ((data << 1) & 0x06) | ((offset >> 8) & 0x01);
83 		int b = (data >> 2) & 0x07;
84 		int g = (data >> 5) & 0x07;
85 
86 		/* set RAM regardless */
87 		starfire_colorram[offset & ~0x100] = data;
88 		starfire_colorram[offset |  0x100] = data;
89 
90 		/* don't modify the palette unless the TRANS bit is set */
91 		starfire_color = data & 0x1f;
92 		if (!(starfire_vidctrl1 & 0x40))
93 			return;
94 
95 		/* modify the pen */
96 		r = (r << 5) | (r << 2) | (r >> 1);
97 		b = (b << 5) | (b << 2) | (b >> 1);
98 		g = (g << 5) | (g << 2) | (g >> 1);
99 		palette_set_color(palette_index, r, g, b);
100 	}
101 
102 	/* handle writes to the rest of color RAM */
103 	else
104 	{
105 		/* set RAM based on CDRM */
106 		starfire_colorram[offset] = (starfire_vidctrl1 & 0x80) ? starfire_color : (data & 0x1f);
107 		scanline_dirty[offset & 0xff] = 1;
108 		starfire_color = data & 0x1f;
109 	}
110 }
111 
READ_HANDLER(starfire_colorram_r)112 READ_HANDLER( starfire_colorram_r )
113 {
114 	return starfire_colorram[offset];
115 }
116 
117 
118 
119 /*************************************
120  *
121  *	Video RAM read/writes
122  *
123  *************************************/
124 
WRITE_HANDLER(starfire_videoram_w)125 WRITE_HANDLER( starfire_videoram_w )
126 {
127 	int sh, lr, dm, ds, mask, d0, dalu;
128 	int offset1 = offset & 0x1fff;
129 	int offset2 = (offset + 0x100) & 0x1fff;
130 
131 	/* PROT */
132 	if (!(offset & 0xe0) && !(starfire_vidctrl1 & 0x20))
133 		return;
134 
135 	/* selector 6A */
136 	if (offset & 0x2000)
137 	{
138 		sh = (starfire_vidctrl >> 1) & 0x07;
139 		lr = starfire_vidctrl & 0x01;
140 	}
141 	else
142 	{
143 		sh = (starfire_vidctrl >> 5) & 0x07;
144 		lr = (starfire_vidctrl >> 4) & 0x01;
145 	}
146 
147 	/* mirror bits 5B/5C/5D/5E */
148 	dm = data;
149 	if (lr)
150 		dm = ((dm & 0x01) << 7) | ((dm & 0x02) << 5) | ((dm & 0x04) << 3) | ((dm & 0x08) << 1) |
151 		     ((dm & 0x10) >> 1) | ((dm & 0x20) >> 3) | ((dm & 0x40) >> 5) | ((dm & 0x80) >> 7);
152 
153 	/* shifters 6D/6E */
154 	ds = (dm << 8) >> sh;
155 	mask = 0xff00 >> sh;
156 
157 	/* ROLL */
158 	if ((offset & 0x1f00) == 0x1f00)
159 	{
160 		if (starfire_vidctrl1 & 0x10)
161 			mask &= 0x00ff;
162 		else
163 			mask &= 0xff00;
164 	}
165 
166 	/* ALU 8B/8D */
167 	d0 = (starfire_videoram[offset1] << 8) | starfire_videoram[offset2];
168 	dalu = d0 & ~mask;
169 	d0 &= mask;
170 	ds &= mask;
171 	switch (~starfire_vidctrl1 & 15)
172 	{
173 		case 0:		dalu |= ds ^ mask;				break;
174 		case 1:		dalu |= (ds | d0) ^ mask;		break;
175 		case 2:		dalu |= (ds ^ mask) & d0;		break;
176 		case 3:		dalu |= 0;						break;
177 		case 4:		dalu |= (ds & d0) ^ mask;		break;
178 		case 5:		dalu |= d0 ^ mask;				break;
179 		case 6:		dalu |= ds ^ d0;				break;
180 		case 7:		dalu |= ds & (d0 ^ mask);		break;
181 		case 8:		dalu |= (ds ^ mask) | d0;		break;
182 		case 9:		dalu |= (ds ^ d0) ^ mask;		break;
183 		case 10:	dalu |= d0;						break;
184 		case 11:	dalu |= ds & d0;				break;
185 		case 12:	dalu |= mask;					break;
186 		case 13:	dalu |= ds | (d0 ^ mask);		break;
187 		case 14:	dalu |= ds | d0;				break;
188 		case 15:	dalu |= ds;						break;
189 	}
190 
191 	/* final output */
192 	starfire_videoram[offset1] = dalu >> 8;
193 	starfire_videoram[offset2] = dalu;
194 	scanline_dirty[offset1 & 0xff] = 1;
195 
196 	/* color output */
197 	if (!(offset & 0x2000) && !(starfire_vidctrl1 & 0x80))
198 	{
199 		if (mask & 0xff00)
200 			starfire_colorram[offset1] = starfire_color;
201 		if (mask & 0x00ff)
202 			starfire_colorram[offset2] = starfire_color;
203 	}
204 }
205 
READ_HANDLER(starfire_videoram_r)206 READ_HANDLER( starfire_videoram_r )
207 {
208 	int sh, mask, d0;
209 	int offset1 = offset & 0x1fff;
210 	int offset2 = (offset + 0x100) & 0x1fff;
211 
212 	/* selector 6A */
213 	if (offset & 0x2000)
214 		sh = (starfire_vidctrl >> 1) & 0x07;
215 	else
216 		sh = (starfire_vidctrl >> 5) & 0x07;
217 
218 	/* shifters 6D/6E */
219 	mask = 0xff00 >> sh;
220 
221 	/* ROLL */
222 	if ((offset & 0x1f00) == 0x1f00)
223 	{
224 		if (starfire_vidctrl1 & 0x10)
225 			mask &= 0x00ff;
226 		else
227 			mask &= 0xff00;
228 	}
229 
230 	/* munge the results */
231 	d0 = (starfire_videoram[offset1] & (mask >> 8)) | (starfire_videoram[offset2] & mask);
232 	d0 = (d0 << sh) | (d0 >> (8 - sh));
233 	return d0 & 0xff;
234 }
235 
236 
237 
238 /*************************************
239  *
240  *	Periodic screen refresh callback
241  *
242  *************************************/
243 
starfire_video_update(int scanline,int count)244 void starfire_video_update(int scanline, int count)
245 {
246 	UINT8 *pix = &starfire_videoram[scanline];
247 	UINT8 *col = &starfire_colorram[scanline];
248 	int x, y;
249 
250 	/* update any dirty scanlines in this range */
251 	for (x = 0; x < 256; x += 8)
252 	{
253 		for (y = 0; y < count; y++)
254 			if (scanline_dirty[scanline + y])
255 			{
256 				int data = pix[y];
257 				int color = col[y];
258 
259 				plot_pixel(tmpbitmap, x + 0, scanline + y, color | ((data >> 2) & 0x20));
260 				plot_pixel(tmpbitmap, x + 1, scanline + y, color | ((data >> 1) & 0x20));
261 				plot_pixel(tmpbitmap, x + 2, scanline + y, color | ((data >> 0) & 0x20));
262 				plot_pixel(tmpbitmap, x + 3, scanline + y, color | ((data << 1) & 0x20));
263 				plot_pixel(tmpbitmap, x + 4, scanline + y, color | ((data << 2) & 0x20));
264 				plot_pixel(tmpbitmap, x + 5, scanline + y, color | ((data << 3) & 0x20));
265 				plot_pixel(tmpbitmap, x + 6, scanline + y, color | ((data << 4) & 0x20));
266 				plot_pixel(tmpbitmap, x + 7, scanline + y, color | ((data << 5) & 0x20));
267 			}
268 
269 		pix += 256;
270 		col += 256;
271 	}
272 
273 	/* mark them not dirty anymore */
274 	for (y = 0; y < count; y++)
275 		scanline_dirty[scanline + y] = 0;
276 }
277 
278 
279 
280 /*************************************
281  *
282  *	Standard screen refresh callback
283  *
284  *************************************/
285 
VIDEO_UPDATE(starfire)286 VIDEO_UPDATE( starfire )
287 {
288 	/* copy the bitmap, remapping the colors */
289 	copybitmap_remap(bitmap, tmpbitmap, 0, 0, 0, 0, &Machine->visible_area, TRANSPARENCY_NONE, 0);
290 }
291