Message ID | 20211002110007.30825-7-mark.cave-ayland@ilande.co.uk (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | macfb: fixes for booting MacOS | expand |
Le 02/10/2021 à 13:00, Mark Cave-Ayland a écrit : > The MacOS toolbox ROM uses the monitor sense to detect the display type and then > offer a fixed set of resolutions and colour depths accordingly. Implement the > monitor sense using information found in Apple Technical Note HW26: "Macintosh > Quadra Built-In Video" along with some local experiments. > > Since the default configuration is 640 x 480 with 8-bit colour then hardcode > the sense register to return MACFB_DISPLAY_VGA for now. > > Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> > --- > hw/display/macfb.c | 117 ++++++++++++++++++++++++++++++++++++- > hw/display/trace-events | 2 + > include/hw/display/macfb.h | 20 +++++++ > 3 files changed, 137 insertions(+), 2 deletions(-) > > diff --git a/hw/display/macfb.c b/hw/display/macfb.c > index 62c2727a5b..5c95aa4a11 100644 > --- a/hw/display/macfb.c > +++ b/hw/display/macfb.c > @@ -28,8 +28,66 @@ > #define MACFB_PAGE_SIZE 4096 > #define MACFB_VRAM_SIZE (4 * MiB) > > -#define DAFB_RESET 0x200 > -#define DAFB_LUT 0x213 > +#define DAFB_MODE_SENSE 0x1c > +#define DAFB_RESET 0x200 > +#define DAFB_LUT 0x213 > + > + > +/* > + * Quadra sense codes taken from Apple Technical Note HW26: > + * "Macintosh Quadra Built-In Video". The sense codes and https://developer.apple.com/library/archive/technotes/hw/hw_26.html > + * extended sense codes have different meanings: > + * > + * Sense: > + * bit 2: SENSE2 (pin 10) > + * bit 1: SENSE1 (pin 7) > + * bit 0: SENSE0 (pin 4) > + * > + * 0 = pin tied to ground > + * 1 = pin unconnected > + * > + * Extended Sense: > + * bit 2: pins 4-10 > + * bit 1: pins 10-7 > + * bit 0: pins 7-4 > + * > + * 0 = pins tied together > + * 1 = pins unconnected > + * > + * Reads from the sense register appear to be active low, i.e. a 1 indicates > + * that the pin is tied to ground, a 0 indicates the pin is disconnected. > + * > + * Writes to the sense register appear to activate pulldowns i.e. a 1 enables > + * a pulldown on a particular pin. > + * > + * The MacOS toolbox appears to use a series of reads and writes to first > + * determine if extended sense is to be used, and then check which pins are > + * tied together in order to determine the display type. > + */ > + > +typedef struct MacFbSense { > + uint8_t type; > + uint8_t sense; > + uint8_t ext_sense; > +} MacFbSense; > + > +static MacFbSense macfb_sense_table[] = { > + { MACFB_DISPLAY_APPLE_21_COLOR, 0x0, 0 }, > + { MACFB_DISPLAY_APPLE_PORTRAIT, 0x1, 0 }, > + { MACFB_DISPLAY_APPLE_12_RGB, 0x2, 0 }, > + { MACFB_DISPLAY_APPLE_2PAGE_MONO, 0x3, 0 }, > + { MACFB_DISPLAY_NTSC_UNDERSCAN, 0x4, 0 }, > + { MACFB_DISPLAY_NTSC_OVERSCAN, 0x4, 0 }, > + { MACFB_DISPLAY_APPLE_12_MONO, 0x6, 0 }, > + { MACFB_DISPLAY_APPLE_13_RGB, 0x6, 0 }, > + { MACFB_DISPLAY_16_COLOR, 0x7, 0x3 }, > + { MACFB_DISPLAY_PAL1_UNDERSCAN, 0x7, 0x0 }, > + { MACFB_DISPLAY_PAL1_OVERSCAN, 0x7, 0x0 }, > + { MACFB_DISPLAY_PAL2_UNDERSCAN, 0x7, 0x6 }, > + { MACFB_DISPLAY_PAL2_OVERSCAN, 0x7, 0x6 }, > + { MACFB_DISPLAY_VGA, 0x7, 0x5 }, > + { MACFB_DISPLAY_SVGA, 0x7, 0x5 }, Perhaps it could be interesting to also have the "no external monitor" entry? But generally not to have monitor prevents the boot of MacOS. ... Reviewed-by: Laurent Vivier <laurent@vivier.eu>
On Mon, 4 Oct 2021, Laurent Vivier wrote: > Le 02/10/2021 à 13:00, Mark Cave-Ayland a écrit : >> The MacOS toolbox ROM uses the monitor sense to detect the display type and then >> offer a fixed set of resolutions and colour depths accordingly. Implement the >> monitor sense using information found in Apple Technical Note HW26: "Macintosh >> Quadra Built-In Video" along with some local experiments. >> >> Since the default configuration is 640 x 480 with 8-bit colour then hardcode >> the sense register to return MACFB_DISPLAY_VGA for now. >> >> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> >> --- >> hw/display/macfb.c | 117 ++++++++++++++++++++++++++++++++++++- >> hw/display/trace-events | 2 + >> include/hw/display/macfb.h | 20 +++++++ >> 3 files changed, 137 insertions(+), 2 deletions(-) >> >> diff --git a/hw/display/macfb.c b/hw/display/macfb.c >> index 62c2727a5b..5c95aa4a11 100644 >> --- a/hw/display/macfb.c >> +++ b/hw/display/macfb.c >> @@ -28,8 +28,66 @@ >> #define MACFB_PAGE_SIZE 4096 >> #define MACFB_VRAM_SIZE (4 * MiB) >> >> -#define DAFB_RESET 0x200 >> -#define DAFB_LUT 0x213 >> +#define DAFB_MODE_SENSE 0x1c >> +#define DAFB_RESET 0x200 >> +#define DAFB_LUT 0x213 >> + >> + >> +/* >> + * Quadra sense codes taken from Apple Technical Note HW26: >> + * "Macintosh Quadra Built-In Video". The sense codes and > > https://developer.apple.com/library/archive/technotes/hw/hw_26.html URLs may change or go away so I think it's better to reference by title in comments, then one can find it by that whereas a stale URL is not much help a few years from now. Regards, BALATON Zoltan >> + * extended sense codes have different meanings: >> + * >> + * Sense: >> + * bit 2: SENSE2 (pin 10) >> + * bit 1: SENSE1 (pin 7) >> + * bit 0: SENSE0 (pin 4) >> + * >> + * 0 = pin tied to ground >> + * 1 = pin unconnected >> + * >> + * Extended Sense: >> + * bit 2: pins 4-10 >> + * bit 1: pins 10-7 >> + * bit 0: pins 7-4 >> + * >> + * 0 = pins tied together >> + * 1 = pins unconnected >> + * >> + * Reads from the sense register appear to be active low, i.e. a 1 indicates >> + * that the pin is tied to ground, a 0 indicates the pin is disconnected. >> + * >> + * Writes to the sense register appear to activate pulldowns i.e. a 1 enables >> + * a pulldown on a particular pin. >> + * >> + * The MacOS toolbox appears to use a series of reads and writes to first >> + * determine if extended sense is to be used, and then check which pins are >> + * tied together in order to determine the display type. >> + */ >> + >> +typedef struct MacFbSense { >> + uint8_t type; >> + uint8_t sense; >> + uint8_t ext_sense; >> +} MacFbSense; >> + >> +static MacFbSense macfb_sense_table[] = { >> + { MACFB_DISPLAY_APPLE_21_COLOR, 0x0, 0 }, >> + { MACFB_DISPLAY_APPLE_PORTRAIT, 0x1, 0 }, >> + { MACFB_DISPLAY_APPLE_12_RGB, 0x2, 0 }, >> + { MACFB_DISPLAY_APPLE_2PAGE_MONO, 0x3, 0 }, >> + { MACFB_DISPLAY_NTSC_UNDERSCAN, 0x4, 0 }, >> + { MACFB_DISPLAY_NTSC_OVERSCAN, 0x4, 0 }, >> + { MACFB_DISPLAY_APPLE_12_MONO, 0x6, 0 }, >> + { MACFB_DISPLAY_APPLE_13_RGB, 0x6, 0 }, >> + { MACFB_DISPLAY_16_COLOR, 0x7, 0x3 }, >> + { MACFB_DISPLAY_PAL1_UNDERSCAN, 0x7, 0x0 }, >> + { MACFB_DISPLAY_PAL1_OVERSCAN, 0x7, 0x0 }, >> + { MACFB_DISPLAY_PAL2_UNDERSCAN, 0x7, 0x6 }, >> + { MACFB_DISPLAY_PAL2_OVERSCAN, 0x7, 0x6 }, >> + { MACFB_DISPLAY_VGA, 0x7, 0x5 }, >> + { MACFB_DISPLAY_SVGA, 0x7, 0x5 }, > > Perhaps it could be interesting to also have the "no external monitor" entry? > But generally not to have monitor prevents the boot of MacOS. > > ... > > Reviewed-by: Laurent Vivier <laurent@vivier.eu> > >
Le 04/10/2021 à 12:32, BALATON Zoltan a écrit : > On Mon, 4 Oct 2021, Laurent Vivier wrote: >> Le 02/10/2021 à 13:00, Mark Cave-Ayland a écrit : >>> The MacOS toolbox ROM uses the monitor sense to detect the display type and then >>> offer a fixed set of resolutions and colour depths accordingly. Implement the >>> monitor sense using information found in Apple Technical Note HW26: "Macintosh >>> Quadra Built-In Video" along with some local experiments. >>> >>> Since the default configuration is 640 x 480 with 8-bit colour then hardcode >>> the sense register to return MACFB_DISPLAY_VGA for now. >>> >>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> >>> --- >>> hw/display/macfb.c | 117 ++++++++++++++++++++++++++++++++++++- >>> hw/display/trace-events | 2 + >>> include/hw/display/macfb.h | 20 +++++++ >>> 3 files changed, 137 insertions(+), 2 deletions(-) >>> >>> diff --git a/hw/display/macfb.c b/hw/display/macfb.c >>> index 62c2727a5b..5c95aa4a11 100644 >>> --- a/hw/display/macfb.c >>> +++ b/hw/display/macfb.c >>> @@ -28,8 +28,66 @@ >>> #define MACFB_PAGE_SIZE 4096 >>> #define MACFB_VRAM_SIZE (4 * MiB) >>> >>> -#define DAFB_RESET 0x200 >>> -#define DAFB_LUT 0x213 >>> +#define DAFB_MODE_SENSE 0x1c >>> +#define DAFB_RESET 0x200 >>> +#define DAFB_LUT 0x213 >>> + >>> + >>> +/* >>> + * Quadra sense codes taken from Apple Technical Note HW26: >>> + * "Macintosh Quadra Built-In Video". The sense codes and >> >> https://developer.apple.com/library/archive/technotes/hw/hw_26.html > > URLs may change or go away so I think it's better to reference by title in comments, then one can > find it by that whereas a stale URL is not much help a few years from now. This URL is very stable (hosted by Apple for 30 years now...) and providing it could help to find a copy of the document in an internet archive. I had some difficulties to find it using the title or the TN number. Thanks, Laurent
diff --git a/hw/display/macfb.c b/hw/display/macfb.c index 62c2727a5b..5c95aa4a11 100644 --- a/hw/display/macfb.c +++ b/hw/display/macfb.c @@ -28,8 +28,66 @@ #define MACFB_PAGE_SIZE 4096 #define MACFB_VRAM_SIZE (4 * MiB) -#define DAFB_RESET 0x200 -#define DAFB_LUT 0x213 +#define DAFB_MODE_SENSE 0x1c +#define DAFB_RESET 0x200 +#define DAFB_LUT 0x213 + + +/* + * Quadra sense codes taken from Apple Technical Note HW26: + * "Macintosh Quadra Built-In Video". The sense codes and + * extended sense codes have different meanings: + * + * Sense: + * bit 2: SENSE2 (pin 10) + * bit 1: SENSE1 (pin 7) + * bit 0: SENSE0 (pin 4) + * + * 0 = pin tied to ground + * 1 = pin unconnected + * + * Extended Sense: + * bit 2: pins 4-10 + * bit 1: pins 10-7 + * bit 0: pins 7-4 + * + * 0 = pins tied together + * 1 = pins unconnected + * + * Reads from the sense register appear to be active low, i.e. a 1 indicates + * that the pin is tied to ground, a 0 indicates the pin is disconnected. + * + * Writes to the sense register appear to activate pulldowns i.e. a 1 enables + * a pulldown on a particular pin. + * + * The MacOS toolbox appears to use a series of reads and writes to first + * determine if extended sense is to be used, and then check which pins are + * tied together in order to determine the display type. + */ + +typedef struct MacFbSense { + uint8_t type; + uint8_t sense; + uint8_t ext_sense; +} MacFbSense; + +static MacFbSense macfb_sense_table[] = { + { MACFB_DISPLAY_APPLE_21_COLOR, 0x0, 0 }, + { MACFB_DISPLAY_APPLE_PORTRAIT, 0x1, 0 }, + { MACFB_DISPLAY_APPLE_12_RGB, 0x2, 0 }, + { MACFB_DISPLAY_APPLE_2PAGE_MONO, 0x3, 0 }, + { MACFB_DISPLAY_NTSC_UNDERSCAN, 0x4, 0 }, + { MACFB_DISPLAY_NTSC_OVERSCAN, 0x4, 0 }, + { MACFB_DISPLAY_APPLE_12_MONO, 0x6, 0 }, + { MACFB_DISPLAY_APPLE_13_RGB, 0x6, 0 }, + { MACFB_DISPLAY_16_COLOR, 0x7, 0x3 }, + { MACFB_DISPLAY_PAL1_UNDERSCAN, 0x7, 0x0 }, + { MACFB_DISPLAY_PAL1_OVERSCAN, 0x7, 0x0 }, + { MACFB_DISPLAY_PAL2_UNDERSCAN, 0x7, 0x6 }, + { MACFB_DISPLAY_PAL2_OVERSCAN, 0x7, 0x6 }, + { MACFB_DISPLAY_VGA, 0x7, 0x5 }, + { MACFB_DISPLAY_SVGA, 0x7, 0x5 }, +}; typedef void macfb_draw_line_func(MacfbState *s, uint8_t *d, uint32_t addr, @@ -253,6 +311,50 @@ static void macfb_invalidate_display(void *opaque) memory_region_set_dirty(&s->mem_vram, 0, MACFB_VRAM_SIZE); } +static uint32_t macfb_sense_read(MacfbState *s) +{ + MacFbSense *macfb_sense; + uint8_t sense; + + macfb_sense = &macfb_sense_table[MACFB_DISPLAY_VGA]; + if (macfb_sense->sense == 0x7) { + /* Extended sense */ + sense = 0; + if (!(macfb_sense->ext_sense & 1)) { + /* Pins 7-4 together */ + if (~s->sense & 3) { + sense = (~s->sense & 7) | 3; + } + } + if (!(macfb_sense->ext_sense & 2)) { + /* Pins 10-7 together */ + if (~s->sense & 6) { + sense = (~s->sense & 7) | 6; + } + } + if (!(macfb_sense->ext_sense & 4)) { + /* Pins 4-10 together */ + if (~s->sense & 5) { + sense = (~s->sense & 7) | 5; + } + } + } else { + /* Normal sense */ + sense = (~macfb_sense->sense & 7) | (~s->sense & 7); + } + + trace_macfb_sense_read(sense); + return sense; +} + +static void macfb_sense_write(MacfbState *s, uint32_t val) +{ + s->sense = val; + + trace_macfb_sense_write(val); + return; +} + static void macfb_update_display(void *opaque) { MacfbState *s = opaque; @@ -290,8 +392,15 @@ static uint64_t macfb_ctrl_read(void *opaque, hwaddr addr, unsigned int size) { + MacfbState *s = opaque; uint64_t val = 0; + switch (addr) { + case DAFB_MODE_SENSE: + val = macfb_sense_read(s); + break; + } + trace_macfb_ctrl_read(addr, val, size); return val; } @@ -303,6 +412,9 @@ static void macfb_ctrl_write(void *opaque, { MacfbState *s = opaque; switch (addr) { + case DAFB_MODE_SENSE: + macfb_sense_write(s, val); + break; case DAFB_RESET: s->palette_current = 0; break; @@ -343,6 +455,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_END_OF_LIST() } }; diff --git a/hw/display/trace-events b/hw/display/trace-events index be1353e8e7..6e378036ab 100644 --- a/hw/display/trace-events +++ b/hw/display/trace-events @@ -171,3 +171,5 @@ sm501_2d_engine_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x" # macfb.c macfb_ctrl_read(uint64_t addr, uint64_t value, int size) "addr 0x%"PRIx64 " value 0x%"PRIx64 " size %d" macfb_ctrl_write(uint64_t addr, uint64_t value, 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 diff --git a/include/hw/display/macfb.h b/include/hw/display/macfb.h index 80806b0306..febf4ce0e8 100644 --- a/include/hw/display/macfb.h +++ b/include/hw/display/macfb.h @@ -17,6 +17,24 @@ #include "ui/console.h" #include "qom/object.h" +typedef enum { + MACFB_DISPLAY_APPLE_21_COLOR = 0, + MACFB_DISPLAY_APPLE_PORTRAIT = 1, + MACFB_DISPLAY_APPLE_12_RGB = 2, + MACFB_DISPLAY_APPLE_2PAGE_MONO = 3, + MACFB_DISPLAY_NTSC_UNDERSCAN = 4, + MACFB_DISPLAY_NTSC_OVERSCAN = 5, + MACFB_DISPLAY_APPLE_12_MONO = 6, + MACFB_DISPLAY_APPLE_13_RGB = 7, + MACFB_DISPLAY_16_COLOR = 8, + MACFB_DISPLAY_PAL1_UNDERSCAN = 9, + MACFB_DISPLAY_PAL1_OVERSCAN = 10, + MACFB_DISPLAY_PAL2_UNDERSCAN = 11, + MACFB_DISPLAY_PAL2_OVERSCAN = 12, + MACFB_DISPLAY_VGA = 13, + MACFB_DISPLAY_SVGA = 14, +} MacfbDisplayType; + typedef struct MacfbState { MemoryRegion mem_vram; MemoryRegion mem_ctrl; @@ -28,6 +46,8 @@ typedef struct MacfbState { uint8_t color_palette[256 * 3]; uint32_t width, height; /* in pixels */ uint8_t depth; + + uint32_t sense; } MacfbState; #define TYPE_MACFB "sysbus-macfb"
The MacOS toolbox ROM uses the monitor sense to detect the display type and then offer a fixed set of resolutions and colour depths accordingly. Implement the monitor sense using information found in Apple Technical Note HW26: "Macintosh Quadra Built-In Video" along with some local experiments. Since the default configuration is 640 x 480 with 8-bit colour then hardcode the sense register to return MACFB_DISPLAY_VGA for now. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- hw/display/macfb.c | 117 ++++++++++++++++++++++++++++++++++++- hw/display/trace-events | 2 + include/hw/display/macfb.h | 20 +++++++ 3 files changed, 137 insertions(+), 2 deletions(-)