[PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM

Mark Cave-Ayland posted 12 patches 4 years, 4 months ago
Maintainers: Laurent Vivier <laurent@vivier.eu>
There is a newer version of this series
[PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Mark Cave-Ayland 4 years, 4 months ago
The monitor modes table is found by experimenting with the Monitors Control
Panel in MacOS and analysing the reads/writes. From this it can be found that
the mode is controlled by writes to the DAFB_MODE_CTRL1 and DAFB_MODE_CTRL2
registers.

Implement the first block of DAFB registers as a register array including the
existing sense register, the newly discovered control registers above, and also
the DAFB_MODE_VADDR1 and DAFB_MODE_VADDR2 registers which are used by NetBSD to
determine the current video mode.

These experiments also show that the offset of the start of video RAM and the
stride can change depending upon the monitor mode, so update macfb_draw_graphic()
and both the BI_MAC_VADDR and BI_MAC_VROW bootinfo for the q800 machine
accordingly.

Finally update macfb_common_realize() so that only the resolution and depth
supported by the display type can be specified on the command line.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
---
 hw/display/macfb.c         | 124 ++++++++++++++++++++++++++++++++-----
 hw/display/trace-events    |   1 +
 hw/m68k/q800.c             |  11 ++--
 include/hw/display/macfb.h |  16 ++++-
 4 files changed, 131 insertions(+), 21 deletions(-)

diff --git a/hw/display/macfb.c b/hw/display/macfb.c
index f98bcdec2d..357fe18be5 100644
--- a/hw/display/macfb.c
+++ b/hw/display/macfb.c
@@ -22,12 +22,16 @@
 #include "migration/vmstate.h"
 #include "trace.h"
 
-#define VIDEO_BASE 0x00001000
+#define VIDEO_BASE 0x0
 #define DAFB_BASE  0x00800000
 
 #define MACFB_PAGE_SIZE 4096
 #define MACFB_VRAM_SIZE (4 * MiB)
 
+#define DAFB_MODE_VADDR1    0x0
+#define DAFB_MODE_VADDR2    0x4
+#define DAFB_MODE_CTRL1     0x8
+#define DAFB_MODE_CTRL2     0xc
 #define DAFB_MODE_SENSE     0x1c
 #define DAFB_RESET          0x200
 #define DAFB_LUT            0x213
@@ -89,6 +93,22 @@ static MacFbSense macfb_sense_table[] = {
     { MACFB_DISPLAY_SVGA, 0x7, 0x5 },
 };
 
+static MacFbMode macfb_mode_table[] = {
+    { MACFB_DISPLAY_VGA, 1, 0x100, 0x71e, 640, 480, 0x400, 0x1000 },
+    { MACFB_DISPLAY_VGA, 2, 0x100, 0x70e, 640, 480, 0x400, 0x1000 },
+    { MACFB_DISPLAY_VGA, 4, 0x100, 0x706, 640, 480, 0x400, 0x1000 },
+    { MACFB_DISPLAY_VGA, 8, 0x100, 0x702, 640, 480, 0x400, 0x1000 },
+    { MACFB_DISPLAY_VGA, 24, 0x100, 0x7ff, 640, 480, 0x1000, 0x1000 },
+    { MACFB_DISPLAY_VGA, 1, 0xd0 , 0x70e, 800, 600, 0x340, 0xe00 },
+    { MACFB_DISPLAY_VGA, 2, 0xd0 , 0x706, 800, 600, 0x340, 0xe00 },
+    { MACFB_DISPLAY_VGA, 4, 0xd0 , 0x702, 800, 600, 0x340, 0xe00 },
+    { MACFB_DISPLAY_VGA, 8, 0xd0,  0x700, 800, 600, 0x340, 0xe00 },
+    { MACFB_DISPLAY_VGA, 24, 0x340, 0x100, 800, 600, 0xd00, 0xe00 },
+    { MACFB_DISPLAY_APPLE_21_COLOR, 1, 0x90, 0x506, 1152, 870, 0x240, 0x80 },
+    { MACFB_DISPLAY_APPLE_21_COLOR, 2, 0x90, 0x502, 1152, 870, 0x240, 0x80 },
+    { MACFB_DISPLAY_APPLE_21_COLOR, 4, 0x90, 0x500, 1152, 870, 0x240, 0x80 },
+    { MACFB_DISPLAY_APPLE_21_COLOR, 8, 0x120, 0x5ff, 1152, 870, 0x480, 0x80 },
+};
 
 typedef void macfb_draw_line_func(MacfbState *s, uint8_t *d, uint32_t addr,
                                   int width);
@@ -246,7 +266,7 @@ static void macfb_draw_graphic(MacfbState *s)
     ram_addr_t page;
     uint32_t v = 0;
     int y, ymin;
-    int macfb_stride = (s->depth * s->width + 7) / 8;
+    int macfb_stride = s->mode->stride;
     macfb_draw_line_func *macfb_draw_line;
 
     switch (s->depth) {
@@ -278,7 +298,7 @@ static void macfb_draw_graphic(MacfbState *s)
                                              DIRTY_MEMORY_VGA);
 
     ymin = -1;
-    page = 0;
+    page = s->mode->offset;
     for (y = 0; y < s->height; y++, page += macfb_stride) {
         if (macfb_check_dirty(s, snap, page, macfb_stride)) {
             uint8_t *data_display;
@@ -323,25 +343,26 @@ static uint32_t macfb_sense_read(MacfbState *s)
         sense = 0;
         if (!(macfb_sense->ext_sense & 1)) {
             /* Pins 7-4 together */
-            if (~s->sense & 3) {
-                sense = (~s->sense & 7) | 3;
+            if (~s->regs[DAFB_MODE_SENSE >> 2] & 3) {
+                sense = (~s->regs[DAFB_MODE_SENSE >> 2] & 7) | 3;
             }
         }
         if (!(macfb_sense->ext_sense & 2)) {
             /* Pins 10-7 together */
-            if (~s->sense & 6) {
-                sense = (~s->sense & 7) | 6;
+            if (~s->regs[DAFB_MODE_SENSE >> 2] & 6) {
+                sense = (~s->regs[DAFB_MODE_SENSE >> 2] & 7) | 6;
             }
         }
         if (!(macfb_sense->ext_sense & 4)) {
             /* Pins 4-10 together */
-            if (~s->sense & 5) {
-                sense = (~s->sense & 7) | 5;
+            if (~s->regs[DAFB_MODE_SENSE >> 2] & 5) {
+                sense = (~s->regs[DAFB_MODE_SENSE >> 2] & 7) | 5;
             }
         }
     } else {
         /* Normal sense */
-        sense = (~macfb_sense->sense & 7) | (~s->sense & 7);
+        sense = (~macfb_sense->sense & 7) |
+                (~s->regs[DAFB_MODE_SENSE >> 2] & 7);
     }
 
     trace_macfb_sense_read(sense);
@@ -350,12 +371,64 @@ static uint32_t macfb_sense_read(MacfbState *s)
 
 static void macfb_sense_write(MacfbState *s, uint32_t val)
 {
-    s->sense = val;
+    s->regs[DAFB_MODE_SENSE >> 2] = val;
 
     trace_macfb_sense_write(val);
     return;
 }
 
+static void macfb_update_mode(MacfbState *s)
+{
+    s->width = s->mode->width;
+    s->height = s->mode->height;
+    s->depth = s->mode->depth;
+
+    trace_macfb_update_mode(s->width, s->height, s->depth);
+    macfb_invalidate_display(s);
+}
+
+static void macfb_mode_write(MacfbState *s)
+{
+    MacFbMode *macfb_mode;
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
+        macfb_mode = &macfb_mode_table[i];
+
+        if (s->type != macfb_mode->type) {
+            continue;
+        }
+
+        if ((s->regs[DAFB_MODE_CTRL1 >> 2] & 0xff) ==
+             (macfb_mode->mode_ctrl1 & 0xff) &&
+            (s->regs[DAFB_MODE_CTRL2 >> 2] & 0xff) ==
+             (macfb_mode->mode_ctrl2 & 0xff)) {
+            s->mode = macfb_mode;
+            macfb_update_mode(s);
+            break;
+        }
+    }
+}
+
+static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
+                                  uint16_t width, uint16_t height,
+                                  uint8_t depth)
+{
+    MacFbMode *macfb_mode;
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
+        macfb_mode = &macfb_mode_table[i];
+
+        if (display_type == macfb_mode->type && width == macfb_mode->width &&
+                height == macfb_mode->height && depth == macfb_mode->depth) {
+            return macfb_mode;
+        }
+    }
+
+    return NULL;
+}
+
 static void macfb_update_display(void *opaque)
 {
     MacfbState *s = opaque;
@@ -397,6 +470,12 @@ static uint64_t macfb_ctrl_read(void *opaque,
     uint64_t val = 0;
 
     switch (addr) {
+    case DAFB_MODE_VADDR1:
+    case DAFB_MODE_VADDR2:
+    case DAFB_MODE_CTRL1:
+    case DAFB_MODE_CTRL2:
+        val = s->regs[addr >> 2];
+        break;
     case DAFB_MODE_SENSE:
         val = macfb_sense_read(s);
         break;
@@ -413,6 +492,17 @@ static void macfb_ctrl_write(void *opaque,
 {
     MacfbState *s = opaque;
     switch (addr) {
+    case DAFB_MODE_VADDR1:
+    case DAFB_MODE_VADDR2:
+        s->regs[addr >> 2] = val;
+        break;
+    case DAFB_MODE_CTRL1 ... DAFB_MODE_CTRL1 + 3:
+    case DAFB_MODE_CTRL2 ... DAFB_MODE_CTRL2 + 3:
+        s->regs[addr >> 2] = val;
+        if (val) {
+            macfb_mode_write(s);
+        }
+        break;
     case DAFB_MODE_SENSE:
         macfb_sense_write(s, val);
         break;
@@ -442,7 +532,7 @@ static const MemoryRegionOps macfb_ctrl_ops = {
 
 static int macfb_post_load(void *opaque, int version_id)
 {
-    macfb_invalidate_display(opaque);
+    macfb_mode_write(opaque);
     return 0;
 }
 
@@ -455,7 +545,7 @@ static const VMStateDescription vmstate_macfb = {
     .fields = (VMStateField[]) {
         VMSTATE_UINT8_ARRAY(color_palette, MacfbState, 256 * 3),
         VMSTATE_UINT32(palette_current, MacfbState),
-        VMSTATE_UINT32(sense, MacfbState),
+        VMSTATE_UINT32_ARRAY(regs, MacfbState, MACFB_NUM_REGS),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -469,9 +559,10 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error **errp)
 {
     DisplaySurface *surface;
 
-    if (s->depth != 1 && s->depth != 2 && s->depth != 4 && s->depth != 8 &&
-        s->depth != 16 && s->depth != 24) {
-        error_setg(errp, "unknown guest depth %d", s->depth);
+    s->mode = macfb_find_mode(s->type, s->width, s->height, s->depth);
+    if (!s->mode) {
+        error_setg(errp, "unknown display mode: width %d, height %d, depth %d",
+                   s->width, s->height, s->depth);
         return false;
     }
 
@@ -493,6 +584,7 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error **errp)
     s->vram_bit_mask = MACFB_VRAM_SIZE - 1;
     memory_region_set_coalescing(&s->mem_vram);
 
+    macfb_update_mode(s);
     return true;
 }
 
diff --git a/hw/display/trace-events b/hw/display/trace-events
index 5753421a43..075cd4614c 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -173,3 +173,4 @@ macfb_ctrl_read(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%"PRIx
 macfb_ctrl_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%"PRIx64 " value 0x%"PRIx64 " size %d"
 macfb_sense_read(uint32_t value) "video sense: 0x%"PRIx32
 macfb_sense_write(uint32_t value) "video sense: 0x%"PRIx32
+macfb_update_mode(uint32_t width, uint32_t height, uint8_t depth) "setting mode to width %"PRId32 " height %"PRId32 " size %d"
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 5223b880bc..df3fd3711e 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -74,7 +74,7 @@
  * is needed by the kernel to have early display and
  * thus provided by the bootloader
  */
-#define VIDEO_BASE            0xf9001000
+#define VIDEO_BASE            0xf9000000
 
 #define MAC_CLOCK  3686418
 
@@ -221,6 +221,7 @@ static void q800_init(MachineState *machine)
     uint8_t *prom;
     const int io_slice_nb = (IO_SIZE / IO_SLICE) - 1;
     int i, checksum;
+    MacFbMode *macfb_mode;
     ram_addr_t ram_size = machine->ram_size;
     const char *kernel_filename = machine->kernel_filename;
     const char *initrd_filename = machine->initrd_filename;
@@ -428,6 +429,8 @@ static void q800_init(MachineState *machine)
     }
     qdev_realize_and_unref(dev, BUS(nubus), &error_fatal);
 
+    macfb_mode = (NUBUS_MACFB(dev)->macfb).mode;
+
     cs = CPU(cpu);
     if (linux_boot) {
         uint64_t high;
@@ -450,12 +453,12 @@ static void q800_init(MachineState *machine)
         BOOTINFO1(cs->as, parameters_base,
                   BI_MAC_MEMSIZE, ram_size >> 20); /* in MB */
         BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size);
-        BOOTINFO1(cs->as, parameters_base, BI_MAC_VADDR, VIDEO_BASE);
+        BOOTINFO1(cs->as, parameters_base, BI_MAC_VADDR,
+                  VIDEO_BASE + macfb_mode->offset);
         BOOTINFO1(cs->as, parameters_base, BI_MAC_VDEPTH, graphic_depth);
         BOOTINFO1(cs->as, parameters_base, BI_MAC_VDIM,
                   (graphic_height << 16) | graphic_width);
-        BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW,
-                  (graphic_width * graphic_depth + 7) / 8);
+        BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW, macfb_mode->stride);
         BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE);
 
         rom = g_malloc(sizeof(*rom));
diff --git a/include/hw/display/macfb.h b/include/hw/display/macfb.h
index e95a97ebdc..0aff0d84d2 100644
--- a/include/hw/display/macfb.h
+++ b/include/hw/display/macfb.h
@@ -35,6 +35,19 @@ typedef enum  {
     MACFB_DISPLAY_SVGA = 14,
 } MacfbDisplayType;
 
+typedef struct MacFbMode {
+    uint8_t type;
+    uint8_t depth;
+    uint32_t mode_ctrl1;
+    uint32_t mode_ctrl2;
+    uint32_t width;
+    uint32_t height;
+    uint32_t stride;
+    uint32_t offset;
+} MacFbMode;
+
+#define MACFB_NUM_REGS      8
+
 typedef struct MacfbState {
     MemoryRegion mem_vram;
     MemoryRegion mem_ctrl;
@@ -48,7 +61,8 @@ typedef struct MacfbState {
     uint8_t depth;
     uint8_t type;
 
-    uint32_t sense;
+    uint32_t regs[MACFB_NUM_REGS];
+    MacFbMode *mode;
 } MacfbState;
 
 #define TYPE_MACFB "sysbus-macfb"
-- 
2.20.1


Re: [PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Laurent Vivier 4 years, 4 months ago
Le 04/10/2021 à 23:19, Mark Cave-Ayland a écrit :
> The monitor modes table is found by experimenting with the Monitors Control
> Panel in MacOS and analysing the reads/writes. From this it can be found that
> the mode is controlled by writes to the DAFB_MODE_CTRL1 and DAFB_MODE_CTRL2
> registers.
> 
> Implement the first block of DAFB registers as a register array including the
> existing sense register, the newly discovered control registers above, and also
> the DAFB_MODE_VADDR1 and DAFB_MODE_VADDR2 registers which are used by NetBSD to
> determine the current video mode.
> 
> These experiments also show that the offset of the start of video RAM and the
> stride can change depending upon the monitor mode, so update macfb_draw_graphic()
> and both the BI_MAC_VADDR and BI_MAC_VROW bootinfo for the q800 machine
> accordingly.
> 
> Finally update macfb_common_realize() so that only the resolution and depth
> supported by the display type can be specified on the command line.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> Reviewed-by: Laurent Vivier <laurent@vivier.eu>
> ---
>  hw/display/macfb.c         | 124 ++++++++++++++++++++++++++++++++-----
>  hw/display/trace-events    |   1 +
>  hw/m68k/q800.c             |  11 ++--
>  include/hw/display/macfb.h |  16 ++++-
>  4 files changed, 131 insertions(+), 21 deletions(-)
> 
> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
> index f98bcdec2d..357fe18be5 100644
> --- a/hw/display/macfb.c
> +++ b/hw/display/macfb.c
>
...
> +static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
> +                                  uint16_t width, uint16_t height,
> +                                  uint8_t depth)
> +{
> +    MacFbMode *macfb_mode;
> +    int i;
> +
> +    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
> +        macfb_mode = &macfb_mode_table[i];
> +
> +        if (display_type == macfb_mode->type && width == macfb_mode->width &&
> +                height == macfb_mode->height && depth == macfb_mode->depth) {
> +            return macfb_mode;
> +        }
> +    }
> +
> +    return NULL;
> +}
> +

I misunderstood this part when I reviewed v1...

It means you have to provide the monitor type to QEMU to switch from the default mode?

But, as a user, how do we know which modes are allowed with which resolution?

Is possible to try to set internally the type here according to the resolution?

Could you provide an command line example how to start the q800 with the 1152x870 resolution?

Thanks,
Laurent


Re: [PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Mark Cave-Ayland 4 years, 4 months ago
On 05/10/2021 10:50, Laurent Vivier wrote:

> Le 04/10/2021 à 23:19, Mark Cave-Ayland a écrit :
>> The monitor modes table is found by experimenting with the Monitors Control
>> Panel in MacOS and analysing the reads/writes. From this it can be found that
>> the mode is controlled by writes to the DAFB_MODE_CTRL1 and DAFB_MODE_CTRL2
>> registers.
>>
>> Implement the first block of DAFB registers as a register array including the
>> existing sense register, the newly discovered control registers above, and also
>> the DAFB_MODE_VADDR1 and DAFB_MODE_VADDR2 registers which are used by NetBSD to
>> determine the current video mode.
>>
>> These experiments also show that the offset of the start of video RAM and the
>> stride can change depending upon the monitor mode, so update macfb_draw_graphic()
>> and both the BI_MAC_VADDR and BI_MAC_VROW bootinfo for the q800 machine
>> accordingly.
>>
>> Finally update macfb_common_realize() so that only the resolution and depth
>> supported by the display type can be specified on the command line.
>>
>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>> Reviewed-by: Laurent Vivier <laurent@vivier.eu>
>> ---
>>   hw/display/macfb.c         | 124 ++++++++++++++++++++++++++++++++-----
>>   hw/display/trace-events    |   1 +
>>   hw/m68k/q800.c             |  11 ++--
>>   include/hw/display/macfb.h |  16 ++++-
>>   4 files changed, 131 insertions(+), 21 deletions(-)
>>
>> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
>> index f98bcdec2d..357fe18be5 100644
>> --- a/hw/display/macfb.c
>> +++ b/hw/display/macfb.c
>>
> ...
>> +static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
>> +                                  uint16_t width, uint16_t height,
>> +                                  uint8_t depth)
>> +{
>> +    MacFbMode *macfb_mode;
>> +    int i;
>> +
>> +    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
>> +        macfb_mode = &macfb_mode_table[i];
>> +
>> +        if (display_type == macfb_mode->type && width == macfb_mode->width &&
>> +                height == macfb_mode->height && depth == macfb_mode->depth) {
>> +            return macfb_mode;
>> +        }
>> +    }
>> +
>> +    return NULL;
>> +}
>> +
> 
> I misunderstood this part when I reviewed v1...
> 
> It means you have to provide the monitor type to QEMU to switch from the default mode?

Not as such: both the MacOS toolbox ROM and MacOS itself offer a fixed set of 
resolutions and depths based upon the display type. What I've done for now is default 
the display type to VGA since it offers both 640x480 and 800x600 in 1, 2, 4, 8, 16 
and 24-bit colour which should cover the most common use of cases of people wanting 
to boot using the MacOS toolbox ROM.

Even if you specify a default on the command line, MacOS still only cares about the 
display type and will allow you to change the resolution and depth dynamically, 
remembering the last resolution and depth across reboots.

During testing I found that having access to the 1152x870 resolution offered by the 
Apple 21" monitor display type was useful to allow larger screen sizes, although only 
up to 8-bit depth so I added a bit of code that will switch from a VGA display type 
to a 21" display type if the graphics resolution is set to 1152x870x8.

Finally if you boot a Linux kernel directly using -kernel then the provided XxYxD is 
placed directly into the relevant bootinfo fields with a VGA display type, unless a 
resolution of 1152x870x8 is specified in which case the 21" display type is used as 
above.

> But, as a user, how do we know which modes are allowed with which resolution?
> 
> Is possible to try to set internally the type here according to the resolution?
> 
> Could you provide an command line example how to start the q800 with the 1152x870 resolution?

Sure - simply add "-g 1152x870x8" to your command line. If the -g parameter is 
omitted then the display type will default to VGA.


ATB,

Mark.

Re: [PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Laurent Vivier 4 years, 4 months ago
Le 05/10/2021 à 13:38, Mark Cave-Ayland a écrit :
> On 05/10/2021 10:50, Laurent Vivier wrote:
> 
>> Le 04/10/2021 à 23:19, Mark Cave-Ayland a écrit :
>>> The monitor modes table is found by experimenting with the Monitors Control
>>> Panel in MacOS and analysing the reads/writes. From this it can be found that
>>> the mode is controlled by writes to the DAFB_MODE_CTRL1 and DAFB_MODE_CTRL2
>>> registers.
>>>
>>> Implement the first block of DAFB registers as a register array including the
>>> existing sense register, the newly discovered control registers above, and also
>>> the DAFB_MODE_VADDR1 and DAFB_MODE_VADDR2 registers which are used by NetBSD to
>>> determine the current video mode.
>>>
>>> These experiments also show that the offset of the start of video RAM and the
>>> stride can change depending upon the monitor mode, so update macfb_draw_graphic()
>>> and both the BI_MAC_VADDR and BI_MAC_VROW bootinfo for the q800 machine
>>> accordingly.
>>>
>>> Finally update macfb_common_realize() so that only the resolution and depth
>>> supported by the display type can be specified on the command line.
>>>
>>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>>> Reviewed-by: Laurent Vivier <laurent@vivier.eu>
>>> ---
>>>   hw/display/macfb.c         | 124 ++++++++++++++++++++++++++++++++-----
>>>   hw/display/trace-events    |   1 +
>>>   hw/m68k/q800.c             |  11 ++--
>>>   include/hw/display/macfb.h |  16 ++++-
>>>   4 files changed, 131 insertions(+), 21 deletions(-)
>>>
>>> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
>>> index f98bcdec2d..357fe18be5 100644
>>> --- a/hw/display/macfb.c
>>> +++ b/hw/display/macfb.c
>>>
>> ...
>>> +static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
>>> +                                  uint16_t width, uint16_t height,
>>> +                                  uint8_t depth)
>>> +{
>>> +    MacFbMode *macfb_mode;
>>> +    int i;
>>> +
>>> +    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
>>> +        macfb_mode = &macfb_mode_table[i];
>>> +
>>> +        if (display_type == macfb_mode->type && width == macfb_mode->width &&
>>> +                height == macfb_mode->height && depth == macfb_mode->depth) {
>>> +            return macfb_mode;
>>> +        }
>>> +    }
>>> +
>>> +    return NULL;
>>> +}
>>> +
>>
>> I misunderstood this part when I reviewed v1...
>>
>> It means you have to provide the monitor type to QEMU to switch from the default mode?
> 
> Not as such: both the MacOS toolbox ROM and MacOS itself offer a fixed set of resolutions and depths
> based upon the display type. What I've done for now is default the display type to VGA since it
> offers both 640x480 and 800x600 in 1, 2, 4, 8, 16 and 24-bit colour which should cover the most
> common use of cases of people wanting to boot using the MacOS toolbox ROM.
> 
> Even if you specify a default on the command line, MacOS still only cares about the display type and
> will allow you to change the resolution and depth dynamically, remembering the last resolution and
> depth across reboots.
> 
> During testing I found that having access to the 1152x870 resolution offered by the Apple 21"
> monitor display type was useful to allow larger screen sizes, although only up to 8-bit depth so I
> added a bit of code that will switch from a VGA display type to a 21" display type if the graphics
> resolution is set to 1152x870x8.
> 
> Finally if you boot a Linux kernel directly using -kernel then the provided XxYxD is placed directly
> into the relevant bootinfo fields with a VGA display type, unless a resolution of 1152x870x8 is
> specified in which case the 21" display type is used as above.
> 
>> But, as a user, how do we know which modes are allowed with which resolution?
>>
>> Is possible to try to set internally the type here according to the resolution?
>>
>> Could you provide an command line example how to start the q800 with the 1152x870 resolution?
> 
> Sure - simply add "-g 1152x870x8" to your command line. If the -g parameter is omitted then the
> display type will default to VGA.
> 

Thank you for the explanation.

Perhaps you can add in the error message the list of the available mode and depth?
(it's not a blocker for the series, it can be added later)

As an user, it's hard to know what are the allowed values.

Thanks,
Laurent

Re: [PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Mark Cave-Ayland 4 years, 4 months ago
On 05/10/2021 16:08, Laurent Vivier wrote:

> Le 05/10/2021 à 13:38, Mark Cave-Ayland a écrit :
>> On 05/10/2021 10:50, Laurent Vivier wrote:
>>
>>> Le 04/10/2021 à 23:19, Mark Cave-Ayland a écrit :
>>>> The monitor modes table is found by experimenting with the Monitors Control
>>>> Panel in MacOS and analysing the reads/writes. From this it can be found that
>>>> the mode is controlled by writes to the DAFB_MODE_CTRL1 and DAFB_MODE_CTRL2
>>>> registers.
>>>>
>>>> Implement the first block of DAFB registers as a register array including the
>>>> existing sense register, the newly discovered control registers above, and also
>>>> the DAFB_MODE_VADDR1 and DAFB_MODE_VADDR2 registers which are used by NetBSD to
>>>> determine the current video mode.
>>>>
>>>> These experiments also show that the offset of the start of video RAM and the
>>>> stride can change depending upon the monitor mode, so update macfb_draw_graphic()
>>>> and both the BI_MAC_VADDR and BI_MAC_VROW bootinfo for the q800 machine
>>>> accordingly.
>>>>
>>>> Finally update macfb_common_realize() so that only the resolution and depth
>>>> supported by the display type can be specified on the command line.
>>>>
>>>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>>>> Reviewed-by: Laurent Vivier <laurent@vivier.eu>
>>>> ---
>>>>    hw/display/macfb.c         | 124 ++++++++++++++++++++++++++++++++-----
>>>>    hw/display/trace-events    |   1 +
>>>>    hw/m68k/q800.c             |  11 ++--
>>>>    include/hw/display/macfb.h |  16 ++++-
>>>>    4 files changed, 131 insertions(+), 21 deletions(-)
>>>>
>>>> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
>>>> index f98bcdec2d..357fe18be5 100644
>>>> --- a/hw/display/macfb.c
>>>> +++ b/hw/display/macfb.c
>>>>
>>> ...
>>>> +static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
>>>> +                                  uint16_t width, uint16_t height,
>>>> +                                  uint8_t depth)
>>>> +{
>>>> +    MacFbMode *macfb_mode;
>>>> +    int i;
>>>> +
>>>> +    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
>>>> +        macfb_mode = &macfb_mode_table[i];
>>>> +
>>>> +        if (display_type == macfb_mode->type && width == macfb_mode->width &&
>>>> +                height == macfb_mode->height && depth == macfb_mode->depth) {
>>>> +            return macfb_mode;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    return NULL;
>>>> +}
>>>> +
>>>
>>> I misunderstood this part when I reviewed v1...
>>>
>>> It means you have to provide the monitor type to QEMU to switch from the default mode?
>>
>> Not as such: both the MacOS toolbox ROM and MacOS itself offer a fixed set of resolutions and depths
>> based upon the display type. What I've done for now is default the display type to VGA since it
>> offers both 640x480 and 800x600 in 1, 2, 4, 8, 16 and 24-bit colour which should cover the most
>> common use of cases of people wanting to boot using the MacOS toolbox ROM.
>>
>> Even if you specify a default on the command line, MacOS still only cares about the display type and
>> will allow you to change the resolution and depth dynamically, remembering the last resolution and
>> depth across reboots.
>>
>> During testing I found that having access to the 1152x870 resolution offered by the Apple 21"
>> monitor display type was useful to allow larger screen sizes, although only up to 8-bit depth so I
>> added a bit of code that will switch from a VGA display type to a 21" display type if the graphics
>> resolution is set to 1152x870x8.
>>
>> Finally if you boot a Linux kernel directly using -kernel then the provided XxYxD is placed directly
>> into the relevant bootinfo fields with a VGA display type, unless a resolution of 1152x870x8 is
>> specified in which case the 21" display type is used as above.
>>
>>> But, as a user, how do we know which modes are allowed with which resolution?
>>>
>>> Is possible to try to set internally the type here according to the resolution?
>>>
>>> Could you provide an command line example how to start the q800 with the 1152x870 resolution?
>>
>> Sure - simply add "-g 1152x870x8" to your command line. If the -g parameter is omitted then the
>> display type will default to VGA.
>>
> 
> Thank you for the explanation.
> 
> Perhaps you can add in the error message the list of the available mode and depth?
> (it's not a blocker for the series, it can be added later)
> 
> As an user, it's hard to know what are the allowed values.

This is where it becomes a bit trickier, since technically booting Linux with -kernel 
you can use any supported values as long as everything fits in the video RAM which is 
why there isn't currently a hard-coded list :)

If you would prefer a fixed set of resolutions for both MacOS and Linux booted with 
-kernel then I think we should aim for VGA (640x480) in 1, 2, 4, 8, 16 and 24-bit 
depths, SVGA (800x600) in 1, 2, 4, 8, 16 and 24-bit depths and 21" (1152x870) in 1, 
2, 4 and 8-bit depths. Do other emulated displays show supported resolutions in the 
error message, or do they rely on including this in the documentation?

One other point to note is that when MacOS detects a VGA display type, it defaults to 
640x480 until you go into the Control Panel and select 800x600 to enable it. It seems 
this was a precaution to prevent damaging VGA monitors that couldn't sync with an 
SVGA signal, since the cable doesn't allow you to distinguish between a VGA and an 
SVGA-capable monitor.

Finally after the initial boot MacOS always boots into the last resolution/depth set 
successfully in the Control Panel for the detected display type. So you could specify 
640x480x8 on the command line, but if you changed this to 800x600x4 before the last 
reboot then MacOS would reprogram the macfb registers with the same values again, 
effectively overriding the -g parameter and making it a no-op...


ATB,

Mark.

Re: [PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Laurent Vivier 4 years, 4 months ago
Le 05/10/2021 à 17:33, Mark Cave-Ayland a écrit :
> On 05/10/2021 16:08, Laurent Vivier wrote:
> 
>> Le 05/10/2021 à 13:38, Mark Cave-Ayland a écrit :
>>> On 05/10/2021 10:50, Laurent Vivier wrote:
>>>
>>>> Le 04/10/2021 à 23:19, Mark Cave-Ayland a écrit :
>>>>> The monitor modes table is found by experimenting with the Monitors Control
>>>>> Panel in MacOS and analysing the reads/writes. From this it can be found that
>>>>> the mode is controlled by writes to the DAFB_MODE_CTRL1 and DAFB_MODE_CTRL2
>>>>> registers.
>>>>>
>>>>> Implement the first block of DAFB registers as a register array including the
>>>>> existing sense register, the newly discovered control registers above, and also
>>>>> the DAFB_MODE_VADDR1 and DAFB_MODE_VADDR2 registers which are used by NetBSD to
>>>>> determine the current video mode.
>>>>>
>>>>> These experiments also show that the offset of the start of video RAM and the
>>>>> stride can change depending upon the monitor mode, so update macfb_draw_graphic()
>>>>> and both the BI_MAC_VADDR and BI_MAC_VROW bootinfo for the q800 machine
>>>>> accordingly.
>>>>>
>>>>> Finally update macfb_common_realize() so that only the resolution and depth
>>>>> supported by the display type can be specified on the command line.
>>>>>
>>>>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>>>>> Reviewed-by: Laurent Vivier <laurent@vivier.eu>
>>>>> ---
>>>>>    hw/display/macfb.c         | 124 ++++++++++++++++++++++++++++++++-----
>>>>>    hw/display/trace-events    |   1 +
>>>>>    hw/m68k/q800.c             |  11 ++--
>>>>>    include/hw/display/macfb.h |  16 ++++-
>>>>>    4 files changed, 131 insertions(+), 21 deletions(-)
>>>>>
>>>>> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
>>>>> index f98bcdec2d..357fe18be5 100644
>>>>> --- a/hw/display/macfb.c
>>>>> +++ b/hw/display/macfb.c
>>>>>
>>>> ...
>>>>> +static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
>>>>> +                                  uint16_t width, uint16_t height,
>>>>> +                                  uint8_t depth)
>>>>> +{
>>>>> +    MacFbMode *macfb_mode;
>>>>> +    int i;
>>>>> +
>>>>> +    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
>>>>> +        macfb_mode = &macfb_mode_table[i];
>>>>> +
>>>>> +        if (display_type == macfb_mode->type && width == macfb_mode->width &&
>>>>> +                height == macfb_mode->height && depth == macfb_mode->depth) {
>>>>> +            return macfb_mode;
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    return NULL;
>>>>> +}
>>>>> +
>>>>
>>>> I misunderstood this part when I reviewed v1...
>>>>
>>>> It means you have to provide the monitor type to QEMU to switch from the default mode?
>>>
>>> Not as such: both the MacOS toolbox ROM and MacOS itself offer a fixed set of resolutions and depths
>>> based upon the display type. What I've done for now is default the display type to VGA since it
>>> offers both 640x480 and 800x600 in 1, 2, 4, 8, 16 and 24-bit colour which should cover the most
>>> common use of cases of people wanting to boot using the MacOS toolbox ROM.
>>>
>>> Even if you specify a default on the command line, MacOS still only cares about the display type and
>>> will allow you to change the resolution and depth dynamically, remembering the last resolution and
>>> depth across reboots.
>>>
>>> During testing I found that having access to the 1152x870 resolution offered by the Apple 21"
>>> monitor display type was useful to allow larger screen sizes, although only up to 8-bit depth so I
>>> added a bit of code that will switch from a VGA display type to a 21" display type if the graphics
>>> resolution is set to 1152x870x8.
>>>
>>> Finally if you boot a Linux kernel directly using -kernel then the provided XxYxD is placed directly
>>> into the relevant bootinfo fields with a VGA display type, unless a resolution of 1152x870x8 is
>>> specified in which case the 21" display type is used as above.
>>>
>>>> But, as a user, how do we know which modes are allowed with which resolution?
>>>>
>>>> Is possible to try to set internally the type here according to the resolution?
>>>>
>>>> Could you provide an command line example how to start the q800 with the 1152x870 resolution?
>>>
>>> Sure - simply add "-g 1152x870x8" to your command line. If the -g parameter is omitted then the
>>> display type will default to VGA.
>>>
>>
>> Thank you for the explanation.
>>
>> Perhaps you can add in the error message the list of the available mode and depth?
>> (it's not a blocker for the series, it can be added later)
>>
>> As an user, it's hard to know what are the allowed values.
> 
> This is where it becomes a bit trickier, since technically booting Linux with -kernel you can use
> any supported values as long as everything fits in the video RAM which is why there isn't currently
> a hard-coded list :)
> 

We need the list of "supported values". I don't want to read the code or try values combination
until it works.

In a perfect world, I would like to be able to use any value I want with "-kernel".

For instance I was using "-g 1200x800x24" and it was working fine.

Now I have:

qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24

If it's not possible (because the original hardware cannot provide it, and we don't know the base
address or things like that), we don't need the list of the display id, but the list of available
modes: (width,height,depth).

Rougly, something like:

qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
Available modes:
    1152x870x8
    1152x870x4
    1152x870x2
    1152x870x1
    800x600x24
    800x600x8
    800x600x4
    800x600x2
    800x600x1
    640x480x24
    640x480x8
    640x480x4
    640x480x2
    640x480x1

diff --git a/hw/display/macfb.c b/hw/display/macfb.c
index 5b8812e9e7d8..4b352eb89c3f 100644
--- a/hw/display/macfb.c
+++ b/hw/display/macfb.c
@@ -438,6 +438,26 @@ static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
     return NULL;
 }

+static gchar *macfb_mode_list(void)
+{
+    gchar *list = NULL;
+    gchar *mode;
+    MacFbMode *macfb_mode;
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
+        macfb_mode = &macfb_mode_table[i];
+
+        mode = g_strdup_printf("    %dx%dx%d\n", macfb_mode->width,
+                               macfb_mode->height, macfb_mode->depth);
+        list = g_strconcat(mode, list, NULL);
+        g_free(mode);
+    }
+
+    return list;
+}
+
+
 static void macfb_update_display(void *opaque)
 {
     MacfbState *s = opaque;
@@ -620,8 +640,13 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error **errp)

     s->mode = macfb_find_mode(s->type, s->width, s->height, s->depth);
     if (!s->mode) {
+        gchar *list;
         error_setg(errp, "unknown display mode: width %d, height %d, depth %d",
                    s->width, s->height, s->depth);
+        list =  macfb_mode_list();
+        error_append_hint(errp, "Available modes:\n%s", list);
+        g_free(list);
+
         return false;
     }


Thanks,
Laurent


Re: [PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Mark Cave-Ayland 4 years, 4 months ago
On 06/10/2021 13:24, Laurent Vivier wrote:

>> This is where it becomes a bit trickier, since technically booting Linux with -kernel you can use
>> any supported values as long as everything fits in the video RAM which is why there isn't currently
>> a hard-coded list :)
>>
> 
> We need the list of "supported values". I don't want to read the code or try values combination
> until it works.
> 
> In a perfect world, I would like to be able to use any value I want with "-kernel".
> 
> For instance I was using "-g 1200x800x24" and it was working fine.
> 
> Now I have:
> 
> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
> 
> If it's not possible (because the original hardware cannot provide it, and we don't know the base
> address or things like that), we don't need the list of the display id, but the list of available
> modes: (width,height,depth).
> 
> Rougly, something like:
> 
> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
> Available modes:
>      1152x870x8
>      1152x870x4
>      1152x870x2
>      1152x870x1
>      800x600x24
>      800x600x8
>      800x600x4
>      800x600x2
>      800x600x1
>      640x480x24
>      640x480x8
>      640x480x4
>      640x480x2
>      640x480x1
> 
> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
> index 5b8812e9e7d8..4b352eb89c3f 100644
> --- a/hw/display/macfb.c
> +++ b/hw/display/macfb.c
> @@ -438,6 +438,26 @@ static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
>       return NULL;
>   }
> 
> +static gchar *macfb_mode_list(void)
> +{
> +    gchar *list = NULL;
> +    gchar *mode;
> +    MacFbMode *macfb_mode;
> +    int i;
> +
> +    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
> +        macfb_mode = &macfb_mode_table[i];
> +
> +        mode = g_strdup_printf("    %dx%dx%d\n", macfb_mode->width,
> +                               macfb_mode->height, macfb_mode->depth);
> +        list = g_strconcat(mode, list, NULL);
> +        g_free(mode);
> +    }
> +
> +    return list;
> +}
> +
> +
>   static void macfb_update_display(void *opaque)
>   {
>       MacfbState *s = opaque;
> @@ -620,8 +640,13 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error **errp)
> 
>       s->mode = macfb_find_mode(s->type, s->width, s->height, s->depth);
>       if (!s->mode) {
> +        gchar *list;
>           error_setg(errp, "unknown display mode: width %d, height %d, depth %d",
>                      s->width, s->height, s->depth);
> +        list =  macfb_mode_list();
> +        error_append_hint(errp, "Available modes:\n%s", list);
> +        g_free(list);
> +
>           return false;
>       }

Hi Laurent,

Thanks for the example - I can certainly squash this into patch 8.

As for allowing extra resolutions via -kernel, since the check is being done in 
macfb_common_realize() then it would be possible to add a qdev property that only 
gets set when -kernel is used on the command line which bypasses the mode check if 
you prefer?

I'm not sure that your existing example of "-g 1200x800x24" (or indeed any resolution 
with 24-bit depth) with -kernel will still work after this patchset given that the 
24-bit encoding scheme has changed. Presumably this would also need a corresponding 
change in the bootinfo/kernel framebuffer/X configuration somewhere?


ATB,

Mark.

Re: [PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Laurent Vivier 4 years, 4 months ago
Le 06/10/2021 à 15:54, Mark Cave-Ayland a écrit :
> On 06/10/2021 13:24, Laurent Vivier wrote:
> 
>>> This is where it becomes a bit trickier, since technically booting Linux with -kernel you can use
>>> any supported values as long as everything fits in the video RAM which is why there isn't currently
>>> a hard-coded list :)
>>>
>>
>> We need the list of "supported values". I don't want to read the code or try values combination
>> until it works.
>>
>> In a perfect world, I would like to be able to use any value I want with "-kernel".
>>
>> For instance I was using "-g 1200x800x24" and it was working fine.
>>
>> Now I have:
>>
>> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
>>
>> If it's not possible (because the original hardware cannot provide it, and we don't know the base
>> address or things like that), we don't need the list of the display id, but the list of available
>> modes: (width,height,depth).
>>
>> Rougly, something like:
>>
>> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
>> Available modes:
>>      1152x870x8
>>      1152x870x4
>>      1152x870x2
>>      1152x870x1
>>      800x600x24
>>      800x600x8
>>      800x600x4
>>      800x600x2
>>      800x600x1
>>      640x480x24
>>      640x480x8
>>      640x480x4
>>      640x480x2
>>      640x480x1
>>
>> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
>> index 5b8812e9e7d8..4b352eb89c3f 100644
>> --- a/hw/display/macfb.c
>> +++ b/hw/display/macfb.c
>> @@ -438,6 +438,26 @@ static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
>>       return NULL;
>>   }
>>
>> +static gchar *macfb_mode_list(void)
>> +{
>> +    gchar *list = NULL;
>> +    gchar *mode;
>> +    MacFbMode *macfb_mode;
>> +    int i;
>> +
>> +    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
>> +        macfb_mode = &macfb_mode_table[i];
>> +
>> +        mode = g_strdup_printf("    %dx%dx%d\n", macfb_mode->width,
>> +                               macfb_mode->height, macfb_mode->depth);
>> +        list = g_strconcat(mode, list, NULL);
>> +        g_free(mode);
>> +    }
>> +
>> +    return list;
>> +}
>> +
>> +
>>   static void macfb_update_display(void *opaque)
>>   {
>>       MacfbState *s = opaque;
>> @@ -620,8 +640,13 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error **errp)
>>
>>       s->mode = macfb_find_mode(s->type, s->width, s->height, s->depth);
>>       if (!s->mode) {
>> +        gchar *list;
>>           error_setg(errp, "unknown display mode: width %d, height %d, depth %d",
>>                      s->width, s->height, s->depth);
>> +        list =  macfb_mode_list();
>> +        error_append_hint(errp, "Available modes:\n%s", list);
>> +        g_free(list);
>> +
>>           return false;
>>       }
> 
> Hi Laurent,
> 
> Thanks for the example - I can certainly squash this into patch 8.

