Skip to content

Commit e6108b9

Browse files
mcaylandvivier
authored andcommitted
macfb: implement mode sense to allow display type to be detected
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 <[email protected]> Reviewed-by: Laurent Vivier <[email protected]> Message-Id: <[email protected]> Signed-off-by: Laurent Vivier <[email protected]>
1 parent 4ec2707 commit e6108b9

File tree

3 files changed

+137
-2
lines changed

3 files changed

+137
-2
lines changed

hw/display/macfb.c

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,66 @@
2828
#define MACFB_PAGE_SIZE 4096
2929
#define MACFB_VRAM_SIZE (4 * MiB)
3030

31-
#define DAFB_RESET 0x200
32-
#define DAFB_LUT 0x213
31+
#define DAFB_MODE_SENSE 0x1c
32+
#define DAFB_RESET 0x200
33+
#define DAFB_LUT 0x213
34+
35+
36+
/*
37+
* Quadra sense codes taken from Apple Technical Note HW26:
38+
* "Macintosh Quadra Built-In Video". The sense codes and
39+
* extended sense codes have different meanings:
40+
*
41+
* Sense:
42+
* bit 2: SENSE2 (pin 10)
43+
* bit 1: SENSE1 (pin 7)
44+
* bit 0: SENSE0 (pin 4)
45+
*
46+
* 0 = pin tied to ground
47+
* 1 = pin unconnected
48+
*
49+
* Extended Sense:
50+
* bit 2: pins 4-10
51+
* bit 1: pins 10-7
52+
* bit 0: pins 7-4
53+
*
54+
* 0 = pins tied together
55+
* 1 = pins unconnected
56+
*
57+
* Reads from the sense register appear to be active low, i.e. a 1 indicates
58+
* that the pin is tied to ground, a 0 indicates the pin is disconnected.
59+
*
60+
* Writes to the sense register appear to activate pulldowns i.e. a 1 enables
61+
* a pulldown on a particular pin.
62+
*
63+
* The MacOS toolbox appears to use a series of reads and writes to first
64+
* determine if extended sense is to be used, and then check which pins are
65+
* tied together in order to determine the display type.
66+
*/
67+
68+
typedef struct MacFbSense {
69+
uint8_t type;
70+
uint8_t sense;
71+
uint8_t ext_sense;
72+
} MacFbSense;
73+
74+
static MacFbSense macfb_sense_table[] = {
75+
{ MACFB_DISPLAY_APPLE_21_COLOR, 0x0, 0 },
76+
{ MACFB_DISPLAY_APPLE_PORTRAIT, 0x1, 0 },
77+
{ MACFB_DISPLAY_APPLE_12_RGB, 0x2, 0 },
78+
{ MACFB_DISPLAY_APPLE_2PAGE_MONO, 0x3, 0 },
79+
{ MACFB_DISPLAY_NTSC_UNDERSCAN, 0x4, 0 },
80+
{ MACFB_DISPLAY_NTSC_OVERSCAN, 0x4, 0 },
81+
{ MACFB_DISPLAY_APPLE_12_MONO, 0x6, 0 },
82+
{ MACFB_DISPLAY_APPLE_13_RGB, 0x6, 0 },
83+
{ MACFB_DISPLAY_16_COLOR, 0x7, 0x3 },
84+
{ MACFB_DISPLAY_PAL1_UNDERSCAN, 0x7, 0x0 },
85+
{ MACFB_DISPLAY_PAL1_OVERSCAN, 0x7, 0x0 },
86+
{ MACFB_DISPLAY_PAL2_UNDERSCAN, 0x7, 0x6 },
87+
{ MACFB_DISPLAY_PAL2_OVERSCAN, 0x7, 0x6 },
88+
{ MACFB_DISPLAY_VGA, 0x7, 0x5 },
89+
{ MACFB_DISPLAY_SVGA, 0x7, 0x5 },
90+
};
3391

3492

3593
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)
253311
memory_region_set_dirty(&s->mem_vram, 0, MACFB_VRAM_SIZE);
254312
}
255313

