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