yes, please.

> As for allowing extra resolutions via -kernel, since the check is being done in
> macfb_common_realize() then it would be possible to add a qdev property that only gets set when
> -kernel is used on the command line which bypasses the mode check if you prefer?
>

I think it can wait and be done by a patch later. For the moment we can focus on MacOS.

> I'm not sure that your existing example of "-g 1200x800x24" (or indeed any resolution with 24-bit
> depth) with -kernel will still work after this patchset given that the 24-bit encoding scheme has
> changed. Presumably this would also need a corresponding change in the bootinfo/kernel framebuffer/X
> configuration somewhere?

The kernel framebuffer should be easy to fix, if needed, normally we pass the needed information via
the bootinfo structure.

My X configuration is broken for a while. With debian/sid I've never been able to start X (even on a
real q800, I think), and with debian/etch we need a special kernel as the ADB stack has been broken
with old kernel. I was not able to start X for a while now...

And GNOME desktop is not available on debian/sid m68k (some packages are missing). Perhaps I should
try Xfce.

So, don't worry about that...

Thanks,
Laurent

Re: [PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Mark Cave-Ayland 4 years, 4 months ago
On 06/10/2021 16:46, Laurent Vivier wrote:
> Le 06/10/2021 à 15:54, Mark Cave-Ayland a écrit :
>> On 06/10/2021 13:24, Laurent Vivier wrote:
>>
>>>> This is where it becomes a bit trickier, since technically booting Linux with -kernel you can use
>>>> any supported values as long as everything fits in the video RAM which is why there isn't currently
>>>> a hard-coded list :)
>>>>
>>>
>>> We need the list of "supported values". I don't want to read the code or try values combination
>>> until it works.
>>>
>>> In a perfect world, I would like to be able to use any value I want with "-kernel".
>>>
>>> For instance I was using "-g 1200x800x24" and it was working fine.
>>>
>>> Now I have:
>>>
>>> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
>>>
>>> If it's not possible (because the original hardware cannot provide it, and we don't know the base
>>> address or things like that), we don't need the list of the display id, but the list of available
>>> modes: (width,height,depth).
>>>
>>> Rougly, something like:
>>>
>>> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
>>> Available modes:
>>>       1152x870x8
>>>       1152x870x4
>>>       1152x870x2
>>>       1152x870x1
>>>       800x600x24
>>>       800x600x8
>>>       800x600x4
>>>       800x600x2
>>>       800x600x1
>>>       640x480x24
>>>       640x480x8
>>>       640x480x4
>>>       640x480x2
>>>       640x480x1
>>>
>>> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
>>> index 5b8812e9e7d8..4b352eb89c3f 100644
>>> --- a/hw/display/macfb.c
>>> +++ b/hw/display/macfb.c
>>> @@ -438,6 +438,26 @@ static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
>>>        return NULL;
>>>    }
>>>
>>> +static gchar *macfb_mode_list(void)
>>> +{
>>> +    gchar *list = NULL;
>>> +    gchar *mode;
>>> +    MacFbMode *macfb_mode;
>>> +    int i;
>>> +
>>> +    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
>>> +        macfb_mode = &macfb_mode_table[i];
>>> +
>>> +        mode = g_strdup_printf("    %dx%dx%d\n", macfb_mode->width,
>>> +                               macfb_mode->height, macfb_mode->depth);
>>> +        list = g_strconcat(mode, list, NULL);
>>> +        g_free(mode);
>>> +    }
>>> +
>>> +    return list;
>>> +}
>>> +
>>> +
>>>    static void macfb_update_display(void *opaque)
>>>    {
>>>        MacfbState *s = opaque;
>>> @@ -620,8 +640,13 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error **errp)
>>>
>>>        s->mode = macfb_find_mode(s->type, s->width, s->height, s->depth);
>>>        if (!s->mode) {
>>> +        gchar *list;
>>>            error_setg(errp, "unknown display mode: width %d, height %d, depth %d",
>>>                       s->width, s->height, s->depth);
>>> +        list =  macfb_mode_list();
>>> +        error_append_hint(errp, "Available modes:\n%s", list);
>>> +        g_free(list);
>>> +
>>>            return false;
>>>        }
>>
>> Hi Laurent,
>>
>> Thanks for the example - I can certainly squash this into patch 8.
> 
> yes, please.

