1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 /* */
4
5 #include "emu.h"
6 #include "k053936.h"
7
8 #define VERBOSE 0
9 #include "logmacro.h"
10
11
12 // Localized K053936/ROZ+
13 #define K053936_MAX_CHIPS 2
14
15 static rectangle K053936_cliprect[K053936_MAX_CHIPS];
16 static int K053936_offset[K053936_MAX_CHIPS][2] = {{0,0},{0,0}};
17 static int K053936_clip_enabled[K053936_MAX_CHIPS] = {0,0};
18 static int K053936_wraparound[K053936_MAX_CHIPS];
19
20
21
22
23 /***************************************************************************/
24 /* */
25 /* 053936 */
26 /* */
27 /***************************************************************************/
28
29 /*
30
31 053936
32 ------
33 Evolution of the 051316. The data bus is 16-bit instead of 8-bit.
34 When used in "simple" mode it can generate the same effects of the 051316, but it
35 doesn't have internal tilemap RAM, so it just generates a couple of X/Y coordinates
36 indicating the pixel to display at each moment. Therefore, the tilemap and tile
37 sizes are not fixed.
38 The important addition over the 051316 is 512x4 words of internal RAM used to control
39 rotation and zoom scanline by scanline instead that on the whole screen, allowing for
40 effects like linescroll (Super Slams) or 3D rotation of the tilemap (Golfing Greats,
41 Premier Soccer).
42
43 control registers
44 000 X counter starting value / 256
45 001 Y counter starting value / 256
46 002 ["simple" mode only] amount to add to the X counter after each line (0 = no rotation)
47 003 ["simple" mode only] amount to add to the Y counter after each line
48 004 ["simple" mode only] amount to add to the X counter after each horizontal pixel
49 005 ["simple" mode only] amount to add to the Y counter after each horizontal pixel (0 = no rotation)
50 006 x------- -------- when set, register (line*4)+2 must be multiplied by 256
51 -x------ -------- when set, registers 002 and 003 must be multiplied by 256
52 --xxxxxx -------- clipping for the generated address? usually 3F, Premier Soccer
53 sets it to 07 before penalty kicks
54 -------- x------- when set, register (line*4)+3 must be multiplied by 256
55 -------- -x------ when set, registers 004 and 005 must be multiplied by 256
56 -------- --xxxxxx clipping for the generated address? usually 3F, Premier Soccer
57 sets it to 0F before penalty kicks
58 007 -------- -x------ enable "super" mode
59 -------- --x----- unknown (enable address clipping from register 006?)
60 -------- ---x---- unknown
61 -------- ------x- (not sure) enable clipping with registers 008-00b
62 008 min x screen coordinate to draw to (only when enabled by register 7)
63 009 max x screen coordinate to draw to (only when enabled by register 7)
64 00a min y screen coordinate to draw to (only when enabled by register 7)
65 00b max y screen coordinate to draw to (only when enabled by register 7)
66 00c unknown
67 00d unknown
68 00e unknown
69 00f unknown
70
71 additional control from extra RAM:
72 (line*4)+0 X counter starting value / 256 (add to register 000)
73 (line*4)+1 Y counter starting value / 256 (add to register 001)
74 (line*4)+2 amount to add to the X counter after each horizontal pixel
75 (line*4)+3 amount to add to the Y counter after each horizontal pixel
76
77 */
78
79
80
81
K053936_zoom_draw(int chip,uint16_t * ctrl,uint16_t * linectrl,screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect,tilemap_t * tmap,int flags,uint32_t priority,int glfgreat_hack)82 static void K053936_zoom_draw(int chip,uint16_t *ctrl,uint16_t *linectrl, screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,tilemap_t *tmap,int flags,uint32_t priority, int glfgreat_hack)
83 {
84 if (!tmap)
85 return;
86
87 if (ctrl[0x07] & 0x0040)
88 {
89 uint32_t startx,starty;
90 int incxx,incxy;
91 rectangle my_clip;
92 int y,maxy;
93
94 // Racin' Force will get to here if glfgreat_hack is enabled, and it ends
95 // up setting a maximum y value of '13', thus causing nothing to be drawn.
96 // It looks like the roz output should be flipped somehow as it seems to be
97 // displaying the wrong areas of the tilemap and is rendered upside down,
98 // although due to the additional post-processing the voxel renderer performs
99 // it's difficult to know what the output SHOULD be. (hold W in Racin' Force
100 // to see the chip output)
101
102 if (((ctrl[0x07] & 0x0002) && ctrl[0x09]) && (glfgreat_hack)) /* wrong, but fixes glfgreat */
103 {
104 my_clip.min_x = ctrl[0x08] + K053936_offset[chip][0]+2;
105 my_clip.max_x = ctrl[0x09] + K053936_offset[chip][0]+2 - 1;
106 if (my_clip.min_x < cliprect.min_x)
107 my_clip.min_x = cliprect.min_x;
108 if (my_clip.max_x > cliprect.max_x)
109 my_clip.max_x = cliprect.max_x;
110
111 y = ctrl[0x0a] + K053936_offset[chip][1]-2;
112 if (y < cliprect.min_y)
113 y = cliprect.min_y;
114 maxy = ctrl[0x0b] + K053936_offset[chip][1]-2 - 1;
115 if (maxy > cliprect.max_y)
116 maxy = cliprect.max_y;
117
118 }
119 else
120 {
121 my_clip.min_x = cliprect.min_x;
122 my_clip.max_x = cliprect.max_x;
123
124 y = cliprect.min_y;
125 maxy = cliprect.max_y;
126 }
127
128 while (y <= maxy)
129 {
130 uint16_t *lineaddr = linectrl + 4*((y - K053936_offset[chip][1]) & 0x1ff);
131 my_clip.min_y = my_clip.max_y = y;
132
133 startx = 256 * (int16_t)(lineaddr[0] + ctrl[0x00]);
134 starty = 256 * (int16_t)(lineaddr[1] + ctrl[0x01]);
135 incxx = (int16_t)(lineaddr[2]);
136 incxy = (int16_t)(lineaddr[3]);
137
138 if (ctrl[0x06] & 0x8000) incxx *= 256;
139 if (ctrl[0x06] & 0x0080) incxy *= 256;
140
141 startx -= K053936_offset[chip][0] * incxx;
142 starty -= K053936_offset[chip][0] * incxy;
143
144 tmap->draw_roz(screen, bitmap, my_clip, startx << 5,starty << 5,
145 incxx << 5,incxy << 5,0,0,
146 K053936_wraparound[chip],
147 flags,priority);
148
149 y++;
150 }
151 }
152 else /* "simple" mode */
153 {
154 uint32_t startx,starty;
155 int incxx,incxy,incyx,incyy;
156
157 startx = 256 * (int16_t)(ctrl[0x00]);
158 starty = 256 * (int16_t)(ctrl[0x01]);
159 incyx = (int16_t)(ctrl[0x02]);
160 incyy = (int16_t)(ctrl[0x03]);
161 incxx = (int16_t)(ctrl[0x04]);
162 incxy = (int16_t)(ctrl[0x05]);
163
164 if (ctrl[0x06] & 0x4000) { incyx *= 256; incyy *= 256; }
165 if (ctrl[0x06] & 0x0040) { incxx *= 256; incxy *= 256; }
166
167 startx -= K053936_offset[chip][1] * incyx;
168 starty -= K053936_offset[chip][1] * incyy;
169
170 startx -= K053936_offset[chip][0] * incxx;
171 starty -= K053936_offset[chip][0] * incxy;
172
173 tmap->draw_roz(screen, bitmap, cliprect, startx << 5,starty << 5,
174 incxx << 5,incxy << 5,incyx << 5,incyy << 5,
175 K053936_wraparound[chip],
176 flags,priority);
177 }
178
179 #if 0
180 if (machine.input().code_pressed(KEYCODE_D))
181 popmessage("%04x %04x %04x %04x\n%04x %04x %04x %04x\n%04x %04x %04x %04x\n%04x %04x %04x %04x",
182 ctrl[0x00],
183 ctrl[0x01],
184 ctrl[0x02],
185 ctrl[0x03],
186 ctrl[0x04],
187 ctrl[0x05],
188 ctrl[0x06],
189 ctrl[0x07],
190 ctrl[0x08],
191 ctrl[0x09],
192 ctrl[0x0a],
193 ctrl[0x0b],
194 ctrl[0x0c],
195 ctrl[0x0d],
196 ctrl[0x0e],
197 ctrl[0x0f]);
198 #endif
199 }
200
201
K053936_0_zoom_draw(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect,tilemap_t * tmap,int flags,uint32_t priority,int glfgreat_hack)202 void K053936_0_zoom_draw(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,tilemap_t *tmap,int flags,uint32_t priority, int glfgreat_hack)
203 {
204 uint16_t *ctrl = reinterpret_cast<uint16_t *>(tmap->machine().root_device().memshare("k053936_0_ctrl")->ptr());
205 uint16_t *linectrl = reinterpret_cast<uint16_t *>(tmap->machine().root_device().memshare("k053936_0_line")->ptr());
206 K053936_zoom_draw(0,ctrl,linectrl,screen,bitmap,cliprect,tmap,flags,priority, glfgreat_hack);
207 }
208
K053936_wraparound_enable(int chip,int status)209 void K053936_wraparound_enable(int chip, int status)
210 {
211 K053936_wraparound[chip] = status;
212 }
213
214
K053936_set_offset(int chip,int xoffs,int yoffs)215 void K053936_set_offset(int chip, int xoffs, int yoffs)
216 {
217 K053936_offset[chip][0] = xoffs;
218 K053936_offset[chip][1] = yoffs;
219 }
220
221
222
223
224 /***************************************************************************/
225 /* */
226 /* 053936 */
227 /* */
228 /***************************************************************************/
229
230 DEFINE_DEVICE_TYPE(K053936, k053936_device, "k053936", "K053936 Video Controller")
231
k053936_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)232 k053936_device::k053936_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
233 : device_t(mconfig, K053936, tag, owner, clock),
234 m_ctrl(nullptr),
235 m_linectrl(nullptr),
236 m_wrap(0),
237 m_xoff(0),
238 m_yoff(0)
239 {
240 }
241
242 //-------------------------------------------------
243 // device_start - device-specific startup
244 //-------------------------------------------------
245
device_start()246 void k053936_device::device_start()
247 {
248 m_ctrl = make_unique_clear<uint16_t[]>(0x20);
249 m_linectrl = make_unique_clear<uint16_t[]>(0x4000);
250
251 save_pointer(NAME(m_ctrl), 0x20);
252 save_pointer(NAME(m_linectrl), 0x4000);
253 }
254
255 //-------------------------------------------------
256 // device_reset - device-specific reset
257 //-------------------------------------------------
258
device_reset()259 void k053936_device::device_reset()
260 {
261 memset(m_ctrl.get(), 0, 0x20);
262 }
263
264
265 /*****************************************************************************
266 DEVICE HANDLERS
267 *****************************************************************************/
268
ctrl_w(offs_t offset,uint16_t data,uint16_t mem_mask)269 void k053936_device::ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask)
270 {
271 COMBINE_DATA(&m_ctrl[offset]);
272 }
273
ctrl_r(offs_t offset)274 uint16_t k053936_device::ctrl_r(offs_t offset)
275 {
276 return m_ctrl[offset];
277 }
278
linectrl_w(offs_t offset,uint16_t data,uint16_t mem_mask)279 void k053936_device::linectrl_w(offs_t offset, uint16_t data, uint16_t mem_mask)
280 {
281 COMBINE_DATA(&m_linectrl[offset]);
282 }
283
linectrl_r(offs_t offset)284 uint16_t k053936_device::linectrl_r(offs_t offset)
285 {
286 return m_linectrl[offset];
287 }
288
289 // there is another implementation of this in video/konamigx.c (!)
290 // why? shall they be merged?
zoom_draw(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect,tilemap_t * tmap,int flags,uint32_t priority,int glfgreat_hack)291 void k053936_device::zoom_draw( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, tilemap_t *tmap, int flags, uint32_t priority, int glfgreat_hack )
292 {
293 if (!tmap)
294 return;
295
296 if (m_ctrl[0x07] & 0x0040)
297 {
298 uint32_t startx, starty;
299 int incxx, incxy;
300 rectangle my_clip;
301 int y, maxy;
302
303 // Racin' Force will get to here if glfgreat_hack is enabled, and it ends
304 // up setting a maximum y value of '13', thus causing nothing to be drawn.
305 // It looks like the roz output should be flipped somehow as it seems to be
306 // displaying the wrong areas of the tilemap and is rendered upside down,
307 // although due to the additional post-processing the voxel renderer performs
308 // it's difficult to know what the output SHOULD be. (hold W in Racin' Force
309 // to see the chip output)
310
311 if (((m_ctrl[0x07] & 0x0002) && m_ctrl[0x09]) && (glfgreat_hack)) /* wrong, but fixes glfgreat */
312 {
313 my_clip.min_x = m_ctrl[0x08] + m_xoff + 2;
314 my_clip.max_x = m_ctrl[0x09] + m_xoff + 2 - 1;
315 if (my_clip.min_x < cliprect.min_x)
316 my_clip.min_x = cliprect.min_x;
317 if (my_clip.max_x > cliprect.max_x)
318 my_clip.max_x = cliprect.max_x;
319
320 y = m_ctrl[0x0a] + m_yoff - 2;
321 if (y < cliprect.min_y)
322 y = cliprect.min_y;
323 maxy = m_ctrl[0x0b] + m_yoff - 2 - 1;
324 if (maxy > cliprect.max_y)
325 maxy = cliprect.max_y;
326 }
327 else
328 {
329 my_clip.min_x = cliprect.min_x;
330 my_clip.max_x = cliprect.max_x;
331
332 y = cliprect.min_y;
333 maxy = cliprect.max_y;
334 }
335
336 while (y <= maxy)
337 {
338 uint16_t *lineaddr = m_linectrl.get() + 4 * ((y - m_yoff) & 0x1ff);
339
340 my_clip.min_y = my_clip.max_y = y;
341
342 startx = 256 * (int16_t)(lineaddr[0] + m_ctrl[0x00]);
343 starty = 256 * (int16_t)(lineaddr[1] + m_ctrl[0x01]);
344 incxx = (int16_t)(lineaddr[2]);
345 incxy = (int16_t)(lineaddr[3]);
346
347 if (m_ctrl[0x06] & 0x8000)
348 incxx *= 256;
349
350 if (m_ctrl[0x06] & 0x0080)
351 incxy *= 256;
352
353 startx -= m_xoff * incxx;
354 starty -= m_xoff * incxy;
355
356 tmap->draw_roz(screen, bitmap, my_clip, startx << 5,starty << 5,
357 incxx << 5,incxy << 5,0,0,
358 m_wrap,
359 flags,priority);
360
361 y++;
362 }
363 }
364 else /* "simple" mode */
365 {
366 uint32_t startx, starty;
367 int incxx, incxy, incyx, incyy;
368
369 startx = 256 * (int16_t)(m_ctrl[0x00]);
370 starty = 256 * (int16_t)(m_ctrl[0x01]);
371 incyx = (int16_t)(m_ctrl[0x02]);
372 incyy = (int16_t)(m_ctrl[0x03]);
373 incxx = (int16_t)(m_ctrl[0x04]);
374 incxy = (int16_t)(m_ctrl[0x05]);
375
376 if (m_ctrl[0x06] & 0x4000)
377 {
378 incyx *= 256;
379 incyy *= 256;
380 }
381
382 if (m_ctrl[0x06] & 0x0040)
383 {
384 incxx *= 256;
385 incxy *= 256;
386 }
387
388 startx -= m_yoff * incyx;
389 starty -= m_yoff * incyy;
390
391 startx -= m_xoff * incxx;
392 starty -= m_xoff * incxy;
393
394 tmap->draw_roz(screen, bitmap, cliprect, startx << 5,starty << 5,
395 incxx << 5,incxy << 5,incyx << 5,incyy << 5,
396 m_wrap,
397 flags,priority);
398 }
399
400 #if 0
401 if (machine.input().code_pressed(KEYCODE_D))
402 popmessage("%04x %04x %04x %04x\n%04x %04x %04x %04x\n%04x %04x %04x %04x\n%04x %04x %04x %04x",
403 m_ctrl[0x00],
404 m_ctrl[0x01],
405 m_ctrl[0x02],
406 m_ctrl[0x03],
407 m_ctrl[0x04],
408 m_ctrl[0x05],
409 m_ctrl[0x06],
410 m_ctrl[0x07],
411 m_ctrl[0x08],
412 m_ctrl[0x09],
413 m_ctrl[0x0a],
414 m_ctrl[0x0b],
415 m_ctrl[0x0c],
416 m_ctrl[0x0d],
417 m_ctrl[0x0e],
418 m_ctrl[0x0f]);
419 #endif
420 }
421
zoom_draw(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect,tilemap_t * tmap,int flags,uint32_t priority,int glfgreat_hack)422 void k053936_device::zoom_draw( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *tmap, int flags, uint32_t priority, int glfgreat_hack )
423 {
424 if (!tmap)
425 return;
426
427 if (m_ctrl[0x07] & 0x0040)
428 {
429 uint32_t startx, starty;
430 int incxx, incxy;
431 rectangle my_clip;
432 int y, maxy;
433
434 // Racin' Force will get to here if glfgreat_hack is enabled, and it ends
435 // up setting a maximum y value of '13', thus causing nothing to be drawn.
436 // It looks like the roz output should be flipped somehow as it seems to be
437 // displaying the wrong areas of the tilemap and is rendered upside down,
438 // although due to the additional post-processing the voxel renderer performs
439 // it's difficult to know what the output SHOULD be. (hold W in Racin' Force
440 // to see the chip output)
441
442 if (((m_ctrl[0x07] & 0x0002) && m_ctrl[0x09]) && (glfgreat_hack)) /* wrong, but fixes glfgreat */
443 {
444 my_clip.min_x = m_ctrl[0x08] + m_xoff + 2;
445 my_clip.max_x = m_ctrl[0x09] + m_xoff + 2 - 1;
446 if (my_clip.min_x < cliprect.min_x)
447 my_clip.min_x = cliprect.min_x;
448 if (my_clip.max_x > cliprect.max_x)
449 my_clip.max_x = cliprect.max_x;
450
451 y = m_ctrl[0x0a] + m_yoff - 2;
452 if (y < cliprect.min_y)
453 y = cliprect.min_y;
454 maxy = m_ctrl[0x0b] + m_yoff - 2 - 1;
455 if (maxy > cliprect.max_y)
456 maxy = cliprect.max_y;
457 }
458 else
459 {
460 my_clip.min_x = cliprect.min_x;
461 my_clip.max_x = cliprect.max_x;
462
463 y = cliprect.min_y;
464 maxy = cliprect.max_y;
465 }
466
467 while (y <= maxy)
468 {
469 uint16_t *lineaddr = m_linectrl.get() + 4 * ((y - m_yoff) & 0x1ff);
470
471 my_clip.min_y = my_clip.max_y = y;
472
473 startx = 256 * (int16_t)(lineaddr[0] + m_ctrl[0x00]);
474 starty = 256 * (int16_t)(lineaddr[1] + m_ctrl[0x01]);
475 incxx = (int16_t)(lineaddr[2]);
476 incxy = (int16_t)(lineaddr[3]);
477
478 if (m_ctrl[0x06] & 0x8000)
479 incxx *= 256;
480
481 if (m_ctrl[0x06] & 0x0080)
482 incxy *= 256;
483
484 startx -= m_xoff * incxx;
485 starty -= m_xoff * incxy;
486
487 tmap->draw_roz(screen, bitmap, my_clip, startx << 5,starty << 5,
488 incxx << 5,incxy << 5,0,0,
489 m_wrap,
490 flags,priority);
491
492 y++;
493 }
494 }
495 else /* "simple" mode */
496 {
497 uint32_t startx, starty;
498 int incxx, incxy, incyx, incyy;
499
500 startx = 256 * (int16_t)(m_ctrl[0x00]);
501 starty = 256 * (int16_t)(m_ctrl[0x01]);
502 incyx = (int16_t)(m_ctrl[0x02]);
503 incyy = (int16_t)(m_ctrl[0x03]);
504 incxx = (int16_t)(m_ctrl[0x04]);
505 incxy = (int16_t)(m_ctrl[0x05]);
506
507 if (m_ctrl[0x06] & 0x4000)
508 {
509 incyx *= 256;
510 incyy *= 256;
511 }
512
513 if (m_ctrl[0x06] & 0x0040)
514 {
515 incxx *= 256;
516 incxy *= 256;
517 }
518
519 startx -= m_yoff * incyx;
520 starty -= m_yoff * incyy;
521
522 startx -= m_xoff * incxx;
523 starty -= m_xoff * incxy;
524
525 tmap->draw_roz(screen, bitmap, cliprect, startx << 5,starty << 5,
526 incxx << 5,incxy << 5,incyx << 5,incyy << 5,
527 m_wrap,
528 flags,priority);
529 }
530 }
531
532
533
534
K053936GP_set_offset(int chip,int xoffs,int yoffs)535 void K053936GP_set_offset(int chip, int xoffs, int yoffs) { K053936_offset[chip][0] = xoffs; K053936_offset[chip][1] = yoffs; }
536
K053936GP_clip_enable(int chip,int status)537 void K053936GP_clip_enable(int chip, int status) { K053936_clip_enabled[chip] = status; }
538
K053936GP_set_cliprect(int chip,int minx,int maxx,int miny,int maxy)539 void K053936GP_set_cliprect(int chip, int minx, int maxx, int miny, int maxy)
540 {
541 rectangle &cliprect = K053936_cliprect[chip];
542 cliprect.set(minx, maxx, miny, maxy);
543 }
544
K053936GP_copyroz32clip(running_machine & machine,bitmap_rgb32 & dst_bitmap,bitmap_ind16 & src_bitmap,const rectangle & dst_cliprect,const rectangle & src_cliprect,uint32_t _startx,uint32_t _starty,int _incxx,int _incxy,int _incyx,int _incyy,int tilebpp,int blend,int alpha,int clip,int pixeldouble_output,palette_device & palette)545 static inline void K053936GP_copyroz32clip( running_machine &machine,
546 bitmap_rgb32 &dst_bitmap, bitmap_ind16 &src_bitmap,
547 const rectangle &dst_cliprect, const rectangle &src_cliprect,
548 uint32_t _startx,uint32_t _starty,int _incxx,int _incxy,int _incyx,int _incyy,
549 int tilebpp, int blend, int alpha, int clip, int pixeldouble_output, palette_device &palette )
550 {
551 static const int colormask[8]={1,3,7,0xf,0x1f,0x3f,0x7f,0xff};
552 int cy, cx;
553 int ecx;
554 int src_pitch, incxy, incxx;
555 int src_minx, src_maxx, src_miny, src_maxy, cmask;
556 uint16_t *src_base;
557 size_t src_size;
558
559 const pen_t *pal_base;
560 int dst_ptr;
561 int dst_size;
562 int dst_base2;
563
564 int tx, dst_pitch;
565 uint32_t *dst_base;
566 int starty, incyy, startx, incyx, ty, sx, sy;
567
568 incxy = _incxy; incxx = _incxx; incyy = _incyy; incyx = _incyx;
569 starty = _starty; startx = _startx;
570
571 if (clip) // set source clip range to some extreme values when disabled
572 {
573 src_minx = src_cliprect.min_x;
574 src_maxx = src_cliprect.max_x;
575 src_miny = src_cliprect.min_y;
576 src_maxy = src_cliprect.max_y;
577 }
578 // this simply isn't safe to do!
579 else { src_minx = src_miny = -0x10000; src_maxx = src_maxy = 0x10000; }
580
581 // set target clip range
582 sx = dst_cliprect.min_x;
583 tx = dst_cliprect.max_x - sx + 1;
584 sy = dst_cliprect.min_y;
585 ty = dst_cliprect.max_y - sy + 1;
586
587 startx += sx * incxx + sy * incyx;
588 starty += sx * incxy + sy * incyy;
589
590 // adjust entry points and other loop constants
591 dst_pitch = dst_bitmap.rowpixels();
592 dst_base = &dst_bitmap.pix(0);
593 dst_base2 = sy * dst_pitch + sx + tx;
594 ecx = tx = -tx;
595
596 tilebpp = (tilebpp-1) & 7;
597 pal_base = palette.pens();
598 cmask = colormask[tilebpp];
599
600 src_pitch = src_bitmap.rowpixels();
601 src_base = &src_bitmap.pix(0);
602 src_size = src_bitmap.width() * src_bitmap.height();
603 dst_size = dst_bitmap.width() * dst_bitmap.height();
604 dst_ptr = 0;//dst_base;
605 cy = starty;
606 cx = startx;
607
608 if (blend > 0)
609 {
610 dst_ptr += dst_pitch; // draw blended
611 starty += incyy;
612 startx += incyx;
613
614 do {
615 do {
616 int srcx = (cx >> 16) & 0x1fff;
617 int srcy = (cy >> 16) & 0x1fff;
618 int pixel;
619 uint32_t offs;
620 offs = srcy * src_pitch + srcx;
621
622 cx += incxx;
623 cy += incxy;
624
625 if (offs>=src_size)
626 continue;
627
628 if (srcx < src_minx || srcx > src_maxx || srcy < src_miny || srcy > src_maxy)
629 continue;
630
631 pixel = src_base[offs];
632 if (!(pixel & cmask))
633 continue;
634
635 if ((dst_ptr+ecx+dst_base2)<dst_size) dst_base[dst_ptr+ecx+dst_base2] = alpha_blend_r32(pal_base[pixel], dst_base[dst_ptr+ecx+dst_base2], alpha);
636
637 if (pixeldouble_output)
638 {
639 ecx++;
640 if ((dst_ptr+ecx+dst_base2)<dst_size) dst_base[dst_ptr+ecx+dst_base2] = alpha_blend_r32(pal_base[pixel], dst_base[dst_ptr+ecx+dst_base2], alpha);
641 }
642 }
643 while (++ecx < 0);
644
645 ecx = tx;
646 dst_ptr += dst_pitch;
647 cy = starty; starty += incyy;
648 cx = startx; startx += incyx;
649 } while (--ty);
650 }
651 else // draw solid
652 {
653 dst_ptr += dst_pitch;
654 starty += incyy;
655 startx += incyx;
656
657 do {
658 do {
659 int srcx = (cx >> 16) & 0x1fff;
660 int srcy = (cy >> 16) & 0x1fff;
661 int pixel;
662 uint32_t offs;
663
664 offs = srcy * src_pitch + srcx;
665
666 cx += incxx;
667 cy += incxy;
668
669 if (offs>=src_size)
670 continue;
671
672 if (srcx < src_minx || srcx > src_maxx || srcy < src_miny || srcy > src_maxy)
673 continue;
674
675 pixel = src_base[offs];
676 if (!(pixel & cmask))
677 continue;
678
679
680
681 if ((dst_ptr+ecx+dst_base2)<dst_size) dst_base[dst_ptr+ecx+dst_base2] = pal_base[pixel];
682
683 if (pixeldouble_output)
684 {
685 ecx++;
686 if ((dst_ptr+ecx+dst_base2)<dst_size) dst_base[dst_ptr+ecx+dst_base2] = pal_base[pixel];
687 }
688 }
689 while (++ecx < 0);
690
691 ecx = tx;
692 dst_ptr += dst_pitch;
693 cy = starty; starty += incyy;
694 cx = startx; startx += incyx;
695 } while (--ty);
696 }
697 }
698
699 // adapted from generic K053936_zoom_draw()
K053936GP_zoom_draw(running_machine & machine,int chip,uint16_t * ctrl,uint16_t * linectrl,bitmap_rgb32 & bitmap,const rectangle & cliprect,tilemap_t * tmap,int tilebpp,int blend,int alpha,int pixeldouble_output,palette_device & palette)700 static void K053936GP_zoom_draw(running_machine &machine,
701 int chip, uint16_t *ctrl, uint16_t *linectrl,
702 bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *tmap,
703 int tilebpp, int blend, int alpha, int pixeldouble_output, palette_device &palette)
704 {
705 uint16_t *lineaddr;
706
707 rectangle my_clip;
708 uint32_t startx, starty;
709 int incxx, incxy, incyx, incyy, y, maxy, clip;
710
711 bitmap_ind16 &src_bitmap = tmap->pixmap();
712 rectangle &src_cliprect = K053936_cliprect[chip];
713 clip = K053936_clip_enabled[chip];
714
715 if (ctrl[0x07] & 0x0040) /* "super" mode */
716 {
717 my_clip.min_x = cliprect.min_x;
718 my_clip.max_x = cliprect.max_x;
719 y = cliprect.min_y;
720 maxy = cliprect.max_y;
721
722 while (y <= maxy)
723 {
724 lineaddr = linectrl + ( ((y - K053936_offset[chip][1]) & 0x1ff) << 2);
725 my_clip.min_y = my_clip.max_y = y;
726
727 startx = (int16_t)(lineaddr[0] + ctrl[0x00]) << 8;
728 starty = (int16_t)(lineaddr[1] + ctrl[0x01]) << 8;
729 incxx = (int16_t)(lineaddr[2]);
730 incxy = (int16_t)(lineaddr[3]);
731
732 if (ctrl[0x06] & 0x8000) incxx <<= 8;
733 if (ctrl[0x06] & 0x0080) incxy <<= 8;
734
735 startx -= K053936_offset[chip][0] * incxx;
736 starty -= K053936_offset[chip][0] * incxy;
737
738 K053936GP_copyroz32clip(machine,
739 bitmap, src_bitmap, my_clip, src_cliprect,
740 startx<<5, starty<<5, incxx<<5, incxy<<5, 0, 0,
741 tilebpp, blend, alpha, clip, pixeldouble_output, palette);
742 y++;
743 }
744 }
745 else /* "simple" mode */
746 {
747 startx = (int16_t)(ctrl[0x00]) << 8;
748 starty = (int16_t)(ctrl[0x01]) << 8;
749 incyx = (int16_t)(ctrl[0x02]);
750 incyy = (int16_t)(ctrl[0x03]);
751 incxx = (int16_t)(ctrl[0x04]);
752 incxy = (int16_t)(ctrl[0x05]);
753
754 if (ctrl[0x06] & 0x4000) { incyx <<= 8; incyy <<= 8; }
755 if (ctrl[0x06] & 0x0040) { incxx <<= 8; incxy <<= 8; }
756
757 startx -= K053936_offset[chip][1] * incyx;
758 starty -= K053936_offset[chip][1] * incyy;
759
760 startx -= K053936_offset[chip][0] * incxx;
761 starty -= K053936_offset[chip][0] * incxy;
762
763 K053936GP_copyroz32clip(machine,
764 bitmap, src_bitmap, cliprect, src_cliprect,
765 startx<<5, starty<<5, incxx<<5, incxy<<5, incyx<<5, incyy<<5,
766 tilebpp, blend, alpha, clip, pixeldouble_output, palette);
767 }
768 }
769
K053936GP_0_zoom_draw(running_machine & machine,bitmap_rgb32 & bitmap,const rectangle & cliprect,tilemap_t * tmap,int tilebpp,int blend,int alpha,int pixeldouble_output,uint16_t * temp_m_k053936_0_ctrl_16,uint16_t * temp_m_k053936_0_linectrl_16,uint16_t * temp_m_k053936_0_ctrl,uint16_t * temp_m_k053936_0_linectrl,palette_device & palette)770 void K053936GP_0_zoom_draw(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect,
771 tilemap_t *tmap, int tilebpp, int blend, int alpha, int pixeldouble_output, uint16_t* temp_m_k053936_0_ctrl_16, uint16_t* temp_m_k053936_0_linectrl_16,uint16_t* temp_m_k053936_0_ctrl, uint16_t* temp_m_k053936_0_linectrl, palette_device &palette)
772 {
773 if (temp_m_k053936_0_ctrl_16)
774 {
775 K053936GP_zoom_draw(machine, 0,temp_m_k053936_0_ctrl_16,temp_m_k053936_0_linectrl_16,bitmap,cliprect,tmap,tilebpp,blend,alpha, pixeldouble_output, palette);
776 }
777 else
778 {
779 K053936GP_zoom_draw(machine, 0,temp_m_k053936_0_ctrl,temp_m_k053936_0_linectrl,bitmap,cliprect,tmap,tilebpp,blend,alpha, pixeldouble_output, palette);
780 }
781 }
782