22
22
#include "migration/vmstate.h"
23
23
#include "trace.h"
24
24
25
- #define VIDEO_BASE 0x00001000
25
+ #define VIDEO_BASE 0x0
26
26
#define DAFB_BASE 0x00800000
27
27
28
28
#define MACFB_PAGE_SIZE 4096
29
29
#define MACFB_VRAM_SIZE (4 * MiB)
30
30
31
+ #define DAFB_MODE_VADDR1 0x0
32
+ #define DAFB_MODE_VADDR2 0x4
33
+ #define DAFB_MODE_CTRL1 0x8
34
+ #define DAFB_MODE_CTRL2 0xc
31
35
#define DAFB_MODE_SENSE 0x1c
32
36
#define DAFB_RESET 0x200
33
37
#define DAFB_LUT 0x213
@@ -89,6 +93,22 @@ static MacFbSense macfb_sense_table[] = {
89
93
{ MACFB_DISPLAY_SVGA , 0x7 , 0x5 },
90
94
};
91
95
96
+ static MacFbMode macfb_mode_table [] = {
97
+ { MACFB_DISPLAY_VGA , 1 , 0x100 , 0x71e , 640 , 480 , 0x400 , 0x1000 },
98
+ { MACFB_DISPLAY_VGA , 2 , 0x100 , 0x70e , 640 , 480 , 0x400 , 0x1000 },
99
+ { MACFB_DISPLAY_VGA , 4 , 0x100 , 0x706 , 640 , 480 , 0x400 , 0x1000 },
100
+ { MACFB_DISPLAY_VGA , 8 , 0x100 , 0x702 , 640 , 480 , 0x400 , 0x1000 },
101
+ { MACFB_DISPLAY_VGA , 24 , 0x100 , 0x7ff , 640 , 480 , 0x1000 , 0x1000 },
102
+ { MACFB_DISPLAY_VGA , 1 , 0xd0 , 0x70e , 800 , 600 , 0x340 , 0xe00 },
103
+ { MACFB_DISPLAY_VGA , 2 , 0xd0 , 0x706 , 800 , 600 , 0x340 , 0xe00 },
104
+ { MACFB_DISPLAY_VGA , 4 , 0xd0 , 0x702 , 800 , 600 , 0x340 , 0xe00 },
105
+ { MACFB_DISPLAY_VGA , 8 , 0xd0 , 0x700 , 800 , 600 , 0x340 , 0xe00 },
106
+ { MACFB_DISPLAY_VGA , 24 , 0x340 , 0x100 , 800 , 600 , 0xd00 , 0xe00 },
107
+ { MACFB_DISPLAY_APPLE_21_COLOR , 1 , 0x90 , 0x506 , 1152 , 870 , 0x240 , 0x80 },
108
+ { MACFB_DISPLAY_APPLE_21_COLOR , 2 , 0x90 , 0x502 , 1152 , 870 , 0x240 , 0x80 },
109
+ { MACFB_DISPLAY_APPLE_21_COLOR , 4 , 0x90 , 0x500 , 1152 , 870 , 0x240 , 0x80 },
110
+ { MACFB_DISPLAY_APPLE_21_COLOR , 8 , 0x120 , 0x5ff , 1152 , 870 , 0x480 , 0x80 },
111
+ };
92
112
93
113
typedef void macfb_draw_line_func (MacfbState * s , uint8_t * d , uint32_t addr ,
94
114
int width );
@@ -246,7 +266,7 @@ static void macfb_draw_graphic(MacfbState *s)
246
266
ram_addr_t page ;
247
267
uint32_t v = 0 ;
248
268
int y , ymin ;
249
- int macfb_stride = ( s -> depth * s -> width + 7 ) / 8 ;
269
+ int macfb_stride = s -> mode -> stride ;
250
270
macfb_draw_line_func * macfb_draw_line ;
251
271
252
272
switch (s -> depth ) {
@@ -278,7 +298,7 @@ static void macfb_draw_graphic(MacfbState *s)
278
298
DIRTY_MEMORY_VGA );
279
299
280
300
ymin = -1 ;
281
- page = 0 ;
301
+ page = s -> mode -> offset ;
282
302
for (y = 0 ; y < s -> height ; y ++ , page += macfb_stride ) {
283
303
if (macfb_check_dirty (s , snap , page , macfb_stride )) {
284
304
uint8_t * data_display ;
@@ -323,25 +343,26 @@ static uint32_t macfb_sense_read(MacfbState *s)
323
343
sense = 0 ;
324
344
if (!(macfb_sense -> ext_sense & 1 )) {
325
345
/* Pins 7-4 together */
326
- if (~s -> sense & 3 ) {
327
- sense = (~s -> sense & 7 ) | 3 ;
346
+ if (~s -> regs [ DAFB_MODE_SENSE >> 2 ] & 3 ) {
347
+ sense = (~s -> regs [ DAFB_MODE_SENSE >> 2 ] & 7 ) | 3 ;
328
348
}
329
349
}
330
350
if (!(macfb_sense -> ext_sense & 2 )) {
331
351
/* Pins 10-7 together */
332
- if (~s -> sense & 6 ) {
333
- sense = (~s -> sense & 7 ) | 6 ;
352
+ if (~s -> regs [ DAFB_MODE_SENSE >> 2 ] & 6 ) {
353
+ sense = (~s -> regs [ DAFB_MODE_SENSE >> 2 ] & 7 ) | 6 ;
334
354
}
335
355
}
336
356
if (!(macfb_sense -> ext_sense & 4 )) {
337
357
/* Pins 4-10 together */
338
- if (~s -> sense & 5 ) {
339
- sense = (~s -> sense & 7 ) | 5 ;
358
+ if (~s -> regs [ DAFB_MODE_SENSE >> 2 ] & 5 ) {
359
+ sense = (~s -> regs [ DAFB_MODE_SENSE >> 2 ] & 7 ) | 5 ;
340
360
}
341
361
}
342
362
} else {
343
363
/* Normal sense */
344
- sense = (~macfb_sense -> sense & 7 ) | (~s -> sense & 7 );
364
+ sense = (~macfb_sense -> sense & 7 ) |
365
+ (~s -> regs [DAFB_MODE_SENSE >> 2 ] & 7 );
345
366
}
346
367
347
368
trace_macfb_sense_read (sense );
@@ -350,12 +371,84 @@ static uint32_t macfb_sense_read(MacfbState *s)
350
371
351
372
static void macfb_sense_write (MacfbState * s , uint32_t val )
352
373
{
353
- s -> sense = val ;
374
+ s -> regs [ DAFB_MODE_SENSE >> 2 ] = val ;
354
375
355
376
trace_macfb_sense_write (val );
356
377
return ;
357
378
}
358
379
380
+ static void macfb_update_mode (MacfbState * s )
381
+ {
382
+ s -> width = s -> mode -> width ;
383
+ s -> height = s -> mode -> height ;
384
+ s -> depth = s -> mode -> depth ;
385
+
386
+ trace_macfb_update_mode (s -> width , s -> height , s -> depth );
387
+ macfb_invalidate_display (s );
388
+ }
389
+
390
+ static void macfb_mode_write (MacfbState * s )
391
+ {
392
+ MacFbMode * macfb_mode ;
393
+ int i ;
394
+
395
+ for (i = 0 ; i < ARRAY_SIZE (macfb_mode_table ); i ++ ) {
396
+ macfb_mode = & macfb_mode_table [i ];
397
+
398
+ if (s -> type != macfb_mode -> type ) {
399
+ continue ;
400
+ }
401
+
402
+ if ((s -> regs [DAFB_MODE_CTRL1 >> 2 ] & 0xff ) ==
403
+ (macfb_mode -> mode_ctrl1 & 0xff ) &&
404
+ (s -> regs [DAFB_MODE_CTRL2 >> 2 ] & 0xff ) ==
405
+ (macfb_mode -> mode_ctrl2 & 0xff )) {
406
+ s -> mode = macfb_mode ;
407
+ macfb_update_mode (s );
408
+ break ;
409
+ }
410
+ }
411
+ }
412
+
413
+ static MacFbMode * macfb_find_mode (MacfbDisplayType display_type ,
414
+ uint16_t width , uint16_t height ,
415
+ uint8_t depth )
416
+ {
417
+ MacFbMode * macfb_mode ;
418
+ int i ;
419
+
420
+ for (i = 0 ; i < ARRAY_SIZE (macfb_mode_table ); i ++ ) {
421
+ macfb_mode = & macfb_mode_table [i ];
422
+
423
+ if (display_type == macfb_mode -> type && width == macfb_mode -> width &&
424
+ height == macfb_mode -> height && depth == macfb_mode -> depth ) {
425
+ return macfb_mode ;
426
+ }
427
+ }
428
+
429
+ return NULL ;
430
+ }
431
+
432
+ static gchar * macfb_mode_list (void )
433
+ {
434
+ gchar * list = NULL ;
435
+ gchar * mode ;
436
+ MacFbMode * macfb_mode ;
437
+ int i ;
438
+
439
+ for (i = 0 ; i < ARRAY_SIZE (macfb_mode_table ); i ++ ) {
440
+ macfb_mode = & macfb_mode_table [i ];
441
+
442
+ mode = g_strdup_printf (" %dx%dx%d\n" , macfb_mode -> width ,
443
+ macfb_mode -> height , macfb_mode -> depth );
444
+ list = g_strconcat (mode , list , NULL );
445
+ g_free (mode );
446
+ }
447
+
448
+ return list ;
449
+ }
450
+
451
+
359
452
static void macfb_update_display (void * opaque )
360
453
{
361
454
MacfbState * s = opaque ;
@@ -397,6 +490,12 @@ static uint64_t macfb_ctrl_read(void *opaque,
397
490
uint64_t val = 0 ;
398
491
399
492
switch (addr ) {
493
+ case DAFB_MODE_VADDR1 :
494
+ case DAFB_MODE_VADDR2 :
495
+ case DAFB_MODE_CTRL1 :
496
+ case DAFB_MODE_CTRL2 :
497
+ val = s -> regs [addr >> 2 ];
498
+ break ;
400
499
case DAFB_MODE_SENSE :
401
500
val = macfb_sense_read (s );
402
501
break ;
@@ -413,6 +512,17 @@ static void macfb_ctrl_write(void *opaque,
413
512
{
414
513
MacfbState * s = opaque ;
415
514
switch (addr ) {
515
+ case DAFB_MODE_VADDR1 :
516
+ case DAFB_MODE_VADDR2 :
517
+ s -> regs [addr >> 2 ] = val ;
518
+ break ;
519
+ case DAFB_MODE_CTRL1 ... DAFB_MODE_CTRL1 + 3 :
520
+ case DAFB_MODE_CTRL2 ... DAFB_MODE_CTRL2 + 3 :
521
+ s -> regs [addr >> 2 ] = val ;
522
+ if (val ) {
523
+ macfb_mode_write (s );
524
+ }
525
+ break ;
416
526
case DAFB_MODE_SENSE :
417
527
macfb_sense_write (s , val );
418
528
break ;
@@ -442,7 +552,7 @@ static const MemoryRegionOps macfb_ctrl_ops = {
442
552
443
553
static int macfb_post_load (void * opaque , int version_id )
444
554
{
445
- macfb_invalidate_display (opaque );
555
+ macfb_mode_write (opaque );
446
556
return 0 ;
447
557
}
448
558
@@ -455,7 +565,7 @@ static const VMStateDescription vmstate_macfb = {
455
565
.fields = (VMStateField []) {
456
566
VMSTATE_UINT8_ARRAY (color_palette , MacfbState , 256 * 3 ),
457
567
VMSTATE_UINT32 (palette_current , MacfbState ),
458
- VMSTATE_UINT32 ( sense , MacfbState ),
568
+ VMSTATE_UINT32_ARRAY ( regs , MacfbState , MACFB_NUM_REGS ),
459
569
VMSTATE_END_OF_LIST ()
460
570
}
461
571
};
@@ -469,9 +579,15 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error **errp)
469
579
{
470
580
DisplaySurface * surface ;
471
581
472
- if (s -> depth != 1 && s -> depth != 2 && s -> depth != 4 && s -> depth != 8 &&
473
- s -> depth != 16 && s -> depth != 24 ) {
474
- error_setg (errp , "unknown guest depth %d" , s -> depth );
582
+ s -> mode = macfb_find_mode (s -> type , s -> width , s -> height , s -> depth );
583
+ if (!s -> mode ) {
584
+ gchar * list ;
585
+ error_setg (errp , "unknown display mode: width %d, height %d, depth %d" ,
586
+ s -> width , s -> height , s -> depth );
587
+ list = macfb_mode_list ();
588
+ error_append_hint (errp , "Available modes:\n%s" , list );
589
+ g_free (list );
590
+
475
591
return false;
476
592
}
477
593
@@ -493,6 +609,7 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error **errp)
493
609
s -> vram_bit_mask = MACFB_VRAM_SIZE - 1 ;
494
610
memory_region_set_coalescing (& s -> mem_vram );
495
611
612
+ macfb_update_mode (s );
496
613
return true;
497
614
}
498
615
0 commit comments