Okay I'll do that for a v3 (and also split the 1st patch that Phil suggested).

>> As for allowing extra resolutions via -kernel, since the check is being done in
>> macfb_common_realize() then it would be possible to add a qdev property that only gets set when
>> -kernel is used on the command line which bypasses the mode check if you prefer?
>>
> 
> I think it can wait and be done by a patch later. For the moment we can focus on MacOS.
> 
>> I'm not sure that your existing example of "-g 1200x800x24" (or indeed any resolution with 24-bit
>> depth) with -kernel will still work after this patchset given that the 24-bit encoding scheme has
>> changed. Presumably this would also need a corresponding change in the bootinfo/kernel framebuffer/X
>> configuration somewhere?
> 
> The kernel framebuffer should be easy to fix, if needed, normally we pass the needed information via
> the bootinfo structure.
> 
> My X configuration is broken for a while. With debian/sid I've never been able to start X (even on a
> real q800, I think), and with debian/etch we need a special kernel as the ADB stack has been broken
> with old kernel. I was not able to start X for a while now...

FWIW I found that the last set of ADB fixes in mac_via.c actually fixed ADB on old 
kernels again (I was able to use keyboard and mouse on the 4.15 kernel you used for 
the original patches), so you may be able to get debian/etch working in QEMU. I'd 
expect forcing EMILE into a 24-bit depth on a real Quadra 800 would also show the 
same issue here.

