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 /* from sndhrdw/pleiads.c */
14 WRITE_HANDLER( pleiads_sound_control_c_w );
15
16 unsigned char *naughtyb_videoram2;
17
18 int videoreg;
19
20 /* use these to draw charset B */
21 unsigned char *naughtyb_scrollreg;
22
23 /* use this to select palette */
24 static unsigned char palreg;
25
26 /* used in Naughty Boy to select video bank */
27 static int bankreg;
28
29
30 static struct rectangle scrollvisiblearea =
31 {
32 2*8, 34*8-1,
33 0*8, 28*8-1
34 };
35
36 static struct rectangle leftvisiblearea =
37 {
38 0*8, 2*8-1,
39 0*8, 28*8-1
40 };
41
42 static struct rectangle rightvisiblearea =
43 {
44 34*8, 36*8-1,
45 0*8, 28*8-1
46 };
47
48
49
50 /***************************************************************************
51
52 Convert the color PROMs into a more useable format.
53
54 Naughty Boy has two 256x4 palette PROMs, one containing the high bits and
55 the other the low bits (2x2x2 color space).
56 The palette PROMs are connected to the RGB output this way:
57
58 bit 3 --
59 -- 270 ohm resistor -- GREEN
60 -- 270 ohm resistor -- BLUE
61 bit 0 -- 270 ohm resistor -- RED
62
63 bit 3 --
64 -- GREEN
65 -- BLUE
66 bit 0 -- RED
67
68 plus 270 ohm pullup and pulldown resistors on all lines
69
70 ***************************************************************************/
naughtyb_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)71 void naughtyb_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
72 {
73 int i;
74 #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
75 #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
76
77
78 for (i = 0;i < Machine->drv->total_colors;i++)
79 {
80 int bit0,bit1;
81
82
83 bit0 = (color_prom[0] >> 0) & 0x01;
84 bit1 = (color_prom[Machine->drv->total_colors] >> 0) & 0x01;
85 *(palette++) = 0x55 * bit0 + 0xaa * bit1;
86 bit0 = (color_prom[0] >> 2) & 0x01;
87 bit1 = (color_prom[Machine->drv->total_colors] >> 2) & 0x01;
88 *(palette++) = 0x55 * bit0 + 0xaa * bit1;
89 bit0 = (color_prom[0] >> 1) & 0x01;
90 bit1 = (color_prom[Machine->drv->total_colors] >> 1) & 0x01;
91 *(palette++) = 0x55 * bit0 + 0xaa * bit1;
92
93 color_prom++;
94 }
95
96 /* first bank of characters use colors 0-31, 64-95, 128-159 and 192-223 */
97 for (i = 0;i < 8;i++)
98 {
99 int j;
100
101
102 for (j = 0;j < 4;j++)
103 {
104 COLOR(0,4*i + j*4*8) = i + j*64;
105 COLOR(0,4*i + j*4*8 + 1) = 8 + i + j*64;
106 COLOR(0,4*i + j*4*8 + 2) = 2*8 + i + j*64;
107 COLOR(0,4*i + j*4*8 + 3) = 3*8 + i + j*64;
108 }
109 }
110
111 /* second bank of characters use colors 32-63, 96-127, 160-191 and 224-255 */
112 for (i = 0;i < 8;i++)
113 {
114 int j;
115
116
117 for (j = 0;j < 4;j++)
118 {
119 COLOR(1,4*i + j*4*8) = i + 32 + j*64;
120 COLOR(1,4*i + j*4*8 + 1) = 8 + i + 32 + j*64;
121 COLOR(1,4*i + j*4*8 + 2) = 2*8 + i + 32 + j*64;
122 COLOR(1,4*i + j*4*8 + 3) = 3*8 + i + 32 + j*64;
123 }
124 }
125 }
126
127
128
129 /***************************************************************************
130
131 Start the video hardware emulation.
132
133 ***************************************************************************/
naughtyb_vh_start(void)134 int naughtyb_vh_start(void)
135 {
136 videoreg = palreg = bankreg = 0;
137
138 /* Naughty Boy has a virtual screen twice as large as the visible screen */
139 if ((dirtybuffer = (unsigned char*)malloc(videoram_size)) == 0)
140 return 1;
141 memset(dirtybuffer, 1, videoram_size);
142
143 if ((tmpbitmap = bitmap_alloc(68*8,28*8)) == 0)
144 {
145 free(dirtybuffer);
146 return 1;
147 }
148
149 return 0;
150 }
151
152
153
154 /***************************************************************************
155
156 Stop the video hardware emulation.
157
158 ***************************************************************************/
naughtyb_vh_stop(void)159 void naughtyb_vh_stop(void)
160 {
161 bitmap_free(tmpbitmap);
162 free(dirtybuffer);
163 }
164
165
166
WRITE_HANDLER(naughtyb_videoram2_w)167 WRITE_HANDLER( naughtyb_videoram2_w )
168 {
169 if (naughtyb_videoram2[offset] != data)
170 {
171 dirtybuffer[offset] = 1;
172
173 naughtyb_videoram2[offset] = data;
174 }
175 }
176
177
178
WRITE_HANDLER(naughtyb_videoreg_w)179 WRITE_HANDLER( naughtyb_videoreg_w )
180 {
181 /* bits 4+5 control the sound circuit */
182 pleiads_sound_control_c_w(offset,data);
183
184 if ((videoreg & 0x0f) != (data & 0x0f))
185 {
186 videoreg = data;
187
188 palreg = (data >> 1) & 0x03; /* pallette sel is bit 1 & 2 */
189 bankreg = (data >> 2) & 0x01; /* banksel is just bit 2 */
190
191 memset (dirtybuffer, 1, videoram_size);
192 }
193 }
194
WRITE_HANDLER(popflame_videoreg_w)195 WRITE_HANDLER( popflame_videoreg_w )
196 {
197 /* bits 4+5 control the sound circuit */
198 pleiads_sound_control_c_w(offset,data);
199
200 if ((videoreg & 0x0f) != (data & 0x0f))
201 {
202 videoreg = data;
203
204 palreg = (data >> 1) & 0x03; /* pallette sel is bit 1 & 2 */
205 bankreg = (data >> 3) & 0x01; /* banksel is just bit 3 */
206
207 memset (dirtybuffer, 1, videoram_size);
208 }
209 }
210
211
212
213 /***************************************************************************
214
215 Draw the game screen in the given osd_bitmap.
216 Do NOT call osd_update_display() from this function, it will be called by
217 the main emulation engine.
218
219 The Naughty Boy screen is split into two sections by the hardware
220
221 NonScrolled = 28x4 - (rows 0,1,34,35, as shown below)
222 this area is split between the top and bottom of the screen,
223 and the address mapping is really funky.
224
225 Scrolled = 28x64, with a 28x32 viewport, as shown below
226 Each column in the virtual screen is 64 (40h) characters high.
227 Thus, column 27 is stored in VRAm at address 0-3fh,
228 column 26 is stored at 40-7f, and so on.
229 This illustration shows the horizonal scroll register set to zero,
230 so the topmost 32 rows of the virtual screen are shown.
231
232 The following screen-to-memory mapping. This is shown from player's viewpoint,
233 which with the CRT rotated 90 degrees CCW. This example shows the horizonal
234 scroll register set to zero.
235
236
237 COLUMN
238 0 1 2 - 25 26 27
239 -------------------------------
240 0| 76E 76A 762 - 70A 706 702 |
241 | | Nonscrolled display
242 1| 76F 76B 762 - 70B 707 703 |
243 |-------------------------------| -----
244 2| 6C0 680 640 - 80 40 00 |
245 | |
246 R 3| 6C1 681 641 - 81 41 01 |
247 O | | 28 x 32 viewport
248 W || | | | into 28x64 virtual,
249 | | scrollable screen
250 32| 6DE 69E 65E 9E 5E 1E |
251 | |
252 33| 6DF 69F 65F - 9F 5F 1F |
253 |-------------------------------| -----
254 34| 76C 768 764 708 704 700 |
255 | | Nonscrolled display
256 35| 76D 769 765 709 705 701 |
257 -------------------------------
258
259
260 ***************************************************************************/
naughtyb_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)261 void naughtyb_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
262 {
263 int offs;
264
265
266 /* for every character in the Video RAM, check if it has been modified */
267 /* since last time and update it accordingly. */
268 for (offs = videoram_size - 1;offs >= 0;offs--)
269 {
270 if (dirtybuffer[offs])
271 {
272 int sx,sy;
273
274
275 dirtybuffer[offs] = 0;
276
277 if (offs < 0x700)
278 {
279 sx = offs % 64;
280 sy = offs / 64;
281 }
282 else
283 {
284 sx = 64 + (offs - 0x700) % 4;
285 sy = (offs - 0x700) / 4;
286 }
287
288 drawgfx(tmpbitmap,Machine->gfx[0],
289 naughtyb_videoram2[offs] + 256 * bankreg,
290 (naughtyb_videoram2[offs] >> 5) + 8 * palreg,
291 0,0,
292 8*sx,8*sy,
293 0,TRANSPARENCY_NONE,0);
294
295 drawgfx(tmpbitmap,Machine->gfx[1],
296 videoram[offs] + 256*bankreg,
297 (videoram[offs] >> 5) + 8 * palreg,
298 0,0,
299 8*sx,8*sy,
300 0,TRANSPARENCY_PEN,0);
301 }
302 }
303
304
305 /* copy the temporary bitmap to the screen */
306 {
307 int scrollx;
308
309
310 copybitmap(bitmap,tmpbitmap,0,0,-66*8,0,&leftvisiblearea,TRANSPARENCY_NONE,0);
311 copybitmap(bitmap,tmpbitmap,0,0,-30*8,0,&rightvisiblearea,TRANSPARENCY_NONE,0);
312
313 scrollx = -*naughtyb_scrollreg + 16;
314 copyscrollbitmap(bitmap,tmpbitmap,1,&scrollx,0,0,&scrollvisiblearea,TRANSPARENCY_NONE,0);
315 }
316 }
317