314+
static uint32_t macfb_sense_read(MacfbState *s)
315+
{
316+
MacFbSense *macfb_sense;
317+
uint8_t sense;
318+
319+
macfb_sense = &macfb_sense_table[MACFB_DISPLAY_VGA];
320+
if (macfb_sense->sense == 0x7) {
321+
/* Extended sense */
322+
sense = 0;
323+
if (!(macfb_sense->ext_sense & 1)) {
324+
/* Pins 7-4 together */
325+
if (~s->sense & 3) {
326+
sense = (~s->sense & 7) | 3;
327+
}
328+
}
329+
if (!(macfb_sense->ext_sense & 2)) {
330+
/* Pins 10-7 together */
331+
if (~s->sense & 6) {
332+
sense = (~s->sense & 7) | 6;
333+
}
334+
}
335+
if (!(macfb_sense->ext_sense & 4)) {
336+
/* Pins 4-10 together */
337+
if (~s->sense & 5) {
338+
sense = (~s->sense & 7) | 5;
339+
}
340+
}
341+
} else {
342+
/* Normal sense */
343+
sense = (~macfb_sense->sense & 7) | (~s->sense & 7);
344+
}
345+
346+
trace_macfb_sense_read(sense);
347+
return sense;
348+
}
349+
350+
static void macfb_sense_write(MacfbState *s, uint32_t val)
351+
{
352+
s->sense = val;
353+
354+
trace_macfb_sense_write(val);
355+
return;
356+
}
357+
256358
static void macfb_update_display(void *opaque)
257359
{
258360
MacfbState *s = opaque;
@@ -290,8 +392,15 @@ static uint64_t macfb_ctrl_read(void *opaque,
290392
hwaddr addr,
291393
unsigned int size)
292394
{
395+
MacfbState *s = opaque;
293396
uint64_t val = 0;
294397

398+
switch (addr) {
399+
case DAFB_MODE_SENSE:
400+
val = macfb_sense_read(s);
401+
break;
402+
}
403+
295404
trace_macfb_ctrl_read(addr, val, size);
296405
return val;
297406
}
@@ -303,6 +412,9 @@ static void macfb_ctrl_write(void *opaque,
303412
{
304413
MacfbState *s = opaque;
305414
switch (addr) {
415+
case DAFB_MODE_SENSE:
416+
macfb_sense_write(s, val);
417+
break;
306418
case DAFB_RESET:
307419
s->palette_current = 0;
308420
break;
@@ -342,6 +454,7 @@ static const VMStateDescription vmstate_macfb = {
342454
.fields = (VMStateField[]) {
343455
VMSTATE_UINT8_ARRAY(color_palette, MacfbState, 256 * 3),
344456
VMSTATE_UINT32(palette_current, MacfbState),
457+
VMSTATE_UINT32(sense, MacfbState),
345458
VMSTATE_END_OF_LIST()
346459
}
347460
};

hw/display/trace-events

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,5 @@ sm501_2d_engine_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
171171
# macfb.c
172172
macfb_ctrl_read(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%"PRIx64 " value 0x%"PRIx64 " size %u"
173173
macfb_ctrl_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%"PRIx64 " value 0x%"PRIx64 " size %u"
174+
macfb_sense_read(uint32_t value) "video sense: 0x%"PRIx32
175+
macfb_sense_write(uint32_t value) "video sense: 0x%"PRIx32

include/hw/display/macfb.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,24 @@
1717
#include "ui/console.h"
1818
#include "qom/object.h"
1919

20+
typedef enum {
21+
MACFB_DISPLAY_APPLE_21_COLOR = 0,
22+
MACFB_DISPLAY_APPLE_PORTRAIT = 1,
23+
MACFB_DISPLAY_APPLE_12_RGB = 2,
24+
MACFB_DISPLAY_APPLE_2PAGE_MONO = 3,
25+
MACFB_DISPLAY_NTSC_UNDERSCAN = 4,
26+
MACFB_DISPLAY_NTSC_OVERSCAN = 5,
27+
MACFB_DISPLAY_APPLE_12_MONO = 6,
28+
MACFB_DISPLAY_APPLE_13_RGB = 7,
29+
MACFB_DISPLAY_16_COLOR = 8,
30+
MACFB_DISPLAY_PAL1_UNDERSCAN = 9,
31+
MACFB_DISPLAY_PAL1_OVERSCAN = 10,
32+
MACFB_DISPLAY_PAL2_UNDERSCAN = 11,
33+
MACFB_DISPLAY_PAL2_OVERSCAN = 12,
34+
MACFB_DISPLAY_VGA = 13,
35+
MACFB_DISPLAY_SVGA = 14,
36+
} MacfbDisplayType;
37+
2038
typedef struct MacfbState {
2139
MemoryRegion mem_vram;
2240
MemoryRegion mem_ctrl;
@@ -28,6 +46,8 @@ typedef struct MacfbState {
2846
uint8_t color_palette[256 * 3];
2947
uint32_t width, height; /* in pixels */
3048
uint8_t depth;
49+
50+
uint32_t sense;
3151
} MacfbState;
3252

3353
#define TYPE_MACFB "sysbus-macfb"

0 commit comments

Comments
 (0)