> And GNOME desktop is not available on debian/sid m68k (some packages are missing). Perhaps I should
> try Xfce.
> 
> So, don't worry about that...

Alright, thanks. I'll see if I can get v3 posted later this evening...


ATB,

Mark.

Re: [PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Laurent Vivier 4 years, 4 months ago
Le 06/10/2021 à 18:09, Mark Cave-Ayland a écrit :
> On 06/10/2021 16:46, Laurent Vivier wrote:
>> Le 06/10/2021 à 15:54, Mark Cave-Ayland a écrit :
>>> On 06/10/2021 13:24, Laurent Vivier wrote:
>>>
>>>>> This is where it becomes a bit trickier, since technically booting Linux with -kernel you can use
>>>>> any supported values as long as everything fits in the video RAM which is why there isn't
>>>>> currently
>>>>> a hard-coded list :)
>>>>>
>>>>
>>>> We need the list of "supported values". I don't want to read the code or try values combination
>>>> until it works.
>>>>
>>>> In a perfect world, I would like to be able to use any value I want with "-kernel".
>>>>
>>>> For instance I was using "-g 1200x800x24" and it was working fine.
>>>>
>>>> Now I have:
>>>>
>>>> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
>>>>
>>>> If it's not possible (because the original hardware cannot provide it, and we don't know the base
>>>> address or things like that), we don't need the list of the display id, but the list of available
>>>> modes: (width,height,depth).
>>>>
>>>> Rougly, something like:
>>>>
>>>> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
>>>> Available modes:
>>>>       1152x870x8
>>>>       1152x870x4
>>>>       1152x870x2
>>>>       1152x870x1
>>>>       800x600x24
>>>>       800x600x8
>>>>       800x600x4
>>>>       800x600x2
>>>>       800x600x1
>>>>       640x480x24
>>>>       640x480x8
>>>>       640x480x4
>>>>       640x480x2
>>>>       640x480x1
>>>>
>>>> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
>>>> index 5b8812e9e7d8..4b352eb89c3f 100644
>>>> --- a/hw/display/macfb.c
>>>> +++ b/hw/display/macfb.c
>>>> @@ -438,6 +438,26 @@ static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
>>>>        return NULL;
>>>>    }
>>>>
>>>> +static gchar *macfb_mode_list(void)
>>>> +{
>>>> +    gchar *list = NULL;
>>>> +    gchar *mode;
>>>> +    MacFbMode *macfb_mode;
>>>> +    int i;
>>>> +
>>>> +    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
>>>> +        macfb_mode = &macfb_mode_table[i];
>>>> +
>>>> +        mode = g_strdup_printf("    %dx%dx%d\n", macfb_mode->width,
>>>> +                               macfb_mode->height, macfb_mode->depth);
>>>> +        list = g_strconcat(mode, list, NULL);
>>>> +        g_free(mode);
>>>> +    }
>>>> +
>>>> +    return list;
>>>> +}
>>>> +
>>>> +
>>>>    static void macfb_update_display(void *opaque)
>>>>    {
>>>>        MacfbState *s = opaque;
>>>> @@ -620,8 +640,13 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error
>>>> **errp)
>>>>
>>>>        s->mode = macfb_find_mode(s->type, s->width, s->height, s->depth);
>>>>        if (!s->mode) {
>>>> +        gchar *list;
>>>>            error_setg(errp, "unknown display mode: width %d, height %d, depth %d",
>>>>                       s->width, s->height, s->depth);
>>>> +        list =  macfb_mode_list();
>>>> +        error_append_hint(errp, "Available modes:\n%s", list);
>>>> +        g_free(list);
>>>> +
>>>>            return false;
>>>>        }
>>>
>>> Hi Laurent,
>>>
>>> Thanks for the example - I can certainly squash this into patch 8.
>>
>> yes, please.
> 
> Okay I'll do that for a v3 (and also split the 1st patch that Phil suggested).
> 
>>> As for allowing extra resolutions via -kernel, since the check is being done in
>>> macfb_common_realize() then it would be possible to add a qdev property that only gets set when
>>> -kernel is used on the command line which bypasses the mode check if you prefer?
>>>
>>
>> I think it can wait and be done by a patch later. For the moment we can focus on MacOS.
>>
>>> I'm not sure that your existing example of "-g 1200x800x24" (or indeed any resolution with 24-bit
>>> depth) with -kernel will still work after this patchset given that the 24-bit encoding scheme has
>>> changed. Presumably this would also need a corresponding change in the bootinfo/kernel framebuffer/X
>>> configuration somewhere?
>>
>> The kernel framebuffer should be easy to fix, if needed, normally we pass the needed information via
>> the bootinfo structure.
>>
>> My X configuration is broken for a while. With debian/sid I've never been able to start X (even on a
>> real q800, I think), and with debian/etch we need a special kernel as the ADB stack has been broken
>> with old kernel. I was not able to start X for a while now...
> 
> FWIW I found that the last set of ADB fixes in mac_via.c actually fixed ADB on old kernels again (I
> was able to use keyboard and mouse on the 4.15 kernel you used for the original patches), so you may
> be able to get debian/etch working in QEMU. I'd expect forcing EMILE into a 24-bit depth on a real
> Quadra 800 would also show the same issue here.
> 

