1 // license:BSD-3-Clause
2 // copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont
3 /***************************************************************************
4
5 video/mac.c
6
7 Macintosh video hardware
8
9 Emulates the video hardware for compact Macintosh series (original
10 Macintosh (128k, 512k, 512ke), Macintosh Plus, Macintosh SE, Macintosh
11 Classic)
12
13 Also emulates on-board video for systems with the
14 RBV, V8, Eagle, Sonora, and DAFB chips.
15
16 ----------------------------------------------------------------------
17 Monitor sense codes
18
19 Apple assigns 3 pins for monitor IDs. These allow 8 possible codes:
20
21 000 - color 2-Page Display (21")
22 001 - monochrome Full Page display (15")
23 010 - color 512x384 (12")
24 011 - monochrome 2 Page display (21")
25 100 - NTSC
26 101 - color Full Page display (15")
27 110 - High-Resolution Color (13" 640x480) or use "type 6" extended codes
28 111 - No monitor connected or use "type 7" extended codes
29
30 For extended codes, you drive one of the 3 pins at a time and read the 2
31 undriven pins. See http://support.apple.com/kb/TA21618?viewlocale=en_US
32 for details.
33
34 Extended codes:
35
36 Sense 2 Low Sense 1 Low Sense 0 Low
37 1 & 0 2 & 0 2 & 1
38
39 Multiple Scan 14" 00 00 11
40 Multiple Scan 16" 00 10 11
41 Multiple Scan 21" 10 00 11
42 PAL Encoder 00 00 00
43 NTSC Encoder 01 01 00
44 VGA/Super VGA 01 01 11
45 RGB 16" 10 11 01
46 PAL Monitor 11 00 00
47 RGB 19" 11 10 10
48 Radius color TPD 11 00 01 (TPD = Two Page Display)
49 Radius mono TPD 11 01 00
50 Apple TPD 11 01 01
51 Apple color FPD 01 11 10 (FPD = Full Page Display)
52
53 ***************************************************************************/
54
55
56 #include "emu.h"
57 #include "sound/asc.h"
58 #include "includes/mac.h"
59 #include "machine/ram.h"
60 #include "render.h"
61
VIDEO_START_MEMBER(mac_state,mac)62 VIDEO_START_MEMBER(mac_state,mac)
63 {
64 }
65
66 #define MAC_MAIN_SCREEN_BUF_OFFSET 0x5900
67 #define MAC_ALT_SCREEN_BUF_OFFSET 0xD900
68
screen_update_mac(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)69 uint32_t mac_state::screen_update_mac(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
70 {
71 uint32_t const video_base = m_ram->size() - (m_screen_buffer ? MAC_MAIN_SCREEN_BUF_OFFSET : MAC_ALT_SCREEN_BUF_OFFSET);
72 uint16_t const *video_ram = (const uint16_t *) (m_ram->pointer() + video_base);
73
74 for (int y = 0; y < MAC_V_VIS; y++)
75 {
76 uint16_t *const line = &bitmap.pix(y);
77
78 for (int x = 0; x < MAC_H_VIS; x += 16)
79 {
80 uint16_t const word = *(video_ram++);
81 for (int b = 0; b < 16; b++)
82 {
83 line[x + b] = (word >> (15 - b)) & 0x0001;
84 }
85 }
86 }
87 return 0;
88 }
89
screen_update_macse30(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)90 uint32_t mac_state::screen_update_macse30(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
91 {
92 uint32_t const video_base = (m_screen_buffer ? 0x8000 : 0) + (MAC_H_VIS/8);
93 uint16_t const *const video_ram = (const uint16_t *) &m_vram[video_base/4];
94
95 for (int y = 0; y < MAC_V_VIS; y++)
96 {
97 uint16_t *const line = &bitmap.pix(y);
98
99 for (int x = 0; x < MAC_H_VIS; x += 16)
100 {
101 uint16_t const word = video_ram[((y * MAC_H_VIS)/16) + ((x/16)^1)];
102 for (int b = 0; b < 16; b++)
103 {
104 line[x + b] = (word >> (15 - b)) & 0x0001;
105 }
106 }
107 }
108 return 0;
109 }
110
111 // IIci/IIsi RAM-Based Video (RBV) and children: V8, Eagle, Spice, VASP, Sonora
112
VIDEO_START_MEMBER(mac_state,macrbv)113 VIDEO_START_MEMBER(mac_state,macrbv)
114 {
115 }
116
VIDEO_RESET_MEMBER(mac_state,maceagle)117 VIDEO_RESET_MEMBER(mac_state,maceagle)
118 {
119 m_rbv_montype = 32;
120 m_rbv_palette[0xfe] = 0xffffff;
121 m_rbv_palette[0xff] = 0;
122 }
123
VIDEO_RESET_MEMBER(mac_state,macrbv)124 VIDEO_RESET_MEMBER(mac_state,macrbv)
125 {
126 int htotal, vtotal;
127 double framerate;
128 int view;
129
130 memset(m_rbv_regs, 0, sizeof(m_rbv_regs));
131
132 m_rbv_count = 0;
133 m_rbv_clutoffs = 0;
134 m_rbv_immed10wr = 0;
135
136 m_rbv_regs[2] = 0x7f;
137 m_rbv_regs[3] = 0;
138
139 m_rbv_type = RBV_TYPE_RBV;
140
141 view = 0;
142
143 m_rbv_montype = m_montype.read_safe(2);
144 rectangle visarea;
145 switch (m_rbv_montype)
146 {
147 case 1: // 15" portrait display
148 visarea.set(0, 640-1, 0, 870-1);
149 htotal = 832;
150 vtotal = 918;
151 framerate = 75.0;
152 view = 1;
153 break;
154
155 case 2: // 12" RGB
156 visarea.set(0, 512-1, 0, 384-1);
157 htotal = 640;
158 vtotal = 407;
159 framerate = 60.15;
160 break;
161
162 case 6: // 13" RGB
163 default:
164 visarea.set(0, 640-1, 0, 480-1);
165 htotal = 800;
166 vtotal = 525;
167 framerate = 59.94;
168 break;
169 }
170
171 // logerror("RBV reset: monitor is %dx%d @ %f Hz\n", visarea.width(), visarea.height(), framerate);
172 m_screen->configure(htotal, vtotal, visarea, HZ_TO_ATTOSECONDS(framerate));
173 render_target *target = machine().render().first_target();
174 target->set_view(view);
175 }
176
VIDEO_RESET_MEMBER(mac_state,macsonora)177 VIDEO_RESET_MEMBER(mac_state,macsonora)
178 {
179 int htotal, vtotal;
180 double framerate;
181 int view = 0;
182
183 memset(m_rbv_regs, 0, sizeof(m_rbv_regs));
184
185 m_rbv_count = 0;
186 m_rbv_clutoffs = 0;
187 m_rbv_immed10wr = 0;
188
189 m_rbv_regs[2] = 0x7f;
190 m_rbv_regs[3] = 0;
191
192 m_rbv_type = RBV_TYPE_SONORA;
193
194 m_rbv_montype = m_montype.read_safe(2);
195 rectangle visarea;
196 switch (m_rbv_montype)
197 {
198 case 1: // 15" portrait display
199 visarea.set(0, 640-1, 0, 870-1);
200 htotal = 832;
201 vtotal = 918;
202 framerate = 75.0;
203 view = 1;
204 break;
205
206 case 2: // 12" RGB
207 visarea.set(0, 512-1, 0, 384-1);
208 htotal = 640;
209 vtotal = 407;
210 framerate = 60.15;
211 break;
212
213 case 6: // 13" RGB
214 default:
215 visarea.set(0, 640-1, 0, 480-1);
216 htotal = 800;
217 vtotal = 525;
218 framerate = 59.94;
219 break;
220 }
221
222 // logerror("Sonora reset: monitor is %dx%d @ %f Hz\n", visarea.width(), visarea.height(), framerate);
223 m_screen->configure(htotal, vtotal, visarea, HZ_TO_ATTOSECONDS(framerate));
224 render_target *target = machine().render().first_target();
225 target->set_view(view);
226 }
227
VIDEO_START_MEMBER(mac_state,macsonora)228 VIDEO_START_MEMBER(mac_state,macsonora)
229 {
230 memset(m_rbv_regs, 0, sizeof(m_rbv_regs));
231
232 m_rbv_count = 0;
233 m_rbv_clutoffs = 0;
234 m_rbv_immed10wr = 0;
235
236 m_rbv_regs[2] = 0x7f;
237 m_rbv_regs[3] = 0;
238 m_rbv_regs[4] = 0x6;
239 m_rbv_regs[5] = 0x3;
240
241 m_sonora_vctl[0] = 0x9f;
242 m_sonora_vctl[1] = 0;
243 m_sonora_vctl[2] = 0;
244
245 m_rbv_type = RBV_TYPE_SONORA;
246 }
247
VIDEO_START_MEMBER(mac_state,macv8)248 VIDEO_START_MEMBER(mac_state,macv8)
249 {
250 memset(m_rbv_regs, 0, sizeof(m_rbv_regs));
251
252 m_rbv_count = 0;
253 m_rbv_clutoffs = 0;
254 m_rbv_immed10wr = 0;
255
256 m_rbv_regs[0] = 0x4f;
257 m_rbv_regs[1] = 0x06;
258 m_rbv_regs[2] = 0x7f;
259
260 m_rbv_type = RBV_TYPE_V8;
261 }
262
screen_update_macrbv(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)263 uint32_t mac_state::screen_update_macrbv(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
264 {
265 uint8_t const *vram8 = (uint8_t *)m_ram->pointer();
266 int hres, vres;
267
268 switch (m_rbv_montype)
269 {
270 case 32: // classic II built-in display
271 hres = MAC_H_VIS;
272 vres = MAC_V_VIS;
273 vram8 += 0x1f9a80; // Classic II apparently doesn't use VRAM?
274 break;
275
276 case 1: // 15" portrait display
277 hres = 640;
278 vres = 870;
279 break;
280
281 case 2: // 12" RGB
282 hres = 512;
283 vres = 384;
284 break;
285
286 case 6: // 13" RGB
287 default:
288 hres = 640;
289 vres = 480;
290 break;
291 }
292
293 switch (m_rbv_regs[0x10] & 7)
294 {
295 case 0: // 1bpp
296 {
297 for (int y = 0; y < vres; y++)
298 {
299 uint32_t *scanline = &bitmap.pix(y);
300 for (int x = 0; x < hres; x+=8)
301 {
302 uint8_t const pixels = vram8[(y * (hres/8)) + ((x/8)^3)];
303
304 *scanline++ = m_rbv_palette[0xfe|(pixels>>7)];
305 *scanline++ = m_rbv_palette[0xfe|((pixels>>6)&1)];
306 *scanline++ = m_rbv_palette[0xfe|((pixels>>5)&1)];
307 *scanline++ = m_rbv_palette[0xfe|((pixels>>4)&1)];
308 *scanline++ = m_rbv_palette[0xfe|((pixels>>3)&1)];
309 *scanline++ = m_rbv_palette[0xfe|((pixels>>2)&1)];
310 *scanline++ = m_rbv_palette[0xfe|((pixels>>1)&1)];
311 *scanline++ = m_rbv_palette[0xfe|(pixels&1)];
312 }
313 }
314 }
315 break;
316
317 case 1: // 2bpp
318 {
319 for (int y = 0; y < vres; y++)
320 {
321 uint32_t *scanline = &bitmap.pix(y);
322 for (int x = 0; x < hres/4; x++)
323 {
324 uint8_t const pixels = vram8[(y * (hres/4)) + (BYTE4_XOR_BE(x))];
325
326 *scanline++ = m_rbv_palette[0xfc|((pixels>>6)&3)];
327 *scanline++ = m_rbv_palette[0xfc|((pixels>>4)&3)];
328 *scanline++ = m_rbv_palette[0xfc|((pixels>>2)&3)];
329 *scanline++ = m_rbv_palette[0xfc|(pixels&3)];
330 }
331 }
332 }
333 break;
334
335 case 2: // 4bpp
336 {
337 for (int y = 0; y < vres; y++)
338 {
339 uint32_t *scanline = &bitmap.pix(y);
340
341 for (int x = 0; x < hres/2; x++)
342 {
343 uint8_t const pixels = vram8[(y * (hres/2)) + (BYTE4_XOR_BE(x))];
344
345 *scanline++ = m_rbv_palette[0xf0|(pixels>>4)];
346 *scanline++ = m_rbv_palette[0xf0|(pixels&0xf)];
347 }
348 }
349 }
350 break;
351
352 case 3: // 8bpp
353 {
354 for (int y = 0; y < vres; y++)
355 {
356 uint32_t *scanline = &bitmap.pix(y);
357
358 for (int x = 0; x < hres; x++)
359 {
360 uint8_t const pixels = vram8[(y * hres) + (BYTE4_XOR_BE(x))];
361 *scanline++ = m_rbv_palette[pixels];
362 }
363 }
364 }
365 }
366
367 return 0;
368 }
369
screen_update_macrbvvram(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)370 uint32_t mac_state::screen_update_macrbvvram(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
371 {
372 int hres, vres;
373 switch (m_rbv_montype)
374 {
375 case 1: // 15" portrait display
376 hres = 640;
377 vres = 870;
378 break;
379
380 case 2: // 12" RGB
381 hres = 512;
382 vres = 384;
383 break;
384
385 case 6: // 13" RGB
386 default:
387 hres = 640;
388 vres = 480;
389 break;
390 }
391
392 switch (m_rbv_regs[0x10] & 7)
393 {
394 case 0: // 1bpp
395 {
396 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
397
398 for (int y = 0; y < vres; y++)
399 {
400 uint32_t *scanline = &bitmap.pix(y);
401 for (int x = 0; x < hres; x+=8)
402 {
403 uint8_t const pixels = vram8[(y * 0x400) + ((x/8)^3)];
404
405 *scanline++ = m_rbv_palette[0x7f|(pixels&0x80)];
406 *scanline++ = m_rbv_palette[0x7f|((pixels<<1)&0x80)];
407 *scanline++ = m_rbv_palette[0x7f|((pixels<<2)&0x80)];
408 *scanline++ = m_rbv_palette[0x7f|((pixels<<3)&0x80)];
409 *scanline++ = m_rbv_palette[0x7f|((pixels<<4)&0x80)];
410 *scanline++ = m_rbv_palette[0x7f|((pixels<<5)&0x80)];
411 *scanline++ = m_rbv_palette[0x7f|((pixels<<6)&0x80)];
412 *scanline++ = m_rbv_palette[0x7f|((pixels<<7)&0x80)];
413 }
414 }
415 }
416 break;
417
418 case 1: // 2bpp
419 {
420 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
421
422 for (int y = 0; y < vres; y++)
423 {
424 uint32_t *scanline = &bitmap.pix(y);
425 for (int x = 0; x < hres/4; x++)
426 {
427 uint8_t const pixels = vram8[(y * (hres/4)) + (BYTE4_XOR_BE(x))];
428
429 *scanline++ = m_rbv_palette[0xfc|((pixels>>6)&3)];
430 *scanline++ = m_rbv_palette[0xfc|((pixels>>4)&3)];
431 *scanline++ = m_rbv_palette[0xfc|((pixels>>2)&3)];
432 *scanline++ = m_rbv_palette[0xfc|(pixels&3)];
433 }
434 }
435 }
436 break;
437
438 case 2: // 4bpp
439 {
440 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
441
442 for (int y = 0; y < vres; y++)
443 {
444 uint32_t *scanline = &bitmap.pix(y);
445
446 for (int x = 0; x < hres/2; x++)
447 {
448 uint8_t const pixels = vram8[(y * (hres/2)) + (BYTE4_XOR_BE(x))];
449
450 *scanline++ = m_rbv_palette[0xf0|(pixels>>4)];
451 *scanline++ = m_rbv_palette[0xf0|(pixels&0xf)];
452 }
453 }
454 }
455 break;
456
457 case 3: // 8bpp
458 {
459 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
460
461 for (int y = 0; y < vres; y++)
462 {
463 uint32_t *scanline = &bitmap.pix(y);
464
465 for (int x = 0; x < hres; x++)
466 {
467 uint8_t const pixels = vram8[(y * 2048) + (BYTE4_XOR_BE(x))];
468 *scanline++ = m_rbv_palette[pixels];
469 }
470 }
471 }
472 }
473
474 return 0;
475 }
476
screen_update_macv8(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)477 uint32_t mac_state::screen_update_macv8(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
478 {
479 int hres, vres;
480 switch (m_rbv_montype)
481 {
482 case 1: // 15" portrait display
483 hres = 640;
484 vres = 870;
485 break;
486
487 case 2: // 12" RGB
488 hres = 512;
489 vres = 384;
490 break;
491
492 case 6: // 13" RGB
493 default:
494 hres = 640;
495 vres = 480;
496 break;
497 }
498
499 switch (m_rbv_regs[0x10] & 7)
500 {
501 case 0: // 1bpp
502 {
503 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
504
505 for (int y = 0; y < vres; y++)
506 {
507 uint32_t *scanline = &bitmap.pix(y);
508 for (int x = 0; x < hres; x+=8)
509 {
510 uint8_t const pixels = vram8[(y * 1024) + ((x/8)^3)];
511
512 *scanline++ = m_rbv_palette[0x7f|(pixels&0x80)];
513 *scanline++ = m_rbv_palette[0x7f|((pixels<<1)&0x80)];
514 *scanline++ = m_rbv_palette[0x7f|((pixels<<2)&0x80)];
515 *scanline++ = m_rbv_palette[0x7f|((pixels<<3)&0x80)];
516 *scanline++ = m_rbv_palette[0x7f|((pixels<<4)&0x80)];
517 *scanline++ = m_rbv_palette[0x7f|((pixels<<5)&0x80)];
518 *scanline++ = m_rbv_palette[0x7f|((pixels<<6)&0x80)];
519 *scanline++ = m_rbv_palette[0x7f|((pixels<<7)&0x80)];
520 }
521 }
522 }
523 break;
524
525 case 1: // 2bpp
526 {
527 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
528
529 for (int y = 0; y < vres; y++)
530 {
531 uint32_t *scanline = &bitmap.pix(y);
532 for (int x = 0; x < hres/4; x++)
533 {
534 uint8_t const pixels = vram8[(y * 1024) + (BYTE4_XOR_BE(x))];
535
536 *scanline++ = m_rbv_palette[0x3f|(pixels&0xc0)];
537 *scanline++ = m_rbv_palette[0x3f|((pixels<<2)&0xc0)];
538 *scanline++ = m_rbv_palette[0x3f|((pixels<<4)&0xc0)];
539 *scanline++ = m_rbv_palette[0x3f|((pixels<<6)&0xc0)];
540 }
541 }
542 }
543 break;
544
545 case 2: // 4bpp
546 {
547 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
548
549 for (int y = 0; y < vres; y++)
550 {
551 uint32_t *scanline = &bitmap.pix(y);
552
553 for (int x = 0; x < hres/2; x++)
554 {
555 uint8_t const pixels = vram8[(y * 1024) + (BYTE4_XOR_BE(x))];
556
557 *scanline++ = m_rbv_palette[(pixels&0xf0) | 0xf];
558 *scanline++ = m_rbv_palette[((pixels&0x0f)<<4) | 0xf];
559 }
560 }
561 }
562 break;
563
564 case 3: // 8bpp
565 {
566 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
567
568 for (int y = 0; y < vres; y++)
569 {
570 uint32_t *scanline = &bitmap.pix(y);
571
572 for (int x = 0; x < hres; x++)
573 {
574 uint8_t const pixels = vram8[(y * 1024) + (BYTE4_XOR_BE(x))];
575 *scanline++ = m_rbv_palette[pixels];
576 }
577 }
578 }
579 break;
580 }
581
582 return 0;
583 }
584
screen_update_macsonora(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)585 uint32_t mac_state::screen_update_macsonora(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
586 {
587 int hres, vres, stride;
588 switch (m_rbv_montype)
589 {
590 case 1: // 15" portrait display
591 stride = hres = 640;
592 vres = 870;
593 break;
594
595 case 2: // 12" RGB
596 stride = hres = 512;
597 vres = 384;
598 break;
599
600 case 6: // 13" RGB
601 default:
602 stride = hres = 640;
603 vres = 480;
604 break;
605 }
606
607 // forced blank?
608 if (m_sonora_vctl[0] & 0x80)
609 {
610 return 0;
611 }
612
613 switch (m_sonora_vctl[1] & 7)
614 {
615 case 0: // 1bpp
616 {
617 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
618
619 for (int y = 0; y < vres; y++)
620 {
621 uint32_t *scanline = &bitmap.pix(y);
622 for (int x = 0; x < hres; x+=8)
623 {
624 uint8_t const pixels = vram8[(y * (stride/8)) + ((x/8)^3)];
625
626 *scanline++ = m_rbv_palette[0x7f|(pixels&0x80)];
627 *scanline++ = m_rbv_palette[0x7f|((pixels<<1)&0x80)];
628 *scanline++ = m_rbv_palette[0x7f|((pixels<<2)&0x80)];
629 *scanline++ = m_rbv_palette[0x7f|((pixels<<3)&0x80)];
630 *scanline++ = m_rbv_palette[0x7f|((pixels<<4)&0x80)];
631 *scanline++ = m_rbv_palette[0x7f|((pixels<<5)&0x80)];
632 *scanline++ = m_rbv_palette[0x7f|((pixels<<6)&0x80)];
633 *scanline++ = m_rbv_palette[0x7f|((pixels<<7)&0x80)];
634 }
635 }
636 }
637 break;
638
639 case 1: // 2bpp
640 {
641 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
642
643 for (int y = 0; y < vres; y++)
644 {
645 uint32_t *scanline = &bitmap.pix(y);
646 for (int x = 0; x < hres/4; x++)
647 {
648 uint8_t const pixels = vram8[(y * (stride/4)) + (BYTE4_XOR_BE(x))];
649
650 *scanline++ = m_rbv_palette[0x3f|(pixels&0xc0)];
651 *scanline++ = m_rbv_palette[0x3f|((pixels<<2)&0xc0)];
652 *scanline++ = m_rbv_palette[0x3f|((pixels<<4)&0xc0)];
653 *scanline++ = m_rbv_palette[0x3f|((pixels<<6)&0xc0)];
654 }
655 }
656 }
657 break;
658
659 case 2: // 4bpp
660 {
661 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
662
663 for (int y = 0; y < vres; y++)
664 {
665 uint32_t *scanline = &bitmap.pix(y);
666 for (int x = 0; x < hres/2; x++)
667 {
668 uint8_t const pixels = vram8[(y * (stride/2)) + (BYTE4_XOR_BE(x))];
669
670 *scanline++ = m_rbv_palette[(pixels&0xf0) | 0xf];
671 *scanline++ = m_rbv_palette[((pixels&0x0f)<<4) | 0xf];
672 }
673 }
674 }
675 break;
676
677 case 3: // 8bpp
678 {
679 uint8_t const *const vram8 = (uint8_t *)m_vram.target();
680
681 for (int y = 0; y < vres; y++)
682 {
683 uint32_t *scanline = &bitmap.pix(y);
684 for (int x = 0; x < hres; x++)
685 {
686 uint8_t const pixels = vram8[(y * stride) + (BYTE4_XOR_BE(x))];
687 *scanline++ = m_rbv_palette[pixels];
688 }
689 }
690 }
691 break;
692
693 case 4: // 16bpp
694 {
695 uint16_t const *const vram16 = (uint16_t *)m_vram.target();
696
697 for (int y = 0; y < vres; y++)
698 {
699 uint32_t *scanline = &bitmap.pix(y);
700 for (int x = 0; x < hres; x++)
701 {
702 uint16_t const pixels = vram16[(y * stride) + (x^1)];
703 *scanline++ = rgb_t(((pixels>>10) & 0x1f)<<3, ((pixels>>5) & 0x1f)<<3, (pixels & 0x1f)<<3);
704 }
705 }
706 }
707 break;
708 }
709
710 return 0;
711 }
712
713