1 /***************************************************************************
2
3 First version of the Dynax blitter.
4
5 Can handle up to 8 256x256 bitmaps; in the games supported, every pair of
6 bitmaps is interleaved horizontally to form 4 higher res 512x256 layer.
7
8 The blitter reads compressed data from ROM and copies it to the bitmap RAM.
9
10 ***************************************************************************/
11
12 #include "driver.h"
13
14
15 static UINT8 *pixmap[8];
16 static int palbank;
17 static int total_pixmaps;
18
19
common_vh_start(int num_pixmaps)20 static int common_vh_start(int num_pixmaps)
21 {
22 int i;
23
24 total_pixmaps = num_pixmaps;
25
26 for (i = 0;i < 8;i++)
27 {
28 if (i < total_pixmaps)
29 {
30 if (!(pixmap[i] = auto_malloc(256*256))) return 1;
31 }
32 else
33 pixmap[i] = NULL;
34 }
35
36 return 0;
37 }
38
VIDEO_START(hnayayoi)39 VIDEO_START( hnayayoi )
40 {
41 return common_vh_start(4); /* 4 bitmaps -> 2 layers */
42 }
43
VIDEO_START(untoucha)44 VIDEO_START( untoucha )
45 {
46 return common_vh_start(8); /* 8 bitmaps -> 4 layers */
47 }
48
49
50
51 /***************************************************************************
52
53 Blitter support
54
55 three parameters:
56 blit_layer: mask of the bitmaps to write to (can write to multiple bitmaps
57 at the same time)
58 blit_dest: position in the destination bitmap where to start blitting
59 blit_src: address of source data in the gfx ROM
60
61 additional parameters specify the palette base, but this is handled while rendering
62 the screen, not during blitting (games change the palette base without redrawing
63 the screen).
64
65 It is not known whether the palette base control registers are part of the blitter
66 hardware or latched somewhere else. Since they are mapped in memory immediately
67 before the bitter parameters, they probably are part of the blitter, but I'm
68 handling them separately anyway.
69
70
71 The format of the blitter data stored in ROM is very simple:
72
73 7654 ---- Pen to draw with
74 ---- 3210 Command
75
76 Commands:
77
78 0 Stop
79 1-b Draw 1-b pixels along X.
80 c Followed by 1 byte (N): draw N pixels along X.
81 d Followed by 2 bytes (X,N): move on the line to pixel (start+X), draw N pixels
82 along X.
83 e Followed by 1 byte (N): set blit_layer = N. Used to draw interleaved graphics
84 with a single blitter run.
85 f Move to next line.
86
87 At the end of the blit, blit_src is left pointing to the next data in the gfx ROM.
88 This is used to draw interleaved graphics with two blitter runs without having to set
89 up blit_src for the second call.
90
91 ***************************************************************************/
92
93 static UINT8 blit_layer;
94 static UINT16 blit_dest;
95 static UINT32 blit_src;
96
WRITE_HANDLER(dynax_blitter_rev1_param_w)97 WRITE_HANDLER( dynax_blitter_rev1_param_w )
98 {
99 switch (offset)
100 {
101 case 0: blit_dest = (blit_dest & 0xff00) | (data << 0); break;
102 case 1: blit_dest = (blit_dest & 0x00ff) | (data << 8); break;
103 case 2: blit_layer = data; break;
104 case 3: blit_src = (blit_src & 0xffff00) | (data << 0); break;
105 case 4: blit_src = (blit_src & 0xff00ff) | (data << 8); break;
106 case 5: blit_src = (blit_src & 0x00ffff) | (data <<16); break;
107 }
108 }
109
copy_pixel(int x,int y,int pen)110 static void copy_pixel(int x,int y,int pen)
111 {
112 if (x >= 0 && x <= 255 && y >= 0 && y <= 255)
113 {
114 int i;
115
116 for (i = 0;i < 8;i++)
117 {
118 if ((~blit_layer & (1 << i)) && (pixmap[i]))
119 pixmap[i][256*y+x] = pen;
120 }
121 }
122 }
123
WRITE_HANDLER(dynax_blitter_rev1_start_w)124 WRITE_HANDLER( dynax_blitter_rev1_start_w )
125 {
126 data8_t *rom = memory_region(REGION_GFX1);
127 int romlen = memory_region_length(REGION_GFX1);
128 int sx = blit_dest & 0xff;
129 int sy = blit_dest >> 8;
130 int x,y;
131
132 x = sx;
133 y = sy;
134 while (blit_src < romlen)
135 {
136 int cmd = rom[blit_src] & 0x0f;
137 int pen = rom[blit_src] >> 4;
138
139 blit_src++;
140
141 switch (cmd)
142 {
143 case 0xf:
144 y++;
145 x = sx;
146 break;
147
148 case 0xe:
149 if (blit_src >= romlen)
150 {
151 usrintf_showmessage("GFXROM OVER %06x",blit_src);
152 return;
153 }
154 x = sx;
155 blit_layer = rom[blit_src++];
156 break;
157
158 case 0xd:
159 if (blit_src >= romlen)
160 {
161 usrintf_showmessage("GFXROM OVER %06x",blit_src);
162 return;
163 }
164 x = sx + rom[blit_src++];
165 /* fall through into next case */
166
167 case 0xc:
168 if (blit_src >= romlen)
169 {
170 usrintf_showmessage("GFXROM OVER %06x",blit_src);
171 return;
172 }
173 cmd = rom[blit_src++];
174 /* fall through into next case */
175
176 case 0xb:
177 case 0xa:
178 case 0x9:
179 case 0x8:
180 case 0x7:
181 case 0x6:
182 case 0x5:
183 case 0x4:
184 case 0x3:
185 case 0x2:
186 case 0x1:
187 while (cmd--)
188 copy_pixel(x++,y,pen);
189 break;
190
191 case 0x0:
192 return;
193 }
194 }
195
196 usrintf_showmessage("GFXROM OVER %06x",blit_src);
197 }
198
WRITE_HANDLER(dynax_blitter_rev1_clear_w)199 WRITE_HANDLER( dynax_blitter_rev1_clear_w )
200 {
201 int pen = data >> 4;
202 int i;
203
204 for (i = 0;i < 8;i++)
205 {
206 if ((~blit_layer & (1 << i)) && (pixmap[i]))
207 memset(pixmap[i] + blit_dest, pen, 0x10000 - blit_dest);
208 }
209 }
210
211
WRITE_HANDLER(hnayayoi_palbank_w)212 WRITE_HANDLER( hnayayoi_palbank_w )
213 {
214 offset *= 8;
215 palbank = (palbank & (0xff00 >> offset)) | (data << offset);
216 }
217
218
draw_layer_interleaved(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int left_pixmap,int right_pixmap,int palbase,int transp)219 static void draw_layer_interleaved(struct mame_bitmap *bitmap, const struct rectangle *cliprect,
220 int left_pixmap, int right_pixmap, int palbase, int transp)
221 {
222 int county,countx,pen,offs;
223 UINT8 *src1 = pixmap[left_pixmap];
224 UINT8 *src2 = pixmap[right_pixmap];
225 UINT16 *dstbase = (UINT16 *)bitmap->base;
226
227 palbase *= 16;
228 offs = 0;
229
230 for (county = 255; county >= 0; county--, dstbase += bitmap->rowpixels)
231 {
232 UINT16 *dst = dstbase;
233
234 if (transp)
235 {
236 for (countx = 255; countx >= 0; countx--, dst += 2)
237 {
238 pen = *(src1++);
239 if (pen) *dst = palbase + pen;
240 pen = *(src2++);
241 if (pen) *(dst+1) = palbase + pen;
242 }
243 }
244 else
245 {
246 for (countx = 255; countx >= 0; countx--, dst += 2)
247 {
248 *dst = palbase + *(src1++);
249 *(dst+1) = palbase + *(src2++);
250 }
251 }
252 }
253 }
254
255
VIDEO_UPDATE(hnayayoi)256 VIDEO_UPDATE( hnayayoi )
257 {
258 int col0 = (palbank >> 0) & 0x0f;
259 int col1 = (palbank >> 4) & 0x0f;
260 int col2 = (palbank >> 8) & 0x0f;
261 int col3 = (palbank >> 12) & 0x0f;
262
263 if (total_pixmaps == 4)
264 {
265 draw_layer_interleaved(bitmap,cliprect,3,2,col1,0);
266 draw_layer_interleaved(bitmap,cliprect,1,0,col0,1);
267 }
268 else /* total_pixmaps == 8 */
269 {
270 draw_layer_interleaved(bitmap,cliprect,7,6,col3,0);
271 draw_layer_interleaved(bitmap,cliprect,5,4,col2,1);
272 draw_layer_interleaved(bitmap,cliprect,3,2,col1,1);
273 draw_layer_interleaved(bitmap,cliprect,1,0,col0,1);
274 }
275 }
276