In fact, I was trying the etch kernel, 2.6.32 that was never able to boot before because VBL
interrupt was not implemented. Now, with your series it boots (congratulation) but there is some
other issues in ADB but I don't think it's related to the changes in QEMU.

I've found another kernel on my disk (4.1.39) and I'm able to start a gnome-session with 1152x870x8
mode. ADB works well. There is an issue with gdm that doesn't take characters from the keyboard but
if I start X manually and then gnome-sessions I'm able to play with it.

Thanks,
Laurent

Re: [PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Laurent Vivier 4 years, 4 months ago
Le 06/10/2021 à 21:24, Laurent Vivier a écrit :
> Le 06/10/2021 à 18:09, Mark Cave-Ayland a écrit :
>> On 06/10/2021 16:46, Laurent Vivier wrote:
>>> Le 06/10/2021 à 15:54, Mark Cave-Ayland a écrit :
>>>> On 06/10/2021 13:24, Laurent Vivier wrote:
>>>>
>>>>>> This is where it becomes a bit trickier, since technically booting Linux with -kernel you can use
>>>>>> any supported values as long as everything fits in the video RAM which is why there isn't
>>>>>> currently
>>>>>> a hard-coded list :)
>>>>>>
>>>>>
>>>>> We need the list of "supported values". I don't want to read the code or try values combination
>>>>> until it works.
>>>>>
>>>>> In a perfect world, I would like to be able to use any value I want with "-kernel".
>>>>>
>>>>> For instance I was using "-g 1200x800x24" and it was working fine.
>>>>>
>>>>> Now I have:
>>>>>
>>>>> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
>>>>>
>>>>> If it's not possible (because the original hardware cannot provide it, and we don't know the base
>>>>> address or things like that), we don't need the list of the display id, but the list of available
>>>>> modes: (width,height,depth).
>>>>>
>>>>> Rougly, something like:
>>>>>
>>>>> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
>>>>> Available modes:
>>>>>       1152x870x8
>>>>>       1152x870x4
>>>>>       1152x870x2
>>>>>       1152x870x1
>>>>>       800x600x24
>>>>>       800x600x8
>>>>>       800x600x4
>>>>>       800x600x2
>>>>>       800x600x1
>>>>>       640x480x24
>>>>>       640x480x8
>>>>>       640x480x4
>>>>>       640x480x2
>>>>>       640x480x1
>>>>>
>>>>> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
>>>>> index 5b8812e9e7d8..4b352eb89c3f 100644
>>>>> --- a/hw/display/macfb.c
>>>>> +++ b/hw/display/macfb.c
>>>>> @@ -438,6 +438,26 @@ static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
>>>>>        return NULL;
>>>>>    }
>>>>>
>>>>> +static gchar *macfb_mode_list(void)
>>>>> +{
>>>>> +    gchar *list = NULL;
>>>>> +    gchar *mode;
>>>>> +    MacFbMode *macfb_mode;
>>>>> +    int i;
>>>>> +
>>>>> +    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
>>>>> +        macfb_mode = &macfb_mode_table[i];
>>>>> +
>>>>> +        mode = g_strdup_printf("    %dx%dx%d\n", macfb_mode->width,
>>>>> +                               macfb_mode->height, macfb_mode->depth);
>>>>> +        list = g_strconcat(mode, list, NULL);
>>>>> +        g_free(mode);
>>>>> +    }
>>>>> +
>>>>> +    return list;
>>>>> +}
>>>>> +
>>>>> +
>>>>>    static void macfb_update_display(void *opaque)
>>>>>    {
>>>>>        MacfbState *s = opaque;
>>>>> @@ -620,8 +640,13 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error
>>>>> **errp)
>>>>>
>>>>>        s->mode = macfb_find_mode(s->type, s->width, s->height, s->depth);
>>>>>        if (!s->mode) {
>>>>> +        gchar *list;
>>>>>            error_setg(errp, "unknown display mode: width %d, height %d, depth %d",
>>>>>                       s->width, s->height, s->depth);
>>>>> +        list =  macfb_mode_list();
>>>>> +        error_append_hint(errp, "Available modes:\n%s", list);
>>>>> +        g_free(list);
>>>>> +
>>>>>            return false;
>>>>>        }
>>>>
>>>> Hi Laurent,
>>>>
>>>> Thanks for the example - I can certainly squash this into patch 8.
>>>
>>> yes, please.
>>
>> Okay I'll do that for a v3 (and also split the 1st patch that Phil suggested).
>>
>>>> As for allowing extra resolutions via -kernel, since the check is being done in
>>>> macfb_common_realize() then it would be possible to add a qdev property that only gets set when
>>>> -kernel is used on the command line which bypasses the mode check if you prefer?
>>>>
>>>
>>> I think it can wait and be done by a patch later. For the moment we can focus on MacOS.
>>>
>>>> I'm not sure that your existing example of "-g 1200x800x24" (or indeed any resolution with 24-bit
>>>> depth) with -kernel will still work after this patchset given that the 24-bit encoding scheme has
>>>> changed. Presumably this would also need a corresponding change in the bootinfo/kernel framebuffer/X
>>>> configuration somewhere?
>>>
>>> The kernel framebuffer should be easy to fix, if needed, normally we pass the needed information via
>>> the bootinfo structure.
>>>
>>> My X configuration is broken for a while. With debian/sid I've never been able to start X (even on a
>>> real q800, I think), and with debian/etch we need a special kernel as the ADB stack has been broken
>>> with old kernel. I was not able to start X for a while now...
>>
>> FWIW I found that the last set of ADB fixes in mac_via.c actually fixed ADB on old kernels again (I
>> was able to use keyboard and mouse on the 4.15 kernel you used for the original patches), so you may
>> be able to get debian/etch working in QEMU. I'd expect forcing EMILE into a 24-bit depth on a real
>> Quadra 800 would also show the same issue here.
>>
> 
> In fact, I was trying the etch kernel, 2.6.32 that was never able to boot before because VBL
> interrupt was not implemented. Now, with your series it boots (congratulation) but there is some
> other issues in ADB but I don't think it's related to the changes in QEMU.
> 
> I've found another kernel on my disk (4.1.39) and I'm able to start a gnome-session with 1152x870x8
> mode. ADB works well. There is an issue with gdm that doesn't take characters from the keyboard but
> if I start X manually and then gnome-sessions I'm able to play with it.

