diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-02-20 22:41:34 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-20 22:41:34 -0800 |
commit | 8f652f110068ed20dd84bdc46233d803bc4150be (patch) | |
tree | 69b7780c4ce6a25353f4f7d75fe93310030d1490 | |
parent | 7135a6783c4ca37f3b9f3baa87573a3f61060db4 (diff) | |
parent | ee43a6e64a6498f457e46f1e2844ab3506ba889d (diff) | |
download | syslinux-8f652f110068ed20dd84bdc46233d803bc4150be.tar.gz |
Merge remote branch 'origin/master' into pathbased
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | com32/lib/Makefile | 7 | ||||
-rw-r--r-- | com32/lib/pci/bios.c (renamed from com32/lib/pci/readbios.c) | 4 | ||||
-rw-r--r-- | com32/lib/pci/pci.h | 3 | ||||
-rw-r--r-- | com32/lib/pci/readx.c | 6 | ||||
-rw-r--r-- | com32/lib/pci/writebios.c | 14 | ||||
-rw-r--r-- | com32/lib/pci/writex.c | 5 | ||||
-rw-r--r-- | com32/lib/sys/vesa/i915resolution.c | 795 | ||||
-rw-r--r-- | com32/lib/sys/vesa/initvesa.c | 9 | ||||
-rw-r--r-- | com32/lib/sys/vesa/video.h | 2 | ||||
-rw-r--r-- | dos/Makefile | 2 | ||||
-rw-r--r-- | dosutil/Makefile | 10 | ||||
-rw-r--r-- | dosutil/copybs.asm (renamed from dos/copybs.asm) | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | dosutil/mdiskchk.com | bin | 7273 -> 7273 bytes |
15 files changed, 833 insertions, 32 deletions
@@ -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 @@ -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 Binary files differindex 78257519..78257519 100755..100644 --- a/dosutil/mdiskchk.com +++ b/dosutil/mdiskchk.com |