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 unsigned char *gberet_videoram,*gberet_colorram;
15 unsigned char *gberet_spritebank;
16 unsigned char *gberet_scrollram;
17 static struct tilemap *bg_tilemap;
18 static int interruptenable;
19 static int flipscreen;
20 static int sprites_type;
21 
22 
23 /***************************************************************************
24 
25   Convert the color PROMs into a more useable format.
26 
27   Green Beret has a 32 bytes palette PROM and two 256 bytes color lookup table
28   PROMs (one for sprites, one for characters).
29   The palette PROM is connected to the RGB output, this way:
30 
31   bit 7 -- 220 ohm resistor  -- BLUE
32         -- 470 ohm resistor  -- BLUE
33         -- 220 ohm resistor  -- GREEN
34         -- 470 ohm resistor  -- GREEN
35         -- 1  kohm resistor  -- GREEN
36         -- 220 ohm resistor  -- RED
37         -- 470 ohm resistor  -- RED
38   bit 0 -- 1  kohm resistor  -- RED
39 
40 ***************************************************************************/
41 
gberet_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)42 void gberet_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
43 {
44 	int i;
45 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
46 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
47 
48 
49 	for (i = 0;i < Machine->drv->total_colors;i++)
50 	{
51 		int bit0,bit1,bit2;
52 
53 
54 		bit0 = (*color_prom >> 0) & 0x01;
55 		bit1 = (*color_prom >> 1) & 0x01;
56 		bit2 = (*color_prom >> 2) & 0x01;
57 		*(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
58 		bit0 = (*color_prom >> 3) & 0x01;
59 		bit1 = (*color_prom >> 4) & 0x01;
60 		bit2 = (*color_prom >> 5) & 0x01;
61 		*(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
62 		bit0 = 0;
63 		bit1 = (*color_prom >> 6) & 0x01;
64 		bit2 = (*color_prom >> 7) & 0x01;
65 		*(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
66 
67 		color_prom++;
68 	}
69 
70 	for (i = 0;i < TOTAL_COLORS(1);i++)
71 	{
72 		if (*color_prom & 0x0f) COLOR(1,i) = *color_prom & 0x0f;
73 		else COLOR(1,i) = 0;
74 		color_prom++;
75 	}
76 	for (i = 0;i < TOTAL_COLORS(0);i++)
77 	{
78 		COLOR(0,i) = (*(color_prom++) & 0x0f) + 0x10;
79 	}
80 }
81 
82 
83 
84 /***************************************************************************
85 
86   Callbacks for the TileMap code
87 
88 ***************************************************************************/
89 
get_tile_info(int tile_index)90 static void get_tile_info(int tile_index)
91 {
92 	unsigned char attr = gberet_colorram[tile_index];
93 	SET_TILE_INFO(0,gberet_videoram[tile_index] + ((attr & 0x40) << 2),attr & 0x0f)
94 	tile_info.flags = TILE_FLIPYX((attr & 0x30) >> 4) | TILE_SPLIT((attr & 0x80) >> 7);
95 }
96 
97 
98 
99 /***************************************************************************
100 
101   Start the video hardware emulation.
102 
103 ***************************************************************************/
104 
gberet_vh_start(void)105 int gberet_vh_start(void)
106 {
107 	bg_tilemap = tilemap_create(get_tile_info,tilemap_scan_rows,TILEMAP_SPLIT,8,8,64,32);
108 
109 	if (!bg_tilemap)
110 		return 0;
111 
112 	bg_tilemap->transmask[0] = 0x0001; /* split type 0 has pen 1 transparent in front half */
113 	bg_tilemap->transmask[1] = 0xffff; /* split type 1 is totally transparent in front half */
114 	tilemap_set_scroll_rows(bg_tilemap,32);
115 
116 	return 0;
117 }
118 
init_gberet(void)119 void init_gberet(void)
120 {
121 	sprites_type = 0;
122 }
123 
init_gberetb(void)124 void init_gberetb(void)
125 {
126 	sprites_type = 1;
127 }
128 
129 
130 
131 /***************************************************************************
132 
133   Memory handlers
134 
135 ***************************************************************************/
136 
WRITE_HANDLER(gberet_videoram_w)137 WRITE_HANDLER( gberet_videoram_w )
138 {
139 	if (gberet_videoram[offset] != data)
140 	{
141 		gberet_videoram[offset] = data;
142 		tilemap_mark_tile_dirty(bg_tilemap,offset);
143 	}
144 }
145 
WRITE_HANDLER(gberet_colorram_w)146 WRITE_HANDLER( gberet_colorram_w )
147 {
148 	if (gberet_colorram[offset] != data)
149 	{
150 		gberet_colorram[offset] = data;
151 		tilemap_mark_tile_dirty(bg_tilemap,offset);
152 	}
153 }
154 
WRITE_HANDLER(gberet_e044_w)155 WRITE_HANDLER( gberet_e044_w )
156 {
157 	/* bit 0 enables interrupts */
158 	interruptenable = data & 1;
159 
160 	/* bit 3 flips screen */
161 	flipscreen = data & 0x08;
162 	tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
163 
164 	/* don't know about the other bits */
165 }
166 
WRITE_HANDLER(gberet_scroll_w)167 WRITE_HANDLER( gberet_scroll_w )
168 {
169 	int scroll;
170 
171 	gberet_scrollram[offset] = data;
172 
173 	scroll = gberet_scrollram[offset & 0x1f] | (gberet_scrollram[offset | 0x20] << 8);
174 	tilemap_set_scrollx(bg_tilemap,offset & 0x1f,scroll);
175 }
176 
WRITE_HANDLER(gberetb_scroll_w)177 WRITE_HANDLER( gberetb_scroll_w )
178 {
179 	if (offset) data |= 0x100;
180 
181 	for (offset = 6;offset < 29;offset++)
182 		tilemap_set_scrollx(bg_tilemap,offset,data + 64-8);
183 }
184 
185 
gberet_interrupt(void)186 int gberet_interrupt(void)
187 {
188 	if (cpu_getiloops() == 0) return interrupt();
189 	else if (cpu_getiloops() % 2)
190 	{
191 		if (interruptenable) return nmi_interrupt();
192 	}
193 
194 	return ignore_interrupt();
195 }
196 
197 
198 
199 /***************************************************************************
200 
201   Display refresh
202 
203 ***************************************************************************/
204 
draw_sprites0(struct osd_bitmap * bitmap)205 static void draw_sprites0(struct osd_bitmap *bitmap)
206 {
207 	int offs;
208 	unsigned char *sr;
209 
210 	if (*gberet_spritebank & 0x08)
211 		sr = spriteram_2;
212 	else sr = spriteram;
213 
214 	for (offs = 0;offs < spriteram_size;offs += 4)
215 	{
216 		if (sr[offs+3])
217 		{
218 			int sx,sy,flipx,flipy;
219 
220 
221 			sx = sr[offs+2] - 2*(sr[offs+1] & 0x80);
222 			sy = sr[offs+3];
223 			if (sprites_type) sy = 240 - sy;
224 			flipx = sr[offs+1] & 0x10;
225 			flipy = sr[offs+1] & 0x20;
226 
227 			if (flipscreen)
228 			{
229 				sx = 240 - sx;
230 				sy = 240 - sy;
231 				flipx = !flipx;
232 				flipy = !flipy;
233 			}
234 
235 			drawgfx(bitmap,Machine->gfx[1],
236 					sr[offs+0] + ((sr[offs+1] & 0x40) << 2),
237 					sr[offs+1] & 0x0f,
238 					flipx,flipy,
239 					sx,sy,
240 					&Machine->visible_area,TRANSPARENCY_COLOR,0);
241 		}
242 	}
243 }
244 
draw_sprites1(struct osd_bitmap * bitmap)245 static void draw_sprites1(struct osd_bitmap *bitmap)
246 {
247 	int offs;
248 	unsigned char *sr;
249 
250 	sr = spriteram;
251 
252 	for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
253 	{
254 		if (sr[offs+1])
255 		{
256 			int sx,sy,flipx,flipy;
257 
258 
259 			sx = sr[offs+2] - 2*(sr[offs+3] & 0x80);
260 			sy = sr[offs+1];
261 			if (sprites_type) sy = 240 - sy;
262 			flipx = sr[offs+3] & 0x10;
263 			flipy = sr[offs+3] & 0x20;
264 
265 			if (flipscreen)
266 			{
267 				sx = 240 - sx;
268 				sy = 240 - sy;
269 				flipx = !flipx;
270 				flipy = !flipy;
271 			}
272 
273 			drawgfx(bitmap,Machine->gfx[1],
274 					sr[offs+0] + ((sr[offs+3] & 0x40) << 2),
275 					sr[offs+3] & 0x0f,
276 					flipx,flipy,
277 					sx,sy,
278 					&Machine->visible_area,TRANSPARENCY_COLOR,0);
279 		}
280 	}
281 }
282 
283 
gberet_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)284 void gberet_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
285 {
286 	tilemap_update(ALL_TILEMAPS);
287 
288 	tilemap_render(ALL_TILEMAPS);
289 
290 	tilemap_draw(bitmap,bg_tilemap,TILEMAP_BACK);
291 	if (sprites_type == 0) draw_sprites0(bitmap);	/* original */
292 	else draw_sprites1(bitmap);	/* bootleg */
293 	tilemap_draw(bitmap,bg_tilemap,TILEMAP_FRONT);
294 }
295