And I'm able to run a 800x600x24 session with the attached xorg.conf

To run 1152x870, the DefaultDepth and DefaultFbBpp must be changed to 8.

Thanks,
Laurent


# /etc/X11/xorg.conf (xorg X Window System server configuration file)
#
# This file was generated by dexconf, the Debian X Configuration tool, using
# values from the debconf database.
#
# Edit this file with caution, and see the /etc/X11/xorg.conf manual page.
# (Type "man /etc/X11/xorg.conf" at the shell prompt.)
#
# This file is automatically updated on xserver-xorg package upgrades *only*
# if it has not been modified since the last upgrade of the xserver-xorg
# package.
#
# If you have edited this file but would like it to be automatically updated
# again, run the following command:
#   sudo dpkg-reconfigure -phigh xserver-xorg

Section "Files"
	FontPath	"/usr/share/fonts/X11/misc"
	FontPath	"/usr/X11R6/lib/X11/fonts/misc"
	FontPath	"/usr/share/fonts/X11/cyrillic"
	FontPath	"/usr/X11R6/lib/X11/fonts/cyrillic"
	FontPath	"/usr/share/fonts/X11/100dpi/:unscaled"
	FontPath	"/usr/X11R6/lib/X11/fonts/100dpi/:unscaled"
	FontPath	"/usr/share/fonts/X11/75dpi/:unscaled"
	FontPath	"/usr/X11R6/lib/X11/fonts/75dpi/:unscaled"
	FontPath	"/usr/share/fonts/X11/Type1"
	FontPath	"/usr/X11R6/lib/X11/fonts/Type1"
	FontPath	"/usr/share/fonts/X11/100dpi"
	FontPath	"/usr/X11R6/lib/X11/fonts/100dpi"
	FontPath	"/usr/share/fonts/X11/75dpi"
	FontPath	"/usr/X11R6/lib/X11/fonts/75dpi"
	# path to defoma fonts
	FontPath	"/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType"
