--- /dev/null
+diff --git a/tools/firmware/vgabios/vbe.c b/tools/firmware/vgabios/vbe.c
+index 26582d0..d2607dc 100644
+--- a/tools/firmware/vgabios/vbe.c
++++ b/tools/firmware/vgabios/vbe.c
+@@ -1438,4 +1438,185 @@ vbe_biosfn_return_protected_mode_interface:
+ _fail:
+ mov ax, #0x014f
+ ret
++
++vesa_EDID:
++ db 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00 /* 0x0000 8-byte header */
++ db 0x04,0x21 /* 0x0008 Vendor ID ("AAA") */
++ db 0xAB,0xCD /* 0x000A Product ID */
++ db 0x00,0x00,0x00,0x00 /* 0x000C Serial number (none) */
++ db 54, 10 /* 0x0010 Week of manufactur (54) and year of manufacture (2000) */
++ db 0x01, 0x01 /* 0x0012 EDID version number (1.1) */
++ db 0x0F /* 0x0014 Video signal interface (analogue, 0.700 : 0.300 : 1.000 V p-p,
++ Video Setup: Blank Level = Black Level, Separate Sync H & V Signals
++ are supported, Composite Sync Signal on Horizontal is supported, Composite
++ Sync Signal on Green Video is supported, Serration on the Vertical Sync
++ is supported) */
++ db 0x21,0x19 /* 0x0015 Scren size (330 mm * 250 mm) */
++ db 0x78 /* 0x0017 Display gamma (2.2) */
++ db 0x0D /* 0x0018 Feature flags (no DMPS states, RGB, display is continuous frequency) */
++ db 0x78,0xF5 /* 0x0019 Least significant bits for chromaticity and default white point */
++ db 0xA6,0x55,0x48,0x9B,0x26,0x12,0x50,0x54 /* 0x001B Most significant bits for chromaticity and default white point */
++ db 0x00 /* 0x0023 Established timings 1 (720 x 400 @ 70Hz, 720 x 400 @ 88Hz,
++ 640 x 480 @ 60Hz, 640 x 480 @ 67Hz, 640 x 480 @ 72Hz, 640 x 480 @ 75Hz,
++ 800 x 600 @ 56Hz, 800 x 600 @ 60Hz) */
++ db 0x00 /* 0x0024 Established timings 2 (800 x 600 @ 72Hz, 800 x 600 @ 75Hz, 832 x 624 @
++ 75Hz not 1024 x 768 @ 87Hz(I), 1024 x 768 @ 60Hz, 1024 x 768 @ 70Hz,
++ 1024 x 768 @ 75Hz, 1280 x 1024 @ 75Hz) */
++ db 0x00 /* 0x0025 Established timings 2 (1152 x 870 @ 75Hz and no manufacturer timings) */
++ db 0x31, 0x59 /* 0x0026 Standard timing #1 (640 x 480 @ 85 Hz) */
++ db 0x45, 0x59 /* 0x0028 Standard timing #2 (800 x 600 @ 85 Hz) */
++ db 0x61, 0x59 /* 0x002A Standard timing #3 (1024 x 768 @ 85 Hz) */
++ db 0x31, 0x4A /* 0x002C Standard timing #4 (640 x 480 @ 70 Hz) */
++ db 0x00, 0x00 /* 0x002E Standard timing #5 (1280 x 960 @ 70 Hz) */
++ db 0x00, 0x00 /* 0x0030 Standard timing #6 (1600 x 1200 @ 60 Hz) */
++ db 0x01, 0x01 /* 0x0032 Standard timing #7 (unused) */
++ db 0x01, 0x01 /* 0x0034 Standard timing #8 (unused) */
++ /* 0x0036 First 18-byte descriptor (1024 x 768) (0x0400 x 0x0300) */
++ db 0xb4, 0x1f /* Pixel clock = 108000000 Hz */
++ db 0x00 /* Horizontal addressable pixels low byte (0x0400 & 0xFF) */
++ db 0x18 /* Horizontal blanking low byte (0x0198 & 0xFF) */
++ db 0x40 /* Horizontal addressable pixels high 4 bits (0x0400 >> 8), and */
++ /* Horizontal blanking high 4 bits (0x0198 >> 8) */
++ db 0x00 /* Vertical addressable pixels low byte (0x0300 & 0xFF) */
++ db 0x03 /* Vertical blanking low byte (0x002A & 0xFF) */
++ db 0x30 /* Vertical addressable pixels high 4 bits (0x0300 >> 8), and */
++ /* Vertical blanking high 4 bits (0x002A >> 8) */
++ db 0x08 /* Horizontal front porch in pixels low byte (0x0030 & 0xFF) */
++ db 0x08 /* Horizontal sync pulse width in pixels low byte (0x0070 & 0xFF) */
++ db 0x11 /* Vertical front porch in lines low 4 bits (0x0001 & 0x0F), and */
++ /* Vertical sync pulse width in lines low 4 bits (0x0003 & 0x0F) */
++ db 0x00 /* Horizontal front porch pixels high 2 bits (0x0030 >> 8), and */
++ /* Horizontal sync pulse width in pixels high 2 bits (0x0070 >> 8), and */
++ /* Vertical front porch in lines high 2 bits (0x0001 >> 4), and */
++ /* Vertical sync pulse width in lines high 2 bits (0x0003 >> 4) */
++ db 0x00 /* Horizontal addressable video image size in mm low 8 bits (0x012C & 0xFF) */
++ db 0x00 /* Vertical addressable video image size in mm low 8 bits (0x00E1 & 0xFF) */
++ db 0x00 /* Horizontal addressable video image size in mm low 8 bits (0x012C >> 8), and */
++ /* Vertical addressable video image size in mm low 8 bits (0x00E1 >> 8) */
++ db 0x00 /* Left and right border size in pixels (0x00) */
++ db 0x00 /* Top and bottom border size in lines (0x00) */
++ db 0x00 /* Flags (non-interlaced, no stereo, analog composite sync, sync on */
++ /* all three (RGB) video signals) */
++ /* 0x0048 First 18-byte descriptor (1152 x 864) */
++ db 0x00, 0x00 /* Pixel clock = 108000000 Hz */
++ db 0x00 /* Horizontal addressable pixels low byte (0x00 & 0x00) */
++ db 0x00 /* Horizontal blanking low byte (0x00 & 0x00) */
++ db 0x00 /* Horizontal addressable pixels high 4 bits (0x00 >> 8), and */
++ /* Horizontal blanking high 4 bits (0x00 >> 8) */
++ db 0x00 /* Vertical addressable pixels low byte (0x00 & 0x00) */
++ db 0x00 /* Vertical blanking low byte (0x00 & 0x00) */
++ db 0x00 /* Vertical addressable pixels high 4 bits (0x00 >> 8), and */
++ /* Vertical blanking high 4 bits (0x00 >> 8) */
++ db 0x00 /* Horizontal front porch in pixels low byte (0x00 & 0x00) */
++ db 0x00 /* Horizontal sync pulse width in pixels low byte (0x00 & 0x00) */
++ db 0x00 /* Vertical front porch in lines low 4 bits (0x00 & 0x00), and */
++ /* Vertical sync pulse width in lines low 4 bits (0x00 & 0x00) */
++ db 0x00 /* Horizontal front porch pixels high 2 bits (0x00 >> 8), and */
++ /* Horizontal sync pulse width in pixels high 2 bits (0x00 >> 8), and */
++ /* Vertical front porch in lines high 2 bits (0x00 >> 4), and */
++ /* Vertical sync pulse width in lines high 2 bits (0x00 >> 4) */
++ db 0x00 /* Horizontal addressable video image size in mm low 8 bits (0x00 & 0x00) */
++ db 0x00 /* Vertical addressable video image size in mm low 8 bits (0x00 & 0x00) */
++ db 0x00 /* Horizontal addressable video image size in mm low 8 bits (0x00 >> 8), and */
++ /* Vertical addressable video image size in mm low 8 bits (0x00 >> 8) */
++ db 0x00 /* Left and right border size in pixels (0x00) */
++ db 0x00 /* Top and bottom border size in lines (0x00) */
++ db 0x00 /* Flags (non-interlaced, no stereo, analog composite sync, sync on */
++ /* all three (RGB) video signals) */
++ db 0x00,0x00,0x00,0xFF,0x00 /* 0x005A Third 18-byte descriptor - display product serial number */
++ .ascii "0123456789"
++ db 0x0A,0x20,0x20
++
++ db 0x00,0x00,0x00,0xFC,0x00 /* 0x006C Fourth 18-byte descriptor - display product name */
++ .ascii "Bochs Screen"
++ db 0x0A
++
++ db 0x00 /* 0x007E Extension block count (none) */
++ db 0x00 /* 0x007F Checksum (ignored - recalculated when needed) */
++
++
++ASM_END
++
++static void vbe_edid(edid, es, di, ds)
++ Bit16u ds,es,di; Bit8u *edid;
++{
++ Bit8u e[128];
++ Bit8u t;
++ Bit8u i = 0;
++ Bit16u ss=get_SS();
++ Bit16u hres;
++ Bit16u vres;
++
++ outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_EDID_XRES);
++ hres = inw(VBE_DISPI_IOPORT_DATA);
++ outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_EDID_YRES);
++ vres = inw(VBE_DISPI_IOPORT_DATA);
++
++ for (i = 0; i < 128; i++)
++ memcpyb(ss, e + i, ds, edid + i, 1);
++ t = hres & 0xFF;
++ memcpyb(ss, e + 0x38, ss, &t, 1);
++ t = ((hres >> 8) & 0xF) << 4;
++ memcpyb(ss, e + 0x3A, ss, &t, 1);
++ t = vres & 0xFF;
++ memcpyb(ss, e + 0x3B, ss, &t, 1);
++ t = ((vres >> 8) & 0xF) << 4;
++ memcpyb(ss, e + 0x3D, ss, &t, 1);
++ memcpyb(es, di, ss, e, 128);
++}
++
++ASM_START
++
++/** Function 15h - Display Identification Extensions
++ * Input: AX = 4F0Ah VBE 2.0 Protected Mode Interface
++ * BL = 00h Get capabilities
++ * BL = 01h Read EDID
++ * CX = Controller unit number
++ * DX = EDID block number (if BL = 01h)
++ * ES:DI = Null pointer/reserved (if BL = 00h)
++ * ES:DI = Pointer to buffer to store EDID block (if BL = 01h)
++ *
++ * Output: AX = Status
++ * BH = Approximate time to get EDID in seconds
++rounded up (if BL = 00h)
++ * BL = DDC level supported: (if BL = 00h)
++ * Bit Meaning if set
++ * 0 DDC1 supported
++ * 1 DDC2 supported
++ * 2 Screen blanked during transfer
++ * BH = Unchanged (if BL = 01h)
++ * CX = Unchanged
++ * ES:DI = Unchanged
++ */
++
++
++vbe_biosfn_display_identification_extensions:
++ cmp bl,#0x01
++ jne _get_capabilities
++
++ mov ax, #0xc000
++ mov ds, ax
++ push ds
++ push di
++ push es
++ push #vesa_EDID
++ call _vbe_edid
++ pop bx
++ pop bx
++ pop bx
++ pop bx
++
++ xor cx,cx
++ mov ax, #0x004f
++ ret
++
++_failed:
++ mov ax, #0x014f
++ ret
++
++_get_capabilities:
++ mov ax, #0x004f
++ mov bx, #0x0101
++ ret
++
+ ASM_END
+diff --git a/tools/firmware/vgabios/vbe.h b/tools/firmware/vgabios/vbe.h
+index 3b78582..d25767a 100644
+--- a/tools/firmware/vgabios/vbe.h
++++ b/tools/firmware/vgabios/vbe.h
+@@ -297,6 +297,8 @@ typedef struct ModeInfoListItem
+ #define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa
+ #define VBE_DISPI_INDEX_LFB_ADDRESS_H 0xb
+ #define VBE_DISPI_INDEX_LFB_ADDRESS_L 0xc
++ #define VBE_DISPI_INDEX_EDID_XRES 0xe
++ #define VBE_DISPI_INDEX_EDID_YRES 0xf
+
+ #define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
+ #define VBE_DISPI_ID0 0xB0C0
+diff --git a/tools/firmware/vgabios/vgabios.c b/tools/firmware/vgabios/vgabios.c
+index a9dbe00..09cfaea 100644
+--- a/tools/firmware/vgabios/vgabios.c
++++ b/tools/firmware/vgabios/vgabios.c
+@@ -382,9 +382,14 @@ int10_test_vbe_08:
+ jmp int10_end
+ int10_test_vbe_0A:
+ cmp al, #0x0A
+- jne int10_normal
++ jne int10_test_vbe_15
+ call vbe_biosfn_return_protected_mode_interface
+ jmp int10_end
++int10_test_vbe_15:
++ cmp al, #0x15
++ jne int10_normal
++ call vbe_biosfn_display_identification_extensions
++ jmp int10_end
+ #endif
+
+ int10_normal: