summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-20 22:41:34 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-20 22:41:34 -0800
commit8f652f110068ed20dd84bdc46233d803bc4150be (patch)
tree69b7780c4ce6a25353f4f7d75fe93310030d1490
parent7135a6783c4ca37f3b9f3baa87573a3f61060db4 (diff)
parentee43a6e64a6498f457e46f1e2844ab3506ba889d (diff)
downloadsyslinux-8f652f110068ed20dd84bdc46233d803bc4150be.tar.gz
Merge remote branch 'origin/master' into pathbased
-rw-r--r--Makefile4
-rw-r--r--NEWS4
-rw-r--r--com32/lib/Makefile7
-rw-r--r--com32/lib/pci/bios.c (renamed from com32/lib/pci/readbios.c)4
-rw-r--r--com32/lib/pci/pci.h3
-rw-r--r--com32/lib/pci/readx.c6
-rw-r--r--com32/lib/pci/writebios.c14
-rw-r--r--com32/lib/pci/writex.c5
-rw-r--r--com32/lib/sys/vesa/i915resolution.c795
-rw-r--r--com32/lib/sys/vesa/initvesa.c9
-rw-r--r--com32/lib/sys/vesa/video.h2
-rw-r--r--dos/Makefile2
-rw-r--r--dosutil/Makefile10
-rw-r--r--dosutil/copybs.asm (renamed from dos/copybs.asm)0
-rw-r--r--[-rwxr-xr-x]dosutil/mdiskchk.combin7273 -> 7273 bytes
15 files changed, 833 insertions, 32 deletions
diff --git a/Makefile b/Makefile
index 639ffd7c..fccd0f53 100644
--- a/Makefile
+++ b/Makefile
@@ -56,7 +56,7 @@ BOBJECTS = $(BTARGET) \
BSUBDIRS = codepage com32 lzo core memdisk modules mbr memdump gpxe sample \
libinstaller dos win32 dosutil
ITARGET =
-IOBJECTS = $(ITARGET) dos/copybs.com \
+IOBJECTS = $(ITARGET) \
utils/gethostip utils/isohybrid utils/mkdiskimage \
mtools/syslinux linux/syslinux extlinux/extlinux
ISUBDIRS = libinstaller mtools linux extlinux utils
@@ -68,7 +68,7 @@ INSTALL_SBIN = extlinux/extlinux
# Things to install in /usr/lib/syslinux
INSTALL_AUX = core/pxelinux.0 gpxe/gpxelinux.0 core/isolinux.bin \
core/isolinux-debug.bin \
- dos/syslinux.com dos/copybs.com win32/syslinux.exe \
+ dos/syslinux.com win32/syslinux.exe \
mbr/*.bin $(MODULES)
INSTALL_AUX_OPT = win32/syslinux.exe
diff --git a/NEWS b/NEWS
index 7687f6d6..bbab62bb 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,10 @@ Changes in 3.85:
* vesamenu.c32: if the image is smaller than the screen, tile
it across the whole screen.
* mkdiskimage: -s option for producing a sparse image.
+ * vesamenu.c32: support arbitrary resolution setting (beyond
+ BIOS support) on some Intel-based video chipsets. This code
+ is a modified version of the "915resolution" tool by
+ Steve Tomljenovic; your mileage might vary.
Changes in 3.84:
* SYSLINUX: make the DOS installer work for MS-DOS 7.x/8.x
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index 7bd340c1..3e6aa810 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -65,10 +65,11 @@ LIBOBJS = \
sys/vesacon_write.o sys/vesaserial_write.o \
sys/vesa/initvesa.o sys/vesa/drawtxt.o sys/vesa/background.o \
sys/vesa/alphatbl.o sys/vesa/screencpy.o sys/vesa/fmtpixel.o \
+ sys/vesa/i915resolution.o \
\
- pci/cfgtype.o pci/scan.o \
- pci/readb.o pci/readw.o pci/readl.o pci/readbios.o \
- pci/writeb.o pci/writew.o pci/writel.o pci/writebios.o \
+ pci/cfgtype.o pci/scan.o pci/bios.o \
+ pci/readb.o pci/readw.o pci/readl.o \
+ pci/writeb.o pci/writew.o pci/writel.o \
\
zlib/adler32.o zlib/compress.o zlib/crc32.o \
zlib/uncompr.o zlib/deflate.o zlib/trees.o zlib/zutil.o \
diff --git a/com32/lib/pci/readbios.c b/com32/lib/pci/bios.c
index f8ff3bff..b3c2c57d 100644
--- a/com32/lib/pci/readbios.c
+++ b/com32/lib/pci/bios.c
@@ -2,13 +2,15 @@
#include <string.h>
#include "pci/pci.h"
-uint32_t __pci_read_bios(uint32_t call, pciaddr_t a)
+uint32_t __pci_read_write_bios(uint32_t call, uint32_t v, pciaddr_t a)
{
com32sys_t rs;
memset(&rs, 0, sizeof rs);
rs.eax.w[0] = call;
rs.ebx.w[0] = a >> 8; /* bus:device:function */
rs.edi.b[0] = a; /* address:reg */
+ rs.ecx.l = v;
+ rs.eflags.l = EFLAGS_CF;
__intcall(0x1a, &rs, &rs);
return (rs.eflags.l & EFLAGS_CF) ? ~(uint32_t) 0 : rs.ecx.l;
diff --git a/com32/lib/pci/pci.h b/com32/lib/pci/pci.h
index 66a1eb50..8d81b0e4 100644
--- a/com32/lib/pci/pci.h
+++ b/com32/lib/pci/pci.h
@@ -10,7 +10,6 @@
#include <sys/cpu.h>
extern enum pci_config_type __pci_cfg_type;
-extern uint32_t __pci_read_bios(uint32_t call, pciaddr_t a);
-extern void __pci_write_bios(uint32_t call, uint32_t v, pciaddr_t a);
+extern uint32_t __pci_read_write_bios(uint32_t call, uint32_t v, pciaddr_t a);
#endif /* PCI_PCI_H */
diff --git a/com32/lib/pci/readx.c b/com32/lib/pci/readx.c
index f073eaa1..ed66d5b2 100644
--- a/com32/lib/pci/readx.c
+++ b/com32/lib/pci/readx.c
@@ -1,7 +1,7 @@
#include "pci/pci.h"
-#include <string.h>
-TYPE BWL(pci_read) (pciaddr_t a) {
+TYPE BWL(pci_read) (pciaddr_t a)
+{
TYPE r;
for (;;) {
@@ -42,7 +42,7 @@ TYPE BWL(pci_read) (pciaddr_t a) {
return r;
case PCI_CFG_BIOS:
- return (TYPE) __pci_read_bios(BIOSCALL, a);
+ return (TYPE) __pci_read_write_bios(BIOSCALL, 0, a);
default:
return (TYPE) ~ 0;
diff --git a/com32/lib/pci/writebios.c b/com32/lib/pci/writebios.c
deleted file mode 100644
index d367eee7..00000000
--- a/com32/lib/pci/writebios.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <com32.h>
-#include <string.h>
-#include "pci/pci.h"
-
-void __pci_write_bios(uint32_t call, uint32_t v, pciaddr_t a)
-{
- com32sys_t rs;
- memset(&rs, 0, sizeof rs);
- rs.eax.w[0] = call;
- rs.ebx.w[0] = a >> 8; /* bus:device:function */
- rs.edi.b[0] = a; /* address:reg */
- rs.ecx.l = v;
- __intcall(0x1a, &rs, NULL);
-}
diff --git a/com32/lib/pci/writex.c b/com32/lib/pci/writex.c
index 14b20380..d83a1eed 100644
--- a/com32/lib/pci/writex.c
+++ b/com32/lib/pci/writex.c
@@ -1,6 +1,7 @@
#include "pci/pci.h"
-void BWL(pci_write) (TYPE v, pciaddr_t a) {
+void BWL(pci_write)(TYPE v, pciaddr_t a)
+{
for (;;) {
switch (__pci_cfg_type) {
case PCI_CFG_AUTO:
@@ -39,7 +40,7 @@ void BWL(pci_write) (TYPE v, pciaddr_t a) {
return;
case PCI_CFG_BIOS:
- __pci_write_bios(BIOSCALL, v, a);
+ __pci_read_write_bios(BIOSCALL, v, a);
return;
default:
diff --git a/com32/lib/sys/vesa/i915resolution.c b/com32/lib/sys/vesa/i915resolution.c
new file mode 100644
index 00000000..6ebb04d3
--- /dev/null
+++ b/com32/lib/sys/vesa/i915resolution.c
@@ -0,0 +1,795 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Based on:
+ *
+ * 915 resolution by steve tomljenovic
+ *
+ * This was tested only on Sony VGN-FS550. Use at your own risk
+ *
+ * This code is based on the techniques used in :
+ *
+ * - 855patch. Many thanks to Christian Zietz (czietz gmx net)
+ * for demonstrating how to shadow the VBIOS into system RAM
+ * and then modify it.
+ *
+ * - 1280patch by Andrew Tipton (andrewtipton null li).
+ *
+ * - 855resolution by Alain Poirier
+ *
+ * This source code is into the public domain.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#define __USE_GNU
+#include <string.h>
+#include <sys/io.h>
+#include <sys/cpu.h>
+#include <sys/pci.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdbool.h>
+#include "video.h"
+#include "debug.h"
+
+#define VBIOS_START 0xc0000
+#define VBIOS_SIZE 0x10000
+
+#define MODE_TABLE_OFFSET_845G 617
+
+#define VERSION "0.5.3"
+
+#define ATI_SIGNATURE1 "ATI MOBILITY RADEON"
+#define ATI_SIGNATURE2 "ATI Technologies Inc"
+#define NVIDIA_SIGNATURE "NVIDIA Corp"
+#define INTEL_SIGNATURE "Intel Corp"
+
+typedef unsigned char * address;
+
+typedef enum {
+ CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, CT_915G, CT_915GM,
+ CT_945G, CT_945GM, CT_946GZ, CT_G965, CT_Q965, CT_945GME,
+ CHIPSET_TYPES
+} chipset_type;
+
+typedef enum {
+ BT_UNKWN, BT_1, BT_2, BT_3
+} bios_type;
+
+static int freqs[] = { 60, 75, 85 };
+
+typedef struct {
+ uint8_t mode;
+ uint8_t bits_per_pixel;
+ uint16_t resolution;
+ uint8_t unknown;
+} __attribute__((packed)) vbios_mode;
+
+typedef struct {
+ uint16_t clock; /* Clock frequency in 10 kHz */
+ uint8_t x1;
+ uint8_t x_total;
+ uint8_t x2;
+ uint8_t y1;
+ uint8_t y_total;
+ uint8_t y2;
+} __attribute__((packed)) vbios_resolution_type1;
+
+typedef struct {
+ uint32_t clock;
+
+ uint16_t x1;
+ uint16_t htotal;
+ uint16_t x2;
+ uint16_t hblank;
+ uint16_t hsyncstart;
+ uint16_t hsyncend;
+
+ uint16_t y1;
+ uint16_t vtotal;
+ uint16_t y2;
+ uint16_t vblank;
+ uint16_t vsyncstart;
+ uint16_t vsyncend;
+} __attribute__((packed)) vbios_modeline_type2;
+
+typedef struct {
+ uint8_t xchars;
+ uint8_t ychars;
+ uint8_t unknown[4];
+
+ vbios_modeline_type2 modelines[];
+} __attribute__((packed)) vbios_resolution_type2;
+
+typedef struct {
+ uint32_t clock;
+
+ uint16_t x1;
+ uint16_t htotal;
+ uint16_t x2;
+ uint16_t hblank;
+ uint16_t hsyncstart;
+ uint16_t hsyncend;
+
+ uint16_t y1;
+ uint16_t vtotal;
+ uint16_t y2;
+ uint16_t vblank;
+ uint16_t vsyncstart;
+ uint16_t vsyncend;
+
+ uint16_t timing_h;
+ uint16_t timing_v;
+
+ uint8_t unknown[6];
+} __attribute__((packed)) vbios_modeline_type3;
+
+typedef struct {
+ unsigned char unknown[6];
+
+ vbios_modeline_type3 modelines[];
+} __attribute__((packed)) vbios_resolution_type3;
+
+
+typedef struct {
+ unsigned int chipset_id;
+ chipset_type chipset;
+ bios_type bios;
+
+ address bios_ptr;
+
+ vbios_mode * mode_table;
+ unsigned int mode_table_size;
+
+ uint8_t b1, b2;
+
+ bool unlocked;
+} vbios_map;
+
+#if 0 /* Debugging hacks */
+static void good_marker(int x)
+{
+ ((uint16_t *)0xb8000)[x] = 0x2f30 - ((x & 0xf0) << 4) + (x & 0x0f);
+}
+
+static void bad_marker(int x)
+{
+ ((uint16_t *)0xb8000)[x] = 0x4f30 - ((x & 0xf0) << 4) + (x & 0x0f);
+}
+
+static void status(const char *fmt, ...)
+{
+ va_list ap;
+ char msg[81], *p;
+ int i;
+ uint16_t *q;
+
+ memset(msg, 0, sizeof msg);
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof msg, fmt, ap);
+ va_end(ap);
+ p = msg;
+ q = (uint16_t *)0xb8000 + 80;
+ for (i = 0; i < 80; i++)
+ *q++ = *p++ + 0x1f00;
+}
+#else
+static inline void good_marker(int x) { (void)x; }
+static inline void bad_marker(int x) { (void)x; }
+static inline void status(const char *fmt, ...) { (void)fmt; }
+#endif
+
+static unsigned int get_chipset_id(void) {
+ return pci_readl(0x80000000);
+}
+
+static chipset_type get_chipset(unsigned int id) {
+ chipset_type type;
+
+ switch (id) {
+ case 0x35758086:
+ type = CT_830;
+ break;
+
+ case 0x25608086:
+ type = CT_845G;
+ break;
+
+ case 0x35808086:
+ type = CT_855GM;
+ break;
+
+ case 0x25708086:
+ type = CT_865G;
+ break;
+
+ case 0x25808086:
+ type = CT_915G;
+ break;
+
+ case 0x25908086:
+ type = CT_915GM;
+ break;
+
+ case 0x27708086:
+ type = CT_945G;
+ break;
+
+ case 0x27a08086:
+ type = CT_945GM;
+ break;
+
+ case 0x29708086:
+ type = CT_946GZ;
+ break;
+
+ case 0x29a08086:
+ type = CT_G965;
+ break;
+
+ case 0x29908086:
+ type = CT_Q965;
+ break;
+
+ case 0x27ac8086:
+ type = CT_945GME;
+ break;
+
+ default:
+ type = CT_UNKWN;
+ break;
+ }
+
+ return type;
+}
+
+
+static vbios_resolution_type1 * map_type1_resolution(vbios_map * map,
+ uint16_t res)
+{
+ vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res));
+ return ptr;
+}
+
+static vbios_resolution_type2 * map_type2_resolution(vbios_map * map,
+ uint16_t res)
+{
+ vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res));
+ return ptr;
+}
+
+static vbios_resolution_type3 * map_type3_resolution(vbios_map * map,
+ uint16_t res)
+{
+ vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res));
+ return ptr;
+}
+
+
+static bool detect_bios_type(vbios_map * map, int entry_size)
+{
+ unsigned int i;
+ uint16_t r1, r2;
+
+ r1 = r2 = 32000;
+
+ for (i = 0; i < map->mode_table_size; i++) {
+ if (map->mode_table[i].resolution <= r1) {
+ r1 = map->mode_table[i].resolution;
+ } else if (map->mode_table[i].resolution <= r2) {
+ r2 = map->mode_table[i].resolution;
+ }
+ }
+
+ return ((r2-r1-6) % entry_size) == 0;
+}
+
+static inline void close_vbios(vbios_map *map)
+{
+ (void)map;
+}
+
+static vbios_map * open_vbios(void)
+{
+ static vbios_map _map;
+ vbios_map * const map = &_map;
+
+ memset(&_map, 0, sizeof _map);
+
+ /*
+ * Determine chipset
+ */
+ map->chipset_id = get_chipset_id();
+ good_marker(0x10);
+ map->chipset = get_chipset(map->chipset_id);
+ good_marker(0x11);
+
+ /*
+ * Map the video bios to memory
+ */
+ map->bios_ptr = (void *)VBIOS_START;
+
+ /*
+ * check if we have ATI Radeon
+ */
+
+ if (memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE1, strlen(ATI_SIGNATURE1)) ||
+ memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE2, strlen(ATI_SIGNATURE2)) ) {
+ debug("ATI chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+ return NULL;
+ }
+
+ /*
+ * check if we have NVIDIA
+ */
+
+ if (memmem(map->bios_ptr, VBIOS_SIZE, NVIDIA_SIGNATURE, strlen(NVIDIA_SIGNATURE))) {
+ debug("NVIDIA chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+ return NULL;
+ }
+
+ /*
+ * check if we have Intel
+ */
+
+ if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) {
+ debug("Intel chipset detected. However, 915resolution was unable to determine the chipset type.\r\n");
+
+ debug("Chipset Id: %x\r\n", map->chipset_id);
+
+ debug("Please report this problem to stomljen@yahoo.com\r\n");
+
+ close_vbios(map);
+ return NULL;
+ }
+
+ /*
+ * check for others
+ */
+
+ if (map->chipset == CT_UNKWN) {
+ debug("Unknown chipset type and unrecognized bios.\r\n");
+ debug("915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+
+ debug("Chipset Id: %x\r\n", map->chipset_id);
+ close_vbios(map);
+ return NULL;
+ }
+
+ /*
+ * Figure out where the mode table is
+ */
+ good_marker(0x12);
+
+ {
+ address p = map->bios_ptr + 16;
+ address limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
+
+ while (p < limit && map->mode_table == 0) {
+ vbios_mode * mode_ptr = (vbios_mode *) p;
+
+ if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&
+ ((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) {
+
+ map->mode_table = mode_ptr;
+ }
+
+ p++;
+ }
+
+ if (map->mode_table == 0) {
+ debug("Unable to locate the mode table.\r\n");
+ close_vbios(map);
+ return NULL;
+ }
+ }
+ good_marker(0x13);
+
+ /*
+ * Determine size of mode table
+ */
+
+ {
+ vbios_mode * mode_ptr = map->mode_table;
+
+ while (mode_ptr->mode != 0xff) {
+ map->mode_table_size++;
+ mode_ptr++;
+ }
+ }
+ good_marker(0x14);
+ status("mode_table_size = %d", map->mode_table_size);
+
+ /*
+ * Figure out what type of bios we have
+ * order of detection is important
+ */
+
+ if (detect_bios_type(map, sizeof(vbios_modeline_type3))) {
+ map->bios = BT_3;
+ }
+ else if (detect_bios_type(map, sizeof(vbios_modeline_type2))) {
+ map->bios = BT_2;
+ }
+ else if (detect_bios_type(map, sizeof(vbios_resolution_type1))) {
+ map->bios = BT_1;
+ }
+ else {
+ debug("Unable to determine bios type.\r\n");
+ debug("Mode Table Offset: $C0000 + $%x\r\n", ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr));
+ debug("Mode Table Entries: %u\r\n", map->mode_table_size);
+ bad_marker(0x15);
+ return NULL;
+ }
+ good_marker(0x15);
+
+ return map;
+}
+
+static void unlock_vbios(vbios_map * map)
+{
+ assert(!map->unlocked);
+
+ map->unlocked = true;
+
+ switch (map->chipset) {
+ case CT_UNKWN:
+ case CHIPSET_TYPES: /* Shut up gcc */
+ break;
+ case CT_830:
+ case CT_855GM:
+ map->b1 = pci_readb(0x8000005a);
+ pci_writeb(0x33, 0x8000005a);
+ break;
+ case CT_845G:
+ case CT_865G:
+ case CT_915G:
+ case CT_915GM:
+ case CT_945G:
+ case CT_945GM:
+ case CT_945GME:
+ case CT_946GZ:
+ case CT_G965:
+ case CT_Q965:
+ map->b1 = pci_readb(0x80000091);
+ map->b2 = pci_readb(0x80000092);
+ pci_writeb(0x33, 0x80000091);
+ pci_writeb(0x33, 0x80000092);
+ break;
+ }
+
+#if DEBUG
+ {
+ unsigned int t = inl(0xcfc);
+ debug("unlock PAM: (0x%08x)\r\n", t);
+ }
+#endif
+}
+
+static void relock_vbios(vbios_map * map)
+{
+ assert(map->unlocked);
+ map->unlocked = false;
+
+ switch (map->chipset) {
+ case CT_UNKWN:
+ case CHIPSET_TYPES: /* Shut up gcc */
+ break;
+ case CT_830:
+ case CT_855GM:
+ pci_writeb(map->b1, 0x8000005a);
+ break;
+ case CT_845G:
+ case CT_865G:
+ case CT_915G:
+ case CT_915GM:
+ case CT_945G:
+ case CT_945GM:
+ case CT_945GME:
+ case CT_946GZ:
+ case CT_G965:
+ case CT_Q965:
+ pci_writeb(map->b1, 0x80000091);
+ pci_writeb(map->b2, 0x80000092);
+ break;
+ }
+
+#if DEBUG
+ {
+ unsigned int t = inl(0xcfc);
+ debug("relock PAM: (0x%08x)\r\n", t);
+ }
+#endif
+}
+
+#if 0
+static void list_modes(vbios_map *map, unsigned int raw)
+{
+ unsigned int i, x, y;
+
+ for (i=0; i < map->mode_table_size; i++) {
+ switch(map->bios) {
+ case BT_1:
+ {
+ vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
+
+ x = ((((unsigned int) res->x2) & 0xf0) << 4) | res->x1;
+ y = ((((unsigned int) res->y2) & 0xf0) << 4) | res->y1;
+
+ if (x != 0 && y != 0) {
+ debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+ }
+
+ if (raw)
+ {
+ debug("Mode %02x (raw) :\r\n\t%02x %02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2);
+ }
+
+ }
+ break;
+ case BT_2:
+ {
+ vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
+
+ x = res->modelines[0].x1+1;
+ y = res->modelines[0].y1+1;
+
+ if (x != 0 && y != 0) {
+ debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+ }
+ }
+ break;
+ case BT_3:
+ {
+ vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
+
+ x = res->modelines[0].x1+1;
+ y = res->modelines[0].y1+1;
+
+ if (x != 0 && y != 0) {
+ debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+ }
+ }
+ break;
+ case BT_UNKWN:
+ break;
+ }
+ }
+}
+#endif
+
+static void gtf_timings(int x, int y, int freq, uint32_t *clock,
+ uint16_t *hsyncstart, uint16_t *hsyncend, uint16_t *hblank,
+ uint16_t *vsyncstart, uint16_t *vsyncend, uint16_t *vblank)
+{
+ int hbl, vbl, vfreq;
+
+ vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5;
+ vfreq = vbl * freq;
+ hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) /
+ (70.0 + 300000.0 / vfreq) / 16.0 + 0.5);
+
+ *vsyncstart = y;
+ *vsyncend = y + 3;
+ *vblank = vbl - 1;
+ *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
+ *hsyncend = x + hbl / 2 - 1;
+ *hblank = x + hbl - 1;
+ *clock = (x + hbl) * vfreq / 1000;
+}
+
+static int set_mode(vbios_map * map, unsigned int mode,
+ unsigned int x, unsigned int y, unsigned int bp,
+ unsigned int htotal, unsigned int vtotal)
+{
+ int xprev, yprev;
+ unsigned int i, j;
+ int rv = -1;
+
+ for (i=0; i < map->mode_table_size; i++) {
+ if (map->mode_table[i].mode == mode) {
+ switch(map->bios) {
+ case BT_1:
+ {
+ vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
+ uint32_t clock;
+ uint16_t hsyncstart, hsyncend, hblank;
+ uint16_t vsyncstart, vsyncend, vblank;
+
+ if (bp) {
+ map->mode_table[i].bits_per_pixel = bp;
+ }
+
+ gtf_timings(x, y, freqs[0], &clock,
+ &hsyncstart, &hsyncend, &hblank,
+ &vsyncstart, &vsyncend, &vblank);
+
+ status("x = %d, y = %d, clock = %lu, h = %d %d %d, v = %d %d %d\n",
+ x, y, clock,
+ hsyncstart, hsyncend, hblank,
+ vsyncstart, vsyncend, vblank);
+
+ htotal = htotal ? htotal : (unsigned int)hblank+1;
+ vtotal = vtotal ? vtotal : (unsigned int)vblank+1;
+
+ res->clock = clock/10; /* Units appear to be 10 kHz */
+ res->x2 = (((htotal-x) >> 8) & 0x0f) | ((x >> 4) & 0xf0);
+ res->x1 = (x & 0xff);
+
+ res->y2 = (((vtotal-y) >> 8) & 0x0f) | ((y >> 4) & 0xf0);
+ res->y1 = (y & 0xff);
+ if (htotal)
+ res->x_total = ((htotal-x) & 0xff);
+
+ if (vtotal)
+ res->y_total = ((vtotal-y) & 0xff);
+
+ rv = 0;
+ }
+ break;
+ case BT_2:
+ {
+ vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
+
+ res->xchars = x / 8;
+ res->ychars = y / 16 - 1;
+ xprev = res->modelines[0].x1;
+ yprev = res->modelines[0].y1;
+
+ for(j=0; j < 3; j++) {
+ vbios_modeline_type2 * modeline = &res->modelines[j];
+
+ if (modeline->x1 == xprev && modeline->y1 == yprev) {
+ modeline->x1 = modeline->x2 = x-1;
+ modeline->y1 = modeline->y2 = y-1;
+
+ gtf_timings(x, y, freqs[j], &modeline->clock,
+ &modeline->hsyncstart, &modeline->hsyncend,
+ &modeline->hblank, &modeline->vsyncstart,
+ &modeline->vsyncend, &modeline->vblank);
+
+ if (htotal)
+ modeline->htotal = htotal;
+ else
+ modeline->htotal = modeline->hblank;
+
+ if (vtotal)
+ modeline->vtotal = vtotal;
+ else
+ modeline->vtotal = modeline->vblank;
+ }
+ }
+
+ rv = 0;
+ }
+ break;
+ case BT_3:
+ {
+ vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
+
+ xprev = res->modelines[0].x1;
+ yprev = res->modelines[0].y1;
+
+ for (j=0; j < 3; j++) {
+ vbios_modeline_type3 * modeline = &res->modelines[j];
+
+ if (modeline->x1 == xprev && modeline->y1 == yprev) {
+ modeline->x1 = modeline->x2 = x-1;
+ modeline->y1 = modeline->y2 = y-1;
+
+ gtf_timings(x, y, freqs[j], &modeline->clock,
+ &modeline->hsyncstart, &modeline->hsyncend,
+ &modeline->hblank, &modeline->vsyncstart,
+ &modeline->vsyncend, &modeline->vblank);
+ if (htotal)
+ modeline->htotal = htotal;
+ else
+ modeline->htotal = modeline->hblank;
+ if (vtotal)
+ modeline->vtotal = vtotal;
+ else
+ modeline->vtotal = modeline->vblank;
+
+ modeline->timing_h = y-1;
+ modeline->timing_v = x-1;
+ }
+ }
+
+ rv = 0;
+ }
+ break;
+ case BT_UNKWN:
+ break;
+ }
+ }
+ }
+
+ return rv;
+}
+
+static inline void display_map_info(vbios_map * map) {
+#ifdef DEBUG
+ static const char * bios_type_names[] =
+ {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
+ static const char * chipset_type_names[] = {
+ "UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G",
+ "945GM", "946GZ", "G965", "Q965", "945GME"
+ };
+
+ debug("Chipset: %s\r\n", chipset_type_names[map->chipset]);
+ debug("BIOS: %s\r\n", bios_type_names[map->bios]);
+
+ debug("Mode Table Offset: $C0000 + $%x\r\n",
+ ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr));
+ debug("Mode Table Entries: %u\r\n", map->mode_table_size);
+#endif
+ (void)map;
+}
+
+int __vesacon_i915resolution(int x, int y)
+{
+ vbios_map * map;
+ unsigned int mode = 0x52; /* 800x600x32 mode in known BIOSes */
+ unsigned int bp = 32; /* 32 bits per pixel */
+ int rv = 0;
+
+ good_marker(0);
+
+ map = open_vbios();
+ if (!map)
+ return -1;
+
+ good_marker(1);
+
+ display_map_info(map);
+
+ debug("\r\n");
+
+ if (mode && x && y) {
+ good_marker(2);
+ cli();
+ good_marker(3);
+ unlock_vbios(map);
+ good_marker(4);
+ rv = set_mode(map, mode, x, y, bp, 0, 0);
+ if (rv)
+ bad_marker(5);
+ else
+ good_marker(5);
+ relock_vbios(map);
+ good_marker(6);
+ sti();
+
+ debug("Patch mode %02x to resolution %dx%d complete\r\n", mode, x, y);
+ }
+ close_vbios(map);
+
+ return rv;
+}
diff --git a/com32/lib/sys/vesa/initvesa.c b/com32/lib/sys/vesa/initvesa.c
index f1224a17..0a436f4c 100644
--- a/com32/lib/sys/vesa/initvesa.c
+++ b/com32/lib/sys/vesa/initvesa.c
@@ -318,8 +318,13 @@ int __vesacon_init(int x, int y)
return 10;
rv = vesacon_set_mode(x, y);
- if (rv)
- return rv;
+ if (rv) {
+ /* Try to see if we can just patch the BIOS... */
+ if (__vesacon_i915resolution(x, y))
+ return rv;
+ if (vesacon_set_mode(x, y))
+ return rv;
+ }
init_text_display();
diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h
index 764228a0..d14494b1 100644
--- a/com32/lib/sys/vesa/video.h
+++ b/com32/lib/sys/vesa/video.h
@@ -92,4 +92,6 @@ void __vesacon_set_cursor(int, int, bool);
void __vesacon_copy_to_screen(size_t, const uint32_t *, size_t);
void __vesacon_init_copy_to_screen(void);
+int __vesacon_i915resolution(int x, int y);
+
#endif /* LIB_SYS_VESA_VIDEO_H */
diff --git a/dos/Makefile b/dos/Makefile
index 0bd7d41e..fbaca6bd 100644
--- a/dos/Makefile
+++ b/dos/Makefile
@@ -38,7 +38,7 @@ LIBOBJS = int2526.o conio.o memcpy.o memset.o skipatou.o atou.o \
VPATH = .:../libfat:../libinstaller
-TARGETS = syslinux.com copybs.com
+TARGETS = syslinux.com
all: $(TARGETS)
diff --git a/dosutil/Makefile b/dosutil/Makefile
index 2a105731..fc10ff90 100644
--- a/dosutil/Makefile
+++ b/dosutil/Makefile
@@ -13,7 +13,7 @@ NASM = nasm
NASMOPT = -O9999
WCTARGETS = mdiskchk.com
-NSTARGETS = eltorito.sys
+NSTARGETS = eltorito.sys copybs.com
TARGETS = $(WCTARGETS) $(NSTARGETS)
%.obj: %.c
@@ -24,23 +24,29 @@ TARGETS = $(WCTARGETS) $(NSTARGETS)
$(UPX) --ultra-brute --lzma $@ || \
$(UPX) --ultra-brute $@ || \
true
+ rm -f $*.0*
+ chmod a-x $@
%.sys: %.asm
$(NASM) $(NASMOPT) -f bin -o $@ -l $*.lst $<
$(UPX) --ultra-brute --lzma $@ || \
$(UPX) --ultra-brute $@ || \
true
+ rm -f $*.0*
+ chmod a-x $@
%.com: %.asm
$(NASM) $(NASMOPT) -f bin -o $@ -l $*.lst $<
$(UPX) --ultra-brute --lzma $@ || \
$(UPX) --ultra-brute $@ || \
true
+ rm -f $*.0*
+ chmod a-x $@
all: $(TARGETS)
tidy dist:
- -rm -f *.obj *.lst *.o
+ -rm -f *.obj *.lst *.o *.0*
clean: tidy
diff --git a/dos/copybs.asm b/dosutil/copybs.asm
index 26407148..26407148 100644
--- a/dos/copybs.asm
+++ b/dosutil/copybs.asm
diff --git a/dosutil/mdiskchk.com b/dosutil/mdiskchk.com
index 78257519..78257519 100755..100644
--- a/dosutil/mdiskchk.com
+++ b/dosutil/mdiskchk.com
Binary files differ