EndSection

Section "Module"
	Load	"i2c"
	Load	"bitmap"
	Load	"ddc"
	Load	"dri"
	Load	"extmod"
	Load	"freetype"
	Load	"glx"
	Load	"int10"
	Load	"vbe"
EndSection

Section "InputDevice"
	Identifier	"Generic Keyboard"
	Driver		"keyboard"
	Option		"CoreKeyboard"
	Option		"XkbRules"	"xorg"
	Option		"XkbModel"	"macintosh"
	Option		"XkbLayout"	"us"
EndSection

Section "InputDevice"
	Identifier	"Configured Mouse"
	Driver		"mouse"
	Option		"CorePointer"
	Option		"Device"		"/dev/input/mice"
	Option		"Protocol"		"ImPS/2"
	Option		"Emulate3Buttons"	"true"
EndSection

Section "Device"
	Identifier	"Generic Video Card"
	Driver		"fbdev"
	Option		"UseFBDev"		"true"
EndSection

Section "Monitor"
	Identifier	"Generic Monitor"
	Option		"DPMS"
	HorizSync	28-60
	VertRefresh	43-60
EndSection

Section "Screen"
	Identifier	"Default Screen"
	Device		"Generic Video Card"
	Monitor		"Generic Monitor"
	DefaultDepth 24
	DefaultFbBpp 32
	SubSection "Display"
		Depth		1
		Modes		"1152x870" "800x600" "640x480"
	EndSubSection
	SubSection "Display"
		Depth		4
		Modes		"1152x870" "800x600" "640x480"
	EndSubSection
	SubSection "Display"
		Depth		8
		Modes		"1152x870" "800x600" "640x480"
	EndSubSection
	SubSection "Display"
		Depth		15
		Modes		"800x600" "640x480"
	EndSubSection
	SubSection "Display"
		Depth		16
		Modes		"800x600" "640x480"
	EndSubSection
	SubSection "Display"
		Depth		24
                FbBpp    32
		Modes		"800x600" "640x480"
	EndSubSection
EndSection

Section "ServerLayout"
	Identifier	"Default Layout"
	Screen		"Default Screen"
	InputDevice	"Generic Keyboard"
	InputDevice	"Configured Mouse"
EndSection

Section "DRI"
	Mode	0666
EndSection
Re: [PATCH v2 08/12] macfb: add common monitor modes supported by the MacOS toolbox ROM
Posted by Mark Cave-Ayland 4 years, 4 months ago
On 06/10/2021 22:16, Laurent Vivier wrote:

> Le 06/10/2021 à 21:24, Laurent Vivier a écrit :
>> Le 06/10/2021 à 18:09, Mark Cave-Ayland a écrit :
>>> On 06/10/2021 16:46, Laurent Vivier wrote:
>>>> Le 06/10/2021 à 15:54, Mark Cave-Ayland a écrit :
>>>>> On 06/10/2021 13:24, Laurent Vivier wrote:
>>>>>
>>>>>>> This is where it becomes a bit trickier, since technically booting Linux with -kernel you can use
>>>>>>> any supported values as long as everything fits in the video RAM which is why there isn't
>>>>>>> currently
>>>>>>> a hard-coded list :)
>>>>>>>
>>>>>>
>>>>>> We need the list of "supported values". I don't want to read the code or try values combination
>>>>>> until it works.
>>>>>>
>>>>>> In a perfect world, I would like to be able to use any value I want with "-kernel".
>>>>>>
>>>>>> For instance I was using "-g 1200x800x24" and it was working fine.
>>>>>>
>>>>>> Now I have:
>>>>>>
>>>>>> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
>>>>>>
>>>>>> If it's not possible (because the original hardware cannot provide it, and we don't know the base
>>>>>> address or things like that), we don't need the list of the display id, but the list of available
>>>>>> modes: (width,height,depth).
>>>>>>
>>>>>> Rougly, something like:
>>>>>>
>>>>>> qemu-system-m68k: unknown display mode: width 1200, height 800, depth 24
>>>>>> Available modes:
>>>>>>        1152x870x8
>>>>>>        1152x870x4
>>>>>>        1152x870x2
>>>>>>        1152x870x1
>>>>>>        800x600x24
>>>>>>        800x600x8
>>>>>>        800x600x4
>>>>>>        800x600x2
>>>>>>        800x600x1
>>>>>>        640x480x24
>>>>>>        640x480x8
>>>>>>        640x480x4
>>>>>>        640x480x2
>>>>>>        640x480x1
>>>>>>
>>>>>> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
>>>>>> index 5b8812e9e7d8..4b352eb89c3f 100644
>>>>>> --- a/hw/display/macfb.c
>>>>>> +++ b/hw/display/macfb.c
>>>>>> @@ -438,6 +438,26 @@ static MacFbMode *macfb_find_mode(MacfbDisplayType display_type,
>>>>>>         return NULL;
>>>>>>     }
>>>>>>
>>>>>> +static gchar *macfb_mode_list(void)
>>>>>> +{
>>>>>> +    gchar *list = NULL;
>>>>>> +    gchar *mode;
>>>>>> +    MacFbMode *macfb_mode;
>>>>>> +    int i;
>>>>>> +
>>>>>> +    for (i = 0; i < ARRAY_SIZE(macfb_mode_table); i++) {
>>>>>> +        macfb_mode = &macfb_mode_table[i];
>>>>>> +
>>>>>> +        mode = g_strdup_printf("    %dx%dx%d\n", macfb_mode->width,
>>>>>> +                               macfb_mode->height, macfb_mode->depth);
>>>>>> +        list = g_strconcat(mode, list, NULL);
>>>>>> +        g_free(mode);
>>>>>> +    }
>>>>>> +
>>>>>> +    return list;
>>>>>> +}
>>>>>> +
>>>>>> +
>>>>>>     static void macfb_update_display(void *opaque)
>>>>>>     {
>>>>>>         MacfbState *s = opaque;
>>>>>> @@ -620,8 +640,13 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error
>>>>>> **errp)
>>>>>>
>>>>>>         s->mode = macfb_find_mode(s->type, s->width, s->height, s->depth);
>>>>>>         if (!s->mode) {
>>>>>> +        gchar *list;
>>>>>>             error_setg(errp, "unknown display mode: width %d, height %d, depth %d",
>>>>>>                        s->width, s->height, s->depth);
>>>>>> +        list =  macfb_mode_list();
>>>>>> +        error_append_hint(errp, "Available modes:\n%s", list);
>>>>>> +        g_free(list);
>>>>>> +
>>>>>>             return false;
>>>>>>         }
>>>>>
>>>>> Hi Laurent,
>>>>>
>>>>> Thanks for the example - I can certainly squash this into patch 8.
>>>>
>>>> yes, please.
>>>
>>> Okay I'll do that for a v3 (and also split the 1st patch that Phil suggested).
>>>
>>>>> As for allowing extra resolutions via -kernel, since the check is being done in
>>>>> macfb_common_realize() then it would be possible to add a qdev property that only gets set when
>>>>> -kernel is used on the command line which bypasses the mode check if you prefer?
>>>>>
>>>>
>>>> I think it can wait and be done by a patch later. For the moment we can focus on MacOS.
>>>>
>>>>> I'm not sure that your existing example of "-g 1200x800x24" (or indeed any resolution with 24-bit
>>>>> depth) with -kernel will still work after this patchset given that the 24-bit encoding scheme has
>>>>> changed. Presumably this would also need a corresponding change in the bootinfo/kernel framebuffer/X
>>>>> configuration somewhere?
>>>>
>>>> The kernel framebuffer should be easy to fix, if needed, normally we pass the needed information via
>>>> the bootinfo structure.
>>>>
>>>> My X configuration is broken for a while. With debian/sid I've never been able to start X (even on a
>>>> real q800, I think), and with debian/etch we need a special kernel as the ADB stack has been broken
>>>> with old kernel. I was not able to start X for a while now...
>>>
>>> FWIW I found that the last set of ADB fixes in mac_via.c actually fixed ADB on old kernels again (I
>>> was able to use keyboard and mouse on the 4.15 kernel you used for the original patches), so you may
>>> be able to get debian/etch working in QEMU. I'd expect forcing EMILE into a 24-bit depth on a real
>>> Quadra 800 would also show the same issue here.
>>>
>>
>> In fact, I was trying the etch kernel, 2.6.32 that was never able to boot before because VBL
>> interrupt was not implemented. Now, with your series it boots (congratulation) but there is some
>> other issues in ADB but I don't think it's related to the changes in QEMU.

That's definitely progress! There are a couple of extra ADB fixes in my gitlab 
q800.upstream branch for NetBSD which may or may not help here?

>> I've found another kernel on my disk (4.1.39) and I'm able to start a gnome-session with 1152x870x8
>> mode. ADB works well. There is an issue with gdm that doesn't take characters from the keyboard but
>> if I start X manually and then gnome-sessions I'm able to play with it.
> 
> And I'm able to run a 800x600x24 session with the attached xorg.conf
> 
> To run 1152x870, the DefaultDepth and DefaultFbBpp must be changed to 8.

Excellent - thanks for the example config. Assuming that this is matching the 
behaviour on the real Quadra 800 then I'm happy these patches are moving the 
emulation in the right direction :)


ATB,

Mark.